分类: 网络与安全
2011-12-28 16:20:00
首先从最简单的以太网层开始。我们知道,目前常用的以太网帧结构有两种,一个是IEEE802.3,一个是Ethernet II,两者的区别也很清楚,就是在目的Mac地址和源Mac地址好后面的两个字节是代表长度还是类型。
EtherType 是以太帧里的一个字段,用来指明应用于帧数据字段的协议。根据 IEEE802.3,Length/EtherType 字段是两个八字节的字段,含义两者取一,这取决于其数值。在量化评估中,字段中的第一个八位字节是最重要的。而当字段值大于等于十进制值 1536 (即十六进制为 0600)时, EtherType 字段表示为 MAC 客户机协议(EtherType 解释)的种类。该字段的长度和 EtherType 详解是互斥的。
Ethertype(十六进制) | 协议 |
0x0000 - 0x05DC | IEEE 802.3 长度 |
0x0101 – 0x01FF | 实验 |
0x0600 | XEROX NS IDP |
0x0660 0x0661 | DLOG |
0x0800 | 网际协议(IP) |
0x0801 | X.75 Internet |
0x0802 | NBS Internet |
0x0803 | ECMA Internet |
0x0804 | Chaosnet |
0x0805 | X.25 Level 3 |
0x0806 | 地址解析协议(ARP : Address Resolution Protocol) |
0x0808 | 帧中继 ARP (Frame Relay ARP) [RFC1701] |
0x6559 | 原始帧中继(Raw Frame Relay) [RFC1701] |
0x8035 | 动态 DARP(DRARP:Dynamic RARP) 反向地址解析协议(RARP:Reverse Address Resolution Protocol) |
0x8037 | Novell Netware IPX |
0x809B | EtherTalk |
0x80D5 | IBM SNA Services over Ethernet |
0x 80F 3 | AppleTalk 地址解析协议(AARP:AppleTalk Address Resolution Protocol) |
0x8100 | 以太网自动保护开关(EAPS:Ethernet Automatic Protection Switching) |
0x8137 | 因特网包交换(IPX:Internet Packet Exchange) |
0x 814C | 简单网络管理协议(SNMP:Simple Network Management Protocol) |
0x86DD | 网际协议v6 (IPv6,Internet Protocol version 6) |
0x880B | 点对点协议(PPP:Point-to-Point Protocol) |
0x 880C | 通用交换管理协议(GSMP:General Switch Management Protocol) |
0x8847 | 多协议标签交换(单播) MPLS:Multi-Protocol Label Switching
|
0x8848 | 多协议标签交换(组播)(MPLS, Multi-Protocol Label Switching
|
0x8863 | 以太网上的 PPP(发现阶段)(PPPoE:PPP Over Ethernet
|
0x8864 | 以太网上的 PPP(PPP 会话阶段) (PPPoE,PPP Over Ethernet |
0x88BB | 轻量级访问点协议(LWAPP:Light Weight Access Point Protocol) |
0x88CC | 链接层发现协议(LLDP:Link Layer Discovery Protocol) |
0x8E88 | 局域网上的 EAP(EAPOL:EAP over LAN) |
0x9000 | 配置测试协议(Loopback) |
0x9100 | VLAN 标签协议标识符(VLAN Tag Protocol Identifier) |
0x9200 | VLAN 标签协议标识符(VLAN Tag Protocol Identifier) |
0xFFFF | 保留 |
在python中我是用一个字典来实现的:
EtherType = {'0x0600':'XEROX NS IDP',
'0x0660':'DLOG',
'0x0661':'DLOG',
'0x0800':'IP',
'0x0801':'X.75',
'0x0802':'NBS',
'0x0803':'ECMA',
'0x0804':'Chaosnet',
'0x0805':'X.25',
'0x0806':'ARP',
'0x0808':'Frame Relay ARP',
'0x6559':'Raw Frame Relay',
'0x8035':'RARP',
'0x8037':'Novell Netware IPX',
'0x809B':'Ether Talk',
'0x80d5':'IBM SNA Service over Ethernet',
'0x80f3':'AARP',
'0x8100':'EAPS',
'0x8137':'IPX',
'0x814c':'SNMP',
'0x86dd':'IPv6',
'0x880b':'PPP',
'0x880c':'GSMP',
'0x8847':'MPLS(unicase)',
'0x8848':'MPLS(multicast)',
'0x8863':'PPPoE(Discovery stage)',
'0x8864':'PPPoE(ppp session stage)',
'0x88bb':'LWAPP',
'0x88cc':'LLDP',
'0x8e88':'EAP over LAN',
'0x9000':'Loopback',
'0x9100':'VLAN Tag PI',
'0x9200':'VLAN Tag PI',
'0xffff':'Reservations'
}
然后根据二进制字符来分解:
# framedata.py
# !/usr/bin/python
class Protocol(object):
def __init__(self):
pass
# transform like '\x01\x0e\0xb0' to '0x010eb0'
def str_to_hex(self,strs):
hex_data =''
for i in range(len(strs)):
tem = ord(strs[i])
tem = hex(tem)
if len(tem)==3:
tem = tem.replace('0x','0x0')
tem = tem.replace('0x','')
hex_data = hex_data+tem
return '0x'+hex_data
class Ethernet(Protocol):
def __init__(self,datastr=None):
self.dst = None
self.src = None
self.ethertype = None
self.len = None
self.type = None
self.datastr = datastr
def decode(self):
tem = self.str_to_hex(self.datastr[0:6])
self.dst = tem[2:4]+':'+tem[4:6]+':'+tem[6:8]+':'+tem[8:10]+':'+tem[10:12]+':'+tem[12:14]
tem = self.str_to_hex(self.datastr[6:12])
self.src = tem[2:4]+':'+tem[4:6]+':'+tem[6:8]+':'+tem[8:10]+':'+tem[10:12]+':'+tem[12:14]
self.unknow = self.str_to_hex(self.datastr[12:14])
tem = int(self.unknow,16)
dststr = 'Destination: '+self.dst
srcstr = 'Source : '+self.src
if tem<=1500:
self.ethertype='IEEE 802.3 Ethernet'
self.len =tem
lenstr = 'Length: '+str(self.len)
return [self.ethertype, dststr,srcstr,lenstr]
elif tem>=1536:
self.ethertype='Eternet II'
self.type = EtherType[self.unknow]
typestr = 'Type: '+self.type+'('+self.unknow+')'
return [self.ethertype, dststr,srcstr,typestr]
其中父类Protocol还在初级探索阶段,没有成型,以后会根据需要完善。
测试:
# !/usr/bin/python
from readpcapfile import *
from framedata import *
data
=rdpcap("C:\\Python25\\code\\pcap\\PcapReader\\pcap\\test_ether.pcap")
for i in range(len(data)):
strs =
data[i][1]
test =
Ethernet(strs)
Ether_data =
test.decode()
print
Ether_data
结果类似于:
['Eternet II', 'Destination:
ff:ff:ff:ff:ff:ff',
'Source
: 00:0e:a6:27:07:ab', 'Type: IP(0x0800)']
['Eternet II', 'Destination: ff:ff:ff:ff:ff:ff',
'Source
: 00:0e:a6:27:07:ab', 'Type: IP(0x0800)']
['Eternet II', 'Destination: ff:ff:ff:ff:ff:ff',
'Source
: 00:0e:a6:27:07:ab', 'Type: IP(0x0800)']
['Eternet II', 'Destination: ff:ff:ff:ff:ff:ff',
'Source
: 00:0e:a6:27:07:ab', 'Type: IP(0x0800)']
['IEEE 802.3 Ethernet', 'Destination: 01:00:0c:cc:cc:cd',
'Source
: 00:0a:8a:1f:55:11', 'Length: 50']
['Eternet II', 'Destination: ff:ff:ff:ff:ff:ff',
'Source
: 00:0e:a6:27:07:ab', 'Type: ARP(0x0806)']
['Eternet II', 'Destination: ff:ff:ff:ff:ff:ff',
'Source
: 00:0e:a6:27:07:ab', 'Type: IP(0x0800)']
['Eternet II', 'Destination: ff:ff:ff:ff:ff:ff',
'Source
: 00:0e:a6:27:07:ab', 'Type: IP(0x0800)']
['Eternet II', 'Destination: ff:ff:ff:ff:ff:ff',
'Source
: 00:0e:a6:27:07:ab', 'Type: IP(0x0800)']
['Eternet II', 'Destination: 00:0f:e2:d7:ef:f9',
'Source
: 00:12:3f:92:b0:41', 'Type: IP(0x0800)']
['Eternet II', 'Destination: 00:0f:e2:d7:ef:f9',
'Source
: 00:12:3f:92:b0:41', 'Type: IP(0x0800)']
['Eternet II', 'Destination: 00:0f:e2:d7:ef:f9',
'Source
: 00:12:3f:92:b0:41', 'Type: IP(0x0800)']
['Eternet II', 'Destination: 00:0f:e2:d7:ef:f9',
'Source
: 00:12:3f:92:b0:41', 'Type: IP(0x0800)']
['Eternet II', 'Destination: 00:0f:e2:d7:ef:f9',
'Source
: 00:12:3f:92:b0:41', 'Type: IP(0x0800)']
['Eternet II', 'Destination: 00:0f:e2:d7:ef:f9',
'Source
: 00:12:3f:92:b0:41', 'Type: IP(0x0800)']
['Eternet II', 'Destination: ff:ff:ff:ff:ff:ff',
'Source
: 00:0e:a6:27:07:ab', 'Type: IP(0x0800)']