summaryrefslogtreecommitdiff
path: root/sbin/ipsecadm/ipsecadm.c
diff options
context:
space:
mode:
Diffstat (limited to 'sbin/ipsecadm/ipsecadm.c')
-rw-r--r--sbin/ipsecadm/ipsecadm.c509
1 files changed, 189 insertions, 320 deletions
diff --git a/sbin/ipsecadm/ipsecadm.c b/sbin/ipsecadm/ipsecadm.c
index 93a91eb29ab..6d3082375a0 100644
--- a/sbin/ipsecadm/ipsecadm.c
+++ b/sbin/ipsecadm/ipsecadm.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ipsecadm.c,v 1.38 2000/05/02 21:50:30 ho Exp $ */
+/* $OpenBSD: ipsecadm.c,v 1.39 2000/09/19 03:18:11 angelos Exp $ */
/*
* The authors of this code are John Ioannidis (ji@tla.org),
* Angelos D. Keromytis (kermit@csd.uch.gr) and
@@ -73,9 +73,7 @@
#define XF_ENC 0x10
#define XF_AUTH 0x20
#define DEL_SPI 0x30
-#define GRP_SPI 0x40
#define FLOW 0x50
-#define BINDSA 0x60
#define FLUSH 0x70
#define ENC_IP 0x80
@@ -184,7 +182,7 @@ usage()
{
fprintf(stderr, "usage: ipsecadm [command] <modifier...>\n"
"\tCommands: new esp, old esp, new ah, old ah, group, delspi, ip4,\n"
- "\t\t flow, bind, flush\n"
+ "\t\t flow, flush\n"
"\tPossible modifiers:\n"
"\t -enc <alg>\t\t\tencryption algorithm\n"
"\t -auth <alg>\t\t\tauthentication algorithm\n"
@@ -192,23 +190,28 @@ usage()
"\t -halfiv\t\t\tuse 4-byte IV in old ESP\n"
"\t -forcetunnel\t\t\tforce IP-in-IP 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 -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 -proto <val>\t\t\tsecurity protocol\n"
- "\t -chain\t\t\tSPI chain delete\n"
+ "\t -sport\t\t\tsource port for flow\n"
+ "\t -dport\t\t\tdestination port for flow\n"
"\t -transport <val>\t\tprotocol number for flow\n"
"\t -addr <ip> <net> <ip> <net>\tsubnets for flow\n"
"\t -delete\t\t\tdelete specified flow\n"
- "\t -bypass\t\t\tcreate/delete a bypass flow\n"
- "\t -sport\t\t\tsource port for flow\n"
- "\t -dport\t\t\tdestination port for flow\n"
- "\t -ingress\t\t\tflow is ingress access control entry\n"
- "\t -[ah|esp|ip4]\t\t\tto flush a particular protocol\n"
- "\talso: dst2, spi2, proto2\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]\t\t\tflush a particular protocol\n"
);
}
@@ -216,9 +219,9 @@ 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, ingress = 0;
- int dport = -1, sport = -1, tproto = -1, setmask = 0;
- u_int32_t spi = SPI_RESERVED_MIN, spi2 = SPI_RESERVED_MIN;
+ int proto = IPPROTO_ESP, proto2 = IPPROTO_AH;
+ int dport = -1, sport = -1, tproto = -1;
+ u_int32_t spi = 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];
@@ -230,7 +233,6 @@ main(int argc, char **argv)
char *transportproto = NULL;
struct sadb_msg smsg;
struct sadb_sa sa;
- struct sadb_sa sa2;
struct sadb_address sad1; /* src */
struct sadb_address sad2; /* dst */
struct sadb_address sad3; /* proxy */
@@ -242,11 +244,14 @@ main(int argc, char **argv)
struct sadb_key skey1;
struct sadb_key skey2;
struct sadb_protocol sprotocol;
+ struct sadb_protocol sprotocol2;
struct iovec iov[20];
int cnt = 0;
u_char realkey[8192], realakey[8192];
int bypass = 0;
-
+ int deny = 0;
+ int ipsec = 0;
+
if (argc < 2)
{
usage();
@@ -256,7 +261,6 @@ main(int argc, char **argv)
/* Zero out */
bzero(&smsg, sizeof(smsg));
bzero(&sa, sizeof(sa));
- bzero(&sa2, sizeof(sa2));
bzero(&skey1, sizeof(skey1));
bzero(&skey2, sizeof(skey2));
bzero(&sad1, sizeof(sad1));
@@ -268,6 +272,7 @@ main(int argc, char **argv)
bzero(&sad7, sizeof(sad7));
bzero(&sad8, sizeof(sad8));
bzero(&sprotocol, sizeof(sprotocol));
+ bzero(&sprotocol2, sizeof(sprotocol2));
bzero(iov, sizeof(iov));
bzero(realkey, sizeof(realkey));
bzero(realakey, sizeof(realakey));
@@ -302,11 +307,9 @@ main(int argc, char **argv)
sa.sadb_sa_replay = 0;
sa.sadb_sa_state = SADB_SASTATE_MATURE;
- /* Initialize */
- sa2.sadb_sa_exttype = SADB_X_EXT_SA2;
- sa2.sadb_sa_len = sizeof(sa2) / 8;
- sa2.sadb_sa_replay = 0;
- sa2.sadb_sa_state = SADB_SASTATE_MATURE;
+ sprotocol2.sadb_protocol_len = 1;
+ sprotocol2.sadb_protocol_exttype = SADB_X_EXT_FLOW_TYPE;
+ sprotocol2.sadb_protocol_direction = IPSP_DIRECTION_OUT;
if (!strcmp(argv[1], "new") && argc > 3)
{
@@ -369,52 +372,37 @@ main(int argc, char **argv)
i++;
}
else
- if (!strcmp(argv[1], "group"))
+ if (!strcmp(argv[1], "flow"))
{
- smsg.sadb_msg_type = SADB_X_GRPSPIS;
- mode = GRP_SPI;
+ /* 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], "bind"))
+ if (!strcmp(argv[1], "flush"))
{
- smsg.sadb_msg_type = SADB_X_BINDSA;
- smsg.sadb_msg_satype = SADB_SATYPE_ESP;
- mode = BINDSA;
+ mode = FLUSH;
+ smsg.sadb_msg_type = SADB_FLUSH;
+ smsg.sadb_msg_satype = SADB_SATYPE_UNSPEC;
i++;
}
- else
- if (!strcmp(argv[1], "flow"))
+ else
+ if (!strcmp(argv[1], "ip4"))
{
- /* 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;
+ mode = ENC_IP;
+ smsg.sadb_msg_type = SADB_ADD;
+ smsg.sadb_msg_satype = SADB_X_SATYPE_IPIP;
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
- {
- fprintf(stderr, "%s: unknown command: %s\n", argv[0],
- argv[1]);
- usage();
- exit(1);
- }
+ {
+ fprintf(stderr, "%s: unknown command: %s\n", argv[0],
+ argv[1]);
+ usage();
+ exit(1);
+ }
for (i++; i < argc; i++)
{
@@ -604,6 +592,7 @@ main(int argc, char **argv)
fprintf(stderr,
"%s: Warning: option iv has been deprecated\n", argv[0]);
+ /* Horrible hack */
if (mode & ESP_OLD)
if (strlen(argv[i + 2]) == 4)
sa.sadb_sa_flags |= SADB_X_SAFLAGS_HALFIV;
@@ -620,23 +609,20 @@ main(int argc, char **argv)
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, "bypass"))
- smsg.sadb_msg_satype = SADB_X_SATYPE_BYPASS;
- else
- {
- fprintf(stderr, "%s: invalid SA type %s\n", argv[0],
- argv[i + 1]);
- exit(1);
- }
+ if(!strcmp(argv[i] + 1, "ip4"))
+ smsg.sadb_msg_satype = SADB_X_SATYPE_IPIP;
+ else
+ {
+ fprintf(stderr, "%s: invalid SA type %s\n",
+ argv[0], argv[i + 1]);
+ exit(1);
+ }
i++;
continue;
}
- if (!strcmp(argv[i] + 1, "spi") && spi == SPI_RESERVED_MIN &&
- (i + 1 < argc) && !bypass)
+ if (!strcmp(argv[i] + 1, "spi") && spi == SPI_LOCAL_USE &&
+ (i + 1 < argc) && !bypass && !deny)
{
spi = htonl(strtoul(argv[i + 1], NULL, 16));
if (spi >= SPI_RESERVED_MIN && spi <= SPI_RESERVED_MAX)
@@ -650,22 +636,6 @@ main(int argc, char **argv)
continue;
}
- if (!strcmp(argv[i] + 1, "spi2") && spi2 == SPI_RESERVED_MIN &&
- (iscmd(mode, GRP_SPI) || iscmd(mode, BINDSA)) && (i + 1 < argc))
- {
- spi2 = htonl(strtoul(argv[i + 1], NULL, 16));
- if (spi2 == SPI_LOCAL_USE ||
- (spi2 >= SPI_RESERVED_MIN && spi2 <= SPI_RESERVED_MAX))
- {
- fprintf(stderr, "%s: invalid spi2 %s\n", argv[0], argv[i + 1]);
- exit(1);
- }
-
- sa2.sadb_sa_spi = spi2;
- i++;
- continue;
- }
-
if (!strcmp(argv[i] + 1, "src") && (i + 1 < argc))
{
sad1.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
@@ -700,7 +670,8 @@ main(int argc, char **argv)
continue;
}
- if (!strcmp(argv[i] + 1, "proxy") && (i + 1 < argc))
+ if (!strcmp(argv[i] + 1, "proxy") && (i + 1 < argc) && !deny &&
+ !bypass && !ipsec)
{
sad3.sadb_address_exttype = SADB_EXT_ADDRESS_PROXY;
#ifdef INET6
@@ -743,6 +714,18 @@ main(int argc, char **argv)
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;
@@ -771,8 +754,7 @@ main(int argc, char **argv)
if (!strcmp(argv[i] + 1, "local") && iscmd(mode, FLOW))
{
- fprintf(stderr,
- "%s: Warning: option local has been deprecated\n",
+ fprintf(stderr, "%s: Warning: option local has been deprecated\n",
argv[0]);
continue;
}
@@ -828,7 +810,6 @@ main(int argc, char **argv)
sizeof(struct sockaddr_in6);
osmask->sin6.sin6_len = sizeof(struct sockaddr_in6);
odmask->sin6.sin6_len = sizeof(struct sockaddr_in6);
- setmask = 1;
if (!inet_pton(AF_INET6, argv[i + 1], &osrc->sin6.sin6_addr))
{
@@ -879,7 +860,6 @@ main(int argc, char **argv)
sizeof(struct sockaddr_in);
osmask->sin.sin_len = sizeof(struct sockaddr_in);
odmask->sin.sin_len = sizeof(struct sockaddr_in);
- setmask = 1;
if (!inet_pton(AF_INET, argv[i + 1], &osrc->sin.sin_addr))
{
@@ -915,21 +895,54 @@ main(int argc, char **argv)
continue;
}
- if (!strcmp(argv[i] + 1, "bypass") && iscmd(mode, FLOW))
+ 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;
- sa.sadb_sa_spi = 0;
- sprotocol.sadb_protocol_len = 1;
- sprotocol.sadb_protocol_exttype = SADB_X_EXT_PROTOCOL;
- sprotocol.sadb_protocol_proto = 0;
- smsg.sadb_msg_satype = SADB_X_SATYPE_BYPASS;
- sad2.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
- sad2.sadb_address_len = (sizeof(sad2) +
- sizeof(struct sockaddr_in)) / 8;
- dst->sin.sin_family = AF_INET;
- dst->sin.sin_len = sizeof(struct sockaddr_in);
- dstset = inet_aton("0.0.0.0", &dst->sin.sin_addr) != -1 ? 1 : 0;
+ sprotocol2.sadb_protocol_proto = FLOW_X_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 = FLOW_X_TYPE_DENY;
+ continue;
+ }
+
+ if (!strcmp(argv[i] + 1, "use") && iscmd(mode, FLOW) && !deny &&
+ !bypass && !ipsec)
+ {
+ ipsec = 1;
+ sprotocol2.sadb_protocol_proto = FLOW_X_TYPE_USE;
+ continue;
+ }
+
+ if (!strcmp(argv[i] + 1, "acquire") && iscmd(mode, FLOW) && !deny &&
+ !bypass && !ipsec)
+ {
+ ipsec = 1;
+ sprotocol2.sadb_protocol_proto = FLOW_X_TYPE_ACQUIRE;
+ continue;
+ }
+
+ if (!strcmp(argv[i] + 1, "require") && iscmd(mode, FLOW) && !deny &&
+ !bypass && !ipsec)
+ {
+ ipsec = 1;
+ sprotocol2.sadb_protocol_proto = FLOW_X_TYPE_REQUIRE;
+ continue;
+ }
+
+ if (!strcmp(argv[i] + 1, "dontacq") && iscmd(mode, FLOW) && !deny &&
+ !bypass && !ipsec)
+ {
+ ipsec = 1;
+ sprotocol2.sadb_protocol_proto = FLOW_X_TYPE_DONTACQ;
continue;
}
@@ -985,19 +998,10 @@ main(int argc, char **argv)
else
sport = htons(atoi(argv[i+1]));
- osrc->sin.sin_port = sport;
- osmask->sin.sin_port = 0xffff;
i++;
continue;
}
- if (!strcmp(argv[i] + 1, "ingress") && iscmd(mode, FLOW))
- {
- sa.sadb_sa_flags |= SADB_X_SAFLAGS_INGRESS_FLOW;
- ingress = 1;
- continue;
- }
-
if (!strcmp(argv[i] + 1, "dport") &&
iscmd(mode, FLOW) && (i + 1 < argc))
{
@@ -1016,13 +1020,11 @@ main(int argc, char **argv)
else
dport = htons(atoi(argv[i + 1]));
- odst->sin.sin_port = dport;
- odmask->sin.sin_port = 0xffff;
i++;
continue;
}
- if (!strcmp(argv[i] + 1, "dst") && (i + 1 < argc) && !bypass)
+ if (!strcmp(argv[i] + 1, "dst") && (i + 1 < argc) && !bypass && !deny)
{
sad2.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
#ifdef INET6
@@ -1058,46 +1060,8 @@ main(int argc, char **argv)
continue;
}
- if (!strcmp(argv[i] + 1, "dst2") &&
- (iscmd(mode, GRP_SPI) || iscmd(mode, BINDSA)) && (i + 1 < argc))
- {
- sad8.sadb_address_exttype = SADB_X_EXT_DST2;
-#ifdef INET6
- if (strchr(argv[i + 1], ':'))
- {
- sad8.sadb_address_len = (sizeof(sad8) +
- ROUNDUP(sizeof(struct sockaddr_in6)))
- / 8;
- dst2->sin6.sin6_family = AF_INET6;
- dst2->sin6.sin6_len = sizeof(struct sockaddr_in6);
- dst2set = inet_pton(AF_INET6, argv[i + 1],
- &dst2->sin6.sin6_addr) != -1 ? 1 : 0;
- }
- else
-#endif /* INET6 */
- {
- sad8.sadb_address_len = (sizeof(sad8) +
- sizeof(struct sockaddr_in)) / 8;
- dst2->sin.sin_family = AF_INET;
- dst2->sin.sin_len = sizeof(struct sockaddr_in);
- dst2set = inet_pton(AF_INET, argv[i + 1],
- &dst2->sin.sin_addr) != -1 ? 1 : 0;
- }
-
- if (dst2set == 0)
- {
- fprintf(stderr,
- "%s: Warning: destination address2 %s is not valid\n",
- argv[0], argv[i + 1]);
- exit(1);
- }
- i++;
- continue;
- }
-
if (!strcmp(argv[i] + 1, "proto") && (i + 1 < argc) &&
- ((iscmd(mode, FLOW) && !bypass) || iscmd(mode, GRP_SPI) ||
- iscmd(mode, DEL_SPI) || iscmd(mode, BINDSA)))
+ ((iscmd(mode, FLOW) && !bypass && !deny) || iscmd(mode, DEL_SPI)))
{
if (isalpha(argv[i + 1][0]))
{
@@ -1152,75 +1116,8 @@ main(int argc, char **argv)
continue;
}
- if (!strcmp(argv[i] + 1, "proto2") &&
- (iscmd(mode, BINDSA) || iscmd(mode, GRP_SPI)) && (i + 1 < argc))
- {
- if (isalpha(argv[i + 1][0]))
- {
- if (!strcasecmp(argv[i + 1], "esp"))
- {
- sprotocol.sadb_protocol_proto = SADB_SATYPE_ESP;
- proto2 = IPPROTO_ESP;
- }
- else
- if (!strcasecmp(argv[i + 1], "ah"))
- {
- sprotocol.sadb_protocol_proto = SADB_SATYPE_AH;
- proto2 = IPPROTO_AH;
- }
- else
- if (!strcasecmp(argv[i + 1], "ip4"))
- {
- sprotocol.sadb_protocol_proto = SADB_X_SATYPE_IPIP;
- proto2 = IPPROTO_IPIP;
- }
- else
- {
- fprintf(stderr,
- "%s: unknown security protocol2 type %s\n",
- argv[0], argv[i+1]);
- exit(1);
- }
- }
- else
- {
- proto2 = atoi(argv[i + 1]);
-
- if (proto2 != IPPROTO_ESP && proto2 != IPPROTO_AH &&
- proto2 != IPPROTO_IPIP)
- {
- fprintf(stderr,
- "%s: unknown security protocol2 %d\n",
- argv[0], proto2);
- exit(1);
- }
-
- if (proto2 == IPPROTO_ESP)
- sprotocol.sadb_protocol_proto = SADB_SATYPE_ESP;
- else
- if (proto2 == IPPROTO_AH)
- sprotocol.sadb_protocol_proto = SADB_SATYPE_AH;
- else
- if (proto2 == IPPROTO_IPIP)
- sprotocol.sadb_protocol_proto = SADB_X_SATYPE_IPIP;
- }
-
- sprotocol.sadb_protocol_exttype = SADB_X_EXT_PROTOCOL;
- sprotocol.sadb_protocol_len = 1;
- i++;
- continue;
- }
-
- if (!strcmp(argv[i] + 1, "chain") &&
- !(sa.sadb_sa_flags & SADB_X_SAFLAGS_CHAINDEL) &&
- iscmd(mode, DEL_SPI))
- {
- sa.sadb_sa_flags |= SADB_X_SAFLAGS_CHAINDEL;
- continue;
- }
-
/* No match */
- fprintf(stderr, "%s: Unknown or invalid option: %s\n",
+ fprintf(stderr, "%s: Unknown, invalid, or duplicated option: %s\n",
argv[0], argv[i]);
exit(1);
}
@@ -1253,82 +1150,35 @@ main(int argc, char **argv)
exit(1);
}
- if (spi == SPI_RESERVED_MIN && !iscmd(mode, FLUSH) && !bypass &&
- (!iscmd(mode, FLOW) || (iscmd(mode, FLOW) &&
- (smsg.sadb_msg_type != SADB_X_DELFLOW ||
- ingress))))
+ if (spi == SPI_LOCAL_USE && !iscmd(mode, FLUSH) && !iscmd(mode, FLOW))
{
fprintf(stderr, "%s: no SPI specified\n", argv[0]);
exit(1);
}
- if ((iscmd(mode, GRP_SPI) || iscmd(mode, BINDSA)) &&
- spi2 == SPI_RESERVED_MIN)
- {
- fprintf(stderr, "%s: no SPI2 specified\n", argv[0]);
- exit(1);
- }
-
if ((isencauth(mode) || iscmd(mode, ENC_IP)) && !srcset)
{
fprintf(stderr, "%s: no source address specified\n", argv[0]);
exit(1);
}
- if ((iscmd(mode, DEL_SPI) || iscmd(mode, GRP_SPI) ||
- (iscmd(mode, FLOW) && !bypass) ||
- iscmd(mode, BINDSA)) && proto != IPPROTO_ESP &&
- proto != IPPROTO_AH && proto != IPPROTO_IPIP)
- {
- fprintf(stderr, "%s: security protocol is none of AH, ESP or IPIP\n",
- argv[0]);
- exit(1);
- }
-
- if ((iscmd(mode, GRP_SPI) || iscmd(mode, BINDSA)) &&
- proto2 != IPPROTO_ESP && proto2 != IPPROTO_AH &&
- proto2 != IPPROTO_IPIP)
- {
- fprintf(stderr, "%s: security protocol2 is none of AH, ESP or IPIP\n",
- argv[0]);
- exit(1);
- }
-
if (!dstset && !iscmd(mode, FLUSH) &&
(!iscmd(mode, FLOW) || (iscmd(mode, FLOW) &&
- (smsg.sadb_msg_type != SADB_X_DELFLOW ||
- ingress))))
+ (smsg.sadb_msg_type != SADB_X_DELFLOW) &&
+ !deny && !bypass && !ipsec)))
{
fprintf(stderr, "%s: no destination address for the SA specified\n",
argv[0]);
exit(1);
}
- if (iscmd(mode, FLOW) && !setmask)
- {
- fprintf(stderr, "%s: no subnets for flow specified\n", argv[0]);
- exit(1);
- }
-
- if (iscmd(mode, FLOW) && !bypass && (sprotocol.sadb_protocol_proto == 0) &&
+ if (iscmd(mode, FLOW) && (sprotocol.sadb_protocol_proto == 0) &&
(odst->sin.sin_port || osrc->sin.sin_port))
{
fprintf(stderr, "%s: no transport protocol supplied with source/destination ports\n", argv[0]);
exit(1);
}
- if ((iscmd(mode, GRP_SPI) || iscmd(mode, BINDSA)) && !dst2set)
- {
- fprintf(stderr, "%s: no destination address2 specified\n", argv[0]);
- exit(1);
- }
-
- if (bypass && ingress)
- {
- fprintf(stderr, "%s: cannot specify \"-bypass\" and \"-ingress\" simultaneously\n", argv[0]);
- exit(1);
- }
-
if ((klen > 2 * 8100) || (alen > 2 * 8100))
{
fprintf(stderr, "%s: key too long\n", argv[0]);
@@ -1366,7 +1216,7 @@ main(int argc, char **argv)
iov[cnt++].iov_len = ROUNDUP(dst->sa.sa_len);
smsg.sadb_msg_len += sad2.sadb_address_len;
- if (src->sa.sa_len)
+ if (sad1.sadb_address_exttype)
{
/* Source address header */
iov[cnt].iov_base = &sad1;
@@ -1420,40 +1270,6 @@ main(int argc, char **argv)
{
switch(mode & CMD_MASK)
{
- case GRP_SPI:
- case BINDSA:
- /* 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;
-
- /* 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;
@@ -1483,7 +1299,7 @@ main(int argc, char **argv)
iov[cnt++].iov_len = ROUNDUP(dst->sa.sa_len);
smsg.sadb_msg_len += sad2.sadb_address_len;
- if (src->sa.sa_len)
+ if (sad1.sadb_address_exttype)
{
/* Source address header */
iov[cnt].iov_base = &sad1;
@@ -1496,7 +1312,8 @@ main(int argc, char **argv)
break;
case FLOW:
- if ((smsg.sadb_msg_type != SADB_X_DELFLOW) || ingress)
+ if ((smsg.sadb_msg_type != SADB_X_DELFLOW) &&
+ (sad2.sadb_address_exttype))
{
/* Destination address header */
iov[cnt].iov_base = &sad2;
@@ -1506,24 +1323,60 @@ main(int argc, char **argv)
iov[cnt++].iov_len = ROUNDUP(dst->sa.sa_len);
smsg.sadb_msg_len += sad2.sadb_address_len;
}
-
- /* SA header */
- iov[cnt].iov_base = &sa;
- iov[cnt++].iov_len = sizeof(sa);
- smsg.sadb_msg_len += sa.sadb_sa_len;
+
+ if (sa.sadb_sa_spi != 0)
+ {
+ /* SA header */
+ iov[cnt].iov_base = &sa;
+ iov[cnt++].iov_len = sizeof(sa);
+ smsg.sadb_msg_len += sa.sadb_sa_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)
{
- /* Protocol2 */
+ /* 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;
+ }
+#ifdef INET6
+ else if (osrc->sa.sa_family == AF_INET6)
+ {
+ osrc->sin6.sin6_port = sport;
+ osmask->sin6.sin6_port = 0xffff;
+ }
+#endif /* INET6 */
+ }
+
iov[cnt].iov_base = &sad4;
iov[cnt++].iov_len = sizeof(sad4);
- /* Flow source addressaddress */
+ /* 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;
@@ -1532,6 +1385,22 @@ main(int argc, char **argv)
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;
+ }
+#ifdef INET6
+ else if (odst->sa.sa_family == AF_INET6)
+ {
+ odst->sin6.sin6_port = dport;
+ odmask->sin6.sin6_port = 0xffff;
+ }
+#endif /* INET6 */
+ }
+
iov[cnt].iov_base = odst;
iov[cnt++].iov_len = ROUNDUP(odst->sa.sa_len);
smsg.sadb_msg_len += sad5.sadb_address_len;
@@ -1554,7 +1423,7 @@ main(int argc, char **argv)
break;
case FLUSH:
- /* No more work needed. */
+ /* No more work needed */
break;
}