【发布时间】:2015-07-12 14:26:12
【问题描述】:
我使用libnetfilter_queue 和iptables 和NFQUEUE 目标将传入的数据包存储在三个不同的队列中,--queue-num x。
我用libnetfilter_queuefunctions成功创建了三个队列,绑定它们,监听它们并从中读取如下:
/* given 'h' as a handler of one of my three queues */
fd = nfq_fd(h);
while ((rv = recv(fd, buf, sizeof(buf), 0)) && rv >= 0) {
nfq_handle_packet(h, buf, rv);
}
由nfq_handle_packet 触发的回调函数具有nfq_set_verdict(qh, id, NF_ACCEPT, 0, NULL); 命令,它会在处理完数据包后立即发送数据包。
问题是:我不希望立即发送每个数据包,因为我需要将它们存储在自定义结构中(如下所示)。
所以我遇到了一个潜在的解决方案:我可能会在我想要排队的每个数据包上调用 NF_DROP 而不是 NF_ACCEPT(所以它不会立即被发送出去),将它存储在我的自定义结构中,然后(迟早)根据我的需要重新注入。
听起来不错,但情况是:我不知道如何从我的用户空间应用程序中随意重新注入排队的数据包。在我的代码的同一点再次使用nfq_set_verdict 是否正确,但使用NF_ACCEPT 判决?或者我应该打开一个套接字(也许是一个原始的)?
这是我的自定义结构
struct List {
int queue;
int pktsize;
unsigned char *buffer;
struct nfq_q_handle *qh;
struct nfqnl_msg_packet_hdr *hdr;
struct List *next;
};
表示使用上述规则捕获的数据包。
这些是我存储数据包的队列。
struct List *List0 = NULL; // low priority
struct List *List1 = NULL; // medium priority
struct List *List2 = NULL; // high priority
我有Ubuntu 14.04 3.13.0-57-generic。
任何建议将不胜感激。
【问题讨论】:
-
我认为您只需推迟对这些数据包的
nfq_set_verdict()调用,直到您准备好将它们推回堆栈。关键是它们在内核中排队。 AFAIK,您不必立即为数据包致电nfq_set_verdict()。您可以将数据包或 ID 保存在列表中,稍后再调用。
标签: c networking network-programming netfilter