Salve ho un problema riguardo i raw socket. Ho la necessita di accedere all'interfaccia eth0 direttamente dall'interfaccia di rete senza passare per TCP o UDP. Seguendo alcuni topic in giro per siti e alcune guide ho tirato fuori questo programma:
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <stdio.h>
#include <netdb.h>
#include <errno.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
int main() {
int sock,i;
struct sockaddr_in6 *address;
struct protoent *proto;
struct ifreq ethreq, Interface, Interface1;
unsigned char buffer[2048];
unsigned char tbuff[2048];
unsigned char *iphead, *ethhead,*phead;
static const uint8_t mys6_addr[16]={0x54,0x04,0x20,0x49,0x0e,0x40,0xc7,0x03,0xa0};
proto=getprotobyname("ipv6");
sock=socket(AF_INET6, SOCK_RAW,proto->p_proto);
if(sock<0) {
perror("socket");
exit(1);
}
strncpy(ethreq.ifr_name, "eth0", IFNAMSIZ);
if (ioctl(sock,SIOCGIFFLAGS, ðreq) == -1) {
perror("ioctl");
close(sock);
exit(1);
}
ethreq.ifr_flags |= IFF_PROMISC;
if (ioctl(sock, SIOCSIFFLAGS, ðreq) == -1) {
perror("ioctl");
close(sock);
exit(1);
}
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);
int s = socket (AF_INET6, SOCK_RAW, proto->p_proto);
struct sockaddr_in6 sin6;
memset(&sin6,0,sizeof(sin6));
sin6.sin6_family = AF_INET6;
sin6.sin6_port = htons(0);
memcpy(sin6.sin6_addr.s6_addr, mys6_addr, sizeof(mys6_addr));
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);
if (i < 42) {
perror("recvfrom():");
printf("Incomplete packet (errno is %d)\n", errno);
close(sock);
exit(0);
}
phead = buffer + 14;
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("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(send(s,tbuff,i-14,0)<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);
return 0;
}
Il programma si blocca alla prima printf del while. Perchè? Ho letto in qualche sito che i raw socket hanno qualche problema nell'invio di pacchetti ipv6 o non sono predisposti per farlo è vero?