3 #############################################################################
5 ## scapy.py --- Interactive packet manipulation tool ##
6 ## see http://www.secdev.org/projects/scapy/ ##
7 ## for more informations ##
9 ## Copyright (C) 2003 Philippe Biondi <phil@secdev.org> ##
11 ## This program is free software; you can redistribute it and/or modify it ##
12 ## under the terms of the GNU General Public License version 2 as ##
13 ## published by the Free Software Foundation; version 2. ##
15 ## This program is distributed in the hope that it will be useful, but ##
16 ## WITHOUT ANY WARRANTY; without even the implied warranty of ##
17 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ##
18 ## General Public License for more details. ##
20 #############################################################################
23 from __future__ import generators
28 DEFAULT_CONFIG_FILE = os.path.join(os.environ["HOME"], ".scapy_startup.py")
31 os.stat(DEFAULT_CONFIG_FILE)
33 DEFAULT_CONFIG_FILE = None
36 print """Usage: scapy.py [-s sessionfile] [-c new_startup_file] [-C]
37 -C: do not read startup file"""
41 #############################
42 ##### Logging subsystem #####
43 #############################
45 class Scapy_Exception(Exception):
48 import logging,traceback,time
50 class ScapyFreqFilter(logging.Filter):
52 logging.Filter.__init__(self)
53 self.warning_table = {}
54 def filter(self, record):
55 wt = conf.warning_threshold
57 stk = traceback.extract_stack()
63 tm,nb = self.warning_table.get(caller, (0,0))
72 record.msg = "more "+record.msg
75 self.warning_table[caller] = (tm,nb)
78 log_scapy = logging.getLogger("scapy")
79 console_handler = logging.StreamHandler()
80 console_handler.setFormatter(logging.Formatter("%(levelname)s: %(message)s"))
81 log_scapy.addHandler(console_handler)
82 log_runtime = logging.getLogger("scapy.runtime") # logs at runtime
83 log_runtime.addFilter(ScapyFreqFilter())
84 log_interactive = logging.getLogger("scapy.interactive") # logs in interactive functions
85 log_loading = logging.getLogger("scapy.loading") # logs when loading scapy
87 if __name__ == "__main__":
95 import socket, sys, getopt, string, struct, random, code
96 import cPickle, copy, types, gzip, base64, re, zlib, array
98 from select import select
100 from fcntl import ioctl
104 warnings.filterwarnings("ignore","tempnam",RuntimeWarning, __name__)
111 log_loading.info("did not find python gnuplot wrapper . Won't be able to plot")
118 log_loading.info("Can't import PyX. Won't be able to use psdump() or pdfdump()")
122 LINUX=sys.platform.startswith("linux")
123 OPENBSD=sys.platform.startswith("openbsd")
124 FREEBSD=sys.platform.startswith("freebsd")
125 DARWIN=sys.platform.startswith("darwin")
126 BIG_ENDIAN= struct.pack("H",1) == "\x00\x01"
127 X86_64 = (os.uname()[4] == 'x86_64')
128 SOLARIS=sys.platform.startswith("sunos")
143 log_loading.warning("did not find pcap module. Fallback to linux primitives")
146 if __name__ == "__main__":
147 log_loading.error("did not find pcap module")
158 log_loading.warning("did not find dnet module. Fallback to linux primitives")
161 if __name__ == "__main__":
162 log_loading.error("did not find dnet module")
168 f = os.popen("tcpdump -V 2> /dev/null")
169 if f.close() >> 8 == 0x7f:
170 log_loading.warning("Failed to execute tcpdump. Check it is installed and in the PATH")
179 from Crypto.Cipher import ARC4
181 log_loading.info("Can't find Crypto python lib. Won't be able to decrypt WEP")
184 # Workarround bug 643005 : https://sourceforge.net/tracker/?func=detail&atid=105470&aid=643005&group_id=5470
186 socket.inet_aton("255.255.255.255")
189 if x == "255.255.255.255":
192 return socket.inet_aton(x)
194 inet_aton = socket.inet_aton
196 inet_ntoa = socket.inet_ntoa
198 inet_ntop = socket.inet_ntop
199 inet_pton = socket.inet_pton
200 except AttributeError:
201 log_loading.info("inet_ntop/pton functions not found. Python IPv6 support not present")
205 # GRE is missing on Solaris
206 socket.IPPROTO_GRE = 47
208 ###############################
209 ## Direct Access dictionnary ##
210 ###############################
213 if x and x[0] in "0123456789":
215 return x.translate("________________________________________________0123456789_______ABCDEFGHIJKLMNOPQRSTUVWXYZ______abcdefghijklmnopqrstuvwxyz_____________________________________________________________________________________________________________________________________")
218 class DADict_Exception(Scapy_Exception):
222 def __init__(self, _name="DADict", **kargs):
224 self.__dict__.update(kargs)
225 def fixname(self,val):
227 def __contains__(self, val):
228 return val in self.__dict__
229 def __getitem__(self, attr):
230 return getattr(self, attr)
231 def __setitem__(self, attr, val):
232 return setattr(self, self.fixname(attr), val)
234 return iter(map(lambda (x,y):y,filter(lambda (x,y):x and x[0]!="_", self.__dict__.items())))
236 for k in self.__dict__.keys():
237 if k and k[0] != "_":
238 print "%10s = %r" % (k,getattr(self,k))
240 return "<%s/ %s>" % (self._name," ".join(filter(lambda x:x and x[0]!="_",self.__dict__.keys())))
242 def _branch(self, br, uniq=0):
243 if uniq and br._name in self:
244 raise DADict_Exception("DADict: [%s] already branched in [%s]" % (br._name, self._name))
247 def _my_find(self, *args, **kargs):
248 if args and self._name not in args:
251 if k not in self or self[k] != kargs[k]:
255 def _find(self, *args, **kargs):
256 return self._recurs_find((), *args, **kargs)
257 def _recurs_find(self, path, *args, **kargs):
260 if self._my_find(*args, **kargs):
263 if isinstance(o, DADict):
264 p = o._recurs_find(path+(self,), *args, **kargs)
268 def _find_all(self, *args, **kargs):
269 return self._recurs_find_all((), *args, **kargs)
270 def _recurs_find_all(self, path, *args, **kargs):
274 if self._my_find(*args, **kargs):
277 if isinstance(o, DADict):
278 p = o._recurs_find_all(path+(self,), *args, **kargs)
282 return filter(lambda x:x and x[0]!="_", self.__dict__.keys())
291 ETHER_BROADCAST = "\xff"*6
301 ARPHDR_LOOPBACK = 772
305 SIOCGIFHWADDR = 0x8927 # Get hardware address
306 SIOCGIFADDR = 0x8915 # get PA address
307 SIOCGIFNETMASK = 0x891b # get network PA mask
308 SIOCGIFNAME = 0x8910 # get iface name
309 SIOCSIFLINK = 0x8911 # set iface channel
310 SIOCGIFCONF = 0x8912 # get iface list
311 SIOCGIFFLAGS = 0x8913 # get flags
312 SIOCSIFFLAGS = 0x8914 # set flags
313 SIOCGIFINDEX = 0x8933 # name -> if_index mapping
314 SIOCGIFCOUNT = 0x8938 # get number of devices
315 SIOCGSTAMP = 0x8906 # get packet timestamp (as a timeval)
319 IFF_UP = 0x1 # Interface is up.
320 IFF_BROADCAST = 0x2 # Broadcast address valid.
321 IFF_DEBUG = 0x4 # Turn on debugging.
322 IFF_LOOPBACK = 0x8 # Is a loopback net.
323 IFF_POINTOPOINT = 0x10 # Interface is point-to-point link.
324 IFF_NOTRAILERS = 0x20 # Avoid use of trailers.
325 IFF_RUNNING = 0x40 # Resources allocated.
326 IFF_NOARP = 0x80 # No address resolution protocol.
327 IFF_PROMISC = 0x100 # Receive all packets.
331 # From netpacket/packet.h
332 PACKET_ADD_MEMBERSHIP = 1
333 PACKET_DROP_MEMBERSHIP = 2
334 PACKET_RECV_OUTPUT = 3
336 PACKET_STATISTICS = 6
337 PACKET_MR_MULTICAST = 0
338 PACKET_MR_PROMISC = 1
339 PACKET_MR_ALLMULTI = 2
345 SO_ATTACH_FILTER = 26
349 RTF_UP = 0x0001 # Route usable
353 #BIOCIMMEDIATE=0x80044270
354 BIOCIMMEDIATE=-2147204496
359 # file parsing to get some values :
361 def load_protocols(filename):
362 spaces = re.compile("[ \t]+|\n")
363 dct = DADict(_name=filename)
365 for l in open(filename):
373 lt = tuple(re.split(spaces, l))
374 if len(lt) < 2 or not lt[0]:
376 dct[lt[0]] = int(lt[1])
378 log_loading.info("Couldn't parse file [%s]: line [%r] (%s)" % (filename,l,e))
380 log_loading.info("Can't open /etc/protocols file")
383 IP_PROTOS=load_protocols("/etc/protocols")
385 def load_ethertypes(filename):
386 spaces = re.compile("[ \t]+|\n")
387 dct = DADict(_name=filename)
398 lt = tuple(re.split(spaces, l))
399 if len(lt) < 2 or not lt[0]:
401 dct[lt[0]] = int(lt[1], 16)
403 log_loading.info("Couldn't parse file [%s]: line [%r] (%s)" % (filename,l,e))
409 ETHER_TYPES=load_ethertypes("/etc/ethertypes")
411 def load_services(filename):
412 spaces = re.compile("[ \t]+|\n")
413 tdct=DADict(_name="%s-tcp"%filename)
414 udct=DADict(_name="%s-udp"%filename)
425 lt = tuple(re.split(spaces, l))
426 if len(lt) < 2 or not lt[0]:
428 if lt[1].endswith("/tcp"):
429 tdct[lt[0]] = int(lt[1].split('/')[0])
430 elif lt[1].endswith("/udp"):
431 udct[lt[0]] = int(lt[1].split('/')[0])
433 log_loading.warning("Couldn't file [%s]: line [%r] (%s)" % (filename,l,e))
436 log_loading.info("Can't open /etc/services file")
439 TCP_SERVICES,UDP_SERVICES=load_services("/etc/services")
441 class ManufDA(DADict):
442 def fixname(self, val):
444 def _get_manuf_couple(self, mac):
445 oui = ":".join(mac.split(":")[:3]).upper()
446 return self.__dict__.get(oui,(mac,mac))
447 def _get_manuf(self, mac):
448 return self._get_manuf_couple(mac)[1]
449 def _get_short_manuf(self, mac):
450 return self._get_manuf_couple(mac)[0]
451 def _resolve_MAC(self, mac):
452 oui = ":".join(mac.split(":")[:3]).upper()
454 return ":".join([self[oui][0]]+ mac.split(":")[3:])
460 def load_manuf(filename):
462 manufdb=ManufDA(_name=filename)
463 for l in open(filename):
466 if not l or l.startswith("#"):
468 oui,shrt=l.split()[:2]
474 manufdb[oui] = shrt,lng
476 log_loading.warning("Couldn't parse one line from [%s] [%r] (%s)" % (filename, l, e))
478 #log_loading.warning("Couldn't open [%s] file" % filename)
482 MANUFDB = load_manuf("/usr/share/wireshark/wireshark/manuf")
495 if (j < 32) or (j >= 127):
496 r=r+conf.color_theme.not_printable(".")
505 if (j < 32) or (j >= 127):
512 if type(x) in (int,long):
514 elif type(x) is tuple:
515 return "(%s)" % ", ".join(map(lhex, x))
516 elif type(x) is list:
517 return "[%s]" % ", ".join(map(lhex, x))
529 print "%02X" % ord(x[i+j]),
535 print sane_color(x[i:i+16])
538 def linehexdump(x, onlyasc=0, onlyhex=0):
543 print "%02X" % ord(x[i]),
550 print ", ".join(map(lambda x: "%#04x"%ord(x), x))
552 def hexstr(x, onlyasc=0, onlyhex=0):
555 s.append(" ".join(map(lambda x:"%02x"%ord(x), x)))
568 for j in range(len(y)):
569 d[-1,j] = d[-1,j-1][0]+INSERT, (-1,j-1)
570 for i in range(len(x)):
571 d[i,-1] = d[i-1,-1][0]+INSERT, (i-1,-1)
573 for j in range(len(y)):
574 for i in range(len(x)):
575 d[i,j] = min( ( d[i-1,j-1][0]+SUBST*(x[i] != y[j]), (i-1,j-1) ),
576 ( d[i-1,j][0]+INSERT, (i-1,j) ),
577 ( d[i,j-1][0]+INSERT, (i,j-1) ) )
584 while not (i == j == -1):
586 backtrackx.append(x[i2+1:i+1])
587 backtracky.append(y[j2+1:j+1])
593 colorize = { 0: lambda x:x,
594 -1: conf.color_theme.left,
595 1: conf.color_theme.right }
602 linex = backtrackx[i:i+16]
603 liney = backtracky[i:i+16]
604 xx = sum(len(k) for k in linex)
605 yy = sum(len(k) for k in liney)
609 if dox and linex == liney:
618 print colorize[doy-dox]("%04x" % xd),
629 print colorize[doy-dox]("%04x" % yd),
641 col = colorize[(linex[j]!=liney[j])*(doy-dox)]
642 print col("%02X" % ord(line[j])),
643 if linex[j]==liney[j]:
644 cl += sane_color(line[j])
646 cl += col(sane(line[j]))
674 if len(pkt) % 2 == 1:
676 s = sum(array.array("H", pkt))
677 s = (s >> 16) + (s & 0xffff)
683 if len(pkt) % 2 == 1:
685 s = sum(array.array("H", pkt))
686 s = (s >> 16) + (s & 0xffff)
689 return (((s>>8)&0xff)|s<<8) & 0xffff
692 log_runtime.warning(x)
695 return "".join(map(lambda x: chr(int(x,16)), mac.split(":")))
698 return ("%02x:"*6)[:-1] % tuple(map(ord, s))
701 return "".join(map(lambda x,y:chr(ord(x)^ord(y)),x,y))
707 ip = inet_aton(socket.gethostbyname(x))
708 return struct.unpack("!I", ip)[0]
710 return inet_ntoa(struct.pack("!I", x))
713 return (0xffffffff00000000L>>x)&0xffffffffL
715 def do_graph(graph,prog=None,format="svg",target=None, type=None,string=None,options=None):
716 """do_graph(graph, prog=conf.prog.dot, format="svg",
717 target="| conf.prog.display", options=None, [string=1]):
718 string: if not None, simply return the graph string
719 graph: GraphViz graph description
720 format: output type (svg, ps, gif, jpg, etc.), passed to dot's "-T" option
721 target: filename or redirect. Defaults pipe to Imagemagick's display program
722 prog: which graphviz program to use
723 options: options to be passed to prog"""
733 target = "| %s" % conf.prog.display
734 if format is not None:
735 format = "-T %s" % format
736 w,r = os.popen2("%s %s %s %s" % (prog,options or "", format or "", target))
741 "{":"{\\tt\\char123}",
742 "}":"{\\tt\\char125}",
743 "\\":"{\\tt\\char92}",
751 "|":"{\\tt\\char124}",
752 "~":"{\\tt\\char126}",
753 "<":"{\\tt\\char60}",
754 ">":"{\\tt\\char62}",
760 s += _TEX_TR.get(c,c)
763 def colgen(*lstcol,**kargs):
764 """Returns a generator that mixes provided quantities forever
765 trans: a function to convert the three arguments into a color. lambda x,y,z:(x,y,z) by default"""
768 trans = kargs.get("trans", lambda x,y,z: (x,y,z))
770 for i in range(len(lstcol)):
771 for j in range(len(lstcol)):
772 for k in range(len(lstcol)):
773 if i != j or j != k or k != i:
774 yield trans(lstcol[(i+j)%len(lstcol)],lstcol[(j+k)%len(lstcol)],lstcol[(k+i)%len(lstcol)])
776 def incremental_label(label="tag%05i", start=0):
781 #########################
782 #### Enum management ####
783 #########################
787 def __init__(self, key, value):
791 return "<%s %s[%r]>" % (self.__dict__.get("_name", self.__class__.__name__), self._key, self._value)
792 def __getattr__(self, attr):
793 return getattr(self._value, attr)
796 def __eq__(self, other):
797 return self._value == int(other)
800 class Enum_metaclass(type):
801 element_class = EnumElement
802 def __new__(cls, name, bases, dct):
804 for k,v in dct.iteritems():
806 v = cls.element_class(k,v)
809 dct["__rdict__"] = rdict
810 return super(Enum_metaclass, cls).__new__(cls, name, bases, dct)
811 def __getitem__(self, attr):
812 return self.__rdict__[attr]
813 def __contains__(self, val):
814 return val in self.__rdict__
815 def get(self, attr, val=None):
816 return self._rdict__.get(attr, val)
818 return "<%s>" % self.__dict__.get("name", self.__name__)
823 ##############################
824 ## Session saving/restoring ##
825 ##############################
828 def save_session(fname, session=None, pickleProto=-1):
830 session = scapy_session
832 to_be_saved = session.copy()
834 if to_be_saved.has_key("__builtins__"):
835 del(to_be_saved["__builtins__"])
837 for k in to_be_saved.keys():
838 if type(to_be_saved[k]) in [types.TypeType, types.ClassType, types.ModuleType]:
839 log_interactive.error("[%s] (%s) can't be saved." % (k, type(to_be_saved[k])))
843 os.rename(fname, fname+".bak")
846 f=gzip.open(fname,"wb")
847 cPickle.dump(to_be_saved, f, pickleProto)
850 def load_session(fname):
852 s = cPickle.load(gzip.open(fname,"rb"))
854 s = cPickle.load(open(fname,"rb"))
855 scapy_session.clear()
856 scapy_session.update(s)
858 def update_session(fname):
860 s = cPickle.load(gzip.open(fname,"rb"))
862 s = cPickle.load(open(fname,"rb"))
863 scapy_session.update(s)
866 def export_object(obj):
867 print base64.encodestring(gzip.zlib.compress(cPickle.dumps(obj,2),9))
869 def import_object(obj=None):
871 obj = sys.stdin.read()
872 return cPickle.loads(gzip.zlib.decompress(base64.decodestring(obj.strip())))
875 def save_object(fname, obj):
876 cPickle.dump(obj,gzip.open(fname,"wb"))
878 def load_object(fname):
879 return cPickle.load(gzip.open(fname,"rb"))
882 ######################
883 ## Extension system ##
884 ######################
887 def load_extension(filename):
889 paths = conf.extensions_paths
890 if type(paths) is not list:
893 name = os.path.realpath(os.path.expanduser(filename))
894 thepath = os.path.dirname(name)
895 thename = os.path.basename(name)
896 if thename.endswith(".py"):
897 thename = thename[:-3]
899 paths.insert(0, thepath)
904 syspath = sys.path[:]
907 extf = imp.find_module(thename, paths)
909 log_runtime.error("Module [%s] not found. Check conf.extensions_paths ?" % filename)
911 ext = imp.load_module(thename, *extf)
913 __builtin__.__dict__.update(ext.__dict__)
937 """Add more powers to a class that have a "src" attribute."""
939 os.system("whois %s" % self.src)
941 t = [32,64,128,255]+[self.ttl]
943 return t[t.index(self.ttl)+1]
945 return self.ottl()-self.ttl-1
948 ##############################
949 ## Routing/Interfaces stuff ##
950 ##############################
955 self.s=socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
958 def invalidate_cache(self):
962 self.invalidate_cache()
963 self.routes = read_routes()
966 rt = "Network Netmask Gateway Iface Output IP\n"
967 for net,msk,gw,iface,addr in self.routes:
968 rt += "%-15s %-15s %-15s %-15s %-15s\n" % (ltoa(net),
975 def make_route(self, host=None, net=None, gw=None, dev=None):
978 elif net is not None:
979 thenet,msk = net.split("/")
982 raise Scapy_Exception("make_route: Incorrect parameters. You should specify a host or a net")
990 dev,ifaddr,x = self.route(nhop)
992 ifaddr = get_if_addr(dev)
993 return (atol(thenet), itom(msk), gw, dev, ifaddr)
995 def add(self, *args, **kargs):
997 add(net="192.168.1.0/24",gw="1.2.3.4")
999 self.invalidate_cache()
1000 self.routes.append(self.make_route(*args,**kargs))
1003 def delt(self, *args, **kargs):
1004 """delt(host|net, gw|dev)"""
1005 self.invalidate_cache()
1006 route = self.make_route(*args,**kargs)
1008 i=self.routes.index(route)
1011 warning("no matching route found")
1013 def ifchange(self, iff, addr):
1014 self.invalidate_cache()
1015 the_addr,the_msk = (addr.split("/")+["32"])[:2]
1016 the_msk = itom(int(the_msk))
1017 the_rawaddr = atol(the_addr)
1018 the_net = the_rawaddr & the_msk
1021 for i in range(len(self.routes)):
1022 net,msk,gw,iface,addr = self.routes[i]
1026 self.routes[i] = (the_net,the_msk,gw,iface,the_addr)
1028 self.routes[i] = (net,msk,gw,iface,the_addr)
1029 for i in arp_cache.keys():
1034 def ifdel(self, iff):
1035 self.invalidate_cache()
1037 for rt in self.routes:
1039 new_routes.append(rt)
1040 self.routes=new_routes
1042 def ifadd(self, iff, addr):
1043 self.invalidate_cache()
1044 the_addr,the_msk = (addr.split("/")+["32"])[:2]
1045 the_msk = itom(int(the_msk))
1046 the_rawaddr = atol(the_addr)
1047 the_net = the_rawaddr & the_msk
1048 self.routes.append((the_net,the_msk,'0.0.0.0',iff,the_addr))
1051 def route(self,dest,verbose=None):
1052 if dest in self.cache:
1053 return self.cache[dest]
1056 # Transform "192.168.*.1-5" to one IP of the set
1057 dst = dest.split("/")[0]
1058 dst = dst.replace("*","0")
1063 m = (dst[l:]+".").find(".")
1064 dst = dst[:l]+dst[l+m:]
1069 for d,m,gw,i,a in self.routes:
1072 pathes.append((0xffffffffL,("lo",a,"0.0.0.0")))
1073 if (dst & m) == (d & m):
1074 pathes.append((m,(i,a,gw)))
1077 warning("No route found (no default route?)")
1078 return "lo","0.0.0.0","0.0.0.0" #XXX linux specific!
1079 # Choose the more specific route (greatest netmask).
1080 # XXX: we don't care about metrics
1083 self.cache[dest] = ret
1086 def get_if_bcast(self, iff):
1087 for net, msk, gw, iface, addr in self.routes:
1088 if (iff == iface and net != 0L):
1089 bcast = atol(addr)|(~msk&0xffffffffL); # FIXME: check error in atol()
1091 warning("No broadcast address found for iface %s\n" % iff);
1094 def get_if_raw_hwaddr(iff):
1096 return (772, '\x00'*6)
1098 l = dnet.intf().get(iff)
1101 raise Scapy_Exception("Error in attempting to get hw address for interface [%s]" % iff)
1102 return l.type,l.data
1103 def get_if_raw_addr(ifname):
1105 return i.get(ifname)["addr"].data
1107 def get_if_raw_hwaddr(iff):
1108 return struct.unpack("16xh6s8x",get_if(iff,SIOCGIFHWADDR))
1110 def get_if_raw_addr(iff):
1112 return get_if(iff, SIOCGIFADDR)[20:24]
1119 # remove 'any' interface
1120 return map(lambda x:x[0],filter(lambda x:x[1] is None,pcap.findalldevs()))
1121 def get_working_if():
1123 return pcap.lookupdev()
1127 def attach_filter(s, filter):
1128 warning("attach_filter() should not be called in PCAP mode")
1129 def set_promisc(s,iff,val=1):
1130 warning("set_promisc() should not be called in DNET/PCAP mode")
1134 f=open("/proc/net/dev","r")
1139 lst.append(l.split(":")[0].strip())
1141 def get_working_if():
1142 for i in get_if_list():
1145 ifflags = struct.unpack("16xH14x",get_if(i,SIOCGIFFLAGS))[0]
1146 if ifflags & IFF_UP:
1149 def attach_filter(s, filter):
1150 # XXX We generate the filter on the interface conf.iface
1151 # because tcpdump open the "any" interface and ppp interfaces
1152 # in cooked mode. As we use them in raw mode, the filter will not
1153 # work... one solution could be to use "any" interface and translate
1154 # the filter from cooked mode to raw mode
1159 f = os.popen("%s -i %s -ddd -s 1600 '%s'" % (conf.prog.tcpdump,conf.iface,filter))
1161 log_interactive.warning("Failed to execute tcpdump: (%s)")
1163 lines = f.readlines()
1165 raise Scapy_Exception("Filter parse error")
1169 bpf += struct.pack("HBBI",*map(long,l.split()))
1171 # XXX. Argl! We need to give the kernel a pointer on the BPF,
1172 # python object header seems to be 20 bytes. 36 bytes for x86 64bits arch.
1174 bpfh = struct.pack("HL", nb, id(bpf)+36)
1176 bpfh = struct.pack("HI", nb, id(bpf)+20)
1177 s.setsockopt(SOL_SOCKET, SO_ATTACH_FILTER, bpfh)
1179 def set_promisc(s,iff,val=1):
1180 mreq = struct.pack("IHH8s", get_if_index(iff), PACKET_MR_PROMISC, 0, "")
1182 cmd = PACKET_ADD_MEMBERSHIP
1184 cmd = PACKET_DROP_MEMBERSHIP
1185 s.setsockopt(SOL_PACKET, cmd, mreq)
1190 def new_read_routes():
1198 print r.loop(addrt, rtlst)
1203 f=os.popen("netstat -rvn") # -f inet
1205 f=os.popen("netstat -rnW") # -W to handle long interface names
1207 f=os.popen("netstat -rn") # -f inet
1211 for l in f.readlines():
1215 if l.find("----") >= 0: # a separation line
1217 if l.find("Destination") >= 0:
1219 if l.find("Mtu") >= 0:
1227 dest,mask,gw,netif,mxfrg,rtt,ref,flg = l.split()[:8]
1230 dest,gw,flg,ref,use,mtu,netif = l.split()[:7]
1232 dest,gw,flg,ref,use,netif = l.split()[:6]
1233 if flg.find("Lc") >= 0:
1235 if dest == "default":
1240 netmask = atol(mask)
1242 dest,netmask = dest.split("/")
1243 netmask = itom(int(netmask))
1245 netmask = itom((dest.count(".") + 1) * 8)
1246 dest += ".0"*(3-dest.count("."))
1250 ifaddr = get_if_addr(netif)
1251 routes.append((dest,netmask,gw,netif,ifaddr))
1255 def read_interfaces():
1259 if not iff.has_key("addr"):
1261 if not iff.has_key("link_addr"):
1263 rawip = iff["addr"].data
1264 ip = inet_ntoa(rawip)
1265 rawll = iff["link_addr"].data
1267 lst[iff["name"]] = (rawll,ll,rawip,ip)
1268 i.loop(addif, ifflist)
1275 f=open("/proc/net/route","r")
1277 s=socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
1278 ifreq = ioctl(s, SIOCGIFADDR,struct.pack("16s16x","lo"))
1279 addrfamily = struct.unpack("h",ifreq[16:18])[0]
1280 if addrfamily == socket.AF_INET:
1281 ifreq2 = ioctl(s, SIOCGIFNETMASK,struct.pack("16s16x","lo"))
1282 msk = socket.ntohl(struct.unpack("I",ifreq2[20:24])[0])
1283 dst = socket.ntohl(struct.unpack("I",ifreq[20:24])[0]) & msk
1284 ifaddr = inet_ntoa(ifreq[20:24])
1285 routes.append((dst, msk, "0.0.0.0", "lo", ifaddr))
1287 warning("Interface lo: unkown address family (%i)"% addrfamily)
1289 for l in f.readlines()[1:]:
1290 iff,dst,gw,flags,x,x,x,msk,x,x,x = l.split()
1291 flags = int(flags,16)
1292 if flags & RTF_UP == 0:
1294 if flags & RTF_REJECT:
1297 ifreq = ioctl(s, SIOCGIFADDR,struct.pack("16s16x",iff))
1298 except IOError: # interface is present in routing tables but does not have any assigned IP
1301 addrfamily = struct.unpack("h",ifreq[16:18])[0]
1302 if addrfamily == socket.AF_INET:
1303 ifaddr = inet_ntoa(ifreq[20:24])
1305 warning("Interface %s: unkown address family (%i)"%(iff, addrfamily))
1307 routes.append((socket.htonl(long(dst,16))&0xffffffffL,
1308 socket.htonl(long(msk,16))&0xffffffffL,
1309 inet_ntoa(struct.pack("I",long(gw,16))),
1315 def get_if(iff,cmd):
1317 ifreq = ioctl(s, cmd, struct.pack("16s16x",iff))
1322 def get_if_index(iff):
1323 return int(struct.unpack("I",get_if(iff, SIOCGIFINDEX)[16:20])[0])
1325 def get_last_packet_timestamp(sock):
1326 ts = ioctl(sock, SIOCGSTAMP, "12345678")
1327 s,us = struct.unpack("II",ts)
1328 return s+us/1000000.0
1331 def get_if_addr(iff):
1332 return inet_ntoa(get_if_raw_addr(iff))
1334 def get_if_hwaddr(iff):
1335 addrfamily, mac = get_if_raw_hwaddr(iff)
1336 if addrfamily in [ARPHDR_ETHER,ARPHDR_LOOPBACK]:
1339 raise Scapy_Exception("Unsupported address family (%i) for interface [%s]" % (addrfamily,iff))
1343 #####################
1344 ## ARP cache stuff ##
1345 #####################
1349 # XXX Fill arp_cache with /etc/ether and arp cache
1352 if 0 and DNET: ## XXX Can't use this because it does not resolve IPs not in cache
1353 dnet_arp_object = dnet.arp()
1354 def getmacbyip(ip, chainCC=0):
1355 tmp = map(ord, inet_aton(ip))
1356 if (tmp[0] & 0xf0) == 0xe0: # mcast @
1357 return "01:00:5e:%.2x:%.2x:%.2x" % (tmp[1]&0x7f,tmp[2],tmp[3])
1358 iff,a,gw = conf.route.route(ip)
1360 return "ff:ff:ff:ff:ff:ff"
1363 res = dnet_arp_object.get(dnet.addr(ip))
1369 def getmacbyip(ip, chainCC=0):
1370 tmp = map(ord, inet_aton(ip))
1371 if (tmp[0] & 0xf0) == 0xe0: # mcast @
1372 return "01:00:5e:%.2x:%.2x:%.2x" % (tmp[1]&0x7f,tmp[2],tmp[3])
1373 iff,a,gw = conf.route.route(ip)
1374 if ( (iff == "lo") or (ip == conf.route.get_if_bcast(iff)) ):
1375 return "ff:ff:ff:ff:ff:ff"
1379 if arp_cache.has_key(ip):
1380 mac, timeout = arp_cache[ip]
1381 if not timeout or (time.time()-timeout < ARPTIMEOUT):
1384 res = srp1(Ether(dst=ETHER_BROADCAST)/ARP(op="who-has", pdst=ip),
1392 mac = res.payload.hwsrc
1393 arp_cache[ip] = (mac,time.time())
1398 ####################
1399 ## Random numbers ##
1400 ####################
1402 def randseq(inf, sup, seed=None, forever=1, renewkeys=0):
1403 """iterate through a sequence in random order.
1404 When all the values have been drawn, if forever=1, the drawing is done again.
1405 If renewkeys=0, the draw will be in the same order, guaranteeing that the same
1406 number will be drawn in not less than the number of integers of the sequence"""
1407 rnd = random.Random(seed)
1422 if turns == 0 or renewkeys:
1423 sbox = [rnd.randint(0,fsmask) for k in xrange(sbox_size)]
1429 for k in range(rounds): # Unbalanced Feistel Network
1432 lsb ^= sbox[ct%sbox_size]
1441 class VolatileValue:
1443 return "<%s>" % self.__class__.__name__
1444 def __getattr__(self, attr):
1445 if attr == "__setstate__":
1446 raise AttributeError(attr)
1447 return getattr(self._fix(),attr)
1452 class RandField(VolatileValue):
1456 class RandNum(RandField):
1459 def __init__(self, min, max):
1460 self.seq = randseq(min,max)
1462 return self.seq.next()
1464 class RandNumGamma(RandField):
1465 def __init__(self, alpha, beta):
1469 return int(round(random.gammavariate(self.alpha, self.beta)))
1471 class RandNumGauss(RandField):
1472 def __init__(self, mu, sigma):
1476 return int(round(random.gauss(self.mu, self.sigma)))
1478 class RandNumExpo(RandField):
1479 def __init__(self, lambd):
1482 return int(round(random.expovariate(self.lambd)))
1484 class RandByte(RandNum):
1486 RandNum.__init__(self, 0, 2L**8-1)
1488 class RandShort(RandNum):
1490 RandNum.__init__(self, 0, 2L**16-1)
1492 class RandInt(RandNum):
1494 RandNum.__init__(self, 0, 2L**32-1)
1496 class RandSInt(RandNum):
1498 RandNum.__init__(self, -2L**31, 2L**31-1)
1500 class RandLong(RandNum):
1502 RandNum.__init__(self, 0, 2L**64-1)
1504 class RandSLong(RandNum):
1506 RandNum.__init__(self, -2L**63, 2L**63-1)
1508 class RandChoice(RandField):
1509 def __init__(self, *args):
1511 raise TypeError("RandChoice needs at least one choice")
1514 return random.choice(self._choice)
1516 class RandString(RandField):
1517 def __init__(self, size, chars="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"):
1522 for i in range(self.size):
1523 s += random.choice(self.chars)
1526 class RandBin(RandString):
1527 def __init__(self, size):
1528 RandString.__init__(self, size, "".join(map(chr,range(256))))
1531 class RandTermString(RandString):
1532 def __init__(self, size, term):
1533 RandString.__init__(self, size, "".join(map(chr,range(1,256))))
1536 return RandString._fix(self)+self.term
1540 class RandIP(RandString):
1541 def __init__(self, iptemplate="0.0.0.0/0"):
1542 self.ip = Net(iptemplate)
1544 return self.ip.choice()
1546 class RandMAC(RandString):
1547 def __init__(self, template="*"):
1548 template += ":*:*:*:*:*"
1549 template = template.split(":")
1552 if template[i] == "*":
1554 elif "-" in template[i]:
1555 x,y = template[i].split("-")
1556 v = RandNum(int(x,16), int(y,16))
1558 v = int(template[i],16)
1561 return "%02x:%02x:%02x:%02x:%02x:%02x" % self.mac
1564 class RandOID(RandString):
1565 def __init__(self, fmt=None, depth=RandNumExpo(0.1), idnum=RandNumExpo(0.01)):
1568 fmt = fmt.split(".")
1569 for i in range(len(fmt)):
1571 fmt[i] = tuple(map(int, fmt[i].split("-")))
1576 if self.ori_fmt is None:
1577 return "<%s>" % self.__class__.__name__
1579 return "<%s [%s]>" % (self.__class__.__name__, self.ori_fmt)
1581 if self.fmt is None:
1582 return ".".join(map(str, [self.idnum for i in xrange(1+self.depth)]))
1587 oid.append(str(self.idnum))
1589 oid += map(str, [self.idnum for i in xrange(1+self.depth)])
1590 elif type(i) is tuple:
1591 oid.append(str(random.randrange(*i)))
1594 return ".".join(oid)
1598 class RandASN1Object(RandField):
1599 def __init__(self, objlist=None):
1601 objlist = map(lambda x:x._asn1_obj,
1602 filter(lambda x:hasattr(x,"_asn1_obj"), ASN1_Class_UNIVERSAL.__rdict__.values()))
1603 self.objlist = objlist
1604 self.chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
1605 def _fix(self, n=0):
1606 o = random.choice(self.objlist)
1607 if issubclass(o, ASN1_INTEGER):
1608 return o(int(random.gauss(0,1000)))
1609 elif issubclass(o, ASN1_STRING):
1610 z = int(random.expovariate(0.05)+1)
1611 return o("".join([random.choice(self.chars) for i in range(z)]))
1612 elif issubclass(o, ASN1_SEQUENCE) and (n < 10):
1613 z = int(random.expovariate(0.08)+1)
1614 return o(map(lambda x:x._fix(n+1), [self.__class__(objlist=self.objlist)]*z))
1615 return ASN1_INTEGER(int(random.gauss(0,1000)))
1617 class RandDHCPOptions(RandField):
1618 def __init__(self, size=None, rndstr=None):
1620 size = RandNumExpo(0.05)
1623 rndstr = RandBin(RandNum(0,255))
1625 self._opts = DHCPOptions.values()
1626 self._opts.remove("pad")
1627 self._opts.remove("end")
1630 for k in range(self.size):
1631 o = random.choice(self._opts)
1633 op.append((o,self.rndstr*1))
1635 op.append((o.name, o.randval()._fix()))
1639 # Automatic timestamp
1641 class AutoTime(VolatileValue):
1642 def __init__(self, base=None):
1646 self.diff = time.time()-base
1648 return time.time()-self.diff
1650 class IntAutoTime(AutoTime):
1652 return int(time.time()-self.diff)
1655 class ZuluTime(AutoTime):
1656 def __init__(self, diff=None):
1659 return time.strftime("%y%m%d%H%M%SZ",time.gmtime(time.time()+self.diff))
1662 class DelayedEval(VolatileValue):
1663 """ Exemple of usage: DelayedEval("time.time()") """
1664 def __init__(self, expr):
1667 return eval(self.expr)
1670 class IncrementalValue(VolatileValue):
1671 def __init__(self, start=0, step=1, restart=-1):
1672 self.start = self.val = start
1674 self.restart = restart
1677 if self.val == self.restart :
1678 self.val = self.start
1680 self.val += self.step
1683 def corrupt_bytes(s, p=0.01, n=None):
1684 s = array.array("B",str(s))
1688 for i in random.sample(xrange(l), n):
1689 s[i] = random.randint(0,255)
1692 def corrupt_bits(s, p=0.01, n=None):
1693 s = array.array("B",str(s))
1697 for i in random.sample(xrange(l), n):
1698 s[i/8] ^= 1 << (i%8)
1702 class CorruptedBytes(VolatileValue):
1703 def __init__(self, s, p=0.01, n=None):
1708 return corrupt_bytes(self.s, self.p, self.n)
1710 class CorruptedBits(CorruptedBytes):
1712 return corrupt_bits(self.s, self.p, self.n)
1718 class ASN1_Error(Exception):
1721 class ASN1_Encoding_Error(ASN1_Error):
1724 class ASN1_Decoding_Error(ASN1_Error):
1727 class ASN1_BadTag_Decoding_Error(ASN1_Decoding_Error):
1732 class ASN1Codec(EnumElement):
1733 def register_stem(cls, stem):
1735 def dec(cls, s, context=None):
1736 return cls._stem.dec(s, context=context)
1737 def safedec(cls, s, context=None):
1738 return cls._stem.safedec(s, context=context)
1743 class ASN1_Codecs_metaclass(Enum_metaclass):
1744 element_class = ASN1Codec
1747 __metaclass__ = ASN1_Codecs_metaclass
1758 class ASN1Tag(EnumElement):
1759 def __init__(self, key, value, context=None, codec=None):
1760 EnumElement.__init__(self, key, value)
1761 self._context = context
1765 def clone(self): # /!\ not a real deep copy. self.codec is shared
1766 return self.__class__(self._key, self._value, self._context, self._codec)
1767 def register_asn1_object(self, asn1obj):
1768 self._asn1_obj = asn1obj
1769 def asn1_object(self, val):
1770 if hasattr(self,"_asn1_obj"):
1771 return self._asn1_obj(val)
1772 raise ASN1_Error("%r does not have any assigned ASN1 object" % self)
1773 def register(self, codecnum, codec):
1774 self._codec[codecnum] = codec
1775 def get_codec(self, codec):
1777 c = self._codec[codec]
1778 except KeyError,msg:
1779 raise ASN1_Error("Codec %r not found for tag %r" % (codec, self))
1782 class ASN1_Class_metaclass(Enum_metaclass):
1783 element_class = ASN1Tag
1784 def __new__(cls, name, bases, dct): # XXX factorise a bit with Enum_metaclass.__new__()
1786 for k,v in b.__dict__.iteritems():
1787 if k not in dct and isinstance(v,ASN1Tag):
1791 for k,v in dct.iteritems():
1796 elif isinstance(v, ASN1Tag):
1798 dct["__rdict__"] = rdict
1800 cls = type.__new__(cls, name, bases, dct)
1801 for v in cls.__dict__.values():
1802 if isinstance(v, ASN1Tag):
1803 v.context = cls # overwrite ASN1Tag contexts, even cloned ones
1808 __metaclass__ = ASN1_Class_metaclass
1810 class ASN1_Class_UNIVERSAL(ASN1_Class):
1822 OBJECT_DESCRIPTOR = 7
1829 SEQUENCE = 0x30#XXX 16 ??
1830 SET = 0x31 #XXX 17 ??
1832 PRINTABLE_STRING = 19
1834 VIDEOTEX_STRING = 21
1837 GENERALIZED_TIME = 24
1841 UNIVERSAL_STRING = 28
1847 class ASN1_Object_metaclass(type):
1848 def __new__(cls, name, bases, dct):
1849 c = super(ASN1_Object_metaclass, cls).__new__(cls, name, bases, dct)
1851 c.tag.register_asn1_object(c)
1853 warning("Error registering %r for %r" % (c.tag, c.codec))
1858 __metaclass__ = ASN1_Object_metaclass
1859 tag = ASN1_Class_UNIVERSAL.ANY
1860 def __init__(self, val):
1862 def enc(self, codec):
1863 return self.tag.get_codec(codec).enc(self.val)
1865 return "<%s[%r]>" % (self.__dict__.get("name", self.__class__.__name__), self.val)
1867 return self.enc(conf.ASN1_default_codec)
1868 def strshow(self, lvl=0):
1869 return (" "*lvl)+repr(self)+"\n"
1870 def show(self, lvl=0):
1871 print self.strshow(lvl)
1872 def __eq__(self, other):
1873 return self.val == other
1874 def __cmp__(self, other):
1875 return cmp(self.val, other)
1877 class ASN1_DECODING_ERROR(ASN1_Object):
1878 tag = ASN1_Class_UNIVERSAL.ERROR
1879 def __init__(self, val, exc=None):
1880 ASN1_Object.__init__(self, val)
1883 return "<%s[%r]{{%s}}>" % (self.__dict__.get("name", self.__class__.__name__),
1884 self.val, self.exc.args[0])
1885 def enc(self, codec):
1886 if isinstance(self.val, ASN1_Object):
1887 return self.val.enc(codec)
1890 class ASN1_force(ASN1_Object):
1891 tag = ASN1_Class_UNIVERSAL.RAW
1892 def enc(self, codec):
1893 if isinstance(self.val, ASN1_Object):
1894 return self.val.enc(codec)
1897 class ASN1_BADTAG(ASN1_force):
1900 class ASN1_INTEGER(ASN1_Object):
1901 tag = ASN1_Class_UNIVERSAL.INTEGER
1903 class ASN1_STRING(ASN1_Object):
1904 tag = ASN1_Class_UNIVERSAL.STRING
1906 class ASN1_BIT_STRING(ASN1_STRING):
1907 tag = ASN1_Class_UNIVERSAL.BIT_STRING
1909 class ASN1_PRINTABLE_STRING(ASN1_STRING):
1910 tag = ASN1_Class_UNIVERSAL.PRINTABLE_STRING
1912 class ASN1_T61_STRING(ASN1_STRING):
1913 tag = ASN1_Class_UNIVERSAL.T61_STRING
1915 class ASN1_IA5_STRING(ASN1_STRING):
1916 tag = ASN1_Class_UNIVERSAL.IA5_STRING
1918 class ASN1_NUMERIC_STRING(ASN1_STRING):
1919 tag = ASN1_Class_UNIVERSAL.NUMERIC_STRING
1921 class ASN1_VIDEOTEX_STRING(ASN1_STRING):
1922 tag = ASN1_Class_UNIVERSAL.VIDEOTEX_STRING
1924 class ASN1_UTC_TIME(ASN1_STRING):
1925 tag = ASN1_Class_UNIVERSAL.UTC_TIME
1927 class ASN1_TIME_TICKS(ASN1_INTEGER):
1928 tag = ASN1_Class_UNIVERSAL.TIME_TICKS
1930 class ASN1_BOOLEAN(ASN1_INTEGER):
1931 tag = ASN1_Class_UNIVERSAL.BOOLEAN
1933 class ASN1_NULL(ASN1_INTEGER):
1934 tag = ASN1_Class_UNIVERSAL.NULL
1936 class ASN1_COUNTER32(ASN1_INTEGER):
1937 tag = ASN1_Class_UNIVERSAL.COUNTER32
1939 class ASN1_SEQUENCE(ASN1_Object):
1940 tag = ASN1_Class_UNIVERSAL.SEQUENCE
1941 def strshow(self, lvl=0):
1942 s = (" "*lvl)+("# %s:" % self.__class__.__name__)+"\n"
1944 s += o.strshow(lvl=lvl+1)
1947 class ASN1_SET(ASN1_SEQUENCE):
1948 tag = ASN1_Class_UNIVERSAL.SET
1950 class ASN1_OID(ASN1_Object):
1951 tag = ASN1_Class_UNIVERSAL.OID
1952 def __init__(self, val):
1953 val = conf.mib._oid(val)
1954 ASN1_Object.__init__(self, val)
1956 return "<%s[%r]>" % (self.__dict__.get("name", self.__class__.__name__), conf.mib._oidname(self.val))
1966 #####[ BER tools ]#####
1969 class BER_Exception(Exception):
1972 class BER_Decoding_Error(ASN1_Decoding_Error):
1973 def __init__(self, msg, decoded=None, remaining=None):
1974 Exception.__init__(self, msg)
1975 self.remaining = remaining
1976 self.decoded = decoded
1978 s = Exception.__str__(self)
1979 if isinstance(self.decoded, BERcodec_Object):
1980 s+="\n### Already decoded ###\n%s" % self.decoded.strshow()
1982 s+="\n### Already decoded ###\n%r" % self.decoded
1983 s+="\n### Remaining ###\n%r" % self.remaining
1986 class BER_BadTag_Decoding_Error(BER_Decoding_Error, ASN1_BadTag_Decoding_Error):
1989 def BER_len_enc(l, size=0):
1990 if l <= 127 and size==0:
1998 raise BER_Exception("BER_len_enc: Length too long (%i) to be encoded [%r]" % (len(s),s))
1999 return chr(len(s)|0x80)+s
2006 raise BER_Decoding_Error("BER_len_dec: Got %i bytes while expecting %i" % (len(s)-1, l),remaining=s)
2013 def BER_num_enc(l, size=1):
2016 x.insert(0, l & 0x7f)
2021 return "".join([chr(k) for k in x])
2024 for i in range(len(s)):
2031 raise BER_Decoding_Error("BER_num_dec: unfinished number description", remaining=s)
2034 #####[ BER classes ]#####
2036 class BERcodec_metaclass(type):
2037 def __new__(cls, name, bases, dct):
2038 c = super(BERcodec_metaclass, cls).__new__(cls, name, bases, dct)
2040 c.tag.register(c.codec, c)
2042 warning("Error registering %r for %r" % (c.tag, c.codec))
2046 class BERcodec_Object:
2047 __metaclass__ = BERcodec_metaclass
2048 codec = ASN1_Codecs.BER
2049 tag = ASN1_Class_UNIVERSAL.ANY
2052 def asn1_object(cls, val):
2053 return cls.tag.asn1_object(val)
2056 def check_string(cls, s):
2058 raise BER_Decoding_Error("%s: Got empty object while expecting tag %r" %
2059 (cls.__name__,cls.tag), remaining=s)
2061 def check_type(cls, s):
2063 if cls.tag != ord(s[0]):
2064 raise BER_BadTag_Decoding_Error("%s: Got tag [%i/%#x] while expecting %r" %
2065 (cls.__name__, ord(s[0]), ord(s[0]),cls.tag), remaining=s)
2068 def check_type_get_len(cls, s):
2069 s2 = cls.check_type(s)
2071 raise BER_Decoding_Error("%s: No bytes while expecting a length" %
2072 cls.__name__, remaining=s)
2073 return BER_len_dec(s2)
2075 def check_type_check_len(cls, s):
2076 l,s3 = cls.check_type_get_len(s)
2078 raise BER_Decoding_Error("%s: Got %i bytes while expecting %i" %
2079 (cls.__name__, len(s3), l), remaining=s)
2080 return l,s3[:l],s3[l:]
2083 def do_dec(cls, s, context=None, safe=False):
2085 context = cls.tag.context
2088 if p not in context:
2092 raise BER_Decoding_Error("Unknown prefix [%02x] for [%r]" % (p,t), remaining=s)
2093 codec = context[p].get_codec(ASN1_Codecs.BER)
2094 return codec.dec(s,context,safe)
2097 def dec(cls, s, context=None, safe=False):
2099 return cls.do_dec(s, context, safe)
2101 return cls.do_dec(s, context, safe)
2102 except BER_BadTag_Decoding_Error,e:
2103 o,remain = BERcodec_Object.dec(e.remaining, context, safe)
2104 return ASN1_BADTAG(o),remain
2105 except BER_Decoding_Error, e:
2106 return ASN1_DECODING_ERROR(s, exc=e),""
2107 except ASN1_Error, e:
2108 return ASN1_DECODING_ERROR(s, exc=e),""
2111 def safedec(cls, s, context=None):
2112 return cls.dec(s, context, safe=True)
2118 return BERcodec_STRING.enc(s)
2120 return BERcodec_INTEGER.enc(int(s))
2124 ASN1_Codecs.BER.register_stem(BERcodec_Object)
2127 class BERcodec_INTEGER(BERcodec_Object):
2128 tag = ASN1_Class_UNIVERSAL.INTEGER
2142 s.append(BER_len_enc(len(s)))
2143 s.append(chr(cls.tag))
2147 def do_dec(cls, s, context=None, safe=False):
2148 l,s,t = cls.check_type_check_len(s)
2151 if ord(s[0])&0x80: # negative int
2156 return cls.asn1_object(x),t
2159 class BERcodec_BOOLEAN(BERcodec_INTEGER):
2160 tag = ASN1_Class_UNIVERSAL.BOOLEAN
2162 class BERcodec_NULL(BERcodec_INTEGER):
2163 tag = ASN1_Class_UNIVERSAL.NULL
2167 return chr(cls.tag)+"\0"
2169 return super(cls,cls).enc(i)
2171 class BERcodec_STRING(BERcodec_Object):
2172 tag = ASN1_Class_UNIVERSAL.STRING
2175 return chr(cls.tag)+BER_len_enc(len(s))+s
2177 def do_dec(cls, s, context=None, safe=False):
2178 l,s,t = cls.check_type_check_len(s)
2179 return cls.tag.asn1_object(s),t
2181 class BERcodec_BIT_STRING(BERcodec_STRING):
2182 tag = ASN1_Class_UNIVERSAL.BIT_STRING
2184 class BERcodec_PRINTABLE_STRING(BERcodec_STRING):
2185 tag = ASN1_Class_UNIVERSAL.PRINTABLE_STRING
2187 class BERcodec_T61_STRING (BERcodec_STRING):
2188 tag = ASN1_Class_UNIVERSAL.T61_STRING
2190 class BERcodec_IA5_STRING(BERcodec_STRING):
2191 tag = ASN1_Class_UNIVERSAL.IA5_STRING
2193 class BERcodec_UTC_TIME(BERcodec_STRING):
2194 tag = ASN1_Class_UNIVERSAL.UTC_TIME
2196 class BERcodec_TIME_TICKS(BERcodec_INTEGER):
2197 tag = ASN1_Class_UNIVERSAL.TIME_TICKS
2199 class BERcodec_COUNTER32(BERcodec_INTEGER):
2200 tag = ASN1_Class_UNIVERSAL.COUNTER32
2202 class BERcodec_SEQUENCE(BERcodec_Object):
2203 tag = ASN1_Class_UNIVERSAL.SEQUENCE
2206 if type(l) is not str:
2207 l = "".join(map(lambda x: x.enc(cls.codec), l))
2208 return chr(cls.tag)+BER_len_enc(len(l))+l
2210 def do_dec(cls, s, context=None, safe=False):
2212 context = cls.tag.context
2213 l,st = cls.check_type_get_len(s) # we may have len(s) < l
2218 o,s = BERcodec_Object.dec(s, context, safe)
2219 except BER_Decoding_Error, err:
2221 if err.decoded is not None:
2222 obj.append(err.decoded)
2227 raise BER_Decoding_Error("Not enough bytes to decode sequence", decoded=obj)
2228 return cls.asn1_object(obj),t
2230 class BERcodec_SET(BERcodec_SEQUENCE):
2231 tag = ASN1_Class_UNIVERSAL.SET
2234 class BERcodec_OID(BERcodec_Object):
2235 tag = ASN1_Class_UNIVERSAL.OID
2239 lst = [int(x) for x in oid.strip(".").split(".")]
2243 s = "".join([BER_num_enc(k) for k in lst])
2244 return chr(cls.tag)+BER_len_enc(len(s))+s
2246 def do_dec(cls, s, context=None, safe=False):
2247 l,s,t = cls.check_type_check_len(s)
2250 l,s = BER_num_dec(s)
2253 lst.insert(0,lst[0]/40)
2255 return cls.asn1_object(".".join([str(k) for k in lst])), t
2262 _mib_re_integer = re.compile("^[0-9]+$")
2263 _mib_re_both = re.compile("^([a-zA-Z_][a-zA-Z0-9_-]*)\(([0-9]+)\)$")
2264 _mib_re_oiddecl = re.compile("$\s*([a-zA-Z0-9_-]+)\s+OBJECT([^:\{\}]|\{[^:]+\})+::=\s*\{([^\}]+)\}",re.M)
2265 _mib_re_strings = re.compile('"[^"]*"')
2266 _mib_re_comments = re.compile('--.*(\r|\n)')
2268 class MIBDict(DADict):
2269 def _findroot(self, x):
2270 if x.startswith("."):
2272 if not x.endswith("."):
2276 for k in self.keys():
2277 if x.startswith(self[k]+"."):
2278 if max < len(self[k]):
2281 return root, x[max:-1]
2282 def _oidname(self, x):
2283 root,remainder = self._findroot(x)
2284 return root+remainder
2286 xl = x.strip(".").split(".")
2288 while p >= 0 and _mib_re_integer.match(xl[p]):
2290 if p != 0 or xl[p] not in self:
2293 return ".".join(xl[p:])
2294 def _make_graph(self, other_keys=[], **kargs):
2295 nodes = [(k,self[k]) for k in self.keys()]
2296 oids = [self[k] for k in self.keys()]
2297 for k in other_keys:
2299 nodes.append(self.oidname(k),k)
2300 s = 'digraph "mib" {\n\trankdir=LR;\n\n'
2302 s += '\t"%s" [ label="%s" ];\n' % (o,k)
2305 parent,remainder = self._findroot(o[:-1])
2306 remainder = remainder[1:]+o[-1]
2308 parent = self[parent]
2309 s += '\t"%s" -> "%s" [label="%s"];\n' % (parent, o,remainder)
2311 do_graph(s, **kargs)
2314 def mib_register(ident, value, the_mib, unresolved):
2315 if ident in the_mib or ident in unresolved:
2316 return ident in the_mib
2320 if _mib_re_integer.match(v):
2324 if v not in the_mib:
2328 elif v in unresolved:
2335 unresolved[ident] = resval
2338 the_mib[ident] = resval
2339 keys = unresolved.keys()
2341 while i < len(keys):
2343 if mib_register(k,unresolved[k], the_mib, {}):
2353 def load_mib(filenames):
2354 the_mib = {'iso': ['1']}
2356 for k in conf.mib.keys():
2357 mib_register(k, conf.mib[k].split("."), the_mib, unresolved)
2359 if type(filenames) is str:
2360 filenames = [filenames]
2361 for fnames in filenames:
2362 for fname in glob(fnames):
2365 cleantext = " ".join(_mib_re_strings.split(" ".join(_mib_re_comments.split(text))))
2366 for m in _mib_re_oiddecl.finditer(cleantext):
2368 ident,oid = gr[0],gr[-1]
2369 ident=fixname(ident)
2371 for i in range(len(oid)):
2372 m = _mib_re_both.match(oid[i])
2374 oid[i] = m.groups()[1]
2375 mib_register(ident, oid, the_mib, unresolved)
2377 newmib = MIBDict(_name="MIB")
2378 for k,o in the_mib.iteritems():
2379 newmib[k]=".".join(o)
2380 for k,o in unresolved.iteritems():
2381 newmib[k]=".".join(o)
2396 def __init__(self, set, _iterpacket=1):
2397 self._iterpacket=_iterpacket
2398 if type(set) is list:
2400 elif isinstance(set, PacketList):
2401 self.set = list(set)
2404 def transf(self, element):
2408 if (type(i) is tuple) and (len(i) == 2) and type(i[0]) is int and type(i[1]) is int:
2414 elif isinstance(i, Gen) and (self._iterpacket or not isinstance(i,Packet)):
2420 return "<SetGen %s>" % self.set.__repr__()
2423 """Generate a list of IPs from a network address or a name"""
2425 ipaddress = re.compile(r"^(\*|[0-2]?[0-9]?[0-9](-[0-2]?[0-9]?[0-9])?)\.(\*|[0-2]?[0-9]?[0-9](-[0-2]?[0-9]?[0-9])?)\.(\*|[0-2]?[0-9]?[0-9](-[0-2]?[0-9]?[0-9])?)\.(\*|[0-2]?[0-9]?[0-9](-[0-2]?[0-9]?[0-9])?)(/[0-3]?[0-9])?$")
2426 def __init__(self, net):
2429 tmp=net.split('/')+["32"]
2430 if not self.ipaddress.match(net):
2431 tmp[0]=socket.gethostbyname(tmp[0])
2432 netmask = int(tmp[1])
2434 def parse_digit(a,netmask):
2435 netmask = min(8,max(netmask,0))
2438 elif a.find("-") >= 0:
2439 x,y = map(int,a.split("-"))
2442 a = (x & (0xffL<<netmask) , max(y, (x | (0xffL>>(8-netmask))))+1)
2444 a = (int(a) & (0xffL<<netmask),(int(a) | (0xffL>>(8-netmask)))+1)
2447 self.parsed = map(lambda x,y: parse_digit(x,y), tmp[0].split("."), map(lambda x,nm=netmask: x-nm, (8,16,24,32)))
2450 for d in xrange(*self.parsed[3]):
2451 for c in xrange(*self.parsed[2]):
2452 for b in xrange(*self.parsed[1]):
2453 for a in xrange(*self.parsed[0]):
2454 yield "%i.%i.%i.%i" % (a,b,c,d)
2457 for v in self.parsed:
2458 ip.append(str(random.randint(v[0],v[1]-1)))
2462 return "Net(%r)" % self.repr
2466 def __init__(self, oid):
2470 for i in oid.split("."):
2473 self.cmpt.append(tuple(map(int, i.split("-"))))
2476 self.fmt = ".".join(fmt)
2478 return "OID(%r)" % self.oid
2480 ii = [k[0] for k in self.cmpt]
2482 yield self.fmt % tuple(ii)
2487 if ii[i] < self.cmpt[i][1]:
2491 ii[i] = self.cmpt[i][0]
2501 def __init__(self, res=None, name="PacketList", stats=None):
2502 """create a packet list from a list of packets
2503 res: the list of packets
2504 stats: a list of classes that will appear in the stats (defaults to [TCP,UDP,ICMP])"""
2506 stats = [ TCP,UDP,ICMP ]
2510 if isinstance(res, PacketList):
2513 self.listname = name
2514 def _elt2pkt(self, elt):
2516 def _elt2sum(self, elt):
2517 return elt.summary()
2518 def _elt2show(self, elt):
2519 return self._elt2sum(elt)
2521 # stats=dict.fromkeys(self.stats,0) ## needs python >= 2.3 :(
2522 stats = dict(map(lambda x: (x,0), self.stats))
2527 if self._elt2pkt(r).haslayer(p):
2534 ct = conf.color_theme
2535 for p in self.stats:
2536 s += " %s%s%s" % (ct.packetlist_proto(p.name),
2538 ct.packetlist_value(stats[p]))
2539 s += " %s%s%s" % (ct.packetlist_proto("Other"),
2541 ct.packetlist_value(other))
2542 return "%s%s%s%s%s" % (ct.punct("<"),
2543 ct.packetlist_name(self.listname),
2547 def __getattr__(self, attr):
2548 return getattr(self.res, attr)
2549 def __getitem__(self, item):
2550 if isinstance(item,type) and issubclass(item,Packet):
2551 return self.__class__(filter(lambda x: item in self._elt2pkt(x),self.res),
2552 name="%s from %s"%(item.__name__,self.listname))
2553 if type(item) is slice:
2554 return self.__class__(self.res.__getitem__(item),
2555 name = "mod %s" % self.listname)
2556 return self.res.__getitem__(item)
2557 def __getslice__(self, *args, **kargs):
2558 return self.__class__(self.res.__getslice__(*args, **kargs),
2559 name="mod %s"%self.listname)
2560 def __add__(self, other):
2561 return self.__class__(self.res+other.res,
2562 name="%s+%s"%(self.listname,other.listname))
2563 def summary(self, prn=None, lfilter=None):
2564 """prints a summary of each packet
2565 prn: function to apply to each packet instead of lambda x:x.summary()
2566 lfilter: truth function to apply to each packet to decide whether it will be displayed"""
2568 if lfilter is not None:
2572 print self._elt2sum(r)
2575 def nsummary(self,prn=None, lfilter=None):
2576 """prints a summary of each packet with the packet's number
2577 prn: function to apply to each packet instead of lambda x:x.summary()
2578 lfilter: truth function to apply to each packet to decide whether it will be displayed"""
2579 for i in range(len(self.res)):
2580 if lfilter is not None:
2581 if not lfilter(self.res[i]):
2583 print conf.color_theme.id(i,"%04i"),
2585 print self._elt2sum(self.res[i])
2587 print prn(self.res[i])
2588 def display(self): # Deprecated. Use show()
2589 """deprecated. is show()"""
2591 def show(self, *args, **kargs):
2592 """Best way to display the packet list. Defaults to nsummary() method"""
2593 return self.nsummary(*args, **kargs)
2595 def filter(self, func):
2596 """Returns a packet list filtered by a truth function"""
2597 return self.__class__(filter(func,self.res),
2598 name="filtered %s"%self.listname)
2599 def make_table(self, *args, **kargs):
2600 """Prints a table using a function that returs for each packet its head column value, head row value and displayed value
2601 ex: p.make_table(lambda x:(x[IP].dst, x[TCP].dport, x[TCP].sprintf("%flags%")) """
2602 return make_table(self.res, *args, **kargs)
2603 def make_lined_table(self, *args, **kargs):
2604 """Same as make_table, but print a table with lines"""
2605 return make_lined_table(self.res, *args, **kargs)
2606 def make_tex_table(self, *args, **kargs):
2607 """Same as make_table, but print a table with LaTeX syntax"""
2608 return make_tex_table(self.res, *args, **kargs)
2610 def plot(self, f, lfilter=None,**kargs):
2611 """Applies a function to each packet to get a value that will be plotted with GnuPlot. A gnuplot object is returned
2612 lfilter: a truth function that decides whether a packet must be ploted"""
2615 if lfilter is not None:
2616 l = filter(lfilter, l)
2618 g.plot(Gnuplot.Data(l, **kargs))
2621 def diffplot(self, f, delay=1, lfilter=None, **kargs):
2622 """diffplot(f, delay=1, lfilter=None)
2623 Applies a function to couples (l[i],l[i+delay])"""
2624 g = Gnuplot.Gnuplot()
2626 if lfilter is not None:
2627 l = filter(lfilter, l)
2628 l = map(f,l[:-delay],l[delay:])
2629 g.plot(Gnuplot.Data(l, **kargs))
2632 def multiplot(self, f, lfilter=None, **kargs):
2633 """Uses a function that returns a label and a value for this label, then plots all the values label by label"""
2636 if lfilter is not None:
2637 l = filter(lfilter, l)
2648 data.append(Gnuplot.Data(d[k], title=k, **kargs))
2654 def rawhexdump(self):
2655 """Prints an hexadecimal dump of each packet in the list"""
2657 hexdump(self._elt2pkt(p))
2659 def hexraw(self, lfilter=None):
2660 """Same as nsummary(), except that if a packet has a Raw layer, it will be hexdumped
2661 lfilter: a truth function that decides whether a packet must be displayed"""
2662 for i in range(len(self.res)):
2663 p = self._elt2pkt(self.res[i])
2664 if lfilter is not None and not lfilter(p):
2666 print "%s %s %s" % (conf.color_theme.id(i,"%04i"),
2667 p.sprintf("%.time%"),
2668 self._elt2sum(self.res[i]))
2670 hexdump(p.getlayer(Raw).load)
2672 def hexdump(self, lfilter=None):
2673 """Same as nsummary(), except that packets are also hexdumped
2674 lfilter: a truth function that decides whether a packet must be displayed"""
2675 for i in range(len(self.res)):
2676 p = self._elt2pkt(self.res[i])
2677 if lfilter is not None and not lfilter(p):
2679 print "%s %s %s" % (conf.color_theme.id(i,"%04i"),
2680 p.sprintf("%.time%"),
2681 self._elt2sum(self.res[i]))
2684 def padding(self, lfilter=None):
2685 """Same as hexraw(), for Padding layer"""
2686 for i in range(len(self.res)):
2687 p = self._elt2pkt(self.res[i])
2688 if p.haslayer(Padding):
2689 if lfilter is None or lfilter(p):
2690 print "%s %s %s" % (conf.color_theme.id(i,"%04i"),
2691 p.sprintf("%.time%"),
2692 self._elt2sum(self.res[i]))
2693 hexdump(p.getlayer(Padding).load)
2695 def nzpadding(self, lfilter=None):
2696 """Same as padding() but only non null padding"""
2697 for i in range(len(self.res)):
2698 p = self._elt2pkt(self.res[i])
2699 if p.haslayer(Padding):
2700 pad = p.getlayer(Padding).load
2701 if pad == pad[0]*len(pad):
2703 if lfilter is None or lfilter(p):
2704 print "%s %s %s" % (conf.color_theme.id(i,"%04i"),
2705 p.sprintf("%.time%"),
2706 self._elt2sum(self.res[i]))
2707 hexdump(p.getlayer(Padding).load)
2710 def conversations(self, getsrcdst=None,**kargs):
2711 """Graphes a conversations between sources and destinations and display it
2712 (using graphviz and imagemagick)
2713 getsrcdst: a function that takes an element of the list and return the source and dest
2714 by defaults, return source and destination IP
2715 type: output type (svg, ps, gif, jpg, etc.), passed to dot's "-T" option
2716 target: filename or redirect. Defaults pipe to Imagemagick's display program
2717 prog: which graphviz program to use"""
2718 if getsrcdst is None:
2719 getsrcdst = lambda x:(x[IP].src, x[IP].dst)
2722 p = self._elt2pkt(p)
2728 conv[c] = conv.get(c,0)+1
2729 gr = 'digraph "conv" {\n'
2731 gr += '\t "%s" -> "%s"\n' % (s,d)
2733 return do_graph(gr, **kargs)
2735 def afterglow(self, src=None, event=None, dst=None, **kargs):
2736 """Experimental clone attempt of http://sourceforge.net/projects/afterglow
2737 each datum is reduced as src -> event -> dst and the data are graphed.
2738 by default we have IP.src -> IP.dport -> IP.dst"""
2740 src = lambda x: x[IP].src
2742 event = lambda x: x[IP].dport
2744 dst = lambda x: x[IP].dst
2750 s,e,d = src(i),event(i),dst(i)
2767 dl[d] = dl.get(d,0)+1
2773 return 2+math.log(n)/4.0
2783 mins,maxs = minmax(map(lambda (x,y): x, sl.values()))
2784 mine,maxe = minmax(map(lambda (x,y): x, el.values()))
2785 mind,maxd = minmax(dl.values())
2787 gr = 'digraph "afterglow" {\n\tedge [len=2.5];\n'
2789 gr += "# src nodes\n"
2791 n,l = sl[s]; n = 1+float(n-mins)/(maxs-mins)
2792 gr += '"src.%s" [label = "%s", shape=box, fillcolor="#FF0000", style=filled, fixedsize=1, height=%.2f,width=%.2f];\n' % (`s`,`s`,n,n)
2793 gr += "# event nodes\n"
2795 n,l = el[e]; n = n = 1+float(n-mine)/(maxe-mine)
2796 gr += '"evt.%s" [label = "%s", shape=circle, fillcolor="#00FFFF", style=filled, fixedsize=1, height=%.2f, width=%.2f];\n' % (`e`,`e`,n,n)
2798 n = dl[d]; n = n = 1+float(n-mind)/(maxd-mind)
2799 gr += '"dst.%s" [label = "%s", shape=triangle, fillcolor="#0000ff", style=filled, fixedsize=1, height=%.2f, width=%.2f];\n' % (`d`,`d`,n,n)
2805 gr += ' "src.%s" -> "evt.%s";\n' % (`s`,`e`)
2809 gr += ' "evt.%s" -> "dst.%s";\n' % (`e`,`d`)
2812 open("/tmp/aze","w").write(gr)
2813 return do_graph(gr, **kargs)
2817 def timeskew_graph(self, ip, **kargs):
2818 """Tries to graph the timeskew between the timestamps and real time for a given ip"""
2819 res = map(lambda x: self._elt2pkt(x), self.res)
2820 b = filter(lambda x:x.haslayer(IP) and x.getlayer(IP).src == ip and x.haslayer(TCP), res)
2823 opts = p.getlayer(TCP).options
2825 if o[0] == "Timestamp":
2826 c.append((p.time,o[1][0]))
2828 warning("No timestamps found in packet list")
2830 d = map(lambda (x,y): (x%2000,((x-c[0][0])-((y-c[0][1])/1000.0))),c)
2831 g = Gnuplot.Gnuplot()
2832 g.plot(Gnuplot.Data(d,**kargs))
2835 def _dump_document(self, **kargs):
2836 d = pyx.document.document()
2838 for i in range(len(self.res)):
2840 c = self._elt2pkt(elt).canvas_dump(**kargs)
2842 c.text(cbb.left(),cbb.top()+1,r"\font\cmssfont=cmss12\cmssfont{Frame %i/%i}" % (i,l),[pyx.text.size.LARGE])
2845 d.append(pyx.document.page(c, paperformat=pyx.document.paperformat.A4,
2846 margin=1*pyx.unit.t_cm,
2852 def psdump(self, filename = None, **kargs):
2853 """Creates a multipage poscript file with a psdump of every packet
2854 filename: name of the file to write to. If empty, a temporary file is used and
2855 conf.prog.psreader is called"""
2856 d = self._dump_document(**kargs)
2857 if filename is None:
2858 filename = "/tmp/scapy.psd.%i" % os.getpid()
2859 d.writePSfile(filename)
2860 os.system("%s %s.ps &" % (conf.prog.psreader,filename))
2862 d.writePSfile(filename)
2865 def pdfdump(self, filename = None, **kargs):
2866 """Creates a PDF file with a psdump of every packet
2867 filename: name of the file to write to. If empty, a temporary file is used and
2868 conf.prog.pdfreader is called"""
2869 d = self._dump_document(**kargs)
2870 if filename is None:
2871 filename = "/tmp/scapy.psd.%i" % os.getpid()
2872 d.writePDFfile(filename)
2873 os.system("%s %s.pdf &" % (conf.prog.pdfreader,filename))
2875 d.writePDFfile(filename)
2878 def sr(self,multi=0):
2879 """sr([multi=1]) -> (SndRcvList, PacketList)
2880 Matches packets in the list and return ( (matched couples), (unmatched packets) )"""
2881 remain = self.res[:]
2884 while i < len(remain):
2887 while j < len(remain)-1:
2893 remain[i]._answered=1
2894 remain[j]._answered=2
2902 remain = filter(lambda x:not hasattr(x,"_answered"), remain)
2903 return SndRcvList(sr),PacketList(remain)
2910 class Dot11PacketList(PacketList):
2911 def __init__(self, res=None, name="Dot11List", stats=None):
2913 stats = [Dot11WEP, Dot11Beacon, UDP, ICMP, TCP]
2915 PacketList.__init__(self, res, name, stats)
2916 def toEthernet(self):
2917 data = map(lambda x:x.getlayer(Dot11), filter(lambda x : x.haslayer(Dot11) and x.type == 2, self.res))
2922 r2.append(Ether()/q.payload.payload.payload) #Dot11/LLC/SNAP/IP
2923 return PacketList(r2,name="Ether from %s"%self.listname)
2927 class SndRcvList(PacketList):
2928 def __init__(self, res=None, name="Results", stats=None):
2929 PacketList.__init__(self, res, name, stats)
2930 def _elt2pkt(self, elt):
2932 def _elt2sum(self, elt):
2933 return "%s ==> %s" % (elt[0].summary(),elt[1].summary())
2936 class ARPingResult(SndRcvList):
2937 def __init__(self, res=None, name="ARPing", stats=None):
2938 PacketList.__init__(self, res, name, stats)
2941 for s,r in self.res:
2942 print r.sprintf("%Ether.src% %ARP.psrc%")
2948 def __init__(self, server=None, port=43, options=None):
2949 if server is not None:
2950 self.server = server
2952 if options is not None:
2953 self.options = options
2956 self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
2957 self.s.connect((self.server,self.port))
2959 self.s.send(self.options+"\n")
2964 def _parse_whois(self, txt):
2966 for l in txt.splitlines():
2967 if not asn and l.startswith("origin:"):
2969 if l.startswith("descr:"):
2972 desc += l[6:].strip()
2973 if asn is not None and desc:
2975 return asn,desc.strip()
2977 def _resolve_one(self, ip):
2978 self.s.send("%s\n" % ip)
2980 while not ("%" in x or "source" in x):
2981 x += self.s.recv(8192)
2982 asn, desc = self._parse_whois(x)
2984 def resolve(self, *ips):
2988 ip,asn,desc = self._resolve_one(ip)
2990 ret.append((ip,asn,desc))
2994 class AS_resolver_riswhois(AS_resolver):
2995 server = "riswhois.ripe.net"
2996 options = "-k -M -1"
2999 class AS_resolver_radb(AS_resolver):
3000 server = "whois.ra.net"
3004 class AS_resolver_cymru(AS_resolver):
3005 server = "whois.cymru.com"
3007 def resolve(self, *ips):
3009 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
3010 s.connect((self.server,self.port))
3011 s.send("begin\r\n"+"\r\n".join(ips)+"\r\nend\r\n")
3019 for l in r.splitlines()[1:]:
3022 asn,ip,desc = map(str.strip, l.split("|"))
3026 ASNlist.append((ip,asn,desc))
3029 class AS_resolver_multi(AS_resolver):
3030 resolvers_list = ( AS_resolver_cymru(),AS_resolver_riswhois(),AS_resolver_radb() )
3031 def __init__(self, *reslist):
3033 self.resolvers_list = reslist
3034 def resolve(self, *ips):
3037 for ASres in self.resolvers_list:
3038 res = ASres.resolve(*todo)
3039 resolved = [ ip for ip,asn,desc in res ]
3040 todo = [ ip for ip in todo if ip not in resolved ]
3046 class TracerouteResult(SndRcvList):
3047 def __init__(self, res=None, name="Traceroute", stats=None):
3048 PacketList.__init__(self, res, name, stats)
3049 self.graphdef = None
3056 return self.make_table(lambda (s,r): (s.sprintf("%IP.dst%:{TCP:tcp%ir,TCP.dport%}{UDP:udp%ir,UDP.dport%}{ICMP:ICMP}"),
3058 r.sprintf("%-15s,IP.src% {TCP:%TCP.flags%}{ICMP:%ir,ICMP.type%}")))
3061 def get_trace(self):
3063 for s,r in self.res:
3069 trace[d][s[IP].ttl] = r[IP].src, ICMP not in r
3070 for k in trace.values():
3071 m = filter(lambda x:k[x][1], k.keys())
3081 """Give a 3D representation of the traceroute.
3082 right button: rotate the scene
3084 left button: move the scene
3085 left button on a ball: toggle IP displaying
3086 ctrl-left button on a ball: scan ports 21,22,23,25,80 and 443 and display the result"""
3087 trace = self.get_trace()
3090 class IPsphere(visual.sphere):
3091 def __init__(self, ip, **kargs):
3092 visual.sphere.__init__(self, **kargs)
3095 self.setlabel(self.ip)
3096 def setlabel(self, txt,visible=None):
3097 if self.label is not None:
3099 visible = self.label.visible
3100 self.label.visible = 0
3101 elif visible is None:
3103 self.label=visual.label(text=txt, pos=self.pos, space=self.radius, xoffset=10, yoffset=20, visible=visible)
3105 self.label.visible ^= 1
3107 visual.scene = visual.display()
3108 visual.scene.exit_on_close(0)
3109 start = visual.box()
3116 for t in range(1,max(ttl)+1):
3120 if tr[t] not in rings[t]:
3121 rings[t].append(tr[t])
3122 tr3d[i].append(rings[t].index(tr[t]))
3124 rings[t].append(("unk",-1))
3125 tr3d[i].append(len(rings[t])-1)
3131 col = (0.75,0.75,0.75)
3133 col = visual.color.green
3135 col = visual.color.blue
3137 s = IPsphere(pos=((l-1)*visual.cos(2*i*visual.pi/l),(l-1)*visual.sin(2*i*visual.pi/l),2*t),
3140 for trlst in tr3d.values():
3144 forecol = colgen(0.625, 0.4375, 0.25, 0.125)
3145 for trlst in tr3d.values():
3146 col = forecol.next()
3149 visual.cylinder(pos=start,axis=ip.pos-start,color=col,radius=0.2)
3154 if visual.scene.kb.keys:
3155 k = visual.scene.kb.getkey()
3158 if visual.scene.mouse.events:
3159 ev = visual.scene.mouse.getevent()
3160 if ev.press == "left":
3168 a,b=sr(IP(dst=o.ip)/TCP(dport=[21,22,23,25,80,443]),timeout=2)
3171 txt = "%s:\nno results" % o.ip
3173 txt = "%s:\n" % o.ip
3175 txt += r.sprintf("{TCP:%IP.src%:%TCP.sport% %TCP.flags%}{TCPerror:%IPerror.dst%:%TCPerror.dport% %IP.src% %ir,ICMP.type%}\n")
3176 o.setlabel(txt, visible=1)
3178 if hasattr(o, "action"):
3180 elif ev.drag == "left":
3182 elif ev.drop == "left":
3185 visual.scene.center -= visual.scene.mouse.pos-movcenter
3186 movcenter = visual.scene.mouse.pos
3189 def world_trace(self):
3193 for s,r in self.res:
3195 if s.haslayer(TCP) or s.haslayer(UDP):
3196 trace_id = (s.src,s.dst,s.proto,s.dport)
3197 elif s.haslayer(ICMP):
3198 trace_id = (s.src,s.dst,s.proto,s.type)
3200 trace_id = (s.src,s.dst,s.proto,0)
3201 trace = rt.get(trace_id,{})
3202 if not r.haslayer(ICMP) or r.type != 11:
3203 if ports_done.has_key(trace_id):
3205 ports_done[trace_id] = None
3206 trace[s.ttl] = r.src
3207 rt[trace_id] = trace
3211 trace = rt[trace_id]
3213 for i in range(max(trace.keys())):
3214 ip = trace.get(i,None)
3220 # loctrace.append((ip,loc)) # no labels yet
3221 loctrace.append(loc)
3223 trt[trace_id] = loctrace
3225 tr = map(lambda x: Gnuplot.Data(x,with="lines"), trt.values())
3226 g = Gnuplot.Gnuplot()
3227 world = Gnuplot.File(conf.gnuplot_world,with="lines")
3231 def make_graph(self,ASres=None,padding=0):
3233 ASres = conf.AS_resolver
3234 self.graphASres = ASres
3235 self.graphpadding = padding
3240 for s,r in self.res:
3241 r = r[IP] or r[IPv6] or r
3242 s = s[IP] or s[IPv6] or s
3245 trace_id = (s.src,s.dst,6,s.dport)
3247 trace_id = (s.src,s.dst,17,s.dport)
3249 trace_id = (s.src,s.dst,1,s.type)
3251 trace_id = (s.src,s.dst,s.proto,0)
3252 trace = rt.get(trace_id,{})
3253 ttl = IPv6 in s and s.hlim or s.ttl
3254 if not (ICMP in r and r[ICMP].type == 11) and not (IPv6 in r and ICMPv6TimeExceeded in r):
3255 if trace_id in ports_done:
3257 ports_done[trace_id] = None
3258 p = ports.get(r.src,[])
3260 p.append(r.sprintf("<T%ir,TCP.sport%> %TCP.sport% %TCP.flags%"))
3261 trace[ttl] = r.sprintf('"%r,src%":T%ir,TCP.sport%')
3263 p.append(r.sprintf("<U%ir,UDP.sport%> %UDP.sport%"))
3264 trace[ttl] = r.sprintf('"%r,src%":U%ir,UDP.sport%')
3266 p.append(r.sprintf("<I%ir,ICMP.type%> ICMP %ICMP.type%"))
3267 trace[ttl] = r.sprintf('"%r,src%":I%ir,ICMP.type%')
3269 p.append(r.sprintf("{IP:<P%ir,proto%> IP %proto%}{IPv6:<P%ir,nh%> IPv6 %nh%}"))
3270 trace[ttl] = r.sprintf('"%r,src%":{IP:P%ir,proto%}{IPv6:P%ir,nh%}')
3273 trace[ttl] = r.sprintf('"%r,src%"')
3274 rt[trace_id] = trace
3276 # Fill holes with unk%i nodes
3277 unknown_label = incremental_label("unk%i")
3283 for n in range(min(k), max(k)):
3284 if not trace.has_key(n):
3285 trace[n] = unknown_label.next()
3286 if not ports_done.has_key(rtk):
3287 if rtk[2] == 1: #ICMP
3288 bh = "%s %i/icmp" % (rtk[1],rtk[3])
3289 elif rtk[2] == 6: #TCP
3290 bh = "%s %i/tcp" % (rtk[1],rtk[3])
3291 elif rtk[2] == 17: #UDP
3292 bh = '%s %i/udp' % (rtk[1],rtk[3])
3294 bh = '%s %i/proto' % (rtk[1],rtk[2])
3298 trace[max(k)+1] = bh
3299 blackholes.append(bh)
3302 ASN_query_list = dict.fromkeys(map(lambda x:x.rsplit(" ",1)[0],ips)).keys()
3306 ASNlist = ASres.resolve(*ASN_query_list)
3310 for ip,asn,desc, in ASNlist:
3313 iplist = ASNs.get(asn,[])
3317 iplist.append(bhip[ip])
3324 backcolorlist=colgen("60","86","ba","ff")
3325 forecolorlist=colgen("a0","70","40","20")
3327 s = "digraph trace {\n"
3329 s += "\n\tnode [shape=ellipse,color=black,style=solid];\n\n"
3331 s += "\n#ASN clustering\n"
3333 s += '\tsubgraph cluster_%s {\n' % asn
3334 col = backcolorlist.next()
3335 s += '\t\tcolor="#%s%s%s";' % col
3336 s += '\t\tnode [fillcolor="#%s%s%s",style=filled];' % col
3337 s += '\t\tfontsize = 10;'
3338 s += '\t\tlabel = "%s\\n[%s]"\n' % (asn,ASDs[asn])
3339 for ip in ASNs[asn]:
3341 s += '\t\t"%s";\n'%ip
3349 s += '\t"%s" [shape=record,color=black,fillcolor=green,style=filled,label="%s|%s"];\n' % (p,p,"|".join(ports[p]))
3351 s += "\n#Blackholes\n"
3352 for bh in blackholes:
3353 s += '\t%s [shape=octagon,color=black,fillcolor=red,style=filled];\n' % bh
3358 for snd,rcv in self.res:
3359 if rcv.src not in ports and rcv.haslayer(Padding):
3360 p = rcv.getlayer(Padding).load
3361 if p != "\x00"*len(p):
3364 s += '\t"%s" [shape=triangle,color=black,fillcolor=red,style=filled];\n' % rcv
3368 s += "\n\tnode [shape=ellipse,color=black,style=solid];\n\n"
3372 s += "#---[%s\n" % `rtk`
3373 s += '\t\tedge [color="#%s%s%s"];\n' % forecolorlist.next()
3376 for n in range(min(k), max(k)):
3377 s += '\t%s ->\n' % trace[n]
3378 s += '\t%s;\n' % trace[max(k)]
3383 def graph(self, ASres=None, padding=0, **kargs):
3384 """x.graph(ASres=conf.AS_resolver, other args):
3385 ASres=None : no AS resolver => no clustering
3386 ASres=AS_resolver() : default whois AS resolver (riswhois.ripe.net)
3387 ASres=AS_resolver_cymru(): use whois.cymru.com whois database
3388 ASres=AS_resolver(server="whois.ra.net")
3389 type: output type (svg, ps, gif, jpg, etc.), passed to dot's "-T" option
3390 target: filename or redirect. Defaults pipe to Imagemagick's display program
3391 prog: which graphviz program to use"""
3393 ASres = conf.AS_resolver
3394 if (self.graphdef is None or
3395 self.graphASres != ASres or
3396 self.graphpadding != padding):
3397 self.make_graph(ASres,padding)
3399 return do_graph(self.graphdef, **kargs)
3409 """For more informations on how this work, please refer to
3410 http://www.secdev.org/projects/scapy/files/scapydoc.pdf
3411 chapter ``Adding a New Field''"""
3414 def __init__(self, name, default, fmt="H"):
3416 if fmt[0] in "@=<>!":
3420 self.default = self.any2i(None,default)
3421 self.sz = struct.calcsize(self.fmt)
3424 def register_owner(self, cls):
3425 self.owners.append(cls)
3427 def i2len(self, pkt, x):
3428 """Convert internal value to a length usable by a FieldLenField"""
3430 def i2count(self, pkt, x):
3431 """Convert internal value to a number of elements usable by a FieldLenField.
3432 Always 1 except for list fields"""
3434 def h2i(self, pkt, x):
3435 """Convert human value to internal value"""
3437 def i2h(self, pkt, x):
3438 """Convert internal value to human value"""
3440 def m2i(self, pkt, x):
3441 """Convert machine value to internal value"""
3443 def i2m(self, pkt, x):
3444 """Convert internal value to machine value"""
3448 def any2i(self, pkt, x):
3449 """Try to understand the most input values possible and make an internal value from them"""
3450 return self.h2i(pkt, x)
3451 def i2repr(self, pkt, x):
3452 """Convert internal value to a nice representation"""
3455 return repr(self.i2h(pkt,x))
3456 def addfield(self, pkt, s, val):
3457 """Add an internal value to a string"""
3458 return s+struct.pack(self.fmt, self.i2m(pkt,val))
3459 def getfield(self, pkt, s):
3460 """Extract an internal value from a string"""
3461 return s[self.sz:], self.m2i(pkt, struct.unpack(self.fmt, s[:self.sz])[0])
3462 def do_copy(self, x):
3463 if hasattr(x, "copy"):
3467 for i in xrange(len(x)):
3468 if isinstance(x[i], Packet):
3472 return "<Field (%s).%s>" % (",".join(x.__name__ for x in self.owners),self.name)
3474 return copy.deepcopy(self)
3476 """Return a volatile object whose value is both random and suitable for this field"""
3479 return {"B":RandByte,"H":RandShort,"I":RandInt, "Q":RandLong}[fmtt]()
3481 if self.fmt[0] in "0123456789":
3482 l = int(self.fmt[:-1])
3484 l = int(self.fmt[1:-1])
3487 warning("no random class for [%s] (fmt=%s)." % (self.name, self.fmt))
3494 def __init__(self, fld):
3496 def __getattr__(self, attr):
3497 return getattr(self.fld,attr)
3499 return hash(self.fld)
3500 def __eq__(self, other):
3501 return self.fld == other
3506 def __init__(self, fld, action_method, **kargs):
3508 self._action_method = action_method
3509 self._privdata = kargs
3510 def any2i(self, pkt, val):
3511 getattr(pkt, self._action_method)(val, self._fld, **self._privdata)
3512 return getattr(self._fld, "any2i")(pkt, val)
3513 def __getattr__(self, attr):
3514 return getattr(self._fld,attr)
3517 class ConditionalField:
3519 def __init__(self, fld, cond):
3522 def _evalcond(self,pkt):
3523 return self.cond(pkt)
3525 def getfield(self, pkt, s):
3526 if self._evalcond(pkt):
3527 return self.fld.getfield(pkt,s)
3531 def addfield(self, pkt, s, val):
3532 if self._evalcond(pkt):
3533 return self.fld.addfield(pkt,s,val)
3536 def __getattr__(self, attr):
3537 return getattr(self.fld,attr)
3541 """Add bytes after the proxified field so that it ends at the specified
3542 alignment from its begining"""
3544 def __init__(self, fld, align, padwith=None):
3547 self._padwith = padwith or ""
3549 def addfield(self, pkt, s, val):
3550 sval = self._fld.addfield(pkt, "", val)
3551 return s+sval+struct.pack("%is" % (-len(sval)%self._align), self._padwith)
3553 def __getattr__(self, attr):
3554 return getattr(self._fld,attr)
3557 class MACField(Field):
3558 def __init__(self, name, default):
3559 Field.__init__(self, name, default, "6s")
3560 def i2m(self, pkt, x):
3562 return "\0\0\0\0\0\0"
3564 def m2i(self, pkt, x):
3566 def any2i(self, pkt, x):
3567 if type(x) is str and len(x) is 6:
3568 x = self.m2i(pkt, x)
3570 def i2repr(self, pkt, x):
3571 x = self.i2h(pkt, x)
3572 if self in conf.resolve:
3573 x = conf.manufdb._resolve_MAC(x)
3578 class DestMACField(MACField):
3579 def __init__(self, name):
3580 MACField.__init__(self, name, None)
3581 def i2h(self, pkt, x):
3584 if isinstance(pkt.payload, IPv6):
3585 dstip = pkt.payload.dst
3586 elif isinstance(pkt.payload, IP):
3587 dstip = pkt.payload.dst
3588 elif isinstance(pkt.payload, ARP):
3589 dstip = pkt.payload.pdst
3590 if isinstance(dstip, Gen):
3591 dstip = dstip.__iter__().next()
3592 if dstip is not None:
3593 if isinstance(pkt.payload, IPv6):
3594 x = getmacbyip6(dstip, chainCC=1)
3596 x = getmacbyip(dstip, chainCC=1)
3598 x = "ff:ff:ff:ff:ff:ff"
3599 warning("Mac address to reach %s not found\n"%dstip)
3600 return MACField.i2h(self, pkt, x)
3601 def i2m(self, pkt, x):
3602 return MACField.i2m(self, pkt, self.i2h(pkt, x))
3604 class SourceMACField(MACField):
3605 def __init__(self, name):
3606 MACField.__init__(self, name, None)
3607 def i2h(self, pkt, x):
3610 if isinstance(pkt.payload, IPv6):
3611 dstip = pkt.payload.dst
3612 elif isinstance(pkt.payload, IP):
3613 dstip = pkt.payload.dst
3614 elif isinstance(pkt.payload, ARP):
3615 dstip = pkt.payload.pdst
3616 if isinstance(dstip, Gen):
3617 dstip = dstip.__iter__().next()
3618 if dstip is not None:
3619 if isinstance(pkt.payload, IPv6):
3620 iff,a,nh = conf.route6.route(dstip)
3622 iff,a,gw = conf.route.route(dstip)
3624 x = get_if_hwaddr(iff)
3628 x = "00:00:00:00:00:00"
3629 return MACField.i2h(self, pkt, x)
3630 def i2m(self, pkt, x):
3631 return MACField.i2m(self, pkt, self.i2h(pkt, x))
3633 class ARPSourceMACField(MACField):
3634 def __init__(self, name):
3635 MACField.__init__(self, name, None)
3636 def i2h(self, pkt, x):
3639 if isinstance(dstip, Gen):
3640 dstip = dstip.__iter__().next()
3641 if dstip is not None:
3642 iff,a,gw = conf.route.route(dstip)
3644 x = get_if_hwaddr(iff)
3648 x = "00:00:00:00:00:00"
3649 return MACField.i2h(self, pkt, x)
3650 def i2m(self, pkt, x):
3651 return MACField.i2m(self, pkt, self.i2h(pkt, x))
3653 class Dot11AddrMACField(MACField):
3654 def is_applicable(self, pkt):
3656 def addfield(self, pkt, s, val):
3657 if self.is_applicable(pkt):
3658 return MACField.addfield(self, pkt, s, val)
3661 def getfield(self, pkt, s):
3662 if self.is_applicable(pkt):
3663 return MACField.getfield(self, pkt, s)
3667 class Dot11Addr2MACField(Dot11AddrMACField):
3668 def is_applicable(self, pkt):
3670 return pkt.subtype in [ 0xb, 0xa, 0xe, 0xf] # RTS, PS-Poll, CF-End, CF-End+CF-Ack
3673 class Dot11Addr3MACField(Dot11AddrMACField):
3674 def is_applicable(self, pkt):
3675 if pkt.type in [0,2]:
3679 class Dot11Addr4MACField(Dot11AddrMACField):
3680 def is_applicable(self, pkt):
3682 if pkt.FCfield & 0x3 == 0x3: # To-DS and From-DS are set
3686 class IPField(Field):
3687 def __init__(self, name, default):
3688 Field.__init__(self, name, default, "4s")
3689 def h2i(self, pkt, x):
3693 except socket.error:
3695 elif type(x) is list:
3696 x = [self.h2i(pkt, n) for n in x]
3698 def resolve(self, x):
3699 if self in conf.resolve:
3701 ret = socket.gethostbyaddr(x)[0]
3708 def i2m(self, pkt, x):
3710 def m2i(self, pkt, x):
3712 def any2i(self, pkt, x):
3713 return self.h2i(pkt,x)
3714 def i2repr(self, pkt, x):
3715 return self.resolve(self.i2h(pkt, x))
3719 class SourceIPField(IPField):
3720 def __init__(self, name, dstname):
3721 IPField.__init__(self, name, None)
3722 self.dstname = dstname
3723 def i2m(self, pkt, x):
3725 iff,x,gw = conf.route.route(getattr(pkt,self.dstname))
3726 return IPField.i2m(self, pkt, x)
3727 def i2h(self, pkt, x):
3729 dst=getattr(pkt,self.dstname)
3730 if isinstance(dst,Gen):
3731 r = map(conf.route.route, dst)
3736 warning("More than one possible route for %s"%repr(dst))
3739 iff,x,gw = conf.route.route(dst)
3740 return IPField.i2h(self, pkt, x)
3745 class ByteField(Field):
3746 def __init__(self, name, default):
3747 Field.__init__(self, name, default, "B")
3749 class XByteField(ByteField):
3750 def i2repr(self, pkt, x):
3753 return lhex(self.i2h(pkt, x))
3755 class X3BytesField(XByteField):
3756 def __init__(self, name, default):
3757 Field.__init__(self, name, default, "!I")
3758 def addfield(self, pkt, s, val):
3759 return s+struct.pack(self.fmt, self.i2m(pkt,val))[1:4]
3760 def getfield(self, pkt, s):
3761 return s[3:], self.m2i(pkt, struct.unpack(self.fmt, "\x00"+s[:3])[0])
3764 class ShortField(Field):
3765 def __init__(self, name, default):
3766 Field.__init__(self, name, default, "H")
3768 class LEShortField(Field):
3769 def __init__(self, name, default):
3770 Field.__init__(self, name, default, "<H")
3772 class XShortField(ShortField):
3773 def i2repr(self, pkt, x):
3776 return lhex(self.i2h(pkt, x))
3779 class IntField(Field):
3780 def __init__(self, name, default):
3781 Field.__init__(self, name, default, "I")
3783 class SignedIntField(Field):
3784 def __init__(self, name, default):
3785 Field.__init__(self, name, default, "i")
3789 class LEIntField(Field):
3790 def __init__(self, name, default):
3791 Field.__init__(self, name, default, "<I")
3793 class LESignedIntField(Field):
3794 def __init__(self, name, default):
3795 Field.__init__(self, name, default, "<i")
3799 class XIntField(IntField):
3800 def i2repr(self, pkt, x):
3803 return lhex(self.i2h(pkt, x))
3806 class LongField(Field):
3807 def __init__(self, name, default):
3808 Field.__init__(self, name, default, "Q")
3810 class XLongField(LongField):
3811 def i2repr(self, pkt, x):
3814 return lhex(self.i2h(pkt, x))
3816 class IEEEFloatField(Field):
3817 def __init__(self, name, default):
3818 Field.__init__(self, name, default, "f")
3820 class IEEEDoubleField(Field):
3821 def __init__(self, name, default):
3822 Field.__init__(self, name, default, "d")
3825 def FIELD_LENGTH_MANAGEMENT_DEPRECATION(x):
3827 for tb in traceback.extract_stack()+[("??",-1,None,"")]:
3829 if line.startswith("fields_desc"):
3833 log_loading.warning("Deprecated use of %s (%s l. %i). See http://trac.secdev.org/scapy/wiki/LengthFields" % (x,f,l))
3835 class StrField(Field):
3836 def __init__(self, name, default, fmt="H", remain=0, shift=0):
3837 Field.__init__(self,name,default,fmt)
3838 self.remain = remain
3841 FIELD_LENGTH_MANAGEMENT_DEPRECATION(self.__class__.__name__)
3842 def i2len(self, pkt, i):
3843 return len(i)+self.shift
3844 def i2m(self, pkt, x):
3847 elif type(x) is not str:
3850 def addfield(self, pkt, s, val):
3851 return s+self.i2m(pkt, val)
3852 def getfield(self, pkt, s):
3853 if self.remain == 0:
3854 return "",self.m2i(pkt, s)
3856 return s[-self.remain:],self.m2i(pkt, s[:-self.remain])
3858 return RandBin(RandNum(0,1200))
3860 class PacketField(StrField):
3862 def __init__(self, name, default, cls, remain=0, shift=0):
3863 StrField.__init__(self, name, default, remain=remain, shift=shift)
3865 def i2m(self, pkt, i):
3867 def m2i(self, pkt, m):
3869 def getfield(self, pkt, s):
3870 i = self.m2i(pkt, s)
3872 if i.haslayer(Padding):
3873 r = i.getlayer(Padding)
3874 del(r.underlayer.payload)
3878 class PacketLenField(PacketField):
3880 def __init__(self, name, default, cls, fld=None, length_from=None, shift=0):
3881 PacketField.__init__(self, name, default, cls, shift=shift)
3882 self.length_from = length_from
3883 if fld is not None or shift != 0:
3884 FIELD_LENGTH_MANAGEMENT_DEPRECATION(self.__class__.__name__)
3885 self.count_from = lambda pkt,fld=fld,shift=shift: getattr(pkt,fld)-shift
3886 def getfield(self, pkt, s):
3887 l = self.length_from(pkt)
3888 i = self.m2i(pkt, s[:l])
3892 class PacketListField(PacketField):
3895 def __init__(self, name, default, cls, fld=None, count_from=None, length_from=None, shift=0):
3897 default = [] # Create a new list for each instance
3898 PacketField.__init__(self, name, default, cls, shift=shift)
3899 self.count_from = count_from
3900 self.length_from = length_from
3902 if fld is not None or shift != 0:
3903 FIELD_LENGTH_MANAGEMENT_DEPRECATION(self.__class__.__name__)
3905 self.count_from = lambda pkt,fld=fld,shift=shift: getattr(pkt,fld)-shift
3907 def any2i(self, pkt, x):
3908 if type(x) is not list:
3912 def i2count(self, pkt, val):
3913 if type(val) is list:
3916 def i2len(self, pkt, val):
3917 return sum( len(p) for p in val )
3918 def do_copy(self, x):
3919 return map(lambda p:p.copy(), x)
3920 def getfield(self, pkt, s):
3922 if self.length_from is not None:
3923 l = self.length_from(pkt)
3924 elif self.count_from is not None:
3925 c = self.count_from(pkt)
3931 remain,ret = s[:l],s[l:]
3937 p = self.m2i(pkt,remain)
3941 del(pad.underlayer.payload)
3945 return remain+ret,lst
3946 def addfield(self, pkt, s, val):
3947 return s+"".join(map(str, val))
3950 class StrFixedLenField(StrField):
3951 def __init__(self, name, default, length=None, length_from=None, shift=0):
3952 StrField.__init__(self, name, default, shift=shift)
3953 self.length_from = length_from
3954 if length is not None:
3955 self.length_from = lambda pkt,length=length: length
3956 def getfield(self, pkt, s):
3957 l = self.length_from(pkt)
3958 return s[l:], self.m2i(pkt,s[:l])
3959 def addfield(self, pkt, s, val):
3960 l = self.length_from(pkt)
3961 return s+struct.pack("%is"%l,self.i2m(pkt, val))
3964 l = self.length_from(None)
3969 class NetBIOSNameField(StrFixedLenField):
3970 def __init__(self, name, default, length=31, shift=0):
3971 StrFixedLenField.__init__(self, name, default, length, shift=shift)
3972 def i2m(self, pkt, x):
3973 l = self.length_from(pkt)/2
3978 x = "".join(map(lambda x: chr(0x41+(ord(x)>>4))+chr(0x41+(ord(x)&0xf)), x))
3981 def m2i(self, pkt, x):
3982 x = x.strip("\x00").strip(" ")
3983 return "".join(map(lambda x,y: chr((((ord(x)-1)&0xf)<<4)+((ord(y)-1)&0xf)), x[::2],x[1::2]))
3985 class StrLenField(StrField):
3986 def __init__(self, name, default, fld=None, length_from=None, shift=0):
3987 StrField.__init__(self, name, default, shift=shift)
3988 self.length_from = length_from
3989 if fld is not None or shift != 0:
3990 FIELD_LENGTH_MANAGEMENT_DEPRECATION(self.__class__.__name__)
3991 self.length_from = lambda pkt,fld=fld,shift=shift: getattr(pkt,fld)-shift
3992 def getfield(self, pkt, s):
3993 l = self.length_from(pkt)
3994 return s[l:], self.m2i(pkt,s[:l])
3996 class FieldListField(Field):
3998 def __init__(self, name, default, field, fld=None, shift=0, length_from=None, count_from=None):
4000 default = [] # Create a new list for each instance
4001 Field.__init__(self, name, default)
4002 self.count_from = count_from
4003 self.length_from = length_from
4005 if fld is not None or shift != 0:
4006 FIELD_LENGTH_MANAGEMENT_DEPRECATION(self.__class__.__name__)
4007 self.count_from = lambda pkt,fld=fld,shift=shift: getattr(pkt,fld)-shift
4010 def i2count(self, pkt, val):
4011 if type(val) is list:
4014 def i2len(self, pkt, val):
4015 return sum( self.field.i2len(pkt,v) for v in val )
4017 def i2m(self, pkt, val):
4021 def any2i(self, pkt, x):
4022 if type(x) is not list:
4026 def addfield(self, pkt, s, val):
4027 val = self.i2m(pkt, val)
4029 s = self.field.addfield(pkt, s, v)
4031 def getfield(self, pkt, s):
4033 if self.length_from is not None:
4034 l = self.length_from(pkt)
4035 elif self.count_from is not None:
4036 c = self.count_from(pkt)
4048 s,v = self.field.getfield(pkt, s)
4052 class FieldLenField(Field):
4053 def __init__(self, name, default, length_of=None, fmt = "H", count_of=None, adjust=lambda pkt,x:x, fld=None):
4054 Field.__init__(self, name, default, fmt)
4055 self.length_of=length_of
4056 self.count_of=count_of
4059 FIELD_LENGTH_MANAGEMENT_DEPRECATION(self.__class__.__name__)
4060 self.length_of = fld
4061 def i2m(self, pkt, x):
4063 if self.length_of is not None:
4064 fld,fval = pkt.getfield_and_val(self.length_of)
4065 f = fld.i2len(pkt, fval)
4067 fld,fval = pkt.getfield_and_val(self.count_of)
4068 f = fld.i2count(pkt, fval)
4069 x = self.adjust(pkt,f)
4072 # see http://www.iana.org/assignments/ipsec-registry for details
4073 ISAKMPAttributeTypes= { "Encryption": (1, { "DES-CBC" : 1,
4076 "RC5-R16-B64-CBC" : 4,
4080 "CAMELLIA-CBC" : 8, }, 0),
4081 "Hash": (2, { "MD5": 1,
4086 "SHA2-512": 6,}, 0),
4087 "Authentication":(3, { "PSK": 1,
4090 "RSA Encryption": 4,
4091 "RSA Encryption Revised": 5,
4092 "ElGamal Encryption": 6,
4093 "ElGamal Encryption Revised": 7,
4095 "HybridInitRSA": 64221,
4096 "HybridRespRSA": 64222,
4097 "HybridInitDSS": 64223,
4098 "HybridRespDSS": 64224,
4099 "XAUTHInitPreShared": 65001,
4100 "XAUTHRespPreShared": 65002,
4101 "XAUTHInitDSS": 65003,
4102 "XAUTHRespDSS": 65004,
4103 "XAUTHInitRSA": 65005,
4104 "XAUTHRespRSA": 65006,
4105 "XAUTHInitRSAEncryption": 65007,
4106 "XAUTHRespRSAEncryption": 65008,
4107 "XAUTHInitRSARevisedEncryption": 65009,
4108 "XAUTHRespRSARevisedEncryptio": 65010, }, 0),
4109 "GroupDesc": (4, { "768MODPgr" : 1,
4118 "8192MODPgr" : 18, }, 0),
4119 "GroupType": (5, {"MODP": 1,
4122 "GroupPrime": (6, {}, 1),
4123 "GroupGenerator1":(7, {}, 1),
4124 "GroupGenerator2":(8, {}, 1),
4125 "GroupCurveA": (9, {}, 1),
4126 "GroupCurveB": (10, {}, 1),
4127 "LifeType": (11, {"Seconds": 1,
4128 "Kilobytes": 2, }, 0),
4129 "LifeDuration": (12, {}, 1),
4131 "KeyLength": (14, {}, 0),
4132 "FieldSize": (15, {}, 0),
4133 "GroupOrder": (16, {}, 1),
4136 # the name 'ISAKMPTransformTypes' is actually a misnomer (since the table
4137 # holds info for all ISAKMP Attribute types, not just transforms, but we'll
4138 # keep it for backwards compatibility... for now at least
4139 ISAKMPTransformTypes = ISAKMPAttributeTypes
4141 ISAKMPTransformNum = {}
4142 for n in ISAKMPTransformTypes:
4143 val = ISAKMPTransformTypes[n]
4147 ISAKMPTransformNum[val[0]] = (n,tmp, val[2])
4154 class ISAKMPTransformSetField(StrLenField):
4156 def type2num(self, (typ,val)):
4157 type_val,enc_dict,tlv = ISAKMPTransformTypes.get(typ, (typ,{},0))
4158 val = enc_dict.get(val, val)
4162 warning("%r should not be TLV but is too big => using TLV encoding" % typ)
4171 return struct.pack("!HH",type_val, val)+s
4172 def num2type(self, typ, enc):
4173 val = ISAKMPTransformNum.get(typ,(typ,{}))
4174 enc = val[1].get(enc,enc)
4176 def i2m(self, pkt, i):
4179 i = map(self.type2num, i)
4181 def m2i(self, pkt, m):
4182 # I try to ensure that we don't read off the end of our packet based
4183 # on bad length fields we're provided in the packet. There are still
4184 # conditions where struct.unpack() may not get enough packet data, but
4185 # worst case that should result in broken attributes (which would
4186 # be expected). (wam)
4189 trans_type, = struct.unpack("!H", m[:2])
4190 is_tlv = not (trans_type & 0x8000)
4192 # We should probably check to make sure the attribute type we
4193 # are looking at is allowed to have a TLV format and issue a
4194 # warning if we're given an TLV on a basic attribute.
4195 value_len, = struct.unpack("!H", m[2:4])
4196 if value_len+4 > len(m):
4197 warning("Bad length for ISAKMP tranform type=%#6x" % trans_type)
4198 value = m[4:4+value_len]
4199 value = reduce(lambda x,y: (x<<8L)|y, struct.unpack("!%s" % ("B"*len(value),), value),0)
4201 trans_type &= 0x7fff
4203 value, = struct.unpack("!H", m[2:4])
4205 lst.append(self.num2type(trans_type, value))
4207 warning("Extra bytes after ISAKMP transform dissection [%r]" % m)
4210 class StrNullField(StrField):
4211 def addfield(self, pkt, s, val):
4212 return s+self.i2m(pkt, val)+"\x00"
4213 def getfield(self, pkt, s):
4218 return s[l+1:],self.m2i(pkt, s[:l])
4220 return RandTermString(RandNum(0,1200),"\x00")
4222 class StrStopField(StrField):
4223 def __init__(self, name, default, stop, additionnal=0):
4224 Field.__init__(self, name, default)
4226 self.additionnal=additionnal
4227 def getfield(self, pkt, s):
4228 l = s.find(self.stop)
4231 # raise Scapy_Exception,"StrStopField: stop value [%s] not found" %stop
4232 l += len(self.stop)+self.additionnal
4235 return RandTermString(RandNum(0,1200),self.stop)
4237 class LenField(Field):
4238 def i2m(self, pkt, x):
4240 x = len(pkt.payload)
4243 class BCDFloatField(Field):
4244 def i2m(self, pkt, x):
4246 def m2i(self, pkt, x):
4249 class BitField(Field):
4250 def __init__(self, name, default, size):
4251 Field.__init__(self, name, default)
4253 self.size = abs(size)
4254 def reverse(self, val):
4256 val = socket.ntohs(val)
4257 elif self.size == 32:
4258 val = socket.ntohl(val)
4261 def addfield(self, pkt, s, val):
4262 val = self.i2m(pkt, val)
4263 if type(s) is tuple:
4269 val = self.reverse(val)
4271 v |= val & ((1L<<self.size) - 1)
4272 bitsdone += self.size
4273 while bitsdone >= 8:
4275 s = s+struct.pack("!B", v >> bitsdone)
4276 v &= (1L<<bitsdone)-1
4281 def getfield(self, pkt, s):
4282 if type(s) is tuple:
4286 # we don't want to process all the string
4287 nb_bytes = (self.size+bn-1)/8 + 1
4290 # split the substring byte by byte
4291 bytes = struct.unpack('!%dB' % nb_bytes , w)
4294 for c in range(nb_bytes):
4295 b |= long(bytes[c]) << (nb_bytes-c-1)*8
4297 # get rid of high order bits
4298 b &= (1L << (nb_bytes*8-bn)) - 1
4300 # remove low order bits
4301 b = b >> (nb_bytes*8 - self.size - bn)
4309 b = self.m2i(pkt, b)
4315 return RandNum(0,2**self.size-1)
4318 class BitFieldLenField(BitField):
4319 def __init__(self, name, default, size, length_of=None, count_of=None, adjust=lambda pkt,x:x):
4320 BitField.__init__(self, name, default, size)
4321 self.length_of=length_of
4322 self.count_of=count_of
4324 def i2m(self, pkt, x):
4325 return FieldLenField.i2m.im_func(self, pkt, x)
4328 class XBitField(BitField):
4329 def i2repr(self, pkt, x):
4330 return lhex(self.i2h(pkt,x))
4333 class EnumField(Field):
4334 def __init__(self, name, default, enum, fmt = "H"):
4337 if type(enum) is list:
4338 keys = xrange(len(enum))
4341 if filter(lambda x: type(x) is str, keys):
4346 Field.__init__(self, name, default, fmt)
4347 def any2i_one(self, pkt, x):
4351 def i2repr_one(self, pkt, x):
4352 if self not in conf.noenum and not isinstance(x,VolatileValue) and x in self.i2s:
4356 def any2i(self, pkt, x):
4358 return map(lambda z,pkt=pkt:self.any2i_one(pkt,z), x)
4360 return self.any2i_one(pkt,x)
4361 def i2repr(self, pkt, x):
4363 return map(lambda z,pkt=pkt:self.i2repr_one(pkt,z), x)
4365 return self.i2repr_one(pkt,x)
4367 class CharEnumField(EnumField):
4368 def __init__(self, name, default, enum, fmt = "1s"):
4369 EnumField.__init__(self, name, default, enum, fmt)
4371 if k and len(k[0]) != 1:
4372 self.i2s,self.s2i = self.s2i,self.i2s
4373 def any2i_one(self, pkt, x):
4378 class BitEnumField(BitField,EnumField):
4379 def __init__(self, name, default, size, enum):
4380 EnumField.__init__(self, name, default, enum)
4382 self.size = abs(size)
4383 def any2i(self, pkt, x):
4384 return EnumField.any2i(self, pkt, x)
4385 def i2repr(self, pkt, x):
4386 return EnumField.i2repr(self, pkt, x)
4388 class ShortEnumField(EnumField):
4389 def __init__(self, name, default, enum):
4390 EnumField.__init__(self, name, default, enum, "H")
4392 class LEShortEnumField(EnumField):
4393 def __init__(self, name, default, enum):
4394 EnumField.__init__(self, name, default, enum, "<H")
4396 class ByteEnumField(EnumField):
4397 def __init__(self, name, default, enum):
4398 EnumField.__init__(self, name, default, enum, "B")
4400 class IntEnumField(EnumField):
4401 def __init__(self, name, default, enum):
4402 EnumField.__init__(self, name, default, enum, "I")
4404 class SignedIntEnumField(EnumField):
4405 def __init__(self, name, default, enum):
4406 EnumField.__init__(self, name, default, enum, "i")
4410 class LEIntEnumField(EnumField):
4411 def __init__(self, name, default, enum):
4412 EnumField.__init__(self, name, default, enum, "<I")
4414 class XShortEnumField(ShortEnumField):
4415 def i2repr_one(self, pkt, x):
4416 if self not in conf.noenum and not isinstance(x,VolatileValue) and x in self.i2s:
4420 # Little endian long field
4421 class LELongField(Field):
4422 def __init__(self, name, default):
4423 Field.__init__(self, name, default, "<Q")
4425 # Little endian fixed length field
4426 class LEFieldLenField(FieldLenField):
4427 def __init__(self, name, default, length_of=None, fmt = "<H", count_of=None, adjust=lambda pkt,x:x, fld=None):
4428 FieldLenField.__init__(self, name, default, length_of=length_of, fmt=fmt, fld=fld, adjust=adjust)
4431 class FlagsField(BitField):
4432 def __init__(self, name, default, size, names):
4433 BitField.__init__(self, name, default, size)
4434 self.multi = type(names) is list
4436 self.names = map(lambda x:[x], names)
4439 def any2i(self, pkt, x):
4442 x = map(lambda y:[y], x.split("+"))
4445 y |= 1 << self.names.index(i)
4448 def i2repr(self, pkt, x):
4449 if type(x) is list or type(x) is tuple:
4469 class IPoptionsField(StrField):
4470 def i2m(self, pkt, x):
4471 return x+"\x00"*(3-((len(x)+3)%4))
4472 def getfield(self, pkt, s):
4473 opsz = (pkt.ihl-5)*4
4475 warning("bad ihl (%i). Assuming ihl=5"%pkt.ihl)
4477 return s[opsz:],s[:opsz]
4479 return RandBin(RandNum(0,39))
4486 3 : ("WScale","!B"),
4487 4 : ("SAckOK",None),
4489 8 : ("Timestamp","!II"),
4490 14 : ("AltChkSum","!BH"),
4491 15 : ("AltChkSumOpt",None)
4504 class TCPOptionsField(StrField):
4506 def getfield(self, pkt, s):
4507 opsz = (pkt.dataofs-5)*4
4509 warning("bad dataofs (%i). Assuming dataofs=5"%pkt.dataofs)
4511 return s[opsz:],self.m2i(pkt,s[:opsz])
4512 def m2i(self, pkt, x):
4517 opt.append(("EOL",None))
4521 opt.append(("NOP",None))
4526 warning("Malformed TCP option (announced length is %i)" % olen)
4529 if TCPOptions[0].has_key(onum):
4530 oname, ofmt = TCPOptions[0][onum]
4532 ofmt += "%iI" % (len(oval)/4)
4533 if ofmt and struct.calcsize(ofmt) == len(oval):
4534 oval = struct.unpack(ofmt, oval)
4537 opt.append((oname, oval))
4539 opt.append((onum, oval))
4543 def i2m(self, pkt, x):
4545 for oname,oval in x:
4546 if type(oname) is str:
4550 elif oname == "EOL":
4553 elif TCPOptions[1].has_key(oname):
4554 onum = TCPOptions[1][oname]
4555 ofmt = TCPOptions[0][onum][1]
4557 ofmt += "%iI" % len(oval)
4558 if ofmt is not None and (type(oval) is not str or "s" in ofmt):
4559 if type(oval) is not tuple:
4561 oval = struct.pack(ofmt, *oval)
4563 warning("option [%s] unknown. Skipped."%oname)
4567 if type(oval) is not str:
4568 warning("option [%i] is not string."%onum)
4570 opt += chr(onum)+chr(2+len(oval))+oval
4571 return opt+"\x00"*(3-((len(opt)+3)%4))
4576 class DNSStrField(StrField):
4577 def i2m(self, pkt, x):
4578 x = [k[:63] for k in x.split(".")] # Truncate chunks that cannont be encoded (more than 63 bytes..)
4579 x = map(lambda y: chr(len(y))+y, x)
4584 def getfield(self, pkt, s):
4592 raise Scapy_Exception("DNS message can't be compressed at this point!")
4599 class DNSRRCountField(ShortField):
4601 def __init__(self, name, default, rr):
4602 ShortField.__init__(self, name, default)
4604 def _countRR(self, pkt):
4605 x = getattr(pkt,self.rr)
4607 while isinstance(x, DNSRR) or isinstance(x, DNSQR):
4612 def i2m(self, pkt, x):
4614 x = self._countRR(pkt)
4616 def i2h(self, pkt, x):
4618 x = self._countRR(pkt)
4628 warning("DNS RR prematured end (ofs=%i, len=%i)"%(p,len(s)))
4636 warning("DNS incomplete jump token at (ofs=%i)" % p)
4638 p = ((l & 0x3f) << 8) + ord(s[p]) - 12
4640 warning("DNS decompression loop detected")
4645 name += s[p:p+l]+"."
4654 class DNSRRField(StrField):
4656 def __init__(self, name, countfld, passon=1):
4657 StrField.__init__(self, name, None)
4658 self.countfld = countfld
4659 self.passon = passon
4660 def i2m(self, pkt, x):
4664 def decodeRR(self, name, s, p):
4666 type,cls,ttl,rdlen = struct.unpack("!HHIH", ret)
4668 rr = DNSRR("\x00"+ret+s[p:p+rdlen])
4669 if rr.type in [2, 3, 4, 5]:
4670 rr.rdata = DNSgetstr(s,p)[0]
4677 def getfield(self, pkt, s):
4678 if type(s) is tuple :
4683 c = getattr(pkt, self.countfld)
4685 warning("wrong value: DNS.%s=%i" % (self.countfld,c))
4689 name,p = DNSgetstr(s,p)
4690 rr,p = self.decodeRR(name, s, p)
4701 class DNSQRField(DNSRRField):
4703 def decodeRR(self, name, s, p):
4706 rr = DNSQR("\x00"+ret)
4712 class RDataField(StrLenField):
4713 def m2i(self, pkt, s):
4716 family = socket.AF_INET
4717 elif pkt.type == 28:
4718 family = socket.AF_INET6
4719 elif pkt.type == 12:
4720 s = DNSgetstr(s, 0)[0]
4721 if family is not None:
4722 s = inet_ntop(family, s)
4724 def i2m(self, pkt, s):
4728 elif pkt.type == 28:
4730 s = inet_pton(socket.AF_INET6, s)
4731 elif pkt.type in [2,3,4,5]:
4732 s = "".join(map(lambda x: chr(len(x))+x, s.split(".")))
4737 class RDLenField(Field):
4738 def __init__(self, name):
4739 Field.__init__(self, name, None, "H")
4740 def i2m(self, pkt, x):
4742 rdataf = pkt.get_field("rdata")
4743 x = len(rdataf.i2m(pkt, pkt.rdata))
4745 def i2h(self, pkt, x):
4747 rdataf = pkt.get_field("rdata")
4748 x = len(rdataf.i2m(pkt, pkt.rdata))
4751 # seconds between 01-01-1900 and 01-01-1970
4752 ntp_basetime = 2208988800
4754 class TimeStampField(BitField):
4755 def __init__(self, name, default, size):
4756 BitField.__init__(self, name, default, size)
4758 def getfield(self, pkt, s):
4759 s,timestamp = BitField.getfield(self, pkt, s)
4762 # timestamp is a 64 bits field :
4763 # + first 32 bits : number of seconds since 1900
4764 # + last 32 bits : fraction part
4766 timestamp -= ntp_basetime
4768 from time import gmtime, strftime
4769 b = strftime("%a, %d %b %Y %H:%M:%S +0000", gmtime(timestamp))
4774 def addfield(self, pkt, s, val):
4776 if type(val) is str:
4777 from time import strptime, mktime
4778 t = int(mktime(strptime(val))) + ntp_basetime + 3600
4781 from time import time
4782 t = int(time()) + ntp_basetime
4786 return BitField.addfield(self,pkt,s, t)
4788 class ICMPTimeStampField(IntField):
4789 re_hmsm = re.compile("([0-2]?[0-9])[Hh:](([0-5]?[0-9])([Mm:]([0-5]?[0-9])([sS:.]([0-9]{0,3}))?)?)?$")
4790 def i2repr(self, pkt, val):
4794 sec, milli = divmod(val, 1000)
4795 min, sec = divmod(sec, 60)
4796 hour, min = divmod(min, 60)
4797 return "%d:%d:%d.%d" %(hour, min, sec, int(milli))
4798 def any2i(self, pkt, val):
4799 if type(val) is str:
4800 hmsms = self.re_hmsm.match(val)
4802 h,_,m,_,s,_,ms = hmsms = hmsms.groups()
4803 ms = int(((ms or "")+"000")[:3])
4804 val = ((int(h)*60+int(m or 0))*60+int(s or 0))*1000+ms
4808 val = int((time.time()%(24*60*60))*1000)
4811 class FloatField(BitField):
4812 def getfield(self, pkt, s):
4813 s,b = BitField.getfield(self, pkt, s)
4815 # fraction point between bits 15 and 16.
4817 frac = b & (1L << (32+1)) - 1
4822 class Dot11SCField(LEShortField):
4823 def is_applicable(self, pkt):
4824 return pkt.type != 1 # control frame
4825 def addfield(self, pkt, s, val):
4826 if self.is_applicable(pkt):
4827 return LEShortField.addfield(self, pkt, s, val)
4830 def getfield(self, pkt, s):
4831 if self.is_applicable(pkt):
4832 return LEShortField.getfield(self, pkt, s)
4836 #####################
4837 #### ASN1 Fields ####
4838 #####################
4840 class ASN1F_badsequence(Exception):
4843 class ASN1F_element:
4846 class ASN1F_optionnal(ASN1F_element):
4847 def __init__(self, field):
4849 def __getattr__(self, attr):
4850 return getattr(self._field,attr)
4851 def dissect(self,pkt,s):
4853 return self._field.dissect(pkt,s)
4854 except ASN1F_badsequence:
4855 self._field.set_val(pkt,None)
4857 except BER_Decoding_Error:
4858 self._field.set_val(pkt,None)
4860 def build(self, pkt):
4861 if self._field.is_empty(pkt):
4863 return self._field.build(pkt)
4865 class ASN1F_field(ASN1F_element):
4869 ASN1_tag = ASN1_Class_UNIVERSAL.ANY
4870 context=ASN1_Class_UNIVERSAL
4872 def __init__(self, name, default, context=None):
4873 if context is not None:
4874 self.context = context
4876 self.default = default
4878 def i2repr(self, pkt, x):
4882 def i2h(self, pkt, x):
4884 def any2i(self, pkt, x):
4886 def m2i(self, pkt, x):
4887 return self.ASN1_tag.get_codec(pkt.ASN1_codec).safedec(x, context=self.context)
4888 def i2m(self, pkt, x):
4891 if isinstance(x, ASN1_Object):
4892 if ( self.ASN1_tag == ASN1_Class_UNIVERSAL.ANY
4893 or x.tag == ASN1_Class_UNIVERSAL.RAW
4894 or x.tag == ASN1_Class_UNIVERSAL.ERROR
4895 or self.ASN1_tag == x.tag ):
4896 return x.enc(pkt.ASN1_codec)
4898 raise ASN1_Error("Encoding Error: got %r instead of an %r for field [%s]" % (x, self.ASN1_tag, self.name))
4899 return self.ASN1_tag.get_codec(pkt.ASN1_codec).enc(x)
4901 def do_copy(self, x):
4902 if hasattr(x, "copy"):
4906 for i in xrange(len(x)):
4907 if isinstance(x[i], Packet):
4911 def build(self, pkt):
4912 return self.i2m(pkt, getattr(pkt, self.name))
4914 def set_val(self, pkt, val):
4915 setattr(pkt, self.name, val)
4916 def is_empty(self, pkt):
4917 return getattr(pkt,self.name) is None
4919 def dissect(self, pkt, s):
4920 v,s = self.m2i(pkt, s)
4921 self.set_val(pkt, v)
4924 def get_fields_list(self):
4928 return hash(self.name)
4931 def __eq__(self, other):
4932 return self.name == other
4939 class ASN1F_INTEGER(ASN1F_field):
4940 ASN1_tag= ASN1_Class_UNIVERSAL.INTEGER
4942 return RandNum(-2**64, 2**64-1)
4944 class ASN1F_NULL(ASN1F_INTEGER):
4945 ASN1_tag= ASN1_Class_UNIVERSAL.NULL
4947 class ASN1F_enum_INTEGER(ASN1F_INTEGER):
4948 def __init__(self, name, default, enum):
4949 ASN1F_INTEGER.__init__(self, name, default)
4952 if type(enum) is list:
4953 keys = xrange(len(enum))
4956 if filter(lambda x: type(x) is str, keys):
4961 def any2i_one(self, pkt, x):
4965 def i2repr_one(self, pkt, x):
4966 return self.i2s.get(x, repr(x))
4968 def any2i(self, pkt, x):
4970 return map(lambda z,pkt=pkt:self.any2i_one(pkt,z), x)
4972 return self.any2i_one(pkt,x)
4973 def i2repr(self, pkt, x):
4975 return map(lambda z,pkt=pkt:self.i2repr_one(pkt,z), x)
4977 return self.i2repr_one(pkt,x)
4979 class ASN1F_STRING(ASN1F_field):
4980 ASN1_tag = ASN1_Class_UNIVERSAL.STRING
4982 return RandString(RandNum(0, 1000))
4984 class ASN1F_PRINTABLE_STRING(ASN1F_STRING):
4985 ASN1_tag = ASN1_Class_UNIVERSAL.PRINTABLE_STRING
4987 class ASN1F_BIT_STRING(ASN1F_STRING):
4988 ASN1_tag = ASN1_Class_UNIVERSAL.BIT_STRING
4990 class ASN1F_UTC_TIME(ASN1F_STRING):
4991 ASN1_tag = ASN1_Class_UNIVERSAL.UTC_TIME
4993 class ASN1F_OID(ASN1F_field):
4994 ASN1_tag = ASN1_Class_UNIVERSAL.OID
4998 class ASN1F_SEQUENCE(ASN1F_field):
4999 ASN1_tag = ASN1_Class_UNIVERSAL.SEQUENCE
5000 def __init__(self, *seq, **kargs):
5001 if "ASN1_tag" in kargs:
5002 self.ASN1_tag = kargs["ASN1_tag"]
5005 return "<%s%r>" % (self.__class__.__name__,self.seq,)
5006 def set_val(self, pkt, val):
5009 def is_empty(self, pkt):
5011 if not f.is_empty(pkt):
5014 def get_fields_list(self):
5015 return reduce(lambda x,y: x+y.get_fields_list(), self.seq, [])
5016 def build(self, pkt):
5017 s = reduce(lambda x,y: x+y.build(pkt), self.seq, "")
5018 return self.i2m(pkt, s)
5019 def dissect(self, pkt, s):
5020 codec = self.ASN1_tag.get_codec(pkt.ASN1_codec)
5022 i,s,remain = codec.check_type_check_len(s)
5023 for obj in self.seq:
5024 s = obj.dissect(pkt,s)
5026 warning("Too many bytes to decode sequence: [%r]" % s) # XXX not reversible!
5028 except ASN1_Error,e:
5029 raise ASN1F_badsequence(e)
5031 class ASN1F_SET(ASN1F_SEQUENCE):
5032 ASN1_tag = ASN1_Class_UNIVERSAL.SET
5034 class ASN1F_SEQUENCE_OF(ASN1F_SEQUENCE):
5037 def __init__(self, name, default, asn1pkt, ASN1_tag=0x30):
5038 self.asn1pkt = asn1pkt
5039 self.tag = chr(ASN1_tag)
5041 self.default = default
5042 def i2repr(self, pkt, i):
5046 def get_fields_list(self):
5048 def set_val(self, pkt, val):
5049 ASN1F_field.set_val(self, pkt, val)
5050 def is_empty(self, pkt):
5051 return ASN1F_field.is_empty(self, pkt)
5052 def build(self, pkt):
5053 val = getattr(pkt, self.name)
5054 if isinstance(val, ASN1_Object) and val.tag == ASN1_Class_UNIVERSAL.RAW:
5059 s = "".join(map(str, val ))
5060 return self.i2m(pkt, s)
5061 def set_val(self, pkt, val):
5062 ASN1F_field.set_val(self, pkt, val)
5063 def dissect(self, pkt, s):
5064 codec = self.ASN1_tag.get_codec(pkt.ASN1_codec)
5065 i,s1,remain = codec.check_type_check_len(s)
5069 p = self.asn1pkt(s1)
5070 except ASN1F_badsequence,e:
5076 del(p[Raw].underlayer.payload)
5079 self.set_val(pkt, lst)
5082 return fuzz(self.asn1pkt())
5084 return "<%s %s>" % (self.__class__.__name__,self.name)
5086 class ASN1F_PACKET(ASN1F_field):
5088 def __init__(self, name, default, cls):
5089 ASN1_field.__init__(self, name, default)
5091 def i2m(self, pkt, x):
5095 def extract_packet(self, cls, x):
5098 except ASN1F_badsequence:
5102 if cpad is not None:
5104 del(cpad.underlayer.payload)
5106 def m2i(self, pkt, x):
5107 return self.extract_packet(self.cls, x)
5110 class ASN1F_CHOICE(ASN1F_PACKET):
5111 ASN1_tag = ASN1_Class_UNIVERSAL.NONE
5112 def __init__(self, name, default, *args):
5116 self.choice[p.ASN1_root.ASN1_tag] = p
5117 # self.context=context
5118 self.default=default
5119 def m2i(self, pkt, x):
5122 raise ASN1_Error("ASN1F_CHOICE: got empty string")
5123 if ord(x[0]) not in self.choice:
5124 return Raw(x),"" # XXX return RawASN1 packet ? Raise error
5125 raise ASN1_Error("Decoding Error: choice [%i] not found in %r" % (ord(x[0]), self.choice.keys()))
5127 z = ASN1F_PACKET.extract_packet(self, self.choice[ord(x[0])], x)
5130 return RandChoice(*map(lambda x:fuzz(x()), self.choice.values()))
5134 ###########################
5135 ## Packet abstract class ##
5136 ###########################
5138 class Packet_metaclass(type):
5139 def __new__(cls, name, bases, dct):
5140 newcls = super(Packet_metaclass, cls).__new__(cls, name, bases, dct)
5141 for f in newcls.fields_desc:
5142 f.register_owner(newcls)
5144 def __getattr__(self, attr):
5145 for k in self.fields_desc:
5148 raise AttributeError(attr)
5150 class NewDefaultValues(Packet_metaclass):
5151 """NewDefaultValues metaclass. Example usage:
5152 class MyPacket(Packet):
5153 fields_desc = [ StrField("my_field", "my default value"), ]
5155 class MyPacket_variant(MyPacket):
5156 __metaclass__ = NewDefaultValues
5157 my_field = "my new default value"
5159 def __new__(cls, name, bases, dct):
5162 if hasattr(b,"fields_desc"):
5163 fields = b.fields_desc
5166 raise Scapy_Exception("No fields_desc in superclasses")
5172 f.default = dct[f.name]
5174 new_fields.append(f)
5175 dct["fields_desc"] = new_fields
5176 return super(NewDefaultValues, cls).__new__(cls, name, bases, dct)
5179 __metaclass__ = Packet_metaclass
5185 overload_fields = {}
5195 def from_hexcap(cls):
5196 return cls(import_hexcap())
5199 def upper_bonds(self):
5200 for fval,upper in self.payload_guess:
5201 print "%-20s %s" % (upper.__name__, ", ".join("%-12s" % ("%s=%r"%i) for i in fval.iteritems()))
5204 def lower_bonds(self):
5205 for lower,fval in self.overload_fields.iteritems():
5206 print "%-20s %s" % (lower.__name__, ", ".join("%-12s" % ("%s=%r"%i) for i in fval.iteritems()))
5208 def __init__(self, _pkt="", post_transform=None, _internal=0, _underlayer=None, **fields):
5209 self.time = time.time()
5211 if self.name is None:
5212 self.name = self.__class__.__name__
5213 self.aliastypes = [ self.__class__ ] + self.aliastypes
5214 self.default_fields = {}
5215 self.overloaded_fields = {}
5218 self.packetfields=[]
5219 self.__dict__["payload"] = NoPayload()
5221 self.underlayer = _underlayer
5222 self.initialized = 1
5226 self.dissection_done(self)
5227 for f in fields.keys():
5228 self.fields[f] = self.get_field(f).any2i(self,fields[f])
5229 if type(post_transform) is list:
5230 self.post_transforms = post_transform
5231 elif post_transform is None:
5232 self.post_transforms = []
5234 self.post_transforms = [post_transform]
5236 def init_fields(self):
5237 self.do_init_fields(self.fields_desc)
5239 def do_init_fields(self, flist):
5241 self.default_fields[f.name] = f.default
5242 self.fieldtype[f.name] = f
5244 self.packetfields.append(f)
5246 def dissection_done(self,pkt):
5247 """DEV: will be called after a dissection is completed"""
5248 self.post_dissection(pkt)
5249 self.payload.dissection_done(pkt)
5251 def post_dissection(self, pkt):
5252 """DEV: is called after the dissection of the whole packet"""
5255 def get_field(self, fld):
5256 """DEV: returns the field instance from the name of the field"""
5257 return self.fieldtype[fld]
5259 def add_payload(self, payload):
5262 elif not isinstance(self.payload, NoPayload):
5263 self.payload.add_payload(payload)
5265 if isinstance(payload, Packet):
5266 self.__dict__["payload"] = payload
5267 payload.add_underlayer(self)
5268 for t in self.aliastypes:
5269 if payload.overload_fields.has_key(t):
5270 self.overloaded_fields = payload.overload_fields[t]
5272 elif type(payload) is str:
5273 self.__dict__["payload"] = Raw(load=payload)
5275 raise TypeError("payload must be either 'Packet' or 'str', not [%s]" % repr(payload))
5276 def remove_payload(self):
5277 self.payload.remove_underlayer(self)
5278 self.__dict__["payload"] = NoPayload()
5279 self.overloaded_fields = {}
5280 def add_underlayer(self, underlayer):
5281 self.underlayer = underlayer
5282 def remove_underlayer(self,other):
5283 self.underlayer = None
5285 """Returns a deep copy of the instance."""
5286 clone = self.__class__()
5287 clone.fields = self.fields.copy()
5288 for k in clone.fields:
5289 clone.fields[k]=self.get_field(k).do_copy(clone.fields[k])
5290 clone.default_fields = self.default_fields.copy()
5291 clone.overloaded_fields = self.overloaded_fields.copy()
5292 clone.overload_fields = self.overload_fields.copy()
5293 clone.underlayer=self.underlayer
5294 clone.explicit=self.explicit
5295 clone.post_transforms=self.post_transforms[:]
5296 clone.__dict__["payload"] = self.payload.copy()
5297 clone.payload.add_underlayer(clone)
5300 def getfieldval(self, attr):
5301 if attr in self.fields:
5302 return self.fields[attr]
5303 if attr in self.overloaded_fields:
5304 return self.overloaded_fields[attr]
5305 if attr in self.default_fields:
5306 return self.default_fields[attr]
5307 return self.payload.getfieldval(attr)
5309 def getfield_and_val(self, attr):
5310 if attr in self.fields:
5311 return self.get_field(attr),self.fields[attr]
5312 if attr in self.overloaded_fields:
5313 return self.get_field(attr),self.overloaded_fields[attr]
5314 if attr in self.default_fields:
5315 return self.get_field(attr),self.default_fields[attr]
5316 return self.payload.getfield_and_val(attr)
5318 def __getattr__(self, attr):
5319 if self.initialized:
5320 fld,v = self.getfield_and_val(attr)
5322 return fld.i2h(self, v)
5324 raise AttributeError(attr)
5326 def setfieldval(self, attr, val):
5327 if self.default_fields.has_key(attr):
5328 fld = self.get_field(attr)
5330 any2i = lambda x,y: y
5333 self.fields[attr] = any2i(self, val)
5335 elif attr == "payload":
5336 self.remove_payload()
5337 self.add_payload(val)
5339 self.payload.setfieldval(attr,val)
5341 def __setattr__(self, attr, val):
5342 if self.initialized:
5344 self.setfieldval(attr,val)
5345 except AttributeError:
5349 self.__dict__[attr] = val
5351 def delfieldval(self, attr):
5352 if self.fields.has_key(attr):
5353 del(self.fields[attr])
5354 self.explicit=0 # in case a default value must be explicited
5355 elif self.default_fields.has_key(attr):
5357 elif attr == "payload":
5358 self.remove_payload()
5360 self.payload.delfieldval(attr)
5362 def __delattr__(self, attr):
5363 if self.initialized:
5365 self.delfieldval(attr)
5366 except AttributeError:
5370 if self.__dict__.has_key(attr):
5371 del(self.__dict__[attr])
5373 raise AttributeError(attr)
5377 ct = conf.color_theme
5378 for f in self.fields_desc:
5379 if isinstance(f, ConditionalField) and not f._evalcond(self):
5381 if f.name in self.fields:
5382 val = f.i2repr(self, self.fields[f.name])
5383 elif f.name in self.overloaded_fields:
5384 val = f.i2repr(self, self.overloaded_fields[f.name])
5387 if isinstance(f, Emph):
5388 ncol = ct.emph_field_name
5389 vcol = ct.emph_field_value
5391 ncol = ct.field_name
5392 vcol = ct.field_value
5395 s += " %s%s%s" % (ncol(f.name),
5398 return "%s%s %s %s%s%s"% (ct.punct("<"),
5399 ct.layer_name(self.__class__.__name__),
5406 def __div__(self, other):
5407 if isinstance(other, Packet):
5408 cloneA = self.copy()
5409 cloneB = other.copy()
5410 cloneA.add_payload(cloneB)
5412 elif type(other) is str:
5413 return self/Raw(load=other)
5415 return other.__rdiv__(self)
5416 def __rdiv__(self, other):
5417 if type(other) is str:
5418 return Raw(load=other)/self
5421 def __mul__(self, other):
5422 if type(other) is int:
5426 def __rmul__(self,other):
5427 return self.__mul__(other)
5429 def __nonzero__(self):
5432 return len(self.__str__())
5435 for f in self.fields_desc:
5436 p = f.addfield(self, p, self.getfieldval(f.name))
5439 def post_build(self, pkt, pay):
5440 """DEV: called right after the current layer is build."""
5443 def build_payload(self):
5444 return self.payload.build(internal=1)
5446 def build(self,internal=0):
5447 if not self.explicit:
5448 self = self.__iter__().next()
5449 pkt = self.do_build()
5450 for t in self.post_transforms:
5452 pay = self.build_payload()
5454 p = self.post_build(pkt,pay)
5456 log_runtime.error("API changed! post_build() now takes 2 arguments. Compatibility is only assured for a short transition time")
5457 p = self.post_build(pkt+pay)
5459 pad = self.payload.getlayer(Padding)
5462 p = self.build_done(p)
5465 def build_done(self, p):
5466 return self.payload.build_done(p)
5468 def do_build_ps(self):
5472 for f in self.fields_desc:
5473 p = f.addfield(self, p, self.getfieldval(f.name) )
5479 pl.append( (f, f.i2repr(self,self.getfieldval(f.name)), r) )
5481 pkt,lst = self.payload.build_ps(internal=1)
5483 lst.append( (self, pl) )
5487 def build_ps(self,internal=0):
5488 p,lst = self.do_build_ps()
5491 # while pkt.haslayer(Padding):
5492 # pkt = pkt.getlayer(Padding)
5493 # lst.append( (pkt, [ ("loakjkjd", pkt.load, pkt.load) ] ) )
5499 def psdump(self, filename=None, **kargs):
5500 """psdump(filename=None, layer_shift=0, rebuild=1)
5501 Creates an EPS file describing a packet. If filename is not provided a temporary file is created and gs is called."""
5502 canvas = self.canvas_dump(**kargs)
5503 if filename is None:
5504 fname = "/tmp/scapy.%i"%os.getpid()
5505 canvas.writeEPSfile(fname)
5506 os.system("%s '%s.eps' &" % (conf.prog.psreader,fname))
5508 canvas.writeEPSfile(filename)
5510 def pdfdump(self, filename=None, **kargs):
5511 """pdfdump(filename=None, layer_shift=0, rebuild=1)
5512 Creates a PDF file describing a packet. If filename is not provided a temporary file is created and xpdf is called."""
5513 canvas = self.canvas_dump(**kargs)
5514 if filename is None:
5515 fname = "/tmp/scapy.%i"%os.getpid()
5516 canvas.writePDFfile(fname)
5517 os.system("%s '%s.pdf' &" % (conf.prog.pdfreader,fname))
5519 canvas.writePDFfile(filename)
5522 def canvas_dump(self, layer_shift=0, rebuild=1):
5523 canvas = pyx.canvas.canvas()
5525 p,t = self.__class__(str(self)).build_ps()
5527 p,t = self.build_ps()
5542 backcolor=colgen(0.6, 0.8, 1.0, trans=pyx.color.rgb)
5543 forecolor=colgen(0.2, 0.5, 0.8, trans=pyx.color.rgb)
5544 # backcolor=makecol(0.376, 0.729, 0.525, 1.0)
5550 s.append("%02x" % ord(c))
5554 def make_dump_txt(x,y,txt):
5555 return pyx.text.text(XDSTART+x*XMUL, (YDUMP-y)*YMUL, r"\tt{%s}"%hexstr(txt), [pyx.text.size.Large])
5558 return pyx.box.rect(o.left(), o.bottom(), o.width(), o.height(), relcenter=(0.5,0.5))
5560 def make_frame(lst):
5563 b.enlarge(pyx.unit.u_pt)
5567 fb.enlarge(pyx.unit.u_pt)
5569 lb.enlarge(pyx.unit.u_pt)
5570 if len(lst) == 2 and fb.left() > lb.right():
5571 return pyx.path.path(pyx.path.moveto(fb.right(), fb.top()),
5572 pyx.path.lineto(fb.left(), fb.top()),
5573 pyx.path.lineto(fb.left(), fb.bottom()),
5574 pyx.path.lineto(fb.right(), fb.bottom()),
5575 pyx.path.moveto(lb.left(), lb.top()),
5576 pyx.path.lineto(lb.right(), lb.top()),
5577 pyx.path.lineto(lb.right(), lb.bottom()),
5578 pyx.path.lineto(lb.left(), lb.bottom()))
5583 gb.enlarge(pyx.unit.u_pt)
5585 if kb != gb and kb != lb:
5586 kb.enlarge(pyx.unit.u_pt)
5587 return pyx.path.path(pyx.path.moveto(fb.left(), fb.top()),
5588 pyx.path.lineto(fb.right(), fb.top()),
5589 pyx.path.lineto(fb.right(), kb.bottom()),
5590 pyx.path.lineto(lb.right(), kb.bottom()),
5591 pyx.path.lineto(lb.right(), lb.bottom()),
5592 pyx.path.lineto(lb.left(), lb.bottom()),
5593 pyx.path.lineto(lb.left(), gb.top()),
5594 pyx.path.lineto(fb.left(), gb.top()),
5595 pyx.path.closepath(),)
5598 def make_dump(s, shift=0, y=0, col=None, bkcol=None, larg=16):
5599 c = pyx.canvas.canvas()
5602 dmp,s = s[:larg-shift],s[larg-shift:]
5603 txt = make_dump_txt(shift, y, dmp)
5610 col = pyx.color.rgb.red
5612 col = pyx.color.rgb.white
5613 c.stroke(make_frame(tlist),[col,pyx.deco.filled([bkcol]),pyx.style.linewidth.Thick])
5616 return c, tlist[-1].bbox(), shift, y
5619 last_shift,last_y=0,0.0
5621 bkcol = backcolor.next()
5622 proto,fields = t.pop()
5624 pt = pyx.text.text(XSTART, (YTXT-y)*YMUL, r"\font\cmssfont=cmss10\cmssfont{%s}" % proto.name, [ pyx.text.size.Large])
5627 ptbb.enlarge(pyx.unit.u_pt*2)
5628 canvas.stroke(ptbb.path(),[pyx.color.rgb.black, pyx.deco.filled([bkcol])])
5630 for fname, fval, fdump in fields:
5631 col = forecolor.next()
5632 ft = pyx.text.text(XSTART, (YTXT-y)*YMUL, r"\font\cmssfont=cmss10\cmssfont{%s}" % tex_escape(fname.name))
5633 if fval is not None:
5635 fval = fval[:18]+"[...]"
5638 vt = pyx.text.text(XSTART+3, (YTXT-y)*YMUL, r"\font\cmssfont=cmss10\cmssfont{%s}" % tex_escape(fval))
5641 dt,target,last_shift,last_y = make_dump(fdump, last_shift, last_y, col, bkcol)
5646 bxvt = make_box(vtb)
5647 bxdt = make_box(dtb)
5648 dtb.enlarge(pyx.unit.u_pt)
5651 cnx = pyx.connector.curve(bxvt,bxdt,absangle1=0, absangle2=-90)
5653 cnx = pyx.connector.curve(bxvt,bxdt,absangle1=0, absangle2=90)
5657 canvas.stroke(cnx,[pyx.style.linewidth.thin,pyx.deco.earrow.small,col])
5663 last_y += layer_shift
5669 def extract_padding(self, s):
5670 """DEV: to be overloaded to extract current layer's padding. Return a couple of strings (actual layer, padding)"""
5673 def post_dissect(self, s):
5674 """DEV: is called right after the current layer has been dissected"""
5677 def pre_dissect(self, s):
5678 """DEV: is called right before the current layer is dissected"""
5681 def do_dissect(self, s):
5682 flist = self.fields_desc[:]
5686 s,fval = f.getfield(self, s)
5687 self.fields[f.name] = fval
5691 def do_dissect_payload(self, s):
5693 cls = self.guess_payload_class(s)
5695 p = cls(s, _internal=1, _underlayer=self)
5696 except KeyboardInterrupt:
5699 if conf.debug_dissector:
5700 if isinstance(cls,type) and issubclass(cls,Packet):
5701 log_runtime.error("%s dissector failed" % cls.name)
5703 log_runtime.error("%s.guess_payload_class() returned [%s]" % (self.__class__.__name__,repr(cls)))
5706 p = Raw(s, _internal=1, _underlayer=self)
5709 def dissect(self, s):
5710 s = self.pre_dissect(s)
5712 s = self.do_dissect(s)
5714 s = self.post_dissect(s)
5716 payl,pad = self.extract_padding(s)
5717 self.do_dissect_payload(payl)
5718 if pad and conf.padding:
5719 self.add_payload(Padding(pad))
5722 def guess_payload_class(self, payload):
5723 """DEV: Guesses the next payload class from layer bonds. Can be overloaded to use a different mechanism."""
5724 for t in self.aliastypes:
5725 for fval, cls in t.payload_guess:
5727 for k in fval.keys():
5728 if not hasattr(self, k) or fval[k] != self.getfieldval(k):
5733 return self.default_payload_class(payload)
5735 def default_payload_class(self, payload):
5736 """DEV: Returns the default payload class if nothing has been found by the guess_payload_class() method."""
5739 def hide_defaults(self):
5740 """Removes fields' values that are the same as default values."""
5741 for k in self.fields.keys():
5742 if self.default_fields.has_key(k):
5743 if self.default_fields[k] == self.fields[k]:
5745 self.payload.hide_defaults()
5747 def clone_with(self, payload=None, **kargs):
5748 pkt = self.__class__()
5751 pkt.time = self.time
5752 pkt.underlayer = self.underlayer
5753 pkt.overload_fields = self.overload_fields.copy()
5754 pkt.post_transforms = self.post_transforms
5755 if payload is not None:
5756 pkt.add_payload(payload)
5761 def loop(todo, done, self=self):
5763 eltname = todo.pop()
5764 elt = self.getfieldval(eltname)
5765 if not isinstance(elt, Gen):
5766 if self.get_field(eltname).islist:
5772 for x in loop(todo[:], done):
5775 if isinstance(self.payload,NoPayload):
5778 payloads = self.payload
5779 for payl in payloads:
5782 if isinstance(done2[k], VolatileValue):
5783 done2[k] = done2[k]._fix()
5784 pkt = self.clone_with(payload=payl, **done2)
5791 todo = [ k for (k,v) in itertools.chain(self.default_fields.iteritems(),
5792 self.overloaded_fields.iteritems())
5793 if isinstance(v, VolatileValue) ] + self.fields.keys()
5795 return loop(todo, done)
5797 def __gt__(self, other):
5798 """True if other is an answer from self (self ==> other)."""
5799 if isinstance(other, Packet):
5801 elif type(other) is str:
5804 raise TypeError((self, other))
5805 def __lt__(self, other):
5806 """True if self is an answer from other (other ==> self)."""
5807 if isinstance(other, Packet):
5808 return self.answers(other)
5809 elif type(other) is str:
5812 raise TypeError((self, other))
5814 def __eq__(self, other):
5815 if not isinstance(other, self.__class__):
5817 for f in self.fields_desc:
5818 if f not in other.fields_desc:
5820 if self.getfieldval(f.name) != other.getfieldval(f.name):
5822 return self.payload == other.payload
5824 def __ne__(self, other):
5825 return not self.__eq__(other)
5828 """DEV: returns a string that has the same value for a request and its answer."""
5829 return self.payload.hashret()
5830 def answers(self, other):
5831 """DEV: true if self is an answer from other"""
5832 if other.__class__ == self.__class__:
5833 return self.payload.answers(other.payload)
5836 def haslayer(self, cls):
5837 """true if self has a layer that is an instance of cls. Superseded by "cls in self" syntax."""
5838 if self.__class__ == cls or self.__class__.__name__ == cls:
5840 for f in self.packetfields:
5841 fvalue_gen = self.getfieldval(f.name)
5842 if fvalue_gen is None:
5845 fvalue_gen = SetGen(fvalue_gen,_iterpacket=0)
5846 for fvalue in fvalue_gen:
5847 if isinstance(fvalue, Packet):
5848 ret = fvalue.haslayer(cls)
5851 return self.payload.haslayer(cls)
5852 def getlayer(self, cls, nb=1, _track=None):
5853 """Return the nb^th layer that is an instance of cls."""
5854 if type(cls) is str and "." in cls:
5855 ccls,fld = cls.split(".",1)
5858 if self.__class__ == cls or self.__class__.name == ccls:
5863 return self.getfieldval(fld)
5866 for f in self.packetfields:
5867 fvalue_gen = self.getfieldval(f.name)
5868 if fvalue_gen is None:
5871 fvalue_gen = SetGen(fvalue_gen,_iterpacket=0)
5872 for fvalue in fvalue_gen:
5873 if isinstance(fvalue, Packet):
5875 ret = fvalue.getlayer(cls, nb, _track=track)
5879 return self.payload.getlayer(cls,nb,_track=_track)
5881 def __getitem__(self, cls):
5882 if type(cls) is slice:
5884 ret = self.getlayer(cls.start, cls.stop)
5886 ret = self.getlayer(cls.start)
5887 if ret is None and cls.step is not None:
5891 return self.getlayer(cls)
5893 def __contains__(self, cls):
5894 """"cls in self" returns true if self has a layer which is an instance of cls."""
5895 return self.haslayer(cls)
5899 def display(self,*args,**kargs): # Deprecated. Use show()
5900 """Deprecated. Use show() method."""
5901 self.show(*args,**kargs)
5902 def show(self, indent=3, lvl="", label_lvl=""):
5903 """Prints a hierarchical view of the packet. "indent" gives the size of indentation for each layer."""
5904 ct = conf.color_theme
5905 print "%s%s %s %s" % (label_lvl,
5907 ct.layer_name(self.name),
5909 for f in self.fields_desc:
5910 if isinstance(f, ConditionalField) and not f._evalcond(self):
5912 if isinstance(f, Emph):
5913 ncol = ct.emph_field_name
5914 vcol = ct.emph_field_value
5916 ncol = ct.field_name
5917 vcol = ct.field_value
5918 fvalue = self.getfieldval(f.name)
5919 if isinstance(fvalue, Packet) or (f.islist and f.holds_packets and type(fvalue) is list):
5920 print "%s \\%-10s\\" % (label_lvl+lvl, ncol(f.name))
5921 fvalue_gen = SetGen(fvalue,_iterpacket=0)
5922 for fvalue in fvalue_gen:
5923 fvalue.show(indent=indent, label_lvl=label_lvl+lvl+" |")
5925 print "%s %-10s%s %s" % (label_lvl+lvl,
5928 vcol(f.i2repr(self,fvalue)))
5929 self.payload.show(indent=indent, lvl=lvl+(" "*indent*self.show_indent), label_lvl=label_lvl)
5931 """Prints a hierarchical view of an assembled version of the packet, so that automatic fields are calculated (checksums, etc.)"""
5932 self.__class__(str(self)).show()
5934 def sprintf(self, fmt, relax=1):
5935 """sprintf(format, [relax=1]) -> str
5936 where format is a string that can include directives. A directive begins and
5937 ends by % and has the following format %[fmt[r],][cls[:nb].]field%.
5939 fmt is a classic printf directive, "r" can be appended for raw substitution
5940 (ex: IP.flags=0x18 instead of SA), nb is the number of the layer we want
5941 (ex: for IP/IP packets, IP:2.src is the src of the upper IP layer).
5942 Special case : "%.time%" is the creation time.
5943 Ex : p.sprintf("%.time% %-15s,IP.src% -> %-15s,IP.dst% %IP.chksum% "
5944 "%03xr,IP.proto% %r,TCP.flags%")
5946 Moreover, the format string can include conditionnal statements. A conditionnal
5947 statement looks like : {layer:string} where layer is a layer name, and string
5948 is the string to insert in place of the condition if it is true, i.e. if layer
5949 is present. If layer is preceded by a "!", the result si inverted. Conditions
5950 can be imbricated. A valid statement can be :
5951 p.sprintf("This is a{TCP: TCP}{UDP: UDP}{ICMP:n ICMP} packet")
5952 p.sprintf("{IP:%IP.dst% {ICMP:%ICMP.type%}{TCP:%TCP.dport%}}")
5954 A side effect is that, to obtain "{" and "}" characters, you must use
5958 escape = { "%": "%",
5963 # Evaluate conditions
5966 j = fmt[i+1:].index("}")
5967 cond = fmt[i+1:i+j+1]
5970 raise Scapy_Exception("Bad condition in format string: [%s] (read sprintf doc!)"%cond)
5971 cond,format = cond[:k],cond[k+1:]
5976 if self.haslayer(cond):
5980 fmt = fmt[:i]+format+fmt[i+j+2:]
5982 # Evaluate directives
5988 if fmt and fmt[0] in escape:
5995 fclsfld = sfclsfld.split(",")
5996 if len(fclsfld) == 1:
5999 elif len(fclsfld) == 2:
6002 raise Scapy_Exception
6004 cls,fld = clsfld.split(".")
6006 cls = self.__class__.__name__
6010 cls,num = cls.split(":")
6014 raise Scapy_Exception("Bad format string [%%%s%s]" % (fmt[:25], fmt[25:] and "..."))
6017 val = time.strftime("%H:%M:%S.%%06i", time.localtime(self.time)) % int((self.time-int(self.time))*1000000)
6018 elif cls == self.__class__.__name__ and hasattr(self, fld):
6020 val = self.payload.sprintf("%%%s,%s:%s.%s%%" % (f,cls,num-1,fld), relax)
6022 elif f[-1] == "r": # Raw field value
6023 val = getattr(self,fld)
6028 val = getattr(self,fld)
6029 if fld in self.fieldtype:
6030 val = self.fieldtype[fld].i2repr(self,val)
6032 val = self.payload.sprintf("%%%s%%" % sfclsfld, relax)
6039 def mysummary(self):
6040 """DEV: can be overloaded to return a string that summarizes the layer.
6041 Only one mysummary() is used in a whole packet summary: the one of the upper layer,
6042 except if a mysummary() also returns (as a couple) a list of layers whose
6043 mysummary() must be called if they are present."""
6046 def summary(self, intern=0):
6047 """Prints a one line summary of a packet."""
6048 found,s,needed = self.payload.summary(intern=1)
6052 if not found or self.__class__ in needed:
6053 ret = self.mysummary()
6054 if type(ret) is tuple:
6060 ret = self.__class__.__name__
6061 ret = "%s%s" % (ret,s)
6063 return found,ret,needed
6067 def lastlayer(self,layer=None):
6068 """Returns the uppest layer of the packet"""
6069 return self.payload.lastlayer(self)
6071 def decode_payload_as(self,cls):
6072 """Reassembles the payload and decode it using another packet class"""
6073 s = str(self.payload)
6074 self.payload = cls(s)
6077 """Not ready yet. Should give the necessary C code that interfaces with libnet to recreate the packet"""
6078 print "libnet_build_%s(" % self.__class__.name.lower()
6079 det = self.__class__(str(self))
6080 for f in self.fields_desc:
6081 val = det.getfieldval(f.name)
6084 elif type(val) is int:
6087 val = '"%s"' % str(val)
6088 print "\t%s, \t\t/* %s */" % (val,f.name)
6091 """Returns a string representing the command you have to type to obtain the same packet"""
6093 for fn,fv in self.fields.items():
6094 fld = self.get_field(fn)
6095 if isinstance(fv, Packet):
6097 elif fld.islist and fld.holds_packets and type(fv) is list:
6098 fv = "[%s]" % ",".join( map(Packet.command, fv))
6101 f.append("%s=%s" % (fn, fv))
6102 c = "%s(%s)" % (self.__class__.__name__, ", ".join(f))
6103 pc = self.payload.command()
6109 class ASN1_Packet(Packet):
6112 def init_fields(self):
6113 flist = self.ASN1_root.get_fields_list()
6114 self.do_init_fields(flist)
6115 self.fields_desc = flist
6117 return self.ASN1_root.build(self)
6118 def do_dissect(self, x):
6119 return self.ASN1_root.dissect(self, x)
6122 class NoPayload(Packet,object):
6123 def __new__(cls, *args, **kargs):
6124 singl = cls.__dict__.get("__singl__")
6126 cls.__singl__ = singl = object.__new__(cls)
6127 Packet.__init__(singl, *args, **kargs)
6129 def __init__(self, *args, **kargs):
6131 def dissection_done(self,pkt):
6133 def add_payload(self, payload):
6134 raise Scapy_Exception("Can't add payload to NoPayload instance")
6135 def remove_payload(self):
6137 def add_underlayer(self,underlayer):
6139 def remove_underlayer(self,other):
6147 def __nonzero__(self):
6149 def build(self, internal=0):
6151 def build_done(self, p):
6153 def build_ps(self, internal=0):
6155 def getfieldval(self, attr):
6156 raise AttributeError(attr)
6157 def getfield_and_val(self, attr):
6158 raise AttributeError(attr)
6159 def setfieldval(self, attr, val):
6160 raise AttributeError(attr)
6161 def delfieldval(self, attr):
6162 raise AttributeError(attr)
6163 def __getattr__(self, attr):
6164 if attr in self.__dict__:
6165 return self.__dict__[attr]
6166 elif attr in self.__class__.__dict__:
6167 return self.__class__.__dict__[attr]
6169 raise AttributeError, attr
6170 def hide_defaults(self):
6174 def __eq__(self, other):
6175 if isinstance(other, NoPayload):
6180 def answers(self, other):
6181 return isinstance(other, NoPayload) or isinstance(other, Padding)
6182 def haslayer(self, cls):
6184 def getlayer(self, cls, nb=1, _track=None):
6185 if _track is not None:
6188 def show(self, indent=3, lvl="", label_lvl=""):
6190 def sprintf(self, fmt, relax):
6194 raise Scapy_Exception("Format not found [%s]"%fmt)
6195 def summary(self, intern=0):
6197 def lastlayer(self,layer):
6203 ####################
6204 ## packet classes ##
6205 ####################
6210 fields_desc = [ StrField("load", "") ]
6211 def answers(self, other):
6215 # l = min(len(s), len(t))
6216 # return s[:l] == t[:l]
6220 def build(self, internal=0):
6224 return Raw.build(self)
6226 class Ether(Packet):
6228 fields_desc = [ DestMACField("dst"),
6229 SourceMACField("src"),
6230 XShortEnumField("type", 0x0000, ETHER_TYPES) ]
6232 return struct.pack("H",self.type)+self.payload.hashret()
6233 def answers(self, other):
6234 if isinstance(other,Ether):
6235 if self.type == other.type:
6236 return self.payload.answers(other.payload)
6238 def mysummary(self):
6239 return self.sprintf("%src% > %dst% (%type%)")
6241 class PPPoE(Packet):
6242 name = "PPP over Ethernet"
6243 fields_desc = [ BitField("version", 1, 4),
6244 BitField("type", 1, 4),
6245 ByteEnumField("code", 0, {0:"Session"}),
6246 XShortField("sessionid", 0x0),
6247 ShortField("len", None) ]
6249 def post_build(self, p, pay):
6251 if self.len is None:
6253 p = p[:4]+struct.pack("!H", l)+p[6:]
6256 class PPPoED(PPPoE):
6257 name = "PPP over Ethernet Discovery"
6258 fields_desc = [ BitField("version", 1, 4),
6259 BitField("type", 1, 4),
6260 ByteEnumField("code", 0x09, {0x09:"PADI",0x07:"PADO",0x19:"PADR",0x65:"PADS",0xa7:"PADT"}),
6261 XShortField("sessionid", 0x0),
6262 ShortField("len", None) ]
6266 fields_desc = [ MACField("dst", ETHER_BROADCAST),
6267 MACField("src", ETHER_ANY),
6268 LenField("len", None, "H") ]
6269 def extract_padding(self,s):
6272 def answers(self, other):
6273 if isinstance(other,Dot3):
6274 return self.payload.answers(other.payload)
6276 def mysummary(self):
6277 return "802.3 %s > %s" % (self.src, self.dst)
6282 fields_desc = [ XByteField("dsap", 0x00),
6283 XByteField("ssap", 0x00),
6284 ByteField("ctrl", 0) ]
6287 class CookedLinux(Packet):
6288 name = "cooked linux"
6289 fields_desc = [ ShortEnumField("pkttype",0, {0: "unicast",
6290 4:"sent-by-us"}), #XXX incomplete
6291 XShortField("lladdrtype",512),
6292 ShortField("lladdrlen",0),
6293 StrFixedLenField("src","",8),
6294 XShortEnumField("proto",0x800,ETHER_TYPES) ]
6300 fields_desc = [ X3BytesField("OUI",0x000000),
6301 XShortEnumField("code", 0x000, ETHER_TYPES) ]
6304 class Dot1Q(Packet):
6306 aliastypes = [ Ether ]
6307 fields_desc = [ BitField("prio", 0, 3),
6308 BitField("id", 0, 1),
6309 BitField("vlan", 1, 12),
6310 XShortEnumField("type", 0x0000, ETHER_TYPES) ]
6311 def answers(self, other):
6312 if isinstance(other,Dot1Q):
6313 if ( (self.type == other.type) and
6314 (self.vlan == other.vlan) ):
6315 return self.payload.answers(other.payload)
6317 return self.payload.answers(other)
6319 def default_payload_class(self, pay):
6320 if self.type <= 1500:
6323 def extract_padding(self,s):
6324 if self.type <= 1500:
6325 return s[:self.type],s[self.type:]
6327 def mysummary(self):
6328 if isinstance(self.underlayer, Ether):
6329 return self.underlayer.sprintf("802.1q %Ether.src% > %Ether.dst% (%Dot1Q.type%) vlan %Dot1Q.vlan%")
6331 return self.sprintf("802.1q (%Dot1Q.type%) vlan %Dot1Q.vlan%")
6336 class RadioTap(Packet):
6337 name = "RadioTap dummy"
6338 fields_desc = [ ByteField('version', 0),
6339 ByteField('pad', 0),
6340 FieldLenField('len', None, 'notdecoded', '@H', adjust=lambda pkt,x:x+8),
6341 FlagsField('present', None, -32, ['TSFT','Flags','Rate','Channel','FHSS','dBm_AntSignal',
6342 'dBm_AntNoise','Lock_Quality','TX_Attenuation','dB_TX_Attenuation',
6343 'dBm_TX_Power', 'Antenna', 'dB_AntSignal', 'dB_AntNoise',
6344 'b14', 'b15','b16','b17','b18','b19','b20','b21','b22','b23',
6345 'b24','b25','b26','b27','b28','b29','b30','Ext']),
6346 StrLenField('notdecoded', "", length_from= lambda pkt:pkt.len-8) ]
6349 name = "Spanning Tree Protocol"
6350 fields_desc = [ ShortField("proto", 0),
6351 ByteField("version", 0),
6352 ByteField("bpdutype", 0),
6353 ByteField("bpduflags", 0),
6354 ShortField("rootid", 0),
6355 MACField("rootmac", ETHER_ANY),
6356 IntField("pathcost", 0),
6357 ShortField("bridgeid", 0),
6358 MACField("bridgemac", ETHER_ANY),
6359 ShortField("portid", 0),
6360 BCDFloatField("age", 1),
6361 BCDFloatField("maxage", 20),
6362 BCDFloatField("hellotime", 2),
6363 BCDFloatField("fwddelay", 15) ]
6366 class EAPOL(Packet):
6368 fields_desc = [ ByteField("version", 1),
6369 ByteEnumField("type", 0, ["EAP_PACKET", "START", "LOGOFF", "KEY", "ASF"]),
6370 LenField("len", None, "H") ]
6377 def extract_padding(self, s):
6381 return chr(self.type)+self.payload.hashret()
6382 def answers(self, other):
6383 if isinstance(other,EAPOL):
6384 if ( (self.type == self.EAP_PACKET) and
6385 (other.type == self.EAP_PACKET) ):
6386 return self.payload.answers(other.payload)
6388 def mysummary(self):
6389 return self.sprintf("EAPOL %EAPOL.type%")
6394 fields_desc = [ ByteEnumField("code", 4, {1:"REQUEST",2:"RESPONSE",3:"SUCCESS",4:"FAILURE"}),
6396 ShortField("len",None),
6397 ConditionalField(ByteEnumField("type",0, {1:"ID",4:"MD5"}), lambda pkt:pkt.code not in [EAP.SUCCESS, EAP.FAILURE])
6407 def answers(self, other):
6408 if isinstance(other,EAP):
6409 if self.code == self.REQUEST:
6411 elif self.code == self.RESPONSE:
6412 if ( (other.code == self.REQUEST) and
6413 (other.type == self.type) ):
6415 elif other.code == self.RESPONSE:
6419 def post_build(self, p, pay):
6420 if self.len is None:
6422 p = p[:2]+chr((l>>8)&0xff)+chr(l&0xff)+p[4:]
6428 fields_desc = [ XShortField("hwtype", 0x0001),
6429 XShortEnumField("ptype", 0x0800, ETHER_TYPES),
6430 ByteField("hwlen", 6),
6431 ByteField("plen", 4),
6432 ShortEnumField("op", 1, {"who-has":1, "is-at":2, "RARP-req":3, "RARP-rep":4, "Dyn-RARP-req":5, "Dyn-RAR-rep":6, "Dyn-RARP-err":7, "InARP-req":8, "InARP-rep":9}),
6433 ARPSourceMACField("hwsrc"),
6434 SourceIPField("psrc","pdst"),
6435 MACField("hwdst", ETHER_ANY),
6436 IPField("pdst", "0.0.0.0") ]
6439 def answers(self, other):
6440 if isinstance(other,ARP):
6441 if ( (self.op == self.is_at) and
6442 (other.op == self.who_has) and
6443 (self.psrc == other.pdst) ):
6446 def extract_padding(self, s):
6448 def mysummary(self):
6449 if self.op == self.is_at:
6450 return "ARP is at %s says %s" % (self.hwsrc, self.psrc)
6451 elif self.op == self.who_has:
6452 return "ARP who has %s says %s" % (self.pdst, self.psrc)
6454 return "ARP %ARP.op% %ARP.psrc% > %ARP.pdst%"
6457 class IP(Packet, IPTools):
6459 fields_desc = [ BitField("version" , 4 , 4),
6460 BitField("ihl", None, 4),
6461 XByteField("tos", 0),
6462 ShortField("len", None),
6463 ShortField("id", 1),
6464 FlagsField("flags", 0, 3, ["MF","DF","evil"]),
6465 BitField("frag", 0, 13),
6466 ByteField("ttl", 64),
6467 ByteEnumField("proto", 0, IP_PROTOS),
6468 XShortField("chksum", None),
6469 #IPField("src", "127.0.0.1"),
6470 Emph(SourceIPField("src","dst")),
6471 Emph(IPField("dst", "127.0.0.1")),
6472 IPoptionsField("options", "") ]
6473 def post_build(self, p, pay):
6477 p = chr(((self.version&0xf)<<4) | ihl&0x0f)+p[1:]
6478 if self.len is None:
6480 p = p[:2]+struct.pack("!H", l)+p[4:]
6481 if self.chksum is None:
6483 p = p[:10]+chr(ck>>8)+chr(ck&0xff)+p[12:]
6486 def extract_padding(self, s):
6487 l = self.len - (self.ihl << 2)
6490 def send(self, s, slp=0):
6493 s.sendto(str(p), (p.dst,0))
6494 except socket.error, msg:
6495 log_runtime.error(msg)
6499 if ( (self.proto == socket.IPPROTO_ICMP)
6500 and (isinstance(self.payload, ICMP))
6501 and (self.payload.type in [3,4,5,11,12]) ):
6502 return self.payload.payload.hashret()
6504 if conf.checkIPsrc and conf.checkIPaddr:
6505 return strxor(inet_aton(self.src),inet_aton(self.dst))+struct.pack("B",self.proto)+self.payload.hashret()
6507 return struct.pack("B", self.proto)+self.payload.hashret()
6508 def answers(self, other):
6509 if not isinstance(other,IP):
6511 if conf.checkIPaddr and (self.dst != other.src):
6513 if ( (self.proto == socket.IPPROTO_ICMP) and
6514 (isinstance(self.payload, ICMP)) and
6515 (self.payload.type in [3,4,5,11,12]) ):
6516 # ICMP error message
6517 return self.payload.payload.answers(other)
6520 if ( (conf.checkIPaddr and (self.src != other.dst)) or
6521 (self.proto != other.proto) ):
6523 return self.payload.answers(other.payload)
6524 def mysummary(self):
6525 s = self.sprintf("%IP.src% > %IP.dst% %IP.proto%")
6527 s += " frag:%i" % self.frag
6534 fields_desc = [ ShortEnumField("sport", 20, TCP_SERVICES),
6535 ShortEnumField("dport", 80, TCP_SERVICES),
6538 BitField("dataofs", None, 4),
6539 BitField("reserved", 0, 4),
6540 FlagsField("flags", 0x2, 8, "FSRPAUEC"),
6541 ShortField("window", 8192),
6542 XShortField("chksum", None),
6543 ShortField("urgptr", 0),
6544 TCPOptionsField("options", {}) ]
6545 def post_build(self, p, pay):
6547 dataofs = self.dataofs
6549 dataofs = 5+((len(self.get_field("options").i2m(self,self.options))+3)/4)
6550 p = p[:12]+chr((dataofs << 4) | ord(p[12])&0x0f)+p[13:]
6551 if self.chksum is None:
6552 if isinstance(self.underlayer, IP):
6553 if self.underlayer.len is not None:
6554 ln = self.underlayer.len-20
6557 psdhdr = struct.pack("!4s4sHH",
6558 inet_aton(self.underlayer.src),
6559 inet_aton(self.underlayer.dst),
6560 self.underlayer.proto,
6562 ck=checksum(psdhdr+p)
6563 p = p[:16]+struct.pack("!H", ck)+p[18:]
6564 elif isinstance(self.underlayer, IPv6) or isinstance(self.underlayer, _IPv6OptionHeader):
6565 ck = in6_chksum(socket.IPPROTO_TCP, self.underlayer, p)
6566 p = p[:16]+struct.pack("!H", ck)+p[18:]
6568 warning("No IP underlayer to compute checksum. Leaving null.")
6572 return struct.pack("H",self.sport ^ self.dport)+self.payload.hashret()
6574 return self.payload.hashret()
6575 def answers(self, other):
6576 if not isinstance(other, TCP):
6579 if not ((self.sport == other.dport) and
6580 (self.dport == other.sport)):
6582 if (abs(other.seq-self.ack) > 2+len(other.payload)):
6585 def mysummary(self):
6586 if isinstance(self.underlayer, IP):
6587 return self.underlayer.sprintf("TCP %IP.src%:%TCP.sport% > %IP.dst%:%TCP.dport% %TCP.flags%")
6588 elif isinstance(self.underlayer, IPv6):
6589 return self.underlayer.sprintf("TCP %IPv6.src%:%TCP.sport% > %IPv6.dst%:%TCP.dport% %TCP.flags%")
6591 return self.sprintf("TCP %TCP.sport% > %TCP.dport% %TCP.flags%")
6595 fields_desc = [ ShortEnumField("sport", 53, UDP_SERVICES),
6596 ShortEnumField("dport", 53, UDP_SERVICES),
6597 ShortField("len", None),
6598 XShortField("chksum", None), ]
6599 def post_build(self, p, pay):
6604 p = p[:4]+struct.pack("!H",l)+p[6:]
6605 if self.chksum is None:
6606 if isinstance(self.underlayer, IP):
6607 if self.underlayer.len is not None:
6608 ln = self.underlayer.len-20
6611 psdhdr = struct.pack("!4s4sHH",
6612 inet_aton(self.underlayer.src),
6613 inet_aton(self.underlayer.dst),
6614 self.underlayer.proto,
6616 ck=checksum(psdhdr+p)
6617 p = p[:6]+struct.pack("!H", ck)+p[8:]
6618 elif isinstance(self.underlayer, IPv6) or isinstance(self.underlayer, _IPv6OptionHeader):
6619 ck = in6_chksum(socket.IPPROTO_UDP, self.underlayer, p)
6620 p = p[:6]+struct.pack("!H", ck)+p[8:]
6622 warning("No IP underlayer to compute checksum. Leaving null.")
6624 def extract_padding(self, s):
6628 return self.payload.hashret()
6629 def answers(self, other):
6630 if not isinstance(other, UDP):
6633 if self.dport != other.sport:
6635 return self.payload.answers(other.payload)
6636 def mysummary(self):
6637 if isinstance(self.underlayer, IP):
6638 return self.underlayer.sprintf("UDP %IP.src%:%UDP.sport% > %IP.dst%:%UDP.dport%")
6639 elif isinstance(self.underlayer, IPv6):
6640 return self.underlayer.sprintf("UDP %IPv6.src%:%UDP.sport% > %IPv6.dst%:%UDP.dport%")
6642 return self.sprintf("UDP %UDP.sport% > %UDP.dport%")
6644 icmptypes = { 0 : "echo-reply",
6646 4 : "source-quench",
6649 9 : "router-advertisement",
6650 10 : "router-solicitation",
6651 11 : "time-exceeded",
6652 12 : "parameter-problem",
6653 13 : "timestamp-request",
6654 14 : "timestamp-reply",
6655 15 : "information-request",
6656 16 : "information-response",
6657 17 : "address-mask-request",
6658 18 : "address-mask-reply" }
6662 fields_desc = [ ByteEnumField("type",8, icmptypes),
6663 ByteField("code",0),
6664 XShortField("chksum", None),
6665 ConditionalField(XShortField("id",0), lambda pkt:pkt.type in [0,8,13,14,15,16]),
6666 ConditionalField(XShortField("seq",0), lambda pkt:pkt.type in [0,8,13,14,15,16]),
6667 ConditionalField(ICMPTimeStampField("ts_ori", None), lambda pkt:pkt.type in [13,14]),
6668 ConditionalField(ICMPTimeStampField("ts_rx", None), lambda pkt:pkt.type in [13,14]),
6669 ConditionalField(ICMPTimeStampField("ts_tx", None), lambda pkt:pkt.type in [13,14]),
6670 ConditionalField(IPField("gw","0.0.0.0"), lambda pkt:pkt.type==5),
6671 ConditionalField(ByteField("ptr",0), lambda pkt:pkt.type==12),
6672 ConditionalField(X3BytesField("reserved",0), lambda pkt:pkt.type==12),
6673 ConditionalField(IntField("unused",0), lambda pkt:pkt.type not in [0,5,8,12,13,14,15,16]),
6675 def post_build(self, p, pay):
6677 if self.chksum is None:
6679 p = p[:2]+chr(ck>>8)+chr(ck&0xff)+p[4:]
6683 return struct.pack("HH",self.id,self.seq)+self.payload.hashret()
6684 def answers(self, other):
6685 if not isinstance(other,ICMP):
6687 if ( (other.type,self.type) in [(8,0),(13,14),(15,16),(17,18)] and
6688 self.id == other.id and
6689 self.seq == other.seq ):
6693 def guess_payload_class(self, payload):
6694 if self.type in [3,4,5,11,12]:
6698 def mysummary(self):
6699 if isinstance(self.underlayer, IP):
6700 return self.underlayer.sprintf("ICMP %IP.src% > %IP.dst% %ICMP.type% %ICMP.code%")
6702 return self.sprintf("ICMP %ICMP.type% %ICMP.code%")
6710 def answers(self, other):
6711 if not isinstance(other, IP):
6713 if not ( ((conf.checkIPsrc == 0) or (self.dst == other.dst)) and
6714 (self.src == other.src) and
6715 ( ((conf.checkIPID == 0)
6716 or (self.id == other.id)
6717 or (conf.checkIPID == 1 and self.id == socket.htons(other.id)))) and
6718 (self.proto == other.proto) ):
6720 return self.payload.answers(other.payload)
6721 def mysummary(self):
6722 return Packet.mysummary(self)
6725 class TCPerror(TCP):
6726 name = "TCP in ICMP"
6727 def answers(self, other):
6728 if not isinstance(other, TCP):
6731 if not ((self.sport == other.sport) and
6732 (self.dport == other.dport)):
6734 if conf.check_TCPerror_seqack:
6735 if self.seq is not None:
6736 if self.seq != other.seq:
6738 if self.ack is not None:
6739 if self.ack != other.ack:
6742 def mysummary(self):
6743 return Packet.mysummary(self)
6746 class UDPerror(UDP):
6747 name = "UDP in ICMP"
6748 def answers(self, other):
6749 if not isinstance(other, UDP):
6752 if not ((self.sport == other.sport) and
6753 (self.dport == other.dport)):
6756 def mysummary(self):
6757 return Packet.mysummary(self)
6761 class ICMPerror(ICMP):
6762 name = "ICMP in ICMP"
6763 def answers(self, other):
6764 if not isinstance(other,ICMP):
6766 if not ((self.type == other.type) and
6767 (self.code == other.code)):
6769 if self.code in [0,8,13,14,17,18]:
6770 if (self.id == other.id and
6771 self.seq == other.seq):
6777 def mysummary(self):
6778 return Packet.mysummary(self)
6781 """See http://namabiiru.hongo.wide.ad.jp/scapy6"""
6782 name = "IPv6 not implemented here."
6783 def __init__(self, *args, **kargs):
6784 log_interactive.error(self.name)
6786 return "<IPv6: ERROR not implemented>"
6788 class _IPv6OptionHeader(Packet):
6789 """See http://namabiiru.hongo.wide.ad.jp/scapy6"""
6790 name = "IPv6 not implemented here."
6791 def __init__(self, *args, **kargs):
6792 log_interactive.error(self.name)
6794 return "<IPv6: ERROR not implemented>"
6798 fields_desc = [ ShortEnumField("pkt_type",2,{2:"data"}),
6799 ShortField("len", None),
6800 ShortField("tunnel_id", 0),
6801 ShortField("session_id", 0),
6802 ShortField("ns", 0),
6803 ShortField("nr", 0),
6804 ShortField("offset", 0) ]
6806 def post_build(self, pkt, pay):
6807 if self.len is None:
6808 l = len(pkt)+len(pay)
6809 pkt = pkt[:2]+struct.pack("!H", l)+pkt[4:]
6813 _PPP_proto = { 0x0001: "Padding Protocol",
6814 0x0003: "ROHC small-CID [RFC3095]",
6815 0x0005: "ROHC large-CID [RFC3095]",
6816 0x0021: "Internet Protocol version 4",
6817 0x0023: "OSI Network Layer",
6818 0x0025: "Xerox NS IDP",
6819 0x0027: "DECnet Phase IV",
6820 0x0029: "Appletalk",
6821 0x002b: "Novell IPX",
6822 0x002d: "Van Jacobson Compressed TCP/IP",
6823 0x002f: "Van Jacobson Uncompressed TCP/IP",
6824 0x0031: "Bridging PDU",
6825 0x0033: "Stream Protocol (ST-II)",
6826 0x0035: "Banyan Vines",
6827 0x0037: "reserved (until 1993) [Typo in RFC1172]",
6828 0x0039: "AppleTalk EDDP",
6829 0x003b: "AppleTalk SmartBuffered",
6830 0x003d: "Multi-Link [RFC1717]",
6831 0x003f: "NETBIOS Framing",
6832 0x0041: "Cisco Systems",
6833 0x0043: "Ascom Timeplex",
6834 0x0045: "Fujitsu Link Backup and Load Balancing (LBLB)",
6835 0x0047: "DCA Remote Lan",
6836 0x0049: "Serial Data Transport Protocol (PPP-SDTP)",
6837 0x004b: "SNA over 802.2",
6839 0x004f: "IPv6 Header Compression",
6840 0x0051: "KNX Bridging Data [ianp]",
6841 0x0053: "Encryption [Meyer]",
6842 0x0055: "Individual Link Encryption [Meyer]",
6843 0x0057: "Internet Protocol version 6 [Hinden]",
6844 0x0059: "PPP Muxing [RFC3153]",
6845 0x005b: "Vendor-Specific Network Protocol (VSNP) [RFC3772]",
6846 0x0061: "RTP IPHC Full Header [RFC3544]",
6847 0x0063: "RTP IPHC Compressed TCP [RFC3544]",
6848 0x0065: "RTP IPHC Compressed Non TCP [RFC3544]",
6849 0x0067: "RTP IPHC Compressed UDP 8 [RFC3544]",
6850 0x0069: "RTP IPHC Compressed RTP 8 [RFC3544]",
6851 0x006f: "Stampede Bridging",
6852 0x0071: "Reserved [Fox]",
6853 0x0073: "MP+ Protocol [Smith]",
6854 0x007d: "reserved (Control Escape) [RFC1661]",
6855 0x007f: "reserved (compression inefficient [RFC1662]",
6856 0x0081: "Reserved Until 20-Oct-2000 [IANA]",
6857 0x0083: "Reserved Until 20-Oct-2000 [IANA]",
6858 0x00c1: "NTCITS IPI [Ungar]",
6859 0x00cf: "reserved (PPP NLID)",
6860 0x00fb: "single link compression in multilink [RFC1962]",
6861 0x00fd: "compressed datagram [RFC1962]",
6862 0x00ff: "reserved (compression inefficient)",
6863 0x0201: "802.1d Hello Packets",
6864 0x0203: "IBM Source Routing BPDU",
6865 0x0205: "DEC LANBridge100 Spanning Tree",
6866 0x0207: "Cisco Discovery Protocol [Sastry]",
6867 0x0209: "Netcs Twin Routing [Korfmacher]",
6868 0x020b: "STP - Scheduled Transfer Protocol [Segal]",
6869 0x020d: "EDP - Extreme Discovery Protocol [Grosser]",
6870 0x0211: "Optical Supervisory Channel Protocol (OSCP)[Prasad]",
6871 0x0213: "Optical Supervisory Channel Protocol (OSCP)[Prasad]",
6873 0x0233: "Sigma Network Systems",
6874 0x0235: "Apple Client Server Protocol [Ridenour]",
6875 0x0281: "MPLS Unicast [RFC3032] ",
6876 0x0283: "MPLS Multicast [RFC3032]",
6877 0x0285: "IEEE p1284.4 standard - data packets [Batchelder]",
6878 0x0287: "ETSI TETRA Network Protocol Type 1 [Nieminen]",
6879 0x0289: "Multichannel Flow Treatment Protocol [McCann]",
6880 0x2063: "RTP IPHC Compressed TCP No Delta [RFC3544]",
6881 0x2065: "RTP IPHC Context State [RFC3544]",
6882 0x2067: "RTP IPHC Compressed UDP 16 [RFC3544]",
6883 0x2069: "RTP IPHC Compressed RTP 16 [RFC3544]",
6884 0x4001: "Cray Communications Control Protocol [Stage]",
6885 0x4003: "CDPD Mobile Network Registration Protocol [Quick]",
6886 0x4005: "Expand accelerator protocol [Rachmani]",
6887 0x4007: "ODSICP NCP [Arvind]",
6888 0x4009: "DOCSIS DLL [Gaedtke]",
6889 0x400B: "Cetacean Network Detection Protocol [Siller]",
6890 0x4021: "Stacker LZS [Simpson]",
6891 0x4023: "RefTek Protocol [Banfill]",
6892 0x4025: "Fibre Channel [Rajagopal]",
6893 0x4027: "EMIT Protocols [Eastham]",
6894 0x405b: "Vendor-Specific Protocol (VSP) [RFC3772]",
6895 0x8021: "Internet Protocol Control Protocol",
6896 0x8023: "OSI Network Layer Control Protocol",
6897 0x8025: "Xerox NS IDP Control Protocol",
6898 0x8027: "DECnet Phase IV Control Protocol",
6899 0x8029: "Appletalk Control Protocol",
6900 0x802b: "Novell IPX Control Protocol",
6903 0x8031: "Bridging NCP",
6904 0x8033: "Stream Protocol Control Protocol",
6905 0x8035: "Banyan Vines Control Protocol",
6906 0x8037: "reserved (until 1993)",
6909 0x803d: "Multi-Link Control Protocol",
6910 0x803f: "NETBIOS Framing Control Protocol",
6911 0x8041: "Cisco Systems Control Protocol",
6912 0x8043: "Ascom Timeplex",
6913 0x8045: "Fujitsu LBLB Control Protocol",
6914 0x8047: "DCA Remote Lan Network Control Protocol (RLNCP)",
6915 0x8049: "Serial Data Control Protocol (PPP-SDCP)",
6916 0x804b: "SNA over 802.2 Control Protocol",
6917 0x804d: "SNA Control Protocol",
6918 0x804f: "IP6 Header Compression Control Protocol",
6919 0x8051: "KNX Bridging Control Protocol [ianp]",
6920 0x8053: "Encryption Control Protocol [Meyer]",
6921 0x8055: "Individual Link Encryption Control Protocol [Meyer]",
6922 0x8057: "IPv6 Control Protovol [Hinden]",
6923 0x8059: "PPP Muxing Control Protocol [RFC3153]",
6924 0x805b: "Vendor-Specific Network Control Protocol (VSNCP) [RFC3772]",
6925 0x806f: "Stampede Bridging Control Protocol",
6926 0x8073: "MP+ Control Protocol [Smith]",
6927 0x8071: "Reserved [Fox]",
6928 0x807d: "Not Used - reserved [RFC1661]",
6929 0x8081: "Reserved Until 20-Oct-2000 [IANA]",
6930 0x8083: "Reserved Until 20-Oct-2000 [IANA]",
6931 0x80c1: "NTCITS IPI Control Protocol [Ungar]",
6932 0x80cf: "Not Used - reserved [RFC1661]",
6933 0x80fb: "single link compression in multilink control [RFC1962]",
6934 0x80fd: "Compression Control Protocol [RFC1962]",
6935 0x80ff: "Not Used - reserved [RFC1661]",
6936 0x8207: "Cisco Discovery Protocol Control [Sastry]",
6937 0x8209: "Netcs Twin Routing [Korfmacher]",
6938 0x820b: "STP - Control Protocol [Segal]",
6939 0x820d: "EDPCP - Extreme Discovery Protocol Ctrl Prtcl [Grosser]",
6940 0x8235: "Apple Client Server Protocol Control [Ridenour]",
6941 0x8281: "MPLSCP [RFC3032]",
6942 0x8285: "IEEE p1284.4 standard - Protocol Control [Batchelder]",
6943 0x8287: "ETSI TETRA TNP1 Control Protocol [Nieminen]",
6944 0x8289: "Multichannel Flow Treatment Protocol [McCann]",
6945 0xc021: "Link Control Protocol",
6946 0xc023: "Password Authentication Protocol",
6947 0xc025: "Link Quality Report",
6948 0xc027: "Shiva Password Authentication Protocol",
6949 0xc029: "CallBack Control Protocol (CBCP)",
6950 0xc02b: "BACP Bandwidth Allocation Control Protocol [RFC2125]",
6951 0xc02d: "BAP [RFC2125]",
6952 0xc05b: "Vendor-Specific Authentication Protocol (VSAP) [RFC3772]",
6953 0xc081: "Container Control Protocol [KEN]",
6954 0xc223: "Challenge Handshake Authentication Protocol",
6955 0xc225: "RSA Authentication Protocol [Narayana]",
6956 0xc227: "Extensible Authentication Protocol [RFC2284]",
6957 0xc229: "Mitsubishi Security Info Exch Ptcl (SIEP) [Seno]",
6958 0xc26f: "Stampede Bridging Authorization Protocol",
6959 0xc281: "Proprietary Authentication Protocol [KEN]",
6960 0xc283: "Proprietary Authentication Protocol [Tackabury]",
6961 0xc481: "Proprietary Node ID Authentication Protocol [KEN]"}
6965 fields_desc = [ XByteField("address",0xff),
6966 XByteField("control",0x03) ]
6968 class PPP_metaclass(Packet_metaclass):
6969 def __call__(self, _pkt=None, *args, **kargs):
6971 if _pkt and _pkt[0] == '\xff':
6973 i = cls.__new__(cls, cls.__name__, cls.__bases__, cls.__dict__)
6974 i.__init__(_pkt=_pkt, *args, **kargs)
6979 __metaclass__ = PPP_metaclass
6980 name = "PPP Link Layer"
6981 fields_desc = [ ShortEnumField("proto", 0x0021, _PPP_proto) ]
6983 _PPP_conftypes = { 1:"Configure-Request",
6986 4:"Configure-Reject",
6987 5:"Terminate-Request",
6990 8:"Protocol-Reject",
6993 11:"Discard-Request",
6998 class PPP_Option_metaclass(Packet_metaclass):
7000 def __call__(self, _pkt=None, *args, **kargs):
7004 cls = self._known_options.get(t,self)
7005 i = cls.__new__(cls, cls.__name__, cls.__bases__, cls.__dict__)
7006 i.__init__(_pkt=_pkt, *args, **kargs)
7008 def _register(self, cls):
7009 self._known_options[cls.fields_desc[0].default] = cls
7012 ### PPP IPCP stuff (RFC 1332)
7014 # All IPCP options are defined below (names and associated classes)
7015 _PPP_ipcpopttypes = { 1:"IP-Addresses (Deprecated)",
7016 2:"IP-Compression-Protocol",
7018 4:"Mobile-IPv4", # not implemented, present for completeness
7019 129:"Primary-DNS-Address",
7020 130:"Primary-NBNS-Address",
7021 131:"Secondary-DNS-Address",
7022 132:"Secondary-NBNS-Address"}
7026 class PPP_IPCP_Option_metaclass(PPP_Option_metaclass):
7030 class PPP_IPCP_Option(Packet):
7031 __metaclass__=PPP_IPCP_Option_metaclass
7032 name = "PPP IPCP Option"
7033 fields_desc = [ ByteEnumField("type" , None , _PPP_ipcpopttypes),
7034 FieldLenField("len", None, length_of="data", fmt="B", adjust=lambda p,x:x+2),
7035 StrLenField("data", "", length_from=lambda p:max(0,p.len-2)) ]
7036 def extract_padding(self, pay):
7039 class PPP_IPCP_Specific_Option_metaclass(PPP_IPCP_Option_metaclass):
7040 def __new__(cls, name, bases, dct):
7041 newcls = super(PPP_IPCP_Specific_Option_metaclass, cls).__new__(cls, name, bases, dct)
7042 PPP_IPCP_Option._register(newcls)
7045 class PPP_IPCP_Option_IPAddress(PPP_IPCP_Option):
7046 __metaclass__=PPP_IPCP_Specific_Option_metaclass
7047 name = "PPP IPCP Option: IP Address"
7048 fields_desc = [ ByteEnumField("type" , 3 , _PPP_ipcpopttypes),
7049 FieldLenField("len", None, length_of="data", fmt="B", adjust=lambda p,x:x+6),
7050 IPField("data","0.0.0.0"),
7051 ConditionalField(StrLenField("garbage","", length_from=lambda pkt:pkt.len-6), lambda p:p.len!=6) ]
7053 class PPP_IPCP_Option_DNS1(PPP_IPCP_Option):
7054 __metaclass__=PPP_IPCP_Specific_Option_metaclass
7055 name = "PPP IPCP Option: DNS1 Address"
7056 fields_desc = [ ByteEnumField("type" , 129 , _PPP_ipcpopttypes),
7057 FieldLenField("len", None, length_of="data", fmt="B", adjust=lambda p,x:x+6),
7058 IPField("data","0.0.0.0"),
7059 ConditionalField(StrLenField("garbage","", length_from=lambda pkt:pkt.len-6), lambda p:p.len!=6) ]
7061 class PPP_IPCP_Option_DNS2(PPP_IPCP_Option):
7062 __metaclass__=PPP_IPCP_Specific_Option_metaclass
7063 name = "PPP IPCP Option: DNS2 Address"
7064 fields_desc = [ ByteEnumField("type" , 131 , _PPP_ipcpopttypes),
7065 FieldLenField("len", None, length_of="data", fmt="B", adjust=lambda p,x:x+6),
7066 IPField("data","0.0.0.0"),
7067 ConditionalField(StrLenField("garbage","", length_from=lambda pkt:pkt.len-6), lambda p:p.len!=6) ]
7069 class PPP_IPCP_Option_NBNS1(PPP_IPCP_Option):
7070 __metaclass__=PPP_IPCP_Specific_Option_metaclass
7071 name = "PPP IPCP Option: NBNS1 Address"
7072 fields_desc = [ ByteEnumField("type" , 130 , _PPP_ipcpopttypes),
7073 FieldLenField("len", None, length_of="data", fmt="B", adjust=lambda p,x:x+6),
7074 IPField("data","0.0.0.0"),
7075 ConditionalField(StrLenField("garbage","", length_from=lambda pkt:pkt.len-6), lambda p:p.len!=6) ]
7077 class PPP_IPCP_Option_NBNS2(PPP_IPCP_Option):
7078 __metaclass__=PPP_IPCP_Specific_Option_metaclass
7079 name = "PPP IPCP Option: NBNS2 Address"
7080 fields_desc = [ ByteEnumField("type" , 132 , _PPP_ipcpopttypes),
7081 FieldLenField("len", None, length_of="data", fmt="B", adjust=lambda p,x:x+6),
7082 IPField("data","0.0.0.0"),
7083 ConditionalField(StrLenField("garbage","", length_from=lambda pkt:pkt.len-6), lambda p:p.len!=6) ]
7088 class PPP_IPCP(Packet):
7089 fields_desc = [ ByteEnumField("code" , 1, _PPP_conftypes),
7090 XByteField("id", 0 ),
7091 FieldLenField("len" , None, fmt="H", length_of="options", adjust=lambda p,x:x+4 ),
7092 PacketListField("options", [], PPP_IPCP_Option, length_from=lambda p:p.len-4,) ]
7097 _PPP_ecpopttypes = { 0:"OUI",
7100 class PPP_ECP_Option_metaclass(PPP_Option_metaclass):
7105 class PPP_ECP_Option(Packet):
7106 __metaclass__=PPP_ECP_Option_metaclass
7107 name = "PPP ECP Option"
7108 fields_desc = [ ByteEnumField("type" , None , _PPP_ecpopttypes),
7109 FieldLenField("len", None, length_of="data", fmt="B", adjust=lambda p,x:x+2),
7110 StrLenField("data", "", length_from=lambda p:max(0,p.len-2)) ]
7111 def extract_padding(self, pay):
7114 class PPP_ECP_Specific_Option_metaclass(PPP_ECP_Option_metaclass):
7115 def __new__(cls, name, bases, dct):
7116 newcls = super(PPP_ECP_Specific_Option_metaclass, cls).__new__(cls, name, bases, dct)
7117 PPP_ECP_Option._register(newcls)
7120 class PPP_ECP_Option_OUI(PPP_ECP_Option):
7121 __metaclass__=PPP_ECP_Specific_Option_metaclass
7122 fields_desc = [ ByteEnumField("type" , 0 , _PPP_ecpopttypes),
7123 FieldLenField("len", None, length_of="data", fmt="B", adjust=lambda p,x:x+2),
7124 StrFixedLenField("oui","",3),
7125 ByteField("subtype",0),
7126 StrLenField("data", "", length_from=lambda p:p.len-6) ]
7130 class PPP_ECP(Packet):
7131 fields_desc = [ ByteEnumField("code" , 1, _PPP_conftypes),
7132 XByteField("id", 0 ),
7133 FieldLenField("len" , None, fmt="H", length_of="options", adjust=lambda p,x:x+4 ),
7134 PacketListField("options", [], PPP_ECP_Option, length_from=lambda p:p.len-4,) ]
7141 fields_desc = [ ShortField("id",0),
7142 BitField("qr",0, 1),
7143 BitEnumField("opcode", 0, 4, {0:"QUERY",1:"IQUERY",2:"STATUS"}),
7144 BitField("aa", 0, 1),
7145 BitField("tc", 0, 1),
7146 BitField("rd", 0, 1),
7147 BitField("ra", 0 ,1),
7148 BitField("z", 0, 3),
7149 BitEnumField("rcode", 0, 4, {0:"ok", 1:"format-error", 2:"server-failure", 3:"name-error", 4:"not-implemented", 5:"refused"}),
7150 DNSRRCountField("qdcount", None, "qd"),
7151 DNSRRCountField("ancount", None, "an"),
7152 DNSRRCountField("nscount", None, "ns"),
7153 DNSRRCountField("arcount", None, "ar"),
7154 DNSQRField("qd", "qdcount"),
7155 DNSRRField("an", "ancount"),
7156 DNSRRField("ns", "nscount"),
7157 DNSRRField("ar", "arcount",0) ]
7158 def answers(self, other):
7159 return (isinstance(other, DNS)
7160 and self.id == other.id
7164 def mysummary(self):
7165 type = ["Qry","Ans"][self.qr]
7169 if self.ancount > 0 and isinstance(self.an, DNSRR):
7170 name = ' "%s"' % self.an.rdata
7173 if self.qdcount > 0 and isinstance(self.qd, DNSQR):
7174 name = ' "%s"' % self.qd.qname
7175 return 'DNS %s%s ' % (type, name)
7177 dnstypes = { 0:"ANY", 255:"ALL",
7178 1:"A", 2:"NS", 3:"MD", 4:"MD", 5:"CNAME", 6:"SOA", 7: "MB", 8:"MG",
7179 9:"MR",10:"NULL",11:"WKS",12:"PTR",13:"HINFO",14:"MINFO",15:"MX",16:"TXT",
7180 17:"RP",18:"AFSDB",28:"AAAA", 33:"SRV",38:"A6",39:"DNAME"}
7182 dnsqtypes = {251:"IXFR",252:"AXFR",253:"MAILB",254:"MAILA",255:"ALL"}
7183 dnsqtypes.update(dnstypes)
7184 dnsclasses = {1: 'IN', 2: 'CS', 3: 'CH', 4: 'HS', 255: 'ANY'}
7187 class DNSQR(Packet):
7188 name = "DNS Question Record"
7190 fields_desc = [ DNSStrField("qname",""),
7191 ShortEnumField("qtype", 1, dnsqtypes),
7192 ShortEnumField("qclass", 1, dnsclasses) ]
7196 class DNSRR(Packet):
7197 name = "DNS Resource Record"
7199 fields_desc = [ DNSStrField("rrname",""),
7200 ShortEnumField("type", 1, dnstypes),
7201 ShortEnumField("rclass", 1, dnsclasses),
7203 RDLenField("rdlen"),
7204 RDataField("rdata", "", length_from=lambda pkt:pkt.rdlen) ]
7209 class BOOTP(Packet):
7211 fields_desc = [ ByteEnumField("op",1, {1:"BOOTREQUEST", 2:"BOOTREPLY"}),
7212 ByteField("htype",1),
7213 ByteField("hlen",6),
7214 ByteField("hops",0),
7216 ShortField("secs",0),
7217 FlagsField("flags", 0, 16, "???????????????B"),
7218 IPField("ciaddr","0.0.0.0"),
7219 IPField("yiaddr","0.0.0.0"),
7220 IPField("siaddr","0.0.0.0"),
7221 IPField("giaddr","0.0.0.0"),
7222 Field("chaddr","", "16s"),
7223 Field("sname","","64s"),
7224 Field("file","","128s"),
7225 StrField("options","") ]
7226 def guess_payload_class(self, payload):
7227 if self.options[:len(dhcpmagic)] == dhcpmagic:
7230 return Packet.guess_payload_class(self, payload)
7231 def extract_padding(self,s):
7232 if self.options[:len(dhcpmagic)] == dhcpmagic:
7233 # set BOOTP options to DHCP magic cookie and make rest a payload of DHCP options
7234 payload = self.options[len(dhcpmagic):]
7235 self.options = self.options[:len(dhcpmagic)]
7236 return payload, None
7240 return struct.pack("L", self.xid)
7241 def answers(self, other):
7242 if not isinstance(other, BOOTP):
7244 return self.xid == other.xid
7248 #DHCP_UNKNOWN, DHCP_IP, DHCP_IPLIST, DHCP_TYPE \
7263 11:"lease_unassigned",
7270 1: IPField("subnet_mask", "0.0.0.0"),
7272 3: IPField("router","0.0.0.0"),
7273 4: IPField("time_server","0.0.0.0"),
7274 5: IPField("IEN_name_server","0.0.0.0"),
7275 6: IPField("name_server","0.0.0.0"),
7276 7: IPField("log_server","0.0.0.0"),
7277 8: IPField("cookie_server","0.0.0.0"),
7278 9: IPField("lpr_server","0.0.0.0"),
7282 17: "root_disk_path",
7283 22: "max_dgram_reass_size",
7286 28: IPField("broadcast_address","0.0.0.0"),
7287 35: "arp_cache_timeout",
7288 36: "ether_or_dot3",
7290 38: "tcp_keepalive_interval",
7291 39: "tcp_keepalive_garbage",
7293 41: IPField("NIS_server","0.0.0.0"),
7294 42: IPField("NTP_server","0.0.0.0"),
7295 43: "vendor_specific",
7296 44: IPField("NetBIOS_server","0.0.0.0"),
7297 45: IPField("NetBIOS_dist_server","0.0.0.0"),
7298 50: IPField("requested_addr","0.0.0.0"),
7299 51: IntField("lease_time", 43200),
7300 54: IPField("server_id","0.0.0.0"),
7301 55: "param_req_list",
7302 57: ShortField("max_dhcp_size", 1500),
7303 58: IntField("renewal_time", 21600),
7304 59: IntField("rebinding_time", 37800),
7305 60: "vendor_class_id",
7308 64: "NISplus_domain",
7309 65: IPField("NISplus_server","0.0.0.0"),
7310 69: IPField("SMTP_server","0.0.0.0"),
7311 70: IPField("POP3_server","0.0.0.0"),
7312 71: IPField("NNTP_server","0.0.0.0"),
7313 72: IPField("WWW_server","0.0.0.0"),
7314 73: IPField("Finger_server","0.0.0.0"),
7315 74: IPField("IRC_server","0.0.0.0"),
7316 75: IPField("StreetTalk_server","0.0.0.0"),
7317 76: "StreetTalk_Dir_Assistance",
7318 82: "relay_agent_Information",
7319 53: ByteEnumField("message-type", 1, DHCPTypes),
7320 # 55: DHCPRequestListField("request-list"),
7326 for k,v in DHCPOptions.iteritems():
7332 DHCPRevOptions[n] = (k,v)
7341 class DHCPOptionsField(StrField):
7343 def i2repr(self,pkt,x):
7346 if type(v) is tuple and len(v) in [2,3]:
7347 if DHCPRevOptions.has_key(v[0]) and isinstance(DHCPRevOptions[v[0]][1],Field):
7348 f = DHCPRevOptions[v[0]][1]
7349 vv = f.i2repr(pkt,v[1])
7352 r = "%s=%s" % (v[0],vv)
7354 r += " (garbage=%r)" % v[2]
7358 return "[%s]" % (" ".join(s))
7360 def getfield(self, pkt, s):
7361 return "", self.m2i(pkt, s)
7362 def m2i(self, pkt, x):
7374 if len(x) < 2 or len(x) < ord(x[1])+2:
7377 elif DHCPOptions.has_key(o):
7380 if isinstance(f, str):
7382 opt.append( (f,x[2:olen+2]) )
7387 left, val = f.getfield(pkt,x[2:olen+2])
7392 otuple = (f.name, val, left)
7394 otuple = (f.name, val)
7399 opt.append((o, x[2:olen+2]))
7402 def i2m(self, pkt, x):
7407 if type(o) is tuple and len(o) in [2,3]:
7410 if isinstance(name, int):
7411 onum, oval = name, val
7412 elif DHCPRevOptions.has_key(name):
7413 onum, f = DHCPRevOptions[name]
7417 oval = f.addfield(pkt,"",f.any2i(pkt,val))
7419 warning("Unknown field option %s" % name)
7428 elif (type(o) is str and DHCPRevOptions.has_key(o) and
7429 DHCPRevOptions[o][1] == None):
7430 s += chr(DHCPRevOptions[o][0])
7431 elif type(o) is int:
7433 elif type(o) is str:
7436 warning("Malformed option %s" % o)
7441 name = "DHCP options"
7442 fields_desc = [ DHCPOptionsField("options","") ]
7445 class Dot11(Packet):
7448 BitField("subtype", 0, 4),
7449 BitEnumField("type", 0, 2, ["Management", "Control", "Data", "Reserved"]),
7450 BitField("proto", 0, 2),
7451 FlagsField("FCfield", 0, 8, ["to-DS", "from-DS", "MF", "retry", "pw-mgt", "MD", "wep", "order"]),
7453 MACField("addr1", ETHER_ANY),
7454 Dot11Addr2MACField("addr2", ETHER_ANY),
7455 Dot11Addr3MACField("addr3", ETHER_ANY),
7456 Dot11SCField("SC", 0),
7457 Dot11Addr4MACField("addr4", ETHER_ANY)
7459 def mysummary(self):
7460 return self.sprintf("802.11 %Dot11.type% %Dot11.subtype% %Dot11.addr2% > %Dot11.addr1%")
7461 def guess_payload_class(self, payload):
7462 if self.type == 0x02 and (self.subtype >= 0x08 and self.subtype <=0xF and self.subtype != 0xD):
7464 elif self.FCfield & 0x40:
7467 return Packet.guess_payload_class(self, payload)
7468 def answers(self, other):
7469 if isinstance(other,Dot11):
7470 if self.type == 0: # management
7471 if self.addr1.lower() != other.addr2.lower(): # check resp DA w/ req SA
7473 if (other.subtype,self.subtype) in [(0,1),(2,3),(4,5)]:
7475 if self.subtype == other.subtype == 11: # auth
7476 return self.payload.answers(other.payload)
7477 elif self.type == 1: # control
7479 elif self.type == 2: # data
7480 return self.payload.answers(other.payload)
7481 elif self.type == 3: # reserved
7484 def unwep(self, key=None, warn=1):
7485 if self.FCfield & 0x40 == 0:
7487 warning("No WEP to remove")
7489 if isinstance(self.payload.payload, NoPayload):
7490 if key or conf.wepkey:
7491 self.payload.decrypt(key)
7492 if isinstance(self.payload.payload, NoPayload):
7494 warning("Dot11 can't be decrypted. Check conf.wepkey.")
7496 self.FCfield &= ~0x40
7497 self.payload=self.payload.payload
7500 class Dot11QoS(Packet):
7502 fields_desc = [ BitField("TID",None,4),
7503 BitField("EOSP",None,1),
7504 BitField("Ack Policy",None,2),
7505 BitField("Reserved",None,1),
7506 ByteField("TXOP",None) ]
7507 def guess_payload_class(self, payload):
7508 if isinstance(self.underlayer, Dot11):
7509 if self.underlayer.FCfield & 0x40:
7511 return Packet.guess_payload_class(self, payload)
7514 capability_list = [ "res8", "res9", "short-slot", "res11",
7515 "res12", "DSSS-OFDM", "res14", "res15",
7516 "ESS", "IBSS", "CFP", "CFP-req",
7517 "privacy", "short-preamble", "PBCC", "agility"]
7519 reason_code = {0:"reserved",1:"unspec", 2:"auth-expired",
7520 3:"deauth-ST-leaving",
7521 4:"inactivity", 5:"AP-full", 6:"class2-from-nonauth",
7522 7:"class3-from-nonass", 8:"disas-ST-leaving",
7525 status_code = {0:"success", 1:"failure", 10:"cannot-support-all-cap",
7526 11:"inexist-asso", 12:"asso-denied", 13:"algo-unsupported",
7527 14:"bad-seq-num", 15:"challenge-failure",
7528 16:"timeout", 17:"AP-full",18:"rate-unsupported" }
7530 class Dot11Beacon(Packet):
7531 name = "802.11 Beacon"
7532 fields_desc = [ LELongField("timestamp", 0),
7533 LEShortField("beacon_interval", 0x0064),
7534 FlagsField("cap", 0, 16, capability_list) ]
7537 class Dot11Elt(Packet):
7538 name = "802.11 Information Element"
7539 fields_desc = [ ByteEnumField("ID", 0, {0:"SSID", 1:"Rates", 2: "FHset", 3:"DSset", 4:"CFset", 5:"TIM", 6:"IBSSset", 16:"challenge",
7540 42:"ERPinfo", 46:"QoS Capability", 47:"ERPinfo", 48:"RSNinfo", 50:"ESRates",221:"vendor",68:"reserved"}),
7541 FieldLenField("len", None, "info", "B"),
7542 StrLenField("info", "", length_from=lambda x:x.len) ]
7543 def mysummary(self):
7545 return "SSID=%s"%repr(self.info),[Dot11]
7549 class Dot11ATIM(Packet):
7550 name = "802.11 ATIM"
7552 class Dot11Disas(Packet):
7553 name = "802.11 Disassociation"
7554 fields_desc = [ LEShortEnumField("reason", 1, reason_code) ]
7556 class Dot11AssoReq(Packet):
7557 name = "802.11 Association Request"
7558 fields_desc = [ FlagsField("cap", 0, 16, capability_list),
7559 LEShortField("listen_interval", 0x00c8) ]
7562 class Dot11AssoResp(Packet):
7563 name = "802.11 Association Response"
7564 fields_desc = [ FlagsField("cap", 0, 16, capability_list),
7565 LEShortField("status", 0),
7566 LEShortField("AID", 0) ]
7568 class Dot11ReassoReq(Packet):
7569 name = "802.11 Reassociation Request"
7570 fields_desc = [ FlagsField("cap", 0, 16, capability_list),
7571 MACField("current_AP", ETHER_ANY),
7572 LEShortField("listen_interval", 0x00c8) ]
7575 class Dot11ReassoResp(Dot11AssoResp):
7576 name = "802.11 Reassociation Response"
7578 class Dot11ProbeReq(Packet):
7579 name = "802.11 Probe Request"
7581 class Dot11ProbeResp(Packet):
7582 name = "802.11 Probe Response"
7583 fields_desc = [ LELongField("timestamp", 0),
7584 LEShortField("beacon_interval", 0x0064),
7585 FlagsField("cap", 0, 16, capability_list) ]
7587 class Dot11Auth(Packet):
7588 name = "802.11 Authentication"
7589 fields_desc = [ LEShortEnumField("algo", 0, ["open", "sharedkey"]),
7590 LEShortField("seqnum", 0),
7591 LEShortEnumField("status", 0, status_code) ]
7592 def answers(self, other):
7593 if self.seqnum == other.seqnum+1:
7597 class Dot11Deauth(Packet):
7598 name = "802.11 Deauthentication"
7599 fields_desc = [ LEShortEnumField("reason", 1, reason_code) ]
7603 class Dot11WEP(Packet):
7604 name = "802.11 WEP packet"
7605 fields_desc = [ StrFixedLenField("iv", "\0\0\0", 3),
7606 ByteField("keyid", 0),
7607 StrField("wepdata",None,remain=4),
7608 IntField("icv",None) ]
7610 def post_dissect(self, s):
7611 # self.icv, = struct.unpack("!I",self.wepdata[-4:])
7612 # self.wepdata = self.wepdata[:-4]
7615 def build_payload(self):
7616 if self.wepdata is None:
7617 return Packet.build_payload(self)
7620 def post_build(self, p, pay):
7621 if self.wepdata is None:
7624 if self.icv is None:
7625 pay += struct.pack("<I",crc32(pay))
7629 c = ARC4.new(self.iv+key)
7630 p = p[:4]+c.encrypt(pay)+icv
7632 warning("No WEP key set (conf.wepkey).. strange results expected..")
7636 def decrypt(self,key=None):
7640 c = ARC4.new(self.iv+key)
7641 self.add_payload(LLC(c.decrypt(self.wepdata)))
7645 class PrismHeader(Packet):
7646 """ iwpriv wlan0 monitor 3 """
7647 name = "Prism header"
7648 fields_desc = [ LEIntField("msgcode",68),
7649 LEIntField("len",144),
7650 StrFixedLenField("dev","",16),
7651 LEIntField("hosttime_did",0),
7652 LEShortField("hosttime_status",0),
7653 LEShortField("hosttime_len",0),
7654 LEIntField("hosttime",0),
7655 LEIntField("mactime_did",0),
7656 LEShortField("mactime_status",0),
7657 LEShortField("mactime_len",0),
7658 LEIntField("mactime",0),
7659 LEIntField("channel_did",0),
7660 LEShortField("channel_status",0),
7661 LEShortField("channel_len",0),
7662 LEIntField("channel",0),
7663 LEIntField("rssi_did",0),
7664 LEShortField("rssi_status",0),
7665 LEShortField("rssi_len",0),
7666 LEIntField("rssi",0),
7667 LEIntField("sq_did",0),
7668 LEShortField("sq_status",0),
7669 LEShortField("sq_len",0),
7671 LEIntField("signal_did",0),
7672 LEShortField("signal_status",0),
7673 LEShortField("signal_len",0),
7674 LESignedIntField("signal",0),
7675 LEIntField("noise_did",0),
7676 LEShortField("noise_status",0),
7677 LEShortField("noise_len",0),
7678 LEIntField("noise",0),
7679 LEIntField("rate_did",0),
7680 LEShortField("rate_status",0),
7681 LEShortField("rate_len",0),
7682 LEIntField("rate",0),
7683 LEIntField("istx_did",0),
7684 LEShortField("istx_status",0),
7685 LEShortField("istx_len",0),
7686 LEIntField("istx",0),
7687 LEIntField("frmlen_did",0),
7688 LEShortField("frmlen_status",0),
7689 LEShortField("frmlen_len",0),
7690 LEIntField("frmlen",0),
7692 def answers(self, other):
7693 if isinstance(other, PrismHeader):
7694 return self.payload.answers(other.payload)
7696 return self.payload.answers(other)
7703 ByteField("version", 0),
7704 ByteEnumField("opcode", 0, { 0:"Hello"}),
7705 ByteEnumField("state", 16, { 16:"Active"}),
7706 ByteField("hellotime", 3),
7707 ByteField("holdtime", 10),
7708 ByteField("priority", 120),
7709 ByteField("group", 1),
7710 ByteField("reserved", 0),
7711 StrFixedLenField("auth","cisco",8),
7712 IPField("virtualIP","192.168.1.1") ]
7724 BitEnumField('leap', 0, 2,
7729 BitField('version', 3, 3),
7730 BitEnumField('mode', 3, 3,
7739 BitField('stratum', 2, 8),
7740 BitField('poll', 0xa, 8), ### XXX : it's a signed int
7741 BitField('precision', 0, 8), ### XXX : it's a signed int
7742 FloatField('delay', 0, 32),
7743 FloatField('dispersion', 0, 32),
7744 IPField('id', "127.0.0.1"),
7745 TimeStampField('ref', 0, 64),
7746 TimeStampField('orig', -1, 64), # -1 means current time
7747 TimeStampField('recv', 0, 64),
7748 TimeStampField('sent', -1, 64)
7750 def mysummary(self):
7751 return self.sprintf("NTP v%ir,NTP.version%, %NTP.mode%")
7756 fields_desc = [ BitField("chksumpresent",0,1),
7757 BitField("reserved0",0,12),
7758 BitField("version",0,3),
7759 XShortEnumField("proto", 0x0000, ETHER_TYPES),
7760 ConditionalField(XShortField("chksum",None),lambda pkt:pkt.chksumpresent==1),
7761 ConditionalField(XShortField("reserved1",None),lambda pkt:pkt.chksumpresent==1),
7763 def post_build(self, p, pay):
7765 if self.chksumpresent and self.chksum is None:
7767 p = p[:4]+chr((c>>8)&0xff)+chr(c&0xff)+p[6:]
7771 class Radius(Packet):
7773 fields_desc = [ ByteEnumField("code", 1, {1: "Access-Request",
7776 4: "Accounting-Request",
7777 5: "Accounting-Accept",
7778 6: "Accounting-Status",
7779 7: "Password-Request",
7781 9: "Password-Reject",
7782 10: "Accounting-Message",
7783 11: "Access-Challenge",
7784 12: "Status-Server",
7785 13: "Status-Client",
7786 21: "Resource-Free-Request",
7787 22: "Resource-Free-Response",
7788 23: "Resource-Query-Request",
7789 24: "Resource-Query-Response",
7790 25: "Alternate-Resource-Reclaim-Request",
7791 26: "NAS-Reboot-Request",
7792 27: "NAS-Reboot-Response",
7793 29: "Next-Passcode",
7795 31: "Terminate-Session",
7796 32: "Password-Expired",
7797 33: "Event-Request",
7798 34: "Event-Response",
7799 40: "Disconnect-Request",
7800 41: "Disconnect-ACK",
7801 42: "Disconnect-NAK",
7805 50: "IP-Address-Allocate",
7806 51: "IP-Address-Release",
7807 253: "Experimental-use",
7811 ShortField("len", None),
7812 StrFixedLenField("authenticator","",16) ]
7813 def post_build(self, p, pay):
7818 p = p[:2]+struct.pack("!H",l)+p[4:]
7827 ByteEnumField("command",1,{1:"req",2:"resp",3:"traceOn",4:"traceOff",5:"sun",
7828 6:"trigReq",7:"trigResp",8:"trigAck",9:"updateReq",
7829 10:"updateResp",11:"updateAck"}),
7830 ByteField("version",1),
7831 ShortField("null",0),
7834 class RIPEntry(Packet):
7837 ShortEnumField("AF",2,{2:"IP"}),
7838 ShortField("RouteTag",0),
7839 IPField("addr","0.0.0.0"),
7840 IPField("mask","0.0.0.0"),
7841 IPField("nextHop","0.0.0.0"),
7842 IntEnumField("metric",1,{16:"Unreach"}),
7848 ISAKMP_payload_type = ["None","SA","Proposal","Transform","KE","ID","CERT","CR","Hash",
7849 "SIG","Nonce","Notification","Delete","VendorID"]
7851 ISAKMP_exchange_type = ["None","base","identity prot.",
7852 "auth only", "aggressive", "info"]
7855 class ISAKMP_class(Packet):
7856 def guess_payload_class(self, payload):
7857 np = self.next_payload
7860 elif np < len(ISAKMP_payload_type):
7861 pt = ISAKMP_payload_type[np]
7862 return globals().get("ISAKMP_payload_%s" % pt, ISAKMP_payload)
7864 return ISAKMP_payload
7867 class ISAKMP(ISAKMP_class): # rfc2408
7870 StrFixedLenField("init_cookie","",8),
7871 StrFixedLenField("resp_cookie","",8),
7872 ByteEnumField("next_payload",0,ISAKMP_payload_type),
7873 XByteField("version",0x10),
7874 ByteEnumField("exch_type",0,ISAKMP_exchange_type),
7875 FlagsField("flags",0, 8, ["encryption","commit","auth_only","res3","res4","res5","res6","res7"]), # XXX use a Flag field
7877 IntField("length",None)
7880 def guess_payload_class(self, payload):
7883 return ISAKMP_class.guess_payload_class(self, payload)
7885 def answers(self, other):
7886 if isinstance(other, ISAKMP):
7887 if other.init_cookie == self.init_cookie:
7890 def post_build(self, p, pay):
7892 if self.length is None:
7893 p = p[:24]+struct.pack("!I",len(p))+p[28:]
7899 class ISAKMP_payload_Transform(ISAKMP_class):
7900 name = "IKE Transform"
7902 ByteEnumField("next_payload",None,ISAKMP_payload_type),
7904 # ShortField("len",None),
7905 ShortField("length",None),
7906 ByteField("num",None),
7907 ByteEnumField("id",1,{1:"KEY_IKE"}),
7908 ShortField("res2",0),
7909 ISAKMPTransformSetField("transforms",None,length_from=lambda x:x.length-8)
7910 # XIntField("enc",0x80010005L),
7911 # XIntField("hash",0x80020002L),
7912 # XIntField("auth",0x80030001L),
7913 # XIntField("group",0x80040002L),
7914 # XIntField("life_type",0x800b0001L),
7915 # XIntField("durationh",0x000c0004L),
7916 # XIntField("durationl",0x00007080L),
7918 def post_build(self, p, pay):
7919 if self.length is None:
7921 p = p[:2]+chr((l>>8)&0xff)+chr(l&0xff)+p[4:]
7928 class ISAKMP_payload_Proposal(ISAKMP_class):
7929 name = "IKE proposal"
7930 # ISAKMP_payload_type = 0
7932 ByteEnumField("next_payload",None,ISAKMP_payload_type),
7934 FieldLenField("length",None,"trans","H", adjust=lambda pkt,x:x+8),
7935 ByteField("proposal",1),
7936 ByteEnumField("proto",1,{1:"ISAKMP"}),
7937 FieldLenField("SPIsize",None,"SPI","B"),
7938 ByteField("trans_nb",None),
7939 StrLenField("SPI","",length_from=lambda x:x.SPIsize),
7940 PacketLenField("trans",Raw(),ISAKMP_payload_Transform,length_from=lambda x:x.length-8),
7944 class ISAKMP_payload(ISAKMP_class):
7945 name = "ISAKMP payload"
7947 ByteEnumField("next_payload",None,ISAKMP_payload_type),
7949 FieldLenField("length",None,"load","H", adjust=lambda pkt,x:x+4),
7950 StrLenField("load","",length_from=lambda x:x.length-4),
7954 class ISAKMP_payload_VendorID(ISAKMP_class):
7955 name = "ISAKMP Vendor ID"
7956 overload_fields = { ISAKMP: { "next_payload":13 }}
7958 ByteEnumField("next_payload",None,ISAKMP_payload_type),
7960 FieldLenField("length",None,"vendorID","H", adjust=lambda pkt,x:x+4),
7961 StrLenField("vendorID","",length_from=lambda x:x.length-4),
7964 class ISAKMP_payload_SA(ISAKMP_class):
7966 overload_fields = { ISAKMP: { "next_payload":1 }}
7968 ByteEnumField("next_payload",None,ISAKMP_payload_type),
7970 FieldLenField("length",None,"prop","H", adjust=lambda pkt,x:x+12),
7971 IntEnumField("DOI",1,{1:"IPSEC"}),
7972 IntEnumField("situation",1,{1:"identity"}),
7973 PacketLenField("prop",Raw(),ISAKMP_payload_Proposal,length_from=lambda x:x.length-12),
7976 class ISAKMP_payload_Nonce(ISAKMP_class):
7977 name = "ISAKMP Nonce"
7978 overload_fields = { ISAKMP: { "next_payload":10 }}
7980 ByteEnumField("next_payload",None,ISAKMP_payload_type),
7982 FieldLenField("length",None,"load","H", adjust=lambda pkt,x:x+4),
7983 StrLenField("load","",length_from=lambda x:x.length-4),
7986 class ISAKMP_payload_KE(ISAKMP_class):
7987 name = "ISAKMP Key Exchange"
7988 overload_fields = { ISAKMP: { "next_payload":4 }}
7990 ByteEnumField("next_payload",None,ISAKMP_payload_type),
7992 FieldLenField("length",None,"load","H", adjust=lambda pkt,x:x+4),
7993 StrLenField("load","",length_from=lambda x:x.length-4),
7996 class ISAKMP_payload_ID(ISAKMP_class):
7997 name = "ISAKMP Identification"
7998 overload_fields = { ISAKMP: { "next_payload":5 }}
8000 ByteEnumField("next_payload",None,ISAKMP_payload_type),
8002 FieldLenField("length",None,"load","H",adjust=lambda pkt,x:x+8),
8003 ByteEnumField("IDtype",1,{1:"IPv4_addr", 11:"Key"}),
8004 ByteEnumField("ProtoID",0,{0:"Unused"}),
8005 ShortEnumField("Port",0,{0:"Unused"}),
8006 # IPField("IdentData","127.0.0.1"),
8007 StrLenField("load","",length_from=lambda x:x.length-8),
8012 class ISAKMP_payload_Hash(ISAKMP_class):
8013 name = "ISAKMP Hash"
8014 overload_fields = { ISAKMP: { "next_payload":8 }}
8016 ByteEnumField("next_payload",None,ISAKMP_payload_type),
8018 FieldLenField("length",None,"load","H",adjust=lambda pkt,x:x+4),
8019 StrLenField("load","",length_from=lambda x:x.length-4),
8024 ISAKMP_payload_type_overload = {}
8025 for i in range(len(ISAKMP_payload_type)):
8026 name = "ISAKMP_payload_%s" % ISAKMP_payload_type[i]
8027 if name in globals():
8028 ISAKMP_payload_type_overload[globals()[name]] = {"next_payload":i}
8032 ISAKMP_class.overload_fields = ISAKMP_payload_type_overload.copy()
8037 # Cisco Skinny protocol
8039 # shamelessly ripped from Ethereal dissector
8041 # Station -> Callmanager
8042 0x0000: "KeepAliveMessage",
8043 0x0001: "RegisterMessage",
8044 0x0002: "IpPortMessage",
8045 0x0003: "KeypadButtonMessage",
8046 0x0004: "EnblocCallMessage",
8047 0x0005: "StimulusMessage",
8048 0x0006: "OffHookMessage",
8049 0x0007: "OnHookMessage",
8050 0x0008: "HookFlashMessage",
8051 0x0009: "ForwardStatReqMessage",
8052 0x000A: "SpeedDialStatReqMessage",
8053 0x000B: "LineStatReqMessage",
8054 0x000C: "ConfigStatReqMessage",
8055 0x000D: "TimeDateReqMessage",
8056 0x000E: "ButtonTemplateReqMessage",
8057 0x000F: "VersionReqMessage",
8058 0x0010: "CapabilitiesResMessage",
8059 0x0011: "MediaPortListMessage",
8060 0x0012: "ServerReqMessage",
8061 0x0020: "AlarmMessage",
8062 0x0021: "MulticastMediaReceptionAck",
8063 0x0022: "OpenReceiveChannelAck",
8064 0x0023: "ConnectionStatisticsRes",
8065 0x0024: "OffHookWithCgpnMessage",
8066 0x0025: "SoftKeySetReqMessage",
8067 0x0026: "SoftKeyEventMessage",
8068 0x0027: "UnregisterMessage",
8069 0x0028: "SoftKeyTemplateReqMessage",
8070 0x0029: "RegisterTokenReq",
8071 0x002A: "MediaTransmissionFailure",
8072 0x002B: "HeadsetStatusMessage",
8073 0x002C: "MediaResourceNotification",
8074 0x002D: "RegisterAvailableLinesMessage",
8075 0x002E: "DeviceToUserDataMessage",
8076 0x002F: "DeviceToUserDataResponseMessage",
8077 0x0030: "UpdateCapabilitiesMessage",
8078 0x0031: "OpenMultiMediaReceiveChannelAckMessage",
8079 0x0032: "ClearConferenceMessage",
8080 0x0033: "ServiceURLStatReqMessage",
8081 0x0034: "FeatureStatReqMessage",
8082 0x0035: "CreateConferenceResMessage",
8083 0x0036: "DeleteConferenceResMessage",
8084 0x0037: "ModifyConferenceResMessage",
8085 0x0038: "AddParticipantResMessage",
8086 0x0039: "AuditConferenceResMessage",
8087 0x0040: "AuditParticipantResMessage",
8088 0x0041: "DeviceToUserDataVersion1Message",
8089 # Callmanager -> Station */
8090 0x0081: "RegisterAckMessage",
8091 0x0082: "StartToneMessage",
8092 0x0083: "StopToneMessage",
8093 0x0085: "SetRingerMessage",
8094 0x0086: "SetLampMessage",
8095 0x0087: "SetHkFDetectMessage",
8096 0x0088: "SetSpeakerModeMessage",
8097 0x0089: "SetMicroModeMessage",
8098 0x008A: "StartMediaTransmission",
8099 0x008B: "StopMediaTransmission",
8100 0x008C: "StartMediaReception",
8101 0x008D: "StopMediaReception",
8102 0x008F: "CallInfoMessage",
8103 0x0090: "ForwardStatMessage",
8104 0x0091: "SpeedDialStatMessage",
8105 0x0092: "LineStatMessage",
8106 0x0093: "ConfigStatMessage",
8107 0x0094: "DefineTimeDate",
8108 0x0095: "StartSessionTransmission",
8109 0x0096: "StopSessionTransmission",
8110 0x0097: "ButtonTemplateMessage",
8111 0x0098: "VersionMessage",
8112 0x0099: "DisplayTextMessage",
8113 0x009A: "ClearDisplay",
8114 0x009B: "CapabilitiesReqMessage",
8115 0x009C: "EnunciatorCommandMessage",
8116 0x009D: "RegisterRejectMessage",
8117 0x009E: "ServerResMessage",
8119 0x0100: "KeepAliveAckMessage",
8120 0x0101: "StartMulticastMediaReception",
8121 0x0102: "StartMulticastMediaTransmission",
8122 0x0103: "StopMulticastMediaReception",
8123 0x0104: "StopMulticastMediaTransmission",
8124 0x0105: "OpenReceiveChannel",
8125 0x0106: "CloseReceiveChannel",
8126 0x0107: "ConnectionStatisticsReq",
8127 0x0108: "SoftKeyTemplateResMessage",
8128 0x0109: "SoftKeySetResMessage",
8129 0x0110: "SelectSoftKeysMessage",
8130 0x0111: "CallStateMessage",
8131 0x0112: "DisplayPromptStatusMessage",
8132 0x0113: "ClearPromptStatusMessage",
8133 0x0114: "DisplayNotifyMessage",
8134 0x0115: "ClearNotifyMessage",
8135 0x0116: "ActivateCallPlaneMessage",
8136 0x0117: "DeactivateCallPlaneMessage",
8137 0x0118: "UnregisterAckMessage",
8138 0x0119: "BackSpaceReqMessage",
8139 0x011A: "RegisterTokenAck",
8140 0x011B: "RegisterTokenReject",
8141 0x0042: "DeviceToUserDataResponseVersion1Message",
8142 0x011C: "StartMediaFailureDetection",
8143 0x011D: "DialedNumberMessage",
8144 0x011E: "UserToDeviceDataMessage",
8145 0x011F: "FeatureStatMessage",
8146 0x0120: "DisplayPriNotifyMessage",
8147 0x0121: "ClearPriNotifyMessage",
8148 0x0122: "StartAnnouncementMessage",
8149 0x0123: "StopAnnouncementMessage",
8150 0x0124: "AnnouncementFinishMessage",
8151 0x0127: "NotifyDtmfToneMessage",
8152 0x0128: "SendDtmfToneMessage",
8153 0x0129: "SubscribeDtmfPayloadReqMessage",
8154 0x012A: "SubscribeDtmfPayloadResMessage",
8155 0x012B: "SubscribeDtmfPayloadErrMessage",
8156 0x012C: "UnSubscribeDtmfPayloadReqMessage",
8157 0x012D: "UnSubscribeDtmfPayloadResMessage",
8158 0x012E: "UnSubscribeDtmfPayloadErrMessage",
8159 0x012F: "ServiceURLStatMessage",
8160 0x0130: "CallSelectStatMessage",
8161 0x0131: "OpenMultiMediaChannelMessage",
8162 0x0132: "StartMultiMediaTransmission",
8163 0x0133: "StopMultiMediaTransmission",
8164 0x0134: "MiscellaneousCommandMessage",
8165 0x0135: "FlowControlCommandMessage",
8166 0x0136: "CloseMultiMediaReceiveChannel",
8167 0x0137: "CreateConferenceReqMessage",
8168 0x0138: "DeleteConferenceReqMessage",
8169 0x0139: "ModifyConferenceReqMessage",
8170 0x013A: "AddParticipantReqMessage",
8171 0x013B: "DropParticipantReqMessage",
8172 0x013C: "AuditConferenceReqMessage",
8173 0x013D: "AuditParticipantReqMessage",
8174 0x013F: "UserToDeviceDataVersion1Message",
8179 class Skinny(Packet):
8181 fields_desc = [ LEIntField("len",0),
8182 LEIntField("res",0),
8183 LEIntEnumField("msg",0,skinny_messages) ]
8185 _rtp_payload_types = {
8186 # http://www.iana.org/assignments/rtp-parameters
8187 0: 'G.711 PCMU', 3: 'GSM',
8188 4: 'G723', 5: 'DVI4',
8189 6: 'DVI4', 7: 'LPC',
8190 8: 'PCMA', 9: 'G722',
8191 10: 'L16', 11: 'L16',
8192 12: 'QCELP', 13: 'CN',
8193 14: 'MPA', 15: 'G728',
8194 16: 'DVI4', 17: 'DVI4',
8195 18: 'G729', 25: 'CelB',
8196 26: 'JPEG', 28: 'nv',
8197 31: 'H261', 32: 'MPV',
8198 33: 'MP2T', 34: 'H263' }
8202 fields_desc = [ BitField('version', 2, 2),
8203 BitField('padding', 0, 1),
8204 BitField('extension', 0, 1),
8205 BitFieldLenField('numsync', None, 4, count_of='sync'),
8206 BitField('marker', 0, 1),
8207 BitEnumField('payload', 0, 7, _rtp_payload_types),
8208 ShortField('sequence', 0),
8209 IntField('timestamp', 0),
8210 IntField('sourcesync', 0),
8211 FieldListField('sync', [], IntField("id",0), count_from=lambda pkt:pkt.numsync) ]
8216 class SebekHead(Packet):
8217 name = "Sebek header"
8218 fields_desc = [ XIntField("magic", 0xd0d0d0),
8219 ShortField("version", 1),
8220 ShortEnumField("type", 0, {"read":0, "write":1,
8221 "socket":2, "open":3}),
8222 IntField("counter", 0),
8223 IntField("time_sec", 0),
8224 IntField("time_usec", 0) ]
8225 def mysummary(self):
8226 return self.sprintf("Sebek Header v%SebekHead.version% %SebekHead.type%")
8228 # we need this because Sebek headers differ between v1 and v3, and
8229 # between v3 type socket and v3 others
8231 class SebekV1(Packet):
8233 fields_desc = [ IntField("pid", 0),
8236 StrFixedLenField("command", "", 12),
8237 FieldLenField("data_length", None, "data",fmt="I"),
8238 StrLenField("data", "", length_from=lambda x:x.data_length) ]
8239 def mysummary(self):
8240 if isinstance(self.underlayer, SebekHead):
8241 return self.underlayer.sprintf("Sebek v1 %SebekHead.type% (%SebekV1.command%)")
8243 return self.sprintf("Sebek v1 (%SebekV1.command%)")
8245 class SebekV3(Packet):
8247 fields_desc = [ IntField("parent_pid", 0),
8251 IntField("inode", 0),
8252 StrFixedLenField("command", "", 12),
8253 FieldLenField("data_length", None, "data",fmt="I"),
8254 StrLenField("data", "", length_from=lambda x:x.data_length) ]
8255 def mysummary(self):
8256 if isinstance(self.underlayer, SebekHead):
8257 return self.underlayer.sprintf("Sebek v%SebekHead.version% %SebekHead.type% (%SebekV3.command%)")
8259 return self.sprintf("Sebek v3 (%SebekV3.command%)")
8261 class SebekV2(SebekV3):
8262 def mysummary(self):
8263 if isinstance(self.underlayer, SebekHead):
8264 return self.underlayer.sprintf("Sebek v%SebekHead.version% %SebekHead.type% (%SebekV2.command%)")
8266 return self.sprintf("Sebek v2 (%SebekV2.command%)")
8268 class SebekV3Sock(Packet):
8269 name = "Sebek v2 socket"
8270 fields_desc = [ IntField("parent_pid", 0),
8274 IntField("inode", 0),
8275 StrFixedLenField("command", "", 12),
8276 IntField("data_length", 15),
8277 IPField("dip", "127.0.0.1"),
8278 ShortField("dport", 0),
8279 IPField("sip", "127.0.0.1"),
8280 ShortField("sport", 0),
8281 ShortEnumField("call", 0, { "bind":2,
8282 "connect":3, "listen":4,
8283 "accept":5, "sendmsg":16,
8284 "recvmsg":17, "sendto":11,
8286 ByteEnumField("proto", 0, IP_PROTOS) ]
8287 def mysummary(self):
8288 if isinstance(self.underlayer, SebekHead):
8289 return self.underlayer.sprintf("Sebek v%SebekHead.version% %SebekHead.type% (%SebekV3Sock.command%)")
8291 return self.sprintf("Sebek v3 socket (%SebekV3Sock.command%)")
8293 class SebekV2Sock(SebekV3Sock):
8294 def mysummary(self):
8295 if isinstance(self.underlayer, SebekHead):
8296 return self.underlayer.sprintf("Sebek v%SebekHead.version% %SebekHead.type% (%SebekV2Sock.command%)")
8298 return self.sprintf("Sebek v2 socket (%SebekV2Sock.command%)")
8302 longname = "Media Gateway Control Protocol"
8303 fields_desc = [ StrStopField("verb","AUEP"," ", -1),
8304 StrFixedLenField("sep1"," ",1),
8305 StrStopField("transaction_id","1234567"," ", -1),
8306 StrFixedLenField("sep2"," ",1),
8307 StrStopField("endpoint","dummy@dummy.net"," ", -1),
8308 StrFixedLenField("sep3"," ",1),
8309 StrStopField("version","MGCP 1.0 NCS 1.0","\x0a", -1),
8310 StrFixedLenField("sep4","\x0a",1),
8314 #class MGCP(Packet):
8316 # longname = "Media Gateway Control Protocol"
8317 # fields_desc = [ ByteEnumField("type",0, ["request","response","others"]),
8318 # ByteField("code0",0),
8319 # ByteField("code1",0),
8320 # ByteField("code2",0),
8321 # ByteField("code3",0),
8322 # ByteField("code4",0),
8323 # IntField("trasid",0),
8324 # IntField("req_time",0),
8325 # ByteField("is_duplicate",0),
8326 # ByteField("req_available",0) ]
8331 StrStopField("dummy","","\x65\x00\x00",1)
8335 class HCI_Hdr(Packet):
8337 fields_desc = [ ByteEnumField("type",2,{1:"command",2:"ACLdata",3:"SCOdata",4:"event",5:"vendor"}),]
8339 def mysummary(self):
8340 return self.sprintf("HCI %type%")
8342 class HCI_ACL_Hdr(Packet):
8343 name = "HCI ACL header"
8344 fields_desc = [ ByteField("handle",0), # Actually, handle is 12 bits and flags is 4.
8345 ByteField("flags",0), # I wait to write a LEBitField
8346 LEShortField("len",None), ]
8347 def post_build(self, p, pay):
8349 if self.len is None:
8351 p = p[:2]+chr(l&0xff)+chr((l>>8)&0xff)+p[4:]
8355 class L2CAP_Hdr(Packet):
8356 name = "L2CAP header"
8357 fields_desc = [ LEShortField("len",None),
8358 LEShortEnumField("cid",0,{1:"control"}),]
8360 def post_build(self, p, pay):
8362 if self.len is None:
8364 p = p[:2]+chr(l&0xff)+chr((l>>8)&0xff)+p[4:]
8369 class L2CAP_CmdHdr(Packet):
8370 name = "L2CAP command header"
8372 ByteEnumField("code",8,{1:"rej",2:"conn_req",3:"conn_resp",
8373 4:"conf_req",5:"conf_resp",6:"disconn_req",
8374 7:"disconn_resp",8:"echo_req",9:"echo_resp",
8375 10:"info_req",11:"info_resp"}),
8377 LEShortField("len",None) ]
8378 def post_build(self, p, pay):
8380 if self.len is None:
8382 p = p[:2]+chr(l&0xff)+chr((l>>8)&0xff)+p[4:]
8384 def answers(self, other):
8385 if other.id == self.id:
8388 if other.code in [2,4,6,8,10] and self.code == other.code+1:
8391 return self.payload.answers(other.payload)
8394 class L2CAP_ConnReq(Packet):
8395 name = "L2CAP Conn Req"
8396 fields_desc = [ LEShortEnumField("psm",0,{1:"SDP",3:"RFCOMM",5:"telephony control"}),
8397 LEShortField("scid",0),
8400 class L2CAP_ConnResp(Packet):
8401 name = "L2CAP Conn Resp"
8402 fields_desc = [ LEShortField("dcid",0),
8403 LEShortField("scid",0),
8404 LEShortEnumField("result",0,["no_info","authen_pend","author_pend"]),
8405 LEShortEnumField("status",0,["success","pend","bad_psm",
8406 "cr_sec_block","cr_no_mem"]),
8408 def answers(self, other):
8409 return self.scid == other.scid
8411 class L2CAP_CmdRej(Packet):
8412 name = "L2CAP Command Rej"
8413 fields_desc = [ LEShortField("reason",0),
8417 class L2CAP_ConfReq(Packet):
8418 name = "L2CAP Conf Req"
8419 fields_desc = [ LEShortField("dcid",0),
8420 LEShortField("flags",0),
8423 class L2CAP_ConfResp(Packet):
8424 name = "L2CAP Conf Resp"
8425 fields_desc = [ LEShortField("scid",0),
8426 LEShortField("flags",0),
8427 LEShortEnumField("result",0,["success","unaccept","reject","unknown"]),
8429 def answers(self, other):
8430 return self.scid == other.scid
8433 class L2CAP_DisconnReq(Packet):
8434 name = "L2CAP Disconn Req"
8435 fields_desc = [ LEShortField("dcid",0),
8436 LEShortField("scid",0), ]
8438 class L2CAP_DisconnResp(Packet):
8439 name = "L2CAP Disconn Resp"
8440 fields_desc = [ LEShortField("dcid",0),
8441 LEShortField("scid",0), ]
8442 def answers(self, other):
8443 return self.scid == other.scid
8447 class L2CAP_InfoReq(Packet):
8448 name = "L2CAP Info Req"
8449 fields_desc = [ LEShortEnumField("type",0,{1:"CL_MTU",2:"FEAT_MASK"}),
8454 class L2CAP_InfoResp(Packet):
8455 name = "L2CAP Info Resp"
8456 fields_desc = [ LEShortField("type",0),
8457 LEShortEnumField("result",0,["success","not_supp"]),
8458 StrField("data",""), ]
8459 def answers(self, other):
8460 return self.type == other.type
8465 class NetBIOS_DS(Packet):
8466 name = "NetBIOS datagram service"
8468 ByteEnumField("type",17, {17:"direct_group"}),
8469 ByteField("flags",0),
8470 XShortField("id",0),
8471 IPField("src","127.0.0.1"),
8472 ShortField("sport",138),
8473 ShortField("len",None),
8474 ShortField("ofs",0),
8475 NetBIOSNameField("srcname",""),
8476 NetBIOSNameField("dstname",""),
8478 def post_build(self, p, pay):
8480 if self.len is None:
8482 p = p[:10]+struct.pack("!H", l)+p[12:]
8485 # ShortField("length",0),
8486 # ShortField("Delimitor",0),
8487 # ByteField("command",0),
8488 # ByteField("data1",0),
8489 # ShortField("data2",0),
8490 # ShortField("XMIt",0),
8491 # ShortField("RSPCor",0),
8492 # StrFixedLenField("dest","",16),
8493 # StrFixedLenField("source","",16),
8500 class IrLAPHead(Packet):
8501 name = "IrDA Link Access Protocol Header"
8502 fields_desc = [ XBitField("Address", 0x7f, 7),
8503 BitEnumField("Type", 1, 1, {"Response":0,
8506 class IrLAPCommand(Packet):
8507 name = "IrDA Link Access Protocol Command"
8508 fields_desc = [ XByteField("Control", 0),
8509 XByteField("Format identifier", 0),
8510 XIntField("Source address", 0),
8511 XIntField("Destination address", 0xffffffffL),
8512 XByteField("Discovery flags", 0x1),
8513 ByteEnumField("Slot number", 255, {"final":255}),
8514 XByteField("Version", 0)]
8517 class IrLMP(Packet):
8518 name = "IrDA Link Management Protocol"
8519 fields_desc = [ XShortField("Service hints", 0),
8520 XByteField("Character set", 0),
8521 StrField("Device name", "") ]
8527 # Name Query Request
8528 # Node Status Request
8529 class NBNSQueryRequest(Packet):
8530 name="NBNS query request"
8531 fields_desc = [ShortField("NAME_TRN_ID",0),
8532 ShortField("FLAGS", 0x0110),
8533 ShortField("QDCOUNT",1),
8534 ShortField("ANCOUNT",0),
8535 ShortField("NSCOUNT",0),
8536 ShortField("ARCOUNT",0),
8537 NetBIOSNameField("QUESTION_NAME","windows"),
8538 ShortEnumField("SUFFIX",0x4141,{0x4141:"workstation",0x4141+0x03:"messenger service",0x4141+0x200:"file server service",0x4141+0x10b:"domain master browser",0x4141+0x10c:"domain controller", 0x4141+0x10e:"browser election service"}),
8539 ByteField("NULL",0),
8540 ShortEnumField("QUESTION_TYPE",0x20, {0x20:"NB",0x21:"NBSTAT"}),
8541 ShortEnumField("QUESTION_CLASS",1,{1:"INTERNET"})]
8543 # Name Registration Request
8544 # Name Refresh Request
8545 # Name Release Request or Demand
8546 class NBNSRequest(Packet):
8548 fields_desc = [ShortField("NAME_TRN_ID",0),
8549 ShortField("FLAGS", 0x2910),
8550 ShortField("QDCOUNT",1),
8551 ShortField("ANCOUNT",0),
8552 ShortField("NSCOUNT",0),
8553 ShortField("ARCOUNT",1),
8554 NetBIOSNameField("QUESTION_NAME","windows"),
8555 ShortEnumField("SUFFIX",0x4141,{0x4141:"workstation",0x4141+0x03:"messenger service",0x4141+0x200:"file server service",0x4141+0x10b:"domain master browser",0x4141+0x10c:"domain controller", 0x4141+0x10e:"browser election service"}),
8556 ByteField("NULL",0),
8557 ShortEnumField("QUESTION_TYPE",0x20, {0x20:"NB",0x21:"NBSTAT"}),
8558 ShortEnumField("QUESTION_CLASS",1,{1:"INTERNET"}),
8559 ShortEnumField("RR_NAME",0xC00C,{0xC00C:"Label String Pointer to QUESTION_NAME"}),
8560 ShortEnumField("RR_TYPE",0x20, {0x20:"NB",0x21:"NBSTAT"}),
8561 ShortEnumField("RR_CLASS",1,{1:"INTERNET"}),
8563 ShortField("RDLENGTH", 6),
8564 BitEnumField("G",0,1,{0:"Unique name",1:"Group name"}),
8565 BitEnumField("OWNER NODE TYPE",00,2,{00:"B node",01:"P node",02:"M node",03:"H node"}),
8566 BitEnumField("UNUSED",0,13,{0:"Unused"}),
8567 IPField("NB_ADDRESS", "127.0.0.1")]
8569 # Name Query Response
8570 # Name Registration Response
8571 class NBNSQueryResponse(Packet):
8572 name="NBNS query response"
8573 fields_desc = [ShortField("NAME_TRN_ID",0),
8574 ShortField("FLAGS", 0x8500),
8575 ShortField("QDCOUNT",0),
8576 ShortField("ANCOUNT",1),
8577 ShortField("NSCOUNT",0),
8578 ShortField("ARCOUNT",0),
8579 NetBIOSNameField("RR_NAME","windows"),
8580 ShortEnumField("SUFFIX",0x4141,{0x4141:"workstation",0x4141+0x03:"messenger service",0x4141+0x200:"file server service",0x4141+0x10b:"domain master browser",0x4141+0x10c:"domain controller", 0x4141+0x10e:"browser election service"}),
8581 ByteField("NULL",0),
8582 ShortEnumField("QUESTION_TYPE",0x20, {0x20:"NB",0x21:"NBSTAT"}),
8583 ShortEnumField("QUESTION_CLASS",1,{1:"INTERNET"}),
8584 IntField("TTL", 0x493e0),
8585 ShortField("RDLENGTH", 6),
8586 ShortField("NB_FLAGS", 0),
8587 IPField("NB_ADDRESS", "127.0.0.1")]
8589 # Name Query Response (negative)
8590 # Name Release Response
8591 class NBNSQueryResponseNegative(Packet):
8592 name="NBNS query response (negative)"
8593 fields_desc = [ShortField("NAME_TRN_ID",0),
8594 ShortField("FLAGS", 0x8506),
8595 ShortField("QDCOUNT",0),
8596 ShortField("ANCOUNT",1),
8597 ShortField("NSCOUNT",0),
8598 ShortField("ARCOUNT",0),
8599 NetBIOSNameField("RR_NAME","windows"),
8600 ShortEnumField("SUFFIX",0x4141,{0x4141:"workstation",0x4141+0x03:"messenger service",0x4141+0x200:"file server service",0x4141+0x10b:"domain master browser",0x4141+0x10c:"domain controller", 0x4141+0x10e:"browser election service"}),
8601 ByteField("NULL",0),
8602 ShortEnumField("RR_TYPE",0x20, {0x20:"NB",0x21:"NBSTAT"}),
8603 ShortEnumField("RR_CLASS",1,{1:"INTERNET"}),
8605 ShortField("RDLENGTH",6),
8606 BitEnumField("G",0,1,{0:"Unique name",1:"Group name"}),
8607 BitEnumField("OWNER NODE TYPE",00,2,{00:"B node",01:"P node",02:"M node",03:"H node"}),
8608 BitEnumField("UNUSED",0,13,{0:"Unused"}),
8609 IPField("NB_ADDRESS", "127.0.0.1")]
8611 # Node Status Response
8612 class NBNSNodeStatusResponse(Packet):
8613 name="NBNS Node Status Response"
8614 fields_desc = [ShortField("NAME_TRN_ID",0),
8615 ShortField("FLAGS", 0x8500),
8616 ShortField("QDCOUNT",0),
8617 ShortField("ANCOUNT",1),
8618 ShortField("NSCOUNT",0),
8619 ShortField("ARCOUNT",0),
8620 NetBIOSNameField("RR_NAME","windows"),
8621 ShortEnumField("SUFFIX",0x4141,{0x4141:"workstation",0x4141+0x03:"messenger service",0x4141+0x200:"file server service",0x4141+0x10b:"domain master browser",0x4141+0x10c:"domain controller", 0x4141+0x10e:"browser election service"}),
8622 ByteField("NULL",0),
8623 ShortEnumField("RR_TYPE",0x21, {0x20:"NB",0x21:"NBSTAT"}),
8624 ShortEnumField("RR_CLASS",1,{1:"INTERNET"}),
8626 ShortField("RDLENGTH",83),
8627 ByteField("NUM_NAMES",1)]
8629 # Service for Node Status Response
8630 class NBNSNodeStatusResponseService(Packet):
8631 name="NBNS Node Status Response Service"
8632 fields_desc = [StrFixedLenField("NETBIOS_NAME","WINDOWS ",15),
8633 ByteEnumField("SUFFIX",0,{0:"workstation",0x03:"messenger service",0x20:"file server service",0x1b:"domain master browser",0x1c:"domain controller", 0x1e:"browser election service"}),
8634 ByteField("NAME_FLAGS",0x4),
8635 ByteEnumField("UNUSED",0,{0:"unused"})]
8637 # End of Node Status Response packet
8638 class NBNSNodeStatusResponseEnd(Packet):
8639 name="NBNS Node Status Response"
8640 fields_desc = [SourceMACField("MAC_ADDRESS"),
8641 BitField("STATISTICS",0,57*8)]
8643 # Wait for Acknowledgement Response
8644 class NBNSWackResponse(Packet):
8645 name="NBNS Wait for Acknowledgement Response"
8646 fields_desc = [ShortField("NAME_TRN_ID",0),
8647 ShortField("FLAGS", 0xBC07),
8648 ShortField("QDCOUNT",0),
8649 ShortField("ANCOUNT",1),
8650 ShortField("NSCOUNT",0),
8651 ShortField("ARCOUNT",0),
8652 NetBIOSNameField("RR_NAME","windows"),
8653 ShortEnumField("SUFFIX",0x4141,{0x4141:"workstation",0x4141+0x03:"messenger service",0x4141+0x200:"file server service",0x4141+0x10b:"domain master browser",0x4141+0x10c:"domain controller", 0x4141+0x10e:"browser election service"}),
8654 ByteField("NULL",0),
8655 ShortEnumField("RR_TYPE",0x20, {0x20:"NB",0x21:"NBSTAT"}),
8656 ShortEnumField("RR_CLASS",1,{1:"INTERNET"}),
8658 ShortField("RDLENGTH",2),
8659 BitField("RDATA",10512,16)] #10512=0010100100010000
8661 class NBTDatagram(Packet):
8662 name="NBT Datagram Packet"
8663 fields_desc= [ByteField("Type", 0x10),
8664 ByteField("Flags", 0x02),
8665 ShortField("ID", 0),
8666 IPField("SourceIP", "127.0.0.1"),
8667 ShortField("SourcePort", 138),
8668 ShortField("Length", 272),
8669 ShortField("Offset", 0),
8670 NetBIOSNameField("SourceName","windows"),
8671 ShortEnumField("SUFFIX1",0x4141,{0x4141:"workstation",0x4141+0x03:"messenger service",0x4141+0x200:"file server service",0x4141+0x10b:"domain master browser",0x4141+0x10c:"domain controller", 0x4141+0x10e:"browser election service"}),
8672 ByteField("NULL",0),
8673 NetBIOSNameField("DestinationName","windows"),
8674 ShortEnumField("SUFFIX2",0x4141,{0x4141:"workstation",0x4141+0x03:"messenger service",0x4141+0x200:"file server service",0x4141+0x10b:"domain master browser",0x4141+0x10c:"domain controller", 0x4141+0x10e:"browser election service"}),
8675 ByteField("NULL",0)]
8678 class NBTSession(Packet):
8679 name="NBT Session Packet"
8680 fields_desc= [ByteEnumField("TYPE",0,{0x00:"Session Message",0x81:"Session Request",0x82:"Positive Session Response",0x83:"Negative Session Response",0x84:"Retarget Session Response",0x85:"Session Keepalive"}),
8681 BitField("RESERVED",0x00,7),
8682 BitField("LENGTH",0,17)]
8685 # SMB NetLogon Response Header
8686 class SMBNetlogon_Protocol_Response_Header(Packet):
8687 name="SMBNetlogon Protocol Response Header"
8688 fields_desc = [StrFixedLenField("Start","\xffSMB",4),
8689 ByteEnumField("Command",0x25,{0x25:"Trans"}),
8690 ByteField("Error_Class",0x02),
8691 ByteField("Reserved",0),
8692 LEShortField("Error_code",4),
8693 ByteField("Flags",0),
8694 LEShortField("Flags2",0x0000),
8695 LEShortField("PIDHigh",0x0000),
8696 LELongField("Signature",0x0),
8697 LEShortField("Unused",0x0),
8698 LEShortField("TID",0),
8699 LEShortField("PID",0),
8700 LEShortField("UID",0),
8701 LEShortField("MID",0),
8702 ByteField("WordCount",17),
8703 LEShortField("TotalParamCount",0),
8704 LEShortField("TotalDataCount",112),
8705 LEShortField("MaxParamCount",0),
8706 LEShortField("MaxDataCount",0),
8707 ByteField("MaxSetupCount",0),
8708 ByteField("unused2",0),
8709 LEShortField("Flags3",0),
8710 ByteField("TimeOut1",0xe8),
8711 ByteField("TimeOut2",0x03),
8712 LEShortField("unused3",0),
8713 LEShortField("unused4",0),
8714 LEShortField("ParamCount2",0),
8715 LEShortField("ParamOffset",0),
8716 LEShortField("DataCount",112),
8717 LEShortField("DataOffset",92),
8718 ByteField("SetupCount", 3),
8719 ByteField("unused5", 0)]
8721 # SMB MailSlot Protocol
8722 class SMBMailSlot(Packet):
8723 name = "SMB Mail Slot Protocol"
8724 fields_desc = [LEShortField("opcode", 1),
8725 LEShortField("priority", 1),
8726 LEShortField("class", 2),
8727 LEShortField("size", 135),
8728 StrNullField("name","\MAILSLOT\NET\GETDC660")]
8730 # SMB NetLogon Protocol Response Tail SAM
8731 class SMBNetlogon_Protocol_Response_Tail_SAM(Packet):
8732 name = "SMB Netlogon Protocol Response Tail SAM"
8733 fields_desc = [ByteEnumField("Command", 0x17, {0x12:"SAM logon request", 0x17:"SAM Active directory Response"}),
8734 ByteField("unused", 0),
8735 ShortField("Data1", 0),
8736 ShortField("Data2", 0xfd01),
8737 ShortField("Data3", 0),
8738 ShortField("Data4", 0xacde),
8739 ShortField("Data5", 0x0fe5),
8740 ShortField("Data6", 0xd10a),
8741 ShortField("Data7", 0x374c),
8742 ShortField("Data8", 0x83e2),
8743 ShortField("Data9", 0x7dd9),
8744 ShortField("Data10", 0x3a16),
8745 ShortField("Data11", 0x73ff),
8746 ByteField("Data12", 0x04),
8747 StrFixedLenField("Data13", "rmff", 4),
8748 ByteField("Data14", 0x0),
8749 ShortField("Data16", 0xc018),
8750 ByteField("Data18", 0x0a),
8751 StrFixedLenField("Data20", "rmff-win2k", 10),
8752 ByteField("Data21", 0xc0),
8753 ShortField("Data22", 0x18c0),
8754 ShortField("Data23", 0x180a),
8755 StrFixedLenField("Data24", "RMFF-WIN2K", 10),
8756 ShortField("Data25", 0),
8757 ByteField("Data26", 0x17),
8758 StrFixedLenField("Data27", "Default-First-Site-Name", 23),
8759 ShortField("Data28", 0x00c0),
8760 ShortField("Data29", 0x3c10),
8761 ShortField("Data30", 0x00c0),
8762 ShortField("Data31", 0x0200),
8763 ShortField("Data32", 0x0),
8764 ShortField("Data33", 0xac14),
8765 ShortField("Data34", 0x0064),
8766 ShortField("Data35", 0x0),
8767 ShortField("Data36", 0x0),
8768 ShortField("Data37", 0x0),
8769 ShortField("Data38", 0x0),
8770 ShortField("Data39", 0x0d00),
8771 ShortField("Data40", 0x0),
8772 ShortField("Data41", 0xffff)]
8774 # SMB NetLogon Protocol Response Tail LM2.0
8775 class SMBNetlogon_Protocol_Response_Tail_LM20(Packet):
8776 name = "SMB Netlogon Protocol Response Tail LM20"
8777 fields_desc = [ByteEnumField("Command",0x06,{0x06:"LM 2.0 Response to logon request"}),
8778 ByteField("unused", 0),
8779 StrFixedLenField("DblSlash", "\\\\", 2),
8780 StrNullField("ServerName","WIN"),
8781 LEShortField("LM20Token", 0xffff)]
8783 # SMBNegociate Protocol Request Header
8784 class SMBNegociate_Protocol_Request_Header(Packet):
8785 name="SMBNegociate Protocol Request Header"
8786 fields_desc = [StrFixedLenField("Start","\xffSMB",4),
8787 ByteEnumField("Command",0x72,{0x72:"SMB_COM_NEGOTIATE"}),
8788 ByteField("Error_Class",0),
8789 ByteField("Reserved",0),
8790 LEShortField("Error_code",0),
8791 ByteField("Flags",0x18),
8792 LEShortField("Flags2",0x0000),
8793 LEShortField("PIDHigh",0x0000),
8794 LELongField("Signature",0x0),
8795 LEShortField("Unused",0x0),
8796 LEShortField("TID",0),
8797 LEShortField("PID",1),
8798 LEShortField("UID",0),
8799 LEShortField("MID",2),
8800 ByteField("WordCount",0),
8801 LEShortField("ByteCount",12)]
8803 # SMB Negociate Protocol Request Tail
8804 class SMBNegociate_Protocol_Request_Tail(Packet):
8805 name="SMB Negociate Protocol Request Tail"
8806 fields_desc=[ByteField("BufferFormat",0x02),
8807 StrNullField("BufferData","NT LM 0.12")]
8809 # SMBNegociate Protocol Response Advanced Security
8810 class SMBNegociate_Protocol_Response_Advanced_Security(Packet):
8811 name="SMBNegociate Protocol Response Advanced Security"
8812 fields_desc = [StrFixedLenField("Start","\xffSMB",4),
8813 ByteEnumField("Command",0x72,{0x72:"SMB_COM_NEGOTIATE"}),
8814 ByteField("Error_Class",0),
8815 ByteField("Reserved",0),
8816 LEShortField("Error_Code",0),
8817 ByteField("Flags",0x98),
8818 LEShortField("Flags2",0x0000),
8819 LEShortField("PIDHigh",0x0000),
8820 LELongField("Signature",0x0),
8821 LEShortField("Unused",0x0),
8822 LEShortField("TID",0),
8823 LEShortField("PID",1),
8824 LEShortField("UID",0),
8825 LEShortField("MID",2),
8826 ByteField("WordCount",17),
8827 LEShortField("DialectIndex",7),
8828 ByteField("SecurityMode",0x03),
8829 LEShortField("MaxMpxCount",50),
8830 LEShortField("MaxNumberVC",1),
8831 LEIntField("MaxBufferSize",16144),
8832 LEIntField("MaxRawSize",65536),
8833 LEIntField("SessionKey",0x0000),
8834 LEShortField("ServerCapabilities",0xf3f9),
8835 BitField("UnixExtensions",0,1),
8836 BitField("Reserved2",0,7),
8837 BitField("ExtendedSecurity",1,1),
8838 BitField("CompBulk",0,2),
8839 BitField("Reserved3",0,5),
8840 # There have been 127490112000000000 tenths of micro-seconds between 1st january 1601 and 1st january 2005. 127490112000000000=0x1C4EF94D6228000, so ServerTimeHigh=0xD6228000 and ServerTimeLow=0x1C4EF94.
8841 LEIntField("ServerTimeHigh",0xD6228000L),
8842 LEIntField("ServerTimeLow",0x1C4EF94),
8843 LEShortField("ServerTimeZone",0x3c),
8844 ByteField("EncryptionKeyLength",0),
8845 LEFieldLenField("ByteCount", None, "SecurityBlob", adjust=lambda pkt,x:x-16),
8846 BitField("GUID",0,128),
8847 StrLenField("SecurityBlob", "", length_from=lambda x:x.ByteCount+16)]
8849 # SMBNegociate Protocol Response No Security
8850 # When using no security, with EncryptionKeyLength=8, you must have an EncryptionKey before the DomainName
8851 class SMBNegociate_Protocol_Response_No_Security(Packet):
8852 name="SMBNegociate Protocol Response No Security"
8853 fields_desc = [StrFixedLenField("Start","\xffSMB",4),
8854 ByteEnumField("Command",0x72,{0x72:"SMB_COM_NEGOTIATE"}),
8855 ByteField("Error_Class",0),
8856 ByteField("Reserved",0),
8857 LEShortField("Error_Code",0),
8858 ByteField("Flags",0x98),
8859 LEShortField("Flags2",0x0000),
8860 LEShortField("PIDHigh",0x0000),
8861 LELongField("Signature",0x0),
8862 LEShortField("Unused",0x0),
8863 LEShortField("TID",0),
8864 LEShortField("PID",1),
8865 LEShortField("UID",0),
8866 LEShortField("MID",2),
8867 ByteField("WordCount",17),
8868 LEShortField("DialectIndex",7),
8869 ByteField("SecurityMode",0x03),
8870 LEShortField("MaxMpxCount",50),
8871 LEShortField("MaxNumberVC",1),
8872 LEIntField("MaxBufferSize",16144),
8873 LEIntField("MaxRawSize",65536),
8874 LEIntField("SessionKey",0x0000),
8875 LEShortField("ServerCapabilities",0xf3f9),
8876 BitField("UnixExtensions",0,1),
8877 BitField("Reserved2",0,7),
8878 BitField("ExtendedSecurity",0,1),
8879 FlagsField("CompBulk",0,2,"CB"),
8880 BitField("Reserved3",0,5),
8881 # There have been 127490112000000000 tenths of micro-seconds between 1st january 1601 and 1st january 2005. 127490112000000000=0x1C4EF94D6228000, so ServerTimeHigh=0xD6228000 and ServerTimeLow=0x1C4EF94.
8882 LEIntField("ServerTimeHigh",0xD6228000L),
8883 LEIntField("ServerTimeLow",0x1C4EF94),
8884 LEShortField("ServerTimeZone",0x3c),
8885 ByteField("EncryptionKeyLength",8),
8886 LEShortField("ByteCount",24),
8887 BitField("EncryptionKey",0,64),
8888 StrNullField("DomainName","WORKGROUP"),
8889 StrNullField("ServerName","RMFF1")]
8891 # SMBNegociate Protocol Response No Security No Key
8892 class SMBNegociate_Protocol_Response_No_Security_No_Key(Packet):
8893 namez="SMBNegociate Protocol Response No Security No Key"
8894 fields_desc = [StrFixedLenField("Start","\xffSMB",4),
8895 ByteEnumField("Command",0x72,{0x72:"SMB_COM_NEGOTIATE"}),
8896 ByteField("Error_Class",0),
8897 ByteField("Reserved",0),
8898 LEShortField("Error_Code",0),
8899 ByteField("Flags",0x98),
8900 LEShortField("Flags2",0x0000),
8901 LEShortField("PIDHigh",0x0000),
8902 LELongField("Signature",0x0),
8903 LEShortField("Unused",0x0),
8904 LEShortField("TID",0),
8905 LEShortField("PID",1),
8906 LEShortField("UID",0),
8907 LEShortField("MID",2),
8908 ByteField("WordCount",17),
8909 LEShortField("DialectIndex",7),
8910 ByteField("SecurityMode",0x03),
8911 LEShortField("MaxMpxCount",50),
8912 LEShortField("MaxNumberVC",1),
8913 LEIntField("MaxBufferSize",16144),
8914 LEIntField("MaxRawSize",65536),
8915 LEIntField("SessionKey",0x0000),
8916 LEShortField("ServerCapabilities",0xf3f9),
8917 BitField("UnixExtensions",0,1),
8918 BitField("Reserved2",0,7),
8919 BitField("ExtendedSecurity",0,1),
8920 FlagsField("CompBulk",0,2,"CB"),
8921 BitField("Reserved3",0,5),
8922 # There have been 127490112000000000 tenths of micro-seconds between 1st january 1601 and 1st january 2005. 127490112000000000=0x1C4EF94D6228000, so ServerTimeHigh=0xD6228000 and ServerTimeLow=0x1C4EF94.
8923 LEIntField("ServerTimeHigh",0xD6228000L),
8924 LEIntField("ServerTimeLow",0x1C4EF94),
8925 LEShortField("ServerTimeZone",0x3c),
8926 ByteField("EncryptionKeyLength",0),
8927 LEShortField("ByteCount",16),
8928 StrNullField("DomainName","WORKGROUP"),
8929 StrNullField("ServerName","RMFF1")]
8931 # Session Setup AndX Request
8932 class SMBSession_Setup_AndX_Request(Packet):
8933 name="Session Setup AndX Request"
8934 fields_desc=[StrFixedLenField("Start","\xffSMB",4),
8935 ByteEnumField("Command",0x73,{0x73:"SMB_COM_SESSION_SETUP_ANDX"}),
8936 ByteField("Error_Class",0),
8937 ByteField("Reserved",0),
8938 LEShortField("Error_Code",0),
8939 ByteField("Flags",0x18),
8940 LEShortField("Flags2",0x0001),
8941 LEShortField("PIDHigh",0x0000),
8942 LELongField("Signature",0x0),
8943 LEShortField("Unused",0x0),
8944 LEShortField("TID",0),
8945 LEShortField("PID",1),
8946 LEShortField("UID",0),
8947 LEShortField("MID",2),
8948 ByteField("WordCount",13),
8949 ByteEnumField("AndXCommand",0x75,{0x75:"SMB_COM_TREE_CONNECT_ANDX"}),
8950 ByteField("Reserved2",0),
8951 LEShortField("AndXOffset",96),
8952 LEShortField("MaxBufferS",2920),
8953 LEShortField("MaxMPXCount",50),
8954 LEShortField("VCNumber",0),
8955 LEIntField("SessionKey",0),
8956 LEFieldLenField("ANSIPasswordLength",None,"ANSIPassword"),
8957 LEShortField("UnicodePasswordLength",0),
8958 LEIntField("Reserved3",0),
8959 LEShortField("ServerCapabilities",0x05),
8960 BitField("UnixExtensions",0,1),
8961 BitField("Reserved4",0,7),
8962 BitField("ExtendedSecurity",0,1),
8963 BitField("CompBulk",0,2),
8964 BitField("Reserved5",0,5),
8965 LEShortField("ByteCount",35),
8966 StrLenField("ANSIPassword", "Pass",length_from=lambda x:x.ANSIPasswordLength),
8967 StrNullField("Account","GUEST"),
8968 StrNullField("PrimaryDomain", ""),
8969 StrNullField("NativeOS","Windows 4.0"),
8970 StrNullField("NativeLanManager","Windows 4.0"),
8971 ByteField("WordCount2",4),
8972 ByteEnumField("AndXCommand2",0xFF,{0xFF:"SMB_COM_NONE"}),
8973 ByteField("Reserved6",0),
8974 LEShortField("AndXOffset2",0),
8975 LEShortField("Flags3",0x2),
8976 LEShortField("PasswordLength",0x1),
8977 LEShortField("ByteCount2",18),
8978 ByteField("Password",0),
8979 StrNullField("Path","\\\\WIN2K\\IPC$"),
8980 StrNullField("Service","IPC")]
8982 # Session Setup AndX Response
8983 class SMBSession_Setup_AndX_Response(Packet):
8984 name="Session Setup AndX Response"
8985 fields_desc=[StrFixedLenField("Start","\xffSMB",4),
8986 ByteEnumField("Command",0x73,{0x73:"SMB_COM_SESSION_SETUP_ANDX"}),
8987 ByteField("Error_Class",0),
8988 ByteField("Reserved",0),
8989 LEShortField("Error_Code",0),
8990 ByteField("Flags",0x90),
8991 LEShortField("Flags2",0x1001),
8992 LEShortField("PIDHigh",0x0000),
8993 LELongField("Signature",0x0),
8994 LEShortField("Unused",0x0),
8995 LEShortField("TID",0),
8996 LEShortField("PID",1),
8997 LEShortField("UID",0),
8998 LEShortField("MID",2),
8999 ByteField("WordCount",3),
9000 ByteEnumField("AndXCommand",0x75,{0x75:"SMB_COM_TREE_CONNECT_ANDX"}),
9001 ByteField("Reserved2",0),
9002 LEShortField("AndXOffset",66),
9003 LEShortField("Action",0),
9004 LEShortField("ByteCount",25),
9005 StrNullField("NativeOS","Windows 4.0"),
9006 StrNullField("NativeLanManager","Windows 4.0"),
9007 StrNullField("PrimaryDomain",""),
9008 ByteField("WordCount2",3),
9009 ByteEnumField("AndXCommand2",0xFF,{0xFF:"SMB_COM_NONE"}),
9010 ByteField("Reserved3",0),
9011 LEShortField("AndXOffset2",80),
9012 LEShortField("OptionalSupport",0x01),
9013 LEShortField("ByteCount2",5),
9014 StrNullField("Service","IPC"),
9015 StrNullField("NativeFileSystem","")]
9017 class MobileIP(Packet):
9018 name = "Mobile IP (RFC3344)"
9019 fields_desc = [ ByteEnumField("type", 1, {1:"RRQ", 3:"RRP"}) ]
9021 class MobileIPRRQ(Packet):
9022 name = "Mobile IP Registration Request (RFC3344)"
9023 fields_desc = [ XByteField("flags", 0),
9024 ShortField("lifetime", 180),
9025 IPField("homeaddr", "0.0.0.0"),
9026 IPField("haaddr", "0.0.0.0"),
9027 IPField("coaddr", "0.0.0.0"),
9028 Field("id", "", "64s") ]
9030 class MobileIPRRP(Packet):
9031 name = "Mobile IP Registration Reply (RFC3344)"
9032 fields_desc = [ ByteField("code", 0),
9033 ShortField("lifetime", 180),
9034 IPField("homeaddr", "0.0.0.0"),
9035 IPField("haaddr", "0.0.0.0"),
9036 Field("id", "", "64s") ]
9038 class MobileIPTunnelData(Packet):
9039 name = "Mobile IP Tunnel Data Message (RFC3519)"
9040 fields_desc = [ ByteField("nexthdr", 4),
9041 ShortField("res", 0) ]
9044 # Cisco Netflow Protocol version 1
9045 class NetflowHeader(Packet):
9046 name = "Netflow Header"
9047 fields_desc = [ ShortField("version", 1) ]
9049 class NetflowHeaderV1(Packet):
9050 name = "Netflow Header V1"
9051 fields_desc = [ ShortField("count", 0),
9052 IntField("sysUptime", 0),
9053 IntField("unixSecs", 0),
9054 IntField("unixNanoSeconds", 0) ]
9057 class NetflowRecordV1(Packet):
9058 name = "Netflow Record"
9059 fields_desc = [ IPField("ipsrc", "0.0.0.0"),
9060 IPField("ipdst", "0.0.0.0"),
9061 IPField("nexthop", "0.0.0.0"),
9062 ShortField("inputIfIndex", 0),
9063 ShortField("outpuIfIndex", 0),
9064 IntField("dpkts", 0),
9065 IntField("dbytes", 0),
9066 IntField("starttime", 0),
9067 IntField("endtime", 0),
9068 ShortField("srcport", 0),
9069 ShortField("dstport", 0),
9070 ShortField("padding", 0),
9071 ByteField("proto", 0),
9072 ByteField("tos", 0),
9073 IntField("padding1", 0),
9074 IntField("padding2", 0) ]
9077 TFTP_operations = { 1:"RRQ",2:"WRQ",3:"DATA",4:"ACK",5:"ERROR",6:"OACK" }
9081 name = "TFTP opcode"
9082 fields_desc = [ ShortEnumField("op", 1, TFTP_operations), ]
9086 class TFTP_RRQ(Packet):
9087 name = "TFTP Read Request"
9088 fields_desc = [ StrNullField("filename", ""),
9089 StrNullField("mode", "octet") ]
9090 def answers(self, other):
9092 def mysummary(self):
9093 return self.sprintf("RRQ %filename%"),[UDP]
9096 class TFTP_WRQ(Packet):
9097 name = "TFTP Write Request"
9098 fields_desc = [ StrNullField("filename", ""),
9099 StrNullField("mode", "octet") ]
9100 def answers(self, other):
9102 def mysummary(self):
9103 return self.sprintf("WRQ %filename%"),[UDP]
9105 class TFTP_DATA(Packet):
9107 fields_desc = [ ShortField("block", 0) ]
9108 def answers(self, other):
9109 return self.block == 1 and isinstance(other, TFTP_RRQ)
9110 def mysummary(self):
9111 return self.sprintf("DATA %block%"),[UDP]
9113 class TFTP_Option(Packet):
9114 fields_desc = [ StrNullField("oname",""),
9115 StrNullField("value","") ]
9116 def extract_padding(self, pkt):
9119 class TFTP_Options(Packet):
9120 fields_desc = [ PacketListField("options", [], TFTP_Option, length_from=lambda x:None) ]
9123 class TFTP_ACK(Packet):
9125 fields_desc = [ ShortField("block", 0) ]
9126 def answers(self, other):
9127 if isinstance(other, TFTP_DATA):
9128 return self.block == other.block
9129 elif isinstance(other, TFTP_RRQ) or isinstance(other, TFTP_WRQ) or isinstance(other, TFTP_OACK):
9130 return self.block == 0
9132 def mysummary(self):
9133 return self.sprintf("ACK %block%"),[UDP]
9135 TFTP_Error_Codes = { 0: "Not defined",
9136 1: "File not found",
9137 2: "Access violation",
9138 3: "Disk full or allocation exceeded",
9139 4: "Illegal TFTP operation",
9140 5: "Unknown transfer ID",
9141 6: "File already exists",
9143 8: "Terminate transfer due to option negotiation",
9146 class TFTP_ERROR(Packet):
9148 fields_desc = [ ShortEnumField("errorcode", 0, TFTP_Error_Codes),
9149 StrNullField("errormsg", "")]
9150 def answers(self, other):
9151 return (isinstance(other, TFTP_DATA) or
9152 isinstance(other, TFTP_RRQ) or
9153 isinstance(other, TFTP_WRQ) or
9154 isinstance(other, TFTP_ACK))
9155 def mysummary(self):
9156 return self.sprintf("ERROR %errorcode%: %errormsg%"),[UDP]
9159 class TFTP_OACK(Packet):
9160 name = "TFTP Option Ack"
9162 def answers(self, other):
9163 return isinstance(other, TFTP_WRQ) or isinstance(other, TFTP_RRQ)
9170 ######[ ASN1 class ]######
9172 class ASN1_Class_SNMP(ASN1_Class_UNIVERSAL):
9184 class ASN1_SNMP_PDU_GET(ASN1_SEQUENCE):
9185 tag = ASN1_Class_SNMP.PDU_GET
9187 class ASN1_SNMP_PDU_NEXT(ASN1_SEQUENCE):
9188 tag = ASN1_Class_SNMP.PDU_NEXT
9190 class ASN1_SNMP_PDU_RESPONSE(ASN1_SEQUENCE):
9191 tag = ASN1_Class_SNMP.PDU_RESPONSE
9193 class ASN1_SNMP_PDU_SET(ASN1_SEQUENCE):
9194 tag = ASN1_Class_SNMP.PDU_SET
9196 class ASN1_SNMP_PDU_TRAPv1(ASN1_SEQUENCE):
9197 tag = ASN1_Class_SNMP.PDU_TRAPv1
9199 class ASN1_SNMP_PDU_BULK(ASN1_SEQUENCE):
9200 tag = ASN1_Class_SNMP.PDU_BULK
9202 class ASN1_SNMP_PDU_INFORM(ASN1_SEQUENCE):
9203 tag = ASN1_Class_SNMP.PDU_INFORM
9205 class ASN1_SNMP_PDU_TRAPv2(ASN1_SEQUENCE):
9206 tag = ASN1_Class_SNMP.PDU_TRAPv2
9209 ######[ BER codecs ]#######
9211 class BERcodec_SNMP_PDU_GET(BERcodec_SEQUENCE):
9212 tag = ASN1_Class_SNMP.PDU_GET
9214 class BERcodec_SNMP_PDU_NEXT(BERcodec_SEQUENCE):
9215 tag = ASN1_Class_SNMP.PDU_NEXT
9217 class BERcodec_SNMP_PDU_RESPONSE(BERcodec_SEQUENCE):
9218 tag = ASN1_Class_SNMP.PDU_RESPONSE
9220 class BERcodec_SNMP_PDU_SET(BERcodec_SEQUENCE):
9221 tag = ASN1_Class_SNMP.PDU_SET
9223 class BERcodec_SNMP_PDU_TRAPv1(BERcodec_SEQUENCE):
9224 tag = ASN1_Class_SNMP.PDU_TRAPv1
9226 class BERcodec_SNMP_PDU_BULK(BERcodec_SEQUENCE):
9227 tag = ASN1_Class_SNMP.PDU_BULK
9229 class BERcodec_SNMP_PDU_INFORM(BERcodec_SEQUENCE):
9230 tag = ASN1_Class_SNMP.PDU_INFORM
9232 class BERcodec_SNMP_PDU_TRAPv2(BERcodec_SEQUENCE):
9233 tag = ASN1_Class_SNMP.PDU_TRAPv2
9237 ######[ ASN1 fields ]######
9239 class ASN1F_SNMP_PDU_GET(ASN1F_SEQUENCE):
9240 ASN1_tag = ASN1_Class_SNMP.PDU_GET
9242 class ASN1F_SNMP_PDU_NEXT(ASN1F_SEQUENCE):
9243 ASN1_tag = ASN1_Class_SNMP.PDU_NEXT
9245 class ASN1F_SNMP_PDU_RESPONSE(ASN1F_SEQUENCE):
9246 ASN1_tag = ASN1_Class_SNMP.PDU_RESPONSE
9248 class ASN1F_SNMP_PDU_SET(ASN1F_SEQUENCE):
9249 ASN1_tag = ASN1_Class_SNMP.PDU_SET
9251 class ASN1F_SNMP_PDU_TRAPv1(ASN1F_SEQUENCE):
9252 ASN1_tag = ASN1_Class_SNMP.PDU_TRAPv1
9254 class ASN1F_SNMP_PDU_BULK(ASN1F_SEQUENCE):
9255 ASN1_tag = ASN1_Class_SNMP.PDU_BULK
9257 class ASN1F_SNMP_PDU_INFORM(ASN1F_SEQUENCE):
9258 ASN1_tag = ASN1_Class_SNMP.PDU_INFORM
9260 class ASN1F_SNMP_PDU_TRAPv2(ASN1F_SEQUENCE):
9261 ASN1_tag = ASN1_Class_SNMP.PDU_TRAPv2
9265 ######[ SNMP Packet ]######
9267 SNMP_error = { 0: "no_error",
9276 9: "wrong_encoding",
9279 12: "inconsistent_value",
9280 13: "ressource_unavailable",
9281 14: "commit_failed",
9283 16: "authorization_error",
9285 18: "inconsistent_name",
9288 SNMP_trap_types = { 0: "cold_start",
9293 5: "egp_neigh_loss",
9294 6: "enterprise_specific",
9297 class SNMPvarbind(ASN1_Packet):
9298 ASN1_codec = ASN1_Codecs.BER
9299 ASN1_root = ASN1F_SEQUENCE( ASN1F_OID("oid","1.3"),
9300 ASN1F_field("value",ASN1_NULL(0))
9304 class SNMPget(ASN1_Packet):
9305 ASN1_codec = ASN1_Codecs.BER
9306 ASN1_root = ASN1F_SNMP_PDU_GET( ASN1F_INTEGER("id",0),
9307 ASN1F_enum_INTEGER("error",0, SNMP_error),
9308 ASN1F_INTEGER("error_index",0),
9309 ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind)
9312 class SNMPnext(ASN1_Packet):
9313 ASN1_codec = ASN1_Codecs.BER
9314 ASN1_root = ASN1F_SNMP_PDU_NEXT( ASN1F_INTEGER("id",0),
9315 ASN1F_enum_INTEGER("error",0, SNMP_error),
9316 ASN1F_INTEGER("error_index",0),
9317 ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind)
9320 class SNMPresponse(ASN1_Packet):
9321 ASN1_codec = ASN1_Codecs.BER
9322 ASN1_root = ASN1F_SNMP_PDU_RESPONSE( ASN1F_INTEGER("id",0),
9323 ASN1F_enum_INTEGER("error",0, SNMP_error),
9324 ASN1F_INTEGER("error_index",0),
9325 ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind)
9328 class SNMPset(ASN1_Packet):
9329 ASN1_codec = ASN1_Codecs.BER
9330 ASN1_root = ASN1F_SNMP_PDU_SET( ASN1F_INTEGER("id",0),
9331 ASN1F_enum_INTEGER("error",0, SNMP_error),
9332 ASN1F_INTEGER("error_index",0),
9333 ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind)
9336 class SNMPtrapv1(ASN1_Packet):
9337 ASN1_codec = ASN1_Codecs.BER
9338 ASN1_root = ASN1F_SNMP_PDU_TRAPv1( ASN1F_INTEGER("id",0),
9339 ASN1F_OID("enterprise", "1.3"),
9340 ASN1F_STRING("agent_addr",""),
9341 ASN1F_enum_INTEGER("generic_trap", 0, SNMP_trap_types),
9342 ASN1F_INTEGER("specific_trap", 0),
9343 ASN1F_INTEGER("time_stamp", IntAutoTime()),
9344 ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind)
9347 class SNMPbulk(ASN1_Packet):
9348 ASN1_codec = ASN1_Codecs.BER
9349 ASN1_root = ASN1F_SNMP_PDU_BULK( ASN1F_INTEGER("id",0),
9350 ASN1F_INTEGER("non_repeaters",0),
9351 ASN1F_INTEGER("max_repetitions",0),
9352 ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind)
9355 class SNMPinform(ASN1_Packet):
9356 ASN1_codec = ASN1_Codecs.BER
9357 ASN1_root = ASN1F_SNMP_PDU_INFORM( ASN1F_INTEGER("id",0),
9358 ASN1F_enum_INTEGER("error",0, SNMP_error),
9359 ASN1F_INTEGER("error_index",0),
9360 ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind)
9363 class SNMPtrapv2(ASN1_Packet):
9364 ASN1_codec = ASN1_Codecs.BER
9365 ASN1_root = ASN1F_SNMP_PDU_TRAPv2( ASN1F_INTEGER("id",0),
9366 ASN1F_enum_INTEGER("error",0, SNMP_error),
9367 ASN1F_INTEGER("error_index",0),
9368 ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind)
9372 class SNMP(ASN1_Packet):
9373 ASN1_codec = ASN1_Codecs.BER
9374 ASN1_root = ASN1F_SEQUENCE(
9375 ASN1F_enum_INTEGER("version", 1, {0:"v1", 1:"v2c", 2:"v2", 3:"v3"}),
9376 ASN1F_STRING("community","public"),
9377 ASN1F_CHOICE("PDU", SNMPget(),
9378 SNMPget, SNMPnext, SNMPresponse, SNMPset,
9379 SNMPtrapv1, SNMPbulk, SNMPinform, SNMPtrapv2)
9381 def answers(self, other):
9382 return ( isinstance(self.PDU, SNMPresponse) and
9383 ( isinstance(other.PDU, SNMPget) or
9384 isinstance(other.PDU, SNMPnext) or
9385 isinstance(other.PDU, SNMPset) ) and
9386 self.PDU.id == other.PDU.id )
9393 ######[ ASN1 class ]######
9395 class ASN1_Class_X509(ASN1_Class_UNIVERSAL):
9402 class ASN1_X509_CONT0(ASN1_SEQUENCE):
9403 tag = ASN1_Class_X509.CONT0
9405 class ASN1_X509_CONT1(ASN1_SEQUENCE):
9406 tag = ASN1_Class_X509.CONT1
9408 class ASN1_X509_CONT2(ASN1_SEQUENCE):
9409 tag = ASN1_Class_X509.CONT2
9411 class ASN1_X509_CONT3(ASN1_SEQUENCE):
9412 tag = ASN1_Class_X509.CONT3
9414 ######[ BER codecs ]#######
9416 class BERcodec_X509_CONT0(BERcodec_SEQUENCE):
9417 tag = ASN1_Class_X509.CONT0
9419 class BERcodec_X509_CONT1(BERcodec_SEQUENCE):
9420 tag = ASN1_Class_X509.CONT1
9422 class BERcodec_X509_CONT2(BERcodec_SEQUENCE):
9423 tag = ASN1_Class_X509.CONT2
9425 class BERcodec_X509_CONT3(BERcodec_SEQUENCE):
9426 tag = ASN1_Class_X509.CONT3
9428 ######[ ASN1 fields ]######
9430 class ASN1F_X509_CONT0(ASN1F_SEQUENCE):
9431 ASN1_tag = ASN1_Class_X509.CONT0
9433 class ASN1F_X509_CONT1(ASN1F_SEQUENCE):
9434 ASN1_tag = ASN1_Class_X509.CONT1
9436 class ASN1F_X509_CONT2(ASN1F_SEQUENCE):
9437 ASN1_tag = ASN1_Class_X509.CONT2
9439 class ASN1F_X509_CONT3(ASN1F_SEQUENCE):
9440 ASN1_tag = ASN1_Class_X509.CONT3
9442 ######[ X509 packets ]######
9444 class X509RDN(ASN1_Packet):
9445 ASN1_codec = ASN1_Codecs.BER
9446 ASN1_root = ASN1F_SET(
9447 ASN1F_SEQUENCE( ASN1F_OID("oid","2.5.4.6"),
9448 ASN1F_PRINTABLE_STRING("value","")
9452 class X509v3Ext(ASN1_Packet):
9453 ASN1_codec = ASN1_Codecs.BER
9454 ASN1_root = ASN1F_field("val",ASN1_NULL(0))
9457 class X509Cert(ASN1_Packet):
9458 ASN1_codec = ASN1_Codecs.BER
9459 ASN1_root = ASN1F_SEQUENCE(
9461 ASN1F_optionnal(ASN1F_X509_CONT0(ASN1F_INTEGER("version",3))),
9462 ASN1F_INTEGER("sn",1),
9463 ASN1F_SEQUENCE(ASN1F_OID("sign_algo","1.2.840.113549.1.1.5"),
9464 ASN1F_field("sa_value",ASN1_NULL(0))),
9465 ASN1F_SEQUENCE_OF("issuer",[],X509RDN),
9466 ASN1F_SEQUENCE(ASN1F_UTC_TIME("not_before",ZuluTime(-600)), # ten minutes ago
9467 ASN1F_UTC_TIME("not_after",ZuluTime(+86400))), # for 24h
9468 ASN1F_SEQUENCE_OF("subject",[],X509RDN),
9470 ASN1F_SEQUENCE(ASN1F_OID("pubkey_algo","1.2.840.113549.1.1.1"),
9471 ASN1F_field("pk_value",ASN1_NULL(0))),
9472 ASN1F_BIT_STRING("pubkey","")
9474 ASN1F_optionnal(ASN1F_X509_CONT3(ASN1F_SEQUENCE_OF("x509v3ext",[],X509v3Ext))),
9477 ASN1F_SEQUENCE(ASN1F_OID("sign_algo2","1.2.840.113549.1.1.5"),
9478 ASN1F_field("sa2_value",ASN1_NULL(0))),
9479 ASN1F_BIT_STRING("signature","")
9490 def bind_bottom_up(lower, upper, __fval=None, **fval):
9491 if __fval is not None:
9493 lower.payload_guess = lower.payload_guess[:]
9494 lower.payload_guess.append((fval, upper))
9497 def bind_top_down(lower, upper, __fval=None, **fval):
9498 if __fval is not None:
9500 upper.overload_fields = upper.overload_fields.copy()
9501 upper.overload_fields[lower] = fval
9503 def bind_layers(lower, upper, __fval=None, **fval):
9504 if __fval is not None:
9506 bind_top_down(lower, upper, **fval)
9507 bind_bottom_up(lower, upper, **fval)
9509 def split_bottom_up(lower, upper, __fval=None, **fval):
9510 if __fval is not None:
9512 def do_filter((f,u),upper=upper,fval=fval):
9516 if k not in f or f[k] != fval[k]:
9519 lower.payload_guess = filter(do_filter, lower.payload_guess)
9521 def split_top_down(lower, upper, __fval=None, **fval):
9522 if __fval is not None:
9524 if lower in upper.overload_fields:
9525 ofval = upper.overload_fields[lower]
9527 if k not in ofval or ofval[k] != fval[k]:
9529 upper.overload_fields = upper.overload_fields.copy()
9530 del(upper.overload_fields[lower])
9532 def split_layers(lower, upper, __fval=None, **fval):
9533 if __fval is not None:
9535 split_bottom_up(lower, upper, **fval)
9536 split_top_down(lower, upper, **fval)
9539 bind_layers( Dot3, LLC, )
9540 bind_layers( GPRS, IP, )
9541 bind_layers( PrismHeader, Dot11, )
9542 bind_layers( RadioTap, Dot11, )
9543 bind_layers( Dot11, LLC, type=2)
9544 bind_layers( Dot11QoS, LLC, )
9545 bind_layers( L2TP, PPP, )
9546 bind_layers( HDLC, PPP, )
9547 bind_layers( PPP, IP, proto=33)
9548 bind_layers( PPP, PPP_IPCP, proto=0x8021)
9549 bind_layers( PPP, PPP_ECP, proto=0x8053)
9550 bind_layers( Ether, LLC, type=122)
9551 bind_layers( Ether, Dot1Q, type=33024)
9552 bind_layers( Ether, Ether, type=1)
9553 bind_layers( Ether, ARP, type=2054)
9554 bind_layers( Ether, IP, type=2048)
9555 bind_layers( Ether, EAPOL, type=34958)
9556 bind_layers( Ether, EAPOL, dst='01:80:c2:00:00:03', type=34958)
9557 bind_layers( Ether, PPPoED, type=34915)
9558 bind_layers( Ether, PPPoE, type=34916)
9559 bind_layers( CookedLinux, LLC, proto=122)
9560 bind_layers( CookedLinux, Dot1Q, proto=33024)
9561 bind_layers( CookedLinux, Ether, proto=1)
9562 bind_layers( CookedLinux, ARP, proto=2054)
9563 bind_layers( CookedLinux, IP, proto=2048)
9564 bind_layers( CookedLinux, EAPOL, proto=34958)
9565 bind_layers( CookedLinux, PPPoED, proto=34915)
9566 bind_layers( CookedLinux, PPPoE, proto=34916)
9567 bind_layers( GRE, LLC, proto=122)
9568 bind_layers( GRE, Dot1Q, proto=33024)
9569 bind_layers( GRE, Ether, proto=1)
9570 bind_layers( GRE, ARP, proto=2054)
9571 bind_layers( GRE, IP, proto=2048)
9572 bind_layers( GRE, EAPOL, proto=34958)
9573 bind_layers( PPPoE, PPP, code=0)
9574 bind_layers( EAPOL, EAP, type=0)
9575 bind_layers( LLC, STP, dsap=66, ssap=66, ctrl=3)
9576 bind_layers( LLC, SNAP, dsap=170, ssap=170, ctrl=3)
9577 bind_layers( SNAP, Dot1Q, code=33024)
9578 bind_layers( SNAP, Ether, code=1)
9579 bind_layers( SNAP, ARP, code=2054)
9580 bind_layers( SNAP, IP, code=2048)
9581 bind_layers( SNAP, EAPOL, code=34958)
9582 bind_layers( SNAP, STP, code=267)
9583 bind_layers( IPerror, IPerror, frag=0, proto=4)
9584 bind_layers( IPerror, ICMPerror, frag=0, proto=1)
9585 bind_layers( IPerror, TCPerror, frag=0, proto=6)
9586 bind_layers( IPerror, UDPerror, frag=0, proto=17)
9587 bind_layers( IP, IP, frag=0, proto=4)
9588 bind_layers( IP, ICMP, frag=0, proto=1)
9589 bind_layers( IP, TCP, frag=0, proto=6)
9590 bind_layers( IP, UDP, frag=0, proto=17)
9591 bind_layers( IP, GRE, frag=0, proto=47)
9592 bind_layers( UDP, L2TP, sport=1701, dport=1701)
9593 bind_layers( UDP, SNMP, sport=161)
9594 bind_layers( UDP, SNMP, dport=161)
9595 bind_layers( UDP, MGCP, dport=2727)
9596 bind_layers( UDP, MGCP, sport=2727)
9597 bind_layers( UDP, DNS, dport=53)
9598 bind_layers( UDP, DNS, sport=53)
9599 bind_layers( UDP, ISAKMP, dport=500, sport=500)
9600 bind_layers( UDP, HSRP, dport=1985, sport=1985)
9601 bind_layers( UDP, NTP, dport=123, sport=123)
9602 bind_layers( UDP, BOOTP, dport=67, sport=68)
9603 bind_layers( UDP, BOOTP, dport=68, sport=67)
9604 bind_layers( BOOTP, DHCP, options='c\x82Sc')
9605 bind_layers( UDP, RIP, sport=520)
9606 bind_layers( UDP, RIP, dport=520)
9607 bind_layers( RIP, RIPEntry, )
9608 bind_layers( RIPEntry, RIPEntry, )
9609 bind_layers( Dot11, Dot11AssoReq, subtype=0, type=0)
9610 bind_layers( Dot11, Dot11AssoResp, subtype=1, type=0)
9611 bind_layers( Dot11, Dot11ReassoReq, subtype=2, type=0)
9612 bind_layers( Dot11, Dot11ReassoResp, subtype=3, type=0)
9613 bind_layers( Dot11, Dot11ProbeReq, subtype=4, type=0)
9614 bind_layers( Dot11, Dot11ProbeResp, subtype=5, type=0)
9615 bind_layers( Dot11, Dot11Beacon, subtype=8, type=0)
9616 bind_layers( Dot11, Dot11ATIM, subtype=9, type=0)
9617 bind_layers( Dot11, Dot11Disas, subtype=10, type=0)
9618 bind_layers( Dot11, Dot11Auth, subtype=11, type=0)
9619 bind_layers( Dot11, Dot11Deauth, subtype=12, type=0)
9620 bind_layers( Dot11Beacon, Dot11Elt, )
9621 bind_layers( Dot11AssoReq, Dot11Elt, )
9622 bind_layers( Dot11AssoResp, Dot11Elt, )
9623 bind_layers( Dot11ReassoReq, Dot11Elt, )
9624 bind_layers( Dot11ReassoResp, Dot11Elt, )
9625 bind_layers( Dot11ProbeReq, Dot11Elt, )
9626 bind_layers( Dot11ProbeResp, Dot11Elt, )
9627 bind_layers( Dot11Auth, Dot11Elt, )
9628 bind_layers( Dot11Elt, Dot11Elt, )
9629 bind_layers( TCP, Skinny, dport=2000)
9630 bind_layers( TCP, Skinny, sport=2000)
9631 bind_layers( UDP, SebekHead, sport=1101)
9632 bind_layers( UDP, SebekHead, dport=1101)
9633 bind_layers( UDP, SebekHead, dport=1101, sport=1101)
9634 bind_layers( SebekHead, SebekV1, version=1)
9635 bind_layers( SebekHead, SebekV2Sock, version=2, type=2)
9636 bind_layers( SebekHead, SebekV2, version=2)
9637 bind_layers( SebekHead, SebekV3Sock, version=3, type=2)
9638 bind_layers( SebekHead, SebekV3, version=3)
9639 bind_layers( CookedLinux, IrLAPHead, proto=23)
9640 bind_layers( IrLAPHead, IrLAPCommand, Type=1)
9641 bind_layers( IrLAPCommand, IrLMP, )
9642 bind_layers( UDP, NBNSQueryRequest, dport=137)
9643 bind_layers( UDP, NBNSRequest, dport=137)
9644 bind_layers( UDP, NBNSQueryResponse, sport=137)
9645 bind_layers( UDP, NBNSQueryResponseNegative, sport=137)
9646 bind_layers( UDP, NBNSNodeStatusResponse, sport=137)
9647 bind_layers( NBNSNodeStatusResponse, NBNSNodeStatusResponseService, )
9648 bind_layers( NBNSNodeStatusResponse, NBNSNodeStatusResponseService, )
9649 bind_layers( NBNSNodeStatusResponseService, NBNSNodeStatusResponseService, )
9650 bind_layers( NBNSNodeStatusResponseService, NBNSNodeStatusResponseEnd, )
9651 bind_layers( UDP, NBNSWackResponse, sport=137)
9652 bind_layers( UDP, NBTDatagram, dport=138)
9653 bind_layers( TCP, NBTSession, dport=139)
9654 bind_layers( NBTSession, SMBNegociate_Protocol_Request_Header, )
9655 bind_layers( SMBNegociate_Protocol_Request_Header, SMBNegociate_Protocol_Request_Tail, )
9656 bind_layers( SMBNegociate_Protocol_Request_Tail, SMBNegociate_Protocol_Request_Tail, )
9657 bind_layers( NBTSession, SMBNegociate_Protocol_Response_Advanced_Security, ExtendedSecurity=1)
9658 bind_layers( NBTSession, SMBNegociate_Protocol_Response_No_Security, ExtendedSecurity=0, EncryptionKeyLength=8)
9659 bind_layers( NBTSession, SMBNegociate_Protocol_Response_No_Security_No_Key, ExtendedSecurity=0, EncryptionKeyLength=0)
9660 bind_layers( NBTSession, SMBSession_Setup_AndX_Request, )
9661 bind_layers( NBTSession, SMBSession_Setup_AndX_Response, )
9662 bind_layers( HCI_Hdr, HCI_ACL_Hdr, type=2)
9663 bind_layers( HCI_Hdr, Raw, )
9664 bind_layers( HCI_ACL_Hdr, L2CAP_Hdr, )
9665 bind_layers( L2CAP_Hdr, L2CAP_CmdHdr, cid=1)
9666 bind_layers( L2CAP_CmdHdr, L2CAP_CmdRej, code=1)
9667 bind_layers( L2CAP_CmdHdr, L2CAP_ConnReq, code=2)
9668 bind_layers( L2CAP_CmdHdr, L2CAP_ConnResp, code=3)
9669 bind_layers( L2CAP_CmdHdr, L2CAP_ConfReq, code=4)
9670 bind_layers( L2CAP_CmdHdr, L2CAP_ConfResp, code=5)
9671 bind_layers( L2CAP_CmdHdr, L2CAP_DisconnReq, code=6)
9672 bind_layers( L2CAP_CmdHdr, L2CAP_DisconnResp, code=7)
9673 bind_layers( L2CAP_CmdHdr, L2CAP_InfoReq, code=10)
9674 bind_layers( L2CAP_CmdHdr, L2CAP_InfoResp, code=11)
9675 bind_layers( UDP, MobileIP, sport=434)
9676 bind_layers( UDP, MobileIP, dport=434)
9677 bind_layers( MobileIP, MobileIPRRQ, type=1)
9678 bind_layers( MobileIP, MobileIPRRP, type=3)
9679 bind_layers( MobileIP, MobileIPTunnelData, type=4)
9680 bind_layers( MobileIPTunnelData, IP, nexthdr=4)
9681 bind_layers( NetflowHeader, NetflowHeaderV1, version=1)
9682 bind_layers( NetflowHeaderV1, NetflowRecordV1, )
9684 bind_layers(UDP, TFTP, dport=69)
9685 bind_layers(TFTP, TFTP_RRQ, op=1)
9686 bind_layers(TFTP, TFTP_WRQ, op=2)
9687 bind_layers(TFTP, TFTP_DATA, op=3)
9688 bind_layers(TFTP, TFTP_ACK, op=4)
9689 bind_layers(TFTP, TFTP_ERROR, op=5)
9690 bind_layers(TFTP, TFTP_OACK, op=6)
9691 bind_layers(TFTP_RRQ, TFTP_Options)
9692 bind_layers(TFTP_WRQ, TFTP_Options)
9693 bind_layers(TFTP_OACK, TFTP_Options)
9700 def fragment(pkt, fragsize=1480):
9701 fragsize = (fragsize+7)/8*8
9704 s = str(p[IP].payload)
9705 nb = (len(s)+fragsize-1)/fragsize
9715 q[IP].frag = i*fragsize/8
9716 r = Raw(load=s[i*fragsize:(i+1)*fragsize])
9717 r.overload_fields = p[IP].payload.overload_fields.copy()
9722 def overlap_frag(p, overlap, fragsize=8, overlap_fragsize=None):
9723 if overlap_fragsize is None:
9724 overlap_fragsize = fragsize
9727 q[IP].add_payload(overlap)
9729 qfrag = fragment(q, overlap_fragsize)
9730 qfrag[-1][IP].flags |= 1
9731 return qfrag+fragment(p, fragsize)
9734 """defrag(plist) -> ([not fragmented], [defragmented],
9735 [ [bad fragments], [bad fragments], ... ])"""
9737 nofrag = PacketList()
9743 if ip.frag == 0 and ip.flags & 1 == 0:
9746 uniq = (ip.id,ip.src,ip.dst,ip.proto)
9748 frags[uniq].append(p)
9750 frags[uniq] = PacketList([p])
9753 for lst in frags.itervalues():
9754 lst.sort(lambda x,y:cmp(x.frag, y.frag))
9757 missfrag.append(lst)
9761 del(p[Padding].underlayer.payload)
9763 if ip.len is None or ip.ihl is None:
9764 clen = len(ip.payload)
9766 clen = ip.len - (ip.ihl<<2)
9769 if clen != q.frag<<3:
9770 if clen > q.frag<<3:
9771 warning("Fragment overlap (%i > %i) %r || %r || %r" % (clen, q.frag<<3, p,txt,q))
9772 missfrag.append(lst)
9775 if q[IP].len is None or q[IP].ihl is None:
9776 clen += len(q[IP].payload)
9778 clen += q[IP].len - (q[IP].ihl<<2)
9780 del(q[Padding].underlayer.payload)
9781 txt.add_payload(q[IP].payload.copy())
9786 ip.flags &= ~1 # !MF
9791 defrag2=PacketList()
9793 defrag2.append(p.__class__(str(p)))
9794 return nofrag,defrag2,missfrag
9796 def defragment(plist):
9797 """defrag(plist) -> plist defragmented as much as possible """
9807 if ip.frag != 0 or ip.flags & 1:
9809 uniq = (ip.id,ip.src,ip.dst,ip.proto)
9811 frags[uniq].append(p)
9819 for lst in frags.itervalues():
9820 lst.sort(lambda x,y:cmp(x.frag, y.frag))
9827 del(p[Padding].underlayer.payload)
9829 if ip.len is None or ip.ihl is None:
9830 clen = len(ip.payload)
9832 clen = ip.len - (ip.ihl<<2)
9835 if clen != q.frag<<3:
9836 if clen > q.frag<<3:
9837 warning("Fragment overlap (%i > %i) %r || %r || %r" % (clen, q.frag<<3, p,txt,q))
9841 if q[IP].len is None or q[IP].ihl is None:
9842 clen += len(q[IP].payload)
9844 clen += q[IP].len - (q[IP].ihl<<2)
9846 del(q[Padding].underlayer.payload)
9847 txt.add_payload(q[IP].payload.copy())
9852 ip.flags &= ~1 # !MF
9856 p._defrag_pos = lst[-1]._defrag_pos
9860 q = p.__class__(str(p))
9861 q._defrag_pos = p._defrag_pos
9865 final.sort(lambda x,y: cmp(x._defrag_pos, y._defrag_pos))
9869 if hasattr(plist, "listname"):
9870 name = "Defragmented %s" % plist.listname
9872 name = "Defragmented"
9875 return PacketList(final, name=name)
9886 def Ether_Dot3_Dispatcher(pkt=None, **kargs):
9887 if type(pkt) is str and len(pkt) >= 14 and struct.unpack("!H", pkt[12:14])[0] <= 1500:
9888 return Dot3(pkt, **kargs)
9889 return Ether(pkt, **kargs)
9891 # According to libdnet
9892 LLTypes = { ARPHDR_ETHER : Ether_Dot3_Dispatcher,
9893 ARPHDR_METRICOM : Ether_Dot3_Dispatcher,
9894 ARPHDR_LOOPBACK : Ether_Dot3_Dispatcher,
9903 119 : PrismHeader, # for atheros
9905 144 : CookedLinux, # called LINUX_IRDA, similar to CookedLinux
9907 0xB1E70073L : HCI_Hdr, # I invented this one
9910 LLNumTypes = { Ether : ARPHDR_ETHER,
9924 L3Types = { ETH_P_IP : IP,
9931 if type(fd) is not int:
9934 r,w,e = select([fd],[],[],0)
9942 def __init__(self, family=socket.AF_INET,type=socket.SOCK_STREAM, proto=0):
9943 self.ins = socket.socket(family, type, proto)
9944 self.outs = self.ins
9948 x.sent_time = time.time()
9949 return self.outs.send(sx)
9951 return Raw(self.ins.recv(x))
9953 return self.ins.fileno()
9958 if self.ins != self.outs:
9959 if self.outs and self.outs.fileno() != -1:
9961 if self.ins and self.ins.fileno() != -1:
9963 def bind_in(self, addr):
9965 def bind_out(self, addr):
9966 self.outs.bind(addr)
9969 class L3RawSocket(SuperSocket):
9970 def __init__(self, type = ETH_P_IP, filter=None, iface=None, promisc=None, nofilter=0):
9971 self.outs = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_RAW)
9972 self.outs.setsockopt(socket.SOL_IP, socket.IP_HDRINCL, 1)
9973 self.ins = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(type))
9975 return Ether(self.ins.recv(x)).payload
9979 x.sent_time = time.time()
9980 self.outs.sendto(sx,(x.dst,0))
9981 except socket.error,msg:
9982 log_runtime.error(msg)
9986 class L3PacketSocket(SuperSocket):
9987 def __init__(self, type = ETH_P_ALL, filter=None, promisc=None, iface=None, nofilter=0):
9989 self.ins = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(type))
9990 self.ins.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 0)
9993 self.ins.bind((iface, type))
9995 if conf.except_filter:
9997 filter = "(%s) and not (%s)" % (filter, conf.except_filter)
9999 filter = "not (%s)" % conf.except_filter
10000 if filter is not None:
10001 attach_filter(self.ins, filter)
10002 self.ins.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 2**30)
10003 self.outs = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(type))
10004 self.outs.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 2**30)
10005 if promisc is None:
10006 promisc = conf.promisc
10007 self.promisc = promisc
10010 self.iff = get_if_list()
10012 if iface.__class__ is list:
10017 set_promisc(self.ins, i)
10024 set_promisc(self.ins, i, 0)
10025 SuperSocket.close(self)
10027 pkt, sa_ll = self.ins.recvfrom(x)
10028 if sa_ll[2] == socket.PACKET_OUTGOING:
10030 if LLTypes.has_key(sa_ll[3]):
10031 cls = LLTypes[sa_ll[3]]
10033 elif L3Types.has_key(sa_ll[1]):
10034 cls = L3Types[sa_ll[1]]
10037 warning("Unable to guess type (interface=%s protocol=%#x family=%i). Using Ethernet" % (sa_ll[0],sa_ll[1],sa_ll[3]))
10043 except KeyboardInterrupt:
10046 if conf.debug_dissector:
10052 if pkt is not None:
10053 pkt.time = get_last_packet_timestamp(self.ins)
10057 if isinstance(x, IPv6):
10058 iff,a,gw = conf.route6.route(x.dst)
10059 elif hasattr(x,"dst"):
10060 iff,a,gw = conf.route.route(x.dst)
10063 sdto = (iff, self.type)
10064 self.outs.bind(sdto)
10065 sn = self.outs.getsockname()
10067 if sn[3] in (ARPHDR_PPP,ARPHDR_TUN):
10068 sdto = (iff, ETH_P_IP)
10069 if LLTypes.has_key(sn[3]):
10070 ll = lambda x:LLTypes[sn[3]]()/x
10073 x.sent_time = time.time()
10074 self.outs.sendto(sx, sdto)
10075 except socket.error,msg:
10076 x.sent_time = time.time() # bad approximation
10077 if conf.auto_fragment and msg[0] == 90:
10078 for p in fragment(x):
10079 self.outs.sendto(str(ll(p)), sdto)
10086 class L2Socket(SuperSocket):
10087 def __init__(self, iface = None, type = ETH_P_ALL, filter=None, nofilter=0):
10090 self.ins = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(type))
10091 self.ins.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 0)
10094 if conf.except_filter:
10096 filter = "(%s) and not (%s)" % (filter, conf.except_filter)
10098 filter = "not (%s)" % conf.except_filter
10099 if filter is not None:
10100 attach_filter(self.ins, filter)
10101 self.ins.bind((iface, type))
10102 self.ins.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 2**30)
10103 self.outs = self.ins
10104 self.outs.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 2**30)
10105 sa_ll = self.outs.getsockname()
10106 if LLTypes.has_key(sa_ll[3]):
10107 self.LL = LLTypes[sa_ll[3]]
10108 elif L3Types.has_key(sa_ll[1]):
10109 self.LL = L3Types[sa_ll[1]]
10111 warning("Unable to guess type (interface=%s protocol=%#x family=%i). Using Ethernet" % (sa_ll[0],sa_ll[1],sa_ll[3]))
10115 pkt, sa_ll = self.ins.recvfrom(x)
10116 if sa_ll[2] == socket.PACKET_OUTGOING:
10120 except KeyboardInterrupt:
10123 if conf.debug_dissector:
10126 q.time = get_last_packet_timestamp(self.ins)
10130 class L2ListenSocket(SuperSocket):
10131 def __init__(self, iface = None, type = ETH_P_ALL, promisc=None, filter=None, nofilter=0):
10134 self.ins = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(type))
10135 self.ins.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 0)
10137 if iface is not None:
10138 self.ins.bind((iface, type))
10140 if conf.except_filter:
10142 filter = "(%s) and not (%s)" % (filter, conf.except_filter)
10144 filter = "not (%s)" % conf.except_filter
10145 if filter is not None:
10146 attach_filter(self.ins, filter)
10147 if promisc is None:
10148 promisc = conf.sniff_promisc
10149 self.promisc = promisc
10151 self.iff = get_if_list()
10153 if iface.__class__ is list:
10159 set_promisc(self.ins, i)
10160 self.ins.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 2**30)
10164 set_promisc(self.ins, i, 0)
10165 SuperSocket.close(self)
10168 pkt, sa_ll = self.ins.recvfrom(x)
10169 if LLTypes.has_key(sa_ll[3]):
10170 cls = LLTypes[sa_ll[3]]
10171 elif L3Types.has_key(sa_ll[1]):
10172 cls = L3Types[sa_ll[1]]
10174 warning("Unable to guess type (interface=%s protocol=%#x family=%i). Using Ethernet" % (sa_ll[0],sa_ll[1],sa_ll[3]))
10179 except KeyboardInterrupt:
10182 if conf.debug_dissector:
10185 pkt.time = get_last_packet_timestamp(self.ins)
10189 raise Scapy_Exception("Can't send anything with L2ListenSocket")
10193 class L3dnetSocket(SuperSocket):
10194 def __init__(self, type = ETH_P_ALL, filter=None, promisc=None, iface=None, nofilter=0):
10196 self.ins = pcap.pcapObject()
10200 self.ins.open_live(iface, 1600, 0, 100)
10202 ioctl(self.ins.fileno(),BIOCIMMEDIATE,struct.pack("I",1))
10206 if type != ETH_P_ALL: # PF_PACKET stuff. Need to emulate this for pcap
10207 filter = "ether proto %i" % type
10211 if conf.except_filter:
10213 filter = "(%s) and not (%s)" % (filter, conf.except_filter)
10215 filter = "not (%s)" % conf.except_filter
10216 if type != ETH_P_ALL: # PF_PACKET stuff. Need to emulate this for pcap
10218 filter = "(ether proto %i) and (%s)" % (type,filter)
10220 filter = "ether proto %i" % type
10222 self.ins.setfilter(filter, 0, 0)
10224 if isinstance(x, IPv6):
10225 iff,a,gw = conf.route6.route(x.dst)
10226 elif hasattr(x,"dst"):
10227 iff,a,gw = conf.route.route(x.dst)
10230 ifs = self.iflist.get(iff)
10232 self.iflist[iff] = ifs = dnet.eth(iff)
10233 sx = str(Ether()/x)
10234 x.sent_time = time.time()
10236 def recv(self,x=MTU):
10237 ll = self.ins.datalink()
10238 if LLTypes.has_key(ll):
10241 warning("Unable to guess datalink type (interface=%s linktype=%i). Using Ethernet" % (self.iface, ll))
10244 pkt = self.ins.next()
10245 if pkt is not None:
10252 except KeyboardInterrupt:
10255 if conf.debug_dissector:
10261 def nonblock_recv(self):
10262 self.ins.setnonblock(1)
10264 self.ins.setnonblock(0)
10268 if hasattr(self, "ins"):
10270 if hasattr(self, "outs"):
10273 class L2dnetSocket(SuperSocket):
10274 def __init__(self, iface = None, type = ETH_P_ALL, filter=None, nofilter=0):
10278 self.ins = pcap.pcapObject()
10279 self.ins.open_live(iface, 1600, 0, 100)
10281 ioctl(self.ins.fileno(),BIOCIMMEDIATE,struct.pack("I",1))
10285 if type != ETH_P_ALL: # PF_PACKET stuff. Need to emulate this for pcap
10286 filter = "ether proto %i" % type
10290 if conf.except_filter:
10292 filter = "(%s) and not (%s)" % (filter, conf.except_filter)
10294 filter = "not (%s)" % conf.except_filter
10295 if type != ETH_P_ALL: # PF_PACKET stuff. Need to emulate this for pcap
10297 filter = "(ether proto %i) and (%s)" % (type,filter)
10299 filter = "ether proto %i" % type
10301 self.ins.setfilter(filter, 0, 0)
10302 self.outs = dnet.eth(iface)
10304 ll = self.ins.datalink()
10305 if LLTypes.has_key(ll):
10308 warning("Unable to guess datalink type (interface=%s linktype=%i). Using Ethernet" % (self.iface, ll))
10311 pkt = self.ins.next()
10312 if pkt is not None:
10319 except KeyboardInterrupt:
10322 if conf.debug_dissector:
10328 def nonblock_recv(self):
10329 self.ins.setnonblock(1)
10331 self.ins.setnonblock(0)
10335 if hasattr(self, "ins"):
10337 if hasattr(self, "outs"):
10344 class L2pcapListenSocket(SuperSocket):
10345 def __init__(self, iface = None, type = ETH_P_ALL, promisc=None, filter=None):
10348 self.ins = pcap.pcapObject()
10352 if promisc is None:
10353 promisc = conf.sniff_promisc
10354 self.promisc = promisc
10355 self.ins.open_live(iface, 1600, self.promisc, 100)
10357 ioctl(self.ins.fileno(),BIOCIMMEDIATE,struct.pack("I",1))
10360 if type == ETH_P_ALL: # Do not apply any filter if Ethernet type is given
10361 if conf.except_filter:
10363 filter = "(%s) and not (%s)" % (filter, conf.except_filter)
10365 filter = "not (%s)" % conf.except_filter
10367 self.ins.setfilter(filter, 0, 0)
10373 ll = self.ins.datalink()
10374 if LLTypes.has_key(ll):
10377 warning("Unable to guess datalink type (interface=%s linktype=%i). Using Ethernet" % (self.iface, ll))
10382 pkt = self.ins.next()
10383 if pkt is not None:
10388 except KeyboardInterrupt:
10391 if conf.debug_dissector:
10398 raise Scapy_Exception("Can't send anything with L2pcapListenSocket")
10401 class SimpleSocket(SuperSocket):
10402 def __init__(self, sock):
10407 class StreamSocket(SimpleSocket):
10408 def __init__(self, sock, basecls=Raw):
10409 SimpleSocket.__init__(self, sock)
10410 self.basecls = basecls
10412 def recv(self, x=MTU):
10413 pkt = self.ins.recv(x, socket.MSG_PEEK)
10415 pkt = self.basecls(pkt)
10417 if pad is not None and pad.underlayer is not None:
10418 del(pad.underlayer.payload)
10419 while pad is not None and not isinstance(pad, NoPayload):
10426 class BluetoothL2CAPSocket(SuperSocket):
10427 def __init__(self, peer):
10428 s = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_RAW,
10429 socket.BTPROTO_L2CAP)
10430 s.connect((peer,0))
10432 self.ins = self.outs = s
10435 return L2CAP_CmdHdr(self.ins.recv(x))
10438 class BluetoothHCISocket(SuperSocket):
10439 def __init__(self, iface=0x10000, type=None):
10440 s = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_RAW, socket.BTPROTO_HCI)
10441 s.setsockopt(socket.SOL_HCI, socket.HCI_DATA_DIR,1)
10442 s.setsockopt(socket.SOL_HCI, socket.HCI_TIME_STAMP,1)
10443 s.setsockopt(socket.SOL_HCI, socket.HCI_FILTER, struct.pack("IIIh2x", 0xffffffffL,0xffffffffL,0xffffffffL,0)) #type mask, event mask, event mask, opcode
10445 self.ins = self.outs = s
10446 # s.connect((peer,0))
10450 return HCI_Hdr(self.ins.recv(x))
10454 ####################
10455 ## Send / Receive ##
10456 ####################
10461 def sndrcv(pks, pkt, timeout = 2, inter = 0, verbose=None, chainCC=0, retry=0, multi=0):
10462 if not isinstance(pkt, Gen):
10465 if verbose is None:
10466 verbose = conf.verb
10467 debug.recv = PacketList([],"Unanswered")
10468 debug.sent = PacketList([],"Sent")
10469 debug.match = SndRcvList([])
10472 # do it here to fix random fields, so that parent and child have the same
10473 all_stimuli = tobesent = [p for p in pkt]
10474 notans = len(tobesent)
10496 rdpipe,wrpipe = os.pipe()
10497 rdpipe=os.fdopen(rdpipe)
10498 wrpipe=os.fdopen(wrpipe,"w")
10510 print "Begin emission:"
10516 print "Finished to send %i packets." % i
10519 except KeyboardInterrupt:
10522 log_runtime.exception("--- Error in child %i" % os.getpid())
10523 log_runtime.info("--- Error in child %i" % os.getpid())
10526 os.setpgrp() # Chance process group to avoid ctrl-C
10527 sent_times = [p.sent_time for p in all_stimuli if p.sent_time]
10528 cPickle.dump( (arp_cache,sent_times), wrpipe )
10533 log_runtime.error("fork error")
10538 inmask = [rdpipe,pks]
10543 remaintime = stoptime-time.time()
10544 if remaintime <= 0:
10547 if FREEBSD or DARWIN:
10548 inp, out, err = select(inmask,[],[], 0.05)
10549 if len(inp) == 0 or pks in inp:
10550 r = pks.nonblock_recv()
10552 inp, out, err = select(inmask,[],[], remaintime)
10559 stoptime = time.time()+timeout
10560 del(inmask[inmask.index(rdpipe)])
10567 for i in range(len(hlst)):
10568 if r.answers(hlst[i]):
10569 ans.append((hlst[i],r))
10577 if not hasattr(hlst[i], '_answered'):
10579 hlst[i]._answered = 1;
10581 if notans == 0 and not multi:
10587 if conf.debug_match:
10588 debug.recv.append(r)
10589 except KeyboardInterrupt:
10594 ac,sent_times = cPickle.load(rdpipe)
10596 warning("Child died unexpectedly. Packets may have not been sent %i"%os.getpid())
10598 arp_cache.update(ac)
10599 for p,t in zip(all_stimuli, sent_times):
10606 remain = reduce(list.__add__, hsent.values(), [])
10608 remain = filter(lambda p: not hasattr(p, '_answered'), remain);
10610 if autostop and len(remain) > 0 and len(remain) != len(tobesent):
10614 if len(tobesent) == 0:
10618 if conf.debug_match:
10619 debug.sent=PacketList(remain[:],"Sent")
10620 debug.match=SndRcvList(ans[:])
10622 #clean the ans list to delete the field _answered
10625 if hasattr(s, '_answered'):
10629 print "\nReceived %i packets, got %i answers, remaining %i packets" % (nbrecv+len(ans), len(ans), notans)
10630 return SndRcvList(ans),PacketList(remain,"Unanswered"),debug.recv
10633 def __gen_send(s, x, inter=0, loop=0, count=None, verbose=None, *args, **kargs):
10634 if not isinstance(x, Gen):
10636 if verbose is None:
10637 verbose = conf.verb
10639 if count is not None:
10653 except KeyboardInterrupt:
10657 print "\nSent %i packets." % n
10659 def send(x, inter=0, loop=0, count=None, verbose=None, *args, **kargs):
10660 """Send packets at layer 3
10661 send(packets, [inter=0], [loop=0], [verbose=conf.verb]) -> None"""
10662 __gen_send(conf.L3socket(*args, **kargs), x, inter=inter, loop=loop, count=count,verbose=verbose)
10664 def sendp(x, inter=0, loop=0, iface=None, iface_hint=None, count=None, verbose=None, *args, **kargs):
10665 """Send packets at layer 2
10666 sendp(packets, [inter=0], [loop=0], [verbose=conf.verb]) -> None"""
10667 if iface is None and iface_hint is not None:
10668 iface = conf.route.route(iface_hint)[0]
10669 __gen_send(conf.L2socket(iface=iface, *args, **kargs), x, inter=inter, loop=loop, count=count, verbose=verbose)
10671 def sendpfast(x, pps=None, mbps=None, realtime=None, loop=0, iface=None):
10672 """Send packets at layer 2 using tcpreplay for performance
10673 pps: packets per second
10674 mpbs: MBits per second
10675 realtime: use packet's timestamp, bending time with realtime value
10676 loop: number of times to process the packet list
10677 iface: output interface """
10680 options = ["--intf1=%s" % iface ]
10681 if pps is not None:
10682 options.append("--pps=%i" % pps)
10683 elif mbps is not None:
10684 options.append("--mbps=%i" % mbps)
10685 elif realtime is not None:
10686 options.append("--multiplier=%i" % realtime)
10688 options.append("--topspeed")
10691 options.append("--loop=%i" % loop)
10693 f = os.tempnam("scapy")
10698 os.spawnlp(os.P_WAIT, conf.prog.tcpreplay, conf.prog.tcpreplay, *options)
10699 except KeyboardInterrupt:
10700 log_interactive.info("Interrupted by user")
10708 def sr(x,filter=None, iface=None, nofilter=0, *args,**kargs):
10709 """Send and receive packets at layer 3
10710 nofilter: put 1 to avoid use of bpf filters
10711 retry: if positive, how many times to resend unanswered packets
10712 if negative, how many times to retry when no more packets are answered
10713 timeout: how much time to wait after the last packet has been sent
10714 verbose: set verbosity level
10715 multi: whether to accept multiple answers for the same stimulus
10716 filter: provide a BPF filter
10717 iface: listen answers only on the given interface"""
10718 if not kargs.has_key("timeout"):
10719 kargs["timeout"] = -1
10720 s = conf.L3socket(filter=filter, iface=iface, nofilter=nofilter)
10721 a,b,c=sndrcv(s,x,*args,**kargs)
10725 def sr1(x,filter=None,iface=None, nofilter=0, *args,**kargs):
10726 """Send packets at layer 3 and return only the first answer
10727 nofilter: put 1 to avoid use of bpf filters
10728 retry: if positive, how many times to resend unanswered packets
10729 if negative, how many times to retry when no more packets are answered
10730 timeout: how much time to wait after the last packet has been sent
10731 verbose: set verbosity level
10732 multi: whether to accept multiple answers for the same stimulus
10733 filter: provide a BPF filter
10734 iface: listen answers only on the given interface"""
10735 if not kargs.has_key("timeout"):
10736 kargs["timeout"] = -1
10737 s=conf.L3socket(filter=filter, nofilter=nofilter, iface=iface)
10738 a,b,c=sndrcv(s,x,*args,**kargs)
10745 def srp(x,iface=None, iface_hint=None, filter=None, nofilter=0, type=ETH_P_ALL, *args,**kargs):
10746 """Send and receive packets at layer 2
10747 nofilter: put 1 to avoid use of bpf filters
10748 retry: if positive, how many times to resend unanswered packets
10749 if negative, how many times to retry when no more packets are answered
10750 timeout: how much time to wait after the last packet has been sent
10751 verbose: set verbosity level
10752 multi: whether to accept multiple answers for the same stimulus
10753 filter: provide a BPF filter
10754 iface: work only on the given interface"""
10755 if not kargs.has_key("timeout"):
10756 kargs["timeout"] = -1
10757 if iface is None and iface_hint is not None:
10758 iface = conf.route.route(iface_hint)[0]
10759 s = conf.L2socket(iface=iface, filter=filter, nofilter=nofilter, type=type)
10760 a,b,c=sndrcv(s ,x,*args,**kargs)
10764 def srp1(*args,**kargs):
10765 """Send and receive packets at layer 2 and return only the first answer
10766 nofilter: put 1 to avoid use of bpf filters
10767 retry: if positive, how many times to resend unanswered packets
10768 if negative, how many times to retry when no more packets are answered
10769 timeout: how much time to wait after the last packet has been sent
10770 verbose: set verbosity level
10771 multi: whether to accept multiple answers for the same stimulus
10772 filter: provide a BPF filter
10773 iface: work only on the given interface"""
10774 if not kargs.has_key("timeout"):
10775 kargs["timeout"] = -1
10776 a,b=srp(*args,**kargs)
10782 def __sr_loop(srfunc, pkts, prn=lambda x:x[1].summary(), prnfail=lambda x:x.summary(), inter=1, timeout=None, count=None, verbose=None, store=1, *args, **kargs):
10785 ct = conf.color_theme
10786 if verbose is None:
10787 verbose = conf.verb
10791 if timeout is None:
10792 timeout = min(2*inter, 5)
10796 col = [ct.even,ct.odd][parity]
10797 if count is not None:
10801 start = time.time()
10802 print "\rsend...\r",
10803 res = srfunc(pkts, timeout=timeout, verbose=0, chainCC=1, *args, **kargs)
10804 n += len(res[0])+len(res[1])
10806 if verbose > 1 and prn and len(res[0]) > 0:
10807 msg = "RECV %i:" % len(res[0])
10808 print "\r"+ct.success(msg),
10811 print " "*len(msg),
10812 if verbose > 1 and prnfail and len(res[1]) > 0:
10813 msg = "fail %i:" % len(res[1])
10814 print "\r"+ct.fail(msg),
10816 print col(prnfail(p))
10817 print " "*len(msg),
10818 if verbose > 1 and not (prn or prnfail):
10819 print "recv:%i fail:%i" % tuple(map(len, res[:2]))
10824 if end-start < inter:
10825 time.sleep(inter+start-end)
10826 except KeyboardInterrupt:
10829 if verbose and n>0:
10830 print ct.normal("\nSent %i packets, received %i packets. %3.1f%% hits." % (n,r,100.0*r/n))
10831 return SndRcvList(ans),PacketList(unans)
10833 def srloop(pkts, *args, **kargs):
10834 """Send a packet at layer 3 in loop and print the answer each time
10835 srloop(pkts, [prn], [inter], [count], ...) --> None"""
10836 return __sr_loop(sr, pkts, *args, **kargs)
10838 def srploop(pkts, *args, **kargs):
10839 """Send a packet at layer 2 in loop and print the answer each time
10840 srloop(pkts, [prn], [inter], [count], ...) --> None"""
10841 return __sr_loop(srp, pkts, *args, **kargs)
10844 def sndrcvflood(pks, pkt, prn=lambda (s,r):r.summary(), chainCC=0, store=1, unique=0):
10845 if not isinstance(pkt, Gen):
10847 tobesent = [p for p in pkt]
10848 received = SndRcvList()
10859 def send_in_loop(tobesent):
10864 packets_to_send = send_in_loop(tobesent)
10866 ssock = rsock = pks.fileno()
10870 readyr,readys,_ = select([rsock],[ssock],[])
10871 if ssock in readys:
10872 pks.send(packets_to_send.next())
10874 if rsock in readyr:
10888 if res is not None:
10891 received.append((i,p))
10892 except KeyboardInterrupt:
10897 def srflood(x,filter=None, iface=None, nofilter=None, *args,**kargs):
10898 """Flood and receive packets at layer 3
10899 prn: function applied to packets received. Ret val is printed if not None
10900 store: if 1 (default), store answers and return them
10901 unique: only consider packets whose print
10902 nofilter: put 1 to avoid use of bpf filters
10903 filter: provide a BPF filter
10904 iface: listen answers only on the given interface"""
10905 s = conf.L3socket(filter=filter, iface=iface, nofilter=nofilter)
10906 r=sndrcvflood(s,x,*args,**kargs)
10910 def srpflood(x,filter=None, iface=None, iface_hint=None, nofilter=None, *args,**kargs):
10911 """Flood and receive packets at layer 2
10912 prn: function applied to packets received. Ret val is printed if not None
10913 store: if 1 (default), store answers and return them
10914 unique: only consider packets whose print
10915 nofilter: put 1 to avoid use of bpf filters
10916 filter: provide a BPF filter
10917 iface: listen answers only on the given interface"""
10918 if iface is None and iface_hint is not None:
10919 iface = conf.route.route(iface_hint)[0]
10920 s = conf.L2socket(filter=filter, iface=iface, nofilter=nofilter)
10921 r=sndrcvflood(s,x,*args,**kargs)
10929 def srbt(peer, pkts, inter=0.1, *args, **kargs):
10930 s = conf.BTsocket(peer=peer)
10931 a,b,c=sndrcv(s,pkts,inter=inter,*args,**kargs)
10935 def srbt1(peer, pkts, *args, **kargs):
10936 a,b = srbt(peer, pkts, *args, **kargs)
10944 #############################
10945 ## pcap capture file stuff ##
10946 #############################
10948 def wrpcap(filename, pkt, *args, **kargs):
10949 """Write a list of packets to a pcap file
10950 gz: set to 1 to save a gzipped capture
10951 linktype: force linktype value
10952 endianness: "<" or ">", force endianness"""
10953 PcapWriter(filename, *args, **kargs).write(pkt)
10955 def rdpcap(filename, count=-1):
10956 """Read a pcap file and return a packet list
10957 count: read only <count> packets"""
10958 return PcapReader(filename).read_all(count=count)
10961 """A stateful pcap reader
10963 Based entirely on scapy.rdpcap(), this class allows for packets
10964 to be dispatched without having to be loaded into memory all at
10968 def __init__(self, filename):
10969 self.filename = filename
10971 self.f = gzip.open(filename,"rb")
10972 magic = self.f.read(4)
10974 self.f = open(filename,"rb")
10975 magic = self.f.read(4)
10976 if magic == "\xa1\xb2\xc3\xd4": #big endian
10978 elif magic == "\xd4\xc3\xb2\xa1": #little endian
10981 raise RuntimeWarning, "Not a pcap capture file (bad magic)"
10982 hdr = self.f.read(20)
10984 raise RuntimeWarning, "Invalid pcap file (too short)"
10985 vermaj,vermin,tz,sig,snaplen,linktype = struct.unpack(self.endian+"HHIIII",hdr)
10986 self.LLcls = LLTypes.get(linktype, Raw)
10987 if self.LLcls == Raw:
10988 warning("PcapReader: unkonwon LL type [%i]/[%#x]. Using Raw packets" % (linktype,linktype))
10990 def __iter__(self):
10994 """impliment the iterator protocol on a set of packets in a
10997 pkt = self.read_packet()
10999 raise StopIteration
11003 def read_packet(self):
11004 """return a single packet read from the file
11006 returns None when no more packets are available
11008 hdr = self.f.read(16)
11011 sec,usec,caplen,olen = struct.unpack(self.endian+"IIII", hdr)
11012 s = self.f.read(caplen)
11015 except KeyboardInterrupt:
11018 if conf.debug_dissector:
11021 p.time = sec+0.000001*usec
11024 def dispatch(self, callback):
11025 """call the specified callback routine for each packet read
11027 This is just a convienience function for the main loop
11028 that allows for easy launching of packet processing in a
11031 p = self.read_packet()
11034 p = self.read_packet()
11036 def read_all(self,count=-1):
11037 """return a list of all packets in the pcap file
11042 p = self.read_packet()
11046 return PacketList(res,name = os.path.basename(self.filename))
11048 def recv(self, size):
11049 """ Emulate a socket
11051 return self.read_packet()
11054 return self.f.fileno()
11059 """A stream PCAP writer with more control than wrpcap()"""
11060 def __init__(self, filename, linktype=None, gz=False, endianness="", append=False, sync=False):
11062 linktype: force linktype to a given value. If None, linktype is taken
11063 from the first writter packet
11064 gz: compress the capture on the fly
11065 endianness: force an endianness (little:"<", big:">"). Default is native
11066 append: append packets to the capture file instead of truncating it
11067 sync: do not bufferize writes to the capture file
11070 self.linktype = linktype
11071 self.header_present = 0
11074 self.endian = endianness
11075 self.filename=filename
11081 self.f = [open,gzip.open][gz](filename,append and "ab" or "wb", gz and 9 or bufsz)
11086 return self.f.fileno()
11088 def _write_header(self, pkt):
11089 self.header_present=1
11091 if self.linktype == None:
11092 if type(pkt) is list or type(pkt) is tuple:
11094 self.linktype = LLNumTypes.get(pkt.__class__,1)
11097 # Even if prone to race conditions, this seems to be
11098 # safest way to tell whether the header is already present
11099 # because we have to handle compressed streams that
11100 # are not as flexible as basic files
11101 g = [open,gzip.open][self.gz](self.filename,"rb")
11105 self.f.write(struct.pack(self.endian+"IHHIIII", 0xa1b2c3d4L,
11106 2, 4, 0, 0, MTU, self.linktype))
11110 def write(self, pkt):
11111 """accepts a either a single packet or a list of packets
11112 to be written to the dumpfile
11114 if not self.header_present:
11115 self._write_header(pkt)
11117 self._write_packet(p)
11119 def _write_packet(self, packet):
11120 """writes a single packet to the pcap file
11124 sec = int(packet.time)
11125 usec = int((packet.time-sec)*1000000)
11126 self.f.write(struct.pack(self.endian+"IIII", sec, usec, l, l))
11128 if self.gz and self.sync:
11132 return self.f.flush()
11134 return self.f.close()
11137 re_extract_hexcap = re.compile("^(0x[0-9a-fA-F]{2,}[ :\t]|(0x)?[0-9a-fA-F]{2,}:|(0x)?[0-9a-fA-F]{3,}[: \t]|) *(([0-9a-fA-F]{2} {,2}){,16})")
11139 def import_hexcap():
11143 l = raw_input().strip()
11145 p += re_extract_hexcap.match(l).groups()[3]
11147 warning("Parsing error during hexcap")
11152 p = p.replace(" ","")
11154 for i in range(len(p)/2):
11155 p2 += chr(int(p[2*i:2*i+2],16))
11160 def wireshark(pktlist):
11161 f = os.tempnam("scapy")
11163 os.spawnlp(os.P_NOWAIT, conf.prog.wireshark, conf.prog.wireshark, "-r", f)
11167 f = os.tempnam("scapy")
11168 open(f,"w").write(x)
11169 os.spawnlp(os.P_WAIT, conf.prog.hexedit, conf.prog.hexedit, f)
11175 #####################
11176 ## knowledge bases ##
11177 #####################
11179 class KnowledgeBase:
11180 def __init__(self, filename):
11181 self.filename = filename
11184 def lazy_init(self):
11187 def reload(self, filename = None):
11188 if filename is not None:
11189 self.filename = filename
11190 oldbase = self.base
11193 if self.base is None:
11194 self.base = oldbase
11196 def get_base(self):
11197 if self.base is None:
11203 ##########################
11204 ## IP location database ##
11205 ##########################
11207 class IPCountryKnowledgeBase(KnowledgeBase):
11209 How to generate the base :
11211 for l in open("GeoIPCountryWhois.csv").readlines():
11212 s,e,c = l.split(",")[2:5]
11213 db.append((int(s[1:-1]),int(e[1:-1]),c[1:-1]))
11214 cPickle.dump(gzip.open("xxx","w"),db)
11216 def lazy_init(self):
11217 self.base = load_object(self.filename)
11220 class CountryLocKnowledgeBase(KnowledgeBase):
11221 def lazy_init(self):
11222 f=open(self.filename)
11228 l = l.strip().split(",")
11233 self.base[c] = (float(long),float(lat))
11240 ip=map(int,ip.split("."))
11241 ip = ip[3]+(ip[2]<<8L)+(ip[1]<<16L)+(ip[0]<<24L)
11243 cloc = country_loc_kdb.get_base()
11244 db = IP_country_kdb.get_base()
11250 if ip > db[guess][0]:
11255 if s <= ip and ip <= e:
11256 return cloc.get(c,None)
11265 # File format (according to p0f.fp) :
11267 # wwww:ttt:D:ss:OOO...:QQ:OS:Details
11269 # wwww - window size
11270 # ttt - initial TTL
11271 # D - don't fragment bit (0=unset, 1=set)
11272 # ss - overall SYN packet size
11273 # OOO - option value and order specification
11276 # details - OS description
11280 class p0fKnowledgeBase(KnowledgeBase):
11281 def __init__(self, filename):
11282 KnowledgeBase.__init__(self, filename)
11283 #self.ttl_range=[255]
11284 def lazy_init(self):
11286 f=open(self.filename)
11288 warning("Can't open base %s" % self.filename)
11293 if l[0] in ["#","\n"]:
11295 l = tuple(l.split(":"))
11298 li = map(int,l[1:4])
11299 #if li[0] not in self.ttl_range:
11300 # self.ttl_range.append(li[0])
11301 # self.ttl_range.sort()
11302 self.base.append((l[0], li[0], li[1], li[2], l[4], l[5], l[6], l[7][:-1]))
11304 warning("Can't parse p0f database (new p0f version ?)")
11309 def packet2p0f(pkt):
11310 while pkt.haslayer(IP) and pkt.haslayer(TCP):
11311 pkt = pkt.getlayer(IP)
11312 if isinstance(pkt.payload, TCP):
11316 if not isinstance(pkt, IP) or not isinstance(pkt.payload, TCP):
11317 raise TypeError("Not a TCP/IP packet")
11318 if pkt.payload.flags & 0x13 != 0x02: #S,!A,!F
11319 raise TypeError("Not a syn packet")
11321 #t = p0f_kdb.ttl_range[:]
11324 #ttl=t[t.index(pkt.ttl)+1]
11327 df = (pkt.flags & 2) / 2
11329 # from p0f/config.h : PACKET_BIG = 100
11338 ilen = (pkt[TCP].dataofs << 2) - 20 # from p0f.c
11339 for option in pkt.payload.options:
11341 if option[0] == "MSS":
11342 ooo += "M" + str(option[1]) + ","
11346 elif option[0] == "WScale":
11347 ooo += "W" + str(option[1]) + ","
11350 elif option[0] == "Timestamp":
11351 if option[1][0] == 0:
11355 if option[1][1] != 0:
11358 elif option[0] == "SAckOK":
11361 elif option[0] == "NOP":
11363 elif option[0] == "EOL":
11371 if ooo == "": ooo = "."
11373 win = pkt.payload.window
11376 win = "S" + str(win/mss)
11377 elif win % (mss + 40) == 0:
11378 win = "T" + str(win/(mss+40))
11385 if pkt[IP].id == 0:
11387 if pkt[IP].options != '':
11389 if pkt[TCP].urgptr != 0:
11391 if pkt[TCP].reserved != 0:
11393 if pkt[TCP].ack != 0:
11397 if pkt[TCP].flags & 40 != 0:
11400 if not isinstance(pkt[TCP].payload, NoPayload):
11402 # FIXME : "!" - broken options segment
11414 def p0f_correl(x,y):
11416 # wwww can be "*" or "%nn"
11417 d += (x[0] == y[0] or y[0] == "*" or (y[0][0] == "%" and x[0].isdigit() and (int(x[0]) % int(y[0][1:])) == 0))
11419 d += (y[1] >= x[1] and y[1] - x[1] < 32)
11420 for i in [2, 3, 5]:
11421 d += (x[i] == y[i])
11422 xopt = x[4].split(",")
11423 yopt = y[4].split(",")
11424 if len(xopt) == len(yopt):
11426 for i in range(len(xopt)):
11427 if not (xopt[i] == yopt[i] or
11428 (len(yopt[i]) == 2 and len(xopt[i]) > 1 and
11429 yopt[i][1] == "*" and xopt[i][0] == yopt[i][0]) or
11430 (len(yopt[i]) > 2 and len(xopt[i]) > 1 and
11431 yopt[i][1] == "%" and xopt[i][0] == yopt[i][0] and
11432 int(xopt[i][1:]) % int(yopt[i][2:]) == 0)):
11441 """Passive OS fingerprinting: which OS emitted this TCP SYN ?
11442 p0f(packet) -> accuracy, [list of guesses]
11444 pb = p0f_kdb.get_base()
11446 warning("p0f base empty.")
11450 sig = packet2p0f(pkt)
11451 max = len(sig[4].split(",")) + 5
11453 d = p0f_correl(sig,b)
11455 r.append((b[6], b[7], b[1] - pkt[IP].ttl))
11465 r = ("UNKNOWN", "[" + ":".join(map(str, packet2p0f(pkt))) + ":?:?]", None)
11470 uptime = pkt2uptime(pkt)
11475 res = pkt.sprintf("%IP.src%:%TCP.sport% - " + r[0] + " " + r[1])
11476 if uptime is not None:
11477 res += pkt.sprintf(" (up: " + str(uptime/3600) + " hrs)\n -> %IP.dst%:%TCP.dport%")
11479 res += pkt.sprintf("\n -> %IP.dst%:%TCP.dport%")
11480 if r[2] is not None:
11481 res += " (distance " + str(r[2]) + ")"
11485 def pkt2uptime(pkt, HZ=100):
11486 """Calculate the date the machine which emitted the packet booted using TCP timestamp
11487 pkt2uptime(pkt, [HZ=100])"""
11488 if not isinstance(pkt, Packet):
11489 raise TypeError("Not a TCP packet")
11490 if isinstance(pkt,NoPayload):
11491 raise TypeError("Not a TCP packet")
11492 if not isinstance(pkt, TCP):
11493 return pkt2uptime(pkt.payload)
11494 for opt in pkt.options:
11495 if opt[0] == "Timestamp":
11496 #t = pkt.time - opt[1][0] * 1.0/HZ
11497 #return time.ctime(t)
11500 raise TypeError("No timestamp option")
11509 def quesoTCPflags(flags):
11515 v |= 2**flv.index(i)
11518 class QuesoKnowledgeBase(KnowledgeBase):
11519 def lazy_init(self):
11521 f = open(self.filename)
11529 if not l or l[0] == ';':
11534 name = l[1:].strip()
11537 if l[0] not in list("0123456"):
11539 res = l[2:].split()
11540 res[-1] = quesoTCPflags(res[-1])
11541 res = " ".join(res)
11542 if not p.has_key(res):
11549 warning("Can't load queso base [%s]", self.filename)
11555 def queso_sig(target, dport=80, timeout=3):
11556 p = queso_kdb.get_base()
11558 for flags in ["S", "SA", "F", "FA", "SF", "P", "SEC"]:
11559 ans, unans = sr(IP(dst=target)/TCP(dport=dport,flags=flags,seq=RandInt()),
11560 timeout=timeout, verbose=0)
11565 rs = "%i" % (r.seq != 0)
11568 elif r.ack-s.seq > 666:
11571 rs += " +%i" % (r.ack-s.seq)
11572 rs += " %X" % r.window
11573 rs += " %x" % r.payload.flags
11577 def queso_search(sig):
11578 p = queso_kdb.get_base()
11592 def queso(*args,**kargs):
11593 """Queso OS fingerprinting
11594 queso(target, dport=80, timeout=3)"""
11595 return queso_search(queso_sig(*args, **kargs))
11599 ######################
11600 ## nmap OS fp stuff ##
11601 ######################
11604 class NmapKnowledgeBase(KnowledgeBase):
11605 def lazy_init(self):
11607 f=open(self.filename)
11616 if not l or l[0] == "#":
11618 if l[:12] == "Fingerprint ":
11619 if name is not None:
11620 self.base.append((name,sig))
11621 name = l[12:].strip()
11625 elif l[:6] == "Class ":
11629 if op < 0 or cl < 0:
11630 warning("error reading nmap os fp base file")
11633 s = map(lambda x: x.split("="), l[op+1:cl].split("%"))
11638 if name is not None:
11639 self.base.append((name,sig))
11642 warning("Can't read nmap database [%s](new nmap version ?)" % self.filename)
11645 def TCPflags2str(f):
11648 for i in range(len(fl)):
11654 def nmap_tcppacket_sig(pkt):
11656 if pkt is not None:
11658 r["DF"] = (pkt.flags & 2) and "Y" or "N"
11659 r["W"] = "%X" % pkt.window
11660 r["ACK"] = pkt.ack==2 and "S++" or pkt.ack==1 and "S" or "O"
11661 r["Flags"] = TCPflags2str(pkt.payload.flags)
11662 r["Ops"] = "".join(map(lambda x: x[0][0],pkt.payload.options))
11668 def nmap_udppacket_sig(S,T):
11673 r["DF"] = (T.flags & 2) and "Y" or "N"
11674 r["TOS"] = "%X" % T.tos
11675 r["IPLEN"] = "%X" % T.len
11676 r["RIPTL"] = "%X" % T.payload.payload.len
11677 r["RID"] = S.id == T.payload.payload.id and "E" or "F"
11678 r["RIPCK"] = S.chksum == T.getlayer(IPerror).chksum and "E" or T.getlayer(IPerror).chksum == 0 and "0" or "F"
11679 r["UCK"] = S.payload.chksum == T.getlayer(UDPerror).chksum and "E" or T.getlayer(UDPerror).chksum ==0 and "0" or "F"
11680 r["ULEN"] = "%X" % T.getlayer(UDPerror).len
11681 r["DAT"] = T.getlayer(Raw) is None and "E" or S.getlayer(Raw).load == T.getlayer(Raw).load and "E" or "F"
11686 def nmap_match_one_sig(seen, ref):
11688 for k in seen.keys():
11690 if seen[k] in ref[k].split("|"):
11692 if c == 0 and seen.get("Resp") == "N":
11695 return 1.0*c/len(seen.keys())
11699 def nmap_sig(target, oport=80, cport=81, ucport=1):
11702 tcpopt = [ ("WScale", 10),
11705 ("Timestamp",(123,0)) ]
11706 tests = [ IP(dst=target, id=1)/TCP(seq=1, sport=5001, dport=oport, options=tcpopt, flags="CS"),
11707 IP(dst=target, id=1)/TCP(seq=1, sport=5002, dport=oport, options=tcpopt, flags=0),
11708 IP(dst=target, id=1)/TCP(seq=1, sport=5003, dport=oport, options=tcpopt, flags="SFUP"),
11709 IP(dst=target, id=1)/TCP(seq=1, sport=5004, dport=oport, options=tcpopt, flags="A"),
11710 IP(dst=target, id=1)/TCP(seq=1, sport=5005, dport=cport, options=tcpopt, flags="S"),
11711 IP(dst=target, id=1)/TCP(seq=1, sport=5006, dport=cport, options=tcpopt, flags="A"),
11712 IP(dst=target, id=1)/TCP(seq=1, sport=5007, dport=cport, options=tcpopt, flags="FPU"),
11713 IP(str(IP(dst=target)/UDP(sport=5008,dport=ucport)/(300*"i"))) ]
11715 ans, unans = sr(tests, timeout=2)
11716 ans += map(lambda x: (x,None), unans)
11719 if S.sport == 5008:
11720 res["PU"] = nmap_udppacket_sig(S,T)
11722 t = "T%i" % (S.sport-5000)
11723 if T is not None and T.haslayer(ICMP):
11724 warning("Test %s answered by an ICMP" % t)
11726 res[t] = nmap_tcppacket_sig(T)
11730 def nmap_probes2sig(tests):
11734 res["PU"] = nmap_udppacket_sig(*tests["PU"])
11737 res[k] = nmap_tcppacket_sig(tests[k])
11741 def nmap_search(sigs):
11743 for os,fp in nmap_kdb.get_base():
11745 for t in sigs.keys():
11747 c += nmap_match_one_sig(sigs[t], fp[t])
11748 c /= len(sigs.keys())
11751 elif c == guess[0]:
11752 guess[1].append(os)
11756 def nmap_fp(target, oport=80, cport=81):
11757 """nmap fingerprinting
11758 nmap_fp(target, [oport=80,] [cport=81,]) -> list of best guesses with accuracy
11760 sigs = nmap_sig(target, oport, cport)
11761 return nmap_search(sigs)
11764 def nmap_sig2txt(sig):
11765 torder = ["TSeq","T1","T2","T3","T4","T5","T6","T7","PU"]
11766 korder = ["Class", "gcd", "SI", "IPID", "TS",
11767 "Resp", "DF", "W", "ACK", "Flags", "Ops",
11768 "TOS", "IPLEN", "RIPTL", "RID", "RIPCK", "UCK", "ULEN", "DAT" ]
11770 for i in sig.keys():
11771 if i not in torder:
11782 s.append("%s=%s"%(k,v))
11783 txt.append("%s(%s)" % (t, "%".join(s)))
11784 return "\n".join(txt)
11790 ###################
11791 ## User commands ##
11792 ###################
11795 def sniff(count=0, store=1, offline=None, prn = None, lfilter=None, L2socket=None, timeout=None, *arg, **karg):
11797 sniff([count=0,] [prn=None,] [store=1,] [offline=None,] [lfilter=None,] + L2ListenSocket args) -> list of packets
11799 count: number of packets to capture. 0 means infinity
11800 store: wether to store sniffed packets or discard them
11801 prn: function to apply to each packet. If something is returned,
11802 it is displayed. Ex:
11803 ex: prn = lambda x: x.summary()
11804 lfilter: python function applied to each packet to determine
11805 if further action may be done
11806 ex: lfilter = lambda x: x.haslayer(Padding)
11807 offline: pcap file to read packets from, instead of sniffing them
11808 timeout: stop sniffing after a given time (default: None)
11809 L2socket: use the provided L2socket
11813 if offline is None:
11814 if L2socket is None:
11815 L2socket = conf.L2listen
11816 s = L2socket(type=ETH_P_ALL, *arg, **karg)
11818 s = PcapReader(offline)
11821 if timeout is not None:
11822 stoptime = time.time()+timeout
11826 if timeout is not None:
11827 remain = stoptime-time.time()
11830 sel = select([s],[],[],remain)
11835 if lfilter and not lfilter(p):
11844 if count > 0 and c >= count:
11846 except KeyboardInterrupt:
11849 return PacketList(lst,"Sniffed")
11853 def arpcachepoison(target, victim, interval=60):
11854 """Poison target's cache with (your MAC,victim's IP) couple
11855 arpcachepoison(target, victim, [interval=60]) -> None
11857 tmac = getmacbyip(target)
11858 p = Ether(dst=tmac)/ARP(op="who-has", psrc=victim, pdst=target)
11861 sendp(p, iface_hint=target)
11864 time.sleep(interval)
11865 except KeyboardInterrupt:
11868 def traceroute(target, dport=80, minttl=1, maxttl=30, sport=RandShort(), l4 = None, filter=None, timeout=2, verbose=None, **kargs):
11869 """Instant TCP traceroute
11870 traceroute(target, [maxttl=30,] [dport=80,] [sport=80,] [verbose=conf.verb]) -> None
11872 if verbose is None:
11873 verbose = conf.verb
11875 # we only consider ICMP error packets and TCP packets with at
11876 # least the ACK flag set *and* either the SYN or the RST flag
11878 filter="(icmp and (icmp[0]=3 or icmp[0]=4 or icmp[0]=5 or icmp[0]=11 or icmp[0]=12)) or (tcp and (tcp[13] & 0x16 > 0x10))"
11880 a,b = sr(IP(dst=target, id=RandShort(), ttl=(minttl,maxttl))/TCP(seq=RandInt(),sport=sport, dport=dport),
11881 timeout=timeout, filter=filter, verbose=verbose, **kargs)
11883 # this should always work
11885 a,b = sr(IP(dst=target, id=RandShort(), ttl=(minttl,maxttl))/l4,
11886 timeout=timeout, filter=filter, verbose=verbose, **kargs)
11888 a = TracerouteResult(a.res)
11896 def arping(net, timeout=2, cache=0, verbose=None, **kargs):
11897 """Send ARP who-has requests to determine which hosts are up
11898 arping(net, [cache=0,] [iface=conf.iface,] [verbose=conf.verb]) -> None
11899 Set cache=True if you want arping to modify internal ARP-Cache"""
11900 if verbose is None:
11901 verbose = conf.verb
11902 ans,unans = srp(Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(pdst=net), verbose=verbose,
11903 filter="arp and arp[7] = 2", timeout=timeout, iface_hint=net, **kargs)
11904 ans = ARPingResult(ans.res)
11906 if cache and ans is not None:
11908 arp_cache[pair[1].psrc] = (pair[1].hwsrc, time.time())
11913 def dyndns_add(nameserver, name, rdata, type="A", ttl=10):
11914 """Send a DNS add message to a nameserver for "name" to have a new "rdata"
11915 dyndns_add(nameserver, name, rdata, type="A", ttl=10) -> result code (0=ok)
11917 example: dyndns_add("ns1.toto.com", "dyn.toto.com", "127.0.0.1")
11920 zone = name[name.find(".")+1:]
11921 r=sr1(IP(dst=nameserver)/UDP()/DNS(opcode=5,
11922 qd=[DNSQR(qname=zone, qtype="SOA")],
11923 ns=[DNSRR(rrname=name, type="A",
11924 ttl=ttl, rdata=rdata)]),
11925 verbose=0, timeout=5)
11926 if r and r.haslayer(DNS):
11927 return r.getlayer(DNS).rcode
11934 def dyndns_del(nameserver, name, type="ALL", ttl=10):
11935 """Send a DNS delete message to a nameserver for "name"
11936 dyndns_del(nameserver, name, type="ANY", ttl=10) -> result code (0=ok)
11938 example: dyndns_del("ns1.toto.com", "dyn.toto.com")
11941 zone = name[name.find(".")+1:]
11942 r=sr1(IP(dst=nameserver)/UDP()/DNS(opcode=5,
11943 qd=[DNSQR(qname=zone, qtype="SOA")],
11944 ns=[DNSRR(rrname=name, type=type,
11945 rclass="ANY", ttl=0, rdata="")]),
11946 verbose=0, timeout=5)
11947 if r and r.haslayer(DNS):
11948 return r.getlayer(DNS).rcode
11953 def is_promisc(ip, fake_bcast="ff:ff:00:00:00:00",**kargs):
11954 """Try to guess if target is in Promisc mode. The target is provided by its ip."""
11956 responses = srp1(Ether(dst=fake_bcast) / ARP(op="who-has", pdst=ip),type=ETH_P_ARP, iface_hint=ip, timeout=1, verbose=0,**kargs)
11958 return responses is not None
11960 def promiscping(net, timeout=2, fake_bcast="ff:ff:ff:ff:ff:fe", **kargs):
11961 """Send ARP who-has requests to determine which hosts are in promiscuous mode
11962 promiscping(net, iface=conf.iface)"""
11963 ans,unans = srp(Ether(dst=fake_bcast)/ARP(pdst=net),
11964 filter="arp and arp[7] = 2", timeout=timeout, iface_hint=net, **kargs)
11965 ans = ARPingResult(ans.res, name="PROMISCPing")
11971 return sr(IP(dst=ip)/UDP()/ISAKMP(init_cookie=RandString(8),
11972 exch_type=2)/ISAKMP_payload_SA(prop=ISAKMP_payload_Proposal()))
11975 def dhcp_request(iface=None,**kargs):
11976 if conf.checkIPaddr != 0:
11977 warning("conf.checkIPaddr is not 0, I may not be able to match the answer")
11980 fam,hw = get_if_raw_hwaddr(iface)
11981 return srp1(Ether(dst="ff:ff:ff:ff:ff:ff")/IP(src="0.0.0.0",dst="255.255.255.255")/UDP(sport=68,dport=67)
11982 /BOOTP(chaddr=hw)/DHCP(options=[("message-type","discover"),"end"]),iface=iface,**kargs)
11984 def snmpwalk(dst, oid="1", community="public"):
11987 r = sr1(IP(dst=dst)/UDP(sport=RandShort())/SNMP(community=community, PDU=SNMPnext(varbindlist=[SNMPvarbind(oid=oid)])),timeout=2, chainCC=1, verbose=0, retry=2)
11994 print "%-40s: %r" % (r[SNMPvarbind].oid.val,r[SNMPvarbind].value)
11995 oid = r[SNMPvarbind].oid
11997 except KeyboardInterrupt:
12001 #####################
12002 ## Reporting stuff ##
12003 #####################
12005 def report_ports(target, ports):
12006 """portscan a target and output a LaTeX table
12007 report_ports(target, ports) -> string"""
12008 ans,unans = sr(IP(dst=target)/TCP(dport=ports),timeout=5)
12009 rep = "\\begin{tabular}{|r|l|l|}\n\\hline\n"
12011 if not r.haslayer(ICMP):
12012 if r.payload.flags == 0x12:
12013 rep += r.sprintf("%TCP.sport% & open & SA \\\\\n")
12016 if r.haslayer(ICMP):
12017 rep += r.sprintf("%TCPerror.dport% & closed & ICMP type %ICMP.type%/%ICMP.code% from %IP.src% \\\\\n")
12018 elif r.payload.flags != 0x12:
12019 rep += r.sprintf("%TCP.sport% & closed & TCP %TCP.flags% \\\\\n")
12022 rep += i.sprintf("%TCP.dport% & ? & unanswered \\\\\n")
12023 rep += "\\hline\n\\end{tabular}\n"
12027 def __make_table(yfmtfunc, fmtfunc, endline, list, fxyz, sortx=None, sorty=None, seplinefunc=None):
12035 xx,yy,zz = map(str, fxyz(e))
12037 vx[xx] = max(vx.get(xx,0), len(xx), len(zz))
12047 vxk.sort(lambda x,y:int(x)-int(y))
12050 vxk.sort(lambda x,y: cmp(atol(x),atol(y)))
12057 vyk.sort(lambda x,y:int(x)-int(y))
12060 vyk.sort(lambda x,y: cmp(atol(x),atol(y)))
12066 sepline = seplinefunc(l, map(lambda x:vx[x],vxk))
12072 vxf[x] = fmtfunc(vx[x])
12080 print vxf[x] % vz.get((x,y), "-"),
12085 def make_table(*args, **kargs):
12086 __make_table(lambda l:"%%-%is" % l, lambda l:"%%-%is" % l, "", *args, **kargs)
12088 def make_lined_table(*args, **kargs):
12089 __make_table(lambda l:"%%-%is |" % l, lambda l:"%%-%is |" % l, "",
12090 seplinefunc=lambda a,x:"+".join(map(lambda y:"-"*(y+2), [a-1]+x+[-2])),
12093 def make_tex_table(*args, **kargs):
12094 __make_table(lambda l: "%s", lambda l: "& %s", "\\\\", seplinefunc=lambda a,x:"\\hline", *args, **kargs)
12097 ######################
12098 ## Online doc stuff ##
12099 ######################
12103 """List user commands"""
12105 for c in user_commands:
12106 doc = "No doc. available"
12108 doc = c.__doc__.split("\n")[0]
12110 print "%-16s : %s" % (c.__name__, doc)
12115 """List available layers, or infos on a given layer"""
12118 all = __builtin__.__dict__.copy()
12119 all.update(globals())
12120 objlst = filter(lambda (n,o): isinstance(o,type) and issubclass(o,Packet), all.items())
12121 objlst.sort(lambda x,y:cmp(x[0],y[0]))
12123 print "%-10s : %s" %(n,o.name)
12125 if isinstance(obj, type) and issubclass(obj, Packet):
12126 for f in obj.fields_desc:
12127 print "%-10s : %-20s = (%s)" % (f.name, f.__class__.__name__, repr(f.default))
12128 elif isinstance(obj, Packet):
12129 for f in obj.fields_desc:
12130 print "%-10s : %-20s = %-15s (%s)" % (f.name, f.__class__.__name__, repr(getattr(obj,f.name)), repr(f.default))
12131 if not isinstance(obj.payload, NoPayload):
12137 print "Not a packet class. Type 'ls()' to list packet classes."
12143 user_commands = [ sr, sr1, srp, srp1, srloop, srploop, sniff, p0f, arpcachepoison, send, sendp, traceroute, arping, ls, lsc, queso, nmap_fp, report_ports, dyndns_add, dyndns_del, is_promisc, promiscping ]
12153 CONDITION = "Condition"
12154 RECV = "Receive condition"
12155 TIMEOUT = "Timeout condition"
12157 class NewStateRequested(Exception):
12158 def __init__(self, state_func, automaton, *args, **kargs):
12159 self.func = state_func
12160 self.state = state_func.atmt_state
12161 self.initial = state_func.atmt_initial
12162 self.error = state_func.atmt_error
12163 self.final = state_func.atmt_final
12164 Exception.__init__(self, "Request state [%s]" % self.state)
12165 self.automaton = automaton
12168 self.action_parameters() # init action parameters
12169 def action_parameters(self, *args, **kargs):
12170 self.action_args = args
12171 self.action_kargs = kargs
12174 return self.func(self.automaton, *self.args, **self.kargs)
12177 def state(initial=0,final=0,error=0):
12178 def deco(f,initial=initial, final=final):
12179 f.atmt_type = ATMT.STATE
12180 f.atmt_state = f.func_name
12181 f.atmt_initial = initial
12182 f.atmt_final = final
12183 f.atmt_error = error
12184 def state_wrapper(self, *args, **kargs):
12185 return ATMT.NewStateRequested(f, self, *args, **kargs)
12187 state_wrapper.func_name = "%s_wrapper" % f.func_name
12188 state_wrapper.atmt_type = ATMT.STATE
12189 state_wrapper.atmt_state = f.func_name
12190 state_wrapper.atmt_initial = initial
12191 state_wrapper.atmt_final = final
12192 state_wrapper.atmt_error = error
12193 state_wrapper.atmt_origfunc = f
12194 return state_wrapper
12197 def action(cond, prio=0):
12198 def deco(f,cond=cond):
12199 if not hasattr(f,"atmt_type"):
12201 f.atmt_type = ATMT.ACTION
12202 f.atmt_cond[cond.atmt_condname] = prio
12206 def condition(state, prio=0):
12207 def deco(f, state=state):
12208 f.atmt_type = ATMT.CONDITION
12209 f.atmt_state = state.atmt_state
12210 f.atmt_condname = f.func_name
12215 def receive_condition(state, prio=0):
12216 def deco(f, state=state):
12217 f.atmt_type = ATMT.RECV
12218 f.atmt_state = state.atmt_state
12219 f.atmt_condname = f.func_name
12224 def timeout(state, timeout):
12225 def deco(f, state=state, timeout=timeout):
12226 f.atmt_type = ATMT.TIMEOUT
12227 f.atmt_state = state.atmt_state
12228 f.atmt_timeout = timeout
12229 f.atmt_condname = f.func_name
12234 class Automaton_metaclass(type):
12235 def __new__(cls, name, bases, dct):
12236 cls = super(Automaton_metaclass, cls).__new__(cls, name, bases, dct)
12239 cls.recv_conditions={}
12243 cls.initial_states=[]
12248 c = classes.pop(0) # order is important to avoid breaking method overloading
12249 classes += list(c.__bases__)
12250 for k,v in c.__dict__.iteritems():
12251 if k not in members:
12254 decorated = [v for v in members.itervalues()
12255 if type(v) is types.FunctionType and hasattr(v, "atmt_type")]
12257 for m in decorated:
12258 if m.atmt_type == ATMT.STATE:
12261 cls.recv_conditions[s]=[]
12262 cls.conditions[s]=[]
12265 cls.initial_states.append(m)
12266 elif m.atmt_type in [ATMT.CONDITION, ATMT.RECV, ATMT.TIMEOUT]:
12267 cls.actions[m.atmt_condname] = []
12269 for m in decorated:
12270 if m.atmt_type == ATMT.CONDITION:
12271 cls.conditions[m.atmt_state].append(m)
12272 elif m.atmt_type == ATMT.RECV:
12273 cls.recv_conditions[m.atmt_state].append(m)
12274 elif m.atmt_type == ATMT.TIMEOUT:
12275 cls.timeout[m.atmt_state].append((m.atmt_timeout, m))
12276 elif m.atmt_type == ATMT.ACTION:
12277 for c in m.atmt_cond:
12278 cls.actions[c].append(m)
12281 for v in cls.timeout.itervalues():
12282 v.sort(lambda (t1,f1),(t2,f2): cmp(t1,t2))
12283 v.append((None, None))
12284 for v in itertools.chain(cls.conditions.itervalues(),
12285 cls.recv_conditions.itervalues()):
12286 v.sort(lambda c1,c2: cmp(c1.atmt_prio,c2.atmt_prio))
12287 for condname,actlst in cls.actions.iteritems():
12288 actlst.sort(lambda c1,c2: cmp(c1.atmt_cond[condname], c2.atmt_cond[condname]))
12293 def graph(self, **kargs):
12294 s = 'digraph "%s" {\n' % self.__class__.__name__
12296 se = "" # Keep initial nodes at the begining for better rendering
12297 for st in self.states.itervalues():
12298 if st.atmt_initial:
12299 se = ('\t"%s" [ style=filled, fillcolor=blue, shape=box, root=true];\n' % st.atmt_state)+se
12300 elif st.atmt_final:
12301 se += '\t"%s" [ style=filled, fillcolor=green, shape=octagon ];\n' % st.atmt_state
12302 elif st.atmt_error:
12303 se += '\t"%s" [ style=filled, fillcolor=red, shape=octagon ];\n' % st.atmt_state
12306 for st in self.states.values():
12307 for n in st.atmt_origfunc.func_code.co_names+st.atmt_origfunc.func_code.co_consts:
12308 if n in self.states:
12309 s += '\t"%s" -> "%s" [ color=green ];\n' % (st.atmt_state,n)
12312 for c,k,v in [("purple",k,v) for k,v in self.conditions.items()]+[("red",k,v) for k,v in self.recv_conditions.items()]:
12314 for n in f.func_code.co_names+f.func_code.co_consts:
12315 if n in self.states:
12316 l = f.atmt_condname
12317 for x in self.actions[f.atmt_condname]:
12318 l += "\\l>[%s]" % x.func_name
12319 s += '\t"%s" -> "%s" [label="%s", color=%s];\n' % (k,n,l,c)
12320 for k,v in self.timeout.iteritems():
12324 for n in f.func_code.co_names+f.func_code.co_consts:
12325 if n in self.states:
12326 l = "%s/%.1fs" % (f.atmt_condname,t)
12327 for x in self.actions[f.atmt_condname]:
12328 l += "\\l>[%s]" % x.func_name
12329 s += '\t"%s" -> "%s" [label="%s",color=blue];\n' % (k,n,l)
12331 return do_graph(s, **kargs)
12336 __metaclass__ = Automaton_metaclass
12338 def __init__(self, *args, **kargs):
12340 self.init_args=args
12341 self.init_kargs=kargs
12342 self.parse_args(*args, **kargs)
12344 def debug(self, lvl, msg):
12345 if self.debug_level >= lvl:
12346 log_interactive.debug(msg)
12351 class ErrorState(Exception):
12352 def __init__(self, msg, result=None):
12353 Exception.__init__(self, msg)
12354 self.result = result
12355 class Stuck(ErrorState):
12358 def parse_args(self, debug=0, store=1, **kargs):
12359 self.debug_level=debug
12360 self.socket_kargs = kargs
12361 self.store_packets = store
12364 def master_filter(self, pkt):
12367 def run_condition(self, cond, *args, **kargs):
12369 cond(self,*args, **kargs)
12370 except ATMT.NewStateRequested, state_req:
12371 self.debug(2, "%s [%s] taken to state [%s]" % (cond.atmt_type, cond.atmt_condname, state_req.state))
12372 if cond.atmt_type == ATMT.RECV:
12373 self.packets.append(args[0])
12374 for action in self.actions[cond.atmt_condname]:
12375 self.debug(2, " + Running action [%s]" % action.func_name)
12376 action(self, *state_req.action_args, **state_req.action_kargs)
12379 self.debug(2, "%s [%s] not taken" % (cond.atmt_type, cond.atmt_condname))
12382 def run(self, *args, **kargs):
12383 # Update default parameters
12384 a = args+self.init_args[len(args):]
12385 k = self.init_kargs
12387 self.parse_args(*a,**k)
12389 # Start the automaton
12390 self.state=self.initial_states[0](self)
12391 self.send_sock = conf.L3socket()
12392 l = conf.L2listen(**self.socket_kargs)
12393 self.packets = PacketList(name="session[%s]"%self.__class__.__name__)
12396 self.debug(1, "## state=[%s]" % self.state.state)
12398 # Entering a new state. First, call new state function
12399 state_output = self.state.run()
12400 if self.state.error:
12401 raise self.ErrorState("Reached %s: [%r]" % (self.state.state, state_output), result=state_output)
12402 if self.state.final:
12403 return state_output
12405 if state_output is None:
12407 elif type(state_output) is not list:
12408 state_output = state_output,
12410 # Then check immediate conditions
12411 for cond in self.conditions[self.state.state]:
12412 self.run_condition(cond, *state_output)
12414 # If still there and no conditions left, we are stuck!
12415 if ( len(self.recv_conditions[self.state.state]) == 0
12416 and len(self.timeout[self.state.state]) == 1 ):
12417 raise self.Stuck("stuck in [%s]" % self.state.state,result=state_output)
12419 # Finally listen and pay attention to timeouts
12420 expirations = iter(self.timeout[self.state.state])
12421 next_timeout,timeout_func = expirations.next()
12426 if next_timeout is not None:
12427 if next_timeout <= t:
12428 self.run_condition(timeout_func, *state_output)
12429 next_timeout,timeout_func = expirations.next()
12430 if next_timeout is None:
12433 remain = next_timeout-t
12435 r,_,_ = select([l],[],[],remain)
12438 if pkt is not None:
12439 if self.master_filter(pkt):
12440 self.debug(3, "RECVD: %s" % pkt.summary())
12441 for rcvcond in self.recv_conditions[self.state.state]:
12442 self.run_condition(rcvcond, pkt, *state_output)
12444 self.debug(4, "FILTR: %s" % pkt.summary())
12446 except ATMT.NewStateRequested,state_req:
12447 self.debug(2, "switching from [%s] to [%s]" % (self.state.state,state_req.state))
12448 self.state = state_req
12449 except KeyboardInterrupt:
12450 self.debug(1,"Interrupted by user")
12453 def my_send(self, pkt):
12454 self.send_sock.send(pkt)
12456 def send(self, pkt):
12458 self.debug(3,"SENT : %s" % pkt.summary())
12459 self.packets.append(pkt.copy())
12466 class TFTP_read(Automaton):
12467 def parse_args(self, filename, server, sport = None, port=69, **kargs):
12468 Automaton.parse_args(self, **kargs)
12469 self.filename = filename
12470 self.server = server
12475 def master_filter(self, pkt):
12476 return ( IP in pkt and pkt[IP].src == self.server and UDP in pkt
12477 and pkt[UDP].dport == self.my_tid
12478 and (self.server_tid is None or pkt[UDP].sport == self.server_tid) )
12481 @ATMT.state(initial=1)
12484 self.my_tid = self.sport or RandShort()._fix()
12485 bind_bottom_up(UDP, TFTP, dport=self.my_tid)
12486 self.server_tid = None
12489 self.l3 = IP(dst=self.server)/UDP(sport=self.my_tid, dport=self.port)/TFTP()
12490 self.last_packet = self.l3/TFTP_RRQ(filename=self.filename, mode="octet")
12491 self.send(self.last_packet)
12494 raise self.WAITING()
12502 @ATMT.receive_condition(WAITING)
12503 def receive_data(self, pkt):
12504 if TFTP_DATA in pkt and pkt[TFTP_DATA].block == self.awaiting:
12505 if self.server_tid is None:
12506 self.server_tid = pkt[UDP].sport
12507 self.l3[UDP].dport = self.server_tid
12508 raise self.RECEIVING(pkt)
12510 @ATMT.receive_condition(WAITING, prio=1)
12511 def receive_error(self, pkt):
12512 if TFTP_ERROR in pkt:
12513 raise self.ERROR(pkt)
12516 @ATMT.timeout(WAITING, 3)
12517 def timeout_waiting(self):
12518 raise self.WAITING()
12519 @ATMT.action(timeout_waiting)
12520 def retransmit_last_packet(self):
12521 self.send(self.last_packet)
12523 @ATMT.action(receive_data)
12524 # @ATMT.action(receive_error)
12525 def send_ack(self):
12526 self.last_packet = self.l3 / TFTP_ACK(block = self.awaiting)
12527 self.send(self.last_packet)
12532 def RECEIVING(self, pkt):
12534 recvd = pkt[Raw].load
12539 if len(recvd) == self.blocksize:
12540 raise self.WAITING()
12544 @ATMT.state(error=1)
12545 def ERROR(self,pkt):
12546 split_bottom_up(UDP, TFTP, dport=self.my_tid)
12547 return pkt[TFTP_ERROR].summary()
12550 @ATMT.state(final=1)
12552 split_bottom_up(UDP, TFTP, dport=self.my_tid)
12558 class TFTP_write(Automaton):
12559 def parse_args(self, filename, data, server, sport=None, port=69,**kargs):
12560 Automaton.parse_args(self, **kargs)
12561 self.filename = filename
12562 self.server = server
12565 self.blocksize = 512
12566 self.origdata = data
12568 def master_filter(self, pkt):
12569 return ( IP in pkt and pkt[IP].src == self.server and UDP in pkt
12570 and pkt[UDP].dport == self.my_tid
12571 and (self.server_tid is None or pkt[UDP].sport == self.server_tid) )
12575 @ATMT.state(initial=1)
12577 self.data = [ self.origdata[i*self.blocksize:(i+1)*self.blocksize]
12578 for i in range( len(self.origdata)/self.blocksize+1) ]
12579 self.my_tid = self.sport or RandShort()._fix()
12580 bind_bottom_up(UDP, TFTP, dport=self.my_tid)
12581 self.server_tid = None
12583 self.l3 = IP(dst=self.server)/UDP(sport=self.my_tid, dport=self.port)/TFTP()
12584 self.last_packet = self.l3/TFTP_WRQ(filename=self.filename, mode="octet")
12585 self.send(self.last_packet)
12589 raise self.WAITING_ACK()
12593 def WAITING_ACK(self):
12596 @ATMT.receive_condition(WAITING_ACK)
12597 def received_ack(self,pkt):
12598 if TFTP_ACK in pkt and pkt[TFTP_ACK].block == self.awaiting:
12599 if self.server_tid is None:
12600 self.server_tid = pkt[UDP].sport
12601 self.l3[UDP].dport = self.server_tid
12602 raise self.SEND_DATA()
12604 @ATMT.receive_condition(WAITING_ACK)
12605 def received_error(self, pkt):
12606 if TFTP_ERROR in pkt:
12607 raise self.ERROR(pkt)
12609 @ATMT.timeout(WAITING_ACK, 3)
12610 def timeout_waiting(self):
12611 raise self.WAITING_ACK()
12612 @ATMT.action(timeout_waiting)
12613 def retransmit_last_packet(self):
12614 self.send(self.last_packet)
12618 def SEND_DATA(self):
12620 self.last_packet = self.l3/TFTP_DATA(block=self.awaiting)/self.data.pop(0)
12621 self.send(self.last_packet)
12623 raise self.WAITING_ACK()
12628 @ATMT.state(error=1)
12629 def ERROR(self,pkt):
12630 split_bottom_up(UDP, TFTP, dport=self.my_tid)
12631 return pkt[TFTP_ERROR].summary()
12634 @ATMT.state(final=1)
12636 split_bottom_up(UDP, TFTP, dport=self.my_tid)
12639 class TFTP_WRQ_server(Automaton):
12641 def parse_args(self, ip=None, sport=None, *args, **kargs):
12642 Automaton.parse_args(self, *args, **kargs)
12646 def master_filter(self, pkt):
12647 return TFTP in pkt and (not self.ip or pkt[IP].dst == self.ip)
12649 @ATMT.state(initial=1)
12654 self.my_tid = self.sport or random.randint(10000,65500)
12655 bind_bottom_up(UDP, TFTP, dport=self.my_tid)
12657 @ATMT.receive_condition(BEGIN)
12658 def receive_WRQ(self,pkt):
12659 if TFTP_WRQ in pkt:
12660 raise self.WAIT_DATA().action_parameters(pkt)
12662 @ATMT.action(receive_WRQ)
12663 def ack_WRQ(self, pkt):
12667 self.filename = pkt[TFTP_WRQ].filename
12668 options = pkt[TFTP_Options]
12669 self.l3 = IP(src=ip.dst, dst=ip.src)/UDP(sport=self.my_tid, dport=pkt.sport)/TFTP()
12670 if options is None:
12671 self.last_packet = self.l3/TFTP_ACK(block=0)
12672 self.send(self.last_packet)
12674 opt = [x for x in options.options if x.oname.upper() == "BLKSIZE"]
12676 self.blksize = int(opt[0].value)
12677 self.debug(2,"Negotiated new blksize at %i" % self.blksize)
12678 self.last_packet = self.l3/TFTP_OACK()/TFTP_Options(options=opt)
12679 self.send(self.last_packet)
12682 def WAIT_DATA(self):
12685 @ATMT.timeout(WAIT_DATA, 1)
12686 def resend_ack(self):
12687 self.send(self.last_packet)
12688 raise self.WAIT_DATA()
12690 @ATMT.receive_condition(WAIT_DATA)
12691 def receive_data(self, pkt):
12692 if TFTP_DATA in pkt:
12693 data = pkt[TFTP_DATA]
12694 if data.block == self.blk:
12695 raise self.DATA(data)
12697 @ATMT.action(receive_data)
12698 def ack_data(self):
12699 self.last_packet = self.l3/TFTP_ACK(block = self.blk)
12700 self.send(self.last_packet)
12703 def DATA(self, data):
12704 self.filedata += data.load
12705 if len(data.load) < self.blksize:
12708 raise self.WAIT_DATA()
12710 @ATMT.state(final=1)
12712 return self.filename,self.filedata
12713 split_bottom_up(UDP, TFTP, dport=self.my_tid)
12716 class TFTP_RRQ_server(Automaton):
12717 def parse_args(self, store=None, joker=None, dir=None, ip=None, sport=None, serve_one=False, **kargs):
12718 Automaton.parse_args(self,**kargs)
12721 if dir is not None:
12722 self.dir = os.path.join(os.path.abspath(dir),"")
12729 self.serve_one = serve_one
12730 self.my_tid = self.sport or random.randint(10000,65500)
12731 bind_bottom_up(UDP, TFTP, dport=self.my_tid)
12733 def master_filter(self, pkt):
12734 return TFTP in pkt and (not self.ip or pkt[IP].dst == self.ip)
12736 @ATMT.state(initial=1)
12737 def WAIT_RRQ(self):
12741 @ATMT.receive_condition(WAIT_RRQ)
12742 def receive_rrq(self, pkt):
12743 if TFTP_RRQ in pkt:
12744 raise self.RECEIVED_RRQ(pkt)
12748 def RECEIVED_RRQ(self, pkt):
12750 options = pkt[TFTP_Options]
12751 self.l3 = IP(src=ip.dst, dst=ip.src)/UDP(sport=self.my_tid, dport=ip.sport)/TFTP()
12752 self.filename = pkt[TFTP_RRQ].filename
12755 if self.filename in self.store:
12756 self.data = self.store[self.filename]
12757 elif self.dir is not None:
12758 fn = os.path.abspath(os.path.join(self.dir, self.filename))
12759 if fn.startswith(self.dir): # Check we're still in the server's directory
12761 self.data=open(fn).read()
12764 if self.data is None:
12765 self.data = self.joker
12768 opt = [x for x in options.options if x.oname.upper() == "BLKSIZE"]
12770 self.blksize = int(opt[0].value)
12771 self.debug(2,"Negotiated new blksize at %i" % self.blksize)
12772 self.last_packet = self.l3/TFTP_OACK()/TFTP_Options(options=opt)
12773 self.send(self.last_packet)
12778 @ATMT.condition(RECEIVED_RRQ)
12779 def file_in_store(self):
12780 if self.data is not None:
12781 self.blknb = len(self.data)/self.blksize+1
12782 raise self.SEND_FILE()
12784 @ATMT.condition(RECEIVED_RRQ)
12785 def file_not_found(self):
12786 if self.data is None:
12787 raise self.WAIT_RRQ()
12788 @ATMT.action(file_not_found)
12789 def send_error(self):
12790 self.send(self.l3/TFTP_ERROR(errorcode=1, errormsg=TFTP_Error_Codes[1]))
12793 def SEND_FILE(self):
12794 self.send(self.l3/TFTP_DATA(block=self.blk)/self.data[(self.blk-1)*self.blksize:self.blk*self.blksize])
12796 @ATMT.timeout(SEND_FILE, 3)
12797 def timeout_waiting_ack(self):
12798 raise self.SEND_FILE()
12800 @ATMT.receive_condition(SEND_FILE)
12801 def received_ack(self, pkt):
12802 if TFTP_ACK in pkt and pkt[TFTP_ACK].block == self.blk:
12803 raise self.RECEIVED_ACK()
12805 def RECEIVED_ACK(self):
12808 @ATMT.condition(RECEIVED_ACK)
12809 def no_more_data(self):
12810 if self.blk > self.blknb:
12813 raise self.WAIT_RRQ()
12814 @ATMT.condition(RECEIVED_ACK, prio=2)
12815 def data_remaining(self):
12816 raise self.SEND_FILE()
12818 @ATMT.state(final=1)
12820 split_bottom_up(UDP, TFTP, dport=self.my_tid)
12825 ########################
12826 ## Answering machines ##
12827 ########################
12829 class ReferenceAM(type):
12830 def __new__(cls, name, bases, dct):
12831 o = super(ReferenceAM, cls).__new__(cls, name, bases, dct)
12832 if o.function_name:
12833 globals()[o.function_name] = lambda o=o,*args,**kargs: o(*args,**kargs)()
12837 class AnsweringMachine(object):
12838 __metaclass__ = ReferenceAM
12841 sniff_options = { "store":0 }
12842 sniff_options_list =