Package dpkt :: Module gre
[hide private]
[frames] | no frames]

Source Code for Module dpkt.gre

  1  # $Id: gre.py 75 2010-08-03 14:42:19Z jon.oberheide $ 
  2  # -*- coding: utf-8 -*- 
  3  """Generic Routing Encapsulation.""" 
  4  from __future__ import absolute_import 
  5   
  6  import struct 
  7  import codecs 
  8   
  9  from . import dpkt 
 10  from . import ethernet 
 11  from .decorators import deprecated 
 12  from .compat import compat_izip 
 13   
 14  GRE_CP = 0x8000  # Checksum Present 
 15  GRE_RP = 0x4000  # Routing Present 
 16  GRE_KP = 0x2000  # Key Present 
 17  GRE_SP = 0x1000  # Sequence Present 
 18  GRE_SS = 0x0800  # Strict Source Route 
 19  GRE_AP = 0x0080  # Acknowledgment Present 
 20   
 21  GRE_opt_fields = ( 
 22      (GRE_CP | GRE_RP, 'sum', 'H'), (GRE_CP | GRE_RP, 'off', 'H'), 
 23      (GRE_KP, 'key', 'I'), (GRE_SP, 'seq', 'I'), (GRE_AP, 'ack', 'I') 
 24  ) 
25 26 27 -class GRE(dpkt.Packet):
28 """Generic Routing Encapsulation. 29 30 TODO: Longer class information.... 31 32 Attributes: 33 __hdr__: Header fields of GRE. 34 TODO. 35 """ 36 37 __hdr__ = ( 38 ('flags', 'H', 0), 39 ('p', 'H', 0x0800), # ETH_TYPE_IP 40 ) 41 sre = () 42 43 @property
44 - def v(self):
45 return self.flags & 0x7
46 47 @v.setter
48 - def v(self, v):
49 self.flags = (self.flags & ~0x7) | (v & 0x7)
50 51 @property
52 - def recur(self):
53 return (self.flags >> 5) & 0x7
54 55 @recur.setter
56 - def recur(self, v):
57 self.flags = (self.flags & ~0xe0) | ((v & 0x7) << 5)
58
59 - class SRE(dpkt.Packet):
60 __hdr__ = [ 61 ('family', 'H', 0), 62 ('off', 'B', 0), 63 ('len', 'B', 0) 64 ] 65
66 - def unpack(self, buf):
67 dpkt.Packet.unpack(self, buf) 68 self.data = self.data[:self.len]
69
70 - def opt_fields_fmts(self):
71 if self.v == 0: 72 fields, fmts = [], [] 73 opt_fields = GRE_opt_fields 74 else: 75 fields, fmts = ['len', 'callid'], ['H', 'H'] 76 opt_fields = GRE_opt_fields[-2:] 77 for flags, field, fmt in opt_fields: 78 if self.flags & flags: 79 fields.append(field) 80 fmts.append(fmt) 81 return fields, fmts
82
83 - def unpack(self, buf):
84 dpkt.Packet.unpack(self, buf) 85 fields, fmts = self.opt_fields_fmts() 86 if fields: 87 fmt = ''.join(fmts) 88 fmtlen = struct.calcsize(fmt) 89 vals = struct.unpack("!" + fmt, self.data[:fmtlen]) 90 self.data = self.data[fmtlen:] 91 self.__dict__.update(dict(compat_izip(fields, vals))) 92 if self.flags & GRE_RP: 93 l = [] 94 while True: 95 sre = self.SRE(self.data) 96 self.data = self.data[len(sre):] 97 l.append(sre) 98 if not sre.len: 99 break 100 self.sre = l 101 try: 102 self.data = ethernet.Ethernet._typesw[self.p](self.data) 103 setattr(self, self.data.__class__.__name__.lower(), self.data) 104 except (KeyError, dpkt.UnpackError): 105 # data alrady set 106 pass
107
108 - def __len__(self):
109 opt_fmtlen = struct.calcsize(b''.join(self.opt_fields_fmts()[1])) 110 return self.__hdr_len__ + opt_fmtlen + sum(map(len, self.sre)) + len(self.data)
111
112 - def __bytes__(self):
113 fields, fmts = self.opt_fields_fmts() 114 if fields: 115 vals = [] 116 for f in fields: 117 vals.append(getattr(self, f)) 118 opt_s = struct.pack(b''.join(fmts), *vals) 119 else: 120 opt_s = b'' 121 return self.pack_hdr() + opt_s + b''.join(map(bytes, self.sre)) + bytes(self.data)
122
123 124 -def test_gre_v1():
125 # Runs all the test associated with this class/file 126 s = codecs.decode("3081880a0067178000068fb100083a76", 'hex') + b"A" * 103 127 g = GRE(s) 128 129 assert g.v == 1 130 assert g.p == 0x880a 131 assert g.seq == 430001 132 assert g.ack == 539254 133 assert g.callid == 6016 134 assert g.len == 103 135 assert g.data == b"A" * 103 136 137 s = codecs.decode("3001880a00b2001100083ab8", 'hex') + b"A" * 178 138 g = GRE(s) 139 140 assert g.v == 1 141 assert g.p == 0x880a 142 assert g.seq == 539320 143 assert g.callid == 17 144 assert g.len == 178 145 assert g.data == b"A" * 178
146 147 148 if __name__ == '__main__': 149 test_gre_v1() 150