關於使用Winpcap發送資料包的心得

來源:互聯網
上載者:User

在對網路資料包發送解析進行編程的時候,人們普遍使用的是Win socket通訊端技術,但該技術僅限於網路層及其以上的傳輸層,對於下層應用的不多,為了瞭解資料包發送的真正機制,需要使用winpcap來進行資料包發送。下面針對兩種協議使用winpcap進行資料包的發送。

winpcap:http://www.winpcap.org/archive/

使用winpcap發送TCP協議資料包

首先本機上應該安裝winpcap以及wpcap,這樣才可以調用winpcap中的函數。

下面針對TCP協議進行分析:

由於要發送的資料必須構建乙太網路資料頭,IP資料包頭和TCP資料包頭,所以待發送的資料應該如下:

乙太網路資料頭 | *.*IP資料頭 | TCP資料頭 | 資料

  1. 定義乙太網路資料頭結構

typedef struct et_header

{

unsigned char eh_dst[6]; //目的地址

unsigned char eh_src[6]; //源地址

unsigned short eh_type; //eh_type的值需要考察上一層的協議,如果為ip則為0×0800

}ET_HEADER;

  1. 定義IP資料前序

typedef struct ip_hdr

{

unsigned char h_verlen; //ip頭部長度(按4位元組對齊)

unsigned char tos; //服務類型

unsigned short total_len; //總長度(包含IP資料頭,TCP資料頭以及資料)

unsigned char version:4; //一般IP類型為IPv4

unsigned short ident; //ID定義單獨IP

unsigned short frag_and_flags;//標誌位位移量

unsigned char ttl; //存留時間

unsigned char proto; //協議類型

unsigned short checksum; //檢查和

unsigned int sourceIP; //源IP地址

unsigned int destIP; //目的IP地址

}IP_HEADER;

  1. 定義TCP資料前序

typedef struct tcp_hdr

{

unsigned short th_sport; //源連接埠

unsigned short th_dport; //目的連接埠

unsigned int th_seq; //序號

unsigned int th_ack; //確認號

unsigned char th_lenres; //4位首部長度

unsigned char th_flag; //標誌位

unsigned short th_win; //視窗大小

unsigned short th_sum; //檢驗和

unsigned short th_urp; //緊急指標

}TCP_HEADER;

上面三個結構類型中構建了資料前序的所有資訊

考慮到檢驗和的問題,需要添加一個偽首部:

typedef struct tsd_hdr

{

unsigned long saddr; //源地址

unsigned long daddr; //目的地址

char mbz; //置空

char ptcl; //協議類型

unsigned short tcpl; //資料包長度

}PSD_HEADER;

以下針對資訊進行處理

處理流程:

l 擷取本地機器裝置列表(調用pcap_findalldevs_ex函數)如果找到網卡裝置就把裝置儲存在interfaceName(可以自訂)變數之中,同時擷取本地IP地址(最基本條件下),調用pcap_freealldevs函數釋放裝置。

l 擷取本地網關的MAC地址,通過聲明PPACKET_OID_DATA OidData,然後進行MAC地址分配空間

OidData=(PPACKET_OID_DATA)malloc(6+sizeof(PACKET_OID_DATA)),調用OidDATA->Oid=OID_802_3_CURRENT_ADDRESS;ZeroMemory(OidData->Data,6);即可獲得MAC地址

l 接下來對資料包的頭部進行賦值,尤其要注意針對由於TCP標誌位較多,可以使用位元運算判斷FLAG的具體值。

l pcap_open( InterfaceName, 100, PCAP_OPENFLAG_PROMISCUOUS, 100, NULL, errbuf )該函數開啟網卡裝置

