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