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