summaryrefslogtreecommitdiffstats
path: root/src/parse.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/parse.c')
-rw-r--r--src/parse.c153
1 files changed, 111 insertions, 42 deletions
diff --git a/src/parse.c b/src/parse.c
index b14e487..0184c5a 100644
--- a/src/parse.c
+++ b/src/parse.c
@@ -24,61 +24,127 @@
#define ssizeof(x) (int)sizeof(x)
#endif
-static void parse_u8(struct nf_conntrack *ct, int attr, void *data)
+static void parse_u8(struct nf_conntrack *ct, int attr, void *data);
+static void parse_u16(struct nf_conntrack *ct, int attr, void *data);
+static void parse_u32(struct nf_conntrack *ct, int attr, void *data);
+static void parse_group(struct nf_conntrack *ct, int attr, void *data);
+static void parse_nat_seq_adj(struct nf_conntrack *ct, int attr, void *data);
+
+struct parser {
+ void (*parse)(struct nf_conntrack *ct, int attr, void *data);
+ int attr;
+};
+
+static struct parser h[ATTR_MAX] = {
+ [NTA_IPV4] = {
+ .parse = parse_group,
+ .attr = ATTR_GRP_ORIG_IPV4,
+ },
+ [NTA_IPV6] = {
+ .parse = parse_group,
+ .attr = ATTR_GRP_ORIG_IPV6,
+ },
+ [NTA_PORT] = {
+ .parse = parse_group,
+ .attr = ATTR_GRP_ORIG_PORT,
+ },
+ [NTA_L4PROTO] = {
+ .parse = parse_u8,
+ .attr = ATTR_L4PROTO,
+ },
+ [NTA_STATE] = {
+ .parse = parse_u8,
+ .attr = ATTR_TCP_STATE,
+ },
+ [NTA_STATUS] = {
+ .parse = parse_u32,
+ .attr = ATTR_STATUS,
+ },
+ [NTA_MARK] = {
+ .parse = parse_u32,
+ .attr = ATTR_MARK,
+ },
+ [NTA_TIMEOUT] = {
+ .parse = parse_u32,
+ .attr = ATTR_TIMEOUT,
+ },
+ [NTA_MASTER_IPV4] = {
+ .parse = parse_group,
+ .attr = ATTR_GRP_MASTER_IPV4,
+ },
+ [NTA_MASTER_IPV6] = {
+ .parse = parse_group,
+ .attr = ATTR_GRP_MASTER_IPV6,
+ },
+ [NTA_MASTER_PORT] = {
+ .parse = parse_group,
+ .attr = ATTR_GRP_MASTER_PORT,
+ },
+ [NTA_SNAT_IPV4] = {
+ .parse = parse_u32,
+ .attr = ATTR_SNAT_IPV4,
+ },
+ [NTA_DNAT_IPV4] = {
+ .parse = parse_u32,
+ .attr = ATTR_DNAT_IPV4,
+ },
+ [NTA_SPAT_PORT] = {
+ .parse = parse_u16,
+ .attr = ATTR_SNAT_PORT,
+ },
+ [NTA_DPAT_PORT] = {
+ .parse = parse_u16,
+ .attr = ATTR_SNAT_PORT,
+ },
+ [NTA_NAT_SEQ_ADJ] = {
+ .parse = parse_nat_seq_adj,
+ },
+};
+
+static void
+parse_u8(struct nf_conntrack *ct, int attr, void *data)
{
uint8_t *value = (uint8_t *) data;
- nfct_set_attr_u8(ct, attr, *value);
+ nfct_set_attr_u8(ct, h[attr].attr, *value);
}
-static void parse_u16(struct nf_conntrack *ct, int attr, void *data)
+static void
+parse_u16(struct nf_conntrack *ct, int attr, void *data)
{
uint16_t *value = (uint16_t *) data;
- nfct_set_attr_u16(ct, attr, ntohs(*value));
+ nfct_set_attr_u16(ct, h[attr].attr, ntohs(*value));
}
-static void parse_u32(struct nf_conntrack *ct, int attr, void *data)
+static void
+parse_u32(struct nf_conntrack *ct, int attr, void *data)
{
uint32_t *value = (uint32_t *) data;
- nfct_set_attr_u32(ct, attr, ntohl(*value));
+ nfct_set_attr_u32(ct, h[attr].attr, ntohl(*value));
}
-static void parse_pointer_be(struct nf_conntrack *ct, int attr, void *data)
+static void
+parse_group(struct nf_conntrack *ct, int attr, void *data)
{
- nfct_set_attr(ct, attr, data);
+ nfct_set_attr_grp(ct, h[attr].attr, data);
}
-typedef void (*parse)(struct nf_conntrack *ct, int attr, void *data);
-
-static parse h[ATTR_MAX] = {
- [ATTR_IPV4_SRC] = parse_pointer_be,
- [ATTR_IPV4_DST] = parse_pointer_be,
- [ATTR_IPV6_SRC] = parse_pointer_be,
- [ATTR_IPV6_DST] = parse_pointer_be,
- [ATTR_L3PROTO] = parse_u8,
- [ATTR_PORT_SRC] = parse_u16,
- [ATTR_PORT_DST] = parse_u16,
- [ATTR_L4PROTO] = parse_u8,
- [ATTR_TCP_STATE] = parse_u8,
- [ATTR_SNAT_IPV4] = parse_u32,
- [ATTR_DNAT_IPV4] = parse_u32,
- [ATTR_SNAT_PORT] = parse_u16,
- [ATTR_DNAT_PORT] = parse_u16,
- [ATTR_TIMEOUT] = parse_u32,
- [ATTR_MARK] = parse_u32,
- [ATTR_STATUS] = parse_u32,
- [ATTR_MASTER_IPV4_SRC] = parse_u32,
- [ATTR_MASTER_IPV4_DST] = parse_u32,
- [ATTR_MASTER_L3PROTO] = parse_u8,
- [ATTR_MASTER_PORT_SRC] = parse_u16,
- [ATTR_MASTER_PORT_DST] = parse_u16,
- [ATTR_MASTER_L4PROTO] = parse_u8,
- [ATTR_ORIG_NAT_SEQ_CORRECTION_POS] = parse_u32,
- [ATTR_ORIG_NAT_SEQ_OFFSET_BEFORE] = parse_u32,
- [ATTR_ORIG_NAT_SEQ_OFFSET_AFTER] = parse_u32,
- [ATTR_REPL_NAT_SEQ_CORRECTION_POS] = parse_u32,
- [ATTR_REPL_NAT_SEQ_OFFSET_BEFORE] = parse_u32,
- [ATTR_REPL_NAT_SEQ_OFFSET_AFTER] = parse_u32,
-};
+static void
+parse_nat_seq_adj(struct nf_conntrack *ct, int attr, void *data)
+{
+ struct nta_attr_natseqadj *this = data;
+ nfct_set_attr_u32(ct, ATTR_ORIG_NAT_SEQ_CORRECTION_POS,
+ ntohl(this->orig_seq_correction_pos));
+ nfct_set_attr_u32(ct, ATTR_ORIG_NAT_SEQ_OFFSET_BEFORE,
+ ntohl(this->orig_seq_correction_pos));
+ nfct_set_attr_u32(ct, ATTR_ORIG_NAT_SEQ_OFFSET_AFTER,
+ ntohl(this->orig_seq_correction_pos));
+ nfct_set_attr_u32(ct, ATTR_REPL_NAT_SEQ_CORRECTION_POS,
+ ntohl(this->orig_seq_correction_pos));
+ nfct_set_attr_u32(ct, ATTR_REPL_NAT_SEQ_OFFSET_BEFORE,
+ ntohl(this->orig_seq_correction_pos));
+ nfct_set_attr_u32(ct, ATTR_REPL_NAT_SEQ_OFFSET_AFTER,
+ ntohl(this->orig_seq_correction_pos));
+}
int
parse_netpld(struct nf_conntrack *ct,
@@ -109,8 +175,11 @@ parse_netpld(struct nf_conntrack *ct,
ATTR_NETWORK2HOST(attr);
if (attr->nta_len > len)
return -1;
- if (h[attr->nta_attr])
- h[attr->nta_attr](ct, attr->nta_attr, NTA_DATA(attr));
+ if (h[attr->nta_attr].parse == NULL) {
+ attr = NTA_NEXT(attr, len);
+ continue;
+ }
+ h[attr->nta_attr].parse(ct, attr->nta_attr, NTA_DATA(attr));
attr = NTA_NEXT(attr, len);
}