add a ICMP_Resequence and make Packet and Session tolerant of port-less protocols

N.B.: ICMP_Resequence doesn't resequence anything; however, it packages the frames
in a TCP_Resequence-compatible way
This commit is contained in:
pi-rho 2013-02-15 12:59:57 -06:00
parent 2df1ccd4af
commit eda1d70d4d
1 changed files with 33 additions and 15 deletions

View File

@ -457,6 +457,19 @@ class TCP_Resequence(object):
hexdump(pkt.payload) hexdump(pkt.payload)
class ICMP_Resequence(object):
"""ICMP session resequencer"""
def __init__(self):
self.cli = None
def handle(self, frame):
if not self.cli:
self.cli = frame.saddr
idx = 1 - (self.cli == frame.saddr)
return (idx, frame, gapstr.GapString(frame.payload))
class Dispatch(object): class Dispatch(object):
def __init__(self, *filenames): def __init__(self, *filenames):
self.pcs = {} self.pcs = {}
@ -490,22 +503,27 @@ class Dispatch(object):
if f: if f:
heapq.heappush(self.tops, (f, pc, filename, fd, pos)) heapq.heappush(self.tops, (f, pc, filename, fd, pos))
def _get_sequencer(self, proto):
if proto == TCP:
return TCP_Resequence()
elif proto == ICMP:
return ICMP_Resequence()
else:
raise NotImplementedError()
def __iter__(self): def __iter__(self):
while self.tops: while self.tops:
f, pc, filename, fd, pos = heapq.heappop(self.tops) f, pc, filename, fd, pos = heapq.heappop(self.tops)
if not self.last: if not self.last:
self.last = (filename, pos) self.last = (filename, pos)
frame = Frame(f) frame = Frame(f, pc.linktype)
if frame.protocol == TCP: if frame.hash not in self.sessions:
# compute TCP session hash self.sessions[frame.hash] = self._get_sequencer(frame.protocol)
tcp_sess = self.sessions.get(frame.hash) ret = self.sessions[frame.hash].handle(frame)
if not tcp_sess:
tcp_sess = TCP_Resequence()
self.sessions[frame.hash] = tcp_sess
ret = tcp_sess.handle(frame)
if ret: if ret:
yield frame.hash, ret yield frame.hash, ret
self.last = None self.last = None
self._read(pc, filename, fd) self._read(pc, filename, fd)
@ -585,9 +603,9 @@ class Packet(UserDict.DictMixin):
self.opcode_desc) self.opcode_desc)
if self.firstframe: if self.firstframe:
print ' %s:%d -> %s:%d (%s.%06dZ)' % (self.firstframe.src_addr, print ' %s:%d -> %s:%d (%s.%06dZ)' % (self.firstframe.src_addr,
self.firstframe.sport, self.firstframe.sport or 0,
self.firstframe.dst_addr, self.firstframe.dst_addr,
self.firstframe.dport, self.firstframe.dport or 0,
time.strftime('%Y-%m-%dT%T', time.gmtime(self.firstframe.time)), time.strftime('%Y-%m-%dT%T', time.gmtime(self.firstframe.time)),
self.firstframe.time_usec) self.firstframe.time_usec)
@ -770,8 +788,8 @@ class Session(object):
def open_out(self, fn, text=True): def open_out(self, fn, text=True):
frame = self.firstframe frame = self.firstframe
fn = '%d-%s~%d-%s~%d---%s' % (frame.time, fn = '%d-%s~%d-%s~%d---%s' % (frame.time,
frame.src_addr, frame.sport, frame.src_addr, frame.sport or 0,
frame.dst_addr, frame.dport, frame.dst_addr, frame.dport or 0,
urllib.quote(fn, '')) urllib.quote(fn, ''))
fullfn = os.path.join(self.basename, fn) fullfn = os.path.join(self.basename, fn)
fullfn2 = os.path.join(self.basename2, fn) fullfn2 = os.path.join(self.basename2, fn)