diff --git a/scapy.py b/scapy.py
index c9658e9eb4c3ef44ac335e8fd7c2249925a6742d..4eefb57eff0f7472ff82c98eb32e4371e7637bf7 100755
--- a/scapy.py
+++ b/scapy.py
@@ -1,14185 +1,5 @@
 #! /usr/bin/env python
 
-#############################################################################
-##                                                                         ##
-## scapy.py --- Interactive packet manipulation tool                       ##
-##              see http://www.secdev.org/projects/scapy/                  ##
-##              for more informations                                      ##
-##                                                                         ##
-## Copyright (C) 2003  Philippe Biondi <phil@secdev.org>                   ##
-##                                                                         ##
-## This program is free software; you can redistribute it and/or modify it ##
-## under the terms of the GNU General Public License version 2 as          ##
-## published by the Free Software Foundation; version 2.                   ##
-##                                                                         ##
-## This program is distributed in the hope that it will be useful, but     ##
-## WITHOUT ANY WARRANTY; without even the implied warranty of              ##
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU       ##
-## General Public License for more details.                                ##
-##                                                                         ##
-#############################################################################
+from scapy.main import interact
 
-
-from __future__ import generators
-import os
-
-VERSION = "1.2.0.2"
-
-DEFAULT_CONFIG_FILE = os.path.join(os.environ["HOME"], ".scapy_startup.py")
-
-try:
-    os.stat(DEFAULT_CONFIG_FILE)
-except OSError:
-    DEFAULT_CONFIG_FILE = None
-
-def usage():
-    print """Usage: scapy.py [-s sessionfile] [-c new_startup_file] [-C]
-    -C: do not read startup file"""
-    sys.exit(0)
-
-
-#############################
-##### Logging subsystem #####
-#############################
-
-class Scapy_Exception(Exception):
-    pass
-
-import logging,traceback,time
-
-class ScapyFreqFilter(logging.Filter):
-    def __init__(self):
-        logging.Filter.__init__(self)
-        self.warning_table = {}
-    def filter(self, record):        
-        wt = conf.warning_threshold
-        if wt > 0:
-            stk = traceback.extract_stack()
-            caller=None
-            for f,l,n,c in stk:
-                if n == 'warning':
-                    break
-                caller = l
-            tm,nb = self.warning_table.get(caller, (0,0))
-            ltm = time.time()
-            if ltm-tm > wt:
-                tm = ltm
-                nb = 0
-            else:
-                if nb < 2:
-                    nb += 1
-                    if nb == 2:
-                        record.msg = "more "+record.msg
-                else:
-                    return 0
-            self.warning_table[caller] = (tm,nb)
-        return 1    
-
-log_scapy = logging.getLogger("scapy")
-console_handler = logging.StreamHandler()
-console_handler.setFormatter(logging.Formatter("%(levelname)s: %(message)s"))
-log_scapy.addHandler(console_handler)
-log_runtime = logging.getLogger("scapy.runtime")          # logs at runtime
-log_runtime.addFilter(ScapyFreqFilter())
-log_interactive = logging.getLogger("scapy.interactive")  # logs in interactive functions
-log_loading = logging.getLogger("scapy.loading")          # logs when loading scapy
-
-if __name__ == "__main__":
-    log_scapy.setLevel(1)
-
-
-##################
-##### Module #####
-##################
-
-import socket, sys, getopt, string, struct, random, code
-import cPickle, copy, types, gzip, base64, re, zlib, array
-from sets import Set
-from select import select
-from glob import glob
-from fcntl import ioctl
-import itertools
-import fcntl
-import warnings
-warnings.filterwarnings("ignore","tempnam",RuntimeWarning, __name__)
-
-
-try:
-    import Gnuplot
-    GNUPLOT=1
-except ImportError:
-    log_loading.info("did not find python gnuplot wrapper . Won't be able to plot")
-    GNUPLOT=0
-
-try:
-    import pyx
-    PYX=1
-except ImportError:
-    log_loading.info("Can't import PyX. Won't be able to use psdump() or pdfdump()")
-    PYX=0
-
-
-LINUX=sys.platform.startswith("linux")
-OPENBSD=sys.platform.startswith("openbsd")
-FREEBSD=sys.platform.startswith("freebsd")
-DARWIN=sys.platform.startswith("darwin")
-BIG_ENDIAN= struct.pack("H",1) == "\x00\x01"
-X86_64 = (os.uname()[4] == 'x86_64')
-SOLARIS=sys.platform.startswith("sunos")
-
-
-if LINUX:
-    DNET=PCAP=0
-else:
-    DNET=PCAP=1
-    
-
-if PCAP:
-    try:
-        import pcap
-        PCAP = 1
-    except ImportError:
-        if LINUX:
-            log_loading.warning("did not find pcap module. Fallback to linux primitives")
-            PCAP = 0
-        else:
-            if __name__ == "__main__":
-                log_loading.error("did not find pcap module")
-                raise SystemExit
-            else:
-                raise
-
-if DNET:
-    try:
-        import dnet
-        DNET = 1
-    except ImportError:
-        if LINUX:
-            log_loading.warning("did not find dnet module. Fallback to linux primitives")
-            DNET = 0
-        else:
-            if __name__ == "__main__":
-                log_loading.error("did not find dnet module")
-                raise SystemExit
-            else:
-                raise
-
-if not PCAP:
-    f = os.popen("tcpdump -V 2> /dev/null")
-    if f.close() >> 8 == 0x7f:
-        log_loading.warning("Failed to execute tcpdump. Check it is installed and in the PATH")
-        TCPDUMP=0
-    else:
-        TCPDUMP=1
-    del(f)
-        
-    
-
-try:
-    from Crypto.Cipher import ARC4
-except ImportError:
-    log_loading.info("Can't find Crypto python lib. Won't be able to decrypt WEP")
-
-
-# Workarround bug 643005 : https://sourceforge.net/tracker/?func=detail&atid=105470&aid=643005&group_id=5470
-try:
-    socket.inet_aton("255.255.255.255")
-except socket.error:
-    def inet_aton(x):
-        if x == "255.255.255.255":
-            return "\xff"*4
-        else:
-            return socket.inet_aton(x)
-else:
-    inet_aton = socket.inet_aton
-
-inet_ntoa = socket.inet_ntoa
-try:
-    inet_ntop = socket.inet_ntop
-    inet_pton = socket.inet_pton
-except AttributeError:
-    log_loading.info("inet_ntop/pton functions not found. Python IPv6 support not present")
-
-
-if SOLARIS:
-    # GRE is missing on Solaris
-    socket.IPPROTO_GRE = 47
-
-###############################
-## Direct Access dictionnary ##
-###############################
-
-def fixname(x):
-    if x and x[0] in "0123456789":
-        x = "n_"+x
-    return x.translate("________________________________________________0123456789_______ABCDEFGHIJKLMNOPQRSTUVWXYZ______abcdefghijklmnopqrstuvwxyz_____________________________________________________________________________________________________________________________________")
-
-
-class DADict_Exception(Scapy_Exception):
-    pass
-
-class DADict:
-    def __init__(self, _name="DADict", **kargs):
-        self._name=_name
-        self.__dict__.update(kargs)
-    def fixname(self,val):
-        return fixname(val)
-    def __contains__(self, val):
-        return val in self.__dict__
-    def __getitem__(self, attr):
-        return getattr(self, attr)
-    def __setitem__(self, attr, val):        
-        return setattr(self, self.fixname(attr), val)
-    def __iter__(self):
-        return iter(map(lambda (x,y):y,filter(lambda (x,y):x and x[0]!="_", self.__dict__.items())))
-    def _show(self):
-        for k in self.__dict__.keys():
-            if k and k[0] != "_":
-                print "%10s = %r" % (k,getattr(self,k))
-    def __repr__(self):
-        return "<%s/ %s>" % (self._name," ".join(filter(lambda x:x and x[0]!="_",self.__dict__.keys())))
-
-    def _branch(self, br, uniq=0):
-        if uniq and br._name in self:
-            raise DADict_Exception("DADict: [%s] already branched in [%s]" % (br._name, self._name))
-        self[br._name] = br
-
-    def _my_find(self, *args, **kargs):
-        if args and self._name not in args:
-            return False
-        for k in kargs:
-            if k not in self or self[k] != kargs[k]:
-                return False
-        return True
-    
-    def _find(self, *args, **kargs):
-         return self._recurs_find((), *args, **kargs)
-    def _recurs_find(self, path, *args, **kargs):
-        if self in path:
-            return None
-        if self._my_find(*args, **kargs):
-            return self
-        for o in self:
-            if isinstance(o, DADict):
-                p = o._recurs_find(path+(self,), *args, **kargs)
-                if p is not None:
-                    return p
-        return None
-    def _find_all(self, *args, **kargs):
-        return self._recurs_find_all((), *args, **kargs)
-    def _recurs_find_all(self, path, *args, **kargs):
-        r = []
-        if self in path:
-            return r
-        if self._my_find(*args, **kargs):
-            r.append(self)
-        for o in self:
-            if isinstance(o, DADict):
-                p = o._recurs_find_all(path+(self,), *args, **kargs)
-                r += p
-        return r
-    def keys(self):
-        return filter(lambda x:x and x[0]!="_", self.__dict__.keys())
-        
-
-
-############
-## Consts ##
-############
-
-ETHER_ANY = "\x00"*6
-ETHER_BROADCAST = "\xff"*6
-
-ETH_P_ALL = 3
-ETH_P_IP = 0x800
-ETH_P_ARP = 0x806
-
-# From net/if_arp.h
-ARPHDR_ETHER = 1
-ARPHDR_METRICOM = 23
-ARPHDR_PPP = 512
-ARPHDR_LOOPBACK = 772
-ARPHDR_TUN = 65534
-
-# From bits/ioctls.h
-SIOCGIFHWADDR  = 0x8927          # Get hardware address    
-SIOCGIFADDR    = 0x8915          # get PA address          
-SIOCGIFNETMASK = 0x891b          # get network PA mask     
-SIOCGIFNAME    = 0x8910          # get iface name          
-SIOCSIFLINK    = 0x8911          # set iface channel       
-SIOCGIFCONF    = 0x8912          # get iface list          
-SIOCGIFFLAGS   = 0x8913          # get flags               
-SIOCSIFFLAGS   = 0x8914          # set flags               
-SIOCGIFINDEX   = 0x8933          # name -> if_index mapping
-SIOCGIFCOUNT   = 0x8938          # get number of devices
-SIOCGSTAMP     = 0x8906          # get packet timestamp (as a timeval)
-
-
-# From if.h
-IFF_UP = 0x1               # Interface is up.
-IFF_BROADCAST = 0x2        # Broadcast address valid.
-IFF_DEBUG = 0x4            # Turn on debugging.
-IFF_LOOPBACK = 0x8         # Is a loopback net.
-IFF_POINTOPOINT = 0x10     # Interface is point-to-point link.
-IFF_NOTRAILERS = 0x20      # Avoid use of trailers.
-IFF_RUNNING = 0x40         # Resources allocated.
-IFF_NOARP = 0x80           # No address resolution protocol.
-IFF_PROMISC = 0x100        # Receive all packets.
-
-
-
-# From netpacket/packet.h
-PACKET_ADD_MEMBERSHIP  = 1
-PACKET_DROP_MEMBERSHIP = 2
-PACKET_RECV_OUTPUT     = 3
-PACKET_RX_RING         = 5
-PACKET_STATISTICS      = 6
-PACKET_MR_MULTICAST    = 0
-PACKET_MR_PROMISC      = 1
-PACKET_MR_ALLMULTI     = 2
-
-
-# From bits/socket.h
-SOL_PACKET = 263
-# From asm/socket.h
-SO_ATTACH_FILTER = 26
-SOL_SOCKET = 1
-
-# From net/route.h
-RTF_UP = 0x0001  # Route usable
-RTF_REJECT = 0x0200
-
-# From BSD net/bpf.h
-#BIOCIMMEDIATE=0x80044270
-BIOCIMMEDIATE=-2147204496
-
-MTU = 1600
-
- 
-# file parsing to get some values :
-
-def load_protocols(filename):
-    spaces = re.compile("[ \t]+|\n")
-    dct = DADict(_name=filename)
-    try:
-        for l in open(filename):
-            try:
-                shrp = l.find("#")
-                if  shrp >= 0:
-                    l = l[:shrp]
-                l = l.strip()
-                if not l:
-                    continue
-                lt = tuple(re.split(spaces, l))
-                if len(lt) < 2 or not lt[0]:
-                    continue
-                dct[lt[0]] = int(lt[1])
-            except Exception,e:
-                log_loading.info("Couldn't parse file [%s]: line [%r] (%s)" % (filename,l,e))
-    except IOError:
-        log_loading.info("Can't open /etc/protocols file")
-    return dct
-
-IP_PROTOS=load_protocols("/etc/protocols")
-
-def load_ethertypes(filename):
-    spaces = re.compile("[ \t]+|\n")
-    dct = DADict(_name=filename)
-    try:
-        f=open(filename)
-        for l in f:
-            try:
-                shrp = l.find("#")
-                if  shrp >= 0:
-                    l = l[:shrp]
-                l = l.strip()
-                if not l:
-                    continue
-                lt = tuple(re.split(spaces, l))
-                if len(lt) < 2 or not lt[0]:
-                    continue
-                dct[lt[0]] = int(lt[1], 16)
-            except Exception,e:
-                log_loading.info("Couldn't parse file [%s]: line [%r] (%s)" % (filename,l,e))
-        f.close()
-    except IOError,msg:
-        pass
-    return dct
-
-ETHER_TYPES=load_ethertypes("/etc/ethertypes")
-
-def load_services(filename):
-    spaces = re.compile("[ \t]+|\n")
-    tdct=DADict(_name="%s-tcp"%filename)
-    udct=DADict(_name="%s-udp"%filename)
-    try:
-        f=open(filename)
-        for l in f:
-            try:
-                shrp = l.find("#")
-                if  shrp >= 0:
-                    l = l[:shrp]
-                l = l.strip()
-                if not l:
-                    continue
-                lt = tuple(re.split(spaces, l))
-                if len(lt) < 2 or not lt[0]:
-                    continue
-                if lt[1].endswith("/tcp"):
-                    tdct[lt[0]] = int(lt[1].split('/')[0])
-                elif lt[1].endswith("/udp"):
-                    udct[lt[0]] = int(lt[1].split('/')[0])
-            except Exception,e:
-                log_loading.warning("Couldn't file [%s]: line [%r] (%s)" % (filename,l,e))
-        f.close()
-    except IOError:
-        log_loading.info("Can't open /etc/services file")
-    return tdct,udct
-
-TCP_SERVICES,UDP_SERVICES=load_services("/etc/services")
-
-class ManufDA(DADict):
-    def fixname(self, val):
-        return val
-    def _get_manuf_couple(self, mac):
-        oui = ":".join(mac.split(":")[:3]).upper()
-        return self.__dict__.get(oui,(mac,mac))
-    def _get_manuf(self, mac):
-        return self._get_manuf_couple(mac)[1]
-    def _get_short_manuf(self, mac):
-        return self._get_manuf_couple(mac)[0]
-    def _resolve_MAC(self, mac):
-        oui = ":".join(mac.split(":")[:3]).upper()
-        if oui in self:
-            return ":".join([self[oui][0]]+ mac.split(":")[3:])
-        return mac
-        
-        
-        
-
-def load_manuf(filename):
-    try:
-        manufdb=ManufDA(_name=filename)
-        for l in open(filename):
-            try:
-                l = l.strip()
-                if not l or l.startswith("#"):
-                    continue
-                oui,shrt=l.split()[:2]
-                i = l.find("#")
-                if i < 0:
-                    lng=shrt
-                else:
-                    lng = l[i+2:]
-                manufdb[oui] = shrt,lng
-            except Exception,e:
-                log_loading.warning("Couldn't parse one line from [%s] [%r] (%s)" % (filename, l, e))
-    except IOError:
-        #log_loading.warning("Couldn't open [%s] file" % filename)
-        pass
-    return manufdb
-    
-MANUFDB = load_manuf("/usr/share/wireshark/wireshark/manuf")
-
-
-
-
-###########
-## Tools ##
-###########
-
-def sane_color(x):
-    r=""
-    for i in x:
-        j = ord(i)
-        if (j < 32) or (j >= 127):
-            r=r+conf.color_theme.not_printable(".")
-        else:
-            r=r+i
-    return r
-
-def sane(x):
-    r=""
-    for i in x:
-        j = ord(i)
-        if (j < 32) or (j >= 127):
-            r=r+"."
-        else:
-            r=r+i
-    return r
-
-def lhex(x):
-    if type(x) in (int,long):
-        return hex(x)
-    elif type(x) is tuple:
-        return "(%s)" % ", ".join(map(lhex, x))
-    elif type(x) is list:
-        return "[%s]" % ", ".join(map(lhex, x))
-    else:
-        return x
-
-def hexdump(x):
-    x=str(x)
-    l = len(x)
-    i = 0
-    while i < l:
-        print "%04x  " % i,
-        for j in range(16):
-            if i+j < l:
-                print "%02X" % ord(x[i+j]),
-            else:
-                print "  ",
-            if j%16 == 7:
-                print "",
-        print " ",
-        print sane_color(x[i:i+16])
-        i += 16
-
-def linehexdump(x, onlyasc=0, onlyhex=0):
-    x = str(x)
-    l = len(x)
-    if not onlyasc:
-        for i in range(l):
-            print "%02X" % ord(x[i]),
-        print "",
-    if not onlyhex:
-        print sane_color(x)
-
-def chexdump(x):
-    x=str(x)
-    print ", ".join(map(lambda x: "%#04x"%ord(x), x))
-    
-def hexstr(x, onlyasc=0, onlyhex=0):
-    s = []
-    if not onlyasc:
-        s.append(" ".join(map(lambda x:"%02x"%ord(x), x)))
-    if not onlyhex:
-        s.append(sane(x)) 
-    return "  ".join(s)
-
-
-def hexdiff(x,y):
-    x=str(x)[::-1]
-    y=str(y)[::-1]
-    SUBST=1
-    INSERT=1
-    d={}
-    d[-1,-1] = 0,(-1,-1)
-    for j in range(len(y)):
-        d[-1,j] = d[-1,j-1][0]+INSERT, (-1,j-1)
-    for i in range(len(x)):
-        d[i,-1] = d[i-1,-1][0]+INSERT, (i-1,-1)
-
-    for j in range(len(y)):
-        for i in range(len(x)):
-            d[i,j] = min( ( d[i-1,j-1][0]+SUBST*(x[i] != y[j]), (i-1,j-1) ),
-                          ( d[i-1,j][0]+INSERT, (i-1,j) ),
-                          ( d[i,j-1][0]+INSERT, (i,j-1) ) )
-                          
-
-    backtrackx = []
-    backtracky = []
-    i=len(x)-1
-    j=len(y)-1
-    while not (i == j == -1):
-        i2,j2 = d[i,j][1]
-        backtrackx.append(x[i2+1:i+1])
-        backtracky.append(y[j2+1:j+1])
-        i,j = i2,j2
-
-        
-
-    x = y = i = 0
-    colorize = { 0: lambda x:x,
-                -1: conf.color_theme.left,
-                 1: conf.color_theme.right }
-    
-    dox=1
-    doy=0
-    l = len(backtrackx)
-    while i < l:
-        separate=0
-        linex = backtrackx[i:i+16]
-        liney = backtracky[i:i+16]
-        xx = sum(len(k) for k in linex)
-        yy = sum(len(k) for k in liney)
-        if dox and not xx:
-            dox = 0
-            doy = 1
-        if dox and linex == liney:
-            doy=1
-            
-        if dox:
-            xd = y
-            j = 0
-            while not linex[j]:
-                j += 1
-                xd -= 1
-            print colorize[doy-dox]("%04x" % xd),
-            x += xx
-            line=linex
-        else:
-            print "    ",
-        if doy:
-            yd = y
-            j = 0
-            while not liney[j]:
-                j += 1
-                yd -= 1
-            print colorize[doy-dox]("%04x" % yd),
-            y += yy
-            line=liney
-        else:
-            print "    ",
-            
-        print " ",
-        
-        cl = ""
-        for j in range(16):
-            if i+j < l:
-                if line[j]:
-                    col = colorize[(linex[j]!=liney[j])*(doy-dox)]
-                    print col("%02X" % ord(line[j])),
-                    if linex[j]==liney[j]:
-                        cl += sane_color(line[j])
-                    else:
-                        cl += col(sane(line[j]))
-                else:
-                    print "  ",
-                    cl += " "
-            else:
-                print "  ",
-            if j == 7:
-                print "",
-
-
-        print " ",cl
-
-        if doy or not yy:
-            doy=0
-            dox=1
-            i += 16
-        else:
-            if yy:
-                dox=0
-                doy=1
-            else:
-                i += 16
-
-    
-crc32 = zlib.crc32
-
-if BIG_ENDIAN:
-    def checksum(pkt):
-        if len(pkt) % 2 == 1:
-            pkt += "\0"
-        s = sum(array.array("H", pkt))
-        s = (s >> 16) + (s & 0xffff)
-        s += s >> 16
-        s = ~s
-        return s & 0xffff
-else:
-    def checksum(pkt):
-        if len(pkt) % 2 == 1:
-            pkt += "\0"
-        s = sum(array.array("H", pkt))
-        s = (s >> 16) + (s & 0xffff)
-        s += s >> 16
-        s = ~s
-        return (((s>>8)&0xff)|s<<8) & 0xffff
-
-def warning(x):
-    log_runtime.warning(x)
-
-def mac2str(mac):
-    return "".join(map(lambda x: chr(int(x,16)), mac.split(":")))
-
-def str2mac(s):
-    return ("%02x:"*6)[:-1] % tuple(map(ord, s)) 
-
-def strxor(x,y):
-    return "".join(map(lambda x,y:chr(ord(x)^ord(y)),x,y))
-
-def atol(x):
-    try:
-        ip = inet_aton(x)
-    except socket.error:
-        ip = inet_aton(socket.gethostbyname(x))
-    return struct.unpack("!I", ip)[0]
-def ltoa(x):
-    return inet_ntoa(struct.pack("!I", x))
-
-def itom(x):
-    return (0xffffffff00000000L>>x)&0xffffffffL
-
-def do_graph(graph,prog=None,format="svg",target=None, type=None,string=None,options=None):
-    """do_graph(graph, prog=conf.prog.dot, format="svg",
-         target="| conf.prog.display", options=None, [string=1]):
-    string: if not None, simply return the graph string
-    graph: GraphViz graph description
-    format: output type (svg, ps, gif, jpg, etc.), passed to dot's "-T" option
-    target: filename or redirect. Defaults pipe to Imagemagick's display program
-    prog: which graphviz program to use
-    options: options to be passed to prog"""
-        
-
-    if string:
-        return graph
-    if type is not None:
-        format=type
-    if prog is None:
-        prog = conf.prog.dot
-    if target is None:
-        target = "| %s" % conf.prog.display
-    if format is not None:
-        format = "-T %s" % format
-    w,r = os.popen2("%s %s %s %s" % (prog,options or "", format or "", target))
-    w.write(graph)
-    w.close()
-
-_TEX_TR = {
-    "{":"{\\tt\\char123}",
-    "}":"{\\tt\\char125}",
-    "\\":"{\\tt\\char92}",
-    "^":"\\^{}",
-    "$":"\\$",
-    "#":"\\#",
-    "~":"\\~",
-    "_":"\\_",
-    "&":"\\&",
-    "%":"\\%",
-    "|":"{\\tt\\char124}",
-    "~":"{\\tt\\char126}",
-    "<":"{\\tt\\char60}",
-    ">":"{\\tt\\char62}",
-    }
-    
-def tex_escape(x):
-    s = ""
-    for c in x:
-        s += _TEX_TR.get(c,c)
-    return s
-
-def colgen(*lstcol,**kargs):
-    """Returns a generator that mixes provided quantities forever
-    trans: a function to convert the three arguments into a color. lambda x,y,z:(x,y,z) by default"""
-    if len(lstcol) < 2:
-        lstcol *= 2
-    trans = kargs.get("trans", lambda x,y,z: (x,y,z))
-    while 1:
-        for i in range(len(lstcol)):
-            for j in range(len(lstcol)):
-                for k in range(len(lstcol)):
-                    if i != j or j != k or k != i:
-                        yield trans(lstcol[(i+j)%len(lstcol)],lstcol[(j+k)%len(lstcol)],lstcol[(k+i)%len(lstcol)])
-
-def incremental_label(label="tag%05i", start=0):
-    while True:
-        yield label % start
-        start += 1
-
-#########################
-#### Enum management ####
-#########################
-
-class EnumElement:
-    _value=None
-    def __init__(self, key, value):
-        self._key = key
-        self._value = value
-    def __repr__(self):
-        return "<%s %s[%r]>" % (self.__dict__.get("_name", self.__class__.__name__), self._key, self._value)
-    def __getattr__(self, attr):
-        return getattr(self._value, attr)
-    def __str__(self):
-        return self._key
-    def __eq__(self, other):
-        return self._value == int(other)
-
-
-class Enum_metaclass(type):
-    element_class = EnumElement
-    def __new__(cls, name, bases, dct):
-        rdict={}
-        for k,v in dct.iteritems():
-            if type(v) is int:
-                v = cls.element_class(k,v)
-                dct[k] = v
-                rdict[v] = k
-        dct["__rdict__"] = rdict
-        return super(Enum_metaclass, cls).__new__(cls, name, bases, dct)
-    def __getitem__(self, attr):
-        return self.__rdict__[attr]
-    def __contains__(self, val):
-        return val in self.__rdict__
-    def get(self, attr, val=None):
-        return self._rdict__.get(attr, val)
-    def __repr__(self):
-        return "<%s>" % self.__dict__.get("name", self.__name__)
-
-
-
-
-##############################
-## Session saving/restoring ##
-##############################
-
-
-def save_session(fname, session=None, pickleProto=-1):
-    if session is None:
-        session = scapy_session
-
-    to_be_saved = session.copy()
-        
-    if to_be_saved.has_key("__builtins__"):
-        del(to_be_saved["__builtins__"])
-
-    for k in to_be_saved.keys():
-        if type(to_be_saved[k]) in [types.TypeType, types.ClassType, types.ModuleType]:
-             log_interactive.error("[%s] (%s) can't be saved." % (k, type(to_be_saved[k])))
-             del(to_be_saved[k])
-
-    try:
-        os.rename(fname, fname+".bak")
-    except OSError:
-        pass
-    f=gzip.open(fname,"wb")
-    cPickle.dump(to_be_saved, f, pickleProto)
-    f.close()
-
-def load_session(fname):
-    try:
-        s = cPickle.load(gzip.open(fname,"rb"))
-    except IOError:
-        s = cPickle.load(open(fname,"rb"))
-    scapy_session.clear()
-    scapy_session.update(s)
-
-def update_session(fname):
-    try:
-        s = cPickle.load(gzip.open(fname,"rb"))
-    except IOError:
-        s = cPickle.load(open(fname,"rb"))
-    scapy_session.update(s)
-
-
-def export_object(obj):
-    print base64.encodestring(gzip.zlib.compress(cPickle.dumps(obj,2),9))
-
-def import_object(obj=None):
-    if obj is None:
-        obj = sys.stdin.read()
-    return cPickle.loads(gzip.zlib.decompress(base64.decodestring(obj.strip())))
-
-
-def save_object(fname, obj):
-    cPickle.dump(obj,gzip.open(fname,"wb"))
-
-def load_object(fname):
-    return cPickle.load(gzip.open(fname,"rb"))
-
-
-######################
-## Extension system ##
-######################
-
-
-def load_extension(filename):
-    import imp
-    paths = conf.extensions_paths
-    if type(paths) is not list:
-        paths = [paths]
-
-    name = os.path.realpath(os.path.expanduser(filename))
-    thepath = os.path.dirname(name)
-    thename = os.path.basename(name)
-    if thename.endswith(".py"):
-        thename = thename[:-3]
-
-    paths.insert(0, thepath)
-    cwd=syspath=None
-    try:
-        cwd = os.getcwd()
-        os.chdir(thepath)
-        syspath = sys.path[:]
-        sys.path += paths
-        try:
-            extf = imp.find_module(thename, paths)
-        except ImportError:
-            log_runtime.error("Module [%s] not found. Check conf.extensions_paths ?" % filename)
-        else:
-            ext = imp.load_module(thename, *extf)
-            import __builtin__
-            __builtin__.__dict__.update(ext.__dict__)
-    finally:
-        if syspath:
-            sys.path=syspath
-        if cwd:
-            os.chdir(cwd)
-    
-
-
-#################
-## Debug class ##
-#################
-
-class debug:
-    recv=[]
-    sent=[]
-    match=[]
-
-
-####################
-## IP Tools class ##
-####################
-
-class IPTools:
-    """Add more powers to a class that have a "src" attribute."""
-    def whois(self):
-        os.system("whois %s" % self.src)
-    def ottl(self):
-        t = [32,64,128,255]+[self.ttl]
-        t.sort()
-        return t[t.index(self.ttl)+1]
-    def hops(self):
-        return self.ottl()-self.ttl-1 
-
-
-##############################
-## Routing/Interfaces stuff ##
-##############################
-
-class Route:
-    def __init__(self):
-        self.resync()
-        self.s=socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
-        self.cache = {}
-
-    def invalidate_cache(self):
-        self.cache = {}
-
-    def resync(self):
-        self.invalidate_cache()
-        self.routes = read_routes()
-
-    def __repr__(self):
-        rt = "Network         Netmask         Gateway         Iface           Output IP\n"
-        for net,msk,gw,iface,addr in self.routes:
-            rt += "%-15s %-15s %-15s %-15s %-15s\n" % (ltoa(net),
-                                              ltoa(msk),
-                                              gw,
-                                              iface,
-                                              addr)
-        return rt
-
-    def make_route(self, host=None, net=None, gw=None, dev=None):
-        if host is not None:
-            thenet,msk = host,32
-        elif net is not None:
-            thenet,msk = net.split("/")
-            msk = int(msk)
-        else:
-            raise Scapy_Exception("make_route: Incorrect parameters. You should specify a host or a net")
-        if gw is None:
-            gw="0.0.0.0"
-        if dev is None:
-            if gw:
-                nhop = gw
-            else:
-                nhop = thenet
-            dev,ifaddr,x = self.route(nhop)
-        else:
-            ifaddr = get_if_addr(dev)
-        return (atol(thenet), itom(msk), gw, dev, ifaddr)
-
-    def add(self, *args, **kargs):
-        """Ex:
-        add(net="192.168.1.0/24",gw="1.2.3.4")
-        """
-        self.invalidate_cache()
-        self.routes.append(self.make_route(*args,**kargs))
-
-        
-    def delt(self,  *args, **kargs):
-        """delt(host|net, gw|dev)"""
-        self.invalidate_cache()
-        route = self.make_route(*args,**kargs)
-        try:
-            i=self.routes.index(route)
-            del(self.routes[i])
-        except ValueError:
-            warning("no matching route found")
-             
-    def ifchange(self, iff, addr):
-        self.invalidate_cache()
-        the_addr,the_msk = (addr.split("/")+["32"])[:2]
-        the_msk = itom(int(the_msk))
-        the_rawaddr = atol(the_addr)
-        the_net = the_rawaddr & the_msk
-        
-        
-        for i in range(len(self.routes)):
-            net,msk,gw,iface,addr = self.routes[i]
-            if iface != iff:
-                continue
-            if gw == '0.0.0.0':
-                self.routes[i] = (the_net,the_msk,gw,iface,the_addr)
-            else:
-                self.routes[i] = (net,msk,gw,iface,the_addr)
-        for i in arp_cache.keys():
-            del(arp_cache[i])
-        
-                
-
-    def ifdel(self, iff):
-        self.invalidate_cache()
-        new_routes=[]
-        for rt in self.routes:
-            if rt[3] != iff:
-                new_routes.append(rt)
-        self.routes=new_routes
-        
-    def ifadd(self, iff, addr):
-        self.invalidate_cache()
-        the_addr,the_msk = (addr.split("/")+["32"])[:2]
-        the_msk = itom(int(the_msk))
-        the_rawaddr = atol(the_addr)
-        the_net = the_rawaddr & the_msk
-        self.routes.append((the_net,the_msk,'0.0.0.0',iff,the_addr))
-
-
-    def route(self,dest,verbose=None):
-        if dest in self.cache:
-            return self.cache[dest]
-        if verbose is None:
-            verbose=conf.verb
-        # Transform "192.168.*.1-5" to one IP of the set
-        dst = dest.split("/")[0]
-        dst = dst.replace("*","0") 
-        while 1:
-            l = dst.find("-")
-            if l < 0:
-                break
-            m = (dst[l:]+".").find(".")
-            dst = dst[:l]+dst[l+m:]
-
-            
-        dst = atol(dst)
-        pathes=[]
-        for d,m,gw,i,a in self.routes:
-            aa = atol(a)
-            if aa == dst:
-                pathes.append((0xffffffffL,("lo",a,"0.0.0.0")))
-            if (dst & m) == (d & m):
-                pathes.append((m,(i,a,gw)))
-        if not pathes:
-            if verbose:
-                warning("No route found (no default route?)")
-            return "lo","0.0.0.0","0.0.0.0" #XXX linux specific!
-        # Choose the more specific route (greatest netmask).
-        # XXX: we don't care about metrics
-        pathes.sort()
-        ret = pathes[-1][1]
-        self.cache[dest] = ret
-        return ret
-            
-    def get_if_bcast(self, iff):
-        for net, msk, gw, iface, addr in self.routes:
-            if (iff == iface and net != 0L):
-                bcast = atol(addr)|(~msk&0xffffffffL); # FIXME: check error in atol()
-                return ltoa(bcast);
-        warning("No broadcast address found for iface %s\n" % iff);
-
-if DNET:
-    def get_if_raw_hwaddr(iff):
-        if iff[:2] == "lo":
-            return (772, '\x00'*6)
-        try:
-            l = dnet.intf().get(iff)
-            l = l["link_addr"]
-        except:
-            raise Scapy_Exception("Error in attempting to get hw address for interface [%s]" % iff)
-        return l.type,l.data
-    def get_if_raw_addr(ifname):
-        i = dnet.intf()
-        return i.get(ifname)["addr"].data
-else:
-    def get_if_raw_hwaddr(iff):
-        return struct.unpack("16xh6s8x",get_if(iff,SIOCGIFHWADDR))
-
-    def get_if_raw_addr(iff):
-        try:
-            return get_if(iff, SIOCGIFADDR)[20:24]
-        except IOError:
-            return "\0\0\0\0"
-
-
-if PCAP:
-    def get_if_list():
-        # remove 'any' interface
-        return map(lambda x:x[0],filter(lambda x:x[1] is None,pcap.findalldevs()))
-    def get_working_if():
-        try:
-            return pcap.lookupdev()
-        except Exception:
-            return 'lo'
-
-    def attach_filter(s, filter):
-        warning("attach_filter() should not be called in PCAP mode")
-    def set_promisc(s,iff,val=1):
-        warning("set_promisc() should not be called in DNET/PCAP mode")
-    
-else:
-    def get_if_list():
-        f=open("/proc/net/dev","r")
-        lst = []
-        f.readline()
-        f.readline()
-        for l in f:
-            lst.append(l.split(":")[0].strip())
-        return lst
-    def get_working_if():
-        for i in get_if_list():
-            if i == 'lo':                
-                continue
-            ifflags = struct.unpack("16xH14x",get_if(i,SIOCGIFFLAGS))[0]
-            if ifflags & IFF_UP:
-                return i
-        return "lo"
-    def attach_filter(s, filter):
-        # XXX We generate the filter on the interface conf.iface 
-        # because tcpdump open the "any" interface and ppp interfaces
-        # in cooked mode. As we use them in raw mode, the filter will not
-        # work... one solution could be to use "any" interface and translate
-        # the filter from cooked mode to raw mode
-        # mode
-        if not TCPDUMP:
-            return
-        try:
-            f = os.popen("%s -i %s -ddd -s 1600 '%s'" % (conf.prog.tcpdump,conf.iface,filter))
-        except OSError,msg:
-            log_interactive.warning("Failed to execute tcpdump: (%s)")
-            return
-        lines = f.readlines()
-        if f.close():
-            raise Scapy_Exception("Filter parse error")
-        nb = int(lines[0])
-        bpf = ""
-        for l in lines[1:]:
-            bpf += struct.pack("HBBI",*map(long,l.split()))
-    
-        # XXX. Argl! We need to give the kernel a pointer on the BPF,
-        # python object header seems to be 20 bytes. 36 bytes for x86 64bits arch.
-        if X86_64:
-            bpfh = struct.pack("HL", nb, id(bpf)+36)
-        else:
-            bpfh = struct.pack("HI", nb, id(bpf)+20)  
-        s.setsockopt(SOL_SOCKET, SO_ATTACH_FILTER, bpfh)
-
-    def set_promisc(s,iff,val=1):
-        mreq = struct.pack("IHH8s", get_if_index(iff), PACKET_MR_PROMISC, 0, "")
-        if val:
-            cmd = PACKET_ADD_MEMBERSHIP
-        else:
-            cmd = PACKET_DROP_MEMBERSHIP
-        s.setsockopt(SOL_PACKET, cmd, mreq)
-
-
-if not LINUX:
-
-    def new_read_routes():
-
-        rtlst = []
-        def addrt(rt,lst):
-            dst,gw = rt
-            lst.append(rt)
-
-        r = dnet.route()
-        print r.loop(addrt, rtlst)
-        return rtlst
-
-    def read_routes():
-        if SOLARIS:
-            f=os.popen("netstat -rvn") # -f inet
-        elif FREEBSD:
-            f=os.popen("netstat -rnW") # -W to handle long interface names
-        else:
-            f=os.popen("netstat -rn") # -f inet
-        ok = 0
-        mtu_present = False
-        routes = []
-        for l in f.readlines():
-            if not l:
-                break
-            l = l.strip()
-            if l.find("----") >= 0: # a separation line
-                continue
-            if l.find("Destination") >= 0:
-                ok = 1
-                if l.find("Mtu") >= 0:
-                    mtu_present = True
-                continue
-            if ok == 0:
-                continue
-            if not l:
-                break
-            if SOLARIS:
-                dest,mask,gw,netif,mxfrg,rtt,ref,flg = l.split()[:8]
-            else:
-                if mtu_present:
-                    dest,gw,flg,ref,use,mtu,netif = l.split()[:7]
-                else:
-                    dest,gw,flg,ref,use,netif = l.split()[:6]
-            if flg.find("Lc") >= 0:
-                continue                
-            if dest == "default":
-                dest = 0L
-                netmask = 0L
-            else:
-                if SOLARIS:
-                    netmask = atol(mask)
-                elif "/" in dest:
-                    dest,netmask = dest.split("/")
-                    netmask = itom(int(netmask))
-                else:
-                    netmask = itom((dest.count(".") + 1) * 8)
-                dest += ".0"*(3-dest.count("."))
-                dest = atol(dest)
-            if not "G" in flg:
-                gw = '0.0.0.0'
-            ifaddr = get_if_addr(netif)
-            routes.append((dest,netmask,gw,netif,ifaddr))
-        f.close()
-        return routes
-
-    def read_interfaces():
-        i = dnet.intf()
-        ifflist = {}
-        def addif(iff,lst):
-            if not iff.has_key("addr"):
-                return
-            if not iff.has_key("link_addr"):
-                return
-            rawip = iff["addr"].data
-            ip = inet_ntoa(rawip)
-            rawll = iff["link_addr"].data
-            ll = str2mac(rawll)
-            lst[iff["name"]] = (rawll,ll,rawip,ip)
-        i.loop(addif, ifflist)
-        return ifflist
-
-            
-else:
-
-    def read_routes():
-        f=open("/proc/net/route","r")
-        routes = []
-        s=socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
-        ifreq = ioctl(s, SIOCGIFADDR,struct.pack("16s16x","lo"))
-        addrfamily = struct.unpack("h",ifreq[16:18])[0]
-        if addrfamily == socket.AF_INET:
-            ifreq2 = ioctl(s, SIOCGIFNETMASK,struct.pack("16s16x","lo"))
-            msk = socket.ntohl(struct.unpack("I",ifreq2[20:24])[0])
-            dst = socket.ntohl(struct.unpack("I",ifreq[20:24])[0]) & msk
-            ifaddr = inet_ntoa(ifreq[20:24])
-            routes.append((dst, msk, "0.0.0.0", "lo", ifaddr))
-        else:
-            warning("Interface lo: unkown address family (%i)"% addrfamily)
-    
-        for l in f.readlines()[1:]:
-            iff,dst,gw,flags,x,x,x,msk,x,x,x = l.split()
-            flags = int(flags,16)
-            if flags & RTF_UP == 0:
-                continue
-            if flags & RTF_REJECT:
-                continue
-            try:
-                ifreq = ioctl(s, SIOCGIFADDR,struct.pack("16s16x",iff))
-            except IOError: # interface is present in routing tables but does not have any assigned IP
-                ifaddr="0.0.0.0"
-            else:
-                addrfamily = struct.unpack("h",ifreq[16:18])[0]
-                if addrfamily == socket.AF_INET:
-                    ifaddr = inet_ntoa(ifreq[20:24])
-                else:
-                    warning("Interface %s: unkown address family (%i)"%(iff, addrfamily))
-                    continue
-            routes.append((socket.htonl(long(dst,16))&0xffffffffL,
-                           socket.htonl(long(msk,16))&0xffffffffL,
-                           inet_ntoa(struct.pack("I",long(gw,16))),
-                           iff, ifaddr))
-        
-        f.close()
-        return routes
-
-    def get_if(iff,cmd):
-        s=socket.socket()
-        ifreq = ioctl(s, cmd, struct.pack("16s16x",iff))
-        s.close()
-        return ifreq
-
-
-    def get_if_index(iff):
-        return int(struct.unpack("I",get_if(iff, SIOCGIFINDEX)[16:20])[0])
-
-    def get_last_packet_timestamp(sock):
-        ts = ioctl(sock, SIOCGSTAMP, "12345678")
-        s,us = struct.unpack("II",ts)
-        return s+us/1000000.0
-
-    
-def get_if_addr(iff):
-    return inet_ntoa(get_if_raw_addr(iff))
-    
-def get_if_hwaddr(iff):
-    addrfamily, mac = get_if_raw_hwaddr(iff)
-    if addrfamily in [ARPHDR_ETHER,ARPHDR_LOOPBACK]:
-        return str2mac(mac)
-    else:
-        raise Scapy_Exception("Unsupported address family (%i) for interface [%s]" % (addrfamily,iff))
-
-
-
-#####################
-## ARP cache stuff ##
-#####################
-
-ARPTIMEOUT=120
-
-# XXX Fill arp_cache with /etc/ether and arp cache
-arp_cache={}
-
-if 0 and DNET: ## XXX Can't use this because it does not resolve IPs not in cache
-    dnet_arp_object = dnet.arp()
-    def getmacbyip(ip, chainCC=0):
-        tmp = map(ord, inet_aton(ip))
-        if (tmp[0] & 0xf0) == 0xe0: # mcast @
-            return "01:00:5e:%.2x:%.2x:%.2x" % (tmp[1]&0x7f,tmp[2],tmp[3])
-        iff,a,gw = conf.route.route(ip)
-        if iff == "lo":
-            return "ff:ff:ff:ff:ff:ff"
-        if gw != "0.0.0.0":
-            ip = gw
-        res = dnet_arp_object.get(dnet.addr(ip))
-        if res is None:
-            return None
-        else:
-            return res.ntoa()
-else:
-    def getmacbyip(ip, chainCC=0):
-        tmp = map(ord, inet_aton(ip))
-        if (tmp[0] & 0xf0) == 0xe0: # mcast @
-            return "01:00:5e:%.2x:%.2x:%.2x" % (tmp[1]&0x7f,tmp[2],tmp[3])
-        iff,a,gw = conf.route.route(ip)
-        if ( (iff == "lo") or (ip == conf.route.get_if_bcast(iff)) ):
-            return "ff:ff:ff:ff:ff:ff"
-        if gw != "0.0.0.0":
-            ip = gw
-    
-        if arp_cache.has_key(ip):
-            mac, timeout = arp_cache[ip]
-            if not timeout or (time.time()-timeout < ARPTIMEOUT):
-                return mac
-
-        res = srp1(Ether(dst=ETHER_BROADCAST)/ARP(op="who-has", pdst=ip),
-                   type=ETH_P_ARP,
-                   iface = iff,
-                   timeout=2,
-                   verbose=0,
-                   chainCC=chainCC,
-                   nofilter=1)
-        if res is not None:
-            mac = res.payload.hwsrc
-            arp_cache[ip] = (mac,time.time())
-            return mac
-        return None
-    
-
-####################
-## Random numbers ##
-####################
-
-def randseq(inf, sup, seed=None, forever=1, renewkeys=0):
-    """iterate through a sequence in random order.
-       When all the values have been drawn, if forever=1, the drawing is done again.
-       If renewkeys=0, the draw will be in the same order, guaranteeing that the same
-       number will be drawn in not less than the number of integers of the sequence"""
-    rnd = random.Random(seed)
-    sbox_size = 256
-
-    top = sup-inf+1
-    
-    n=0
-    while (1<<n) < top:
-        n += 1
-
-    fs = min(3,(n+1)/2)
-    fsmask = 2**fs-1
-    rounds = max(n,3)
-    turns = 0
-
-    while 1:
-        if turns == 0 or renewkeys:
-            sbox = [rnd.randint(0,fsmask) for k in xrange(sbox_size)]
-        turns += 1
-        i = 0
-        while i < 2**n:
-            ct = i
-            i += 1
-            for k in range(rounds): # Unbalanced Feistel Network
-                lsb = ct & fsmask
-                ct >>= fs
-                lsb ^= sbox[ct%sbox_size]
-                ct |= lsb << (n-fs)
-            
-            if ct < top:
-                yield inf+ct
-        if not forever:
-            break
-
-
-class VolatileValue:
-    def __repr__(self):
-        return "<%s>" % self.__class__.__name__
-    def __getattr__(self, attr):
-        if attr == "__setstate__":
-            raise AttributeError(attr)
-        return getattr(self._fix(),attr)
-    def _fix(self):
-        return None
-
-
-class RandField(VolatileValue):
-    pass
-
-
-class RandNum(RandField):
-    min = 0
-    max = 0
-    def __init__(self, min, max):
-        self.seq = randseq(min,max)
-    def _fix(self):
-        return self.seq.next()
-
-class RandNumGamma(RandField):
-    def __init__(self, alpha, beta):
-        self.alpha = alpha
-        self.beta = beta
-    def _fix(self):
-        return int(round(random.gammavariate(self.alpha, self.beta)))
-
-class RandNumGauss(RandField):
-    def __init__(self, mu, sigma):
-        self.mu = mu
-        self.sigma = sigma
-    def _fix(self):
-        return int(round(random.gauss(self.mu, self.sigma)))
-
-class RandNumExpo(RandField):
-    def __init__(self, lambd):
-        self.lambd = lambd
-    def _fix(self):
-        return int(round(random.expovariate(self.lambd)))
-
-class RandByte(RandNum):
-    def __init__(self):
-        RandNum.__init__(self, 0, 2L**8-1)
-
-class RandShort(RandNum):
-    def __init__(self):
-        RandNum.__init__(self, 0, 2L**16-1)
-
-class RandInt(RandNum):
-    def __init__(self):
-        RandNum.__init__(self, 0, 2L**32-1)
-
-class RandSInt(RandNum):
-    def __init__(self):
-        RandNum.__init__(self, -2L**31, 2L**31-1)
-
-class RandLong(RandNum):
-    def __init__(self):
-        RandNum.__init__(self, 0, 2L**64-1)
-
-class RandSLong(RandNum):
-    def __init__(self):
-        RandNum.__init__(self, -2L**63, 2L**63-1)
-
-class RandChoice(RandField):
-    def __init__(self, *args):
-        if not args:
-            raise TypeError("RandChoice needs at least one choice")
-        self._choice = args
-    def _fix(self):
-        return random.choice(self._choice)
-    
-class RandString(RandField):
-    def __init__(self, size, chars="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"):
-        self.chars = chars
-        self.size = size
-    def _fix(self):
-        s = ""
-        for i in range(self.size):
-            s += random.choice(self.chars)
-        return s
-
-class RandBin(RandString):
-    def __init__(self, size):
-        RandString.__init__(self, size, "".join(map(chr,range(256))))
-
-
-class RandTermString(RandString):
-    def __init__(self, size, term):
-        RandString.__init__(self, size, "".join(map(chr,range(1,256))))
-        self.term = term
-    def _fix(self):
-        return RandString._fix(self)+self.term
-    
-    
-
-class RandIP(RandString):
-    def __init__(self, iptemplate="0.0.0.0/0"):
-        self.ip = Net(iptemplate)
-    def _fix(self):
-        return self.ip.choice()
-
-class RandMAC(RandString):
-    def __init__(self, template="*"):
-        template += ":*:*:*:*:*"
-        template = template.split(":")
-        self.mac = ()
-        for i in range(6):
-            if template[i] == "*":
-                v = RandByte()
-            elif "-" in template[i]:
-                x,y = template[i].split("-")
-                v = RandNum(int(x,16), int(y,16))
-            else:
-                v = int(template[i],16)
-            self.mac += (v,)
-    def _fix(self):
-        return "%02x:%02x:%02x:%02x:%02x:%02x" % self.mac
-    
-
-class RandOID(RandString):
-    def __init__(self, fmt=None, depth=RandNumExpo(0.1), idnum=RandNumExpo(0.01)):
-        self.ori_fmt = fmt
-        if fmt is not None:
-            fmt = fmt.split(".")
-            for i in range(len(fmt)):
-                if "-" in fmt[i]:
-                    fmt[i] = tuple(map(int, fmt[i].split("-")))
-        self.fmt = fmt
-        self.depth = depth
-        self.idnum = idnum
-    def __repr__(self):
-        if self.ori_fmt is None:
-            return "<%s>" % self.__class__.__name__
-        else:
-            return "<%s [%s]>" % (self.__class__.__name__, self.ori_fmt)
-    def _fix(self):
-        if self.fmt is None:
-            return ".".join(map(str, [self.idnum for i in xrange(1+self.depth)]))
-        else:
-            oid = []
-            for i in self.fmt:
-                if i == "*":
-                    oid.append(str(self.idnum))
-                elif i == "**":
-                    oid += map(str, [self.idnum for i in xrange(1+self.depth)])
-                elif type(i) is tuple:
-                    oid.append(str(random.randrange(*i)))
-                else:
-                    oid.append(i)
-            return ".".join(oid)
-            
-
-
-class RandASN1Object(RandField):
-    def __init__(self, objlist=None):
-        if objlist is None:
-            objlist = map(lambda x:x._asn1_obj,
-                          filter(lambda x:hasattr(x,"_asn1_obj"), ASN1_Class_UNIVERSAL.__rdict__.values()))
-        self.objlist = objlist
-        self.chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
-    def _fix(self, n=0):
-        o = random.choice(self.objlist)
-        if issubclass(o, ASN1_INTEGER):
-            return o(int(random.gauss(0,1000)))
-        elif issubclass(o, ASN1_STRING):
-            z = int(random.expovariate(0.05)+1)
-            return o("".join([random.choice(self.chars) for i in range(z)]))
-        elif issubclass(o, ASN1_SEQUENCE) and (n < 10):
-            z = int(random.expovariate(0.08)+1)
-            return o(map(lambda x:x._fix(n+1), [self.__class__(objlist=self.objlist)]*z))
-        return ASN1_INTEGER(int(random.gauss(0,1000)))
-
-class RandDHCPOptions(RandField):
-    def __init__(self, size=None, rndstr=None):
-        if size is None:
-            size = RandNumExpo(0.05)
-        self.size = size
-        if rndstr is None:
-            rndstr = RandBin(RandNum(0,255))
-        self.rndstr=rndstr
-        self._opts = DHCPOptions.values()
-        self._opts.remove("pad")
-        self._opts.remove("end")
-    def _fix(self):
-        op = []
-        for k in range(self.size):
-            o = random.choice(self._opts)
-            if type(o) is str:
-                op.append((o,self.rndstr*1))
-            else:
-                op.append((o.name, o.randval()._fix()))
-        return op
-            
-
-# Automatic timestamp
-
-class AutoTime(VolatileValue):
-    def __init__(self, base=None):
-        if base == None:
-            self.diff = 0
-        else:
-            self.diff = time.time()-base
-    def _fix(self):
-        return time.time()-self.diff
-            
-class IntAutoTime(AutoTime):
-    def _fix(self):
-        return int(time.time()-self.diff)
-
-
-class ZuluTime(AutoTime):
-    def __init__(self, diff=None):
-        self.diff=diff
-    def _fix(self):
-        return time.strftime("%y%m%d%H%M%SZ",time.gmtime(time.time()+self.diff))
-
-
-class DelayedEval(VolatileValue):
-    """ Exemple of usage: DelayedEval("time.time()") """
-    def __init__(self, expr):
-        self.expr = expr
-    def _fix(self):
-        return eval(self.expr)
-
-
-class IncrementalValue(VolatileValue):
-    def __init__(self, start=0, step=1, restart=-1):
-        self.start = self.val = start
-        self.step = step
-        self.restart = restart
-    def _fix(self):
-        v = self.val
-        if self.val == self.restart :
-            self.val = self.start
-        else:
-            self.val += self.step
-        return v
-
-def corrupt_bytes(s, p=0.01, n=None):
-    s = array.array("B",str(s))
-    l = len(s)
-    if n is None:
-        n = max(1,int(l*p))
-    for i in random.sample(xrange(l), n):
-        s[i] = random.randint(0,255)
-    return s.tostring()
-
-def corrupt_bits(s, p=0.01, n=None):
-    s = array.array("B",str(s))
-    l = len(s)*8
-    if n is None:
-        n = max(1,int(l*p))
-    for i in random.sample(xrange(l), n):
-        s[i/8] ^= 1 << (i%8)
-    return s.tostring()
-
-    
-class CorruptedBytes(VolatileValue):
-    def __init__(self, s, p=0.01, n=None):
-        self.s = s
-        self.p = p
-        self.n = n
-    def _fix(self):
-        return corrupt_bytes(self.s, self.p, self.n)
-
-class CorruptedBits(CorruptedBytes):
-    def _fix(self):
-        return corrupt_bits(self.s, self.p, self.n)
-
-##############
-#### ASN1 ####
-##############
-
-class ASN1_Error(Exception):
-    pass
-
-class ASN1_Encoding_Error(ASN1_Error):
-    pass
-
-class ASN1_Decoding_Error(ASN1_Error):
-    pass
-
-class ASN1_BadTag_Decoding_Error(ASN1_Decoding_Error):
-    pass
-
-
-
-class ASN1Codec(EnumElement):
-    def register_stem(cls, stem):
-        cls._stem = stem
-    def dec(cls, s, context=None):
-        return cls._stem.dec(s, context=context)
-    def safedec(cls, s, context=None):
-        return cls._stem.safedec(s, context=context)
-    def get_stem(cls):
-        return cls.stem
-    
-
-class ASN1_Codecs_metaclass(Enum_metaclass):
-    element_class = ASN1Codec
-
-class ASN1_Codecs:
-    __metaclass__ = ASN1_Codecs_metaclass
-    BER = 1
-    DER = 2
-    PER = 3
-    CER = 4
-    LWER = 5
-    BACnet = 6
-    OER = 7
-    SER = 8
-    XER = 9
-
-class ASN1Tag(EnumElement):
-    def __init__(self, key, value, context=None, codec=None):
-        EnumElement.__init__(self, key, value)
-        self._context = context
-        if codec == None:
-            codec = {}
-        self._codec = codec
-    def clone(self): # /!\ not a real deep copy. self.codec is shared
-        return self.__class__(self._key, self._value, self._context, self._codec)
-    def register_asn1_object(self, asn1obj):
-        self._asn1_obj = asn1obj
-    def asn1_object(self, val):
-        if hasattr(self,"_asn1_obj"):
-            return self._asn1_obj(val)
-        raise ASN1_Error("%r does not have any assigned ASN1 object" % self)
-    def register(self, codecnum, codec):
-        self._codec[codecnum] = codec
-    def get_codec(self, codec):
-        try:
-            c = self._codec[codec]
-        except KeyError,msg:
-            raise ASN1_Error("Codec %r not found for tag %r" % (codec, self))
-        return c
-
-class ASN1_Class_metaclass(Enum_metaclass):
-    element_class = ASN1Tag
-    def __new__(cls, name, bases, dct): # XXX factorise a bit with Enum_metaclass.__new__()
-        for b in bases:
-            for k,v in b.__dict__.iteritems():
-                if k not in dct and isinstance(v,ASN1Tag):
-                    dct[k] = v.clone()
-
-        rdict = {}
-        for k,v in dct.iteritems():
-            if type(v) is int:
-                v = ASN1Tag(k,v) 
-                dct[k] = v
-                rdict[v] = v
-            elif isinstance(v, ASN1Tag):
-                rdict[v] = v
-        dct["__rdict__"] = rdict
-
-        cls = type.__new__(cls, name, bases, dct)
-        for v in cls.__dict__.values():
-            if isinstance(v, ASN1Tag): 
-                v.context = cls # overwrite ASN1Tag contexts, even cloned ones
-        return cls
-            
-
-class ASN1_Class:
-    __metaclass__ = ASN1_Class_metaclass
-
-class ASN1_Class_UNIVERSAL(ASN1_Class):
-    name = "UNIVERSAL"
-    ERROR = -3
-    RAW = -2
-    NONE = -1
-    ANY = 0
-    BOOLEAN = 1
-    INTEGER = 2
-    BIT_STRING = 3
-    STRING = 4
-    NULL = 5
-    OID = 6
-    OBJECT_DESCRIPTOR = 7
-    EXTERNAL = 8
-    REAL = 9
-    ENUMERATED = 10
-    EMBEDDED_PDF = 11
-    UTF8_STRING = 12
-    RELATIVE_OID = 13
-    SEQUENCE = 0x30#XXX 16 ??
-    SET = 0x31 #XXX 17 ??
-    NUMERIC_STRING = 18
-    PRINTABLE_STRING = 19
-    T61_STRING = 20
-    VIDEOTEX_STRING = 21
-    IA5_STRING = 22
-    UTC_TIME = 23
-    GENERALIZED_TIME = 24
-    GRAPHIC_STRING = 25
-    ISO646_STRING = 26
-    GENERAL_STRING = 27
-    UNIVERSAL_STRING = 28
-    CHAR_STRING = 29
-    BMP_STRING = 30
-    COUNTER32 = 0x41
-    TIME_TICKS = 0x43
-
-class ASN1_Object_metaclass(type):
-    def __new__(cls, name, bases, dct):
-        c = super(ASN1_Object_metaclass, cls).__new__(cls, name, bases, dct)
-        try:
-            c.tag.register_asn1_object(c)
-        except:
-            warning("Error registering %r for %r" % (c.tag, c.codec))
-        return c
-
-
-class ASN1_Object:
-    __metaclass__ = ASN1_Object_metaclass
-    tag = ASN1_Class_UNIVERSAL.ANY
-    def __init__(self, val):
-        self.val = val
-    def enc(self, codec):
-        return self.tag.get_codec(codec).enc(self.val)
-    def __repr__(self):
-        return "<%s[%r]>" % (self.__dict__.get("name", self.__class__.__name__), self.val)
-    def __str__(self):
-        return self.enc(conf.ASN1_default_codec)
-    def strshow(self, lvl=0):
-        return ("  "*lvl)+repr(self)+"\n"
-    def show(self, lvl=0):
-        print self.strshow(lvl)
-    def __eq__(self, other):
-        return self.val == other
-    def __cmp__(self, other):
-        return cmp(self.val, other)
-
-class ASN1_DECODING_ERROR(ASN1_Object):
-    tag = ASN1_Class_UNIVERSAL.ERROR
-    def __init__(self, val, exc=None):
-        ASN1_Object.__init__(self, val)
-        self.exc = exc
-    def __repr__(self):
-        return "<%s[%r]{{%s}}>" % (self.__dict__.get("name", self.__class__.__name__),
-                                   self.val, self.exc.args[0])
-    def enc(self, codec):
-        if isinstance(self.val, ASN1_Object):
-            return self.val.enc(codec)
-        return self.val
-
-class ASN1_force(ASN1_Object):
-    tag = ASN1_Class_UNIVERSAL.RAW
-    def enc(self, codec):
-        if isinstance(self.val, ASN1_Object):
-            return self.val.enc(codec)
-        return self.val
-
-class ASN1_BADTAG(ASN1_force):
-    pass
-
-class ASN1_INTEGER(ASN1_Object):
-    tag = ASN1_Class_UNIVERSAL.INTEGER
-
-class ASN1_STRING(ASN1_Object):
-    tag = ASN1_Class_UNIVERSAL.STRING
-
-class ASN1_BIT_STRING(ASN1_STRING):
-    tag = ASN1_Class_UNIVERSAL.BIT_STRING
-
-class ASN1_PRINTABLE_STRING(ASN1_STRING):
-    tag = ASN1_Class_UNIVERSAL.PRINTABLE_STRING
-
-class ASN1_T61_STRING(ASN1_STRING):
-    tag = ASN1_Class_UNIVERSAL.T61_STRING
-
-class ASN1_IA5_STRING(ASN1_STRING):
-    tag = ASN1_Class_UNIVERSAL.IA5_STRING
-
-class ASN1_NUMERIC_STRING(ASN1_STRING):
-    tag = ASN1_Class_UNIVERSAL.NUMERIC_STRING
-
-class ASN1_VIDEOTEX_STRING(ASN1_STRING):
-    tag = ASN1_Class_UNIVERSAL.VIDEOTEX_STRING
-
-class ASN1_UTC_TIME(ASN1_STRING):
-    tag = ASN1_Class_UNIVERSAL.UTC_TIME
-
-class ASN1_TIME_TICKS(ASN1_INTEGER):
-    tag = ASN1_Class_UNIVERSAL.TIME_TICKS
-
-class ASN1_BOOLEAN(ASN1_INTEGER):
-    tag = ASN1_Class_UNIVERSAL.BOOLEAN
-    
-class ASN1_NULL(ASN1_INTEGER):
-    tag = ASN1_Class_UNIVERSAL.NULL
-
-class ASN1_COUNTER32(ASN1_INTEGER):
-    tag = ASN1_Class_UNIVERSAL.COUNTER32
-    
-class ASN1_SEQUENCE(ASN1_Object):
-    tag = ASN1_Class_UNIVERSAL.SEQUENCE
-    def strshow(self, lvl=0):
-        s = ("  "*lvl)+("# %s:" % self.__class__.__name__)+"\n"
-        for o in self.val:
-            s += o.strshow(lvl=lvl+1)
-        return s
-    
-class ASN1_SET(ASN1_SEQUENCE):
-    tag = ASN1_Class_UNIVERSAL.SET
-    
-class ASN1_OID(ASN1_Object):
-    tag = ASN1_Class_UNIVERSAL.OID
-    def __init__(self, val):
-        val = conf.mib._oid(val)
-        ASN1_Object.__init__(self, val)
-    def __repr__(self):
-        return "<%s[%r]>" % (self.__dict__.get("name", self.__class__.__name__), conf.mib._oidname(self.val))
-    
-
-
-##################
-## BER encoding ##
-##################
-
-
-
-#####[ BER tools ]#####
-
-
-class BER_Exception(Exception):
-    pass
-
-class BER_Decoding_Error(ASN1_Decoding_Error):
-    def __init__(self, msg, decoded=None, remaining=None):
-        Exception.__init__(self, msg)
-        self.remaining = remaining
-        self.decoded = decoded
-    def __str__(self):
-        s = Exception.__str__(self)
-        if isinstance(self.decoded, BERcodec_Object):
-            s+="\n### Already decoded ###\n%s" % self.decoded.strshow()
-        else:
-            s+="\n### Already decoded ###\n%r" % self.decoded
-        s+="\n### Remaining ###\n%r" % self.remaining
-        return s
-
-class BER_BadTag_Decoding_Error(BER_Decoding_Error, ASN1_BadTag_Decoding_Error):
-    pass
-
-def BER_len_enc(l, size=0):
-        if l <= 127 and size==0:
-            return chr(l)
-        s = ""
-        while l or size>0:
-            s = chr(l&0xff)+s
-            l >>= 8L
-            size -= 1
-        if len(s) > 127:
-            raise BER_Exception("BER_len_enc: Length too long (%i) to be encoded [%r]" % (len(s),s))
-        return chr(len(s)|0x80)+s
-def BER_len_dec(s):
-        l = ord(s[0])
-        if not l & 0x80:
-            return l,s[1:]
-        l &= 0x7f
-        if len(s) <= l:
-            raise BER_Decoding_Error("BER_len_dec: Got %i bytes while expecting %i" % (len(s)-1, l),remaining=s)
-        ll = 0L
-        for c in s[1:l+1]:
-            ll <<= 8L
-            ll |= ord(c)
-        return ll,s[l+1:]
-        
-def BER_num_enc(l, size=1):
-        x=[]
-        while l or size>0:
-            x.insert(0, l & 0x7f)
-            if len(x) > 1:
-                x[0] |= 0x80
-            l >>= 7
-            size -= 1
-        return "".join([chr(k) for k in x])
-def BER_num_dec(s):
-        x = 0
-        for i in range(len(s)):
-            c = ord(s[i])
-            x <<= 7
-            x |= c&0x7f
-            if not c&0x80:
-                break
-        if c&0x80:
-            raise BER_Decoding_Error("BER_num_dec: unfinished number description", remaining=s)
-        return x, s[i+1:]
-
-#####[ BER classes ]#####
-
-class BERcodec_metaclass(type):
-    def __new__(cls, name, bases, dct):
-        c = super(BERcodec_metaclass, cls).__new__(cls, name, bases, dct)
-        try:
-            c.tag.register(c.codec, c)
-        except:
-            warning("Error registering %r for %r" % (c.tag, c.codec))
-        return c
-
-
-class BERcodec_Object:
-    __metaclass__ = BERcodec_metaclass
-    codec = ASN1_Codecs.BER
-    tag = ASN1_Class_UNIVERSAL.ANY
-
-    @classmethod
-    def asn1_object(cls, val):
-        return cls.tag.asn1_object(val)
-
-    @classmethod
-    def check_string(cls, s):
-        if not s:
-            raise BER_Decoding_Error("%s: Got empty object while expecting tag %r" %
-                                     (cls.__name__,cls.tag), remaining=s)        
-    @classmethod
-    def check_type(cls, s):
-        cls.check_string(s)
-        if cls.tag != ord(s[0]):
-            raise BER_BadTag_Decoding_Error("%s: Got tag [%i/%#x] while expecting %r" %
-                                            (cls.__name__, ord(s[0]), ord(s[0]),cls.tag), remaining=s)
-        return s[1:]
-    @classmethod
-    def check_type_get_len(cls, s):
-        s2 = cls.check_type(s)
-        if not s2:
-            raise BER_Decoding_Error("%s: No bytes while expecting a length" %
-                                     cls.__name__, remaining=s)
-        return BER_len_dec(s2)
-    @classmethod
-    def check_type_check_len(cls, s):
-        l,s3 = cls.check_type_get_len(s)
-        if len(s3) < l:
-            raise BER_Decoding_Error("%s: Got %i bytes while expecting %i" %
-                                     (cls.__name__, len(s3), l), remaining=s)
-        return l,s3[:l],s3[l:]
-
-    @classmethod
-    def do_dec(cls, s, context=None, safe=False):
-        if context is None:
-            context = cls.tag.context
-        cls.check_string(s)
-        p = ord(s[0])
-        if p not in context:
-            t = s
-            if len(t) > 18:
-                t = t[:15]+"..."
-            raise BER_Decoding_Error("Unknown prefix [%02x] for [%r]" % (p,t), remaining=s)
-        codec = context[p].get_codec(ASN1_Codecs.BER)
-        return codec.dec(s,context,safe)
-
-    @classmethod
-    def dec(cls, s, context=None, safe=False):
-        if not safe:
-            return cls.do_dec(s, context, safe)
-        try:
-            return cls.do_dec(s, context, safe)
-        except BER_BadTag_Decoding_Error,e:
-            o,remain = BERcodec_Object.dec(e.remaining, context, safe)
-            return ASN1_BADTAG(o),remain
-        except BER_Decoding_Error, e:
-            return ASN1_DECODING_ERROR(s, exc=e),""
-        except ASN1_Error, e:
-            return ASN1_DECODING_ERROR(s, exc=e),""
-
-    @classmethod
-    def safedec(cls, s, context=None):
-        return cls.dec(s, context, safe=True)
-
-
-    @classmethod
-    def enc(cls, s):
-        if type(s) is str:
-            return BERcodec_STRING.enc(s)
-        else:
-            return BERcodec_INTEGER.enc(int(s))
-
-            
-
-ASN1_Codecs.BER.register_stem(BERcodec_Object)
-
-
-class BERcodec_INTEGER(BERcodec_Object):
-    tag = ASN1_Class_UNIVERSAL.INTEGER
-    @classmethod
-    def enc(cls, i):
-        s = []
-        while 1:
-            s.append(i&0xff)
-            if -127 <= i < 0:
-                break
-            if 128 <= i <= 255:
-                s.append(0)
-            i >>= 8
-            if not i:
-                break
-        s = map(chr, s)
-        s.append(BER_len_enc(len(s)))
-        s.append(chr(cls.tag))
-        s.reverse()
-        return "".join(s)
-    @classmethod
-    def do_dec(cls, s, context=None, safe=False):
-        l,s,t = cls.check_type_check_len(s)
-        x = 0L
-        if s:
-            if ord(s[0])&0x80: # negative int
-                x = -1L
-            for c in s:
-                x <<= 8
-                x |= ord(c)
-        return cls.asn1_object(x),t
-    
-
-class BERcodec_BOOLEAN(BERcodec_INTEGER):
-    tag = ASN1_Class_UNIVERSAL.BOOLEAN
-
-class BERcodec_NULL(BERcodec_INTEGER):
-    tag = ASN1_Class_UNIVERSAL.NULL
-    @classmethod
-    def enc(cls, i):
-        if i == 0:
-            return chr(cls.tag)+"\0"
-        else:
-            return super(cls,cls).enc(i)
-
-class BERcodec_STRING(BERcodec_Object):
-    tag = ASN1_Class_UNIVERSAL.STRING
-    @classmethod
-    def enc(cls,s):
-        return chr(cls.tag)+BER_len_enc(len(s))+s
-    @classmethod
-    def do_dec(cls, s, context=None, safe=False):
-        l,s,t = cls.check_type_check_len(s)
-        return cls.tag.asn1_object(s),t
-
-class BERcodec_BIT_STRING(BERcodec_STRING):
-    tag = ASN1_Class_UNIVERSAL.BIT_STRING
-
-class BERcodec_PRINTABLE_STRING(BERcodec_STRING):
-    tag = ASN1_Class_UNIVERSAL.PRINTABLE_STRING
-
-class BERcodec_T61_STRING (BERcodec_STRING):
-    tag = ASN1_Class_UNIVERSAL.T61_STRING
-
-class BERcodec_IA5_STRING(BERcodec_STRING):
-    tag = ASN1_Class_UNIVERSAL.IA5_STRING
-
-class BERcodec_UTC_TIME(BERcodec_STRING):
-    tag = ASN1_Class_UNIVERSAL.UTC_TIME
-
-class BERcodec_TIME_TICKS(BERcodec_INTEGER):
-    tag = ASN1_Class_UNIVERSAL.TIME_TICKS
-
-class BERcodec_COUNTER32(BERcodec_INTEGER):
-    tag = ASN1_Class_UNIVERSAL.COUNTER32
-
-class BERcodec_SEQUENCE(BERcodec_Object):
-    tag = ASN1_Class_UNIVERSAL.SEQUENCE
-    @classmethod
-    def enc(cls, l):
-        if type(l) is not str:
-            l = "".join(map(lambda x: x.enc(cls.codec), l))
-        return chr(cls.tag)+BER_len_enc(len(l))+l
-    @classmethod
-    def do_dec(cls, s, context=None, safe=False):
-        if context is None:
-            context = cls.tag.context
-        l,st = cls.check_type_get_len(s) # we may have len(s) < l
-        s,t = st[:l],st[l:]
-        obj = []
-        while s:
-            try:
-                o,s = BERcodec_Object.dec(s, context, safe)
-            except BER_Decoding_Error, err:
-                err.remaining += t
-                if err.decoded is not None:
-                    obj.append(err.decoded)
-                err.decoded = obj
-                raise 
-            obj.append(o)
-        if len(st) < l:
-            raise BER_Decoding_Error("Not enough bytes to decode sequence", decoded=obj)
-        return cls.asn1_object(obj),t
-
-class BERcodec_SET(BERcodec_SEQUENCE):
-    tag = ASN1_Class_UNIVERSAL.SET
-
-
-class BERcodec_OID(BERcodec_Object):
-    tag = ASN1_Class_UNIVERSAL.OID
-
-    @classmethod
-    def enc(cls, oid):
-        lst = [int(x) for x in oid.strip(".").split(".")]
-        if len(lst) >= 2:
-            lst[1] += 40*lst[0]
-            del(lst[0])
-        s = "".join([BER_num_enc(k) for k in lst])
-        return chr(cls.tag)+BER_len_enc(len(s))+s
-    @classmethod
-    def do_dec(cls, s, context=None, safe=False):
-        l,s,t = cls.check_type_check_len(s)
-        lst = []
-        while s:
-            l,s = BER_num_dec(s)
-            lst.append(l)
-        if (len(lst) > 0):
-            lst.insert(0,lst[0]/40)
-            lst[1] %= 40
-        return cls.asn1_object(".".join([str(k) for k in lst])), t
-
-
-#################
-## MIB parsing ##
-#################
-
-_mib_re_integer = re.compile("^[0-9]+$")
-_mib_re_both = re.compile("^([a-zA-Z_][a-zA-Z0-9_-]*)\(([0-9]+)\)$")
-_mib_re_oiddecl = re.compile("$\s*([a-zA-Z0-9_-]+)\s+OBJECT[^:]+::=\s*\{([^\}]+)\}",re.M)
-_mib_re_strings = re.compile('"[^"]*"')
-_mib_re_comments = re.compile('--.*(\r|\n)')
-
-class MIBDict(DADict):
-    def _findroot(self, x):
-        if x.startswith("."):
-            x = x[1:]
-        if not x.endswith("."):
-            x += "."
-        max=0
-        root="."
-        for k in self.keys():
-            if x.startswith(self[k]+"."):
-                if max < len(self[k]):
-                    max = len(self[k])
-                    root = k
-        return root, x[max:-1]
-    def _oidname(self, x):
-        root,remainder = self._findroot(x)
-        return root+remainder
-    def _oid(self, x):
-        xl = x.strip(".").split(".")
-        p = len(xl)-1
-        while p >= 0 and _mib_re_integer.match(xl[p]):
-            p -= 1
-        if p != 0 or xl[p] not in self:
-            return x
-        xl[p] = self[xl[p]] 
-        return ".".join(xl[p:])
-    def _make_graph(self, other_keys=[], **kargs):
-        nodes = [(k,self[k]) for k in self.keys()]
-        oids = [self[k] for k in self.keys()]
-        for k in other_keys:
-            if k not in oids:
-                nodes.append(self.oidname(k),k)
-        s = 'digraph "mib" {\n\trankdir=LR;\n\n'
-        for k,o in nodes:
-            s += '\t"%s" [ label="%s"  ];\n' % (o,k)
-        s += "\n"
-        for k,o in nodes:
-            parent,remainder = self._findroot(o[:-1])
-            remainder = remainder[1:]+o[-1]
-            if parent != ".":
-                parent = self[parent]
-            s += '\t"%s" -> "%s" [label="%s"];\n' % (parent, o,remainder)
-        s += "}\n"
-        do_graph(s, **kargs)
-
-
-def mib_register(ident, value, the_mib, unresolved):
-    if ident in the_mib or ident in unresolved:
-        return ident in the_mib
-    resval = []
-    not_resolved = 0
-    for v in value:
-        if _mib_re_integer.match(v):
-            resval.append(v)
-        else:
-            v = fixname(v)
-            if v not in the_mib:
-                not_resolved = 1
-            if v in the_mib:
-                v = the_mib[v]
-            elif v in unresolved:
-                v = unresolved[v]
-            if type(v) is list:
-                resval += v
-            else:
-                resval.append(v)
-    if not_resolved:
-        unresolved[ident] = resval
-        return False
-    else:
-        the_mib[ident] = resval
-        keys = unresolved.keys()
-        i = 0
-        while i < len(keys):
-            k = keys[i]
-            if mib_register(k,unresolved[k], the_mib, {}):
-                del(unresolved[k])
-                del(keys[i])
-                i = 0
-            else:
-                i += 1
-                    
-        return True
-
-
-def load_mib(filenames):
-    the_mib = {'iso': ['1']}
-    unresolved = {}
-    for k in conf.mib.keys():
-        mib_register(k, conf.mib[k].split("."), the_mib, unresolved)
-
-    if type(filenames) is str:
-        filenames = [filenames]
-    for fnames in filenames:
-        for fname in glob(fnames):
-            f = open(fname)
-            text = f.read()
-            cleantext = " ".join(_mib_re_strings.split(" ".join(_mib_re_comments.split(text))))
-            for m in _mib_re_oiddecl.finditer(cleantext):
-                ident,oid = m.groups()
-                ident=fixname(ident)
-                oid = oid.split()
-                for i in range(len(oid)):
-                    m = _mib_re_both.match(oid[i])
-                    if m:
-                        oid[i] = m.groups()[1]
-                mib_register(ident, oid, the_mib, unresolved)
-
-    newmib = MIBDict(_name="MIB")
-    for k,o in the_mib.iteritems():
-        newmib[k]=".".join(o)
-    for k,o in unresolved.iteritems():
-        newmib[k]=".".join(o)
-
-    conf.mib=newmib
-
-
-
-################
-## Generators ##
-################
-
-class Gen(object):
-    def __iter__(self):
-        return iter([])
-    
-class SetGen(Gen):
-    def __init__(self, set, _iterpacket=1):
-        self._iterpacket=_iterpacket
-        if type(set) is list:
-            self.set = set
-        elif isinstance(set, PacketList):
-            self.set = list(set)
-        else:
-            self.set = [set]
-    def transf(self, element):
-        return element
-    def __iter__(self):
-        for i in self.set:
-            if (type(i) is tuple) and (len(i) == 2) and type(i[0]) is int and type(i[1]) is int:
-                if  (i[0] <= i[1]):
-                    j=i[0]
-                    while j <= i[1]:
-                        yield j
-                        j += 1
-            elif isinstance(i, Gen) and (self._iterpacket or not isinstance(i,Packet)):
-                for j in i:
-                    yield j
-            else:
-                yield i
-    def __repr__(self):
-        return "<SetGen %s>" % self.set.__repr__()
-
-class Net(Gen):
-    """Generate a list of IPs from a network address or a name"""
-    name = "ip"
-    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])?$")
-    def __init__(self, net):
-        self.repr=net
-
-        tmp=net.split('/')+["32"]
-        if not self.ipaddress.match(net):
-            tmp[0]=socket.gethostbyname(tmp[0])
-        netmask = int(tmp[1])
-
-        def parse_digit(a,netmask):
-            netmask = min(8,max(netmask,0))
-            if a == "*":
-                a = (0,256)
-            elif a.find("-") >= 0:
-                x,y = map(int,a.split("-"))
-                if x > y:
-                    y = x
-                a = (x &  (0xffL<<netmask) , max(y, (x | (0xffL>>(8-netmask))))+1)
-            else:
-                a = (int(a) & (0xffL<<netmask),(int(a) | (0xffL>>(8-netmask)))+1)
-            return a
-
-        self.parsed = map(lambda x,y: parse_digit(x,y), tmp[0].split("."), map(lambda x,nm=netmask: x-nm, (8,16,24,32)))
-                                                                                               
-    def __iter__(self):
-        for d in xrange(*self.parsed[3]):
-            for c in xrange(*self.parsed[2]):
-                for b in xrange(*self.parsed[1]):
-                    for a in xrange(*self.parsed[0]):
-                        yield "%i.%i.%i.%i" % (a,b,c,d)
-    def choice(self):
-        ip = []
-        for v in self.parsed:
-            ip.append(str(random.randint(v[0],v[1]-1)))
-        return ".".join(ip) 
-                          
-    def __repr__(self):
-        return "Net(%r)" % self.repr
-
-class OID(Gen):
-    name = "OID"
-    def __init__(self, oid):
-        self.oid = oid        
-        self.cmpt = []
-        fmt = []        
-        for i in oid.split("."):
-            if "-" in i:
-                fmt.append("%i")
-                self.cmpt.append(tuple(map(int, i.split("-"))))
-            else:
-                fmt.append(i)
-        self.fmt = ".".join(fmt)
-    def __repr__(self):
-        return "OID(%r)" % self.oid
-    def __iter__(self):        
-        ii = [k[0] for k in self.cmpt]
-        while 1:
-            yield self.fmt % tuple(ii)
-            i = 0
-            while 1:
-                if i >= len(ii):
-                    raise StopIteration
-                if ii[i] < self.cmpt[i][1]:
-                    ii[i]+=1
-                    break
-                else:
-                    ii[i] = self.cmpt[i][0]
-                i += 1
- 
-
-#############
-## Results ##
-#############
-
-class PacketList:
-    res = []
-    def __init__(self, res=None, name="PacketList", stats=None):
-        """create a packet list from a list of packets
-           res: the list of packets
-           stats: a list of classes that will appear in the stats (defaults to [TCP,UDP,ICMP])"""
-        if stats is None:
-            stats = [ TCP,UDP,ICMP ]
-        self.stats = stats
-        if res is None:
-            res = []
-        if isinstance(res, PacketList):
-            res = res.res
-        self.res = res
-        self.listname = name
-    def _elt2pkt(self, elt):
-        return elt
-    def _elt2sum(self, elt):
-        return elt.summary()
-    def _elt2show(self, elt):
-        return self._elt2sum(elt)
-    def __repr__(self):
-#        stats=dict.fromkeys(self.stats,0) ## needs python >= 2.3  :(
-        stats = dict(map(lambda x: (x,0), self.stats))
-        other = 0
-        for r in self.res:
-            f = 0
-            for p in stats:
-                if self._elt2pkt(r).haslayer(p):
-                    stats[p] += 1
-                    f = 1
-                    break
-            if not f:
-                other += 1
-        s = ""
-        ct = conf.color_theme
-        for p in self.stats:
-            s += " %s%s%s" % (ct.packetlist_proto(p.name),
-                              ct.punct(":"),
-                              ct.packetlist_value(stats[p]))
-        s += " %s%s%s" % (ct.packetlist_proto("Other"),
-                          ct.punct(":"),
-                          ct.packetlist_value(other))
-        return "%s%s%s%s%s" % (ct.punct("<"),
-                               ct.packetlist_name(self.listname),
-                               ct.punct(":"),
-                               s,
-                               ct.punct(">"))
-    def __getattr__(self, attr):
-        return getattr(self.res, attr)
-    def __getitem__(self, item):
-        if isinstance(item,type) and issubclass(item,Packet):
-            return self.__class__(filter(lambda x: item in self._elt2pkt(x),self.res),
-                                  name="%s from %s"%(item.__name__,self.listname))
-        if type(item) is slice:
-            return self.__class__(self.res.__getitem__(item),
-                                  name = "mod %s" % self.listname)
-        return self.res.__getitem__(item)
-    def __getslice__(self, *args, **kargs):
-        return self.__class__(self.res.__getslice__(*args, **kargs),
-                              name="mod %s"%self.listname)
-    def __add__(self, other):
-        return self.__class__(self.res+other.res,
-                              name="%s+%s"%(self.listname,other.listname))
-    def summary(self, prn=None, lfilter=None):
-        """prints a summary of each packet
-prn:     function to apply to each packet instead of lambda x:x.summary()
-lfilter: truth function to apply to each packet to decide whether it will be displayed"""
-        for r in self.res:
-            if lfilter is not None:
-                if not lfilter(r):
-                    continue
-            if prn is None:
-                print self._elt2sum(r)
-            else:
-                print prn(r)
-    def nsummary(self,prn=None, lfilter=None):
-        """prints a summary of each packet with the packet's number
-prn:     function to apply to each packet instead of lambda x:x.summary()
-lfilter: truth function to apply to each packet to decide whether it will be displayed"""
-        for i in range(len(self.res)):
-            if lfilter is not None:
-                if not lfilter(self.res[i]):
-                    continue
-            print conf.color_theme.id(i,"%04i"),
-            if prn is None:
-                print self._elt2sum(self.res[i])
-            else:
-                print prn(self.res[i])
-    def display(self): # Deprecated. Use show()
-        """deprecated. is show()"""
-        self.show()
-    def show(self, *args, **kargs):
-        """Best way to display the packet list. Defaults to nsummary() method"""
-        return self.nsummary(*args, **kargs)
-    
-    def filter(self, func):
-        """Returns a packet list filtered by a truth function"""
-        return self.__class__(filter(func,self.res),
-                              name="filtered %s"%self.listname)
-    def make_table(self, *args, **kargs):
-        """Prints a table using a function that returs for each packet its head column value, head row value and displayed value
-        ex: p.make_table(lambda x:(x[IP].dst, x[TCP].dport, x[TCP].sprintf("%flags%")) """
-        return make_table(self.res, *args, **kargs)
-    def make_lined_table(self, *args, **kargs):
-        """Same as make_table, but print a table with lines"""
-        return make_lined_table(self.res, *args, **kargs)
-    def make_tex_table(self, *args, **kargs):
-        """Same as make_table, but print a table with LaTeX syntax"""
-        return make_tex_table(self.res, *args, **kargs)
-
-    def plot(self, f, lfilter=None,**kargs):
-        """Applies a function to each packet to get a value that will be plotted with GnuPlot. A gnuplot object is returned
-        lfilter: a truth function that decides whether a packet must be ploted"""
-        g=Gnuplot.Gnuplot()
-        l = self.res
-        if lfilter is not None:
-            l = filter(lfilter, l)
-        l = map(f,l)
-        g.plot(Gnuplot.Data(l, **kargs))
-        return g
-
-    def diffplot(self, f, delay=1, lfilter=None, **kargs):
-        """diffplot(f, delay=1, lfilter=None)
-        Applies a function to couples (l[i],l[i+delay])"""
-        g = Gnuplot.Gnuplot()
-        l = self.res
-        if lfilter is not None:
-            l = filter(lfilter, l)
-        l = map(f,l[:-delay],l[delay:])
-        g.plot(Gnuplot.Data(l, **kargs))
-        return g
-
-    def multiplot(self, f, lfilter=None, **kargs):
-        """Uses a function that returns a label and a value for this label, then plots all the values label by label"""
-        g=Gnuplot.Gnuplot()
-        l = self.res
-        if lfilter is not None:
-            l = filter(lfilter, l)
-
-        d={}
-        for e in l:
-            k,v = f(e)
-            if k in d:
-                d[k].append(v)
-            else:
-                d[k] = [v]
-        data=[]
-        for k in d:
-            data.append(Gnuplot.Data(d[k], title=k, **kargs))
-
-        g.plot(*data)
-        return g
-        
-
-    def rawhexdump(self):
-        """Prints an hexadecimal dump of each packet in the list"""
-        for p in self:
-            hexdump(self._elt2pkt(p))
-
-    def hexraw(self, lfilter=None):
-        """Same as nsummary(), except that if a packet has a Raw layer, it will be hexdumped
-        lfilter: a truth function that decides whether a packet must be displayed"""
-        for i in range(len(self.res)):
-            p = self._elt2pkt(self.res[i])
-            if lfilter is not None and not lfilter(p):
-                continue
-            print "%s %s %s" % (conf.color_theme.id(i,"%04i"),
-                                p.sprintf("%.time%"),
-                                self._elt2sum(self.res[i]))
-            if p.haslayer(Raw):
-                hexdump(p.getlayer(Raw).load)
-
-    def hexdump(self, lfilter=None):
-        """Same as nsummary(), except that packets are also hexdumped
-        lfilter: a truth function that decides whether a packet must be displayed"""
-        for i in range(len(self.res)):
-            p = self._elt2pkt(self.res[i])
-            if lfilter is not None and not lfilter(p):
-                continue
-            print "%s %s %s" % (conf.color_theme.id(i,"%04i"),
-                                p.sprintf("%.time%"),
-                                self._elt2sum(self.res[i]))
-            hexdump(p)
-
-    def padding(self, lfilter=None):
-        """Same as hexraw(), for Padding layer"""
-        for i in range(len(self.res)):
-            p = self._elt2pkt(self.res[i])
-            if p.haslayer(Padding):
-                if lfilter is None or lfilter(p):
-                    print "%s %s %s" % (conf.color_theme.id(i,"%04i"),
-                                        p.sprintf("%.time%"),
-                                        self._elt2sum(self.res[i]))
-                    hexdump(p.getlayer(Padding).load)
-
-    def nzpadding(self, lfilter=None):
-        """Same as padding() but only non null padding"""
-        for i in range(len(self.res)):
-            p = self._elt2pkt(self.res[i])
-            if p.haslayer(Padding):
-                pad = p.getlayer(Padding).load
-                if pad == pad[0]*len(pad):
-                    continue
-                if lfilter is None or lfilter(p):
-                    print "%s %s %s" % (conf.color_theme.id(i,"%04i"),
-                                        p.sprintf("%.time%"),
-                                        self._elt2sum(self.res[i]))
-                    hexdump(p.getlayer(Padding).load)
-        
-
-    def conversations(self, getsrcdst=None,**kargs):
-        """Graphes a conversations between sources and destinations and display it
-        (using graphviz and imagemagick)
-        getsrcdst: a function that takes an element of the list and return the source and dest
-                   by defaults, return source and destination IP
-        type: output type (svg, ps, gif, jpg, etc.), passed to dot's "-T" option
-        target: filename or redirect. Defaults pipe to Imagemagick's display program
-        prog: which graphviz program to use"""
-        if getsrcdst is None:
-            getsrcdst = lambda x:(x[IP].src, x[IP].dst)
-        conv = {}
-        for p in self.res:
-            p = self._elt2pkt(p)
-            try:
-                c = getsrcdst(p)
-            except:
-                #XXX warning()
-                continue
-            conv[c] = conv.get(c,0)+1
-        gr = 'digraph "conv" {\n'
-        for s,d in conv:
-            gr += '\t "%s" -> "%s"\n' % (s,d)
-        gr += "}\n"        
-        return do_graph(gr, **kargs)
-
-    def afterglow(self, src=None, event=None, dst=None, **kargs):
-        """Experimental clone attempt of http://sourceforge.net/projects/afterglow
-        each datum is reduced as src -> event -> dst and the data are graphed.
-        by default we have IP.src -> IP.dport -> IP.dst"""
-        if src is None:
-            src = lambda x: x[IP].src
-        if event is None:
-            event = lambda x: x[IP].dport
-        if dst is None:
-            dst = lambda x: x[IP].dst
-        sl = {}
-        el = {}
-        dl = {}
-        for i in self.res:
-            try:
-                s,e,d = src(i),event(i),dst(i)
-                if s in sl:
-                    n,l = sl[s]
-                    n += 1
-                    if e not in l:
-                        l.append(e)
-                    sl[s] = (n,l)
-                else:
-                    sl[s] = (1,[e])
-                if e in el:
-                    n,l = el[e]
-                    n+=1
-                    if d not in l:
-                        l.append(d)
-                    el[e] = (n,l)
-                else:
-                    el[e] = (1,[d])
-                dl[d] = dl.get(d,0)+1
-            except:
-                continue
-
-        import math
-        def normalize(n):
-            return 2+math.log(n)/4.0
-
-        def minmax(x):
-            m,M = min(x),max(x)
-            if m == M:
-                m = 0
-            if M == 0:
-                M = 1
-            return m,M
-
-        mins,maxs = minmax(map(lambda (x,y): x, sl.values()))
-        mine,maxe = minmax(map(lambda (x,y): x, el.values()))
-        mind,maxd = minmax(dl.values())
-    
-        gr = 'digraph "afterglow" {\n\tedge [len=2.5];\n'
-
-        gr += "# src nodes\n"
-        for s in sl:
-            n,l = sl[s]; n = 1+float(n-mins)/(maxs-mins)
-            gr += '"src.%s" [label = "%s", shape=box, fillcolor="#FF0000", style=filled, fixedsize=1, height=%.2f,width=%.2f];\n' % (`s`,`s`,n,n)
-        gr += "# event nodes\n"
-        for e in el:
-            n,l = el[e]; n = n = 1+float(n-mine)/(maxe-mine)
-            gr += '"evt.%s" [label = "%s", shape=circle, fillcolor="#00FFFF", style=filled, fixedsize=1, height=%.2f, width=%.2f];\n' % (`e`,`e`,n,n)
-        for d in dl:
-            n = dl[d]; n = n = 1+float(n-mind)/(maxd-mind)
-            gr += '"dst.%s" [label = "%s", shape=triangle, fillcolor="#0000ff", style=filled, fixedsize=1, height=%.2f, width=%.2f];\n' % (`d`,`d`,n,n)
-
-        gr += "###\n"
-        for s in sl:
-            n,l = sl[s]
-            for e in l:
-                gr += ' "src.%s" -> "evt.%s";\n' % (`s`,`e`) 
-        for e in el:
-            n,l = el[e]
-            for d in l:
-                gr += ' "evt.%s" -> "dst.%s";\n' % (`e`,`d`) 
-            
-        gr += "}"
-        open("/tmp/aze","w").write(gr)
-        return do_graph(gr, **kargs)
-        
-
-        
-    def timeskew_graph(self, ip, **kargs):
-        """Tries to graph the timeskew between the timestamps and real time for a given ip"""
-        res = map(lambda x: self._elt2pkt(x), self.res)
-        b = filter(lambda x:x.haslayer(IP) and x.getlayer(IP).src == ip and x.haslayer(TCP), res)
-        c = []
-        for p in b:
-            opts = p.getlayer(TCP).options
-            for o in opts:
-                if o[0] == "Timestamp":
-                    c.append((p.time,o[1][0]))
-        if not c:
-            warning("No timestamps found in packet list")
-            return
-        d = map(lambda (x,y): (x%2000,((x-c[0][0])-((y-c[0][1])/1000.0))),c)
-        g = Gnuplot.Gnuplot()
-        g.plot(Gnuplot.Data(d,**kargs))
-        return g
-        
-    def _dump_document(self, **kargs):
-        d = pyx.document.document()
-        l = len(self.res)
-        for i in range(len(self.res)):
-            elt = self.res[i]
-            c = self._elt2pkt(elt).canvas_dump(**kargs)
-            cbb = c.bbox()
-            c.text(cbb.left(),cbb.top()+1,r"\font\cmssfont=cmss12\cmssfont{Frame %i/%i}" % (i,l),[pyx.text.size.LARGE])
-            if conf.verb >= 2:
-                os.write(1,".")
-            d.append(pyx.document.page(c, paperformat=pyx.document.paperformat.A4,
-                                       margin=1*pyx.unit.t_cm,
-                                       fittosize=1))
-        return d
-                     
-                 
-
-    def psdump(self, filename = None, **kargs):
-        """Creates a multipage poscript file with a psdump of every packet
-        filename: name of the file to write to. If empty, a temporary file is used and
-                  conf.prog.psreader is called"""
-        d = self._dump_document(**kargs)
-        if filename is None:
-            filename = "/tmp/scapy.psd.%i" % os.getpid()
-            d.writePSfile(filename)
-            os.system("%s %s.ps &" % (conf.prog.psreader,filename))
-        else:
-            d.writePSfile(filename)
-        print
-        
-    def pdfdump(self, filename = None, **kargs):
-        """Creates a PDF file with a psdump of every packet
-        filename: name of the file to write to. If empty, a temporary file is used and
-                  conf.prog.pdfreader is called"""
-        d = self._dump_document(**kargs)
-        if filename is None:
-            filename = "/tmp/scapy.psd.%i" % os.getpid()
-            d.writePDFfile(filename)
-            os.system("%s %s.pdf &" % (conf.prog.pdfreader,filename))
-        else:
-            d.writePDFfile(filename)
-        print
-
-    def sr(self,multi=0):
-        """sr([multi=1]) -> (SndRcvList, PacketList)
-        Matches packets in the list and return ( (matched couples), (unmatched packets) )"""
-        remain = self.res[:]
-        sr = []
-        i = 0
-        while i < len(remain):
-            s = remain[i]
-            j = i
-            while j < len(remain)-1:
-                j += 1
-                r = remain[j]
-                if r.answers(s):
-                    sr.append((s,r))
-                    if multi:
-                        remain[i]._answered=1
-                        remain[j]._answered=2
-                        continue
-                    del(remain[j])
-                    del(remain[i])
-                    i -= 1
-                    break
-            i += 1
-        if multi:
-            remain = filter(lambda x:not hasattr(x,"_answered"), remain)
-        return SndRcvList(sr),PacketList(remain)
-        
-
-
-        
-
-
-class Dot11PacketList(PacketList):
-    def __init__(self, res=None, name="Dot11List", stats=None):
-        if stats is None:
-            stats = [Dot11WEP, Dot11Beacon, UDP, ICMP, TCP]
-
-        PacketList.__init__(self, res, name, stats)
-    def toEthernet(self):
-        data = map(lambda x:x.getlayer(Dot11), filter(lambda x : x.haslayer(Dot11) and x.type == 2, self.res))
-        r2 = []
-        for p in data:
-            q = p.copy()
-            q.unwep()
-            r2.append(Ether()/q.payload.payload.payload) #Dot11/LLC/SNAP/IP
-        return PacketList(r2,name="Ether from %s"%self.listname)
-        
-        
-
-class SndRcvList(PacketList):
-    def __init__(self, res=None, name="Results", stats=None):
-        PacketList.__init__(self, res, name, stats)
-    def _elt2pkt(self, elt):
-        return elt[1]
-    def _elt2sum(self, elt):
-        return "%s ==> %s" % (elt[0].summary(),elt[1].summary()) 
-
-
-class ARPingResult(SndRcvList):
-    def __init__(self, res=None, name="ARPing", stats=None):
-        PacketList.__init__(self, res, name, stats)
-
-    def show(self):
-        for s,r in self.res:
-            print r.sprintf("%Ether.src% %ARP.psrc%")
-
-
-class AS_resolver:
-    server = None
-    options = "-k" 
-    def __init__(self, server=None, port=43, options=None):
-        if server is not None:
-            self.server = server
-        self.port = port
-        if options is not None:
-            self.options = options
-        
-    def _start(self):
-        self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-        self.s.connect((self.server,self.port))
-        if self.options:
-            self.s.send(self.options+"\n")
-            self.s.recv(8192)
-    def _stop(self):
-        self.s.close()
-        
-    def _parse_whois(self, txt):
-        asn,desc = None,""
-        for l in txt.splitlines():
-            if not asn and l.startswith("origin:"):
-                asn = l[7:].strip()
-            if l.startswith("descr:"):
-                if desc:
-                    desc += r"\n"
-                desc += l[6:].strip()
-            if asn is not None and desc:
-                break
-        return asn,desc.strip()
-
-    def _resolve_one(self, ip):
-        self.s.send("%s\n" % ip)
-        x = ""
-        while not ("%" in x  or "source" in x):
-            x += self.s.recv(8192)
-        asn, desc = self._parse_whois(x)
-        return ip,asn,desc
-    def resolve(self, *ips):
-        self._start()
-        ret = []
-        for ip in ips:
-            ip,asn,desc = self._resolve_one(ip)
-            if asn is not None:
-                ret.append((ip,asn,desc))
-        self._stop()
-        return ret
-
-class AS_resolver_riswhois(AS_resolver):
-    server = "riswhois.ripe.net"
-    options = "-k -M -1"
-
-
-class AS_resolver_radb(AS_resolver):
-    server = "whois.ra.net"
-    options = "-k -M"
-    
-
-class AS_resolver_cymru(AS_resolver):
-    server = "whois.cymru.com"
-    options = None
-    def resolve(self, *ips):
-        ASNlist = []
-        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-        s.connect((self.server,self.port))
-        s.send("begin\r\n"+"\r\n".join(ips)+"\r\nend\r\n")
-        r = ""
-        while 1:
-            l = s.recv(8192)
-            if l == "":
-                break
-            r += l
-        s.close()
-        for l in r.splitlines()[1:]:
-            if "|" not in l:
-                continue
-            asn,ip,desc = map(str.strip, l.split("|"))
-            if asn == "NA":
-                continue
-            asn = int(asn)
-            ASNlist.append((ip,asn,desc))
-        return ASNlist
-
-class AS_resolver_multi(AS_resolver):
-    resolvers_list = ( AS_resolver_cymru(),AS_resolver_riswhois(),AS_resolver_radb() )
-    def __init__(self, *reslist):
-        if reslist:
-            self.resolvers_list = reslist
-    def resolve(self, *ips):
-        todo = ips
-        ret = []
-        for ASres in self.resolvers_list:
-            res = ASres.resolve(*todo)
-            resolved = [ ip for ip,asn,desc in res ]
-            todo = [ ip for ip in todo if ip not in resolved ]
-            ret += res
-        return ret
-    
-    
-
-class TracerouteResult(SndRcvList):
-    def __init__(self, res=None, name="Traceroute", stats=None):
-        PacketList.__init__(self, res, name, stats)
-        self.graphdef = None
-        self.graphASres = 0
-        self.padding = 0
-        self.hloc = None
-        self.nloc = None
-
-    def show(self):
-        return self.make_table(lambda (s,r): (s.sprintf("%IP.dst%:{TCP:tcp%ir,TCP.dport%}{UDP:udp%ir,UDP.dport%}{ICMP:ICMP}"),
-                                              s.ttl,
-                                              r.sprintf("%-15s,IP.src% {TCP:%TCP.flags%}{ICMP:%ir,ICMP.type%}")))
-
-
-    def get_trace(self):
-        trace = {}
-        for s,r in self.res:
-            if IP not in s:
-                continue
-            d = s[IP].dst
-            if d not in trace:
-                trace[d] = {}
-            trace[d][s[IP].ttl] = r[IP].src, ICMP not in r
-        for k in trace.values():
-            m = filter(lambda x:k[x][1], k.keys())
-            if not m:
-                continue
-            m = min(m)
-            for l in k.keys():
-                if l > m:
-                    del(k[l])
-        return trace
-
-    def trace3D(self):
-        """Give a 3D representation of the traceroute.
-        right button: rotate the scene
-        middle button: zoom
-        left button: move the scene
-        left button on a ball: toggle IP displaying
-        ctrl-left button on a ball: scan ports 21,22,23,25,80 and 443 and display the result"""
-        trace = self.get_trace()
-        import visual
-
-        class IPsphere(visual.sphere):
-            def __init__(self, ip, **kargs):
-                visual.sphere.__init__(self, **kargs)
-                self.ip=ip
-                self.label=None
-                self.setlabel(self.ip)
-            def setlabel(self, txt,visible=None):
-                if self.label is not None:
-                    if visible is None:
-                        visible = self.label.visible
-                    self.label.visible = 0
-                elif visible is None:
-                    visible=0
-                self.label=visual.label(text=txt, pos=self.pos, space=self.radius, xoffset=10, yoffset=20, visible=visible)
-            def action(self):
-                self.label.visible ^= 1
-
-        visual.scene = visual.display()
-        visual.scene.exit_on_close(0)
-        start = visual.box()
-        rings={}
-        tr3d = {}
-        for i in trace:
-            tr = trace[i]
-            tr3d[i] = []
-            ttl = tr.keys()
-            for t in range(1,max(ttl)+1):
-                if t not in rings:
-                    rings[t] = []
-                if t in tr:
-                    if tr[t] not in rings[t]:
-                        rings[t].append(tr[t])
-                    tr3d[i].append(rings[t].index(tr[t]))
-                else:
-                    rings[t].append(("unk",-1))
-                    tr3d[i].append(len(rings[t])-1)
-        for t in rings:
-            r = rings[t]
-            l = len(r)
-            for i in range(l):
-                if r[i][1] == -1:
-                    col = (0.75,0.75,0.75)
-                elif r[i][1]:
-                    col = visual.color.green
-                else:
-                    col = visual.color.blue
-                
-                s = IPsphere(pos=((l-1)*visual.cos(2*i*visual.pi/l),(l-1)*visual.sin(2*i*visual.pi/l),2*t),
-                             ip = r[i][0],
-                             color = col)
-                for trlst in tr3d.values():
-                    if t <= len(trlst):
-                        if trlst[t-1] == i:
-                            trlst[t-1] = s
-        forecol = colgen(0.625, 0.4375, 0.25, 0.125)
-        for trlst in tr3d.values():
-            col = forecol.next()
-            start = (0,0,0)
-            for ip in trlst:
-                visual.cylinder(pos=start,axis=ip.pos-start,color=col,radius=0.2)
-                start = ip.pos
-        
-        movcenter=None
-        while 1:
-            if visual.scene.kb.keys:
-                k = visual.scene.kb.getkey()
-                if k == "esc":
-                    break
-            if visual.scene.mouse.events:
-                ev = visual.scene.mouse.getevent()
-                if ev.press == "left":
-                    o = ev.pick
-                    if o:
-                        if ev.ctrl:
-                            if o.ip == "unk":
-                                continue
-                            savcolor = o.color
-                            o.color = (1,0,0)
-                            a,b=sr(IP(dst=o.ip)/TCP(dport=[21,22,23,25,80,443]),timeout=2)
-                            o.color = savcolor
-                            if len(a) == 0:
-                                txt = "%s:\nno results" % o.ip
-                            else:
-                                txt = "%s:\n" % o.ip
-                                for s,r in a:
-                                    txt += r.sprintf("{TCP:%IP.src%:%TCP.sport% %TCP.flags%}{TCPerror:%IPerror.dst%:%TCPerror.dport% %IP.src% %ir,ICMP.type%}\n")
-                            o.setlabel(txt, visible=1)
-                        else:
-                            if hasattr(o, "action"):
-                                o.action()
-                elif ev.drag == "left":
-                    movcenter = ev.pos
-                elif ev.drop == "left":
-                    movcenter = None
-            if movcenter:
-                visual.scene.center -= visual.scene.mouse.pos-movcenter
-                movcenter = visual.scene.mouse.pos
-                
-                
-    def world_trace(self):
-        ips = {}
-        rt = {}
-        ports_done = {}
-        for s,r in self.res:
-            ips[r.src] = None
-            if s.haslayer(TCP) or s.haslayer(UDP):
-                trace_id = (s.src,s.dst,s.proto,s.dport)
-            elif s.haslayer(ICMP):
-                trace_id = (s.src,s.dst,s.proto,s.type)
-            else:
-                trace_id = (s.src,s.dst,s.proto,0)
-            trace = rt.get(trace_id,{})
-            if not r.haslayer(ICMP) or r.type != 11:
-                if ports_done.has_key(trace_id):
-                    continue
-                ports_done[trace_id] = None
-            trace[s.ttl] = r.src
-            rt[trace_id] = trace
-
-        trt = {}
-        for trace_id in rt:
-            trace = rt[trace_id]
-            loctrace = []
-            for i in range(max(trace.keys())):
-                ip = trace.get(i,None)
-                if ip is None:
-                    continue
-                loc = locate_ip(ip)
-                if loc is None:
-                    continue
-#                loctrace.append((ip,loc)) # no labels yet
-                loctrace.append(loc)
-            if loctrace:
-                trt[trace_id] = loctrace
-
-        tr = map(lambda x: Gnuplot.Data(x,with="lines"), trt.values())
-        g = Gnuplot.Gnuplot()
-        world = Gnuplot.File(conf.gnuplot_world,with="lines")
-        g.plot(world,*tr)
-        return g
-
-    def make_graph(self,ASres=None,padding=0):
-        if ASres is None:
-            ASres = conf.AS_resolver
-        self.graphASres = ASres
-        self.graphpadding = padding
-        ips = {}
-        rt = {}
-        ports = {}
-        ports_done = {}
-        for s,r in self.res:
-            r = r[IP] or r[IPv6] or r
-            s = s[IP] or s[IPv6] or s
-            ips[r.src] = None
-            if TCP in s:
-                trace_id = (s.src,s.dst,6,s.dport)
-            elif UDP in s:
-                trace_id = (s.src,s.dst,17,s.dport)
-            elif ICMP in s:
-                trace_id = (s.src,s.dst,1,s.type)
-            else:
-                trace_id = (s.src,s.dst,s.proto,0)
-            trace = rt.get(trace_id,{})
-            ttl = IPv6 in s and s.hlim or s.ttl
-            if not (ICMP in r and r[ICMP].type == 11) and not (IPv6 in r and ICMPv6TimeExceeded in r):
-                if trace_id in ports_done:
-                    continue
-                ports_done[trace_id] = None
-                p = ports.get(r.src,[])
-                if TCP in r:
-                    p.append(r.sprintf("<T%ir,TCP.sport%> %TCP.sport% %TCP.flags%"))
-                    trace[ttl] = r.sprintf('"%r,src%":T%ir,TCP.sport%')
-                elif UDP in r:
-                    p.append(r.sprintf("<U%ir,UDP.sport%> %UDP.sport%"))
-                    trace[ttl] = r.sprintf('"%r,src%":U%ir,UDP.sport%')
-                elif ICMP in r:
-                    p.append(r.sprintf("<I%ir,ICMP.type%> ICMP %ICMP.type%"))
-                    trace[ttl] = r.sprintf('"%r,src%":I%ir,ICMP.type%')
-                else:
-                    p.append(r.sprintf("{IP:<P%ir,proto%> IP %proto%}{IPv6:<P%ir,nh%> IPv6 %nh%}"))
-                    trace[ttl] = r.sprintf('"%r,src%":{IP:P%ir,proto%}{IPv6:P%ir,nh%}')
-                ports[r.src] = p
-            else:
-                trace[ttl] = r.sprintf('"%r,src%"')
-            rt[trace_id] = trace
-    
-        # Fill holes with unk%i nodes
-        unknown_label = incremental_label("unk%i")
-        blackholes = []
-        bhip = {}
-        for rtk in rt:
-            trace = rt[rtk]
-            k = trace.keys()
-            for n in range(min(k), max(k)):
-                if not trace.has_key(n):
-                    trace[n] = unknown_label.next()
-            if not ports_done.has_key(rtk):
-                if rtk[2] == 1: #ICMP
-                    bh = "%s %i/icmp" % (rtk[1],rtk[3])
-                elif rtk[2] == 6: #TCP
-                    bh = "%s %i/tcp" % (rtk[1],rtk[3])
-                elif rtk[2] == 17: #UDP                    
-                    bh = '%s %i/udp' % (rtk[1],rtk[3])
-                else:
-                    bh = '%s %i/proto' % (rtk[1],rtk[2]) 
-                ips[bh] = None
-                bhip[rtk[1]] = bh
-                bh = '"%s"' % bh
-                trace[max(k)+1] = bh
-                blackholes.append(bh)
-    
-        # Find AS numbers
-        ASN_query_list = dict.fromkeys(map(lambda x:x.rsplit(" ",1)[0],ips)).keys()
-        if ASres is None:            
-            ASNlist = []
-        else:
-            ASNlist = ASres.resolve(*ASN_query_list)            
-    
-        ASNs = {}
-        ASDs = {}
-        for ip,asn,desc, in ASNlist:
-            if asn is None:
-                continue
-            iplist = ASNs.get(asn,[])
-            if ip in bhip:
-                if ip in ports:
-                    iplist.append(ip)
-                iplist.append(bhip[ip])
-            else:
-                iplist.append(ip)
-            ASNs[asn] = iplist
-            ASDs[asn] = desc
-    
-    
-        backcolorlist=colgen("60","86","ba","ff")
-        forecolorlist=colgen("a0","70","40","20")
-    
-        s = "digraph trace {\n"
-    
-        s += "\n\tnode [shape=ellipse,color=black,style=solid];\n\n"
-    
-        s += "\n#ASN clustering\n"
-        for asn in ASNs:
-            s += '\tsubgraph cluster_%s {\n' % asn
-            col = backcolorlist.next()
-            s += '\t\tcolor="#%s%s%s";' % col
-            s += '\t\tnode [fillcolor="#%s%s%s",style=filled];' % col
-            s += '\t\tfontsize = 10;'
-            s += '\t\tlabel = "%s\\n[%s]"\n' % (asn,ASDs[asn])
-            for ip in ASNs[asn]:
-    
-                s += '\t\t"%s";\n'%ip
-            s += "\t}\n"
-    
-    
-    
-    
-        s += "#endpoints\n"
-        for p in ports:
-            s += '\t"%s" [shape=record,color=black,fillcolor=green,style=filled,label="%s|%s"];\n' % (p,p,"|".join(ports[p]))
-    
-        s += "\n#Blackholes\n"
-        for bh in blackholes:
-            s += '\t%s [shape=octagon,color=black,fillcolor=red,style=filled];\n' % bh
-
-        if padding:
-            s += "\n#Padding\n"
-            pad={}
-            for snd,rcv in self.res:
-                if rcv.src not in ports and rcv.haslayer(Padding):
-                    p = rcv.getlayer(Padding).load
-                    if p != "\x00"*len(p):
-                        pad[rcv.src]=None
-            for rcv in pad:
-                s += '\t"%s" [shape=triangle,color=black,fillcolor=red,style=filled];\n' % rcv
-    
-    
-            
-        s += "\n\tnode [shape=ellipse,color=black,style=solid];\n\n"
-    
-    
-        for rtk in rt:
-            s += "#---[%s\n" % `rtk`
-            s += '\t\tedge [color="#%s%s%s"];\n' % forecolorlist.next()
-            trace = rt[rtk]
-            k = trace.keys()
-            for n in range(min(k), max(k)):
-                s += '\t%s ->\n' % trace[n]
-            s += '\t%s;\n' % trace[max(k)]
-    
-        s += "}\n";
-        self.graphdef = s
-    
-    def graph(self, ASres=None, padding=0, **kargs):
-        """x.graph(ASres=conf.AS_resolver, other args):
-        ASres=None          : no AS resolver => no clustering
-        ASres=AS_resolver() : default whois AS resolver (riswhois.ripe.net)
-        ASres=AS_resolver_cymru(): use whois.cymru.com whois database
-        ASres=AS_resolver(server="whois.ra.net")
-        type: output type (svg, ps, gif, jpg, etc.), passed to dot's "-T" option
-        target: filename or redirect. Defaults pipe to Imagemagick's display program
-        prog: which graphviz program to use"""
-        if ASres is None:
-            ASres = conf.AS_resolver
-        if (self.graphdef is None or
-            self.graphASres != ASres or
-            self.graphpadding != padding):
-            self.make_graph(ASres,padding)
-
-        return do_graph(self.graphdef, **kargs)
-
-
-        
-    
-############
-## Fields ##
-############
-
-class Field:
-    """For more informations on how this work, please refer to
-       http://www.secdev.org/projects/scapy/files/scapydoc.pdf
-       chapter ``Adding a New Field''"""
-    islist=0
-    holds_packets=0
-    def __init__(self, name, default, fmt="H"):
-        self.name = name
-        if fmt[0] in "@=<>!":
-            self.fmt = fmt
-        else:
-            self.fmt = "!"+fmt
-        self.default = self.any2i(None,default)
-        self.sz = struct.calcsize(self.fmt)
-        self.owners = []
-
-    def register_owner(self, cls):
-        self.owners.append(cls)
-
-    def i2len(self, pkt, x):
-        """Convert internal value to a length usable by a FieldLenField"""
-        return self.sz
-    def i2count(self, pkt, x):
-        """Convert internal value to a number of elements usable by a FieldLenField.
-        Always 1 except for list fields"""
-        return 1
-    def h2i(self, pkt, x):
-        """Convert human value to internal value"""
-        return x
-    def i2h(self, pkt, x):
-        """Convert internal value to human value"""
-        return x
-    def m2i(self, pkt, x):
-        """Convert machine value to internal value"""
-        return x
-    def i2m(self, pkt, x):
-        """Convert internal value to machine value"""
-        if x is None:
-            x = 0
-        return x
-    def any2i(self, pkt, x):
-        """Try to understand the most input values possible and make an internal value from them"""
-        return self.h2i(pkt, x)
-    def i2repr(self, pkt, x):
-        """Convert internal value to a nice representation"""
-        if x is None:
-            x = 0
-        return repr(self.i2h(pkt,x))
-    def addfield(self, pkt, s, val):
-        """Add an internal value  to a string"""
-        return s+struct.pack(self.fmt, self.i2m(pkt,val))
-    def getfield(self, pkt, s):
-        """Extract an internal value from a string"""
-        return  s[self.sz:], self.m2i(pkt, struct.unpack(self.fmt, s[:self.sz])[0])
-    def do_copy(self, x):
-        if hasattr(x, "copy"):
-            return x.copy()
-        if type(x) is list:
-            x = x[:]
-            for i in xrange(len(x)):
-                if isinstance(x[i], Packet):
-                    x[i] = x[i].copy()
-        return x
-    def __repr__(self):
-        return "<Field (%s).%s>" % (",".join(x.__name__ for x in self.owners),self.name)
-    def copy(self):
-        return copy.deepcopy(self)
-    def randval(self):
-        """Return a volatile object whose value is both random and suitable for this field"""
-        fmtt = self.fmt[-1]
-        if fmtt in "BHIQ":
-            return {"B":RandByte,"H":RandShort,"I":RandInt, "Q":RandLong}[fmtt]()
-        elif fmtt == "s":
-            if self.fmt[0] in "0123456789":
-                l = int(self.fmt[:-1])
-            else:
-                l = int(self.fmt[1:-1])
-            return RandBin(l)
-        else:
-            warning("no random class for [%s] (fmt=%s)." % (self.name, self.fmt))
-            
-
-
-
-class Emph:
-    fld = ""
-    def __init__(self, fld):
-        self.fld = fld
-    def __getattr__(self, attr):
-        return getattr(self.fld,attr)
-    def __hash__(self):
-        return hash(self.fld)
-    def __eq__(self, other):
-        return self.fld == other
-    
-
-class ActionField:
-    _fld = None
-    def __init__(self, fld, action_method, **kargs):
-        self._fld = fld
-        self._action_method = action_method
-        self._privdata = kargs
-    def any2i(self, pkt, val):
-        getattr(pkt, self._action_method)(val, self._fld, **self._privdata)
-        return getattr(self._fld, "any2i")(pkt, val)
-    def __getattr__(self, attr):
-        return getattr(self._fld,attr)
-
-
-class ConditionalField:
-    fld = None
-    def __init__(self, fld, cond):
-        self.fld = fld
-        self.cond = cond
-    def _evalcond(self,pkt):
-        return self.cond(pkt)
-        
-    def getfield(self, pkt, s):
-        if self._evalcond(pkt):
-            return self.fld.getfield(pkt,s)
-        else:
-            return s,None
-        
-    def addfield(self, pkt, s, val):
-        if self._evalcond(pkt):
-            return self.fld.addfield(pkt,s,val)
-        else:
-            return s
-    def __getattr__(self, attr):
-        return getattr(self.fld,attr)
-        
-
-class PadField:
-    """Add bytes after the proxified field so that it ends at the specified
-       alignment from its begining"""
-    _fld = None
-    def __init__(self, fld, align, padwith=None):
-        self._fld = fld
-        self._align = align
-        self._padwith = padwith or ""
-
-    def addfield(self, pkt, s, val):
-        sval = self._fld.addfield(pkt, "", val)
-        return s+sval+struct.pack("%is" % (-len(sval)%self._align), self._padwith)
-    
-    def __getattr__(self, attr):
-        return getattr(self._fld,attr)
-        
-
-class MACField(Field):
-    def __init__(self, name, default):
-        Field.__init__(self, name, default, "6s")
-    def i2m(self, pkt, x):
-        if x is None:
-            return "\0\0\0\0\0\0"
-        return mac2str(x)
-    def m2i(self, pkt, x):
-        return str2mac(x)
-    def any2i(self, pkt, x):
-        if type(x) is str and len(x) is 6:
-            x = self.m2i(pkt, x)
-        return x
-    def i2repr(self, pkt, x):
-        x = self.i2h(pkt, x)
-        if self in conf.resolve:
-            x = conf.manufdb._resolve_MAC(x)
-        return x
-    def randval(self):
-        return RandMAC()
-
-class DestMACField(MACField):
-    def __init__(self, name):
-        MACField.__init__(self, name, None)
-    def i2h(self, pkt, x):
-        if x is None:
-            dstip = None
-            if isinstance(pkt.payload, IPv6):
-                dstip = pkt.payload.dst            
-            elif isinstance(pkt.payload, IP):
-                dstip = pkt.payload.dst
-            elif isinstance(pkt.payload, ARP):
-                dstip = pkt.payload.pdst
-            if isinstance(dstip, Gen):
-                dstip = dstip.__iter__().next()
-            if dstip is not None:
-                if isinstance(pkt.payload, IPv6):
-                    x = getmacbyip6(dstip, chainCC=1)
-                else:    
-                    x = getmacbyip(dstip, chainCC=1)
-            if x is None:
-                x = "ff:ff:ff:ff:ff:ff"
-                warning("Mac address to reach %s not found\n"%dstip)
-        return MACField.i2h(self, pkt, x)
-    def i2m(self, pkt, x):
-        return MACField.i2m(self, pkt, self.i2h(pkt, x))
-        
-class SourceMACField(MACField):
-    def __init__(self, name):
-        MACField.__init__(self, name, None)
-    def i2h(self, pkt, x):
-        if x is None:
-            dstip = None
-            if isinstance(pkt.payload, IPv6):
-                dstip = pkt.payload.dst
-            elif isinstance(pkt.payload, IP):
-                dstip = pkt.payload.dst
-            elif isinstance(pkt.payload, ARP):
-                dstip = pkt.payload.pdst
-            if isinstance(dstip, Gen):
-                dstip = dstip.__iter__().next()
-            if dstip is not None:
-                if isinstance(pkt.payload, IPv6):
-                    iff,a,nh = conf.route6.route(dstip)
-                else:
-                    iff,a,gw = conf.route.route(dstip)
-                try:
-                    x = get_if_hwaddr(iff)
-                except:
-                    pass
-                if x is None:
-                    x = "00:00:00:00:00:00"
-        return MACField.i2h(self, pkt, x)
-    def i2m(self, pkt, x):
-        return MACField.i2m(self, pkt, self.i2h(pkt, x))
-        
-class ARPSourceMACField(MACField):
-    def __init__(self, name):
-        MACField.__init__(self, name, None)
-    def i2h(self, pkt, x):
-        if x is None:
-            dstip = pkt.pdst
-            if isinstance(dstip, Gen):
-                dstip = dstip.__iter__().next()
-            if dstip is not None:
-                iff,a,gw = conf.route.route(dstip)
-                try:
-                    x = get_if_hwaddr(iff)
-                except:
-                    pass
-                if x is None:
-                    x = "00:00:00:00:00:00"
-        return MACField.i2h(self, pkt, x)
-    def i2m(self, pkt, x):
-        return MACField.i2m(self, pkt, self.i2h(pkt, x))
-
-class Dot11AddrMACField(MACField):
-    def is_applicable(self, pkt):
-        return 1
-    def addfield(self, pkt, s, val):
-        if self.is_applicable(pkt):
-            return MACField.addfield(self, pkt, s, val)
-        else:
-            return s        
-    def getfield(self, pkt, s):
-        if self.is_applicable(pkt):
-            return MACField.getfield(self, pkt, s)
-        else:
-            return s,None
-
-class Dot11Addr2MACField(Dot11AddrMACField):
-    def is_applicable(self, pkt):
-        if pkt.type == 1:
-            return pkt.subtype in [ 0xb, 0xa, 0xe, 0xf] # RTS, PS-Poll, CF-End, CF-End+CF-Ack
-        return 1
-
-class Dot11Addr3MACField(Dot11AddrMACField):
-    def is_applicable(self, pkt):
-        if pkt.type in [0,2]:
-            return 1
-        return 0
-
-class Dot11Addr4MACField(Dot11AddrMACField):
-    def is_applicable(self, pkt):
-        if pkt.type == 2:
-            if pkt.FCfield & 0x3 == 0x3: # To-DS and From-DS are set
-                return 1
-        return 0
-    
-class IPField(Field):
-    def __init__(self, name, default):
-        Field.__init__(self, name, default, "4s")
-    def h2i(self, pkt, x):
-        if type(x) is str:
-            try:
-                inet_aton(x)
-            except socket.error:
-                x = Net(x)
-        elif type(x) is list:
-            x = [self.h2i(pkt, n) for n in x] 
-        return x
-    def resolve(self, x):
-        if self in conf.resolve:
-            try:
-                ret = socket.gethostbyaddr(x)[0]
-            except:
-                pass
-            else:
-                if ret:
-                    return ret
-        return x
-    def i2m(self, pkt, x):
-        return inet_aton(x)
-    def m2i(self, pkt, x):
-        return inet_ntoa(x)
-    def any2i(self, pkt, x):
-        return self.h2i(pkt,x)
-    def i2repr(self, pkt, x):
-        return self.resolve(self.i2h(pkt, x))
-    def randval(self):
-        return RandIP()
-
-class SourceIPField(IPField):
-    def __init__(self, name, dstname):
-        IPField.__init__(self, name, None)
-        self.dstname = dstname
-    def i2m(self, pkt, x):
-        if x is None:
-            iff,x,gw = conf.route.route(getattr(pkt,self.dstname))
-        return IPField.i2m(self, pkt, x)
-    def i2h(self, pkt, x):
-        if x is None:
-            dst=getattr(pkt,self.dstname)
-            if isinstance(dst,Gen):
-                r = map(conf.route.route, dst)
-                r.sort()
-                if r[0] == r[-1]:
-                    x=r[0][1]
-                else:
-                    warning("More than one possible route for %s"%repr(dst))
-                    return None
-            else:
-                iff,x,gw = conf.route.route(dst)
-        return IPField.i2h(self, pkt, x)
-
-    
-
-
-class ByteField(Field):
-    def __init__(self, name, default):
-        Field.__init__(self, name, default, "B")
-        
-class XByteField(ByteField):
-    def i2repr(self, pkt, x):
-        if x is None:
-            x = 0
-        return lhex(self.i2h(pkt, x))
-
-class X3BytesField(XByteField):
-    def __init__(self, name, default):
-        Field.__init__(self, name, default, "!I")
-    def addfield(self, pkt, s, val):
-        return s+struct.pack(self.fmt, self.i2m(pkt,val))[1:4]
-    def getfield(self, pkt, s):
-        return  s[3:], self.m2i(pkt, struct.unpack(self.fmt, "\x00"+s[:3])[0])
-
-
-class ShortField(Field):
-    def __init__(self, name, default):
-        Field.__init__(self, name, default, "H")
-
-class LEShortField(Field):
-    def __init__(self, name, default):
-        Field.__init__(self, name, default, "<H")
-
-class XShortField(ShortField):
-    def i2repr(self, pkt, x):
-        if x is None:
-            x = 0
-        return lhex(self.i2h(pkt, x))
-
-
-class IntField(Field):
-    def __init__(self, name, default):
-        Field.__init__(self, name, default, "I")
-
-class SignedIntField(Field):
-    def __init__(self, name, default):
-        Field.__init__(self, name, default, "i")
-    def randval(self):
-        return RandSInt()
-
-class LEIntField(Field):
-    def __init__(self, name, default):
-        Field.__init__(self, name, default, "<I")
-
-class LESignedIntField(Field):
-    def __init__(self, name, default):
-        Field.__init__(self, name, default, "<i")
-    def randval(self):
-        return RandSInt()
-
-class XIntField(IntField):
-    def i2repr(self, pkt, x):
-        if x is None:
-            x = 0
-        return lhex(self.i2h(pkt, x))
-
-
-class LongField(Field):
-    def __init__(self, name, default):
-        Field.__init__(self, name, default, "Q")
-
-class XLongField(LongField):
-    def i2repr(self, pkt, x):
-        if x is None:
-            x = 0
-        return lhex(self.i2h(pkt, x))
-
-class IEEEFloatField(Field):
-    def __init__(self, name, default):
-        Field.__init__(self, name, default, "f")
-
-class IEEEDoubleField(Field):
-    def __init__(self, name, default):
-        Field.__init__(self, name, default, "d")
-
-
-def FIELD_LENGTH_MANAGEMENT_DEPRECATION(x):
-    try:
-        for tb in traceback.extract_stack()+[("??",-1,None,"")]:
-            f,l,_,line = tb
-            if line.startswith("fields_desc"):
-                break
-    except:
-        f,l="??",-1
-    log_loading.warning("Deprecated use of %s (%s l. %i). See http://trac.secdev.org/scapy/wiki/LengthFields" % (x,f,l))
-
-class StrField(Field):
-    def __init__(self, name, default, fmt="H", remain=0, shift=0):
-        Field.__init__(self,name,default,fmt)
-        self.remain = remain        
-        self.shift = shift
-        if shift != 0:
-            FIELD_LENGTH_MANAGEMENT_DEPRECATION(self.__class__.__name__)
-    def i2len(self, pkt, i):
-        return len(i)+self.shift
-    def i2m(self, pkt, x):
-        if x is None:
-            x = ""
-        return x
-    def addfield(self, pkt, s, val):
-        return s+self.i2m(pkt, val)
-    def getfield(self, pkt, s):
-        if self.remain == 0:
-            return "",self.m2i(pkt, s)
-        else:
-            return s[-self.remain:],self.m2i(pkt, s[:-self.remain])
-    def randval(self):
-        return RandBin(RandNum(0,1200))
-
-class PacketField(StrField):
-    holds_packets=1
-    def __init__(self, name, default, cls, remain=0, shift=0):
-        StrField.__init__(self, name, default, remain=remain, shift=shift)
-        self.cls = cls
-    def i2m(self, pkt, i):
-        return str(i)
-    def m2i(self, pkt, m):
-        return self.cls(m)
-    def getfield(self, pkt, s):
-        i = self.m2i(pkt, s)
-        remain = ""
-        if i.haslayer(Padding):
-            r = i.getlayer(Padding)
-            del(r.underlayer.payload)
-            remain = r.load
-        return remain,i
-    
-class PacketLenField(PacketField):
-    holds_packets=1
-    def __init__(self, name, default, cls, fld=None, length_from=None, shift=0):
-        PacketField.__init__(self, name, default, cls, shift=shift)
-        self.length_from = length_from
-        if fld is not None or shift != 0:
-            FIELD_LENGTH_MANAGEMENT_DEPRECATION(self.__class__.__name__)
-            self.count_from = lambda pkt,fld=fld,shift=shift: getattr(pkt,fld)-shift
-    def getfield(self, pkt, s):
-        l = self.length_from(pkt)
-        i = self.m2i(pkt, s[:l])
-        return s[l:],i
-
-
-class PacketListField(PacketField):
-    islist = 1
-    holds_packets=1
-    def __init__(self, name, default, cls, fld=None, count_from=None, length_from=None, shift=0):
-        if default is None:
-            default = []  # Create a new list for each instance
-        PacketField.__init__(self, name, default, cls, shift=shift)
-        self.count_from = count_from
-        self.length_from = length_from
-
-        if fld is not None or shift != 0:
-            FIELD_LENGTH_MANAGEMENT_DEPRECATION(self.__class__.__name__)
-        if fld is not None:
-            self.count_from = lambda pkt,fld=fld,shift=shift: getattr(pkt,fld)-shift
-
-    def any2i(self, pkt, x):
-        if type(x) is not list:
-            return [x]
-        else:
-            return x
-    def i2count(self, pkt, val):
-        if type(val) is list:
-            return len(val)
-        return 1
-    def i2len(self, pkt, val):
-        return sum( len(p) for p in val )
-    def do_copy(self, x):
-        return map(lambda p:p.copy(), x)
-    def getfield(self, pkt, s):
-        c = l = None
-        if self.length_from is not None:
-            l = self.length_from(pkt)
-        elif self.count_from is not None:
-            c = self.count_from(pkt)
-            
-        lst = []
-        ret = ""
-        remain = s
-        if l is not None:
-            remain,ret = s[:l],s[l:]
-        while remain:
-            if c is not None:
-                if c <= 0:
-                    break
-                c -= 1
-            p = self.m2i(pkt,remain)
-            if Padding in p:
-                pad = p[Padding]
-                remain = pad.load
-                del(pad.underlayer.payload)
-            else:
-                remain = ""
-            lst.append(p)
-        return remain+ret,lst
-    def addfield(self, pkt, s, val):
-        return s+"".join(map(str, val))
-
-
-class StrFixedLenField(StrField):
-    def __init__(self, name, default, length=None, length_from=None, shift=0):
-        StrField.__init__(self, name, default, shift=shift)
-        self.length_from  = length_from
-        if length is not None:
-            self.length_from = lambda pkt,length=length: length
-    def getfield(self, pkt, s):
-        l = self.length_from(pkt)
-        return s[l:], self.m2i(pkt,s[:l])
-    def addfield(self, pkt, s, val):
-        l = self.length_from(pkt)
-        return s+struct.pack("%is"%l,self.i2m(pkt, val))
-    def randval(self):
-        try:
-            l = self.length_from(None)
-        except:
-            l = RandNum(0,200)
-        return RandBin(l)
-
-class NetBIOSNameField(StrFixedLenField):
-    def __init__(self, name, default, length=31, shift=0):
-        StrFixedLenField.__init__(self, name, default, length, shift=shift)
-    def i2m(self, pkt, x):
-        l = self.length_from(pkt)/2
-        if x is None:
-            x = ""
-        x += " "*(l)
-        x = x[:l]
-        x = "".join(map(lambda x: chr(0x41+(ord(x)>>4))+chr(0x41+(ord(x)&0xf)), x))
-        x = " "+x
-        return x
-    def m2i(self, pkt, x):
-        x = x.strip("\x00").strip(" ")
-        return "".join(map(lambda x,y: chr((((ord(x)-1)&0xf)<<4)+((ord(y)-1)&0xf)), x[::2],x[1::2]))
-
-class StrLenField(StrField):
-    def __init__(self, name, default, fld=None, length_from=None, shift=0):
-        StrField.__init__(self, name, default, shift=shift)
-        self.length_from = length_from
-        if fld is not None or shift != 0:
-            FIELD_LENGTH_MANAGEMENT_DEPRECATION(self.__class__.__name__)
-            self.length_from = lambda pkt,fld=fld,shift=shift: getattr(pkt,fld)-shift
-    def getfield(self, pkt, s):
-        l = self.length_from(pkt)
-        return s[l:], self.m2i(pkt,s[:l])
-
-class FieldListField(Field):
-    islist=1
-    def __init__(self, name, default, field, fld=None, shift=0, length_from=None, count_from=None):
-        if default is None:
-            default = []  # Create a new list for each instance
-        Field.__init__(self, name, default)
-        self.count_from = count_from
-        self.length_from = length_from
-        self.field = field
-        if fld is not None or shift != 0:
-            FIELD_LENGTH_MANAGEMENT_DEPRECATION(self.__class__.__name__)
-            self.count_from = lambda pkt,fld=fld,shift=shift: getattr(pkt,fld)-shift
-            
-            
-    def i2count(self, pkt, val):
-        if type(val) is list:
-            return len(val)
-        return 1
-    def i2len(self, pkt, val):
-        return sum( self.field.i2len(pkt,v) for v in val )
-    
-    def i2m(self, pkt, val):
-        if val is None:
-            val = []
-        return val
-    def any2i(self, pkt, x):
-        if type(x) is not list:
-            return [x]
-        else:
-            return x
-    def addfield(self, pkt, s, val):
-        val = self.i2m(pkt, val)
-        for v in val:
-            s = self.field.addfield(pkt, s, v)
-        return s
-    def getfield(self, pkt, s):
-        c = l = None
-        if self.length_from is not None:
-            l = self.length_from(pkt)
-        elif self.count_from is not None:
-            c = self.count_from(pkt)
-
-        val = []
-        ret=""
-        if l is not None:
-            s,ret = s[:l],s[l:]
-            
-        while s:
-            if c is not None:
-                if c <= 0:
-                    break
-                c -= 1
-            s,v = self.field.getfield(pkt, s)
-            val.append(v)
-        return s+ret, val
-
-class FieldLenField(Field):
-    def __init__(self, name, default,  length_of=None, fmt = "H", count_of=None, adjust=lambda pkt,x:x, fld=None):
-        Field.__init__(self, name, default, fmt)
-        self.length_of=length_of
-        self.count_of=count_of
-        self.adjust=adjust
-        if fld is not None:
-            FIELD_LENGTH_MANAGEMENT_DEPRECATION(self.__class__.__name__)
-            self.length_of = fld
-    def i2m(self, pkt, x):
-        if x is None:
-            if self.length_of is not None:
-                fld,fval = pkt.getfield_and_val(self.length_of)
-                f = fld.i2len(pkt, fval)
-            else:
-                fld,fval = pkt.getfield_and_val(self.count_of)
-                f = fld.i2count(pkt, fval)
-            x = self.adjust(pkt,f)
-        return x
-
-# see http://www.iana.org/assignments/ipsec-registry for details
-ISAKMPAttributeTypes= { "Encryption":    (1, { "DES-CBC"  : 1,
-                                                "IDEA-CBC" : 2,
-                                                "Blowfish-CBC" : 3,
-                                                "RC5-R16-B64-CBC" : 4,
-                                                "3DES-CBC" : 5, 
-                                                "CAST-CBC" : 6, 
-                                                "AES-CBC" : 7, 
-                                                "CAMELLIA-CBC" : 8, }, 0),
-                         "Hash":          (2, { "MD5": 1,
-                                                "SHA": 2,
-                                                "Tiger": 3,
-                                                "SHA2-256": 4,
-                                                "SHA2-384": 5,
-                                                "SHA2-512": 6,}, 0),
-                         "Authentication":(3, { "PSK": 1, 
-                                                "DSS": 2,
-                                                "RSA Sig": 3,
-                                                "RSA Encryption": 4,
-                                                "RSA Encryption Revised": 5,
-                                                "ElGamal Encryption": 6,
-                                                "ElGamal Encryption Revised": 7,
-                                                "ECDSA Sig": 8,
-                                                "HybridInitRSA": 64221,
-                                                "HybridRespRSA": 64222,
-                                                "HybridInitDSS": 64223,
-                                                "HybridRespDSS": 64224,
-                                                "XAUTHInitPreShared": 65001,
-                                                "XAUTHRespPreShared": 65002,
-                                                "XAUTHInitDSS": 65003,
-                                                "XAUTHRespDSS": 65004,
-                                                "XAUTHInitRSA": 65005,
-                                                "XAUTHRespRSA": 65006,
-                                                "XAUTHInitRSAEncryption": 65007,
-                                                "XAUTHRespRSAEncryption": 65008,
-                                                "XAUTHInitRSARevisedEncryption": 65009,
-                                                "XAUTHRespRSARevisedEncryptio": 65010, }, 0),
-                         "GroupDesc":     (4, { "768MODPgr"  : 1,
-                                                "1024MODPgr" : 2, 
-                                                "EC2Ngr155"  : 3,
-                                                "EC2Ngr185"  : 4,
-                                                "1536MODPgr" : 5, 
-                                                "2048MODPgr" : 14, 
-                                                "3072MODPgr" : 15, 
-                                                "4096MODPgr" : 16, 
-                                                "6144MODPgr" : 17, 
-                                                "8192MODPgr" : 18, }, 0),
-                         "GroupType":      (5,  {"MODP":       1,
-                                                 "ECP":        2,
-                                                 "EC2N":       3}, 0),
-                         "GroupPrime":     (6,  {}, 1),
-                         "GroupGenerator1":(7,  {}, 1),
-                         "GroupGenerator2":(8,  {}, 1),
-                         "GroupCurveA":    (9,  {}, 1),
-                         "GroupCurveB":    (10, {}, 1),
-                         "LifeType":       (11, {"Seconds":     1,
-                                                 "Kilobytes":   2,  }, 0),
-                         "LifeDuration":   (12, {}, 1),
-                         "PRF":            (13, {}, 0),
-                         "KeyLength":      (14, {}, 0),
-                         "FieldSize":      (15, {}, 0),
-                         "GroupOrder":     (16, {}, 1),
-                         }
-
-# the name 'ISAKMPTransformTypes' is actually a misnomer (since the table 
-# holds info for all ISAKMP Attribute types, not just transforms, but we'll 
-# keep it for backwards compatibility... for now at least
-ISAKMPTransformTypes = ISAKMPAttributeTypes
-
-ISAKMPTransformNum = {}
-for n in ISAKMPTransformTypes:
-    val = ISAKMPTransformTypes[n]
-    tmp = {}
-    for e in val[1]:
-        tmp[val[1][e]] = e
-    ISAKMPTransformNum[val[0]] = (n,tmp, val[2])
-del(n)
-del(e)
-del(tmp)
-del(val)
-
-
-class ISAKMPTransformSetField(StrLenField):
-    islist=1
-    def type2num(self, (typ,val)):
-        type_val,enc_dict,tlv = ISAKMPTransformTypes.get(typ, (typ,{},0))
-        val = enc_dict.get(val, val)
-        s = ""
-        if (val & ~0xffff):
-            if not tlv:
-                warning("%r should not be TLV but is too big => using TLV encoding" % typ)
-            n = 0
-            while val:
-                s = chr(val&0xff)+s
-                val >>= 8
-                n += 1
-            val = n
-        else:
-            type_val |= 0x8000
-        return struct.pack("!HH",type_val, val)+s
-    def num2type(self, typ, enc):
-        val = ISAKMPTransformNum.get(typ,(typ,{}))
-        enc = val[1].get(enc,enc)
-        return (val[0],enc)
-    def i2m(self, pkt, i):
-        if i is None:
-            return ""
-        i = map(self.type2num, i)
-        return "".join(i)
-    def m2i(self, pkt, m):
-        # I try to ensure that we don't read off the end of our packet based
-        # on bad length fields we're provided in the packet. There are still
-        # conditions where struct.unpack() may not get enough packet data, but
-        # worst case that should result in broken attributes (which would
-        # be expected). (wam)
-        lst = []
-        while len(m) >= 4:
-            trans_type, = struct.unpack("!H", m[:2])
-            is_tlv = not (trans_type & 0x8000)
-            if is_tlv:
-                # We should probably check to make sure the attribute type we
-                # are looking at is allowed to have a TLV format and issue a 
-                # warning if we're given an TLV on a basic attribute.
-                value_len, = struct.unpack("!H", m[2:4])
-                if value_len+4 > len(m):
-                    warning("Bad length for ISAKMP tranform type=%#6x" % trans_type)
-                value = m[4:4+value_len]
-                value = reduce(lambda x,y: (x<<8L)|y, struct.unpack("!%s" % ("B"*len(value),), value),0)
-            else:
-                trans_type &= 0x7fff
-                value_len=0
-                value, = struct.unpack("!H", m[2:4])
-            m=m[4+value_len:]
-            lst.append(self.num2type(trans_type, value))
-        if len(m) > 0:
-            warning("Extra bytes after ISAKMP transform dissection [%r]" % m)
-        return lst
-
-class StrNullField(StrField):
-    def addfield(self, pkt, s, val):
-        return s+self.i2m(pkt, val)+"\x00"
-    def getfield(self, pkt, s):
-        l = s.find("\x00")
-        if l < 0:
-            #XXX \x00 not found
-            return "",s
-        return s[l+1:],self.m2i(pkt, s[:l])
-    def randval(self):
-        return RandTermString(RandNum(0,1200),"\x00")
-
-class StrStopField(StrField):
-    def __init__(self, name, default, stop, additionnal=0):
-        Field.__init__(self, name, default)
-        self.stop=stop
-        self.additionnal=additionnal
-    def getfield(self, pkt, s):
-        l = s.find(self.stop)
-        if l < 0:
-            return "",s
-#            raise Scapy_Exception,"StrStopField: stop value [%s] not found" %stop
-        l += len(self.stop)+self.additionnal
-        return s[l:],s[:l]
-    def randval(self):
-        return RandTermString(RandNum(0,1200),self.stop)
-
-class LenField(Field):
-    def i2m(self, pkt, x):
-        if x is None:
-            x = len(pkt.payload)
-        return x
-
-class BCDFloatField(Field):
-    def i2m(self, pkt, x):
-        return int(256*x)
-    def m2i(self, pkt, x):
-        return x/256.0
-
-class BitField(Field):
-    def __init__(self, name, default, size):
-        Field.__init__(self, name, default)
-        self.rev = size < 0 
-        self.size = abs(size)
-    def reverse(self, val):
-        if self.size == 16:
-            val = socket.ntohs(val)
-        elif self.size == 32:
-            val = socket.ntohl(val)
-        return val
-        
-    def addfield(self, pkt, s, val):
-        val = self.i2m(pkt, val)
-        if type(s) is tuple:
-            s,bitsdone,v = s
-        else:
-            bitsdone = 0
-            v = 0
-        if self.rev:
-            val = self.reverse(val)
-        v <<= self.size
-        v |= val & ((1L<<self.size) - 1)
-        bitsdone += self.size
-        while bitsdone >= 8:
-            bitsdone -= 8
-            s = s+struct.pack("!B", v >> bitsdone)
-            v &= (1L<<bitsdone)-1
-        if bitsdone:
-            return s,bitsdone,v
-        else:
-            return s
-    def getfield(self, pkt, s):
-        if type(s) is tuple:
-            s,bn = s
-        else:
-            bn = 0
-        # we don't want to process all the string
-        nb_bytes = (self.size+bn-1)/8 + 1
-        w = s[:nb_bytes]
-
-        # split the substring byte by byte
-        bytes = struct.unpack('!%dB' % nb_bytes , w)
-
-        b = 0L
-        for c in range(nb_bytes):
-            b |= long(bytes[c]) << (nb_bytes-c-1)*8
-
-        # get rid of high order bits
-        b &= (1L << (nb_bytes*8-bn)) - 1
-
-        # remove low order bits
-        b = b >> (nb_bytes*8 - self.size - bn)
-
-        if self.rev:
-            b = self.reverse(b)
-
-        bn += self.size
-        s = s[bn/8:]
-        bn = bn%8
-        b = self.m2i(pkt, b)
-        if bn:
-            return (s,bn),b
-        else:
-            return s,b
-    def randval(self):
-        return RandNum(0,2**self.size-1)
-
-
-class BitFieldLenField(BitField):
-    def __init__(self, name, default, size, length_of=None, count_of=None, adjust=lambda pkt,x:x):
-        BitField.__init__(self, name, default, size)
-        self.length_of=length_of
-        self.count_of=count_of
-        self.adjust=adjust
-    def i2m(self, pkt, x):
-        return FieldLenField.i2m.im_func(self, pkt, x)
-
-
-class XBitField(BitField):
-    def i2repr(self, pkt, x):
-        return lhex(self.i2h(pkt,x))
-
-
-class EnumField(Field):
-    def __init__(self, name, default, enum, fmt = "H"):
-        i2s = self.i2s = {}
-        s2i = self.s2i = {}
-        if type(enum) is list:
-            keys = xrange(len(enum))
-        else:
-            keys = enum.keys()
-        if filter(lambda x: type(x) is str, keys):
-            i2s,s2i = s2i,i2s
-        for k in keys:
-            i2s[k] = enum[k]
-            s2i[enum[k]] = k
-        Field.__init__(self, name, default, fmt)
-    def any2i_one(self, pkt, x):
-        if type(x) is str:
-            x = self.s2i[x]
-        return x
-    def i2repr_one(self, pkt, x):
-        if self not in conf.noenum and not isinstance(x,VolatileValue) and x in self.i2s:
-            return self.i2s[x]
-        return repr(x)
-    
-    def any2i(self, pkt, x):
-        if type(x) is list:
-            return map(lambda z,pkt=pkt:self.any2i_one(pkt,z), x)
-        else:
-            return self.any2i_one(pkt,x)        
-    def i2repr(self, pkt, x):
-        if type(x) is list:
-            return map(lambda z,pkt=pkt:self.i2repr_one(pkt,z), x)
-        else:
-            return self.i2repr_one(pkt,x)
-
-class CharEnumField(EnumField):
-    def __init__(self, name, default, enum, fmt = "1s"):
-        EnumField.__init__(self, name, default, enum, fmt)
-        k = self.i2s.keys()
-        if k and len(k[0]) != 1:
-            self.i2s,self.s2i = self.s2i,self.i2s
-    def any2i_one(self, pkt, x):
-        if len(x) != 1:
-            x = self.s2i[x]
-        return x
-
-class BitEnumField(BitField,EnumField):
-    def __init__(self, name, default, size, enum):
-        EnumField.__init__(self, name, default, enum)
-        self.rev = size < 0
-        self.size = abs(size)
-    def any2i(self, pkt, x):
-        return EnumField.any2i(self, pkt, x)
-    def i2repr(self, pkt, x):
-        return EnumField.i2repr(self, pkt, x)
-
-class ShortEnumField(EnumField):
-    def __init__(self, name, default, enum):
-        EnumField.__init__(self, name, default, enum, "H")
-
-class LEShortEnumField(EnumField):
-    def __init__(self, name, default, enum):
-        EnumField.__init__(self, name, default, enum, "<H")
-
-class ByteEnumField(EnumField):
-    def __init__(self, name, default, enum):
-        EnumField.__init__(self, name, default, enum, "B")
-
-class IntEnumField(EnumField):
-    def __init__(self, name, default, enum):
-        EnumField.__init__(self, name, default, enum, "I")
-
-class SignedIntEnumField(EnumField):
-    def __init__(self, name, default, enum):
-        EnumField.__init__(self, name, default, enum, "i")
-    def randval(self):
-        return RandSInt()
-
-class LEIntEnumField(EnumField):
-    def __init__(self, name, default, enum):
-        EnumField.__init__(self, name, default, enum, "<I")
-
-class XShortEnumField(ShortEnumField):
-    def i2repr_one(self, pkt, x):
-        if self not in conf.noenum and not isinstance(x,VolatileValue) and x in self.i2s:
-            return self.i2s[x]
-        return lhex(x)
-
-# Little endian long field
-class LELongField(Field):
-    def __init__(self, name, default):
-        Field.__init__(self, name, default, "<Q")
-
-# Little endian fixed length field
-class LEFieldLenField(FieldLenField):
-    def __init__(self, name, default,  length_of=None, fmt = "<H", count_of=None, adjust=lambda pkt,x:x, fld=None):
-        FieldLenField.__init__(self, name, default, length_of=length_of, fmt=fmt, fld=fld, adjust=adjust)
-
-
-class FlagsField(BitField):
-    def __init__(self, name, default, size, names):
-        BitField.__init__(self, name, default, size)
-        self.multi = type(names) is list
-        if self.multi:
-            self.names = map(lambda x:[x], names)
-        else:
-            self.names = names
-    def any2i(self, pkt, x):
-        if type(x) is str:
-            if self.multi:
-                x = map(lambda y:[y], x.split("+"))
-            y = 0
-            for i in x:
-                y |= 1 << self.names.index(i)
-            x = y
-        return x
-    def i2repr(self, pkt, x):
-        if type(x) is list or type(x) is tuple:
-            return repr(x)
-        if self.multi:
-            r = []
-        else:
-            r = ""
-        i=0
-        while x:
-            if x & 1:
-                r += self.names[i]
-            i += 1
-            x >>= 1
-        if self.multi:
-            r = "+".join(r)
-        return r
-
-            
-
-
-
-class IPoptionsField(StrField):
-    def i2m(self, pkt, x):
-        return x+"\x00"*(3-((len(x)+3)%4))
-    def getfield(self, pkt, s):
-        opsz = (pkt.ihl-5)*4
-        if opsz < 0:
-            warning("bad ihl (%i). Assuming ihl=5"%pkt.ihl)
-            opsz = 0
-        return s[opsz:],s[:opsz]
-    def randval(self):
-        return RandBin(RandNum(0,39))
-
-
-TCPOptions = (
-              { 0 : ("EOL",None),
-                1 : ("NOP",None),
-                2 : ("MSS","!H"),
-                3 : ("WScale","!B"),
-                4 : ("SAckOK",None),
-                5 : ("SAck","!"),
-                8 : ("Timestamp","!II"),
-                14 : ("AltChkSum","!BH"),
-                15 : ("AltChkSumOpt",None)
-                },
-              { "EOL":0,
-                "NOP":1,
-                "MSS":2,
-                "WScale":3,
-                "SAckOK":4,
-                "SAck":5,
-                "Timestamp":8,
-                "AltChkSum":14,
-                "AltChkSumOpt":15,
-                } )
-
-class TCPOptionsField(StrField):
-    islist=1
-    def getfield(self, pkt, s):
-        opsz = (pkt.dataofs-5)*4
-        if opsz < 0:
-            warning("bad dataofs (%i). Assuming dataofs=5"%pkt.dataofs)
-            opsz = 0
-        return s[opsz:],self.m2i(pkt,s[:opsz])
-    def m2i(self, pkt, x):
-        opt = []
-        while x:
-            onum = ord(x[0])
-            if onum == 0:
-                opt.append(("EOL",None))
-                x=x[1:]
-                break
-            if onum == 1:
-                opt.append(("NOP",None))
-                x=x[1:]
-                continue
-            olen = ord(x[1])
-            if olen < 2:
-                warning("Malformed TCP option (announced length is %i)" % olen)
-                olen = 2
-            oval = x[2:olen]
-            if TCPOptions[0].has_key(onum):
-                oname, ofmt = TCPOptions[0][onum]
-                if onum == 5: #SAck
-                    ofmt += "%iI" % (len(oval)/4)
-                if ofmt and struct.calcsize(ofmt) == len(oval):
-                    oval = struct.unpack(ofmt, oval)
-                    if len(oval) == 1:
-                        oval = oval[0]
-                opt.append((oname, oval))
-            else:
-                opt.append((onum, oval))
-            x = x[olen:]
-        return opt
-    
-    def i2m(self, pkt, x):
-        opt = ""
-        for oname,oval in x:
-            if type(oname) is str:
-                if oname == "NOP":
-                    opt += "\x01"
-                    continue
-                elif oname == "EOL":
-                    opt += "\x00"
-                    continue
-                elif TCPOptions[1].has_key(oname):
-                    onum = TCPOptions[1][oname]
-                    ofmt = TCPOptions[0][onum][1]
-                    if onum == 5: #SAck
-                        ofmt += "%iI" % len(oval)
-                    if ofmt is not None and (type(oval) is not str or "s" in ofmt):
-                        if type(oval) is not tuple:
-                            oval = (oval,)
-                        oval = struct.pack(ofmt, *oval)
-                else:
-                    warning("option [%s] unknown. Skipped."%oname)
-                    continue
-            else:
-                onum = oname
-                if type(oval) is not str:
-                    warning("option [%i] is not string."%onum)
-                    continue
-            opt += chr(onum)+chr(2+len(oval))+oval
-        return opt+"\x00"*(3-((len(opt)+3)%4))
-    def randval(self):
-        return [] # XXX
-    
-
-class DNSStrField(StrField):
-    def i2m(self, pkt, x):
-        x = [k[:63] for k in x.split(".")] # Truncate chunks that cannont be encoded (more than 63 bytes..)
-        x = map(lambda y: chr(len(y))+y, x)
-        x = "".join(x)
-        if x[-1] != "\x00":
-            x += "\x00"
-        return x
-    def getfield(self, pkt, s):
-        n = ""
-        while 1:
-            l = ord(s[0])
-            s = s[1:]
-            if not l:
-                break
-            if l & 0xc0:
-                raise Scapy_Exception("DNS message can't be compressed at this point!")
-            else:
-                n += s[:l]+"."
-                s = s[l:]
-        return s, n
-
-
-class DNSRRCountField(ShortField):
-    holds_packets=1
-    def __init__(self, name, default, rr):
-        ShortField.__init__(self, name, default)
-        self.rr = rr
-    def _countRR(self, pkt):
-        x = getattr(pkt,self.rr)
-        i = 0
-        while isinstance(x, DNSRR) or isinstance(x, DNSQR):
-            x = x.payload
-            i += 1
-        return i
-        
-    def i2m(self, pkt, x):
-        if x is None:
-            x = self._countRR(pkt)
-        return x
-    def i2h(self, pkt, x):
-        if x is None:
-            x = self._countRR(pkt)
-        return x
-    
-
-def DNSgetstr(s,p):
-    name = ""
-    q = 0
-    jpath = [p]
-    while 1:
-        if p >= len(s):
-            warning("DNS RR prematured end (ofs=%i, len=%i)"%(p,len(s)))
-            break
-        l = ord(s[p])
-        p += 1
-        if l & 0xc0:
-            if not q:
-                q = p+1
-            if p >= len(s):
-                warning("DNS incomplete jump token at (ofs=%i)" % p)
-                break
-            p = ((l & 0x3f) << 8) + ord(s[p]) - 12
-            if p in jpath:
-                warning("DNS decompression loop detected")
-                break
-            jpath.append(p)
-            continue
-        elif l > 0:
-            name += s[p:p+l]+"."
-            p += l
-            continue
-        break
-    if q:
-        p = q
-    return name,p
-        
-
-class DNSRRField(StrField):
-    holds_packets=1
-    def __init__(self, name, countfld, passon=1):
-        StrField.__init__(self, name, None)
-        self.countfld = countfld
-        self.passon = passon
-    def i2m(self, pkt, x):
-        if x is None:
-            return ""
-        return str(x)
-    def decodeRR(self, name, s, p):
-        ret = s[p:p+10]
-        type,cls,ttl,rdlen = struct.unpack("!HHIH", ret)
-        p += 10
-        rr = DNSRR("\x00"+ret+s[p:p+rdlen])
-        if rr.type in [2, 3, 4, 5]:
-            rr.rdata = DNSgetstr(s,p)[0]
-        del(rr.rdlen)
-        
-        p += rdlen
-        
-        rr.rrname = name
-        return rr,p
-    def getfield(self, pkt, s):
-        if type(s) is tuple :
-            s,p = s
-        else:
-            p = 0
-        ret = None
-        c = getattr(pkt, self.countfld)
-        if c > len(s):
-            warning("wrong value: DNS.%s=%i" % (self.countfld,c))
-            return s,""
-        while c:
-            c -= 1
-            name,p = DNSgetstr(s,p)
-            rr,p = self.decodeRR(name, s, p)
-            if ret is None:
-                ret = rr
-            else:
-                ret.add_payload(rr)
-        if self.passon:
-            return (s,p),ret
-        else:
-            return s[p:],ret
-            
-            
-class DNSQRField(DNSRRField):
-    holds_packets=1
-    def decodeRR(self, name, s, p):
-        ret = s[p:p+4]
-        p += 4
-        rr = DNSQR("\x00"+ret)
-        rr.qname = name
-        return rr,p
-        
-        
-
-class RDataField(StrLenField):
-    def m2i(self, pkt, s):
-        family = None
-        if pkt.type == 1:
-            family = socket.AF_INET
-        elif pkt.type == 28:
-            family = socket.AF_INET6
-        elif pkt.type == 12:
-            s = DNSgetstr(s, 0)[0]
-        if family is not None:    
-            s = inet_ntop(family, s)
-        return s
-    def i2m(self, pkt, s):
-        if pkt.type == 1:
-            if s:
-                s = inet_aton(s)
-        elif pkt.type == 28:
-            if s:
-                s = inet_pton(socket.AF_INET6, s)
-        elif pkt.type in [2,3,4,5]:
-            s = "".join(map(lambda x: chr(len(x))+x, s.split(".")))
-            if ord(s[-1]):
-                s += "\x00"
-        return s
-
-class RDLenField(Field):
-    def __init__(self, name):
-        Field.__init__(self, name, None, "H")
-    def i2m(self, pkt, x):
-        if x is None:
-            rdataf = pkt.get_field("rdata")
-            x = len(rdataf.i2m(pkt, pkt.rdata))
-        return x
-    def i2h(self, pkt, x):
-        if x is None:
-            rdataf = pkt.get_field("rdata")
-            x = len(rdataf.i2m(pkt, pkt.rdata))
-        return x
-    
-# seconds between 01-01-1900 and 01-01-1970
-ntp_basetime = 2208988800
-
-class TimeStampField(BitField):
-    def __init__(self, name, default, size):
-        BitField.__init__(self, name, default, size)
-        self.size  = size
-    def getfield(self, pkt, s):
-        s,timestamp = BitField.getfield(self, pkt, s)
-
-        if timestamp:
-            # timestamp is a 64 bits field :
-            #  + first 32 bits : number of seconds since 1900
-            #  + last 32 bits  : fraction part
-            timestamp >>= 32
-            timestamp -= ntp_basetime
-            
-            from time import gmtime, strftime
-            b = strftime("%a, %d %b %Y %H:%M:%S +0000", gmtime(timestamp))
-        else:
-            b = 'None'
-        
-        return s, b
-    def addfield(self, pkt, s, val):
-        t = -1
-        if type(val) is str:
-            from time import strptime, mktime
-            t = int(mktime(strptime(val))) + ntp_basetime + 3600
-        else:
-            if val == -1:
-                from time import time
-                t = int(time()) + ntp_basetime
-            else:
-                t = val
-        t <<= 32
-        return BitField.addfield(self,pkt,s, t)
-
-class ICMPTimeStampField(IntField):
-    re_hmsm = re.compile("([0-2]?[0-9])[Hh:](([0-5]?[0-9])([Mm:]([0-5]?[0-9])([sS:.]([0-9]{0,3}))?)?)?$")
-    def i2repr(self, pkt, val):
-        if val is None:
-            return "--"
-        else:
-            sec, milli = divmod(val, 1000)
-            min, sec = divmod(sec, 60)
-            hour, min = divmod(min, 60)
-            return "%d:%d:%d.%d" %(hour, min, sec, int(milli))
-    def any2i(self, pkt, val):
-        if type(val) is str:
-            hmsms = self.re_hmsm.match(val)
-            if hmsms:
-                h,_,m,_,s,_,ms = hmsms = hmsms.groups()
-                ms = int(((ms or "")+"000")[:3])
-                val = ((int(h)*60+int(m or 0))*60+int(s or 0))*1000+ms
-            else:
-                val = 0
-        elif val is None:
-            val = int((time.time()%(24*60*60))*1000)
-        return val
-
-class FloatField(BitField):
-    def getfield(self, pkt, s):
-        s,b = BitField.getfield(self, pkt, s)
-        
-        # fraction point between bits 15 and 16.
-        sec = b >> 16
-        frac = b & (1L << (32+1)) - 1
-        frac /= 65536.0
-        b = sec+frac
-        return s,b    
-
-class Dot11SCField(LEShortField):
-    def is_applicable(self, pkt):
-        return pkt.type != 1 # control frame
-    def addfield(self, pkt, s, val):
-        if self.is_applicable(pkt):
-            return LEShortField.addfield(self, pkt, s, val)
-        else:
-            return s
-    def getfield(self, pkt, s):
-        if self.is_applicable(pkt):
-            return LEShortField.getfield(self, pkt, s)
-        else:
-            return s,None
-
-#####################
-#### ASN1 Fields ####
-#####################
-
-class ASN1F_badsequence(Exception):
-    pass
-
-class ASN1F_element:
-    pass
-
-class ASN1F_optionnal(ASN1F_element):
-    def __init__(self, field):
-        self._field=field
-    def __getattr__(self, attr):
-        return getattr(self._field,attr)
-    def dissect(self,pkt,s):
-        try:
-            return self._field.dissect(pkt,s)
-        except ASN1F_badsequence:
-            self._field.set_val(pkt,None)
-            return s
-        except BER_Decoding_Error:
-            self._field.set_val(pkt,None)
-            return s
-    def build(self, pkt):
-        if self._field.is_empty(pkt):
-            return ""
-        return self._field.build(pkt)
-
-class ASN1F_field(ASN1F_element):
-    holds_packets=0
-    islist=0
-
-    ASN1_tag = ASN1_Class_UNIVERSAL.ANY
-    context=ASN1_Class_UNIVERSAL
-    
-    def __init__(self, name, default, context=None):
-        if context is not None:
-            self.context = context
-        self.name = name
-        self.default = default
-
-    def i2repr(self, pkt, x):
-        if x is None:
-            x = 0
-        return repr(x)
-    def i2h(self, pkt, x):
-        return x
-    def any2i(self, pkt, x):
-        return x
-    def m2i(self, pkt, x):
-        return self.ASN1_tag.get_codec(pkt.ASN1_codec).safedec(x, context=self.context)
-    def i2m(self, pkt, x):
-        if x is None:
-            x = 0
-        if isinstance(x, ASN1_Object):
-            if ( self.ASN1_tag == ASN1_Class_UNIVERSAL.ANY
-                 or x.tag == ASN1_Class_UNIVERSAL.RAW
-                 or x.tag == ASN1_Class_UNIVERSAL.ERROR
-                 or self.ASN1_tag == x.tag ):
-                return x.enc(pkt.ASN1_codec)
-            else:
-                raise ASN1_Error("Encoding Error: got %r instead of an %r for field [%s]" % (x, self.ASN1_tag, self.name))
-        return self.ASN1_tag.get_codec(pkt.ASN1_codec).enc(x)
-
-    def do_copy(self, x):
-        if hasattr(x, "copy"):
-            return x.copy()
-        if type(x) is list:
-            x = x[:]
-            for i in xrange(len(x)):
-                if isinstance(x[i], Packet):
-                    x[i] = x[i].copy()
-        return x
-
-    def build(self, pkt):
-        return self.i2m(pkt, getattr(pkt, self.name))
-
-    def set_val(self, pkt, val):
-        setattr(pkt, self.name, val)
-    def is_empty(self, pkt):
-        return getattr(pkt,self.name) is None
-    
-    def dissect(self, pkt, s):
-        v,s = self.m2i(pkt, s)
-        self.set_val(pkt, v)
-        return s
-
-    def get_fields_list(self):
-        return [self]
-
-    def __hash__(self):
-        return hash(self.name)
-    def __str__(self):
-        return self.name
-    def __eq__(self, other):
-        return self.name == other
-    def __repr__(self):
-        return self.name
-    def randval(self):
-        return RandInt()
-
-
-class ASN1F_INTEGER(ASN1F_field):
-    ASN1_tag= ASN1_Class_UNIVERSAL.INTEGER
-    def randval(self):
-        return RandNum(-2**64, 2**64-1)
-
-class ASN1F_NULL(ASN1F_INTEGER):
-    ASN1_tag= ASN1_Class_UNIVERSAL.NULL
-
-class ASN1F_enum_INTEGER(ASN1F_INTEGER):
-    def __init__(self, name, default, enum):
-        ASN1F_INTEGER.__init__(self, name, default)
-        i2s = self.i2s = {}
-        s2i = self.s2i = {}
-        if type(enum) is list:
-            keys = xrange(len(enum))
-        else:
-            keys = enum.keys()
-        if filter(lambda x: type(x) is str, keys):
-            i2s,s2i = s2i,i2s
-        for k in keys:
-            i2s[k] = enum[k]
-            s2i[enum[k]] = k
-    def any2i_one(self, pkt, x):
-        if type(x) is str:
-            x = self.s2i[x]
-        return x
-    def i2repr_one(self, pkt, x):
-        return self.i2s.get(x, repr(x))
-    
-    def any2i(self, pkt, x):
-        if type(x) is list:
-            return map(lambda z,pkt=pkt:self.any2i_one(pkt,z), x)
-        else:
-            return self.any2i_one(pkt,x)        
-    def i2repr(self, pkt, x):
-        if type(x) is list:
-            return map(lambda z,pkt=pkt:self.i2repr_one(pkt,z), x)
-        else:
-            return self.i2repr_one(pkt,x)
-
-class ASN1F_STRING(ASN1F_field):
-    ASN1_tag = ASN1_Class_UNIVERSAL.STRING
-    def randval(self):
-        return RandString(RandNum(0, 1000))
-
-class ASN1F_PRINTABLE_STRING(ASN1F_STRING):
-    ASN1_tag = ASN1_Class_UNIVERSAL.PRINTABLE_STRING
-
-class ASN1F_BIT_STRING(ASN1F_STRING):
-    ASN1_tag = ASN1_Class_UNIVERSAL.BIT_STRING
-
-class ASN1F_UTC_TIME(ASN1F_STRING):
-    ASN1_tag = ASN1_Class_UNIVERSAL.UTC_TIME
-
-class ASN1F_OID(ASN1F_field):
-    ASN1_tag = ASN1_Class_UNIVERSAL.OID
-    def randval(self):
-        return RandOID()
-
-class ASN1F_SEQUENCE(ASN1F_field):
-    ASN1_tag = ASN1_Class_UNIVERSAL.SEQUENCE
-    def __init__(self, *seq, **kargs):
-        if "ASN1_tag" in kargs:
-            self.ASN1_tag = kargs["ASN1_tag"]
-        self.seq = seq
-    def __repr__(self):
-        return "<%s%r>" % (self.__class__.__name__,self.seq,)
-    def set_val(self, pkt, val):
-        for f in self.seq:
-            f.set_val(pkt,val)
-    def is_empty(self, pkt):
-        for f in self.seq:
-            if not f.is_empty(pkt):
-                return False
-        return True
-    def get_fields_list(self):
-        return reduce(lambda x,y: x+y.get_fields_list(), self.seq, [])
-    def build(self, pkt):
-        s = reduce(lambda x,y: x+y.build(pkt), self.seq, "")
-        return self.i2m(pkt, s)
-    def dissect(self, pkt, s):
-        codec = self.ASN1_tag.get_codec(pkt.ASN1_codec)
-        try:
-            i,s,remain = codec.check_type_check_len(s)
-            for obj in self.seq:
-                s = obj.dissect(pkt,s)
-            if s:
-                warning("Too many bytes to decode sequence: [%r]" % s) # XXX not reversible!
-            return remain
-        except ASN1_Error,e:
-            raise ASN1F_badsequence(e)
-
-class ASN1F_SET(ASN1F_SEQUENCE):
-    ASN1_tag = ASN1_Class_UNIVERSAL.SET
-
-class ASN1F_SEQUENCE_OF(ASN1F_SEQUENCE):
-    holds_packets = 1
-    islist = 1
-    def __init__(self, name, default, asn1pkt, ASN1_tag=0x30):
-        self.asn1pkt = asn1pkt
-        self.tag = chr(ASN1_tag)
-        self.name = name
-        self.default = default
-    def i2repr(self, pkt, i):
-        if i is None:
-            return []
-        return i
-    def get_fields_list(self):
-        return [self]
-    def set_val(self, pkt, val):
-        ASN1F_field.set_val(self, pkt, val)
-    def is_empty(self, pkt):
-        return ASN1F_field.is_empty(self, pkt)
-    def build(self, pkt):
-        val = getattr(pkt, self.name)
-        if isinstance(val, ASN1_Object) and val.tag == ASN1_Class_UNIVERSAL.RAW:
-            s = val
-        elif val is None:
-            s = ""
-        else:
-            s = "".join(map(str, val ))
-        return self.i2m(pkt, s)
-    def set_val(self, pkt, val):
-        ASN1F_field.set_val(self, pkt, val)
-    def dissect(self, pkt, s):
-        codec = self.ASN1_tag.get_codec(pkt.ASN1_codec)
-        i,s1,remain = codec.check_type_check_len(s)
-        lst = []
-        while s1:
-            try:
-                p = self.asn1pkt(s1)
-            except ASN1F_badsequence,e:
-                lst.append(Raw(s1))
-                break
-            lst.append(p)
-            if Raw in p:
-                s1 = p[Raw].load
-                del(p[Raw].underlayer.payload)
-            else:
-                break
-        self.set_val(pkt, lst)
-        return remain
-    def randval(self):
-        return fuzz(self.asn1pkt())
-    def __repr__(self):
-        return "<%s %s>" % (self.__class__.__name__,self.name)
-
-class ASN1F_PACKET(ASN1F_field):
-    holds_packets = 1
-    def __init__(self, name, default, cls):
-        ASN1_field.__init__(self, name, default)
-        self.cls = cls
-    def i2m(self, pkt, x):
-        if x is None:
-            x = ""
-        return str(x)
-    def extract_packet(self, cls, x):
-        try:
-            c = cls(x)
-        except ASN1F_badsequence:
-            c = Raw(x)
-        cpad = c[Padding]
-        x = ""
-        if cpad is not None:
-            x = cpad.load
-            del(cpad.underlayer.payload)
-        return c,x
-    def m2i(self, pkt, x):
-        return self.extract_packet(self.cls, x)
-
-
-class ASN1F_CHOICE(ASN1F_PACKET):
-    ASN1_tag = ASN1_Class_UNIVERSAL.NONE
-    def __init__(self, name, default, *args):
-        self.name=name
-        self.choice = {}
-        for p in args:
-            self.choice[p.ASN1_root.ASN1_tag] = p
-#        self.context=context
-        self.default=default
-    def m2i(self, pkt, x):
-        if len(x) == 0:
-            return Raw(),""
-            raise ASN1_Error("ASN1F_CHOICE: got empty string")
-        if ord(x[0]) not in self.choice:
-            return Raw(x),"" # XXX return RawASN1 packet ? Raise error 
-            raise ASN1_Error("Decoding Error: choice [%i] not found in %r" % (ord(x[0]), self.choice.keys()))
-
-        z = ASN1F_PACKET.extract_packet(self, self.choice[ord(x[0])], x)
-        return z
-    def randval(self):
-        return RandChoice(*map(lambda x:fuzz(x()), self.choice.values()))
-            
-    
-
-###########################
-## Packet abstract class ##
-###########################
-
-class Packet_metaclass(type):
-    def __new__(cls, name, bases, dct):
-        newcls = super(Packet_metaclass, cls).__new__(cls, name, bases, dct)
-        for f in newcls.fields_desc:
-            f.register_owner(newcls)
-        return newcls
-    def __getattr__(self, attr):
-        for k in self.fields_desc:
-            if k.name == attr:
-                return k
-        raise AttributeError(attr)
-
-class NewDefaultValues(Packet_metaclass):
-    """NewDefaultValues metaclass. Example usage:
-    class MyPacket(Packet):
-        fields_desc = [ StrField("my_field", "my default value"),  ]
-        
-    class MyPacket_variant(MyPacket):
-        __metaclass__ = NewDefaultValues
-        my_field = "my new default value"
-    """    
-    def __new__(cls, name, bases, dct):
-        fields = None
-        for b in bases:
-            if hasattr(b,"fields_desc"):
-                fields = b.fields_desc
-                break
-        if fields is None:
-            raise Scapy_Exception("No fields_desc in superclasses")
-
-        new_fields = []
-        for f in fields:
-            if f.name in dct:
-                f = f.copy()
-                f.default = dct[f.name]
-                del(dct[f.name])
-            new_fields.append(f)
-        dct["fields_desc"] = new_fields
-        return super(NewDefaultValues, cls).__new__(cls, name, bases, dct)
-
-class Packet(Gen):
-    __metaclass__ = Packet_metaclass
-    name=None
-
-    fields_desc = []
-
-    aliastypes = []
-    overload_fields = {}
-
-    underlayer = None
-
-    payload_guess = []
-    initialized = 0
-    show_indent=1
-    explicit = 0
-
-    @classmethod
-    def from_hexcap(cls):
-        return cls(import_hexcap())
-
-    @classmethod
-    def upper_bonds(self):
-        for fval,upper in self.payload_guess:
-            print "%-20s  %s" % (upper.__name__, ", ".join("%-12s" % ("%s=%r"%i) for i in fval.iteritems()))
-
-    @classmethod
-    def lower_bonds(self):
-        for lower,fval in self.overload_fields.iteritems():
-            print "%-20s  %s" % (lower.__name__, ", ".join("%-12s" % ("%s=%r"%i) for i in fval.iteritems()))
-
-    def __init__(self, _pkt="", post_transform=None, _internal=0, _underlayer=None, **fields):
-        self.time  = time.time()
-        self.sent_time = 0
-        if self.name is None:
-            self.name = self.__class__.__name__
-        self.aliastypes = [ self.__class__ ] + self.aliastypes
-        self.default_fields = {}
-        self.overloaded_fields = {}
-        self.fields={}
-        self.fieldtype={}
-        self.packetfields=[]
-        self.__dict__["payload"] = NoPayload()
-        self.init_fields()
-        self.underlayer = _underlayer
-        self.initialized = 1
-        if _pkt:
-            self.dissect(_pkt)
-            if not _internal:
-                self.dissection_done(self)
-        for f in fields.keys():
-            self.fields[f] = self.get_field(f).any2i(self,fields[f])
-        if type(post_transform) is list:
-            self.post_transforms = post_transform
-        elif post_transform is None:
-            self.post_transforms = []
-        else:
-            self.post_transforms = [post_transform]
-
-    def init_fields(self):
-        self.do_init_fields(self.fields_desc)
-
-    def do_init_fields(self, flist):
-        for f in flist:
-            self.default_fields[f.name] = f.default
-            self.fieldtype[f.name] = f
-            if f.holds_packets:
-                self.packetfields.append(f)
-            
-    def dissection_done(self,pkt):
-        """DEV: will be called after a dissection is completed"""
-        self.post_dissection(pkt)
-        self.payload.dissection_done(pkt)
-        
-    def post_dissection(self, pkt):
-        """DEV: is called after the dissection of the whole packet"""
-        pass
-
-    def get_field(self, fld):
-        """DEV: returns the field instance from the name of the field"""
-        return self.fieldtype[fld]
-        
-    def add_payload(self, payload):
-        if payload is None:
-            return
-        elif not isinstance(self.payload, NoPayload):
-            self.payload.add_payload(payload)
-        else:
-            if isinstance(payload, Packet):
-                self.__dict__["payload"] = payload
-                payload.add_underlayer(self)
-                for t in self.aliastypes:
-                    if payload.overload_fields.has_key(t):
-                        self.overloaded_fields = payload.overload_fields[t]
-                        break
-            elif type(payload) is str:
-                self.__dict__["payload"] = Raw(load=payload)
-            else:
-                raise TypeError("payload must be either 'Packet' or 'str', not [%s]" % repr(payload))
-    def remove_payload(self):
-        self.payload.remove_underlayer(self)
-        self.__dict__["payload"] = NoPayload()
-        self.overloaded_fields = {}
-    def add_underlayer(self, underlayer):
-        self.underlayer = underlayer
-    def remove_underlayer(self,other):
-        self.underlayer = None
-    def copy(self):
-        """Returns a deep copy of the instance."""
-        clone = self.__class__()
-        clone.fields = self.fields.copy()
-        for k in clone.fields:
-            clone.fields[k]=self.get_field(k).do_copy(clone.fields[k])
-        clone.default_fields = self.default_fields.copy()
-        clone.overloaded_fields = self.overloaded_fields.copy()
-        clone.overload_fields = self.overload_fields.copy()
-        clone.underlayer=self.underlayer
-        clone.explicit=self.explicit
-        clone.post_transforms=self.post_transforms[:]
-        clone.__dict__["payload"] = self.payload.copy()
-        clone.payload.add_underlayer(clone)
-        return clone
-
-    def getfieldval(self, attr):
-        if attr in self.fields:
-            return self.fields[attr]
-        if attr in self.overloaded_fields:
-            return self.overloaded_fields[attr]
-        if attr in self.default_fields:
-            return self.default_fields[attr]
-        return self.payload.getfieldval(attr)
-    
-    def getfield_and_val(self, attr):
-        if attr in self.fields:
-            return self.get_field(attr),self.fields[attr]
-        if attr in self.overloaded_fields:
-            return self.get_field(attr),self.overloaded_fields[attr]
-        if attr in self.default_fields:
-            return self.get_field(attr),self.default_fields[attr]
-        return self.payload.getfield_and_val(attr)
-    
-    def __getattr__(self, attr):
-        if self.initialized:
-            fld,v = self.getfield_and_val(attr)
-            if fld is not None:
-                return fld.i2h(self, v)
-            return v
-        raise AttributeError(attr)
-
-    def setfieldval(self, attr, val):
-        if self.default_fields.has_key(attr):
-            fld = self.get_field(attr)
-            if fld is None:
-                any2i = lambda x,y: y
-            else:
-                any2i = fld.any2i
-            self.fields[attr] = any2i(self, val)
-            self.explicit=0
-        elif attr == "payload":
-            self.remove_payload()
-            self.add_payload(val)
-        else:
-            self.payload.setfieldval(attr,val)
-
-    def __setattr__(self, attr, val):
-        if self.initialized:
-            try:
-                self.setfieldval(attr,val)
-            except AttributeError:
-                pass
-            else:
-                return
-        self.__dict__[attr] = val
-
-    def delfieldval(self, attr):
-        if self.fields.has_key(attr):
-            del(self.fields[attr])
-            self.explicit=0 # in case a default value must be explicited
-        elif self.default_fields.has_key(attr):
-            pass
-        elif attr == "payload":
-            self.remove_payload()
-        else:
-            self.payload.delfieldval(attr)
-
-    def __delattr__(self, attr):
-        if self.initialized:
-            try:
-                self.delfieldval(attr)
-            except AttributeError:
-                pass
-            else:
-                return
-        if self.__dict__.has_key(attr):
-            del(self.__dict__[attr])
-        else:
-            raise AttributeError(attr)
-            
-    def __repr__(self):
-        s = ""
-        ct = conf.color_theme
-        for f in self.fields_desc:
-            if isinstance(f, ConditionalField) and not f._evalcond(self):
-                continue
-            if f.name in self.fields:
-                val = f.i2repr(self, self.fields[f.name])
-            elif f.name in self.overloaded_fields:
-                val =  f.i2repr(self, self.overloaded_fields[f.name])
-            else:
-                continue
-            if isinstance(f, Emph):
-                ncol = ct.emph_field_name
-                vcol = ct.emph_field_value
-            else:
-                ncol = ct.field_name
-                vcol = ct.field_value
-
-                
-            s += " %s%s%s" % (ncol(f.name),
-                              ct.punct("="),
-                              vcol(val))
-        return "%s%s %s %s%s%s"% (ct.punct("<"),
-                                  ct.layer_name(self.__class__.__name__),
-                                  s,
-                                  ct.punct("|"),
-                                  repr(self.payload),
-                                  ct.punct(">"))
-    def __str__(self):
-        return self.build()
-    def __div__(self, other):
-        if isinstance(other, Packet):
-            cloneA = self.copy()
-            cloneB = other.copy()
-            cloneA.add_payload(cloneB)
-            return cloneA
-        elif type(other) is str:
-            return self/Raw(load=other)
-        else:
-            return other.__rdiv__(self)
-    def __rdiv__(self, other):
-        if type(other) is str:
-            return Raw(load=other)/self
-        else:
-            raise TypeError
-    def __mul__(self, other):
-        if type(other) is int:
-            return  [self]*other
-        else:
-            raise TypeError
-    def __rmul__(self,other):
-        return self.__mul__(other)
-    
-    def __nonzero__(self):
-        return True
-    def __len__(self):
-        return len(self.__str__())
-    def do_build(self):
-        p=""
-        for f in self.fields_desc:
-            p = f.addfield(self, p, self.getfieldval(f.name))
-        return p
-    
-    def post_build(self, pkt, pay):
-        """DEV: called right after the current layer is build."""
-        return pkt+pay
-
-    def build_payload(self):
-        return self.payload.build(internal=1)
-
-    def build(self,internal=0):
-        if not self.explicit:
-            self = self.__iter__().next()
-        pkt = self.do_build()
-        for t in self.post_transforms:
-            pkt = t(pkt)
-        pay = self.build_payload()
-        try:
-            p = self.post_build(pkt,pay)
-        except TypeError:
-            log_runtime.error("API changed! post_build() now takes 2 arguments. Compatibility is only assured for a short transition time")
-            p = self.post_build(pkt+pay)
-        if not internal:
-            pad = self.payload.getlayer(Padding) 
-            if pad: 
-                p += pad.build()
-            p = self.build_done(p)
-        return p
-
-    def build_done(self, p):
-        return self.payload.build_done(p)
-
-    def do_build_ps(self):
-        p=""
-        pl = []
-        q=""
-        for f in self.fields_desc:
-            p = f.addfield(self, p, self.getfieldval(f.name) )
-            if type(p) is str:
-                r = p[len(q):]
-                q = p
-            else:
-                r = ""
-            pl.append( (f, f.i2repr(self,self.getfieldval(f.name)), r) )
-            
-        pkt,lst = self.payload.build_ps(internal=1)
-        p += pkt
-        lst.append( (self, pl) )
-        
-        return p,lst
-    
-    def build_ps(self,internal=0):
-        p,lst = self.do_build_ps()
-#        if not internal:
-#            pkt = self
-#            while pkt.haslayer(Padding):
-#                pkt = pkt.getlayer(Padding)
-#                lst.append( (pkt, [ ("loakjkjd", pkt.load, pkt.load) ] ) )
-#                p += pkt.load
-#                pkt = pkt.payload
-        return p,lst
-
-
-    def psdump(self, filename=None, **kargs):
-        """psdump(filename=None, layer_shift=0, rebuild=1)
-Creates an EPS file describing a packet. If filename is not provided a temporary file is created and gs is called."""
-        canvas = self.canvas_dump(**kargs)
-        if filename is None:
-            fname = "/tmp/scapy.%i"%os.getpid()
-            canvas.writeEPSfile(fname)
-            os.system("%s '%s.eps' &" % (conf.prog.psreader,fname))
-        else:
-            canvas.writeEPSfile(filename)
-
-    def pdfdump(self, filename=None, **kargs):
-        """pdfdump(filename=None, layer_shift=0, rebuild=1)
-        Creates a PDF file describing a packet. If filename is not provided a temporary file is created and xpdf is called."""
-        canvas = self.canvas_dump(**kargs)
-        if filename is None:
-            fname = "/tmp/scapy.%i"%os.getpid()
-            canvas.writePDFfile(fname)
-            os.system("%s '%s.pdf' &" % (conf.prog.pdfreader,fname))
-        else:
-            canvas.writePDFfile(filename)
-
-        
-    def canvas_dump(self, layer_shift=0, rebuild=1):
-        canvas = pyx.canvas.canvas()
-        if rebuild:
-            p,t = self.__class__(str(self)).build_ps()
-        else:
-            p,t = self.build_ps()
-        YTXT=len(t)
-        for n,l in t:
-            YTXT += len(l)
-        YTXT = float(YTXT)
-        YDUMP=YTXT
-
-        XSTART = 1
-        XDSTART = 10
-        y = 0.0
-        yd = 0.0
-        xd = 0 
-        XMUL= 0.55
-        YMUL = 0.4
-    
-        backcolor=colgen(0.6, 0.8, 1.0, trans=pyx.color.rgb)
-        forecolor=colgen(0.2, 0.5, 0.8, trans=pyx.color.rgb)
-#        backcolor=makecol(0.376, 0.729, 0.525, 1.0)
-        
-        
-        def hexstr(x):
-            s = []
-            for c in x:
-                s.append("%02x" % ord(c))
-            return " ".join(s)
-
-                
-        def make_dump_txt(x,y,txt):
-            return pyx.text.text(XDSTART+x*XMUL, (YDUMP-y)*YMUL, r"\tt{%s}"%hexstr(txt), [pyx.text.size.Large])
-
-        def make_box(o):
-            return pyx.box.rect(o.left(), o.bottom(), o.width(), o.height(), relcenter=(0.5,0.5))
-
-        def make_frame(lst):
-            if len(lst) == 1:
-                b = lst[0].bbox()
-                b.enlarge(pyx.unit.u_pt)
-                return b.path()
-            else:
-                fb = lst[0].bbox()
-                fb.enlarge(pyx.unit.u_pt)
-                lb = lst[-1].bbox()
-                lb.enlarge(pyx.unit.u_pt)
-                if len(lst) == 2 and fb.left() > lb.right():
-                    return pyx.path.path(pyx.path.moveto(fb.right(), fb.top()),
-                                         pyx.path.lineto(fb.left(), fb.top()),
-                                         pyx.path.lineto(fb.left(), fb.bottom()),
-                                         pyx.path.lineto(fb.right(), fb.bottom()),
-                                         pyx.path.moveto(lb.left(), lb.top()),
-                                         pyx.path.lineto(lb.right(), lb.top()),
-                                         pyx.path.lineto(lb.right(), lb.bottom()),
-                                         pyx.path.lineto(lb.left(), lb.bottom()))
-                else:
-                    # XXX
-                    gb = lst[1].bbox()
-                    if gb != lb:
-                        gb.enlarge(pyx.unit.u_pt)
-                    kb = lst[-2].bbox()
-                    if kb != gb and kb != lb:
-                        kb.enlarge(pyx.unit.u_pt)
-                    return pyx.path.path(pyx.path.moveto(fb.left(), fb.top()),
-                                         pyx.path.lineto(fb.right(), fb.top()),
-                                         pyx.path.lineto(fb.right(), kb.bottom()),
-                                         pyx.path.lineto(lb.right(), kb.bottom()),
-                                         pyx.path.lineto(lb.right(), lb.bottom()),
-                                         pyx.path.lineto(lb.left(), lb.bottom()),
-                                         pyx.path.lineto(lb.left(), gb.top()),
-                                         pyx.path.lineto(fb.left(), gb.top()),
-                                         pyx.path.closepath(),)
-                                         
-
-        def make_dump(s, shift=0, y=0, col=None, bkcol=None, larg=16):
-            c = pyx.canvas.canvas()
-            tlist = []
-            while s:
-                dmp,s = s[:larg-shift],s[larg-shift:]
-                txt = make_dump_txt(shift, y, dmp)
-                tlist.append(txt)
-                shift += len(dmp)
-                if shift >= 16:
-                    shift = 0
-                    y += 1
-            if col is None:
-                col = pyx.color.rgb.red
-            if bkcol is None:
-                col = pyx.color.rgb.white
-            c.stroke(make_frame(tlist),[col,pyx.deco.filled([bkcol]),pyx.style.linewidth.Thick])
-            for txt in tlist:
-                c.insert(txt)
-            return c, tlist[-1].bbox(), shift, y
-                            
-
-        last_shift,last_y=0,0.0
-        while t:
-            bkcol = backcolor.next()
-            proto,fields = t.pop()
-            y += 0.5
-            pt = pyx.text.text(XSTART, (YTXT-y)*YMUL, r"\font\cmssfont=cmss10\cmssfont{%s}" % proto.name, [ pyx.text.size.Large])
-            y += 1
-            ptbb=pt.bbox()
-            ptbb.enlarge(pyx.unit.u_pt*2)
-            canvas.stroke(ptbb.path(),[pyx.color.rgb.black, pyx.deco.filled([bkcol])])
-            canvas.insert(pt)
-            for fname, fval, fdump in fields:
-                col = forecolor.next()
-                ft = pyx.text.text(XSTART, (YTXT-y)*YMUL, r"\font\cmssfont=cmss10\cmssfont{%s}" % tex_escape(fname.name))
-                if fval is not None:
-                    if len(fval) > 18:
-                        fval = fval[:18]+"[...]"
-                else:
-                    fval=""
-                vt = pyx.text.text(XSTART+3, (YTXT-y)*YMUL, r"\font\cmssfont=cmss10\cmssfont{%s}" % tex_escape(fval))
-                y += 1.0
-                if fdump:
-                    dt,target,last_shift,last_y = make_dump(fdump, last_shift, last_y, col, bkcol)
-
-                    dtb = dt.bbox()
-                    dtb=target
-                    vtb = vt.bbox()
-                    bxvt = make_box(vtb)
-                    bxdt = make_box(dtb)
-                    dtb.enlarge(pyx.unit.u_pt)
-                    try:
-                        if yd < 0:
-                            cnx = pyx.connector.curve(bxvt,bxdt,absangle1=0, absangle2=-90)
-                        else:
-                            cnx = pyx.connector.curve(bxvt,bxdt,absangle1=0, absangle2=90)
-                    except:
-                        pass
-                    else:
-                        canvas.stroke(cnx,[pyx.style.linewidth.thin,pyx.deco.earrow.small,col])
-                        
-                    canvas.insert(dt)
-                
-                canvas.insert(ft)
-                canvas.insert(vt)
-            last_y += layer_shift
-    
-        return canvas
-
-
-
-    def extract_padding(self, s):
-        """DEV: to be overloaded to extract current layer's padding. Return a couple of strings (actual layer, padding)"""
-        return s,None
-
-    def post_dissect(self, s):
-        """DEV: is called right after the current layer has been dissected"""
-        return s
-
-    def pre_dissect(self, s):
-        """DEV: is called right before the current layer is dissected"""
-        return s
-
-    def do_dissect(self, s):
-        flist = self.fields_desc[:]
-        flist.reverse()
-        while s and flist:
-            f = flist.pop()
-            s,fval = f.getfield(self, s)
-            self.fields[f.name] = fval
-            
-        return s
-
-    def do_dissect_payload(self, s):
-        if s:
-            cls = self.guess_payload_class(s)
-            try:
-                p = cls(s, _internal=1, _underlayer=self)
-            except KeyboardInterrupt:
-                raise
-            except:
-                if conf.debug_dissector:
-                    if isinstance(cls,type) and issubclass(cls,Packet):
-                        log_runtime.error("%s dissector failed" % cls.name)
-                    else:
-                        log_runtime.error("%s.guess_payload_class() returned [%s]" % (self.__class__.__name__,repr(cls)))
-                    if cls is not None:
-                        raise
-                p = Raw(s, _internal=1, _underlayer=self)
-            self.add_payload(p)
-
-    def dissect(self, s):
-        s = self.pre_dissect(s)
-
-        s = self.do_dissect(s)
-
-        s = self.post_dissect(s)
-            
-        payl,pad = self.extract_padding(s)
-        self.do_dissect_payload(payl)
-        if pad and conf.padding:
-            self.add_payload(Padding(pad))
-
-
-    def guess_payload_class(self, payload):
-        """DEV: Guesses the next payload class from layer bonds. Can be overloaded to use a different mechanism."""
-        for t in self.aliastypes:
-            for fval, cls in t.payload_guess:
-                ok = 1
-                for k in fval.keys():
-                    if not hasattr(self, k) or fval[k] != self.getfieldval(k):
-                        ok = 0
-                        break
-                if ok:
-                    return cls
-        return self.default_payload_class(payload)
-    
-    def default_payload_class(self, payload):
-        """DEV: Returns the default payload class if nothing has been found by the guess_payload_class() method."""
-        return Raw
-
-    def hide_defaults(self):
-        """Removes fields' values that are the same as default values."""
-        for k in self.fields.keys():
-            if self.default_fields.has_key(k):
-                if self.default_fields[k] == self.fields[k]:
-                    del(self.fields[k])
-        self.payload.hide_defaults()
-            
-    def clone_with(self, payload=None, **kargs):
-        pkt = self.__class__()
-        pkt.explicit = 1
-        pkt.fields = kargs
-        pkt.time = self.time
-        pkt.underlayer = self.underlayer
-        pkt.overload_fields = self.overload_fields.copy()
-        pkt.post_transforms = self.post_transforms
-        if payload is not None:
-            pkt.add_payload(payload)
-        return pkt
-        
-
-    def __iter__(self):
-        def loop(todo, done, self=self):
-            if todo:
-                eltname = todo.pop()
-                elt = self.getfieldval(eltname)
-                if not isinstance(elt, Gen):
-                    if self.get_field(eltname).islist:
-                        elt = SetGen([elt])
-                    else:
-                        elt = SetGen(elt)
-                for e in elt:
-                    done[eltname]=e
-                    for x in loop(todo[:], done):
-                        yield x
-            else:
-                if isinstance(self.payload,NoPayload):
-                    payloads = [None]
-                else:
-                    payloads = self.payload
-                for payl in payloads:
-                    done2=done.copy()
-                    for k in done2:
-                        if isinstance(done2[k], VolatileValue):
-                            done2[k] = done2[k]._fix()
-                    pkt = self.clone_with(payload=payl, **done2)
-                    yield pkt
-
-        if self.explicit:
-            todo = []
-            done = self.fields
-        else:
-            todo = [ k for (k,v) in itertools.chain(self.default_fields.iteritems(),
-                                                    self.overloaded_fields.iteritems())
-                     if isinstance(v, VolatileValue) ] + self.fields.keys()
-            done = {}
-        return loop(todo, done)
-
-    def __gt__(self, other):
-        """True if other is an answer from self (self ==> other)."""
-        if isinstance(other, Packet):
-            return other < self
-        elif type(other) is str:
-            return 1
-        else:
-            raise TypeError((self, other))
-    def __lt__(self, other):
-        """True if self is an answer from other (other ==> self)."""
-        if isinstance(other, Packet):
-            return self.answers(other)
-        elif type(other) is str:
-            return 1
-        else:
-            raise TypeError((self, other))
-
-    def __eq__(self, other):
-        if not isinstance(other, self.__class__):
-            return False
-        for f in self.fields_desc:
-            if f not in other.fields_desc:
-                return False
-            if self.getfieldval(f.name) != other.getfieldval(f.name):
-                return False
-        return self.payload == other.payload
-
-    def __ne__(self, other):
-        return not self.__eq__(other)
-
-    def hashret(self):
-        """DEV: returns a string that has the same value for a request and its answer."""
-        return self.payload.hashret()
-    def answers(self, other):
-        """DEV: true if self is an answer from other"""
-        if other.__class__ == self.__class__:
-            return self.payload.answers(other.payload)
-        return 0
-
-    def haslayer(self, cls):
-        """true if self has a layer that is an instance of cls. Superseded by "cls in self" syntax."""
-        if self.__class__ == cls or self.__class__.__name__ == cls:
-            return 1
-        for f in self.packetfields:
-            fvalue_gen = self.getfieldval(f.name)
-            if fvalue_gen is None:
-                continue
-            if not f.islist:
-                fvalue_gen = SetGen(fvalue_gen,_iterpacket=0)
-            for fvalue in fvalue_gen:
-                if isinstance(fvalue, Packet):
-                    ret = fvalue.haslayer(cls)
-                    if ret:
-                        return ret
-        return self.payload.haslayer(cls)
-    def getlayer(self, cls, nb=1, _track=None):
-        """Return the nb^th layer that is an instance of cls."""
-        if type(cls) is str and "." in cls:
-            ccls,fld = cls.split(".",1)
-        else:
-            ccls,fld = cls,None
-        if self.__class__ == cls or self.__class__.name == ccls:
-            if nb == 1:
-                if fld is None:
-                    return self
-                else:
-                    return self.getfieldval(fld)
-            else:
-                nb -=1
-        for f in self.packetfields:
-            fvalue_gen = self.getfieldval(f.name)
-            if fvalue_gen is None:
-                continue
-            if not f.islist:
-                fvalue_gen = SetGen(fvalue_gen,_iterpacket=0)
-            for fvalue in fvalue_gen:
-                if isinstance(fvalue, Packet):
-                    track=[]
-                    ret = fvalue.getlayer(cls, nb, _track=track)
-                    if ret is not None:
-                        return ret
-                    nb = track[0]
-        return self.payload.getlayer(cls,nb,_track=_track)
-
-    def __getitem__(self, cls):
-        if type(cls) is slice:
-            if cls.stop:
-                ret = self.getlayer(cls.start, cls.stop)
-            else:
-                ret = self.getlayer(cls.start)
-            if ret is None and cls.step is not None:
-                ret = cls.step
-            return ret
-        else:
-            return self.getlayer(cls)
-        
-    def __contains__(self, cls):
-        """"cls in self" returns true if self has a layer which is an instance of cls."""
-        return self.haslayer(cls)
-        
-    
-
-    def display(self,*args,**kargs):  # Deprecated. Use show()
-        """Deprecated. Use show() method."""
-        self.show(*args,**kargs)
-    def show(self, indent=3, lvl="", label_lvl=""):
-        """Prints a hierarchical view of the packet. "indent" gives the size of indentation for each layer."""
-        ct = conf.color_theme
-        print "%s%s %s %s" % (label_lvl,
-                              ct.punct("###["),
-                              ct.layer_name(self.name),
-                              ct.punct("]###"))
-        for f in self.fields_desc:
-            if isinstance(f, ConditionalField) and not f._evalcond(self):
-                continue
-            if isinstance(f, Emph):
-                ncol = ct.emph_field_name
-                vcol = ct.emph_field_value
-            else:
-                ncol = ct.field_name
-                vcol = ct.field_value
-            fvalue = self.getfieldval(f.name)
-            if isinstance(fvalue, Packet) or (f.islist and f.holds_packets and type(fvalue) is list):
-                print "%s  \\%-10s\\" % (label_lvl+lvl, ncol(f.name))
-                fvalue_gen = SetGen(fvalue,_iterpacket=0)
-                for fvalue in fvalue_gen:
-                    fvalue.show(indent=indent, label_lvl=label_lvl+lvl+"   |")
-            else:
-                print "%s  %-10s%s %s" % (label_lvl+lvl,
-                                          ncol(f.name),
-                                          ct.punct("="),
-                                          vcol(f.i2repr(self,fvalue)))
-        self.payload.show(indent=indent, lvl=lvl+(" "*indent*self.show_indent), label_lvl=label_lvl)
-    def show2(self):
-        """Prints a hierarchical view of an assembled version of the packet, so that automatic fields are calculated (checksums, etc.)"""
-        self.__class__(str(self)).show()
-
-    def sprintf(self, fmt, relax=1):
-        """sprintf(format, [relax=1]) -> str
-where format is a string that can include directives. A directive begins and
-ends by % and has the following format %[fmt[r],][cls[:nb].]field%.
-
-fmt is a classic printf directive, "r" can be appended for raw substitution
-(ex: IP.flags=0x18 instead of SA), nb is the number of the layer we want
-(ex: for IP/IP packets, IP:2.src is the src of the upper IP layer).
-Special case : "%.time%" is the creation time.
-Ex : p.sprintf("%.time% %-15s,IP.src% -> %-15s,IP.dst% %IP.chksum% "
-               "%03xr,IP.proto% %r,TCP.flags%")
-
-Moreover, the format string can include conditionnal statements. A conditionnal
-statement looks like : {layer:string} where layer is a layer name, and string
-is the string to insert in place of the condition if it is true, i.e. if layer
-is present. If layer is preceded by a "!", the result si inverted. Conditions
-can be imbricated. A valid statement can be :
-  p.sprintf("This is a{TCP: TCP}{UDP: UDP}{ICMP:n ICMP} packet")
-  p.sprintf("{IP:%IP.dst% {ICMP:%ICMP.type%}{TCP:%TCP.dport%}}")
-
-A side effect is that, to obtain "{" and "}" characters, you must use
-"%(" and "%)".
-"""
-
-        escape = { "%": "%",
-                   "(": "{",
-                   ")": "}" }
-
-
-        # Evaluate conditions 
-        while "{" in fmt:
-            i = fmt.rindex("{")
-            j = fmt[i+1:].index("}")
-            cond = fmt[i+1:i+j+1]
-            k = cond.find(":")
-            if k < 0:
-                raise Scapy_Exception("Bad condition in format string: [%s] (read sprintf doc!)"%cond)
-            cond,format = cond[:k],cond[k+1:]
-            res = False
-            if cond[0] == "!":
-                res = True
-                cond = cond[1:]
-            if self.haslayer(cond):
-                res = not res
-            if not res:
-                format = ""
-            fmt = fmt[:i]+format+fmt[i+j+2:]
-
-        # Evaluate directives
-        s = ""
-        while "%" in fmt:
-            i = fmt.index("%")
-            s += fmt[:i]
-            fmt = fmt[i+1:]
-            if fmt and fmt[0] in escape:
-                s += escape[fmt[0]]
-                fmt = fmt[1:]
-                continue
-            try:
-                i = fmt.index("%")
-                sfclsfld = fmt[:i]
-                fclsfld = sfclsfld.split(",")
-                if len(fclsfld) == 1:
-                    f = "s"
-                    clsfld = fclsfld[0]
-                elif len(fclsfld) == 2:
-                    f,clsfld = fclsfld
-                else:
-                    raise Scapy_Exception
-                if "." in clsfld:
-                    cls,fld = clsfld.split(".")
-                else:
-                    cls = self.__class__.__name__
-                    fld = clsfld
-                num = 1
-                if ":" in cls:
-                    cls,num = cls.split(":")
-                    num = int(num)
-                fmt = fmt[i+1:]
-            except:
-                raise Scapy_Exception("Bad format string [%%%s%s]" % (fmt[:25], fmt[25:] and "..."))
-            else:
-                if fld == "time":
-                    val = time.strftime("%H:%M:%S.%%06i", time.localtime(self.time)) % int((self.time-int(self.time))*1000000)
-                elif cls == self.__class__.__name__ and hasattr(self, fld):
-                    if num > 1:
-                        val = self.payload.sprintf("%%%s,%s:%s.%s%%" % (f,cls,num-1,fld), relax)
-                        f = "s"
-                    elif f[-1] == "r":  # Raw field value
-                        val = getattr(self,fld)
-                        f = f[:-1]
-                        if not f:
-                            f = "s"
-                    else:
-                        val = getattr(self,fld)
-                        if fld in self.fieldtype:
-                            val = self.fieldtype[fld].i2repr(self,val)
-                else:
-                    val = self.payload.sprintf("%%%s%%" % sfclsfld, relax)
-                    f = "s"
-                s += ("%"+f) % val
-            
-        s += fmt
-        return s
-
-    def mysummary(self):
-        """DEV: can be overloaded to return a string that summarizes the layer.
-           Only one mysummary() is used in a whole packet summary: the one of the upper layer,
-           except if a mysummary() also returns (as a couple) a list of layers whose
-           mysummary() must be called if they are present."""
-        return ""
-
-    def summary(self, intern=0):
-        """Prints a one line summary of a packet."""
-        found,s,needed = self.payload.summary(intern=1)
-        if s:
-            s = " / "+s
-        ret = ""
-        if not found or self.__class__ in needed:
-            ret = self.mysummary()
-            if type(ret) is tuple:
-                ret,n = ret
-                needed += n
-        if ret or needed:
-            found = 1
-        if not ret:
-            ret = self.__class__.__name__
-        ret = "%s%s" % (ret,s)
-        if intern:
-            return found,ret,needed
-        else:
-            return ret
-    
-    def lastlayer(self,layer=None):
-        """Returns the uppest layer of the packet"""
-        return self.payload.lastlayer(self)
-
-    def decode_payload_as(self,cls):
-        """Reassembles the payload and decode it using another packet class"""
-        s = str(self.payload)
-        self.payload = cls(s)
-
-    def libnet(self):
-        """Not ready yet. Should give the necessary C code that interfaces with libnet to recreate the packet"""
-        print "libnet_build_%s(" % self.__class__.name.lower()
-        det = self.__class__(str(self))
-        for f in self.fields_desc:
-            val = det.getfieldval(f.name)
-            if val is None:
-                val = 0
-            elif type(val) is int:
-                val = str(val)
-            else:
-                val = '"%s"' % str(val)
-            print "\t%s, \t\t/* %s */" % (val,f.name)
-        print ");"
-    def command(self):
-        """Returns a string representing the command you have to type to obtain the same packet"""
-        f = []
-        for fn,fv in self.fields.items():
-            fld = self.get_field(fn)
-            if isinstance(fv, Packet):
-                fv = fv.command()
-            elif fld.islist and fld.holds_packets and type(fv) is list:
-                fv = "[%s]" % ",".join( map(Packet.command, fv))
-            else:
-                fv = repr(fv)
-            f.append("%s=%s" % (fn, fv))
-        c = "%s(%s)" % (self.__class__.__name__, ", ".join(f))
-        pc = self.payload.command()
-        if pc:
-            c += "/"+pc
-        return c                    
-
-
-class ASN1_Packet(Packet):
-    ASN1_root = None
-    ASN1_codec = None    
-    def init_fields(self):
-        flist = self.ASN1_root.get_fields_list()
-        self.do_init_fields(flist)
-        self.fields_desc = flist    
-    def do_build(self):
-        return self.ASN1_root.build(self)    
-    def do_dissect(self, x):
-        return self.ASN1_root.dissect(self, x)
-        
-
-class NoPayload(Packet,object):
-    def __new__(cls, *args, **kargs):
-        singl = cls.__dict__.get("__singl__")
-        if singl is None:
-            cls.__singl__ = singl = object.__new__(cls)
-            Packet.__init__(singl, *args, **kargs)
-        return singl
-    def __init__(self, *args, **kargs):
-        pass
-    def dissection_done(self,pkt):
-        return
-    def add_payload(self, payload):
-        raise Scapy_Exception("Can't add payload to NoPayload instance")
-    def remove_payload(self):
-        pass
-    def add_underlayer(self,underlayer):
-        pass
-    def remove_underlayer(self,other):
-        pass
-    def copy(self):
-        return self
-    def __repr__(self):
-        return ""
-    def __str__(self):
-        return ""
-    def __nonzero__(self):
-        return False
-    def build(self, internal=0):
-        return ""    
-    def build_done(self, p):
-        return p
-    def build_ps(self, internal=0):
-        return "",[]
-    def getfieldval(self, attr):
-        raise AttributeError(attr)
-    def getfield_and_val(self, attr):
-        raise AttributeError(attr)
-    def setfieldval(self, attr, val):
-        raise AttributeError(attr)
-    def delfieldval(self, attr):
-        raise AttributeError(attr)
-    def __getattr__(self, attr):
-        if attr in self.__dict__:
-            return self.__dict__[attr]
-        elif attr in self.__class__.__dict__:
-            return self.__class__.__dict__[attr]
-        else:
-            raise AttributeError, attr
-    def hide_defaults(self):
-        pass
-    def __iter__(self):
-        return iter([])
-    def __eq__(self, other):
-        if isinstance(other, NoPayload):
-            return True
-        return False
-    def hashret(self):
-        return ""
-    def answers(self, other):
-        return isinstance(other, NoPayload) or isinstance(other, Padding)
-    def haslayer(self, cls):
-        return 0
-    def getlayer(self, cls, nb=1, _track=None):
-        if _track is not None:
-            _track.append(nb)
-        return None
-    def show(self, indent=3, lvl="", label_lvl=""):
-        pass
-    def sprintf(self, fmt, relax):
-        if relax:
-            return "??"
-        else:
-            raise Scapy_Exception("Format not found [%s]"%fmt)
-    def summary(self, intern=0):
-        return 0,"",[]
-    def lastlayer(self,layer):
-        return layer
-    def command(self):
-        return ""
-    
-
-####################
-## packet classes ##
-####################
-    
-            
-class Raw(Packet):
-    name = "Raw"
-    fields_desc = [ StrField("load", "") ]
-    def answers(self, other):
-        return 1
-#        s = str(other)
-#        t = self.load
-#        l = min(len(s), len(t))
-#        return  s[:l] == t[:l]
-        
-class Padding(Raw):
-    name = "Padding"
-    def build(self, internal=0):
-        if internal:
-            return ""
-        else:
-            return Raw.build(self)
-
-class Ether(Packet):
-    name = "Ethernet"
-    fields_desc = [ DestMACField("dst"),
-                    SourceMACField("src"),
-                    XShortEnumField("type", 0x0000, ETHER_TYPES) ]
-    def hashret(self):
-        return struct.pack("H",self.type)+self.payload.hashret()
-    def answers(self, other):
-        if isinstance(other,Ether):
-            if self.type == other.type:
-                return self.payload.answers(other.payload)
-        return 0
-    def mysummary(self):
-        return self.sprintf("%src% > %dst% (%type%)")
-
-class PPPoE(Packet):
-    name = "PPP over Ethernet"
-    fields_desc = [ BitField("version", 1, 4),
-                    BitField("type", 1, 4),
-                    ByteEnumField("code", 0, {0:"Session"}),
-                    XShortField("sessionid", 0x0),
-                    ShortField("len", None) ]
-
-    def post_build(self, p, pay):
-        p += pay
-        if self.len is None:
-            l = len(p)-6
-            p = p[:4]+struct.pack("!H", l)+p[6:]
-        return p
-
-class PPPoED(PPPoE):
-    name = "PPP over Ethernet Discovery"
-    fields_desc = [ BitField("version", 1, 4),
-                    BitField("type", 1, 4),
-                    ByteEnumField("code", 0x09, {0x09:"PADI",0x07:"PADO",0x19:"PADR",0x65:"PADS",0xa7:"PADT"}),
-                    XShortField("sessionid", 0x0),
-                    ShortField("len", None) ]
-
-class Dot3(Packet):
-    name = "802.3"
-    fields_desc = [ MACField("dst", ETHER_BROADCAST),
-                    MACField("src", ETHER_ANY),
-                    LenField("len", None, "H") ]
-    def extract_padding(self,s):
-        l = self.len
-        return s[:l],s[l:]
-    def answers(self, other):
-        if isinstance(other,Dot3):
-            return self.payload.answers(other.payload)
-        return 0
-    def mysummary(self):
-        return "802.3 %s > %s" % (self.src, self.dst)
-
-
-class LLC(Packet):
-    name = "LLC"
-    fields_desc = [ XByteField("dsap", 0x00),
-                    XByteField("ssap", 0x00),
-                    ByteField("ctrl", 0) ]
-
-
-class CookedLinux(Packet):
-    name = "cooked linux"
-    fields_desc = [ ShortEnumField("pkttype",0, {0: "unicast",
-                                                 4:"sent-by-us"}), #XXX incomplete
-                    XShortField("lladdrtype",512),
-                    ShortField("lladdrlen",0),
-                    StrFixedLenField("src","",8),
-                    XShortEnumField("proto",0x800,ETHER_TYPES) ]
-                    
-                                   
-
-class SNAP(Packet):
-    name = "SNAP"
-    fields_desc = [ X3BytesField("OUI",0x000000),
-                    XShortEnumField("code", 0x000, ETHER_TYPES) ]
-
-
-class Dot1Q(Packet):
-    name = "802.1Q"
-    aliastypes = [ Ether ]
-    fields_desc =  [ BitField("prio", 0, 3),
-                     BitField("id", 0, 1),
-                     BitField("vlan", 1, 12),
-                     XShortEnumField("type", 0x0000, ETHER_TYPES) ]
-    def answers(self, other):
-        if isinstance(other,Dot1Q):
-            if ( (self.type == other.type) and
-                 (self.vlan == other.vlan) ):
-                return self.payload.answers(other.payload)
-        else:
-            return self.payload.answers(other)
-        return 0
-    def default_payload_class(self, pay):
-        if self.type <= 1500:
-            return LLC
-        return Raw
-    def extract_padding(self,s):
-        if self.type <= 1500:
-            return s[:self.type],s[self.type:]
-        return s,None
-    def mysummary(self):
-        if isinstance(self.underlayer, Ether):
-            return self.underlayer.sprintf("802.1q %Ether.src% > %Ether.dst% (%Dot1Q.type%) vlan %Dot1Q.vlan%")
-        else:
-            return self.sprintf("802.1q (%Dot1Q.type%) vlan %Dot1Q.vlan%")
-
-            
-
-
-class RadioTap(Packet):
-    name = "RadioTap dummy"
-    fields_desc = [ ByteField('version', 0),
-                    ByteField('pad', 0),
-                    FieldLenField('len', None, 'notdecoded', '@H', adjust=lambda pkt,x:x+8),
-                    FlagsField('present', None, -32, ['TSFT','Flags','Rate','Channel','FHSS','dBm_AntSignal',
-                                                     'dBm_AntNoise','Lock_Quality','TX_Attenuation','dB_TX_Attenuation',
-                                                      'dBm_TX_Power', 'Antenna', 'dB_AntSignal', 'dB_AntNoise',
-                                                     'b14', 'b15','b16','b17','b18','b19','b20','b21','b22','b23',
-                                                     'b24','b25','b26','b27','b28','b29','b30','Ext']),
-                    StrLenField('notdecoded', "", length_from= lambda pkt:pkt.len-8) ]
-
-class STP(Packet):
-    name = "Spanning Tree Protocol"
-    fields_desc = [ ShortField("proto", 0),
-                    ByteField("version", 0),
-                    ByteField("bpdutype", 0),
-                    ByteField("bpduflags", 0),
-                    ShortField("rootid", 0),
-                    MACField("rootmac", ETHER_ANY),
-                    IntField("pathcost", 0),
-                    ShortField("bridgeid", 0),
-                    MACField("bridgemac", ETHER_ANY),
-                    ShortField("portid", 0),
-                    BCDFloatField("age", 1),
-                    BCDFloatField("maxage", 20),
-                    BCDFloatField("hellotime", 2),
-                    BCDFloatField("fwddelay", 15) ]
-
-
-class EAPOL(Packet):
-    name = "EAPOL"
-    fields_desc = [ ByteField("version", 1),
-                    ByteEnumField("type", 0, ["EAP_PACKET", "START", "LOGOFF", "KEY", "ASF"]),
-                    LenField("len", None, "H") ]
-    
-    EAP_PACKET= 0
-    START = 1
-    LOGOFF = 2
-    KEY = 3
-    ASF = 4
-    def extract_padding(self, s):
-        l = self.len
-        return s[:l],s[l:]
-    def hashret(self):
-        return chr(self.type)+self.payload.hashret()
-    def answers(self, other):
-        if isinstance(other,EAPOL):
-            if ( (self.type == self.EAP_PACKET) and
-                 (other.type == self.EAP_PACKET) ):
-                return self.payload.answers(other.payload)
-        return 0
-    def mysummary(self):
-        return self.sprintf("EAPOL %EAPOL.type%")
-             
-
-class EAP(Packet):
-    name = "EAP"
-    fields_desc = [ ByteEnumField("code", 4, {1:"REQUEST",2:"RESPONSE",3:"SUCCESS",4:"FAILURE"}),
-                    ByteField("id", 0),
-                    ShortField("len",None),
-                    ConditionalField(ByteEnumField("type",0, {1:"ID",4:"MD5"}), lambda pkt:pkt.code not in [EAP.SUCCESS, EAP.FAILURE])
-
-                                     ]
-    
-    REQUEST = 1
-    RESPONSE = 2
-    SUCCESS = 3
-    FAILURE = 4
-    TYPE_ID = 1
-    TYPE_MD5 = 4
-    def answers(self, other):
-        if isinstance(other,EAP):
-            if self.code == self.REQUEST:
-                return 0
-            elif self.code == self.RESPONSE:
-                if ( (other.code == self.REQUEST) and
-                     (other.type == self.type) ):
-                    return 1
-            elif other.code == self.RESPONSE:
-                return 1
-        return 0
-    
-    def post_build(self, p, pay):
-        if self.len is None:
-            l = len(p)+len(pay)
-            p = p[:2]+chr((l>>8)&0xff)+chr(l&0xff)+p[4:]
-        return p+pay
-             
-
-class ARP(Packet):
-    name = "ARP"
-    fields_desc = [ XShortField("hwtype", 0x0001),
-                    XShortEnumField("ptype",  0x0800, ETHER_TYPES),
-                    ByteField("hwlen", 6),
-                    ByteField("plen", 4),
-                    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}),
-                    ARPSourceMACField("hwsrc"),
-                    SourceIPField("psrc","pdst"),
-                    MACField("hwdst", ETHER_ANY),
-                    IPField("pdst", "0.0.0.0") ]
-    who_has = 1
-    is_at = 2
-    def answers(self, other):
-        if isinstance(other,ARP):
-            if ( (self.op == self.is_at) and
-                 (other.op == self.who_has) and
-                 (self.psrc == other.pdst) ):
-                return 1
-        return 0
-    def extract_padding(self, s):
-        return "",s
-    def mysummary(self):
-        if self.op == self.is_at:
-            return "ARP is at %s says %s" % (self.hwsrc, self.psrc)
-        elif self.op == self.who_has:
-            return "ARP who has %s says %s" % (self.pdst, self.psrc)
-        else:
-            return "ARP %ARP.op% %ARP.psrc% > %ARP.pdst%"
-                 
-
-class IP(Packet, IPTools):
-    name = "IP"
-    fields_desc = [ BitField("version" , 4 , 4),
-                    BitField("ihl", None, 4),
-                    XByteField("tos", 0),
-                    ShortField("len", None),
-                    ShortField("id", 1),
-                    FlagsField("flags", 0, 3, ["MF","DF","evil"]),
-                    BitField("frag", 0, 13),
-                    ByteField("ttl", 64),
-                    ByteEnumField("proto", 0, IP_PROTOS),
-                    XShortField("chksum", None),
-                    #IPField("src", "127.0.0.1"),
-                    Emph(SourceIPField("src","dst")),
-                    Emph(IPField("dst", "127.0.0.1")),
-                    IPoptionsField("options", "") ]
-    def post_build(self, p, pay):
-        ihl = self.ihl
-        if ihl is None:
-            ihl = len(p)/4
-            p = chr(((self.version&0xf)<<4) | ihl&0x0f)+p[1:]
-        if self.len is None:
-            l = len(p)+len(pay)
-            p = p[:2]+struct.pack("!H", l)+p[4:]
-        if self.chksum is None:
-            ck = checksum(p)
-            p = p[:10]+chr(ck>>8)+chr(ck&0xff)+p[12:]
-        return p+pay
-
-    def extract_padding(self, s):
-        l = self.len - (self.ihl << 2)
-        return s[:l],s[l:]
-
-    def send(self, s, slp=0):
-        for p in self:
-            try:
-                s.sendto(str(p), (p.dst,0))
-            except socket.error, msg:
-                log_runtime.error(msg)
-            if slp:
-                time.sleep(slp)
-    def hashret(self):
-        if ( (self.proto == socket.IPPROTO_ICMP)
-             and (isinstance(self.payload, ICMP))
-             and (self.payload.type in [3,4,5,11,12]) ):
-            return self.payload.payload.hashret()
-        else:
-            if conf.checkIPsrc and conf.checkIPaddr:
-                return strxor(inet_aton(self.src),inet_aton(self.dst))+struct.pack("B",self.proto)+self.payload.hashret()
-            else:
-                return struct.pack("B", self.proto)+self.payload.hashret()
-    def answers(self, other):
-        if not isinstance(other,IP):
-            return 0
-        if conf.checkIPaddr and (self.dst != other.src):
-            return 0
-        if ( (self.proto == socket.IPPROTO_ICMP) and
-             (isinstance(self.payload, ICMP)) and
-             (self.payload.type in [3,4,5,11,12]) ):
-            # ICMP error message
-            return self.payload.payload.answers(other)
-
-        else:
-            if ( (conf.checkIPaddr and (self.src != other.dst)) or
-                 (self.proto != other.proto) ):
-                return 0
-            return self.payload.answers(other.payload)
-    def mysummary(self):
-        s = self.sprintf("%IP.src% > %IP.dst% %IP.proto%")
-        if self.frag:
-            s += " frag:%i" % self.frag
-        return s
-                 
-    
-
-class TCP(Packet):
-    name = "TCP"
-    fields_desc = [ ShortEnumField("sport", 20, TCP_SERVICES),
-                    ShortEnumField("dport", 80, TCP_SERVICES),
-                    IntField("seq", 0),
-                    IntField("ack", 0),
-                    BitField("dataofs", None, 4),
-                    BitField("reserved", 0, 4),
-                    FlagsField("flags", 0x2, 8, "FSRPAUEC"),
-                    ShortField("window", 8192),
-                    XShortField("chksum", None),
-                    ShortField("urgptr", 0),
-                    TCPOptionsField("options", {}) ]
-    def post_build(self, p, pay):
-        p += pay
-        dataofs = self.dataofs
-        if dataofs is None:
-            dataofs = 5+((len(self.get_field("options").i2m(self,self.options))+3)/4)
-            p = p[:12]+chr((dataofs << 4) | ord(p[12])&0x0f)+p[13:]
-        if self.chksum is None:
-            if isinstance(self.underlayer, IP):
-                if self.underlayer.len is not None:
-                    ln = self.underlayer.len-20
-                else:
-                    ln = len(p)
-                psdhdr = struct.pack("!4s4sHH",
-                                     inet_aton(self.underlayer.src),
-                                     inet_aton(self.underlayer.dst),
-                                     self.underlayer.proto,
-                                     ln)
-                ck=checksum(psdhdr+p)
-                p = p[:16]+struct.pack("!H", ck)+p[18:]
-            elif isinstance(self.underlayer, IPv6) or isinstance(self.underlayer, _IPv6OptionHeader):
-                ck = in6_chksum(socket.IPPROTO_TCP, self.underlayer, p)
-                p = p[:16]+struct.pack("!H", ck)+p[18:]
-            else:
-                warning("No IP underlayer to compute checksum. Leaving null.")
-        return p
-    def hashret(self):
-        if conf.checkIPsrc:
-            return struct.pack("H",self.sport ^ self.dport)+self.payload.hashret()
-        else:
-            return self.payload.hashret()
-    def answers(self, other):
-        if not isinstance(other, TCP):
-            return 0
-        if conf.checkIPsrc:
-            if not ((self.sport == other.dport) and
-                    (self.dport == other.sport)):
-                return 0
-        if (abs(other.seq-self.ack) > 2+len(other.payload)):
-            return 0
-        return 1
-    def mysummary(self):
-        if isinstance(self.underlayer, IP):
-            return self.underlayer.sprintf("TCP %IP.src%:%TCP.sport% > %IP.dst%:%TCP.dport% %TCP.flags%")
-        elif isinstance(self.underlayer, IPv6):
-            return self.underlayer.sprintf("TCP %IPv6.src%:%TCP.sport% > %IPv6.dst%:%TCP.dport% %TCP.flags%")
-        else:
-            return self.sprintf("TCP %TCP.sport% > %TCP.dport% %TCP.flags%")
-
-class UDP(Packet):
-    name = "UDP"
-    fields_desc = [ ShortEnumField("sport", 53, UDP_SERVICES),
-                    ShortEnumField("dport", 53, UDP_SERVICES),
-                    ShortField("len", None),
-                    XShortField("chksum", None), ]
-    def post_build(self, p, pay):
-        p += pay
-        l = self.len
-        if l is None:
-            l = len(p)
-            p = p[:4]+struct.pack("!H",l)+p[6:]
-        if self.chksum is None:
-            if isinstance(self.underlayer, IP):
-                if self.underlayer.len is not None:
-                    ln = self.underlayer.len-20
-                else:
-                    ln = len(p)
-                psdhdr = struct.pack("!4s4sHH",
-                                     inet_aton(self.underlayer.src),
-                                     inet_aton(self.underlayer.dst),
-                                     self.underlayer.proto,
-                                     ln)
-                ck=checksum(psdhdr+p)
-                p = p[:6]+struct.pack("!H", ck)+p[8:]
-            elif isinstance(self.underlayer, IPv6) or isinstance(self.underlayer, _IPv6OptionHeader):
-                ck = in6_chksum(socket.IPPROTO_UDP, self.underlayer, p)
-                p = p[:6]+struct.pack("!H", ck)+p[8:]
-            else:
-                warning("No IP underlayer to compute checksum. Leaving null.")
-        return p
-    def extract_padding(self, s):
-        l = self.len - 8
-        return s[:l],s[l:]
-    def hashret(self):
-        return self.payload.hashret()
-    def answers(self, other):
-        if not isinstance(other, UDP):
-            return 0
-        if conf.checkIPsrc:
-            if self.dport != other.sport:
-                return 0
-        return self.payload.answers(other.payload)
-    def mysummary(self):
-        if isinstance(self.underlayer, IP):
-            return self.underlayer.sprintf("UDP %IP.src%:%UDP.sport% > %IP.dst%:%UDP.dport%")
-        elif isinstance(self.underlayer, IPv6):
-            return self.underlayer.sprintf("UDP %IPv6.src%:%UDP.sport% > %IPv6.dst%:%UDP.dport%")
-        else:
-            return self.sprintf("UDP %UDP.sport% > %UDP.dport%")    
-
-icmptypes = { 0 : "echo-reply",
-              3 : "dest-unreach",
-              4 : "source-quench",
-              5 : "redirect",
-              8 : "echo-request",
-              9 : "router-advertisement",
-              10 : "router-solicitation",
-              11 : "time-exceeded",
-              12 : "parameter-problem",
-              13 : "timestamp-request",
-              14 : "timestamp-reply",
-              15 : "information-request",
-              16 : "information-response",
-              17 : "address-mask-request",
-              18 : "address-mask-reply" }
-
-class ICMP(Packet):
-    name = "ICMP"
-    fields_desc = [ ByteEnumField("type",8, icmptypes),
-                    ByteField("code",0),
-                    XShortField("chksum", None),
-                    ConditionalField(XShortField("id",0),  lambda pkt:pkt.type in [0,8,13,14,15,16]),
-                    ConditionalField(XShortField("seq",0), lambda pkt:pkt.type in [0,8,13,14,15,16]),
-                    ConditionalField(ICMPTimeStampField("ts_ori", None), lambda pkt:pkt.type in [13,14]),
-                    ConditionalField(ICMPTimeStampField("ts_rx", None), lambda pkt:pkt.type in [13,14]),
-                    ConditionalField(ICMPTimeStampField("ts_tx", None), lambda pkt:pkt.type in [13,14]),
-                    ConditionalField(IPField("gw","0.0.0.0"),  lambda pkt:pkt.type==5),
-                    ConditionalField(ByteField("ptr",0),   lambda pkt:pkt.type==12),
-                    ConditionalField(X3BytesField("reserved",0), lambda pkt:pkt.type==12),
-                    ConditionalField(IntField("unused",0), lambda pkt:pkt.type not in [0,5,8,12,13,14,15,16]),
-                    ]
-    def post_build(self, p, pay):
-        p += pay
-        if self.chksum is None:
-            ck = checksum(p)
-            p = p[:2]+chr(ck>>8)+chr(ck&0xff)+p[4:]
-        return p
-    
-    def hashret(self):
-        return struct.pack("HH",self.id,self.seq)+self.payload.hashret()
-    def answers(self, other):
-        if not isinstance(other,ICMP):
-            return 0
-        if ( (other.type,self.type) in [(8,0),(13,14),(15,16),(17,18)] and
-             self.id == other.id and
-             self.seq == other.seq ):
-            return 1
-        return 0
-
-    def guess_payload_class(self, payload):
-        if self.type in [3,4,5,11,12]:
-            return IPerror
-        else:
-            return None
-    def mysummary(self):
-        if isinstance(self.underlayer, IP):
-            return self.underlayer.sprintf("ICMP %IP.src% > %IP.dst% %ICMP.type% %ICMP.code%")
-        else:
-            return self.sprintf("ICMP %ICMP.type% %ICMP.code%")
-    
-        
-
-
-
-class IPerror(IP):
-    name = "IP in ICMP"
-    def answers(self, other):
-        if not isinstance(other, IP):
-            return 0
-        if not ( ((conf.checkIPsrc == 0) or (self.dst == other.dst)) and
-                 (self.src == other.src) and
-                 ( ((conf.checkIPID == 0)
-                    or (self.id == other.id)
-                    or (conf.checkIPID == 1 and self.id == socket.htons(other.id)))) and
-                 (self.proto == other.proto) ):
-            return 0
-        return self.payload.answers(other.payload)
-    def mysummary(self):
-        return Packet.mysummary(self)
-
-
-class TCPerror(TCP):
-    name = "TCP in ICMP"
-    def answers(self, other):
-        if not isinstance(other, TCP):
-            return 0
-        if conf.checkIPsrc:
-            if not ((self.sport == other.sport) and
-                    (self.dport == other.dport)):
-                return 0
-        if conf.check_TCPerror_seqack:
-            if self.seq is not None:
-                if self.seq != other.seq:
-                    return 0
-            if self.ack is not None:
-                if self.ack != other.ack:
-                    return 0
-        return 1
-    def mysummary(self):
-        return Packet.mysummary(self)
-
-
-class UDPerror(UDP):
-    name = "UDP in ICMP"
-    def answers(self, other):
-        if not isinstance(other, UDP):
-            return 0
-        if conf.checkIPsrc:
-            if not ((self.sport == other.sport) and
-                    (self.dport == other.dport)):
-                return 0
-        return 1
-    def mysummary(self):
-        return Packet.mysummary(self)
-
-                    
-
-class ICMPerror(ICMP):
-    name = "ICMP in ICMP"
-    def answers(self, other):
-        if not isinstance(other,ICMP):
-            return 0
-        if not ((self.type == other.type) and
-                (self.code == other.code)):
-            return 0
-        if self.code in [0,8,13,14,17,18]:
-            if (self.id == other.id and
-                self.seq == other.seq):
-                return 1
-            else:
-                return 0
-        else:
-            return 1
-    def mysummary(self):
-        return Packet.mysummary(self)
-
-class IPv6(Packet):
-    """See http://namabiiru.hongo.wide.ad.jp/scapy6"""
-    name = "IPv6 not implemented here." 
-    def __init__(self, *args, **kargs):
-        log_interactive.error(self.name)
-    def __repr__(self):
-        return "<IPv6: ERROR not implemented>"
-    
-class _IPv6OptionHeader(Packet):
-    """See http://namabiiru.hongo.wide.ad.jp/scapy6"""
-    name = "IPv6 not implemented here."
-    def __init__(self, *args, **kargs):
-        log_interactive.error(self.name)
-    def __repr__(self):
-        return "<IPv6: ERROR not implemented>"
-
-
-class L2TP(Packet):
-    fields_desc = [ ShortEnumField("pkt_type",2,{2:"data"}),
-                    ShortField("len", None),
-                    ShortField("tunnel_id", 0),
-                    ShortField("session_id", 0),
-                    ShortField("ns", 0),
-                    ShortField("nr", 0),
-                    ShortField("offset", 0) ]
-
-    def post_build(self, pkt, pay):
-        if self.len is None:
-            l = len(pkt)+len(pay)
-            pkt = pkt[:2]+struct.pack("!H", l)+pkt[4:]
-        return pkt+pay
-
-
-_PPP_proto = { 0x0001: "Padding Protocol",
-               0x0003: "ROHC small-CID [RFC3095]",
-               0x0005: "ROHC large-CID [RFC3095]",
-               0x0021: "Internet Protocol version 4",
-               0x0023: "OSI Network Layer",
-               0x0025: "Xerox NS IDP",
-               0x0027: "DECnet Phase IV",
-               0x0029: "Appletalk",
-               0x002b: "Novell IPX",
-               0x002d: "Van Jacobson Compressed TCP/IP",
-               0x002f: "Van Jacobson Uncompressed TCP/IP",
-               0x0031: "Bridging PDU",
-               0x0033: "Stream Protocol (ST-II)",
-               0x0035: "Banyan Vines",
-               0x0037: "reserved (until 1993) [Typo in RFC1172]",
-               0x0039: "AppleTalk EDDP",
-               0x003b: "AppleTalk SmartBuffered",
-               0x003d: "Multi-Link [RFC1717]",
-               0x003f: "NETBIOS Framing",
-               0x0041: "Cisco Systems",
-               0x0043: "Ascom Timeplex",
-               0x0045: "Fujitsu Link Backup and Load Balancing (LBLB)",
-               0x0047: "DCA Remote Lan",
-               0x0049: "Serial Data Transport Protocol (PPP-SDTP)",
-               0x004b: "SNA over 802.2",
-               0x004d: "SNA",
-               0x004f: "IPv6 Header Compression",
-               0x0051: "KNX Bridging Data [ianp]",
-               0x0053: "Encryption [Meyer]",
-               0x0055: "Individual Link Encryption [Meyer]",
-               0x0057: "Internet Protocol version 6 [Hinden]",
-               0x0059: "PPP Muxing [RFC3153]",
-               0x005b: "Vendor-Specific Network Protocol (VSNP) [RFC3772]",
-               0x0061: "RTP IPHC Full Header [RFC3544]",
-               0x0063: "RTP IPHC Compressed TCP [RFC3544]",
-               0x0065: "RTP IPHC Compressed Non TCP [RFC3544]",
-               0x0067: "RTP IPHC Compressed UDP 8 [RFC3544]",
-               0x0069: "RTP IPHC Compressed RTP 8 [RFC3544]",
-               0x006f: "Stampede Bridging",
-               0x0071: "Reserved [Fox]",
-               0x0073: "MP+ Protocol [Smith]",
-               0x007d: "reserved (Control Escape) [RFC1661]",
-               0x007f: "reserved (compression inefficient [RFC1662]",
-               0x0081: "Reserved Until 20-Oct-2000 [IANA]",
-               0x0083: "Reserved Until 20-Oct-2000 [IANA]",
-               0x00c1: "NTCITS IPI [Ungar]",
-               0x00cf: "reserved (PPP NLID)",
-               0x00fb: "single link compression in multilink [RFC1962]",
-               0x00fd: "compressed datagram [RFC1962]",
-               0x00ff: "reserved (compression inefficient)",
-               0x0201: "802.1d Hello Packets",
-               0x0203: "IBM Source Routing BPDU",
-               0x0205: "DEC LANBridge100 Spanning Tree",
-               0x0207: "Cisco Discovery Protocol [Sastry]",
-               0x0209: "Netcs Twin Routing [Korfmacher]",
-               0x020b: "STP - Scheduled Transfer Protocol [Segal]",
-               0x020d: "EDP - Extreme Discovery Protocol [Grosser]",
-               0x0211: "Optical Supervisory Channel Protocol (OSCP)[Prasad]",
-               0x0213: "Optical Supervisory Channel Protocol (OSCP)[Prasad]",
-               0x0231: "Luxcom",
-               0x0233: "Sigma Network Systems",
-               0x0235: "Apple Client Server Protocol [Ridenour]",
-               0x0281: "MPLS Unicast [RFC3032]  ",
-               0x0283: "MPLS Multicast [RFC3032]",
-               0x0285: "IEEE p1284.4 standard - data packets [Batchelder]",
-               0x0287: "ETSI TETRA Network Protocol Type 1 [Nieminen]",
-               0x0289: "Multichannel Flow Treatment Protocol [McCann]",
-               0x2063: "RTP IPHC Compressed TCP No Delta [RFC3544]",
-               0x2065: "RTP IPHC Context State [RFC3544]",
-               0x2067: "RTP IPHC Compressed UDP 16 [RFC3544]",
-               0x2069: "RTP IPHC Compressed RTP 16 [RFC3544]",
-               0x4001: "Cray Communications Control Protocol [Stage]",
-               0x4003: "CDPD Mobile Network Registration Protocol [Quick]",
-               0x4005: "Expand accelerator protocol [Rachmani]",
-               0x4007: "ODSICP NCP [Arvind]",
-               0x4009: "DOCSIS DLL [Gaedtke]",
-               0x400B: "Cetacean Network Detection Protocol [Siller]",
-               0x4021: "Stacker LZS [Simpson]",
-               0x4023: "RefTek Protocol [Banfill]",
-               0x4025: "Fibre Channel [Rajagopal]",
-               0x4027: "EMIT Protocols [Eastham]",
-               0x405b: "Vendor-Specific Protocol (VSP) [RFC3772]",
-               0x8021: "Internet Protocol Control Protocol",
-               0x8023: "OSI Network Layer Control Protocol",
-               0x8025: "Xerox NS IDP Control Protocol",
-               0x8027: "DECnet Phase IV Control Protocol",
-               0x8029: "Appletalk Control Protocol",
-               0x802b: "Novell IPX Control Protocol",
-               0x802d: "reserved",
-               0x802f: "reserved",
-               0x8031: "Bridging NCP",
-               0x8033: "Stream Protocol Control Protocol",
-               0x8035: "Banyan Vines Control Protocol",
-               0x8037: "reserved (until 1993)",
-               0x8039: "reserved",
-               0x803b: "reserved",
-               0x803d: "Multi-Link Control Protocol",
-               0x803f: "NETBIOS Framing Control Protocol",
-               0x8041: "Cisco Systems Control Protocol",
-               0x8043: "Ascom Timeplex",
-               0x8045: "Fujitsu LBLB Control Protocol",
-               0x8047: "DCA Remote Lan Network Control Protocol (RLNCP)",
-               0x8049: "Serial Data Control Protocol (PPP-SDCP)",
-               0x804b: "SNA over 802.2 Control Protocol",
-               0x804d: "SNA Control Protocol",
-               0x804f: "IP6 Header Compression Control Protocol",
-               0x8051: "KNX Bridging Control Protocol [ianp]",
-               0x8053: "Encryption Control Protocol [Meyer]",
-               0x8055: "Individual Link Encryption Control Protocol [Meyer]",
-               0x8057: "IPv6 Control Protovol [Hinden]",
-               0x8059: "PPP Muxing Control Protocol [RFC3153]",
-               0x805b: "Vendor-Specific Network Control Protocol (VSNCP) [RFC3772]",
-               0x806f: "Stampede Bridging Control Protocol",
-               0x8073: "MP+ Control Protocol [Smith]",
-               0x8071: "Reserved [Fox]",
-               0x807d: "Not Used - reserved [RFC1661]",
-               0x8081: "Reserved Until 20-Oct-2000 [IANA]",
-               0x8083: "Reserved Until 20-Oct-2000 [IANA]",
-               0x80c1: "NTCITS IPI Control Protocol [Ungar]",
-               0x80cf: "Not Used - reserved [RFC1661]",
-               0x80fb: "single link compression in multilink control [RFC1962]",
-               0x80fd: "Compression Control Protocol [RFC1962]",
-               0x80ff: "Not Used - reserved [RFC1661]",
-               0x8207: "Cisco Discovery Protocol Control [Sastry]",
-               0x8209: "Netcs Twin Routing [Korfmacher]",
-               0x820b: "STP - Control Protocol [Segal]",
-               0x820d: "EDPCP - Extreme Discovery Protocol Ctrl Prtcl [Grosser]",
-               0x8235: "Apple Client Server Protocol Control [Ridenour]",
-               0x8281: "MPLSCP [RFC3032]",
-               0x8285: "IEEE p1284.4 standard - Protocol Control [Batchelder]",
-               0x8287: "ETSI TETRA TNP1 Control Protocol [Nieminen]",
-               0x8289: "Multichannel Flow Treatment Protocol [McCann]",
-               0xc021: "Link Control Protocol",
-               0xc023: "Password Authentication Protocol",
-               0xc025: "Link Quality Report",
-               0xc027: "Shiva Password Authentication Protocol",
-               0xc029: "CallBack Control Protocol (CBCP)",
-               0xc02b: "BACP Bandwidth Allocation Control Protocol [RFC2125]",
-               0xc02d: "BAP [RFC2125]",
-               0xc05b: "Vendor-Specific Authentication Protocol (VSAP) [RFC3772]",
-               0xc081: "Container Control Protocol [KEN]",
-               0xc223: "Challenge Handshake Authentication Protocol",
-               0xc225: "RSA Authentication Protocol [Narayana]",
-               0xc227: "Extensible Authentication Protocol [RFC2284]",
-               0xc229: "Mitsubishi Security Info Exch Ptcl (SIEP) [Seno]",
-               0xc26f: "Stampede Bridging Authorization Protocol",
-               0xc281: "Proprietary Authentication Protocol [KEN]",
-               0xc283: "Proprietary Authentication Protocol [Tackabury]",
-               0xc481: "Proprietary Node ID Authentication Protocol [KEN]"}
-
-
-class HDLC(Packet):
-    fields_desc = [ XByteField("address",0xff),
-                    XByteField("control",0x03)  ]
-
-class PPP_metaclass(Packet_metaclass):
-    def __call__(self, _pkt=None, *args, **kargs):
-        cls = self
-        if _pkt and _pkt[0] == '\xff':
-            cls = HDLC
-        i = cls.__new__(cls, cls.__name__, cls.__bases__, cls.__dict__)
-        i.__init__(_pkt=_pkt, *args, **kargs)
-        return i
-    
-
-class PPP(Packet):
-    __metaclass__ = PPP_metaclass
-    name = "PPP Link Layer"
-    fields_desc = [ ShortEnumField("proto", 0x0021, _PPP_proto) ]
-
-_PPP_conftypes = { 1:"Configure-Request",
-                   2:"Configure-Ack",
-                   3:"Configure-Nak",
-                   4:"Configure-Reject",
-                   5:"Terminate-Request",
-                   6:"Terminate-Ack",
-                   7:"Code-Reject",
-                   8:"Protocol-Reject",
-                   9:"Echo-Request",
-                   10:"Echo-Reply",
-                   11:"Discard-Request",
-                   14:"Reset-Request",
-                   15:"Reset-Ack",
-                   }
-
-class PPP_Option_metaclass(Packet_metaclass):
-    _known_options={}
-    def __call__(self, _pkt=None, *args, **kargs):
-        cls = self
-        if _pkt:
-            t = ord(_pkt[0])
-            cls = self._known_options.get(t,self)
-        i = cls.__new__(cls, cls.__name__, cls.__bases__, cls.__dict__)
-        i.__init__(_pkt=_pkt, *args, **kargs)
-        return i
-    def _register(self, cls):
-        self._known_options[cls.fields_desc[0].default] = cls
-
-
-### PPP IPCP stuff (RFC 1332)
-
-# All IPCP options are defined below (names and associated classes) 
-_PPP_ipcpopttypes = {     1:"IP-Addresses (Deprecated)",
-                          2:"IP-Compression-Protocol",
-                          3:"IP-Address",
-                          4:"Mobile-IPv4", # not implemented, present for completeness
-                          129:"Primary-DNS-Address",
-                          130:"Primary-NBNS-Address",
-                          131:"Secondary-DNS-Address",
-                          132:"Secondary-NBNS-Address"}
-
-
-
-class PPP_IPCP_Option_metaclass(PPP_Option_metaclass):
-    _known_options={}
-
-
-class PPP_IPCP_Option(Packet):
-    __metaclass__=PPP_IPCP_Option_metaclass
-    name = "PPP IPCP Option"
-    fields_desc = [ ByteEnumField("type" , None , _PPP_ipcpopttypes),
-                    FieldLenField("len", None, length_of="data", fmt="B", adjust=lambda p,x:x+2),
-                    StrLenField("data", "", length_from=lambda p:max(0,p.len-2)) ]
-    def extract_padding(self, pay):
-        return "",pay
-
-class PPP_IPCP_Specific_Option_metaclass(PPP_IPCP_Option_metaclass):
-    def __new__(cls, name, bases, dct):
-        newcls = super(PPP_IPCP_Specific_Option_metaclass, cls).__new__(cls, name, bases, dct)
-        PPP_IPCP_Option._register(newcls)
-        
-
-class PPP_IPCP_Option_IPAddress(PPP_IPCP_Option):
-    __metaclass__=PPP_IPCP_Specific_Option_metaclass
-    name = "PPP IPCP Option: IP Address"
-    fields_desc = [ ByteEnumField("type" , 3 , _PPP_ipcpopttypes),
-                    FieldLenField("len", None, length_of="data", fmt="B", adjust=lambda p,x:x+6),
-                    IPField("data","0.0.0.0"),
-                    ConditionalField(StrLenField("garbage","", length_from=lambda pkt:pkt.len-6), lambda p:p.len!=6) ]
-
-class PPP_IPCP_Option_DNS1(PPP_IPCP_Option):
-    __metaclass__=PPP_IPCP_Specific_Option_metaclass
-    name = "PPP IPCP Option: DNS1 Address"
-    fields_desc = [ ByteEnumField("type" , 129 , _PPP_ipcpopttypes),
-                    FieldLenField("len", None, length_of="data", fmt="B", adjust=lambda p,x:x+6),
-                    IPField("data","0.0.0.0"),
-                    ConditionalField(StrLenField("garbage","", length_from=lambda pkt:pkt.len-6), lambda p:p.len!=6) ]
-
-class PPP_IPCP_Option_DNS2(PPP_IPCP_Option):
-    __metaclass__=PPP_IPCP_Specific_Option_metaclass
-    name = "PPP IPCP Option: DNS2 Address"
-    fields_desc = [ ByteEnumField("type" , 131 , _PPP_ipcpopttypes),
-                    FieldLenField("len", None, length_of="data", fmt="B", adjust=lambda p,x:x+6),
-                    IPField("data","0.0.0.0"),
-                    ConditionalField(StrLenField("garbage","", length_from=lambda pkt:pkt.len-6), lambda p:p.len!=6) ]
-
-class PPP_IPCP_Option_NBNS1(PPP_IPCP_Option):
-    __metaclass__=PPP_IPCP_Specific_Option_metaclass
-    name = "PPP IPCP Option: NBNS1 Address"
-    fields_desc = [ ByteEnumField("type" , 130 , _PPP_ipcpopttypes),
-                    FieldLenField("len", None, length_of="data", fmt="B", adjust=lambda p,x:x+6),
-                    IPField("data","0.0.0.0"),
-                    ConditionalField(StrLenField("garbage","", length_from=lambda pkt:pkt.len-6), lambda p:p.len!=6) ]
-
-class PPP_IPCP_Option_NBNS2(PPP_IPCP_Option):
-    __metaclass__=PPP_IPCP_Specific_Option_metaclass
-    name = "PPP IPCP Option: NBNS2 Address"
-    fields_desc = [ ByteEnumField("type" , 132 , _PPP_ipcpopttypes),
-                    FieldLenField("len", None, length_of="data", fmt="B", adjust=lambda p,x:x+6),
-                    IPField("data","0.0.0.0"),
-                    ConditionalField(StrLenField("garbage","", length_from=lambda pkt:pkt.len-6), lambda p:p.len!=6) ]
-
-
-
-
-class PPP_IPCP(Packet):
-    fields_desc = [ ByteEnumField("code" , 1, _PPP_conftypes),
-		    XByteField("id", 0 ),
-                    FieldLenField("len" , None, fmt="H", length_of="options", adjust=lambda p,x:x+4 ),
-                    PacketListField("options", [],  PPP_IPCP_Option, length_from=lambda p:p.len-4,) ]
-
-
-### ECP
-
-_PPP_ecpopttypes = { 0:"OUI",
-                     1:"DESE", }
-
-class PPP_ECP_Option_metaclass(PPP_Option_metaclass):
-    _known_options={}
-
-
-
-class PPP_ECP_Option(Packet):
-    __metaclass__=PPP_ECP_Option_metaclass
-    name = "PPP ECP Option"
-    fields_desc = [ ByteEnumField("type" , None , _PPP_ecpopttypes),
-                    FieldLenField("len", None, length_of="data", fmt="B", adjust=lambda p,x:x+2),
-                    StrLenField("data", "", length_from=lambda p:max(0,p.len-2)) ]
-    def extract_padding(self, pay):
-        return "",pay
-
-class PPP_ECP_Specific_Option_metaclass(PPP_ECP_Option_metaclass):
-    def __new__(cls, name, bases, dct):
-        newcls = super(PPP_ECP_Specific_Option_metaclass, cls).__new__(cls, name, bases, dct)
-        PPP_ECP_Option._register(newcls)
-        
-
-class PPP_ECP_Option_OUI(PPP_ECP_Option):
-    __metaclass__=PPP_ECP_Specific_Option_metaclass
-    fields_desc = [ ByteEnumField("type" , 0 , _PPP_ecpopttypes),
-                    FieldLenField("len", None, length_of="data", fmt="B", adjust=lambda p,x:x+2),
-                    StrFixedLenField("oui","",3),
-                    ByteField("subtype",0),
-                    StrLenField("data", "", length_from=lambda p:p.len-6) ]
-                    
-
-
-class PPP_ECP(Packet):
-    fields_desc = [ ByteEnumField("code" , 1, _PPP_conftypes),
-		    XByteField("id", 0 ),
-                    FieldLenField("len" , None, fmt="H", length_of="options", adjust=lambda p,x:x+4 ),
-                    PacketListField("options", [],  PPP_ECP_Option, length_from=lambda p:p.len-4,) ]
-
-
-
-
-class DNS(Packet):
-    name = "DNS"
-    fields_desc = [ ShortField("id",0),
-                    BitField("qr",0, 1),
-                    BitEnumField("opcode", 0, 4, {0:"QUERY",1:"IQUERY",2:"STATUS"}),
-                    BitField("aa", 0, 1),
-                    BitField("tc", 0, 1),
-                    BitField("rd", 0, 1),
-                    BitField("ra", 0 ,1),
-                    BitField("z", 0, 3),
-                    BitEnumField("rcode", 0, 4, {0:"ok", 1:"format-error", 2:"server-failure", 3:"name-error", 4:"not-implemented", 5:"refused"}),
-                    DNSRRCountField("qdcount", None, "qd"),
-                    DNSRRCountField("ancount", None, "an"),
-                    DNSRRCountField("nscount", None, "ns"),
-                    DNSRRCountField("arcount", None, "ar"),
-                    DNSQRField("qd", "qdcount"),
-                    DNSRRField("an", "ancount"),
-                    DNSRRField("ns", "nscount"),
-                    DNSRRField("ar", "arcount",0) ]
-    def answers(self, other):
-        return (isinstance(other, DNS)
-                and self.id == other.id
-                and self.qr == 1
-                and other.qr == 0)
-        
-    def mysummary(self):
-        type = ["Qry","Ans"][self.qr]
-        name = ""
-        if self.qr:
-            type = "Ans"
-            if self.ancount > 0 and isinstance(self.an, DNSRR):
-                name = ' "%s"' % self.an.rdata
-        else:
-            type = "Qry"
-            if self.qdcount > 0 and isinstance(self.qd, DNSQR):
-                name = ' "%s"' % self.qd.qname
-        return 'DNS %s%s ' % (type, name)
-
-dnstypes = { 0:"ANY", 255:"ALL",
-             1:"A", 2:"NS", 3:"MD", 4:"MD", 5:"CNAME", 6:"SOA", 7: "MB", 8:"MG",
-             9:"MR",10:"NULL",11:"WKS",12:"PTR",13:"HINFO",14:"MINFO",15:"MX",16:"TXT",
-             17:"RP",18:"AFSDB",28:"AAAA", 33:"SRV",38:"A6",39:"DNAME"}
-
-dnsqtypes = {251:"IXFR",252:"AXFR",253:"MAILB",254:"MAILA",255:"ALL"}
-dnsqtypes.update(dnstypes)
-dnsclasses =  {1: 'IN',  2: 'CS',  3: 'CH',  4: 'HS',  255: 'ANY'}
-
-
-class DNSQR(Packet):
-    name = "DNS Question Record"
-    show_indent=0
-    fields_desc = [ DNSStrField("qname",""),
-                    ShortEnumField("qtype", 1, dnsqtypes),
-                    ShortEnumField("qclass", 1, dnsclasses) ]
-                    
-                    
-
-class DNSRR(Packet):
-    name = "DNS Resource Record"
-    show_indent=0
-    fields_desc = [ DNSStrField("rrname",""),
-                    ShortEnumField("type", 1, dnstypes),
-                    ShortEnumField("rclass", 1, dnsclasses),
-                    IntField("ttl", 0),
-                    RDLenField("rdlen"),
-                    RDataField("rdata", "", length_from=lambda pkt:pkt.rdlen) ]
-
-dhcpmagic="c\x82Sc"
-
-
-class BOOTP(Packet):
-    name = "BOOTP"
-    fields_desc = [ ByteEnumField("op",1, {1:"BOOTREQUEST", 2:"BOOTREPLY"}),
-                    ByteField("htype",1),
-                    ByteField("hlen",6),
-                    ByteField("hops",0),
-                    IntField("xid",0),
-                    ShortField("secs",0),
-                    FlagsField("flags", 0, 16, "???????????????B"),
-                    IPField("ciaddr","0.0.0.0"),
-                    IPField("yiaddr","0.0.0.0"),
-                    IPField("siaddr","0.0.0.0"),
-                    IPField("giaddr","0.0.0.0"),
-                    Field("chaddr","", "16s"),
-                    Field("sname","","64s"),
-                    Field("file","","128s"),
-                    StrField("options","") ]
-    def guess_payload_class(self, payload):
-        if self.options[:len(dhcpmagic)] == dhcpmagic:
-            return DHCP
-        else:
-            return Packet.guess_payload_class(self, payload)
-    def extract_padding(self,s):
-        if self.options[:len(dhcpmagic)] == dhcpmagic:
-            # set BOOTP options to DHCP magic cookie and make rest a payload of DHCP options
-            payload = self.options[len(dhcpmagic):]
-            self.options = self.options[:len(dhcpmagic)]
-            return payload, None
-        else:
-            return "", None
-    def hashret(self):
-        return struct.pack("L", self.xid)
-    def answers(self, other):
-        if not isinstance(other, BOOTP):
-            return 0
-        return self.xid == other.xid
-
-
-
-#DHCP_UNKNOWN, DHCP_IP, DHCP_IPLIST, DHCP_TYPE \
-#= range(4)
-#
-
-DHCPTypes = {
-                1: "discover",
-                2: "offer",
-                3: "request",
-                4: "decline",
-                5: "ack",
-                6: "nak",
-                7: "release",
-                8: "inform",
-                9: "force_renew",
-                10:"lease_query",
-                11:"lease_unassigned",
-                12:"lease_unknown",
-                13:"lease_active",
-                }
-
-DHCPOptions = {
-    0: "pad",
-    1: IPField("subnet_mask", "0.0.0.0"),
-    2: "time_zone",
-    3: IPField("router","0.0.0.0"),
-    4: IPField("time_server","0.0.0.0"),
-    5: IPField("IEN_name_server","0.0.0.0"),
-    6: IPField("name_server","0.0.0.0"),
-    7: IPField("log_server","0.0.0.0"),
-    8: IPField("cookie_server","0.0.0.0"),
-    9: IPField("lpr_server","0.0.0.0"),
-    12: "hostname",
-    14: "dump_path",
-    15: "domain",
-    17: "root_disk_path",
-    22: "max_dgram_reass_size",
-    23: "default_ttl",
-    24: "pmtu_timeout",
-    28: IPField("broadcast_address","0.0.0.0"),
-    35: "arp_cache_timeout",
-    36: "ether_or_dot3",
-    37: "tcp_ttl",
-    38: "tcp_keepalive_interval",
-    39: "tcp_keepalive_garbage",
-    40: "NIS_domain",
-    41: IPField("NIS_server","0.0.0.0"),
-    42: IPField("NTP_server","0.0.0.0"),
-    43: "vendor_specific",
-    44: IPField("NetBIOS_server","0.0.0.0"),
-    45: IPField("NetBIOS_dist_server","0.0.0.0"),
-    50: IPField("requested_addr","0.0.0.0"),
-    51: IntField("lease_time", 43200),
-    54: IPField("server_id","0.0.0.0"),
-    55: "param_req_list",
-    57: ShortField("max_dhcp_size", 1500),
-    58: IntField("renewal_time", 21600),
-    59: IntField("rebinding_time", 37800),
-    60: "vendor_class_id",
-    61: "client_id",
-    
-    64: "NISplus_domain",
-    65: IPField("NISplus_server","0.0.0.0"),
-    69: IPField("SMTP_server","0.0.0.0"),
-    70: IPField("POP3_server","0.0.0.0"),
-    71: IPField("NNTP_server","0.0.0.0"),
-    72: IPField("WWW_server","0.0.0.0"),
-    73: IPField("Finger_server","0.0.0.0"),
-    74: IPField("IRC_server","0.0.0.0"),
-    75: IPField("StreetTalk_server","0.0.0.0"),
-    76: "StreetTalk_Dir_Assistance",
-    82: "relay_agent_Information",
-    53: ByteEnumField("message-type", 1, DHCPTypes),
-    #             55: DHCPRequestListField("request-list"),
-    255: "end"
-    }
-
-DHCPRevOptions = {}
-
-for k,v in DHCPOptions.iteritems():
-    if type(v) is str:
-        n = v
-        v = None
-    else:
-        n = v.name
-    DHCPRevOptions[n] = (k,v)
-del(n)
-del(v)
-del(k)
-    
-    
-
-
-
-class DHCPOptionsField(StrField):
-    islist=1
-    def i2repr(self,pkt,x):
-        s = []
-        for v in x:
-            if type(v) is tuple and len(v) in [2,3]:
-                if  DHCPRevOptions.has_key(v[0]) and isinstance(DHCPRevOptions[v[0]][1],Field):
-                    f = DHCPRevOptions[v[0]][1]
-                    vv = f.i2repr(pkt,v[1])
-                else:
-                    vv = repr(v[1])
-                r = "%s=%s" % (v[0],vv)
-                if len(v) > 2:
-                    r += " (garbage=%r)" % v[2]
-                s.append(r)
-            else:
-                s.append(sane(v))
-        return "[%s]" % (" ".join(s))
-        
-    def getfield(self, pkt, s):
-        return "", self.m2i(pkt, s)
-    def m2i(self, pkt, x):
-        opt = []
-        while x:
-            o = ord(x[0])
-            if o == 255:
-                opt.append("end")
-                x = x[1:]
-                continue
-            if o == 0:
-                opt.append("pad")
-                x = x[1:]
-                continue
-            if len(x) < 2 or len(x) < ord(x[1])+2:
-                opt.append(x)
-                break
-            elif DHCPOptions.has_key(o):
-                f = DHCPOptions[o]
-
-                if isinstance(f, str):
-                    olen = ord(x[1])
-                    opt.append( (f,x[2:olen+2]) )
-                    x = x[olen+2:]
-                else:
-                    olen = ord(x[1])
-                    try:
-                        left, val = f.getfield(pkt,x[2:olen+2])
-                    except:
-                        opt.append(x)
-                        break
-                    if left:
-                        otuple = (f.name, val, left)
-                    else:
-                        otuple = (f.name, val)
-                    opt.append(otuple)
-                    x = x[olen+2:]
-            else:
-                olen = ord(x[1])
-                opt.append((o, x[2:olen+2]))
-                x = x[olen+2:]
-        return opt
-    def i2m(self, pkt, x):
-        if type(x) is str:
-            return x
-        s = ""
-        for o in x:
-            if type(o) is tuple and len(o) in [2,3]:
-                name, val = o[:2]
-
-                if isinstance(name, int):
-                    onum, oval = name, val
-                elif DHCPRevOptions.has_key(name):
-                    onum, f = DHCPRevOptions[name]
-                    if  f is None:
-                        oval = val
-                    else:
-                        oval = f.addfield(pkt,"",f.any2i(pkt,val))
-                else:
-                    warning("Unknown field option %s" % name)
-                    continue
-                if len(o) > 2:
-                    oval += o[2]
-
-                s += chr(onum)
-                s += chr(len(oval))
-                s += oval
-
-            elif (type(o) is str and DHCPRevOptions.has_key(o) and 
-                  DHCPRevOptions[o][1] == None):
-                s += chr(DHCPRevOptions[o][0])
-            elif type(o) is int:
-                s += chr(o)+"\0"
-            elif type(o) is str:
-                s += o
-            else:
-                warning("Malformed option %s" % o)
-        return s
-
-
-class DHCP(Packet):
-    name = "DHCP options"
-    fields_desc = [ DHCPOptionsField("options","") ]
-
-
-class Dot11(Packet):
-    name = "802.11"
-    fields_desc = [
-                    BitField("subtype", 0, 4),
-                    BitEnumField("type", 0, 2, ["Management", "Control", "Data", "Reserved"]),
-                    BitField("proto", 0, 2),
-                    FlagsField("FCfield", 0, 8, ["to-DS", "from-DS", "MF", "retry", "pw-mgt", "MD", "wep", "order"]),
-                    ShortField("ID",0),
-                    MACField("addr1", ETHER_ANY),
-                    Dot11Addr2MACField("addr2", ETHER_ANY),
-                    Dot11Addr3MACField("addr3", ETHER_ANY),
-                    Dot11SCField("SC", 0),
-                    Dot11Addr4MACField("addr4", ETHER_ANY) 
-                    ]
-    def mysummary(self):
-        return self.sprintf("802.11 %Dot11.type% %Dot11.subtype% %Dot11.addr2% > %Dot11.addr1%")
-    def guess_payload_class(self, payload):
-        if self.type == 0x02 and (self.subtype >= 0x08 and self.subtype <=0xF and self.subtype != 0xD):
-            return Dot11QoS
-	elif self.FCfield & 0x40:
-            return Dot11WEP
-        else:
-            return Packet.guess_payload_class(self, payload)
-    def answers(self, other):
-        if isinstance(other,Dot11):
-            if self.type == 0: # management
-                if self.addr1.lower() != other.addr2.lower(): # check resp DA w/ req SA
-                    return 0
-                if (other.subtype,self.subtype) in [(0,1),(2,3),(4,5)]:
-                    return 1
-                if self.subtype == other.subtype == 11: # auth
-                    return self.payload.answers(other.payload)
-            elif self.type == 1: # control
-                return 0
-            elif self.type == 2: # data
-                return self.payload.answers(other.payload)
-            elif self.type == 3: # reserved
-                return 0
-        return 0
-    def unwep(self, key=None, warn=1):
-        if self.FCfield & 0x40 == 0:
-            if warn:
-                warning("No WEP to remove")
-            return
-        if  isinstance(self.payload.payload, NoPayload):
-            if key or conf.wepkey:
-                self.payload.decrypt(key)
-            if isinstance(self.payload.payload, NoPayload):
-                if warn:
-                    warning("Dot11 can't be decrypted. Check conf.wepkey.")
-                return
-        self.FCfield &= ~0x40
-        self.payload=self.payload.payload
-
-
-class Dot11QoS(Packet):
-    name = "802.11 QoS"
-    fields_desc = [ BitField("TID",None,4),
-                    BitField("EOSP",None,1),
-                    BitField("Ack Policy",None,2),
-                    BitField("Reserved",None,1),
-                    ByteField("TXOP",None) ]
-    def guess_payload_class(self, payload):
-        if isinstance(self.underlayer, Dot11):
-            if self.underlayer.FCfield & 0x40:
-                return Dot11WEP
-        return Packet.guess_payload_class(self, payload)
-
-
-capability_list = [ "res8", "res9", "short-slot", "res11",
-                    "res12", "DSSS-OFDM", "res14", "res15",
-                   "ESS", "IBSS", "CFP", "CFP-req",
-                   "privacy", "short-preamble", "PBCC", "agility"]
-
-reason_code = {0:"reserved",1:"unspec", 2:"auth-expired",
-               3:"deauth-ST-leaving",
-               4:"inactivity", 5:"AP-full", 6:"class2-from-nonauth",
-               7:"class3-from-nonass", 8:"disas-ST-leaving",
-               9:"ST-not-auth"}
-
-status_code = {0:"success", 1:"failure", 10:"cannot-support-all-cap",
-               11:"inexist-asso", 12:"asso-denied", 13:"algo-unsupported",
-               14:"bad-seq-num", 15:"challenge-failure",
-               16:"timeout", 17:"AP-full",18:"rate-unsupported" }
-
-class Dot11Beacon(Packet):
-    name = "802.11 Beacon"
-    fields_desc = [ LELongField("timestamp", 0),
-                    LEShortField("beacon_interval", 0x0064),
-                    FlagsField("cap", 0, 16, capability_list) ]
-    
-
-class Dot11Elt(Packet):
-    name = "802.11 Information Element"
-    fields_desc = [ ByteEnumField("ID", 0, {0:"SSID", 1:"Rates", 2: "FHset", 3:"DSset", 4:"CFset", 5:"TIM", 6:"IBSSset", 16:"challenge",
-                                            42:"ERPinfo", 46:"QoS Capability", 47:"ERPinfo", 48:"RSNinfo", 50:"ESRates",221:"vendor",68:"reserved"}),
-                    FieldLenField("len", None, "info", "B"),
-                    StrLenField("info", "", length_from=lambda x:x.len) ]
-    def mysummary(self):
-        if self.ID == 0:
-            return "SSID=%s"%repr(self.info),[Dot11]
-        else:
-            return ""
-
-class Dot11ATIM(Packet):
-    name = "802.11 ATIM"
-
-class Dot11Disas(Packet):
-    name = "802.11 Disassociation"
-    fields_desc = [ LEShortEnumField("reason", 1, reason_code) ]
-
-class Dot11AssoReq(Packet):
-    name = "802.11 Association Request"
-    fields_desc = [ FlagsField("cap", 0, 16, capability_list),
-                    LEShortField("listen_interval", 0x00c8) ]
-
-
-class Dot11AssoResp(Packet):
-    name = "802.11 Association Response"
-    fields_desc = [ FlagsField("cap", 0, 16, capability_list),
-                    LEShortField("status", 0),
-                    LEShortField("AID", 0) ]
-
-class Dot11ReassoReq(Packet):
-    name = "802.11 Reassociation Request"
-    fields_desc = [ FlagsField("cap", 0, 16, capability_list),
-                    MACField("current_AP", ETHER_ANY),
-                    LEShortField("listen_interval", 0x00c8) ]
-
-
-class Dot11ReassoResp(Dot11AssoResp):
-    name = "802.11 Reassociation Response"
-
-class Dot11ProbeReq(Packet):
-    name = "802.11 Probe Request"
-    
-class Dot11ProbeResp(Packet):
-    name = "802.11 Probe Response"
-    fields_desc = [ LELongField("timestamp", 0),
-                    LEShortField("beacon_interval", 0x0064),
-                    FlagsField("cap", 0, 16, capability_list) ]
-    
-class Dot11Auth(Packet):
-    name = "802.11 Authentication"
-    fields_desc = [ LEShortEnumField("algo", 0, ["open", "sharedkey"]),
-                    LEShortField("seqnum", 0),
-                    LEShortEnumField("status", 0, status_code) ]
-    def answers(self, other):
-        if self.seqnum == other.seqnum+1:
-            return 1
-        return 0
-
-class Dot11Deauth(Packet):
-    name = "802.11 Deauthentication"
-    fields_desc = [ LEShortEnumField("reason", 1, reason_code) ]
-
-
-
-class Dot11WEP(Packet):
-    name = "802.11 WEP packet"
-    fields_desc = [ StrFixedLenField("iv", "\0\0\0", 3),
-                    ByteField("keyid", 0),
-                    StrField("wepdata",None,remain=4),
-                    IntField("icv",None) ]
-
-    def post_dissect(self, s):
-#        self.icv, = struct.unpack("!I",self.wepdata[-4:])
-#        self.wepdata = self.wepdata[:-4]
-        self.decrypt()
-
-    def build_payload(self):
-        if self.wepdata is None:
-            return Packet.build_payload(self)
-        return ""
-
-    def post_build(self, p, pay):
-        if self.wepdata is None:
-            key = conf.wepkey
-            if key:
-                if self.icv is None:
-                    pay += struct.pack("<I",crc32(pay))
-                    icv = ""
-                else:
-                    icv = p[4:8]
-                c = ARC4.new(self.iv+key)
-                p = p[:4]+c.encrypt(pay)+icv
-            else:
-                warning("No WEP key set (conf.wepkey).. strange results expected..")
-        return p
-            
-
-    def decrypt(self,key=None):
-        if key is None:
-            key = conf.wepkey
-        if key:
-            c = ARC4.new(self.iv+key)
-            self.add_payload(LLC(c.decrypt(self.wepdata)))
-                    
-
-
-class PrismHeader(Packet):
-    """ iwpriv wlan0 monitor 3 """
-    name = "Prism header"
-    fields_desc = [ LEIntField("msgcode",68),
-                    LEIntField("len",144),
-                    StrFixedLenField("dev","",16),
-                    LEIntField("hosttime_did",0),
-                  LEShortField("hosttime_status",0),
-                  LEShortField("hosttime_len",0),
-                    LEIntField("hosttime",0),
-                    LEIntField("mactime_did",0),
-                  LEShortField("mactime_status",0),
-                  LEShortField("mactime_len",0),
-                    LEIntField("mactime",0),
-                    LEIntField("channel_did",0),
-                  LEShortField("channel_status",0),
-                  LEShortField("channel_len",0),
-                    LEIntField("channel",0),
-                    LEIntField("rssi_did",0),
-                  LEShortField("rssi_status",0),
-                  LEShortField("rssi_len",0),
-                    LEIntField("rssi",0),
-                    LEIntField("sq_did",0),
-                  LEShortField("sq_status",0),
-                  LEShortField("sq_len",0),
-                    LEIntField("sq",0),
-                    LEIntField("signal_did",0),
-                  LEShortField("signal_status",0),
-                  LEShortField("signal_len",0),
-              LESignedIntField("signal",0),
-                    LEIntField("noise_did",0),
-                  LEShortField("noise_status",0),
-                  LEShortField("noise_len",0),
-                    LEIntField("noise",0),
-                    LEIntField("rate_did",0),
-                  LEShortField("rate_status",0),
-                  LEShortField("rate_len",0),
-                    LEIntField("rate",0),
-                    LEIntField("istx_did",0),
-                  LEShortField("istx_status",0),
-                  LEShortField("istx_len",0),
-                    LEIntField("istx",0),
-                    LEIntField("frmlen_did",0),
-                  LEShortField("frmlen_status",0),
-                  LEShortField("frmlen_len",0),
-                    LEIntField("frmlen",0),
-                    ]
-    def answers(self, other):
-        if isinstance(other, PrismHeader):
-            return self.payload.answers(other.payload)
-        else:
-            return self.payload.answers(other)
-
-
-
-class HSRP(Packet):
-    name = "HSRP"
-    fields_desc = [
-        ByteField("version", 0),
-        ByteEnumField("opcode", 0, { 0:"Hello"}),
-        ByteEnumField("state", 16, { 16:"Active"}),
-        ByteField("hellotime", 3),
-        ByteField("holdtime", 10),
-        ByteField("priority", 120),
-        ByteField("group", 1),
-        ByteField("reserved", 0),
-        StrFixedLenField("auth","cisco",8),
-        IPField("virtualIP","192.168.1.1") ]
-        
-
-
-        
-        
-
-
-class NTP(Packet):
-    # RFC 1769
-    name = "NTP"
-    fields_desc = [ 
-         BitEnumField('leap', 0, 2,
-                      { 0: 'nowarning',
-                        1: 'longminute',
-                        2: 'shortminute',
-                        3: 'notsync'}),
-         BitField('version', 3, 3),
-         BitEnumField('mode', 3, 3,
-                      { 0: 'reserved',
-                        1: 'sym_active',
-                        2: 'sym_passive',
-                        3: 'client',
-                        4: 'server',
-                        5: 'broadcast',
-                        6: 'control',
-                        7: 'private'}),
-         BitField('stratum', 2, 8),
-         BitField('poll', 0xa, 8),          ### XXX : it's a signed int
-         BitField('precision', 0, 8),       ### XXX : it's a signed int
-         FloatField('delay', 0, 32),
-         FloatField('dispersion', 0, 32),
-         IPField('id', "127.0.0.1"),
-         TimeStampField('ref', 0, 64),
-         TimeStampField('orig', -1, 64),  # -1 means current time
-         TimeStampField('recv', 0, 64),
-         TimeStampField('sent', -1, 64) 
-         ]
-    def mysummary(self):
-        return self.sprintf("NTP v%ir,NTP.version%, %NTP.mode%")
-
-
-class GRE(Packet):
-    name = "GRE"
-    fields_desc = [ BitField("chksumpresent",0,1),
-                    BitField("reserved0",0,12),
-                    BitField("version",0,3),
-                    XShortEnumField("proto", 0x0000, ETHER_TYPES),
-                    ConditionalField(XShortField("chksum",None),lambda pkt:pkt.chksumpresent==1),
-                    ConditionalField(XShortField("reserved1",None),lambda pkt:pkt.chksumpresent==1),
-                    ]
-    def post_build(self, p, pay):
-        p += pay
-        if self.chksumpresent and self.chksum is None:
-            c = checksum(p)
-            p = p[:4]+chr((c>>8)&0xff)+chr(c&0xff)+p[6:]
-        return p
-            
-
-class Radius(Packet):
-    name = "Radius"
-    fields_desc = [ ByteEnumField("code", 1, {1: "Access-Request",
-                                              2: "Access-Accept",
-                                              3: "Access-Reject",
-                                              4: "Accounting-Request",
-                                              5: "Accounting-Accept",
-                                              6: "Accounting-Status",
-                                              7: "Password-Request",
-                                              8: "Password-Ack",
-                                              9: "Password-Reject",
-                                              10: "Accounting-Message",
-                                              11: "Access-Challenge",
-                                              12: "Status-Server",
-                                              13: "Status-Client",
-                                              21: "Resource-Free-Request",
-                                              22: "Resource-Free-Response",
-                                              23: "Resource-Query-Request",
-                                              24: "Resource-Query-Response",
-                                              25: "Alternate-Resource-Reclaim-Request",
-                                              26: "NAS-Reboot-Request",
-                                              27: "NAS-Reboot-Response",
-                                              29: "Next-Passcode",
-                                              30: "New-Pin",
-                                              31: "Terminate-Session",
-                                              32: "Password-Expired",
-                                              33: "Event-Request",
-                                              34: "Event-Response",
-                                              40: "Disconnect-Request",
-                                              41: "Disconnect-ACK",
-                                              42: "Disconnect-NAK",
-                                              43: "CoA-Request",
-                                              44: "CoA-ACK",
-                                              45: "CoA-NAK",
-                                              50: "IP-Address-Allocate",
-                                              51: "IP-Address-Release",
-                                              253: "Experimental-use",
-                                              254: "Reserved",
-                                              255: "Reserved"} ),
-                    ByteField("id", 0),
-                    ShortField("len", None),
-                    StrFixedLenField("authenticator","",16) ]
-    def post_build(self, p, pay):
-        p += pay
-        l = self.len
-        if l is None:
-            l = len(p)
-            p = p[:2]+struct.pack("!H",l)+p[4:]
-        return p
-
-
-
-
-class RIP(Packet):
-    name = "RIP header"
-    fields_desc = [
-        ByteEnumField("command",1,{1:"req",2:"resp",3:"traceOn",4:"traceOff",5:"sun",
-                                   6:"trigReq",7:"trigResp",8:"trigAck",9:"updateReq",
-                                   10:"updateResp",11:"updateAck"}),
-        ByteField("version",1),
-        ShortField("null",0),
-        ]
-
-class RIPEntry(Packet):
-    name = "RIP entry"
-    fields_desc = [
-        ShortEnumField("AF",2,{2:"IP"}),
-        ShortField("RouteTag",0),
-        IPField("addr","0.0.0.0"),
-        IPField("mask","0.0.0.0"),
-        IPField("nextHop","0.0.0.0"),
-        IntEnumField("metric",1,{16:"Unreach"}),
-        ]
-        
-
-
-
-ISAKMP_payload_type = ["None","SA","Proposal","Transform","KE","ID","CERT","CR","Hash",
-                       "SIG","Nonce","Notification","Delete","VendorID"]
-
-ISAKMP_exchange_type = ["None","base","identity prot.",
-                        "auth only", "aggressive", "info"]
-
-
-class ISAKMP_class(Packet):
-    def guess_payload_class(self, payload):
-        np = self.next_payload
-        if np == 0:
-            return Raw
-        elif np < len(ISAKMP_payload_type):
-            pt = ISAKMP_payload_type[np]
-            return globals().get("ISAKMP_payload_%s" % pt, ISAKMP_payload)
-        else:
-            return ISAKMP_payload
-
-
-class ISAKMP(ISAKMP_class): # rfc2408
-    name = "ISAKMP"
-    fields_desc = [
-        StrFixedLenField("init_cookie","",8),
-        StrFixedLenField("resp_cookie","",8),
-        ByteEnumField("next_payload",0,ISAKMP_payload_type),
-        XByteField("version",0x10),
-        ByteEnumField("exch_type",0,ISAKMP_exchange_type),
-        FlagsField("flags",0, 8, ["encryption","commit","auth_only","res3","res4","res5","res6","res7"]), # XXX use a Flag field
-        IntField("id",0),
-        IntField("length",None)
-        ]
-
-    def guess_payload_class(self, payload):
-        if self.flags & 1:
-            return Raw
-        return ISAKMP_class.guess_payload_class(self, payload)
-
-    def answers(self, other):
-        if isinstance(other, ISAKMP):
-            if other.init_cookie == self.init_cookie:
-                return 1
-        return 0
-    def post_build(self, p, pay):
-        p += pay
-        if self.length is None:
-            p = p[:24]+struct.pack("!I",len(p))+p[28:]
-        return p
-       
-
-
-
-class ISAKMP_payload_Transform(ISAKMP_class):
-    name = "IKE Transform"
-    fields_desc = [
-        ByteEnumField("next_payload",None,ISAKMP_payload_type),
-        ByteField("res",0),
-#        ShortField("len",None),
-        ShortField("length",None),
-        ByteField("num",None),
-        ByteEnumField("id",1,{1:"KEY_IKE"}),
-        ShortField("res2",0),
-        ISAKMPTransformSetField("transforms",None,length_from=lambda x:x.length-8)
-#        XIntField("enc",0x80010005L),
-#        XIntField("hash",0x80020002L),
-#        XIntField("auth",0x80030001L),
-#        XIntField("group",0x80040002L),
-#        XIntField("life_type",0x800b0001L),
-#        XIntField("durationh",0x000c0004L),
-#        XIntField("durationl",0x00007080L),
-        ]
-    def post_build(self, p, pay):
-        if self.length is None:
-            l = len(p)
-            p = p[:2]+chr((l>>8)&0xff)+chr(l&0xff)+p[4:]
-        p += pay
-        return p
-            
-
-
-        
-class ISAKMP_payload_Proposal(ISAKMP_class):
-    name = "IKE proposal"
-#    ISAKMP_payload_type = 0
-    fields_desc = [
-        ByteEnumField("next_payload",None,ISAKMP_payload_type),
-        ByteField("res",0),
-        FieldLenField("length",None,"trans","H", adjust=lambda pkt,x:x+8),
-        ByteField("proposal",1),
-        ByteEnumField("proto",1,{1:"ISAKMP"}),
-        FieldLenField("SPIsize",None,"SPI","B"),
-        ByteField("trans_nb",None),
-        StrLenField("SPI","",length_from=lambda x:x.SPIsize),
-        PacketLenField("trans",Raw(),ISAKMP_payload_Transform,length_from=lambda x:x.length-8),
-        ]
-
-
-class ISAKMP_payload(ISAKMP_class):
-    name = "ISAKMP payload"
-    fields_desc = [
-        ByteEnumField("next_payload",None,ISAKMP_payload_type),
-        ByteField("res",0),
-        FieldLenField("length",None,"load","H", adjust=lambda pkt,x:x+4),
-        StrLenField("load","",length_from=lambda x:x.length-4),
-        ]
-
-
-class ISAKMP_payload_VendorID(ISAKMP_class):
-    name = "ISAKMP Vendor ID"
-    overload_fields = { ISAKMP: { "next_payload":13 }}
-    fields_desc = [
-        ByteEnumField("next_payload",None,ISAKMP_payload_type),
-        ByteField("res",0),
-        FieldLenField("length",None,"vendorID","H", adjust=lambda pkt,x:x+4),
-        StrLenField("vendorID","",length_from=lambda x:x.length-4),
-        ]
-
-class ISAKMP_payload_SA(ISAKMP_class):
-    name = "ISAKMP SA"
-    overload_fields = { ISAKMP: { "next_payload":1 }}
-    fields_desc = [
-        ByteEnumField("next_payload",None,ISAKMP_payload_type),
-        ByteField("res",0),
-        FieldLenField("length",None,"prop","H", adjust=lambda pkt,x:x+12),
-        IntEnumField("DOI",1,{1:"IPSEC"}),
-        IntEnumField("situation",1,{1:"identity"}),
-        PacketLenField("prop",Raw(),ISAKMP_payload_Proposal,length_from=lambda x:x.length-12),
-        ]
-
-class ISAKMP_payload_Nonce(ISAKMP_class):
-    name = "ISAKMP Nonce"
-    overload_fields = { ISAKMP: { "next_payload":10 }}
-    fields_desc = [
-        ByteEnumField("next_payload",None,ISAKMP_payload_type),
-        ByteField("res",0),
-        FieldLenField("length",None,"load","H", adjust=lambda pkt,x:x+4),
-        StrLenField("load","",length_from=lambda x:x.length-4),
-        ]
-
-class ISAKMP_payload_KE(ISAKMP_class):
-    name = "ISAKMP Key Exchange"
-    overload_fields = { ISAKMP: { "next_payload":4 }}
-    fields_desc = [
-        ByteEnumField("next_payload",None,ISAKMP_payload_type),
-        ByteField("res",0),
-        FieldLenField("length",None,"load","H", adjust=lambda pkt,x:x+4),
-        StrLenField("load","",length_from=lambda x:x.length-4),
-        ]
-
-class ISAKMP_payload_ID(ISAKMP_class):
-    name = "ISAKMP Identification"
-    overload_fields = { ISAKMP: { "next_payload":5 }}
-    fields_desc = [
-        ByteEnumField("next_payload",None,ISAKMP_payload_type),
-        ByteField("res",0),
-        FieldLenField("length",None,"load","H",adjust=lambda pkt,x:x+8),
-        ByteEnumField("IDtype",1,{1:"IPv4_addr", 11:"Key"}),
-        ByteEnumField("ProtoID",0,{0:"Unused"}),
-        ShortEnumField("Port",0,{0:"Unused"}),
-#        IPField("IdentData","127.0.0.1"),
-        StrLenField("load","",length_from=lambda x:x.length-8),
-        ]
-
-
-
-class ISAKMP_payload_Hash(ISAKMP_class):
-    name = "ISAKMP Hash"
-    overload_fields = { ISAKMP: { "next_payload":8 }}
-    fields_desc = [
-        ByteEnumField("next_payload",None,ISAKMP_payload_type),
-        ByteField("res",0),
-        FieldLenField("length",None,"load","H",adjust=lambda pkt,x:x+4),
-        StrLenField("load","",length_from=lambda x:x.length-4),
-        ]
-
-
-
-ISAKMP_payload_type_overload = {}
-for i in range(len(ISAKMP_payload_type)):
-    name = "ISAKMP_payload_%s" % ISAKMP_payload_type[i]
-    if name in globals():
-        ISAKMP_payload_type_overload[globals()[name]] = {"next_payload":i}
-
-del(i)
-del(name)
-ISAKMP_class.overload_fields = ISAKMP_payload_type_overload.copy()
-
-
-        
-
-# Cisco Skinny protocol
-
-# shamelessly ripped from Ethereal dissector
-skinny_messages = { 
-# Station -> Callmanager
-  0x0000: "KeepAliveMessage",
-  0x0001: "RegisterMessage",
-  0x0002: "IpPortMessage",
-  0x0003: "KeypadButtonMessage",
-  0x0004: "EnblocCallMessage",
-  0x0005: "StimulusMessage",
-  0x0006: "OffHookMessage",
-  0x0007: "OnHookMessage",
-  0x0008: "HookFlashMessage",
-  0x0009: "ForwardStatReqMessage",
-  0x000A: "SpeedDialStatReqMessage",
-  0x000B: "LineStatReqMessage",
-  0x000C: "ConfigStatReqMessage",
-  0x000D: "TimeDateReqMessage",
-  0x000E: "ButtonTemplateReqMessage",
-  0x000F: "VersionReqMessage",
-  0x0010: "CapabilitiesResMessage",
-  0x0011: "MediaPortListMessage",
-  0x0012: "ServerReqMessage",
-  0x0020: "AlarmMessage",
-  0x0021: "MulticastMediaReceptionAck",
-  0x0022: "OpenReceiveChannelAck",
-  0x0023: "ConnectionStatisticsRes",
-  0x0024: "OffHookWithCgpnMessage",
-  0x0025: "SoftKeySetReqMessage",
-  0x0026: "SoftKeyEventMessage",
-  0x0027: "UnregisterMessage",
-  0x0028: "SoftKeyTemplateReqMessage",
-  0x0029: "RegisterTokenReq",
-  0x002A: "MediaTransmissionFailure",
-  0x002B: "HeadsetStatusMessage",
-  0x002C: "MediaResourceNotification",
-  0x002D: "RegisterAvailableLinesMessage",
-  0x002E: "DeviceToUserDataMessage",
-  0x002F: "DeviceToUserDataResponseMessage",
-  0x0030: "UpdateCapabilitiesMessage",
-  0x0031: "OpenMultiMediaReceiveChannelAckMessage",
-  0x0032: "ClearConferenceMessage",
-  0x0033: "ServiceURLStatReqMessage",
-  0x0034: "FeatureStatReqMessage",
-  0x0035: "CreateConferenceResMessage",
-  0x0036: "DeleteConferenceResMessage",
-  0x0037: "ModifyConferenceResMessage",
-  0x0038: "AddParticipantResMessage",
-  0x0039: "AuditConferenceResMessage",
-  0x0040: "AuditParticipantResMessage",
-  0x0041: "DeviceToUserDataVersion1Message",
-# Callmanager -> Station */
-  0x0081: "RegisterAckMessage",
-  0x0082: "StartToneMessage",
-  0x0083: "StopToneMessage",
-  0x0085: "SetRingerMessage",
-  0x0086: "SetLampMessage",
-  0x0087: "SetHkFDetectMessage",
-  0x0088: "SetSpeakerModeMessage",
-  0x0089: "SetMicroModeMessage",
-  0x008A: "StartMediaTransmission",
-  0x008B: "StopMediaTransmission",
-  0x008C: "StartMediaReception",
-  0x008D: "StopMediaReception",
-  0x008F: "CallInfoMessage",
-  0x0090: "ForwardStatMessage",
-  0x0091: "SpeedDialStatMessage",
-  0x0092: "LineStatMessage",
-  0x0093: "ConfigStatMessage",
-  0x0094: "DefineTimeDate",
-  0x0095: "StartSessionTransmission",
-  0x0096: "StopSessionTransmission",
-  0x0097: "ButtonTemplateMessage",
-  0x0098: "VersionMessage",
-  0x0099: "DisplayTextMessage",
-  0x009A: "ClearDisplay",
-  0x009B: "CapabilitiesReqMessage",
-  0x009C: "EnunciatorCommandMessage",
-  0x009D: "RegisterRejectMessage",
-  0x009E: "ServerResMessage",
-  0x009F: "Reset",
-  0x0100: "KeepAliveAckMessage",
-  0x0101: "StartMulticastMediaReception",
-  0x0102: "StartMulticastMediaTransmission",
-  0x0103: "StopMulticastMediaReception",
-  0x0104: "StopMulticastMediaTransmission",
-  0x0105: "OpenReceiveChannel",
-  0x0106: "CloseReceiveChannel",
-  0x0107: "ConnectionStatisticsReq",
-  0x0108: "SoftKeyTemplateResMessage",
-  0x0109: "SoftKeySetResMessage",
-  0x0110: "SelectSoftKeysMessage",
-  0x0111: "CallStateMessage",
-  0x0112: "DisplayPromptStatusMessage",
-  0x0113: "ClearPromptStatusMessage",
-  0x0114: "DisplayNotifyMessage",
-  0x0115: "ClearNotifyMessage",
-  0x0116: "ActivateCallPlaneMessage",
-  0x0117: "DeactivateCallPlaneMessage",
-  0x0118: "UnregisterAckMessage",
-  0x0119: "BackSpaceReqMessage",
-  0x011A: "RegisterTokenAck",
-  0x011B: "RegisterTokenReject",
-  0x0042: "DeviceToUserDataResponseVersion1Message",
-  0x011C: "StartMediaFailureDetection",
-  0x011D: "DialedNumberMessage",
-  0x011E: "UserToDeviceDataMessage",
-  0x011F: "FeatureStatMessage",
-  0x0120: "DisplayPriNotifyMessage",
-  0x0121: "ClearPriNotifyMessage",
-  0x0122: "StartAnnouncementMessage",
-  0x0123: "StopAnnouncementMessage",
-  0x0124: "AnnouncementFinishMessage",
-  0x0127: "NotifyDtmfToneMessage",
-  0x0128: "SendDtmfToneMessage",
-  0x0129: "SubscribeDtmfPayloadReqMessage",
-  0x012A: "SubscribeDtmfPayloadResMessage",
-  0x012B: "SubscribeDtmfPayloadErrMessage",
-  0x012C: "UnSubscribeDtmfPayloadReqMessage",
-  0x012D: "UnSubscribeDtmfPayloadResMessage",
-  0x012E: "UnSubscribeDtmfPayloadErrMessage",
-  0x012F: "ServiceURLStatMessage",
-  0x0130: "CallSelectStatMessage",
-  0x0131: "OpenMultiMediaChannelMessage",
-  0x0132: "StartMultiMediaTransmission",
-  0x0133: "StopMultiMediaTransmission",
-  0x0134: "MiscellaneousCommandMessage",
-  0x0135: "FlowControlCommandMessage",
-  0x0136: "CloseMultiMediaReceiveChannel",
-  0x0137: "CreateConferenceReqMessage",
-  0x0138: "DeleteConferenceReqMessage",
-  0x0139: "ModifyConferenceReqMessage",
-  0x013A: "AddParticipantReqMessage",
-  0x013B: "DropParticipantReqMessage",
-  0x013C: "AuditConferenceReqMessage",
-  0x013D: "AuditParticipantReqMessage",
-  0x013F: "UserToDeviceDataVersion1Message",
-  }
-
-
-        
-class Skinny(Packet):
-    name="Skinny"
-    fields_desc = [ LEIntField("len",0),
-                    LEIntField("res",0),
-                    LEIntEnumField("msg",0,skinny_messages) ]
-
-_rtp_payload_types = {
-    # http://www.iana.org/assignments/rtp-parameters
-    0:  'G.711 PCMU',    3:  'GSM',
-    4:  'G723',    5:  'DVI4',
-    6:  'DVI4',    7:  'LPC',
-    8:  'PCMA',    9:  'G722',
-    10: 'L16',     11: 'L16',
-    12: 'QCELP',   13: 'CN',
-    14: 'MPA',     15: 'G728',
-    16: 'DVI4',    17: 'DVI4',
-    18: 'G729',    25: 'CelB',
-    26: 'JPEG',    28: 'nv',
-    31: 'H261',    32: 'MPV',
-    33: 'MP2T',    34: 'H263' }
-
-class RTP(Packet):
-    name="RTP"
-    fields_desc = [ BitField('version', 2, 2),
-                    BitField('padding', 0, 1),
-                    BitField('extension', 0, 1),
-                    BitFieldLenField('numsync', None, 4, count_of='sync'),
-                    BitField('marker', 0, 1),
-                    BitEnumField('payload', 0, 7, _rtp_payload_types),
-                    ShortField('sequence', 0),
-                    IntField('timestamp', 0),
-                    IntField('sourcesync', 0),
-                    FieldListField('sync', [], IntField("id",0), count_from=lambda pkt:pkt.numsync) ]
-    
-### SEBEK
-
-
-class SebekHead(Packet):
-    name = "Sebek header"
-    fields_desc = [ XIntField("magic", 0xd0d0d0),
-                    ShortField("version", 1),
-                    ShortEnumField("type", 0, {"read":0, "write":1,
-                                             "socket":2, "open":3}),
-                    IntField("counter", 0),
-                    IntField("time_sec", 0),
-                    IntField("time_usec", 0) ]
-    def mysummary(self):
-        return self.sprintf("Sebek Header v%SebekHead.version% %SebekHead.type%")
-
-# we need this because Sebek headers differ between v1 and v3, and
-# between v3 type socket and v3 others
-
-class SebekV1(Packet):
-    name = "Sebek v1"
-    fields_desc = [ IntField("pid", 0),
-                    IntField("uid", 0),
-                    IntField("fd", 0),
-                    StrFixedLenField("command", "", 12),
-                    FieldLenField("data_length", None, "data",fmt="I"),
-                    StrLenField("data", "", length_from=lambda x:x.data_length) ]
-    def mysummary(self):
-        if isinstance(self.underlayer, SebekHead):
-            return self.underlayer.sprintf("Sebek v1 %SebekHead.type% (%SebekV1.command%)")
-        else:
-            return self.sprintf("Sebek v1 (%SebekV1.command%)")
-
-class SebekV3(Packet):
-    name = "Sebek v3"
-    fields_desc = [ IntField("parent_pid", 0),
-                    IntField("pid", 0),
-                    IntField("uid", 0),
-                    IntField("fd", 0),
-                    IntField("inode", 0),
-                    StrFixedLenField("command", "", 12),
-                    FieldLenField("data_length", None, "data",fmt="I"),
-                    StrLenField("data", "", length_from=lambda x:x.data_length) ]
-    def mysummary(self):
-        if isinstance(self.underlayer, SebekHead):
-            return self.underlayer.sprintf("Sebek v%SebekHead.version% %SebekHead.type% (%SebekV3.command%)")
-        else:
-            return self.sprintf("Sebek v3 (%SebekV3.command%)")
-
-class SebekV2(SebekV3):
-    def mysummary(self):
-        if isinstance(self.underlayer, SebekHead):
-            return self.underlayer.sprintf("Sebek v%SebekHead.version% %SebekHead.type% (%SebekV2.command%)")
-        else:
-            return self.sprintf("Sebek v2 (%SebekV2.command%)")
-
-class SebekV3Sock(Packet):
-    name = "Sebek v2 socket"
-    fields_desc = [ IntField("parent_pid", 0),
-                    IntField("pid", 0),
-                    IntField("uid", 0),
-                    IntField("fd", 0),
-                    IntField("inode", 0),
-                    StrFixedLenField("command", "", 12),
-                    IntField("data_length", 15),
-                    IPField("dip", "127.0.0.1"),
-                    ShortField("dport", 0),
-                    IPField("sip", "127.0.0.1"),
-                    ShortField("sport", 0),
-                    ShortEnumField("call", 0, { "bind":2,
-                                                "connect":3, "listen":4,
-                                               "accept":5, "sendmsg":16,
-                                               "recvmsg":17, "sendto":11,
-                                               "recvfrom":12}),
-                    ByteEnumField("proto", 0, IP_PROTOS) ]
-    def mysummary(self):
-        if isinstance(self.underlayer, SebekHead):
-            return self.underlayer.sprintf("Sebek v%SebekHead.version% %SebekHead.type% (%SebekV3Sock.command%)")
-        else:
-            return self.sprintf("Sebek v3 socket (%SebekV3Sock.command%)")
-
-class SebekV2Sock(SebekV3Sock):
-    def mysummary(self):
-        if isinstance(self.underlayer, SebekHead):
-            return self.underlayer.sprintf("Sebek v%SebekHead.version% %SebekHead.type% (%SebekV2Sock.command%)")
-        else:
-            return self.sprintf("Sebek v2 socket (%SebekV2Sock.command%)")
-
-class MGCP(Packet):
-    name = "MGCP"
-    longname = "Media Gateway Control Protocol"
-    fields_desc = [ StrStopField("verb","AUEP"," ", -1),
-                    StrFixedLenField("sep1"," ",1),
-                    StrStopField("transaction_id","1234567"," ", -1),
-                    StrFixedLenField("sep2"," ",1),
-                    StrStopField("endpoint","dummy@dummy.net"," ", -1),
-                    StrFixedLenField("sep3"," ",1),
-                    StrStopField("version","MGCP 1.0 NCS 1.0","\x0a", -1),
-                    StrFixedLenField("sep4","\x0a",1),
-                    ]
-                    
-    
-#class MGCP(Packet):
-#    name = "MGCP"
-#    longname = "Media Gateway Control Protocol"
-#    fields_desc = [ ByteEnumField("type",0, ["request","response","others"]),
-#                    ByteField("code0",0),
-#                    ByteField("code1",0),
-#                    ByteField("code2",0),
-#                    ByteField("code3",0),
-#                    ByteField("code4",0),
-#                    IntField("trasid",0),
-#                    IntField("req_time",0),
-#                    ByteField("is_duplicate",0),
-#                    ByteField("req_available",0) ]
-#
-class GPRS(Packet):
-    name = "GPRSdummy"
-    fields_desc = [
-        StrStopField("dummy","","\x65\x00\x00",1)
-        ]
-
-
-class HCI_Hdr(Packet):
-    name = "HCI header"
-    fields_desc = [ ByteEnumField("type",2,{1:"command",2:"ACLdata",3:"SCOdata",4:"event",5:"vendor"}),]
-
-    def mysummary(self):
-        return self.sprintf("HCI %type%")
-
-class HCI_ACL_Hdr(Packet):
-    name = "HCI ACL header"
-    fields_desc = [ ByteField("handle",0), # Actually, handle is 12 bits and flags is 4.
-                    ByteField("flags",0),  # I wait to write a LEBitField
-                    LEShortField("len",None), ]
-    def post_build(self, p, pay):
-        p += pay
-        if self.len is None:
-            l = len(p)-4
-            p = p[:2]+chr(l&0xff)+chr((l>>8)&0xff)+p[4:]
-        return p
-                    
-
-class L2CAP_Hdr(Packet):
-    name = "L2CAP header"
-    fields_desc = [ LEShortField("len",None),
-                    LEShortEnumField("cid",0,{1:"control"}),]
-    
-    def post_build(self, p, pay):
-        p += pay
-        if self.len is None:
-            l = len(p)-4
-            p = p[:2]+chr(l&0xff)+chr((l>>8)&0xff)+p[4:]
-        return p
-                    
-                
-
-class L2CAP_CmdHdr(Packet):
-    name = "L2CAP command header"
-    fields_desc = [
-        ByteEnumField("code",8,{1:"rej",2:"conn_req",3:"conn_resp",
-                                4:"conf_req",5:"conf_resp",6:"disconn_req",
-                                7:"disconn_resp",8:"echo_req",9:"echo_resp",
-                                10:"info_req",11:"info_resp"}),
-        ByteField("id",0),
-        LEShortField("len",None) ]
-    def post_build(self, p, pay):
-        p += pay
-        if self.len is None:
-            l = len(p)-4
-            p = p[:2]+chr(l&0xff)+chr((l>>8)&0xff)+p[4:]
-        return p
-    def answers(self, other):
-        if other.id == self.id:
-            if self.code == 1:
-                return 1
-            if other.code in [2,4,6,8,10] and self.code == other.code+1:
-                if other.code == 8:
-                    return 1
-                return self.payload.answers(other.payload)
-        return 0
-
-class L2CAP_ConnReq(Packet):
-    name = "L2CAP Conn Req"
-    fields_desc = [ LEShortEnumField("psm",0,{1:"SDP",3:"RFCOMM",5:"telephony control"}),
-                    LEShortField("scid",0),
-                    ]
-
-class L2CAP_ConnResp(Packet):
-    name = "L2CAP Conn Resp"
-    fields_desc = [ LEShortField("dcid",0),
-                    LEShortField("scid",0),
-                    LEShortEnumField("result",0,["no_info","authen_pend","author_pend"]),
-                    LEShortEnumField("status",0,["success","pend","bad_psm",
-                                               "cr_sec_block","cr_no_mem"]),
-                    ]
-    def answers(self, other):
-        return self.scid == other.scid
-
-class L2CAP_CmdRej(Packet):
-    name = "L2CAP Command Rej"
-    fields_desc = [ LEShortField("reason",0),
-                    ]
-    
-
-class L2CAP_ConfReq(Packet):
-    name = "L2CAP Conf Req"
-    fields_desc = [ LEShortField("dcid",0),
-                    LEShortField("flags",0),
-                    ]
-
-class L2CAP_ConfResp(Packet):
-    name = "L2CAP Conf Resp"
-    fields_desc = [ LEShortField("scid",0),
-                    LEShortField("flags",0),
-                    LEShortEnumField("result",0,["success","unaccept","reject","unknown"]),
-                    ]
-    def answers(self, other):
-        return self.scid == other.scid
-
-
-class L2CAP_DisconnReq(Packet):
-    name = "L2CAP Disconn Req"
-    fields_desc = [ LEShortField("dcid",0),
-                    LEShortField("scid",0), ]
-
-class L2CAP_DisconnResp(Packet):
-    name = "L2CAP Disconn Resp"
-    fields_desc = [ LEShortField("dcid",0),
-                    LEShortField("scid",0), ]
-    def answers(self, other):
-        return self.scid == other.scid
-
-    
-
-class L2CAP_InfoReq(Packet):
-    name = "L2CAP Info Req"
-    fields_desc = [ LEShortEnumField("type",0,{1:"CL_MTU",2:"FEAT_MASK"}),
-                    StrField("data","")
-                    ]
-
-
-class L2CAP_InfoResp(Packet):
-    name = "L2CAP Info Resp"
-    fields_desc = [ LEShortField("type",0),
-                    LEShortEnumField("result",0,["success","not_supp"]),
-                    StrField("data",""), ]
-    def answers(self, other):
-        return self.type == other.type
-
-
-
-
-class NetBIOS_DS(Packet):
-    name = "NetBIOS datagram service"
-    fields_desc = [
-        ByteEnumField("type",17, {17:"direct_group"}),
-        ByteField("flags",0),
-        XShortField("id",0),
-        IPField("src","127.0.0.1"),
-        ShortField("sport",138),
-        ShortField("len",None),
-        ShortField("ofs",0),
-        NetBIOSNameField("srcname",""),
-        NetBIOSNameField("dstname",""),
-        ]
-    def post_build(self, p, pay):
-        p += pay
-        if self.len is None:
-            l = len(p)-14
-            p = p[:10]+struct.pack("!H", l)+p[12:]
-        return p
-        
-#        ShortField("length",0),
-#        ShortField("Delimitor",0),
-#        ByteField("command",0),
-#        ByteField("data1",0),
-#        ShortField("data2",0),
-#        ShortField("XMIt",0),
-#        ShortField("RSPCor",0),
-#        StrFixedLenField("dest","",16),
-#        StrFixedLenField("source","",16),
-#        
-#        ]
-#
-
-# IR
-
-class IrLAPHead(Packet):
-    name = "IrDA Link Access Protocol Header"
-    fields_desc = [ XBitField("Address", 0x7f, 7),
-                    BitEnumField("Type", 1, 1, {"Response":0,
-                                                "Command":1})]
-
-class IrLAPCommand(Packet):
-    name = "IrDA Link Access Protocol Command"
-    fields_desc = [ XByteField("Control", 0),
-                    XByteField("Format identifier", 0),
-                    XIntField("Source address", 0),
-                    XIntField("Destination address", 0xffffffffL),
-                    XByteField("Discovery flags", 0x1),
-                    ByteEnumField("Slot number", 255, {"final":255}),
-                    XByteField("Version", 0)]
-
-
-class IrLMP(Packet):
-    name = "IrDA Link Management Protocol"
-    fields_desc = [ XShortField("Service hints", 0),
-                    XByteField("Character set", 0),
-                    StrField("Device name", "") ]
-
-
-#NetBIOS
-
-
-# Name Query Request
-# Node Status Request
-class NBNSQueryRequest(Packet):
-    name="NBNS query request"
-    fields_desc = [ShortField("NAME_TRN_ID",0),
-                   ShortField("FLAGS", 0x0110),
-                   ShortField("QDCOUNT",1),
-                   ShortField("ANCOUNT",0),
-                   ShortField("NSCOUNT",0),
-                   ShortField("ARCOUNT",0),
-                   NetBIOSNameField("QUESTION_NAME","windows"),
-                   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"}),
-                   ByteField("NULL",0),
-                   ShortEnumField("QUESTION_TYPE",0x20, {0x20:"NB",0x21:"NBSTAT"}),
-                   ShortEnumField("QUESTION_CLASS",1,{1:"INTERNET"})]
-
-# Name Registration Request
-# Name Refresh Request
-# Name Release Request or Demand
-class NBNSRequest(Packet):
-    name="NBNS request"
-    fields_desc = [ShortField("NAME_TRN_ID",0),
-                   ShortField("FLAGS", 0x2910),
-                   ShortField("QDCOUNT",1),
-                   ShortField("ANCOUNT",0),
-                   ShortField("NSCOUNT",0),
-                   ShortField("ARCOUNT",1),
-                   NetBIOSNameField("QUESTION_NAME","windows"),
-                   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"}),
-                   ByteField("NULL",0),
-                   ShortEnumField("QUESTION_TYPE",0x20, {0x20:"NB",0x21:"NBSTAT"}),
-                   ShortEnumField("QUESTION_CLASS",1,{1:"INTERNET"}),
-                   ShortEnumField("RR_NAME",0xC00C,{0xC00C:"Label String Pointer to QUESTION_NAME"}),
-                   ShortEnumField("RR_TYPE",0x20, {0x20:"NB",0x21:"NBSTAT"}),
-                   ShortEnumField("RR_CLASS",1,{1:"INTERNET"}),
-                   IntField("TTL", 0),
-                   ShortField("RDLENGTH", 6),
-                   BitEnumField("G",0,1,{0:"Unique name",1:"Group name"}),
-                   BitEnumField("OWNER NODE TYPE",00,2,{00:"B node",01:"P node",02:"M node",03:"H node"}),
-                   BitEnumField("UNUSED",0,13,{0:"Unused"}),
-                   IPField("NB_ADDRESS", "127.0.0.1")]
-
-# Name Query Response
-# Name Registration Response
-class NBNSQueryResponse(Packet):
-    name="NBNS query response"
-    fields_desc = [ShortField("NAME_TRN_ID",0),
-                   ShortField("FLAGS", 0x8500),
-                   ShortField("QDCOUNT",0),
-                   ShortField("ANCOUNT",1),
-                   ShortField("NSCOUNT",0),
-                   ShortField("ARCOUNT",0),
-                   NetBIOSNameField("RR_NAME","windows"),
-                   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"}),
-                   ByteField("NULL",0),
-                   ShortEnumField("QUESTION_TYPE",0x20, {0x20:"NB",0x21:"NBSTAT"}),
-                   ShortEnumField("QUESTION_CLASS",1,{1:"INTERNET"}),
-                   IntField("TTL", 0x493e0),
-                   ShortField("RDLENGTH", 6),
-                   ShortField("NB_FLAGS", 0),
-                   IPField("NB_ADDRESS", "127.0.0.1")]
-
-# Name Query Response (negative)
-# Name Release Response
-class NBNSQueryResponseNegative(Packet):
-    name="NBNS query response (negative)"
-    fields_desc = [ShortField("NAME_TRN_ID",0), 
-                   ShortField("FLAGS", 0x8506),
-                   ShortField("QDCOUNT",0),
-                   ShortField("ANCOUNT",1),
-                   ShortField("NSCOUNT",0),
-                   ShortField("ARCOUNT",0),
-                   NetBIOSNameField("RR_NAME","windows"),
-                   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"}),
-                   ByteField("NULL",0),
-                   ShortEnumField("RR_TYPE",0x20, {0x20:"NB",0x21:"NBSTAT"}),
-                   ShortEnumField("RR_CLASS",1,{1:"INTERNET"}),
-                   IntField("TTL",0),
-                   ShortField("RDLENGTH",6),
-                   BitEnumField("G",0,1,{0:"Unique name",1:"Group name"}),
-                   BitEnumField("OWNER NODE TYPE",00,2,{00:"B node",01:"P node",02:"M node",03:"H node"}),
-                   BitEnumField("UNUSED",0,13,{0:"Unused"}),
-                   IPField("NB_ADDRESS", "127.0.0.1")]
-    
-# Node Status Response
-class NBNSNodeStatusResponse(Packet):
-    name="NBNS Node Status Response"
-    fields_desc = [ShortField("NAME_TRN_ID",0), 
-                   ShortField("FLAGS", 0x8500),
-                   ShortField("QDCOUNT",0),
-                   ShortField("ANCOUNT",1),
-                   ShortField("NSCOUNT",0),
-                   ShortField("ARCOUNT",0),
-                   NetBIOSNameField("RR_NAME","windows"),
-                   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"}),
-                   ByteField("NULL",0),
-                   ShortEnumField("RR_TYPE",0x21, {0x20:"NB",0x21:"NBSTAT"}),
-                   ShortEnumField("RR_CLASS",1,{1:"INTERNET"}),
-                   IntField("TTL",0),
-                   ShortField("RDLENGTH",83),
-                   ByteField("NUM_NAMES",1)]
-
-# Service for Node Status Response
-class NBNSNodeStatusResponseService(Packet):
-    name="NBNS Node Status Response Service"
-    fields_desc = [StrFixedLenField("NETBIOS_NAME","WINDOWS         ",15),
-                   ByteEnumField("SUFFIX",0,{0:"workstation",0x03:"messenger service",0x20:"file server service",0x1b:"domain master browser",0x1c:"domain controller", 0x1e:"browser election service"}),
-                   ByteField("NAME_FLAGS",0x4),
-                   ByteEnumField("UNUSED",0,{0:"unused"})]
-
-# End of Node Status Response packet
-class NBNSNodeStatusResponseEnd(Packet):
-    name="NBNS Node Status Response"
-    fields_desc = [SourceMACField("MAC_ADDRESS"),
-                   BitField("STATISTICS",0,57*8)]
-
-# Wait for Acknowledgement Response
-class NBNSWackResponse(Packet):
-    name="NBNS Wait for Acknowledgement Response"
-    fields_desc = [ShortField("NAME_TRN_ID",0),
-                   ShortField("FLAGS", 0xBC07),
-                   ShortField("QDCOUNT",0),
-                   ShortField("ANCOUNT",1),
-                   ShortField("NSCOUNT",0),
-                   ShortField("ARCOUNT",0),
-                   NetBIOSNameField("RR_NAME","windows"),
-                   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"}),
-                   ByteField("NULL",0),
-                   ShortEnumField("RR_TYPE",0x20, {0x20:"NB",0x21:"NBSTAT"}),
-                   ShortEnumField("RR_CLASS",1,{1:"INTERNET"}),
-                   IntField("TTL", 2),
-                   ShortField("RDLENGTH",2),
-                   BitField("RDATA",10512,16)] #10512=0010100100010000
-
-class NBTDatagram(Packet):
-    name="NBT Datagram Packet"
-    fields_desc= [ByteField("Type", 0x10),
-                  ByteField("Flags", 0x02),
-                  ShortField("ID", 0),
-                  IPField("SourceIP", "127.0.0.1"),
-                  ShortField("SourcePort", 138),
-                  ShortField("Length", 272),
-                  ShortField("Offset", 0),
-                  NetBIOSNameField("SourceName","windows"),
-                  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"}),
-                  ByteField("NULL",0),
-                  NetBIOSNameField("DestinationName","windows"),
-                  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"}),
-                  ByteField("NULL",0)]
-    
-
-class NBTSession(Packet):
-    name="NBT Session Packet"
-    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"}),
-                  BitField("RESERVED",0x00,7),
-                  BitField("LENGTH",0,17)]
-
-
-# SMB NetLogon Response Header
-class SMBNetlogon_Protocol_Response_Header(Packet):
-    name="SMBNetlogon Protocol Response Header"
-    fields_desc = [StrFixedLenField("Start","\xffSMB",4),
-                   ByteEnumField("Command",0x25,{0x25:"Trans"}),
-                   ByteField("Error_Class",0x02),
-                   ByteField("Reserved",0),
-                   LEShortField("Error_code",4),
-                   ByteField("Flags",0),
-                   LEShortField("Flags2",0x0000),
-                   LEShortField("PIDHigh",0x0000),
-                   LELongField("Signature",0x0),
-                   LEShortField("Unused",0x0),
-                   LEShortField("TID",0),
-                   LEShortField("PID",0),
-                   LEShortField("UID",0),
-                   LEShortField("MID",0),
-                   ByteField("WordCount",17),
-                   LEShortField("TotalParamCount",0),
-                   LEShortField("TotalDataCount",112),
-                   LEShortField("MaxParamCount",0),
-                   LEShortField("MaxDataCount",0),
-                   ByteField("MaxSetupCount",0),
-                   ByteField("unused2",0),
-                   LEShortField("Flags3",0),
-                   ByteField("TimeOut1",0xe8),
-                   ByteField("TimeOut2",0x03),
-                   LEShortField("unused3",0),
-                   LEShortField("unused4",0),
-                   LEShortField("ParamCount2",0),
-                   LEShortField("ParamOffset",0),
-                   LEShortField("DataCount",112),
-                   LEShortField("DataOffset",92),
-                   ByteField("SetupCount", 3),
-                   ByteField("unused5", 0)]
-
-# SMB MailSlot Protocol
-class SMBMailSlot(Packet):
-    name = "SMB Mail Slot Protocol"
-    fields_desc = [LEShortField("opcode", 1),
-                   LEShortField("priority", 1),
-                   LEShortField("class", 2),
-                   LEShortField("size", 135),
-                   StrNullField("name","\MAILSLOT\NET\GETDC660")]
-
-# SMB NetLogon Protocol Response Tail SAM
-class SMBNetlogon_Protocol_Response_Tail_SAM(Packet):
-    name = "SMB Netlogon Protocol Response Tail SAM"
-    fields_desc = [ByteEnumField("Command", 0x17, {0x12:"SAM logon request", 0x17:"SAM Active directory Response"}),
-                   ByteField("unused", 0),
-                   ShortField("Data1", 0),
-                   ShortField("Data2", 0xfd01),
-                   ShortField("Data3", 0),
-                   ShortField("Data4", 0xacde),
-                   ShortField("Data5", 0x0fe5),
-                   ShortField("Data6", 0xd10a),
-                   ShortField("Data7", 0x374c),
-                   ShortField("Data8", 0x83e2),
-                   ShortField("Data9", 0x7dd9),
-                   ShortField("Data10", 0x3a16),
-                   ShortField("Data11", 0x73ff),
-                   ByteField("Data12", 0x04),
-                   StrFixedLenField("Data13", "rmff", 4),
-                   ByteField("Data14", 0x0),
-                   ShortField("Data16", 0xc018),
-                   ByteField("Data18", 0x0a),
-                   StrFixedLenField("Data20", "rmff-win2k", 10),
-                   ByteField("Data21", 0xc0),
-                   ShortField("Data22", 0x18c0),
-                   ShortField("Data23", 0x180a),
-                   StrFixedLenField("Data24", "RMFF-WIN2K", 10),
-                   ShortField("Data25", 0),
-                   ByteField("Data26", 0x17),
-                   StrFixedLenField("Data27", "Default-First-Site-Name", 23),
-                   ShortField("Data28", 0x00c0),
-                   ShortField("Data29", 0x3c10),
-                   ShortField("Data30", 0x00c0),
-                   ShortField("Data31", 0x0200),
-                   ShortField("Data32", 0x0),
-                   ShortField("Data33", 0xac14),
-                   ShortField("Data34", 0x0064),
-                   ShortField("Data35", 0x0),
-                   ShortField("Data36", 0x0),
-                   ShortField("Data37", 0x0),
-                   ShortField("Data38", 0x0),
-                   ShortField("Data39", 0x0d00),
-                   ShortField("Data40", 0x0),
-                   ShortField("Data41", 0xffff)]                   
-
-# SMB NetLogon Protocol Response Tail LM2.0
-class SMBNetlogon_Protocol_Response_Tail_LM20(Packet):
-    name = "SMB Netlogon Protocol Response Tail LM20"
-    fields_desc = [ByteEnumField("Command",0x06,{0x06:"LM 2.0 Response to logon request"}),
-                   ByteField("unused", 0),
-                   StrFixedLenField("DblSlash", "\\\\", 2),
-                   StrNullField("ServerName","WIN"),
-                   LEShortField("LM20Token", 0xffff)]
-
-# SMBNegociate Protocol Request Header
-class SMBNegociate_Protocol_Request_Header(Packet):
-    name="SMBNegociate Protocol Request Header"
-    fields_desc = [StrFixedLenField("Start","\xffSMB",4),
-                   ByteEnumField("Command",0x72,{0x72:"SMB_COM_NEGOTIATE"}),
-                   ByteField("Error_Class",0),
-                   ByteField("Reserved",0),
-                   LEShortField("Error_code",0),
-                   ByteField("Flags",0x18),
-                   LEShortField("Flags2",0x0000),
-                   LEShortField("PIDHigh",0x0000),
-                   LELongField("Signature",0x0),
-                   LEShortField("Unused",0x0),
-                   LEShortField("TID",0),
-                   LEShortField("PID",1),
-                   LEShortField("UID",0),
-                   LEShortField("MID",2),
-                   ByteField("WordCount",0),
-                   LEShortField("ByteCount",12)]
-
-# SMB Negociate Protocol Request Tail
-class SMBNegociate_Protocol_Request_Tail(Packet):
-    name="SMB Negociate Protocol Request Tail"
-    fields_desc=[ByteField("BufferFormat",0x02),
-                 StrNullField("BufferData","NT LM 0.12")]
-
-# SMBNegociate Protocol Response Advanced Security
-class SMBNegociate_Protocol_Response_Advanced_Security(Packet):
-    name="SMBNegociate Protocol Response Advanced Security"
-    fields_desc = [StrFixedLenField("Start","\xffSMB",4),
-                   ByteEnumField("Command",0x72,{0x72:"SMB_COM_NEGOTIATE"}),
-                   ByteField("Error_Class",0),
-                   ByteField("Reserved",0),
-                   LEShortField("Error_Code",0),
-                   ByteField("Flags",0x98),
-                   LEShortField("Flags2",0x0000),
-                   LEShortField("PIDHigh",0x0000),
-                   LELongField("Signature",0x0),
-                   LEShortField("Unused",0x0),
-                   LEShortField("TID",0),
-                   LEShortField("PID",1),
-                   LEShortField("UID",0),
-                   LEShortField("MID",2),
-                   ByteField("WordCount",17),
-                   LEShortField("DialectIndex",7),
-                   ByteField("SecurityMode",0x03),
-                   LEShortField("MaxMpxCount",50),
-                   LEShortField("MaxNumberVC",1),
-                   LEIntField("MaxBufferSize",16144),
-                   LEIntField("MaxRawSize",65536),
-                   LEIntField("SessionKey",0x0000),
-                   LEShortField("ServerCapabilities",0xf3f9),
-                   BitField("UnixExtensions",0,1),
-                   BitField("Reserved2",0,7),
-                   BitField("ExtendedSecurity",1,1),
-                   BitField("CompBulk",0,2),
-                   BitField("Reserved3",0,5),
-# There have been 127490112000000000 tenths of micro-seconds between 1st january 1601 and 1st january 2005. 127490112000000000=0x1C4EF94D6228000, so ServerTimeHigh=0xD6228000 and ServerTimeLow=0x1C4EF94.
-                   LEIntField("ServerTimeHigh",0xD6228000L),
-                   LEIntField("ServerTimeLow",0x1C4EF94),
-                   LEShortField("ServerTimeZone",0x3c),
-                   ByteField("EncryptionKeyLength",0),
-                   LEFieldLenField("ByteCount", None, "SecurityBlob", adjust=lambda pkt,x:x-16),
-                   BitField("GUID",0,128),
-                   StrLenField("SecurityBlob", "", length_from=lambda x:x.ByteCount+16)]
-
-# SMBNegociate Protocol Response No Security
-# When using no security, with EncryptionKeyLength=8, you must have an EncryptionKey before the DomainName
-class SMBNegociate_Protocol_Response_No_Security(Packet):
-    name="SMBNegociate Protocol Response No Security"
-    fields_desc = [StrFixedLenField("Start","\xffSMB",4),
-                   ByteEnumField("Command",0x72,{0x72:"SMB_COM_NEGOTIATE"}),
-                   ByteField("Error_Class",0),
-                   ByteField("Reserved",0),
-                   LEShortField("Error_Code",0),
-                   ByteField("Flags",0x98),
-                   LEShortField("Flags2",0x0000),
-                   LEShortField("PIDHigh",0x0000),
-                   LELongField("Signature",0x0),
-                   LEShortField("Unused",0x0),
-                   LEShortField("TID",0),
-                   LEShortField("PID",1),
-                   LEShortField("UID",0),
-                   LEShortField("MID",2),
-                   ByteField("WordCount",17),
-                   LEShortField("DialectIndex",7),
-                   ByteField("SecurityMode",0x03),
-                   LEShortField("MaxMpxCount",50),
-                   LEShortField("MaxNumberVC",1),
-                   LEIntField("MaxBufferSize",16144),
-                   LEIntField("MaxRawSize",65536),
-                   LEIntField("SessionKey",0x0000),
-                   LEShortField("ServerCapabilities",0xf3f9),
-                   BitField("UnixExtensions",0,1),
-                   BitField("Reserved2",0,7),
-                   BitField("ExtendedSecurity",0,1),
-                   FlagsField("CompBulk",0,2,"CB"),
-                   BitField("Reserved3",0,5),
-                   # There have been 127490112000000000 tenths of micro-seconds between 1st january 1601 and 1st january 2005. 127490112000000000=0x1C4EF94D6228000, so ServerTimeHigh=0xD6228000 and ServerTimeLow=0x1C4EF94.
-                   LEIntField("ServerTimeHigh",0xD6228000L),
-                   LEIntField("ServerTimeLow",0x1C4EF94),
-                   LEShortField("ServerTimeZone",0x3c),
-                   ByteField("EncryptionKeyLength",8),
-                   LEShortField("ByteCount",24),
-                   BitField("EncryptionKey",0,64),
-                   StrNullField("DomainName","WORKGROUP"),
-                   StrNullField("ServerName","RMFF1")]
-    
-# SMBNegociate Protocol Response No Security No Key
-class SMBNegociate_Protocol_Response_No_Security_No_Key(Packet):
-    namez="SMBNegociate Protocol Response No Security No Key"
-    fields_desc = [StrFixedLenField("Start","\xffSMB",4),
-                   ByteEnumField("Command",0x72,{0x72:"SMB_COM_NEGOTIATE"}),
-                   ByteField("Error_Class",0),
-                   ByteField("Reserved",0),
-                   LEShortField("Error_Code",0),
-                   ByteField("Flags",0x98),
-                   LEShortField("Flags2",0x0000),
-                   LEShortField("PIDHigh",0x0000),
-                   LELongField("Signature",0x0),
-                   LEShortField("Unused",0x0),
-                   LEShortField("TID",0),
-                   LEShortField("PID",1),
-                   LEShortField("UID",0),
-                   LEShortField("MID",2),
-                   ByteField("WordCount",17),
-                   LEShortField("DialectIndex",7),
-                   ByteField("SecurityMode",0x03),
-                   LEShortField("MaxMpxCount",50),
-                   LEShortField("MaxNumberVC",1),
-                   LEIntField("MaxBufferSize",16144),
-                   LEIntField("MaxRawSize",65536),
-                   LEIntField("SessionKey",0x0000),
-                   LEShortField("ServerCapabilities",0xf3f9),
-                   BitField("UnixExtensions",0,1),
-                   BitField("Reserved2",0,7),
-                   BitField("ExtendedSecurity",0,1),
-                   FlagsField("CompBulk",0,2,"CB"),
-                   BitField("Reserved3",0,5),
-                   # There have been 127490112000000000 tenths of micro-seconds between 1st january 1601 and 1st january 2005. 127490112000000000=0x1C4EF94D6228000, so ServerTimeHigh=0xD6228000 and ServerTimeLow=0x1C4EF94.
-                   LEIntField("ServerTimeHigh",0xD6228000L),
-                   LEIntField("ServerTimeLow",0x1C4EF94),
-                   LEShortField("ServerTimeZone",0x3c),
-                   ByteField("EncryptionKeyLength",0),
-                   LEShortField("ByteCount",16),
-                   StrNullField("DomainName","WORKGROUP"),
-                   StrNullField("ServerName","RMFF1")]
-    
-# Session Setup AndX Request
-class SMBSession_Setup_AndX_Request(Packet):
-    name="Session Setup AndX Request"
-    fields_desc=[StrFixedLenField("Start","\xffSMB",4),
-                ByteEnumField("Command",0x73,{0x73:"SMB_COM_SESSION_SETUP_ANDX"}),
-                 ByteField("Error_Class",0),
-                 ByteField("Reserved",0),
-                 LEShortField("Error_Code",0),
-                 ByteField("Flags",0x18),
-                 LEShortField("Flags2",0x0001),
-                 LEShortField("PIDHigh",0x0000),
-                 LELongField("Signature",0x0),
-                 LEShortField("Unused",0x0),
-                 LEShortField("TID",0),
-                 LEShortField("PID",1),
-                 LEShortField("UID",0),
-                 LEShortField("MID",2),
-                 ByteField("WordCount",13),
-                 ByteEnumField("AndXCommand",0x75,{0x75:"SMB_COM_TREE_CONNECT_ANDX"}),
-                 ByteField("Reserved2",0),
-                 LEShortField("AndXOffset",96),
-                 LEShortField("MaxBufferS",2920),
-                 LEShortField("MaxMPXCount",50),
-                 LEShortField("VCNumber",0),
-                 LEIntField("SessionKey",0),
-                 LEFieldLenField("ANSIPasswordLength",None,"ANSIPassword"),
-                 LEShortField("UnicodePasswordLength",0),
-                 LEIntField("Reserved3",0),
-                 LEShortField("ServerCapabilities",0x05),
-                 BitField("UnixExtensions",0,1),
-                 BitField("Reserved4",0,7),
-                 BitField("ExtendedSecurity",0,1),
-                 BitField("CompBulk",0,2),
-                 BitField("Reserved5",0,5),
-                 LEShortField("ByteCount",35),
-                 StrLenField("ANSIPassword", "Pass",length_from=lambda x:x.ANSIPasswordLength),
-                 StrNullField("Account","GUEST"),
-                 StrNullField("PrimaryDomain",  ""),
-                 StrNullField("NativeOS","Windows 4.0"),
-                 StrNullField("NativeLanManager","Windows 4.0"),
-                 ByteField("WordCount2",4),
-                 ByteEnumField("AndXCommand2",0xFF,{0xFF:"SMB_COM_NONE"}),
-                 ByteField("Reserved6",0),
-                 LEShortField("AndXOffset2",0),
-                 LEShortField("Flags3",0x2),
-                 LEShortField("PasswordLength",0x1),
-                 LEShortField("ByteCount2",18),
-                 ByteField("Password",0),
-                 StrNullField("Path","\\\\WIN2K\\IPC$"),
-                 StrNullField("Service","IPC")]
-
-# Session Setup AndX Response
-class SMBSession_Setup_AndX_Response(Packet):
-    name="Session Setup AndX Response"
-    fields_desc=[StrFixedLenField("Start","\xffSMB",4),
-                 ByteEnumField("Command",0x73,{0x73:"SMB_COM_SESSION_SETUP_ANDX"}),
-                 ByteField("Error_Class",0),
-                 ByteField("Reserved",0),
-                 LEShortField("Error_Code",0),
-                 ByteField("Flags",0x90),
-                 LEShortField("Flags2",0x1001),
-                 LEShortField("PIDHigh",0x0000),
-                 LELongField("Signature",0x0),
-                 LEShortField("Unused",0x0),
-                 LEShortField("TID",0),
-                 LEShortField("PID",1),
-                 LEShortField("UID",0),
-                 LEShortField("MID",2),
-                 ByteField("WordCount",3),
-                 ByteEnumField("AndXCommand",0x75,{0x75:"SMB_COM_TREE_CONNECT_ANDX"}),
-                 ByteField("Reserved2",0),
-                 LEShortField("AndXOffset",66),
-                 LEShortField("Action",0),
-                 LEShortField("ByteCount",25),
-                 StrNullField("NativeOS","Windows 4.0"),
-                 StrNullField("NativeLanManager","Windows 4.0"),
-                 StrNullField("PrimaryDomain",""),
-                 ByteField("WordCount2",3),
-                 ByteEnumField("AndXCommand2",0xFF,{0xFF:"SMB_COM_NONE"}),
-                 ByteField("Reserved3",0),
-                 LEShortField("AndXOffset2",80),
-                 LEShortField("OptionalSupport",0x01),
-                 LEShortField("ByteCount2",5),
-                 StrNullField("Service","IPC"),
-                 StrNullField("NativeFileSystem","")]
-
-class MobileIP(Packet):
-    name = "Mobile IP (RFC3344)"
-    fields_desc = [ ByteEnumField("type", 1, {1:"RRQ", 3:"RRP"}) ]
-
-class MobileIPRRQ(Packet):
-    name = "Mobile IP Registration Request (RFC3344)"
-    fields_desc = [ XByteField("flags", 0),
-                    ShortField("lifetime", 180),
-                    IPField("homeaddr", "0.0.0.0"),
-                    IPField("haaddr", "0.0.0.0"),
-                    IPField("coaddr", "0.0.0.0"),
-                    Field("id", "", "64s") ]
-
-class MobileIPRRP(Packet):
-    name = "Mobile IP Registration Reply (RFC3344)"
-    fields_desc = [ ByteField("code", 0),
-                    ShortField("lifetime", 180),
-                    IPField("homeaddr", "0.0.0.0"),
-                    IPField("haaddr", "0.0.0.0"),
-                    Field("id", "", "64s") ]
-
-class MobileIPTunnelData(Packet):
-    name = "Mobile IP Tunnel Data Message (RFC3519)"
-    fields_desc = [ ByteField("nexthdr", 4),
-                    ShortField("res", 0) ]
-
-
-# Cisco Netflow Protocol version 1
-class NetflowHeader(Packet):
-    name = "Netflow Header"
-    fields_desc = [ ShortField("version", 1) ]
-    
-class NetflowHeaderV1(Packet):
-    name = "Netflow Header V1"
-    fields_desc = [ ShortField("count", 0),
-                    IntField("sysUptime", 0),
-                    IntField("unixSecs", 0),
-                    IntField("unixNanoSeconds", 0) ]
-
-
-class NetflowRecordV1(Packet):
-    name = "Netflow Record"
-    fields_desc = [ IPField("ipsrc", "0.0.0.0"),
-                    IPField("ipdst", "0.0.0.0"),
-                    IPField("nexthop", "0.0.0.0"),
-                    ShortField("inputIfIndex", 0),
-                    ShortField("outpuIfIndex", 0),
-                    IntField("dpkts", 0),
-                    IntField("dbytes", 0),
-                    IntField("starttime", 0),
-                    IntField("endtime", 0),
-                    ShortField("srcport", 0),
-                    ShortField("dstport", 0),
-                    ShortField("padding", 0),
-                    ByteField("proto", 0),
-                    ByteField("tos", 0),
-                    IntField("padding1", 0),
-                    IntField("padding2", 0) ]
-
-
-TFTP_operations = { 1:"RRQ",2:"WRQ",3:"DATA",4:"ACK",5:"ERROR",6:"OACK" }
-
-
-class TFTP(Packet):
-    name = "TFTP opcode"
-    fields_desc = [ ShortEnumField("op", 1, TFTP_operations), ]
-    
-
-
-class TFTP_RRQ(Packet):
-    name = "TFTP Read Request"
-    fields_desc = [ StrNullField("filename", ""),
-                    StrNullField("mode", "octet") ]
-    def answers(self, other):
-        return 0
-    def mysummary(self):
-        return self.sprintf("RRQ %filename%"),[UDP]
-        
-
-class TFTP_WRQ(Packet):
-    name = "TFTP Write Request"
-    fields_desc = [ StrNullField("filename", ""),
-                    StrNullField("mode", "octet") ]
-    def answers(self, other):
-        return 0
-    def mysummary(self):
-        return self.sprintf("WRQ %filename%"),[UDP]
-
-class TFTP_DATA(Packet):
-    name = "TFTP Data"
-    fields_desc = [ ShortField("block", 0) ]
-    def answers(self, other):
-        return  self.block == 1 and isinstance(other, TFTP_RRQ)
-    def mysummary(self):
-        return self.sprintf("DATA %block%"),[UDP]
-
-class TFTP_Option(Packet):
-    fields_desc = [ StrNullField("oname",""),
-                    StrNullField("value","") ]
-    def extract_padding(self, pkt):
-        return "",pkt
-
-class TFTP_Options(Packet):
-    fields_desc = [ PacketListField("options", [], TFTP_Option, length_from=lambda x:None) ]
-
-    
-class TFTP_ACK(Packet):
-    name = "TFTP Ack"
-    fields_desc = [ ShortField("block", 0) ]
-    def answers(self, other):
-        if isinstance(other, TFTP_DATA):
-            return self.block == other.block
-        elif isinstance(other, TFTP_RRQ) or isinstance(other, TFTP_WRQ) or isinstance(other, TFTP_OACK):
-            return self.block == 0
-        return 0
-    def mysummary(self):
-        return self.sprintf("ACK %block%"),[UDP]
-
-TFTP_Error_Codes = {  0: "Not defined",
-                      1: "File not found",
-                      2: "Access violation",
-                      3: "Disk full or allocation exceeded",
-                      4: "Illegal TFTP operation",
-                      5: "Unknown transfer ID",
-                      6: "File already exists",
-                      7: "No such user",
-                      8: "Terminate transfer due to option negotiation",
-                      }
-    
-class TFTP_ERROR(Packet):
-    name = "TFTP Error"
-    fields_desc = [ ShortEnumField("errorcode", 0, TFTP_Error_Codes),
-                    StrNullField("errormsg", "")]
-    def answers(self, other):
-        return (isinstance(other, TFTP_DATA) or
-                isinstance(other, TFTP_RRQ) or
-                isinstance(other, TFTP_WRQ) or 
-                isinstance(other, TFTP_ACK))
-    def mysummary(self):
-        return self.sprintf("ERROR %errorcode%: %errormsg%"),[UDP]
-
-
-class TFTP_OACK(Packet):
-    name = "TFTP Option Ack"
-    fields_desc = [  ]
-    def answers(self, other):
-        return isinstance(other, TFTP_WRQ) or isinstance(other, TFTP_RRQ)
-
-
-##########
-## SNMP ##
-##########
-
-######[ ASN1 class ]######
-
-class ASN1_Class_SNMP(ASN1_Class_UNIVERSAL):
-    name="SNMP"
-    PDU_GET = 0xa0
-    PDU_NEXT = 0xa1
-    PDU_RESPONSE = 0xa2
-    PDU_SET = 0xa3
-    PDU_TRAPv1 = 0xa4
-    PDU_BULK = 0xa5
-    PDU_INFORM = 0xa6
-    PDU_TRAPv2 = 0xa7
-
-
-class ASN1_SNMP_PDU_GET(ASN1_SEQUENCE):
-    tag = ASN1_Class_SNMP.PDU_GET
-
-class ASN1_SNMP_PDU_NEXT(ASN1_SEQUENCE):
-    tag = ASN1_Class_SNMP.PDU_NEXT
-
-class ASN1_SNMP_PDU_RESPONSE(ASN1_SEQUENCE):
-    tag = ASN1_Class_SNMP.PDU_RESPONSE
-
-class ASN1_SNMP_PDU_SET(ASN1_SEQUENCE):
-    tag = ASN1_Class_SNMP.PDU_SET
-
-class ASN1_SNMP_PDU_TRAPv1(ASN1_SEQUENCE):
-    tag = ASN1_Class_SNMP.PDU_TRAPv1
-
-class ASN1_SNMP_PDU_BULK(ASN1_SEQUENCE):
-    tag = ASN1_Class_SNMP.PDU_BULK
-
-class ASN1_SNMP_PDU_INFORM(ASN1_SEQUENCE):
-    tag = ASN1_Class_SNMP.PDU_INFORM
-
-class ASN1_SNMP_PDU_TRAPv2(ASN1_SEQUENCE):
-    tag = ASN1_Class_SNMP.PDU_TRAPv2
-
-
-######[ BER codecs ]#######
-
-class BERcodec_SNMP_PDU_GET(BERcodec_SEQUENCE):
-    tag = ASN1_Class_SNMP.PDU_GET
-
-class BERcodec_SNMP_PDU_NEXT(BERcodec_SEQUENCE):
-    tag = ASN1_Class_SNMP.PDU_NEXT
-
-class BERcodec_SNMP_PDU_RESPONSE(BERcodec_SEQUENCE):
-    tag = ASN1_Class_SNMP.PDU_RESPONSE
-
-class BERcodec_SNMP_PDU_SET(BERcodec_SEQUENCE):
-    tag = ASN1_Class_SNMP.PDU_SET
-
-class BERcodec_SNMP_PDU_TRAPv1(BERcodec_SEQUENCE):
-    tag = ASN1_Class_SNMP.PDU_TRAPv1
-
-class BERcodec_SNMP_PDU_BULK(BERcodec_SEQUENCE):
-    tag = ASN1_Class_SNMP.PDU_BULK
-
-class BERcodec_SNMP_PDU_INFORM(BERcodec_SEQUENCE):
-    tag = ASN1_Class_SNMP.PDU_INFORM
-
-class BERcodec_SNMP_PDU_TRAPv2(BERcodec_SEQUENCE):
-    tag = ASN1_Class_SNMP.PDU_TRAPv2
-
-
-
-######[ ASN1 fields ]######
-
-class ASN1F_SNMP_PDU_GET(ASN1F_SEQUENCE):
-    ASN1_tag = ASN1_Class_SNMP.PDU_GET
-
-class ASN1F_SNMP_PDU_NEXT(ASN1F_SEQUENCE):
-    ASN1_tag = ASN1_Class_SNMP.PDU_NEXT
-
-class ASN1F_SNMP_PDU_RESPONSE(ASN1F_SEQUENCE):
-    ASN1_tag = ASN1_Class_SNMP.PDU_RESPONSE
-
-class ASN1F_SNMP_PDU_SET(ASN1F_SEQUENCE):
-    ASN1_tag = ASN1_Class_SNMP.PDU_SET
-
-class ASN1F_SNMP_PDU_TRAPv1(ASN1F_SEQUENCE):
-    ASN1_tag = ASN1_Class_SNMP.PDU_TRAPv1
-
-class ASN1F_SNMP_PDU_BULK(ASN1F_SEQUENCE):
-    ASN1_tag = ASN1_Class_SNMP.PDU_BULK
-
-class ASN1F_SNMP_PDU_INFORM(ASN1F_SEQUENCE):
-    ASN1_tag = ASN1_Class_SNMP.PDU_INFORM
-
-class ASN1F_SNMP_PDU_TRAPv2(ASN1F_SEQUENCE):
-    ASN1_tag = ASN1_Class_SNMP.PDU_TRAPv2
-
-
-
-######[ SNMP Packet ]######
-
-SNMP_error = { 0: "no_error",
-               1: "too_big",
-               2: "no_such_name",
-               3: "bad_value",
-               4: "read_only",
-               5: "generic_error",
-               6: "no_access",
-               7: "wrong_type",
-               8: "wrong_length",
-               9: "wrong_encoding",
-              10: "wrong_value",
-              11: "no_creation",
-              12: "inconsistent_value",
-              13: "ressource_unavailable",
-              14: "commit_failed",
-              15: "undo_failed",
-              16: "authorization_error",
-              17: "not_writable",
-              18: "inconsistent_name",
-               }
-
-SNMP_trap_types = { 0: "cold_start",
-                    1: "warm_start",
-                    2: "link_down",
-                    3: "link_up",
-                    4: "auth_failure",
-                    5: "egp_neigh_loss",
-                    6: "enterprise_specific",
-                    }
-
-class SNMPvarbind(ASN1_Packet):
-    ASN1_codec = ASN1_Codecs.BER
-    ASN1_root = ASN1F_SEQUENCE( ASN1F_OID("oid","1.3"),
-                                ASN1F_field("value",ASN1_NULL(0))
-                                )
-
-
-class SNMPget(ASN1_Packet):
-    ASN1_codec = ASN1_Codecs.BER
-    ASN1_root = ASN1F_SNMP_PDU_GET( ASN1F_INTEGER("id",0),
-                                    ASN1F_enum_INTEGER("error",0, SNMP_error),
-                                    ASN1F_INTEGER("error_index",0),
-                                    ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind)
-                                    )
-
-class SNMPnext(ASN1_Packet):
-    ASN1_codec = ASN1_Codecs.BER
-    ASN1_root = ASN1F_SNMP_PDU_NEXT( ASN1F_INTEGER("id",0),
-                                     ASN1F_enum_INTEGER("error",0, SNMP_error),
-                                     ASN1F_INTEGER("error_index",0),
-                                     ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind)
-                                     )
-
-class SNMPresponse(ASN1_Packet):
-    ASN1_codec = ASN1_Codecs.BER
-    ASN1_root = ASN1F_SNMP_PDU_RESPONSE( ASN1F_INTEGER("id",0),
-                                         ASN1F_enum_INTEGER("error",0, SNMP_error),
-                                         ASN1F_INTEGER("error_index",0),
-                                         ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind)
-                                         )
-
-class SNMPset(ASN1_Packet):
-    ASN1_codec = ASN1_Codecs.BER
-    ASN1_root = ASN1F_SNMP_PDU_SET( ASN1F_INTEGER("id",0),
-                                    ASN1F_enum_INTEGER("error",0, SNMP_error),
-                                    ASN1F_INTEGER("error_index",0),
-                                    ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind)
-                                    )
-    
-class SNMPtrapv1(ASN1_Packet):
-    ASN1_codec = ASN1_Codecs.BER
-    ASN1_root = ASN1F_SNMP_PDU_TRAPv1( ASN1F_INTEGER("id",0),
-                                       ASN1F_OID("enterprise", "1.3"),
-                                       ASN1F_STRING("agent_addr",""),
-                                       ASN1F_enum_INTEGER("generic_trap", 0, SNMP_trap_types),
-                                       ASN1F_INTEGER("specific_trap", 0),
-                                       ASN1F_INTEGER("time_stamp", IntAutoTime()),
-                                       ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind)
-                                       )
-
-class SNMPbulk(ASN1_Packet):
-    ASN1_codec = ASN1_Codecs.BER
-    ASN1_root = ASN1F_SNMP_PDU_BULK( ASN1F_INTEGER("id",0),
-                                     ASN1F_INTEGER("non_repeaters",0),
-                                     ASN1F_INTEGER("max_repetitions",0),
-                                     ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind)
-                                     )
-    
-class SNMPinform(ASN1_Packet):
-    ASN1_codec = ASN1_Codecs.BER
-    ASN1_root = ASN1F_SNMP_PDU_INFORM( ASN1F_INTEGER("id",0),
-                                       ASN1F_enum_INTEGER("error",0, SNMP_error),
-                                       ASN1F_INTEGER("error_index",0),
-                                       ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind)
-                                       )
-    
-class SNMPtrapv2(ASN1_Packet):
-    ASN1_codec = ASN1_Codecs.BER
-    ASN1_root = ASN1F_SNMP_PDU_TRAPv2( ASN1F_INTEGER("id",0),
-                                       ASN1F_enum_INTEGER("error",0, SNMP_error),
-                                       ASN1F_INTEGER("error_index",0),
-                                       ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind)
-                                       )
-    
-
-class SNMP(ASN1_Packet):
-    ASN1_codec = ASN1_Codecs.BER
-    ASN1_root = ASN1F_SEQUENCE(
-        ASN1F_enum_INTEGER("version", 1, {0:"v1", 1:"v2c", 2:"v2", 3:"v3"}),
-        ASN1F_STRING("community","public"),
-        ASN1F_CHOICE("PDU", SNMPget(),
-                     SNMPget, SNMPnext, SNMPresponse, SNMPset,
-                     SNMPtrapv1, SNMPbulk, SNMPinform, SNMPtrapv2)
-        )
-    def answers(self, other):
-        return ( isinstance(self.PDU, SNMPresponse)    and
-                 ( isinstance(other.PDU, SNMPget) or
-                   isinstance(other.PDU, SNMPnext) or
-                   isinstance(other.PDU, SNMPset)    ) and
-                 self.PDU.id == other.PDU.id )
-
-
-##########
-## X509 ##
-##########
-
-######[ ASN1 class ]######
-
-class ASN1_Class_X509(ASN1_Class_UNIVERSAL):
-    name="X509"
-    CONT0 = 0xa0
-    CONT1 = 0xa1
-    CONT2 = 0xa2
-    CONT3 = 0xa3
-
-class ASN1_X509_CONT0(ASN1_SEQUENCE):
-    tag = ASN1_Class_X509.CONT0
-
-class ASN1_X509_CONT1(ASN1_SEQUENCE):
-    tag = ASN1_Class_X509.CONT1
-
-class ASN1_X509_CONT2(ASN1_SEQUENCE):
-    tag = ASN1_Class_X509.CONT2
-
-class ASN1_X509_CONT3(ASN1_SEQUENCE):
-    tag = ASN1_Class_X509.CONT3
-
-######[ BER codecs ]#######
-
-class BERcodec_X509_CONT0(BERcodec_SEQUENCE):
-    tag = ASN1_Class_X509.CONT0
-
-class BERcodec_X509_CONT1(BERcodec_SEQUENCE):
-    tag = ASN1_Class_X509.CONT1
-    
-class BERcodec_X509_CONT2(BERcodec_SEQUENCE):
-    tag = ASN1_Class_X509.CONT2
-    
-class BERcodec_X509_CONT3(BERcodec_SEQUENCE):
-    tag = ASN1_Class_X509.CONT3
-
-######[ ASN1 fields ]######
-
-class ASN1F_X509_CONT0(ASN1F_SEQUENCE):
-    ASN1_tag = ASN1_Class_X509.CONT0
-    
-class ASN1F_X509_CONT1(ASN1F_SEQUENCE):
-    ASN1_tag = ASN1_Class_X509.CONT1
-    
-class ASN1F_X509_CONT2(ASN1F_SEQUENCE):
-    ASN1_tag = ASN1_Class_X509.CONT2
-    
-class ASN1F_X509_CONT3(ASN1F_SEQUENCE):
-    ASN1_tag = ASN1_Class_X509.CONT3
-
-######[ X509 packets ]######
-
-class X509RDN(ASN1_Packet):
-    ASN1_codec = ASN1_Codecs.BER
-    ASN1_root = ASN1F_SET(
-                  ASN1F_SEQUENCE( ASN1F_OID("oid","2.5.4.6"),
-                                  ASN1F_PRINTABLE_STRING("value","")
-                                  )
-                  )
-
-class X509v3Ext(ASN1_Packet):
-    ASN1_codec = ASN1_Codecs.BER
-    ASN1_root = ASN1F_field("val",ASN1_NULL(0))
-    
-
-class X509Cert(ASN1_Packet):
-    ASN1_codec = ASN1_Codecs.BER
-    ASN1_root = ASN1F_SEQUENCE(
-        ASN1F_SEQUENCE(
-            ASN1F_optionnal(ASN1F_X509_CONT0(ASN1F_INTEGER("version",3))),
-            ASN1F_INTEGER("sn",1),
-            ASN1F_SEQUENCE(ASN1F_OID("sign_algo","1.2.840.113549.1.1.5"),
-                           ASN1F_field("sa_value",ASN1_NULL(0))),
-            ASN1F_SEQUENCE_OF("issuer",[],X509RDN),
-            ASN1F_SEQUENCE(ASN1F_UTC_TIME("not_before",ZuluTime(-600)),  # ten minutes ago
-                           ASN1F_UTC_TIME("not_after",ZuluTime(+86400))), # for 24h
-            ASN1F_SEQUENCE_OF("subject",[],X509RDN),
-            ASN1F_SEQUENCE(
-                ASN1F_SEQUENCE(ASN1F_OID("pubkey_algo","1.2.840.113549.1.1.1"),
-                               ASN1F_field("pk_value",ASN1_NULL(0))),
-                ASN1F_BIT_STRING("pubkey","")
-                ),
-            ASN1F_optionnal(ASN1F_X509_CONT3(ASN1F_SEQUENCE_OF("x509v3ext",[],X509v3Ext))),
-            
-        ),
-        ASN1F_SEQUENCE(ASN1F_OID("sign_algo2","1.2.840.113549.1.1.5"),
-                       ASN1F_field("sa2_value",ASN1_NULL(0))),
-        ASN1F_BIT_STRING("signature","")
-        )
-
-
-
-
-#################
-## Bind layers ##
-#################
-
-
-def bind_bottom_up(lower, upper, __fval=None, **fval):
-    if __fval is not None:
-        fval.update(__fval)
-    lower.payload_guess = lower.payload_guess[:]
-    lower.payload_guess.append((fval, upper))
-    
-
-def bind_top_down(lower, upper, __fval=None, **fval):
-    if __fval is not None:
-        fval.update(__fval)
-    upper.overload_fields = upper.overload_fields.copy()
-    upper.overload_fields[lower] = fval
-    
-def bind_layers(lower, upper, __fval=None, **fval):
-    if __fval is not None:
-        fval.update(__fval)
-    bind_top_down(lower, upper, **fval)
-    bind_bottom_up(lower, upper, **fval)
-
-def split_bottom_up(lower, upper, __fval=None, **fval):
-    if __fval is not None:
-        fval.update(__fval)
-    def do_filter((f,u),upper=upper,fval=fval):
-        if u != upper:
-            return True
-        for k in fval:
-            if k not in f or f[k] != fval[k]:
-                return True
-        return False
-    lower.payload_guess = filter(do_filter, lower.payload_guess)
-        
-def split_top_down(lower, upper, __fval=None, **fval):
-    if __fval is not None:
-        fval.update(__fval)
-    if lower in upper.overload_fields:
-        ofval = upper.overload_fields[lower]
-        for k in fval:
-            if k not in ofval or ofval[k] != fval[k]:
-                return
-        upper.overload_fields = upper.overload_fields.copy()
-        del(upper.overload_fields[lower])
-
-def split_layers(lower, upper, __fval=None, **fval):
-    if __fval is not None:
-        fval.update(__fval)
-    split_bottom_up(lower, upper, **fval)
-    split_top_down(lower, upper, **fval)
-
-
-bind_layers( Dot3,          LLC,           )
-bind_layers( GPRS,          IP,            )
-bind_layers( PrismHeader,   Dot11,         )
-bind_layers( RadioTap,      Dot11,         )
-bind_layers( Dot11,         LLC,           type=2)
-bind_layers( Dot11QoS,      LLC,           )
-bind_layers( L2TP,          PPP,           )
-bind_layers( HDLC,          PPP,           )
-bind_layers( PPP,           IP,            proto=33)
-bind_layers( PPP,           PPP_IPCP,      proto=0x8021)
-bind_layers( PPP,           PPP_ECP,       proto=0x8053)
-bind_layers( Ether,         LLC,           type=122)
-bind_layers( Ether,         Dot1Q,         type=33024)
-bind_layers( Ether,         Ether,         type=1)
-bind_layers( Ether,         ARP,           type=2054)
-bind_layers( Ether,         IP,            type=2048)
-bind_layers( Ether,         EAPOL,         type=34958)
-bind_layers( Ether,         EAPOL,         dst='01:80:c2:00:00:03', type=34958)
-bind_layers( Ether,         PPPoED,        type=34915)
-bind_layers( Ether,         PPPoE,         type=34916)
-bind_layers( CookedLinux,   LLC,           proto=122)
-bind_layers( CookedLinux,   Dot1Q,         proto=33024)
-bind_layers( CookedLinux,   Ether,         proto=1)
-bind_layers( CookedLinux,   ARP,           proto=2054)
-bind_layers( CookedLinux,   IP,            proto=2048)
-bind_layers( CookedLinux,   EAPOL,         proto=34958)
-bind_layers( CookedLinux,   PPPoED,        proto=34915)
-bind_layers( CookedLinux,   PPPoE,         proto=34916)
-bind_layers( GRE,           LLC,           proto=122)
-bind_layers( GRE,           Dot1Q,         proto=33024)
-bind_layers( GRE,           Ether,         proto=1)
-bind_layers( GRE,           ARP,           proto=2054)
-bind_layers( GRE,           IP,            proto=2048)
-bind_layers( GRE,           EAPOL,         proto=34958)
-bind_layers( PPPoE,         PPP,           code=0)
-bind_layers( EAPOL,         EAP,           type=0)
-bind_layers( LLC,           STP,           dsap=66, ssap=66, ctrl=3)
-bind_layers( LLC,           SNAP,          dsap=170, ssap=170, ctrl=3)
-bind_layers( SNAP,          Dot1Q,         code=33024)
-bind_layers( SNAP,          Ether,         code=1)
-bind_layers( SNAP,          ARP,           code=2054)
-bind_layers( SNAP,          IP,            code=2048)
-bind_layers( SNAP,          EAPOL,         code=34958)
-bind_layers( SNAP,          STP,           code=267)
-bind_layers( IPerror,       IPerror,       frag=0, proto=4)
-bind_layers( IPerror,       ICMPerror,     frag=0, proto=1)
-bind_layers( IPerror,       TCPerror,      frag=0, proto=6)
-bind_layers( IPerror,       UDPerror,      frag=0, proto=17)
-bind_layers( IP,            IP,            frag=0, proto=4)
-bind_layers( IP,            ICMP,          frag=0, proto=1)
-bind_layers( IP,            TCP,           frag=0, proto=6)
-bind_layers( IP,            UDP,           frag=0, proto=17)
-bind_layers( IP,            GRE,           frag=0, proto=47)
-bind_layers( UDP,           L2TP,          sport=1701, dport=1701)
-bind_layers( UDP,           SNMP,          sport=161)
-bind_layers( UDP,           SNMP,          dport=161)
-bind_layers( UDP,           MGCP,          dport=2727)
-bind_layers( UDP,           MGCP,          sport=2727)
-bind_layers( UDP,           DNS,           dport=53)
-bind_layers( UDP,           DNS,           sport=53)
-bind_layers( UDP,           ISAKMP,        dport=500, sport=500)
-bind_layers( UDP,           HSRP,          dport=1985, sport=1985)
-bind_layers( UDP,           NTP,           dport=123, sport=123)
-bind_layers( UDP,           BOOTP,         dport=67, sport=68)
-bind_layers( UDP,           BOOTP,         dport=68, sport=67)
-bind_layers( BOOTP,         DHCP,          options='c\x82Sc')
-bind_layers( UDP,           RIP,           sport=520)
-bind_layers( UDP,           RIP,           dport=520)
-bind_layers( RIP,           RIPEntry,      )
-bind_layers( RIPEntry,      RIPEntry,      )
-bind_layers( Dot11,         Dot11AssoReq,    subtype=0, type=0)
-bind_layers( Dot11,         Dot11AssoResp,   subtype=1, type=0)
-bind_layers( Dot11,         Dot11ReassoReq,  subtype=2, type=0)
-bind_layers( Dot11,         Dot11ReassoResp, subtype=3, type=0)
-bind_layers( Dot11,         Dot11ProbeReq,   subtype=4, type=0)
-bind_layers( Dot11,         Dot11ProbeResp,  subtype=5, type=0)
-bind_layers( Dot11,         Dot11Beacon,     subtype=8, type=0)
-bind_layers( Dot11,         Dot11ATIM,       subtype=9, type=0)
-bind_layers( Dot11,         Dot11Disas,      subtype=10, type=0)
-bind_layers( Dot11,         Dot11Auth,       subtype=11, type=0)
-bind_layers( Dot11,         Dot11Deauth,     subtype=12, type=0)
-bind_layers( Dot11Beacon,     Dot11Elt,    )
-bind_layers( Dot11AssoReq,    Dot11Elt,    )
-bind_layers( Dot11AssoResp,   Dot11Elt,    )
-bind_layers( Dot11ReassoReq,  Dot11Elt,    )
-bind_layers( Dot11ReassoResp, Dot11Elt,    )
-bind_layers( Dot11ProbeReq,   Dot11Elt,    )
-bind_layers( Dot11ProbeResp,  Dot11Elt,    )
-bind_layers( Dot11Auth,       Dot11Elt,    )
-bind_layers( Dot11Elt,        Dot11Elt,    )
-bind_layers( TCP,           Skinny,        dport=2000)
-bind_layers( TCP,           Skinny,        sport=2000)
-bind_layers( UDP,           SebekHead,     sport=1101)
-bind_layers( UDP,           SebekHead,     dport=1101)
-bind_layers( UDP,           SebekHead,     dport=1101, sport=1101)
-bind_layers( SebekHead,     SebekV1,       version=1)
-bind_layers( SebekHead,     SebekV2Sock,   version=2, type=2)
-bind_layers( SebekHead,     SebekV2,       version=2)
-bind_layers( SebekHead,     SebekV3Sock,   version=3, type=2)
-bind_layers( SebekHead,     SebekV3,       version=3)
-bind_layers( CookedLinux,   IrLAPHead,     proto=23)
-bind_layers( IrLAPHead,     IrLAPCommand,  Type=1)
-bind_layers( IrLAPCommand,  IrLMP,         )
-bind_layers( UDP,           NBNSQueryRequest,  dport=137)
-bind_layers( UDP,           NBNSRequest,       dport=137)
-bind_layers( UDP,           NBNSQueryResponse, sport=137)
-bind_layers( UDP,           NBNSQueryResponseNegative, sport=137)
-bind_layers( UDP,           NBNSNodeStatusResponse,    sport=137)
-bind_layers( NBNSNodeStatusResponse,        NBNSNodeStatusResponseService, )
-bind_layers( NBNSNodeStatusResponse,        NBNSNodeStatusResponseService, )
-bind_layers( NBNSNodeStatusResponseService, NBNSNodeStatusResponseService, )
-bind_layers( NBNSNodeStatusResponseService, NBNSNodeStatusResponseEnd, )
-bind_layers( UDP,           NBNSWackResponse, sport=137)
-bind_layers( UDP,           NBTDatagram,      dport=138)
-bind_layers( TCP,           NBTSession,       dport=139)
-bind_layers( NBTSession,                           SMBNegociate_Protocol_Request_Header, )
-bind_layers( SMBNegociate_Protocol_Request_Header, SMBNegociate_Protocol_Request_Tail, )
-bind_layers( SMBNegociate_Protocol_Request_Tail,   SMBNegociate_Protocol_Request_Tail, )
-bind_layers( NBTSession,    SMBNegociate_Protocol_Response_Advanced_Security,  ExtendedSecurity=1)
-bind_layers( NBTSession,    SMBNegociate_Protocol_Response_No_Security,        ExtendedSecurity=0, EncryptionKeyLength=8)
-bind_layers( NBTSession,    SMBNegociate_Protocol_Response_No_Security_No_Key, ExtendedSecurity=0, EncryptionKeyLength=0)
-bind_layers( NBTSession,    SMBSession_Setup_AndX_Request, )
-bind_layers( NBTSession,    SMBSession_Setup_AndX_Response, )
-bind_layers( HCI_Hdr,       HCI_ACL_Hdr,   type=2)
-bind_layers( HCI_Hdr,       Raw,           )
-bind_layers( HCI_ACL_Hdr,   L2CAP_Hdr,     )
-bind_layers( L2CAP_Hdr,     L2CAP_CmdHdr,      cid=1)
-bind_layers( L2CAP_CmdHdr,  L2CAP_CmdRej,      code=1)
-bind_layers( L2CAP_CmdHdr,  L2CAP_ConnReq,     code=2)
-bind_layers( L2CAP_CmdHdr,  L2CAP_ConnResp,    code=3)
-bind_layers( L2CAP_CmdHdr,  L2CAP_ConfReq,     code=4)
-bind_layers( L2CAP_CmdHdr,  L2CAP_ConfResp,    code=5)
-bind_layers( L2CAP_CmdHdr,  L2CAP_DisconnReq,  code=6)
-bind_layers( L2CAP_CmdHdr,  L2CAP_DisconnResp, code=7)
-bind_layers( L2CAP_CmdHdr,  L2CAP_InfoReq,     code=10)
-bind_layers( L2CAP_CmdHdr,  L2CAP_InfoResp,    code=11)
-bind_layers( UDP,           MobileIP,           sport=434)
-bind_layers( UDP,           MobileIP,           dport=434)
-bind_layers( MobileIP,      MobileIPRRQ,        type=1)
-bind_layers( MobileIP,      MobileIPRRP,        type=3)
-bind_layers( MobileIP,      MobileIPTunnelData, type=4)
-bind_layers( MobileIPTunnelData, IP,           nexthdr=4)
-bind_layers( NetflowHeader,   NetflowHeaderV1, version=1)
-bind_layers( NetflowHeaderV1, NetflowRecordV1, )
-
-bind_layers(UDP, TFTP, dport=69)
-bind_layers(TFTP, TFTP_RRQ, op=1)
-bind_layers(TFTP, TFTP_WRQ, op=2)
-bind_layers(TFTP, TFTP_DATA, op=3)
-bind_layers(TFTP, TFTP_ACK, op=4)
-bind_layers(TFTP, TFTP_ERROR, op=5)
-bind_layers(TFTP, TFTP_OACK, op=6)
-bind_layers(TFTP_RRQ, TFTP_Options)
-bind_layers(TFTP_WRQ, TFTP_Options)
-bind_layers(TFTP_OACK, TFTP_Options)
-
-
-###################
-## Fragmentation ##
-###################
-
-def fragment(pkt, fragsize=1480):
-    fragsize = (fragsize+7)/8*8
-    lst = []
-    for p in pkt:
-        s = str(p[IP].payload)
-        nb = (len(s)+fragsize-1)/fragsize
-        for i in range(nb):            
-            q = p.copy()
-            del(q[IP].payload)
-            del(q[IP].chksum)
-            del(q[IP].len)
-            if i == nb-1:
-                q[IP].flags &= ~1
-            else:
-                q[IP].flags |= 1 
-            q[IP].frag = i*fragsize/8
-            r = Raw(load=s[i*fragsize:(i+1)*fragsize])
-            r.overload_fields = p[IP].payload.overload_fields.copy()
-            q.add_payload(r)
-            lst.append(q)
-    return lst
-
-def overlap_frag(p, overlap, fragsize=8, overlap_fragsize=None):
-    if overlap_fragsize is None:
-        overlap_fragsize = fragsize
-    q = p.copy()
-    del(q[IP].payload)
-    q[IP].add_payload(overlap)
-
-    qfrag = fragment(q, overlap_fragsize)
-    qfrag[-1][IP].flags |= 1
-    return qfrag+fragment(p, fragsize)
-
-def defrag(plist):
-    """defrag(plist) -> ([not fragmented], [defragmented],
-                  [ [bad fragments], [bad fragments], ... ])"""
-    frags = {}
-    nofrag = PacketList()
-    for p in plist:
-        ip = p[IP]
-        if IP not in p:
-            nofrag.append(p)
-            continue
-        if ip.frag == 0 and ip.flags & 1 == 0:
-            nofrag.append(p)
-            continue
-        uniq = (ip.id,ip.src,ip.dst,ip.proto)
-        if uniq in frags:
-            frags[uniq].append(p)
-        else:
-            frags[uniq] = PacketList([p])
-    defrag = []
-    missfrag = []
-    for lst in frags.itervalues():
-        lst.sort(lambda x,y:cmp(x.frag, y.frag))
-        p = lst[0]
-        if p.frag > 0:
-            missfrag.append(lst)
-            continue
-        p = p.copy()
-        if Padding in p:
-            del(p[Padding].underlayer.payload)
-        ip = p[IP]
-        if ip.len is None or ip.ihl is None:
-            clen = len(ip.payload)
-        else:
-            clen = ip.len - (ip.ihl<<2)
-        txt = Raw()
-        for q in lst[1:]:
-            if clen != q.frag<<3:
-                if clen > q.frag<<3:
-                    warning("Fragment overlap (%i > %i) %r || %r ||  %r" % (clen, q.frag<<3, p,txt,q))
-                missfrag.append(lst)
-                txt = None
-                break
-            if q[IP].len is None or q[IP].ihl is None:
-                clen += len(q[IP].payload)
-            else:
-                clen += q[IP].len - (q[IP].ihl<<2)
-            if Padding in q:
-                del(q[Padding].underlayer.payload)
-            txt.add_payload(q[IP].payload.copy())
-            
-        if txt is None:
-            continue
-
-        ip.flags &= ~1 # !MF
-        del(ip.chksum)
-        del(ip.len)
-        p = p/txt
-        defrag.append(p)
-    defrag2=PacketList()
-    for p in defrag:
-        defrag2.append(p.__class__(str(p)))
-    return nofrag,defrag2,missfrag
-            
-def defragment(plist):
-    """defrag(plist) -> plist defragmented as much as possible """
-    frags = {}
-    final = []
-
-    pos = 0
-    for p in plist:
-        p._defrag_pos = pos
-        pos += 1
-        if IP in p:
-            ip = p[IP]
-            if ip.frag != 0 or ip.flags & 1:
-                ip = p[IP]
-                uniq = (ip.id,ip.src,ip.dst,ip.proto)
-                if uniq in frags:
-                    frags[uniq].append(p)
-                else:
-                    frags[uniq] = [p]
-                continue
-        final.append(p)
-
-    defrag = []
-    missfrag = []
-    for lst in frags.itervalues():
-        lst.sort(lambda x,y:cmp(x.frag, y.frag))
-        p = lst[0]
-        if p.frag > 0:
-            missfrag += lst
-            continue
-        p = p.copy()
-        if Padding in p:
-            del(p[Padding].underlayer.payload)
-        ip = p[IP]
-        if ip.len is None or ip.ihl is None:
-            clen = len(ip.payload)
-        else:
-            clen = ip.len - (ip.ihl<<2)
-        txt = Raw()
-        for q in lst[1:]:
-            if clen != q.frag<<3:
-                if clen > q.frag<<3:
-                    warning("Fragment overlap (%i > %i) %r || %r ||  %r" % (clen, q.frag<<3, p,txt,q))
-                missfrag += lst
-                txt = None
-                break
-            if q[IP].len is None or q[IP].ihl is None:
-                clen += len(q[IP].payload)
-            else:
-                clen += q[IP].len - (q[IP].ihl<<2)
-            if Padding in q:
-                del(q[Padding].underlayer.payload)
-            txt.add_payload(q[IP].payload.copy())
-            
-        if txt is None:
-            continue
-
-        ip.flags &= ~1 # !MF
-        del(ip.chksum)
-        del(ip.len)
-        p = p/txt
-        p._defrag_pos = lst[-1]._defrag_pos
-        defrag.append(p)
-    defrag2=[]
-    for p in defrag:
-        q = p.__class__(str(p))
-        q._defrag_pos = p._defrag_pos
-        defrag2.append(q)
-    final += defrag2
-    final += missfrag
-    final.sort(lambda x,y: cmp(x._defrag_pos, y._defrag_pos))
-    for p in final:
-        del(p._defrag_pos)
-
-    if hasattr(plist, "listname"):
-        name = "Defragmented %s" % plist.listname
-    else:
-        name = "Defragmented"
-        
-    
-    return PacketList(final, name=name)
-            
-            
-        
-    
-
-
-###################
-## Super sockets ##
-###################
-
-def Ether_Dot3_Dispatcher(pkt=None, **kargs):
-    if type(pkt) is str and len(pkt) >= 14 and struct.unpack("!H", pkt[12:14])[0] <= 1500:
-        return Dot3(pkt, **kargs)
-    return Ether(pkt, **kargs)
-
-# According to libdnet
-LLTypes = { ARPHDR_ETHER : Ether_Dot3_Dispatcher,
-            ARPHDR_METRICOM : Ether_Dot3_Dispatcher,
-            ARPHDR_LOOPBACK : Ether_Dot3_Dispatcher,
-            9: PPP,
-            12 : IP,
-            101 : IP,
-            801 : Dot11,
-            802 : PrismHeader,
-            803 : RadioTap,
-            105 : Dot11,
-            113 : CookedLinux,
-            119 : PrismHeader, # for atheros
-            127 : RadioTap,
-            144 : CookedLinux, # called LINUX_IRDA, similar to CookedLinux
-            783 : IrLAPHead,
-            0xB1E70073L : HCI_Hdr, # I invented this one
-            }
-
-LLNumTypes = { Ether : ARPHDR_ETHER,
-               PPP: 9,
-               IP  : 12,
-               IP  : 101,
-               Dot11  : 801,
-               PrismHeader : 802,
-               RadioTap    : 803,
-               RadioTap    : 127,
-               Dot11 : 105,
-               CookedLinux : 113,
-               CookedLinux : 144,
-               IrLAPHead : 783
-            }
-
-L3Types = { ETH_P_IP : IP,
-            ETH_P_ARP : ARP,
-            ETH_P_ALL : IP
-            }
-
-
-def flush_fd(fd):
-    if type(fd) is not int:
-        fd = fd.fileno()
-    while 1:
-        r,w,e = select([fd],[],[],0)
-        if r:
-            os.read(fd,MTU)
-        else:
-            break
-
-class SuperSocket:
-    closed=0
-    def __init__(self, family=socket.AF_INET,type=socket.SOCK_STREAM, proto=0):
-        self.ins = socket.socket(family, type, proto)
-        self.outs = self.ins
-        self.promisc=None
-    def send(self, x):
-        sx = str(x)
-        x.sent_time = time.time()
-        return self.outs.send(sx)
-    def recv(self, x):
-        return Raw(self.ins.recv(x))
-    def fileno(self):
-        return self.ins.fileno()
-    def close(self):
-        if self.closed:
-            return
-        self.closed=1
-        if self.ins != self.outs:
-            if self.outs and self.outs.fileno() != -1:
-                self.outs.close()
-        if self.ins and self.ins.fileno() != -1:
-            self.ins.close()
-    def bind_in(self, addr):
-        self.ins.bind(addr)
-    def bind_out(self, addr):
-        self.outs.bind(addr)
-
-
-class L3RawSocket(SuperSocket):
-    def __init__(self, type = ETH_P_IP, filter=None, iface=None, promisc=None, nofilter=0):
-        self.outs = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_RAW)
-        self.outs.setsockopt(socket.SOL_IP, socket.IP_HDRINCL, 1)
-        self.ins = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(type))
-    def recv(self, x):
-        return Ether(self.ins.recv(x)).payload
-    def send(self, x):
-        try:
-            sx = str(x)
-            x.sent_time = time.time()
-            self.outs.sendto(sx,(x.dst,0))
-        except socket.error,msg:
-            log_runtime.error(msg)
-        
-
-
-class L3PacketSocket(SuperSocket):
-    def __init__(self, type = ETH_P_ALL, filter=None, promisc=None, iface=None, nofilter=0):
-        self.type = type
-        self.ins = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(type))
-        self.ins.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 0)
-        flush_fd(self.ins)
-        if iface:
-            self.ins.bind((iface, type))
-        if not nofilter:
-            if conf.except_filter:
-                if filter:
-                    filter = "(%s) and not (%s)" % (filter, conf.except_filter)
-                else:
-                    filter = "not (%s)" % conf.except_filter
-            if filter is not None:
-                attach_filter(self.ins, filter)
-        self.ins.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 2**30)
-        self.outs = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(type))
-        self.outs.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 2**30)
-        if promisc is None:
-            promisc = conf.promisc
-        self.promisc = promisc
-        if self.promisc:
-            if iface is None:
-                self.iff = get_if_list()
-            else:
-                if iface.__class__ is list:
-                    self.iff = iface
-                else:
-                    self.iff = [iface]
-            for i in self.iff:
-                set_promisc(self.ins, i)
-    def close(self):
-        if self.closed:
-            return
-        self.closed=1
-        if self.promisc:
-            for i in self.iff:
-                set_promisc(self.ins, i, 0)
-        SuperSocket.close(self)
-    def recv(self, x):
-        pkt, sa_ll = self.ins.recvfrom(x)
-        if sa_ll[2] == socket.PACKET_OUTGOING:
-            return None
-        if LLTypes.has_key(sa_ll[3]):
-            cls = LLTypes[sa_ll[3]]
-            lvl = 2
-        elif L3Types.has_key(sa_ll[1]):
-            cls = L3Types[sa_ll[1]]
-            lvl = 3
-        else:
-            warning("Unable to guess type (interface=%s protocol=%#x family=%i). Using Ethernet" % (sa_ll[0],sa_ll[1],sa_ll[3]))
-            cls = Ether
-            lvl = 2
-
-        try:
-            pkt = cls(pkt)
-        except KeyboardInterrupt:
-            raise
-        except:
-            if conf.debug_dissector:
-                raise
-            pkt = Raw(pkt)
-        if lvl == 2:
-            pkt = pkt.payload
-            
-        if pkt is not None:
-            pkt.time = get_last_packet_timestamp(self.ins)
-        return pkt
-    
-    def send(self, x):
-        if isinstance(x, IPv6):
-            iff,a,gw = conf.route6.route(x.dst)
-        elif hasattr(x,"dst"):
-            iff,a,gw = conf.route.route(x.dst)
-        else:
-            iff = conf.iface
-        sdto = (iff, self.type)
-        self.outs.bind(sdto)
-        sn = self.outs.getsockname()
-        ll = lambda x:x
-        if sn[3] in (ARPHDR_PPP,ARPHDR_TUN):
-            sdto = (iff, ETH_P_IP)
-        if LLTypes.has_key(sn[3]):
-            ll = lambda x:LLTypes[sn[3]]()/x
-        try:
-            sx = str(ll(x))
-            x.sent_time = time.time()
-            self.outs.sendto(sx, sdto)
-        except socket.error,msg:
-            x.sent_time = time.time()  # bad approximation
-            if conf.auto_fragment and msg[0] == 90:
-                for p in fragment(x):
-                    self.outs.sendto(str(ll(p)), sdto)
-            else:
-                raise
-                    
-
-
-
-class L2Socket(SuperSocket):
-    def __init__(self, iface = None, type = ETH_P_ALL, filter=None, nofilter=0):
-        if iface is None:
-            iface = conf.iface
-        self.ins = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(type))
-        self.ins.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 0)
-        flush_fd(self.ins)
-        if not nofilter: 
-            if conf.except_filter:
-                if filter:
-                    filter = "(%s) and not (%s)" % (filter, conf.except_filter)
-                else:
-                    filter = "not (%s)" % conf.except_filter
-            if filter is not None:
-                attach_filter(self.ins, filter)
-        self.ins.bind((iface, type))
-        self.ins.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 2**30)
-        self.outs = self.ins
-        self.outs.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 2**30)
-        sa_ll = self.outs.getsockname()
-        if LLTypes.has_key(sa_ll[3]):
-            self.LL = LLTypes[sa_ll[3]]
-        elif L3Types.has_key(sa_ll[1]):
-            self.LL = L3Types[sa_ll[1]]
-        else:
-            warning("Unable to guess type (interface=%s protocol=%#x family=%i). Using Ethernet" % (sa_ll[0],sa_ll[1],sa_ll[3]))
-            self.LL = Ether
-            
-    def recv(self, x):
-        pkt, sa_ll = self.ins.recvfrom(x)
-        if sa_ll[2] == socket.PACKET_OUTGOING:
-            return None
-        try:
-            q = self.LL(pkt)
-        except KeyboardInterrupt:
-            raise
-        except:
-            if conf.debug_dissector:
-                raise
-            q = Raw(pkt)
-        q.time = get_last_packet_timestamp(self.ins)
-        return q
-
-
-class L2ListenSocket(SuperSocket):
-    def __init__(self, iface = None, type = ETH_P_ALL, promisc=None, filter=None, nofilter=0):
-        self.type = type
-        self.outs = None
-        self.ins = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(type))
-        self.ins.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 0)
-        flush_fd(self.ins)
-        if iface is not None:
-            self.ins.bind((iface, type))
-        if not nofilter:
-            if conf.except_filter:
-                if filter:
-                    filter = "(%s) and not (%s)" % (filter, conf.except_filter)
-                else:
-                    filter = "not (%s)" % conf.except_filter
-            if filter is not None:
-                attach_filter(self.ins, filter)
-        if promisc is None:
-            promisc = conf.sniff_promisc
-        self.promisc = promisc
-        if iface is None:
-            self.iff = get_if_list()
-        else:
-            if iface.__class__ is list:
-                self.iff = iface
-            else:
-                self.iff = [iface]
-        if self.promisc:
-            for i in self.iff:
-                set_promisc(self.ins, i)
-        self.ins.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 2**30)
-    def close(self):
-        if self.promisc:
-            for i in self.iff:
-                set_promisc(self.ins, i, 0)
-        SuperSocket.close(self)
-
-    def recv(self, x):
-        pkt, sa_ll = self.ins.recvfrom(x)
-        if LLTypes.has_key(sa_ll[3]):
-            cls = LLTypes[sa_ll[3]]
-        elif L3Types.has_key(sa_ll[1]):
-            cls = L3Types[sa_ll[1]]
-        else:
-            warning("Unable to guess type (interface=%s protocol=%#x family=%i). Using Ethernet" % (sa_ll[0],sa_ll[1],sa_ll[3]))
-            cls = Ether
-
-        try:
-            pkt = cls(pkt)
-        except KeyboardInterrupt:
-            raise
-        except:
-            if conf.debug_dissector:
-                raise
-            pkt = Raw(pkt)
-        pkt.time = get_last_packet_timestamp(self.ins)
-        return pkt
-    
-    def send(self, x):
-        raise Scapy_Exception("Can't send anything with L2ListenSocket")
-
-
-
-class L3dnetSocket(SuperSocket):
-    def __init__(self, type = ETH_P_ALL, filter=None, promisc=None, iface=None, nofilter=0):
-        self.iflist = {}
-        self.ins = pcap.pcapObject()
-        if iface is None:
-            iface = conf.iface
-        self.iface = iface
-        self.ins.open_live(iface, 1600, 0, 100)
-        try:
-            ioctl(self.ins.fileno(),BIOCIMMEDIATE,struct.pack("I",1))
-        except:
-            pass
-        if nofilter:
-            if type != ETH_P_ALL:  # PF_PACKET stuff. Need to emulate this for pcap
-                filter = "ether proto %i" % type
-            else:
-                filter = None
-        else:
-            if conf.except_filter:
-                if filter:
-                    filter = "(%s) and not (%s)" % (filter, conf.except_filter)
-                else:
-                    filter = "not (%s)" % conf.except_filter
-            if type != ETH_P_ALL:  # PF_PACKET stuff. Need to emulate this for pcap
-                if filter:
-                    filter = "(ether proto %i) and (%s)" % (type,filter)
-                else:
-                    filter = "ether proto %i" % type
-        if filter:
-            self.ins.setfilter(filter, 0, 0)
-    def send(self, x):
-        if isinstance(x, IPv6):
-            iff,a,gw = conf.route6.route(x.dst)
-        elif hasattr(x,"dst"):
-            iff,a,gw = conf.route.route(x.dst)
-        else:
-            iff = conf.iface
-        ifs = self.iflist.get(iff)
-        if ifs is None:
-            self.iflist[iff] = ifs = dnet.eth(iff)
-        sx = str(Ether()/x)
-        x.sent_time = time.time()
-        ifs.send(sx)
-    def recv(self,x=MTU):
-        ll = self.ins.datalink()
-        if LLTypes.has_key(ll):
-            cls = LLTypes[ll]
-        else:
-            warning("Unable to guess datalink type (interface=%s linktype=%i). Using Ethernet" % (self.iface, ll))
-            cls = Ether
-
-        pkt = self.ins.next()
-        if pkt is not None:
-            l,pkt,ts = pkt
-        if pkt is None:
-            return
-
-        try:
-            pkt = cls(pkt)
-        except KeyboardInterrupt:
-            raise
-        except:
-            if conf.debug_dissector:
-                raise
-            pkt = Raw(pkt)
-        pkt.time = ts
-        return pkt.payload
-
-    def nonblock_recv(self):
-        self.ins.setnonblock(1)
-        p = self.recv()
-        self.ins.setnonblock(0)
-        return p
-
-    def close(self):
-        if hasattr(self, "ins"):
-            del(self.ins)
-        if hasattr(self, "outs"):
-            del(self.outs)
-
-class L2dnetSocket(SuperSocket):
-    def __init__(self, iface = None, type = ETH_P_ALL, filter=None, nofilter=0):
-        if iface is None:
-            iface = conf.iface
-        self.iface = iface
-        self.ins = pcap.pcapObject()
-        self.ins.open_live(iface, 1600, 0, 100)
-        try:
-            ioctl(self.ins.fileno(),BIOCIMMEDIATE,struct.pack("I",1))
-        except:
-            pass
-        if nofilter:
-            if type != ETH_P_ALL:  # PF_PACKET stuff. Need to emulate this for pcap
-                filter = "ether proto %i" % type
-            else:
-                filter = None
-        else:
-            if conf.except_filter:
-                if filter:
-                    filter = "(%s) and not (%s)" % (filter, conf.except_filter)
-                else:
-                    filter = "not (%s)" % conf.except_filter
-            if type != ETH_P_ALL:  # PF_PACKET stuff. Need to emulate this for pcap
-                if filter:
-                    filter = "(ether proto %i) and (%s)" % (type,filter)
-                else:
-                    filter = "ether proto %i" % type
-        if filter:
-            self.ins.setfilter(filter, 0, 0)
-        self.outs = dnet.eth(iface)
-    def recv(self,x):
-        ll = self.ins.datalink()
-        if LLTypes.has_key(ll):
-            cls = LLTypes[ll]
-        else:
-            warning("Unable to guess datalink type (interface=%s linktype=%i). Using Ethernet" % (self.iface, ll))
-            cls = Ether
-
-        pkt = self.ins.next()
-        if pkt is not None:
-            l,pkt,ts = pkt
-        if pkt is None:
-            return
-        
-        try:
-            pkt = cls(pkt)
-        except KeyboardInterrupt:
-            raise
-        except:
-            if conf.debug_dissector:
-                raise
-            pkt = Raw(pkt)
-        pkt.time = ts
-        return pkt
-
-    def nonblock_recv(self):
-        self.ins.setnonblock(1)
-        p = self.recv(MTU)
-        self.ins.setnonblock(0)
-        return p
-
-    def close(self):
-        if hasattr(self, "ins"):
-            del(self.ins)
-        if hasattr(self, "outs"):
-            del(self.outs)
-    
-    
-    
-
-
-class L2pcapListenSocket(SuperSocket):
-    def __init__(self, iface = None, type = ETH_P_ALL, promisc=None, filter=None):
-        self.type = type
-        self.outs = None
-        self.ins = pcap.pcapObject()
-        self.iface = iface
-        if iface is None:
-            iface = conf.iface
-        if promisc is None:
-            promisc = conf.sniff_promisc
-        self.promisc = promisc
-        self.ins.open_live(iface, 1600, self.promisc, 100)
-        try:
-            ioctl(self.ins.fileno(),BIOCIMMEDIATE,struct.pack("I",1))
-        except:
-            pass
-        if type == ETH_P_ALL: # Do not apply any filter if Ethernet type is given
-            if conf.except_filter:
-                if filter:
-                    filter = "(%s) and not (%s)" % (filter, conf.except_filter)
-                else:
-                    filter = "not (%s)" % conf.except_filter
-            if filter:
-                self.ins.setfilter(filter, 0, 0)
-
-    def close(self):
-        del(self.ins)
-        
-    def recv(self, x):
-        ll = self.ins.datalink()
-        if LLTypes.has_key(ll):
-            cls = LLTypes[ll]
-        else:
-            warning("Unable to guess datalink type (interface=%s linktype=%i). Using Ethernet" % (self.iface, ll))
-            cls = Ether
-
-        pkt = None
-        while pkt is None:
-            pkt = self.ins.next()
-            if pkt is not None:
-                l,pkt,ts = pkt
-        
-        try:
-            pkt = cls(pkt)
-        except KeyboardInterrupt:
-            raise
-        except:
-            if conf.debug_dissector:
-                raise
-            pkt = Raw(pkt)
-        pkt.time = ts
-        return pkt
-
-    def send(self, x):
-        raise Scapy_Exception("Can't send anything with L2pcapListenSocket")
-
-
-class SimpleSocket(SuperSocket):
-    def __init__(self, sock):
-        self.ins = sock
-        self.outs = sock
-
-
-class StreamSocket(SimpleSocket):
-    def __init__(self, sock, basecls=Raw):
-        SimpleSocket.__init__(self, sock)
-        self.basecls = basecls
-        
-    def recv(self, x=MTU):
-        pkt = self.ins.recv(x, socket.MSG_PEEK)
-        x = len(pkt)
-        pkt = self.basecls(pkt)
-        pad = pkt[Padding]
-        if pad is not None and pad.underlayer is not None:
-            del(pad.underlayer.payload)
-        while pad is not None and not isinstance(pad, NoPayload):
-            x -= len(pad.load)
-            pad = pad.payload
-        self.ins.recv(x)
-        return pkt
-        
-        
-class BluetoothL2CAPSocket(SuperSocket):
-    def __init__(self, peer):
-        s = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_RAW,
-                          socket.BTPROTO_L2CAP)
-        s.connect((peer,0))
-        
-        self.ins = self.outs = s
-
-    def recv(self, x):
-        return L2CAP_CmdHdr(self.ins.recv(x))
-    
-
-class BluetoothHCISocket(SuperSocket):
-    def __init__(self, iface=0x10000, type=None):
-        s = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_RAW, socket.BTPROTO_HCI)
-        s.setsockopt(socket.SOL_HCI, socket.HCI_DATA_DIR,1)
-        s.setsockopt(socket.SOL_HCI, socket.HCI_TIME_STAMP,1)
-        s.setsockopt(socket.SOL_HCI, socket.HCI_FILTER, struct.pack("IIIh2x", 0xffffffffL,0xffffffffL,0xffffffffL,0)) #type mask, event mask, event mask, opcode
-        s.bind((iface,))
-        self.ins = self.outs = s
-#        s.connect((peer,0))
-        
-
-    def recv(self, x):
-        return HCI_Hdr(self.ins.recv(x))
-    
-
-
-####################
-## Send / Receive ##
-####################
-
-
-
-
-def sndrcv(pks, pkt, timeout = 2, inter = 0, verbose=None, chainCC=0, retry=0, multi=0):
-    if not isinstance(pkt, Gen):
-        pkt = SetGen(pkt)
-        
-    if verbose is None:
-        verbose = conf.verb
-    debug.recv = PacketList([],"Unanswered")
-    debug.sent = PacketList([],"Sent")
-    debug.match = SndRcvList([])
-    nbrecv=0
-    ans = []
-    # do it here to fix random fields, so that parent and child have the same
-    all_stimuli = tobesent = [p for p in pkt]
-    notans = len(tobesent)
-
-    hsent={}
-    for i in tobesent:
-        h = i.hashret()
-        if h in hsent:
-            hsent[h].append(i)
-        else:
-            hsent[h] = [i]
-    if retry < 0:
-        retry = -retry
-        autostop=retry
-    else:
-        autostop=0
-
-
-    while retry >= 0:
-        found=0
-    
-        if timeout < 0:
-            timeout = None
-            
-        rdpipe,wrpipe = os.pipe()
-        rdpipe=os.fdopen(rdpipe)
-        wrpipe=os.fdopen(wrpipe,"w")
-
-        pid=1
-        try:
-            pid = os.fork()
-            if pid == 0:
-                try:
-                    sys.stdin.close()
-                    rdpipe.close()
-                    try:
-                        i = 0
-                        if verbose:
-                            print "Begin emission:"
-                        for p in tobesent:
-                            pks.send(p)
-                            i += 1
-                            time.sleep(inter)
-                        if verbose:
-                            print "Finished to send %i packets." % i
-                    except SystemExit:
-                        pass
-                    except KeyboardInterrupt:
-                        pass
-                    except:
-                        log_runtime.exception("--- Error in child %i" % os.getpid())
-                        log_runtime.info("--- Error in child %i" % os.getpid())
-                finally:
-                    try:
-                        os.setpgrp() # Chance process group to avoid ctrl-C
-                        sent_times = [p.sent_time for p in all_stimuli if p.sent_time]
-                        cPickle.dump( (arp_cache,sent_times), wrpipe )
-                        wrpipe.close()
-                    except:
-                        pass
-            elif pid < 0:
-                log_runtime.error("fork error")
-            else:
-                wrpipe.close()
-                stoptime = 0
-                remaintime = None
-                inmask = [rdpipe,pks]
-                try:
-                    try:
-                        while 1:
-                            if stoptime:
-                                remaintime = stoptime-time.time()
-                                if remaintime <= 0:
-                                    break
-                            r = None
-                            if FREEBSD or DARWIN:
-                                inp, out, err = select(inmask,[],[], 0.05)
-                                if len(inp) == 0 or pks in inp:
-                                    r = pks.nonblock_recv()
-                            else:
-                                inp, out, err = select(inmask,[],[], remaintime)
-                                if len(inp) == 0:
-                                    break
-                                if pks in inp:
-                                    r = pks.recv(MTU)
-                            if rdpipe in inp:
-                                if timeout:
-                                    stoptime = time.time()+timeout
-                                del(inmask[inmask.index(rdpipe)])
-                            if r is None:
-                                continue
-                            ok = 0
-                            h = r.hashret()
-                            if h in hsent:
-                                hlst = hsent[h]
-                                for i in range(len(hlst)):
-                                    if r.answers(hlst[i]):
-                                        ans.append((hlst[i],r))
-                                        if verbose > 1:
-                                            os.write(1, "*")
-                                        ok = 1                                
-                                        if not multi:
-                                            del(hlst[i])
-                                            notans -= 1;
-                                        else:
-                                            if not hasattr(hlst[i], '_answered'):
-                                                notans -= 1;
-                                            hlst[i]._answered = 1;
-                                        break
-                            if notans == 0 and not multi:
-                                break
-                            if not ok:
-                                if verbose > 1:
-                                    os.write(1, ".")
-                                nbrecv += 1
-                                if conf.debug_match:
-                                    debug.recv.append(r)
-                    except KeyboardInterrupt:
-                        if chainCC:
-                            raise
-                finally:
-                    try:
-                        ac,sent_times = cPickle.load(rdpipe)
-                    except EOFError:
-                        warning("Child died unexpectedly. Packets may have not been sent %i"%os.getpid())
-                    else:
-                        arp_cache.update(ac)
-                        for p,t in zip(all_stimuli, sent_times):
-                            p.sent_time = t
-                    os.waitpid(pid,0)
-        finally:
-            if pid == 0:
-                os._exit(0)
-
-        remain = reduce(list.__add__, hsent.values(), [])
-        if multi:
-            remain = filter(lambda p: not hasattr(p, '_answered'), remain);
-            
-        if autostop and len(remain) > 0 and len(remain) != len(tobesent):
-            retry = autostop
-            
-        tobesent = remain
-        if len(tobesent) == 0:
-            break
-        retry -= 1
-        
-    if conf.debug_match:
-        debug.sent=PacketList(remain[:],"Sent")
-        debug.match=SndRcvList(ans[:])
-
-    #clean the ans list to delete the field _answered
-    if (multi):
-        for s,r in ans:
-            if hasattr(s, '_answered'):
-                del(s._answered)
-    
-    if verbose:
-        print "\nReceived %i packets, got %i answers, remaining %i packets" % (nbrecv+len(ans), len(ans), notans)
-    return SndRcvList(ans),PacketList(remain,"Unanswered"),debug.recv
-
-
-def __gen_send(s, x, inter=0, loop=0, count=None, verbose=None, *args, **kargs):
-    if not isinstance(x, Gen):
-        x = SetGen(x)
-    if verbose is None:
-        verbose = conf.verb
-    n = 0
-    if count is not None:
-        loop = -count
-    elif not loop:
-        loop=-1
-    try:
-        while loop:
-            for p in x:
-                s.send(p)
-                n += 1
-                if verbose:
-                    os.write(1,".")
-                time.sleep(inter)
-            if loop < 0:
-                loop += 1
-    except KeyboardInterrupt:
-        pass
-    s.close()
-    if verbose:
-        print "\nSent %i packets." % n
-
-def send(x, inter=0, loop=0, count=None, verbose=None, *args, **kargs):
-    """Send packets at layer 3
-send(packets, [inter=0], [loop=0], [verbose=conf.verb]) -> None"""
-    __gen_send(conf.L3socket(*args, **kargs), x, inter=inter, loop=loop, count=count,verbose=verbose)
-
-def sendp(x, inter=0, loop=0, iface=None, iface_hint=None, count=None, verbose=None, *args, **kargs):
-    """Send packets at layer 2
-sendp(packets, [inter=0], [loop=0], [verbose=conf.verb]) -> None"""
-    if iface is None and iface_hint is not None:
-        iface = conf.route.route(iface_hint)[0]
-    __gen_send(conf.L2socket(iface=iface, *args, **kargs), x, inter=inter, loop=loop, count=count, verbose=verbose)
-
-def sendpfast(x, pps=None, mbps=None, realtime=None, loop=0, iface=None):
-    """Send packets at layer 2 using tcpreplay for performance
-    pps:  packets per second
-    mpbs: MBits per second
-    realtime: use packet's timestamp, bending time with realtime value
-    loop: number of times to process the packet list
-    iface: output interface """
-    if iface is None:
-        iface = conf.iface
-    options = ["--intf1=%s" % iface ]
-    if pps is not None:
-        options.append("--pps=%i" % pps)
-    elif mbps is not None:
-        options.append("--mbps=%i" % mbps)
-    elif realtime is not None:
-        options.append("--multiplier=%i" % realtime)
-    else:
-        options.append("--topspeed")
-
-    if loop:
-        options.append("--loop=%i" % loop)
-
-    f = os.tempnam("scapy")
-    options.append(f)
-    wrpcap(f, x)
-    try:
-        try:
-            os.spawnlp(os.P_WAIT, conf.prog.tcpreplay, conf.prog.tcpreplay, *options)
-        except KeyboardInterrupt:
-            log_interactive.info("Interrupted by user")
-    finally:
-        os.unlink(f)
-
-        
-
-        
-    
-def sr(x,filter=None, iface=None, nofilter=0, *args,**kargs):
-    """Send and receive packets at layer 3
-nofilter: put 1 to avoid use of bpf filters
-retry:    if positive, how many times to resend unanswered packets
-          if negative, how many times to retry when no more packets are answered
-timeout:  how much time to wait after the last packet has been sent
-verbose:  set verbosity level
-multi:    whether to accept multiple answers for the same stimulus
-filter:   provide a BPF filter
-iface:    listen answers only on the given interface"""
-    if not kargs.has_key("timeout"):
-        kargs["timeout"] = -1
-    s = conf.L3socket(filter=filter, iface=iface, nofilter=nofilter)
-    a,b,c=sndrcv(s,x,*args,**kargs)
-    s.close()
-    return a,b
-
-def sr1(x,filter=None,iface=None, nofilter=0, *args,**kargs):
-    """Send packets at layer 3 and return only the first answer
-nofilter: put 1 to avoid use of bpf filters
-retry:    if positive, how many times to resend unanswered packets
-          if negative, how many times to retry when no more packets are answered
-timeout:  how much time to wait after the last packet has been sent
-verbose:  set verbosity level
-multi:    whether to accept multiple answers for the same stimulus
-filter:   provide a BPF filter
-iface:    listen answers only on the given interface"""
-    if not kargs.has_key("timeout"):
-        kargs["timeout"] = -1
-    s=conf.L3socket(filter=filter, nofilter=nofilter, iface=iface)
-    a,b,c=sndrcv(s,x,*args,**kargs)
-    s.close()
-    if len(a) > 0:
-        return a[0][1]
-    else:
-        return None
-
-def srp(x,iface=None, iface_hint=None, filter=None, nofilter=0, type=ETH_P_ALL, *args,**kargs):
-    """Send and receive packets at layer 2
-nofilter: put 1 to avoid use of bpf filters
-retry:    if positive, how many times to resend unanswered packets
-          if negative, how many times to retry when no more packets are answered
-timeout:  how much time to wait after the last packet has been sent
-verbose:  set verbosity level
-multi:    whether to accept multiple answers for the same stimulus
-filter:   provide a BPF filter
-iface:    work only on the given interface"""
-    if not kargs.has_key("timeout"):
-        kargs["timeout"] = -1
-    if iface is None and iface_hint is not None:
-        iface = conf.route.route(iface_hint)[0]
-    s = conf.L2socket(iface=iface, filter=filter, nofilter=nofilter, type=type)
-    a,b,c=sndrcv(s ,x,*args,**kargs)
-    s.close()
-    return a,b
-
-def srp1(*args,**kargs):
-    """Send and receive packets at layer 2 and return only the first answer
-nofilter: put 1 to avoid use of bpf filters
-retry:    if positive, how many times to resend unanswered packets
-          if negative, how many times to retry when no more packets are answered
-timeout:  how much time to wait after the last packet has been sent
-verbose:  set verbosity level
-multi:    whether to accept multiple answers for the same stimulus
-filter:   provide a BPF filter
-iface:    work only on the given interface"""
-    if not kargs.has_key("timeout"):
-        kargs["timeout"] = -1
-    a,b=srp(*args,**kargs)
-    if len(a) > 0:
-        return a[0][1]
-    else:
-        return None
-
-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):
-    n = 0
-    r = 0
-    ct = conf.color_theme
-    if verbose is None:
-        verbose = conf.verb
-    parity = 0
-    ans=[]
-    unans=[]
-    if timeout is None:
-        timeout = min(2*inter, 5)
-    try:
-        while 1:
-            parity ^= 1
-            col = [ct.even,ct.odd][parity]
-            if count is not None:
-                if count == 0:
-                    break
-                count -= 1
-            start = time.time()
-            print "\rsend...\r",
-            res = srfunc(pkts, timeout=timeout, verbose=0, chainCC=1, *args, **kargs)
-            n += len(res[0])+len(res[1])
-            r += len(res[0])
-            if verbose > 1 and prn and len(res[0]) > 0:
-                msg = "RECV %i:" % len(res[0])
-                print  "\r"+ct.success(msg),
-                for p in res[0]:
-                    print col(prn(p))
-                    print " "*len(msg),
-            if verbose > 1 and prnfail and len(res[1]) > 0:
-                msg = "fail %i:" % len(res[1])
-                print "\r"+ct.fail(msg),
-                for p in res[1]:
-                    print col(prnfail(p))
-                    print " "*len(msg),
-            if verbose > 1 and not (prn or prnfail):
-                print "recv:%i  fail:%i" % tuple(map(len, res[:2]))
-            if store:
-                ans += res[0]
-                unans += res[1]
-            end=time.time()
-            if end-start < inter:
-                time.sleep(inter+start-end)
-    except KeyboardInterrupt:
-        pass
- 
-    if verbose and n>0:
-        print ct.normal("\nSent %i packets, received %i packets. %3.1f%% hits." % (n,r,100.0*r/n))
-    return SndRcvList(ans),PacketList(unans)
-
-def srloop(pkts, *args, **kargs):
-    """Send a packet at layer 3 in loop and print the answer each time
-srloop(pkts, [prn], [inter], [count], ...) --> None"""
-    return __sr_loop(sr, pkts, *args, **kargs)
-
-def srploop(pkts, *args, **kargs):
-    """Send a packet at layer 2 in loop and print the answer each time
-srloop(pkts, [prn], [inter], [count], ...) --> None"""
-    return __sr_loop(srp, pkts, *args, **kargs)
-
-
-def sndrcvflood(pks, pkt, prn=lambda (s,r):r.summary(), chainCC=0, store=1, unique=0):
-    if not isinstance(pkt, Gen):
-        pkt = SetGen(pkt)
-    tobesent = [p for p in pkt]
-    received = SndRcvList()
-    seen = {}
-
-    hsent={}
-    for i in tobesent:
-        h = i.hashret()
-        if h in hsent:
-            hsent[h].append(i)
-        else:
-            hsent[h] = [i]
-
-    def send_in_loop(tobesent):
-        while 1:
-            for p in tobesent:
-                yield p
-
-    packets_to_send = send_in_loop(tobesent)
-
-    ssock = rsock = pks.fileno()
-
-    try:
-        while 1:
-            readyr,readys,_ = select([rsock],[ssock],[])
-            if ssock in readys:
-                pks.send(packets_to_send.next())
-                
-            if rsock in readyr:
-                p = pks.recv(MTU)
-                if p is None:
-                    continue
-                h = p.hashret()
-                if h in hsent:
-                    hlst = hsent[h]
-                    for i in hlst:
-                        if p.answers(i):
-                            res = prn((i,p))
-                            if unique:
-                                if res in seen:
-                                    continue
-                                seen[res] = None
-                            if res is not None:
-                                print res
-                            if store:
-                                received.append((i,p))
-    except KeyboardInterrupt:
-        if chainCC:
-            raise
-    return received
-
-def srflood(x,filter=None, iface=None, nofilter=None, *args,**kargs):
-    """Flood and receive packets at layer 3
-prn:      function applied to packets received. Ret val is printed if not None
-store:    if 1 (default), store answers and return them
-unique:   only consider packets whose print 
-nofilter: put 1 to avoid use of bpf filters
-filter:   provide a BPF filter
-iface:    listen answers only on the given interface"""
-    s = conf.L3socket(filter=filter, iface=iface, nofilter=nofilter)
-    r=sndrcvflood(s,x,*args,**kargs)
-    s.close()
-    return r
-
-def srpflood(x,filter=None, iface=None, iface_hint=None, nofilter=None, *args,**kargs):
-    """Flood and receive packets at layer 2
-prn:      function applied to packets received. Ret val is printed if not None
-store:    if 1 (default), store answers and return them
-unique:   only consider packets whose print 
-nofilter: put 1 to avoid use of bpf filters
-filter:   provide a BPF filter
-iface:    listen answers only on the given interface"""
-    if iface is None and iface_hint is not None:
-        iface = conf.route.route(iface_hint)[0]    
-    s = conf.L2socket(filter=filter, iface=iface, nofilter=nofilter)
-    r=sndrcvflood(s,x,*args,**kargs)
-    s.close()
-    return r
-
-           
-## Bluetooth
-
-
-def srbt(peer, pkts, inter=0.1, *args, **kargs):
-    s = conf.BTsocket(peer=peer)
-    a,b,c=sndrcv(s,pkts,inter=inter,*args,**kargs)
-    s.close()
-    return a,b
-
-def srbt1(peer, pkts, *args, **kargs):
-    a,b = srbt(peer, pkts, *args, **kargs)
-    if len(a) > 0:
-        return a[0][1]
-        
-    
-
-
-
-#############################
-## pcap capture file stuff ##
-#############################
-
-def wrpcap(filename, pkt, *args, **kargs):
-    """Write a list of packets to a pcap file
-gz: set to 1 to save a gzipped capture
-linktype: force linktype value
-endianness: "<" or ">", force endianness"""
-    PcapWriter(filename, *args, **kargs).write(pkt)
-
-def rdpcap(filename, count=-1):
-    """Read a pcap file and return a packet list
-count: read only <count> packets"""
-    return PcapReader(filename).read_all(count=count)
-
-class PcapReader:
-    """A stateful pcap reader
-    
-    Based entirely on scapy.rdpcap(), this class allows for packets
-    to be dispatched without having to be loaded into memory all at
-    once
-    """
-
-    def __init__(self, filename):
-        self.filename = filename
-        try:
-            self.f = gzip.open(filename,"rb")
-            magic = self.f.read(4)
-        except IOError:
-            self.f = open(filename,"rb")
-            magic = self.f.read(4)
-        if magic == "\xa1\xb2\xc3\xd4": #big endian
-            self.endian = ">"
-        elif  magic == "\xd4\xc3\xb2\xa1": #little endian
-            self.endian = "<"
-        else:
-            raise RuntimeWarning, "Not a pcap capture file (bad magic)"
-        hdr = self.f.read(20)
-        if len(hdr)<20:
-            raise RuntimeWarning, "Invalid pcap file (too short)"
-        vermaj,vermin,tz,sig,snaplen,linktype = struct.unpack(self.endian+"HHIIII",hdr)
-        self.LLcls = LLTypes.get(linktype, Raw)
-        if self.LLcls == Raw:
-            warning("PcapReader: unkonwon LL type [%i]/[%#x]. Using Raw packets" % (linktype,linktype))
-
-    def __iter__(self):
-        return self
-
-    def next(self):
-        """impliment the iterator protocol on a set of packets in a
-        pcap file
-        """
-        pkt = self.read_packet()
-        if pkt == None:
-            raise StopIteration
-        return pkt
-
-
-    def read_packet(self):
-        """return a single packet read from the file
-        
-        returns None when no more packets are available
-        """
-        hdr = self.f.read(16)
-        if len(hdr) < 16:
-            return None
-        sec,usec,caplen,olen = struct.unpack(self.endian+"IIII", hdr)
-        s = self.f.read(caplen)
-        try:
-            p = self.LLcls(s)
-        except KeyboardInterrupt:
-            raise
-        except:
-            if conf.debug_dissector:
-                raise
-            p = Raw(s)
-        p.time = sec+0.000001*usec
-        return p
-
-    def dispatch(self, callback):
-        """call the specified callback routine for each packet read
-        
-        This is just a convienience function for the main loop
-        that allows for easy launching of packet processing in a 
-        thread.
-        """
-        p = self.read_packet()
-        while p != None:
-            callback(p)
-            p = self.read_packet()
-
-    def read_all(self,count=-1):
-        """return a list of all packets in the pcap file
-        """
-        res=[]
-        while count != 0:
-            count -= 1
-            p = self.read_packet()
-            if p is None:
-                break
-            res.append(p)
-        return PacketList(res,name = os.path.basename(self.filename))
-
-    def recv(self, size):
-        """ Emulate a socket
-        """
-        return self.read_packet()
-
-    def fileno(self):
-        return self.f.fileno()
-        
-
-
-class PcapWriter:
-    """A stream PCAP writer with more control than wrpcap()"""
-    def __init__(self, filename, linktype=None, gz=False, endianness="", append=False, sync=False):
-        """
-        linktype: force linktype to a given value. If None, linktype is taken
-                  from the first writter packet
-        gz: compress the capture on the fly
-        endianness: force an endianness (little:"<", big:">"). Default is native
-        append: append packets to the capture file instead of truncating it
-        sync: do not bufferize writes to the capture file
-        """
-        
-        self.linktype = linktype
-        self.header_present = 0
-        self.append=append
-        self.gz = gz
-        self.endian = endianness
-        self.filename=filename
-        self.sync=sync
-        bufsz=4096
-        if sync:
-            bufsz=0
-
-        self.f = [open,gzip.open][gz](filename,append and "ab" or "wb", gz and 9 or bufsz)
-        
-            
-
-    def fileno(self):
-        return self.f.fileno()
-
-    def _write_header(self, pkt):
-        self.header_present=1
-
-        if self.linktype == None:
-            if type(pkt) is list or type(pkt) is tuple:
-                pkt = pkt[0]
-            self.linktype = LLNumTypes.get(pkt.__class__,1)
-
-        if self.append:
-            # Even if prone to race conditions, this seems to be
-            # safest way to tell whether the header is already present
-            # because we have to handle compressed streams that
-            # are not as flexible as basic files
-            g = [open,gzip.open][self.gz](self.filename,"rb")
-            if g.read(16):
-                return
-            
-        self.f.write(struct.pack(self.endian+"IHHIIII", 0xa1b2c3d4L,
-                                 2, 4, 0, 0, MTU, self.linktype))
-        self.f.flush()
-    
-
-    def write(self, pkt):
-        """accepts a either a single packet or a list of packets
-        to be written to the dumpfile
-        """
-        if not self.header_present:
-            self._write_header(pkt)
-        for p in pkt:
-            self._write_packet(p)
-
-    def _write_packet(self, packet):
-        """writes a single packet to the pcap file
-        """
-        s = str(packet)
-        l = len(s)
-        sec = int(packet.time)
-        usec = int((packet.time-sec)*1000000)
-        self.f.write(struct.pack(self.endian+"IIII", sec, usec, l, l))
-        self.f.write(s)
-        if self.gz and self.sync:
-            self.f.flush()
-
-    def flush(self):
-        return self.f.flush()
-    def close(self):
-        return self.f.close()
-                
-
-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})")
-
-def import_hexcap():
-    p = ""
-    try:
-        while 1:
-            l = raw_input().strip()
-            try:
-                p += re_extract_hexcap.match(l).groups()[3]
-            except:
-                warning("Parsing error during hexcap")
-                continue
-    except EOFError:
-        pass
-    
-    p = p.replace(" ","")
-    p2=""
-    for i in range(len(p)/2):
-        p2 += chr(int(p[2*i:2*i+2],16))
-    return p2
-        
-
-
-def wireshark(pktlist):
-    f = os.tempnam("scapy")
-    wrpcap(f, pktlist)
-    os.spawnlp(os.P_NOWAIT, conf.prog.wireshark, conf.prog.wireshark, "-r", f)
-
-def hexedit(x):
-    x = str(x)
-    f = os.tempnam("scapy")
-    open(f,"w").write(x)
-    os.spawnlp(os.P_WAIT, conf.prog.hexedit, conf.prog.hexedit, f)
-    x = open(f).read()
-    os.unlink(f)
-    return x
-
-
-#####################
-## knowledge bases ##
-#####################
-
-class KnowledgeBase:
-    def __init__(self, filename):
-        self.filename = filename
-        self.base = None
-
-    def lazy_init(self):
-        self.base = ""
-
-    def reload(self, filename = None):
-        if filename is not None:
-            self.filename = filename
-        oldbase = self.base
-        self.base = None
-        self.lazy_init()
-        if self.base is None:
-            self.base = oldbase
-
-    def get_base(self):
-        if self.base is None:
-            self.lazy_init()
-        return self.base
-    
-
-
-##########################
-## IP location database ##
-##########################
-
-class IPCountryKnowledgeBase(KnowledgeBase):
-    """
-How to generate the base :
-db = []
-for l in open("GeoIPCountryWhois.csv").readlines():
-    s,e,c = l.split(",")[2:5]
-    db.append((int(s[1:-1]),int(e[1:-1]),c[1:-1]))
-cPickle.dump(gzip.open("xxx","w"),db)
-"""
-    def lazy_init(self):
-        self.base = load_object(self.filename)
-
-
-class CountryLocKnowledgeBase(KnowledgeBase):
-    def lazy_init(self):
-        f=open(self.filename)
-        self.base = {}
-        while 1:
-            l = f.readline()
-            if not l:
-                break
-            l = l.strip().split(",")
-            if len(l) != 3:
-                continue
-            c,lat,long = l
-            
-            self.base[c] = (float(long),float(lat))
-        f.close()
-            
-        
-
-
-def locate_ip(ip):
-    ip=map(int,ip.split("."))
-    ip = ip[3]+(ip[2]<<8L)+(ip[1]<<16L)+(ip[0]<<24L)
-
-    cloc = country_loc_kdb.get_base()
-    db = IP_country_kdb.get_base()
-
-    d=0
-    f=len(db)-1
-    while (f-d) > 1:
-        guess = (d+f)/2
-        if ip > db[guess][0]:
-            d = guess
-        else:
-            f = guess
-    s,e,c = db[guess]
-    if  s <= ip and ip <= e:
-        return cloc.get(c,None)
-
-
-    
-
-###############
-## p0f stuff ##
-###############
-
-# File format (according to p0f.fp) :
-#
-# wwww:ttt:D:ss:OOO...:QQ:OS:Details
-#
-# wwww    - window size
-# ttt     - initial TTL
-# D       - don't fragment bit  (0=unset, 1=set) 
-# ss      - overall SYN packet size
-# OOO     - option value and order specification
-# QQ      - quirks list
-# OS      - OS genre
-# details - OS description
-
-
-
-class p0fKnowledgeBase(KnowledgeBase):
-    def __init__(self, filename):
-        KnowledgeBase.__init__(self, filename)
-        #self.ttl_range=[255]
-    def lazy_init(self):
-        try:
-            f=open(self.filename)
-        except IOError:
-            warning("Can't open base %s" % self.filename)
-            return
-        try:
-            self.base = []
-            for l in f:
-                if l[0] in ["#","\n"]:
-                    continue
-                l = tuple(l.split(":"))
-                if len(l) < 8:
-                    continue
-                li = map(int,l[1:4])
-                #if li[0] not in self.ttl_range:
-                #    self.ttl_range.append(li[0])
-                #    self.ttl_range.sort()
-                self.base.append((l[0], li[0], li[1], li[2], l[4], l[5], l[6], l[7][:-1]))
-        except:
-            warning("Can't parse p0f database (new p0f version ?)")
-            self.base = None
-        f.close()
-
-
-def packet2p0f(pkt):
-    while pkt.haslayer(IP) and pkt.haslayer(TCP):
-        pkt = pkt.getlayer(IP)
-        if isinstance(pkt.payload, TCP):
-            break
-        pkt = pkt.payload
-
-    if not isinstance(pkt, IP) or not isinstance(pkt.payload, TCP):
-        raise TypeError("Not a TCP/IP packet")
-    if pkt.payload.flags & 0x13 != 0x02: #S,!A,!F
-        raise TypeError("Not a syn packet")
-    
-    #t = p0f_kdb.ttl_range[:]
-    #t += [pkt.ttl]
-    #t.sort()
-    #ttl=t[t.index(pkt.ttl)+1]
-    ttl = pkt.ttl
-
-    df = (pkt.flags & 2) / 2
-    ss = len(pkt)
-    # from p0f/config.h : PACKET_BIG = 100
-    if ss > 100:
-        ss = 0
-
-    ooo = ""
-    mss = -1
-    qqT = False
-    qqP = False
-    #qqBroken = False
-    ilen = (pkt[TCP].dataofs << 2) - 20 # from p0f.c
-    for option in pkt.payload.options:
-        ilen -= 1
-        if option[0] == "MSS":
-            ooo += "M" + str(option[1]) + ","
-            mss = option[1]
-            # FIXME: qqBroken
-            ilen -= 3
-        elif option[0] == "WScale":
-            ooo += "W" + str(option[1]) + ","
-            # FIXME: qqBroken
-            ilen -= 2
-        elif option[0] == "Timestamp":
-            if option[1][0] == 0:
-                ooo += "T0,"
-            else:
-                ooo += "T,"
-            if option[1][1] != 0:
-                qqT = True
-            ilen -= 9
-        elif option[0] == "SAckOK":
-            ooo += "S,"
-            ilen -= 1
-        elif option[0] == "NOP":
-            ooo += "N,"
-        elif option[0] == "EOL":
-            ooo += "E,"
-            if ilen > 0:
-                qqP = True
-        else:
-            ooo += "?,"
-            # FIXME: ilen
-    ooo = ooo[:-1]
-    if ooo == "": ooo = "."
-
-    win = pkt.payload.window
-    if mss != -1:
-        if win % mss == 0:
-            win = "S" + str(win/mss)
-        elif win % (mss + 40) == 0:
-            win = "T" + str(win/(mss+40))
-        win = str(win)
-
-    qq = ""
-
-    if qqP:
-        qq += "P"
-    if pkt[IP].id == 0:
-        qq += "Z"
-    if pkt[IP].options != '':
-        qq += "I"
-    if pkt[TCP].urgptr != 0:
-        qq += "U"
-    if pkt[TCP].reserved != 0:
-        qq += "X"
-    if pkt[TCP].ack != 0:
-        qq += "A"
-    if qqT:
-        qq += "T"
-    if pkt[TCP].flags & 40 != 0:
-        # U or P
-        qq += "F"
-    if not isinstance(pkt[TCP].payload, NoPayload):
-        qq += "D"
-    # FIXME : "!" - broken options segment
-
-    if qq == "":
-        qq = "."
-
-    return (win,
-            ttl,
-            df,
-            ss,
-            ooo,
-            qq)
-
-def p0f_correl(x,y):
-    d = 0
-    # wwww can be "*" or "%nn"
-    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))
-    # ttl
-    d += (y[1] >= x[1] and y[1] - x[1] < 32)
-    for i in [2, 3, 5]:
-        d += (x[i] == y[i])
-    xopt = x[4].split(",")
-    yopt = y[4].split(",")
-    if len(xopt) == len(yopt):
-        same = True
-        for i in range(len(xopt)):
-            if not (xopt[i] == yopt[i] or
-                    (len(yopt[i]) == 2 and len(xopt[i]) > 1 and
-                     yopt[i][1] == "*" and xopt[i][0] == yopt[i][0]) or
-                    (len(yopt[i]) > 2 and len(xopt[i]) > 1 and
-                     yopt[i][1] == "%" and xopt[i][0] == yopt[i][0] and
-                     int(xopt[i][1:]) % int(yopt[i][2:]) == 0)):
-                same = False
-                break
-        if same:
-            d += len(xopt)
-    return d
-
-
-def p0f(pkt):
-    """Passive OS fingerprinting: which OS emitted this TCP SYN ?
-p0f(packet) -> accuracy, [list of guesses]
-"""
-    pb = p0f_kdb.get_base()
-    if not pb:
-        warning("p0f base empty.")
-        return []
-    s = len(pb[0][0])
-    r = []
-    sig = packet2p0f(pkt)
-    max = len(sig[4].split(",")) + 5
-    for b in pb:
-        d = p0f_correl(sig,b)
-        if d == max:
-            r.append((b[6], b[7], b[1] - pkt[IP].ttl))
-    return r
-            
-
-def prnp0f(pkt):
-    try:
-        r = p0f(pkt)
-    except:
-        return
-    if r == []:
-        r = ("UNKNOWN", "[" + ":".join(map(str, packet2p0f(pkt))) + ":?:?]", None)
-    else:
-        r = r[0]
-    uptime = None
-    try:
-        uptime = pkt2uptime(pkt)
-    except:
-        pass
-    if uptime == 0:
-        uptime = None
-    res = pkt.sprintf("%IP.src%:%TCP.sport% - " + r[0] + " " + r[1])
-    if uptime is not None:
-        res += pkt.sprintf(" (up: " + str(uptime/3600) + " hrs)\n  -> %IP.dst%:%TCP.dport%")
-    else:
-        res += pkt.sprintf("\n  -> %IP.dst%:%TCP.dport%")
-    if r[2] is not None:
-        res += " (distance " + str(r[2]) + ")"
-    print res
-
-
-def pkt2uptime(pkt, HZ=100):
-    """Calculate the date the machine which emitted the packet booted using TCP timestamp
-pkt2uptime(pkt, [HZ=100])"""
-    if not isinstance(pkt, Packet):
-        raise TypeError("Not a TCP packet")
-    if isinstance(pkt,NoPayload):
-        raise TypeError("Not a TCP packet")
-    if not isinstance(pkt, TCP):
-        return pkt2uptime(pkt.payload)
-    for opt in pkt.options:
-        if opt[0] == "Timestamp":
-            #t = pkt.time - opt[1][0] * 1.0/HZ
-            #return time.ctime(t)
-            t = opt[1][0] / HZ
-            return t
-    raise TypeError("No timestamp option")
-
-
-
-#################
-## Queso stuff ##
-#################
-
-
-def quesoTCPflags(flags):
-    if flags == "-":
-        return "-"
-    flv = "FSRPAUXY"
-    v = 0
-    for i in flags:
-        v |= 2**flv.index(i)
-    return "%x" % v
-
-class QuesoKnowledgeBase(KnowledgeBase):
-    def lazy_init(self):
-        try:
-            f = open(self.filename)
-        except IOError:
-            return
-        self.base = {}
-        p = None
-        try:
-            for l in f:
-                l = l.strip()
-                if not l or l[0] == ';':
-                    continue
-                if l[0] == '*':
-                    if p is not None:
-                        p[""] = name
-                    name = l[1:].strip()
-                    p = self.base
-                    continue
-                if l[0] not in list("0123456"):
-                    continue
-                res = l[2:].split()
-                res[-1] = quesoTCPflags(res[-1])
-                res = " ".join(res)
-                if not p.has_key(res):
-                    p[res] = {}
-                p = p[res]
-            if p is not None:
-                p[""] = name
-        except:
-            self.base = None
-            warning("Can't load queso base [%s]", self.filename)
-        f.close()
-            
-        
-
-    
-def queso_sig(target, dport=80, timeout=3):
-    p = queso_kdb.get_base()
-    ret = []
-    for flags in ["S", "SA", "F", "FA", "SF", "P", "SEC"]:
-        ans, unans = sr(IP(dst=target)/TCP(dport=dport,flags=flags,seq=RandInt()),
-                        timeout=timeout, verbose=0)
-        if len(ans) == 0:
-            rs = "- - - -"
-        else:
-            s,r = ans[0]
-            rs = "%i" % (r.seq != 0)
-            if not r.ack:
-                r += " 0"
-            elif r.ack-s.seq > 666:
-                rs += " R" % 0
-            else:
-                rs += " +%i" % (r.ack-s.seq)
-            rs += " %X" % r.window
-            rs += " %x" % r.payload.flags
-        ret.append(rs)
-    return ret
-            
-def queso_search(sig):
-    p = queso_kdb.get_base()
-    sig.reverse()
-    ret = []
-    try:
-        while sig:
-            s = sig.pop()
-            p = p[s]
-            if p.has_key(""):
-                ret.append(p[""])
-    except KeyError:
-        pass
-    return ret
-        
-
-def queso(*args,**kargs):
-    """Queso OS fingerprinting
-queso(target, dport=80, timeout=3)"""
-    return queso_search(queso_sig(*args, **kargs))
-
-
-
-######################
-## nmap OS fp stuff ##
-######################
-
-
-class NmapKnowledgeBase(KnowledgeBase):
-    def lazy_init(self):
-        try:
-            f=open(self.filename)
-        except IOError:
-            return
-
-        self.base = []
-        name = None
-        try:
-            for l in f:
-                l = l.strip()
-                if not l or l[0] == "#":
-                    continue
-                if l[:12] == "Fingerprint ":
-                    if name is not None:
-                        self.base.append((name,sig))
-                    name = l[12:].strip()
-                    sig={}
-                    p = self.base
-                    continue
-                elif l[:6] == "Class ":
-                    continue
-                op = l.find("(")
-                cl = l.find(")")
-                if op < 0 or cl < 0:
-                    warning("error reading nmap os fp base file")
-                    continue
-                test = l[:op]
-                s = map(lambda x: x.split("="), l[op+1:cl].split("%"))
-                si = {}
-                for n,v in s:
-                    si[n] = v
-                sig[test]=si
-            if name is not None:
-                self.base.append((name,sig))
-        except:
-            self.base = None
-            warning("Can't read nmap database [%s](new nmap version ?)" % self.filename)
-        f.close()
-        
-def TCPflags2str(f):
-    fl="FSRPAUEC"
-    s=""
-    for i in range(len(fl)):
-        if f & 1:
-            s = fl[i]+s
-        f >>= 1
-    return s
-
-def nmap_tcppacket_sig(pkt):
-    r = {}
-    if pkt is not None:
-#        r["Resp"] = "Y"
-        r["DF"] = (pkt.flags & 2) and "Y" or "N"
-        r["W"] = "%X" % pkt.window
-        r["ACK"] = pkt.ack==2 and "S++" or pkt.ack==1 and "S" or "O"
-        r["Flags"] = TCPflags2str(pkt.payload.flags)
-        r["Ops"] = "".join(map(lambda x: x[0][0],pkt.payload.options))
-    else:
-        r["Resp"] = "N"
-    return r
-
-
-def nmap_udppacket_sig(S,T):
-    r={}
-    if T is None:
-        r["Resp"] = "N"
-    else:
-        r["DF"] = (T.flags & 2) and "Y" or "N"
-        r["TOS"] = "%X" % T.tos
-        r["IPLEN"] = "%X" % T.len
-        r["RIPTL"] = "%X" % T.payload.payload.len
-        r["RID"] = S.id == T.payload.payload.id and "E" or "F"
-        r["RIPCK"] = S.chksum == T.getlayer(IPerror).chksum and "E" or T.getlayer(IPerror).chksum == 0 and "0" or "F"
-        r["UCK"] = S.payload.chksum == T.getlayer(UDPerror).chksum and "E" or T.getlayer(UDPerror).chksum ==0 and "0" or "F"
-        r["ULEN"] = "%X" % T.getlayer(UDPerror).len
-        r["DAT"] = T.getlayer(Raw) is None and "E" or S.getlayer(Raw).load == T.getlayer(Raw).load and "E" or "F"
-    return r
-    
-
-
-def nmap_match_one_sig(seen, ref):
-    c = 0
-    for k in seen.keys():
-        if ref.has_key(k):
-            if seen[k] in ref[k].split("|"):
-                c += 1
-    if c == 0 and seen.get("Resp") == "N":
-        return 0.7
-    else:
-        return 1.0*c/len(seen.keys())
-        
-        
-
-def nmap_sig(target, oport=80, cport=81, ucport=1):
-    res = {}
-
-    tcpopt = [ ("WScale", 10),
-               ("NOP",None),
-               ("MSS", 256),
-               ("Timestamp",(123,0)) ]
-    tests = [ IP(dst=target, id=1)/TCP(seq=1, sport=5001, dport=oport, options=tcpopt, flags="CS"),
-              IP(dst=target, id=1)/TCP(seq=1, sport=5002, dport=oport, options=tcpopt, flags=0),
-              IP(dst=target, id=1)/TCP(seq=1, sport=5003, dport=oport, options=tcpopt, flags="SFUP"),
-              IP(dst=target, id=1)/TCP(seq=1, sport=5004, dport=oport, options=tcpopt, flags="A"),
-              IP(dst=target, id=1)/TCP(seq=1, sport=5005, dport=cport, options=tcpopt, flags="S"),
-              IP(dst=target, id=1)/TCP(seq=1, sport=5006, dport=cport, options=tcpopt, flags="A"),
-              IP(dst=target, id=1)/TCP(seq=1, sport=5007, dport=cport, options=tcpopt, flags="FPU"),
-              IP(str(IP(dst=target)/UDP(sport=5008,dport=ucport)/(300*"i"))) ]
-
-    ans, unans = sr(tests, timeout=2)
-    ans += map(lambda x: (x,None), unans)
-
-    for S,T in ans:
-        if S.sport == 5008:
-            res["PU"] = nmap_udppacket_sig(S,T)
-        else:
-            t = "T%i" % (S.sport-5000)
-            if T is not None and T.haslayer(ICMP):
-                warning("Test %s answered by an ICMP" % t)
-                T=None
-            res[t] = nmap_tcppacket_sig(T)
-
-    return res
-
-def nmap_probes2sig(tests):
-    tests=tests.copy()
-    res = {}
-    if "PU" in tests:
-        res["PU"] = nmap_udppacket_sig(*tests["PU"])
-        del(tests["PU"])
-    for k in tests:
-        res[k] = nmap_tcppacket_sig(tests[k])
-    return res
-        
-
-def nmap_search(sigs):
-    guess = 0,[]
-    for os,fp in nmap_kdb.get_base():
-        c = 0.0
-        for t in sigs.keys():
-            if t in fp:
-                c += nmap_match_one_sig(sigs[t], fp[t])
-        c /= len(sigs.keys())
-        if c > guess[0]:
-            guess = c,[ os ]
-        elif c == guess[0]:
-            guess[1].append(os)
-    return guess
-    
-    
-def nmap_fp(target, oport=80, cport=81):
-    """nmap fingerprinting
-nmap_fp(target, [oport=80,] [cport=81,]) -> list of best guesses with accuracy
-"""
-    sigs = nmap_sig(target, oport, cport)
-    return nmap_search(sigs)
-        
-
-def nmap_sig2txt(sig):
-    torder = ["TSeq","T1","T2","T3","T4","T5","T6","T7","PU"]
-    korder = ["Class", "gcd", "SI", "IPID", "TS",
-              "Resp", "DF", "W", "ACK", "Flags", "Ops",
-              "TOS", "IPLEN", "RIPTL", "RID", "RIPCK", "UCK", "ULEN", "DAT" ]
-    txt=[]
-    for i in sig.keys():
-        if i not in torder:
-            torder.append(i)
-    for t in torder:
-        sl = sig.get(t)
-        if sl is None:
-            continue
-        s = []
-        for k in korder:
-            v = sl.get(k)
-            if v is None:
-                continue
-            s.append("%s=%s"%(k,v))
-        txt.append("%s(%s)" % (t, "%".join(s)))
-    return "\n".join(txt)
-            
-        
-
-
-
-###################
-## User commands ##
-###################
-
-
-def sniff(count=0, store=1, offline=None, prn = None, lfilter=None, L2socket=None, timeout=None, *arg, **karg):
-    """Sniff packets
-sniff([count=0,] [prn=None,] [store=1,] [offline=None,] [lfilter=None,] + L2ListenSocket args) -> list of packets
-
-  count: number of packets to capture. 0 means infinity
-  store: wether to store sniffed packets or discard them
-    prn: function to apply to each packet. If something is returned,
-         it is displayed. Ex:
-         ex: prn = lambda x: x.summary()
-lfilter: python function applied to each packet to determine
-         if further action may be done
-         ex: lfilter = lambda x: x.haslayer(Padding)
-offline: pcap file to read packets from, instead of sniffing them
-timeout: stop sniffing after a given time (default: None)
-L2socket: use the provided L2socket
-    """
-    c = 0
-
-    if offline is None:
-        if L2socket is None:
-            L2socket = conf.L2listen
-        s = L2socket(type=ETH_P_ALL, *arg, **karg)
-    else:
-        s = PcapReader(offline)
-
-    lst = []
-    if timeout is not None:
-        stoptime = time.time()+timeout
-    remain = None
-    while 1:
-        try:
-            if timeout is not None:
-                remain = stoptime-time.time()
-                if remain <= 0:
-                    break
-            sel = select([s],[],[],remain)
-            if s in sel[0]:
-                p = s.recv(MTU)
-                if p is None:
-                    break
-                if lfilter and not lfilter(p):
-                    continue
-                if store:
-                    lst.append(p)
-                c += 1
-                if prn:
-                    r = prn(p)
-                    if r is not None:
-                        print r
-                if count > 0 and c >= count:
-                    break
-        except KeyboardInterrupt:
-            break
-    s.close()
-    return PacketList(lst,"Sniffed")
-
-
-
-def arpcachepoison(target, victim, interval=60):
-    """Poison target's cache with (your MAC,victim's IP) couple
-arpcachepoison(target, victim, [interval=60]) -> None
-"""
-    tmac = getmacbyip(target)
-    p = Ether(dst=tmac)/ARP(op="who-has", psrc=victim, pdst=target)
-    try:
-        while 1:
-            sendp(p, iface_hint=target)
-            if conf.verb > 1:
-                os.write(1,".")
-            time.sleep(interval)
-    except KeyboardInterrupt:
-        pass
-
-def traceroute(target, dport=80, minttl=1, maxttl=30, sport=RandShort(), l4 = None, filter=None, timeout=2, verbose=None, **kargs):
-    """Instant TCP traceroute
-traceroute(target, [maxttl=30,] [dport=80,] [sport=80,] [verbose=conf.verb]) -> None
-"""
-    if verbose is None:
-        verbose = conf.verb
-    if filter is None:
-        # we only consider ICMP error packets and TCP packets with at
-        # least the ACK flag set *and* either the SYN or the RST flag
-        # set
-        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))"
-    if l4 is None:
-        a,b = sr(IP(dst=target, id=RandShort(), ttl=(minttl,maxttl))/TCP(seq=RandInt(),sport=sport, dport=dport),
-                 timeout=timeout, filter=filter, verbose=verbose, **kargs)
-    else:
-        # this should always work
-        filter="ip"
-        a,b = sr(IP(dst=target, id=RandShort(), ttl=(minttl,maxttl))/l4,
-                 timeout=timeout, filter=filter, verbose=verbose, **kargs)
-
-    a = TracerouteResult(a.res)
-    if verbose:
-        a.show()
-    return a,b
-
-
-
-
-def arping(net, timeout=2, cache=0, verbose=None, **kargs):
-    """Send ARP who-has requests to determine which hosts are up
-arping(net, [cache=0,] [iface=conf.iface,] [verbose=conf.verb]) -> None
-Set cache=True if you want arping to modify internal ARP-Cache"""
-    if verbose is None:
-        verbose = conf.verb
-    ans,unans = srp(Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(pdst=net), verbose=verbose,
-                    filter="arp and arp[7] = 2", timeout=timeout, iface_hint=net, **kargs)
-    ans = ARPingResult(ans.res)
-
-    if cache and ans is not None:
-        for pair in ans:
-            arp_cache[pair[1].psrc] = (pair[1].hwsrc, time.time())
-    if verbose:
-        ans.show()
-    return ans,unans
-
-def dyndns_add(nameserver, name, rdata, type="A", ttl=10):
-    """Send a DNS add message to a nameserver for "name" to have a new "rdata"
-dyndns_add(nameserver, name, rdata, type="A", ttl=10) -> result code (0=ok)
-
-example: dyndns_add("ns1.toto.com", "dyn.toto.com", "127.0.0.1")
-RFC2136
-"""
-    zone = name[name.find(".")+1:]
-    r=sr1(IP(dst=nameserver)/UDP()/DNS(opcode=5,
-                                       qd=[DNSQR(qname=zone, qtype="SOA")],
-                                       ns=[DNSRR(rrname=name, type="A",
-                                                 ttl=ttl, rdata=rdata)]),
-          verbose=0, timeout=5)
-    if r and r.haslayer(DNS):
-        return r.getlayer(DNS).rcode
-    else:
-        return -1
-    
-    
-    
-
-def dyndns_del(nameserver, name, type="ALL", ttl=10):
-    """Send a DNS delete message to a nameserver for "name"
-dyndns_del(nameserver, name, type="ANY", ttl=10) -> result code (0=ok)
-
-example: dyndns_del("ns1.toto.com", "dyn.toto.com")
-RFC2136
-"""
-    zone = name[name.find(".")+1:]
-    r=sr1(IP(dst=nameserver)/UDP()/DNS(opcode=5,
-                                       qd=[DNSQR(qname=zone, qtype="SOA")],
-                                       ns=[DNSRR(rrname=name, type=type,
-                                                 rclass="ANY", ttl=0, rdata="")]),
-          verbose=0, timeout=5)
-    if r and r.haslayer(DNS):
-        return r.getlayer(DNS).rcode
-    else:
-        return -1
-    
-
-def is_promisc(ip, fake_bcast="ff:ff:00:00:00:00",**kargs):
-    """Try to guess if target is in Promisc mode. The target is provided by its ip."""
-
-    responses = srp1(Ether(dst=fake_bcast) / ARP(op="who-has", pdst=ip),type=ETH_P_ARP, iface_hint=ip, timeout=1, verbose=0,**kargs)
-
-    return responses is not None
-
-def promiscping(net, timeout=2, fake_bcast="ff:ff:ff:ff:ff:fe", **kargs):
-    """Send ARP who-has requests to determine which hosts are in promiscuous mode
-    promiscping(net, iface=conf.iface)"""
-    ans,unans = srp(Ether(dst=fake_bcast)/ARP(pdst=net),
-                    filter="arp and arp[7] = 2", timeout=timeout, iface_hint=net, **kargs)
-    ans = ARPingResult(ans.res, name="PROMISCPing")
-
-    ans.display()
-    return ans,unans
-
-def ikescan(ip):
-    return sr(IP(dst=ip)/UDP()/ISAKMP(init_cookie=RandString(8),
-                                      exch_type=2)/ISAKMP_payload_SA(prop=ISAKMP_payload_Proposal()))
-
-
-def dhcp_request(iface=None,**kargs):
-    if conf.checkIPaddr != 0:
-        warning("conf.checkIPaddr is not 0, I may not be able to match the answer")
-    if iface is None:
-        iface = conf.iface
-    fam,hw = get_if_raw_hwaddr(iface)
-    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)
-                 /BOOTP(chaddr=hw)/DHCP(options=[("message-type","discover"),"end"]),iface=iface,**kargs)
-
-def snmpwalk(dst, oid="1", community="public"):
-    try:
-        while 1:
-            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)
-            if ICMP in r:
-                print repr(r)
-                break
-            if r is None:
-                print "No answers"
-                break
-            print "%-40s: %r" % (r[SNMPvarbind].oid.val,r[SNMPvarbind].value)
-            oid = r[SNMPvarbind].oid
-            
-    except KeyboardInterrupt:
-        pass
-
-
-#####################
-## Reporting stuff ##
-#####################
-
-def report_ports(target, ports):
-    """portscan a target and output a LaTeX table
-report_ports(target, ports) -> string"""
-    ans,unans = sr(IP(dst=target)/TCP(dport=ports),timeout=5)
-    rep = "\\begin{tabular}{|r|l|l|}\n\\hline\n"
-    for s,r in ans:
-        if not r.haslayer(ICMP):
-            if r.payload.flags == 0x12:
-                rep += r.sprintf("%TCP.sport% & open & SA \\\\\n")
-    rep += "\\hline\n"
-    for s,r in ans:
-        if r.haslayer(ICMP):
-            rep += r.sprintf("%TCPerror.dport% & closed & ICMP type %ICMP.type%/%ICMP.code% from %IP.src% \\\\\n")
-        elif r.payload.flags != 0x12:
-            rep += r.sprintf("%TCP.sport% & closed & TCP %TCP.flags% \\\\\n")
-    rep += "\\hline\n"
-    for i in unans:
-        rep += i.sprintf("%TCP.dport% & ? & unanswered \\\\\n")
-    rep += "\\hline\n\\end{tabular}\n"
-    return rep
-
-
-def __make_table(yfmtfunc, fmtfunc, endline, list, fxyz, sortx=None, sorty=None, seplinefunc=None):
-    vx = {} 
-    vy = {} 
-    vz = {}
-    vxf = {}
-    vyf = {}
-    l = 0
-    for e in list:
-        xx,yy,zz = map(str, fxyz(e))
-        l = max(len(yy),l)
-        vx[xx] = max(vx.get(xx,0), len(xx), len(zz))
-        vy[yy] = None
-        vz[(xx,yy)] = zz
-
-    vxk = vx.keys()
-    vyk = vy.keys()
-    if sortx:
-        vxk.sort(sortx)
-    else:
-        try:
-            vxk.sort(lambda x,y:int(x)-int(y))
-        except:
-            try:
-                vxk.sort(lambda x,y: cmp(atol(x),atol(y)))
-            except:
-                vxk.sort()
-    if sorty:
-        vyk.sort(sorty)
-    else:
-        try:
-            vyk.sort(lambda x,y:int(x)-int(y))
-        except:
-            try:
-                vyk.sort(lambda x,y: cmp(atol(x),atol(y)))
-            except:
-                vyk.sort()
-
-
-    if seplinefunc:
-        sepline = seplinefunc(l, map(lambda x:vx[x],vxk))
-        print sepline
-
-    fmt = yfmtfunc(l)
-    print fmt % "",
-    for x in vxk:
-        vxf[x] = fmtfunc(vx[x])
-        print vxf[x] % x,
-    print endline
-    if seplinefunc:
-        print sepline
-    for y in vyk:
-        print fmt % y,
-        for x in vxk:
-            print vxf[x] % vz.get((x,y), "-"),
-        print endline
-    if seplinefunc:
-        print sepline
-
-def make_table(*args, **kargs):
-    __make_table(lambda l:"%%-%is" % l, lambda l:"%%-%is" % l, "", *args, **kargs)
-    
-def make_lined_table(*args, **kargs):
-    __make_table(lambda l:"%%-%is |" % l, lambda l:"%%-%is |" % l, "",
-                 seplinefunc=lambda a,x:"+".join(map(lambda y:"-"*(y+2), [a-1]+x+[-2])),
-                 *args, **kargs)
-
-def make_tex_table(*args, **kargs):
-    __make_table(lambda l: "%s", lambda l: "& %s", "\\\\", seplinefunc=lambda a,x:"\\hline", *args, **kargs)
-    
-
-######################
-## Online doc stuff ##
-######################
-
-
-def lsc(cmd=None):
-    """List user commands"""
-    if cmd is None:
-        for c in user_commands:
-            doc = "No doc. available"
-            if c.__doc__:
-                doc = c.__doc__.split("\n")[0]
-            
-            print "%-16s : %s" % (c.__name__, doc)
-    else:
-        print cmd.__doc__
-
-def ls(obj=None):
-    """List  available layers, or infos on a given layer"""
-    if obj is None:
-        import __builtin__
-        all = __builtin__.__dict__.copy()
-        all.update(globals())
-        objlst = filter(lambda (n,o): isinstance(o,type) and issubclass(o,Packet), all.items())
-        objlst.sort(lambda x,y:cmp(x[0],y[0]))
-        for n,o in objlst:
-            print "%-10s : %s" %(n,o.name)
-    else:
-        if isinstance(obj, type) and issubclass(obj, Packet):
-            for f in obj.fields_desc:
-                print "%-10s : %-20s = (%s)" % (f.name, f.__class__.__name__,  repr(f.default))
-        elif isinstance(obj, Packet):
-            for f in obj.fields_desc:
-                print "%-10s : %-20s = %-15s (%s)" % (f.name, f.__class__.__name__, repr(getattr(obj,f.name)), repr(f.default))
-            if not isinstance(obj.payload, NoPayload):
-                print "--"
-                ls(obj.payload)
-                
-
-        else:
-            print "Not a packet class. Type 'ls()' to list packet classes."
-
-
-    
-
-
-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 ]
-
-
-##############
-## Automata ##
-##############
-
-class ATMT:
-    STATE = "State"
-    ACTION = "Action"
-    CONDITION = "Condition"
-    RECV = "Receive condition"
-    TIMEOUT = "Timeout condition"
-
-    class NewStateRequested(Exception):
-        def __init__(self, state_func, automaton, *args, **kargs):
-            self.func = state_func
-            self.state = state_func.atmt_state
-            self.initial = state_func.atmt_initial
-            self.error = state_func.atmt_error
-            self.final = state_func.atmt_final
-            Exception.__init__(self, "Request state [%s]" % self.state)
-            self.automaton = automaton
-            self.args = args
-            self.kargs = kargs
-            self.action_parameters() # init action parameters
-        def action_parameters(self, *args, **kargs):
-            self.action_args = args
-            self.action_kargs = kargs
-            return self
-        def run(self):
-            return self.func(self.automaton, *self.args, **self.kargs)
-
-    @staticmethod
-    def state(initial=0,final=0,error=0):
-        def deco(f,initial=initial, final=final):
-            f.atmt_type = ATMT.STATE
-            f.atmt_state = f.func_name
-            f.atmt_initial = initial
-            f.atmt_final = final
-            f.atmt_error = error
-            def state_wrapper(self, *args, **kargs):
-                return ATMT.NewStateRequested(f, self, *args, **kargs)
-
-            state_wrapper.func_name = "%s_wrapper" % f.func_name
-            state_wrapper.atmt_type = ATMT.STATE
-            state_wrapper.atmt_state = f.func_name
-            state_wrapper.atmt_initial = initial
-            state_wrapper.atmt_final = final
-            state_wrapper.atmt_error = error
-            state_wrapper.atmt_origfunc = f
-            return state_wrapper
-        return deco
-    @staticmethod
-    def action(cond, prio=0):
-        def deco(f,cond=cond):
-            if not hasattr(f,"atmt_type"):
-                f.atmt_cond = {}
-            f.atmt_type = ATMT.ACTION
-            f.atmt_cond[cond.atmt_condname] = prio
-            return f
-        return deco
-    @staticmethod
-    def condition(state, prio=0):
-        def deco(f, state=state):
-            f.atmt_type = ATMT.CONDITION
-            f.atmt_state = state.atmt_state
-            f.atmt_condname = f.func_name
-            f.atmt_prio = prio
-            return f
-        return deco
-    @staticmethod
-    def receive_condition(state, prio=0):
-        def deco(f, state=state):
-            f.atmt_type = ATMT.RECV
-            f.atmt_state = state.atmt_state
-            f.atmt_condname = f.func_name
-            f.atmt_prio = prio
-            return f
-        return deco
-    @staticmethod
-    def timeout(state, timeout):
-        def deco(f, state=state, timeout=timeout):
-            f.atmt_type = ATMT.TIMEOUT
-            f.atmt_state = state.atmt_state
-            f.atmt_timeout = timeout
-            f.atmt_condname = f.func_name
-            return f
-        return deco
-
-
-class Automaton_metaclass(type):
-    def __new__(cls, name, bases, dct):
-        cls = super(Automaton_metaclass, cls).__new__(cls, name, bases, dct)
-        cls.states={}
-        cls.state = None
-        cls.recv_conditions={}
-        cls.conditions={}
-        cls.timeout={}
-        cls.actions={}
-        cls.initial_states=[]
-
-        members = {}
-        classes = [cls]
-        while classes:
-            c = classes.pop(0) # order is important to avoid breaking method overloading
-            classes += list(c.__bases__)
-            for k,v in c.__dict__.iteritems():
-                if k not in members:
-                    members[k] = v
-
-        decorated = [v for v in members.itervalues()
-                     if type(v) is types.FunctionType and hasattr(v, "atmt_type")]
-        
-        for m in decorated:
-            if m.atmt_type == ATMT.STATE:
-                s = m.atmt_state
-                cls.states[s] = m
-                cls.recv_conditions[s]=[]
-                cls.conditions[s]=[]
-                cls.timeout[s]=[]
-                if m.atmt_initial:
-                    cls.initial_states.append(m)
-            elif m.atmt_type in [ATMT.CONDITION, ATMT.RECV, ATMT.TIMEOUT]:
-                cls.actions[m.atmt_condname] = []
-    
-        for m in decorated:
-            if m.atmt_type == ATMT.CONDITION:
-                cls.conditions[m.atmt_state].append(m)
-            elif m.atmt_type == ATMT.RECV:
-                cls.recv_conditions[m.atmt_state].append(m)
-            elif m.atmt_type == ATMT.TIMEOUT:
-                cls.timeout[m.atmt_state].append((m.atmt_timeout, m))
-            elif m.atmt_type == ATMT.ACTION:
-                for c in m.atmt_cond:
-                    cls.actions[c].append(m)
-            
-
-        for v in cls.timeout.itervalues():
-            v.sort(lambda (t1,f1),(t2,f2): cmp(t1,t2))
-            v.append((None, None))
-        for v in itertools.chain(cls.conditions.itervalues(),
-                                 cls.recv_conditions.itervalues()):
-            v.sort(lambda c1,c2: cmp(c1.atmt_prio,c2.atmt_prio))
-        for condname,actlst in cls.actions.iteritems():
-            actlst.sort(lambda c1,c2: cmp(c1.atmt_cond[condname], c2.atmt_cond[condname]))
-
-        return cls
-
-        
-    def graph(self, **kargs):
-        s = 'digraph "%s" {\n'  % self.__class__.__name__
-        
-        se = "" # Keep initial nodes at the begining for better rendering
-        for st in self.states.itervalues():
-            if st.atmt_initial:
-                se = ('\t"%s" [ style=filled, fillcolor=blue, shape=box, root=true];\n' % st.atmt_state)+se
-            elif st.atmt_final:
-                se += '\t"%s" [ style=filled, fillcolor=green, shape=octagon ];\n' % st.atmt_state
-            elif st.atmt_error:
-                se += '\t"%s" [ style=filled, fillcolor=red, shape=octagon ];\n' % st.atmt_state
-        s += se
-
-        for st in self.states.values():
-            for n in st.atmt_origfunc.func_code.co_names+st.atmt_origfunc.func_code.co_consts:
-                if n in self.states:
-                    s += '\t"%s" -> "%s" [ color=green ];\n' % (st.atmt_state,n)
-            
-
-        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()]:
-            for f in v:
-                for n in f.func_code.co_names+f.func_code.co_consts:
-                    if n in self.states:
-                        l = f.atmt_condname
-                        for x in self.actions[f.atmt_condname]:
-                            l += "\\l>[%s]" % x.func_name
-                        s += '\t"%s" -> "%s" [label="%s", color=%s];\n' % (k,n,l,c)
-        for k,v in self.timeout.iteritems():
-            for t,f in v:
-                if f is None:
-                    continue
-                for n in f.func_code.co_names+f.func_code.co_consts:
-                    if n in self.states:
-                        l = "%s/%.1fs" % (f.atmt_condname,t)                        
-                        for x in self.actions[f.atmt_condname]:
-                            l += "\\l>[%s]" % x.func_name
-                        s += '\t"%s" -> "%s" [label="%s",color=blue];\n' % (k,n,l)
-        s += "}\n"
-        return do_graph(s, **kargs)
-        
-
-
-class Automaton:
-    __metaclass__ = Automaton_metaclass
-
-    def __init__(self, *args, **kargs):
-        self.debug_level=0
-        self.init_args=args
-        self.init_kargs=kargs
-        self.parse_args(*args, **kargs)
-
-    def debug(self, lvl, msg):
-        if self.debug_level >= lvl:
-            log_interactive.debug(msg)
-            
-
-
-
-    class ErrorState(Exception):
-        def __init__(self, msg, result=None):
-            Exception.__init__(self, msg)
-            self.result = result
-    class Stuck(ErrorState):
-        pass
-
-    def parse_args(self, debug=0, store=1, **kargs):
-        self.debug_level=debug
-        self.socket_kargs = kargs
-        self.store_packets = store
-        
-
-    def master_filter(self, pkt):
-        return True
-
-    def run_condition(self, cond, *args, **kargs):
-        try:
-            cond(self,*args, **kargs)
-        except ATMT.NewStateRequested, state_req:
-            self.debug(2, "%s [%s] taken to state [%s]" % (cond.atmt_type, cond.atmt_condname, state_req.state))
-            if cond.atmt_type == ATMT.RECV:
-                self.packets.append(args[0])
-            for action in self.actions[cond.atmt_condname]:
-                self.debug(2, "   + Running action [%s]" % action.func_name)
-                action(self, *state_req.action_args, **state_req.action_kargs)
-            raise
-        else:
-            self.debug(2, "%s [%s] not taken" % (cond.atmt_type, cond.atmt_condname))
-            
-
-    def run(self, *args, **kargs):
-        # Update default parameters
-        a = args+self.init_args[len(args):]
-        k = self.init_kargs
-        k.update(kargs)
-        self.parse_args(*a,**k)
-
-        # Start the automaton
-        self.state=self.initial_states[0](self)
-        self.send_sock = conf.L3socket()
-        l = conf.L2listen(**self.socket_kargs)
-        self.packets = PacketList(name="session[%s]"%self.__class__.__name__)
-        while 1:
-            try:
-                self.debug(1, "## state=[%s]" % self.state.state)
-
-                # Entering a new state. First, call new state function
-                state_output = self.state.run()
-                if self.state.error:
-                    raise self.ErrorState("Reached %s: [%r]" % (self.state.state, state_output), result=state_output)
-                if self.state.final:
-                    return state_output
-
-                if state_output is None:
-                    state_output = ()
-                elif type(state_output) is not list:
-                    state_output = state_output,
-                
-                # Then check immediate conditions
-                for cond in self.conditions[self.state.state]:
-                    self.run_condition(cond, *state_output)
-
-                # If still there and no conditions left, we are stuck!
-                if ( len(self.recv_conditions[self.state.state]) == 0
-                     and len(self.timeout[self.state.state]) == 1 ):
-                    raise self.Stuck("stuck in [%s]" % self.state.state,result=state_output)
-
-                # Finally listen and pay attention to timeouts
-                expirations = iter(self.timeout[self.state.state])
-                next_timeout,timeout_func = expirations.next()
-                t0 = time.time()
-                
-                while 1:
-                    t = time.time()-t0
-                    if next_timeout is not None:
-                        if next_timeout <= t:
-                            self.run_condition(timeout_func, *state_output)
-                            next_timeout,timeout_func = expirations.next()
-                    if next_timeout is None:
-                        remain = None
-                    else:
-                        remain = next_timeout-t
-    
-                    r,_,_ = select([l],[],[],remain)
-                    if l in r:
-                        pkt = l.recv(MTU)
-                        if pkt is not None:
-                            if self.master_filter(pkt):
-                                self.debug(3, "RECVD: %s" % pkt.summary())
-                                for rcvcond in self.recv_conditions[self.state.state]:
-                                    self.run_condition(rcvcond, pkt, *state_output)
-                            else:
-                                self.debug(4, "FILTR: %s" % pkt.summary())
-
-            except ATMT.NewStateRequested,state_req:
-                self.debug(2, "switching from [%s] to [%s]" % (self.state.state,state_req.state))
-                self.state = state_req
-            except KeyboardInterrupt:
-                self.debug(1,"Interrupted by user")
-                break
-
-    def my_send(self, pkt):
-        self.send_sock.send(pkt)
-
-    def send(self, pkt):
-        self.my_send(pkt)
-        self.debug(3,"SENT : %s" % pkt.summary())
-        self.packets.append(pkt.copy())
-
-
-        
-
-    
-
-class TFTP_read(Automaton):
-    def parse_args(self, filename, server, sport = None, port=69, **kargs):
-        Automaton.parse_args(self, **kargs)
-        self.filename = filename
-        self.server = server
-        self.port = port
-        self.sport = sport
-
-
-    def master_filter(self, pkt):
-        return ( IP in pkt and pkt[IP].src == self.server and UDP in pkt
-                 and pkt[UDP].dport == self.my_tid
-                 and (self.server_tid is None or pkt[UDP].sport == self.server_tid) )
-        
-    # BEGIN
-    @ATMT.state(initial=1)
-    def BEGIN(self):
-        self.blocksize=512
-        self.my_tid = self.sport or RandShort()._fix()
-        bind_bottom_up(UDP, TFTP, dport=self.my_tid)
-        self.server_tid = None
-        self.res = ""
-
-        self.l3 = IP(dst=self.server)/UDP(sport=self.my_tid, dport=self.port)/TFTP()
-        self.last_packet = self.l3/TFTP_RRQ(filename=self.filename, mode="octet")
-        self.send(self.last_packet)
-        self.awaiting=1
-        
-        raise self.WAITING()
-        
-    # WAITING
-    @ATMT.state()
-    def WAITING(self):
-        pass
-
-
-    @ATMT.receive_condition(WAITING)
-    def receive_data(self, pkt):
-        if TFTP_DATA in pkt and pkt[TFTP_DATA].block == self.awaiting:
-            if self.server_tid is None:
-                self.server_tid = pkt[UDP].sport
-                self.l3[UDP].dport = self.server_tid
-            raise self.RECEIVING(pkt)
-
-    @ATMT.receive_condition(WAITING, prio=1)
-    def receive_error(self, pkt):
-        if TFTP_ERROR in pkt:
-            raise self.ERROR(pkt)
-    
-        
-    @ATMT.timeout(WAITING, 3)
-    def timeout_waiting(self):
-        raise self.WAITING()
-    @ATMT.action(timeout_waiting)
-    def retransmit_last_packet(self):
-        self.send(self.last_packet)
-
-    @ATMT.action(receive_data)
-#    @ATMT.action(receive_error)
-    def send_ack(self):
-        self.last_packet = self.l3 / TFTP_ACK(block = self.awaiting)
-        self.send(self.last_packet)
-    
-
-    # RECEIVED
-    @ATMT.state()
-    def RECEIVING(self, pkt):
-        if Raw in pkt:
-            recvd = pkt[Raw].load
-        else:
-            recvd = ""
-        self.res += recvd
-        self.awaiting += 1
-        if len(recvd) == self.blocksize:
-            raise self.WAITING()
-        raise self.END()
-
-    # ERROR
-    @ATMT.state(error=1)
-    def ERROR(self,pkt):
-        split_bottom_up(UDP, TFTP, dport=self.my_tid)
-        return pkt[TFTP_ERROR].summary()
-    
-    #END
-    @ATMT.state(final=1)
-    def END(self):
-        split_bottom_up(UDP, TFTP, dport=self.my_tid)
-        return self.res
-
-
-
-
-class TFTP_write(Automaton):
-    def parse_args(self, filename, data, server, sport=None, port=69,**kargs):
-        Automaton.parse_args(self, **kargs)
-        self.filename = filename
-        self.server = server
-        self.port = port
-        self.sport = sport
-        self.blocksize = 512
-        self.origdata = data
-
-    def master_filter(self, pkt):
-        return ( IP in pkt and pkt[IP].src == self.server and UDP in pkt
-                 and pkt[UDP].dport == self.my_tid
-                 and (self.server_tid is None or pkt[UDP].sport == self.server_tid) )
-        
-
-    # BEGIN
-    @ATMT.state(initial=1)
-    def BEGIN(self):
-        self.data = [ self.origdata[i*self.blocksize:(i+1)*self.blocksize]
-                      for i in range( len(self.origdata)/self.blocksize+1) ] 
-        self.my_tid = self.sport or RandShort()._fix()
-        bind_bottom_up(UDP, TFTP, dport=self.my_tid)
-        self.server_tid = None
-        
-        self.l3 = IP(dst=self.server)/UDP(sport=self.my_tid, dport=self.port)/TFTP()
-        self.last_packet = self.l3/TFTP_WRQ(filename=self.filename, mode="octet")
-        self.send(self.last_packet)
-        self.res = ""
-        self.awaiting=0
-
-        raise self.WAITING_ACK()
-        
-    # WAITING_ACK
-    @ATMT.state()
-    def WAITING_ACK(self):
-        pass
-
-    @ATMT.receive_condition(WAITING_ACK)    
-    def received_ack(self,pkt):
-        if TFTP_ACK in pkt and pkt[TFTP_ACK].block == self.awaiting:
-            if self.server_tid is None:
-                self.server_tid = pkt[UDP].sport
-                self.l3[UDP].dport = self.server_tid
-            raise self.SEND_DATA()
-
-    @ATMT.receive_condition(WAITING_ACK)
-    def received_error(self, pkt):
-        if TFTP_ERROR in pkt:
-            raise self.ERROR(pkt)
-
-    @ATMT.timeout(WAITING_ACK, 3)
-    def timeout_waiting(self):
-        raise self.WAITING_ACK()
-    @ATMT.action(timeout_waiting)
-    def retransmit_last_packet(self):
-        self.send(self.last_packet)
-    
-    # SEND_DATA
-    @ATMT.state()
-    def SEND_DATA(self):
-        self.awaiting += 1
-        self.last_packet = self.l3/TFTP_DATA(block=self.awaiting)/self.data.pop(0)
-        self.send(self.last_packet)
-        if self.data:
-            raise self.WAITING_ACK()
-        raise self.END()
-    
-
-    # ERROR
-    @ATMT.state(error=1)
-    def ERROR(self,pkt):
-        split_bottom_up(UDP, TFTP, dport=self.my_tid)
-        return pkt[TFTP_ERROR].summary()
-
-    # END
-    @ATMT.state(final=1)
-    def END(self):
-        split_bottom_up(UDP, TFTP, dport=self.my_tid)
-
-
-class TFTP_WRQ_server(Automaton):
-
-    def parse_args(self, ip=None, sport=None, *args, **kargs):
-        Automaton.parse_args(self, *args, **kargs)
-        self.ip = ip
-        self.sport = sport
-
-    def master_filter(self, pkt):
-        return TFTP in pkt and (not self.ip or pkt[IP].dst == self.ip)
-
-    @ATMT.state(initial=1)
-    def BEGIN(self):
-        self.blksize=512
-        self.blk=1
-        self.filedata=""
-        self.my_tid = self.sport or random.randint(10000,65500)
-        bind_bottom_up(UDP, TFTP, dport=self.my_tid)
-
-    @ATMT.receive_condition(BEGIN)
-    def receive_WRQ(self,pkt):
-        if TFTP_WRQ in pkt:
-            raise self.WAIT_DATA().action_parameters(pkt)
-        
-    @ATMT.action(receive_WRQ)
-    def ack_WRQ(self, pkt):
-        ip = pkt[IP]
-        self.ip = ip.dst
-        self.dst = ip.src
-        self.filename = pkt[TFTP_WRQ].filename
-        options = pkt[TFTP_Options]
-        self.l3 = IP(src=ip.dst, dst=ip.src)/UDP(sport=self.my_tid, dport=pkt.sport)/TFTP()
-        if options is None:
-            self.last_packet = self.l3/TFTP_ACK(block=0)
-            self.send(self.last_packet)
-        else:
-            opt = [x for x in options.options if x.oname.upper() == "BLKSIZE"]
-            if opt:
-                self.blksize = int(opt[0].value)
-                self.debug(2,"Negotiated new blksize at %i" % self.blksize)
-            self.last_packet = self.l3/TFTP_OACK()/TFTP_Options(options=opt)
-            self.send(self.last_packet)
-
-    @ATMT.state()
-    def WAIT_DATA(self):
-        pass
-
-    @ATMT.timeout(WAIT_DATA, 1)
-    def resend_ack(self):
-        self.send(self.last_packet)
-        raise self.WAIT_DATA()
-        
-    @ATMT.receive_condition(WAIT_DATA)
-    def receive_data(self, pkt):
-        if TFTP_DATA in pkt:
-            data = pkt[TFTP_DATA]
-            if data.block == self.blk:
-                raise self.DATA(data)
-
-    @ATMT.action(receive_data)
-    def ack_data(self):
-        self.last_packet = self.l3/TFTP_ACK(block = self.blk)
-        self.send(self.last_packet)
-
-    @ATMT.state()
-    def DATA(self, data):
-        self.filedata += data.load
-        if len(data.load) < self.blksize:
-            raise self.END()
-        self.blk += 1
-        raise self.WAIT_DATA()
-
-    @ATMT.state(final=1)
-    def END(self):
-        return self.filename,self.filedata
-        split_bottom_up(UDP, TFTP, dport=self.my_tid)
-        
-
-class TFTP_RRQ_server(Automaton):
-    def parse_args(self, store=None, joker=None, dir=None, ip=None, sport=None, serve_one=False, **kargs):
-        Automaton.parse_args(self,**kargs)
-        if store is None:
-            store = {}
-        if dir is not None:
-            self.dir = os.path.join(os.path.abspath(dir),"")
-        else:
-            self.dir = None
-        self.store = store
-        self.joker = joker
-        self.ip = ip
-        self.sport = sport
-        self.serve_one = serve_one
-        self.my_tid = self.sport or random.randint(10000,65500)
-        bind_bottom_up(UDP, TFTP, dport=self.my_tid)
-        
-    def master_filter(self, pkt):
-        return TFTP in pkt and (not self.ip or pkt[IP].dst == self.ip)
-
-    @ATMT.state(initial=1)
-    def WAIT_RRQ(self):
-        self.blksize=512
-        self.blk=0
-
-    @ATMT.receive_condition(WAIT_RRQ)
-    def receive_rrq(self, pkt):
-        if TFTP_RRQ in pkt:
-            raise self.RECEIVED_RRQ(pkt)
-
-
-    @ATMT.state()
-    def RECEIVED_RRQ(self, pkt):
-        ip = pkt[IP]
-        options = pkt[TFTP_Options]
-        self.l3 = IP(src=ip.dst, dst=ip.src)/UDP(sport=self.my_tid, dport=ip.sport)/TFTP()
-        self.filename = pkt[TFTP_RRQ].filename
-        self.blk=1
-        self.data = None
-        if self.filename in self.store:
-            self.data = self.store[self.filename]
-        elif self.dir is not None:
-            fn = os.path.abspath(os.path.join(self.dir, self.filename))
-            if fn.startswith(self.dir): # Check we're still in the server's directory
-                try:
-                    self.data=open(fn).read()
-                except IOError:
-                    pass
-        if self.data is None:
-            self.data = self.joker
-
-        if options:
-            opt = [x for x in options.options if x.oname.upper() == "BLKSIZE"]
-            if opt:
-                self.blksize = int(opt[0].value)
-                self.debug(2,"Negotiated new blksize at %i" % self.blksize)
-            self.last_packet = self.l3/TFTP_OACK()/TFTP_Options(options=opt)
-            self.send(self.last_packet)
-                
-
-            
-
-    @ATMT.condition(RECEIVED_RRQ)
-    def file_in_store(self):
-        if self.data is not None:
-            self.blknb = len(self.data)/self.blksize+1
-            raise self.SEND_FILE()
-
-    @ATMT.condition(RECEIVED_RRQ)
-    def file_not_found(self):
-        if self.data is None:
-            raise self.WAIT_RRQ()
-    @ATMT.action(file_not_found)
-    def send_error(self):
-        self.send(self.l3/TFTP_ERROR(errorcode=1, errormsg=TFTP_Error_Codes[1]))
-
-    @ATMT.state()
-    def SEND_FILE(self):
-        self.send(self.l3/TFTP_DATA(block=self.blk)/self.data[(self.blk-1)*self.blksize:self.blk*self.blksize])
-        
-    @ATMT.timeout(SEND_FILE, 3)
-    def timeout_waiting_ack(self):
-        raise self.SEND_FILE()
-            
-    @ATMT.receive_condition(SEND_FILE)
-    def received_ack(self, pkt):
-        if TFTP_ACK in pkt and pkt[TFTP_ACK].block == self.blk:
-            raise self.RECEIVED_ACK()
-    @ATMT.state()
-    def RECEIVED_ACK(self):
-        self.blk += 1
-
-    @ATMT.condition(RECEIVED_ACK)
-    def no_more_data(self):
-        if self.blk > self.blknb:
-            if self.serve_one:
-                raise self.END()
-            raise self.WAIT_RRQ()
-    @ATMT.condition(RECEIVED_ACK, prio=2)
-    def data_remaining(self):
-        raise self.SEND_FILE()
-
-    @ATMT.state(final=1)
-    def END(self):
-        split_bottom_up(UDP, TFTP, dport=self.my_tid)
-    
-
-        
-
-########################
-## Answering machines ##
-########################
-
-class ReferenceAM(type):
-    def __new__(cls, name, bases, dct):
-        o = super(ReferenceAM, cls).__new__(cls, name, bases, dct)
-        if o.function_name:
-            globals()[o.function_name] = lambda o=o,*args,**kargs: o(*args,**kargs)()
-        return o
-
-
-class AnsweringMachine(object):
-    __metaclass__ = ReferenceAM
-    function_name = ""
-    filter = None
-    sniff_options = { "store":0 }
-    sniff_options_list = [ "store", "iface", "count", "promisc", "filter", "type", "prn" ]
-    send_options = { "verbose":0 }
-    send_options_list = ["iface", "inter", "loop", "verbose"]
-    send_function = staticmethod(send)
-    
-    
-    def __init__(self, **kargs):
-        self.mode = 0
-        if self.filter:
-            kargs.setdefault("filter",self.filter)
-        kargs.setdefault("prn", self.reply)
-        self.optam1 = {}
-        self.optam2 = {}
-        self.optam0 = {}
-        doptsend,doptsniff = self.parse_all_options(1, kargs)
-        self.defoptsend = self.send_options.copy()
-        self.defoptsend.update(doptsend)
-        self.defoptsniff = self.sniff_options.copy()
-        self.defoptsniff.update(doptsniff)
-        self.optsend,self.optsniff = [{},{}]
-
-    def __getattr__(self, attr):
-        for d in [self.optam2, self.optam1]:
-            if attr in d:
-                return d[attr]
-        raise AttributeError,attr
-                
-    def __setattr__(self, attr, val):
-        mode = self.__dict__.get("mode",0)
-        if mode == 0:
-            self.__dict__[attr] = val
-        else:
-            [self.optam1, self.optam2][mode-1][attr] = val
-
-    def parse_options(self):
-        pass
-
-    def parse_all_options(self, mode, kargs):
-        sniffopt = {}
-        sendopt = {}
-        for k in kargs.keys():            
-            if k in self.sniff_options_list:
-                sniffopt[k] = kargs[k]
-            if k in self.send_options_list:
-                sendopt[k] = kargs[k]
-            if k in self.sniff_options_list+self.send_options_list:
-                del(kargs[k])
-        if mode != 2 or kargs:
-            if mode == 1:
-                self.optam0 = kargs
-            elif mode == 2 and kargs:
-                k = self.optam0.copy()
-                k.update(kargs)
-                self.parse_options(**k)
-                kargs = k 
-            omode = self.__dict__.get("mode",0)
-            self.__dict__["mode"] = mode
-            self.parse_options(**kargs)
-            self.__dict__["mode"] = omode
-        return sendopt,sniffopt
-
-    def is_request(self, req):
-        return 1
-
-    def make_reply(self, req):
-        return req
-
-    def send_reply(self, reply):
-        self.send_function(reply, **self.optsend)
-
-    def print_reply(self, req, reply):
-        print "%s ==> %s" % (req.summary(),reply.summary())
-
-    def reply(self, pkt):
-        if not self.is_request(pkt):
-            return
-        reply = self.make_reply(pkt)
-        self.send_reply(reply)
-        if conf.verb >= 0:
-            self.print_reply(pkt, reply)
-
-    def run(self, *args, **kargs):
-        log_interactive.warning("run() method deprecated. The intance is now callable")
-        self(*args,**kargs)
-
-    def __call__(self, *args, **kargs):
-        optsend,optsniff = self.parse_all_options(2,kargs)
-        self.optsend=self.defoptsend.copy()
-        self.optsend.update(optsend)
-        self.optsniff=self.defoptsniff.copy()
-        self.optsniff.update(optsniff)
-
-        try:
-            self.sniff()
-        except KeyboardInterrupt:
-            print "Interrupted by user"
-        
-    def sniff(self):
-        sniff(**self.optsniff)
-
-
-class BOOTP_am(AnsweringMachine):
-    function_name = "bootpd"
-    filter = "udp and port 68 and port 67"
-    send_function = staticmethod(sendp)
-    def parse_options(self, pool=Net("192.168.1.128/25"), network="192.168.1.0/24",gw="192.168.1.1",
-                      domain="localnet", renewal_time=60, lease_time=1800):
-        if type(pool) is str:
-            poom = Net(pool)
-        self.domain = domain
-        netw,msk = (network.split("/")+["32"])[:2]
-        msk = itom(int(msk))
-        self.netmask = ltoa(msk)
-        self.network = ltoa(atol(netw)&msk)
-        self.broadcast = ltoa( atol(self.network) | (0xffffffff&~msk) )
-        self.gw = gw
-        if isinstance(pool,Gen):
-            pool = [k for k in pool if k not in [gw, self.network, self.broadcast]]
-            pool.reverse()
-        if len(pool) == 1:
-            pool, = pool
-        self.pool = pool
-        self.lease_time = lease_time
-        self.renewal_time = renewal_time
-        self.leases = {}
-
-    def is_request(self, req):
-        if not req.haslayer(BOOTP):
-            return 0
-        reqb = req.getlayer(BOOTP)
-        if reqb.op != 1:
-            return 0
-        return 1
-
-    def print_reply(self, req, reply):
-        print "Reply %s to %s" % (reply.getlayer(IP).dst,reply.dst)
-
-    def make_reply(self, req):        
-        mac = req.src
-        if type(self.pool) is list:
-            if not self.leases.has_key(mac):
-                self.leases[mac] = self.pool.pop()
-            ip = self.leases[mac]
-        else:
-            ip = self.pool
-            
-        repb = req.getlayer(BOOTP).copy()
-        repb.op="BOOTREPLY"
-        repb.yiaddr = ip
-        repb.siaddr = self.gw
-        repb.ciaddr = self.gw
-        repb.giaddr = self.gw
-        del(repb.payload)
-        rep=Ether(dst=mac)/IP(dst=ip)/UDP(sport=req.dport,dport=req.sport)/repb
-        return rep
-
-
-class DHCP_am(BOOTP_am):
-    function_name="dhcpd"
-    def make_reply(self, req):
-        resp = BOOTP_am.make_reply(self, req)
-        if DHCP in req:
-            dhcp_options = [(op[0],{1:2,3:5}.get(op[1],op[1]))
-                            for op in req[DHCP].options
-                            if type(op) is tuple  and op[0] == "message-type"]
-            dhcp_options += [("server_id",self.gw),
-                             ("domain", self.domain),
-                             ("router", self.gw),
-                             ("name_server", self.gw),
-                             ("broadcast_address", self.broadcast),
-                             ("subnet_mask", self.netmask),
-                             ("renewal_time", self.renewal_time),
-                             ("lease_time", self.lease_time), 
-                             "end"
-                             ]
-            resp /= DHCP(options=dhcp_options)
-        return resp
-    
-
-
-class DNS_am(AnsweringMachine):
-    function_name="dns_spoof"
-    filter = "udp port 53"
-
-    def parse_options(self, joker="192.168.1.1", match=None):
-        if match is None:
-            self.match = {}
-        else:
-            self.match = match
-        self.joker=joker
-
-    def is_request(self, req):
-        return req.haslayer(DNS) and req.getlayer(DNS).qr == 0
-    
-    def make_reply(self, req):
-        ip = req.getlayer(IP)
-        dns = req.getlayer(DNS)
-        resp = IP(dst=ip.src, src=ip.dst)/UDP(dport=ip.sport,sport=ip.dport)
-        rdata = self.match.get(dns.qd.qname, self.joker)
-        resp /= DNS(id=dns.id, qr=1, qd=dns.qd,
-                    an=DNSRR(rrname=dns.qd.qname, ttl=10, rdata=rdata))
-        return resp
-
-
-class WiFi_am(AnsweringMachine):
-    """Before using this, initialize "iffrom" and "ifto" interfaces:
-iwconfig iffrom mode monitor
-iwpriv orig_ifto hostapd 1
-ifconfig ifto up
-note: if ifto=wlan0ap then orig_ifto=wlan0
-note: ifto and iffrom must be set on the same channel
-ex:
-ifconfig eth1 up
-iwconfig eth1 mode monitor
-iwconfig eth1 channel 11
-iwpriv wlan0 hostapd 1
-ifconfig wlan0ap up
-iwconfig wlan0 channel 11
-iwconfig wlan0 essid dontexist
-iwconfig wlan0 mode managed
-"""
-    function_name = "airpwn"
-    filter = None
-    
-    def parse_options(iffrom, ifto, replace, pattern="", ignorepattern=""):
-        self.iffrom = iffrom
-        self.ifto = ifto
-        ptrn = re.compile(pattern)
-        iptrn = re.compile(ignorepattern)
-        
-    def is_request(self, pkt):
-        if not isinstance(pkt,Dot11):
-            return 0
-        if not pkt.FCfield & 1:
-            return 0
-        if not pkt.haslayer(TCP):
-            return 0
-        ip = pkt.getlayer(IP)
-        tcp = pkt.getlayer(TCP)
-        pay = str(tcp.payload)
-        if not self.ptrn.match(pay):
-            return 0
-        if self.iptrn.match(pay):
-            return 0
-
-    def make_reply(self, p):
-        ip = p.getlayer(IP)
-        tcp = p.getlayer(TCP)
-        pay = str(tcp.payload)
-        del(p.payload.payload.payload)
-        p.FCfield="from-DS"
-        p.addr1,p.addr2 = p.addr2,p.addr1
-        p /= IP(src=ip.dst,dst=ip.src)
-        p /= TCP(sport=tcp.dport, dport=tcp.sport,
-                 seq=tcp.ack, ack=tcp.seq+len(pay),
-                 flags="PA")
-        q = p.copy()
-        p /= self.replace
-        q.ID += 1
-        q.getlayer(TCP).flags="RA"
-        q.getlayer(TCP).seq+=len(replace)
-        return [p,q]
-    
-    def print_reply(self):
-        print p.sprintf("Sent %IP.src%:%IP.sport% > %IP.dst%:%TCP.dport%")
-
-    def send_reply(self, reply):
-        sendp(reply, iface=self.ifto, **self.optsend)
-
-    def sniff(self):
-        sniff(iface=self.iffrom, **self.optsniff)
-
-
-
-class ARP_am(AnsweringMachine):
-    function_name="farpd"
-    filter = "arp"
-    send_function = staticmethod(sendp)
-
-    def parse_options(self, IP_addr=None, iface=None, ARP_addr=None):
-        self.IP_addr=IP_addr
-        self.iface=iface
-        self.ARP_addr=ARP_addr
-
-    def is_request(self, req):
-        return (req.haslayer(ARP) and
-                req.getlayer(ARP).op == 1 and
-                (self.IP_addr == None or self.IP_addr == req.getlayer(ARP).pdst))
-    
-    def make_reply(self, req):
-        ether = req.getlayer(Ether)
-        arp = req.getlayer(ARP)
-        iff,a,gw = conf.route.route(arp.psrc)
-        if self.iface != None:
-            iff = iface
-        ARP_addr = self.ARP_addr
-        IP_addr = arp.pdst
-        resp = Ether(dst=ether.src,
-                     src=ARP_addr)/ARP(op="is-at",
-                                       hwsrc=ARP_addr,
-                                       psrc=IP_addr,
-                                       hwdst=arp.hwsrc,
-                                       pdst=arp.pdst)
-        return resp
-
-    def sniff(self):
-        sniff(iface=self.iface, **self.optsniff)
-
-
-#############
-## Fuzzing ##
-#############
-
-
-def fuzz(p, _inplace=0):
-    if not _inplace:
-        p = p.copy()
-    q = p
-    while not isinstance(q, NoPayload):
-        for f in q.fields_desc:
-            if isinstance(f, PacketListField):
-                for r in getattr(q, f.name):
-                    print "fuzzing", repr(r)
-                    fuzz(r, _inplace=1)
-            elif f.default is not None:
-                rnd = f.randval()
-                if rnd is not None:
-                    q.default_fields[f.name] = rnd
-        q = q.payload
-    return p
-
-
-
-
-###################
-## Testing stuff ##
-###################
-
-
-
-def merge(x,y):
-    if len(x) > len(y):
-        y += "\x00"*(len(x)-len(y))
-    elif len(x) < len(y):
-        x += "\x00"*(len(y)-len(x))
-    m = ""
-    for i in range(len(x)/ss):
-        m += x[ss*i:ss*(i+1)]+y[ss*i:ss*(i+1)]
-    return  m
-#    return  "".join(map(str.__add__, x, y))
-
-
-def voip_play(s1,list=None,**kargs):
-    FIFO="/tmp/conv1.%i.%%i" % os.getpid()
-    FIFO1=FIFO % 1
-    FIFO2=FIFO % 2
-    
-    os.mkfifo(FIFO1)
-    os.mkfifo(FIFO2)
-    try:
-        os.system("soxmix -t .ul %s -t .ul %s -t ossdsp /dev/dsp &" % (FIFO1,FIFO2))
-        
-        c1=open(FIFO1,"w", 4096)
-        c2=open(FIFO2,"w", 4096)
-        fcntl.fcntl(c1.fileno(),fcntl.F_SETFL, os.O_NONBLOCK)
-        fcntl.fcntl(c2.fileno(),fcntl.F_SETFL, os.O_NONBLOCK)
-    
-    #    dsp,rd = os.popen2("sox -t .ul -c 2 - -t ossdsp /dev/dsp")
-        def play(pkt,last=[]):
-            if not pkt:
-                return 
-            if not pkt.haslayer(UDP):
-                return 
-            ip=pkt.getlayer(IP)
-            if s1 in [ip.src, ip.dst]:
-                if not last:
-                    last.append(pkt)
-                    return
-                load=last.pop()
-    #            x1 = load.load[12:]
-                c1.write(load.load[12:])
-                if load.getlayer(IP).src == ip.src:
-    #                x2 = ""
-                    c2.write("\x00"*len(load.load[12:]))
-                    last.append(pkt)
-                else:
-    #                x2 = pkt.load[:12]
-                    c2.write(pkt.load[12:])
-    #            dsp.write(merge(x1,x2))
-    
-        if list is None:
-            sniff(store=0, prn=play, **kargs)
-        else:
-            for p in list:
-                play(p)
-    finally:
-        os.unlink(FIFO1)
-        os.unlink(FIFO2)
-
-
-
-def voip_play1(s1,list=None,**kargs):
-
-    
-    dsp,rd = os.popen2("sox -t .ul - -t ossdsp /dev/dsp")
-    def play(pkt):
-        if not pkt:
-            return 
-        if not pkt.haslayer(UDP):
-            return 
-        ip=pkt.getlayer(IP)
-        if s1 in [ip.src, ip.dst]:
-            dsp.write(pkt.getlayer(Raw).load[12:])
-    try:
-        if list is None:
-            sniff(store=0, prn=play, **kargs)
-        else:
-            for p in list:
-                play(p)
-    finally:
-        dsp.close()
-        rd.close()
-
-def voip_play2(s1,**kargs):
-    dsp,rd = os.popen2("sox -t .ul -c 2 - -t ossdsp /dev/dsp")
-    def play(pkt,last=[]):
-        if not pkt:
-            return 
-        if not pkt.haslayer(UDP):
-            return 
-        ip=pkt.getlayer(IP)
-        if s1 in [ip.src, ip.dst]:
-            if not last:
-                last.append(pkt)
-                return
-            load=last.pop()
-            x1 = load.load[12:]
-#            c1.write(load.load[12:])
-            if load.getlayer(IP).src == ip.src:
-                x2 = ""
-#                c2.write("\x00"*len(load.load[12:]))
-                last.append(pkt)
-            else:
-                x2 = pkt.load[:12]
-#                c2.write(pkt.load[12:])
-            dsp.write(merge(x1,x2))
-            
-    sniff(store=0, prn=play, **kargs)
-
-def voip_play3(lst=None,**kargs):
-    dsp,rd = os.popen2("sox -t .ul - -t ossdsp /dev/dsp")
-    try:
-        def play(pkt, dsp=dsp):
-            if pkt and pkt.haslayer(UDP) and pkt.haslayer(Raw):
-                dsp.write(pkt.getlayer(RTP).load)
-        if lst is None:
-            sniff(store=0, prn=play, **kargs)
-        else:
-            for p in lst:
-                play(p)
-    finally:
-        try:
-            dsp.close()
-            rd.close()
-        except:
-            pass
-
-
-def IPID_count(lst, funcID=lambda x:x[1].id, funcpres=lambda x:x[1].summary()):
-    idlst = map(funcID, lst)
-    idlst.sort()
-    classes = [idlst[0]]+map(lambda x:x[1],filter(lambda (x,y): abs(x-y)>50, map(lambda x,y: (x,y),idlst[:-1], idlst[1:])))
-    lst = map(lambda x:(funcID(x), funcpres(x)), lst)
-    lst.sort()
-    print "Probably %i classes:" % len(classes), classes
-    for id,pr in lst:
-        print "%5i" % id, pr
-    
-    
-    
-            
-
-last=None
-
-
-def tethereal(*args,**kargs):
-    sniff(prn=lambda x: x.display(),*args,**kargs)
-
-def etherleak(target, **kargs):
-    return srpflood(Ether()/ARP(pdst=target), prn=lambda (s,r): Padding in r and hexstr(r[Padding].load),
-                    filter="arp", **kargs)
-
-
-def fragleak(target,sport=123, dport=123, timeout=0.2, onlyasc=0):
-    load = "XXXXYYYYYYYYYY"
-#    getmacbyip(target)
-#    pkt = IP(dst=target, id=RandShort(), options="\x22"*40)/UDP()/load
-    pkt = IP(dst=target, id=RandShort(), options="\x00"*40, flags=1)/UDP(sport=sport, dport=sport)/load
-    s=conf.L3socket()
-    intr=0
-    found={}
-    try:
-        while 1:
-            try:
-                if not intr:
-                    s.send(pkt)
-                sin,sout,serr = select([s],[],[],timeout)
-                if not sin:
-                    continue
-                ans=s.recv(1600)
-                if not isinstance(ans, IP): #TODO: IPv6
-                    continue
-                if not isinstance(ans.payload, ICMP):
-                    continue
-                if not isinstance(ans.payload.payload, IPerror):
-                    continue
-                if ans.payload.payload.dst != target:
-                    continue
-                if ans.src  != target:
-                    print "leak from", ans.src,
-
-
-#                print repr(ans)
-                if not ans.haslayer(Padding):
-                    continue
-
-                
-#                print repr(ans.payload.payload.payload.payload)
-                
-#                if not isinstance(ans.payload.payload.payload.payload, Raw):
-#                    continue
-#                leak = ans.payload.payload.payload.payload.load[len(load):]
-                leak = ans.getlayer(Padding).load
-                if leak not in found:
-                    found[leak]=None
-                    linehexdump(leak, onlyasc=onlyasc)
-            except KeyboardInterrupt:
-                if intr:
-                    raise
-                intr=1
-    except KeyboardInterrupt:
-        pass
-
-def fragleak2(target, timeout=0.4, onlyasc=0):
-    found={}
-    try:
-        while 1:
-            p = sr1(IP(dst=target, options="\x00"*40, proto=200)/"XXXXYYYYYYYYYYYY",timeout=timeout,verbose=0)
-            if not p:
-                continue
-            if Padding in p:
-                leak  = p[Padding].load
-                if leak not in found:
-                    found[leak]=None
-                    linehexdump(leak,onlyasc=onlyasc)
-    except:
-        pass
-    
-
-
-plst=[]
-def get_toDS():
-    global plst
-    while 1:
-        p,=sniff(iface="eth1",count=1)
-        if not isinstance(p,Dot11):
-            continue
-        if p.FCfield & 1:
-            plst.append(p)
-            print "."
-
-
-#    if not ifto.endswith("ap"):
-#        print "iwpriv %s hostapd 1" % ifto
-#        os.system("iwpriv %s hostapd 1" % ifto)
-#        ifto += "ap"
-#        
-#    os.system("iwconfig %s mode monitor" % iffrom)
-#    
-
-def airpwn(iffrom, ifto, replace, pattern="", ignorepattern=""):
-    """Before using this, initialize "iffrom" and "ifto" interfaces:
-iwconfig iffrom mode monitor
-iwpriv orig_ifto hostapd 1
-ifconfig ifto up
-note: if ifto=wlan0ap then orig_ifto=wlan0
-note: ifto and iffrom must be set on the same channel
-ex:
-ifconfig eth1 up
-iwconfig eth1 mode monitor
-iwconfig eth1 channel 11
-iwpriv wlan0 hostapd 1
-ifconfig wlan0ap up
-iwconfig wlan0 channel 11
-iwconfig wlan0 essid dontexist
-iwconfig wlan0 mode managed
-"""
-    
-    ptrn = re.compile(pattern)
-    iptrn = re.compile(ignorepattern)
-    def do_airpwn(p, ifto=ifto, replace=replace, ptrn=ptrn, iptrn=iptrn):
-        if not isinstance(p,Dot11):
-            return
-        if not p.FCfield & 1:
-            return
-        if not p.haslayer(TCP):
-            return
-        ip = p.getlayer(IP)
-        tcp = p.getlayer(TCP)
-        pay = str(tcp.payload)
-#        print "got tcp"
-        if not ptrn.match(pay):
-            return
-#        print "match 1"
-        if iptrn.match(pay):
-            return
-#        print "match 2"
-        del(p.payload.payload.payload)
-        p.FCfield="from-DS"
-        p.addr1,p.addr2 = p.addr2,p.addr1
-        q = p.copy()
-        p /= IP(src=ip.dst,dst=ip.src)
-        p /= TCP(sport=tcp.dport, dport=tcp.sport,
-                 seq=tcp.ack, ack=tcp.seq+len(pay),
-                 flags="PA")
-        q = p.copy()
-        p /= replace
-        q.ID += 1
-        q.getlayer(TCP).flags="RA"
-        q.getlayer(TCP).seq+=len(replace)
-        
-        sendp([p,q], iface=ifto, verbose=0)
-#        print "send",repr(p)        
-#        print "send",repr(q)
-        print p.sprintf("Sent %IP.src%:%IP.sport% > %IP.dst%:%TCP.dport%")
-
-    sniff(iface=iffrom,prn=do_airpwn)
-
-            
-        
-    
-##################
-## Color themes ##
-##################
-
-class Color:
-    normal = "\033[0m"
-    black = "\033[30m"
-    red = "\033[31m"
-    green = "\033[32m"
-    yellow = "\033[33m"
-    blue = "\033[34m"
-    purple = "\033[35m"
-    cyan = "\033[36m"
-    grey = "\033[37m"
-
-    bold = "\033[1m"
-    uline = "\033[4m"
-    blink = "\033[5m"
-    invert = "\033[7m"
-        
-
-class ColorTheme:
-    def __repr__(self):
-        return "<%s>" % self.__class__.__name__
-    def __getattr__(self, attr):
-        return lambda x:x
-        
-
-class NoTheme(ColorTheme):
-    pass
-
-
-class AnsiColorTheme(ColorTheme):
-    def __getattr__(self, attr):
-        if attr.startswith("__"):
-            raise AttributeError(attr)
-        s = "style_%s" % attr 
-        if s in self.__class__.__dict__:
-            before = getattr(self, s)
-            after = self.style_normal
-        else:
-            before = after = ""
-
-        def do_style(val, fmt=None, before=before, after=after):
-            if fmt is None:
-                if type(val) is not str:
-                    val = str(val)
-            else:
-                val = fmt % val
-            return before+val+after
-        return do_style
-        
-        
-    style_normal = ""
-    style_prompt = ""
-    style_punct = ""
-    style_id = ""
-    style_not_printable = ""
-    style_layer_name = ""
-    style_field_name = ""
-    style_field_value = ""
-    style_emph_field_name = ""
-    style_emph_field_value = ""
-    style_packetlist_name = ""
-    style_packetlist_proto = ""
-    style_packetlist_value = ""
-    style_fail = ""
-    style_success = ""
-    style_odd = ""
-    style_even = ""
-    style_opening = ""
-    style_active = ""
-    style_closed = ""
-    style_left = ""
-    style_right = ""
-
-class BlackAndWhite(AnsiColorTheme):
-    pass
-
-class DefaultTheme(AnsiColorTheme):
-    style_normal = Color.normal
-    style_prompt = Color.blue+Color.bold
-    style_punct = Color.normal
-    style_id = Color.blue+Color.bold
-    style_not_printable = Color.grey
-    style_layer_name = Color.red+Color.bold
-    style_field_name = Color.blue
-    style_field_value = Color.purple
-    style_emph_field_name = Color.blue+Color.uline+Color.bold
-    style_emph_field_value = Color.purple+Color.uline+Color.bold
-    style_packetlist_name = Color.red+Color.bold
-    style_packetlist_proto = Color.blue
-    style_packetlist_value = Color.purple
-    style_fail = Color.red+Color.bold
-    style_success = Color.blue+Color.bold
-    style_even = Color.black+Color.bold
-    style_odd = Color.black
-    style_opening = Color.yellow
-    style_active = Color.black
-    style_closed = Color.grey
-    style_left = Color.blue+Color.invert
-    style_right = Color.red+Color.invert
-    
-class BrightTheme(AnsiColorTheme):
-    style_normal = Color.normal
-    style_punct = Color.normal
-    style_id = Color.yellow+Color.bold
-    style_layer_name = Color.red+Color.bold
-    style_field_name = Color.yellow+Color.bold
-    style_field_value = Color.purple+Color.bold
-    style_emph_field_name = Color.yellow+Color.bold
-    style_emph_field_value = Color.green+Color.bold
-    style_packetlist_name = Color.red+Color.bold
-    style_packetlist_proto = Color.yellow+Color.bold
-    style_packetlist_value = Color.purple+Color.bold
-    style_fail = Color.red+Color.bold
-    style_success = Color.blue+Color.bold
-    style_even = Color.black+Color.bold
-    style_odd = Color.black
-    style_left = Color.cyan+Color.invert
-    style_right = Color.purple+Color.invert
-
-
-class RastaTheme(AnsiColorTheme):
-    style_normal = Color.normal+Color.green+Color.bold
-    style_prompt = Color.yellow+Color.bold
-    style_punct = Color.red
-    style_id = Color.green+Color.bold
-    style_not_printable = Color.green
-    style_layer_name = Color.red+Color.bold
-    style_field_name = Color.yellow+Color.bold
-    style_field_value = Color.green+Color.bold
-    style_emph_field_name = Color.green
-    style_emph_field_value = Color.green
-    style_packetlist_name = Color.red+Color.bold
-    style_packetlist_proto = Color.yellow+Color.bold
-    style_packetlist_value = Color.green+Color.bold
-    style_fail = Color.red
-    style_success = Color.red+Color.bold
-    style_even = Color.yellow
-    style_odd = Color.green
-    style_left = Color.yellow+Color.invert
-    style_right = Color.red+Color.invert
-
-
-class FormatTheme(ColorTheme):
-    def __getattr__(self, attr):
-        if attr.startswith("__"):
-            raise AttributeError(attr)
-        col = self.__class__.__dict__.get("style_%s" % attr, "%s")
-        def do_style(val, fmt=None, col=col):
-            if fmt is None:
-                if type(val) is not str:
-                    val = str(val)
-            else:
-                val = fmt % val
-            return col % val
-        return do_style
-        
-
-class LatexTheme(FormatTheme):
-    style_prompt = r"\textcolor{blue}{%s}"
-    style_not_printable = r"\textcolor{gray}{%s}"
-    style_layer_name = r"\textcolor{red}{\bf %s}"
-    style_field_name = r"\textcolor{blue}{%s}"
-    style_field_value = r"\textcolor{purple}{%s}"
-    style_emph_field_name = r"\textcolor{blue}{\underline{%s}}" #ul
-    style_emph_field_value = r"\textcolor{purple}{\underline{%s}}" #ul
-    style_packetlist_name = r"\textcolor{red}{\bf %s}"
-    style_packetlist_proto = r"\textcolor{blue}{%s}"
-    style_packetlist_value = r"\textcolor{purple}{%s}"
-    style_fail = r"\textcolor{red}{\bf %s}"
-    style_success = r"\textcolor{blue}{\bf %s}"
-    style_left = r"\textcolor{blue}{%s}"
-    style_right = r"\textcolor{red}{%s}"
-#    style_even = r"}{\bf "
-#    style_odd = ""
-
-class LatexTheme2(FormatTheme):
-    style_prompt = r"@`@textcolor@[@blue@]@@[@%s@]@"
-    style_not_printable = r"@`@textcolor@[@gray@]@@[@%s@]@"
-    style_layer_name = r"@`@textcolor@[@red@]@@[@@`@bfseries@[@@]@%s@]@"
-    style_field_name = r"@`@textcolor@[@blue@]@@[@%s@]@"
-    style_field_value = r"@`@textcolor@[@purple@]@@[@%s@]@"
-    style_emph_field_name = r"@`@textcolor@[@blue@]@@[@@`@underline@[@%s@]@@]@" 
-    style_emph_field_value = r"@`@textcolor@[@purple@]@@[@@`@underline@[@%s@]@@]@" 
-    style_packetlist_name = r"@`@textcolor@[@red@]@@[@@`@bfseries@[@@]@%s@]@"
-    style_packetlist_proto = r"@`@textcolor@[@blue@]@@[@%s@]@"
-    style_packetlist_value = r"@`@textcolor@[@purple@]@@[@%s@]@"
-    style_fail = r"@`@textcolor@[@red@]@@[@@`@bfseries@[@@]@%s@]@"
-    style_success = r"@`@textcolor@[@blue@]@@[@@`@bfserices@[@@]@%s@]@"
-    style_even = r"@`@textcolor@[@gray@]@@[@@`@bfseries@[@@]@%s@]@"
-#    style_odd = r"@`@textcolor@[@black@]@@[@@`@bfseries@[@@]@%s@]@"
-    style_left = r"@`@textcolor@[@blue@]@@[@%s@]@"
-    style_right = r"@`@textcolor@[@red@]@@[@%s@]@"
-
-class HTMLTheme(FormatTheme):
-    style_prompt = "<span class=prompt>%s</span>"
-    style_not_printable = "<span class=not_printable>%s</span>"
-    style_layer_name = "<span class=layer_name>%s</span>"
-    style_field_name = "<span class=field_name>%s</span>"
-    style_field_value = "<span class=field_value>%s</span>"
-    style_emph_field_name = "<span class=emph_field_name>%s</span>"
-    style_emph_field_value = "<span class=emph_field_value>%s</span>"
-    style_packetlist_name = "<span class=packetlist_name>%s</span>"
-    style_packetlist_proto = "<span class=packetlist_proto>%s</span>"
-    style_packetlist_value = "<span class=packetlist_value>%s</span>"
-    style_fail = "<span class=fail>%s</span>"
-    style_success = "<span class=success>%s</span>"
-    style_even = "<span class=even>%s</span>"
-    style_odd = "<span class=odd>%s</span>"
-    style_left = "<span class=left>%s</span>"
-    style_right = "<span class=right>%s</span>"
-
-class HTMLTheme2(HTMLTheme):
-    style_prompt = "#[#span class=prompt#]#%s#[#/span#]#"
-    style_not_printable = "#[#span class=not_printable#]#%s#[#/span#]#"
-    style_layer_name = "#[#span class=layer_name#]#%s#[#/span#]#"
-    style_field_name = "#[#span class=field_name#]#%s#[#/span#]#"
-    style_field_value = "#[#span class=field_value#]#%s#[#/span#]#"
-    style_emph_field_name = "#[#span class=emph_field_name#]#%s#[#/span#]#"
-    style_emph_field_value = "#[#span class=emph_field_value#]#%s#[#/span#]#"
-    style_packetlist_name = "#[#span class=packetlist_name#]#%s#[#/span#]#"
-    style_packetlist_proto = "#[#span class=packetlist_proto#]#%s#[#/span#]#"
-    style_packetlist_value = "#[#span class=packetlist_value#]#%s#[#/span#]#"
-    style_fail = "#[#span class=fail#]#%s#[#/span#]#"
-    style_success = "#[#span class=success#]#%s#[#/span#]#"
-    style_even = "#[#span class=even#]#%s#[#/span#]#"
-    style_odd = "#[#span class=odd#]#%s#[#/span#]#"
-    style_left = "#[#span class=left#]#%s#[#/span#]#"
-    style_right = "#[#span class=right#]#%s#[#/span#]#"
-
-
-class ColorPrompt:
-    __prompt = ">>> "
-    def __str__(self):
-        try:
-            ct = conf.color_theme
-            if isinstance(ct, AnsiColorTheme):
-                ## ^A and ^B delimit invisible caracters for readline to count right
-                return "\001%s\002" % ct.prompt("\002"+conf.prompt+"\001")
-            else:
-                return ct.prompt(conf.prompt)
-        except:
-            return self.__prompt
-
-############
-## Config ##
-############
-
-class ConfClass:
-    def configure(self, cnf):
-        self.__dict__ = cnf.__dict__.copy()
-    def __repr__(self):
-        return str(self)
-    def __str__(self):
-        s="Version    = %s\n" % VERSION
-        keys = self.__class__.__dict__.copy()
-        keys.update(self.__dict__)
-        keys = keys.keys()
-        keys.sort()
-        for i in keys:
-            if i[0] != "_":
-                s += "%-10s = %s\n" % (i, repr(getattr(self, i)))
-        return s[:-1]
-    
-class ProgPath(ConfClass):
-    pdfreader = "acroread"
-    psreader = "gv"
-    dot = "dot"
-    display = "display"
-    tcpdump = "tcpdump"
-    tcpreplay = "tcpreplay"
-    hexedit = "hexer"
-    wireshark = "wireshark"
-    
-class Resolve:
-    def __init__(self):
-        self.fields = {}
-    def add(self, *flds):
-        for fld in flds:
-            self.fields[fld]=None
-    def remove(self, *flds):
-        for fld in flds:
-            if fld in self.fields:
-                del(self.fields[fld])
-    def __contains__(self, elt):
-        return elt in self.fields
-    def __repr__(self):
-        return "<Resolve [%s]>" %  " ".join(str(x) for x in self.fields)
-    
-        
-
-
-class Conf(ConfClass):
-    """This object contains the configuration of scapy.
-session  : filename where the session will be saved
-stealth  : if 1, prevents any unwanted packet to go out (ARP, DNS, ...)
-checkIPID: if 0, doesn't check that IPID matches between IP sent and ICMP IP citation received
-           if 1, checks that they either are equal or byte swapped equals (bug in some IP stacks)
-           if 2, strictly checks that they are equals
-checkIPsrc: if 1, checks IP src in IP and ICMP IP citation match (bug in some NAT stacks)
-check_TCPerror_seqack: if 1, also check that TCP seq and ack match the ones in ICMP citation
-iff      : selects the default output interface for srp() and sendp(). default:"eth0")
-verb     : level of verbosity, from 0 (almost mute) to 3 (verbose)
-promisc  : default mode for listening socket (to get answers if you spoof on a lan)
-sniff_promisc : default mode for sniff()
-filter   : bpf filter added to every sniffing socket to exclude traffic from analysis
-histfile : history file
-padding  : includes padding in desassembled packets
-except_filter : BPF filter for packets to ignore
-debug_match : when 1, store received packet that are not matched into debug.recv
-route    : holds the Scapy routing table and provides methods to manipulate it
-warning_threshold : how much time between warnings from the same place
-ASN1_default_codec: Codec used by default for ASN1 objects
-mib      : holds MIB direct access dictionnary
-resolve   : holds list of fields for which resolution should be done
-noenum    : holds list of enum fields for which conversion to string should NOT be done
-AS_resolver: choose the AS resolver class to use
-extensions_paths: path or list of paths where extensions are to be looked for
-"""
-    session = ""  
-    stealth = "not implemented"
-    iface = get_working_if()
-    checkIPID = 0
-    checkIPsrc = 1
-    checkIPaddr = 1
-    check_TCPerror_seqack = 0
-    verb = 2
-    prompt = ">>> "
-    promisc = 1
-    sniff_promisc = 1
-    L3socket = L3PacketSocket
-    L2socket = L2Socket
-    L2listen = L2ListenSocket
-    BTsocket = BluetoothL2CAPSocket
-    histfile = os.path.join(os.environ["HOME"], ".scapy_history")
-    padding = 1
-    p0f_base ="/etc/p0f/p0f.fp"
-    queso_base ="/etc/queso.conf"
-    nmap_base ="/usr/share/nmap/nmap-os-fingerprints"
-    IPCountry_base = "GeoIPCountry4Scapy.gz"
-    countryLoc_base = "countryLoc.csv"
-    gnuplot_world = "world.dat"
-    except_filter = ""
-    debug_match = 0
-    route = Route()
-    wepkey = ""
-    auto_fragment = 1
-    debug_dissector = 0
-    color_theme = DefaultTheme()
-    warning_threshold = 5
-    ASN1_default_codec = ASN1_Codecs.BER
-    mib = MIBDict(_name="MIB")
-    prog = ProgPath()
-    resolve = Resolve()
-    noenum = Resolve()
-    ethertypes = ETHER_TYPES
-    protocols = IP_PROTOS
-    services_tcp = TCP_SERVICES
-    services_udp = UDP_SERVICES
-    manufdb = MANUFDB
-    AS_resolver = AS_resolver_multi()
-    extensions_paths = "."
-        
-
-conf=Conf()
-
-betteriface = conf.route.route("0.0.0.0", verbose=0)[0]
-if betteriface != "lo": #XXX linux specific...
-    conf.iface = betteriface
-del(betteriface)
-
-if PCAP:
-    conf.L2listen=L2pcapListenSocket
-    if DNET:
-        conf.L3socket=L3dnetSocket
-        conf.L2socket=L2dnetSocket
-
-
-p0f_kdb = p0fKnowledgeBase(conf.p0f_base)
-queso_kdb = QuesoKnowledgeBase(conf.queso_base)
-nmap_kdb = NmapKnowledgeBase(conf.nmap_base)
-IP_country_kdb = IPCountryKnowledgeBase(conf.IPCountry_base)
-country_loc_kdb = CountryLocKnowledgeBase(conf.countryLoc_base)
-
-
-#########################
-##### Autorun stuff #####
-#########################
-
-class StopAutorun(Scapy_Exception):
-    code_run = ""
-
-class ScapyAutorunInterpreter(code.InteractiveInterpreter):
-    def __init__(self, *args, **kargs):
-        code.InteractiveInterpreter.__init__(self, *args, **kargs)
-        self.error = 0
-    def showsyntaxerror(self, *args, **kargs):
-        self.error = 1
-        return code.InteractiveInterpreter.showsyntaxerror(self, *args, **kargs)
-    def showtraceback(self, *args, **kargs):
-        self.error = 1
-        exc_type, exc_value, exc_tb = sys.exc_info()
-        if isinstance(exc_value, StopAutorun):
-            raise exc_value
-        return code.InteractiveInterpreter.showtraceback(self, *args, **kargs)
-
-
-def autorun_commands(cmds,my_globals=None,verb=0):
-    sv = conf.verb
-    import __builtin__
-    try:
-        try:
-            if my_globals is None:
-                my_globals = globals()
-            conf.verb = verb
-            interp = ScapyAutorunInterpreter(my_globals)
-            cmd = ""
-            cmds = cmds.splitlines()
-            cmds.append("") # ensure we finish multiline commands
-            cmds.reverse()
-            __builtin__.__dict__["_"] = None
-            while 1:
-                if cmd:
-                    sys.stderr.write(sys.__dict__.get("ps2","... "))
-                else:
-                    sys.stderr.write(str(sys.__dict__.get("ps1",ColorPrompt())))
-                    
-                l = cmds.pop()
-                print l
-                cmd += "\n"+l
-                if interp.runsource(cmd):
-                    continue
-                if interp.error:
-                    return 0
-                cmd = ""
-                if len(cmds) <= 1:
-                    break
-        except SystemExit:
-            pass
-    finally:
-        conf.verb = sv
-    return _
-
-def autorun_get_interactive_session(cmds, **kargs):
-    class StringWriter:
-        def __init__(self):
-            self.s = ""
-        def write(self, x):
-            self.s += x
-            
-    sw = StringWriter()
-    sstdout,sstderr = sys.stdout,sys.stderr
-    try:
-        try:
-            sys.stdout = sys.stderr = sw
-            res = autorun_commands(cmds, **kargs)
-        except StopAutorun,e:
-            e.code_run = sw.s
-            raise
-    finally:
-        sys.stdout,sys.stderr = sstdout,sstderr
-    return sw.s,res
-
-def autorun_get_text_interactive_session(cmds, **kargs):
-    ct = conf.color_theme
-    try:
-        conf.color_theme = NoTheme()
-        s,res = autorun_get_interactive_session(cmds, **kargs)
-    finally:
-        conf.color_theme = ct
-    return s,res
-
-def autorun_get_ansi_interactive_session(cmds, **kargs):
-    ct = conf.color_theme
-    try:
-        conf.color_theme = DefaultTheme()
-        s,res = autorun_get_interactive_session(cmds, **kargs)
-    finally:
-        conf.color_theme = ct
-    return s,res
-
-def autorun_get_html_interactive_session(cmds, **kargs):
-    ct = conf.color_theme
-    to_html = lambda s: s.replace("<","&lt;").replace(">","&gt;").replace("#[#","<").replace("#]#",">")
-    try:
-        try:
-            conf.color_theme = HTMLTheme2()
-            s,res = autorun_get_interactive_session(cmds, **kargs)
-        except StopAutorun,e:
-            e.code_run = to_html(e.code_run)
-            raise
-    finally:
-        conf.color_theme = ct
-    
-    return to_html(s),res
-
-def autorun_get_latex_interactive_session(cmds, **kargs):
-    ct = conf.color_theme
-    to_latex = lambda s: tex_escape(s).replace("@[@","{").replace("@]@","}").replace("@`@","\\")
-    try:
-        try:
-            conf.color_theme = LatexTheme2()
-            s,res = autorun_get_interactive_session(cmds, **kargs)
-        except StopAutorun,e:
-            e.code_run = to_latex(e.code_run)
-            raise
-    finally:
-        conf.color_theme = ct
-    return to_latex(s),res
-
-
-################
-##### Main #####
-################
-
-def scapy_write_history_file(readline):
-    if conf.histfile:
-        try:
-            readline.write_history_file(conf.histfile)
-        except IOError,e:
-            try:
-                warning("Could not write history to [%s]\n\t (%s)" % (conf.histfile,e))
-                tmp = os.tempnam("","scapy")
-                readline.write_history_file(tmp)
-                warning("Wrote history to [%s]" % tmp)
-            except:
-                warning("Cound not write history to [%s]. Discarded" % tmp)
-
-
-def interact(mydict=None,argv=None,mybanner=None,loglevel=1):
-    global session
-    import code,sys,cPickle,types,os,imp,getopt,logging
-
-    logging.getLogger("scapy").setLevel(loglevel)
-
-    the_banner = "Welcome to Scapy (%s)"
-    if mybanner is not None:
-        the_banner += "\n"
-        the_banner += mybanner
-
-    if argv is None:
-        argv = sys.argv
-
-#    scapy_module = argv[0][argv[0].rfind("/")+1:]
-#    if not scapy_module:
-#        scapy_module = "scapy"
-#    else:
-#        if scapy_module.endswith(".py"):
-#            scapy_module = scapy_module[:-3]
-#
-#    scapy=imp.load_module("scapy",*imp.find_module(scapy_module))
-    
-    
-#    __builtin__.__dict__.update(scapy.__dict__)
-    import __builtin__
-    __builtin__.__dict__.update(globals())
-    globkeys = globals().keys()
-    globkeys.append("scapy_session")
-    if mydict is not None:
-        __builtin__.__dict__.update(mydict)
-        globkeys += mydict.keys()
-    
-    import re, atexit
-    try:
-        import rlcompleter,readline
-    except ImportError:
-        log_loading.info("Can't load Python libreadline or completer")
-        READLINE=0
-    else:
-        READLINE=1
-        class ScapyCompleter(rlcompleter.Completer):
-            def global_matches(self, text):
-                matches = []
-                n = len(text)
-                for lst in [dir(__builtin__), session.keys()]:
-                    for word in lst:
-                        if word[:n] == text and word != "__builtins__":
-                            matches.append(word)
-                return matches
-        
-    
-            def attr_matches(self, text):
-                m = re.match(r"(\w+(\.\w+)*)\.(\w*)", text)
-                if not m:
-                    return
-                expr, attr = m.group(1, 3)
-                try:
-                    object = eval(expr)
-                except:
-                    object = eval(expr, session)
-                if isinstance(object, Packet) or isinstance(object, Packet_metaclass):
-                    words = filter(lambda x: x[0]!="_",dir(object))
-                    words += [x.name for x in object.fields_desc]
-                else:
-                    words = dir(object)
-                    if hasattr( object,"__class__" ):
-                        words = words + rlcompleter.get_class_members(object.__class__)
-                matches = []
-                n = len(attr)
-                for word in words:
-                    if word[:n] == attr and word != "__builtins__":
-                        matches.append("%s.%s" % (expr, word))
-                return matches
-    
-        readline.set_completer(ScapyCompleter().complete)
-        readline.parse_and_bind("C-o: operate-and-get-next")
-        readline.parse_and_bind("tab: complete")
-    
-    
-    session=None
-    session_name=""
-    CONFIG_FILE = DEFAULT_CONFIG_FILE
-
-    iface = None
-    try:
-        opts=getopt.getopt(argv[1:], "hs:Cc:")
-        for opt, parm in opts[0]:
-            if opt == "-h":
-                usage()
-            elif opt == "-s":
-                session_name = parm
-            elif opt == "-c":
-                CONFIG_FILE = parm
-            elif opt == "-C":
-                CONFIG_FILE = None
-        
-        if len(opts[1]) > 0:
-            raise getopt.GetoptError("Too many parameters : [%s]" % string.join(opts[1]),None)
-
-
-    except getopt.GetoptError, msg:
-        log_loading.error(msg)
-        sys.exit(1)
-
-
-    if CONFIG_FILE:
-        read_config_file(CONFIG_FILE)
-        
-    if session_name:
-        try:
-            os.stat(session_name)
-        except OSError:
-            log_loading.info("New session [%s]" % session_name)
-        else:
-            try:
-                try:
-                    session = cPickle.load(gzip.open(session_name,"rb"))
-                except IOError:
-                    session = cPickle.load(open(session_name,"rb"))
-                log_loading.info("Using session [%s]" % session_name)
-            except EOFError:
-                log_loading.error("Error opening session [%s]" % session_name)
-            except AttributeError:
-                log_loading.error("Error opening session [%s]. Attribute missing" %  session_name)
-
-        if session:
-            if "conf" in session:
-                conf.configure(session["conf"])
-                session["conf"] = conf
-        else:
-            conf.session = session_name
-            session={"conf":conf}
-            
-    else:
-        session={"conf": conf}
-
-    __builtin__.__dict__["scapy_session"] = session
-
-
-    if READLINE:
-        if conf.histfile:
-            try:
-                readline.read_history_file(conf.histfile)
-            except IOError:
-                pass
-        atexit.register(scapy_write_history_file,readline)
-    
-    sys.ps1 = ColorPrompt()
-    code.interact(banner = the_banner % (VERSION), local=session)
-
-    if conf.session:
-        save_session(conf.session, session)
-
-
-    for k in globkeys:
-        try:
-            del(__builtin__.__dict__[k])
-        except:
-            pass
-
-def read_config_file(configfile):
-    try:
-        execfile(configfile)
-    except IOError,e:
-        log_loading.warning("Cannot read config file [%s] [%s]" % (configfile,e))
-    except Exception,e:
-        log_loading.exception("Error during evaluation of config file [%s]" % configfile)
-        
-
-if __name__ == "__main__":
-    interact()
-else:
-    if DEFAULT_CONFIG_FILE:
-        read_config_file(DEFAULT_CONFIG_FILE)
+interact()
diff --git a/scapy/__init__.py b/scapy/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/scapy/ansmachine.py b/scapy/ansmachine.py
new file mode 100644
index 0000000000000000000000000000000000000000..adf7f1f32226bb196d1d5b8dea57691f106866da
--- /dev/null
+++ b/scapy/ansmachine.py
@@ -0,0 +1,119 @@
+########################
+## Answering machines ##
+########################
+
+from sendrecv import send,sendp
+
+class ReferenceAM(type):
+    def __new__(cls, name, bases, dct):
+        o = super(ReferenceAM, cls).__new__(cls, name, bases, dct)
+        if o.function_name:
+            globals()[o.function_name] = lambda o=o,*args,**kargs: o(*args,**kargs)()
+        return o
+
+
+class AnsweringMachine(object):
+    __metaclass__ = ReferenceAM
+    function_name = ""
+    filter = None
+    sniff_options = { "store":0 }
+    sniff_options_list = [ "store", "iface", "count", "promisc", "filter", "type", "prn" ]
+    send_options = { "verbose":0 }
+    send_options_list = ["iface", "inter", "loop", "verbose"]
+    send_function = staticmethod(send)
+    
+    
+    def __init__(self, **kargs):
+        self.mode = 0
+        if self.filter:
+            kargs.setdefault("filter",self.filter)
+        kargs.setdefault("prn", self.reply)
+        self.optam1 = {}
+        self.optam2 = {}
+        self.optam0 = {}
+        doptsend,doptsniff = self.parse_all_options(1, kargs)
+        self.defoptsend = self.send_options.copy()
+        self.defoptsend.update(doptsend)
+        self.defoptsniff = self.sniff_options.copy()
+        self.defoptsniff.update(doptsniff)
+        self.optsend,self.optsniff = [{},{}]
+
+    def __getattr__(self, attr):
+        for d in [self.optam2, self.optam1]:
+            if attr in d:
+                return d[attr]
+        raise AttributeError,attr
+                
+    def __setattr__(self, attr, val):
+        mode = self.__dict__.get("mode",0)
+        if mode == 0:
+            self.__dict__[attr] = val
+        else:
+            [self.optam1, self.optam2][mode-1][attr] = val
+
+    def parse_options(self):
+        pass
+
+    def parse_all_options(self, mode, kargs):
+        sniffopt = {}
+        sendopt = {}
+        for k in kargs.keys():            
+            if k in self.sniff_options_list:
+                sniffopt[k] = kargs[k]
+            if k in self.send_options_list:
+                sendopt[k] = kargs[k]
+            if k in self.sniff_options_list+self.send_options_list:
+                del(kargs[k])
+        if mode != 2 or kargs:
+            if mode == 1:
+                self.optam0 = kargs
+            elif mode == 2 and kargs:
+                k = self.optam0.copy()
+                k.update(kargs)
+                self.parse_options(**k)
+                kargs = k 
+            omode = self.__dict__.get("mode",0)
+            self.__dict__["mode"] = mode
+            self.parse_options(**kargs)
+            self.__dict__["mode"] = omode
+        return sendopt,sniffopt
+
+    def is_request(self, req):
+        return 1
+
+    def make_reply(self, req):
+        return req
+
+    def send_reply(self, reply):
+        self.send_function(reply, **self.optsend)
+
+    def print_reply(self, req, reply):
+        print "%s ==> %s" % (req.summary(),reply.summary())
+
+    def reply(self, pkt):
+        if not self.is_request(pkt):
+            return
+        reply = self.make_reply(pkt)
+        self.send_reply(reply)
+        if conf.verb >= 0:
+            self.print_reply(pkt, reply)
+
+    def run(self, *args, **kargs):
+        log_interactive.warning("run() method deprecated. The intance is now callable")
+        self(*args,**kargs)
+
+    def __call__(self, *args, **kargs):
+        optsend,optsniff = self.parse_all_options(2,kargs)
+        self.optsend=self.defoptsend.copy()
+        self.optsend.update(optsend)
+        self.optsniff=self.defoptsniff.copy()
+        self.optsniff.update(optsniff)
+
+        try:
+            self.sniff()
+        except KeyboardInterrupt:
+            print "Interrupted by user"
+        
+    def sniff(self):
+        sniff(**self.optsniff)
+
diff --git a/scapy/arch.py b/scapy/arch.py
new file mode 100644
index 0000000000000000000000000000000000000000..debf2c1bbed57e8081cee7fcd948dba6f14b2336
--- /dev/null
+++ b/scapy/arch.py
@@ -0,0 +1,421 @@
+
+import sys,os,struct,socket,time
+from fcntl import ioctl
+from data import *
+
+try:
+    import Gnuplot
+    GNUPLOT=1
+except ImportError:
+    log_loading.info("did not find python gnuplot wrapper . Won't be able to plot")
+    GNUPLOT=0
+
+try:
+    import pyx
+    PYX=1
+except ImportError:
+    log_loading.info("Can't import PyX. Won't be able to use psdump() or pdfdump()")
+    PYX=0
+
+
+LINUX=sys.platform.startswith("linux")
+OPENBSD=sys.platform.startswith("openbsd")
+FREEBSD=sys.platform.startswith("freebsd")
+DARWIN=sys.platform.startswith("darwin")
+BIG_ENDIAN= struct.pack("H",1) == "\x00\x01"
+X86_64 = (os.uname()[4] == 'x86_64')
+SOLARIS=sys.platform.startswith("sunos")
+
+if LINUX:
+    DNET=PCAP=0
+else:
+    DNET=PCAP=1
+    
+
+if PCAP:
+    try:
+        import pcap
+        PCAP = 1
+    except ImportError:
+        if LINUX:
+            log_loading.warning("did not find pcap module. Fallback to linux primitives")
+            PCAP = 0
+        else:
+            if __name__ == "__main__":
+                log_loading.error("did not find pcap module")
+                raise SystemExit
+            else:
+                raise
+
+if DNET:
+    try:
+        import dnet
+        DNET = 1
+    except ImportError:
+        if LINUX:
+            log_loading.warning("did not find dnet module. Fallback to linux primitives")
+            DNET = 0
+        else:
+            if __name__ == "__main__":
+                log_loading.error("did not find dnet module")
+                raise SystemExit
+            else:
+                raise
+
+if not PCAP:
+    f = os.popen("tcpdump -V 2> /dev/null")
+    if f.close() >> 8 == 0x7f:
+        log_loading.warning("Failed to execute tcpdump. Check it is installed and in the PATH")
+        TCPDUMP=0
+    else:
+        TCPDUMP=1
+    del(f)
+        
+    
+
+try:
+    from Crypto.Cipher import ARC4
+except ImportError:
+    log_loading.info("Can't find Crypto python lib. Won't be able to decrypt WEP")
+
+
+# Workarround bug 643005 : https://sourceforge.net/tracker/?func=detail&atid=105470&aid=643005&group_id=5470
+try:
+    socket.inet_aton("255.255.255.255")
+except socket.error:
+    def inet_aton(x):
+        if x == "255.255.255.255":
+            return "\xff"*4
+        else:
+            return socket.inet_aton(x)
+else:
+    inet_aton = socket.inet_aton
+
+inet_ntoa = socket.inet_ntoa
+try:
+    inet_ntop = socket.inet_ntop
+    inet_pton = socket.inet_pton
+except AttributeError:
+    log_loading.info("inet_ntop/pton functions not found. Python IPv6 support not present")
+
+
+if SOLARIS:
+    # GRE is missing on Solaris
+    socket.IPPROTO_GRE = 47
+
+
+
+######################
+## Interfaces stuff ##
+######################
+
+
+if DNET:
+    def get_if_raw_hwaddr(iff):
+        if iff[:2] == "lo":
+            return (772, '\x00'*6)
+        try:
+            l = dnet.intf().get(iff)
+            l = l["link_addr"]
+        except:
+            raise Scapy_Exception("Error in attempting to get hw address for interface [%s]" % iff)
+        return l.type,l.data
+    def get_if_raw_addr(ifname):
+        i = dnet.intf()
+        return i.get(ifname)["addr"].data
+else:
+    def get_if_raw_hwaddr(iff):
+        return struct.unpack("16xh6s8x",get_if(iff,SIOCGIFHWADDR))
+
+    def get_if_raw_addr(iff):
+        try:
+            return get_if(iff, SIOCGIFADDR)[20:24]
+        except IOError:
+            return "\0\0\0\0"
+
+
+if PCAP:
+    def get_if_list():
+        # remove 'any' interface
+        return map(lambda x:x[0],filter(lambda x:x[1] is None,pcap.findalldevs()))
+    def get_working_if():
+        try:
+            return pcap.lookupdev()
+        except Exception:
+            return 'lo'
+
+    def attach_filter(s, filter):
+        warning("attach_filter() should not be called in PCAP mode")
+    def set_promisc(s,iff,val=1):
+        warning("set_promisc() should not be called in DNET/PCAP mode")
+    
+else:
+    def get_if_list():
+        f=open("/proc/net/dev","r")
+        lst = []
+        f.readline()
+        f.readline()
+        for l in f:
+            lst.append(l.split(":")[0].strip())
+        return lst
+    def get_working_if():
+        for i in get_if_list():
+            if i == 'lo':                
+                continue
+            ifflags = struct.unpack("16xH14x",get_if(i,SIOCGIFFLAGS))[0]
+            if ifflags & IFF_UP:
+                return i
+        return "lo"
+    def attach_filter(s, filter):
+        # XXX We generate the filter on the interface conf.iface 
+        # because tcpdump open the "any" interface and ppp interfaces
+        # in cooked mode. As we use them in raw mode, the filter will not
+        # work... one solution could be to use "any" interface and translate
+        # the filter from cooked mode to raw mode
+        # mode
+        if not TCPDUMP:
+            return
+        try:
+            f = os.popen("%s -i %s -ddd -s 1600 '%s'" % (conf.prog.tcpdump,conf.iface,filter))
+        except OSError,msg:
+            log_interactive.warning("Failed to execute tcpdump: (%s)")
+            return
+        lines = f.readlines()
+        if f.close():
+            raise Scapy_Exception("Filter parse error")
+        nb = int(lines[0])
+        bpf = ""
+        for l in lines[1:]:
+            bpf += struct.pack("HBBI",*map(long,l.split()))
+    
+        # XXX. Argl! We need to give the kernel a pointer on the BPF,
+        # python object header seems to be 20 bytes. 36 bytes for x86 64bits arch.
+        if X86_64:
+            bpfh = struct.pack("HL", nb, id(bpf)+36)
+        else:
+            bpfh = struct.pack("HI", nb, id(bpf)+20)  
+        s.setsockopt(SOL_SOCKET, SO_ATTACH_FILTER, bpfh)
+
+    def set_promisc(s,iff,val=1):
+        mreq = struct.pack("IHH8s", get_if_index(iff), PACKET_MR_PROMISC, 0, "")
+        if val:
+            cmd = PACKET_ADD_MEMBERSHIP
+        else:
+            cmd = PACKET_DROP_MEMBERSHIP
+        s.setsockopt(SOL_PACKET, cmd, mreq)
+
+
+
+##################
+## Routes stuff ##
+##################
+
+if not LINUX:
+
+    def new_read_routes():
+
+        rtlst = []
+        def addrt(rt,lst):
+            dst,gw = rt
+            lst.append(rt)
+
+        r = dnet.route()
+        print r.loop(addrt, rtlst)
+        return rtlst
+
+    def read_routes():
+        if SOLARIS:
+            f=os.popen("netstat -rvn") # -f inet
+        elif FREEBSD:
+            f=os.popen("netstat -rnW") # -W to handle long interface names
+        else:
+            f=os.popen("netstat -rn") # -f inet
+        ok = 0
+        mtu_present = False
+        routes = []
+        for l in f.readlines():
+            if not l:
+                break
+            l = l.strip()
+            if l.find("----") >= 0: # a separation line
+                continue
+            if l.find("Destination") >= 0:
+                ok = 1
+                if l.find("Mtu") >= 0:
+                    mtu_present = True
+                continue
+            if ok == 0:
+                continue
+            if not l:
+                break
+            if SOLARIS:
+                dest,mask,gw,netif,mxfrg,rtt,ref,flg = l.split()[:8]
+            else:
+                if mtu_present:
+                    dest,gw,flg,ref,use,mtu,netif = l.split()[:7]
+                else:
+                    dest,gw,flg,ref,use,netif = l.split()[:6]
+            if flg.find("Lc") >= 0:
+                continue                
+            if dest == "default":
+                dest = 0L
+                netmask = 0L
+            else:
+                if SOLARIS:
+                    netmask = atol(mask)
+                elif "/" in dest:
+                    dest,netmask = dest.split("/")
+                    netmask = itom(int(netmask))
+                else:
+                    netmask = itom((dest.count(".") + 1) * 8)
+                dest += ".0"*(3-dest.count("."))
+                dest = atol(dest)
+            if not "G" in flg:
+                gw = '0.0.0.0'
+            ifaddr = get_if_addr(netif)
+            routes.append((dest,netmask,gw,netif,ifaddr))
+        f.close()
+        return routes
+
+    def read_interfaces():
+        i = dnet.intf()
+        ifflist = {}
+        def addif(iff,lst):
+            if not iff.has_key("addr"):
+                return
+            if not iff.has_key("link_addr"):
+                return
+            rawip = iff["addr"].data
+            ip = inet_ntoa(rawip)
+            rawll = iff["link_addr"].data
+            ll = str2mac(rawll)
+            lst[iff["name"]] = (rawll,ll,rawip,ip)
+        i.loop(addif, ifflist)
+        return ifflist
+
+            
+else:
+
+    def read_routes():
+        f=open("/proc/net/route","r")
+        routes = []
+        s=socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+        ifreq = ioctl(s, SIOCGIFADDR,struct.pack("16s16x","lo"))
+        addrfamily = struct.unpack("h",ifreq[16:18])[0]
+        if addrfamily == socket.AF_INET:
+            ifreq2 = ioctl(s, SIOCGIFNETMASK,struct.pack("16s16x","lo"))
+            msk = socket.ntohl(struct.unpack("I",ifreq2[20:24])[0])
+            dst = socket.ntohl(struct.unpack("I",ifreq[20:24])[0]) & msk
+            ifaddr = inet_ntoa(ifreq[20:24])
+            routes.append((dst, msk, "0.0.0.0", "lo", ifaddr))
+        else:
+            warning("Interface lo: unkown address family (%i)"% addrfamily)
+    
+        for l in f.readlines()[1:]:
+            iff,dst,gw,flags,x,x,x,msk,x,x,x = l.split()
+            flags = int(flags,16)
+            if flags & RTF_UP == 0:
+                continue
+            if flags & RTF_REJECT:
+                continue
+            try:
+                ifreq = ioctl(s, SIOCGIFADDR,struct.pack("16s16x",iff))
+            except IOError: # interface is present in routing tables but does not have any assigned IP
+                ifaddr="0.0.0.0"
+            else:
+                addrfamily = struct.unpack("h",ifreq[16:18])[0]
+                if addrfamily == socket.AF_INET:
+                    ifaddr = inet_ntoa(ifreq[20:24])
+                else:
+                    warning("Interface %s: unkown address family (%i)"%(iff, addrfamily))
+                    continue
+            routes.append((socket.htonl(long(dst,16))&0xffffffffL,
+                           socket.htonl(long(msk,16))&0xffffffffL,
+                           inet_ntoa(struct.pack("I",long(gw,16))),
+                           iff, ifaddr))
+        
+        f.close()
+        return routes
+
+    def get_if(iff,cmd):
+        s=socket.socket()
+        ifreq = ioctl(s, cmd, struct.pack("16s16x",iff))
+        s.close()
+        return ifreq
+
+
+    def get_if_index(iff):
+        return int(struct.unpack("I",get_if(iff, SIOCGIFINDEX)[16:20])[0])
+
+    def get_last_packet_timestamp(sock):
+        ts = ioctl(sock, SIOCGSTAMP, "12345678")
+        s,us = struct.unpack("II",ts)
+        return s+us/1000000.0
+
+    
+def get_if_addr(iff):
+    return inet_ntoa(get_if_raw_addr(iff))
+    
+def get_if_hwaddr(iff):
+    addrfamily, mac = get_if_raw_hwaddr(iff)
+    if addrfamily in [ARPHDR_ETHER,ARPHDR_LOOPBACK]:
+        return str2mac(mac)
+    else:
+        raise Scapy_Exception("Unsupported address family (%i) for interface [%s]" % (addrfamily,iff))
+
+
+
+#####################
+## ARP cache stuff ##
+#####################
+
+ARPTIMEOUT=120
+
+# XXX Fill arp_cache with /etc/ether and arp cache
+arp_cache={}
+
+if 0 and DNET: ## XXX Can't use this because it does not resolve IPs not in cache
+    dnet_arp_object = dnet.arp()
+    def getmacbyip(ip, chainCC=0):
+        tmp = map(ord, inet_aton(ip))
+        if (tmp[0] & 0xf0) == 0xe0: # mcast @
+            return "01:00:5e:%.2x:%.2x:%.2x" % (tmp[1]&0x7f,tmp[2],tmp[3])
+        iff,a,gw = conf.route.route(ip)
+        if iff == "lo":
+            return "ff:ff:ff:ff:ff:ff"
+        if gw != "0.0.0.0":
+            ip = gw
+        res = dnet_arp_object.get(dnet.addr(ip))
+        if res is None:
+            return None
+        else:
+            return res.ntoa()
+else:
+    def getmacbyip(ip, chainCC=0):
+        tmp = map(ord, inet_aton(ip))
+        if (tmp[0] & 0xf0) == 0xe0: # mcast @
+            return "01:00:5e:%.2x:%.2x:%.2x" % (tmp[1]&0x7f,tmp[2],tmp[3])
+        iff,a,gw = conf.route.route(ip)
+        if ( (iff == "lo") or (ip == conf.route.get_if_bcast(iff)) ):
+            return "ff:ff:ff:ff:ff:ff"
+        if gw != "0.0.0.0":
+            ip = gw
+    
+        if arp_cache.has_key(ip):
+            mac, timeout = arp_cache[ip]
+            if not timeout or (time.time()-timeout < ARPTIMEOUT):
+                return mac
+
+        res = srp1(Ether(dst=ETHER_BROADCAST)/ARP(op="who-has", pdst=ip),
+                   type=ETH_P_ARP,
+                   iface = iff,
+                   timeout=2,
+                   verbose=0,
+                   chainCC=chainCC,
+                   nofilter=1)
+        if res is not None:
+            mac = res.payload.hwsrc
+            arp_cache[ip] = (mac,time.time())
+            return mac
+        return None
+    
diff --git a/scapy/asn1.py b/scapy/asn1.py
new file mode 100644
index 0000000000000000000000000000000000000000..456f1eaa94f2ebe125f1e3f28b56a2096d450303
--- /dev/null
+++ b/scapy/asn1.py
@@ -0,0 +1,272 @@
+import random
+from error import Scapy_Exception
+from volatile import RandField
+from utils import Enum_metaclass, EnumElement
+
+class RandASN1Object(RandField):
+    def __init__(self, objlist=None):
+        if objlist is None:
+            objlist = map(lambda x:x._asn1_obj,
+                          filter(lambda x:hasattr(x,"_asn1_obj"), ASN1_Class_UNIVERSAL.__rdict__.values()))
+        self.objlist = objlist
+        self.chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
+    def _fix(self, n=0):
+        o = random.choice(self.objlist)
+        if issubclass(o, ASN1_INTEGER):
+            return o(int(random.gauss(0,1000)))
+        elif issubclass(o, ASN1_STRING):
+            z = int(random.expovariate(0.05)+1)
+            return o("".join([random.choice(self.chars) for i in range(z)]))
+        elif issubclass(o, ASN1_SEQUENCE) and (n < 10):
+            z = int(random.expovariate(0.08)+1)
+            return o(map(lambda x:x._fix(n+1), [self.__class__(objlist=self.objlist)]*z))
+        return ASN1_INTEGER(int(random.gauss(0,1000)))
+
+
+##############
+#### ASN1 ####
+##############
+
+class ASN1_Error(Scapy_Exception):
+    pass
+
+class ASN1_Encoding_Error(ASN1_Error):
+    pass
+
+class ASN1_Decoding_Error(ASN1_Error):
+    pass
+
+class ASN1_BadTag_Decoding_Error(ASN1_Decoding_Error):
+    pass
+
+
+
+class ASN1Codec(EnumElement):
+    def register_stem(cls, stem):
+        cls._stem = stem
+    def dec(cls, s, context=None):
+        return cls._stem.dec(s, context=context)
+    def safedec(cls, s, context=None):
+        return cls._stem.safedec(s, context=context)
+    def get_stem(cls):
+        return cls.stem
+    
+
+class ASN1_Codecs_metaclass(Enum_metaclass):
+    element_class = ASN1Codec
+
+class ASN1_Codecs:
+    __metaclass__ = ASN1_Codecs_metaclass
+    BER = 1
+    DER = 2
+    PER = 3
+    CER = 4
+    LWER = 5
+    BACnet = 6
+    OER = 7
+    SER = 8
+    XER = 9
+
+class ASN1Tag(EnumElement):
+    def __init__(self, key, value, context=None, codec=None):
+        EnumElement.__init__(self, key, value)
+        self._context = context
+        if codec == None:
+            codec = {}
+        self._codec = codec
+    def clone(self): # /!\ not a real deep copy. self.codec is shared
+        return self.__class__(self._key, self._value, self._context, self._codec)
+    def register_asn1_object(self, asn1obj):
+        self._asn1_obj = asn1obj
+    def asn1_object(self, val):
+        if hasattr(self,"_asn1_obj"):
+            return self._asn1_obj(val)
+        raise ASN1_Error("%r does not have any assigned ASN1 object" % self)
+    def register(self, codecnum, codec):
+        self._codec[codecnum] = codec
+    def get_codec(self, codec):
+        try:
+            c = self._codec[codec]
+        except KeyError,msg:
+            raise ASN1_Error("Codec %r not found for tag %r" % (codec, self))
+        return c
+
+class ASN1_Class_metaclass(Enum_metaclass):
+    element_class = ASN1Tag
+    def __new__(cls, name, bases, dct): # XXX factorise a bit with Enum_metaclass.__new__()
+        for b in bases:
+            for k,v in b.__dict__.iteritems():
+                if k not in dct and isinstance(v,ASN1Tag):
+                    dct[k] = v.clone()
+
+        rdict = {}
+        for k,v in dct.iteritems():
+            if type(v) is int:
+                v = ASN1Tag(k,v) 
+                dct[k] = v
+                rdict[v] = v
+            elif isinstance(v, ASN1Tag):
+                rdict[v] = v
+        dct["__rdict__"] = rdict
+
+        cls = type.__new__(cls, name, bases, dct)
+        for v in cls.__dict__.values():
+            if isinstance(v, ASN1Tag): 
+                v.context = cls # overwrite ASN1Tag contexts, even cloned ones
+        return cls
+            
+
+class ASN1_Class:
+    __metaclass__ = ASN1_Class_metaclass
+
+class ASN1_Class_UNIVERSAL(ASN1_Class):
+    name = "UNIVERSAL"
+    ERROR = -3
+    RAW = -2
+    NONE = -1
+    ANY = 0
+    BOOLEAN = 1
+    INTEGER = 2
+    BIT_STRING = 3
+    STRING = 4
+    NULL = 5
+    OID = 6
+    OBJECT_DESCRIPTOR = 7
+    EXTERNAL = 8
+    REAL = 9
+    ENUMERATED = 10
+    EMBEDDED_PDF = 11
+    UTF8_STRING = 12
+    RELATIVE_OID = 13
+    SEQUENCE = 0x30#XXX 16 ??
+    SET = 0x31 #XXX 17 ??
+    NUMERIC_STRING = 18
+    PRINTABLE_STRING = 19
+    T61_STRING = 20
+    VIDEOTEX_STRING = 21
+    IA5_STRING = 22
+    UTC_TIME = 23
+    GENERALIZED_TIME = 24
+    GRAPHIC_STRING = 25
+    ISO646_STRING = 26
+    GENERAL_STRING = 27
+    UNIVERSAL_STRING = 28
+    CHAR_STRING = 29
+    BMP_STRING = 30
+    COUNTER32 = 0x41
+    TIME_TICKS = 0x43
+
+class ASN1_Object_metaclass(type):
+    def __new__(cls, name, bases, dct):
+        c = super(ASN1_Object_metaclass, cls).__new__(cls, name, bases, dct)
+        try:
+            c.tag.register_asn1_object(c)
+        except:
+            warning("Error registering %r for %r" % (c.tag, c.codec))
+        return c
+
+
+class ASN1_Object:
+    __metaclass__ = ASN1_Object_metaclass
+    tag = ASN1_Class_UNIVERSAL.ANY
+    def __init__(self, val):
+        self.val = val
+    def enc(self, codec):
+        return self.tag.get_codec(codec).enc(self.val)
+    def __repr__(self):
+        return "<%s[%r]>" % (self.__dict__.get("name", self.__class__.__name__), self.val)
+    def __str__(self):
+        return self.enc(conf.ASN1_default_codec)
+    def strshow(self, lvl=0):
+        return ("  "*lvl)+repr(self)+"\n"
+    def show(self, lvl=0):
+        print self.strshow(lvl)
+    def __eq__(self, other):
+        return self.val == other
+    def __cmp__(self, other):
+        return cmp(self.val, other)
+
+class ASN1_DECODING_ERROR(ASN1_Object):
+    tag = ASN1_Class_UNIVERSAL.ERROR
+    def __init__(self, val, exc=None):
+        ASN1_Object.__init__(self, val)
+        self.exc = exc
+    def __repr__(self):
+        return "<%s[%r]{{%s}}>" % (self.__dict__.get("name", self.__class__.__name__),
+                                   self.val, self.exc.args[0])
+    def enc(self, codec):
+        if isinstance(self.val, ASN1_Object):
+            return self.val.enc(codec)
+        return self.val
+
+class ASN1_force(ASN1_Object):
+    tag = ASN1_Class_UNIVERSAL.RAW
+    def enc(self, codec):
+        if isinstance(self.val, ASN1_Object):
+            return self.val.enc(codec)
+        return self.val
+
+class ASN1_BADTAG(ASN1_force):
+    pass
+
+class ASN1_INTEGER(ASN1_Object):
+    tag = ASN1_Class_UNIVERSAL.INTEGER
+
+class ASN1_STRING(ASN1_Object):
+    tag = ASN1_Class_UNIVERSAL.STRING
+
+class ASN1_BIT_STRING(ASN1_STRING):
+    tag = ASN1_Class_UNIVERSAL.BIT_STRING
+
+class ASN1_PRINTABLE_STRING(ASN1_STRING):
+    tag = ASN1_Class_UNIVERSAL.PRINTABLE_STRING
+
+class ASN1_T61_STRING(ASN1_STRING):
+    tag = ASN1_Class_UNIVERSAL.T61_STRING
+
+class ASN1_IA5_STRING(ASN1_STRING):
+    tag = ASN1_Class_UNIVERSAL.IA5_STRING
+
+class ASN1_NUMERIC_STRING(ASN1_STRING):
+    tag = ASN1_Class_UNIVERSAL.NUMERIC_STRING
+
+class ASN1_VIDEOTEX_STRING(ASN1_STRING):
+    tag = ASN1_Class_UNIVERSAL.VIDEOTEX_STRING
+
+class ASN1_UTC_TIME(ASN1_STRING):
+    tag = ASN1_Class_UNIVERSAL.UTC_TIME
+
+class ASN1_TIME_TICKS(ASN1_INTEGER):
+    tag = ASN1_Class_UNIVERSAL.TIME_TICKS
+
+class ASN1_BOOLEAN(ASN1_INTEGER):
+    tag = ASN1_Class_UNIVERSAL.BOOLEAN
+    
+class ASN1_NULL(ASN1_INTEGER):
+    tag = ASN1_Class_UNIVERSAL.NULL
+
+class ASN1_COUNTER32(ASN1_INTEGER):
+    tag = ASN1_Class_UNIVERSAL.COUNTER32
+    
+class ASN1_SEQUENCE(ASN1_Object):
+    tag = ASN1_Class_UNIVERSAL.SEQUENCE
+    def strshow(self, lvl=0):
+        s = ("  "*lvl)+("# %s:" % self.__class__.__name__)+"\n"
+        for o in self.val:
+            s += o.strshow(lvl=lvl+1)
+        return s
+    
+class ASN1_SET(ASN1_SEQUENCE):
+    tag = ASN1_Class_UNIVERSAL.SET
+    
+class ASN1_OID(ASN1_Object):
+    tag = ASN1_Class_UNIVERSAL.OID
+    def __init__(self, val):
+        val = conf.mib._oid(val)
+        ASN1_Object.__init__(self, val)
+    def __repr__(self):
+        return "<%s[%r]>" % (self.__dict__.get("name", self.__class__.__name__), conf.mib._oidname(self.val))
+    
+
+
+ASN1_default_codec = ASN1_Codecs.BER
diff --git a/scapy/asn1fields.py b/scapy/asn1fields.py
new file mode 100644
index 0000000000000000000000000000000000000000..110e285df76ccc7eaa1bdbc8dd473ece93af7290
--- /dev/null
+++ b/scapy/asn1fields.py
@@ -0,0 +1,301 @@
+from asn1 import *
+from ber import *
+from volatile import *
+
+#####################
+#### ASN1 Fields ####
+#####################
+
+class ASN1F_badsequence(Exception):
+    pass
+
+class ASN1F_element:
+    pass
+
+class ASN1F_optionnal(ASN1F_element):
+    def __init__(self, field):
+        self._field=field
+    def __getattr__(self, attr):
+        return getattr(self._field,attr)
+    def dissect(self,pkt,s):
+        try:
+            return self._field.dissect(pkt,s)
+        except ASN1F_badsequence:
+            self._field.set_val(pkt,None)
+            return s
+        except BER_Decoding_Error:
+            self._field.set_val(pkt,None)
+            return s
+    def build(self, pkt):
+        if self._field.is_empty(pkt):
+            return ""
+        return self._field.build(pkt)
+
+class ASN1F_field(ASN1F_element):
+    holds_packets=0
+    islist=0
+
+    ASN1_tag = ASN1_Class_UNIVERSAL.ANY
+    context=ASN1_Class_UNIVERSAL
+    
+    def __init__(self, name, default, context=None):
+        if context is not None:
+            self.context = context
+        self.name = name
+        self.default = default
+
+    def i2repr(self, pkt, x):
+        if x is None:
+            x = 0
+        return repr(x)
+    def i2h(self, pkt, x):
+        return x
+    def any2i(self, pkt, x):
+        return x
+    def m2i(self, pkt, x):
+        return self.ASN1_tag.get_codec(pkt.ASN1_codec).safedec(x, context=self.context)
+    def i2m(self, pkt, x):
+        if x is None:
+            x = 0
+        if isinstance(x, ASN1_Object):
+            if ( self.ASN1_tag == ASN1_Class_UNIVERSAL.ANY
+                 or x.tag == ASN1_Class_UNIVERSAL.RAW
+                 or x.tag == ASN1_Class_UNIVERSAL.ERROR
+                 or self.ASN1_tag == x.tag ):
+                return x.enc(pkt.ASN1_codec)
+            else:
+                raise ASN1_Error("Encoding Error: got %r instead of an %r for field [%s]" % (x, self.ASN1_tag, self.name))
+        return self.ASN1_tag.get_codec(pkt.ASN1_codec).enc(x)
+
+    def do_copy(self, x):
+        if hasattr(x, "copy"):
+            return x.copy()
+        if type(x) is list:
+            x = x[:]
+            for i in xrange(len(x)):
+                if isinstance(x[i], Packet):
+                    x[i] = x[i].copy()
+        return x
+
+    def build(self, pkt):
+        return self.i2m(pkt, getattr(pkt, self.name))
+
+    def set_val(self, pkt, val):
+        setattr(pkt, self.name, val)
+    def is_empty(self, pkt):
+        return getattr(pkt,self.name) is None
+    
+    def dissect(self, pkt, s):
+        v,s = self.m2i(pkt, s)
+        self.set_val(pkt, v)
+        return s
+
+    def get_fields_list(self):
+        return [self]
+
+    def __hash__(self):
+        return hash(self.name)
+    def __str__(self):
+        return self.name
+    def __eq__(self, other):
+        return self.name == other
+    def __repr__(self):
+        return self.name
+    def randval(self):
+        return RandInt()
+
+
+class ASN1F_INTEGER(ASN1F_field):
+    ASN1_tag= ASN1_Class_UNIVERSAL.INTEGER
+    def randval(self):
+        return RandNum(-2**64, 2**64-1)
+
+class ASN1F_NULL(ASN1F_INTEGER):
+    ASN1_tag= ASN1_Class_UNIVERSAL.NULL
+
+class ASN1F_enum_INTEGER(ASN1F_INTEGER):
+    def __init__(self, name, default, enum):
+        ASN1F_INTEGER.__init__(self, name, default)
+        i2s = self.i2s = {}
+        s2i = self.s2i = {}
+        if type(enum) is list:
+            keys = xrange(len(enum))
+        else:
+            keys = enum.keys()
+        if filter(lambda x: type(x) is str, keys):
+            i2s,s2i = s2i,i2s
+        for k in keys:
+            i2s[k] = enum[k]
+            s2i[enum[k]] = k
+    def any2i_one(self, pkt, x):
+        if type(x) is str:
+            x = self.s2i[x]
+        return x
+    def i2repr_one(self, pkt, x):
+        return self.i2s.get(x, repr(x))
+    
+    def any2i(self, pkt, x):
+        if type(x) is list:
+            return map(lambda z,pkt=pkt:self.any2i_one(pkt,z), x)
+        else:
+            return self.any2i_one(pkt,x)        
+    def i2repr(self, pkt, x):
+        if type(x) is list:
+            return map(lambda z,pkt=pkt:self.i2repr_one(pkt,z), x)
+        else:
+            return self.i2repr_one(pkt,x)
+
+class ASN1F_STRING(ASN1F_field):
+    ASN1_tag = ASN1_Class_UNIVERSAL.STRING
+    def randval(self):
+        return RandString(RandNum(0, 1000))
+
+class ASN1F_PRINTABLE_STRING(ASN1F_STRING):
+    ASN1_tag = ASN1_Class_UNIVERSAL.PRINTABLE_STRING
+
+class ASN1F_BIT_STRING(ASN1F_STRING):
+    ASN1_tag = ASN1_Class_UNIVERSAL.BIT_STRING
+
+class ASN1F_UTC_TIME(ASN1F_STRING):
+    ASN1_tag = ASN1_Class_UNIVERSAL.UTC_TIME
+
+class ASN1F_OID(ASN1F_field):
+    ASN1_tag = ASN1_Class_UNIVERSAL.OID
+    def randval(self):
+        return RandOID()
+
+class ASN1F_SEQUENCE(ASN1F_field):
+    ASN1_tag = ASN1_Class_UNIVERSAL.SEQUENCE
+    def __init__(self, *seq, **kargs):
+        if "ASN1_tag" in kargs:
+            self.ASN1_tag = kargs["ASN1_tag"]
+        self.seq = seq
+    def __repr__(self):
+        return "<%s%r>" % (self.__class__.__name__,self.seq,)
+    def set_val(self, pkt, val):
+        for f in self.seq:
+            f.set_val(pkt,val)
+    def is_empty(self, pkt):
+        for f in self.seq:
+            if not f.is_empty(pkt):
+                return False
+        return True
+    def get_fields_list(self):
+        return reduce(lambda x,y: x+y.get_fields_list(), self.seq, [])
+    def build(self, pkt):
+        s = reduce(lambda x,y: x+y.build(pkt), self.seq, "")
+        return self.i2m(pkt, s)
+    def dissect(self, pkt, s):
+        codec = self.ASN1_tag.get_codec(pkt.ASN1_codec)
+        try:
+            i,s,remain = codec.check_type_check_len(s)
+            for obj in self.seq:
+                s = obj.dissect(pkt,s)
+            if s:
+                warning("Too many bytes to decode sequence: [%r]" % s) # XXX not reversible!
+            return remain
+        except ASN1_Error,e:
+            raise ASN1F_badsequence(e)
+
+class ASN1F_SET(ASN1F_SEQUENCE):
+    ASN1_tag = ASN1_Class_UNIVERSAL.SET
+
+class ASN1F_SEQUENCE_OF(ASN1F_SEQUENCE):
+    holds_packets = 1
+    islist = 1
+    def __init__(self, name, default, asn1pkt, ASN1_tag=0x30):
+        self.asn1pkt = asn1pkt
+        self.tag = chr(ASN1_tag)
+        self.name = name
+        self.default = default
+    def i2repr(self, pkt, i):
+        if i is None:
+            return []
+        return i
+    def get_fields_list(self):
+        return [self]
+    def set_val(self, pkt, val):
+        ASN1F_field.set_val(self, pkt, val)
+    def is_empty(self, pkt):
+        return ASN1F_field.is_empty(self, pkt)
+    def build(self, pkt):
+        val = getattr(pkt, self.name)
+        if isinstance(val, ASN1_Object) and val.tag == ASN1_Class_UNIVERSAL.RAW:
+            s = val
+        elif val is None:
+            s = ""
+        else:
+            s = "".join(map(str, val ))
+        return self.i2m(pkt, s)
+    def set_val(self, pkt, val):
+        ASN1F_field.set_val(self, pkt, val)
+    def dissect(self, pkt, s):
+        codec = self.ASN1_tag.get_codec(pkt.ASN1_codec)
+        i,s1,remain = codec.check_type_check_len(s)
+        lst = []
+        while s1:
+            try:
+                p = self.asn1pkt(s1)
+            except ASN1F_badsequence,e:
+                lst.append(Raw(s1))
+                break
+            lst.append(p)
+            if Raw in p:
+                s1 = p[Raw].load
+                del(p[Raw].underlayer.payload)
+            else:
+                break
+        self.set_val(pkt, lst)
+        return remain
+    def randval(self):
+        return fuzz(self.asn1pkt())
+    def __repr__(self):
+        return "<%s %s>" % (self.__class__.__name__,self.name)
+
+class ASN1F_PACKET(ASN1F_field):
+    holds_packets = 1
+    def __init__(self, name, default, cls):
+        ASN1_field.__init__(self, name, default)
+        self.cls = cls
+    def i2m(self, pkt, x):
+        if x is None:
+            x = ""
+        return str(x)
+    def extract_packet(self, cls, x):
+        try:
+            c = cls(x)
+        except ASN1F_badsequence:
+            c = Raw(x)
+        cpad = c[Padding]
+        x = ""
+        if cpad is not None:
+            x = cpad.load
+            del(cpad.underlayer.payload)
+        return c,x
+    def m2i(self, pkt, x):
+        return self.extract_packet(self.cls, x)
+
+
+class ASN1F_CHOICE(ASN1F_PACKET):
+    ASN1_tag = ASN1_Class_UNIVERSAL.NONE
+    def __init__(self, name, default, *args):
+        self.name=name
+        self.choice = {}
+        for p in args:
+            self.choice[p.ASN1_root.ASN1_tag] = p
+#        self.context=context
+        self.default=default
+    def m2i(self, pkt, x):
+        if len(x) == 0:
+            return Raw(),""
+            raise ASN1_Error("ASN1F_CHOICE: got empty string")
+        if ord(x[0]) not in self.choice:
+            return Raw(x),"" # XXX return RawASN1 packet ? Raise error 
+            raise ASN1_Error("Decoding Error: choice [%i] not found in %r" % (ord(x[0]), self.choice.keys()))
+
+        z = ASN1F_PACKET.extract_packet(self, self.choice[ord(x[0])], x)
+        return z
+    def randval(self):
+        return RandChoice(*map(lambda x:fuzz(x()), self.choice.values()))
+            
+    
diff --git a/scapy/asn1packet.py b/scapy/asn1packet.py
new file mode 100644
index 0000000000000000000000000000000000000000..e8ce01f3ed676ec728cade123e9a38e442c26dea
--- /dev/null
+++ b/scapy/asn1packet.py
@@ -0,0 +1,15 @@
+from packet import *
+
+class ASN1_Packet(Packet):
+    ASN1_root = None
+    ASN1_codec = None    
+    def init_fields(self):
+        flist = self.ASN1_root.get_fields_list()
+        self.do_init_fields(flist)
+        self.fields_desc = flist    
+    def do_build(self):
+        return self.ASN1_root.build(self)    
+    def do_dissect(self, x):
+        return self.ASN1_root.dissect(self, x)
+        
+
diff --git a/scapy/automaton.py b/scapy/automaton.py
new file mode 100644
index 0000000000000000000000000000000000000000..5893c957c2bc54e842736e1ed8c5e033dfb929cd
--- /dev/null
+++ b/scapy/automaton.py
@@ -0,0 +1,321 @@
+import types,itertools,time
+from select import select
+from config import conf
+
+##############
+## Automata ##
+##############
+
+class ATMT:
+    STATE = "State"
+    ACTION = "Action"
+    CONDITION = "Condition"
+    RECV = "Receive condition"
+    TIMEOUT = "Timeout condition"
+
+    class NewStateRequested(Exception):
+        def __init__(self, state_func, automaton, *args, **kargs):
+            self.func = state_func
+            self.state = state_func.atmt_state
+            self.initial = state_func.atmt_initial
+            self.error = state_func.atmt_error
+            self.final = state_func.atmt_final
+            Exception.__init__(self, "Request state [%s]" % self.state)
+            self.automaton = automaton
+            self.args = args
+            self.kargs = kargs
+            self.action_parameters() # init action parameters
+        def action_parameters(self, *args, **kargs):
+            self.action_args = args
+            self.action_kargs = kargs
+            return self
+        def run(self):
+            return self.func(self.automaton, *self.args, **self.kargs)
+
+    @staticmethod
+    def state(initial=0,final=0,error=0):
+        def deco(f,initial=initial, final=final):
+            f.atmt_type = ATMT.STATE
+            f.atmt_state = f.func_name
+            f.atmt_initial = initial
+            f.atmt_final = final
+            f.atmt_error = error
+            def state_wrapper(self, *args, **kargs):
+                return ATMT.NewStateRequested(f, self, *args, **kargs)
+
+            state_wrapper.func_name = "%s_wrapper" % f.func_name
+            state_wrapper.atmt_type = ATMT.STATE
+            state_wrapper.atmt_state = f.func_name
+            state_wrapper.atmt_initial = initial
+            state_wrapper.atmt_final = final
+            state_wrapper.atmt_error = error
+            state_wrapper.atmt_origfunc = f
+            return state_wrapper
+        return deco
+    @staticmethod
+    def action(cond, prio=0):
+        def deco(f,cond=cond):
+            if not hasattr(f,"atmt_type"):
+                f.atmt_cond = {}
+            f.atmt_type = ATMT.ACTION
+            f.atmt_cond[cond.atmt_condname] = prio
+            return f
+        return deco
+    @staticmethod
+    def condition(state, prio=0):
+        def deco(f, state=state):
+            f.atmt_type = ATMT.CONDITION
+            f.atmt_state = state.atmt_state
+            f.atmt_condname = f.func_name
+            f.atmt_prio = prio
+            return f
+        return deco
+    @staticmethod
+    def receive_condition(state, prio=0):
+        def deco(f, state=state):
+            f.atmt_type = ATMT.RECV
+            f.atmt_state = state.atmt_state
+            f.atmt_condname = f.func_name
+            f.atmt_prio = prio
+            return f
+        return deco
+    @staticmethod
+    def timeout(state, timeout):
+        def deco(f, state=state, timeout=timeout):
+            f.atmt_type = ATMT.TIMEOUT
+            f.atmt_state = state.atmt_state
+            f.atmt_timeout = timeout
+            f.atmt_condname = f.func_name
+            return f
+        return deco
+
+
+class Automaton_metaclass(type):
+    def __new__(cls, name, bases, dct):
+        cls = super(Automaton_metaclass, cls).__new__(cls, name, bases, dct)
+        cls.states={}
+        cls.state = None
+        cls.recv_conditions={}
+        cls.conditions={}
+        cls.timeout={}
+        cls.actions={}
+        cls.initial_states=[]
+
+        members = {}
+        classes = [cls]
+        while classes:
+            c = classes.pop(0) # order is important to avoid breaking method overloading
+            classes += list(c.__bases__)
+            for k,v in c.__dict__.iteritems():
+                if k not in members:
+                    members[k] = v
+
+        decorated = [v for v in members.itervalues()
+                     if type(v) is types.FunctionType and hasattr(v, "atmt_type")]
+        
+        for m in decorated:
+            if m.atmt_type == ATMT.STATE:
+                s = m.atmt_state
+                cls.states[s] = m
+                cls.recv_conditions[s]=[]
+                cls.conditions[s]=[]
+                cls.timeout[s]=[]
+                if m.atmt_initial:
+                    cls.initial_states.append(m)
+            elif m.atmt_type in [ATMT.CONDITION, ATMT.RECV, ATMT.TIMEOUT]:
+                cls.actions[m.atmt_condname] = []
+    
+        for m in decorated:
+            if m.atmt_type == ATMT.CONDITION:
+                cls.conditions[m.atmt_state].append(m)
+            elif m.atmt_type == ATMT.RECV:
+                cls.recv_conditions[m.atmt_state].append(m)
+            elif m.atmt_type == ATMT.TIMEOUT:
+                cls.timeout[m.atmt_state].append((m.atmt_timeout, m))
+            elif m.atmt_type == ATMT.ACTION:
+                for c in m.atmt_cond:
+                    cls.actions[c].append(m)
+            
+
+        for v in cls.timeout.itervalues():
+            v.sort(lambda (t1,f1),(t2,f2): cmp(t1,t2))
+            v.append((None, None))
+        for v in itertools.chain(cls.conditions.itervalues(),
+                                 cls.recv_conditions.itervalues()):
+            v.sort(lambda c1,c2: cmp(c1.atmt_prio,c2.atmt_prio))
+        for condname,actlst in cls.actions.iteritems():
+            actlst.sort(lambda c1,c2: cmp(c1.atmt_cond[condname], c2.atmt_cond[condname]))
+
+        return cls
+
+        
+    def graph(self, **kargs):
+        s = 'digraph "%s" {\n'  % self.__class__.__name__
+        
+        se = "" # Keep initial nodes at the begining for better rendering
+        for st in self.states.itervalues():
+            if st.atmt_initial:
+                se = ('\t"%s" [ style=filled, fillcolor=blue, shape=box, root=true];\n' % st.atmt_state)+se
+            elif st.atmt_final:
+                se += '\t"%s" [ style=filled, fillcolor=green, shape=octagon ];\n' % st.atmt_state
+            elif st.atmt_error:
+                se += '\t"%s" [ style=filled, fillcolor=red, shape=octagon ];\n' % st.atmt_state
+        s += se
+
+        for st in self.states.values():
+            for n in st.atmt_origfunc.func_code.co_names+st.atmt_origfunc.func_code.co_consts:
+                if n in self.states:
+                    s += '\t"%s" -> "%s" [ color=green ];\n' % (st.atmt_state,n)
+            
+
+        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()]:
+            for f in v:
+                for n in f.func_code.co_names+f.func_code.co_consts:
+                    if n in self.states:
+                        l = f.atmt_condname
+                        for x in self.actions[f.atmt_condname]:
+                            l += "\\l>[%s]" % x.func_name
+                        s += '\t"%s" -> "%s" [label="%s", color=%s];\n' % (k,n,l,c)
+        for k,v in self.timeout.iteritems():
+            for t,f in v:
+                if f is None:
+                    continue
+                for n in f.func_code.co_names+f.func_code.co_consts:
+                    if n in self.states:
+                        l = "%s/%.1fs" % (f.atmt_condname,t)                        
+                        for x in self.actions[f.atmt_condname]:
+                            l += "\\l>[%s]" % x.func_name
+                        s += '\t"%s" -> "%s" [label="%s",color=blue];\n' % (k,n,l)
+        s += "}\n"
+        return do_graph(s, **kargs)
+        
+
+
+class Automaton:
+    __metaclass__ = Automaton_metaclass
+
+    def __init__(self, *args, **kargs):
+        self.debug_level=0
+        self.init_args=args
+        self.init_kargs=kargs
+        self.parse_args(*args, **kargs)
+
+    def debug(self, lvl, msg):
+        if self.debug_level >= lvl:
+            log_interactive.debug(msg)
+            
+
+
+
+    class ErrorState(Exception):
+        def __init__(self, msg, result=None):
+            Exception.__init__(self, msg)
+            self.result = result
+    class Stuck(ErrorState):
+        pass
+
+    def parse_args(self, debug=0, store=1, **kargs):
+        self.debug_level=debug
+        self.socket_kargs = kargs
+        self.store_packets = store
+        
+
+    def master_filter(self, pkt):
+        return True
+
+    def run_condition(self, cond, *args, **kargs):
+        try:
+            cond(self,*args, **kargs)
+        except ATMT.NewStateRequested, state_req:
+            self.debug(2, "%s [%s] taken to state [%s]" % (cond.atmt_type, cond.atmt_condname, state_req.state))
+            if cond.atmt_type == ATMT.RECV:
+                self.packets.append(args[0])
+            for action in self.actions[cond.atmt_condname]:
+                self.debug(2, "   + Running action [%s]" % action.func_name)
+                action(self, *state_req.action_args, **state_req.action_kargs)
+            raise
+        else:
+            self.debug(2, "%s [%s] not taken" % (cond.atmt_type, cond.atmt_condname))
+            
+
+    def run(self, *args, **kargs):
+        # Update default parameters
+        a = args+self.init_args[len(args):]
+        k = self.init_kargs
+        k.update(kargs)
+        self.parse_args(*a,**k)
+
+        # Start the automaton
+        self.state=self.initial_states[0](self)
+        self.send_sock = conf.L3socket()
+        l = conf.L2listen(**self.socket_kargs)
+        self.packets = PacketList(name="session[%s]"%self.__class__.__name__)
+        while 1:
+            try:
+                self.debug(1, "## state=[%s]" % self.state.state)
+
+                # Entering a new state. First, call new state function
+                state_output = self.state.run()
+                if self.state.error:
+                    raise self.ErrorState("Reached %s: [%r]" % (self.state.state, state_output), result=state_output)
+                if self.state.final:
+                    return state_output
+
+                if state_output is None:
+                    state_output = ()
+                elif type(state_output) is not list:
+                    state_output = state_output,
+                
+                # Then check immediate conditions
+                for cond in self.conditions[self.state.state]:
+                    self.run_condition(cond, *state_output)
+
+                # If still there and no conditions left, we are stuck!
+                if ( len(self.recv_conditions[self.state.state]) == 0
+                     and len(self.timeout[self.state.state]) == 1 ):
+                    raise self.Stuck("stuck in [%s]" % self.state.state,result=state_output)
+
+                # Finally listen and pay attention to timeouts
+                expirations = iter(self.timeout[self.state.state])
+                next_timeout,timeout_func = expirations.next()
+                t0 = time.time()
+                
+                while 1:
+                    t = time.time()-t0
+                    if next_timeout is not None:
+                        if next_timeout <= t:
+                            self.run_condition(timeout_func, *state_output)
+                            next_timeout,timeout_func = expirations.next()
+                    if next_timeout is None:
+                        remain = None
+                    else:
+                        remain = next_timeout-t
+    
+                    r,_,_ = select([l],[],[],remain)
+                    if l in r:
+                        pkt = l.recv(MTU)
+                        if pkt is not None:
+                            if self.master_filter(pkt):
+                                self.debug(3, "RECVD: %s" % pkt.summary())
+                                for rcvcond in self.recv_conditions[self.state.state]:
+                                    self.run_condition(rcvcond, pkt, *state_output)
+                            else:
+                                self.debug(4, "FILTR: %s" % pkt.summary())
+
+            except ATMT.NewStateRequested,state_req:
+                self.debug(2, "switching from [%s] to [%s]" % (self.state.state,state_req.state))
+                self.state = state_req
+            except KeyboardInterrupt:
+                self.debug(1,"Interrupted by user")
+                break
+
+    def my_send(self, pkt):
+        self.send_sock.send(pkt)
+
+    def send(self, pkt):
+        self.my_send(pkt)
+        self.debug(3,"SENT : %s" % pkt.summary())
+        self.packets.append(pkt.copy())
+
+
+        
diff --git a/scapy/autorun.py b/scapy/autorun.py
new file mode 100644
index 0000000000000000000000000000000000000000..4fc93fd774c2a6868d78fc02a3fa71f1f6877a78
--- /dev/null
+++ b/scapy/autorun.py
@@ -0,0 +1,129 @@
+import code,sys
+from error import Scapy_Exception
+
+#########################
+##### Autorun stuff #####
+#########################
+
+class StopAutorun(Scapy_Exception):
+    code_run = ""
+
+class ScapyAutorunInterpreter(code.InteractiveInterpreter):
+    def __init__(self, *args, **kargs):
+        code.InteractiveInterpreter.__init__(self, *args, **kargs)
+        self.error = 0
+    def showsyntaxerror(self, *args, **kargs):
+        self.error = 1
+        return code.InteractiveInterpreter.showsyntaxerror(self, *args, **kargs)
+    def showtraceback(self, *args, **kargs):
+        self.error = 1
+        exc_type, exc_value, exc_tb = sys.exc_info()
+        if isinstance(exc_value, StopAutorun):
+            raise exc_value
+        return code.InteractiveInterpreter.showtraceback(self, *args, **kargs)
+
+
+def autorun_commands(cmds,my_globals=None,verb=0):
+    sv = conf.verb
+    import __builtin__
+    try:
+        try:
+            if my_globals is None:
+                my_globals = globals()
+            conf.verb = verb
+            interp = ScapyAutorunInterpreter(my_globals)
+            cmd = ""
+            cmds = cmds.splitlines()
+            cmds.append("") # ensure we finish multiline commands
+            cmds.reverse()
+            __builtin__.__dict__["_"] = None
+            while 1:
+                if cmd:
+                    sys.stderr.write(sys.__dict__.get("ps2","... "))
+                else:
+                    sys.stderr.write(str(sys.__dict__.get("ps1",ColorPrompt())))
+                    
+                l = cmds.pop()
+                print l
+                cmd += "\n"+l
+                if interp.runsource(cmd):
+                    continue
+                if interp.error:
+                    return 0
+                cmd = ""
+                if len(cmds) <= 1:
+                    break
+        except SystemExit:
+            pass
+    finally:
+        conf.verb = sv
+    return _
+
+def autorun_get_interactive_session(cmds, **kargs):
+    class StringWriter:
+        def __init__(self):
+            self.s = ""
+        def write(self, x):
+            self.s += x
+            
+    sw = StringWriter()
+    sstdout,sstderr = sys.stdout,sys.stderr
+    try:
+        try:
+            sys.stdout = sys.stderr = sw
+            res = autorun_commands(cmds, **kargs)
+        except StopAutorun,e:
+            e.code_run = sw.s
+            raise
+    finally:
+        sys.stdout,sys.stderr = sstdout,sstderr
+    return sw.s,res
+
+def autorun_get_text_interactive_session(cmds, **kargs):
+    ct = conf.color_theme
+    try:
+        conf.color_theme = NoTheme()
+        s,res = autorun_get_interactive_session(cmds, **kargs)
+    finally:
+        conf.color_theme = ct
+    return s,res
+
+def autorun_get_ansi_interactive_session(cmds, **kargs):
+    ct = conf.color_theme
+    try:
+        conf.color_theme = DefaultTheme()
+        s,res = autorun_get_interactive_session(cmds, **kargs)
+    finally:
+        conf.color_theme = ct
+    return s,res
+
+def autorun_get_html_interactive_session(cmds, **kargs):
+    ct = conf.color_theme
+    to_html = lambda s: s.replace("<","&lt;").replace(">","&gt;").replace("#[#","<").replace("#]#",">")
+    try:
+        try:
+            conf.color_theme = HTMLTheme2()
+            s,res = autorun_get_interactive_session(cmds, **kargs)
+        except StopAutorun,e:
+            e.code_run = to_html(e.code_run)
+            raise
+    finally:
+        conf.color_theme = ct
+    
+    return to_html(s),res
+
+def autorun_get_latex_interactive_session(cmds, **kargs):
+    ct = conf.color_theme
+    to_latex = lambda s: tex_escape(s).replace("@[@","{").replace("@]@","}").replace("@`@","\\")
+    try:
+        try:
+            conf.color_theme = LatexTheme2()
+            s,res = autorun_get_interactive_session(cmds, **kargs)
+        except StopAutorun,e:
+            e.code_run = to_latex(e.code_run)
+            raise
+    finally:
+        conf.color_theme = ct
+    return to_latex(s),res
+
+
diff --git a/scapy/ber.py b/scapy/ber.py
new file mode 100644
index 0000000000000000000000000000000000000000..6d0e748726a5059a86ed3f2886a08a6c91e34517
--- /dev/null
+++ b/scapy/ber.py
@@ -0,0 +1,300 @@
+from asn1 import ASN1_Decoding_Error,ASN1_BadTag_Decoding_Error,ASN1_Codecs,ASN1_Class_UNIVERSAL
+
+##################
+## BER encoding ##
+##################
+
+
+
+#####[ BER tools ]#####
+
+
+class BER_Exception(Exception):
+    pass
+
+class BER_Decoding_Error(ASN1_Decoding_Error):
+    def __init__(self, msg, decoded=None, remaining=None):
+        Exception.__init__(self, msg)
+        self.remaining = remaining
+        self.decoded = decoded
+    def __str__(self):
+        s = Exception.__str__(self)
+        if isinstance(self.decoded, BERcodec_Object):
+            s+="\n### Already decoded ###\n%s" % self.decoded.strshow()
+        else:
+            s+="\n### Already decoded ###\n%r" % self.decoded
+        s+="\n### Remaining ###\n%r" % self.remaining
+        return s
+
+class BER_BadTag_Decoding_Error(BER_Decoding_Error, ASN1_BadTag_Decoding_Error):
+    pass
+
+def BER_len_enc(l, size=0):
+        if l <= 127 and size==0:
+            return chr(l)
+        s = ""
+        while l or size>0:
+            s = chr(l&0xff)+s
+            l >>= 8L
+            size -= 1
+        if len(s) > 127:
+            raise BER_Exception("BER_len_enc: Length too long (%i) to be encoded [%r]" % (len(s),s))
+        return chr(len(s)|0x80)+s
+def BER_len_dec(s):
+        l = ord(s[0])
+        if not l & 0x80:
+            return l,s[1:]
+        l &= 0x7f
+        if len(s) <= l:
+            raise BER_Decoding_Error("BER_len_dec: Got %i bytes while expecting %i" % (len(s)-1, l),remaining=s)
+        ll = 0L
+        for c in s[1:l+1]:
+            ll <<= 8L
+            ll |= ord(c)
+        return ll,s[l+1:]
+        
+def BER_num_enc(l, size=1):
+        x=[]
+        while l or size>0:
+            x.insert(0, l & 0x7f)
+            if len(x) > 1:
+                x[0] |= 0x80
+            l >>= 7
+            size -= 1
+        return "".join([chr(k) for k in x])
+def BER_num_dec(s):
+        x = 0
+        for i in range(len(s)):
+            c = ord(s[i])
+            x <<= 7
+            x |= c&0x7f
+            if not c&0x80:
+                break
+        if c&0x80:
+            raise BER_Decoding_Error("BER_num_dec: unfinished number description", remaining=s)
+        return x, s[i+1:]
+
+#####[ BER classes ]#####
+
+class BERcodec_metaclass(type):
+    def __new__(cls, name, bases, dct):
+        c = super(BERcodec_metaclass, cls).__new__(cls, name, bases, dct)
+        try:
+            c.tag.register(c.codec, c)
+        except:
+            warning("Error registering %r for %r" % (c.tag, c.codec))
+        return c
+
+
+class BERcodec_Object:
+    __metaclass__ = BERcodec_metaclass
+    codec = ASN1_Codecs.BER
+    tag = ASN1_Class_UNIVERSAL.ANY
+
+    @classmethod
+    def asn1_object(cls, val):
+        return cls.tag.asn1_object(val)
+
+    @classmethod
+    def check_string(cls, s):
+        if not s:
+            raise BER_Decoding_Error("%s: Got empty object while expecting tag %r" %
+                                     (cls.__name__,cls.tag), remaining=s)        
+    @classmethod
+    def check_type(cls, s):
+        cls.check_string(s)
+        if cls.tag != ord(s[0]):
+            raise BER_BadTag_Decoding_Error("%s: Got tag [%i/%#x] while expecting %r" %
+                                            (cls.__name__, ord(s[0]), ord(s[0]),cls.tag), remaining=s)
+        return s[1:]
+    @classmethod
+    def check_type_get_len(cls, s):
+        s2 = cls.check_type(s)
+        if not s2:
+            raise BER_Decoding_Error("%s: No bytes while expecting a length" %
+                                     cls.__name__, remaining=s)
+        return BER_len_dec(s2)
+    @classmethod
+    def check_type_check_len(cls, s):
+        l,s3 = cls.check_type_get_len(s)
+        if len(s3) < l:
+            raise BER_Decoding_Error("%s: Got %i bytes while expecting %i" %
+                                     (cls.__name__, len(s3), l), remaining=s)
+        return l,s3[:l],s3[l:]
+
+    @classmethod
+    def do_dec(cls, s, context=None, safe=False):
+        if context is None:
+            context = cls.tag.context
+        cls.check_string(s)
+        p = ord(s[0])
+        if p not in context:
+            t = s
+            if len(t) > 18:
+                t = t[:15]+"..."
+            raise BER_Decoding_Error("Unknown prefix [%02x] for [%r]" % (p,t), remaining=s)
+        codec = context[p].get_codec(ASN1_Codecs.BER)
+        return codec.dec(s,context,safe)
+
+    @classmethod
+    def dec(cls, s, context=None, safe=False):
+        if not safe:
+            return cls.do_dec(s, context, safe)
+        try:
+            return cls.do_dec(s, context, safe)
+        except BER_BadTag_Decoding_Error,e:
+            o,remain = BERcodec_Object.dec(e.remaining, context, safe)
+            return ASN1_BADTAG(o),remain
+        except BER_Decoding_Error, e:
+            return ASN1_DECODING_ERROR(s, exc=e),""
+        except ASN1_Error, e:
+            return ASN1_DECODING_ERROR(s, exc=e),""
+
+    @classmethod
+    def safedec(cls, s, context=None):
+        return cls.dec(s, context, safe=True)
+
+
+    @classmethod
+    def enc(cls, s):
+        if type(s) is str:
+            return BERcodec_STRING.enc(s)
+        else:
+            return BERcodec_INTEGER.enc(int(s))
+
+            
+
+ASN1_Codecs.BER.register_stem(BERcodec_Object)
+
+
+class BERcodec_INTEGER(BERcodec_Object):
+    tag = ASN1_Class_UNIVERSAL.INTEGER
+    @classmethod
+    def enc(cls, i):
+        s = []
+        while 1:
+            s.append(i&0xff)
+            if -127 <= i < 0:
+                break
+            if 128 <= i <= 255:
+                s.append(0)
+            i >>= 8
+            if not i:
+                break
+        s = map(chr, s)
+        s.append(BER_len_enc(len(s)))
+        s.append(chr(cls.tag))
+        s.reverse()
+        return "".join(s)
+    @classmethod
+    def do_dec(cls, s, context=None, safe=False):
+        l,s,t = cls.check_type_check_len(s)
+        x = 0L
+        if s:
+            if ord(s[0])&0x80: # negative int
+                x = -1L
+            for c in s:
+                x <<= 8
+                x |= ord(c)
+        return cls.asn1_object(x),t
+    
+
+class BERcodec_BOOLEAN(BERcodec_INTEGER):
+    tag = ASN1_Class_UNIVERSAL.BOOLEAN
+
+class BERcodec_NULL(BERcodec_INTEGER):
+    tag = ASN1_Class_UNIVERSAL.NULL
+    @classmethod
+    def enc(cls, i):
+        if i == 0:
+            return chr(cls.tag)+"\0"
+        else:
+            return super(cls,cls).enc(i)
+
+class BERcodec_STRING(BERcodec_Object):
+    tag = ASN1_Class_UNIVERSAL.STRING
+    @classmethod
+    def enc(cls,s):
+        return chr(cls.tag)+BER_len_enc(len(s))+s
+    @classmethod
+    def do_dec(cls, s, context=None, safe=False):
+        l,s,t = cls.check_type_check_len(s)
+        return cls.tag.asn1_object(s),t
+
+class BERcodec_BIT_STRING(BERcodec_STRING):
+    tag = ASN1_Class_UNIVERSAL.BIT_STRING
+
+class BERcodec_PRINTABLE_STRING(BERcodec_STRING):
+    tag = ASN1_Class_UNIVERSAL.PRINTABLE_STRING
+
+class BERcodec_T61_STRING (BERcodec_STRING):
+    tag = ASN1_Class_UNIVERSAL.T61_STRING
+
+class BERcodec_IA5_STRING(BERcodec_STRING):
+    tag = ASN1_Class_UNIVERSAL.IA5_STRING
+
+class BERcodec_UTC_TIME(BERcodec_STRING):
+    tag = ASN1_Class_UNIVERSAL.UTC_TIME
+
+class BERcodec_TIME_TICKS(BERcodec_INTEGER):
+    tag = ASN1_Class_UNIVERSAL.TIME_TICKS
+
+class BERcodec_COUNTER32(BERcodec_INTEGER):
+    tag = ASN1_Class_UNIVERSAL.COUNTER32
+
+class BERcodec_SEQUENCE(BERcodec_Object):
+    tag = ASN1_Class_UNIVERSAL.SEQUENCE
+    @classmethod
+    def enc(cls, l):
+        if type(l) is not str:
+            l = "".join(map(lambda x: x.enc(cls.codec), l))
+        return chr(cls.tag)+BER_len_enc(len(l))+l
+    @classmethod
+    def do_dec(cls, s, context=None, safe=False):
+        if context is None:
+            context = cls.tag.context
+        l,st = cls.check_type_get_len(s) # we may have len(s) < l
+        s,t = st[:l],st[l:]
+        obj = []
+        while s:
+            try:
+                o,s = BERcodec_Object.dec(s, context, safe)
+            except BER_Decoding_Error, err:
+                err.remaining += t
+                if err.decoded is not None:
+                    obj.append(err.decoded)
+                err.decoded = obj
+                raise 
+            obj.append(o)
+        if len(st) < l:
+            raise BER_Decoding_Error("Not enough bytes to decode sequence", decoded=obj)
+        return cls.asn1_object(obj),t
+
+class BERcodec_SET(BERcodec_SEQUENCE):
+    tag = ASN1_Class_UNIVERSAL.SET
+
+
+class BERcodec_OID(BERcodec_Object):
+    tag = ASN1_Class_UNIVERSAL.OID
+
+    @classmethod
+    def enc(cls, oid):
+        lst = [int(x) for x in oid.strip(".").split(".")]
+        if len(lst) >= 2:
+            lst[1] += 40*lst[0]
+            del(lst[0])
+        s = "".join([BER_num_enc(k) for k in lst])
+        return chr(cls.tag)+BER_len_enc(len(s))+s
+    @classmethod
+    def do_dec(cls, s, context=None, safe=False):
+        l,s,t = cls.check_type_check_len(s)
+        lst = []
+        while s:
+            l,s = BER_num_dec(s)
+            lst.append(l)
+        if (len(lst) > 0):
+            lst.insert(0,lst[0]/40)
+            lst[1] %= 40
+        return cls.asn1_object(".".join([str(k) for k in lst])), t
+
+
diff --git a/scapy/config.py b/scapy/config.py
new file mode 100644
index 0000000000000000000000000000000000000000..59a37ac6f31dd82cb641bc8fb461a325fa469492
--- /dev/null
+++ b/scapy/config.py
@@ -0,0 +1,167 @@
+import os
+from arch import *
+from data import *
+from themes import *
+
+############
+## Config ##
+############
+
+class ConfClass:
+    def configure(self, cnf):
+        self.__dict__ = cnf.__dict__.copy()
+    def __repr__(self):
+        return str(self)
+    def __str__(self):
+        s="Version    = %s\n" % VERSION
+        keys = self.__class__.__dict__.copy()
+        keys.update(self.__dict__)
+        keys = keys.keys()
+        keys.sort()
+        for i in keys:
+            if i[0] != "_":
+                s += "%-10s = %s\n" % (i, repr(getattr(self, i)))
+        return s[:-1]
+    
+class ProgPath(ConfClass):
+    pdfreader = "acroread"
+    psreader = "gv"
+    dot = "dot"
+    display = "display"
+    tcpdump = "tcpdump"
+    tcpreplay = "tcpreplay"
+    hexedit = "hexer"
+    wireshark = "wireshark"
+    
+class Resolve:
+    def __init__(self):
+        self.fields = {}
+    def add(self, *flds):
+        for fld in flds:
+            self.fields[fld]=None
+    def remove(self, *flds):
+        for fld in flds:
+            if fld in self.fields:
+                del(self.fields[fld])
+    def __contains__(self, elt):
+        return elt in self.fields
+    def __repr__(self):
+        return "<Resolve [%s]>" %  " ".join(str(x) for x in self.fields)
+    
+
+class Num2Layer:
+    def __init__(self):
+        self.num2layer = {}
+        self.layer2num = {}
+        
+    def register(self, num, layer):
+        self.register_num2layer(num, layer)
+        self.register_layer2num(num, layer)
+        
+    def register_num2layer(self, num, layer):
+        self.num2layer[num] = layer
+    def register_layer2num(self, num, layer):
+        self.layer2num[layer] = num
+
+    def __getitem__(self, item):
+        if isinstance(item, Packet_metaclass):
+            return self.layer2num[item]
+        return self.num2layer[item]
+    def __contains__(self, item):
+        if isinstance(item, Packet_metaclass):
+            return item in self.layer2num
+        return item in self.num2layer
+    def get(self, item, default=None):
+        if item in self:
+            return self[item]
+        return default
+    
+    def __repr__(self):
+        lst = []
+        for num,layer in self.num2layer.iteritems():
+            if layer in self.layer2num and self.layer2num[layer] == num:
+                dir = "<->"
+            else:
+                dir = " ->"
+            lst.append((num,"%#6x %s %-20s (%s)" % (num,dir,layer.__name__,layer.name)))
+        for layer,num in self.layer2num.iteritems():
+            if num not in self.num2layer or self.num2layer[num] != layer:
+                lst.append((num,"%#6x <-  %-20s (%s)" % (num,layer.__name__,layer.name)))
+        lst.sort()
+        return "\n".join(y for x,y in lst)
+            
+
+
+
+class Conf(ConfClass):
+    """This object contains the configuration of scapy.
+session  : filename where the session will be saved
+stealth  : if 1, prevents any unwanted packet to go out (ARP, DNS, ...)
+checkIPID: if 0, doesn't check that IPID matches between IP sent and ICMP IP citation received
+           if 1, checks that they either are equal or byte swapped equals (bug in some IP stacks)
+           if 2, strictly checks that they are equals
+checkIPsrc: if 1, checks IP src in IP and ICMP IP citation match (bug in some NAT stacks)
+check_TCPerror_seqack: if 1, also check that TCP seq and ack match the ones in ICMP citation
+iff      : selects the default output interface for srp() and sendp(). default:"eth0")
+verb     : level of verbosity, from 0 (almost mute) to 3 (verbose)
+promisc  : default mode for listening socket (to get answers if you spoof on a lan)
+sniff_promisc : default mode for sniff()
+filter   : bpf filter added to every sniffing socket to exclude traffic from analysis
+histfile : history file
+padding  : includes padding in desassembled packets
+except_filter : BPF filter for packets to ignore
+debug_match : when 1, store received packet that are not matched into debug.recv
+route    : holds the Scapy routing table and provides methods to manipulate it
+warning_threshold : how much time between warnings from the same place
+ASN1_default_codec: Codec used by default for ASN1 objects
+mib      : holds MIB direct access dictionnary
+resolve   : holds list of fields for which resolution should be done
+noenum    : holds list of enum fields for which conversion to string should NOT be done
+AS_resolver: choose the AS resolver class to use
+extensions_paths: path or list of paths where extensions are to be looked for
+"""
+    session = ""  
+    stealth = "not implemented"
+    iface = get_working_if()
+    checkIPID = 0
+    checkIPsrc = 1
+    checkIPaddr = 1
+    check_TCPerror_seqack = 0
+    verb = 2
+    prompt = ">>> "
+    promisc = 1
+    sniff_promisc = 1
+    l2types = Num2Layer()
+    l3types = Num2Layer()
+    L3socket = None
+    L2socket = None
+    L2listen = None
+    histfile = os.path.join(os.environ["HOME"], ".scapy_history")
+    padding = 1
+    p0f_base ="/etc/p0f/p0f.fp"
+    queso_base ="/etc/queso.conf"
+    nmap_base ="/usr/share/nmap/nmap-os-fingerprints"
+    IPCountry_base = "GeoIPCountry4Scapy.gz"
+    countryLoc_base = "countryLoc.csv"
+    gnuplot_world = "world.dat"
+    except_filter = ""
+    debug_match = 0
+    wepkey = ""
+    route = None # Filed by arch
+    auto_fragment = 1
+    debug_dissector = 0
+    color_theme = DefaultTheme()
+    warning_threshold = 5
+    prog = ProgPath()
+    resolve = Resolve()
+    noenum = Resolve()
+    ethertypes = ETHER_TYPES
+    protocols = IP_PROTOS
+    services_tcp = TCP_SERVICES
+    services_udp = UDP_SERVICES
+    extensions_paths = "."
+    manufdb = load_manuf("/usr/share/wireshark/wireshark/manuf")   
+
+conf=Conf()
+
+
diff --git a/scapy/dadict.py b/scapy/dadict.py
new file mode 100644
index 0000000000000000000000000000000000000000..2f1cee20bd021a6e7ba192ff0b98f423c9f16b46
--- /dev/null
+++ b/scapy/dadict.py
@@ -0,0 +1,78 @@
+from scapy.error import Scapy_Exception
+
+###############################
+## Direct Access dictionnary ##
+###############################
+
+def fixname(x):
+    if x and x[0] in "0123456789":
+        x = "n_"+x
+    return x.translate("________________________________________________0123456789_______ABCDEFGHIJKLMNOPQRSTUVWXYZ______abcdefghijklmnopqrstuvwxyz_____________________________________________________________________________________________________________________________________")
+
+
+class DADict_Exception(Scapy_Exception):
+    pass
+
+class DADict:
+    def __init__(self, _name="DADict", **kargs):
+        self._name=_name
+        self.__dict__.update(kargs)
+    def fixname(self,val):
+        return fixname(val)
+    def __contains__(self, val):
+        return val in self.__dict__
+    def __getitem__(self, attr):
+        return getattr(self, attr)
+    def __setitem__(self, attr, val):        
+        return setattr(self, self.fixname(attr), val)
+    def __iter__(self):
+        return iter(map(lambda (x,y):y,filter(lambda (x,y):x and x[0]!="_", self.__dict__.items())))
+    def _show(self):
+        for k in self.__dict__.keys():
+            if k and k[0] != "_":
+                print "%10s = %r" % (k,getattr(self,k))
+    def __repr__(self):
+        return "<%s/ %s>" % (self._name," ".join(filter(lambda x:x and x[0]!="_",self.__dict__.keys())))
+
+    def _branch(self, br, uniq=0):
+        if uniq and br._name in self:
+            raise DADict_Exception("DADict: [%s] already branched in [%s]" % (br._name, self._name))
+        self[br._name] = br
+
+    def _my_find(self, *args, **kargs):
+        if args and self._name not in args:
+            return False
+        for k in kargs:
+            if k not in self or self[k] != kargs[k]:
+                return False
+        return True
+    
+    def _find(self, *args, **kargs):
+         return self._recurs_find((), *args, **kargs)
+    def _recurs_find(self, path, *args, **kargs):
+        if self in path:
+            return None
+        if self._my_find(*args, **kargs):
+            return self
+        for o in self:
+            if isinstance(o, DADict):
+                p = o._recurs_find(path+(self,), *args, **kargs)
+                if p is not None:
+                    return p
+        return None
+    def _find_all(self, *args, **kargs):
+        return self._recurs_find_all((), *args, **kargs)
+    def _recurs_find_all(self, path, *args, **kargs):
+        r = []
+        if self in path:
+            return r
+        if self._my_find(*args, **kargs):
+            r.append(self)
+        for o in self:
+            if isinstance(o, DADict):
+                p = o._recurs_find_all(path+(self,), *args, **kargs)
+                r += p
+        return r
+    def keys(self):
+        return filter(lambda x:x and x[0]!="_", self.__dict__.keys())
+        
diff --git a/scapy/data.py b/scapy/data.py
new file mode 100644
index 0000000000000000000000000000000000000000..889b66c502c2c8b961cd3c1f7d2129acbf8f5f25
--- /dev/null
+++ b/scapy/data.py
@@ -0,0 +1,230 @@
+import re
+from dadict import DADict
+
+############
+## Consts ##
+############
+
+ETHER_ANY = "\x00"*6
+ETHER_BROADCAST = "\xff"*6
+
+ETH_P_ALL = 3
+ETH_P_IP = 0x800
+ETH_P_ARP = 0x806
+
+# From net/if_arp.h
+ARPHDR_ETHER = 1
+ARPHDR_METRICOM = 23
+ARPHDR_PPP = 512
+ARPHDR_LOOPBACK = 772
+ARPHDR_TUN = 65534
+
+# From bits/ioctls.h
+SIOCGIFHWADDR  = 0x8927          # Get hardware address    
+SIOCGIFADDR    = 0x8915          # get PA address          
+SIOCGIFNETMASK = 0x891b          # get network PA mask     
+SIOCGIFNAME    = 0x8910          # get iface name          
+SIOCSIFLINK    = 0x8911          # set iface channel       
+SIOCGIFCONF    = 0x8912          # get iface list          
+SIOCGIFFLAGS   = 0x8913          # get flags               
+SIOCSIFFLAGS   = 0x8914          # set flags               
+SIOCGIFINDEX   = 0x8933          # name -> if_index mapping
+SIOCGIFCOUNT   = 0x8938          # get number of devices
+SIOCGSTAMP     = 0x8906          # get packet timestamp (as a timeval)
+
+
+# From if.h
+IFF_UP = 0x1               # Interface is up.
+IFF_BROADCAST = 0x2        # Broadcast address valid.
+IFF_DEBUG = 0x4            # Turn on debugging.
+IFF_LOOPBACK = 0x8         # Is a loopback net.
+IFF_POINTOPOINT = 0x10     # Interface is point-to-point link.
+IFF_NOTRAILERS = 0x20      # Avoid use of trailers.
+IFF_RUNNING = 0x40         # Resources allocated.
+IFF_NOARP = 0x80           # No address resolution protocol.
+IFF_PROMISC = 0x100        # Receive all packets.
+
+
+
+# From netpacket/packet.h
+PACKET_ADD_MEMBERSHIP  = 1
+PACKET_DROP_MEMBERSHIP = 2
+PACKET_RECV_OUTPUT     = 3
+PACKET_RX_RING         = 5
+PACKET_STATISTICS      = 6
+PACKET_MR_MULTICAST    = 0
+PACKET_MR_PROMISC      = 1
+PACKET_MR_ALLMULTI     = 2
+
+
+# From bits/socket.h
+SOL_PACKET = 263
+# From asm/socket.h
+SO_ATTACH_FILTER = 26
+SOL_SOCKET = 1
+
+# From net/route.h
+RTF_UP = 0x0001  # Route usable
+RTF_REJECT = 0x0200
+
+# From BSD net/bpf.h
+#BIOCIMMEDIATE=0x80044270
+BIOCIMMEDIATE=-2147204496
+
+MTU = 1600
+
+ 
+# file parsing to get some values :
+
+def load_protocols(filename):
+    spaces = re.compile("[ \t]+|\n")
+    dct = DADict(_name=filename)
+    try:
+        for l in open(filename):
+            try:
+                shrp = l.find("#")
+                if  shrp >= 0:
+                    l = l[:shrp]
+                l = l.strip()
+                if not l:
+                    continue
+                lt = tuple(re.split(spaces, l))
+                if len(lt) < 2 or not lt[0]:
+                    continue
+                dct[lt[0]] = int(lt[1])
+            except Exception,e:
+                log_loading.info("Couldn't parse file [%s]: line [%r] (%s)" % (filename,l,e))
+    except IOError:
+        log_loading.info("Can't open /etc/protocols file")
+    return dct
+
+IP_PROTOS=load_protocols("/etc/protocols")
+
+def load_ethertypes(filename):
+    spaces = re.compile("[ \t]+|\n")
+    dct = DADict(_name=filename)
+    try:
+        f=open(filename)
+        for l in f:
+            try:
+                shrp = l.find("#")
+                if  shrp >= 0:
+                    l = l[:shrp]
+                l = l.strip()
+                if not l:
+                    continue
+                lt = tuple(re.split(spaces, l))
+                if len(lt) < 2 or not lt[0]:
+                    continue
+                dct[lt[0]] = int(lt[1], 16)
+            except Exception,e:
+                log_loading.info("Couldn't parse file [%s]: line [%r] (%s)" % (filename,l,e))
+        f.close()
+    except IOError,msg:
+        pass
+    return dct
+
+ETHER_TYPES=load_ethertypes("/etc/ethertypes")
+
+def load_services(filename):
+    spaces = re.compile("[ \t]+|\n")
+    tdct=DADict(_name="%s-tcp"%filename)
+    udct=DADict(_name="%s-udp"%filename)
+    try:
+        f=open(filename)
+        for l in f:
+            try:
+                shrp = l.find("#")
+                if  shrp >= 0:
+                    l = l[:shrp]
+                l = l.strip()
+                if not l:
+                    continue
+                lt = tuple(re.split(spaces, l))
+                if len(lt) < 2 or not lt[0]:
+                    continue
+                if lt[1].endswith("/tcp"):
+                    tdct[lt[0]] = int(lt[1].split('/')[0])
+                elif lt[1].endswith("/udp"):
+                    udct[lt[0]] = int(lt[1].split('/')[0])
+            except Exception,e:
+                log_loading.warning("Couldn't file [%s]: line [%r] (%s)" % (filename,l,e))
+        f.close()
+    except IOError:
+        log_loading.info("Can't open /etc/services file")
+    return tdct,udct
+
+TCP_SERVICES,UDP_SERVICES=load_services("/etc/services")
+
+class ManufDA(DADict):
+    def fixname(self, val):
+        return val
+    def _get_manuf_couple(self, mac):
+        oui = ":".join(mac.split(":")[:3]).upper()
+        return self.__dict__.get(oui,(mac,mac))
+    def _get_manuf(self, mac):
+        return self._get_manuf_couple(mac)[1]
+    def _get_short_manuf(self, mac):
+        return self._get_manuf_couple(mac)[0]
+    def _resolve_MAC(self, mac):
+        oui = ":".join(mac.split(":")[:3]).upper()
+        if oui in self:
+            return ":".join([self[oui][0]]+ mac.split(":")[3:])
+        return mac
+        
+        
+        
+
+def load_manuf(filename):
+    try:
+        manufdb=ManufDA(_name=filename)
+        for l in open(filename):
+            try:
+                l = l.strip()
+                if not l or l.startswith("#"):
+                    continue
+                oui,shrt=l.split()[:2]
+                i = l.find("#")
+                if i < 0:
+                    lng=shrt
+                else:
+                    lng = l[i+2:]
+                manufdb[oui] = shrt,lng
+            except Exception,e:
+                log_loading.warning("Couldn't parse one line from [%s] [%r] (%s)" % (filename, l, e))
+    except IOError:
+        #log_loading.warning("Couldn't open [%s] file" % filename)
+        pass
+    return manufdb
+    
+
+
+
+
+#####################
+## knowledge bases ##
+#####################
+
+class KnowledgeBase:
+    def __init__(self, filename):
+        self.filename = filename
+        self.base = None
+
+    def lazy_init(self):
+        self.base = ""
+
+    def reload(self, filename = None):
+        if filename is not None:
+            self.filename = filename
+        oldbase = self.base
+        self.base = None
+        self.lazy_init()
+        if self.base is None:
+            self.base = oldbase
+
+    def get_base(self):
+        if self.base is None:
+            self.lazy_init()
+        return self.base
+    
+
diff --git a/scapy/error.py b/scapy/error.py
new file mode 100644
index 0000000000000000000000000000000000000000..c67ba14257764235e5a5a23f6c0529fa0f32b0fd
--- /dev/null
+++ b/scapy/error.py
@@ -0,0 +1,51 @@
+
+#############################
+##### Logging subsystem #####
+#############################
+
+class Scapy_Exception(Exception):
+    pass
+
+import logging,traceback,time
+
+class ScapyFreqFilter(logging.Filter):
+    def __init__(self):
+        logging.Filter.__init__(self)
+        self.warning_table = {}
+    def filter(self, record):        
+        wt = conf.warning_threshold
+        if wt > 0:
+            stk = traceback.extract_stack()
+            caller=None
+            for f,l,n,c in stk:
+                if n == 'warning':
+                    break
+                caller = l
+            tm,nb = self.warning_table.get(caller, (0,0))
+            ltm = time.time()
+            if ltm-tm > wt:
+                tm = ltm
+                nb = 0
+            else:
+                if nb < 2:
+                    nb += 1
+                    if nb == 2:
+                        record.msg = "more "+record.msg
+                else:
+                    return 0
+            self.warning_table[caller] = (tm,nb)
+        return 1    
+
+log_scapy = logging.getLogger("scapy")
+console_handler = logging.StreamHandler()
+console_handler.setFormatter(logging.Formatter("%(levelname)s: %(message)s"))
+log_scapy.addHandler(console_handler)
+log_runtime = logging.getLogger("scapy.runtime")          # logs at runtime
+log_runtime.addFilter(ScapyFreqFilter())
+log_interactive = logging.getLogger("scapy.interactive")  # logs in interactive functions
+log_loading = logging.getLogger("scapy.loading")          # logs when loading scapy
+
+if __name__ == "__main__":
+    log_scapy.setLevel(1)
+
+
diff --git a/scapy/fields.py b/scapy/fields.py
new file mode 100644
index 0000000000000000000000000000000000000000..ba7d6074f88931780abf29047afe7c73ace18489
--- /dev/null
+++ b/scapy/fields.py
@@ -0,0 +1,939 @@
+import struct,copy,socket
+from data import *
+from utils import *
+
+############
+## Fields ##
+############
+
+class Field:
+    """For more informations on how this work, please refer to
+       http://www.secdev.org/projects/scapy/files/scapydoc.pdf
+       chapter ``Adding a New Field''"""
+    islist=0
+    holds_packets=0
+    def __init__(self, name, default, fmt="H"):
+        self.name = name
+        if fmt[0] in "@=<>!":
+            self.fmt = fmt
+        else:
+            self.fmt = "!"+fmt
+        self.default = self.any2i(None,default)
+        self.sz = struct.calcsize(self.fmt)
+        self.owners = []
+
+    def register_owner(self, cls):
+        self.owners.append(cls)
+
+    def i2len(self, pkt, x):
+        """Convert internal value to a length usable by a FieldLenField"""
+        return self.sz
+    def i2count(self, pkt, x):
+        """Convert internal value to a number of elements usable by a FieldLenField.
+        Always 1 except for list fields"""
+        return 1
+    def h2i(self, pkt, x):
+        """Convert human value to internal value"""
+        return x
+    def i2h(self, pkt, x):
+        """Convert internal value to human value"""
+        return x
+    def m2i(self, pkt, x):
+        """Convert machine value to internal value"""
+        return x
+    def i2m(self, pkt, x):
+        """Convert internal value to machine value"""
+        if x is None:
+            x = 0
+        return x
+    def any2i(self, pkt, x):
+        """Try to understand the most input values possible and make an internal value from them"""
+        return self.h2i(pkt, x)
+    def i2repr(self, pkt, x):
+        """Convert internal value to a nice representation"""
+        if x is None:
+            x = 0
+        return repr(self.i2h(pkt,x))
+    def addfield(self, pkt, s, val):
+        """Add an internal value  to a string"""
+        return s+struct.pack(self.fmt, self.i2m(pkt,val))
+    def getfield(self, pkt, s):
+        """Extract an internal value from a string"""
+        return  s[self.sz:], self.m2i(pkt, struct.unpack(self.fmt, s[:self.sz])[0])
+    def do_copy(self, x):
+        if hasattr(x, "copy"):
+            return x.copy()
+        if type(x) is list:
+            x = x[:]
+            for i in xrange(len(x)):
+                if isinstance(x[i], Packet):
+                    x[i] = x[i].copy()
+        return x
+    def __repr__(self):
+        return "<Field (%s).%s>" % (",".join(x.__name__ for x in self.owners),self.name)
+    def copy(self):
+        return copy.deepcopy(self)
+    def randval(self):
+        """Return a volatile object whose value is both random and suitable for this field"""
+        fmtt = self.fmt[-1]
+        if fmtt in "BHIQ":
+            return {"B":RandByte,"H":RandShort,"I":RandInt, "Q":RandLong}[fmtt]()
+        elif fmtt == "s":
+            if self.fmt[0] in "0123456789":
+                l = int(self.fmt[:-1])
+            else:
+                l = int(self.fmt[1:-1])
+            return RandBin(l)
+        else:
+            warning("no random class for [%s] (fmt=%s)." % (self.name, self.fmt))
+            
+
+
+
+class Emph:
+    fld = ""
+    def __init__(self, fld):
+        self.fld = fld
+    def __getattr__(self, attr):
+        return getattr(self.fld,attr)
+    def __hash__(self):
+        return hash(self.fld)
+    def __eq__(self, other):
+        return self.fld == other
+    
+
+class ActionField:
+    _fld = None
+    def __init__(self, fld, action_method, **kargs):
+        self._fld = fld
+        self._action_method = action_method
+        self._privdata = kargs
+    def any2i(self, pkt, val):
+        getattr(pkt, self._action_method)(val, self._fld, **self._privdata)
+        return getattr(self._fld, "any2i")(pkt, val)
+    def __getattr__(self, attr):
+        return getattr(self._fld,attr)
+
+
+class ConditionalField:
+    fld = None
+    def __init__(self, fld, cond):
+        self.fld = fld
+        self.cond = cond
+    def _evalcond(self,pkt):
+        return self.cond(pkt)
+        
+    def getfield(self, pkt, s):
+        if self._evalcond(pkt):
+            return self.fld.getfield(pkt,s)
+        else:
+            return s,None
+        
+    def addfield(self, pkt, s, val):
+        if self._evalcond(pkt):
+            return self.fld.addfield(pkt,s,val)
+        else:
+            return s
+    def __getattr__(self, attr):
+        return getattr(self.fld,attr)
+        
+
+class PadField:
+    """Add bytes after the proxified field so that it ends at the specified
+       alignment from its begining"""
+    _fld = None
+    def __init__(self, fld, align, padwith=None):
+        self._fld = fld
+        self._align = align
+        self._padwith = padwith or ""
+
+    def addfield(self, pkt, s, val):
+        sval = self._fld.addfield(pkt, "", val)
+        return s+sval+struct.pack("%is" % (-len(sval)%self._align), self._padwith)
+    
+    def __getattr__(self, attr):
+        return getattr(self._fld,attr)
+        
+
+class MACField(Field):
+    def __init__(self, name, default):
+        Field.__init__(self, name, default, "6s")
+    def i2m(self, pkt, x):
+        if x is None:
+            return "\0\0\0\0\0\0"
+        return mac2str(x)
+    def m2i(self, pkt, x):
+        return str2mac(x)
+    def any2i(self, pkt, x):
+        if type(x) is str and len(x) is 6:
+            x = self.m2i(pkt, x)
+        return x
+    def i2repr(self, pkt, x):
+        x = self.i2h(pkt, x)
+        if self in conf.resolve:
+            x = conf.manufdb._resolve_MAC(x)
+        return x
+    def randval(self):
+        return RandMAC()
+
+class DestMACField(MACField):
+    def __init__(self, name):
+        MACField.__init__(self, name, None)
+    def i2h(self, pkt, x):
+        if x is None:
+            dstip = None
+            if isinstance(pkt.payload, IPv6):
+                dstip = pkt.payload.dst            
+            elif isinstance(pkt.payload, IP):
+                dstip = pkt.payload.dst
+            elif isinstance(pkt.payload, ARP):
+                dstip = pkt.payload.pdst
+            if isinstance(dstip, Gen):
+                dstip = dstip.__iter__().next()
+            if dstip is not None:
+                if isinstance(pkt.payload, IPv6):
+                    x = getmacbyip6(dstip, chainCC=1)
+                else:    
+                    x = getmacbyip(dstip, chainCC=1)
+            if x is None:
+                x = "ff:ff:ff:ff:ff:ff"
+                warning("Mac address to reach %s not found\n"%dstip)
+        return MACField.i2h(self, pkt, x)
+    def i2m(self, pkt, x):
+        return MACField.i2m(self, pkt, self.i2h(pkt, x))
+        
+class SourceMACField(MACField):
+    def __init__(self, name):
+        MACField.__init__(self, name, None)
+    def i2h(self, pkt, x):
+        if x is None:
+            dstip = None
+            if isinstance(pkt.payload, IPv6):
+                dstip = pkt.payload.dst
+            elif isinstance(pkt.payload, IP):
+                dstip = pkt.payload.dst
+            elif isinstance(pkt.payload, ARP):
+                dstip = pkt.payload.pdst
+            if isinstance(dstip, Gen):
+                dstip = dstip.__iter__().next()
+            if dstip is not None:
+                if isinstance(pkt.payload, IPv6):
+                    iff,a,nh = conf.route6.route(dstip)
+                else:
+                    iff,a,gw = conf.route.route(dstip)
+                try:
+                    x = get_if_hwaddr(iff)
+                except:
+                    pass
+                if x is None:
+                    x = "00:00:00:00:00:00"
+        return MACField.i2h(self, pkt, x)
+    def i2m(self, pkt, x):
+        return MACField.i2m(self, pkt, self.i2h(pkt, x))
+        
+class ARPSourceMACField(MACField):
+    def __init__(self, name):
+        MACField.__init__(self, name, None)
+    def i2h(self, pkt, x):
+        if x is None:
+            dstip = pkt.pdst
+            if isinstance(dstip, Gen):
+                dstip = dstip.__iter__().next()
+            if dstip is not None:
+                iff,a,gw = conf.route.route(dstip)
+                try:
+                    x = get_if_hwaddr(iff)
+                except:
+                    pass
+                if x is None:
+                    x = "00:00:00:00:00:00"
+        return MACField.i2h(self, pkt, x)
+    def i2m(self, pkt, x):
+        return MACField.i2m(self, pkt, self.i2h(pkt, x))
+
+class Dot11AddrMACField(MACField):
+    def is_applicable(self, pkt):
+        return 1
+    def addfield(self, pkt, s, val):
+        if self.is_applicable(pkt):
+            return MACField.addfield(self, pkt, s, val)
+        else:
+            return s        
+    def getfield(self, pkt, s):
+        if self.is_applicable(pkt):
+            return MACField.getfield(self, pkt, s)
+        else:
+            return s,None
+
+class Dot11Addr2MACField(Dot11AddrMACField):
+    def is_applicable(self, pkt):
+        if pkt.type == 1:
+            return pkt.subtype in [ 0xb, 0xa, 0xe, 0xf] # RTS, PS-Poll, CF-End, CF-End+CF-Ack
+        return 1
+
+class Dot11Addr3MACField(Dot11AddrMACField):
+    def is_applicable(self, pkt):
+        if pkt.type in [0,2]:
+            return 1
+        return 0
+
+class Dot11Addr4MACField(Dot11AddrMACField):
+    def is_applicable(self, pkt):
+        if pkt.type == 2:
+            if pkt.FCfield & 0x3 == 0x3: # To-DS and From-DS are set
+                return 1
+        return 0
+    
+class IPField(Field):
+    def __init__(self, name, default):
+        Field.__init__(self, name, default, "4s")
+    def h2i(self, pkt, x):
+        if type(x) is str:
+            try:
+                inet_aton(x)
+            except socket.error:
+                x = Net(x)
+        elif type(x) is list:
+            x = [self.h2i(pkt, n) for n in x] 
+        return x
+    def resolve(self, x):
+        if self in conf.resolve:
+            try:
+                ret = socket.gethostbyaddr(x)[0]
+            except:
+                pass
+            else:
+                if ret:
+                    return ret
+        return x
+    def i2m(self, pkt, x):
+        return inet_aton(x)
+    def m2i(self, pkt, x):
+        return inet_ntoa(x)
+    def any2i(self, pkt, x):
+        return self.h2i(pkt,x)
+    def i2repr(self, pkt, x):
+        return self.resolve(self.i2h(pkt, x))
+    def randval(self):
+        return RandIP()
+
+class SourceIPField(IPField):
+    def __init__(self, name, dstname):
+        IPField.__init__(self, name, None)
+        self.dstname = dstname
+    def i2m(self, pkt, x):
+        if x is None:
+            iff,x,gw = conf.route.route(getattr(pkt,self.dstname))
+        return IPField.i2m(self, pkt, x)
+    def i2h(self, pkt, x):
+        if x is None:
+            dst=getattr(pkt,self.dstname)
+            if isinstance(dst,Gen):
+                r = map(conf.route.route, dst)
+                r.sort()
+                if r[0] == r[-1]:
+                    x=r[0][1]
+                else:
+                    warning("More than one possible route for %s"%repr(dst))
+                    return None
+            else:
+                iff,x,gw = conf.route.route(dst)
+        return IPField.i2h(self, pkt, x)
+
+    
+
+
+class ByteField(Field):
+    def __init__(self, name, default):
+        Field.__init__(self, name, default, "B")
+        
+class XByteField(ByteField):
+    def i2repr(self, pkt, x):
+        if x is None:
+            x = 0
+        return lhex(self.i2h(pkt, x))
+
+class X3BytesField(XByteField):
+    def __init__(self, name, default):
+        Field.__init__(self, name, default, "!I")
+    def addfield(self, pkt, s, val):
+        return s+struct.pack(self.fmt, self.i2m(pkt,val))[1:4]
+    def getfield(self, pkt, s):
+        return  s[3:], self.m2i(pkt, struct.unpack(self.fmt, "\x00"+s[:3])[0])
+
+
+class ShortField(Field):
+    def __init__(self, name, default):
+        Field.__init__(self, name, default, "H")
+
+class LEShortField(Field):
+    def __init__(self, name, default):
+        Field.__init__(self, name, default, "<H")
+
+class XShortField(ShortField):
+    def i2repr(self, pkt, x):
+        if x is None:
+            x = 0
+        return lhex(self.i2h(pkt, x))
+
+
+class IntField(Field):
+    def __init__(self, name, default):
+        Field.__init__(self, name, default, "I")
+
+class SignedIntField(Field):
+    def __init__(self, name, default):
+        Field.__init__(self, name, default, "i")
+    def randval(self):
+        return RandSInt()
+
+class LEIntField(Field):
+    def __init__(self, name, default):
+        Field.__init__(self, name, default, "<I")
+
+class LESignedIntField(Field):
+    def __init__(self, name, default):
+        Field.__init__(self, name, default, "<i")
+    def randval(self):
+        return RandSInt()
+
+class XIntField(IntField):
+    def i2repr(self, pkt, x):
+        if x is None:
+            x = 0
+        return lhex(self.i2h(pkt, x))
+
+
+class LongField(Field):
+    def __init__(self, name, default):
+        Field.__init__(self, name, default, "Q")
+
+class XLongField(LongField):
+    def i2repr(self, pkt, x):
+        if x is None:
+            x = 0
+        return lhex(self.i2h(pkt, x))
+
+class IEEEFloatField(Field):
+    def __init__(self, name, default):
+        Field.__init__(self, name, default, "f")
+
+class IEEEDoubleField(Field):
+    def __init__(self, name, default):
+        Field.__init__(self, name, default, "d")
+
+import traceback
+def FIELD_LENGTH_MANAGEMENT_DEPRECATION(x):
+    try:
+        for tb in traceback.extract_stack()+[("??",-1,None,"")]:
+            f,l,_,line = tb
+            if line.startswith("fields_desc"):
+                break
+    except:
+        f,l="??",-1
+    log_loading.warning("Deprecated use of %s (%s l. %i). See http://trac.secdev.org/scapy/wiki/LengthFields" % (x,f,l))
+
+class StrField(Field):
+    def __init__(self, name, default, fmt="H", remain=0, shift=0):
+        Field.__init__(self,name,default,fmt)
+        self.remain = remain        
+        self.shift = shift
+        if shift != 0:
+            FIELD_LENGTH_MANAGEMENT_DEPRECATION(self.__class__.__name__)
+    def i2len(self, pkt, i):
+        return len(i)+self.shift
+    def i2m(self, pkt, x):
+        if x is None:
+            x = ""
+        return x
+    def addfield(self, pkt, s, val):
+        return s+self.i2m(pkt, val)
+    def getfield(self, pkt, s):
+        if self.remain == 0:
+            return "",self.m2i(pkt, s)
+        else:
+            return s[-self.remain:],self.m2i(pkt, s[:-self.remain])
+    def randval(self):
+        return RandBin(RandNum(0,1200))
+
+class PacketField(StrField):
+    holds_packets=1
+    def __init__(self, name, default, cls, remain=0, shift=0):
+        StrField.__init__(self, name, default, remain=remain, shift=shift)
+        self.cls = cls
+    def i2m(self, pkt, i):
+        return str(i)
+    def m2i(self, pkt, m):
+        return self.cls(m)
+    def getfield(self, pkt, s):
+        i = self.m2i(pkt, s)
+        remain = ""
+        if i.haslayer(Padding):
+            r = i.getlayer(Padding)
+            del(r.underlayer.payload)
+            remain = r.load
+        return remain,i
+    
+class PacketLenField(PacketField):
+    holds_packets=1
+    def __init__(self, name, default, cls, fld=None, length_from=None, shift=0):
+        PacketField.__init__(self, name, default, cls, shift=shift)
+        self.length_from = length_from
+        if fld is not None or shift != 0:
+            FIELD_LENGTH_MANAGEMENT_DEPRECATION(self.__class__.__name__)
+            self.count_from = lambda pkt,fld=fld,shift=shift: getattr(pkt,fld)-shift
+    def getfield(self, pkt, s):
+        l = self.length_from(pkt)
+        i = self.m2i(pkt, s[:l])
+        return s[l:],i
+
+
+class PacketListField(PacketField):
+    islist = 1
+    holds_packets=1
+    def __init__(self, name, default, cls, fld=None, count_from=None, length_from=None, shift=0):
+        if default is None:
+            default = []  # Create a new list for each instance
+        PacketField.__init__(self, name, default, cls, shift=shift)
+        self.count_from = count_from
+        self.length_from = length_from
+
+        if fld is not None or shift != 0:
+            FIELD_LENGTH_MANAGEMENT_DEPRECATION(self.__class__.__name__)
+        if fld is not None:
+            self.count_from = lambda pkt,fld=fld,shift=shift: getattr(pkt,fld)-shift
+
+    def any2i(self, pkt, x):
+        if type(x) is not list:
+            return [x]
+        else:
+            return x
+    def i2count(self, pkt, val):
+        if type(val) is list:
+            return len(val)
+        return 1
+    def i2len(self, pkt, val):
+        return sum( len(p) for p in val )
+    def do_copy(self, x):
+        return map(lambda p:p.copy(), x)
+    def getfield(self, pkt, s):
+        c = l = None
+        if self.length_from is not None:
+            l = self.length_from(pkt)
+        elif self.count_from is not None:
+            c = self.count_from(pkt)
+            
+        lst = []
+        ret = ""
+        remain = s
+        if l is not None:
+            remain,ret = s[:l],s[l:]
+        while remain:
+            if c is not None:
+                if c <= 0:
+                    break
+                c -= 1
+            p = self.m2i(pkt,remain)
+            if Padding in p:
+                pad = p[Padding]
+                remain = pad.load
+                del(pad.underlayer.payload)
+            else:
+                remain = ""
+            lst.append(p)
+        return remain+ret,lst
+    def addfield(self, pkt, s, val):
+        return s+"".join(map(str, val))
+
+
+class StrFixedLenField(StrField):
+    def __init__(self, name, default, length=None, length_from=None, shift=0):
+        StrField.__init__(self, name, default, shift=shift)
+        self.length_from  = length_from
+        if length is not None:
+            self.length_from = lambda pkt,length=length: length
+    def getfield(self, pkt, s):
+        l = self.length_from(pkt)
+        return s[l:], self.m2i(pkt,s[:l])
+    def addfield(self, pkt, s, val):
+        l = self.length_from(pkt)
+        return s+struct.pack("%is"%l,self.i2m(pkt, val))
+    def randval(self):
+        try:
+            l = self.length_from(None)
+        except:
+            l = RandNum(0,200)
+        return RandBin(l)
+
+class NetBIOSNameField(StrFixedLenField):
+    def __init__(self, name, default, length=31, shift=0):
+        StrFixedLenField.__init__(self, name, default, length, shift=shift)
+    def i2m(self, pkt, x):
+        l = self.length_from(pkt)/2
+        if x is None:
+            x = ""
+        x += " "*(l)
+        x = x[:l]
+        x = "".join(map(lambda x: chr(0x41+(ord(x)>>4))+chr(0x41+(ord(x)&0xf)), x))
+        x = " "+x
+        return x
+    def m2i(self, pkt, x):
+        x = x.strip("\x00").strip(" ")
+        return "".join(map(lambda x,y: chr((((ord(x)-1)&0xf)<<4)+((ord(y)-1)&0xf)), x[::2],x[1::2]))
+
+class StrLenField(StrField):
+    def __init__(self, name, default, fld=None, length_from=None, shift=0):
+        StrField.__init__(self, name, default, shift=shift)
+        self.length_from = length_from
+        if fld is not None or shift != 0:
+            FIELD_LENGTH_MANAGEMENT_DEPRECATION(self.__class__.__name__)
+            self.length_from = lambda pkt,fld=fld,shift=shift: getattr(pkt,fld)-shift
+    def getfield(self, pkt, s):
+        l = self.length_from(pkt)
+        return s[l:], self.m2i(pkt,s[:l])
+
+class FieldListField(Field):
+    islist=1
+    def __init__(self, name, default, field, fld=None, shift=0, length_from=None, count_from=None):
+        if default is None:
+            default = []  # Create a new list for each instance
+        Field.__init__(self, name, default)
+        self.count_from = count_from
+        self.length_from = length_from
+        self.field = field
+        if fld is not None or shift != 0:
+            FIELD_LENGTH_MANAGEMENT_DEPRECATION(self.__class__.__name__)
+            self.count_from = lambda pkt,fld=fld,shift=shift: getattr(pkt,fld)-shift
+            
+            
+    def i2count(self, pkt, val):
+        if type(val) is list:
+            return len(val)
+        return 1
+    def i2len(self, pkt, val):
+        return sum( self.field.i2len(pkt,v) for v in val )
+    
+    def i2m(self, pkt, val):
+        if val is None:
+            val = []
+        return val
+    def any2i(self, pkt, x):
+        if type(x) is not list:
+            return [x]
+        else:
+            return x
+    def addfield(self, pkt, s, val):
+        val = self.i2m(pkt, val)
+        for v in val:
+            s = self.field.addfield(pkt, s, v)
+        return s
+    def getfield(self, pkt, s):
+        c = l = None
+        if self.length_from is not None:
+            l = self.length_from(pkt)
+        elif self.count_from is not None:
+            c = self.count_from(pkt)
+
+        val = []
+        ret=""
+        if l is not None:
+            s,ret = s[:l],s[l:]
+            
+        while s:
+            if c is not None:
+                if c <= 0:
+                    break
+                c -= 1
+            s,v = self.field.getfield(pkt, s)
+            val.append(v)
+        return s+ret, val
+
+class FieldLenField(Field):
+    def __init__(self, name, default,  length_of=None, fmt = "H", count_of=None, adjust=lambda pkt,x:x, fld=None):
+        Field.__init__(self, name, default, fmt)
+        self.length_of=length_of
+        self.count_of=count_of
+        self.adjust=adjust
+        if fld is not None:
+            FIELD_LENGTH_MANAGEMENT_DEPRECATION(self.__class__.__name__)
+            self.length_of = fld
+    def i2m(self, pkt, x):
+        if x is None:
+            if self.length_of is not None:
+                fld,fval = pkt.getfield_and_val(self.length_of)
+                f = fld.i2len(pkt, fval)
+            else:
+                fld,fval = pkt.getfield_and_val(self.count_of)
+                f = fld.i2count(pkt, fval)
+            x = self.adjust(pkt,f)
+        return x
+
+class StrNullField(StrField):
+    def addfield(self, pkt, s, val):
+        return s+self.i2m(pkt, val)+"\x00"
+    def getfield(self, pkt, s):
+        l = s.find("\x00")
+        if l < 0:
+            #XXX \x00 not found
+            return "",s
+        return s[l+1:],self.m2i(pkt, s[:l])
+    def randval(self):
+        return RandTermString(RandNum(0,1200),"\x00")
+
+class StrStopField(StrField):
+    def __init__(self, name, default, stop, additionnal=0):
+        Field.__init__(self, name, default)
+        self.stop=stop
+        self.additionnal=additionnal
+    def getfield(self, pkt, s):
+        l = s.find(self.stop)
+        if l < 0:
+            return "",s
+#            raise Scapy_Exception,"StrStopField: stop value [%s] not found" %stop
+        l += len(self.stop)+self.additionnal
+        return s[l:],s[:l]
+    def randval(self):
+        return RandTermString(RandNum(0,1200),self.stop)
+
+class LenField(Field):
+    def i2m(self, pkt, x):
+        if x is None:
+            x = len(pkt.payload)
+        return x
+
+class BCDFloatField(Field):
+    def i2m(self, pkt, x):
+        return int(256*x)
+    def m2i(self, pkt, x):
+        return x/256.0
+
+class BitField(Field):
+    def __init__(self, name, default, size):
+        Field.__init__(self, name, default)
+        self.rev = size < 0 
+        self.size = abs(size)
+    def reverse(self, val):
+        if self.size == 16:
+            val = socket.ntohs(val)
+        elif self.size == 32:
+            val = socket.ntohl(val)
+        return val
+        
+    def addfield(self, pkt, s, val):
+        val = self.i2m(pkt, val)
+        if type(s) is tuple:
+            s,bitsdone,v = s
+        else:
+            bitsdone = 0
+            v = 0
+        if self.rev:
+            val = self.reverse(val)
+        v <<= self.size
+        v |= val & ((1L<<self.size) - 1)
+        bitsdone += self.size
+        while bitsdone >= 8:
+            bitsdone -= 8
+            s = s+struct.pack("!B", v >> bitsdone)
+            v &= (1L<<bitsdone)-1
+        if bitsdone:
+            return s,bitsdone,v
+        else:
+            return s
+    def getfield(self, pkt, s):
+        if type(s) is tuple:
+            s,bn = s
+        else:
+            bn = 0
+        # we don't want to process all the string
+        nb_bytes = (self.size+bn-1)/8 + 1
+        w = s[:nb_bytes]
+
+        # split the substring byte by byte
+        bytes = struct.unpack('!%dB' % nb_bytes , w)
+
+        b = 0L
+        for c in range(nb_bytes):
+            b |= long(bytes[c]) << (nb_bytes-c-1)*8
+
+        # get rid of high order bits
+        b &= (1L << (nb_bytes*8-bn)) - 1
+
+        # remove low order bits
+        b = b >> (nb_bytes*8 - self.size - bn)
+
+        if self.rev:
+            b = self.reverse(b)
+
+        bn += self.size
+        s = s[bn/8:]
+        bn = bn%8
+        b = self.m2i(pkt, b)
+        if bn:
+            return (s,bn),b
+        else:
+            return s,b
+    def randval(self):
+        return RandNum(0,2**self.size-1)
+
+
+class BitFieldLenField(BitField):
+    def __init__(self, name, default, size, length_of=None, count_of=None, adjust=lambda pkt,x:x):
+        BitField.__init__(self, name, default, size)
+        self.length_of=length_of
+        self.count_of=count_of
+        self.adjust=adjust
+    def i2m(self, pkt, x):
+        return FieldLenField.i2m.im_func(self, pkt, x)
+
+
+class XBitField(BitField):
+    def i2repr(self, pkt, x):
+        return lhex(self.i2h(pkt,x))
+
+
+class EnumField(Field):
+    def __init__(self, name, default, enum, fmt = "H"):
+        i2s = self.i2s = {}
+        s2i = self.s2i = {}
+        if type(enum) is list:
+            keys = xrange(len(enum))
+        else:
+            keys = enum.keys()
+        if filter(lambda x: type(x) is str, keys):
+            i2s,s2i = s2i,i2s
+        for k in keys:
+            i2s[k] = enum[k]
+            s2i[enum[k]] = k
+        Field.__init__(self, name, default, fmt)
+    def any2i_one(self, pkt, x):
+        if type(x) is str:
+            x = self.s2i[x]
+        return x
+    def i2repr_one(self, pkt, x):
+        if self not in conf.noenum and not isinstance(x,VolatileValue) and x in self.i2s:
+            return self.i2s[x]
+        return repr(x)
+    
+    def any2i(self, pkt, x):
+        if type(x) is list:
+            return map(lambda z,pkt=pkt:self.any2i_one(pkt,z), x)
+        else:
+            return self.any2i_one(pkt,x)        
+    def i2repr(self, pkt, x):
+        if type(x) is list:
+            return map(lambda z,pkt=pkt:self.i2repr_one(pkt,z), x)
+        else:
+            return self.i2repr_one(pkt,x)
+
+class CharEnumField(EnumField):
+    def __init__(self, name, default, enum, fmt = "1s"):
+        EnumField.__init__(self, name, default, enum, fmt)
+        k = self.i2s.keys()
+        if k and len(k[0]) != 1:
+            self.i2s,self.s2i = self.s2i,self.i2s
+    def any2i_one(self, pkt, x):
+        if len(x) != 1:
+            x = self.s2i[x]
+        return x
+
+class BitEnumField(BitField,EnumField):
+    def __init__(self, name, default, size, enum):
+        EnumField.__init__(self, name, default, enum)
+        self.rev = size < 0
+        self.size = abs(size)
+    def any2i(self, pkt, x):
+        return EnumField.any2i(self, pkt, x)
+    def i2repr(self, pkt, x):
+        return EnumField.i2repr(self, pkt, x)
+
+class ShortEnumField(EnumField):
+    def __init__(self, name, default, enum):
+        EnumField.__init__(self, name, default, enum, "H")
+
+class LEShortEnumField(EnumField):
+    def __init__(self, name, default, enum):
+        EnumField.__init__(self, name, default, enum, "<H")
+
+class ByteEnumField(EnumField):
+    def __init__(self, name, default, enum):
+        EnumField.__init__(self, name, default, enum, "B")
+
+class IntEnumField(EnumField):
+    def __init__(self, name, default, enum):
+        EnumField.__init__(self, name, default, enum, "I")
+
+class SignedIntEnumField(EnumField):
+    def __init__(self, name, default, enum):
+        EnumField.__init__(self, name, default, enum, "i")
+    def randval(self):
+        return RandSInt()
+
+class LEIntEnumField(EnumField):
+    def __init__(self, name, default, enum):
+        EnumField.__init__(self, name, default, enum, "<I")
+
+class XShortEnumField(ShortEnumField):
+    def i2repr_one(self, pkt, x):
+        if self not in conf.noenum and not isinstance(x,VolatileValue) and x in self.i2s:
+            return self.i2s[x]
+        return lhex(x)
+
+# Little endian long field
+class LELongField(Field):
+    def __init__(self, name, default):
+        Field.__init__(self, name, default, "<Q")
+
+# Little endian fixed length field
+class LEFieldLenField(FieldLenField):
+    def __init__(self, name, default,  length_of=None, fmt = "<H", count_of=None, adjust=lambda pkt,x:x, fld=None):
+        FieldLenField.__init__(self, name, default, length_of=length_of, fmt=fmt, fld=fld, adjust=adjust)
+
+
+class FlagsField(BitField):
+    def __init__(self, name, default, size, names):
+        BitField.__init__(self, name, default, size)
+        self.multi = type(names) is list
+        if self.multi:
+            self.names = map(lambda x:[x], names)
+        else:
+            self.names = names
+    def any2i(self, pkt, x):
+        if type(x) is str:
+            if self.multi:
+                x = map(lambda y:[y], x.split("+"))
+            y = 0
+            for i in x:
+                y |= 1 << self.names.index(i)
+            x = y
+        return x
+    def i2repr(self, pkt, x):
+        if type(x) is list or type(x) is tuple:
+            return repr(x)
+        if self.multi:
+            r = []
+        else:
+            r = ""
+        i=0
+        while x:
+            if x & 1:
+                r += self.names[i]
+            i += 1
+            x >>= 1
+        if self.multi:
+            r = "+".join(r)
+        return r
+
+            
+
+
+class FloatField(BitField):
+    def getfield(self, pkt, s):
+        s,b = BitField.getfield(self, pkt, s)
+        
+        # fraction point between bits 15 and 16.
+        sec = b >> 16
+        frac = b & (1L << (32+1)) - 1
+        frac /= 65536.0
+        b = sec+frac
+        return s,b    
+
diff --git a/scapy/geoip.py b/scapy/geoip.py
new file mode 100644
index 0000000000000000000000000000000000000000..fec7814e0472665c2e8df50a7a2ca893e611d47a
--- /dev/null
+++ b/scapy/geoip.py
@@ -0,0 +1,64 @@
+from scapy.data import KnowledgeBase
+from scapy.config import conf
+
+##########################
+## IP location database ##
+##########################
+
+class IPCountryKnowledgeBase(KnowledgeBase):
+    """
+How to generate the base :
+db = []
+for l in open("GeoIPCountryWhois.csv").readlines():
+    s,e,c = l.split(",")[2:5]
+    db.append((int(s[1:-1]),int(e[1:-1]),c[1:-1]))
+cPickle.dump(gzip.open("xxx","w"),db)
+"""
+    def lazy_init(self):
+        self.base = load_object(self.filename)
+
+
+class CountryLocKnowledgeBase(KnowledgeBase):
+    def lazy_init(self):
+        f=open(self.filename)
+        self.base = {}
+        while 1:
+            l = f.readline()
+            if not l:
+                break
+            l = l.strip().split(",")
+            if len(l) != 3:
+                continue
+            c,lat,long = l
+            
+            self.base[c] = (float(long),float(lat))
+        f.close()
+            
+        
+
+
+def locate_ip(ip):
+    ip=map(int,ip.split("."))
+    ip = ip[3]+(ip[2]<<8L)+(ip[1]<<16L)+(ip[0]<<24L)
+
+    cloc = country_loc_kdb.get_base()
+    db = IP_country_kdb.get_base()
+
+    d=0
+    f=len(db)-1
+    while (f-d) > 1:
+        guess = (d+f)/2
+        if ip > db[guess][0]:
+            d = guess
+        else:
+            f = guess
+    s,e,c = db[guess]
+    if  s <= ip and ip <= e:
+        return cloc.get(c,None)
+
+
+
+
+
+conf.IP_country_kdb = IPCountryKnowledgeBase(conf.IPCountry_base)
+conf.country_loc_kdb = CountryLocKnowledgeBase(conf.countryLoc_base)
diff --git a/scapy/layers/__init__.py b/scapy/layers/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/scapy/layers/bluetooth.py b/scapy/layers/bluetooth.py
new file mode 100644
index 0000000000000000000000000000000000000000..d2f9447f379d5a77954bbe540c4db75017710919
--- /dev/null
+++ b/scapy/layers/bluetooth.py
@@ -0,0 +1,195 @@
+import socket,struct
+
+from scapy.config import conf
+from scapy.packet import *
+from scapy.fields import *
+#from scapy.supersocket import SuperSocket
+#from scapy.layers.l2 import CookedLinux
+
+
+class HCI_Hdr(Packet):
+    name = "HCI header"
+    fields_desc = [ ByteEnumField("type",2,{1:"command",2:"ACLdata",3:"SCOdata",4:"event",5:"vendor"}),]
+
+    def mysummary(self):
+        return self.sprintf("HCI %type%")
+
+class HCI_ACL_Hdr(Packet):
+    name = "HCI ACL header"
+    fields_desc = [ ByteField("handle",0), # Actually, handle is 12 bits and flags is 4.
+                    ByteField("flags",0),  # I wait to write a LEBitField
+                    LEShortField("len",None), ]
+    def post_build(self, p, pay):
+        p += pay
+        if self.len is None:
+            l = len(p)-4
+            p = p[:2]+chr(l&0xff)+chr((l>>8)&0xff)+p[4:]
+        return p
+                    
+
+class L2CAP_Hdr(Packet):
+    name = "L2CAP header"
+    fields_desc = [ LEShortField("len",None),
+                    LEShortEnumField("cid",0,{1:"control"}),]
+    
+    def post_build(self, p, pay):
+        p += pay
+        if self.len is None:
+            l = len(p)-4
+            p = p[:2]+chr(l&0xff)+chr((l>>8)&0xff)+p[4:]
+        return p
+                    
+                
+
+class L2CAP_CmdHdr(Packet):
+    name = "L2CAP command header"
+    fields_desc = [
+        ByteEnumField("code",8,{1:"rej",2:"conn_req",3:"conn_resp",
+                                4:"conf_req",5:"conf_resp",6:"disconn_req",
+                                7:"disconn_resp",8:"echo_req",9:"echo_resp",
+                                10:"info_req",11:"info_resp"}),
+        ByteField("id",0),
+        LEShortField("len",None) ]
+    def post_build(self, p, pay):
+        p += pay
+        if self.len is None:
+            l = len(p)-4
+            p = p[:2]+chr(l&0xff)+chr((l>>8)&0xff)+p[4:]
+        return p
+    def answers(self, other):
+        if other.id == self.id:
+            if self.code == 1:
+                return 1
+            if other.code in [2,4,6,8,10] and self.code == other.code+1:
+                if other.code == 8:
+                    return 1
+                return self.payload.answers(other.payload)
+        return 0
+
+class L2CAP_ConnReq(Packet):
+    name = "L2CAP Conn Req"
+    fields_desc = [ LEShortEnumField("psm",0,{1:"SDP",3:"RFCOMM",5:"telephony control"}),
+                    LEShortField("scid",0),
+                    ]
+
+class L2CAP_ConnResp(Packet):
+    name = "L2CAP Conn Resp"
+    fields_desc = [ LEShortField("dcid",0),
+                    LEShortField("scid",0),
+                    LEShortEnumField("result",0,["no_info","authen_pend","author_pend"]),
+                    LEShortEnumField("status",0,["success","pend","bad_psm",
+                                               "cr_sec_block","cr_no_mem"]),
+                    ]
+    def answers(self, other):
+        return self.scid == other.scid
+
+class L2CAP_CmdRej(Packet):
+    name = "L2CAP Command Rej"
+    fields_desc = [ LEShortField("reason",0),
+                    ]
+    
+
+class L2CAP_ConfReq(Packet):
+    name = "L2CAP Conf Req"
+    fields_desc = [ LEShortField("dcid",0),
+                    LEShortField("flags",0),
+                    ]
+
+class L2CAP_ConfResp(Packet):
+    name = "L2CAP Conf Resp"
+    fields_desc = [ LEShortField("scid",0),
+                    LEShortField("flags",0),
+                    LEShortEnumField("result",0,["success","unaccept","reject","unknown"]),
+                    ]
+    def answers(self, other):
+        return self.scid == other.scid
+
+
+class L2CAP_DisconnReq(Packet):
+    name = "L2CAP Disconn Req"
+    fields_desc = [ LEShortField("dcid",0),
+                    LEShortField("scid",0), ]
+
+class L2CAP_DisconnResp(Packet):
+    name = "L2CAP Disconn Resp"
+    fields_desc = [ LEShortField("dcid",0),
+                    LEShortField("scid",0), ]
+    def answers(self, other):
+        return self.scid == other.scid
+
+    
+
+class L2CAP_InfoReq(Packet):
+    name = "L2CAP Info Req"
+    fields_desc = [ LEShortEnumField("type",0,{1:"CL_MTU",2:"FEAT_MASK"}),
+                    StrField("data","")
+                    ]
+
+
+class L2CAP_InfoResp(Packet):
+    name = "L2CAP Info Resp"
+    fields_desc = [ LEShortField("type",0),
+                    LEShortEnumField("result",0,["success","not_supp"]),
+                    StrField("data",""), ]
+    def answers(self, other):
+        return self.type == other.type
+
+
+
+bind_layers( HCI_Hdr,       HCI_ACL_Hdr,   type=2)
+bind_layers( HCI_Hdr,       Raw,           )
+bind_layers( HCI_ACL_Hdr,   L2CAP_Hdr,     )
+bind_layers( L2CAP_Hdr,     L2CAP_CmdHdr,      cid=1)
+bind_layers( L2CAP_CmdHdr,  L2CAP_CmdRej,      code=1)
+bind_layers( L2CAP_CmdHdr,  L2CAP_ConnReq,     code=2)
+bind_layers( L2CAP_CmdHdr,  L2CAP_ConnResp,    code=3)
+bind_layers( L2CAP_CmdHdr,  L2CAP_ConfReq,     code=4)
+bind_layers( L2CAP_CmdHdr,  L2CAP_ConfResp,    code=5)
+bind_layers( L2CAP_CmdHdr,  L2CAP_DisconnReq,  code=6)
+bind_layers( L2CAP_CmdHdr,  L2CAP_DisconnResp, code=7)
+bind_layers( L2CAP_CmdHdr,  L2CAP_InfoReq,     code=10)
+bind_layers( L2CAP_CmdHdr,  L2CAP_InfoResp,    code=11)
+        
+class BluetoothL2CAPSocket(SuperSocket):
+    def __init__(self, peer):
+        s = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_RAW,
+                          socket.BTPROTO_L2CAP)
+        s.connect((peer,0))
+        
+        self.ins = self.outs = s
+
+    def recv(self, x):
+        return L2CAP_CmdHdr(self.ins.recv(x))
+    
+
+class BluetoothHCISocket(SuperSocket):
+    def __init__(self, iface=0x10000, type=None):
+        s = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_RAW, socket.BTPROTO_HCI)
+        s.setsockopt(socket.SOL_HCI, socket.HCI_DATA_DIR,1)
+        s.setsockopt(socket.SOL_HCI, socket.HCI_TIME_STAMP,1)
+        s.setsockopt(socket.SOL_HCI, socket.HCI_FILTER, struct.pack("IIIh2x", 0xffffffffL,0xffffffffL,0xffffffffL,0)) #type mask, event mask, event mask, opcode
+        s.bind((iface,))
+        self.ins = self.outs = s
+#        s.connect((peer,0))
+        
+
+    def recv(self, x):
+        return HCI_Hdr(self.ins.recv(x))
+    
+## Bluetooth
+
+
+def srbt(peer, pkts, inter=0.1, *args, **kargs):
+    s = conf.BTsocket(peer=peer)
+    a,b,c=sndrcv(s,pkts,inter=inter,*args,**kargs)
+    s.close()
+    return a,b
+
+def srbt1(peer, pkts, *args, **kargs):
+    a,b = srbt(peer, pkts, *args, **kargs)
+    if len(a) > 0:
+        return a[0][1]
+        
+    
+
+conf.BTsocket = BluetoothL2CAPSocket
diff --git a/scapy/layers/dhcp.py b/scapy/layers/dhcp.py
new file mode 100644
index 0000000000000000000000000000000000000000..84c12da2c2c2c071de22313d9b78ca1398aed3a4
--- /dev/null
+++ b/scapy/layers/dhcp.py
@@ -0,0 +1,337 @@
+import struct
+
+from scapy.packet import *
+from scapy.fields import *
+from scapy.ansmachine import *
+from scapy.layers.inet import UDP
+
+dhcpmagic="c\x82Sc"
+
+
+class BOOTP(Packet):
+    name = "BOOTP"
+    fields_desc = [ ByteEnumField("op",1, {1:"BOOTREQUEST", 2:"BOOTREPLY"}),
+                    ByteField("htype",1),
+                    ByteField("hlen",6),
+                    ByteField("hops",0),
+                    IntField("xid",0),
+                    ShortField("secs",0),
+                    FlagsField("flags", 0, 16, "???????????????B"),
+                    IPField("ciaddr","0.0.0.0"),
+                    IPField("yiaddr","0.0.0.0"),
+                    IPField("siaddr","0.0.0.0"),
+                    IPField("giaddr","0.0.0.0"),
+                    Field("chaddr","", "16s"),
+                    Field("sname","","64s"),
+                    Field("file","","128s"),
+                    StrField("options","") ]
+    def guess_payload_class(self, payload):
+        if self.options[:len(dhcpmagic)] == dhcpmagic:
+            return DHCP
+        else:
+            return Packet.guess_payload_class(self, payload)
+    def extract_padding(self,s):
+        if self.options[:len(dhcpmagic)] == dhcpmagic:
+            # set BOOTP options to DHCP magic cookie and make rest a payload of DHCP options
+            payload = self.options[len(dhcpmagic):]
+            self.options = self.options[:len(dhcpmagic)]
+            return payload, None
+        else:
+            return "", None
+    def hashret(self):
+        return struct.pack("L", self.xid)
+    def answers(self, other):
+        if not isinstance(other, BOOTP):
+            return 0
+        return self.xid == other.xid
+
+
+
+#DHCP_UNKNOWN, DHCP_IP, DHCP_IPLIST, DHCP_TYPE \
+#= range(4)
+#
+
+DHCPTypes = {
+                1: "discover",
+                2: "offer",
+                3: "request",
+                4: "decline",
+                5: "ack",
+                6: "nak",
+                7: "release",
+                8: "inform",
+                9: "force_renew",
+                10:"lease_query",
+                11:"lease_unassigned",
+                12:"lease_unknown",
+                13:"lease_active",
+                }
+
+DHCPOptions = {
+    0: "pad",
+    1: IPField("subnet_mask", "0.0.0.0"),
+    2: "time_zone",
+    3: IPField("router","0.0.0.0"),
+    4: IPField("time_server","0.0.0.0"),
+    5: IPField("IEN_name_server","0.0.0.0"),
+    6: IPField("name_server","0.0.0.0"),
+    7: IPField("log_server","0.0.0.0"),
+    8: IPField("cookie_server","0.0.0.0"),
+    9: IPField("lpr_server","0.0.0.0"),
+    12: "hostname",
+    14: "dump_path",
+    15: "domain",
+    17: "root_disk_path",
+    22: "max_dgram_reass_size",
+    23: "default_ttl",
+    24: "pmtu_timeout",
+    28: IPField("broadcast_address","0.0.0.0"),
+    35: "arp_cache_timeout",
+    36: "ether_or_dot3",
+    37: "tcp_ttl",
+    38: "tcp_keepalive_interval",
+    39: "tcp_keepalive_garbage",
+    40: "NIS_domain",
+    41: IPField("NIS_server","0.0.0.0"),
+    42: IPField("NTP_server","0.0.0.0"),
+    43: "vendor_specific",
+    44: IPField("NetBIOS_server","0.0.0.0"),
+    45: IPField("NetBIOS_dist_server","0.0.0.0"),
+    50: IPField("requested_addr","0.0.0.0"),
+    51: IntField("lease_time", 43200),
+    54: IPField("server_id","0.0.0.0"),
+    55: "param_req_list",
+    57: ShortField("max_dhcp_size", 1500),
+    58: IntField("renewal_time", 21600),
+    59: IntField("rebinding_time", 37800),
+    60: "vendor_class_id",
+    61: "client_id",
+    
+    64: "NISplus_domain",
+    65: IPField("NISplus_server","0.0.0.0"),
+    69: IPField("SMTP_server","0.0.0.0"),
+    70: IPField("POP3_server","0.0.0.0"),
+    71: IPField("NNTP_server","0.0.0.0"),
+    72: IPField("WWW_server","0.0.0.0"),
+    73: IPField("Finger_server","0.0.0.0"),
+    74: IPField("IRC_server","0.0.0.0"),
+    75: IPField("StreetTalk_server","0.0.0.0"),
+    76: "StreetTalk_Dir_Assistance",
+    82: "relay_agent_Information",
+    53: ByteEnumField("message-type", 1, DHCPTypes),
+    #             55: DHCPRequestListField("request-list"),
+    255: "end"
+    }
+
+DHCPRevOptions = {}
+
+for k,v in DHCPOptions.iteritems():
+    if type(v) is str:
+        n = v
+        v = None
+    else:
+        n = v.name
+    DHCPRevOptions[n] = (k,v)
+del(n)
+del(v)
+del(k)
+    
+    
+
+
+
+class DHCPOptionsField(StrField):
+    islist=1
+    def i2repr(self,pkt,x):
+        s = []
+        for v in x:
+            if type(v) is tuple and len(v) in [2,3]:
+                if  DHCPRevOptions.has_key(v[0]) and isinstance(DHCPRevOptions[v[0]][1],Field):
+                    f = DHCPRevOptions[v[0]][1]
+                    vv = f.i2repr(pkt,v[1])
+                else:
+                    vv = repr(v[1])
+                r = "%s=%s" % (v[0],vv)
+                if len(v) > 2:
+                    r += " (garbage=%r)" % v[2]
+                s.append(r)
+            else:
+                s.append(sane(v))
+        return "[%s]" % (" ".join(s))
+        
+    def getfield(self, pkt, s):
+        return "", self.m2i(pkt, s)
+    def m2i(self, pkt, x):
+        opt = []
+        while x:
+            o = ord(x[0])
+            if o == 255:
+                opt.append("end")
+                x = x[1:]
+                continue
+            if o == 0:
+                opt.append("pad")
+                x = x[1:]
+                continue
+            if len(x) < 2 or len(x) < ord(x[1])+2:
+                opt.append(x)
+                break
+            elif DHCPOptions.has_key(o):
+                f = DHCPOptions[o]
+
+                if isinstance(f, str):
+                    olen = ord(x[1])
+                    opt.append( (f,x[2:olen+2]) )
+                    x = x[olen+2:]
+                else:
+                    olen = ord(x[1])
+                    try:
+                        left, val = f.getfield(pkt,x[2:olen+2])
+                    except:
+                        opt.append(x)
+                        break
+                    if left:
+                        otuple = (f.name, val, left)
+                    else:
+                        otuple = (f.name, val)
+                    opt.append(otuple)
+                    x = x[olen+2:]
+            else:
+                olen = ord(x[1])
+                opt.append((o, x[2:olen+2]))
+                x = x[olen+2:]
+        return opt
+    def i2m(self, pkt, x):
+        if type(x) is str:
+            return x
+        s = ""
+        for o in x:
+            if type(o) is tuple and len(o) in [2,3]:
+                name, val = o[:2]
+
+                if isinstance(name, int):
+                    onum, oval = name, val
+                elif DHCPRevOptions.has_key(name):
+                    onum, f = DHCPRevOptions[name]
+                    if  f is None:
+                        oval = val
+                    else:
+                        oval = f.addfield(pkt,"",f.any2i(pkt,val))
+                else:
+                    warning("Unknown field option %s" % name)
+                    continue
+                if len(o) > 2:
+                    oval += o[2]
+
+                s += chr(onum)
+                s += chr(len(oval))
+                s += oval
+
+            elif (type(o) is str and DHCPRevOptions.has_key(o) and 
+                  DHCPRevOptions[o][1] == None):
+                s += chr(DHCPRevOptions[o][0])
+            elif type(o) is int:
+                s += chr(o)+"\0"
+            elif type(o) is str:
+                s += o
+            else:
+                warning("Malformed option %s" % o)
+        return s
+
+
+class DHCP(Packet):
+    name = "DHCP options"
+    fields_desc = [ DHCPOptionsField("options","") ]
+
+
+bind_layers( UDP,           BOOTP,         dport=67, sport=68)
+bind_layers( UDP,           BOOTP,         dport=68, sport=67)
+bind_layers( BOOTP,         DHCP,          options='c\x82Sc')
+def dhcp_request(iface=None,**kargs):
+    if conf.checkIPaddr != 0:
+        warning("conf.checkIPaddr is not 0, I may not be able to match the answer")
+    if iface is None:
+        iface = conf.iface
+    fam,hw = get_if_raw_hwaddr(iface)
+    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)
+                 /BOOTP(chaddr=hw)/DHCP(options=[("message-type","discover"),"end"]),iface=iface,**kargs)
+
+
+class BOOTP_am(AnsweringMachine):
+    function_name = "bootpd"
+    filter = "udp and port 68 and port 67"
+    send_function = staticmethod(sendp)
+    def parse_options(self, pool=Net("192.168.1.128/25"), network="192.168.1.0/24",gw="192.168.1.1",
+                      domain="localnet", renewal_time=60, lease_time=1800):
+        if type(pool) is str:
+            poom = Net(pool)
+        self.domain = domain
+        netw,msk = (network.split("/")+["32"])[:2]
+        msk = itom(int(msk))
+        self.netmask = ltoa(msk)
+        self.network = ltoa(atol(netw)&msk)
+        self.broadcast = ltoa( atol(self.network) | (0xffffffff&~msk) )
+        self.gw = gw
+        if isinstance(pool,Gen):
+            pool = [k for k in pool if k not in [gw, self.network, self.broadcast]]
+            pool.reverse()
+        if len(pool) == 1:
+            pool, = pool
+        self.pool = pool
+        self.lease_time = lease_time
+        self.renewal_time = renewal_time
+        self.leases = {}
+
+    def is_request(self, req):
+        if not req.haslayer(BOOTP):
+            return 0
+        reqb = req.getlayer(BOOTP)
+        if reqb.op != 1:
+            return 0
+        return 1
+
+    def print_reply(self, req, reply):
+        print "Reply %s to %s" % (reply.getlayer(IP).dst,reply.dst)
+
+    def make_reply(self, req):        
+        mac = req.src
+        if type(self.pool) is list:
+            if not self.leases.has_key(mac):
+                self.leases[mac] = self.pool.pop()
+            ip = self.leases[mac]
+        else:
+            ip = self.pool
+            
+        repb = req.getlayer(BOOTP).copy()
+        repb.op="BOOTREPLY"
+        repb.yiaddr = ip
+        repb.siaddr = self.gw
+        repb.ciaddr = self.gw
+        repb.giaddr = self.gw
+        del(repb.payload)
+        rep=Ether(dst=mac)/IP(dst=ip)/UDP(sport=req.dport,dport=req.sport)/repb
+        return rep
+
+
+class DHCP_am(BOOTP_am):
+    function_name="dhcpd"
+    def make_reply(self, req):
+        resp = BOOTP_am.make_reply(self, req)
+        if DHCP in req:
+            dhcp_options = [(op[0],{1:2,3:5}.get(op[1],op[1]))
+                            for op in req[DHCP].options
+                            if type(op) is tuple  and op[0] == "message-type"]
+            dhcp_options += [("server_id",self.gw),
+                             ("domain", self.domain),
+                             ("router", self.gw),
+                             ("name_server", self.gw),
+                             ("broadcast_address", self.broadcast),
+                             ("subnet_mask", self.netmask),
+                             ("renewal_time", self.renewal_time),
+                             ("lease_time", self.lease_time), 
+                             "end"
+                             ]
+            resp /= DHCP(options=dhcp_options)
+        return resp
+    
+
diff --git a/scapy/layers/dns.py b/scapy/layers/dns.py
new file mode 100644
index 0000000000000000000000000000000000000000..c880700e3a42ebba3095d5a412433569f2392375
--- /dev/null
+++ b/scapy/layers/dns.py
@@ -0,0 +1,316 @@
+import socket,struct
+
+from scapy.packet import *
+from scapy.fields import *
+from scapy.ansmachine import *
+from scapy.layers.inet import UDP
+
+class DNSStrField(StrField):
+    def i2m(self, pkt, x):
+        x = [k[:63] for k in x.split(".")] # Truncate chunks that cannont be encoded (more than 63 bytes..)
+        x = map(lambda y: chr(len(y))+y, x)
+        x = "".join(x)
+        if x[-1] != "\x00":
+            x += "\x00"
+        return x
+    def getfield(self, pkt, s):
+        n = ""
+        while 1:
+            l = ord(s[0])
+            s = s[1:]
+            if not l:
+                break
+            if l & 0xc0:
+                raise Scapy_Exception("DNS message can't be compressed at this point!")
+            else:
+                n += s[:l]+"."
+                s = s[l:]
+        return s, n
+
+
+class DNSRRCountField(ShortField):
+    holds_packets=1
+    def __init__(self, name, default, rr):
+        ShortField.__init__(self, name, default)
+        self.rr = rr
+    def _countRR(self, pkt):
+        x = getattr(pkt,self.rr)
+        i = 0
+        while isinstance(x, DNSRR) or isinstance(x, DNSQR):
+            x = x.payload
+            i += 1
+        return i
+        
+    def i2m(self, pkt, x):
+        if x is None:
+            x = self._countRR(pkt)
+        return x
+    def i2h(self, pkt, x):
+        if x is None:
+            x = self._countRR(pkt)
+        return x
+    
+
+def DNSgetstr(s,p):
+    name = ""
+    q = 0
+    jpath = [p]
+    while 1:
+        if p >= len(s):
+            warning("DNS RR prematured end (ofs=%i, len=%i)"%(p,len(s)))
+            break
+        l = ord(s[p])
+        p += 1
+        if l & 0xc0:
+            if not q:
+                q = p+1
+            if p >= len(s):
+                warning("DNS incomplete jump token at (ofs=%i)" % p)
+                break
+            p = ((l & 0x3f) << 8) + ord(s[p]) - 12
+            if p in jpath:
+                warning("DNS decompression loop detected")
+                break
+            jpath.append(p)
+            continue
+        elif l > 0:
+            name += s[p:p+l]+"."
+            p += l
+            continue
+        break
+    if q:
+        p = q
+    return name,p
+        
+
+class DNSRRField(StrField):
+    holds_packets=1
+    def __init__(self, name, countfld, passon=1):
+        StrField.__init__(self, name, None)
+        self.countfld = countfld
+        self.passon = passon
+    def i2m(self, pkt, x):
+        if x is None:
+            return ""
+        return str(x)
+    def decodeRR(self, name, s, p):
+        ret = s[p:p+10]
+        type,cls,ttl,rdlen = struct.unpack("!HHIH", ret)
+        p += 10
+        rr = DNSRR("\x00"+ret+s[p:p+rdlen])
+        if rr.type in [2, 3, 4, 5]:
+            rr.rdata = DNSgetstr(s,p)[0]
+        del(rr.rdlen)
+        
+        p += rdlen
+        
+        rr.rrname = name
+        return rr,p
+    def getfield(self, pkt, s):
+        if type(s) is tuple :
+            s,p = s
+        else:
+            p = 0
+        ret = None
+        c = getattr(pkt, self.countfld)
+        if c > len(s):
+            warning("wrong value: DNS.%s=%i" % (self.countfld,c))
+            return s,""
+        while c:
+            c -= 1
+            name,p = DNSgetstr(s,p)
+            rr,p = self.decodeRR(name, s, p)
+            if ret is None:
+                ret = rr
+            else:
+                ret.add_payload(rr)
+        if self.passon:
+            return (s,p),ret
+        else:
+            return s[p:],ret
+            
+            
+class DNSQRField(DNSRRField):
+    holds_packets=1
+    def decodeRR(self, name, s, p):
+        ret = s[p:p+4]
+        p += 4
+        rr = DNSQR("\x00"+ret)
+        rr.qname = name
+        return rr,p
+        
+        
+
+class RDataField(StrLenField):
+    def m2i(self, pkt, s):
+        family = None
+        if pkt.type == 1:
+            family = socket.AF_INET
+        elif pkt.type == 28:
+            family = socket.AF_INET6
+        elif pkt.type == 12:
+            s = DNSgetstr(s, 0)[0]
+        if family is not None:    
+            s = inet_ntop(family, s)
+        return s
+    def i2m(self, pkt, s):
+        if pkt.type == 1:
+            if s:
+                s = inet_aton(s)
+        elif pkt.type == 28:
+            if s:
+                s = inet_pton(socket.AF_INET6, s)
+        elif pkt.type in [2,3,4,5]:
+            s = "".join(map(lambda x: chr(len(x))+x, s.split(".")))
+            if ord(s[-1]):
+                s += "\x00"
+        return s
+
+class RDLenField(Field):
+    def __init__(self, name):
+        Field.__init__(self, name, None, "H")
+    def i2m(self, pkt, x):
+        if x is None:
+            rdataf = pkt.get_field("rdata")
+            x = len(rdataf.i2m(pkt, pkt.rdata))
+        return x
+    def i2h(self, pkt, x):
+        if x is None:
+            rdataf = pkt.get_field("rdata")
+            x = len(rdataf.i2m(pkt, pkt.rdata))
+        return x
+    
+
+class DNS(Packet):
+    name = "DNS"
+    fields_desc = [ ShortField("id",0),
+                    BitField("qr",0, 1),
+                    BitEnumField("opcode", 0, 4, {0:"QUERY",1:"IQUERY",2:"STATUS"}),
+                    BitField("aa", 0, 1),
+                    BitField("tc", 0, 1),
+                    BitField("rd", 0, 1),
+                    BitField("ra", 0 ,1),
+                    BitField("z", 0, 3),
+                    BitEnumField("rcode", 0, 4, {0:"ok", 1:"format-error", 2:"server-failure", 3:"name-error", 4:"not-implemented", 5:"refused"}),
+                    DNSRRCountField("qdcount", None, "qd"),
+                    DNSRRCountField("ancount", None, "an"),
+                    DNSRRCountField("nscount", None, "ns"),
+                    DNSRRCountField("arcount", None, "ar"),
+                    DNSQRField("qd", "qdcount"),
+                    DNSRRField("an", "ancount"),
+                    DNSRRField("ns", "nscount"),
+                    DNSRRField("ar", "arcount",0) ]
+    def answers(self, other):
+        return (isinstance(other, DNS)
+                and self.id == other.id
+                and self.qr == 1
+                and other.qr == 0)
+        
+    def mysummary(self):
+        type = ["Qry","Ans"][self.qr]
+        name = ""
+        if self.qr:
+            type = "Ans"
+            if self.ancount > 0 and isinstance(self.an, DNSRR):
+                name = ' "%s"' % self.an.rdata
+        else:
+            type = "Qry"
+            if self.qdcount > 0 and isinstance(self.qd, DNSQR):
+                name = ' "%s"' % self.qd.qname
+        return 'DNS %s%s ' % (type, name)
+
+dnstypes = { 0:"ANY", 255:"ALL",
+             1:"A", 2:"NS", 3:"MD", 4:"MD", 5:"CNAME", 6:"SOA", 7: "MB", 8:"MG",
+             9:"MR",10:"NULL",11:"WKS",12:"PTR",13:"HINFO",14:"MINFO",15:"MX",16:"TXT",
+             17:"RP",18:"AFSDB",28:"AAAA", 33:"SRV",38:"A6",39:"DNAME"}
+
+dnsqtypes = {251:"IXFR",252:"AXFR",253:"MAILB",254:"MAILA",255:"ALL"}
+dnsqtypes.update(dnstypes)
+dnsclasses =  {1: 'IN',  2: 'CS',  3: 'CH',  4: 'HS',  255: 'ANY'}
+
+
+class DNSQR(Packet):
+    name = "DNS Question Record"
+    show_indent=0
+    fields_desc = [ DNSStrField("qname",""),
+                    ShortEnumField("qtype", 1, dnsqtypes),
+                    ShortEnumField("qclass", 1, dnsclasses) ]
+                    
+                    
+
+class DNSRR(Packet):
+    name = "DNS Resource Record"
+    show_indent=0
+    fields_desc = [ DNSStrField("rrname",""),
+                    ShortEnumField("type", 1, dnstypes),
+                    ShortEnumField("rclass", 1, dnsclasses),
+                    IntField("ttl", 0),
+                    RDLenField("rdlen"),
+                    RDataField("rdata", "", length_from=lambda pkt:pkt.rdlen) ]
+
+bind_layers( UDP,           DNS,           dport=53)
+bind_layers( UDP,           DNS,           sport=53)
+def dyndns_add(nameserver, name, rdata, type="A", ttl=10):
+    """Send a DNS add message to a nameserver for "name" to have a new "rdata"
+dyndns_add(nameserver, name, rdata, type="A", ttl=10) -> result code (0=ok)
+
+example: dyndns_add("ns1.toto.com", "dyn.toto.com", "127.0.0.1")
+RFC2136
+"""
+    zone = name[name.find(".")+1:]
+    r=sr1(IP(dst=nameserver)/UDP()/DNS(opcode=5,
+                                       qd=[DNSQR(qname=zone, qtype="SOA")],
+                                       ns=[DNSRR(rrname=name, type="A",
+                                                 ttl=ttl, rdata=rdata)]),
+          verbose=0, timeout=5)
+    if r and r.haslayer(DNS):
+        return r.getlayer(DNS).rcode
+    else:
+        return -1
+    
+    
+    
+
+def dyndns_del(nameserver, name, type="ALL", ttl=10):
+    """Send a DNS delete message to a nameserver for "name"
+dyndns_del(nameserver, name, type="ANY", ttl=10) -> result code (0=ok)
+
+example: dyndns_del("ns1.toto.com", "dyn.toto.com")
+RFC2136
+"""
+    zone = name[name.find(".")+1:]
+    r=sr1(IP(dst=nameserver)/UDP()/DNS(opcode=5,
+                                       qd=[DNSQR(qname=zone, qtype="SOA")],
+                                       ns=[DNSRR(rrname=name, type=type,
+                                                 rclass="ANY", ttl=0, rdata="")]),
+          verbose=0, timeout=5)
+    if r and r.haslayer(DNS):
+        return r.getlayer(DNS).rcode
+    else:
+        return -1
+    
+
+class DNS_am(AnsweringMachine):
+    function_name="dns_spoof"
+    filter = "udp port 53"
+
+    def parse_options(self, joker="192.168.1.1", match=None):
+        if match is None:
+            self.match = {}
+        else:
+            self.match = match
+        self.joker=joker
+
+    def is_request(self, req):
+        return req.haslayer(DNS) and req.getlayer(DNS).qr == 0
+    
+    def make_reply(self, req):
+        ip = req.getlayer(IP)
+        dns = req.getlayer(DNS)
+        resp = IP(dst=ip.src, src=ip.dst)/UDP(dport=ip.sport,sport=ip.dport)
+        rdata = self.match.get(dns.qd.qname, self.joker)
+        resp /= DNS(id=dns.id, qr=1, qd=dns.qd,
+                    an=DNSRR(rrname=dns.qd.qname, ttl=10, rdata=rdata))
+        return resp
+
+
diff --git a/scapy/layers/dot11.py b/scapy/layers/dot11.py
new file mode 100644
index 0000000000000000000000000000000000000000..b09058fd2ffe77c896d20675ed5571823f36d842
--- /dev/null
+++ b/scapy/layers/dot11.py
@@ -0,0 +1,469 @@
+import re,struct
+
+from scapy.packet import *
+from scapy.fields import *
+from scapy.layers.l2 import *
+
+class PrismHeader(Packet):
+    """ iwpriv wlan0 monitor 3 """
+    name = "Prism header"
+    fields_desc = [ LEIntField("msgcode",68),
+                    LEIntField("len",144),
+                    StrFixedLenField("dev","",16),
+                    LEIntField("hosttime_did",0),
+                  LEShortField("hosttime_status",0),
+                  LEShortField("hosttime_len",0),
+                    LEIntField("hosttime",0),
+                    LEIntField("mactime_did",0),
+                  LEShortField("mactime_status",0),
+                  LEShortField("mactime_len",0),
+                    LEIntField("mactime",0),
+                    LEIntField("channel_did",0),
+                  LEShortField("channel_status",0),
+                  LEShortField("channel_len",0),
+                    LEIntField("channel",0),
+                    LEIntField("rssi_did",0),
+                  LEShortField("rssi_status",0),
+                  LEShortField("rssi_len",0),
+                    LEIntField("rssi",0),
+                    LEIntField("sq_did",0),
+                  LEShortField("sq_status",0),
+                  LEShortField("sq_len",0),
+                    LEIntField("sq",0),
+                    LEIntField("signal_did",0),
+                  LEShortField("signal_status",0),
+                  LEShortField("signal_len",0),
+              LESignedIntField("signal",0),
+                    LEIntField("noise_did",0),
+                  LEShortField("noise_status",0),
+                  LEShortField("noise_len",0),
+                    LEIntField("noise",0),
+                    LEIntField("rate_did",0),
+                  LEShortField("rate_status",0),
+                  LEShortField("rate_len",0),
+                    LEIntField("rate",0),
+                    LEIntField("istx_did",0),
+                  LEShortField("istx_status",0),
+                  LEShortField("istx_len",0),
+                    LEIntField("istx",0),
+                    LEIntField("frmlen_did",0),
+                  LEShortField("frmlen_status",0),
+                  LEShortField("frmlen_len",0),
+                    LEIntField("frmlen",0),
+                    ]
+    def answers(self, other):
+        if isinstance(other, PrismHeader):
+            return self.payload.answers(other.payload)
+        else:
+            return self.payload.answers(other)
+
+class RadioTap(Packet):
+    name = "RadioTap dummy"
+    fields_desc = [ ByteField('version', 0),
+                    ByteField('pad', 0),
+                    FieldLenField('len', None, 'notdecoded', '@H', adjust=lambda pkt,x:x+8),
+                    FlagsField('present', None, -32, ['TSFT','Flags','Rate','Channel','FHSS','dBm_AntSignal',
+                                                     'dBm_AntNoise','Lock_Quality','TX_Attenuation','dB_TX_Attenuation',
+                                                      'dBm_TX_Power', 'Antenna', 'dB_AntSignal', 'dB_AntNoise',
+                                                     'b14', 'b15','b16','b17','b18','b19','b20','b21','b22','b23',
+                                                     'b24','b25','b26','b27','b28','b29','b30','Ext']),
+                    StrLenField('notdecoded', "", length_from= lambda pkt:pkt.len-8) ]
+
+
+
+class Dot11SCField(LEShortField):
+    def is_applicable(self, pkt):
+        return pkt.type != 1 # control frame
+    def addfield(self, pkt, s, val):
+        if self.is_applicable(pkt):
+            return LEShortField.addfield(self, pkt, s, val)
+        else:
+            return s
+    def getfield(self, pkt, s):
+        if self.is_applicable(pkt):
+            return LEShortField.getfield(self, pkt, s)
+        else:
+            return s,None
+
+class Dot11(Packet):
+    name = "802.11"
+    fields_desc = [
+                    BitField("subtype", 0, 4),
+                    BitEnumField("type", 0, 2, ["Management", "Control", "Data", "Reserved"]),
+                    BitField("proto", 0, 2),
+                    FlagsField("FCfield", 0, 8, ["to-DS", "from-DS", "MF", "retry", "pw-mgt", "MD", "wep", "order"]),
+                    ShortField("ID",0),
+                    MACField("addr1", ETHER_ANY),
+                    Dot11Addr2MACField("addr2", ETHER_ANY),
+                    Dot11Addr3MACField("addr3", ETHER_ANY),
+                    Dot11SCField("SC", 0),
+                    Dot11Addr4MACField("addr4", ETHER_ANY) 
+                    ]
+    def mysummary(self):
+        return self.sprintf("802.11 %Dot11.type% %Dot11.subtype% %Dot11.addr2% > %Dot11.addr1%")
+    def guess_payload_class(self, payload):
+        if self.type == 0x02 and (self.subtype >= 0x08 and self.subtype <=0xF and self.subtype != 0xD):
+            return Dot11QoS
+	elif self.FCfield & 0x40:
+            return Dot11WEP
+        else:
+            return Packet.guess_payload_class(self, payload)
+    def answers(self, other):
+        if isinstance(other,Dot11):
+            if self.type == 0: # management
+                if self.addr1.lower() != other.addr2.lower(): # check resp DA w/ req SA
+                    return 0
+                if (other.subtype,self.subtype) in [(0,1),(2,3),(4,5)]:
+                    return 1
+                if self.subtype == other.subtype == 11: # auth
+                    return self.payload.answers(other.payload)
+            elif self.type == 1: # control
+                return 0
+            elif self.type == 2: # data
+                return self.payload.answers(other.payload)
+            elif self.type == 3: # reserved
+                return 0
+        return 0
+    def unwep(self, key=None, warn=1):
+        if self.FCfield & 0x40 == 0:
+            if warn:
+                warning("No WEP to remove")
+            return
+        if  isinstance(self.payload.payload, NoPayload):
+            if key or conf.wepkey:
+                self.payload.decrypt(key)
+            if isinstance(self.payload.payload, NoPayload):
+                if warn:
+                    warning("Dot11 can't be decrypted. Check conf.wepkey.")
+                return
+        self.FCfield &= ~0x40
+        self.payload=self.payload.payload
+
+
+class Dot11QoS(Packet):
+    name = "802.11 QoS"
+    fields_desc = [ BitField("TID",None,4),
+                    BitField("EOSP",None,1),
+                    BitField("Ack Policy",None,2),
+                    BitField("Reserved",None,1),
+                    ByteField("TXOP",None) ]
+    def guess_payload_class(self, payload):
+        if isinstance(self.underlayer, Dot11):
+            if self.underlayer.FCfield & 0x40:
+                return Dot11WEP
+        return Packet.guess_payload_class(self, payload)
+
+
+capability_list = [ "res8", "res9", "short-slot", "res11",
+                    "res12", "DSSS-OFDM", "res14", "res15",
+                   "ESS", "IBSS", "CFP", "CFP-req",
+                   "privacy", "short-preamble", "PBCC", "agility"]
+
+reason_code = {0:"reserved",1:"unspec", 2:"auth-expired",
+               3:"deauth-ST-leaving",
+               4:"inactivity", 5:"AP-full", 6:"class2-from-nonauth",
+               7:"class3-from-nonass", 8:"disas-ST-leaving",
+               9:"ST-not-auth"}
+
+status_code = {0:"success", 1:"failure", 10:"cannot-support-all-cap",
+               11:"inexist-asso", 12:"asso-denied", 13:"algo-unsupported",
+               14:"bad-seq-num", 15:"challenge-failure",
+               16:"timeout", 17:"AP-full",18:"rate-unsupported" }
+
+class Dot11Beacon(Packet):
+    name = "802.11 Beacon"
+    fields_desc = [ LELongField("timestamp", 0),
+                    LEShortField("beacon_interval", 0x0064),
+                    FlagsField("cap", 0, 16, capability_list) ]
+    
+
+class Dot11Elt(Packet):
+    name = "802.11 Information Element"
+    fields_desc = [ ByteEnumField("ID", 0, {0:"SSID", 1:"Rates", 2: "FHset", 3:"DSset", 4:"CFset", 5:"TIM", 6:"IBSSset", 16:"challenge",
+                                            42:"ERPinfo", 46:"QoS Capability", 47:"ERPinfo", 48:"RSNinfo", 50:"ESRates",221:"vendor",68:"reserved"}),
+                    FieldLenField("len", None, "info", "B"),
+                    StrLenField("info", "", length_from=lambda x:x.len) ]
+    def mysummary(self):
+        if self.ID == 0:
+            return "SSID=%s"%repr(self.info),[Dot11]
+        else:
+            return ""
+
+class Dot11ATIM(Packet):
+    name = "802.11 ATIM"
+
+class Dot11Disas(Packet):
+    name = "802.11 Disassociation"
+    fields_desc = [ LEShortEnumField("reason", 1, reason_code) ]
+
+class Dot11AssoReq(Packet):
+    name = "802.11 Association Request"
+    fields_desc = [ FlagsField("cap", 0, 16, capability_list),
+                    LEShortField("listen_interval", 0x00c8) ]
+
+
+class Dot11AssoResp(Packet):
+    name = "802.11 Association Response"
+    fields_desc = [ FlagsField("cap", 0, 16, capability_list),
+                    LEShortField("status", 0),
+                    LEShortField("AID", 0) ]
+
+class Dot11ReassoReq(Packet):
+    name = "802.11 Reassociation Request"
+    fields_desc = [ FlagsField("cap", 0, 16, capability_list),
+                    MACField("current_AP", ETHER_ANY),
+                    LEShortField("listen_interval", 0x00c8) ]
+
+
+class Dot11ReassoResp(Dot11AssoResp):
+    name = "802.11 Reassociation Response"
+
+class Dot11ProbeReq(Packet):
+    name = "802.11 Probe Request"
+    
+class Dot11ProbeResp(Packet):
+    name = "802.11 Probe Response"
+    fields_desc = [ LELongField("timestamp", 0),
+                    LEShortField("beacon_interval", 0x0064),
+                    FlagsField("cap", 0, 16, capability_list) ]
+    
+class Dot11Auth(Packet):
+    name = "802.11 Authentication"
+    fields_desc = [ LEShortEnumField("algo", 0, ["open", "sharedkey"]),
+                    LEShortField("seqnum", 0),
+                    LEShortEnumField("status", 0, status_code) ]
+    def answers(self, other):
+        if self.seqnum == other.seqnum+1:
+            return 1
+        return 0
+
+class Dot11Deauth(Packet):
+    name = "802.11 Deauthentication"
+    fields_desc = [ LEShortEnumField("reason", 1, reason_code) ]
+
+
+
+class Dot11WEP(Packet):
+    name = "802.11 WEP packet"
+    fields_desc = [ StrFixedLenField("iv", "\0\0\0", 3),
+                    ByteField("keyid", 0),
+                    StrField("wepdata",None,remain=4),
+                    IntField("icv",None) ]
+
+    def post_dissect(self, s):
+#        self.icv, = struct.unpack("!I",self.wepdata[-4:])
+#        self.wepdata = self.wepdata[:-4]
+        self.decrypt()
+
+    def build_payload(self):
+        if self.wepdata is None:
+            return Packet.build_payload(self)
+        return ""
+
+    def post_build(self, p, pay):
+        if self.wepdata is None:
+            key = conf.wepkey
+            if key:
+                if self.icv is None:
+                    pay += struct.pack("<I",crc32(pay))
+                    icv = ""
+                else:
+                    icv = p[4:8]
+                c = ARC4.new(self.iv+key)
+                p = p[:4]+c.encrypt(pay)+icv
+            else:
+                warning("No WEP key set (conf.wepkey).. strange results expected..")
+        return p
+            
+
+    def decrypt(self,key=None):
+        if key is None:
+            key = conf.wepkey
+        if key:
+            c = ARC4.new(self.iv+key)
+            self.add_payload(LLC(c.decrypt(self.wepdata)))
+                    
+
+bind_layers( PrismHeader,   Dot11,         )
+bind_layers( RadioTap,      Dot11,         )
+bind_layers( Dot11,         LLC,           type=2)
+bind_layers( Dot11QoS,      LLC,           )
+bind_layers( Dot11,         Dot11AssoReq,    subtype=0, type=0)
+bind_layers( Dot11,         Dot11AssoResp,   subtype=1, type=0)
+bind_layers( Dot11,         Dot11ReassoReq,  subtype=2, type=0)
+bind_layers( Dot11,         Dot11ReassoResp, subtype=3, type=0)
+bind_layers( Dot11,         Dot11ProbeReq,   subtype=4, type=0)
+bind_layers( Dot11,         Dot11ProbeResp,  subtype=5, type=0)
+bind_layers( Dot11,         Dot11Beacon,     subtype=8, type=0)
+bind_layers( Dot11,         Dot11ATIM,       subtype=9, type=0)
+bind_layers( Dot11,         Dot11Disas,      subtype=10, type=0)
+bind_layers( Dot11,         Dot11Auth,       subtype=11, type=0)
+bind_layers( Dot11,         Dot11Deauth,     subtype=12, type=0)
+bind_layers( Dot11Beacon,     Dot11Elt,    )
+bind_layers( Dot11AssoReq,    Dot11Elt,    )
+bind_layers( Dot11AssoResp,   Dot11Elt,    )
+bind_layers( Dot11ReassoReq,  Dot11Elt,    )
+bind_layers( Dot11ReassoResp, Dot11Elt,    )
+bind_layers( Dot11ProbeReq,   Dot11Elt,    )
+bind_layers( Dot11ProbeResp,  Dot11Elt,    )
+bind_layers( Dot11Auth,       Dot11Elt,    )
+bind_layers( Dot11Elt,        Dot11Elt,    )
+
+
+conf.l2types.register(801, Dot11)
+conf.l2types.register_num2layer(105, Dot11)
+conf.l2types.register(802, PrismHeader)
+conf.l2types.register(803, RadioTap)
+conf.l2types.register_num2layer(127, RadioTap)
+
+
+class WiFi_am(AnsweringMachine):
+    """Before using this, initialize "iffrom" and "ifto" interfaces:
+iwconfig iffrom mode monitor
+iwpriv orig_ifto hostapd 1
+ifconfig ifto up
+note: if ifto=wlan0ap then orig_ifto=wlan0
+note: ifto and iffrom must be set on the same channel
+ex:
+ifconfig eth1 up
+iwconfig eth1 mode monitor
+iwconfig eth1 channel 11
+iwpriv wlan0 hostapd 1
+ifconfig wlan0ap up
+iwconfig wlan0 channel 11
+iwconfig wlan0 essid dontexist
+iwconfig wlan0 mode managed
+"""
+    function_name = "airpwn"
+    filter = None
+    
+    def parse_options(iffrom, ifto, replace, pattern="", ignorepattern=""):
+        self.iffrom = iffrom
+        self.ifto = ifto
+        ptrn = re.compile(pattern)
+        iptrn = re.compile(ignorepattern)
+        
+    def is_request(self, pkt):
+        if not isinstance(pkt,Dot11):
+            return 0
+        if not pkt.FCfield & 1:
+            return 0
+        if not pkt.haslayer(TCP):
+            return 0
+        ip = pkt.getlayer(IP)
+        tcp = pkt.getlayer(TCP)
+        pay = str(tcp.payload)
+        if not self.ptrn.match(pay):
+            return 0
+        if self.iptrn.match(pay):
+            return 0
+
+    def make_reply(self, p):
+        ip = p.getlayer(IP)
+        tcp = p.getlayer(TCP)
+        pay = str(tcp.payload)
+        del(p.payload.payload.payload)
+        p.FCfield="from-DS"
+        p.addr1,p.addr2 = p.addr2,p.addr1
+        p /= IP(src=ip.dst,dst=ip.src)
+        p /= TCP(sport=tcp.dport, dport=tcp.sport,
+                 seq=tcp.ack, ack=tcp.seq+len(pay),
+                 flags="PA")
+        q = p.copy()
+        p /= self.replace
+        q.ID += 1
+        q.getlayer(TCP).flags="RA"
+        q.getlayer(TCP).seq+=len(replace)
+        return [p,q]
+    
+    def print_reply(self):
+        print p.sprintf("Sent %IP.src%:%IP.sport% > %IP.dst%:%TCP.dport%")
+
+    def send_reply(self, reply):
+        sendp(reply, iface=self.ifto, **self.optsend)
+
+    def sniff(self):
+        sniff(iface=self.iffrom, **self.optsniff)
+
+
+
+plst=[]
+def get_toDS():
+    global plst
+    while 1:
+        p,=sniff(iface="eth1",count=1)
+        if not isinstance(p,Dot11):
+            continue
+        if p.FCfield & 1:
+            plst.append(p)
+            print "."
+
+
+#    if not ifto.endswith("ap"):
+#        print "iwpriv %s hostapd 1" % ifto
+#        os.system("iwpriv %s hostapd 1" % ifto)
+#        ifto += "ap"
+#        
+#    os.system("iwconfig %s mode monitor" % iffrom)
+#    
+
+def airpwn(iffrom, ifto, replace, pattern="", ignorepattern=""):
+    """Before using this, initialize "iffrom" and "ifto" interfaces:
+iwconfig iffrom mode monitor
+iwpriv orig_ifto hostapd 1
+ifconfig ifto up
+note: if ifto=wlan0ap then orig_ifto=wlan0
+note: ifto and iffrom must be set on the same channel
+ex:
+ifconfig eth1 up
+iwconfig eth1 mode monitor
+iwconfig eth1 channel 11
+iwpriv wlan0 hostapd 1
+ifconfig wlan0ap up
+iwconfig wlan0 channel 11
+iwconfig wlan0 essid dontexist
+iwconfig wlan0 mode managed
+"""
+    
+    ptrn = re.compile(pattern)
+    iptrn = re.compile(ignorepattern)
+    def do_airpwn(p, ifto=ifto, replace=replace, ptrn=ptrn, iptrn=iptrn):
+        if not isinstance(p,Dot11):
+            return
+        if not p.FCfield & 1:
+            return
+        if not p.haslayer(TCP):
+            return
+        ip = p.getlayer(IP)
+        tcp = p.getlayer(TCP)
+        pay = str(tcp.payload)
+#        print "got tcp"
+        if not ptrn.match(pay):
+            return
+#        print "match 1"
+        if iptrn.match(pay):
+            return
+#        print "match 2"
+        del(p.payload.payload.payload)
+        p.FCfield="from-DS"
+        p.addr1,p.addr2 = p.addr2,p.addr1
+        q = p.copy()
+        p /= IP(src=ip.dst,dst=ip.src)
+        p /= TCP(sport=tcp.dport, dport=tcp.sport,
+                 seq=tcp.ack, ack=tcp.seq+len(pay),
+                 flags="PA")
+        q = p.copy()
+        p /= replace
+        q.ID += 1
+        q.getlayer(TCP).flags="RA"
+        q.getlayer(TCP).seq+=len(replace)
+        
+        sendp([p,q], iface=ifto, verbose=0)
+#        print "send",repr(p)        
+#        print "send",repr(q)
+        print p.sprintf("Sent %IP.src%:%IP.sport% > %IP.dst%:%TCP.dport%")
+
+    sniff(iface=iffrom,prn=do_airpwn)
+
+            
+        
diff --git a/scapy/layers/gprs.py b/scapy/layers/gprs.py
new file mode 100644
index 0000000000000000000000000000000000000000..8686fcc1917a843d55b9b1bd0eadecc84d15e201
--- /dev/null
+++ b/scapy/layers/gprs.py
@@ -0,0 +1,8 @@
+class GPRS(Packet):
+    name = "GPRSdummy"
+    fields_desc = [
+        StrStopField("dummy","","\x65\x00\x00",1)
+        ]
+
+
+bind_layers( GPRS,          IP,            )
diff --git a/scapy/layers/hsrp.py b/scapy/layers/hsrp.py
new file mode 100644
index 0000000000000000000000000000000000000000..b8b57fbdf3b08d5efee08aa6fa084f343fb7d8cf
--- /dev/null
+++ b/scapy/layers/hsrp.py
@@ -0,0 +1,19 @@
+class HSRP(Packet):
+    name = "HSRP"
+    fields_desc = [
+        ByteField("version", 0),
+        ByteEnumField("opcode", 0, { 0:"Hello"}),
+        ByteEnumField("state", 16, { 16:"Active"}),
+        ByteField("hellotime", 3),
+        ByteField("holdtime", 10),
+        ByteField("priority", 120),
+        ByteField("group", 1),
+        ByteField("reserved", 0),
+        StrFixedLenField("auth","cisco",8),
+        IPField("virtualIP","192.168.1.1") ]
+        
+
+
+        
+        
+bind_layers( UDP,           HSRP,          dport=1985, sport=1985)
diff --git a/scapy/layers/inet.py b/scapy/layers/inet.py
new file mode 100644
index 0000000000000000000000000000000000000000..98f47d8e8be3d7adbacca44c8b92b92ed698f285
--- /dev/null
+++ b/scapy/layers/inet.py
@@ -0,0 +1,818 @@
+import os,time,struct,re,socket
+from select import select
+
+from scapy.layers.l2 import *
+from scapy.fields import *
+from scapy.volatile import *
+from config import conf
+from sendrecv import sr,sr1
+
+
+
+####################
+## IP Tools class ##
+####################
+
+class IPTools:
+    """Add more powers to a class that have a "src" attribute."""
+    def whois(self):
+        os.system("whois %s" % self.src)
+    def ottl(self):
+        t = [32,64,128,255]+[self.ttl]
+        t.sort()
+        return t[t.index(self.ttl)+1]
+    def hops(self):
+        return self.ottl()-self.ttl-1 
+
+
+
+class IPoptionsField(StrField):
+    def i2m(self, pkt, x):
+        return x+"\x00"*(3-((len(x)+3)%4))
+    def getfield(self, pkt, s):
+        opsz = (pkt.ihl-5)*4
+        if opsz < 0:
+            warning("bad ihl (%i). Assuming ihl=5"%pkt.ihl)
+            opsz = 0
+        return s[opsz:],s[:opsz]
+    def randval(self):
+        return RandBin(RandNum(0,39))
+
+
+TCPOptions = (
+              { 0 : ("EOL",None),
+                1 : ("NOP",None),
+                2 : ("MSS","!H"),
+                3 : ("WScale","!B"),
+                4 : ("SAckOK",None),
+                5 : ("SAck","!"),
+                8 : ("Timestamp","!II"),
+                14 : ("AltChkSum","!BH"),
+                15 : ("AltChkSumOpt",None)
+                },
+              { "EOL":0,
+                "NOP":1,
+                "MSS":2,
+                "WScale":3,
+                "SAckOK":4,
+                "SAck":5,
+                "Timestamp":8,
+                "AltChkSum":14,
+                "AltChkSumOpt":15,
+                } )
+
+class TCPOptionsField(StrField):
+    islist=1
+    def getfield(self, pkt, s):
+        opsz = (pkt.dataofs-5)*4
+        if opsz < 0:
+            warning("bad dataofs (%i). Assuming dataofs=5"%pkt.dataofs)
+            opsz = 0
+        return s[opsz:],self.m2i(pkt,s[:opsz])
+    def m2i(self, pkt, x):
+        opt = []
+        while x:
+            onum = ord(x[0])
+            if onum == 0:
+                opt.append(("EOL",None))
+                x=x[1:]
+                break
+            if onum == 1:
+                opt.append(("NOP",None))
+                x=x[1:]
+                continue
+            olen = ord(x[1])
+            if olen < 2:
+                warning("Malformed TCP option (announced length is %i)" % olen)
+                olen = 2
+            oval = x[2:olen]
+            if TCPOptions[0].has_key(onum):
+                oname, ofmt = TCPOptions[0][onum]
+                if onum == 5: #SAck
+                    ofmt += "%iI" % (len(oval)/4)
+                if ofmt and struct.calcsize(ofmt) == len(oval):
+                    oval = struct.unpack(ofmt, oval)
+                    if len(oval) == 1:
+                        oval = oval[0]
+                opt.append((oname, oval))
+            else:
+                opt.append((onum, oval))
+            x = x[olen:]
+        return opt
+    
+    def i2m(self, pkt, x):
+        opt = ""
+        for oname,oval in x:
+            if type(oname) is str:
+                if oname == "NOP":
+                    opt += "\x01"
+                    continue
+                elif oname == "EOL":
+                    opt += "\x00"
+                    continue
+                elif TCPOptions[1].has_key(oname):
+                    onum = TCPOptions[1][oname]
+                    ofmt = TCPOptions[0][onum][1]
+                    if onum == 5: #SAck
+                        ofmt += "%iI" % len(oval)
+                    if ofmt is not None and (type(oval) is not str or "s" in ofmt):
+                        if type(oval) is not tuple:
+                            oval = (oval,)
+                        oval = struct.pack(ofmt, *oval)
+                else:
+                    warning("option [%s] unknown. Skipped."%oname)
+                    continue
+            else:
+                onum = oname
+                if type(oval) is not str:
+                    warning("option [%i] is not string."%onum)
+                    continue
+            opt += chr(onum)+chr(2+len(oval))+oval
+        return opt+"\x00"*(3-((len(opt)+3)%4))
+    def randval(self):
+        return [] # XXX
+    
+
+class ICMPTimeStampField(IntField):
+    re_hmsm = re.compile("([0-2]?[0-9])[Hh:](([0-5]?[0-9])([Mm:]([0-5]?[0-9])([sS:.]([0-9]{0,3}))?)?)?$")
+    def i2repr(self, pkt, val):
+        if val is None:
+            return "--"
+        else:
+            sec, milli = divmod(val, 1000)
+            min, sec = divmod(sec, 60)
+            hour, min = divmod(min, 60)
+            return "%d:%d:%d.%d" %(hour, min, sec, int(milli))
+    def any2i(self, pkt, val):
+        if type(val) is str:
+            hmsms = self.re_hmsm.match(val)
+            if hmsms:
+                h,_,m,_,s,_,ms = hmsms = hmsms.groups()
+                ms = int(((ms or "")+"000")[:3])
+                val = ((int(h)*60+int(m or 0))*60+int(s or 0))*1000+ms
+            else:
+                val = 0
+        elif val is None:
+            val = int((time.time()%(24*60*60))*1000)
+        return val
+
+
+class IP(Packet, IPTools):
+    name = "IP"
+    fields_desc = [ BitField("version" , 4 , 4),
+                    BitField("ihl", None, 4),
+                    XByteField("tos", 0),
+                    ShortField("len", None),
+                    ShortField("id", 1),
+                    FlagsField("flags", 0, 3, ["MF","DF","evil"]),
+                    BitField("frag", 0, 13),
+                    ByteField("ttl", 64),
+                    ByteEnumField("proto", 0, IP_PROTOS),
+                    XShortField("chksum", None),
+                    #IPField("src", "127.0.0.1"),
+                    Emph(SourceIPField("src","dst")),
+                    Emph(IPField("dst", "127.0.0.1")),
+                    IPoptionsField("options", "") ]
+    def post_build(self, p, pay):
+        ihl = self.ihl
+        if ihl is None:
+            ihl = len(p)/4
+            p = chr(((self.version&0xf)<<4) | ihl&0x0f)+p[1:]
+        if self.len is None:
+            l = len(p)+len(pay)
+            p = p[:2]+struct.pack("!H", l)+p[4:]
+        if self.chksum is None:
+            ck = checksum(p)
+            p = p[:10]+chr(ck>>8)+chr(ck&0xff)+p[12:]
+        return p+pay
+
+    def extract_padding(self, s):
+        l = self.len - (self.ihl << 2)
+        return s[:l],s[l:]
+
+    def send(self, s, slp=0):
+        for p in self:
+            try:
+                s.sendto(str(p), (p.dst,0))
+            except socket.error, msg:
+                log_runtime.error(msg)
+            if slp:
+                time.sleep(slp)
+    def hashret(self):
+        if ( (self.proto == socket.IPPROTO_ICMP)
+             and (isinstance(self.payload, ICMP))
+             and (self.payload.type in [3,4,5,11,12]) ):
+            return self.payload.payload.hashret()
+        else:
+            if conf.checkIPsrc and conf.checkIPaddr:
+                return strxor(inet_aton(self.src),inet_aton(self.dst))+struct.pack("B",self.proto)+self.payload.hashret()
+            else:
+                return struct.pack("B", self.proto)+self.payload.hashret()
+    def answers(self, other):
+        if not isinstance(other,IP):
+            return 0
+        if conf.checkIPaddr and (self.dst != other.src):
+            return 0
+        if ( (self.proto == socket.IPPROTO_ICMP) and
+             (isinstance(self.payload, ICMP)) and
+             (self.payload.type in [3,4,5,11,12]) ):
+            # ICMP error message
+            return self.payload.payload.answers(other)
+
+        else:
+            if ( (conf.checkIPaddr and (self.src != other.dst)) or
+                 (self.proto != other.proto) ):
+                return 0
+            return self.payload.answers(other.payload)
+    def mysummary(self):
+        s = self.sprintf("%IP.src% > %IP.dst% %IP.proto%")
+        if self.frag:
+            s += " frag:%i" % self.frag
+        return s
+                 
+    
+
+class TCP(Packet):
+    name = "TCP"
+    fields_desc = [ ShortEnumField("sport", 20, TCP_SERVICES),
+                    ShortEnumField("dport", 80, TCP_SERVICES),
+                    IntField("seq", 0),
+                    IntField("ack", 0),
+                    BitField("dataofs", None, 4),
+                    BitField("reserved", 0, 4),
+                    FlagsField("flags", 0x2, 8, "FSRPAUEC"),
+                    ShortField("window", 8192),
+                    XShortField("chksum", None),
+                    ShortField("urgptr", 0),
+                    TCPOptionsField("options", {}) ]
+    def post_build(self, p, pay):
+        p += pay
+        dataofs = self.dataofs
+        if dataofs is None:
+            dataofs = 5+((len(self.get_field("options").i2m(self,self.options))+3)/4)
+            p = p[:12]+chr((dataofs << 4) | ord(p[12])&0x0f)+p[13:]
+        if self.chksum is None:
+            if isinstance(self.underlayer, IP):
+                if self.underlayer.len is not None:
+                    ln = self.underlayer.len-20
+                else:
+                    ln = len(p)
+                psdhdr = struct.pack("!4s4sHH",
+                                     inet_aton(self.underlayer.src),
+                                     inet_aton(self.underlayer.dst),
+                                     self.underlayer.proto,
+                                     ln)
+                ck=checksum(psdhdr+p)
+                p = p[:16]+struct.pack("!H", ck)+p[18:]
+            elif isinstance(self.underlayer, IPv6) or isinstance(self.underlayer, _IPv6OptionHeader):
+                ck = in6_chksum(socket.IPPROTO_TCP, self.underlayer, p)
+                p = p[:16]+struct.pack("!H", ck)+p[18:]
+            else:
+                warning("No IP underlayer to compute checksum. Leaving null.")
+        return p
+    def hashret(self):
+        if conf.checkIPsrc:
+            return struct.pack("H",self.sport ^ self.dport)+self.payload.hashret()
+        else:
+            return self.payload.hashret()
+    def answers(self, other):
+        if not isinstance(other, TCP):
+            return 0
+        if conf.checkIPsrc:
+            if not ((self.sport == other.dport) and
+                    (self.dport == other.sport)):
+                return 0
+        if (abs(other.seq-self.ack) > 2+len(other.payload)):
+            return 0
+        return 1
+    def mysummary(self):
+        if isinstance(self.underlayer, IP):
+            return self.underlayer.sprintf("TCP %IP.src%:%TCP.sport% > %IP.dst%:%TCP.dport% %TCP.flags%")
+        elif isinstance(self.underlayer, IPv6):
+            return self.underlayer.sprintf("TCP %IPv6.src%:%TCP.sport% > %IPv6.dst%:%TCP.dport% %TCP.flags%")
+        else:
+            return self.sprintf("TCP %TCP.sport% > %TCP.dport% %TCP.flags%")
+
+class UDP(Packet):
+    name = "UDP"
+    fields_desc = [ ShortEnumField("sport", 53, UDP_SERVICES),
+                    ShortEnumField("dport", 53, UDP_SERVICES),
+                    ShortField("len", None),
+                    XShortField("chksum", None), ]
+    def post_build(self, p, pay):
+        p += pay
+        l = self.len
+        if l is None:
+            l = len(p)
+            p = p[:4]+struct.pack("!H",l)+p[6:]
+        if self.chksum is None:
+            if isinstance(self.underlayer, IP):
+                if self.underlayer.len is not None:
+                    ln = self.underlayer.len-20
+                else:
+                    ln = len(p)
+                psdhdr = struct.pack("!4s4sHH",
+                                     inet_aton(self.underlayer.src),
+                                     inet_aton(self.underlayer.dst),
+                                     self.underlayer.proto,
+                                     ln)
+                ck=checksum(psdhdr+p)
+                p = p[:6]+struct.pack("!H", ck)+p[8:]
+            elif isinstance(self.underlayer, IPv6) or isinstance(self.underlayer, _IPv6OptionHeader):
+                ck = in6_chksum(socket.IPPROTO_UDP, self.underlayer, p)
+                p = p[:6]+struct.pack("!H", ck)+p[8:]
+            else:
+                warning("No IP underlayer to compute checksum. Leaving null.")
+        return p
+    def extract_padding(self, s):
+        l = self.len - 8
+        return s[:l],s[l:]
+    def hashret(self):
+        return self.payload.hashret()
+    def answers(self, other):
+        if not isinstance(other, UDP):
+            return 0
+        if conf.checkIPsrc:
+            if self.dport != other.sport:
+                return 0
+        return self.payload.answers(other.payload)
+    def mysummary(self):
+        if isinstance(self.underlayer, IP):
+            return self.underlayer.sprintf("UDP %IP.src%:%UDP.sport% > %IP.dst%:%UDP.dport%")
+        elif isinstance(self.underlayer, IPv6):
+            return self.underlayer.sprintf("UDP %IPv6.src%:%UDP.sport% > %IPv6.dst%:%UDP.dport%")
+        else:
+            return self.sprintf("UDP %UDP.sport% > %UDP.dport%")    
+
+icmptypes = { 0 : "echo-reply",
+              3 : "dest-unreach",
+              4 : "source-quench",
+              5 : "redirect",
+              8 : "echo-request",
+              9 : "router-advertisement",
+              10 : "router-solicitation",
+              11 : "time-exceeded",
+              12 : "parameter-problem",
+              13 : "timestamp-request",
+              14 : "timestamp-reply",
+              15 : "information-request",
+              16 : "information-response",
+              17 : "address-mask-request",
+              18 : "address-mask-reply" }
+
+class ICMP(Packet):
+    name = "ICMP"
+    fields_desc = [ ByteEnumField("type",8, icmptypes),
+                    ByteField("code",0),
+                    XShortField("chksum", None),
+                    ConditionalField(XShortField("id",0),  lambda pkt:pkt.type in [0,8,13,14,15,16]),
+                    ConditionalField(XShortField("seq",0), lambda pkt:pkt.type in [0,8,13,14,15,16]),
+                    ConditionalField(ICMPTimeStampField("ts_ori", None), lambda pkt:pkt.type in [13,14]),
+                    ConditionalField(ICMPTimeStampField("ts_rx", None), lambda pkt:pkt.type in [13,14]),
+                    ConditionalField(ICMPTimeStampField("ts_tx", None), lambda pkt:pkt.type in [13,14]),
+                    ConditionalField(IPField("gw","0.0.0.0"),  lambda pkt:pkt.type==5),
+                    ConditionalField(ByteField("ptr",0),   lambda pkt:pkt.type==12),
+                    ConditionalField(X3BytesField("reserved",0), lambda pkt:pkt.type==12),
+                    ConditionalField(IntField("unused",0), lambda pkt:pkt.type not in [0,5,8,12,13,14,15,16]),
+                    ]
+    def post_build(self, p, pay):
+        p += pay
+        if self.chksum is None:
+            ck = checksum(p)
+            p = p[:2]+chr(ck>>8)+chr(ck&0xff)+p[4:]
+        return p
+    
+    def hashret(self):
+        return struct.pack("HH",self.id,self.seq)+self.payload.hashret()
+    def answers(self, other):
+        if not isinstance(other,ICMP):
+            return 0
+        if ( (other.type,self.type) in [(8,0),(13,14),(15,16),(17,18)] and
+             self.id == other.id and
+             self.seq == other.seq ):
+            return 1
+        return 0
+
+    def guess_payload_class(self, payload):
+        if self.type in [3,4,5,11,12]:
+            return IPerror
+        else:
+            return None
+    def mysummary(self):
+        if isinstance(self.underlayer, IP):
+            return self.underlayer.sprintf("ICMP %IP.src% > %IP.dst% %ICMP.type% %ICMP.code%")
+        else:
+            return self.sprintf("ICMP %ICMP.type% %ICMP.code%")
+    
+        
+
+
+
+class IPerror(IP):
+    name = "IP in ICMP"
+    def answers(self, other):
+        if not isinstance(other, IP):
+            return 0
+        if not ( ((conf.checkIPsrc == 0) or (self.dst == other.dst)) and
+                 (self.src == other.src) and
+                 ( ((conf.checkIPID == 0)
+                    or (self.id == other.id)
+                    or (conf.checkIPID == 1 and self.id == socket.htons(other.id)))) and
+                 (self.proto == other.proto) ):
+            return 0
+        return self.payload.answers(other.payload)
+    def mysummary(self):
+        return Packet.mysummary(self)
+
+
+class TCPerror(TCP):
+    name = "TCP in ICMP"
+    def answers(self, other):
+        if not isinstance(other, TCP):
+            return 0
+        if conf.checkIPsrc:
+            if not ((self.sport == other.sport) and
+                    (self.dport == other.dport)):
+                return 0
+        if conf.check_TCPerror_seqack:
+            if self.seq is not None:
+                if self.seq != other.seq:
+                    return 0
+            if self.ack is not None:
+                if self.ack != other.ack:
+                    return 0
+        return 1
+    def mysummary(self):
+        return Packet.mysummary(self)
+
+
+class UDPerror(UDP):
+    name = "UDP in ICMP"
+    def answers(self, other):
+        if not isinstance(other, UDP):
+            return 0
+        if conf.checkIPsrc:
+            if not ((self.sport == other.sport) and
+                    (self.dport == other.dport)):
+                return 0
+        return 1
+    def mysummary(self):
+        return Packet.mysummary(self)
+
+                    
+
+class ICMPerror(ICMP):
+    name = "ICMP in ICMP"
+    def answers(self, other):
+        if not isinstance(other,ICMP):
+            return 0
+        if not ((self.type == other.type) and
+                (self.code == other.code)):
+            return 0
+        if self.code in [0,8,13,14,17,18]:
+            if (self.id == other.id and
+                self.seq == other.seq):
+                return 1
+            else:
+                return 0
+        else:
+            return 1
+    def mysummary(self):
+        return Packet.mysummary(self)
+
+bind_layers( Ether,         IP,            type=2048)
+bind_layers( CookedLinux,   IP,            proto=2048)
+bind_layers( GRE,           IP,            proto=2048)
+bind_layers( SNAP,          IP,            code=2048)
+bind_layers( IPerror,       IPerror,       frag=0, proto=4)
+bind_layers( IPerror,       ICMPerror,     frag=0, proto=1)
+bind_layers( IPerror,       TCPerror,      frag=0, proto=6)
+bind_layers( IPerror,       UDPerror,      frag=0, proto=17)
+bind_layers( IP,            IP,            frag=0, proto=4)
+bind_layers( IP,            ICMP,          frag=0, proto=1)
+bind_layers( IP,            TCP,           frag=0, proto=6)
+bind_layers( IP,            UDP,           frag=0, proto=17)
+bind_layers( IP,            GRE,           frag=0, proto=47)
+
+conf.l2types.register(101, IP)
+conf.l2types.register_num2layer(12, IP)
+
+conf.l3types.register(ETH_P_IP, IP)
+conf.l3types.register_num2layer(ETH_P_ALL, IP)
+
+
+###################
+## Fragmentation ##
+###################
+
+def fragment(pkt, fragsize=1480):
+    fragsize = (fragsize+7)/8*8
+    lst = []
+    for p in pkt:
+        s = str(p[IP].payload)
+        nb = (len(s)+fragsize-1)/fragsize
+        for i in range(nb):            
+            q = p.copy()
+            del(q[IP].payload)
+            del(q[IP].chksum)
+            del(q[IP].len)
+            if i == nb-1:
+                q[IP].flags &= ~1
+            else:
+                q[IP].flags |= 1 
+            q[IP].frag = i*fragsize/8
+            r = Raw(load=s[i*fragsize:(i+1)*fragsize])
+            r.overload_fields = p[IP].payload.overload_fields.copy()
+            q.add_payload(r)
+            lst.append(q)
+    return lst
+
+def overlap_frag(p, overlap, fragsize=8, overlap_fragsize=None):
+    if overlap_fragsize is None:
+        overlap_fragsize = fragsize
+    q = p.copy()
+    del(q[IP].payload)
+    q[IP].add_payload(overlap)
+
+    qfrag = fragment(q, overlap_fragsize)
+    qfrag[-1][IP].flags |= 1
+    return qfrag+fragment(p, fragsize)
+
+def defrag(plist):
+    """defrag(plist) -> ([not fragmented], [defragmented],
+                  [ [bad fragments], [bad fragments], ... ])"""
+    frags = {}
+    nofrag = PacketList()
+    for p in plist:
+        ip = p[IP]
+        if IP not in p:
+            nofrag.append(p)
+            continue
+        if ip.frag == 0 and ip.flags & 1 == 0:
+            nofrag.append(p)
+            continue
+        uniq = (ip.id,ip.src,ip.dst,ip.proto)
+        if uniq in frags:
+            frags[uniq].append(p)
+        else:
+            frags[uniq] = PacketList([p])
+    defrag = []
+    missfrag = []
+    for lst in frags.itervalues():
+        lst.sort(lambda x,y:cmp(x.frag, y.frag))
+        p = lst[0]
+        if p.frag > 0:
+            missfrag.append(lst)
+            continue
+        p = p.copy()
+        if Padding in p:
+            del(p[Padding].underlayer.payload)
+        ip = p[IP]
+        if ip.len is None or ip.ihl is None:
+            clen = len(ip.payload)
+        else:
+            clen = ip.len - (ip.ihl<<2)
+        txt = Raw()
+        for q in lst[1:]:
+            if clen != q.frag<<3:
+                if clen > q.frag<<3:
+                    warning("Fragment overlap (%i > %i) %r || %r ||  %r" % (clen, q.frag<<3, p,txt,q))
+                missfrag.append(lst)
+                txt = None
+                break
+            if q[IP].len is None or q[IP].ihl is None:
+                clen += len(q[IP].payload)
+            else:
+                clen += q[IP].len - (q[IP].ihl<<2)
+            if Padding in q:
+                del(q[Padding].underlayer.payload)
+            txt.add_payload(q[IP].payload.copy())
+            
+        if txt is None:
+            continue
+
+        ip.flags &= ~1 # !MF
+        del(ip.chksum)
+        del(ip.len)
+        p = p/txt
+        defrag.append(p)
+    defrag2=PacketList()
+    for p in defrag:
+        defrag2.append(p.__class__(str(p)))
+    return nofrag,defrag2,missfrag
+            
+def defragment(plist):
+    """defrag(plist) -> plist defragmented as much as possible """
+    frags = {}
+    final = []
+
+    pos = 0
+    for p in plist:
+        p._defrag_pos = pos
+        pos += 1
+        if IP in p:
+            ip = p[IP]
+            if ip.frag != 0 or ip.flags & 1:
+                ip = p[IP]
+                uniq = (ip.id,ip.src,ip.dst,ip.proto)
+                if uniq in frags:
+                    frags[uniq].append(p)
+                else:
+                    frags[uniq] = [p]
+                continue
+        final.append(p)
+
+    defrag = []
+    missfrag = []
+    for lst in frags.itervalues():
+        lst.sort(lambda x,y:cmp(x.frag, y.frag))
+        p = lst[0]
+        if p.frag > 0:
+            missfrag += lst
+            continue
+        p = p.copy()
+        if Padding in p:
+            del(p[Padding].underlayer.payload)
+        ip = p[IP]
+        if ip.len is None or ip.ihl is None:
+            clen = len(ip.payload)
+        else:
+            clen = ip.len - (ip.ihl<<2)
+        txt = Raw()
+        for q in lst[1:]:
+            if clen != q.frag<<3:
+                if clen > q.frag<<3:
+                    warning("Fragment overlap (%i > %i) %r || %r ||  %r" % (clen, q.frag<<3, p,txt,q))
+                missfrag += lst
+                txt = None
+                break
+            if q[IP].len is None or q[IP].ihl is None:
+                clen += len(q[IP].payload)
+            else:
+                clen += q[IP].len - (q[IP].ihl<<2)
+            if Padding in q:
+                del(q[Padding].underlayer.payload)
+            txt.add_payload(q[IP].payload.copy())
+            
+        if txt is None:
+            continue
+
+        ip.flags &= ~1 # !MF
+        del(ip.chksum)
+        del(ip.len)
+        p = p/txt
+        p._defrag_pos = lst[-1]._defrag_pos
+        defrag.append(p)
+    defrag2=[]
+    for p in defrag:
+        q = p.__class__(str(p))
+        q._defrag_pos = p._defrag_pos
+        defrag2.append(q)
+    final += defrag2
+    final += missfrag
+    final.sort(lambda x,y: cmp(x._defrag_pos, y._defrag_pos))
+    for p in final:
+        del(p._defrag_pos)
+
+    if hasattr(plist, "listname"):
+        name = "Defragmented %s" % plist.listname
+    else:
+        name = "Defragmented"
+        
+    
+    return PacketList(final, name=name)
+            
+            
+        
+    
+def traceroute(target, dport=80, minttl=1, maxttl=30, sport=RandShort(), l4 = None, filter=None, timeout=2, verbose=None, **kargs):
+    """Instant TCP traceroute
+traceroute(target, [maxttl=30,] [dport=80,] [sport=80,] [verbose=conf.verb]) -> None
+"""
+    if verbose is None:
+        verbose = conf.verb
+    if filter is None:
+        # we only consider ICMP error packets and TCP packets with at
+        # least the ACK flag set *and* either the SYN or the RST flag
+        # set
+        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))"
+    if l4 is None:
+        a,b = sr(IP(dst=target, id=RandShort(), ttl=(minttl,maxttl))/TCP(seq=RandInt(),sport=sport, dport=dport),
+                 timeout=timeout, filter=filter, verbose=verbose, **kargs)
+    else:
+        # this should always work
+        filter="ip"
+        a,b = sr(IP(dst=target, id=RandShort(), ttl=(minttl,maxttl))/l4,
+                 timeout=timeout, filter=filter, verbose=verbose, **kargs)
+
+    a = TracerouteResult(a.res)
+    if verbose:
+        a.show()
+    return a,b
+
+
+
+#####################
+## Reporting stuff ##
+#####################
+
+def report_ports(target, ports):
+    """portscan a target and output a LaTeX table
+report_ports(target, ports) -> string"""
+    ans,unans = sr(IP(dst=target)/TCP(dport=ports),timeout=5)
+    rep = "\\begin{tabular}{|r|l|l|}\n\\hline\n"
+    for s,r in ans:
+        if not r.haslayer(ICMP):
+            if r.payload.flags == 0x12:
+                rep += r.sprintf("%TCP.sport% & open & SA \\\\\n")
+    rep += "\\hline\n"
+    for s,r in ans:
+        if r.haslayer(ICMP):
+            rep += r.sprintf("%TCPerror.dport% & closed & ICMP type %ICMP.type%/%ICMP.code% from %IP.src% \\\\\n")
+        elif r.payload.flags != 0x12:
+            rep += r.sprintf("%TCP.sport% & closed & TCP %TCP.flags% \\\\\n")
+    rep += "\\hline\n"
+    for i in unans:
+        rep += i.sprintf("%TCP.dport% & ? & unanswered \\\\\n")
+    rep += "\\hline\n\\end{tabular}\n"
+    return rep
+
+
+
+def IPID_count(lst, funcID=lambda x:x[1].id, funcpres=lambda x:x[1].summary()):
+    idlst = map(funcID, lst)
+    idlst.sort()
+    classes = [idlst[0]]+map(lambda x:x[1],filter(lambda (x,y): abs(x-y)>50, map(lambda x,y: (x,y),idlst[:-1], idlst[1:])))
+    lst = map(lambda x:(funcID(x), funcpres(x)), lst)
+    lst.sort()
+    print "Probably %i classes:" % len(classes), classes
+    for id,pr in lst:
+        print "%5i" % id, pr
+    
+    
+def fragleak(target,sport=123, dport=123, timeout=0.2, onlyasc=0):
+    load = "XXXXYYYYYYYYYY"
+#    getmacbyip(target)
+#    pkt = IP(dst=target, id=RandShort(), options="\x22"*40)/UDP()/load
+    pkt = IP(dst=target, id=RandShort(), options="\x00"*40, flags=1)/UDP(sport=sport, dport=sport)/load
+    s=conf.L3socket()
+    intr=0
+    found={}
+    try:
+        while 1:
+            try:
+                if not intr:
+                    s.send(pkt)
+                sin,sout,serr = select([s],[],[],timeout)
+                if not sin:
+                    continue
+                ans=s.recv(1600)
+                if not isinstance(ans, IP): #TODO: IPv6
+                    continue
+                if not isinstance(ans.payload, ICMP):
+                    continue
+                if not isinstance(ans.payload.payload, IPerror):
+                    continue
+                if ans.payload.payload.dst != target:
+                    continue
+                if ans.src  != target:
+                    print "leak from", ans.src,
+
+
+#                print repr(ans)
+                if not ans.haslayer(Padding):
+                    continue
+
+                
+#                print repr(ans.payload.payload.payload.payload)
+                
+#                if not isinstance(ans.payload.payload.payload.payload, Raw):
+#                    continue
+#                leak = ans.payload.payload.payload.payload.load[len(load):]
+                leak = ans.getlayer(Padding).load
+                if leak not in found:
+                    found[leak]=None
+                    linehexdump(leak, onlyasc=onlyasc)
+            except KeyboardInterrupt:
+                if intr:
+                    raise
+                intr=1
+    except KeyboardInterrupt:
+        pass
+
+def fragleak2(target, timeout=0.4, onlyasc=0):
+    found={}
+    try:
+        while 1:
+            p = sr1(IP(dst=target, options="\x00"*40, proto=200)/"XXXXYYYYYYYYYYYY",timeout=timeout,verbose=0)
+            if not p:
+                continue
+            if Padding in p:
+                leak  = p[Padding].load
+                if leak not in found:
+                    found[leak]=None
+                    linehexdump(leak,onlyasc=onlyasc)
+    except:
+        pass
+    
+
diff --git a/scapy/layers/ip6.py b/scapy/layers/ip6.py
new file mode 100644
index 0000000000000000000000000000000000000000..9dd938cc2b5a42bf69f20bd778a087b460d0f566
--- /dev/null
+++ b/scapy/layers/ip6.py
@@ -0,0 +1,22 @@
+from scapy.error import log_interactive
+from scapy.packet import *
+from scapy.fields import *
+
+
+class IPv6(Packet):
+    """See http://namabiiru.hongo.wide.ad.jp/scapy6"""
+    name = "IPv6 not implemented here." 
+    def __init__(self, *args, **kargs):
+        log_interactive.error(self.name)
+    def __repr__(self):
+        return "<IPv6: ERROR not implemented>"
+    
+class _IPv6OptionHeader(Packet):
+    """See http://namabiiru.hongo.wide.ad.jp/scapy6"""
+    name = "IPv6 not implemented here."
+    def __init__(self, *args, **kargs):
+        log_interactive.error(self.name)
+    def __repr__(self):
+        return "<IPv6: ERROR not implemented>"
+
+
diff --git a/scapy/layers/ir.py b/scapy/layers/ir.py
new file mode 100644
index 0000000000000000000000000000000000000000..e0e47e4b8a2b4574477c01cbe40f0eaa3e0506b2
--- /dev/null
+++ b/scapy/layers/ir.py
@@ -0,0 +1,35 @@
+from scapy.packet import *
+from scapy.fields import *
+from scapy.layers.l2 import CookedLinux
+
+
+
+# IR
+
+class IrLAPHead(Packet):
+    name = "IrDA Link Access Protocol Header"
+    fields_desc = [ XBitField("Address", 0x7f, 7),
+                    BitEnumField("Type", 1, 1, {"Response":0,
+                                                "Command":1})]
+
+class IrLAPCommand(Packet):
+    name = "IrDA Link Access Protocol Command"
+    fields_desc = [ XByteField("Control", 0),
+                    XByteField("Format identifier", 0),
+                    XIntField("Source address", 0),
+                    XIntField("Destination address", 0xffffffffL),
+                    XByteField("Discovery flags", 0x1),
+                    ByteEnumField("Slot number", 255, {"final":255}),
+                    XByteField("Version", 0)]
+
+
+class IrLMP(Packet):
+    name = "IrDA Link Management Protocol"
+    fields_desc = [ XShortField("Service hints", 0),
+                    XByteField("Character set", 0),
+                    StrField("Device name", "") ]
+
+
+bind_layers( CookedLinux,   IrLAPHead,     proto=23)
+bind_layers( IrLAPHead,     IrLAPCommand,  Type=1)
+bind_layers( IrLAPCommand,  IrLMP,         )
diff --git a/scapy/layers/isakmp.py b/scapy/layers/isakmp.py
new file mode 100644
index 0000000000000000000000000000000000000000..b7aafc82a3cdd365755eccead0bbfe772afb7329
--- /dev/null
+++ b/scapy/layers/isakmp.py
@@ -0,0 +1,338 @@
+import struct
+from scapy.packet import *
+from scapy.fields import *
+from scapy.ansmachine import *
+from scapy.layers.inet import UDP
+
+
+# see http://www.iana.org/assignments/ipsec-registry for details
+ISAKMPAttributeTypes= { "Encryption":    (1, { "DES-CBC"  : 1,
+                                                "IDEA-CBC" : 2,
+                                                "Blowfish-CBC" : 3,
+                                                "RC5-R16-B64-CBC" : 4,
+                                                "3DES-CBC" : 5, 
+                                                "CAST-CBC" : 6, 
+                                                "AES-CBC" : 7, 
+                                                "CAMELLIA-CBC" : 8, }, 0),
+                         "Hash":          (2, { "MD5": 1,
+                                                "SHA": 2,
+                                                "Tiger": 3,
+                                                "SHA2-256": 4,
+                                                "SHA2-384": 5,
+                                                "SHA2-512": 6,}, 0),
+                         "Authentication":(3, { "PSK": 1, 
+                                                "DSS": 2,
+                                                "RSA Sig": 3,
+                                                "RSA Encryption": 4,
+                                                "RSA Encryption Revised": 5,
+                                                "ElGamal Encryption": 6,
+                                                "ElGamal Encryption Revised": 7,
+                                                "ECDSA Sig": 8,
+                                                "HybridInitRSA": 64221,
+                                                "HybridRespRSA": 64222,
+                                                "HybridInitDSS": 64223,
+                                                "HybridRespDSS": 64224,
+                                                "XAUTHInitPreShared": 65001,
+                                                "XAUTHRespPreShared": 65002,
+                                                "XAUTHInitDSS": 65003,
+                                                "XAUTHRespDSS": 65004,
+                                                "XAUTHInitRSA": 65005,
+                                                "XAUTHRespRSA": 65006,
+                                                "XAUTHInitRSAEncryption": 65007,
+                                                "XAUTHRespRSAEncryption": 65008,
+                                                "XAUTHInitRSARevisedEncryption": 65009,
+                                                "XAUTHRespRSARevisedEncryptio": 65010, }, 0),
+                         "GroupDesc":     (4, { "768MODPgr"  : 1,
+                                                "1024MODPgr" : 2, 
+                                                "EC2Ngr155"  : 3,
+                                                "EC2Ngr185"  : 4,
+                                                "1536MODPgr" : 5, 
+                                                "2048MODPgr" : 14, 
+                                                "3072MODPgr" : 15, 
+                                                "4096MODPgr" : 16, 
+                                                "6144MODPgr" : 17, 
+                                                "8192MODPgr" : 18, }, 0),
+                         "GroupType":      (5,  {"MODP":       1,
+                                                 "ECP":        2,
+                                                 "EC2N":       3}, 0),
+                         "GroupPrime":     (6,  {}, 1),
+                         "GroupGenerator1":(7,  {}, 1),
+                         "GroupGenerator2":(8,  {}, 1),
+                         "GroupCurveA":    (9,  {}, 1),
+                         "GroupCurveB":    (10, {}, 1),
+                         "LifeType":       (11, {"Seconds":     1,
+                                                 "Kilobytes":   2,  }, 0),
+                         "LifeDuration":   (12, {}, 1),
+                         "PRF":            (13, {}, 0),
+                         "KeyLength":      (14, {}, 0),
+                         "FieldSize":      (15, {}, 0),
+                         "GroupOrder":     (16, {}, 1),
+                         }
+
+# the name 'ISAKMPTransformTypes' is actually a misnomer (since the table 
+# holds info for all ISAKMP Attribute types, not just transforms, but we'll 
+# keep it for backwards compatibility... for now at least
+ISAKMPTransformTypes = ISAKMPAttributeTypes
+
+ISAKMPTransformNum = {}
+for n in ISAKMPTransformTypes:
+    val = ISAKMPTransformTypes[n]
+    tmp = {}
+    for e in val[1]:
+        tmp[val[1][e]] = e
+    ISAKMPTransformNum[val[0]] = (n,tmp, val[2])
+del(n)
+del(e)
+del(tmp)
+del(val)
+
+
+class ISAKMPTransformSetField(StrLenField):
+    islist=1
+    def type2num(self, (typ,val)):
+        type_val,enc_dict,tlv = ISAKMPTransformTypes.get(typ, (typ,{},0))
+        val = enc_dict.get(val, val)
+        s = ""
+        if (val & ~0xffff):
+            if not tlv:
+                warning("%r should not be TLV but is too big => using TLV encoding" % typ)
+            n = 0
+            while val:
+                s = chr(val&0xff)+s
+                val >>= 8
+                n += 1
+            val = n
+        else:
+            type_val |= 0x8000
+        return struct.pack("!HH",type_val, val)+s
+    def num2type(self, typ, enc):
+        val = ISAKMPTransformNum.get(typ,(typ,{}))
+        enc = val[1].get(enc,enc)
+        return (val[0],enc)
+    def i2m(self, pkt, i):
+        if i is None:
+            return ""
+        i = map(self.type2num, i)
+        return "".join(i)
+    def m2i(self, pkt, m):
+        # I try to ensure that we don't read off the end of our packet based
+        # on bad length fields we're provided in the packet. There are still
+        # conditions where struct.unpack() may not get enough packet data, but
+        # worst case that should result in broken attributes (which would
+        # be expected). (wam)
+        lst = []
+        while len(m) >= 4:
+            trans_type, = struct.unpack("!H", m[:2])
+            is_tlv = not (trans_type & 0x8000)
+            if is_tlv:
+                # We should probably check to make sure the attribute type we
+                # are looking at is allowed to have a TLV format and issue a 
+                # warning if we're given an TLV on a basic attribute.
+                value_len, = struct.unpack("!H", m[2:4])
+                if value_len+4 > len(m):
+                    warning("Bad length for ISAKMP tranform type=%#6x" % trans_type)
+                value = m[4:4+value_len]
+                value = reduce(lambda x,y: (x<<8L)|y, struct.unpack("!%s" % ("B"*len(value),), value),0)
+            else:
+                trans_type &= 0x7fff
+                value_len=0
+                value, = struct.unpack("!H", m[2:4])
+            m=m[4+value_len:]
+            lst.append(self.num2type(trans_type, value))
+        if len(m) > 0:
+            warning("Extra bytes after ISAKMP transform dissection [%r]" % m)
+        return lst
+
+
+ISAKMP_payload_type = ["None","SA","Proposal","Transform","KE","ID","CERT","CR","Hash",
+                       "SIG","Nonce","Notification","Delete","VendorID"]
+
+ISAKMP_exchange_type = ["None","base","identity prot.",
+                        "auth only", "aggressive", "info"]
+
+
+class ISAKMP_class(Packet):
+    def guess_payload_class(self, payload):
+        np = self.next_payload
+        if np == 0:
+            return Raw
+        elif np < len(ISAKMP_payload_type):
+            pt = ISAKMP_payload_type[np]
+            return globals().get("ISAKMP_payload_%s" % pt, ISAKMP_payload)
+        else:
+            return ISAKMP_payload
+
+
+class ISAKMP(ISAKMP_class): # rfc2408
+    name = "ISAKMP"
+    fields_desc = [
+        StrFixedLenField("init_cookie","",8),
+        StrFixedLenField("resp_cookie","",8),
+        ByteEnumField("next_payload",0,ISAKMP_payload_type),
+        XByteField("version",0x10),
+        ByteEnumField("exch_type",0,ISAKMP_exchange_type),
+        FlagsField("flags",0, 8, ["encryption","commit","auth_only","res3","res4","res5","res6","res7"]), # XXX use a Flag field
+        IntField("id",0),
+        IntField("length",None)
+        ]
+
+    def guess_payload_class(self, payload):
+        if self.flags & 1:
+            return Raw
+        return ISAKMP_class.guess_payload_class(self, payload)
+
+    def answers(self, other):
+        if isinstance(other, ISAKMP):
+            if other.init_cookie == self.init_cookie:
+                return 1
+        return 0
+    def post_build(self, p, pay):
+        p += pay
+        if self.length is None:
+            p = p[:24]+struct.pack("!I",len(p))+p[28:]
+        return p
+       
+
+
+
+class ISAKMP_payload_Transform(ISAKMP_class):
+    name = "IKE Transform"
+    fields_desc = [
+        ByteEnumField("next_payload",None,ISAKMP_payload_type),
+        ByteField("res",0),
+#        ShortField("len",None),
+        ShortField("length",None),
+        ByteField("num",None),
+        ByteEnumField("id",1,{1:"KEY_IKE"}),
+        ShortField("res2",0),
+        ISAKMPTransformSetField("transforms",None,length_from=lambda x:x.length-8)
+#        XIntField("enc",0x80010005L),
+#        XIntField("hash",0x80020002L),
+#        XIntField("auth",0x80030001L),
+#        XIntField("group",0x80040002L),
+#        XIntField("life_type",0x800b0001L),
+#        XIntField("durationh",0x000c0004L),
+#        XIntField("durationl",0x00007080L),
+        ]
+    def post_build(self, p, pay):
+        if self.length is None:
+            l = len(p)
+            p = p[:2]+chr((l>>8)&0xff)+chr(l&0xff)+p[4:]
+        p += pay
+        return p
+            
+
+
+        
+class ISAKMP_payload_Proposal(ISAKMP_class):
+    name = "IKE proposal"
+#    ISAKMP_payload_type = 0
+    fields_desc = [
+        ByteEnumField("next_payload",None,ISAKMP_payload_type),
+        ByteField("res",0),
+        FieldLenField("length",None,"trans","H", adjust=lambda pkt,x:x+8),
+        ByteField("proposal",1),
+        ByteEnumField("proto",1,{1:"ISAKMP"}),
+        FieldLenField("SPIsize",None,"SPI","B"),
+        ByteField("trans_nb",None),
+        StrLenField("SPI","",length_from=lambda x:x.SPIsize),
+        PacketLenField("trans",Raw(),ISAKMP_payload_Transform,length_from=lambda x:x.length-8),
+        ]
+
+
+class ISAKMP_payload(ISAKMP_class):
+    name = "ISAKMP payload"
+    fields_desc = [
+        ByteEnumField("next_payload",None,ISAKMP_payload_type),
+        ByteField("res",0),
+        FieldLenField("length",None,"load","H", adjust=lambda pkt,x:x+4),
+        StrLenField("load","",length_from=lambda x:x.length-4),
+        ]
+
+
+class ISAKMP_payload_VendorID(ISAKMP_class):
+    name = "ISAKMP Vendor ID"
+    overload_fields = { ISAKMP: { "next_payload":13 }}
+    fields_desc = [
+        ByteEnumField("next_payload",None,ISAKMP_payload_type),
+        ByteField("res",0),
+        FieldLenField("length",None,"vendorID","H", adjust=lambda pkt,x:x+4),
+        StrLenField("vendorID","",length_from=lambda x:x.length-4),
+        ]
+
+class ISAKMP_payload_SA(ISAKMP_class):
+    name = "ISAKMP SA"
+    overload_fields = { ISAKMP: { "next_payload":1 }}
+    fields_desc = [
+        ByteEnumField("next_payload",None,ISAKMP_payload_type),
+        ByteField("res",0),
+        FieldLenField("length",None,"prop","H", adjust=lambda pkt,x:x+12),
+        IntEnumField("DOI",1,{1:"IPSEC"}),
+        IntEnumField("situation",1,{1:"identity"}),
+        PacketLenField("prop",Raw(),ISAKMP_payload_Proposal,length_from=lambda x:x.length-12),
+        ]
+
+class ISAKMP_payload_Nonce(ISAKMP_class):
+    name = "ISAKMP Nonce"
+    overload_fields = { ISAKMP: { "next_payload":10 }}
+    fields_desc = [
+        ByteEnumField("next_payload",None,ISAKMP_payload_type),
+        ByteField("res",0),
+        FieldLenField("length",None,"load","H", adjust=lambda pkt,x:x+4),
+        StrLenField("load","",length_from=lambda x:x.length-4),
+        ]
+
+class ISAKMP_payload_KE(ISAKMP_class):
+    name = "ISAKMP Key Exchange"
+    overload_fields = { ISAKMP: { "next_payload":4 }}
+    fields_desc = [
+        ByteEnumField("next_payload",None,ISAKMP_payload_type),
+        ByteField("res",0),
+        FieldLenField("length",None,"load","H", adjust=lambda pkt,x:x+4),
+        StrLenField("load","",length_from=lambda x:x.length-4),
+        ]
+
+class ISAKMP_payload_ID(ISAKMP_class):
+    name = "ISAKMP Identification"
+    overload_fields = { ISAKMP: { "next_payload":5 }}
+    fields_desc = [
+        ByteEnumField("next_payload",None,ISAKMP_payload_type),
+        ByteField("res",0),
+        FieldLenField("length",None,"load","H",adjust=lambda pkt,x:x+8),
+        ByteEnumField("IDtype",1,{1:"IPv4_addr", 11:"Key"}),
+        ByteEnumField("ProtoID",0,{0:"Unused"}),
+        ShortEnumField("Port",0,{0:"Unused"}),
+#        IPField("IdentData","127.0.0.1"),
+        StrLenField("load","",length_from=lambda x:x.length-8),
+        ]
+
+
+
+class ISAKMP_payload_Hash(ISAKMP_class):
+    name = "ISAKMP Hash"
+    overload_fields = { ISAKMP: { "next_payload":8 }}
+    fields_desc = [
+        ByteEnumField("next_payload",None,ISAKMP_payload_type),
+        ByteField("res",0),
+        FieldLenField("length",None,"load","H",adjust=lambda pkt,x:x+4),
+        StrLenField("load","",length_from=lambda x:x.length-4),
+        ]
+
+
+
+ISAKMP_payload_type_overload = {}
+for i in range(len(ISAKMP_payload_type)):
+    name = "ISAKMP_payload_%s" % ISAKMP_payload_type[i]
+    if name in globals():
+        ISAKMP_payload_type_overload[globals()[name]] = {"next_payload":i}
+
+del(i)
+del(name)
+ISAKMP_class.overload_fields = ISAKMP_payload_type_overload.copy()
+
+
+bind_layers( UDP,           ISAKMP,        dport=500, sport=500)
+def ikescan(ip):
+    return sr(IP(dst=ip)/UDP()/ISAKMP(init_cookie=RandString(8),
+                                      exch_type=2)/ISAKMP_payload_SA(prop=ISAKMP_payload_Proposal()))
+
diff --git a/scapy/layers/l2.py b/scapy/layers/l2.py
new file mode 100644
index 0000000000000000000000000000000000000000..1e4cadf0f3a8321b7d9cbc6d34ad2cfa53b49002
--- /dev/null
+++ b/scapy/layers/l2.py
@@ -0,0 +1,360 @@
+import os,struct,time
+from scapy.config import conf
+from scapy.packet import *
+from scapy.ansmachine import *
+
+class Ether_or_Dot3_metaclass(Packet_metaclass):
+    def __call__(self, _pkt=None, *args, **kargs):
+        cls = self
+        if _pkt and len(_pkt) >= 14:
+            if struct.unpack("!H", _pkt[12:14])[0] <= 1500:
+                cls = Dot3
+            else:
+                cls = Ether
+        i = cls.__new__(cls, cls.__name__, cls.__bases__, cls.__dict__)
+        i.__init__(_pkt=_pkt, *args, **kargs)
+        return i
+
+class Ether(Packet):
+    __metaclass__ = Ether_or_Dot3_metaclass
+    name = "Ethernet"
+    fields_desc = [ DestMACField("dst"),
+                    SourceMACField("src"),
+                    XShortEnumField("type", 0x0000, ETHER_TYPES) ]
+    def hashret(self):
+        return struct.pack("H",self.type)+self.payload.hashret()
+    def answers(self, other):
+        if isinstance(other,Ether):
+            if self.type == other.type:
+                return self.payload.answers(other.payload)
+        return 0
+    def mysummary(self):
+        return self.sprintf("%src% > %dst% (%type%)")
+
+class Dot3(Packet):
+    __metaclass__ = Ether_or_Dot3_metaclass
+    name = "802.3"
+    fields_desc = [ MACField("dst", ETHER_BROADCAST),
+                    MACField("src", ETHER_ANY),
+                    LenField("len", None, "H") ]
+    def extract_padding(self,s):
+        l = self.len
+        return s[:l],s[l:]
+    def answers(self, other):
+        if isinstance(other,Dot3):
+            return self.payload.answers(other.payload)
+        return 0
+    def mysummary(self):
+        return "802.3 %s > %s" % (self.src, self.dst)
+
+
+class LLC(Packet):
+    name = "LLC"
+    fields_desc = [ XByteField("dsap", 0x00),
+                    XByteField("ssap", 0x00),
+                    ByteField("ctrl", 0) ]
+
+
+class CookedLinux(Packet):
+    name = "cooked linux"
+    fields_desc = [ ShortEnumField("pkttype",0, {0: "unicast",
+                                                 4:"sent-by-us"}), #XXX incomplete
+                    XShortField("lladdrtype",512),
+                    ShortField("lladdrlen",0),
+                    StrFixedLenField("src","",8),
+                    XShortEnumField("proto",0x800,ETHER_TYPES) ]
+                    
+                                   
+
+class SNAP(Packet):
+    name = "SNAP"
+    fields_desc = [ X3BytesField("OUI",0x000000),
+                    XShortEnumField("code", 0x000, ETHER_TYPES) ]
+
+
+class Dot1Q(Packet):
+    name = "802.1Q"
+    aliastypes = [ Ether ]
+    fields_desc =  [ BitField("prio", 0, 3),
+                     BitField("id", 0, 1),
+                     BitField("vlan", 1, 12),
+                     XShortEnumField("type", 0x0000, ETHER_TYPES) ]
+    def answers(self, other):
+        if isinstance(other,Dot1Q):
+            if ( (self.type == other.type) and
+                 (self.vlan == other.vlan) ):
+                return self.payload.answers(other.payload)
+        else:
+            return self.payload.answers(other)
+        return 0
+    def default_payload_class(self, pay):
+        if self.type <= 1500:
+            return LLC
+        return Raw
+    def extract_padding(self,s):
+        if self.type <= 1500:
+            return s[:self.type],s[self.type:]
+        return s,None
+    def mysummary(self):
+        if isinstance(self.underlayer, Ether):
+            return self.underlayer.sprintf("802.1q %Ether.src% > %Ether.dst% (%Dot1Q.type%) vlan %Dot1Q.vlan%")
+        else:
+            return self.sprintf("802.1q (%Dot1Q.type%) vlan %Dot1Q.vlan%")
+
+            
+
+
+class STP(Packet):
+    name = "Spanning Tree Protocol"
+    fields_desc = [ ShortField("proto", 0),
+                    ByteField("version", 0),
+                    ByteField("bpdutype", 0),
+                    ByteField("bpduflags", 0),
+                    ShortField("rootid", 0),
+                    MACField("rootmac", ETHER_ANY),
+                    IntField("pathcost", 0),
+                    ShortField("bridgeid", 0),
+                    MACField("bridgemac", ETHER_ANY),
+                    ShortField("portid", 0),
+                    BCDFloatField("age", 1),
+                    BCDFloatField("maxage", 20),
+                    BCDFloatField("hellotime", 2),
+                    BCDFloatField("fwddelay", 15) ]
+
+
+class EAPOL(Packet):
+    name = "EAPOL"
+    fields_desc = [ ByteField("version", 1),
+                    ByteEnumField("type", 0, ["EAP_PACKET", "START", "LOGOFF", "KEY", "ASF"]),
+                    LenField("len", None, "H") ]
+    
+    EAP_PACKET= 0
+    START = 1
+    LOGOFF = 2
+    KEY = 3
+    ASF = 4
+    def extract_padding(self, s):
+        l = self.len
+        return s[:l],s[l:]
+    def hashret(self):
+        return chr(self.type)+self.payload.hashret()
+    def answers(self, other):
+        if isinstance(other,EAPOL):
+            if ( (self.type == self.EAP_PACKET) and
+                 (other.type == self.EAP_PACKET) ):
+                return self.payload.answers(other.payload)
+        return 0
+    def mysummary(self):
+        return self.sprintf("EAPOL %EAPOL.type%")
+             
+
+class EAP(Packet):
+    name = "EAP"
+    fields_desc = [ ByteEnumField("code", 4, {1:"REQUEST",2:"RESPONSE",3:"SUCCESS",4:"FAILURE"}),
+                    ByteField("id", 0),
+                    ShortField("len",None),
+                    ConditionalField(ByteEnumField("type",0, {1:"ID",4:"MD5"}), lambda pkt:pkt.code not in [EAP.SUCCESS, EAP.FAILURE])
+
+                                     ]
+    
+    REQUEST = 1
+    RESPONSE = 2
+    SUCCESS = 3
+    FAILURE = 4
+    TYPE_ID = 1
+    TYPE_MD5 = 4
+    def answers(self, other):
+        if isinstance(other,EAP):
+            if self.code == self.REQUEST:
+                return 0
+            elif self.code == self.RESPONSE:
+                if ( (other.code == self.REQUEST) and
+                     (other.type == self.type) ):
+                    return 1
+            elif other.code == self.RESPONSE:
+                return 1
+        return 0
+    
+    def post_build(self, p, pay):
+        if self.len is None:
+            l = len(p)+len(pay)
+            p = p[:2]+chr((l>>8)&0xff)+chr(l&0xff)+p[4:]
+        return p+pay
+             
+
+class ARP(Packet):
+    name = "ARP"
+    fields_desc = [ XShortField("hwtype", 0x0001),
+                    XShortEnumField("ptype",  0x0800, ETHER_TYPES),
+                    ByteField("hwlen", 6),
+                    ByteField("plen", 4),
+                    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}),
+                    ARPSourceMACField("hwsrc"),
+                    SourceIPField("psrc","pdst"),
+                    MACField("hwdst", ETHER_ANY),
+                    IPField("pdst", "0.0.0.0") ]
+    who_has = 1
+    is_at = 2
+    def answers(self, other):
+        if isinstance(other,ARP):
+            if ( (self.op == self.is_at) and
+                 (other.op == self.who_has) and
+                 (self.psrc == other.pdst) ):
+                return 1
+        return 0
+    def extract_padding(self, s):
+        return "",s
+    def mysummary(self):
+        if self.op == self.is_at:
+            return "ARP is at %s says %s" % (self.hwsrc, self.psrc)
+        elif self.op == self.who_has:
+            return "ARP who has %s says %s" % (self.pdst, self.psrc)
+        else:
+            return "ARP %ARP.op% %ARP.psrc% > %ARP.pdst%"
+                 
+
+
+class GRE(Packet):
+    name = "GRE"
+    fields_desc = [ BitField("chksumpresent",0,1),
+                    BitField("reserved0",0,12),
+                    BitField("version",0,3),
+                    XShortEnumField("proto", 0x0000, ETHER_TYPES),
+                    ConditionalField(XShortField("chksum",None),lambda pkt:pkt.chksumpresent==1),
+                    ConditionalField(XShortField("reserved1",None),lambda pkt:pkt.chksumpresent==1),
+                    ]
+    def post_build(self, p, pay):
+        p += pay
+        if self.chksumpresent and self.chksum is None:
+            c = checksum(p)
+            p = p[:4]+chr((c>>8)&0xff)+chr(c&0xff)+p[6:]
+        return p
+            
+
+
+
+bind_layers( Dot3,          LLC,           )
+bind_layers( Ether,         LLC,           type=122)
+bind_layers( Ether,         Dot1Q,         type=33024)
+bind_layers( Ether,         Ether,         type=1)
+bind_layers( Ether,         ARP,           type=2054)
+bind_layers( Ether,         EAPOL,         type=34958)
+bind_layers( Ether,         EAPOL,         dst='01:80:c2:00:00:03', type=34958)
+bind_layers( CookedLinux,   LLC,           proto=122)
+bind_layers( CookedLinux,   Dot1Q,         proto=33024)
+bind_layers( CookedLinux,   Ether,         proto=1)
+bind_layers( CookedLinux,   ARP,           proto=2054)
+bind_layers( CookedLinux,   EAPOL,         proto=34958)
+bind_layers( GRE,           LLC,           proto=122)
+bind_layers( GRE,           Dot1Q,         proto=33024)
+bind_layers( GRE,           Ether,         proto=1)
+bind_layers( GRE,           ARP,           proto=2054)
+bind_layers( GRE,           EAPOL,         proto=34958)
+bind_layers( EAPOL,         EAP,           type=0)
+bind_layers( LLC,           STP,           dsap=66, ssap=66, ctrl=3)
+bind_layers( LLC,           SNAP,          dsap=170, ssap=170, ctrl=3)
+bind_layers( SNAP,          Dot1Q,         code=33024)
+bind_layers( SNAP,          Ether,         code=1)
+bind_layers( SNAP,          ARP,           code=2054)
+bind_layers( SNAP,          EAPOL,         code=34958)
+bind_layers( SNAP,          STP,           code=267)
+
+conf.l2types.register(ARPHDR_ETHER, Ether)
+conf.l2types.register_num2layer(ARPHDR_METRICOM, Ether)
+conf.l2types.register_num2layer(ARPHDR_LOOPBACK, Ether)
+conf.l2types.register_layer2num(ARPHDR_ETHER, Dot3)
+conf.l2types.register(113, CookedLinux)
+conf.l2types.register(144, CookedLinux)  # called LINUX_IRDA, similar to CookedLinux
+
+conf.l3types.register(ETH_P_ARP, ARP)
+
+def arpcachepoison(target, victim, interval=60):
+    """Poison target's cache with (your MAC,victim's IP) couple
+arpcachepoison(target, victim, [interval=60]) -> None
+"""
+    tmac = getmacbyip(target)
+    p = Ether(dst=tmac)/ARP(op="who-has", psrc=victim, pdst=target)
+    try:
+        while 1:
+            sendp(p, iface_hint=target)
+            if conf.verb > 1:
+                os.write(1,".")
+            time.sleep(interval)
+    except KeyboardInterrupt:
+        pass
+
+
+def arping(net, timeout=2, cache=0, verbose=None, **kargs):
+    """Send ARP who-has requests to determine which hosts are up
+arping(net, [cache=0,] [iface=conf.iface,] [verbose=conf.verb]) -> None
+Set cache=True if you want arping to modify internal ARP-Cache"""
+    if verbose is None:
+        verbose = conf.verb
+    ans,unans = srp(Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(pdst=net), verbose=verbose,
+                    filter="arp and arp[7] = 2", timeout=timeout, iface_hint=net, **kargs)
+    ans = ARPingResult(ans.res)
+
+    if cache and ans is not None:
+        for pair in ans:
+            arp_cache[pair[1].psrc] = (pair[1].hwsrc, time.time())
+    if verbose:
+        ans.show()
+    return ans,unans
+
+def is_promisc(ip, fake_bcast="ff:ff:00:00:00:00",**kargs):
+    """Try to guess if target is in Promisc mode. The target is provided by its ip."""
+
+    responses = srp1(Ether(dst=fake_bcast) / ARP(op="who-has", pdst=ip),type=ETH_P_ARP, iface_hint=ip, timeout=1, verbose=0,**kargs)
+
+    return responses is not None
+
+def promiscping(net, timeout=2, fake_bcast="ff:ff:ff:ff:ff:fe", **kargs):
+    """Send ARP who-has requests to determine which hosts are in promiscuous mode
+    promiscping(net, iface=conf.iface)"""
+    ans,unans = srp(Ether(dst=fake_bcast)/ARP(pdst=net),
+                    filter="arp and arp[7] = 2", timeout=timeout, iface_hint=net, **kargs)
+    ans = ARPingResult(ans.res, name="PROMISCPing")
+
+    ans.display()
+    return ans,unans
+
+
+class ARP_am(AnsweringMachine):
+    function_name="farpd"
+    filter = "arp"
+    send_function = staticmethod(sendp)
+
+    def parse_options(self, IP_addr=None, iface=None, ARP_addr=None):
+        self.IP_addr=IP_addr
+        self.iface=iface
+        self.ARP_addr=ARP_addr
+
+    def is_request(self, req):
+        return (req.haslayer(ARP) and
+                req.getlayer(ARP).op == 1 and
+                (self.IP_addr == None or self.IP_addr == req.getlayer(ARP).pdst))
+    
+    def make_reply(self, req):
+        ether = req.getlayer(Ether)
+        arp = req.getlayer(ARP)
+        iff,a,gw = conf.route.route(arp.psrc)
+        if self.iface != None:
+            iff = iface
+        ARP_addr = self.ARP_addr
+        IP_addr = arp.pdst
+        resp = Ether(dst=ether.src,
+                     src=ARP_addr)/ARP(op="is-at",
+                                       hwsrc=ARP_addr,
+                                       psrc=IP_addr,
+                                       hwdst=arp.hwsrc,
+                                       pdst=arp.pdst)
+        return resp
+
+    def sniff(self):
+        sniff(iface=self.iface, **self.optsniff)
+
+def etherleak(target, **kargs):
+    return srpflood(Ether()/ARP(pdst=target), prn=lambda (s,r): Padding in r and hexstr(r[Padding].load),
+                    filter="arp", **kargs)
+
+
diff --git a/scapy/layers/l2tp.py b/scapy/layers/l2tp.py
new file mode 100644
index 0000000000000000000000000000000000000000..b5d001a8bf99945b41cbfd673570f72c8931f264
--- /dev/null
+++ b/scapy/layers/l2tp.py
@@ -0,0 +1,25 @@
+import struct
+
+from scapy.packet import *
+from scapy.fields import *
+from scapy.layers.inet import UDP
+from scapy.layers.ppp import PPP
+
+class L2TP(Packet):
+    fields_desc = [ ShortEnumField("pkt_type",2,{2:"data"}),
+                    ShortField("len", None),
+                    ShortField("tunnel_id", 0),
+                    ShortField("session_id", 0),
+                    ShortField("ns", 0),
+                    ShortField("nr", 0),
+                    ShortField("offset", 0) ]
+
+    def post_build(self, pkt, pay):
+        if self.len is None:
+            l = len(pkt)+len(pay)
+            pkt = pkt[:2]+struct.pack("!H", l)+pkt[4:]
+        return pkt+pay
+
+
+bind_layers( UDP,           L2TP,          sport=1701, dport=1701)
+bind_layers( L2TP,          PPP,           )
diff --git a/scapy/layers/mgcp.py b/scapy/layers/mgcp.py
new file mode 100644
index 0000000000000000000000000000000000000000..fec4dbf52e48dc15c1f271f2a12c9732eac6797c
--- /dev/null
+++ b/scapy/layers/mgcp.py
@@ -0,0 +1,34 @@
+from scapy.packet import *
+from scapy.fields import *
+from scapy.layers.inet import UDP
+
+class MGCP(Packet):
+    name = "MGCP"
+    longname = "Media Gateway Control Protocol"
+    fields_desc = [ StrStopField("verb","AUEP"," ", -1),
+                    StrFixedLenField("sep1"," ",1),
+                    StrStopField("transaction_id","1234567"," ", -1),
+                    StrFixedLenField("sep2"," ",1),
+                    StrStopField("endpoint","dummy@dummy.net"," ", -1),
+                    StrFixedLenField("sep3"," ",1),
+                    StrStopField("version","MGCP 1.0 NCS 1.0","\x0a", -1),
+                    StrFixedLenField("sep4","\x0a",1),
+                    ]
+                    
+    
+#class MGCP(Packet):
+#    name = "MGCP"
+#    longname = "Media Gateway Control Protocol"
+#    fields_desc = [ ByteEnumField("type",0, ["request","response","others"]),
+#                    ByteField("code0",0),
+#                    ByteField("code1",0),
+#                    ByteField("code2",0),
+#                    ByteField("code3",0),
+#                    ByteField("code4",0),
+#                    IntField("trasid",0),
+#                    IntField("req_time",0),
+#                    ByteField("is_duplicate",0),
+#                    ByteField("req_available",0) ]
+#
+bind_layers( UDP,           MGCP,          dport=2727)
+bind_layers( UDP,           MGCP,          sport=2727)
diff --git a/scapy/layers/mobileip.py b/scapy/layers/mobileip.py
new file mode 100644
index 0000000000000000000000000000000000000000..a455525e68cd837f06e07f59b05d490b9d98d910
--- /dev/null
+++ b/scapy/layers/mobileip.py
@@ -0,0 +1,33 @@
+class MobileIP(Packet):
+    name = "Mobile IP (RFC3344)"
+    fields_desc = [ ByteEnumField("type", 1, {1:"RRQ", 3:"RRP"}) ]
+
+class MobileIPRRQ(Packet):
+    name = "Mobile IP Registration Request (RFC3344)"
+    fields_desc = [ XByteField("flags", 0),
+                    ShortField("lifetime", 180),
+                    IPField("homeaddr", "0.0.0.0"),
+                    IPField("haaddr", "0.0.0.0"),
+                    IPField("coaddr", "0.0.0.0"),
+                    Field("id", "", "64s") ]
+
+class MobileIPRRP(Packet):
+    name = "Mobile IP Registration Reply (RFC3344)"
+    fields_desc = [ ByteField("code", 0),
+                    ShortField("lifetime", 180),
+                    IPField("homeaddr", "0.0.0.0"),
+                    IPField("haaddr", "0.0.0.0"),
+                    Field("id", "", "64s") ]
+
+class MobileIPTunnelData(Packet):
+    name = "Mobile IP Tunnel Data Message (RFC3519)"
+    fields_desc = [ ByteField("nexthdr", 4),
+                    ShortField("res", 0) ]
+
+
+bind_layers( UDP,           MobileIP,           sport=434)
+bind_layers( UDP,           MobileIP,           dport=434)
+bind_layers( MobileIP,      MobileIPRRQ,        type=1)
+bind_layers( MobileIP,      MobileIPRRP,        type=3)
+bind_layers( MobileIP,      MobileIPTunnelData, type=4)
+bind_layers( MobileIPTunnelData, IP,           nexthdr=4)
diff --git a/scapy/layers/netbios.py b/scapy/layers/netbios.py
new file mode 100644
index 0000000000000000000000000000000000000000..fdfa4215a9702e10e9f1a9d53d55e8f0a0f0351a
--- /dev/null
+++ b/scapy/layers/netbios.py
@@ -0,0 +1,210 @@
+import struct
+from scapy.packet import *
+from scapy.fields import *
+from scapy.layers.inet import UDP,TCP
+
+class NetBIOS_DS(Packet):
+    name = "NetBIOS datagram service"
+    fields_desc = [
+        ByteEnumField("type",17, {17:"direct_group"}),
+        ByteField("flags",0),
+        XShortField("id",0),
+        IPField("src","127.0.0.1"),
+        ShortField("sport",138),
+        ShortField("len",None),
+        ShortField("ofs",0),
+        NetBIOSNameField("srcname",""),
+        NetBIOSNameField("dstname",""),
+        ]
+    def post_build(self, p, pay):
+        p += pay
+        if self.len is None:
+            l = len(p)-14
+            p = p[:10]+struct.pack("!H", l)+p[12:]
+        return p
+        
+#        ShortField("length",0),
+#        ShortField("Delimitor",0),
+#        ByteField("command",0),
+#        ByteField("data1",0),
+#        ShortField("data2",0),
+#        ShortField("XMIt",0),
+#        ShortField("RSPCor",0),
+#        StrFixedLenField("dest","",16),
+#        StrFixedLenField("source","",16),
+#        
+#        ]
+#
+
+#NetBIOS
+
+
+# Name Query Request
+# Node Status Request
+class NBNSQueryRequest(Packet):
+    name="NBNS query request"
+    fields_desc = [ShortField("NAME_TRN_ID",0),
+                   ShortField("FLAGS", 0x0110),
+                   ShortField("QDCOUNT",1),
+                   ShortField("ANCOUNT",0),
+                   ShortField("NSCOUNT",0),
+                   ShortField("ARCOUNT",0),
+                   NetBIOSNameField("QUESTION_NAME","windows"),
+                   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"}),
+                   ByteField("NULL",0),
+                   ShortEnumField("QUESTION_TYPE",0x20, {0x20:"NB",0x21:"NBSTAT"}),
+                   ShortEnumField("QUESTION_CLASS",1,{1:"INTERNET"})]
+
+# Name Registration Request
+# Name Refresh Request
+# Name Release Request or Demand
+class NBNSRequest(Packet):
+    name="NBNS request"
+    fields_desc = [ShortField("NAME_TRN_ID",0),
+                   ShortField("FLAGS", 0x2910),
+                   ShortField("QDCOUNT",1),
+                   ShortField("ANCOUNT",0),
+                   ShortField("NSCOUNT",0),
+                   ShortField("ARCOUNT",1),
+                   NetBIOSNameField("QUESTION_NAME","windows"),
+                   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"}),
+                   ByteField("NULL",0),
+                   ShortEnumField("QUESTION_TYPE",0x20, {0x20:"NB",0x21:"NBSTAT"}),
+                   ShortEnumField("QUESTION_CLASS",1,{1:"INTERNET"}),
+                   ShortEnumField("RR_NAME",0xC00C,{0xC00C:"Label String Pointer to QUESTION_NAME"}),
+                   ShortEnumField("RR_TYPE",0x20, {0x20:"NB",0x21:"NBSTAT"}),
+                   ShortEnumField("RR_CLASS",1,{1:"INTERNET"}),
+                   IntField("TTL", 0),
+                   ShortField("RDLENGTH", 6),
+                   BitEnumField("G",0,1,{0:"Unique name",1:"Group name"}),
+                   BitEnumField("OWNER NODE TYPE",00,2,{00:"B node",01:"P node",02:"M node",03:"H node"}),
+                   BitEnumField("UNUSED",0,13,{0:"Unused"}),
+                   IPField("NB_ADDRESS", "127.0.0.1")]
+
+# Name Query Response
+# Name Registration Response
+class NBNSQueryResponse(Packet):
+    name="NBNS query response"
+    fields_desc = [ShortField("NAME_TRN_ID",0),
+                   ShortField("FLAGS", 0x8500),
+                   ShortField("QDCOUNT",0),
+                   ShortField("ANCOUNT",1),
+                   ShortField("NSCOUNT",0),
+                   ShortField("ARCOUNT",0),
+                   NetBIOSNameField("RR_NAME","windows"),
+                   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"}),
+                   ByteField("NULL",0),
+                   ShortEnumField("QUESTION_TYPE",0x20, {0x20:"NB",0x21:"NBSTAT"}),
+                   ShortEnumField("QUESTION_CLASS",1,{1:"INTERNET"}),
+                   IntField("TTL", 0x493e0),
+                   ShortField("RDLENGTH", 6),
+                   ShortField("NB_FLAGS", 0),
+                   IPField("NB_ADDRESS", "127.0.0.1")]
+
+# Name Query Response (negative)
+# Name Release Response
+class NBNSQueryResponseNegative(Packet):
+    name="NBNS query response (negative)"
+    fields_desc = [ShortField("NAME_TRN_ID",0), 
+                   ShortField("FLAGS", 0x8506),
+                   ShortField("QDCOUNT",0),
+                   ShortField("ANCOUNT",1),
+                   ShortField("NSCOUNT",0),
+                   ShortField("ARCOUNT",0),
+                   NetBIOSNameField("RR_NAME","windows"),
+                   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"}),
+                   ByteField("NULL",0),
+                   ShortEnumField("RR_TYPE",0x20, {0x20:"NB",0x21:"NBSTAT"}),
+                   ShortEnumField("RR_CLASS",1,{1:"INTERNET"}),
+                   IntField("TTL",0),
+                   ShortField("RDLENGTH",6),
+                   BitEnumField("G",0,1,{0:"Unique name",1:"Group name"}),
+                   BitEnumField("OWNER NODE TYPE",00,2,{00:"B node",01:"P node",02:"M node",03:"H node"}),
+                   BitEnumField("UNUSED",0,13,{0:"Unused"}),
+                   IPField("NB_ADDRESS", "127.0.0.1")]
+    
+# Node Status Response
+class NBNSNodeStatusResponse(Packet):
+    name="NBNS Node Status Response"
+    fields_desc = [ShortField("NAME_TRN_ID",0), 
+                   ShortField("FLAGS", 0x8500),
+                   ShortField("QDCOUNT",0),
+                   ShortField("ANCOUNT",1),
+                   ShortField("NSCOUNT",0),
+                   ShortField("ARCOUNT",0),
+                   NetBIOSNameField("RR_NAME","windows"),
+                   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"}),
+                   ByteField("NULL",0),
+                   ShortEnumField("RR_TYPE",0x21, {0x20:"NB",0x21:"NBSTAT"}),
+                   ShortEnumField("RR_CLASS",1,{1:"INTERNET"}),
+                   IntField("TTL",0),
+                   ShortField("RDLENGTH",83),
+                   ByteField("NUM_NAMES",1)]
+
+# Service for Node Status Response
+class NBNSNodeStatusResponseService(Packet):
+    name="NBNS Node Status Response Service"
+    fields_desc = [StrFixedLenField("NETBIOS_NAME","WINDOWS         ",15),
+                   ByteEnumField("SUFFIX",0,{0:"workstation",0x03:"messenger service",0x20:"file server service",0x1b:"domain master browser",0x1c:"domain controller", 0x1e:"browser election service"}),
+                   ByteField("NAME_FLAGS",0x4),
+                   ByteEnumField("UNUSED",0,{0:"unused"})]
+
+# End of Node Status Response packet
+class NBNSNodeStatusResponseEnd(Packet):
+    name="NBNS Node Status Response"
+    fields_desc = [SourceMACField("MAC_ADDRESS"),
+                   BitField("STATISTICS",0,57*8)]
+
+# Wait for Acknowledgement Response
+class NBNSWackResponse(Packet):
+    name="NBNS Wait for Acknowledgement Response"
+    fields_desc = [ShortField("NAME_TRN_ID",0),
+                   ShortField("FLAGS", 0xBC07),
+                   ShortField("QDCOUNT",0),
+                   ShortField("ANCOUNT",1),
+                   ShortField("NSCOUNT",0),
+                   ShortField("ARCOUNT",0),
+                   NetBIOSNameField("RR_NAME","windows"),
+                   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"}),
+                   ByteField("NULL",0),
+                   ShortEnumField("RR_TYPE",0x20, {0x20:"NB",0x21:"NBSTAT"}),
+                   ShortEnumField("RR_CLASS",1,{1:"INTERNET"}),
+                   IntField("TTL", 2),
+                   ShortField("RDLENGTH",2),
+                   BitField("RDATA",10512,16)] #10512=0010100100010000
+
+class NBTDatagram(Packet):
+    name="NBT Datagram Packet"
+    fields_desc= [ByteField("Type", 0x10),
+                  ByteField("Flags", 0x02),
+                  ShortField("ID", 0),
+                  IPField("SourceIP", "127.0.0.1"),
+                  ShortField("SourcePort", 138),
+                  ShortField("Length", 272),
+                  ShortField("Offset", 0),
+                  NetBIOSNameField("SourceName","windows"),
+                  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"}),
+                  ByteField("NULL",0),
+                  NetBIOSNameField("DestinationName","windows"),
+                  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"}),
+                  ByteField("NULL",0)]
+    
+
+class NBTSession(Packet):
+    name="NBT Session Packet"
+    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"}),
+                  BitField("RESERVED",0x00,7),
+                  BitField("LENGTH",0,17)]
+
+bind_layers( UDP,           NBNSQueryRequest,  dport=137)
+bind_layers( UDP,           NBNSRequest,       dport=137)
+bind_layers( UDP,           NBNSQueryResponse, sport=137)
+bind_layers( UDP,           NBNSQueryResponseNegative, sport=137)
+bind_layers( UDP,           NBNSNodeStatusResponse,    sport=137)
+bind_layers( NBNSNodeStatusResponse,        NBNSNodeStatusResponseService, )
+bind_layers( NBNSNodeStatusResponse,        NBNSNodeStatusResponseService, )
+bind_layers( NBNSNodeStatusResponseService, NBNSNodeStatusResponseService, )
+bind_layers( NBNSNodeStatusResponseService, NBNSNodeStatusResponseEnd, )
+bind_layers( UDP,           NBNSWackResponse, sport=137)
+bind_layers( UDP,           NBTDatagram,      dport=138)
+bind_layers( TCP,           NBTSession,       dport=139)
diff --git a/scapy/layers/netflow.py b/scapy/layers/netflow.py
new file mode 100644
index 0000000000000000000000000000000000000000..aa652e205def1f3d37356d0686bb009b3ab0d44d
--- /dev/null
+++ b/scapy/layers/netflow.py
@@ -0,0 +1,35 @@
+# Cisco Netflow Protocol version 1
+class NetflowHeader(Packet):
+    name = "Netflow Header"
+    fields_desc = [ ShortField("version", 1) ]
+    
+class NetflowHeaderV1(Packet):
+    name = "Netflow Header V1"
+    fields_desc = [ ShortField("count", 0),
+                    IntField("sysUptime", 0),
+                    IntField("unixSecs", 0),
+                    IntField("unixNanoSeconds", 0) ]
+
+
+class NetflowRecordV1(Packet):
+    name = "Netflow Record"
+    fields_desc = [ IPField("ipsrc", "0.0.0.0"),
+                    IPField("ipdst", "0.0.0.0"),
+                    IPField("nexthop", "0.0.0.0"),
+                    ShortField("inputIfIndex", 0),
+                    ShortField("outpuIfIndex", 0),
+                    IntField("dpkts", 0),
+                    IntField("dbytes", 0),
+                    IntField("starttime", 0),
+                    IntField("endtime", 0),
+                    ShortField("srcport", 0),
+                    ShortField("dstport", 0),
+                    ShortField("padding", 0),
+                    ByteField("proto", 0),
+                    ByteField("tos", 0),
+                    IntField("padding1", 0),
+                    IntField("padding2", 0) ]
+
+
+bind_layers( NetflowHeader,   NetflowHeaderV1, version=1)
+bind_layers( NetflowHeaderV1, NetflowRecordV1, )
diff --git a/scapy/layers/ntp.py b/scapy/layers/ntp.py
new file mode 100644
index 0000000000000000000000000000000000000000..5f07bb9f9ac105e60360c92b0028ab0ea7430d5d
--- /dev/null
+++ b/scapy/layers/ntp.py
@@ -0,0 +1,77 @@
+from scapy.packet import *
+from scapy.fields import *
+from scapy.layers.inet import UDP
+
+# seconds between 01-01-1900 and 01-01-1970
+ntp_basetime = 2208988800
+
+class TimeStampField(BitField):
+    def __init__(self, name, default, size):
+        BitField.__init__(self, name, default, size)
+        self.size  = size
+    def getfield(self, pkt, s):
+        s,timestamp = BitField.getfield(self, pkt, s)
+
+        if timestamp:
+            # timestamp is a 64 bits field :
+            #  + first 32 bits : number of seconds since 1900
+            #  + last 32 bits  : fraction part
+            timestamp >>= 32
+            timestamp -= ntp_basetime
+            
+            from time import gmtime, strftime
+            b = strftime("%a, %d %b %Y %H:%M:%S +0000", gmtime(timestamp))
+        else:
+            b = 'None'
+        
+        return s, b
+    def addfield(self, pkt, s, val):
+        t = -1
+        if type(val) is str:
+            from time import strptime, mktime
+            t = int(mktime(strptime(val))) + ntp_basetime + 3600
+        else:
+            if val == -1:
+                from time import time
+                t = int(time()) + ntp_basetime
+            else:
+                t = val
+        t <<= 32
+        return BitField.addfield(self,pkt,s, t)
+
+
+class NTP(Packet):
+    # RFC 1769
+    name = "NTP"
+    fields_desc = [ 
+         BitEnumField('leap', 0, 2,
+                      { 0: 'nowarning',
+                        1: 'longminute',
+                        2: 'shortminute',
+                        3: 'notsync'}),
+         BitField('version', 3, 3),
+         BitEnumField('mode', 3, 3,
+                      { 0: 'reserved',
+                        1: 'sym_active',
+                        2: 'sym_passive',
+                        3: 'client',
+                        4: 'server',
+                        5: 'broadcast',
+                        6: 'control',
+                        7: 'private'}),
+         BitField('stratum', 2, 8),
+         BitField('poll', 0xa, 8),          ### XXX : it's a signed int
+         BitField('precision', 0, 8),       ### XXX : it's a signed int
+         FloatField('delay', 0, 32),
+         FloatField('dispersion', 0, 32),
+         IPField('id', "127.0.0.1"),
+         TimeStampField('ref', 0, 64),
+         TimeStampField('orig', -1, 64),  # -1 means current time
+         TimeStampField('recv', 0, 64),
+         TimeStampField('sent', -1, 64) 
+         ]
+    def mysummary(self):
+        return self.sprintf("NTP v%ir,NTP.version%, %NTP.mode%")
+
+
+bind_layers( UDP,           NTP,           dport=123, sport=123)
diff --git a/scapy/layers/ppp.py b/scapy/layers/ppp.py
new file mode 100644
index 0000000000000000000000000000000000000000..cec4e18db2db95a35b11b30651e78b4ff9b8a437
--- /dev/null
+++ b/scapy/layers/ppp.py
@@ -0,0 +1,362 @@
+import struct
+from scapy.packet import *
+from scapy.layers.l2 import *
+from scapy.layers.inet import *
+from scapy.fields import *
+
+class PPPoE(Packet):
+    name = "PPP over Ethernet"
+    fields_desc = [ BitField("version", 1, 4),
+                    BitField("type", 1, 4),
+                    ByteEnumField("code", 0, {0:"Session"}),
+                    XShortField("sessionid", 0x0),
+                    ShortField("len", None) ]
+
+    def post_build(self, p, pay):
+        p += pay
+        if self.len is None:
+            l = len(p)-6
+            p = p[:4]+struct.pack("!H", l)+p[6:]
+        return p
+
+class PPPoED(PPPoE):
+    name = "PPP over Ethernet Discovery"
+    fields_desc = [ BitField("version", 1, 4),
+                    BitField("type", 1, 4),
+                    ByteEnumField("code", 0x09, {0x09:"PADI",0x07:"PADO",0x19:"PADR",0x65:"PADS",0xa7:"PADT"}),
+                    XShortField("sessionid", 0x0),
+                    ShortField("len", None) ]
+
+
+_PPP_proto = { 0x0001: "Padding Protocol",
+               0x0003: "ROHC small-CID [RFC3095]",
+               0x0005: "ROHC large-CID [RFC3095]",
+               0x0021: "Internet Protocol version 4",
+               0x0023: "OSI Network Layer",
+               0x0025: "Xerox NS IDP",
+               0x0027: "DECnet Phase IV",
+               0x0029: "Appletalk",
+               0x002b: "Novell IPX",
+               0x002d: "Van Jacobson Compressed TCP/IP",
+               0x002f: "Van Jacobson Uncompressed TCP/IP",
+               0x0031: "Bridging PDU",
+               0x0033: "Stream Protocol (ST-II)",
+               0x0035: "Banyan Vines",
+               0x0037: "reserved (until 1993) [Typo in RFC1172]",
+               0x0039: "AppleTalk EDDP",
+               0x003b: "AppleTalk SmartBuffered",
+               0x003d: "Multi-Link [RFC1717]",
+               0x003f: "NETBIOS Framing",
+               0x0041: "Cisco Systems",
+               0x0043: "Ascom Timeplex",
+               0x0045: "Fujitsu Link Backup and Load Balancing (LBLB)",
+               0x0047: "DCA Remote Lan",
+               0x0049: "Serial Data Transport Protocol (PPP-SDTP)",
+               0x004b: "SNA over 802.2",
+               0x004d: "SNA",
+               0x004f: "IPv6 Header Compression",
+               0x0051: "KNX Bridging Data [ianp]",
+               0x0053: "Encryption [Meyer]",
+               0x0055: "Individual Link Encryption [Meyer]",
+               0x0057: "Internet Protocol version 6 [Hinden]",
+               0x0059: "PPP Muxing [RFC3153]",
+               0x005b: "Vendor-Specific Network Protocol (VSNP) [RFC3772]",
+               0x0061: "RTP IPHC Full Header [RFC3544]",
+               0x0063: "RTP IPHC Compressed TCP [RFC3544]",
+               0x0065: "RTP IPHC Compressed Non TCP [RFC3544]",
+               0x0067: "RTP IPHC Compressed UDP 8 [RFC3544]",
+               0x0069: "RTP IPHC Compressed RTP 8 [RFC3544]",
+               0x006f: "Stampede Bridging",
+               0x0071: "Reserved [Fox]",
+               0x0073: "MP+ Protocol [Smith]",
+               0x007d: "reserved (Control Escape) [RFC1661]",
+               0x007f: "reserved (compression inefficient [RFC1662]",
+               0x0081: "Reserved Until 20-Oct-2000 [IANA]",
+               0x0083: "Reserved Until 20-Oct-2000 [IANA]",
+               0x00c1: "NTCITS IPI [Ungar]",
+               0x00cf: "reserved (PPP NLID)",
+               0x00fb: "single link compression in multilink [RFC1962]",
+               0x00fd: "compressed datagram [RFC1962]",
+               0x00ff: "reserved (compression inefficient)",
+               0x0201: "802.1d Hello Packets",
+               0x0203: "IBM Source Routing BPDU",
+               0x0205: "DEC LANBridge100 Spanning Tree",
+               0x0207: "Cisco Discovery Protocol [Sastry]",
+               0x0209: "Netcs Twin Routing [Korfmacher]",
+               0x020b: "STP - Scheduled Transfer Protocol [Segal]",
+               0x020d: "EDP - Extreme Discovery Protocol [Grosser]",
+               0x0211: "Optical Supervisory Channel Protocol (OSCP)[Prasad]",
+               0x0213: "Optical Supervisory Channel Protocol (OSCP)[Prasad]",
+               0x0231: "Luxcom",
+               0x0233: "Sigma Network Systems",
+               0x0235: "Apple Client Server Protocol [Ridenour]",
+               0x0281: "MPLS Unicast [RFC3032]  ",
+               0x0283: "MPLS Multicast [RFC3032]",
+               0x0285: "IEEE p1284.4 standard - data packets [Batchelder]",
+               0x0287: "ETSI TETRA Network Protocol Type 1 [Nieminen]",
+               0x0289: "Multichannel Flow Treatment Protocol [McCann]",
+               0x2063: "RTP IPHC Compressed TCP No Delta [RFC3544]",
+               0x2065: "RTP IPHC Context State [RFC3544]",
+               0x2067: "RTP IPHC Compressed UDP 16 [RFC3544]",
+               0x2069: "RTP IPHC Compressed RTP 16 [RFC3544]",
+               0x4001: "Cray Communications Control Protocol [Stage]",
+               0x4003: "CDPD Mobile Network Registration Protocol [Quick]",
+               0x4005: "Expand accelerator protocol [Rachmani]",
+               0x4007: "ODSICP NCP [Arvind]",
+               0x4009: "DOCSIS DLL [Gaedtke]",
+               0x400B: "Cetacean Network Detection Protocol [Siller]",
+               0x4021: "Stacker LZS [Simpson]",
+               0x4023: "RefTek Protocol [Banfill]",
+               0x4025: "Fibre Channel [Rajagopal]",
+               0x4027: "EMIT Protocols [Eastham]",
+               0x405b: "Vendor-Specific Protocol (VSP) [RFC3772]",
+               0x8021: "Internet Protocol Control Protocol",
+               0x8023: "OSI Network Layer Control Protocol",
+               0x8025: "Xerox NS IDP Control Protocol",
+               0x8027: "DECnet Phase IV Control Protocol",
+               0x8029: "Appletalk Control Protocol",
+               0x802b: "Novell IPX Control Protocol",
+               0x802d: "reserved",
+               0x802f: "reserved",
+               0x8031: "Bridging NCP",
+               0x8033: "Stream Protocol Control Protocol",
+               0x8035: "Banyan Vines Control Protocol",
+               0x8037: "reserved (until 1993)",
+               0x8039: "reserved",
+               0x803b: "reserved",
+               0x803d: "Multi-Link Control Protocol",
+               0x803f: "NETBIOS Framing Control Protocol",
+               0x8041: "Cisco Systems Control Protocol",
+               0x8043: "Ascom Timeplex",
+               0x8045: "Fujitsu LBLB Control Protocol",
+               0x8047: "DCA Remote Lan Network Control Protocol (RLNCP)",
+               0x8049: "Serial Data Control Protocol (PPP-SDCP)",
+               0x804b: "SNA over 802.2 Control Protocol",
+               0x804d: "SNA Control Protocol",
+               0x804f: "IP6 Header Compression Control Protocol",
+               0x8051: "KNX Bridging Control Protocol [ianp]",
+               0x8053: "Encryption Control Protocol [Meyer]",
+               0x8055: "Individual Link Encryption Control Protocol [Meyer]",
+               0x8057: "IPv6 Control Protovol [Hinden]",
+               0x8059: "PPP Muxing Control Protocol [RFC3153]",
+               0x805b: "Vendor-Specific Network Control Protocol (VSNCP) [RFC3772]",
+               0x806f: "Stampede Bridging Control Protocol",
+               0x8073: "MP+ Control Protocol [Smith]",
+               0x8071: "Reserved [Fox]",
+               0x807d: "Not Used - reserved [RFC1661]",
+               0x8081: "Reserved Until 20-Oct-2000 [IANA]",
+               0x8083: "Reserved Until 20-Oct-2000 [IANA]",
+               0x80c1: "NTCITS IPI Control Protocol [Ungar]",
+               0x80cf: "Not Used - reserved [RFC1661]",
+               0x80fb: "single link compression in multilink control [RFC1962]",
+               0x80fd: "Compression Control Protocol [RFC1962]",
+               0x80ff: "Not Used - reserved [RFC1661]",
+               0x8207: "Cisco Discovery Protocol Control [Sastry]",
+               0x8209: "Netcs Twin Routing [Korfmacher]",
+               0x820b: "STP - Control Protocol [Segal]",
+               0x820d: "EDPCP - Extreme Discovery Protocol Ctrl Prtcl [Grosser]",
+               0x8235: "Apple Client Server Protocol Control [Ridenour]",
+               0x8281: "MPLSCP [RFC3032]",
+               0x8285: "IEEE p1284.4 standard - Protocol Control [Batchelder]",
+               0x8287: "ETSI TETRA TNP1 Control Protocol [Nieminen]",
+               0x8289: "Multichannel Flow Treatment Protocol [McCann]",
+               0xc021: "Link Control Protocol",
+               0xc023: "Password Authentication Protocol",
+               0xc025: "Link Quality Report",
+               0xc027: "Shiva Password Authentication Protocol",
+               0xc029: "CallBack Control Protocol (CBCP)",
+               0xc02b: "BACP Bandwidth Allocation Control Protocol [RFC2125]",
+               0xc02d: "BAP [RFC2125]",
+               0xc05b: "Vendor-Specific Authentication Protocol (VSAP) [RFC3772]",
+               0xc081: "Container Control Protocol [KEN]",
+               0xc223: "Challenge Handshake Authentication Protocol",
+               0xc225: "RSA Authentication Protocol [Narayana]",
+               0xc227: "Extensible Authentication Protocol [RFC2284]",
+               0xc229: "Mitsubishi Security Info Exch Ptcl (SIEP) [Seno]",
+               0xc26f: "Stampede Bridging Authorization Protocol",
+               0xc281: "Proprietary Authentication Protocol [KEN]",
+               0xc283: "Proprietary Authentication Protocol [Tackabury]",
+               0xc481: "Proprietary Node ID Authentication Protocol [KEN]"}
+
+
+class HDLC(Packet):
+    fields_desc = [ XByteField("address",0xff),
+                    XByteField("control",0x03)  ]
+
+class PPP_metaclass(Packet_metaclass):
+    def __call__(self, _pkt=None, *args, **kargs):
+        cls = self
+        if _pkt and _pkt[0] == '\xff':
+            cls = HDLC
+        i = cls.__new__(cls, cls.__name__, cls.__bases__, cls.__dict__)
+        i.__init__(_pkt=_pkt, *args, **kargs)
+        return i
+    
+
+class PPP(Packet):
+    __metaclass__ = PPP_metaclass
+    name = "PPP Link Layer"
+    fields_desc = [ ShortEnumField("proto", 0x0021, _PPP_proto) ]
+
+_PPP_conftypes = { 1:"Configure-Request",
+                   2:"Configure-Ack",
+                   3:"Configure-Nak",
+                   4:"Configure-Reject",
+                   5:"Terminate-Request",
+                   6:"Terminate-Ack",
+                   7:"Code-Reject",
+                   8:"Protocol-Reject",
+                   9:"Echo-Request",
+                   10:"Echo-Reply",
+                   11:"Discard-Request",
+                   14:"Reset-Request",
+                   15:"Reset-Ack",
+                   }
+
+class PPP_Option_metaclass(Packet_metaclass):
+    _known_options={}
+    def __call__(self, _pkt=None, *args, **kargs):
+        cls = self
+        if _pkt:
+            t = ord(_pkt[0])
+            cls = self._known_options.get(t,self)
+        i = cls.__new__(cls, cls.__name__, cls.__bases__, cls.__dict__)
+        i.__init__(_pkt=_pkt, *args, **kargs)
+        return i
+    def _register(self, cls):
+        self._known_options[cls.fields_desc[0].default] = cls
+
+
+### PPP IPCP stuff (RFC 1332)
+
+# All IPCP options are defined below (names and associated classes) 
+_PPP_ipcpopttypes = {     1:"IP-Addresses (Deprecated)",
+                          2:"IP-Compression-Protocol",
+                          3:"IP-Address",
+                          4:"Mobile-IPv4", # not implemented, present for completeness
+                          129:"Primary-DNS-Address",
+                          130:"Primary-NBNS-Address",
+                          131:"Secondary-DNS-Address",
+                          132:"Secondary-NBNS-Address"}
+
+
+
+class PPP_IPCP_Option_metaclass(PPP_Option_metaclass):
+    _known_options={}
+
+
+class PPP_IPCP_Option(Packet):
+    __metaclass__=PPP_IPCP_Option_metaclass
+    name = "PPP IPCP Option"
+    fields_desc = [ ByteEnumField("type" , None , _PPP_ipcpopttypes),
+                    FieldLenField("len", None, length_of="data", fmt="B", adjust=lambda p,x:x+2),
+                    StrLenField("data", "", length_from=lambda p:max(0,p.len-2)) ]
+    def extract_padding(self, pay):
+        return "",pay
+
+class PPP_IPCP_Specific_Option_metaclass(PPP_IPCP_Option_metaclass):
+    def __new__(cls, name, bases, dct):
+        newcls = super(PPP_IPCP_Specific_Option_metaclass, cls).__new__(cls, name, bases, dct)
+        PPP_IPCP_Option._register(newcls)
+        
+
+class PPP_IPCP_Option_IPAddress(PPP_IPCP_Option):
+    __metaclass__=PPP_IPCP_Specific_Option_metaclass
+    name = "PPP IPCP Option: IP Address"
+    fields_desc = [ ByteEnumField("type" , 3 , _PPP_ipcpopttypes),
+                    FieldLenField("len", None, length_of="data", fmt="B", adjust=lambda p,x:x+6),
+                    IPField("data","0.0.0.0"),
+                    ConditionalField(StrLenField("garbage","", length_from=lambda pkt:pkt.len-6), lambda p:p.len!=6) ]
+
+class PPP_IPCP_Option_DNS1(PPP_IPCP_Option):
+    __metaclass__=PPP_IPCP_Specific_Option_metaclass
+    name = "PPP IPCP Option: DNS1 Address"
+    fields_desc = [ ByteEnumField("type" , 129 , _PPP_ipcpopttypes),
+                    FieldLenField("len", None, length_of="data", fmt="B", adjust=lambda p,x:x+6),
+                    IPField("data","0.0.0.0"),
+                    ConditionalField(StrLenField("garbage","", length_from=lambda pkt:pkt.len-6), lambda p:p.len!=6) ]
+
+class PPP_IPCP_Option_DNS2(PPP_IPCP_Option):
+    __metaclass__=PPP_IPCP_Specific_Option_metaclass
+    name = "PPP IPCP Option: DNS2 Address"
+    fields_desc = [ ByteEnumField("type" , 131 , _PPP_ipcpopttypes),
+                    FieldLenField("len", None, length_of="data", fmt="B", adjust=lambda p,x:x+6),
+                    IPField("data","0.0.0.0"),
+                    ConditionalField(StrLenField("garbage","", length_from=lambda pkt:pkt.len-6), lambda p:p.len!=6) ]
+
+class PPP_IPCP_Option_NBNS1(PPP_IPCP_Option):
+    __metaclass__=PPP_IPCP_Specific_Option_metaclass
+    name = "PPP IPCP Option: NBNS1 Address"
+    fields_desc = [ ByteEnumField("type" , 130 , _PPP_ipcpopttypes),
+                    FieldLenField("len", None, length_of="data", fmt="B", adjust=lambda p,x:x+6),
+                    IPField("data","0.0.0.0"),
+                    ConditionalField(StrLenField("garbage","", length_from=lambda pkt:pkt.len-6), lambda p:p.len!=6) ]
+
+class PPP_IPCP_Option_NBNS2(PPP_IPCP_Option):
+    __metaclass__=PPP_IPCP_Specific_Option_metaclass
+    name = "PPP IPCP Option: NBNS2 Address"
+    fields_desc = [ ByteEnumField("type" , 132 , _PPP_ipcpopttypes),
+                    FieldLenField("len", None, length_of="data", fmt="B", adjust=lambda p,x:x+6),
+                    IPField("data","0.0.0.0"),
+                    ConditionalField(StrLenField("garbage","", length_from=lambda pkt:pkt.len-6), lambda p:p.len!=6) ]
+
+
+
+
+class PPP_IPCP(Packet):
+    fields_desc = [ ByteEnumField("code" , 1, _PPP_conftypes),
+		    XByteField("id", 0 ),
+                    FieldLenField("len" , None, fmt="H", length_of="options", adjust=lambda p,x:x+4 ),
+                    PacketListField("options", [],  PPP_IPCP_Option, length_from=lambda p:p.len-4,) ]
+
+
+### ECP
+
+_PPP_ecpopttypes = { 0:"OUI",
+                     1:"DESE", }
+
+class PPP_ECP_Option_metaclass(PPP_Option_metaclass):
+    _known_options={}
+
+
+
+class PPP_ECP_Option(Packet):
+    __metaclass__=PPP_ECP_Option_metaclass
+    name = "PPP ECP Option"
+    fields_desc = [ ByteEnumField("type" , None , _PPP_ecpopttypes),
+                    FieldLenField("len", None, length_of="data", fmt="B", adjust=lambda p,x:x+2),
+                    StrLenField("data", "", length_from=lambda p:max(0,p.len-2)) ]
+    def extract_padding(self, pay):
+        return "",pay
+
+class PPP_ECP_Specific_Option_metaclass(PPP_ECP_Option_metaclass):
+    def __new__(cls, name, bases, dct):
+        newcls = super(PPP_ECP_Specific_Option_metaclass, cls).__new__(cls, name, bases, dct)
+        PPP_ECP_Option._register(newcls)
+        
+
+class PPP_ECP_Option_OUI(PPP_ECP_Option):
+    __metaclass__=PPP_ECP_Specific_Option_metaclass
+    fields_desc = [ ByteEnumField("type" , 0 , _PPP_ecpopttypes),
+                    FieldLenField("len", None, length_of="data", fmt="B", adjust=lambda p,x:x+2),
+                    StrFixedLenField("oui","",3),
+                    ByteField("subtype",0),
+                    StrLenField("data", "", length_from=lambda p:p.len-6) ]
+                    
+
+
+class PPP_ECP(Packet):
+    fields_desc = [ ByteEnumField("code" , 1, _PPP_conftypes),
+		    XByteField("id", 0 ),
+                    FieldLenField("len" , None, fmt="H", length_of="options", adjust=lambda p,x:x+4 ),
+                    PacketListField("options", [],  PPP_ECP_Option, length_from=lambda p:p.len-4,) ]
+
+bind_layers( Ether,         PPPoED,        type=34915)
+bind_layers( Ether,         PPPoE,         type=34916)
+bind_layers( CookedLinux,   PPPoED,        proto=34915)
+bind_layers( CookedLinux,   PPPoE,         proto=34916)
+bind_layers( PPPoE,         PPP,           code=0)
+bind_layers( HDLC,          PPP,           )
+bind_layers( PPP,           IP,            proto=33)
+bind_layers( PPP,           PPP_IPCP,      proto=0x8021)
+bind_layers( PPP,           PPP_ECP,       proto=0x8053)
diff --git a/scapy/layers/radius.py b/scapy/layers/radius.py
new file mode 100644
index 0000000000000000000000000000000000000000..13946b9a85a675a9f99b96c4932aeb84d4f06839
--- /dev/null
+++ b/scapy/layers/radius.py
@@ -0,0 +1,56 @@
+import struct
+from scapy.packet import *
+from scapy.fields import *
+
+class Radius(Packet):
+    name = "Radius"
+    fields_desc = [ ByteEnumField("code", 1, {1: "Access-Request",
+                                              2: "Access-Accept",
+                                              3: "Access-Reject",
+                                              4: "Accounting-Request",
+                                              5: "Accounting-Accept",
+                                              6: "Accounting-Status",
+                                              7: "Password-Request",
+                                              8: "Password-Ack",
+                                              9: "Password-Reject",
+                                              10: "Accounting-Message",
+                                              11: "Access-Challenge",
+                                              12: "Status-Server",
+                                              13: "Status-Client",
+                                              21: "Resource-Free-Request",
+                                              22: "Resource-Free-Response",
+                                              23: "Resource-Query-Request",
+                                              24: "Resource-Query-Response",
+                                              25: "Alternate-Resource-Reclaim-Request",
+                                              26: "NAS-Reboot-Request",
+                                              27: "NAS-Reboot-Response",
+                                              29: "Next-Passcode",
+                                              30: "New-Pin",
+                                              31: "Terminate-Session",
+                                              32: "Password-Expired",
+                                              33: "Event-Request",
+                                              34: "Event-Response",
+                                              40: "Disconnect-Request",
+                                              41: "Disconnect-ACK",
+                                              42: "Disconnect-NAK",
+                                              43: "CoA-Request",
+                                              44: "CoA-ACK",
+                                              45: "CoA-NAK",
+                                              50: "IP-Address-Allocate",
+                                              51: "IP-Address-Release",
+                                              253: "Experimental-use",
+                                              254: "Reserved",
+                                              255: "Reserved"} ),
+                    ByteField("id", 0),
+                    ShortField("len", None),
+                    StrFixedLenField("authenticator","",16) ]
+    def post_build(self, p, pay):
+        p += pay
+        l = self.len
+        if l is None:
+            l = len(p)
+            p = p[:2]+struct.pack("!H",l)+p[4:]
+        return p
+
+
+
diff --git a/scapy/layers/rip.py b/scapy/layers/rip.py
new file mode 100644
index 0000000000000000000000000000000000000000..f41b611cc29a62079f2c6c896042355f3d7842ab
--- /dev/null
+++ b/scapy/layers/rip.py
@@ -0,0 +1,31 @@
+from scapy.packet import *
+from scapy.fields import *
+from scapy.layers.inet import UDP
+
+class RIP(Packet):
+    name = "RIP header"
+    fields_desc = [
+        ByteEnumField("command",1,{1:"req",2:"resp",3:"traceOn",4:"traceOff",5:"sun",
+                                   6:"trigReq",7:"trigResp",8:"trigAck",9:"updateReq",
+                                   10:"updateResp",11:"updateAck"}),
+        ByteField("version",1),
+        ShortField("null",0),
+        ]
+
+class RIPEntry(Packet):
+    name = "RIP entry"
+    fields_desc = [
+        ShortEnumField("AF",2,{2:"IP"}),
+        ShortField("RouteTag",0),
+        IPField("addr","0.0.0.0"),
+        IPField("mask","0.0.0.0"),
+        IPField("nextHop","0.0.0.0"),
+        IntEnumField("metric",1,{16:"Unreach"}),
+        ]
+        
+
+
+bind_layers( UDP,           RIP,           sport=520)
+bind_layers( UDP,           RIP,           dport=520)
+bind_layers( RIP,           RIPEntry,      )
+bind_layers( RIPEntry,      RIPEntry,      )
diff --git a/scapy/layers/rtp.py b/scapy/layers/rtp.py
new file mode 100644
index 0000000000000000000000000000000000000000..f926f2aa5da0dc9ca6c66be7d2edf03031162884
--- /dev/null
+++ b/scapy/layers/rtp.py
@@ -0,0 +1,31 @@
+from scapy.packet import *
+from scapy.fields import *
+
+_rtp_payload_types = {
+    # http://www.iana.org/assignments/rtp-parameters
+    0:  'G.711 PCMU',    3:  'GSM',
+    4:  'G723',          5:  'DVI4',
+    6:  'DVI4',          7:  'LPC',
+    8:  'PCMA',          9:  'G722',
+    10: 'L16',           11: 'L16',
+    12: 'QCELP',         13: 'CN',
+    14: 'MPA',           15: 'G728',
+    16: 'DVI4',          17: 'DVI4',
+    18: 'G729',          25: 'CelB',
+    26: 'JPEG',          28: 'nv',
+    31: 'H261',          32: 'MPV',
+    33: 'MP2T',          34: 'H263' }
+
+class RTP(Packet):
+    name="RTP"
+    fields_desc = [ BitField('version', 2, 2),
+                    BitField('padding', 0, 1),
+                    BitField('extension', 0, 1),
+                    BitFieldLenField('numsync', None, 4, count_of='sync'),
+                    BitField('marker', 0, 1),
+                    BitEnumField('payload', 0, 7, _rtp_payload_types),
+                    ShortField('sequence', 0),
+                    IntField('timestamp', 0),
+                    IntField('sourcesync', 0),
+                    FieldListField('sync', [], IntField("id",0), count_from=lambda pkt:pkt.numsync) ]
+    
diff --git a/scapy/layers/sebek.py b/scapy/layers/sebek.py
new file mode 100644
index 0000000000000000000000000000000000000000..a22138c18401a4dcc3164f4fa275ca0ddd7c1a7c
--- /dev/null
+++ b/scapy/layers/sebek.py
@@ -0,0 +1,95 @@
+### SEBEK
+
+
+class SebekHead(Packet):
+    name = "Sebek header"
+    fields_desc = [ XIntField("magic", 0xd0d0d0),
+                    ShortField("version", 1),
+                    ShortEnumField("type", 0, {"read":0, "write":1,
+                                             "socket":2, "open":3}),
+                    IntField("counter", 0),
+                    IntField("time_sec", 0),
+                    IntField("time_usec", 0) ]
+    def mysummary(self):
+        return self.sprintf("Sebek Header v%SebekHead.version% %SebekHead.type%")
+
+# we need this because Sebek headers differ between v1 and v3, and
+# between v3 type socket and v3 others
+
+class SebekV1(Packet):
+    name = "Sebek v1"
+    fields_desc = [ IntField("pid", 0),
+                    IntField("uid", 0),
+                    IntField("fd", 0),
+                    StrFixedLenField("command", "", 12),
+                    FieldLenField("data_length", None, "data",fmt="I"),
+                    StrLenField("data", "", length_from=lambda x:x.data_length) ]
+    def mysummary(self):
+        if isinstance(self.underlayer, SebekHead):
+            return self.underlayer.sprintf("Sebek v1 %SebekHead.type% (%SebekV1.command%)")
+        else:
+            return self.sprintf("Sebek v1 (%SebekV1.command%)")
+
+class SebekV3(Packet):
+    name = "Sebek v3"
+    fields_desc = [ IntField("parent_pid", 0),
+                    IntField("pid", 0),
+                    IntField("uid", 0),
+                    IntField("fd", 0),
+                    IntField("inode", 0),
+                    StrFixedLenField("command", "", 12),
+                    FieldLenField("data_length", None, "data",fmt="I"),
+                    StrLenField("data", "", length_from=lambda x:x.data_length) ]
+    def mysummary(self):
+        if isinstance(self.underlayer, SebekHead):
+            return self.underlayer.sprintf("Sebek v%SebekHead.version% %SebekHead.type% (%SebekV3.command%)")
+        else:
+            return self.sprintf("Sebek v3 (%SebekV3.command%)")
+
+class SebekV2(SebekV3):
+    def mysummary(self):
+        if isinstance(self.underlayer, SebekHead):
+            return self.underlayer.sprintf("Sebek v%SebekHead.version% %SebekHead.type% (%SebekV2.command%)")
+        else:
+            return self.sprintf("Sebek v2 (%SebekV2.command%)")
+
+class SebekV3Sock(Packet):
+    name = "Sebek v2 socket"
+    fields_desc = [ IntField("parent_pid", 0),
+                    IntField("pid", 0),
+                    IntField("uid", 0),
+                    IntField("fd", 0),
+                    IntField("inode", 0),
+                    StrFixedLenField("command", "", 12),
+                    IntField("data_length", 15),
+                    IPField("dip", "127.0.0.1"),
+                    ShortField("dport", 0),
+                    IPField("sip", "127.0.0.1"),
+                    ShortField("sport", 0),
+                    ShortEnumField("call", 0, { "bind":2,
+                                                "connect":3, "listen":4,
+                                               "accept":5, "sendmsg":16,
+                                               "recvmsg":17, "sendto":11,
+                                               "recvfrom":12}),
+                    ByteEnumField("proto", 0, IP_PROTOS) ]
+    def mysummary(self):
+        if isinstance(self.underlayer, SebekHead):
+            return self.underlayer.sprintf("Sebek v%SebekHead.version% %SebekHead.type% (%SebekV3Sock.command%)")
+        else:
+            return self.sprintf("Sebek v3 socket (%SebekV3Sock.command%)")
+
+class SebekV2Sock(SebekV3Sock):
+    def mysummary(self):
+        if isinstance(self.underlayer, SebekHead):
+            return self.underlayer.sprintf("Sebek v%SebekHead.version% %SebekHead.type% (%SebekV2Sock.command%)")
+        else:
+            return self.sprintf("Sebek v2 socket (%SebekV2Sock.command%)")
+
+bind_layers( UDP,           SebekHead,     sport=1101)
+bind_layers( UDP,           SebekHead,     dport=1101)
+bind_layers( UDP,           SebekHead,     dport=1101, sport=1101)
+bind_layers( SebekHead,     SebekV1,       version=1)
+bind_layers( SebekHead,     SebekV2Sock,   version=2, type=2)
+bind_layers( SebekHead,     SebekV2,       version=2)
+bind_layers( SebekHead,     SebekV3Sock,   version=3, type=2)
+bind_layers( SebekHead,     SebekV3,       version=3)
diff --git a/scapy/layers/skinny.py b/scapy/layers/skinny.py
new file mode 100644
index 0000000000000000000000000000000000000000..d8eb918ffcec18246c60b9ca4293dce04c9f15d8
--- /dev/null
+++ b/scapy/layers/skinny.py
@@ -0,0 +1,154 @@
+from scapy.packet import *
+from scapy.fields import *
+from scapy.layers.inet import TCP
+
+# Cisco Skinny protocol
+
+# shamelessly ripped from Ethereal dissector
+skinny_messages = { 
+# Station -> Callmanager
+  0x0000: "KeepAliveMessage",
+  0x0001: "RegisterMessage",
+  0x0002: "IpPortMessage",
+  0x0003: "KeypadButtonMessage",
+  0x0004: "EnblocCallMessage",
+  0x0005: "StimulusMessage",
+  0x0006: "OffHookMessage",
+  0x0007: "OnHookMessage",
+  0x0008: "HookFlashMessage",
+  0x0009: "ForwardStatReqMessage",
+  0x000A: "SpeedDialStatReqMessage",
+  0x000B: "LineStatReqMessage",
+  0x000C: "ConfigStatReqMessage",
+  0x000D: "TimeDateReqMessage",
+  0x000E: "ButtonTemplateReqMessage",
+  0x000F: "VersionReqMessage",
+  0x0010: "CapabilitiesResMessage",
+  0x0011: "MediaPortListMessage",
+  0x0012: "ServerReqMessage",
+  0x0020: "AlarmMessage",
+  0x0021: "MulticastMediaReceptionAck",
+  0x0022: "OpenReceiveChannelAck",
+  0x0023: "ConnectionStatisticsRes",
+  0x0024: "OffHookWithCgpnMessage",
+  0x0025: "SoftKeySetReqMessage",
+  0x0026: "SoftKeyEventMessage",
+  0x0027: "UnregisterMessage",
+  0x0028: "SoftKeyTemplateReqMessage",
+  0x0029: "RegisterTokenReq",
+  0x002A: "MediaTransmissionFailure",
+  0x002B: "HeadsetStatusMessage",
+  0x002C: "MediaResourceNotification",
+  0x002D: "RegisterAvailableLinesMessage",
+  0x002E: "DeviceToUserDataMessage",
+  0x002F: "DeviceToUserDataResponseMessage",
+  0x0030: "UpdateCapabilitiesMessage",
+  0x0031: "OpenMultiMediaReceiveChannelAckMessage",
+  0x0032: "ClearConferenceMessage",
+  0x0033: "ServiceURLStatReqMessage",
+  0x0034: "FeatureStatReqMessage",
+  0x0035: "CreateConferenceResMessage",
+  0x0036: "DeleteConferenceResMessage",
+  0x0037: "ModifyConferenceResMessage",
+  0x0038: "AddParticipantResMessage",
+  0x0039: "AuditConferenceResMessage",
+  0x0040: "AuditParticipantResMessage",
+  0x0041: "DeviceToUserDataVersion1Message",
+# Callmanager -> Station */
+  0x0081: "RegisterAckMessage",
+  0x0082: "StartToneMessage",
+  0x0083: "StopToneMessage",
+  0x0085: "SetRingerMessage",
+  0x0086: "SetLampMessage",
+  0x0087: "SetHkFDetectMessage",
+  0x0088: "SetSpeakerModeMessage",
+  0x0089: "SetMicroModeMessage",
+  0x008A: "StartMediaTransmission",
+  0x008B: "StopMediaTransmission",
+  0x008C: "StartMediaReception",
+  0x008D: "StopMediaReception",
+  0x008F: "CallInfoMessage",
+  0x0090: "ForwardStatMessage",
+  0x0091: "SpeedDialStatMessage",
+  0x0092: "LineStatMessage",
+  0x0093: "ConfigStatMessage",
+  0x0094: "DefineTimeDate",
+  0x0095: "StartSessionTransmission",
+  0x0096: "StopSessionTransmission",
+  0x0097: "ButtonTemplateMessage",
+  0x0098: "VersionMessage",
+  0x0099: "DisplayTextMessage",
+  0x009A: "ClearDisplay",
+  0x009B: "CapabilitiesReqMessage",
+  0x009C: "EnunciatorCommandMessage",
+  0x009D: "RegisterRejectMessage",
+  0x009E: "ServerResMessage",
+  0x009F: "Reset",
+  0x0100: "KeepAliveAckMessage",
+  0x0101: "StartMulticastMediaReception",
+  0x0102: "StartMulticastMediaTransmission",
+  0x0103: "StopMulticastMediaReception",
+  0x0104: "StopMulticastMediaTransmission",
+  0x0105: "OpenReceiveChannel",
+  0x0106: "CloseReceiveChannel",
+  0x0107: "ConnectionStatisticsReq",
+  0x0108: "SoftKeyTemplateResMessage",
+  0x0109: "SoftKeySetResMessage",
+  0x0110: "SelectSoftKeysMessage",
+  0x0111: "CallStateMessage",
+  0x0112: "DisplayPromptStatusMessage",
+  0x0113: "ClearPromptStatusMessage",
+  0x0114: "DisplayNotifyMessage",
+  0x0115: "ClearNotifyMessage",
+  0x0116: "ActivateCallPlaneMessage",
+  0x0117: "DeactivateCallPlaneMessage",
+  0x0118: "UnregisterAckMessage",
+  0x0119: "BackSpaceReqMessage",
+  0x011A: "RegisterTokenAck",
+  0x011B: "RegisterTokenReject",
+  0x0042: "DeviceToUserDataResponseVersion1Message",
+  0x011C: "StartMediaFailureDetection",
+  0x011D: "DialedNumberMessage",
+  0x011E: "UserToDeviceDataMessage",
+  0x011F: "FeatureStatMessage",
+  0x0120: "DisplayPriNotifyMessage",
+  0x0121: "ClearPriNotifyMessage",
+  0x0122: "StartAnnouncementMessage",
+  0x0123: "StopAnnouncementMessage",
+  0x0124: "AnnouncementFinishMessage",
+  0x0127: "NotifyDtmfToneMessage",
+  0x0128: "SendDtmfToneMessage",
+  0x0129: "SubscribeDtmfPayloadReqMessage",
+  0x012A: "SubscribeDtmfPayloadResMessage",
+  0x012B: "SubscribeDtmfPayloadErrMessage",
+  0x012C: "UnSubscribeDtmfPayloadReqMessage",
+  0x012D: "UnSubscribeDtmfPayloadResMessage",
+  0x012E: "UnSubscribeDtmfPayloadErrMessage",
+  0x012F: "ServiceURLStatMessage",
+  0x0130: "CallSelectStatMessage",
+  0x0131: "OpenMultiMediaChannelMessage",
+  0x0132: "StartMultiMediaTransmission",
+  0x0133: "StopMultiMediaTransmission",
+  0x0134: "MiscellaneousCommandMessage",
+  0x0135: "FlowControlCommandMessage",
+  0x0136: "CloseMultiMediaReceiveChannel",
+  0x0137: "CreateConferenceReqMessage",
+  0x0138: "DeleteConferenceReqMessage",
+  0x0139: "ModifyConferenceReqMessage",
+  0x013A: "AddParticipantReqMessage",
+  0x013B: "DropParticipantReqMessage",
+  0x013C: "AuditConferenceReqMessage",
+  0x013D: "AuditParticipantReqMessage",
+  0x013F: "UserToDeviceDataVersion1Message",
+  }
+
+
+        
+class Skinny(Packet):
+    name="Skinny"
+    fields_desc = [ LEIntField("len",0),
+                    LEIntField("res",0),
+                    LEIntEnumField("msg",0,skinny_messages) ]
+
+bind_layers( TCP,           Skinny,        dport=2000)
+bind_layers( TCP,           Skinny,        sport=2000)
diff --git a/scapy/layers/smb.py b/scapy/layers/smb.py
new file mode 100644
index 0000000000000000000000000000000000000000..d999c360bb13e6d6e0769cc59484759404a42d6d
--- /dev/null
+++ b/scapy/layers/smb.py
@@ -0,0 +1,345 @@
+from scapy.packet import *
+from scapy.fields import *
+from scapy.layers.netbios import NBTSession
+
+
+# SMB NetLogon Response Header
+class SMBNetlogon_Protocol_Response_Header(Packet):
+    name="SMBNetlogon Protocol Response Header"
+    fields_desc = [StrFixedLenField("Start","\xffSMB",4),
+                   ByteEnumField("Command",0x25,{0x25:"Trans"}),
+                   ByteField("Error_Class",0x02),
+                   ByteField("Reserved",0),
+                   LEShortField("Error_code",4),
+                   ByteField("Flags",0),
+                   LEShortField("Flags2",0x0000),
+                   LEShortField("PIDHigh",0x0000),
+                   LELongField("Signature",0x0),
+                   LEShortField("Unused",0x0),
+                   LEShortField("TID",0),
+                   LEShortField("PID",0),
+                   LEShortField("UID",0),
+                   LEShortField("MID",0),
+                   ByteField("WordCount",17),
+                   LEShortField("TotalParamCount",0),
+                   LEShortField("TotalDataCount",112),
+                   LEShortField("MaxParamCount",0),
+                   LEShortField("MaxDataCount",0),
+                   ByteField("MaxSetupCount",0),
+                   ByteField("unused2",0),
+                   LEShortField("Flags3",0),
+                   ByteField("TimeOut1",0xe8),
+                   ByteField("TimeOut2",0x03),
+                   LEShortField("unused3",0),
+                   LEShortField("unused4",0),
+                   LEShortField("ParamCount2",0),
+                   LEShortField("ParamOffset",0),
+                   LEShortField("DataCount",112),
+                   LEShortField("DataOffset",92),
+                   ByteField("SetupCount", 3),
+                   ByteField("unused5", 0)]
+
+# SMB MailSlot Protocol
+class SMBMailSlot(Packet):
+    name = "SMB Mail Slot Protocol"
+    fields_desc = [LEShortField("opcode", 1),
+                   LEShortField("priority", 1),
+                   LEShortField("class", 2),
+                   LEShortField("size", 135),
+                   StrNullField("name","\MAILSLOT\NET\GETDC660")]
+
+# SMB NetLogon Protocol Response Tail SAM
+class SMBNetlogon_Protocol_Response_Tail_SAM(Packet):
+    name = "SMB Netlogon Protocol Response Tail SAM"
+    fields_desc = [ByteEnumField("Command", 0x17, {0x12:"SAM logon request", 0x17:"SAM Active directory Response"}),
+                   ByteField("unused", 0),
+                   ShortField("Data1", 0),
+                   ShortField("Data2", 0xfd01),
+                   ShortField("Data3", 0),
+                   ShortField("Data4", 0xacde),
+                   ShortField("Data5", 0x0fe5),
+                   ShortField("Data6", 0xd10a),
+                   ShortField("Data7", 0x374c),
+                   ShortField("Data8", 0x83e2),
+                   ShortField("Data9", 0x7dd9),
+                   ShortField("Data10", 0x3a16),
+                   ShortField("Data11", 0x73ff),
+                   ByteField("Data12", 0x04),
+                   StrFixedLenField("Data13", "rmff", 4),
+                   ByteField("Data14", 0x0),
+                   ShortField("Data16", 0xc018),
+                   ByteField("Data18", 0x0a),
+                   StrFixedLenField("Data20", "rmff-win2k", 10),
+                   ByteField("Data21", 0xc0),
+                   ShortField("Data22", 0x18c0),
+                   ShortField("Data23", 0x180a),
+                   StrFixedLenField("Data24", "RMFF-WIN2K", 10),
+                   ShortField("Data25", 0),
+                   ByteField("Data26", 0x17),
+                   StrFixedLenField("Data27", "Default-First-Site-Name", 23),
+                   ShortField("Data28", 0x00c0),
+                   ShortField("Data29", 0x3c10),
+                   ShortField("Data30", 0x00c0),
+                   ShortField("Data31", 0x0200),
+                   ShortField("Data32", 0x0),
+                   ShortField("Data33", 0xac14),
+                   ShortField("Data34", 0x0064),
+                   ShortField("Data35", 0x0),
+                   ShortField("Data36", 0x0),
+                   ShortField("Data37", 0x0),
+                   ShortField("Data38", 0x0),
+                   ShortField("Data39", 0x0d00),
+                   ShortField("Data40", 0x0),
+                   ShortField("Data41", 0xffff)]                   
+
+# SMB NetLogon Protocol Response Tail LM2.0
+class SMBNetlogon_Protocol_Response_Tail_LM20(Packet):
+    name = "SMB Netlogon Protocol Response Tail LM20"
+    fields_desc = [ByteEnumField("Command",0x06,{0x06:"LM 2.0 Response to logon request"}),
+                   ByteField("unused", 0),
+                   StrFixedLenField("DblSlash", "\\\\", 2),
+                   StrNullField("ServerName","WIN"),
+                   LEShortField("LM20Token", 0xffff)]
+
+# SMBNegociate Protocol Request Header
+class SMBNegociate_Protocol_Request_Header(Packet):
+    name="SMBNegociate Protocol Request Header"
+    fields_desc = [StrFixedLenField("Start","\xffSMB",4),
+                   ByteEnumField("Command",0x72,{0x72:"SMB_COM_NEGOTIATE"}),
+                   ByteField("Error_Class",0),
+                   ByteField("Reserved",0),
+                   LEShortField("Error_code",0),
+                   ByteField("Flags",0x18),
+                   LEShortField("Flags2",0x0000),
+                   LEShortField("PIDHigh",0x0000),
+                   LELongField("Signature",0x0),
+                   LEShortField("Unused",0x0),
+                   LEShortField("TID",0),
+                   LEShortField("PID",1),
+                   LEShortField("UID",0),
+                   LEShortField("MID",2),
+                   ByteField("WordCount",0),
+                   LEShortField("ByteCount",12)]
+
+# SMB Negociate Protocol Request Tail
+class SMBNegociate_Protocol_Request_Tail(Packet):
+    name="SMB Negociate Protocol Request Tail"
+    fields_desc=[ByteField("BufferFormat",0x02),
+                 StrNullField("BufferData","NT LM 0.12")]
+
+# SMBNegociate Protocol Response Advanced Security
+class SMBNegociate_Protocol_Response_Advanced_Security(Packet):
+    name="SMBNegociate Protocol Response Advanced Security"
+    fields_desc = [StrFixedLenField("Start","\xffSMB",4),
+                   ByteEnumField("Command",0x72,{0x72:"SMB_COM_NEGOTIATE"}),
+                   ByteField("Error_Class",0),
+                   ByteField("Reserved",0),
+                   LEShortField("Error_Code",0),
+                   ByteField("Flags",0x98),
+                   LEShortField("Flags2",0x0000),
+                   LEShortField("PIDHigh",0x0000),
+                   LELongField("Signature",0x0),
+                   LEShortField("Unused",0x0),
+                   LEShortField("TID",0),
+                   LEShortField("PID",1),
+                   LEShortField("UID",0),
+                   LEShortField("MID",2),
+                   ByteField("WordCount",17),
+                   LEShortField("DialectIndex",7),
+                   ByteField("SecurityMode",0x03),
+                   LEShortField("MaxMpxCount",50),
+                   LEShortField("MaxNumberVC",1),
+                   LEIntField("MaxBufferSize",16144),
+                   LEIntField("MaxRawSize",65536),
+                   LEIntField("SessionKey",0x0000),
+                   LEShortField("ServerCapabilities",0xf3f9),
+                   BitField("UnixExtensions",0,1),
+                   BitField("Reserved2",0,7),
+                   BitField("ExtendedSecurity",1,1),
+                   BitField("CompBulk",0,2),
+                   BitField("Reserved3",0,5),
+# There have been 127490112000000000 tenths of micro-seconds between 1st january 1601 and 1st january 2005. 127490112000000000=0x1C4EF94D6228000, so ServerTimeHigh=0xD6228000 and ServerTimeLow=0x1C4EF94.
+                   LEIntField("ServerTimeHigh",0xD6228000L),
+                   LEIntField("ServerTimeLow",0x1C4EF94),
+                   LEShortField("ServerTimeZone",0x3c),
+                   ByteField("EncryptionKeyLength",0),
+                   LEFieldLenField("ByteCount", None, "SecurityBlob", adjust=lambda pkt,x:x-16),
+                   BitField("GUID",0,128),
+                   StrLenField("SecurityBlob", "", length_from=lambda x:x.ByteCount+16)]
+
+# SMBNegociate Protocol Response No Security
+# When using no security, with EncryptionKeyLength=8, you must have an EncryptionKey before the DomainName
+class SMBNegociate_Protocol_Response_No_Security(Packet):
+    name="SMBNegociate Protocol Response No Security"
+    fields_desc = [StrFixedLenField("Start","\xffSMB",4),
+                   ByteEnumField("Command",0x72,{0x72:"SMB_COM_NEGOTIATE"}),
+                   ByteField("Error_Class",0),
+                   ByteField("Reserved",0),
+                   LEShortField("Error_Code",0),
+                   ByteField("Flags",0x98),
+                   LEShortField("Flags2",0x0000),
+                   LEShortField("PIDHigh",0x0000),
+                   LELongField("Signature",0x0),
+                   LEShortField("Unused",0x0),
+                   LEShortField("TID",0),
+                   LEShortField("PID",1),
+                   LEShortField("UID",0),
+                   LEShortField("MID",2),
+                   ByteField("WordCount",17),
+                   LEShortField("DialectIndex",7),
+                   ByteField("SecurityMode",0x03),
+                   LEShortField("MaxMpxCount",50),
+                   LEShortField("MaxNumberVC",1),
+                   LEIntField("MaxBufferSize",16144),
+                   LEIntField("MaxRawSize",65536),
+                   LEIntField("SessionKey",0x0000),
+                   LEShortField("ServerCapabilities",0xf3f9),
+                   BitField("UnixExtensions",0,1),
+                   BitField("Reserved2",0,7),
+                   BitField("ExtendedSecurity",0,1),
+                   FlagsField("CompBulk",0,2,"CB"),
+                   BitField("Reserved3",0,5),
+                   # There have been 127490112000000000 tenths of micro-seconds between 1st january 1601 and 1st january 2005. 127490112000000000=0x1C4EF94D6228000, so ServerTimeHigh=0xD6228000 and ServerTimeLow=0x1C4EF94.
+                   LEIntField("ServerTimeHigh",0xD6228000L),
+                   LEIntField("ServerTimeLow",0x1C4EF94),
+                   LEShortField("ServerTimeZone",0x3c),
+                   ByteField("EncryptionKeyLength",8),
+                   LEShortField("ByteCount",24),
+                   BitField("EncryptionKey",0,64),
+                   StrNullField("DomainName","WORKGROUP"),
+                   StrNullField("ServerName","RMFF1")]
+    
+# SMBNegociate Protocol Response No Security No Key
+class SMBNegociate_Protocol_Response_No_Security_No_Key(Packet):
+    namez="SMBNegociate Protocol Response No Security No Key"
+    fields_desc = [StrFixedLenField("Start","\xffSMB",4),
+                   ByteEnumField("Command",0x72,{0x72:"SMB_COM_NEGOTIATE"}),
+                   ByteField("Error_Class",0),
+                   ByteField("Reserved",0),
+                   LEShortField("Error_Code",0),
+                   ByteField("Flags",0x98),
+                   LEShortField("Flags2",0x0000),
+                   LEShortField("PIDHigh",0x0000),
+                   LELongField("Signature",0x0),
+                   LEShortField("Unused",0x0),
+                   LEShortField("TID",0),
+                   LEShortField("PID",1),
+                   LEShortField("UID",0),
+                   LEShortField("MID",2),
+                   ByteField("WordCount",17),
+                   LEShortField("DialectIndex",7),
+                   ByteField("SecurityMode",0x03),
+                   LEShortField("MaxMpxCount",50),
+                   LEShortField("MaxNumberVC",1),
+                   LEIntField("MaxBufferSize",16144),
+                   LEIntField("MaxRawSize",65536),
+                   LEIntField("SessionKey",0x0000),
+                   LEShortField("ServerCapabilities",0xf3f9),
+                   BitField("UnixExtensions",0,1),
+                   BitField("Reserved2",0,7),
+                   BitField("ExtendedSecurity",0,1),
+                   FlagsField("CompBulk",0,2,"CB"),
+                   BitField("Reserved3",0,5),
+                   # There have been 127490112000000000 tenths of micro-seconds between 1st january 1601 and 1st january 2005. 127490112000000000=0x1C4EF94D6228000, so ServerTimeHigh=0xD6228000 and ServerTimeLow=0x1C4EF94.
+                   LEIntField("ServerTimeHigh",0xD6228000L),
+                   LEIntField("ServerTimeLow",0x1C4EF94),
+                   LEShortField("ServerTimeZone",0x3c),
+                   ByteField("EncryptionKeyLength",0),
+                   LEShortField("ByteCount",16),
+                   StrNullField("DomainName","WORKGROUP"),
+                   StrNullField("ServerName","RMFF1")]
+    
+# Session Setup AndX Request
+class SMBSession_Setup_AndX_Request(Packet):
+    name="Session Setup AndX Request"
+    fields_desc=[StrFixedLenField("Start","\xffSMB",4),
+                ByteEnumField("Command",0x73,{0x73:"SMB_COM_SESSION_SETUP_ANDX"}),
+                 ByteField("Error_Class",0),
+                 ByteField("Reserved",0),
+                 LEShortField("Error_Code",0),
+                 ByteField("Flags",0x18),
+                 LEShortField("Flags2",0x0001),
+                 LEShortField("PIDHigh",0x0000),
+                 LELongField("Signature",0x0),
+                 LEShortField("Unused",0x0),
+                 LEShortField("TID",0),
+                 LEShortField("PID",1),
+                 LEShortField("UID",0),
+                 LEShortField("MID",2),
+                 ByteField("WordCount",13),
+                 ByteEnumField("AndXCommand",0x75,{0x75:"SMB_COM_TREE_CONNECT_ANDX"}),
+                 ByteField("Reserved2",0),
+                 LEShortField("AndXOffset",96),
+                 LEShortField("MaxBufferS",2920),
+                 LEShortField("MaxMPXCount",50),
+                 LEShortField("VCNumber",0),
+                 LEIntField("SessionKey",0),
+                 LEFieldLenField("ANSIPasswordLength",None,"ANSIPassword"),
+                 LEShortField("UnicodePasswordLength",0),
+                 LEIntField("Reserved3",0),
+                 LEShortField("ServerCapabilities",0x05),
+                 BitField("UnixExtensions",0,1),
+                 BitField("Reserved4",0,7),
+                 BitField("ExtendedSecurity",0,1),
+                 BitField("CompBulk",0,2),
+                 BitField("Reserved5",0,5),
+                 LEShortField("ByteCount",35),
+                 StrLenField("ANSIPassword", "Pass",length_from=lambda x:x.ANSIPasswordLength),
+                 StrNullField("Account","GUEST"),
+                 StrNullField("PrimaryDomain",  ""),
+                 StrNullField("NativeOS","Windows 4.0"),
+                 StrNullField("NativeLanManager","Windows 4.0"),
+                 ByteField("WordCount2",4),
+                 ByteEnumField("AndXCommand2",0xFF,{0xFF:"SMB_COM_NONE"}),
+                 ByteField("Reserved6",0),
+                 LEShortField("AndXOffset2",0),
+                 LEShortField("Flags3",0x2),
+                 LEShortField("PasswordLength",0x1),
+                 LEShortField("ByteCount2",18),
+                 ByteField("Password",0),
+                 StrNullField("Path","\\\\WIN2K\\IPC$"),
+                 StrNullField("Service","IPC")]
+
+# Session Setup AndX Response
+class SMBSession_Setup_AndX_Response(Packet):
+    name="Session Setup AndX Response"
+    fields_desc=[StrFixedLenField("Start","\xffSMB",4),
+                 ByteEnumField("Command",0x73,{0x73:"SMB_COM_SESSION_SETUP_ANDX"}),
+                 ByteField("Error_Class",0),
+                 ByteField("Reserved",0),
+                 LEShortField("Error_Code",0),
+                 ByteField("Flags",0x90),
+                 LEShortField("Flags2",0x1001),
+                 LEShortField("PIDHigh",0x0000),
+                 LELongField("Signature",0x0),
+                 LEShortField("Unused",0x0),
+                 LEShortField("TID",0),
+                 LEShortField("PID",1),
+                 LEShortField("UID",0),
+                 LEShortField("MID",2),
+                 ByteField("WordCount",3),
+                 ByteEnumField("AndXCommand",0x75,{0x75:"SMB_COM_TREE_CONNECT_ANDX"}),
+                 ByteField("Reserved2",0),
+                 LEShortField("AndXOffset",66),
+                 LEShortField("Action",0),
+                 LEShortField("ByteCount",25),
+                 StrNullField("NativeOS","Windows 4.0"),
+                 StrNullField("NativeLanManager","Windows 4.0"),
+                 StrNullField("PrimaryDomain",""),
+                 ByteField("WordCount2",3),
+                 ByteEnumField("AndXCommand2",0xFF,{0xFF:"SMB_COM_NONE"}),
+                 ByteField("Reserved3",0),
+                 LEShortField("AndXOffset2",80),
+                 LEShortField("OptionalSupport",0x01),
+                 LEShortField("ByteCount2",5),
+                 StrNullField("Service","IPC"),
+                 StrNullField("NativeFileSystem","")]
+
+bind_layers( NBTSession,                           SMBNegociate_Protocol_Request_Header, )
+bind_layers( NBTSession,    SMBNegociate_Protocol_Response_Advanced_Security,  ExtendedSecurity=1)
+bind_layers( NBTSession,    SMBNegociate_Protocol_Response_No_Security,        ExtendedSecurity=0, EncryptionKeyLength=8)
+bind_layers( NBTSession,    SMBNegociate_Protocol_Response_No_Security_No_Key, ExtendedSecurity=0, EncryptionKeyLength=0)
+bind_layers( NBTSession,    SMBSession_Setup_AndX_Request, )
+bind_layers( NBTSession,    SMBSession_Setup_AndX_Response, )
+bind_layers( SMBNegociate_Protocol_Request_Header, SMBNegociate_Protocol_Request_Tail, )
+bind_layers( SMBNegociate_Protocol_Request_Tail,   SMBNegociate_Protocol_Request_Tail, )
diff --git a/scapy/layers/snmp.py b/scapy/layers/snmp.py
new file mode 100644
index 0000000000000000000000000000000000000000..58559cd5d278b32d7861e6396d81f8b3df81645f
--- /dev/null
+++ b/scapy/layers/snmp.py
@@ -0,0 +1,244 @@
+from scapy.asn1packet import *
+from scapy.asn1fields import *
+from scapy.layers.inet import UDP
+
+##########
+## SNMP ##
+##########
+
+######[ ASN1 class ]######
+
+class ASN1_Class_SNMP(ASN1_Class_UNIVERSAL):
+    name="SNMP"
+    PDU_GET = 0xa0
+    PDU_NEXT = 0xa1
+    PDU_RESPONSE = 0xa2
+    PDU_SET = 0xa3
+    PDU_TRAPv1 = 0xa4
+    PDU_BULK = 0xa5
+    PDU_INFORM = 0xa6
+    PDU_TRAPv2 = 0xa7
+
+
+class ASN1_SNMP_PDU_GET(ASN1_SEQUENCE):
+    tag = ASN1_Class_SNMP.PDU_GET
+
+class ASN1_SNMP_PDU_NEXT(ASN1_SEQUENCE):
+    tag = ASN1_Class_SNMP.PDU_NEXT
+
+class ASN1_SNMP_PDU_RESPONSE(ASN1_SEQUENCE):
+    tag = ASN1_Class_SNMP.PDU_RESPONSE
+
+class ASN1_SNMP_PDU_SET(ASN1_SEQUENCE):
+    tag = ASN1_Class_SNMP.PDU_SET
+
+class ASN1_SNMP_PDU_TRAPv1(ASN1_SEQUENCE):
+    tag = ASN1_Class_SNMP.PDU_TRAPv1
+
+class ASN1_SNMP_PDU_BULK(ASN1_SEQUENCE):
+    tag = ASN1_Class_SNMP.PDU_BULK
+
+class ASN1_SNMP_PDU_INFORM(ASN1_SEQUENCE):
+    tag = ASN1_Class_SNMP.PDU_INFORM
+
+class ASN1_SNMP_PDU_TRAPv2(ASN1_SEQUENCE):
+    tag = ASN1_Class_SNMP.PDU_TRAPv2
+
+
+######[ BER codecs ]#######
+
+class BERcodec_SNMP_PDU_GET(BERcodec_SEQUENCE):
+    tag = ASN1_Class_SNMP.PDU_GET
+
+class BERcodec_SNMP_PDU_NEXT(BERcodec_SEQUENCE):
+    tag = ASN1_Class_SNMP.PDU_NEXT
+
+class BERcodec_SNMP_PDU_RESPONSE(BERcodec_SEQUENCE):
+    tag = ASN1_Class_SNMP.PDU_RESPONSE
+
+class BERcodec_SNMP_PDU_SET(BERcodec_SEQUENCE):
+    tag = ASN1_Class_SNMP.PDU_SET
+
+class BERcodec_SNMP_PDU_TRAPv1(BERcodec_SEQUENCE):
+    tag = ASN1_Class_SNMP.PDU_TRAPv1
+
+class BERcodec_SNMP_PDU_BULK(BERcodec_SEQUENCE):
+    tag = ASN1_Class_SNMP.PDU_BULK
+
+class BERcodec_SNMP_PDU_INFORM(BERcodec_SEQUENCE):
+    tag = ASN1_Class_SNMP.PDU_INFORM
+
+class BERcodec_SNMP_PDU_TRAPv2(BERcodec_SEQUENCE):
+    tag = ASN1_Class_SNMP.PDU_TRAPv2
+
+
+
+######[ ASN1 fields ]######
+
+class ASN1F_SNMP_PDU_GET(ASN1F_SEQUENCE):
+    ASN1_tag = ASN1_Class_SNMP.PDU_GET
+
+class ASN1F_SNMP_PDU_NEXT(ASN1F_SEQUENCE):
+    ASN1_tag = ASN1_Class_SNMP.PDU_NEXT
+
+class ASN1F_SNMP_PDU_RESPONSE(ASN1F_SEQUENCE):
+    ASN1_tag = ASN1_Class_SNMP.PDU_RESPONSE
+
+class ASN1F_SNMP_PDU_SET(ASN1F_SEQUENCE):
+    ASN1_tag = ASN1_Class_SNMP.PDU_SET
+
+class ASN1F_SNMP_PDU_TRAPv1(ASN1F_SEQUENCE):
+    ASN1_tag = ASN1_Class_SNMP.PDU_TRAPv1
+
+class ASN1F_SNMP_PDU_BULK(ASN1F_SEQUENCE):
+    ASN1_tag = ASN1_Class_SNMP.PDU_BULK
+
+class ASN1F_SNMP_PDU_INFORM(ASN1F_SEQUENCE):
+    ASN1_tag = ASN1_Class_SNMP.PDU_INFORM
+
+class ASN1F_SNMP_PDU_TRAPv2(ASN1F_SEQUENCE):
+    ASN1_tag = ASN1_Class_SNMP.PDU_TRAPv2
+
+
+
+######[ SNMP Packet ]######
+
+SNMP_error = { 0: "no_error",
+               1: "too_big",
+               2: "no_such_name",
+               3: "bad_value",
+               4: "read_only",
+               5: "generic_error",
+               6: "no_access",
+               7: "wrong_type",
+               8: "wrong_length",
+               9: "wrong_encoding",
+              10: "wrong_value",
+              11: "no_creation",
+              12: "inconsistent_value",
+              13: "ressource_unavailable",
+              14: "commit_failed",
+              15: "undo_failed",
+              16: "authorization_error",
+              17: "not_writable",
+              18: "inconsistent_name",
+               }
+
+SNMP_trap_types = { 0: "cold_start",
+                    1: "warm_start",
+                    2: "link_down",
+                    3: "link_up",
+                    4: "auth_failure",
+                    5: "egp_neigh_loss",
+                    6: "enterprise_specific",
+                    }
+
+class SNMPvarbind(ASN1_Packet):
+    ASN1_codec = ASN1_Codecs.BER
+    ASN1_root = ASN1F_SEQUENCE( ASN1F_OID("oid","1.3"),
+                                ASN1F_field("value",ASN1_NULL(0))
+                                )
+
+
+class SNMPget(ASN1_Packet):
+    ASN1_codec = ASN1_Codecs.BER
+    ASN1_root = ASN1F_SNMP_PDU_GET( ASN1F_INTEGER("id",0),
+                                    ASN1F_enum_INTEGER("error",0, SNMP_error),
+                                    ASN1F_INTEGER("error_index",0),
+                                    ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind)
+                                    )
+
+class SNMPnext(ASN1_Packet):
+    ASN1_codec = ASN1_Codecs.BER
+    ASN1_root = ASN1F_SNMP_PDU_NEXT( ASN1F_INTEGER("id",0),
+                                     ASN1F_enum_INTEGER("error",0, SNMP_error),
+                                     ASN1F_INTEGER("error_index",0),
+                                     ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind)
+                                     )
+
+class SNMPresponse(ASN1_Packet):
+    ASN1_codec = ASN1_Codecs.BER
+    ASN1_root = ASN1F_SNMP_PDU_RESPONSE( ASN1F_INTEGER("id",0),
+                                         ASN1F_enum_INTEGER("error",0, SNMP_error),
+                                         ASN1F_INTEGER("error_index",0),
+                                         ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind)
+                                         )
+
+class SNMPset(ASN1_Packet):
+    ASN1_codec = ASN1_Codecs.BER
+    ASN1_root = ASN1F_SNMP_PDU_SET( ASN1F_INTEGER("id",0),
+                                    ASN1F_enum_INTEGER("error",0, SNMP_error),
+                                    ASN1F_INTEGER("error_index",0),
+                                    ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind)
+                                    )
+    
+class SNMPtrapv1(ASN1_Packet):
+    ASN1_codec = ASN1_Codecs.BER
+    ASN1_root = ASN1F_SNMP_PDU_TRAPv1( ASN1F_INTEGER("id",0),
+                                       ASN1F_OID("enterprise", "1.3"),
+                                       ASN1F_STRING("agent_addr",""),
+                                       ASN1F_enum_INTEGER("generic_trap", 0, SNMP_trap_types),
+                                       ASN1F_INTEGER("specific_trap", 0),
+                                       ASN1F_INTEGER("time_stamp", IntAutoTime()),
+                                       ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind)
+                                       )
+
+class SNMPbulk(ASN1_Packet):
+    ASN1_codec = ASN1_Codecs.BER
+    ASN1_root = ASN1F_SNMP_PDU_BULK( ASN1F_INTEGER("id",0),
+                                     ASN1F_INTEGER("non_repeaters",0),
+                                     ASN1F_INTEGER("max_repetitions",0),
+                                     ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind)
+                                     )
+    
+class SNMPinform(ASN1_Packet):
+    ASN1_codec = ASN1_Codecs.BER
+    ASN1_root = ASN1F_SNMP_PDU_INFORM( ASN1F_INTEGER("id",0),
+                                       ASN1F_enum_INTEGER("error",0, SNMP_error),
+                                       ASN1F_INTEGER("error_index",0),
+                                       ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind)
+                                       )
+    
+class SNMPtrapv2(ASN1_Packet):
+    ASN1_codec = ASN1_Codecs.BER
+    ASN1_root = ASN1F_SNMP_PDU_TRAPv2( ASN1F_INTEGER("id",0),
+                                       ASN1F_enum_INTEGER("error",0, SNMP_error),
+                                       ASN1F_INTEGER("error_index",0),
+                                       ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind)
+                                       )
+    
+
+class SNMP(ASN1_Packet):
+    ASN1_codec = ASN1_Codecs.BER
+    ASN1_root = ASN1F_SEQUENCE(
+        ASN1F_enum_INTEGER("version", 1, {0:"v1", 1:"v2c", 2:"v2", 3:"v3"}),
+        ASN1F_STRING("community","public"),
+        ASN1F_CHOICE("PDU", SNMPget(),
+                     SNMPget, SNMPnext, SNMPresponse, SNMPset,
+                     SNMPtrapv1, SNMPbulk, SNMPinform, SNMPtrapv2)
+        )
+    def answers(self, other):
+        return ( isinstance(self.PDU, SNMPresponse)    and
+                 ( isinstance(other.PDU, SNMPget) or
+                   isinstance(other.PDU, SNMPnext) or
+                   isinstance(other.PDU, SNMPset)    ) and
+                 self.PDU.id == other.PDU.id )
+
+bind_layers( UDP,           SNMP,          sport=161)
+bind_layers( UDP,           SNMP,          dport=161)
+def snmpwalk(dst, oid="1", community="public"):
+    try:
+        while 1:
+            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)
+            if ICMP in r:
+                print repr(r)
+                break
+            if r is None:
+                print "No answers"
+                break
+            print "%-40s: %r" % (r[SNMPvarbind].oid.val,r[SNMPvarbind].value)
+            oid = r[SNMPvarbind].oid
+            
+    except KeyboardInterrupt:
+        pass
+
diff --git a/scapy/layers/tftp.py b/scapy/layers/tftp.py
new file mode 100644
index 0000000000000000000000000000000000000000..5b3c879916dc97f52e534e281135793afbd80c16
--- /dev/null
+++ b/scapy/layers/tftp.py
@@ -0,0 +1,468 @@
+import os,random
+from scapy.packet import *
+from scapy.fields import *
+from scapy.automaton import *
+from scapy.layers.inet import UDP
+
+
+
+TFTP_operations = { 1:"RRQ",2:"WRQ",3:"DATA",4:"ACK",5:"ERROR",6:"OACK" }
+
+
+class TFTP(Packet):
+    name = "TFTP opcode"
+    fields_desc = [ ShortEnumField("op", 1, TFTP_operations), ]
+    
+
+
+class TFTP_RRQ(Packet):
+    name = "TFTP Read Request"
+    fields_desc = [ StrNullField("filename", ""),
+                    StrNullField("mode", "octet") ]
+    def answers(self, other):
+        return 0
+    def mysummary(self):
+        return self.sprintf("RRQ %filename%"),[UDP]
+        
+
+class TFTP_WRQ(Packet):
+    name = "TFTP Write Request"
+    fields_desc = [ StrNullField("filename", ""),
+                    StrNullField("mode", "octet") ]
+    def answers(self, other):
+        return 0
+    def mysummary(self):
+        return self.sprintf("WRQ %filename%"),[UDP]
+
+class TFTP_DATA(Packet):
+    name = "TFTP Data"
+    fields_desc = [ ShortField("block", 0) ]
+    def answers(self, other):
+        return  self.block == 1 and isinstance(other, TFTP_RRQ)
+    def mysummary(self):
+        return self.sprintf("DATA %block%"),[UDP]
+
+class TFTP_Option(Packet):
+    fields_desc = [ StrNullField("oname",""),
+                    StrNullField("value","") ]
+    def extract_padding(self, pkt):
+        return "",pkt
+
+class TFTP_Options(Packet):
+    fields_desc = [ PacketListField("options", [], TFTP_Option, length_from=lambda x:None) ]
+
+    
+class TFTP_ACK(Packet):
+    name = "TFTP Ack"
+    fields_desc = [ ShortField("block", 0) ]
+    def answers(self, other):
+        if isinstance(other, TFTP_DATA):
+            return self.block == other.block
+        elif isinstance(other, TFTP_RRQ) or isinstance(other, TFTP_WRQ) or isinstance(other, TFTP_OACK):
+            return self.block == 0
+        return 0
+    def mysummary(self):
+        return self.sprintf("ACK %block%"),[UDP]
+
+TFTP_Error_Codes = {  0: "Not defined",
+                      1: "File not found",
+                      2: "Access violation",
+                      3: "Disk full or allocation exceeded",
+                      4: "Illegal TFTP operation",
+                      5: "Unknown transfer ID",
+                      6: "File already exists",
+                      7: "No such user",
+                      8: "Terminate transfer due to option negotiation",
+                      }
+    
+class TFTP_ERROR(Packet):
+    name = "TFTP Error"
+    fields_desc = [ ShortEnumField("errorcode", 0, TFTP_Error_Codes),
+                    StrNullField("errormsg", "")]
+    def answers(self, other):
+        return (isinstance(other, TFTP_DATA) or
+                isinstance(other, TFTP_RRQ) or
+                isinstance(other, TFTP_WRQ) or 
+                isinstance(other, TFTP_ACK))
+    def mysummary(self):
+        return self.sprintf("ERROR %errorcode%: %errormsg%"),[UDP]
+
+
+class TFTP_OACK(Packet):
+    name = "TFTP Option Ack"
+    fields_desc = [  ]
+    def answers(self, other):
+        return isinstance(other, TFTP_WRQ) or isinstance(other, TFTP_RRQ)
+
+
+bind_layers(UDP, TFTP, dport=69)
+bind_layers(TFTP, TFTP_RRQ, op=1)
+bind_layers(TFTP, TFTP_WRQ, op=2)
+bind_layers(TFTP, TFTP_DATA, op=3)
+bind_layers(TFTP, TFTP_ACK, op=4)
+bind_layers(TFTP, TFTP_ERROR, op=5)
+bind_layers(TFTP, TFTP_OACK, op=6)
+bind_layers(TFTP_RRQ, TFTP_Options)
+bind_layers(TFTP_WRQ, TFTP_Options)
+bind_layers(TFTP_OACK, TFTP_Options)
+    
+
+class TFTP_read(Automaton):
+    def parse_args(self, filename, server, sport = None, port=69, **kargs):
+        Automaton.parse_args(self, **kargs)
+        self.filename = filename
+        self.server = server
+        self.port = port
+        self.sport = sport
+
+
+    def master_filter(self, pkt):
+        return ( IP in pkt and pkt[IP].src == self.server and UDP in pkt
+                 and pkt[UDP].dport == self.my_tid
+                 and (self.server_tid is None or pkt[UDP].sport == self.server_tid) )
+        
+    # BEGIN
+    @ATMT.state(initial=1)
+    def BEGIN(self):
+        self.blocksize=512
+        self.my_tid = self.sport or RandShort()._fix()
+        bind_bottom_up(UDP, TFTP, dport=self.my_tid)
+        self.server_tid = None
+        self.res = ""
+
+        self.l3 = IP(dst=self.server)/UDP(sport=self.my_tid, dport=self.port)/TFTP()
+        self.last_packet = self.l3/TFTP_RRQ(filename=self.filename, mode="octet")
+        self.send(self.last_packet)
+        self.awaiting=1
+        
+        raise self.WAITING()
+        
+    # WAITING
+    @ATMT.state()
+    def WAITING(self):
+        pass
+
+
+    @ATMT.receive_condition(WAITING)
+    def receive_data(self, pkt):
+        if TFTP_DATA in pkt and pkt[TFTP_DATA].block == self.awaiting:
+            if self.server_tid is None:
+                self.server_tid = pkt[UDP].sport
+                self.l3[UDP].dport = self.server_tid
+            raise self.RECEIVING(pkt)
+
+    @ATMT.receive_condition(WAITING, prio=1)
+    def receive_error(self, pkt):
+        if TFTP_ERROR in pkt:
+            raise self.ERROR(pkt)
+    
+        
+    @ATMT.timeout(WAITING, 3)
+    def timeout_waiting(self):
+        raise self.WAITING()
+    @ATMT.action(timeout_waiting)
+    def retransmit_last_packet(self):
+        self.send(self.last_packet)
+
+    @ATMT.action(receive_data)
+#    @ATMT.action(receive_error)
+    def send_ack(self):
+        self.last_packet = self.l3 / TFTP_ACK(block = self.awaiting)
+        self.send(self.last_packet)
+    
+
+    # RECEIVED
+    @ATMT.state()
+    def RECEIVING(self, pkt):
+        if Raw in pkt:
+            recvd = pkt[Raw].load
+        else:
+            recvd = ""
+        self.res += recvd
+        self.awaiting += 1
+        if len(recvd) == self.blocksize:
+            raise self.WAITING()
+        raise self.END()
+
+    # ERROR
+    @ATMT.state(error=1)
+    def ERROR(self,pkt):
+        split_bottom_up(UDP, TFTP, dport=self.my_tid)
+        return pkt[TFTP_ERROR].summary()
+    
+    #END
+    @ATMT.state(final=1)
+    def END(self):
+        split_bottom_up(UDP, TFTP, dport=self.my_tid)
+        return self.res
+
+
+
+
+class TFTP_write(Automaton):
+    def parse_args(self, filename, data, server, sport=None, port=69,**kargs):
+        Automaton.parse_args(self, **kargs)
+        self.filename = filename
+        self.server = server
+        self.port = port
+        self.sport = sport
+        self.blocksize = 512
+        self.origdata = data
+
+    def master_filter(self, pkt):
+        return ( IP in pkt and pkt[IP].src == self.server and UDP in pkt
+                 and pkt[UDP].dport == self.my_tid
+                 and (self.server_tid is None or pkt[UDP].sport == self.server_tid) )
+        
+
+    # BEGIN
+    @ATMT.state(initial=1)
+    def BEGIN(self):
+        self.data = [ self.origdata[i*self.blocksize:(i+1)*self.blocksize]
+                      for i in range( len(self.origdata)/self.blocksize+1) ] 
+        self.my_tid = self.sport or RandShort()._fix()
+        bind_bottom_up(UDP, TFTP, dport=self.my_tid)
+        self.server_tid = None
+        
+        self.l3 = IP(dst=self.server)/UDP(sport=self.my_tid, dport=self.port)/TFTP()
+        self.last_packet = self.l3/TFTP_WRQ(filename=self.filename, mode="octet")
+        self.send(self.last_packet)
+        self.res = ""
+        self.awaiting=0
+
+        raise self.WAITING_ACK()
+        
+    # WAITING_ACK
+    @ATMT.state()
+    def WAITING_ACK(self):
+        pass
+
+    @ATMT.receive_condition(WAITING_ACK)    
+    def received_ack(self,pkt):
+        if TFTP_ACK in pkt and pkt[TFTP_ACK].block == self.awaiting:
+            if self.server_tid is None:
+                self.server_tid = pkt[UDP].sport
+                self.l3[UDP].dport = self.server_tid
+            raise self.SEND_DATA()
+
+    @ATMT.receive_condition(WAITING_ACK)
+    def received_error(self, pkt):
+        if TFTP_ERROR in pkt:
+            raise self.ERROR(pkt)
+
+    @ATMT.timeout(WAITING_ACK, 3)
+    def timeout_waiting(self):
+        raise self.WAITING_ACK()
+    @ATMT.action(timeout_waiting)
+    def retransmit_last_packet(self):
+        self.send(self.last_packet)
+    
+    # SEND_DATA
+    @ATMT.state()
+    def SEND_DATA(self):
+        self.awaiting += 1
+        self.last_packet = self.l3/TFTP_DATA(block=self.awaiting)/self.data.pop(0)
+        self.send(self.last_packet)
+        if self.data:
+            raise self.WAITING_ACK()
+        raise self.END()
+    
+
+    # ERROR
+    @ATMT.state(error=1)
+    def ERROR(self,pkt):
+        split_bottom_up(UDP, TFTP, dport=self.my_tid)
+        return pkt[TFTP_ERROR].summary()
+
+    # END
+    @ATMT.state(final=1)
+    def END(self):
+        split_bottom_up(UDP, TFTP, dport=self.my_tid)
+
+
+class TFTP_WRQ_server(Automaton):
+
+    def parse_args(self, ip=None, sport=None, *args, **kargs):
+        Automaton.parse_args(self, *args, **kargs)
+        self.ip = ip
+        self.sport = sport
+
+    def master_filter(self, pkt):
+        return TFTP in pkt and (not self.ip or pkt[IP].dst == self.ip)
+
+    @ATMT.state(initial=1)
+    def BEGIN(self):
+        self.blksize=512
+        self.blk=1
+        self.filedata=""
+        self.my_tid = self.sport or random.randint(10000,65500)
+        bind_bottom_up(UDP, TFTP, dport=self.my_tid)
+
+    @ATMT.receive_condition(BEGIN)
+    def receive_WRQ(self,pkt):
+        if TFTP_WRQ in pkt:
+            raise self.WAIT_DATA().action_parameters(pkt)
+        
+    @ATMT.action(receive_WRQ)
+    def ack_WRQ(self, pkt):
+        ip = pkt[IP]
+        self.ip = ip.dst
+        self.dst = ip.src
+        self.filename = pkt[TFTP_WRQ].filename
+        options = pkt[TFTP_Options]
+        self.l3 = IP(src=ip.dst, dst=ip.src)/UDP(sport=self.my_tid, dport=pkt.sport)/TFTP()
+        if options is None:
+            self.last_packet = self.l3/TFTP_ACK(block=0)
+            self.send(self.last_packet)
+        else:
+            opt = [x for x in options.options if x.oname.upper() == "BLKSIZE"]
+            if opt:
+                self.blksize = int(opt[0].value)
+                self.debug(2,"Negotiated new blksize at %i" % self.blksize)
+            self.last_packet = self.l3/TFTP_OACK()/TFTP_Options(options=opt)
+            self.send(self.last_packet)
+
+    @ATMT.state()
+    def WAIT_DATA(self):
+        pass
+
+    @ATMT.timeout(WAIT_DATA, 1)
+    def resend_ack(self):
+        self.send(self.last_packet)
+        raise self.WAIT_DATA()
+        
+    @ATMT.receive_condition(WAIT_DATA)
+    def receive_data(self, pkt):
+        if TFTP_DATA in pkt:
+            data = pkt[TFTP_DATA]
+            if data.block == self.blk:
+                raise self.DATA(data)
+
+    @ATMT.action(receive_data)
+    def ack_data(self):
+        self.last_packet = self.l3/TFTP_ACK(block = self.blk)
+        self.send(self.last_packet)
+
+    @ATMT.state()
+    def DATA(self, data):
+        self.filedata += data.load
+        if len(data.load) < self.blksize:
+            raise self.END()
+        self.blk += 1
+        raise self.WAIT_DATA()
+
+    @ATMT.state(final=1)
+    def END(self):
+        return self.filename,self.filedata
+        split_bottom_up(UDP, TFTP, dport=self.my_tid)
+        
+
+class TFTP_RRQ_server(Automaton):
+    def parse_args(self, store=None, joker=None, dir=None, ip=None, sport=None, serve_one=False, **kargs):
+        Automaton.parse_args(self,**kargs)
+        if store is None:
+            store = {}
+        if dir is not None:
+            self.dir = os.path.join(os.path.abspath(dir),"")
+        else:
+            self.dir = None
+        self.store = store
+        self.joker = joker
+        self.ip = ip
+        self.sport = sport
+        self.serve_one = serve_one
+        self.my_tid = self.sport or random.randint(10000,65500)
+        bind_bottom_up(UDP, TFTP, dport=self.my_tid)
+        
+    def master_filter(self, pkt):
+        return TFTP in pkt and (not self.ip or pkt[IP].dst == self.ip)
+
+    @ATMT.state(initial=1)
+    def WAIT_RRQ(self):
+        self.blksize=512
+        self.blk=0
+
+    @ATMT.receive_condition(WAIT_RRQ)
+    def receive_rrq(self, pkt):
+        if TFTP_RRQ in pkt:
+            raise self.RECEIVED_RRQ(pkt)
+
+
+    @ATMT.state()
+    def RECEIVED_RRQ(self, pkt):
+        ip = pkt[IP]
+        options = pkt[TFTP_Options]
+        self.l3 = IP(src=ip.dst, dst=ip.src)/UDP(sport=self.my_tid, dport=ip.sport)/TFTP()
+        self.filename = pkt[TFTP_RRQ].filename
+        self.blk=1
+        self.data = None
+        if self.filename in self.store:
+            self.data = self.store[self.filename]
+        elif self.dir is not None:
+            fn = os.path.abspath(os.path.join(self.dir, self.filename))
+            if fn.startswith(self.dir): # Check we're still in the server's directory
+                try:
+                    self.data=open(fn).read()
+                except IOError:
+                    pass
+        if self.data is None:
+            self.data = self.joker
+
+        if options:
+            opt = [x for x in options.options if x.oname.upper() == "BLKSIZE"]
+            if opt:
+                self.blksize = int(opt[0].value)
+                self.debug(2,"Negotiated new blksize at %i" % self.blksize)
+            self.last_packet = self.l3/TFTP_OACK()/TFTP_Options(options=opt)
+            self.send(self.last_packet)
+                
+
+            
+
+    @ATMT.condition(RECEIVED_RRQ)
+    def file_in_store(self):
+        if self.data is not None:
+            self.blknb = len(self.data)/self.blksize+1
+            raise self.SEND_FILE()
+
+    @ATMT.condition(RECEIVED_RRQ)
+    def file_not_found(self):
+        if self.data is None:
+            raise self.WAIT_RRQ()
+    @ATMT.action(file_not_found)
+    def send_error(self):
+        self.send(self.l3/TFTP_ERROR(errorcode=1, errormsg=TFTP_Error_Codes[1]))
+
+    @ATMT.state()
+    def SEND_FILE(self):
+        self.send(self.l3/TFTP_DATA(block=self.blk)/self.data[(self.blk-1)*self.blksize:self.blk*self.blksize])
+        
+    @ATMT.timeout(SEND_FILE, 3)
+    def timeout_waiting_ack(self):
+        raise self.SEND_FILE()
+            
+    @ATMT.receive_condition(SEND_FILE)
+    def received_ack(self, pkt):
+        if TFTP_ACK in pkt and pkt[TFTP_ACK].block == self.blk:
+            raise self.RECEIVED_ACK()
+    @ATMT.state()
+    def RECEIVED_ACK(self):
+        self.blk += 1
+
+    @ATMT.condition(RECEIVED_ACK)
+    def no_more_data(self):
+        if self.blk > self.blknb:
+            if self.serve_one:
+                raise self.END()
+            raise self.WAIT_RRQ()
+    @ATMT.condition(RECEIVED_ACK, prio=2)
+    def data_remaining(self):
+        raise self.SEND_FILE()
+
+    @ATMT.state(final=1)
+    def END(self):
+        split_bottom_up(UDP, TFTP, dport=self.my_tid)
+    
+
+        
+
diff --git a/scapy/layers/x509.py b/scapy/layers/x509.py
new file mode 100644
index 0000000000000000000000000000000000000000..4c3e8182d9e4d2d60f05e83fc6cab83f45182b45
--- /dev/null
+++ b/scapy/layers/x509.py
@@ -0,0 +1,99 @@
+from scapy.asn1packet import *
+from scapy.asn1fields import *
+
+##########
+## X509 ##
+##########
+
+######[ ASN1 class ]######
+
+class ASN1_Class_X509(ASN1_Class_UNIVERSAL):
+    name="X509"
+    CONT0 = 0xa0
+    CONT1 = 0xa1
+    CONT2 = 0xa2
+    CONT3 = 0xa3
+
+class ASN1_X509_CONT0(ASN1_SEQUENCE):
+    tag = ASN1_Class_X509.CONT0
+
+class ASN1_X509_CONT1(ASN1_SEQUENCE):
+    tag = ASN1_Class_X509.CONT1
+
+class ASN1_X509_CONT2(ASN1_SEQUENCE):
+    tag = ASN1_Class_X509.CONT2
+
+class ASN1_X509_CONT3(ASN1_SEQUENCE):
+    tag = ASN1_Class_X509.CONT3
+
+######[ BER codecs ]#######
+
+class BERcodec_X509_CONT0(BERcodec_SEQUENCE):
+    tag = ASN1_Class_X509.CONT0
+
+class BERcodec_X509_CONT1(BERcodec_SEQUENCE):
+    tag = ASN1_Class_X509.CONT1
+    
+class BERcodec_X509_CONT2(BERcodec_SEQUENCE):
+    tag = ASN1_Class_X509.CONT2
+    
+class BERcodec_X509_CONT3(BERcodec_SEQUENCE):
+    tag = ASN1_Class_X509.CONT3
+
+######[ ASN1 fields ]######
+
+class ASN1F_X509_CONT0(ASN1F_SEQUENCE):
+    ASN1_tag = ASN1_Class_X509.CONT0
+    
+class ASN1F_X509_CONT1(ASN1F_SEQUENCE):
+    ASN1_tag = ASN1_Class_X509.CONT1
+    
+class ASN1F_X509_CONT2(ASN1F_SEQUENCE):
+    ASN1_tag = ASN1_Class_X509.CONT2
+    
+class ASN1F_X509_CONT3(ASN1F_SEQUENCE):
+    ASN1_tag = ASN1_Class_X509.CONT3
+
+######[ X509 packets ]######
+
+class X509RDN(ASN1_Packet):
+    ASN1_codec = ASN1_Codecs.BER
+    ASN1_root = ASN1F_SET(
+                  ASN1F_SEQUENCE( ASN1F_OID("oid","2.5.4.6"),
+                                  ASN1F_PRINTABLE_STRING("value","")
+                                  )
+                  )
+
+class X509v3Ext(ASN1_Packet):
+    ASN1_codec = ASN1_Codecs.BER
+    ASN1_root = ASN1F_field("val",ASN1_NULL(0))
+    
+
+class X509Cert(ASN1_Packet):
+    ASN1_codec = ASN1_Codecs.BER
+    ASN1_root = ASN1F_SEQUENCE(
+        ASN1F_SEQUENCE(
+            ASN1F_optionnal(ASN1F_X509_CONT0(ASN1F_INTEGER("version",3))),
+            ASN1F_INTEGER("sn",1),
+            ASN1F_SEQUENCE(ASN1F_OID("sign_algo","1.2.840.113549.1.1.5"),
+                           ASN1F_field("sa_value",ASN1_NULL(0))),
+            ASN1F_SEQUENCE_OF("issuer",[],X509RDN),
+            ASN1F_SEQUENCE(ASN1F_UTC_TIME("not_before",ZuluTime(-600)),  # ten minutes ago
+                           ASN1F_UTC_TIME("not_after",ZuluTime(+86400))), # for 24h
+            ASN1F_SEQUENCE_OF("subject",[],X509RDN),
+            ASN1F_SEQUENCE(
+                ASN1F_SEQUENCE(ASN1F_OID("pubkey_algo","1.2.840.113549.1.1.1"),
+                               ASN1F_field("pk_value",ASN1_NULL(0))),
+                ASN1F_BIT_STRING("pubkey","")
+                ),
+            ASN1F_optionnal(ASN1F_X509_CONT3(ASN1F_SEQUENCE_OF("x509v3ext",[],X509v3Ext))),
+            
+        ),
+        ASN1F_SEQUENCE(ASN1F_OID("sign_algo2","1.2.840.113549.1.1.5"),
+                       ASN1F_field("sa2_value",ASN1_NULL(0))),
+        ASN1F_BIT_STRING("signature","")
+        )
+
+
+
+
diff --git a/scapy/main.py b/scapy/main.py
new file mode 100644
index 0000000000000000000000000000000000000000..86de2d2c979f37de93b92c8028bb9f5fa3387ee7
--- /dev/null
+++ b/scapy/main.py
@@ -0,0 +1,265 @@
+
+from __future__ import generators
+import os,sys
+
+VERSION = "1.2.0.2"
+
+DEFAULT_CONFIG_FILE = os.path.join(os.environ["HOME"], ".scapy_startup.py")
+
+try:
+    os.stat(DEFAULT_CONFIG_FILE)
+except OSError:
+    DEFAULT_CONFIG_FILE = None
+
+def usage():
+    print """Usage: scapy.py [-s sessionfile] [-c new_startup_file] [-C]
+    -C: do not read startup file"""
+    sys.exit(0)
+
+
+from config import conf
+from themes import ColorPrompt
+
+
+######################
+## Extension system ##
+######################
+
+
+def load_extension(filename):
+    import imp
+    paths = conf.extensions_paths
+    if type(paths) is not list:
+        paths = [paths]
+
+    name = os.path.realpath(os.path.expanduser(filename))
+    thepath = os.path.dirname(name)
+    thename = os.path.basename(name)
+    if thename.endswith(".py"):
+        thename = thename[:-3]
+
+    paths.insert(0, thepath)
+    cwd=syspath=None
+    try:
+        cwd = os.getcwd()
+        os.chdir(thepath)
+        syspath = sys.path[:]
+        sys.path += paths
+        try:
+            extf = imp.find_module(thename, paths)
+        except ImportError:
+            log_runtime.error("Module [%s] not found. Check conf.extensions_paths ?" % filename)
+        else:
+            ext = imp.load_module(thename, *extf)
+            import __builtin__
+            __builtin__.__dict__.update(ext.__dict__)
+    finally:
+        if syspath:
+            sys.path=syspath
+        if cwd:
+            os.chdir(cwd)
+    
+
+################
+##### Main #####
+################
+
+def scapy_write_history_file(readline):
+    if conf.histfile:
+        try:
+            readline.write_history_file(conf.histfile)
+        except IOError,e:
+            try:
+                warning("Could not write history to [%s]\n\t (%s)" % (conf.histfile,e))
+                tmp = os.tempnam("","scapy")
+                readline.write_history_file(tmp)
+                warning("Wrote history to [%s]" % tmp)
+            except:
+                warning("Cound not write history to [%s]. Discarded" % tmp)
+
+
+def interact(mydict=None,argv=None,mybanner=None,loglevel=1):
+    global session
+    import code,sys,cPickle,types,os,imp,getopt,logging,re
+
+    logging.getLogger("scapy").setLevel(loglevel)
+
+    the_banner = "Welcome to Scapy (%s)"
+    if mybanner is not None:
+        the_banner += "\n"
+        the_banner += mybanner
+
+    if argv is None:
+        argv = sys.argv
+
+#    scapy_module = argv[0][argv[0].rfind("/")+1:]
+#    if not scapy_module:
+#        scapy_module = "scapy"
+#    else:
+#        if scapy_module.endswith(".py"):
+#            scapy_module = scapy_module[:-3]
+#
+#    scapy=imp.load_module("scapy",*imp.find_module(scapy_module))
+    
+    
+#    __builtin__.__dict__.update(scapy.__dict__)
+    import __builtin__
+    scapy_builtins = {}
+    for m in [ "ansmachine","arch","automaton","autorun","config","dadict","data","error","fields","main",
+               "mib","packet","plist","route","sendrecv","supersocket","themes","utils","volatile","asn1","asn1f" ]:
+        mod = __import__("scapy."+m,globals(),locals(),".")
+        scapy_builtins.update(mod.__dict__)
+    for m in ["l2","inet","dot11","dhcp","dns","ip6","isakmp","l2tp","mgcp","netbios","ntp","ppp","radius","rip",
+              "skinny","smb","rtp","tftp","snmp","x509" ]: # "ir","bluetooth","hsrp","gprs"
+        mod = __import__("scapy.layers."+m,globals(),locals(),".")
+        scapy_builtins.update(mod.__dict__)
+    __builtin__.__dict__.update(scapy_builtins)
+    globkeys = scapy_builtins.keys()
+    globkeys.append("scapy_session")
+    scapy_builtins=None # XXX replace with "with" statement
+    if mydict is not None:
+        __builtin__.__dict__.update(mydict)
+        globkeys += mydict.keys()
+    
+    import re, atexit
+    try:
+        import rlcompleter,readline
+    except ImportError:
+        log_loading.info("Can't load Python libreadline or completer")
+        READLINE=0
+    else:
+        READLINE=1
+        class ScapyCompleter(rlcompleter.Completer):
+            def global_matches(self, text):
+                matches = []
+                n = len(text)
+                for lst in [dir(__builtin__), session.keys()]:
+                    for word in lst:
+                        if word[:n] == text and word != "__builtins__":
+                            matches.append(word)
+                return matches
+        
+    
+            def attr_matches(self, text):
+                m = re.match(r"(\w+(\.\w+)*)\.(\w*)", text)
+                if not m:
+                    return
+                expr, attr = m.group(1, 3)
+                try:
+                    object = eval(expr)
+                except:
+                    object = eval(expr, session)
+                if isinstance(object, Packet) or isinstance(object, Packet_metaclass):
+                    words = filter(lambda x: x[0]!="_",dir(object))
+                    words += [x.name for x in object.fields_desc]
+                else:
+                    words = dir(object)
+                    if hasattr( object,"__class__" ):
+                        words = words + rlcompleter.get_class_members(object.__class__)
+                matches = []
+                n = len(attr)
+                for word in words:
+                    if word[:n] == attr and word != "__builtins__":
+                        matches.append("%s.%s" % (expr, word))
+                return matches
+    
+        readline.set_completer(ScapyCompleter().complete)
+        readline.parse_and_bind("C-o: operate-and-get-next")
+        readline.parse_and_bind("tab: complete")
+    
+    
+    session=None
+    session_name=""
+    CONFIG_FILE = DEFAULT_CONFIG_FILE
+
+    iface = None
+    try:
+        opts=getopt.getopt(argv[1:], "hs:Cc:")
+        for opt, parm in opts[0]:
+            if opt == "-h":
+                usage()
+            elif opt == "-s":
+                session_name = parm
+            elif opt == "-c":
+                CONFIG_FILE = parm
+            elif opt == "-C":
+                CONFIG_FILE = None
+        
+        if len(opts[1]) > 0:
+            raise getopt.GetoptError("Too many parameters : [%s]" % " ".join(opts[1]))
+
+
+    except getopt.GetoptError, msg:
+        log_loading.error(msg)
+        sys.exit(1)
+
+
+    if CONFIG_FILE:
+        read_config_file(CONFIG_FILE)
+        
+    if session_name:
+        try:
+            os.stat(session_name)
+        except OSError:
+            log_loading.info("New session [%s]" % session_name)
+        else:
+            try:
+                try:
+                    session = cPickle.load(gzip.open(session_name,"rb"))
+                except IOError:
+                    session = cPickle.load(open(session_name,"rb"))
+                log_loading.info("Using session [%s]" % session_name)
+            except EOFError:
+                log_loading.error("Error opening session [%s]" % session_name)
+            except AttributeError:
+                log_loading.error("Error opening session [%s]. Attribute missing" %  session_name)
+
+        if session:
+            if "conf" in session:
+                conf.configure(session["conf"])
+                session["conf"] = conf
+        else:
+            conf.session = session_name
+            session={"conf":conf}
+            
+    else:
+        session={"conf": conf}
+
+    __builtin__.__dict__["scapy_session"] = session
+
+
+    if READLINE:
+        if conf.histfile:
+            try:
+                readline.read_history_file(conf.histfile)
+            except IOError:
+                pass
+        atexit.register(scapy_write_history_file,readline)
+    
+    sys.ps1 = ColorPrompt()
+    code.interact(banner = the_banner % (VERSION), local=session)
+
+    if conf.session:
+        save_session(conf.session, session)
+
+
+    for k in globkeys:
+        try:
+            del(__builtin__.__dict__[k])
+        except:
+            pass
+
+def read_config_file(configfile):
+    try:
+        execfile(configfile)
+    except IOError,e:
+        log_loading.warning("Cannot read config file [%s] [%s]" % (configfile,e))
+    except Exception,e:
+        log_loading.exception("Error during evaluation of config file [%s]" % configfile)
+        
+
+if __name__ == "__main__":
+    interact()
+else:
+    if DEFAULT_CONFIG_FILE:
+        read_config_file(DEFAULT_CONFIG_FILE)
diff --git a/scapy/mib.py b/scapy/mib.py
new file mode 100644
index 0000000000000000000000000000000000000000..3e5d7d733171eec7199a2ce1ec0c587ddcd0e815
--- /dev/null
+++ b/scapy/mib.py
@@ -0,0 +1,134 @@
+import re
+from glob import glob
+from dadict import DADict
+from config import conf
+
+#################
+## MIB parsing ##
+#################
+
+_mib_re_integer = re.compile("^[0-9]+$")
+_mib_re_both = re.compile("^([a-zA-Z_][a-zA-Z0-9_-]*)\(([0-9]+)\)$")
+_mib_re_oiddecl = re.compile("$\s*([a-zA-Z0-9_-]+)\s+OBJECT[^:]+::=\s*\{([^\}]+)\}",re.M)
+_mib_re_strings = re.compile('"[^"]*"')
+_mib_re_comments = re.compile('--.*(\r|\n)')
+
+class MIBDict(DADict):
+    def _findroot(self, x):
+        if x.startswith("."):
+            x = x[1:]
+        if not x.endswith("."):
+            x += "."
+        max=0
+        root="."
+        for k in self.keys():
+            if x.startswith(self[k]+"."):
+                if max < len(self[k]):
+                    max = len(self[k])
+                    root = k
+        return root, x[max:-1]
+    def _oidname(self, x):
+        root,remainder = self._findroot(x)
+        return root+remainder
+    def _oid(self, x):
+        xl = x.strip(".").split(".")
+        p = len(xl)-1
+        while p >= 0 and _mib_re_integer.match(xl[p]):
+            p -= 1
+        if p != 0 or xl[p] not in self:
+            return x
+        xl[p] = self[xl[p]] 
+        return ".".join(xl[p:])
+    def _make_graph(self, other_keys=[], **kargs):
+        nodes = [(k,self[k]) for k in self.keys()]
+        oids = [self[k] for k in self.keys()]
+        for k in other_keys:
+            if k not in oids:
+                nodes.append(self.oidname(k),k)
+        s = 'digraph "mib" {\n\trankdir=LR;\n\n'
+        for k,o in nodes:
+            s += '\t"%s" [ label="%s"  ];\n' % (o,k)
+        s += "\n"
+        for k,o in nodes:
+            parent,remainder = self._findroot(o[:-1])
+            remainder = remainder[1:]+o[-1]
+            if parent != ".":
+                parent = self[parent]
+            s += '\t"%s" -> "%s" [label="%s"];\n' % (parent, o,remainder)
+        s += "}\n"
+        do_graph(s, **kargs)
+
+
+def mib_register(ident, value, the_mib, unresolved):
+    if ident in the_mib or ident in unresolved:
+        return ident in the_mib
+    resval = []
+    not_resolved = 0
+    for v in value:
+        if _mib_re_integer.match(v):
+            resval.append(v)
+        else:
+            v = fixname(v)
+            if v not in the_mib:
+                not_resolved = 1
+            if v in the_mib:
+                v = the_mib[v]
+            elif v in unresolved:
+                v = unresolved[v]
+            if type(v) is list:
+                resval += v
+            else:
+                resval.append(v)
+    if not_resolved:
+        unresolved[ident] = resval
+        return False
+    else:
+        the_mib[ident] = resval
+        keys = unresolved.keys()
+        i = 0
+        while i < len(keys):
+            k = keys[i]
+            if mib_register(k,unresolved[k], the_mib, {}):
+                del(unresolved[k])
+                del(keys[i])
+                i = 0
+            else:
+                i += 1
+                    
+        return True
+
+
+def load_mib(filenames):
+    the_mib = {'iso': ['1']}
+    unresolved = {}
+    for k in conf.mib.keys():
+        mib_register(k, conf.mib[k].split("."), the_mib, unresolved)
+
+    if type(filenames) is str:
+        filenames = [filenames]
+    for fnames in filenames:
+        for fname in glob(fnames):
+            f = open(fname)
+            text = f.read()
+            cleantext = " ".join(_mib_re_strings.split(" ".join(_mib_re_comments.split(text))))
+            for m in _mib_re_oiddecl.finditer(cleantext):
+                ident,oid = m.groups()
+                ident=fixname(ident)
+                oid = oid.split()
+                for i in range(len(oid)):
+                    m = _mib_re_both.match(oid[i])
+                    if m:
+                        oid[i] = m.groups()[1]
+                mib_register(ident, oid, the_mib, unresolved)
+
+    newmib = MIBDict(_name="MIB")
+    for k,o in the_mib.iteritems():
+        newmib[k]=".".join(o)
+    for k,o in unresolved.iteritems():
+        newmib[k]=".".join(o)
+
+    conf.mib=newmib
+
+
+
+conf.mib = MIBDict(_name="MIB")
diff --git a/scapy/nmap.py b/scapy/nmap.py
new file mode 100644
index 0000000000000000000000000000000000000000..5b4911931ee0adbf37ebea6a7cf2e372a3bc01f7
--- /dev/null
+++ b/scapy/nmap.py
@@ -0,0 +1,195 @@
+from scapy.data import KnowledgeBase
+from scapy.config import conf
+
+######################
+## nmap OS fp stuff ##
+######################
+
+
+class NmapKnowledgeBase(KnowledgeBase):
+    def lazy_init(self):
+        try:
+            f=open(self.filename)
+        except IOError:
+            return
+
+        self.base = []
+        name = None
+        try:
+            for l in f:
+                l = l.strip()
+                if not l or l[0] == "#":
+                    continue
+                if l[:12] == "Fingerprint ":
+                    if name is not None:
+                        self.base.append((name,sig))
+                    name = l[12:].strip()
+                    sig={}
+                    p = self.base
+                    continue
+                elif l[:6] == "Class ":
+                    continue
+                op = l.find("(")
+                cl = l.find(")")
+                if op < 0 or cl < 0:
+                    warning("error reading nmap os fp base file")
+                    continue
+                test = l[:op]
+                s = map(lambda x: x.split("="), l[op+1:cl].split("%"))
+                si = {}
+                for n,v in s:
+                    si[n] = v
+                sig[test]=si
+            if name is not None:
+                self.base.append((name,sig))
+        except:
+            self.base = None
+            warning("Can't read nmap database [%s](new nmap version ?)" % self.filename)
+        f.close()
+
+nmap_kdb = NmapKnowledgeBase(conf.nmap_base)
+
+def TCPflags2str(f):
+    fl="FSRPAUEC"
+    s=""
+    for i in range(len(fl)):
+        if f & 1:
+            s = fl[i]+s
+        f >>= 1
+    return s
+
+def nmap_tcppacket_sig(pkt):
+    r = {}
+    if pkt is not None:
+#        r["Resp"] = "Y"
+        r["DF"] = (pkt.flags & 2) and "Y" or "N"
+        r["W"] = "%X" % pkt.window
+        r["ACK"] = pkt.ack==2 and "S++" or pkt.ack==1 and "S" or "O"
+        r["Flags"] = TCPflags2str(pkt.payload.flags)
+        r["Ops"] = "".join(map(lambda x: x[0][0],pkt.payload.options))
+    else:
+        r["Resp"] = "N"
+    return r
+
+
+def nmap_udppacket_sig(S,T):
+    r={}
+    if T is None:
+        r["Resp"] = "N"
+    else:
+        r["DF"] = (T.flags & 2) and "Y" or "N"
+        r["TOS"] = "%X" % T.tos
+        r["IPLEN"] = "%X" % T.len
+        r["RIPTL"] = "%X" % T.payload.payload.len
+        r["RID"] = S.id == T.payload.payload.id and "E" or "F"
+        r["RIPCK"] = S.chksum == T.getlayer(IPerror).chksum and "E" or T.getlayer(IPerror).chksum == 0 and "0" or "F"
+        r["UCK"] = S.payload.chksum == T.getlayer(UDPerror).chksum and "E" or T.getlayer(UDPerror).chksum ==0 and "0" or "F"
+        r["ULEN"] = "%X" % T.getlayer(UDPerror).len
+        r["DAT"] = T.getlayer(Raw) is None and "E" or S.getlayer(Raw).load == T.getlayer(Raw).load and "E" or "F"
+    return r
+    
+
+
+def nmap_match_one_sig(seen, ref):
+    c = 0
+    for k in seen.keys():
+        if ref.has_key(k):
+            if seen[k] in ref[k].split("|"):
+                c += 1
+    if c == 0 and seen.get("Resp") == "N":
+        return 0.7
+    else:
+        return 1.0*c/len(seen.keys())
+        
+        
+
+def nmap_sig(target, oport=80, cport=81, ucport=1):
+    res = {}
+
+    tcpopt = [ ("WScale", 10),
+               ("NOP",None),
+               ("MSS", 256),
+               ("Timestamp",(123,0)) ]
+    tests = [ IP(dst=target, id=1)/TCP(seq=1, sport=5001, dport=oport, options=tcpopt, flags="CS"),
+              IP(dst=target, id=1)/TCP(seq=1, sport=5002, dport=oport, options=tcpopt, flags=0),
+              IP(dst=target, id=1)/TCP(seq=1, sport=5003, dport=oport, options=tcpopt, flags="SFUP"),
+              IP(dst=target, id=1)/TCP(seq=1, sport=5004, dport=oport, options=tcpopt, flags="A"),
+              IP(dst=target, id=1)/TCP(seq=1, sport=5005, dport=cport, options=tcpopt, flags="S"),
+              IP(dst=target, id=1)/TCP(seq=1, sport=5006, dport=cport, options=tcpopt, flags="A"),
+              IP(dst=target, id=1)/TCP(seq=1, sport=5007, dport=cport, options=tcpopt, flags="FPU"),
+              IP(str(IP(dst=target)/UDP(sport=5008,dport=ucport)/(300*"i"))) ]
+
+    ans, unans = sr(tests, timeout=2)
+    ans += map(lambda x: (x,None), unans)
+
+    for S,T in ans:
+        if S.sport == 5008:
+            res["PU"] = nmap_udppacket_sig(S,T)
+        else:
+            t = "T%i" % (S.sport-5000)
+            if T is not None and T.haslayer(ICMP):
+                warning("Test %s answered by an ICMP" % t)
+                T=None
+            res[t] = nmap_tcppacket_sig(T)
+
+    return res
+
+def nmap_probes2sig(tests):
+    tests=tests.copy()
+    res = {}
+    if "PU" in tests:
+        res["PU"] = nmap_udppacket_sig(*tests["PU"])
+        del(tests["PU"])
+    for k in tests:
+        res[k] = nmap_tcppacket_sig(tests[k])
+    return res
+        
+
+def nmap_search(sigs):
+    guess = 0,[]
+    for os,fp in nmap_kdb.get_base():
+        c = 0.0
+        for t in sigs.keys():
+            if t in fp:
+                c += nmap_match_one_sig(sigs[t], fp[t])
+        c /= len(sigs.keys())
+        if c > guess[0]:
+            guess = c,[ os ]
+        elif c == guess[0]:
+            guess[1].append(os)
+    return guess
+    
+    
+def nmap_fp(target, oport=80, cport=81):
+    """nmap fingerprinting
+nmap_fp(target, [oport=80,] [cport=81,]) -> list of best guesses with accuracy
+"""
+    sigs = nmap_sig(target, oport, cport)
+    return nmap_search(sigs)
+        
+
+def nmap_sig2txt(sig):
+    torder = ["TSeq","T1","T2","T3","T4","T5","T6","T7","PU"]
+    korder = ["Class", "gcd", "SI", "IPID", "TS",
+              "Resp", "DF", "W", "ACK", "Flags", "Ops",
+              "TOS", "IPLEN", "RIPTL", "RID", "RIPCK", "UCK", "ULEN", "DAT" ]
+    txt=[]
+    for i in sig.keys():
+        if i not in torder:
+            torder.append(i)
+    for t in torder:
+        sl = sig.get(t)
+        if sl is None:
+            continue
+        s = []
+        for k in korder:
+            v = sl.get(k)
+            if v is None:
+                continue
+            s.append("%s=%s"%(k,v))
+        txt.append("%s(%s)" % (t, "%".join(s)))
+    return "\n".join(txt)
+            
+        
+
+
diff --git a/scapy/p0f.py b/scapy/p0f.py
new file mode 100644
index 0000000000000000000000000000000000000000..05118e9289933ace65cb01c6bbc00b3e33031fb4
--- /dev/null
+++ b/scapy/p0f.py
@@ -0,0 +1,247 @@
+from scapy.data import KnowledgeBase
+from scapy.config import conf
+
+###############
+## p0f stuff ##
+###############
+
+# File format (according to p0f.fp) :
+#
+# wwww:ttt:D:ss:OOO...:QQ:OS:Details
+#
+# wwww    - window size
+# ttt     - initial TTL
+# D       - don't fragment bit  (0=unset, 1=set) 
+# ss      - overall SYN packet size
+# OOO     - option value and order specification
+# QQ      - quirks list
+# OS      - OS genre
+# details - OS description
+
+
+
+class p0fKnowledgeBase(KnowledgeBase):
+    def __init__(self, filename):
+        KnowledgeBase.__init__(self, filename)
+        #self.ttl_range=[255]
+    def lazy_init(self):
+        try:
+            f=open(self.filename)
+        except IOError:
+            warning("Can't open base %s" % self.filename)
+            return
+        try:
+            self.base = []
+            for l in f:
+                if l[0] in ["#","\n"]:
+                    continue
+                l = tuple(l.split(":"))
+                if len(l) < 8:
+                    continue
+                li = map(int,l[1:4])
+                #if li[0] not in self.ttl_range:
+                #    self.ttl_range.append(li[0])
+                #    self.ttl_range.sort()
+                self.base.append((l[0], li[0], li[1], li[2], l[4], l[5], l[6], l[7][:-1]))
+        except:
+            warning("Can't parse p0f database (new p0f version ?)")
+            self.base = None
+        f.close()
+
+p0f_kdb = p0fKnowledgeBase(conf.p0f_base)
+
+
+def packet2p0f(pkt):
+    while pkt.haslayer(IP) and pkt.haslayer(TCP):
+        pkt = pkt.getlayer(IP)
+        if isinstance(pkt.payload, TCP):
+            break
+        pkt = pkt.payload
+
+    if not isinstance(pkt, IP) or not isinstance(pkt.payload, TCP):
+        raise TypeError("Not a TCP/IP packet")
+    if pkt.payload.flags & 0x13 != 0x02: #S,!A,!F
+        raise TypeError("Not a syn packet")
+    
+    #t = p0f_kdb.ttl_range[:]
+    #t += [pkt.ttl]
+    #t.sort()
+    #ttl=t[t.index(pkt.ttl)+1]
+    ttl = pkt.ttl
+
+    df = (pkt.flags & 2) / 2
+    ss = len(pkt)
+    # from p0f/config.h : PACKET_BIG = 100
+    if ss > 100:
+        ss = 0
+
+    ooo = ""
+    mss = -1
+    qqT = False
+    qqP = False
+    #qqBroken = False
+    ilen = (pkt[TCP].dataofs << 2) - 20 # from p0f.c
+    for option in pkt.payload.options:
+        ilen -= 1
+        if option[0] == "MSS":
+            ooo += "M" + str(option[1]) + ","
+            mss = option[1]
+            # FIXME: qqBroken
+            ilen -= 3
+        elif option[0] == "WScale":
+            ooo += "W" + str(option[1]) + ","
+            # FIXME: qqBroken
+            ilen -= 2
+        elif option[0] == "Timestamp":
+            if option[1][0] == 0:
+                ooo += "T0,"
+            else:
+                ooo += "T,"
+            if option[1][1] != 0:
+                qqT = True
+            ilen -= 9
+        elif option[0] == "SAckOK":
+            ooo += "S,"
+            ilen -= 1
+        elif option[0] == "NOP":
+            ooo += "N,"
+        elif option[0] == "EOL":
+            ooo += "E,"
+            if ilen > 0:
+                qqP = True
+        else:
+            ooo += "?,"
+            # FIXME: ilen
+    ooo = ooo[:-1]
+    if ooo == "": ooo = "."
+
+    win = pkt.payload.window
+    if mss != -1:
+        if win % mss == 0:
+            win = "S" + str(win/mss)
+        elif win % (mss + 40) == 0:
+            win = "T" + str(win/(mss+40))
+        win = str(win)
+
+    qq = ""
+
+    if qqP:
+        qq += "P"
+    if pkt[IP].id == 0:
+        qq += "Z"
+    if pkt[IP].options != '':
+        qq += "I"
+    if pkt[TCP].urgptr != 0:
+        qq += "U"
+    if pkt[TCP].reserved != 0:
+        qq += "X"
+    if pkt[TCP].ack != 0:
+        qq += "A"
+    if qqT:
+        qq += "T"
+    if pkt[TCP].flags & 40 != 0:
+        # U or P
+        qq += "F"
+    if not isinstance(pkt[TCP].payload, NoPayload):
+        qq += "D"
+    # FIXME : "!" - broken options segment
+
+    if qq == "":
+        qq = "."
+
+    return (win,
+            ttl,
+            df,
+            ss,
+            ooo,
+            qq)
+
+def p0f_correl(x,y):
+    d = 0
+    # wwww can be "*" or "%nn"
+    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))
+    # ttl
+    d += (y[1] >= x[1] and y[1] - x[1] < 32)
+    for i in [2, 3, 5]:
+        d += (x[i] == y[i])
+    xopt = x[4].split(",")
+    yopt = y[4].split(",")
+    if len(xopt) == len(yopt):
+        same = True
+        for i in range(len(xopt)):
+            if not (xopt[i] == yopt[i] or
+                    (len(yopt[i]) == 2 and len(xopt[i]) > 1 and
+                     yopt[i][1] == "*" and xopt[i][0] == yopt[i][0]) or
+                    (len(yopt[i]) > 2 and len(xopt[i]) > 1 and
+                     yopt[i][1] == "%" and xopt[i][0] == yopt[i][0] and
+                     int(xopt[i][1:]) % int(yopt[i][2:]) == 0)):
+                same = False
+                break
+        if same:
+            d += len(xopt)
+    return d
+
+
+def p0f(pkt):
+    """Passive OS fingerprinting: which OS emitted this TCP SYN ?
+p0f(packet) -> accuracy, [list of guesses]
+"""
+    pb = p0f_kdb.get_base()
+    if not pb:
+        warning("p0f base empty.")
+        return []
+    s = len(pb[0][0])
+    r = []
+    sig = packet2p0f(pkt)
+    max = len(sig[4].split(",")) + 5
+    for b in pb:
+        d = p0f_correl(sig,b)
+        if d == max:
+            r.append((b[6], b[7], b[1] - pkt[IP].ttl))
+    return r
+            
+
+def prnp0f(pkt):
+    try:
+        r = p0f(pkt)
+    except:
+        return
+    if r == []:
+        r = ("UNKNOWN", "[" + ":".join(map(str, packet2p0f(pkt))) + ":?:?]", None)
+    else:
+        r = r[0]
+    uptime = None
+    try:
+        uptime = pkt2uptime(pkt)
+    except:
+        pass
+    if uptime == 0:
+        uptime = None
+    res = pkt.sprintf("%IP.src%:%TCP.sport% - " + r[0] + " " + r[1])
+    if uptime is not None:
+        res += pkt.sprintf(" (up: " + str(uptime/3600) + " hrs)\n  -> %IP.dst%:%TCP.dport%")
+    else:
+        res += pkt.sprintf("\n  -> %IP.dst%:%TCP.dport%")
+    if r[2] is not None:
+        res += " (distance " + str(r[2]) + ")"
+    print res
+
+
+def pkt2uptime(pkt, HZ=100):
+    """Calculate the date the machine which emitted the packet booted using TCP timestamp
+pkt2uptime(pkt, [HZ=100])"""
+    if not isinstance(pkt, Packet):
+        raise TypeError("Not a TCP packet")
+    if isinstance(pkt,NoPayload):
+        raise TypeError("Not a TCP packet")
+    if not isinstance(pkt, TCP):
+        return pkt2uptime(pkt.payload)
+    for opt in pkt.options:
+        if opt[0] == "Timestamp":
+            #t = pkt.time - opt[1][0] * 1.0/HZ
+            #return time.ctime(t)
+            t = opt[1][0] / HZ
+            return t
+    raise TypeError("No timestamp option")
+
+
diff --git a/scapy/packet.py b/scapy/packet.py
new file mode 100644
index 0000000000000000000000000000000000000000..0957fb72c59d9150fe7acecd749e1d7391568a25
--- /dev/null
+++ b/scapy/packet.py
@@ -0,0 +1,1293 @@
+import re,time,itertools,os,random,socket
+from fields import *
+
+
+################
+## Generators ##
+################
+
+class Gen(object):
+    def __iter__(self):
+        return iter([])
+    
+class SetGen(Gen):
+    def __init__(self, set, _iterpacket=1):
+        self._iterpacket=_iterpacket
+        if type(set) is list:
+            self.set = set
+        elif isinstance(set, PacketList):
+            self.set = list(set)
+        else:
+            self.set = [set]
+    def transf(self, element):
+        return element
+    def __iter__(self):
+        for i in self.set:
+            if (type(i) is tuple) and (len(i) == 2) and type(i[0]) is int and type(i[1]) is int:
+                if  (i[0] <= i[1]):
+                    j=i[0]
+                    while j <= i[1]:
+                        yield j
+                        j += 1
+            elif isinstance(i, Gen) and (self._iterpacket or not isinstance(i,Packet)):
+                for j in i:
+                    yield j
+            else:
+                yield i
+    def __repr__(self):
+        return "<SetGen %s>" % self.set.__repr__()
+
+class Net(Gen):
+    """Generate a list of IPs from a network address or a name"""
+    name = "ip"
+    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])?$")
+    def __init__(self, net):
+        self.repr=net
+
+        tmp=net.split('/')+["32"]
+        if not self.ipaddress.match(net):
+            tmp[0]=socket.gethostbyname(tmp[0])
+        netmask = int(tmp[1])
+
+        def parse_digit(a,netmask):
+            netmask = min(8,max(netmask,0))
+            if a == "*":
+                a = (0,256)
+            elif a.find("-") >= 0:
+                x,y = map(int,a.split("-"))
+                if x > y:
+                    y = x
+                a = (x &  (0xffL<<netmask) , max(y, (x | (0xffL>>(8-netmask))))+1)
+            else:
+                a = (int(a) & (0xffL<<netmask),(int(a) | (0xffL>>(8-netmask)))+1)
+            return a
+
+        self.parsed = map(lambda x,y: parse_digit(x,y), tmp[0].split("."), map(lambda x,nm=netmask: x-nm, (8,16,24,32)))
+                                                                                               
+    def __iter__(self):
+        for d in xrange(*self.parsed[3]):
+            for c in xrange(*self.parsed[2]):
+                for b in xrange(*self.parsed[1]):
+                    for a in xrange(*self.parsed[0]):
+                        yield "%i.%i.%i.%i" % (a,b,c,d)
+    def choice(self):
+        ip = []
+        for v in self.parsed:
+            ip.append(str(random.randint(v[0],v[1]-1)))
+        return ".".join(ip) 
+                          
+    def __repr__(self):
+        return "Net(%r)" % self.repr
+
+class OID(Gen):
+    name = "OID"
+    def __init__(self, oid):
+        self.oid = oid        
+        self.cmpt = []
+        fmt = []        
+        for i in oid.split("."):
+            if "-" in i:
+                fmt.append("%i")
+                self.cmpt.append(tuple(map(int, i.split("-"))))
+            else:
+                fmt.append(i)
+        self.fmt = ".".join(fmt)
+    def __repr__(self):
+        return "OID(%r)" % self.oid
+    def __iter__(self):        
+        ii = [k[0] for k in self.cmpt]
+        while 1:
+            yield self.fmt % tuple(ii)
+            i = 0
+            while 1:
+                if i >= len(ii):
+                    raise StopIteration
+                if ii[i] < self.cmpt[i][1]:
+                    ii[i]+=1
+                    break
+                else:
+                    ii[i] = self.cmpt[i][0]
+                i += 1
+ 
+###########################
+## Packet abstract class ##
+###########################
+
+class Packet_metaclass(type):
+    def __new__(cls, name, bases, dct):
+        newcls = super(Packet_metaclass, cls).__new__(cls, name, bases, dct)
+        for f in newcls.fields_desc:
+            f.register_owner(newcls)
+        return newcls
+    def __getattr__(self, attr):
+        for k in self.fields_desc:
+            if k.name == attr:
+                return k
+        raise AttributeError(attr)
+
+class NewDefaultValues(Packet_metaclass):
+    """NewDefaultValues metaclass. Example usage:
+    class MyPacket(Packet):
+        fields_desc = [ StrField("my_field", "my default value"),  ]
+        
+    class MyPacket_variant(MyPacket):
+        __metaclass__ = NewDefaultValues
+        my_field = "my new default value"
+    """    
+    def __new__(cls, name, bases, dct):
+        fields = None
+        for b in bases:
+            if hasattr(b,"fields_desc"):
+                fields = b.fields_desc
+                break
+        if fields is None:
+            raise Scapy_Exception("No fields_desc in superclasses")
+
+        new_fields = []
+        for f in fields:
+            if f.name in dct:
+                f = f.copy()
+                f.default = dct[f.name]
+                del(dct[f.name])
+            new_fields.append(f)
+        dct["fields_desc"] = new_fields
+        return super(NewDefaultValues, cls).__new__(cls, name, bases, dct)
+
+class Packet(Gen):
+    __metaclass__ = Packet_metaclass
+    name=None
+
+    fields_desc = []
+
+    aliastypes = []
+    overload_fields = {}
+
+    underlayer = None
+
+    payload_guess = []
+    initialized = 0
+    show_indent=1
+    explicit = 0
+
+    @classmethod
+    def from_hexcap(cls):
+        return cls(import_hexcap())
+
+    @classmethod
+    def upper_bonds(self):
+        for fval,upper in self.payload_guess:
+            print "%-20s  %s" % (upper.__name__, ", ".join("%-12s" % ("%s=%r"%i) for i in fval.iteritems()))
+
+    @classmethod
+    def lower_bonds(self):
+        for lower,fval in self.overload_fields.iteritems():
+            print "%-20s  %s" % (lower.__name__, ", ".join("%-12s" % ("%s=%r"%i) for i in fval.iteritems()))
+
+    def __init__(self, _pkt="", post_transform=None, _internal=0, _underlayer=None, **fields):
+        self.time  = time.time()
+        self.sent_time = 0
+        if self.name is None:
+            self.name = self.__class__.__name__
+        self.aliastypes = [ self.__class__ ] + self.aliastypes
+        self.default_fields = {}
+        self.overloaded_fields = {}
+        self.fields={}
+        self.fieldtype={}
+        self.packetfields=[]
+        self.__dict__["payload"] = NoPayload()
+        self.init_fields()
+        self.underlayer = _underlayer
+        self.initialized = 1
+        if _pkt:
+            self.dissect(_pkt)
+            if not _internal:
+                self.dissection_done(self)
+        for f in fields.keys():
+            self.fields[f] = self.get_field(f).any2i(self,fields[f])
+        if type(post_transform) is list:
+            self.post_transforms = post_transform
+        elif post_transform is None:
+            self.post_transforms = []
+        else:
+            self.post_transforms = [post_transform]
+
+    def init_fields(self):
+        self.do_init_fields(self.fields_desc)
+
+    def do_init_fields(self, flist):
+        for f in flist:
+            self.default_fields[f.name] = f.default
+            self.fieldtype[f.name] = f
+            if f.holds_packets:
+                self.packetfields.append(f)
+            
+    def dissection_done(self,pkt):
+        """DEV: will be called after a dissection is completed"""
+        self.post_dissection(pkt)
+        self.payload.dissection_done(pkt)
+        
+    def post_dissection(self, pkt):
+        """DEV: is called after the dissection of the whole packet"""
+        pass
+
+    def get_field(self, fld):
+        """DEV: returns the field instance from the name of the field"""
+        return self.fieldtype[fld]
+        
+    def add_payload(self, payload):
+        if payload is None:
+            return
+        elif not isinstance(self.payload, NoPayload):
+            self.payload.add_payload(payload)
+        else:
+            if isinstance(payload, Packet):
+                self.__dict__["payload"] = payload
+                payload.add_underlayer(self)
+                for t in self.aliastypes:
+                    if payload.overload_fields.has_key(t):
+                        self.overloaded_fields = payload.overload_fields[t]
+                        break
+            elif type(payload) is str:
+                self.__dict__["payload"] = Raw(load=payload)
+            else:
+                raise TypeError("payload must be either 'Packet' or 'str', not [%s]" % repr(payload))
+    def remove_payload(self):
+        self.payload.remove_underlayer(self)
+        self.__dict__["payload"] = NoPayload()
+        self.overloaded_fields = {}
+    def add_underlayer(self, underlayer):
+        self.underlayer = underlayer
+    def remove_underlayer(self,other):
+        self.underlayer = None
+    def copy(self):
+        """Returns a deep copy of the instance."""
+        clone = self.__class__()
+        clone.fields = self.fields.copy()
+        for k in clone.fields:
+            clone.fields[k]=self.get_field(k).do_copy(clone.fields[k])
+        clone.default_fields = self.default_fields.copy()
+        clone.overloaded_fields = self.overloaded_fields.copy()
+        clone.overload_fields = self.overload_fields.copy()
+        clone.underlayer=self.underlayer
+        clone.explicit=self.explicit
+        clone.post_transforms=self.post_transforms[:]
+        clone.__dict__["payload"] = self.payload.copy()
+        clone.payload.add_underlayer(clone)
+        return clone
+
+    def getfieldval(self, attr):
+        if attr in self.fields:
+            return self.fields[attr]
+        if attr in self.overloaded_fields:
+            return self.overloaded_fields[attr]
+        if attr in self.default_fields:
+            return self.default_fields[attr]
+        return self.payload.getfieldval(attr)
+    
+    def getfield_and_val(self, attr):
+        if attr in self.fields:
+            return self.get_field(attr),self.fields[attr]
+        if attr in self.overloaded_fields:
+            return self.get_field(attr),self.overloaded_fields[attr]
+        if attr in self.default_fields:
+            return self.get_field(attr),self.default_fields[attr]
+        return self.payload.getfield_and_val(attr)
+    
+    def __getattr__(self, attr):
+        if self.initialized:
+            fld,v = self.getfield_and_val(attr)
+            if fld is not None:
+                return fld.i2h(self, v)
+            return v
+        raise AttributeError(attr)
+
+    def setfieldval(self, attr, val):
+        if self.default_fields.has_key(attr):
+            fld = self.get_field(attr)
+            if fld is None:
+                any2i = lambda x,y: y
+            else:
+                any2i = fld.any2i
+            self.fields[attr] = any2i(self, val)
+            self.explicit=0
+        elif attr == "payload":
+            self.remove_payload()
+            self.add_payload(val)
+        else:
+            self.payload.setfieldval(attr,val)
+
+    def __setattr__(self, attr, val):
+        if self.initialized:
+            try:
+                self.setfieldval(attr,val)
+            except AttributeError:
+                pass
+            else:
+                return
+        self.__dict__[attr] = val
+
+    def delfieldval(self, attr):
+        if self.fields.has_key(attr):
+            del(self.fields[attr])
+            self.explicit=0 # in case a default value must be explicited
+        elif self.default_fields.has_key(attr):
+            pass
+        elif attr == "payload":
+            self.remove_payload()
+        else:
+            self.payload.delfieldval(attr)
+
+    def __delattr__(self, attr):
+        if self.initialized:
+            try:
+                self.delfieldval(attr)
+            except AttributeError:
+                pass
+            else:
+                return
+        if self.__dict__.has_key(attr):
+            del(self.__dict__[attr])
+        else:
+            raise AttributeError(attr)
+            
+    def __repr__(self):
+        s = ""
+        ct = conf.color_theme
+        for f in self.fields_desc:
+            if isinstance(f, ConditionalField) and not f._evalcond(self):
+                continue
+            if f.name in self.fields:
+                val = f.i2repr(self, self.fields[f.name])
+            elif f.name in self.overloaded_fields:
+                val =  f.i2repr(self, self.overloaded_fields[f.name])
+            else:
+                continue
+            if isinstance(f, Emph):
+                ncol = ct.emph_field_name
+                vcol = ct.emph_field_value
+            else:
+                ncol = ct.field_name
+                vcol = ct.field_value
+
+                
+            s += " %s%s%s" % (ncol(f.name),
+                              ct.punct("="),
+                              vcol(val))
+        return "%s%s %s %s%s%s"% (ct.punct("<"),
+                                  ct.layer_name(self.__class__.__name__),
+                                  s,
+                                  ct.punct("|"),
+                                  repr(self.payload),
+                                  ct.punct(">"))
+    def __str__(self):
+        return self.build()
+    def __div__(self, other):
+        if isinstance(other, Packet):
+            cloneA = self.copy()
+            cloneB = other.copy()
+            cloneA.add_payload(cloneB)
+            return cloneA
+        elif type(other) is str:
+            return self/Raw(load=other)
+        else:
+            return other.__rdiv__(self)
+    def __rdiv__(self, other):
+        if type(other) is str:
+            return Raw(load=other)/self
+        else:
+            raise TypeError
+    def __mul__(self, other):
+        if type(other) is int:
+            return  [self]*other
+        else:
+            raise TypeError
+    def __rmul__(self,other):
+        return self.__mul__(other)
+    
+    def __nonzero__(self):
+        return True
+    def __len__(self):
+        return len(self.__str__())
+    def do_build(self):
+        p=""
+        for f in self.fields_desc:
+            p = f.addfield(self, p, self.getfieldval(f.name))
+        return p
+    
+    def post_build(self, pkt, pay):
+        """DEV: called right after the current layer is build."""
+        return pkt+pay
+
+    def build_payload(self):
+        return self.payload.build(internal=1)
+
+    def build(self,internal=0):
+        if not self.explicit:
+            self = self.__iter__().next()
+        pkt = self.do_build()
+        for t in self.post_transforms:
+            pkt = t(pkt)
+        pay = self.build_payload()
+        try:
+            p = self.post_build(pkt,pay)
+        except TypeError:
+            log_runtime.error("API changed! post_build() now takes 2 arguments. Compatibility is only assured for a short transition time")
+            p = self.post_build(pkt+pay)
+        if not internal:
+            pad = self.payload.getlayer(Padding) 
+            if pad: 
+                p += pad.build()
+            p = self.build_done(p)
+        return p
+
+    def build_done(self, p):
+        return self.payload.build_done(p)
+
+    def do_build_ps(self):
+        p=""
+        pl = []
+        q=""
+        for f in self.fields_desc:
+            p = f.addfield(self, p, self.getfieldval(f.name) )
+            if type(p) is str:
+                r = p[len(q):]
+                q = p
+            else:
+                r = ""
+            pl.append( (f, f.i2repr(self,self.getfieldval(f.name)), r) )
+            
+        pkt,lst = self.payload.build_ps(internal=1)
+        p += pkt
+        lst.append( (self, pl) )
+        
+        return p,lst
+    
+    def build_ps(self,internal=0):
+        p,lst = self.do_build_ps()
+#        if not internal:
+#            pkt = self
+#            while pkt.haslayer(Padding):
+#                pkt = pkt.getlayer(Padding)
+#                lst.append( (pkt, [ ("loakjkjd", pkt.load, pkt.load) ] ) )
+#                p += pkt.load
+#                pkt = pkt.payload
+        return p,lst
+
+
+    def psdump(self, filename=None, **kargs):
+        """psdump(filename=None, layer_shift=0, rebuild=1)
+Creates an EPS file describing a packet. If filename is not provided a temporary file is created and gs is called."""
+        canvas = self.canvas_dump(**kargs)
+        if filename is None:
+            fname = "/tmp/scapy.%i"%os.getpid()
+            canvas.writeEPSfile(fname)
+            os.system("%s '%s.eps' &" % (conf.prog.psreader,fname))
+        else:
+            canvas.writeEPSfile(filename)
+
+    def pdfdump(self, filename=None, **kargs):
+        """pdfdump(filename=None, layer_shift=0, rebuild=1)
+        Creates a PDF file describing a packet. If filename is not provided a temporary file is created and xpdf is called."""
+        canvas = self.canvas_dump(**kargs)
+        if filename is None:
+            fname = "/tmp/scapy.%i"%os.getpid()
+            canvas.writePDFfile(fname)
+            os.system("%s '%s.pdf' &" % (conf.prog.pdfreader,fname))
+        else:
+            canvas.writePDFfile(filename)
+
+        
+    def canvas_dump(self, layer_shift=0, rebuild=1):
+        canvas = pyx.canvas.canvas()
+        if rebuild:
+            p,t = self.__class__(str(self)).build_ps()
+        else:
+            p,t = self.build_ps()
+        YTXT=len(t)
+        for n,l in t:
+            YTXT += len(l)
+        YTXT = float(YTXT)
+        YDUMP=YTXT
+
+        XSTART = 1
+        XDSTART = 10
+        y = 0.0
+        yd = 0.0
+        xd = 0 
+        XMUL= 0.55
+        YMUL = 0.4
+    
+        backcolor=colgen(0.6, 0.8, 1.0, trans=pyx.color.rgb)
+        forecolor=colgen(0.2, 0.5, 0.8, trans=pyx.color.rgb)
+#        backcolor=makecol(0.376, 0.729, 0.525, 1.0)
+        
+        
+        def hexstr(x):
+            s = []
+            for c in x:
+                s.append("%02x" % ord(c))
+            return " ".join(s)
+
+                
+        def make_dump_txt(x,y,txt):
+            return pyx.text.text(XDSTART+x*XMUL, (YDUMP-y)*YMUL, r"\tt{%s}"%hexstr(txt), [pyx.text.size.Large])
+
+        def make_box(o):
+            return pyx.box.rect(o.left(), o.bottom(), o.width(), o.height(), relcenter=(0.5,0.5))
+
+        def make_frame(lst):
+            if len(lst) == 1:
+                b = lst[0].bbox()
+                b.enlarge(pyx.unit.u_pt)
+                return b.path()
+            else:
+                fb = lst[0].bbox()
+                fb.enlarge(pyx.unit.u_pt)
+                lb = lst[-1].bbox()
+                lb.enlarge(pyx.unit.u_pt)
+                if len(lst) == 2 and fb.left() > lb.right():
+                    return pyx.path.path(pyx.path.moveto(fb.right(), fb.top()),
+                                         pyx.path.lineto(fb.left(), fb.top()),
+                                         pyx.path.lineto(fb.left(), fb.bottom()),
+                                         pyx.path.lineto(fb.right(), fb.bottom()),
+                                         pyx.path.moveto(lb.left(), lb.top()),
+                                         pyx.path.lineto(lb.right(), lb.top()),
+                                         pyx.path.lineto(lb.right(), lb.bottom()),
+                                         pyx.path.lineto(lb.left(), lb.bottom()))
+                else:
+                    # XXX
+                    gb = lst[1].bbox()
+                    if gb != lb:
+                        gb.enlarge(pyx.unit.u_pt)
+                    kb = lst[-2].bbox()
+                    if kb != gb and kb != lb:
+                        kb.enlarge(pyx.unit.u_pt)
+                    return pyx.path.path(pyx.path.moveto(fb.left(), fb.top()),
+                                         pyx.path.lineto(fb.right(), fb.top()),
+                                         pyx.path.lineto(fb.right(), kb.bottom()),
+                                         pyx.path.lineto(lb.right(), kb.bottom()),
+                                         pyx.path.lineto(lb.right(), lb.bottom()),
+                                         pyx.path.lineto(lb.left(), lb.bottom()),
+                                         pyx.path.lineto(lb.left(), gb.top()),
+                                         pyx.path.lineto(fb.left(), gb.top()),
+                                         pyx.path.closepath(),)
+                                         
+
+        def make_dump(s, shift=0, y=0, col=None, bkcol=None, larg=16):
+            c = pyx.canvas.canvas()
+            tlist = []
+            while s:
+                dmp,s = s[:larg-shift],s[larg-shift:]
+                txt = make_dump_txt(shift, y, dmp)
+                tlist.append(txt)
+                shift += len(dmp)
+                if shift >= 16:
+                    shift = 0
+                    y += 1
+            if col is None:
+                col = pyx.color.rgb.red
+            if bkcol is None:
+                col = pyx.color.rgb.white
+            c.stroke(make_frame(tlist),[col,pyx.deco.filled([bkcol]),pyx.style.linewidth.Thick])
+            for txt in tlist:
+                c.insert(txt)
+            return c, tlist[-1].bbox(), shift, y
+                            
+
+        last_shift,last_y=0,0.0
+        while t:
+            bkcol = backcolor.next()
+            proto,fields = t.pop()
+            y += 0.5
+            pt = pyx.text.text(XSTART, (YTXT-y)*YMUL, r"\font\cmssfont=cmss10\cmssfont{%s}" % proto.name, [ pyx.text.size.Large])
+            y += 1
+            ptbb=pt.bbox()
+            ptbb.enlarge(pyx.unit.u_pt*2)
+            canvas.stroke(ptbb.path(),[pyx.color.rgb.black, pyx.deco.filled([bkcol])])
+            canvas.insert(pt)
+            for fname, fval, fdump in fields:
+                col = forecolor.next()
+                ft = pyx.text.text(XSTART, (YTXT-y)*YMUL, r"\font\cmssfont=cmss10\cmssfont{%s}" % tex_escape(fname.name))
+                if fval is not None:
+                    if len(fval) > 18:
+                        fval = fval[:18]+"[...]"
+                else:
+                    fval=""
+                vt = pyx.text.text(XSTART+3, (YTXT-y)*YMUL, r"\font\cmssfont=cmss10\cmssfont{%s}" % tex_escape(fval))
+                y += 1.0
+                if fdump:
+                    dt,target,last_shift,last_y = make_dump(fdump, last_shift, last_y, col, bkcol)
+
+                    dtb = dt.bbox()
+                    dtb=target
+                    vtb = vt.bbox()
+                    bxvt = make_box(vtb)
+                    bxdt = make_box(dtb)
+                    dtb.enlarge(pyx.unit.u_pt)
+                    try:
+                        if yd < 0:
+                            cnx = pyx.connector.curve(bxvt,bxdt,absangle1=0, absangle2=-90)
+                        else:
+                            cnx = pyx.connector.curve(bxvt,bxdt,absangle1=0, absangle2=90)
+                    except:
+                        pass
+                    else:
+                        canvas.stroke(cnx,[pyx.style.linewidth.thin,pyx.deco.earrow.small,col])
+                        
+                    canvas.insert(dt)
+                
+                canvas.insert(ft)
+                canvas.insert(vt)
+            last_y += layer_shift
+    
+        return canvas
+
+
+
+    def extract_padding(self, s):
+        """DEV: to be overloaded to extract current layer's padding. Return a couple of strings (actual layer, padding)"""
+        return s,None
+
+    def post_dissect(self, s):
+        """DEV: is called right after the current layer has been dissected"""
+        return s
+
+    def pre_dissect(self, s):
+        """DEV: is called right before the current layer is dissected"""
+        return s
+
+    def do_dissect(self, s):
+        flist = self.fields_desc[:]
+        flist.reverse()
+        while s and flist:
+            f = flist.pop()
+            s,fval = f.getfield(self, s)
+            self.fields[f.name] = fval
+            
+        return s
+
+    def do_dissect_payload(self, s):
+        if s:
+            cls = self.guess_payload_class(s)
+            try:
+                p = cls(s, _internal=1, _underlayer=self)
+            except KeyboardInterrupt:
+                raise
+            except:
+                if conf.debug_dissector:
+                    if isinstance(cls,type) and issubclass(cls,Packet):
+                        log_runtime.error("%s dissector failed" % cls.name)
+                    else:
+                        log_runtime.error("%s.guess_payload_class() returned [%s]" % (self.__class__.__name__,repr(cls)))
+                    if cls is not None:
+                        raise
+                p = Raw(s, _internal=1, _underlayer=self)
+            self.add_payload(p)
+
+    def dissect(self, s):
+        s = self.pre_dissect(s)
+
+        s = self.do_dissect(s)
+
+        s = self.post_dissect(s)
+            
+        payl,pad = self.extract_padding(s)
+        self.do_dissect_payload(payl)
+        if pad and conf.padding:
+            self.add_payload(Padding(pad))
+
+
+    def guess_payload_class(self, payload):
+        """DEV: Guesses the next payload class from layer bonds. Can be overloaded to use a different mechanism."""
+        for t in self.aliastypes:
+            for fval, cls in t.payload_guess:
+                ok = 1
+                for k in fval.keys():
+                    if not hasattr(self, k) or fval[k] != self.getfieldval(k):
+                        ok = 0
+                        break
+                if ok:
+                    return cls
+        return self.default_payload_class(payload)
+    
+    def default_payload_class(self, payload):
+        """DEV: Returns the default payload class if nothing has been found by the guess_payload_class() method."""
+        return Raw
+
+    def hide_defaults(self):
+        """Removes fields' values that are the same as default values."""
+        for k in self.fields.keys():
+            if self.default_fields.has_key(k):
+                if self.default_fields[k] == self.fields[k]:
+                    del(self.fields[k])
+        self.payload.hide_defaults()
+            
+    def clone_with(self, payload=None, **kargs):
+        pkt = self.__class__()
+        pkt.explicit = 1
+        pkt.fields = kargs
+        pkt.time = self.time
+        pkt.underlayer = self.underlayer
+        pkt.overload_fields = self.overload_fields.copy()
+        pkt.post_transforms = self.post_transforms
+        if payload is not None:
+            pkt.add_payload(payload)
+        return pkt
+        
+
+    def __iter__(self):
+        def loop(todo, done, self=self):
+            if todo:
+                eltname = todo.pop()
+                elt = self.getfieldval(eltname)
+                if not isinstance(elt, Gen):
+                    if self.get_field(eltname).islist:
+                        elt = SetGen([elt])
+                    else:
+                        elt = SetGen(elt)
+                for e in elt:
+                    done[eltname]=e
+                    for x in loop(todo[:], done):
+                        yield x
+            else:
+                if isinstance(self.payload,NoPayload):
+                    payloads = [None]
+                else:
+                    payloads = self.payload
+                for payl in payloads:
+                    done2=done.copy()
+                    for k in done2:
+                        if isinstance(done2[k], VolatileValue):
+                            done2[k] = done2[k]._fix()
+                    pkt = self.clone_with(payload=payl, **done2)
+                    yield pkt
+
+        if self.explicit:
+            todo = []
+            done = self.fields
+        else:
+            todo = [ k for (k,v) in itertools.chain(self.default_fields.iteritems(),
+                                                    self.overloaded_fields.iteritems())
+                     if isinstance(v, VolatileValue) ] + self.fields.keys()
+            done = {}
+        return loop(todo, done)
+
+    def __gt__(self, other):
+        """True if other is an answer from self (self ==> other)."""
+        if isinstance(other, Packet):
+            return other < self
+        elif type(other) is str:
+            return 1
+        else:
+            raise TypeError((self, other))
+    def __lt__(self, other):
+        """True if self is an answer from other (other ==> self)."""
+        if isinstance(other, Packet):
+            return self.answers(other)
+        elif type(other) is str:
+            return 1
+        else:
+            raise TypeError((self, other))
+
+    def __eq__(self, other):
+        if not isinstance(other, self.__class__):
+            return False
+        for f in self.fields_desc:
+            if f not in other.fields_desc:
+                return False
+            if self.getfieldval(f.name) != other.getfieldval(f.name):
+                return False
+        return self.payload == other.payload
+
+    def __ne__(self, other):
+        return not self.__eq__(other)
+
+    def hashret(self):
+        """DEV: returns a string that has the same value for a request and its answer."""
+        return self.payload.hashret()
+    def answers(self, other):
+        """DEV: true if self is an answer from other"""
+        if other.__class__ == self.__class__:
+            return self.payload.answers(other.payload)
+        return 0
+
+    def haslayer(self, cls):
+        """true if self has a layer that is an instance of cls. Superseded by "cls in self" syntax."""
+        if self.__class__ == cls or self.__class__.__name__ == cls:
+            return 1
+        for f in self.packetfields:
+            fvalue_gen = self.getfieldval(f.name)
+            if fvalue_gen is None:
+                continue
+            if not f.islist:
+                fvalue_gen = SetGen(fvalue_gen,_iterpacket=0)
+            for fvalue in fvalue_gen:
+                if isinstance(fvalue, Packet):
+                    ret = fvalue.haslayer(cls)
+                    if ret:
+                        return ret
+        return self.payload.haslayer(cls)
+    def getlayer(self, cls, nb=1, _track=None):
+        """Return the nb^th layer that is an instance of cls."""
+        if type(cls) is str and "." in cls:
+            ccls,fld = cls.split(".",1)
+        else:
+            ccls,fld = cls,None
+        if self.__class__ == cls or self.__class__.name == ccls:
+            if nb == 1:
+                if fld is None:
+                    return self
+                else:
+                    return self.getfieldval(fld)
+            else:
+                nb -=1
+        for f in self.packetfields:
+            fvalue_gen = self.getfieldval(f.name)
+            if fvalue_gen is None:
+                continue
+            if not f.islist:
+                fvalue_gen = SetGen(fvalue_gen,_iterpacket=0)
+            for fvalue in fvalue_gen:
+                if isinstance(fvalue, Packet):
+                    track=[]
+                    ret = fvalue.getlayer(cls, nb, _track=track)
+                    if ret is not None:
+                        return ret
+                    nb = track[0]
+        return self.payload.getlayer(cls,nb,_track=_track)
+
+    def __getitem__(self, cls):
+        if type(cls) is slice:
+            if cls.stop:
+                ret = self.getlayer(cls.start, cls.stop)
+            else:
+                ret = self.getlayer(cls.start)
+            if ret is None and cls.step is not None:
+                ret = cls.step
+            return ret
+        else:
+            return self.getlayer(cls)
+        
+    def __contains__(self, cls):
+        """"cls in self" returns true if self has a layer which is an instance of cls."""
+        return self.haslayer(cls)
+        
+    
+
+    def display(self,*args,**kargs):  # Deprecated. Use show()
+        """Deprecated. Use show() method."""
+        self.show(*args,**kargs)
+    def show(self, indent=3, lvl="", label_lvl=""):
+        """Prints a hierarchical view of the packet. "indent" gives the size of indentation for each layer."""
+        ct = conf.color_theme
+        print "%s%s %s %s" % (label_lvl,
+                              ct.punct("###["),
+                              ct.layer_name(self.name),
+                              ct.punct("]###"))
+        for f in self.fields_desc:
+            if isinstance(f, ConditionalField) and not f._evalcond(self):
+                continue
+            if isinstance(f, Emph):
+                ncol = ct.emph_field_name
+                vcol = ct.emph_field_value
+            else:
+                ncol = ct.field_name
+                vcol = ct.field_value
+            fvalue = self.getfieldval(f.name)
+            if isinstance(fvalue, Packet) or (f.islist and f.holds_packets and type(fvalue) is list):
+                print "%s  \\%-10s\\" % (label_lvl+lvl, ncol(f.name))
+                fvalue_gen = SetGen(fvalue,_iterpacket=0)
+                for fvalue in fvalue_gen:
+                    fvalue.show(indent=indent, label_lvl=label_lvl+lvl+"   |")
+            else:
+                print "%s  %-10s%s %s" % (label_lvl+lvl,
+                                          ncol(f.name),
+                                          ct.punct("="),
+                                          vcol(f.i2repr(self,fvalue)))
+        self.payload.show(indent=indent, lvl=lvl+(" "*indent*self.show_indent), label_lvl=label_lvl)
+    def show2(self):
+        """Prints a hierarchical view of an assembled version of the packet, so that automatic fields are calculated (checksums, etc.)"""
+        self.__class__(str(self)).show()
+
+    def sprintf(self, fmt, relax=1):
+        """sprintf(format, [relax=1]) -> str
+where format is a string that can include directives. A directive begins and
+ends by % and has the following format %[fmt[r],][cls[:nb].]field%.
+
+fmt is a classic printf directive, "r" can be appended for raw substitution
+(ex: IP.flags=0x18 instead of SA), nb is the number of the layer we want
+(ex: for IP/IP packets, IP:2.src is the src of the upper IP layer).
+Special case : "%.time%" is the creation time.
+Ex : p.sprintf("%.time% %-15s,IP.src% -> %-15s,IP.dst% %IP.chksum% "
+               "%03xr,IP.proto% %r,TCP.flags%")
+
+Moreover, the format string can include conditionnal statements. A conditionnal
+statement looks like : {layer:string} where layer is a layer name, and string
+is the string to insert in place of the condition if it is true, i.e. if layer
+is present. If layer is preceded by a "!", the result si inverted. Conditions
+can be imbricated. A valid statement can be :
+  p.sprintf("This is a{TCP: TCP}{UDP: UDP}{ICMP:n ICMP} packet")
+  p.sprintf("{IP:%IP.dst% {ICMP:%ICMP.type%}{TCP:%TCP.dport%}}")
+
+A side effect is that, to obtain "{" and "}" characters, you must use
+"%(" and "%)".
+"""
+
+        escape = { "%": "%",
+                   "(": "{",
+                   ")": "}" }
+
+
+        # Evaluate conditions 
+        while "{" in fmt:
+            i = fmt.rindex("{")
+            j = fmt[i+1:].index("}")
+            cond = fmt[i+1:i+j+1]
+            k = cond.find(":")
+            if k < 0:
+                raise Scapy_Exception("Bad condition in format string: [%s] (read sprintf doc!)"%cond)
+            cond,format = cond[:k],cond[k+1:]
+            res = False
+            if cond[0] == "!":
+                res = True
+                cond = cond[1:]
+            if self.haslayer(cond):
+                res = not res
+            if not res:
+                format = ""
+            fmt = fmt[:i]+format+fmt[i+j+2:]
+
+        # Evaluate directives
+        s = ""
+        while "%" in fmt:
+            i = fmt.index("%")
+            s += fmt[:i]
+            fmt = fmt[i+1:]
+            if fmt and fmt[0] in escape:
+                s += escape[fmt[0]]
+                fmt = fmt[1:]
+                continue
+            try:
+                i = fmt.index("%")
+                sfclsfld = fmt[:i]
+                fclsfld = sfclsfld.split(",")
+                if len(fclsfld) == 1:
+                    f = "s"
+                    clsfld = fclsfld[0]
+                elif len(fclsfld) == 2:
+                    f,clsfld = fclsfld
+                else:
+                    raise Scapy_Exception
+                if "." in clsfld:
+                    cls,fld = clsfld.split(".")
+                else:
+                    cls = self.__class__.__name__
+                    fld = clsfld
+                num = 1
+                if ":" in cls:
+                    cls,num = cls.split(":")
+                    num = int(num)
+                fmt = fmt[i+1:]
+            except:
+                raise Scapy_Exception("Bad format string [%%%s%s]" % (fmt[:25], fmt[25:] and "..."))
+            else:
+                if fld == "time":
+                    val = time.strftime("%H:%M:%S.%%06i", time.localtime(self.time)) % int((self.time-int(self.time))*1000000)
+                elif cls == self.__class__.__name__ and hasattr(self, fld):
+                    if num > 1:
+                        val = self.payload.sprintf("%%%s,%s:%s.%s%%" % (f,cls,num-1,fld), relax)
+                        f = "s"
+                    elif f[-1] == "r":  # Raw field value
+                        val = getattr(self,fld)
+                        f = f[:-1]
+                        if not f:
+                            f = "s"
+                    else:
+                        val = getattr(self,fld)
+                        if fld in self.fieldtype:
+                            val = self.fieldtype[fld].i2repr(self,val)
+                else:
+                    val = self.payload.sprintf("%%%s%%" % sfclsfld, relax)
+                    f = "s"
+                s += ("%"+f) % val
+            
+        s += fmt
+        return s
+
+    def mysummary(self):
+        """DEV: can be overloaded to return a string that summarizes the layer.
+           Only one mysummary() is used in a whole packet summary: the one of the upper layer,
+           except if a mysummary() also returns (as a couple) a list of layers whose
+           mysummary() must be called if they are present."""
+        return ""
+
+    def summary(self, intern=0):
+        """Prints a one line summary of a packet."""
+        found,s,needed = self.payload.summary(intern=1)
+        if s:
+            s = " / "+s
+        ret = ""
+        if not found or self.__class__ in needed:
+            ret = self.mysummary()
+            if type(ret) is tuple:
+                ret,n = ret
+                needed += n
+        if ret or needed:
+            found = 1
+        if not ret:
+            ret = self.__class__.__name__
+        ret = "%s%s" % (ret,s)
+        if intern:
+            return found,ret,needed
+        else:
+            return ret
+    
+    def lastlayer(self,layer=None):
+        """Returns the uppest layer of the packet"""
+        return self.payload.lastlayer(self)
+
+    def decode_payload_as(self,cls):
+        """Reassembles the payload and decode it using another packet class"""
+        s = str(self.payload)
+        self.payload = cls(s)
+
+    def libnet(self):
+        """Not ready yet. Should give the necessary C code that interfaces with libnet to recreate the packet"""
+        print "libnet_build_%s(" % self.__class__.name.lower()
+        det = self.__class__(str(self))
+        for f in self.fields_desc:
+            val = det.getfieldval(f.name)
+            if val is None:
+                val = 0
+            elif type(val) is int:
+                val = str(val)
+            else:
+                val = '"%s"' % str(val)
+            print "\t%s, \t\t/* %s */" % (val,f.name)
+        print ");"
+    def command(self):
+        """Returns a string representing the command you have to type to obtain the same packet"""
+        f = []
+        for fn,fv in self.fields.items():
+            fld = self.get_field(fn)
+            if isinstance(fv, Packet):
+                fv = fv.command()
+            elif fld.islist and fld.holds_packets and type(fv) is list:
+                fv = "[%s]" % ",".join( map(Packet.command, fv))
+            else:
+                fv = repr(fv)
+            f.append("%s=%s" % (fn, fv))
+        c = "%s(%s)" % (self.__class__.__name__, ", ".join(f))
+        pc = self.payload.command()
+        if pc:
+            c += "/"+pc
+        return c                    
+
+class NoPayload(Packet,object):
+    def __new__(cls, *args, **kargs):
+        singl = cls.__dict__.get("__singl__")
+        if singl is None:
+            cls.__singl__ = singl = object.__new__(cls)
+            Packet.__init__(singl, *args, **kargs)
+        return singl
+    def __init__(self, *args, **kargs):
+        pass
+    def dissection_done(self,pkt):
+        return
+    def add_payload(self, payload):
+        raise Scapy_Exception("Can't add payload to NoPayload instance")
+    def remove_payload(self):
+        pass
+    def add_underlayer(self,underlayer):
+        pass
+    def remove_underlayer(self,other):
+        pass
+    def copy(self):
+        return self
+    def __repr__(self):
+        return ""
+    def __str__(self):
+        return ""
+    def __nonzero__(self):
+        return False
+    def build(self, internal=0):
+        return ""    
+    def build_done(self, p):
+        return p
+    def build_ps(self, internal=0):
+        return "",[]
+    def getfieldval(self, attr):
+        raise AttributeError(attr)
+    def getfield_and_val(self, attr):
+        raise AttributeError(attr)
+    def setfieldval(self, attr, val):
+        raise AttributeError(attr)
+    def delfieldval(self, attr):
+        raise AttributeError(attr)
+    def __getattr__(self, attr):
+        if attr in self.__dict__:
+            return self.__dict__[attr]
+        elif attr in self.__class__.__dict__:
+            return self.__class__.__dict__[attr]
+        else:
+            raise AttributeError, attr
+    def hide_defaults(self):
+        pass
+    def __iter__(self):
+        return iter([])
+    def __eq__(self, other):
+        if isinstance(other, NoPayload):
+            return True
+        return False
+    def hashret(self):
+        return ""
+    def answers(self, other):
+        return isinstance(other, NoPayload) or isinstance(other, Padding)
+    def haslayer(self, cls):
+        return 0
+    def getlayer(self, cls, nb=1, _track=None):
+        if _track is not None:
+            _track.append(nb)
+        return None
+    def show(self, indent=3, lvl="", label_lvl=""):
+        pass
+    def sprintf(self, fmt, relax):
+        if relax:
+            return "??"
+        else:
+            raise Scapy_Exception("Format not found [%s]"%fmt)
+    def summary(self, intern=0):
+        return 0,"",[]
+    def lastlayer(self,layer):
+        return layer
+    def command(self):
+        return ""
+    
+####################
+## packet classes ##
+####################
+
+            
+class Raw(Packet):
+    name = "Raw"
+    fields_desc = [ StrField("load", "") ]
+    def answers(self, other):
+        return 1
+#        s = str(other)
+#        t = self.load
+#        l = min(len(s), len(t))
+#        return  s[:l] == t[:l]
+        
+class Padding(Raw):
+    name = "Padding"
+    def build(self, internal=0):
+        if internal:
+            return ""
+        else:
+            return Raw.build(self)
+
+#################
+## Bind layers ##
+#################
+
+
+def bind_bottom_up(lower, upper, __fval=None, **fval):
+    if __fval is not None:
+        fval.update(__fval)
+    lower.payload_guess = lower.payload_guess[:]
+    lower.payload_guess.append((fval, upper))
+    
+
+def bind_top_down(lower, upper, __fval=None, **fval):
+    if __fval is not None:
+        fval.update(__fval)
+    upper.overload_fields = upper.overload_fields.copy()
+    upper.overload_fields[lower] = fval
+    
+def bind_layers(lower, upper, __fval=None, **fval):
+    if __fval is not None:
+        fval.update(__fval)
+    bind_top_down(lower, upper, **fval)
+    bind_bottom_up(lower, upper, **fval)
+
+def split_bottom_up(lower, upper, __fval=None, **fval):
+    if __fval is not None:
+        fval.update(__fval)
+    def do_filter((f,u),upper=upper,fval=fval):
+        if u != upper:
+            return True
+        for k in fval:
+            if k not in f or f[k] != fval[k]:
+                return True
+        return False
+    lower.payload_guess = filter(do_filter, lower.payload_guess)
+        
+def split_top_down(lower, upper, __fval=None, **fval):
+    if __fval is not None:
+        fval.update(__fval)
+    if lower in upper.overload_fields:
+        ofval = upper.overload_fields[lower]
+        for k in fval:
+            if k not in ofval or ofval[k] != fval[k]:
+                return
+        upper.overload_fields = upper.overload_fields.copy()
+        del(upper.overload_fields[lower])
+
+def split_layers(lower, upper, __fval=None, **fval):
+    if __fval is not None:
+        fval.update(__fval)
+    split_bottom_up(lower, upper, **fval)
+    split_top_down(lower, upper, **fval)
+
+
+def ls(obj=None):
+    """List  available layers, or infos on a given layer"""
+    if obj is None:
+        import __builtin__
+        all = __builtin__.__dict__.copy()
+        all.update(globals())
+        objlst = filter(lambda (n,o): isinstance(o,type) and issubclass(o,Packet), all.items())
+        objlst.sort(lambda x,y:cmp(x[0],y[0]))
+        for n,o in objlst:
+            print "%-10s : %s" %(n,o.name)
+    else:
+        if isinstance(obj, type) and issubclass(obj, Packet):
+            for f in obj.fields_desc:
+                print "%-10s : %-20s = (%s)" % (f.name, f.__class__.__name__,  repr(f.default))
+        elif isinstance(obj, Packet):
+            for f in obj.fields_desc:
+                print "%-10s : %-20s = %-15s (%s)" % (f.name, f.__class__.__name__, repr(getattr(obj,f.name)), repr(f.default))
+            if not isinstance(obj.payload, NoPayload):
+                print "--"
+                ls(obj.payload)
+                
+
+        else:
+            print "Not a packet class. Type 'ls()' to list packet classes."
+
+
+    
+#############
+## Fuzzing ##
+#############
+
+
+def fuzz(p, _inplace=0):
+    if not _inplace:
+        p = p.copy()
+    q = p
+    while not isinstance(q, NoPayload):
+        for f in q.fields_desc:
+            if isinstance(f, PacketListField):
+                for r in getattr(q, f.name):
+                    print "fuzzing", repr(r)
+                    fuzz(r, _inplace=1)
+            elif f.default is not None:
+                rnd = f.randval()
+                if rnd is not None:
+                    q.default_fields[f.name] = rnd
+        q = q.payload
+    return p
+
+
+
diff --git a/scapy/plist.py b/scapy/plist.py
new file mode 100644
index 0000000000000000000000000000000000000000..7560b095b1ab7df78ac9ea5e122c6be6f32969f6
--- /dev/null
+++ b/scapy/plist.py
@@ -0,0 +1,912 @@
+import os,socket
+from config import conf
+
+#############
+## Results ##
+#############
+
+class PacketList:
+    res = []
+    def __init__(self, res=None, name="PacketList", stats=None):
+        """create a packet list from a list of packets
+           res: the list of packets
+           stats: a list of classes that will appear in the stats (defaults to [TCP,UDP,ICMP])"""
+        if stats is None:
+            stats = [ TCP,UDP,ICMP ]
+        self.stats = stats
+        if res is None:
+            res = []
+        if isinstance(res, PacketList):
+            res = res.res
+        self.res = res
+        self.listname = name
+    def _elt2pkt(self, elt):
+        return elt
+    def _elt2sum(self, elt):
+        return elt.summary()
+    def _elt2show(self, elt):
+        return self._elt2sum(elt)
+    def __repr__(self):
+#        stats=dict.fromkeys(self.stats,0) ## needs python >= 2.3  :(
+        stats = dict(map(lambda x: (x,0), self.stats))
+        other = 0
+        for r in self.res:
+            f = 0
+            for p in stats:
+                if self._elt2pkt(r).haslayer(p):
+                    stats[p] += 1
+                    f = 1
+                    break
+            if not f:
+                other += 1
+        s = ""
+        ct = conf.color_theme
+        for p in self.stats:
+            s += " %s%s%s" % (ct.packetlist_proto(p.name),
+                              ct.punct(":"),
+                              ct.packetlist_value(stats[p]))
+        s += " %s%s%s" % (ct.packetlist_proto("Other"),
+                          ct.punct(":"),
+                          ct.packetlist_value(other))
+        return "%s%s%s%s%s" % (ct.punct("<"),
+                               ct.packetlist_name(self.listname),
+                               ct.punct(":"),
+                               s,
+                               ct.punct(">"))
+    def __getattr__(self, attr):
+        return getattr(self.res, attr)
+    def __getitem__(self, item):
+        if isinstance(item,type) and issubclass(item,Packet):
+            return self.__class__(filter(lambda x: item in self._elt2pkt(x),self.res),
+                                  name="%s from %s"%(item.__name__,self.listname))
+        if type(item) is slice:
+            return self.__class__(self.res.__getitem__(item),
+                                  name = "mod %s" % self.listname)
+        return self.res.__getitem__(item)
+    def __getslice__(self, *args, **kargs):
+        return self.__class__(self.res.__getslice__(*args, **kargs),
+                              name="mod %s"%self.listname)
+    def __add__(self, other):
+        return self.__class__(self.res+other.res,
+                              name="%s+%s"%(self.listname,other.listname))
+    def summary(self, prn=None, lfilter=None):
+        """prints a summary of each packet
+prn:     function to apply to each packet instead of lambda x:x.summary()
+lfilter: truth function to apply to each packet to decide whether it will be displayed"""
+        for r in self.res:
+            if lfilter is not None:
+                if not lfilter(r):
+                    continue
+            if prn is None:
+                print self._elt2sum(r)
+            else:
+                print prn(r)
+    def nsummary(self,prn=None, lfilter=None):
+        """prints a summary of each packet with the packet's number
+prn:     function to apply to each packet instead of lambda x:x.summary()
+lfilter: truth function to apply to each packet to decide whether it will be displayed"""
+        for i in range(len(self.res)):
+            if lfilter is not None:
+                if not lfilter(self.res[i]):
+                    continue
+            print conf.color_theme.id(i,"%04i"),
+            if prn is None:
+                print self._elt2sum(self.res[i])
+            else:
+                print prn(self.res[i])
+    def display(self): # Deprecated. Use show()
+        """deprecated. is show()"""
+        self.show()
+    def show(self, *args, **kargs):
+        """Best way to display the packet list. Defaults to nsummary() method"""
+        return self.nsummary(*args, **kargs)
+    
+    def filter(self, func):
+        """Returns a packet list filtered by a truth function"""
+        return self.__class__(filter(func,self.res),
+                              name="filtered %s"%self.listname)
+    def make_table(self, *args, **kargs):
+        """Prints a table using a function that returs for each packet its head column value, head row value and displayed value
+        ex: p.make_table(lambda x:(x[IP].dst, x[TCP].dport, x[TCP].sprintf("%flags%")) """
+        return make_table(self.res, *args, **kargs)
+    def make_lined_table(self, *args, **kargs):
+        """Same as make_table, but print a table with lines"""
+        return make_lined_table(self.res, *args, **kargs)
+    def make_tex_table(self, *args, **kargs):
+        """Same as make_table, but print a table with LaTeX syntax"""
+        return make_tex_table(self.res, *args, **kargs)
+
+    def plot(self, f, lfilter=None,**kargs):
+        """Applies a function to each packet to get a value that will be plotted with GnuPlot. A gnuplot object is returned
+        lfilter: a truth function that decides whether a packet must be ploted"""
+        g=Gnuplot.Gnuplot()
+        l = self.res
+        if lfilter is not None:
+            l = filter(lfilter, l)
+        l = map(f,l)
+        g.plot(Gnuplot.Data(l, **kargs))
+        return g
+
+    def diffplot(self, f, delay=1, lfilter=None, **kargs):
+        """diffplot(f, delay=1, lfilter=None)
+        Applies a function to couples (l[i],l[i+delay])"""
+        g = Gnuplot.Gnuplot()
+        l = self.res
+        if lfilter is not None:
+            l = filter(lfilter, l)
+        l = map(f,l[:-delay],l[delay:])
+        g.plot(Gnuplot.Data(l, **kargs))
+        return g
+
+    def multiplot(self, f, lfilter=None, **kargs):
+        """Uses a function that returns a label and a value for this label, then plots all the values label by label"""
+        g=Gnuplot.Gnuplot()
+        l = self.res
+        if lfilter is not None:
+            l = filter(lfilter, l)
+
+        d={}
+        for e in l:
+            k,v = f(e)
+            if k in d:
+                d[k].append(v)
+            else:
+                d[k] = [v]
+        data=[]
+        for k in d:
+            data.append(Gnuplot.Data(d[k], title=k, **kargs))
+
+        g.plot(*data)
+        return g
+        
+
+    def rawhexdump(self):
+        """Prints an hexadecimal dump of each packet in the list"""
+        for p in self:
+            hexdump(self._elt2pkt(p))
+
+    def hexraw(self, lfilter=None):
+        """Same as nsummary(), except that if a packet has a Raw layer, it will be hexdumped
+        lfilter: a truth function that decides whether a packet must be displayed"""
+        for i in range(len(self.res)):
+            p = self._elt2pkt(self.res[i])
+            if lfilter is not None and not lfilter(p):
+                continue
+            print "%s %s %s" % (conf.color_theme.id(i,"%04i"),
+                                p.sprintf("%.time%"),
+                                self._elt2sum(self.res[i]))
+            if p.haslayer(Raw):
+                hexdump(p.getlayer(Raw).load)
+
+    def hexdump(self, lfilter=None):
+        """Same as nsummary(), except that packets are also hexdumped
+        lfilter: a truth function that decides whether a packet must be displayed"""
+        for i in range(len(self.res)):
+            p = self._elt2pkt(self.res[i])
+            if lfilter is not None and not lfilter(p):
+                continue
+            print "%s %s %s" % (conf.color_theme.id(i,"%04i"),
+                                p.sprintf("%.time%"),
+                                self._elt2sum(self.res[i]))
+            hexdump(p)
+
+    def padding(self, lfilter=None):
+        """Same as hexraw(), for Padding layer"""
+        for i in range(len(self.res)):
+            p = self._elt2pkt(self.res[i])
+            if p.haslayer(Padding):
+                if lfilter is None or lfilter(p):
+                    print "%s %s %s" % (conf.color_theme.id(i,"%04i"),
+                                        p.sprintf("%.time%"),
+                                        self._elt2sum(self.res[i]))
+                    hexdump(p.getlayer(Padding).load)
+
+    def nzpadding(self, lfilter=None):
+        """Same as padding() but only non null padding"""
+        for i in range(len(self.res)):
+            p = self._elt2pkt(self.res[i])
+            if p.haslayer(Padding):
+                pad = p.getlayer(Padding).load
+                if pad == pad[0]*len(pad):
+                    continue
+                if lfilter is None or lfilter(p):
+                    print "%s %s %s" % (conf.color_theme.id(i,"%04i"),
+                                        p.sprintf("%.time%"),
+                                        self._elt2sum(self.res[i]))
+                    hexdump(p.getlayer(Padding).load)
+        
+
+    def conversations(self, getsrcdst=None,**kargs):
+        """Graphes a conversations between sources and destinations and display it
+        (using graphviz and imagemagick)
+        getsrcdst: a function that takes an element of the list and return the source and dest
+                   by defaults, return source and destination IP
+        type: output type (svg, ps, gif, jpg, etc.), passed to dot's "-T" option
+        target: filename or redirect. Defaults pipe to Imagemagick's display program
+        prog: which graphviz program to use"""
+        if getsrcdst is None:
+            getsrcdst = lambda x:(x[IP].src, x[IP].dst)
+        conv = {}
+        for p in self.res:
+            p = self._elt2pkt(p)
+            try:
+                c = getsrcdst(p)
+            except:
+                #XXX warning()
+                continue
+            conv[c] = conv.get(c,0)+1
+        gr = 'digraph "conv" {\n'
+        for s,d in conv:
+            gr += '\t "%s" -> "%s"\n' % (s,d)
+        gr += "}\n"        
+        return do_graph(gr, **kargs)
+
+    def afterglow(self, src=None, event=None, dst=None, **kargs):
+        """Experimental clone attempt of http://sourceforge.net/projects/afterglow
+        each datum is reduced as src -> event -> dst and the data are graphed.
+        by default we have IP.src -> IP.dport -> IP.dst"""
+        if src is None:
+            src = lambda x: x[IP].src
+        if event is None:
+            event = lambda x: x[IP].dport
+        if dst is None:
+            dst = lambda x: x[IP].dst
+        sl = {}
+        el = {}
+        dl = {}
+        for i in self.res:
+            try:
+                s,e,d = src(i),event(i),dst(i)
+                if s in sl:
+                    n,l = sl[s]
+                    n += 1
+                    if e not in l:
+                        l.append(e)
+                    sl[s] = (n,l)
+                else:
+                    sl[s] = (1,[e])
+                if e in el:
+                    n,l = el[e]
+                    n+=1
+                    if d not in l:
+                        l.append(d)
+                    el[e] = (n,l)
+                else:
+                    el[e] = (1,[d])
+                dl[d] = dl.get(d,0)+1
+            except:
+                continue
+
+        import math
+        def normalize(n):
+            return 2+math.log(n)/4.0
+
+        def minmax(x):
+            m,M = min(x),max(x)
+            if m == M:
+                m = 0
+            if M == 0:
+                M = 1
+            return m,M
+
+        mins,maxs = minmax(map(lambda (x,y): x, sl.values()))
+        mine,maxe = minmax(map(lambda (x,y): x, el.values()))
+        mind,maxd = minmax(dl.values())
+    
+        gr = 'digraph "afterglow" {\n\tedge [len=2.5];\n'
+
+        gr += "# src nodes\n"
+        for s in sl:
+            n,l = sl[s]; n = 1+float(n-mins)/(maxs-mins)
+            gr += '"src.%s" [label = "%s", shape=box, fillcolor="#FF0000", style=filled, fixedsize=1, height=%.2f,width=%.2f];\n' % (`s`,`s`,n,n)
+        gr += "# event nodes\n"
+        for e in el:
+            n,l = el[e]; n = n = 1+float(n-mine)/(maxe-mine)
+            gr += '"evt.%s" [label = "%s", shape=circle, fillcolor="#00FFFF", style=filled, fixedsize=1, height=%.2f, width=%.2f];\n' % (`e`,`e`,n,n)
+        for d in dl:
+            n = dl[d]; n = n = 1+float(n-mind)/(maxd-mind)
+            gr += '"dst.%s" [label = "%s", shape=triangle, fillcolor="#0000ff", style=filled, fixedsize=1, height=%.2f, width=%.2f];\n' % (`d`,`d`,n,n)
+
+        gr += "###\n"
+        for s in sl:
+            n,l = sl[s]
+            for e in l:
+                gr += ' "src.%s" -> "evt.%s";\n' % (`s`,`e`) 
+        for e in el:
+            n,l = el[e]
+            for d in l:
+                gr += ' "evt.%s" -> "dst.%s";\n' % (`e`,`d`) 
+            
+        gr += "}"
+        open("/tmp/aze","w").write(gr)
+        return do_graph(gr, **kargs)
+        
+
+        
+    def timeskew_graph(self, ip, **kargs):
+        """Tries to graph the timeskew between the timestamps and real time for a given ip"""
+        res = map(lambda x: self._elt2pkt(x), self.res)
+        b = filter(lambda x:x.haslayer(IP) and x.getlayer(IP).src == ip and x.haslayer(TCP), res)
+        c = []
+        for p in b:
+            opts = p.getlayer(TCP).options
+            for o in opts:
+                if o[0] == "Timestamp":
+                    c.append((p.time,o[1][0]))
+        if not c:
+            warning("No timestamps found in packet list")
+            return
+        d = map(lambda (x,y): (x%2000,((x-c[0][0])-((y-c[0][1])/1000.0))),c)
+        g = Gnuplot.Gnuplot()
+        g.plot(Gnuplot.Data(d,**kargs))
+        return g
+        
+    def _dump_document(self, **kargs):
+        d = pyx.document.document()
+        l = len(self.res)
+        for i in range(len(self.res)):
+            elt = self.res[i]
+            c = self._elt2pkt(elt).canvas_dump(**kargs)
+            cbb = c.bbox()
+            c.text(cbb.left(),cbb.top()+1,r"\font\cmssfont=cmss12\cmssfont{Frame %i/%i}" % (i,l),[pyx.text.size.LARGE])
+            if conf.verb >= 2:
+                os.write(1,".")
+            d.append(pyx.document.page(c, paperformat=pyx.document.paperformat.A4,
+                                       margin=1*pyx.unit.t_cm,
+                                       fittosize=1))
+        return d
+                     
+                 
+
+    def psdump(self, filename = None, **kargs):
+        """Creates a multipage poscript file with a psdump of every packet
+        filename: name of the file to write to. If empty, a temporary file is used and
+                  conf.prog.psreader is called"""
+        d = self._dump_document(**kargs)
+        if filename is None:
+            filename = "/tmp/scapy.psd.%i" % os.getpid()
+            d.writePSfile(filename)
+            os.system("%s %s.ps &" % (conf.prog.psreader,filename))
+        else:
+            d.writePSfile(filename)
+        print
+        
+    def pdfdump(self, filename = None, **kargs):
+        """Creates a PDF file with a psdump of every packet
+        filename: name of the file to write to. If empty, a temporary file is used and
+                  conf.prog.pdfreader is called"""
+        d = self._dump_document(**kargs)
+        if filename is None:
+            filename = "/tmp/scapy.psd.%i" % os.getpid()
+            d.writePDFfile(filename)
+            os.system("%s %s.pdf &" % (conf.prog.pdfreader,filename))
+        else:
+            d.writePDFfile(filename)
+        print
+
+    def sr(self,multi=0):
+        """sr([multi=1]) -> (SndRcvList, PacketList)
+        Matches packets in the list and return ( (matched couples), (unmatched packets) )"""
+        remain = self.res[:]
+        sr = []
+        i = 0
+        while i < len(remain):
+            s = remain[i]
+            j = i
+            while j < len(remain)-1:
+                j += 1
+                r = remain[j]
+                if r.answers(s):
+                    sr.append((s,r))
+                    if multi:
+                        remain[i]._answered=1
+                        remain[j]._answered=2
+                        continue
+                    del(remain[j])
+                    del(remain[i])
+                    i -= 1
+                    break
+            i += 1
+        if multi:
+            remain = filter(lambda x:not hasattr(x,"_answered"), remain)
+        return SndRcvList(sr),PacketList(remain)
+        
+
+
+        
+
+
+class Dot11PacketList(PacketList):
+    def __init__(self, res=None, name="Dot11List", stats=None):
+        if stats is None:
+            stats = [Dot11WEP, Dot11Beacon, UDP, ICMP, TCP]
+
+        PacketList.__init__(self, res, name, stats)
+    def toEthernet(self):
+        data = map(lambda x:x.getlayer(Dot11), filter(lambda x : x.haslayer(Dot11) and x.type == 2, self.res))
+        r2 = []
+        for p in data:
+            q = p.copy()
+            q.unwep()
+            r2.append(Ether()/q.payload.payload.payload) #Dot11/LLC/SNAP/IP
+        return PacketList(r2,name="Ether from %s"%self.listname)
+        
+        
+
+class SndRcvList(PacketList):
+    def __init__(self, res=None, name="Results", stats=None):
+        PacketList.__init__(self, res, name, stats)
+    def _elt2pkt(self, elt):
+        return elt[1]
+    def _elt2sum(self, elt):
+        return "%s ==> %s" % (elt[0].summary(),elt[1].summary()) 
+
+
+class ARPingResult(SndRcvList):
+    def __init__(self, res=None, name="ARPing", stats=None):
+        PacketList.__init__(self, res, name, stats)
+
+    def show(self):
+        for s,r in self.res:
+            print r.sprintf("%Ether.src% %ARP.psrc%")
+
+
+class AS_resolver:
+    server = None
+    options = "-k" 
+    def __init__(self, server=None, port=43, options=None):
+        if server is not None:
+            self.server = server
+        self.port = port
+        if options is not None:
+            self.options = options
+        
+    def _start(self):
+        self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+        self.s.connect((self.server,self.port))
+        if self.options:
+            self.s.send(self.options+"\n")
+            self.s.recv(8192)
+    def _stop(self):
+        self.s.close()
+        
+    def _parse_whois(self, txt):
+        asn,desc = None,""
+        for l in txt.splitlines():
+            if not asn and l.startswith("origin:"):
+                asn = l[7:].strip()
+            if l.startswith("descr:"):
+                if desc:
+                    desc += r"\n"
+                desc += l[6:].strip()
+            if asn is not None and desc:
+                break
+        return asn,desc.strip()
+
+    def _resolve_one(self, ip):
+        self.s.send("%s\n" % ip)
+        x = ""
+        while not ("%" in x  or "source" in x):
+            x += self.s.recv(8192)
+        asn, desc = self._parse_whois(x)
+        return ip,asn,desc
+    def resolve(self, *ips):
+        self._start()
+        ret = []
+        for ip in ips:
+            ip,asn,desc = self._resolve_one(ip)
+            if asn is not None:
+                ret.append((ip,asn,desc))
+        self._stop()
+        return ret
+
+class AS_resolver_riswhois(AS_resolver):
+    server = "riswhois.ripe.net"
+    options = "-k -M -1"
+
+
+class AS_resolver_radb(AS_resolver):
+    server = "whois.ra.net"
+    options = "-k -M"
+    
+
+class AS_resolver_cymru(AS_resolver):
+    server = "whois.cymru.com"
+    options = None
+    def resolve(self, *ips):
+        ASNlist = []
+        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+        s.connect((self.server,self.port))
+        s.send("begin\r\n"+"\r\n".join(ips)+"\r\nend\r\n")
+        r = ""
+        while 1:
+            l = s.recv(8192)
+            if l == "":
+                break
+            r += l
+        s.close()
+        for l in r.splitlines()[1:]:
+            if "|" not in l:
+                continue
+            asn,ip,desc = map(str.strip, l.split("|"))
+            if asn == "NA":
+                continue
+            asn = int(asn)
+            ASNlist.append((ip,asn,desc))
+        return ASNlist
+
+class AS_resolver_multi(AS_resolver):
+    resolvers_list = ( AS_resolver_cymru(),AS_resolver_riswhois(),AS_resolver_radb() )
+    def __init__(self, *reslist):
+        if reslist:
+            self.resolvers_list = reslist
+    def resolve(self, *ips):
+        todo = ips
+        ret = []
+        for ASres in self.resolvers_list:
+            res = ASres.resolve(*todo)
+            resolved = [ ip for ip,asn,desc in res ]
+            todo = [ ip for ip in todo if ip not in resolved ]
+            ret += res
+        return ret
+    
+    
+
+class TracerouteResult(SndRcvList):
+    def __init__(self, res=None, name="Traceroute", stats=None):
+        PacketList.__init__(self, res, name, stats)
+        self.graphdef = None
+        self.graphASres = 0
+        self.padding = 0
+        self.hloc = None
+        self.nloc = None
+
+    def show(self):
+        return self.make_table(lambda (s,r): (s.sprintf("%IP.dst%:{TCP:tcp%ir,TCP.dport%}{UDP:udp%ir,UDP.dport%}{ICMP:ICMP}"),
+                                              s.ttl,
+                                              r.sprintf("%-15s,IP.src% {TCP:%TCP.flags%}{ICMP:%ir,ICMP.type%}")))
+
+
+    def get_trace(self):
+        trace = {}
+        for s,r in self.res:
+            if IP not in s:
+                continue
+            d = s[IP].dst
+            if d not in trace:
+                trace[d] = {}
+            trace[d][s[IP].ttl] = r[IP].src, ICMP not in r
+        for k in trace.values():
+            m = filter(lambda x:k[x][1], k.keys())
+            if not m:
+                continue
+            m = min(m)
+            for l in k.keys():
+                if l > m:
+                    del(k[l])
+        return trace
+
+    def trace3D(self):
+        """Give a 3D representation of the traceroute.
+        right button: rotate the scene
+        middle button: zoom
+        left button: move the scene
+        left button on a ball: toggle IP displaying
+        ctrl-left button on a ball: scan ports 21,22,23,25,80 and 443 and display the result"""
+        trace = self.get_trace()
+        import visual
+
+        class IPsphere(visual.sphere):
+            def __init__(self, ip, **kargs):
+                visual.sphere.__init__(self, **kargs)
+                self.ip=ip
+                self.label=None
+                self.setlabel(self.ip)
+            def setlabel(self, txt,visible=None):
+                if self.label is not None:
+                    if visible is None:
+                        visible = self.label.visible
+                    self.label.visible = 0
+                elif visible is None:
+                    visible=0
+                self.label=visual.label(text=txt, pos=self.pos, space=self.radius, xoffset=10, yoffset=20, visible=visible)
+            def action(self):
+                self.label.visible ^= 1
+
+        visual.scene = visual.display()
+        visual.scene.exit_on_close(0)
+        start = visual.box()
+        rings={}
+        tr3d = {}
+        for i in trace:
+            tr = trace[i]
+            tr3d[i] = []
+            ttl = tr.keys()
+            for t in range(1,max(ttl)+1):
+                if t not in rings:
+                    rings[t] = []
+                if t in tr:
+                    if tr[t] not in rings[t]:
+                        rings[t].append(tr[t])
+                    tr3d[i].append(rings[t].index(tr[t]))
+                else:
+                    rings[t].append(("unk",-1))
+                    tr3d[i].append(len(rings[t])-1)
+        for t in rings:
+            r = rings[t]
+            l = len(r)
+            for i in range(l):
+                if r[i][1] == -1:
+                    col = (0.75,0.75,0.75)
+                elif r[i][1]:
+                    col = visual.color.green
+                else:
+                    col = visual.color.blue
+                
+                s = IPsphere(pos=((l-1)*visual.cos(2*i*visual.pi/l),(l-1)*visual.sin(2*i*visual.pi/l),2*t),
+                             ip = r[i][0],
+                             color = col)
+                for trlst in tr3d.values():
+                    if t <= len(trlst):
+                        if trlst[t-1] == i:
+                            trlst[t-1] = s
+        forecol = colgen(0.625, 0.4375, 0.25, 0.125)
+        for trlst in tr3d.values():
+            col = forecol.next()
+            start = (0,0,0)
+            for ip in trlst:
+                visual.cylinder(pos=start,axis=ip.pos-start,color=col,radius=0.2)
+                start = ip.pos
+        
+        movcenter=None
+        while 1:
+            if visual.scene.kb.keys:
+                k = visual.scene.kb.getkey()
+                if k == "esc":
+                    break
+            if visual.scene.mouse.events:
+                ev = visual.scene.mouse.getevent()
+                if ev.press == "left":
+                    o = ev.pick
+                    if o:
+                        if ev.ctrl:
+                            if o.ip == "unk":
+                                continue
+                            savcolor = o.color
+                            o.color = (1,0,0)
+                            a,b=sr(IP(dst=o.ip)/TCP(dport=[21,22,23,25,80,443]),timeout=2)
+                            o.color = savcolor
+                            if len(a) == 0:
+                                txt = "%s:\nno results" % o.ip
+                            else:
+                                txt = "%s:\n" % o.ip
+                                for s,r in a:
+                                    txt += r.sprintf("{TCP:%IP.src%:%TCP.sport% %TCP.flags%}{TCPerror:%IPerror.dst%:%TCPerror.dport% %IP.src% %ir,ICMP.type%}\n")
+                            o.setlabel(txt, visible=1)
+                        else:
+                            if hasattr(o, "action"):
+                                o.action()
+                elif ev.drag == "left":
+                    movcenter = ev.pos
+                elif ev.drop == "left":
+                    movcenter = None
+            if movcenter:
+                visual.scene.center -= visual.scene.mouse.pos-movcenter
+                movcenter = visual.scene.mouse.pos
+                
+                
+    def world_trace(self):
+        ips = {}
+        rt = {}
+        ports_done = {}
+        for s,r in self.res:
+            ips[r.src] = None
+            if s.haslayer(TCP) or s.haslayer(UDP):
+                trace_id = (s.src,s.dst,s.proto,s.dport)
+            elif s.haslayer(ICMP):
+                trace_id = (s.src,s.dst,s.proto,s.type)
+            else:
+                trace_id = (s.src,s.dst,s.proto,0)
+            trace = rt.get(trace_id,{})
+            if not r.haslayer(ICMP) or r.type != 11:
+                if ports_done.has_key(trace_id):
+                    continue
+                ports_done[trace_id] = None
+            trace[s.ttl] = r.src
+            rt[trace_id] = trace
+
+        trt = {}
+        for trace_id in rt:
+            trace = rt[trace_id]
+            loctrace = []
+            for i in range(max(trace.keys())):
+                ip = trace.get(i,None)
+                if ip is None:
+                    continue
+                loc = locate_ip(ip)
+                if loc is None:
+                    continue
+#                loctrace.append((ip,loc)) # no labels yet
+                loctrace.append(loc)
+            if loctrace:
+                trt[trace_id] = loctrace
+
+        tr = map(lambda x: Gnuplot.Data(x,with="lines"), trt.values())
+        g = Gnuplot.Gnuplot()
+        world = Gnuplot.File(conf.gnuplot_world,with="lines")
+        g.plot(world,*tr)
+        return g
+
+    def make_graph(self,ASres=None,padding=0):
+        if ASres is None:
+            ASres = conf.AS_resolver
+        self.graphASres = ASres
+        self.graphpadding = padding
+        ips = {}
+        rt = {}
+        ports = {}
+        ports_done = {}
+        for s,r in self.res:
+            r = r[IP] or r[IPv6] or r
+            s = s[IP] or s[IPv6] or s
+            ips[r.src] = None
+            if TCP in s:
+                trace_id = (s.src,s.dst,6,s.dport)
+            elif UDP in s:
+                trace_id = (s.src,s.dst,17,s.dport)
+            elif ICMP in s:
+                trace_id = (s.src,s.dst,1,s.type)
+            else:
+                trace_id = (s.src,s.dst,s.proto,0)
+            trace = rt.get(trace_id,{})
+            ttl = IPv6 in s and s.hlim or s.ttl
+            if not (ICMP in r and r[ICMP].type == 11) and not (IPv6 in r and ICMPv6TimeExceeded in r):
+                if trace_id in ports_done:
+                    continue
+                ports_done[trace_id] = None
+                p = ports.get(r.src,[])
+                if TCP in r:
+                    p.append(r.sprintf("<T%ir,TCP.sport%> %TCP.sport% %TCP.flags%"))
+                    trace[ttl] = r.sprintf('"%r,src%":T%ir,TCP.sport%')
+                elif UDP in r:
+                    p.append(r.sprintf("<U%ir,UDP.sport%> %UDP.sport%"))
+                    trace[ttl] = r.sprintf('"%r,src%":U%ir,UDP.sport%')
+                elif ICMP in r:
+                    p.append(r.sprintf("<I%ir,ICMP.type%> ICMP %ICMP.type%"))
+                    trace[ttl] = r.sprintf('"%r,src%":I%ir,ICMP.type%')
+                else:
+                    p.append(r.sprintf("{IP:<P%ir,proto%> IP %proto%}{IPv6:<P%ir,nh%> IPv6 %nh%}"))
+                    trace[ttl] = r.sprintf('"%r,src%":{IP:P%ir,proto%}{IPv6:P%ir,nh%}')
+                ports[r.src] = p
+            else:
+                trace[ttl] = r.sprintf('"%r,src%"')
+            rt[trace_id] = trace
+    
+        # Fill holes with unk%i nodes
+        unknown_label = incremental_label("unk%i")
+        blackholes = []
+        bhip = {}
+        for rtk in rt:
+            trace = rt[rtk]
+            k = trace.keys()
+            for n in range(min(k), max(k)):
+                if not trace.has_key(n):
+                    trace[n] = unknown_label.next()
+            if not ports_done.has_key(rtk):
+                if rtk[2] == 1: #ICMP
+                    bh = "%s %i/icmp" % (rtk[1],rtk[3])
+                elif rtk[2] == 6: #TCP
+                    bh = "%s %i/tcp" % (rtk[1],rtk[3])
+                elif rtk[2] == 17: #UDP                    
+                    bh = '%s %i/udp' % (rtk[1],rtk[3])
+                else:
+                    bh = '%s %i/proto' % (rtk[1],rtk[2]) 
+                ips[bh] = None
+                bhip[rtk[1]] = bh
+                bh = '"%s"' % bh
+                trace[max(k)+1] = bh
+                blackholes.append(bh)
+    
+        # Find AS numbers
+        ASN_query_list = dict.fromkeys(map(lambda x:x.rsplit(" ",1)[0],ips)).keys()
+        if ASres is None:            
+            ASNlist = []
+        else:
+            ASNlist = ASres.resolve(*ASN_query_list)            
+    
+        ASNs = {}
+        ASDs = {}
+        for ip,asn,desc, in ASNlist:
+            if asn is None:
+                continue
+            iplist = ASNs.get(asn,[])
+            if ip in bhip:
+                if ip in ports:
+                    iplist.append(ip)
+                iplist.append(bhip[ip])
+            else:
+                iplist.append(ip)
+            ASNs[asn] = iplist
+            ASDs[asn] = desc
+    
+    
+        backcolorlist=colgen("60","86","ba","ff")
+        forecolorlist=colgen("a0","70","40","20")
+    
+        s = "digraph trace {\n"
+    
+        s += "\n\tnode [shape=ellipse,color=black,style=solid];\n\n"
+    
+        s += "\n#ASN clustering\n"
+        for asn in ASNs:
+            s += '\tsubgraph cluster_%s {\n' % asn
+            col = backcolorlist.next()
+            s += '\t\tcolor="#%s%s%s";' % col
+            s += '\t\tnode [fillcolor="#%s%s%s",style=filled];' % col
+            s += '\t\tfontsize = 10;'
+            s += '\t\tlabel = "%s\\n[%s]"\n' % (asn,ASDs[asn])
+            for ip in ASNs[asn]:
+    
+                s += '\t\t"%s";\n'%ip
+            s += "\t}\n"
+    
+    
+    
+    
+        s += "#endpoints\n"
+        for p in ports:
+            s += '\t"%s" [shape=record,color=black,fillcolor=green,style=filled,label="%s|%s"];\n' % (p,p,"|".join(ports[p]))
+    
+        s += "\n#Blackholes\n"
+        for bh in blackholes:
+            s += '\t%s [shape=octagon,color=black,fillcolor=red,style=filled];\n' % bh
+
+        if padding:
+            s += "\n#Padding\n"
+            pad={}
+            for snd,rcv in self.res:
+                if rcv.src not in ports and rcv.haslayer(Padding):
+                    p = rcv.getlayer(Padding).load
+                    if p != "\x00"*len(p):
+                        pad[rcv.src]=None
+            for rcv in pad:
+                s += '\t"%s" [shape=triangle,color=black,fillcolor=red,style=filled];\n' % rcv
+    
+    
+            
+        s += "\n\tnode [shape=ellipse,color=black,style=solid];\n\n"
+    
+    
+        for rtk in rt:
+            s += "#---[%s\n" % `rtk`
+            s += '\t\tedge [color="#%s%s%s"];\n' % forecolorlist.next()
+            trace = rt[rtk]
+            k = trace.keys()
+            for n in range(min(k), max(k)):
+                s += '\t%s ->\n' % trace[n]
+            s += '\t%s;\n' % trace[max(k)]
+    
+        s += "}\n";
+        self.graphdef = s
+    
+    def graph(self, ASres=None, padding=0, **kargs):
+        """x.graph(ASres=conf.AS_resolver, other args):
+        ASres=None          : no AS resolver => no clustering
+        ASres=AS_resolver() : default whois AS resolver (riswhois.ripe.net)
+        ASres=AS_resolver_cymru(): use whois.cymru.com whois database
+        ASres=AS_resolver(server="whois.ra.net")
+        type: output type (svg, ps, gif, jpg, etc.), passed to dot's "-T" option
+        target: filename or redirect. Defaults pipe to Imagemagick's display program
+        prog: which graphviz program to use"""
+        if ASres is None:
+            ASres = conf.AS_resolver
+        if (self.graphdef is None or
+            self.graphASres != ASres or
+            self.graphpadding != padding):
+            self.make_graph(ASres,padding)
+
+        return do_graph(self.graphdef, **kargs)
+
+
+conf.AS_resolver = AS_resolver_multi()
+        
diff --git a/scapy/queso.py b/scapy/queso.py
new file mode 100644
index 0000000000000000000000000000000000000000..92daa32e2eb16adcd58b99800db68aacdb8bb2b6
--- /dev/null
+++ b/scapy/queso.py
@@ -0,0 +1,98 @@
+from scapy.data import KnowledgeBase
+from scapy.config import conf
+
+#################
+## Queso stuff ##
+#################
+
+
+def quesoTCPflags(flags):
+    if flags == "-":
+        return "-"
+    flv = "FSRPAUXY"
+    v = 0
+    for i in flags:
+        v |= 2**flv.index(i)
+    return "%x" % v
+
+class QuesoKnowledgeBase(KnowledgeBase):
+    def lazy_init(self):
+        try:
+            f = open(self.filename)
+        except IOError:
+            return
+        self.base = {}
+        p = None
+        try:
+            for l in f:
+                l = l.strip()
+                if not l or l[0] == ';':
+                    continue
+                if l[0] == '*':
+                    if p is not None:
+                        p[""] = name
+                    name = l[1:].strip()
+                    p = self.base
+                    continue
+                if l[0] not in list("0123456"):
+                    continue
+                res = l[2:].split()
+                res[-1] = quesoTCPflags(res[-1])
+                res = " ".join(res)
+                if not p.has_key(res):
+                    p[res] = {}
+                p = p[res]
+            if p is not None:
+                p[""] = name
+        except:
+            self.base = None
+            warning("Can't load queso base [%s]", self.filename)
+        f.close()
+            
+        
+queso_kdb = QuesoKnowledgeBase(conf.queso_base)
+
+    
+def queso_sig(target, dport=80, timeout=3):
+    p = queso_kdb.get_base()
+    ret = []
+    for flags in ["S", "SA", "F", "FA", "SF", "P", "SEC"]:
+        ans, unans = sr(IP(dst=target)/TCP(dport=dport,flags=flags,seq=RandInt()),
+                        timeout=timeout, verbose=0)
+        if len(ans) == 0:
+            rs = "- - - -"
+        else:
+            s,r = ans[0]
+            rs = "%i" % (r.seq != 0)
+            if not r.ack:
+                r += " 0"
+            elif r.ack-s.seq > 666:
+                rs += " R" % 0
+            else:
+                rs += " +%i" % (r.ack-s.seq)
+            rs += " %X" % r.window
+            rs += " %x" % r.payload.flags
+        ret.append(rs)
+    return ret
+            
+def queso_search(sig):
+    p = queso_kdb.get_base()
+    sig.reverse()
+    ret = []
+    try:
+        while sig:
+            s = sig.pop()
+            p = p[s]
+            if p.has_key(""):
+                ret.append(p[""])
+    except KeyError:
+        pass
+    return ret
+        
+
+def queso(*args,**kargs):
+    """Queso OS fingerprinting
+queso(target, dport=80, timeout=3)"""
+    return queso_search(queso_sig(*args, **kargs))
+
+
diff --git a/scapy/route.py b/scapy/route.py
new file mode 100644
index 0000000000000000000000000000000000000000..d7cd7646610816dc66c161028b076ffa4cb04d57
--- /dev/null
+++ b/scapy/route.py
@@ -0,0 +1,157 @@
+import socket
+from arch import read_routes
+from utils import atol
+from config import conf
+
+##############################
+## Routing/Interfaces stuff ##
+##############################
+
+class Route:
+    def __init__(self):
+        self.resync()
+        self.s=socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+        self.cache = {}
+
+    def invalidate_cache(self):
+        self.cache = {}
+
+    def resync(self):
+        self.invalidate_cache()
+        self.routes = read_routes()
+
+    def __repr__(self):
+        rt = "Network         Netmask         Gateway         Iface           Output IP\n"
+        for net,msk,gw,iface,addr in self.routes:
+            rt += "%-15s %-15s %-15s %-15s %-15s\n" % (ltoa(net),
+                                              ltoa(msk),
+                                              gw,
+                                              iface,
+                                              addr)
+        return rt
+
+    def make_route(self, host=None, net=None, gw=None, dev=None):
+        if host is not None:
+            thenet,msk = host,32
+        elif net is not None:
+            thenet,msk = net.split("/")
+            msk = int(msk)
+        else:
+            raise Scapy_Exception("make_route: Incorrect parameters. You should specify a host or a net")
+        if gw is None:
+            gw="0.0.0.0"
+        if dev is None:
+            if gw:
+                nhop = gw
+            else:
+                nhop = thenet
+            dev,ifaddr,x = self.route(nhop)
+        else:
+            ifaddr = get_if_addr(dev)
+        return (atol(thenet), itom(msk), gw, dev, ifaddr)
+
+    def add(self, *args, **kargs):
+        """Ex:
+        add(net="192.168.1.0/24",gw="1.2.3.4")
+        """
+        self.invalidate_cache()
+        self.routes.append(self.make_route(*args,**kargs))
+
+        
+    def delt(self,  *args, **kargs):
+        """delt(host|net, gw|dev)"""
+        self.invalidate_cache()
+        route = self.make_route(*args,**kargs)
+        try:
+            i=self.routes.index(route)
+            del(self.routes[i])
+        except ValueError:
+            warning("no matching route found")
+             
+    def ifchange(self, iff, addr):
+        self.invalidate_cache()
+        the_addr,the_msk = (addr.split("/")+["32"])[:2]
+        the_msk = itom(int(the_msk))
+        the_rawaddr = atol(the_addr)
+        the_net = the_rawaddr & the_msk
+        
+        
+        for i in range(len(self.routes)):
+            net,msk,gw,iface,addr = self.routes[i]
+            if iface != iff:
+                continue
+            if gw == '0.0.0.0':
+                self.routes[i] = (the_net,the_msk,gw,iface,the_addr)
+            else:
+                self.routes[i] = (net,msk,gw,iface,the_addr)
+        for i in arp_cache.keys():
+            del(arp_cache[i])
+        
+                
+
+    def ifdel(self, iff):
+        self.invalidate_cache()
+        new_routes=[]
+        for rt in self.routes:
+            if rt[3] != iff:
+                new_routes.append(rt)
+        self.routes=new_routes
+        
+    def ifadd(self, iff, addr):
+        self.invalidate_cache()
+        the_addr,the_msk = (addr.split("/")+["32"])[:2]
+        the_msk = itom(int(the_msk))
+        the_rawaddr = atol(the_addr)
+        the_net = the_rawaddr & the_msk
+        self.routes.append((the_net,the_msk,'0.0.0.0',iff,the_addr))
+
+
+    def route(self,dest,verbose=None):
+        if dest in self.cache:
+            return self.cache[dest]
+        if verbose is None:
+            verbose=conf.verb
+        # Transform "192.168.*.1-5" to one IP of the set
+        dst = dest.split("/")[0]
+        dst = dst.replace("*","0") 
+        while 1:
+            l = dst.find("-")
+            if l < 0:
+                break
+            m = (dst[l:]+".").find(".")
+            dst = dst[:l]+dst[l+m:]
+
+            
+        dst = atol(dst)
+        pathes=[]
+        for d,m,gw,i,a in self.routes:
+            aa = atol(a)
+            if aa == dst:
+                pathes.append((0xffffffffL,("lo",a,"0.0.0.0")))
+            if (dst & m) == (d & m):
+                pathes.append((m,(i,a,gw)))
+        if not pathes:
+            if verbose:
+                warning("No route found (no default route?)")
+            return "lo","0.0.0.0","0.0.0.0" #XXX linux specific!
+        # Choose the more specific route (greatest netmask).
+        # XXX: we don't care about metrics
+        pathes.sort()
+        ret = pathes[-1][1]
+        self.cache[dest] = ret
+        return ret
+            
+    def get_if_bcast(self, iff):
+        for net, msk, gw, iface, addr in self.routes:
+            if (iff == iface and net != 0L):
+                bcast = atol(addr)|(~msk&0xffffffffL); # FIXME: check error in atol()
+                return ltoa(bcast);
+        warning("No broadcast address found for iface %s\n" % iff);
+
+conf.route=Route()
+
+#XXX use "with"
+_betteriface = conf.route.route("0.0.0.0", verbose=0)[0]
+if _betteriface != "lo": #XXX linux specific...
+    conf.iface = _betteriface
+del(_betteriface)
diff --git a/scapy/sendrecv.py b/scapy/sendrecv.py
new file mode 100644
index 0000000000000000000000000000000000000000..03ce3658921fe7faedc164e7c0fe2c6a4d0243b5
--- /dev/null
+++ b/scapy/sendrecv.py
@@ -0,0 +1,547 @@
+import cPickle,os,sys,time
+from select import select
+from data import *
+from config import conf
+
+
+#################
+## Debug class ##
+#################
+
+class debug:
+    recv=[]
+    sent=[]
+    match=[]
+
+
+####################
+## Send / Receive ##
+####################
+
+
+
+
+def sndrcv(pks, pkt, timeout = 2, inter = 0, verbose=None, chainCC=0, retry=0, multi=0):
+    if not isinstance(pkt, Gen):
+        pkt = SetGen(pkt)
+        
+    if verbose is None:
+        verbose = conf.verb
+    debug.recv = PacketList([],"Unanswered")
+    debug.sent = PacketList([],"Sent")
+    debug.match = SndRcvList([])
+    nbrecv=0
+    ans = []
+    # do it here to fix random fields, so that parent and child have the same
+    all_stimuli = tobesent = [p for p in pkt]
+    notans = len(tobesent)
+
+    hsent={}
+    for i in tobesent:
+        h = i.hashret()
+        if h in hsent:
+            hsent[h].append(i)
+        else:
+            hsent[h] = [i]
+    if retry < 0:
+        retry = -retry
+        autostop=retry
+    else:
+        autostop=0
+
+
+    while retry >= 0:
+        found=0
+    
+        if timeout < 0:
+            timeout = None
+            
+        rdpipe,wrpipe = os.pipe()
+        rdpipe=os.fdopen(rdpipe)
+        wrpipe=os.fdopen(wrpipe,"w")
+
+        pid=1
+        try:
+            pid = os.fork()
+            if pid == 0:
+                try:
+                    sys.stdin.close()
+                    rdpipe.close()
+                    try:
+                        i = 0
+                        if verbose:
+                            print "Begin emission:"
+                        for p in tobesent:
+                            pks.send(p)
+                            i += 1
+                            time.sleep(inter)
+                        if verbose:
+                            print "Finished to send %i packets." % i
+                    except SystemExit:
+                        pass
+                    except KeyboardInterrupt:
+                        pass
+                    except:
+                        log_runtime.exception("--- Error in child %i" % os.getpid())
+                        log_runtime.info("--- Error in child %i" % os.getpid())
+                finally:
+                    try:
+                        os.setpgrp() # Chance process group to avoid ctrl-C
+                        sent_times = [p.sent_time for p in all_stimuli if p.sent_time]
+                        cPickle.dump( (arp_cache,sent_times), wrpipe )
+                        wrpipe.close()
+                    except:
+                        pass
+            elif pid < 0:
+                log_runtime.error("fork error")
+            else:
+                wrpipe.close()
+                stoptime = 0
+                remaintime = None
+                inmask = [rdpipe,pks]
+                try:
+                    try:
+                        while 1:
+                            if stoptime:
+                                remaintime = stoptime-time.time()
+                                if remaintime <= 0:
+                                    break
+                            r = None
+                            if FREEBSD or DARWIN:
+                                inp, out, err = select(inmask,[],[], 0.05)
+                                if len(inp) == 0 or pks in inp:
+                                    r = pks.nonblock_recv()
+                            else:
+                                inp, out, err = select(inmask,[],[], remaintime)
+                                if len(inp) == 0:
+                                    break
+                                if pks in inp:
+                                    r = pks.recv(MTU)
+                            if rdpipe in inp:
+                                if timeout:
+                                    stoptime = time.time()+timeout
+                                del(inmask[inmask.index(rdpipe)])
+                            if r is None:
+                                continue
+                            ok = 0
+                            h = r.hashret()
+                            if h in hsent:
+                                hlst = hsent[h]
+                                for i in range(len(hlst)):
+                                    if r.answers(hlst[i]):
+                                        ans.append((hlst[i],r))
+                                        if verbose > 1:
+                                            os.write(1, "*")
+                                        ok = 1                                
+                                        if not multi:
+                                            del(hlst[i])
+                                            notans -= 1;
+                                        else:
+                                            if not hasattr(hlst[i], '_answered'):
+                                                notans -= 1;
+                                            hlst[i]._answered = 1;
+                                        break
+                            if notans == 0 and not multi:
+                                break
+                            if not ok:
+                                if verbose > 1:
+                                    os.write(1, ".")
+                                nbrecv += 1
+                                if conf.debug_match:
+                                    debug.recv.append(r)
+                    except KeyboardInterrupt:
+                        if chainCC:
+                            raise
+                finally:
+                    try:
+                        ac,sent_times = cPickle.load(rdpipe)
+                    except EOFError:
+                        warning("Child died unexpectedly. Packets may have not been sent %i"%os.getpid())
+                    else:
+                        arp_cache.update(ac)
+                        for p,t in zip(all_stimuli, sent_times):
+                            p.sent_time = t
+                    os.waitpid(pid,0)
+        finally:
+            if pid == 0:
+                os._exit(0)
+
+        remain = reduce(list.__add__, hsent.values(), [])
+        if multi:
+            remain = filter(lambda p: not hasattr(p, '_answered'), remain);
+            
+        if autostop and len(remain) > 0 and len(remain) != len(tobesent):
+            retry = autostop
+            
+        tobesent = remain
+        if len(tobesent) == 0:
+            break
+        retry -= 1
+        
+    if conf.debug_match:
+        debug.sent=PacketList(remain[:],"Sent")
+        debug.match=SndRcvList(ans[:])
+
+    #clean the ans list to delete the field _answered
+    if (multi):
+        for s,r in ans:
+            if hasattr(s, '_answered'):
+                del(s._answered)
+    
+    if verbose:
+        print "\nReceived %i packets, got %i answers, remaining %i packets" % (nbrecv+len(ans), len(ans), notans)
+    return SndRcvList(ans),PacketList(remain,"Unanswered"),debug.recv
+
+
+def __gen_send(s, x, inter=0, loop=0, count=None, verbose=None, *args, **kargs):
+    if not isinstance(x, Gen):
+        x = SetGen(x)
+    if verbose is None:
+        verbose = conf.verb
+    n = 0
+    if count is not None:
+        loop = -count
+    elif not loop:
+        loop=-1
+    try:
+        while loop:
+            for p in x:
+                s.send(p)
+                n += 1
+                if verbose:
+                    os.write(1,".")
+                time.sleep(inter)
+            if loop < 0:
+                loop += 1
+    except KeyboardInterrupt:
+        pass
+    s.close()
+    if verbose:
+        print "\nSent %i packets." % n
+
+def send(x, inter=0, loop=0, count=None, verbose=None, *args, **kargs):
+    """Send packets at layer 3
+send(packets, [inter=0], [loop=0], [verbose=conf.verb]) -> None"""
+    __gen_send(conf.L3socket(*args, **kargs), x, inter=inter, loop=loop, count=count,verbose=verbose)
+
+def sendp(x, inter=0, loop=0, iface=None, iface_hint=None, count=None, verbose=None, *args, **kargs):
+    """Send packets at layer 2
+sendp(packets, [inter=0], [loop=0], [verbose=conf.verb]) -> None"""
+    if iface is None and iface_hint is not None:
+        iface = conf.route.route(iface_hint)[0]
+    __gen_send(conf.L2socket(iface=iface, *args, **kargs), x, inter=inter, loop=loop, count=count, verbose=verbose)
+
+def sendpfast(x, pps=None, mbps=None, realtime=None, loop=0, iface=None):
+    """Send packets at layer 2 using tcpreplay for performance
+    pps:  packets per second
+    mpbs: MBits per second
+    realtime: use packet's timestamp, bending time with realtime value
+    loop: number of times to process the packet list
+    iface: output interface """
+    if iface is None:
+        iface = conf.iface
+    options = ["--intf1=%s" % iface ]
+    if pps is not None:
+        options.append("--pps=%i" % pps)
+    elif mbps is not None:
+        options.append("--mbps=%i" % mbps)
+    elif realtime is not None:
+        options.append("--multiplier=%i" % realtime)
+    else:
+        options.append("--topspeed")
+
+    if loop:
+        options.append("--loop=%i" % loop)
+
+    f = os.tempnam("scapy")
+    options.append(f)
+    wrpcap(f, x)
+    try:
+        try:
+            os.spawnlp(os.P_WAIT, conf.prog.tcpreplay, conf.prog.tcpreplay, *options)
+        except KeyboardInterrupt:
+            log_interactive.info("Interrupted by user")
+    finally:
+        os.unlink(f)
+
+        
+
+        
+    
+def sr(x,filter=None, iface=None, nofilter=0, *args,**kargs):
+    """Send and receive packets at layer 3
+nofilter: put 1 to avoid use of bpf filters
+retry:    if positive, how many times to resend unanswered packets
+          if negative, how many times to retry when no more packets are answered
+timeout:  how much time to wait after the last packet has been sent
+verbose:  set verbosity level
+multi:    whether to accept multiple answers for the same stimulus
+filter:   provide a BPF filter
+iface:    listen answers only on the given interface"""
+    if not kargs.has_key("timeout"):
+        kargs["timeout"] = -1
+    s = conf.L3socket(filter=filter, iface=iface, nofilter=nofilter)
+    a,b,c=sndrcv(s,x,*args,**kargs)
+    s.close()
+    return a,b
+
+def sr1(x,filter=None,iface=None, nofilter=0, *args,**kargs):
+    """Send packets at layer 3 and return only the first answer
+nofilter: put 1 to avoid use of bpf filters
+retry:    if positive, how many times to resend unanswered packets
+          if negative, how many times to retry when no more packets are answered
+timeout:  how much time to wait after the last packet has been sent
+verbose:  set verbosity level
+multi:    whether to accept multiple answers for the same stimulus
+filter:   provide a BPF filter
+iface:    listen answers only on the given interface"""
+    if not kargs.has_key("timeout"):
+        kargs["timeout"] = -1
+    s=conf.L3socket(filter=filter, nofilter=nofilter, iface=iface)
+    a,b,c=sndrcv(s,x,*args,**kargs)
+    s.close()
+    if len(a) > 0:
+        return a[0][1]
+    else:
+        return None
+
+def srp(x,iface=None, iface_hint=None, filter=None, nofilter=0, type=ETH_P_ALL, *args,**kargs):
+    """Send and receive packets at layer 2
+nofilter: put 1 to avoid use of bpf filters
+retry:    if positive, how many times to resend unanswered packets
+          if negative, how many times to retry when no more packets are answered
+timeout:  how much time to wait after the last packet has been sent
+verbose:  set verbosity level
+multi:    whether to accept multiple answers for the same stimulus
+filter:   provide a BPF filter
+iface:    work only on the given interface"""
+    if not kargs.has_key("timeout"):
+        kargs["timeout"] = -1
+    if iface is None and iface_hint is not None:
+        iface = conf.route.route(iface_hint)[0]
+    s = conf.L2socket(iface=iface, filter=filter, nofilter=nofilter, type=type)
+    a,b,c=sndrcv(s ,x,*args,**kargs)
+    s.close()
+    return a,b
+
+def srp1(*args,**kargs):
+    """Send and receive packets at layer 2 and return only the first answer
+nofilter: put 1 to avoid use of bpf filters
+retry:    if positive, how many times to resend unanswered packets
+          if negative, how many times to retry when no more packets are answered
+timeout:  how much time to wait after the last packet has been sent
+verbose:  set verbosity level
+multi:    whether to accept multiple answers for the same stimulus
+filter:   provide a BPF filter
+iface:    work only on the given interface"""
+    if not kargs.has_key("timeout"):
+        kargs["timeout"] = -1
+    a,b=srp(*args,**kargs)
+    if len(a) > 0:
+        return a[0][1]
+    else:
+        return None
+
+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):
+    n = 0
+    r = 0
+    ct = conf.color_theme
+    if verbose is None:
+        verbose = conf.verb
+    parity = 0
+    ans=[]
+    unans=[]
+    if timeout is None:
+        timeout = min(2*inter, 5)
+    try:
+        while 1:
+            parity ^= 1
+            col = [ct.even,ct.odd][parity]
+            if count is not None:
+                if count == 0:
+                    break
+                count -= 1
+            start = time.time()
+            print "\rsend...\r",
+            res = srfunc(pkts, timeout=timeout, verbose=0, chainCC=1, *args, **kargs)
+            n += len(res[0])+len(res[1])
+            r += len(res[0])
+            if verbose > 1 and prn and len(res[0]) > 0:
+                msg = "RECV %i:" % len(res[0])
+                print  "\r"+ct.success(msg),
+                for p in res[0]:
+                    print col(prn(p))
+                    print " "*len(msg),
+            if verbose > 1 and prnfail and len(res[1]) > 0:
+                msg = "fail %i:" % len(res[1])
+                print "\r"+ct.fail(msg),
+                for p in res[1]:
+                    print col(prnfail(p))
+                    print " "*len(msg),
+            if verbose > 1 and not (prn or prnfail):
+                print "recv:%i  fail:%i" % tuple(map(len, res[:2]))
+            if store:
+                ans += res[0]
+                unans += res[1]
+            end=time.time()
+            if end-start < inter:
+                time.sleep(inter+start-end)
+    except KeyboardInterrupt:
+        pass
+ 
+    if verbose and n>0:
+        print ct.normal("\nSent %i packets, received %i packets. %3.1f%% hits." % (n,r,100.0*r/n))
+    return SndRcvList(ans),PacketList(unans)
+
+def srloop(pkts, *args, **kargs):
+    """Send a packet at layer 3 in loop and print the answer each time
+srloop(pkts, [prn], [inter], [count], ...) --> None"""
+    return __sr_loop(sr, pkts, *args, **kargs)
+
+def srploop(pkts, *args, **kargs):
+    """Send a packet at layer 2 in loop and print the answer each time
+srloop(pkts, [prn], [inter], [count], ...) --> None"""
+    return __sr_loop(srp, pkts, *args, **kargs)
+
+
+def sndrcvflood(pks, pkt, prn=lambda (s,r):r.summary(), chainCC=0, store=1, unique=0):
+    if not isinstance(pkt, Gen):
+        pkt = SetGen(pkt)
+    tobesent = [p for p in pkt]
+    received = SndRcvList()
+    seen = {}
+
+    hsent={}
+    for i in tobesent:
+        h = i.hashret()
+        if h in hsent:
+            hsent[h].append(i)
+        else:
+            hsent[h] = [i]
+
+    def send_in_loop(tobesent):
+        while 1:
+            for p in tobesent:
+                yield p
+
+    packets_to_send = send_in_loop(tobesent)
+
+    ssock = rsock = pks.fileno()
+
+    try:
+        while 1:
+            readyr,readys,_ = select([rsock],[ssock],[])
+            if ssock in readys:
+                pks.send(packets_to_send.next())
+                
+            if rsock in readyr:
+                p = pks.recv(MTU)
+                if p is None:
+                    continue
+                h = p.hashret()
+                if h in hsent:
+                    hlst = hsent[h]
+                    for i in hlst:
+                        if p.answers(i):
+                            res = prn((i,p))
+                            if unique:
+                                if res in seen:
+                                    continue
+                                seen[res] = None
+                            if res is not None:
+                                print res
+                            if store:
+                                received.append((i,p))
+    except KeyboardInterrupt:
+        if chainCC:
+            raise
+    return received
+
+def srflood(x,filter=None, iface=None, nofilter=None, *args,**kargs):
+    """Flood and receive packets at layer 3
+prn:      function applied to packets received. Ret val is printed if not None
+store:    if 1 (default), store answers and return them
+unique:   only consider packets whose print 
+nofilter: put 1 to avoid use of bpf filters
+filter:   provide a BPF filter
+iface:    listen answers only on the given interface"""
+    s = conf.L3socket(filter=filter, iface=iface, nofilter=nofilter)
+    r=sndrcvflood(s,x,*args,**kargs)
+    s.close()
+    return r
+
+def srpflood(x,filter=None, iface=None, iface_hint=None, nofilter=None, *args,**kargs):
+    """Flood and receive packets at layer 2
+prn:      function applied to packets received. Ret val is printed if not None
+store:    if 1 (default), store answers and return them
+unique:   only consider packets whose print 
+nofilter: put 1 to avoid use of bpf filters
+filter:   provide a BPF filter
+iface:    listen answers only on the given interface"""
+    if iface is None and iface_hint is not None:
+        iface = conf.route.route(iface_hint)[0]    
+    s = conf.L2socket(filter=filter, iface=iface, nofilter=nofilter)
+    r=sndrcvflood(s,x,*args,**kargs)
+    s.close()
+    return r
+
+           
+
+
+def sniff(count=0, store=1, offline=None, prn = None, lfilter=None, L2socket=None, timeout=None, *arg, **karg):
+    """Sniff packets
+sniff([count=0,] [prn=None,] [store=1,] [offline=None,] [lfilter=None,] + L2ListenSocket args) -> list of packets
+
+  count: number of packets to capture. 0 means infinity
+  store: wether to store sniffed packets or discard them
+    prn: function to apply to each packet. If something is returned,
+         it is displayed. Ex:
+         ex: prn = lambda x: x.summary()
+lfilter: python function applied to each packet to determine
+         if further action may be done
+         ex: lfilter = lambda x: x.haslayer(Padding)
+offline: pcap file to read packets from, instead of sniffing them
+timeout: stop sniffing after a given time (default: None)
+L2socket: use the provided L2socket
+    """
+    c = 0
+
+    if offline is None:
+        if L2socket is None:
+            L2socket = conf.L2listen
+        s = L2socket(type=ETH_P_ALL, *arg, **karg)
+    else:
+        s = PcapReader(offline)
+
+    lst = []
+    if timeout is not None:
+        stoptime = time.time()+timeout
+    remain = None
+    while 1:
+        try:
+            if timeout is not None:
+                remain = stoptime-time.time()
+                if remain <= 0:
+                    break
+            sel = select([s],[],[],remain)
+            if s in sel[0]:
+                p = s.recv(MTU)
+                if p is None:
+                    break
+                if lfilter and not lfilter(p):
+                    continue
+                if store:
+                    lst.append(p)
+                c += 1
+                if prn:
+                    r = prn(p)
+                    if r is not None:
+                        print r
+                if count > 0 and c >= count:
+                    break
+        except KeyboardInterrupt:
+            break
+    s.close()
+    return PacketList(lst,"Sniffed")
+
+
diff --git a/scapy/supersocket.py b/scapy/supersocket.py
new file mode 100644
index 0000000000000000000000000000000000000000..f9406018ea21586241e7ab35a2abe33a1fbf7dfd
--- /dev/null
+++ b/scapy/supersocket.py
@@ -0,0 +1,513 @@
+import socket,time,os,struct
+from select import select
+from packet import Raw
+from data import *
+from config import conf
+from arch import PCAP,DNET
+
+def flush_fd(fd):
+    if type(fd) is not int:
+        fd = fd.fileno()
+    while 1:
+        r,w,e = select([fd],[],[],0)
+        if r:
+            os.read(fd,MTU)
+        else:
+            break
+
+class SuperSocket:
+    closed=0
+    def __init__(self, family=socket.AF_INET,type=socket.SOCK_STREAM, proto=0):
+        self.ins = socket.socket(family, type, proto)
+        self.outs = self.ins
+        self.promisc=None
+    def send(self, x):
+        sx = str(x)
+        x.sent_time = time.time()
+        return self.outs.send(sx)
+    def recv(self, x):
+        return Raw(self.ins.recv(x))
+    def fileno(self):
+        return self.ins.fileno()
+    def close(self):
+        if self.closed:
+            return
+        self.closed=1
+        if self.ins != self.outs:
+            if self.outs and self.outs.fileno() != -1:
+                self.outs.close()
+        if self.ins and self.ins.fileno() != -1:
+            self.ins.close()
+    def bind_in(self, addr):
+        self.ins.bind(addr)
+    def bind_out(self, addr):
+        self.outs.bind(addr)
+
+
+class L3RawSocket(SuperSocket):
+    def __init__(self, type = ETH_P_IP, filter=None, iface=None, promisc=None, nofilter=0):
+        self.outs = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_RAW)
+        self.outs.setsockopt(socket.SOL_IP, socket.IP_HDRINCL, 1)
+        self.ins = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(type))
+    def recv(self, x):
+        return Ether(self.ins.recv(x)).payload
+    def send(self, x):
+        try:
+            sx = str(x)
+            x.sent_time = time.time()
+            self.outs.sendto(sx,(x.dst,0))
+        except socket.error,msg:
+            log_runtime.error(msg)
+        
+
+
+class L3PacketSocket(SuperSocket):
+    def __init__(self, type = ETH_P_ALL, filter=None, promisc=None, iface=None, nofilter=0):
+        self.type = type
+        self.ins = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(type))
+        self.ins.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 0)
+        flush_fd(self.ins)
+        if iface:
+            self.ins.bind((iface, type))
+        if not nofilter:
+            if conf.except_filter:
+                if filter:
+                    filter = "(%s) and not (%s)" % (filter, conf.except_filter)
+                else:
+                    filter = "not (%s)" % conf.except_filter
+            if filter is not None:
+                attach_filter(self.ins, filter)
+        self.ins.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 2**30)
+        self.outs = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(type))
+        self.outs.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 2**30)
+        if promisc is None:
+            promisc = conf.promisc
+        self.promisc = promisc
+        if self.promisc:
+            if iface is None:
+                self.iff = get_if_list()
+            else:
+                if iface.__class__ is list:
+                    self.iff = iface
+                else:
+                    self.iff = [iface]
+            for i in self.iff:
+                set_promisc(self.ins, i)
+    def close(self):
+        if self.closed:
+            return
+        self.closed=1
+        if self.promisc:
+            for i in self.iff:
+                set_promisc(self.ins, i, 0)
+        SuperSocket.close(self)
+    def recv(self, x):
+        pkt, sa_ll = self.ins.recvfrom(x)
+        if sa_ll[2] == socket.PACKET_OUTGOING:
+            return None
+        if sa_ll[3] in conf.l2types:
+            cls = conf.l2types[sa_ll[3]]
+            lvl = 2
+        elif sa_ll[1] in conf.l3types:
+            cls = conf.l3types[sa_ll[1]]
+            lvl = 3
+        else:
+            warning("Unable to guess type (interface=%s protocol=%#x family=%i). Using Ethernet" % (sa_ll[0],sa_ll[1],sa_ll[3]))
+            cls = Ether
+            lvl = 2
+
+        try:
+            pkt = cls(pkt)
+        except KeyboardInterrupt:
+            raise
+        except:
+            if conf.debug_dissector:
+                raise
+            pkt = Raw(pkt)
+        if lvl == 2:
+            pkt = pkt.payload
+            
+        if pkt is not None:
+            pkt.time = get_last_packet_timestamp(self.ins)
+        return pkt
+    
+    def send(self, x):
+        if isinstance(x, IPv6):
+            iff,a,gw = conf.route6.route(x.dst)
+        elif hasattr(x,"dst"):
+            iff,a,gw = conf.route.route(x.dst)
+        else:
+            iff = conf.iface
+        sdto = (iff, self.type)
+        self.outs.bind(sdto)
+        sn = self.outs.getsockname()
+        ll = lambda x:x
+        if sn[3] in (ARPHDR_PPP,ARPHDR_TUN):
+            sdto = (iff, ETH_P_IP)
+        if sn[3] in conf.l2types:
+            ll = lambda x:conf.l2types[sn[3]]()/x
+        try:
+            sx = str(ll(x))
+            x.sent_time = time.time()
+            self.outs.sendto(sx, sdto)
+        except socket.error,msg:
+            x.sent_time = time.time()  # bad approximation
+            if conf.auto_fragment and msg[0] == 90:
+                for p in fragment(x):
+                    self.outs.sendto(str(ll(p)), sdto)
+            else:
+                raise
+                    
+
+
+
+class L2Socket(SuperSocket):
+    def __init__(self, iface = None, type = ETH_P_ALL, filter=None, nofilter=0):
+        if iface is None:
+            iface = conf.iface
+        self.ins = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(type))
+        self.ins.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 0)
+        flush_fd(self.ins)
+        if not nofilter: 
+            if conf.except_filter:
+                if filter:
+                    filter = "(%s) and not (%s)" % (filter, conf.except_filter)
+                else:
+                    filter = "not (%s)" % conf.except_filter
+            if filter is not None:
+                attach_filter(self.ins, filter)
+        self.ins.bind((iface, type))
+        self.ins.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 2**30)
+        self.outs = self.ins
+        self.outs.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 2**30)
+        sa_ll = self.outs.getsockname()
+        if sa_ll[3] in conf.l2types:
+            self.LL = conf.l2types[sa_ll[3]]
+        elif sa_ll[1] in conf.l3types:
+            self.LL = conf.l3types[sa_ll[1]]
+        else:
+            warning("Unable to guess type (interface=%s protocol=%#x family=%i). Using Ethernet" % (sa_ll[0],sa_ll[1],sa_ll[3]))
+            self.LL = Ether
+            
+    def recv(self, x):
+        pkt, sa_ll = self.ins.recvfrom(x)
+        if sa_ll[2] == socket.PACKET_OUTGOING:
+            return None
+        try:
+            q = self.LL(pkt)
+        except KeyboardInterrupt:
+            raise
+        except:
+            if conf.debug_dissector:
+                raise
+            q = Raw(pkt)
+        q.time = get_last_packet_timestamp(self.ins)
+        return q
+
+
+class L2ListenSocket(SuperSocket):
+    def __init__(self, iface = None, type = ETH_P_ALL, promisc=None, filter=None, nofilter=0):
+        self.type = type
+        self.outs = None
+        self.ins = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(type))
+        self.ins.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 0)
+        flush_fd(self.ins)
+        if iface is not None:
+            self.ins.bind((iface, type))
+        if not nofilter:
+            if conf.except_filter:
+                if filter:
+                    filter = "(%s) and not (%s)" % (filter, conf.except_filter)
+                else:
+                    filter = "not (%s)" % conf.except_filter
+            if filter is not None:
+                attach_filter(self.ins, filter)
+        if promisc is None:
+            promisc = conf.sniff_promisc
+        self.promisc = promisc
+        if iface is None:
+            self.iff = get_if_list()
+        else:
+            if iface.__class__ is list:
+                self.iff = iface
+            else:
+                self.iff = [iface]
+        if self.promisc:
+            for i in self.iff:
+                set_promisc(self.ins, i)
+        self.ins.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 2**30)
+    def close(self):
+        if self.promisc:
+            for i in self.iff:
+                set_promisc(self.ins, i, 0)
+        SuperSocket.close(self)
+
+    def recv(self, x):
+        pkt, sa_ll = self.ins.recvfrom(x)
+        if sa_ll[3] in conf.l2types :
+            cls = conf.l2types[sa_ll[3]]
+        elif sa_ll[1] in conf.l3types:
+            cls = conf.l3types[sa_ll[1]]
+        else:
+            warning("Unable to guess type (interface=%s protocol=%#x family=%i). Using Ethernet" % (sa_ll[0],sa_ll[1],sa_ll[3]))
+            cls = Ether
+
+        try:
+            pkt = cls(pkt)
+        except KeyboardInterrupt:
+            raise
+        except:
+            if conf.debug_dissector:
+                raise
+            pkt = Raw(pkt)
+        pkt.time = get_last_packet_timestamp(self.ins)
+        return pkt
+    
+    def send(self, x):
+        raise Scapy_Exception("Can't send anything with L2ListenSocket")
+
+
+
+class L3dnetSocket(SuperSocket):
+    def __init__(self, type = ETH_P_ALL, filter=None, promisc=None, iface=None, nofilter=0):
+        self.iflist = {}
+        self.ins = pcap.pcapObject()
+        if iface is None:
+            iface = conf.iface
+        self.iface = iface
+        self.ins.open_live(iface, 1600, 0, 100)
+        try:
+            ioctl(self.ins.fileno(),BIOCIMMEDIATE,struct.pack("I",1))
+        except:
+            pass
+        if nofilter:
+            if type != ETH_P_ALL:  # PF_PACKET stuff. Need to emulate this for pcap
+                filter = "ether proto %i" % type
+            else:
+                filter = None
+        else:
+            if conf.except_filter:
+                if filter:
+                    filter = "(%s) and not (%s)" % (filter, conf.except_filter)
+                else:
+                    filter = "not (%s)" % conf.except_filter
+            if type != ETH_P_ALL:  # PF_PACKET stuff. Need to emulate this for pcap
+                if filter:
+                    filter = "(ether proto %i) and (%s)" % (type,filter)
+                else:
+                    filter = "ether proto %i" % type
+        if filter:
+            self.ins.setfilter(filter, 0, 0)
+    def send(self, x):
+        if isinstance(x, IPv6):
+            iff,a,gw = conf.route6.route(x.dst)
+        elif hasattr(x,"dst"):
+            iff,a,gw = conf.route.route(x.dst)
+        else:
+            iff = conf.iface
+        ifs = self.iflist.get(iff)
+        if ifs is None:
+            self.iflist[iff] = ifs = dnet.eth(iff)
+        sx = str(Ether()/x)
+        x.sent_time = time.time()
+        ifs.send(sx)
+    def recv(self,x=MTU):
+        ll = self.ins.datalink()
+        if ll in conf.l2types:
+            cls = conf.l2types[ll]
+        else:
+            warning("Unable to guess datalink type (interface=%s linktype=%i). Using Ethernet" % (self.iface, ll))
+            cls = Ether
+
+        pkt = self.ins.next()
+        if pkt is not None:
+            l,pkt,ts = pkt
+        if pkt is None:
+            return
+
+        try:
+            pkt = cls(pkt)
+        except KeyboardInterrupt:
+            raise
+        except:
+            if conf.debug_dissector:
+                raise
+            pkt = Raw(pkt)
+        pkt.time = ts
+        return pkt.payload
+
+    def nonblock_recv(self):
+        self.ins.setnonblock(1)
+        p = self.recv()
+        self.ins.setnonblock(0)
+        return p
+
+    def close(self):
+        if hasattr(self, "ins"):
+            del(self.ins)
+        if hasattr(self, "outs"):
+            del(self.outs)
+
+class L2dnetSocket(SuperSocket):
+    def __init__(self, iface = None, type = ETH_P_ALL, filter=None, nofilter=0):
+        if iface is None:
+            iface = conf.iface
+        self.iface = iface
+        self.ins = pcap.pcapObject()
+        self.ins.open_live(iface, 1600, 0, 100)
+        try:
+            ioctl(self.ins.fileno(),BIOCIMMEDIATE,struct.pack("I",1))
+        except:
+            pass
+        if nofilter:
+            if type != ETH_P_ALL:  # PF_PACKET stuff. Need to emulate this for pcap
+                filter = "ether proto %i" % type
+            else:
+                filter = None
+        else:
+            if conf.except_filter:
+                if filter:
+                    filter = "(%s) and not (%s)" % (filter, conf.except_filter)
+                else:
+                    filter = "not (%s)" % conf.except_filter
+            if type != ETH_P_ALL:  # PF_PACKET stuff. Need to emulate this for pcap
+                if filter:
+                    filter = "(ether proto %i) and (%s)" % (type,filter)
+                else:
+                    filter = "ether proto %i" % type
+        if filter:
+            self.ins.setfilter(filter, 0, 0)
+        self.outs = dnet.eth(iface)
+    def recv(self,x):
+        ll = self.ins.datalink()
+        if ll in conf.l2types:
+            cls = conf.l2types[ll]
+        else:
+            warning("Unable to guess datalink type (interface=%s linktype=%i). Using Ethernet" % (self.iface, ll))
+            cls = Ether
+
+        pkt = self.ins.next()
+        if pkt is not None:
+            l,pkt,ts = pkt
+        if pkt is None:
+            return
+        
+        try:
+            pkt = cls(pkt)
+        except KeyboardInterrupt:
+            raise
+        except:
+            if conf.debug_dissector:
+                raise
+            pkt = Raw(pkt)
+        pkt.time = ts
+        return pkt
+
+    def nonblock_recv(self):
+        self.ins.setnonblock(1)
+        p = self.recv(MTU)
+        self.ins.setnonblock(0)
+        return p
+
+    def close(self):
+        if hasattr(self, "ins"):
+            del(self.ins)
+        if hasattr(self, "outs"):
+            del(self.outs)
+    
+    
+    
+
+
+class L2pcapListenSocket(SuperSocket):
+    def __init__(self, iface = None, type = ETH_P_ALL, promisc=None, filter=None):
+        self.type = type
+        self.outs = None
+        self.ins = pcap.pcapObject()
+        self.iface = iface
+        if iface is None:
+            iface = conf.iface
+        if promisc is None:
+            promisc = conf.sniff_promisc
+        self.promisc = promisc
+        self.ins.open_live(iface, 1600, self.promisc, 100)
+        try:
+            ioctl(self.ins.fileno(),BIOCIMMEDIATE,struct.pack("I",1))
+        except:
+            pass
+        if type == ETH_P_ALL: # Do not apply any filter if Ethernet type is given
+            if conf.except_filter:
+                if filter:
+                    filter = "(%s) and not (%s)" % (filter, conf.except_filter)
+                else:
+                    filter = "not (%s)" % conf.except_filter
+            if filter:
+                self.ins.setfilter(filter, 0, 0)
+
+    def close(self):
+        del(self.ins)
+        
+    def recv(self, x):
+        ll = self.ins.datalink()
+        if ll in conf.l2types:
+            cls = conf.l2types[ll]
+        else:
+            warning("Unable to guess datalink type (interface=%s linktype=%i). Using Ethernet" % (self.iface, ll))
+            cls = Ether
+
+        pkt = None
+        while pkt is None:
+            pkt = self.ins.next()
+            if pkt is not None:
+                l,pkt,ts = pkt
+        
+        try:
+            pkt = cls(pkt)
+        except KeyboardInterrupt:
+            raise
+        except:
+            if conf.debug_dissector:
+                raise
+            pkt = Raw(pkt)
+        pkt.time = ts
+        return pkt
+
+    def send(self, x):
+        raise Scapy_Exception("Can't send anything with L2pcapListenSocket")
+
+
+class SimpleSocket(SuperSocket):
+    def __init__(self, sock):
+        self.ins = sock
+        self.outs = sock
+
+
+class StreamSocket(SimpleSocket):
+    def __init__(self, sock, basecls=Raw):
+        SimpleSocket.__init__(self, sock)
+        self.basecls = basecls
+        
+    def recv(self, x=MTU):
+        pkt = self.ins.recv(x, socket.MSG_PEEK)
+        x = len(pkt)
+        pkt = self.basecls(pkt)
+        pad = pkt[Padding]
+        if pad is not None and pad.underlayer is not None:
+            del(pad.underlayer.payload)
+        while pad is not None and not isinstance(pad, NoPayload):
+            x -= len(pad.load)
+            pad = pad.payload
+        self.ins.recv(x)
+        return pkt
+        
+
+conf.L3socket = L3PacketSocket
+conf.L2socket = L2Socket
+conf.L2listen = L2ListenSocket
+
+if PCAP:
+    conf.L2listen=L2pcapListenSocket
+    if DNET:
+        conf.L3socket=L3dnetSocket
+        conf.L2socket=L2dnetSocket
+
diff --git a/scapy/themes.py b/scapy/themes.py
new file mode 100644
index 0000000000000000000000000000000000000000..64035799cb23dab34f06046b9ef30c6d3a1fbaf3
--- /dev/null
+++ b/scapy/themes.py
@@ -0,0 +1,247 @@
+    
+##################
+## Color themes ##
+##################
+
+class Color:
+    normal = "\033[0m"
+    black = "\033[30m"
+    red = "\033[31m"
+    green = "\033[32m"
+    yellow = "\033[33m"
+    blue = "\033[34m"
+    purple = "\033[35m"
+    cyan = "\033[36m"
+    grey = "\033[37m"
+
+    bold = "\033[1m"
+    uline = "\033[4m"
+    blink = "\033[5m"
+    invert = "\033[7m"
+        
+
+class ColorTheme:
+    def __repr__(self):
+        return "<%s>" % self.__class__.__name__
+    def __getattr__(self, attr):
+        return lambda x:x
+        
+
+class NoTheme(ColorTheme):
+    pass
+
+
+class AnsiColorTheme(ColorTheme):
+    def __getattr__(self, attr):
+        if attr.startswith("__"):
+            raise AttributeError(attr)
+        s = "style_%s" % attr 
+        if s in self.__class__.__dict__:
+            before = getattr(self, s)
+            after = self.style_normal
+        else:
+            before = after = ""
+
+        def do_style(val, fmt=None, before=before, after=after):
+            if fmt is None:
+                if type(val) is not str:
+                    val = str(val)
+            else:
+                val = fmt % val
+            return before+val+after
+        return do_style
+        
+        
+    style_normal = ""
+    style_prompt = ""
+    style_punct = ""
+    style_id = ""
+    style_not_printable = ""
+    style_layer_name = ""
+    style_field_name = ""
+    style_field_value = ""
+    style_emph_field_name = ""
+    style_emph_field_value = ""
+    style_packetlist_name = ""
+    style_packetlist_proto = ""
+    style_packetlist_value = ""
+    style_fail = ""
+    style_success = ""
+    style_odd = ""
+    style_even = ""
+    style_opening = ""
+    style_active = ""
+    style_closed = ""
+    style_left = ""
+    style_right = ""
+
+class BlackAndWhite(AnsiColorTheme):
+    pass
+
+class DefaultTheme(AnsiColorTheme):
+    style_normal = Color.normal
+    style_prompt = Color.blue+Color.bold
+    style_punct = Color.normal
+    style_id = Color.blue+Color.bold
+    style_not_printable = Color.grey
+    style_layer_name = Color.red+Color.bold
+    style_field_name = Color.blue
+    style_field_value = Color.purple
+    style_emph_field_name = Color.blue+Color.uline+Color.bold
+    style_emph_field_value = Color.purple+Color.uline+Color.bold
+    style_packetlist_name = Color.red+Color.bold
+    style_packetlist_proto = Color.blue
+    style_packetlist_value = Color.purple
+    style_fail = Color.red+Color.bold
+    style_success = Color.blue+Color.bold
+    style_even = Color.black+Color.bold
+    style_odd = Color.black
+    style_opening = Color.yellow
+    style_active = Color.black
+    style_closed = Color.grey
+    style_left = Color.blue+Color.invert
+    style_right = Color.red+Color.invert
+    
+class BrightTheme(AnsiColorTheme):
+    style_normal = Color.normal
+    style_punct = Color.normal
+    style_id = Color.yellow+Color.bold
+    style_layer_name = Color.red+Color.bold
+    style_field_name = Color.yellow+Color.bold
+    style_field_value = Color.purple+Color.bold
+    style_emph_field_name = Color.yellow+Color.bold
+    style_emph_field_value = Color.green+Color.bold
+    style_packetlist_name = Color.red+Color.bold
+    style_packetlist_proto = Color.yellow+Color.bold
+    style_packetlist_value = Color.purple+Color.bold
+    style_fail = Color.red+Color.bold
+    style_success = Color.blue+Color.bold
+    style_even = Color.black+Color.bold
+    style_odd = Color.black
+    style_left = Color.cyan+Color.invert
+    style_right = Color.purple+Color.invert
+
+
+class RastaTheme(AnsiColorTheme):
+    style_normal = Color.normal+Color.green+Color.bold
+    style_prompt = Color.yellow+Color.bold
+    style_punct = Color.red
+    style_id = Color.green+Color.bold
+    style_not_printable = Color.green
+    style_layer_name = Color.red+Color.bold
+    style_field_name = Color.yellow+Color.bold
+    style_field_value = Color.green+Color.bold
+    style_emph_field_name = Color.green
+    style_emph_field_value = Color.green
+    style_packetlist_name = Color.red+Color.bold
+    style_packetlist_proto = Color.yellow+Color.bold
+    style_packetlist_value = Color.green+Color.bold
+    style_fail = Color.red
+    style_success = Color.red+Color.bold
+    style_even = Color.yellow
+    style_odd = Color.green
+    style_left = Color.yellow+Color.invert
+    style_right = Color.red+Color.invert
+
+
+class FormatTheme(ColorTheme):
+    def __getattr__(self, attr):
+        if attr.startswith("__"):
+            raise AttributeError(attr)
+        col = self.__class__.__dict__.get("style_%s" % attr, "%s")
+        def do_style(val, fmt=None, col=col):
+            if fmt is None:
+                if type(val) is not str:
+                    val = str(val)
+            else:
+                val = fmt % val
+            return col % val
+        return do_style
+        
+
+class LatexTheme(FormatTheme):
+    style_prompt = r"\textcolor{blue}{%s}"
+    style_not_printable = r"\textcolor{gray}{%s}"
+    style_layer_name = r"\textcolor{red}{\bf %s}"
+    style_field_name = r"\textcolor{blue}{%s}"
+    style_field_value = r"\textcolor{purple}{%s}"
+    style_emph_field_name = r"\textcolor{blue}{\underline{%s}}" #ul
+    style_emph_field_value = r"\textcolor{purple}{\underline{%s}}" #ul
+    style_packetlist_name = r"\textcolor{red}{\bf %s}"
+    style_packetlist_proto = r"\textcolor{blue}{%s}"
+    style_packetlist_value = r"\textcolor{purple}{%s}"
+    style_fail = r"\textcolor{red}{\bf %s}"
+    style_success = r"\textcolor{blue}{\bf %s}"
+    style_left = r"\textcolor{blue}{%s}"
+    style_right = r"\textcolor{red}{%s}"
+#    style_even = r"}{\bf "
+#    style_odd = ""
+
+class LatexTheme2(FormatTheme):
+    style_prompt = r"@`@textcolor@[@blue@]@@[@%s@]@"
+    style_not_printable = r"@`@textcolor@[@gray@]@@[@%s@]@"
+    style_layer_name = r"@`@textcolor@[@red@]@@[@@`@bfseries@[@@]@%s@]@"
+    style_field_name = r"@`@textcolor@[@blue@]@@[@%s@]@"
+    style_field_value = r"@`@textcolor@[@purple@]@@[@%s@]@"
+    style_emph_field_name = r"@`@textcolor@[@blue@]@@[@@`@underline@[@%s@]@@]@" 
+    style_emph_field_value = r"@`@textcolor@[@purple@]@@[@@`@underline@[@%s@]@@]@" 
+    style_packetlist_name = r"@`@textcolor@[@red@]@@[@@`@bfseries@[@@]@%s@]@"
+    style_packetlist_proto = r"@`@textcolor@[@blue@]@@[@%s@]@"
+    style_packetlist_value = r"@`@textcolor@[@purple@]@@[@%s@]@"
+    style_fail = r"@`@textcolor@[@red@]@@[@@`@bfseries@[@@]@%s@]@"
+    style_success = r"@`@textcolor@[@blue@]@@[@@`@bfserices@[@@]@%s@]@"
+    style_even = r"@`@textcolor@[@gray@]@@[@@`@bfseries@[@@]@%s@]@"
+#    style_odd = r"@`@textcolor@[@black@]@@[@@`@bfseries@[@@]@%s@]@"
+    style_left = r"@`@textcolor@[@blue@]@@[@%s@]@"
+    style_right = r"@`@textcolor@[@red@]@@[@%s@]@"
+
+class HTMLTheme(FormatTheme):
+    style_prompt = "<span class=prompt>%s</span>"
+    style_not_printable = "<span class=not_printable>%s</span>"
+    style_layer_name = "<span class=layer_name>%s</span>"
+    style_field_name = "<span class=field_name>%s</span>"
+    style_field_value = "<span class=field_value>%s</span>"
+    style_emph_field_name = "<span class=emph_field_name>%s</span>"
+    style_emph_field_value = "<span class=emph_field_value>%s</span>"
+    style_packetlist_name = "<span class=packetlist_name>%s</span>"
+    style_packetlist_proto = "<span class=packetlist_proto>%s</span>"
+    style_packetlist_value = "<span class=packetlist_value>%s</span>"
+    style_fail = "<span class=fail>%s</span>"
+    style_success = "<span class=success>%s</span>"
+    style_even = "<span class=even>%s</span>"
+    style_odd = "<span class=odd>%s</span>"
+    style_left = "<span class=left>%s</span>"
+    style_right = "<span class=right>%s</span>"
+
+class HTMLTheme2(HTMLTheme):
+    style_prompt = "#[#span class=prompt#]#%s#[#/span#]#"
+    style_not_printable = "#[#span class=not_printable#]#%s#[#/span#]#"
+    style_layer_name = "#[#span class=layer_name#]#%s#[#/span#]#"
+    style_field_name = "#[#span class=field_name#]#%s#[#/span#]#"
+    style_field_value = "#[#span class=field_value#]#%s#[#/span#]#"
+    style_emph_field_name = "#[#span class=emph_field_name#]#%s#[#/span#]#"
+    style_emph_field_value = "#[#span class=emph_field_value#]#%s#[#/span#]#"
+    style_packetlist_name = "#[#span class=packetlist_name#]#%s#[#/span#]#"
+    style_packetlist_proto = "#[#span class=packetlist_proto#]#%s#[#/span#]#"
+    style_packetlist_value = "#[#span class=packetlist_value#]#%s#[#/span#]#"
+    style_fail = "#[#span class=fail#]#%s#[#/span#]#"
+    style_success = "#[#span class=success#]#%s#[#/span#]#"
+    style_even = "#[#span class=even#]#%s#[#/span#]#"
+    style_odd = "#[#span class=odd#]#%s#[#/span#]#"
+    style_left = "#[#span class=left#]#%s#[#/span#]#"
+    style_right = "#[#span class=right#]#%s#[#/span#]#"
+
+
+class ColorPrompt:
+    __prompt = ">>> "
+    def __str__(self):
+        try:
+            ct = conf.color_theme
+            if isinstance(ct, AnsiColorTheme):
+                ## ^A and ^B delimit invisible caracters for readline to count right
+                return "\001%s\002" % ct.prompt("\002"+conf.prompt+"\001")
+            else:
+                return ct.prompt(conf.prompt)
+        except:
+            return self.__prompt
+
diff --git a/scapy/utils.py b/scapy/utils.py
new file mode 100644
index 0000000000000000000000000000000000000000..a5f6704108237a55513bd8dbdc4360f0f513555f
--- /dev/null
+++ b/scapy/utils.py
@@ -0,0 +1,746 @@
+import os,sys,socket,types
+import random
+import gzip,zlib,cPickle
+import re,struct,array
+from arch import *
+
+###########
+## Tools ##
+###########
+
+def sane_color(x):
+    r=""
+    for i in x:
+        j = ord(i)
+        if (j < 32) or (j >= 127):
+            r=r+conf.color_theme.not_printable(".")
+        else:
+            r=r+i
+    return r
+
+def sane(x):
+    r=""
+    for i in x:
+        j = ord(i)
+        if (j < 32) or (j >= 127):
+            r=r+"."
+        else:
+            r=r+i
+    return r
+
+def lhex(x):
+    if type(x) in (int,long):
+        return hex(x)
+    elif type(x) is tuple:
+        return "(%s)" % ", ".join(map(lhex, x))
+    elif type(x) is list:
+        return "[%s]" % ", ".join(map(lhex, x))
+    else:
+        return x
+
+def hexdump(x):
+    x=str(x)
+    l = len(x)
+    i = 0
+    while i < l:
+        print "%04x  " % i,
+        for j in range(16):
+            if i+j < l:
+                print "%02X" % ord(x[i+j]),
+            else:
+                print "  ",
+            if j%16 == 7:
+                print "",
+        print " ",
+        print sane_color(x[i:i+16])
+        i += 16
+
+def linehexdump(x, onlyasc=0, onlyhex=0):
+    x = str(x)
+    l = len(x)
+    if not onlyasc:
+        for i in range(l):
+            print "%02X" % ord(x[i]),
+        print "",
+    if not onlyhex:
+        print sane_color(x)
+
+def chexdump(x):
+    x=str(x)
+    print ", ".join(map(lambda x: "%#04x"%ord(x), x))
+    
+def hexstr(x, onlyasc=0, onlyhex=0):
+    s = []
+    if not onlyasc:
+        s.append(" ".join(map(lambda x:"%02x"%ord(x), x)))
+    if not onlyhex:
+        s.append(sane(x)) 
+    return "  ".join(s)
+
+
+def hexdiff(x,y):
+    x=str(x)[::-1]
+    y=str(y)[::-1]
+    SUBST=1
+    INSERT=1
+    d={}
+    d[-1,-1] = 0,(-1,-1)
+    for j in range(len(y)):
+        d[-1,j] = d[-1,j-1][0]+INSERT, (-1,j-1)
+    for i in range(len(x)):
+        d[i,-1] = d[i-1,-1][0]+INSERT, (i-1,-1)
+
+    for j in range(len(y)):
+        for i in range(len(x)):
+            d[i,j] = min( ( d[i-1,j-1][0]+SUBST*(x[i] != y[j]), (i-1,j-1) ),
+                          ( d[i-1,j][0]+INSERT, (i-1,j) ),
+                          ( d[i,j-1][0]+INSERT, (i,j-1) ) )
+                          
+
+    backtrackx = []
+    backtracky = []
+    i=len(x)-1
+    j=len(y)-1
+    while not (i == j == -1):
+        i2,j2 = d[i,j][1]
+        backtrackx.append(x[i2+1:i+1])
+        backtracky.append(y[j2+1:j+1])
+        i,j = i2,j2
+
+        
+
+    x = y = i = 0
+    colorize = { 0: lambda x:x,
+                -1: conf.color_theme.left,
+                 1: conf.color_theme.right }
+    
+    dox=1
+    doy=0
+    l = len(backtrackx)
+    while i < l:
+        separate=0
+        linex = backtrackx[i:i+16]
+        liney = backtracky[i:i+16]
+        xx = sum(len(k) for k in linex)
+        yy = sum(len(k) for k in liney)
+        if dox and not xx:
+            dox = 0
+            doy = 1
+        if dox and linex == liney:
+            doy=1
+            
+        if dox:
+            xd = y
+            j = 0
+            while not linex[j]:
+                j += 1
+                xd -= 1
+            print colorize[doy-dox]("%04x" % xd),
+            x += xx
+            line=linex
+        else:
+            print "    ",
+        if doy:
+            yd = y
+            j = 0
+            while not liney[j]:
+                j += 1
+                yd -= 1
+            print colorize[doy-dox]("%04x" % yd),
+            y += yy
+            line=liney
+        else:
+            print "    ",
+            
+        print " ",
+        
+        cl = ""
+        for j in range(16):
+            if i+j < l:
+                if line[j]:
+                    col = colorize[(linex[j]!=liney[j])*(doy-dox)]
+                    print col("%02X" % ord(line[j])),
+                    if linex[j]==liney[j]:
+                        cl += sane_color(line[j])
+                    else:
+                        cl += col(sane(line[j]))
+                else:
+                    print "  ",
+                    cl += " "
+            else:
+                print "  ",
+            if j == 7:
+                print "",
+
+
+        print " ",cl
+
+        if doy or not yy:
+            doy=0
+            dox=1
+            i += 16
+        else:
+            if yy:
+                dox=0
+                doy=1
+            else:
+                i += 16
+
+    
+crc32 = zlib.crc32
+
+if BIG_ENDIAN:
+    def checksum(pkt):
+        if len(pkt) % 2 == 1:
+            pkt += "\0"
+        s = sum(array.array("H", pkt))
+        s = (s >> 16) + (s & 0xffff)
+        s += s >> 16
+        s = ~s
+        return s & 0xffff
+else:
+    def checksum(pkt):
+        if len(pkt) % 2 == 1:
+            pkt += "\0"
+        s = sum(array.array("H", pkt))
+        s = (s >> 16) + (s & 0xffff)
+        s += s >> 16
+        s = ~s
+        return (((s>>8)&0xff)|s<<8) & 0xffff
+
+def warning(x):
+    log_runtime.warning(x)
+
+def mac2str(mac):
+    return "".join(map(lambda x: chr(int(x,16)), mac.split(":")))
+
+def str2mac(s):
+    return ("%02x:"*6)[:-1] % tuple(map(ord, s)) 
+
+def strxor(x,y):
+    return "".join(map(lambda x,y:chr(ord(x)^ord(y)),x,y))
+
+def atol(x):
+    try:
+        ip = inet_aton(x)
+    except socket.error:
+        ip = inet_aton(socket.gethostbyname(x))
+    return struct.unpack("!I", ip)[0]
+def ltoa(x):
+    return inet_ntoa(struct.pack("!I", x))
+
+def itom(x):
+    return (0xffffffff00000000L>>x)&0xffffffffL
+
+def do_graph(graph,prog=None,format="svg",target=None, type=None,string=None,options=None):
+    """do_graph(graph, prog=conf.prog.dot, format="svg",
+         target="| conf.prog.display", options=None, [string=1]):
+    string: if not None, simply return the graph string
+    graph: GraphViz graph description
+    format: output type (svg, ps, gif, jpg, etc.), passed to dot's "-T" option
+    target: filename or redirect. Defaults pipe to Imagemagick's display program
+    prog: which graphviz program to use
+    options: options to be passed to prog"""
+        
+
+    if string:
+        return graph
+    if type is not None:
+        format=type
+    if prog is None:
+        prog = conf.prog.dot
+    if target is None:
+        target = "| %s" % conf.prog.display
+    if format is not None:
+        format = "-T %s" % format
+    w,r = os.popen2("%s %s %s %s" % (prog,options or "", format or "", target))
+    w.write(graph)
+    w.close()
+
+_TEX_TR = {
+    "{":"{\\tt\\char123}",
+    "}":"{\\tt\\char125}",
+    "\\":"{\\tt\\char92}",
+    "^":"\\^{}",
+    "$":"\\$",
+    "#":"\\#",
+    "~":"\\~",
+    "_":"\\_",
+    "&":"\\&",
+    "%":"\\%",
+    "|":"{\\tt\\char124}",
+    "~":"{\\tt\\char126}",
+    "<":"{\\tt\\char60}",
+    ">":"{\\tt\\char62}",
+    }
+    
+def tex_escape(x):
+    s = ""
+    for c in x:
+        s += _TEX_TR.get(c,c)
+    return s
+
+def colgen(*lstcol,**kargs):
+    """Returns a generator that mixes provided quantities forever
+    trans: a function to convert the three arguments into a color. lambda x,y,z:(x,y,z) by default"""
+    if len(lstcol) < 2:
+        lstcol *= 2
+    trans = kargs.get("trans", lambda x,y,z: (x,y,z))
+    while 1:
+        for i in range(len(lstcol)):
+            for j in range(len(lstcol)):
+                for k in range(len(lstcol)):
+                    if i != j or j != k or k != i:
+                        yield trans(lstcol[(i+j)%len(lstcol)],lstcol[(j+k)%len(lstcol)],lstcol[(k+i)%len(lstcol)])
+
+def incremental_label(label="tag%05i", start=0):
+    while True:
+        yield label % start
+        start += 1
+
+#########################
+#### Enum management ####
+#########################
+
+class EnumElement:
+    _value=None
+    def __init__(self, key, value):
+        self._key = key
+        self._value = value
+    def __repr__(self):
+        return "<%s %s[%r]>" % (self.__dict__.get("_name", self.__class__.__name__), self._key, self._value)
+    def __getattr__(self, attr):
+        return getattr(self._value, attr)
+    def __str__(self):
+        return self._key
+    def __eq__(self, other):
+        return self._value == int(other)
+
+
+class Enum_metaclass(type):
+    element_class = EnumElement
+    def __new__(cls, name, bases, dct):
+        rdict={}
+        for k,v in dct.iteritems():
+            if type(v) is int:
+                v = cls.element_class(k,v)
+                dct[k] = v
+                rdict[v] = k
+        dct["__rdict__"] = rdict
+        return super(Enum_metaclass, cls).__new__(cls, name, bases, dct)
+    def __getitem__(self, attr):
+        return self.__rdict__[attr]
+    def __contains__(self, val):
+        return val in self.__rdict__
+    def get(self, attr, val=None):
+        return self._rdict__.get(attr, val)
+    def __repr__(self):
+        return "<%s>" % self.__dict__.get("name", self.__name__)
+
+
+
+
+##############################
+## Session saving/restoring ##
+##############################
+
+
+def save_session(fname, session=None, pickleProto=-1):
+    if session is None:
+        session = scapy_session
+
+    to_be_saved = session.copy()
+        
+    if to_be_saved.has_key("__builtins__"):
+        del(to_be_saved["__builtins__"])
+
+    for k in to_be_saved.keys():
+        if type(to_be_saved[k]) in [types.TypeType, types.ClassType, types.ModuleType]:
+             log_interactive.error("[%s] (%s) can't be saved." % (k, type(to_be_saved[k])))
+             del(to_be_saved[k])
+
+    try:
+        os.rename(fname, fname+".bak")
+    except OSError:
+        pass
+    f=gzip.open(fname,"wb")
+    cPickle.dump(to_be_saved, f, pickleProto)
+    f.close()
+
+def load_session(fname):
+    try:
+        s = cPickle.load(gzip.open(fname,"rb"))
+    except IOError:
+        s = cPickle.load(open(fname,"rb"))
+    scapy_session.clear()
+    scapy_session.update(s)
+
+def update_session(fname):
+    try:
+        s = cPickle.load(gzip.open(fname,"rb"))
+    except IOError:
+        s = cPickle.load(open(fname,"rb"))
+    scapy_session.update(s)
+
+
+def export_object(obj):
+    print gzip.zlib.compress(cPickle.dumps(obj,2),9).encode("base64")
+
+def import_object(obj=None):
+    if obj is None:
+        obj = sys.stdin.read()
+    return cPickle.loads(gzip.zlib.decompress(obj.strip().decode("base64")))
+
+
+def save_object(fname, obj):
+    cPickle.dump(obj,gzip.open(fname,"wb"))
+
+def load_object(fname):
+    return cPickle.load(gzip.open(fname,"rb"))
+
+def corrupt_bytes(s, p=0.01, n=None):
+    s = array.array("B",str(s))
+    l = len(s)
+    if n is None:
+        n = max(1,int(l*p))
+    for i in random.sample(xrange(l), n):
+        s[i] = random.randint(0,255)
+    return s.tostring()
+
+def corrupt_bits(s, p=0.01, n=None):
+    s = array.array("B",str(s))
+    l = len(s)*8
+    if n is None:
+        n = max(1,int(l*p))
+    for i in random.sample(xrange(l), n):
+        s[i/8] ^= 1 << (i%8)
+    return s.tostring()
+
+    
+
+
+#############################
+## pcap capture file stuff ##
+#############################
+
+def wrpcap(filename, pkt, *args, **kargs):
+    """Write a list of packets to a pcap file
+gz: set to 1 to save a gzipped capture
+linktype: force linktype value
+endianness: "<" or ">", force endianness"""
+    PcapWriter(filename, *args, **kargs).write(pkt)
+
+def rdpcap(filename, count=-1):
+    """Read a pcap file and return a packet list
+count: read only <count> packets"""
+    return PcapReader(filename).read_all(count=count)
+
+class PcapReader:
+    """A stateful pcap reader
+    
+    Based entirely on scapy.rdpcap(), this class allows for packets
+    to be dispatched without having to be loaded into memory all at
+    once
+    """
+
+    def __init__(self, filename):
+        self.filename = filename
+        try:
+            self.f = gzip.open(filename,"rb")
+            magic = self.f.read(4)
+        except IOError:
+            self.f = open(filename,"rb")
+            magic = self.f.read(4)
+        if magic == "\xa1\xb2\xc3\xd4": #big endian
+            self.endian = ">"
+        elif  magic == "\xd4\xc3\xb2\xa1": #little endian
+            self.endian = "<"
+        else:
+            raise RuntimeWarning, "Not a pcap capture file (bad magic)"
+        hdr = self.f.read(20)
+        if len(hdr)<20:
+            raise RuntimeWarning, "Invalid pcap file (too short)"
+        vermaj,vermin,tz,sig,snaplen,linktype = struct.unpack(self.endian+"HHIIII",hdr)
+        self.LLcls = conf.l2types.get(linktype, Raw)
+        if self.LLcls == Raw:
+            warning("PcapReader: unkonwon LL type [%i]/[%#x]. Using Raw packets" % (linktype,linktype))
+
+    def __iter__(self):
+        return self
+
+    def next(self):
+        """impliment the iterator protocol on a set of packets in a
+        pcap file
+        """
+        pkt = self.read_packet()
+        if pkt == None:
+            raise StopIteration
+        return pkt
+
+
+    def read_packet(self):
+        """return a single packet read from the file
+        
+        returns None when no more packets are available
+        """
+        hdr = self.f.read(16)
+        if len(hdr) < 16:
+            return None
+        sec,usec,caplen,olen = struct.unpack(self.endian+"IIII", hdr)
+        s = self.f.read(caplen)
+        try:
+            p = self.LLcls(s)
+        except KeyboardInterrupt:
+            raise
+        except:
+            if conf.debug_dissector:
+                raise
+            p = Raw(s)
+        p.time = sec+0.000001*usec
+        return p
+
+    def dispatch(self, callback):
+        """call the specified callback routine for each packet read
+        
+        This is just a convienience function for the main loop
+        that allows for easy launching of packet processing in a 
+        thread.
+        """
+        p = self.read_packet()
+        while p != None:
+            callback(p)
+            p = self.read_packet()
+
+    def read_all(self,count=-1):
+        """return a list of all packets in the pcap file
+        """
+        res=[]
+        while count != 0:
+            count -= 1
+            p = self.read_packet()
+            if p is None:
+                break
+            res.append(p)
+        return PacketList(res,name = os.path.basename(self.filename))
+
+    def recv(self, size):
+        """ Emulate a socket
+        """
+        return self.read_packet()
+
+    def fileno(self):
+        return self.f.fileno()
+        
+
+
+class PcapWriter:
+    """A stream PCAP writer with more control than wrpcap()"""
+    def __init__(self, filename, linktype=None, gz=False, endianness="", append=False, sync=False):
+        """
+        linktype: force linktype to a given value. If None, linktype is taken
+                  from the first writter packet
+        gz: compress the capture on the fly
+        endianness: force an endianness (little:"<", big:">"). Default is native
+        append: append packets to the capture file instead of truncating it
+        sync: do not bufferize writes to the capture file
+        """
+        
+        self.linktype = linktype
+        self.header_present = 0
+        self.append=append
+        self.gz = gz
+        self.endian = endianness
+        self.filename=filename
+        self.sync=sync
+        bufsz=4096
+        if sync:
+            bufsz=0
+
+        self.f = [open,gzip.open][gz](filename,append and "ab" or "wb", gz and 9 or bufsz)
+        
+            
+
+    def fileno(self):
+        return self.f.fileno()
+
+    def _write_header(self, pkt):
+        self.header_present=1
+
+        if self.linktype == None:
+            if type(pkt) is list or type(pkt) is tuple:
+                pkt = pkt[0]
+            self.linktype = conf.l2types.get(pkt.__class__,1)
+
+        if self.append:
+            # Even if prone to race conditions, this seems to be
+            # safest way to tell whether the header is already present
+            # because we have to handle compressed streams that
+            # are not as flexible as basic files
+            g = [open,gzip.open][self.gz](self.filename,"rb")
+            if g.read(16):
+                return
+            
+        self.f.write(struct.pack(self.endian+"IHHIIII", 0xa1b2c3d4L,
+                                 2, 4, 0, 0, MTU, self.linktype))
+        self.f.flush()
+    
+
+    def write(self, pkt):
+        """accepts a either a single packet or a list of packets
+        to be written to the dumpfile
+        """
+        if not self.header_present:
+            self._write_header(pkt)
+        for p in pkt:
+            self._write_packet(p)
+
+    def _write_packet(self, packet):
+        """writes a single packet to the pcap file
+        """
+        s = str(packet)
+        l = len(s)
+        sec = int(packet.time)
+        usec = int((packet.time-sec)*1000000)
+        self.f.write(struct.pack(self.endian+"IIII", sec, usec, l, l))
+        self.f.write(s)
+        if self.gz and self.sync:
+            self.f.flush()
+
+    def flush(self):
+        return self.f.flush()
+    def close(self):
+        return self.f.close()
+                
+
+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})")
+
+def import_hexcap():
+    p = ""
+    try:
+        while 1:
+            l = raw_input().strip()
+            try:
+                p += re_extract_hexcap.match(l).groups()[3]
+            except:
+                warning("Parsing error during hexcap")
+                continue
+    except EOFError:
+        pass
+    
+    p = p.replace(" ","")
+    p2=""
+    for i in range(len(p)/2):
+        p2 += chr(int(p[2*i:2*i+2],16))
+    return p2
+        
+
+
+def wireshark(pktlist):
+    f = os.tempnam("scapy")
+    wrpcap(f, pktlist)
+    os.spawnlp(os.P_NOWAIT, conf.prog.wireshark, conf.prog.wireshark, "-r", f)
+
+def hexedit(x):
+    x = str(x)
+    f = os.tempnam("scapy")
+    open(f,"w").write(x)
+    os.spawnlp(os.P_WAIT, conf.prog.hexedit, conf.prog.hexedit, f)
+    x = open(f).read()
+    os.unlink(f)
+    return x
+
+def __make_table(yfmtfunc, fmtfunc, endline, list, fxyz, sortx=None, sorty=None, seplinefunc=None):
+    vx = {} 
+    vy = {} 
+    vz = {}
+    vxf = {}
+    vyf = {}
+    l = 0
+    for e in list:
+        xx,yy,zz = map(str, fxyz(e))
+        l = max(len(yy),l)
+        vx[xx] = max(vx.get(xx,0), len(xx), len(zz))
+        vy[yy] = None
+        vz[(xx,yy)] = zz
+
+    vxk = vx.keys()
+    vyk = vy.keys()
+    if sortx:
+        vxk.sort(sortx)
+    else:
+        try:
+            vxk.sort(lambda x,y:int(x)-int(y))
+        except:
+            try:
+                vxk.sort(lambda x,y: cmp(atol(x),atol(y)))
+            except:
+                vxk.sort()
+    if sorty:
+        vyk.sort(sorty)
+    else:
+        try:
+            vyk.sort(lambda x,y:int(x)-int(y))
+        except:
+            try:
+                vyk.sort(lambda x,y: cmp(atol(x),atol(y)))
+            except:
+                vyk.sort()
+
+
+    if seplinefunc:
+        sepline = seplinefunc(l, map(lambda x:vx[x],vxk))
+        print sepline
+
+    fmt = yfmtfunc(l)
+    print fmt % "",
+    for x in vxk:
+        vxf[x] = fmtfunc(vx[x])
+        print vxf[x] % x,
+    print endline
+    if seplinefunc:
+        print sepline
+    for y in vyk:
+        print fmt % y,
+        for x in vxk:
+            print vxf[x] % vz.get((x,y), "-"),
+        print endline
+    if seplinefunc:
+        print sepline
+
+def make_table(*args, **kargs):
+    __make_table(lambda l:"%%-%is" % l, lambda l:"%%-%is" % l, "", *args, **kargs)
+    
+def make_lined_table(*args, **kargs):
+    __make_table(lambda l:"%%-%is |" % l, lambda l:"%%-%is |" % l, "",
+                 seplinefunc=lambda a,x:"+".join(map(lambda y:"-"*(y+2), [a-1]+x+[-2])),
+                 *args, **kargs)
+
+def make_tex_table(*args, **kargs):
+    __make_table(lambda l: "%s", lambda l: "& %s", "\\\\", seplinefunc=lambda a,x:"\\hline", *args, **kargs)
+    
+
+######################
+## Online doc stuff ##
+######################
+
+
+def lsc(cmd=None):
+    """List user commands"""
+    if cmd is None:
+        for c in user_commands:
+            doc = "No doc. available"
+            if c.__doc__:
+                doc = c.__doc__.split("\n")[0]
+            
+            print "%-16s : %s" % (c.__name__, doc)
+    else:
+        print cmd.__doc__
+
+
+#XXX 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 ]
+
+
+
+def tethereal(*args,**kargs):
+    sniff(prn=lambda x: x.display(),*args,**kargs)
+
diff --git a/scapy/voip.py b/scapy/voip.py
new file mode 100644
index 0000000000000000000000000000000000000000..df2e4f8c5bcae5e0bd67c1a388817ee9f74a0980
--- /dev/null
+++ b/scapy/voip.py
@@ -0,0 +1,134 @@
+import os
+###################
+## Testing stuff ##
+###################
+
+
+
+def merge(x,y):
+    if len(x) > len(y):
+        y += "\x00"*(len(x)-len(y))
+    elif len(x) < len(y):
+        x += "\x00"*(len(y)-len(x))
+    m = ""
+    for i in range(len(x)/ss):
+        m += x[ss*i:ss*(i+1)]+y[ss*i:ss*(i+1)]
+    return  m
+#    return  "".join(map(str.__add__, x, y))
+
+
+def voip_play(s1,list=None,**kargs):
+    FIFO="/tmp/conv1.%i.%%i" % os.getpid()
+    FIFO1=FIFO % 1
+    FIFO2=FIFO % 2
+    
+    os.mkfifo(FIFO1)
+    os.mkfifo(FIFO2)
+    try:
+        os.system("soxmix -t .ul %s -t .ul %s -t ossdsp /dev/dsp &" % (FIFO1,FIFO2))
+        
+        c1=open(FIFO1,"w", 4096)
+        c2=open(FIFO2,"w", 4096)
+        fcntl.fcntl(c1.fileno(),fcntl.F_SETFL, os.O_NONBLOCK)
+        fcntl.fcntl(c2.fileno(),fcntl.F_SETFL, os.O_NONBLOCK)
+    
+    #    dsp,rd = os.popen2("sox -t .ul -c 2 - -t ossdsp /dev/dsp")
+        def play(pkt,last=[]):
+            if not pkt:
+                return 
+            if not pkt.haslayer(UDP):
+                return 
+            ip=pkt.getlayer(IP)
+            if s1 in [ip.src, ip.dst]:
+                if not last:
+                    last.append(pkt)
+                    return
+                load=last.pop()
+    #            x1 = load.load[12:]
+                c1.write(load.load[12:])
+                if load.getlayer(IP).src == ip.src:
+    #                x2 = ""
+                    c2.write("\x00"*len(load.load[12:]))
+                    last.append(pkt)
+                else:
+    #                x2 = pkt.load[:12]
+                    c2.write(pkt.load[12:])
+    #            dsp.write(merge(x1,x2))
+    
+        if list is None:
+            sniff(store=0, prn=play, **kargs)
+        else:
+            for p in list:
+                play(p)
+    finally:
+        os.unlink(FIFO1)
+        os.unlink(FIFO2)
+
+
+
+def voip_play1(s1,list=None,**kargs):
+
+    
+    dsp,rd = os.popen2("sox -t .ul - -t ossdsp /dev/dsp")
+    def play(pkt):
+        if not pkt:
+            return 
+        if not pkt.haslayer(UDP):
+            return 
+        ip=pkt.getlayer(IP)
+        if s1 in [ip.src, ip.dst]:
+            dsp.write(pkt.getlayer(Raw).load[12:])
+    try:
+        if list is None:
+            sniff(store=0, prn=play, **kargs)
+        else:
+            for p in list:
+                play(p)
+    finally:
+        dsp.close()
+        rd.close()
+
+def voip_play2(s1,**kargs):
+    dsp,rd = os.popen2("sox -t .ul -c 2 - -t ossdsp /dev/dsp")
+    def play(pkt,last=[]):
+        if not pkt:
+            return 
+        if not pkt.haslayer(UDP):
+            return 
+        ip=pkt.getlayer(IP)
+        if s1 in [ip.src, ip.dst]:
+            if not last:
+                last.append(pkt)
+                return
+            load=last.pop()
+            x1 = load.load[12:]
+#            c1.write(load.load[12:])
+            if load.getlayer(IP).src == ip.src:
+                x2 = ""
+#                c2.write("\x00"*len(load.load[12:]))
+                last.append(pkt)
+            else:
+                x2 = pkt.load[:12]
+#                c2.write(pkt.load[12:])
+            dsp.write(merge(x1,x2))
+            
+    sniff(store=0, prn=play, **kargs)
+
+def voip_play3(lst=None,**kargs):
+    dsp,rd = os.popen2("sox -t .ul - -t ossdsp /dev/dsp")
+    try:
+        def play(pkt, dsp=dsp):
+            if pkt and pkt.haslayer(UDP) and pkt.haslayer(Raw):
+                dsp.write(pkt.getlayer(RTP).load)
+        if lst is None:
+            sniff(store=0, prn=play, **kargs)
+        else:
+            for p in lst:
+                play(p)
+    finally:
+        try:
+            dsp.close()
+            rd.close()
+        except:
+            pass
+
diff --git a/scapy/volatile.py b/scapy/volatile.py
new file mode 100644
index 0000000000000000000000000000000000000000..8a1b831f9b79ccf0a028660baedcf50e637491c8
--- /dev/null
+++ b/scapy/volatile.py
@@ -0,0 +1,280 @@
+import random,time
+
+####################
+## Random numbers ##
+####################
+
+def randseq(inf, sup, seed=None, forever=1, renewkeys=0):
+    """iterate through a sequence in random order.
+       When all the values have been drawn, if forever=1, the drawing is done again.
+       If renewkeys=0, the draw will be in the same order, guaranteeing that the same
+       number will be drawn in not less than the number of integers of the sequence"""
+    rnd = random.Random(seed)
+    sbox_size = 256
+
+    top = sup-inf+1
+    
+    n=0
+    while (1<<n) < top:
+        n += 1
+
+    fs = min(3,(n+1)/2)
+    fsmask = 2**fs-1
+    rounds = max(n,3)
+    turns = 0
+
+    while 1:
+        if turns == 0 or renewkeys:
+            sbox = [rnd.randint(0,fsmask) for k in xrange(sbox_size)]
+        turns += 1
+        i = 0
+        while i < 2**n:
+            ct = i
+            i += 1
+            for k in range(rounds): # Unbalanced Feistel Network
+                lsb = ct & fsmask
+                ct >>= fs
+                lsb ^= sbox[ct%sbox_size]
+                ct |= lsb << (n-fs)
+            
+            if ct < top:
+                yield inf+ct
+        if not forever:
+            break
+
+
+class VolatileValue:
+    def __repr__(self):
+        return "<%s>" % self.__class__.__name__
+    def __getattr__(self, attr):
+        if attr == "__setstate__":
+            raise AttributeError(attr)
+        return getattr(self._fix(),attr)
+    def _fix(self):
+        return None
+
+
+class RandField(VolatileValue):
+    pass
+
+
+class RandNum(RandField):
+    min = 0
+    max = 0
+    def __init__(self, min, max):
+        self.seq = randseq(min,max)
+    def _fix(self):
+        return self.seq.next()
+
+class RandNumGamma(RandField):
+    def __init__(self, alpha, beta):
+        self.alpha = alpha
+        self.beta = beta
+    def _fix(self):
+        return int(round(random.gammavariate(self.alpha, self.beta)))
+
+class RandNumGauss(RandField):
+    def __init__(self, mu, sigma):
+        self.mu = mu
+        self.sigma = sigma
+    def _fix(self):
+        return int(round(random.gauss(self.mu, self.sigma)))
+
+class RandNumExpo(RandField):
+    def __init__(self, lambd):
+        self.lambd = lambd
+    def _fix(self):
+        return int(round(random.expovariate(self.lambd)))
+
+class RandByte(RandNum):
+    def __init__(self):
+        RandNum.__init__(self, 0, 2L**8-1)
+
+class RandShort(RandNum):
+    def __init__(self):
+        RandNum.__init__(self, 0, 2L**16-1)
+
+class RandInt(RandNum):
+    def __init__(self):
+        RandNum.__init__(self, 0, 2L**32-1)
+
+class RandSInt(RandNum):
+    def __init__(self):
+        RandNum.__init__(self, -2L**31, 2L**31-1)
+
+class RandLong(RandNum):
+    def __init__(self):
+        RandNum.__init__(self, 0, 2L**64-1)
+
+class RandSLong(RandNum):
+    def __init__(self):
+        RandNum.__init__(self, -2L**63, 2L**63-1)
+
+class RandChoice(RandField):
+    def __init__(self, *args):
+        if not args:
+            raise TypeError("RandChoice needs at least one choice")
+        self._choice = args
+    def _fix(self):
+        return random.choice(self._choice)
+    
+class RandString(RandField):
+    def __init__(self, size, chars="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"):
+        self.chars = chars
+        self.size = size
+    def _fix(self):
+        s = ""
+        for i in range(self.size):
+            s += random.choice(self.chars)
+        return s
+
+class RandBin(RandString):
+    def __init__(self, size):
+        RandString.__init__(self, size, "".join(map(chr,range(256))))
+
+
+class RandTermString(RandString):
+    def __init__(self, size, term):
+        RandString.__init__(self, size, "".join(map(chr,range(1,256))))
+        self.term = term
+    def _fix(self):
+        return RandString._fix(self)+self.term
+    
+    
+
+class RandIP(RandString):
+    def __init__(self, iptemplate="0.0.0.0/0"):
+        self.ip = Net(iptemplate)
+    def _fix(self):
+        return self.ip.choice()
+
+class RandMAC(RandString):
+    def __init__(self, template="*"):
+        template += ":*:*:*:*:*"
+        template = template.split(":")
+        self.mac = ()
+        for i in range(6):
+            if template[i] == "*":
+                v = RandByte()
+            elif "-" in template[i]:
+                x,y = template[i].split("-")
+                v = RandNum(int(x,16), int(y,16))
+            else:
+                v = int(template[i],16)
+            self.mac += (v,)
+    def _fix(self):
+        return "%02x:%02x:%02x:%02x:%02x:%02x" % self.mac
+    
+
+class RandOID(RandString):
+    def __init__(self, fmt=None, depth=RandNumExpo(0.1), idnum=RandNumExpo(0.01)):
+        self.ori_fmt = fmt
+        if fmt is not None:
+            fmt = fmt.split(".")
+            for i in range(len(fmt)):
+                if "-" in fmt[i]:
+                    fmt[i] = tuple(map(int, fmt[i].split("-")))
+        self.fmt = fmt
+        self.depth = depth
+        self.idnum = idnum
+    def __repr__(self):
+        if self.ori_fmt is None:
+            return "<%s>" % self.__class__.__name__
+        else:
+            return "<%s [%s]>" % (self.__class__.__name__, self.ori_fmt)
+    def _fix(self):
+        if self.fmt is None:
+            return ".".join(map(str, [self.idnum for i in xrange(1+self.depth)]))
+        else:
+            oid = []
+            for i in self.fmt:
+                if i == "*":
+                    oid.append(str(self.idnum))
+                elif i == "**":
+                    oid += map(str, [self.idnum for i in xrange(1+self.depth)])
+                elif type(i) is tuple:
+                    oid.append(str(random.randrange(*i)))
+                else:
+                    oid.append(i)
+            return ".".join(oid)
+            
+
+
+class RandDHCPOptions(RandField):
+    def __init__(self, size=None, rndstr=None):
+        if size is None:
+            size = RandNumExpo(0.05)
+        self.size = size
+        if rndstr is None:
+            rndstr = RandBin(RandNum(0,255))
+        self.rndstr=rndstr
+        self._opts = DHCPOptions.values()
+        self._opts.remove("pad")
+        self._opts.remove("end")
+    def _fix(self):
+        op = []
+        for k in range(self.size):
+            o = random.choice(self._opts)
+            if type(o) is str:
+                op.append((o,self.rndstr*1))
+            else:
+                op.append((o.name, o.randval()._fix()))
+        return op
+            
+
+# Automatic timestamp
+
+class AutoTime(VolatileValue):
+    def __init__(self, base=None):
+        if base == None:
+            self.diff = 0
+        else:
+            self.diff = time.time()-base
+    def _fix(self):
+        return time.time()-self.diff
+            
+class IntAutoTime(AutoTime):
+    def _fix(self):
+        return int(time.time()-self.diff)
+
+
+class ZuluTime(AutoTime):
+    def __init__(self, diff=None):
+        self.diff=diff
+    def _fix(self):
+        return time.strftime("%y%m%d%H%M%SZ",time.gmtime(time.time()+self.diff))
+
+
+class DelayedEval(VolatileValue):
+    """ Exemple of usage: DelayedEval("time.time()") """
+    def __init__(self, expr):
+        self.expr = expr
+    def _fix(self):
+        return eval(self.expr)
+
+
+class IncrementalValue(VolatileValue):
+    def __init__(self, start=0, step=1, restart=-1):
+        self.start = self.val = start
+        self.step = step
+        self.restart = restart
+    def _fix(self):
+        v = self.val
+        if self.val == self.restart :
+            self.val = self.start
+        else:
+            self.val += self.step
+        return v
+
+class CorruptedBytes(VolatileValue):
+    def __init__(self, s, p=0.01, n=None):
+        self.s = s
+        self.p = p
+        self.n = n
+    def _fix(self):
+        return corrupt_bytes(self.s, self.p, self.n)
+
+class CorruptedBits(CorruptedBytes):
+    def _fix(self):
+        return corrupt_bits(self.s, self.p, self.n)
+