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