Question

I am capturing packets over 3G on Android and I get an output that is bizarre. I see mac addresses instead of IP addresses and have no clue how to decode it. I see the IP addresses when I run the same capture over WIFI. It appears as if the link type needs to be changed for 3G interface.

Currently, I only see "EN10MB (Ethernet)" option under the list of Data link types (tcpdump -L). I see different link types on tcpdump website (http://www.tcpdump.org/linktypes.html) and I think probably I somehow need to recompile the source, so that I get "LINKTYPE_GPRS_LLC" under Data link types to get the right capture.

Does anyone know how to do this? I have the source for libpcap (v0.9.8) and tcpdump (v3.9.8) (one that comes along with AOSP 4.2.1 source).

Thanks and I really look forward to hear from you guys.

Here is a sample output that I get for a capture over 3G interface:

ping google.com

tcpdump -vvvs 0

22:11:51.450906 40:00:40:11:12:18 (oui Unknown) > 45:00:00:38:66:22 (oui Unknown), ethertype Unknown (0x1528), length 56: 0x0000: 4a4b 4201 2107 bad2 0035 0024 5a5e 140c JKB.!.��.5.$Z^.. 0x0010: 0100 0001 0000 0000 0000 0667 6f6f 676c ...........googl 0x0020: 6503 636f 6d00 0001 0001 e.com.....

22:11:52.363748 00:00:fd:11:0c:9c (oui Unknown) > 45:00:00:e8:ed:ed (oui Unknown), ethertype Unknown (0x4201), length 232:

Was it helpful?

Solution

So, here's what solved the problem.

Looks like when we explicitly specify the interface name (cdma_rmnet4 in my case) or do not specify any interface (in this case it automatically assumes the interface to be cdma_rmnet4), it gives the same garbled output.

But when we capture it with “-i any” flag, it does capture on some “LINUX_SLL” interface, which gives the correct output. I googled it and found out that LINUX_SLL is Linux cooked mode capture by libpcap to capture from the "any" device and to capture on some devices where the native link layer header isn't available or can't be used, which is the case with 3G/mobile packets.

OTHER TIPS

If by "Currently, I only see "EN10MB (Ethernet)" option under the list of Data link types (tcpdump -L)." you mean that, when you run tcpdump -L, that means that, on the interface on which you're capturing, the only link-layer header type it claims that it can supply are Ethernet headers.

If that's what it's supplying, tcpdump should be reporting the right packet data.

If that's not what it's supplying, then the driver or networking stack on the version of the Linux kernel your mobile phone/tablet is running is broken - it's supplying the wrong ARPHRD_ value to libpcap, which is then passing that lie on to tcpdump or whatever other program is using libpcap.

The best way to fix this would be to fix the driver or whatever is supplying ARPHRD_ETHER. Unfortunately, a quick look at the 3.11 kernel's include/uapi/linux/if_arp.h doesn't show an ARPHRD_ value that appears to be intended for this.

Note, however, that this is NOT necessarily LINKTYPE_GPRS_LLC! That LINKTYPE_ value is for GPRS LLC frames, as described in 3GPP TS 04.64; those can encapsulate Subnetwork Dependent Convergence Protocol frames, which can encapsulate IP frames (at least according to the Wireshark dissector for GPRS LLC frames), but Android might be using some completely different link-layer headers. GPRS is NOT a 3G service; I think 3G data uses a different link layer.

Tcpdump does not know how to dissect GPRS LLC frames, so, IF that's what the driver is supplying, that wouldn't help without changes to tcpdump to understand GPRS LLC and the Subnetwork Dependent Convergence Protocol.

A quick look at tcpdump's output, and at this similar Wireshark question, suggests that the link-layer type might be LINKTYPE_RAW - the first octet of an Ethernet frame is the first octet of the destination address, so it appears that the first octet of those frames is 0x45, which is also the value that the first octet of an IPv4 frame without options would have (IP version 4, header length 5 32-bit words or 20 bytes).

Try, as an experiment, a version of tcpdump that treats DLT_EN10MB as if it were DLT_RAW; if that works with the 3G interface, then either the drivers or networking stack need to be changed to supply ARPHRD_NONE to libpcap or libpcap needs to look at the device name and, for the Android device or devices in question, map ARPHRD_ETHER to DLT_RAW rather than DLT_EN10MB. What's the name of the device on which you're capturing, i.e., the argument to the -i flag? If you didn't pass an argument to -i, what is the output of ifconfig -a on Android?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top