Linux网络数据捕获之原始套接字
2012-08-11 16:39
363 查看
处于一些目的,有时需要对到达网口的所有网络数据进行捕获,系统也提供了这样的接口,稍微懂网络编程的都知道SOCK_DGRAM、SOCK_STREAM,差不多就UDP、TCP之类的吧。但是还有一个很少用的叫SOCK_RAW,原始套接字,使用它你可以捕获网卡上的所有网络数据,当然这需要超级用户权限。贴个列子吧,网上摘的,具体出处忘了
其实原始套接字不仅可以捕获数据,也可以发送数据,而且是任意格式的数据,从MAC头到IP头之类的数据段都在自己的控制范围之内,什么ARP攻击、DDoS攻击之类的都离不开原始套接字吧,不过这些封包是重点,这里篇幅有限不涉及封包了吧,只介绍如何将数据发出去
#include <stdio.h> #include <unistd.h> #include <string.h> #include <sys/socket.h> #include <sys/types.h> #include <linux/if_ether.h> #include <linux/in.h> #include <linux/if.h> #include <linux/sockios.h> #include <sys/socket.h> #include <netpacket/packet.h> #include <net/ethernet.h> /* the L2 protocols */ #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #define BUFFER_MAX 2048 int main(int argc, char *argv[]) { int sock, n_read; char buffer[BUFFER_MAX]; struct sockaddr_ll sll; struct ifreq ifstruct; if((sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) < 0) { perror( "create socket error"); return -1; } memset(&sll, 0, sizeof(sll)); sll.sll_family = PF_PACKET; sll.sll_protocol = htons(ETH_P_ALL); //get net card index ethx->index strcpy(ifstruct.ifr_name, "eth0"); ioctl(sock, SIOCGIFINDEX, &ifstruct); sll.sll_ifindex = ifstruct.ifr_ifindex; //bind net card if (bind(sock, (struct sockaddr *)&sll, sizeof(sll)) == -1) { perror("bind error:\n"); return -1; } while(1) { n_read = recvfrom(sock, buffer, 2048, 0, NULL, NULL); if(n_read <= 0) { perror("recvfrom\n"); return -1; } //process packet } return 0; }
其实原始套接字不仅可以捕获数据,也可以发送数据,而且是任意格式的数据,从MAC头到IP头之类的数据段都在自己的控制范围之内,什么ARP攻击、DDoS攻击之类的都离不开原始套接字吧,不过这些封包是重点,这里篇幅有限不涉及封包了吧,只介绍如何将数据发出去
#include <stdio.h> #include <unistd.h> #include <string.h> #include <sys/socket.h> #include <sys/types.h> #include <linux/if_ether.h> #include <linux/in.h> #include <linux/if.h> #include <linux/sockios.h> #include <sys/socket.h> #include <netpacket/packet.h> #include <net/ethernet.h> /* the L2 protocols */ #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #define BUFFER_MAX 2048 int main(int argc, char *argv[]) { int sockfd; int n_write; int n_res; struct sockaddr_ll sll; struct ifreq ifstruct; char buffer[BUFFER_MAX]; char MAC_BUFFER[ETH_ALEN]= {0x00,0x18,0x82,0xab,0xd2,0xf9}; char TYPE_BUFFER[2] = {0x88,0x66}; if((sockfd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) < 0) { perror("create socket error:"); return -1; } n_res = 0; n_write = 0; memset(&sll, 0, sizeof(sll)); sll.sll_family = PF_PACKET; sll.sll_protocol = htons(ETH_P_ALL); //get netcard interface index ethx->ifindex strcpy(ifstruct.ifr_name, "eth0"); ioctl(sockfd, SIOCGIFINDEX, &ifstruct); sll.sll_ifindex = ifstruct.ifr_ifindex; //get the local netcard mac strcpy(ifstruct.ifr_name, "eth0"); ioctl(sockfd, SIOCGIFHWADDR, &ifstruct); memcpy(sll.sll_addr, ifstruct.ifr_ifru.ifru_hwaddr.sa_data, ETH_ALEN); sll.sll_halen = ETH_ALEN; //bind the netcard if(bind(sockfd, (struct sockaddr *)&sll, sizeof(sll)) == -1) { perror("bind error:"); return -1; } //get the netcard work mode memset(&ifstruct, 0, sizeof(ifstruct)); strcpy(ifstruct.ifr_name, "eth0"); if(ioctl(sockfd, SIOCGIFFLAGS, &ifstruct) == -1) { perror("iotcl error:"); return -1; } //set the netcard work mode ifstruct.ifr_flags |= IFF_PROMISC; if(ioctl(sockfd, SIOCSIFFLAGS, &ifstruct) == -1) { perror("iotcl()\n"); printf("Fun:%s Line:%d\n", __func__, __LINE__); return -1; } memcpy(buffer,MAC_BUFFER,ETH_ALEN); memcpy(buffer+6,sll.sll_addr,ETH_ALEN); memcpy(buffer+12,TYPE_BUFFER,2); while(1) { n_res = sendto(sockfd, buffer, 1024, 0, (struct sockaddr *)&sll, sizeof(sll)); if(n_res < 0) { perror("sendto error:"); return -1; } n_write += n_res; if(n_write >= 2048 * 2560) { break; } } return 0; }
相关文章推荐
- 以原始套接字方式对网络数据进行捕获(转)
- 以原始套接字方式对网络数据进行捕获
- Linux网络编程:原始套接字的魔力【续】
- Linux网络编程:原始套接字的魔力【上】
- 【Linux网络编程】原始套接字实例:MAC 头部报文分析
- Linux网络编程--10. 原始套接字 --11. 后记
- 利用原始套接字实现一个简单的采集网络数据包
- Linux网络编程:原始套接字编程及实例分析(二)
- Linux网络编程:原始套接字的魔力【上】
- Linux网络编程:原始套接字的魔力【上】
- 【Linux网络编程】原始套接字实例:MAC 地址扫描器
- Linux网络编程:原始套接字的魔力【上】
- Linux网络编程:原始套接字的魔力【下】
- Linux 网络编程之原始套接字
- linux实现抓包 (使用原始套接字数据连路层协议)
- Linux网络编程:原始套接字的魔力【上】
- Linux网络编程:原始套接字的魔力【续】
- Linux网络编程:原始套接字的魔力【续】
- Linux网络编程: 原始套接字
- Linux网络编程之原始套接字-ping协议实现