linux基礎編程 鏈路層socket 擺脫winPcap 誇網段socket通訊 可誇平台移植__區塊鏈

來源:互聯網
上載者:User
在linux環境中要從鏈路層(MAC)直接收發資料幀,可以通過libpcap與libnet兩個動態庫來分別完成收與發的工作。雖然它已被廣泛使用,但在要求進行跨平台移植的軟體中使用就很難辦到了。。

這是一種更為直接地、無須安裝其它庫的從MAC層收發資料幀的方式,即通過定義鏈路層的通訊端來完成。

下面的代碼也是我做的項目中的代碼(誇網段訪問網路中的嵌入式裝置),去掉了敏感部分,和大家共用。

但是得尊重別人的勞動成果,轉載註明出處,謝謝。

#include <string.h>         #include <stdio.h>          #include <unistd.h>#include <stdlib.h>#include <errno.h> #include <pthread.h>#include <sys/types.h>      #include <sys/socket.h>      #include <sys/ioctl.h>       #include <net/if.h>         #include <linux/if_packet.h>#include <arpa/inet.h>/*鏈路層socket接收埠*/#define RAW_PROTOCOL 0x0909#define ETH_NAME "eth0"#define __DEBUG#ifdef __DEBUG#define DBG(fmt,args...) fprintf(stdout,  fmt,  ##args)#else#define DBG(fmt,args...)#endif#define ERR(fmt,args...) fprintf(stderr,  fmt,  ##args)static int raw_fd;static int if_index;static int isSearchQuit = 0;unsigned char my_mac[6];/*用於本機儲存網卡地址*//*接收鏈路層資料包*/int GetPacket(unsigned char *buf, int *len){int length = 0;length = recvfrom( raw_fd, buf, 2000, 0, NULL, NULL );if ( length < 0 ){ERR("failed to receive buf!");return -1;}else{*len = length;return 0;}}/*發送鏈路層資料包*/int SendPacket(unsigned char *buf, int len){struct sockaddr_ll link;link.sll_ifindex = if_index;memcpy( link.sll_addr, buf, link.sll_halen );if ( sendto( raw_fd, buf, len, 0, (struct sockaddr *)&link, sizeof(link) ) < 0 ){ERR( "failed to send to RAW socket!\r\n" );return -1;}return 0;}void ShowData(unsigned char *d1,int len){int i;for(i=0;i<len;i++)printf("%02x ",d1[i]);printf("\n\r");}void *RawSocketThread(void *arg){unsigned char rcvPackage[70];unsigned char sndPackage[70];int len;int curStatus = 0;while(1){int ret = 0;int done = 0;ret = GetPacket(rcvPackage,&len);//block hereif(ret == -1)break;ShowData(rcvPackage,len);sleep(1);ret = SendPacket(rcvPackage,len);if(ret ==-1)break;}pthread_exit(NULL);close(raw_fd);}int RawSocketInit(){pthread_t tRawSocketThr;struct ifreq req;/*建立鏈路層socket,注意PF_PACKET,SOCK_RAW,以及RAW_PROTOCOL(自訂的)*/if ( (raw_fd = socket(PF_PACKET, SOCK_RAW, htons( RAW_PROTOCOL ) ) ) < 0 ){ERR( "failed to create raw socket!\n" );return -1;}/*綁定網卡*/strcpy( req.ifr_name, ETH_NAME );if ( ioctl( raw_fd, SIOCGIFFLAGS, &req ) < 0 ){ERR( "failed to do ioctl!" );return -1;}/*設定工作模式*/req.ifr_flags |= IFF_PROMISC;if ( ioctl( raw_fd, SIOCSIFFLAGS, &req ) < 0 ){ERR( "failed to set eth0 into promisc mode!" );return -1;}if ( ioctl( raw_fd, SIOCGIFHWADDR, &req ) < 0 ){ERR( "failed to get interface hw address!" );return -1;}memcpy( my_mac, req.ifr_hwaddr.sa_data, sizeof(my_mac) );if ( ioctl( raw_fd, SIOCGIFINDEX, &req ) < 0 ){ERR( "failed to get interface index!" );return -1;}if_index = req.ifr_ifindex;if(pthread_create(&tRawSocketThr,NULL,RawSocketThread,NULL) == -1){ERR("ERROR in RawSocketThread\n");return -1;}pthread_detach(tIPNCSearchThr);return 0;}#if 1int main(){int count =0;RawSocketInit();while(1){sleep(1);}}#endif 

運行結果,接收自網路中的完整資料包:

[root@localhost src]# ./RawSocketff ff ff ff ff ff 1c 6f 65 dc fa fb 09 09 00 00 00 00 06 04 01 00 00 00 00 00 00 00 c0 a8 01 dc ff ff ff ff ff ff c0 a8 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 



相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.