summaryrefslogtreecommitdiff
path: root/sbin/ipsecadm/ipsecadm.c
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2006-05-26 04:03:00 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2006-05-26 04:03:00 +0000
commit58dd5b5b8aa404c30d78d7408ddfdfc17e5478d3 (patch)
tree8958ac9984fda1f82f8a1603b59e13b740abbe19 /sbin/ipsecadm/ipsecadm.c
parent9136cbc0bb5ea9a90e52d6fff4329a3f724c5a4a (diff)
let us not talk about ipsecadm and vpn anymore; ok reyk
Diffstat (limited to 'sbin/ipsecadm/ipsecadm.c')
-rw-r--r--sbin/ipsecadm/ipsecadm.c1581
1 files changed, 0 insertions, 1581 deletions
diff --git a/sbin/ipsecadm/ipsecadm.c b/sbin/ipsecadm/ipsecadm.c
deleted file mode 100644
index 7bacfe281e1..00000000000
--- a/sbin/ipsecadm/ipsecadm.c
+++ /dev/null
@@ -1,1581 +0,0 @@
-/* $OpenBSD: ipsecadm.c,v 1.86 2005/06/07 02:36:41 henning Exp $ */
-/*
- * The authors of this code are John Ioannidis (ji@tla.org),
- * Angelos D. Keromytis (kermit@csd.uch.gr) and
- * Niels Provos (provos@physnet.uni-hamburg.de).
- *
- * This code was written by John Ioannidis for BSD/OS in Athens, Greece,
- * in November 1995.
- *
- * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
- * by Angelos D. Keromytis.
- *
- * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
- * and Niels Provos.
- *
- * Additional features in 1999 by Angelos D. Keromytis.
- *
- * Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis,
- * Angelos D. Keromytis and Niels Provos.
- * Copyright (c) 2001, Angelos D. Keromytis.
- *
- * Permission to use, copy, and modify this software with or without fee
- * is hereby granted, provided that this entire notice is included in
- * all copies of any software which is or includes a copy or
- * modification of this software.
- * You may use this code under the GNU public license if you so wish. Please
- * contribute changes back to the authors under this freer than GPL license
- * so that we may further the use of strong encryption without limitations to
- * all.
- *
- * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
- * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
- * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
- * PURPOSE.
- */
-
-#include <sys/param.h>
-#include <sys/file.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <sys/mbuf.h>
-#include <sys/sysctl.h>
-#include <sys/uio.h>
-#include <sys/stat.h>
-
-#include <net/if.h>
-#include <net/route.h>
-#include <net/if_dl.h>
-#include <netinet/in.h>
-#include <net/pfkeyv2.h>
-#include <netinet/ip_ipsp.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-#include <netdb.h>
-#include <errno.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <ctype.h>
-#include <stdlib.h>
-#include <string.h>
-#include <paths.h>
-#include <err.h>
-
-#define KEYSIZE_LIMIT 1024
-
-#define ESP_OLD 0x0001
-#define ESP_NEW 0x0002
-#define AH_OLD 0x0004
-#define AH_NEW 0x0008
-
-#define XF_ENC 0x0100
-#define XF_AUTH 0x0200
-#define DEL_SPI 0x0300
-#define GRP_SPI 0x0400
-#define FLOW 0x0500
-#define FLUSH 0x0700
-#define XF_COMP 0x0900
-#define SHOW 0x0a00
-#define MONITOR 0x0b00
-
-/* pseudo commands */
-#define IPCOMP 0x1000
-#define TCPMD5 0x2000
-#define ENC_IP 0x4000
-
-#define CMD_MASK 0xff00
-#define XFORM_MASK 0x0f00
-
-#define isencauth(x) ((x)&~CMD_MASK)
-#define iscmd(x,y) (((x) & CMD_MASK) == (y))
-
-typedef struct {
- char *name;
- int id, flags;
-} transform;
-
-transform xf[] = {
- { "null", SADB_EALG_NULL, XF_ENC | ESP_NEW },
- { "des", SADB_EALG_DESCBC, XF_ENC | ESP_OLD | ESP_NEW },
- { "3des", SADB_EALG_3DESCBC, XF_ENC | ESP_OLD | ESP_NEW },
- { "aes", SADB_X_EALG_AES, XF_ENC | ESP_NEW },
- { "aesctr", SADB_X_EALG_AESCTR, XF_ENC | ESP_NEW },
- { "blf", SADB_X_EALG_BLF, XF_ENC | ESP_NEW },
- { "cast", SADB_X_EALG_CAST, XF_ENC | ESP_NEW },
- { "skipjack", SADB_X_EALG_SKIPJACK, XF_ENC | ESP_NEW },
- { "md5", SADB_AALG_MD5HMAC, XF_AUTH | AH_NEW | ESP_NEW },
- { "sha1", SADB_AALG_SHA1HMAC, XF_AUTH | AH_NEW | ESP_NEW },
- { "sha2-256", SADB_X_AALG_SHA2_256, XF_AUTH | AH_NEW | ESP_NEW },
- { "sha2-384", SADB_X_AALG_SHA2_384, XF_AUTH | AH_NEW | ESP_NEW },
- { "sha2-512", SADB_X_AALG_SHA2_512, XF_AUTH | AH_NEW | ESP_NEW },
- { "md5", SADB_X_AALG_MD5, XF_AUTH | AH_OLD },
- { "sha1", SADB_X_AALG_SHA1, XF_AUTH | AH_OLD },
- { "rmd160", SADB_X_AALG_RIPEMD160HMAC, XF_AUTH | AH_NEW | ESP_NEW },
- { "deflate", SADB_X_CALG_DEFLATE, XF_COMP | IPCOMP },
- { "lzs", SADB_X_CALG_LZS, XF_COMP | IPCOMP },
-};
-
-#define ROUNDUP(x) (((x) + sizeof(u_int64_t) - 1) & ~(sizeof(u_int64_t) - 1))
-
-void ipsecadm_monitor(void);
-void ipsecadm_show(u_int8_t);
-int addrparse(const char *, struct sockaddr *, struct sockaddr *);
-void xf_set(struct iovec *, int, int);
-int x2i(u_char *);
-int isvalid(char *, int, int);
-__dead void usage(void);
-
-/*
- * returns 0 if "str" represents an address, returns 1 if address/mask,
- * returns -1 on failure.
- */
-int
-addrparse(const char *str, struct sockaddr *addr, struct sockaddr *mask)
-{
- struct addrinfo hints, *res = NULL;
- char *p = NULL, *sp, *ep;
- u_long prefixlen = 0;
- u_char *ap;
- int bitlen;
-
- /* slash */
- if (mask && (p = strchr(str, '/')) != NULL) {
- if (!p[1])
- return -1;
- ep = NULL;
- prefixlen = strtoul(p + 1, &ep, 10);
- if (*ep)
- return -1;
-
- sp = strdup(str);
- if (!sp)
- return -1;
- sp[p - str] = '\0';
- str = sp;
- } else
- sp = NULL;
-
- memset(&hints, 0, sizeof(hints));
- hints.ai_socktype = SOCK_DGRAM; /* dummy */
- hints.ai_flags = AI_NUMERICHOST;
- hints.ai_family = PF_UNSPEC;
- if (getaddrinfo(str, "0", &hints, &res) != 0)
- return -1;
- if (res->ai_next)
- goto fail;
-
- memcpy(addr, res->ai_addr, res->ai_addrlen);
-
- if (!p) {
- freeaddrinfo(res);
- if (sp)
- free(sp);
- return 0;
- }
- switch (res->ai_family) {
- case AF_INET:
- ap = (u_char *) & ((struct sockaddr_in *) mask)->sin_addr;
- bitlen = 32;
- break;
- case AF_INET6:
- ap = (u_char *) & ((struct sockaddr_in6 *) mask)->sin6_addr;
- bitlen = 128;
- break;
- default:
- goto fail;
- }
-
- if (prefixlen > bitlen)
- goto fail;
-
- memset(mask, 0, addr->sa_len);
- mask->sa_len = addr->sa_len;
- mask->sa_family = addr->sa_family;
- memset(ap, 0xff, prefixlen / 8);
- if (prefixlen % 8)
- ap[prefixlen / 8] = (0xff00 >> (prefixlen % 8)) & 0xff;
-
- if (res)
- freeaddrinfo(res);
- if (sp)
- free(sp);
- return 1;
-
-fail:
- if (res)
- freeaddrinfo(res);
- if (sp)
- free(sp);
- return -1;
-}
-
-void
-xf_set(struct iovec *iov, int cnt, int len)
-{
- struct sadb_msg sm;
- int sd;
-
- sd = socket(PF_KEY, SOCK_RAW, PF_KEY_V2);
- if (sd < 0)
- errx(1, "socket: %s%s", strerror(errno),
- errno == EPROTONOSUPPORT ?
- "\nMake sure your kernel is compiled with option KEY" : "");
- if (writev(sd, iov, cnt) != len)
- err(1, "write");
- if (read(sd, &sm, sizeof(sm)) != sizeof(sm))
- err(1, "read");
- if (sm.sadb_msg_errno != 0) {
- /* XXX We need better error reporting than this */
- errno = sm.sadb_msg_errno;
- err(1, "pfkey");
- }
- close(sd);
-}
-
-int
-x2i(u_char *s)
-{
- char ss[3];
-
- ss[0] = s[0];
- ss[1] = s[1];
- ss[2] = 0;
-
- if (!isxdigit(s[0]) || !isxdigit(s[1]))
- errx(1, "keys should be specified in hex digits");
- return strtoul(ss, NULL, 16);
-}
-
-int
-isvalid(char *option, int type, int mode)
-{
- int i;
-
- for (i = sizeof(xf) / sizeof(transform) - 1; i >= 0; i--)
- if (!strcmp(option, xf[i].name) &&
- (xf[i].flags & XFORM_MASK) == type &&
- (xf[i].flags & mode)) {
- goto gotit;
- }
- return 0;
-gotit:
- if (!strcmp(option, "des") || !strcmp(option, "skipjack"))
- warnx("warning: use of %s is strongly discouraged due to"
- " cryptographic weaknesses", option);
- return xf[i].id;
-}
-
-void
-usage(void)
-{
- fprintf(stderr, "usage: ipsecadm command [modifier ...]\n"
- "\tCommands: new esp, old esp, new ah, old ah, group, delspi, ip4, ipcomp,\n"
- "\t\t tcpmd5, flow, flush, show, monitor\n"
- "\tPossible modifiers:\n"
- "\t -enc <alg>\t\t\tencryption algorithm\n"
- "\t -auth <alg>\t\t\tauthentication algorithm\n"
- "\t -comp <alg>\t\t\tcompression algorithm\n"
- "\t -src <ip>\t\t\tsource address to be used\n"
- "\t -halfiv\t\t\tuse 4-byte IV in old ESP\n"
- "\t -forcetunnel\t\t\tforce IP-in-IP encapsulation\n"
- "\t -udpencap <port>\t\tenable ESP-in-UDP encapsulation\n"
- "\t -dst <ip>\t\t\tdestination address to be used\n"
- "\t -proto <val>\t\t\tsecurity protocol\n"
- "\t -proxy <ip>\t\t\tproxy address to be used\n"
- "\t -spi <val>\t\t\tSPI to be used\n"
- "\t -cpi <val>\t\t\tCPI to be used\n"
- "\t -key <val>\t\t\tkey material to be used\n"
- "\t -keyfile <file>\t\tfile to read key material from\n"
- "\t -authkey <val>\t\tkey material for auth in new esp\n"
- "\t -authkeyfile <file>\t\tfile to read authkey material from\n"
- "\t -sport <port>\t\t\tsource port for flow\n"
- "\t -dport <port>\t\t\tdestination port for flow\n"
- "\t -transport <val>\t\tprotocol number for flow\n"
- "\t -addr <srcnet> <mask> <dstnet> <mask>\t\tsubnets for flow\n"
- "\t -addr <srcnet/prefix> <dstnet/prefix>\t\tsame as above but in CIDR\n"
- "\t -delete\t\t\tdelete specified flow\n"
- "\t -bypass\t\t\tpermit a flow through without IPsec\n"
- "\t -permit\t\t\tsame as bypass\n"
- "\t -deny\t\t\t\tcreate a deny-packets flow\n"
- "\t -use\t\t\t\tuse an SA for a flow if it exists\n"
- "\t -acquire\t\t\tsend unprotected while acquiring SA\n"
- "\t -require\t\t\trequire an SA for a flow, use key mgmt.\n"
- "\t -dontacq\t\t\trequire, without using key mgmt.\n"
- "\t -in\t\t\t\tspecify incoming-packet policy\n"
- "\t -out\t\t\t\tspecify outgoing-packet policy\n"
- "\t -[ah|esp|ip4|ipcomp|tcpmd5]\tflush a particular protocol\n"
- "\t -srcid <id>\t\t\tsource identity for flows\n"
- "\t -dstid <id>\t\t\tdestination identity for flows\n"
- "\t -srcid_type <type>\t\tsource identity type\n"
- "\t -dstid_type <type>\t\tdestination identity type\n"
- "\talso: dst2, spi2, proto2\n"
- );
- exit(1);
-}
-
-int
-main(int argc, char *argv[])
-{
- int auth = 0, enc = 0, klen = 0, alen = 0, mode = ESP_NEW, i = 0;
- int proto = IPPROTO_ESP, proto2 = IPPROTO_AH, sproto2 = SADB_SATYPE_AH;
- int dport = -1, sport = -1, tproto = -1;
- int srcset = 0, dstset = 0, dst2set = 0, proxyset = 0;
- int cnt = 0, bypass = 0, deny = 0, ipsec = 0, comp = 0;
- u_int32_t spi = SPI_LOCAL_USE, spi2 = SPI_LOCAL_USE;
- u_int32_t cpi = SPI_LOCAL_USE;
- union sockaddr_union *src, *dst, *dst2, *osrc, *odst, *osmask;
- union sockaddr_union *odmask, *proxy;
- u_char srcbuf[256], dstbuf[256], dst2buf[256], osrcbuf[256];
- u_char odstbuf[256], osmaskbuf[256], odmaskbuf[256], proxybuf[256];
- u_char *keyp = NULL, *authp = NULL;
- u_char *srcid = NULL, *dstid = NULL;
- struct protoent *tp;
- struct servent *svp;
- char *transportproto = NULL;
- struct sadb_msg smsg;
- struct sadb_sa sa, sa2;
- struct sadb_address sad1, sad2, sad3; /* src, dst, proxy */
- struct sadb_address sad4, sad5; /* osrc, odst */
- struct sadb_address sad6, sad7, sad8; /* osmask, odmask, dst2 */
- struct sadb_ident sid1, sid2;
- struct sadb_key skey1, skey2;
- struct sadb_protocol sprotocol, sprotocol2;
- struct sadb_x_udpencap udpencap; /* Peer UDP Port */
- u_char realkey[8192], realakey[8192];
- struct iovec iov[30];
- struct addrinfo hints, *res;
- const char *errstr;
- u_long ll;
- char *ep;
-
- if (argc < 2)
- usage();
-
- /* Zero out */
- memset(&smsg, 0, sizeof(smsg));
- memset(&sa, 0, sizeof(sa));
- memset(&sa2, 0, sizeof(sa2));
- memset(&skey1, 0, sizeof(skey1));
- memset(&skey2, 0, sizeof(skey2));
- memset(&sad1, 0, sizeof(sad1));
- memset(&sad2, 0, sizeof(sad2));
- memset(&sad3, 0, sizeof(sad3));
- memset(&sad4, 0, sizeof(sad4));
- memset(&sad5, 0, sizeof(sad5));
- memset(&sad6, 0, sizeof(sad6));
- memset(&sad7, 0, sizeof(sad7));
- memset(&sad8, 0, sizeof(sad8));
- memset(&sprotocol, 0, sizeof(sprotocol));
- memset(&sprotocol2, 0, sizeof(sprotocol2));
- memset(iov, 0, sizeof(iov));
- memset(realkey, 0, sizeof(realkey));
- memset(realakey, 0, sizeof(realakey));
- memset(&sid1, 0, sizeof(sid1));
- memset(&sid2, 0, sizeof(sid2));
- memset(&udpencap, 0, sizeof(udpencap));
-
- src = (union sockaddr_union *) srcbuf;
- dst = (union sockaddr_union *) dstbuf;
- dst2 = (union sockaddr_union *) dst2buf;
- osrc = (union sockaddr_union *) osrcbuf;
- odst = (union sockaddr_union *) odstbuf;
- osmask = (union sockaddr_union *) osmaskbuf;
- odmask = (union sockaddr_union *) odmaskbuf;
- proxy = (union sockaddr_union *) proxybuf;
-
- memset(srcbuf, 0, sizeof(srcbuf));
- memset(dstbuf, 0, sizeof(dstbuf));
- memset(dst2buf, 0, sizeof(dst2buf));
- memset(osrcbuf, 0, sizeof(osrcbuf));
- memset(odstbuf, 0, sizeof(odstbuf));
- memset(osmaskbuf, 0, sizeof(osmaskbuf));
- memset(odmaskbuf, 0, sizeof(odmaskbuf));
- memset(proxybuf, 0, sizeof(proxybuf));
-
- /* Initialize */
- smsg.sadb_msg_version = PF_KEY_V2;
- smsg.sadb_msg_seq = 1;
- smsg.sadb_msg_pid = getpid();
- smsg.sadb_msg_len = sizeof(smsg) / 8;
-
- /* Initialize */
- sa.sadb_sa_exttype = SADB_EXT_SA;
- sa.sadb_sa_len = sizeof(sa) / 8;
- sa.sadb_sa_replay = 0;
- sa.sadb_sa_state = SADB_SASTATE_MATURE;
-
- sa2.sadb_sa_exttype = SADB_X_EXT_SA2;
- sa2.sadb_sa_len = sizeof(sa) / 8;
- sa2.sadb_sa_replay = 0;
- sa2.sadb_sa_state = SADB_SASTATE_MATURE;
-
- sid1.sadb_ident_len = sizeof(sid1) / 8;
- sid1.sadb_ident_exttype = SADB_EXT_IDENTITY_SRC;
-
- sid2.sadb_ident_len = sizeof(sid2) / 8;
- sid2.sadb_ident_exttype = SADB_EXT_IDENTITY_DST;
-
- sprotocol2.sadb_protocol_len = 1;
- sprotocol2.sadb_protocol_exttype = SADB_X_EXT_FLOW_TYPE;
- sprotocol2.sadb_protocol_direction = IPSP_DIRECTION_OUT;
- sprotocol2.sadb_protocol_flags = SADB_X_POLICYFLAGS_POLICY;
- sprotocol.sadb_protocol_exttype = SADB_X_EXT_PROTOCOL;
- sprotocol.sadb_protocol_len = 1;
-
- if (!strcmp(argv[1], "new") && argc > 3) {
- if (!strcmp(argv[2], "esp")) {
- mode = ESP_NEW;
- smsg.sadb_msg_type = SADB_ADD;
- smsg.sadb_msg_satype = SADB_SATYPE_ESP;
- } else if (!strcmp(argv[2], "ah")) {
- mode = AH_NEW;
- smsg.sadb_msg_type = SADB_ADD;
- smsg.sadb_msg_satype = SADB_SATYPE_AH;
- } else
- errx(1, "unexpected identifier %s", argv[2]);
-
- i += 2;
- } else if (!strcmp(argv[1], "old") && argc > 3) {
- if (!strcmp(argv[2], "esp")) {
- mode = ESP_OLD;
- smsg.sadb_msg_type = SADB_ADD;
- smsg.sadb_msg_satype = SADB_SATYPE_ESP;
- sa.sadb_sa_flags |= SADB_X_SAFLAGS_RANDOMPADDING;
- sa.sadb_sa_flags |= SADB_X_SAFLAGS_NOREPLAY;
- } else if (!strcmp(argv[2], "ah")) {
- mode = AH_OLD;
- smsg.sadb_msg_type = SADB_ADD;
- smsg.sadb_msg_satype = SADB_SATYPE_AH;
- sa.sadb_sa_flags |= SADB_X_SAFLAGS_NOREPLAY;
- } else
- errx(1, "unexpected identifier %s", argv[2]);
-
- i += 2;
- } else if (!strcmp(argv[1], "delspi")) {
- smsg.sadb_msg_type = SADB_DELETE;
- smsg.sadb_msg_satype = SADB_SATYPE_ESP;
- mode = DEL_SPI;
- i++;
- } else if (!strcmp(argv[1], "group")) {
- smsg.sadb_msg_type = SADB_X_GRPSPIS;
- smsg.sadb_msg_satype = SADB_SATYPE_ESP;
- mode = GRP_SPI;
- i++;
- } else if (!strcmp(argv[1], "flow")) {
- /* It may not be ADDFLOW, but never mind that for now */
- smsg.sadb_msg_type = SADB_X_ADDFLOW;
- smsg.sadb_msg_satype = SADB_SATYPE_ESP;
- mode = FLOW;
- i++;
- } else if (!strcmp(argv[1], "flush")) {
- mode = FLUSH;
- smsg.sadb_msg_type = SADB_FLUSH;
- smsg.sadb_msg_satype = SADB_SATYPE_UNSPEC;
- i++;
- } else if (!strcmp(argv[1], "ip4")) {
- mode = ENC_IP;
- smsg.sadb_msg_type = SADB_ADD;
- smsg.sadb_msg_satype = SADB_X_SATYPE_IPIP;
- i++;
- } else if (!strcmp(argv[1], "tcpmd5")) {
- mode = TCPMD5;
- smsg.sadb_msg_type = SADB_ADD;
- smsg.sadb_msg_satype = SADB_X_SATYPE_TCPSIGNATURE;
- i++;
- } else if (!strcmp(argv[1], "ipcomp")) {
- mode = IPCOMP;
- smsg.sadb_msg_type = SADB_ADD;
- smsg.sadb_msg_satype = SADB_X_SATYPE_IPCOMP;
- i++;
- } else if (!strcmp(argv[1], "monitor")) {
- mode = MONITOR;
- i++;
- } else if (!strcmp(argv[1], "show")) {
- mode = SHOW;
- smsg.sadb_msg_satype = SADB_SATYPE_UNSPEC;
- i++;
- } else {
- warnx("unknown command: %s", argv[1]);
- usage();
- }
-
- for (i++; i < argc; i++) {
- if (argv[i][0] != '-')
- errx(1, "expected option, got %s", argv[i]);
- if (!strcmp(argv[i] + 1, "enc") && enc == 0 && (i + 1 < argc)) {
- if ((enc = isvalid(argv[i + 1], XF_ENC, mode)) == 0)
- errx(1, "invalid encryption algorithm %s",
- argv[i + 1]);
- skey1.sadb_key_exttype = SADB_EXT_KEY_ENCRYPT;
- sa.sadb_sa_encrypt = enc;
- i++;
- continue;
- }
- if (!strcmp(argv[i] + 1, "auth") && auth == 0 && (i + 1 < argc)) {
- if ((auth = isvalid(argv[i + 1], XF_AUTH, mode)) == 0)
- errx(1, "invalid auth algorithm %s", argv[i + 1]);
- skey2.sadb_key_exttype = SADB_EXT_KEY_AUTH;
- sa.sadb_sa_auth = auth;
- i++;
- continue;
- }
- if (!strcmp(argv[i] + 1, "comp") && comp == 0 && (i + 1 < argc)) {
- if ((comp = isvalid(argv[i + 1], XF_COMP, mode)) == 0)
- errx(1, "invalid comp algorithm %s", argv[i + 1]);
- /*
- * Use encryption algo slot to store compression algo
- * since we cannot modify sadb_sa
- */
- sa.sadb_sa_encrypt = comp;
- i++;
- continue;
- }
- if (!strcmp(argv[i] + 1, "key") && keyp == NULL &&
- (i + 1 < argc)) {
- if (mode & (AH_NEW | AH_OLD | TCPMD5)) {
- authp = (u_char *)argv[++i];
- alen = strlen((char *)authp) / 2;
- } else {
- keyp = (u_char *)argv[++i];
- klen = strlen((char *)keyp) / 2;
- }
- continue;
- }
- if (!strcmp(argv[i] + 1, "keyfile") && keyp == NULL &&
- (i + 1 < argc)) {
- struct stat sb;
- u_char *pptr;
- int fd;
-
- if (stat(argv[++i], &sb) < 0)
- err(1, "stat");
- if ((sb.st_size > KEYSIZE_LIMIT) || (sb.st_size == 0))
- errx(1, "file %s is too %s "
- "(must be between 1 and %d bytes)",
- argv[i], sb.st_size ? "large" : "small",
- KEYSIZE_LIMIT);
- if ((pptr = malloc(sb.st_size)) == NULL)
- err(1, "malloc");
- if ((fd = open(argv[i], O_RDONLY)) < 0)
- err(1, "open");
- if (read(fd, pptr, sb.st_size) < sb.st_size)
- err(1, "read");
- close(fd);
-
- if (mode & (AH_NEW | AH_OLD | TCPMD5)) {
- authp = pptr;
- alen = sb.st_size / 2;
- } else {
- keyp = pptr;
- klen = sb.st_size / 2;
- }
- continue;
- }
- if (!strcmp(argv[i] + 1, "authkeyfile") && authp == NULL &&
- (i + 1 < argc)) {
- struct stat sb;
- int fd;
-
- if (!(mode & ESP_NEW))
- errx(1, "invalid option %s for selected mode",
- argv[i]);
- if (stat(argv[++i], &sb) < 0)
- err(1, "stat");
- if ((sb.st_size > KEYSIZE_LIMIT) || (sb.st_size == 0))
- errx(1, "file %s is too %s "
- "(must be between 1 and %d bytes)",
- argv[i], sb.st_size ? "large" : "small",
- KEYSIZE_LIMIT);
- if ((authp = malloc(sb.st_size)) == NULL)
- err(1, "malloc");
- if ((fd = open(argv[i], O_RDONLY)) < 0)
- err(1, "open");
- if (read(fd, authp, sb.st_size) < sb.st_size)
- err(1, "read");
- close(fd);
-
- alen = sb.st_size / 2;
- continue;
- }
- if (!strcmp(argv[i] + 1, "authkey") && authp == NULL &&
- (i + 1 < argc)) {
- if (!(mode & ESP_NEW))
- errx(1, "invalid option %s for selected mode",
- argv[i]);
- authp = (u_char *)argv[++i];
- alen = strlen((char *)authp) / 2;
- continue;
- }
- if (!strcmp(argv[i] + 1, "iv") && (i + 1 < argc)) {
- if (mode & (AH_OLD | AH_NEW))
- errx(1, "invalid option %s with auth",
- argv[i]);
- warnx("warning: option iv has been deprecated");
-
- /* Horrible hack */
- if (mode & ESP_OLD)
- if (strlen(argv[i + 2]) == 4)
- sa.sadb_sa_flags |= SADB_X_SAFLAGS_HALFIV;
-
- i++;
- continue;
- }
- if ((iscmd(mode, FLUSH) || iscmd(mode, SHOW)) &&
- smsg.sadb_msg_satype == SADB_SATYPE_UNSPEC) {
- if (!strcmp(argv[i] + 1, "esp"))
- smsg.sadb_msg_satype = SADB_SATYPE_ESP;
- else if (!strcmp(argv[i] + 1, "ah"))
- smsg.sadb_msg_satype = SADB_SATYPE_AH;
- else if (!strcmp(argv[i] + 1, "ip4"))
- smsg.sadb_msg_satype = SADB_X_SATYPE_IPIP;
- else if (!strcmp(argv[i] + 1, "tcpmd5"))
- smsg.sadb_msg_satype = SADB_X_SATYPE_TCPSIGNATURE;
- else if (!strcmp(argv[i] + 1, "ipcomp"))
- smsg.sadb_msg_satype = SADB_X_SATYPE_IPCOMP;
- else
- errx(1, "invalid SA type %s", argv[i] + 1);
- i++;
- continue;
- }
- if (!strcmp(argv[i] + 1, "spi") && iscmd(mode, FLOW)) {
- warnx("use of flag \"-spi\" is deprecated with "
- "flow creation or deletion");
- i++;
- continue;
- }
- if (!strcmp(argv[i] + 1, "spi") && spi == SPI_LOCAL_USE &&
- (i + 1 < argc) && !bypass && !deny) {
- ll = strtoul(argv[i + 1], &ep, 16);
- if ((argv[i + 1] == '\0' || *ep != '\0') ||
- (errno == ERANGE && ll == ULONG_MAX) ||
- (ll >= SPI_RESERVED_MIN && ll <= SPI_RESERVED_MAX))
- errx(1, "invalid spi %s", argv[i + 1]);
- spi = ll;
- sa.sadb_sa_spi = htonl(spi);
- i++;
- continue;
- }
- if (!strcmp(argv[i] + 1, "spi2") && spi2 == SPI_LOCAL_USE &&
- iscmd(mode, GRP_SPI) && (i + 1 < argc)) {
- ll = strtoul(argv[i + 1], &ep, 16);
- if ((argv[i + 1] == '\0' || *ep != '\0') ||
- (errno == ERANGE && ll == ULONG_MAX) ||
- (ll >= SPI_RESERVED_MIN && ll <= SPI_RESERVED_MAX))
- errx(1, "invalid spi2 %s", argv[i + 1]);
- spi2 = ll;
- sa2.sadb_sa_spi = htonl(spi2);
- i++;
- continue;
- }
- if (!strcmp(argv[i] + 1, "cpi") && cpi == SPI_LOCAL_USE &&
- (i + 1 < argc) && !bypass && !deny) {
- ll = strtoul(argv[i + 1], &ep, 16);
- if ((argv[i + 1] == '\0' || *ep != '\0') ||
- (errno == ERANGE && ll == ULONG_MAX) ||
- (ll >= CPI_RESERVED_MIN && ll <= CPI_RESERVED_MAX) ||
- (ll > USHRT_MAX))
- errx(1, "invalid cpi %s", argv[i + 1]);
- cpi = ll;
- sa.sadb_sa_spi = ntohl(cpi);
- i++;
- continue;
- }
- if (!strcmp(argv[i] + 1, "dst2") &&
- iscmd(mode, GRP_SPI) && (i + 1 < argc)) {
- sad8.sadb_address_exttype = SADB_X_EXT_DST2;
- memset(&hints, 0, sizeof(hints));
- hints.ai_socktype = SOCK_DGRAM; /*dummy*/
- hints.ai_family = PF_UNSPEC;
- if (getaddrinfo(argv[i + 1], "0", &hints, &res) != 0)
- errx(1, "destination address2 %s is not valid",
- argv[i + 1]);
-
- if (res->ai_next)
- errx(1, "destination address2 %s resolves to "
- "multiple addresses", argv[i + 1]);
-
- switch (res->ai_family) {
- case AF_INET6:
- if (res->ai_addrlen != sizeof(dst2->sin6))
- errx(1, "destination address2 %s resolves "
- "to unexpected address", argv[i + 1]);
- memcpy(&dst2->sin6, res->ai_addr,
- sizeof(dst2->sin6));
- dst2set = 1;
- break;
- case AF_INET:
- if (res->ai_addrlen != sizeof(dst2->sin))
- errx(1, "destination address2 %s resolves "
- "to unexpected address", argv[i + 1]);
- memcpy(&dst2->sin, res->ai_addr,
- sizeof(dst2->sin));
- dst2set = 1;
- break;
- default:
- errx(1, "destination address2 %s resolved to "
- "unsupported address family", argv[i + 1]);
- /* NOTREACHED */
- }
-
- freeaddrinfo(res);
-
- if (dst2set == 0)
- errx(1, "destination address2 %s is not valid",
- argv[i + 1]);
- i++;
- continue;
- }
- if (!strcmp(argv[i] + 1, "src") && (i + 1 < argc)) {
- sad1.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
- memset(&hints, 0, sizeof(hints));
- hints.ai_socktype = SOCK_DGRAM; /*dummy*/
- hints.ai_family = PF_UNSPEC;
- if (getaddrinfo(argv[i + 1], "0", &hints, &res) != 0)
- errx(1, "source address %s is not valid",
- argv[i + 1]);
-
- if (res->ai_next)
- errx(1, "source address %s resolves to "
- "multiple addresses", argv[i + 1]);
-
- switch (res->ai_family) {
- case AF_INET6:
- if (res->ai_addrlen != sizeof(src->sin6))
- errx(1, "source address %s resolves to "
- "unexpected address", argv[i + 1]);
- memcpy(&src->sin6, res->ai_addr,
- sizeof(src->sin6));
- srcset = 1;
- sad1.sadb_address_len = (sizeof(sad1) +
- ROUNDUP(sizeof(struct sockaddr_in6))) / 8;
- break;
- case AF_INET:
- if (res->ai_addrlen != sizeof(src->sin))
- errx(1, "source address %s resolves to "
- "unexpected address", argv[i + 1]);
- memcpy(&src->sin, res->ai_addr,
- sizeof(src->sin));
- srcset = 1;
- sad1.sadb_address_len = (sizeof(sad1) +
- ROUNDUP(sizeof(struct sockaddr_in))) / 8;
- break;
- default:
- errx(1, "source address %s resolved to "
- "unsupported address family", argv[i + 1]);
- /* NOTREACHED */
- }
-
- freeaddrinfo(res);
-
- if (srcset == 0)
- errx(1, "source address %s is not valid",
- argv[i + 1]);
- i++;
- continue;
- }
- if (!strcmp(argv[i] + 1, "proxy") && (i + 1 < argc) && !deny &&
- !bypass && !ipsec) {
- sad3.sadb_address_exttype = SADB_EXT_ADDRESS_PROXY;
- memset(&hints, 0, sizeof(hints));
- hints.ai_socktype = SOCK_DGRAM; /*dummy*/
- hints.ai_family = PF_UNSPEC;
- if (getaddrinfo(argv[i + 1], "0", &hints, &res) != 0)
- errx(1, "proxy address %s is not valid",
- argv[i + 1]);
-
- if (res->ai_next)
- errx(1, "proxy address %s resolves to "
- "multiple addresses", argv[i + 1]);
-
- switch (res->ai_family) {
- case AF_INET6:
- if (res->ai_addrlen != sizeof(proxy->sin6))
- errx(1, "proxy address %s resolves to "
- "unexpected address", argv[i + 1]);
- memcpy(&proxy->sin6, res->ai_addr,
- sizeof(proxy->sin6));
- proxyset = 1;
- sad3.sadb_address_len = (sizeof(sad3) +
- ROUNDUP(sizeof(struct sockaddr_in6))) / 8;
- break;
- case AF_INET:
- if (res->ai_addrlen != sizeof(proxy->sin))
- errx(1, "proxy address %s resolves to "
- "unexpected address", argv[i + 1]);
- memcpy(&proxy->sin, res->ai_addr,
- sizeof(proxy->sin));
- proxyset = 1;
- sad3.sadb_address_len = (sizeof(sad3) +
- ROUNDUP(sizeof(struct sockaddr_in))) / 8;
- break;
- default:
- errx(1, "proxy address %s resolved to "
- "unsupported address family", argv[i + 1]);
- /* NOTREACHED */
- }
-
- freeaddrinfo(res);
-
- if (proxyset == 0)
- errx(1, "proxy address %s is not valid",
- argv[i + 1]);
- i++;
- continue;
- }
- if (!strcmp(argv[i] + 1, "newpadding")) {
- warnx("warning: option newpadding has been deprecated");
- continue;
- }
- if (!strcmp(argv[i] + 1, "in") && iscmd(mode, FLOW)) {
- sprotocol2.sadb_protocol_direction = IPSP_DIRECTION_IN;
- continue;
- }
- if (!strcmp(argv[i] + 1, "out") && iscmd(mode, FLOW)) {
- sprotocol2.sadb_protocol_direction = IPSP_DIRECTION_OUT;
- continue;
- }
- if (!strcmp(argv[i] + 1, "forcetunnel") && isencauth(mode)) {
- sa.sadb_sa_flags |= SADB_X_SAFLAGS_TUNNEL;
- continue;
- }
- if (!strcmp(argv[i] + 1, "udpencap") &&
- udpencap.sadb_x_udpencap_port == 0 && (i + 1 < argc)) {
- if (!(mode & ESP_NEW))
- errx(1, "option udpencap can "
- "be used only with new ESP");
- sa.sadb_sa_flags |= SADB_X_SAFLAGS_UDPENCAP;
- udpencap.sadb_x_udpencap_exttype = SADB_X_EXT_UDPENCAP;
- udpencap.sadb_x_udpencap_len = sizeof(udpencap) / 8;
- udpencap.sadb_x_udpencap_port =
- strtonum(argv[i + 1], 0, USHRT_MAX, &errstr);
- if (errstr)
- errx(1, "invalid port %s", argv[i + 1]);
- udpencap.sadb_x_udpencap_port =
- htons(udpencap.sadb_x_udpencap_port);
- udpencap.sadb_x_udpencap_reserved = 0;
- i++;
- continue;
- }
- if (!strcmp(argv[i] + 1, "halfiv")) {
- if (!(mode & ESP_OLD))
- errx(1, "option halfiv can be used only "
- "with old ESP");
- sa.sadb_sa_flags |= SADB_X_SAFLAGS_HALFIV;
- continue;
- }
- if (!strcmp(argv[i] + 1, "delete") && iscmd(mode, FLOW)) {
- smsg.sadb_msg_type = SADB_X_DELFLOW;
- continue;
- }
- if (!strcmp(argv[i] + 1, "local") && iscmd(mode, FLOW)) {
- warnx("warning: option local has been deprecated");
- continue;
- }
- if (!strcmp(argv[i] + 1, "tunnel") &&
- (isencauth(mode) || mode == ENC_IP) && (i + 2 < argc)) {
- i += 2;
- sa.sadb_sa_flags |= SADB_X_SAFLAGS_TUNNEL;
- continue;
- }
- if (!strcmp(argv[i] + 1, "srcid") && (iscmd(mode, FLOW) ||
- isencauth(mode)) && (i + 1 < argc)) {
- int len = ROUNDUP(strlen(argv[i + 1]) + 1);
-
- if (srcid != NULL)
- errx(1, "srcid specified multiple times");
- if ((srcid = calloc(len, sizeof(char))) == NULL)
- err(1, "calloc");
- strlcpy((char *)srcid, argv[i + 1], len);
- sid1.sadb_ident_len += ROUNDUP(strlen((char *)srcid) + 1) /
- sizeof(u_int64_t);
- i++;
- continue;
- }
- if (!strcmp(argv[i] + 1, "dstid") && (iscmd(mode, FLOW) ||
- isencauth(mode)) && (i + 1 < argc)) {
- int len = ROUNDUP(strlen(argv[i + 1]) + 1);
-
- if (dstid != NULL)
- errx(1, "dstid specified multiple times");
- if ((dstid = calloc(len, sizeof(char))) == NULL)
- err(1, "calloc");
- strlcpy((char *)dstid, argv[i + 1], len);
- sid2.sadb_ident_len += ROUNDUP(strlen((char *)dstid) + 1) /
- sizeof(u_int64_t);
- i++;
- continue;
- }
- if (!strcmp(argv[i] + 1, "srcid_type") && (iscmd(mode, FLOW) ||
- isencauth(mode)) && (i + 1 < argc)) {
- if (sid1.sadb_ident_type != 0)
- errx(1, "srcid_type specified multiple times");
- if (!strcmp(argv[i + 1], "prefix"))
- sid1.sadb_ident_type = SADB_IDENTTYPE_PREFIX;
- else if (!strcmp(argv[i + 1], "fqdn"))
- sid1.sadb_ident_type = SADB_IDENTTYPE_FQDN;
- else if (!strcmp(argv[i + 1], "ufqdn"))
- sid1.sadb_ident_type = SADB_IDENTTYPE_USERFQDN;
- else
- errx(1, "unknown identity type \"%s\"",
- argv[i + 1]);
- i++;
- continue;
- }
- if (!strcmp(argv[i] + 1, "dstid_type") && (iscmd(mode, FLOW) ||
- isencauth(mode)) && (i + 1 < argc)) {
- if (sid2.sadb_ident_type != 0)
- errx(1, "dstid_type specified multiple times");
- if (!strcmp(argv[i + 1], "prefix"))
- sid2.sadb_ident_type = SADB_IDENTTYPE_PREFIX;
- else if (!strcmp(argv[i + 1], "fqdn"))
- sid2.sadb_ident_type = SADB_IDENTTYPE_FQDN;
- else if (!strcmp(argv[i + 1], "ufqdn"))
- sid2.sadb_ident_type = SADB_IDENTTYPE_USERFQDN;
- else
- errx(1, "unknown identity type \"%s\"",
- argv[i + 1]);
- i++;
- continue;
- }
- if (!strcmp(argv[i] + 1, "addr") && iscmd(mode, FLOW) &&
- (i + 1 < argc)) {
- int advance;
-
- sad4.sadb_address_exttype = SADB_X_EXT_SRC_FLOW;
- sad5.sadb_address_exttype = SADB_X_EXT_DST_FLOW;
- sad6.sadb_address_exttype = SADB_X_EXT_SRC_MASK;
- sad7.sadb_address_exttype = SADB_X_EXT_DST_MASK;
-
- switch (addrparse(argv[i + 1], &osrc->sa, &osmask->sa)) {
- case 0:
- advance = 4;
- if (i + 4 >= argc)
- errx(1, "-addr takes 4 arguments");
- if (addrparse(argv[i + 2], &osmask->sa, NULL) != 0 ||
- addrparse(argv[i + 3], &odst->sa, NULL) != 0 ||
- addrparse(argv[i + 4], &odmask->sa, NULL) != 0)
- errx(1, "invalid address on -addr");
- break;
- case 1:
- advance = 2;
- if (i + 2 >= argc)
- errx(1, "-addr takes 2 arguments");
- if (addrparse(argv[i + 2], &odst->sa,
- &odmask->sa) != 1)
- errx(1, "invalid address on -addr");
- break;
- default:
- errx(1, "invalid address %s on -addr", argv[i + 1]);
- /* NOTREACHED */
- }
- if (osrc->sa.sa_family != odst->sa.sa_family)
- errx(1, "mixed address families specified in addr");
- sad4.sadb_address_len = (sizeof(sad4) +
- ROUNDUP(osrc->sa.sa_len)) / 8;
- sad5.sadb_address_len = (sizeof(sad5) +
- ROUNDUP(odst->sa.sa_len)) / 8;
- sad6.sadb_address_len = (sizeof(sad6) +
- ROUNDUP(osmask->sa.sa_len)) / 8;
- sad7.sadb_address_len = (sizeof(sad7) +
- ROUNDUP(odmask->sa.sa_len)) / 8;
-
- i += advance;
- continue;
- }
- if ((!strcmp(argv[i] + 1, "bypass") || !strcmp(argv[i] + 1, "permit"))
- && iscmd(mode, FLOW) && !deny &&
- !ipsec && !bypass) {
- /* Setup everything for a bypass flow */
- bypass = 1;
- sprotocol2.sadb_protocol_proto = SADB_X_FLOW_TYPE_BYPASS;
- continue;
- }
- if (!strcmp(argv[i] + 1, "deny") && iscmd(mode, FLOW) && !ipsec &&
- !deny && !bypass) {
- /* Setup everything for a deny flow */
- deny = 1;
- sprotocol2.sadb_protocol_proto = SADB_X_FLOW_TYPE_DENY;
- continue;
- }
- if (!strcmp(argv[i] + 1, "use") && iscmd(mode, FLOW) && !deny &&
- !bypass && !ipsec) {
- ipsec = 1;
- sprotocol2.sadb_protocol_proto = SADB_X_FLOW_TYPE_USE;
- continue;
- }
- if (!strcmp(argv[i] + 1, "acquire") && iscmd(mode, FLOW) && !deny &&
- !bypass && !ipsec) {
- ipsec = 1;
- sprotocol2.sadb_protocol_proto = SADB_X_FLOW_TYPE_ACQUIRE;
- continue;
- }
- if (!strcmp(argv[i] + 1, "require") && iscmd(mode, FLOW) && !deny &&
- !bypass && !ipsec) {
- ipsec = 1;
- sprotocol2.sadb_protocol_proto = SADB_X_FLOW_TYPE_REQUIRE;
- continue;
- }
- if (!strcmp(argv[i] + 1, "dontacq") && iscmd(mode, FLOW) && !deny &&
- !bypass && !ipsec) {
- ipsec = 1;
- sprotocol2.sadb_protocol_proto = SADB_X_FLOW_TYPE_DONTACQ;
- continue;
- }
- if (!strcmp(argv[i] + 1, "transport") &&
- iscmd(mode, FLOW) && (i + 1 < argc)) {
- if (isalpha(argv[i + 1][0])) {
- tp = getprotobyname(argv[i + 1]);
- if (tp == NULL)
- errx(1, "unknown protocol %s",
- argv[i + 1]);
- tproto = tp->p_proto;
- transportproto = argv[i + 1];
- } else {
- tproto = strtonum(argv[i + 1], 0, INT_MAX,
- &errstr);
- if (errstr)
- errx(1, "bad protocol %s",
- argv[i + 1]);
- tp = getprotobynumber(tproto);
- if (tp == NULL)
- transportproto = "UNKNOWN";
- else
- transportproto = tp->p_name;
- }
-
- sprotocol.sadb_protocol_len = 1;
- sprotocol.sadb_protocol_exttype = SADB_X_EXT_PROTOCOL;
- sprotocol.sadb_protocol_proto = tproto;
- i++;
- continue;
- }
- if (!strcmp(argv[i] + 1, "sport") &&
- iscmd(mode, FLOW) && (i + 1 < argc)) {
- if (isalpha(argv[i + 1][0])) {
- svp = getservbyname(argv[i + 1], transportproto);
- if (svp == NULL)
- errx(1, "unknown service port %s for "
- "protocol %s", argv[i + 1],
- transportproto);
- sport = svp->s_port;
- } else {
- sport = strtonum(argv[i + 1], 0, USHRT_MAX,
- &errstr);
- if (errstr)
- errx(1, "invalid port %s", argv[i + 1]);
- sport = htons(sport);
- }
- i++;
- continue;
- }
- if (!strcmp(argv[i] + 1, "dport") &&
- iscmd(mode, FLOW) && (i + 1 < argc)) {
- if (isalpha(argv[i + 1][0])) {
- svp = getservbyname(argv[i + 1], transportproto);
- if (svp == NULL)
- errx(1, "unknown service port %s for "
- "protocol %s", argv[i + 1],
- transportproto);
- dport = svp->s_port;
- } else {
- dport = strtonum(argv[i + 1], 0, USHRT_MAX,
- &errstr);
- if (errstr)
- errx(1, "invalid port %s", argv[i + 1]);
- dport = htons(dport);
- }
- i++;
- continue;
- }
- if (!strcmp(argv[i] + 1, "dst") && (i + 1 < argc) && !bypass && !deny) {
- sad2.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
- memset(&hints, 0, sizeof(hints));
- hints.ai_socktype = SOCK_DGRAM; /*dummy*/
- hints.ai_family = PF_UNSPEC;
- if (getaddrinfo(argv[i + 1], "0", &hints, &res) != 0)
- errx(1, "destination address %s is not valid",
- argv[i + 1]);
-
- if (res->ai_next)
- errx(1, "destination address %s resolves to "
- "multiple addresses", argv[i + 1]);
-
- switch (res->ai_family) {
- case AF_INET6:
- if (res->ai_addrlen != sizeof(dst->sin6))
- errx(1, "destination address %s resolves to "
- "unexpected address", argv[i + 1]);
- memcpy(&dst->sin6, res->ai_addr,
- sizeof(dst->sin6));
- dstset = 1;
- sad2.sadb_address_len = (sizeof(sad2) +
- ROUNDUP(sizeof(struct sockaddr_in6))) / 8;
- break;
- case AF_INET:
- if (res->ai_addrlen != sizeof(dst->sin))
- errx(1, "destination address %s resolves to "
- "unexpected address", argv[i + 1]);
- memcpy(&dst->sin, res->ai_addr,
- sizeof(dst->sin));
- dstset = 1;
- sad2.sadb_address_len = (sizeof(sad2) +
- ROUNDUP(sizeof(struct sockaddr_in))) / 8;
- break;
- default:
- errx(1, "destination address %s resolved to "
- "unsupported address family", argv[i + 1]);
- /* NOTREACHED */
- }
-
- freeaddrinfo(res);
-
- if (dstset == 0)
- errx(1, "destination address %s is not valid",
- argv[i + 1]);
- i++;
- continue;
- }
- if (!strcmp(argv[i] + 1, "proto2") &&
- iscmd(mode, GRP_SPI) && (i + 1 < argc)) {
- if (isalpha(argv[i + 1][0])) {
- if (!strcasecmp(argv[i + 1], "esp")) {
- sprotocol.sadb_protocol_proto = sproto2 =
- SADB_SATYPE_ESP;
- proto2 = IPPROTO_ESP;
- } else if (!strcasecmp(argv[i + 1], "ah")) {
- sprotocol.sadb_protocol_proto = sproto2 =
- SADB_SATYPE_AH;
- proto2 = IPPROTO_AH;
- } else if (!strcasecmp(argv[i + 1], "ip4")) {
- sprotocol.sadb_protocol_proto = sproto2 =
- SADB_X_SATYPE_IPIP;
- proto2 = IPPROTO_IPIP;
- } else if (!strcasecmp(argv[i + 1], "ipcomp")) {
- sprotocol.sadb_protocol_proto = sproto2 =
- SADB_X_SATYPE_IPCOMP;
- } else
- errx(1, "unknown security protocol2 "
- "type %s", argv[i + 1]);
- } else {
- proto2 = strtonum(argv[i + 1], 0, INT_MAX,
- &errstr);
- if (errstr || (proto2 != IPPROTO_ESP &&
- proto2 != IPPROTO_AH &&
- proto2 != IPPROTO_IPIP &&
- proto2 != IPPROTO_IPCOMP))
- errx(1, "unknown security protocol2 %s",
- argv[i + 1]);
- if (proto2 == IPPROTO_ESP)
- sprotocol.sadb_protocol_proto = sproto2 =
- SADB_SATYPE_ESP;
- else if (proto2 == IPPROTO_AH)
- sprotocol.sadb_protocol_proto = sproto2 =
- SADB_SATYPE_AH;
- else if (proto2 == IPPROTO_IPIP)
- sprotocol.sadb_protocol_proto = sproto2 =
- SADB_X_SATYPE_IPIP;
- else if (proto2 == IPPROTO_IPCOMP)
- sprotocol.sadb_protocol_proto = sproto2 =
- SADB_X_SATYPE_IPCOMP;
- }
- i++;
- continue;
- }
- if (!strcmp(argv[i] + 1, "proto") && (i + 1 < argc) &&
- ((iscmd(mode, FLOW) && !bypass && !deny) || iscmd(mode, DEL_SPI) ||
- iscmd(mode, GRP_SPI))) {
- if (isalpha(argv[i + 1][0])) {
- if (!strcasecmp(argv[i + 1], "esp")) {
- smsg.sadb_msg_satype = SADB_SATYPE_ESP;
- proto = IPPROTO_ESP;
- } else if (!strcasecmp(argv[i + 1], "ah")) {
- smsg.sadb_msg_satype = SADB_SATYPE_AH;
- proto = IPPROTO_AH;
- } else if (!strcasecmp(argv[i + 1], "ip4")) {
- smsg.sadb_msg_satype = SADB_X_SATYPE_IPIP;
- proto = IPPROTO_IPIP;
- } else if (!strcasecmp(argv[i + 1], "ipcomp")) {
- smsg.sadb_msg_satype = SADB_X_SATYPE_IPCOMP;
- proto = IPPROTO_IPCOMP;
- } else if (!strcasecmp(argv[i + 1], "tcpmd5")) {
- smsg.sadb_msg_satype = SADB_X_SATYPE_TCPSIGNATURE;
- proto = IPPROTO_TCP;
- } else
- errx(1, "unknown security protocol type %s",
- argv[i + 1]);
- } else {
- proto = strtonum(argv[i + 1], 0, INT_MAX,
- &errstr);
- if (errstr || (proto != IPPROTO_ESP &&
- proto != IPPROTO_AH &&
- proto != IPPROTO_IPIP &&
- proto != IPPROTO_IPCOMP)) {
- errx(1, "unknown security protocol %s",
- argv[i + 1]);
- }
- if (proto == IPPROTO_ESP)
- smsg.sadb_msg_satype = SADB_SATYPE_ESP;
- else if (proto == IPPROTO_AH)
- smsg.sadb_msg_satype = SADB_SATYPE_AH;
- else if (proto == IPPROTO_IPIP)
- smsg.sadb_msg_satype = SADB_X_SATYPE_IPIP;
- else if (proto == IPPROTO_IPCOMP)
- smsg.sadb_msg_satype = SADB_X_SATYPE_IPCOMP;
- }
- i++;
- continue;
- }
- errx(1, "unknown option: %s", argv[i]);
- }
-
- if (iscmd(mode, SHOW)) {
- ipsecadm_show(smsg.sadb_msg_satype);
- exit(0);
- } else if (iscmd(mode, MONITOR)) {
- ipsecadm_monitor();
- exit(0);
- }
-
- /* Sanity checks */
- if ((mode & (ESP_NEW | ESP_OLD)) && enc == 0 && auth == 0)
- errx(1, "no encryption or authentication algorithm specified");
- if (iscmd(mode, GRP_SPI) && spi2 == SPI_LOCAL_USE)
- errx(1, "no SPI2 specified");
- if ((mode & (AH_NEW | AH_OLD)) && auth == 0)
- errx(1, "no authentication algorithm specified");
- if (iscmd(mode, IPCOMP) && comp == 0)
- errx(1, "no compression algorithm specified");
- if ((srcid != NULL) && (sid1.sadb_ident_type == 0))
- errx(1, "srcid_type not specified");
- if ((dstid != NULL) && (sid2.sadb_ident_type == 0))
- errx(1, "dstid_type not specified");
- if ((srcid == NULL) && (sid1.sadb_ident_type != 0))
- errx(1, "srcid_type specified, but no srcid given");
- if ((dstid == NULL) && (sid2.sadb_ident_type != 0))
- errx(1, "dstid_type specified, but no dstid given");
- if (((mode & (ESP_NEW | ESP_OLD)) && enc && keyp == NULL) ||
- ((mode & (AH_NEW | AH_OLD | TCPMD5)) && authp == NULL))
- errx(1, "no key material specified");
- if ((mode & ESP_NEW) && auth && authp == NULL)
- errx(1, "no auth key material specified");
- if (spi == SPI_LOCAL_USE && !iscmd(mode, FLUSH) && !iscmd(mode, FLOW)
- && !iscmd(mode, IPCOMP))
- errx(1, "no SPI specified");
- if (iscmd(mode, IPCOMP) && cpi == SPI_LOCAL_USE)
- errx(1, "no CPI specified");
- if ((isencauth(mode) || iscmd(mode, ENC_IP)) && !srcset)
- errx(1, "no source address specified");
- if (!dstset && !iscmd(mode, FLUSH) && !iscmd(mode, FLOW))
- errx(1, "no destination address for the SA specified");
- if (iscmd(mode, FLOW) && (sprotocol.sadb_protocol_proto == 0) &&
- (odst->sin.sin_port || osrc->sin.sin_port))
- errx(1, "no transport protocol supplied with"
- " source/destination ports");
- if (iscmd(mode, GRP_SPI) && !dst2set)
- errx(1, "no destination address2 specified");
- if ((klen > 2 * 8100) || (alen > 2 * 8100))
- errx(1, "key too long");
- if (iscmd(mode, FLOW) && proto == IPPROTO_IPCOMP)
- sprotocol2.sadb_protocol_proto = SADB_X_FLOW_TYPE_USE;
- if (keyp != NULL)
- for (i = 0; i < klen; i++)
- realkey[i] = x2i(keyp + 2 * i);
- if (authp != NULL)
- for (i = 0; i < alen; i++)
- realakey[i] = x2i(authp + 2 * i);
- /* message header */
- iov[cnt].iov_base = &smsg;
- iov[cnt++].iov_len = sizeof(smsg);
-
- if (isencauth(mode) || iscmd(mode, TCPMD5)) { /* XXX */
- /* SA header */
- iov[cnt].iov_base = &sa;
- iov[cnt++].iov_len = sizeof(sa);
- smsg.sadb_msg_len += sa.sadb_sa_len;
-
- /* Destination address header */
- iov[cnt].iov_base = &sad2;
- iov[cnt++].iov_len = sizeof(sad2);
- /* Destination address */
- iov[cnt].iov_base = dst;
- iov[cnt++].iov_len = ROUNDUP(dst->sa.sa_len);
- smsg.sadb_msg_len += sad2.sadb_address_len;
-
- if (srcid) {
- iov[cnt].iov_base = &sid1;
- iov[cnt++].iov_len = sizeof(sid1);
- /* SRC identity */
- iov[cnt].iov_base = srcid;
- iov[cnt++].iov_len = ROUNDUP(strlen((char *)srcid) + 1);
- smsg.sadb_msg_len += sid1.sadb_ident_len;
- }
- if (dstid) {
- iov[cnt].iov_base = &sid2;
- iov[cnt++].iov_len = sizeof(sid2);
- /* DST identity */
- iov[cnt].iov_base = dstid;
- iov[cnt++].iov_len = ROUNDUP(strlen((char *)dstid) + 1);
- smsg.sadb_msg_len += sid2.sadb_ident_len;
- }
- if (sad1.sadb_address_exttype) {
- /* Source address header */
- iov[cnt].iov_base = &sad1;
- iov[cnt++].iov_len = sizeof(sad1);
- /* Source address */
- iov[cnt].iov_base = src;
- iov[cnt++].iov_len = ROUNDUP(src->sa.sa_len);
- smsg.sadb_msg_len += sad1.sadb_address_len;
- }
- if (proxy->sa.sa_len) {
- /* Proxy address header */
- iov[cnt].iov_base = &sad3;
- iov[cnt++].iov_len = sizeof(sad3);
- /* Proxy address */
- iov[cnt].iov_base = proxy;
- iov[cnt++].iov_len = ROUNDUP(proxy->sa.sa_len);
- smsg.sadb_msg_len += sad3.sadb_address_len;
- }
- if (keyp) {
- /* Key header */
- iov[cnt].iov_base = &skey1;
- iov[cnt++].iov_len = sizeof(skey1);
- /* Key */
- iov[cnt].iov_base = realkey;
- iov[cnt++].iov_len = ((klen + 7) / 8) * 8;
- skey1.sadb_key_exttype = SADB_EXT_KEY_ENCRYPT;
- skey1.sadb_key_len = (sizeof(skey1) + ((klen + 7) / 8) * 8) / 8;
- skey1.sadb_key_bits = 8 * klen;
- smsg.sadb_msg_len += skey1.sadb_key_len;
- }
- if (authp) {
- /* Auth key header */
- iov[cnt].iov_base = &skey2;
- iov[cnt++].iov_len = sizeof(skey2);
- /* Auth key */
- iov[cnt].iov_base = realakey;
- iov[cnt++].iov_len = ((alen + 7) / 8) * 8;
- skey2.sadb_key_exttype = SADB_EXT_KEY_AUTH;
- skey2.sadb_key_len = (sizeof(skey2) + ((alen + 7) / 8) * 8) / 8;
- skey2.sadb_key_bits = 8 * alen;
- smsg.sadb_msg_len += skey2.sadb_key_len;
- }
- if (sa.sadb_sa_flags & SADB_X_SAFLAGS_UDPENCAP) {
- iov[cnt].iov_base = &udpencap;
- iov[cnt++].iov_len = sizeof(udpencap);
- smsg.sadb_msg_len += udpencap.sadb_x_udpencap_len;
- }
- } else {
- switch (mode & CMD_MASK) {
- case GRP_SPI:
- /* SA header */
- iov[cnt].iov_base = &sa;
- iov[cnt++].iov_len = sizeof(sa);
- smsg.sadb_msg_len += sa.sadb_sa_len;
-
- /* Destination address header */
- iov[cnt].iov_base = &sad2;
- iov[cnt++].iov_len = sizeof(sad2);
- /* Destination address */
- iov[cnt].iov_base = dst;
- iov[cnt++].iov_len = ROUNDUP(dst->sa.sa_len);
- smsg.sadb_msg_len += sad2.sadb_address_len;
-
- /* SA header */
- iov[cnt].iov_base = &sa2;
- iov[cnt++].iov_len = sizeof(sa2);
- smsg.sadb_msg_len += sa2.sadb_sa_len;
-
- /* Destination2 address header */
- iov[cnt].iov_base = &sad8;
- iov[cnt++].iov_len = sizeof(sad8);
- /* Destination2 address */
- iov[cnt].iov_base = dst2;
- iov[cnt++].iov_len = ROUNDUP(dst2->sa.sa_len);
- smsg.sadb_msg_len += sad8.sadb_address_len;
-
- sprotocol.sadb_protocol_proto = sproto2;
-
- /* Protocol2 */
- iov[cnt].iov_base = &sprotocol;
- iov[cnt++].iov_len = sizeof(sprotocol);
- smsg.sadb_msg_len += sprotocol.sadb_protocol_len;
- break;
-
- case DEL_SPI:
- /* SA header */
- iov[cnt].iov_base = &sa;
- iov[cnt++].iov_len = sizeof(sa);
- smsg.sadb_msg_len += sa.sadb_sa_len;
-
- /* Destination address header */
- iov[cnt].iov_base = &sad2;
- iov[cnt++].iov_len = sizeof(sad2);
- /* Destination address */
- iov[cnt].iov_base = dst;
- iov[cnt++].iov_len = ROUNDUP(dst->sa.sa_len);
- smsg.sadb_msg_len += sad2.sadb_address_len;
- break;
-
- case ENC_IP:
- /* SA header */
- iov[cnt].iov_base = &sa;
- iov[cnt++].iov_len = sizeof(sa);
- smsg.sadb_msg_len += sa.sadb_sa_len;
-
- /* Destination address header */
- iov[cnt].iov_base = &sad2;
- iov[cnt++].iov_len = sizeof(sad2);
- /* Destination address */
- iov[cnt].iov_base = dst;
- iov[cnt++].iov_len = ROUNDUP(dst->sa.sa_len);
- smsg.sadb_msg_len += sad2.sadb_address_len;
-
- if (sad1.sadb_address_exttype) {
- /* Source address header */
- iov[cnt].iov_base = &sad1;
- iov[cnt++].iov_len = sizeof(sad1);
- /* Source address */
- iov[cnt].iov_base = src;
- iov[cnt++].iov_len = ROUNDUP(src->sa.sa_len);
- smsg.sadb_msg_len += sad1.sadb_address_len;
- }
- break;
-
- case IPCOMP:
- /* SA header */
- iov[cnt].iov_base = &sa;
- iov[cnt++].iov_len = sizeof(sa);
- smsg.sadb_msg_len += sa.sadb_sa_len;
-
- /* Destination address header */
- iov[cnt].iov_base = &sad2;
- iov[cnt++].iov_len = sizeof(sad2);
- /* Destination address */
- iov[cnt].iov_base = dst;
- iov[cnt++].iov_len = ROUNDUP(dst->sa.sa_len);
- smsg.sadb_msg_len += sad2.sadb_address_len;
-
- if (sad1.sadb_address_exttype) {
- /* Source address header */
- iov[cnt].iov_base = &sad1;
- iov[cnt++].iov_len = sizeof(sad1);
- /* Source address */
- iov[cnt].iov_base = src;
- iov[cnt++].iov_len = ROUNDUP(src->sa.sa_len);
- smsg.sadb_msg_len += sad1.sadb_address_len;
- }
- break;
-
- case FLOW:
- if ((smsg.sadb_msg_type != SADB_X_DELFLOW) &&
- (sad2.sadb_address_exttype)) {
- /* Destination address header */
- iov[cnt].iov_base = &sad2;
- iov[cnt++].iov_len = sizeof(sad2);
- /* Destination address */
- iov[cnt].iov_base = dst;
- iov[cnt++].iov_len = ROUNDUP(dst->sa.sa_len);
- smsg.sadb_msg_len += sad2.sadb_address_len;
- }
- if ((sad1.sadb_address_exttype) &&
- (smsg.sadb_msg_type != SADB_X_DELFLOW)) {
- /* Source address header */
- iov[cnt].iov_base = &sad1;
- iov[cnt++].iov_len = sizeof(sad1);
- /* Source address */
- iov[cnt].iov_base = src;
- iov[cnt++].iov_len = ROUNDUP(src->sa.sa_len);
- smsg.sadb_msg_len += sad1.sadb_address_len;
- }
- if (sprotocol.sadb_protocol_len) {
- /* Transport protocol */
- iov[cnt].iov_base = &sprotocol;
- iov[cnt++].iov_len = sizeof(sprotocol);
- smsg.sadb_msg_len += sprotocol.sadb_protocol_len;
- }
- /* Flow type */
- iov[cnt].iov_base = &sprotocol2;
- iov[cnt++].iov_len = sizeof(sprotocol2);
- smsg.sadb_msg_len += sprotocol2.sadb_protocol_len;
-
- /* Flow source address header */
- if ((sport != -1) && (sport != 0)) {
- if (osrc->sa.sa_family == AF_INET) {
- osrc->sin.sin_port = sport;
- osmask->sin.sin_port = 0xffff;
- } else if (osrc->sa.sa_family == AF_INET6) {
- osrc->sin6.sin6_port = sport;
- osmask->sin6.sin6_port = 0xffff;
- }
- }
- iov[cnt].iov_base = &sad4;
- iov[cnt++].iov_len = sizeof(sad4);
- /* Flow source address */
- iov[cnt].iov_base = osrc;
- iov[cnt++].iov_len = ROUNDUP(osrc->sa.sa_len);
- smsg.sadb_msg_len += sad4.sadb_address_len;
-
- /* Flow destination address header */
- iov[cnt].iov_base = &sad5;
- iov[cnt++].iov_len = sizeof(sad5);
- /* Flow destination address */
- if ((dport != -1) && (dport != 0)) {
- if (odst->sa.sa_family == AF_INET) {
- odst->sin.sin_port = dport;
- odmask->sin.sin_port = 0xffff;
- } else if (odst->sa.sa_family == AF_INET6) {
- odst->sin6.sin6_port = dport;
- odmask->sin6.sin6_port = 0xffff;
- }
- }
- iov[cnt].iov_base = odst;
- iov[cnt++].iov_len = ROUNDUP(odst->sa.sa_len);
- smsg.sadb_msg_len += sad5.sadb_address_len;
-
- /* Flow source address mask header */
- iov[cnt].iov_base = &sad6;
- iov[cnt++].iov_len = sizeof(sad6);
- /* Flow source address mask */
- iov[cnt].iov_base = osmask;
- iov[cnt++].iov_len = ROUNDUP(osmask->sa.sa_len);
- smsg.sadb_msg_len += sad6.sadb_address_len;
-
- /* Flow destination address mask header */
- iov[cnt].iov_base = &sad7;
- iov[cnt++].iov_len = sizeof(sad7);
- /* Flow destination address mask */
- iov[cnt].iov_base = odmask;
- iov[cnt++].iov_len = ROUNDUP(odmask->sa.sa_len);
- smsg.sadb_msg_len += sad7.sadb_address_len;
-
- if (srcid &&
- (smsg.sadb_msg_type != SADB_X_DELFLOW)) {
- iov[cnt].iov_base = &sid1;
- iov[cnt++].iov_len = sizeof(sid1);
- /* SRC identity */
- iov[cnt].iov_base = srcid;
- iov[cnt++].iov_len = ROUNDUP(strlen((char *)srcid) + 1);
- smsg.sadb_msg_len += sid1.sadb_ident_len;
- }
- if (dstid &&
- (smsg.sadb_msg_type != SADB_X_DELFLOW)) {
- iov[cnt].iov_base = &sid2;
- iov[cnt++].iov_len = sizeof(sid2);
- /* DST identity */
- iov[cnt].iov_base = dstid;
- iov[cnt++].iov_len = ROUNDUP(strlen((char *)dstid) + 1);
- smsg.sadb_msg_len += sid2.sadb_ident_len;
- }
- break;
-
- case FLUSH:
- /* No more work needed */
- break;
- }
- }
-
- xf_set(iov, cnt, smsg.sadb_msg_len * 8);
- exit(0);
-}