Advertisement
Guest User

Untitled

a guest
Jul 14th, 2011
274
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 28.09 KB | None | 0 0
  1. cat fields.py
  2. ## This file is part of Scapy
  3. ## See http://www.secdev.org/projects/scapy for more informations
  4. ## Copyright (C) Philippe Biondi <phil@secdev.org>
  5. ## This program is published under a GPLv2 license
  6.  
  7. """
  8. Fields: basic data structures that make up parts of packets.
  9. """
  10.  
  11. import struct,copy,socket
  12. from config import conf
  13. from volatile import *
  14. from data import *
  15. from utils import *
  16. from base_classes import BasePacket,Gen,Net
  17.  
  18.  
  19. ############
  20. ## Fields ##
  21. ############
  22.  
  23. class Field(object):
  24.     """For more informations on how this work, please refer to
  25.       http://www.secdev.org/projects/scapy/files/scapydoc.pdf
  26.       chapter ``Adding a New Field''"""
  27.     islist=0
  28.     holds_packets=0
  29.     def __init__(self, name, default, fmt="H"):
  30.         self.name = name
  31.         if fmt[0] in "@=<>!":
  32.             self.fmt = fmt
  33.         else:
  34.             self.fmt = "!"+fmt
  35.         self.default = self.any2i(None,default)
  36.         self.sz = struct.calcsize(self.fmt)
  37.         self.owners = []
  38.  
  39.     def register_owner(self, cls):
  40.         self.owners.append(cls)
  41.  
  42.     def i2len(self, pkt, x):
  43.         """Convert internal value to a length usable by a FieldLenField"""
  44.         return self.sz
  45.     def i2count(self, pkt, x):
  46.         """Convert internal value to a number of elements usable by a FieldLenField.
  47.        Always 1 except for list fields"""
  48.         return 1
  49.     def h2i(self, pkt, x):
  50.         """Convert human value to internal value"""
  51.         return x
  52.     def i2h(self, pkt, x):
  53.         """Convert internal value to human value"""
  54.         return x
  55.     def m2i(self, pkt, x):
  56.         """Convert machine value to internal value"""
  57.         return x
  58.     def i2m(self, pkt, x):
  59.         """Convert internal value to machine value"""
  60.         if x is None:
  61.             x = 0
  62.         return x
  63.     def any2i(self, pkt, x):
  64.         """Try to understand the most input values possible and make an internal value from them"""
  65.         return self.h2i(pkt, x)
  66.     def i2repr(self, pkt, x):
  67.         """Convert internal value to a nice representation"""
  68.         return repr(self.i2h(pkt,x))
  69.     def addfield(self, pkt, s, val):
  70.         """Add an internal value  to a string"""
  71.         return s+struct.pack(self.fmt, self.i2m(pkt,val))
  72.     def getfield(self, pkt, s):
  73.         """Extract an internal value from a string"""
  74.         return  s[self.sz:], self.m2i(pkt, struct.unpack(self.fmt, s[:self.sz])[0])
  75.     def do_copy(self, x):
  76.         if hasattr(x, "copy"):
  77.             return x.copy()
  78.         if type(x) is list:
  79.             x = x[:]
  80.             for i in xrange(len(x)):
  81.                 if isinstance(x[i], BasePacket):
  82.                     x[i] = x[i].copy()
  83.         return x
  84.     def __repr__(self):
  85.         return "<Field (%s).%s>" % (",".join(x.__name__ for x in self.owners),self.name)
  86.     def copy(self):
  87.         return copy.deepcopy(self)
  88.     def randval(self):
  89.         """Return a volatile object whose value is both random and suitable for this field"""
  90.         fmtt = self.fmt[-1]
  91.         if fmtt in "BHIQ":
  92.             return {"B":RandByte,"H":RandShort,"I":RandInt, "Q":RandLong}[fmtt]()
  93.         elif fmtt == "s":
  94.             if self.fmt[0] in "0123456789":
  95.                 l = int(self.fmt[:-1])
  96.             else:
  97.                 l = int(self.fmt[1:-1])
  98.             return RandBin(l)
  99.         else:
  100.             warning("no random class for [%s] (fmt=%s)." % (self.name, self.fmt))
  101.            
  102.  
  103.  
  104.  
  105. class Emph(object):
  106.     fld = ""
  107.     def __init__(self, fld):
  108.         self.fld = fld
  109.     def __getattr__(self, attr):
  110.         return getattr(self.fld,attr)
  111.     def __hash__(self):
  112.         return hash(self.fld)
  113.     def __eq__(self, other):
  114.         return self.fld == other
  115.    
  116.  
  117. class ActionField(object):
  118.     _fld = None
  119.     def __init__(self, fld, action_method, **kargs):
  120.         self._fld = fld
  121.         self._action_method = action_method
  122.         self._privdata = kargs
  123.     def any2i(self, pkt, val):
  124.         getattr(pkt, self._action_method)(val, self._fld, **self._privdata)
  125.         return getattr(self._fld, "any2i")(pkt, val)
  126.     def __getattr__(self, attr):
  127.         return getattr(self._fld,attr)
  128.  
  129.  
  130. class ConditionalField(object):
  131.     fld = None
  132.     def __init__(self, fld, cond):
  133.         self.fld = fld
  134.         self.cond = cond
  135.     def _evalcond(self,pkt):
  136.         return self.cond(pkt)
  137.        
  138.     def getfield(self, pkt, s):
  139.         if self._evalcond(pkt):
  140.             return self.fld.getfield(pkt,s)
  141.         else:
  142.             return s,None
  143.        
  144.     def addfield(self, pkt, s, val):
  145.         if self._evalcond(pkt):
  146.             return self.fld.addfield(pkt,s,val)
  147.         else:
  148.             return s
  149.     def __getattr__(self, attr):
  150.         return getattr(self.fld,attr)
  151.        
  152.  
  153. class PadField(object):
  154.     """Add bytes after the proxified field so that it ends at the specified
  155.       alignment from its begining"""
  156.     _fld = None
  157.     def __init__(self, fld, align, padwith=None):
  158.         self._fld = fld
  159.         self._align = align
  160.         self._padwith = padwith or ""
  161.  
  162.     def padlen(self, flen):
  163.         return -flen%self._align
  164.  
  165.     def getfield(self, pkt, s):
  166.         remain,val = self._fld.getfield(pkt,s)
  167.         padlen = self.padlen(len(s)-len(remain))
  168.         return remain[padlen:], val
  169.  
  170.     def addfield(self, pkt, s, val):
  171.         sval = self._fld.addfield(pkt, "", val)
  172.         return s+sval+struct.pack("%is" % (self.padlen(len(sval))), self._padwith)
  173.    
  174.     def __getattr__(self, attr):
  175.         return getattr(self._fld,attr)
  176.        
  177.  
  178. class MACField(Field,object):
  179.     def __init__(self, name, default):
  180.         Field.__init__(self, name, default, "6s")
  181.     def i2m(self, pkt, x):
  182.         if x is None:
  183.             return "\0\0\0\0\0\0"
  184.         return mac2str(x)
  185.     def m2i(self, pkt, x):
  186.         return str2mac(x)
  187.     def any2i(self, pkt, x):
  188.         if type(x) is str and len(x) is 6:
  189.             x = self.m2i(pkt, x)
  190.         return x
  191.     def i2repr(self, pkt, x):
  192.         x = self.i2h(pkt, x)
  193.         if self in conf.resolve:
  194.             x = conf.manufdb._resolve_MAC(x)
  195.         return x
  196.     def randval(self):
  197.         return RandMAC()
  198.  
  199.  
  200. class IPField(Field,object):
  201.     def __init__(self, name, default):
  202.         Field.__init__(self, name, default, "4s")
  203.     def h2i(self, pkt, x):
  204.         if type(x) is str:
  205.             try:
  206.                 inet_aton(x)
  207.             except socket.error:
  208.                 x = Net(x)
  209.         elif type(x) is list:
  210.             x = [self.h2i(pkt, n) for n in x]
  211.         return x
  212.     def resolve(self, x):
  213.         if self in conf.resolve:
  214.             try:
  215.                 ret = socket.gethostbyaddr(x)[0]
  216.             except:
  217.                 pass
  218.             else:
  219.                 if ret:
  220.                     return ret
  221.         return x
  222.     def i2m(self, pkt, x):
  223.         return inet_aton(x)
  224.     def m2i(self, pkt, x):
  225.         return inet_ntoa(x)
  226.     def any2i(self, pkt, x):
  227.         return self.h2i(pkt,x)
  228.     def i2repr(self, pkt, x):
  229.         return self.resolve(self.i2h(pkt, x))
  230.     def randval(self):
  231.         return RandIP()
  232.  
  233. class SourceIPField(IPField,object):
  234.     def __init__(self, name, dstname):
  235.         IPField.__init__(self, name, None)
  236.         self.dstname = dstname
  237.     def i2m(self, pkt, x):
  238.         if x is None:
  239.             iff,x,gw = pkt.route()
  240.             if x is None:
  241.                 x = "0.0.0.0"
  242.         return IPField.i2m(self, pkt, x)
  243.     def i2h(self, pkt, x):
  244.         if x is None:
  245.             dst=getattr(pkt,self.dstname)
  246.             if isinstance(dst,Gen):
  247.                 r = map(conf.route.route, dst)
  248.                 r.sort()
  249.                 if r[0] != r[-1]:
  250.                     warning("More than one possible route for %s"%repr(dst))
  251.                 iff,x,gw = r[0]
  252.             else:
  253.                 iff,x,gw = conf.route.route(dst)
  254.         return IPField.i2h(self, pkt, x)
  255.  
  256.    
  257.  
  258.  
  259. class ByteField(Field,object):
  260.     def __init__(self, name, default):
  261.         Field.__init__(self, name, default, "B")
  262.        
  263. class XByteField(ByteField,object):
  264.     def i2repr(self, pkt, x):
  265.         return lhex(self.i2h(pkt, x))
  266.  
  267. class OByteField(ByteField, object):
  268.     def i2repr(self, pkt, x):
  269.         return "%03o"%self.i2h(pkt, x)
  270.  
  271. class X3BytesField(XByteField, object):
  272.     def __init__(self, name, default):
  273.         Field.__init__(self, name, default, "!I")
  274.     def addfield(self, pkt, s, val):
  275.         return s+struct.pack(self.fmt, self.i2m(pkt,val))[1:4]
  276.     def getfield(self, pkt, s):
  277.         return  s[3:], self.m2i(pkt, struct.unpack(self.fmt, "\x00"+s[:3])[0])
  278.  
  279.  
  280. class ShortField(Field, object):
  281.     def __init__(self, name, default):
  282.         Field.__init__(self, name, default, "H")
  283.  
  284. class LEShortField(Field, object):
  285.     def __init__(self, name, default):
  286.         Field.__init__(self, name, default, "<H")
  287.  
  288. class XShortField(ShortField, object):
  289.     def i2repr(self, pkt, x):
  290.         return lhex(self.i2h(pkt, x))
  291.  
  292.  
  293. class IntField(Field,object):
  294.     def __init__(self, name, default):
  295.         Field.__init__(self, name, default, "I")
  296.  
  297. class SignedIntField(Field, object):
  298.     def __init__(self, name, default):
  299.         Field.__init__(self, name, default, "i")
  300.     def randval(self):
  301.         return RandSInt()
  302.  
  303. class LEIntField(Field, object):
  304.     def __init__(self, name, default):
  305.         Field.__init__(self, name, default, "<I")
  306.  
  307. class LESignedIntField(Field, object):
  308.     def __init__(self, name, default):
  309.         Field.__init__(self, name, default, "<i")
  310.     def randval(self):
  311.         return RandSInt()
  312.  
  313. class XIntField(IntField, object):
  314.     def i2repr(self, pkt, x):
  315.         return lhex(self.i2h(pkt, x))
  316.  
  317.  
  318. class LongField(Field,object):
  319.     def __init__(self, name, default):
  320.         Field.__init__(self, name, default, "Q")
  321.  
  322. class XLongField(LongField, object):
  323.     def i2repr(self, pkt, x):
  324.         return lhex(self.i2h(pkt, x))
  325.  
  326. class IEEEFloatField(Field, object):
  327.     def __init__(self, name, default):
  328.         Field.__init__(self, name, default, "f")
  329.  
  330. class IEEEDoubleField(Field, object):
  331.     def __init__(self, name, default):
  332.         Field.__init__(self, name, default, "d")
  333.  
  334.  
  335. class StrField(Field, object):
  336.     def __init__(self, name, default, fmt="H", remain=0):
  337.         Field.__init__(self,name,default,fmt)
  338.         self.remain = remain        
  339.     def i2len(self, pkt, i):
  340.         return len(i)
  341.     def i2m(self, pkt, x):
  342.         if x is None:
  343.             x = ""
  344.         elif type(x) is not str:
  345.             x=str(x)
  346.         return x
  347.     def addfield(self, pkt, s, val):
  348.         return s+self.i2m(pkt, val)
  349.     def getfield(self, pkt, s):
  350.         if self.remain == 0:
  351.             return "",self.m2i(pkt, s)
  352.         else:
  353.             return s[-self.remain:],self.m2i(pkt, s[:-self.remain])
  354.     def randval(self):
  355.         return RandBin(RandNum(0,1200))
  356.  
  357. class PacketField(StrField, object):
  358.     holds_packets=1
  359.     def __init__(self, name, default, cls, remain=0):
  360.         StrField.__init__(self, name, default, remain=remain)
  361.         self.cls = cls
  362.     def i2m(self, pkt, i):
  363.         return str(i)
  364.     def m2i(self, pkt, m):
  365.         return self.cls(m)
  366.     def getfield(self, pkt, s):
  367.         i = self.m2i(pkt, s)
  368.         remain = ""
  369.         if 'Padding' in i:
  370.             r = i['Padding']
  371.             del(r.underlayer.payload)
  372.             remain = r.load
  373.         return remain,i
  374.    
  375. class PacketLenField(PacketField,object):
  376.     holds_packets=1
  377.     def __init__(self, name, default, cls, length_from=None):
  378.         PacketField.__init__(self, name, default, cls)
  379.         self.length_from = length_from
  380.     def getfield(self, pkt, s):
  381.         l = self.length_from(pkt)
  382.         try:
  383.             i = self.m2i(pkt, s[:l])
  384.         except Exception:
  385.             if conf.debug_dissector:
  386.                 raise
  387.             i = conf.raw_layer(load=s[:l])
  388.         return s[l:],i
  389.  
  390.  
  391. class PacketListField(PacketField, object):
  392.     islist = 1
  393.     holds_packets=1
  394.     def __init__(self, name, default, cls, count_from=None, length_from=None):
  395.         if default is None:
  396.             default = []  # Create a new list for each instance
  397.         PacketField.__init__(self, name, default, cls)
  398.         self.count_from = count_from
  399.         self.length_from = length_from
  400.  
  401.  
  402.     def any2i(self, pkt, x):
  403.         if type(x) is not list:
  404.             return [x]
  405.         else:
  406.             return x
  407.     def i2count(self, pkt, val):
  408.         if type(val) is list:
  409.             return len(val)
  410.         return 1
  411.     def i2len(self, pkt, val):
  412.         return sum( len(p) for p in val )
  413.     def do_copy(self, x):
  414.         return map(lambda p:p.copy(), x)
  415.     def getfield(self, pkt, s):
  416.         c = l = None
  417.         if self.length_from is not None:
  418.             l = self.length_from(pkt)
  419.         elif self.count_from is not None:
  420.             c = self.count_from(pkt)
  421.            
  422.         lst = []
  423.         ret = ""
  424.         remain = s
  425.         if l is not None:
  426.             remain,ret = s[:l],s[l:]
  427.         while remain:
  428.             if c is not None:
  429.                 if c <= 0:
  430.                     break
  431.                 c -= 1
  432.             try:
  433.                 p = self.m2i(pkt,remain)
  434.             except Exception:
  435.                 if conf.debug_dissector:
  436.                     raise
  437.                 p = conf.raw_layer(load=remain)
  438.                 remain = ""
  439.             else:
  440.                 if 'Padding' in p:
  441.                     pad = p['Padding']
  442.                     remain = pad.load
  443.                     del(pad.underlayer.payload)
  444.                 else:
  445.                     remain = ""
  446.             lst.append(p)
  447.         return remain+ret,lst
  448.     def addfield(self, pkt, s, val):
  449.         return s+"".join(map(str, val))
  450.  
  451.  
  452. class StrFixedLenField(StrField, object):
  453.     def __init__(self, name, default, length=None, length_from=None):
  454.         StrField.__init__(self, name, default)
  455.         self.length_from  = length_from
  456.         if length is not None:
  457.             self.length_from = lambda pkt,length=length: length
  458.     def i2repr(self, pkt, v):
  459.         if type(v) is str:
  460.             v = v.rstrip("\0")
  461.         return repr(v)
  462.     def getfield(self, pkt, s):
  463.         l = self.length_from(pkt)
  464.         return s[l:], self.m2i(pkt,s[:l])
  465.     def addfield(self, pkt, s, val):
  466.         l = self.length_from(pkt)
  467.         return s+struct.pack("%is"%l,self.i2m(pkt, val))
  468.     def randval(self):
  469.         try:
  470.             l = self.length_from(None)
  471.         except:
  472.             l = RandNum(0,200)
  473.         return RandBin(l)
  474.  
  475. class StrFixedLenEnumField(StrFixedLenField, object):
  476.     def __init__(self, name, default, length=None, enum=None, length_from=None):
  477.         StrFixedLenField.__init__(self, name, default, length=length, length_from=length_from)
  478.         self.enum = enum
  479.     def i2repr(self, pkt, v):
  480.         r = v.rstrip("\0")
  481.         rr = repr(r)
  482.         if v in self.enum:
  483.             rr = "%s (%s)" % (rr, self.enum[v])
  484.         elif r in self.enum:
  485.             rr = "%s (%s)" % (rr, self.enum[r])
  486.         return rr
  487.  
  488. class NetBIOSNameField(StrFixedLenField, object):
  489.     def __init__(self, name, default, length=31):
  490.         StrFixedLenField.__init__(self, name, default, length)
  491.     def i2m(self, pkt, x):
  492.         l = self.length_from(pkt)/2
  493.         if x is None:
  494.             x = ""
  495.         x += " "*(l)
  496.         x = x[:l]
  497.         x = "".join(map(lambda x: chr(0x41+(ord(x)>>4))+chr(0x41+(ord(x)&0xf)), x))
  498.         x = " "+x
  499.         return x
  500.     def m2i(self, pkt, x):
  501.         x = x.strip("\x00").strip(" ")
  502.         return "".join(map(lambda x,y: chr((((ord(x)-1)&0xf)<<4)+((ord(y)-1)&0xf)), x[::2],x[1::2]))
  503.  
  504. class StrLenField(StrField, object):
  505.     def __init__(self, name, default, fld=None, length_from=None):
  506.         StrField.__init__(self, name, default)
  507.         self.length_from = length_from
  508.     def getfield(self, pkt, s):
  509.         l = self.length_from(pkt)
  510.         return s[l:], self.m2i(pkt,s[:l])
  511.  
  512. class FieldListField(Field, object):
  513.     islist=1
  514.     def __init__(self, name, default, field, length_from=None, count_from=None):
  515.         if default is None:
  516.             default = []  # Create a new list for each instance
  517.         Field.__init__(self, name, default)
  518.         self.count_from = count_from
  519.         self.length_from = length_from
  520.         self.field = field            
  521.            
  522.     def i2count(self, pkt, val):
  523.         if type(val) is list:
  524.             return len(val)
  525.         return 1
  526.     def i2len(self, pkt, val):
  527.         return sum( self.field.i2len(pkt,v) for v in val )
  528.    
  529.     def i2m(self, pkt, val):
  530.         if val is None:
  531.             val = []
  532.         return val
  533.     def any2i(self, pkt, x):
  534.         if type(x) is not list:
  535.             return [x]
  536.         else:
  537.             return x
  538.     def addfield(self, pkt, s, val):
  539.         val = self.i2m(pkt, val)
  540.         for v in val:
  541.             s = self.field.addfield(pkt, s, v)
  542.         return s
  543.     def getfield(self, pkt, s):
  544.         c = l = None
  545.         if self.length_from is not None:
  546.             l = self.length_from(pkt)
  547.         elif self.count_from is not None:
  548.             c = self.count_from(pkt)
  549.  
  550.         val = []
  551.         ret=""
  552.         if l is not None:
  553.             s,ret = s[:l],s[l:]
  554.            
  555.         while s:
  556.             if c is not None:
  557.                 if c <= 0:
  558.                     break
  559.                 c -= 1
  560.             s,v = self.field.getfield(pkt, s)
  561.             val.append(v)
  562.         return s+ret, val
  563.  
  564. class FieldLenField(Field, object):
  565.     def __init__(self, name, default,  length_of=None, fmt = "H", count_of=None, adjust=lambda pkt,x:x, fld=None):
  566.         Field.__init__(self, name, default, fmt)
  567.         self.length_of=length_of
  568.         self.count_of=count_of
  569.         self.adjust=adjust
  570.         if fld is not None:
  571.             FIELD_LENGTH_MANAGEMENT_DEPRECATION(self.__class__.__name__)
  572.             self.length_of = fld
  573.     def i2m(self, pkt, x):
  574.         if x is None:
  575.             if self.length_of is not None:
  576.                 fld,fval = pkt.getfield_and_val(self.length_of)
  577.                 f = fld.i2len(pkt, fval)
  578.             else:
  579.                 fld,fval = pkt.getfield_and_val(self.count_of)
  580.                 f = fld.i2count(pkt, fval)
  581.             x = self.adjust(pkt,f)
  582.         return x
  583.  
  584. class StrNullField(StrField, object):
  585.     def addfield(self, pkt, s, val):
  586.         return s+self.i2m(pkt, val)+"\x00"
  587.     def getfield(self, pkt, s):
  588.         l = s.find("\x00")
  589.         if l < 0:
  590.             #XXX \x00 not found
  591.             return "",s
  592.         return s[l+1:],self.m2i(pkt, s[:l])
  593.     def randval(self):
  594.         return RandTermString(RandNum(0,1200),"\x00")
  595.  
  596. class StrStopField(StrField, object):
  597.     def __init__(self, name, default, stop, additionnal=0):
  598.         Field.__init__(self, name, default)
  599.         self.stop=stop
  600.         self.additionnal=additionnal
  601.     def getfield(self, pkt, s):
  602.         l = s.find(self.stop)
  603.         if l < 0:
  604.             return "",s
  605. #            raise Scapy_Exception,"StrStopField: stop value [%s] not found" %stop
  606.         l += len(self.stop)+self.additionnal
  607.         return s[l:],s[:l]
  608.     def randval(self):
  609.         return RandTermString(RandNum(0,1200),self.stop)
  610.  
  611. class LenField(Field, object):
  612.     def i2m(self, pkt, x):
  613.         if x is None:
  614.             x = len(pkt.payload)
  615.         return x
  616.  
  617. class BCDFloatField(Field,object):
  618.     def i2m(self, pkt, x):
  619.         return int(256*x)
  620.     def m2i(self, pkt, x):
  621.         return x/256.0
  622.  
  623. class BitField(Field, object):
  624.     def __init__(self, name, default, size):
  625.         Field.__init__(self, name, default)
  626.         self.rev = size < 0
  627.         self.size = abs(size)
  628.     def reverse(self, val):
  629.         if self.size == 16:
  630.             val = socket.ntohs(val)
  631.         elif self.size == 32:
  632.             val = socket.ntohl(val)
  633.         return val
  634.        
  635.     def addfield(self, pkt, s, val):
  636.         val = self.i2m(pkt, val)
  637.         if type(s) is tuple:
  638.             s,bitsdone,v = s
  639.         else:
  640.             bitsdone = 0
  641.             v = 0
  642.         if self.rev:
  643.             val = self.reverse(val)
  644.         v <<= self.size
  645.         v |= val & ((1L<<self.size) - 1)
  646.         bitsdone += self.size
  647.         while bitsdone >= 8:
  648.             bitsdone -= 8
  649.             s = s+struct.pack("!B", v >> bitsdone)
  650.             v &= (1L<<bitsdone)-1
  651.         if bitsdone:
  652.             return s,bitsdone,v
  653.         else:
  654.             return s
  655.     def getfield(self, pkt, s):
  656.         if type(s) is tuple:
  657.             s,bn = s
  658.         else:
  659.             bn = 0
  660.         # we don't want to process all the string
  661.         nb_bytes = (self.size+bn-1)/8 + 1
  662.         w = s[:nb_bytes]
  663.  
  664.         # split the substring byte by byte
  665.         bytes = struct.unpack('!%dB' % nb_bytes , w)
  666.  
  667.         b = 0L
  668.         for c in range(nb_bytes):
  669.             b |= long(bytes[c]) << (nb_bytes-c-1)*8
  670.  
  671.         # get rid of high order bits
  672.         b &= (1L << (nb_bytes*8-bn)) - 1
  673.  
  674.         # remove low order bits
  675.         b = b >> (nb_bytes*8 - self.size - bn)
  676.  
  677.         if self.rev:
  678.             b = self.reverse(b)
  679.  
  680.         bn += self.size
  681.         s = s[bn/8:]
  682.         bn = bn%8
  683.         b = self.m2i(pkt, b)
  684.         if bn:
  685.             return (s,bn),b
  686.         else:
  687.             return s,b
  688.     def randval(self):
  689.         return RandNum(0,2**self.size-1)
  690.  
  691.  
  692. class BitFieldLenField(BitField, object):
  693.     def __init__(self, name, default, size, length_of=None, count_of=None, adjust=lambda pkt,x:x):
  694.         BitField.__init__(self, name, default, size)
  695.         self.length_of=length_of
  696.         self.count_of=count_of
  697.         self.adjust=adjust
  698.     def i2m(self, pkt, x):
  699.         return FieldLenField.i2m.im_func(self, pkt, x)
  700.  
  701.  
  702. class XBitField(BitField, object):
  703.     def i2repr(self, pkt, x):
  704.         return lhex(self.i2h(pkt,x))
  705.  
  706.  
  707. class EnumField(Field, object):
  708.     def __init__(self, name, default, enum, fmt = "H"):
  709.         i2s = self.i2s = {}
  710.         s2i = self.s2i = {}
  711.         if type(enum) is list:
  712.             keys = xrange(len(enum))
  713.         else:
  714.             keys = enum.keys()
  715.         if filter(lambda x: type(x) is str, keys):
  716.             i2s,s2i = s2i,i2s
  717.         for k in keys:
  718.             i2s[k] = enum[k]
  719.             s2i[enum[k]] = k
  720.         Field.__init__(self, name, default, fmt)
  721.     def any2i_one(self, pkt, x):
  722.         if type(x) is str:
  723.             x = self.s2i[x]
  724.         return x
  725.     def i2repr_one(self, pkt, x):
  726.         if self not in conf.noenum and not isinstance(x,VolatileValue) and x in self.i2s:
  727.             return self.i2s[x]
  728.         return repr(x)
  729.    
  730.     def any2i(self, pkt, x):
  731.         if type(x) is list:
  732.             return map(lambda z,pkt=pkt:self.any2i_one(pkt,z), x)
  733.         else:
  734.             return self.any2i_one(pkt,x)        
  735.     def i2repr(self, pkt, x):
  736.         if type(x) is list:
  737.             return map(lambda z,pkt=pkt:self.i2repr_one(pkt,z), x)
  738.         else:
  739.             return self.i2repr_one(pkt,x)
  740.  
  741. class CharEnumField(EnumField, object):
  742.     def __init__(self, name, default, enum, fmt = "1s"):
  743.         EnumField.__init__(self, name, default, enum, fmt)
  744.         k = self.i2s.keys()
  745.         if k and len(k[0]) != 1:
  746.             self.i2s,self.s2i = self.s2i,self.i2s
  747.     def any2i_one(self, pkt, x):
  748.         if len(x) != 1:
  749.             x = self.s2i[x]
  750.         return x
  751.  
  752. class BitEnumField(BitField,EnumField, object):
  753.     def __init__(self, name, default, size, enum):
  754.         EnumField.__init__(self, name, default, enum)
  755.         self.rev = size < 0
  756.         self.size = abs(size)
  757.     def any2i(self, pkt, x):
  758.         return EnumField.any2i(self, pkt, x)
  759.     def i2repr(self, pkt, x):
  760.         return EnumField.i2repr(self, pkt, x)
  761.  
  762. class ShortEnumField(EnumField, object):
  763.     def __init__(self, name, default, enum):
  764.         EnumField.__init__(self, name, default, enum, "H")
  765.  
  766. class LEShortEnumField(EnumField, object):
  767.     def __init__(self, name, default, enum):
  768.         EnumField.__init__(self, name, default, enum, "<H")
  769.  
  770. class ByteEnumField(EnumField, object):
  771.     def __init__(self, name, default, enum):
  772.         EnumField.__init__(self, name, default, enum, "B")
  773.  
  774. class IntEnumField(EnumField, object):
  775.     def __init__(self, name, default, enum):
  776.         EnumField.__init__(self, name, default, enum, "I")
  777.  
  778. class SignedIntEnumField(EnumField, object):
  779.     def __init__(self, name, default, enum):
  780.         EnumField.__init__(self, name, default, enum, "i")
  781.     def randval(self):
  782.         return RandSInt()
  783.  
  784. class LEIntEnumField(EnumField, object):
  785.     def __init__(self, name, default, enum):
  786.         EnumField.__init__(self, name, default, enum, "<I")
  787.  
  788. class XShortEnumField(ShortEnumField, object):
  789.     def i2repr_one(self, pkt, x):
  790.         if self not in conf.noenum and not isinstance(x,VolatileValue) and x in self.i2s:
  791.             return self.i2s[x]
  792.         return lhex(x)
  793.  
  794. class MultiEnumField(EnumField, object):
  795.     def __init__(self, name, default, enum, depends_on, fmt = "H"):
  796.        
  797.         self.depends_on = depends_on
  798.         self.i2s_multi = enum
  799.         self.s2i_multi = {}
  800.         self.s2i_all = {}
  801.         for m in enum:
  802.             self.s2i_multi[m] = s2i = {}
  803.             for k,v in enum[m].iteritems():
  804.                 s2i[v] = k
  805.                 self.s2i_all[v] = k
  806.         Field.__init__(self, name, default, fmt)
  807.     def any2i_one(self, pkt, x):
  808.         if type (x) is str:
  809.             v = self.depends_on(pkt)
  810.             if v in self.s2i_multi:
  811.                 s2i = self.s2i_multi[v]
  812.                 if x in s2i:
  813.                     return s2i[x]
  814.             return self.s2i_all[x]
  815.         return x
  816.     def i2repr_one(self, pkt, x):
  817.         v = self.depends_on(pkt)
  818.         if v in self.i2s_multi:
  819.             return self.i2s_multi[v].get(x,x)
  820.         return x
  821.  
  822. class BitMultiEnumField(BitField,MultiEnumField, object):
  823.     def __init__(self, name, default, size, enum, depends_on):
  824.         MultiEnumField.__init__(self, name, default, enum)
  825.         self.rev = size < 0
  826.         self.size = abs(size)
  827.     def any2i(self, pkt, x):
  828.         return MultiEnumField.any2i(self, pkt, x)
  829.     def i2repr(self, pkt, x):
  830.         return MultiEnumField.i2repr(self, pkt, x)
  831.  
  832.  
  833. # Little endian long field
  834. class LELongField(Field, object):
  835.     def __init__(self, name, default):
  836.         Field.__init__(self, name, default, "<Q")
  837.  
  838. # Little endian fixed length field
  839. class LEFieldLenField(FieldLenField, object):
  840.     def __init__(self, name, default,  length_of=None, fmt = "<H", count_of=None, adjust=lambda pkt,x:x, fld=None):
  841.         FieldLenField.__init__(self, name, default, length_of=length_of, fmt=fmt, fld=fld, adjust=adjust)
  842.  
  843.  
  844. class FlagsField(BitField, object):
  845.     def __init__(self, name, default, size, names):
  846.         self.multi = type(names) is list
  847.         if self.multi:
  848.             self.names = map(lambda x:[x], names)
  849.         else:
  850.             self.names = names
  851.         BitField.__init__(self, name, default, size)
  852.     def any2i(self, pkt, x):
  853.         if type(x) is str:
  854.             if self.multi:
  855.                 x = map(lambda y:[y], x.split("+"))
  856.             y = 0
  857.             for i in x:
  858.                 y |= 1 << self.names.index(i)
  859.             x = y
  860.         return x
  861.     def i2repr(self, pkt, x):
  862.         if type(x) is list or type(x) is tuple:
  863.             return repr(x)
  864.         if self.multi:
  865.             r = []
  866.         else:
  867.             r = ""
  868.         i=0
  869.         while x:
  870.             if x & 1:
  871.                 r += self.names[i]
  872.             i += 1
  873.             x >>= 1
  874.         if self.multi:
  875.             r = "+".join(r)
  876.         return r
  877.  
  878.            
  879.  
  880.  
  881. class FixedPointField(BitField, object):
  882.     def __init__(self, name, default, size, frac_bits=16):
  883.         self.frac_bits = frac_bits
  884.         BitField.__init__(self, name, default, size)
  885.  
  886.     def any2i(self, pkt, val):
  887.         if val is None:
  888.             return val
  889.         ival = int(val)
  890.         fract = int( (val-ival) * 2**self.frac_bits )
  891.         return (ival << self.frac_bits) | fract
  892.  
  893.     def i2h(self, pkt, val):
  894.         int_part = val >> self.frac_bits
  895.         frac_part = val & (1L << self.frac_bits) - 1
  896.         frac_part /= 2.0**self.frac_bits
  897.         return int_part+frac_part
  898.     def i2repr(self, pkt, val):
  899.         return self.i2h(pkt, val)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement