1*a71a9546SAutomerger Merge Worker /* Copyright (C) 2000-2002 Joakim Axelsson <[email protected]> 2*a71a9546SAutomerger Merge Worker * Patrick Schaaf <[email protected]> 3*a71a9546SAutomerger Merge Worker * Martin Josefsson <[email protected]> 4*a71a9546SAutomerger Merge Worker * Copyright (C) 2003-2010 Jozsef Kadlecsik <[email protected]> 5*a71a9546SAutomerger Merge Worker * 6*a71a9546SAutomerger Merge Worker * This program is free software; you can redistribute it and/or modify 7*a71a9546SAutomerger Merge Worker * it under the terms of the GNU General Public License version 2 as 8*a71a9546SAutomerger Merge Worker * published by the Free Software Foundation. 9*a71a9546SAutomerger Merge Worker */ 10*a71a9546SAutomerger Merge Worker 11*a71a9546SAutomerger Merge Worker /* Shared library add-on to iptables to add IP set matching. */ 12*a71a9546SAutomerger Merge Worker #include <stdbool.h> 13*a71a9546SAutomerger Merge Worker #include <stdio.h> 14*a71a9546SAutomerger Merge Worker #include <netdb.h> 15*a71a9546SAutomerger Merge Worker #include <string.h> 16*a71a9546SAutomerger Merge Worker #include <stdlib.h> 17*a71a9546SAutomerger Merge Worker #include <getopt.h> 18*a71a9546SAutomerger Merge Worker #include <ctype.h> 19*a71a9546SAutomerger Merge Worker #include <errno.h> 20*a71a9546SAutomerger Merge Worker 21*a71a9546SAutomerger Merge Worker #include <xtables.h> 22*a71a9546SAutomerger Merge Worker #include <linux/netfilter/xt_set.h> 23*a71a9546SAutomerger Merge Worker #include "libxt_set.h" 24*a71a9546SAutomerger Merge Worker 25*a71a9546SAutomerger Merge Worker #ifdef DEBUG 26*a71a9546SAutomerger Merge Worker #define DEBUGP(x, args...) fprintf(stderr, x, ## args) 27*a71a9546SAutomerger Merge Worker #else 28*a71a9546SAutomerger Merge Worker #define DEBUGP(x, args...) 29*a71a9546SAutomerger Merge Worker #endif 30*a71a9546SAutomerger Merge Worker 31*a71a9546SAutomerger Merge Worker /* Revision 0 */ 32*a71a9546SAutomerger Merge Worker 33*a71a9546SAutomerger Merge Worker static void 34*a71a9546SAutomerger Merge Worker set_help_v0(void) 35*a71a9546SAutomerger Merge Worker { 36*a71a9546SAutomerger Merge Worker printf("set match options:\n" 37*a71a9546SAutomerger Merge Worker " [!] --match-set name flags\n" 38*a71a9546SAutomerger Merge Worker " 'name' is the set name from to match,\n" 39*a71a9546SAutomerger Merge Worker " 'flags' are the comma separated list of\n" 40*a71a9546SAutomerger Merge Worker " 'src' and 'dst' specifications.\n"); 41*a71a9546SAutomerger Merge Worker } 42*a71a9546SAutomerger Merge Worker 43*a71a9546SAutomerger Merge Worker static const struct option set_opts_v0[] = { 44*a71a9546SAutomerger Merge Worker {.name = "match-set", .has_arg = true, .val = '1'}, 45*a71a9546SAutomerger Merge Worker {.name = "set", .has_arg = true, .val = '2'}, 46*a71a9546SAutomerger Merge Worker XT_GETOPT_TABLEEND, 47*a71a9546SAutomerger Merge Worker }; 48*a71a9546SAutomerger Merge Worker 49*a71a9546SAutomerger Merge Worker static void 50*a71a9546SAutomerger Merge Worker set_check_v0(unsigned int flags) 51*a71a9546SAutomerger Merge Worker { 52*a71a9546SAutomerger Merge Worker if (!flags) 53*a71a9546SAutomerger Merge Worker xtables_error(PARAMETER_PROBLEM, 54*a71a9546SAutomerger Merge Worker "You must specify `--match-set' with proper arguments"); 55*a71a9546SAutomerger Merge Worker } 56*a71a9546SAutomerger Merge Worker 57*a71a9546SAutomerger Merge Worker static int 58*a71a9546SAutomerger Merge Worker set_parse_v0(int c, char **argv, int invert, unsigned int *flags, 59*a71a9546SAutomerger Merge Worker const void *entry, struct xt_entry_match **match) 60*a71a9546SAutomerger Merge Worker { 61*a71a9546SAutomerger Merge Worker struct xt_set_info_match_v0 *myinfo = 62*a71a9546SAutomerger Merge Worker (struct xt_set_info_match_v0 *) (*match)->data; 63*a71a9546SAutomerger Merge Worker struct xt_set_info_v0 *info = &myinfo->match_set; 64*a71a9546SAutomerger Merge Worker 65*a71a9546SAutomerger Merge Worker switch (c) { 66*a71a9546SAutomerger Merge Worker case '2': 67*a71a9546SAutomerger Merge Worker fprintf(stderr, 68*a71a9546SAutomerger Merge Worker "--set option deprecated, please use --match-set\n"); 69*a71a9546SAutomerger Merge Worker /* fall through */ 70*a71a9546SAutomerger Merge Worker case '1': /* --match-set <set> <flag>[,<flag> */ 71*a71a9546SAutomerger Merge Worker if (info->u.flags[0]) 72*a71a9546SAutomerger Merge Worker xtables_error(PARAMETER_PROBLEM, 73*a71a9546SAutomerger Merge Worker "--match-set can be specified only once"); 74*a71a9546SAutomerger Merge Worker if (invert) 75*a71a9546SAutomerger Merge Worker info->u.flags[0] |= IPSET_MATCH_INV; 76*a71a9546SAutomerger Merge Worker 77*a71a9546SAutomerger Merge Worker if (!argv[optind] 78*a71a9546SAutomerger Merge Worker || argv[optind][0] == '-' 79*a71a9546SAutomerger Merge Worker || argv[optind][0] == '!') 80*a71a9546SAutomerger Merge Worker xtables_error(PARAMETER_PROBLEM, 81*a71a9546SAutomerger Merge Worker "--match-set requires two args."); 82*a71a9546SAutomerger Merge Worker 83*a71a9546SAutomerger Merge Worker if (strlen(optarg) > IPSET_MAXNAMELEN - 1) 84*a71a9546SAutomerger Merge Worker xtables_error(PARAMETER_PROBLEM, 85*a71a9546SAutomerger Merge Worker "setname `%s' too long, max %d characters.", 86*a71a9546SAutomerger Merge Worker optarg, IPSET_MAXNAMELEN - 1); 87*a71a9546SAutomerger Merge Worker 88*a71a9546SAutomerger Merge Worker get_set_byname(optarg, (struct xt_set_info *)info); 89*a71a9546SAutomerger Merge Worker parse_dirs_v0(argv[optind], info); 90*a71a9546SAutomerger Merge Worker DEBUGP("parse: set index %u\n", info->index); 91*a71a9546SAutomerger Merge Worker optind++; 92*a71a9546SAutomerger Merge Worker 93*a71a9546SAutomerger Merge Worker *flags = 1; 94*a71a9546SAutomerger Merge Worker break; 95*a71a9546SAutomerger Merge Worker } 96*a71a9546SAutomerger Merge Worker 97*a71a9546SAutomerger Merge Worker return 1; 98*a71a9546SAutomerger Merge Worker } 99*a71a9546SAutomerger Merge Worker 100*a71a9546SAutomerger Merge Worker static void 101*a71a9546SAutomerger Merge Worker print_match_v0(const char *prefix, const struct xt_set_info_v0 *info) 102*a71a9546SAutomerger Merge Worker { 103*a71a9546SAutomerger Merge Worker int i; 104*a71a9546SAutomerger Merge Worker char setname[IPSET_MAXNAMELEN]; 105*a71a9546SAutomerger Merge Worker 106*a71a9546SAutomerger Merge Worker get_set_byid(setname, info->index); 107*a71a9546SAutomerger Merge Worker printf("%s %s %s", 108*a71a9546SAutomerger Merge Worker (info->u.flags[0] & IPSET_MATCH_INV) ? " !" : "", 109*a71a9546SAutomerger Merge Worker prefix, 110*a71a9546SAutomerger Merge Worker setname); 111*a71a9546SAutomerger Merge Worker for (i = 0; i < IPSET_DIM_MAX; i++) { 112*a71a9546SAutomerger Merge Worker if (!info->u.flags[i]) 113*a71a9546SAutomerger Merge Worker break; 114*a71a9546SAutomerger Merge Worker printf("%s%s", 115*a71a9546SAutomerger Merge Worker i == 0 ? " " : ",", 116*a71a9546SAutomerger Merge Worker info->u.flags[i] & IPSET_SRC ? "src" : "dst"); 117*a71a9546SAutomerger Merge Worker } 118*a71a9546SAutomerger Merge Worker } 119*a71a9546SAutomerger Merge Worker 120*a71a9546SAutomerger Merge Worker /* Prints out the matchinfo. */ 121*a71a9546SAutomerger Merge Worker static void 122*a71a9546SAutomerger Merge Worker set_print_v0(const void *ip, const struct xt_entry_match *match, int numeric) 123*a71a9546SAutomerger Merge Worker { 124*a71a9546SAutomerger Merge Worker const struct xt_set_info_match_v0 *info = (const void *)match->data; 125*a71a9546SAutomerger Merge Worker 126*a71a9546SAutomerger Merge Worker print_match_v0("match-set", &info->match_set); 127*a71a9546SAutomerger Merge Worker } 128*a71a9546SAutomerger Merge Worker 129*a71a9546SAutomerger Merge Worker static void 130*a71a9546SAutomerger Merge Worker set_save_v0(const void *ip, const struct xt_entry_match *match) 131*a71a9546SAutomerger Merge Worker { 132*a71a9546SAutomerger Merge Worker const struct xt_set_info_match_v0 *info = (const void *)match->data; 133*a71a9546SAutomerger Merge Worker 134*a71a9546SAutomerger Merge Worker print_match_v0("--match-set", &info->match_set); 135*a71a9546SAutomerger Merge Worker } 136*a71a9546SAutomerger Merge Worker 137*a71a9546SAutomerger Merge Worker /* Revision 1 */ 138*a71a9546SAutomerger Merge Worker static int 139*a71a9546SAutomerger Merge Worker set_parse_v1(int c, char **argv, int invert, unsigned int *flags, 140*a71a9546SAutomerger Merge Worker const void *entry, struct xt_entry_match **match) 141*a71a9546SAutomerger Merge Worker { 142*a71a9546SAutomerger Merge Worker struct xt_set_info_match_v1 *myinfo = 143*a71a9546SAutomerger Merge Worker (struct xt_set_info_match_v1 *) (*match)->data; 144*a71a9546SAutomerger Merge Worker struct xt_set_info *info = &myinfo->match_set; 145*a71a9546SAutomerger Merge Worker 146*a71a9546SAutomerger Merge Worker switch (c) { 147*a71a9546SAutomerger Merge Worker case '2': 148*a71a9546SAutomerger Merge Worker fprintf(stderr, 149*a71a9546SAutomerger Merge Worker "--set option deprecated, please use --match-set\n"); 150*a71a9546SAutomerger Merge Worker /* fall through */ 151*a71a9546SAutomerger Merge Worker case '1': /* --match-set <set> <flag>[,<flag> */ 152*a71a9546SAutomerger Merge Worker if (info->dim) 153*a71a9546SAutomerger Merge Worker xtables_error(PARAMETER_PROBLEM, 154*a71a9546SAutomerger Merge Worker "--match-set can be specified only once"); 155*a71a9546SAutomerger Merge Worker if (invert) 156*a71a9546SAutomerger Merge Worker info->flags |= IPSET_INV_MATCH; 157*a71a9546SAutomerger Merge Worker 158*a71a9546SAutomerger Merge Worker if (!argv[optind] 159*a71a9546SAutomerger Merge Worker || argv[optind][0] == '-' 160*a71a9546SAutomerger Merge Worker || argv[optind][0] == '!') 161*a71a9546SAutomerger Merge Worker xtables_error(PARAMETER_PROBLEM, 162*a71a9546SAutomerger Merge Worker "--match-set requires two args."); 163*a71a9546SAutomerger Merge Worker 164*a71a9546SAutomerger Merge Worker if (strlen(optarg) > IPSET_MAXNAMELEN - 1) 165*a71a9546SAutomerger Merge Worker xtables_error(PARAMETER_PROBLEM, 166*a71a9546SAutomerger Merge Worker "setname `%s' too long, max %d characters.", 167*a71a9546SAutomerger Merge Worker optarg, IPSET_MAXNAMELEN - 1); 168*a71a9546SAutomerger Merge Worker 169*a71a9546SAutomerger Merge Worker get_set_byname(optarg, info); 170*a71a9546SAutomerger Merge Worker parse_dirs(argv[optind], info); 171*a71a9546SAutomerger Merge Worker DEBUGP("parse: set index %u\n", info->index); 172*a71a9546SAutomerger Merge Worker optind++; 173*a71a9546SAutomerger Merge Worker 174*a71a9546SAutomerger Merge Worker *flags = 1; 175*a71a9546SAutomerger Merge Worker break; 176*a71a9546SAutomerger Merge Worker } 177*a71a9546SAutomerger Merge Worker 178*a71a9546SAutomerger Merge Worker return 1; 179*a71a9546SAutomerger Merge Worker } 180*a71a9546SAutomerger Merge Worker 181*a71a9546SAutomerger Merge Worker static void 182*a71a9546SAutomerger Merge Worker print_match(const char *prefix, const struct xt_set_info *info) 183*a71a9546SAutomerger Merge Worker { 184*a71a9546SAutomerger Merge Worker int i; 185*a71a9546SAutomerger Merge Worker char setname[IPSET_MAXNAMELEN]; 186*a71a9546SAutomerger Merge Worker 187*a71a9546SAutomerger Merge Worker get_set_byid(setname, info->index); 188*a71a9546SAutomerger Merge Worker printf("%s %s %s", 189*a71a9546SAutomerger Merge Worker (info->flags & IPSET_INV_MATCH) ? " !" : "", 190*a71a9546SAutomerger Merge Worker prefix, 191*a71a9546SAutomerger Merge Worker setname); 192*a71a9546SAutomerger Merge Worker for (i = 1; i <= info->dim; i++) { 193*a71a9546SAutomerger Merge Worker printf("%s%s", 194*a71a9546SAutomerger Merge Worker i == 1 ? " " : ",", 195*a71a9546SAutomerger Merge Worker info->flags & (1 << i) ? "src" : "dst"); 196*a71a9546SAutomerger Merge Worker } 197*a71a9546SAutomerger Merge Worker } 198*a71a9546SAutomerger Merge Worker 199*a71a9546SAutomerger Merge Worker /* Prints out the matchinfo. */ 200*a71a9546SAutomerger Merge Worker static void 201*a71a9546SAutomerger Merge Worker set_print_v1(const void *ip, const struct xt_entry_match *match, int numeric) 202*a71a9546SAutomerger Merge Worker { 203*a71a9546SAutomerger Merge Worker const struct xt_set_info_match_v1 *info = (const void *)match->data; 204*a71a9546SAutomerger Merge Worker 205*a71a9546SAutomerger Merge Worker print_match("match-set", &info->match_set); 206*a71a9546SAutomerger Merge Worker } 207*a71a9546SAutomerger Merge Worker 208*a71a9546SAutomerger Merge Worker static void 209*a71a9546SAutomerger Merge Worker set_save_v1(const void *ip, const struct xt_entry_match *match) 210*a71a9546SAutomerger Merge Worker { 211*a71a9546SAutomerger Merge Worker const struct xt_set_info_match_v1 *info = (const void *)match->data; 212*a71a9546SAutomerger Merge Worker 213*a71a9546SAutomerger Merge Worker print_match("--match-set", &info->match_set); 214*a71a9546SAutomerger Merge Worker } 215*a71a9546SAutomerger Merge Worker 216*a71a9546SAutomerger Merge Worker /* Revision 2 */ 217*a71a9546SAutomerger Merge Worker static void 218*a71a9546SAutomerger Merge Worker set_help_v2(void) 219*a71a9546SAutomerger Merge Worker { 220*a71a9546SAutomerger Merge Worker printf("set match options:\n" 221*a71a9546SAutomerger Merge Worker " [!] --match-set name flags [--return-nomatch]\n" 222*a71a9546SAutomerger Merge Worker " 'name' is the set name from to match,\n" 223*a71a9546SAutomerger Merge Worker " 'flags' are the comma separated list of\n" 224*a71a9546SAutomerger Merge Worker " 'src' and 'dst' specifications.\n"); 225*a71a9546SAutomerger Merge Worker } 226*a71a9546SAutomerger Merge Worker 227*a71a9546SAutomerger Merge Worker static const struct option set_opts_v2[] = { 228*a71a9546SAutomerger Merge Worker {.name = "match-set", .has_arg = true, .val = '1'}, 229*a71a9546SAutomerger Merge Worker {.name = "set", .has_arg = true, .val = '2'}, 230*a71a9546SAutomerger Merge Worker {.name = "return-nomatch", .has_arg = false, .val = '3'}, 231*a71a9546SAutomerger Merge Worker XT_GETOPT_TABLEEND, 232*a71a9546SAutomerger Merge Worker }; 233*a71a9546SAutomerger Merge Worker 234*a71a9546SAutomerger Merge Worker static int 235*a71a9546SAutomerger Merge Worker set_parse_v2(int c, char **argv, int invert, unsigned int *flags, 236*a71a9546SAutomerger Merge Worker const void *entry, struct xt_entry_match **match) 237*a71a9546SAutomerger Merge Worker { 238*a71a9546SAutomerger Merge Worker struct xt_set_info_match_v1 *myinfo = 239*a71a9546SAutomerger Merge Worker (struct xt_set_info_match_v1 *) (*match)->data; 240*a71a9546SAutomerger Merge Worker struct xt_set_info *info = &myinfo->match_set; 241*a71a9546SAutomerger Merge Worker 242*a71a9546SAutomerger Merge Worker switch (c) { 243*a71a9546SAutomerger Merge Worker case '3': 244*a71a9546SAutomerger Merge Worker info->flags |= IPSET_RETURN_NOMATCH; 245*a71a9546SAutomerger Merge Worker break; 246*a71a9546SAutomerger Merge Worker case '2': 247*a71a9546SAutomerger Merge Worker fprintf(stderr, 248*a71a9546SAutomerger Merge Worker "--set option deprecated, please use --match-set\n"); 249*a71a9546SAutomerger Merge Worker /* fall through */ 250*a71a9546SAutomerger Merge Worker case '1': /* --match-set <set> <flag>[,<flag> */ 251*a71a9546SAutomerger Merge Worker if (info->dim) 252*a71a9546SAutomerger Merge Worker xtables_error(PARAMETER_PROBLEM, 253*a71a9546SAutomerger Merge Worker "--match-set can be specified only once"); 254*a71a9546SAutomerger Merge Worker if (invert) 255*a71a9546SAutomerger Merge Worker info->flags |= IPSET_INV_MATCH; 256*a71a9546SAutomerger Merge Worker 257*a71a9546SAutomerger Merge Worker if (!argv[optind] 258*a71a9546SAutomerger Merge Worker || argv[optind][0] == '-' 259*a71a9546SAutomerger Merge Worker || argv[optind][0] == '!') 260*a71a9546SAutomerger Merge Worker xtables_error(PARAMETER_PROBLEM, 261*a71a9546SAutomerger Merge Worker "--match-set requires two args."); 262*a71a9546SAutomerger Merge Worker 263*a71a9546SAutomerger Merge Worker if (strlen(optarg) > IPSET_MAXNAMELEN - 1) 264*a71a9546SAutomerger Merge Worker xtables_error(PARAMETER_PROBLEM, 265*a71a9546SAutomerger Merge Worker "setname `%s' too long, max %d characters.", 266*a71a9546SAutomerger Merge Worker optarg, IPSET_MAXNAMELEN - 1); 267*a71a9546SAutomerger Merge Worker 268*a71a9546SAutomerger Merge Worker get_set_byname(optarg, info); 269*a71a9546SAutomerger Merge Worker parse_dirs(argv[optind], info); 270*a71a9546SAutomerger Merge Worker DEBUGP("parse: set index %u\n", info->index); 271*a71a9546SAutomerger Merge Worker optind++; 272*a71a9546SAutomerger Merge Worker 273*a71a9546SAutomerger Merge Worker *flags = 1; 274*a71a9546SAutomerger Merge Worker break; 275*a71a9546SAutomerger Merge Worker } 276*a71a9546SAutomerger Merge Worker 277*a71a9546SAutomerger Merge Worker return 1; 278*a71a9546SAutomerger Merge Worker } 279*a71a9546SAutomerger Merge Worker 280*a71a9546SAutomerger Merge Worker /* Prints out the matchinfo. */ 281*a71a9546SAutomerger Merge Worker static void 282*a71a9546SAutomerger Merge Worker set_print_v2(const void *ip, const struct xt_entry_match *match, int numeric) 283*a71a9546SAutomerger Merge Worker { 284*a71a9546SAutomerger Merge Worker const struct xt_set_info_match_v1 *info = (const void *)match->data; 285*a71a9546SAutomerger Merge Worker 286*a71a9546SAutomerger Merge Worker print_match("match-set", &info->match_set); 287*a71a9546SAutomerger Merge Worker if (info->match_set.flags & IPSET_RETURN_NOMATCH) 288*a71a9546SAutomerger Merge Worker printf(" return-nomatch"); 289*a71a9546SAutomerger Merge Worker } 290*a71a9546SAutomerger Merge Worker 291*a71a9546SAutomerger Merge Worker static void 292*a71a9546SAutomerger Merge Worker set_save_v2(const void *ip, const struct xt_entry_match *match) 293*a71a9546SAutomerger Merge Worker { 294*a71a9546SAutomerger Merge Worker const struct xt_set_info_match_v1 *info = (const void *)match->data; 295*a71a9546SAutomerger Merge Worker 296*a71a9546SAutomerger Merge Worker print_match("--match-set", &info->match_set); 297*a71a9546SAutomerger Merge Worker if (info->match_set.flags & IPSET_RETURN_NOMATCH) 298*a71a9546SAutomerger Merge Worker printf(" --return-nomatch"); 299*a71a9546SAutomerger Merge Worker } 300*a71a9546SAutomerger Merge Worker 301*a71a9546SAutomerger Merge Worker /* Revision 3 */ 302*a71a9546SAutomerger Merge Worker static void 303*a71a9546SAutomerger Merge Worker set_help_v3(void) 304*a71a9546SAutomerger Merge Worker { 305*a71a9546SAutomerger Merge Worker printf("set match options:\n" 306*a71a9546SAutomerger Merge Worker " [!] --match-set name flags [--return-nomatch]\n" 307*a71a9546SAutomerger Merge Worker " [! --update-counters] [! --update-subcounters]\n" 308*a71a9546SAutomerger Merge Worker " [[!] --packets-eq value | --packets-lt value | --packets-gt value\n" 309*a71a9546SAutomerger Merge Worker " [[!] --bytes-eq value | --bytes-lt value | --bytes-gt value\n" 310*a71a9546SAutomerger Merge Worker " 'name' is the set name from to match,\n" 311*a71a9546SAutomerger Merge Worker " 'flags' are the comma separated list of\n" 312*a71a9546SAutomerger Merge Worker " 'src' and 'dst' specifications.\n"); 313*a71a9546SAutomerger Merge Worker } 314*a71a9546SAutomerger Merge Worker 315*a71a9546SAutomerger Merge Worker static const struct option set_opts_v3[] = { 316*a71a9546SAutomerger Merge Worker {.name = "match-set", .has_arg = true, .val = '1'}, 317*a71a9546SAutomerger Merge Worker {.name = "set", .has_arg = true, .val = '2'}, 318*a71a9546SAutomerger Merge Worker {.name = "return-nomatch", .has_arg = false, .val = '3'}, 319*a71a9546SAutomerger Merge Worker {.name = "update-counters", .has_arg = false, .val = '4'}, 320*a71a9546SAutomerger Merge Worker {.name = "packets-eq", .has_arg = true, .val = '5'}, 321*a71a9546SAutomerger Merge Worker {.name = "packets-lt", .has_arg = true, .val = '6'}, 322*a71a9546SAutomerger Merge Worker {.name = "packets-gt", .has_arg = true, .val = '7'}, 323*a71a9546SAutomerger Merge Worker {.name = "bytes-eq", .has_arg = true, .val = '8'}, 324*a71a9546SAutomerger Merge Worker {.name = "bytes-lt", .has_arg = true, .val = '9'}, 325*a71a9546SAutomerger Merge Worker {.name = "bytes-gt", .has_arg = true, .val = '0'}, 326*a71a9546SAutomerger Merge Worker {.name = "update-subcounters", .has_arg = false, .val = 'a'}, 327*a71a9546SAutomerger Merge Worker XT_GETOPT_TABLEEND, 328*a71a9546SAutomerger Merge Worker }; 329*a71a9546SAutomerger Merge Worker 330*a71a9546SAutomerger Merge Worker static uint64_t 331*a71a9546SAutomerger Merge Worker parse_counter(const char *opt) 332*a71a9546SAutomerger Merge Worker { 333*a71a9546SAutomerger Merge Worker uintmax_t value; 334*a71a9546SAutomerger Merge Worker 335*a71a9546SAutomerger Merge Worker if (!xtables_strtoul(opt, NULL, &value, 0, UINT64_MAX)) 336*a71a9546SAutomerger Merge Worker xtables_error(PARAMETER_PROBLEM, 337*a71a9546SAutomerger Merge Worker "Cannot parse %s as a counter value", opt); 338*a71a9546SAutomerger Merge Worker return (uint64_t)value; 339*a71a9546SAutomerger Merge Worker } 340*a71a9546SAutomerger Merge Worker 341*a71a9546SAutomerger Merge Worker static int 342*a71a9546SAutomerger Merge Worker set_parse_v3(int c, char **argv, int invert, unsigned int *flags, 343*a71a9546SAutomerger Merge Worker const void *entry, struct xt_entry_match **match) 344*a71a9546SAutomerger Merge Worker { 345*a71a9546SAutomerger Merge Worker struct xt_set_info_match_v3 *info = 346*a71a9546SAutomerger Merge Worker (struct xt_set_info_match_v3 *) (*match)->data; 347*a71a9546SAutomerger Merge Worker 348*a71a9546SAutomerger Merge Worker switch (c) { 349*a71a9546SAutomerger Merge Worker case 'a': 350*a71a9546SAutomerger Merge Worker if (invert) 351*a71a9546SAutomerger Merge Worker info->flags |= IPSET_FLAG_SKIP_SUBCOUNTER_UPDATE; 352*a71a9546SAutomerger Merge Worker break; 353*a71a9546SAutomerger Merge Worker case '0': 354*a71a9546SAutomerger Merge Worker if (info->bytes.op != IPSET_COUNTER_NONE) 355*a71a9546SAutomerger Merge Worker xtables_error(PARAMETER_PROBLEM, 356*a71a9546SAutomerger Merge Worker "only one of the --bytes-[eq|lt|gt] is allowed"); 357*a71a9546SAutomerger Merge Worker if (invert) 358*a71a9546SAutomerger Merge Worker xtables_error(PARAMETER_PROBLEM, 359*a71a9546SAutomerger Merge Worker "--bytes-gt option cannot be inverted"); 360*a71a9546SAutomerger Merge Worker info->bytes.op = IPSET_COUNTER_GT; 361*a71a9546SAutomerger Merge Worker info->bytes.value = parse_counter(optarg); 362*a71a9546SAutomerger Merge Worker break; 363*a71a9546SAutomerger Merge Worker case '9': 364*a71a9546SAutomerger Merge Worker if (info->bytes.op != IPSET_COUNTER_NONE) 365*a71a9546SAutomerger Merge Worker xtables_error(PARAMETER_PROBLEM, 366*a71a9546SAutomerger Merge Worker "only one of the --bytes-[eq|lt|gt] is allowed"); 367*a71a9546SAutomerger Merge Worker if (invert) 368*a71a9546SAutomerger Merge Worker xtables_error(PARAMETER_PROBLEM, 369*a71a9546SAutomerger Merge Worker "--bytes-lt option cannot be inverted"); 370*a71a9546SAutomerger Merge Worker info->bytes.op = IPSET_COUNTER_LT; 371*a71a9546SAutomerger Merge Worker info->bytes.value = parse_counter(optarg); 372*a71a9546SAutomerger Merge Worker break; 373*a71a9546SAutomerger Merge Worker case '8': 374*a71a9546SAutomerger Merge Worker if (info->bytes.op != IPSET_COUNTER_NONE) 375*a71a9546SAutomerger Merge Worker xtables_error(PARAMETER_PROBLEM, 376*a71a9546SAutomerger Merge Worker "only one of the --bytes-[eq|lt|gt] is allowed"); 377*a71a9546SAutomerger Merge Worker info->bytes.op = invert ? IPSET_COUNTER_NE : IPSET_COUNTER_EQ; 378*a71a9546SAutomerger Merge Worker info->bytes.value = parse_counter(optarg); 379*a71a9546SAutomerger Merge Worker break; 380*a71a9546SAutomerger Merge Worker case '7': 381*a71a9546SAutomerger Merge Worker if (info->packets.op != IPSET_COUNTER_NONE) 382*a71a9546SAutomerger Merge Worker xtables_error(PARAMETER_PROBLEM, 383*a71a9546SAutomerger Merge Worker "only one of the --packets-[eq|lt|gt] is allowed"); 384*a71a9546SAutomerger Merge Worker if (invert) 385*a71a9546SAutomerger Merge Worker xtables_error(PARAMETER_PROBLEM, 386*a71a9546SAutomerger Merge Worker "--packets-gt option cannot be inverted"); 387*a71a9546SAutomerger Merge Worker info->packets.op = IPSET_COUNTER_GT; 388*a71a9546SAutomerger Merge Worker info->packets.value = parse_counter(optarg); 389*a71a9546SAutomerger Merge Worker break; 390*a71a9546SAutomerger Merge Worker case '6': 391*a71a9546SAutomerger Merge Worker if (info->packets.op != IPSET_COUNTER_NONE) 392*a71a9546SAutomerger Merge Worker xtables_error(PARAMETER_PROBLEM, 393*a71a9546SAutomerger Merge Worker "only one of the --packets-[eq|lt|gt] is allowed"); 394*a71a9546SAutomerger Merge Worker if (invert) 395*a71a9546SAutomerger Merge Worker xtables_error(PARAMETER_PROBLEM, 396*a71a9546SAutomerger Merge Worker "--packets-lt option cannot be inverted"); 397*a71a9546SAutomerger Merge Worker info->packets.op = IPSET_COUNTER_LT; 398*a71a9546SAutomerger Merge Worker info->packets.value = parse_counter(optarg); 399*a71a9546SAutomerger Merge Worker break; 400*a71a9546SAutomerger Merge Worker case '5': 401*a71a9546SAutomerger Merge Worker if (info->packets.op != IPSET_COUNTER_NONE) 402*a71a9546SAutomerger Merge Worker xtables_error(PARAMETER_PROBLEM, 403*a71a9546SAutomerger Merge Worker "only one of the --packets-[eq|lt|gt] is allowed"); 404*a71a9546SAutomerger Merge Worker info->packets.op = invert ? IPSET_COUNTER_NE : IPSET_COUNTER_EQ; 405*a71a9546SAutomerger Merge Worker info->packets.value = parse_counter(optarg); 406*a71a9546SAutomerger Merge Worker break; 407*a71a9546SAutomerger Merge Worker case '4': 408*a71a9546SAutomerger Merge Worker if (invert) 409*a71a9546SAutomerger Merge Worker info->flags |= IPSET_FLAG_SKIP_COUNTER_UPDATE; 410*a71a9546SAutomerger Merge Worker break; 411*a71a9546SAutomerger Merge Worker case '3': 412*a71a9546SAutomerger Merge Worker if (invert) 413*a71a9546SAutomerger Merge Worker xtables_error(PARAMETER_PROBLEM, 414*a71a9546SAutomerger Merge Worker "--return-nomatch flag cannot be inverted"); 415*a71a9546SAutomerger Merge Worker info->flags |= IPSET_FLAG_RETURN_NOMATCH; 416*a71a9546SAutomerger Merge Worker break; 417*a71a9546SAutomerger Merge Worker case '2': 418*a71a9546SAutomerger Merge Worker fprintf(stderr, 419*a71a9546SAutomerger Merge Worker "--set option deprecated, please use --match-set\n"); 420*a71a9546SAutomerger Merge Worker /* fall through */ 421*a71a9546SAutomerger Merge Worker case '1': /* --match-set <set> <flag>[,<flag> */ 422*a71a9546SAutomerger Merge Worker if (info->match_set.dim) 423*a71a9546SAutomerger Merge Worker xtables_error(PARAMETER_PROBLEM, 424*a71a9546SAutomerger Merge Worker "--match-set can be specified only once"); 425*a71a9546SAutomerger Merge Worker if (invert) 426*a71a9546SAutomerger Merge Worker info->match_set.flags |= IPSET_INV_MATCH; 427*a71a9546SAutomerger Merge Worker 428*a71a9546SAutomerger Merge Worker if (!argv[optind] 429*a71a9546SAutomerger Merge Worker || argv[optind][0] == '-' 430*a71a9546SAutomerger Merge Worker || argv[optind][0] == '!') 431*a71a9546SAutomerger Merge Worker xtables_error(PARAMETER_PROBLEM, 432*a71a9546SAutomerger Merge Worker "--match-set requires two args."); 433*a71a9546SAutomerger Merge Worker 434*a71a9546SAutomerger Merge Worker if (strlen(optarg) > IPSET_MAXNAMELEN - 1) 435*a71a9546SAutomerger Merge Worker xtables_error(PARAMETER_PROBLEM, 436*a71a9546SAutomerger Merge Worker "setname `%s' too long, max %d characters.", 437*a71a9546SAutomerger Merge Worker optarg, IPSET_MAXNAMELEN - 1); 438*a71a9546SAutomerger Merge Worker 439*a71a9546SAutomerger Merge Worker get_set_byname(optarg, &info->match_set); 440*a71a9546SAutomerger Merge Worker parse_dirs(argv[optind], &info->match_set); 441*a71a9546SAutomerger Merge Worker DEBUGP("parse: set index %u\n", info->match_set.index); 442*a71a9546SAutomerger Merge Worker optind++; 443*a71a9546SAutomerger Merge Worker 444*a71a9546SAutomerger Merge Worker *flags = 1; 445*a71a9546SAutomerger Merge Worker break; 446*a71a9546SAutomerger Merge Worker } 447*a71a9546SAutomerger Merge Worker 448*a71a9546SAutomerger Merge Worker return 1; 449*a71a9546SAutomerger Merge Worker } 450*a71a9546SAutomerger Merge Worker 451*a71a9546SAutomerger Merge Worker static void 452*a71a9546SAutomerger Merge Worker set_printv3_counter(const struct ip_set_counter_match0 *c, const char *name, 453*a71a9546SAutomerger Merge Worker const char *sep) 454*a71a9546SAutomerger Merge Worker { 455*a71a9546SAutomerger Merge Worker switch (c->op) { 456*a71a9546SAutomerger Merge Worker case IPSET_COUNTER_EQ: 457*a71a9546SAutomerger Merge Worker printf(" %s%s-eq %llu", sep, name, c->value); 458*a71a9546SAutomerger Merge Worker break; 459*a71a9546SAutomerger Merge Worker case IPSET_COUNTER_NE: 460*a71a9546SAutomerger Merge Worker printf(" ! %s%s-eq %llu", sep, name, c->value); 461*a71a9546SAutomerger Merge Worker break; 462*a71a9546SAutomerger Merge Worker case IPSET_COUNTER_LT: 463*a71a9546SAutomerger Merge Worker printf(" %s%s-lt %llu", sep, name, c->value); 464*a71a9546SAutomerger Merge Worker break; 465*a71a9546SAutomerger Merge Worker case IPSET_COUNTER_GT: 466*a71a9546SAutomerger Merge Worker printf(" %s%s-gt %llu", sep, name, c->value); 467*a71a9546SAutomerger Merge Worker break; 468*a71a9546SAutomerger Merge Worker } 469*a71a9546SAutomerger Merge Worker } 470*a71a9546SAutomerger Merge Worker 471*a71a9546SAutomerger Merge Worker static void 472*a71a9546SAutomerger Merge Worker set_print_v3_matchinfo(const struct xt_set_info_match_v3 *info, 473*a71a9546SAutomerger Merge Worker const char *opt, const char *sep) 474*a71a9546SAutomerger Merge Worker { 475*a71a9546SAutomerger Merge Worker print_match(opt, &info->match_set); 476*a71a9546SAutomerger Merge Worker if (info->flags & IPSET_FLAG_RETURN_NOMATCH) 477*a71a9546SAutomerger Merge Worker printf(" %sreturn-nomatch", sep); 478*a71a9546SAutomerger Merge Worker if ((info->flags & IPSET_FLAG_SKIP_COUNTER_UPDATE)) 479*a71a9546SAutomerger Merge Worker printf(" ! %supdate-counters", sep); 480*a71a9546SAutomerger Merge Worker if ((info->flags & IPSET_FLAG_SKIP_SUBCOUNTER_UPDATE)) 481*a71a9546SAutomerger Merge Worker printf(" ! %supdate-subcounters", sep); 482*a71a9546SAutomerger Merge Worker set_printv3_counter(&info->packets, "packets", sep); 483*a71a9546SAutomerger Merge Worker set_printv3_counter(&info->bytes, "bytes", sep); 484*a71a9546SAutomerger Merge Worker } 485*a71a9546SAutomerger Merge Worker 486*a71a9546SAutomerger Merge Worker /* Prints out the matchinfo. */ 487*a71a9546SAutomerger Merge Worker static void 488*a71a9546SAutomerger Merge Worker set_print_v3(const void *ip, const struct xt_entry_match *match, int numeric) 489*a71a9546SAutomerger Merge Worker { 490*a71a9546SAutomerger Merge Worker const struct xt_set_info_match_v3 *info = (const void *)match->data; 491*a71a9546SAutomerger Merge Worker 492*a71a9546SAutomerger Merge Worker set_print_v3_matchinfo(info, "match-set", ""); 493*a71a9546SAutomerger Merge Worker } 494*a71a9546SAutomerger Merge Worker 495*a71a9546SAutomerger Merge Worker static void 496*a71a9546SAutomerger Merge Worker set_save_v3(const void *ip, const struct xt_entry_match *match) 497*a71a9546SAutomerger Merge Worker { 498*a71a9546SAutomerger Merge Worker const struct xt_set_info_match_v3 *info = (const void *)match->data; 499*a71a9546SAutomerger Merge Worker 500*a71a9546SAutomerger Merge Worker set_print_v3_matchinfo(info, "--match-set", "--"); 501*a71a9546SAutomerger Merge Worker } 502*a71a9546SAutomerger Merge Worker 503*a71a9546SAutomerger Merge Worker /* Revision 4 */ 504*a71a9546SAutomerger Merge Worker static int 505*a71a9546SAutomerger Merge Worker set_parse_v4(int c, char **argv, int invert, unsigned int *flags, 506*a71a9546SAutomerger Merge Worker const void *entry, struct xt_entry_match **match) 507*a71a9546SAutomerger Merge Worker { 508*a71a9546SAutomerger Merge Worker struct xt_set_info_match_v4 *info = 509*a71a9546SAutomerger Merge Worker (struct xt_set_info_match_v4 *) (*match)->data; 510*a71a9546SAutomerger Merge Worker 511*a71a9546SAutomerger Merge Worker switch (c) { 512*a71a9546SAutomerger Merge Worker case 'a': 513*a71a9546SAutomerger Merge Worker if (invert) 514*a71a9546SAutomerger Merge Worker info->flags |= IPSET_FLAG_SKIP_SUBCOUNTER_UPDATE; 515*a71a9546SAutomerger Merge Worker break; 516*a71a9546SAutomerger Merge Worker case '0': 517*a71a9546SAutomerger Merge Worker if (info->bytes.op != IPSET_COUNTER_NONE) 518*a71a9546SAutomerger Merge Worker xtables_error(PARAMETER_PROBLEM, 519*a71a9546SAutomerger Merge Worker "only one of the --bytes-[eq|lt|gt] is allowed"); 520*a71a9546SAutomerger Merge Worker if (invert) 521*a71a9546SAutomerger Merge Worker xtables_error(PARAMETER_PROBLEM, 522*a71a9546SAutomerger Merge Worker "--bytes-gt option cannot be inverted"); 523*a71a9546SAutomerger Merge Worker info->bytes.op = IPSET_COUNTER_GT; 524*a71a9546SAutomerger Merge Worker info->bytes.value = parse_counter(optarg); 525*a71a9546SAutomerger Merge Worker break; 526*a71a9546SAutomerger Merge Worker case '9': 527*a71a9546SAutomerger Merge Worker if (info->bytes.op != IPSET_COUNTER_NONE) 528*a71a9546SAutomerger Merge Worker xtables_error(PARAMETER_PROBLEM, 529*a71a9546SAutomerger Merge Worker "only one of the --bytes-[eq|lt|gt] is allowed"); 530*a71a9546SAutomerger Merge Worker if (invert) 531*a71a9546SAutomerger Merge Worker xtables_error(PARAMETER_PROBLEM, 532*a71a9546SAutomerger Merge Worker "--bytes-lt option cannot be inverted"); 533*a71a9546SAutomerger Merge Worker info->bytes.op = IPSET_COUNTER_LT; 534*a71a9546SAutomerger Merge Worker info->bytes.value = parse_counter(optarg); 535*a71a9546SAutomerger Merge Worker break; 536*a71a9546SAutomerger Merge Worker case '8': 537*a71a9546SAutomerger Merge Worker if (info->bytes.op != IPSET_COUNTER_NONE) 538*a71a9546SAutomerger Merge Worker xtables_error(PARAMETER_PROBLEM, 539*a71a9546SAutomerger Merge Worker "only one of the --bytes-[eq|lt|gt] is allowed"); 540*a71a9546SAutomerger Merge Worker info->bytes.op = invert ? IPSET_COUNTER_NE : IPSET_COUNTER_EQ; 541*a71a9546SAutomerger Merge Worker info->bytes.value = parse_counter(optarg); 542*a71a9546SAutomerger Merge Worker break; 543*a71a9546SAutomerger Merge Worker case '7': 544*a71a9546SAutomerger Merge Worker if (info->packets.op != IPSET_COUNTER_NONE) 545*a71a9546SAutomerger Merge Worker xtables_error(PARAMETER_PROBLEM, 546*a71a9546SAutomerger Merge Worker "only one of the --packets-[eq|lt|gt] is allowed"); 547*a71a9546SAutomerger Merge Worker if (invert) 548*a71a9546SAutomerger Merge Worker xtables_error(PARAMETER_PROBLEM, 549*a71a9546SAutomerger Merge Worker "--packets-gt option cannot be inverted"); 550*a71a9546SAutomerger Merge Worker info->packets.op = IPSET_COUNTER_GT; 551*a71a9546SAutomerger Merge Worker info->packets.value = parse_counter(optarg); 552*a71a9546SAutomerger Merge Worker break; 553*a71a9546SAutomerger Merge Worker case '6': 554*a71a9546SAutomerger Merge Worker if (info->packets.op != IPSET_COUNTER_NONE) 555*a71a9546SAutomerger Merge Worker xtables_error(PARAMETER_PROBLEM, 556*a71a9546SAutomerger Merge Worker "only one of the --packets-[eq|lt|gt] is allowed"); 557*a71a9546SAutomerger Merge Worker if (invert) 558*a71a9546SAutomerger Merge Worker xtables_error(PARAMETER_PROBLEM, 559*a71a9546SAutomerger Merge Worker "--packets-lt option cannot be inverted"); 560*a71a9546SAutomerger Merge Worker info->packets.op = IPSET_COUNTER_LT; 561*a71a9546SAutomerger Merge Worker info->packets.value = parse_counter(optarg); 562*a71a9546SAutomerger Merge Worker break; 563*a71a9546SAutomerger Merge Worker case '5': 564*a71a9546SAutomerger Merge Worker if (info->packets.op != IPSET_COUNTER_NONE) 565*a71a9546SAutomerger Merge Worker xtables_error(PARAMETER_PROBLEM, 566*a71a9546SAutomerger Merge Worker "only one of the --packets-[eq|lt|gt] is allowed"); 567*a71a9546SAutomerger Merge Worker info->packets.op = invert ? IPSET_COUNTER_NE : IPSET_COUNTER_EQ; 568*a71a9546SAutomerger Merge Worker info->packets.value = parse_counter(optarg); 569*a71a9546SAutomerger Merge Worker break; 570*a71a9546SAutomerger Merge Worker case '4': 571*a71a9546SAutomerger Merge Worker if (invert) 572*a71a9546SAutomerger Merge Worker info->flags |= IPSET_FLAG_SKIP_COUNTER_UPDATE; 573*a71a9546SAutomerger Merge Worker break; 574*a71a9546SAutomerger Merge Worker case '3': 575*a71a9546SAutomerger Merge Worker if (invert) 576*a71a9546SAutomerger Merge Worker xtables_error(PARAMETER_PROBLEM, 577*a71a9546SAutomerger Merge Worker "--return-nomatch flag cannot be inverted"); 578*a71a9546SAutomerger Merge Worker info->flags |= IPSET_FLAG_RETURN_NOMATCH; 579*a71a9546SAutomerger Merge Worker break; 580*a71a9546SAutomerger Merge Worker case '2': 581*a71a9546SAutomerger Merge Worker fprintf(stderr, 582*a71a9546SAutomerger Merge Worker "--set option deprecated, please use --match-set\n"); 583*a71a9546SAutomerger Merge Worker /* fall through */ 584*a71a9546SAutomerger Merge Worker case '1': /* --match-set <set> <flag>[,<flag> */ 585*a71a9546SAutomerger Merge Worker if (info->match_set.dim) 586*a71a9546SAutomerger Merge Worker xtables_error(PARAMETER_PROBLEM, 587*a71a9546SAutomerger Merge Worker "--match-set can be specified only once"); 588*a71a9546SAutomerger Merge Worker if (invert) 589*a71a9546SAutomerger Merge Worker info->match_set.flags |= IPSET_INV_MATCH; 590*a71a9546SAutomerger Merge Worker 591*a71a9546SAutomerger Merge Worker if (!argv[optind] 592*a71a9546SAutomerger Merge Worker || argv[optind][0] == '-' 593*a71a9546SAutomerger Merge Worker || argv[optind][0] == '!') 594*a71a9546SAutomerger Merge Worker xtables_error(PARAMETER_PROBLEM, 595*a71a9546SAutomerger Merge Worker "--match-set requires two args."); 596*a71a9546SAutomerger Merge Worker 597*a71a9546SAutomerger Merge Worker if (strlen(optarg) > IPSET_MAXNAMELEN - 1) 598*a71a9546SAutomerger Merge Worker xtables_error(PARAMETER_PROBLEM, 599*a71a9546SAutomerger Merge Worker "setname `%s' too long, max %d characters.", 600*a71a9546SAutomerger Merge Worker optarg, IPSET_MAXNAMELEN - 1); 601*a71a9546SAutomerger Merge Worker 602*a71a9546SAutomerger Merge Worker get_set_byname(optarg, &info->match_set); 603*a71a9546SAutomerger Merge Worker parse_dirs(argv[optind], &info->match_set); 604*a71a9546SAutomerger Merge Worker DEBUGP("parse: set index %u\n", info->match_set.index); 605*a71a9546SAutomerger Merge Worker optind++; 606*a71a9546SAutomerger Merge Worker 607*a71a9546SAutomerger Merge Worker *flags = 1; 608*a71a9546SAutomerger Merge Worker break; 609*a71a9546SAutomerger Merge Worker } 610*a71a9546SAutomerger Merge Worker 611*a71a9546SAutomerger Merge Worker return 1; 612*a71a9546SAutomerger Merge Worker } 613*a71a9546SAutomerger Merge Worker 614*a71a9546SAutomerger Merge Worker static void 615*a71a9546SAutomerger Merge Worker set_printv4_counter(const struct ip_set_counter_match *c, const char *name, 616*a71a9546SAutomerger Merge Worker const char *sep) 617*a71a9546SAutomerger Merge Worker { 618*a71a9546SAutomerger Merge Worker switch (c->op) { 619*a71a9546SAutomerger Merge Worker case IPSET_COUNTER_EQ: 620*a71a9546SAutomerger Merge Worker printf(" %s%s-eq %llu", sep, name, c->value); 621*a71a9546SAutomerger Merge Worker break; 622*a71a9546SAutomerger Merge Worker case IPSET_COUNTER_NE: 623*a71a9546SAutomerger Merge Worker printf(" ! %s%s-eq %llu", sep, name, c->value); 624*a71a9546SAutomerger Merge Worker break; 625*a71a9546SAutomerger Merge Worker case IPSET_COUNTER_LT: 626*a71a9546SAutomerger Merge Worker printf(" %s%s-lt %llu", sep, name, c->value); 627*a71a9546SAutomerger Merge Worker break; 628*a71a9546SAutomerger Merge Worker case IPSET_COUNTER_GT: 629*a71a9546SAutomerger Merge Worker printf(" %s%s-gt %llu", sep, name, c->value); 630*a71a9546SAutomerger Merge Worker break; 631*a71a9546SAutomerger Merge Worker } 632*a71a9546SAutomerger Merge Worker } 633*a71a9546SAutomerger Merge Worker 634*a71a9546SAutomerger Merge Worker static void 635*a71a9546SAutomerger Merge Worker set_print_v4_matchinfo(const struct xt_set_info_match_v4 *info, 636*a71a9546SAutomerger Merge Worker const char *opt, const char *sep) 637*a71a9546SAutomerger Merge Worker { 638*a71a9546SAutomerger Merge Worker print_match(opt, &info->match_set); 639*a71a9546SAutomerger Merge Worker if (info->flags & IPSET_FLAG_RETURN_NOMATCH) 640*a71a9546SAutomerger Merge Worker printf(" %sreturn-nomatch", sep); 641*a71a9546SAutomerger Merge Worker if ((info->flags & IPSET_FLAG_SKIP_COUNTER_UPDATE)) 642*a71a9546SAutomerger Merge Worker printf(" ! %supdate-counters", sep); 643*a71a9546SAutomerger Merge Worker if ((info->flags & IPSET_FLAG_SKIP_SUBCOUNTER_UPDATE)) 644*a71a9546SAutomerger Merge Worker printf(" ! %supdate-subcounters", sep); 645*a71a9546SAutomerger Merge Worker set_printv4_counter(&info->packets, "packets", sep); 646*a71a9546SAutomerger Merge Worker set_printv4_counter(&info->bytes, "bytes", sep); 647*a71a9546SAutomerger Merge Worker } 648*a71a9546SAutomerger Merge Worker 649*a71a9546SAutomerger Merge Worker /* Prints out the matchinfo. */ 650*a71a9546SAutomerger Merge Worker static void 651*a71a9546SAutomerger Merge Worker set_print_v4(const void *ip, const struct xt_entry_match *match, int numeric) 652*a71a9546SAutomerger Merge Worker { 653*a71a9546SAutomerger Merge Worker const struct xt_set_info_match_v4 *info = (const void *)match->data; 654*a71a9546SAutomerger Merge Worker 655*a71a9546SAutomerger Merge Worker set_print_v4_matchinfo(info, "match-set", ""); 656*a71a9546SAutomerger Merge Worker } 657*a71a9546SAutomerger Merge Worker 658*a71a9546SAutomerger Merge Worker static void 659*a71a9546SAutomerger Merge Worker set_save_v4(const void *ip, const struct xt_entry_match *match) 660*a71a9546SAutomerger Merge Worker { 661*a71a9546SAutomerger Merge Worker const struct xt_set_info_match_v4 *info = (const void *)match->data; 662*a71a9546SAutomerger Merge Worker 663*a71a9546SAutomerger Merge Worker set_print_v4_matchinfo(info, "--match-set", "--"); 664*a71a9546SAutomerger Merge Worker } 665*a71a9546SAutomerger Merge Worker 666*a71a9546SAutomerger Merge Worker static struct xtables_match set_mt_reg[] = { 667*a71a9546SAutomerger Merge Worker { 668*a71a9546SAutomerger Merge Worker .name = "set", 669*a71a9546SAutomerger Merge Worker .revision = 0, 670*a71a9546SAutomerger Merge Worker .version = XTABLES_VERSION, 671*a71a9546SAutomerger Merge Worker .family = NFPROTO_IPV4, 672*a71a9546SAutomerger Merge Worker .size = XT_ALIGN(sizeof(struct xt_set_info_match_v0)), 673*a71a9546SAutomerger Merge Worker .userspacesize = XT_ALIGN(sizeof(struct xt_set_info_match_v0)), 674*a71a9546SAutomerger Merge Worker .help = set_help_v0, 675*a71a9546SAutomerger Merge Worker .parse = set_parse_v0, 676*a71a9546SAutomerger Merge Worker .final_check = set_check_v0, 677*a71a9546SAutomerger Merge Worker .print = set_print_v0, 678*a71a9546SAutomerger Merge Worker .save = set_save_v0, 679*a71a9546SAutomerger Merge Worker .extra_opts = set_opts_v0, 680*a71a9546SAutomerger Merge Worker }, 681*a71a9546SAutomerger Merge Worker { 682*a71a9546SAutomerger Merge Worker .name = "set", 683*a71a9546SAutomerger Merge Worker .revision = 1, 684*a71a9546SAutomerger Merge Worker .version = XTABLES_VERSION, 685*a71a9546SAutomerger Merge Worker .family = NFPROTO_UNSPEC, 686*a71a9546SAutomerger Merge Worker .size = XT_ALIGN(sizeof(struct xt_set_info_match_v1)), 687*a71a9546SAutomerger Merge Worker .userspacesize = XT_ALIGN(sizeof(struct xt_set_info_match_v1)), 688*a71a9546SAutomerger Merge Worker .help = set_help_v0, 689*a71a9546SAutomerger Merge Worker .parse = set_parse_v1, 690*a71a9546SAutomerger Merge Worker .final_check = set_check_v0, 691*a71a9546SAutomerger Merge Worker .print = set_print_v1, 692*a71a9546SAutomerger Merge Worker .save = set_save_v1, 693*a71a9546SAutomerger Merge Worker .extra_opts = set_opts_v0, 694*a71a9546SAutomerger Merge Worker }, 695*a71a9546SAutomerger Merge Worker { 696*a71a9546SAutomerger Merge Worker .name = "set", 697*a71a9546SAutomerger Merge Worker .revision = 2, 698*a71a9546SAutomerger Merge Worker .version = XTABLES_VERSION, 699*a71a9546SAutomerger Merge Worker .family = NFPROTO_UNSPEC, 700*a71a9546SAutomerger Merge Worker .size = XT_ALIGN(sizeof(struct xt_set_info_match_v1)), 701*a71a9546SAutomerger Merge Worker .userspacesize = XT_ALIGN(sizeof(struct xt_set_info_match_v1)), 702*a71a9546SAutomerger Merge Worker .help = set_help_v2, 703*a71a9546SAutomerger Merge Worker .parse = set_parse_v2, 704*a71a9546SAutomerger Merge Worker .final_check = set_check_v0, 705*a71a9546SAutomerger Merge Worker .print = set_print_v2, 706*a71a9546SAutomerger Merge Worker .save = set_save_v2, 707*a71a9546SAutomerger Merge Worker .extra_opts = set_opts_v2, 708*a71a9546SAutomerger Merge Worker }, 709*a71a9546SAutomerger Merge Worker { 710*a71a9546SAutomerger Merge Worker .name = "set", 711*a71a9546SAutomerger Merge Worker .revision = 3, 712*a71a9546SAutomerger Merge Worker .version = XTABLES_VERSION, 713*a71a9546SAutomerger Merge Worker .family = NFPROTO_UNSPEC, 714*a71a9546SAutomerger Merge Worker .size = XT_ALIGN(sizeof(struct xt_set_info_match_v3)), 715*a71a9546SAutomerger Merge Worker .userspacesize = XT_ALIGN(sizeof(struct xt_set_info_match_v3)), 716*a71a9546SAutomerger Merge Worker .help = set_help_v3, 717*a71a9546SAutomerger Merge Worker .parse = set_parse_v3, 718*a71a9546SAutomerger Merge Worker .final_check = set_check_v0, 719*a71a9546SAutomerger Merge Worker .print = set_print_v3, 720*a71a9546SAutomerger Merge Worker .save = set_save_v3, 721*a71a9546SAutomerger Merge Worker .extra_opts = set_opts_v3, 722*a71a9546SAutomerger Merge Worker }, 723*a71a9546SAutomerger Merge Worker { 724*a71a9546SAutomerger Merge Worker .name = "set", 725*a71a9546SAutomerger Merge Worker .revision = 4, 726*a71a9546SAutomerger Merge Worker .version = XTABLES_VERSION, 727*a71a9546SAutomerger Merge Worker .family = NFPROTO_UNSPEC, 728*a71a9546SAutomerger Merge Worker .size = XT_ALIGN(sizeof(struct xt_set_info_match_v4)), 729*a71a9546SAutomerger Merge Worker .userspacesize = XT_ALIGN(sizeof(struct xt_set_info_match_v4)), 730*a71a9546SAutomerger Merge Worker .help = set_help_v3, 731*a71a9546SAutomerger Merge Worker .parse = set_parse_v4, 732*a71a9546SAutomerger Merge Worker .final_check = set_check_v0, 733*a71a9546SAutomerger Merge Worker .print = set_print_v4, 734*a71a9546SAutomerger Merge Worker .save = set_save_v4, 735*a71a9546SAutomerger Merge Worker .extra_opts = set_opts_v3, 736*a71a9546SAutomerger Merge Worker }, 737*a71a9546SAutomerger Merge Worker }; 738*a71a9546SAutomerger Merge Worker 739*a71a9546SAutomerger Merge Worker void _init(void) 740*a71a9546SAutomerger Merge Worker { 741*a71a9546SAutomerger Merge Worker xtables_register_matches(set_mt_reg, ARRAY_SIZE(set_mt_reg)); 742*a71a9546SAutomerger Merge Worker } 743