本文主要是介绍linux RAW SOCKET加Packet af定制2层报文,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
前几天做了一个feature,使用raw socket加AF_PACKET。选择了一部分,修改了下,变成一个简单的例子,分享出来。用这个只要你能接入网络,你想发什么就发什么,别干坏事就好:-)。AF_PACKET和AF_INET区别就是一个可以脱光到2层,一个只能到3层。直接把代码贴出来,希望感兴趣的人可以参考。
客户端:
#include <stdio.h> #include<errno.h> #include<stdlib.h> #include<unistd.h> #include<sys/types.h> #include<sys/socket.h> #include<netinet/in.h> #include<netdb.h> #include<linux/if.h> #include<linux/if_packet.h> #include<linux/sockios.h> #include<linux/if_ether.h> #include<string.h> struct socks { int fd; struct sockaddr_ll addr; } dp_socket[2]; int create_sockets( void ) { struct ifreq ifr; struct sockaddr_ll addr; int retval; int s; __u16 type; int dev, num_devs=2; type = htons(0x8d8d); for (dev = 0 ; dev <num_devs; ++dev) { type = htons(0x8d8d + dev); dp_socket[dev].fd = -1; s = socket (PF_PACKET, SOCK_RAW, type); if (s < 0) { return (s); } memset (( void *)&ifr, 0, sizeof (ifr)); snprintf (ifr.ifr_name, sizeof (ifr.ifr_name), "eth0" ); retval = ioctl (s, SIOCGIFINDEX, &ifr); if (retval < 0) { close (s); return (retval); } memset (&addr, 0, sizeof (addr)); addr.sll_family = AF_PACKET; addr.sll_ifindex = ifr.ifr_ifindex; addr.sll_protocol = type; retval = bind (s, ( struct sockaddr *) &addr, sizeof (addr)); if (retval < 0) { close (s); return (retval); } dp_socket[dev].fd = s; memset (&dp_socket[dev].addr, 0, sizeof (dp_socket[dev].addr)); dp_socket[dev].addr.sll_family = AF_PACKET; dp_socket[dev].addr.sll_ifindex = ifr.ifr_ifindex; dp_socket[dev].addr.sll_protocol = type; } return 0; } int main( void ) { fd_set rfd_set, wfd_set; int i; char rbuf[512]; int ret; char wbuf[512]; struct ethhdr *rhdr = ( struct ethhdr *)rbuf; struct ethhdr *whdr = ( struct ethhdr *)wbuf; FD_ZERO(&rfd_set); FD_ZERO(&wfd_set); create_sockets(); FD_SET(dp_socket[1].fd, &rfd_set); memset (wbuf + sizeof (*whdr), 0, 512 - sizeof (*whdr)); memcpy (wbuf + sizeof (*whdr), "coming" , 7); whdr->h_dest[0] = 0x00; whdr->h_dest[1] = 0x22; whdr->h_dest[2] = 0x68; whdr->h_dest[3] = 0x14; whdr->h_dest[4] = 0xe1; whdr->h_dest[5] = 0xb1; whdr->h_proto = htons(0x8d8d); rhdr->h_proto = htons(0x8d8e); while (1) { ret = write(dp_socket[0].fd, wbuf, 7 + sizeof (*whdr)); if (select(FD_SETSIZE, &rfd_set, NULL, NULL, NULL) < 0) { printf ( "select error\n" ); exit (-1); } memset (rbuf + sizeof (*rhdr), 0, 512 - sizeof (*rhdr)); if (FD_ISSET(dp_socket[1].fd, &rfd_set)) { ret = read(dp_socket[1].fd, rbuf, 512); if (ret > 0) { printf ( "%s\n" ,rbuf+ sizeof (*rhdr)); } ret = write(dp_socket[0].fd, wbuf, 7 + sizeof (*whdr)); if (ret <=0) { printf ( "error write\n" ); } sleep(1); } } return 0; } |
服务端:
#include <stdio.h> #include<errno.h> #include<stdlib.h> #include<unistd.h> #include<sys/types.h> #include<sys/socket.h> #include<netinet/in.h> #include<netdb.h> #include<linux/if.h> #include<linux/if_packet.h> #include<linux/if_ether.h> #include<linux/sockios.h> #include<string.h>struct socks {int fd;struct sockaddr_ll addr; } dp_socket[2];int create_sockets(void) {struct ifreq ifr;struct sockaddr_ll addr;int retval;int s;__u16 type;int dev, num_devs=2;type = htons(0x8d8d);for (dev = 0 ; dev < num_devs; ++dev) {type = htons(0x8d8d + dev);dp_socket[dev].fd = -1;s = socket (PF_PACKET, SOCK_RAW, type);if (s < 0) {return (s);}memset ((void*)&ifr, 0, sizeof (ifr));snprintf (ifr.ifr_name, sizeof (ifr.ifr_name), "eth0");retval = ioctl (s, SIOCGIFINDEX, &ifr);if (retval < 0) {close (s);return (retval);}memset (&addr, 0, sizeof (addr));addr.sll_family = AF_PACKET;addr.sll_ifindex = ifr.ifr_ifindex;addr.sll_protocol = type;retval = bind (s, (struct sockaddr *) &addr, sizeof (addr));if (retval < 0) {close (s);return (retval);}dp_socket[dev].fd = s;memset(&dp_socket[dev].addr, 0, sizeof(dp_socket[dev].addr));dp_socket[dev].addr.sll_family = AF_PACKET;dp_socket[dev].addr.sll_ifindex = ifr.ifr_ifindex;dp_socket[dev].addr.sll_protocol = type;}return 0; }int main(void) {fd_set rfd_set, wfd_set;int i;unsigned char rbuf[512];char wbuf[512];struct ethhdr *hdr = (struct ethhdr *)rbuf;struct ethhdr *whdr = (struct ethhdr *)wbuf;hdr->h_proto = htons(0x8d8d);whdr->h_proto = htons(0x8d8e);FD_ZERO(&rfd_set);FD_ZERO(&wfd_set);create_sockets();FD_SET(dp_socket[0].fd, &rfd_set);//FD_SET(dp_socket[1].fd, &wfd_set);while (1) {if (select(FD_SETSIZE, &rfd_set, NULL, NULL, NULL) < 0) {printf("select error\n");exit(-1);}memset(rbuf + sizeof(*hdr), 0, 512 - sizeof(*hdr));memset(wbuf + sizeof(*hdr), 0, 512 - sizeof(*hdr));memcpy(wbuf + sizeof(*hdr), "got it", 7);if(FD_ISSET(dp_socket[0].fd, &rfd_set)) {int ret;ret = read(dp_socket[0].fd, rbuf, 511);if (ret > 0) {//printf("%02x %02x %02x %02x %02x %02x\n",rbuf[0],rbuf[1],rbuf[2],rbuf[3], rbuf[4], rbuf[5]);printf("%s\n",rbuf + sizeof(*hdr));}ret = write(dp_socket[1].fd, wbuf, sizeof(*hdr) + 7);if (ret <=0) {printf("error write\n");}}}return 0; }
这篇关于linux RAW SOCKET加Packet af定制2层报文的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!