使用iptables TPROXY重定向到原始套接字

时间:2016-04-30 12:13:54

标签: c linux iptables raw-sockets

我打算使用iptables的TPROXY目标将一些UDP数据包重定向到 一个原始套接字,但套接字不会收到任何数据包。它适用于UDP 插座。我错过了什么或原始套接字无法接收数据 等级TPROXY有效吗?

iptables -A PREROUTING -t mangle -p udp --dport 8816 --dst 127.0.0.1 -j
TPROXY --on-port 0 --on-ip 127.0.0.2

使用重定向数据包的代码:

#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>

char _errstr[100];
#define CHECK(X) \
if (! (X)) {\
    sprintf(_errstr, "%d: check failed", __LINE__);\
    perror(_errstr);\
    exit(1);\
}

int main() {
    int r;
    int fd = socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
    CHECK(fd != 0);
    int val = 1;
    CHECK(setsockopt(fd, SOL_IP, IP_TRANSPARENT, &val, sizeof(val))== 0);
    char buff[1500] = {0};

    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = inet_addr("127.0.0.2");
    r = bind(fd, (struct sockaddr* )&addr, sizeof(addr));
    CHECK(r == 0);

    r = read(fd, buff, 1500);
    CHECK(r >= 0);

    int c;
    for (c=0; r>c; c++)
        printf("%02X ", 0xFF & *(buff + c));

    return 0;
}

我使用netcat(nc -u 127.0.0.1 8816)测试并看到了IPTables规则 匹配,但没有数据包发送到原始套接字。

1 个答案:

答案 0 :(得分:1)

问题出在r = bind(fd, (struct sockaddr* )&addr, sizeof(addr));。你不应该bind到一个原始套接字,而应该用setsockopt调用SO_BINDTODEVICE绑定到接口,在你的情况下,它是具有地址的接口{ {1}}。

有关如何使用此选项的详细信息,请查看http://linux.die.net/man/7/socket