通过无线网卡在数据链路层进行通信

通过无线网卡在数据链路层进行通信

 

 

两台如何能够绕过 tcp/ip 进行通信呢?答案就是使用 raw 套接字,即原始套接字。

 

下面给出源码,分为 server 端和 client 端。

 

 

server

 

#include"stdio.h"

#include"string.h"

#include"unistd.h"

#include"sys/socket.h"

#include"netpacket/packet.h"

#include"linux/if_ether.h"

#include"sys/ioctl.h"

#include"net/if.h"  

int get_iface_index(int fd, const char* interface_name)

{

struct ifreq ifr;  

memset(&ifr, 0, sizeof(ifr));

strcpy (ifr.ifr_name,interface_name);  

if (ioctl(fd, SIOCGIFINDEX, &ifr) == -1)

{ return (-1); }  

return ifr.ifr_ifindex;

}  

int main()

{

int s;

unsigned char msg[]="hello th";  

int n;

struct sockaddr_ll addr;

int socklen;  

s = socket(AF_PACKET,SOCK_RAW,htons(ETH_P_ALL));  

memset(&addr,0,sizeof(addr));

addr.sll_family = AF_PACKET;

addr.sll_ifindex = get_iface_index(s,"ath0");

addr.sll_protocol = htons(ETH_P_ALL);

addr.sll_halen = 6;

addr.sll_pkttype    = PACKET_OUTGOING;  

while(1){

printf("%s/n",msg);

n = sendto(s,msg,10,0,(struct sockaddr *)&addr,sizeof(addr));

printf("%d bytes written./n",n);

}

close(s);

}

 

 

 

client

 

client 端需要注意的是,需要将网卡设为混杂模式才能够接收到不是专门发 给它的数据,将网卡设为混在模式和将网卡退出混杂模式的函数在下面的代码中都给出了。

 

#include"stdio.h"

#include"string.h"

#include"unistd.h"

#include"sys/socket.h"

#include"netpacket/packet.h"

#include"linux/if_ether.h"

#include"sys/ioctl.h"

#include"net/if.h"  

int get_iface_index(int fd, const char* interface_name)

{

struct ifreq ifr;  

memset(&ifr, 0, sizeof(ifr));

strcpy (ifr.ifr_name,interface_name);  

if (ioctl(fd, SIOCGIFINDEX, &ifr) == -1)

{ return (-1); }

return ifr.ifr_ifindex;

}  

int set_promisc(int f, char *i_name)

{

         struct    ifreq    ifr;

        int s=0;  

         strcpy(ifr.ifr_name, i_name);

         if    ((s = ioctl(f, SIOCGIFFLAGS, &ifr)) < 0)

         {          close(f);     return -1;        }

         ifr.ifr_flags |= IFF_PROMISC;

        if    ((s = ioctl(f, SIOCSIFFLAGS, &ifr)) < 0)  

         {        return(-1);         }

        return 1;

}

 

int unset_promisc(int f, char *i_name)

{

         struct    ifreq    ifr;

          int s=0;  

         strcpy(ifr.ifr_name, i_name);

         if    ((s = ioctl(f, SIOCGIFFLAGS, &ifr)) < 0)

         {         close(f);    return -1;         }

        ifr.ifr_flags &=~ IFF_PROMISC;

 

               if    ((s = ioctl(f, SIOCSIFFLAGS, &ifr)) < 0)  

               {           return(-1);          }

             return 1;

}

 

int main()

{

int s;

unsigned char msg[10]="asdasdaasd";  

int n;

struct sockaddr_ll addr;

int socklen;  

s = socket(AF_PACKET,SOCK_RAW,htons(ETH_P_ALL));

memset(&addr,0,sizeof(addr));

addr.sll_family = AF_PACKET;

addr.sll_ifindex = get_iface_index(s,"ath0");

addr.sll_protocol = htons(ETH_P_ALL);

addr.sll_halen = 6;  

int u=set_promisc(s,"ath0");    

bind(s,(struct sockaddr *)&addr,sizeof(addr));  

while(1){

n = recvfrom(s,msg,10,0,(struct sockaddr *)&addr,&socklen);

printf("%s/n",msg);

printf("%d bytes read from : ",n);

printf("%2X:%2X:%2X:%2X:%2X:%2X/n",addr.sll_addr[0],/

addr.sll_addr[1],addr.sll_addr[2],/

addr.sll_addr[3],addr.sll_addr[4],/

addr.sll_addr[5]);  

}

close(s);

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值