2014-01-24 3 views
1

Я пытаюсь захватить только пакеты из определенного интерфейса, и вместо этого я получаю пакеты со всех интерфейсов. Что я делаю не так?Sniffing интерфейс ethernet на linux

bool Snooper::raw_init (const char *device) 
{ 

uid_t privid = geteuid(); 
int  retval; 
bool  retVal = false; 

do { 
    if ((retval = setuid(0)) != 0) { 
     perror("seteuid error"); 
     break; 
    } 

    cap_t caps = cap_get_proc(); 
    cap_value_t cap_list[2]; 
    cap_list[0] = CAP_NET_RAW; 
    cap_list[1] = CAP_SETUID; 
    if ((retval = cap_set_flag(caps, CAP_EFFECTIVE, 2, cap_list, CAP_SET)) == -1) { 
     perror("cap_set_flag error"); 
     break; 
    } 
    if ((retval = cap_set_proc(caps)) == -1) { 
     perror("cap_set_proc error"); 
     break; 
    } 

    struct ifreq ifr; 
    memset(&ifr, 0, sizeof (struct ifreq)); 

    /* Open A Raw Socket */ 
    if ((m_sockfd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_ALL))) < 1) { 
     perror("Snooper::raw_init:socket Error"); 
     break; 
    } 

    /* Set the device to use */ 
    strncpy(ifr.ifr_name, device, strlen(device) + 1); 

    /* Get the current flags that the device might have */ 
    if (ioctl(m_sockfd, SIOCGIFFLAGS, &ifr) == -1) { 
     perror("Error: Could not retrieve the flags from the device.\n"); 
     break; 
    } 

    printf("The interface is ::: %s\n", device); 
    perror("Retrieved flags from interface successfully"); 

    /* Set the old flags plus the IFF_PROMISC flag */ 
    ifr.ifr_flags |= IFF_PROMISC; 
    if (ioctl(m_sockfd, SIOCSIFFLAGS, &ifr) == -1) { 
     perror("Error: Could not set flag IFF_PROMISC"); 
     break; 
    } 
    printf("Setting interface ::: %s ::: to promisc\n", device); 

    /* Configure the device */ 
    if (ioctl(m_sockfd, SIOCGIFINDEX, &ifr) < 0) { 
     perror("Error: Error getting the device index.\n"); 
     break; 
    } 
    retVal = true; 
} while(false); 

if ((retval = seteuid(privid)) != 0) { 
    perror("seteuid error"); 
} 
return retVal; 
} 

Прежде всего, подтвердите, что я могу доверять root, так как это требует IFF_PROMISC. Затем создайте сокет для трафика UDP, заготовьте IOCtl для устройства и, наконец, IOCtl для PROMISC.

Теперь, когда у меня есть готовый сокет, я петлю на recv, однако я также получаю пакеты от других интерфейсов.

+0

Благодаря @Vlad Лазаренко сейчас работает. Я думал, что это будет привязка, однако ни один из других примеров, найденных в других местах, никогда не использовался bind, и поэтому он был опущен. Как кто-либо еще хочет выполнять однотипную задачу. После компиляции. chown root exe, затем chmod a + s exe. Хотя вы должны иметь права root для выполнения любого действия. –

ответ

1

Чтобы захватить пакеты с определенного интерфейса, вам необходимо привязать ваш сокет к этому интерфейсу с помощью функции bind. Вы можете посмотреть, например, this answer.

0

Небольшая pcap программа, которая может быть в состоянии помочь Вам

#include<stdio.h> 
#include<stdlib.h> 
#include<string.h> 
#include<pcap/pcap.h> 
#include<netinet/if_ether.h> 
#include<netinet/ip.h> 
#include<netinet/tcp.h> 

void process_packet(u_char *args, const struct pcap_pkthdr *header, 
           const u_char *buffer) 
{ 
// printf("In Process_Packet\n"); 
struct ethhdr *eth = (struct ethhdr *)(buffer); 

printf("%.2x: %.2x: %.2x: %.2x: %.2x: %.2x: %.2x:\n ", eth->h_dest[0], eth->h_dest[1], eth->h_dest[2], eth->h_dest[3], eth->h_dest[4], eth->h_dest[5], eth->h_dest[6]); 

printf("%x \n", htons(eth->h_proto)); 

if(htons(eth->h_proto)== ETHERTYPE_ARP) 
{ 
    printf("ARP PACKET\n"); 
} 

struct iphdr *iph = (struct iphdr*)(buffer + sizeof(struct ethhdr)); 

int ipheader = iph-> ihl *4; 

printf("Source IP Address :%s\n ", inet_ntoa(iph->saddr)); 

printf("Destination IP Address :%s\n ", inet_ntoa(iph->daddr)); 
} 
int main() 
{ 
pcap_if_t *alldevspec,*devices; 
pcap_addr_t *a; 
pcap_t *handle; 
const char filter_exp[]="IP"; 
bpf_u_int32 netp; 
char errbuf[PCAP_ERRBUF_SIZE]; 
struct bpf_program fp; 
int ret=0, count =1, n=0; 
char devs[100][100],*devicename; 

ret = pcap_findalldevs(&alldevspec,errbuf); 

if(ret < 0) 
{ 
    printf("Error in finding the devices\n"); 
    return -1; 
} 

for(devices = alldevspec; devices!= NULL; devices = devices->next) 
{ 
    printf("%d %s-%s \n",count, devices->name,devices->description); 

    for(a=devices->addresses;a;a=a->next) 
    { 
     printf("family %d \n", (a->addr)->sa_family); 

     if(devices->name != NULL) 
     { 
      strcpy(devs[count], devices->name); 
     } 

     switch((a->addr)->sa_family) 
     { 
      case AF_INET: 
      printf("%s \n",inet_ntoa(((struct sockaddr_in*)a->addr)->sin_addr.s_addr)); 
      break; 

      case AF_INET6: 
      break; 
     } 
    } 
++count; 
} 

printf("Enter the device u want to select\n"); 
scanf("%d",&n); 
devicename = devs[n]; 

handle = pcap_open_live(devicename,65536,1,-1,errbuf); 

if(handle == NULL) 
{ 
    printf("Error in opening the device\n"); 
    return -1; 
} 

pcap_compile(handle,&fp, filter_exp,-1,netp); 
pcap_setfilter(handle, &fp); 
pcap_loop(handle,-1,process_packet,NULL); 

return 0; 
} 
Смежные вопросы