13e4ead4b7b6d9ae5ac4b4cf4c1333a116f8a2d15Phil## This file is part of Scapy 23e4ead4b7b6d9ae5ac4b4cf4c1333a116f8a2d15Phil## See http://www.secdev.org/projects/scapy for more informations 33e4ead4b7b6d9ae5ac4b4cf4c1333a116f8a2d15Phil## Copyright (C) Philippe Biondi <phil@secdev.org> 43e4ead4b7b6d9ae5ac4b4cf4c1333a116f8a2d15Phil## This program is published under a GPLv2 license 53e4ead4b7b6d9ae5ac4b4cf4c1333a116f8a2d15Phil 60ce149b41a10223c75f33a135d0a7ddc6bd2e022Dirk Loss""" 70ce149b41a10223c75f33a135d0a7ddc6bd2e022Dirk LossPacketList: holds several packets and allows to do operations on them. 80ce149b41a10223c75f33a135d0a7ddc6bd2e022Dirk Loss""" 90ce149b41a10223c75f33a135d0a7ddc6bd2e022Dirk Loss 100ce149b41a10223c75f33a135d0a7ddc6bd2e022Dirk Loss 1122a55b62eb35e8611fe03b99e4ff4f257a97b5d1gpotterfrom __future__ import absolute_import 12b72a0b59db7b6fa0726ffa22da3b88679bffe69cgpotterfrom __future__ import print_function 1360f945fd1bc6b8d4ef561d1eb17c327ecc3c954bDirk Lossimport os,subprocess 14f13602150438b4afd00a46f1dafb4062369cc835Philfrom collections import defaultdict 15bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil 166057906368d55634d11e1d19a5cca1f127595b11Robin Jarryfrom scapy.config import conf 176057906368d55634d11e1d19a5cca1f127595b11Robin Jarryfrom scapy.base_classes import BasePacket,BasePacketList 186057906368d55634d11e1d19a5cca1f127595b11Robin Jarryfrom scapy.utils import do_graph,hexdump,make_table,make_lined_table,make_tex_table,get_temp_file 19e02f12feef2f5bf68e1632f01ef3ab6192d35bbbPhil 20431b04a95da67282a59bdf0a1898e106b18814d0gpotterfrom scapy.consts import plt, MATPLOTLIB_INLINED, MATPLOTLIB_DEFAULT_PLOT_KARGS 21d51edef8530fe1e944f13eb65ef863c2d7f04b1dgpotterfrom functools import reduce 2222a55b62eb35e8611fe03b99e4ff4f257a97b5d1gpotterimport scapy.modules.six as six 2322a55b62eb35e8611fe03b99e4ff4f257a97b5d1gpotterfrom scapy.modules.six.moves import filter, range, zip 245c6b1ce778d0462812fb3be4f5689682f9431a8ePhil 255c6b1ce778d0462812fb3be4f5689682f9431a8ePhil 26bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil############# 27bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil## Results ## 28bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil############# 29bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil 3033c3b1a112faf0f223cf0d983aac85b95ff2c248Philclass PacketList(BasePacketList): 31aefe6fcbe454cd014487523c5470d933fa70e95cPierre LALET __slots__ = ["stats", "res", "listname"] 32bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil def __init__(self, res=None, name="PacketList", stats=None): 33bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil """create a packet list from a list of packets 34bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil res: the list of packets 35bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil stats: a list of classes that will appear in the stats (defaults to [TCP,UDP,ICMP])""" 36bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil if stats is None: 37e02f12feef2f5bf68e1632f01ef3ab6192d35bbbPhil stats = conf.stats_classic_protocols 38bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil self.stats = stats 39bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil if res is None: 40bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil res = [] 41f53402a82b096ef1224460412790dba0daf8c60aPierre LALET elif isinstance(res, PacketList): 42bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil res = res.res 43bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil self.res = res 44bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil self.listname = name 45bed0f3587db8b886d3c09cd9529eacf23b84590cPierre LALET def __len__(self): 46bed0f3587db8b886d3c09cd9529eacf23b84590cPierre LALET return len(self.res) 47bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil def _elt2pkt(self, elt): 48bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil return elt 49bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil def _elt2sum(self, elt): 50bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil return elt.summary() 51bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil def _elt2show(self, elt): 52bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil return self._elt2sum(elt) 53bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil def __repr__(self): 54b2a7a54a35112117fd642b7f9e75ca43857a0cb9Pierre LALET stats = {x: 0 for x in self.stats} 55bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil other = 0 56bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil for r in self.res: 57bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil f = 0 58bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil for p in stats: 59bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil if self._elt2pkt(r).haslayer(p): 60bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil stats[p] += 1 61bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil f = 1 62bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil break 63bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil if not f: 64bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil other += 1 65bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil s = "" 66bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil ct = conf.color_theme 67bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil for p in self.stats: 6806627eecaccb736e24ec155e1dcf3700acb25a0cPierre LALET s += " %s%s%s" % (ct.packetlist_proto(p._name), 69bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil ct.punct(":"), 70bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil ct.packetlist_value(stats[p])) 71bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil s += " %s%s%s" % (ct.packetlist_proto("Other"), 72bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil ct.punct(":"), 73bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil ct.packetlist_value(other)) 74bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil return "%s%s%s%s%s" % (ct.punct("<"), 75bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil ct.packetlist_name(self.listname), 76bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil ct.punct(":"), 77bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil s, 78bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil ct.punct(">")) 79bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil def __getattr__(self, attr): 80bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil return getattr(self.res, attr) 81bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil def __getitem__(self, item): 8233c3b1a112faf0f223cf0d983aac85b95ff2c248Phil if isinstance(item,type) and issubclass(item,BasePacket): 8352165d0dd55a1071b935d002a41a95210c97f8e7Guillaume Valadon return self.__class__([x for x in self.res if item in self._elt2pkt(x)], 84bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil name="%s from %s"%(item.__name__,self.listname)) 85d51edef8530fe1e944f13eb65ef863c2d7f04b1dgpotter if isinstance(item, slice): 86bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil return self.__class__(self.res.__getitem__(item), 87bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil name = "mod %s" % self.listname) 88bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil return self.res.__getitem__(item) 89bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil def __getslice__(self, *args, **kargs): 90bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil return self.__class__(self.res.__getslice__(*args, **kargs), 91bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil name="mod %s"%self.listname) 92bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil def __add__(self, other): 93bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil return self.__class__(self.res+other.res, 94bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil name="%s+%s"%(self.listname,other.listname)) 95bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil def summary(self, prn=None, lfilter=None): 96bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil """prints a summary of each packet 97bb2ddd8ef0416706e645595b6b5484ee4f409ad3Philprn: function to apply to each packet instead of lambda x:x.summary() 98bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phillfilter: truth function to apply to each packet to decide whether it will be displayed""" 99bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil for r in self.res: 100bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil if lfilter is not None: 101bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil if not lfilter(r): 102bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil continue 103bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil if prn is None: 104b72a0b59db7b6fa0726ffa22da3b88679bffe69cgpotter print(self._elt2sum(r)) 105bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil else: 106b72a0b59db7b6fa0726ffa22da3b88679bffe69cgpotter print(prn(r)) 1074cca8708a5fdc52e592aa2661ab7c4b06fd539b3Pierre LALET def nsummary(self, prn=None, lfilter=None): 108bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil """prints a summary of each packet with the packet's number 109bb2ddd8ef0416706e645595b6b5484ee4f409ad3Philprn: function to apply to each packet instead of lambda x:x.summary() 110bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phillfilter: truth function to apply to each packet to decide whether it will be displayed""" 1114cca8708a5fdc52e592aa2661ab7c4b06fd539b3Pierre LALET for i, res in enumerate(self.res): 112bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil if lfilter is not None: 1134cca8708a5fdc52e592aa2661ab7c4b06fd539b3Pierre LALET if not lfilter(res): 114bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil continue 115b72a0b59db7b6fa0726ffa22da3b88679bffe69cgpotter print(conf.color_theme.id(i,fmt="%04i"), end=' ') 116bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil if prn is None: 117b72a0b59db7b6fa0726ffa22da3b88679bffe69cgpotter print(self._elt2sum(res)) 118bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil else: 119b72a0b59db7b6fa0726ffa22da3b88679bffe69cgpotter print(prn(res)) 120bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil def display(self): # Deprecated. Use show() 121bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil """deprecated. is show()""" 122bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil self.show() 123bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil def show(self, *args, **kargs): 124bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil """Best way to display the packet list. Defaults to nsummary() method""" 125bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil return self.nsummary(*args, **kargs) 126bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil 127bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil def filter(self, func): 128bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil """Returns a packet list filtered by a truth function""" 12952165d0dd55a1071b935d002a41a95210c97f8e7Guillaume Valadon return self.__class__([x for x in self.res if func(x)], 130bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil name="filtered %s"%self.listname) 131bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil def make_table(self, *args, **kargs): 132ed95a6a3cea25583d339e564b7c93bdbcbbf9483Guillaume Valadon """Prints a table using a function that returns for each packet its head column value, head row value and displayed value 133bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil ex: p.make_table(lambda x:(x[IP].dst, x[TCP].dport, x[TCP].sprintf("%flags%")) """ 134bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil return make_table(self.res, *args, **kargs) 135bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil def make_lined_table(self, *args, **kargs): 136bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil """Same as make_table, but print a table with lines""" 137bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil return make_lined_table(self.res, *args, **kargs) 138bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil def make_tex_table(self, *args, **kargs): 139bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil """Same as make_table, but print a table with LaTeX syntax""" 140bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil return make_tex_table(self.res, *args, **kargs) 141bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil 142f50242c428cc6780a2637ab0482c5c63af42a1daPierre LALET def plot(self, f, lfilter=None, plot_xy=False, **kargs): 1439cb4a70de3c57dd3779a0aa87ea25914ac6ef98dGuillaume Valadon """Applies a function to each packet to get a value that will be plotted 14469eb6679cac0ede212f8e6204227136e30d785d5Guillaume Valadon with matplotlib. A list of matplotlib.lines.Line2D is returned. 14569eb6679cac0ede212f8e6204227136e30d785d5Guillaume Valadon 146ed95a6a3cea25583d339e564b7c93bdbcbbf9483Guillaume Valadon lfilter: a truth function that decides whether a packet must be plotted 14769eb6679cac0ede212f8e6204227136e30d785d5Guillaume Valadon """ 14869eb6679cac0ede212f8e6204227136e30d785d5Guillaume Valadon 14969eb6679cac0ede212f8e6204227136e30d785d5Guillaume Valadon # Get the list of packets 150f50242c428cc6780a2637ab0482c5c63af42a1daPierre LALET if lfilter is None: 151f50242c428cc6780a2637ab0482c5c63af42a1daPierre LALET l = [f(e) for e in self.res] 152f50242c428cc6780a2637ab0482c5c63af42a1daPierre LALET else: 153f50242c428cc6780a2637ab0482c5c63af42a1daPierre LALET l = [f(e) for e in self.res if lfilter(e)] 1549cb4a70de3c57dd3779a0aa87ea25914ac6ef98dGuillaume Valadon 1559cb4a70de3c57dd3779a0aa87ea25914ac6ef98dGuillaume Valadon # Mimic the default gnuplot output 1569cb4a70de3c57dd3779a0aa87ea25914ac6ef98dGuillaume Valadon if kargs == {}: 1579cb4a70de3c57dd3779a0aa87ea25914ac6ef98dGuillaume Valadon kargs = MATPLOTLIB_DEFAULT_PLOT_KARGS 158f50242c428cc6780a2637ab0482c5c63af42a1daPierre LALET if plot_xy: 159f50242c428cc6780a2637ab0482c5c63af42a1daPierre LALET lines = plt.plot(*zip(*l), **kargs) 160f50242c428cc6780a2637ab0482c5c63af42a1daPierre LALET else: 161f50242c428cc6780a2637ab0482c5c63af42a1daPierre LALET lines = plt.plot(l, **kargs) 1629cb4a70de3c57dd3779a0aa87ea25914ac6ef98dGuillaume Valadon 1639cb4a70de3c57dd3779a0aa87ea25914ac6ef98dGuillaume Valadon # Call show() if matplotlib is not inlined 1649cb4a70de3c57dd3779a0aa87ea25914ac6ef98dGuillaume Valadon if not MATPLOTLIB_INLINED: 1659cb4a70de3c57dd3779a0aa87ea25914ac6ef98dGuillaume Valadon plt.show() 1669cb4a70de3c57dd3779a0aa87ea25914ac6ef98dGuillaume Valadon 1679cb4a70de3c57dd3779a0aa87ea25914ac6ef98dGuillaume Valadon return lines 168bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil 169bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil def diffplot(self, f, delay=1, lfilter=None, **kargs): 170bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil """diffplot(f, delay=1, lfilter=None) 17169eb6679cac0ede212f8e6204227136e30d785d5Guillaume Valadon Applies a function to couples (l[i],l[i+delay]) 17269eb6679cac0ede212f8e6204227136e30d785d5Guillaume Valadon 17369eb6679cac0ede212f8e6204227136e30d785d5Guillaume Valadon A list of matplotlib.lines.Line2D is returned. 17469eb6679cac0ede212f8e6204227136e30d785d5Guillaume Valadon """ 17569eb6679cac0ede212f8e6204227136e30d785d5Guillaume Valadon 17669eb6679cac0ede212f8e6204227136e30d785d5Guillaume Valadon # Get the list of packets 1772d349c190ac3e65b130e0e123b018221fd2ff7d9Guillaume Valadon if lfilter is None: 1782d349c190ac3e65b130e0e123b018221fd2ff7d9Guillaume Valadon l = [f(self.res[i], self.res[i+1]) 17922a55b62eb35e8611fe03b99e4ff4f257a97b5d1gpotter for i in range(len(self.res) - delay)] 1802d349c190ac3e65b130e0e123b018221fd2ff7d9Guillaume Valadon else: 1812d349c190ac3e65b130e0e123b018221fd2ff7d9Guillaume Valadon l = [f(self.res[i], self.res[i+1]) 18222a55b62eb35e8611fe03b99e4ff4f257a97b5d1gpotter for i in range(len(self.res) - delay) 1832d349c190ac3e65b130e0e123b018221fd2ff7d9Guillaume Valadon if lfilter(self.res[i])] 1849cb4a70de3c57dd3779a0aa87ea25914ac6ef98dGuillaume Valadon 1859cb4a70de3c57dd3779a0aa87ea25914ac6ef98dGuillaume Valadon # Mimic the default gnuplot output 1869cb4a70de3c57dd3779a0aa87ea25914ac6ef98dGuillaume Valadon if kargs == {}: 1879cb4a70de3c57dd3779a0aa87ea25914ac6ef98dGuillaume Valadon kargs = MATPLOTLIB_DEFAULT_PLOT_KARGS 1889cb4a70de3c57dd3779a0aa87ea25914ac6ef98dGuillaume Valadon lines = plt.plot(l, **kargs) 1899cb4a70de3c57dd3779a0aa87ea25914ac6ef98dGuillaume Valadon 1909cb4a70de3c57dd3779a0aa87ea25914ac6ef98dGuillaume Valadon # Call show() if matplotlib is not inlined 1919cb4a70de3c57dd3779a0aa87ea25914ac6ef98dGuillaume Valadon if not MATPLOTLIB_INLINED: 1929cb4a70de3c57dd3779a0aa87ea25914ac6ef98dGuillaume Valadon plt.show() 1939cb4a70de3c57dd3779a0aa87ea25914ac6ef98dGuillaume Valadon 1949cb4a70de3c57dd3779a0aa87ea25914ac6ef98dGuillaume Valadon return lines 195bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil 196f50242c428cc6780a2637ab0482c5c63af42a1daPierre LALET def multiplot(self, f, lfilter=None, plot_xy=False, **kargs): 197c38efa07ef66290c38b1ff100e41995e243bec20Guillaume Valadon """Uses a function that returns a label and a value for this label, then 198c38efa07ef66290c38b1ff100e41995e243bec20Guillaume Valadon plots all the values label by label. 199c38efa07ef66290c38b1ff100e41995e243bec20Guillaume Valadon 200c38efa07ef66290c38b1ff100e41995e243bec20Guillaume Valadon A list of matplotlib.lines.Line2D is returned. 201c38efa07ef66290c38b1ff100e41995e243bec20Guillaume Valadon """ 202c38efa07ef66290c38b1ff100e41995e243bec20Guillaume Valadon 203c38efa07ef66290c38b1ff100e41995e243bec20Guillaume Valadon # Get the list of packets 204f50242c428cc6780a2637ab0482c5c63af42a1daPierre LALET if lfilter is None: 205f50242c428cc6780a2637ab0482c5c63af42a1daPierre LALET l = (f(e) for e in self.res) 206f50242c428cc6780a2637ab0482c5c63af42a1daPierre LALET else: 207f50242c428cc6780a2637ab0482c5c63af42a1daPierre LALET l = (f(e) for e in self.res if lfilter(e)) 208bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil 209c38efa07ef66290c38b1ff100e41995e243bec20Guillaume Valadon # Apply the function f to the packets 210f50242c428cc6780a2637ab0482c5c63af42a1daPierre LALET d = {} 211f50242c428cc6780a2637ab0482c5c63af42a1daPierre LALET for k, v in l: 212f50242c428cc6780a2637ab0482c5c63af42a1daPierre LALET d.setdefault(k, []).append(v) 213c38efa07ef66290c38b1ff100e41995e243bec20Guillaume Valadon 214c38efa07ef66290c38b1ff100e41995e243bec20Guillaume Valadon # Mimic the default gnuplot output 215f50242c428cc6780a2637ab0482c5c63af42a1daPierre LALET if not kargs: 216c38efa07ef66290c38b1ff100e41995e243bec20Guillaume Valadon kargs = MATPLOTLIB_DEFAULT_PLOT_KARGS 2179cb4a70de3c57dd3779a0aa87ea25914ac6ef98dGuillaume Valadon 218f50242c428cc6780a2637ab0482c5c63af42a1daPierre LALET if plot_xy: 219f3a4c64e3cb35bcc55b9282cf04c79bbd07942d4Pierre LALET lines = [plt.plot(*zip(*pl), **dict(kargs, label=k)) 22022a55b62eb35e8611fe03b99e4ff4f257a97b5d1gpotter for k, pl in six.iteritems(d)] 221f50242c428cc6780a2637ab0482c5c63af42a1daPierre LALET else: 222f3a4c64e3cb35bcc55b9282cf04c79bbd07942d4Pierre LALET lines = [plt.plot(pl, **dict(kargs, label=k)) 22322a55b62eb35e8611fe03b99e4ff4f257a97b5d1gpotter for k, pl in six.iteritems(d)] 2249cb4a70de3c57dd3779a0aa87ea25914ac6ef98dGuillaume Valadon plt.legend(loc="center right", bbox_to_anchor=(1.5, 0.5)) 2259cb4a70de3c57dd3779a0aa87ea25914ac6ef98dGuillaume Valadon 2269cb4a70de3c57dd3779a0aa87ea25914ac6ef98dGuillaume Valadon # Call show() if matplotlib is not inlined 2279cb4a70de3c57dd3779a0aa87ea25914ac6ef98dGuillaume Valadon if not MATPLOTLIB_INLINED: 2289cb4a70de3c57dd3779a0aa87ea25914ac6ef98dGuillaume Valadon plt.show() 229bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil 2309cb4a70de3c57dd3779a0aa87ea25914ac6ef98dGuillaume Valadon return lines 231bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil 232bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil def rawhexdump(self): 233bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil """Prints an hexadecimal dump of each packet in the list""" 234bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil for p in self: 235bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil hexdump(self._elt2pkt(p)) 236bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil 237bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil def hexraw(self, lfilter=None): 238bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil """Same as nsummary(), except that if a packet has a Raw layer, it will be hexdumped 239bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil lfilter: a truth function that decides whether a packet must be displayed""" 2404cca8708a5fdc52e592aa2661ab7c4b06fd539b3Pierre LALET for i, res in enumerate(self.res): 2414cca8708a5fdc52e592aa2661ab7c4b06fd539b3Pierre LALET p = self._elt2pkt(res) 242bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil if lfilter is not None and not lfilter(p): 243bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil continue 244b72a0b59db7b6fa0726ffa22da3b88679bffe69cgpotter print("%s %s %s" % (conf.color_theme.id(i,fmt="%04i"), 245bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil p.sprintf("%.time%"), 246b72a0b59db7b6fa0726ffa22da3b88679bffe69cgpotter self._elt2sum(res))) 2475f56932f2ba2726f17ec7095b460e5dfafe53199Phil if p.haslayer(conf.raw_layer): 2485f56932f2ba2726f17ec7095b460e5dfafe53199Phil hexdump(p.getlayer(conf.raw_layer).load) 249bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil 250bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil def hexdump(self, lfilter=None): 251bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil """Same as nsummary(), except that packets are also hexdumped 252bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil lfilter: a truth function that decides whether a packet must be displayed""" 2534cca8708a5fdc52e592aa2661ab7c4b06fd539b3Pierre LALET for i, res in enumerate(self.res): 2544cca8708a5fdc52e592aa2661ab7c4b06fd539b3Pierre LALET p = self._elt2pkt(res) 255bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil if lfilter is not None and not lfilter(p): 256bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil continue 257b72a0b59db7b6fa0726ffa22da3b88679bffe69cgpotter print("%s %s %s" % (conf.color_theme.id(i,fmt="%04i"), 258bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil p.sprintf("%.time%"), 259b72a0b59db7b6fa0726ffa22da3b88679bffe69cgpotter self._elt2sum(res))) 260bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil hexdump(p) 261bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil 262bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil def padding(self, lfilter=None): 263bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil """Same as hexraw(), for Padding layer""" 264f53402a82b096ef1224460412790dba0daf8c60aPierre LALET for i, res in enumerate(self.res): 2654cca8708a5fdc52e592aa2661ab7c4b06fd539b3Pierre LALET p = self._elt2pkt(res) 266eec79622b3fafb8e713a93a061a8be0de0691282Phil if p.haslayer(conf.padding_layer): 267bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil if lfilter is None or lfilter(p): 268b72a0b59db7b6fa0726ffa22da3b88679bffe69cgpotter print("%s %s %s" % (conf.color_theme.id(i,fmt="%04i"), 269bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil p.sprintf("%.time%"), 270b72a0b59db7b6fa0726ffa22da3b88679bffe69cgpotter self._elt2sum(res))) 271eec79622b3fafb8e713a93a061a8be0de0691282Phil hexdump(p.getlayer(conf.padding_layer).load) 272bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil 273bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil def nzpadding(self, lfilter=None): 274bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil """Same as padding() but only non null padding""" 275f53402a82b096ef1224460412790dba0daf8c60aPierre LALET for i, res in enumerate(self.res): 2764cca8708a5fdc52e592aa2661ab7c4b06fd539b3Pierre LALET p = self._elt2pkt(res) 277eec79622b3fafb8e713a93a061a8be0de0691282Phil if p.haslayer(conf.padding_layer): 278eec79622b3fafb8e713a93a061a8be0de0691282Phil pad = p.getlayer(conf.padding_layer).load 279bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil if pad == pad[0]*len(pad): 280bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil continue 281bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil if lfilter is None or lfilter(p): 282b72a0b59db7b6fa0726ffa22da3b88679bffe69cgpotter print("%s %s %s" % (conf.color_theme.id(i,fmt="%04i"), 283bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil p.sprintf("%.time%"), 284b72a0b59db7b6fa0726ffa22da3b88679bffe69cgpotter self._elt2sum(res))) 285eec79622b3fafb8e713a93a061a8be0de0691282Phil hexdump(p.getlayer(conf.padding_layer).load) 286bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil 287bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil 288bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil def conversations(self, getsrcdst=None,**kargs): 289bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil """Graphes a conversations between sources and destinations and display it 290bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil (using graphviz and imagemagick) 29198d3ff422570ae47c2f19f7d8115431e0e2b6ed3Pierre Lalet getsrcdst: a function that takes an element of the list and 29298d3ff422570ae47c2f19f7d8115431e0e2b6ed3Pierre Lalet returns the source, the destination and optionally 29398d3ff422570ae47c2f19f7d8115431e0e2b6ed3Pierre Lalet a label. By default, returns the IP source and 29498d3ff422570ae47c2f19f7d8115431e0e2b6ed3Pierre Lalet destination from IP and ARP layers 295bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil type: output type (svg, ps, gif, jpg, etc.), passed to dot's "-T" option 296bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil target: filename or redirect. Defaults pipe to Imagemagick's display program 297bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil prog: which graphviz program to use""" 298bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil if getsrcdst is None: 29998d3ff422570ae47c2f19f7d8115431e0e2b6ed3Pierre Lalet def getsrcdst(pkt): 3006057906368d55634d11e1d19a5cca1f127595b11Robin Jarry if 'IP' in pkt: 3016057906368d55634d11e1d19a5cca1f127595b11Robin Jarry return (pkt['IP'].src, pkt['IP'].dst) 3026057906368d55634d11e1d19a5cca1f127595b11Robin Jarry if 'ARP' in pkt: 3036057906368d55634d11e1d19a5cca1f127595b11Robin Jarry return (pkt['ARP'].psrc, pkt['ARP'].pdst) 30498d3ff422570ae47c2f19f7d8115431e0e2b6ed3Pierre Lalet raise TypeError() 305bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil conv = {} 306bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil for p in self.res: 307bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil p = self._elt2pkt(p) 308bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil try: 309bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil c = getsrcdst(p) 310bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil except: 31198d3ff422570ae47c2f19f7d8115431e0e2b6ed3Pierre Lalet # No warning here: it's OK that getsrcdst() raises an 31298d3ff422570ae47c2f19f7d8115431e0e2b6ed3Pierre Lalet # exception, since it might be, for example, a 31398d3ff422570ae47c2f19f7d8115431e0e2b6ed3Pierre Lalet # function that expects a specific layer in each 31498d3ff422570ae47c2f19f7d8115431e0e2b6ed3Pierre Lalet # packet. The try/except approach is faster and 31598d3ff422570ae47c2f19f7d8115431e0e2b6ed3Pierre Lalet # considered more Pythonic than adding tests. 316bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil continue 31798d3ff422570ae47c2f19f7d8115431e0e2b6ed3Pierre Lalet if len(c) == 3: 31898d3ff422570ae47c2f19f7d8115431e0e2b6ed3Pierre Lalet conv.setdefault(c[:2], set()).add(c[2]) 31998d3ff422570ae47c2f19f7d8115431e0e2b6ed3Pierre Lalet else: 32098d3ff422570ae47c2f19f7d8115431e0e2b6ed3Pierre Lalet conv[c] = conv.get(c, 0) + 1 321bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil gr = 'digraph "conv" {\n' 32222a55b62eb35e8611fe03b99e4ff4f257a97b5d1gpotter for (s, d), l in six.iteritems(conv): 32398d3ff422570ae47c2f19f7d8115431e0e2b6ed3Pierre Lalet gr += '\t "%s" -> "%s" [label="%s"]\n' % ( 32498d3ff422570ae47c2f19f7d8115431e0e2b6ed3Pierre Lalet s, d, ', '.join(str(x) for x in l) if isinstance(l, set) else l 32598d3ff422570ae47c2f19f7d8115431e0e2b6ed3Pierre Lalet ) 326bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil gr += "}\n" 327bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil return do_graph(gr, **kargs) 328bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil 329bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil def afterglow(self, src=None, event=None, dst=None, **kargs): 330bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil """Experimental clone attempt of http://sourceforge.net/projects/afterglow 331bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil each datum is reduced as src -> event -> dst and the data are graphed. 332bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil by default we have IP.src -> IP.dport -> IP.dst""" 333bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil if src is None: 334b26fe5984bbb57a24c72f50bb536a8f5ba3d528dPhil src = lambda x: x['IP'].src 335bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil if event is None: 336b26fe5984bbb57a24c72f50bb536a8f5ba3d528dPhil event = lambda x: x['IP'].dport 337bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil if dst is None: 338b26fe5984bbb57a24c72f50bb536a8f5ba3d528dPhil dst = lambda x: x['IP'].dst 339bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil sl = {} 340bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil el = {} 341bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil dl = {} 342bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil for i in self.res: 343bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil try: 344bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil s,e,d = src(i),event(i),dst(i) 345bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil if s in sl: 346bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil n,l = sl[s] 347bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil n += 1 348bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil if e not in l: 349bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil l.append(e) 350bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil sl[s] = (n,l) 351bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil else: 352bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil sl[s] = (1,[e]) 353bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil if e in el: 354bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil n,l = el[e] 355bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil n+=1 356bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil if d not in l: 357bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil l.append(d) 358bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil el[e] = (n,l) 359bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil else: 360bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil el[e] = (1,[d]) 361bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil dl[d] = dl.get(d,0)+1 362bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil except: 363bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil continue 364bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil 365bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil import math 366bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil def normalize(n): 367bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil return 2+math.log(n)/4.0 368bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil 369bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil def minmax(x): 370241e2c497945a93117ce42ebc2a555e3871ca716Pierre LALET m, M = reduce(lambda a, b: (min(a[0], b[0]), max(a[1], b[1])), 371241e2c497945a93117ce42ebc2a555e3871ca716Pierre LALET ((a, a) for a in x)) 372bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil if m == M: 373bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil m = 0 374bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil if M == 0: 375bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil M = 1 376241e2c497945a93117ce42ebc2a555e3871ca716Pierre LALET return m, M 377bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil 37822a55b62eb35e8611fe03b99e4ff4f257a97b5d1gpotter mins, maxs = minmax(x for x, _ in six.itervalues(sl)) 37922a55b62eb35e8611fe03b99e4ff4f257a97b5d1gpotter mine, maxe = minmax(x for x, _ in six.itervalues(el)) 38022a55b62eb35e8611fe03b99e4ff4f257a97b5d1gpotter mind, maxd = minmax(six.itervalues(dl)) 381bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil 382bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil gr = 'digraph "afterglow" {\n\tedge [len=2.5];\n' 383bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil 384bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil gr += "# src nodes\n" 385bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil for s in sl: 386bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil n,l = sl[s]; n = 1+float(n-mins)/(maxs-mins) 387d51edef8530fe1e944f13eb65ef863c2d7f04b1dgpotter gr += '"src.%s" [label = "%s", shape=box, fillcolor="#FF0000", style=filled, fixedsize=1, height=%.2f,width=%.2f];\n' % (repr(s),repr(s),n,n) 388bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil gr += "# event nodes\n" 389bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil for e in el: 390bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil n,l = el[e]; n = n = 1+float(n-mine)/(maxe-mine) 391d51edef8530fe1e944f13eb65ef863c2d7f04b1dgpotter gr += '"evt.%s" [label = "%s", shape=circle, fillcolor="#00FFFF", style=filled, fixedsize=1, height=%.2f, width=%.2f];\n' % (repr(e),repr(e),n,n) 392bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil for d in dl: 393bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil n = dl[d]; n = n = 1+float(n-mind)/(maxd-mind) 394d51edef8530fe1e944f13eb65ef863c2d7f04b1dgpotter gr += '"dst.%s" [label = "%s", shape=triangle, fillcolor="#0000ff", style=filled, fixedsize=1, height=%.2f, width=%.2f];\n' % (repr(d),repr(d),n,n) 395bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil 396bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil gr += "###\n" 397bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil for s in sl: 398bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil n,l = sl[s] 399bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil for e in l: 400d51edef8530fe1e944f13eb65ef863c2d7f04b1dgpotter gr += ' "src.%s" -> "evt.%s";\n' % (repr(s),repr(e)) 401bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil for e in el: 402bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil n,l = el[e] 403bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil for d in l: 404d51edef8530fe1e944f13eb65ef863c2d7f04b1dgpotter gr += ' "evt.%s" -> "dst.%s";\n' % (repr(e),repr(d)) 405bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil 406bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil gr += "}" 407bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil return do_graph(gr, **kargs) 408bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil 409b26fe5984bbb57a24c72f50bb536a8f5ba3d528dPhil 410bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil def _dump_document(self, **kargs): 411e02f12feef2f5bf68e1632f01ef3ab6192d35bbbPhil import pyx 412bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil d = pyx.document.document() 413bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil l = len(self.res) 414f53402a82b096ef1224460412790dba0daf8c60aPierre LALET for i, res in enumerate(self.res): 415f53402a82b096ef1224460412790dba0daf8c60aPierre LALET c = self._elt2pkt(res).canvas_dump(**kargs) 416bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil cbb = c.bbox() 417bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil c.text(cbb.left(),cbb.top()+1,r"\font\cmssfont=cmss12\cmssfont{Frame %i/%i}" % (i,l),[pyx.text.size.LARGE]) 418bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil if conf.verb >= 2: 4195c620d0941a75b79fb16fd9b1f3957ba0e553f03Pierre LALET os.write(1, b".") 420bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil d.append(pyx.document.page(c, paperformat=pyx.document.paperformat.A4, 421bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil margin=1*pyx.unit.t_cm, 422bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil fittosize=1)) 423bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil return d 424bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil 425bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil 426bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil 427bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil def psdump(self, filename = None, **kargs): 428ed95a6a3cea25583d339e564b7c93bdbcbbf9483Guillaume Valadon """Creates a multi-page postcript file with a psdump of every packet 429bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil filename: name of the file to write to. If empty, a temporary file is used and 430bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil conf.prog.psreader is called""" 431bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil d = self._dump_document(**kargs) 432bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil if filename is None: 43383c9b88a1ea492cfb2d860df146d193164c0ba80Phil filename = get_temp_file(autoext=".ps") 434bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil d.writePSfile(filename) 435881980d3999c698e52cbe1299ca2e63dd3838170Guillaume Valadon with ContextManagerSubprocess("psdump()"): 436881980d3999c698e52cbe1299ca2e63dd3838170Guillaume Valadon subprocess.Popen([conf.prog.psreader, filename+".ps"]) 437bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil else: 438bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil d.writePSfile(filename) 439b72a0b59db7b6fa0726ffa22da3b88679bffe69cgpotter print() 440bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil 441bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil def pdfdump(self, filename = None, **kargs): 442bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil """Creates a PDF file with a psdump of every packet 443bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil filename: name of the file to write to. If empty, a temporary file is used and 444bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil conf.prog.pdfreader is called""" 445bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil d = self._dump_document(**kargs) 446bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil if filename is None: 44783c9b88a1ea492cfb2d860df146d193164c0ba80Phil filename = get_temp_file(autoext=".pdf") 448bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil d.writePDFfile(filename) 449881980d3999c698e52cbe1299ca2e63dd3838170Guillaume Valadon with ContextManagerSubprocess("psdump()"): 450881980d3999c698e52cbe1299ca2e63dd3838170Guillaume Valadon subprocess.Popen([conf.prog.pdfreader, filename+".pdf"]) 451bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil else: 452bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil d.writePDFfile(filename) 453b72a0b59db7b6fa0726ffa22da3b88679bffe69cgpotter print() 454bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil 455bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil def sr(self,multi=0): 456bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil """sr([multi=1]) -> (SndRcvList, PacketList) 457bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil Matches packets in the list and return ( (matched couples), (unmatched packets) )""" 458bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil remain = self.res[:] 459bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil sr = [] 460bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil i = 0 461bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil while i < len(remain): 462bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil s = remain[i] 463bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil j = i 464bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil while j < len(remain)-1: 465bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil j += 1 466bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil r = remain[j] 467bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil if r.answers(s): 468bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil sr.append((s,r)) 469bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil if multi: 470bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil remain[i]._answered=1 471bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil remain[j]._answered=2 472bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil continue 473bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil del(remain[j]) 474bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil del(remain[i]) 475bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil i -= 1 476bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil break 477bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil i += 1 478bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil if multi: 47952165d0dd55a1071b935d002a41a95210c97f8e7Guillaume Valadon remain = [x for x in remain if not hasattr(x, "_answered")] 480bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil return SndRcvList(sr),PacketList(remain) 481f13602150438b4afd00a46f1dafb4062369cc835Phil 482f13602150438b4afd00a46f1dafb4062369cc835Phil def sessions(self, session_extractor=None): 483f13602150438b4afd00a46f1dafb4062369cc835Phil if session_extractor is None: 484f13602150438b4afd00a46f1dafb4062369cc835Phil def session_extractor(p): 485e28fc9af59ebd347eb70aa90f0317a553cbe2a91Phil sess = "Other" 486f13602150438b4afd00a46f1dafb4062369cc835Phil if 'Ether' in p: 487f13602150438b4afd00a46f1dafb4062369cc835Phil if 'IP' in p: 488f13602150438b4afd00a46f1dafb4062369cc835Phil if 'TCP' in p: 489f13602150438b4afd00a46f1dafb4062369cc835Phil sess = p.sprintf("TCP %IP.src%:%r,TCP.sport% > %IP.dst%:%r,TCP.dport%") 490f13602150438b4afd00a46f1dafb4062369cc835Phil elif 'UDP' in p: 491f13602150438b4afd00a46f1dafb4062369cc835Phil sess = p.sprintf("UDP %IP.src%:%r,UDP.sport% > %IP.dst%:%r,UDP.dport%") 492f13602150438b4afd00a46f1dafb4062369cc835Phil elif 'ICMP' in p: 493f13602150438b4afd00a46f1dafb4062369cc835Phil sess = p.sprintf("ICMP %IP.src% > %IP.dst% type=%r,ICMP.type% code=%r,ICMP.code% id=%ICMP.id%") 494f13602150438b4afd00a46f1dafb4062369cc835Phil else: 495f13602150438b4afd00a46f1dafb4062369cc835Phil sess = p.sprintf("IP %IP.src% > %IP.dst% proto=%IP.proto%") 496f13602150438b4afd00a46f1dafb4062369cc835Phil elif 'ARP' in p: 497f13602150438b4afd00a46f1dafb4062369cc835Phil sess = p.sprintf("ARP %ARP.psrc% > %ARP.pdst%") 498f13602150438b4afd00a46f1dafb4062369cc835Phil else: 499f13602150438b4afd00a46f1dafb4062369cc835Phil sess = p.sprintf("Ethernet type=%04xr,Ether.type%") 500f13602150438b4afd00a46f1dafb4062369cc835Phil return sess 501f13602150438b4afd00a46f1dafb4062369cc835Phil sessions = defaultdict(self.__class__) 502f13602150438b4afd00a46f1dafb4062369cc835Phil for p in self.res: 503f13602150438b4afd00a46f1dafb4062369cc835Phil sess = session_extractor(self._elt2pkt(p)) 504f13602150438b4afd00a46f1dafb4062369cc835Phil sessions[sess].append(p) 505f13602150438b4afd00a46f1dafb4062369cc835Phil return dict(sessions) 5068cd8caea2cbda8001f31ad0f01835d765691ebfePhil 5078cd8caea2cbda8001f31ad0f01835d765691ebfePhil def replace(self, *args, **kargs): 5088cd8caea2cbda8001f31ad0f01835d765691ebfePhil """ 5098cd8caea2cbda8001f31ad0f01835d765691ebfePhil lst.replace(<field>,[<oldvalue>,]<newvalue>) 5108cd8caea2cbda8001f31ad0f01835d765691ebfePhil lst.replace( (fld,[ov],nv),(fld,[ov,]nv),...) 5118cd8caea2cbda8001f31ad0f01835d765691ebfePhil if ov is None, all values are replaced 5128cd8caea2cbda8001f31ad0f01835d765691ebfePhil ex: 5138cd8caea2cbda8001f31ad0f01835d765691ebfePhil lst.replace( IP.src, "192.168.1.1", "10.0.0.1" ) 5148cd8caea2cbda8001f31ad0f01835d765691ebfePhil lst.replace( IP.ttl, 64 ) 5158cd8caea2cbda8001f31ad0f01835d765691ebfePhil lst.replace( (IP.ttl, 64), (TCP.sport, 666, 777), ) 5168cd8caea2cbda8001f31ad0f01835d765691ebfePhil """ 5178cd8caea2cbda8001f31ad0f01835d765691ebfePhil delete_checksums = kargs.get("delete_checksums",False) 5188cd8caea2cbda8001f31ad0f01835d765691ebfePhil x=PacketList(name="Replaced %s" % self.listname) 519d51edef8530fe1e944f13eb65ef863c2d7f04b1dgpotter if not isinstance(args[0], tuple): 5208cd8caea2cbda8001f31ad0f01835d765691ebfePhil args = (args,) 5218cd8caea2cbda8001f31ad0f01835d765691ebfePhil for p in self.res: 5228cd8caea2cbda8001f31ad0f01835d765691ebfePhil p = self._elt2pkt(p) 5238cd8caea2cbda8001f31ad0f01835d765691ebfePhil copied = False 5248cd8caea2cbda8001f31ad0f01835d765691ebfePhil for scheme in args: 5258cd8caea2cbda8001f31ad0f01835d765691ebfePhil fld = scheme[0] 5268cd8caea2cbda8001f31ad0f01835d765691ebfePhil old = scheme[1] # not used if len(scheme) == 2 5278cd8caea2cbda8001f31ad0f01835d765691ebfePhil new = scheme[-1] 5288cd8caea2cbda8001f31ad0f01835d765691ebfePhil for o in fld.owners: 5298cd8caea2cbda8001f31ad0f01835d765691ebfePhil if o in p: 5308cd8caea2cbda8001f31ad0f01835d765691ebfePhil if len(scheme) == 2 or p[o].getfieldval(fld.name) == old: 5318cd8caea2cbda8001f31ad0f01835d765691ebfePhil if not copied: 5328cd8caea2cbda8001f31ad0f01835d765691ebfePhil p = p.copy() 5338cd8caea2cbda8001f31ad0f01835d765691ebfePhil if delete_checksums: 5348cd8caea2cbda8001f31ad0f01835d765691ebfePhil p.delete_checksums() 5358cd8caea2cbda8001f31ad0f01835d765691ebfePhil copied = True 5368cd8caea2cbda8001f31ad0f01835d765691ebfePhil setattr(p[o], fld.name, new) 5378cd8caea2cbda8001f31ad0f01835d765691ebfePhil x.append(p) 5388cd8caea2cbda8001f31ad0f01835d765691ebfePhil return x 539bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil 540bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil 541bb2ddd8ef0416706e645595b6b5484ee4f409ad3Philclass SndRcvList(PacketList): 542aefe6fcbe454cd014487523c5470d933fa70e95cPierre LALET __slots__ = [] 543bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil def __init__(self, res=None, name="Results", stats=None): 544bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil PacketList.__init__(self, res, name, stats) 545bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil def _elt2pkt(self, elt): 546bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil return elt[1] 547bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil def _elt2sum(self, elt): 548bb2ddd8ef0416706e645595b6b5484ee4f409ad3Phil return "%s ==> %s" % (elt[0].summary(),elt[1].summary()) 549