📄 eroute.c
字号:
/* * manipulate eroutes * Copyright (C) 1996 John Ioannidis. * Copyright (C) 1997, 1998, 1999, 2000, 2001 Richard Guy Briggs. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. */char eroute_c_version[] = "RCSID $Id: eroute.c,v 1.61 2004/12/10 12:38:29 paul Exp $";#include <sys/types.h>#include <linux/types.h> /* new */#include <string.h>#include <errno.h>#include <stdlib.h> /* system(), strtoul() */#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <sys/stat.h>#include <fcntl.h>#include <netdb.h>#include <unistd.h>#include <openswan.h>#if 0#include <linux/autoconf.h> /* CONFIG_IPSEC_PFKEYv2 */#endif/* permanently turn it on since netlink support has been disabled */#include <signal.h>#include <pfkeyv2.h>#include <pfkey.h>#include "openswan/radij.h"#include "openswan/ipsec_encap.h"#include <stdio.h>#include <getopt.h>char *program_name;char me[] = "ipsec eroute";extern char *optarg;extern int optind, opterr, optopt;char *eroute_af_opt, *said_af_opt, *edst_opt, *spi_opt, *proto_opt, *said_opt, *dst_opt, *src_opt;char *transport_proto_opt, *src_port_opt, *dst_port_opt;int action_type = 0;int pfkey_sock;fd_set pfkey_socks;uint32_t pfkey_seq = 0;#define EMT_IFADDR 1 /* set enc if addr */#define EMT_SETSPI 2 /* Set SPI properties */#define EMT_DELSPI 3 /* Delete an SPI */#define EMT_GRPSPIS 4 /* Group SPIs (output order) */#define EMT_SETEROUTE 5 /* set an extended route */#define EMT_DELEROUTE 6 /* del an extended route */#define EMT_TESTROUTE 7 /* try to find route, print to console */#define EMT_SETDEBUG 8 /* set debug level if active */#define EMT_UNGRPSPIS 9 /* UnGroup SPIs (output order) */#define EMT_CLREROUTE 10 /* clear the extended route table */#define EMT_CLRSPIS 11 /* clear the spi table */#define EMT_REPLACEROUTE 12 /* set an extended route */#define EMT_GETDEBUG 13 /* get debug level if active */#define EMT_INEROUTE 14 /* set incoming policy for IPIP on a chain */static void add_port(int af, ip_address * addr, short port){ switch (af) { case AF_INET: addr->u.v4.sin_port = port; break; case AF_INET6: addr->u.v6.sin6_port = port; break; }}static voidusage(char* arg){ fprintf(stdout, "usage: %s --{add,addin,replace} --eraf <inet | inet6> --src <src>/<srcmaskbits>|<srcmask> --dst <dst>/<dstmaskbits>|<dstmask> [ --transport-proto <protocol> ] [ --src-port <source-port> ] [ --dst-port <dest-port> ] <SA>\n", arg); fprintf(stdout, " where <SA> is '--af <inet | inet6> --edst <edst> --spi <spi> --proto <proto>'\n"); fprintf(stdout, " OR '--said <said>'\n"); fprintf(stdout, " OR '--said <%%passthrough | %%passthrough4 | %%passthrough6 | %%drop | %%reject | %%trap | %%hold | %%pass>'.\n"); fprintf(stdout, " %s --del --eraf <inet | inet6>--src <src>/<srcmaskbits>|<srcmask> --dst <dst>/<dstmaskbits>|<dstmask> [ --transport-proto <protocol> ] [ --src-port <source-port> ] [ --dst-port <dest-port> ]\n", arg); fprintf(stdout, " %s --clear\n", arg); fprintf(stdout, " %s --help\n", arg); fprintf(stdout, " %s --version\n", arg); fprintf(stdout, " %s\n", arg); fprintf(stdout, " [ --debug ] is optional to any %s command.\n", arg); fprintf(stdout, " [ --label <label> ] is optional to any %s command.\n", arg);exit(1);}static struct option const longopts[] ={ {"dst", 1, 0, 'D'}, {"src", 1, 0, 'S'}, {"eraf", 1, 0, 'f'}, {"add", 0, 0, 'a'}, {"addin", 0, 0, 'A'}, {"replace", 0, 0, 'r'}, {"clear", 0, 0, 'c'}, {"del", 0, 0, 'd'}, {"af", 1, 0, 'i'}, {"edst", 1, 0, 'e'}, {"proto", 1, 0, 'p'}, {"transport-proto", 1, 0, 'P'}, {"src-port", 1, 0, 'Q'}, {"dst-port", 1, 0, 'R'}, {"help", 0, 0, 'h'}, {"spi", 1, 0, 's'}, {"said", 1, 0, 'I'}, {"version", 0, 0, 'v'}, {"label", 1, 0, 'l'}, {"optionsfrom", 1, 0, '+'}, {"debug", 0, 0, 'g'}, {0, 0, 0, 0}};intmain(int argc, char **argv){/* int fd; */ char *endptr;/* int ret; */ int c, previous = -1; const char* error_s; int debug = 0; int error = 0; char ipaddr_txt[ADDRTOT_BUF]; struct sadb_ext *extensions[SADB_EXT_MAX + 1]; struct sadb_msg *pfkey_msg; ip_address pfkey_address_s_ska; /*struct sockaddr_in pfkey_address_d_ska;*/ ip_address pfkey_address_sflow_ska; ip_address pfkey_address_dflow_ska; ip_address pfkey_address_smask_ska; ip_address pfkey_address_dmask_ska; int transport_proto = 0; int src_port = 0; int dst_port = 0; ip_said said; ip_subnet s_subnet, d_subnet; int eroute_af = 0; int said_af = 0; int argcount = argc; program_name = argv[0]; eroute_af_opt = said_af_opt = edst_opt = spi_opt = proto_opt = said_opt = dst_opt = src_opt = NULL; while((c = getopt_long(argc, argv, ""/*"acdD:e:i:hprs:S:f:vl:+:g"*/, longopts, 0)) != EOF) { switch(c) { case 'g': debug = 1; pfkey_lib_debug = PF_KEY_DEBUG_PARSE_MAX; argcount--; break; case 'a': if(action_type) { fprintf(stderr, "%s: Only one of '--add', '--addin', '--replace', '--clear', or '--del' options permitted.\n", program_name); exit(1); } action_type = EMT_SETEROUTE; break; case 'A': if(action_type) { fprintf(stderr, "%s: Only one of '--add', '--addin', '--replace', '--clear', or '--del' options permitted.\n", program_name); exit(1); } action_type = EMT_INEROUTE; break; case 'r': if(action_type) { fprintf(stderr, "%s: Only one of '--add', '--addin', '--replace', '--clear', or '--del' options permitted.\n", program_name); exit(1); } action_type = EMT_REPLACEROUTE; break; case 'c': if(action_type) { fprintf(stderr, "%s: Only one of '--add', '--addin', '--replace', '--clear', or '--del' options permitted.\n", program_name); exit(1); } action_type = EMT_CLREROUTE; break; case 'd': if(action_type) { fprintf(stderr, "%s: Only one of '--add', '--addin', '--replace', '--clear', or '--del' options permitted.\n", program_name); exit(1); } action_type = EMT_DELEROUTE; break; case 'e': if(said_opt) { fprintf(stderr, "%s: Error, EDST parameter redefined:%s, already defined in SA:%s\n", program_name, optarg, said_opt); exit (1); } if(edst_opt) { fprintf(stderr, "%s: Error, EDST parameter redefined:%s, already defined as:%s\n", program_name, optarg, edst_opt); exit (1); } error_s = ttoaddr(optarg, 0, said_af, &said.dst); if(error_s != NULL) { fprintf(stderr, "%s: Error, %s converting --edst argument:%s\n", program_name, error_s, optarg); exit (1); } edst_opt = optarg; break; case 'h': case '?': usage(program_name); exit(1); case 's': if(said_opt) { fprintf(stderr, "%s: Error, SPI parameter redefined:%s, already defined in SA:%s\n", program_name, optarg, said_opt); exit (1); } if(spi_opt) { fprintf(stderr, "%s: Error, SPI parameter redefined:%s, already defined as:%s\n", program_name, optarg, spi_opt); exit (1); } said.spi = htonl(strtoul(optarg, &endptr, 0)); if(!(endptr == optarg + strlen(optarg))) { fprintf(stderr, "%s: Invalid character in SPI parameter: %s\n", program_name, optarg); exit (1); } if(ntohl(said.spi) < 0x100) { fprintf(stderr, "%s: Illegal reserved spi: %s => 0x%x Must be larger than 0x100.\n", program_name, optarg, ntohl(said.spi)); exit(1); } spi_opt = optarg; break; case 'p': if(said_opt) { fprintf(stderr, "%s: Error, PROTO parameter redefined:%s, already defined in SA:%s\n", program_name, optarg, said_opt); exit (1); } if(proto_opt) { fprintf(stderr, "%s: Error, PROTO parameter redefined:%s, already defined as:%s\n", program_name, optarg, proto_opt); exit (1); }#if 0 if(said.proto) { fprintf(stderr, "%s: Warning, PROTO parameter redefined:%s\n", program_name, optarg); exit (1); }#endif if(!strcmp(optarg, "ah")) said.proto = SA_AH; if(!strcmp(optarg, "esp")) said.proto = SA_ESP; if(!strcmp(optarg, "tun")) said.proto = SA_IPIP; if(!strcmp(optarg, "comp")) said.proto = SA_COMP; if(said.proto == 0) { fprintf(stderr, "%s: Invalid PROTO parameter: %s\n", program_name, optarg); exit (1); } proto_opt = optarg; break; case 'I': if(said_opt) { fprintf(stderr, "%s: Error, SAID parameter redefined:%s, already defined in SA:%s\n", program_name, optarg, said_opt); exit (1); } if(proto_opt) { fprintf(stderr, "%s: Error, PROTO parameter redefined in SA:%s, already defined as:%s\n", program_name, optarg, proto_opt); exit (1); } if(edst_opt) { fprintf(stderr, "%s: Error, EDST parameter redefined in SA:%s, already defined as:%s\n", program_name, optarg, edst_opt); exit (1); } if(spi_opt) { fprintf(stderr, "%s: Error, SPI parameter redefined in SA:%s, already defined as:%s\n", program_name, optarg, spi_opt); exit (1); } if(said_af_opt) { fprintf(stderr, "%s: Error, address family parameter redefined in SA:%s, already defined as:%s\n", program_name, optarg, said_af_opt); exit (1); } error_s = ttosa(optarg, 0, &said); if(error_s != NULL) { fprintf(stderr, "%s: Error, %s converting --sa argument:%s\n", program_name, error_s, optarg); exit (1); } else if(ntohl(said.spi) < 0x100){ fprintf(stderr, "%s: Illegal reserved spi: %s => 0x%x Must be larger than or equal to 0x100.\n", program_name, optarg, said.spi); exit(1); } said_af = addrtypeof(&said.dst); said_opt = optarg; break; case 'v': fprintf(stdout, "%s %s\n", me, ipsec_version_code()); fprintf(stdout, "See `ipsec --copyright' for copyright information.\n"); exit(1); case 'D': if(dst_opt) { fprintf(stderr, "%s: Error, --dst parameter redefined:%s, already defined as:%s\n", program_name, optarg, dst_opt); exit (1); } error_s = ttosubnet(optarg, 0, eroute_af, &d_subnet); if (error_s != NULL) { fprintf(stderr, "%s: Error, %s converting --dst argument: %s\n", program_name, error_s, optarg); exit (1); } dst_opt = optarg; break; case 'S': if(src_opt) { fprintf(stderr, "%s: Error, --src parameter redefined:%s, already defined as:%s\n", program_name, optarg, src_opt); exit (1); } error_s = ttosubnet(optarg, 0, eroute_af, &s_subnet); if (error_s != NULL) { fprintf(stderr, "%s: Error, %s converting --src argument: %s\n", program_name, error_s, optarg); exit (1); } src_opt = optarg; break; case 'P': if (transport_proto_opt) { fprintf(stderr, "%s: Error, --transport-proto" " paramter redefined:%s, " "already defined as:%s\n", program_name, optarg, transport_proto_opt); exit(1); } transport_proto_opt = optarg; break; case 'Q': if (src_port_opt) { fprintf(stderr, "%s: Error, --src-port" " parameter redefined:%s, " "already defined as:%s\n", program_name, optarg, src_port_opt); exit(1); } src_port_opt = optarg; break; case 'R': if (dst_port_opt) { fprintf(stderr, "%s: Error, --dst-port" " parameter redefined:%s, " "already defined as:%s\n", program_name, optarg, dst_port_opt); exit(1); } dst_port_opt = optarg; break; case 'l': program_name = malloc(strlen(argv[0]) + 10 /* update this when changing the sprintf() */ + strlen(optarg)); sprintf(program_name, "%s --label %s", argv[0], optarg); argcount -= 2; break; case 'i': /* specifies the address family of the SAID, stored in said_af */ if(said_af_opt) { fprintf(stderr, "%s: Error, address family of SAID redefined:%s, already defined as:%s\n", program_name, optarg, said_af_opt); exit (1); } if(!strcmp(optarg, "inet")) said_af = AF_INET; if(!strcmp(optarg, "inet6")) said_af = AF_INET6; if(said_af == 0) { fprintf(stderr, "%s: Invalid address family parameter for SAID: %s\n", program_name, optarg); exit (1); } said_af_opt = optarg; break; case 'f': /* specifies the address family of the eroute, stored in eroute_af */ if(eroute_af_opt) { fprintf(stderr, "%s: Error, address family of eroute redefined:%s, already defined as:%s\n", program_name, optarg, eroute_af_opt); exit (1); } if(!strcmp(optarg, "inet")) eroute_af = AF_INET; if(!strcmp(optarg, "inet6")) eroute_af = AF_INET6; if(eroute_af == 0) { fprintf(stderr, "%s: Invalid address family parameter for eroute: %s\n", program_name, optarg); exit (1); } eroute_af_opt = optarg; break; case '+': /* optionsfrom */ optionsfrom(optarg, &argc, &argv, optind, stderr); /* no return on error */ break; default: break; } previous = c; } if(debug) { fprintf(stdout, "%s: DEBUG: argc=%d\n", program_name, argc); } if(argcount == 1) { struct stat sts; if ( ((stat ("/proc/net/pfkey", &sts)) == 0) ) { fprintf(stderr, "%s: NETKEY does not support eroute table.\n",program_name); exit(1); } else { system("cat /proc/net/ipsec_eroute"); exit(0); } } /* Sanity checks */ if(debug) { fprintf(stdout, "%s: DEBUG: action_type=%d\n", program_name, action_type); } if (transport_proto_opt != 0) { struct protoent * proto = getprotobyname(transport_proto_opt); if (proto != 0) { transport_proto = proto->p_proto; } else { transport_proto = strtoul(transport_proto_opt, &endptr, 0); if ((*endptr != '\0') || (transport_proto == 0 && endptr == transport_proto_opt)) { fprintf(stderr, "%s: Invalid character in --transport-proto parameter: %s\n", program_name, transport_proto_opt); exit (1); } if (transport_proto > 255) { fprintf(stderr, "%s: --transport-proto parameter: %s must be in the range 0 to 255 inclusive\n", program_name, transport_proto_opt); exit (1); } } } if (src_port_opt != 0 || dst_port_opt != 0) { switch (transport_proto) { case IPPROTO_UDP: case IPPROTO_TCP:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -