日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Winpcap网络编程十之Winpcap实战,两台主机通过中间主机通信

發布時間:2025/5/22 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Winpcap网络编程十之Winpcap实战,两台主机通过中间主机通信 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

注:源碼等等的我不會全然公開的,此篇文章寫出來為大家的網絡編程或者課程設計提供一定的思路..

好,本次我們須要完畢的任務是:

完畢兩臺主機通過中間主機的數據通信(網絡層)

  • ?添加基于IP地址的轉發功能
  • ?添加網絡層封裝

事實上最基本的就是基于IP地址的轉發功能,網絡層的封裝事實上我們在0基礎功能中就已經做好了。

首先,實驗的思路是A通過中間主機B向C發送數據。那么B則作為一個路由器,B要監聽兩個網卡,一個網卡發來的數據通過還有一個網卡發出去。

示意圖例如以下:

A--------->B1===B2------------>C

從圖上能夠看出,B主機的兩個網卡數據互通,A和B1則處于一個局域網內,B2和C處于還有一個局域網內。

就比方這樣,如今室友A在用有線上網,我的電腦B也在用有線上網,我們的有線處在同一局域網,我的電腦B同一時候散著一個無線網,我的手機C又連接到了這個無線上。

那么要實現A到C的數據傳送,即模擬室友A要發送數據到我的手機C,那么流程則是這種:

室友A在有線局域網發送數據到我的網卡B1,B1將數據通過網卡B2轉發到無線局域網,通過無線局域網到達我的手機C。

A的發送要構建一個幀,目的MAC地址為B1,目的IP為C。B則要開啟兩個網卡,B1監聽接收數據,B2網卡則要用ARP協議掃描所在無線局域網內的IP和MAC,B獲取到了A發來的幀之后,解析它的IP地址和MAC地址,匹配剛才掃描得到的IP和MAC相應表,將源MAC換成B2網卡MAC,目的MAC換成C的MAC,IP不變,數據data不變。構建新幀之后發送出去。

好啦,思路大體就是這樣。

須要三個程序,一個是發送,一個路由,一個接收。所以一共三個程序要同一時候執行起來執行。

以上是我的大體思路,如有錯誤,還請指正。現已用代碼實現完成。

代碼暫不公開,僅僅提供部分重點代碼解析:

一、發送端

事實上發送端和0基礎功能的發送差點兒相同

個人編寫的交互流程例如以下:

IP地址:121.250.216.221 MAC地址:3c970e4b56d6con:127------------------------------------------- IP地址:121.250.216.227 MAC地址:089e01b948f4con:128------------------------------------------- IP地址:121.250.216.228 MAC地址:10bf48705aeecon:129獲取MAC地址完成,請輸入你要發送對方的IP地址: 192.168.1.3 請輸入你要發送的內容: im cqc 要發送的內容:im cqc

詳細代碼不再解析,同上一篇0基礎功能。

二、路由端

首先要開啟兩個網卡,聲明兩個網卡對象和處理器

pcap_if_t *d,*d2; //選中的網絡適配器 pcap_t *adhandle,*adhandle2; //捕捉實例,是pcap_open返回的對象,adhandle是用來發送數據,adhandle2是用來接收數據

一個用來接收一個用來發送,這里定義了adhandle是用來發送,adhandle2是用來接收數據。

?那么打開適配器就在main方法中,提前打開兩個網卡

int num;printf("請輸入你要轉發數據的網卡代號:\n");//讓用戶選擇選擇哪個適配器進行轉發scanf_s("%d",&num);//跳轉到選中的適配器for(d=alldevs, i=0; i< num-1 ; d=d->next, i++);//執行到此處說明用戶的輸入是合法的,找到發送數據網卡if((adhandle = pcap_open(d->name, //設備名稱65535, //存放數據包的內容長度PCAP_OPENFLAG_PROMISCUOUS, //混雜模式1000, //超時時間NULL, //遠程驗證errbuf //錯誤緩沖)) == NULL){//打開適配器失敗,打印錯誤并釋放適配器列表fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n", d->name);// 釋放設備列表 pcap_freealldevs(alldevs);return -1;}int num2;printf("請輸入你要接收數據的網卡代號:");//讓用戶選擇用哪個網卡來收數據scanf_s("%d",&num2);//用戶輸入的數字超出合理范圍//跳轉到選中的適配器for(d2=alldevs, i=0; i< num2-1 ; d2=d2->next, i++);//執行到此處說明用戶的輸入是合法的if((adhandle2 = pcap_open(d2->name, //設備名稱65535, //存放數據包的內容長度PCAP_OPENFLAG_PROMISCUOUS, //混雜模式1000, //超時時間NULL, //遠程驗證errbuf //錯誤緩沖)) == NULL){//打開適配器失敗,打印錯誤并釋放適配器列表fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n", d2->name);

接下來用用于發送的handle處理器來掃描它的局域網IP,獲得局域網內的MAC地址,記錄在一個表中,存放IP和MAC的相應關系。

這個表能夠用結構體數組來保存,比方能夠這樣:

struct ip_mac_list{IpAddress ip;unsigned char mac[6]; };ip_mac_list list[256]; //存儲IP和MAC地址的相應表

那么以上便是準備工作,我們完畢了兩個網卡的打開,發送網卡掃描獲取局域網MAC,接下來便是最重要的監聽加轉發。

那么這個怎辦?那就開一個新線程。

讓我們聲明一個新的路由線程。

?

DWORD WINAPI RouteThread(LPVOID lpParameter);

那么線程要接收進來什么參數呢?

首先必需要的是兩個網卡處理器,在main方法中已經做好初始化的adhandle和adhandle2,另外還有alldevs,能夠持有這個指針來釋放設備列表,出現錯誤時釋放資源并退出。

0基礎功能中聲明過了

struct sparam sp;
struct gparam gp;

這兩個就是發送ARP線程和接收ARP線程中的兩個參數,那么仿照這個功能,我們定義一個新的結構體

struct rparam{pcap_t *adhandle_rec;pcap_t *adhandle_send;pcap_if_t * alldevs; //全部網絡適配器 };

在main方法中把它來初始化賦值

?

rp.adhandle_send = adhandle;rp.adhandle_rec = adhandle2;rp.alldevs = alldevs;

當做參數傳入這個線程

?

routethread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) RouteThread, &rp,0, NULL);

當中第四個參數就是傳遞了這個結構體進去。注意這個語句最好不要直接放在main方法中直接調用,能夠在所有獲取完MAC地址之后再開啟這個線程。

那么接下來就說一下這個線程都干了些什么,僅僅簡略說一下核心部分。

首先開啟了這個線程之后會一直都在運行,那么就能夠增加

while((res = pcap_next_ex(adhandle2,&header,&pkt_data))>=0)

這種while推斷語句來一直監聽數據包的接收,然后解析數據。

?

ethernet = (EthernetHeader *)(pkt_data);for(int i=0;i<6;i++){sou_mac[i] = ethernet->SourMAC[i];}for(int i=0;i<6;i++){des_mac[i] = ethernet->DestMAC[i];}// 獲得IP數據包頭部的位置ip = (IpHeader *) (pkt_data +14); //14為以太網幀頭部長度//獲得TCP頭部的位置ip_len = (ip->Version_HLen & 0xf) *4;tcp = (TcpHeader *)((u_char *)ip+ip_len);data = (char *)((u_char *)tcp+20);printf("data:%s\n",data);printf("ip:");printf("%d.%d.%d.%d -> %d.%d.%d.%d\n",ip->SourceAddr.byte1,ip->SourceAddr.byte2,ip->SourceAddr.byte3,ip->SourceAddr.byte4,ip->DestinationAddr.byte1,ip->DestinationAddr.byte2,ip->DestinationAddr.byte3,ip->DestinationAddr.byte4);printf("sou_mac:%02x-%02x-%02x-%02x-%02x-%02x\n", sou_mac[0], sou_mac[1], sou_mac[2],sou_mac[3], sou_mac[4], sou_mac[5]);printf("des_mac:%02x-%02x-%02x-%02x-%02x-%02x\n", des_mac[0], des_mac[1], des_mac[2],des_mac[3], des_mac[4], des_mac[5]);


