網路封包就是一層層疊上去的方式建構而成,解析時候再一層層分下來。乙太網路封包最底層就是MAC層,記載本地唯一的機器位址,以及目的唯一的機器位址。再來是VLAN層,記載包含VLAN ID, 優先權記錄。再疊上來就是所謂的第三層,任何乙太封包最後都會帶一個FCS結尾。
比方說,一個UDP封包,就是由「MAC」+「VLAN(選擇性)」+「Type(通常是2個bytes,0x0800)」+「IP Header」+「UDP Header」+「Payload」+「FCS」。以圖示來說就是:
從Wireshark抓包來看,一個簡單的UDP的樣子如下:
所以我這個header要做的動作就是按照這樣步驟,去一層一層加上去。然後我引用了另一個同事的header,主要在於將MAC以及IPv4用Class方式包裝,就不用一個byte一個byte去注意。
Genetor主要動作如下:
- #include "ProtocolPkt.h"
- CProtocolPkt ether_pkt;//宣告
- 開始設定值
CMAC tempMAC; tempMAC.SetMAC(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF); ether_pkt.hdr_ethernet.SetDestMAC(tempMAC); tempMAC.SetMAC(0x00, 0x22, 0xA2, 0x00, 0xAA, 0x01); ether_pkt.hdr_ethernet.SetSourceMAC(tempMAC); ether_pkt.hdr_ethernet.hdr_vlan.SetVLANCFI(1); ether_pkt.hdr_ethernet.hdr_vlan.SetVLANPriority(3); ether_pkt.hdr_ethernet.hdr_vlan.SetVLANID(1111); ether_pkt.hdr_ethernet.SetEtherTypeLength(0x0800); ether_pkt.hdr_ipv4.SetSourceIP(CIPv4(192, 168, 0, 10)); ether_pkt.hdr_ipv4.SetDestIP(CIPv4(192, 168, 0, 20)); ether_pkt.hdr_ipv4.SetProtocol(IPPROTOCOL_UDP); ether_pkt.hdr_ipv4.SetTotalLength(nicmode.packet_len-14); UI32_T protMap = 0; //決定要啟用哪個protocol protMap |= PACKET_ETHERNET;//開啟MAC protMap |= ether_pkt.PACKET_IPV4;//開啟IP //protMap |= ether_pkt.PACKET_UDP;//關閉UDP //protMap |= ether_pkt.PACKET_VLAN;//關閉VLAN //protMap |= ether_pkt.PACKET_ICMP;//關閉ICMP //protMap |= ether_pkt.PACKET_DHCP;//關閉DHCP ether_pkt.SetProtocolMap(protMap); //Copy至其他資料來源。將ether_pkt資料,按照長度,完全copy到指定的地方 ether_pkt.CopyPacket(data, packet_len);
然後我的Data大概就會長成這樣:
Parser主要動作如下:
因為少了設定,動作上看起來會簡單許多。include部份就不列上去了。
CProtocolPkt ether_pkt; ether_pkt.ParsePacket(reply_data, 64*sizeof(unsigned char)); //然後我可以在這邊做一些判斷,比方說判斷是不是ping reply包 if(ether_pkt.hdr_ipv4.GetProtocol() == 1) // ip header protocol = ICMP if(ether_pkt.hdr_icmp.GetType() == 0) // ICMP header type = 0因為我的工作有許多要分析包和產生包的動作,每次都用char*去兜包的方式蠻煩的,用這個class就可以減少很多時間,增加可讀性。
然後這個class寫得可能不是很好,因為我電腦是win7 64+i3+8G ram,實測起來一秒鐘大概只可以分析處理1500個封包左右,還有一些可以改進的地方。像wireshark在我電腦,不會當機的情況下大約處理1000個/秒,但還包含顯示,以及更多protocol判斷,反正目前用來沒有大量分析包的需求,將就囉。
Source code:
- BasicElement.h(裡頭包含許多可能沒用到的class)
- ProtocolPkt.h
0 意見:
張貼留言