Index: head/lib/libipsec/Makefile =================================================================== --- head/lib/libipsec/Makefile (revision 62582) +++ head/lib/libipsec/Makefile (revision 62583) @@ -1,54 +1,54 @@ # Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # 3. Neither the name of the project nor the names of its contributors # may be used to endorse or promote products derived from this software # without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # $FreeBSD$ LIB= ipsec -SHLIB_MAJOR= 0 +SHLIB_MAJOR= 1 SHLIB_MINOR= 0 CFLAGS+=-I${.OBJDIR} CFLAGS+=-DIPSEC_DEBUG -DIPSEC .if !defined(NOINET6) CFLAGS+=-DINET6 .endif -.PATH: ${.CURDIR}/../../sys/netkey -SRCS= pfkey.c pfkey_dump.c +#.PATH: ${.CURDIR}/../../sys/netkey +#SRCS= pfkey.c pfkey_dump.c SRCS+= ipsec_strerror.c policy_parse.y policy_token.l SRCS+= ipsec_dump_policy.c ipsec_get_policylen.c -SRCS+= key_debug.c +#SRCS+= key_debug.c CLEANFILES+= y.tab.c y.tab.h YFLAGS+=-d -p __libipsecyy LFLAGS+=-P__libipsecyy MAN3= ipsec_set_policy.3 ipsec_strerror.3 MLINKS+=ipsec_set_policy.3 ipsec_get_policylen.3 \ ipsec_set_policy.3 ipsec_dump_policy.3 SRCS+= y.tab.h y.tab.h: policy_parse.y .include Index: head/lib/libipsec/ipsec_dump_policy.c =================================================================== --- head/lib/libipsec/ipsec_dump_policy.c (revision 62582) +++ head/lib/libipsec/ipsec_dump_policy.c (revision 62583) @@ -1,253 +1,307 @@ +/* $FreeBSD$ */ +/* $KAME: ipsec_dump_policy.c,v 1.11 2000/05/07 05:29:47 itojun Exp $ */ + /* * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #include #include #include #include #include #include #include +#include #include #include #include #include "ipsec_strerror.h" static const char *ipsp_dir_strs[] = { "any", "in", "out", }; static const char *ipsp_policy_strs[] = { "discard", "none", "ipsec", "entrust", "bypass", }; -static int set_addresses __P((char *buf, caddr_t ptr)); +static char *ipsec_dump_ipsecrequest __P((char *, size_t, + struct sadb_x_ipsecrequest *, size_t)); +static int set_addresses __P((char *, size_t, struct sockaddr *, + struct sockaddr *)); +static char *set_address __P((char *, size_t, struct sockaddr *)); /* * policy is sadb_x_policy buffer. * Must call free() later. * When delimiter == NULL, alternatively ' '(space) is applied. */ char * ipsec_dump_policy(policy, delimiter) caddr_t policy; char *delimiter; { struct sadb_x_policy *xpl = (struct sadb_x_policy *)policy; struct sadb_x_ipsecrequest *xisr; - int xtlen, buflen; + size_t off, buflen; char *buf; - int error; + char isrbuf[1024]; + char *newbuf; /* sanity check */ if (policy == NULL) return NULL; if (xpl->sadb_x_policy_exttype != SADB_X_EXT_POLICY) { - ipsec_errcode = EIPSEC_INVAL_EXTTYPE; + __ipsec_errcode = EIPSEC_INVAL_EXTTYPE; return NULL; } /* set delimiter */ if (delimiter == NULL) delimiter = " "; switch (xpl->sadb_x_policy_dir) { case IPSEC_DIR_ANY: case IPSEC_DIR_INBOUND: case IPSEC_DIR_OUTBOUND: break; default: - ipsec_errcode = EIPSEC_INVAL_DIR; + __ipsec_errcode = EIPSEC_INVAL_DIR; return NULL; } switch (xpl->sadb_x_policy_type) { case IPSEC_POLICY_DISCARD: case IPSEC_POLICY_NONE: case IPSEC_POLICY_IPSEC: case IPSEC_POLICY_BYPASS: case IPSEC_POLICY_ENTRUST: break; default: - ipsec_errcode = EIPSEC_INVAL_POLICY; + __ipsec_errcode = EIPSEC_INVAL_POLICY; return NULL; } buflen = strlen(ipsp_dir_strs[xpl->sadb_x_policy_dir]) + 1 /* space */ + strlen(ipsp_policy_strs[xpl->sadb_x_policy_type]) + 1; /* NUL */ if ((buf = malloc(buflen)) == NULL) { - ipsec_errcode = EIPSEC_NO_BUFS; + __ipsec_errcode = EIPSEC_NO_BUFS; return NULL; } - strcpy(buf, ipsp_dir_strs[xpl->sadb_x_policy_dir]); - strcat(buf, " "); - strcat(buf, ipsp_policy_strs[xpl->sadb_x_policy_type]); + snprintf(buf, buflen, "%s %s", ipsp_dir_strs[xpl->sadb_x_policy_dir], + ipsp_policy_strs[xpl->sadb_x_policy_type]); if (xpl->sadb_x_policy_type != IPSEC_POLICY_IPSEC) { - ipsec_errcode = EIPSEC_NO_ERROR; + __ipsec_errcode = EIPSEC_NO_ERROR; return buf; } - xtlen = PFKEY_EXTLEN(xpl) - sizeof(*xpl); - xisr = (struct sadb_x_ipsecrequest *)(xpl + 1); - /* count length of buffer for use */ - /* XXX non-seriously */ - while (xtlen > 0) { - buflen += 20; - if (xisr->sadb_x_ipsecrequest_mode ==IPSEC_MODE_TUNNEL) - buflen += 50; - xtlen -= xisr->sadb_x_ipsecrequest_len; - xisr = (struct sadb_x_ipsecrequest *)((caddr_t)xisr - + xisr->sadb_x_ipsecrequest_len); + off = sizeof(*xpl); + while (off < PFKEY_EXTLEN(xpl)) { + xisr = (struct sadb_x_ipsecrequest *)((caddr_t)xpl + off); + off += xisr->sadb_x_ipsecrequest_len; } /* validity check */ - if (xtlen < 0) { - ipsec_errcode = EIPSEC_INVAL_SADBMSG; + if (off != PFKEY_EXTLEN(xpl)) { + __ipsec_errcode = EIPSEC_INVAL_SADBMSG; free(buf); return NULL; } - if ((buf = realloc(buf, buflen)) == NULL) { - ipsec_errcode = EIPSEC_NO_BUFS; - return NULL; - } + off = sizeof(*xpl); + while (off < PFKEY_EXTLEN(xpl)) { + xisr = (struct sadb_x_ipsecrequest *)((caddr_t)xpl + off); - xtlen = PFKEY_EXTLEN(xpl) - sizeof(*xpl); - xisr = (struct sadb_x_ipsecrequest *)(xpl + 1); - - while (xtlen > 0) { - strcat(buf, delimiter); - - switch (xisr->sadb_x_ipsecrequest_proto) { - case IPPROTO_ESP: - strcat(buf, "esp"); - break; - case IPPROTO_AH: - strcat(buf, "ah"); - break; - case IPPROTO_IPCOMP: - strcat(buf, "ipcomp"); - break; - default: - ipsec_errcode = EIPSEC_INVAL_PROTO; + if (ipsec_dump_ipsecrequest(isrbuf, sizeof(isrbuf), xisr, + PFKEY_EXTLEN(xpl) - off) == NULL) { free(buf); return NULL; } - strcat(buf, "/"); - - switch (xisr->sadb_x_ipsecrequest_mode) { - case IPSEC_MODE_ANY: - strcat(buf, "any"); - break; - case IPSEC_MODE_TRANSPORT: - strcat(buf, "transport"); - break; - case IPSEC_MODE_TUNNEL: - strcat(buf, "tunnel"); - break; - default: - ipsec_errcode = EIPSEC_INVAL_MODE; + buflen = strlen(buf) + strlen(delimiter) + strlen(isrbuf) + 1; + newbuf = (char *)realloc(buf, buflen); + if (newbuf == NULL) { + __ipsec_errcode = EIPSEC_NO_BUFS; free(buf); return NULL; } + buf = newbuf; + snprintf(buf, buflen, "%s%s%s", buf, delimiter, isrbuf); - strcat(buf, "/"); + off += xisr->sadb_x_ipsecrequest_len; + } - if (xisr->sadb_x_ipsecrequest_len > sizeof(*xisr)) { - error = set_addresses(buf, (caddr_t)(xisr + 1)); - if (error) { - ipsec_errcode = EIPSEC_INVAL_MODE; - free(buf); - return NULL; - } - } + __ipsec_errcode = EIPSEC_NO_ERROR; + return buf; +} - switch (xisr->sadb_x_ipsecrequest_level) { - case IPSEC_LEVEL_DEFAULT: - strcat(buf, "/default"); - break; - case IPSEC_LEVEL_USE: - strcat(buf, "/use"); - break; - case IPSEC_LEVEL_REQUIRE: - strcat(buf, "/require"); - break; - case IPSEC_LEVEL_UNIQUE: - strcat(buf, "/unique"); - break; - default: - ipsec_errcode = EIPSEC_INVAL_LEVEL; - free(buf); +static char * +ipsec_dump_ipsecrequest(buf, len, xisr, bound) + char *buf; + size_t len; + struct sadb_x_ipsecrequest *xisr; + size_t bound; /* boundary */ +{ + const char *proto, *mode, *level; + char abuf[NI_MAXHOST * 2 + 2]; + + if (xisr->sadb_x_ipsecrequest_len > bound) { + __ipsec_errcode = EIPSEC_INVAL_PROTO; + return NULL; + } + + switch (xisr->sadb_x_ipsecrequest_proto) { + case IPPROTO_ESP: + proto = "esp"; + break; + case IPPROTO_AH: + proto = "ah"; + break; + case IPPROTO_IPCOMP: + proto = "ipcomp"; + break; + default: + __ipsec_errcode = EIPSEC_INVAL_PROTO; + return NULL; + } + + switch (xisr->sadb_x_ipsecrequest_mode) { + case IPSEC_MODE_ANY: + mode = "any"; + break; + case IPSEC_MODE_TRANSPORT: + mode = "transport"; + break; + case IPSEC_MODE_TUNNEL: + mode = "tunnel"; + break; + default: + __ipsec_errcode = EIPSEC_INVAL_MODE; + return NULL; + } + + abuf[0] = '\0'; + if (xisr->sadb_x_ipsecrequest_len > sizeof(*xisr)) { + struct sockaddr *sa1, *sa2; + caddr_t p; + + p = (caddr_t)(xisr + 1); + sa1 = (struct sockaddr *)p; + sa2 = (struct sockaddr *)(p + sa1->sa_len); + if (sizeof(*xisr) + sa1->sa_len + sa2->sa_len != + xisr->sadb_x_ipsecrequest_len) { + __ipsec_errcode = EIPSEC_INVAL_ADDRESS; return NULL; } + if (set_addresses(abuf, sizeof(abuf), sa1, sa2) != 0) { + __ipsec_errcode = EIPSEC_INVAL_ADDRESS; + return NULL; + } + } - xtlen -= xisr->sadb_x_ipsecrequest_len; - xisr = (struct sadb_x_ipsecrequest *)((caddr_t)xisr - + xisr->sadb_x_ipsecrequest_len); + switch (xisr->sadb_x_ipsecrequest_level) { + case IPSEC_LEVEL_DEFAULT: + level = "default"; + break; + case IPSEC_LEVEL_USE: + level = "use"; + break; + case IPSEC_LEVEL_REQUIRE: + level = "require"; + break; + case IPSEC_LEVEL_UNIQUE: + level = "unique"; + break; + default: + __ipsec_errcode = EIPSEC_INVAL_LEVEL; + return NULL; } - ipsec_errcode = EIPSEC_NO_ERROR; + if (xisr->sadb_x_ipsecrequest_reqid == 0) + snprintf(buf, len, "%s/%s/%s/%s", proto, mode, abuf, level); + else { + int ch; + + if (xisr->sadb_x_ipsecrequest_reqid > IPSEC_MANUAL_REQID_MAX) + ch = '#'; + else + ch = ':'; + snprintf(buf, len, "%s/%s/%s/%s%c%d", proto, mode, abuf, level, + ch, xisr->sadb_x_ipsecrequest_reqid); + } + return buf; } static int -set_addresses(buf, ptr) +set_addresses(buf, len, sa1, sa2) char *buf; - caddr_t ptr; + size_t len; + struct sockaddr *sa1; + struct sockaddr *sa2; { - char tmp[100]; /* XXX */ - struct sockaddr *saddr = (struct sockaddr *)ptr; + char tmp1[NI_MAXHOST], tmp2[NI_MAXHOST]; - getnameinfo(saddr, saddr->sa_len, tmp, sizeof(tmp), - NULL, 0, NI_NUMERICHOST); + if (set_address(tmp1, sizeof(tmp1), sa1) == NULL || + set_address(tmp2, sizeof(tmp2), sa2) == NULL) + return -1; + if (strlen(tmp1) + 1 + strlen(tmp2) + 1 > len) + return -1; + snprintf(buf, len, "%s-%s", tmp1, tmp2); + return 0; +} - strcat(buf, tmp); +static char * +set_address(buf, len, sa) + char *buf; + size_t len; + struct sockaddr *sa; +{ +#ifdef NI_WITHSCOPEID + const int niflags = NI_NUMERICHOST | NI_WITHSCOPEID; +#else + const int niflags = NI_NUMERICHOST; +#endif - strcat(buf, "-"); - - saddr = (struct sockaddr *)((caddr_t)saddr + saddr->sa_len); - getnameinfo(saddr, saddr->sa_len, tmp, sizeof(tmp), - NULL, 0, NI_NUMERICHOST); - - strcat(buf, tmp); - - return 0; + if (len < 1) + return NULL; + buf[0] = '\0'; + if (getnameinfo(sa, sa->sa_len, buf, len, NULL, 0, niflags) != 0) + return NULL; + return buf; } Index: head/lib/libipsec/ipsec_get_policylen.c =================================================================== --- head/lib/libipsec/ipsec_get_policylen.c (revision 62582) +++ head/lib/libipsec/ipsec_get_policylen.c (revision 62583) @@ -1,44 +1,47 @@ +/* $FreeBSD$ */ +/* $KAME: ipsec_get_policylen.c,v 1.5 2000/05/07 05:25:03 itojun Exp $ */ + /* * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #include #include + +#include #include #include "ipsec_strerror.h" int ipsec_get_policylen(policy) caddr_t policy; { return policy ? PFKEY_EXTLEN(policy) : -1; } Index: head/lib/libipsec/ipsec_set_policy.3 =================================================================== --- head/lib/libipsec/ipsec_set_policy.3 (revision 62582) +++ head/lib/libipsec/ipsec_set_policy.3 (revision 62583) @@ -1,248 +1,257 @@ .\" Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. +.\" $FreeBSD$ +.\" $KAME: ipsec_set_policy.3,v 1.10 2000/05/07 05:25:03 itojun Exp $ +.\" .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" 3. Neither the name of the project nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. .\" .\" THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE .\" ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $Id: ipsec_set_policy.3,v 1.5 1999/10/20 00:21:06 sakane Exp $ -.\" $FreeBSD$ -.\" .Dd May 5, 1998 .Dt IPSEC_SET_POLICY 3 .Os .Sh NAME .Nm ipsec_set_policy , .Nm ipsec_get_policylen , .Nm ipsec_dump_policy .Nd manipulate IPsec policy specification structure from readable string +.\" .Sh LIBRARY .Lb libipsec .Sh SYNOPSIS -.Fd #include .Fd #include .Ft "char *" .Fn ipsec_set_policy "char *policy" "int len" .Ft int .Fn ipsec_get_policylen "char *buf" .Ft "char *" .Fn ipsec_dump_policy "char *buf" "char *delim" .Sh DESCRIPTION .Fn ipsec_set_policy generates IPsec policy specification structure, namely .Li struct sadb_x_policy and/or .Li struct sadb_x_ipsecrequest from human-readable policy specification. policy specification must be given as C string .Fa policy and length .Fa len of .Fa policy . .Fn ipsec_set_policy will return the buffer of IPsec policy specification structure. .Pp You may want the length of the generated buffer such when calling .Xr setsockopt 2 . .Fn ipsec_get_policylen will return the length. .Pp .Fn ipsec_dump_policy converts IPsec policy structure into readable form. Therefore, .Fn ipsec_dump_policy can be regarded as inverse conversion of .Fn ipsec_set_policy . .Fa buf points to a IPsec policy structure, .Li struct sadb_x_policy . .Fa delim is a delimiter string, which is usually a blank character. If you set .Fa delim to .Dv NULL , single whitespace is assumed. .Fn ipsec_dump_policy returns pointer to dynamically allocated string. It is caller's responsibility to reclaim the region, by using .Xr free 3 . .Pp .Fa policy is formatted as either of the following: .Bl -tag -width "discard" .It Ar direction Li entrust .Ar direction must be .Li in or .Li out . .Ar direction specifies which direction the policy needs to be applied. .Li entrust means to consult to SPD defined by .Xr setkey 8 . .It Ar direction Li bypass .Li bypass means to be bypassed the IPsec processing. .Pq packet will be transmitted in clear . This is for privileged socket. .It Xo .Ar direction .Li ipsec .Ar request ... .Xc .Li ipsec means that the matching packets are subject to IPsec processing. .Li ipsec can be followed by one or more .Ar request string, which is formatted as below: .Bl -tag -width "discard" .It Xo .Ar protocol .Li / .Ar mode .Li / .Ar src .Li - .Ar dst .Op Ar /level .Xc .Ar protocol is either .Li ah , .Li esp or .Li ipcomp . .Pp .Ar mode is either .Li transport or .Li tunnel . .Pp .Ar src and .Ar dst specifies IPsec endpoint. .Ar src always means .Dq sending node and .Ar dst always means .Dq receiving node . Therefore, when .Ar direction is .Li in , .Ar dst is this node and .Ar src is the other node .Pq peer . .Pp .Ar level must be set to one of the following: -.Li default , use +.Li default , use , require or -.Li require . +.Li unique . .Li default means that the kernel should consult the system default policy defined by .Xr sysctl 8 , such as .Li net.inet.ipsec.esp_trans_deflev . See .Xr ipsec 4 regarding the system default. .Li use means that a relevant SA can be used when available, since the kernel may perform IPsec operation against packets when possible. In this case, packets can be transmitted in clear .Pq when SA is not available , or encrypted .Pq when SA is available . .Li require means that a relevant SA is required, since the kernel must perform IPsec operation against packets. +.Li unique +is the same as +.Li require , +but adds the restriction that the SA for outbound traffic is used +only for this policy. +You may need the identifier in order to relate the policy and the SA +when you define the SA by manual keying. +You can put the decimal number as the identifier after +.Li unique +like +.Li unique : number . +.Li number +must be between 1 and 32767 . If the .Ar request string is kept unambiguous, .Ar level and slash prior to .Ar level can be omitted. However, it is encouraged to specify them explicitly to avoid unintended behaviors. If .Ar level is omitted, it will be interpreted as .Li default . .El .El .Pp Note that there is a bit difference of specification from .Xr setkey 8 . In specification by .Xr setkey 8 , both entrust and bypass are not used. Refer to .Xr setkey 8 for detail. .Pp Here are several examples .Pq long lines are wrapped for readability : .Bd -literal -offset indent in discard out ipsec esp/transport/10.1.1.1-10.1.1.2/require in ipsec ah/transport/10.1.1.2-10.1.1.1/require -in ipsec esp/transport/10.1.1.2-10.1.1.1/use - ah/tunnel/10.1.1.2-10.1.1.1/require +out ipsec esp/transport/10.1.1.2-10.1.1.1/use + ah/tunnel/10.1.1.2-10.1.1.1/unique:1000 in ipsec ipcomp/transport/10.1.1.2-10.1.1.1/use esp/transport/10.1.1.2-10.1.1.1/use .Ed .Sh RETURN VALUES .Fn ipsec_set_policy returns a pointer to the allocated buffer of policy specification if successful; otherwise a NULL pointer is returned. .Fn ipsec_get_policylen returns with positive value .Pq meaning the buffer size on success, and negative value on errors. .Fn ipsec_dump_policy returns a pointer to dynamically allocated region on success, and .Dv NULL on errors. .Sh SEE ALSO .Xr ipsec_strerror 3 , -.Xr ipsec 4 , +.Xr ispec 4 , .Xr setkey 8 .Sh HISTORY The functions first appeared in WIDE/KAME IPv6 protocol stack kit. -.Pp -IPv6 and IPsec support based on the KAME Project (http://www.kame.net/) stack -was initially integrated into -.Fx 4.0 Index: head/lib/libipsec/ipsec_strerror.3 =================================================================== --- head/lib/libipsec/ipsec_strerror.3 (revision 62582) +++ head/lib/libipsec/ipsec_strerror.3 (revision 62583) @@ -1,66 +1,80 @@ .\" Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. +.\" $FreeBSD$ +.\" $KAME: ipsec_strerror.3,v 1.6 2000/05/07 05:25:03 itojun Exp $ +.\" .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" 3. Neither the name of the project nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. .\" .\" THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE .\" ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $Id: ipsec_strerror.3,v 1.2 1999/09/21 03:49:19 itojun Exp $ -.\" $FreeBSD$ -.\" .Dd May 6, 1998 .Dt IPSEC_STRERROR 3 .Os +.\" .Sh NAME .Nm ipsec_strerror .Nd error code for IPsec policy manipulation library -.Sh LIBRARY -.Lb libipsec +.\" .Sh SYNOPSIS -.Fd #include .Fd #include .Ft "char *" -.Fn ipsec_strerror void +.Fn ipsec_strerror +.\" .Sh DESCRIPTION .Pa netinet6/ipsec.h declares .Pp .Dl extern int ipsec_errcode; .Pp which is used to pass error code from IPsec policy manipulation library to user program. .Fn ipsec_strerror can be used to obtain error message string for the error code. +.Pp +The array pointed to is not to be modified by the program. +Since +.Fn ipsec_strerror +uses +.Xr strerror 3 +as underlying function, calling +.Xr strerror 3 +after +.Fn ipsec_strerror +would make the return value from +.Fn ipsec_strerror +invalid, or overwritten. +.\" .Sh RETURN VALUES .Fn ipsec_strerror always return a pointer to C string. The C string must not be overwritten by user programs. .\" -.\" .Sh SEE ALSO +.Sh SEE ALSO +.Xr ipsec_set_policy 3 .\" .Sh HISTORY The functions first appeared in WIDE/KAME IPv6 protocol stack kit. -.Pp -IPv6 and IPsec support based on the KAME Project (http://www.kame.net/) stack -was initially integrated into -.Fx 4.0 +.\" +.\" .Sh BUGS +.\" (to be written) Index: head/lib/libipsec/ipsec_strerror.c =================================================================== --- head/lib/libipsec/ipsec_strerror.c (revision 62582) +++ head/lib/libipsec/ipsec_strerror.c (revision 62583) @@ -1,87 +1,88 @@ +/* $FreeBSD$ */ +/* $KAME: ipsec_strerror.c,v 1.6 2000/05/07 05:25:03 itojun Exp $ */ + /* * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #include #include #include #include #include "ipsec_strerror.h" -int ipsec_errcode; +int __ipsec_errcode; static char *ipsec_errlist[] = { "Success", /*EIPSEC_NO_ERROR*/ "Not supported", /*EIPSEC_NOT_SUPPORTED*/ "Invalid argument", /*EIPSEC_INVAL_ARGUMENT*/ "Invalid sadb message", /*EIPSEC_INVAL_SADBMSG*/ "Invalid version", /*EIPSEC_INVAL_VERSION*/ "Invalid security policy", /*EIPSEC_INVAL_POLICY*/ "Invalid address specification", /*EIPSEC_INVAL_ADDRESS*/ "Invalid ipsec protocol", /*EIPSEC_INVAL_PROTO*/ "Invalid ipsec mode", /*EIPSEC_INVAL_MODE*/ "Invalid ipsec level", /*EIPSEC_INVAL_LEVEL*/ "Invalid SA type", /*EIPSEC_INVAL_SATYPE*/ "Invalid message type", /*EIPSEC_INVAL_MSGTYPE*/ "Invalid extension type", /*EIPSEC_INVAL_EXTTYPE*/ "Invalid algorithm type", /*EIPSEC_INVAL_ALGS*/ "Invalid key length", /*EIPSEC_INVAL_KEYLEN*/ "Invalid address family", /*EIPSEC_INVAL_FAMILY*/ "Invalid prefix length", /*EIPSEC_INVAL_PREFIXLEN*/ "Invalid direciton", /*EIPSEC_INVAL_DIR*/ "SPI range violation", /*EIPSEC_INVAL_SPI*/ "No protocol specified", /*EIPSEC_NO_PROTO*/ "No algorithm specified", /*EIPSEC_NO_ALGS*/ "No buffers available", /*EIPSEC_NO_BUFS*/ "Must get supported algorithms list first", /*EIPSEC_DO_GET_SUPP_LIST*/ "Protocol mismatch", /*EIPSEC_PROTO_MISMATCH*/ "Family mismatch", /*EIPSEC_FAMILY_MISMATCH*/ "Too few arguments", /*EIPSEC_FEW_ARGUMENTS*/ NULL, /*EIPSEC_SYSTEM_ERROR*/ "Unknown error", /*EIPSEC_MAX*/ }; char *ipsec_strerror(void) { - if (ipsec_errcode < 0 || ipsec_errcode > EIPSEC_MAX) - ipsec_errcode = EIPSEC_MAX; + if (__ipsec_errcode < 0 || __ipsec_errcode > EIPSEC_MAX) + __ipsec_errcode = EIPSEC_MAX; - return ipsec_errlist[ipsec_errcode]; + return ipsec_errlist[__ipsec_errcode]; } -void ipsec_set_strerror(char *str) +void __ipsec_set_strerror(char *str) { - ipsec_errcode = EIPSEC_SYSTEM_ERROR; + __ipsec_errcode = EIPSEC_SYSTEM_ERROR; ipsec_errlist[EIPSEC_SYSTEM_ERROR] = str; return; } Index: head/lib/libipsec/ipsec_strerror.h =================================================================== --- head/lib/libipsec/ipsec_strerror.h (revision 62582) +++ head/lib/libipsec/ipsec_strerror.h (revision 62583) @@ -1,62 +1,63 @@ +/* $FreeBSD$ */ +/* $KAME: ipsec_strerror.h,v 1.7 2000/05/07 05:25:03 itojun Exp $ */ + /* * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ -extern int ipsec_errcode; -extern void ipsec_set_strerror(char *str); +extern int __ipsec_errcode; +extern void __ipsec_set_strerror __P((char *)); -#define EIPSEC_NO_ERROR 0 /*success*/ -#define EIPSEC_NOT_SUPPORTED 1 /*not supported*/ -#define EIPSEC_INVAL_ARGUMENT 2 /*invalid argument*/ -#define EIPSEC_INVAL_SADBMSG 3 /*invalid sadb message*/ -#define EIPSEC_INVAL_VERSION 4 /*invalid version*/ -#define EIPSEC_INVAL_POLICY 5 /*invalid security policy*/ -#define EIPSEC_INVAL_ADDRESS 6 /*invalid address specification*/ -#define EIPSEC_INVAL_PROTO 7 /*invalid ipsec protocol*/ -#define EIPSEC_INVAL_MODE 8 /*Invalid ipsec mode*/ -#define EIPSEC_INVAL_LEVEL 9 /*invalid ipsec level*/ -#define EIPSEC_INVAL_SATYPE 10 /*invalid SA type*/ -#define EIPSEC_INVAL_MSGTYPE 11 /*invalid message type*/ -#define EIPSEC_INVAL_EXTTYPE 12 /*invalid extension type*/ -#define EIPSEC_INVAL_ALGS 13 /*Invalid algorithm type*/ -#define EIPSEC_INVAL_KEYLEN 14 /*invalid key length*/ -#define EIPSEC_INVAL_FAMILY 15 /*invalid address family*/ -#define EIPSEC_INVAL_PREFIXLEN 16 /*SPI range violation*/ -#define EIPSEC_INVAL_DIR 17 /*Invalid direciton*/ -#define EIPSEC_INVAL_SPI 18 /*invalid prefixlen*/ -#define EIPSEC_NO_PROTO 19 /*no protocol specified*/ -#define EIPSEC_NO_ALGS 20 /*No algorithm specified*/ -#define EIPSEC_NO_BUFS 21 /*no buffers available*/ -#define EIPSEC_DO_GET_SUPP_LIST 22 /*must get supported algorithm first*/ -#define EIPSEC_PROTO_MISMATCH 23 /*protocol mismatch*/ -#define EIPSEC_FAMILY_MISMATCH 24 /*family mismatch*/ -#define EIPSEC_FEW_ARGUMENTS 25 /*Too few arguments*/ -#define EIPSEC_SYSTEM_ERROR 26 /*system error*/ -#define EIPSEC_MAX 27 /*unknown error*/ +#define EIPSEC_NO_ERROR 0 /*success*/ +#define EIPSEC_NOT_SUPPORTED 1 /*not supported*/ +#define EIPSEC_INVAL_ARGUMENT 2 /*invalid argument*/ +#define EIPSEC_INVAL_SADBMSG 3 /*invalid sadb message*/ +#define EIPSEC_INVAL_VERSION 4 /*invalid version*/ +#define EIPSEC_INVAL_POLICY 5 /*invalid security policy*/ +#define EIPSEC_INVAL_ADDRESS 6 /*invalid address specification*/ +#define EIPSEC_INVAL_PROTO 7 /*invalid ipsec protocol*/ +#define EIPSEC_INVAL_MODE 8 /*Invalid ipsec mode*/ +#define EIPSEC_INVAL_LEVEL 9 /*invalid ipsec level*/ +#define EIPSEC_INVAL_SATYPE 10 /*invalid SA type*/ +#define EIPSEC_INVAL_MSGTYPE 11 /*invalid message type*/ +#define EIPSEC_INVAL_EXTTYPE 12 /*invalid extension type*/ +#define EIPSEC_INVAL_ALGS 13 /*Invalid algorithm type*/ +#define EIPSEC_INVAL_KEYLEN 14 /*invalid key length*/ +#define EIPSEC_INVAL_FAMILY 15 /*invalid address family*/ +#define EIPSEC_INVAL_PREFIXLEN 16 /*SPI range violation*/ +#define EIPSEC_INVAL_DIR 17 /*Invalid direciton*/ +#define EIPSEC_INVAL_SPI 18 /*invalid prefixlen*/ +#define EIPSEC_NO_PROTO 19 /*no protocol specified*/ +#define EIPSEC_NO_ALGS 20 /*No algorithm specified*/ +#define EIPSEC_NO_BUFS 21 /*no buffers available*/ +#define EIPSEC_DO_GET_SUPP_LIST 22 /*must get supported algorithm first*/ +#define EIPSEC_PROTO_MISMATCH 23 /*protocol mismatch*/ +#define EIPSEC_FAMILY_MISMATCH 24 /*family mismatch*/ +#define EIPSEC_FEW_ARGUMENTS 25 /*Too few arguments*/ +#define EIPSEC_SYSTEM_ERROR 26 /*system error*/ +#define EIPSEC_MAX 27 /*unknown error*/ Index: head/lib/libipsec/libpfkey.h =================================================================== --- head/lib/libipsec/libpfkey.h (nonexistent) +++ head/lib/libipsec/libpfkey.h (revision 62583) @@ -0,0 +1,77 @@ +/* $FreeBSD$ */ +/* $KAME: libpfkey.h,v 1.1 2000/06/08 21:28:32 itojun Exp $ */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +extern void pfkey_sadump __P((struct sadb_msg *)); +extern void pfkey_spdump __P((struct sadb_msg *)); + +struct sockaddr; +int ipsec_check_keylen __P((u_int, u_int, u_int)); +u_int pfkey_set_softrate __P((u_int, u_int)); +u_int pfkey_get_softrate __P((u_int)); +int pfkey_send_getspi __P((int, u_int, u_int, struct sockaddr *, + struct sockaddr *, u_int32_t, u_int32_t, u_int32_t, u_int32_t)); +int pfkey_send_update __P((int, u_int, u_int, struct sockaddr *, + struct sockaddr *, u_int32_t, u_int32_t, u_int, + caddr_t, u_int, u_int, u_int, u_int, u_int, u_int32_t, u_int64_t, + u_int64_t, u_int64_t, u_int32_t)); +int pfkey_send_add __P((int, u_int, u_int, struct sockaddr *, + struct sockaddr *, u_int32_t, u_int32_t, u_int, + caddr_t, u_int, u_int, u_int, u_int, u_int, u_int32_t, u_int64_t, + u_int64_t, u_int64_t, u_int32_t)); +int pfkey_send_delete __P((int, u_int, u_int, + struct sockaddr *, struct sockaddr *, u_int32_t)); +int pfkey_send_get __P((int, u_int, u_int, + struct sockaddr *, struct sockaddr *, u_int32_t)); +int pfkey_send_register __P((int, u_int)); +int pfkey_recv_register __P((int)); +int pfkey_send_flush __P((int, u_int)); +int pfkey_send_dump __P((int, u_int)); +int pfkey_send_promisc_toggle __P((int, int)); +int pfkey_send_spdadd __P((int, struct sockaddr *, u_int, + struct sockaddr *, u_int, u_int, caddr_t, int, u_int32_t)); +int pfkey_send_spdupdate __P((int, struct sockaddr *, u_int, + struct sockaddr *, u_int, u_int, caddr_t, int, u_int32_t)); +int pfkey_send_spddelete __P((int, struct sockaddr *, u_int, + struct sockaddr *, u_int, u_int, caddr_t, int, u_int32_t)); +int pfkey_send_spddelete2 __P((int, u_int32_t)); +int pfkey_send_spdget __P((int, u_int32_t)); +int pfkey_send_spdsetidx __P((int, struct sockaddr *, u_int, + struct sockaddr *, u_int, u_int, caddr_t, int, u_int32_t)); +int pfkey_send_spdflush __P((int)); +int pfkey_send_spddump __P((int)); + +int pfkey_open __P((void)); +void pfkey_close __P((int)); +struct sadb_msg *pfkey_recv __P((int)); +int pfkey_send __P((int, struct sadb_msg *, int)); +int pfkey_align __P((struct sadb_msg *, caddr_t *)); +int pfkey_check __P((caddr_t *)); Property changes on: head/lib/libipsec/libpfkey.h ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Index: head/lib/libipsec/pfkey.c =================================================================== --- head/lib/libipsec/pfkey.c (revision 62582) +++ head/lib/libipsec/pfkey.c (revision 62583) @@ -1,1421 +1,1595 @@ +/* $FreeBSD$ */ +/* $KAME: pfkey.c,v 1.31 2000/06/10 14:17:43 sakane Exp $ */ + /* * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ -#ifndef lint -static char *rcsid = "@(#) pfkey.c $Revision: 1.10 $"; -#endif - #include #include #include #include #include #include -#include #include #include #include #include #include #include "ipsec_strerror.h" +#include "libpfkey.h" -#define CALLOC(size, cast) (cast)calloc(1, (size)) +#define CALLOC(size, cast) (cast)calloc(1, (size)) -static int pfkey_send_x1 __P((int so, u_int type, u_int satype, u_int mode, - struct sockaddr *src, struct sockaddr *dst, u_int32_t spi, u_int wsize, - caddr_t keymat, - u_int e_type, u_int e_keylen, u_int a_type, u_int a_keylen, - u_int flags, - u_int32_t l_alloc, u_int32_t l_bytes, - u_int32_t l_addtime, u_int32_t l_usetime, u_int32_t seq)); -static int pfkey_send_x2 __P((int so, u_int type, u_int satype, u_int mode, - struct sockaddr *src, struct sockaddr *dst, u_int32_t spi)); -static int pfkey_send_x3 __P((int so, u_int type, u_int satype)); +static int pfkey_send_x1 __P((int, u_int, u_int, u_int, struct sockaddr *, + struct sockaddr *, u_int32_t, u_int32_t, u_int, caddr_t, + u_int, u_int, u_int, u_int, u_int, u_int32_t, u_int32_t, + u_int32_t, u_int32_t, u_int32_t)); +static int pfkey_send_x2 __P((int, u_int, u_int, u_int, + struct sockaddr *, struct sockaddr *, u_int32_t)); +static int pfkey_send_x3 __P((int, u_int, u_int)); +static int pfkey_send_x4 __P((int, u_int, struct sockaddr *, u_int, + struct sockaddr *, u_int, u_int, char *, int, u_int32_t)); +static int pfkey_send_x5 __P((int, u_int, u_int32_t)); -static caddr_t pfkey_setsadbmsg __P((caddr_t buf, u_int type, u_int tlen, - u_int satype, u_int mode, u_int32_t seq, pid_t pid)); -static caddr_t pfkey_setsadbsa __P((caddr_t buf, u_int32_t spi, u_int wsize, - u_int auth, u_int enc, u_int32_t flags)); -static caddr_t pfkey_setsadbaddr __P((caddr_t buf, u_int exttype, - struct sockaddr *saddr, u_int prefixlen, u_int ul_proto)); -static caddr_t pfkey_setsadbkey(caddr_t buf, u_int type, - caddr_t key, u_int keylen); -static caddr_t pfkey_setsadblifetime(caddr_t buf, u_int type, - u_int32_t l_alloc, u_int32_t l_bytes, - u_int32_t l_addtime, u_int32_t l_usetime); +static caddr_t pfkey_setsadbmsg __P((caddr_t, u_int, u_int, + u_int, u_int32_t, pid_t)); +static caddr_t pfkey_setsadbsa __P((caddr_t, u_int32_t, u_int, + u_int, u_int, u_int32_t)); +static caddr_t pfkey_setsadbaddr __P((caddr_t, u_int, + struct sockaddr *, u_int, u_int)); +static caddr_t pfkey_setsadbkey __P((caddr_t, u_int, caddr_t, u_int)); +static caddr_t pfkey_setsadblifetime __P((caddr_t, u_int, u_int32_t, u_int32_t, + u_int32_t, u_int32_t)); +static caddr_t pfkey_setsadbxsa2 __P((caddr_t, u_int32_t, u_int32_t)); /* * check key length against algorithm specified. * supported is either SADB_EXT_SUPPORTED_ENCRYPT or SADB_EXT_SUPPORTED_AUTH. * Refer to keyv2.h to get more info. * keylen is the unit of bit. * OUT: * -1: invalid. * 0: valid. */ struct sadb_msg *ipsec_supported = NULL; int ipsec_check_keylen(supported, alg_id, keylen) u_int supported; u_int alg_id; u_int keylen; { u_int tlen; caddr_t p; struct sadb_supported *sup; struct sadb_alg *alg; /* validity check */ if (ipsec_supported == NULL) { - ipsec_errcode = EIPSEC_DO_GET_SUPP_LIST; + __ipsec_errcode = EIPSEC_DO_GET_SUPP_LIST; return -1; } switch (supported) { case SADB_EXT_SUPPORTED_AUTH: case SADB_EXT_SUPPORTED_ENCRYPT: break; default: - ipsec_errcode = EIPSEC_INVAL_ARGUMENT; + __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; return -1; } tlen = ipsec_supported->sadb_msg_len - sizeof(struct sadb_msg); p = (caddr_t)ipsec_supported + sizeof(struct sadb_msg); for (; tlen > 0; tlen -= sup->sadb_supported_len, p += sup->sadb_supported_len) { sup = (struct sadb_supported *)p; if (sup->sadb_supported_exttype != supported) continue; { u_int ttlen = sup->sadb_supported_len; caddr_t pp = p + sizeof(*sup); for (; ttlen > 0; ttlen -= sizeof(*alg), pp += sizeof(*alg)) { alg = (struct sadb_alg *)pp; if (alg->sadb_alg_id == alg_id) goto found; } } } - ipsec_errcode = EIPSEC_NOT_SUPPORTED; + __ipsec_errcode = EIPSEC_NOT_SUPPORTED; return -1; /* NOTREACHED */ found: if (keylen < alg->sadb_alg_minbits || keylen > alg->sadb_alg_maxbits) { - ipsec_errcode = EIPSEC_INVAL_KEYLEN; + __ipsec_errcode = EIPSEC_INVAL_KEYLEN; return -1; } - ipsec_errcode = EIPSEC_NO_ERROR; + __ipsec_errcode = EIPSEC_NO_ERROR; return 0; } /* * set the rate for SOFT lifetime against HARD one. * If rate is more than 100 or equal to zero, then set to 100. */ static u_int soft_lifetime_allocations_rate = PFKEY_SOFT_LIFETIME_RATE; static u_int soft_lifetime_bytes_rate = PFKEY_SOFT_LIFETIME_RATE; static u_int soft_lifetime_addtime_rate = PFKEY_SOFT_LIFETIME_RATE; static u_int soft_lifetime_usetime_rate = PFKEY_SOFT_LIFETIME_RATE; u_int pfkey_set_softrate(type, rate) u_int type, rate; { - ipsec_errcode = EIPSEC_NO_ERROR; + __ipsec_errcode = EIPSEC_NO_ERROR; if (rate > 100 || rate == 0) rate = 100; switch (type) { case SADB_X_LIFETIME_ALLOCATIONS: soft_lifetime_allocations_rate = rate; return 0; case SADB_X_LIFETIME_BYTES: soft_lifetime_bytes_rate = rate; return 0; case SADB_X_LIFETIME_ADDTIME: soft_lifetime_addtime_rate = rate; return 0; case SADB_X_LIFETIME_USETIME: soft_lifetime_usetime_rate = rate; return 0; } - ipsec_errcode = EIPSEC_INVAL_ARGUMENT; + __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; return 1; } /* * get current rate for SOFT lifetime against HARD one. * ATTENTION: ~0 is returned if invalid type was passed. */ u_int pfkey_get_softrate(type) u_int type; { switch (type) { case SADB_X_LIFETIME_ALLOCATIONS: return soft_lifetime_allocations_rate; case SADB_X_LIFETIME_BYTES: return soft_lifetime_bytes_rate; case SADB_X_LIFETIME_ADDTIME: return soft_lifetime_addtime_rate; case SADB_X_LIFETIME_USETIME: return soft_lifetime_usetime_rate; } return ~0; } /* * sending SADB_GETSPI message to the kernel. * OUT: * positive: success and return length sent. * -1 : error occured, and set errno. */ int -pfkey_send_getspi(so, satype, mode, src, dst, min, max, seq) +pfkey_send_getspi(so, satype, mode, src, dst, min, max, reqid, seq) int so; u_int satype, mode; struct sockaddr *src, *dst; - u_int32_t min, max, seq; + u_int32_t min, max, reqid, seq; { struct sadb_msg *newmsg; int len; int need_spirange = 0; caddr_t p; + int plen; /* validity check */ if (src == NULL || dst == NULL) { - ipsec_errcode = EIPSEC_INVAL_ARGUMENT; + __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; return -1; } if (src->sa_family != dst->sa_family) { - ipsec_errcode = EIPSEC_FAMILY_MISMATCH; + __ipsec_errcode = EIPSEC_FAMILY_MISMATCH; return -1; } if (min > max || (min > 0 && min <= 255)) { - ipsec_errcode = EIPSEC_INVAL_SPI; + __ipsec_errcode = EIPSEC_INVAL_SPI; return -1; } + switch (src->sa_family) { + case AF_INET: + plen = sizeof(struct in_addr) << 3; + break; + case AF_INET6: + plen = sizeof(struct in6_addr) << 3; + break; + default: + __ipsec_errcode = EIPSEC_INVAL_FAMILY; + return -1; + } /* create new sadb_msg to send. */ len = sizeof(struct sadb_msg) + + sizeof(struct sadb_x_sa2) + sizeof(struct sadb_address) + PFKEY_ALIGN8(src->sa_len) + sizeof(struct sadb_address) + PFKEY_ALIGN8(dst->sa_len); if (min > 255 && max < ~0) { need_spirange++; len += sizeof(struct sadb_spirange); } if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) { - ipsec_set_strerror(strerror(errno)); + __ipsec_set_strerror(strerror(errno)); return -1; } p = pfkey_setsadbmsg((caddr_t)newmsg, SADB_GETSPI, - len, satype, mode, seq, getpid()); + len, satype, seq, getpid()); + p = pfkey_setsadbxsa2(p, mode, reqid); + /* set sadb_address for source */ - p = pfkey_setsadbaddr(p, - SADB_EXT_ADDRESS_SRC, - src, - _INALENBYAF(src->sa_family) << 3, - IPSEC_ULPROTO_ANY); + p = pfkey_setsadbaddr(p, SADB_EXT_ADDRESS_SRC, src, plen, + IPSEC_ULPROTO_ANY); /* set sadb_address for destination */ - p = pfkey_setsadbaddr(p, - SADB_EXT_ADDRESS_DST, - dst, - _INALENBYAF(dst->sa_family) << 3, - IPSEC_ULPROTO_ANY); + p = pfkey_setsadbaddr(p, SADB_EXT_ADDRESS_DST, dst, plen, + IPSEC_ULPROTO_ANY); /* proccessing spi range */ if (need_spirange) { int _len = sizeof(struct sadb_spirange); -#define _SADB_SPIRANGE(p) ((struct sadb_spirange *)(p)) +#define _SADB_SPIRANGE(p) ((struct sadb_spirange *)(p)) _SADB_SPIRANGE(p)->sadb_spirange_len = PFKEY_UNIT64(_len); _SADB_SPIRANGE(p)->sadb_spirange_exttype = SADB_EXT_SPIRANGE; _SADB_SPIRANGE(p)->sadb_spirange_min = min; _SADB_SPIRANGE(p)->sadb_spirange_max = max; #undef _SADB_SPIRANGE(p) p += _len; } /* send message */ len = pfkey_send(so, newmsg, len); free(newmsg); if (len < 0) return -1; - ipsec_errcode = EIPSEC_NO_ERROR; + __ipsec_errcode = EIPSEC_NO_ERROR; return len; } /* * sending SADB_UPDATE message to the kernel. * The length of key material is a_keylen + e_keylen. * OUT: * positive: success and return length sent. * -1 : error occured, and set errno. */ int -pfkey_send_update(so, satype, mode, src, dst, spi, wsize, +pfkey_send_update(so, satype, mode, src, dst, spi, reqid, wsize, keymat, e_type, e_keylen, a_type, a_keylen, flags, l_alloc, l_bytes, l_addtime, l_usetime, seq) int so; u_int satype, mode, wsize; struct sockaddr *src, *dst; - u_int32_t spi; + u_int32_t spi, reqid; caddr_t keymat; u_int e_type, e_keylen, a_type, a_keylen, flags; u_int32_t l_alloc; u_int64_t l_bytes, l_addtime, l_usetime; u_int32_t seq; { int len; if ((len = pfkey_send_x1(so, SADB_UPDATE, satype, mode, src, dst, spi, - wsize, keymat, e_type, e_keylen, a_type, a_keylen, flags, + reqid, wsize, + keymat, e_type, e_keylen, a_type, a_keylen, flags, l_alloc, l_bytes, l_addtime, l_usetime, seq)) < 0) return -1; return len; } /* * sending SADB_ADD message to the kernel. * The length of key material is a_keylen + e_keylen. * OUT: * positive: success and return length sent. * -1 : error occured, and set errno. */ int -pfkey_send_add(so, satype, mode, src, dst, spi, wsize, +pfkey_send_add(so, satype, mode, src, dst, spi, reqid, wsize, keymat, e_type, e_keylen, a_type, a_keylen, flags, l_alloc, l_bytes, l_addtime, l_usetime, seq) int so; u_int satype, mode, wsize; struct sockaddr *src, *dst; - u_int32_t spi; + u_int32_t spi, reqid; caddr_t keymat; u_int e_type, e_keylen, a_type, a_keylen, flags; u_int32_t l_alloc; u_int64_t l_bytes, l_addtime, l_usetime; u_int32_t seq; { int len; if ((len = pfkey_send_x1(so, SADB_ADD, satype, mode, src, dst, spi, - wsize, keymat, e_type, e_keylen, a_type, a_keylen, flags, + reqid, wsize, + keymat, e_type, e_keylen, a_type, a_keylen, flags, l_alloc, l_bytes, l_addtime, l_usetime, seq)) < 0) return -1; return len; } /* * sending SADB_DELETE message to the kernel. * OUT: * positive: success and return length sent. * -1 : error occured, and set errno. */ int pfkey_send_delete(so, satype, mode, src, dst, spi) int so; u_int satype, mode; struct sockaddr *src, *dst; u_int32_t spi; { int len; if ((len = pfkey_send_x2(so, SADB_DELETE, satype, mode, src, dst, spi)) < 0) return -1; return len; } /* * sending SADB_GET message to the kernel. * OUT: * positive: success and return length sent. * -1 : error occured, and set errno. */ int pfkey_send_get(so, satype, mode, src, dst, spi) int so; u_int satype, mode; struct sockaddr *src, *dst; u_int32_t spi; { int len; if ((len = pfkey_send_x2(so, SADB_GET, satype, mode, src, dst, spi)) < 0) return -1; return len; } /* * sending SADB_REGISTER message to the kernel. * OUT: * positive: success and return length sent. * -1 : error occured, and set errno. */ int pfkey_send_register(so, satype) int so; u_int satype; { int len; if ((len = pfkey_send_x3(so, SADB_REGISTER, satype)) < 0) return -1; return len; } /* * receiving SADB_REGISTER message from the kernel, and copy buffer for * sadb_supported returned into ipsec_supported. * OUT: * 0: success and return length sent. * -1: error occured, and set errno. */ int pfkey_recv_register(so) int so; { pid_t pid = getpid(); struct sadb_msg *newmsg; struct sadb_supported *sup; caddr_t p; int tlen; /* receive message */ do { if ((newmsg = pfkey_recv(so)) == NULL) return -1; } while (newmsg->sadb_msg_type != SADB_REGISTER || newmsg->sadb_msg_pid != pid); /* check and fix */ newmsg->sadb_msg_len = PFKEY_UNUNIT64(newmsg->sadb_msg_len); tlen = newmsg->sadb_msg_len - sizeof(struct sadb_msg); p = (caddr_t)newmsg + sizeof(struct sadb_msg); while (tlen > 0) { sup = (struct sadb_supported *)p; switch (sup->sadb_supported_exttype) { case SADB_EXT_SUPPORTED_AUTH: case SADB_EXT_SUPPORTED_ENCRYPT: sup->sadb_supported_len = PFKEY_EXTLEN(sup); break; default: - ipsec_errcode = EIPSEC_INVAL_SATYPE; + __ipsec_errcode = EIPSEC_INVAL_SATYPE; free(newmsg); return -1; } tlen -= sup->sadb_supported_len; p += sup->sadb_supported_len; } if (tlen < 0) { - ipsec_errcode = EIPSEC_INVAL_SATYPE; + __ipsec_errcode = EIPSEC_INVAL_SATYPE; return -1; } if (ipsec_supported != NULL) free(ipsec_supported); ipsec_supported = newmsg; - ipsec_errcode = EIPSEC_NO_ERROR; + __ipsec_errcode = EIPSEC_NO_ERROR; return 0; } /* * sending SADB_FLUSH message to the kernel. * OUT: * positive: success and return length sent. * -1 : error occured, and set errno. */ int pfkey_send_flush(so, satype) int so; u_int satype; { int len; if ((len = pfkey_send_x3(so, SADB_FLUSH, satype)) < 0) return -1; return len; } /* * sending SADB_DUMP message to the kernel. * OUT: * positive: success and return length sent. * -1 : error occured, and set errno. */ int pfkey_send_dump(so, satype) int so; u_int satype; { int len; if ((len = pfkey_send_x3(so, SADB_DUMP, satype)) < 0) return -1; return len; } /* * sending SADB_X_PROMISC message to the kernel. * NOTE that this function handles promisc mode toggle only. * IN: * flag: set promisc off if zero, set promisc on if non-zero. * OUT: * positive: success and return length sent. * -1 : error occured, and set errno. * 0 : error occured, and set errno. * others: a pointer to new allocated buffer in which supported * algorithms is. */ int pfkey_send_promisc_toggle(so, flag) int so; int flag; { int len; if ((len = pfkey_send_x3(so, SADB_X_PROMISC, (flag ? 1 : 0))) < 0) return -1; return len; } /* * sending SADB_X_SPDADD message to the kernel. - * The length of key material is a_keylen + e_keylen. * OUT: * positive: success and return length sent. * -1 : error occured, and set errno. */ int pfkey_send_spdadd(so, src, prefs, dst, prefd, proto, policy, policylen, seq) int so; struct sockaddr *src, *dst; u_int prefs, prefd, proto; - char *policy; + caddr_t policy; int policylen; u_int32_t seq; { - struct sadb_msg *newmsg; int len; - caddr_t p; - /* validity check */ - if (src == NULL || dst == NULL) { - ipsec_errcode = EIPSEC_INVAL_ARGUMENT; + if ((len = pfkey_send_x4(so, SADB_X_SPDADD, + src, prefs, dst, prefd, proto, + policy, policylen, seq)) < 0) return -1; - } - if (src->sa_family != dst->sa_family) { - ipsec_errcode = EIPSEC_FAMILY_MISMATCH; - return -1; - } - if (prefs > (_INALENBYAF(src->sa_family) << 3) - || prefd > (_INALENBYAF(dst->sa_family) << 3)) { - ipsec_errcode = EIPSEC_INVAL_PREFIXLEN; - return -1; - } - /* create new sadb_msg to reply. */ - len = sizeof(struct sadb_msg) - + sizeof(struct sadb_address) - + PFKEY_ALIGN8(_SALENBYAF(src->sa_family)) - + sizeof(struct sadb_address) - + PFKEY_ALIGN8(_SALENBYAF(src->sa_family)) - + policylen; + return len; +} - if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) { - ipsec_set_strerror(strerror(errno)); - return -1; - } +/* + * sending SADB_X_SPDUPDATE message to the kernel. + * OUT: + * positive: success and return length sent. + * -1 : error occured, and set errno. + */ +int +pfkey_send_spdupdate(so, src, prefs, dst, prefd, proto, policy, policylen, seq) + int so; + struct sockaddr *src, *dst; + u_int prefs, prefd, proto; + caddr_t policy; + int policylen; + u_int32_t seq; +{ + int len; - p = pfkey_setsadbmsg((caddr_t)newmsg, SADB_X_SPDADD, len, - SADB_SATYPE_UNSPEC, IPSEC_MODE_ANY, seq, getpid()); - p = pfkey_setsadbaddr(p, - SADB_EXT_ADDRESS_SRC, - src, - prefs, - proto); - p = pfkey_setsadbaddr(p, - SADB_EXT_ADDRESS_DST, - dst, - prefd, - proto); - memcpy(p, policy, policylen); - - /* send message */ - len = pfkey_send(so, newmsg, len); - free(newmsg); - - if (len < 0) + if ((len = pfkey_send_x4(so, SADB_X_SPDUPDATE, + src, prefs, dst, prefd, proto, + policy, policylen, seq)) < 0) return -1; - ipsec_errcode = EIPSEC_NO_ERROR; return len; } /* * sending SADB_X_SPDDELETE message to the kernel. - * The length of key material is a_keylen + e_keylen. * OUT: * positive: success and return length sent. * -1 : error occured, and set errno. */ int -pfkey_send_spddelete(so, src, prefs, dst, prefd, proto, seq) +pfkey_send_spddelete(so, src, prefs, dst, prefd, proto, policy, policylen, seq) int so; struct sockaddr *src, *dst; u_int prefs, prefd, proto; + caddr_t policy; + int policylen; u_int32_t seq; { - struct sadb_msg *newmsg; int len; - caddr_t p; - /* validity check */ - if (src == NULL || dst == NULL) { - ipsec_errcode = EIPSEC_INVAL_ARGUMENT; + if (policylen != sizeof(struct sadb_x_policy)) { + __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; return -1; } - if (src->sa_family != dst->sa_family) { - ipsec_errcode = EIPSEC_FAMILY_MISMATCH; + + if ((len = pfkey_send_x4(so, SADB_X_SPDDELETE, + src, prefs, dst, prefd, proto, + policy, policylen, seq)) < 0) return -1; - } - if (prefs > (_INALENBYAF(src->sa_family) << 3) - || prefd > (_INALENBYAF(dst->sa_family) << 3)) { - ipsec_errcode = EIPSEC_INVAL_PREFIXLEN; + + return len; +} + +/* + * sending SADB_X_SPDDELETE message to the kernel. + * OUT: + * positive: success and return length sent. + * -1 : error occured, and set errno. + */ +int +pfkey_send_spddelete2(so, spid) + int so; + u_int32_t spid; +{ + int len; + + if ((len = pfkey_send_x5(so, SADB_X_SPDDELETE2, spid)) < 0) return -1; - } - /* create new sadb_msg to reply. */ - len = sizeof(struct sadb_msg) - + sizeof(struct sadb_address) - + PFKEY_ALIGN8(_SALENBYAF(src->sa_family)) - + sizeof(struct sadb_address) - + PFKEY_ALIGN8(_SALENBYAF(src->sa_family)); + return len; +} - if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) { - ipsec_set_strerror(strerror(errno)); +/* + * sending SADB_X_SPDGET message to the kernel. + * OUT: + * positive: success and return length sent. + * -1 : error occured, and set errno. + */ +int +pfkey_send_spdget(so, spid) + int so; + u_int32_t spid; +{ + int len; + + if ((len = pfkey_send_x5(so, SADB_X_SPDGET, spid)) < 0) return -1; - } - p = pfkey_setsadbmsg((caddr_t)newmsg, SADB_X_SPDDELETE, len, - SADB_SATYPE_UNSPEC, IPSEC_MODE_ANY, seq, getpid()); - p = pfkey_setsadbaddr(p, - SADB_EXT_ADDRESS_SRC, - src, - prefs, - proto); - p = pfkey_setsadbaddr(p, - SADB_EXT_ADDRESS_DST, - dst, - prefd, - proto); + return len; +} - /* send message */ - len = pfkey_send(so, newmsg, len); - free(newmsg); +/* + * sending SADB_X_SPDSETIDX message to the kernel. + * OUT: + * positive: success and return length sent. + * -1 : error occured, and set errno. + */ +int +pfkey_send_spdsetidx(so, src, prefs, dst, prefd, proto, policy, policylen, seq) + int so; + struct sockaddr *src, *dst; + u_int prefs, prefd, proto; + caddr_t policy; + int policylen; + u_int32_t seq; +{ + int len; - if (len < 0) + if (policylen != sizeof(struct sadb_x_policy)) { + __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; return -1; + } - ipsec_errcode = EIPSEC_NO_ERROR; + if ((len = pfkey_send_x4(so, SADB_X_SPDSETIDX, + src, prefs, dst, prefd, proto, + policy, policylen, seq)) < 0) + return -1; + return len; } /* * sending SADB_SPDFLUSH message to the kernel. * OUT: * positive: success and return length sent. * -1 : error occured, and set errno. */ int pfkey_send_spdflush(so) int so; { int len; if ((len = pfkey_send_x3(so, SADB_X_SPDFLUSH, SADB_SATYPE_UNSPEC)) < 0) return -1; return len; } /* * sending SADB_SPDDUMP message to the kernel. * OUT: * positive: success and return length sent. * -1 : error occured, and set errno. */ int pfkey_send_spddump(so) int so; { int len; if ((len = pfkey_send_x3(so, SADB_X_SPDDUMP, SADB_SATYPE_UNSPEC)) < 0) return -1; return len; } /* sending SADB_ADD or SADB_UPDATE message to the kernel */ static int -pfkey_send_x1(so, type, satype, mode, src, dst, spi, wsize, +pfkey_send_x1(so, type, satype, mode, src, dst, spi, reqid, wsize, keymat, e_type, e_keylen, a_type, a_keylen, flags, l_alloc, l_bytes, l_addtime, l_usetime, seq) int so; u_int type, satype, mode; struct sockaddr *src, *dst; - u_int32_t spi; + u_int32_t spi, reqid; u_int wsize; caddr_t keymat; u_int e_type, e_keylen, a_type, a_keylen, flags; u_int32_t l_alloc, l_bytes, l_addtime, l_usetime, seq; { struct sadb_msg *newmsg; int len; caddr_t p; + int plen; /* validity check */ if (src == NULL || dst == NULL) { - ipsec_errcode = EIPSEC_INVAL_ARGUMENT; + __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; return -1; } if (src->sa_family != dst->sa_family) { - ipsec_errcode = EIPSEC_FAMILY_MISMATCH; + __ipsec_errcode = EIPSEC_FAMILY_MISMATCH; return -1; } + switch (src->sa_family) { + case AF_INET: + plen = sizeof(struct in_addr) << 3; + break; + case AF_INET6: + plen = sizeof(struct in6_addr) << 3; + break; + default: + __ipsec_errcode = EIPSEC_INVAL_FAMILY; + return -1; + } switch (satype) { case SADB_SATYPE_ESP: if (e_type == SADB_EALG_NONE) { - ipsec_errcode = EIPSEC_NO_ALGS; + __ipsec_errcode = EIPSEC_NO_ALGS; return -1; } break; case SADB_SATYPE_AH: if (e_type != SADB_EALG_NONE) { - ipsec_errcode = EIPSEC_INVAL_ALGS; + __ipsec_errcode = EIPSEC_INVAL_ALGS; return -1; } if (a_type == SADB_AALG_NONE) { - ipsec_errcode = EIPSEC_NO_ALGS; + __ipsec_errcode = EIPSEC_NO_ALGS; return -1; } break; case SADB_X_SATYPE_IPCOMP: break; default: - ipsec_errcode = EIPSEC_INVAL_SATYPE; + __ipsec_errcode = EIPSEC_INVAL_SATYPE; return -1; } /* create new sadb_msg to reply. */ len = sizeof(struct sadb_msg) + sizeof(struct sadb_sa) + + sizeof(struct sadb_x_sa2) + sizeof(struct sadb_address) + PFKEY_ALIGN8(src->sa_len) + sizeof(struct sadb_address) + PFKEY_ALIGN8(dst->sa_len) + sizeof(struct sadb_lifetime) + sizeof(struct sadb_lifetime); if (e_type != SADB_EALG_NONE) len += (sizeof(struct sadb_key) + PFKEY_ALIGN8(e_keylen)); if (a_type != SADB_AALG_NONE) len += (sizeof(struct sadb_key) + PFKEY_ALIGN8(a_keylen)); if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) { - ipsec_set_strerror(strerror(errno)); + __ipsec_set_strerror(strerror(errno)); return -1; } p = pfkey_setsadbmsg((caddr_t)newmsg, type, len, - satype, mode, seq, getpid()); + satype, seq, getpid()); p = pfkey_setsadbsa(p, spi, wsize, a_type, e_type, flags); - p = pfkey_setsadbaddr(p, - SADB_EXT_ADDRESS_SRC, - src, - _INALENBYAF(src->sa_family) << 3, - IPSEC_ULPROTO_ANY); - p = pfkey_setsadbaddr(p, - SADB_EXT_ADDRESS_DST, - dst, - _INALENBYAF(dst->sa_family) << 3, - IPSEC_ULPROTO_ANY); + p = pfkey_setsadbxsa2(p, mode, reqid); + p = pfkey_setsadbaddr(p, SADB_EXT_ADDRESS_SRC, src, plen, + IPSEC_ULPROTO_ANY); + p = pfkey_setsadbaddr(p, SADB_EXT_ADDRESS_DST, dst, plen, + IPSEC_ULPROTO_ANY); if (e_type != SADB_EALG_NONE) p = pfkey_setsadbkey(p, SADB_EXT_KEY_ENCRYPT, keymat, e_keylen); if (a_type != SADB_AALG_NONE) p = pfkey_setsadbkey(p, SADB_EXT_KEY_AUTH, keymat + e_keylen, a_keylen); /* set sadb_lifetime for destination */ p = pfkey_setsadblifetime(p, SADB_EXT_LIFETIME_HARD, l_alloc, l_bytes, l_addtime, l_usetime); p = pfkey_setsadblifetime(p, SADB_EXT_LIFETIME_SOFT, l_alloc, l_bytes, l_addtime, l_usetime); /* send message */ len = pfkey_send(so, newmsg, len); free(newmsg); if (len < 0) return -1; - ipsec_errcode = EIPSEC_NO_ERROR; + __ipsec_errcode = EIPSEC_NO_ERROR; return len; } /* sending SADB_DELETE or SADB_GET message to the kernel */ static int pfkey_send_x2(so, type, satype, mode, src, dst, spi) int so; u_int type, satype, mode; struct sockaddr *src, *dst; u_int32_t spi; { struct sadb_msg *newmsg; int len; caddr_t p; + int plen; /* validity check */ if (src == NULL || dst == NULL) { - ipsec_errcode = EIPSEC_INVAL_ARGUMENT; + __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; return -1; } if (src->sa_family != dst->sa_family) { - ipsec_errcode = EIPSEC_FAMILY_MISMATCH; + __ipsec_errcode = EIPSEC_FAMILY_MISMATCH; return -1; } + switch (src->sa_family) { + case AF_INET: + plen = sizeof(struct in_addr) << 3; + break; + case AF_INET6: + plen = sizeof(struct in6_addr) << 3; + break; + default: + __ipsec_errcode = EIPSEC_INVAL_FAMILY; + return -1; + } /* create new sadb_msg to reply. */ len = sizeof(struct sadb_msg) + sizeof(struct sadb_sa) + sizeof(struct sadb_address) + PFKEY_ALIGN8(src->sa_len) + sizeof(struct sadb_address) + PFKEY_ALIGN8(dst->sa_len); if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) { - ipsec_set_strerror(strerror(errno)); + __ipsec_set_strerror(strerror(errno)); return -1; } - p = pfkey_setsadbmsg((caddr_t)newmsg, type, len, satype, mode, 0, getpid()); + p = pfkey_setsadbmsg((caddr_t)newmsg, type, len, satype, 0, getpid()); p = pfkey_setsadbsa(p, spi, 0, 0, 0, 0); - p = pfkey_setsadbaddr(p, - SADB_EXT_ADDRESS_SRC, - src, - _INALENBYAF(src->sa_family) << 3, - IPSEC_ULPROTO_ANY); - p = pfkey_setsadbaddr(p, - SADB_EXT_ADDRESS_DST, - dst, - _INALENBYAF(dst->sa_family) << 3, - IPSEC_ULPROTO_ANY); + p = pfkey_setsadbaddr(p, SADB_EXT_ADDRESS_SRC, src, plen, + IPSEC_ULPROTO_ANY); + p = pfkey_setsadbaddr(p, SADB_EXT_ADDRESS_DST, dst, plen, + IPSEC_ULPROTO_ANY); /* send message */ len = pfkey_send(so, newmsg, len); free(newmsg); if (len < 0) return -1; - ipsec_errcode = EIPSEC_NO_ERROR; + __ipsec_errcode = EIPSEC_NO_ERROR; return len; } /* * sending SADB_REGISTER, SADB_FLUSH, SADB_DUMP or SADB_X_PROMISC message * to the kernel */ static int pfkey_send_x3(so, type, satype) int so; u_int type, satype; { struct sadb_msg *newmsg; int len; /* validity check */ switch (type) { case SADB_X_PROMISC: if (satype != 0 && satype != 1) { - ipsec_errcode = EIPSEC_INVAL_SATYPE; + __ipsec_errcode = EIPSEC_INVAL_SATYPE; return -1; } break; default: switch (satype) { case SADB_SATYPE_UNSPEC: case SADB_SATYPE_AH: case SADB_SATYPE_ESP: case SADB_X_SATYPE_IPCOMP: break; default: - ipsec_errcode = EIPSEC_INVAL_SATYPE; + __ipsec_errcode = EIPSEC_INVAL_SATYPE; return -1; } } /* create new sadb_msg to send. */ len = sizeof(struct sadb_msg); if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) { - ipsec_set_strerror(strerror(errno)); + __ipsec_set_strerror(strerror(errno)); return -1; } - (void)pfkey_setsadbmsg((caddr_t)newmsg, type, len, satype, 0, 0, getpid()); + (void)pfkey_setsadbmsg((caddr_t)newmsg, type, len, satype, 0, getpid()); /* send message */ len = pfkey_send(so, newmsg, len); free(newmsg); if (len < 0) return -1; - ipsec_errcode = EIPSEC_NO_ERROR; + __ipsec_errcode = EIPSEC_NO_ERROR; return len; } +/* sending SADB_X_SPDADD message to the kernel */ +static int +pfkey_send_x4(so, type, src, prefs, dst, prefd, proto, policy, policylen, seq) + int so; + struct sockaddr *src, *dst; + u_int type, prefs, prefd, proto; + char *policy; + int policylen; + u_int32_t seq; +{ + struct sadb_msg *newmsg; + int len; + caddr_t p; + int plen; + + /* validity check */ + if (src == NULL || dst == NULL) { + __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; + return -1; + } + if (src->sa_family != dst->sa_family) { + __ipsec_errcode = EIPSEC_FAMILY_MISMATCH; + return -1; + } + + switch (src->sa_family) { + case AF_INET: + plen = sizeof(struct in_addr) << 3; + break; + case AF_INET6: + plen = sizeof(struct in6_addr) << 3; + break; + default: + __ipsec_errcode = EIPSEC_INVAL_FAMILY; + return -1; + } + if (prefs > plen || prefd > plen) { + __ipsec_errcode = EIPSEC_INVAL_PREFIXLEN; + return -1; + } + + /* create new sadb_msg to reply. */ + len = sizeof(struct sadb_msg) + + sizeof(struct sadb_address) + + PFKEY_ALIGN8(src->sa_len) + + sizeof(struct sadb_address) + + PFKEY_ALIGN8(src->sa_len) + + policylen; + + if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) { + __ipsec_set_strerror(strerror(errno)); + return -1; + } + + p = pfkey_setsadbmsg((caddr_t)newmsg, type, len, + SADB_SATYPE_UNSPEC, seq, getpid()); + p = pfkey_setsadbaddr(p, + SADB_EXT_ADDRESS_SRC, + src, + prefs, + proto); + p = pfkey_setsadbaddr(p, + SADB_EXT_ADDRESS_DST, + dst, + prefd, + proto); + memcpy(p, policy, policylen); + + /* send message */ + len = pfkey_send(so, newmsg, len); + free(newmsg); + + if (len < 0) + return -1; + + __ipsec_errcode = EIPSEC_NO_ERROR; + return len; +} + +/* sending SADB_X_SPDGET or SADB_X_SPDDELETE message to the kernel */ +static int +pfkey_send_x5(so, type, spid) + int so; + u_int type; + u_int32_t spid; +{ + struct sadb_msg *newmsg; + struct sadb_x_policy xpl; + int len; + caddr_t p; + + /* create new sadb_msg to reply. */ + len = sizeof(struct sadb_msg) + + sizeof(xpl); + + if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) { + __ipsec_set_strerror(strerror(errno)); + return -1; + } + + p = pfkey_setsadbmsg((caddr_t)newmsg, type, len, + SADB_SATYPE_UNSPEC, 0, getpid()); + + memset(&xpl, 0, sizeof(xpl)); + xpl.sadb_x_policy_len = PFKEY_UNUNIT64(sizeof(xpl)); + xpl.sadb_x_policy_exttype = SADB_X_EXT_POLICY; + xpl.sadb_x_policy_id = spid; + + memcpy(p, &xpl, sizeof(xpl)); + + /* send message */ + len = pfkey_send(so, newmsg, len); + free(newmsg); + + if (len < 0) + return -1; + + __ipsec_errcode = EIPSEC_NO_ERROR; + return len; +} + /* * open a socket. * OUT: * -1: fail. * others : success and return value of socket. */ int pfkey_open() { int so; const int bufsiz = 128 * 1024; /*is 128K enough?*/ if ((so = socket(PF_KEY, SOCK_RAW, PF_KEY_V2)) < 0) { - ipsec_set_strerror(strerror(errno)); + __ipsec_set_strerror(strerror(errno)); return -1; } /* * This is a temporary workaround for KAME PR 154. * Don't really care even if it fails. */ (void)setsockopt(so, SOL_SOCKET, SO_SNDBUF, &bufsiz, sizeof(bufsiz)); (void)setsockopt(so, SOL_SOCKET, SO_RCVBUF, &bufsiz, sizeof(bufsiz)); - ipsec_errcode = EIPSEC_NO_ERROR; + __ipsec_errcode = EIPSEC_NO_ERROR; return so; } /* * close a socket. * OUT: * 0: success. * -1: fail. */ void pfkey_close(so) int so; { (void)close(so); - ipsec_errcode = EIPSEC_NO_ERROR; + __ipsec_errcode = EIPSEC_NO_ERROR; return; } /* * receive sadb_msg data, and return pointer to new buffer allocated. * Must free this buffer later. * OUT: * NULL : error occured. * others : a pointer to sadb_msg structure. */ struct sadb_msg * pfkey_recv(so) int so; { struct sadb_msg buf, *newmsg; int len, reallen; while ((len = recv(so, (caddr_t)&buf, sizeof(buf), MSG_PEEK)) < 0) { if (errno == EINTR) continue; - ipsec_set_strerror(strerror(errno)); + __ipsec_set_strerror(strerror(errno)); return NULL; } if (len < sizeof(buf)) { recv(so, (caddr_t)&buf, sizeof(buf), 0); - ipsec_errcode = EIPSEC_MAX; + __ipsec_errcode = EIPSEC_MAX; return NULL; } /* read real message */ reallen = PFKEY_UNUNIT64(buf.sadb_msg_len); if ((newmsg = CALLOC(reallen, struct sadb_msg *)) == 0) { - ipsec_set_strerror(strerror(errno)); + __ipsec_set_strerror(strerror(errno)); return NULL; } while ((len = recv(so, (caddr_t)newmsg, reallen, 0)) < 0) { if (errno == EINTR) continue; - ipsec_set_strerror(strerror(errno)); + __ipsec_set_strerror(strerror(errno)); free(newmsg); return NULL; } if (len != reallen) { - ipsec_errcode = EIPSEC_SYSTEM_ERROR; + __ipsec_errcode = EIPSEC_SYSTEM_ERROR; free(newmsg); return NULL; } - ipsec_errcode = EIPSEC_NO_ERROR; + __ipsec_errcode = EIPSEC_NO_ERROR; return newmsg; } /* * send message to a socket. * OUT: * others: success and return length sent. * -1 : fail. */ int pfkey_send(so, msg, len) int so; struct sadb_msg *msg; int len; { if ((len = send(so, (caddr_t)msg, len, 0)) < 0) { - ipsec_set_strerror(strerror(errno)); + __ipsec_set_strerror(strerror(errno)); return -1; } - ipsec_errcode = EIPSEC_NO_ERROR; + __ipsec_errcode = EIPSEC_NO_ERROR; return len; } /* * %%% Utilities * NOTE: These functions are derived from netkey/key.c in KAME. */ /* * set the pointer to each header in this message buffer. * IN: msg: pointer to message buffer. * mhp: pointer to the buffer initialized like below: * caddr_t mhp[SADB_EXT_MAX + 1]; * OUT: -1: invalid. * 0: valid. */ int pfkey_align(msg, mhp) struct sadb_msg *msg; caddr_t *mhp; { struct sadb_ext *ext; int tlen, extlen; int i; /* validity check */ if (msg == NULL || mhp == NULL) { - ipsec_errcode = EIPSEC_INVAL_ARGUMENT; + __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; return -1; } /* initialize */ for (i = 0; i < SADB_EXT_MAX + 1; i++) mhp[i] = NULL; mhp[0] = (caddr_t)msg; tlen = PFKEY_UNUNIT64(msg->sadb_msg_len) - sizeof(struct sadb_msg); ext = (struct sadb_ext *)((caddr_t)msg + sizeof(struct sadb_msg)); while (tlen > 0) { /* duplicate check */ /* XXX Are there duplication either KEY_AUTH or KEY_ENCRYPT ?*/ if (mhp[ext->sadb_ext_type] != NULL) { - ipsec_errcode = EIPSEC_INVAL_EXTTYPE; + __ipsec_errcode = EIPSEC_INVAL_EXTTYPE; return -1; } /* set pointer */ switch (ext->sadb_ext_type) { case SADB_EXT_SA: case SADB_EXT_LIFETIME_CURRENT: case SADB_EXT_LIFETIME_HARD: case SADB_EXT_LIFETIME_SOFT: case SADB_EXT_ADDRESS_SRC: case SADB_EXT_ADDRESS_DST: case SADB_EXT_ADDRESS_PROXY: case SADB_EXT_KEY_AUTH: /* XXX should to be check weak keys. */ case SADB_EXT_KEY_ENCRYPT: /* XXX should to be check weak keys. */ case SADB_EXT_IDENTITY_SRC: case SADB_EXT_IDENTITY_DST: case SADB_EXT_SENSITIVITY: case SADB_EXT_PROPOSAL: case SADB_EXT_SUPPORTED_AUTH: case SADB_EXT_SUPPORTED_ENCRYPT: case SADB_EXT_SPIRANGE: case SADB_X_EXT_POLICY: + case SADB_X_EXT_SA2: mhp[ext->sadb_ext_type] = (caddr_t)ext; break; default: - ipsec_errcode = EIPSEC_INVAL_EXTTYPE; + __ipsec_errcode = EIPSEC_INVAL_EXTTYPE; return -1; } extlen = PFKEY_EXTLEN(ext); tlen -= extlen; ext = (struct sadb_ext *)((caddr_t)ext + extlen); } - ipsec_errcode = EIPSEC_NO_ERROR; + __ipsec_errcode = EIPSEC_NO_ERROR; return 0; } /* * check basic usage for sadb_msg, * NOTE: This routine is derived from netkey/key.c in KAME. * IN: msg: pointer to message buffer. * mhp: pointer to the buffer initialized like below: * * caddr_t mhp[SADB_EXT_MAX + 1]; * * OUT: -1: invalid. * 0: valid. */ int pfkey_check(mhp) caddr_t *mhp; { struct sadb_msg *msg; /* validity check */ if (mhp == NULL || mhp[0] == NULL) { - ipsec_errcode = EIPSEC_INVAL_ARGUMENT; + __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; return -1; } msg = (struct sadb_msg *)mhp[0]; /* check version */ if (msg->sadb_msg_version != PF_KEY_V2) { - ipsec_errcode = EIPSEC_INVAL_VERSION; + __ipsec_errcode = EIPSEC_INVAL_VERSION; return -1; } /* check type */ if (msg->sadb_msg_type > SADB_MAX) { - ipsec_errcode = EIPSEC_INVAL_MSGTYPE; + __ipsec_errcode = EIPSEC_INVAL_MSGTYPE; return -1; } /* check SA type */ switch (msg->sadb_msg_satype) { case SADB_SATYPE_UNSPEC: switch (msg->sadb_msg_type) { case SADB_GETSPI: case SADB_UPDATE: case SADB_ADD: case SADB_DELETE: case SADB_GET: case SADB_ACQUIRE: case SADB_EXPIRE: - ipsec_errcode = EIPSEC_INVAL_SATYPE; + __ipsec_errcode = EIPSEC_INVAL_SATYPE; return -1; } break; case SADB_SATYPE_ESP: case SADB_SATYPE_AH: case SADB_X_SATYPE_IPCOMP: switch (msg->sadb_msg_type) { case SADB_X_SPDADD: case SADB_X_SPDDELETE: case SADB_X_SPDGET: case SADB_X_SPDDUMP: case SADB_X_SPDFLUSH: - ipsec_errcode = EIPSEC_INVAL_SATYPE; + __ipsec_errcode = EIPSEC_INVAL_SATYPE; return -1; } break; case SADB_SATYPE_RSVP: case SADB_SATYPE_OSPFV2: case SADB_SATYPE_RIPV2: case SADB_SATYPE_MIP: - ipsec_errcode = EIPSEC_NOT_SUPPORTED; + __ipsec_errcode = EIPSEC_NOT_SUPPORTED; return -1; case 1: /* XXX: What does it do ? */ if (msg->sadb_msg_type == SADB_X_PROMISC) break; /*FALLTHROUGH*/ default: - ipsec_errcode = EIPSEC_INVAL_SATYPE; + __ipsec_errcode = EIPSEC_INVAL_SATYPE; return -1; } /* check field of upper layer protocol and address family */ if (mhp[SADB_EXT_ADDRESS_SRC] != NULL && mhp[SADB_EXT_ADDRESS_DST] != NULL) { struct sadb_address *src0, *dst0; src0 = (struct sadb_address *)(mhp[SADB_EXT_ADDRESS_SRC]); dst0 = (struct sadb_address *)(mhp[SADB_EXT_ADDRESS_DST]); if (src0->sadb_address_proto != dst0->sadb_address_proto) { - ipsec_errcode = EIPSEC_PROTO_MISMATCH; + __ipsec_errcode = EIPSEC_PROTO_MISMATCH; return -1; } if (PFKEY_ADDR_SADDR(src0)->sa_family != PFKEY_ADDR_SADDR(dst0)->sa_family) { - ipsec_errcode = EIPSEC_FAMILY_MISMATCH; + __ipsec_errcode = EIPSEC_FAMILY_MISMATCH; return -1; } switch (PFKEY_ADDR_SADDR(src0)->sa_family) { case AF_INET: case AF_INET6: break; default: - ipsec_errcode = EIPSEC_INVAL_FAMILY; + __ipsec_errcode = EIPSEC_INVAL_FAMILY; return -1; } /* * prefixlen == 0 is valid because there must be the case * all addresses are matched. */ } - ipsec_errcode = EIPSEC_NO_ERROR; + __ipsec_errcode = EIPSEC_NO_ERROR; return 0; } /* * set data into sadb_msg. * `buf' must has been allocated sufficiently. */ static caddr_t -pfkey_setsadbmsg(buf, type, tlen, satype, mode, seq, pid) +pfkey_setsadbmsg(buf, type, tlen, satype, seq, pid) caddr_t buf; - u_int type, satype, mode; + u_int type, satype; u_int tlen; u_int32_t seq; pid_t pid; { struct sadb_msg *p; u_int len; p = (struct sadb_msg *)buf; - len = sizeof(struct sadb_sa); + len = sizeof(struct sadb_msg); memset(p, 0, len); p->sadb_msg_version = PF_KEY_V2; p->sadb_msg_type = type; p->sadb_msg_errno = 0; p->sadb_msg_satype = satype; p->sadb_msg_len = PFKEY_UNIT64(tlen); - p->sadb_msg_mode = mode; p->sadb_msg_reserved = 0; p->sadb_msg_seq = seq; p->sadb_msg_pid = (u_int32_t)pid; return(buf + len); } /* * copy secasvar data into sadb_address. * `buf' must has been allocated sufficiently. */ static caddr_t pfkey_setsadbsa(buf, spi, wsize, auth, enc, flags) caddr_t buf; u_int32_t spi, flags; u_int wsize, auth, enc; { struct sadb_sa *p; u_int len; p = (struct sadb_sa *)buf; len = sizeof(struct sadb_sa); memset(p, 0, len); p->sadb_sa_len = PFKEY_UNIT64(len); p->sadb_sa_exttype = SADB_EXT_SA; p->sadb_sa_spi = spi; p->sadb_sa_replay = wsize; p->sadb_sa_state = SADB_SASTATE_LARVAL; p->sadb_sa_auth = auth; p->sadb_sa_encrypt = enc; p->sadb_sa_flags = flags; return(buf + len); } /* * set data into sadb_address. * `buf' must has been allocated sufficiently. * prefixlen is in bits. */ static caddr_t pfkey_setsadbaddr(buf, exttype, saddr, prefixlen, ul_proto) caddr_t buf; u_int exttype; struct sockaddr *saddr; u_int prefixlen; u_int ul_proto; { struct sadb_address *p; u_int len; p = (struct sadb_address *)buf; len = sizeof(struct sadb_address) + PFKEY_ALIGN8(saddr->sa_len); memset(p, 0, len); p->sadb_address_len = PFKEY_UNIT64(len); p->sadb_address_exttype = exttype & 0xffff; p->sadb_address_proto = ul_proto & 0xff; p->sadb_address_prefixlen = prefixlen; p->sadb_address_reserved = 0; memcpy(p + 1, saddr, saddr->sa_len); return(buf + len); } /* * set sadb_key structure after clearing buffer with zero. * OUT: the pointer of buf + len. */ static caddr_t pfkey_setsadbkey(buf, type, key, keylen) caddr_t buf, key; u_int type, keylen; { struct sadb_key *p; u_int len; p = (struct sadb_key *)buf; len = sizeof(struct sadb_key) + PFKEY_ALIGN8(keylen); memset(p, 0, len); p->sadb_key_len = PFKEY_UNIT64(len); p->sadb_key_exttype = type; p->sadb_key_bits = keylen << 3; p->sadb_key_reserved = 0; memcpy(p + 1, key, keylen); return buf + len; } /* * set sadb_lifetime structure after clearing buffer with zero. * OUT: the pointer of buf + len. */ static caddr_t pfkey_setsadblifetime(buf, type, l_alloc, l_bytes, l_addtime, l_usetime) caddr_t buf; u_int type; u_int32_t l_alloc, l_bytes, l_addtime, l_usetime; { struct sadb_lifetime *p; u_int len; p = (struct sadb_lifetime *)buf; len = sizeof(struct sadb_lifetime); memset(p, 0, len); p->sadb_lifetime_len = PFKEY_UNIT64(len); p->sadb_lifetime_exttype = type; switch (type) { case SADB_EXT_LIFETIME_SOFT: p->sadb_lifetime_allocations = (l_alloc * soft_lifetime_allocations_rate) /100; p->sadb_lifetime_bytes - = ((l_bytes * soft_lifetime_bytes_rate) /100) << 10; + = (l_bytes * soft_lifetime_bytes_rate) /100; p->sadb_lifetime_addtime = (l_addtime * soft_lifetime_addtime_rate) /100; p->sadb_lifetime_usetime = (l_usetime * soft_lifetime_usetime_rate) /100; break; case SADB_EXT_LIFETIME_HARD: p->sadb_lifetime_allocations = l_alloc; - p->sadb_lifetime_bytes = l_bytes << 10; + p->sadb_lifetime_bytes = l_bytes; p->sadb_lifetime_addtime = l_addtime; p->sadb_lifetime_usetime = l_usetime; break; } return buf + len; +} + +/* + * copy secasvar data into sadb_address. + * `buf' must has been allocated sufficiently. + */ +static caddr_t +pfkey_setsadbxsa2(buf, mode0, reqid) + caddr_t buf; + u_int32_t mode0; + u_int32_t reqid; +{ + struct sadb_x_sa2 *p; + u_int8_t mode = mode0 & 0xff; + u_int len; + + p = (struct sadb_x_sa2 *)buf; + len = sizeof(struct sadb_x_sa2); + + memset(p, 0, len); + p->sadb_x_sa2_len = PFKEY_UNIT64(len); + p->sadb_x_sa2_exttype = SADB_X_EXT_SA2; + p->sadb_x_sa2_mode = mode; + p->sadb_x_sa2_reqid = reqid; + + return(buf + len); } Index: head/lib/libipsec/pfkey_dump.c =================================================================== --- head/lib/libipsec/pfkey_dump.c (revision 62582) +++ head/lib/libipsec/pfkey_dump.c (revision 62583) @@ -1,463 +1,526 @@ +/* $FreeBSD$ */ +/* $KAME: pfkey_dump.c,v 1.19 2000/06/10 06:47:11 sakane Exp $ */ + /* * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #include #include #include #include #include #include #include #include #include -#ifdef INET6 -#include -#endif #include #include #include #include #include #include +#include #include "ipsec_strerror.h" +#include "libpfkey.h" -#define GETMSGSTR(str, num) \ -{ \ +#define GETMSGSTR(str, num) \ +do { \ if (sizeof((str)[0]) == 0 \ || num >= sizeof(str)/sizeof((str)[0])) \ printf("%d ", (num)); \ else if (strlen((str)[(num)]) == 0) \ printf("%d ", (num)); \ else \ printf("%s ", (str)[(num)]); \ -} +} while (0) -#define GETAF(p) \ - (((struct sockaddr *)(p))->sa_family) +static char *str_ipaddr __P((struct sockaddr *)); +static char *str_prefport __P((u_int, u_int, u_int)); +static char *str_time __P((time_t)); +static void str_lifetime_byte __P((struct sadb_lifetime *, char *)); -static char *_str_ipaddr __P((u_int family, caddr_t addr)); -static char *_str_prefport __P((u_int family, u_int pref, u_int port)); -static char *_str_time __P((time_t t)); -static void _str_lifetime_byte __P((struct sadb_lifetime *x, char *str)); - /* * Must to be re-written about following strings. */ static char *_str_satype[] = { "unspec", "unknown", "ah", "esp", "unknown", "rsvp", "ospfv2", "ripv2", "mip", "ipcomp", }; static char *_str_mode[] = { "any", "transport", "tunnel", }; static char *_str_upper[] = { /*0*/ "ip", "icmp", "igmp", "ggp", "ip4", "", "tcp", "", "egp", "", /*10*/ "", "", "", "", "", "", "", "udp", "", "", /*20*/ "", "", "idp", "", "", "", "", "", "", "tp", /*30*/ "", "", "", "", "", "", "", "", "", "", /*40*/ "", "ip6", "", "rt6", "frag6", "", "rsvp", "gre", "", "", /*50*/ "esp", "ah", "", "", "", "", "", "", "icmp6", "none", /*60*/ "dst6", }; static char *_str_state[] = { "larval", "mature", "dying", "dead", }; static char *_str_alg_auth[] = { "none", "hmac-md5", "hmac-sha1", "md5", "sha", "null", }; static char *_str_alg_enc[] = { "none", "des-cbc", "3des-cbc", "null", "blowfish-cbc", "cast128-cbc", "rc5-cbc", }; static char *_str_alg_comp[] = { "none", "oui", "deflate", "lzs", }; /* * dump SADB_MSG formated. For debugging, you should use kdebug_sadb(). */ void pfkey_sadump(m) struct sadb_msg *m; { caddr_t mhp[SADB_EXT_MAX + 1]; struct sadb_sa *m_sa; + struct sadb_x_sa2 *m_sa2; struct sadb_lifetime *m_lftc, *m_lfth, *m_lfts; struct sadb_address *m_saddr, *m_daddr, *m_paddr; struct sadb_key *m_auth, *m_enc; struct sadb_ident *m_sid, *m_did; struct sadb_sens *m_sens; /* check pfkey message. */ if (pfkey_align(m, mhp)) { printf("%s\n", ipsec_strerror()); return; } if (pfkey_check(mhp)) { printf("%s\n", ipsec_strerror()); return; } m_sa = (struct sadb_sa *)mhp[SADB_EXT_SA]; + m_sa2 = (struct sadb_x_sa2 *)mhp[SADB_X_EXT_SA2]; m_lftc = (struct sadb_lifetime *)mhp[SADB_EXT_LIFETIME_CURRENT]; m_lfth = (struct sadb_lifetime *)mhp[SADB_EXT_LIFETIME_HARD]; m_lfts = (struct sadb_lifetime *)mhp[SADB_EXT_LIFETIME_SOFT]; m_saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC]; m_daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST]; m_paddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_PROXY]; m_auth = (struct sadb_key *)mhp[SADB_EXT_KEY_AUTH]; m_enc = (struct sadb_key *)mhp[SADB_EXT_KEY_ENCRYPT]; m_sid = (struct sadb_ident *)mhp[SADB_EXT_IDENTITY_SRC]; - m_did = (struct sadb_ident *)mhp[SADB_EXT_IDENTITY_SRC]; + m_did = (struct sadb_ident *)mhp[SADB_EXT_IDENTITY_DST]; m_sens = (struct sadb_sens *)mhp[SADB_EXT_SENSITIVITY]; /* source address */ if (m_saddr == NULL) { printf("no ADDRESS_SRC extension.\n"); return; } - printf("%s ", - _str_ipaddr(GETAF(m_saddr + 1), _INADDRBYSA(m_saddr + 1))); + printf("%s ", str_ipaddr((struct sockaddr *)(m_saddr + 1))); /* destination address */ if (m_daddr == NULL) { printf("no ADDRESS_DST extension.\n"); return; } - printf("%s ", - _str_ipaddr(GETAF(m_daddr + 1), _INADDRBYSA(m_daddr + 1))); + printf("%s ", str_ipaddr((struct sockaddr *)(m_daddr + 1))); /* SA type */ if (m_sa == NULL) { printf("no SA extension.\n"); return; } + if (m_sa2 == NULL) { + printf("no SA2 extension.\n"); + return; + } printf("\n\t"); GETMSGSTR(_str_satype, m->sadb_msg_satype); printf("mode="); - GETMSGSTR(_str_mode, m->sadb_msg_mode); + GETMSGSTR(_str_mode, m_sa2->sadb_x_sa2_mode); - printf("spi=%u(0x%08x) replay=%u flags=0x%08x\n", + printf("spi=%u(0x%08x) reqid=%u(0x%08x)\n", (u_int32_t)ntohl(m_sa->sadb_sa_spi), (u_int32_t)ntohl(m_sa->sadb_sa_spi), - m_sa->sadb_sa_replay, - m_sa->sadb_sa_flags); + (u_int32_t)m_sa2->sadb_x_sa2_reqid, + (u_int32_t)m_sa2->sadb_x_sa2_reqid); /* encryption key */ if (m->sadb_msg_satype == SADB_X_SATYPE_IPCOMP) { printf("\tC: "); GETMSGSTR(_str_alg_comp, m_sa->sadb_sa_encrypt); } else if (m->sadb_msg_satype == SADB_SATYPE_ESP) { if (m_enc != NULL) { printf("\tE: "); GETMSGSTR(_str_alg_enc, m_sa->sadb_sa_encrypt); ipsec_hexdump((caddr_t)m_enc + sizeof(*m_enc), m_enc->sadb_key_bits / 8); printf("\n"); } } /* authentication key */ if (m_auth != NULL) { printf("\tA: "); GETMSGSTR(_str_alg_auth, m_sa->sadb_sa_auth); ipsec_hexdump((caddr_t)m_auth + sizeof(*m_auth), m_auth->sadb_key_bits / 8); printf("\n"); } + /* replay windoe size & flags */ + printf("\treplay=%u flags=0x%08x ", + m_sa->sadb_sa_replay, + m_sa->sadb_sa_flags); + /* state */ - printf("\tstate="); + printf("state="); GETMSGSTR(_str_state, m_sa->sadb_sa_state); printf("seq=%lu pid=%lu\n", (u_long)m->sadb_msg_seq, (u_long)m->sadb_msg_pid); /* lifetime */ if (m_lftc != NULL) { time_t tmp_time = time(0); printf("\tcreated: %s", - _str_time(m_lftc->sadb_lifetime_addtime)); - printf("\tcurrent: %s\n", _str_time(tmp_time)); + str_time(m_lftc->sadb_lifetime_addtime)); + printf("\tcurrent: %s\n", str_time(tmp_time)); printf("\tdiff: %lu(s)", (u_long)(m_lftc->sadb_lifetime_addtime == 0 ? 0 : (tmp_time - m_lftc->sadb_lifetime_addtime))); printf("\thard: %lu(s)", (u_long)(m_lfth == NULL ? 0 : m_lfth->sadb_lifetime_addtime)); printf("\tsoft: %lu(s)\n", (u_long)(m_lfts == NULL ? 0 : m_lfts->sadb_lifetime_addtime)); printf("\tlast: %s", - _str_time(m_lftc->sadb_lifetime_usetime)); + str_time(m_lftc->sadb_lifetime_usetime)); printf("\thard: %lu(s)", (u_long)(m_lfth == NULL ? 0 : m_lfth->sadb_lifetime_usetime)); printf("\tsoft: %lu(s)\n", (u_long)(m_lfts == NULL ? 0 : m_lfts->sadb_lifetime_usetime)); - _str_lifetime_byte(m_lftc, "current"); - _str_lifetime_byte(m_lfth, "hard"); - _str_lifetime_byte(m_lfts, "soft"); + str_lifetime_byte(m_lftc, "current"); + str_lifetime_byte(m_lfth, "hard"); + str_lifetime_byte(m_lfts, "soft"); printf("\n"); printf("\tallocated: %lu", (unsigned long)m_lftc->sadb_lifetime_allocations); printf("\thard: %lu", (u_long)(m_lfth == NULL ? 0 : m_lfth->sadb_lifetime_allocations)); printf("\tsoft: %lu\n", (u_long)(m_lfts == NULL ? 0 : m_lfts->sadb_lifetime_allocations)); } /* XXX DEBUG */ - printf("\trefcnt=%d\n", m->sadb_msg_reserved); + printf("\trefcnt=%u\n", m->sadb_msg_reserved); return; } void pfkey_spdump(m) struct sadb_msg *m; { + char pbuf[NI_MAXSERV]; caddr_t mhp[SADB_EXT_MAX + 1]; struct sadb_address *m_saddr, *m_daddr; struct sadb_x_policy *m_xpl; + struct sockaddr *sa; + u_int16_t port; /* check pfkey message. */ if (pfkey_align(m, mhp)) { printf("%s\n", ipsec_strerror()); return; } if (pfkey_check(mhp)) { printf("%s\n", ipsec_strerror()); return; } m_saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC]; m_daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST]; m_xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY]; /* source address */ if (m_saddr == NULL) { printf("no ADDRESS_SRC extension.\n"); return; } - printf("%s%s ", - _str_ipaddr(GETAF(m_saddr + 1), _INADDRBYSA(m_saddr + 1)), - _str_prefport(GETAF(m_saddr + 1), - m_saddr->sadb_address_prefixlen, - _INPORTBYSA(m_saddr + 1))); + sa = (struct sockaddr *)(m_saddr + 1); + switch (sa->sa_family) { + case AF_INET: + case AF_INET6: + if (getnameinfo(sa, sa->sa_len, NULL, 0, pbuf, sizeof(pbuf), + NI_NUMERICSERV) != 0) + port = 0; /*XXX*/ + else + port = atoi(pbuf); + printf("%s%s ", str_ipaddr(sa), + str_prefport(sa->sa_family, + m_saddr->sadb_address_prefixlen, port)); + break; + default: + printf("unknown-af "); + break; + } /* destination address */ if (m_daddr == NULL) { printf("no ADDRESS_DST extension.\n"); return; } - printf("%s%s ", - _str_ipaddr(GETAF(m_daddr + 1), _INADDRBYSA(m_daddr + 1)), - _str_prefport(GETAF(m_daddr + 1), - m_daddr->sadb_address_prefixlen, - _INPORTBYSA(m_daddr + 1))); + sa = (struct sockaddr *)(m_daddr + 1); + switch (sa->sa_family) { + case AF_INET: + case AF_INET6: + if (getnameinfo(sa, sa->sa_len, NULL, 0, pbuf, sizeof(pbuf), + NI_NUMERICSERV) != 0) + port = 0; /*XXX*/ + else + port = atoi(pbuf); + printf("%s%s ", str_ipaddr(sa), + str_prefport(sa->sa_family, + m_daddr->sadb_address_prefixlen, port)); + break; + default: + printf("unknown-af "); + break; + } /* upper layer protocol */ - if (m_saddr->sadb_address_proto != m_saddr->sadb_address_proto) { + if (m_saddr->sadb_address_proto != m_daddr->sadb_address_proto) { printf("upper layer protocol mismatched.\n"); return; } if (m_saddr->sadb_address_proto == IPSEC_ULPROTO_ANY) printf("any"); else GETMSGSTR(_str_upper, m_saddr->sadb_address_proto); /* policy */ { char *d_xpl; if (m_xpl == NULL) { printf("no X_POLICY extension.\n"); return; } d_xpl = ipsec_dump_policy((char *)m_xpl, "\n\t"); /* dump SPD */ printf("\n\t%s\n", d_xpl); free(d_xpl); } - printf("\tseq=%ld pid=%ld\n", + printf("\tspid=%ld seq=%ld pid=%ld\n", + (u_long)m_xpl->sadb_x_policy_id, (u_long)m->sadb_msg_seq, (u_long)m->sadb_msg_pid); /* XXX TEST */ - printf("\trefcnt=%d\n", m->sadb_msg_reserved); + printf("\trefcnt=%u\n", m->sadb_msg_reserved); return; } /* * set "ipaddress" to buffer. */ static char * -_str_ipaddr(family, addr) - u_int family; - caddr_t addr; +str_ipaddr(sa) + struct sockaddr *sa; { - static char buf[128]; - char addrbuf[128]; + static char buf[NI_MAXHOST]; +#ifdef NI_WITHSCOPEID + const int niflag = NI_NUMERICHOST | NI_WITHSCOPEID; +#else + const int niflag = NI_NUMERICHOST; +#endif - if (addr == NULL) + if (sa == NULL) return ""; - inet_ntop(family, addr, addrbuf, sizeof(addrbuf)); - - snprintf(buf, sizeof(buf), "%s", addrbuf); - - return buf; + if (getnameinfo(sa, sa->sa_len, buf, sizeof(buf), NULL, 0, niflag) == 0) + return buf; + return NULL; } /* * set "/prefix[port number]" to buffer. */ static char * -_str_prefport(family, pref, port) +str_prefport(family, pref, port) u_int family, pref, port; { static char buf[128]; char prefbuf[10]; char portbuf[10]; + int plen; - if (pref == (_INALENBYAF(family) << 3)) + switch (family) { + case AF_INET: + plen = sizeof(struct in_addr) << 3; + break; + case AF_INET6: + plen = sizeof(struct in6_addr) << 3; + break; + default: + return "?"; + } + + if (pref == plen) prefbuf[0] = '\0'; else snprintf(prefbuf, sizeof(prefbuf), "/%u", pref); if (port == IPSEC_PORT_ANY) snprintf(portbuf, sizeof(portbuf), "[%s]", "any"); else - snprintf(portbuf, sizeof(portbuf), "[%u]", ntohs(port)); + snprintf(portbuf, sizeof(portbuf), "[%u]", port); snprintf(buf, sizeof(buf), "%s%s", prefbuf, portbuf); return buf; } /* * set "Mon Day Time Year" to buffer */ static char * -_str_time(t) +str_time(t) time_t t; { static char buf[128]; if (t == 0) { int i = 0; for (;i < 20;) buf[i++] = ' '; } else { char *t0; t0 = ctime(&t); memcpy(buf, t0 + 4, 20); } buf[20] = '\0'; return(buf); } static void -_str_lifetime_byte(x, str) +str_lifetime_byte(x, str) struct sadb_lifetime *x; char *str; { double y; char *unit; int w; if (x == NULL) { printf("\t%s: 0(bytes)", str); return; } +#if 0 + if ((x->sadb_lifetime_bytes) / 1024 / 1024) { + y = (x->sadb_lifetime_bytes) * 1.0 / 1024 / 1024; + unit = "M"; + w = 1; + } else if ((x->sadb_lifetime_bytes) / 1024) { + y = (x->sadb_lifetime_bytes) * 1.0 / 1024; + unit = "K"; + w = 1; + } else { + y = (x->sadb_lifetime_bytes) * 1.0; + unit = ""; + w = 0; + } +#else y = (x->sadb_lifetime_bytes) * 1.0; unit = ""; w = 0; +#endif printf("\t%s: %.*f(%sbytes)", str, w, y, unit); } Index: head/lib/libipsec/policy_parse.y =================================================================== --- head/lib/libipsec/policy_parse.y (revision 62582) +++ head/lib/libipsec/policy_parse.y (revision 62583) @@ -1,426 +1,432 @@ +/* $FreeBSD$ */ +/* $KAME: policy_parse.y,v 1.10 2000/05/07 05:25:03 itojun Exp $ */ + /* * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ -/* KAME $Id: policy_parse.y,v 1.1 1999/10/20 01:26:41 sakane Exp $ */ /* * IN/OUT bound policy configuration take place such below: * in * out * * is one of following: * "discard", "none", "ipsec ", "entrust", "bypass", * * The following requests are accepted as : * * protocol/mode/src-dst/level * protocol/mode/src-dst parsed as protocol/mode/src-dst/default * protocol/mode/src-dst/ parsed as protocol/mode/src-dst/default * protocol/transport parsed as protocol/mode/any-any/default * protocol/transport//level parsed as protocol/mode/any-any/level * * You can concatenate these requests with either ' '(single space) or '\n'. */ %{ #include #include #include #include #include #include #include -#include #include #include #include "ipsec_strerror.h" -#define ATOX(c) \ +#define ATOX(c) \ (isdigit(c) ? (c - '0') : (isupper(c) ? (c - 'A' + 10) : (c - 'a' + 10) )) static caddr_t pbuf = NULL; /* sadb_x_policy buffer */ static int tlen = 0; /* total length of pbuf */ static int offset = 0; /* offset of pbuf */ -static int p_dir, p_type, p_protocol, p_mode, p_level; +static int p_dir, p_type, p_protocol, p_mode, p_level, p_reqid; static struct sockaddr *p_src = NULL; static struct sockaddr *p_dst = NULL; +struct _val; extern void yyerror __P((char *msg)); -static struct sockaddr *parse_sockaddr __P((/*struct _val *buf*/)); +static struct sockaddr *parse_sockaddr __P((struct _val *buf)); static int rule_check __P((void)); static int init_x_policy __P((void)); static int set_x_request __P((struct sockaddr *src, struct sockaddr *dst)); static int set_sockaddr __P((struct sockaddr *addr)); static void policy_parse_request_init __P((void)); static caddr_t policy_parse __P((char *msg, int msglen)); extern void __policy__strbuffer__init__ __P((char *msg)); -extern int yyparse(); -extern int yylex(); +extern int yyparse __P((void)); +extern int yylex __P((void)); %} %union { u_int num; struct _val { int len; char *buf; } val; } -%token DIR ACTION PROTOCOL MODE LEVEL +%token DIR ACTION PROTOCOL MODE LEVEL LEVEL_SPECIFY %token IPADDRESS %token ME ANY %token SLASH HYPHEN %type DIR ACTION PROTOCOL MODE LEVEL -%type IPADDRESS +%type IPADDRESS LEVEL_SPECIFY %% policy_spec : DIR ACTION { p_dir = $1; p_type = $2; if (init_x_policy()) return -1; } rules + | DIR + { + p_dir = $1; + p_type = 0; /* ignored it by kernel */ + + if (init_x_policy()) + return -1; + } ; rules : /*NOTHING*/ | rules rule { if (rule_check() < 0) return -1; if (set_x_request(p_src, p_dst) < 0) return -1; policy_parse_request_init(); } ; rule : protocol SLASH mode SLASH addresses SLASH level | protocol SLASH mode SLASH addresses SLASH | protocol SLASH mode SLASH addresses | protocol SLASH mode SLASH | protocol SLASH mode SLASH SLASH level | protocol SLASH mode | protocol SLASH { - ipsec_errcode = EIPSEC_FEW_ARGUMENTS; + __ipsec_errcode = EIPSEC_FEW_ARGUMENTS; return -1; } | protocol { - ipsec_errcode = EIPSEC_FEW_ARGUMENTS; + __ipsec_errcode = EIPSEC_FEW_ARGUMENTS; return -1; } ; protocol : PROTOCOL { p_protocol = $1; } ; mode : MODE { p_mode = $1; } ; level - : LEVEL { p_level = $1; } + : LEVEL { + p_level = $1; + p_reqid = 0; + } + | LEVEL_SPECIFY { + p_level = IPSEC_LEVEL_UNIQUE; + p_reqid = atol($1.buf); /* atol() is good. */ + } ; addresses : IPADDRESS { p_src = parse_sockaddr(&$1); if (p_src == NULL) return -1; } HYPHEN IPADDRESS { p_dst = parse_sockaddr(&$4); if (p_dst == NULL) return -1; } | ME HYPHEN ANY { if (p_dir != IPSEC_DIR_OUTBOUND) { - ipsec_errcode = EIPSEC_INVAL_DIR; + __ipsec_errcode = EIPSEC_INVAL_DIR; return -1; } } | ANY HYPHEN ME { if (p_dir != IPSEC_DIR_INBOUND) { - ipsec_errcode = EIPSEC_INVAL_DIR; + __ipsec_errcode = EIPSEC_INVAL_DIR; return -1; } } /* | ME HYPHEN ME */ ; %% void yyerror(msg) char *msg; { - fprintf(stderr, "%s\n", msg); + extern char *__libipsecyytext; /*XXX*/ + fprintf(stderr, "libipsec: %s while parsing \"%s\"\n", + msg, __libipsecyytext); + return; } static struct sockaddr * parse_sockaddr(buf) struct _val *buf; { struct addrinfo hints, *res; char *serv = NULL; int error; struct sockaddr *newaddr = NULL; memset(&hints, 0, sizeof(hints)); hints.ai_family = PF_UNSPEC; hints.ai_flags = AI_NUMERICHOST; error = getaddrinfo(buf->buf, serv, &hints, &res); - if (error != 0 || res->ai_addr == NULL) { - ipsec_set_strerror(error == EAI_SYSTEM ? - gai_strerror(error) : strerror(errno)); + if (error != 0) { + yyerror("invalid IP address"); + __ipsec_set_strerror(gai_strerror(error)); return NULL; } if (res->ai_addr == NULL) { - ipsec_set_strerror(gai_strerror(error)); + yyerror("invalid IP address"); + __ipsec_set_strerror(gai_strerror(error)); return NULL; } newaddr = malloc(res->ai_addr->sa_len); if (newaddr == NULL) { - ipsec_errcode = EIPSEC_NO_BUFS; + __ipsec_errcode = EIPSEC_NO_BUFS; freeaddrinfo(res); return NULL; } memcpy(newaddr, res->ai_addr, res->ai_addr->sa_len); - /* - * XXX: If the scope of the destination is link-local, - * embed the scope-id(in this case, interface index) - * into the address. - */ - if (newaddr->sa_family == AF_INET6) { - struct sockaddr_in6 *sin6; - - sin6 = (struct sockaddr_in6 *)newaddr; - if(IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) && - sin6->sin6_scope_id != 0) - *(u_short *)&sin6->sin6_addr.s6_addr[2] = - htons(sin6->sin6_scope_id & 0xffff); - } - freeaddrinfo(res); - ipsec_errcode = EIPSEC_NO_ERROR; + __ipsec_errcode = EIPSEC_NO_ERROR; return newaddr; } static int rule_check() { if (p_type == IPSEC_POLICY_IPSEC) { if (p_protocol == IPPROTO_IP) { - ipsec_errcode = EIPSEC_NO_PROTO; + __ipsec_errcode = EIPSEC_NO_PROTO; return -1; } if (p_mode != IPSEC_MODE_TRANSPORT && p_mode != IPSEC_MODE_TUNNEL) { - ipsec_errcode = EIPSEC_INVAL_MODE; + __ipsec_errcode = EIPSEC_INVAL_MODE; return -1; } if (p_src == NULL && p_dst == NULL) { if (p_mode != IPSEC_MODE_TRANSPORT) { - ipsec_errcode = EIPSEC_INVAL_ADDRESS; + __ipsec_errcode = EIPSEC_INVAL_ADDRESS; return -1; } } else if (p_src->sa_family != p_dst->sa_family) { - ipsec_errcode = EIPSEC_FAMILY_MISMATCH; + __ipsec_errcode = EIPSEC_FAMILY_MISMATCH; return -1; } } - ipsec_errcode = EIPSEC_NO_ERROR; + __ipsec_errcode = EIPSEC_NO_ERROR; return 0; } static int init_x_policy() { struct sadb_x_policy *p; tlen = sizeof(struct sadb_x_policy); pbuf = malloc(tlen); if (pbuf == NULL) { - ipsec_errcode = EIPSEC_NO_BUFS; + __ipsec_errcode = EIPSEC_NO_BUFS; return -1; } p = (struct sadb_x_policy *)pbuf; p->sadb_x_policy_len = 0; /* must update later */ p->sadb_x_policy_exttype = SADB_X_EXT_POLICY; p->sadb_x_policy_type = p_type; p->sadb_x_policy_dir = p_dir; p->sadb_x_policy_reserved = 0; offset = tlen; - ipsec_errcode = EIPSEC_NO_ERROR; + __ipsec_errcode = EIPSEC_NO_ERROR; return 0; } static int set_x_request(src, dst) struct sockaddr *src, *dst; { struct sadb_x_ipsecrequest *p; int reqlen; reqlen = sizeof(*p) + (src ? src->sa_len : 0) + (dst ? dst->sa_len : 0); tlen += reqlen; /* increment to total length */ pbuf = realloc(pbuf, tlen); if (pbuf == NULL) { - ipsec_errcode = EIPSEC_NO_BUFS; + __ipsec_errcode = EIPSEC_NO_BUFS; return -1; } p = (struct sadb_x_ipsecrequest *)&pbuf[offset]; p->sadb_x_ipsecrequest_len = reqlen; p->sadb_x_ipsecrequest_proto = p_protocol; p->sadb_x_ipsecrequest_mode = p_mode; p->sadb_x_ipsecrequest_level = p_level; + p->sadb_x_ipsecrequest_reqid = p_reqid; offset += sizeof(*p); if (set_sockaddr(src) || set_sockaddr(dst)) return -1; - ipsec_errcode = EIPSEC_NO_ERROR; + __ipsec_errcode = EIPSEC_NO_ERROR; return 0; } static int set_sockaddr(addr) struct sockaddr *addr; { if (addr == NULL) { - ipsec_errcode = EIPSEC_NO_ERROR; + __ipsec_errcode = EIPSEC_NO_ERROR; return 0; } /* tlen has already incremented */ memcpy(&pbuf[offset], addr, addr->sa_len); offset += addr->sa_len; - ipsec_errcode = EIPSEC_NO_ERROR; + __ipsec_errcode = EIPSEC_NO_ERROR; return 0; } static void policy_parse_request_init() { p_protocol = IPPROTO_IP; p_mode = IPSEC_MODE_ANY; p_level = IPSEC_LEVEL_DEFAULT; + p_reqid = 0; if (p_src != NULL) { free(p_src); p_src = NULL; } if (p_dst != NULL) { free(p_dst); p_dst = NULL; } return; } static caddr_t policy_parse(msg, msglen) char *msg; int msglen; { int error; pbuf = NULL; tlen = 0; /* initialize */ p_dir = IPSEC_DIR_INVALID; p_type = IPSEC_POLICY_DISCARD; policy_parse_request_init(); __policy__strbuffer__init__(msg); error = yyparse(); /* it must be set errcode. */ if (error) { if (pbuf != NULL) free(pbuf); return NULL; } /* update total length */ ((struct sadb_x_policy *)pbuf)->sadb_x_policy_len = PFKEY_UNIT64(tlen); - ipsec_errcode = EIPSEC_NO_ERROR; + __ipsec_errcode = EIPSEC_NO_ERROR; return pbuf; } caddr_t ipsec_set_policy(msg, msglen) char *msg; int msglen; { caddr_t policy; policy = policy_parse(msg, msglen); if (policy == NULL) { - if (ipsec_errcode == EIPSEC_NO_ERROR) - ipsec_errcode = EIPSEC_INVAL_ARGUMENT; + if (__ipsec_errcode == EIPSEC_NO_ERROR) + __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; return NULL; } - ipsec_errcode = EIPSEC_NO_ERROR; + __ipsec_errcode = EIPSEC_NO_ERROR; return policy; } Index: head/lib/libipsec/policy_token.l =================================================================== --- head/lib/libipsec/policy_token.l (revision 62582) +++ head/lib/libipsec/policy_token.l (revision 62583) @@ -1,137 +1,148 @@ +/* $FreeBSD$ */ +/* $KAME: policy_token.l,v 1.9 2000/05/07 05:25:03 itojun Exp $ */ + /* * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ %{ #include #include #include #include #include #include #include #include #include #include #include #include #include #include +#ifndef __NetBSD__ #include "y.tab.h" -#define yylval __libipsecyylval /* XXX */ +#else +#include "policy_parse.h" +#endif +#define yylval __libipsecyylval /* XXX */ + +int yylex __P((void)); %} %option noyywrap /* common section */ nl \n ws [ \t]+ digit [0-9] -letter [0-9A-Za-z] hexdigit [0-9A-Fa-f] special [()+\|\?\*,] dot \. comma \, hyphen \- colon \: slash \/ bcl \{ ecl \} blcl \[ elcl \] percent \% semi \; usec {dot}{digit}{1,6} comment \#.* ccomment "/*" bracketstring \<[^>]*\> quotedstring \"[^"]*\" decstring {digit}+ hexpair {hexdigit}{hexdigit} hexstring 0[xX]{hexdigit}+ octetstring {octet}({dot}{octet})+ -ipaddress [a-zA-Z0-9:\._][a-zA-Z0-9:\._]*(%{letter}{letter}+)? -name {letter}(({letter}|{digit}|{hyphen})*({letter}|{digit}))* -hostname {name}(({dot}{name})+{dot}?)? +ipaddress [a-zA-Z0-9:\._][a-zA-Z0-9:\._]*(%[a-zA-Z0-9]+)? %% in { yylval.num = IPSEC_DIR_INBOUND; return(DIR); } out { yylval.num = IPSEC_DIR_OUTBOUND; return(DIR); } discard { yylval.num = IPSEC_POLICY_DISCARD; return(ACTION); } none { yylval.num = IPSEC_POLICY_NONE; return(ACTION); } ipsec { yylval.num = IPSEC_POLICY_IPSEC; return(ACTION); } bypass { yylval.num = IPSEC_POLICY_BYPASS; return(ACTION); } entrust { yylval.num = IPSEC_POLICY_ENTRUST; return(ACTION); } esp { yylval.num = IPPROTO_ESP; return(PROTOCOL); } ah { yylval.num = IPPROTO_AH; return(PROTOCOL); } ipcomp { yylval.num = IPPROTO_IPCOMP; return(PROTOCOL); } transport { yylval.num = IPSEC_MODE_TRANSPORT; return(MODE); } tunnel { yylval.num = IPSEC_MODE_TUNNEL; return(MODE); } me { return(ME); } any { return(ANY); } default { yylval.num = IPSEC_LEVEL_DEFAULT; return(LEVEL); } use { yylval.num = IPSEC_LEVEL_USE; return(LEVEL); } require { yylval.num = IPSEC_LEVEL_REQUIRE; return(LEVEL); } +unique{colon}{decstring} { + yylval.val.len = strlen(yytext + 7); + yylval.val.buf = yytext + 7; + return(LEVEL_SPECIFY); + } unique { yylval.num = IPSEC_LEVEL_UNIQUE; return(LEVEL); } {slash} { return(SLASH); } {ipaddress} { yylval.val.len = strlen(yytext); - yylval.val.buf = strdup(yytext); + yylval.val.buf = yytext; return(IPADDRESS); } {hyphen} { return(HYPHEN); } {ws} { ; } {nl} { ; } %% + +void __policy__strbuffer__init__ __P((char *)); void __policy__strbuffer__init__(msg) char *msg; { YY_BUFFER_STATE yyb; yyb = (YY_BUFFER_STATE)yy_scan_string(msg); yy_switch_to_buffer(yyb); return; } Index: head/lib/libipsec/test-policy.c =================================================================== --- head/lib/libipsec/test-policy.c (revision 62582) +++ head/lib/libipsec/test-policy.c (revision 62583) @@ -1,179 +1,317 @@ +/* $FreeBSD$ */ +/* $KAME: test-policy.c,v 1.13 2000/05/07 05:25:03 itojun Exp $ */ + /* * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #include #include #include #include -#include #include #include #include #include #include #include #include +#include #include -char *requests[] = { -"must_error", /* error */ -"in ipsec must_error", /* error */ -"out ipsec esp/must_error", /* error */ -"out discard", -"out none", -"in entrust", -"out entrust", -"in bypass", /* may be error */ -"out ipsec esp", /* error */ -"in ipsec ah/transport", -"in ipsec ah/tunnel", /* error */ -"out ipsec ah/transport/", -"out ipsec ah/tunnel/", /* error */ -"in ipsec esp / transport / 10.0.0.1-10.0.0.2", -"in ipsec esp/tunnel/::1-::2", -"in ipsec esp/tunnel/10.0.0.1-::2", /* error */ -"in ipsec esp/tunnel/::1-::2/require", -"out ipsec ah/transport//use", -"out ipsec ah/transport esp/use", -"in ipsec ah/transport esp/tunnel", /* error */ -"in ipsec +struct req_t { + int result; /* expected result; 0:ok 1:ng */ + char *str; +} reqs[] = { +{ 0, "out ipsec" }, +{ 1, "must_error" }, +{ 1, "in ipsec must_error" }, +{ 1, "out ipsec esp/must_error" }, +{ 1, "out discard" }, +{ 1, "out none" }, +{ 0, "in entrust" }, +{ 0, "out entrust" }, +{ 1, "out ipsec esp" }, +{ 0, "in ipsec ah/transport" }, +{ 1, "in ipsec ah/tunnel" }, +{ 0, "out ipsec ah/transport/" }, +{ 1, "out ipsec ah/tunnel/" }, +{ 0, "in ipsec esp / transport / 10.0.0.1-10.0.0.2" }, +{ 0, "in ipsec esp/tunnel/::1-::2" }, +{ 1, "in ipsec esp/tunnel/10.0.0.1-::2" }, +{ 0, "in ipsec esp/tunnel/::1-::2/require" }, +{ 0, "out ipsec ah/transport//use" }, +{ 1, "out ipsec ah/transport esp/use" }, +{ 1, "in ipsec ah/transport esp/tunnel" }, +{ 0, "in ipsec ah/transport esp/tunnel/::1-::1" }, +{ 0, "in ipsec ah / transport - esp / tunnel / ::1-::2", -" -out ipsec -ah/transport/::1-::2 esp/tunnel/::3-::4/use ah/transport/::5-::6/require -ah/transport/::1-::2 esp/tunnel/::3-::4/use ah/transport/::5-::6/require -ah/transport/::1-::2 esp/tunnel/::3-::4/use ah/transport/::5-::6/require -", -"out ipsec esp/transport/fec0::10-fec0::11/use", + esp / tunnel / ::1-::2" }, +{ 0, "out ipsec + ah/transport/::1-::2 esp/tunnel/::3-::4/use ah/transport/::5-::6/require + ah/transport/::1-::2 esp/tunnel/::3-::4/use ah/transport/::5-::6/require + ah/transport/::1-::2 esp/tunnel/::3-::4/use ah/transport/::5-::6/require + " }, +{ 0, "out ipsec esp/transport/fec0::10-fec0::11/use" }, }; -int test(char *buf, int family); +int test1 __P((void)); +int test1sub1 __P((struct req_t *)); +int test1sub2 __P((char *, int)); +int test2 __P((void)); +int test2sub __P((int)); int main(ac, av) int ac; char **av; { - int do_setsockopt; - char *buf; - int i; + test1(); + test2(); - if (ac != 1) - do_setsockopt = 1; - else - do_setsockopt = 0; + exit(0); +} - for (i = 0; i < sizeof(requests)/sizeof(requests[0]); i++) { - printf("*** requests ***\n"); - printf("\t[%s]\n", requests[i]); +int +test1() +{ + int i; + int result; - buf = ipsec_set_policy(requests[i], strlen(requests[i])); - if (buf == NULL) { - printf("ipsec_set_policy: %s\n", ipsec_strerror()); - continue; + printf("TEST1\n"); + for (i = 0; i < sizeof(reqs)/sizeof(reqs[0]); i++) { + printf("#%d [%s]\n", i + 1, reqs[i].str); + + result = test1sub1(&reqs[i]); + if (result == 0 && reqs[i].result == 1) { + errx(1, "ERROR: expecting failure.\n"); + } else if (result == 1 && reqs[i].result == 0) { + errx(1, "ERROR: expecting success.\n"); } + } - printf("\tsetlen:%d\n", ipsec_get_policylen(buf)); + return 0; +} - if (do_setsockopt) { - printf("\tPF_INET:\n"); - test(buf, PF_INET); +int +test1sub1(req) + struct req_t *req; +{ + char *buf; - printf("\tPF_INET6:\n"); - test(buf, PF_INET6); - } else { - kdebug_sadb_x_policy((struct sadb_ext *)buf); - } + buf = ipsec_set_policy(req->str, strlen(req->str)); + if (buf == NULL) { + printf("ipsec_set_policy: %s\n", ipsec_strerror()); + return 1; + } + + if (test1sub2(buf, PF_INET) != 0 + || test1sub2(buf, PF_INET6) != 0) { free(buf); + return 1; } +#if 0 + kdebug_sadb_x_policy((struct sadb_ext *)buf); +#endif + free(buf); return 0; } int -test(policy, family) +test1sub2(policy, family) char *policy; int family; { - int so, proto, optname; + int so; + int proto = 0, optname = 0; int len; char getbuf[1024]; switch (family) { case PF_INET: proto = IPPROTO_IP; optname = IP_IPSEC_POLICY; break; case PF_INET6: proto = IPPROTO_IPV6; optname = IPV6_IPSEC_POLICY; break; } if ((so = socket(family, SOCK_DGRAM, 0)) < 0) err(1, "socket"); len = ipsec_get_policylen(policy); +#if 0 + printf("\tsetlen:%d\n", len); +#endif + if (setsockopt(so, proto, optname, policy, len) < 0) { - printf("error on setsockopt"); - goto end; + printf("fail to set sockopt; %s\n", strerror(errno)); + close(so); + return 1; } - len = sizeof(getbuf); memset(getbuf, 0, sizeof(getbuf)); + memcpy(getbuf, policy, sizeof(struct sadb_x_policy)); if (getsockopt(so, proto, optname, getbuf, &len) < 0) { - printf("error on getsockopt"); - goto end; + printf("fail to get sockopt; %s\n", strerror(errno)); + close(so); + return 1; } { char *buf = NULL; +#if 0 printf("\tgetlen:%d\n", len); +#endif if ((buf = ipsec_dump_policy(getbuf, NULL)) == NULL) { printf("%s\n", ipsec_strerror()); - goto end; - } else { - printf("\t[%s]\n", buf); - free(buf); + close(so); + return 1; } +#if 0 + printf("\t[%s]\n", buf); +#endif + free(buf); } - end: close (so); + return 0; +} +char addr[] = { + 28, 28, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, +}; + +int +test2() +{ + int so; + char *pol1 = "out ipsec"; + char *pol2 = "out ipsec ah/transport//use"; + char *sp1, *sp2; + int splen1, splen2; + int spid; + struct sadb_msg *m; + + printf("TEST2\n"); + if (getuid() != 0) + errx(1, "root privilege required.\n"); + + sp1 = ipsec_set_policy(pol1, strlen(pol1)); + splen1 = ipsec_get_policylen(sp1); + sp2 = ipsec_set_policy(pol2, strlen(pol2)); + splen2 = ipsec_get_policylen(sp2); + + if ((so = pfkey_open()) < 0) + errx(1, "ERROR: %s\n", ipsec_strerror()); + + printf("spdflush()\n"); + if (pfkey_send_spdflush(so) < 0) + errx(1, "ERROR: %s\n", ipsec_strerror()); + m = pfkey_recv(so); + free(m); + + printf("spdsetidx()\n"); + if (pfkey_send_spdsetidx(so, (struct sockaddr *)addr, 128, + (struct sockaddr *)addr, 128, + 255, sp1, splen1, 0) < 0) + errx(1, "ERROR: %s\n", ipsec_strerror()); + m = pfkey_recv(so); + free(m); + + printf("spdupdate()\n"); + if (pfkey_send_spdupdate(so, (struct sockaddr *)addr, 128, + (struct sockaddr *)addr, 128, + 255, sp2, splen2, 0) < 0) + errx(1, "ERROR: %s\n", ipsec_strerror()); + m = pfkey_recv(so); + free(m); + + printf("spddelete()\n"); + if (pfkey_send_spddelete(so, (struct sockaddr *)addr, 128, + (struct sockaddr *)addr, 128, + 255, sp1, splen1, 0) < 0) + errx(1, "ERROR: %s\n", ipsec_strerror()); + m = pfkey_recv(so); + free(m); + + printf("spdadd()\n"); + if (pfkey_send_spdadd(so, (struct sockaddr *)addr, 128, + (struct sockaddr *)addr, 128, + 255, sp2, splen2, 0) < 0) + errx(1, "ERROR: %s\n", ipsec_strerror()); + spid = test2sub(so); + + printf("spdget(%u)\n", spid); + if (pfkey_send_spdget(so, spid) < 0) + errx(1, "ERROR: %s\n", ipsec_strerror()); + m = pfkey_recv(so); + free(m); + + printf("spddelete2()\n"); + if (pfkey_send_spddelete2(so, spid) < 0) + errx(1, "ERROR: %s\n", ipsec_strerror()); + m = pfkey_recv(so); + free(m); + + /* expecting failure */ + printf("spdupdate()\n"); + if (pfkey_send_spdupdate(so, (struct sockaddr *)addr, 128, + (struct sockaddr *)addr, 128, + 255, sp2, splen2, 0) == 0) { + errx(1, "ERROR: expecting failure.\n"); + } + return 0; +} + +int +test2sub(so) + int so; +{ + struct sadb_msg *msg; + caddr_t mhp[SADB_EXT_MAX + 1]; + + if ((msg = pfkey_recv(so)) == NULL) + errx(1, "ERROR: pfkey_recv failure.\n"); + if (pfkey_align(msg, mhp) < 0) + errx(1, "ERROR: pfkey_align failure.\n"); + + return ((struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY])->sadb_x_policy_id; } Index: head/sbin/setkey/Makefile =================================================================== --- head/sbin/setkey/Makefile (revision 62582) +++ head/sbin/setkey/Makefile (revision 62583) @@ -1,58 +1,65 @@ # Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # 3. Neither the name of the project nor the names of its contributors # may be used to endorse or promote products derived from this software # without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # $FreeBSD$ PROG= setkey SRCS= setkey.c parse.y token.l CFLAGS+=-g +CFLAGS+=-I${.CURDIR}/../../lib/libipsec DPADD= ${LIBL} ${LIBY} LDADD= -ll -ly CLEANFILES+= y.tab.c y.tab.h key_test.o keytest YFLAGS+=-d + +# libpfkey. +# ipsec_strerror.c is for avoiding shlib reference to non-exported function. +.PATH: ${.CURDIR}/../../lib/libipsec ${.CURDIR}/../../sys/netkey +SRCS+= pfkey.c pfkey_dump.c key_debug.c ipsec_strerror.c +CFLAGS+=-I${.CURDIR}/../../lib/libipsec -I${.CURDIR}/../../sys/netkey SCRIPTS= scriptdump BINOWN = root BINGRP = bin BINMODE = 555 all: ${PROG} scriptdump SRCS+=y.tab.h y.tab.h: parse.y CFLAGS+=-DIPSEC_DEBUG -DINET6 -DYY_NO_UNPUT -I${.OBJDIR} DPADD+= ${LIBIPSEC} LDADD+= -lipsec CLEANFILES+= scriptdump y.tab.h MAN8= setkey.8 LOCALPREFIX= /usr/local scriptdump: scriptdump.pl sed -e 's#@LOCALPREFIX@#${LOCALPREFIX}#' < $> > scriptdump .include Index: head/sbin/setkey/parse.y =================================================================== --- head/sbin/setkey/parse.y (revision 62582) +++ head/sbin/setkey/parse.y (revision 62583) @@ -1,787 +1,902 @@ +/* $FreeBSD$ */ +/* $KAME: parse.y,v 1.29 2000/06/10 14:17:44 sakane Exp $ */ + /* * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ -/* KAME $Id: parse.y,v 1.7 1999/10/27 17:08:57 sakane Exp $ */ %{ #include #include #include #include #include #include #include #include #include #include #include #include +#include #include #include -#include +#include "libpfkey.h" #include "vchar.h" #define ATOX(c) \ (isdigit(c) ? (c - '0') : (isupper(c) ? (c - 'A' + 10) : (c - 'a' + 10) )) -u_int p_type; -u_int32_t p_spi; -struct sockaddr *p_src, *p_dst; -u_int p_prefs, p_prefd, p_upper; -u_int p_satype, p_ext, p_alg_enc, p_alg_auth, p_replay, p_mode; -u_int p_key_enc_len, p_key_auth_len; -caddr_t p_key_enc, p_key_auth; -time_t p_lt_hard, p_lt_soft; +u_int p_type; +u_int32_t p_spi; +struct sockaddr *p_src, *p_dst; +u_int p_prefs, p_prefd, p_upper; +u_int p_satype, p_ext, p_alg_enc, p_alg_auth, p_replay, p_mode; +u_int32_t p_reqid; +u_int p_key_enc_len, p_key_auth_len; +caddr_t p_key_enc, p_key_auth; +time_t p_lt_hard, p_lt_soft; -u_int p_policy_len; -char *p_policy; +u_int p_policy_len; +char *p_policy; /* temporary buffer */ -static struct sockaddr *pp_addr; -static u_int pp_prefix; -static u_int pp_port; -static caddr_t pp_key; +static struct sockaddr *pp_addr; +static u_int pp_prefix; +static u_int pp_port; +static caddr_t pp_key; -extern u_char m_buf[BUFSIZ]; -extern int m_len; -extern char cmdarg[8192]; -extern int f_debug; +extern u_char m_buf[BUFSIZ]; +extern int m_len; +extern char cmdarg[8192]; +extern int f_debug; -int setkeymsg __P((void)); -static int setvarbuf __P((int *, struct sadb_ext *, int, caddr_t, int)); -void parse_init __P((void)); -void free_buffer __P((void)); +int setkeymsg __P((void)); +static struct addrinfo *parse_addr __P((char *, char *, int)); +static int setvarbuf __P((int *, struct sadb_ext *, int, caddr_t, int)); +void parse_init __P((void)); +void free_buffer __P((void)); -extern int setkeymsg __P((void)); -extern int sendkeymsg __P((void)); +extern int setkeymsg __P((void)); +extern int sendkeymsg __P((void)); -extern int yylex __P((void)); -extern void yyerror __P((char *)); +extern int yylex __P((void)); +extern void yyfatal __P((const char *)); +extern void yyerror __P((const char *)); %} %union { unsigned long num; vchar_t val; } %token EOT %token ADD GET DELETE FLUSH DUMP -%token IP4_ADDRESS IP6_ADDRESS PREFIX PORT PORTANY +%token ADDRESS PREFIX PORT PORTANY %token UP_PROTO PR_ESP PR_AH PR_IPCOMP %token F_PROTOCOL F_AUTH F_ENC F_REPLAY F_COMP F_RAWCPI -%token F_MODE MODE -%token F_EXT EXTENSION +%token F_MODE MODE F_REQID +%token F_EXT EXTENSION NOCYCLICSEQ %token ALG_AUTH ALG_ENC ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_COMP %token F_LIFETIME_HARD F_LIFETIME_SOFT %token DECSTRING QUOTEDSTRING HEXSTRING ANY /* SPD management */ %token SPDADD SPDDELETE SPDDUMP SPDFLUSH %token F_POLICY PL_REQUESTS +%type PORT PREFIX EXTENSION MODE +%type UP_PROTO PR_ESP PR_AH PR_IPCOMP +%type ALG_AUTH ALG_ENC ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_COMP +%type DECSTRING +%type ADDRESS PL_REQUESTS +%type key_string policy_requests +%type QUOTEDSTRING HEXSTRING + %% commands : /*NOTHING*/ | commands command { if (f_debug) { printf("cmdarg:\n%s\n", cmdarg); } else { setkeymsg(); sendkeymsg(); } free_buffer(); parse_init(); } ; command : add_command | get_command | delete_command | flush_command | dump_command | spdadd_command | spddelete_command | spddump_command | spdflush_command ; /* commands concerned with management, there is in tail of this file. */ /* add command */ add_command : ADD { p_type = SADB_ADD; } sa_selector_spec extension_spec algorithm_spec EOT ; /* delete */ delete_command : DELETE { p_type = SADB_DELETE; } - sa_selector_spec extension_spec EOT + sa_selector_spec extension_spec + { + if (p_mode != IPSEC_MODE_ANY) + yyerror("WARNING: mode is obsoleted."); + } + EOT ; /* get command */ get_command : GET { p_type = SADB_GET; } - sa_selector_spec extension_spec EOT + sa_selector_spec extension_spec + { + if (p_mode != IPSEC_MODE_ANY) + yyerror("WARNING: mode is obsoleted."); + } + EOT ; /* flush */ flush_command : FLUSH { p_type = SADB_FLUSH; } protocol_spec EOT ; /* dump */ dump_command : DUMP { p_type = SADB_DUMP; } protocol_spec EOT ; /* sa_selector_spec */ sa_selector_spec : ipaddress { p_src = pp_addr; } ipaddress { p_dst = pp_addr; } protocol_spec spi ; protocol_spec : /*NOTHING*/ { p_satype = SADB_SATYPE_UNSPEC; } | PR_ESP { p_satype = SADB_SATYPE_ESP; - if ($1.num == 1) + if ($1 == 1) p_ext |= SADB_X_EXT_OLD; else p_ext &= ~SADB_X_EXT_OLD; } | PR_AH { p_satype = SADB_SATYPE_AH; - if ($1.num == 1) + if ($1 == 1) p_ext |= SADB_X_EXT_OLD; else p_ext &= ~SADB_X_EXT_OLD; } | PR_IPCOMP { p_satype = SADB_X_SATYPE_IPCOMP; } ; spi - : DECSTRING { p_spi = $1.num; } + : DECSTRING { p_spi = $1; } | HEXSTRING { caddr_t bp; - caddr_t yp = $1.val.buf; + caddr_t yp = $1.buf; char buf0[4], buf[4]; int i, j; /* sanity check */ - if ($1.val.len > 4) { + if ($1.len > 4) { yyerror("SPI too big."); - free($1.val.buf); + free($1.buf); return -1; } bp = buf0; while (*yp) { *bp = (ATOX(yp[0]) << 4) | ATOX(yp[1]); yp += 2, bp++; } /* initialize */ for (i = 0; i < 4; i++) buf[i] = 0; - for (j = $1.val.len - 1, i = 3; j >= 0; j--, i--) + for (j = $1.len - 1, i = 3; j >= 0; j--, i--) buf[i] = buf0[j]; /* XXX: endian */ p_spi = ntohl(*(u_int32_t *)buf); - free($1.val.buf); + free($1.buf); } ; algorithm_spec : esp_spec | ah_spec | ipcomp_spec ; esp_spec : F_ENC enc_alg enc_key F_AUTH auth_alg auth_key | F_ENC enc_alg enc_key ; ah_spec : F_AUTH auth_alg auth_key ; ipcomp_spec - : F_COMP ALG_COMP { p_alg_enc = $2.num; } - | F_COMP ALG_COMP { p_alg_enc = $2.num; } + : F_COMP ALG_COMP { p_alg_enc = $2; } + | F_COMP ALG_COMP { p_alg_enc = $2; } F_RAWCPI { p_ext |= SADB_X_EXT_RAWCPI; } ; enc_alg - : ALG_ENC { p_alg_enc = $1.num; } + : ALG_ENC { p_alg_enc = $1; } | ALG_ENC_DESDERIV { - p_alg_enc = $1.num; + p_alg_enc = $1; if (p_ext & SADB_X_EXT_OLD) { yyerror("algorithm mismatched."); return -1; } p_ext |= SADB_X_EXT_DERIV; } | ALG_ENC_DES32IV { - p_alg_enc = $1.num; + p_alg_enc = $1; if (!(p_ext & SADB_X_EXT_OLD)) { yyerror("algorithm mismatched."); return -1; } p_ext |= SADB_X_EXT_IV4B; } ; enc_key : /*NOTHING*/ { if (p_alg_enc != SADB_EALG_NULL) { yyerror("no key found."); return -1; } } | key_string { - p_key_enc_len = $1.val.len; + p_key_enc_len = $1.len; p_key_enc = pp_key; if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT, p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) { yyerror(ipsec_strerror()); return -1; } } ; auth_alg - : ALG_AUTH { p_alg_auth = $1.num; } + : ALG_AUTH { p_alg_auth = $1; } ; auth_key : /*NOTHING*/ { if (p_alg_auth != SADB_AALG_NULL) { yyerror("no key found."); return -1; } } | key_string { - p_key_auth_len = $1.val.len; + p_key_auth_len = $1.len; p_key_auth = pp_key; if (ipsec_check_keylen(SADB_EXT_SUPPORTED_AUTH, p_alg_auth, PFKEY_UNUNIT64(p_key_auth_len)) < 0) { yyerror(ipsec_strerror()); return -1; } } ; key_string : QUOTEDSTRING { - pp_key = $1.val.buf; + pp_key = $1.buf; /* free pp_key later */ } | HEXSTRING { caddr_t bp; - caddr_t yp = $1.val.buf; + caddr_t yp = $1.buf; - if ((pp_key = malloc($1.val.len)) == 0) { - free($1.val.buf); - yyerror(strerror(errno)); + if ((pp_key = malloc($1.len)) == 0) { + free($1.buf); + yyerror("not enough core"); return -1; } - memset(pp_key, 0, $1.val.len); + memset(pp_key, 0, $1.len); bp = pp_key; while (*yp) { *bp = (ATOX(yp[0]) << 4) | ATOX(yp[1]); yp += 2, bp++; } - free($1.val.buf); + free($1.buf); } ; extension_spec : /*NOTHING*/ | extension_spec extension ; extension - : F_EXT EXTENSION { p_ext |= $1.num; } - | F_MODE MODE { p_mode = $2.num; } + : F_EXT EXTENSION { p_ext |= $2; } + | F_EXT NOCYCLICSEQ { p_ext &= ~SADB_X_EXT_CYCSEQ; } + | F_MODE MODE { p_mode = $2; } | F_MODE ANY { p_mode = IPSEC_MODE_ANY; } + | F_REQID DECSTRING { p_reqid = $2; } | F_REPLAY DECSTRING { if (p_ext & SADB_X_EXT_OLD) { yyerror("replay prevention " "only use on new spec."); return -1; } - p_replay = $2.num; + p_replay = $2; } - | F_LIFETIME_HARD DECSTRING { p_lt_hard = $2.num; } - | F_LIFETIME_SOFT DECSTRING { p_lt_soft = $2.num; } + | F_LIFETIME_HARD DECSTRING { p_lt_hard = $2; } + | F_LIFETIME_SOFT DECSTRING { p_lt_soft = $2; } ; /* definition about command for SPD management */ /* spdadd */ spdadd_command : SPDADD { p_type = SADB_X_SPDADD; p_satype = SADB_SATYPE_UNSPEC; } sp_selector_spec policy_spec EOT ; spddelete_command: SPDDELETE { p_type = SADB_X_SPDDELETE; p_satype = SADB_SATYPE_UNSPEC; } - sp_selector_spec EOT + sp_selector_spec policy_spec EOT ; spddump_command: SPDDUMP { p_type = SADB_X_SPDDUMP; p_satype = SADB_SATYPE_UNSPEC; } EOT ; spdflush_command: SPDFLUSH { p_type = SADB_X_SPDFLUSH; p_satype = SADB_SATYPE_UNSPEC; } EOT ; /* sp_selector_spec */ sp_selector_spec : ipaddress { p_src = pp_addr; } prefix { p_prefs = pp_prefix; } - port { _INPORTBYSA(p_src) = htons(pp_port); } + port + { + switch (p_src->sa_family) { + case AF_INET: + ((struct sockaddr_in *)p_src)->sin_port = + htons(pp_port); + break; +#ifdef INET6 + case AF_INET6: + ((struct sockaddr_in6 *)p_src)->sin6_port = + htons(pp_port); + break; +#endif + default: + exit(1); /*XXX*/ + } + } ipaddress { p_dst = pp_addr; } prefix { p_prefd = pp_prefix; } - port { _INPORTBYSA(p_dst) = htons(pp_port); } + port + { + switch (p_dst->sa_family) { + case AF_INET: + ((struct sockaddr_in *)p_dst)->sin_port = + htons(pp_port); + break; +#ifdef INET6 + case AF_INET6: + ((struct sockaddr_in6 *)p_dst)->sin6_port = + htons(pp_port); + break; +#endif + default: + exit(1); /*XXX*/ + } + } upper_spec + { + /* XXX is it something userland should check? */ +#if 0 + switch (p_upper) { + case IPPROTO_ICMP: + case IPPROTO_ICMPV6: + if (_INPORTBYSA(p_src) != IPSEC_PORT_ANY + || _INPORTBYSA(p_dst) != IPSEC_PORT_ANY) { + yyerror("port number must be \"any\"."); + return -1; + } + if ((pp_addr->sa_family == AF_INET6 + && p_upper == IPPROTO_ICMP) + || (pp_addr->sa_family == AF_INET + && p_upper == IPPROTO_ICMPV6)) { + yyerror("upper layer protocol " + "mismatched.\n"); + return -1; + } + break; + default: + break; + } +#endif + } ; ipaddress - : IP4_ADDRESS + : ADDRESS { - struct sockaddr_in *in; - u_int sa_len = $1.val.len; + struct addrinfo *res; - if ((in = (struct sockaddr_in *)malloc(sa_len)) == 0) { - yyerror(strerror(errno)); - free($1.val.buf); + res = parse_addr($1.buf, NULL, AI_NUMERICHOST); + if (res == NULL) { + free($1.buf); return -1; } - memset((caddr_t)in, 0, sa_len); - - in->sin_family = PF_INET; - in->sin_len = sa_len; - in->sin_port = IPSEC_PORT_ANY; - (void)inet_pton(PF_INET, $1.val.buf, &in->sin_addr); - - pp_addr = (struct sockaddr *)in; - free($1.val.buf); - } - | IP6_ADDRESS - { -#ifdef INET6 - struct sockaddr_in6 *in6; - u_int sa_len = $1.val.len; - struct addrinfo hints, *res; - int ret_gai; - - if ((in6 = (struct sockaddr_in6 *)malloc(sa_len)) == 0) { - free($1.val.buf); - yyerror(strerror(errno)); - return -1; + pp_addr = (struct sockaddr *)malloc(res->ai_addrlen); + if (!pp_addr) { + yyerror("not enough core"); + goto end; } - memset((caddr_t)in6, 0, sa_len); - bzero(&hints, sizeof(struct addrinfo)); - hints.ai_flags = AI_NUMERICHOST; - hints.ai_family = AF_INET6; - ret_gai = getaddrinfo($1.val.buf, NULL, &hints, &res); - if (ret_gai) { - free($1.val.buf); - free(in6); - yyerror(gai_strerror(ret_gai)); - if (ret_gai == EAI_SYSTEM) - yyerror(strerror(errno)); - return -1; - } - (void)memcpy(in6, res->ai_addr, res->ai_addrlen); - - /* - * XXX: If the scope of the destination is link-local, - * embed the scope-id(in this case, interface index) - * into the address. - */ - if (IN6_IS_ADDR_LINKLOCAL(&in6->sin6_addr) && - in6->sin6_scope_id != 0) - *(u_short *)&in6->sin6_addr.s6_addr[2] = - htons(in6->sin6_scope_id & 0xffff); - + memcpy(pp_addr, res->ai_addr, res->ai_addrlen); + end: freeaddrinfo(res); - - pp_addr = (struct sockaddr *)in6; -#else - yyerror("IPv6 address not supported"); -#endif - free($1.val.buf); + free($1.buf); } ; prefix : /*NOTHING*/ { pp_prefix = ~0; } - | PREFIX { pp_prefix = $1.num; } + | PREFIX { pp_prefix = $1; } ; port : /*NOTHING*/ { pp_port = IPSEC_PORT_ANY; } - | PORT { pp_port = $1.num; } + | PORT { pp_port = $1; } | PORTANY { pp_port = IPSEC_PORT_ANY; } ; upper_spec - : DECSTRING { p_upper = $1.num; } - | UP_PROTO { p_upper = $1.num; } + : DECSTRING { p_upper = $1; } + | UP_PROTO { p_upper = $1; } | PR_ESP { p_upper = IPPROTO_ESP; }; | PR_AH { p_upper = IPPROTO_AH; }; | PR_IPCOMP { p_upper = IPPROTO_IPCOMP; }; | ANY { p_upper = IPSEC_ULPROTO_ANY; } ; policy_spec : F_POLICY policy_requests { - p_policy = ipsec_set_policy($2.val.buf, $2.val.len); + p_policy = ipsec_set_policy($2.buf, $2.len); if (p_policy == NULL) { - free($2.val.buf); + free($2.buf); p_policy = NULL; yyerror(ipsec_strerror()); return -1; } p_policy_len = ipsec_get_policylen(p_policy); - free($2.val.buf); + free($2.buf); } ; -policy_requests: - /*NOTHING*/ - | PL_REQUESTS { $$ = $1; } +policy_requests + : PL_REQUESTS { $$ = $1; } ; %% int setkeymsg() { struct sadb_msg m_msg; m_msg.sadb_msg_version = PF_KEY_V2; m_msg.sadb_msg_type = p_type; m_msg.sadb_msg_errno = 0; m_msg.sadb_msg_satype = p_satype; - m_msg.sadb_msg_mode = p_mode; m_msg.sadb_msg_reserved = 0; m_msg.sadb_msg_seq = 0; m_msg.sadb_msg_pid = getpid(); m_len = sizeof(struct sadb_msg); memcpy(m_buf, &m_msg, m_len); switch (p_type) { case SADB_FLUSH: case SADB_DUMP: break; case SADB_ADD: /* set encryption algorithm, if present. */ if (p_satype != SADB_X_SATYPE_IPCOMP && p_alg_enc != SADB_EALG_NONE) { struct sadb_key m_key; m_key.sadb_key_len = PFKEY_UNIT64(sizeof(m_key) + PFKEY_ALIGN8(p_key_enc_len)); m_key.sadb_key_exttype = SADB_EXT_KEY_ENCRYPT; m_key.sadb_key_bits = p_key_enc_len * 8; m_key.sadb_key_reserved = 0; setvarbuf(&m_len, (struct sadb_ext *)&m_key, sizeof(m_key), (caddr_t)p_key_enc, p_key_enc_len); } /* set authentication algorithm, if present. */ if (p_alg_auth != SADB_AALG_NONE) { struct sadb_key m_key; m_key.sadb_key_len = PFKEY_UNIT64(sizeof(m_key) + PFKEY_ALIGN8(p_key_auth_len)); m_key.sadb_key_exttype = SADB_EXT_KEY_AUTH; m_key.sadb_key_bits = p_key_auth_len * 8; m_key.sadb_key_reserved = 0; setvarbuf(&m_len, (struct sadb_ext *)&m_key, sizeof(m_key), (caddr_t)p_key_auth, p_key_auth_len); } /* set lifetime for HARD */ if (p_lt_hard != 0) { struct sadb_lifetime m_lt; u_int len = sizeof(struct sadb_lifetime); m_lt.sadb_lifetime_len = PFKEY_UNIT64(len); m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD; m_lt.sadb_lifetime_allocations = 0; m_lt.sadb_lifetime_bytes = 0; m_lt.sadb_lifetime_addtime = p_lt_hard; m_lt.sadb_lifetime_usetime = 0; memcpy(m_buf + m_len, &m_lt, len); m_len += len; } /* set lifetime for SOFT */ if (p_lt_soft != 0) { struct sadb_lifetime m_lt; u_int len = sizeof(struct sadb_lifetime); m_lt.sadb_lifetime_len = PFKEY_UNIT64(len); m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_SOFT; m_lt.sadb_lifetime_allocations = 0; m_lt.sadb_lifetime_bytes = 0; m_lt.sadb_lifetime_addtime = p_lt_soft; m_lt.sadb_lifetime_usetime = 0; memcpy(m_buf + m_len, &m_lt, len); m_len += len; } /* FALLTHROUGH */ case SADB_DELETE: case SADB_GET: { struct sadb_sa m_sa; + struct sadb_x_sa2 m_sa2; struct sadb_address m_addr; u_int len; len = sizeof(struct sadb_sa); m_sa.sadb_sa_len = PFKEY_UNIT64(len); m_sa.sadb_sa_exttype = SADB_EXT_SA; m_sa.sadb_sa_spi = htonl(p_spi); m_sa.sadb_sa_replay = p_replay; m_sa.sadb_sa_state = 0; m_sa.sadb_sa_auth = p_alg_auth; m_sa.sadb_sa_encrypt = p_alg_enc; m_sa.sadb_sa_flags = p_ext; memcpy(m_buf + m_len, &m_sa, len); m_len += len; + len = sizeof(struct sadb_x_sa2); + m_sa2.sadb_x_sa2_len = PFKEY_UNIT64(len); + m_sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2; + m_sa2.sadb_x_sa2_mode = p_mode; + m_sa2.sadb_x_sa2_reqid = p_reqid; + + memcpy(m_buf + m_len, &m_sa2, len); + m_len += len; + /* set src */ m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + PFKEY_ALIGN8(p_src->sa_len)); m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC; m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY; - m_addr.sadb_address_prefixlen = - _INALENBYAF(p_src->sa_family) << 3; + switch (p_src->sa_family) { + case AF_INET: + m_addr.sadb_address_prefixlen = + sizeof(struct in_addr) << 3; + break; +#ifdef INET6 + case AF_INET6: + m_addr.sadb_address_prefixlen = + sizeof(struct in6_addr) << 3; + break; +#endif + default: + yyerror("unsupported address family"); + exit(1); /*XXX*/ + } m_addr.sadb_address_reserved = 0; setvarbuf(&m_len, (struct sadb_ext *)&m_addr, sizeof(m_addr), (caddr_t)p_src, p_src->sa_len); /* set dst */ m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + PFKEY_ALIGN8(p_dst->sa_len)); m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST; m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY; - m_addr.sadb_address_prefixlen = - _INALENBYAF(p_dst->sa_family) << 3; + switch (p_dst->sa_family) { + case AF_INET: + m_addr.sadb_address_prefixlen = + sizeof(struct in_addr) << 3; + break; +#ifdef INET6 + case AF_INET6: + m_addr.sadb_address_prefixlen = + sizeof(struct in6_addr) << 3; + break; +#endif + default: + yyerror("unsupported address family"); + exit(1); /*XXX*/ + } m_addr.sadb_address_reserved = 0; setvarbuf(&m_len, (struct sadb_ext *)&m_addr, sizeof(m_addr), (caddr_t)p_dst, p_dst->sa_len); } break; /* for SPD management */ case SADB_X_SPDFLUSH: case SADB_X_SPDDUMP: break; case SADB_X_SPDADD: + case SADB_X_SPDDELETE: { + struct sadb_address m_addr; + u_int8_t plen; + memcpy(m_buf + m_len, p_policy, p_policy_len); m_len += p_policy_len; free(p_policy); p_policy = NULL; - } - /* FALLTHROUGH */ - case SADB_X_SPDDELETE: - { - struct sadb_address m_addr; - /* set src */ m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + PFKEY_ALIGN8(p_src->sa_len)); m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC; m_addr.sadb_address_proto = p_upper; + switch (p_src->sa_family) { + case AF_INET: + plen = sizeof(struct in_addr) << 3; + break; +#ifdef INET6 + case AF_INET6: + plen = sizeof(struct in6_addr) << 3; + break; +#endif + default: + yyerror("unsupported address family"); + exit(1); /*XXX*/ + } m_addr.sadb_address_prefixlen = - (p_prefs != ~0 ? p_prefs : - _INALENBYAF(p_src->sa_family) << 3); + (p_prefs != ~0 ? p_prefs : plen); m_addr.sadb_address_reserved = 0; setvarbuf(&m_len, (struct sadb_ext *)&m_addr, sizeof(m_addr), (caddr_t)p_src, p_src->sa_len); /* set dst */ m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + PFKEY_ALIGN8(p_dst->sa_len)); m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST; m_addr.sadb_address_proto = p_upper; + switch (p_dst->sa_family) { + case AF_INET: + plen = sizeof(struct in_addr) << 3; + break; +#ifdef INET6 + case AF_INET6: + plen = sizeof(struct in6_addr) << 3; + break; +#endif + default: + yyerror("unsupported address family"); + exit(1); /*XXX*/ + } m_addr.sadb_address_prefixlen = - (p_prefd != ~0 ? p_prefd : - _INALENBYAF(p_dst->sa_family) << 3); + (p_prefd != ~0 ? p_prefd : plen); m_addr.sadb_address_reserved = 0; setvarbuf(&m_len, (struct sadb_ext *)&m_addr, sizeof(m_addr), (caddr_t)p_dst, p_dst->sa_len); } break; } ((struct sadb_msg *)m_buf)->sadb_msg_len = PFKEY_UNIT64(m_len); return 0; } +static struct addrinfo * +parse_addr(host, port, flag) + char *host; + char *port; + int flag; +{ + struct addrinfo hints, *res = NULL; + int error; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; + hints.ai_flags = flag; + error = getaddrinfo(host, port, &hints, &res); + if (error != 0) { + yyerror(gai_strerror(error)); + return NULL; + } + if (res->ai_next != NULL) { + yyerror(gai_strerror(error)); + } + return res; +} + static int setvarbuf(off, ebuf, elen, vbuf, vlen) caddr_t vbuf; struct sadb_ext *ebuf; int *off, elen, vlen; { memset(m_buf + *off, 0, PFKEY_UNUNIT64(ebuf->sadb_ext_len)); memcpy(m_buf + *off, (caddr_t)ebuf, elen); memcpy(m_buf + *off + elen, vbuf, vlen); (*off) += PFKEY_ALIGN8(elen + vlen); return 0; } void parse_init() { p_type = 0; p_spi = 0; p_src = 0, p_dst = 0; pp_prefix = p_prefs = p_prefd = ~0; pp_port = IPSEC_PORT_ANY; p_upper = 0; p_satype = 0; - p_ext = SADB_X_EXT_NONE; + p_ext = SADB_X_EXT_CYCSEQ; p_alg_enc = SADB_EALG_NONE; p_alg_auth = SADB_AALG_NONE; p_mode = IPSEC_MODE_ANY; - p_replay = 4; + p_reqid = 0; + p_replay = 0; p_key_enc_len = p_key_auth_len = 0; p_key_enc = p_key_auth = 0; p_lt_hard = p_lt_soft = 0; p_policy_len = 0; p_policy = NULL; memset(cmdarg, 0, sizeof(cmdarg)); return; } void free_buffer() { if (p_src) free(p_src); if (p_dst) free(p_dst); if (p_key_enc) free(p_key_enc); if (p_key_auth) free(p_key_auth); return; } Index: head/sbin/setkey/sample.cf =================================================================== --- head/sbin/setkey/sample.cf (revision 62582) +++ head/sbin/setkey/sample.cf (revision 62583) @@ -1,219 +1,219 @@ # Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # 3. Neither the name of the project nor the names of its contributors # may be used to endorse or promote products derived from this software # without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # # $FreeBSD$ # There are sample scripts for IPsec configuration by manual keying. # A security association is uniquely identified by a triple consisting # of a Security Parameter Index (SPI), an IP Destination Address, and a # security protocol (AH or ESP) identifier. You must take care of these # parameters when you configure by manual keying. # ESP transport mode is recommended for TCP port number 110 between # Host-A and Host-B. Encryption algorithm is blowfish-cbc whose key # is "kamekame", and authentication algorithm is hmac-sha1 whose key # is "this is the test key". # # ============ ESP ============ # | | # Host-A Host-B # fec0::10 -------------------- fec0::11 # # At Host-A and Host-B, spdadd fec0::10[any] fec0::11[110] tcp -P out ipsec esp/transport/fec0::10-fec0::11/use ; spdadd fec0::11[110] fec0::10[any] tcp -P in ipsec esp/transport/fec0::11-fec0::10/use ; add fec0::10 fec0::11 esp 0x10001 -m transport -E blowfish-cbc "kamekame" -A hmac-sha1 "this is the test key" ; add fec0::11 fec0::10 esp 0x10002 -m transport -E blowfish-cbc "kamekame" -A hmac-sha1 "this is the test key" ; # "[any]" is wildcard of port number. Note that "[0]" is the number of # zero in port number. # Security protocol is old AH tunnel mode, i.e. RFC1826, with keyed-md5 # whose key is "this is the test" as authentication algorithm. # That protocol takes place between Gateway-A and Gateway-B. # # ======= AH ======= # | | # Network-A Gateway-A Gateway-B Network-B # 10.0.1.0/24 ---- 172.16.0.1 ----- 172.16.0.2 ---- 10.0.2.0/24 # # At Gateway-A: spdadd 10.0.1.0/24 10.0.2.0/24 any -P out ipsec ah/tunnel/172.16.0.1-172.16.0.2/require ; spdadd 10.0.2.0/24 10.0.1.0/24 any -P in ipsec ah/tunnel/172.16.0.2-172.16.0.1/require ; add 172.16.0.1 172.16.0.2 ah-old 0x10003 -m any -A keyed-md5 "this is the test" ; add 172.16.0.2 172.16.0.1 ah-old 0x10004 -m any -A keyed-md5 "this is the test" ; # If port number field is omitted such above then "[any]" is employed. # -m specifies the mode of SA to be used. "-m any" means wildcard of # mode of security protocol. You can use this SAs for both tunnel and # transport mode. # At Gateway-B. Attention to the selector and peer's IP address for tunnel. spdadd 10.0.2.0/24 10.0.1.0/24 any -P out ipsec ah/tunnel/172.16.0.2-172.16.0.1/require ; spdadd 10.0.1.0/24 10.0.2.0/24 any -P in ipsec ah/tunnel/172.16.0.1-172.16.0.2/require ; add 172.16.0.1 172.16.0.2 ah-old 0x10003 -m tunnel -A keyed-md5 "this is the test" ; add 172.16.0.2 172.16.0.1 ah-old 0x10004 -m tunnel -A keyed-md5 "this is the test" ; # AH transport mode followed by ESP tunnel mode is required between # Gateway-A and Gateway-B. # Encryption algorithm is 3des-cbc, and authentication algorithm for ESP # is hmac-sha1. Authentication algorithm for AH is hmac-md5. # # ========== AH ========= # | ======= ESP ===== | # | | | | # Network-A Gateway-A Gateway-B Network-B # fec0:0:0:1::/64 --- fec0:0:0:1::1 ---- fec0:0:0:2::1 --- fec0:0:0:2::/64 # # At Gateway-A: spdadd fec0:0:0:1::/64 fec0:0:0:2::/64 any -P out ipsec esp/tunnel/fec0:0:0:1::1-fec0:0:0:2::1/require ah/transport/fec0:0:0:1::1-fec0:0:0:2::1/require ; spdadd fec0:0:0:2::/64 fec0:0:0:1::/64 any -P in ipsec esp/tunnel/fec0:0:0:2::1-fec0:0:0:1::1/require ah/transport/fec0:0:0:2::1-fec0:0:0:1::1/require ; add fec0:0:0:1::1 fec0:0:0:2::1 esp 0x10001 -m tunnel -E 3des-cbc "kamekame12341234kame1234" -A hmac-sha1 "this is the test key" ; add fec0:0:0:1::1 fec0:0:0:2::1 ah 0x10001 -m transport -A hmac-md5 "this is the test" ; add fec0:0:0:2::1 fec0:0:0:1::1 esp 0x10001 -m tunnel -E 3des-cbc "kamekame12341234kame1234" -A hmac-sha1 "this is the test key" ; add fec0:0:0:2::1 fec0:0:0:1::1 ah 0x10001 -m transport -A hmac-md5 "this is the test" ; # ESP tunnel mode is required between Host-A and Gateway-A. # Encryption algorithm is cast128-cbc, and authentication algorithm # for ESP is hmac-sha1. # ESP transport mode is recommended between Host-A and Host-B. # Encryption algorithm is rc5-cbc, and authentication algorithm # for ESP is hmac-md5. # # ================== ESP ================= # | ======= ESP ======= | # | | | | # Host-A Gateway-A Host-B # fec0:0:0:1::1 ---- fec0:0:0:2::1 ---- fec0:0:0:2::2 # # At Host-A: spdadd fec0:0:0:1::1[any] fec0:0:0:2::2[80] tcp -P out ipsec esp/transport/fec0:0:0:1::1-fec0:0:0:2::2/use esp/tunnel/fec0:0:0:1::1-fec0:0:0:2::1/require ; spdadd fec0:0:0:2::1[80] fec0:0:0:1::1[any] tcp -P in ipsec esp/transport/fec0:0:0:2::2-fec0:0:0:1::1/use esp/tunnel/fec0:0:0:2::1-fec0:0:0:1::1/require ; add fec0:0:0:1::1 fec0:0:0:2::2 esp 0x10001 -m transport -E cast128-cbc "12341234" -A hmac-sha1 "this is the test key" ; add fec0:0:0:1::1 fec0:0:0:2::1 esp 0x10002 -E rc5-cbc "kamekame" -A hmac-md5 "this is the test" ; add fec0:0:0:2::2 fec0:0:0:1::1 esp 0x10003 -m transport -E cast128-cbc "12341234" -A hmac-sha1 "this is the test key" ; add fec0:0:0:2::1 fec0:0:0:1::1 esp 0x10004 -E rc5-cbc "kamekame" -A hmac-md5 "this is the test" ; # By "get" command, you can get a entry of either SP or SA. get fec0:0:0:1::1 fec0:0:0:2::2 ah 0x10004 ; # Also delete command, you can delete a entry of either SP or SA. -spddelete out fec0:0:0:1::/64 fec0:0:0:2:/64 any ; +spddelete fec0:0:0:1::/64 fec0:0:0:2::/64 any -P out; delete fec0:0:0:1::1 fec0:0:0:2::2 ah 0x10004 ; # By dump command, you can dump all entry of either SP or SA. dump ; spddump ; dump esp ; flush esp ; # By flush command, you can flush all entry of either SP or SA. flush ; spdflush ; # "flush" and "dump" commands can specify a security protocol. dump esp ; flush ah ; # XXX add ::1 ::1 esp 10001 -m transport -E simple ; add ::1 ::1 esp 10002 -m transport -E des-deriv "12341234" ; add ::1 ::1 esp-old 10003 -m transport -E des-32iv "12341234" ; add ::1 ::1 esp 10004 -m transport -E simple -A null ; add ::1 ::1 esp 10005 -m transport -E simple -A hmac-md5 "1234123412341234" ; add ::1 ::1 esp 10006 -m tunnel -E simple -A hmac-sha1 "12341234123412341234" ; add ::1 ::1 esp 10007 -m transport -E simple -A keyed-md5 "1234123412341234" ; add ::1 ::1 esp 10008 -m any -E simple -A keyed-sha1 "12341234123412341234" ; add ::1 ::1 esp 10009 -m transport -E des-cbc "testtest" ; add ::1 ::1 esp 10010 -m transport -E 3des-cbc "testtest12341234testtest" ; add ::1 ::1 esp 10011 -m tunnel -E cast128-cbc "testtest1234" ; add ::1 ::1 esp 10012 -m tunnel -E blowfish-cbc "testtest1234" ; add ::1 ::1 esp 10013 -m tunnel -E rc5-cbc "testtest1234" ; add ::1 ::1 esp 10014 -m any -E rc5-cbc "testtest1234" ; add ::1 ::1 esp 10015 -m transport -f zero-pad -E simple ; add ::1 ::1 esp 10016 -m tunnel -f random-pad -r 8 -lh 100 -ls 80 -E simple ; -add ::1 ::1 esp 10017 -m transport -f seq-pad -f cyclic-seq -E simple ; +add ::1 ::1 esp 10017 -m transport -f seq-pad -f nocyclic-seq -E simple ; add ::1 ::1 esp 10018 -m transport -E simple ; #add ::1 ::1 ah 20000 -m transport -A null ; add ::1 ::1 ah 20001 -m any -A hmac-md5 "1234123412341234"; add ::1 ::1 ah 20002 -m tunnel -A hmac-sha1 "12341234123412341234"; add ::1 ::1 ah 20003 -m transport -A keyed-md5 "1234123412341234"; add ::1 ::1 ah-old 20004 -m transport -A keyed-md5 "1234123412341234"; add ::1 ::1 ah 20005 -m transport -A keyed-sha1 "12341234123412341234"; #add ::1 ::1 ipcomp 30000 -C oui ; add ::1 ::1 ipcomp 30001 -C deflate ; #add ::1 ::1 ipcomp 30002 -C lzs ; # enjoy. Index: head/sbin/setkey/scriptdump.pl =================================================================== --- head/sbin/setkey/scriptdump.pl (revision 62582) +++ head/sbin/setkey/scriptdump.pl (revision 62583) @@ -1,54 +1,56 @@ #! @LOCALPREFIX@/bin/perl # $FreeBSD$ if ($< != 0) { print STDERR "must be root to invoke this\n"; exit 1; } $mode = 'add'; while ($i = shift @ARGV) { if ($i eq '-d') { $mode = 'delete'; } else { print STDERR "usage: scriptdump [-d]\n"; exit 1; } } open(IN, "setkey -D |") || die; foreach $_ () { if (/^[^\t]/) { ($src, $dst) = split(/\s+/, $_); - } elsif (/^\t(esp|ah) mode=(\S+) spi=(\d+).*replay=(\d+)/) { - ($proto, $ipsecmode, $spi, $replay) = ($1, $2, $3, $4); + } elsif (/^\t(esp|ah) mode=(\S+) spi=(\d+).*reqid=(\d+)/) { + ($proto, $ipsecmode, $spi, $reqid) = ($1, $2, $3, $4); } elsif (/^\tE: (\S+) (.*)/) { $ealgo = $1; $ekey = $2; $ekey =~ s/\s//g; $ekey =~ s/^/0x/g; } elsif (/^\tA: (\S+) (.*)/) { $aalgo = $1; $akey = $2; $akey =~ s/\s//g; $akey =~ s/^/0x/g; - } elsif (/^\tstate=/) { + } elsif (/^\treplay=(\d+) flags=(0x\d+) state=/) { print "$mode $src $dst $proto $spi -m $ipsecmode"; - print " -r $replay" if $replay; + $replay = $1; + print " -u $reqid" if $reqid; if ($mode eq 'add') { + print " -r $replay" if $replay; if ($proto eq 'esp') { print " -E $ealgo $ekey" if $ealgo; print " -A $aalgo $akey" if $aalgo; } elsif ($proto eq 'ah') { print " -A $aalgo $akey" if $aalgo; } - } + } print ";\n"; $src = $dst = $upper = $proxy = ''; $ealgo = $ekey = $aalgo = $akey = ''; } } close(IN); exit 0; Index: head/sbin/setkey/setkey.8 =================================================================== --- head/sbin/setkey/setkey.8 (revision 62582) +++ head/sbin/setkey/setkey.8 (revision 62583) @@ -1,552 +1,561 @@ +.\" $FreeBSD$ +.\" $KAME: setkey.8,v 1.28 2000/06/16 12:03:46 sakane Exp $ +.\" .\" Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. .\" All rights reserved. -.\" +.\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" 3. Neither the name of the project nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. -.\" +.\" .\" THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE .\" ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $Id: setkey.8,v 1.14 1999/10/27 17:08:58 sakane Exp $ -.\" $FreeBSD$ -.\" .Dd May 17, 1998 .Dt SETKEY 8 -.Os +.Os KAME +.\" .Sh NAME .Nm setkey -.Nd manually manipulate the SA/SP database. +.Nd manually manipulate the IPsec SA/SP database. +.\" .Sh SYNOPSIS .Nm setkey .Op Fl dv .Fl c .Nm setkey .Op Fl dv .Fl f Ar filename .Nm setkey .Op Fl adPlv .Fl D .Nm setkey .Op Fl dPv .Fl F .Nm setkey .Op Fl h .Fl x -.\" +.\" .Sh DESCRIPTION .Nm -updates, or lists the content of, Security Association Database (SAD) entries -in the kernel as well as Security Policy Database (SPD) entries. +addes, updates, dumpes, or flushes +Security Association Database (SAD) entries +as well as Security Policy Database (SPD) entries in the kernel. .Pp .Nm -takes a series of operation from standard input +takes a series of operations from the standard input .Po if invoked with .Fl c .Pc -or file named +or the file named .Ar filename .Po if invoked with .Fl f Ar filename .Pc . .Bl -tag -width Ds .It Fl D Dump the SAD entries. If with .Fl P , the SPD entries are dumped. .It Fl F -Flush the SAD. +Flush the SAD entries. If with .Fl P , -the SPD are flushed. +the SPD entries are flushed. .It Fl a .Nm -usually do not display dead SAD entries on +usually does not display dead SAD entries with .Fl D . -With +If with .Fl a , -dead SAD entries will be displayed as well. -Dead SAD entries are kept in the kernel, -when they are referenced from any of SPD entries in the kernel. +the dead SAD entries will be displayed as well. +A dead SAD entry means that +it has been expired but remains +because it is referenced by SPD entries. .It Fl d -Enable debugging messages. +Enable to print debugging messages for command parser, +without talking to kernel. It is not used usually. .It Fl x Loop forever and dump all the messages transmitted to .Dv PF_KEY socket. .It Fl h Add hexadecimal dump on .Fl x mode. -The order is significant. .It Fl l Loop forever with short output on .Fl D . .It Fl v Be verbose. .Dv PF_KEY socket .Po including messages sent from other processes .Pc . .El .Pp -Operation has the following grammar. -Note that lines, that start with a -hashmark ('#') are treated as comment lines. -Description of meta-arguments follows. +Operations have the following grammar. Note that lines starting with +hashmarks ('#') are treated as comment lines. .Bl -tag -width Ds .It Xo .Li add .Ar src Ar dst Ar protocol Ar spi .Op Ar extensions .Ar algorithm... .Li ; .Xc -Add a SAD entry. +Add an SAD entry. .\" .It Xo .Li get .Ar src Ar dst Ar protocol Ar spi -.Op Ar mode .Li ; .Xc -Show a SAD entry. +Show an SAD entry. .\" .It Xo .Li delete .Ar src Ar dst Ar protocol Ar spi -.Op Ar mode .Li ; .Xc -Remove a SAD entry. +Remove an SAD entry. .\" .It Xo .Li flush .Op Ar protocol .Li ; .Xc -Clear all SAD entries that matches the options. +Clear all SAD entries matched by the options. .\" .It Xo .Li dump .Op Ar protocol .Li ; .Xc -Dumps all SAD entries that matches the options. +Dumps all SAD entries matched by the options. .\" .It Xo .Li spdadd .Ar src_range Ar dst_range Ar upperspec Ar policy .Li ; .Xc -Add a SPD entry. +Add an SPD entry. .\" .It Xo .Li spddelete -.Ar src_range Ar dst_range Ar upperspec +.Ar src_range Ar dst_range Ar upperspec Fl P Ar direction .Li ; .Xc -Delete a SPD entry. +Delete an SPD entry. .\" .It Xo .Li spdflush .Li ; .Xc Clear all SPD entries. .\" .It Xo .Li spddump .Li ; .Xc Dumps all SPD entries. .El .\" .Pp Meta-arguments are as follows: .Bl -tag -compact -width Ds .It Ar src .It Ar dst Source/destination of the secure communication is specified as IPv4/v6 address. .Nm does not consult hostname-to-address for arguments .Ar src and .Ar dst . They must be in numeric form. .\" .Pp .It Ar protocol .Ar protocol is one of following: .Bl -tag -width Fl -compact .It Li esp ESP based on rfc2405 .It Li esp-old ESP based on rfc1827 .It Li ah AH based on rfc2402 .It Li ah-old AH based on rfc1826 .It Li ipcomp IPCOMP .El .\" .Pp .It Ar spi -Security Parameter Index (SPI) for the SA and SPD. +Security Parameter Index (SPI) for the SAD and the SPD. It must be decimal number or hexadecimal number +You can not use the set of SPI values in the range 0 through 255. .Po with .Li 0x attached .Pc . .\" .Pp .It Ar extensions -takes some of the following: -.Bl -tag -width Fl -compact +take some of the following: +.Bl -tag -width Fl -compact +.\" .It Fl m Ar mode -Specify an security protocol mode for use. By default, -.Li any . +Specify a security protocol mode for use. .Ar mode is one of following: .Li transport , tunnel or .Li any . +The default value is +.Li any . +.\" .It Fl r Ar size Specify window size of bytes for replay prevention. .Ar size must be decimal number in 32-bit word. If .Ar size is zero or not specified, replay check don't take place. +.\" +.It Fl u Ar id +Specify the identifier of policy. See also +.Xr ipsec_set_policy 3 . +.\" .It Fl f Ar pad_option .Ar pad_option is one of following: .Li zero-pad , random-pad or .Li seq-pad -.It Fl f Li cyclic-seq -Allow cyclic sequence number. +.\" +.It Fl f Li nocyclic-seq +Don't allow cyclic sequence number. +.\" .It Fl lh Ar time .It Fl ls Ar time Specify hard/soft lifetime. .El .\" .Pp .It Ar algorithm -.Bl -tag -width Fl -compact +.Bl -tag -width Fl -compact .It Fl E Ar ealgo Ar key Specify encryption algorithm. .It Fl A Ar aalgo Ar key Specify authentication algorithm. If .Fl A is used for esp, it will be treated as ESP payload authentication algorithm. .It Fl C Ar calgo Op Fl R Specify compression algorithm. If .Fl R -is specified with +is not specified with .Li ipcomp line, the kernel will use well-known IPComp CPI .Pq compression parameter index on IPComp CPI field on packets, and .Ar spi field will be ignored. .Ar spi field is only for kernel internal use in this case. .\"Therefore, compression protocol number will appear on IPComp CPI field. If .Fl R -is not used, +is used, the value on .Ar spi field will appear on IPComp CPI field on outgoing packets. .Ar spi field needs to be smaller than .Li 0x10000 in this case. .El .Pp .Li esp SAs accept .Fl E and .Fl A . .Li esp-old SAs accept .Fl E only. .Li ah and .Li ah-old SAs accept .Fl A only. .Li ipcomp SAs accept .Fl C only. .Pp .Ar key -must be double-quoted character string or a series of hexadecimal digits. +must be double-quoted character string or series of hexadecimal digits. .Pp Possible values for .Ar ealgo , .Ar aalgo and .Ar calgo are specified in separate section. .\" .It Ar src_range .It Ar dst_range -These are selection of the secure communication is specified as +These are selections of the secure communication specified as IPv4/v6 address or IPv4/v6 address range, and it may accompany TCP/UDP port specification. This takes the following form: .Bd -literal -offset .Ar address .Ar address/prefixlen .Ar address[port] .Ar address/prefixlen[port] .Ed .Pp .Ar prefixlen and .Ar port must be decimal number. The square bracket around .Ar port is really necessary. They are not manpage metacharacters. .Pp .Nm does not consult hostname-to-address for arguments .Ar src and .Ar dst . They must be in numeric form. .\" .It Ar upperspec Upper-layer protocol to be used. Currently .Li tcp , .Li udp and .Li any can be specified. .Li any stands for .Dq any protocol . .Pp NOTE: .Ar upperspec does not work against forwarding case at this moment, as it requires extra reassembly at forwarding node -.Pq not implemented as this moment . +.Pq not implemented at this moment . .\" .It Ar policy .Ar policy is the one of following: .Bd -literal -offset .Xo .Fl P .Ar direction .Li discard .Xc .Xo .Fl P .Ar direction .Li none .Xc .Xo .Fl P .Ar direction .Li ipsec .Ar protocol/mode/src-dst/level .Xc .Ed .Pp You must specify the direction of its policy as .Ar direction . Either .Li out or .Li in are used. .Li discard means the packet matching indexes will be discarded. .Li none means that IPsec operation will not take place onto the packet. .Li ipsec means that IPsec operation will take place onto the packet. Either .Li ah , .Li esp or .Li ipcomp is to be set as .Ar protocol . .Ar mode is either .Li transport or .Li tunnel . You must specify the end-points addresses of the SA as .Ar src and .Ar dst with .Sq - between these addresses which is used to specify the SA to use. .Ar level is to be one of the following: .Li default , use or .Li require . .Li default -means kernel consults to the system wide default against protocol you +means the kernel consults to the system wide default against protocol you specified, e.g. .Li esp_trans_deflev -sysctl variable, when kernel processes the packet. +sysctl variable, when the kernel processes the packet. .Li use -means that kernel use a SA if it's available, -otherwise kernel keeps normal operation. +means that the kernel use a SA if it's available, +otherwise the kernel keeps normal operation. .Li require -means SA is required whenever kernel deals with the packet. +means SA is required whenever the kernel deals with the packet. Note that .Dq Li discard and .Dq Li none are not in the syntax described in .Xr ipsec_set_policy 3 . There are little differences in the syntax. See .Xr ipsec_set_policy 3 for detail. .Pp .El .Pp .\" .Sh ALGORITHMS The following list shows the supported algorithms. .Sy protocol and .Sy algorithm are almost orthogonal. -Following are the list of authentication algorithms that can be used as +Followings are the list of authentication algorithms that can be used as .Ar aalgo in .Fl A Ar aalgo of .Ar protocol parameter: .Pp .Bd -literal -offset indent algorithm keylen (bits) comment hmac-md5 128 ah: rfc2403 128 ah-old: rfc2085 hmac-sha1 160 ah: rfc2404 160 ah-old: 128bit ICV (no document) keyed-md5 128 ah: 96bit ICV (no document) 128 ah-old: rfc1828 keyed-sha1 160 ah: 96bit ICV (no document) 160 ah-old: 128bit ICV (no document) null 0 to 2048 for debugging .Ed .Pp -Following are the list of encryption algorithms that can be used as +Followings are the list of encryption algorithms that can be used as .Ar ealgo in .Fl E Ar ealgo of .Ar protocol parameter: .Pp .Bd -literal -offset indent algorithm keylen (bits) comment des-cbc 64 esp-old: rfc1829, esp: rfc2405 3des-cbc 192 rfc2451 simple 0 to 2048 rfc2410 blowfish-cbc 40 to 448 rfc2451 cast128-cbc 40 to 128 rfc2451 rc5-cbc 40 to 2040 rfc2451 des-deriv 64 ipsec-ciph-des-derived-01 (expired) 3des-deriv 192 no document .Ed .Pp -Following are the list of compression algorithms that can be used as +Followings are the list of compression algorithms that can be used as .Ar calgo in .Fl C Ar calgo of .Ar protocol parameter: .Pp .Bd -literal -offset indent algorithm comment deflate rfc2394 lzs rfc2395 .Ed -.\" +.\" .Sh EXAMPLES .Bd -literal -offset add 3ffe:501:4819::1 3ffe:501:481d::1 esp 123457 -E des-cbc "ESP SA!!" ; add 3ffe:501:4819::1 3ffe:501:481d::1 ah 123456 -A hmac-sha1 "AH SA configuration!" ; add 10.0.11.41 10.0.11.33 esp 0x10001 -E des-cbc "ESP with" -A hmac-md5 "authentication!!" ; get 3ffe:501:4819::1 3ffe:501:481d::1 ah 123456 ; flush ; dump esp ; spdadd 10.0.11.41/32[21] 10.0.11.33/32[any] any -P out ipsec esp/tunnel/192.168.0.1-192.168.1.2/require ; .Ed -.\" +.\" .Sh RETURN VALUES The command exits with 0 on success, and non-zero on errors. -.\" +.\" .Sh SEE ALSO .Xr ipsec_set_policy 3 , .Xr sysctl 8 -.\" +.\" .Sh HISTORY The .Nm command first appeared in WIDE Hydrangea IPv6 protocol stack kit. The command was completely re-designed in June 1998. -.Pp -IPv6 and IPsec support based on the KAME Project (http://www.kame.net/) stack -was initially integrated into -.Fx 4.0 +.\" +.\" .Sh BUGS Index: head/sbin/setkey/setkey.c =================================================================== --- head/sbin/setkey/setkey.c (revision 62582) +++ head/sbin/setkey/setkey.c (revision 62583) @@ -1,566 +1,578 @@ +/* $FreeBSD$ */ +/* $KAME: setkey.c,v 1.14 2000/06/10 06:47:09 sakane Exp $ */ + /* * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ -/* KAME $Id: setkey.c,v 1.5 1999/10/26 09:39:37 sakane Exp $ */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include -void Usage __P((void)); -int main __P((int, char **)); -int get_supported __P((void)); -void sendkeyshort __P((u_int)); -void promisc __P((void)); -int sendkeymsg __P((void)); -int postproc __P((struct sadb_msg *, int)); -const char *numstr __P((int)); -void shortdump_hdr __P((void)); -void shortdump __P((struct sadb_msg *)); +#include "libpfkey.h" +void Usage __P((void)); +int main __P((int, char **)); +int get_supported __P((void)); +void sendkeyshort __P((u_int)); +void promisc __P((void)); +int sendkeymsg __P((void)); +int postproc __P((struct sadb_msg *, int)); +const char *numstr __P((int)); +void shortdump_hdr __P((void)); +void shortdump __P((struct sadb_msg *)); + #define MODE_SCRIPT 1 #define MODE_CMDDUMP 2 #define MODE_CMDFLUSH 3 +#define MODE_PROMISC 4 int so; -int f_forever = 0; -int f_all = 0; -int f_debug = 0; -int f_verbose = 0; -int f_mode = 0; -int f_cmddump = 0; -int f_policy = 0; -int f_promisc = 0; -int f_hexdump = 0; -char *pname; +int f_forever = 0; +int f_all = 0; +int f_debug = 0; +int f_verbose = 0; +int f_mode = 0; +int f_cmddump = 0; +int f_policy = 0; +int f_hexdump = 0; +char *pname; -u_char m_buf[BUFSIZ]; -u_int m_len; +u_char m_buf[BUFSIZ]; +u_int m_len; -extern int lineno; +extern int lineno; -extern int parse __P((FILE **)); +extern int parse __P((FILE **)); void Usage() { printf("Usage:\t%s [-dv] -c\n", pname); printf("\t%s [-dv] -f (file)\n", pname); printf("\t%s [-Padlv] -D\n", pname); printf("\t%s [-Pdv] -F\n", pname); printf("\t%s [-h] -x\n", pname); pfkey_close(so); - exit(0); + exit(1); } int main(ac, av) int ac; char **av; { FILE *fp = stdin; int c; pname = *av; if (ac == 1) Usage(); while ((c = getopt(ac, av, "acdf:hlvxDFP")) != EOF) { switch (c) { case 'c': f_mode = MODE_SCRIPT; fp = stdin; break; case 'f': f_mode = MODE_SCRIPT; if ((fp = fopen(optarg, "r")) == NULL) { err(-1, "fopen"); /*NOTREACHED*/ } break; case 'D': f_mode = MODE_CMDDUMP; break; case 'F': f_mode = MODE_CMDFLUSH; break; case 'a': f_all = 1; break; case 'l': f_forever = 1; break; case 'h': f_hexdump = 1; break; case 'x': - f_promisc = 1; - promisc(); - /*NOTREACHED*/ + f_mode = MODE_PROMISC; + break; case 'P': f_policy = 1; break; case 'd': f_debug = 1; break; case 'v': f_verbose = 1; break; default: Usage(); /*NOTREACHED*/ } } switch (f_mode) { case MODE_CMDDUMP: sendkeyshort(f_policy ? SADB_X_SPDDUMP: SADB_DUMP); break; case MODE_CMDFLUSH: sendkeyshort(f_policy ? SADB_X_SPDFLUSH: SADB_FLUSH); pfkey_close(so); break; case MODE_SCRIPT: if (get_supported() < 0) { errx(-1, "%s", ipsec_strerror()); /*NOTREACHED*/ } - parse(&fp); + if (parse(&fp)) + exit (1); break; + case MODE_PROMISC: + promisc(); + /*NOTREACHED*/ default: Usage(); + /*NOTREACHED*/ } exit(0); } int get_supported() { int so; if ((so = pfkey_open()) < 0) { perror("pfkey_open"); return -1; } /* debug mode ? */ if (f_debug) return 0; if (pfkey_send_register(so, PF_UNSPEC) < 0) return -1; if (pfkey_recv_register(so) < 0) return -1; return 0; } void sendkeyshort(type) u_int type; { struct sadb_msg *m_msg = (struct sadb_msg *)m_buf; m_len = sizeof(struct sadb_msg); m_msg->sadb_msg_version = PF_KEY_V2; m_msg->sadb_msg_type = type; m_msg->sadb_msg_errno = 0; m_msg->sadb_msg_satype = SADB_SATYPE_UNSPEC; m_msg->sadb_msg_len = PFKEY_UNIT64(m_len); m_msg->sadb_msg_reserved = 0; - m_msg->sadb_msg_reserved = 0; m_msg->sadb_msg_seq = 0; m_msg->sadb_msg_pid = getpid(); sendkeymsg(); return; } void promisc() { struct sadb_msg *m_msg = (struct sadb_msg *)m_buf; u_char rbuf[1024 * 32]; /* XXX: Enough ? Should I do MSG_PEEK ? */ int so, len; m_len = sizeof(struct sadb_msg); m_msg->sadb_msg_version = PF_KEY_V2; m_msg->sadb_msg_type = SADB_X_PROMISC; m_msg->sadb_msg_errno = 0; m_msg->sadb_msg_satype = 1; m_msg->sadb_msg_len = PFKEY_UNIT64(m_len); m_msg->sadb_msg_reserved = 0; - m_msg->sadb_msg_reserved = 0; m_msg->sadb_msg_seq = 0; m_msg->sadb_msg_pid = getpid(); if ((so = socket(PF_KEY, SOCK_RAW, PF_KEY_V2)) < 0) { err(1, "socket(PF_KEY)"); /*NOTREACHED*/ } if ((len = send(so, m_buf, m_len, 0)) < 0) { err(1, "send"); /*NOTREACHED*/ } while (1) { struct sadb_msg *base; if ((len = recv(so, rbuf, sizeof(*base), MSG_PEEK)) < 0) { err(1, "recv"); /*NOTREACHED*/ } if (len != sizeof(*base)) continue; base = (struct sadb_msg *)rbuf; if ((len = recv(so, rbuf, PFKEY_UNUNIT64(base->sadb_msg_len), 0)) < 0) { err(1, "recv"); /*NOTREACHED*/ } if (f_hexdump) { int i; for (i = 0; i < len; i++) { if (i % 16 == 0) printf("%08x: ", i); printf("%02x ", rbuf[i] & 0xff); if (i % 16 == 15) printf("\n"); } if (len % 16) printf("\n"); } /* adjust base pointer for promisc mode */ if (base->sadb_msg_type == SADB_X_PROMISC) { if (sizeof(*base) < len) base++; else base = NULL; } if (base) { kdebug_sadb(base); printf("\n"); fflush(stdout); } } } int sendkeymsg() { int so; u_char rbuf[1024 * 32]; /* XXX: Enough ? Should I do MSG_PEEK ? */ int len; struct sadb_msg *msg; if ((so = pfkey_open()) < 0) { perror("pfkey_open"); return -1; } { struct timeval tv; tv.tv_sec = 1; tv.tv_usec = 0; if (setsockopt(so, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) { perror("setsockopt"); goto end; } } if (f_forever) shortdump_hdr(); again: - if (f_verbose) + if (f_verbose) { kdebug_sadb((struct sadb_msg *)m_buf); + printf("\n"); + } if ((len = send(so, m_buf, m_len, 0)) < 0) { perror("send"); goto end; } msg = (struct sadb_msg *)rbuf; do { if ((len = recv(so, rbuf, sizeof(rbuf), 0)) < 0) { perror("recv"); goto end; } if (PFKEY_UNUNIT64(msg->sadb_msg_len) != len) { warnx("invalid keymsg length"); break; } - if (f_verbose) + if (f_verbose) { kdebug_sadb((struct sadb_msg *)rbuf); + printf("\n"); + } if (postproc(msg, len) < 0) break; } while (msg->sadb_msg_errno || msg->sadb_msg_seq); if (f_forever) { fflush(stdout); sleep(1); goto again; } end: pfkey_close(so); return(0); } int postproc(msg, len) struct sadb_msg *msg; int len; { if (msg->sadb_msg_errno != 0) { char inf[80]; char *errmsg = NULL; if (f_mode == MODE_SCRIPT) snprintf(inf, sizeof(inf), "The result of line %d: ", lineno); else inf[0] = '\0'; switch (msg->sadb_msg_errno) { case ENOENT: switch (msg->sadb_msg_type) { case SADB_DELETE: case SADB_GET: case SADB_X_SPDDELETE: errmsg = "No entry"; break; case SADB_DUMP: errmsg = "No SAD entries"; break; case SADB_X_SPDDUMP: errmsg = "No SPD entries"; break; } break; default: errmsg = strerror(msg->sadb_msg_errno); } printf("%s%s.\n", inf, errmsg); return(-1); } switch (msg->sadb_msg_type) { case SADB_GET: pfkey_sadump(msg); break; case SADB_DUMP: /* filter out DEAD SAs */ if (!f_all) { caddr_t mhp[SADB_EXT_MAX + 1]; struct sadb_sa *sa; pfkey_align(msg, mhp); pfkey_check(mhp); if ((sa = (struct sadb_sa *)mhp[SADB_EXT_SA]) != NULL) { if (sa->sadb_sa_state == SADB_SASTATE_DEAD) break; } } if (f_forever) shortdump(msg); else pfkey_sadump(msg); msg = (struct sadb_msg *)((caddr_t)msg + PFKEY_UNUNIT64(msg->sadb_msg_len)); - if (f_verbose) + if (f_verbose) { kdebug_sadb((struct sadb_msg *)msg); + printf("\n"); + } break; case SADB_X_SPDDUMP: pfkey_spdump(msg); if (msg->sadb_msg_seq == 0) break; msg = (struct sadb_msg *)((caddr_t)msg + PFKEY_UNUNIT64(msg->sadb_msg_len)); - if (f_verbose) + if (f_verbose) { kdebug_sadb((struct sadb_msg *)msg); + printf("\n"); + } break; } return(0); } /*------------------------------------------------------------*/ static char *satype[] = { NULL, NULL, "ah", "esp" }; static char *sastate[] = { "L", "M", "D", "d" }; static char *ipproto[] = { /*0*/ "ip", "icmp", "igmp", "ggp", "ip4", NULL, "tcp", NULL, "egp", NULL, /*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, "udp", NULL, NULL, /*20*/ NULL, NULL, "idp", NULL, NULL, NULL, NULL, NULL, NULL, "tp", /*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*40*/ NULL, "ip6", NULL, "rt6", "frag6", NULL, "rsvp", "gre", NULL, NULL, /*50*/ "esp", "ah", NULL, NULL, NULL, NULL, NULL, NULL, "icmp6", "none", /*60*/ "dst6", }; #define STR_OR_ID(x, tab) \ (((x) < sizeof(tab)/sizeof(tab[0]) && tab[(x)]) ? tab[(x)] : numstr(x)) const char * numstr(x) int x; { static char buf[20]; snprintf(buf, sizeof(buf), "#%d", x); return buf; } void shortdump_hdr() { printf("%-4s %-3s %-1s %-8s %-7s %s -> %s\n", "time", "p", "s", "spi", "ltime", "src", "dst"); } void shortdump(msg) struct sadb_msg *msg; { caddr_t mhp[SADB_EXT_MAX + 1]; char buf[1024], pbuf[10]; struct sadb_sa *sa; struct sadb_address *saddr; struct sadb_lifetime *lts, *lth, *ltc; struct sockaddr *s; u_int t; time_t cur = time(0); pfkey_align(msg, mhp); pfkey_check(mhp); printf("%02lu%02lu", (u_long)(cur % 3600) / 60, (u_long)(cur % 60)); printf(" %-3s", STR_OR_ID(msg->sadb_msg_satype, satype)); if ((sa = (struct sadb_sa *)mhp[SADB_EXT_SA]) != NULL) { printf(" %-1s", STR_OR_ID(sa->sadb_sa_state, sastate)); printf(" %08x", (u_int32_t)ntohl(sa->sadb_sa_spi)); } else printf("%-1s %-8s", "?", "?"); lts = (struct sadb_lifetime *)mhp[SADB_EXT_LIFETIME_SOFT]; lth = (struct sadb_lifetime *)mhp[SADB_EXT_LIFETIME_HARD]; ltc = (struct sadb_lifetime *)mhp[SADB_EXT_LIFETIME_CURRENT]; if (lts && lth && ltc) { if (ltc->sadb_lifetime_addtime == 0) t = (u_long)0; else t = (u_long)(cur - ltc->sadb_lifetime_addtime); if (t >= 1000) strcpy(buf, " big/"); else snprintf(buf, sizeof(buf), " %3lu/", (u_long)t); printf("%s", buf); t = (u_long)lth->sadb_lifetime_addtime; if (t >= 1000) strcpy(buf, "big"); else snprintf(buf, sizeof(buf), "%-3lu", (u_long)t); printf("%s", buf); } else printf(" ???/???"); printf(" "); if ((saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC]) != NULL) { if (saddr->sadb_address_proto) printf("%s ", STR_OR_ID(saddr->sadb_address_proto, ipproto)); s = (struct sockaddr *)(saddr + 1); getnameinfo(s, s->sa_len, buf, sizeof(buf), pbuf, sizeof(pbuf), NI_NUMERICHOST|NI_NUMERICSERV); if (strcmp(pbuf, "0") != 0) printf("%s[%s]", buf, pbuf); else printf("%s", buf); } else printf("?"); printf(" -> "); if ((saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST]) != NULL) { if (saddr->sadb_address_proto) printf("%s ", STR_OR_ID(saddr->sadb_address_proto, ipproto)); s = (struct sockaddr *)(saddr + 1); getnameinfo(s, s->sa_len, buf, sizeof(buf), pbuf, sizeof(pbuf), NI_NUMERICHOST|NI_NUMERICSERV); if (strcmp(pbuf, "0") != 0) printf("%s[%s]", buf, pbuf); else printf("%s", buf); } else printf("?"); printf("\n"); } Index: head/sbin/setkey/test-pfkey.c =================================================================== --- head/sbin/setkey/test-pfkey.c (revision 62582) +++ head/sbin/setkey/test-pfkey.c (revision 62583) @@ -1,480 +1,531 @@ +/* $FreeBSD$ */ +/* $KAME: test-pfkey.c,v 1.4 2000/06/07 00:29:14 itojun Exp $ */ + /* * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ -/* KAME $Id: test-pfkey.c,v 1.2 1999/10/26 08:09:17 itojun Exp $ */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include +#include -u_char m_buf[BUFSIZ]; -u_int m_len; -char *pname; +u_char m_buf[BUFSIZ]; +u_int m_len; +char *pname; -void Usage __P((void)); -int sendkeymsg __P((void)); -void key_setsadbmsg __P((u_int)); -void key_setsadbsens __P((void)); -void key_setsadbprop __P((void)); -void key_setsadbid __P((u_int, caddr_t)); -void key_setsadblft __P((u_int, u_int)); -void key_setspirange __P((void)); -void key_setsadbkey __P((u_int, caddr_t)); -void key_setsadbsa __P((void)); -void key_setsadbaddr __P((u_int, u_int, caddr_t)); -void key_setsadbextbuf __P((caddr_t, int, caddr_t, int, caddr_t, int)); +void Usage __P((void)); +int sendkeymsg __P((void)); +void key_setsadbmsg __P((u_int)); +void key_setsadbsens __P((void)); +void key_setsadbprop __P((void)); +void key_setsadbid __P((u_int, caddr_t)); +void key_setsadblft __P((u_int, u_int)); +void key_setspirange __P((void)); +void key_setsadbkey __P((u_int, caddr_t)); +void key_setsadbsa __P((void)); +void key_setsadbaddr __P((u_int, u_int, caddr_t)); +void key_setsadbextbuf __P((caddr_t, int, caddr_t, int, caddr_t, int)); void Usage() { printf("Usage:\t%s number\n", pname); exit(0); } int main(ac, av) int ac; char **av; { pname = *av; if (ac == 1) Usage(); key_setsadbmsg(atoi(*(av+1))); sendkeymsg(); exit(0); } /* %%% */ int sendkeymsg() { u_char rbuf[1024 * 32]; /* XXX: Enough ? Should I do MSG_PEEK ? */ int so, len; if ((so = socket(PF_KEY, SOCK_RAW, PF_KEY_V2)) < 0) { perror("socket(PF_KEY)"); goto end; } +#if 0 + { +#include + struct timeval tv; + tv.tv_sec = 1; + tv.tv_usec = 0; + if (setsockopt(so, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) { + perror("setsockopt"); + goto end; + } + } +#endif pfkey_sadump((struct sadb_msg *)m_buf); if ((len = send(so, m_buf, m_len, 0)) < 0) { perror("send"); goto end; } if ((len = recv(so, rbuf, sizeof(rbuf), 0)) < 0) { perror("recv"); goto end; } pfkey_sadump((struct sadb_msg *)rbuf); end: (void)close(so); return(0); } void key_setsadbmsg(type) u_int type; { struct sadb_msg m_msg; + memset(&m_msg, 0, sizeof(m_msg)); m_msg.sadb_msg_version = PF_KEY_V2; m_msg.sadb_msg_type = type; m_msg.sadb_msg_errno = 0; m_msg.sadb_msg_satype = SADB_SATYPE_ESP; +#if 0 m_msg.sadb_msg_reserved = 0; +#endif m_msg.sadb_msg_seq = 0; m_msg.sadb_msg_pid = getpid(); m_len = sizeof(struct sadb_msg); memcpy(m_buf, &m_msg, m_len); switch (type) { case SADB_GETSPI: /**/ key_setsadbaddr(SADB_EXT_ADDRESS_SRC, AF_INET, "10.0.3.4"); key_setsadbaddr(SADB_EXT_ADDRESS_DST, AF_INET, "127.0.0.1"); key_setspirange(); /**/ break; case SADB_ADD: /* */ key_setsadbaddr(SADB_EXT_ADDRESS_PROXY, AF_INET6, "3ffe::1"); case SADB_UPDATE: key_setsadbsa(); key_setsadblft(SADB_EXT_LIFETIME_HARD, 10); key_setsadblft(SADB_EXT_LIFETIME_SOFT, 5); key_setsadbaddr(SADB_EXT_ADDRESS_SRC, AF_INET, "192.168.1.1"); key_setsadbaddr(SADB_EXT_ADDRESS_DST, AF_INET, "10.0.3.4"); /* XXX key_setsadbkey(SADB_EXT_KEY_AUTH, "abcde"); */ key_setsadbkey(SADB_EXT_KEY_AUTH, "1234567812345678"); key_setsadbkey(SADB_EXT_KEY_ENCRYPT, "12345678"); key_setsadbid(SADB_EXT_IDENTITY_SRC, "hoge1234@hoge.com"); key_setsadbid(SADB_EXT_IDENTITY_DST, "hage5678@hage.net"); key_setsadbsens(); /* */ break; case SADB_DELETE: /* */ key_setsadbsa(); key_setsadbaddr(SADB_EXT_ADDRESS_SRC, AF_INET, "192.168.1.1"); key_setsadbaddr(SADB_EXT_ADDRESS_DST, AF_INET, "10.0.3.4"); key_setsadbaddr(SADB_EXT_ADDRESS_PROXY, AF_INET6, "3ffe::1"); /* */ break; case SADB_GET: /* */ key_setsadbsa(); key_setsadbaddr(SADB_EXT_ADDRESS_SRC, AF_INET, "192.168.1.1"); key_setsadbaddr(SADB_EXT_ADDRESS_DST, AF_INET, "10.0.3.4"); key_setsadbaddr(SADB_EXT_ADDRESS_PROXY, AF_INET6, "3ffe::1"); /* */ break; case SADB_ACQUIRE: /* */ key_setsadbaddr(SADB_EXT_ADDRESS_SRC, AF_INET, "192.168.1.1"); key_setsadbaddr(SADB_EXT_ADDRESS_DST, AF_INET, "10.0.3.4"); key_setsadbaddr(SADB_EXT_ADDRESS_PROXY, AF_INET6, "3ffe::1"); key_setsadbid(SADB_EXT_IDENTITY_SRC, "hoge1234@hoge.com"); key_setsadbid(SADB_EXT_IDENTITY_DST, "hage5678@hage.net"); key_setsadbsens(); key_setsadbprop(); /* */ break; case SADB_REGISTER: /* */ /* */ break; case SADB_EXPIRE: case SADB_FLUSH: break; case SADB_DUMP: break; case SADB_X_PROMISC: /* */ /* */ break; case SADB_X_PCHANGE: break; /* for SPD management */ case SADB_X_SPDFLUSH: case SADB_X_SPDDUMP: break; case SADB_X_SPDADD: +#if 0 + { + struct sadb_x_policy m_policy; + + m_policy.sadb_x_policy_len = PFKEY_UNIT64(sizeof(m_policy)); + m_policy.sadb_x_policy_exttype = SADB_X_EXT_POLICY; + m_policy.sadb_x_policy_type = SADB_X_PL_IPSEC; + m_policy.sadb_x_policy_esp_trans = 1; + m_policy.sadb_x_policy_ah_trans = 2; + m_policy.sadb_x_policy_esp_network = 3; + m_policy.sadb_x_policy_ah_network = 4; + m_policy.sadb_x_policy_reserved = 0; + + memcpy(m_buf + m_len, &m_policy, sizeof(struct sadb_x_policy)); + m_len += sizeof(struct sadb_x_policy); + } +#endif + case SADB_X_SPDDELETE: key_setsadbaddr(SADB_EXT_ADDRESS_SRC, AF_INET, "192.168.1.1"); key_setsadbaddr(SADB_EXT_ADDRESS_DST, AF_INET, "10.0.3.4"); break; } ((struct sadb_msg *)m_buf)->sadb_msg_len = PFKEY_UNIT64(m_len); return; } void key_setsadbsens() { struct sadb_sens m_sens; u_char buf[64]; u_int s, i, slen, ilen, len; /* make sens & integ */ s = htonl(0x01234567); i = htonl(0x89abcdef); slen = sizeof(s); ilen = sizeof(i); memcpy(buf, &s, slen); memcpy(buf + slen, &i, ilen); len = sizeof(m_sens) + PFKEY_ALIGN8(slen) + PFKEY_ALIGN8(ilen); m_sens.sadb_sens_len = PFKEY_UNIT64(len); m_sens.sadb_sens_exttype = SADB_EXT_SENSITIVITY; m_sens.sadb_sens_dpd = 1; m_sens.sadb_sens_sens_level = 2; m_sens.sadb_sens_sens_len = PFKEY_ALIGN8(slen); m_sens.sadb_sens_integ_level = 3; m_sens.sadb_sens_integ_len = PFKEY_ALIGN8(ilen); m_sens.sadb_sens_reserved = 0; key_setsadbextbuf(m_buf, m_len, (caddr_t)&m_sens, sizeof(struct sadb_sens), buf, slen + ilen); m_len += len; return; } void key_setsadbprop() { struct sadb_prop m_prop; struct sadb_comb *m_comb; u_char buf[256]; u_int len = sizeof(m_prop) + sizeof(m_comb) * 2; /* make prop & comb */ m_prop.sadb_prop_len = PFKEY_UNIT64(len); m_prop.sadb_prop_exttype = SADB_EXT_PROPOSAL; m_prop.sadb_prop_replay = 0; m_prop.sadb_prop_reserved[0] = 0; m_prop.sadb_prop_reserved[1] = 0; m_prop.sadb_prop_reserved[2] = 0; /* the 1st is ESP DES-CBC HMAC-MD5 */ m_comb = (struct sadb_comb *)buf; m_comb->sadb_comb_auth = SADB_AALG_MD5HMAC; m_comb->sadb_comb_encrypt = SADB_EALG_DESCBC; m_comb->sadb_comb_flags = 0; m_comb->sadb_comb_auth_minbits = 8; m_comb->sadb_comb_auth_maxbits = 96; m_comb->sadb_comb_encrypt_minbits = 64; m_comb->sadb_comb_encrypt_maxbits = 64; m_comb->sadb_comb_reserved = 0; m_comb->sadb_comb_soft_allocations = 0; m_comb->sadb_comb_hard_allocations = 0; m_comb->sadb_comb_soft_bytes = 0; m_comb->sadb_comb_hard_bytes = 0; m_comb->sadb_comb_soft_addtime = 0; m_comb->sadb_comb_hard_addtime = 0; m_comb->sadb_comb_soft_usetime = 0; m_comb->sadb_comb_hard_usetime = 0; /* the 2st is ESP 3DES-CBC and AH HMAC-SHA1 */ m_comb = (struct sadb_comb *)(buf + sizeof(*m_comb)); m_comb->sadb_comb_auth = SADB_AALG_SHA1HMAC; m_comb->sadb_comb_encrypt = SADB_EALG_3DESCBC; m_comb->sadb_comb_flags = 0; m_comb->sadb_comb_auth_minbits = 8; m_comb->sadb_comb_auth_maxbits = 96; m_comb->sadb_comb_encrypt_minbits = 64; m_comb->sadb_comb_encrypt_maxbits = 64; m_comb->sadb_comb_reserved = 0; m_comb->sadb_comb_soft_allocations = 0; m_comb->sadb_comb_hard_allocations = 0; m_comb->sadb_comb_soft_bytes = 0; m_comb->sadb_comb_hard_bytes = 0; m_comb->sadb_comb_soft_addtime = 0; m_comb->sadb_comb_hard_addtime = 0; m_comb->sadb_comb_soft_usetime = 0; m_comb->sadb_comb_hard_usetime = 0; key_setsadbextbuf(m_buf, m_len, (caddr_t)&m_prop, sizeof(struct sadb_prop), buf, sizeof(*m_comb) * 2); m_len += len; return; } void key_setsadbid(ext, str) u_int ext; caddr_t str; { struct sadb_ident m_id; u_int idlen = strlen(str), len; len = sizeof(m_id) + PFKEY_ALIGN8(idlen); m_id.sadb_ident_len = PFKEY_UNIT64(len); m_id.sadb_ident_exttype = ext; m_id.sadb_ident_type = SADB_IDENTTYPE_USERFQDN; m_id.sadb_ident_reserved = 0; m_id.sadb_ident_id = getpid(); key_setsadbextbuf(m_buf, m_len, (caddr_t)&m_id, sizeof(struct sadb_ident), str, idlen); m_len += len; return; } void key_setsadblft(ext, time) u_int ext, time; { struct sadb_lifetime m_lft; m_lft.sadb_lifetime_len = PFKEY_UNIT64(sizeof(m_lft)); m_lft.sadb_lifetime_exttype = ext; m_lft.sadb_lifetime_allocations = 0x2; m_lft.sadb_lifetime_bytes = 0x1000; m_lft.sadb_lifetime_addtime = time; m_lft.sadb_lifetime_usetime = 0x0020; memcpy(m_buf + m_len, &m_lft, sizeof(struct sadb_lifetime)); m_len += sizeof(struct sadb_lifetime); return; } void key_setspirange() { struct sadb_spirange m_spi; m_spi.sadb_spirange_len = PFKEY_UNIT64(sizeof(m_spi)); m_spi.sadb_spirange_exttype = SADB_EXT_SPIRANGE; m_spi.sadb_spirange_min = 0x00001000; m_spi.sadb_spirange_max = 0x00002000; m_spi.sadb_spirange_reserved = 0; memcpy(m_buf + m_len, &m_spi, sizeof(struct sadb_spirange)); m_len += sizeof(struct sadb_spirange); return; } void key_setsadbkey(ext, str) u_int ext; caddr_t str; { struct sadb_key m_key; u_int keylen = strlen(str); u_int len; len = sizeof(struct sadb_key) + PFKEY_ALIGN8(keylen); m_key.sadb_key_len = PFKEY_UNIT64(len); m_key.sadb_key_exttype = ext; m_key.sadb_key_bits = keylen * 8; m_key.sadb_key_reserved = 0; key_setsadbextbuf(m_buf, m_len, (caddr_t)&m_key, sizeof(struct sadb_key), str, keylen); m_len += len; return; } void key_setsadbsa() { struct sadb_sa m_sa; m_sa.sadb_sa_len = PFKEY_UNIT64(sizeof(struct sadb_sa)); m_sa.sadb_sa_exttype = SADB_EXT_SA; m_sa.sadb_sa_spi = htonl(0x12345678); m_sa.sadb_sa_replay = 4; m_sa.sadb_sa_state = 0; m_sa.sadb_sa_auth = SADB_AALG_MD5HMAC; m_sa.sadb_sa_encrypt = SADB_EALG_DESCBC; m_sa.sadb_sa_flags = 0; memcpy(m_buf + m_len, &m_sa, sizeof(struct sadb_sa)); m_len += sizeof(struct sadb_sa); return; } void key_setsadbaddr(ext, af, str) u_int ext, af; caddr_t str; { struct sadb_address m_addr; - u_char abuf[64]; - struct sockaddr *a = (struct sockaddr *)abuf; u_int len; + struct addrinfo hints, *res; + const char *serv; + int plen; + switch (af) { + case AF_INET: + plen = sizeof(struct in_addr) << 3; + break; + case AF_INET6: + plen = sizeof(struct in6_addr) << 3; + break; + default: + /* XXX bark */ + exit(1); + } + /* make sockaddr buffer */ - memset(abuf, 0, sizeof(abuf)); - a->sa_len = _SALENBYAF(af); - a->sa_family = af; - _INPORTBYSA(a) = - (ext == SADB_EXT_ADDRESS_PROXY ? 0 : htons(0x1234)); - if (inet_pton(af, str, _INADDRBYSA(a)) != 1) - ; /* XXX do something */ + memset(&hints, 0, sizeof(hints)); + hints.ai_family = af; + hints.ai_socktype = SOCK_DGRAM; /*dummy*/ + hints.ai_flags = AI_NUMERICHOST; + serv = (ext == SADB_EXT_ADDRESS_PROXY ? "0" : "4660"); /*0x1234*/ + if (getaddrinfo(str, serv, &hints, &res) != 0 || res->ai_next) { + /* XXX bark */ + exit(1); + } - len = sizeof(struct sadb_address) + PFKEY_ALIGN8(a->sa_len); + len = sizeof(struct sadb_address) + PFKEY_ALIGN8(res->ai_addrlen); m_addr.sadb_address_len = PFKEY_UNIT64(len); m_addr.sadb_address_exttype = ext; m_addr.sadb_address_proto = (ext == SADB_EXT_ADDRESS_PROXY ? 0 : IPPROTO_TCP); - m_addr.sadb_address_prefixlen = _INALENBYAF(af); + m_addr.sadb_address_prefixlen = plen; m_addr.sadb_address_reserved = 0; key_setsadbextbuf(m_buf, m_len, (caddr_t)&m_addr, sizeof(struct sadb_address), - abuf, a->sa_len); + (caddr_t)res->ai_addr, res->ai_addrlen); m_len += len; + + freeaddrinfo(res); return; } void key_setsadbextbuf(dst, off, ebuf, elen, vbuf, vlen) caddr_t dst, ebuf, vbuf; int off, elen, vlen; { memset(dst + off, 0, elen + vlen); memcpy(dst + off, (caddr_t)ebuf, elen); memcpy(dst + off + elen, vbuf, vlen); return; } Index: head/sbin/setkey/token.l =================================================================== --- head/sbin/setkey/token.l (revision 62582) +++ head/sbin/setkey/token.l (revision 62583) @@ -1,322 +1,315 @@ +/* $FreeBSD$ */ +/* $KAME: token.l,v 1.13 2000/06/07 00:29:14 itojun Exp $ */ + /* * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ %{ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "vchar.h" #include "y.tab.h" #define DECHO \ if (f_debug) {printf("<%d>", yy_start); ECHO ; printf("\n"); } #define CMDARG \ { \ char *__buf__ = strdup(yytext), *__p__; \ for (__p__ = __buf__; *__p__ != NULL; __p__++) \ if (*__p__ == '\n' || *__p__ == '\t') \ *__p__ = ' '; \ strcat(cmdarg, __buf__); \ free(__buf__); \ } #define PREPROC DECHO CMDARG -int lineno = 1; -char cmdarg[8192]; /* XXX: BUFSIZ is the better ? */ +int lineno = 1; +char cmdarg[8192]; /* XXX: BUFSIZ is the better ? */ -extern u_char m_buf[BUFSIZ]; -extern u_int m_len; -extern int f_debug; +extern u_char m_buf[BUFSIZ]; +extern u_int m_len; +extern int f_debug; -int yylex __P((void)); -void yyerror __P((char *s)); -extern void parse_init __P((void)); -int parse __P((FILE **)); -int yyparse __P((void)); +int yylex __P((void)); +void yyfatal __P((const char *s)); +void yyerror __P((const char *s)); +extern void parse_init __P((void)); +int parse __P((FILE **)); +int yyparse __P((void)); %} /* common section */ nl \n ws [ \t]+ digit [0-9] letter [0-9A-Za-z] hexdigit [0-9A-Fa-f] /*octet (([01]?{digit}?{digit})|((2([0-4]{digit}))|(25[0-5])))*/ special [()+\|\?\*,] dot \. comma \, hyphen \- colon \: slash \/ bcl \{ ecl \} blcl \[ elcl \] percent \% semi \; usec {dot}{digit}{1,6} comment \#.* ccomment "/*" bracketstring \<[^>]*\> quotedstring \"[^"]*\" decstring {digit}+ hexpair {hexdigit}{hexdigit} hexstring 0[xX]{hexdigit}+ octetstring {octet}({dot}{octet})+ -ipaddress {ipv4addr}|{ipv6addr} -ipv4addr {digit}{1,3}({dot}{digit}{1,3}){0,3} -ipv6addr {hexdigit}{0,4}({colon}{hexdigit}{0,4}){2,7}(%{letter}{letter}+)? +ipaddress [a-fA-F0-9:]([a-fA-F0-9:\.]*|[a-fA-F0-9:\.]*%[a-zA-Z0-9]*) ipaddrmask {slash}{digit}{1,3} ipaddrport {blcl}{decstring}{elcl} keyword {letter}{letter}+ name {letter}(({letter}|{digit}|{hyphen})*({letter}|{digit}))* hostname {name}(({dot}{name})+{dot}?)? %s S_PL %% add { PREPROC; return(ADD); } delete { PREPROC; return(DELETE); } get { PREPROC; return(GET); } flush { PREPROC; return(FLUSH); } dump { PREPROC; return(DUMP); } /* for management SPD */ spdadd { PREPROC; return(SPDADD); } spddelete { PREPROC; return(SPDDELETE); } spddump { PREPROC; return(SPDDUMP); } spdflush { PREPROC; return(SPDFLUSH); } {hyphen}P { BEGIN S_PL; PREPROC; return(F_POLICY); } [a-zA-Z0-9:\.\-_/ \n\t][a-zA-Z0-9:\.\-_/ \n\t]* { yymore(); /* count up for nl */ { char *p; for (p = yytext; *p != NULL; p++) if (*p == '\n') lineno++; } yylval.val.len = strlen(yytext); yylval.val.buf = strdup(yytext); return(PL_REQUESTS); } {semi} { PREPROC; BEGIN INITIAL; return(EOT); } /* security protocols */ ah { PREPROC; yylval.num = 0; return(PR_AH); } esp { PREPROC; yylval.num = 0; return(PR_ESP); } ah-old { PREPROC; yylval.num = 1; return(PR_AH); } esp-old { PREPROC; yylval.num = 1; return(PR_ESP); } ipcomp { PREPROC; yylval.num = 0; return(PR_IPCOMP); } /* authentication alogorithm */ {hyphen}A { PREPROC; return(F_AUTH); } hmac-md5 { PREPROC; yylval.num = SADB_AALG_MD5HMAC; return(ALG_AUTH); } hmac-sha1 { PREPROC; yylval.num = SADB_AALG_SHA1HMAC; return(ALG_AUTH); } keyed-md5 { PREPROC; yylval.num = SADB_AALG_MD5; return(ALG_AUTH); } keyed-sha1 { PREPROC; yylval.num = SADB_AALG_SHA; return(ALG_AUTH); } null { PREPROC; yylval.num = SADB_AALG_NULL; return(ALG_AUTH); } /* encryption alogorithm */ {hyphen}E { PREPROC; return(F_ENC); } des-cbc { PREPROC; yylval.num = SADB_EALG_DESCBC; return(ALG_ENC); } 3des-cbc { PREPROC; yylval.num = SADB_EALG_3DESCBC; return(ALG_ENC); } simple { PREPROC; yylval.num = SADB_EALG_NULL; return(ALG_ENC); } blowfish-cbc { PREPROC; yylval.num = SADB_EALG_BLOWFISHCBC; return(ALG_ENC); } cast128-cbc { PREPROC; yylval.num = SADB_EALG_CAST128CBC; return(ALG_ENC); } rc5-cbc { PREPROC; yylval.num = SADB_EALG_RC5CBC; return(ALG_ENC); } des-deriv { PREPROC; yylval.num = SADB_EALG_DESCBC; return(ALG_ENC_DESDERIV); } des-32iv { PREPROC; yylval.num = SADB_EALG_DESCBC; return(ALG_ENC_DES32IV); } /* compression algorithms */ {hyphen}C { PREPROC; return(F_COMP); } oui { PREPROC; yylval.num = SADB_X_CALG_OUI; return(ALG_COMP); } deflate { PREPROC; yylval.num = SADB_X_CALG_DEFLATE; return(ALG_COMP); } lzs { PREPROC; yylval.num = SADB_X_CALG_LZS; return(ALG_COMP); } {hyphen}R { PREPROC; return(F_RAWCPI); } /* extension */ {hyphen}m { PREPROC; return(F_MODE); } transport { PREPROC; yylval.num = IPSEC_MODE_TRANSPORT; return(MODE); } tunnel { PREPROC; yylval.num = IPSEC_MODE_TUNNEL; return(MODE); } +{hyphen}u { PREPROC; return(F_REQID); } {hyphen}f { PREPROC; return(F_EXT); } random-pad { PREPROC; yylval.num = SADB_X_EXT_PRAND; return(EXTENSION); } seq-pad { PREPROC; yylval.num = SADB_X_EXT_PSEQ; return(EXTENSION); } zero-pad { PREPROC; yylval.num = SADB_X_EXT_PZERO; return(EXTENSION); } -cyclic-seq { PREPROC; yylval.num = SADB_X_EXT_CYCSEQ; return(EXTENSION); } +nocyclic-seq { PREPROC; return(NOCYCLICSEQ); } {hyphen}r { PREPROC; return(F_REPLAY); } {hyphen}lh { PREPROC; return(F_LIFETIME_HARD); } {hyphen}ls { PREPROC; return(F_LIFETIME_SOFT); } /* upper layer protocols */ icmp { PREPROC; yylval.num = IPPROTO_ICMP; return(UP_PROTO); } icmp6 { PREPROC; yylval.num = IPPROTO_ICMPV6; return(UP_PROTO); } tcp { PREPROC; yylval.num = IPPROTO_TCP; return(UP_PROTO); } udp { PREPROC; yylval.num = IPPROTO_UDP; return(UP_PROTO); } /* ... */ any { PREPROC; return(ANY); } {ws} { PREPROC; } {nl} { lineno++; } {comment} {semi} { PREPROC; return(EOT); } /* parameter */ {decstring} { char *bp; PREPROC; - yylval.num = strtol(yytext, &bp, 10); + yylval.num = strtoul(yytext, &bp, 10); return(DECSTRING); } -{ipv4addr} { - /* - * I can't supprt the type without dot, - * because it's umbiguous against {decstring}. - * e.g. 127 - */ +{ipaddress} { PREPROC; - yylval.val.len = sizeof(struct sockaddr_in); + yylval.val.len = yyleng; yylval.val.buf = strdup(yytext); - return(IP4_ADDRESS); + return(ADDRESS); } -{ipv6addr} { -#ifdef INET6 - PREPROC; - - yylval.val.len = sizeof(struct sockaddr_in6); - yylval.val.buf = strdup(yytext); - - return(IP6_ADDRESS); -#else - yyerror("IPv6 address not supported"); -#endif - } - {ipaddrmask} { PREPROC; yytext++; yylval.num = atoi(yytext); return(PREFIX); } {ipaddrport} { char *p = yytext; PREPROC; while (*++p != ']') ; *p = NULL; yytext++; yylval.num = atoi(yytext); return(PORT); } {blcl}any{elcl} { - char *p = yytext; PREPROC; return(PORTANY); } {hexstring} { int len = yyleng - 2; /* (str - "0x") */ PREPROC; yylval.val.len = (len & 1) + (len / 2); /* fixed string if length is odd. */ if (len & 1) { yytext[1] = '0'; yylval.val.buf = strdup(yytext + 1); } else yylval.val.buf = strdup(yytext + 2); return(HEXSTRING); } {quotedstring} { char *p = yytext; PREPROC; while (*++p != '"') ; *p = NULL; yytext++; yylval.val.len = yyleng - 2; yylval.val.buf = strdup(yytext); return(QUOTEDSTRING); } -. { yyerror("Syntax error"); } +. { + yyfatal("Syntax error"); + /*NOTREACHED*/ + } %% void -yyerror(char *s) +yyfatal(s) + const char *s; { + yyerror(s); + exit(1); +} + +void +yyerror(s) + const char *s; +{ printf("line %d: %s at [%s]\n", lineno, s, yytext); } int parse(fp) FILE **fp; { yyin = *fp; parse_init(); if (yyparse()) { printf("parse failed, line %d.\n", lineno); return(-1); } return(0); } - Index: head/sbin/setkey/vchar.h =================================================================== --- head/sbin/setkey/vchar.h (revision 62582) +++ head/sbin/setkey/vchar.h (revision 62583) @@ -1,35 +1,36 @@ +/* $FreeBSD$ */ +/* $KAME: vchar.h,v 1.2 2000/06/07 00:29:14 itojun Exp $ */ + /* * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ typedef struct { - u_int len; - caddr_t buf; + u_int len; + caddr_t buf; } vchar_t; Index: head/usr.sbin/setkey/Makefile =================================================================== --- head/usr.sbin/setkey/Makefile (revision 62582) +++ head/usr.sbin/setkey/Makefile (revision 62583) @@ -1,58 +1,65 @@ # Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # 3. Neither the name of the project nor the names of its contributors # may be used to endorse or promote products derived from this software # without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # $FreeBSD$ PROG= setkey SRCS= setkey.c parse.y token.l CFLAGS+=-g +CFLAGS+=-I${.CURDIR}/../../lib/libipsec DPADD= ${LIBL} ${LIBY} LDADD= -ll -ly CLEANFILES+= y.tab.c y.tab.h key_test.o keytest YFLAGS+=-d + +# libpfkey. +# ipsec_strerror.c is for avoiding shlib reference to non-exported function. +.PATH: ${.CURDIR}/../../lib/libipsec ${.CURDIR}/../../sys/netkey +SRCS+= pfkey.c pfkey_dump.c key_debug.c ipsec_strerror.c +CFLAGS+=-I${.CURDIR}/../../lib/libipsec -I${.CURDIR}/../../sys/netkey SCRIPTS= scriptdump BINOWN = root BINGRP = bin BINMODE = 555 all: ${PROG} scriptdump SRCS+=y.tab.h y.tab.h: parse.y CFLAGS+=-DIPSEC_DEBUG -DINET6 -DYY_NO_UNPUT -I${.OBJDIR} DPADD+= ${LIBIPSEC} LDADD+= -lipsec CLEANFILES+= scriptdump y.tab.h MAN8= setkey.8 LOCALPREFIX= /usr/local scriptdump: scriptdump.pl sed -e 's#@LOCALPREFIX@#${LOCALPREFIX}#' < $> > scriptdump .include Index: head/usr.sbin/setkey/parse.y =================================================================== --- head/usr.sbin/setkey/parse.y (revision 62582) +++ head/usr.sbin/setkey/parse.y (revision 62583) @@ -1,787 +1,902 @@ +/* $FreeBSD$ */ +/* $KAME: parse.y,v 1.29 2000/06/10 14:17:44 sakane Exp $ */ + /* * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ -/* KAME $Id: parse.y,v 1.7 1999/10/27 17:08:57 sakane Exp $ */ %{ #include #include #include #include #include #include #include #include #include #include #include #include +#include #include #include -#include +#include "libpfkey.h" #include "vchar.h" #define ATOX(c) \ (isdigit(c) ? (c - '0') : (isupper(c) ? (c - 'A' + 10) : (c - 'a' + 10) )) -u_int p_type; -u_int32_t p_spi; -struct sockaddr *p_src, *p_dst; -u_int p_prefs, p_prefd, p_upper; -u_int p_satype, p_ext, p_alg_enc, p_alg_auth, p_replay, p_mode; -u_int p_key_enc_len, p_key_auth_len; -caddr_t p_key_enc, p_key_auth; -time_t p_lt_hard, p_lt_soft; +u_int p_type; +u_int32_t p_spi; +struct sockaddr *p_src, *p_dst; +u_int p_prefs, p_prefd, p_upper; +u_int p_satype, p_ext, p_alg_enc, p_alg_auth, p_replay, p_mode; +u_int32_t p_reqid; +u_int p_key_enc_len, p_key_auth_len; +caddr_t p_key_enc, p_key_auth; +time_t p_lt_hard, p_lt_soft; -u_int p_policy_len; -char *p_policy; +u_int p_policy_len; +char *p_policy; /* temporary buffer */ -static struct sockaddr *pp_addr; -static u_int pp_prefix; -static u_int pp_port; -static caddr_t pp_key; +static struct sockaddr *pp_addr; +static u_int pp_prefix; +static u_int pp_port; +static caddr_t pp_key; -extern u_char m_buf[BUFSIZ]; -extern int m_len; -extern char cmdarg[8192]; -extern int f_debug; +extern u_char m_buf[BUFSIZ]; +extern int m_len; +extern char cmdarg[8192]; +extern int f_debug; -int setkeymsg __P((void)); -static int setvarbuf __P((int *, struct sadb_ext *, int, caddr_t, int)); -void parse_init __P((void)); -void free_buffer __P((void)); +int setkeymsg __P((void)); +static struct addrinfo *parse_addr __P((char *, char *, int)); +static int setvarbuf __P((int *, struct sadb_ext *, int, caddr_t, int)); +void parse_init __P((void)); +void free_buffer __P((void)); -extern int setkeymsg __P((void)); -extern int sendkeymsg __P((void)); +extern int setkeymsg __P((void)); +extern int sendkeymsg __P((void)); -extern int yylex __P((void)); -extern void yyerror __P((char *)); +extern int yylex __P((void)); +extern void yyfatal __P((const char *)); +extern void yyerror __P((const char *)); %} %union { unsigned long num; vchar_t val; } %token EOT %token ADD GET DELETE FLUSH DUMP -%token IP4_ADDRESS IP6_ADDRESS PREFIX PORT PORTANY +%token ADDRESS PREFIX PORT PORTANY %token UP_PROTO PR_ESP PR_AH PR_IPCOMP %token F_PROTOCOL F_AUTH F_ENC F_REPLAY F_COMP F_RAWCPI -%token F_MODE MODE -%token F_EXT EXTENSION +%token F_MODE MODE F_REQID +%token F_EXT EXTENSION NOCYCLICSEQ %token ALG_AUTH ALG_ENC ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_COMP %token F_LIFETIME_HARD F_LIFETIME_SOFT %token DECSTRING QUOTEDSTRING HEXSTRING ANY /* SPD management */ %token SPDADD SPDDELETE SPDDUMP SPDFLUSH %token F_POLICY PL_REQUESTS +%type PORT PREFIX EXTENSION MODE +%type UP_PROTO PR_ESP PR_AH PR_IPCOMP +%type ALG_AUTH ALG_ENC ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_COMP +%type DECSTRING +%type ADDRESS PL_REQUESTS +%type key_string policy_requests +%type QUOTEDSTRING HEXSTRING + %% commands : /*NOTHING*/ | commands command { if (f_debug) { printf("cmdarg:\n%s\n", cmdarg); } else { setkeymsg(); sendkeymsg(); } free_buffer(); parse_init(); } ; command : add_command | get_command | delete_command | flush_command | dump_command | spdadd_command | spddelete_command | spddump_command | spdflush_command ; /* commands concerned with management, there is in tail of this file. */ /* add command */ add_command : ADD { p_type = SADB_ADD; } sa_selector_spec extension_spec algorithm_spec EOT ; /* delete */ delete_command : DELETE { p_type = SADB_DELETE; } - sa_selector_spec extension_spec EOT + sa_selector_spec extension_spec + { + if (p_mode != IPSEC_MODE_ANY) + yyerror("WARNING: mode is obsoleted."); + } + EOT ; /* get command */ get_command : GET { p_type = SADB_GET; } - sa_selector_spec extension_spec EOT + sa_selector_spec extension_spec + { + if (p_mode != IPSEC_MODE_ANY) + yyerror("WARNING: mode is obsoleted."); + } + EOT ; /* flush */ flush_command : FLUSH { p_type = SADB_FLUSH; } protocol_spec EOT ; /* dump */ dump_command : DUMP { p_type = SADB_DUMP; } protocol_spec EOT ; /* sa_selector_spec */ sa_selector_spec : ipaddress { p_src = pp_addr; } ipaddress { p_dst = pp_addr; } protocol_spec spi ; protocol_spec : /*NOTHING*/ { p_satype = SADB_SATYPE_UNSPEC; } | PR_ESP { p_satype = SADB_SATYPE_ESP; - if ($1.num == 1) + if ($1 == 1) p_ext |= SADB_X_EXT_OLD; else p_ext &= ~SADB_X_EXT_OLD; } | PR_AH { p_satype = SADB_SATYPE_AH; - if ($1.num == 1) + if ($1 == 1) p_ext |= SADB_X_EXT_OLD; else p_ext &= ~SADB_X_EXT_OLD; } | PR_IPCOMP { p_satype = SADB_X_SATYPE_IPCOMP; } ; spi - : DECSTRING { p_spi = $1.num; } + : DECSTRING { p_spi = $1; } | HEXSTRING { caddr_t bp; - caddr_t yp = $1.val.buf; + caddr_t yp = $1.buf; char buf0[4], buf[4]; int i, j; /* sanity check */ - if ($1.val.len > 4) { + if ($1.len > 4) { yyerror("SPI too big."); - free($1.val.buf); + free($1.buf); return -1; } bp = buf0; while (*yp) { *bp = (ATOX(yp[0]) << 4) | ATOX(yp[1]); yp += 2, bp++; } /* initialize */ for (i = 0; i < 4; i++) buf[i] = 0; - for (j = $1.val.len - 1, i = 3; j >= 0; j--, i--) + for (j = $1.len - 1, i = 3; j >= 0; j--, i--) buf[i] = buf0[j]; /* XXX: endian */ p_spi = ntohl(*(u_int32_t *)buf); - free($1.val.buf); + free($1.buf); } ; algorithm_spec : esp_spec | ah_spec | ipcomp_spec ; esp_spec : F_ENC enc_alg enc_key F_AUTH auth_alg auth_key | F_ENC enc_alg enc_key ; ah_spec : F_AUTH auth_alg auth_key ; ipcomp_spec - : F_COMP ALG_COMP { p_alg_enc = $2.num; } - | F_COMP ALG_COMP { p_alg_enc = $2.num; } + : F_COMP ALG_COMP { p_alg_enc = $2; } + | F_COMP ALG_COMP { p_alg_enc = $2; } F_RAWCPI { p_ext |= SADB_X_EXT_RAWCPI; } ; enc_alg - : ALG_ENC { p_alg_enc = $1.num; } + : ALG_ENC { p_alg_enc = $1; } | ALG_ENC_DESDERIV { - p_alg_enc = $1.num; + p_alg_enc = $1; if (p_ext & SADB_X_EXT_OLD) { yyerror("algorithm mismatched."); return -1; } p_ext |= SADB_X_EXT_DERIV; } | ALG_ENC_DES32IV { - p_alg_enc = $1.num; + p_alg_enc = $1; if (!(p_ext & SADB_X_EXT_OLD)) { yyerror("algorithm mismatched."); return -1; } p_ext |= SADB_X_EXT_IV4B; } ; enc_key : /*NOTHING*/ { if (p_alg_enc != SADB_EALG_NULL) { yyerror("no key found."); return -1; } } | key_string { - p_key_enc_len = $1.val.len; + p_key_enc_len = $1.len; p_key_enc = pp_key; if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT, p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) { yyerror(ipsec_strerror()); return -1; } } ; auth_alg - : ALG_AUTH { p_alg_auth = $1.num; } + : ALG_AUTH { p_alg_auth = $1; } ; auth_key : /*NOTHING*/ { if (p_alg_auth != SADB_AALG_NULL) { yyerror("no key found."); return -1; } } | key_string { - p_key_auth_len = $1.val.len; + p_key_auth_len = $1.len; p_key_auth = pp_key; if (ipsec_check_keylen(SADB_EXT_SUPPORTED_AUTH, p_alg_auth, PFKEY_UNUNIT64(p_key_auth_len)) < 0) { yyerror(ipsec_strerror()); return -1; } } ; key_string : QUOTEDSTRING { - pp_key = $1.val.buf; + pp_key = $1.buf; /* free pp_key later */ } | HEXSTRING { caddr_t bp; - caddr_t yp = $1.val.buf; + caddr_t yp = $1.buf; - if ((pp_key = malloc($1.val.len)) == 0) { - free($1.val.buf); - yyerror(strerror(errno)); + if ((pp_key = malloc($1.len)) == 0) { + free($1.buf); + yyerror("not enough core"); return -1; } - memset(pp_key, 0, $1.val.len); + memset(pp_key, 0, $1.len); bp = pp_key; while (*yp) { *bp = (ATOX(yp[0]) << 4) | ATOX(yp[1]); yp += 2, bp++; } - free($1.val.buf); + free($1.buf); } ; extension_spec : /*NOTHING*/ | extension_spec extension ; extension - : F_EXT EXTENSION { p_ext |= $1.num; } - | F_MODE MODE { p_mode = $2.num; } + : F_EXT EXTENSION { p_ext |= $2; } + | F_EXT NOCYCLICSEQ { p_ext &= ~SADB_X_EXT_CYCSEQ; } + | F_MODE MODE { p_mode = $2; } | F_MODE ANY { p_mode = IPSEC_MODE_ANY; } + | F_REQID DECSTRING { p_reqid = $2; } | F_REPLAY DECSTRING { if (p_ext & SADB_X_EXT_OLD) { yyerror("replay prevention " "only use on new spec."); return -1; } - p_replay = $2.num; + p_replay = $2; } - | F_LIFETIME_HARD DECSTRING { p_lt_hard = $2.num; } - | F_LIFETIME_SOFT DECSTRING { p_lt_soft = $2.num; } + | F_LIFETIME_HARD DECSTRING { p_lt_hard = $2; } + | F_LIFETIME_SOFT DECSTRING { p_lt_soft = $2; } ; /* definition about command for SPD management */ /* spdadd */ spdadd_command : SPDADD { p_type = SADB_X_SPDADD; p_satype = SADB_SATYPE_UNSPEC; } sp_selector_spec policy_spec EOT ; spddelete_command: SPDDELETE { p_type = SADB_X_SPDDELETE; p_satype = SADB_SATYPE_UNSPEC; } - sp_selector_spec EOT + sp_selector_spec policy_spec EOT ; spddump_command: SPDDUMP { p_type = SADB_X_SPDDUMP; p_satype = SADB_SATYPE_UNSPEC; } EOT ; spdflush_command: SPDFLUSH { p_type = SADB_X_SPDFLUSH; p_satype = SADB_SATYPE_UNSPEC; } EOT ; /* sp_selector_spec */ sp_selector_spec : ipaddress { p_src = pp_addr; } prefix { p_prefs = pp_prefix; } - port { _INPORTBYSA(p_src) = htons(pp_port); } + port + { + switch (p_src->sa_family) { + case AF_INET: + ((struct sockaddr_in *)p_src)->sin_port = + htons(pp_port); + break; +#ifdef INET6 + case AF_INET6: + ((struct sockaddr_in6 *)p_src)->sin6_port = + htons(pp_port); + break; +#endif + default: + exit(1); /*XXX*/ + } + } ipaddress { p_dst = pp_addr; } prefix { p_prefd = pp_prefix; } - port { _INPORTBYSA(p_dst) = htons(pp_port); } + port + { + switch (p_dst->sa_family) { + case AF_INET: + ((struct sockaddr_in *)p_dst)->sin_port = + htons(pp_port); + break; +#ifdef INET6 + case AF_INET6: + ((struct sockaddr_in6 *)p_dst)->sin6_port = + htons(pp_port); + break; +#endif + default: + exit(1); /*XXX*/ + } + } upper_spec + { + /* XXX is it something userland should check? */ +#if 0 + switch (p_upper) { + case IPPROTO_ICMP: + case IPPROTO_ICMPV6: + if (_INPORTBYSA(p_src) != IPSEC_PORT_ANY + || _INPORTBYSA(p_dst) != IPSEC_PORT_ANY) { + yyerror("port number must be \"any\"."); + return -1; + } + if ((pp_addr->sa_family == AF_INET6 + && p_upper == IPPROTO_ICMP) + || (pp_addr->sa_family == AF_INET + && p_upper == IPPROTO_ICMPV6)) { + yyerror("upper layer protocol " + "mismatched.\n"); + return -1; + } + break; + default: + break; + } +#endif + } ; ipaddress - : IP4_ADDRESS + : ADDRESS { - struct sockaddr_in *in; - u_int sa_len = $1.val.len; + struct addrinfo *res; - if ((in = (struct sockaddr_in *)malloc(sa_len)) == 0) { - yyerror(strerror(errno)); - free($1.val.buf); + res = parse_addr($1.buf, NULL, AI_NUMERICHOST); + if (res == NULL) { + free($1.buf); return -1; } - memset((caddr_t)in, 0, sa_len); - - in->sin_family = PF_INET; - in->sin_len = sa_len; - in->sin_port = IPSEC_PORT_ANY; - (void)inet_pton(PF_INET, $1.val.buf, &in->sin_addr); - - pp_addr = (struct sockaddr *)in; - free($1.val.buf); - } - | IP6_ADDRESS - { -#ifdef INET6 - struct sockaddr_in6 *in6; - u_int sa_len = $1.val.len; - struct addrinfo hints, *res; - int ret_gai; - - if ((in6 = (struct sockaddr_in6 *)malloc(sa_len)) == 0) { - free($1.val.buf); - yyerror(strerror(errno)); - return -1; + pp_addr = (struct sockaddr *)malloc(res->ai_addrlen); + if (!pp_addr) { + yyerror("not enough core"); + goto end; } - memset((caddr_t)in6, 0, sa_len); - bzero(&hints, sizeof(struct addrinfo)); - hints.ai_flags = AI_NUMERICHOST; - hints.ai_family = AF_INET6; - ret_gai = getaddrinfo($1.val.buf, NULL, &hints, &res); - if (ret_gai) { - free($1.val.buf); - free(in6); - yyerror(gai_strerror(ret_gai)); - if (ret_gai == EAI_SYSTEM) - yyerror(strerror(errno)); - return -1; - } - (void)memcpy(in6, res->ai_addr, res->ai_addrlen); - - /* - * XXX: If the scope of the destination is link-local, - * embed the scope-id(in this case, interface index) - * into the address. - */ - if (IN6_IS_ADDR_LINKLOCAL(&in6->sin6_addr) && - in6->sin6_scope_id != 0) - *(u_short *)&in6->sin6_addr.s6_addr[2] = - htons(in6->sin6_scope_id & 0xffff); - + memcpy(pp_addr, res->ai_addr, res->ai_addrlen); + end: freeaddrinfo(res); - - pp_addr = (struct sockaddr *)in6; -#else - yyerror("IPv6 address not supported"); -#endif - free($1.val.buf); + free($1.buf); } ; prefix : /*NOTHING*/ { pp_prefix = ~0; } - | PREFIX { pp_prefix = $1.num; } + | PREFIX { pp_prefix = $1; } ; port : /*NOTHING*/ { pp_port = IPSEC_PORT_ANY; } - | PORT { pp_port = $1.num; } + | PORT { pp_port = $1; } | PORTANY { pp_port = IPSEC_PORT_ANY; } ; upper_spec - : DECSTRING { p_upper = $1.num; } - | UP_PROTO { p_upper = $1.num; } + : DECSTRING { p_upper = $1; } + | UP_PROTO { p_upper = $1; } | PR_ESP { p_upper = IPPROTO_ESP; }; | PR_AH { p_upper = IPPROTO_AH; }; | PR_IPCOMP { p_upper = IPPROTO_IPCOMP; }; | ANY { p_upper = IPSEC_ULPROTO_ANY; } ; policy_spec : F_POLICY policy_requests { - p_policy = ipsec_set_policy($2.val.buf, $2.val.len); + p_policy = ipsec_set_policy($2.buf, $2.len); if (p_policy == NULL) { - free($2.val.buf); + free($2.buf); p_policy = NULL; yyerror(ipsec_strerror()); return -1; } p_policy_len = ipsec_get_policylen(p_policy); - free($2.val.buf); + free($2.buf); } ; -policy_requests: - /*NOTHING*/ - | PL_REQUESTS { $$ = $1; } +policy_requests + : PL_REQUESTS { $$ = $1; } ; %% int setkeymsg() { struct sadb_msg m_msg; m_msg.sadb_msg_version = PF_KEY_V2; m_msg.sadb_msg_type = p_type; m_msg.sadb_msg_errno = 0; m_msg.sadb_msg_satype = p_satype; - m_msg.sadb_msg_mode = p_mode; m_msg.sadb_msg_reserved = 0; m_msg.sadb_msg_seq = 0; m_msg.sadb_msg_pid = getpid(); m_len = sizeof(struct sadb_msg); memcpy(m_buf, &m_msg, m_len); switch (p_type) { case SADB_FLUSH: case SADB_DUMP: break; case SADB_ADD: /* set encryption algorithm, if present. */ if (p_satype != SADB_X_SATYPE_IPCOMP && p_alg_enc != SADB_EALG_NONE) { struct sadb_key m_key; m_key.sadb_key_len = PFKEY_UNIT64(sizeof(m_key) + PFKEY_ALIGN8(p_key_enc_len)); m_key.sadb_key_exttype = SADB_EXT_KEY_ENCRYPT; m_key.sadb_key_bits = p_key_enc_len * 8; m_key.sadb_key_reserved = 0; setvarbuf(&m_len, (struct sadb_ext *)&m_key, sizeof(m_key), (caddr_t)p_key_enc, p_key_enc_len); } /* set authentication algorithm, if present. */ if (p_alg_auth != SADB_AALG_NONE) { struct sadb_key m_key; m_key.sadb_key_len = PFKEY_UNIT64(sizeof(m_key) + PFKEY_ALIGN8(p_key_auth_len)); m_key.sadb_key_exttype = SADB_EXT_KEY_AUTH; m_key.sadb_key_bits = p_key_auth_len * 8; m_key.sadb_key_reserved = 0; setvarbuf(&m_len, (struct sadb_ext *)&m_key, sizeof(m_key), (caddr_t)p_key_auth, p_key_auth_len); } /* set lifetime for HARD */ if (p_lt_hard != 0) { struct sadb_lifetime m_lt; u_int len = sizeof(struct sadb_lifetime); m_lt.sadb_lifetime_len = PFKEY_UNIT64(len); m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD; m_lt.sadb_lifetime_allocations = 0; m_lt.sadb_lifetime_bytes = 0; m_lt.sadb_lifetime_addtime = p_lt_hard; m_lt.sadb_lifetime_usetime = 0; memcpy(m_buf + m_len, &m_lt, len); m_len += len; } /* set lifetime for SOFT */ if (p_lt_soft != 0) { struct sadb_lifetime m_lt; u_int len = sizeof(struct sadb_lifetime); m_lt.sadb_lifetime_len = PFKEY_UNIT64(len); m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_SOFT; m_lt.sadb_lifetime_allocations = 0; m_lt.sadb_lifetime_bytes = 0; m_lt.sadb_lifetime_addtime = p_lt_soft; m_lt.sadb_lifetime_usetime = 0; memcpy(m_buf + m_len, &m_lt, len); m_len += len; } /* FALLTHROUGH */ case SADB_DELETE: case SADB_GET: { struct sadb_sa m_sa; + struct sadb_x_sa2 m_sa2; struct sadb_address m_addr; u_int len; len = sizeof(struct sadb_sa); m_sa.sadb_sa_len = PFKEY_UNIT64(len); m_sa.sadb_sa_exttype = SADB_EXT_SA; m_sa.sadb_sa_spi = htonl(p_spi); m_sa.sadb_sa_replay = p_replay; m_sa.sadb_sa_state = 0; m_sa.sadb_sa_auth = p_alg_auth; m_sa.sadb_sa_encrypt = p_alg_enc; m_sa.sadb_sa_flags = p_ext; memcpy(m_buf + m_len, &m_sa, len); m_len += len; + len = sizeof(struct sadb_x_sa2); + m_sa2.sadb_x_sa2_len = PFKEY_UNIT64(len); + m_sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2; + m_sa2.sadb_x_sa2_mode = p_mode; + m_sa2.sadb_x_sa2_reqid = p_reqid; + + memcpy(m_buf + m_len, &m_sa2, len); + m_len += len; + /* set src */ m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + PFKEY_ALIGN8(p_src->sa_len)); m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC; m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY; - m_addr.sadb_address_prefixlen = - _INALENBYAF(p_src->sa_family) << 3; + switch (p_src->sa_family) { + case AF_INET: + m_addr.sadb_address_prefixlen = + sizeof(struct in_addr) << 3; + break; +#ifdef INET6 + case AF_INET6: + m_addr.sadb_address_prefixlen = + sizeof(struct in6_addr) << 3; + break; +#endif + default: + yyerror("unsupported address family"); + exit(1); /*XXX*/ + } m_addr.sadb_address_reserved = 0; setvarbuf(&m_len, (struct sadb_ext *)&m_addr, sizeof(m_addr), (caddr_t)p_src, p_src->sa_len); /* set dst */ m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + PFKEY_ALIGN8(p_dst->sa_len)); m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST; m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY; - m_addr.sadb_address_prefixlen = - _INALENBYAF(p_dst->sa_family) << 3; + switch (p_dst->sa_family) { + case AF_INET: + m_addr.sadb_address_prefixlen = + sizeof(struct in_addr) << 3; + break; +#ifdef INET6 + case AF_INET6: + m_addr.sadb_address_prefixlen = + sizeof(struct in6_addr) << 3; + break; +#endif + default: + yyerror("unsupported address family"); + exit(1); /*XXX*/ + } m_addr.sadb_address_reserved = 0; setvarbuf(&m_len, (struct sadb_ext *)&m_addr, sizeof(m_addr), (caddr_t)p_dst, p_dst->sa_len); } break; /* for SPD management */ case SADB_X_SPDFLUSH: case SADB_X_SPDDUMP: break; case SADB_X_SPDADD: + case SADB_X_SPDDELETE: { + struct sadb_address m_addr; + u_int8_t plen; + memcpy(m_buf + m_len, p_policy, p_policy_len); m_len += p_policy_len; free(p_policy); p_policy = NULL; - } - /* FALLTHROUGH */ - case SADB_X_SPDDELETE: - { - struct sadb_address m_addr; - /* set src */ m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + PFKEY_ALIGN8(p_src->sa_len)); m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC; m_addr.sadb_address_proto = p_upper; + switch (p_src->sa_family) { + case AF_INET: + plen = sizeof(struct in_addr) << 3; + break; +#ifdef INET6 + case AF_INET6: + plen = sizeof(struct in6_addr) << 3; + break; +#endif + default: + yyerror("unsupported address family"); + exit(1); /*XXX*/ + } m_addr.sadb_address_prefixlen = - (p_prefs != ~0 ? p_prefs : - _INALENBYAF(p_src->sa_family) << 3); + (p_prefs != ~0 ? p_prefs : plen); m_addr.sadb_address_reserved = 0; setvarbuf(&m_len, (struct sadb_ext *)&m_addr, sizeof(m_addr), (caddr_t)p_src, p_src->sa_len); /* set dst */ m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + PFKEY_ALIGN8(p_dst->sa_len)); m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST; m_addr.sadb_address_proto = p_upper; + switch (p_dst->sa_family) { + case AF_INET: + plen = sizeof(struct in_addr) << 3; + break; +#ifdef INET6 + case AF_INET6: + plen = sizeof(struct in6_addr) << 3; + break; +#endif + default: + yyerror("unsupported address family"); + exit(1); /*XXX*/ + } m_addr.sadb_address_prefixlen = - (p_prefd != ~0 ? p_prefd : - _INALENBYAF(p_dst->sa_family) << 3); + (p_prefd != ~0 ? p_prefd : plen); m_addr.sadb_address_reserved = 0; setvarbuf(&m_len, (struct sadb_ext *)&m_addr, sizeof(m_addr), (caddr_t)p_dst, p_dst->sa_len); } break; } ((struct sadb_msg *)m_buf)->sadb_msg_len = PFKEY_UNIT64(m_len); return 0; } +static struct addrinfo * +parse_addr(host, port, flag) + char *host; + char *port; + int flag; +{ + struct addrinfo hints, *res = NULL; + int error; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; + hints.ai_flags = flag; + error = getaddrinfo(host, port, &hints, &res); + if (error != 0) { + yyerror(gai_strerror(error)); + return NULL; + } + if (res->ai_next != NULL) { + yyerror(gai_strerror(error)); + } + return res; +} + static int setvarbuf(off, ebuf, elen, vbuf, vlen) caddr_t vbuf; struct sadb_ext *ebuf; int *off, elen, vlen; { memset(m_buf + *off, 0, PFKEY_UNUNIT64(ebuf->sadb_ext_len)); memcpy(m_buf + *off, (caddr_t)ebuf, elen); memcpy(m_buf + *off + elen, vbuf, vlen); (*off) += PFKEY_ALIGN8(elen + vlen); return 0; } void parse_init() { p_type = 0; p_spi = 0; p_src = 0, p_dst = 0; pp_prefix = p_prefs = p_prefd = ~0; pp_port = IPSEC_PORT_ANY; p_upper = 0; p_satype = 0; - p_ext = SADB_X_EXT_NONE; + p_ext = SADB_X_EXT_CYCSEQ; p_alg_enc = SADB_EALG_NONE; p_alg_auth = SADB_AALG_NONE; p_mode = IPSEC_MODE_ANY; - p_replay = 4; + p_reqid = 0; + p_replay = 0; p_key_enc_len = p_key_auth_len = 0; p_key_enc = p_key_auth = 0; p_lt_hard = p_lt_soft = 0; p_policy_len = 0; p_policy = NULL; memset(cmdarg, 0, sizeof(cmdarg)); return; } void free_buffer() { if (p_src) free(p_src); if (p_dst) free(p_dst); if (p_key_enc) free(p_key_enc); if (p_key_auth) free(p_key_auth); return; } Index: head/usr.sbin/setkey/sample.cf =================================================================== --- head/usr.sbin/setkey/sample.cf (revision 62582) +++ head/usr.sbin/setkey/sample.cf (revision 62583) @@ -1,219 +1,219 @@ # Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # 3. Neither the name of the project nor the names of its contributors # may be used to endorse or promote products derived from this software # without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # # $FreeBSD$ # There are sample scripts for IPsec configuration by manual keying. # A security association is uniquely identified by a triple consisting # of a Security Parameter Index (SPI), an IP Destination Address, and a # security protocol (AH or ESP) identifier. You must take care of these # parameters when you configure by manual keying. # ESP transport mode is recommended for TCP port number 110 between # Host-A and Host-B. Encryption algorithm is blowfish-cbc whose key # is "kamekame", and authentication algorithm is hmac-sha1 whose key # is "this is the test key". # # ============ ESP ============ # | | # Host-A Host-B # fec0::10 -------------------- fec0::11 # # At Host-A and Host-B, spdadd fec0::10[any] fec0::11[110] tcp -P out ipsec esp/transport/fec0::10-fec0::11/use ; spdadd fec0::11[110] fec0::10[any] tcp -P in ipsec esp/transport/fec0::11-fec0::10/use ; add fec0::10 fec0::11 esp 0x10001 -m transport -E blowfish-cbc "kamekame" -A hmac-sha1 "this is the test key" ; add fec0::11 fec0::10 esp 0x10002 -m transport -E blowfish-cbc "kamekame" -A hmac-sha1 "this is the test key" ; # "[any]" is wildcard of port number. Note that "[0]" is the number of # zero in port number. # Security protocol is old AH tunnel mode, i.e. RFC1826, with keyed-md5 # whose key is "this is the test" as authentication algorithm. # That protocol takes place between Gateway-A and Gateway-B. # # ======= AH ======= # | | # Network-A Gateway-A Gateway-B Network-B # 10.0.1.0/24 ---- 172.16.0.1 ----- 172.16.0.2 ---- 10.0.2.0/24 # # At Gateway-A: spdadd 10.0.1.0/24 10.0.2.0/24 any -P out ipsec ah/tunnel/172.16.0.1-172.16.0.2/require ; spdadd 10.0.2.0/24 10.0.1.0/24 any -P in ipsec ah/tunnel/172.16.0.2-172.16.0.1/require ; add 172.16.0.1 172.16.0.2 ah-old 0x10003 -m any -A keyed-md5 "this is the test" ; add 172.16.0.2 172.16.0.1 ah-old 0x10004 -m any -A keyed-md5 "this is the test" ; # If port number field is omitted such above then "[any]" is employed. # -m specifies the mode of SA to be used. "-m any" means wildcard of # mode of security protocol. You can use this SAs for both tunnel and # transport mode. # At Gateway-B. Attention to the selector and peer's IP address for tunnel. spdadd 10.0.2.0/24 10.0.1.0/24 any -P out ipsec ah/tunnel/172.16.0.2-172.16.0.1/require ; spdadd 10.0.1.0/24 10.0.2.0/24 any -P in ipsec ah/tunnel/172.16.0.1-172.16.0.2/require ; add 172.16.0.1 172.16.0.2 ah-old 0x10003 -m tunnel -A keyed-md5 "this is the test" ; add 172.16.0.2 172.16.0.1 ah-old 0x10004 -m tunnel -A keyed-md5 "this is the test" ; # AH transport mode followed by ESP tunnel mode is required between # Gateway-A and Gateway-B. # Encryption algorithm is 3des-cbc, and authentication algorithm for ESP # is hmac-sha1. Authentication algorithm for AH is hmac-md5. # # ========== AH ========= # | ======= ESP ===== | # | | | | # Network-A Gateway-A Gateway-B Network-B # fec0:0:0:1::/64 --- fec0:0:0:1::1 ---- fec0:0:0:2::1 --- fec0:0:0:2::/64 # # At Gateway-A: spdadd fec0:0:0:1::/64 fec0:0:0:2::/64 any -P out ipsec esp/tunnel/fec0:0:0:1::1-fec0:0:0:2::1/require ah/transport/fec0:0:0:1::1-fec0:0:0:2::1/require ; spdadd fec0:0:0:2::/64 fec0:0:0:1::/64 any -P in ipsec esp/tunnel/fec0:0:0:2::1-fec0:0:0:1::1/require ah/transport/fec0:0:0:2::1-fec0:0:0:1::1/require ; add fec0:0:0:1::1 fec0:0:0:2::1 esp 0x10001 -m tunnel -E 3des-cbc "kamekame12341234kame1234" -A hmac-sha1 "this is the test key" ; add fec0:0:0:1::1 fec0:0:0:2::1 ah 0x10001 -m transport -A hmac-md5 "this is the test" ; add fec0:0:0:2::1 fec0:0:0:1::1 esp 0x10001 -m tunnel -E 3des-cbc "kamekame12341234kame1234" -A hmac-sha1 "this is the test key" ; add fec0:0:0:2::1 fec0:0:0:1::1 ah 0x10001 -m transport -A hmac-md5 "this is the test" ; # ESP tunnel mode is required between Host-A and Gateway-A. # Encryption algorithm is cast128-cbc, and authentication algorithm # for ESP is hmac-sha1. # ESP transport mode is recommended between Host-A and Host-B. # Encryption algorithm is rc5-cbc, and authentication algorithm # for ESP is hmac-md5. # # ================== ESP ================= # | ======= ESP ======= | # | | | | # Host-A Gateway-A Host-B # fec0:0:0:1::1 ---- fec0:0:0:2::1 ---- fec0:0:0:2::2 # # At Host-A: spdadd fec0:0:0:1::1[any] fec0:0:0:2::2[80] tcp -P out ipsec esp/transport/fec0:0:0:1::1-fec0:0:0:2::2/use esp/tunnel/fec0:0:0:1::1-fec0:0:0:2::1/require ; spdadd fec0:0:0:2::1[80] fec0:0:0:1::1[any] tcp -P in ipsec esp/transport/fec0:0:0:2::2-fec0:0:0:1::1/use esp/tunnel/fec0:0:0:2::1-fec0:0:0:1::1/require ; add fec0:0:0:1::1 fec0:0:0:2::2 esp 0x10001 -m transport -E cast128-cbc "12341234" -A hmac-sha1 "this is the test key" ; add fec0:0:0:1::1 fec0:0:0:2::1 esp 0x10002 -E rc5-cbc "kamekame" -A hmac-md5 "this is the test" ; add fec0:0:0:2::2 fec0:0:0:1::1 esp 0x10003 -m transport -E cast128-cbc "12341234" -A hmac-sha1 "this is the test key" ; add fec0:0:0:2::1 fec0:0:0:1::1 esp 0x10004 -E rc5-cbc "kamekame" -A hmac-md5 "this is the test" ; # By "get" command, you can get a entry of either SP or SA. get fec0:0:0:1::1 fec0:0:0:2::2 ah 0x10004 ; # Also delete command, you can delete a entry of either SP or SA. -spddelete out fec0:0:0:1::/64 fec0:0:0:2:/64 any ; +spddelete fec0:0:0:1::/64 fec0:0:0:2::/64 any -P out; delete fec0:0:0:1::1 fec0:0:0:2::2 ah 0x10004 ; # By dump command, you can dump all entry of either SP or SA. dump ; spddump ; dump esp ; flush esp ; # By flush command, you can flush all entry of either SP or SA. flush ; spdflush ; # "flush" and "dump" commands can specify a security protocol. dump esp ; flush ah ; # XXX add ::1 ::1 esp 10001 -m transport -E simple ; add ::1 ::1 esp 10002 -m transport -E des-deriv "12341234" ; add ::1 ::1 esp-old 10003 -m transport -E des-32iv "12341234" ; add ::1 ::1 esp 10004 -m transport -E simple -A null ; add ::1 ::1 esp 10005 -m transport -E simple -A hmac-md5 "1234123412341234" ; add ::1 ::1 esp 10006 -m tunnel -E simple -A hmac-sha1 "12341234123412341234" ; add ::1 ::1 esp 10007 -m transport -E simple -A keyed-md5 "1234123412341234" ; add ::1 ::1 esp 10008 -m any -E simple -A keyed-sha1 "12341234123412341234" ; add ::1 ::1 esp 10009 -m transport -E des-cbc "testtest" ; add ::1 ::1 esp 10010 -m transport -E 3des-cbc "testtest12341234testtest" ; add ::1 ::1 esp 10011 -m tunnel -E cast128-cbc "testtest1234" ; add ::1 ::1 esp 10012 -m tunnel -E blowfish-cbc "testtest1234" ; add ::1 ::1 esp 10013 -m tunnel -E rc5-cbc "testtest1234" ; add ::1 ::1 esp 10014 -m any -E rc5-cbc "testtest1234" ; add ::1 ::1 esp 10015 -m transport -f zero-pad -E simple ; add ::1 ::1 esp 10016 -m tunnel -f random-pad -r 8 -lh 100 -ls 80 -E simple ; -add ::1 ::1 esp 10017 -m transport -f seq-pad -f cyclic-seq -E simple ; +add ::1 ::1 esp 10017 -m transport -f seq-pad -f nocyclic-seq -E simple ; add ::1 ::1 esp 10018 -m transport -E simple ; #add ::1 ::1 ah 20000 -m transport -A null ; add ::1 ::1 ah 20001 -m any -A hmac-md5 "1234123412341234"; add ::1 ::1 ah 20002 -m tunnel -A hmac-sha1 "12341234123412341234"; add ::1 ::1 ah 20003 -m transport -A keyed-md5 "1234123412341234"; add ::1 ::1 ah-old 20004 -m transport -A keyed-md5 "1234123412341234"; add ::1 ::1 ah 20005 -m transport -A keyed-sha1 "12341234123412341234"; #add ::1 ::1 ipcomp 30000 -C oui ; add ::1 ::1 ipcomp 30001 -C deflate ; #add ::1 ::1 ipcomp 30002 -C lzs ; # enjoy. Index: head/usr.sbin/setkey/scriptdump.pl =================================================================== --- head/usr.sbin/setkey/scriptdump.pl (revision 62582) +++ head/usr.sbin/setkey/scriptdump.pl (revision 62583) @@ -1,54 +1,56 @@ #! @LOCALPREFIX@/bin/perl # $FreeBSD$ if ($< != 0) { print STDERR "must be root to invoke this\n"; exit 1; } $mode = 'add'; while ($i = shift @ARGV) { if ($i eq '-d') { $mode = 'delete'; } else { print STDERR "usage: scriptdump [-d]\n"; exit 1; } } open(IN, "setkey -D |") || die; foreach $_ () { if (/^[^\t]/) { ($src, $dst) = split(/\s+/, $_); - } elsif (/^\t(esp|ah) mode=(\S+) spi=(\d+).*replay=(\d+)/) { - ($proto, $ipsecmode, $spi, $replay) = ($1, $2, $3, $4); + } elsif (/^\t(esp|ah) mode=(\S+) spi=(\d+).*reqid=(\d+)/) { + ($proto, $ipsecmode, $spi, $reqid) = ($1, $2, $3, $4); } elsif (/^\tE: (\S+) (.*)/) { $ealgo = $1; $ekey = $2; $ekey =~ s/\s//g; $ekey =~ s/^/0x/g; } elsif (/^\tA: (\S+) (.*)/) { $aalgo = $1; $akey = $2; $akey =~ s/\s//g; $akey =~ s/^/0x/g; - } elsif (/^\tstate=/) { + } elsif (/^\treplay=(\d+) flags=(0x\d+) state=/) { print "$mode $src $dst $proto $spi -m $ipsecmode"; - print " -r $replay" if $replay; + $replay = $1; + print " -u $reqid" if $reqid; if ($mode eq 'add') { + print " -r $replay" if $replay; if ($proto eq 'esp') { print " -E $ealgo $ekey" if $ealgo; print " -A $aalgo $akey" if $aalgo; } elsif ($proto eq 'ah') { print " -A $aalgo $akey" if $aalgo; } - } + } print ";\n"; $src = $dst = $upper = $proxy = ''; $ealgo = $ekey = $aalgo = $akey = ''; } } close(IN); exit 0; Index: head/usr.sbin/setkey/setkey.8 =================================================================== --- head/usr.sbin/setkey/setkey.8 (revision 62582) +++ head/usr.sbin/setkey/setkey.8 (revision 62583) @@ -1,552 +1,561 @@ +.\" $FreeBSD$ +.\" $KAME: setkey.8,v 1.28 2000/06/16 12:03:46 sakane Exp $ +.\" .\" Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. .\" All rights reserved. -.\" +.\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" 3. Neither the name of the project nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. -.\" +.\" .\" THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE .\" ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $Id: setkey.8,v 1.14 1999/10/27 17:08:58 sakane Exp $ -.\" $FreeBSD$ -.\" .Dd May 17, 1998 .Dt SETKEY 8 -.Os +.Os KAME +.\" .Sh NAME .Nm setkey -.Nd manually manipulate the SA/SP database. +.Nd manually manipulate the IPsec SA/SP database. +.\" .Sh SYNOPSIS .Nm setkey .Op Fl dv .Fl c .Nm setkey .Op Fl dv .Fl f Ar filename .Nm setkey .Op Fl adPlv .Fl D .Nm setkey .Op Fl dPv .Fl F .Nm setkey .Op Fl h .Fl x -.\" +.\" .Sh DESCRIPTION .Nm -updates, or lists the content of, Security Association Database (SAD) entries -in the kernel as well as Security Policy Database (SPD) entries. +addes, updates, dumpes, or flushes +Security Association Database (SAD) entries +as well as Security Policy Database (SPD) entries in the kernel. .Pp .Nm -takes a series of operation from standard input +takes a series of operations from the standard input .Po if invoked with .Fl c .Pc -or file named +or the file named .Ar filename .Po if invoked with .Fl f Ar filename .Pc . .Bl -tag -width Ds .It Fl D Dump the SAD entries. If with .Fl P , the SPD entries are dumped. .It Fl F -Flush the SAD. +Flush the SAD entries. If with .Fl P , -the SPD are flushed. +the SPD entries are flushed. .It Fl a .Nm -usually do not display dead SAD entries on +usually does not display dead SAD entries with .Fl D . -With +If with .Fl a , -dead SAD entries will be displayed as well. -Dead SAD entries are kept in the kernel, -when they are referenced from any of SPD entries in the kernel. +the dead SAD entries will be displayed as well. +A dead SAD entry means that +it has been expired but remains +because it is referenced by SPD entries. .It Fl d -Enable debugging messages. +Enable to print debugging messages for command parser, +without talking to kernel. It is not used usually. .It Fl x Loop forever and dump all the messages transmitted to .Dv PF_KEY socket. .It Fl h Add hexadecimal dump on .Fl x mode. -The order is significant. .It Fl l Loop forever with short output on .Fl D . .It Fl v Be verbose. .Dv PF_KEY socket .Po including messages sent from other processes .Pc . .El .Pp -Operation has the following grammar. -Note that lines, that start with a -hashmark ('#') are treated as comment lines. -Description of meta-arguments follows. +Operations have the following grammar. Note that lines starting with +hashmarks ('#') are treated as comment lines. .Bl -tag -width Ds .It Xo .Li add .Ar src Ar dst Ar protocol Ar spi .Op Ar extensions .Ar algorithm... .Li ; .Xc -Add a SAD entry. +Add an SAD entry. .\" .It Xo .Li get .Ar src Ar dst Ar protocol Ar spi -.Op Ar mode .Li ; .Xc -Show a SAD entry. +Show an SAD entry. .\" .It Xo .Li delete .Ar src Ar dst Ar protocol Ar spi -.Op Ar mode .Li ; .Xc -Remove a SAD entry. +Remove an SAD entry. .\" .It Xo .Li flush .Op Ar protocol .Li ; .Xc -Clear all SAD entries that matches the options. +Clear all SAD entries matched by the options. .\" .It Xo .Li dump .Op Ar protocol .Li ; .Xc -Dumps all SAD entries that matches the options. +Dumps all SAD entries matched by the options. .\" .It Xo .Li spdadd .Ar src_range Ar dst_range Ar upperspec Ar policy .Li ; .Xc -Add a SPD entry. +Add an SPD entry. .\" .It Xo .Li spddelete -.Ar src_range Ar dst_range Ar upperspec +.Ar src_range Ar dst_range Ar upperspec Fl P Ar direction .Li ; .Xc -Delete a SPD entry. +Delete an SPD entry. .\" .It Xo .Li spdflush .Li ; .Xc Clear all SPD entries. .\" .It Xo .Li spddump .Li ; .Xc Dumps all SPD entries. .El .\" .Pp Meta-arguments are as follows: .Bl -tag -compact -width Ds .It Ar src .It Ar dst Source/destination of the secure communication is specified as IPv4/v6 address. .Nm does not consult hostname-to-address for arguments .Ar src and .Ar dst . They must be in numeric form. .\" .Pp .It Ar protocol .Ar protocol is one of following: .Bl -tag -width Fl -compact .It Li esp ESP based on rfc2405 .It Li esp-old ESP based on rfc1827 .It Li ah AH based on rfc2402 .It Li ah-old AH based on rfc1826 .It Li ipcomp IPCOMP .El .\" .Pp .It Ar spi -Security Parameter Index (SPI) for the SA and SPD. +Security Parameter Index (SPI) for the SAD and the SPD. It must be decimal number or hexadecimal number +You can not use the set of SPI values in the range 0 through 255. .Po with .Li 0x attached .Pc . .\" .Pp .It Ar extensions -takes some of the following: -.Bl -tag -width Fl -compact +take some of the following: +.Bl -tag -width Fl -compact +.\" .It Fl m Ar mode -Specify an security protocol mode for use. By default, -.Li any . +Specify a security protocol mode for use. .Ar mode is one of following: .Li transport , tunnel or .Li any . +The default value is +.Li any . +.\" .It Fl r Ar size Specify window size of bytes for replay prevention. .Ar size must be decimal number in 32-bit word. If .Ar size is zero or not specified, replay check don't take place. +.\" +.It Fl u Ar id +Specify the identifier of policy. See also +.Xr ipsec_set_policy 3 . +.\" .It Fl f Ar pad_option .Ar pad_option is one of following: .Li zero-pad , random-pad or .Li seq-pad -.It Fl f Li cyclic-seq -Allow cyclic sequence number. +.\" +.It Fl f Li nocyclic-seq +Don't allow cyclic sequence number. +.\" .It Fl lh Ar time .It Fl ls Ar time Specify hard/soft lifetime. .El .\" .Pp .It Ar algorithm -.Bl -tag -width Fl -compact +.Bl -tag -width Fl -compact .It Fl E Ar ealgo Ar key Specify encryption algorithm. .It Fl A Ar aalgo Ar key Specify authentication algorithm. If .Fl A is used for esp, it will be treated as ESP payload authentication algorithm. .It Fl C Ar calgo Op Fl R Specify compression algorithm. If .Fl R -is specified with +is not specified with .Li ipcomp line, the kernel will use well-known IPComp CPI .Pq compression parameter index on IPComp CPI field on packets, and .Ar spi field will be ignored. .Ar spi field is only for kernel internal use in this case. .\"Therefore, compression protocol number will appear on IPComp CPI field. If .Fl R -is not used, +is used, the value on .Ar spi field will appear on IPComp CPI field on outgoing packets. .Ar spi field needs to be smaller than .Li 0x10000 in this case. .El .Pp .Li esp SAs accept .Fl E and .Fl A . .Li esp-old SAs accept .Fl E only. .Li ah and .Li ah-old SAs accept .Fl A only. .Li ipcomp SAs accept .Fl C only. .Pp .Ar key -must be double-quoted character string or a series of hexadecimal digits. +must be double-quoted character string or series of hexadecimal digits. .Pp Possible values for .Ar ealgo , .Ar aalgo and .Ar calgo are specified in separate section. .\" .It Ar src_range .It Ar dst_range -These are selection of the secure communication is specified as +These are selections of the secure communication specified as IPv4/v6 address or IPv4/v6 address range, and it may accompany TCP/UDP port specification. This takes the following form: .Bd -literal -offset .Ar address .Ar address/prefixlen .Ar address[port] .Ar address/prefixlen[port] .Ed .Pp .Ar prefixlen and .Ar port must be decimal number. The square bracket around .Ar port is really necessary. They are not manpage metacharacters. .Pp .Nm does not consult hostname-to-address for arguments .Ar src and .Ar dst . They must be in numeric form. .\" .It Ar upperspec Upper-layer protocol to be used. Currently .Li tcp , .Li udp and .Li any can be specified. .Li any stands for .Dq any protocol . .Pp NOTE: .Ar upperspec does not work against forwarding case at this moment, as it requires extra reassembly at forwarding node -.Pq not implemented as this moment . +.Pq not implemented at this moment . .\" .It Ar policy .Ar policy is the one of following: .Bd -literal -offset .Xo .Fl P .Ar direction .Li discard .Xc .Xo .Fl P .Ar direction .Li none .Xc .Xo .Fl P .Ar direction .Li ipsec .Ar protocol/mode/src-dst/level .Xc .Ed .Pp You must specify the direction of its policy as .Ar direction . Either .Li out or .Li in are used. .Li discard means the packet matching indexes will be discarded. .Li none means that IPsec operation will not take place onto the packet. .Li ipsec means that IPsec operation will take place onto the packet. Either .Li ah , .Li esp or .Li ipcomp is to be set as .Ar protocol . .Ar mode is either .Li transport or .Li tunnel . You must specify the end-points addresses of the SA as .Ar src and .Ar dst with .Sq - between these addresses which is used to specify the SA to use. .Ar level is to be one of the following: .Li default , use or .Li require . .Li default -means kernel consults to the system wide default against protocol you +means the kernel consults to the system wide default against protocol you specified, e.g. .Li esp_trans_deflev -sysctl variable, when kernel processes the packet. +sysctl variable, when the kernel processes the packet. .Li use -means that kernel use a SA if it's available, -otherwise kernel keeps normal operation. +means that the kernel use a SA if it's available, +otherwise the kernel keeps normal operation. .Li require -means SA is required whenever kernel deals with the packet. +means SA is required whenever the kernel deals with the packet. Note that .Dq Li discard and .Dq Li none are not in the syntax described in .Xr ipsec_set_policy 3 . There are little differences in the syntax. See .Xr ipsec_set_policy 3 for detail. .Pp .El .Pp .\" .Sh ALGORITHMS The following list shows the supported algorithms. .Sy protocol and .Sy algorithm are almost orthogonal. -Following are the list of authentication algorithms that can be used as +Followings are the list of authentication algorithms that can be used as .Ar aalgo in .Fl A Ar aalgo of .Ar protocol parameter: .Pp .Bd -literal -offset indent algorithm keylen (bits) comment hmac-md5 128 ah: rfc2403 128 ah-old: rfc2085 hmac-sha1 160 ah: rfc2404 160 ah-old: 128bit ICV (no document) keyed-md5 128 ah: 96bit ICV (no document) 128 ah-old: rfc1828 keyed-sha1 160 ah: 96bit ICV (no document) 160 ah-old: 128bit ICV (no document) null 0 to 2048 for debugging .Ed .Pp -Following are the list of encryption algorithms that can be used as +Followings are the list of encryption algorithms that can be used as .Ar ealgo in .Fl E Ar ealgo of .Ar protocol parameter: .Pp .Bd -literal -offset indent algorithm keylen (bits) comment des-cbc 64 esp-old: rfc1829, esp: rfc2405 3des-cbc 192 rfc2451 simple 0 to 2048 rfc2410 blowfish-cbc 40 to 448 rfc2451 cast128-cbc 40 to 128 rfc2451 rc5-cbc 40 to 2040 rfc2451 des-deriv 64 ipsec-ciph-des-derived-01 (expired) 3des-deriv 192 no document .Ed .Pp -Following are the list of compression algorithms that can be used as +Followings are the list of compression algorithms that can be used as .Ar calgo in .Fl C Ar calgo of .Ar protocol parameter: .Pp .Bd -literal -offset indent algorithm comment deflate rfc2394 lzs rfc2395 .Ed -.\" +.\" .Sh EXAMPLES .Bd -literal -offset add 3ffe:501:4819::1 3ffe:501:481d::1 esp 123457 -E des-cbc "ESP SA!!" ; add 3ffe:501:4819::1 3ffe:501:481d::1 ah 123456 -A hmac-sha1 "AH SA configuration!" ; add 10.0.11.41 10.0.11.33 esp 0x10001 -E des-cbc "ESP with" -A hmac-md5 "authentication!!" ; get 3ffe:501:4819::1 3ffe:501:481d::1 ah 123456 ; flush ; dump esp ; spdadd 10.0.11.41/32[21] 10.0.11.33/32[any] any -P out ipsec esp/tunnel/192.168.0.1-192.168.1.2/require ; .Ed -.\" +.\" .Sh RETURN VALUES The command exits with 0 on success, and non-zero on errors. -.\" +.\" .Sh SEE ALSO .Xr ipsec_set_policy 3 , .Xr sysctl 8 -.\" +.\" .Sh HISTORY The .Nm command first appeared in WIDE Hydrangea IPv6 protocol stack kit. The command was completely re-designed in June 1998. -.Pp -IPv6 and IPsec support based on the KAME Project (http://www.kame.net/) stack -was initially integrated into -.Fx 4.0 +.\" +.\" .Sh BUGS Index: head/usr.sbin/setkey/setkey.c =================================================================== --- head/usr.sbin/setkey/setkey.c (revision 62582) +++ head/usr.sbin/setkey/setkey.c (revision 62583) @@ -1,566 +1,578 @@ +/* $FreeBSD$ */ +/* $KAME: setkey.c,v 1.14 2000/06/10 06:47:09 sakane Exp $ */ + /* * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ -/* KAME $Id: setkey.c,v 1.5 1999/10/26 09:39:37 sakane Exp $ */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include -void Usage __P((void)); -int main __P((int, char **)); -int get_supported __P((void)); -void sendkeyshort __P((u_int)); -void promisc __P((void)); -int sendkeymsg __P((void)); -int postproc __P((struct sadb_msg *, int)); -const char *numstr __P((int)); -void shortdump_hdr __P((void)); -void shortdump __P((struct sadb_msg *)); +#include "libpfkey.h" +void Usage __P((void)); +int main __P((int, char **)); +int get_supported __P((void)); +void sendkeyshort __P((u_int)); +void promisc __P((void)); +int sendkeymsg __P((void)); +int postproc __P((struct sadb_msg *, int)); +const char *numstr __P((int)); +void shortdump_hdr __P((void)); +void shortdump __P((struct sadb_msg *)); + #define MODE_SCRIPT 1 #define MODE_CMDDUMP 2 #define MODE_CMDFLUSH 3 +#define MODE_PROMISC 4 int so; -int f_forever = 0; -int f_all = 0; -int f_debug = 0; -int f_verbose = 0; -int f_mode = 0; -int f_cmddump = 0; -int f_policy = 0; -int f_promisc = 0; -int f_hexdump = 0; -char *pname; +int f_forever = 0; +int f_all = 0; +int f_debug = 0; +int f_verbose = 0; +int f_mode = 0; +int f_cmddump = 0; +int f_policy = 0; +int f_hexdump = 0; +char *pname; -u_char m_buf[BUFSIZ]; -u_int m_len; +u_char m_buf[BUFSIZ]; +u_int m_len; -extern int lineno; +extern int lineno; -extern int parse __P((FILE **)); +extern int parse __P((FILE **)); void Usage() { printf("Usage:\t%s [-dv] -c\n", pname); printf("\t%s [-dv] -f (file)\n", pname); printf("\t%s [-Padlv] -D\n", pname); printf("\t%s [-Pdv] -F\n", pname); printf("\t%s [-h] -x\n", pname); pfkey_close(so); - exit(0); + exit(1); } int main(ac, av) int ac; char **av; { FILE *fp = stdin; int c; pname = *av; if (ac == 1) Usage(); while ((c = getopt(ac, av, "acdf:hlvxDFP")) != EOF) { switch (c) { case 'c': f_mode = MODE_SCRIPT; fp = stdin; break; case 'f': f_mode = MODE_SCRIPT; if ((fp = fopen(optarg, "r")) == NULL) { err(-1, "fopen"); /*NOTREACHED*/ } break; case 'D': f_mode = MODE_CMDDUMP; break; case 'F': f_mode = MODE_CMDFLUSH; break; case 'a': f_all = 1; break; case 'l': f_forever = 1; break; case 'h': f_hexdump = 1; break; case 'x': - f_promisc = 1; - promisc(); - /*NOTREACHED*/ + f_mode = MODE_PROMISC; + break; case 'P': f_policy = 1; break; case 'd': f_debug = 1; break; case 'v': f_verbose = 1; break; default: Usage(); /*NOTREACHED*/ } } switch (f_mode) { case MODE_CMDDUMP: sendkeyshort(f_policy ? SADB_X_SPDDUMP: SADB_DUMP); break; case MODE_CMDFLUSH: sendkeyshort(f_policy ? SADB_X_SPDFLUSH: SADB_FLUSH); pfkey_close(so); break; case MODE_SCRIPT: if (get_supported() < 0) { errx(-1, "%s", ipsec_strerror()); /*NOTREACHED*/ } - parse(&fp); + if (parse(&fp)) + exit (1); break; + case MODE_PROMISC: + promisc(); + /*NOTREACHED*/ default: Usage(); + /*NOTREACHED*/ } exit(0); } int get_supported() { int so; if ((so = pfkey_open()) < 0) { perror("pfkey_open"); return -1; } /* debug mode ? */ if (f_debug) return 0; if (pfkey_send_register(so, PF_UNSPEC) < 0) return -1; if (pfkey_recv_register(so) < 0) return -1; return 0; } void sendkeyshort(type) u_int type; { struct sadb_msg *m_msg = (struct sadb_msg *)m_buf; m_len = sizeof(struct sadb_msg); m_msg->sadb_msg_version = PF_KEY_V2; m_msg->sadb_msg_type = type; m_msg->sadb_msg_errno = 0; m_msg->sadb_msg_satype = SADB_SATYPE_UNSPEC; m_msg->sadb_msg_len = PFKEY_UNIT64(m_len); m_msg->sadb_msg_reserved = 0; - m_msg->sadb_msg_reserved = 0; m_msg->sadb_msg_seq = 0; m_msg->sadb_msg_pid = getpid(); sendkeymsg(); return; } void promisc() { struct sadb_msg *m_msg = (struct sadb_msg *)m_buf; u_char rbuf[1024 * 32]; /* XXX: Enough ? Should I do MSG_PEEK ? */ int so, len; m_len = sizeof(struct sadb_msg); m_msg->sadb_msg_version = PF_KEY_V2; m_msg->sadb_msg_type = SADB_X_PROMISC; m_msg->sadb_msg_errno = 0; m_msg->sadb_msg_satype = 1; m_msg->sadb_msg_len = PFKEY_UNIT64(m_len); m_msg->sadb_msg_reserved = 0; - m_msg->sadb_msg_reserved = 0; m_msg->sadb_msg_seq = 0; m_msg->sadb_msg_pid = getpid(); if ((so = socket(PF_KEY, SOCK_RAW, PF_KEY_V2)) < 0) { err(1, "socket(PF_KEY)"); /*NOTREACHED*/ } if ((len = send(so, m_buf, m_len, 0)) < 0) { err(1, "send"); /*NOTREACHED*/ } while (1) { struct sadb_msg *base; if ((len = recv(so, rbuf, sizeof(*base), MSG_PEEK)) < 0) { err(1, "recv"); /*NOTREACHED*/ } if (len != sizeof(*base)) continue; base = (struct sadb_msg *)rbuf; if ((len = recv(so, rbuf, PFKEY_UNUNIT64(base->sadb_msg_len), 0)) < 0) { err(1, "recv"); /*NOTREACHED*/ } if (f_hexdump) { int i; for (i = 0; i < len; i++) { if (i % 16 == 0) printf("%08x: ", i); printf("%02x ", rbuf[i] & 0xff); if (i % 16 == 15) printf("\n"); } if (len % 16) printf("\n"); } /* adjust base pointer for promisc mode */ if (base->sadb_msg_type == SADB_X_PROMISC) { if (sizeof(*base) < len) base++; else base = NULL; } if (base) { kdebug_sadb(base); printf("\n"); fflush(stdout); } } } int sendkeymsg() { int so; u_char rbuf[1024 * 32]; /* XXX: Enough ? Should I do MSG_PEEK ? */ int len; struct sadb_msg *msg; if ((so = pfkey_open()) < 0) { perror("pfkey_open"); return -1; } { struct timeval tv; tv.tv_sec = 1; tv.tv_usec = 0; if (setsockopt(so, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) { perror("setsockopt"); goto end; } } if (f_forever) shortdump_hdr(); again: - if (f_verbose) + if (f_verbose) { kdebug_sadb((struct sadb_msg *)m_buf); + printf("\n"); + } if ((len = send(so, m_buf, m_len, 0)) < 0) { perror("send"); goto end; } msg = (struct sadb_msg *)rbuf; do { if ((len = recv(so, rbuf, sizeof(rbuf), 0)) < 0) { perror("recv"); goto end; } if (PFKEY_UNUNIT64(msg->sadb_msg_len) != len) { warnx("invalid keymsg length"); break; } - if (f_verbose) + if (f_verbose) { kdebug_sadb((struct sadb_msg *)rbuf); + printf("\n"); + } if (postproc(msg, len) < 0) break; } while (msg->sadb_msg_errno || msg->sadb_msg_seq); if (f_forever) { fflush(stdout); sleep(1); goto again; } end: pfkey_close(so); return(0); } int postproc(msg, len) struct sadb_msg *msg; int len; { if (msg->sadb_msg_errno != 0) { char inf[80]; char *errmsg = NULL; if (f_mode == MODE_SCRIPT) snprintf(inf, sizeof(inf), "The result of line %d: ", lineno); else inf[0] = '\0'; switch (msg->sadb_msg_errno) { case ENOENT: switch (msg->sadb_msg_type) { case SADB_DELETE: case SADB_GET: case SADB_X_SPDDELETE: errmsg = "No entry"; break; case SADB_DUMP: errmsg = "No SAD entries"; break; case SADB_X_SPDDUMP: errmsg = "No SPD entries"; break; } break; default: errmsg = strerror(msg->sadb_msg_errno); } printf("%s%s.\n", inf, errmsg); return(-1); } switch (msg->sadb_msg_type) { case SADB_GET: pfkey_sadump(msg); break; case SADB_DUMP: /* filter out DEAD SAs */ if (!f_all) { caddr_t mhp[SADB_EXT_MAX + 1]; struct sadb_sa *sa; pfkey_align(msg, mhp); pfkey_check(mhp); if ((sa = (struct sadb_sa *)mhp[SADB_EXT_SA]) != NULL) { if (sa->sadb_sa_state == SADB_SASTATE_DEAD) break; } } if (f_forever) shortdump(msg); else pfkey_sadump(msg); msg = (struct sadb_msg *)((caddr_t)msg + PFKEY_UNUNIT64(msg->sadb_msg_len)); - if (f_verbose) + if (f_verbose) { kdebug_sadb((struct sadb_msg *)msg); + printf("\n"); + } break; case SADB_X_SPDDUMP: pfkey_spdump(msg); if (msg->sadb_msg_seq == 0) break; msg = (struct sadb_msg *)((caddr_t)msg + PFKEY_UNUNIT64(msg->sadb_msg_len)); - if (f_verbose) + if (f_verbose) { kdebug_sadb((struct sadb_msg *)msg); + printf("\n"); + } break; } return(0); } /*------------------------------------------------------------*/ static char *satype[] = { NULL, NULL, "ah", "esp" }; static char *sastate[] = { "L", "M", "D", "d" }; static char *ipproto[] = { /*0*/ "ip", "icmp", "igmp", "ggp", "ip4", NULL, "tcp", NULL, "egp", NULL, /*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, "udp", NULL, NULL, /*20*/ NULL, NULL, "idp", NULL, NULL, NULL, NULL, NULL, NULL, "tp", /*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*40*/ NULL, "ip6", NULL, "rt6", "frag6", NULL, "rsvp", "gre", NULL, NULL, /*50*/ "esp", "ah", NULL, NULL, NULL, NULL, NULL, NULL, "icmp6", "none", /*60*/ "dst6", }; #define STR_OR_ID(x, tab) \ (((x) < sizeof(tab)/sizeof(tab[0]) && tab[(x)]) ? tab[(x)] : numstr(x)) const char * numstr(x) int x; { static char buf[20]; snprintf(buf, sizeof(buf), "#%d", x); return buf; } void shortdump_hdr() { printf("%-4s %-3s %-1s %-8s %-7s %s -> %s\n", "time", "p", "s", "spi", "ltime", "src", "dst"); } void shortdump(msg) struct sadb_msg *msg; { caddr_t mhp[SADB_EXT_MAX + 1]; char buf[1024], pbuf[10]; struct sadb_sa *sa; struct sadb_address *saddr; struct sadb_lifetime *lts, *lth, *ltc; struct sockaddr *s; u_int t; time_t cur = time(0); pfkey_align(msg, mhp); pfkey_check(mhp); printf("%02lu%02lu", (u_long)(cur % 3600) / 60, (u_long)(cur % 60)); printf(" %-3s", STR_OR_ID(msg->sadb_msg_satype, satype)); if ((sa = (struct sadb_sa *)mhp[SADB_EXT_SA]) != NULL) { printf(" %-1s", STR_OR_ID(sa->sadb_sa_state, sastate)); printf(" %08x", (u_int32_t)ntohl(sa->sadb_sa_spi)); } else printf("%-1s %-8s", "?", "?"); lts = (struct sadb_lifetime *)mhp[SADB_EXT_LIFETIME_SOFT]; lth = (struct sadb_lifetime *)mhp[SADB_EXT_LIFETIME_HARD]; ltc = (struct sadb_lifetime *)mhp[SADB_EXT_LIFETIME_CURRENT]; if (lts && lth && ltc) { if (ltc->sadb_lifetime_addtime == 0) t = (u_long)0; else t = (u_long)(cur - ltc->sadb_lifetime_addtime); if (t >= 1000) strcpy(buf, " big/"); else snprintf(buf, sizeof(buf), " %3lu/", (u_long)t); printf("%s", buf); t = (u_long)lth->sadb_lifetime_addtime; if (t >= 1000) strcpy(buf, "big"); else snprintf(buf, sizeof(buf), "%-3lu", (u_long)t); printf("%s", buf); } else printf(" ???/???"); printf(" "); if ((saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC]) != NULL) { if (saddr->sadb_address_proto) printf("%s ", STR_OR_ID(saddr->sadb_address_proto, ipproto)); s = (struct sockaddr *)(saddr + 1); getnameinfo(s, s->sa_len, buf, sizeof(buf), pbuf, sizeof(pbuf), NI_NUMERICHOST|NI_NUMERICSERV); if (strcmp(pbuf, "0") != 0) printf("%s[%s]", buf, pbuf); else printf("%s", buf); } else printf("?"); printf(" -> "); if ((saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST]) != NULL) { if (saddr->sadb_address_proto) printf("%s ", STR_OR_ID(saddr->sadb_address_proto, ipproto)); s = (struct sockaddr *)(saddr + 1); getnameinfo(s, s->sa_len, buf, sizeof(buf), pbuf, sizeof(pbuf), NI_NUMERICHOST|NI_NUMERICSERV); if (strcmp(pbuf, "0") != 0) printf("%s[%s]", buf, pbuf); else printf("%s", buf); } else printf("?"); printf("\n"); } Index: head/usr.sbin/setkey/test-pfkey.c =================================================================== --- head/usr.sbin/setkey/test-pfkey.c (revision 62582) +++ head/usr.sbin/setkey/test-pfkey.c (revision 62583) @@ -1,480 +1,531 @@ +/* $FreeBSD$ */ +/* $KAME: test-pfkey.c,v 1.4 2000/06/07 00:29:14 itojun Exp $ */ + /* * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ -/* KAME $Id: test-pfkey.c,v 1.2 1999/10/26 08:09:17 itojun Exp $ */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include +#include -u_char m_buf[BUFSIZ]; -u_int m_len; -char *pname; +u_char m_buf[BUFSIZ]; +u_int m_len; +char *pname; -void Usage __P((void)); -int sendkeymsg __P((void)); -void key_setsadbmsg __P((u_int)); -void key_setsadbsens __P((void)); -void key_setsadbprop __P((void)); -void key_setsadbid __P((u_int, caddr_t)); -void key_setsadblft __P((u_int, u_int)); -void key_setspirange __P((void)); -void key_setsadbkey __P((u_int, caddr_t)); -void key_setsadbsa __P((void)); -void key_setsadbaddr __P((u_int, u_int, caddr_t)); -void key_setsadbextbuf __P((caddr_t, int, caddr_t, int, caddr_t, int)); +void Usage __P((void)); +int sendkeymsg __P((void)); +void key_setsadbmsg __P((u_int)); +void key_setsadbsens __P((void)); +void key_setsadbprop __P((void)); +void key_setsadbid __P((u_int, caddr_t)); +void key_setsadblft __P((u_int, u_int)); +void key_setspirange __P((void)); +void key_setsadbkey __P((u_int, caddr_t)); +void key_setsadbsa __P((void)); +void key_setsadbaddr __P((u_int, u_int, caddr_t)); +void key_setsadbextbuf __P((caddr_t, int, caddr_t, int, caddr_t, int)); void Usage() { printf("Usage:\t%s number\n", pname); exit(0); } int main(ac, av) int ac; char **av; { pname = *av; if (ac == 1) Usage(); key_setsadbmsg(atoi(*(av+1))); sendkeymsg(); exit(0); } /* %%% */ int sendkeymsg() { u_char rbuf[1024 * 32]; /* XXX: Enough ? Should I do MSG_PEEK ? */ int so, len; if ((so = socket(PF_KEY, SOCK_RAW, PF_KEY_V2)) < 0) { perror("socket(PF_KEY)"); goto end; } +#if 0 + { +#include + struct timeval tv; + tv.tv_sec = 1; + tv.tv_usec = 0; + if (setsockopt(so, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) { + perror("setsockopt"); + goto end; + } + } +#endif pfkey_sadump((struct sadb_msg *)m_buf); if ((len = send(so, m_buf, m_len, 0)) < 0) { perror("send"); goto end; } if ((len = recv(so, rbuf, sizeof(rbuf), 0)) < 0) { perror("recv"); goto end; } pfkey_sadump((struct sadb_msg *)rbuf); end: (void)close(so); return(0); } void key_setsadbmsg(type) u_int type; { struct sadb_msg m_msg; + memset(&m_msg, 0, sizeof(m_msg)); m_msg.sadb_msg_version = PF_KEY_V2; m_msg.sadb_msg_type = type; m_msg.sadb_msg_errno = 0; m_msg.sadb_msg_satype = SADB_SATYPE_ESP; +#if 0 m_msg.sadb_msg_reserved = 0; +#endif m_msg.sadb_msg_seq = 0; m_msg.sadb_msg_pid = getpid(); m_len = sizeof(struct sadb_msg); memcpy(m_buf, &m_msg, m_len); switch (type) { case SADB_GETSPI: /**/ key_setsadbaddr(SADB_EXT_ADDRESS_SRC, AF_INET, "10.0.3.4"); key_setsadbaddr(SADB_EXT_ADDRESS_DST, AF_INET, "127.0.0.1"); key_setspirange(); /**/ break; case SADB_ADD: /* */ key_setsadbaddr(SADB_EXT_ADDRESS_PROXY, AF_INET6, "3ffe::1"); case SADB_UPDATE: key_setsadbsa(); key_setsadblft(SADB_EXT_LIFETIME_HARD, 10); key_setsadblft(SADB_EXT_LIFETIME_SOFT, 5); key_setsadbaddr(SADB_EXT_ADDRESS_SRC, AF_INET, "192.168.1.1"); key_setsadbaddr(SADB_EXT_ADDRESS_DST, AF_INET, "10.0.3.4"); /* XXX key_setsadbkey(SADB_EXT_KEY_AUTH, "abcde"); */ key_setsadbkey(SADB_EXT_KEY_AUTH, "1234567812345678"); key_setsadbkey(SADB_EXT_KEY_ENCRYPT, "12345678"); key_setsadbid(SADB_EXT_IDENTITY_SRC, "hoge1234@hoge.com"); key_setsadbid(SADB_EXT_IDENTITY_DST, "hage5678@hage.net"); key_setsadbsens(); /* */ break; case SADB_DELETE: /* */ key_setsadbsa(); key_setsadbaddr(SADB_EXT_ADDRESS_SRC, AF_INET, "192.168.1.1"); key_setsadbaddr(SADB_EXT_ADDRESS_DST, AF_INET, "10.0.3.4"); key_setsadbaddr(SADB_EXT_ADDRESS_PROXY, AF_INET6, "3ffe::1"); /* */ break; case SADB_GET: /* */ key_setsadbsa(); key_setsadbaddr(SADB_EXT_ADDRESS_SRC, AF_INET, "192.168.1.1"); key_setsadbaddr(SADB_EXT_ADDRESS_DST, AF_INET, "10.0.3.4"); key_setsadbaddr(SADB_EXT_ADDRESS_PROXY, AF_INET6, "3ffe::1"); /* */ break; case SADB_ACQUIRE: /* */ key_setsadbaddr(SADB_EXT_ADDRESS_SRC, AF_INET, "192.168.1.1"); key_setsadbaddr(SADB_EXT_ADDRESS_DST, AF_INET, "10.0.3.4"); key_setsadbaddr(SADB_EXT_ADDRESS_PROXY, AF_INET6, "3ffe::1"); key_setsadbid(SADB_EXT_IDENTITY_SRC, "hoge1234@hoge.com"); key_setsadbid(SADB_EXT_IDENTITY_DST, "hage5678@hage.net"); key_setsadbsens(); key_setsadbprop(); /* */ break; case SADB_REGISTER: /* */ /* */ break; case SADB_EXPIRE: case SADB_FLUSH: break; case SADB_DUMP: break; case SADB_X_PROMISC: /* */ /* */ break; case SADB_X_PCHANGE: break; /* for SPD management */ case SADB_X_SPDFLUSH: case SADB_X_SPDDUMP: break; case SADB_X_SPDADD: +#if 0 + { + struct sadb_x_policy m_policy; + + m_policy.sadb_x_policy_len = PFKEY_UNIT64(sizeof(m_policy)); + m_policy.sadb_x_policy_exttype = SADB_X_EXT_POLICY; + m_policy.sadb_x_policy_type = SADB_X_PL_IPSEC; + m_policy.sadb_x_policy_esp_trans = 1; + m_policy.sadb_x_policy_ah_trans = 2; + m_policy.sadb_x_policy_esp_network = 3; + m_policy.sadb_x_policy_ah_network = 4; + m_policy.sadb_x_policy_reserved = 0; + + memcpy(m_buf + m_len, &m_policy, sizeof(struct sadb_x_policy)); + m_len += sizeof(struct sadb_x_policy); + } +#endif + case SADB_X_SPDDELETE: key_setsadbaddr(SADB_EXT_ADDRESS_SRC, AF_INET, "192.168.1.1"); key_setsadbaddr(SADB_EXT_ADDRESS_DST, AF_INET, "10.0.3.4"); break; } ((struct sadb_msg *)m_buf)->sadb_msg_len = PFKEY_UNIT64(m_len); return; } void key_setsadbsens() { struct sadb_sens m_sens; u_char buf[64]; u_int s, i, slen, ilen, len; /* make sens & integ */ s = htonl(0x01234567); i = htonl(0x89abcdef); slen = sizeof(s); ilen = sizeof(i); memcpy(buf, &s, slen); memcpy(buf + slen, &i, ilen); len = sizeof(m_sens) + PFKEY_ALIGN8(slen) + PFKEY_ALIGN8(ilen); m_sens.sadb_sens_len = PFKEY_UNIT64(len); m_sens.sadb_sens_exttype = SADB_EXT_SENSITIVITY; m_sens.sadb_sens_dpd = 1; m_sens.sadb_sens_sens_level = 2; m_sens.sadb_sens_sens_len = PFKEY_ALIGN8(slen); m_sens.sadb_sens_integ_level = 3; m_sens.sadb_sens_integ_len = PFKEY_ALIGN8(ilen); m_sens.sadb_sens_reserved = 0; key_setsadbextbuf(m_buf, m_len, (caddr_t)&m_sens, sizeof(struct sadb_sens), buf, slen + ilen); m_len += len; return; } void key_setsadbprop() { struct sadb_prop m_prop; struct sadb_comb *m_comb; u_char buf[256]; u_int len = sizeof(m_prop) + sizeof(m_comb) * 2; /* make prop & comb */ m_prop.sadb_prop_len = PFKEY_UNIT64(len); m_prop.sadb_prop_exttype = SADB_EXT_PROPOSAL; m_prop.sadb_prop_replay = 0; m_prop.sadb_prop_reserved[0] = 0; m_prop.sadb_prop_reserved[1] = 0; m_prop.sadb_prop_reserved[2] = 0; /* the 1st is ESP DES-CBC HMAC-MD5 */ m_comb = (struct sadb_comb *)buf; m_comb->sadb_comb_auth = SADB_AALG_MD5HMAC; m_comb->sadb_comb_encrypt = SADB_EALG_DESCBC; m_comb->sadb_comb_flags = 0; m_comb->sadb_comb_auth_minbits = 8; m_comb->sadb_comb_auth_maxbits = 96; m_comb->sadb_comb_encrypt_minbits = 64; m_comb->sadb_comb_encrypt_maxbits = 64; m_comb->sadb_comb_reserved = 0; m_comb->sadb_comb_soft_allocations = 0; m_comb->sadb_comb_hard_allocations = 0; m_comb->sadb_comb_soft_bytes = 0; m_comb->sadb_comb_hard_bytes = 0; m_comb->sadb_comb_soft_addtime = 0; m_comb->sadb_comb_hard_addtime = 0; m_comb->sadb_comb_soft_usetime = 0; m_comb->sadb_comb_hard_usetime = 0; /* the 2st is ESP 3DES-CBC and AH HMAC-SHA1 */ m_comb = (struct sadb_comb *)(buf + sizeof(*m_comb)); m_comb->sadb_comb_auth = SADB_AALG_SHA1HMAC; m_comb->sadb_comb_encrypt = SADB_EALG_3DESCBC; m_comb->sadb_comb_flags = 0; m_comb->sadb_comb_auth_minbits = 8; m_comb->sadb_comb_auth_maxbits = 96; m_comb->sadb_comb_encrypt_minbits = 64; m_comb->sadb_comb_encrypt_maxbits = 64; m_comb->sadb_comb_reserved = 0; m_comb->sadb_comb_soft_allocations = 0; m_comb->sadb_comb_hard_allocations = 0; m_comb->sadb_comb_soft_bytes = 0; m_comb->sadb_comb_hard_bytes = 0; m_comb->sadb_comb_soft_addtime = 0; m_comb->sadb_comb_hard_addtime = 0; m_comb->sadb_comb_soft_usetime = 0; m_comb->sadb_comb_hard_usetime = 0; key_setsadbextbuf(m_buf, m_len, (caddr_t)&m_prop, sizeof(struct sadb_prop), buf, sizeof(*m_comb) * 2); m_len += len; return; } void key_setsadbid(ext, str) u_int ext; caddr_t str; { struct sadb_ident m_id; u_int idlen = strlen(str), len; len = sizeof(m_id) + PFKEY_ALIGN8(idlen); m_id.sadb_ident_len = PFKEY_UNIT64(len); m_id.sadb_ident_exttype = ext; m_id.sadb_ident_type = SADB_IDENTTYPE_USERFQDN; m_id.sadb_ident_reserved = 0; m_id.sadb_ident_id = getpid(); key_setsadbextbuf(m_buf, m_len, (caddr_t)&m_id, sizeof(struct sadb_ident), str, idlen); m_len += len; return; } void key_setsadblft(ext, time) u_int ext, time; { struct sadb_lifetime m_lft; m_lft.sadb_lifetime_len = PFKEY_UNIT64(sizeof(m_lft)); m_lft.sadb_lifetime_exttype = ext; m_lft.sadb_lifetime_allocations = 0x2; m_lft.sadb_lifetime_bytes = 0x1000; m_lft.sadb_lifetime_addtime = time; m_lft.sadb_lifetime_usetime = 0x0020; memcpy(m_buf + m_len, &m_lft, sizeof(struct sadb_lifetime)); m_len += sizeof(struct sadb_lifetime); return; } void key_setspirange() { struct sadb_spirange m_spi; m_spi.sadb_spirange_len = PFKEY_UNIT64(sizeof(m_spi)); m_spi.sadb_spirange_exttype = SADB_EXT_SPIRANGE; m_spi.sadb_spirange_min = 0x00001000; m_spi.sadb_spirange_max = 0x00002000; m_spi.sadb_spirange_reserved = 0; memcpy(m_buf + m_len, &m_spi, sizeof(struct sadb_spirange)); m_len += sizeof(struct sadb_spirange); return; } void key_setsadbkey(ext, str) u_int ext; caddr_t str; { struct sadb_key m_key; u_int keylen = strlen(str); u_int len; len = sizeof(struct sadb_key) + PFKEY_ALIGN8(keylen); m_key.sadb_key_len = PFKEY_UNIT64(len); m_key.sadb_key_exttype = ext; m_key.sadb_key_bits = keylen * 8; m_key.sadb_key_reserved = 0; key_setsadbextbuf(m_buf, m_len, (caddr_t)&m_key, sizeof(struct sadb_key), str, keylen); m_len += len; return; } void key_setsadbsa() { struct sadb_sa m_sa; m_sa.sadb_sa_len = PFKEY_UNIT64(sizeof(struct sadb_sa)); m_sa.sadb_sa_exttype = SADB_EXT_SA; m_sa.sadb_sa_spi = htonl(0x12345678); m_sa.sadb_sa_replay = 4; m_sa.sadb_sa_state = 0; m_sa.sadb_sa_auth = SADB_AALG_MD5HMAC; m_sa.sadb_sa_encrypt = SADB_EALG_DESCBC; m_sa.sadb_sa_flags = 0; memcpy(m_buf + m_len, &m_sa, sizeof(struct sadb_sa)); m_len += sizeof(struct sadb_sa); return; } void key_setsadbaddr(ext, af, str) u_int ext, af; caddr_t str; { struct sadb_address m_addr; - u_char abuf[64]; - struct sockaddr *a = (struct sockaddr *)abuf; u_int len; + struct addrinfo hints, *res; + const char *serv; + int plen; + switch (af) { + case AF_INET: + plen = sizeof(struct in_addr) << 3; + break; + case AF_INET6: + plen = sizeof(struct in6_addr) << 3; + break; + default: + /* XXX bark */ + exit(1); + } + /* make sockaddr buffer */ - memset(abuf, 0, sizeof(abuf)); - a->sa_len = _SALENBYAF(af); - a->sa_family = af; - _INPORTBYSA(a) = - (ext == SADB_EXT_ADDRESS_PROXY ? 0 : htons(0x1234)); - if (inet_pton(af, str, _INADDRBYSA(a)) != 1) - ; /* XXX do something */ + memset(&hints, 0, sizeof(hints)); + hints.ai_family = af; + hints.ai_socktype = SOCK_DGRAM; /*dummy*/ + hints.ai_flags = AI_NUMERICHOST; + serv = (ext == SADB_EXT_ADDRESS_PROXY ? "0" : "4660"); /*0x1234*/ + if (getaddrinfo(str, serv, &hints, &res) != 0 || res->ai_next) { + /* XXX bark */ + exit(1); + } - len = sizeof(struct sadb_address) + PFKEY_ALIGN8(a->sa_len); + len = sizeof(struct sadb_address) + PFKEY_ALIGN8(res->ai_addrlen); m_addr.sadb_address_len = PFKEY_UNIT64(len); m_addr.sadb_address_exttype = ext; m_addr.sadb_address_proto = (ext == SADB_EXT_ADDRESS_PROXY ? 0 : IPPROTO_TCP); - m_addr.sadb_address_prefixlen = _INALENBYAF(af); + m_addr.sadb_address_prefixlen = plen; m_addr.sadb_address_reserved = 0; key_setsadbextbuf(m_buf, m_len, (caddr_t)&m_addr, sizeof(struct sadb_address), - abuf, a->sa_len); + (caddr_t)res->ai_addr, res->ai_addrlen); m_len += len; + + freeaddrinfo(res); return; } void key_setsadbextbuf(dst, off, ebuf, elen, vbuf, vlen) caddr_t dst, ebuf, vbuf; int off, elen, vlen; { memset(dst + off, 0, elen + vlen); memcpy(dst + off, (caddr_t)ebuf, elen); memcpy(dst + off + elen, vbuf, vlen); return; } Index: head/usr.sbin/setkey/token.l =================================================================== --- head/usr.sbin/setkey/token.l (revision 62582) +++ head/usr.sbin/setkey/token.l (revision 62583) @@ -1,322 +1,315 @@ +/* $FreeBSD$ */ +/* $KAME: token.l,v 1.13 2000/06/07 00:29:14 itojun Exp $ */ + /* * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ %{ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "vchar.h" #include "y.tab.h" #define DECHO \ if (f_debug) {printf("<%d>", yy_start); ECHO ; printf("\n"); } #define CMDARG \ { \ char *__buf__ = strdup(yytext), *__p__; \ for (__p__ = __buf__; *__p__ != NULL; __p__++) \ if (*__p__ == '\n' || *__p__ == '\t') \ *__p__ = ' '; \ strcat(cmdarg, __buf__); \ free(__buf__); \ } #define PREPROC DECHO CMDARG -int lineno = 1; -char cmdarg[8192]; /* XXX: BUFSIZ is the better ? */ +int lineno = 1; +char cmdarg[8192]; /* XXX: BUFSIZ is the better ? */ -extern u_char m_buf[BUFSIZ]; -extern u_int m_len; -extern int f_debug; +extern u_char m_buf[BUFSIZ]; +extern u_int m_len; +extern int f_debug; -int yylex __P((void)); -void yyerror __P((char *s)); -extern void parse_init __P((void)); -int parse __P((FILE **)); -int yyparse __P((void)); +int yylex __P((void)); +void yyfatal __P((const char *s)); +void yyerror __P((const char *s)); +extern void parse_init __P((void)); +int parse __P((FILE **)); +int yyparse __P((void)); %} /* common section */ nl \n ws [ \t]+ digit [0-9] letter [0-9A-Za-z] hexdigit [0-9A-Fa-f] /*octet (([01]?{digit}?{digit})|((2([0-4]{digit}))|(25[0-5])))*/ special [()+\|\?\*,] dot \. comma \, hyphen \- colon \: slash \/ bcl \{ ecl \} blcl \[ elcl \] percent \% semi \; usec {dot}{digit}{1,6} comment \#.* ccomment "/*" bracketstring \<[^>]*\> quotedstring \"[^"]*\" decstring {digit}+ hexpair {hexdigit}{hexdigit} hexstring 0[xX]{hexdigit}+ octetstring {octet}({dot}{octet})+ -ipaddress {ipv4addr}|{ipv6addr} -ipv4addr {digit}{1,3}({dot}{digit}{1,3}){0,3} -ipv6addr {hexdigit}{0,4}({colon}{hexdigit}{0,4}){2,7}(%{letter}{letter}+)? +ipaddress [a-fA-F0-9:]([a-fA-F0-9:\.]*|[a-fA-F0-9:\.]*%[a-zA-Z0-9]*) ipaddrmask {slash}{digit}{1,3} ipaddrport {blcl}{decstring}{elcl} keyword {letter}{letter}+ name {letter}(({letter}|{digit}|{hyphen})*({letter}|{digit}))* hostname {name}(({dot}{name})+{dot}?)? %s S_PL %% add { PREPROC; return(ADD); } delete { PREPROC; return(DELETE); } get { PREPROC; return(GET); } flush { PREPROC; return(FLUSH); } dump { PREPROC; return(DUMP); } /* for management SPD */ spdadd { PREPROC; return(SPDADD); } spddelete { PREPROC; return(SPDDELETE); } spddump { PREPROC; return(SPDDUMP); } spdflush { PREPROC; return(SPDFLUSH); } {hyphen}P { BEGIN S_PL; PREPROC; return(F_POLICY); } [a-zA-Z0-9:\.\-_/ \n\t][a-zA-Z0-9:\.\-_/ \n\t]* { yymore(); /* count up for nl */ { char *p; for (p = yytext; *p != NULL; p++) if (*p == '\n') lineno++; } yylval.val.len = strlen(yytext); yylval.val.buf = strdup(yytext); return(PL_REQUESTS); } {semi} { PREPROC; BEGIN INITIAL; return(EOT); } /* security protocols */ ah { PREPROC; yylval.num = 0; return(PR_AH); } esp { PREPROC; yylval.num = 0; return(PR_ESP); } ah-old { PREPROC; yylval.num = 1; return(PR_AH); } esp-old { PREPROC; yylval.num = 1; return(PR_ESP); } ipcomp { PREPROC; yylval.num = 0; return(PR_IPCOMP); } /* authentication alogorithm */ {hyphen}A { PREPROC; return(F_AUTH); } hmac-md5 { PREPROC; yylval.num = SADB_AALG_MD5HMAC; return(ALG_AUTH); } hmac-sha1 { PREPROC; yylval.num = SADB_AALG_SHA1HMAC; return(ALG_AUTH); } keyed-md5 { PREPROC; yylval.num = SADB_AALG_MD5; return(ALG_AUTH); } keyed-sha1 { PREPROC; yylval.num = SADB_AALG_SHA; return(ALG_AUTH); } null { PREPROC; yylval.num = SADB_AALG_NULL; return(ALG_AUTH); } /* encryption alogorithm */ {hyphen}E { PREPROC; return(F_ENC); } des-cbc { PREPROC; yylval.num = SADB_EALG_DESCBC; return(ALG_ENC); } 3des-cbc { PREPROC; yylval.num = SADB_EALG_3DESCBC; return(ALG_ENC); } simple { PREPROC; yylval.num = SADB_EALG_NULL; return(ALG_ENC); } blowfish-cbc { PREPROC; yylval.num = SADB_EALG_BLOWFISHCBC; return(ALG_ENC); } cast128-cbc { PREPROC; yylval.num = SADB_EALG_CAST128CBC; return(ALG_ENC); } rc5-cbc { PREPROC; yylval.num = SADB_EALG_RC5CBC; return(ALG_ENC); } des-deriv { PREPROC; yylval.num = SADB_EALG_DESCBC; return(ALG_ENC_DESDERIV); } des-32iv { PREPROC; yylval.num = SADB_EALG_DESCBC; return(ALG_ENC_DES32IV); } /* compression algorithms */ {hyphen}C { PREPROC; return(F_COMP); } oui { PREPROC; yylval.num = SADB_X_CALG_OUI; return(ALG_COMP); } deflate { PREPROC; yylval.num = SADB_X_CALG_DEFLATE; return(ALG_COMP); } lzs { PREPROC; yylval.num = SADB_X_CALG_LZS; return(ALG_COMP); } {hyphen}R { PREPROC; return(F_RAWCPI); } /* extension */ {hyphen}m { PREPROC; return(F_MODE); } transport { PREPROC; yylval.num = IPSEC_MODE_TRANSPORT; return(MODE); } tunnel { PREPROC; yylval.num = IPSEC_MODE_TUNNEL; return(MODE); } +{hyphen}u { PREPROC; return(F_REQID); } {hyphen}f { PREPROC; return(F_EXT); } random-pad { PREPROC; yylval.num = SADB_X_EXT_PRAND; return(EXTENSION); } seq-pad { PREPROC; yylval.num = SADB_X_EXT_PSEQ; return(EXTENSION); } zero-pad { PREPROC; yylval.num = SADB_X_EXT_PZERO; return(EXTENSION); } -cyclic-seq { PREPROC; yylval.num = SADB_X_EXT_CYCSEQ; return(EXTENSION); } +nocyclic-seq { PREPROC; return(NOCYCLICSEQ); } {hyphen}r { PREPROC; return(F_REPLAY); } {hyphen}lh { PREPROC; return(F_LIFETIME_HARD); } {hyphen}ls { PREPROC; return(F_LIFETIME_SOFT); } /* upper layer protocols */ icmp { PREPROC; yylval.num = IPPROTO_ICMP; return(UP_PROTO); } icmp6 { PREPROC; yylval.num = IPPROTO_ICMPV6; return(UP_PROTO); } tcp { PREPROC; yylval.num = IPPROTO_TCP; return(UP_PROTO); } udp { PREPROC; yylval.num = IPPROTO_UDP; return(UP_PROTO); } /* ... */ any { PREPROC; return(ANY); } {ws} { PREPROC; } {nl} { lineno++; } {comment} {semi} { PREPROC; return(EOT); } /* parameter */ {decstring} { char *bp; PREPROC; - yylval.num = strtol(yytext, &bp, 10); + yylval.num = strtoul(yytext, &bp, 10); return(DECSTRING); } -{ipv4addr} { - /* - * I can't supprt the type without dot, - * because it's umbiguous against {decstring}. - * e.g. 127 - */ +{ipaddress} { PREPROC; - yylval.val.len = sizeof(struct sockaddr_in); + yylval.val.len = yyleng; yylval.val.buf = strdup(yytext); - return(IP4_ADDRESS); + return(ADDRESS); } -{ipv6addr} { -#ifdef INET6 - PREPROC; - - yylval.val.len = sizeof(struct sockaddr_in6); - yylval.val.buf = strdup(yytext); - - return(IP6_ADDRESS); -#else - yyerror("IPv6 address not supported"); -#endif - } - {ipaddrmask} { PREPROC; yytext++; yylval.num = atoi(yytext); return(PREFIX); } {ipaddrport} { char *p = yytext; PREPROC; while (*++p != ']') ; *p = NULL; yytext++; yylval.num = atoi(yytext); return(PORT); } {blcl}any{elcl} { - char *p = yytext; PREPROC; return(PORTANY); } {hexstring} { int len = yyleng - 2; /* (str - "0x") */ PREPROC; yylval.val.len = (len & 1) + (len / 2); /* fixed string if length is odd. */ if (len & 1) { yytext[1] = '0'; yylval.val.buf = strdup(yytext + 1); } else yylval.val.buf = strdup(yytext + 2); return(HEXSTRING); } {quotedstring} { char *p = yytext; PREPROC; while (*++p != '"') ; *p = NULL; yytext++; yylval.val.len = yyleng - 2; yylval.val.buf = strdup(yytext); return(QUOTEDSTRING); } -. { yyerror("Syntax error"); } +. { + yyfatal("Syntax error"); + /*NOTREACHED*/ + } %% void -yyerror(char *s) +yyfatal(s) + const char *s; { + yyerror(s); + exit(1); +} + +void +yyerror(s) + const char *s; +{ printf("line %d: %s at [%s]\n", lineno, s, yytext); } int parse(fp) FILE **fp; { yyin = *fp; parse_init(); if (yyparse()) { printf("parse failed, line %d.\n", lineno); return(-1); } return(0); } - Index: head/usr.sbin/setkey/vchar.h =================================================================== --- head/usr.sbin/setkey/vchar.h (revision 62582) +++ head/usr.sbin/setkey/vchar.h (revision 62583) @@ -1,35 +1,36 @@ +/* $FreeBSD$ */ +/* $KAME: vchar.h,v 1.2 2000/06/07 00:29:14 itojun Exp $ */ + /* * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ typedef struct { - u_int len; - caddr_t buf; + u_int len; + caddr_t buf; } vchar_t;