[tcpdump-workers] Missing packet fields in big endian with ath9k
Hi all! I'm doing a project of mine. It's about guiding a robot in my living room using wifi. At first I tried to use two raspberry pi with a wifi dongle (ath9k-htc) and libpcap to capture wifi packets and read the rssi from my robot mac address. It works fine. But then I thought in using OpenWRT. Since I was able to get my hands on two cheap TP-LINK MR-3220 (ath9k) I recompiled the code to run on mips. The thing is all the info I gather from the packets are "like misaligned". For example, if I print the mac address's for each packet I get : 11:96:77:3c:38:e7, d8:d8:b2:94:58:98, 35:8e:ad:e4:a0:4a where the mac from the robot is 38:e7:d8:d8:b2:94! And the rest of the bits in the collected packets are also off.. So, the code prints everything fine in the Raspberry Pi (RSSI, type and subtype of frames, etc), why not in openwrt?! My headers go like this: #define EXTRACT_LE_16BITS(p) ((u_int16_t)((u_int16_t) * ((const u_int8_t *)(p) + 1) << 8 | (u_int16_t)*((const u_int8_t *)(p) + 0))) struct sniff_80211 { u_int16_t control[2];//32bit u_int16_t duration; u_char add1[6]; u_char add2[6]; u_char add3[6]; u_int16_t seq; }; typedef struct _mac_header { unsigned char fc[2]; unsigned char id[2]; unsigned char add1[6]; unsigned char add2[6]; unsigned char add3[6]; unsigned char sc[2]; }mac_header; struct frame_control { unsigned protocol :2; unsigned type :2; unsigned subtype :4; unsigned to_ds :1; unsigned from_ds :1; unsigned more_frag :1; unsigned retry :1; unsigned pwr_mgt :1; unsigned more_data :1; unsigned wep :1; unsigned order :1; }; My "logic" is this: pcap_open_live(device->name, 1024, 1, 500, errbuf) For each captured packet with libpcap: pcap_next_ex(adhandle, &header, &data) Do: struct ath_rx_radiotap_header *first = (struct ath_rx_radiotap_header*) (data); int radio_len3 = get_unaligned_le16(&first->wr_ihdr.it_len); cout << radio_len3 << endl; mac_header *p = (mac_header*) (data + radio_len); struct frame_control *c = (struct frame_control*) p->fc; cout << ether_ntoa((struct ether_addr *) p->add1) << " " << ether_ntoa((struct ether_addr *) p->add2) << " " << ether_ntoa((struct ether_addr *) p->add3) << " " << first->wr_antenna << " " << c->type << " " << c->subtype << endl; This prints (with, for example a filter of type data, subtype qos-data): 13 <- radiotap header length 38:e7:d8:d8:b2:94 f8:d1:11:96:77:3c 58:98:35:8e:ad:e4 ? 0 8 <- (this is addr1, addr2, addr3, rssi, type, subtype of captured packet) Notice strange char for rssi value and type 0 subtype 8 where it should be type 2 (data) subtype 8 13 38:e7:d8:d8:b2:94 f8:d1:11:96:77:3c 58:98:35:8e:ad:e4 ? 0 8 34 f8:d1:11:96:77:3c 38:e7:d8:d8:b2:94 58:98:35:8e:ad:e4 ? 0 8 34 f8:d1:11:96:77:3c 38:e7:d8:d8:b2:94 58:98:35:8e:ad:e4 ? 0 8 13 38:e7:d8:d8:b2:94 f8:d1:11:96:77:3c 58:98:35:8e:ad:e4 ? 0 8 13 38:e7:d8:d8:b2:94 f8:d1:11:96:77:3c 58:98:35:8e:ad:e4 ? 0 8 34 f8:d1:11:96:77:3c 38:e7:d8:d8:b2:94 58:98:35:8e:ad:e4 ? 0 8 What could be wrong in openwrt that isn't on the raspberry pi?! Is it the little endian of raspberry vs the big endian of the uplink ? If so how can I get the info I want? (rssi, type and subtype of packet)? Thanks for any help! I've been scratching my head for days now.. PS: maybe this question doesn't belong here, but I can't get help anywhere else.. Again, thanks in advance. ___ tcpdump-workers mailing list tcpdump-workers@lists.tcpdump.org https://lists.sandelman.ca/mailman/listinfo/tcpdump-workers
Re: [tcpdump-workers] Missing packet fields in big endian with ath9k
Hi Michael, thnks for replying. I check for link type this way: (pcap_datalink(dev_handler) == DLT_IEEE802_11) , So i'm pretty sure its the right data link. Unless pcap_datalink() is broken.. Meanwhile I've media some progress by looking at iwcap (https://dev.openwrt.org/browser/trunk/package/iwcap/src/iwcap.c?rev=30747) specifically, by using #define FRAMETYPE_MASK 0xFC #define FRAMETYPE_BEACON 0x80 #define FRAMETYPE_DATA 0x08 #define FRAMETYPE_PROBREQ 0x40 and testing with this: u8 frametype = *(u8 *)(data + radio_len); if ((frametype & FRAMETYPE_MASK) == FRAMETYPE_PROBREQ) { cout << "len: " << radio_len << endl; cout << ether_ntoa((struct ether_addr *) p->add1) << " " << ether_ntoa((struct ether_addr *) p->add2) << " " << ether_ntoa((struct ether_addr *) p->add3) << endl; } I manage to print the packets I'm interested in. However I still can't access the RSSI value of the packet.. Is it the [byte data] & FRAMETYPE_MASK (0xFC) logic operation that does the "magic"? I don't have enough knowledge to understand what the operation does.. Do you have and care to explain? If I type cast the radio tap struct and do the same thin on the rssi field ( ssi_signal & FRAMETYPE_MASK) does the result equals the rssi signal in decimal?! Thnks in advance On Apr 26, 2013, at 7:16 PM, Michael Richardson wrote: > > It sounds like you are not taking into account the link type. > EN10B and LINUX encapsulations are different. "tcpdump" without any > arguments listens on "any" interface, which is a cooked "LINUX" > encapsulation. I' doubt that the one on openwrt does the same thing. > > -- > ] Never tell me the odds! | ipv6 mesh networks > [ > ] Michael Richardson, Sandelman Software Works| network architect > [ > ] m...@sandelman.ca http://www.sandelman.ca/| ruby on rails > [ > ___ tcpdump-workers mailing list tcpdump-workers@lists.tcpdump.org https://lists.sandelman.ca/mailman/listinfo/tcpdump-workers
Re: [tcpdump-workers] Missing packet fields in big endian with ath9k
Hi Harris, thnks for your help. On Apr 27, 2013, at 2:03 AM, Guy Harris wrote: > > On Apr 26, 2013, at 11:50 AM, Luis Correia wrote: > >> I check for link type this way: >> (pcap_datalink(dev_handler) ==DLT_IEEE802_11) , >> So i'm pretty sure its the right data link. > > DLT_IEEE802_11 is the *wrong* data link if you're getting a radiotap header > in your packets, as you seem to indicate below! If you're getting a radiotap > header, and pcap_datalink(dev_handler) == DLT_IEEE802_11, the driver for your > network adapter is buggy - it's returning ARPHRD_IEEE80211 when it should be > returning ARPHRD_IEEE80211_RADIOTAP. Im getting DLT_IEEE802_11_RADIO. Is this ok? > >> Meanwhile I've media some progress by looking at iwcap >> (https://dev.openwrt.org/browser/trunk/package/iwcap/src/iwcap.c?rev=30747) > > What happens if you try to run iwcap on that interface? I'll run iwcap to see what happens. > >> However I still can't access the RSSI value of the packet.. About the rssi values I managed to get them by teaching myself little endian vs big endian and redefining my struct's fields. I'm now getting correct rssi values almost every time. (Negative, distance coherent..) However sometimes I see packets with positive values!! I'm debugging that.. PS: If I'm not mistaken aren't you the guy that wrote libpcap?! If so, Congrats on you're work! > > If you're getting packets without a radio header (which is what > DLT_IEEE802_11 would imply), there's no place to get the RSSI from. > > If you're getting packets with a radiotap header (which is what > DLT_IEEE802_11_RADIO would imply), the only way to get the RSSI is if the > driver is violating the radiotap spec, because the only mention of RSSI at > > http://www.radiotap.org > > is > > http://www.radiotap.org/suggested-fields/RSSI > > and, as they say, the presence-bit value picked by OpenBSD clashes with an > officially assigned value for a different field. > > You might, however, be able to get signal and noise levels, *if* the driver > supplies them (just because a given value *can* be supplied in a radiotap > header doesn't mean that a given driver *will* supply it): > > http://www.radiotap.org/defined-fields/Antenna%20signal > > http://www.radiotap.org/defined-fields/Antenna%20noise > > http://www.radiotap.org/defined-fields/dB%20antenna%20signal > > http://www.radiotap.org/defined-fields/dB%20antenna%20noise ___ tcpdump-workers mailing list tcpdump-workers@lists.tcpdump.org https://lists.sandelman.ca/mailman/listinfo/tcpdump-workers