1*a71a9546SAutomerger Merge Worker /*
2*a71a9546SAutomerger Merge Worker * Shared library add-on to iptables to add early socket matching support.
3*a71a9546SAutomerger Merge Worker *
4*a71a9546SAutomerger Merge Worker * Copyright (C) 2007 BalaBit IT Ltd.
5*a71a9546SAutomerger Merge Worker */
6*a71a9546SAutomerger Merge Worker #include <stdio.h>
7*a71a9546SAutomerger Merge Worker #include <xtables.h>
8*a71a9546SAutomerger Merge Worker #include <linux/netfilter/xt_socket.h>
9*a71a9546SAutomerger Merge Worker
10*a71a9546SAutomerger Merge Worker enum {
11*a71a9546SAutomerger Merge Worker O_TRANSPARENT = 0,
12*a71a9546SAutomerger Merge Worker O_NOWILDCARD = 1,
13*a71a9546SAutomerger Merge Worker O_RESTORESKMARK = 2,
14*a71a9546SAutomerger Merge Worker };
15*a71a9546SAutomerger Merge Worker
16*a71a9546SAutomerger Merge Worker static const struct xt_option_entry socket_mt_opts[] = {
17*a71a9546SAutomerger Merge Worker {.name = "transparent", .id = O_TRANSPARENT, .type = XTTYPE_NONE},
18*a71a9546SAutomerger Merge Worker XTOPT_TABLEEND,
19*a71a9546SAutomerger Merge Worker };
20*a71a9546SAutomerger Merge Worker
21*a71a9546SAutomerger Merge Worker static const struct xt_option_entry socket_mt_opts_v2[] = {
22*a71a9546SAutomerger Merge Worker {.name = "transparent", .id = O_TRANSPARENT, .type = XTTYPE_NONE},
23*a71a9546SAutomerger Merge Worker {.name = "nowildcard", .id = O_NOWILDCARD, .type = XTTYPE_NONE},
24*a71a9546SAutomerger Merge Worker XTOPT_TABLEEND,
25*a71a9546SAutomerger Merge Worker };
26*a71a9546SAutomerger Merge Worker
27*a71a9546SAutomerger Merge Worker static const struct xt_option_entry socket_mt_opts_v3[] = {
28*a71a9546SAutomerger Merge Worker {.name = "transparent", .id = O_TRANSPARENT, .type = XTTYPE_NONE},
29*a71a9546SAutomerger Merge Worker {.name = "nowildcard", .id = O_NOWILDCARD, .type = XTTYPE_NONE},
30*a71a9546SAutomerger Merge Worker {.name = "restore-skmark", .id = O_RESTORESKMARK, .type = XTTYPE_NONE},
31*a71a9546SAutomerger Merge Worker XTOPT_TABLEEND,
32*a71a9546SAutomerger Merge Worker };
33*a71a9546SAutomerger Merge Worker
socket_mt_help(void)34*a71a9546SAutomerger Merge Worker static void socket_mt_help(void)
35*a71a9546SAutomerger Merge Worker {
36*a71a9546SAutomerger Merge Worker printf(
37*a71a9546SAutomerger Merge Worker "socket match options:\n"
38*a71a9546SAutomerger Merge Worker " --transparent Ignore non-transparent sockets\n\n");
39*a71a9546SAutomerger Merge Worker }
40*a71a9546SAutomerger Merge Worker
socket_mt_help_v2(void)41*a71a9546SAutomerger Merge Worker static void socket_mt_help_v2(void)
42*a71a9546SAutomerger Merge Worker {
43*a71a9546SAutomerger Merge Worker printf(
44*a71a9546SAutomerger Merge Worker "socket match options:\n"
45*a71a9546SAutomerger Merge Worker " --nowildcard Do not ignore LISTEN sockets bound on INADDR_ANY\n"
46*a71a9546SAutomerger Merge Worker " --transparent Ignore non-transparent sockets\n\n");
47*a71a9546SAutomerger Merge Worker }
48*a71a9546SAutomerger Merge Worker
socket_mt_help_v3(void)49*a71a9546SAutomerger Merge Worker static void socket_mt_help_v3(void)
50*a71a9546SAutomerger Merge Worker {
51*a71a9546SAutomerger Merge Worker printf(
52*a71a9546SAutomerger Merge Worker "socket match options:\n"
53*a71a9546SAutomerger Merge Worker " --nowildcard Do not ignore LISTEN sockets bound on INADDR_ANY\n"
54*a71a9546SAutomerger Merge Worker " --transparent Ignore non-transparent sockets\n"
55*a71a9546SAutomerger Merge Worker " --restore-skmark Set the packet mark to the socket mark if\n"
56*a71a9546SAutomerger Merge Worker " the socket matches and transparent / \n"
57*a71a9546SAutomerger Merge Worker " nowildcard conditions are satisfied\n\n");
58*a71a9546SAutomerger Merge Worker }
59*a71a9546SAutomerger Merge Worker
socket_mt_parse(struct xt_option_call * cb)60*a71a9546SAutomerger Merge Worker static void socket_mt_parse(struct xt_option_call *cb)
61*a71a9546SAutomerger Merge Worker {
62*a71a9546SAutomerger Merge Worker struct xt_socket_mtinfo1 *info = cb->data;
63*a71a9546SAutomerger Merge Worker
64*a71a9546SAutomerger Merge Worker xtables_option_parse(cb);
65*a71a9546SAutomerger Merge Worker switch (cb->entry->id) {
66*a71a9546SAutomerger Merge Worker case O_TRANSPARENT:
67*a71a9546SAutomerger Merge Worker info->flags |= XT_SOCKET_TRANSPARENT;
68*a71a9546SAutomerger Merge Worker break;
69*a71a9546SAutomerger Merge Worker }
70*a71a9546SAutomerger Merge Worker }
71*a71a9546SAutomerger Merge Worker
socket_mt_parse_v2(struct xt_option_call * cb)72*a71a9546SAutomerger Merge Worker static void socket_mt_parse_v2(struct xt_option_call *cb)
73*a71a9546SAutomerger Merge Worker {
74*a71a9546SAutomerger Merge Worker struct xt_socket_mtinfo2 *info = cb->data;
75*a71a9546SAutomerger Merge Worker
76*a71a9546SAutomerger Merge Worker xtables_option_parse(cb);
77*a71a9546SAutomerger Merge Worker switch (cb->entry->id) {
78*a71a9546SAutomerger Merge Worker case O_TRANSPARENT:
79*a71a9546SAutomerger Merge Worker info->flags |= XT_SOCKET_TRANSPARENT;
80*a71a9546SAutomerger Merge Worker break;
81*a71a9546SAutomerger Merge Worker case O_NOWILDCARD:
82*a71a9546SAutomerger Merge Worker info->flags |= XT_SOCKET_NOWILDCARD;
83*a71a9546SAutomerger Merge Worker break;
84*a71a9546SAutomerger Merge Worker }
85*a71a9546SAutomerger Merge Worker }
86*a71a9546SAutomerger Merge Worker
socket_mt_parse_v3(struct xt_option_call * cb)87*a71a9546SAutomerger Merge Worker static void socket_mt_parse_v3(struct xt_option_call *cb)
88*a71a9546SAutomerger Merge Worker {
89*a71a9546SAutomerger Merge Worker struct xt_socket_mtinfo2 *info = cb->data;
90*a71a9546SAutomerger Merge Worker
91*a71a9546SAutomerger Merge Worker xtables_option_parse(cb);
92*a71a9546SAutomerger Merge Worker switch (cb->entry->id) {
93*a71a9546SAutomerger Merge Worker case O_TRANSPARENT:
94*a71a9546SAutomerger Merge Worker info->flags |= XT_SOCKET_TRANSPARENT;
95*a71a9546SAutomerger Merge Worker break;
96*a71a9546SAutomerger Merge Worker case O_NOWILDCARD:
97*a71a9546SAutomerger Merge Worker info->flags |= XT_SOCKET_NOWILDCARD;
98*a71a9546SAutomerger Merge Worker break;
99*a71a9546SAutomerger Merge Worker case O_RESTORESKMARK:
100*a71a9546SAutomerger Merge Worker info->flags |= XT_SOCKET_RESTORESKMARK;
101*a71a9546SAutomerger Merge Worker break;
102*a71a9546SAutomerger Merge Worker }
103*a71a9546SAutomerger Merge Worker }
104*a71a9546SAutomerger Merge Worker
105*a71a9546SAutomerger Merge Worker static void
socket_mt_save(const void * ip,const struct xt_entry_match * match)106*a71a9546SAutomerger Merge Worker socket_mt_save(const void *ip, const struct xt_entry_match *match)
107*a71a9546SAutomerger Merge Worker {
108*a71a9546SAutomerger Merge Worker const struct xt_socket_mtinfo1 *info = (const void *)match->data;
109*a71a9546SAutomerger Merge Worker
110*a71a9546SAutomerger Merge Worker if (info->flags & XT_SOCKET_TRANSPARENT)
111*a71a9546SAutomerger Merge Worker printf(" --transparent");
112*a71a9546SAutomerger Merge Worker }
113*a71a9546SAutomerger Merge Worker
114*a71a9546SAutomerger Merge Worker static void
socket_mt_print(const void * ip,const struct xt_entry_match * match,int numeric)115*a71a9546SAutomerger Merge Worker socket_mt_print(const void *ip, const struct xt_entry_match *match,
116*a71a9546SAutomerger Merge Worker int numeric)
117*a71a9546SAutomerger Merge Worker {
118*a71a9546SAutomerger Merge Worker printf(" socket");
119*a71a9546SAutomerger Merge Worker socket_mt_save(ip, match);
120*a71a9546SAutomerger Merge Worker }
121*a71a9546SAutomerger Merge Worker
122*a71a9546SAutomerger Merge Worker static void
socket_mt_save_v2(const void * ip,const struct xt_entry_match * match)123*a71a9546SAutomerger Merge Worker socket_mt_save_v2(const void *ip, const struct xt_entry_match *match)
124*a71a9546SAutomerger Merge Worker {
125*a71a9546SAutomerger Merge Worker const struct xt_socket_mtinfo2 *info = (const void *)match->data;
126*a71a9546SAutomerger Merge Worker
127*a71a9546SAutomerger Merge Worker if (info->flags & XT_SOCKET_TRANSPARENT)
128*a71a9546SAutomerger Merge Worker printf(" --transparent");
129*a71a9546SAutomerger Merge Worker if (info->flags & XT_SOCKET_NOWILDCARD)
130*a71a9546SAutomerger Merge Worker printf(" --nowildcard");
131*a71a9546SAutomerger Merge Worker }
132*a71a9546SAutomerger Merge Worker
133*a71a9546SAutomerger Merge Worker static void
socket_mt_print_v2(const void * ip,const struct xt_entry_match * match,int numeric)134*a71a9546SAutomerger Merge Worker socket_mt_print_v2(const void *ip, const struct xt_entry_match *match,
135*a71a9546SAutomerger Merge Worker int numeric)
136*a71a9546SAutomerger Merge Worker {
137*a71a9546SAutomerger Merge Worker printf(" socket");
138*a71a9546SAutomerger Merge Worker socket_mt_save_v2(ip, match);
139*a71a9546SAutomerger Merge Worker }
140*a71a9546SAutomerger Merge Worker
141*a71a9546SAutomerger Merge Worker static void
socket_mt_save_v3(const void * ip,const struct xt_entry_match * match)142*a71a9546SAutomerger Merge Worker socket_mt_save_v3(const void *ip, const struct xt_entry_match *match)
143*a71a9546SAutomerger Merge Worker {
144*a71a9546SAutomerger Merge Worker const struct xt_socket_mtinfo3 *info = (const void *)match->data;
145*a71a9546SAutomerger Merge Worker
146*a71a9546SAutomerger Merge Worker if (info->flags & XT_SOCKET_TRANSPARENT)
147*a71a9546SAutomerger Merge Worker printf(" --transparent");
148*a71a9546SAutomerger Merge Worker if (info->flags & XT_SOCKET_NOWILDCARD)
149*a71a9546SAutomerger Merge Worker printf(" --nowildcard");
150*a71a9546SAutomerger Merge Worker if (info->flags & XT_SOCKET_RESTORESKMARK)
151*a71a9546SAutomerger Merge Worker printf(" --restore-skmark");
152*a71a9546SAutomerger Merge Worker }
153*a71a9546SAutomerger Merge Worker
154*a71a9546SAutomerger Merge Worker static void
socket_mt_print_v3(const void * ip,const struct xt_entry_match * match,int numeric)155*a71a9546SAutomerger Merge Worker socket_mt_print_v3(const void *ip, const struct xt_entry_match *match,
156*a71a9546SAutomerger Merge Worker int numeric)
157*a71a9546SAutomerger Merge Worker {
158*a71a9546SAutomerger Merge Worker printf(" socket");
159*a71a9546SAutomerger Merge Worker socket_mt_save_v3(ip, match);
160*a71a9546SAutomerger Merge Worker }
161*a71a9546SAutomerger Merge Worker
162*a71a9546SAutomerger Merge Worker static struct xtables_match socket_mt_reg[] = {
163*a71a9546SAutomerger Merge Worker {
164*a71a9546SAutomerger Merge Worker .name = "socket",
165*a71a9546SAutomerger Merge Worker .revision = 0,
166*a71a9546SAutomerger Merge Worker .family = NFPROTO_IPV4,
167*a71a9546SAutomerger Merge Worker .version = XTABLES_VERSION,
168*a71a9546SAutomerger Merge Worker .size = XT_ALIGN(0),
169*a71a9546SAutomerger Merge Worker .userspacesize = XT_ALIGN(0),
170*a71a9546SAutomerger Merge Worker },
171*a71a9546SAutomerger Merge Worker {
172*a71a9546SAutomerger Merge Worker .name = "socket",
173*a71a9546SAutomerger Merge Worker .revision = 1,
174*a71a9546SAutomerger Merge Worker .family = NFPROTO_UNSPEC,
175*a71a9546SAutomerger Merge Worker .version = XTABLES_VERSION,
176*a71a9546SAutomerger Merge Worker .size = XT_ALIGN(sizeof(struct xt_socket_mtinfo1)),
177*a71a9546SAutomerger Merge Worker .userspacesize = XT_ALIGN(sizeof(struct xt_socket_mtinfo1)),
178*a71a9546SAutomerger Merge Worker .help = socket_mt_help,
179*a71a9546SAutomerger Merge Worker .print = socket_mt_print,
180*a71a9546SAutomerger Merge Worker .save = socket_mt_save,
181*a71a9546SAutomerger Merge Worker .x6_parse = socket_mt_parse,
182*a71a9546SAutomerger Merge Worker .x6_options = socket_mt_opts,
183*a71a9546SAutomerger Merge Worker },
184*a71a9546SAutomerger Merge Worker {
185*a71a9546SAutomerger Merge Worker .name = "socket",
186*a71a9546SAutomerger Merge Worker .revision = 2,
187*a71a9546SAutomerger Merge Worker .family = NFPROTO_UNSPEC,
188*a71a9546SAutomerger Merge Worker .version = XTABLES_VERSION,
189*a71a9546SAutomerger Merge Worker .size = XT_ALIGN(sizeof(struct xt_socket_mtinfo2)),
190*a71a9546SAutomerger Merge Worker .userspacesize = XT_ALIGN(sizeof(struct xt_socket_mtinfo2)),
191*a71a9546SAutomerger Merge Worker .help = socket_mt_help_v2,
192*a71a9546SAutomerger Merge Worker .print = socket_mt_print_v2,
193*a71a9546SAutomerger Merge Worker .save = socket_mt_save_v2,
194*a71a9546SAutomerger Merge Worker .x6_parse = socket_mt_parse_v2,
195*a71a9546SAutomerger Merge Worker .x6_options = socket_mt_opts_v2,
196*a71a9546SAutomerger Merge Worker },
197*a71a9546SAutomerger Merge Worker {
198*a71a9546SAutomerger Merge Worker .name = "socket",
199*a71a9546SAutomerger Merge Worker .revision = 3,
200*a71a9546SAutomerger Merge Worker .family = NFPROTO_UNSPEC,
201*a71a9546SAutomerger Merge Worker .version = XTABLES_VERSION,
202*a71a9546SAutomerger Merge Worker .size = XT_ALIGN(sizeof(struct xt_socket_mtinfo2)),
203*a71a9546SAutomerger Merge Worker .userspacesize = XT_ALIGN(sizeof(struct xt_socket_mtinfo2)),
204*a71a9546SAutomerger Merge Worker .help = socket_mt_help_v3,
205*a71a9546SAutomerger Merge Worker .print = socket_mt_print_v3,
206*a71a9546SAutomerger Merge Worker .save = socket_mt_save_v3,
207*a71a9546SAutomerger Merge Worker .x6_parse = socket_mt_parse_v3,
208*a71a9546SAutomerger Merge Worker .x6_options = socket_mt_opts_v3,
209*a71a9546SAutomerger Merge Worker },
210*a71a9546SAutomerger Merge Worker };
211*a71a9546SAutomerger Merge Worker
_init(void)212*a71a9546SAutomerger Merge Worker void _init(void)
213*a71a9546SAutomerger Merge Worker {
214*a71a9546SAutomerger Merge Worker xtables_register_matches(socket_mt_reg, ARRAY_SIZE(socket_mt_reg));
215*a71a9546SAutomerger Merge Worker }
216