使用这个东西,我可以获得socket(PF_INET, SOCK_DGRAM,0)套接字的原始目标IP地址。
socket(PF_INET, SOCK_DGRAM,0)
如何获得原始目标端口?
取决于重定向机制。如果使用的是REDIRECT(实际上是NAT),则需要在应用NAT之前使用SO_ORIGINAL_DST或libnetfilter_conntrack来查询连接的原始目标。但是,由于可以使用同一个侦听器套接字为多个连接提供服务,因此必须对每个数据包执行此查找。
您可以使用conntrack命令行工具尝试libnetfilter_conntrack及其提供的服务。
一种替代方法是使用TPROXY进行重定向,这是在这种情况下使用的。在那里,您可以使用recvmsg()使用辅助消息获得数据包的原始目标。查找的关键是IP_RECVORIGDSTsetsockopt。
关于TPROXY的更多信息可以在内核文档目录的tproxy.txt文件中找到。它有点难用,但是由于它是由堆栈而不是数据包过滤子系统实现的,因此工作更可靠。
编辑: 添加如何使用TProxy查询UDP目标地址。
编辑: SO_ORIGINAL_DST与udp
SO_ORIGINAL_DST应该与udp套接字一起使用,但是内核不允许您指定连接端点,它将使用您调用SO_ORIGINAL_DST的套接字来获取此地址信息。
这意味着只有将UDP套接字正确绑定(绑定到重定向到的地址/端口)并连接(绑定到有关的客户端),它才会起作用。您的侦听器套接字可能绑定到0.0.0.0,并且不仅为单个客户端提供服务,而且还为多个客户端提供服务。
但是,您不需要使用实际的侦听器套接字来查询目标地址。由于UDP在建立连接时不会传输数据报,因此您可以创建一个新的UDP套接字,将其绑定到重定向地址,然后将其连接到客户端(您知道的地址,因为它无论如何都会将第一个数据包发送给侦听器)。然后,您可以使用此套接字在其上运行SO_ORIGINAL_DST,但是有罪魁祸首:
基于TProxy的方法显然更好。