然后接下來每接收到一個數據,就進行構建新的幀轉發出去,目的MAC先匹配list表,假設list沒有找到,那么我讓他指定了一個mac,比方廣播MAC。源MAC地址則賦值網卡的MAC地址。

注意,傳統以太網中數據長度為45-1500,那么我在構建前把解析出的data作了下推斷長度再構建,由于我已經把sendbuffer聲明為一個固定長度了,為了防止越界,我先進行一個長度推斷。

//下面開始構建幀發送//首先推斷data最大值小于1500if(strlen(data)<1500){//目的MACBYTE send_destmac[6];bool findMac = false;for(int c = 0;c<con;c++){if(ip->DestinationAddr.byte1 == list[c].ip.byte1&&ip->DestinationAddr.byte2 == list[c].ip.byte2&&ip->DestinationAddr.byte3 == list[c].ip.byte3&&ip->DestinationAddr.byte4 == list[c].ip.byte4){printf("Find its MAC!\n");findMac = true;send_destmac[0] = list[c].mac[0]; send_destmac[1] = list[c].mac[1];send_destmac[2] = list[c].mac[2];send_destmac[3] = list[c].mac[3];send_destmac[4] = list[c].mac[4];send_destmac[5] = list[c].mac[5];}}if(!findMac){send_destmac[0] = 0xff; send_destmac[1] = 0xff; send_destmac[2] = 0xff; send_destmac[3] = 0xff; send_destmac[4] = 0xff; send_destmac[5] = 0xff; }printf("destmac:%02x-%02x-%02x-%02x-%02x-%02x\n",send_destmac[0],send_destmac[1],send_destmac[2],send_destmac[3],send_destmac[4],send_destmac[5]);memcpy(send_ethernet.DestMAC, send_destmac, 6);//源MAC地址BYTE send_hostmac[6];//源MAC地址send_hostmac[0] = local_mac[0]; //賦值本地MAC地址send_hostmac[1] = local_mac[1];send_hostmac[2] = local_mac[2];send_hostmac[3] = local_mac[3];send_hostmac[4] = local_mac[4];send_hostmac[5] = local_mac[5];//賦值源MAC地址memcpy(send_ethernet.SourMAC, send_hostmac, 6);send_ethernet.EthType = htons(0x0800);//賦值SendBuffermemcpy(&SendBuffer, &send_ethernet, sizeof(struct EthernetHeader));

以上僅僅是賦值了幀頭,至于IP頭,TCP頭,數據的賦值就參照0基礎功能的來賦值吧,不要忘了校驗和的檢驗。好,大體上就是這樣,接受來數據包并轉發出去的原理就是這樣。

三、接收

不用多改,就是0基礎功能中的接收,在此寫一寫小小的優化措施,防止接收到過多的數據幀而造成不斷亂蹦,導致你看不到接收的東西。

在打印的時候加一個過濾就好了。部分代碼例如以下:

在main方法中提示用戶輸入要接收的IP地址

printf("請輸入要接收的IP地址,輸入0.0.0.0代表所有接收,請輸入\n");bool receiveAll = false;u_int ip1,ip2,ip3,ip4;bool legal = false;while(!legal){scanf_s("%d.%d.%d.%d",&ip1,&ip2,&ip3,&ip4);if(ip1==0&&ip2==0&&ip3==0&&ip4==0){receiveAll = true;legal = true;break;}if(ip1<0||ip1>255||ip2<0||ip2>255||ip3<0||ip3>255||ip4<1||ip4>254){legal = false;printf("對不起,IP輸入不合法,請又一次輸入:\n");}else{legal = true;}}

打印時的推斷

if(receiveAll||(ip->SourceAddr.byte1==ip1&&ip->SourceAddr.byte2==ip2&&ip->SourceAddr.byte3==ip3&&ip->SourceAddr.byte4==ip4)){printf("%d.%d.%d.%d.%d -> %d.%d.%d.%d.%d\n",ip->SourceAddr.byte1,ip->SourceAddr.byte2,ip->SourceAddr.byte3,ip->SourceAddr.byte4,sport,ip->DestinationAddr.byte1,ip->DestinationAddr.byte2,ip->DestinationAddr.byte3,ip->DestinationAddr.byte4,dport);printf("sou_mac:%02x-%02x-%02x-%02x-%02x-%02x\n", sou_mac[0], sou_mac[1], sou_mac[2],sou_mac[3], sou_mac[4], sou_mac[5]);printf("des_mac:%02x-%02x-%02x-%02x-%02x-%02x\n", des_mac[0], des_mac[1], des_mac[2],des_mac[3], des_mac[4], des_mac[5]);printf("%s\n",data);printf("-----------------------------------------------------\n");}


