C语言 如何获得ipset超时编程?



我试图以编程方式获得ipset的超时值(不使用userspaceipset工具)。

下面的例子试图从名为"my_set"它是用这个命令创建的:ipset create my_set hash:ip timeout 86400

以下是示例代码,我尝试了几种不同的方法来访问超时数据字段:
#include "stdlib.h"
#include <libipset/types.h>
#include <libipset/session.h>
int main(int argc, char* argv[]) {
ipset_load_types();
struct ipset_session *session;
session = ipset_session_init(NULL, NULL);
ipset_session_data_set(session, IPSET_SETNAME, "my_set");
/* Validate set exist */
if (ipset_type_get(session, IPSET_CMD_TEST) == NULL) {
printf("Error: Can't find setn");
exit(1);
}
if ((const uint32_t*)ipset_session_data_get(session, IPSET_OPT_TIMEOUT) == NULL)
printf("Timeout field is NULLn");
const struct ipset_data* data = ipset_session_data(session);
if (!ipset_data_flags_test(data, IPSET_FLAG(IPSET_OPT_TIMEOUT)))
printf("Timeout field is not presentn");
if (!ipset_data_test(data, IPSET_OPT_TIMEOUT))
printf("Timeout field is not presentn");
if ((const uint32_t*)ipset_session_data_get(session, IPSET_OPT_TIMEOUT) == NULL)
printf("Timeout field is NULLn");
}

编译:gcc -lipset test.c

输出是:

Timeout field is NULL
Timeout field is not present
Timeout field is not present
Timeout field is NULL

我认为超时不是由内核提供的,但我不知道如何使用ipset API向内核询问该信息。我找不到任何API文档,我正试图使用我在这里或这里找到的ipset源中的示例

这里的API对这个任务没有用处。

从我所看到的,libipset有一些相当愚蠢的接口。没有一种合适的方法可以通过库获得给定集合的属性,相关的命令行工具(ipset(8))也没有提供一种简单的方法来查询它们。但是,在发布"列表"时,它们是可用的。命令。

似乎您想要的信息只在需要时由库实时查询,然后删除,不留下任何痕迹。这意味着即使在执行了ipset_cmd(session, IPSET_CMD_LIST, 0)之类的操作之后,使用ipset_session_data_get(session, IPSET_OPT_TIMEOUT)进行检查也不会产生任何结果!很有趣。

"proper"获取此信息的方法是使用原始netlink套接字并直接与ipset netlink子系统(NFNL_SUBSYS_IPSET)交换适当的消息,这是libipset在引子下所做的,但这是相当的困境…

然而,由于库允许您创建"会话";注册一个回调函数来调用打印信息,你可以[ab]使用它来得到你想要的。

下面是一个工作示例:

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <libipset/types.h>
#include <libipset/session.h>
struct info {
uint32_t timeout;
bool ok;
};
/* Callback print function executed by libipset when information is available.
* Extract whatever information is needed and store it through the private data
* pointer.
*/
static int dummy_print_fn(struct ipset_session *session, void *data, const char *_fmt, ...) {
struct info *out = data;
const uint32_t *ptr = ipset_session_data_get(session, IPSET_OPT_TIMEOUT);
if (ptr != NULL) {
out->timeout = *ptr;
out->ok = true;
} else {
out->ok = false;
}
return 0;
}
int main(int argc, char* argv[]) {
ipset_load_types();
struct ipset_session *session;
/* Passed as private data pointer to dummy_print_fn. */
struct info info;
/* Register dummy print callback and &info as private data ptr. */
if ((session = ipset_session_init(dummy_print_fn, &info)) == NULL) {
printf("Error: Can't initialize sessionn");
exit(1);
}
if (ipset_session_data_set(session, IPSET_SETNAME, "my_set") != 0) {
printf("Error: Can't give set namen");
exit(1);
}
/* Validate set exists */
if (ipset_type_get(session, IPSET_CMD_TEST) == NULL) {
printf("Error: Can't find setn");
exit(1);
}
/* Execute a list command to get the information you want through the
* registered callback function.
*/
if (ipset_cmd(session, IPSET_CMD_LIST, 0) != 0) {
printf("Error: list command failedn");
exit(1);
}
if (info.ok)
printf("Timeout: %un", info.timeout);
else
printf("Timeout: field unavailablen");
return 0;
}

最新更新