通过linux中的RAW套接字重新发送数据包

时间:2016-05-04 09:33:27

标签: c linux sockets raw-sockets

需要从一个界面读取原始数据并通过另一个界面发送。

open&& config(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);

然后循环:

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))
    }

然后,如果我抓住sock_raw_inner任何数据包(例如arp请求),它会一次又一次地通过sendto在sock_raw_inner上发送。怎么了?感谢。

1 个答案:

答案 0 :(得分:0)

您的sock_raw_inner仍在侦听每个接口,因为不支持您尝试执行的eth0上的绑定。因此,发送到另一个接口的数据包确实会被sock_raw_inner

接收

从man(7)socket中提取(参见粗体文字)

  

SO_BINDTODEVICE                 将此套接字绑定到特定设备,如" eth0",作为speci                 在传递的接口名称中。如果名称是空的                 字符串或选项长度为零,套接字设备绑定                 已移除。传递的选项是一个可变长度的空终止                 nated接口名称字符串,最大大小为IFNAMSIZ。                 如果套接字绑定到接口,则仅接收来自的数据包                 该特定接口由套接字处理。注意                 这仅适用于某些套接字类型,尤其是AF_INET                 插座。 数据包套接字不支持(使用正常                 bind(8)那里。