|
Line
Link Here
|
|
Fix the handling of the "any" device, including making it reject |
|
Fix the handling of the "any" device, including making it reject |
| 1 |
attempts to open it in monitor mode. |
1 |
attempts to open it in monitor mode. |
| 2 |
-- |
|
|
| 3 |
pcap-linux.c | 68 ++++++++++++++++++++++++++++++++++++----------------------- |
2 |
pcap-linux.c | 68 ++++++++++++++++++++++++++++++++++++----------------------- |
| 4 |
1 file changed, 42 insertions(+), 26 deletions(-) |
3 |
1 file changed, 42 insertions(+), 26 deletions(-) |
| 5 |
-- a/pcap-linux.c |
4 |
++ b/pcap-linux.c |
|
Lines 297-302
Link Here
|
| 297 |
{ |
297 |
{ |
| 298 |
pcap_t *handle; |
298 |
pcap_t *handle; |
| 299 |
|
299 |
|
|
|
300 |
/* |
| 301 |
* A null device name is equivalent to the "any" device. |
| 302 |
*/ |
| 303 |
if (device == NULL) |
| 304 |
device = "any"; |
| 305 |
|
| 300 |
#ifdef HAVE_DAG_API |
306 |
#ifdef HAVE_DAG_API |
| 301 |
if (strstr(device, "dag")) { |
307 |
if (strstr(device, "dag")) { |
| 302 |
return dag_create(device, ebuf); |
308 |
return dag_create(device, ebuf); |
|
Lines 338-347
Link Here
|
| 338 |
struct iwreq ireq; |
344 |
struct iwreq ireq; |
| 339 |
#endif |
345 |
#endif |
| 340 |
|
346 |
|
| 341 |
if (p->opt.source == NULL) { |
347 |
if (strcmp(p->opt.source, "any") == 0) { |
| 342 |
/* |
348 |
/* |
| 343 |
* This is equivalent to the "any" device, and we don't |
349 |
* Monitor mode makes no sense on the "any" device. |
| 344 |
* support monitor mode on it. |
|
|
| 345 |
*/ |
350 |
*/ |
| 346 |
return 0; |
351 |
return 0; |
| 347 |
} |
352 |
} |
|
Lines 518-529
Link Here
|
| 518 |
handle->stats_op = pcap_stats_linux; |
523 |
handle->stats_op = pcap_stats_linux; |
| 519 |
|
524 |
|
| 520 |
/* |
525 |
/* |
| 521 |
* NULL and "any" are special devices which give us the hint to |
526 |
* The "any" device is a special device which causes us not |
| 522 |
* monitor all devices. |
527 |
* to bind to a particular device and thus to look at all |
|
|
528 |
* devices. |
| 523 |
*/ |
529 |
*/ |
| 524 |
if (!device || strcmp(device, "any") == 0) { |
530 |
if (strcmp(device, "any") == 0) { |
| 525 |
device = NULL; |
|
|
| 526 |
handle->md.device = strdup("any"); |
| 527 |
if (handle->opt.promisc) { |
531 |
if (handle->opt.promisc) { |
| 528 |
handle->opt.promisc = 0; |
532 |
handle->opt.promisc = 0; |
| 529 |
/* Just a warning. */ |
533 |
/* Just a warning. */ |
|
Lines 531-540
Link Here
|
| 531 |
"Promiscuous mode not supported on the \"any\" device"); |
535 |
"Promiscuous mode not supported on the \"any\" device"); |
| 532 |
status = PCAP_WARNING_PROMISC_NOTSUP; |
536 |
status = PCAP_WARNING_PROMISC_NOTSUP; |
| 533 |
} |
537 |
} |
|
|
538 |
} |
| 534 |
|
539 |
|
| 535 |
} else |
540 |
handle->md.device = strdup(device); |
| 536 |
handle->md.device = strdup(device); |
|
|
| 537 |
|
| 538 |
if (handle->md.device == NULL) { |
541 |
if (handle->md.device == NULL) { |
| 539 |
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "strdup: %s", |
542 |
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "strdup: %s", |
| 540 |
pcap_strerror(errno) ); |
543 |
pcap_strerror(errno) ); |
|
Lines 1657-1675
Link Here
|
| 1657 |
activate_new(pcap_t *handle) |
1660 |
activate_new(pcap_t *handle) |
| 1658 |
{ |
1661 |
{ |
| 1659 |
#ifdef HAVE_PF_PACKET_SOCKETS |
1662 |
#ifdef HAVE_PF_PACKET_SOCKETS |
|
|
1663 |
const char *device = handle->opt.source; |
| 1664 |
int is_any_device = (strcmp(device, "any") == 0); |
| 1660 |
int sock_fd = -1, arptype, val; |
1665 |
int sock_fd = -1, arptype, val; |
| 1661 |
int err = 0; |
1666 |
int err = 0; |
| 1662 |
struct packet_mreq mr; |
1667 |
struct packet_mreq mr; |
| 1663 |
const char* device = handle->opt.source; |
|
|
| 1664 |
|
1668 |
|
| 1665 |
/* |
1669 |
/* |
| 1666 |
* Open a socket with protocol family packet. If a device is |
1670 |
* Open a socket with protocol family packet. If the |
| 1667 |
* given we try to open it in raw mode otherwise we use |
1671 |
* "any" device was specified, we open a SOCK_DGRAM |
| 1668 |
* the cooked interface. |
1672 |
* socket for the cooked interface, otherwise we first |
| 1669 |
*/ |
1673 |
* try a SOCK_RAW socket for the raw interface. |
| 1670 |
sock_fd = device ? |
1674 |
*/ |
| 1671 |
socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)) |
1675 |
sock_fd = is_any_device ? |
| 1672 |
: socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_ALL)); |
1676 |
socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_ALL)) : |
|
|
1677 |
socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); |
| 1673 |
|
1678 |
|
| 1674 |
if (sock_fd == -1) { |
1679 |
if (sock_fd == -1) { |
| 1675 |
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "socket: %s", |
1680 |
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "socket: %s", |
|
Lines 1704-1710
Link Here
|
| 1704 |
* to cooked mode if we have an unknown interface type |
1709 |
* to cooked mode if we have an unknown interface type |
| 1705 |
* or a type we know doesn't work well in raw mode. |
1710 |
* or a type we know doesn't work well in raw mode. |
| 1706 |
*/ |
1711 |
*/ |
| 1707 |
if (device) { |
1712 |
if (!is_any_device) { |
| 1708 |
/* Assume for now we don't need cooked mode. */ |
1713 |
/* Assume for now we don't need cooked mode. */ |
| 1709 |
handle->md.cooked = 0; |
1714 |
handle->md.cooked = 0; |
| 1710 |
|
1715 |
|
|
Lines 1819-1833
Link Here
|
| 1819 |
} |
1824 |
} |
| 1820 |
} else { |
1825 |
} else { |
| 1821 |
/* |
1826 |
/* |
| 1822 |
* This is cooked mode. |
1827 |
* The "any" device. |
|
|
1828 |
*/ |
| 1829 |
if (handle->opt.rfmon) { |
| 1830 |
/* |
| 1831 |
* It doesn't support monitor mode. |
| 1832 |
*/ |
| 1833 |
return PCAP_ERROR_RFMON_NOTSUP; |
| 1834 |
} |
| 1835 |
|
| 1836 |
/* |
| 1837 |
* It uses cooked mode. |
| 1823 |
*/ |
1838 |
*/ |
| 1824 |
handle->md.cooked = 1; |
1839 |
handle->md.cooked = 1; |
| 1825 |
handle->linktype = DLT_LINUX_SLL; |
1840 |
handle->linktype = DLT_LINUX_SLL; |
| 1826 |
|
1841 |
|
| 1827 |
/* |
1842 |
/* |
| 1828 |
* We're not bound to a device. |
1843 |
* We're not bound to a device. |
| 1829 |
* XXX - true? Or true only if we're using |
|
|
| 1830 |
* the "any" device? |
| 1831 |
* For now, we're using this as an indication |
1844 |
* For now, we're using this as an indication |
| 1832 |
* that we can't transmit; stop doing that only |
1845 |
* that we can't transmit; stop doing that only |
| 1833 |
* if we figure out how to transmit in cooked |
1846 |
* if we figure out how to transmit in cooked |
|
Lines 1852-1861
Link Here
|
| 1852 |
|
1865 |
|
| 1853 |
/* |
1866 |
/* |
| 1854 |
* Hmm, how can we set promiscuous mode on all interfaces? |
1867 |
* Hmm, how can we set promiscuous mode on all interfaces? |
| 1855 |
* I am not sure if that is possible at all. |
1868 |
* I am not sure if that is possible at all. For now, we |
|
|
1869 |
* silently ignore attempts to turn promiscuous mode on |
| 1870 |
* for the "any" device (so you don't have to explicitly |
| 1871 |
* disable it in programs such as tcpdump). |
| 1856 |
*/ |
1872 |
*/ |
| 1857 |
|
1873 |
|
| 1858 |
if (device && handle->opt.promisc) { |
1874 |
if (!is_any_device && handle->opt.promisc) { |
| 1859 |
memset(&mr, 0, sizeof(mr)); |
1875 |
memset(&mr, 0, sizeof(mr)); |
| 1860 |
mr.mr_ifindex = handle->md.ifindex; |
1876 |
mr.mr_ifindex = handle->md.ifindex; |
| 1861 |
mr.mr_type = PACKET_MR_PROMISC; |
1877 |
mr.mr_type = PACKET_MR_PROMISC; |
|
Lines 3118-3124
Link Here
|
| 3118 |
|
3134 |
|
| 3119 |
/* Bind to the given device */ |
3135 |
/* Bind to the given device */ |
| 3120 |
|
3136 |
|
| 3121 |
if (!device) { |
3137 |
if (strcmp(device, "any") == 0) { |
| 3122 |
strncpy(handle->errbuf, "pcap_activate: The \"any\" device isn't supported on 2.0[.x]-kernel systems", |
3138 |
strncpy(handle->errbuf, "pcap_activate: The \"any\" device isn't supported on 2.0[.x]-kernel systems", |
| 3123 |
PCAP_ERRBUF_SIZE); |
3139 |
PCAP_ERRBUF_SIZE); |
| 3124 |
return PCAP_ERROR; |
3140 |
return PCAP_ERROR; |