Dirk
Dirk

Reputation: 21

Packet Sniffer under Linux in C/C++

I try to capture network pakets with a raw socket under 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:

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

Upvotes: 2

Views: 10705

Answers (2)

thuovila
thuovila

Reputation: 2030

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. Search for IFF_PROMISC (old kernels) and PACKET_MR_PROMISC (the new fancier/more complicated way).

Upvotes: 2

abligh
abligh

Reputation: 25199

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 is what tcpdump and wireshark use under the hood.

Upvotes: 5

Related Questions