netfilter_nft: rule_t: have src/dst/nat addresses and ports
instead of guessing if it is remote host / external or internal address...
This commit is contained in:
parent
25206a7a3f
commit
90fb7801eb
|
@ -292,7 +292,7 @@ delete_filter_rule(const char * ifname, unsigned short port, int proto)
|
|||
|
||||
refresh_nft_cache_filter();
|
||||
LIST_FOREACH(p, &head_filter, entry) {
|
||||
if (p->eport == port && p->proto == proto && p->type == RULE_FILTER) {
|
||||
if (p->dport == port && p->proto == proto && p->type == RULE_FILTER) {
|
||||
r = rule_del_handle(p);
|
||||
nft_send_rule(r, NFT_MSG_DELRULE, RULE_CHAIN_FILTER);
|
||||
break;
|
||||
|
@ -318,10 +318,10 @@ delete_redirect_and_filter_rules(unsigned short eport, int proto)
|
|||
|
||||
// Delete Redirect Rule
|
||||
LIST_FOREACH(p, &head_redirect, entry) {
|
||||
if (p->eport == eport && p->proto == proto &&
|
||||
if (p->dport == eport && p->proto == proto &&
|
||||
(p->type == RULE_NAT && p->nat_type == NFT_NAT_DNAT)) {
|
||||
iaddr = p->iaddr;
|
||||
iport = p->iport;
|
||||
iaddr = p->nat_addr;
|
||||
iport = p->nat_port;
|
||||
|
||||
r = rule_del_handle(p);
|
||||
/* Todo: send bulk request */
|
||||
|
@ -334,8 +334,8 @@ delete_redirect_and_filter_rules(unsigned short eport, int proto)
|
|||
refresh_nft_cache_filter();
|
||||
// Delete Forward Rule
|
||||
LIST_FOREACH(p, &head_filter, entry) {
|
||||
if (p->eport == iport &&
|
||||
p->iaddr == iaddr && p->type == RULE_FILTER) {
|
||||
if (p->nat_port == iport &&
|
||||
p->nat_addr == iaddr && p->type == RULE_FILTER) {
|
||||
r = rule_del_handle(p);
|
||||
/* Todo: send bulk request */
|
||||
nft_send_rule(r, NFT_MSG_DELRULE, RULE_CHAIN_FILTER);
|
||||
|
@ -350,10 +350,10 @@ delete_redirect_and_filter_rules(unsigned short eport, int proto)
|
|||
refresh_nft_cache_peer();
|
||||
// Delete Peer Rule
|
||||
LIST_FOREACH(p, &head_peer, entry) {
|
||||
if (p->eport == eport && p->proto == proto &&
|
||||
if (p->nat_port == eport && p->proto == proto &&
|
||||
(p->type == RULE_NAT && p->nat_type == NFT_NAT_SNAT)) {
|
||||
iaddr = p->iaddr;
|
||||
iport = p->iport;
|
||||
iaddr = p->daddr;
|
||||
iport = p->dport;
|
||||
|
||||
r = rule_del_handle(p);
|
||||
/* Todo: send bulk request */
|
||||
|
@ -366,8 +366,8 @@ delete_redirect_and_filter_rules(unsigned short eport, int proto)
|
|||
refresh_nft_cache_filter();
|
||||
// Delete Forward Rule
|
||||
LIST_FOREACH(p, &head_filter, entry) {
|
||||
if (p->eport == iport &&
|
||||
p->iaddr == iaddr && p->type == RULE_FILTER) {
|
||||
if (p->dport == iport &&
|
||||
p->daddr == iaddr && p->type == RULE_FILTER) {
|
||||
r = rule_del_handle(p);
|
||||
/* Todo: send bulk request */
|
||||
nft_send_rule(r, NFT_MSG_DELRULE, RULE_CHAIN_FILTER);
|
||||
|
@ -405,18 +405,18 @@ get_peer_rule_by_index(int index,
|
|||
}
|
||||
|
||||
if (eport != NULL) {
|
||||
*eport = r->eport;
|
||||
*eport = r->nat_port;
|
||||
}
|
||||
|
||||
if (iaddr != NULL) {
|
||||
if (inet_ntop(AF_INET, &r->iaddr, iaddr, iaddrlen) == NULL) {
|
||||
if (inet_ntop(AF_INET, &r->daddr, iaddr, iaddrlen) == NULL) {
|
||||
syslog(LOG_ERR, "%s: inet_ntop: %m",
|
||||
"get_peer_rule_by_index");
|
||||
}
|
||||
}
|
||||
|
||||
if (iport != NULL) {
|
||||
*iport = r->iport;
|
||||
*iport = r->dport;
|
||||
}
|
||||
|
||||
if (proto != NULL) {
|
||||
|
@ -424,8 +424,8 @@ get_peer_rule_by_index(int index,
|
|||
}
|
||||
|
||||
if (rhost != NULL) {
|
||||
if (r->rhost) {
|
||||
if (inet_ntop(AF_INET, &r->rhost, rhost, rhostlen) == NULL) {
|
||||
if (r->saddr) {
|
||||
if (inet_ntop(AF_INET, &r->saddr, rhost, rhostlen) == NULL) {
|
||||
syslog(LOG_ERR, "%s: inet_ntop: %m",
|
||||
"get_peer_rule_by_index");
|
||||
}
|
||||
|
@ -435,7 +435,7 @@ get_peer_rule_by_index(int index,
|
|||
}
|
||||
|
||||
if (rport != NULL) {
|
||||
*rport = r->rport;
|
||||
*rport = r->sport;
|
||||
}
|
||||
|
||||
if (desc != NULL) {
|
||||
|
@ -450,7 +450,7 @@ get_peer_rule_by_index(int index,
|
|||
}
|
||||
|
||||
if (timestamp) {
|
||||
*timestamp = get_timestamp(r->eport, r->proto);
|
||||
*timestamp = get_timestamp(r->dport, r->proto);
|
||||
}
|
||||
/*
|
||||
* TODO: Implement counter in case of add {nat,filter}
|
||||
|
@ -524,18 +524,18 @@ get_redirect_rule_by_index(int index,
|
|||
}
|
||||
|
||||
if (eport != NULL) {
|
||||
*eport = r->eport;
|
||||
*eport = r->dport;
|
||||
}
|
||||
|
||||
if (iaddr != NULL) {
|
||||
if (inet_ntop(AF_INET, &r->iaddr, iaddr, iaddrlen) == NULL) {
|
||||
if (inet_ntop(AF_INET, &r->nat_addr, iaddr, iaddrlen) == NULL) {
|
||||
syslog(LOG_ERR, "%s: inet_ntop: %m",
|
||||
"get_redirect_rule_by_index");
|
||||
}
|
||||
}
|
||||
|
||||
if (iport != NULL) {
|
||||
*iport = r->iport;
|
||||
*iport = r->nat_port;
|
||||
}
|
||||
|
||||
if (proto != NULL) {
|
||||
|
@ -543,8 +543,8 @@ get_redirect_rule_by_index(int index,
|
|||
}
|
||||
|
||||
if (rhost != NULL) {
|
||||
if (r->rhost) {
|
||||
if (inet_ntop(AF_INET, &r->rhost, rhost, rhostlen) == NULL) {
|
||||
if (r->saddr) {
|
||||
if (inet_ntop(AF_INET, &r->saddr, rhost, rhostlen) == NULL) {
|
||||
syslog(LOG_ERR, "%s: inet_ntop: %m",
|
||||
"get_redirect_rule_by_index");
|
||||
}
|
||||
|
@ -604,10 +604,10 @@ get_nat_redirect_rule(const char * nat_chain_name, const char * ifname,
|
|||
|
||||
LIST_FOREACH(p, &head_redirect, entry) {
|
||||
if (p->proto == proto &&
|
||||
p->eport == eport) {
|
||||
p->dport == eport) {
|
||||
|
||||
if (p->iaddr && iaddr) {
|
||||
addr.s_addr = p->iaddr;
|
||||
if (p->nat_addr && iaddr) {
|
||||
addr.s_addr = p->nat_addr;
|
||||
if (inet_ntop(AF_INET, &addr, iaddr, iaddrlen) == NULL) {
|
||||
syslog(LOG_ERR, "%s: inet_ntop: %m",
|
||||
"get_nat_redirect_rule");
|
||||
|
@ -619,7 +619,7 @@ get_nat_redirect_rule(const char * nat_chain_name, const char * ifname,
|
|||
}
|
||||
|
||||
if (iport)
|
||||
*iport = p->iport;
|
||||
*iport = p->nat_port;
|
||||
|
||||
if(timestamp != NULL)
|
||||
*timestamp = get_timestamp(eport, proto);
|
||||
|
@ -659,8 +659,8 @@ get_portmappings_in_range(unsigned short startport, unsigned short endport,
|
|||
|
||||
LIST_FOREACH(p, &head_redirect, entry) {
|
||||
if (p->proto == proto &&
|
||||
startport <= p->eport &&
|
||||
p->eport <= endport) {
|
||||
startport <= p->dport &&
|
||||
p->dport <= endport) {
|
||||
|
||||
if (*number >= capacity) {
|
||||
capacity += 128;
|
||||
|
@ -677,7 +677,7 @@ get_portmappings_in_range(unsigned short startport, unsigned short endport,
|
|||
}
|
||||
array = tmp;
|
||||
}
|
||||
array[*number] = p->eport;
|
||||
array[*number] = p->dport;
|
||||
(*number)++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -129,8 +129,8 @@ void
|
|||
print_rule_t(const char *func, int line, const rule_t *r)
|
||||
{
|
||||
fprintf(stdout, "%s[%d]: ", func, line);
|
||||
printf("%s %s %d %hu => %hu\n", r->table, r->chain, (int)r->type,
|
||||
r->eport, r->iport);
|
||||
printf("%s %s %d %hu => %hu => %hu\n", r->table, r->chain, (int)r->type,
|
||||
r->sport, r->dport, r->nat_port);
|
||||
}
|
||||
|
||||
/* print out the "filter" and "nat" tables */
|
||||
|
@ -300,14 +300,9 @@ parse_rule_nat(struct nftnl_expr *e, rule_t *r)
|
|||
}
|
||||
reg_val_ptr = get_reg_val_ptr(r, addr_min_reg);
|
||||
if (reg_val_ptr != NULL) {
|
||||
if (r->nat_type == NFT_NAT_DNAT) {
|
||||
r->iaddr = (in_addr_t)*reg_val_ptr;
|
||||
r->iport = proto_min_val;
|
||||
} else if (r->nat_type == NFT_NAT_SNAT) {
|
||||
r->eaddr = (in_addr_t)*reg_val_ptr;
|
||||
if (proto_min_reg == NFT_REG_1) {
|
||||
r->eport = proto_min_val;
|
||||
}
|
||||
r->nat_addr = (in_addr_t)*reg_val_ptr;
|
||||
if (proto_min_reg == NFT_REG_1) {
|
||||
r->nat_port = proto_min_val;
|
||||
}
|
||||
} else {
|
||||
syslog(LOG_ERR, "%s: invalid addr_min_reg %u", "parse_rule_nat", addr_min_reg);
|
||||
|
@ -371,6 +366,9 @@ parse_rule_payload(struct nftnl_expr *e, rule_t *r)
|
|||
if (offset == offsetof(struct tcphdr, dest) &&
|
||||
len == sizeof(uint16_t)) {
|
||||
*regptr = RULE_REG_TCP_DPORT;
|
||||
} else if (offset == offsetof(struct tcphdr, source) &&
|
||||
len == sizeof(uint16_t)) {
|
||||
*regptr = RULE_REG_TCP_SPORT;
|
||||
} else if (offset == offsetof(struct tcphdr, source) &&
|
||||
len == sizeof(uint16_t) * 2) {
|
||||
*regptr = RULE_REG_TCP_SD_PORT;
|
||||
|
@ -428,44 +426,36 @@ parse_rule_cmp(struct nftnl_expr *e, rule_t *r)
|
|||
break;
|
||||
case RULE_REG_IP_SRC_ADDR:
|
||||
if (data_len == sizeof(in_addr_t)) {
|
||||
r->rhost = *(const in_addr_t *)data_val;
|
||||
r->saddr = *(const in_addr_t *)data_val;
|
||||
}
|
||||
break;
|
||||
case RULE_REG_IP6_SRC_ADDR:
|
||||
if (data_len == sizeof(struct in6_addr)) {
|
||||
r->rhost6 = *(const struct in6_addr *)data_val;
|
||||
r->saddr6 = *(const struct in6_addr *)data_val;
|
||||
}
|
||||
break;
|
||||
case RULE_REG_IP_DEST_ADDR:
|
||||
if (data_len == sizeof(in_addr_t)) {
|
||||
if (r->type == RULE_FILTER) {
|
||||
r->iaddr = *(const in_addr_t *)data_val;
|
||||
} else {
|
||||
r->rhost = *(const in_addr_t *)data_val;
|
||||
}
|
||||
r->daddr = *(const in_addr_t *)data_val;
|
||||
}
|
||||
break;
|
||||
case RULE_REG_IP6_DEST_ADDR:
|
||||
if (data_len == sizeof(struct in6_addr)) {
|
||||
if (r->type == RULE_FILTER) {
|
||||
r->iaddr6 = *(const struct in6_addr *)data_val;
|
||||
} else {
|
||||
r->rhost6 = *(const struct in6_addr *)data_val;
|
||||
}
|
||||
r->daddr6 = *(const struct in6_addr *)data_val;
|
||||
}
|
||||
break;
|
||||
case RULE_REG_IP_SD_ADDR:
|
||||
if (data_len == sizeof(in_addr_t) * 2) {
|
||||
const in_addr_t *addrp = (const in_addr_t *)data_val;
|
||||
r->iaddr = addrp[0];
|
||||
r->rhost = addrp[1];
|
||||
r->saddr = addrp[0];
|
||||
r->daddr = addrp[1];
|
||||
}
|
||||
break;
|
||||
case RULE_REG_IP6_SD_ADDR:
|
||||
if (data_len == sizeof(struct in6_addr) * 2) {
|
||||
const struct in6_addr *addrp6 = (const struct in6_addr *)data_val;
|
||||
r->iaddr6 = addrp6[0];
|
||||
r->rhost6 = addrp6[1];
|
||||
r->saddr6 = addrp6[0];
|
||||
r->daddr6 = addrp6[1];
|
||||
}
|
||||
break;
|
||||
case RULE_REG_IP_PROTO:
|
||||
|
@ -474,16 +464,21 @@ parse_rule_cmp(struct nftnl_expr *e, rule_t *r)
|
|||
r->proto = *(const uint8_t *)data_val;
|
||||
}
|
||||
break;
|
||||
case RULE_REG_TCP_SPORT:
|
||||
if (data_len == sizeof(uint16_t)) {
|
||||
r->sport = ntohs(*(const uint16_t *)data_val);
|
||||
}
|
||||
break;
|
||||
case RULE_REG_TCP_DPORT:
|
||||
if (data_len == sizeof(uint16_t)) {
|
||||
r->eport = ntohs(*(const uint16_t *)data_val);
|
||||
r->dport = ntohs(*(const uint16_t *)data_val);
|
||||
}
|
||||
break;
|
||||
case RULE_REG_TCP_SD_PORT:
|
||||
if (data_len == sizeof(uint16_t) * 2) {
|
||||
const uint16_t * ports = (const uint16_t *)data_val;
|
||||
r->eport = ntohs(ports[0]);
|
||||
r->rport = ntohs(ports[1]);
|
||||
r->sport = ntohs(ports[0]);
|
||||
r->dport = ntohs(ports[1]);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -33,6 +33,7 @@ enum rule_reg_type {
|
|||
RULE_REG_IP6_SD_ADDR, /* source & dest */
|
||||
RULE_REG_IP_PROTO,
|
||||
RULE_REG_IP6_PROTO,
|
||||
RULE_REG_TCP_SPORT,
|
||||
RULE_REG_TCP_DPORT,
|
||||
RULE_REG_TCP_SD_PORT, /* source & dest */
|
||||
RULE_REG_IMM_VAL, /* immediate */
|
||||
|
@ -63,14 +64,14 @@ typedef struct rule_t {
|
|||
uint32_t family;
|
||||
uint32_t ingress_ifidx;
|
||||
uint32_t egress_ifidx;
|
||||
in_addr_t eaddr;
|
||||
in_addr_t iaddr;
|
||||
in_addr_t rhost;
|
||||
struct in6_addr iaddr6;
|
||||
struct in6_addr rhost6;
|
||||
uint16_t eport;
|
||||
uint16_t iport;
|
||||
uint16_t rport;
|
||||
in_addr_t saddr;
|
||||
struct in6_addr saddr6;
|
||||
uint16_t sport;
|
||||
in_addr_t daddr;
|
||||
struct in6_addr daddr6;
|
||||
uint16_t dport;
|
||||
in_addr_t nat_addr;
|
||||
uint16_t nat_port;
|
||||
uint8_t proto;
|
||||
enum rule_reg_type reg1_type;
|
||||
enum rule_reg_type reg2_type;
|
||||
|
|
|
@ -153,10 +153,10 @@ find_pinhole(const char * ifname,
|
|||
if (p->desc_len == 0)
|
||||
continue;
|
||||
|
||||
if ((proto == p->proto) && (rem_port == p->rport)
|
||||
&& (0 == memcmp(&saddr, &p->rhost6, sizeof(struct in6_addr)))
|
||||
&& (int_port == p->iport) &&
|
||||
(0 == memcmp(&daddr, &p->iaddr6, sizeof(struct in6_addr)))) {
|
||||
if ((proto == p->proto) && (rem_port == p->sport)
|
||||
&& (0 == memcmp(&saddr, &p->saddr6, sizeof(struct in6_addr)))
|
||||
&& (int_port == p->dport) &&
|
||||
(0 == memcmp(&daddr, &p->daddr6, sizeof(struct in6_addr)))) {
|
||||
|
||||
if (sscanf(p->desc, PINEHOLE_LABEL_FORMAT_SKIPDESC, &uid, &ts) != 2) {
|
||||
syslog(LOG_DEBUG, "rule with label '%s' is not a IGD pinhole", p->desc);
|
||||
|
@ -259,23 +259,23 @@ update_pinhole(unsigned short uid, unsigned int timestamp)
|
|||
if (0 == strcmp(tmp_label, label_start)) {
|
||||
/* Source IP Address */
|
||||
// Check if empty
|
||||
if (0 == memcmp(&rhost_addr, &p->rhost6, sizeof(struct in6_addr))) {
|
||||
if (0 == memcmp(&rhost_addr, &p->saddr6, sizeof(struct in6_addr))) {
|
||||
rhost_addr_p = NULL;
|
||||
raddr[0] = '*';
|
||||
raddr[1] = '\0';
|
||||
} else {
|
||||
rhost_addr_p = &p->rhost6;
|
||||
rhost_addr_p = &p->saddr6;
|
||||
inet_ntop(AF_INET6, rhost_addr_p, raddr, INET6_ADDRSTRLEN);
|
||||
}
|
||||
|
||||
/* Source Port */
|
||||
rport = p->iport;
|
||||
rport = p->sport;
|
||||
|
||||
/* Destination IP Address */
|
||||
ihost_addr = p->iaddr6;
|
||||
ihost_addr = p->daddr6;
|
||||
|
||||
/* Destination Port */
|
||||
iport = p->eport;
|
||||
iport = p->dport;
|
||||
|
||||
proto = p->proto;
|
||||
|
||||
|
@ -357,23 +357,23 @@ get_pinhole_info(unsigned short uid,
|
|||
if (0 == strcmp(tmp_label, label_start)) {
|
||||
/* Source IP Address */
|
||||
if (rem_host && (rem_host[0] != '\0')) {
|
||||
if(inet_ntop(AF_INET6, &p->rhost6, rem_host, rem_hostlen) == NULL)
|
||||
if(inet_ntop(AF_INET6, &p->saddr6, rem_host, rem_hostlen) == NULL)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Source Port */
|
||||
if (rem_port)
|
||||
*rem_port = p->rport;
|
||||
*rem_port = p->sport;
|
||||
|
||||
/* Destination IP Address */
|
||||
if (int_client) {
|
||||
if(inet_ntop(AF_INET6, &p->iaddr6, int_client, int_clientlen) == NULL)
|
||||
if(inet_ntop(AF_INET6, &p->daddr6, int_client, int_clientlen) == NULL)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Destination Port */
|
||||
if (int_port)
|
||||
*int_port = p->eport;
|
||||
*int_port = p->dport;
|
||||
|
||||
if (proto)
|
||||
*proto = p->proto;
|
||||
|
|
Loading…
Reference in New Issue