Raw prise avec un appareil lier à l'aide d'setsockopt() ne fonctionne pas sous Fedora core 6(2.6.18-1.2798.fc6)

Merci de n'importe qui pourrait les aider sur cette question. Veuillez

Dans le ci-dessous un exemple de code,nous avons eu lier raw chaussette avec eth0. mais lors de l'exécution du programme
le recvfrom de raw chaussette est de la réception de paquets de eth0 & eth1 sur la même machine(xx_86).
Il n'est pas clair pour moi pourquoi,pourrait aider sur cette question.
J'espère que le setsockopt ne fonctionne pas correctement
OS: Fedora core 6(2.6.18-1.2798.fc6)

Sampe code:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <linux/if_ether.h>
#include <net/if.h>
#include <linux/filter.h>
#include <sys/ioctl.h> 
#include <string.h>
#include <arpa/inet.h>
int main(int argc, char **argv) {
int sock, i;
unsigned char buffer[2048];
unsigned char tbuff[2048];
unsigned char *iphead, *ethhead,*phead;
struct ifreq ethreq;
//NOTE: use TCPDUMP to build the filter array.
//set filter to sniff only port 443
//$ sudo tcpdump -dd port 443
//raw for recvfrom eth0
if ((sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP))) == -1) {
perror("socket");
exit(1);
}
//set network card to promiscuos
strncpy(ethreq.ifr_name, "eth0", IFNAMSIZ);
if (ioctl(sock,SIOCGIFFLAGS, &ethreq) == -1) {
perror("ioctl");
close(sock);
exit(1);
}
ethreq.ifr_flags |= IFF_PROMISC;
if (ioctl(sock, SIOCSIFFLAGS, &ethreq) == -1) {
perror("ioctl");
close(sock);
exit(1);
}
//bind to sock with eth0 
struct ifreq Interface;
memset(&Interface, 0, sizeof(Interface));
strncpy(Interface.ifr_ifrn.ifrn_name, "eth0", IFNAMSIZ);
if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, &Interface, sizeof(Interface)) < 0)    { close(sock); }
//open the RAW socket for sendto
int s = socket (PF_INET, SOCK_RAW, IPPROTO_RAW);
struct sockaddr_in sin;
memset(&sin,0,sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_port = htons(0);
sin.sin_addr.s_addr = inet_addr ("10.3.161.104");
//inform kernal don't fill IP and Transport header
int one = 1;
const int *val = &one;
if (setsockopt (s, IPPROTO_IP, IP_HDRINCL, val, sizeof (one)) < 0)
printf ("Warning: Cannot set HDRINCL!\n");
//bind the sock descriptor with eth0
struct ifreq Interface1;
memset(&Interface1, 0, sizeof(Interface1));
strncpy(Interface1.ifr_ifrn.ifrn_name, "eth0", IFNAMSIZ);
if (setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE, &Interface1, sizeof(Interface1)) < 0) { close(s); }
while (1) {
printf("----------------------\n");
i = recvfrom(sock, buffer, sizeof(buffer), 0, NULL, NULL);
printf("%d bytes read\n", i);
//check header size: Ethernet = 14, IP = 20, TCP = 8 (sum = 42)
if (i < 42) {
perror("recvfrom():");
printf("Incomplete packet (errno is %d)\n", errno);
close(sock);
exit(0);
}
phead = buffer + 14; //(skip ethernet  header)
memcpy(tbuff,phead,i-14); 
iphead=tbuff;
if (*iphead == 0x45) {
int ptrindex= iphead[9];
switch(ptrindex){
case 1:
printf("The transport protocl is:ICMP\n");
break;
case 2:
printf("The transport protol is:IGMP\n");
break;
case 6:
printf("The transport protocol is:TCP\n");
break;
case 17:
printf("The transport protocol is:UDP\n");
break;
case 103:
printf("The transport protocol is:PIM\n"); 
break; 
default:
printf("The transport protocol is:%d\n",iphead[9]);
}           
//printf("%d",*ptrindex);
//printf("\n The transport protocol is :%u\n",iphead[9]);
printf("Source Address: %d.%d.%d.%d, Port: %d\n",
iphead[12], iphead[13], iphead[14], iphead[15], (iphead[20] << 8) + iphead[21]);
printf("Dest Address: %d.%d.%d.%d, Port: %d\n",
iphead[16], iphead[17], iphead[18], iphead[19], (iphead[22] << 8) + iphead[23]);
if(sendto(s,tbuff,i-14,0,(struct sockaddr *)&sin,sizeof(sin))<0)
printf("error\n");
else{printf("\nThe received packet is send\n");}
memset(buffer,0,sizeof(buffer));
memset(tbuff,0,sizeof(tbuff));
}
else{ printf("The non ip had received");}
}
close(sock);
}
Ok, pourquoi ne pas vous avez un perror() sur setsockopt() erreur?

OriginalL'auteur viswanathan J | 2012-03-29