libxt_esp.c revision 181dead3f13befe02769ef479bcbb51801b7fc4e
1524518261009f3f81febfdd8398becc4a80cc941Rusty Russell/* Shared library add-on to iptables to add ESP support. */ 2524518261009f3f81febfdd8398becc4a80cc941Rusty Russell#include <stdio.h> 3524518261009f3f81febfdd8398becc4a80cc941Rusty Russell#include <netdb.h> 4524518261009f3f81febfdd8398becc4a80cc941Rusty Russell#include <string.h> 5524518261009f3f81febfdd8398becc4a80cc941Rusty Russell#include <stdlib.h> 6524518261009f3f81febfdd8398becc4a80cc941Rusty Russell#include <getopt.h> 7524518261009f3f81febfdd8398becc4a80cc941Rusty Russell#include <errno.h> 80a04e8d695549788213f842cc99c724a564a88dfYasuyuki KOZAKAI#include <xtables.h> 90a04e8d695549788213f842cc99c724a564a88dfYasuyuki KOZAKAI#include <linux/netfilter/xt_esp.h> 10524518261009f3f81febfdd8398becc4a80cc941Rusty Russell 11524518261009f3f81febfdd8398becc4a80cc941Rusty Russell/* Function which prints out usage message. */ 12181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardtstatic void esp_help(void) 13524518261009f3f81febfdd8398becc4a80cc941Rusty Russell{ 14524518261009f3f81febfdd8398becc4a80cc941Rusty Russell printf( 15524518261009f3f81febfdd8398becc4a80cc941Rusty Russell"ESP v%s options:\n" 16524518261009f3f81febfdd8398becc4a80cc941Rusty Russell" --espspi [!] spi[:spi]\n" 17524518261009f3f81febfdd8398becc4a80cc941Rusty Russell" match spi (range)\n", 1880fe35d6339b53a12ddaec41885613e4e37ed031Harald WelteIPTABLES_VERSION); 19524518261009f3f81febfdd8398becc4a80cc941Rusty Russell} 20524518261009f3f81febfdd8398becc4a80cc941Rusty Russell 21181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardtstatic const struct option esp_opts[] = { 22500f483fff529dcd88ec96b9d5054be6cd6363a0Patrick McHardy { "espspi", 1, NULL, '1' }, 23500f483fff529dcd88ec96b9d5054be6cd6363a0Patrick McHardy { } 24524518261009f3f81febfdd8398becc4a80cc941Rusty Russell}; 25524518261009f3f81febfdd8398becc4a80cc941Rusty Russell 26524518261009f3f81febfdd8398becc4a80cc941Rusty Russellstatic u_int32_t 27524518261009f3f81febfdd8398becc4a80cc941Rusty Russellparse_esp_spi(const char *spistr) 28524518261009f3f81febfdd8398becc4a80cc941Rusty Russell{ 29524518261009f3f81febfdd8398becc4a80cc941Rusty Russell unsigned long int spi; 30524518261009f3f81febfdd8398becc4a80cc941Rusty Russell char* ep; 31524518261009f3f81febfdd8398becc4a80cc941Rusty Russell 32524518261009f3f81febfdd8398becc4a80cc941Rusty Russell spi = strtoul(spistr,&ep,0) ; 33524518261009f3f81febfdd8398becc4a80cc941Rusty Russell 34524518261009f3f81febfdd8398becc4a80cc941Rusty Russell if ( spistr == ep ) { 35524518261009f3f81febfdd8398becc4a80cc941Rusty Russell exit_error(PARAMETER_PROBLEM, 36524518261009f3f81febfdd8398becc4a80cc941Rusty Russell "ESP no valid digits in spi `%s'", spistr); 37524518261009f3f81febfdd8398becc4a80cc941Rusty Russell } 38524518261009f3f81febfdd8398becc4a80cc941Rusty Russell if ( spi == ULONG_MAX && errno == ERANGE ) { 39524518261009f3f81febfdd8398becc4a80cc941Rusty Russell exit_error(PARAMETER_PROBLEM, 40524518261009f3f81febfdd8398becc4a80cc941Rusty Russell "spi `%s' specified too big: would overflow", spistr); 41524518261009f3f81febfdd8398becc4a80cc941Rusty Russell } 42524518261009f3f81febfdd8398becc4a80cc941Rusty Russell if ( *spistr != '\0' && *ep != '\0' ) { 43524518261009f3f81febfdd8398becc4a80cc941Rusty Russell exit_error(PARAMETER_PROBLEM, 44524518261009f3f81febfdd8398becc4a80cc941Rusty Russell "ESP error parsing spi `%s'", spistr); 45524518261009f3f81febfdd8398becc4a80cc941Rusty Russell } 46524518261009f3f81febfdd8398becc4a80cc941Rusty Russell return (u_int32_t) spi; 47524518261009f3f81febfdd8398becc4a80cc941Rusty Russell} 48524518261009f3f81febfdd8398becc4a80cc941Rusty Russell 49524518261009f3f81febfdd8398becc4a80cc941Rusty Russellstatic void 50524518261009f3f81febfdd8398becc4a80cc941Rusty Russellparse_esp_spis(const char *spistring, u_int32_t *spis) 51524518261009f3f81febfdd8398becc4a80cc941Rusty Russell{ 52524518261009f3f81febfdd8398becc4a80cc941Rusty Russell char *buffer; 53524518261009f3f81febfdd8398becc4a80cc941Rusty Russell char *cp; 54524518261009f3f81febfdd8398becc4a80cc941Rusty Russell 55524518261009f3f81febfdd8398becc4a80cc941Rusty Russell buffer = strdup(spistring); 56524518261009f3f81febfdd8398becc4a80cc941Rusty Russell if ((cp = strchr(buffer, ':')) == NULL) 57524518261009f3f81febfdd8398becc4a80cc941Rusty Russell spis[0] = spis[1] = parse_esp_spi(buffer); 58524518261009f3f81febfdd8398becc4a80cc941Rusty Russell else { 59524518261009f3f81febfdd8398becc4a80cc941Rusty Russell *cp = '\0'; 60524518261009f3f81febfdd8398becc4a80cc941Rusty Russell cp++; 61524518261009f3f81febfdd8398becc4a80cc941Rusty Russell 62524518261009f3f81febfdd8398becc4a80cc941Rusty Russell spis[0] = buffer[0] ? parse_esp_spi(buffer) : 0; 63524518261009f3f81febfdd8398becc4a80cc941Rusty Russell spis[1] = cp[0] ? parse_esp_spi(cp) : 0xFFFFFFFF; 642c627cf60cfb1a4e67aea1b2333f2a11e23fecd8Yasuyuki KOZAKAI if (spis[0] > spis[1]) 652c627cf60cfb1a4e67aea1b2333f2a11e23fecd8Yasuyuki KOZAKAI exit_error(PARAMETER_PROBLEM, 662c627cf60cfb1a4e67aea1b2333f2a11e23fecd8Yasuyuki KOZAKAI "Invalid ESP spi range: %s", spistring); 67524518261009f3f81febfdd8398becc4a80cc941Rusty Russell } 68524518261009f3f81febfdd8398becc4a80cc941Rusty Russell free(buffer); 69524518261009f3f81febfdd8398becc4a80cc941Rusty Russell} 70524518261009f3f81febfdd8398becc4a80cc941Rusty Russell 71524518261009f3f81febfdd8398becc4a80cc941Rusty Russell/* Initialize the match. */ 72181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardtstatic void esp_init(struct xt_entry_match *m) 73524518261009f3f81febfdd8398becc4a80cc941Rusty Russell{ 740a04e8d695549788213f842cc99c724a564a88dfYasuyuki KOZAKAI struct xt_esp *espinfo = (struct xt_esp *)m->data; 75524518261009f3f81febfdd8398becc4a80cc941Rusty Russell 76524518261009f3f81febfdd8398becc4a80cc941Rusty Russell espinfo->spis[1] = 0xFFFFFFFF; 77524518261009f3f81febfdd8398becc4a80cc941Rusty Russell} 78524518261009f3f81febfdd8398becc4a80cc941Rusty Russell 79524518261009f3f81febfdd8398becc4a80cc941Rusty Russell#define ESP_SPI 0x01 80524518261009f3f81febfdd8398becc4a80cc941Rusty Russell 81524518261009f3f81febfdd8398becc4a80cc941Rusty Russell/* Function which parses command options; returns true if it 82524518261009f3f81febfdd8398becc4a80cc941Rusty Russell ate an option */ 83524518261009f3f81febfdd8398becc4a80cc941Rusty Russellstatic int 84181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardtesp_parse(int c, char **argv, int invert, unsigned int *flags, 85181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt const void *entry, struct xt_entry_match **match) 86524518261009f3f81febfdd8398becc4a80cc941Rusty Russell{ 870a04e8d695549788213f842cc99c724a564a88dfYasuyuki KOZAKAI struct xt_esp *espinfo = (struct xt_esp *)(*match)->data; 88524518261009f3f81febfdd8398becc4a80cc941Rusty Russell 89524518261009f3f81febfdd8398becc4a80cc941Rusty Russell switch (c) { 90524518261009f3f81febfdd8398becc4a80cc941Rusty Russell case '1': 91524518261009f3f81febfdd8398becc4a80cc941Rusty Russell if (*flags & ESP_SPI) 92524518261009f3f81febfdd8398becc4a80cc941Rusty Russell exit_error(PARAMETER_PROBLEM, 93f0ac814a2137abe334bd0000d59e9be4721e1ddcHarald Welte "Only one `--espspi' allowed"); 94b77f1dafb9f35752bb9685323bcacb32a0e6ddc5Harald Welte check_inverse(optarg, &invert, &optind, 0); 95524518261009f3f81febfdd8398becc4a80cc941Rusty Russell parse_esp_spis(argv[optind-1], espinfo->spis); 96524518261009f3f81febfdd8398becc4a80cc941Rusty Russell if (invert) 970a04e8d695549788213f842cc99c724a564a88dfYasuyuki KOZAKAI espinfo->invflags |= XT_ESP_INV_SPI; 98524518261009f3f81febfdd8398becc4a80cc941Rusty Russell *flags |= ESP_SPI; 99524518261009f3f81febfdd8398becc4a80cc941Rusty Russell break; 100524518261009f3f81febfdd8398becc4a80cc941Rusty Russell default: 101524518261009f3f81febfdd8398becc4a80cc941Rusty Russell return 0; 102524518261009f3f81febfdd8398becc4a80cc941Rusty Russell } 103524518261009f3f81febfdd8398becc4a80cc941Rusty Russell 104524518261009f3f81febfdd8398becc4a80cc941Rusty Russell return 1; 105524518261009f3f81febfdd8398becc4a80cc941Rusty Russell} 106524518261009f3f81febfdd8398becc4a80cc941Rusty Russell 107524518261009f3f81febfdd8398becc4a80cc941Rusty Russellstatic void 108524518261009f3f81febfdd8398becc4a80cc941Rusty Russellprint_spis(const char *name, u_int32_t min, u_int32_t max, 109524518261009f3f81febfdd8398becc4a80cc941Rusty Russell int invert) 110524518261009f3f81febfdd8398becc4a80cc941Rusty Russell{ 111524518261009f3f81febfdd8398becc4a80cc941Rusty Russell const char *inv = invert ? "!" : ""; 112524518261009f3f81febfdd8398becc4a80cc941Rusty Russell 113524518261009f3f81febfdd8398becc4a80cc941Rusty Russell if (min != 0 || max != 0xFFFFFFFF || invert) { 1140a04e8d695549788213f842cc99c724a564a88dfYasuyuki KOZAKAI if (min == max) 1150a04e8d695549788213f842cc99c724a564a88dfYasuyuki KOZAKAI printf("%s:%s%u ", name, inv, min); 1160a04e8d695549788213f842cc99c724a564a88dfYasuyuki KOZAKAI else 1170a04e8d695549788213f842cc99c724a564a88dfYasuyuki KOZAKAI printf("%ss:%s%u:%u ", name, inv, min, max); 118524518261009f3f81febfdd8398becc4a80cc941Rusty Russell } 119524518261009f3f81febfdd8398becc4a80cc941Rusty Russell} 120524518261009f3f81febfdd8398becc4a80cc941Rusty Russell 121524518261009f3f81febfdd8398becc4a80cc941Rusty Russell/* Prints out the union ipt_matchinfo. */ 122524518261009f3f81febfdd8398becc4a80cc941Rusty Russellstatic void 123181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardtesp_print(const void *ip, const struct xt_entry_match *match, int numeric) 124524518261009f3f81febfdd8398becc4a80cc941Rusty Russell{ 1250a04e8d695549788213f842cc99c724a564a88dfYasuyuki KOZAKAI const struct xt_esp *esp = (struct xt_esp *)match->data; 126524518261009f3f81febfdd8398becc4a80cc941Rusty Russell 127524518261009f3f81febfdd8398becc4a80cc941Rusty Russell printf("esp "); 128524518261009f3f81febfdd8398becc4a80cc941Rusty Russell print_spis("spi", esp->spis[0], esp->spis[1], 1290a04e8d695549788213f842cc99c724a564a88dfYasuyuki KOZAKAI esp->invflags & XT_ESP_INV_SPI); 1300a04e8d695549788213f842cc99c724a564a88dfYasuyuki KOZAKAI if (esp->invflags & ~XT_ESP_INV_MASK) 131524518261009f3f81febfdd8398becc4a80cc941Rusty Russell printf("Unknown invflags: 0x%X ", 1320a04e8d695549788213f842cc99c724a564a88dfYasuyuki KOZAKAI esp->invflags & ~XT_ESP_INV_MASK); 133524518261009f3f81febfdd8398becc4a80cc941Rusty Russell} 134524518261009f3f81febfdd8398becc4a80cc941Rusty Russell 135524518261009f3f81febfdd8398becc4a80cc941Rusty Russell/* Saves the union ipt_matchinfo in parsable form to stdout. */ 136181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardtstatic void esp_save(const void *ip, const struct xt_entry_match *match) 137524518261009f3f81febfdd8398becc4a80cc941Rusty Russell{ 1380a04e8d695549788213f842cc99c724a564a88dfYasuyuki KOZAKAI const struct xt_esp *espinfo = (struct xt_esp *)match->data; 139524518261009f3f81febfdd8398becc4a80cc941Rusty Russell 140f0ac814a2137abe334bd0000d59e9be4721e1ddcHarald Welte if (!(espinfo->spis[0] == 0 141f0ac814a2137abe334bd0000d59e9be4721e1ddcHarald Welte && espinfo->spis[1] == 0xFFFFFFFF)) { 142f0ac814a2137abe334bd0000d59e9be4721e1ddcHarald Welte printf("--espspi %s", 1430a04e8d695549788213f842cc99c724a564a88dfYasuyuki KOZAKAI (espinfo->invflags & XT_ESP_INV_SPI) ? "! " : ""); 144524518261009f3f81febfdd8398becc4a80cc941Rusty Russell if (espinfo->spis[0] 145524518261009f3f81febfdd8398becc4a80cc941Rusty Russell != espinfo->spis[1]) 146f0ac814a2137abe334bd0000d59e9be4721e1ddcHarald Welte printf("%u:%u ", 147524518261009f3f81febfdd8398becc4a80cc941Rusty Russell espinfo->spis[0], 148524518261009f3f81febfdd8398becc4a80cc941Rusty Russell espinfo->spis[1]); 149524518261009f3f81febfdd8398becc4a80cc941Rusty Russell else 150f0ac814a2137abe334bd0000d59e9be4721e1ddcHarald Welte printf("%u ", 151524518261009f3f81febfdd8398becc4a80cc941Rusty Russell espinfo->spis[0]); 152524518261009f3f81febfdd8398becc4a80cc941Rusty Russell } 153524518261009f3f81febfdd8398becc4a80cc941Rusty Russell 154524518261009f3f81febfdd8398becc4a80cc941Rusty Russell} 155524518261009f3f81febfdd8398becc4a80cc941Rusty Russell 156181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardtstatic struct xtables_match esp_match = { 1570a04e8d695549788213f842cc99c724a564a88dfYasuyuki KOZAKAI .family = AF_INET, 1580a04e8d695549788213f842cc99c724a564a88dfYasuyuki KOZAKAI .name = "esp", 1590a04e8d695549788213f842cc99c724a564a88dfYasuyuki KOZAKAI .version = IPTABLES_VERSION, 1600a04e8d695549788213f842cc99c724a564a88dfYasuyuki KOZAKAI .size = XT_ALIGN(sizeof(struct xt_esp)), 1610a04e8d695549788213f842cc99c724a564a88dfYasuyuki KOZAKAI .userspacesize = XT_ALIGN(sizeof(struct xt_esp)), 162181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt .help = esp_help, 163181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt .init = esp_init, 164181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt .parse = esp_parse, 165181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt .print = esp_print, 166181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt .save = esp_save, 167181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt .extra_opts = esp_opts, 1680a04e8d695549788213f842cc99c724a564a88dfYasuyuki KOZAKAI}; 1690a04e8d695549788213f842cc99c724a564a88dfYasuyuki KOZAKAI 170181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardtstatic struct xtables_match esp_match6 = { 1710a04e8d695549788213f842cc99c724a564a88dfYasuyuki KOZAKAI .family = AF_INET6, 1728caee8b9e34fed4562fcff553197c161fc9d9979Pablo Neira .name = "esp", 1738caee8b9e34fed4562fcff553197c161fc9d9979Pablo Neira .version = IPTABLES_VERSION, 1740a04e8d695549788213f842cc99c724a564a88dfYasuyuki KOZAKAI .size = XT_ALIGN(sizeof(struct xt_esp)), 1750a04e8d695549788213f842cc99c724a564a88dfYasuyuki KOZAKAI .userspacesize = XT_ALIGN(sizeof(struct xt_esp)), 176181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt .help = esp_help, 177181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt .init = esp_init, 178181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt .parse = esp_parse, 179181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt .print = esp_print, 180181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt .save = esp_save, 181181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt .extra_opts = esp_opts, 182524518261009f3f81febfdd8398becc4a80cc941Rusty Russell}; 183524518261009f3f81febfdd8398becc4a80cc941Rusty Russell 184524518261009f3f81febfdd8398becc4a80cc941Rusty Russellvoid 185524518261009f3f81febfdd8398becc4a80cc941Rusty Russell_init(void) 186524518261009f3f81febfdd8398becc4a80cc941Rusty Russell{ 187181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt xtables_register_match(&esp_match); 188181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt xtables_register_match(&esp_match6); 189524518261009f3f81febfdd8398becc4a80cc941Rusty Russell} 190