Skip to content

Commit d144f8e

Browse files
authored
Merge pull request #99 from amm3/ignore_handshake
Fixes sequence number bugs when running decoders with the ignore_handshake flag
2 parents e4da987 + 4e77d60 commit d144f8e

1 file changed

Lines changed: 44 additions & 24 deletions

File tree

lib/dshell.py

Lines changed: 44 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -637,6 +637,10 @@ def UDP(self, addr, data, pkt, ts=None, **kwargs):
637637
return self.packetHandler(udp=Packet(self, addr, pkt=pkt, ts=ts, **kwargs), data=data)
638638

639639
# if no PacketHandler, we need to track state
640+
if not self.find(addr):
641+
conn = self.track(addr, ts=ts, state='init', **kwargs)
642+
conn.nextoffset['cs'] = 0
643+
conn.nextoffset['sc'] = 0
640644
self.track(addr, data, ts, **kwargs)
641645

642646
except Exception, e:
@@ -705,33 +709,49 @@ def TCP(self, addr, tcp, ts, **kwargs):
705709
self.count += 1
706710

707711
try:
708-
# close connection
712+
# attempt to find an existing connection for this address
709713
conn = self.find(addr)
710-
if tcp.flags & (dpkt.tcp.TH_FIN | dpkt.tcp.TH_RST) and conn:
711-
conn.closeIP(addr[0]) #track if FIN has been seen in connection
712-
if conn and conn.connectionClosed():
713-
# we might occasionally have data in a FIN packet
714-
self.track(addr, str(tcp.data), ts, offset=tcp.seq)
715-
self.close(conn, ts)
716-
# init connection, set TCP ISN
717-
elif not self.ignore_handshake and (tcp.flags == dpkt.tcp.TH_SYN or tcp.flags == dpkt.tcp.TH_SYN | dpkt.tcp.TH_CWR | dpkt.tcp.TH_ECE):
718-
if conn:
719-
self.track(addr, str(tcp.data), ts, offset=tcp.seq)
720-
self.close(conn, ts)
721-
conn = self.track(addr, ts=ts, state='init', **kwargs)
722-
if conn:
714+
715+
if self.ignore_handshake:
716+
# if we are ignoring handshakes, we will track all connections,
717+
# even if we did not see the initialization handshake.
718+
if not conn:
719+
conn = self.track(addr, ts=ts, state='init', **kwargs)
720+
# align the sequence numbers when we first see a connection
721+
if conn.nextoffset['cs'] is None and addr == conn.addr:
723722
conn.nextoffset['cs'] = tcp.seq + 1
724-
# SYN ACK
725-
elif not self.ignore_handshake and tcp.flags == (dpkt.tcp.TH_SYN | dpkt.tcp.TH_ACK):
726-
conn = self.find(addr, state='init')
727-
if conn and tcp.ack == conn.nextoffset['cs']:
723+
elif conn.nextoffset['sc'] is None and addr != conn.addr:
728724
conn.nextoffset['sc'] = tcp.seq + 1
729-
conn.state = 'established'
730-
731-
# all other states, or always if ignoring handshake
732-
if self.ignore_handshake or self.find(addr, state='established'):
733725
self.track(addr, str(tcp.data), ts,
734-
state='established', offset=tcp.seq, **kwargs)
726+
state='established', offset=tcp.seq, **kwargs)
727+
728+
else:
729+
# otherwise, only track connections if we see a TCP handshake
730+
if (tcp.flags == dpkt.tcp.TH_SYN
731+
or tcp.flags == dpkt.tcp.TH_SYN | dpkt.tcp.TH_CWR | dpkt.tcp.TH_ECE):
732+
# SYN
733+
if conn:
734+
# if a connection already exists for the addr,
735+
# close the old one to start fresh
736+
self.close(conn, ts)
737+
conn = self.track(addr, ts=ts, state='init', **kwargs)
738+
if conn:
739+
conn.nextoffset['cs'] = tcp.seq + 1
740+
elif tcp.flags == (dpkt.tcp.TH_SYN | dpkt.tcp.TH_ACK):
741+
# SYN ACK
742+
if conn and tcp.ack == conn.nextoffset['cs']:
743+
conn.nextoffset['sc'] = tcp.seq + 1
744+
conn.state = 'established'
745+
if conn and conn.state == 'established':
746+
self.track(addr, str(tcp.data), ts,
747+
state='established', offset=tcp.seq, **kwargs)
748+
749+
# close connection
750+
if conn and tcp.flags & (dpkt.tcp.TH_FIN | dpkt.tcp.TH_RST):
751+
# flag that an IP is closing a connection with FIN or RST
752+
conn.closeIP(addr[0])
753+
if conn and conn.connectionClosed():
754+
self.close(conn, ts)
735755

736756
except Exception, e:
737757
self._exc(e)
@@ -875,7 +895,7 @@ class Connection(Packet):
875895
def __init__(self, decoder, addr, ts=None, **kwargs):
876896
self.state = None
877897
# the offset we expect for the next blob in this direction
878-
self.nextoffset = {'cs': 0, 'sc': 0}
898+
self.nextoffset = {'cs': None, 'sc': None}
879899
# init IP-level data
880900
Packet.__init__(self, decoder, addr, ts=ts, **kwargs)
881901
self.clientip, self.clientport, self.serverip, self.serverport = (

0 commit comments

Comments
 (0)