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