处于一些目的,有时需要对到达网口的所有网络数据进行捕获,系统也提供了这样的接口,稍微懂网络编程的都知道SOCK_DGRAM、SOCK_STREAM,差不多就UDP、TCP之类的吧。但是还有一个很少用的叫SOCK_RAW,原始套接字,使用它你可以捕获网卡上的所有网络数据,当然这需要超级用户权限。贴个列子吧,网上摘的,具体出处忘了
#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;
}
#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; }