l pcap_sendpacket( pcap_t *p, Buffer, sizeof(Buffer) 發送資料包,Buffer就是要發送資料包,p表示winpcap控制代碼

使用Winpcap發送UDP資料包

類似TCP所不同的是需要添加UDP頭部資料

UDP資料包頭

struct udphdr
{
u_int16_t source; /* source port */
u_int16_t dest; /* destination port */
u_int16_t len; /* udp length */
u_int16_t checkl; /* udp checksum */
};

為了避免重複,下面說明資料包頭部資訊的設定

ether_header* pether_header=(ether_header*)buffer; //乙太網路首部指標

ip_header* pip_herder=(ip_header*)(buffer + sizeof(ether_header)); //IP資料頭指標

udphdr* pudp_herder=(udphdr*)(buffer + sizeof(ether_header) + sizeof(ip_header));//UDP資料頭指標

//針對乙太網路頭部源地址進行賦值

pether_header->ether_dhost[0] = 1; //0×0 * 16 + 0×0;;

pether_header->ether_dhost[1] = 1; //0×2 * 16 + 0×1;

pether_header->ether_dhost[2] = 1; //0×2 * 16 + 0×7;

pether_header->ether_dhost[3] = 1; //0×2 * 16 + 0×3;

pether_header->ether_dhost[4] = 1; //0×7 * 16 + 0×2;

pether_header->ether_dhost[5] = 1; //0xf * 16 + 0xe;

//針對乙太網路頭部目的地址進行賦值

pether_header->ether_shost[0] = 1; //0×0 * 16 + 0×0;;

pether_header->ether_shost[1] = 1; //0×1 * 16 + 0xF;

pether_header->ether_shost[2] = 1; //0xD * 16 + 0×0;

pether_header->ether_shost[3] = 1; //0×1 * 16 + 0×6;

pether_header->ether_shost[4] = 1; //0×6 * 16 + 0×3;

pether_header->ether_shost[5] = 1; //0×7 * 16 + 0×1;

//針對乙太網路協議進行賦值

pether_header->ether_type = htons(ETHERTYPE_IP);

//構建IP資料頭

pip_herder->ihl = sizeof(ip_header) / 4; //以4位元組為單位

pip_herder->version = 4; //設定版本號碼

pip_herder->tos = 0; //設定類型

pip_herder->tot_len = htons(sizeof(buffer) – sizeof(ether_header)); //設定長度

pip_herder->id = htons(0×1000);//設定ID

pip_herder->frag_off = htons(0);//設定位移量

pip_herder->ttl = 0×80;//設定TTL

pip_herder->protocol = IPPROTO_UDP; //設定協議類型

pip_herder->check = 0; //設定檢驗和

pip_herder->saddr = inet_addr(“192.168.18.*”); //設定源地址

pip_herder->daddr = inet_addr(“122.*.*.*”);//設定目的地址

pip_herder->check = in_cksum((u_int16_t*)pip_herder, sizeof(ip_header)); //重新設定檢驗和

//構建UDP資料頭;

pudp_herder->dest = htons(7865); //目的連接埠號碼

pudp_herder->source = htons(2834);//源連接埠號碼

pudp_herder->len = htons(sizeof(buffer) – sizeof(ether_header) – sizeof(ip_header));//設定長度

pudp_herder->checkl = 0;//設定檢驗和

//構造偽UDP首部

char buffer2[64] = { 0 };

Psd_Header* psd = (Psd_Header*)buffer2;

psd->sourceip = inet_addr(“192.168.18.*”);

psd->destip = inet_addr(“122.*.*.*”);

psd->ptcl = IPPROTO_UDP;

psd->plen = htons(sizeof(buffer) – sizeof(ether_header) – sizeof(ip_header));

psd->mbz = 0;

memcpy(buffer2 + sizeof(Psd_Header), (void*)pudp_herder, sizeof(buffer) – sizeof(ether_header) – sizeof(ip_header));

pudp_herder->checkl = in_cksum((u_int16_t *)buffer2,sizeof(buffer) – sizeof(ether_header) – sizeof(ip_header) + sizeof(Psd_Header));

接下來調用pcap_open,pcap_sendpacket即可發送資料包

小結:通過研究這兩個協議瞭解了winpcap發送資料包的過程和原理,相信針對其他協議也是大同小異。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.