Skip to content
Advertisement

resend packets via RAW sockets in linux

It’s needed to read raw data from one interface and send it via another.

open&&config(the same for sock_raw_outer):

sock_raw_inner = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
setsockopt(sock_raw_inner, SOL_SOCKET, SO_BINDTODEVICE, "eth0", 4);
struct ifreq if_idx1;
memset(&if_idx1, 0, sizeof(struct ifreq));
strncpy(if_idx1.ifr_name, opt, strlen(opt));
ioctl(sock_raw_inner, SIOCGIFINDEX, &if_idx1);

then in cycle:

data_size = recvfrom(sock_raw_inner, buffer, 65536, MSG_DONTWAIT, NULL, NULL);
    if (data_size > 0) {
        struct sockaddr_ll socket_address;
        socket_address.sll_ifindex = if_idx2.ifr_ifindex;
        socket_address.sll_halen = ETH_ALEN;
        //copy dest
        socket_address.sll_addr[0] = buffer[0];
        socket_address.sll_addr[1] = buffer[1];
        socket_address.sll_addr[2] = buffer[2];
        socket_address.sll_addr[3] = buffer[3];
        socket_address.sll_addr[4] = buffer[4];
        socket_address.sll_addr[5] = buffer[5];
        sendto(sock_raw_outer, buffer, size, 0, (struct sockaddr*)&socket_address, sizeof(struct sockaddr_ll))
    }

then, if I catch on sock_raw_inner any packet(arp request, for example), it sended on sock_raw_inner again and again by sendto. What’s wrong? Thanks.

Advertisement

Answer

Your sock_raw_inner is still listening on every interface because the bind on eth0 you are trying to perform is not supported. So the packet sent to another interface is indeed then received by your sock_raw_inner

Extract from man (7) socket (see bold text)

SO_BINDTODEVICE Bind this socket to a particular device like “eth0”, as speci- fied in the passed interface name. If the name is an empty string or the option length is zero, the socket device binding is removed. The passed option is a variable-length null termi- nated interface name string with the maximum size of IFNAMSIZ. If a socket is bound to an interface, only packets received from that particular interface are processed by the socket. Note that this only works for some socket types, particularly AF_INET sockets. It is not supported for packet sockets (use normal bind(8) there).

User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement