• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1## This file is part of Scapy
2## See http://www.secdev.org/projects/scapy for more informations
3## Copyright (C) Philippe Biondi <phil@secdev.org>
4## This program is published under a GPLv2 license
5
6"""
7Fields: basic data structures that make up parts of packets.
8"""
9
10from __future__ import absolute_import
11import struct,copy,socket,collections
12from scapy.config import conf
13from scapy.dadict import DADict
14from scapy.volatile import *
15from scapy.data import *
16from scapy.compat import *
17from scapy.utils import *
18from scapy.base_classes import BasePacket, Gen, Net, Field_metaclass
19from scapy.error import warning
20import scapy.modules.six as six
21from scapy.modules.six.moves import range
22
23
24############
25## Fields ##
26############
27
28class Field(six.with_metaclass(Field_metaclass, object)):
29    """For more informations on how this work, please refer to
30       http://www.secdev.org/projects/scapy/files/scapydoc.pdf
31       chapter ``Adding a New Field''"""
32    __slots__ = ["name", "fmt", "default", "sz", "owners"]
33    islist = 0
34    ismutable = False
35    holds_packets = 0
36    def __init__(self, name, default, fmt="H"):
37        self.name = name
38        if fmt[0] in "@=<>!":
39            self.fmt = fmt
40        else:
41            self.fmt = "!"+fmt
42        self.default = self.any2i(None,default)
43        self.sz = struct.calcsize(self.fmt)
44        self.owners = []
45
46    def register_owner(self, cls):
47        self.owners.append(cls)
48
49    def i2len(self, pkt, x):
50        """Convert internal value to a length usable by a FieldLenField"""
51        return self.sz
52    def i2count(self, pkt, x):
53        """Convert internal value to a number of elements usable by a FieldLenField.
54        Always 1 except for list fields"""
55        return 1
56    def h2i(self, pkt, x):
57        """Convert human value to internal value"""
58        return x
59    def i2h(self, pkt, x):
60        """Convert internal value to human value"""
61        return x
62    def m2i(self, pkt, x):
63        """Convert machine value to internal value"""
64        return x
65    def i2m(self, pkt, x):
66        """Convert internal value to machine value"""
67        if x is None:
68            x = 0
69        elif isinstance(x, str):
70            return raw(x)
71        return x
72    def any2i(self, pkt, x):
73        """Try to understand the most input values possible and make an internal value from them"""
74        return self.h2i(pkt, x)
75    def i2repr(self, pkt, x):
76        """Convert internal value to a nice representation"""
77        return repr(self.i2h(pkt,x))
78    def addfield(self, pkt, s, val):
79        """Add an internal value  to a string"""
80        return s+struct.pack(self.fmt, self.i2m(pkt,val))
81    def getfield(self, pkt, s):
82        """Extract an internal value from a string"""
83        return  s[self.sz:], self.m2i(pkt, struct.unpack(self.fmt, s[:self.sz])[0])
84    def do_copy(self, x):
85        if hasattr(x, "copy"):
86            return x.copy()
87        if isinstance(x, list):
88            x = x[:]
89            for i in range(len(x)):
90                if isinstance(x[i], BasePacket):
91                    x[i] = x[i].copy()
92        return x
93    def __repr__(self):
94        return "<Field (%s).%s>" % (",".join(x.__name__ for x in self.owners),self.name)
95    def copy(self):
96        return copy.deepcopy(self)
97    def randval(self):
98        """Return a volatile object whose value is both random and suitable for this field"""
99        fmtt = self.fmt[-1]
100        if fmtt in "BHIQ":
101            return {"B":RandByte,"H":RandShort,"I":RandInt, "Q":RandLong}[fmtt]()
102        elif fmtt == "s":
103            if self.fmt[0] in "0123456789":
104                l = int(self.fmt[:-1])
105            else:
106                l = int(self.fmt[1:-1])
107            return RandBin(l)
108        else:
109            warning("no random class for [%s] (fmt=%s).", self.name, self.fmt)
110
111
112
113
114class Emph(object):
115    __slots__ = ["fld"]
116    def __init__(self, fld):
117        self.fld = fld
118    def __getattr__(self, attr):
119        return getattr(self.fld,attr)
120    def __hash__(self):
121        return hash(self.fld)
122    def __eq__(self, other):
123        return self.fld == other
124
125
126class ActionField(object):
127    __slots__ = ["_fld", "_action_method", "_privdata"]
128    def __init__(self, fld, action_method, **kargs):
129        self._fld = fld
130        self._action_method = action_method
131        self._privdata = kargs
132    def any2i(self, pkt, val):
133        getattr(pkt, self._action_method)(val, self._fld, **self._privdata)
134        return getattr(self._fld, "any2i")(pkt, val)
135    def __getattr__(self, attr):
136        return getattr(self._fld,attr)
137
138
139class ConditionalField(object):
140    __slots__ = ["fld", "cond"]
141    def __init__(self, fld, cond):
142        self.fld = fld
143        self.cond = cond
144    def _evalcond(self,pkt):
145        return self.cond(pkt)
146
147    def getfield(self, pkt, s):
148        if self._evalcond(pkt):
149            return self.fld.getfield(pkt,s)
150        else:
151            return s,None
152
153    def addfield(self, pkt, s, val):
154        if self._evalcond(pkt):
155            return self.fld.addfield(pkt,s,val)
156        else:
157            return s
158    def __getattr__(self, attr):
159        return getattr(self.fld,attr)
160
161
162class PadField(object):
163    """Add bytes after the proxified field so that it ends at the specified
164       alignment from its beginning"""
165    __slots__ = ["_fld", "_align", "_padwith"]
166    def __init__(self, fld, align, padwith=None):
167        self._fld = fld
168        self._align = align
169        self._padwith = padwith or b""
170
171    def padlen(self, flen):
172        return -flen%self._align
173
174    def getfield(self, pkt, s):
175        remain,val = self._fld.getfield(pkt,s)
176        padlen = self.padlen(len(s)-len(remain))
177        return remain[padlen:], val
178
179    def addfield(self, pkt, s, val):
180        sval = self._fld.addfield(pkt, b"", val)
181        return s+sval+struct.pack("%is" % (self.padlen(len(sval))), self._padwith)
182
183    def __getattr__(self, attr):
184        return getattr(self._fld,attr)
185
186
187class DestField(Field):
188    __slots__ = ["defaultdst"]
189    # Each subclass must have its own bindings attribute
190    # bindings = {}
191    def __init__(self, name, default):
192        self.defaultdst = default
193    def dst_from_pkt(self, pkt):
194        for addr, condition in self.bindings.get(pkt.payload.__class__, []):
195            try:
196                if all(pkt.payload.getfieldval(field) == value
197                       for field, value in six.iteritems(condition)):
198                    return addr
199            except AttributeError:
200                pass
201        return self.defaultdst
202    @classmethod
203    def bind_addr(cls, layer, addr, **condition):
204        cls.bindings.setdefault(layer, []).append((addr, condition))
205
206
207class MACField(Field):
208    def __init__(self, name, default):
209        Field.__init__(self, name, default, "6s")
210    def i2m(self, pkt, x):
211        if x is None:
212            return b"\0\0\0\0\0\0"
213        return mac2str(x)
214    def m2i(self, pkt, x):
215        return str2mac(x)
216    def any2i(self, pkt, x):
217        if isinstance(x, bytes) and len(x) == 6:
218            x = self.m2i(pkt, x)
219        return x
220    def i2repr(self, pkt, x):
221        x = self.i2h(pkt, x)
222        if self in conf.resolve:
223            x = conf.manufdb._resolve_MAC(x)
224        return x
225    def randval(self):
226        return RandMAC()
227
228
229class IPField(Field):
230    slots = []
231    def __init__(self, name, default):
232        Field.__init__(self, name, default, "4s")
233    def h2i(self, pkt, x):
234        if isinstance(x, bytes):
235            x = plain_str(x)
236        if isinstance(x, str):
237            try:
238                inet_aton(x)
239            except socket.error:
240                x = Net(x)
241        elif isinstance(x, list):
242            x = [self.h2i(pkt, n) for n in x]
243        return x
244    def resolve(self, x):
245        if self in conf.resolve:
246            try:
247                ret = socket.gethostbyaddr(x)[0]
248            except:
249                pass
250            else:
251                if ret:
252                    return ret
253        return x
254    def i2m(self, pkt, x):
255        return inet_aton(x)
256    def m2i(self, pkt, x):
257        return inet_ntoa(x)
258    def any2i(self, pkt, x):
259        return self.h2i(pkt,x)
260    def i2repr(self, pkt, x):
261        return self.resolve(self.i2h(pkt, x))
262    def randval(self):
263        return RandIP()
264
265class SourceIPField(IPField):
266    __slots__ = ["dstname"]
267    def __init__(self, name, dstname):
268        IPField.__init__(self, name, None)
269        self.dstname = dstname
270    def __findaddr(self, pkt):
271        if conf.route is None:
272            # unused import, only to initialize conf.route
273            import scapy.route
274        dst = ("0.0.0.0" if self.dstname is None
275               else getattr(pkt, self.dstname))
276        if isinstance(dst, (Gen, list)):
277            r = {conf.route.route(daddr) for daddr in dst}
278            if len(r) > 1:
279                warning("More than one possible route for %r" % (dst,))
280            return min(r)[1]
281        return conf.route.route(dst)[1]
282    def i2m(self, pkt, x):
283        if x is None:
284            x = self.__findaddr(pkt)
285        return IPField.i2m(self, pkt, x)
286    def i2h(self, pkt, x):
287        if x is None:
288            x = self.__findaddr(pkt)
289        return IPField.i2h(self, pkt, x)
290
291
292
293
294class ByteField(Field):
295    def __init__(self, name, default):
296        Field.__init__(self, name, default, "B")
297
298class XByteField(ByteField):
299    def i2repr(self, pkt, x):
300        return lhex(self.i2h(pkt, x))
301
302class OByteField(ByteField):
303    def i2repr(self, pkt, x):
304        return "%03o"%self.i2h(pkt, x)
305
306class X3BytesField(XByteField):
307    def __init__(self, name, default):
308        Field.__init__(self, name, default, "!I")
309    def addfield(self, pkt, s, val):
310        return s+struct.pack(self.fmt, self.i2m(pkt,val))[1:4]
311    def getfield(self, pkt, s):
312        return  s[3:], self.m2i(pkt, struct.unpack(self.fmt, b"\x00"+s[:3])[0])
313
314class ThreeBytesField(X3BytesField, ByteField):
315    def i2repr(self, pkt, x):
316        return ByteField.i2repr(self, pkt, x)
317
318class SignedByteField(Field):
319    def __init__(self, name, default):
320        Field.__init__(self, name, default, "b")
321
322class ShortField(Field):
323    def __init__(self, name, default):
324        Field.__init__(self, name, default, "H")
325
326class SignedShortField(Field):
327    def __init__(self, name, default):
328        Field.__init__(self, name, default, "h")
329
330class LEShortField(Field):
331    def __init__(self, name, default):
332        Field.__init__(self, name, default, "<H")
333
334class XShortField(ShortField):
335    def i2repr(self, pkt, x):
336        return lhex(self.i2h(pkt, x))
337
338
339class IntField(Field):
340    def __init__(self, name, default):
341        Field.__init__(self, name, default, "I")
342
343class SignedIntField(Field):
344    def __init__(self, name, default):
345        Field.__init__(self, name, default, "i")
346    def randval(self):
347        return RandSInt()
348
349class LEIntField(Field):
350    def __init__(self, name, default):
351        Field.__init__(self, name, default, "<I")
352
353class LESignedIntField(Field):
354    def __init__(self, name, default):
355        Field.__init__(self, name, default, "<i")
356    def randval(self):
357        return RandSInt()
358
359class XIntField(IntField):
360    def i2repr(self, pkt, x):
361        return lhex(self.i2h(pkt, x))
362
363
364class LongField(Field):
365    def __init__(self, name, default):
366        Field.__init__(self, name, default, "Q")
367
368class LELongField(LongField):
369    def __init__(self, name, default):
370        Field.__init__(self, name, default, "<Q")
371
372class XLongField(LongField):
373    def i2repr(self, pkt, x):
374        return lhex(self.i2h(pkt, x))
375
376class IEEEFloatField(Field):
377    def __init__(self, name, default):
378        Field.__init__(self, name, default, "f")
379
380class IEEEDoubleField(Field):
381    def __init__(self, name, default):
382        Field.__init__(self, name, default, "d")
383
384
385class StrField(Field):
386    __slots__ = ["remain"]
387    def __init__(self, name, default, fmt="H", remain=0):
388        Field.__init__(self,name,default,fmt)
389        self.remain = remain
390    def i2len(self, pkt, i):
391        return len(i)
392    def any2i(self, pkt, x):
393        if isinstance(x, str if six.PY3 else unicode):
394            x = raw(x)
395        return super(StrField, self).any2i(pkt, x)
396    def i2repr(self, pkt, x):
397        val = super(StrField, self).i2repr(pkt, x)
398        if val[:2] in ['b"', "b'"]:
399            return val[1:]
400        return val
401    def i2m(self, pkt, x):
402        if x is None:
403            return b""
404        if not isinstance(x, bytes):
405            return raw(x)
406        return x
407    def addfield(self, pkt, s, val):
408        return s + self.i2m(pkt, val)
409    def getfield(self, pkt, s):
410        if self.remain == 0:
411            return b"", self.m2i(pkt, s)
412        else:
413            return s[-self.remain:],self.m2i(pkt, s[:-self.remain])
414    def randval(self):
415        return RandBin(RandNum(0,1200))
416
417class PacketField(StrField):
418    __slots__ = ["cls"]
419    holds_packets = 1
420    def __init__(self, name, default, cls, remain=0):
421        StrField.__init__(self, name, default, remain=remain)
422        self.cls = cls
423    def i2m(self, pkt, i):
424        if i is None:
425            return b""
426        return raw(i)
427    def m2i(self, pkt, m):
428        return self.cls(m)
429    def getfield(self, pkt, s):
430        i = self.m2i(pkt, s)
431        remain = b""
432        if conf.padding_layer in i:
433            r = i[conf.padding_layer]
434            del(r.underlayer.payload)
435            remain = r.load
436        return remain,i
437
438class PacketLenField(PacketField):
439    __slots__ = ["length_from"]
440    def __init__(self, name, default, cls, length_from=None):
441        PacketField.__init__(self, name, default, cls)
442        self.length_from = length_from
443    def getfield(self, pkt, s):
444        l = self.length_from(pkt)
445        try:
446            i = self.m2i(pkt, s[:l])
447        except Exception:
448            if conf.debug_dissector:
449                raise
450            i = conf.raw_layer(load=s[:l])
451        return s[l:],i
452
453
454class PacketListField(PacketField):
455    """ PacketListField represents a series of Packet instances that might occur right in the middle of another Packet
456    field list.
457    This field type may also be used to indicate that a series of Packet instances have a sibling semantic instead of
458    a parent/child relationship (i.e. a stack of layers).
459    """
460    __slots__ = ["count_from", "length_from", "next_cls_cb"]
461    islist = 1
462    def __init__(self, name, default, cls=None, count_from=None, length_from=None, next_cls_cb=None):
463        """ The number of Packet instances that are dissected by this field can be parametrized using one of three
464        different mechanisms/parameters:
465            * count_from: a callback that returns the number of Packet instances to dissect. The callback prototype is:
466            count_from(pkt:Packet) -> int
467            * length_from: a callback that returns the number of bytes that must be dissected by this field. The
468            callback prototype is:
469            length_from(pkt:Packet) -> int
470            * next_cls_cb: a callback that enables a Scapy developer to dynamically discover if another Packet instance
471            should be dissected or not. See below for this callback prototype.
472
473        The bytes that are not consumed during the dissection of this field are passed to the next field of the current
474        packet.
475
476        For the serialization of such a field, the list of Packets that are contained in a PacketListField can be
477        heterogeneous and is unrestricted.
478
479        The type of the Packet instances that are dissected with this field is specified or discovered using one of the
480        following mechanism:
481            * the cls parameter may contain a callable that returns an instance of the dissected Packet. This
482                may either be a reference of a Packet subclass (e.g. DNSRROPT in layers/dns.py) to generate an
483                homogeneous PacketListField or a function deciding the type of the Packet instance
484                (e.g. _CDPGuessAddrRecord in contrib/cdp.py)
485            * the cls parameter may contain a class object with a defined "dispatch_hook" classmethod. That
486                method must return a Packet instance. The dispatch_hook callmethod must implement the following prototype:
487                dispatch_hook(cls, _pkt:Optional[Packet], *args, **kargs) -> Packet_metaclass
488                The _pkt parameter may contain a reference to the packet instance containing the PacketListField that is
489                being dissected.
490            * the next_cls_cb parameter may contain a callable whose prototype is:
491                cbk(pkt:Packet, lst:List[Packet], cur:Optional[Packet], remain:str) -> Optional[Packet_metaclass]
492                The pkt argument contains a reference to the Packet instance containing the PacketListField that is
493                being dissected. The lst argument is the list of all Packet instances that were previously parsed during
494                the current PacketListField dissection, save for the very last Packet instance. The cur argument
495                contains a reference to that very last parsed Packet instance. The remain argument contains the bytes
496                that may still be consumed by the current PacketListField dissection operation. This callback returns
497                either the type of the next Packet to dissect or None to indicate that no more Packet are to be
498                dissected.
499                These four arguments allows a variety of dynamic discovery of the number of Packet to dissect and of the
500                type of each one of these Packets, including: type determination based on current Packet instances or
501                its underlayers, continuation based on the previously parsed Packet instances within that
502                PacketListField, continuation based on a look-ahead on the bytes to be dissected...
503
504        The cls and next_cls_cb parameters are semantically exclusive, although one could specify both. If both are
505        specified, cls is silently ignored. The same is true for count_from and next_cls_cb.
506        length_from and next_cls_cb are compatible and the dissection will end, whichever of the two stop conditions
507        comes first.
508
509        @param name: the name of the field
510        @param default: the default value of this field; generally an empty Python list
511        @param cls: either a callable returning a Packet instance or a class object defining a dispatch_hook class
512            method
513        @param count_from: a callback returning the number of Packet instances to dissect
514        @param length_from: a callback returning the number of bytes to dissect
515        @param next_cls_cb: a callback returning either None or the type of the next Packet to dissect.
516        """
517        if default is None:
518            default = []  # Create a new list for each instance
519        PacketField.__init__(self, name, default, cls)
520        self.count_from = count_from
521        self.length_from = length_from
522        self.next_cls_cb = next_cls_cb
523
524    def any2i(self, pkt, x):
525        if not isinstance(x, list):
526            return [x]
527        else:
528            return x
529    def i2count(self, pkt, val):
530        if isinstance(val, list):
531            return len(val)
532        return 1
533    def i2len(self, pkt, val):
534        return sum( len(p) for p in val )
535    def do_copy(self, x):
536        if x is None:
537            return None
538        else:
539            return [p if isinstance(p, six.string_types) else p.copy() for p in x]
540    def getfield(self, pkt, s):
541        c = l = cls = None
542        if self.length_from is not None:
543            l = self.length_from(pkt)
544        elif self.count_from is not None:
545            c = self.count_from(pkt)
546        if self.next_cls_cb is not None:
547            cls = self.next_cls_cb(pkt, [], None, s)
548            c = 1
549
550        lst = []
551        ret = b""
552        remain = s
553        if l is not None:
554            remain,ret = s[:l],s[l:]
555        while remain:
556            if c is not None:
557                if c <= 0:
558                    break
559                c -= 1
560            try:
561                if cls is not None:
562                    p = cls(remain)
563                else:
564                    p = self.m2i(pkt, remain)
565            except Exception:
566                if conf.debug_dissector:
567                    raise
568                p = conf.raw_layer(load=remain)
569                remain = b""
570            else:
571                if conf.padding_layer in p:
572                    pad = p[conf.padding_layer]
573                    remain = pad.load
574                    del(pad.underlayer.payload)
575                    if self.next_cls_cb is not None:
576                        cls = self.next_cls_cb(pkt, lst, p, remain)
577                        if cls is not None:
578                            c += 1
579                else:
580                    remain = b""
581            lst.append(p)
582        return remain+ret,lst
583    def addfield(self, pkt, s, val):
584        return s + b"".join(raw(v) for v in val)
585
586
587class StrFixedLenField(StrField):
588    __slots__ = ["length_from"]
589    def __init__(self, name, default, length=None, length_from=None):
590        StrField.__init__(self, name, default)
591        self.length_from  = length_from
592        if length is not None:
593            self.length_from = lambda pkt,length=length: length
594    def i2repr(self, pkt, v):
595        if isinstance(v, bytes):
596            v = v.rstrip(b"\0")
597        return super(StrFixedLenField, self).i2repr(pkt, v)
598    def getfield(self, pkt, s):
599        l = self.length_from(pkt)
600        return s[l:], self.m2i(pkt,s[:l])
601    def addfield(self, pkt, s, val):
602        l = self.length_from(pkt)
603        return s+struct.pack("%is"%l,self.i2m(pkt, val))
604    def randval(self):
605        try:
606            l = self.length_from(None)
607        except:
608            l = RandNum(0,200)
609        return RandBin(l)
610
611class StrFixedLenEnumField(StrFixedLenField):
612    __slots__ = ["enum"]
613    def __init__(self, name, default, length=None, enum=None, length_from=None):
614        StrFixedLenField.__init__(self, name, default, length=length, length_from=length_from)
615        self.enum = enum
616    def i2repr(self, pkt, v):
617        r = v.rstrip("\0")
618        rr = repr(r)
619        if v in self.enum:
620            rr = "%s (%s)" % (rr, self.enum[v])
621        elif r in self.enum:
622            rr = "%s (%s)" % (rr, self.enum[r])
623        return rr
624
625class NetBIOSNameField(StrFixedLenField):
626    def __init__(self, name, default, length=31):
627        StrFixedLenField.__init__(self, name, default, length)
628    def i2m(self, pkt, x):
629        l = self.length_from(pkt)//2
630        if x is None:
631            x = b""
632        x += b" "*(l)
633        x = x[:l]
634        x = b"".join(chb(0x41 + orb(b)>>4) + chb(0x41 + orb(b)&0xf) for b in x)
635        x = b" "+x
636        return x
637    def m2i(self, pkt, x):
638        x = x.strip(b"\x00").strip(b" ")
639        return b"".join(map(lambda x,y: chb((((orb(x)-1)&0xf)<<4)+((orb(y)-1)&0xf)), x[::2],x[1::2]))
640
641class StrLenField(StrField):
642    __slots__ = ["length_from"]
643    def __init__(self, name, default, fld=None, length_from=None):
644        StrField.__init__(self, name, default)
645        self.length_from = length_from
646    def getfield(self, pkt, s):
647        l = self.length_from(pkt)
648        return s[l:], self.m2i(pkt,s[:l])
649
650class XStrField(StrField):
651    """
652    StrField which value is printed as hexadecimal.
653    """
654
655    def i2repr(self, pkt, x):
656        if x is None:
657            return repr(x)
658        return bytes_hex(x).decode()
659
660class XStrLenField(StrLenField):
661    """
662    StrLenField which value is printed as hexadecimal.
663    """
664
665    def i2repr(self, pkt, x):
666        if not x:
667            return repr(x)
668        return bytes_hex(x[:self.length_from(pkt)]).decode()
669
670class XStrFixedLenField(StrFixedLenField):
671    """
672    StrFixedLenField which value is printed as hexadecimal.
673    """
674
675    def i2repr(self, pkt, x):
676        if not x:
677            return repr(x)
678        return bytes_hex(x[:self.length_from(pkt)]).decode()
679
680class StrLenFieldUtf16(StrLenField):
681    def h2i(self, pkt, x):
682        return plain_str(x).encode('utf-16')[2:]
683    def i2h(self, pkt, x):
684        return x.decode('utf-16')
685
686class BoundStrLenField(StrLenField):
687    __slots__ = ["minlen", "maxlen"]
688    def __init__(self,name, default, minlen= 0, maxlen= 255, fld=None, length_from=None):
689        StrLenField.__init__(self, name, default, fld, length_from)
690        self.minlen = minlen
691        self.maxlen = maxlen
692
693    def randval(self):
694        return RandBin(RandNum(self.minlen, self.maxlen))
695
696class FieldListField(Field):
697    __slots__ = ["field", "count_from", "length_from"]
698    islist = 1
699    def __init__(self, name, default, field, length_from=None, count_from=None):
700        if default is None:
701            default = []  # Create a new list for each instance
702        self.field = field
703        Field.__init__(self, name, default)
704        self.count_from = count_from
705        self.length_from = length_from
706
707    def i2count(self, pkt, val):
708        if isinstance(val, list):
709            return len(val)
710        return 1
711    def i2len(self, pkt, val):
712        return int(sum(self.field.i2len(pkt,v) for v in val))
713
714    def i2m(self, pkt, val):
715        if val is None:
716            val = []
717        return val
718    def any2i(self, pkt, x):
719        if not isinstance(x, list):
720            return [self.field.any2i(pkt, x)]
721        else:
722            return [self.field.any2i(pkt, e) for e in x]
723    def i2repr(self, pkt, x):
724        res = []
725        for v in x:
726            r = self.field.i2repr(pkt, v)
727            res.append(r)
728        return "[%s]" % ", ".join(res)
729    def addfield(self, pkt, s, val):
730        val = self.i2m(pkt, val)
731        for v in val:
732            s = self.field.addfield(pkt, s, v)
733        return s
734    def getfield(self, pkt, s):
735        c = l = None
736        if self.length_from is not None:
737            l = self.length_from(pkt)
738        elif self.count_from is not None:
739            c = self.count_from(pkt)
740
741        val = []
742        ret = b""
743        if l is not None:
744            s,ret = s[:l],s[l:]
745
746        while s:
747            if c is not None:
748                if c <= 0:
749                    break
750                c -= 1
751            s,v = self.field.getfield(pkt, s)
752            val.append(v)
753        return s+ret, val
754
755class FieldLenField(Field):
756    __slots__ = ["length_of", "count_of", "adjust"]
757    def __init__(self, name, default,  length_of=None, fmt = "H", count_of=None, adjust=lambda pkt,x:x, fld=None):
758        Field.__init__(self, name, default, fmt)
759        self.length_of = length_of
760        self.count_of = count_of
761        self.adjust = adjust
762        if fld is not None:
763            #FIELD_LENGTH_MANAGEMENT_DEPRECATION(self.__class__.__name__)
764            self.length_of = fld
765    def i2m(self, pkt, x):
766        if x is None:
767            if self.length_of is not None:
768                fld,fval = pkt.getfield_and_val(self.length_of)
769                f = fld.i2len(pkt, fval)
770            else:
771                fld,fval = pkt.getfield_and_val(self.count_of)
772                f = fld.i2count(pkt, fval)
773            x = self.adjust(pkt,f)
774        return x
775
776class StrNullField(StrField):
777    def addfield(self, pkt, s, val):
778        return s+self.i2m(pkt, val)+b"\x00"
779    def getfield(self, pkt, s):
780        l = s.find(b"\x00")
781        if l < 0:
782            #XXX \x00 not found
783            return b"",s
784        return s[l+1:],self.m2i(pkt, s[:l])
785    def randval(self):
786        return RandTermString(RandNum(0,1200),b"\x00")
787
788class StrStopField(StrField):
789    __slots__ = ["stop", "additionnal"]
790    def __init__(self, name, default, stop, additionnal=0):
791        Field.__init__(self, name, default)
792        self.stop = stop
793        self.additionnal = additionnal
794    def getfield(self, pkt, s):
795        l = s.find(self.stop)
796        if l < 0:
797            return b"",s
798#            raise Scapy_Exception,"StrStopField: stop value [%s] not found" %stop
799        l += len(self.stop)+self.additionnal
800        return s[l:],s[:l]
801    def randval(self):
802        return RandTermString(RandNum(0,1200),self.stop)
803
804class LenField(Field):
805    __slots__ = ["adjust"]
806    def __init__(self, name, default, fmt="H", adjust=lambda x: x):
807        Field.__init__(self, name, default, fmt)
808        self.adjust = adjust
809    def i2m(self, pkt, x):
810        if x is None:
811            x = self.adjust(len(pkt.payload))
812        return x
813
814class BCDFloatField(Field):
815    def i2m(self, pkt, x):
816        return int(256*x)
817    def m2i(self, pkt, x):
818        return x/256.0
819
820class BitField(Field):
821    __slots__ = ["rev", "size"]
822    def __init__(self, name, default, size):
823        Field.__init__(self, name, default)
824        self.rev = size < 0
825        self.size = abs(size)
826    def reverse(self, val):
827        if self.size == 16:
828            # Replaces socket.ntohs (but work on both little/big endian)
829            val = struct.unpack('>H',struct.pack('<H', int(val)))[0]
830        elif self.size == 32:
831            # Same here but for socket.ntohl
832            val = struct.unpack('>I',struct.pack('<I', int(val)))[0]
833        return val
834
835    def addfield(self, pkt, s, val):
836        val = self.i2m(pkt, val)
837        if isinstance(s, tuple):
838            s,bitsdone,v = s
839        else:
840            bitsdone = 0
841            v = 0
842        if self.rev:
843            val = self.reverse(val)
844        v <<= self.size
845        v |= val & ((1<<self.size) - 1)
846        bitsdone += self.size
847        while bitsdone >= 8:
848            bitsdone -= 8
849            s = s+struct.pack("!B", v >> bitsdone)
850            v &= (1<<bitsdone)-1
851        if bitsdone:
852            return s,bitsdone,v
853        else:
854            return s
855    def getfield(self, pkt, s):
856        if isinstance(s, tuple):
857            s,bn = s
858        else:
859            bn = 0
860        # we don't want to process all the string
861        nb_bytes = (self.size+bn-1)//8 + 1
862        w = s[:nb_bytes]
863
864        # split the substring byte by byte
865        _bytes = struct.unpack('!%dB' % nb_bytes , w)
866
867        b = 0
868        for c in range(nb_bytes):
869            b |= int(_bytes[c]) << (nb_bytes-c-1)*8
870
871        # get rid of high order bits
872        b &= (1 << (nb_bytes*8-bn)) - 1
873
874        # remove low order bits
875        b = b >> (nb_bytes*8 - self.size - bn)
876
877        if self.rev:
878            b = self.reverse(b)
879
880        bn += self.size
881        s = s[bn//8:]
882        bn = bn%8
883        b = self.m2i(pkt, b)
884        if bn:
885            return (s,bn),b
886        else:
887            return s,b
888    def randval(self):
889        return RandNum(0,2**self.size-1)
890    def i2len(self, pkt, x):
891        return float(self.size)/8
892
893
894class BitFieldLenField(BitField):
895    __slots__ = ["length_of", "count_of", "adjust"]
896    def __init__(self, name, default, size, length_of=None, count_of=None, adjust=lambda pkt,x:x):
897        BitField.__init__(self, name, default, size)
898        self.length_of = length_of
899        self.count_of = count_of
900        self.adjust = adjust
901    def i2m(self, pkt, x):
902        return (FieldLenField.i2m.__func__ if six.PY2 else FieldLenField.i2m)(self, pkt, x)
903
904
905class XBitField(BitField):
906    def i2repr(self, pkt, x):
907        return lhex(self.i2h(pkt,x))
908
909
910class _EnumField(Field):
911    def __init__(self, name, default, enum, fmt = "H"):
912        """ Initializes enum fields.
913
914        @param name:    name of this field
915        @param default: default value of this field
916        @param enum:    either a dict or a tuple of two callables. Dict keys are
917                        the internal values, while the dict values are the
918                        user-friendly representations. If the tuple is provided,
919                        the first callable receives the internal value as
920                        parameter and returns the user-friendly representation
921                        and the second callable does the converse. The first
922                        callable may return None to default to a literal string
923                        (repr()) representation.
924        @param fmt:     struct.pack format used to parse and serialize the
925                        internal value from and to machine representation.
926        """
927        if isinstance(enum, tuple):
928            self.i2s_cb = enum[0]
929            self.s2i_cb = enum[1]
930            self.i2s = None
931            self.s2i = None
932        else:
933            i2s = self.i2s = {}
934            s2i = self.s2i = {}
935            self.i2s_cb = None
936            self.s2i_cb = None
937            if isinstance(enum, list):
938                keys = range(len(enum))
939            elif isinstance(enum, DADict):
940                keys = enum.iterkeys()
941            else:
942                keys = list(enum)
943            if any(isinstance(x, str) for x in keys):
944                i2s, s2i = s2i, i2s
945            for k in keys:
946                i2s[k] = enum[k]
947                s2i[enum[k]] = k
948        Field.__init__(self, name, default, fmt)
949
950    def any2i_one(self, pkt, x):
951        if isinstance(x, str):
952            try:
953                x = self.s2i[x]
954            except TypeError:
955                x = self.s2i_cb(x)
956        return x
957
958    def i2repr_one(self, pkt, x):
959        if self not in conf.noenum and not isinstance(x,VolatileValue):
960            try:
961                return self.i2s[x]
962            except KeyError:
963                pass
964            except TypeError:
965                ret = self.i2s_cb(x)
966                if ret is not None:
967                    return ret
968        return repr(x)
969
970    def any2i(self, pkt, x):
971        if isinstance(x, list):
972            return [self.any2i_one(pkt, z) for z in x]
973        else:
974            return self.any2i_one(pkt,x)
975
976    def i2repr(self, pkt, x):
977        if isinstance(x, list):
978            return [self.i2repr_one(pkt, z) for z in x]
979        else:
980            return self.i2repr_one(pkt,x)
981
982class EnumField(_EnumField):
983    __slots__ = ["i2s", "s2i", "s2i_cb", "i2s_cb"]
984
985class CharEnumField(EnumField):
986    def __init__(self, name, default, enum, fmt = "1s"):
987        EnumField.__init__(self, name, default, enum, fmt)
988        if self.i2s is not None:
989            k = list(self.i2s)
990            if k and len(k[0]) != 1:
991                self.i2s,self.s2i = self.s2i,self.i2s
992    def any2i_one(self, pkt, x):
993        if len(x) != 1:
994            if self.s2i is None:
995                x = self.s2i_cb(x)
996            else:
997                x = self.s2i[x]
998        return x
999
1000class BitEnumField(BitField, _EnumField):
1001    __slots__ = EnumField.__slots__
1002    def __init__(self, name, default, size, enum):
1003        _EnumField.__init__(self, name, default, enum)
1004        self.rev = size < 0
1005        self.size = abs(size)
1006    def any2i(self, pkt, x):
1007        return _EnumField.any2i(self, pkt, x)
1008    def i2repr(self, pkt, x):
1009        return _EnumField.i2repr(self, pkt, x)
1010
1011class ShortEnumField(EnumField):
1012    __slots__ = EnumField.__slots__
1013    def __init__(self, name, default, enum):
1014        EnumField.__init__(self, name, default, enum, "H")
1015
1016class LEShortEnumField(EnumField):
1017    def __init__(self, name, default, enum):
1018        EnumField.__init__(self, name, default, enum, "<H")
1019
1020class ByteEnumField(EnumField):
1021    def __init__(self, name, default, enum):
1022        EnumField.__init__(self, name, default, enum, "B")
1023
1024class IntEnumField(EnumField):
1025    def __init__(self, name, default, enum):
1026        EnumField.__init__(self, name, default, enum, "I")
1027
1028class SignedIntEnumField(EnumField):
1029    def __init__(self, name, default, enum):
1030        EnumField.__init__(self, name, default, enum, "i")
1031    def randval(self):
1032        return RandSInt()
1033
1034class LEIntEnumField(EnumField):
1035    def __init__(self, name, default, enum):
1036        EnumField.__init__(self, name, default, enum, "<I")
1037
1038class XShortEnumField(ShortEnumField):
1039    def i2repr_one(self, pkt, x):
1040        if self not in conf.noenum and not isinstance(x,VolatileValue):
1041            try:
1042                return self.i2s[x]
1043            except KeyError:
1044                pass
1045            except TypeError:
1046                ret = self.i2s_cb(x)
1047                if ret is not None:
1048                    return ret
1049        return lhex(x)
1050
1051
1052class _MultiEnumField(_EnumField):
1053    def __init__(self, name, default, enum, depends_on, fmt = "H"):
1054
1055        self.depends_on = depends_on
1056        self.i2s_multi = enum
1057        self.s2i_multi = {}
1058        self.s2i_all = {}
1059        for m in enum:
1060            self.s2i_multi[m] = s2i = {}
1061            for k,v in six.iteritems(enum[m]):
1062                s2i[v] = k
1063                self.s2i_all[v] = k
1064        Field.__init__(self, name, default, fmt)
1065    def any2i_one(self, pkt, x):
1066        if isinstance(x, str):
1067            v = self.depends_on(pkt)
1068            if v in self.s2i_multi:
1069                s2i = self.s2i_multi[v]
1070                if x in s2i:
1071                    return s2i[x]
1072            return self.s2i_all[x]
1073        return x
1074    def i2repr_one(self, pkt, x):
1075        v = self.depends_on(pkt)
1076        if v in self.i2s_multi:
1077            return self.i2s_multi[v].get(x,x)
1078        return x
1079
1080class MultiEnumField(_MultiEnumField, EnumField):
1081    __slots__ = ["depends_on", "i2s_multi", "s2i_multi", "s2i_all"]
1082
1083class BitMultiEnumField(BitField, _MultiEnumField):
1084    __slots__ = EnumField.__slots__ + MultiEnumField.__slots__
1085    def __init__(self, name, default, size, enum, depends_on):
1086        _MultiEnumField.__init__(self, name, default, enum, depends_on)
1087        self.rev = size < 0
1088        self.size = abs(size)
1089    def any2i(self, pkt, x):
1090        return _MultiEnumField.any2i(self, pkt, x)
1091    def i2repr(self, pkt, x):
1092        return _MultiEnumField.i2repr(self, pkt, x)
1093
1094
1095class ByteEnumKeysField(ByteEnumField):
1096    """ByteEnumField that picks valid values when fuzzed. """
1097    def randval(self):
1098        return RandEnumKeys(self.i2s)
1099
1100
1101class ShortEnumKeysField(ShortEnumField):
1102    """ShortEnumField that picks valid values when fuzzed. """
1103    def randval(self):
1104        return RandEnumKeys(self.i2s)
1105
1106
1107class IntEnumKeysField(IntEnumField):
1108    """IntEnumField that picks valid values when fuzzed. """
1109    def randval(self):
1110        return RandEnumKeys(self.i2s)
1111
1112
1113# Little endian long field
1114class LELongField(Field):
1115    def __init__(self, name, default):
1116        Field.__init__(self, name, default, "<Q")
1117
1118# Little endian fixed length field
1119class LEFieldLenField(FieldLenField):
1120    def __init__(self, name, default,  length_of=None, fmt = "<H", count_of=None, adjust=lambda pkt,x:x, fld=None):
1121        FieldLenField.__init__(self, name, default, length_of=length_of, fmt=fmt, count_of=count_of, fld=fld, adjust=adjust)
1122
1123
1124class FlagValue(object):
1125    __slots__ = ["value", "names", "multi"]
1126    def _fixvalue(self, value):
1127        if isinstance(value, six.string_types):
1128            value = value.split('+') if self.multi else list(value)
1129        if isinstance(value, list):
1130            y = 0
1131            for i in value:
1132                y |= 1 << self.names.index(i)
1133            value = y
1134        return None if value is None else int(value)
1135    def __init__(self, value, names):
1136        self.multi = isinstance(names, list)
1137        self.names = names
1138        self.value = self._fixvalue(value)
1139    def __hash__(self):
1140        return hash(self.value)
1141    def __int__(self):
1142        return self.value
1143    def __eq__(self, other):
1144        return self.value == self._fixvalue(other)
1145    def __lt__(self, other):
1146        return self.value < self._fixvalue(other)
1147    def __le__(self, other):
1148        return self.value <= self._fixvalue(other)
1149    def __gt__(self, other):
1150        return self.value > self._fixvalue(other)
1151    def __ge__(self, other):
1152        return self.value >= self._fixvalue(other)
1153    def __ne__(self, other):
1154        return self.value != self._fixvalue(other)
1155    def __and__(self, other):
1156        return self.__class__(self.value & self._fixvalue(other), self.names)
1157    __rand__ = __and__
1158    def __or__(self, other):
1159        return self.__class__(self.value | self._fixvalue(other), self.names)
1160    __ror__ = __or__
1161    def __lshift__(self, other):
1162        return self.value << self._fixvalue(other)
1163    def __rshift__(self, other):
1164        return self.value >> self._fixvalue(other)
1165    def __nonzero__(self):
1166        return bool(self.value)
1167    __bool__ = __nonzero__
1168    def flagrepr(self):
1169        warning("obj.flagrepr() is obsolete. Use str(obj) instead.")
1170        return str(self)
1171    def __str__(self):
1172        i = 0
1173        r = []
1174        x = int(self)
1175        while x:
1176            if x & 1:
1177                r.append(self.names[i])
1178            i += 1
1179            x >>= 1
1180        return ("+" if self.multi else "").join(r)
1181    def __repr__(self):
1182        return "<Flag %d (%s)>" % (self, self)
1183    def __deepcopy__(self, memo):
1184        return self.__class__(int(self), self.names)
1185    def __getattr__(self, attr):
1186        if attr in self.__slots__:
1187            return super(FlagValue, self).__getattr__(attr)
1188        try:
1189            if self.multi:
1190                return bool((2 ** self.names.index(attr)) & int(self))
1191            return all(bool((2 ** self.names.index(flag)) & int(self))
1192                       for flag in attr)
1193        except ValueError:
1194            return super(FlagValue, self).__getattr__(attr)
1195    def __setattr__(self, attr, value):
1196        if attr == "value" and not isinstance(value, six.integer_types):
1197            raise ValueError(value)
1198        if attr in self.__slots__:
1199            return super(FlagValue, self).__setattr__(attr, value)
1200        if attr in self.names:
1201            if value:
1202                self.value |= (2 ** self.names.index(attr))
1203            else:
1204                self.value &= ~(2 ** self.names.index(attr))
1205        else:
1206            return super(FlagValue, self).__setattr__(attr, value)
1207    def copy(self):
1208        return self.__class__(self.value, self.names)
1209
1210
1211class FlagsField(BitField):
1212    """ Handle Flag type field
1213
1214   Make sure all your flags have a label
1215
1216   Example:
1217       >>> from scapy.packet import Packet
1218       >>> class FlagsTest(Packet):
1219               fields_desc = [FlagsField("flags", 0, 8, ["f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7"])]
1220       >>> FlagsTest(flags=9).show2()
1221       ###[ FlagsTest ]###
1222         flags     = f0+f3
1223       >>> FlagsTest(flags=0).show2().strip()
1224       ###[ FlagsTest ]###
1225         flags     =
1226
1227   :param name: field's name
1228   :param default: default value for the field
1229   :param size: number of bits in the field
1230   :param names: (list or dict) label for each flag, Least Significant Bit tag's name is written first
1231   """
1232    ismutable = True
1233    __slots__ = ["multi", "names"]
1234
1235    def __init__(self, name, default, size, names):
1236        self.multi = isinstance(names, list)
1237        self.names = names
1238        BitField.__init__(self, name, default, size)
1239
1240    def _fixup_val(self, x):
1241        """Returns a FlagValue instance when needed. Internal method, to be
1242used in *2i() and i2*() methods.
1243
1244        """
1245        if isinstance(x, (list, tuple)):
1246            return type(x)(
1247                v if v is None or isinstance(v, FlagValue)
1248                else FlagValue(v, self.names)
1249                for v in x
1250            )
1251        return x if x is None or isinstance(x, FlagValue) else FlagValue(x, self.names)
1252
1253    def any2i(self, pkt, x):
1254        return self._fixup_val(super(FlagsField, self).any2i(pkt, x))
1255
1256    def m2i(self, pkt, x):
1257        return self._fixup_val(super(FlagsField, self).m2i(pkt, x))
1258
1259    def i2h(self, pkt, x):
1260        return self._fixup_val(super(FlagsField, self).i2h(pkt, x))
1261
1262    def i2repr(self, pkt, x):
1263        if isinstance(x, (list, tuple)):
1264            return repr(type(x)(
1265                None if v is None else str(self._fixup_val(v)) for v in x
1266            ))
1267        return None if x is None else str(self._fixup_val(x))
1268
1269
1270MultiFlagsEntry = collections.namedtuple('MultiFlagEntry', ['short', 'long'])
1271
1272
1273class MultiFlagsField(BitField):
1274    __slots__ = FlagsField.__slots__ + ["depends_on"]
1275
1276    def __init__(self, name, default, size, names, depends_on):
1277        self.names = names
1278        self.depends_on = depends_on
1279        super(MultiFlagsField, self).__init__(name, default, size)
1280
1281    def any2i(self, pkt, x):
1282        assert isinstance(x, six.integer_types + (set,)), 'set expected'
1283
1284        if pkt is not None:
1285            if isinstance(x, six.integer_types):
1286                x = self.m2i(pkt, x)
1287            else:
1288                v = self.depends_on(pkt)
1289                if v is not None:
1290                    assert v in self.names, 'invalid dependency'
1291                    these_names = self.names[v]
1292                    s = set()
1293                    for i in x:
1294                        for val in six.itervalues(these_names):
1295                            if val.short == i:
1296                                s.add(i)
1297                                break
1298                        else:
1299                            assert False, 'Unknown flag "{}" with this dependency'.format(i)
1300                            continue
1301                    x = s
1302        return x
1303
1304    def i2m(self, pkt, x):
1305        v = self.depends_on(pkt)
1306        if v in self.names:
1307            these_names = self.names[v]
1308        else:
1309            these_names = {}
1310
1311        r = 0
1312        for flag_set in x:
1313            for i, val in six.iteritems(these_names):
1314                if val.short == flag_set:
1315                    r |= 1 << i
1316                    break
1317            else:
1318                r |= 1 << int(flag_set[len('bit '):])
1319        return r
1320
1321    def m2i(self, pkt, x):
1322        v = self.depends_on(pkt)
1323        if v in self.names:
1324            these_names = self.names[v]
1325        else:
1326            these_names = {}
1327
1328        r = set()
1329        i = 0
1330
1331        while x:
1332            if x & 1:
1333                if i in these_names:
1334                    r.add(these_names[i].short)
1335                else:
1336                    r.add('bit {}'.format(i))
1337            x >>= 1
1338            i += 1
1339        return r
1340
1341    def i2repr(self, pkt, x):
1342        v = self.depends_on(pkt)
1343        if v in self.names:
1344            these_names = self.names[v]
1345        else:
1346            these_names = {}
1347
1348        r = set()
1349        for flag_set in x:
1350            for i in six.itervalues(these_names):
1351                if i.short == flag_set:
1352                    r.add("{} ({})".format(i.long, i.short))
1353                    break
1354            else:
1355                r.add(flag_set)
1356        return repr(r)
1357
1358
1359class FixedPointField(BitField):
1360    __slots__ = ['frac_bits']
1361    def __init__(self, name, default, size, frac_bits=16):
1362        self.frac_bits = frac_bits
1363        BitField.__init__(self, name, default, size)
1364
1365    def any2i(self, pkt, val):
1366        if val is None:
1367            return val
1368        ival = int(val)
1369        fract = int( (val-ival) * 2**self.frac_bits )
1370        return (ival << self.frac_bits) | fract
1371
1372    def i2h(self, pkt, val):
1373        int_part = val >> self.frac_bits
1374        frac_part = val & (1 << self.frac_bits) - 1
1375        frac_part /= 2.0**self.frac_bits
1376        return int_part+frac_part
1377    def i2repr(self, pkt, val):
1378        return self.i2h(pkt, val)
1379
1380
1381# Base class for IPv4 and IPv6 Prefixes inspired by IPField and IP6Field.
1382# Machine values are encoded in a multiple of wordbytes bytes.
1383class _IPPrefixFieldBase(Field):
1384    __slots__ = ["wordbytes", "maxbytes", "aton", "ntoa", "length_from"]
1385    def __init__(self, name, default, wordbytes, maxbytes, aton, ntoa, length_from):
1386        self.wordbytes = wordbytes
1387        self.maxbytes = maxbytes
1388        self.aton = aton
1389        self.ntoa = ntoa
1390        Field.__init__(self, name, default, "%is" % self.maxbytes)
1391        self.length_from = length_from
1392
1393    def _numbytes(self, pfxlen):
1394        wbits= self.wordbytes * 8
1395        return ((pfxlen + (wbits - 1)) // wbits) * self.wordbytes
1396
1397    def h2i(self, pkt, x):
1398        # "fc00:1::1/64" -> ("fc00:1::1", 64)
1399        [pfx,pfxlen]= x.split('/')
1400        self.aton(pfx) # check for validity
1401        return (pfx, int(pfxlen))
1402
1403
1404    def i2h(self, pkt, x):
1405        # ("fc00:1::1", 64) -> "fc00:1::1/64"
1406        (pfx,pfxlen)= x
1407        return "%s/%i" % (pfx,pfxlen)
1408
1409    def i2m(self, pkt, x):
1410        # ("fc00:1::1", 64) -> (b"\xfc\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01", 64)
1411        (pfx,pfxlen)= x
1412        s= self.aton(pfx);
1413        return (s[:self._numbytes(pfxlen)], pfxlen)
1414
1415    def m2i(self, pkt, x):
1416        # (b"\xfc\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01", 64) -> ("fc00:1::1", 64)
1417        (s,pfxlen)= x
1418
1419        if len(s) < self.maxbytes:
1420            s= s + (b"\0" * (self.maxbytes - len(s)))
1421        return (self.ntoa(s), pfxlen)
1422
1423    def any2i(self, pkt, x):
1424        if x is None:
1425            return (self.ntoa(b"\0"*self.maxbytes), 1)
1426
1427        return self.h2i(pkt,x)
1428
1429    def i2len(self, pkt, x):
1430        (_,pfxlen)= x
1431        return pfxlen
1432
1433    def addfield(self, pkt, s, val):
1434        (rawpfx,pfxlen)= self.i2m(pkt,val)
1435        fmt= "!%is" % self._numbytes(pfxlen)
1436        return s+struct.pack(fmt, rawpfx)
1437
1438    def getfield(self, pkt, s):
1439        pfxlen= self.length_from(pkt)
1440        numbytes= self._numbytes(pfxlen)
1441        fmt= "!%is" % numbytes
1442        return s[numbytes:], self.m2i(pkt, (struct.unpack(fmt, s[:numbytes])[0], pfxlen))
1443
1444
1445class IPPrefixField(_IPPrefixFieldBase):
1446    def __init__(self, name, default, wordbytes=1, length_from= None):
1447        _IPPrefixFieldBase.__init__(self, name, default, wordbytes, 4, inet_aton, inet_ntoa, length_from)
1448
1449
1450class IP6PrefixField(_IPPrefixFieldBase):
1451    def __init__(self, name, default, wordbytes= 1, length_from= None):
1452        _IPPrefixFieldBase.__init__(self, name, default, wordbytes, 16, lambda a: inet_pton(socket.AF_INET6, a), lambda n: inet_ntop(socket.AF_INET6, n), length_from)
1453
1454class UTCTimeField(IntField):
1455    __slots__ = ["epoch", "delta", "strf", "use_nano"]
1456    def __init__(self, name, default, epoch=None, use_nano=False, strf="%a, %d %b %Y %H:%M:%S +0000"):
1457        IntField.__init__(self, name, default)
1458        if epoch is None:
1459            mk_epoch = EPOCH
1460        else:
1461            mk_epoch = time.mktime(epoch)
1462        self.epoch = mk_epoch
1463        self.delta = mk_epoch - EPOCH
1464        self.strf = strf
1465        self.use_nano = use_nano
1466    def i2repr(self, pkt, x):
1467        if x is None:
1468            x = 0
1469        elif self.use_nano:
1470            x = x/1e9
1471        x = int(x) + self.delta
1472        t = time.strftime(self.strf, time.gmtime(x))
1473        return "%s (%d)" % (t, x)
1474    def i2m(self, pkt, x):
1475        return int(x) if x != None else 0
1476