| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- --- a/pcap-linux.c
- +++ b/pcap-linux.c
- @@ -297,6 +297,12 @@ pcap_create(const char *device, char *eb
- {
- pcap_t *handle;
-
- + /*
- + * A null device name is equivalent to the "any" device.
- + */
- + if (device == NULL)
- + device = "any";
- +
- #ifdef HAVE_DAG_API
- if (strstr(device, "dag")) {
- return dag_create(device, ebuf);
- @@ -338,10 +344,9 @@ pcap_can_set_rfmon_linux(pcap_t *p)
- struct iwreq ireq;
- #endif
-
- - if (p->opt.source == NULL) {
- + if (strcmp(p->opt.source, "any") == 0) {
- /*
- - * This is equivalent to the "any" device, and we don't
- - * support monitor mode on it.
- + * Monitor mode makes no sense on the "any" device.
- */
- return 0;
- }
- @@ -518,12 +523,11 @@ pcap_activate_linux(pcap_t *handle)
- handle->stats_op = pcap_stats_linux;
-
- /*
- - * NULL and "any" are special devices which give us the hint to
- - * monitor all devices.
- + * The "any" device is a special device which causes us not
- + * to bind to a particular device and thus to look at all
- + * devices.
- */
- - if (!device || strcmp(device, "any") == 0) {
- - device = NULL;
- - handle->md.device = strdup("any");
- + if (strcmp(device, "any") == 0) {
- if (handle->opt.promisc) {
- handle->opt.promisc = 0;
- /* Just a warning. */
- @@ -531,10 +535,9 @@ pcap_activate_linux(pcap_t *handle)
- "Promiscuous mode not supported on the \"any\" device");
- status = PCAP_WARNING_PROMISC_NOTSUP;
- }
- + }
-
- - } else
- - handle->md.device = strdup(device);
- -
- + handle->md.device = strdup(device);
- if (handle->md.device == NULL) {
- snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "strdup: %s",
- pcap_strerror(errno) );
- @@ -1657,19 +1660,21 @@ static int
- activate_new(pcap_t *handle)
- {
- #ifdef HAVE_PF_PACKET_SOCKETS
- + const char *device = handle->opt.source;
- + int is_any_device = (strcmp(device, "any") == 0);
- int sock_fd = -1, arptype, val;
- int err = 0;
- struct packet_mreq mr;
- - const char* device = handle->opt.source;
-
- /*
- - * Open a socket with protocol family packet. If a device is
- - * given we try to open it in raw mode otherwise we use
- - * the cooked interface.
- - */
- - sock_fd = device ?
- - socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))
- - : socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_ALL));
- + * Open a socket with protocol family packet. If the
- + * "any" device was specified, we open a SOCK_DGRAM
- + * socket for the cooked interface, otherwise we first
- + * try a SOCK_RAW socket for the raw interface.
- + */
- + sock_fd = is_any_device ?
- + socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_ALL)) :
- + socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
-
- if (sock_fd == -1) {
- snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "socket: %s",
- @@ -1704,7 +1709,7 @@ activate_new(pcap_t *handle)
- * to cooked mode if we have an unknown interface type
- * or a type we know doesn't work well in raw mode.
- */
- - if (device) {
- + if (!is_any_device) {
- /* Assume for now we don't need cooked mode. */
- handle->md.cooked = 0;
-
- @@ -1819,15 +1824,23 @@ activate_new(pcap_t *handle)
- }
- } else {
- /*
- - * This is cooked mode.
- + * The "any" device.
- + */
- + if (handle->opt.rfmon) {
- + /*
- + * It doesn't support monitor mode.
- + */
- + return PCAP_ERROR_RFMON_NOTSUP;
- + }
- +
- + /*
- + * It uses cooked mode.
- */
- handle->md.cooked = 1;
- handle->linktype = DLT_LINUX_SLL;
-
- /*
- * We're not bound to a device.
- - * XXX - true? Or true only if we're using
- - * the "any" device?
- * For now, we're using this as an indication
- * that we can't transmit; stop doing that only
- * if we figure out how to transmit in cooked
- @@ -1852,10 +1865,13 @@ activate_new(pcap_t *handle)
-
- /*
- * Hmm, how can we set promiscuous mode on all interfaces?
- - * I am not sure if that is possible at all.
- + * I am not sure if that is possible at all. For now, we
- + * silently ignore attempts to turn promiscuous mode on
- + * for the "any" device (so you don't have to explicitly
- + * disable it in programs such as tcpdump).
- */
-
- - if (device && handle->opt.promisc) {
- + if (!is_any_device && handle->opt.promisc) {
- memset(&mr, 0, sizeof(mr));
- mr.mr_ifindex = handle->md.ifindex;
- mr.mr_type = PACKET_MR_PROMISC;
- @@ -3118,7 +3134,7 @@ activate_old(pcap_t *handle)
-
- /* Bind to the given device */
-
- - if (!device) {
- + if (strcmp(device, "any") == 0) {
- strncpy(handle->errbuf, "pcap_activate: The \"any\" device isn't supported on 2.0[.x]-kernel systems",
- PCAP_ERRBUF_SIZE);
- return PCAP_ERROR;
|