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