Properly assign ACK and CTS packets to the right TA.
diff --git a/app.py b/app.py
index 309d60c..d727a0b 100644
--- a/app.py
+++ b/app.py
@@ -193,13 +193,13 @@
for i, (p, frame) in enumerate(wifipacket.Packetize(reader)):
if not timebase: timebase = p.pcap_secs
ta = p.get('ta')
+ ra = p.get('ra')
if ta not in show_hosts and aliases.get(ta) not in show_hosts:
- ta = '~other' # '~' causes it to sort last in the list
+ ta = ra = '~other' # '~' causes it to sort last in the list
elif ta in aliases:
ta = aliases[ta]
- ra = p.get('ra')
if ra not in show_hosts and aliases.get(ra) not in show_hosts:
- ra = '~other' # '~' causes it to sort last in the list
+ ta = ra = '~other' # '~' causes it to sort last in the list
elif ra in aliases:
ra = aliases[ra]
out[(ta,ra)].append(('%.6f' % (p.pcap_secs - timebase),
@@ -211,9 +211,10 @@
for sesskey in sessions:
ta, ra = sesskey
for k in keys:
- if ta.startswith('~'): ta = ta[1:]
- if ra.startswith('~'): ra = ra[1:]
- headers.append('%s to %s (%s)' % (ta, ra, k))
+ if ta == '~other' and ra == '~other':
+ headers.append('other (%s)' % (k,))
+ else:
+ headers.append('%s to %s (%s)' % (ta, ra, k))
for secs, values in out[sesskey]:
data.append([secs] + extra + list(values))
extra += [None] * len(keys)
diff --git a/wifipacket.py b/wifipacket.py
index 57ffb37..240ea13 100755
--- a/wifipacket.py
+++ b/wifipacket.py
@@ -231,6 +231,8 @@
if network != LINKTYPE_IEEE802_11_RADIOTAP:
raise ValueError('unexpected tcpdump network type %r' % network)
+ last_ta = None
+ last_ra = None
while 1:
opt = Struct({})
@@ -314,11 +316,26 @@
opt.seq = (seq & 0xfff0) >> 4
opt.frag = (seq & 0x000f)
ofs += 2
- else:
+ else: # ta, ra, xa
if len(frame) < ofs + 6: break
opt[fieldname] = MacAddr(frame[ofs:ofs + 6])
ofs += 6
+ # ACK and CTS packets omit TA field for efficiency, so we have to fill
+ # it in from the previous packet's RA field. We can check that the
+ # new packet's RA == the previous packet's TA, just to make sure we're
+ # not lying about it.
+ if not opt.get('ta'):
+ if (last_ta and last_ra
+ and last_ta == opt.get('ra')
+ and last_ra != opt.get('ra')):
+ opt['ta'] = last_ra
+ last_ta = None
+ last_ra = None
+ else:
+ last_ta = opt.get('ta')
+ last_ra = opt.get('ra')
+
yield opt, frame