简体   繁体   English

C / C ++中Linux下的Packet Sniffer

[英]Packet Sniffer under Linux in C/C++

I try to capture network pakets with a raw socket under linux.. 我尝试在Linux下使用原始套接字捕获网络包。
This sometimes works. 这有时可行。 It seems that I can capture some of the conversations, but not all. 看来我可以捕捉到部分对话,但不能全部捕捉。

I create a socket: 我创建一个套接字:

sock = socket( PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));  

then I bind it to eth0 by: 然后我通过以下方式将其绑定到eth0:

struct sockaddr_ll sll;
struct ifreq ifr;

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

strcpy( ifr.ifr_name, "eth0");

if(( ioctl( sock, SIOCGIFINDEX, &ifr))==-1)
{
   printf( "error\n");
   return(-1);
}
sll.sll_family = AF_PACKET;
sll.sll_ifindex = ifr.ifr_ifindex;
sll.sll_protocol = htons( ETH_P_ALL);

bind( sock, (struct sockaddr*)&sll, sizeof( sll));

then I try to receive: 然后我尝试接收:

int packetsize = 65535;
char packet[packetsize];

struct ether_header *eth = (struct ether_header *) packet;
struct iphdr *ip = (struct iphdr *) (packet + sizeof(struct ether_header));

struct tcphdr *tcp = (struct tcphdr*) (packet+sizeof( struct ether_header)+sizeof( struct iphdr));
struct udphdr *udp = (struct udphdr*) (packet+sizeof( struct ether_header)+sizeof( struct iphdr));



int k;

while(1)
{
    k = read( sock, packet, sizeof( packet));

    if( k>0)
    {
        if( ntohs( eth-> ether_type) == 0x0800)
        {       
            inet_ntop( AF_INET, &ip->saddr, source, 16);
            inet_ntop( AF_INET, &ip->daddr, dest, 16);

            switch (ip->protocol)
            {
            case 6://TCP
                printf( "TCP: %s:%d -> %s:%d\n", source, ntohs( tcp->source), dest, ntohs( tcp->dest));
                break;
            case 17://UDP
                printf( "UDP: %s:%d -> %s:%d\n", source, ntohs( udp->source), dest, ntohs( udp->dest));
                break;
            default:
                break;
            }//switch           
        }// if 0x800    
    }//if( k>0)
}//while

I can capture some of the packets in the network, but not all. 我可以捕获网络中的某些数据包,但不是全部。 It seems that I miss whole conversations between two parties. 看来我很想念两方之间的整个对话。

Does anybody have an idea, what I do wrong? 有人知道我做错了什么吗?

Thanks in advance 提前致谢

Dirk 短剑

Unless this is some sort of homework exercise or an exercise in masochism, I strongly suggest you use libpcap which which will provide a portable way of solving this problem that has been tested to death. 除非这是某种家庭作业练习或受虐狂练习,否则我强烈建议您使用libpcap ,它会提供一种可移植的方式来解决已被测试杀死的问题。 libpcap is what tcpdump and wireshark use under the hood. libpcaptcpdumpwiresharkwireshark使用的东西。

If by "whole conversations between two parties" you mean hosts other than the one running your code, you need to set the interface into promiscuous mode. 如果通过“两方之间的整个对话”来表示主机而不是运行代码的主机,则需要将接口设置为混杂模式。

Speaking of libpcap , a good place to see how to enable promiscuous mode, is pcap-linux.c in the libpcap sources. 说到libpcap ,在libpcap源码中的pcap-linux.c是查看如何启用混杂模式的好地方。 Search for IFF_PROMISC (old kernels) and PACKET_MR_PROMISC (the new fancier/more complicated way). 搜索IFF_PROMISC (旧内核)和PACKET_MR_PROMISC (新的,更复杂的方法)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM