libipt_ah.c revision 8b7c64d6ba156a99008fcd810cba874c73294333
1/* Shared library add-on to iptables to add AH support. */ 2#include <stdio.h> 3#include <netdb.h> 4#include <string.h> 5#include <stdlib.h> 6#include <getopt.h> 7#include <errno.h> 8#include <iptables.h> 9#include <linux/netfilter_ipv4/ipt_ah.h> 10 11/* Function which prints out usage message. */ 12static void ah_help(void) 13{ 14 printf( 15"ah match options:\n" 16" --ahspi [!] spi[:spi]\n" 17" match spi (range)\n"); 18} 19 20static const struct option ah_opts[] = { 21 { "ahspi", 1, NULL, '1' }, 22 { .name = NULL } 23}; 24 25static u_int32_t 26parse_ah_spi(const char *spistr) 27{ 28 unsigned long int spi; 29 char* ep; 30 31 spi = strtoul(spistr,&ep,0) ; 32 33 if ( spistr == ep ) { 34 exit_error(PARAMETER_PROBLEM, 35 "AH no valid digits in spi `%s'", spistr); 36 } 37 if ( spi == ULONG_MAX && errno == ERANGE ) { 38 exit_error(PARAMETER_PROBLEM, 39 "spi `%s' specified too big: would overflow", spistr); 40 } 41 if ( *spistr != '\0' && *ep != '\0' ) { 42 exit_error(PARAMETER_PROBLEM, 43 "AH error parsing spi `%s'", spistr); 44 } 45 return (u_int32_t) spi; 46} 47 48static void 49parse_ah_spis(const char *spistring, u_int32_t *spis) 50{ 51 char *buffer; 52 char *cp; 53 54 buffer = strdup(spistring); 55 if ((cp = strchr(buffer, ':')) == NULL) 56 spis[0] = spis[1] = parse_ah_spi(buffer); 57 else { 58 *cp = '\0'; 59 cp++; 60 61 spis[0] = buffer[0] ? parse_ah_spi(buffer) : 0; 62 spis[1] = cp[0] ? parse_ah_spi(cp) : 0xFFFFFFFF; 63 } 64 free(buffer); 65} 66 67/* Initialize the match. */ 68static void ah_init(struct xt_entry_match *m) 69{ 70 struct ipt_ah *ahinfo = (struct ipt_ah *)m->data; 71 72 ahinfo->spis[1] = 0xFFFFFFFF; 73} 74 75#define AH_SPI 0x01 76 77/* Function which parses command options; returns true if it 78 ate an option */ 79static int ah_parse(int c, char **argv, int invert, unsigned int *flags, 80 const void *entry, struct xt_entry_match **match) 81{ 82 struct ipt_ah *ahinfo = (struct ipt_ah *)(*match)->data; 83 84 switch (c) { 85 case '1': 86 if (*flags & AH_SPI) 87 exit_error(PARAMETER_PROBLEM, 88 "Only one `--ahspi' allowed"); 89 check_inverse(optarg, &invert, &optind, 0); 90 parse_ah_spis(argv[optind-1], ahinfo->spis); 91 if (invert) 92 ahinfo->invflags |= IPT_AH_INV_SPI; 93 *flags |= AH_SPI; 94 break; 95 default: 96 return 0; 97 } 98 99 return 1; 100} 101 102static void 103print_spis(const char *name, u_int32_t min, u_int32_t max, 104 int invert) 105{ 106 const char *inv = invert ? "!" : ""; 107 108 if (min != 0 || max != 0xFFFFFFFF || invert) { 109 printf("%s", name); 110 if (min == max) { 111 printf(":%s", inv); 112 printf("%u", min); 113 } else { 114 printf("s:%s", inv); 115 printf("%u",min); 116 printf(":"); 117 printf("%u",max); 118 } 119 printf(" "); 120 } 121} 122 123/* Prints out the union ipt_matchinfo. */ 124static void ah_print(const void *ip, const struct xt_entry_match *match, 125 int numeric) 126{ 127 const struct ipt_ah *ah = (struct ipt_ah *)match->data; 128 129 printf("ah "); 130 print_spis("spi", ah->spis[0], ah->spis[1], 131 ah->invflags & IPT_AH_INV_SPI); 132 if (ah->invflags & ~IPT_AH_INV_MASK) 133 printf("Unknown invflags: 0x%X ", 134 ah->invflags & ~IPT_AH_INV_MASK); 135} 136 137/* Saves the union ipt_matchinfo in parsable form to stdout. */ 138static void ah_save(const void *ip, const struct xt_entry_match *match) 139{ 140 const struct ipt_ah *ahinfo = (struct ipt_ah *)match->data; 141 142 if (!(ahinfo->spis[0] == 0 143 && ahinfo->spis[1] == 0xFFFFFFFF)) { 144 printf("--ahspi %s", 145 (ahinfo->invflags & IPT_AH_INV_SPI) ? "! " : ""); 146 if (ahinfo->spis[0] 147 != ahinfo->spis[1]) 148 printf("%u:%u ", 149 ahinfo->spis[0], 150 ahinfo->spis[1]); 151 else 152 printf("%u ", 153 ahinfo->spis[0]); 154 } 155 156} 157 158static struct xtables_match ah_mt_reg = { 159 .name = "ah", 160 .version = XTABLES_VERSION, 161 .family = PF_INET, 162 .size = XT_ALIGN(sizeof(struct ipt_ah)), 163 .userspacesize = XT_ALIGN(sizeof(struct ipt_ah)), 164 .help = ah_help, 165 .init = ah_init, 166 .parse = ah_parse, 167 .print = ah_print, 168 .save = ah_save, 169 .extra_opts = ah_opts, 170}; 171 172void 173_init(void) 174{ 175 xtables_register_match(&ah_mt_reg); 176} 177