From 5262990d8e4d2fb2fa3e52854f79789500eff0c2 Mon Sep 17 00:00:00 2001 From: Nils Andreas Svee Date: Sun, 1 Jul 2018 23:22:18 +0200 Subject: [PATCH 1/2] miniupnpd: support newer libnftnl versions --- miniupnpd/Makefile.linux_nft | 7 + miniupnpd/netfilter_nft/nftnlrdr.c | 8 +- miniupnpd/netfilter_nft/nftnlrdr_misc.c | 288 ++++++++++++------------ miniupnpd/netfilter_nft/nftnlrdr_misc.h | 10 +- 4 files changed, 160 insertions(+), 153 deletions(-) diff --git a/miniupnpd/Makefile.linux_nft b/miniupnpd/Makefile.linux_nft index 0c03ca3..489ba21 100644 --- a/miniupnpd/Makefile.linux_nft +++ b/miniupnpd/Makefile.linux_nft @@ -74,6 +74,13 @@ endif # ($(TEST),1) LDLIBS += $(shell $(PKG_CONFIG) --static --libs-only-l libssl) +TEST := $(shell $(PKG_CONFIG) --exists uuid && echo 1) +ifeq ($(TEST),1) +LDLIBS += $(shell $(PKG_CONFIG) --static --libs-only-l uuid) +else +$(info please install uuid-dev package / libuuid) +endif # ($(TEST),1) + TESTUPNPDESCGENOBJS = testupnpdescgen.o upnpdescgen.o EXECUTABLES = miniupnpd testupnpdescgen testgetifstats \ diff --git a/miniupnpd/netfilter_nft/nftnlrdr.c b/miniupnpd/netfilter_nft/nftnlrdr.c index 389273f..494685e 100644 --- a/miniupnpd/netfilter_nft/nftnlrdr.c +++ b/miniupnpd/netfilter_nft/nftnlrdr.c @@ -63,7 +63,7 @@ add_redirect_rule2(const char * ifname, const char * iaddr, unsigned short iport, int proto, const char * desc, unsigned int timestamp) { - struct nft_rule *r; + struct nftnl_rule *r; UNUSED(rhost); UNUSED(timestamp); d_printf(("add redirect rule2(%s, %s, %u, %s, %u, %d, %s)!\n", @@ -87,7 +87,7 @@ add_peer_redirect_rule2(const char * ifname, const char * iaddr, unsigned short iport, int proto, const char * desc, unsigned int timestamp) { - struct nft_rule *r; + struct nftnl_rule *r; UNUSED(ifname); UNUSED(timestamp); d_printf(("add peer redirect rule2()!\n")); @@ -111,7 +111,7 @@ add_filter_rule2(const char * ifname, unsigned short eport, unsigned short iport, int proto, const char * desc) { - struct nft_rule *r = NULL; + struct nftnl_rule *r = NULL; in_addr_t rhost_addr = 0; d_printf(("add_filter_rule2(%s, %s, %s, %d, %d, %d, %s)\n", @@ -150,7 +150,7 @@ int delete_redirect_and_filter_rules(unsigned short eport, int proto) { rule_t *p; - struct nft_rule *r = NULL; + struct nftnl_rule *r = NULL; in_addr_t iaddr = 0; uint16_t iport = 0; extern void print_rule(rule_t *r) ; diff --git a/miniupnpd/netfilter_nft/nftnlrdr_misc.c b/miniupnpd/netfilter_nft/nftnlrdr_misc.c index a35c45e..f709904 100644 --- a/miniupnpd/netfilter_nft/nftnlrdr_misc.c +++ b/miniupnpd/netfilter_nft/nftnlrdr_misc.c @@ -237,17 +237,17 @@ set_reg (rule_t *r, uint32_t dreg, enum rule_reg_type type, uint32_t val) } static inline void -parse_rule_immediate(struct nft_rule_expr *e, rule_t *r) +parse_rule_immediate(struct nftnl_expr *e, rule_t *r) { uint32_t dreg, reg_val, reg_len; - dreg = nft_rule_expr_get_u32(e, NFT_EXPR_IMM_DREG); + dreg = nftnl_expr_get_u32(e, NFTNL_EXPR_IMM_DREG); if (dreg == NFT_REG_VERDICT) { - reg_val = nft_rule_expr_get_u32(e, NFT_EXPR_IMM_VERDICT); + reg_val = nftnl_expr_get_u32(e, NFTNL_EXPR_IMM_VERDICT); } else { - reg_val = *(uint32_t *)nft_rule_expr_get(e, - NFT_EXPR_IMM_DATA, + reg_val = *(uint32_t *)nftnl_expr_get(e, + NFTNL_EXPR_IMM_DATA, ®_len); } @@ -256,20 +256,20 @@ parse_rule_immediate(struct nft_rule_expr *e, rule_t *r) } static inline void -parse_rule_counter(struct nft_rule_expr *e, rule_t *r) +parse_rule_counter(struct nftnl_expr *e, rule_t *r) { r->type = RULE_COUNTER; - r->bytes = nft_rule_expr_get_u64(e, NFT_EXPR_CTR_BYTES); - r->packets = nft_rule_expr_get_u64(e, NFT_EXPR_CTR_PACKETS); + r->bytes = nftnl_expr_get_u64(e, NFTNL_EXPR_CTR_BYTES); + r->packets = nftnl_expr_get_u64(e, NFTNL_EXPR_CTR_PACKETS); return; } static inline void -parse_rule_meta(struct nft_rule_expr *e, rule_t *r) +parse_rule_meta(struct nftnl_expr *e, rule_t *r) { - uint32_t key = nft_rule_expr_get_u32(e, NFT_EXPR_META_KEY); - uint32_t dreg = nft_rule_expr_get_u32(e, NFT_EXPR_META_DREG); + uint32_t key = nftnl_expr_get_u32(e, NFTNL_EXPR_META_KEY); + uint32_t dreg = nftnl_expr_get_u32(e, NFTNL_EXPR_META_DREG); enum rule_reg_type reg_type; switch (key) { @@ -290,18 +290,18 @@ parse_rule_meta(struct nft_rule_expr *e, rule_t *r) } static inline void -parse_rule_nat(struct nft_rule_expr *e, rule_t *r) +parse_rule_nat(struct nftnl_expr *e, rule_t *r) { uint32_t addr_min_reg, addr_max_reg, proto_min_reg, proto_max_reg; uint16_t proto_min_val; r->type = RULE_NAT; - r->nat_type = nft_rule_expr_get_u32(e, NFT_EXPR_NAT_TYPE); - r->family = nft_rule_expr_get_u32(e, NFT_EXPR_NAT_FAMILY); - addr_min_reg = nft_rule_expr_get_u32(e, NFT_EXPR_NAT_REG_ADDR_MIN); - addr_max_reg = nft_rule_expr_get_u32(e, NFT_EXPR_NAT_REG_ADDR_MAX); - proto_min_reg = nft_rule_expr_get_u32(e, NFT_EXPR_NAT_REG_PROTO_MIN); - proto_max_reg = nft_rule_expr_get_u32(e, NFT_EXPR_NAT_REG_PROTO_MAX); + r->nat_type = nftnl_expr_get_u32(e, NFTNL_EXPR_NAT_TYPE); + r->family = nftnl_expr_get_u32(e, NFTNL_EXPR_NAT_FAMILY); + addr_min_reg = nftnl_expr_get_u32(e, NFTNL_EXPR_NAT_REG_ADDR_MIN); + addr_max_reg = nftnl_expr_get_u32(e, NFTNL_EXPR_NAT_REG_ADDR_MAX); + proto_min_reg = nftnl_expr_get_u32(e, NFTNL_EXPR_NAT_REG_PROTO_MIN); + proto_max_reg = nftnl_expr_get_u32(e, NFTNL_EXPR_NAT_REG_PROTO_MAX); if (addr_min_reg != addr_max_reg || proto_min_reg != proto_max_reg) { @@ -325,15 +325,15 @@ parse_rule_nat(struct nft_rule_expr *e, rule_t *r) } static inline void -parse_rule_payload(struct nft_rule_expr *e, rule_t *r) +parse_rule_payload(struct nftnl_expr *e, rule_t *r) { uint32_t base, dreg, offset, len; uint32_t *regptr; - dreg = nft_rule_expr_get_u32(e, NFT_EXPR_PAYLOAD_DREG); - base = nft_rule_expr_get_u32(e, NFT_EXPR_PAYLOAD_BASE); - offset = nft_rule_expr_get_u32(e, NFT_EXPR_PAYLOAD_OFFSET); - len = nft_rule_expr_get_u32(e, NFT_EXPR_PAYLOAD_LEN); + dreg = nftnl_expr_get_u32(e, NFTNL_EXPR_PAYLOAD_DREG); + base = nftnl_expr_get_u32(e, NFTNL_EXPR_PAYLOAD_BASE); + offset = nftnl_expr_get_u32(e, NFTNL_EXPR_PAYLOAD_OFFSET); + len = nftnl_expr_get_u32(e, NFTNL_EXPR_PAYLOAD_LEN); regptr = get_reg_type_ptr(r, dreg); switch (base) { @@ -377,16 +377,16 @@ parse_rule_payload(struct nft_rule_expr *e, rule_t *r) * Note: Currently support only NFT_REG_1 */ static inline void -parse_rule_cmp(struct nft_rule_expr *e, rule_t *r) { +parse_rule_cmp(struct nftnl_expr *e, rule_t *r) { uint32_t data_len; void *data_val; uint32_t op, sreg; uint16_t *ports; in_addr_t *addrp; - data_val = (void *)nft_rule_expr_get(e, NFT_EXPR_CMP_DATA, &data_len); - sreg = nft_rule_expr_get_u32(e, NFT_EXPR_CMP_SREG); - op = nft_rule_expr_get_u32(e, NFT_EXPR_CMP_OP); + data_val = (void *)nftnl_expr_get(e, NFTNL_EXPR_CMP_DATA, &data_len); + sreg = nftnl_expr_get_u32(e, NFTNL_EXPR_CMP_SREG); + op = nftnl_expr_get_u32(e, NFTNL_EXPR_CMP_OP); if (sreg != NFT_REG_1) { syslog(LOG_ERR, "parse_rule_cmp: Unsupport reg:%d", sreg); @@ -453,11 +453,11 @@ parse_rule_cmp(struct nft_rule_expr *e, rule_t *r) { } static int -rule_expr_cb(struct nft_rule_expr *e, void *data) +rule_expr_cb(struct nftnl_expr *e, void *data) { rule_t *r = data; - const char *attr_name = nft_rule_expr_get_str(e, - NFT_RULE_EXPR_ATTR_NAME); + const char *attr_name = nftnl_expr_get_str(e, + NFTNL_EXPR_NAME); if (strncmp("cmp", attr_name, sizeof("cmp")) == 0) { parse_rule_cmp(e, r); @@ -481,10 +481,10 @@ rule_expr_cb(struct nft_rule_expr *e, void *data) static int table_cb(const struct nlmsghdr *nlh, void *data) { - struct nft_rule *t; + struct nftnl_rule *t; uint32_t len; - struct nft_rule_expr *expr; - struct nft_rule_expr_iter *itr; + struct nftnl_expr *expr; + struct nftnl_expr_iter *itr; rule_t *r; char *chain; UNUSED(data); @@ -492,18 +492,18 @@ table_cb(const struct nlmsghdr *nlh, void *data) r = malloc(sizeof(rule_t)); memset(r, 0, sizeof(rule_t)); - t = nft_rule_alloc(); + t = nftnl_rule_alloc(); if (t == NULL) { perror("OOM"); goto err; } - if (nft_rule_nlmsg_parse(nlh, t) < 0) { - perror("nft_rule_nlmsg_parse"); + if (nftnl_rule_nlmsg_parse(nlh, t) < 0) { + perror("nftnl_rule_nlmsg_parse"); goto err_free; } - chain = (char *)nft_rule_attr_get_data(t, NFT_RULE_ATTR_CHAIN, &len); + chain = (char *)nftnl_rule_get_data(t, NFTNL_RULE_CHAIN, &len); if (strcmp(chain, miniupnpd_nft_nat_chain) != 0 && strcmp(chain, miniupnpd_nft_peer_chain) != 0 && strcmp(chain, miniupnpd_nft_forward_chain) != 0) { @@ -511,14 +511,14 @@ table_cb(const struct nlmsghdr *nlh, void *data) } r->table = strdup( - (char *)nft_rule_attr_get_data(t, NFT_RULE_ATTR_TABLE, &len)); + (char *)nftnl_rule_get_data(t, NFTNL_RULE_TABLE, &len)); r->chain = strdup(chain); - r->family = *(uint32_t*)nft_rule_attr_get_data(t, NFT_RULE_ATTR_FAMILY, + r->family = *(uint32_t*)nftnl_rule_get_data(t, NFTNL_RULE_FAMILY, &len); - r->desc = (char *)nft_rule_attr_get_data(t, NFT_RULE_ATTR_USERDATA, + r->desc = (char *)nftnl_rule_get_data(t, NFTNL_RULE_USERDATA, &len); - r->handle = *(uint32_t*)nft_rule_attr_get_data(t, - NFT_RULE_ATTR_HANDLE, + r->handle = *(uint32_t*)nftnl_rule_get_data(t, + NFTNL_RULE_HANDLE, &len); if (strcmp(r->table, NFT_TABLE_NAT) == 0) { r->type = RULE_NAT; @@ -529,9 +529,9 @@ table_cb(const struct nlmsghdr *nlh, void *data) rule_list_peer_length++; } - itr = nft_rule_expr_iter_create(t); + itr = nftnl_expr_iter_create(t); - while ((expr = nft_rule_expr_iter_next(itr)) != NULL) { + while ((expr = nftnl_expr_iter_next(itr)) != NULL) { rule_expr_cb(expr, r); } @@ -544,7 +544,7 @@ table_cb(const struct nlmsghdr *nlh, void *data) rule_skip: err_free: - nft_rule_free(t); + nftnl_rule_free(t); err: return MNL_CB_OK; } @@ -613,8 +613,8 @@ reflesh_nft_cache(uint32_t family) { char buf[MNL_SOCKET_BUFFER_SIZE]; struct nlmsghdr *nlh; - uint32_t portid, seq, type = NFT_OUTPUT_DEFAULT; - struct nft_rule *t; + uint32_t portid, seq, type = NFTNL_OUTPUT_DEFAULT; + struct nftnl_rule *t; rule_t *p1, *p2; int ret; @@ -642,17 +642,17 @@ reflesh_nft_cache(uint32_t family) } LIST_INIT(&head); - t = nft_rule_alloc(); + t = nftnl_rule_alloc(); if (t == NULL) { perror("OOM"); exit(EXIT_FAILURE); } seq = time(NULL); - nlh = nft_rule_nlmsg_build_hdr(buf, NFT_MSG_GETRULE, family, + nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_GETRULE, family, NLM_F_DUMP, seq); - nft_rule_nlmsg_build_payload(nlh, t); - nft_rule_free(t); + nftnl_rule_nlmsg_build_payload(nlh, t); + nftnl_rule_free(t); if (nl == NULL) { nl = mnl_socket_open(NETLINK_NETFILTER); @@ -695,157 +695,157 @@ reflesh_nft_cache(uint32_t family) } static void -expr_add_payload(struct nft_rule *r, uint32_t base, uint32_t dreg, +expr_add_payload(struct nftnl_rule *r, uint32_t base, uint32_t dreg, uint32_t offset, uint32_t len) { - struct nft_rule_expr *e; + struct nftnl_expr *e; - e = nft_rule_expr_alloc("payload"); + e = nftnl_expr_alloc("payload"); if (e == NULL) { perror("expr payload oom"); exit(EXIT_FAILURE); } - nft_rule_expr_set_u32(e, NFT_EXPR_PAYLOAD_BASE, base); - nft_rule_expr_set_u32(e, NFT_EXPR_PAYLOAD_DREG, dreg); - nft_rule_expr_set_u32(e, NFT_EXPR_PAYLOAD_OFFSET, offset); - nft_rule_expr_set_u32(e, NFT_EXPR_PAYLOAD_LEN, len); + nftnl_expr_set_u32(e, NFTNL_EXPR_PAYLOAD_BASE, base); + nftnl_expr_set_u32(e, NFTNL_EXPR_PAYLOAD_DREG, dreg); + nftnl_expr_set_u32(e, NFTNL_EXPR_PAYLOAD_OFFSET, offset); + nftnl_expr_set_u32(e, NFTNL_EXPR_PAYLOAD_LEN, len); - nft_rule_add_expr(r, e); + nftnl_rule_add_expr(r, e); } #if 0 static void -expr_add_bitwise(struct nft_rule *r, uint32_t sreg, uint32_t dreg, +expr_add_bitwise(struct nftnl_rule *r, uint32_t sreg, uint32_t dreg, uint32_t len, uint32_t mask, uint32_t xor) { - struct nft_rule_expr *e; + struct nftnl_expr *e; - e = nft_rule_expr_alloc("bitwise"); + e = nftnl_expr_alloc("bitwise"); if (e == NULL) { perror("expr cmp bitwise"); exit(EXIT_FAILURE); } - nft_rule_expr_set_u32(e, NFT_EXPR_BITWISE_SREG, sreg); - nft_rule_expr_set_u32(e, NFT_EXPR_BITWISE_DREG, dreg); - nft_rule_expr_set_u32(e, NFT_EXPR_BITWISE_LEN, len); - nft_rule_expr_set(e, NFT_EXPR_BITWISE_MASK, &mask, sizeof(mask)); - nft_rule_expr_set(e, NFT_EXPR_BITWISE_XOR, &xor, sizeof(xor)); + nftnl_expr_set_u32(e, NFTNL_EXPR_BITWISE_SREG, sreg); + nftnl_expr_set_u32(e, NFTNL_EXPR_BITWISE_DREG, dreg); + nftnl_expr_set_u32(e, NFTNL_EXPR_BITWISE_LEN, len); + nftnl_expr_set(e, NFTNL_EXPR_BITWISE_MASK, &mask, sizeof(mask)); + nftnl_expr_set(e, NFTNL_EXPR_BITWISE_XOR, &xor, sizeof(xor)); - nft_rule_add_expr(r, e); + nftnl_rule_add_expr(r, e); } #endif static void -expr_add_cmp(struct nft_rule *r, uint32_t sreg, uint32_t op, +expr_add_cmp(struct nftnl_rule *r, uint32_t sreg, uint32_t op, const void *data, uint32_t data_len) { - struct nft_rule_expr *e; + struct nftnl_expr *e; - e = nft_rule_expr_alloc("cmp"); + e = nftnl_expr_alloc("cmp"); if (e == NULL) { perror("expr cmp oom"); exit(EXIT_FAILURE); } - nft_rule_expr_set_u32(e, NFT_EXPR_CMP_SREG, sreg); - nft_rule_expr_set_u32(e, NFT_EXPR_CMP_OP, op); - nft_rule_expr_set(e, NFT_EXPR_CMP_DATA, data, data_len); + nftnl_expr_set_u32(e, NFTNL_EXPR_CMP_SREG, sreg); + nftnl_expr_set_u32(e, NFTNL_EXPR_CMP_OP, op); + nftnl_expr_set(e, NFTNL_EXPR_CMP_DATA, data, data_len); - nft_rule_add_expr(r, e); + nftnl_rule_add_expr(r, e); } static void -expr_add_meta(struct nft_rule *r, uint32_t meta_key, uint32_t dreg) +expr_add_meta(struct nftnl_rule *r, uint32_t meta_key, uint32_t dreg) { - struct nft_rule_expr *e; + struct nftnl_expr *e; - e = nft_rule_expr_alloc("meta"); + e = nftnl_expr_alloc("meta"); if (e == NULL) { perror("expr meta oom"); exit(EXIT_FAILURE); } - nft_rule_expr_set_u32(e, NFT_EXPR_META_KEY, meta_key); - nft_rule_expr_set_u32(e, NFT_EXPR_META_DREG, dreg); + nftnl_expr_set_u32(e, NFTNL_EXPR_META_KEY, meta_key); + nftnl_expr_set_u32(e, NFTNL_EXPR_META_DREG, dreg); - nft_rule_add_expr(r, e); + nftnl_rule_add_expr(r, e); } static void -expr_set_reg_val_u32(struct nft_rule *r, enum nft_registers dreg, uint32_t val) +expr_set_reg_val_u32(struct nftnl_rule *r, enum nft_registers dreg, uint32_t val) { - struct nft_rule_expr *e; - e = nft_rule_expr_alloc("immediate"); + struct nftnl_expr *e; + e = nftnl_expr_alloc("immediate"); if (e == NULL) { perror("expr dreg oom"); exit(EXIT_FAILURE); } - nft_rule_expr_set_u32(e, NFT_EXPR_IMM_DREG, dreg); - nft_rule_expr_set_u32(e, NFT_EXPR_IMM_DATA, val); - nft_rule_add_expr(r, e); + nftnl_expr_set_u32(e, NFTNL_EXPR_IMM_DREG, dreg); + nftnl_expr_set_u32(e, NFTNL_EXPR_IMM_DATA, val); + nftnl_rule_add_expr(r, e); } static void -expr_set_reg_val_u16(struct nft_rule *r, enum nft_registers dreg, uint32_t val) +expr_set_reg_val_u16(struct nftnl_rule *r, enum nft_registers dreg, uint32_t val) { - struct nft_rule_expr *e; - e = nft_rule_expr_alloc("immediate"); + struct nftnl_expr *e; + e = nftnl_expr_alloc("immediate"); if (e == NULL) { perror("expr dreg oom"); exit(EXIT_FAILURE); } - nft_rule_expr_set_u32(e, NFT_EXPR_IMM_DREG, dreg); - nft_rule_expr_set_u16(e, NFT_EXPR_IMM_DATA, val); - nft_rule_add_expr(r, e); + nftnl_expr_set_u32(e, NFTNL_EXPR_IMM_DREG, dreg); + nftnl_expr_set_u16(e, NFTNL_EXPR_IMM_DATA, val); + nftnl_rule_add_expr(r, e); } static void -expr_set_reg_verdict(struct nft_rule *r, uint32_t val) +expr_set_reg_verdict(struct nftnl_rule *r, uint32_t val) { - struct nft_rule_expr *e; - e = nft_rule_expr_alloc("immediate"); + struct nftnl_expr *e; + e = nftnl_expr_alloc("immediate"); if (e == NULL) { perror("expr dreg oom"); exit(EXIT_FAILURE); } - nft_rule_expr_set_u32(e, NFT_EXPR_IMM_DREG, NFT_REG_VERDICT); - nft_rule_expr_set_u32(e, NFT_EXPR_IMM_VERDICT, val); - nft_rule_add_expr(r, e); + nftnl_expr_set_u32(e, NFTNL_EXPR_IMM_DREG, NFT_REG_VERDICT); + nftnl_expr_set_u32(e, NFTNL_EXPR_IMM_VERDICT, val); + nftnl_rule_add_expr(r, e); } static void -expr_add_nat(struct nft_rule *r, uint32_t t, uint32_t family, +expr_add_nat(struct nftnl_rule *r, uint32_t t, uint32_t family, in_addr_t addr_min, uint32_t proto_min, uint32_t flags) { - struct nft_rule_expr *e; + struct nftnl_expr *e; UNUSED(flags); - e = nft_rule_expr_alloc("nat"); + e = nftnl_expr_alloc("nat"); if (e == NULL) { perror("expr nat oom"); exit(EXIT_FAILURE); } - nft_rule_expr_set_u32(e, NFT_EXPR_NAT_TYPE, t); - nft_rule_expr_set_u32(e, NFT_EXPR_NAT_FAMILY, family); + nftnl_expr_set_u32(e, NFTNL_EXPR_NAT_TYPE, t); + nftnl_expr_set_u32(e, NFTNL_EXPR_NAT_FAMILY, family); expr_set_reg_val_u32(r, NFT_REG_1, (uint32_t)addr_min); - nft_rule_expr_set_u32(e, NFT_EXPR_NAT_REG_ADDR_MIN, NFT_REG_1); - nft_rule_expr_set_u32(e, NFT_EXPR_NAT_REG_ADDR_MAX, NFT_REG_1); + nftnl_expr_set_u32(e, NFTNL_EXPR_NAT_REG_ADDR_MIN, NFT_REG_1); + nftnl_expr_set_u32(e, NFTNL_EXPR_NAT_REG_ADDR_MAX, NFT_REG_1); expr_set_reg_val_u16(r, NFT_REG_2, proto_min); - nft_rule_expr_set_u16(e, NFT_EXPR_NAT_REG_PROTO_MIN, NFT_REG_2); - nft_rule_expr_set_u16(e, NFT_EXPR_NAT_REG_PROTO_MAX, NFT_REG_2); + nftnl_expr_set_u16(e, NFTNL_EXPR_NAT_REG_PROTO_MIN, NFT_REG_2); + nftnl_expr_set_u16(e, NFTNL_EXPR_NAT_REG_PROTO_MAX, NFT_REG_2); - nft_rule_add_expr(r, e); + nftnl_rule_add_expr(r, e); } /* * Todo: add expr for rhost */ -struct nft_rule * +struct nftnl_rule * rule_set_snat(uint8_t family, uint8_t proto, in_addr_t rhost, unsigned short rport, in_addr_t ehost, unsigned short eport, @@ -853,27 +853,27 @@ rule_set_snat(uint8_t family, uint8_t proto, const char *descr, const char *handle) { - struct nft_rule *r = NULL; + struct nftnl_rule *r = NULL; uint32_t destport; in_addr_t addr[2]; uint16_t port[2]; uint32_t descr_len; UNUSED(handle); - r = nft_rule_alloc(); + r = nftnl_rule_alloc(); if (r == NULL) { perror("OOM"); exit(EXIT_FAILURE); } - nft_rule_attr_set(r, NFT_RULE_ATTR_TABLE, NFT_TABLE_NAT); - nft_rule_attr_set(r, NFT_RULE_ATTR_CHAIN, miniupnpd_nft_peer_chain); + nftnl_rule_set(r, NFTNL_RULE_TABLE, NFT_TABLE_NAT); + nftnl_rule_set(r, NFTNL_RULE_CHAIN, miniupnpd_nft_peer_chain); if (descr != NULL) { descr_len = strlen(descr); - nft_rule_attr_set_data(r, NFT_RULE_ATTR_USERDATA, + nftnl_rule_set_data(r, NFTNL_RULE_USERDATA, descr, descr_len); } - nft_rule_attr_set_u32(r, NFT_RULE_ATTR_FAMILY, family); + nftnl_rule_set_u32(r, NFTNL_RULE_FAMILY, family); addr[0] = ihost; addr[1] = rhost; @@ -907,14 +907,14 @@ rule_set_snat(uint8_t family, uint8_t proto, /* * Todo: add expr for rhost */ -struct nft_rule * +struct nftnl_rule * rule_set_dnat(uint8_t family, const char * ifname, uint8_t proto, in_addr_t rhost, unsigned short eport, in_addr_t ihost, uint32_t iport, const char *descr, const char *handle) { - struct nft_rule *r = NULL; + struct nftnl_rule *r = NULL; uint16_t dport; uint64_t handle_num; uint32_t if_idx; @@ -923,24 +923,24 @@ rule_set_dnat(uint8_t family, const char * ifname, uint8_t proto, UNUSED(handle); UNUSED(rhost); - r = nft_rule_alloc(); + r = nftnl_rule_alloc(); if (r == NULL) { perror("OOM"); exit(EXIT_FAILURE); } - nft_rule_attr_set(r, NFT_RULE_ATTR_TABLE, NFT_TABLE_NAT); - nft_rule_attr_set(r, NFT_RULE_ATTR_CHAIN, miniupnpd_nft_nat_chain); - nft_rule_attr_set_u32(r, NFT_RULE_ATTR_FAMILY, family); + nftnl_rule_set(r, NFTNL_RULE_TABLE, NFT_TABLE_NAT); + nftnl_rule_set(r, NFTNL_RULE_CHAIN, miniupnpd_nft_nat_chain); + nftnl_rule_set_u32(r, NFTNL_RULE_FAMILY, family); if (descr != NULL) { descr_len = strlen(descr); - nft_rule_attr_set_data(r, NFT_RULE_ATTR_USERDATA, + nftnl_rule_set_data(r, NFTNL_RULE_USERDATA, descr, descr_len); } if (handle != NULL) { handle_num = atoll(handle); - nft_rule_attr_set_u64(r, NFT_RULE_ATTR_POSITION, handle_num); + nftnl_rule_set_u64(r, NFTNL_RULE_POSITION, handle_num); } if (ifname != NULL) { @@ -975,36 +975,36 @@ rule_set_dnat(uint8_t family, const char * ifname, uint8_t proto, return r; } -struct nft_rule * +struct nftnl_rule * rule_set_filter(uint8_t family, const char * ifname, uint8_t proto, in_addr_t rhost, in_addr_t iaddr, unsigned short eport, unsigned short iport, const char *descr, const char *handle) { - struct nft_rule *r = NULL; + struct nftnl_rule *r = NULL; uint16_t dport; uint64_t handle_num; uint32_t if_idx; uint32_t descr_len; UNUSED(eport); - r = nft_rule_alloc(); + r = nftnl_rule_alloc(); if (r == NULL) { perror("OOM"); exit(EXIT_FAILURE); } - nft_rule_attr_set(r, NFT_RULE_ATTR_TABLE, NFT_TABLE_FILTER); - nft_rule_attr_set(r, NFT_RULE_ATTR_CHAIN, miniupnpd_nft_forward_chain); - nft_rule_attr_set_u32(r, NFT_RULE_ATTR_FAMILY, family); + nftnl_rule_set(r, NFTNL_RULE_TABLE, NFT_TABLE_FILTER); + nftnl_rule_set(r, NFTNL_RULE_CHAIN, miniupnpd_nft_forward_chain); + nftnl_rule_set_u32(r, NFTNL_RULE_FAMILY, family); if (descr != NULL) { descr_len = strlen(descr); - nft_rule_attr_set_data(r, NFT_RULE_ATTR_USERDATA, + nftnl_rule_set_data(r, NFTNL_RULE_USERDATA, descr, descr_len); } if (handle != NULL) { handle_num = atoll(handle); - nft_rule_attr_set_u64(r, NFT_RULE_ATTR_POSITION, handle_num); + nftnl_rule_set_u64(r, NFTNL_RULE_POSITION, handle_num); } if (ifname != NULL) { @@ -1040,21 +1040,21 @@ rule_set_filter(uint8_t family, const char * ifname, uint8_t proto, return r; } -struct nft_rule * +struct nftnl_rule * rule_del_handle(rule_t *rule) { - struct nft_rule *r = NULL; + struct nftnl_rule *r = NULL; - r = nft_rule_alloc(); + r = nftnl_rule_alloc(); if (r == NULL) { perror("OOM"); exit(EXIT_FAILURE); } - nft_rule_attr_set(r, NFT_RULE_ATTR_TABLE, rule->table); - nft_rule_attr_set(r, NFT_RULE_ATTR_CHAIN, rule->chain); - nft_rule_attr_set_u32(r, NFT_RULE_ATTR_FAMILY, rule->family); - nft_rule_attr_set_u64(r, NFT_RULE_ATTR_HANDLE, rule->handle); + nftnl_rule_set(r, NFTNL_RULE_TABLE, rule->table); + nftnl_rule_set(r, NFTNL_RULE_CHAIN, rule->chain); + nftnl_rule_set_u32(r, NFTNL_RULE_FAMILY, rule->family); + nftnl_rule_set_u64(r, NFTNL_RULE_HANDLE, rule->handle); return r; } @@ -1077,7 +1077,7 @@ nft_mnl_batch_put(char *buf, uint16_t type, uint32_t seq) } int -nft_send_request(struct nft_rule * rule, uint16_t cmd) +nft_send_request(struct nftnl_rule * rule, uint16_t cmd) { struct nlmsghdr *nlh; struct mnl_nlmsg_batch *batch; @@ -1105,14 +1105,14 @@ nft_send_request(struct nft_rule * rule, uint16_t cmd) NFNL_MSG_BATCH_BEGIN, seq++); mnl_nlmsg_batch_next(batch); - nlh = nft_rule_nlmsg_build_hdr(mnl_nlmsg_batch_current(batch), + nlh = nftnl_rule_nlmsg_build_hdr(mnl_nlmsg_batch_current(batch), cmd, - nft_rule_attr_get_u32(rule, NFT_RULE_ATTR_FAMILY), + nftnl_rule_get_u32(rule, NFTNL_RULE_FAMILY), NLM_F_APPEND|NLM_F_CREATE|NLM_F_ACK, seq++); - nft_rule_nlmsg_build_payload(nlh, rule); - nft_rule_free(rule); + nftnl_rule_nlmsg_build_payload(nlh, rule); + nftnl_rule_free(rule); mnl_nlmsg_batch_next(batch); nft_mnl_batch_put(mnl_nlmsg_batch_current(batch), NFNL_MSG_BATCH_END, diff --git a/miniupnpd/netfilter_nft/nftnlrdr_misc.h b/miniupnpd/netfilter_nft/nftnlrdr_misc.h index e04403e..7f0a981 100644 --- a/miniupnpd/netfilter_nft/nftnlrdr_misc.h +++ b/miniupnpd/netfilter_nft/nftnlrdr_misc.h @@ -66,25 +66,25 @@ extern rule_t **peer_cache; extern rule_t **redirect_cache; int -nft_send_request(struct nft_rule * rule, uint16_t cmd); -struct nft_rule * +nft_send_request(struct nftnl_rule * rule, uint16_t cmd); +struct nftnl_rule * rule_set_dnat(uint8_t family, const char * ifname, uint8_t proto, in_addr_t rhost, unsigned short eport, in_addr_t ihost, uint32_t iport, const char *descr, const char *handle); -struct nft_rule * +struct nftnl_rule * rule_set_snat(uint8_t family, uint8_t proto, in_addr_t rhost, unsigned short rport, in_addr_t ehost, unsigned short eport, in_addr_t ihost, unsigned short iport, const char *descr, const char *handle); -struct nft_rule * +struct nftnl_rule * rule_set_filter(uint8_t family, const char * ifname, uint8_t proto, in_addr_t rhost, in_addr_t iaddr, unsigned short eport, unsigned short iport, const char * descr, const char *handle); -struct nft_rule * +struct nftnl_rule * rule_del_handle(rule_t *r); void reflesh_nft_cache(uint32_t family); From 181428e84397c990a13dfcb4535aa28da8087697 Mon Sep 17 00:00:00 2001 From: Nils Andreas Svee Date: Sat, 14 Jul 2018 19:59:26 +0200 Subject: [PATCH 2/2] miniupnpd: add update_portmappings functions for nft --- miniupnpd/netfilter_nft/nftnlrdr.c | 109 +++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) diff --git a/miniupnpd/netfilter_nft/nftnlrdr.c b/miniupnpd/netfilter_nft/nftnlrdr.c index 494685e..5392f9e 100644 --- a/miniupnpd/netfilter_nft/nftnlrdr.c +++ b/miniupnpd/netfilter_nft/nftnlrdr.c @@ -45,6 +45,16 @@ #define d_printf(x) #endif +/* list to keep timestamps for port mappings having a lease duration */ +struct timestamp_entry { + struct timestamp_entry * next; + unsigned int timestamp; + unsigned short eport; + short protocol; +}; + +static struct timestamp_entry * timestamp_list = NULL; + /* dummy init and shutdown functions */ int init_redirect(void) { @@ -56,6 +66,57 @@ void shutdown_redirect(void) return; } +static unsigned int +get_timestamp(unsigned short eport, int proto) +{ + struct timestamp_entry * e; + e = timestamp_list; + while(e) { + if(e->eport == eport && e->protocol == (short)proto) + return e->timestamp; + e = e->next; + } + return 0; +} + +static void +remove_timestamp_entry(unsigned short eport, int proto) +{ + struct timestamp_entry * e; + struct timestamp_entry * * p; + p = ×tamp_list; + e = *p; + while(e) { + if(e->eport == eport && e->protocol == (short)proto) { + /* remove the entry */ + *p = e->next; + free(e); + return; + } + p = &(e->next); + e = *p; + } +} + +static void +add_timestamp_entry(unsigned short eport, int proto, unsigned timestamp) +{ + struct timestamp_entry * tmp; + tmp = malloc(sizeof(struct timestamp_entry)); + if(tmp) + { + tmp->next = timestamp_list; + tmp->timestamp = timestamp; + tmp->eport = eport; + tmp->protocol = (short)proto; + timestamp_list = tmp; + } + else + { + syslog(LOG_ERR, "add_timestamp_entry() malloc(%lu) error", + sizeof(struct timestamp_entry)); + } +} int add_redirect_rule2(const char * ifname, @@ -327,6 +388,10 @@ get_redirect_rule_by_index(int index, strncpy(desc, r->desc, desclen); } + if (timestamp != NULL) { + *timestamp = get_timestamp(*eport, *proto); + } + /* * TODO: Implement counter in case of add {nat,filter} */ @@ -375,6 +440,10 @@ get_nat_redirect_rule(const char * nat_chain_name, const char * ifname, strncpy(desc, p->desc, desclen); } *iport = p->iport; + + if(timestamp != NULL) + *timestamp = get_timestamp(eport, proto); + return 0; } } @@ -431,6 +500,46 @@ get_portmappings_in_range(unsigned short startport, unsigned short endport, return array; } +int +update_portmapping_desc_timestamp(const char * ifname, + unsigned short eport, int proto, + const char * desc, unsigned int timestamp) +{ + UNUSED(ifname); + UNUSED(desc); + remove_timestamp_entry(eport, proto); + add_timestamp_entry(eport, proto, timestamp); + return 0; +} + +int +update_portmapping(const char * ifname, unsigned short eport, int proto, + unsigned short iport, const char * desc, + unsigned int timestamp) +{ + char iaddr[4]; + char iaddr_str[16]; + char rhost[32]; + int r; + + if (get_redirect_rule(NULL, eport, proto, iaddr, 0, NULL, NULL, 0, rhost, 0, NULL, 0, 0) < 0) + return -1; + + r = delete_redirect_and_filter_rules(eport, proto); + if (r < 0) + return -1; + + inet_ntop(AF_INET, &iaddr, iaddr_str, sizeof(iaddr_str)); + + if(add_redirect_rule2(ifname, rhost, eport, iaddr_str, iport, proto, + desc, timestamp) < 0) + return -1; + if(add_filter_rule2(ifname, rhost, iaddr_str, eport, iport, proto, desc) < 0) + return -1; + + return 0; +} + /* for debug */ /* read the "filter" and "nat" tables */ int