Skip to content

Commit 1350ca2

Browse files
authored
Merge pull request #1212 from guedou/plist_ipv6
PacketList: sessions() and conversations() IPv6 support
2 parents c2acc60 + 7eebded commit 1350ca2

2 files changed

Lines changed: 35 additions & 10 deletions

File tree

scapy/plist.py

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -297,8 +297,11 @@ def conversations(self, getsrcdst=None,**kargs):
297297
prog: which graphviz program to use"""
298298
if getsrcdst is None:
299299
def getsrcdst(pkt):
300+
"""Extract src and dst addresses"""
300301
if 'IP' in pkt:
301302
return (pkt['IP'].src, pkt['IP'].dst)
303+
if 'IPv6' in pkt:
304+
return (pkt['IPv6'].src, pkt['IPv6'].dst)
302305
if 'ARP' in pkt:
303306
return (pkt['ARP'].psrc, pkt['ARP'].pdst)
304307
raise TypeError()
@@ -482,22 +485,32 @@ def sr(self,multi=0):
482485
def sessions(self, session_extractor=None):
483486
if session_extractor is None:
484487
def session_extractor(p):
485-
sess = "Other"
488+
"""Extract sessions from packets"""
486489
if 'Ether' in p:
487-
if 'IP' in p:
490+
if 'IP' in p or 'IPv6' in p:
491+
ip_src_fmt = "{IP:%IP.src%}{IPv6:%IPv6.src%}"
492+
ip_dst_fmt = "{IP:%IP.dst%}{IPv6:%IPv6.dst%}"
493+
addr_fmt = (ip_src_fmt, ip_dst_fmt)
488494
if 'TCP' in p:
489-
sess = p.sprintf("TCP %IP.src%:%r,TCP.sport% > %IP.dst%:%r,TCP.dport%")
495+
fmt = "TCP {}:%r,TCP.sport% > {}:%r,TCP.dport%"
490496
elif 'UDP' in p:
491-
sess = p.sprintf("UDP %IP.src%:%r,UDP.sport% > %IP.dst%:%r,UDP.dport%")
497+
fmt = "UDP {}:%r,UDP.sport% > {}:%r,UDP.dport%"
492498
elif 'ICMP' in p:
493-
sess = p.sprintf("ICMP %IP.src% > %IP.dst% type=%r,ICMP.type% code=%r,ICMP.code% id=%ICMP.id%")
499+
fmt = "ICMP {} > {} type=%r,ICMP.type% code=%r," \
500+
"ICMP.code% id=%ICMP.id%"
501+
elif 'ICMPv6' in p:
502+
fmt = "ICMPv6 {} > {} type=%r,ICMPv6.type% " \
503+
"code=%r,ICMPv6.code%"
504+
elif 'IPv6' in p:
505+
fmt = "IPv6 {} > {} nh=%IPv6.nh%"
494506
else:
495-
sess = p.sprintf("IP %IP.src% > %IP.dst% proto=%IP.proto%")
507+
fmt = "IP {} > {} proto=%IP.proto%"
508+
return p.sprintf(fmt.format(*addr_fmt))
496509
elif 'ARP' in p:
497-
sess = p.sprintf("ARP %ARP.psrc% > %ARP.pdst%")
510+
return p.sprintf("ARP %ARP.psrc% > %ARP.pdst%")
498511
else:
499-
sess = p.sprintf("Ethernet type=%04xr,Ether.type%")
500-
return sess
512+
return p.sprintf("Ethernet type=%04xr,Ether.type%")
513+
return "Other"
501514
sessions = defaultdict(self.__class__)
502515
for p in self.res:
503516
sess = session_extractor(self._elt2pkt(p))

test/regression.uts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9978,12 +9978,24 @@ def test_conversations(mock_do_graph):
99789978
mock_do_graph.side_effect = fake_do_graph
99799979
plist = PacketList([IP(dst="127.0.0.2")/TCP(dport=i) for i in range(2)])
99809980
plist.extend([IP(src="127.0.0.2")/TCP(sport=i) for i in range(2)])
9981+
plist.extend([IPv6(dst="::2", src="::1")/TCP(sport=i) for i in range(2)])
9982+
plist.extend([IPv6(src="::2", dst="::1")/TCP(sport=i) for i in range(2)])
9983+
plist.extend([Ether()/ARP(pdst="127.0.0.1")])
99819984
result_conversations = plist.conversations()
9982-
assert(len(result_conversations.split('\n')) == 5)
9985+
assert(len(result_conversations.split('\n')) == 8)
99839986
assert(result_conversations.startswith('digraph "conv" {'))
9987+
assert("127.0.0.1" in result_conversations)
9988+
assert("::1" in result_conversations)
99849989

99859990
test_conversations()
99869991

9992+
= sessions()
9993+
9994+
pl = PacketList([Ether()/IPv6()/ICMPv6EchoRequest(), Ether()/IPv6()/IPv6()])
9995+
pl.extend([Ether()/IP()/IP(), Ether()/ARP()])
9996+
pl.extend([Ether()/Ether()/IP()])
9997+
assert(len(pl.sessions().keys()) == 5)
9998+
99879999
= afterglow()
998810000

998910001
import mock

0 commit comments

Comments
 (0)