1
2
3 """Ethernet II, LLC (802.3+802.2), LLC/SNAP, and Novell raw 802.3,
4 with automatic 802.1q, MPLS, PPPoE, and Cisco ISL decapsulation."""
5
6 import struct
7 import dpkt, stp
8
9 ETH_CRC_LEN = 4
10 ETH_HDR_LEN = 14
11
12 ETH_LEN_MIN = 64
13 ETH_LEN_MAX = 1518
14
15 ETH_MTU = (ETH_LEN_MAX - ETH_HDR_LEN - ETH_CRC_LEN)
16 ETH_MIN = (ETH_LEN_MIN - ETH_HDR_LEN - ETH_CRC_LEN)
17
18
19 ETH_TYPE_PUP = 0x0200
20 ETH_TYPE_IP = 0x0800
21 ETH_TYPE_ARP = 0x0806
22 ETH_TYPE_CDP = 0x2000
23 ETH_TYPE_DTP = 0x2004
24 ETH_TYPE_REVARP = 0x8035
25 ETH_TYPE_8021Q = 0x8100
26 ETH_TYPE_IPX = 0x8137
27 ETH_TYPE_IP6 = 0x86DD
28 ETH_TYPE_PPP = 0x880B
29 ETH_TYPE_MPLS = 0x8847
30 ETH_TYPE_MPLS_MCAST = 0x8848
31 ETH_TYPE_PPPoE_DISC = 0x8863
32 ETH_TYPE_PPPoE = 0x8864
33
35 __hdr__ = (
36 ('dst', '6s', ''),
37 ('src', '6s', ''),
38 ('type', 'H', ETH_TYPE_IP)
39 )
40 _typesw = {}
41
59
61 dpkt.Packet.unpack(self, buf)
62 if self.type > 1500:
63
64 self._unpack_data(self.data)
65 elif self.dst.startswith('\x01\x00\x0c\x00\x00') or \
66 self.dst.startswith('\x03\x00\x0c\x00\x00'):
67
68
69 self.unpack(self.data[12:])
70 elif self.data.startswith('\xff\xff'):
71
72 self.type = ETH_TYPE_IPX
73 self.data = self.ipx = self._typesw[ETH_TYPE_IPX](self.data[2:])
74 else:
75
76
77 if self.data.startswith('\xaa\xaa'):
78
79 self.type = struct.unpack('>H', self.data[6:8])[0]
80 self._unpack_data(self.data[8:])
81 else:
82
83 dsap = ord(self.data[0])
84 if dsap == 0x06:
85 self.data = self.ip = self._typesw[ETH_TYPE_IP](self.data[3:])
86 elif dsap == 0x10 or dsap == 0xe0:
87 self.data = self.ipx = self._typesw[ETH_TYPE_IPX](self.data[3:])
88 elif dsap == 0x42:
89 self.data = self.stp = stp.STP(self.data[3:])
90
93 set_type = classmethod(set_type)
94
97 get_type = classmethod(get_type)
98
99
101 import os
102 d = dict.fromkeys([ x[:-3] for x in os.listdir(os.path.dirname(__file__) or '.') if x.endswith('.py') ])
103 g = globals()
104 for k, v in g.iteritems():
105 if k.startswith('ETH_TYPE_'):
106 name = k[9:]
107 modname = name.lower()
108 if modname in d:
109 mod = __import__(modname, g)
110 Ethernet.set_type(v, getattr(mod, name))
111
112 if not Ethernet._typesw:
113 __load_types()
114
115 if __name__ == '__main__':
116 import unittest
117
120 s = '\x00\xb0\xd0\xe1\x80r\x00\x11$\x8c\x11\xde\x86\xdd`\x00\x00\x00\x00(\x06@\xfe\x80\x00\x00\x00\x00\x00\x00\x02\x11$\xff\xfe\x8c\x11\xde\xfe\x80\x00\x00\x00\x00\x00\x00\x02\xb0\xd0\xff\xfe\xe1\x80r\xcd\xd3\x00\x16\xffP\xd7\x13\x00\x00\x00\x00\xa0\x02\xff\xffg\xd3\x00\x00\x02\x04\x05\xa0\x01\x03\x03\x00\x01\x01\x08\n}\x18:a\x00\x00\x00\x00'
121 eth = Ethernet(s)
122
123 unittest.main()
124