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