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):
2367 ident,oid = m.groups()
2368 ident=fixname(ident)
2370 for i in range(len(oid)):
2371 m = _mib_re_both.match(oid[i])
2373 oid[i] = m.groups()[1]
2374 mib_register(ident, oid, the_mib, unresolved)
2376 newmib = MIBDict(_name="MIB")
2377 for k,o in the_mib.iteritems():
2378 newmib[k]=".".join(o)
2379 for k,o in unresolved.iteritems():
2380 newmib[k]=".".join(o)
2395 def __init__(self, set, _iterpacket=1):
2396 self._iterpacket=_iterpacket
2397 if type(set) is list:
2399 elif isinstance(set, PacketList):
2400 self.set = list(set)
2403 def transf(self, element):
2407 if (type(i) is tuple) and (len(i) == 2) and type(i[0]) is int and type(i[1]) is int:
2413 elif isinstance(i, Gen) and (self._iterpacket or not isinstance(i,Packet)):
2419 return "<SetGen %s>" % self.set.__repr__()
2422 """Generate a list of IPs from a network address or a name"""
2424 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])?$")
2425 def __init__(self, net):
2428 tmp=net.split('/')+["32"]
2429 if not self.ipaddress.match(net):
2430 tmp[0]=socket.gethostbyname(tmp[0])
2431 netmask = int(tmp[1])
2433 def parse_digit(a,netmask):
2434 netmask = min(8,max(netmask,0))
2437 elif a.find("-") >= 0:
2438 x,y = map(int,a.split("-"))
2441 a = (x & (0xffL<<netmask) , max(y, (x | (0xffL>>(8-netmask))))+1)
2443 a = (int(a) & (0xffL<<netmask),(int(a) | (0xffL>>(8-netmask)))+1)
2446 self.parsed = map(lambda x,y: parse_digit(x,y), tmp[0].split("."), map(lambda x,nm=netmask: x-nm, (8,16,24,32)))
2449 for d in xrange(*self.parsed[3]):
2450 for c in xrange(*self.parsed[2]):
2451 for b in xrange(*self.parsed[1]):
2452 for a in xrange(*self.parsed[0]):
2453 yield "%i.%i.%i.%i" % (a,b,c,d)
2456 for v in self.parsed:
2457 ip.append(str(random.randint(v[0],v[1]-1)))
2461 return "Net(%r)" % self.repr
2465 def __init__(self, oid):
2469 for i in oid.split("."):
2472 self.cmpt.append(tuple(map(int, i.split("-"))))
2475 self.fmt = ".".join(fmt)
2477 return "OID(%r)" % self.oid
2479 ii = [k[0] for k in self.cmpt]
2481 yield self.fmt % tuple(ii)
2486 if ii[i] < self.cmpt[i][1]:
2490 ii[i] = self.cmpt[i][0]
2500 def __init__(self, res=None, name="PacketList", stats=None):
2501 """create a packet list from a list of packets
2502 res: the list of packets
2503 stats: a list of classes that will appear in the stats (defaults to [TCP,UDP,ICMP])"""
2505 stats = [ TCP,UDP,ICMP ]
2509 if isinstance(res, PacketList):
2512 self.listname = name
2513 def _elt2pkt(self, elt):
2515 def _elt2sum(self, elt):
2516 return elt.summary()
2517 def _elt2show(self, elt):
2518 return self._elt2sum(elt)
2520 # stats=dict.fromkeys(self.stats,0) ## needs python >= 2.3 :(
2521 stats = dict(map(lambda x: (x,0), self.stats))
2526 if self._elt2pkt(r).haslayer(p):
2533 ct = conf.color_theme
2534 for p in self.stats:
2535 s += " %s%s%s" % (ct.packetlist_proto(p.name),
2537 ct.packetlist_value(stats[p]))
2538 s += " %s%s%s" % (ct.packetlist_proto("Other"),
2540 ct.packetlist_value(other))
2541 return "%s%s%s%s%s" % (ct.punct("<"),
2542 ct.packetlist_name(self.listname),
2546 def __getattr__(self, attr):
2547 return getattr(self.res, attr)
2548 def __getitem__(self, item):
2549 if isinstance(item,type) and issubclass(item,Packet):
2550 return self.__class__(filter(lambda x: item in self._elt2pkt(x),self.res),
2551 name="%s from %s"%(item.__name__,self.listname))
2552 if type(item) is slice:
2553 return self.__class__(self.res.__getitem__(item),
2554 name = "mod %s" % self.listname)
2555 return self.res.__getitem__(item)
2556 def __getslice__(self, *args, **kargs):
2557 return self.__class__(self.res.__getslice__(*args, **kargs),
2558 name="mod %s"%self.listname)
2559 def __add__(self, other):
2560 return self.__class__(self.res+other.res,
2561 name="%s+%s"%(self.listname,other.listname))
2562 def summary(self, prn=None, lfilter=None):
2563 """prints a summary of each packet
2564 prn: function to apply to each packet instead of lambda x:x.summary()
2565 lfilter: truth function to apply to each packet to decide whether it will be displayed"""
2567 if lfilter is not None:
2571 print self._elt2sum(r)
2574 def nsummary(self,prn=None, lfilter=None):
2575 """prints a summary of each packet with the packet's number
2576 prn: function to apply to each packet instead of lambda x:x.summary()
2577 lfilter: truth function to apply to each packet to decide whether it will be displayed"""
2578 for i in range(len(self.res)):
2579 if lfilter is not None:
2580 if not lfilter(self.res[i]):
2582 print conf.color_theme.id(i,"%04i"),
2584 print self._elt2sum(self.res[i])
2586 print prn(self.res[i])
2587 def display(self): # Deprecated. Use show()
2588 """deprecated. is show()"""
2590 def show(self, *args, **kargs):
2591 """Best way to display the packet list. Defaults to nsummary() method"""
2592 return self.nsummary(*args, **kargs)
2594 def filter(self, func):
2595 """Returns a packet list filtered by a truth function"""
2596 return self.__class__(filter(func,self.res),
2597 name="filtered %s"%self.listname)
2598 def make_table(self, *args, **kargs):
2599 """Prints a table using a function that returs for each packet its head column value, head row value and displayed value
2600 ex: p.make_table(lambda x:(x[IP].dst, x[TCP].dport, x[TCP].sprintf("%flags%")) """
2601 return make_table(self.res, *args, **kargs)
2602 def make_lined_table(self, *args, **kargs):
2603 """Same as make_table, but print a table with lines"""
2604 return make_lined_table(self.res, *args, **kargs)
2605 def make_tex_table(self, *args, **kargs):
2606 """Same as make_table, but print a table with LaTeX syntax"""
2607 return make_tex_table(self.res, *args, **kargs)
2609 def plot(self, f, lfilter=None,**kargs):
2610 """Applies a function to each packet to get a value that will be plotted with GnuPlot. A gnuplot object is returned
2611 lfilter: a truth function that decides whether a packet must be ploted"""
2614 if lfilter is not None:
2615 l = filter(lfilter, l)
2617 g.plot(Gnuplot.Data(l, **kargs))
2620 def diffplot(self, f, delay=1, lfilter=None, **kargs):
2621 """diffplot(f, delay=1, lfilter=None)
2622 Applies a function to couples (l[i],l[i+delay])"""
2623 g = Gnuplot.Gnuplot()
2625 if lfilter is not None:
2626 l = filter(lfilter, l)
2627 l = map(f,l[:-delay],l[delay:])
2628 g.plot(Gnuplot.Data(l, **kargs))
2631 def multiplot(self, f, lfilter=None, **kargs):
2632 """Uses a function that returns a label and a value for this label, then plots all the values label by label"""
2635 if lfilter is not None:
2636 l = filter(lfilter, l)
2647 data.append(Gnuplot.Data(d[k], title=k, **kargs))
2653 def rawhexdump(self):
2654 """Prints an hexadecimal dump of each packet in the list"""
2656 hexdump(self._elt2pkt(p))
2658 def hexraw(self, lfilter=None):
2659 """Same as nsummary(), except that if a packet has a Raw layer, it will be hexdumped
2660 lfilter: a truth function that decides whether a packet must be displayed"""
2661 for i in range(len(self.res)):
2662 p = self._elt2pkt(self.res[i])
2663 if lfilter is not None and not lfilter(p):
2665 print "%s %s %s" % (conf.color_theme.id(i,"%04i"),
2666 p.sprintf("%.time%"),
2667 self._elt2sum(self.res[i]))
2669 hexdump(p.getlayer(Raw).load)
2671 def hexdump(self, lfilter=None):
2672 """Same as nsummary(), except that packets are also hexdumped
2673 lfilter: a truth function that decides whether a packet must be displayed"""
2674 for i in range(len(self.res)):
2675 p = self._elt2pkt(self.res[i])
2676 if lfilter is not None and not lfilter(p):
2678 print "%s %s %s" % (conf.color_theme.id(i,"%04i"),
2679 p.sprintf("%.time%"),
2680 self._elt2sum(self.res[i]))
2683 def padding(self, lfilter=None):
2684 """Same as hexraw(), for Padding layer"""
2685 for i in range(len(self.res)):
2686 p = self._elt2pkt(self.res[i])
2687 if p.haslayer(Padding):
2688 if lfilter is None or lfilter(p):
2689 print "%s %s %s" % (conf.color_theme.id(i,"%04i"),
2690 p.sprintf("%.time%"),
2691 self._elt2sum(self.res[i]))
2692 hexdump(p.getlayer(Padding).load)
2694 def nzpadding(self, lfilter=None):
2695 """Same as padding() but only non null padding"""
2696 for i in range(len(self.res)):
2697 p = self._elt2pkt(self.res[i])
2698 if p.haslayer(Padding):
2699 pad = p.getlayer(Padding).load
2700 if pad == pad[0]*len(pad):
2702 if lfilter is None or lfilter(p):
2703 print "%s %s %s" % (conf.color_theme.id(i,"%04i"),
2704 p.sprintf("%.time%"),
2705 self._elt2sum(self.res[i]))
2706 hexdump(p.getlayer(Padding).load)
2709 def conversations(self, getsrcdst=None,**kargs):
2710 """Graphes a conversations between sources and destinations and display it
2711 (using graphviz and imagemagick)
2712 getsrcdst: a function that takes an element of the list and return the source and dest
2713 by defaults, return source and destination IP
2714 type: output type (svg, ps, gif, jpg, etc.), passed to dot's "-T" option
2715 target: filename or redirect. Defaults pipe to Imagemagick's display program
2716 prog: which graphviz program to use"""
2717 if getsrcdst is None:
2718 getsrcdst = lambda x:(x[IP].src, x[IP].dst)
2721 p = self._elt2pkt(p)
2727 conv[c] = conv.get(c,0)+1
2728 gr = 'digraph "conv" {\n'
2730 gr += '\t "%s" -> "%s"\n' % (s,d)
2732 return do_graph(gr, **kargs)
2734 def afterglow(self, src=None, event=None, dst=None, **kargs):
2735 """Experimental clone attempt of http://sourceforge.net/projects/afterglow
2736 each datum is reduced as src -> event -> dst and the data are graphed.
2737 by default we have IP.src -> IP.dport -> IP.dst"""
2739 src = lambda x: x[IP].src
2741 event = lambda x: x[IP].dport
2743 dst = lambda x: x[IP].dst
2749 s,e,d = src(i),event(i),dst(i)
2766 dl[d] = dl.get(d,0)+1
2772 return 2+math.log(n)/4.0
2782 mins,maxs = minmax(map(lambda (x,y): x, sl.values()))
2783 mine,maxe = minmax(map(lambda (x,y): x, el.values()))
2784 mind,maxd = minmax(dl.values())
2786 gr = 'digraph "afterglow" {\n\tedge [len=2.5];\n'
2788 gr += "# src nodes\n"
2790 n,l = sl[s]; n = 1+float(n-mins)/(maxs-mins)
2791 gr += '"src.%s" [label = "%s", shape=box, fillcolor="#FF0000", style=filled, fixedsize=1, height=%.2f,width=%.2f];\n' % (`s`,`s`,n,n)
2792 gr += "# event nodes\n"
2794 n,l = el[e]; n = n = 1+float(n-mine)/(maxe-mine)
2795 gr += '"evt.%s" [label = "%s", shape=circle, fillcolor="#00FFFF", style=filled, fixedsize=1, height=%.2f, width=%.2f];\n' % (`e`,`e`,n,n)
2797 n = dl[d]; n = n = 1+float(n-mind)/(maxd-mind)
2798 gr += '"dst.%s" [label = "%s", shape=triangle, fillcolor="#0000ff", style=filled, fixedsize=1, height=%.2f, width=%.2f];\n' % (`d`,`d`,n,n)
2804 gr += ' "src.%s" -> "evt.%s";\n' % (`s`,`e`)
2808 gr += ' "evt.%s" -> "dst.%s";\n' % (`e`,`d`)
2811 open("/tmp/aze","w").write(gr)
2812 return do_graph(gr, **kargs)
2816 def timeskew_graph(self, ip, **kargs):
2817 """Tries to graph the timeskew between the timestamps and real time for a given ip"""
2818 res = map(lambda x: self._elt2pkt(x), self.res)
2819 b = filter(lambda x:x.haslayer(IP) and x.getlayer(IP).src == ip and x.haslayer(TCP), res)
2822 opts = p.getlayer(TCP).options
2824 if o[0] == "Timestamp":
2825 c.append((p.time,o[1][0]))
2827 warning("No timestamps found in packet list")
2829 d = map(lambda (x,y): (x%2000,((x-c[0][0])-((y-c[0][1])/1000.0))),c)
2830 g = Gnuplot.Gnuplot()
2831 g.plot(Gnuplot.Data(d,**kargs))
2834 def _dump_document(self, **kargs):
2835 d = pyx.document.document()
2837 for i in range(len(self.res)):
2839 c = self._elt2pkt(elt).canvas_dump(**kargs)
2841 c.text(cbb.left(),cbb.top()+1,r"\font\cmssfont=cmss12\cmssfont{Frame %i/%i}" % (i,l),[pyx.text.size.LARGE])
2844 d.append(pyx.document.page(c, paperformat=pyx.document.paperformat.A4,
2845 margin=1*pyx.unit.t_cm,
2851 def psdump(self, filename = None, **kargs):
2852 """Creates a multipage poscript file with a psdump of every packet
2853 filename: name of the file to write to. If empty, a temporary file is used and
2854 conf.prog.psreader is called"""
2855 d = self._dump_document(**kargs)
2856 if filename is None:
2857 filename = "/tmp/scapy.psd.%i" % os.getpid()
2858 d.writePSfile(filename)
2859 os.system("%s %s.ps &" % (conf.prog.psreader,filename))
2861 d.writePSfile(filename)
2864 def pdfdump(self, filename = None, **kargs):
2865 """Creates a PDF file with a psdump of every packet
2866 filename: name of the file to write to. If empty, a temporary file is used and
2867 conf.prog.pdfreader is called"""
2868 d = self._dump_document(**kargs)
2869 if filename is None:
2870 filename = "/tmp/scapy.psd.%i" % os.getpid()
2871 d.writePDFfile(filename)
2872 os.system("%s %s.pdf &" % (conf.prog.pdfreader,filename))
2874 d.writePDFfile(filename)
2877 def sr(self,multi=0):
2878 """sr([multi=1]) -> (SndRcvList, PacketList)
2879 Matches packets in the list and return ( (matched couples), (unmatched packets) )"""
2880 remain = self.res[:]
2883 while i < len(remain):
2886 while j < len(remain)-1:
2892 remain[i]._answered=1
2893 remain[j]._answered=2
2901 remain = filter(lambda x:not hasattr(x,"_answered"), remain)
2902 return SndRcvList(sr),PacketList(remain)
2909 class Dot11PacketList(PacketList):
2910 def __init__(self, res=None, name="Dot11List", stats=None):
2912 stats = [Dot11WEP, Dot11Beacon, UDP, ICMP, TCP]
2914 PacketList.__init__(self, res, name, stats)
2915 def toEthernet(self):
2916 data = map(lambda x:x.getlayer(Dot11), filter(lambda x : x.haslayer(Dot11) and x.type == 2, self.res))
2921 r2.append(Ether()/q.payload.payload.payload) #Dot11/LLC/SNAP/IP
2922 return PacketList(r2,name="Ether from %s"%self.listname)
2926 class SndRcvList(PacketList):
2927 def __init__(self, res=None, name="Results", stats=None):
2928 PacketList.__init__(self, res, name, stats)
2929 def _elt2pkt(self, elt):
2931 def _elt2sum(self, elt):
2932 return "%s ==> %s" % (elt[0].summary(),elt[1].summary())
2935 class ARPingResult(SndRcvList):
2936 def __init__(self, res=None, name="ARPing", stats=None):
2937 PacketList.__init__(self, res, name, stats)
2940 for s,r in self.res:
2941 print r.sprintf("%Ether.src% %ARP.psrc%")
2947 def __init__(self, server=None, port=43, options=None):
2948 if server is not None:
2949 self.server = server
2951 if options is not None:
2952 self.options = options
2955 self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
2956 self.s.connect((self.server,self.port))
2958 self.s.send(self.options+"\n")
2963 def _parse_whois(self, txt):
2965 for l in txt.splitlines():
2966 if not asn and l.startswith("origin:"):
2968 if l.startswith("descr:"):
2971 desc += l[6:].strip()
2972 if asn is not None and desc:
2974 return asn,desc.strip()
2976 def _resolve_one(self, ip):
2977 self.s.send("%s\n" % ip)
2979 while not ("%" in x or "source" in x):
2980 x += self.s.recv(8192)
2981 asn, desc = self._parse_whois(x)
2983 def resolve(self, *ips):
2987 ip,asn,desc = self._resolve_one(ip)
2989 ret.append((ip,asn,desc))
2993 class AS_resolver_riswhois(AS_resolver):
2994 server = "riswhois.ripe.net"
2995 options = "-k -M -1"
2998 class AS_resolver_radb(AS_resolver):
2999 server = "whois.ra.net"
3003 class AS_resolver_cymru(AS_resolver):
3004 server = "whois.cymru.com"
3006 def resolve(self, *ips):
3008 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
3009 s.connect((self.server,self.port))
3010 s.send("begin\r\n"+"\r\n".join(ips)+"\r\nend\r\n")
3018 for l in r.splitlines()[1:]:
3021 asn,ip,desc = map(str.strip, l.split("|"))
3025 ASNlist.append((ip,asn,desc))
3028 class AS_resolver_multi(AS_resolver):
3029 resolvers_list = ( AS_resolver_cymru(),AS_resolver_riswhois(),AS_resolver_radb() )
3030 def __init__(self, *reslist):
3032 self.resolvers_list = reslist
3033 def resolve(self, *ips):
3036 for ASres in self.resolvers_list:
3037 res = ASres.resolve(*todo)
3038 resolved = [ ip for ip,asn,desc in res ]
3039 todo = [ ip for ip in todo if ip not in resolved ]
3045 class TracerouteResult(SndRcvList):
3046 def __init__(self, res=None, name="Traceroute", stats=None):
3047 PacketList.__init__(self, res, name, stats)
3048 self.graphdef = None
3055 return self.make_table(lambda (s,r): (s.sprintf("%IP.dst%:{TCP:tcp%ir,TCP.dport%}{UDP:udp%ir,UDP.dport%}{ICMP:ICMP}"),
3057 r.sprintf("%-15s,IP.src% {TCP:%TCP.flags%}{ICMP:%ir,ICMP.type%}")))
3060 def get_trace(self):
3062 for s,r in self.res:
3068 trace[d][s[IP].ttl] = r[IP].src, ICMP not in r
3069 for k in trace.values():
3070 m = filter(lambda x:k[x][1], k.keys())
3080 """Give a 3D representation of the traceroute.
3081 right button: rotate the scene
3083 left button: move the scene
3084 left button on a ball: toggle IP displaying
3085 ctrl-left button on a ball: scan ports 21,22,23,25,80 and 443 and display the result"""
3086 trace = self.get_trace()
3089 class IPsphere(visual.sphere):
3090 def __init__(self, ip, **kargs):
3091 visual.sphere.__init__(self, **kargs)
3094 self.setlabel(self.ip)
3095 def setlabel(self, txt,visible=None):
3096 if self.label is not None:
3098 visible = self.label.visible
3099 self.label.visible = 0
3100 elif visible is None:
3102 self.label=visual.label(text=txt, pos=self.pos, space=self.radius, xoffset=10, yoffset=20, visible=visible)
3104 self.label.visible ^= 1
3106 visual.scene = visual.display()
3107 visual.scene.exit_on_close(0)
3108 start = visual.box()
3115 for t in range(1,max(ttl)+1):
3119 if tr[t] not in rings[t]:
3120 rings[t].append(tr[t])
3121 tr3d[i].append(rings[t].index(tr[t]))
3123 rings[t].append(("unk",-1))
3124 tr3d[i].append(len(rings[t])-1)
3130 col = (0.75,0.75,0.75)
3132 col = visual.color.green
3134 col = visual.color.blue
3136 s = IPsphere(pos=((l-1)*visual.cos(2*i*visual.pi/l),(l-1)*visual.sin(2*i*visual.pi/l),2*t),
3139 for trlst in tr3d.values():
3143 forecol = colgen(0.625, 0.4375, 0.25, 0.125)
3144 for trlst in tr3d.values():
3145 col = forecol.next()
3148 visual.cylinder(pos=start,axis=ip.pos-start,color=col,radius=0.2)
3153 if visual.scene.kb.keys:
3154 k = visual.scene.kb.getkey()
3157 if visual.scene.mouse.events:
3158 ev = visual.scene.mouse.getevent()
3159 if ev.press == "left":
3167 a,b=sr(IP(dst=o.ip)/TCP(dport=[21,22,23,25,80,443]),timeout=2)
3170 txt = "%s:\nno results" % o.ip
3172 txt = "%s:\n" % o.ip
3174 txt += r.sprintf("{TCP:%IP.src%:%TCP.sport% %TCP.flags%}{TCPerror:%IPerror.dst%:%TCPerror.dport% %IP.src% %ir,ICMP.type%}\n")
3175 o.setlabel(txt, visible=1)
3177 if hasattr(o, "action"):
3179 elif ev.drag == "left":
3181 elif ev.drop == "left":
3184 visual.scene.center -= visual.scene.mouse.pos-movcenter
3185 movcenter = visual.scene.mouse.pos
3188 def world_trace(self):
3192 for s,r in self.res:
3194 if s.haslayer(TCP) or s.haslayer(UDP):
3195 trace_id = (s.src,s.dst,s.proto,s.dport)
3196 elif s.haslayer(ICMP):
3197 trace_id = (s.src,s.dst,s.proto,s.type)
3199 trace_id = (s.src,s.dst,s.proto,0)
3200 trace = rt.get(trace_id,{})
3201 if not r.haslayer(ICMP) or r.type != 11:
3202 if ports_done.has_key(trace_id):
3204 ports_done[trace_id] = None
3205 trace[s.ttl] = r.src
3206 rt[trace_id] = trace
3210 trace = rt[trace_id]
3212 for i in range(max(trace.keys())):
3213 ip = trace.get(i,None)
3219 # loctrace.append((ip,loc)) # no labels yet
3220 loctrace.append(loc)
3222 trt[trace_id] = loctrace
3224 tr = map(lambda x: Gnuplot.Data(x,with="lines"), trt.values())
3225 g = Gnuplot.Gnuplot()
3226 world = Gnuplot.File(conf.gnuplot_world,with="lines")
3230 def make_graph(self,ASres=None,padding=0):
3232 ASres = conf.AS_resolver
3233 self.graphASres = ASres
3234 self.graphpadding = padding
3239 for s,r in self.res:
3240 r = r[IP] or r[IPv6] or r
3241 s = s[IP] or s[IPv6] or s
3244 trace_id = (s.src,s.dst,6,s.dport)
3246 trace_id = (s.src,s.dst,17,s.dport)
3248 trace_id = (s.src,s.dst,1,s.type)
3250 trace_id = (s.src,s.dst,s.proto,0)
3251 trace = rt.get(trace_id,{})
3252 ttl = IPv6 in s and s.hlim or s.ttl
3253 if not (ICMP in r and r[ICMP].type == 11) and not (IPv6 in r and ICMPv6TimeExceeded in r):
3254 if trace_id in ports_done:
3256 ports_done[trace_id] = None
3257 p = ports.get(r.src,[])
3259 p.append(r.sprintf("<T%ir,TCP.sport%> %TCP.sport% %TCP.flags%"))
3260 trace[ttl] = r.sprintf('"%r,src%":T%ir,TCP.sport%')
3262 p.append(r.sprintf("<U%ir,UDP.sport%> %UDP.sport%"))
3263 trace[ttl] = r.sprintf('"%r,src%":U%ir,UDP.sport%')
3265 p.append(r.sprintf("<I%ir,ICMP.type%> ICMP %ICMP.type%"))
3266 trace[ttl] = r.sprintf('"%r,src%":I%ir,ICMP.type%')
3268 p.append(r.sprintf("{IP:<P%ir,proto%> IP %proto%}{IPv6:<P%ir,nh%> IPv6 %nh%}"))
3269 trace[ttl] = r.sprintf('"%r,src%":{IP:P%ir,proto%}{IPv6:P%ir,nh%}')
3272 trace[ttl] = r.sprintf('"%r,src%"')
3273 rt[trace_id] = trace
3275 # Fill holes with unk%i nodes
3276 unknown_label = incremental_label("unk%i")
3282 for n in range(min(k), max(k)):
3283 if not trace.has_key(n):
3284 trace[n] = unknown_label.next()
3285 if not ports_done.has_key(rtk):
3286 if rtk[2] == 1: #ICMP
3287 bh = "%s %i/icmp" % (rtk[1],rtk[3])
3288 elif rtk[2] == 6: #TCP
3289 bh = "%s %i/tcp" % (rtk[1],rtk[3])
3290 elif rtk[2] == 17: #UDP
3291 bh = '%s %i/udp' % (rtk[1],rtk[3])
3293 bh = '%s %i/proto' % (rtk[1],rtk[2])
3297 trace[max(k)+1] = bh
3298 blackholes.append(bh)
3301 ASN_query_list = dict.fromkeys(map(lambda x:x.rsplit(" ",1)[0],ips)).keys()
3305 ASNlist = ASres.resolve(*ASN_query_list)
3309 for ip,asn,desc, in ASNlist:
3312 iplist = ASNs.get(asn,[])
3316 iplist.append(bhip[ip])
3323 backcolorlist=colgen("60","86","ba","ff")
3324 forecolorlist=colgen("a0","70","40","20")
3326 s = "digraph trace {\n"
3328 s += "\n\tnode [shape=ellipse,color=black,style=solid];\n\n"
3330 s += "\n#ASN clustering\n"
3332 s += '\tsubgraph cluster_%s {\n' % asn
3333 col = backcolorlist.next()
3334 s += '\t\tcolor="#%s%s%s";' % col
3335 s += '\t\tnode [fillcolor="#%s%s%s",style=filled];' % col
3336 s += '\t\tfontsize = 10;'
3337 s += '\t\tlabel = "%s\\n[%s]"\n' % (asn,ASDs[asn])
3338 for ip in ASNs[asn]:
3340 s += '\t\t"%s";\n'%ip
3348 s += '\t"%s" [shape=record,color=black,fillcolor=green,style=filled,label="%s|%s"];\n' % (p,p,"|".join(ports[p]))
3350 s += "\n#Blackholes\n"
3351 for bh in blackholes:
3352 s += '\t%s [shape=octagon,color=black,fillcolor=red,style=filled];\n' % bh
3357 for snd,rcv in self.res:
3358 if rcv.src not in ports and rcv.haslayer(Padding):
3359 p = rcv.getlayer(Padding).load
3360 if p != "\x00"*len(p):
3363 s += '\t"%s" [shape=triangle,color=black,fillcolor=red,style=filled];\n' % rcv
3367 s += "\n\tnode [shape=ellipse,color=black,style=solid];\n\n"
3371 s += "#---[%s\n" % `rtk`
3372 s += '\t\tedge [color="#%s%s%s"];\n' % forecolorlist.next()
3375 for n in range(min(k), max(k)):
3376 s += '\t%s ->\n' % trace[n]
3377 s += '\t%s;\n' % trace[max(k)]
3382 def graph(self, ASres=None, padding=0, **kargs):
3383 """x.graph(ASres=conf.AS_resolver, other args):
3384 ASres=None : no AS resolver => no clustering
3385 ASres=AS_resolver() : default whois AS resolver (riswhois.ripe.net)
3386 ASres=AS_resolver_cymru(): use whois.cymru.com whois database
3387 ASres=AS_resolver(server="whois.ra.net")
3388 type: output type (svg, ps, gif, jpg, etc.), passed to dot's "-T" option
3389 target: filename or redirect. Defaults pipe to Imagemagick's display program
3390 prog: which graphviz program to use"""
3392 ASres = conf.AS_resolver
3393 if (self.graphdef is None or
3394 self.graphASres != ASres or
3395 self.graphpadding != padding):
3396 self.make_graph(ASres,padding)
3398 return do_graph(self.graphdef, **kargs)
3408 """For more informations on how this work, please refer to
3409 http://www.secdev.org/projects/scapy/files/scapydoc.pdf
3410 chapter ``Adding a New Field''"""
3413 def __init__(self, name, default, fmt="H"):
3415 if fmt[0] in "@=<>!":
3419 self.default = self.any2i(None,default)
3420 self.sz = struct.calcsize(self.fmt)
3423 def register_owner(self, cls):
3424 self.owners.append(cls)
3426 def i2len(self, pkt, x):
3427 """Convert internal value to a length usable by a FieldLenField"""
3429 def i2count(self, pkt, x):
3430 """Convert internal value to a number of elements usable by a FieldLenField.
3431 Always 1 except for list fields"""
3433 def h2i(self, pkt, x):
3434 """Convert human value to internal value"""
3436 def i2h(self, pkt, x):
3437 """Convert internal value to human value"""
3439 def m2i(self, pkt, x):
3440 """Convert machine value to internal value"""
3442 def i2m(self, pkt, x):
3443 """Convert internal value to machine value"""
3447 def any2i(self, pkt, x):
3448 """Try to understand the most input values possible and make an internal value from them"""
3449 return self.h2i(pkt, x)
3450 def i2repr(self, pkt, x):
3451 """Convert internal value to a nice representation"""
3454 return repr(self.i2h(pkt,x))
3455 def addfield(self, pkt, s, val):
3456 """Add an internal value to a string"""
3457 return s+struct.pack(self.fmt, self.i2m(pkt,val))
3458 def getfield(self, pkt, s):
3459 """Extract an internal value from a string"""
3460 return s[self.sz:], self.m2i(pkt, struct.unpack(self.fmt, s[:self.sz])[0])
3461 def do_copy(self, x):
3462 if hasattr(x, "copy"):
3466 for i in xrange(len(x)):
3467 if isinstance(x[i], Packet):
3471 return "<Field (%s).%s>" % (",".join(x.__name__ for x in self.owners),self.name)
3473 return copy.deepcopy(self)
3475 """Return a volatile object whose value is both random and suitable for this field"""
3478 return {"B":RandByte,"H":RandShort,"I":RandInt, "Q":RandLong}[fmtt]()
3480 if self.fmt[0] in "0123456789":
3481 l = int(self.fmt[:-1])
3483 l = int(self.fmt[1:-1])
3486 warning("no random class for [%s] (fmt=%s)." % (self.name, self.fmt))
3493 def __init__(self, fld):
3495 def __getattr__(self, attr):
3496 return getattr(self.fld,attr)
3498 return hash(self.fld)
3499 def __eq__(self, other):
3500 return self.fld == other
3505 def __init__(self, fld, action_method, **kargs):
3507 self._action_method = action_method
3508 self._privdata = kargs
3509 def any2i(self, pkt, val):
3510 getattr(pkt, self._action_method)(val, self._fld, **self._privdata)
3511 return getattr(self._fld, "any2i")(pkt, val)
3512 def __getattr__(self, attr):
3513 return getattr(self._fld,attr)
3516 class ConditionalField:
3518 def __init__(self, fld, cond):
3521 def _evalcond(self,pkt):
3522 return self.cond(pkt)
3524 def getfield(self, pkt, s):
3525 if self._evalcond(pkt):
3526 return self.fld.getfield(pkt,s)
3530 def addfield(self, pkt, s, val):
3531 if self._evalcond(pkt):
3532 return self.fld.addfield(pkt,s,val)
3535 def __getattr__(self, attr):
3536 return getattr(self.fld,attr)
3540 """Add bytes after the proxified field so that it ends at the specified
3541 alignment from its begining"""
3543 def __init__(self, fld, align, padwith=None):
3546 self._padwith = padwith or ""
3548 def addfield(self, pkt, s, val):
3549 sval = self._fld.addfield(pkt, "", val)
3550 return s+sval+struct.pack("%is" % (-len(sval)%self._align), self._padwith)
3552 def __getattr__(self, attr):
3553 return getattr(self._fld,attr)
3556 class MACField(Field):
3557 def __init__(self, name, default):
3558 Field.__init__(self, name, default, "6s")
3559 def i2m(self, pkt, x):
3561 return "\0\0\0\0\0\0"
3563 def m2i(self, pkt, x):
3565 def any2i(self, pkt, x):
3566 if type(x) is str and len(x) is 6:
3567 x = self.m2i(pkt, x)
3569 def i2repr(self, pkt, x):
3570 x = self.i2h(pkt, x)
3571 if self in conf.resolve:
3572 x = conf.manufdb._resolve_MAC(x)
3577 class DestMACField(MACField):
3578 def __init__(self, name):
3579 MACField.__init__(self, name, None)
3580 def i2h(self, pkt, x):
3583 if isinstance(pkt.payload, IPv6):
3584 dstip = pkt.payload.dst
3585 elif isinstance(pkt.payload, IP):
3586 dstip = pkt.payload.dst
3587 elif isinstance(pkt.payload, ARP):
3588 dstip = pkt.payload.pdst
3589 if isinstance(dstip, Gen):
3590 dstip = dstip.__iter__().next()
3591 if dstip is not None:
3592 if isinstance(pkt.payload, IPv6):
3593 x = getmacbyip6(dstip, chainCC=1)
3595 x = getmacbyip(dstip, chainCC=1)
3597 x = "ff:ff:ff:ff:ff:ff"
3598 warning("Mac address to reach %s not found\n"%dstip)
3599 return MACField.i2h(self, pkt, x)
3600 def i2m(self, pkt, x):
3601 return MACField.i2m(self, pkt, self.i2h(pkt, x))
3603 class SourceMACField(MACField):
3604 def __init__(self, name):
3605 MACField.__init__(self, name, None)
3606 def i2h(self, pkt, x):
3609 if isinstance(pkt.payload, IPv6):
3610 dstip = pkt.payload.dst
3611 elif isinstance(pkt.payload, IP):
3612 dstip = pkt.payload.dst
3613 elif isinstance(pkt.payload, ARP):
3614 dstip = pkt.payload.pdst
3615 if isinstance(dstip, Gen):
3616 dstip = dstip.__iter__().next()
3617 if dstip is not None:
3618 if isinstance(pkt.payload, IPv6):
3619 iff,a,nh = conf.route6.route(dstip)
3621 iff,a,gw = conf.route.route(dstip)
3623 x = get_if_hwaddr(iff)
3627 x = "00:00:00:00:00:00"
3628 return MACField.i2h(self, pkt, x)
3629 def i2m(self, pkt, x):
3630 return MACField.i2m(self, pkt, self.i2h(pkt, x))
3632 class ARPSourceMACField(MACField):
3633 def __init__(self, name):
3634 MACField.__init__(self, name, None)
3635 def i2h(self, pkt, x):
3638 if isinstance(dstip, Gen):
3639 dstip = dstip.__iter__().next()
3640 if dstip is not None:
3641 iff,a,gw = conf.route.route(dstip)
3643 x = get_if_hwaddr(iff)
3647 x = "00:00:00:00:00:00"
3648 return MACField.i2h(self, pkt, x)
3649 def i2m(self, pkt, x):
3650 return MACField.i2m(self, pkt, self.i2h(pkt, x))
3652 class Dot11AddrMACField(MACField):
3653 def is_applicable(self, pkt):
3655 def addfield(self, pkt, s, val):
3656 if self.is_applicable(pkt):
3657 return MACField.addfield(self, pkt, s, val)
3660 def getfield(self, pkt, s):
3661 if self.is_applicable(pkt):
3662 return MACField.getfield(self, pkt, s)
3666 class Dot11Addr2MACField(Dot11AddrMACField):
3667 def is_applicable(self, pkt):
3669 return pkt.subtype in [ 0xb, 0xa, 0xe, 0xf] # RTS, PS-Poll, CF-End, CF-End+CF-Ack
3672 class Dot11Addr3MACField(Dot11AddrMACField):
3673 def is_applicable(self, pkt):
3674 if pkt.type in [0,2]:
3678 class Dot11Addr4MACField(Dot11AddrMACField):
3679 def is_applicable(self, pkt):
3681 if pkt.FCfield & 0x3 == 0x3: # To-DS and From-DS are set
3685 class IPField(Field):
3686 def __init__(self, name, default):
3687 Field.__init__(self, name, default, "4s")
3688 def h2i(self, pkt, x):
3692 except socket.error:
3694 elif type(x) is list:
3695 x = [self.h2i(pkt, n) for n in x]
3697 def resolve(self, x):
3698 if self in conf.resolve:
3700 ret = socket.gethostbyaddr(x)[0]
3707 def i2m(self, pkt, x):
3709 def m2i(self, pkt, x):
3711 def any2i(self, pkt, x):
3712 return self.h2i(pkt,x)
3713 def i2repr(self, pkt, x):
3714 return self.resolve(self.i2h(pkt, x))
3718 class SourceIPField(IPField):
3719 def __init__(self, name, dstname):
3720 IPField.__init__(self, name, None)
3721 self.dstname = dstname
3722 def i2m(self, pkt, x):
3724 iff,x,gw = conf.route.route(getattr(pkt,self.dstname))
3725 return IPField.i2m(self, pkt, x)
3726 def i2h(self, pkt, x):
3728 dst=getattr(pkt,self.dstname)
3729 if isinstance(dst,Gen):
3730 r = map(conf.route.route, dst)
3735 warning("More than one possible route for %s"%repr(dst))
3738 iff,x,gw = conf.route.route(dst)
3739 return IPField.i2h(self, pkt, x)
3744 class ByteField(Field):
3745 def __init__(self, name, default):
3746 Field.__init__(self, name, default, "B")
3748 class XByteField(ByteField):
3749 def i2repr(self, pkt, x):
3752 return lhex(self.i2h(pkt, x))
3754 class X3BytesField(XByteField):
3755 def __init__(self, name, default):
3756 Field.__init__(self, name, default, "!I")
3757 def addfield(self, pkt, s, val):
3758 return s+struct.pack(self.fmt, self.i2m(pkt,val))[1:4]
3759 def getfield(self, pkt, s):
3760 return s[3:], self.m2i(pkt, struct.unpack(self.fmt, "\x00"+s[:3])[0])
3763 class ShortField(Field):
3764 def __init__(self, name, default):
3765 Field.__init__(self, name, default, "H")
3767 class LEShortField(Field):
3768 def __init__(self, name, default):
3769 Field.__init__(self, name, default, "<H")
3771 class XShortField(ShortField):
3772 def i2repr(self, pkt, x):
3775 return lhex(self.i2h(pkt, x))
3778 class IntField(Field):
3779 def __init__(self, name, default):
3780 Field.__init__(self, name, default, "I")
3782 class SignedIntField(Field):
3783 def __init__(self, name, default):
3784 Field.__init__(self, name, default, "i")
3788 class LEIntField(Field):
3789 def __init__(self, name, default):
3790 Field.__init__(self, name, default, "<I")
3792 class LESignedIntField(Field):
3793 def __init__(self, name, default):
3794 Field.__init__(self, name, default, "<i")
3798 class XIntField(IntField):
3799 def i2repr(self, pkt, x):
3802 return lhex(self.i2h(pkt, x))
3805 class LongField(Field):
3806 def __init__(self, name, default):
3807 Field.__init__(self, name, default, "Q")
3809 class XLongField(LongField):
3810 def i2repr(self, pkt, x):
3813 return lhex(self.i2h(pkt, x))
3815 class IEEEFloatField(Field):
3816 def __init__(self, name, default):
3817 Field.__init__(self, name, default, "f")
3819 class IEEEDoubleField(Field):
3820 def __init__(self, name, default):
3821 Field.__init__(self, name, default, "d")
3824 def FIELD_LENGTH_MANAGEMENT_DEPRECATION(x):
3826 for tb in traceback.extract_stack()+[("??",-1,None,"")]:
3828 if line.startswith("fields_desc"):
3832 log_loading.warning("Deprecated use of %s (%s l. %i). See http://trac.secdev.org/scapy/wiki/LengthFields" % (x,f,l))
3834 class StrField(Field):
3835 def __init__(self, name, default, fmt="H", remain=0, shift=0):
3836 Field.__init__(self,name,default,fmt)
3837 self.remain = remain
3840 FIELD_LENGTH_MANAGEMENT_DEPRECATION(self.__class__.__name__)
3841 def i2len(self, pkt, i):
3842 return len(i)+self.shift
3843 def i2m(self, pkt, x):
3846 elif type(x) is not str:
3849 def addfield(self, pkt, s, val):
3850 return s+self.i2m(pkt, val)
3851 def getfield(self, pkt, s):
3852 if self.remain == 0:
3853 return "",self.m2i(pkt, s)
3855 return s[-self.remain:],self.m2i(pkt, s[:-self.remain])
3857 return RandBin(RandNum(0,1200))
3859 class PacketField(StrField):
3861 def __init__(self, name, default, cls, remain=0, shift=0):
3862 StrField.__init__(self, name, default, remain=remain, shift=shift)
3864 def i2m(self, pkt, i):
3866 def m2i(self, pkt, m):
3868 def getfield(self, pkt, s):
3869 i = self.m2i(pkt, s)
3871 if i.haslayer(Padding):
3872 r = i.getlayer(Padding)
3873 del(r.underlayer.payload)
3877 class PacketLenField(PacketField):
3879 def __init__(self, name, default, cls, fld=None, length_from=None, shift=0):
3880 PacketField.__init__(self, name, default, cls, shift=shift)
3881 self.length_from = length_from
3882 if fld is not None or shift != 0:
3883 FIELD_LENGTH_MANAGEMENT_DEPRECATION(self.__class__.__name__)
3884 self.count_from = lambda pkt,fld=fld,shift=shift: getattr(pkt,fld)-shift
3885 def getfield(self, pkt, s):
3886 l = self.length_from(pkt)
3887 i = self.m2i(pkt, s[:l])
3891 class PacketListField(PacketField):
3894 def __init__(self, name, default, cls, fld=None, count_from=None, length_from=None, shift=0):
3896 default = [] # Create a new list for each instance
3897 PacketField.__init__(self, name, default, cls, shift=shift)
3898 self.count_from = count_from
3899 self.length_from = length_from
3901 if fld is not None or shift != 0:
3902 FIELD_LENGTH_MANAGEMENT_DEPRECATION(self.__class__.__name__)
3904 self.count_from = lambda pkt,fld=fld,shift=shift: getattr(pkt,fld)-shift
3906 def any2i(self, pkt, x):
3907 if type(x) is not list:
3911 def i2count(self, pkt, val):
3912 if type(val) is list:
3915 def i2len(self, pkt, val):
3916 return sum( len(p) for p in val )
3917 def do_copy(self, x):
3918 return map(lambda p:p.copy(), x)
3919 def getfield(self, pkt, s):
3921 if self.length_from is not None:
3922 l = self.length_from(pkt)
3923 elif self.count_from is not None:
3924 c = self.count_from(pkt)
3930 remain,ret = s[:l],s[l:]
3936 p = self.m2i(pkt,remain)
3940 del(pad.underlayer.payload)
3944 return remain+ret,lst
3945 def addfield(self, pkt, s, val):
3946 return s+"".join(map(str, val))
3949 class StrFixedLenField(StrField):
3950 def __init__(self, name, default, length=None, length_from=None, shift=0):
3951 StrField.__init__(self, name, default, shift=shift)
3952 self.length_from = length_from
3953 if length is not None:
3954 self.length_from = lambda pkt,length=length: length
3955 def getfield(self, pkt, s):
3956 l = self.length_from(pkt)
3957 return s[l:], self.m2i(pkt,s[:l])
3958 def addfield(self, pkt, s, val):
3959 l = self.length_from(pkt)
3960 return s+struct.pack("%is"%l,self.i2m(pkt, val))
3963 l = self.length_from(None)
3968 class NetBIOSNameField(StrFixedLenField):
3969 def __init__(self, name, default, length=31, shift=0):
3970 StrFixedLenField.__init__(self, name, default, length, shift=shift)
3971 def i2m(self, pkt, x):
3972 l = self.length_from(pkt)/2
3977 x = "".join(map(lambda x: chr(0x41+(ord(x)>>4))+chr(0x41+(ord(x)&0xf)), x))
3980 def m2i(self, pkt, x):
3981 x = x.strip("\x00").strip(" ")
3982 return "".join(map(lambda x,y: chr((((ord(x)-1)&0xf)<<4)+((ord(y)-1)&0xf)), x[::2],x[1::2]))
3984 class StrLenField(StrField):
3985 def __init__(self, name, default, fld=None, length_from=None, shift=0):
3986 StrField.__init__(self, name, default, shift=shift)
3987 self.length_from = length_from
3988 if fld is not None or shift != 0:
3989 FIELD_LENGTH_MANAGEMENT_DEPRECATION(self.__class__.__name__)
3990 self.length_from = lambda pkt,fld=fld,shift=shift: getattr(pkt,fld)-shift
3991 def getfield(self, pkt, s):
3992 l = self.length_from(pkt)
3993 return s[l:], self.m2i(pkt,s[:l])
3995 class FieldListField(Field):
3997 def __init__(self, name, default, field, fld=None, shift=0, length_from=None, count_from=None):
3999 default = [] # Create a new list for each instance
4000 Field.__init__(self, name, default)
4001 self.count_from = count_from
4002 self.length_from = length_from
4004 if fld is not None or shift != 0:
4005 FIELD_LENGTH_MANAGEMENT_DEPRECATION(self.__class__.__name__)
4006 self.count_from = lambda pkt,fld=fld,shift=shift: getattr(pkt,fld)-shift
4009 def i2count(self, pkt, val):
4010 if type(val) is list:
4013 def i2len(self, pkt, val):
4014 return sum( self.field.i2len(pkt,v) for v in val )
4016 def i2m(self, pkt, val):
4020 def any2i(self, pkt, x):
4021 if type(x) is not list:
4025 def addfield(self, pkt, s, val):
4026 val = self.i2m(pkt, val)
4028 s = self.field.addfield(pkt, s, v)
4030 def getfield(self, pkt, s):
4032 if self.length_from is not None:
4033 l = self.length_from(pkt)
4034 elif self.count_from is not None:
4035 c = self.count_from(pkt)
4047 s,v = self.field.getfield(pkt, s)
4051 class FieldLenField(Field):
4052 def __init__(self, name, default, length_of=None, fmt = "H", count_of=None, adjust=lambda pkt,x:x, fld=None):
4053 Field.__init__(self, name, default, fmt)
4054 self.length_of=length_of
4055 self.count_of=count_of
4058 FIELD_LENGTH_MANAGEMENT_DEPRECATION(self.__class__.__name__)
4059 self.length_of = fld
4060 def i2m(self, pkt, x):
4062 if self.length_of is not None:
4063 fld,fval = pkt.getfield_and_val(self.length_of)
4064 f = fld.i2len(pkt, fval)
4066 fld,fval = pkt.getfield_and_val(self.count_of)
4067 f = fld.i2count(pkt, fval)
4068 x = self.adjust(pkt,f)
4071 # see http://www.iana.org/assignments/ipsec-registry for details
4072 ISAKMPAttributeTypes= { "Encryption": (1, { "DES-CBC" : 1,
4075 "RC5-R16-B64-CBC" : 4,
4079 "CAMELLIA-CBC" : 8, }, 0),
4080 "Hash": (2, { "MD5": 1,
4085 "SHA2-512": 6,}, 0),
4086 "Authentication":(3, { "PSK": 1,
4089 "RSA Encryption": 4,
4090 "RSA Encryption Revised": 5,
4091 "ElGamal Encryption": 6,
4092 "ElGamal Encryption Revised": 7,
4094 "HybridInitRSA": 64221,
4095 "HybridRespRSA": 64222,
4096 "HybridInitDSS": 64223,
4097 "HybridRespDSS": 64224,
4098 "XAUTHInitPreShared": 65001,
4099 "XAUTHRespPreShared": 65002,
4100 "XAUTHInitDSS": 65003,
4101 "XAUTHRespDSS": 65004,
4102 "XAUTHInitRSA": 65005,
4103 "XAUTHRespRSA": 65006,
4104 "XAUTHInitRSAEncryption": 65007,
4105 "XAUTHRespRSAEncryption": 65008,
4106 "XAUTHInitRSARevisedEncryption": 65009,
4107 "XAUTHRespRSARevisedEncryptio": 65010, }, 0),
4108 "GroupDesc": (4, { "768MODPgr" : 1,
4117 "8192MODPgr" : 18, }, 0),
4118 "GroupType": (5, {"MODP": 1,
4121 "GroupPrime": (6, {}, 1),
4122 "GroupGenerator1":(7, {}, 1),
4123 "GroupGenerator2":(8, {}, 1),
4124 "GroupCurveA": (9, {}, 1),
4125 "GroupCurveB": (10, {}, 1),
4126 "LifeType": (11, {"Seconds": 1,
4127 "Kilobytes": 2, }, 0),
4128 "LifeDuration": (12, {}, 1),
4130 "KeyLength": (14, {}, 0),
4131 "FieldSize": (15, {}, 0),
4132 "GroupOrder": (16, {}, 1),
4135 # the name 'ISAKMPTransformTypes' is actually a misnomer (since the table
4136 # holds info for all ISAKMP Attribute types, not just transforms, but we'll
4137 # keep it for backwards compatibility... for now at least
4138 ISAKMPTransformTypes = ISAKMPAttributeTypes
4140 ISAKMPTransformNum = {}
4141 for n in ISAKMPTransformTypes:
4142 val = ISAKMPTransformTypes[n]
4146 ISAKMPTransformNum[val[0]] = (n,tmp, val[2])
4153 class ISAKMPTransformSetField(StrLenField):
4155 def type2num(self, (typ,val)):
4156 type_val,enc_dict,tlv = ISAKMPTransformTypes.get(typ, (typ,{},0))
4157 val = enc_dict.get(val, val)
4161 warning("%r should not be TLV but is too big => using TLV encoding" % typ)
4170 return struct.pack("!HH",type_val, val)+s
4171 def num2type(self, typ, enc):
4172 val = ISAKMPTransformNum.get(typ,(typ,{}))
4173 enc = val[1].get(enc,enc)
4175 def i2m(self, pkt, i):
4178 i = map(self.type2num, i)
4180 def m2i(self, pkt, m):
4181 # I try to ensure that we don't read off the end of our packet based
4182 # on bad length fields we're provided in the packet. There are still
4183 # conditions where struct.unpack() may not get enough packet data, but
4184 # worst case that should result in broken attributes (which would
4185 # be expected). (wam)
4188 trans_type, = struct.unpack("!H", m[:2])
4189 is_tlv = not (trans_type & 0x8000)
4191 # We should probably check to make sure the attribute type we
4192 # are looking at is allowed to have a TLV format and issue a
4193 # warning if we're given an TLV on a basic attribute.
4194 value_len, = struct.unpack("!H", m[2:4])
4195 if value_len+4 > len(m):
4196 warning("Bad length for ISAKMP tranform type=%#6x" % trans_type)
4197 value = m[4:4+value_len]
4198 value = reduce(lambda x,y: (x<<8L)|y, struct.unpack("!%s" % ("B"*len(value),), value),0)
4200 trans_type &= 0x7fff
4202 value, = struct.unpack("!H", m[2:4])
4204 lst.append(self.num2type(trans_type, value))
4206 warning("Extra bytes after ISAKMP transform dissection [%r]" % m)
4209 class StrNullField(StrField):
4210 def addfield(self, pkt, s, val):
4211 return s+self.i2m(pkt, val)+"\x00"
4212 def getfield(self, pkt, s):
4217 return s[l+1:],self.m2i(pkt, s[:l])
4219 return RandTermString(RandNum(0,1200),"\x00")
4221 class StrStopField(StrField):
4222 def __init__(self, name, default, stop, additionnal=0):
4223 Field.__init__(self, name, default)
4225 self.additionnal=additionnal
4226 def getfield(self, pkt, s):
4227 l = s.find(self.stop)
4230 # raise Scapy_Exception,"StrStopField: stop value [%s] not found" %stop
4231 l += len(self.stop)+self.additionnal
4234 return RandTermString(RandNum(0,1200),self.stop)
4236 class LenField(Field):
4237 def i2m(self, pkt, x):
4239 x = len(pkt.payload)
4242 class BCDFloatField(Field):
4243 def i2m(self, pkt, x):
4245 def m2i(self, pkt, x):
4248 class BitField(Field):
4249 def __init__(self, name, default, size):
4250 Field.__init__(self, name, default)
4252 self.size = abs(size)
4253 def reverse(self, val):
4255 val = socket.ntohs(val)
4256 elif self.size == 32:
4257 val = socket.ntohl(val)
4260 def addfield(self, pkt, s, val):
4261 val = self.i2m(pkt, val)
4262 if type(s) is tuple:
4268 val = self.reverse(val)
4270 v |= val & ((1L<<self.size) - 1)
4271 bitsdone += self.size
4272 while bitsdone >= 8:
4274 s = s+struct.pack("!B", v >> bitsdone)
4275 v &= (1L<<bitsdone)-1
4280 def getfield(self, pkt, s):
4281 if type(s) is tuple:
4285 # we don't want to process all the string
4286 nb_bytes = (self.size+bn-1)/8 + 1
4289 # split the substring byte by byte
4290 bytes = struct.unpack('!%dB' % nb_bytes , w)
4293 for c in range(nb_bytes):
4294 b |= long(bytes[c]) << (nb_bytes-c-1)*8
4296 # get rid of high order bits
4297 b &= (1L << (nb_bytes*8-bn)) - 1
4299 # remove low order bits
4300 b = b >> (nb_bytes*8 - self.size - bn)
4308 b = self.m2i(pkt, b)
4314 return RandNum(0,2**self.size-1)
4317 class BitFieldLenField(BitField):
4318 def __init__(self, name, default, size, length_of=None, count_of=None, adjust=lambda pkt,x:x):
4319 BitField.__init__(self, name, default, size)
4320 self.length_of=length_of
4321 self.count_of=count_of
4323 def i2m(self, pkt, x):
4324 return FieldLenField.i2m.im_func(self, pkt, x)
4327 class XBitField(BitField):
4328 def i2repr(self, pkt, x):
4329 return lhex(self.i2h(pkt,x))
4332 class EnumField(Field):
4333 def __init__(self, name, default, enum, fmt = "H"):
4336 if type(enum) is list:
4337 keys = xrange(len(enum))
4340 if filter(lambda x: type(x) is str, keys):
4345 Field.__init__(self, name, default, fmt)
4346 def any2i_one(self, pkt, x):
4350 def i2repr_one(self, pkt, x):
4351 if self not in conf.noenum and not isinstance(x,VolatileValue) and x in self.i2s:
4355 def any2i(self, pkt, x):
4357 return map(lambda z,pkt=pkt:self.any2i_one(pkt,z), x)
4359 return self.any2i_one(pkt,x)
4360 def i2repr(self, pkt, x):
4362 return map(lambda z,pkt=pkt:self.i2repr_one(pkt,z), x)
4364 return self.i2repr_one(pkt,x)
4366 class CharEnumField(EnumField):
4367 def __init__(self, name, default, enum, fmt = "1s"):
4368 EnumField.__init__(self, name, default, enum, fmt)
4370 if k and len(k[0]) != 1:
4371 self.i2s,self.s2i = self.s2i,self.i2s
4372 def any2i_one(self, pkt, x):
4377 class BitEnumField(BitField,EnumField):
4378 def __init__(self, name, default, size, enum):
4379 EnumField.__init__(self, name, default, enum)
4381 self.size = abs(size)
4382 def any2i(self, pkt, x):
4383 return EnumField.any2i(self, pkt, x)
4384 def i2repr(self, pkt, x):
4385 return EnumField.i2repr(self, pkt, x)
4387 class ShortEnumField(EnumField):
4388 def __init__(self, name, default, enum):
4389 EnumField.__init__(self, name, default, enum, "H")
4391 class LEShortEnumField(EnumField):
4392 def __init__(self, name, default, enum):
4393 EnumField.__init__(self, name, default, enum, "<H")
4395 class ByteEnumField(EnumField):
4396 def __init__(self, name, default, enum):
4397 EnumField.__init__(self, name, default, enum, "B")
4399 class IntEnumField(EnumField):
4400 def __init__(self, name, default, enum):
4401 EnumField.__init__(self, name, default, enum, "I")
4403 class SignedIntEnumField(EnumField):
4404 def __init__(self, name, default, enum):
4405 EnumField.__init__(self, name, default, enum, "i")
4409 class LEIntEnumField(EnumField):
4410 def __init__(self, name, default, enum):
4411 EnumField.__init__(self, name, default, enum, "<I")
4413 class XShortEnumField(ShortEnumField):
4414 def i2repr_one(self, pkt, x):
4415 if self not in conf.noenum and not isinstance(x,VolatileValue) and x in self.i2s:
4419 # Little endian long field
4420 class LELongField(Field):
4421 def __init__(self, name, default):
4422 Field.__init__(self, name, default, "<Q")
4424 # Little endian fixed length field
4425 class LEFieldLenField(FieldLenField):
4426 def __init__(self, name, default, length_of=None, fmt = "<H", count_of=None, adjust=lambda pkt,x:x, fld=None):
4427 FieldLenField.__init__(self, name, default, length_of=length_of, fmt=fmt, fld=fld, adjust=adjust)
4430 class FlagsField(BitField):
4431 def __init__(self, name, default, size, names):
4432 BitField.__init__(self, name, default, size)
4433 self.multi = type(names) is list
4435 self.names = map(lambda x:[x], names)
4438 def any2i(self, pkt, x):
4441 x = map(lambda y:[y], x.split("+"))
4444 y |= 1 << self.names.index(i)
4447 def i2repr(self, pkt, x):
4448 if type(x) is list or type(x) is tuple:
4468 class IPoptionsField(StrField):
4469 def i2m(self, pkt, x):
4470 return x+"\x00"*(3-((len(x)+3)%4))
4471 def getfield(self, pkt, s):
4472 opsz = (pkt.ihl-5)*4
4474 warning("bad ihl (%i). Assuming ihl=5"%pkt.ihl)
4476 return s[opsz:],s[:opsz]
4478 return RandBin(RandNum(0,39))
4485 3 : ("WScale","!B"),
4486 4 : ("SAckOK",None),
4488 8 : ("Timestamp","!II"),
4489 14 : ("AltChkSum","!BH"),
4490 15 : ("AltChkSumOpt",None)
4503 class TCPOptionsField(StrField):
4505 def getfield(self, pkt, s):
4506 opsz = (pkt.dataofs-5)*4
4508 warning("bad dataofs (%i). Assuming dataofs=5"%pkt.dataofs)
4510 return s[opsz:],self.m2i(pkt,s[:opsz])
4511 def m2i(self, pkt, x):
4516 opt.append(("EOL",None))
4520 opt.append(("NOP",None))
4525 warning("Malformed TCP option (announced length is %i)" % olen)
4528 if TCPOptions[0].has_key(onum):
4529 oname, ofmt = TCPOptions[0][onum]
4531 ofmt += "%iI" % (len(oval)/4)
4532 if ofmt and struct.calcsize(ofmt) == len(oval):
4533 oval = struct.unpack(ofmt, oval)
4536 opt.append((oname, oval))
4538 opt.append((onum, oval))
4542 def i2m(self, pkt, x):
4544 for oname,oval in x:
4545 if type(oname) is str:
4549 elif oname == "EOL":
4552 elif TCPOptions[1].has_key(oname):
4553 onum = TCPOptions[1][oname]
4554 ofmt = TCPOptions[0][onum][1]
4556 ofmt += "%iI" % len(oval)
4557 if ofmt is not None and (type(oval) is not str or "s" in ofmt):
4558 if type(oval) is not tuple:
4560 oval = struct.pack(ofmt, *oval)
4562 warning("option [%s] unknown. Skipped."%oname)
4566 if type(oval) is not str:
4567 warning("option [%i] is not string."%onum)
4569 opt += chr(onum)+chr(2+len(oval))+oval
4570 return opt+"\x00"*(3-((len(opt)+3)%4))
4575 class DNSStrField(StrField):
4576 def i2m(self, pkt, x):
4577 x = [k[:63] for k in x.split(".")] # Truncate chunks that cannont be encoded (more than 63 bytes..)
4578 x = map(lambda y: chr(len(y))+y, x)
4583 def getfield(self, pkt, s):
4591 raise Scapy_Exception("DNS message can't be compressed at this point!")
4598 class DNSRRCountField(ShortField):
4600 def __init__(self, name, default, rr):
4601 ShortField.__init__(self, name, default)
4603 def _countRR(self, pkt):
4604 x = getattr(pkt,self.rr)
4606 while isinstance(x, DNSRR) or isinstance(x, DNSQR):
4611 def i2m(self, pkt, x):
4613 x = self._countRR(pkt)
4615 def i2h(self, pkt, x):
4617 x = self._countRR(pkt)
4627 warning("DNS RR prematured end (ofs=%i, len=%i)"%(p,len(s)))
4635 warning("DNS incomplete jump token at (ofs=%i)" % p)
4637 p = ((l & 0x3f) << 8) + ord(s[p]) - 12
4639 warning("DNS decompression loop detected")
4644 name += s[p:p+l]+"."
4653 class DNSRRField(StrField):
4655 def __init__(self, name, countfld, passon=1):
4656 StrField.__init__(self, name, None)
4657 self.countfld = countfld
4658 self.passon = passon
4659 def i2m(self, pkt, x):
4663 def decodeRR(self, name, s, p):
4665 type,cls,ttl,rdlen = struct.unpack("!HHIH", ret)
4667 rr = DNSRR("\x00"+ret+s[p:p+rdlen])
4668 if rr.type in [2, 3, 4, 5]:
4669 rr.rdata = DNSgetstr(s,p)[0]
4676 def getfield(self, pkt, s):
4677 if type(s) is tuple :
4682 c = getattr(pkt, self.countfld)
4684 warning("wrong value: DNS.%s=%i" % (self.countfld,c))
4688 name,p = DNSgetstr(s,p)
4689 rr,p = self.decodeRR(name, s, p)
4700 class DNSQRField(DNSRRField):
4702 def decodeRR(self, name, s, p):
4705 rr = DNSQR("\x00"+ret)
4711 class RDataField(StrLenField):
4712 def m2i(self, pkt, s):
4715 family = socket.AF_INET
4716 elif pkt.type == 28:
4717 family = socket.AF_INET6
4718 elif pkt.type == 12:
4719 s = DNSgetstr(s, 0)[0]
4720 if family is not None:
4721 s = inet_ntop(family, s)
4723 def i2m(self, pkt, s):
4727 elif pkt.type == 28:
4729 s = inet_pton(socket.AF_INET6, s)
4730 elif pkt.type in [2,3,4,5]:
4731 s = "".join(map(lambda x: chr(len(x))+x, s.split(".")))
4736 class RDLenField(Field):
4737 def __init__(self, name):
4738 Field.__init__(self, name, None, "H")
4739 def i2m(self, pkt, x):
4741 rdataf = pkt.get_field("rdata")
4742 x = len(rdataf.i2m(pkt, pkt.rdata))
4744 def i2h(self, pkt, x):
4746 rdataf = pkt.get_field("rdata")
4747 x = len(rdataf.i2m(pkt, pkt.rdata))
4750 # seconds between 01-01-1900 and 01-01-1970
4751 ntp_basetime = 2208988800
4753 class TimeStampField(BitField):
4754 def __init__(self, name, default, size):
4755 BitField.__init__(self, name, default, size)
4757 def getfield(self, pkt, s):
4758 s,timestamp = BitField.getfield(self, pkt, s)
4761 # timestamp is a 64 bits field :
4762 # + first 32 bits : number of seconds since 1900
4763 # + last 32 bits : fraction part
4765 timestamp -= ntp_basetime
4767 from time import gmtime, strftime
4768 b = strftime("%a, %d %b %Y %H:%M:%S +0000", gmtime(timestamp))
4773 def addfield(self, pkt, s, val):
4775 if type(val) is str:
4776 from time import strptime, mktime
4777 t = int(mktime(strptime(val))) + ntp_basetime + 3600
4780 from time import time
4781 t = int(time()) + ntp_basetime
4785 return BitField.addfield(self,pkt,s, t)
4787 class ICMPTimeStampField(IntField):
4788 re_hmsm = re.compile("([0-2]?[0-9])[Hh:](([0-5]?[0-9])([Mm:]([0-5]?[0-9])([sS:.]([0-9]{0,3}))?)?)?$")
4789 def i2repr(self, pkt, val):
4793 sec, milli = divmod(val, 1000)
4794 min, sec = divmod(sec, 60)
4795 hour, min = divmod(min, 60)
4796 return "%d:%d:%d.%d" %(hour, min, sec, int(milli))
4797 def any2i(self, pkt, val):
4798 if type(val) is str:
4799 hmsms = self.re_hmsm.match(val)
4801 h,_,m,_,s,_,ms = hmsms = hmsms.groups()
4802 ms = int(((ms or "")+"000")[:3])
4803 val = ((int(h)*60+int(m or 0))*60+int(s or 0))*1000+ms
4807 val = int((time.time()%(24*60*60))*1000)
4810 class FloatField(BitField):
4811 def getfield(self, pkt, s):
4812 s,b = BitField.getfield(self, pkt, s)
4814 # fraction point between bits 15 and 16.
4816 frac = b & (1L << (32+1)) - 1
4821 class Dot11SCField(LEShortField):
4822 def is_applicable(self, pkt):
4823 return pkt.type != 1 # control frame
4824 def addfield(self, pkt, s, val):
4825 if self.is_applicable(pkt):
4826 return LEShortField.addfield(self, pkt, s, val)
4829 def getfield(self, pkt, s):
4830 if self.is_applicable(pkt):
4831 return LEShortField.getfield(self, pkt, s)
4835 #####################
4836 #### ASN1 Fields ####
4837 #####################
4839 class ASN1F_badsequence(Exception):
4842 class ASN1F_element:
4845 class ASN1F_optionnal(ASN1F_element):
4846 def __init__(self, field):
4848 def __getattr__(self, attr):
4849 return getattr(self._field,attr)
4850 def dissect(self,pkt,s):
4852 return self._field.dissect(pkt,s)
4853 except ASN1F_badsequence:
4854 self._field.set_val(pkt,None)
4856 except BER_Decoding_Error:
4857 self._field.set_val(pkt,None)
4859 def build(self, pkt):
4860 if self._field.is_empty(pkt):
4862 return self._field.build(pkt)
4864 class ASN1F_field(ASN1F_element):
4868 ASN1_tag = ASN1_Class_UNIVERSAL.ANY
4869 context=ASN1_Class_UNIVERSAL
4871 def __init__(self, name, default, context=None):
4872 if context is not None:
4873 self.context = context
4875 self.default = default
4877 def i2repr(self, pkt, x):
4881 def i2h(self, pkt, x):
4883 def any2i(self, pkt, x):
4885 def m2i(self, pkt, x):
4886 return self.ASN1_tag.get_codec(pkt.ASN1_codec).safedec(x, context=self.context)
4887 def i2m(self, pkt, x):
4890 if isinstance(x, ASN1_Object):
4891 if ( self.ASN1_tag == ASN1_Class_UNIVERSAL.ANY
4892 or x.tag == ASN1_Class_UNIVERSAL.RAW
4893 or x.tag == ASN1_Class_UNIVERSAL.ERROR
4894 or self.ASN1_tag == x.tag ):
4895 return x.enc(pkt.ASN1_codec)
4897 raise ASN1_Error("Encoding Error: got %r instead of an %r for field [%s]" % (x, self.ASN1_tag, self.name))
4898 return self.ASN1_tag.get_codec(pkt.ASN1_codec).enc(x)
4900 def do_copy(self, x):
4901 if hasattr(x, "copy"):
4905 for i in xrange(len(x)):
4906 if isinstance(x[i], Packet):
4910 def build(self, pkt):
4911 return self.i2m(pkt, getattr(pkt, self.name))
4913 def set_val(self, pkt, val):
4914 setattr(pkt, self.name, val)
4915 def is_empty(self, pkt):
4916 return getattr(pkt,self.name) is None
4918 def dissect(self, pkt, s):
4919 v,s = self.m2i(pkt, s)
4920 self.set_val(pkt, v)
4923 def get_fields_list(self):
4927 return hash(self.name)
4930 def __eq__(self, other):
4931 return self.name == other
4938 class ASN1F_INTEGER(ASN1F_field):
4939 ASN1_tag= ASN1_Class_UNIVERSAL.INTEGER
4941 return RandNum(-2**64, 2**64-1)
4943 class ASN1F_NULL(ASN1F_INTEGER):
4944 ASN1_tag= ASN1_Class_UNIVERSAL.NULL
4946 class ASN1F_enum_INTEGER(ASN1F_INTEGER):
4947 def __init__(self, name, default, enum):
4948 ASN1F_INTEGER.__init__(self, name, default)
4951 if type(enum) is list:
4952 keys = xrange(len(enum))
4955 if filter(lambda x: type(x) is str, keys):
4960 def any2i_one(self, pkt, x):
4964 def i2repr_one(self, pkt, x):
4965 return self.i2s.get(x, repr(x))
4967 def any2i(self, pkt, x):
4969 return map(lambda z,pkt=pkt:self.any2i_one(pkt,z), x)
4971 return self.any2i_one(pkt,x)
4972 def i2repr(self, pkt, x):
4974 return map(lambda z,pkt=pkt:self.i2repr_one(pkt,z), x)
4976 return self.i2repr_one(pkt,x)
4978 class ASN1F_STRING(ASN1F_field):
4979 ASN1_tag = ASN1_Class_UNIVERSAL.STRING
4981 return RandString(RandNum(0, 1000))
4983 class ASN1F_PRINTABLE_STRING(ASN1F_STRING):
4984 ASN1_tag = ASN1_Class_UNIVERSAL.PRINTABLE_STRING
4986 class ASN1F_BIT_STRING(ASN1F_STRING):
4987 ASN1_tag = ASN1_Class_UNIVERSAL.BIT_STRING
4989 class ASN1F_UTC_TIME(ASN1F_STRING):
4990 ASN1_tag = ASN1_Class_UNIVERSAL.UTC_TIME
4992 class ASN1F_OID(ASN1F_field):
4993 ASN1_tag = ASN1_Class_UNIVERSAL.OID
4997 class ASN1F_SEQUENCE(ASN1F_field):
4998 ASN1_tag = ASN1_Class_UNIVERSAL.SEQUENCE
4999 def __init__(self, *seq, **kargs):
5000 if "ASN1_tag" in kargs:
5001 self.ASN1_tag = kargs["ASN1_tag"]
5004 return "<%s%r>" % (self.__class__.__name__,self.seq,)
5005 def set_val(self, pkt, val):
5008 def is_empty(self, pkt):
5010 if not f.is_empty(pkt):
5013 def get_fields_list(self):
5014 return reduce(lambda x,y: x+y.get_fields_list(), self.seq, [])
5015 def build(self, pkt):
5016 s = reduce(lambda x,y: x+y.build(pkt), self.seq, "")
5017 return self.i2m(pkt, s)
5018 def dissect(self, pkt, s):
5019 codec = self.ASN1_tag.get_codec(pkt.ASN1_codec)
5021 i,s,remain = codec.check_type_check_len(s)
5022 for obj in self.seq:
5023 s = obj.dissect(pkt,s)
5025 warning("Too many bytes to decode sequence: [%r]" % s) # XXX not reversible!
5027 except ASN1_Error,e:
5028 raise ASN1F_badsequence(e)
5030 class ASN1F_SET(ASN1F_SEQUENCE):
5031 ASN1_tag = ASN1_Class_UNIVERSAL.SET
5033 class ASN1F_SEQUENCE_OF(ASN1F_SEQUENCE):
5036 def __init__(self, name, default, asn1pkt, ASN1_tag=0x30):
5037 self.asn1pkt = asn1pkt
5038 self.tag = chr(ASN1_tag)
5040 self.default = default
5041 def i2repr(self, pkt, i):
5045 def get_fields_list(self):
5047 def set_val(self, pkt, val):
5048 ASN1F_field.set_val(self, pkt, val)
5049 def is_empty(self, pkt):
5050 return ASN1F_field.is_empty(self, pkt)
5051 def build(self, pkt):
5052 val = getattr(pkt, self.name)
5053 if isinstance(val, ASN1_Object) and val.tag == ASN1_Class_UNIVERSAL.RAW:
5058 s = "".join(map(str, val ))
5059 return self.i2m(pkt, s)
5060 def set_val(self, pkt, val):
5061 ASN1F_field.set_val(self, pkt, val)
5062 def dissect(self, pkt, s):
5063 codec = self.ASN1_tag.get_codec(pkt.ASN1_codec)
5064 i,s1,remain = codec.check_type_check_len(s)
5068 p = self.asn1pkt(s1)
5069 except ASN1F_badsequence,e:
5075 del(p[Raw].underlayer.payload)
5078 self.set_val(pkt, lst)
5081 return fuzz(self.asn1pkt())
5083 return "<%s %s>" % (self.__class__.__name__,self.name)
5085 class ASN1F_PACKET(ASN1F_field):
5087 def __init__(self, name, default, cls):
5088 ASN1_field.__init__(self, name, default)
5090 def i2m(self, pkt, x):
5094 def extract_packet(self, cls, x):
5097 except ASN1F_badsequence:
5101 if cpad is not None:
5103 del(cpad.underlayer.payload)
5105 def m2i(self, pkt, x):
5106 return self.extract_packet(self.cls, x)
5109 class ASN1F_CHOICE(ASN1F_PACKET):
5110 ASN1_tag = ASN1_Class_UNIVERSAL.NONE
5111 def __init__(self, name, default, *args):
5115 self.choice[p.ASN1_root.ASN1_tag] = p
5116 # self.context=context
5117 self.default=default
5118 def m2i(self, pkt, x):
5121 raise ASN1_Error("ASN1F_CHOICE: got empty string")
5122 if ord(x[0]) not in self.choice:
5123 return Raw(x),"" # XXX return RawASN1 packet ? Raise error
5124 raise ASN1_Error("Decoding Error: choice [%i] not found in %r" % (ord(x[0]), self.choice.keys()))
5126 z = ASN1F_PACKET.extract_packet(self, self.choice[ord(x[0])], x)
5129 return RandChoice(*map(lambda x:fuzz(x()), self.choice.values()))
5133 ###########################
5134 ## Packet abstract class ##
5135 ###########################
5137 class Packet_metaclass(type):
5138 def __new__(cls, name, bases, dct):
5139 newcls = super(Packet_metaclass, cls).__new__(cls, name, bases, dct)
5140 for f in newcls.fields_desc:
5141 f.register_owner(newcls)
5143 def __getattr__(self, attr):
5144 for k in self.fields_desc:
5147 raise AttributeError(attr)
5149 class NewDefaultValues(Packet_metaclass):
5150 """NewDefaultValues metaclass. Example usage:
5151 class MyPacket(Packet):
5152 fields_desc = [ StrField("my_field", "my default value"), ]
5154 class MyPacket_variant(MyPacket):
5155 __metaclass__ = NewDefaultValues
5156 my_field = "my new default value"
5158 def __new__(cls, name, bases, dct):
5161 if hasattr(b,"fields_desc"):
5162 fields = b.fields_desc
5165 raise Scapy_Exception("No fields_desc in superclasses")
5171 f.default = dct[f.name]
5173 new_fields.append(f)
5174 dct["fields_desc"] = new_fields
5175 return super(NewDefaultValues, cls).__new__(cls, name, bases, dct)
5178 __metaclass__ = Packet_metaclass
5184 overload_fields = {}
5194 def from_hexcap(cls):
5195 return cls(import_hexcap())
5198 def upper_bonds(self):
5199 for fval,upper in self.payload_guess:
5200 print "%-20s %s" % (upper.__name__, ", ".join("%-12s" % ("%s=%r"%i) for i in fval.iteritems()))
5203 def lower_bonds(self):
5204 for lower,fval in self.overload_fields.iteritems():
5205 print "%-20s %s" % (lower.__name__, ", ".join("%-12s" % ("%s=%r"%i) for i in fval.iteritems()))
5207 def __init__(self, _pkt="", post_transform=None, _internal=0, _underlayer=None, **fields):
5208 self.time = time.time()
5210 if self.name is None:
5211 self.name = self.__class__.__name__
5212 self.aliastypes = [ self.__class__ ] + self.aliastypes
5213 self.default_fields = {}
5214 self.overloaded_fields = {}
5217 self.packetfields=[]
5218 self.__dict__["payload"] = NoPayload()
5220 self.underlayer = _underlayer
5221 self.initialized = 1
5225 self.dissection_done(self)
5226 for f in fields.keys():
5227 self.fields[f] = self.get_field(f).any2i(self,fields[f])
5228 if type(post_transform) is list:
5229 self.post_transforms = post_transform
5230 elif post_transform is None:
5231 self.post_transforms = []
5233 self.post_transforms = [post_transform]
5235 def init_fields(self):
5236 self.do_init_fields(self.fields_desc)
5238 def do_init_fields(self, flist):
5240 self.default_fields[f.name] = f.default
5241 self.fieldtype[f.name] = f
5243 self.packetfields.append(f)
5245 def dissection_done(self,pkt):
5246 """DEV: will be called after a dissection is completed"""
5247 self.post_dissection(pkt)
5248 self.payload.dissection_done(pkt)
5250 def post_dissection(self, pkt):
5251 """DEV: is called after the dissection of the whole packet"""
5254 def get_field(self, fld):
5255 """DEV: returns the field instance from the name of the field"""
5256 return self.fieldtype[fld]
5258 def add_payload(self, payload):
5261 elif not isinstance(self.payload, NoPayload):
5262 self.payload.add_payload(payload)
5264 if isinstance(payload, Packet):
5265 self.__dict__["payload"] = payload
5266 payload.add_underlayer(self)
5267 for t in self.aliastypes:
5268 if payload.overload_fields.has_key(t):
5269 self.overloaded_fields = payload.overload_fields[t]
5271 elif type(payload) is str:
5272 self.__dict__["payload"] = Raw(load=payload)
5274 raise TypeError("payload must be either 'Packet' or 'str', not [%s]" % repr(payload))
5275 def remove_payload(self):
5276 self.payload.remove_underlayer(self)
5277 self.__dict__["payload"] = NoPayload()
5278 self.overloaded_fields = {}
5279 def add_underlayer(self, underlayer):
5280 self.underlayer = underlayer
5281 def remove_underlayer(self,other):
5282 self.underlayer = None
5284 """Returns a deep copy of the instance."""
5285 clone = self.__class__()
5286 clone.fields = self.fields.copy()
5287 for k in clone.fields:
5288 clone.fields[k]=self.get_field(k).do_copy(clone.fields[k])
5289 clone.default_fields = self.default_fields.copy()
5290 clone.overloaded_fields = self.overloaded_fields.copy()
5291 clone.overload_fields = self.overload_fields.copy()
5292 clone.underlayer=self.underlayer
5293 clone.explicit=self.explicit
5294 clone.post_transforms=self.post_transforms[:]
5295 clone.__dict__["payload"] = self.payload.copy()
5296 clone.payload.add_underlayer(clone)
5299 def getfieldval(self, attr):
5300 if attr in self.fields:
5301 return self.fields[attr]
5302 if attr in self.overloaded_fields:
5303 return self.overloaded_fields[attr]
5304 if attr in self.default_fields:
5305 return self.default_fields[attr]
5306 return self.payload.getfieldval(attr)
5308 def getfield_and_val(self, attr):
5309 if attr in self.fields:
5310 return self.get_field(attr),self.fields[attr]
5311 if attr in self.overloaded_fields:
5312 return self.get_field(attr),self.overloaded_fields[attr]
5313 if attr in self.default_fields:
5314 return self.get_field(attr),self.default_fields[attr]
5315 return self.payload.getfield_and_val(attr)
5317 def __getattr__(self, attr):
5318 if self.initialized:
5319 fld,v = self.getfield_and_val(attr)
5321 return fld.i2h(self, v)
5323 raise AttributeError(attr)
5325 def setfieldval(self, attr, val):
5326 if self.default_fields.has_key(attr):
5327 fld = self.get_field(attr)
5329 any2i = lambda x,y: y
5332 self.fields[attr] = any2i(self, val)
5334 elif attr == "payload":
5335 self.remove_payload()
5336 self.add_payload(val)
5338 self.payload.setfieldval(attr,val)
5340 def __setattr__(self, attr, val):
5341 if self.initialized:
5343 self.setfieldval(attr,val)
5344 except AttributeError:
5348 self.__dict__[attr] = val
5350 def delfieldval(self, attr):
5351 if self.fields.has_key(attr):
5352 del(self.fields[attr])
5353 self.explicit=0 # in case a default value must be explicited
5354 elif self.default_fields.has_key(attr):
5356 elif attr == "payload":
5357 self.remove_payload()
5359 self.payload.delfieldval(attr)
5361 def __delattr__(self, attr):
5362 if self.initialized:
5364 self.delfieldval(attr)
5365 except AttributeError:
5369 if self.__dict__.has_key(attr):
5370 del(self.__dict__[attr])
5372 raise AttributeError(attr)
5376 ct = conf.color_theme
5377 for f in self.fields_desc:
5378 if isinstance(f, ConditionalField) and not f._evalcond(self):
5380 if f.name in self.fields:
5381 val = f.i2repr(self, self.fields[f.name])
5382 elif f.name in self.overloaded_fields:
5383 val = f.i2repr(self, self.overloaded_fields[f.name])
5386 if isinstance(f, Emph):
5387 ncol = ct.emph_field_name
5388 vcol = ct.emph_field_value
5390 ncol = ct.field_name
5391 vcol = ct.field_value
5394 s += " %s%s%s" % (ncol(f.name),
5397 return "%s%s %s %s%s%s"% (ct.punct("<"),
5398 ct.layer_name(self.__class__.__name__),
5405 def __div__(self, other):
5406 if isinstance(other, Packet):
5407 cloneA = self.copy()
5408 cloneB = other.copy()
5409 cloneA.add_payload(cloneB)
5411 elif type(other) is str:
5412 return self/Raw(load=other)
5414 return other.__rdiv__(self)
5415 def __rdiv__(self, other):
5416 if type(other) is str:
5417 return Raw(load=other)/self
5420 def __mul__(self, other):
5421 if type(other) is int:
5425 def __rmul__(self,other):
5426 return self.__mul__(other)
5428 def __nonzero__(self):
5431 return len(self.__str__())
5434 for f in self.fields_desc:
5435 p = f.addfield(self, p, self.getfieldval(f.name))
5438 def post_build(self, pkt, pay):
5439 """DEV: called right after the current layer is build."""
5442 def build_payload(self):
5443 return self.payload.build(internal=1)
5445 def build(self,internal=0):
5446 if not self.explicit:
5447 self = self.__iter__().next()
5448 pkt = self.do_build()
5449 for t in self.post_transforms:
5451 pay = self.build_payload()
5453 p = self.post_build(pkt,pay)
5455 log_runtime.error("API changed! post_build() now takes 2 arguments. Compatibility is only assured for a short transition time")
5456 p = self.post_build(pkt+pay)
5458 pad = self.payload.getlayer(Padding)
5461 p = self.build_done(p)
5464 def build_done(self, p):
5465 return self.payload.build_done(p)
5467 def do_build_ps(self):
5471 for f in self.fields_desc:
5472 p = f.addfield(self, p, self.getfieldval(f.name) )
5478 pl.append( (f, f.i2repr(self,self.getfieldval(f.name)), r) )
5480 pkt,lst = self.payload.build_ps(internal=1)
5482 lst.append( (self, pl) )
5486 def build_ps(self,internal=0):
5487 p,lst = self.do_build_ps()
5490 # while pkt.haslayer(Padding):
5491 # pkt = pkt.getlayer(Padding)
5492 # lst.append( (pkt, [ ("loakjkjd", pkt.load, pkt.load) ] ) )
5498 def psdump(self, filename=None, **kargs):
5499 """psdump(filename=None, layer_shift=0, rebuild=1)
5500 Creates an EPS file describing a packet. If filename is not provided a temporary file is created and gs is called."""
5501 canvas = self.canvas_dump(**kargs)
5502 if filename is None:
5503 fname = "/tmp/scapy.%i"%os.getpid()
5504 canvas.writeEPSfile(fname)
5505 os.system("%s '%s.eps' &" % (conf.prog.psreader,fname))
5507 canvas.writeEPSfile(filename)
5509 def pdfdump(self, filename=None, **kargs):
5510 """pdfdump(filename=None, layer_shift=0, rebuild=1)
5511 Creates a PDF file describing a packet. If filename is not provided a temporary file is created and xpdf is called."""
5512 canvas = self.canvas_dump(**kargs)
5513 if filename is None:
5514 fname = "/tmp/scapy.%i"%os.getpid()
5515 canvas.writePDFfile(fname)
5516 os.system("%s '%s.pdf' &" % (conf.prog.pdfreader,fname))
5518 canvas.writePDFfile(filename)
5521 def canvas_dump(self, layer_shift=0, rebuild=1):
5522 canvas = pyx.canvas.canvas()
5524 p,t = self.__class__(str(self)).build_ps()
5526 p,t = self.build_ps()
5541 backcolor=colgen(0.6, 0.8, 1.0, trans=pyx.color.rgb)
5542 forecolor=colgen(0.2, 0.5, 0.8, trans=pyx.color.rgb)
5543 # backcolor=makecol(0.376, 0.729, 0.525, 1.0)
5549 s.append("%02x" % ord(c))
5553 def make_dump_txt(x,y,txt):
5554 return pyx.text.text(XDSTART+x*XMUL, (YDUMP-y)*YMUL, r"\tt{%s}"%hexstr(txt), [pyx.text.size.Large])
5557 return pyx.box.rect(o.left(), o.bottom(), o.width(), o.height(), relcenter=(0.5,0.5))
5559 def make_frame(lst):
5562 b.enlarge(pyx.unit.u_pt)
5566 fb.enlarge(pyx.unit.u_pt)
5568 lb.enlarge(pyx.unit.u_pt)
5569 if len(lst) == 2 and fb.left() > lb.right():
5570 return pyx.path.path(pyx.path.moveto(fb.right(), fb.top()),
5571 pyx.path.lineto(fb.left(), fb.top()),
5572 pyx.path.lineto(fb.left(), fb.bottom()),
5573 pyx.path.lineto(fb.right(), fb.bottom()),
5574 pyx.path.moveto(lb.left(), lb.top()),
5575 pyx.path.lineto(lb.right(), lb.top()),
5576 pyx.path.lineto(lb.right(), lb.bottom()),
5577 pyx.path.lineto(lb.left(), lb.bottom()))
5582 gb.enlarge(pyx.unit.u_pt)
5584 if kb != gb and kb != lb:
5585 kb.enlarge(pyx.unit.u_pt)
5586 return pyx.path.path(pyx.path.moveto(fb.left(), fb.top()),
5587 pyx.path.lineto(fb.right(), fb.top()),
5588 pyx.path.lineto(fb.right(), kb.bottom()),
5589 pyx.path.lineto(lb.right(), kb.bottom()),
5590 pyx.path.lineto(lb.right(), lb.bottom()),
5591 pyx.path.lineto(lb.left(), lb.bottom()),
5592 pyx.path.lineto(lb.left(), gb.top()),
5593 pyx.path.lineto(fb.left(), gb.top()),
5594 pyx.path.closepath(),)
5597 def make_dump(s, shift=0, y=0, col=None, bkcol=None, larg=16):
5598 c = pyx.canvas.canvas()
5601 dmp,s = s[:larg-shift],s[larg-shift:]
5602 txt = make_dump_txt(shift, y, dmp)
5609 col = pyx.color.rgb.red
5611 col = pyx.color.rgb.white
5612 c.stroke(make_frame(tlist),[col,pyx.deco.filled([bkcol]),pyx.style.linewidth.Thick])
5615 return c, tlist[-1].bbox(), shift, y
5618 last_shift,last_y=0,0.0
5620 bkcol = backcolor.next()
5621 proto,fields = t.pop()
5623 pt = pyx.text.text(XSTART, (YTXT-y)*YMUL, r"\font\cmssfont=cmss10\cmssfont{%s}" % proto.name, [ pyx.text.size.Large])
5626 ptbb.enlarge(pyx.unit.u_pt*2)
5627 canvas.stroke(ptbb.path(),[pyx.color.rgb.black, pyx.deco.filled([bkcol])])
5629 for fname, fval, fdump in fields:
5630 col = forecolor.next()
5631 ft = pyx.text.text(XSTART, (YTXT-y)*YMUL, r"\font\cmssfont=cmss10\cmssfont{%s}" % tex_escape(fname.name))
5632 if fval is not None:
5634 fval = fval[:18]+"[...]"
5637 vt = pyx.text.text(XSTART+3, (YTXT-y)*YMUL, r"\font\cmssfont=cmss10\cmssfont{%s}" % tex_escape(fval))
5640 dt,target,last_shift,last_y = make_dump(fdump, last_shift, last_y, col, bkcol)
5645 bxvt = make_box(vtb)
5646 bxdt = make_box(dtb)
5647 dtb.enlarge(pyx.unit.u_pt)
5650 cnx = pyx.connector.curve(bxvt,bxdt,absangle1=0, absangle2=-90)
5652 cnx = pyx.connector.curve(bxvt,bxdt,absangle1=0, absangle2=90)
5656 canvas.stroke(cnx,[pyx.style.linewidth.thin,pyx.deco.earrow.small,col])
5662 last_y += layer_shift
5668 def extract_padding(self, s):
5669 """DEV: to be overloaded to extract current layer's padding. Return a couple of strings (actual layer, padding)"""
5672 def post_dissect(self, s):
5673 """DEV: is called right after the current layer has been dissected"""
5676 def pre_dissect(self, s):
5677 """DEV: is called right before the current layer is dissected"""
5680 def do_dissect(self, s):
5681 flist = self.fields_desc[:]
5685 s,fval = f.getfield(self, s)
5686 self.fields[f.name] = fval
5690 def do_dissect_payload(self, s):
5692 cls = self.guess_payload_class(s)
5694 p = cls(s, _internal=1, _underlayer=self)
5695 except KeyboardInterrupt:
5698 if conf.debug_dissector:
5699 if isinstance(cls,type) and issubclass(cls,Packet):
5700 log_runtime.error("%s dissector failed" % cls.name)
5702 log_runtime.error("%s.guess_payload_class() returned [%s]" % (self.__class__.__name__,repr(cls)))
5705 p = Raw(s, _internal=1, _underlayer=self)
5708 def dissect(self, s):
5709 s = self.pre_dissect(s)
5711 s = self.do_dissect(s)
5713 s = self.post_dissect(s)
5715 payl,pad = self.extract_padding(s)
5716 self.do_dissect_payload(payl)
5717 if pad and conf.padding:
5718 self.add_payload(Padding(pad))
5721 def guess_payload_class(self, payload):
5722 """DEV: Guesses the next payload class from layer bonds. Can be overloaded to use a different mechanism."""
5723 for t in self.aliastypes:
5724 for fval, cls in t.payload_guess:
5726 for k in fval.keys():
5727 if not hasattr(self, k) or fval[k] != self.getfieldval(k):
5732 return self.default_payload_class(payload)
5734 def default_payload_class(self, payload):
5735 """DEV: Returns the default payload class if nothing has been found by the guess_payload_class() method."""
5738 def hide_defaults(self):
5739 """Removes fields' values that are the same as default values."""
5740 for k in self.fields.keys():
5741 if self.default_fields.has_key(k):
5742 if self.default_fields[k] == self.fields[k]:
5744 self.payload.hide_defaults()
5746 def clone_with(self, payload=None, **kargs):
5747 pkt = self.__class__()
5750 pkt.time = self.time
5751 pkt.underlayer = self.underlayer
5752 pkt.overload_fields = self.overload_fields.copy()
5753 pkt.post_transforms = self.post_transforms
5754 if payload is not None:
5755 pkt.add_payload(payload)
5760 def loop(todo, done, self=self):
5762 eltname = todo.pop()
5763 elt = self.getfieldval(eltname)
5764 if not isinstance(elt, Gen):
5765 if self.get_field(eltname).islist:
5771 for x in loop(todo[:], done):
5774 if isinstance(self.payload,NoPayload):
5777 payloads = self.payload
5778 for payl in payloads:
5781 if isinstance(done2[k], VolatileValue):
5782 done2[k] = done2[k]._fix()
5783 pkt = self.clone_with(payload=payl, **done2)
5790 todo = [ k for (k,v) in itertools.chain(self.default_fields.iteritems(),
5791 self.overloaded_fields.iteritems())
5792 if isinstance(v, VolatileValue) ] + self.fields.keys()
5794 return loop(todo, done)
5796 def __gt__(self, other):
5797 """True if other is an answer from self (self ==> other)."""
5798 if isinstance(other, Packet):
5800 elif type(other) is str:
5803 raise TypeError((self, other))
5804 def __lt__(self, other):
5805 """True if self is an answer from other (other ==> self)."""
5806 if isinstance(other, Packet):
5807 return self.answers(other)
5808 elif type(other) is str:
5811 raise TypeError((self, other))
5813 def __eq__(self, other):
5814 if not isinstance(other, self.__class__):
5816 for f in self.fields_desc:
5817 if f not in other.fields_desc:
5819 if self.getfieldval(f.name) != other.getfieldval(f.name):
5821 return self.payload == other.payload
5823 def __ne__(self, other):
5824 return not self.__eq__(other)
5827 """DEV: returns a string that has the same value for a request and its answer."""
5828 return self.payload.hashret()
5829 def answers(self, other):
5830 """DEV: true if self is an answer from other"""
5831 if other.__class__ == self.__class__:
5832 return self.payload.answers(other.payload)
5835 def haslayer(self, cls):
5836 """true if self has a layer that is an instance of cls. Superseded by "cls in self" syntax."""
5837 if self.__class__ == cls or self.__class__.__name__ == cls:
5839 for f in self.packetfields:
5840 fvalue_gen = self.getfieldval(f.name)
5841 if fvalue_gen is None:
5844 fvalue_gen = SetGen(fvalue_gen,_iterpacket=0)
5845 for fvalue in fvalue_gen:
5846 if isinstance(fvalue, Packet):
5847 ret = fvalue.haslayer(cls)
5850 return self.payload.haslayer(cls)
5851 def getlayer(self, cls, nb=1, _track=None):
5852 """Return the nb^th layer that is an instance of cls."""
5853 if type(cls) is str and "." in cls:
5854 ccls,fld = cls.split(".",1)
5857 if self.__class__ == cls or self.__class__.name == ccls:
5862 return self.getfieldval(fld)
5865 for f in self.packetfields:
5866 fvalue_gen = self.getfieldval(f.name)
5867 if fvalue_gen is None:
5870 fvalue_gen = SetGen(fvalue_gen,_iterpacket=0)
5871 for fvalue in fvalue_gen:
5872 if isinstance(fvalue, Packet):
5874 ret = fvalue.getlayer(cls, nb, _track=track)
5878 return self.payload.getlayer(cls,nb,_track=_track)
5880 def __getitem__(self, cls):
5881 if type(cls) is slice:
5883 ret = self.getlayer(cls.start, cls.stop)
5885 ret = self.getlayer(cls.start)
5886 if ret is None and cls.step is not None:
5890 return self.getlayer(cls)
5892 def __contains__(self, cls):
5893 """"cls in self" returns true if self has a layer which is an instance of cls."""
5894 return self.haslayer(cls)
5898 def display(self,*args,**kargs): # Deprecated. Use show()
5899 """Deprecated. Use show() method."""
5900 self.show(*args,**kargs)
5901 def show(self, indent=3, lvl="", label_lvl=""):
5902 """Prints a hierarchical view of the packet. "indent" gives the size of indentation for each layer."""
5903 ct = conf.color_theme
5904 print "%s%s %s %s" % (label_lvl,
5906 ct.layer_name(self.name),
5908 for f in self.fields_desc:
5909 if isinstance(f, ConditionalField) and not f._evalcond(self):
5911 if isinstance(f, Emph):
5912 ncol = ct.emph_field_name
5913 vcol = ct.emph_field_value
5915 ncol = ct.field_name
5916 vcol = ct.field_value
5917 fvalue = self.getfieldval(f.name)
5918 if isinstance(fvalue, Packet) or (f.islist and f.holds_packets and type(fvalue) is list):
5919 print "%s \\%-10s\\" % (label_lvl+lvl, ncol(f.name))
5920 fvalue_gen = SetGen(fvalue,_iterpacket=0)
5921 for fvalue in fvalue_gen:
5922 fvalue.show(indent=indent, label_lvl=label_lvl+lvl+" |")
5924 print "%s %-10s%s %s" % (label_lvl+lvl,
5927 vcol(f.i2repr(self,fvalue)))
5928 self.payload.show(indent=indent, lvl=lvl+(" "*indent*self.show_indent), label_lvl=label_lvl)
5930 """Prints a hierarchical view of an assembled version of the packet, so that automatic fields are calculated (checksums, etc.)"""
5931 self.__class__(str(self)).show()
5933 def sprintf(self, fmt, relax=1):
5934 """sprintf(format, [relax=1]) -> str
5935 where format is a string that can include directives. A directive begins and
5936 ends by % and has the following format %[fmt[r],][cls[:nb].]field%.
5938 fmt is a classic printf directive, "r" can be appended for raw substitution
5939 (ex: IP.flags=0x18 instead of SA), nb is the number of the layer we want
5940 (ex: for IP/IP packets, IP:2.src is the src of the upper IP layer).
5941 Special case : "%.time%" is the creation time.
5942 Ex : p.sprintf("%.time% %-15s,IP.src% -> %-15s,IP.dst% %IP.chksum% "
5943 "%03xr,IP.proto% %r,TCP.flags%")
5945 Moreover, the format string can include conditionnal statements. A conditionnal
5946 statement looks like : {layer:string} where layer is a layer name, and string
5947 is the string to insert in place of the condition if it is true, i.e. if layer
5948 is present. If layer is preceded by a "!", the result si inverted. Conditions
5949 can be imbricated. A valid statement can be :
5950 p.sprintf("This is a{TCP: TCP}{UDP: UDP}{ICMP:n ICMP} packet")
5951 p.sprintf("{IP:%IP.dst% {ICMP:%ICMP.type%}{TCP:%TCP.dport%}}")
5953 A side effect is that, to obtain "{" and "}" characters, you must use
5957 escape = { "%": "%",
5962 # Evaluate conditions
5965 j = fmt[i+1:].index("}")
5966 cond = fmt[i+1:i+j+1]
5969 raise Scapy_Exception("Bad condition in format string: [%s] (read sprintf doc!)"%cond)
5970 cond,format = cond[:k],cond[k+1:]
5975 if self.haslayer(cond):
5979 fmt = fmt[:i]+format+fmt[i+j+2:]
5981 # Evaluate directives
5987 if fmt and fmt[0] in escape:
5994 fclsfld = sfclsfld.split(",")
5995 if len(fclsfld) == 1:
5998 elif len(fclsfld) == 2:
6001 raise Scapy_Exception
6003 cls,fld = clsfld.split(".")
6005 cls = self.__class__.__name__
6009 cls,num = cls.split(":")
6013 raise Scapy_Exception("Bad format string [%%%s%s]" % (fmt[:25], fmt[25:] and "..."))
6016 val = time.strftime("%H:%M:%S.%%06i", time.localtime(self.time)) % int((self.time-int(self.time))*1000000)
6017 elif cls == self.__class__.__name__ and hasattr(self, fld):
6019 val = self.payload.sprintf("%%%s,%s:%s.%s%%" % (f,cls,num-1,fld), relax)
6021 elif f[-1] == "r": # Raw field value
6022 val = getattr(self,fld)
6027 val = getattr(self,fld)
6028 if fld in self.fieldtype:
6029 val = self.fieldtype[fld].i2repr(self,val)
6031 val = self.payload.sprintf("%%%s%%" % sfclsfld, relax)
6038 def mysummary(self):
6039 """DEV: can be overloaded to return a string that summarizes the layer.
6040 Only one mysummary() is used in a whole packet summary: the one of the upper layer,
6041 except if a mysummary() also returns (as a couple) a list of layers whose
6042 mysummary() must be called if they are present."""
6045 def summary(self, intern=0):
6046 """Prints a one line summary of a packet."""
6047 found,s,needed = self.payload.summary(intern=1)
6051 if not found or self.__class__ in needed:
6052 ret = self.mysummary()
6053 if type(ret) is tuple:
6059 ret = self.__class__.__name__
6060 ret = "%s%s" % (ret,s)
6062 return found,ret,needed
6066 def lastlayer(self,layer=None):
6067 """Returns the uppest layer of the packet"""
6068 return self.payload.lastlayer(self)
6070 def decode_payload_as(self,cls):
6071 """Reassembles the payload and decode it using another packet class"""
6072 s = str(self.payload)
6073 self.payload = cls(s)
6076 """Not ready yet. Should give the necessary C code that interfaces with libnet to recreate the packet"""
6077 print "libnet_build_%s(" % self.__class__.name.lower()
6078 det = self.__class__(str(self))
6079 for f in self.fields_desc:
6080 val = det.getfieldval(f.name)
6083 elif type(val) is int:
6086 val = '"%s"' % str(val)
6087 print "\t%s, \t\t/* %s */" % (val,f.name)
6090 """Returns a string representing the command you have to type to obtain the same packet"""
6092 for fn,fv in self.fields.items():
6093 fld = self.get_field(fn)
6094 if isinstance(fv, Packet):
6096 elif fld.islist and fld.holds_packets and type(fv) is list:
6097 fv = "[%s]" % ",".join( map(Packet.command, fv))
6100 f.append("%s=%s" % (fn, fv))
6101 c = "%s(%s)" % (self.__class__.__name__, ", ".join(f))
6102 pc = self.payload.command()
6108 class ASN1_Packet(Packet):
6111 def init_fields(self):
6112 flist = self.ASN1_root.get_fields_list()
6113 self.do_init_fields(flist)
6114 self.fields_desc = flist
6116 return self.ASN1_root.build(self)
6117 def do_dissect(self, x):
6118 return self.ASN1_root.dissect(self, x)
6121 class NoPayload(Packet,object):
6122 def __new__(cls, *args, **kargs):
6123 singl = cls.__dict__.get("__singl__")
6125 cls.__singl__ = singl = object.__new__(cls)
6126 Packet.__init__(singl, *args, **kargs)
6128 def __init__(self, *args, **kargs):
6130 def dissection_done(self,pkt):
6132 def add_payload(self, payload):
6133 raise Scapy_Exception("Can't add payload to NoPayload instance")
6134 def remove_payload(self):
6136 def add_underlayer(self,underlayer):
6138 def remove_underlayer(self,other):
6146 def __nonzero__(self):
6148 def build(self, internal=0):
6150 def build_done(self, p):
6152 def build_ps(self, internal=0):
6154 def getfieldval(self, attr):
6155 raise AttributeError(attr)
6156 def getfield_and_val(self, attr):
6157 raise AttributeError(attr)
6158 def setfieldval(self, attr, val):
6159 raise AttributeError(attr)
6160 def delfieldval(self, attr):
6161 raise AttributeError(attr)
6162 def __getattr__(self, attr):
6163 if attr in self.__dict__:
6164 return self.__dict__[attr]
6165 elif attr in self.__class__.__dict__:
6166 return self.__class__.__dict__[attr]
6168 raise AttributeError, attr
6169 def hide_defaults(self):
6173 def __eq__(self, other):
6174 if isinstance(other, NoPayload):
6179 def answers(self, other):
6180 return isinstance(other, NoPayload) or isinstance(other, Padding)
6181 def haslayer(self, cls):
6183 def getlayer(self, cls, nb=1, _track=None):
6184 if _track is not None:
6187 def show(self, indent=3, lvl="", label_lvl=""):
6189 def sprintf(self, fmt, relax):
6193 raise Scapy_Exception("Format not found [%s]"%fmt)
6194 def summary(self, intern=0):
6196 def lastlayer(self,layer):
6202 ####################
6203 ## packet classes ##
6204 ####################
6209 fields_desc = [ StrField("load", "") ]
6210 def answers(self, other):
6214 # l = min(len(s), len(t))
6215 # return s[:l] == t[:l]
6219 def build(self, internal=0):
6223 return Raw.build(self)
6225 class Ether(Packet):
6227 fields_desc = [ DestMACField("dst"),
6228 SourceMACField("src"),
6229 XShortEnumField("type", 0x0000, ETHER_TYPES) ]
6231 return struct.pack("H",self.type)+self.payload.hashret()
6232 def answers(self, other):
6233 if isinstance(other,Ether):
6234 if self.type == other.type:
6235 return self.payload.answers(other.payload)
6237 def mysummary(self):
6238 return self.sprintf("%src% > %dst% (%type%)")
6240 class PPPoE(Packet):
6241 name = "PPP over Ethernet"
6242 fields_desc = [ BitField("version", 1, 4),
6243 BitField("type", 1, 4),
6244 ByteEnumField("code", 0, {0:"Session"}),
6245 XShortField("sessionid", 0x0),
6246 ShortField("len", None) ]
6248 def post_build(self, p, pay):
6250 if self.len is None:
6252 p = p[:4]+struct.pack("!H", l)+p[6:]
6255 class PPPoED(PPPoE):
6256 name = "PPP over Ethernet Discovery"
6257 fields_desc = [ BitField("version", 1, 4),
6258 BitField("type", 1, 4),
6259 ByteEnumField("code", 0x09, {0x09:"PADI",0x07:"PADO",0x19:"PADR",0x65:"PADS",0xa7:"PADT"}),
6260 XShortField("sessionid", 0x0),
6261 ShortField("len", None) ]
6265 fields_desc = [ MACField("dst", ETHER_BROADCAST),
6266 MACField("src", ETHER_ANY),
6267 LenField("len", None, "H") ]
6268 def extract_padding(self,s):
6271 def answers(self, other):
6272 if isinstance(other,Dot3):
6273 return self.payload.answers(other.payload)
6275 def mysummary(self):
6276 return "802.3 %s > %s" % (self.src, self.dst)
6281 fields_desc = [ XByteField("dsap", 0x00),
6282 XByteField("ssap", 0x00),
6283 ByteField("ctrl", 0) ]
6286 class CookedLinux(Packet):
6287 name = "cooked linux"
6288 fields_desc = [ ShortEnumField("pkttype",0, {0: "unicast",
6289 4:"sent-by-us"}), #XXX incomplete
6290 XShortField("lladdrtype",512),
6291 ShortField("lladdrlen",0),
6292 StrFixedLenField("src","",8),
6293 XShortEnumField("proto",0x800,ETHER_TYPES) ]
6299 fields_desc = [ X3BytesField("OUI",0x000000),
6300 XShortEnumField("code", 0x000, ETHER_TYPES) ]
6303 class Dot1Q(Packet):
6305 aliastypes = [ Ether ]
6306 fields_desc = [ BitField("prio", 0, 3),
6307 BitField("id", 0, 1),
6308 BitField("vlan", 1, 12),
6309 XShortEnumField("type", 0x0000, ETHER_TYPES) ]
6310 def answers(self, other):
6311 if isinstance(other,Dot1Q):
6312 if ( (self.type == other.type) and
6313 (self.vlan == other.vlan) ):
6314 return self.payload.answers(other.payload)
6316 return self.payload.answers(other)
6318 def default_payload_class(self, pay):
6319 if self.type <= 1500:
6322 def extract_padding(self,s):
6323 if self.type <= 1500:
6324 return s[:self.type],s[self.type:]
6326 def mysummary(self):
6327 if isinstance(self.underlayer, Ether):
6328 return self.underlayer.sprintf("802.1q %Ether.src% > %Ether.dst% (%Dot1Q.type%) vlan %Dot1Q.vlan%")
6330 return self.sprintf("802.1q (%Dot1Q.type%) vlan %Dot1Q.vlan%")
6335 class RadioTap(Packet):
6336 name = "RadioTap dummy"
6337 fields_desc = [ ByteField('version', 0),
6338 ByteField('pad', 0),
6339 FieldLenField('len', None, 'notdecoded', '@H', adjust=lambda pkt,x:x+8),
6340 FlagsField('present', None, -32, ['TSFT','Flags','Rate','Channel','FHSS','dBm_AntSignal',
6341 'dBm_AntNoise','Lock_Quality','TX_Attenuation','dB_TX_Attenuation',
6342 'dBm_TX_Power', 'Antenna', 'dB_AntSignal', 'dB_AntNoise',
6343 'b14', 'b15','b16','b17','b18','b19','b20','b21','b22','b23',
6344 'b24','b25','b26','b27','b28','b29','b30','Ext']),
6345 StrLenField('notdecoded', "", length_from= lambda pkt:pkt.len-8) ]
6348 name = "Spanning Tree Protocol"
6349 fields_desc = [ ShortField("proto", 0),
6350 ByteField("version", 0),
6351 ByteField("bpdutype", 0),
6352 ByteField("bpduflags", 0),
6353 ShortField("rootid", 0),
6354 MACField("rootmac", ETHER_ANY),
6355 IntField("pathcost", 0),
6356 ShortField("bridgeid", 0),
6357 MACField("bridgemac", ETHER_ANY),
6358 ShortField("portid", 0),
6359 BCDFloatField("age", 1),
6360 BCDFloatField("maxage", 20),
6361 BCDFloatField("hellotime", 2),
6362 BCDFloatField("fwddelay", 15) ]
6365 class EAPOL(Packet):
6367 fields_desc = [ ByteField("version", 1),
6368 ByteEnumField("type", 0, ["EAP_PACKET", "START", "LOGOFF", "KEY", "ASF"]),
6369 LenField("len", None, "H") ]
6376 def extract_padding(self, s):
6380 return chr(self.type)+self.payload.hashret()
6381 def answers(self, other):
6382 if isinstance(other,EAPOL):
6383 if ( (self.type == self.EAP_PACKET) and
6384 (other.type == self.EAP_PACKET) ):
6385 return self.payload.answers(other.payload)
6387 def mysummary(self):
6388 return self.sprintf("EAPOL %EAPOL.type%")
6393 fields_desc = [ ByteEnumField("code", 4, {1:"REQUEST",2:"RESPONSE",3:"SUCCESS",4:"FAILURE"}),
6395 ShortField("len",None),
6396 ConditionalField(ByteEnumField("type",0, {1:"ID",4:"MD5"}), lambda pkt:pkt.code not in [EAP.SUCCESS, EAP.FAILURE])
6406 def answers(self, other):
6407 if isinstance(other,EAP):
6408 if self.code == self.REQUEST:
6410 elif self.code == self.RESPONSE:
6411 if ( (other.code == self.REQUEST) and
6412 (other.type == self.type) ):
6414 elif other.code == self.RESPONSE:
6418 def post_build(self, p, pay):
6419 if self.len is None:
6421 p = p[:2]+chr((l>>8)&0xff)+chr(l&0xff)+p[4:]
6427 fields_desc = [ XShortField("hwtype", 0x0001),
6428 XShortEnumField("ptype", 0x0800, ETHER_TYPES),
6429 ByteField("hwlen", 6),
6430 ByteField("plen", 4),
6431 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}),
6432 ARPSourceMACField("hwsrc"),
6433 SourceIPField("psrc","pdst"),
6434 MACField("hwdst", ETHER_ANY),
6435 IPField("pdst", "0.0.0.0") ]
6438 def answers(self, other):
6439 if isinstance(other,ARP):
6440 if ( (self.op == self.is_at) and
6441 (other.op == self.who_has) and
6442 (self.psrc == other.pdst) ):
6445 def extract_padding(self, s):
6447 def mysummary(self):
6448 if self.op == self.is_at:
6449 return "ARP is at %s says %s" % (self.hwsrc, self.psrc)
6450 elif self.op == self.who_has:
6451 return "ARP who has %s says %s" % (self.pdst, self.psrc)
6453 return "ARP %ARP.op% %ARP.psrc% > %ARP.pdst%"
6456 class IP(Packet, IPTools):
6458 fields_desc = [ BitField("version" , 4 , 4),
6459 BitField("ihl", None, 4),
6460 XByteField("tos", 0),
6461 ShortField("len", None),
6462 ShortField("id", 1),
6463 FlagsField("flags", 0, 3, ["MF","DF","evil"]),
6464 BitField("frag", 0, 13),
6465 ByteField("ttl", 64),
6466 ByteEnumField("proto", 0, IP_PROTOS),
6467 XShortField("chksum", None),
6468 #IPField("src", "127.0.0.1"),
6469 Emph(SourceIPField("src","dst")),
6470 Emph(IPField("dst", "127.0.0.1")),
6471 IPoptionsField("options", "") ]
6472 def post_build(self, p, pay):
6476 p = chr(((self.version&0xf)<<4) | ihl&0x0f)+p[1:]
6477 if self.len is None:
6479 p = p[:2]+struct.pack("!H", l)+p[4:]
6480 if self.chksum is None:
6482 p = p[:10]+chr(ck>>8)+chr(ck&0xff)+p[12:]
6485 def extract_padding(self, s):
6486 l = self.len - (self.ihl << 2)
6489 def send(self, s, slp=0):
6492 s.sendto(str(p), (p.dst,0))
6493 except socket.error, msg:
6494 log_runtime.error(msg)
6498 if ( (self.proto == socket.IPPROTO_ICMP)
6499 and (isinstance(self.payload, ICMP))
6500 and (self.payload.type in [3,4,5,11,12]) ):
6501 return self.payload.payload.hashret()
6503 if conf.checkIPsrc and conf.checkIPaddr:
6504 return strxor(inet_aton(self.src),inet_aton(self.dst))+struct.pack("B",self.proto)+self.payload.hashret()
6506 return struct.pack("B", self.proto)+self.payload.hashret()
6507 def answers(self, other):
6508 if not isinstance(other,IP):
6510 if conf.checkIPaddr and (self.dst != other.src):
6512 if ( (self.proto == socket.IPPROTO_ICMP) and
6513 (isinstance(self.payload, ICMP)) and
6514 (self.payload.type in [3,4,5,11,12]) ):
6515 # ICMP error message
6516 return self.payload.payload.answers(other)
6519 if ( (conf.checkIPaddr and (self.src != other.dst)) or
6520 (self.proto != other.proto) ):
6522 return self.payload.answers(other.payload)
6523 def mysummary(self):
6524 s = self.sprintf("%IP.src% > %IP.dst% %IP.proto%")
6526 s += " frag:%i" % self.frag
6533 fields_desc = [ ShortEnumField("sport", 20, TCP_SERVICES),
6534 ShortEnumField("dport", 80, TCP_SERVICES),
6537 BitField("dataofs", None, 4),
6538 BitField("reserved", 0, 4),
6539 FlagsField("flags", 0x2, 8, "FSRPAUEC"),
6540 ShortField("window", 8192),
6541 XShortField("chksum", None),
6542 ShortField("urgptr", 0),
6543 TCPOptionsField("options", {}) ]
6544 def post_build(self, p, pay):
6546 dataofs = self.dataofs
6548 dataofs = 5+((len(self.get_field("options").i2m(self,self.options))+3)/4)
6549 p = p[:12]+chr((dataofs << 4) | ord(p[12])&0x0f)+p[13:]
6550 if self.chksum is None:
6551 if isinstance(self.underlayer, IP):
6552 if self.underlayer.len is not None:
6553 ln = self.underlayer.len-20
6556 psdhdr = struct.pack("!4s4sHH",
6557 inet_aton(self.underlayer.src),
6558 inet_aton(self.underlayer.dst),
6559 self.underlayer.proto,
6561 ck=checksum(psdhdr+p)
6562 p = p[:16]+struct.pack("!H", ck)+p[18:]
6563 elif isinstance(self.underlayer, IPv6) or isinstance(self.underlayer, _IPv6OptionHeader):
6564 ck = in6_chksum(socket.IPPROTO_TCP, self.underlayer, p)
6565 p = p[:16]+struct.pack("!H", ck)+p[18:]
6567 warning("No IP underlayer to compute checksum. Leaving null.")
6571 return struct.pack("H",self.sport ^ self.dport)+self.payload.hashret()
6573 return self.payload.hashret()
6574 def answers(self, other):
6575 if not isinstance(other, TCP):
6578 if not ((self.sport == other.dport) and
6579 (self.dport == other.sport)):
6581 if (abs(other.seq-self.ack) > 2+len(other.payload)):
6584 def mysummary(self):
6585 if isinstance(self.underlayer, IP):
6586 return self.underlayer.sprintf("TCP %IP.src%:%TCP.sport% > %IP.dst%:%TCP.dport% %TCP.flags%")
6587 elif isinstance(self.underlayer, IPv6):
6588 return self.underlayer.sprintf("TCP %IPv6.src%:%TCP.sport% > %IPv6.dst%:%TCP.dport% %TCP.flags%")
6590 return self.sprintf("TCP %TCP.sport% > %TCP.dport% %TCP.flags%")
6594 fields_desc = [ ShortEnumField("sport", 53, UDP_SERVICES),
6595 ShortEnumField("dport", 53, UDP_SERVICES),
6596 ShortField("len", None),
6597 XShortField("chksum", None), ]
6598 def post_build(self, p, pay):
6603 p = p[:4]+struct.pack("!H",l)+p[6:]
6604 if self.chksum is None:
6605 if isinstance(self.underlayer, IP):
6606 if self.underlayer.len is not None:
6607 ln = self.underlayer.len-20
6610 psdhdr = struct.pack("!4s4sHH",
6611 inet_aton(self.underlayer.src),
6612 inet_aton(self.underlayer.dst),
6613 self.underlayer.proto,
6615 ck=checksum(psdhdr+p)
6616 p = p[:6]+struct.pack("!H", ck)+p[8:]
6617 elif isinstance(self.underlayer, IPv6) or isinstance(self.underlayer, _IPv6OptionHeader):
6618 ck = in6_chksum(socket.IPPROTO_UDP, self.underlayer, p)
6619 p = p[:6]+struct.pack("!H", ck)+p[8:]
6621 warning("No IP underlayer to compute checksum. Leaving null.")
6623 def extract_padding(self, s):
6627 return self.payload.hashret()
6628 def answers(self, other):
6629 if not isinstance(other, UDP):
6632 if self.dport != other.sport:
6634 return self.payload.answers(other.payload)
6635 def mysummary(self):
6636 if isinstance(self.underlayer, IP):
6637 return self.underlayer.sprintf("UDP %IP.src%:%UDP.sport% > %IP.dst%:%UDP.dport%")
6638 elif isinstance(self.underlayer, IPv6):
6639 return self.underlayer.sprintf("UDP %IPv6.src%:%UDP.sport% > %IPv6.dst%:%UDP.dport%")
6641 return self.sprintf("UDP %UDP.sport% > %UDP.dport%")
6643 icmptypes = { 0 : "echo-reply",
6645 4 : "source-quench",
6648 9 : "router-advertisement",
6649 10 : "router-solicitation",
6650 11 : "time-exceeded",
6651 12 : "parameter-problem",
6652 13 : "timestamp-request",
6653 14 : "timestamp-reply",
6654 15 : "information-request",
6655 16 : "information-response",
6656 17 : "address-mask-request",
6657 18 : "address-mask-reply" }
6661 fields_desc = [ ByteEnumField("type",8, icmptypes),
6662 ByteField("code",0),
6663 XShortField("chksum", None),
6664 ConditionalField(XShortField("id",0), lambda pkt:pkt.type in [0,8,13,14,15,16]),
6665 ConditionalField(XShortField("seq",0), lambda pkt:pkt.type in [0,8,13,14,15,16]),
6666 ConditionalField(ICMPTimeStampField("ts_ori", None), lambda pkt:pkt.type in [13,14]),
6667 ConditionalField(ICMPTimeStampField("ts_rx", None), lambda pkt:pkt.type in [13,14]),
6668 ConditionalField(ICMPTimeStampField("ts_tx", None), lambda pkt:pkt.type in [13,14]),
6669 ConditionalField(IPField("gw","0.0.0.0"), lambda pkt:pkt.type==5),
6670 ConditionalField(ByteField("ptr",0), lambda pkt:pkt.type==12),
6671 ConditionalField(X3BytesField("reserved",0), lambda pkt:pkt.type==12),
6672 ConditionalField(IntField("unused",0), lambda pkt:pkt.type not in [0,5,8,12,13,14,15,16]),
6674 def post_build(self, p, pay):
6676 if self.chksum is None:
6678 p = p[:2]+chr(ck>>8)+chr(ck&0xff)+p[4:]
6682 return struct.pack("HH",self.id,self.seq)+self.payload.hashret()
6683 def answers(self, other):
6684 if not isinstance(other,ICMP):
6686 if ( (other.type,self.type) in [(8,0),(13,14),(15,16),(17,18)] and
6687 self.id == other.id and
6688 self.seq == other.seq ):
6692 def guess_payload_class(self, payload):
6693 if self.type in [3,4,5,11,12]:
6697 def mysummary(self):
6698 if isinstance(self.underlayer, IP):
6699 return self.underlayer.sprintf("ICMP %IP.src% > %IP.dst% %ICMP.type% %ICMP.code%")
6701 return self.sprintf("ICMP %ICMP.type% %ICMP.code%")
6709 def answers(self, other):
6710 if not isinstance(other, IP):
6712 if not ( ((conf.checkIPsrc == 0) or (self.dst == other.dst)) and
6713 (self.src == other.src) and
6714 ( ((conf.checkIPID == 0)
6715 or (self.id == other.id)
6716 or (conf.checkIPID == 1 and self.id == socket.htons(other.id)))) and
6717 (self.proto == other.proto) ):
6719 return self.payload.answers(other.payload)
6720 def mysummary(self):
6721 return Packet.mysummary(self)
6724 class TCPerror(TCP):
6725 name = "TCP in ICMP"
6726 def answers(self, other):
6727 if not isinstance(other, TCP):
6730 if not ((self.sport == other.sport) and
6731 (self.dport == other.dport)):
6733 if conf.check_TCPerror_seqack:
6734 if self.seq is not None:
6735 if self.seq != other.seq:
6737 if self.ack is not None:
6738 if self.ack != other.ack:
6741 def mysummary(self):
6742 return Packet.mysummary(self)
6745 class UDPerror(UDP):
6746 name = "UDP in ICMP"
6747 def answers(self, other):
6748 if not isinstance(other, UDP):
6751 if not ((self.sport == other.sport) and
6752 (self.dport == other.dport)):
6755 def mysummary(self):
6756 return Packet.mysummary(self)
6760 class ICMPerror(ICMP):
6761 name = "ICMP in ICMP"
6762 def answers(self, other):
6763 if not isinstance(other,ICMP):
6765 if not ((self.type == other.type) and
6766 (self.code == other.code)):
6768 if self.code in [0,8,13,14,17,18]:
6769 if (self.id == other.id and
6770 self.seq == other.seq):
6776 def mysummary(self):
6777 return Packet.mysummary(self)
6780 """See http://namabiiru.hongo.wide.ad.jp/scapy6"""
6781 name = "IPv6 not implemented here."
6782 def __init__(self, *args, **kargs):
6783 log_interactive.error(self.name)
6785 return "<IPv6: ERROR not implemented>"
6787 class _IPv6OptionHeader(Packet):
6788 """See http://namabiiru.hongo.wide.ad.jp/scapy6"""
6789 name = "IPv6 not implemented here."
6790 def __init__(self, *args, **kargs):
6791 log_interactive.error(self.name)
6793 return "<IPv6: ERROR not implemented>"
6797 fields_desc = [ ShortEnumField("pkt_type",2,{2:"data"}),
6798 ShortField("len", None),
6799 ShortField("tunnel_id", 0),
6800 ShortField("session_id", 0),
6801 ShortField("ns", 0),
6802 ShortField("nr", 0),
6803 ShortField("offset", 0) ]
6805 def post_build(self, pkt, pay):
6806 if self.len is None:
6807 l = len(pkt)+len(pay)
6808 pkt = pkt[:2]+struct.pack("!H", l)+pkt[4:]
6812 _PPP_proto = { 0x0001: "Padding Protocol",
6813 0x0003: "ROHC small-CID [RFC3095]",
6814 0x0005: "ROHC large-CID [RFC3095]",
6815 0x0021: "Internet Protocol version 4",
6816 0x0023: "OSI Network Layer",
6817 0x0025: "Xerox NS IDP",
6818 0x0027: "DECnet Phase IV",
6819 0x0029: "Appletalk",
6820 0x002b: "Novell IPX",
6821 0x002d: "Van Jacobson Compressed TCP/IP",
6822 0x002f: "Van Jacobson Uncompressed TCP/IP",
6823 0x0031: "Bridging PDU",
6824 0x0033: "Stream Protocol (ST-II)",
6825 0x0035: "Banyan Vines",
6826 0x0037: "reserved (until 1993) [Typo in RFC1172]",
6827 0x0039: "AppleTalk EDDP",
6828 0x003b: "AppleTalk SmartBuffered",
6829 0x003d: "Multi-Link [RFC1717]",
6830 0x003f: "NETBIOS Framing",
6831 0x0041: "Cisco Systems",
6832 0x0043: "Ascom Timeplex",
6833 0x0045: "Fujitsu Link Backup and Load Balancing (LBLB)",
6834 0x0047: "DCA Remote Lan",
6835 0x0049: "Serial Data Transport Protocol (PPP-SDTP)",
6836 0x004b: "SNA over 802.2",
6838 0x004f: "IPv6 Header Compression",
6839 0x0051: "KNX Bridging Data [ianp]",
6840 0x0053: "Encryption [Meyer]",
6841 0x0055: "Individual Link Encryption [Meyer]",
6842 0x0057: "Internet Protocol version 6 [Hinden]",
6843 0x0059: "PPP Muxing [RFC3153]",
6844 0x005b: "Vendor-Specific Network Protocol (VSNP) [RFC3772]",
6845 0x0061: "RTP IPHC Full Header [RFC3544]",
6846 0x0063: "RTP IPHC Compressed TCP [RFC3544]",
6847 0x0065: "RTP IPHC Compressed Non TCP [RFC3544]",
6848 0x0067: "RTP IPHC Compressed UDP 8 [RFC3544]",
6849 0x0069: "RTP IPHC Compressed RTP 8 [RFC3544]",
6850 0x006f: "Stampede Bridging",
6851 0x0071: "Reserved [Fox]",
6852 0x0073: "MP+ Protocol [Smith]",
6853 0x007d: "reserved (Control Escape) [RFC1661]",
6854 0x007f: "reserved (compression inefficient [RFC1662]",
6855 0x0081: "Reserved Until 20-Oct-2000 [IANA]",
6856 0x0083: "Reserved Until 20-Oct-2000 [IANA]",
6857 0x00c1: "NTCITS IPI [Ungar]",
6858 0x00cf: "reserved (PPP NLID)",
6859 0x00fb: "single link compression in multilink [RFC1962]",
6860 0x00fd: "compressed datagram [RFC1962]",
6861 0x00ff: "reserved (compression inefficient)",
6862 0x0201: "802.1d Hello Packets",
6863 0x0203: "IBM Source Routing BPDU",
6864 0x0205: "DEC LANBridge100 Spanning Tree",
6865 0x0207: "Cisco Discovery Protocol [Sastry]",
6866 0x0209: "Netcs Twin Routing [Korfmacher]",
6867 0x020b: "STP - Scheduled Transfer Protocol [Segal]",
6868 0x020d: "EDP - Extreme Discovery Protocol [Grosser]",
6869 0x0211: "Optical Supervisory Channel Protocol (OSCP)[Prasad]",
6870 0x0213: "Optical Supervisory Channel Protocol (OSCP)[Prasad]",
6872 0x0233: "Sigma Network Systems",
6873 0x0235: "Apple Client Server Protocol [Ridenour]",
6874 0x0281: "MPLS Unicast [RFC3032] ",
6875 0x0283: "MPLS Multicast [RFC3032]",
6876 0x0285: "IEEE p1284.4 standard - data packets [Batchelder]",
6877 0x0287: "ETSI TETRA Network Protocol Type 1 [Nieminen]",
6878 0x0289: "Multichannel Flow Treatment Protocol [McCann]",
6879 0x2063: "RTP IPHC Compressed TCP No Delta [RFC3544]",
6880 0x2065: "RTP IPHC Context State [RFC3544]",
6881 0x2067: "RTP IPHC Compressed UDP 16 [RFC3544]",
6882 0x2069: "RTP IPHC Compressed RTP 16 [RFC3544]",
6883 0x4001: "Cray Communications Control Protocol [Stage]",
6884 0x4003: "CDPD Mobile Network Registration Protocol [Quick]",
6885 0x4005: "Expand accelerator protocol [Rachmani]",
6886 0x4007: "ODSICP NCP [Arvind]",
6887 0x4009: "DOCSIS DLL [Gaedtke]",
6888 0x400B: "Cetacean Network Detection Protocol [Siller]",
6889 0x4021: "Stacker LZS [Simpson]",
6890 0x4023: "RefTek Protocol [Banfill]",
6891 0x4025: "Fibre Channel [Rajagopal]",
6892 0x4027: "EMIT Protocols [Eastham]",
6893 0x405b: "Vendor-Specific Protocol (VSP) [RFC3772]",
6894 0x8021: "Internet Protocol Control Protocol",
6895 0x8023: "OSI Network Layer Control Protocol",
6896 0x8025: "Xerox NS IDP Control Protocol",
6897 0x8027: "DECnet Phase IV Control Protocol",
6898 0x8029: "Appletalk Control Protocol",
6899 0x802b: "Novell IPX Control Protocol",
6902 0x8031: "Bridging NCP",
6903 0x8033: "Stream Protocol Control Protocol",
6904 0x8035: "Banyan Vines Control Protocol",
6905 0x8037: "reserved (until 1993)",
6908 0x803d: "Multi-Link Control Protocol",
6909 0x803f: "NETBIOS Framing Control Protocol",
6910 0x8041: "Cisco Systems Control Protocol",
6911 0x8043: "Ascom Timeplex",
6912 0x8045: "Fujitsu LBLB Control Protocol",
6913 0x8047: "DCA Remote Lan Network Control Protocol (RLNCP)",
6914 0x8049: "Serial Data Control Protocol (PPP-SDCP)",
6915 0x804b: "SNA over 802.2 Control Protocol",
6916 0x804d: "SNA Control Protocol",
6917 0x804f: "IP6 Header Compression Control Protocol",
6918 0x8051: "KNX Bridging Control Protocol [ianp]",
6919 0x8053: "Encryption Control Protocol [Meyer]",
6920 0x8055: "Individual Link Encryption Control Protocol [Meyer]",
6921 0x8057: "IPv6 Control Protovol [Hinden]",
6922 0x8059: "PPP Muxing Control Protocol [RFC3153]",
6923 0x805b: "Vendor-Specific Network Control Protocol (VSNCP) [RFC3772]",
6924 0x806f: "Stampede Bridging Control Protocol",
6925 0x8073: "MP+ Control Protocol [Smith]",
6926 0x8071: "Reserved [Fox]",
6927 0x807d: "Not Used - reserved [RFC1661]",
6928 0x8081: "Reserved Until 20-Oct-2000 [IANA]",
6929 0x8083: "Reserved Until 20-Oct-2000 [IANA]",
6930 0x80c1: "NTCITS IPI Control Protocol [Ungar]",
6931 0x80cf: "Not Used - reserved [RFC1661]",
6932 0x80fb: "single link compression in multilink control [RFC1962]",
6933 0x80fd: "Compression Control Protocol [RFC1962]",
6934 0x80ff: "Not Used - reserved [RFC1661]",
6935 0x8207: "Cisco Discovery Protocol Control [Sastry]",
6936 0x8209: "Netcs Twin Routing [Korfmacher]",
6937 0x820b: "STP - Control Protocol [Segal]",
6938 0x820d: "EDPCP - Extreme Discovery Protocol Ctrl Prtcl [Grosser]",
6939 0x8235: "Apple Client Server Protocol Control [Ridenour]",
6940 0x8281: "MPLSCP [RFC3032]",
6941 0x8285: "IEEE p1284.4 standard - Protocol Control [Batchelder]",
6942 0x8287: "ETSI TETRA TNP1 Control Protocol [Nieminen]",
6943 0x8289: "Multichannel Flow Treatment Protocol [McCann]",
6944 0xc021: "Link Control Protocol",
6945 0xc023: "Password Authentication Protocol",
6946 0xc025: "Link Quality Report",
6947 0xc027: "Shiva Password Authentication Protocol",
6948 0xc029: "CallBack Control Protocol (CBCP)",
6949 0xc02b: "BACP Bandwidth Allocation Control Protocol [RFC2125]",
6950 0xc02d: "BAP [RFC2125]",
6951 0xc05b: "Vendor-Specific Authentication Protocol (VSAP) [RFC3772]",
6952 0xc081: "Container Control Protocol [KEN]",
6953 0xc223: "Challenge Handshake Authentication Protocol",
6954 0xc225: "RSA Authentication Protocol [Narayana]",
6955 0xc227: "Extensible Authentication Protocol [RFC2284]",
6956 0xc229: "Mitsubishi Security Info Exch Ptcl (SIEP) [Seno]",
6957 0xc26f: "Stampede Bridging Authorization Protocol",
6958 0xc281: "Proprietary Authentication Protocol [KEN]",
6959 0xc283: "Proprietary Authentication Protocol [Tackabury]",
6960 0xc481: "Proprietary Node ID Authentication Protocol [KEN]"}
6964 fields_desc = [ XByteField("address",0xff),
6965 XByteField("control",0x03) ]
6967 class PPP_metaclass(Packet_metaclass):
6968 def __call__(self, _pkt=None, *args, **kargs):
6970 if _pkt and _pkt[0] == '\xff':
6972 i = cls.__new__(cls, cls.__name__, cls.__bases__, cls.__dict__)
6973 i.__init__(_pkt=_pkt, *args, **kargs)
6978 __metaclass__ = PPP_metaclass
6979 name = "PPP Link Layer"
6980 fields_desc = [ ShortEnumField("proto", 0x0021, _PPP_proto) ]
6982 _PPP_conftypes = { 1:"Configure-Request",
6985 4:"Configure-Reject",
6986 5:"Terminate-Request",
6989 8:"Protocol-Reject",
6992 11:"Discard-Request",
6997 class PPP_Option_metaclass(Packet_metaclass):
6999 def __call__(self, _pkt=None, *args, **kargs):
7003 cls = self._known_options.get(t,self)
7004 i = cls.__new__(cls, cls.__name__, cls.__bases__, cls.__dict__)
7005 i.__init__(_pkt=_pkt, *args, **kargs)
7007 def _register(self, cls):
7008 self._known_options[cls.fields_desc[0].default] = cls
7011 ### PPP IPCP stuff (RFC 1332)
7013 # All IPCP options are defined below (names and associated classes)
7014 _PPP_ipcpopttypes = { 1:"IP-Addresses (Deprecated)",
7015 2:"IP-Compression-Protocol",
7017 4:"Mobile-IPv4", # not implemented, present for completeness
7018 129:"Primary-DNS-Address",
7019 130:"Primary-NBNS-Address",
7020 131:"Secondary-DNS-Address",
7021 132:"Secondary-NBNS-Address"}
7025 class PPP_IPCP_Option_metaclass(PPP_Option_metaclass):
7029 class PPP_IPCP_Option(Packet):
7030 __metaclass__=PPP_IPCP_Option_metaclass
7031 name = "PPP IPCP Option"
7032 fields_desc = [ ByteEnumField("type" , None , _PPP_ipcpopttypes),
7033 FieldLenField("len", None, length_of="data", fmt="B", adjust=lambda p,x:x+2),
7034 StrLenField("data", "", length_from=lambda p:max(0,p.len-2)) ]
7035 def extract_padding(self, pay):
7038 class PPP_IPCP_Specific_Option_metaclass(PPP_IPCP_Option_metaclass):
7039 def __new__(cls, name, bases, dct):
7040 newcls = super(PPP_IPCP_Specific_Option_metaclass, cls).__new__(cls, name, bases, dct)
7041 PPP_IPCP_Option._register(newcls)
7044 class PPP_IPCP_Option_IPAddress(PPP_IPCP_Option):
7045 __metaclass__=PPP_IPCP_Specific_Option_metaclass
7046 name = "PPP IPCP Option: IP Address"
7047 fields_desc = [ ByteEnumField("type" , 3 , _PPP_ipcpopttypes),
7048 FieldLenField("len", None, length_of="data", fmt="B", adjust=lambda p,x:x+6),
7049 IPField("data","0.0.0.0"),
7050 ConditionalField(StrLenField("garbage","", length_from=lambda pkt:pkt.len-6), lambda p:p.len!=6) ]
7052 class PPP_IPCP_Option_DNS1(PPP_IPCP_Option):
7053 __metaclass__=PPP_IPCP_Specific_Option_metaclass
7054 name = "PPP IPCP Option: DNS1 Address"
7055 fields_desc = [ ByteEnumField("type" , 129 , _PPP_ipcpopttypes),
7056 FieldLenField("len", None, length_of="data", fmt="B", adjust=lambda p,x:x+6),
7057 IPField("data","0.0.0.0"),
7058 ConditionalField(StrLenField("garbage","", length_from=lambda pkt:pkt.len-6), lambda p:p.len!=6) ]
7060 class PPP_IPCP_Option_DNS2(PPP_IPCP_Option):
7061 __metaclass__=PPP_IPCP_Specific_Option_metaclass
7062 name = "PPP IPCP Option: DNS2 Address"
7063 fields_desc = [ ByteEnumField("type" , 131 , _PPP_ipcpopttypes),
7064 FieldLenField("len", None, length_of="data", fmt="B", adjust=lambda p,x:x+6),
7065 IPField("data","0.0.0.0"),
7066 ConditionalField(StrLenField("garbage","", length_from=lambda pkt:pkt.len-6), lambda p:p.len!=6) ]
7068 class PPP_IPCP_Option_NBNS1(PPP_IPCP_Option):
7069 __metaclass__=PPP_IPCP_Specific_Option_metaclass
7070 name = "PPP IPCP Option: NBNS1 Address"
7071 fields_desc = [ ByteEnumField("type" , 130 , _PPP_ipcpopttypes),
7072 FieldLenField("len", None, length_of="data", fmt="B", adjust=lambda p,x:x+6),
7073 IPField("data","0.0.0.0"),
7074 ConditionalField(StrLenField("garbage","", length_from=lambda pkt:pkt.len-6), lambda p:p.len!=6) ]
7076 class PPP_IPCP_Option_NBNS2(PPP_IPCP_Option):
7077 __metaclass__=PPP_IPCP_Specific_Option_metaclass
7078 name = "PPP IPCP Option: NBNS2 Address"
7079 fields_desc = [ ByteEnumField("type" , 132 , _PPP_ipcpopttypes),
7080 FieldLenField("len", None, length_of="data", fmt="B", adjust=lambda p,x:x+6),
7081 IPField("data","0.0.0.0"),
7082 ConditionalField(StrLenField("garbage","", length_from=lambda pkt:pkt.len-6), lambda p:p.len!=6) ]
7087 class PPP_IPCP(Packet):
7088 fields_desc = [ ByteEnumField("code" , 1, _PPP_conftypes),
7089 XByteField("id", 0 ),
7090 FieldLenField("len" , None, fmt="H", length_of="options", adjust=lambda p,x:x+4 ),
7091 PacketListField("options", [], PPP_IPCP_Option, length_from=lambda p:p.len-4,) ]
7096 _PPP_ecpopttypes = { 0:"OUI",
7099 class PPP_ECP_Option_metaclass(PPP_Option_metaclass):
7104 class PPP_ECP_Option(Packet):
7105 __metaclass__=PPP_ECP_Option_metaclass
7106 name = "PPP ECP Option"
7107 fields_desc = [ ByteEnumField("type" , None , _PPP_ecpopttypes),
7108 FieldLenField("len", None, length_of="data", fmt="B", adjust=lambda p,x:x+2),
7109 StrLenField("data", "", length_from=lambda p:max(0,p.len-2)) ]
7110 def extract_padding(self, pay):
7113 class PPP_ECP_Specific_Option_metaclass(PPP_ECP_Option_metaclass):
7114 def __new__(cls, name, bases, dct):
7115 newcls = super(PPP_ECP_Specific_Option_metaclass, cls).__new__(cls, name, bases, dct)
7116 PPP_ECP_Option._register(newcls)
7119 class PPP_ECP_Option_OUI(PPP_ECP_Option):
7120 __metaclass__=PPP_ECP_Specific_Option_metaclass
7121 fields_desc = [ ByteEnumField("type" , 0 , _PPP_ecpopttypes),
7122 FieldLenField("len", None, length_of="data", fmt="B", adjust=lambda p,x:x+2),
7123 StrFixedLenField("oui","",3),
7124 ByteField("subtype",0),
7125 StrLenField("data", "", length_from=lambda p:p.len-6) ]
7129 class PPP_ECP(Packet):
7130 fields_desc = [ ByteEnumField("code" , 1, _PPP_conftypes),
7131 XByteField("id", 0 ),
7132 FieldLenField("len" , None, fmt="H", length_of="options", adjust=lambda p,x:x+4 ),
7133 PacketListField("options", [], PPP_ECP_Option, length_from=lambda p:p.len-4,) ]
7140 fields_desc = [ ShortField("id",0),
7141 BitField("qr",0, 1),
7142 BitEnumField("opcode", 0, 4, {0:"QUERY",1:"IQUERY",2:"STATUS"}),
7143 BitField("aa", 0, 1),
7144 BitField("tc", 0, 1),
7145 BitField("rd", 0, 1),
7146 BitField("ra", 0 ,1),
7147 BitField("z", 0, 3),
7148 BitEnumField("rcode", 0, 4, {0:"ok", 1:"format-error", 2:"server-failure", 3:"name-error", 4:"not-implemented", 5:"refused"}),
7149 DNSRRCountField("qdcount", None, "qd"),
7150 DNSRRCountField("ancount", None, "an"),
7151 DNSRRCountField("nscount", None, "ns"),
7152 DNSRRCountField("arcount", None, "ar"),
7153 DNSQRField("qd", "qdcount"),
7154 DNSRRField("an", "ancount"),
7155 DNSRRField("ns", "nscount"),
7156 DNSRRField("ar", "arcount",0) ]
7157 def answers(self, other):
7158 return (isinstance(other, DNS)
7159 and self.id == other.id
7163 def mysummary(self):
7164 type = ["Qry","Ans"][self.qr]
7168 if self.ancount > 0 and isinstance(self.an, DNSRR):
7169 name = ' "%s"' % self.an.rdata
7172 if self.qdcount > 0 and isinstance(self.qd, DNSQR):
7173 name = ' "%s"' % self.qd.qname
7174 return 'DNS %s%s ' % (type, name)
7176 dnstypes = { 0:"ANY", 255:"ALL",
7177 1:"A", 2:"NS", 3:"MD", 4:"MD", 5:"CNAME", 6:"SOA", 7: "MB", 8:"MG",
7178 9:"MR",10:"NULL",11:"WKS",12:"PTR",13:"HINFO",14:"MINFO",15:"MX",16:"TXT",
7179 17:"RP",18:"AFSDB",28:"AAAA", 33:"SRV",38:"A6",39:"DNAME"}
7181 dnsqtypes = {251:"IXFR",252:"AXFR",253:"MAILB",254:"MAILA",255:"ALL"}
7182 dnsqtypes.update(dnstypes)
7183 dnsclasses = {1: 'IN', 2: 'CS', 3: 'CH', 4: 'HS', 255: 'ANY'}
7186 class DNSQR(Packet):
7187 name = "DNS Question Record"
7189 fields_desc = [ DNSStrField("qname",""),
7190 ShortEnumField("qtype", 1, dnsqtypes),
7191 ShortEnumField("qclass", 1, dnsclasses) ]
7195 class DNSRR(Packet):
7196 name = "DNS Resource Record"
7198 fields_desc = [ DNSStrField("rrname",""),
7199 ShortEnumField("type", 1, dnstypes),
7200 ShortEnumField("rclass", 1, dnsclasses),
7202 RDLenField("rdlen"),
7203 RDataField("rdata", "", length_from=lambda pkt:pkt.rdlen) ]
7208 class BOOTP(Packet):
7210 fields_desc = [ ByteEnumField("op",1, {1:"BOOTREQUEST", 2:"BOOTREPLY"}),
7211 ByteField("htype",1),
7212 ByteField("hlen",6),
7213 ByteField("hops",0),
7215 ShortField("secs",0),
7216 FlagsField("flags", 0, 16, "???????????????B"),
7217 IPField("ciaddr","0.0.0.0"),
7218 IPField("yiaddr","0.0.0.0"),
7219 IPField("siaddr","0.0.0.0"),
7220 IPField("giaddr","0.0.0.0"),
7221 Field("chaddr","", "16s"),
7222 Field("sname","","64s"),
7223 Field("file","","128s"),
7224 StrField("options","") ]
7225 def guess_payload_class(self, payload):
7226 if self.options[:len(dhcpmagic)] == dhcpmagic:
7229 return Packet.guess_payload_class(self, payload)
7230 def extract_padding(self,s):
7231 if self.options[:len(dhcpmagic)] == dhcpmagic:
7232 # set BOOTP options to DHCP magic cookie and make rest a payload of DHCP options
7233 payload = self.options[len(dhcpmagic):]
7234 self.options = self.options[:len(dhcpmagic)]
7235 return payload, None
7239 return struct.pack("L", self.xid)
7240 def answers(self, other):
7241 if not isinstance(other, BOOTP):
7243 return self.xid == other.xid
7247 #DHCP_UNKNOWN, DHCP_IP, DHCP_IPLIST, DHCP_TYPE \
7262 11:"lease_unassigned",
7269 1: IPField("subnet_mask", "0.0.0.0"),
7271 3: IPField("router","0.0.0.0"),
7272 4: IPField("time_server","0.0.0.0"),
7273 5: IPField("IEN_name_server","0.0.0.0"),
7274 6: IPField("name_server","0.0.0.0"),
7275 7: IPField("log_server","0.0.0.0"),
7276 8: IPField("cookie_server","0.0.0.0"),
7277 9: IPField("lpr_server","0.0.0.0"),
7281 17: "root_disk_path",
7282 22: "max_dgram_reass_size",
7285 28: IPField("broadcast_address","0.0.0.0"),
7286 35: "arp_cache_timeout",
7287 36: "ether_or_dot3",
7289 38: "tcp_keepalive_interval",
7290 39: "tcp_keepalive_garbage",
7292 41: IPField("NIS_server","0.0.0.0"),
7293 42: IPField("NTP_server","0.0.0.0"),
7294 43: "vendor_specific",
7295 44: IPField("NetBIOS_server","0.0.0.0"),
7296 45: IPField("NetBIOS_dist_server","0.0.0.0"),
7297 50: IPField("requested_addr","0.0.0.0"),
7298 51: IntField("lease_time", 43200),
7299 54: IPField("server_id","0.0.0.0"),
7300 55: "param_req_list",
7301 57: ShortField("max_dhcp_size", 1500),
7302 58: IntField("renewal_time", 21600),
7303 59: IntField("rebinding_time", 37800),
7304 60: "vendor_class_id",
7307 64: "NISplus_domain",
7308 65: IPField("NISplus_server","0.0.0.0"),
7309 69: IPField("SMTP_server","0.0.0.0"),
7310 70: IPField("POP3_server","0.0.0.0"),
7311 71: IPField("NNTP_server","0.0.0.0"),
7312 72: IPField("WWW_server","0.0.0.0"),
7313 73: IPField("Finger_server","0.0.0.0"),
7314 74: IPField("IRC_server","0.0.0.0"),
7315 75: IPField("StreetTalk_server","0.0.0.0"),
7316 76: "StreetTalk_Dir_Assistance",
7317 82: "relay_agent_Information",
7318 53: ByteEnumField("message-type", 1, DHCPTypes),
7319 # 55: DHCPRequestListField("request-list"),
7325 for k,v in DHCPOptions.iteritems():
7331 DHCPRevOptions[n] = (k,v)
7340 class DHCPOptionsField(StrField):
7342 def i2repr(self,pkt,x):
7345 if type(v) is tuple and len(v) in [2,3]:
7346 if DHCPRevOptions.has_key(v[0]) and isinstance(DHCPRevOptions[v[0]][1],Field):
7347 f = DHCPRevOptions[v[0]][1]
7348 vv = f.i2repr(pkt,v[1])
7351 r = "%s=%s" % (v[0],vv)
7353 r += " (garbage=%r)" % v[2]
7357 return "[%s]" % (" ".join(s))
7359 def getfield(self, pkt, s):
7360 return "", self.m2i(pkt, s)
7361 def m2i(self, pkt, x):
7373 if len(x) < 2 or len(x) < ord(x[1])+2:
7376 elif DHCPOptions.has_key(o):
7379 if isinstance(f, str):
7381 opt.append( (f,x[2:olen+2]) )
7386 left, val = f.getfield(pkt,x[2:olen+2])
7391 otuple = (f.name, val, left)
7393 otuple = (f.name, val)
7398 opt.append((o, x[2:olen+2]))
7401 def i2m(self, pkt, x):
7406 if type(o) is tuple and len(o) in [2,3]:
7409 if isinstance(name, int):
7410 onum, oval = name, val
7411 elif DHCPRevOptions.has_key(name):
7412 onum, f = DHCPRevOptions[name]
7416 oval = f.addfield(pkt,"",f.any2i(pkt,val))
7418 warning("Unknown field option %s" % name)
7427 elif (type(o) is str and DHCPRevOptions.has_key(o) and
7428 DHCPRevOptions[o][1] == None):
7429 s += chr(DHCPRevOptions[o][0])
7430 elif type(o) is int:
7432 elif type(o) is str:
7435 warning("Malformed option %s" % o)
7440 name = "DHCP options"
7441 fields_desc = [ DHCPOptionsField("options","") ]
7444 class Dot11(Packet):
7447 BitField("subtype", 0, 4),
7448 BitEnumField("type", 0, 2, ["Management", "Control", "Data", "Reserved"]),
7449 BitField("proto", 0, 2),
7450 FlagsField("FCfield", 0, 8, ["to-DS", "from-DS", "MF", "retry", "pw-mgt", "MD", "wep", "order"]),
7452 MACField("addr1", ETHER_ANY),
7453 Dot11Addr2MACField("addr2", ETHER_ANY),
7454 Dot11Addr3MACField("addr3", ETHER_ANY),
7455 Dot11SCField("SC", 0),
7456 Dot11Addr4MACField("addr4", ETHER_ANY)
7458 def mysummary(self):
7459 return self.sprintf("802.11 %Dot11.type% %Dot11.subtype% %Dot11.addr2% > %Dot11.addr1%")
7460 def guess_payload_class(self, payload):
7461 if self.type == 0x02 and (self.subtype >= 0x08 and self.subtype <=0xF and self.subtype != 0xD):
7463 elif self.FCfield & 0x40:
7466 return Packet.guess_payload_class(self, payload)
7467 def answers(self, other):
7468 if isinstance(other,Dot11):
7469 if self.type == 0: # management
7470 if self.addr1.lower() != other.addr2.lower(): # check resp DA w/ req SA
7472 if (other.subtype,self.subtype) in [(0,1),(2,3),(4,5)]:
7474 if self.subtype == other.subtype == 11: # auth
7475 return self.payload.answers(other.payload)
7476 elif self.type == 1: # control
7478 elif self.type == 2: # data
7479 return self.payload.answers(other.payload)
7480 elif self.type == 3: # reserved
7483 def unwep(self, key=None, warn=1):
7484 if self.FCfield & 0x40 == 0:
7486 warning("No WEP to remove")
7488 if isinstance(self.payload.payload, NoPayload):
7489 if key or conf.wepkey:
7490 self.payload.decrypt(key)
7491 if isinstance(self.payload.payload, NoPayload):
7493 warning("Dot11 can't be decrypted. Check conf.wepkey.")
7495 self.FCfield &= ~0x40
7496 self.payload=self.payload.payload
7499 class Dot11QoS(Packet):
7501 fields_desc = [ BitField("TID",None,4),
7502 BitField("EOSP",None,1),
7503 BitField("Ack Policy",None,2),
7504 BitField("Reserved",None,1),
7505 ByteField("TXOP",None) ]
7506 def guess_payload_class(self, payload):
7507 if isinstance(self.underlayer, Dot11):
7508 if self.underlayer.FCfield & 0x40:
7510 return Packet.guess_payload_class(self, payload)
7513 capability_list = [ "res8", "res9", "short-slot", "res11",
7514 "res12", "DSSS-OFDM", "res14", "res15",
7515 "ESS", "IBSS", "CFP", "CFP-req",
7516 "privacy", "short-preamble", "PBCC", "agility"]
7518 reason_code = {0:"reserved",1:"unspec", 2:"auth-expired",
7519 3:"deauth-ST-leaving",
7520 4:"inactivity", 5:"AP-full", 6:"class2-from-nonauth",
7521 7:"class3-from-nonass", 8:"disas-ST-leaving",
7524 status_code = {0:"success", 1:"failure", 10:"cannot-support-all-cap",
7525 11:"inexist-asso", 12:"asso-denied", 13:"algo-unsupported",
7526 14:"bad-seq-num", 15:"challenge-failure",
7527 16:"timeout", 17:"AP-full",18:"rate-unsupported" }
7529 class Dot11Beacon(Packet):
7530 name = "802.11 Beacon"
7531 fields_desc = [ LELongField("timestamp", 0),
7532 LEShortField("beacon_interval", 0x0064),
7533 FlagsField("cap", 0, 16, capability_list) ]
7536 class Dot11Elt(Packet):
7537 name = "802.11 Information Element"
7538 fields_desc = [ ByteEnumField("ID", 0, {0:"SSID", 1:"Rates", 2: "FHset", 3:"DSset", 4:"CFset", 5:"TIM", 6:"IBSSset", 16:"challenge",
7539 42:"ERPinfo", 46:"QoS Capability", 47:"ERPinfo", 48:"RSNinfo", 50:"ESRates",221:"vendor",68:"reserved"}),
7540 FieldLenField("len", None, "info", "B"),
7541 StrLenField("info", "", length_from=lambda x:x.len) ]
7542 def mysummary(self):
7544 return "SSID=%s"%repr(self.info),[Dot11]
7548 class Dot11ATIM(Packet):
7549 name = "802.11 ATIM"
7551 class Dot11Disas(Packet):
7552 name = "802.11 Disassociation"
7553 fields_desc = [ LEShortEnumField("reason", 1, reason_code) ]
7555 class Dot11AssoReq(Packet):
7556 name = "802.11 Association Request"
7557 fields_desc = [ FlagsField("cap", 0, 16, capability_list),
7558 LEShortField("listen_interval", 0x00c8) ]
7561 class Dot11AssoResp(Packet):
7562 name = "802.11 Association Response"
7563 fields_desc = [ FlagsField("cap", 0, 16, capability_list),
7564 LEShortField("status", 0),
7565 LEShortField("AID", 0) ]
7567 class Dot11ReassoReq(Packet):
7568 name = "802.11 Reassociation Request"
7569 fields_desc = [ FlagsField("cap", 0, 16, capability_list),
7570 MACField("current_AP", ETHER_ANY),
7571 LEShortField("listen_interval", 0x00c8) ]
7574 class Dot11ReassoResp(Dot11AssoResp):
7575 name = "802.11 Reassociation Response"
7577 class Dot11ProbeReq(Packet):
7578 name = "802.11 Probe Request"
7580 class Dot11ProbeResp(Packet):
7581 name = "802.11 Probe Response"
7582 fields_desc = [ LELongField("timestamp", 0),
7583 LEShortField("beacon_interval", 0x0064),
7584 FlagsField("cap", 0, 16, capability_list) ]
7586 class Dot11Auth(Packet):
7587 name = "802.11 Authentication"
7588 fields_desc = [ LEShortEnumField("algo", 0, ["open", "sharedkey"]),
7589 LEShortField("seqnum", 0),
7590 LEShortEnumField("status", 0, status_code) ]
7591 def answers(self, other):
7592 if self.seqnum == other.seqnum+1:
7596 class Dot11Deauth(Packet):
7597 name = "802.11 Deauthentication"
7598 fields_desc = [ LEShortEnumField("reason", 1, reason_code) ]
7602 class Dot11WEP(Packet):
7603 name = "802.11 WEP packet"
7604 fields_desc = [ StrFixedLenField("iv", "\0\0\0", 3),
7605 ByteField("keyid", 0),
7606 StrField("wepdata",None,remain=4),
7607 IntField("icv",None) ]
7609 def post_dissect(self, s):
7610 # self.icv, = struct.unpack("!I",self.wepdata[-4:])
7611 # self.wepdata = self.wepdata[:-4]
7614 def build_payload(self):
7615 if self.wepdata is None:
7616 return Packet.build_payload(self)
7619 def post_build(self, p, pay):
7620 if self.wepdata is None:
7623 if self.icv is None:
7624 pay += struct.pack("<I",crc32(pay))
7628 c = ARC4.new(self.iv+key)
7629 p = p[:4]+c.encrypt(pay)+icv
7631 warning("No WEP key set (conf.wepkey).. strange results expected..")
7635 def decrypt(self,key=None):
7639 c = ARC4.new(self.iv+key)
7640 self.add_payload(LLC(c.decrypt(self.wepdata)))
7644 class PrismHeader(Packet):
7645 """ iwpriv wlan0 monitor 3 """
7646 name = "Prism header"
7647 fields_desc = [ LEIntField("msgcode",68),
7648 LEIntField("len",144),
7649 StrFixedLenField("dev","",16),
7650 LEIntField("hosttime_did",0),
7651 LEShortField("hosttime_status",0),
7652 LEShortField("hosttime_len",0),
7653 LEIntField("hosttime",0),
7654 LEIntField("mactime_did",0),
7655 LEShortField("mactime_status",0),
7656 LEShortField("mactime_len",0),
7657 LEIntField("mactime",0),
7658 LEIntField("channel_did",0),
7659 LEShortField("channel_status",0),
7660 LEShortField("channel_len",0),
7661 LEIntField("channel",0),
7662 LEIntField("rssi_did",0),
7663 LEShortField("rssi_status",0),
7664 LEShortField("rssi_len",0),
7665 LEIntField("rssi",0),
7666 LEIntField("sq_did",0),
7667 LEShortField("sq_status",0),
7668 LEShortField("sq_len",0),
7670 LEIntField("signal_did",0),
7671 LEShortField("signal_status",0),
7672 LEShortField("signal_len",0),
7673 LESignedIntField("signal",0),
7674 LEIntField("noise_did",0),
7675 LEShortField("noise_status",0),
7676 LEShortField("noise_len",0),
7677 LEIntField("noise",0),
7678 LEIntField("rate_did",0),
7679 LEShortField("rate_status",0),
7680 LEShortField("rate_len",0),
7681 LEIntField("rate",0),
7682 LEIntField("istx_did",0),
7683 LEShortField("istx_status",0),
7684 LEShortField("istx_len",0),
7685 LEIntField("istx",0),
7686 LEIntField("frmlen_did",0),
7687 LEShortField("frmlen_status",0),
7688 LEShortField("frmlen_len",0),
7689 LEIntField("frmlen",0),
7691 def answers(self, other):
7692 if isinstance(other, PrismHeader):
7693 return self.payload.answers(other.payload)
7695 return self.payload.answers(other)
7702 ByteField("version", 0),
7703 ByteEnumField("opcode", 0, { 0:"Hello"}),
7704 ByteEnumField("state", 16, { 16:"Active"}),
7705 ByteField("hellotime", 3),
7706 ByteField("holdtime", 10),
7707 ByteField("priority", 120),
7708 ByteField("group", 1),
7709 ByteField("reserved", 0),
7710 StrFixedLenField("auth","cisco",8),
7711 IPField("virtualIP","192.168.1.1") ]
7723 BitEnumField('leap', 0, 2,
7728 BitField('version', 3, 3),
7729 BitEnumField('mode', 3, 3,
7738 BitField('stratum', 2, 8),
7739 BitField('poll', 0xa, 8), ### XXX : it's a signed int
7740 BitField('precision', 0, 8), ### XXX : it's a signed int
7741 FloatField('delay', 0, 32),
7742 FloatField('dispersion', 0, 32),
7743 IPField('id', "127.0.0.1"),
7744 TimeStampField('ref', 0, 64),
7745 TimeStampField('orig', -1, 64), # -1 means current time
7746 TimeStampField('recv', 0, 64),
7747 TimeStampField('sent', -1, 64)
7749 def mysummary(self):
7750 return self.sprintf("NTP v%ir,NTP.version%, %NTP.mode%")
7755 fields_desc = [ BitField("chksumpresent",0,1),
7756 BitField("reserved0",0,12),
7757 BitField("version",0,3),
7758 XShortEnumField("proto", 0x0000, ETHER_TYPES),
7759 ConditionalField(XShortField("chksum",None),lambda pkt:pkt.chksumpresent==1),
7760 ConditionalField(XShortField("reserved1",None),lambda pkt:pkt.chksumpresent==1),
7762 def post_build(self, p, pay):
7764 if self.chksumpresent and self.chksum is None:
7766 p = p[:4]+chr((c>>8)&0xff)+chr(c&0xff)+p[6:]
7770 class Radius(Packet):
7772 fields_desc = [ ByteEnumField("code", 1, {1: "Access-Request",
7775 4: "Accounting-Request",
7776 5: "Accounting-Accept",
7777 6: "Accounting-Status",
7778 7: "Password-Request",
7780 9: "Password-Reject",
7781 10: "Accounting-Message",
7782 11: "Access-Challenge",
7783 12: "Status-Server",
7784 13: "Status-Client",
7785 21: "Resource-Free-Request",
7786 22: "Resource-Free-Response",
7787 23: "Resource-Query-Request",
7788 24: "Resource-Query-Response",
7789 25: "Alternate-Resource-Reclaim-Request",
7790 26: "NAS-Reboot-Request",
7791 27: "NAS-Reboot-Response",
7792 29: "Next-Passcode",
7794 31: "Terminate-Session",
7795 32: "Password-Expired",
7796 33: "Event-Request",
7797 34: "Event-Response",
7798 40: "Disconnect-Request",
7799 41: "Disconnect-ACK",
7800 42: "Disconnect-NAK",
7804 50: "IP-Address-Allocate",
7805 51: "IP-Address-Release",
7806 253: "Experimental-use",
7810 ShortField("len", None),
7811 StrFixedLenField("authenticator","",16) ]
7812 def post_build(self, p, pay):
7817 p = p[:2]+struct.pack("!H",l)+p[4:]
7826 ByteEnumField("command",1,{1:"req",2:"resp",3:"traceOn",4:"traceOff",5:"sun",
7827 6:"trigReq",7:"trigResp",8:"trigAck",9:"updateReq",
7828 10:"updateResp",11:"updateAck"}),
7829 ByteField("version",1),
7830 ShortField("null",0),
7833 class RIPEntry(Packet):
7836 ShortEnumField("AF",2,{2:"IP"}),
7837 ShortField("RouteTag",0),
7838 IPField("addr","0.0.0.0"),
7839 IPField("mask","0.0.0.0"),
7840 IPField("nextHop","0.0.0.0"),
7841 IntEnumField("metric",1,{16:"Unreach"}),
7847 ISAKMP_payload_type = ["None","SA","Proposal","Transform","KE","ID","CERT","CR","Hash",
7848 "SIG","Nonce","Notification","Delete","VendorID"]
7850 ISAKMP_exchange_type = ["None","base","identity prot.",
7851 "auth only", "aggressive", "info"]
7854 class ISAKMP_class(Packet):
7855 def guess_payload_class(self, payload):
7856 np = self.next_payload
7859 elif np < len(ISAKMP_payload_type):
7860 pt = ISAKMP_payload_type[np]
7861 return globals().get("ISAKMP_payload_%s" % pt, ISAKMP_payload)
7863 return ISAKMP_payload
7866 class ISAKMP(ISAKMP_class): # rfc2408
7869 StrFixedLenField("init_cookie","",8),
7870 StrFixedLenField("resp_cookie","",8),
7871 ByteEnumField("next_payload",0,ISAKMP_payload_type),
7872 XByteField("version",0x10),
7873 ByteEnumField("exch_type",0,ISAKMP_exchange_type),
7874 FlagsField("flags",0, 8, ["encryption","commit","auth_only","res3","res4","res5","res6","res7"]), # XXX use a Flag field
7876 IntField("length",None)
7879 def guess_payload_class(self, payload):
7882 return ISAKMP_class.guess_payload_class(self, payload)
7884 def answers(self, other):
7885 if isinstance(other, ISAKMP):
7886 if other.init_cookie == self.init_cookie:
7889 def post_build(self, p, pay):
7891 if self.length is None:
7892 p = p[:24]+struct.pack("!I",len(p))+p[28:]
7898 class ISAKMP_payload_Transform(ISAKMP_class):
7899 name = "IKE Transform"
7901 ByteEnumField("next_payload",None,ISAKMP_payload_type),
7903 # ShortField("len",None),
7904 ShortField("length",None),
7905 ByteField("num",None),
7906 ByteEnumField("id",1,{1:"KEY_IKE"}),
7907 ShortField("res2",0),
7908 ISAKMPTransformSetField("transforms",None,length_from=lambda x:x.length-8)
7909 # XIntField("enc",0x80010005L),
7910 # XIntField("hash",0x80020002L),
7911 # XIntField("auth",0x80030001L),
7912 # XIntField("group",0x80040002L),
7913 # XIntField("life_type",0x800b0001L),
7914 # XIntField("durationh",0x000c0004L),
7915 # XIntField("durationl",0x00007080L),
7917 def post_build(self, p, pay):
7918 if self.length is None:
7920 p = p[:2]+chr((l>>8)&0xff)+chr(l&0xff)+p[4:]
7927 class ISAKMP_payload_Proposal(ISAKMP_class):
7928 name = "IKE proposal"
7929 # ISAKMP_payload_type = 0
7931 ByteEnumField("next_payload",None,ISAKMP_payload_type),
7933 FieldLenField("length",None,"trans","H", adjust=lambda pkt,x:x+8),
7934 ByteField("proposal",1),
7935 ByteEnumField("proto",1,{1:"ISAKMP"}),
7936 FieldLenField("SPIsize",None,"SPI","B"),
7937 ByteField("trans_nb",None),
7938 StrLenField("SPI","",length_from=lambda x:x.SPIsize),
7939 PacketLenField("trans",Raw(),ISAKMP_payload_Transform,length_from=lambda x:x.length-8),
7943 class ISAKMP_payload(ISAKMP_class):
7944 name = "ISAKMP payload"
7946 ByteEnumField("next_payload",None,ISAKMP_payload_type),
7948 FieldLenField("length",None,"load","H", adjust=lambda pkt,x:x+4),
7949 StrLenField("load","",length_from=lambda x:x.length-4),
7953 class ISAKMP_payload_VendorID(ISAKMP_class):
7954 name = "ISAKMP Vendor ID"
7955 overload_fields = { ISAKMP: { "next_payload":13 }}
7957 ByteEnumField("next_payload",None,ISAKMP_payload_type),
7959 FieldLenField("length",None,"vendorID","H", adjust=lambda pkt,x:x+4),
7960 StrLenField("vendorID","",length_from=lambda x:x.length-4),
7963 class ISAKMP_payload_SA(ISAKMP_class):
7965 overload_fields = { ISAKMP: { "next_payload":1 }}
7967 ByteEnumField("next_payload",None,ISAKMP_payload_type),
7969 FieldLenField("length",None,"prop","H", adjust=lambda pkt,x:x+12),
7970 IntEnumField("DOI",1,{1:"IPSEC"}),
7971 IntEnumField("situation",1,{1:"identity"}),
7972 PacketLenField("prop",Raw(),ISAKMP_payload_Proposal,length_from=lambda x:x.length-12),
7975 class ISAKMP_payload_Nonce(ISAKMP_class):
7976 name = "ISAKMP Nonce"
7977 overload_fields = { ISAKMP: { "next_payload":10 }}
7979 ByteEnumField("next_payload",None,ISAKMP_payload_type),
7981 FieldLenField("length",None,"load","H", adjust=lambda pkt,x:x+4),
7982 StrLenField("load","",length_from=lambda x:x.length-4),
7985 class ISAKMP_payload_KE(ISAKMP_class):
7986 name = "ISAKMP Key Exchange"
7987 overload_fields = { ISAKMP: { "next_payload":4 }}
7989 ByteEnumField("next_payload",None,ISAKMP_payload_type),
7991 FieldLenField("length",None,"load","H", adjust=lambda pkt,x:x+4),
7992 StrLenField("load","",length_from=lambda x:x.length-4),
7995 class ISAKMP_payload_ID(ISAKMP_class):
7996 name = "ISAKMP Identification"
7997 overload_fields = { ISAKMP: { "next_payload":5 }}
7999 ByteEnumField("next_payload",None,ISAKMP_payload_type),
8001 FieldLenField("length",None,"load","H",adjust=lambda pkt,x:x+8),
8002 ByteEnumField("IDtype",1,{1:"IPv4_addr", 11:"Key"}),
8003 ByteEnumField("ProtoID",0,{0:"Unused"}),
8004 ShortEnumField("Port",0,{0:"Unused"}),
8005 # IPField("IdentData","127.0.0.1"),
8006 StrLenField("load","",length_from=lambda x:x.length-8),
8011 class ISAKMP_payload_Hash(ISAKMP_class):
8012 name = "ISAKMP Hash"
8013 overload_fields = { ISAKMP: { "next_payload":8 }}
8015 ByteEnumField("next_payload",None,ISAKMP_payload_type),
8017 FieldLenField("length",None,"load","H",adjust=lambda pkt,x:x+4),
8018 StrLenField("load","",length_from=lambda x:x.length-4),
8023 ISAKMP_payload_type_overload = {}
8024 for i in range(len(ISAKMP_payload_type)):
8025 name = "ISAKMP_payload_%s" % ISAKMP_payload_type[i]
8026 if name in globals():
8027 ISAKMP_payload_type_overload[globals()[name]] = {"next_payload":i}
8031 ISAKMP_class.overload_fields = ISAKMP_payload_type_overload.copy()
8036 # Cisco Skinny protocol
8038 # shamelessly ripped from Ethereal dissector
8040 # Station -> Callmanager
8041 0x0000: "KeepAliveMessage",
8042 0x0001: "RegisterMessage",
8043 0x0002: "IpPortMessage",
8044 0x0003: "KeypadButtonMessage",
8045 0x0004: "EnblocCallMessage",
8046 0x0005: "StimulusMessage",
8047 0x0006: "OffHookMessage",
8048 0x0007: "OnHookMessage",
8049 0x0008: "HookFlashMessage",
8050 0x0009: "ForwardStatReqMessage",
8051 0x000A: "SpeedDialStatReqMessage",
8052 0x000B: "LineStatReqMessage",
8053 0x000C: "ConfigStatReqMessage",
8054 0x000D: "TimeDateReqMessage",
8055 0x000E: "ButtonTemplateReqMessage",
8056 0x000F: "VersionReqMessage",
8057 0x0010: "CapabilitiesResMessage",
8058 0x0011: "MediaPortListMessage",
8059 0x0012: "ServerReqMessage",
8060 0x0020: "AlarmMessage",
8061 0x0021: "MulticastMediaReceptionAck",
8062 0x0022: "OpenReceiveChannelAck",
8063 0x0023: "ConnectionStatisticsRes",
8064 0x0024: "OffHookWithCgpnMessage",
8065 0x0025: "SoftKeySetReqMessage",
8066 0x0026: "SoftKeyEventMessage",
8067 0x0027: "UnregisterMessage",
8068 0x0028: "SoftKeyTemplateReqMessage",
8069 0x0029: "RegisterTokenReq",
8070 0x002A: "MediaTransmissionFailure",
8071 0x002B: "HeadsetStatusMessage",
8072 0x002C: "MediaResourceNotification",
8073 0x002D: "RegisterAvailableLinesMessage",
8074 0x002E: "DeviceToUserDataMessage",
8075 0x002F: "DeviceToUserDataResponseMessage",
8076 0x0030: "UpdateCapabilitiesMessage",
8077 0x0031: "OpenMultiMediaReceiveChannelAckMessage",
8078 0x0032: "ClearConferenceMessage",
8079 0x0033: "ServiceURLStatReqMessage",
8080 0x0034: "FeatureStatReqMessage",
8081 0x0035: "CreateConferenceResMessage",
8082 0x0036: "DeleteConferenceResMessage",
8083 0x0037: "ModifyConferenceResMessage",
8084 0x0038: "AddParticipantResMessage",
8085 0x0039: "AuditConferenceResMessage",
8086 0x0040: "AuditParticipantResMessage",
8087 0x0041: "DeviceToUserDataVersion1Message",
8088 # Callmanager -> Station */
8089 0x0081: "RegisterAckMessage",
8090 0x0082: "StartToneMessage",
8091 0x0083: "StopToneMessage",
8092 0x0085: "SetRingerMessage",
8093 0x0086: "SetLampMessage",
8094 0x0087: "SetHkFDetectMessage",
8095 0x0088: "SetSpeakerModeMessage",
8096 0x0089: "SetMicroModeMessage",
8097 0x008A: "StartMediaTransmission",
8098 0x008B: "StopMediaTransmission",
8099 0x008C: "StartMediaReception",
8100 0x008D: "StopMediaReception",
8101 0x008F: "CallInfoMessage",
8102 0x0090: "ForwardStatMessage",
8103 0x0091: "SpeedDialStatMessage",
8104 0x0092: "LineStatMessage",
8105 0x0093: "ConfigStatMessage",
8106 0x0094: "DefineTimeDate",
8107 0x0095: "StartSessionTransmission",
8108 0x0096: "StopSessionTransmission",
8109 0x0097: "ButtonTemplateMessage",
8110 0x0098: "VersionMessage",
8111 0x0099: "DisplayTextMessage",
8112 0x009A: "ClearDisplay",
8113 0x009B: "CapabilitiesReqMessage",
8114 0x009C: "EnunciatorCommandMessage",
8115 0x009D: "RegisterRejectMessage",
8116 0x009E: "ServerResMessage",
8118 0x0100: "KeepAliveAckMessage",
8119 0x0101: "StartMulticastMediaReception",
8120 0x0102: "StartMulticastMediaTransmission",
8121 0x0103: "StopMulticastMediaReception",
8122 0x0104: "StopMulticastMediaTransmission",
8123 0x0105: "OpenReceiveChannel",
8124 0x0106: "CloseReceiveChannel",
8125 0x0107: "ConnectionStatisticsReq",
8126 0x0108: "SoftKeyTemplateResMessage",
8127 0x0109: "SoftKeySetResMessage",
8128 0x0110: "SelectSoftKeysMessage",
8129 0x0111: "CallStateMessage",
8130 0x0112: "DisplayPromptStatusMessage",
8131 0x0113: "ClearPromptStatusMessage",
8132 0x0114: "DisplayNotifyMessage",
8133 0x0115: "ClearNotifyMessage",
8134 0x0116: "ActivateCallPlaneMessage",
8135 0x0117: "DeactivateCallPlaneMessage",
8136 0x0118: "UnregisterAckMessage",
8137 0x0119: "BackSpaceReqMessage",
8138 0x011A: "RegisterTokenAck",
8139 0x011B: "RegisterTokenReject",
8140 0x0042: "DeviceToUserDataResponseVersion1Message",
8141 0x011C: "StartMediaFailureDetection",
8142 0x011D: "DialedNumberMessage",
8143 0x011E: "UserToDeviceDataMessage",
8144 0x011F: "FeatureStatMessage",
8145 0x0120: "DisplayPriNotifyMessage",
8146 0x0121: "ClearPriNotifyMessage",
8147 0x0122: "StartAnnouncementMessage",
8148 0x0123: "StopAnnouncementMessage",
8149 0x0124: "AnnouncementFinishMessage",
8150 0x0127: "NotifyDtmfToneMessage",
8151 0x0128: "SendDtmfToneMessage",
8152 0x0129: "SubscribeDtmfPayloadReqMessage",
8153 0x012A: "SubscribeDtmfPayloadResMessage",
8154 0x012B: "SubscribeDtmfPayloadErrMessage",
8155 0x012C: "UnSubscribeDtmfPayloadReqMessage",
8156 0x012D: "UnSubscribeDtmfPayloadResMessage",
8157 0x012E: "UnSubscribeDtmfPayloadErrMessage",
8158 0x012F: "ServiceURLStatMessage",
8159 0x0130: "CallSelectStatMessage",
8160 0x0131: "OpenMultiMediaChannelMessage",
8161 0x0132: "StartMultiMediaTransmission",
8162 0x0133: "StopMultiMediaTransmission",
8163 0x0134: "MiscellaneousCommandMessage",
8164 0x0135: "FlowControlCommandMessage",
8165 0x0136: "CloseMultiMediaReceiveChannel",
8166 0x0137: "CreateConferenceReqMessage",
8167 0x0138: "DeleteConferenceReqMessage",
8168 0x0139: "ModifyConferenceReqMessage",
8169 0x013A: "AddParticipantReqMessage",
8170 0x013B: "DropParticipantReqMessage",
8171 0x013C: "AuditConferenceReqMessage",
8172 0x013D: "AuditParticipantReqMessage",
8173 0x013F: "UserToDeviceDataVersion1Message",
8178 class Skinny(Packet):
8180 fields_desc = [ LEIntField("len",0),
8181 LEIntField("res",0),
8182 LEIntEnumField("msg",0,skinny_messages) ]
8184 _rtp_payload_types = {
8185 # http://www.iana.org/assignments/rtp-parameters
8186 0: 'G.711 PCMU', 3: 'GSM',
8187 4: 'G723', 5: 'DVI4',
8188 6: 'DVI4', 7: 'LPC',
8189 8: 'PCMA', 9: 'G722',
8190 10: 'L16', 11: 'L16',
8191 12: 'QCELP', 13: 'CN',
8192 14: 'MPA', 15: 'G728',
8193 16: 'DVI4', 17: 'DVI4',
8194 18: 'G729', 25: 'CelB',
8195 26: 'JPEG', 28: 'nv',
8196 31: 'H261', 32: 'MPV',
8197 33: 'MP2T', 34: 'H263' }
8201 fields_desc = [ BitField('version', 2, 2),
8202 BitField('padding', 0, 1),
8203 BitField('extension', 0, 1),
8204 BitFieldLenField('numsync', None, 4, count_of='sync'),
8205 BitField('marker', 0, 1),
8206 BitEnumField('payload', 0, 7, _rtp_payload_types),
8207 ShortField('sequence', 0),
8208 IntField('timestamp', 0),
8209 IntField('sourcesync', 0),
8210 FieldListField('sync', [], IntField("id",0), count_from=lambda pkt:pkt.numsync) ]
8215 class SebekHead(Packet):
8216 name = "Sebek header"
8217 fields_desc = [ XIntField("magic", 0xd0d0d0),
8218 ShortField("version", 1),
8219 ShortEnumField("type", 0, {"read":0, "write":1,
8220 "socket":2, "open":3}),
8221 IntField("counter", 0),
8222 IntField("time_sec", 0),
8223 IntField("time_usec", 0) ]
8224 def mysummary(self):
8225 return self.sprintf("Sebek Header v%SebekHead.version% %SebekHead.type%")
8227 # we need this because Sebek headers differ between v1 and v3, and
8228 # between v3 type socket and v3 others
8230 class SebekV1(Packet):
8232 fields_desc = [ IntField("pid", 0),
8235 StrFixedLenField("command", "", 12),
8236 FieldLenField("data_length", None, "data",fmt="I"),
8237 StrLenField("data", "", length_from=lambda x:x.data_length) ]
8238 def mysummary(self):
8239 if isinstance(self.underlayer, SebekHead):
8240 return self.underlayer.sprintf("Sebek v1 %SebekHead.type% (%SebekV1.command%)")
8242 return self.sprintf("Sebek v1 (%SebekV1.command%)")
8244 class SebekV3(Packet):
8246 fields_desc = [ IntField("parent_pid", 0),
8250 IntField("inode", 0),
8251 StrFixedLenField("command", "", 12),
8252 FieldLenField("data_length", None, "data",fmt="I"),
8253 StrLenField("data", "", length_from=lambda x:x.data_length) ]
8254 def mysummary(self):
8255 if isinstance(self.underlayer, SebekHead):
8256 return self.underlayer.sprintf("Sebek v%SebekHead.version% %SebekHead.type% (%SebekV3.command%)")
8258 return self.sprintf("Sebek v3 (%SebekV3.command%)")
8260 class SebekV2(SebekV3):
8261 def mysummary(self):
8262 if isinstance(self.underlayer, SebekHead):
8263 return self.underlayer.sprintf("Sebek v%SebekHead.version% %SebekHead.type% (%SebekV2.command%)")
8265 return self.sprintf("Sebek v2 (%SebekV2.command%)")
8267 class SebekV3Sock(Packet):
8268 name = "Sebek v2 socket"
8269 fields_desc = [ IntField("parent_pid", 0),
8273 IntField("inode", 0),
8274 StrFixedLenField("command", "", 12),
8275 IntField("data_length", 15),
8276 IPField("dip", "127.0.0.1"),
8277 ShortField("dport", 0),
8278 IPField("sip", "127.0.0.1"),
8279 ShortField("sport", 0),
8280 ShortEnumField("call", 0, { "bind":2,
8281 "connect":3, "listen":4,
8282 "accept":5, "sendmsg":16,
8283 "recvmsg":17, "sendto":11,
8285 ByteEnumField("proto", 0, IP_PROTOS) ]
8286 def mysummary(self):
8287 if isinstance(self.underlayer, SebekHead):
8288 return self.underlayer.sprintf("Sebek v%SebekHead.version% %SebekHead.type% (%SebekV3Sock.command%)")
8290 return self.sprintf("Sebek v3 socket (%SebekV3Sock.command%)")
8292 class SebekV2Sock(SebekV3Sock):
8293 def mysummary(self):
8294 if isinstance(self.underlayer, SebekHead):
8295 return self.underlayer.sprintf("Sebek v%SebekHead.version% %SebekHead.type% (%SebekV2Sock.command%)")
8297 return self.sprintf("Sebek v2 socket (%SebekV2Sock.command%)")
8301 longname = "Media Gateway Control Protocol"
8302 fields_desc = [ StrStopField("verb","AUEP"," ", -1),
8303 StrFixedLenField("sep1"," ",1),
8304 StrStopField("transaction_id","1234567"," ", -1),
8305 StrFixedLenField("sep2"," ",1),
8306 StrStopField("endpoint","dummy@dummy.net"," ", -1),
8307 StrFixedLenField("sep3"," ",1),
8308 StrStopField("version","MGCP 1.0 NCS 1.0","\x0a", -1),
8309 StrFixedLenField("sep4","\x0a",1),
8313 #class MGCP(Packet):
8315 # longname = "Media Gateway Control Protocol"
8316 # fields_desc = [ ByteEnumField("type",0, ["request","response","others"]),
8317 # ByteField("code0",0),
8318 # ByteField("code1",0),
8319 # ByteField("code2",0),
8320 # ByteField("code3",0),
8321 # ByteField("code4",0),
8322 # IntField("trasid",0),
8323 # IntField("req_time",0),
8324 # ByteField("is_duplicate",0),
8325 # ByteField("req_available",0) ]
8330 StrStopField("dummy","","\x65\x00\x00",1)
8334 class HCI_Hdr(Packet):
8336 fields_desc = [ ByteEnumField("type",2,{1:"command",2:"ACLdata",3:"SCOdata",4:"event",5:"vendor"}),]
8338 def mysummary(self):
8339 return self.sprintf("HCI %type%")
8341 class HCI_ACL_Hdr(Packet):
8342 name = "HCI ACL header"
8343 fields_desc = [ ByteField("handle",0), # Actually, handle is 12 bits and flags is 4.
8344 ByteField("flags",0), # I wait to write a LEBitField
8345 LEShortField("len",None), ]
8346 def post_build(self, p, pay):
8348 if self.len is None:
8350 p = p[:2]+chr(l&0xff)+chr((l>>8)&0xff)+p[4:]
8354 class L2CAP_Hdr(Packet):
8355 name = "L2CAP header"
8356 fields_desc = [ LEShortField("len",None),
8357 LEShortEnumField("cid",0,{1:"control"}),]
8359 def post_build(self, p, pay):
8361 if self.len is None:
8363 p = p[:2]+chr(l&0xff)+chr((l>>8)&0xff)+p[4:]
8368 class L2CAP_CmdHdr(Packet):
8369 name = "L2CAP command header"
8371 ByteEnumField("code",8,{1:"rej",2:"conn_req",3:"conn_resp",
8372 4:"conf_req",5:"conf_resp",6:"disconn_req",
8373 7:"disconn_resp",8:"echo_req",9:"echo_resp",
8374 10:"info_req",11:"info_resp"}),
8376 LEShortField("len",None) ]
8377 def post_build(self, p, pay):
8379 if self.len is None:
8381 p = p[:2]+chr(l&0xff)+chr((l>>8)&0xff)+p[4:]
8383 def answers(self, other):
8384 if other.id == self.id:
8387 if other.code in [2,4,6,8,10] and self.code == other.code+1:
8390 return self.payload.answers(other.payload)
8393 class L2CAP_ConnReq(Packet):
8394 name = "L2CAP Conn Req"
8395 fields_desc = [ LEShortEnumField("psm",0,{1:"SDP",3:"RFCOMM",5:"telephony control"}),
8396 LEShortField("scid",0),
8399 class L2CAP_ConnResp(Packet):
8400 name = "L2CAP Conn Resp"
8401 fields_desc = [ LEShortField("dcid",0),
8402 LEShortField("scid",0),
8403 LEShortEnumField("result",0,["no_info","authen_pend","author_pend"]),
8404 LEShortEnumField("status",0,["success","pend","bad_psm",
8405 "cr_sec_block","cr_no_mem"]),
8407 def answers(self, other):
8408 return self.scid == other.scid
8410 class L2CAP_CmdRej(Packet):
8411 name = "L2CAP Command Rej"
8412 fields_desc = [ LEShortField("reason",0),
8416 class L2CAP_ConfReq(Packet):
8417 name = "L2CAP Conf Req"
8418 fields_desc = [ LEShortField("dcid",0),
8419 LEShortField("flags",0),
8422 class L2CAP_ConfResp(Packet):
8423 name = "L2CAP Conf Resp"
8424 fields_desc = [ LEShortField("scid",0),
8425 LEShortField("flags",0),
8426 LEShortEnumField("result",0,["success","unaccept","reject","unknown"]),
8428 def answers(self, other):
8429 return self.scid == other.scid
8432 class L2CAP_DisconnReq(Packet):
8433 name = "L2CAP Disconn Req"
8434 fields_desc = [ LEShortField("dcid",0),
8435 LEShortField("scid",0), ]
8437 class L2CAP_DisconnResp(Packet):
8438 name = "L2CAP Disconn Resp"
8439 fields_desc = [ LEShortField("dcid",0),
8440 LEShortField("scid",0), ]
8441 def answers(self, other):
8442 return self.scid == other.scid
8446 class L2CAP_InfoReq(Packet):
8447 name = "L2CAP Info Req"
8448 fields_desc = [ LEShortEnumField("type",0,{1:"CL_MTU",2:"FEAT_MASK"}),
8453 class L2CAP_InfoResp(Packet):
8454 name = "L2CAP Info Resp"
8455 fields_desc = [ LEShortField("type",0),
8456 LEShortEnumField("result",0,["success","not_supp"]),
8457 StrField("data",""), ]
8458 def answers(self, other):
8459 return self.type == other.type
8464 class NetBIOS_DS(Packet):
8465 name = "NetBIOS datagram service"
8467 ByteEnumField("type",17, {17:"direct_group"}),
8468 ByteField("flags",0),
8469 XShortField("id",0),
8470 IPField("src","127.0.0.1"),
8471 ShortField("sport",138),
8472 ShortField("len",None),
8473 ShortField("ofs",0),
8474 NetBIOSNameField("srcname",""),
8475 NetBIOSNameField("dstname",""),
8477 def post_build(self, p, pay):
8479 if self.len is None:
8481 p = p[:10]+struct.pack("!H", l)+p[12:]
8484 # ShortField("length",0),
8485 # ShortField("Delimitor",0),
8486 # ByteField("command",0),
8487 # ByteField("data1",0),
8488 # ShortField("data2",0),
8489 # ShortField("XMIt",0),
8490 # ShortField("RSPCor",0),
8491 # StrFixedLenField("dest","",16),
8492 # StrFixedLenField("source","",16),
8499 class IrLAPHead(Packet):
8500 name = "IrDA Link Access Protocol Header"
8501 fields_desc = [ XBitField("Address", 0x7f, 7),
8502 BitEnumField("Type", 1, 1, {"Response":0,
8505 class IrLAPCommand(Packet):
8506 name = "IrDA Link Access Protocol Command"
8507 fields_desc = [ XByteField("Control", 0),
8508 XByteField("Format identifier", 0),
8509 XIntField("Source address", 0),
8510 XIntField("Destination address", 0xffffffffL),
8511 XByteField("Discovery flags", 0x1),
8512 ByteEnumField("Slot number", 255, {"final":255}),
8513 XByteField("Version", 0)]
8516 class IrLMP(Packet):
8517 name = "IrDA Link Management Protocol"
8518 fields_desc = [ XShortField("Service hints", 0),
8519 XByteField("Character set", 0),
8520 StrField("Device name", "") ]
8526 # Name Query Request
8527 # Node Status Request
8528 class NBNSQueryRequest(Packet):
8529 name="NBNS query request"
8530 fields_desc = [ShortField("NAME_TRN_ID",0),
8531 ShortField("FLAGS", 0x0110),
8532 ShortField("QDCOUNT",1),
8533 ShortField("ANCOUNT",0),
8534 ShortField("NSCOUNT",0),
8535 ShortField("ARCOUNT",0),
8536 NetBIOSNameField("QUESTION_NAME","windows"),
8537 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"}),
8538 ByteField("NULL",0),
8539 ShortEnumField("QUESTION_TYPE",0x20, {0x20:"NB",0x21:"NBSTAT"}),
8540 ShortEnumField("QUESTION_CLASS",1,{1:"INTERNET"})]
8542 # Name Registration Request
8543 # Name Refresh Request
8544 # Name Release Request or Demand
8545 class NBNSRequest(Packet):
8547 fields_desc = [ShortField("NAME_TRN_ID",0),
8548 ShortField("FLAGS", 0x2910),
8549 ShortField("QDCOUNT",1),
8550 ShortField("ANCOUNT",0),
8551 ShortField("NSCOUNT",0),
8552 ShortField("ARCOUNT",1),
8553 NetBIOSNameField("QUESTION_NAME","windows"),
8554 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"}),
8555 ByteField("NULL",0),
8556 ShortEnumField("QUESTION_TYPE",0x20, {0x20:"NB",0x21:"NBSTAT"}),
8557 ShortEnumField("QUESTION_CLASS",1,{1:"INTERNET"}),
8558 ShortEnumField("RR_NAME",0xC00C,{0xC00C:"Label String Pointer to QUESTION_NAME"}),
8559 ShortEnumField("RR_TYPE",0x20, {0x20:"NB",0x21:"NBSTAT"}),
8560 ShortEnumField("RR_CLASS",1,{1:"INTERNET"}),
8562 ShortField("RDLENGTH", 6),
8563 BitEnumField("G",0,1,{0:"Unique name",1:"Group name"}),
8564 BitEnumField("OWNER NODE TYPE",00,2,{00:"B node",01:"P node",02:"M node",03:"H node"}),
8565 BitEnumField("UNUSED",0,13,{0:"Unused"}),
8566 IPField("NB_ADDRESS", "127.0.0.1")]
8568 # Name Query Response
8569 # Name Registration Response
8570 class NBNSQueryResponse(Packet):
8571 name="NBNS query response"
8572 fields_desc = [ShortField("NAME_TRN_ID",0),
8573 ShortField("FLAGS", 0x8500),
8574 ShortField("QDCOUNT",0),
8575 ShortField("ANCOUNT",1),
8576 ShortField("NSCOUNT",0),
8577 ShortField("ARCOUNT",0),
8578 NetBIOSNameField("RR_NAME","windows"),
8579 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"}),
8580 ByteField("NULL",0),
8581 ShortEnumField("QUESTION_TYPE",0x20, {0x20:"NB",0x21:"NBSTAT"}),
8582 ShortEnumField("QUESTION_CLASS",1,{1:"INTERNET"}),
8583 IntField("TTL", 0x493e0),
8584 ShortField("RDLENGTH", 6),
8585 ShortField("NB_FLAGS", 0),
8586 IPField("NB_ADDRESS", "127.0.0.1")]
8588 # Name Query Response (negative)
8589 # Name Release Response
8590 class NBNSQueryResponseNegative(Packet):
8591 name="NBNS query response (negative)"
8592 fields_desc = [ShortField("NAME_TRN_ID",0),
8593 ShortField("FLAGS", 0x8506),
8594 ShortField("QDCOUNT",0),
8595 ShortField("ANCOUNT",1),
8596 ShortField("NSCOUNT",0),
8597 ShortField("ARCOUNT",0),
8598 NetBIOSNameField("RR_NAME","windows"),
8599 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"}),
8600 ByteField("NULL",0),
8601 ShortEnumField("RR_TYPE",0x20, {0x20:"NB",0x21:"NBSTAT"}),
8602 ShortEnumField("RR_CLASS",1,{1:"INTERNET"}),
8604 ShortField("RDLENGTH",6),
8605 BitEnumField("G",0,1,{0:"Unique name",1:"Group name"}),
8606 BitEnumField("OWNER NODE TYPE",00,2,{00:"B node",01:"P node",02:"M node",03:"H node"}),
8607 BitEnumField("UNUSED",0,13,{0:"Unused"}),
8608 IPField("NB_ADDRESS", "127.0.0.1")]
8610 # Node Status Response
8611 class NBNSNodeStatusResponse(Packet):
8612 name="NBNS Node Status Response"
8613 fields_desc = [ShortField("NAME_TRN_ID",0),
8614 ShortField("FLAGS", 0x8500),
8615 ShortField("QDCOUNT",0),
8616 ShortField("ANCOUNT",1),
8617 ShortField("NSCOUNT",0),
8618 ShortField("ARCOUNT",0),
8619 NetBIOSNameField("RR_NAME","windows"),
8620 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"}),
8621 ByteField("NULL",0),
8622 ShortEnumField("RR_TYPE",0x21, {0x20:"NB",0x21:"NBSTAT"}),
8623 ShortEnumField("RR_CLASS",1,{1:"INTERNET"}),
8625 ShortField("RDLENGTH",83),
8626 ByteField("NUM_NAMES",1)]
8628 # Service for Node Status Response
8629 class NBNSNodeStatusResponseService(Packet):
8630 name="NBNS Node Status Response Service"
8631 fields_desc = [StrFixedLenField("NETBIOS_NAME","WINDOWS ",15),
8632 ByteEnumField("SUFFIX",0,{0:"workstation",0x03:"messenger service",0x20:"file server service",0x1b:"domain master browser",0x1c:"domain controller", 0x1e:"browser election service"}),
8633 ByteField("NAME_FLAGS",0x4),
8634 ByteEnumField("UNUSED",0,{0:"unused"})]
8636 # End of Node Status Response packet
8637 class NBNSNodeStatusResponseEnd(Packet):
8638 name="NBNS Node Status Response"
8639 fields_desc = [SourceMACField("MAC_ADDRESS"),
8640 BitField("STATISTICS",0,57*8)]
8642 # Wait for Acknowledgement Response
8643 class NBNSWackResponse(Packet):
8644 name="NBNS Wait for Acknowledgement Response"
8645 fields_desc = [ShortField("NAME_TRN_ID",0),
8646 ShortField("FLAGS", 0xBC07),
8647 ShortField("QDCOUNT",0),
8648 ShortField("ANCOUNT",1),
8649 ShortField("NSCOUNT",0),
8650 ShortField("ARCOUNT",0),
8651 NetBIOSNameField("RR_NAME","windows"),
8652 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"}),
8653 ByteField("NULL",0),
8654 ShortEnumField("RR_TYPE",0x20, {0x20:"NB",0x21:"NBSTAT"}),
8655 ShortEnumField("RR_CLASS",1,{1:"INTERNET"}),
8657 ShortField("RDLENGTH",2),
8658 BitField("RDATA",10512,16)] #10512=0010100100010000
8660 class NBTDatagram(Packet):
8661 name="NBT Datagram Packet"
8662 fields_desc= [ByteField("Type", 0x10),
8663 ByteField("Flags", 0x02),
8664 ShortField("ID", 0),
8665 IPField("SourceIP", "127.0.0.1"),
8666 ShortField("SourcePort", 138),
8667 ShortField("Length", 272),
8668 ShortField("Offset", 0),
8669 NetBIOSNameField("SourceName","windows"),
8670 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"}),
8671 ByteField("NULL",0),
8672 NetBIOSNameField("DestinationName","windows"),
8673 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"}),
8674 ByteField("NULL",0)]
8677 class NBTSession(Packet):
8678 name="NBT Session Packet"
8679 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"}),
8680 BitField("RESERVED",0x00,7),
8681 BitField("LENGTH",0,17)]
8684 # SMB NetLogon Response Header
8685 class SMBNetlogon_Protocol_Response_Header(Packet):
8686 name="SMBNetlogon Protocol Response Header"
8687 fields_desc = [StrFixedLenField("Start","\xffSMB",4),
8688 ByteEnumField("Command",0x25,{0x25:"Trans"}),
8689 ByteField("Error_Class",0x02),
8690 ByteField("Reserved",0),
8691 LEShortField("Error_code",4),
8692 ByteField("Flags",0),
8693 LEShortField("Flags2",0x0000),
8694 LEShortField("PIDHigh",0x0000),
8695 LELongField("Signature",0x0),
8696 LEShortField("Unused",0x0),
8697 LEShortField("TID",0),
8698 LEShortField("PID",0),
8699 LEShortField("UID",0),
8700 LEShortField("MID",0),
8701 ByteField("WordCount",17),
8702 LEShortField("TotalParamCount",0),
8703 LEShortField("TotalDataCount",112),
8704 LEShortField("MaxParamCount",0),
8705 LEShortField("MaxDataCount",0),
8706 ByteField("MaxSetupCount",0),
8707 ByteField("unused2",0),
8708 LEShortField("Flags3",0),
8709 ByteField("TimeOut1",0xe8),
8710 ByteField("TimeOut2",0x03),
8711 LEShortField("unused3",0),
8712 LEShortField("unused4",0),
8713 LEShortField("ParamCount2",0),
8714 LEShortField("ParamOffset",0),
8715 LEShortField("DataCount",112),
8716 LEShortField("DataOffset",92),
8717 ByteField("SetupCount", 3),
8718 ByteField("unused5", 0)]
8720 # SMB MailSlot Protocol
8721 class SMBMailSlot(Packet):
8722 name = "SMB Mail Slot Protocol"
8723 fields_desc = [LEShortField("opcode", 1),
8724 LEShortField("priority", 1),
8725 LEShortField("class", 2),
8726 LEShortField("size", 135),
8727 StrNullField("name","\MAILSLOT\NET\GETDC660")]
8729 # SMB NetLogon Protocol Response Tail SAM
8730 class SMBNetlogon_Protocol_Response_Tail_SAM(Packet):
8731 name = "SMB Netlogon Protocol Response Tail SAM"
8732 fields_desc = [ByteEnumField("Command", 0x17, {0x12:"SAM logon request", 0x17:"SAM Active directory Response"}),
8733 ByteField("unused", 0),
8734 ShortField("Data1", 0),
8735 ShortField("Data2", 0xfd01),
8736 ShortField("Data3", 0),
8737 ShortField("Data4", 0xacde),
8738 ShortField("Data5", 0x0fe5),
8739 ShortField("Data6", 0xd10a),
8740 ShortField("Data7", 0x374c),
8741 ShortField("Data8", 0x83e2),
8742 ShortField("Data9", 0x7dd9),
8743 ShortField("Data10", 0x3a16),
8744 ShortField("Data11", 0x73ff),
8745 ByteField("Data12", 0x04),
8746 StrFixedLenField("Data13", "rmff", 4),
8747 ByteField("Data14", 0x0),
8748 ShortField("Data16", 0xc018),
8749 ByteField("Data18", 0x0a),
8750 StrFixedLenField("Data20", "rmff-win2k", 10),
8751 ByteField("Data21", 0xc0),
8752 ShortField("Data22", 0x18c0),
8753 ShortField("Data23", 0x180a),
8754 StrFixedLenField("Data24", "RMFF-WIN2K", 10),
8755 ShortField("Data25", 0),
8756 ByteField("Data26", 0x17),
8757 StrFixedLenField("Data27", "Default-First-Site-Name", 23),
8758 ShortField("Data28", 0x00c0),
8759 ShortField("Data29", 0x3c10),
8760 ShortField("Data30", 0x00c0),
8761 ShortField("Data31", 0x0200),
8762 ShortField("Data32", 0x0),
8763 ShortField("Data33", 0xac14),
8764 ShortField("Data34", 0x0064),
8765 ShortField("Data35", 0x0),
8766 ShortField("Data36", 0x0),
8767 ShortField("Data37", 0x0),
8768 ShortField("Data38", 0x0),
8769 ShortField("Data39", 0x0d00),
8770 ShortField("Data40", 0x0),
8771 ShortField("Data41", 0xffff)]
8773 # SMB NetLogon Protocol Response Tail LM2.0
8774 class SMBNetlogon_Protocol_Response_Tail_LM20(Packet):
8775 name = "SMB Netlogon Protocol Response Tail LM20"
8776 fields_desc = [ByteEnumField("Command",0x06,{0x06:"LM 2.0 Response to logon request"}),
8777 ByteField("unused", 0),
8778 StrFixedLenField("DblSlash", "\\\\", 2),
8779 StrNullField("ServerName","WIN"),
8780 LEShortField("LM20Token", 0xffff)]
8782 # SMBNegociate Protocol Request Header
8783 class SMBNegociate_Protocol_Request_Header(Packet):
8784 name="SMBNegociate Protocol Request Header"
8785 fields_desc = [StrFixedLenField("Start","\xffSMB",4),
8786 ByteEnumField("Command",0x72,{0x72:"SMB_COM_NEGOTIATE"}),
8787 ByteField("Error_Class",0),
8788 ByteField("Reserved",0),
8789 LEShortField("Error_code",0),
8790 ByteField("Flags",0x18),
8791 LEShortField("Flags2",0x0000),
8792 LEShortField("PIDHigh",0x0000),
8793 LELongField("Signature",0x0),
8794 LEShortField("Unused",0x0),
8795 LEShortField("TID",0),
8796 LEShortField("PID",1),
8797 LEShortField("UID",0),
8798 LEShortField("MID",2),
8799 ByteField("WordCount",0),
8800 LEShortField("ByteCount",12)]
8802 # SMB Negociate Protocol Request Tail
8803 class SMBNegociate_Protocol_Request_Tail(Packet):
8804 name="SMB Negociate Protocol Request Tail"
8805 fields_desc=[ByteField("BufferFormat",0x02),
8806 StrNullField("BufferData","NT LM 0.12")]
8808 # SMBNegociate Protocol Response Advanced Security
8809 class SMBNegociate_Protocol_Response_Advanced_Security(Packet):
8810 name="SMBNegociate Protocol Response Advanced Security"
8811 fields_desc = [StrFixedLenField("Start","\xffSMB",4),
8812 ByteEnumField("Command",0x72,{0x72:"SMB_COM_NEGOTIATE"}),
8813 ByteField("Error_Class",0),
8814 ByteField("Reserved",0),
8815 LEShortField("Error_Code",0),
8816 ByteField("Flags",0x98),
8817 LEShortField("Flags2",0x0000),
8818 LEShortField("PIDHigh",0x0000),
8819 LELongField("Signature",0x0),
8820 LEShortField("Unused",0x0),
8821 LEShortField("TID",0),
8822 LEShortField("PID",1),
8823 LEShortField("UID",0),
8824 LEShortField("MID",2),
8825 ByteField("WordCount",17),
8826 LEShortField("DialectIndex",7),
8827 ByteField("SecurityMode",0x03),
8828 LEShortField("MaxMpxCount",50),
8829 LEShortField("MaxNumberVC",1),
8830 LEIntField("MaxBufferSize",16144),
8831 LEIntField("MaxRawSize",65536),
8832 LEIntField("SessionKey",0x0000),
8833 LEShortField("ServerCapabilities",0xf3f9),
8834 BitField("UnixExtensions",0,1),
8835 BitField("Reserved2",0,7),
8836 BitField("ExtendedSecurity",1,1),
8837 BitField("CompBulk",0,2),
8838 BitField("Reserved3",0,5),
8839 # There have been 127490112000000000 tenths of micro-seconds between 1st january 1601 and 1st january 2005. 127490112000000000=0x1C4EF94D6228000, so ServerTimeHigh=0xD6228000 and ServerTimeLow=0x1C4EF94.
8840 LEIntField("ServerTimeHigh",0xD6228000L),
8841 LEIntField("ServerTimeLow",0x1C4EF94),
8842 LEShortField("ServerTimeZone",0x3c),
8843 ByteField("EncryptionKeyLength",0),
8844 LEFieldLenField("ByteCount", None, "SecurityBlob", adjust=lambda pkt,x:x-16),
8845 BitField("GUID",0,128),
8846 StrLenField("SecurityBlob", "", length_from=lambda x:x.ByteCount+16)]
8848 # SMBNegociate Protocol Response No Security
8849 # When using no security, with EncryptionKeyLength=8, you must have an EncryptionKey before the DomainName
8850 class SMBNegociate_Protocol_Response_No_Security(Packet):
8851 name="SMBNegociate Protocol Response No Security"
8852 fields_desc = [StrFixedLenField("Start","\xffSMB",4),
8853 ByteEnumField("Command",0x72,{0x72:"SMB_COM_NEGOTIATE"}),
8854 ByteField("Error_Class",0),
8855 ByteField("Reserved",0),
8856 LEShortField("Error_Code",0),
8857 ByteField("Flags",0x98),
8858 LEShortField("Flags2",0x0000),
8859 LEShortField("PIDHigh",0x0000),
8860 LELongField("Signature",0x0),
8861 LEShortField("Unused",0x0),
8862 LEShortField("TID",0),
8863 LEShortField("PID",1),
8864 LEShortField("UID",0),
8865 LEShortField("MID",2),
8866 ByteField("WordCount",17),
8867 LEShortField("DialectIndex",7),
8868 ByteField("SecurityMode",0x03),
8869 LEShortField("MaxMpxCount",50),
8870 LEShortField("MaxNumberVC",1),
8871 LEIntField("MaxBufferSize",16144),
8872 LEIntField("MaxRawSize",65536),
8873 LEIntField("SessionKey",0x0000),
8874 LEShortField("ServerCapabilities",0xf3f9),
8875 BitField("UnixExtensions",0,1),
8876 BitField("Reserved2",0,7),
8877 BitField("ExtendedSecurity",0,1),
8878 FlagsField("CompBulk",0,2,"CB"),
8879 BitField("Reserved3",0,5),
8880 # There have been 127490112000000000 tenths of micro-seconds between 1st january 1601 and 1st january 2005. 127490112000000000=0x1C4EF94D6228000, so ServerTimeHigh=0xD6228000 and ServerTimeLow=0x1C4EF94.
8881 LEIntField("ServerTimeHigh",0xD6228000L),
8882 LEIntField("ServerTimeLow",0x1C4EF94),
8883 LEShortField("ServerTimeZone",0x3c),
8884 ByteField("EncryptionKeyLength",8),
8885 LEShortField("ByteCount",24),
8886 BitField("EncryptionKey",0,64),
8887 StrNullField("DomainName","WORKGROUP"),
8888 StrNullField("ServerName","RMFF1")]
8890 # SMBNegociate Protocol Response No Security No Key
8891 class SMBNegociate_Protocol_Response_No_Security_No_Key(Packet):
8892 namez="SMBNegociate Protocol Response No Security No Key"
8893 fields_desc = [StrFixedLenField("Start","\xffSMB",4),
8894 ByteEnumField("Command",0x72,{0x72:"SMB_COM_NEGOTIATE"}),
8895 ByteField("Error_Class",0),
8896 ByteField("Reserved",0),
8897 LEShortField("Error_Code",0),
8898 ByteField("Flags",0x98),
8899 LEShortField("Flags2",0x0000),
8900 LEShortField("PIDHigh",0x0000),
8901 LELongField("Signature",0x0),
8902 LEShortField("Unused",0x0),
8903 LEShortField("TID",0),
8904 LEShortField("PID",1),
8905 LEShortField("UID",0),
8906 LEShortField("MID",2),
8907 ByteField("WordCount",17),
8908 LEShortField("DialectIndex",7),
8909 ByteField("SecurityMode",0x03),
8910 LEShortField("MaxMpxCount",50),
8911 LEShortField("MaxNumberVC",1),
8912 LEIntField("MaxBufferSize",16144),
8913 LEIntField("MaxRawSize",65536),
8914 LEIntField("SessionKey",0x0000),
8915 LEShortField("ServerCapabilities",0xf3f9),
8916 BitField("UnixExtensions",0,1),
8917 BitField("Reserved2",0,7),
8918 BitField("ExtendedSecurity",0,1),
8919 FlagsField("CompBulk",0,2,"CB"),
8920 BitField("Reserved3",0,5),
8921 # There have been 127490112000000000 tenths of micro-seconds between 1st january 1601 and 1st january 2005. 127490112000000000=0x1C4EF94D6228000, so ServerTimeHigh=0xD6228000 and ServerTimeLow=0x1C4EF94.
8922 LEIntField("ServerTimeHigh",0xD6228000L),
8923 LEIntField("ServerTimeLow",0x1C4EF94),
8924 LEShortField("ServerTimeZone",0x3c),
8925 ByteField("EncryptionKeyLength",0),
8926 LEShortField("ByteCount",16),
8927 StrNullField("DomainName","WORKGROUP"),
8928 StrNullField("ServerName","RMFF1")]
8930 # Session Setup AndX Request
8931 class SMBSession_Setup_AndX_Request(Packet):
8932 name="Session Setup AndX Request"
8933 fields_desc=[StrFixedLenField("Start","\xffSMB",4),
8934 ByteEnumField("Command",0x73,{0x73:"SMB_COM_SESSION_SETUP_ANDX"}),
8935 ByteField("Error_Class",0),
8936 ByteField("Reserved",0),
8937 LEShortField("Error_Code",0),
8938 ByteField("Flags",0x18),
8939 LEShortField("Flags2",0x0001),
8940 LEShortField("PIDHigh",0x0000),
8941 LELongField("Signature",0x0),
8942 LEShortField("Unused",0x0),
8943 LEShortField("TID",0),
8944 LEShortField("PID",1),
8945 LEShortField("UID",0),
8946 LEShortField("MID",2),
8947 ByteField("WordCount",13),
8948 ByteEnumField("AndXCommand",0x75,{0x75:"SMB_COM_TREE_CONNECT_ANDX"}),
8949 ByteField("Reserved2",0),
8950 LEShortField("AndXOffset",96),
8951 LEShortField("MaxBufferS",2920),
8952 LEShortField("MaxMPXCount",50),
8953 LEShortField("VCNumber",0),
8954 LEIntField("SessionKey",0),
8955 LEFieldLenField("ANSIPasswordLength",None,"ANSIPassword"),
8956 LEShortField("UnicodePasswordLength",0),
8957 LEIntField("Reserved3",0),
8958 LEShortField("ServerCapabilities",0x05),
8959 BitField("UnixExtensions",0,1),
8960 BitField("Reserved4",0,7),
8961 BitField("ExtendedSecurity",0,1),
8962 BitField("CompBulk",0,2),
8963 BitField("Reserved5",0,5),
8964 LEShortField("ByteCount",35),
8965 StrLenField("ANSIPassword", "Pass",length_from=lambda x:x.ANSIPasswordLength),
8966 StrNullField("Account","GUEST"),
8967 StrNullField("PrimaryDomain", ""),
8968 StrNullField("NativeOS","Windows 4.0"),
8969 StrNullField("NativeLanManager","Windows 4.0"),
8970 ByteField("WordCount2",4),
8971 ByteEnumField("AndXCommand2",0xFF,{0xFF:"SMB_COM_NONE"}),
8972 ByteField("Reserved6",0),
8973 LEShortField("AndXOffset2",0),
8974 LEShortField("Flags3",0x2),
8975 LEShortField("PasswordLength",0x1),
8976 LEShortField("ByteCount2",18),
8977 ByteField("Password",0),
8978 StrNullField("Path","\\\\WIN2K\\IPC$"),
8979 StrNullField("Service","IPC")]
8981 # Session Setup AndX Response
8982 class SMBSession_Setup_AndX_Response(Packet):
8983 name="Session Setup AndX Response"
8984 fields_desc=[StrFixedLenField("Start","\xffSMB",4),
8985 ByteEnumField("Command",0x73,{0x73:"SMB_COM_SESSION_SETUP_ANDX"}),
8986 ByteField("Error_Class",0),
8987 ByteField("Reserved",0),
8988 LEShortField("Error_Code",0),
8989 ByteField("Flags",0x90),
8990 LEShortField("Flags2",0x1001),
8991 LEShortField("PIDHigh",0x0000),
8992 LELongField("Signature",0x0),
8993 LEShortField("Unused",0x0),
8994 LEShortField("TID",0),
8995 LEShortField("PID",1),
8996 LEShortField("UID",0),
8997 LEShortField("MID",2),
8998 ByteField("WordCount",3),
8999 ByteEnumField("AndXCommand",0x75,{0x75:"SMB_COM_TREE_CONNECT_ANDX"}),
9000 ByteField("Reserved2",0),
9001 LEShortField("AndXOffset",66),
9002 LEShortField("Action",0),
9003 LEShortField("ByteCount",25),
9004 StrNullField("NativeOS","Windows 4.0"),
9005 StrNullField("NativeLanManager","Windows 4.0"),
9006 StrNullField("PrimaryDomain",""),
9007 ByteField("WordCount2",3),
9008 ByteEnumField("AndXCommand2",0xFF,{0xFF:"SMB_COM_NONE"}),
9009 ByteField("Reserved3",0),
9010 LEShortField("AndXOffset2",80),
9011 LEShortField("OptionalSupport",0x01),
9012 LEShortField("ByteCount2",5),
9013 StrNullField("Service","IPC"),
9014 StrNullField("NativeFileSystem","")]
9016 class MobileIP(Packet):
9017 name = "Mobile IP (RFC3344)"
9018 fields_desc = [ ByteEnumField("type", 1, {1:"RRQ", 3:"RRP"}) ]
9020 class MobileIPRRQ(Packet):
9021 name = "Mobile IP Registration Request (RFC3344)"
9022 fields_desc = [ XByteField("flags", 0),
9023 ShortField("lifetime", 180),
9024 IPField("homeaddr", "0.0.0.0"),
9025 IPField("haaddr", "0.0.0.0"),
9026 IPField("coaddr", "0.0.0.0"),
9027 Field("id", "", "64s") ]
9029 class MobileIPRRP(Packet):
9030 name = "Mobile IP Registration Reply (RFC3344)"
9031 fields_desc = [ ByteField("code", 0),
9032 ShortField("lifetime", 180),
9033 IPField("homeaddr", "0.0.0.0"),
9034 IPField("haaddr", "0.0.0.0"),
9035 Field("id", "", "64s") ]
9037 class MobileIPTunnelData(Packet):
9038 name = "Mobile IP Tunnel Data Message (RFC3519)"
9039 fields_desc = [ ByteField("nexthdr", 4),
9040 ShortField("res", 0) ]
9043 # Cisco Netflow Protocol version 1
9044 class NetflowHeader(Packet):
9045 name = "Netflow Header"
9046 fields_desc = [ ShortField("version", 1) ]
9048 class NetflowHeaderV1(Packet):
9049 name = "Netflow Header V1"
9050 fields_desc = [ ShortField("count", 0),
9051 IntField("sysUptime", 0),
9052 IntField("unixSecs", 0),
9053 IntField("unixNanoSeconds", 0) ]
9056 class NetflowRecordV1(Packet):
9057 name = "Netflow Record"
9058 fields_desc = [ IPField("ipsrc", "0.0.0.0"),
9059 IPField("ipdst", "0.0.0.0"),
9060 IPField("nexthop", "0.0.0.0"),
9061 ShortField("inputIfIndex", 0),
9062 ShortField("outpuIfIndex", 0),
9063 IntField("dpkts", 0),
9064 IntField("dbytes", 0),
9065 IntField("starttime", 0),
9066 IntField("endtime", 0),
9067 ShortField("srcport", 0),
9068 ShortField("dstport", 0),
9069 ShortField("padding", 0),
9070 ByteField("proto", 0),
9071 ByteField("tos", 0),
9072 IntField("padding1", 0),
9073 IntField("padding2", 0) ]
9076 TFTP_operations = { 1:"RRQ",2:"WRQ",3:"DATA",4:"ACK",5:"ERROR",6:"OACK" }
9080 name = "TFTP opcode"
9081 fields_desc = [ ShortEnumField("op", 1, TFTP_operations), ]
9085 class TFTP_RRQ(Packet):
9086 name = "TFTP Read Request"
9087 fields_desc = [ StrNullField("filename", ""),
9088 StrNullField("mode", "octet") ]
9089 def answers(self, other):
9091 def mysummary(self):
9092 return self.sprintf("RRQ %filename%"),[UDP]
9095 class TFTP_WRQ(Packet):
9096 name = "TFTP Write Request"
9097 fields_desc = [ StrNullField("filename", ""),
9098 StrNullField("mode", "octet") ]
9099 def answers(self, other):
9101 def mysummary(self):
9102 return self.sprintf("WRQ %filename%"),[UDP]
9104 class TFTP_DATA(Packet):
9106 fields_desc = [ ShortField("block", 0) ]
9107 def answers(self, other):
9108 return self.block == 1 and isinstance(other, TFTP_RRQ)
9109 def mysummary(self):
9110 return self.sprintf("DATA %block%"),[UDP]
9112 class TFTP_Option(Packet):
9113 fields_desc = [ StrNullField("oname",""),
9114 StrNullField("value","") ]
9115 def extract_padding(self, pkt):
9118 class TFTP_Options(Packet):
9119 fields_desc = [ PacketListField("options", [], TFTP_Option, length_from=lambda x:None) ]
9122 class TFTP_ACK(Packet):
9124 fields_desc = [ ShortField("block", 0) ]
9125 def answers(self, other):
9126 if isinstance(other, TFTP_DATA):
9127 return self.block == other.block
9128 elif isinstance(other, TFTP_RRQ) or isinstance(other, TFTP_WRQ) or isinstance(other, TFTP_OACK):
9129 return self.block == 0
9131 def mysummary(self):
9132 return self.sprintf("ACK %block%"),[UDP]
9134 TFTP_Error_Codes = { 0: "Not defined",
9135 1: "File not found",
9136 2: "Access violation",
9137 3: "Disk full or allocation exceeded",
9138 4: "Illegal TFTP operation",
9139 5: "Unknown transfer ID",
9140 6: "File already exists",
9142 8: "Terminate transfer due to option negotiation",
9145 class TFTP_ERROR(Packet):
9147 fields_desc = [ ShortEnumField("errorcode", 0, TFTP_Error_Codes),
9148 StrNullField("errormsg", "")]
9149 def answers(self, other):
9150 return (isinstance(other, TFTP_DATA) or
9151 isinstance(other, TFTP_RRQ) or
9152 isinstance(other, TFTP_WRQ) or
9153 isinstance(other, TFTP_ACK))
9154 def mysummary(self):
9155 return self.sprintf("ERROR %errorcode%: %errormsg%"),[UDP]
9158 class TFTP_OACK(Packet):
9159 name = "TFTP Option Ack"
9161 def answers(self, other):
9162 return isinstance(other, TFTP_WRQ) or isinstance(other, TFTP_RRQ)
9169 ######[ ASN1 class ]######
9171 class ASN1_Class_SNMP(ASN1_Class_UNIVERSAL):
9183 class ASN1_SNMP_PDU_GET(ASN1_SEQUENCE):
9184 tag = ASN1_Class_SNMP.PDU_GET
9186 class ASN1_SNMP_PDU_NEXT(ASN1_SEQUENCE):
9187 tag = ASN1_Class_SNMP.PDU_NEXT
9189 class ASN1_SNMP_PDU_RESPONSE(ASN1_SEQUENCE):
9190 tag = ASN1_Class_SNMP.PDU_RESPONSE
9192 class ASN1_SNMP_PDU_SET(ASN1_SEQUENCE):
9193 tag = ASN1_Class_SNMP.PDU_SET
9195 class ASN1_SNMP_PDU_TRAPv1(ASN1_SEQUENCE):
9196 tag = ASN1_Class_SNMP.PDU_TRAPv1
9198 class ASN1_SNMP_PDU_BULK(ASN1_SEQUENCE):
9199 tag = ASN1_Class_SNMP.PDU_BULK
9201 class ASN1_SNMP_PDU_INFORM(ASN1_SEQUENCE):
9202 tag = ASN1_Class_SNMP.PDU_INFORM
9204 class ASN1_SNMP_PDU_TRAPv2(ASN1_SEQUENCE):
9205 tag = ASN1_Class_SNMP.PDU_TRAPv2
9208 ######[ BER codecs ]#######
9210 class BERcodec_SNMP_PDU_GET(BERcodec_SEQUENCE):
9211 tag = ASN1_Class_SNMP.PDU_GET
9213 class BERcodec_SNMP_PDU_NEXT(BERcodec_SEQUENCE):
9214 tag = ASN1_Class_SNMP.PDU_NEXT
9216 class BERcodec_SNMP_PDU_RESPONSE(BERcodec_SEQUENCE):
9217 tag = ASN1_Class_SNMP.PDU_RESPONSE
9219 class BERcodec_SNMP_PDU_SET(BERcodec_SEQUENCE):
9220 tag = ASN1_Class_SNMP.PDU_SET
9222 class BERcodec_SNMP_PDU_TRAPv1(BERcodec_SEQUENCE):
9223 tag = ASN1_Class_SNMP.PDU_TRAPv1
9225 class BERcodec_SNMP_PDU_BULK(BERcodec_SEQUENCE):
9226 tag = ASN1_Class_SNMP.PDU_BULK
9228 class BERcodec_SNMP_PDU_INFORM(BERcodec_SEQUENCE):
9229 tag = ASN1_Class_SNMP.PDU_INFORM
9231 class BERcodec_SNMP_PDU_TRAPv2(BERcodec_SEQUENCE):
9232 tag = ASN1_Class_SNMP.PDU_TRAPv2
9236 ######[ ASN1 fields ]######
9238 class ASN1F_SNMP_PDU_GET(ASN1F_SEQUENCE):
9239 ASN1_tag = ASN1_Class_SNMP.PDU_GET
9241 class ASN1F_SNMP_PDU_NEXT(ASN1F_SEQUENCE):
9242 ASN1_tag = ASN1_Class_SNMP.PDU_NEXT
9244 class ASN1F_SNMP_PDU_RESPONSE(ASN1F_SEQUENCE):
9245 ASN1_tag = ASN1_Class_SNMP.PDU_RESPONSE
9247 class ASN1F_SNMP_PDU_SET(ASN1F_SEQUENCE):
9248 ASN1_tag = ASN1_Class_SNMP.PDU_SET
9250 class ASN1F_SNMP_PDU_TRAPv1(ASN1F_SEQUENCE):
9251 ASN1_tag = ASN1_Class_SNMP.PDU_TRAPv1
9253 class ASN1F_SNMP_PDU_BULK(ASN1F_SEQUENCE):
9254 ASN1_tag = ASN1_Class_SNMP.PDU_BULK
9256 class ASN1F_SNMP_PDU_INFORM(ASN1F_SEQUENCE):
9257 ASN1_tag = ASN1_Class_SNMP.PDU_INFORM
9259 class ASN1F_SNMP_PDU_TRAPv2(ASN1F_SEQUENCE):
9260 ASN1_tag = ASN1_Class_SNMP.PDU_TRAPv2
9264 ######[ SNMP Packet ]######
9266 SNMP_error = { 0: "no_error",
9275 9: "wrong_encoding",
9278 12: "inconsistent_value",
9279 13: "ressource_unavailable",
9280 14: "commit_failed",
9282 16: "authorization_error",
9284 18: "inconsistent_name",
9287 SNMP_trap_types = { 0: "cold_start",
9292 5: "egp_neigh_loss",
9293 6: "enterprise_specific",
9296 class SNMPvarbind(ASN1_Packet):
9297 ASN1_codec = ASN1_Codecs.BER
9298 ASN1_root = ASN1F_SEQUENCE( ASN1F_OID("oid","1.3"),
9299 ASN1F_field("value",ASN1_NULL(0))
9303 class SNMPget(ASN1_Packet):
9304 ASN1_codec = ASN1_Codecs.BER
9305 ASN1_root = ASN1F_SNMP_PDU_GET( ASN1F_INTEGER("id",0),
9306 ASN1F_enum_INTEGER("error",0, SNMP_error),
9307 ASN1F_INTEGER("error_index",0),
9308 ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind)
9311 class SNMPnext(ASN1_Packet):
9312 ASN1_codec = ASN1_Codecs.BER
9313 ASN1_root = ASN1F_SNMP_PDU_NEXT( ASN1F_INTEGER("id",0),
9314 ASN1F_enum_INTEGER("error",0, SNMP_error),
9315 ASN1F_INTEGER("error_index",0),
9316 ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind)
9319 class SNMPresponse(ASN1_Packet):
9320 ASN1_codec = ASN1_Codecs.BER
9321 ASN1_root = ASN1F_SNMP_PDU_RESPONSE( ASN1F_INTEGER("id",0),
9322 ASN1F_enum_INTEGER("error",0, SNMP_error),
9323 ASN1F_INTEGER("error_index",0),
9324 ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind)
9327 class SNMPset(ASN1_Packet):
9328 ASN1_codec = ASN1_Codecs.BER
9329 ASN1_root = ASN1F_SNMP_PDU_SET( ASN1F_INTEGER("id",0),
9330 ASN1F_enum_INTEGER("error",0, SNMP_error),
9331 ASN1F_INTEGER("error_index",0),
9332 ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind)
9335 class SNMPtrapv1(ASN1_Packet):
9336 ASN1_codec = ASN1_Codecs.BER
9337 ASN1_root = ASN1F_SNMP_PDU_TRAPv1( ASN1F_INTEGER("id",0),
9338 ASN1F_OID("enterprise", "1.3"),
9339 ASN1F_STRING("agent_addr",""),
9340 ASN1F_enum_INTEGER("generic_trap", 0, SNMP_trap_types),
9341 ASN1F_INTEGER("specific_trap", 0),
9342 ASN1F_INTEGER("time_stamp", IntAutoTime()),
9343 ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind)
9346 class SNMPbulk(ASN1_Packet):
9347 ASN1_codec = ASN1_Codecs.BER
9348 ASN1_root = ASN1F_SNMP_PDU_BULK( ASN1F_INTEGER("id",0),
9349 ASN1F_INTEGER("non_repeaters",0),
9350 ASN1F_INTEGER("max_repetitions",0),
9351 ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind)
9354 class SNMPinform(ASN1_Packet):
9355 ASN1_codec = ASN1_Codecs.BER
9356 ASN1_root = ASN1F_SNMP_PDU_INFORM( ASN1F_INTEGER("id",0),
9357 ASN1F_enum_INTEGER("error",0, SNMP_error),
9358 ASN1F_INTEGER("error_index",0),
9359 ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind)
9362 class SNMPtrapv2(ASN1_Packet):
9363 ASN1_codec = ASN1_Codecs.BER
9364 ASN1_root = ASN1F_SNMP_PDU_TRAPv2( ASN1F_INTEGER("id",0),
9365 ASN1F_enum_INTEGER("error",0, SNMP_error),
9366 ASN1F_INTEGER("error_index",0),
9367 ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind)
9371 class SNMP(ASN1_Packet):
9372 ASN1_codec = ASN1_Codecs.BER
9373 ASN1_root = ASN1F_SEQUENCE(
9374 ASN1F_enum_INTEGER("version", 1, {0:"v1", 1:"v2c", 2:"v2", 3:"v3"}),
9375 ASN1F_STRING("community","public"),
9376 ASN1F_CHOICE("PDU", SNMPget(),
9377 SNMPget, SNMPnext, SNMPresponse, SNMPset,
9378 SNMPtrapv1, SNMPbulk, SNMPinform, SNMPtrapv2)
9380 def answers(self, other):
9381 return ( isinstance(self.PDU, SNMPresponse) and
9382 ( isinstance(other.PDU, SNMPget) or
9383 isinstance(other.PDU, SNMPnext) or
9384 isinstance(other.PDU, SNMPset) ) and
9385 self.PDU.id == other.PDU.id )
9392 ######[ ASN1 class ]######
9394 class ASN1_Class_X509(ASN1_Class_UNIVERSAL):
9401 class ASN1_X509_CONT0(ASN1_SEQUENCE):
9402 tag = ASN1_Class_X509.CONT0
9404 class ASN1_X509_CONT1(ASN1_SEQUENCE):
9405 tag = ASN1_Class_X509.CONT1
9407 class ASN1_X509_CONT2(ASN1_SEQUENCE):
9408 tag = ASN1_Class_X509.CONT2
9410 class ASN1_X509_CONT3(ASN1_SEQUENCE):
9411 tag = ASN1_Class_X509.CONT3
9413 ######[ BER codecs ]#######
9415 class BERcodec_X509_CONT0(BERcodec_SEQUENCE):
9416 tag = ASN1_Class_X509.CONT0
9418 class BERcodec_X509_CONT1(BERcodec_SEQUENCE):
9419 tag = ASN1_Class_X509.CONT1
9421 class BERcodec_X509_CONT2(BERcodec_SEQUENCE):
9422 tag = ASN1_Class_X509.CONT2
9424 class BERcodec_X509_CONT3(BERcodec_SEQUENCE):
9425 tag = ASN1_Class_X509.CONT3
9427 ######[ ASN1 fields ]######
9429 class ASN1F_X509_CONT0(ASN1F_SEQUENCE):
9430 ASN1_tag = ASN1_Class_X509.CONT0
9432 class ASN1F_X509_CONT1(ASN1F_SEQUENCE):
9433 ASN1_tag = ASN1_Class_X509.CONT1
9435 class ASN1F_X509_CONT2(ASN1F_SEQUENCE):
9436 ASN1_tag = ASN1_Class_X509.CONT2
9438 class ASN1F_X509_CONT3(ASN1F_SEQUENCE):
9439 ASN1_tag = ASN1_Class_X509.CONT3
9441 ######[ X509 packets ]######
9443 class X509RDN(ASN1_Packet):
9444 ASN1_codec = ASN1_Codecs.BER
9445 ASN1_root = ASN1F_SET(
9446 ASN1F_SEQUENCE( ASN1F_OID("oid","2.5.4.6"),
9447 ASN1F_PRINTABLE_STRING("value","")
9451 class X509v3Ext(ASN1_Packet):
9452 ASN1_codec = ASN1_Codecs.BER
9453 ASN1_root = ASN1F_field("val",ASN1_NULL(0))
9456 class X509Cert(ASN1_Packet):
9457 ASN1_codec = ASN1_Codecs.BER
9458 ASN1_root = ASN1F_SEQUENCE(
9460 ASN1F_optionnal(ASN1F_X509_CONT0(ASN1F_INTEGER("version",3))),
9461 ASN1F_INTEGER("sn",1),
9462 ASN1F_SEQUENCE(ASN1F_OID("sign_algo","1.2.840.113549.1.1.5"),
9463 ASN1F_field("sa_value",ASN1_NULL(0))),
9464 ASN1F_SEQUENCE_OF("issuer",[],X509RDN),
9465 ASN1F_SEQUENCE(ASN1F_UTC_TIME("not_before",ZuluTime(-600)), # ten minutes ago
9466 ASN1F_UTC_TIME("not_after",ZuluTime(+86400))), # for 24h
9467 ASN1F_SEQUENCE_OF("subject",[],X509RDN),
9469 ASN1F_SEQUENCE(ASN1F_OID("pubkey_algo","1.2.840.113549.1.1.1"),
9470 ASN1F_field("pk_value",ASN1_NULL(0))),
9471 ASN1F_BIT_STRING("pubkey","")
9473 ASN1F_optionnal(ASN1F_X509_CONT3(ASN1F_SEQUENCE_OF("x509v3ext",[],X509v3Ext))),
9476 ASN1F_SEQUENCE(ASN1F_OID("sign_algo2","1.2.840.113549.1.1.5"),
9477 ASN1F_field("sa2_value",ASN1_NULL(0))),
9478 ASN1F_BIT_STRING("signature","")
9489 def bind_bottom_up(lower, upper, __fval=None, **fval):
9490 if __fval is not None:
9492 lower.payload_guess = lower.payload_guess[:]
9493 lower.payload_guess.append((fval, upper))
9496 def bind_top_down(lower, upper, __fval=None, **fval):
9497 if __fval is not None:
9499 upper.overload_fields = upper.overload_fields.copy()
9500 upper.overload_fields[lower] = fval
9502 def bind_layers(lower, upper, __fval=None, **fval):
9503 if __fval is not None:
9505 bind_top_down(lower, upper, **fval)
9506 bind_bottom_up(lower, upper, **fval)
9508 def split_bottom_up(lower, upper, __fval=None, **fval):
9509 if __fval is not None:
9511 def do_filter((f,u),upper=upper,fval=fval):
9515 if k not in f or f[k] != fval[k]:
9518 lower.payload_guess = filter(do_filter, lower.payload_guess)
9520 def split_top_down(lower, upper, __fval=None, **fval):
9521 if __fval is not None:
9523 if lower in upper.overload_fields:
9524 ofval = upper.overload_fields[lower]
9526 if k not in ofval or ofval[k] != fval[k]:
9528 upper.overload_fields = upper.overload_fields.copy()
9529 del(upper.overload_fields[lower])
9531 def split_layers(lower, upper, __fval=None, **fval):
9532 if __fval is not None:
9534 split_bottom_up(lower, upper, **fval)
9535 split_top_down(lower, upper, **fval)
9538 bind_layers( Dot3, LLC, )
9539 bind_layers( GPRS, IP, )
9540 bind_layers( PrismHeader, Dot11, )
9541 bind_layers( RadioTap, Dot11, )
9542 bind_layers( Dot11, LLC, type=2)
9543 bind_layers( Dot11QoS, LLC, )
9544 bind_layers( L2TP, PPP, )
9545 bind_layers( HDLC, PPP, )
9546 bind_layers( PPP, IP, proto=33)
9547 bind_layers( PPP, PPP_IPCP, proto=0x8021)
9548 bind_layers( PPP, PPP_ECP, proto=0x8053)
9549 bind_layers( Ether, LLC, type=122)
9550 bind_layers( Ether, Dot1Q, type=33024)
9551 bind_layers( Ether, Ether, type=1)
9552 bind_layers( Ether, ARP, type=2054)
9553 bind_layers( Ether, IP, type=2048)
9554 bind_layers( Ether, EAPOL, type=34958)
9555 bind_layers( Ether, EAPOL, dst='01:80:c2:00:00:03', type=34958)
9556 bind_layers( Ether, PPPoED, type=34915)
9557 bind_layers( Ether, PPPoE, type=34916)
9558 bind_layers( CookedLinux, LLC, proto=122)
9559 bind_layers( CookedLinux, Dot1Q, proto=33024)
9560 bind_layers( CookedLinux, Ether, proto=1)
9561 bind_layers( CookedLinux, ARP, proto=2054)
9562 bind_layers( CookedLinux, IP, proto=2048)
9563 bind_layers( CookedLinux, EAPOL, proto=34958)
9564 bind_layers( CookedLinux, PPPoED, proto=34915)
9565 bind_layers( CookedLinux, PPPoE, proto=34916)
9566 bind_layers( GRE, LLC, proto=122)
9567 bind_layers( GRE, Dot1Q, proto=33024)
9568 bind_layers( GRE, Ether, proto=1)
9569 bind_layers( GRE, ARP, proto=2054)
9570 bind_layers( GRE, IP, proto=2048)
9571 bind_layers( GRE, EAPOL, proto=34958)
9572 bind_layers( PPPoE, PPP, code=0)
9573 bind_layers( EAPOL, EAP, type=0)
9574 bind_layers( LLC, STP, dsap=66, ssap=66, ctrl=3)
9575 bind_layers( LLC, SNAP, dsap=170, ssap=170, ctrl=3)
9576 bind_layers( SNAP, Dot1Q, code=33024)
9577 bind_layers( SNAP, Ether, code=1)
9578 bind_layers( SNAP, ARP, code=2054)
9579 bind_layers( SNAP, IP, code=2048)
9580 bind_layers( SNAP, EAPOL, code=34958)
9581 bind_layers( SNAP, STP, code=267)
9582 bind_layers( IPerror, IPerror, frag=0, proto=4)
9583 bind_layers( IPerror, ICMPerror, frag=0, proto=1)
9584 bind_layers( IPerror, TCPerror, frag=0, proto=6)
9585 bind_layers( IPerror, UDPerror, frag=0, proto=17)
9586 bind_layers( IP, IP, frag=0, proto=4)
9587 bind_layers( IP, ICMP, frag=0, proto=1)
9588 bind_layers( IP, TCP, frag=0, proto=6)
9589 bind_layers( IP, UDP, frag=0, proto=17)
9590 bind_layers( IP, GRE, frag=0, proto=47)
9591 bind_layers( UDP, L2TP, sport=1701, dport=1701)
9592 bind_layers( UDP, SNMP, sport=161)
9593 bind_layers( UDP, SNMP, dport=161)
9594 bind_layers( UDP, MGCP, dport=2727)
9595 bind_layers( UDP, MGCP, sport=2727)
9596 bind_layers( UDP, DNS, dport=53)
9597 bind_layers( UDP, DNS, sport=53)
9598 bind_layers( UDP, ISAKMP, dport=500, sport=500)
9599 bind_layers( UDP, HSRP, dport=1985, sport=1985)
9600 bind_layers( UDP, NTP, dport=123, sport=123)
9601 bind_layers( UDP, BOOTP, dport=67, sport=68)
9602 bind_layers( UDP, BOOTP, dport=68, sport=67)
9603 bind_layers( BOOTP, DHCP, options='c\x82Sc')
9604 bind_layers( UDP, RIP, sport=520)
9605 bind_layers( UDP, RIP, dport=520)
9606 bind_layers( RIP, RIPEntry, )
9607 bind_layers( RIPEntry, RIPEntry, )
9608 bind_layers( Dot11, Dot11AssoReq, subtype=0, type=0)
9609 bind_layers( Dot11, Dot11AssoResp, subtype=1, type=0)
9610 bind_layers( Dot11, Dot11ReassoReq, subtype=2, type=0)
9611 bind_layers( Dot11, Dot11ReassoResp, subtype=3, type=0)
9612 bind_layers( Dot11, Dot11ProbeReq, subtype=4, type=0)
9613 bind_layers( Dot11, Dot11ProbeResp, subtype=5, type=0)
9614 bind_layers( Dot11, Dot11Beacon, subtype=8, type=0)
9615 bind_layers( Dot11, Dot11ATIM, subtype=9, type=0)
9616 bind_layers( Dot11, Dot11Disas, subtype=10, type=0)
9617 bind_layers( Dot11, Dot11Auth, subtype=11, type=0)
9618 bind_layers( Dot11, Dot11Deauth, subtype=12, type=0)
9619 bind_layers( Dot11Beacon, Dot11Elt, )
9620 bind_layers( Dot11AssoReq, Dot11Elt, )
9621 bind_layers( Dot11AssoResp, Dot11Elt, )
9622 bind_layers( Dot11ReassoReq, Dot11Elt, )
9623 bind_layers( Dot11ReassoResp, Dot11Elt, )
9624 bind_layers( Dot11ProbeReq, Dot11Elt, )
9625 bind_layers( Dot11ProbeResp, Dot11Elt, )
9626 bind_layers( Dot11Auth, Dot11Elt, )
9627 bind_layers( Dot11Elt, Dot11Elt, )
9628 bind_layers( TCP, Skinny, dport=2000)
9629 bind_layers( TCP, Skinny, sport=2000)
9630 bind_layers( UDP, SebekHead, sport=1101)
9631 bind_layers( UDP, SebekHead, dport=1101)
9632 bind_layers( UDP, SebekHead, dport=1101, sport=1101)
9633 bind_layers( SebekHead, SebekV1, version=1)
9634 bind_layers( SebekHead, SebekV2Sock, version=2, type=2)
9635 bind_layers( SebekHead, SebekV2, version=2)
9636 bind_layers( SebekHead, SebekV3Sock, version=3, type=2)
9637 bind_layers( SebekHead, SebekV3, version=3)
9638 bind_layers( CookedLinux, IrLAPHead, proto=23)
9639 bind_layers( IrLAPHead, IrLAPCommand, Type=1)
9640 bind_layers( IrLAPCommand, IrLMP, )
9641 bind_layers( UDP, NBNSQueryRequest, dport=137)
9642 bind_layers( UDP, NBNSRequest, dport=137)
9643 bind_layers( UDP, NBNSQueryResponse, sport=137)
9644 bind_layers( UDP, NBNSQueryResponseNegative, sport=137)
9645 bind_layers( UDP, NBNSNodeStatusResponse, sport=137)
9646 bind_layers( NBNSNodeStatusResponse, NBNSNodeStatusResponseService, )
9647 bind_layers( NBNSNodeStatusResponse, NBNSNodeStatusResponseService, )
9648 bind_layers( NBNSNodeStatusResponseService, NBNSNodeStatusResponseService, )
9649 bind_layers( NBNSNodeStatusResponseService, NBNSNodeStatusResponseEnd, )
9650 bind_layers( UDP, NBNSWackResponse, sport=137)
9651 bind_layers( UDP, NBTDatagram, dport=138)
9652 bind_layers( TCP, NBTSession, dport=139)
9653 bind_layers( NBTSession, SMBNegociate_Protocol_Request_Header, )
9654 bind_layers( SMBNegociate_Protocol_Request_Header, SMBNegociate_Protocol_Request_Tail, )
9655 bind_layers( SMBNegociate_Protocol_Request_Tail, SMBNegociate_Protocol_Request_Tail, )
9656 bind_layers( NBTSession, SMBNegociate_Protocol_Response_Advanced_Security, ExtendedSecurity=1)
9657 bind_layers( NBTSession, SMBNegociate_Protocol_Response_No_Security, ExtendedSecurity=0, EncryptionKeyLength=8)
9658 bind_layers( NBTSession, SMBNegociate_Protocol_Response_No_Security_No_Key, ExtendedSecurity=0, EncryptionKeyLength=0)
9659 bind_layers( NBTSession, SMBSession_Setup_AndX_Request, )
9660 bind_layers( NBTSession, SMBSession_Setup_AndX_Response, )
9661 bind_layers( HCI_Hdr, HCI_ACL_Hdr, type=2)
9662 bind_layers( HCI_Hdr, Raw, )
9663 bind_layers( HCI_ACL_Hdr, L2CAP_Hdr, )
9664 bind_layers( L2CAP_Hdr, L2CAP_CmdHdr, cid=1)
9665 bind_layers( L2CAP_CmdHdr, L2CAP_CmdRej, code=1)
9666 bind_layers( L2CAP_CmdHdr, L2CAP_ConnReq, code=2)
9667 bind_layers( L2CAP_CmdHdr, L2CAP_ConnResp, code=3)
9668 bind_layers( L2CAP_CmdHdr, L2CAP_ConfReq, code=4)
9669 bind_layers( L2CAP_CmdHdr, L2CAP_ConfResp, code=5)
9670 bind_layers( L2CAP_CmdHdr, L2CAP_DisconnReq, code=6)
9671 bind_layers( L2CAP_CmdHdr, L2CAP_DisconnResp, code=7)
9672 bind_layers( L2CAP_CmdHdr, L2CAP_InfoReq, code=10)
9673 bind_layers( L2CAP_CmdHdr, L2CAP_InfoResp, code=11)
9674 bind_layers( UDP, MobileIP, sport=434)
9675 bind_layers( UDP, MobileIP, dport=434)
9676 bind_layers( MobileIP, MobileIPRRQ, type=1)
9677 bind_layers( MobileIP, MobileIPRRP, type=3)
9678 bind_layers( MobileIP, MobileIPTunnelData, type=4)
9679 bind_layers( MobileIPTunnelData, IP, nexthdr=4)
9680 bind_layers( NetflowHeader, NetflowHeaderV1, version=1)
9681 bind_layers( NetflowHeaderV1, NetflowRecordV1, )
9683 bind_layers(UDP, TFTP, dport=69)
9684 bind_layers(TFTP, TFTP_RRQ, op=1)
9685 bind_layers(TFTP, TFTP_WRQ, op=2)
9686 bind_layers(TFTP, TFTP_DATA, op=3)
9687 bind_layers(TFTP, TFTP_ACK, op=4)
9688 bind_layers(TFTP, TFTP_ERROR, op=5)
9689 bind_layers(TFTP, TFTP_OACK, op=6)
9690 bind_layers(TFTP_RRQ, TFTP_Options)
9691 bind_layers(TFTP_WRQ, TFTP_Options)
9692 bind_layers(TFTP_OACK, TFTP_Options)
9699 def fragment(pkt, fragsize=1480):
9700 fragsize = (fragsize+7)/8*8
9703 s = str(p[IP].payload)
9704 nb = (len(s)+fragsize-1)/fragsize
9714 q[IP].frag = i*fragsize/8
9715 r = Raw(load=s[i*fragsize:(i+1)*fragsize])
9716 r.overload_fields = p[IP].payload.overload_fields.copy()
9721 def overlap_frag(p, overlap, fragsize=8, overlap_fragsize=None):
9722 if overlap_fragsize is None:
9723 overlap_fragsize = fragsize
9726 q[IP].add_payload(overlap)
9728 qfrag = fragment(q, overlap_fragsize)
9729 qfrag[-1][IP].flags |= 1
9730 return qfrag+fragment(p, fragsize)
9733 """defrag(plist) -> ([not fragmented], [defragmented],
9734 [ [bad fragments], [bad fragments], ... ])"""
9736 nofrag = PacketList()
9742 if ip.frag == 0 and ip.flags & 1 == 0:
9745 uniq = (ip.id,ip.src,ip.dst,ip.proto)
9747 frags[uniq].append(p)
9749 frags[uniq] = PacketList([p])
9752 for lst in frags.itervalues():
9753 lst.sort(lambda x,y:cmp(x.frag, y.frag))
9756 missfrag.append(lst)
9760 del(p[Padding].underlayer.payload)
9762 if ip.len is None or ip.ihl is None:
9763 clen = len(ip.payload)
9765 clen = ip.len - (ip.ihl<<2)
9768 if clen != q.frag<<3:
9769 if clen > q.frag<<3:
9770 warning("Fragment overlap (%i > %i) %r || %r || %r" % (clen, q.frag<<3, p,txt,q))
9771 missfrag.append(lst)
9774 if q[IP].len is None or q[IP].ihl is None:
9775 clen += len(q[IP].payload)
9777 clen += q[IP].len - (q[IP].ihl<<2)
9779 del(q[Padding].underlayer.payload)
9780 txt.add_payload(q[IP].payload.copy())
9785 ip.flags &= ~1 # !MF
9790 defrag2=PacketList()
9792 defrag2.append(p.__class__(str(p)))
9793 return nofrag,defrag2,missfrag
9795 def defragment(plist):
9796 """defrag(plist) -> plist defragmented as much as possible """
9806 if ip.frag != 0 or ip.flags & 1:
9808 uniq = (ip.id,ip.src,ip.dst,ip.proto)
9810 frags[uniq].append(p)
9818 for lst in frags.itervalues():
9819 lst.sort(lambda x,y:cmp(x.frag, y.frag))
9826 del(p[Padding].underlayer.payload)
9828 if ip.len is None or ip.ihl is None:
9829 clen = len(ip.payload)
9831 clen = ip.len - (ip.ihl<<2)
9834 if clen != q.frag<<3:
9835 if clen > q.frag<<3:
9836 warning("Fragment overlap (%i > %i) %r || %r || %r" % (clen, q.frag<<3, p,txt,q))
9840 if q[IP].len is None or q[IP].ihl is None:
9841 clen += len(q[IP].payload)
9843 clen += q[IP].len - (q[IP].ihl<<2)
9845 del(q[Padding].underlayer.payload)
9846 txt.add_payload(q[IP].payload.copy())
9851 ip.flags &= ~1 # !MF
9855 p._defrag_pos = lst[-1]._defrag_pos
9859 q = p.__class__(str(p))
9860 q._defrag_pos = p._defrag_pos
9864 final.sort(lambda x,y: cmp(x._defrag_pos, y._defrag_pos))
9868 if hasattr(plist, "listname"):
9869 name = "Defragmented %s" % plist.listname
9871 name = "Defragmented"
9874 return PacketList(final, name=name)
9885 def Ether_Dot3_Dispatcher(pkt=None, **kargs):
9886 if type(pkt) is str and len(pkt) >= 14 and struct.unpack("!H", pkt[12:14])[0] <= 1500:
9887 return Dot3(pkt, **kargs)
9888 return Ether(pkt, **kargs)
9890 # According to libdnet
9891 LLTypes = { ARPHDR_ETHER : Ether_Dot3_Dispatcher,
9892 ARPHDR_METRICOM : Ether_Dot3_Dispatcher,
9893 ARPHDR_LOOPBACK : Ether_Dot3_Dispatcher,
9902 119 : PrismHeader, # for atheros
9904 144 : CookedLinux, # called LINUX_IRDA, similar to CookedLinux
9906 0xB1E70073L : HCI_Hdr, # I invented this one
9909 LLNumTypes = { Ether : ARPHDR_ETHER,
9923 L3Types = { ETH_P_IP : IP,
9930 if type(fd) is not int:
9933 r,w,e = select([fd],[],[],0)
9941 def __init__(self, family=socket.AF_INET,type=socket.SOCK_STREAM, proto=0):
9942 self.ins = socket.socket(family, type, proto)
9943 self.outs = self.ins
9947 x.sent_time = time.time()
9948 return self.outs.send(sx)
9950 return Raw(self.ins.recv(x))
9952 return self.ins.fileno()
9957 if self.ins != self.outs:
9958 if self.outs and self.outs.fileno() != -1:
9960 if self.ins and self.ins.fileno() != -1:
9962 def bind_in(self, addr):
9964 def bind_out(self, addr):
9965 self.outs.bind(addr)
9968 class L3RawSocket(SuperSocket):
9969 def __init__(self, type = ETH_P_IP, filter=None, iface=None, promisc=None, nofilter=0):
9970 self.outs = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_RAW)
9971 self.outs.setsockopt(socket.SOL_IP, socket.IP_HDRINCL, 1)
9972 self.ins = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(type))
9974 return Ether(self.ins.recv(x)).payload
9978 x.sent_time = time.time()
9979 self.outs.sendto(sx,(x.dst,0))
9980 except socket.error,msg:
9981 log_runtime.error(msg)
9985 class L3PacketSocket(SuperSocket):
9986 def __init__(self, type = ETH_P_ALL, filter=None, promisc=None, iface=None, nofilter=0):
9988 self.ins = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(type))
9989 self.ins.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 0)
9992 self.ins.bind((iface, type))
9994 if conf.except_filter:
9996 filter = "(%s) and not (%s)" % (filter, conf.except_filter)
9998 filter = "not (%s)" % conf.except_filter
9999 if filter is not None:
10000 attach_filter(self.ins, filter)
10001 self.ins.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 2**30)
10002 self.outs = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(type))
10003 self.outs.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 2**30)
10004 if promisc is None:
10005 promisc = conf.promisc
10006 self.promisc = promisc
10009 self.iff = get_if_list()
10011 if iface.__class__ is list:
10016 set_promisc(self.ins, i)
10023 set_promisc(self.ins, i, 0)
10024 SuperSocket.close(self)
10026 pkt, sa_ll = self.ins.recvfrom(x)
10027 if sa_ll[2] == socket.PACKET_OUTGOING:
10029 if LLTypes.has_key(sa_ll[3]):
10030 cls = LLTypes[sa_ll[3]]
10032 elif L3Types.has_key(sa_ll[1]):
10033 cls = L3Types[sa_ll[1]]
10036 warning("Unable to guess type (interface=%s protocol=%#x family=%i). Using Ethernet" % (sa_ll[0],sa_ll[1],sa_ll[3]))
10042 except KeyboardInterrupt:
10045 if conf.debug_dissector:
10051 if pkt is not None:
10052 pkt.time = get_last_packet_timestamp(self.ins)
10056 if isinstance(x, IPv6):
10057 iff,a,gw = conf.route6.route(x.dst)
10058 elif hasattr(x,"dst"):
10059 iff,a,gw = conf.route.route(x.dst)
10062 sdto = (iff, self.type)
10063 self.outs.bind(sdto)
10064 sn = self.outs.getsockname()
10066 if sn[3] in (ARPHDR_PPP,ARPHDR_TUN):
10067 sdto = (iff, ETH_P_IP)
10068 if LLTypes.has_key(sn[3]):
10069 ll = lambda x:LLTypes[sn[3]]()/x
10072 x.sent_time = time.time()
10073 self.outs.sendto(sx, sdto)
10074 except socket.error,msg:
10075 x.sent_time = time.time() # bad approximation
10076 if conf.auto_fragment and msg[0] == 90:
10077 for p in fragment(x):
10078 self.outs.sendto(str(ll(p)), sdto)
10085 class L2Socket(SuperSocket):
10086 def __init__(self, iface = None, type = ETH_P_ALL, filter=None, nofilter=0):
10089 self.ins = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(type))
10090 self.ins.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 0)
10093 if conf.except_filter:
10095 filter = "(%s) and not (%s)" % (filter, conf.except_filter)
10097 filter = "not (%s)" % conf.except_filter
10098 if filter is not None:
10099 attach_filter(self.ins, filter)
10100 self.ins.bind((iface, type))
10101 self.ins.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 2**30)
10102 self.outs = self.ins
10103 self.outs.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 2**30)
10104 sa_ll = self.outs.getsockname()
10105 if LLTypes.has_key(sa_ll[3]):
10106 self.LL = LLTypes[sa_ll[3]]
10107 elif L3Types.has_key(sa_ll[1]):
10108 self.LL = L3Types[sa_ll[1]]
10110 warning("Unable to guess type (interface=%s protocol=%#x family=%i). Using Ethernet" % (sa_ll[0],sa_ll[1],sa_ll[3]))
10114 pkt, sa_ll = self.ins.recvfrom(x)
10115 if sa_ll[2] == socket.PACKET_OUTGOING:
10119 except KeyboardInterrupt:
10122 if conf.debug_dissector:
10125 q.time = get_last_packet_timestamp(self.ins)
10129 class L2ListenSocket(SuperSocket):
10130 def __init__(self, iface = None, type = ETH_P_ALL, promisc=None, filter=None, nofilter=0):
10133 self.ins = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(type))
10134 self.ins.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 0)
10136 if iface is not None:
10137 self.ins.bind((iface, type))
10139 if conf.except_filter:
10141 filter = "(%s) and not (%s)" % (filter, conf.except_filter)
10143 filter = "not (%s)" % conf.except_filter
10144 if filter is not None:
10145 attach_filter(self.ins, filter)
10146 if promisc is None:
10147 promisc = conf.sniff_promisc
10148 self.promisc = promisc
10150 self.iff = get_if_list()
10152 if iface.__class__ is list:
10158 set_promisc(self.ins, i)
10159 self.ins.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 2**30)
10163 set_promisc(self.ins, i, 0)
10164 SuperSocket.close(self)
10167 pkt, sa_ll = self.ins.recvfrom(x)
10168 if LLTypes.has_key(sa_ll[3]):
10169 cls = LLTypes[sa_ll[3]]
10170 elif L3Types.has_key(sa_ll[1]):
10171 cls = L3Types[sa_ll[1]]
10173 warning("Unable to guess type (interface=%s protocol=%#x family=%i). Using Ethernet" % (sa_ll[0],sa_ll[1],sa_ll[3]))
10178 except KeyboardInterrupt:
10181 if conf.debug_dissector:
10184 pkt.time = get_last_packet_timestamp(self.ins)
10188 raise Scapy_Exception("Can't send anything with L2ListenSocket")
10192 class L3dnetSocket(SuperSocket):
10193 def __init__(self, type = ETH_P_ALL, filter=None, promisc=None, iface=None, nofilter=0):
10195 self.ins = pcap.pcapObject()
10199 self.ins.open_live(iface, 1600, 0, 100)
10201 ioctl(self.ins.fileno(),BIOCIMMEDIATE,struct.pack("I",1))
10205 if type != ETH_P_ALL: # PF_PACKET stuff. Need to emulate this for pcap
10206 filter = "ether proto %i" % type
10210 if conf.except_filter:
10212 filter = "(%s) and not (%s)" % (filter, conf.except_filter)
10214 filter = "not (%s)" % conf.except_filter
10215 if type != ETH_P_ALL: # PF_PACKET stuff. Need to emulate this for pcap
10217 filter = "(ether proto %i) and (%s)" % (type,filter)
10219 filter = "ether proto %i" % type
10221 self.ins.setfilter(filter, 0, 0)
10223 if isinstance(x, IPv6):
10224 iff,a,gw = conf.route6.route(x.dst)
10225 elif hasattr(x,"dst"):
10226 iff,a,gw = conf.route.route(x.dst)
10229 ifs = self.iflist.get(iff)
10231 self.iflist[iff] = ifs = dnet.eth(iff)
10232 sx = str(Ether()/x)
10233 x.sent_time = time.time()
10235 def recv(self,x=MTU):
10236 ll = self.ins.datalink()
10237 if LLTypes.has_key(ll):
10240 warning("Unable to guess datalink type (interface=%s linktype=%i). Using Ethernet" % (self.iface, ll))
10243 pkt = self.ins.next()
10244 if pkt is not None:
10251 except KeyboardInterrupt:
10254 if conf.debug_dissector:
10260 def nonblock_recv(self):
10261 self.ins.setnonblock(1)
10263 self.ins.setnonblock(0)
10267 if hasattr(self, "ins"):
10269 if hasattr(self, "outs"):
10272 class L2dnetSocket(SuperSocket):
10273 def __init__(self, iface = None, type = ETH_P_ALL, filter=None, nofilter=0):
10277 self.ins = pcap.pcapObject()
10278 self.ins.open_live(iface, 1600, 0, 100)
10280 ioctl(self.ins.fileno(),BIOCIMMEDIATE,struct.pack("I",1))
10284 if type != ETH_P_ALL: # PF_PACKET stuff. Need to emulate this for pcap
10285 filter = "ether proto %i" % type
10289 if conf.except_filter:
10291 filter = "(%s) and not (%s)" % (filter, conf.except_filter)
10293 filter = "not (%s)" % conf.except_filter
10294 if type != ETH_P_ALL: # PF_PACKET stuff. Need to emulate this for pcap
10296 filter = "(ether proto %i) and (%s)" % (type,filter)
10298 filter = "ether proto %i" % type
10300 self.ins.setfilter(filter, 0, 0)
10301 self.outs = dnet.eth(iface)
10303 ll = self.ins.datalink()
10304 if LLTypes.has_key(ll):
10307 warning("Unable to guess datalink type (interface=%s linktype=%i). Using Ethernet" % (self.iface, ll))
10310 pkt = self.ins.next()
10311 if pkt is not None:
10318 except KeyboardInterrupt:
10321 if conf.debug_dissector:
10327 def nonblock_recv(self):
10328 self.ins.setnonblock(1)
10330 self.ins.setnonblock(0)
10334 if hasattr(self, "ins"):
10336 if hasattr(self, "outs"):
10343 class L2pcapListenSocket(SuperSocket):
10344 def __init__(self, iface = None, type = ETH_P_ALL, promisc=None, filter=None):
10347 self.ins = pcap.pcapObject()
10351 if promisc is None:
10352 promisc = conf.sniff_promisc
10353 self.promisc = promisc
10354 self.ins.open_live(iface, 1600, self.promisc, 100)
10356 ioctl(self.ins.fileno(),BIOCIMMEDIATE,struct.pack("I",1))
10359 if type == ETH_P_ALL: # Do not apply any filter if Ethernet type is given
10360 if conf.except_filter:
10362 filter = "(%s) and not (%s)" % (filter, conf.except_filter)
10364 filter = "not (%s)" % conf.except_filter
10366 self.ins.setfilter(filter, 0, 0)
10372 ll = self.ins.datalink()
10373 if LLTypes.has_key(ll):
10376 warning("Unable to guess datalink type (interface=%s linktype=%i). Using Ethernet" % (self.iface, ll))
10381 pkt = self.ins.next()
10382 if pkt is not None:
10387 except KeyboardInterrupt:
10390 if conf.debug_dissector:
10397 raise Scapy_Exception("Can't send anything with L2pcapListenSocket")
10400 class SimpleSocket(SuperSocket):
10401 def __init__(self, sock):
10406 class StreamSocket(SimpleSocket):
10407 def __init__(self, sock, basecls=Raw):
10408 SimpleSocket.__init__(self, sock)
10409 self.basecls = basecls
10411 def recv(self, x=MTU):
10412 pkt = self.ins.recv(x, socket.MSG_PEEK)
10414 pkt = self.basecls(pkt)
10416 if pad is not None and pad.underlayer is not None:
10417 del(pad.underlayer.payload)
10418 while pad is not None and not isinstance(pad, NoPayload):
10425 class BluetoothL2CAPSocket(SuperSocket):
10426 def __init__(self, peer):
10427 s = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_RAW,
10428 socket.BTPROTO_L2CAP)
10429 s.connect((peer,0))
10431 self.ins = self.outs = s
10434 return L2CAP_CmdHdr(self.ins.recv(x))
10437 class BluetoothHCISocket(SuperSocket):
10438 def __init__(self, iface=0x10000, type=None):
10439 s = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_RAW, socket.BTPROTO_HCI)
10440 s.setsockopt(socket.SOL_HCI, socket.HCI_DATA_DIR,1)
10441 s.setsockopt(socket.SOL_HCI, socket.HCI_TIME_STAMP,1)
10442 s.setsockopt(socket.SOL_HCI, socket.HCI_FILTER, struct.pack("IIIh2x", 0xffffffffL,0xffffffffL,0xffffffffL,0)) #type mask, event mask, event mask, opcode
10444 self.ins = self.outs = s
10445 # s.connect((peer,0))
10449 return HCI_Hdr(self.ins.recv(x))
10453 ####################
10454 ## Send / Receive ##
10455 ####################
10460 def sndrcv(pks, pkt, timeout = 2, inter = 0, verbose=None, chainCC=0, retry=0, multi=0):
10461 if not isinstance(pkt, Gen):
10464 if verbose is None:
10465 verbose = conf.verb
10466 debug.recv = PacketList([],"Unanswered")
10467 debug.sent = PacketList([],"Sent")
10468 debug.match = SndRcvList([])
10471 # do it here to fix random fields, so that parent and child have the same
10472 all_stimuli = tobesent = [p for p in pkt]
10473 notans = len(tobesent)
10495 rdpipe,wrpipe = os.pipe()
10496 rdpipe=os.fdopen(rdpipe)
10497 wrpipe=os.fdopen(wrpipe,"w")
10509 print "Begin emission:"
10515 print "Finished to send %i packets." % i
10518 except KeyboardInterrupt:
10521 log_runtime.exception("--- Error in child %i" % os.getpid())
10522 log_runtime.info("--- Error in child %i" % os.getpid())
10525 os.setpgrp() # Chance process group to avoid ctrl-C
10526 sent_times = [p.sent_time for p in all_stimuli if p.sent_time]
10527 cPickle.dump( (arp_cache,sent_times), wrpipe )
10532 log_runtime.error("fork error")
10537 inmask = [rdpipe,pks]
10542 remaintime = stoptime-time.time()
10543 if remaintime <= 0:
10546 if FREEBSD or DARWIN:
10547 inp, out, err = select(inmask,[],[], 0.05)
10548 if len(inp) == 0 or pks in inp:
10549 r = pks.nonblock_recv()
10551 inp, out, err = select(inmask,[],[], remaintime)
10558 stoptime = time.time()+timeout
10559 del(inmask[inmask.index(rdpipe)])
10566 for i in range(len(hlst)):
10567 if r.answers(hlst[i]):
10568 ans.append((hlst[i],r))
10576 if not hasattr(hlst[i], '_answered'):
10578 hlst[i]._answered = 1;
10580 if notans == 0 and not multi:
10586 if conf.debug_match:
10587 debug.recv.append(r)
10588 except KeyboardInterrupt:
10593 ac,sent_times = cPickle.load(rdpipe)
10595 warning("Child died unexpectedly. Packets may have not been sent %i"%os.getpid())
10597 arp_cache.update(ac)
10598 for p,t in zip(all_stimuli, sent_times):
10605 remain = reduce(list.__add__, hsent.values(), [])
10607 remain = filter(lambda p: not hasattr(p, '_answered'), remain);
10609 if autostop and len(remain) > 0 and len(remain) != len(tobesent):
10613 if len(tobesent) == 0:
10617 if conf.debug_match:
10618 debug.sent=PacketList(remain[:],"Sent")
10619 debug.match=SndRcvList(ans[:])
10621 #clean the ans list to delete the field _answered
10624 if hasattr(s, '_answered'):
10628 print "\nReceived %i packets, got %i answers, remaining %i packets" % (nbrecv+len(ans), len(ans), notans)
10629 return SndRcvList(ans),PacketList(remain,"Unanswered"),debug.recv
10632 def __gen_send(s, x, inter=0, loop=0, count=None, verbose=None, *args, **kargs):
10633 if not isinstance(x, Gen):
10635 if verbose is None:
10636 verbose = conf.verb
10638 if count is not None:
10652 except KeyboardInterrupt:
10656 print "\nSent %i packets." % n
10658 def send(x, inter=0, loop=0, count=None, verbose=None, *args, **kargs):
10659 """Send packets at layer 3
10660 send(packets, [inter=0], [loop=0], [verbose=conf.verb]) -> None"""
10661 __gen_send(conf.L3socket(*args, **kargs), x, inter=inter, loop=loop, count=count,verbose=verbose)
10663 def sendp(x, inter=0, loop=0, iface=None, iface_hint=None, count=None, verbose=None, *args, **kargs):
10664 """Send packets at layer 2
10665 sendp(packets, [inter=0], [loop=0], [verbose=conf.verb]) -> None"""
10666 if iface is None and iface_hint is not None:
10667 iface = conf.route.route(iface_hint)[0]
10668 __gen_send(conf.L2socket(iface=iface, *args, **kargs), x, inter=inter, loop=loop, count=count, verbose=verbose)
10670 def sendpfast(x, pps=None, mbps=None, realtime=None, loop=0, iface=None):
10671 """Send packets at layer 2 using tcpreplay for performance
10672 pps: packets per second
10673 mpbs: MBits per second
10674 realtime: use packet's timestamp, bending time with realtime value
10675 loop: number of times to process the packet list
10676 iface: output interface """
10679 options = ["--intf1=%s" % iface ]
10680 if pps is not None:
10681 options.append("--pps=%i" % pps)
10682 elif mbps is not None:
10683 options.append("--mbps=%i" % mbps)
10684 elif realtime is not None:
10685 options.append("--multiplier=%i" % realtime)
10687 options.append("--topspeed")
10690 options.append("--loop=%i" % loop)
10692 f = os.tempnam("scapy")
10697 os.spawnlp(os.P_WAIT, conf.prog.tcpreplay, conf.prog.tcpreplay, *options)
10698 except KeyboardInterrupt:
10699 log_interactive.info("Interrupted by user")
10707 def sr(x,filter=None, iface=None, nofilter=0, *args,**kargs):
10708 """Send and receive packets at layer 3
10709 nofilter: put 1 to avoid use of bpf filters
10710 retry: if positive, how many times to resend unanswered packets
10711 if negative, how many times to retry when no more packets are answered
10712 timeout: how much time to wait after the last packet has been sent
10713 verbose: set verbosity level
10714 multi: whether to accept multiple answers for the same stimulus
10715 filter: provide a BPF filter
10716 iface: listen answers only on the given interface"""
10717 if not kargs.has_key("timeout"):
10718 kargs["timeout"] = -1
10719 s = conf.L3socket(filter=filter, iface=iface, nofilter=nofilter)
10720 a,b,c=sndrcv(s,x,*args,**kargs)
10724 def sr1(x,filter=None,iface=None, nofilter=0, *args,**kargs):
10725 """Send packets at layer 3 and return only the first answer
10726 nofilter: put 1 to avoid use of bpf filters
10727 retry: if positive, how many times to resend unanswered packets
10728 if negative, how many times to retry when no more packets are answered
10729 timeout: how much time to wait after the last packet has been sent
10730 verbose: set verbosity level
10731 multi: whether to accept multiple answers for the same stimulus
10732 filter: provide a BPF filter
10733 iface: listen answers only on the given interface"""
10734 if not kargs.has_key("timeout"):
10735 kargs["timeout"] = -1
10736 s=conf.L3socket(filter=filter, nofilter=nofilter, iface=iface)
10737 a,b,c=sndrcv(s,x,*args,**kargs)
10744 def srp(x,iface=None, iface_hint=None, filter=None, nofilter=0, type=ETH_P_ALL, *args,**kargs):
10745 """Send and receive packets at layer 2
10746 nofilter: put 1 to avoid use of bpf filters
10747 retry: if positive, how many times to resend unanswered packets
10748 if negative, how many times to retry when no more packets are answered
10749 timeout: how much time to wait after the last packet has been sent
10750 verbose: set verbosity level
10751 multi: whether to accept multiple answers for the same stimulus
10752 filter: provide a BPF filter
10753 iface: work only on the given interface"""
10754 if not kargs.has_key("timeout"):
10755 kargs["timeout"] = -1
10756 if iface is None and iface_hint is not None:
10757 iface = conf.route.route(iface_hint)[0]
10758 s = conf.L2socket(iface=iface, filter=filter, nofilter=nofilter, type=type)
10759 a,b,c=sndrcv(s ,x,*args,**kargs)
10763 def srp1(*args,**kargs):
10764 """Send and receive packets at layer 2 and return only the first answer
10765 nofilter: put 1 to avoid use of bpf filters
10766 retry: if positive, how many times to resend unanswered packets
10767 if negative, how many times to retry when no more packets are answered
10768 timeout: how much time to wait after the last packet has been sent
10769 verbose: set verbosity level
10770 multi: whether to accept multiple answers for the same stimulus
10771 filter: provide a BPF filter
10772 iface: work only on the given interface"""
10773 if not kargs.has_key("timeout"):
10774 kargs["timeout"] = -1
10775 a,b=srp(*args,**kargs)
10781 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):
10784 ct = conf.color_theme
10785 if verbose is None:
10786 verbose = conf.verb
10790 if timeout is None:
10791 timeout = min(2*inter, 5)
10795 col = [ct.even,ct.odd][parity]
10796 if count is not None:
10800 start = time.time()
10801 print "\rsend...\r",
10802 res = srfunc(pkts, timeout=timeout, verbose=0, chainCC=1, *args, **kargs)
10803 n += len(res[0])+len(res[1])
10805 if verbose > 1 and prn and len(res[0]) > 0:
10806 msg = "RECV %i:" % len(res[0])
10807 print "\r"+ct.success(msg),
10810 print " "*len(msg),
10811 if verbose > 1 and prnfail and len(res[1]) > 0:
10812 msg = "fail %i:" % len(res[1])
10813 print "\r"+ct.fail(msg),
10815 print col(prnfail(p))
10816 print " "*len(msg),
10817 if verbose > 1 and not (prn or prnfail):
10818 print "recv:%i fail:%i" % tuple(map(len, res[:2]))
10823 if end-start < inter:
10824 time.sleep(inter+start-end)
10825 except KeyboardInterrupt:
10828 if verbose and n>0:
10829 print ct.normal("\nSent %i packets, received %i packets. %3.1f%% hits." % (n,r,100.0*r/n))
10830 return SndRcvList(ans),PacketList(unans)
10832 def srloop(pkts, *args, **kargs):
10833 """Send a packet at layer 3 in loop and print the answer each time
10834 srloop(pkts, [prn], [inter], [count], ...) --> None"""
10835 return __sr_loop(sr, pkts, *args, **kargs)
10837 def srploop(pkts, *args, **kargs):
10838 """Send a packet at layer 2 in loop and print the answer each time
10839 srloop(pkts, [prn], [inter], [count], ...) --> None"""
10840 return __sr_loop(srp, pkts, *args, **kargs)
10843 def sndrcvflood(pks, pkt, prn=lambda (s,r):r.summary(), chainCC=0, store=1, unique=0):
10844 if not isinstance(pkt, Gen):
10846 tobesent = [p for p in pkt]
10847 received = SndRcvList()
10858 def send_in_loop(tobesent):
10863 packets_to_send = send_in_loop(tobesent)
10865 ssock = rsock = pks.fileno()
10869 readyr,readys,_ = select([rsock],[ssock],[])
10870 if ssock in readys:
10871 pks.send(packets_to_send.next())
10873 if rsock in readyr:
10887 if res is not None:
10890 received.append((i,p))
10891 except KeyboardInterrupt:
10896 def srflood(x,filter=None, iface=None, nofilter=None, *args,**kargs):
10897 """Flood and receive packets at layer 3
10898 prn: function applied to packets received. Ret val is printed if not None
10899 store: if 1 (default), store answers and return them
10900 unique: only consider packets whose print
10901 nofilter: put 1 to avoid use of bpf filters
10902 filter: provide a BPF filter
10903 iface: listen answers only on the given interface"""
10904 s = conf.L3socket(filter=filter, iface=iface, nofilter=nofilter)
10905 r=sndrcvflood(s,x,*args,**kargs)
10909 def srpflood(x,filter=None, iface=None, iface_hint=None, nofilter=None, *args,**kargs):
10910 """Flood and receive packets at layer 2
10911 prn: function applied to packets received. Ret val is printed if not None
10912 store: if 1 (default), store answers and return them
10913 unique: only consider packets whose print
10914 nofilter: put 1 to avoid use of bpf filters
10915 filter: provide a BPF filter
10916 iface: listen answers only on the given interface"""
10917 if iface is None and iface_hint is not None:
10918 iface = conf.route.route(iface_hint)[0]
10919 s = conf.L2socket(filter=filter, iface=iface, nofilter=nofilter)
10920 r=sndrcvflood(s,x,*args,**kargs)
10928 def srbt(peer, pkts, inter=0.1, *args, **kargs):
10929 s = conf.BTsocket(peer=peer)
10930 a,b,c=sndrcv(s,pkts,inter=inter,*args,**kargs)
10934 def srbt1(peer, pkts, *args, **kargs):
10935 a,b = srbt(peer, pkts, *args, **kargs)
10943 #############################
10944 ## pcap capture file stuff ##
10945 #############################
10947 def wrpcap(filename, pkt, *args, **kargs):
10948 """Write a list of packets to a pcap file
10949 gz: set to 1 to save a gzipped capture
10950 linktype: force linktype value
10951 endianness: "<" or ">", force endianness"""
10952 PcapWriter(filename, *args, **kargs).write(pkt)
10954 def rdpcap(filename, count=-1):
10955 """Read a pcap file and return a packet list
10956 count: read only <count> packets"""
10957 return PcapReader(filename).read_all(count=count)
10960 """A stateful pcap reader
10962 Based entirely on scapy.rdpcap(), this class allows for packets
10963 to be dispatched without having to be loaded into memory all at
10967 def __init__(self, filename):
10968 self.filename = filename
10970 self.f = gzip.open(filename,"rb")
10971 magic = self.f.read(4)
10973 self.f = open(filename,"rb")
10974 magic = self.f.read(4)
10975 if magic == "\xa1\xb2\xc3\xd4": #big endian
10977 elif magic == "\xd4\xc3\xb2\xa1": #little endian
10980 raise RuntimeWarning, "Not a pcap capture file (bad magic)"
10981 hdr = self.f.read(20)
10983 raise RuntimeWarning, "Invalid pcap file (too short)"
10984 vermaj,vermin,tz,sig,snaplen,linktype = struct.unpack(self.endian+"HHIIII",hdr)
10985 self.LLcls = LLTypes.get(linktype, Raw)
10986 if self.LLcls == Raw:
10987 warning("PcapReader: unkonwon LL type [%i]/[%#x]. Using Raw packets" % (linktype,linktype))
10989 def __iter__(self):
10993 """impliment the iterator protocol on a set of packets in a
10996 pkt = self.read_packet()
10998 raise StopIteration
11002 def read_packet(self):
11003 """return a single packet read from the file
11005 returns None when no more packets are available
11007 hdr = self.f.read(16)
11010 sec,usec,caplen,olen = struct.unpack(self.endian+"IIII", hdr)
11011 s = self.f.read(caplen)
11014 except KeyboardInterrupt:
11017 if conf.debug_dissector:
11020 p.time = sec+0.000001*usec
11023 def dispatch(self, callback):
11024 """call the specified callback routine for each packet read
11026 This is just a convienience function for the main loop
11027 that allows for easy launching of packet processing in a
11030 p = self.read_packet()
11033 p = self.read_packet()
11035 def read_all(self,count=-1):
11036 """return a list of all packets in the pcap file
11041 p = self.read_packet()
11045 return PacketList(res,name = os.path.basename(self.filename))
11047 def recv(self, size):
11048 """ Emulate a socket
11050 return self.read_packet()
11053 return self.f.fileno()
11058 """A stream PCAP writer with more control than wrpcap()"""
11059 def __init__(self, filename, linktype=None, gz=False, endianness="", append=False, sync=False):
11061 linktype: force linktype to a given value. If None, linktype is taken
11062 from the first writter packet
11063 gz: compress the capture on the fly
11064 endianness: force an endianness (little:"<", big:">"). Default is native
11065 append: append packets to the capture file instead of truncating it
11066 sync: do not bufferize writes to the capture file
11069 self.linktype = linktype
11070 self.header_present = 0
11073 self.endian = endianness
11074 self.filename=filename
11080 self.f = [open,gzip.open][gz](filename,append and "ab" or "wb", gz and 9 or bufsz)
11085 return self.f.fileno()
11087 def _write_header(self, pkt):
11088 self.header_present=1
11090 if self.linktype == None:
11091 if type(pkt) is list or type(pkt) is tuple:
11093 self.linktype = LLNumTypes.get(pkt.__class__,1)
11096 # Even if prone to race conditions, this seems to be
11097 # safest way to tell whether the header is already present
11098 # because we have to handle compressed streams that
11099 # are not as flexible as basic files
11100 g = [open,gzip.open][self.gz](self.filename,"rb")
11104 self.f.write(struct.pack(self.endian+"IHHIIII", 0xa1b2c3d4L,
11105 2, 4, 0, 0, MTU, self.linktype))
11109 def write(self, pkt):
11110 """accepts a either a single packet or a list of packets
11111 to be written to the dumpfile
11113 if not self.header_present:
11114 self._write_header(pkt)
11116 self._write_packet(p)
11118 def _write_packet(self, packet):
11119 """writes a single packet to the pcap file
11123 sec = int(packet.time)
11124 usec = int((packet.time-sec)*1000000)
11125 self.f.write(struct.pack(self.endian+"IIII", sec, usec, l, l))
11127 if self.gz and self.sync:
11131 return self.f.flush()
11133 return self.f.close()
11136 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})")
11138 def import_hexcap():
11142 l = raw_input().strip()
11144 p += re_extract_hexcap.match(l).groups()[3]
11146 warning("Parsing error during hexcap")
11151 p = p.replace(" ","")
11153 for i in range(len(p)/2):
11154 p2 += chr(int(p[2*i:2*i+2],16))
11159 def wireshark(pktlist):
11160 f = os.tempnam("scapy")
11162 os.spawnlp(os.P_NOWAIT, conf.prog.wireshark, conf.prog.wireshark, "-r", f)
11166 f = os.tempnam("scapy")
11167 open(f,"w").write(x)
11168 os.spawnlp(os.P_WAIT, conf.prog.hexedit, conf.prog.hexedit, f)
11174 #####################
11175 ## knowledge bases ##
11176 #####################
11178 class KnowledgeBase:
11179 def __init__(self, filename):
11180 self.filename = filename
11183 def lazy_init(self):
11186 def reload(self, filename = None):
11187 if filename is not None:
11188 self.filename = filename
11189 oldbase = self.base
11192 if self.base is None:
11193 self.base = oldbase
11195 def get_base(self):
11196 if self.base is None:
11202 ##########################
11203 ## IP location database ##
11204 ##########################
11206 class IPCountryKnowledgeBase(KnowledgeBase):
11208 How to generate the base :
11210 for l in open("GeoIPCountryWhois.csv").readlines():
11211 s,e,c = l.split(",")[2:5]
11212 db.append((int(s[1:-1]),int(e[1:-1]),c[1:-1]))
11213 cPickle.dump(gzip.open("xxx","w"),db)
11215 def lazy_init(self):
11216 self.base = load_object(self.filename)
11219 class CountryLocKnowledgeBase(KnowledgeBase):
11220 def lazy_init(self):
11221 f=open(self.filename)
11227 l = l.strip().split(",")
11232 self.base[c] = (float(long),float(lat))
11239 ip=map(int,ip.split("."))
11240 ip = ip[3]+(ip[2]<<8L)+(ip[1]<<16L)+(ip[0]<<24L)
11242 cloc = country_loc_kdb.get_base()
11243 db = IP_country_kdb.get_base()
11249 if ip > db[guess][0]:
11254 if s <= ip and ip <= e:
11255 return cloc.get(c,None)
11264 # File format (according to p0f.fp) :
11266 # wwww:ttt:D:ss:OOO...:QQ:OS:Details
11268 # wwww - window size
11269 # ttt - initial TTL
11270 # D - don't fragment bit (0=unset, 1=set)
11271 # ss - overall SYN packet size
11272 # OOO - option value and order specification
11275 # details - OS description
11279 class p0fKnowledgeBase(KnowledgeBase):
11280 def __init__(self, filename):
11281 KnowledgeBase.__init__(self, filename)
11282 #self.ttl_range=[255]
11283 def lazy_init(self):
11285 f=open(self.filename)
11287 warning("Can't open base %s" % self.filename)
11292 if l[0] in ["#","\n"]:
11294 l = tuple(l.split(":"))
11297 li = map(int,l[1:4])
11298 #if li[0] not in self.ttl_range:
11299 # self.ttl_range.append(li[0])
11300 # self.ttl_range.sort()
11301 self.base.append((l[0], li[0], li[1], li[2], l[4], l[5], l[6], l[7][:-1]))
11303 warning("Can't parse p0f database (new p0f version ?)")
11308 def packet2p0f(pkt):
11309 while pkt.haslayer(IP) and pkt.haslayer(TCP):
11310 pkt = pkt.getlayer(IP)
11311 if isinstance(pkt.payload, TCP):
11315 if not isinstance(pkt, IP) or not isinstance(pkt.payload, TCP):
11316 raise TypeError("Not a TCP/IP packet")
11317 if pkt.payload.flags & 0x13 != 0x02: #S,!A,!F
11318 raise TypeError("Not a syn packet")
11320 #t = p0f_kdb.ttl_range[:]
11323 #ttl=t[t.index(pkt.ttl)+1]
11326 df = (pkt.flags & 2) / 2
11328 # from p0f/config.h : PACKET_BIG = 100
11337 ilen = (pkt[TCP].dataofs << 2) - 20 # from p0f.c
11338 for option in pkt.payload.options:
11340 if option[0] == "MSS":
11341 ooo += "M" + str(option[1]) + ","
11345 elif option[0] == "WScale":
11346 ooo += "W" + str(option[1]) + ","
11349 elif option[0] == "Timestamp":
11350 if option[1][0] == 0:
11354 if option[1][1] != 0:
11357 elif option[0] == "SAckOK":
11360 elif option[0] == "NOP":
11362 elif option[0] == "EOL":
11370 if ooo == "": ooo = "."
11372 win = pkt.payload.window
11375 win = "S" + str(win/mss)
11376 elif win % (mss + 40) == 0:
11377 win = "T" + str(win/(mss+40))
11384 if pkt[IP].id == 0:
11386 if pkt[IP].options != '':
11388 if pkt[TCP].urgptr != 0:
11390 if pkt[TCP].reserved != 0:
11392 if pkt[TCP].ack != 0:
11396 if pkt[TCP].flags & 40 != 0:
11399 if not isinstance(pkt[TCP].payload, NoPayload):
11401 # FIXME : "!" - broken options segment
11413 def p0f_correl(x,y):
11415 # wwww can be "*" or "%nn"
11416 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))
11418 d += (y[1] >= x[1] and y[1] - x[1] < 32)
11419 for i in [2, 3, 5]:
11420 d += (x[i] == y[i])
11421 xopt = x[4].split(",")
11422 yopt = y[4].split(",")
11423 if len(xopt) == len(yopt):
11425 for i in range(len(xopt)):
11426 if not (xopt[i] == yopt[i] or
11427 (len(yopt[i]) == 2 and len(xopt[i]) > 1 and
11428 yopt[i][1] == "*" and xopt[i][0] == yopt[i][0]) or
11429 (len(yopt[i]) > 2 and len(xopt[i]) > 1 and
11430 yopt[i][1] == "%" and xopt[i][0] == yopt[i][0] and
11431 int(xopt[i][1:]) % int(yopt[i][2:]) == 0)):
11440 """Passive OS fingerprinting: which OS emitted this TCP SYN ?
11441 p0f(packet) -> accuracy, [list of guesses]
11443 pb = p0f_kdb.get_base()
11445 warning("p0f base empty.")
11449 sig = packet2p0f(pkt)
11450 max = len(sig[4].split(",")) + 5
11452 d = p0f_correl(sig,b)
11454 r.append((b[6], b[7], b[1] - pkt[IP].ttl))
11464 r = ("UNKNOWN", "[" + ":".join(map(str, packet2p0f(pkt))) + ":?:?]", None)
11469 uptime = pkt2uptime(pkt)
11474 res = pkt.sprintf("%IP.src%:%TCP.sport% - " + r[0] + " " + r[1])
11475 if uptime is not None:
11476 res += pkt.sprintf(" (up: " + str(uptime/3600) + " hrs)\n -> %IP.dst%:%TCP.dport%")
11478 res += pkt.sprintf("\n -> %IP.dst%:%TCP.dport%")
11479 if r[2] is not None:
11480 res += " (distance " + str(r[2]) + ")"
11484 def pkt2uptime(pkt, HZ=100):
11485 """Calculate the date the machine which emitted the packet booted using TCP timestamp
11486 pkt2uptime(pkt, [HZ=100])"""
11487 if not isinstance(pkt, Packet):
11488 raise TypeError("Not a TCP packet")
11489 if isinstance(pkt,NoPayload):
11490 raise TypeError("Not a TCP packet")
11491 if not isinstance(pkt, TCP):
11492 return pkt2uptime(pkt.payload)
11493 for opt in pkt.options:
11494 if opt[0] == "Timestamp":
11495 #t = pkt.time - opt[1][0] * 1.0/HZ
11496 #return time.ctime(t)
11499 raise TypeError("No timestamp option")
11508 def quesoTCPflags(flags):
11514 v |= 2**flv.index(i)
11517 class QuesoKnowledgeBase(KnowledgeBase):
11518 def lazy_init(self):
11520 f = open(self.filename)
11528 if not l or l[0] == ';':
11533 name = l[1:].strip()
11536 if l[0] not in list("0123456"):
11538 res = l[2:].split()
11539 res[-1] = quesoTCPflags(res[-1])
11540 res = " ".join(res)
11541 if not p.has_key(res):
11548 warning("Can't load queso base [%s]", self.filename)
11554 def queso_sig(target, dport=80, timeout=3):
11555 p = queso_kdb.get_base()
11557 for flags in ["S", "SA", "F", "FA", "SF", "P", "SEC"]:
11558 ans, unans = sr(IP(dst=target)/TCP(dport=dport,flags=flags,seq=RandInt()),
11559 timeout=timeout, verbose=0)
11564 rs = "%i" % (r.seq != 0)
11567 elif r.ack-s.seq > 666:
11570 rs += " +%i" % (r.ack-s.seq)
11571 rs += " %X" % r.window
11572 rs += " %x" % r.payload.flags
11576 def queso_search(sig):
11577 p = queso_kdb.get_base()
11591 def queso(*args,**kargs):
11592 """Queso OS fingerprinting
11593 queso(target, dport=80, timeout=3)"""
11594 return queso_search(queso_sig(*args, **kargs))
11598 ######################
11599 ## nmap OS fp stuff ##
11600 ######################
11603 class NmapKnowledgeBase(KnowledgeBase):
11604 def lazy_init(self):
11606 f=open(self.filename)
11615 if not l or l[0] == "#":
11617 if l[:12] == "Fingerprint ":
11618 if name is not None:
11619 self.base.append((name,sig))
11620 name = l[12:].strip()
11624 elif l[:6] == "Class ":
11628 if op < 0 or cl < 0:
11629 warning("error reading nmap os fp base file")
11632 s = map(lambda x: x.split("="), l[op+1:cl].split("%"))
11637 if name is not None:
11638 self.base.append((name,sig))
11641 warning("Can't read nmap database [%s](new nmap version ?)" % self.filename)
11644 def TCPflags2str(f):
11647 for i in range(len(fl)):
11653 def nmap_tcppacket_sig(pkt):
11655 if pkt is not None:
11657 r["DF"] = (pkt.flags & 2) and "Y" or "N"
11658 r["W"] = "%X" % pkt.window
11659 r["ACK"] = pkt.ack==2 and "S++" or pkt.ack==1 and "S" or "O"
11660 r["Flags"] = TCPflags2str(pkt.payload.flags)
11661 r["Ops"] = "".join(map(lambda x: x[0][0],pkt.payload.options))
11667 def nmap_udppacket_sig(S,T):
11672 r["DF"] = (T.flags & 2) and "Y" or "N"
11673 r["TOS"] = "%X" % T.tos
11674 r["IPLEN"] = "%X" % T.len
11675 r["RIPTL"] = "%X" % T.payload.payload.len
11676 r["RID"] = S.id == T.payload.payload.id and "E" or "F"
11677 r["RIPCK"] = S.chksum == T.getlayer(IPerror).chksum and "E" or T.getlayer(IPerror).chksum == 0 and "0" or "F"
11678 r["UCK"] = S.payload.chksum == T.getlayer(UDPerror).chksum and "E" or T.getlayer(UDPerror).chksum ==0 and "0" or "F"
11679 r["ULEN"] = "%X" % T.getlayer(UDPerror).len
11680 r["DAT"] = T.getlayer(Raw) is None and "E" or S.getlayer(Raw).load == T.getlayer(Raw).load and "E" or "F"
11685 def nmap_match_one_sig(seen, ref):
11687 for k in seen.keys():
11689 if seen[k] in ref[k].split("|"):
11691 if c == 0 and seen.get("Resp") == "N":
11694 return 1.0*c/len(seen.keys())
11698 def nmap_sig(target, oport=80, cport=81, ucport=1):
11701 tcpopt = [ ("WScale", 10),
11704 ("Timestamp",(123,0)) ]
11705 tests = [ IP(dst=target, id=1)/TCP(seq=1, sport=5001, dport=oport, options=tcpopt, flags="CS"),
11706 IP(dst=target, id=1)/TCP(seq=1, sport=5002, dport=oport, options=tcpopt, flags=0),
11707 IP(dst=target, id=1)/TCP(seq=1, sport=5003, dport=oport, options=tcpopt, flags="SFUP"),
11708 IP(dst=target, id=1)/TCP(seq=1, sport=5004, dport=oport, options=tcpopt, flags="A"),
11709 IP(dst=target, id=1)/TCP(seq=1, sport=5005, dport=cport, options=tcpopt, flags="S"),
11710 IP(dst=target, id=1)/TCP(seq=1, sport=5006, dport=cport, options=tcpopt, flags="A"),
11711 IP(dst=target, id=1)/TCP(seq=1, sport=5007, dport=cport, options=tcpopt, flags="FPU"),
11712 IP(str(IP(dst=target)/UDP(sport=5008,dport=ucport)/(300*"i"))) ]
11714 ans, unans = sr(tests, timeout=2)
11715 ans += map(lambda x: (x,None), unans)
11718 if S.sport == 5008:
11719 res["PU"] = nmap_udppacket_sig(S,T)
11721 t = "T%i" % (S.sport-5000)
11722 if T is not None and T.haslayer(ICMP):
11723 warning("Test %s answered by an ICMP" % t)
11725 res[t] = nmap_tcppacket_sig(T)
11729 def nmap_probes2sig(tests):
11733 res["PU"] = nmap_udppacket_sig(*tests["PU"])
11736 res[k] = nmap_tcppacket_sig(tests[k])
11740 def nmap_search(sigs):
11742 for os,fp in nmap_kdb.get_base():
11744 for t in sigs.keys():
11746 c += nmap_match_one_sig(sigs[t], fp[t])
11747 c /= len(sigs.keys())
11750 elif c == guess[0]:
11751 guess[1].append(os)
11755 def nmap_fp(target, oport=80, cport=81):
11756 """nmap fingerprinting
11757 nmap_fp(target, [oport=80,] [cport=81,]) -> list of best guesses with accuracy
11759 sigs = nmap_sig(target, oport, cport)
11760 return nmap_search(sigs)
11763 def nmap_sig2txt(sig):
11764 torder = ["TSeq","T1","T2","T3","T4","T5","T6","T7","PU"]
11765 korder = ["Class", "gcd", "SI", "IPID", "TS",
11766 "Resp", "DF", "W", "ACK", "Flags", "Ops",
11767 "TOS", "IPLEN", "RIPTL", "RID", "RIPCK", "UCK", "ULEN", "DAT" ]
11769 for i in sig.keys():
11770 if i not in torder:
11781 s.append("%s=%s"%(k,v))
11782 txt.append("%s(%s)" % (t, "%".join(s)))
11783 return "\n".join(txt)
11789 ###################
11790 ## User commands ##
11791 ###################
11794 def sniff(count=0, store=1, offline=None, prn = None, lfilter=None, L2socket=None, timeout=None, *arg, **karg):
11796 sniff([count=0,] [prn=None,] [store=1,] [offline=None,] [lfilter=None,] + L2ListenSocket args) -> list of packets
11798 count: number of packets to capture. 0 means infinity
11799 store: wether to store sniffed packets or discard them
11800 prn: function to apply to each packet. If something is returned,
11801 it is displayed. Ex:
11802 ex: prn = lambda x: x.summary()
11803 lfilter: python function applied to each packet to determine
11804 if further action may be done
11805 ex: lfilter = lambda x: x.haslayer(Padding)
11806 offline: pcap file to read packets from, instead of sniffing them
11807 timeout: stop sniffing after a given time (default: None)
11808 L2socket: use the provided L2socket
11812 if offline is None:
11813 if L2socket is None:
11814 L2socket = conf.L2listen
11815 s = L2socket(type=ETH_P_ALL, *arg, **karg)
11817 s = PcapReader(offline)
11820 if timeout is not None:
11821 stoptime = time.time()+timeout
11825 if timeout is not None:
11826 remain = stoptime-time.time()
11829 sel = select([s],[],[],remain)
11834 if lfilter and not lfilter(p):
11843 if count > 0 and c >= count:
11845 except KeyboardInterrupt:
11848 return PacketList(lst,"Sniffed")
11852 def arpcachepoison(target, victim, interval=60):
11853 """Poison target's cache with (your MAC,victim's IP) couple
11854 arpcachepoison(target, victim, [interval=60]) -> None
11856 tmac = getmacbyip(target)
11857 p = Ether(dst=tmac)/ARP(op="who-has", psrc=victim, pdst=target)
11860 sendp(p, iface_hint=target)
11863 time.sleep(interval)
11864 except KeyboardInterrupt:
11867 def traceroute(target, dport=80, minttl=1, maxttl=30, sport=RandShort(), l4 = None, filter=None, timeout=2, verbose=None, **kargs):
11868 """Instant TCP traceroute
11869 traceroute(target, [maxttl=30,] [dport=80,] [sport=80,] [verbose=conf.verb]) -> None
11871 if verbose is None:
11872 verbose = conf.verb
11874 # we only consider ICMP error packets and TCP packets with at
11875 # least the ACK flag set *and* either the SYN or the RST flag
11877 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))"
11879 a,b = sr(IP(dst=target, id=RandShort(), ttl=(minttl,maxttl))/TCP(seq=RandInt(),sport=sport, dport=dport),
11880 timeout=timeout, filter=filter, verbose=verbose, **kargs)
11882 # this should always work
11884 a,b = sr(IP(dst=target, id=RandShort(), ttl=(minttl,maxttl))/l4,
11885 timeout=timeout, filter=filter, verbose=verbose, **kargs)
11887 a = TracerouteResult(a.res)
11895 def arping(net, timeout=2, cache=0, verbose=None, **kargs):
11896 """Send ARP who-has requests to determine which hosts are up
11897 arping(net, [cache=0,] [iface=conf.iface,] [verbose=conf.verb]) -> None
11898 Set cache=True if you want arping to modify internal ARP-Cache"""
11899 if verbose is None:
11900 verbose = conf.verb
11901 ans,unans = srp(Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(pdst=net), verbose=verbose,
11902 filter="arp and arp[7] = 2", timeout=timeout, iface_hint=net, **kargs)
11903 ans = ARPingResult(ans.res)
11905 if cache and ans is not None:
11907 arp_cache[pair[1].psrc] = (pair[1].hwsrc, time.time())
11912 def dyndns_add(nameserver, name, rdata, type="A", ttl=10):
11913 """Send a DNS add message to a nameserver for "name" to have a new "rdata"
11914 dyndns_add(nameserver, name, rdata, type="A", ttl=10) -> result code (0=ok)
11916 example: dyndns_add("ns1.toto.com", "dyn.toto.com", "127.0.0.1")
11919 zone = name[name.find(".")+1:]
11920 r=sr1(IP(dst=nameserver)/UDP()/DNS(opcode=5,
11921 qd=[DNSQR(qname=zone, qtype="SOA")],
11922 ns=[DNSRR(rrname=name, type="A",
11923 ttl=ttl, rdata=rdata)]),
11924 verbose=0, timeout=5)
11925 if r and r.haslayer(DNS):
11926 return r.getlayer(DNS).rcode
11933 def dyndns_del(nameserver, name, type="ALL", ttl=10):
11934 """Send a DNS delete message to a nameserver for "name"
11935 dyndns_del(nameserver, name, type="ANY", ttl=10) -> result code (0=ok)
11937 example: dyndns_del("ns1.toto.com", "dyn.toto.com")
11940 zone = name[name.find(".")+1:]
11941 r=sr1(IP(dst=nameserver)/UDP()/DNS(opcode=5,
11942 qd=[DNSQR(qname=zone, qtype="SOA")],
11943 ns=[DNSRR(rrname=name, type=type,
11944 rclass="ANY", ttl=0, rdata="")]),
11945 verbose=0, timeout=5)
11946 if r and r.haslayer(DNS):
11947 return r.getlayer(DNS).rcode
11952 def is_promisc(ip, fake_bcast="ff:ff:00:00:00:00",**kargs):
11953 """Try to guess if target is in Promisc mode. The target is provided by its ip."""
11955 responses = srp1(Ether(dst=fake_bcast) / ARP(op="who-has", pdst=ip),type=ETH_P_ARP, iface_hint=ip, timeout=1, verbose=0,**kargs)
11957 return responses is not None
11959 def promiscping(net, timeout=2, fake_bcast="ff:ff:ff:ff:ff:fe", **kargs):
11960 """Send ARP who-has requests to determine which hosts are in promiscuous mode
11961 promiscping(net, iface=conf.iface)"""
11962 ans,unans = srp(Ether(dst=fake_bcast)/ARP(pdst=net),
11963 filter="arp and arp[7] = 2", timeout=timeout, iface_hint=net, **kargs)
11964 ans = ARPingResult(ans.res, name="PROMISCPing")
11970 return sr(IP(dst=ip)/UDP()/ISAKMP(init_cookie=RandString(8),
11971 exch_type=2)/ISAKMP_payload_SA(prop=ISAKMP_payload_Proposal()))
11974 def dhcp_request(iface=None,**kargs):
11975 if conf.checkIPaddr != 0:
11976 warning("conf.checkIPaddr is not 0, I may not be able to match the answer")
11979 fam,hw = get_if_raw_hwaddr(iface)
11980 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)
11981 /BOOTP(chaddr=hw)/DHCP(options=[("message-type","discover"),"end"]),iface=iface,**kargs)
11983 def snmpwalk(dst, oid="1", community="public"):
11986 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)
11993 print "%-40s: %r" % (r[SNMPvarbind].oid.val,r[SNMPvarbind].value)
11994 oid = r[SNMPvarbind].oid
11996 except KeyboardInterrupt:
12000 #####################
12001 ## Reporting stuff ##
12002 #####################
12004 def report_ports(target, ports):
12005 """portscan a target and output a LaTeX table
12006 report_ports(target, ports) -> string"""
12007 ans,unans = sr(IP(dst=target)/TCP(dport=ports),timeout=5)
12008 rep = "\\begin{tabular}{|r|l|l|}\n\\hline\n"
12010 if not r.haslayer(ICMP):
12011 if r.payload.flags == 0x12:
12012 rep += r.sprintf("%TCP.sport% & open & SA \\\\\n")
12015 if r.haslayer(ICMP):
12016 rep += r.sprintf("%TCPerror.dport% & closed & ICMP type %ICMP.type%/%ICMP.code% from %IP.src% \\\\\n")
12017 elif r.payload.flags != 0x12:
12018 rep += r.sprintf("%TCP.sport% & closed & TCP %TCP.flags% \\\\\n")
12021 rep += i.sprintf("%TCP.dport% & ? & unanswered \\\\\n")
12022 rep += "\\hline\n\\end{tabular}\n"
12026 def __make_table(yfmtfunc, fmtfunc, endline, list, fxyz, sortx=None, sorty=None, seplinefunc=None):
12034 xx,yy,zz = map(str, fxyz(e))
12036 vx[xx] = max(vx.get(xx,0), len(xx), len(zz))
12046 vxk.sort(lambda x,y:int(x)-int(y))
12049 vxk.sort(lambda x,y: cmp(atol(x),atol(y)))
12056 vyk.sort(lambda x,y:int(x)-int(y))
12059 vyk.sort(lambda x,y: cmp(atol(x),atol(y)))
12065 sepline = seplinefunc(l, map(lambda x:vx[x],vxk))
12071 vxf[x] = fmtfunc(vx[x])
12079 print vxf[x] % vz.get((x,y), "-"),
12084 def make_table(*args, **kargs):
12085 __make_table(lambda l:"%%-%is" % l, lambda l:"%%-%is" % l, "", *args, **kargs)
12087 def make_lined_table(*args, **kargs):
12088 __make_table(lambda l:"%%-%is |" % l, lambda l:"%%-%is |" % l, "",
12089 seplinefunc=lambda a,x:"+".join(map(lambda y:"-"*(y+2), [a-1]+x+[-2])),
12092 def make_tex_table(*args, **kargs):
12093 __make_table(lambda l: "%s", lambda l: "& %s", "\\\\", seplinefunc=lambda a,x:"\\hline", *args, **kargs)
12096 ######################
12097 ## Online doc stuff ##
12098 ######################
12102 """List user commands"""
12104 for c in user_commands:
12105 doc = "No doc. available"
12107 doc = c.__doc__.split("\n")[0]
12109 print "%-16s : %s" % (c.__name__, doc)
12114 """List available layers, or infos on a given layer"""
12117 all = __builtin__.__dict__.copy()
12118 all.update(globals())
12119 objlst = filter(lambda (n,o): isinstance(o,type) and issubclass(o,Packet), all.items())
12120 objlst.sort(lambda x,y:cmp(x[0],y[0]))
12122 print "%-10s : %s" %(n,o.name)
12124 if isinstance(obj, type) and issubclass(obj, Packet):
12125 for f in obj.fields_desc:
12126 print "%-10s : %-20s = (%s)" % (f.name, f.__class__.__name__, repr(f.default))
12127 elif isinstance(obj, Packet):
12128 for f in obj.fields_desc:
12129 print "%-10s : %-20s = %-15s (%s)" % (f.name, f.__class__.__name__, repr(getattr(obj,f.name)), repr(f.default))
12130 if not isinstance(obj.payload, NoPayload):
12136 print "Not a packet class. Type 'ls()' to list packet classes."
12142 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 ]
12152 CONDITION = "Condition"
12153 RECV = "Receive condition"
12154 TIMEOUT = "Timeout condition"
12156 class NewStateRequested(Exception):
12157 def __init__(self, state_func, automaton, *args, **kargs):
12158 self.func = state_func
12159 self.state = state_func.atmt_state
12160 self.initial = state_func.atmt_initial
12161 self.error = state_func.atmt_error
12162 self.final = state_func.atmt_final
12163 Exception.__init__(self, "Request state [%s]" % self.state)
12164 self.automaton = automaton
12167 self.action_parameters() # init action parameters
12168 def action_parameters(self, *args, **kargs):
12169 self.action_args = args
12170 self.action_kargs = kargs
12173 return self.func(self.automaton, *self.args, **self.kargs)
12176 def state(initial=0,final=0,error=0):
12177 def deco(f,initial=initial, final=final):
12178 f.atmt_type = ATMT.STATE
12179 f.atmt_state = f.func_name
12180 f.atmt_initial = initial
12181 f.atmt_final = final
12182 f.atmt_error = error
12183 def state_wrapper(self, *args, **kargs):
12184 return ATMT.NewStateRequested(f, self, *args, **kargs)
12186 state_wrapper.func_name = "%s_wrapper" % f.func_name
12187 state_wrapper.atmt_type = ATMT.STATE
12188 state_wrapper.atmt_state = f.func_name
12189 state_wrapper.atmt_initial = initial
12190 state_wrapper.atmt_final = final
12191 state_wrapper.atmt_error = error
12192 state_wrapper.atmt_origfunc = f
12193 return state_wrapper
12196 def action(cond, prio=0):
12197 def deco(f,cond=cond):
12198 if not hasattr(f,"atmt_type"):
12200 f.atmt_type = ATMT.ACTION
12201 f.atmt_cond[cond.atmt_condname] = prio
12205 def condition(state, prio=0):
12206 def deco(f, state=state):
12207 f.atmt_type = ATMT.CONDITION
12208 f.atmt_state = state.atmt_state
12209 f.atmt_condname = f.func_name
12214 def receive_condition(state, prio=0):
12215 def deco(f, state=state):
12216 f.atmt_type = ATMT.RECV
12217 f.atmt_state = state.atmt_state
12218 f.atmt_condname = f.func_name
12223 def timeout(state, timeout):
12224 def deco(f, state=state, timeout=timeout):
12225 f.atmt_type = ATMT.TIMEOUT
12226 f.atmt_state = state.atmt_state
12227 f.atmt_timeout = timeout
12228 f.atmt_condname = f.func_name
12233 class Automaton_metaclass(type):
12234 def __new__(cls, name, bases, dct):
12235 cls = super(Automaton_metaclass, cls).__new__(cls, name, bases, dct)
12238 cls.recv_conditions={}
12242 cls.initial_states=[]
12247 c = classes.pop(0) # order is important to avoid breaking method overloading
12248 classes += list(c.__bases__)
12249 for k,v in c.__dict__.iteritems():
12250 if k not in members:
12253 decorated = [v for v in members.itervalues()
12254 if type(v) is types.FunctionType and hasattr(v, "atmt_type")]
12256 for m in decorated:
12257 if m.atmt_type == ATMT.STATE:
12260 cls.recv_conditions[s]=[]
12261 cls.conditions[s]=[]
12264 cls.initial_states.append(m)
12265 elif m.atmt_type in [ATMT.CONDITION, ATMT.RECV, ATMT.TIMEOUT]:
12266 cls.actions[m.atmt_condname] = []
12268 for m in decorated:
12269 if m.atmt_type == ATMT.CONDITION:
12270 cls.conditions[m.atmt_state].append(m)
12271 elif m.atmt_type == ATMT.RECV:
12272 cls.recv_conditions[m.atmt_state].append(m)
12273 elif m.atmt_type == ATMT.TIMEOUT:
12274 cls.timeout[m.atmt_state].append((m.atmt_timeout, m))
12275 elif m.atmt_type == ATMT.ACTION:
12276 for c in m.atmt_cond:
12277 cls.actions[c].append(m)
12280 for v in cls.timeout.itervalues():
12281 v.sort(lambda (t1,f1),(t2,f2): cmp(t1,t2))
12282 v.append((None, None))
12283 for v in itertools.chain(cls.conditions.itervalues(),
12284 cls.recv_conditions.itervalues()):
12285 v.sort(lambda c1,c2: cmp(c1.atmt_prio,c2.atmt_prio))
12286 for condname,actlst in cls.actions.iteritems():
12287 actlst.sort(lambda c1,c2: cmp(c1.atmt_cond[condname], c2.atmt_cond[condname]))
12292 def graph(self, **kargs):
12293 s = 'digraph "%s" {\n' % self.__class__.__name__
12295 se = "" # Keep initial nodes at the begining for better rendering
12296 for st in self.states.itervalues():
12297 if st.atmt_initial:
12298 se = ('\t"%s" [ style=filled, fillcolor=blue, shape=box, root=true];\n' % st.atmt_state)+se
12299 elif st.atmt_final:
12300 se += '\t"%s" [ style=filled, fillcolor=green, shape=octagon ];\n' % st.atmt_state
12301 elif st.atmt_error:
12302 se += '\t"%s" [ style=filled, fillcolor=red, shape=octagon ];\n' % st.atmt_state
12305 for st in self.states.values():
12306 for n in st.atmt_origfunc.func_code.co_names+st.atmt_origfunc.func_code.co_consts:
12307 if n in self.states:
12308 s += '\t"%s" -> "%s" [ color=green ];\n' % (st.atmt_state,n)
12311 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()]:
12313 for n in f.func_code.co_names+f.func_code.co_consts:
12314 if n in self.states:
12315 l = f.atmt_condname
12316 for x in self.actions[f.atmt_condname]:
12317 l += "\\l>[%s]" % x.func_name
12318 s += '\t"%s" -> "%s" [label="%s", color=%s];\n' % (k,n,l,c)
12319 for k,v in self.timeout.iteritems():
12323 for n in f.func_code.co_names+f.func_code.co_consts:
12324 if n in self.states:
12325 l = "%s/%.1fs" % (f.atmt_condname,t)
12326 for x in self.actions[f.atmt_condname]:
12327 l += "\\l>[%s]" % x.func_name
12328 s += '\t"%s" -> "%s" [label="%s",color=blue];\n' % (k,n,l)
12330 return do_graph(s, **kargs)
12335 __metaclass__ = Automaton_metaclass
12337 def __init__(self, *args, **kargs):
12339 self.init_args=args
12340 self.init_kargs=kargs
12341 self.parse_args(*args, **kargs)
12343 def debug(self, lvl, msg):
12344 if self.debug_level >= lvl:
12345 log_interactive.debug(msg)
12350 class ErrorState(Exception):
12351 def __init__(self, msg, result=None):
12352 Exception.__init__(self, msg)
12353 self.result = result
12354 class Stuck(ErrorState):
12357 def parse_args(self, debug=0, store=1, **kargs):
12358 self.debug_level=debug
12359 self.socket_kargs = kargs
12360 self.store_packets = store
12363 def master_filter(self, pkt):
12366 def run_condition(self, cond, *args, **kargs):
12368 cond(self,*args, **kargs)
12369 except ATMT.NewStateRequested, state_req:
12370 self.debug(2, "%s [%s] taken to state [%s]" % (cond.atmt_type, cond.atmt_condname, state_req.state))
12371 if cond.atmt_type == ATMT.RECV:
12372 self.packets.append(args[0])
12373 for action in self.actions[cond.atmt_condname]:
12374 self.debug(2, " + Running action [%s]" % action.func_name)
12375 action(self, *state_req.action_args, **state_req.action_kargs)
12378 self.debug(2, "%s [%s] not taken" % (cond.atmt_type, cond.atmt_condname))
12381 def run(self, *args, **kargs):
12382 # Update default parameters
12383 a = args+self.init_args[len(args):]
12384 k = self.init_kargs
12386 self.parse_args(*a,**k)
12388 # Start the automaton
12389 self.state=self.initial_states[0](self)
12390 self.send_sock = conf.L3socket()
12391 l = conf.L2listen(**self.socket_kargs)
12392 self.packets = PacketList(name="session[%s]"%self.__class__.__name__)
12395 self.debug(1, "## state=[%s]" % self.state.state)
12397 # Entering a new state. First, call new state function
12398 state_output = self.state.run()
12399 if self.state.error:
12400 raise self.ErrorState("Reached %s: [%r]" % (self.state.state, state_output), result=state_output)
12401 if self.state.final:
12402 return state_output
12404 if state_output is None:
12406 elif type(state_output) is not list:
12407 state_output = state_output,
12409 # Then check immediate conditions
12410 for cond in self.conditions[self.state.state]:
12411 self.run_condition(cond, *state_output)
12413 # If still there and no conditions left, we are stuck!
12414 if ( len(self.recv_conditions[self.state.state]) == 0
12415 and len(self.timeout[self.state.state]) == 1 ):
12416 raise self.Stuck("stuck in [%s]" % self.state.state,result=state_output)
12418 # Finally listen and pay attention to timeouts
12419 expirations = iter(self.timeout[self.state.state])
12420 next_timeout,timeout_func = expirations.next()
12425 if next_timeout is not None:
12426 if next_timeout <= t:
12427 self.run_condition(timeout_func, *state_output)
12428 next_timeout,timeout_func = expirations.next()
12429 if next_timeout is None:
12432 remain = next_timeout-t
12434 r,_,_ = select([l],[],[],remain)
12437 if pkt is not None:
12438 if self.master_filter(pkt):
12439 self.debug(3, "RECVD: %s" % pkt.summary())
12440 for rcvcond in self.recv_conditions[self.state.state]:
12441 self.run_condition(rcvcond, pkt, *state_output)
12443 self.debug(4, "FILTR: %s" % pkt.summary())
12445 except ATMT.NewStateRequested,state_req:
12446 self.debug(2, "switching from [%s] to [%s]" % (self.state.state,state_req.state))
12447 self.state = state_req
12448 except KeyboardInterrupt:
12449 self.debug(1,"Interrupted by user")
12452 def my_send(self, pkt):
12453 self.send_sock.send(pkt)
12455 def send(self, pkt):
12457 self.debug(3,"SENT : %s" % pkt.summary())
12458 self.packets.append(pkt.copy())
12465 class TFTP_read(Automaton):
12466 def parse_args(self, filename, server, sport = None, port=69, **kargs):
12467 Automaton.parse_args(self, **kargs)
12468 self.filename = filename
12469 self.server = server
12474 def master_filter(self, pkt):
12475 return ( IP in pkt and pkt[IP].src == self.server and UDP in pkt
12476 and pkt[UDP].dport == self.my_tid
12477 and (self.server_tid is None or pkt[UDP].sport == self.server_tid) )
12480 @ATMT.state(initial=1)
12483 self.my_tid = self.sport or RandShort()._fix()
12484 bind_bottom_up(UDP, TFTP, dport=self.my_tid)
12485 self.server_tid = None
12488 self.l3 = IP(dst=self.server)/UDP(sport=self.my_tid, dport=self.port)/TFTP()
12489 self.last_packet = self.l3/TFTP_RRQ(filename=self.filename, mode="octet")
12490 self.send(self.last_packet)
12493 raise self.WAITING()
12501 @ATMT.receive_condition(WAITING)
12502 def receive_data(self, pkt):
12503 if TFTP_DATA in pkt and pkt[TFTP_DATA].block == self.awaiting:
12504 if self.server_tid is None:
12505 self.server_tid = pkt[UDP].sport
12506 self.l3[UDP].dport = self.server_tid
12507 raise self.RECEIVING(pkt)
12509 @ATMT.receive_condition(WAITING, prio=1)
12510 def receive_error(self, pkt):
12511 if TFTP_ERROR in pkt:
12512 raise self.ERROR(pkt)
12515 @ATMT.timeout(WAITING, 3)
12516 def timeout_waiting(self):
12517 raise self.WAITING()
12518 @ATMT.action(timeout_waiting)
12519 def retransmit_last_packet(self):
12520 self.send(self.last_packet)
12522 @ATMT.action(receive_data)
12523 # @ATMT.action(receive_error)
12524 def send_ack(self):
12525 self.last_packet = self.l3 / TFTP_ACK(block = self.awaiting)
12526 self.send(self.last_packet)
12531 def RECEIVING(self, pkt):
12533 recvd = pkt[Raw].load
12538 if len(recvd) == self.blocksize:
12539 raise self.WAITING()
12543 @ATMT.state(error=1)
12544 def ERROR(self,pkt):
12545 split_bottom_up(UDP, TFTP, dport=self.my_tid)
12546 return pkt[TFTP_ERROR].summary()
12549 @ATMT.state(final=1)
12551 split_bottom_up(UDP, TFTP, dport=self.my_tid)
12557 class TFTP_write(Automaton):
12558 def parse_args(self, filename, data, server, sport=None, port=69,**kargs):
12559 Automaton.parse_args(self, **kargs)
12560 self.filename = filename
12561 self.server = server
12564 self.blocksize = 512
12565 self.origdata = data
12567 def master_filter(self, pkt):
12568 return ( IP in pkt and pkt[IP].src == self.server and UDP in pkt
12569 and pkt[UDP].dport == self.my_tid
12570 and (self.server_tid is None or pkt[UDP].sport == self.server_tid) )
12574 @ATMT.state(initial=1)
12576 self.data = [ self.origdata[i*self.blocksize:(i+1)*self.blocksize]
12577 for i in range( len(self.origdata)/self.blocksize+1) ]
12578 self.my_tid = self.sport or RandShort()._fix()
12579 bind_bottom_up(UDP, TFTP, dport=self.my_tid)
12580 self.server_tid = None
12582 self.l3 = IP(dst=self.server)/UDP(sport=self.my_tid, dport=self.port)/TFTP()
12583 self.last_packet = self.l3/TFTP_WRQ(filename=self.filename, mode="octet")
12584 self.send(self.last_packet)
12588 raise self.WAITING_ACK()
12592 def WAITING_ACK(self):
12595 @ATMT.receive_condition(WAITING_ACK)
12596 def received_ack(self,pkt):
12597 if TFTP_ACK in pkt and pkt[TFTP_ACK].block == self.awaiting:
12598 if self.server_tid is None:
12599 self.server_tid = pkt[UDP].sport
12600 self.l3[UDP].dport = self.server_tid
12601 raise self.SEND_DATA()
12603 @ATMT.receive_condition(WAITING_ACK)
12604 def received_error(self, pkt):
12605 if TFTP_ERROR in pkt:
12606 raise self.ERROR(pkt)
12608 @ATMT.timeout(WAITING_ACK, 3)
12609 def timeout_waiting(self):
12610 raise self.WAITING_ACK()
12611 @ATMT.action(timeout_waiting)
12612 def retransmit_last_packet(self):
12613 self.send(self.last_packet)
12617 def SEND_DATA(self):
12619 self.last_packet = self.l3/TFTP_DATA(block=self.awaiting)/self.data.pop(0)
12620 self.send(self.last_packet)
12622 raise self.WAITING_ACK()
12627 @ATMT.state(error=1)
12628 def ERROR(self,pkt):
12629 split_bottom_up(UDP, TFTP, dport=self.my_tid)
12630 return pkt[TFTP_ERROR].summary()
12633 @ATMT.state(final=1)
12635 split_bottom_up(UDP, TFTP, dport=self.my_tid)
12638 class TFTP_WRQ_server(Automaton):
12640 def parse_args(self, ip=None, sport=None, *args, **kargs):
12641 Automaton.parse_args(self, *args, **kargs)
12645 def master_filter(self, pkt):
12646 return TFTP in pkt and (not self.ip or pkt[IP].dst == self.ip)
12648 @ATMT.state(initial=1)
12653 self.my_tid = self.sport or random.randint(10000,65500)
12654 bind_bottom_up(UDP, TFTP, dport=self.my_tid)
12656 @ATMT.receive_condition(BEGIN)
12657 def receive_WRQ(self,pkt):
12658 if TFTP_WRQ in pkt:
12659 raise self.WAIT_DATA().action_parameters(pkt)
12661 @ATMT.action(receive_WRQ)
12662 def ack_WRQ(self, pkt):
12666 self.filename = pkt[TFTP_WRQ].filename
12667 options = pkt[TFTP_Options]
12668 self.l3 = IP(src=ip.dst, dst=ip.src)/UDP(sport=self.my_tid, dport=pkt.sport)/TFTP()
12669 if options is None:
12670 self.last_packet = self.l3/TFTP_ACK(block=0)
12671 self.send(self.last_packet)
12673 opt = [x for x in options.options if x.oname.upper() == "BLKSIZE"]
12675 self.blksize = int(opt[0].value)
12676 self.debug(2,"Negotiated new blksize at %i" % self.blksize)
12677 self.last_packet = self.l3/TFTP_OACK()/TFTP_Options(options=opt)
12678 self.send(self.last_packet)
12681 def WAIT_DATA(self):
12684 @ATMT.timeout(WAIT_DATA, 1)
12685 def resend_ack(self):
12686 self.send(self.last_packet)
12687 raise self.WAIT_DATA()
12689 @ATMT.receive_condition(WAIT_DATA)
12690 def receive_data(self, pkt):
12691 if TFTP_DATA in pkt:
12692 data = pkt[TFTP_DATA]
12693 if data.block == self.blk:
12694 raise self.DATA(data)
12696 @ATMT.action(receive_data)
12697 def ack_data(self):
12698 self.last_packet = self.l3/TFTP_ACK(block = self.blk)
12699 self.send(self.last_packet)
12702 def DATA(self, data):
12703 self.filedata += data.load
12704 if len(data.load) < self.blksize:
12707 raise self.WAIT_DATA()
12709 @ATMT.state(final=1)
12711 return self.filename,self.filedata
12712 split_bottom_up(UDP, TFTP, dport=self.my_tid)
12715 class TFTP_RRQ_server(Automaton):
12716 def parse_args(self, store=None, joker=None, dir=None, ip=None, sport=None, serve_one=False, **kargs):
12717 Automaton.parse_args(self,**kargs)
12720 if dir is not None:
12721 self.dir = os.path.join(os.path.abspath(dir),"")
12728 self.serve_one = serve_one
12729 self.my_tid = self.sport or random.randint(10000,65500)
12730 bind_bottom_up(UDP, TFTP, dport=self.my_tid)
12732 def master_filter(self, pkt):
12733 return TFTP in pkt and (not self.ip or pkt[IP].dst == self.ip)
12735 @ATMT.state(initial=1)
12736 def WAIT_RRQ(self):
12740 @ATMT.receive_condition(WAIT_RRQ)
12741 def receive_rrq(self, pkt):
12742 if TFTP_RRQ in pkt:
12743 raise self.RECEIVED_RRQ(pkt)
12747 def RECEIVED_RRQ(self, pkt):
12749 options = pkt[TFTP_Options]
12750 self.l3 = IP(src=ip.dst, dst=ip.src)/UDP(sport=self.my_tid, dport=ip.sport)/TFTP()
12751 self.filename = pkt[TFTP_RRQ].filename
12754 if self.filename in self.store:
12755 self.data = self.store[self.filename]
12756 elif self.dir is not None:
12757 fn = os.path.abspath(os.path.join(self.dir, self.filename))
12758 if fn.startswith(self.dir): # Check we're still in the server's directory
12760 self.data=open(fn).read()
12763 if self.data is None:
12764 self.data = self.joker
12767 opt = [x for x in options.options if x.oname.upper() == "BLKSIZE"]
12769 self.blksize = int(opt[0].value)
12770 self.debug(2,"Negotiated new blksize at %i" % self.blksize)
12771 self.last_packet = self.l3/TFTP_OACK()/TFTP_Options(options=opt)
12772 self.send(self.last_packet)
12777 @ATMT.condition(RECEIVED_RRQ)
12778 def file_in_store(self):
12779 if self.data is not None:
12780 self.blknb = len(self.data)/self.blksize+1
12781 raise self.SEND_FILE()
12783 @ATMT.condition(RECEIVED_RRQ)
12784 def file_not_found(self):
12785 if self.data is None:
12786 raise self.WAIT_RRQ()
12787 @ATMT.action(file_not_found)
12788 def send_error(self):
12789 self.send(self.l3/TFTP_ERROR(errorcode=1, errormsg=TFTP_Error_Codes[1]))
12792 def SEND_FILE(self):
12793 self.send(self.l3/TFTP_DATA(block=self.blk)/self.data[(self.blk-1)*self.blksize:self.blk*self.blksize])
12795 @ATMT.timeout(SEND_FILE, 3)
12796 def timeout_waiting_ack(self):
12797 raise self.SEND_FILE()
12799 @ATMT.receive_condition(SEND_FILE)
12800 def received_ack(self, pkt):
12801 if TFTP_ACK in pkt and pkt[TFTP_ACK].block == self.blk:
12802 raise self.RECEIVED_ACK()
12804 def RECEIVED_ACK(self):
12807 @ATMT.condition(RECEIVED_ACK)
12808 def no_more_data(self):
12809 if self.blk > self.blknb:
12812 raise self.WAIT_RRQ()
12813 @ATMT.condition(RECEIVED_ACK, prio=2)
12814 def data_remaining(self):
12815 raise self.SEND_FILE()
12817 @ATMT.state(final=1)
12819 split_bottom_up(UDP, TFTP, dport=self.my_tid)
12824 ########################
12825 ## Answering machines ##
12826 ########################
12828 class ReferenceAM(type):
12829 def __new__(cls, name, bases, dct):
12830 o = super(ReferenceAM, cls).__new__(cls, name, bases, dct)
12831 if o.function_name:
12832 globals()[o.function_name] = lambda o=o,*args,**kargs: o(*args,**kargs)()
12836 class AnsweringMachine(object):
12837 __metaclass__ = ReferenceAM
12840 sniff_options = { "store":0 }