?好,代碼就先放送這么多,詳細的實現僅僅要有了思路我相信肯定不難,如有問題,歡迎與我交流。

我的郵箱 1016903103@qq.com?




轉載于:https://www.cnblogs.com/mfrbuaa/p/4060226.html

總結

以上是生活随笔為你收集整理的Winpcap网络编程十之Winpcap实战,两台主机通过中间主机通信的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 中文字幕+乱码+中文字幕明步 | 欧美黑人一级爽快片淫片高清 | 风韵少妇性饥渴推油按摩视频 | 亚洲黄色在线看 | 在线中文字幕第一页 | 手机av免费在线观看 | 在线看的免费网站 | 亚洲综合精品国产一区二区三区 | 日批视频在线免费看 | 国产影视一区二区 | 9i看片成人免费高清 | 欧美一区二区三区在线看 | aaa国产视频 | 长篇高h肉爽文丝袜 | 成人午夜视频网站 | 欧美日本综合 | 国产一级片免费在线观看 | 日韩精品人妻中文字幕有码 | 午夜精品剧场 | jav中文字幕| 午夜精品一二三区 | 播色屋| 亚洲夜夜夜 | 中文字幕十一区 | 国产精品久久久久久亚洲毛片 | 欧美激情一区二区视频 | 91成人免费在线观看 | 销魂奶水汁系列小说 | 综合网在线观看 | 新呦u视频一区二区 | 午夜三级影院 | 黑人操欧美人 | 亚洲日本中文字幕 | 免费高清视频在线观看 | 黄色天堂 | 色婷婷av一区二区三区软件 | 久久天堂av综合合色蜜桃网 | 黄色网址你懂得 | 91久久久久一区二区 | 欧美色图一区二区 | 黄视频网站免费看 | 日韩在线观看视频一区 | 古代黄色片 | 蜜桃av乱码一区二区三区 | 欧美中文在线观看 | 日本综合久久 | 国产伦精品一区二区三区视频孕妇 | 欧美日韩中文字幕在线视频 | 久久无码人妻丰满熟妇区毛片 | www黄色在线观看 | 蜜芽一区二区 | 亚洲色图视频在线观看 | 秋霞99| 亚洲va久久久噜噜噜久久天堂 | 国产最新精品视频 | 禁欲天堂 | 黄色一几片| 成人一区二区视频 | 日韩人妻一区二区三区蜜桃视频 | 阿拉伯性视频xxxx | 久久精品无码一区 | 日本h视频在线观看 | 亚洲www视频 | 国产乱人乱精一区二视频国产精品 | 性插插视频 | 91tv在线观看| 天天干夜夜怕 | 午夜爱爱毛片xxxx视频免费看 | 91av成人| 在线少妇 | 国产美女激情视频 | 日韩女人性猛交 | 精品国产乱码久久久久久蜜臀网站 | 成人激情四射网 | 欧美极品少妇xxxxⅹ喷水 | 国产日韩精品久久 | 久久精品日韩无码 | 小宵虎南在线观看 | 男女黄网站 | 91精东传媒理伦片在线观看 | 亚洲无码一区二区三区 | 日韩精品在线免费视频 | 日韩欧美二区 | 国产人妖av | 高跟鞋肉丝交足91 | 国产精品99久久久精品无码 | brazzers精品成人一区 | 亚洲精品动漫在线观看 | 曰批女人视频在线观看 | 日韩欧美中文在线观看 | 成人在线免费视频观看 | 伊人青青草视频 | 91视频免费观看 | 日韩少妇内射免费播放18禁裸乳 | 久久久久久久久99精品 | 国产麻豆午夜三级精品 | 欧美精品日韩少妇 | 国产强被迫伦姧在线观看无码 | 中文字幕日韩三级 |