libnftnl 1.3.2
expr/synproxy.c
1#include <stdio.h>
2#include <stdint.h>
3#include <string.h>
4#include <arpa/inet.h>
5#include <errno.h>
6#include <linux/netfilter/nf_tables.h>
7
8#include "internal.h"
9#include <libmnl/libmnl.h>
10#include <libnftnl/expr.h>
11#include <libnftnl/rule.h>
12
14 uint16_t mss;
15 uint8_t wscale;
16 uint32_t flags;
17};
18
19static int
20nftnl_expr_synproxy_set(struct nftnl_expr *e, uint16_t type,
21 const void *data, uint32_t data_len, uint32_t byteorder)
22{
23 struct nftnl_expr_synproxy *synproxy = nftnl_expr_data(e);
24
25 switch(type) {
26 case NFTNL_EXPR_SYNPROXY_MSS:
27 memcpy(&synproxy->mss, data, data_len);
28 break;
29 case NFTNL_EXPR_SYNPROXY_WSCALE:
30 memcpy(&synproxy->wscale, data, data_len);
31 break;
32 case NFTNL_EXPR_SYNPROXY_FLAGS:
33 memcpy(&synproxy->flags, data, data_len);
34 break;
35 }
36 return 0;
37}
38
39static const void *
40nftnl_expr_synproxy_get(const struct nftnl_expr *e, uint16_t type,
41 uint32_t *data_len)
42{
43 struct nftnl_expr_synproxy *synproxy = nftnl_expr_data(e);
44
45 switch(type) {
46 case NFTNL_EXPR_SYNPROXY_MSS:
47 *data_len = sizeof(synproxy->mss);
48 return &synproxy->mss;
49 case NFTNL_EXPR_SYNPROXY_WSCALE:
50 *data_len = sizeof(synproxy->wscale);
51 return &synproxy->wscale;
52 case NFTNL_EXPR_SYNPROXY_FLAGS:
53 *data_len = sizeof(synproxy->flags);
54 return &synproxy->flags;
55 }
56 return NULL;
57}
58
59static int nftnl_expr_synproxy_cb(const struct nlattr *attr, void *data)
60{
61 const struct nlattr **tb = data;
62 int type = mnl_attr_get_type(attr);
63
64 if (mnl_attr_type_valid(attr, NFTA_SYNPROXY_MAX) < 0)
65 return MNL_CB_OK;
66
67 switch(type) {
68 case NFTNL_EXPR_SYNPROXY_MSS:
69 if (mnl_attr_validate(attr, MNL_TYPE_U16) < 0)
70 abi_breakage();
71 break;
72
73 case NFTNL_EXPR_SYNPROXY_WSCALE:
74 if (mnl_attr_validate(attr, MNL_TYPE_U8) < 0)
75 abi_breakage();
76 break;
77
78 case NFTNL_EXPR_SYNPROXY_FLAGS:
79 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
80 abi_breakage();
81 break;
82 }
83
84 tb[type] = attr;
85 return MNL_CB_OK;
86}
87
88static void
89nftnl_expr_synproxy_build(struct nlmsghdr *nlh, const struct nftnl_expr *e)
90{
91 struct nftnl_expr_synproxy *synproxy = nftnl_expr_data(e);
92
93 if (e->flags & (1 << NFTNL_EXPR_SYNPROXY_MSS))
94 mnl_attr_put_u16(nlh, NFTA_SYNPROXY_MSS,
95 htons(synproxy->mss));
96 if (e->flags & (1 << NFTNL_EXPR_SYNPROXY_WSCALE))
97 mnl_attr_put_u8(nlh, NFTA_SYNPROXY_WSCALE,
98 synproxy->wscale);
99 if (e->flags & (1 << NFTNL_EXPR_SYNPROXY_FLAGS))
100 mnl_attr_put_u32(nlh, NFTA_SYNPROXY_FLAGS,
101 htonl(synproxy->flags));
102}
103
104static int
105nftnl_expr_synproxy_parse(struct nftnl_expr *e, struct nlattr *attr)
106{
107 struct nftnl_expr_synproxy *synproxy = nftnl_expr_data(e);
108 struct nlattr *tb[NFTA_SYNPROXY_MAX + 1] = {};
109
110 if (mnl_attr_parse_nested(attr, nftnl_expr_synproxy_cb, tb) < 0)
111 return -1;
112
113 if (tb[NFTA_SYNPROXY_MSS]) {
114 synproxy->mss = ntohs(mnl_attr_get_u16(tb[NFTA_SYNPROXY_MSS]));
115 e->flags |= (1 << NFTNL_EXPR_SYNPROXY_MSS);
116 }
117
118 if (tb[NFTA_SYNPROXY_WSCALE]) {
119 synproxy->wscale = mnl_attr_get_u8(tb[NFTA_SYNPROXY_WSCALE]);
120 e->flags |= (1 << NFTNL_EXPR_SYNPROXY_WSCALE);
121 }
122
123 if (tb[NFTA_SYNPROXY_FLAGS]) {
124 synproxy->flags = ntohl(mnl_attr_get_u32(tb[NFTA_SYNPROXY_FLAGS]));
125 e->flags |= (1 << NFTNL_EXPR_SYNPROXY_FLAGS);
126 }
127
128 return 0;
129}
130
131static int
132nftnl_expr_synproxy_snprintf(char *buf, size_t len,
133 uint32_t flags, const struct nftnl_expr *e)
134{
135 struct nftnl_expr_synproxy *synproxy = nftnl_expr_data(e);
136 int ret, offset = 0;
137
138 if (e->flags & (1 << NFTNL_EXPR_SYNPROXY_MSS) &&
139 e->flags & (1 << NFTNL_EXPR_SYNPROXY_WSCALE)) {
140 ret = snprintf(buf, len, "mss %u wscale %u ", synproxy->mss,
141 synproxy->wscale);
142 SNPRINTF_BUFFER_SIZE(ret, len, offset);
143 }
144
145 return offset;
146}
147
148static struct attr_policy synproxy_attr_policy[__NFTNL_EXPR_SYNPROXY_MAX] = {
149 [NFTNL_EXPR_SYNPROXY_MSS] = { .maxlen = sizeof(uint16_t) },
150 [NFTNL_EXPR_SYNPROXY_WSCALE] = { .maxlen = sizeof(uint8_t) },
151 [NFTNL_EXPR_SYNPROXY_FLAGS] = { .maxlen = sizeof(uint32_t) },
152};
153
154struct expr_ops expr_ops_synproxy = {
155 .name = "synproxy",
156 .alloc_len = sizeof(struct nftnl_expr_synproxy),
157 .nftnl_max_attr = __NFTNL_EXPR_SYNPROXY_MAX - 1,
158 .attr_policy = synproxy_attr_policy,
159 .set = nftnl_expr_synproxy_set,
160 .get = nftnl_expr_synproxy_get,
161 .parse = nftnl_expr_synproxy_parse,
162 .build = nftnl_expr_synproxy_build,
163 .output = nftnl_expr_synproxy_snprintf,
164};