diff options
author | Guy Harris <guy@alum.mit.edu> | 2014-03-21 10:57:05 -0700 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2014-03-21 10:57:05 -0700 |
commit | 8705d011e5ce9fb3f22470382e69d480a2c8d976 (patch) | |
tree | 3b8275df9392f00a3c594313fea17c66738c3c3f /pcap-linux.c | |
parent | dbdee5152f2850ce78cf098532293a5abdba5ced (diff) |
Work around annoying Android problem.
For various annoying reasons having to do with DHCP software, some
versions of Android give the mobile-phone-network interface an ARPHRD_
value of ARPHRD_ETHER, even though the packet supplied by that interface
have no link-layer header, and begin with an IP header, so that the
ARPHRD_ value should be ARPHRD_NONE.
Detect those devices by checking the device name, and use DLT_RAW for them.
Diffstat (limited to 'pcap-linux.c')
-rw-r--r-- | pcap-linux.c | 28 |
1 files changed, 24 insertions, 4 deletions
diff --git a/pcap-linux.c b/pcap-linux.c index a15a8b1f..4ef0eedb 100644 --- a/pcap-linux.c +++ b/pcap-linux.c @@ -316,7 +316,7 @@ struct pcap_linux { /* * Prototypes for internal functions and methods. */ -static void map_arphrd_to_dlt(pcap_t *, int, int); +static void map_arphrd_to_dlt(pcap_t *, int, const char *, int); #ifdef HAVE_PF_PACKET_SOCKETS static short int map_packet_type_to_sll_type(short int); #endif @@ -2556,12 +2556,32 @@ map_packet_type_to_sll_type(short int sll_pkttype) * * Sets the link type to -1 if unable to map the type. */ -static void map_arphrd_to_dlt(pcap_t *handle, int arptype, int cooked_ok) +static void map_arphrd_to_dlt(pcap_t *handle, int arptype, const char *device, + int cooked_ok) { + static const char cdma_rmnet[] = "cdma_rmnet"; + switch (arptype) { case ARPHRD_ETHER: /* + * For various annoying reasons having to do with DHCP + * software, some versions of Android give the mobile- + * phone-network interface an ARPHRD_ value of + * ARPHRD_ETHER, even though the packet supplied by + * that interface have no link-layer header, and begin + * with an IP header, so that the ARPHRD_ value should + * be ARPHRD_NONE. + * + * Detect those devices by checking the device name, and + * use DLT_RAW for them. + */ + if (strncmp(device, cdma_rmnet, sizeof cdma_rmnet - 1) == 0) { + handle->linktype = DLT_RAW; + return; + } + + /* * This is (presumably) a real Ethernet capture; give it a * link-layer-type list with DLT_EN10MB and DLT_DOCSIS, so * that an application can let you choose it, in case you're @@ -3074,7 +3094,7 @@ activate_new(pcap_t *handle) close(sock_fd); return arptype; } - map_arphrd_to_dlt(handle, arptype, 1); + map_arphrd_to_dlt(handle, arptype, device, 1); if (handle->linktype == -1 || handle->linktype == DLT_LINUX_SLL || handle->linktype == DLT_LINUX_IRDA || @@ -5575,7 +5595,7 @@ activate_old(pcap_t *handle) * Try to find the DLT_ type corresponding to that * link-layer type. */ - map_arphrd_to_dlt(handle, arptype, 0); + map_arphrd_to_dlt(handle, arptype, device, 0); if (handle->linktype == -1) { snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "unknown arptype %d", arptype); |