Packet Sniffer под Linux в C / Stack Overflow

Я пытаюсь захватить сетевой пакет с необработанным сокетом под Linux.
Это иногда работает. Кажется, я могу запечатлеть некоторые разговоры, но не все.

Я создаю сокет:

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

затем я связываю его с 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));

тогда я пытаюсь получить:

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

Я могу перехватить некоторые пакеты в сети, но не все.
Кажется, я скучаю по целым разговорам между двумя сторонами.

У кого-нибудь есть идея, что я делаю не так?

заранее спасибо

кортик

1

Решение

Если это не какое-то домашнее задание или мазохизм, я настоятельно рекомендую вам использовать libpcap который предоставит портативный способ решения этой проблемы, которая была испытана до смерти. libpcap это что tcpdump а также wireshark использовать под капотом.

4

Другие решения

Если под «целыми разговорами между двумя сторонами» вы подразумеваете хосты, отличные от того, на котором выполняется ваш код, вам необходимо установить интерфейс в беспорядочный режим.

Говоря о libpcapХорошее место, чтобы увидеть, как включить неразборчивый режим, это PCAP-linux.c в libpcap источники. Ищи IFF_PROMISC (старые ядра) и PACKET_MR_PROMISC (новый любитель / более сложный способ).

2

По вопросам рекламы [email protected]