summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAngelos D. Keromytis <angelos@cvs.openbsd.org>2000-09-19 03:18:12 +0000
committerAngelos D. Keromytis <angelos@cvs.openbsd.org>2000-09-19 03:18:12 +0000
commit62af38125dfdf39add4e4d088b780b0b0b6bdafa (patch)
tree91a27799b781b87e8b0a47f34918b890eac4a65a
parent069cad44ac518c92a5a6a825e0137a88dc044c29 (diff)
Update to use the new framework.
-rw-r--r--sbin/ipsecadm/ipsecadm.8197
-rw-r--r--sbin/ipsecadm/ipsecadm.c509
2 files changed, 302 insertions, 404 deletions
diff --git a/sbin/ipsecadm/ipsecadm.8 b/sbin/ipsecadm/ipsecadm.8
index 0615163650c..a2a065e6994 100644
--- a/sbin/ipsecadm/ipsecadm.8
+++ b/sbin/ipsecadm/ipsecadm.8
@@ -1,4 +1,4 @@
-.\" $OpenBSD: ipsecadm.8,v 1.26 2000/04/22 01:50:15 angelos Exp $
+.\" $OpenBSD: ipsecadm.8,v 1.27 2000/09/19 03:18:11 angelos Exp $
.\"
.\" Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de>
.\" All rights reserved.
@@ -147,71 +147,97 @@ The specified SA will be deleted.
Allowed modifiers are:
.Fl dst ,
.Fl spi ,
-.Fl proto ,
-and
-.Fl chain .
-.It group
-Group two SAs together.
-Allowed modifiers are:
-.Fl dst ,
-.Fl spi ,
-.Fl proto ,
-.Fl dst2 ,
-.Fl spi2 ,
and
-.Fl proto2 .
+.Fl proto .
.It flow
-Create a flow determining which packets are routed via which Security
-Association, or (for ingress flows) which packets may be received over
-an incoming SA.
+Create a flow determining what security parameters a packet should
+have (input or output).
Allowed modifiers are:
+.Fl src ,
.Fl dst ,
-.Fl spi ,
+.Fl spi ,
.Fl proto ,
.Fl addr ,
.Fl transport ,
.Fl sport ,
.Fl dport ,
.Fl delete ,
-.Fl ingress ,
+.Fl in ,
+.Fl out ,
+.Fl deny ,
+.Fl use ,
+.Fl acquire ,
+.Fl require ,
+.Fl dontacq ,
+.Fl permit ,
and
.Fl bypass .
The
.Xr netstat 1
-command shows the existing egress (outbound) flows.
+command shows all specified flows.
+Flows are directional, and the
+.Fl in
+and
+.Fl out
+modifiers are used to specify the direction.
+By default, flows are assumed to apply to outgoing packets.
+If the
+.Fl spi
+is not specified, the kernel will attempt to find an appropriate
+Security Association from those already present (an SA that matches
+the destination address, if set, and the security protocol).
+If the destination address is set to all zeroes (0.0.0.0) or left
+unspecified, the destination address from the packet will be used
+to locate an SA (the source address is used for incoming flows).
+For incoming flows, the destination address (if specified) should
+point to the expected source of the SA (the remote SA peer).
+If no such SA exists, key management daemons will be used to generate
+them if
+.Fl acquire
+or
+.Fl require
+were used.
+If
+.Fl acquire
+was used, traffic will be allowed out (or in) and IPsec will be used
+when the relevant SAs have been established.
+If
+.Fl require
+was used, traffic will not be allowed in or out until it is protected
+by IPsec.
+If
+.Fl dontacq
+was used, traffic will not be allowed in or out until it is protected
+by IPsec, but key management will not be asked to provide such an SA.
+The
+.Fl proto
+argument (by default set to
+.Nm esp )
+will be used to determine what type of SA should be established.
A
.Nm bypass
+or
+.Nm permit
flow is used to specify a flow for which IPSec processing will be
-bypassed, i.e packets will not be processed by any SAs.
+bypassed, i.e packets will/need not be processed by any SAs.
For
-.Nm bypass
+.Nm permit
flows, additional modifiers are restricted to:
.Fl addr ,
.Fl transport ,
.Fl sport ,
.Fl dport ,
+.Fl in ,
+.Fl out ,
and
.Fl delete .
-These flows always have SPI 0, destination 0.0.0.0 and protocol 0.
-.It bind
-Associate an incoming Security Association with an outgoing Security
-Association.
-When a socket receives packets secured by the incoming SA all
-responses will be processed by the outgoing SA.
-Allowed modifiers are:
-.Fl dst ,
-.Fl spi ,
-.Fl proto ,
-.Fl dst2 ,
-.Fl spi2 ,
-and
-.Fl proto2 .
-The IP address 0.0.0.0 can be used as wildcard for
-.Fl src
-and
-.Fl dst .
-This can be useful while travelling where the IP address of potential
-clients is not known.
+A
+.Nm deny
+flow is used to specify classes of packets that must be dropped
+(either on output or input) without further processing.
+.Nm deny
+takes the same additional modifiers as
+.Nm bypass .
.It flush
Flush SAs from from kernel.
This includes flushing any flows and
@@ -372,11 +398,9 @@ This option causes use of a 4 byte IV in old ESP (as opposed to 8 bytes).
It may only be used with old ESP.
.It Fl proto
The security protocol needed by
-.Nm delspi ,
-.Nm flow ,
-.Nm group
+.Nm delspi
or
-.Nm bind
+.Nm flow ,
to uniquely specify the SA.
The default value is 50 which means
.Nm IPPROTO_ESP .
@@ -386,25 +410,6 @@ and 4
.Nm ( IPPROTO_IP ) .
One can also specify the symbolic names "esp", "ah", and "ip4",
case insensitive.
-.It Fl chain
-Delete the whole SPI chain, otherwise delete only the SPI given.
-.It Fl dst2
-The second IP destination address used by
-.Nm group .
-.It Fl spi2
-The second SPI used by
-.Nm group .
-.It Fl proto2
-The second security protocol used by
-.Nm group .
-It defaults to
-.Nm IPPROTO_AH .
-Other accepted values are 50
-.Nm ( IPPROTO_ESP ) ,
-and 4
-.Nm ( IPPROTO_IP ) .
-One can also specify the symbolic names "esp", "ah", and "ip4",
-case insensitive.
.It Fl addr
The source address, source network mask, destination address and destination
network mask against which packets need to match to use the specified
@@ -432,21 +437,6 @@ Instead of a number, a valid service name that appears in
can be used.
.It Fl delete
Instead of creating a flow, an existing flow is deleted.
-.It Fl ingress
-For
-.Nm flow ,
-create or delete an
-.Nm ingress
-flow.
-An SA's
-.Nm ingress
-flows specify the types of packets that may be accepted over that SA,
-if the sysctl variable
-.Bl -tag -width xxxxxxxxxxxxxxxxxxxxx
-.It net.inet.ip.ipsec-acl
-.El
-.Pp
-is set to any non-zero value.
.It Fl bypass
For
.Nm flow ,
@@ -454,9 +444,48 @@ create or delete a
.Nm bypass
flow.
Packets matching this flow will not be processed by IPSec.
+.It Fl deny
For
-.Nm flush ,
-only flush SAs of type bypass.
+.Nm flow ,
+create or delete a
+.Nm deny
+flow.
+Packets matching this flow will be dropped.
+.It Fl use
+For
+.Nm flow ,
+specify that packets matching this flow should try to use IPsec if
+possible.
+.It Fl acquire
+For
+.Nm flow ,
+specify that packets matching this flow should try to use IPsec and
+establish SAs dynamically if possible, but permit unencrypted
+traffic.
+.It Fl require
+For
+.Nm flow ,
+specify that packets matching this flow must use IPsec, and establish
+SAs dynamically as needed. If no SAs are established, traffic is not
+allowed through.
+.It Fl acquire
+For
+.Nm flow ,
+specify that packets matching this flow must use IPsec.
+If such SAs are not present, simply drop the packets.
+Such a policy may be used to demand peers to establish SAs before they
+can communicate with us, without going through the burden of
+initiating the SA ourselves (thus allowing for some denial of service
+attacks).
+This flow type is particularly suitable for security gateways.
+.It Fl in
+For
+.Nm flow ,
+specify that it should be used to match incoming packets only.
+.It Fl out
+For
+.Nm flow ,
+specify that it should be used to match outgoing packets only.
.It Fl ah
For
.Nm flush ,
@@ -497,7 +526,7 @@ ipsecadm old ah -auth md5 -spi 1001 -dst 169.20.12.2 -src 169.20.12.3 \e\
Setup a flow using the above SA:
.Bd -literal
ipsecadm flow -dst 169.20.12.2 -spi 1001 -proto ah \e\
- -addr 10.1.1.0 255.255.255.0 10.0.0.0 255.0.0.0
+ -addr 10.1.1.0 255.255.255.0 10.0.0.0 255.0.0.0 -out
.Ed
.Pp
Setup an inbound SA:
@@ -511,12 +540,12 @@ ipsecadm new esp -enc blf -auth md5 -spi 1002 -dst 169.20.12.3 \e\
Setup an ingress flow on for the inbound SA:
.Bd -literal
ipsecadm flow -addr 10.0.0.0 255.0.0.0 10.1.1.0 255.255.255.0 \e\
- -dst 10.10.32.1 -spi 1002 -proto esp -ingress
+ -dst 10.10.32.1 -spi 1002 -proto esp -in
.Ed
.Pp
Setup a bypass flow:
.Bd -literal
-ipsecadm flow -bypass \e\
+ipsecadm flow -bypass -out \e\
-addr 10.1.1.0 255.255.255.0 10.1.1.0 255.255.255.0
.Ed
.Pp
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;
}