Home | Trees | Indices | Help |
|
---|
|
1 # $Id: ethernet.py 65 2010-03-26 02:53:51Z dugsong $ 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 # minimum frame length with CRC 13 ETH_LEN_MAX = 1518 # maximum frame length with CRC 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 # Ethernet payload types - http://standards.ieee.org/regauth/ethertype 19 ETH_TYPE_PUP = 0x0200 # PUP protocol 20 ETH_TYPE_IP = 0x0800 # IP protocol 21 ETH_TYPE_ARP = 0x0806 # address resolution protocol 22 ETH_TYPE_AOE = 0x88a2 # AoE protocol 23 ETH_TYPE_CDP = 0x2000 # Cisco Discovery Protocol 24 ETH_TYPE_DTP = 0x2004 # Cisco Dynamic Trunking Protocol 25 ETH_TYPE_REVARP = 0x8035 # reverse addr resolution protocol 26 ETH_TYPE_8021Q = 0x8100 # IEEE 802.1Q VLAN tagging 27 ETH_TYPE_IPX = 0x8137 # Internetwork Packet Exchange 28 ETH_TYPE_IP6 = 0x86DD # IPv6 protocol 29 ETH_TYPE_PPP = 0x880B # PPP 30 ETH_TYPE_MPLS = 0x8847 # MPLS 31 ETH_TYPE_MPLS_MCAST = 0x8848 # MPLS Multicast 32 ETH_TYPE_PPPoE_DISC = 0x8863 # PPP Over Ethernet Discovery Stage 33 ETH_TYPE_PPPoE = 0x8864 # PPP Over Ethernet Session Stage 34 ETH_TYPE_LLDP = 0x88CC #Link Layer Discovery Protocol 35 36 # MPLS label stack fields 37 MPLS_LABEL_MASK = 0xfffff000 38 MPLS_QOS_MASK = 0x00000e00 39 MPLS_TTL_MASK = 0x000000ff 40 MPLS_LABEL_SHIFT= 12 41 MPLS_QOS_SHIFT = 9 42 MPLS_TTL_SHIFT = 0 43 MPLS_STACK_BOTTOM=0x0100 4446 __hdr__ = ( 47 ('dst', '6s', ''), 48 ('src', '6s', ''), 49 ('type', 'H', ETH_TYPE_IP) 50 ) 51 _typesw = {} 52115 116 # XXX - auto-load Ethernet dispatch table from ETH_TYPE_* definitions54 if self.type == ETH_TYPE_8021Q: 55 self.tag, self.type = struct.unpack('>HH', buf[:4]) 56 buf = buf[4:] 57 elif self.type == ETH_TYPE_MPLS or \ 58 self.type == ETH_TYPE_MPLS_MCAST: 59 # XXX - skip labels (max # of labels is undefined, just use 24) 60 self.labels = [] 61 for i in range(24): 62 entry = struct.unpack('>I', buf[i*4:i*4+4])[0] 63 label = ((entry & MPLS_LABEL_MASK) >> MPLS_LABEL_SHIFT, \ 64 (entry & MPLS_QOS_MASK) >> MPLS_QOS_SHIFT, \ 65 (entry & MPLS_TTL_MASK) >> MPLS_TTL_SHIFT) 66 self.labels.append(label) 67 if entry & MPLS_STACK_BOTTOM: 68 break 69 self.type = ETH_TYPE_IP 70 buf = buf[(i + 1) * 4:] 71 try: 72 self.data = self._typesw[self.type](buf) 73 setattr(self, self.data.__class__.__name__.lower(), self.data) 74 except (KeyError, dpkt.UnpackError): 75 self.data = buf7678 dpkt.Packet.unpack(self, buf) 79 if self.type > 1500: 80 # Ethernet II 81 self._unpack_data(self.data) 82 elif self.dst.startswith('\x01\x00\x0c\x00\x00') or \ 83 self.dst.startswith('\x03\x00\x0c\x00\x00'): 84 # Cisco ISL 85 self.vlan = struct.unpack('>H', self.data[6:8])[0] 86 self.unpack(self.data[12:]) 87 elif self.data.startswith('\xff\xff'): 88 # Novell "raw" 802.3 89 self.type = ETH_TYPE_IPX 90 self.data = self.ipx = self._typesw[ETH_TYPE_IPX](self.data[2:]) 91 else: 92 # 802.2 LLC 93 self.dsap, self.ssap, self.ctl = struct.unpack('BBB', self.data[:3]) 94 if self.data.startswith('\xaa\xaa'): 95 # SNAP 96 self.type = struct.unpack('>H', self.data[6:8])[0] 97 self._unpack_data(self.data[8:]) 98 else: 99 # non-SNAP 100 dsap = ord(self.data[0]) 101 if dsap == 0x06: # SAP_IP 102 self.data = self.ip = self._typesw[ETH_TYPE_IP](self.data[3:]) 103 elif dsap == 0x10 or dsap == 0xe0: # SAP_NETWARE{1,2} 104 self.data = self.ipx = self._typesw[ETH_TYPE_IPX](self.data[3:]) 105 elif dsap == 0x42: # SAP_STP 106 self.data = self.stp = stp.STP(self.data[3:])107 110 set_type = classmethod(set_type) 111 114 get_type = classmethod(get_type)118 g = globals() 119 for k, v in g.iteritems(): 120 if k.startswith('ETH_TYPE_'): 121 name = k[9:] 122 modname = name.lower() 123 try: 124 mod = __import__(modname, g) 125 except ImportError: 126 continue 127 Ethernet.set_type(v, getattr(mod, name))128 129 if not Ethernet._typesw: 130 __load_types() 131 132 if __name__ == '__main__': 133 import unittest 134139 140 unittest.main() 141137 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' 138 eth = Ethernet(s)
Home | Trees | Indices | Help |
|
---|
Generated by Epydoc 3.0.1 on Thu Mar 19 07:50:10 2015 | http://epydoc.sourceforge.net |