在Linux中拦截/重新路由TCP SYN数据包到C ++程序

时间:2009-02-27 09:57:01

标签: c++ linux tcp

我正在尝试找到拦截我的计算机在c ++程序中发送的TCP SYN数据包的最简单方法。我知道有几种选择。一个是监控所有流量,只是选择性地使用SYN数据包,其余部分不做任何事情。我遇到的另一个选择是使用包过滤实用程序,它将SYN包转发到我的程序。有人建议我使用netfilter

我想知道是否还有其他选择,或者我应该深入研究netfilter。此外,任何有关如何使用netfilter执行此操作的指示都会有所帮助。

编辑:我想拦截SYN数据包,可能需要修改它(重新路由到不同的目的地,更改目标端口等),然后再将其重新注入网络

编辑:我能够使用iptables和libnetfilter_queue的组合来完成此操作。我使用ipfilter将所有TCP SYN数据包重定向到特定队列(这是使用一个简单的命令)
然后在C程序中,我能够使用libnetfilter_queue API访问队列中的数据包,分析它们并将它们重新注入网络。

2 个答案:

答案 0 :(得分:4)

如果您只想查看数据包,请使用libpcap和数据包过滤 - 这对大多数UNIX变体都有效。

如果您想以某种方式拦截和重写数据包,请提供有关您尝试执行的操作的更多信息,以及之后应该对数据包执行的操作。

正如您所建议的那样,这可能是netfilter及其queue模块的应用程序,尽管这需要2.6.14或更高版本的内核:

  

主要特点

     
      
  • 从内核nfnetlink_queue子系统接收排队的数据包
  •   
  • 发布判决和/或将更改的数据包重新注入内核   nfnetlink_queue子系统
  •   

答案 1 :(得分:0)

您可以使用原始套接字或例如pcap库。使用pcap,您可以设置过滤器并捕获有趣的流量:

#include <pcap.h>
...
pcap_t* reader_handle;
char errbuf[PCAP_ERRBUF_SIZE];
if ( (reader_handle = pcap_open_live(device_string, capture_size, 0, timeout, errbuf) ) == NULL)
{
    //ooops
}
struct bpf_program fp;
if (pcap_compile(reader_handle, &fp, filter_string, 1, 0) == -1)
{
    //ooops, cleanup
}
if (pcap_setfilter(reader_handle, &fp) == -1)
{
    //ooops, cleanup
}
pcap_freecode(&fp);

然后你只是捕获,有几种不同的方式,例如:

pcap_pkthdr* header; 
u_char* pkt_data;
const int status = pcap_next_ex(reader_handle, &header, &pkt_data);
// Check the status

结束捕获后:

pcap_close(reader_handle);

您需要使用原始套接字的权限。上面的例子可以很好地用C ++包装。