11b8db4f4ca250f13a0e7edddb31cfc1f82d42806Jan Engelhardt#include <stdint.h> 2e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher#include <stdio.h> 3e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher#include <string.h> 45d9678ad3eabc34ac40dfe055d7f6a8e44445a5aJan Engelhardt#include <xtables.h> 51b8db4f4ca250f13a0e7edddb31cfc1f82d42806Jan Engelhardt#include <limits.h> /* INT_MAX in ip6_tables.h */ 6e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher#include <linux/netfilter_ipv4/ip_tables.h> 7e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 8fc9237da4e8455e34193a56e56e561d7cd0b31baHarald Welte/* special hack for icmp-type 'any': 9fc9237da4e8455e34193a56e56e561d7cd0b31baHarald Welte * Up to kernel <=2.4.20 the problem was: 10fc9237da4e8455e34193a56e56e561d7cd0b31baHarald Welte * '-p icmp ' matches all icmp packets 11fc9237da4e8455e34193a56e56e561d7cd0b31baHarald Welte * '-p icmp -m icmp' matches _only_ ICMP type 0 :( 12fc9237da4e8455e34193a56e56e561d7cd0b31baHarald Welte * This is now fixed by initializing the field * to icmp type 0xFF 13fc9237da4e8455e34193a56e56e561d7cd0b31baHarald Welte * See: https://bugzilla.netfilter.org/cgi-bin/bugzilla/show_bug.cgi?id=37 14fc9237da4e8455e34193a56e56e561d7cd0b31baHarald Welte */ 15fc9237da4e8455e34193a56e56e561d7cd0b31baHarald Welte 161b8db4f4ca250f13a0e7edddb31cfc1f82d42806Jan Engelhardtenum { 171b8db4f4ca250f13a0e7edddb31cfc1f82d42806Jan Engelhardt O_ICMP_TYPE = 0, 181b8db4f4ca250f13a0e7edddb31cfc1f82d42806Jan Engelhardt}; 191b8db4f4ca250f13a0e7edddb31cfc1f82d42806Jan Engelhardt 20e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherstruct icmp_names { 21e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher const char *name; 227ac405297ec38449b30e3b05fd6bf2082fd3d803Jan Engelhardt uint8_t type; 237ac405297ec38449b30e3b05fd6bf2082fd3d803Jan Engelhardt uint8_t code_min, code_max; 24e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher}; 25e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 26e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherstatic const struct icmp_names icmp_codes[] = { 27fc9237da4e8455e34193a56e56e561d7cd0b31baHarald Welte { "any", 0xFF, 0, 0xFF }, 28e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "echo-reply", 0, 0, 0xFF }, 29e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher /* Alias */ { "pong", 0, 0, 0xFF }, 30e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 31e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "destination-unreachable", 3, 0, 0xFF }, 32e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "network-unreachable", 3, 0, 0 }, 33e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "host-unreachable", 3, 1, 1 }, 34e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "protocol-unreachable", 3, 2, 2 }, 35e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "port-unreachable", 3, 3, 3 }, 36e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "fragmentation-needed", 3, 4, 4 }, 37e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "source-route-failed", 3, 5, 5 }, 38e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "network-unknown", 3, 6, 6 }, 39e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "host-unknown", 3, 7, 7 }, 40e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "network-prohibited", 3, 9, 9 }, 41e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "host-prohibited", 3, 10, 10 }, 42e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "TOS-network-unreachable", 3, 11, 11 }, 43e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "TOS-host-unreachable", 3, 12, 12 }, 44e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "communication-prohibited", 3, 13, 13 }, 45e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "host-precedence-violation", 3, 14, 14 }, 46e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "precedence-cutoff", 3, 15, 15 }, 47e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 48e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "source-quench", 4, 0, 0xFF }, 49e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 50e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "redirect", 5, 0, 0xFF }, 51e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "network-redirect", 5, 0, 0 }, 52e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "host-redirect", 5, 1, 1 }, 53e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "TOS-network-redirect", 5, 2, 2 }, 54e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "TOS-host-redirect", 5, 3, 3 }, 55e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 56e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "echo-request", 8, 0, 0xFF }, 57e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher /* Alias */ { "ping", 8, 0, 0xFF }, 58e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 59e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "router-advertisement", 9, 0, 0xFF }, 60e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 61e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "router-solicitation", 10, 0, 0xFF }, 62e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 63e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "time-exceeded", 11, 0, 0xFF }, 64e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher /* Alias */ { "ttl-exceeded", 11, 0, 0xFF }, 65e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "ttl-zero-during-transit", 11, 0, 0 }, 66e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "ttl-zero-during-reassembly", 11, 1, 1 }, 67e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 68e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "parameter-problem", 12, 0, 0xFF }, 69e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "ip-header-bad", 12, 0, 0 }, 70e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "required-option-missing", 12, 1, 1 }, 71e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 72e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "timestamp-request", 13, 0, 0xFF }, 73e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 74e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "timestamp-reply", 14, 0, 0xFF }, 75e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 76e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "address-mask-request", 17, 0, 0xFF }, 77e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 78e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "address-mask-reply", 18, 0, 0xFF } 79e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher}; 80e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 81e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherstatic void 82500f483fff529dcd88ec96b9d5054be6cd6363a0Patrick McHardyprint_icmptypes(void) 83e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher{ 84e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher unsigned int i; 85e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher printf("Valid ICMP Types:"); 86e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 872c69b55e55f2efc5a334b87ccdceaa9de0ecb658Jan Engelhardt for (i = 0; i < ARRAY_SIZE(icmp_codes); ++i) { 88e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (i && icmp_codes[i].type == icmp_codes[i-1].type) { 89e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (icmp_codes[i].code_min == icmp_codes[i-1].code_min 90e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher && (icmp_codes[i].code_max 91e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher == icmp_codes[i-1].code_max)) 92e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher printf(" (%s)", icmp_codes[i].name); 93e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher else 94e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher printf("\n %s", icmp_codes[i].name); 95e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 96e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher else 97e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher printf("\n%s", icmp_codes[i].name); 98e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 99e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher printf("\n"); 100e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher} 101e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 10259d164019340d110d302634e429320577f0db7beJan Engelhardtstatic void icmp_help(void) 103e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher{ 104e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher printf( 1058b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt"icmp match options:\n" 106967279231a9ecfa99f26694a954afc535c63db1dJan Engelhardt"[!] --icmp-type typename match icmp type\n" 1073d12c3bbffb43182df9ac5c0ad549b095d30d021Jan Engelhardt"[!] --icmp-type type[/code] (or numeric type or type/code)\n"); 108e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher print_icmptypes(); 109e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher} 110e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1111b8db4f4ca250f13a0e7edddb31cfc1f82d42806Jan Engelhardtstatic const struct xt_option_entry icmp_opts[] = { 1121b8db4f4ca250f13a0e7edddb31cfc1f82d42806Jan Engelhardt {.name = "icmp-type", .id = O_ICMP_TYPE, .type = XTTYPE_STRING, 1131b8db4f4ca250f13a0e7edddb31cfc1f82d42806Jan Engelhardt .flags = XTOPT_MAND | XTOPT_INVERT}, 1141b8db4f4ca250f13a0e7edddb31cfc1f82d42806Jan Engelhardt XTOPT_TABLEEND, 115e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher}; 116e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1178115e5425721cd610b6390c3d4c24540773b0520Pablo Neirastatic void 1187ac405297ec38449b30e3b05fd6bf2082fd3d803Jan Engelhardtparse_icmp(const char *icmptype, uint8_t *type, uint8_t code[]) 119e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher{ 1202c69b55e55f2efc5a334b87ccdceaa9de0ecb658Jan Engelhardt static const unsigned int limit = ARRAY_SIZE(icmp_codes); 121e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher unsigned int match = limit; 122e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher unsigned int i; 123e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 124e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher for (i = 0; i < limit; i++) { 125e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (strncasecmp(icmp_codes[i].name, icmptype, strlen(icmptype)) 126e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher == 0) { 127e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (match != limit) 1281829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt xtables_error(PARAMETER_PROBLEM, 129e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher "Ambiguous ICMP type `%s':" 130e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher " `%s' or `%s'?", 131e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher icmptype, 132e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher icmp_codes[match].name, 133e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher icmp_codes[i].name); 134e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher match = i; 135e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 136e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 137e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 138e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (match != limit) { 139e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher *type = icmp_codes[match].type; 140e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher code[0] = icmp_codes[match].code_min; 141e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher code[1] = icmp_codes[match].code_max; 142e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } else { 143e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher char *slash; 144e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher char buffer[strlen(icmptype) + 1]; 145b47197629735fa1cb93112dfd7d1c4fbcdb24a95Harald Welte unsigned int number; 146e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 147e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher strcpy(buffer, icmptype); 148e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher slash = strchr(buffer, '/'); 149e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 150e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (slash) 151e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher *slash = '\0'; 152e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1535f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt if (!xtables_strtoui(buffer, NULL, &number, 0, UINT8_MAX)) 1541829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt xtables_error(PARAMETER_PROBLEM, 155e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher "Invalid ICMP type `%s'\n", buffer); 156e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher *type = number; 157e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (slash) { 1585f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt if (!xtables_strtoui(slash+1, NULL, &number, 0, UINT8_MAX)) 1591829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt xtables_error(PARAMETER_PROBLEM, 160e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher "Invalid ICMP code `%s'\n", 161e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher slash+1); 162e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher code[0] = code[1] = number; 163e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } else { 164e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher code[0] = 0; 165e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher code[1] = 0xFF; 166e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 167e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 168e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher} 169e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 17059d164019340d110d302634e429320577f0db7beJan Engelhardtstatic void icmp_init(struct xt_entry_match *m) 171e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher{ 172e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher struct ipt_icmp *icmpinfo = (struct ipt_icmp *)m->data; 173e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 174fc9237da4e8455e34193a56e56e561d7cd0b31baHarald Welte icmpinfo->type = 0xFF; 175e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher icmpinfo->code[1] = 0xFF; 176e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher} 177e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1781b8db4f4ca250f13a0e7edddb31cfc1f82d42806Jan Engelhardtstatic void icmp_parse(struct xt_option_call *cb) 179e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher{ 1801b8db4f4ca250f13a0e7edddb31cfc1f82d42806Jan Engelhardt struct ipt_icmp *icmpinfo = cb->data; 181e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1821b8db4f4ca250f13a0e7edddb31cfc1f82d42806Jan Engelhardt xtables_option_parse(cb); 1831b8db4f4ca250f13a0e7edddb31cfc1f82d42806Jan Engelhardt parse_icmp(cb->arg, &icmpinfo->type, icmpinfo->code); 1841b8db4f4ca250f13a0e7edddb31cfc1f82d42806Jan Engelhardt if (cb->invert) 1851b8db4f4ca250f13a0e7edddb31cfc1f82d42806Jan Engelhardt icmpinfo->invflags |= IPT_ICMP_INV; 186e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher} 187e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1887ac405297ec38449b30e3b05fd6bf2082fd3d803Jan Engelhardtstatic void print_icmptype(uint8_t type, 1897ac405297ec38449b30e3b05fd6bf2082fd3d803Jan Engelhardt uint8_t code_min, uint8_t code_max, 190e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher int invert, 191e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher int numeric) 192e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher{ 193e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (!numeric) { 194e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher unsigned int i; 195e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1962c69b55e55f2efc5a334b87ccdceaa9de0ecb658Jan Engelhardt for (i = 0; i < ARRAY_SIZE(icmp_codes); ++i) 197e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (icmp_codes[i].type == type 198e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher && icmp_codes[i].code_min == code_min 199e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher && icmp_codes[i].code_max == code_max) 200e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher break; 201e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 2022c69b55e55f2efc5a334b87ccdceaa9de0ecb658Jan Engelhardt if (i != ARRAY_SIZE(icmp_codes)) { 20373866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt printf(" %s%s", 204e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher invert ? "!" : "", 205e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher icmp_codes[i].name); 206e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher return; 207e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 208e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 209e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 210e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (invert) 21173866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt printf(" !"); 212e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 213e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher printf("type %u", type); 21473866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt if (code_min == code_max) 21573866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt printf(" code %u", code_min); 21673866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt else if (code_min != 0 || code_max != 0xFF) 21773866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt printf(" codes %u-%u", code_min, code_max); 218e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher} 219e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 22059d164019340d110d302634e429320577f0db7beJan Engelhardtstatic void icmp_print(const void *ip, const struct xt_entry_match *match, 22159d164019340d110d302634e429320577f0db7beJan Engelhardt int numeric) 222e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher{ 223e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher const struct ipt_icmp *icmp = (struct ipt_icmp *)match->data; 224e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 22573866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt printf(" icmp"); 226e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher print_icmptype(icmp->type, icmp->code[0], icmp->code[1], 227e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher icmp->invflags & IPT_ICMP_INV, 228e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher numeric); 229e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 230e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (icmp->invflags & ~IPT_ICMP_INV) 23173866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt printf(" Unknown invflags: 0x%X", 232e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher icmp->invflags & ~IPT_ICMP_INV); 233e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher} 234e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 23559d164019340d110d302634e429320577f0db7beJan Engelhardtstatic void icmp_save(const void *ip, const struct xt_entry_match *match) 236e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher{ 237e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher const struct ipt_icmp *icmp = (struct ipt_icmp *)match->data; 238e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 239e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (icmp->invflags & IPT_ICMP_INV) 24073866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt printf(" !"); 241e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 242fc9237da4e8455e34193a56e56e561d7cd0b31baHarald Welte /* special hack for 'any' case */ 243fc9237da4e8455e34193a56e56e561d7cd0b31baHarald Welte if (icmp->type == 0xFF) { 24473866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt printf(" --icmp-type any"); 245fc9237da4e8455e34193a56e56e561d7cd0b31baHarald Welte } else { 24673866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt printf(" --icmp-type %u", icmp->type); 247fc9237da4e8455e34193a56e56e561d7cd0b31baHarald Welte if (icmp->code[0] != 0 || icmp->code[1] != 0xFF) 248fc9237da4e8455e34193a56e56e561d7cd0b31baHarald Welte printf("/%u", icmp->code[0]); 249fc9237da4e8455e34193a56e56e561d7cd0b31baHarald Welte } 250e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher} 251e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 2528b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardtstatic struct xtables_match icmp_mt_reg = { 2538caee8b9e34fed4562fcff553197c161fc9d9979Pablo Neira .name = "icmp", 2548b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt .version = XTABLES_VERSION, 25503d99486d8283552705b58dc55b6085dffc38792Jan Engelhardt .family = NFPROTO_IPV4, 2568b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt .size = XT_ALIGN(sizeof(struct ipt_icmp)), 2578b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt .userspacesize = XT_ALIGN(sizeof(struct ipt_icmp)), 25859d164019340d110d302634e429320577f0db7beJan Engelhardt .help = icmp_help, 25959d164019340d110d302634e429320577f0db7beJan Engelhardt .init = icmp_init, 26059d164019340d110d302634e429320577f0db7beJan Engelhardt .print = icmp_print, 26159d164019340d110d302634e429320577f0db7beJan Engelhardt .save = icmp_save, 2621b8db4f4ca250f13a0e7edddb31cfc1f82d42806Jan Engelhardt .x6_parse = icmp_parse, 2631b8db4f4ca250f13a0e7edddb31cfc1f82d42806Jan Engelhardt .x6_options = icmp_opts, 264e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher}; 265e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 266e6869a8f59d779ff4d5a0984c86d80db7078496Marc Bouchervoid _init(void) 267e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher{ 2688b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt xtables_register_match(&icmp_mt_reg); 269e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher} 270