libxt_esp.c revision 8b7c64d6ba156a99008fcd810cba874c73294333
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( 158b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt"esp match options:\n" 16524518261009f3f81febfdd8398becc4a80cc941Rusty Russell" --espspi [!] spi[:spi]\n" 178b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt" match spi (range)\n"); 18524518261009f3f81febfdd8398becc4a80cc941Rusty Russell} 19524518261009f3f81febfdd8398becc4a80cc941Rusty Russell 20181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardtstatic const struct option esp_opts[] = { 21500f483fff529dcd88ec96b9d5054be6cd6363a0Patrick McHardy { "espspi", 1, NULL, '1' }, 229ee386a1b6d7704b259460152c959ab0e79e02aaMax Kellermann { .name = NULL } 23524518261009f3f81febfdd8398becc4a80cc941Rusty Russell}; 24524518261009f3f81febfdd8398becc4a80cc941Rusty Russell 25524518261009f3f81febfdd8398becc4a80cc941Rusty Russellstatic u_int32_t 26524518261009f3f81febfdd8398becc4a80cc941Rusty Russellparse_esp_spi(const char *spistr) 27524518261009f3f81febfdd8398becc4a80cc941Rusty Russell{ 28524518261009f3f81febfdd8398becc4a80cc941Rusty Russell unsigned long int spi; 29524518261009f3f81febfdd8398becc4a80cc941Rusty Russell char* ep; 30524518261009f3f81febfdd8398becc4a80cc941Rusty Russell 31524518261009f3f81febfdd8398becc4a80cc941Rusty Russell spi = strtoul(spistr,&ep,0) ; 32524518261009f3f81febfdd8398becc4a80cc941Rusty Russell 33524518261009f3f81febfdd8398becc4a80cc941Rusty Russell if ( spistr == ep ) { 34524518261009f3f81febfdd8398becc4a80cc941Rusty Russell exit_error(PARAMETER_PROBLEM, 35524518261009f3f81febfdd8398becc4a80cc941Rusty Russell "ESP no valid digits in spi `%s'", spistr); 36524518261009f3f81febfdd8398becc4a80cc941Rusty Russell } 37524518261009f3f81febfdd8398becc4a80cc941Rusty Russell if ( spi == ULONG_MAX && errno == ERANGE ) { 38524518261009f3f81febfdd8398becc4a80cc941Rusty Russell exit_error(PARAMETER_PROBLEM, 39524518261009f3f81febfdd8398becc4a80cc941Rusty Russell "spi `%s' specified too big: would overflow", spistr); 40524518261009f3f81febfdd8398becc4a80cc941Rusty Russell } 41524518261009f3f81febfdd8398becc4a80cc941Rusty Russell if ( *spistr != '\0' && *ep != '\0' ) { 42524518261009f3f81febfdd8398becc4a80cc941Rusty Russell exit_error(PARAMETER_PROBLEM, 43524518261009f3f81febfdd8398becc4a80cc941Rusty Russell "ESP error parsing spi `%s'", spistr); 44524518261009f3f81febfdd8398becc4a80cc941Rusty Russell } 45524518261009f3f81febfdd8398becc4a80cc941Rusty Russell return (u_int32_t) spi; 46524518261009f3f81febfdd8398becc4a80cc941Rusty Russell} 47524518261009f3f81febfdd8398becc4a80cc941Rusty Russell 48524518261009f3f81febfdd8398becc4a80cc941Rusty Russellstatic void 49524518261009f3f81febfdd8398becc4a80cc941Rusty Russellparse_esp_spis(const char *spistring, u_int32_t *spis) 50524518261009f3f81febfdd8398becc4a80cc941Rusty Russell{ 51524518261009f3f81febfdd8398becc4a80cc941Rusty Russell char *buffer; 52524518261009f3f81febfdd8398becc4a80cc941Rusty Russell char *cp; 53524518261009f3f81febfdd8398becc4a80cc941Rusty Russell 54524518261009f3f81febfdd8398becc4a80cc941Rusty Russell buffer = strdup(spistring); 55524518261009f3f81febfdd8398becc4a80cc941Rusty Russell if ((cp = strchr(buffer, ':')) == NULL) 56524518261009f3f81febfdd8398becc4a80cc941Rusty Russell spis[0] = spis[1] = parse_esp_spi(buffer); 57524518261009f3f81febfdd8398becc4a80cc941Rusty Russell else { 58524518261009f3f81febfdd8398becc4a80cc941Rusty Russell *cp = '\0'; 59524518261009f3f81febfdd8398becc4a80cc941Rusty Russell cp++; 60524518261009f3f81febfdd8398becc4a80cc941Rusty Russell 61524518261009f3f81febfdd8398becc4a80cc941Rusty Russell spis[0] = buffer[0] ? parse_esp_spi(buffer) : 0; 62524518261009f3f81febfdd8398becc4a80cc941Rusty Russell spis[1] = cp[0] ? parse_esp_spi(cp) : 0xFFFFFFFF; 632c627cf60cfb1a4e67aea1b2333f2a11e23fecd8Yasuyuki KOZAKAI if (spis[0] > spis[1]) 642c627cf60cfb1a4e67aea1b2333f2a11e23fecd8Yasuyuki KOZAKAI exit_error(PARAMETER_PROBLEM, 652c627cf60cfb1a4e67aea1b2333f2a11e23fecd8Yasuyuki KOZAKAI "Invalid ESP spi range: %s", spistring); 66524518261009f3f81febfdd8398becc4a80cc941Rusty Russell } 67524518261009f3f81febfdd8398becc4a80cc941Rusty Russell free(buffer); 68524518261009f3f81febfdd8398becc4a80cc941Rusty Russell} 69524518261009f3f81febfdd8398becc4a80cc941Rusty Russell 70524518261009f3f81febfdd8398becc4a80cc941Rusty Russell/* Initialize the match. */ 71181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardtstatic void esp_init(struct xt_entry_match *m) 72524518261009f3f81febfdd8398becc4a80cc941Rusty Russell{ 730a04e8d695549788213f842cc99c724a564a88dfYasuyuki KOZAKAI struct xt_esp *espinfo = (struct xt_esp *)m->data; 74524518261009f3f81febfdd8398becc4a80cc941Rusty Russell 75524518261009f3f81febfdd8398becc4a80cc941Rusty Russell espinfo->spis[1] = 0xFFFFFFFF; 76524518261009f3f81febfdd8398becc4a80cc941Rusty Russell} 77524518261009f3f81febfdd8398becc4a80cc941Rusty Russell 78524518261009f3f81febfdd8398becc4a80cc941Rusty Russell#define ESP_SPI 0x01 79524518261009f3f81febfdd8398becc4a80cc941Rusty Russell 80524518261009f3f81febfdd8398becc4a80cc941Rusty Russell/* Function which parses command options; returns true if it 81524518261009f3f81febfdd8398becc4a80cc941Rusty Russell ate an option */ 82524518261009f3f81febfdd8398becc4a80cc941Rusty Russellstatic int 83181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardtesp_parse(int c, char **argv, int invert, unsigned int *flags, 84181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt const void *entry, struct xt_entry_match **match) 85524518261009f3f81febfdd8398becc4a80cc941Rusty Russell{ 860a04e8d695549788213f842cc99c724a564a88dfYasuyuki KOZAKAI struct xt_esp *espinfo = (struct xt_esp *)(*match)->data; 87524518261009f3f81febfdd8398becc4a80cc941Rusty Russell 88524518261009f3f81febfdd8398becc4a80cc941Rusty Russell switch (c) { 89524518261009f3f81febfdd8398becc4a80cc941Rusty Russell case '1': 90524518261009f3f81febfdd8398becc4a80cc941Rusty Russell if (*flags & ESP_SPI) 91524518261009f3f81febfdd8398becc4a80cc941Rusty Russell exit_error(PARAMETER_PROBLEM, 92f0ac814a2137abe334bd0000d59e9be4721e1ddcHarald Welte "Only one `--espspi' allowed"); 93b77f1dafb9f35752bb9685323bcacb32a0e6ddc5Harald Welte check_inverse(optarg, &invert, &optind, 0); 94524518261009f3f81febfdd8398becc4a80cc941Rusty Russell parse_esp_spis(argv[optind-1], espinfo->spis); 95524518261009f3f81febfdd8398becc4a80cc941Rusty Russell if (invert) 960a04e8d695549788213f842cc99c724a564a88dfYasuyuki KOZAKAI espinfo->invflags |= XT_ESP_INV_SPI; 97524518261009f3f81febfdd8398becc4a80cc941Rusty Russell *flags |= ESP_SPI; 98524518261009f3f81febfdd8398becc4a80cc941Rusty Russell break; 99524518261009f3f81febfdd8398becc4a80cc941Rusty Russell default: 100524518261009f3f81febfdd8398becc4a80cc941Rusty Russell return 0; 101524518261009f3f81febfdd8398becc4a80cc941Rusty Russell } 102524518261009f3f81febfdd8398becc4a80cc941Rusty Russell 103524518261009f3f81febfdd8398becc4a80cc941Rusty Russell return 1; 104524518261009f3f81febfdd8398becc4a80cc941Rusty Russell} 105524518261009f3f81febfdd8398becc4a80cc941Rusty Russell 106524518261009f3f81febfdd8398becc4a80cc941Rusty Russellstatic void 107524518261009f3f81febfdd8398becc4a80cc941Rusty Russellprint_spis(const char *name, u_int32_t min, u_int32_t max, 108524518261009f3f81febfdd8398becc4a80cc941Rusty Russell int invert) 109524518261009f3f81febfdd8398becc4a80cc941Rusty Russell{ 110524518261009f3f81febfdd8398becc4a80cc941Rusty Russell const char *inv = invert ? "!" : ""; 111524518261009f3f81febfdd8398becc4a80cc941Rusty Russell 112524518261009f3f81febfdd8398becc4a80cc941Rusty Russell if (min != 0 || max != 0xFFFFFFFF || invert) { 1130a04e8d695549788213f842cc99c724a564a88dfYasuyuki KOZAKAI if (min == max) 1140a04e8d695549788213f842cc99c724a564a88dfYasuyuki KOZAKAI printf("%s:%s%u ", name, inv, min); 1150a04e8d695549788213f842cc99c724a564a88dfYasuyuki KOZAKAI else 1160a04e8d695549788213f842cc99c724a564a88dfYasuyuki KOZAKAI printf("%ss:%s%u:%u ", name, inv, min, max); 117524518261009f3f81febfdd8398becc4a80cc941Rusty Russell } 118524518261009f3f81febfdd8398becc4a80cc941Rusty Russell} 119524518261009f3f81febfdd8398becc4a80cc941Rusty Russell 120524518261009f3f81febfdd8398becc4a80cc941Rusty Russell/* Prints out the union ipt_matchinfo. */ 121524518261009f3f81febfdd8398becc4a80cc941Rusty Russellstatic void 122181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardtesp_print(const void *ip, const struct xt_entry_match *match, int numeric) 123524518261009f3f81febfdd8398becc4a80cc941Rusty Russell{ 1240a04e8d695549788213f842cc99c724a564a88dfYasuyuki KOZAKAI const struct xt_esp *esp = (struct xt_esp *)match->data; 125524518261009f3f81febfdd8398becc4a80cc941Rusty Russell 126524518261009f3f81febfdd8398becc4a80cc941Rusty Russell printf("esp "); 127524518261009f3f81febfdd8398becc4a80cc941Rusty Russell print_spis("spi", esp->spis[0], esp->spis[1], 1280a04e8d695549788213f842cc99c724a564a88dfYasuyuki KOZAKAI esp->invflags & XT_ESP_INV_SPI); 1290a04e8d695549788213f842cc99c724a564a88dfYasuyuki KOZAKAI if (esp->invflags & ~XT_ESP_INV_MASK) 130524518261009f3f81febfdd8398becc4a80cc941Rusty Russell printf("Unknown invflags: 0x%X ", 1310a04e8d695549788213f842cc99c724a564a88dfYasuyuki KOZAKAI esp->invflags & ~XT_ESP_INV_MASK); 132524518261009f3f81febfdd8398becc4a80cc941Rusty Russell} 133524518261009f3f81febfdd8398becc4a80cc941Rusty Russell 134524518261009f3f81febfdd8398becc4a80cc941Rusty Russell/* Saves the union ipt_matchinfo in parsable form to stdout. */ 135181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardtstatic void esp_save(const void *ip, const struct xt_entry_match *match) 136524518261009f3f81febfdd8398becc4a80cc941Rusty Russell{ 1370a04e8d695549788213f842cc99c724a564a88dfYasuyuki KOZAKAI const struct xt_esp *espinfo = (struct xt_esp *)match->data; 138524518261009f3f81febfdd8398becc4a80cc941Rusty Russell 139f0ac814a2137abe334bd0000d59e9be4721e1ddcHarald Welte if (!(espinfo->spis[0] == 0 140f0ac814a2137abe334bd0000d59e9be4721e1ddcHarald Welte && espinfo->spis[1] == 0xFFFFFFFF)) { 141f0ac814a2137abe334bd0000d59e9be4721e1ddcHarald Welte printf("--espspi %s", 1420a04e8d695549788213f842cc99c724a564a88dfYasuyuki KOZAKAI (espinfo->invflags & XT_ESP_INV_SPI) ? "! " : ""); 143524518261009f3f81febfdd8398becc4a80cc941Rusty Russell if (espinfo->spis[0] 144524518261009f3f81febfdd8398becc4a80cc941Rusty Russell != espinfo->spis[1]) 145f0ac814a2137abe334bd0000d59e9be4721e1ddcHarald Welte printf("%u:%u ", 146524518261009f3f81febfdd8398becc4a80cc941Rusty Russell espinfo->spis[0], 147524518261009f3f81febfdd8398becc4a80cc941Rusty Russell espinfo->spis[1]); 148524518261009f3f81febfdd8398becc4a80cc941Rusty Russell else 149f0ac814a2137abe334bd0000d59e9be4721e1ddcHarald Welte printf("%u ", 150524518261009f3f81febfdd8398becc4a80cc941Rusty Russell espinfo->spis[0]); 151524518261009f3f81febfdd8398becc4a80cc941Rusty Russell } 152524518261009f3f81febfdd8398becc4a80cc941Rusty Russell 153524518261009f3f81febfdd8398becc4a80cc941Rusty Russell} 154524518261009f3f81febfdd8398becc4a80cc941Rusty Russell 155181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardtstatic struct xtables_match esp_match = { 1560a04e8d695549788213f842cc99c724a564a88dfYasuyuki KOZAKAI .family = AF_INET, 1570a04e8d695549788213f842cc99c724a564a88dfYasuyuki KOZAKAI .name = "esp", 1588b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt .version = XTABLES_VERSION, 1590a04e8d695549788213f842cc99c724a564a88dfYasuyuki KOZAKAI .size = XT_ALIGN(sizeof(struct xt_esp)), 1600a04e8d695549788213f842cc99c724a564a88dfYasuyuki KOZAKAI .userspacesize = XT_ALIGN(sizeof(struct xt_esp)), 161181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt .help = esp_help, 162181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt .init = esp_init, 163181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt .parse = esp_parse, 164181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt .print = esp_print, 165181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt .save = esp_save, 166181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt .extra_opts = esp_opts, 1670a04e8d695549788213f842cc99c724a564a88dfYasuyuki KOZAKAI}; 1680a04e8d695549788213f842cc99c724a564a88dfYasuyuki KOZAKAI 169181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardtstatic struct xtables_match esp_match6 = { 1700a04e8d695549788213f842cc99c724a564a88dfYasuyuki KOZAKAI .family = AF_INET6, 1718caee8b9e34fed4562fcff553197c161fc9d9979Pablo Neira .name = "esp", 1728b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt .version = XTABLES_VERSION, 1730a04e8d695549788213f842cc99c724a564a88dfYasuyuki KOZAKAI .size = XT_ALIGN(sizeof(struct xt_esp)), 1740a04e8d695549788213f842cc99c724a564a88dfYasuyuki KOZAKAI .userspacesize = XT_ALIGN(sizeof(struct xt_esp)), 175181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt .help = esp_help, 176181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt .init = esp_init, 177181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt .parse = esp_parse, 178181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt .print = esp_print, 179181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt .save = esp_save, 180181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt .extra_opts = esp_opts, 181524518261009f3f81febfdd8398becc4a80cc941Rusty Russell}; 182524518261009f3f81febfdd8398becc4a80cc941Rusty Russell 183524518261009f3f81febfdd8398becc4a80cc941Rusty Russellvoid 184524518261009f3f81febfdd8398becc4a80cc941Rusty Russell_init(void) 185524518261009f3f81febfdd8398becc4a80cc941Rusty Russell{ 186181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt xtables_register_match(&esp_match); 187181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt xtables_register_match(&esp_match6); 188524518261009f3f81febfdd8398becc4a80cc941Rusty Russell} 189