19640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt/* Shared library add-on to iptables to add u32 matching, 29640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt * generalized matching on values found at packet offsets 39640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt * 49640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt * Detailed doc is in the kernel module source 59640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt * net/netfilter/xt_u32.c 69640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt * 79640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt * (C) 2002 by Don Cohen <don-netf@isis.cs3-inc.com> 89640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt * Released under the terms of GNU GPL v2 9032722b2d24138ee92e459c779ae4869f33b1f37Jan Engelhardt * 10032722b2d24138ee92e459c779ae4869f33b1f37Jan Engelhardt * Copyright © CC Computer Consultants GmbH, 2007 11032722b2d24138ee92e459c779ae4869f33b1f37Jan Engelhardt * Contact: <jengelh@computergmbh.de> 129640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt */ 139640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt#include <ctype.h> 149640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt#include <errno.h> 154f7f187ffe1773487071b413491f062d141309ddJan Engelhardt#include <stdint.h> 169640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt#include <stdlib.h> 179640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt#include <stdio.h> 189640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt#include <xtables.h> 19a2a7f2b531cc582ab6cc3c2b73715ed1d58b9eabJan Engelhardt#include <linux/netfilter/xt_u32.h> 209640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt 214f7f187ffe1773487071b413491f062d141309ddJan Engelhardtenum { 224f7f187ffe1773487071b413491f062d141309ddJan Engelhardt O_U32 = 0, 234f7f187ffe1773487071b413491f062d141309ddJan Engelhardt}; 244f7f187ffe1773487071b413491f062d141309ddJan Engelhardt 254f7f187ffe1773487071b413491f062d141309ddJan Engelhardtstatic const struct xt_option_entry u32_opts[] = { 265a66f40d2f64e8792e1360906d3d6a1c829ba2b7Jan Engelhardt {.name = "u32", .id = O_U32, .type = XTTYPE_STRING, 275a66f40d2f64e8792e1360906d3d6a1c829ba2b7Jan Engelhardt .flags = XTOPT_MAND}, 284f7f187ffe1773487071b413491f062d141309ddJan Engelhardt XTOPT_TABLEEND, 299640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt}; 309640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt 319640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardtstatic void u32_help(void) 329640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt{ 339640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt printf( 348b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt "u32 match options:\n" 359640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt "[!] --u32 tests\n" 369640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt "\t\t""tests := location \"=\" value | tests \"&&\" location \"=\" value\n" 379640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt "\t\t""value := range | value \",\" range\n" 389640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt "\t\t""range := number | number \":\" number\n" 399640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt "\t\t""location := number | location operator number\n" 408b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt "\t\t""operator := \"&\" | \"<<\" | \">>\" | \"@\"\n"); 419640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt} 429640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt 439640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardtstatic void u32_dump(const struct xt_u32 *data) 449640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt{ 459640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt const struct xt_u32_test *ct; 469640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt unsigned int testind, i; 479640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt 4873866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt printf(" \""); 499640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt for (testind = 0; testind < data->ntests; ++testind) { 509640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt ct = &data->tests[testind]; 519640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt 529640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt if (testind > 0) 539640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt printf("&&"); 549640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt 559640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt printf("0x%x", ct->location[0].number); 569640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt for (i = 1; i < ct->nnums; ++i) { 579640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt switch (ct->location[i].nextop) { 589640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt case XT_U32_AND: 599640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt printf("&"); 609640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt break; 619640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt case XT_U32_LEFTSH: 629640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt printf("<<"); 639640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt break; 649640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt case XT_U32_RIGHTSH: 659640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt printf(">>"); 669640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt break; 679640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt case XT_U32_AT: 689640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt printf("@"); 699640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt break; 709640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt } 719640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt printf("0x%x", ct->location[i].number); 729640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt } 739640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt 749640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt printf("="); 759640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt for (i = 0; i < ct->nvalues; ++i) { 769640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt if (i > 0) 779640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt printf(","); 789640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt if (ct->value[i].min == ct->value[i].max) 799640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt printf("0x%x", ct->value[i].min); 809640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt else 819640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt printf("0x%x:0x%x", ct->value[i].min, 829640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt ct->value[i].max); 839640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt } 849640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt } 8573866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt putchar('\"'); 869640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt} 879640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt 889640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt/* string_to_number() is not quite what we need here ... */ 894f7f187ffe1773487071b413491f062d141309ddJan Engelhardtstatic uint32_t parse_number(const char **s, int pos) 909640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt{ 917ac405297ec38449b30e3b05fd6bf2082fd3d803Jan Engelhardt uint32_t number; 929640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt char *end; 939640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt 949640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt errno = 0; 959640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt number = strtoul(*s, &end, 0); 969640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt if (end == *s) 971829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt xtables_error(PARAMETER_PROBLEM, 989640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt "u32: at char %d: expected number", pos); 999640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt if (errno != 0) 1001829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt xtables_error(PARAMETER_PROBLEM, 1019640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt "u32: at char %d: error reading number", pos); 1029640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt *s = end; 1039640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt return number; 1049640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt} 1059640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt 1064f7f187ffe1773487071b413491f062d141309ddJan Engelhardtstatic void u32_parse(struct xt_option_call *cb) 1079640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt{ 1084f7f187ffe1773487071b413491f062d141309ddJan Engelhardt struct xt_u32 *data = cb->data; 1099640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt unsigned int testind = 0, locind = 0, valind = 0; 1109640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt struct xt_u32_test *ct = &data->tests[testind]; /* current test */ 1114f7f187ffe1773487071b413491f062d141309ddJan Engelhardt const char *arg = cb->arg; /* the argument string */ 1124f7f187ffe1773487071b413491f062d141309ddJan Engelhardt const char *start = cb->arg; 1139640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt int state = 0; 1149640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt 115373e8513c4b9b0491e46ae89397ead03d093ee76Jan Engelhardt xtables_option_parse(cb); 1164f7f187ffe1773487071b413491f062d141309ddJan Engelhardt data->invert = cb->invert; 1179640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt 1189640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt /* 1199640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt * states: 1209640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt * 0 = looking for numbers and operations, 1219640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt * 1 = looking for ranges 1229640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt */ 1239640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt while (1) { 1249640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt /* read next operand/number or range */ 1259640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt while (isspace(*arg)) 1269640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt ++arg; 1279640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt 1289640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt if (*arg == '\0') { 1299640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt /* end of argument found */ 1309640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt if (state == 0) 1311829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt xtables_error(PARAMETER_PROBLEM, 1329640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt "u32: abrupt end of input after location specifier"); 1339640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt if (valind == 0) 1341829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt xtables_error(PARAMETER_PROBLEM, 1359640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt "u32: test ended with no value specified"); 1369640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt 1379640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt ct->nnums = locind; 1389640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt ct->nvalues = valind; 1399640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt data->ntests = ++testind; 1409640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt 1419640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt if (testind > XT_U32_MAXSIZE) 1421829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt xtables_error(PARAMETER_PROBLEM, 14355951a0532e35cf73bd83b01014387616eb31431Jan Engelhardt "u32: at char %u: too many \"&&\"s", 14455951a0532e35cf73bd83b01014387616eb31431Jan Engelhardt (unsigned int)(arg - start)); 1454f7f187ffe1773487071b413491f062d141309ddJan Engelhardt return; 1469640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt } 1479640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt 1489640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt if (state == 0) { 1499640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt /* 1509640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt * reading location: read a number if nothing read yet, 1519640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt * otherwise either op number or = to end location spec 1529640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt */ 1539640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt if (*arg == '=') { 1549640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt if (locind == 0) { 1551829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt xtables_error(PARAMETER_PROBLEM, 15655951a0532e35cf73bd83b01014387616eb31431Jan Engelhardt "u32: at char %u: " 1579640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt "location spec missing", 15855951a0532e35cf73bd83b01014387616eb31431Jan Engelhardt (unsigned int)(arg - start)); 1599640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt } else { 1609640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt ++arg; 1619640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt state = 1; 1629640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt } 1639640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt } else { 1649640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt if (locind != 0) { 1659640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt /* need op before number */ 1669640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt if (*arg == '&') { 1679640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt ct->location[locind].nextop = XT_U32_AND; 1689640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt } else if (*arg == '<') { 1699640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt if (*++arg != '<') 1701829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt xtables_error(PARAMETER_PROBLEM, 17155951a0532e35cf73bd83b01014387616eb31431Jan Engelhardt "u32: at char %u: a second '<' was expected", (unsigned int)(arg - start)); 1729640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt ct->location[locind].nextop = XT_U32_LEFTSH; 1739640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt } else if (*arg == '>') { 1749640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt if (*++arg != '>') 1751829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt xtables_error(PARAMETER_PROBLEM, 17655951a0532e35cf73bd83b01014387616eb31431Jan Engelhardt "u32: at char %u: a second '>' was expected", (unsigned int)(arg - start)); 1779640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt ct->location[locind].nextop = XT_U32_RIGHTSH; 1789640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt } else if (*arg == '@') { 1799640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt ct->location[locind].nextop = XT_U32_AT; 1809640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt } else { 1811829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt xtables_error(PARAMETER_PROBLEM, 18255951a0532e35cf73bd83b01014387616eb31431Jan Engelhardt "u32: at char %u: operator expected", (unsigned int)(arg - start)); 1839640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt } 1849640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt ++arg; 1859640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt } 1869640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt /* now a number; string_to_number skips white space? */ 1879640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt ct->location[locind].number = 1889640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt parse_number(&arg, arg - start); 1899640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt if (++locind > XT_U32_MAXSIZE) 1901829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt xtables_error(PARAMETER_PROBLEM, 19155951a0532e35cf73bd83b01014387616eb31431Jan Engelhardt "u32: at char %u: too many operators", (unsigned int)(arg - start)); 1929640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt } 1939640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt } else { 1949640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt /* 1959640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt * state 1 - reading values: read a range if nothing 1969640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt * read yet, otherwise either ,range or && to end 1979640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt * test spec 1989640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt */ 1999640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt if (*arg == '&') { 2009640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt if (*++arg != '&') 2011829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt xtables_error(PARAMETER_PROBLEM, 20255951a0532e35cf73bd83b01014387616eb31431Jan Engelhardt "u32: at char %u: a second '&' was expected", (unsigned int)(arg - start)); 2039640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt if (valind == 0) { 2041829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt xtables_error(PARAMETER_PROBLEM, 20555951a0532e35cf73bd83b01014387616eb31431Jan Engelhardt "u32: at char %u: value spec missing", (unsigned int)(arg - start)); 2069640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt } else { 2079640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt ct->nnums = locind; 2089640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt ct->nvalues = valind; 2099640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt ct = &data->tests[++testind]; 2109640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt if (testind > XT_U32_MAXSIZE) 2111829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt xtables_error(PARAMETER_PROBLEM, 21255951a0532e35cf73bd83b01014387616eb31431Jan Engelhardt "u32: at char %u: too many \"&&\"s", (unsigned int)(arg - start)); 2139640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt ++arg; 2149640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt state = 0; 2159640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt locind = 0; 2169640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt valind = 0; 2179640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt } 2189640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt } else { /* read value range */ 2199640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt if (valind > 0) { /* need , before number */ 2209640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt if (*arg != ',') 2211829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt xtables_error(PARAMETER_PROBLEM, 22255951a0532e35cf73bd83b01014387616eb31431Jan Engelhardt "u32: at char %u: expected \",\" or \"&&\"", (unsigned int)(arg - start)); 2239640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt ++arg; 2249640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt } 2259640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt ct->value[valind].min = 2269640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt parse_number(&arg, arg - start); 2279640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt 2289640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt while (isspace(*arg)) 2299640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt ++arg; 2309640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt 2319640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt if (*arg == ':') { 2329640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt ++arg; 2339640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt ct->value[valind].max = 2349640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt parse_number(&arg, arg-start); 2359640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt } else { 2369640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt ct->value[valind].max = 2379640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt ct->value[valind].min; 2389640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt } 2399640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt 2409640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt if (++valind > XT_U32_MAXSIZE) 2411829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt xtables_error(PARAMETER_PROBLEM, 24255951a0532e35cf73bd83b01014387616eb31431Jan Engelhardt "u32: at char %u: too many \",\"s", (unsigned int)(arg - start)); 2439640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt } 2449640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt } 2459640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt } 2469640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt} 2479640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt 2489640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardtstatic void u32_print(const void *ip, const struct xt_entry_match *match, 2499640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt int numeric) 2509640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt{ 2519640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt const struct xt_u32 *data = (const void *)match->data; 25273866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt printf(" u32"); 2539640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt if (data->invert) 25473866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt printf(" !"); 2559640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt u32_dump(data); 2569640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt} 2579640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt 2589640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardtstatic void u32_save(const void *ip, const struct xt_entry_match *match) 2599640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt{ 2609640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt const struct xt_u32 *data = (const void *)match->data; 2619640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt if (data->invert) 26273866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt printf(" !"); 26373866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt printf(" --u32"); 2649640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt u32_dump(data); 2659640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt} 2669640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt 267181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardtstatic struct xtables_match u32_match = { 2689640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt .name = "u32", 26942979363f3958b4436c6d2503753c182c58e55eaJan Engelhardt .family = NFPROTO_UNSPEC, 2708b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt .version = XTABLES_VERSION, 2719640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt .size = XT_ALIGN(sizeof(struct xt_u32)), 2729640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt .userspacesize = XT_ALIGN(sizeof(struct xt_u32)), 2739640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt .help = u32_help, 2749640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt .print = u32_print, 2759640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt .save = u32_save, 2764f7f187ffe1773487071b413491f062d141309ddJan Engelhardt .x6_parse = u32_parse, 2774f7f187ffe1773487071b413491f062d141309ddJan Engelhardt .x6_options = u32_opts, 2789640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt}; 2799640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt 2809640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardtvoid _init(void) 2819640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt{ 282181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt xtables_register_match(&u32_match); 2839640e529bd08c4c0458246fae0fd6b473c94ab46Jan Engelhardt} 284