aboutsummaryrefslogtreecommitdiff
path: root/pcap-linux.c
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2014-03-21 10:57:05 -0700
committerGuy Harris <guy@alum.mit.edu>2014-03-21 10:57:05 -0700
commit8705d011e5ce9fb3f22470382e69d480a2c8d976 (patch)
tree3b8275df9392f00a3c594313fea17c66738c3c3f /pcap-linux.c
parentdbdee5152f2850ce78cf098532293a5abdba5ced (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.c28
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);