通过无线网卡在数据链路层进行通信
两台如何能够绕过 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);
}