[C++]自己寫一個好用的網路封包Generator與Parser

在介紹這個封包產生與解析的C++ Header檔案之前,先簡單介紹一下乙太網路封包的格式。

網路封包就是一層層疊上去的方式建構而成,解析時候再一層層分下來。乙太網路封包最底層就是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主要動作如下:

  1. #include "ProtocolPkt.h"
  2. CProtocolPkt ether_pkt;//宣告
  3. 開始設定值
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:

0 意見:

搜尋此網誌

總網頁瀏覽量

TK呱呱

Made with by TK