libipsec and IPsec related apps. (and some KAME related man pages)

Reviewed by: freebsd-arch, cvs-committers
Obtained from: KAME project
This commit is contained in:
Yoshinobu Inoue 2000-01-06 12:40:54 +00:00
parent 171eec1876
commit 9a4365d0e0
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=55505
73 changed files with 18408 additions and 10 deletions

View File

@ -21,7 +21,8 @@ SUBDIR= ${_csu} libcom_err ${_libm} libmd ${_libcrypt} \
libncurses libradius libskey libtacplus \
${_compat} libalias libatm ${_libbind} libc ${_libc_r} libcalendar \
libcam libcompat libdevstat libdisk libedit libfetch libform \
libftpio libgnumalloc ${_libio} libipx libkvm libmenu ${_libncp} \
libftpio libgnumalloc ${_libio} libipsec libipx libkvm libmenu \
${_libncp} \
libnetgraph libopie libpam libpanel libpcap libresolv librpcsvc libss \
libstand ${_libtelnet} libutil ${_libvgl} libwrap libxpg4 liby libz

50
lib/libipsec/Makefile Normal file
View File

@ -0,0 +1,50 @@
# 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
CFLAGS+=-I${.OBJDIR}
CFLAGS+=-DIPSEC_DEBUG -DIPSEC -DINET6
.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
LDADD+= -ll -ly
CLEANFILES+= y.tab.c y.tab.h
YFLAGS+=-d -p __libyy
LFLAGS+=-P__libyy
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 <bsd.lib.mk>

View File

@ -0,0 +1,253 @@
/*
* 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 <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <netkey/key_var.h>
#include <netinet/in.h>
#include <netinet6/ipsec.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
#include <netdb.h>
#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));
/*
* 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;
char *buf;
int error;
/* sanity check */
if (policy == NULL)
return NULL;
if (xpl->sadb_x_policy_exttype != SADB_X_EXT_POLICY) {
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;
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;
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;
return NULL;
}
strcpy(buf, ipsp_dir_strs[xpl->sadb_x_policy_dir]);
strcat(buf, " ");
strcat(buf, ipsp_policy_strs[xpl->sadb_x_policy_type]);
if (xpl->sadb_x_policy_type != IPSEC_POLICY_IPSEC) {
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);
}
/* validity check */
if (xtlen < 0) {
ipsec_errcode = EIPSEC_INVAL_SADBMSG;
free(buf);
return NULL;
}
if ((buf = realloc(buf, buflen)) == NULL) {
ipsec_errcode = EIPSEC_NO_BUFS;
return NULL;
}
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;
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;
free(buf);
return NULL;
}
strcat(buf, "/");
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;
}
}
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);
return NULL;
}
xtlen -= xisr->sadb_x_ipsecrequest_len;
xisr = (struct sadb_x_ipsecrequest *)((caddr_t)xisr
+ xisr->sadb_x_ipsecrequest_len);
}
ipsec_errcode = EIPSEC_NO_ERROR;
return buf;
}
static int
set_addresses(buf, ptr)
char *buf;
caddr_t ptr;
{
char tmp[100]; /* XXX */
struct sockaddr *saddr = (struct sockaddr *)ptr;
getnameinfo(saddr, saddr->sa_len, tmp, sizeof(tmp),
NULL, 0, NI_NUMERICHOST);
strcat(buf, tmp);
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;
}

View File

@ -0,0 +1,44 @@
/*
* 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 <sys/types.h>
#include <sys/param.h>
#include <net/pfkeyv2.h>
#include "ipsec_strerror.h"
int
ipsec_get_policylen(policy)
caddr_t policy;
{
return policy ? PFKEY_EXTLEN(policy) : -1;
}

View File

@ -0,0 +1,253 @@
.\" 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: 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 KAME
.\"
.Sh NAME
.Nm ipsec_set_policy ,
.Nm ipsec_get_policylen ,
.Nm ipsec_dump_policy
.Nd manipulate IPsec policy specification structure from readable string
.\"
.Sh SYNOPSIS
.Fd #include <netinet6/ipsec.h>
.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.
.Po
packet will be transmitted in clear
.Pc .
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
or
.Li require .
.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.
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
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 ispec 4
.Xr setkey 8
.\"
.Sh HISTORY
The functions first appeared in WIDE/KAME IPv6 protocol stack kit.
.\"
.\" .Sh BUGS
.\" (to be written)

View File

@ -0,0 +1,66 @@
.\" 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: ipsec_strerror.3,v 1.2 1999/09/21 03:49:19 itojun Exp $
.\" $FreeBSD$
.\"
.Dd May 6, 1998
.Dt IPSEC_STRERROR 3
.Os KAME
.\"
.Sh NAME
.Nm ipsec_strerror
.Nd error code for IPsec policy manipulation library
.\"
.Sh SYNOPSIS
.Fd #include <netinet6/ipsec.h>
.Ft "char *"
.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.
.\"
.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 HISTORY
The functions first appeared in WIDE/KAME IPv6 protocol stack kit.
.\"
.\" .Sh BUGS
.\" (to be written)

View File

@ -0,0 +1,87 @@
/*
* 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 <sys/types.h>
#include <sys/param.h>
#include <string.h>
#include <netinet6/ipsec.h>
#include "ipsec_strerror.h"
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;
return ipsec_errlist[ipsec_errcode];
}
void ipsec_set_strerror(char *str)
{
ipsec_errcode = EIPSEC_SYSTEM_ERROR;
ipsec_errlist[EIPSEC_SYSTEM_ERROR] = str;
return;
}

View File

@ -0,0 +1,62 @@
/*
* 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);
#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*/

1421
lib/libipsec/pfkey.c Normal file

File diff suppressed because it is too large Load Diff

463
lib/libipsec/pfkey_dump.c Normal file
View File

@ -0,0 +1,463 @@
/*
* 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 <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <netinet6/ipsec.h>
#include <net/pfkeyv2.h>
#include <netkey/key_var.h>
#include <netkey/key_debug.h>
#include <netinet/in.h>
#include <netinet6/ipsec.h>
#ifdef INET6
#include <netinet6/in6.h>
#endif
#include <arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include "ipsec_strerror.h"
#define GETMSGSTR(str, num) \
{ \
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)]); \
}
#define GETAF(p) \
(((struct sockaddr *)(p))->sa_family)
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_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_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_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)));
/* 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)));
/* SA type */
if (m_sa == NULL) {
printf("no SA extension.\n");
return;
}
printf("\n\t");
GETMSGSTR(_str_satype, m->sadb_msg_satype);
printf("mode=");
GETMSGSTR(_str_mode, m->sadb_msg_mode);
printf("spi=%u(0x%08x) replay=%u flags=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);
/* 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");
}
/* state */
printf("\tstate=");
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));
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));
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");
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);
return;
}
void
pfkey_spdump(m)
struct sadb_msg *m;
{
caddr_t mhp[SADB_EXT_MAX + 1];
struct sadb_address *m_saddr, *m_daddr;
struct sadb_x_policy *m_xpl;
/* 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)));
/* 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)));
/* upper layer protocol */
if (m_saddr->sadb_address_proto != m_saddr->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",
(u_long)m->sadb_msg_seq,
(u_long)m->sadb_msg_pid);
/* XXX TEST */
printf("\trefcnt=%d\n", m->sadb_msg_reserved);
return;
}
/*
* set "ipaddress" to buffer.
*/
static char *
_str_ipaddr(family, addr)
u_int family;
caddr_t addr;
{
static char buf[128];
char addrbuf[128];
if (addr == NULL)
return "";
inet_ntop(family, addr, addrbuf, sizeof(addrbuf));
snprintf(buf, sizeof(buf), "%s", addrbuf);
return buf;
}
/*
* set "/prefix[port number]" to buffer.
*/
static char *
_str_prefport(family, pref, port)
u_int family, pref, port;
{
static char buf[128];
char prefbuf[10];
char portbuf[10];
if (pref == (_INALENBYAF(family) << 3))
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(buf, sizeof(buf), "%s%s", prefbuf, portbuf);
return buf;
}
/*
* set "Mon Day Time Year" to buffer
*/
static char *
_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)
struct sadb_lifetime *x;
char *str;
{
double y;
char *unit;
int w;
if (x == NULL) {
printf("\t%s: 0(bytes)", str);
return;
}
y = (x->sadb_lifetime_bytes) * 1.0;
unit = "";
w = 0;
printf("\t%s: %.*f(%sbytes)", str, w, y, unit);
}

426
lib/libipsec/policy_parse.y Normal file
View File

@ -0,0 +1,426 @@
/*
* 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 <policy>
* out <policy>
*
* <policy> is one of following:
* "discard", "none", "ipsec <requests>", "entrust", "bypass",
*
* The following requests are accepted as <requests>:
*
* 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 <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet6/ipsec.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include "ipsec_strerror.h"
#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 struct sockaddr *p_src = NULL;
static struct sockaddr *p_dst = NULL;
extern void yyerror __P((char *msg));
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();
%}
%union {
u_int num;
struct _val {
int len;
char *buf;
} val;
}
%token DIR ACTION PROTOCOL MODE LEVEL
%token IPADDRESS
%token ME ANY
%token SLASH HYPHEN
%type <num> DIR ACTION PROTOCOL MODE LEVEL
%type <val> IPADDRESS
%%
policy_spec
: DIR ACTION
{
p_dir = $1;
p_type = $2;
if (init_x_policy())
return -1;
}
rules
;
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;
return -1;
}
| protocol {
ipsec_errcode = EIPSEC_FEW_ARGUMENTS;
return -1;
}
;
protocol
: PROTOCOL { p_protocol = $1; }
;
mode
: MODE { p_mode = $1; }
;
level
: LEVEL { p_level = $1; }
;
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;
return -1;
}
}
| ANY HYPHEN ME {
if (p_dir != IPSEC_DIR_INBOUND) {
ipsec_errcode = EIPSEC_INVAL_DIR;
return -1;
}
}
/*
| ME HYPHEN ME
*/
;
%%
void
yyerror(msg)
char *msg;
{
fprintf(stderr, "%s\n", msg);
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));
return NULL;
}
if (res->ai_addr == NULL) {
ipsec_set_strerror(gai_strerror(error));
return NULL;
}
newaddr = malloc(res->ai_addr->sa_len);
if (newaddr == NULL) {
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;
return newaddr;
}
static int
rule_check()
{
if (p_type == IPSEC_POLICY_IPSEC) {
if (p_protocol == IPPROTO_IP) {
ipsec_errcode = EIPSEC_NO_PROTO;
return -1;
}
if (p_mode != IPSEC_MODE_TRANSPORT
&& p_mode != IPSEC_MODE_TUNNEL) {
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;
return -1;
}
}
else if (p_src->sa_family != p_dst->sa_family) {
ipsec_errcode = EIPSEC_FAMILY_MISMATCH;
return -1;
}
}
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;
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;
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;
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;
offset += sizeof(*p);
if (set_sockaddr(src) || set_sockaddr(dst))
return -1;
ipsec_errcode = EIPSEC_NO_ERROR;
return 0;
}
static int
set_sockaddr(addr)
struct sockaddr *addr;
{
if (addr == NULL) {
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;
return 0;
}
static void
policy_parse_request_init()
{
p_protocol = IPPROTO_IP;
p_mode = IPSEC_MODE_ANY;
p_level = IPSEC_LEVEL_DEFAULT;
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;
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;
return NULL;
}
ipsec_errcode = EIPSEC_NO_ERROR;
return policy;
}

137
lib/libipsec/policy_token.l Normal file
View File

@ -0,0 +1,137 @@
/*
* 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 <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <net/route.h>
#include <net/pfkeyv2.h>
#include <netkey/keydb.h>
#include <netkey/key_debug.h>
#include <netinet/in.h>
#include <netinet6/ipsec.h>
#include <stdlib.h>
#include <limits.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include "y.tab.h"
#define yylval __libyylval /* XXX */
%}
%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}?)?
%%
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 { yylval.num = IPSEC_LEVEL_UNIQUE; return(LEVEL); }
{slash} { return(SLASH); }
{ipaddress} {
yylval.val.len = strlen(yytext);
yylval.val.buf = strdup(yytext);
return(IPADDRESS);
}
{hyphen} { return(HYPHEN); }
{ws} { ; }
{nl} { ; }
%%
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;
}

179
lib/libipsec/test-policy.c Normal file
View File

@ -0,0 +1,179 @@
/*
* 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 <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet6/in6.h>
#include <netkey/keyv2.h>
#include <netkey/key_debug.h>
#include <netinet6/ipsec.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <err.h>
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
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",
};
int test(char *buf, int family);
int
main(ac, av)
int ac;
char **av;
{
int do_setsockopt;
char *buf;
int i;
if (ac != 1)
do_setsockopt = 1;
else
do_setsockopt = 0;
for (i = 0; i < sizeof(requests)/sizeof(requests[0]); i++) {
printf("*** requests ***\n");
printf("\t[%s]\n", requests[i]);
buf = ipsec_set_policy(requests[i], strlen(requests[i]));
if (buf == NULL) {
printf("ipsec_set_policy: %s\n", ipsec_strerror());
continue;
}
printf("\tsetlen:%d\n", ipsec_get_policylen(buf));
if (do_setsockopt) {
printf("\tPF_INET:\n");
test(buf, PF_INET);
printf("\tPF_INET6:\n");
test(buf, PF_INET6);
} else {
kdebug_sadb_x_policy((struct sadb_ext *)buf);
}
free(buf);
}
return 0;
}
int
test(policy, family)
char *policy;
int family;
{
int so, proto, optname;
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 (setsockopt(so, proto, optname, policy, len) < 0) {
printf("error on setsockopt");
goto end;
}
len = sizeof(getbuf);
memset(getbuf, 0, sizeof(getbuf));
if (getsockopt(so, proto, optname, getbuf, &len) < 0) {
printf("error on getsockopt");
goto end;
}
{
char *buf = NULL;
printf("\tgetlen:%d\n", len);
if ((buf = ipsec_dump_policy(getbuf, NULL)) == NULL) {
printf("%s\n", ipsec_strerror());
goto end;
} else {
printf("\t[%s]\n", buf);
free(buf);
}
}
end:
close (so);
return 0;
}

View File

@ -8,7 +8,8 @@ COPTS+= -Wall -Wmissing-prototypes
.if ${MACHINE_ARCH} == "alpha"
COPTS+= -fno-builtin # GCC's builtin memcpy doesn't do unaligned copies
.endif
DPADD= ${LIBM}
LDADD= -lm
CFLAGS+=-DIPSEC
DPADD= ${LIBM} ${LIBIPSEC}
LDADD= -lm -lipsec
.include <bsd.prog.mk>

View File

@ -47,6 +47,7 @@ packets to network hosts
.Op Fl i Ar wait
.Op Fl l Ar preload
.Op Fl p Ar pattern
.Op Fl P Ar policy
.Op Fl s Ar packetsize
.Op Fl S Ar src_addr
.Bo
@ -147,6 +148,13 @@ For example,
.Dq Li \-p ff
will cause the sent packet to be filled with all
ones.
.It Fl P Ar policy
.Ar policy
specifies IPsec policy for the ping session.
For details please refer to
.Xr ipsec 4
and
.Xr ipsec_set_policy 3 .
.It Fl Q
Somewhat quiet output.
.No Don Ap t

View File

@ -92,6 +92,10 @@ static const char rcsid[] =
#include <netinet/ip_var.h>
#include <arpa/inet.h>
#ifdef IPSEC
#include <netinet6/ipsec.h>
#endif /*IPSEC*/
#define PHDR_LEN sizeof(struct timeval)
#define DEFDATALEN (64 - PHDR_LEN) /* default data length */
#define FLOOD_BACKOFF 20000 /* usecs to back off if F_FLOOD mode */
@ -124,6 +128,11 @@ int options;
#define F_MTTL 0x0800
#define F_MIF 0x1000
#define F_AUDIBLE 0x2000
#ifdef IPSEC
#ifdef IPSEC_POLICY_IPSEC
#define F_POLICY 0x4000
#endif /*IPSEC_POLICY_IPSEC*/
#endif /*IPSEC*/
/*
* MAX_DUP_CHK is the number of bits in received table, i.e. the maximum
@ -204,6 +213,10 @@ main(argc, argv)
struct msghdr msg;
struct sockaddr_in from;
char ctrl[sizeof(struct cmsghdr) + sizeof(struct timeval)];
#ifdef IPSEC_POLICY_IPSEC
char *policy_in = NULL;
char *policy_out = NULL;
#endif
/*
* Do the stuff that we need root priv's for *first*, and
@ -219,7 +232,14 @@ main(argc, argv)
preload = 0;
datap = &outpack[8 + PHDR_LEN];
while ((ch = getopt(argc, argv, "I:LQRS:T:c:adfi:l:np:qrs:v")) != -1) {
#ifndef IPSEC
while ((ch = getopt(argc, argv, "I:LQRT:c:adfi:l:np:qrs:v")) != -1)
#else
#ifdef IPSEC_POLICY_IPSEC
while ((ch = getopt(argc, argv, "I:LQRT:c:adfi:l:np:qrs:vP:")) != -1)
#endif /*IPSEC_POLICY_IPSEC*/
#endif
{
switch(ch) {
case 'a':
options |= F_AUDIBLE;
@ -331,6 +351,19 @@ main(argc, argv)
case 'v':
options |= F_VERBOSE;
break;
#ifdef IPSEC
#ifdef IPSEC_POLICY_IPSEC
case 'P':
options |= F_POLICY;
if (!strncmp("in", optarg, 2))
policy_in = strdup(optarg);
else if (!strncmp("out", optarg, 3))
policy_out = strdup(optarg);
else
errx(1, "invalid security policy");
break;
#endif /*IPSEC_POLICY_IPSEC*/
#endif /*IPSEC*/
default:
usage();
}
@ -419,6 +452,32 @@ main(argc, argv)
if (options & F_SO_DONTROUTE)
(void)setsockopt(s, SOL_SOCKET, SO_DONTROUTE, (char *)&hold,
sizeof(hold));
#ifdef IPSEC
#ifdef IPSEC_POLICY_IPSEC
if (options & F_POLICY) {
char *buf;
if (policy_in != NULL) {
buf = ipsec_set_policy(policy_in, strlen(policy_in));
if (buf == NULL)
errx(EX_CONFIG, ipsec_strerror());
if (setsockopt(s, IPPROTO_IP, IP_IPSEC_POLICY,
buf, ipsec_get_policylen(buf)) < 0)
err(EX_CONFIG, "ipsec policy cannot be configured");
free(buf);
}
if (policy_out != NULL) {
buf = ipsec_set_policy(policy_out, strlen(policy_out));
if (buf == NULL)
errx(EX_CONFIG, ipsec_strerror());
if (setsockopt(s, IPPROTO_IP, IP_IPSEC_POLICY,
buf, ipsec_get_policylen(buf)) < 0)
err(EX_CONFIG, "ipsec policy cannot be configured");
free(buf);
}
}
#endif /*IPSEC_POLICY_IPSEC*/
#endif /*IPSEC*/
/* record route option */
if (options & F_RROUTE) {
@ -1326,7 +1385,13 @@ usage()
{
fprintf(stderr, "%s\n%s\n%s\n",
"usage: ping [-QRadfnqrv] [-c count] [-i wait] [-l preload] [-p pattern]",
" [-s packetsize] [-S src_addr]",
" [host | [-L] [-I iface] [-T ttl] mcast-group]");
" "
#ifdef IPSEC
#ifdef IPSEC_POLICY_IPSEC
"[-P policy] "
#endif
#endif
"[-s packetsize] [-S src_addr]",
"[host | [-L] [-I iface] [-T ttl] mcast-group]");
exit(EX_USAGE);
}

56
sbin/setkey/Makefile Normal file
View File

@ -0,0 +1,56 @@
# 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
LDADD+= -ll -ly
CLEANFILES+= y.tab.c y.tab.h key_test.o keytest
YFLAGS+=-d
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}
LDADD+= -lipsec
CLEANFILES+= scriptdump y.tab.h
MAN8= setkey.8
LOCALPREFIX= /usr/local
scriptdump: scriptdump.pl
sed -e 's#@LOCALPREFIX@#${LOCALPREFIX}#' < $> > scriptdump
.include <bsd.prog.mk>

787
sbin/setkey/parse.y Normal file
View File

@ -0,0 +1,787 @@
/*
* 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 <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <net/route.h>
#include <netinet/in.h>
#include <net/pfkeyv2.h>
#include <netkey/key_var.h>
#include <netinet6/ipsec.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <ctype.h>
#include <errno.h>
#include <netdb.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_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;
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));
extern int setkeymsg __P((void));
extern int sendkeymsg __P((void));
extern int yylex __P((void));
extern void yyerror __P((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 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 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
%%
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
;
/* get command */
get_command
: GET { p_type = SADB_GET; }
sa_selector_spec extension_spec 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)
p_ext |= SADB_X_EXT_OLD;
else
p_ext &= ~SADB_X_EXT_OLD;
}
| PR_AH
{
p_satype = SADB_SATYPE_AH;
if ($1.num == 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; }
| HEXSTRING
{
caddr_t bp;
caddr_t yp = $1.val.buf;
char buf0[4], buf[4];
int i, j;
/* sanity check */
if ($1.val.len > 4) {
yyerror("SPI too big.");
free($1.val.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--)
buf[i] = buf0[j];
/* XXX: endian */
p_spi = ntohl(*(u_int32_t *)buf);
free($1.val.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_RAWCPI { p_ext |= SADB_X_EXT_RAWCPI; }
;
enc_alg
: ALG_ENC { p_alg_enc = $1.num; }
| ALG_ENC_DESDERIV
{
p_alg_enc = $1.num;
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;
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 = 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; }
;
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 = 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;
/* free pp_key later */
}
| HEXSTRING
{
caddr_t bp;
caddr_t yp = $1.val.buf;
if ((pp_key = malloc($1.val.len)) == 0) {
free($1.val.buf);
yyerror(strerror(errno));
return -1;
}
memset(pp_key, 0, $1.val.len);
bp = pp_key;
while (*yp) {
*bp = (ATOX(yp[0]) << 4) | ATOX(yp[1]);
yp += 2, bp++;
}
free($1.val.buf);
}
;
extension_spec
: /*NOTHING*/
| extension_spec extension
;
extension
: F_EXT EXTENSION { p_ext |= $1.num; }
| F_MODE MODE { p_mode = $2.num; }
| F_MODE ANY { p_mode = IPSEC_MODE_ANY; }
| F_REPLAY DECSTRING
{
if (p_ext & SADB_X_EXT_OLD) {
yyerror("replay prevention "
"only use on new spec.");
return -1;
}
p_replay = $2.num;
}
| F_LIFETIME_HARD DECSTRING { p_lt_hard = $2.num; }
| F_LIFETIME_SOFT DECSTRING { p_lt_soft = $2.num; }
;
/* 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
;
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); }
ipaddress { p_dst = pp_addr; }
prefix { p_prefd = pp_prefix; }
port { _INPORTBYSA(p_dst) = htons(pp_port); }
upper_spec
;
ipaddress
: IP4_ADDRESS
{
struct sockaddr_in *in;
u_int sa_len = $1.val.len;
if ((in = (struct sockaddr_in *)malloc(sa_len)) == 0) {
yyerror(strerror(errno));
free($1.val.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;
}
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);
freeaddrinfo(res);
pp_addr = (struct sockaddr *)in6;
#else
yyerror("IPv6 address not supported");
#endif
free($1.val.buf);
}
;
prefix
: /*NOTHING*/ { pp_prefix = ~0; }
| PREFIX { pp_prefix = $1.num; }
;
port
: /*NOTHING*/ { pp_port = IPSEC_PORT_ANY; }
| PORT { pp_port = $1.num; }
| PORTANY { pp_port = IPSEC_PORT_ANY; }
;
upper_spec
: DECSTRING { p_upper = $1.num; }
| UP_PROTO { p_upper = $1.num; }
| 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);
if (p_policy == NULL) {
free($2.val.buf);
p_policy = NULL;
yyerror(ipsec_strerror());
return -1;
}
p_policy_len = ipsec_get_policylen(p_policy);
free($2.val.buf);
}
;
policy_requests:
/*NOTHING*/
| 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_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;
/* 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;
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;
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:
{
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;
m_addr.sadb_address_prefixlen =
(p_prefs != ~0 ? p_prefs :
_INALENBYAF(p_src->sa_family) << 3);
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;
m_addr.sadb_address_prefixlen =
(p_prefd != ~0 ? p_prefd :
_INALENBYAF(p_dst->sa_family) << 3);
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 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_alg_enc = SADB_EALG_NONE;
p_alg_auth = SADB_AALG_NONE;
p_mode = IPSEC_MODE_ANY;
p_replay = 4;
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;
}

219
sbin/setkey/sample.cf Normal file
View File

@ -0,0 +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 ;
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 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.

54
sbin/setkey/scriptdump.pl Normal file
View File

@ -0,0 +1,54 @@
#! @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 $_ (<IN>) {
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 (/^\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=/) {
print "$mode $src $dst $proto $spi -m $ipsecmode";
print " -r $replay" if $replay;
if ($mode eq 'add') {
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;

550
sbin/setkey/setkey.8 Normal file
View File

@ -0,0 +1,550 @@
.\" 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 KAME
.\"
.Sh NAME
.Nm setkey
.Nd manually manipulate the 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.
.Pp
.Nm
takes a series of operation from standard input
.Po
if invoked with
.Fl c
.Pc
or 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.
If with
.Fl P ,
the SPD are flushed.
.It Fl a
.Nm
usually do not display dead SAD entries on
.Fl D .
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.
.It Fl d
Enable debugging messages.
.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.
.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.
.\"
.It Xo
.Li get
.Ar src Ar dst Ar protocol Ar spi
.Op Ar mode
.Li ;
.Xc
Show a SAD entry.
.\"
.It Xo
.Li delete
.Ar src Ar dst Ar protocol Ar spi
.Op Ar mode
.Li ;
.Xc
Remove a SAD entry.
.\"
.It Xo
.Li flush
.Op Ar protocol
.Li ;
.Xc
Clear all SAD entries that matches the options.
.\"
.It Xo
.Li dump
.Op Ar protocol
.Li ;
.Xc
Dumps all SAD entries that matches the options.
.\"
.It Xo
.Li spdadd
.Ar src_range Ar dst_range Ar upperspec Ar policy
.Li ;
.Xc
Add a SPD entry.
.\"
.It Xo
.Li spddelete
.Ar src_range Ar dst_range Ar upperspec
.Li ;
.Xc
Delete a SPD entry.
.\"
.It Xo
.Li spdflush
.Li ;
.Xc
Clear all SPD entries.
.\"
.It Xo
.Li spddump
.Li ;
.Xc
Dumps all SAD 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.
It must be decimal number or hexadecimal number
.Po
with
.Li 0x
attached
.Pc .
.\"
.Pp
.It Ar extensions
takes 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 .
.Ar mode
is one of following:
.Li transport , tunnel
or
.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 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 lh Ar time
.It Fl ls Ar time
Specify hard/soft lifetime.
.El
.\"
.Pp
.It Ar algorithm
.Bl -tag -width Fl -compact
.It Fl E Ar ealgo Ar key
Specify encryption algorithm.
.It Fl A Ar ealgo 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
.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,
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.
.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
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 .
.\"
.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
specified, e.g.
.Li esp_trans_deflev
sysctl variable, when kernel processes the packet.
.Li use
means that kernel use a SA if it's available,
otherwise kernel keeps normal operation.
.Li require
means SA is required whenever 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
.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
.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
.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.
.\"
.\" .Sh BUGS

566
sbin/setkey/setkey.c Normal file
View File

@ -0,0 +1,566 @@
/*
* 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 <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <err.h>
#include <net/route.h>
#include <netinet/in.h>
#include <net/pfkeyv2.h>
#include <netkey/keydb.h>
#include <netkey/key_debug.h>
#include <netinet6/ipsec.h>
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <errno.h>
#include <netdb.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
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;
u_char m_buf[BUFSIZ];
u_int m_len;
extern int lineno;
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);
}
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*/
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);
break;
default:
Usage();
}
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)
kdebug_sadb((struct sadb_msg *)m_buf);
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)
kdebug_sadb((struct sadb_msg *)rbuf);
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)
kdebug_sadb((struct sadb_msg *)msg);
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)
kdebug_sadb((struct sadb_msg *)msg);
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");
}

480
sbin/setkey/test-pfkey.c Normal file
View File

@ -0,0 +1,480 @@
/*
* 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 <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <net/route.h>
#include <net/pfkeyv2.h>
#include <netinet/in.h>
#include <netkey/keydb.h>
#include <netkey/key_var.h>
#include <netkey/key_debug.h>
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <errno.h>
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()
{
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;
}
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;
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;
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 (type) {
case SADB_GETSPI:
/*<base, address(SD), SPI range>*/
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();
/*<base, SA(*), address(SD)>*/
break;
case SADB_ADD:
/* <base, SA, (lifetime(HSC),) address(SD), (address(P),)
key(AE), (identity(SD),) (sensitivity)> */
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();
/* <base, SA, (lifetime(HSC),) address(SD), (address(P),)
(identity(SD),) (sensitivity)> */
break;
case SADB_DELETE:
/* <base, SA(*), address(SDP)> */
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");
/* <base, SA(*), address(SDP)> */
break;
case SADB_GET:
/* <base, SA(*), address(SDP)> */
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");
/* <base, SA, (lifetime(HSC),) address(SD), (address(P),)
key(AE), (identity(SD),) (sensitivity)> */
break;
case SADB_ACQUIRE:
/* <base, address(SD), (address(P),) (identity(SD),)
(sensitivity,) proposal> */
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();
/* <base, address(SD), (address(P),) (identity(SD),)
(sensitivity,) proposal> */
break;
case SADB_REGISTER:
/* <base> */
/* <base, supported> */
break;
case SADB_EXPIRE:
case SADB_FLUSH:
break;
case SADB_DUMP:
break;
case SADB_X_PROMISC:
/* <base> */
/* <base, base(, others)> */
break;
case SADB_X_PCHANGE:
break;
/* for SPD management */
case SADB_X_SPDFLUSH:
case SADB_X_SPDDUMP:
break;
case SADB_X_SPDADD:
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;
/* 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 */
len = sizeof(struct sadb_address) + PFKEY_ALIGN8(a->sa_len);
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_reserved = 0;
key_setsadbextbuf(m_buf, m_len,
(caddr_t)&m_addr, sizeof(struct sadb_address),
abuf, a->sa_len);
m_len += len;
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;
}

161
sbin/setkey/test-policy.c Normal file
View File

@ -0,0 +1,161 @@
/*
* 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 <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet6/in6.h>
#include <netkey/keyv2.h>
#include <stdlib.h>
#include <string.h>
#include <netinet6/ipsec.h>
char *requests[] = {
"must_error", /* must be error */
"ipsec must_error", /* must be error */
"ipsec esp/must_error", /* must be error */
"discard",
"none",
"entrust",
"bypass", /* may be error */
"ipsec esp", /* must be error */
"ipsec ah/require",
"ipsec ah/use/",
"ipsec esp/require ah/default/203.178.141.194",
"ipsec ah/use/203.178.141.195 esp/use/203.178.141.194",
"ipsec esp/elf.wide.ydc.co.jp esp/www.wide.ydc.co.jp"
"
ipsec esp/require ah/use esp/require/10.0.0.1
ah/use/3ffe:501:481d::1 ah/use/3ffe:501:481d::1 ah/use/3ffe:501:481d::1
ah/use/3ffe:501:481d::1 ah/use/3ffe:501:481d::1 ah/use/3ffe:501:481d::1
ah/use/3ffe:501:481d::1 ah/use/3ffe:501:481d::1 ah/use/3ffe:501:481d::1
ah/use/3ffe:501:481d::1 ah/use/3ffe:501:481d::1 ah/use/3ffe:501:481d::1
ah/use/3ffe:501:481d::1 ah/use/3ffe:501:481d::1 ah/use/3ffe:501:481d::1
ah/use/3ffe:501:481d::1 ah/use/3ffe:501:481d::1 ah/use/3ffe:501:481d::1
ah/use/3ffe:501:481d::1 ah/use/3ffe:501:481d::1 ah/use/3ffe:501:481d::1
ah/use/3ffe:501:481d::1 ah/use/3ffe:501:481d::1ah/use/3ffe:501:481d::1
",
};
u_char *p_secpolicy;
int test(char *buf, int family);
char *setpolicy(char *req);
main()
{
int i;
char *buf;
for (i = 0; i < sizeof(requests)/sizeof(requests[0]); i++) {
printf("* requests:[%s]\n", requests[i]);
if ((buf = setpolicy(requests[i])) == NULL)
continue;
printf("\tsetlen:%d\n", PFKEY_EXTLEN(buf));
printf("\tPF_INET:\n");
test(buf, PF_INET);
printf("\tPF_INET6:\n");
test(buf, PF_INET6);
free(buf);
}
}
int test(char *policy, int family)
{
int so, proto, optname;
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)
perror("socket");
if (setsockopt(so, proto, optname, policy, PFKEY_EXTLEN(policy)) < 0)
perror("setsockopt");
len = sizeof(getbuf);
memset(getbuf, 0, sizeof(getbuf));
if (getsockopt(so, proto, optname, getbuf, &len) < 0)
perror("getsockopt");
{
char *buf = NULL;
printf("\tgetlen:%d\n", len);
if ((buf = ipsec_dump_policy(getbuf, NULL)) == NULL)
ipsec_strerror();
else
printf("\t[%s]\n", buf);
free(buf);
}
close (so);
}
char *setpolicy(char *req)
{
int len;
char *buf;
if ((len = ipsec_get_policylen(req)) < 0) {
printf("ipsec_get_policylen: %s\n", ipsec_strerror());
return NULL;
}
if ((buf = malloc(len)) == NULL) {
perror("malloc");
return NULL;
}
if ((len = ipsec_set_policy(buf, len, req)) < 0) {
printf("ipsec_set_policy: %s\n", ipsec_strerror());
free(buf);
return NULL;
}
return buf;
}

322
sbin/setkey/token.l Normal file
View File

@ -0,0 +1,322 @@
/*
* 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 <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <net/route.h>
#include <net/pfkeyv2.h>
#include <netkey/keydb.h>
#include <netkey/key_debug.h>
#include <netinet/in.h>
#include <netinet6/ipsec.h>
#include <stdlib.h>
#include <limits.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#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 ? */
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));
%}
/* 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}+)?
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); }
<S_PL>[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);
}
<S_PL>{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}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); }
{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);
return(DECSTRING);
}
{ipv4addr} {
/*
* I can't supprt the type without dot,
* because it's umbiguous against {decstring}.
* e.g. 127
*/
PREPROC;
yylval.val.len = sizeof(struct sockaddr_in);
yylval.val.buf = strdup(yytext);
return(IP4_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"); }
%%
void
yyerror(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);
}

35
sbin/setkey/vchar.h Normal file
View File

@ -0,0 +1,35 @@
/*
* 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;
} vchar_t;

View File

@ -3,9 +3,11 @@
MAN4= ahc.4 alpm.4 amd.4 atkbd.4 atkbdc.4 aue.4 blackhole.4 bpf.4 \
bridge.4 ccd.4 cd.4 ch.4 da.4 dc.4 ddb.4 de.4 \
divert.4 drum.4 dummynet.4 fd.4 fdc.4 fpa.4 fxp.4 \
divert.4 drum.4 dummynet.4 faith.4 fd.4 fdc.4 fpa.4 fxp.4 \
gif.4 \
icmp.4 ifmib.4 iic.4 iicbb.4 iicbus.4 iicsmb.4 \
inet.4 intpm.4 intro.4 ip.4 ipfirewall.4 keyboard.4 kld.4 \
inet.4 inet6.4 intpm.4 intro.4 ip.4 ipfirewall.4 ipsec.4 \
kame.4 keyboard.4 kld.4 \
kue.4 lo.4 lp.4 lpbb.4 lpt.4 mem.4 mouse.4 mtio.4 natm.4 ncr.4 \
netintro.4 null.4 ohci.4 pass.4 pci.4 pcm.4 pcvt.4 \
ppbus.4 ppi.4 ppp.4 psm.4 pt.4 pty.4 rl.4 \

122
share/man/man4/faith.4 Normal file
View File

@ -0,0 +1,122 @@
.\" 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.
.\"
.\" $Id: faith.4,v 1.1.1.1 1999/08/08 23:30:37 itojun Exp $
.\" $FreeBSD$
.\"
.Dd April 10, 1999
.Dt FAITH 4
.Os KAME
.Sh NAME
.Nm faith
.Nd
.Tn IPv6-to-IPv4 TCP relay capturing interface
.Sh SYNOPSIS
.Cd "pseudo-device faith 1"
.Sh DESCRIPTION
The
.Nm
interface captures IPv6 TCP traffic,
for implementing userland IPv6-to-IPv4 TCP relay
like
.Xr faithd 8 .
.Pp
Special action will be taken when IPv6 TCP traffic is seen on a router,
and routing table suggests to route it to
.Nm
interface.
In this case, the packet will be accepted by the router,
regardless of list of IPv6 interface addresses assigned to the router.
The packet will be captured by an IPv6 TCP socket, if it has
.Dv IN6P_FAITH
flag turned on and it has matching address/port pairs.
In result,
.Nm
will let you capture IPv6 TCP traffic to some specific destination addresses.
Userland programs, such as
.Xr faithd 8
can use this behavior to relay IPv6 TCP traffic to IPv4 TCP traffic.
The program can accept some specific IPv6 TCP traffic, perform
.Xr getsockname 3
to get the IPv6 destination address specified by the client,
and perform application-specific address mapping to relay IPv6 TCP to IPv4 TCP.
.Pp
.Dv IN6P_FAITH
flag on IPv6 TCP socket can be set by using
.Xr setsockopt 2 ,
with level equals to
.Dv IPPROTO_IPV6
and optname equals to
.Dv IPv6_FAITH .
.Pp
To handle error reports by ICMPv6, some of ICMPv6 packets routed to
.Nm
interface will be delivered to IPv6 TCP, as well.
.Pp
To understand how
.Nm
can be used, take a look at source code of
.Xr faithd 8 .
.Pp
As
.Nm
interface implements potentially dangerous operation,
great care must be taken when configuring
.Nm
interface.
To avoid possible misuse,
.Xr sysctl 8
variable
.Li net.inet6.ip6.keepfaith
must be set to
.Li 1
prior to the use of the interface.
When
.Li net.inet6.ip6.keepfaith
is
.Li 0 ,
no packet will be captured by
.Nm
interface.
.Pp
.Nm
interface is intended to be used on routers, not on hosts.
.\"
.Sh SEE ALSO
.Xr inet 4 ,
.Xr inet6 4 ,
.Xr faithd 8 .
.\" .Rs
.\" .%A Jun-ichiro itojun Hagino
.\" .%A Kazu Yamamoto
.\" .%T ``FAITH'' IPv6-to-IPv4 TCP relay translator
.\" .%D July 1999
.\" .Re
.\"
.Sh HISTORY
The FAITH IPv6-to-IPv4 TCP relay translator was first appeared in
WIDE hydrangea IPv6 stack.

232
share/man/man4/gif.4 Normal file
View File

@ -0,0 +1,232 @@
.\" 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.
.\"
.\" $Id: gif.4,v 1.2 1999/09/29 15:36:17 itojun Exp $
.\" $FreeBSD$
.\"
.Dd April 10, 1999
.Dt GIF 4
.Os KAME
.Sh NAME
.Nm gif
.Nd
.Tn Generic tunnel interface
.Sh SYNOPSIS
.Cd "pseudo-device gif 4"
.Sh DESCRIPTION
The
.Nm
interface is a generic tunnelling pseudo device for IPv4 and IPv6.
It can tunnel IPv[46] traffic over IPv[46].
Therefore, there can be four possible configurations.
The behavior of
.Nm
is mainly based on RFC1933 IPv6-over-IPv4 configured tunnel.
.Pp
To use
.Nm gif ,
administrator needs to configure protocol and addresses used for the outer
header.
This can be done by using
.Xr gifconfig 8 ,
or
.Dv SIOCSIFPHYADDR
ioctl.
Also, administrator needs to configure protocol and addresses used for the
inner header, by using
.Xr ifconfig 8 .
Note that IPv6 link-local address
.Pq those start with Li fe80::
will be automatically configured whenever possible.
You may need to remove IPv6 link-local address manually using
.Xr ifconfig 8 ,
when you would like to disable the use of IPv6 as inner header
.Pq like when you need pure IPv4-over-IPv6 tunnel .
Finally, use routing table to route the packets toward
.Nm
interface.
.Pp
.Nm
interface can be configued to perform bidirectional tunnel, or
multi-destination tunnel.
This is controlled by
.Dv IFF_LINK0
interface flag.
Also,
.Nm
can be configured to be ECN friendly.
This can be configured by
.Dv IFF_LINK1 .
.\"
.Ss Bidirectional and multi-destination mode
Usually,
.Nm
implements bidirectional tunnel.
.Xr gifconfig 8
should configure a tunnel ingress point
.Pq this node
and an egress point
.Pq tunnel endpoint ,
and
one
.Nm
interface will tunnel to only a single tunnel endpoint,
and accept from only a single tunnel endpoint.
Source and destination address for outer IP header is always the
ingress and the egress point configued by
.Xr gifconfig 8 .
.Pp
With
.Dv IFF_LINK0
interface flag,
.Nm
can be configured to implement multi-destination tunnel.
With
.Dv IFF_LINK0 ,
it is able to configure egress point to IPv4 wildcard address
.Pq Nm 0.0.0.0
or IPv6 unspecified address
.Pq Nm 0::0 .
In this case, destination address for the outer IP header is
determined based on the routing table setup.
Therefore, one
.Nm
interface can tunnel to multiple destinations.
Also,
.Nm
will accept tunneled traffic from any outer source address.
.Pp
When finding a
.Nm gif
interface from the inbound tunneled traffic,
bidirectional mode interface is preferred than multi-destination mode interface.
For example, if you have the following three
.Nm
interfaces on node A, tunneled traffic from C to A will match the second
.Nm
interface, not the third one.
.Bl -bullet -compact -offset indent
.It
bidirectional, A to B
.It
bidirectional, A to C
.It
multi-destination, A to any
.El
.Pp
Please note that multi-destination mode is far less secure
than bidirectional mode.
Multi-destination mode
.Nm
can accept tunneled packet from anybody,
and can be attacked from a malicious node.
.Pp
.Ss ECN friendly behavior
.Nm
can be configured to be ECN friendly, as described in
.Dv draft-ipsec-ecn-00.txt .
This is turned off by default, and can be turned on by
.Dv IFF_LINK1
interface flag.
.Pp
Without
.Dv IFF_LINK1 ,
.Nm
will show a normal behavior, like described in RFC1933.
This can be summarized as follows:
.Bl -tag -width "Ingress" -offset indent
.It Ingress
Set outer TOS bit to
.Dv 0 .
.It Egress
Drop outer TOS bit.
.El
.Pp
With
.Dv IFF_LINK1 ,
.Nm
will copy ECN bits
.Po
.Dv 0x02
and
.Dv 0x01
on IPv4 TOS byte or IPv6 traffic class byte
.Pc
on egress and ingress, as follows:
.Bl -tag -width "Ingress" -offset indent
.It Ingress
Copy TOS bits except for ECN CE
.Po
masked with
.Dv 0xfe
.Pc
from
inner to outer.
set ECN CE bit to
.Dv 0 .
.It Egress
Use inner TOS bits with some change.
If outer ECN CE bit is
.Dv 1 ,
enable ECN CE bit on the inner.
.El
.Pp
Note that the ECN friendly behavior violates RFC1933.
This should be used in mutual agreement with the tunnel endpoint.
.Pp
.Ss Backward compatibility
.Nm
interface will capture packets toward IPv4-in-IPv4 tunnel,
which has been used by
.Xr vif 4
multicast tunnel device
.Pq used in MBone community .
For compatibility, IPv4-in-IPv4 traffic will be matched to
.Nm
interfaces first, and then sent to
.Xr vif 4
if no match is found.
.\"
.Sh SEE ALSO
.Xr inet 4 ,
.Xr inet6 4 ,
.Xr vif 4 ,
.Xr gifconfig 8 ,
RFC1933
.Rs
.%A Sally Floyd
.%A David L. Black
.%A K. K. Ramakrishnan
.%T "IPsec Interactions with ECN"
.%D February 1999
.%O http://www.aciri.org/floyd/papers/draft-ipsec-ecn-00.txt
.Re
.\"
.Sh HISTORY
The
.Nm
device first appeared in WIDE hydrangea IPv6 kit.

287
share/man/man4/inet6.4 Normal file
View File

@ -0,0 +1,287 @@
.\" 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.
.\"
.\" $Id: inet6.4,v 1.1.1.1 1999/08/08 23:30:37 itojun Exp $
.\" $FreeBSD$
.\"
.Dd January 29, 1999
.Dt INET6 4
.Os KAME
.Sh NAME
.Nm inet6
.Nd Internet protocol version 6 family
.Sh SYNOPSIS
.Fd #include <sys/types.h>
.Fd #include <netinet/in.h>
.Sh DESCRIPTION
The
.Nm
family is an updated version of
.Xr inet 4
family.
While
.Xr inet 4
implements Internet Protocol version 4,
.Nm
implements Internet Protocol version 6.
.Pp
.Nm
is a collection of protocols layered atop the
.Em Internet Protocol version 6
.Pq Tn IPv6
transport layer, and utilizing the IPv6 address format.
The
.Nm
family provides protocol support for the
.Dv SOCK_STREAM , SOCK_DGRAM ,
and
.Dv SOCK_RAW
socket types; the
.Dv SOCK_RAW
interface provides access to the
.Tn IPv6
protocol.
.Sh ADDRESSING
IPv6 addresses are 16 byte quantities, stored in network standard format
The include file
.Aq Pa netinet/in.h
defines this address
as a discriminated union.
.Pp
Sockets bound to the
.Nm
family utilize the following addressing structure,
.Bd -literal -offset indent
struct sockaddr_in6 {
u_char sin6_len;
u_char sin6_family;
u_int16_t sin6_port;
u_int32_t sin6_flowinfo;
struct in6_addr sin6_addr;
u_int32_t sin6_scope_id;
};
.Ed
.Pp
Sockets may be created with the local address
.Dq Dv ::
.Po
which is equal to IPv6 address
.Dv 0:0:0:0:0:0:0:0
.Pc
to effect
.Dq wildcard
matching on incoming messages.
The address in a
.Xr connect 2
or
.Xr sendto 2
call may be given as
.Dq Dv ::
to mean
.Dq this host .
.Dq Dv ::
can be obtained by setting
.Dv sin6_addr
field into 0, or by using the address contained in variable
.Dv in6addr_any .
.Pp
IPv6 defines scoped address such as link-local or site-local address.
To manipulate link-local addresses properly from the userland,
programs must use advanced API defined in RFC2292.
Otherwise, the address is ambiguous to the kernel and error will be generated.
Scoped address is not for daily use at this moment both from specification
and implementation point of view.
Most of normal userland program
like
.Xr telnet 1
or
.Xr telnetd 8
cannot handle scoped address properly.
Only special programs,
like
.Xr ping6 8 ,
supports scoped address.
For example,
.Xr ping6 8
has special option for specifying outgoing interface
to disambiguate scoped addresses.
.Pp
Scoped addresses are handled specially in the kernel.
Scoped addresses will have its interface index embedded into the address,
in routing table or interface structure.
Therefore,
the address on some of the kernel structure is not the same as that on the wire.
The embedded index will be visible on
.Dv PF_ROUTE
socket and results from
.Xr ifconfig 8 ,
HOWEVER, users should never use the embedded form.
For details please consult
.Pa IMPLEMENTATION
supplied with KAME kit.
.Sh PROTOCOLS
The
.Nm
family is comprised of the
.Tn IPv6
network protocol, Internet Control
Message Protocol version 6
.Pq Tn ICMPv6 ,
Transmission Control Protocol
.Pq Tn TCP ,
and User Datagram Protocol
.Pq Tn UDP .
.Tn TCP
is used to support the
.Dv SOCK_STREAM
abstraction while
.Tn UDP
is used to support the
.Dv SOCK_DGRAM
abstraction.
Note that
.Tn TCP
and
.Tn UDP
are common to
.Xr inet 4
and
.Nm inet6 .
A raw interface to
.Tn IPv6
is available
by creating an Internet socket of type
.Dv SOCK_RAW .
The
.Tn ICMPv6
message protocol is accessible from a raw socket.
.\" .Pp
.\" The 128-bit IPv6 address contains both network and host parts.
.\" However, direct examination of addresses is discouraged.
.\" For those programs which absolutely need to break addresses
.\" into their component parts, the following
.\" .Xr ioctl 2
.\" commands are provided for a datagram socket in the
.\" .Nm
.\" domain; they have the same form as the
.\" .Dv SIOCIFADDR
.\" command (see
.\" .Xr intro 4 ) .
.\" .Pp
.\" .Bl -tag -width SIOCSIFNETMASK
.\" .It Dv SIOCSIFNETMASK
.\" Set interface network mask.
.\" The network mask defines the network part of the address;
.\" if it contains more of the address than the address type would indicate,
.\" then subnets are in use.
.\" .It Dv SIOCGIFNETMASK
.\" Get interface network mask.
.\" .El
.\" .Sh ROUTING
.\" The current implementation of Internet protocols includes some routing-table
.\" adaptations to provide enhanced caching of certain end-to-end
.\" information necessary for Transaction TCP and Path MTU Discovery. The
.\" following changes are the most significant:
.\" .Bl -enum
.\" .It
.\" All IP routes, except those with the
.\" .Dv RTF_CLONING
.\" flag and those to multicast destinations, have the
.\" .Dv RTF_PRCLONING
.\" flag forcibly enabled (they are thus said to be
.\" .Dq "protocol cloning" ).
.\" .It
.\" When the last reference to an IP route is dropped, the route is
.\" examined to determine if it was created by cloning such a route. If
.\" this is the case, the
.\" .Dv RTF_PROTO3
.\" flag is turned on, and the expiration timer is initialized to go off
.\" in net.inet.ip.rtexpire seconds. If such a route is re-referenced,
.\" the flag and expiration timer are reset.
.\" .It
.\" A kernel timeout runs once every ten minutes, or sooner if there are
.\" soon-to-expire routes in the kernel routing table, and deletes the
.\" expired routes.
.\" .El
.\" .Pp
.\" A dynamic process is in place to modify the value of
.\" net.inet.ip.rtexpire if the number of cached routes grows too large.
.\" If after an expiration run there are still more than
.\" net.inet.ip.rtmaxcache unreferenced routes remaining, the rtexpire
.\" value is multiplied by 3/4, and any routes which have longer
.\" expiration times have those times adjusted. This process is damped
.\" somewhat by specification of a minimum rtexpire value
.\" (net.inet.ip.rtminexpire), and by restricting the reduction to once in
.\" a ten-minute period.
.\" .Pp
.\" If some external process deletes the original route from which a
.\" protocol-cloned route was generated, the ``child route'' is deleted.
.\" (This is actually a generic mechanism in the routing code support for
.\" protocol-requested cloning.)
.\" .Pp
.\" No attempt is made to manage routes which were not created by protocol
.\" cloning; these are assumed to be static, under the management of an
.\" external routing process, or under the management of a link layer
.\" (e.g.,
.\" .Tn ARP
.\" for Ethernets).
.\" .Pp
.\" Only certain types of network activity will result in the cloning of a
.\" route using this mechanism. Specifically, those protocols (such as
.\" .Tn TCP
.\" and
.\" .Tn UDP )
.\" which themselves cache a long-lasting reference to route for a destination
.\" will trigger the mechanism; whereas raw
.\" .Tn IP
.\" packets, whether locally-generated or forwarded, will not.
.Sh SEE ALSO
.Xr ioctl 2 ,
.Xr socket 2 ,
.Xr sysctl 3 ,
.Xr icmp6 4 ,
.Xr intro 4 ,
.\" .Xr ip6 4 ,
.Xr tcp 4 ,
.Xr ttcp 4 ,
.Xr udp 4
.Sh CAVEAT
The IPv6 support is subject to change as the Internet protocols develop.
Users should not depend on details of the current implementation,
but rather the services exported.
.Pp
Users are suggested to implement
.Dq version independent
code as much as possible, as you will need to support both
.Xr inet 4
and
.Nm inet6 .
.Sh HISTORY
The
.Nm
protocol interface are defined in RFC2553 and RFC2292.
The implementation described herein appeared in WIDE/KAME project.

228
share/man/man4/ipsec.4 Normal file
View File

@ -0,0 +1,228 @@
.\" 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.
.\"
.\" $Id: ipsec.4,v 1.2 1999/10/07 03:55:08 itojun Exp $
.\" $FreeBSD$
.\"
.Dd January 29, 1999
.Dt IPSEC 4
.Os KAME
.Sh NAME
.Nm ipsec
.Nd IP security protocol
.Sh SYNOPSIS
.Fd #include <sys/types.h>
.Fd #include <netinet/in.h>
.Fd #include <netinet6/ipsec.h>
.Sh DESCRIPTION
.Nm
is a security protocol in Internet Protocol layer.
.Nm
is defined for both IPv4 and IPv6
.Po
.Xr inet 4
and
.Xr inet6 4
.Pc .
.Nm
consists of two sub-protocols, namely
ESP
.Pq encapsulated security payload
and AH
.Pq authentication header .
ESP protects IP payload from wire-tapping by encrypting it by
secret key cryptography algorithms.
AH guarantees integrity of IP packet
and protects it from intermediate alteration or impersonation,
by attaching cryptographic checksum computed by one-way hash functions.
.Nm
has two operation modes: transport mode and tunnel mode.
Transport mode is for protecting peer-to-peer commuication between end nodes.
Tunnel mode includes IP-in-IP encapsulation operation
and is designed for security gateways, like VPN configurations.
.\"
.Sh KERNEL INTERFACE
.Nm
is controlled by key management engine, and policy engine in the
operating system kernel.
.Pp
Key management engine can be accessed from the userland by using
.Dv PF_KEY
sockets.
The
.Dv PF_KEY
socket API is defined in RFC2367.
.Pp
Policy engine can be controlled by extended part of
.Dv PF_KEY
API,
.Xr setsockopt 2
operations, and
.Xr sysctl 3
interface.
The kernel implements
extended version of
.Dv PF_KEY
interface, and allows you to define IPsec policy like per-packet filters.
.Xr setsockopt 2
interface is used to define per-socket behavior, and
.Xr sysctl 3
interface is used to define host-wide default behavior.
.Pp
The kernel code does not implement dynamic encryption key exchange protocol
like IKE
.Pq Internet Key Exchange .
That should be implemented as userland programs
.Pq usually as daemons ,
by using the above described APIs.
.\"
.Sh POLICY MANAGEMENT
The kernel implements experimental policy management code.
You can manage the IPsec policy in two ways.
One is to configure per-socket policy using
.Xr setsockopt 3 .
The other is to configure kernel packet filter-based policy using
.Dv PF_KEY
interface, via
.Xr setkey 8 .
In both cases, IPsec policy must be specified with syntax described in
.Xr ipsec_set_policy 3 .
.Pp
With
.Xr setsockopt 3 ,
you can define IPsec policy in per-socket basis.
You can enforce particular IPsec policy onto packets that go through
particular socket.
.Pp
With
.Xr setkey 8
you can define IPsec policy against packets,
using sort of packet filtering rule.
Refer to
.Xr setkey 8
on how to use it.
.Pp
In the latter case,
.Dq Li default
policy is allowed for use with
.Xr setkey 8 .
By configuring policy to
.Li default ,
you can refer system-wide
.Xr sysctl 8
variable for default settings.
The following variables are available.
.Li 1
means
.Dq Li use ,
and
.Li 2
means
.Dq Li require
in the syntax.
.Bl -column net.inet6.ipsec6.esp_trans_deflev integerxxx
.It Sy Name Type Changeable
.It net.inet.ipsec.esp_trans_deflev integer yes
.It net.inet.ipsec.esp_net_deflev integer yes
.It net.inet.ipsec.ah_trans_deflev integer yes
.It net.inet.ipsec.ah_net_deflev integer yes
.It net.inet6.ipsec6.esp_trans_deflev integer yes
.It net.inet6.ipsec6.esp_net_deflev integer yes
.It net.inet6.ipsec6.ah_trans_deflev integer yes
.It net.inet6.ipsec6.ah_net_deflev integer yes
.El
.Pp
If kernel finds no matching policy system wide default value is applied.
System wide default is specified by the following
.Xr sysctl 8
variables.
.Li 0
means
.Dq Li discard
which asks the kernel to drop the packet.
.Li 1
means
.Dq Li none .
.Bl -column net.inet6.ipsec6.def_policy integerxxx
.It Sy Name Type Changeable
.It net.inet.ipsec.def_policy integer yes
.It net.inet6.ipsec6.def_policy integer yes
.El
.\"
.Sh PROTOCOLS
The
.Nm
protocol works like plug-in to
.Xr inet 4
and
.Xr inet6 4
protocols.
Therefore,
.Nm
supports most of the protocols defined upon those IP-layer protocols.
Some of the protocols, like
.Xr icmp 4
or
.Xr icmp6 4 ,
may behave differently with
.Nm ipsec .
This is because
.Nm
can prevent
.Xr icmp 4
or
.Xr icmp6 4
routines from looking into IP payload.
.\"
.Sh SEE ALSO
.Xr ioctl 2 ,
.Xr socket 2 ,
.Xr ipsec_set_policy 3 ,
.Xr icmp6 4 ,
.Xr intro 4 ,
.Xr ip6 4 ,
.Xr setkey 8 ,
.Xr sysctl 8 ,
.Xr racoon 8 .
.Pp
.Rs
.%T RFC2367
.Re
.Rs
.%A "D. L. McDonald"
.%T "A Simple IP Security API Extension to BSD Sockets"
.%N "draft-mcdonald-simple-ipsec-api-03.txt"
.%O "internet draft"
.Re
.Sh CAVEAT
The IPsec support is subject to change as the IPsec protocols develop.
.Pp
There is no single standard for policy engine API,
so the policy engine API described herein is just for KAME implementation.
.\"
.Sh HISTORY
The implementation described herein appeared in WIDE/KAME IPv6/IPsec stack.

217
share/man/man4/kame.4 Normal file
View File

@ -0,0 +1,217 @@
.\" 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: kame.4,v 1.4 1999/10/07 04:01:15 itojun Exp $
.\" $FreeBSD$
.\"
.Dd April 13, 1999
.Dt KAME 4
.Os KAME
.\"
.Sh NAME
.Nm KAME
.Nd introduction and roadmap to KAME IPv6 software package
.\"
.Sh DESCRIPTION
.Nm KAME
software package is a result of joint work of several IPv6 researchers
in Japan, to provide reference implementation of IPv6 to
Berkeley Software Distribution
.Pq BSD
derived system such as BSD/OS,
FreeBSD, NetBSD and OpenBSD
.Pq in alphabetical order .
.Pp
.\" Package consists of set of patches and additions to kernel,
.\" modification to application, daemons, header files and libraries.
KAME kit consists of IPv6/IPsec-ready kernel, application, daemons,
header files and libraries.
.\"
.Sh HIGHLIGHTS
Following are some of highlights of this implementation.
.\"
.Ss Kernel
IPv6 and IPsec protocol stacks are implemented and available.
See below for conformance to standards and/or internet drafts.
.\"
.Ss Plug and Play and protocol stack/interface configuration
.Xr ndp 8 ,
.Xr prefix 8 ,
.Xr rrenumd 8 ,
.Xr rtadvd 8 ,
.Xr rtsol 8 ,
.Xr rtsold 8 .
.\"
.Ss Routing
.Xr bgpd 8 ,
.Xr hroute6d 8 ,
.Xr rip6admin 8 ,
.Xr rip6query 8 ,
.Xr route6d 8 .
.\"
.Ss Multicast (includes routing and utilities)
.Xr mcastread 1 ,
.Xr mcastsend 1 ,
.Xr mchat 1 ,
.Xr ifmcstat 8 ,
.Xr mld6query 8 ,
.Xr pim6dd 8 ,
.Xr pim6sd 8 ,
.Xr pim6stat 8 .
.\"
.Ss Transition Tools
Two IPv4 to IPv6 transition tools are available.
TCP relay translator, FAITH
.Po
.Xr faithd 8
.Pc .
and SIIT IPv6-to-v4 header translator implementation
.Po
.Xr ptrconfig 8
.Pc .
.\"
.Ss IPsec and tunnelling
.Xr gifconfig 8 ,
.Xr ipsec 4 ,
.Xr dtcpc 8 ,
.Xr dtcps 8 ,
.Xr racoon 8 ,
.Xr setkey 8 .
.Pp
Dozen of existing tools are modified for IPsec support, like
.Xr ping 8 .
.\"
.Ss Utilities/Diagnosis
.Xr cksum6 1 ,
.Xr v6test 1 ,
.Xr icmp6dump 8 ,
.Xr ping6 8 ,
.Xr traceroute6 8 ,
.Xr v6p 8 .
.Pp
Dozen of existing utilities are modified for IPv6/IPsec support, like
.Xr ftp 1
and/or
.Xr telnet 1 .
.\"
.Ss Application Daemons
.Xr inetd 8
modified for IPv4/v6 support, or
IPv6-only
.Xr inet6d 8
is supplied.
.Pp
Dozen of existing daemons are modified for IPv6/IPsec support, like
.Xr ftpd 8
and/or
.Xr telnetd 8 .
.\"
.Ss Miscellaneous
SuMiRe IPv4 NAT
.Po
.Xr pma 8
.Pc
is available in addition to OS-supplied IPv4 NAT.
.\"
.Sh DOCUMENTATION
Although some of documentations have not modified yet, program itself
may be heavily modified.
Following lists are not complete, but give you some idea what kind of
new software modules are available, or, modifications are made.
Please refer to each manual page for detail.
Manpages are installed into
.Pa /usr/local/v6/man
so you may want to add the pathname to
.Dv MANPATH .
.\"
.Ss Installation and basic usage documentations
Please read following files in directory
.Pa /usr/local/v6/share/doc/kame
to get basic idea and installation methods on
.Nm KAME :
.Pa README ,
.Pa RELNOTES ,
.Pa USAGE
and
.Pa IMPLEMENTATION .
Also check latest status of project at web page:
.Pa http://www.kame.net/ .
.Po
Hope you can see a
.Dq Dancing Turtle
.Dv :-)
.Pc
.\"
.Ss APIs introduced or modified
.Xr if_indextoname 3 ,
.Xr getipnodebyname 3 ,
.Xr gethostbyname 3 ,
.Xr rresvport_af 3 ,
.Xr hosts_ctl 3 ,
.Xr ipsec_get_policylen 3 ,
.Xr getnameinfo 3 ,
.Xr freeaddrinfo 3 ,
.Xr getaddrinfo 3 ,
.Xr pcap 3 ,
.Xr getipnodebyaddr 3 ,
.Xr resolver 3 ,
.Xr ipsec_strerror 3 ,
.Xr gai_strerror 3 ,
.Xr hosts_access 3 ,
.Xr request_set 3 ,
.Xr request_init 3 ,
.Xr freehostent 3 ,
.Xr if_nameindex 3 ,
.Xr if_freenameindex 3 ,
.Xr if_nametoindex 3 ,
.Xr ipsec_dump_policy 3 ,
.Xr ipsec_set_policy 3 .
.\"
.Ss Added/modified/renamed features and tools
Please consult the manpages referred above.
.\"
.Sh REFERENCES
To understand
.Nm KAME
protocol stack conformance, please refer
.Pa /usr/local/v6/share/doc/kame/IMPLEMENTATION .
.Pp
Bug reporting form, user mailing list, frequently asked questions list,
latest packages, related software, and more information can be found at
.Pa http://www.kame.net/ .
.\"
.Ss "Related project"
TAHI project who is providing verification technology for IPv6, is
heavily related with KAME project.
You can get current verification
status of KAME software at following THAI project web page:
.Pa http://www.tahi.org/
.\"
.Sh HISTORY
The
.Nm
project started in April 1999.

View File

@ -12,6 +12,6 @@ BINGRP= kmem
BINMODE=2555
DPADD= ${LIBKVM} ${LIBIPX} ${LIBNETGRAPH}
LDADD= -lkvm -lipx -lnetgraph
CFLAGS+=-DINET6
CFLAGS+=-DINET6 -DIPSEC
.include <bsd.prog.mk>

View File

@ -48,6 +48,7 @@ SUBDIR= IPXrouted \
mrouted \
mtest \
mtree \
ndp \
newsyslog \
ngctl \
ntp \
@ -80,10 +81,13 @@ SUBDIR= IPXrouted \
rpc.yppasswdd \
rpc.ypupdated \
rpc.ypxfrd \
rrenumd \
rtadvd \
rtprio \
rtsold \
rwhod \
sa \
setkey \
sliplogin \
slstat \
spray \

25
usr.sbin/ndp/Makefile Normal file
View File

@ -0,0 +1,25 @@
# Copyright (c) 1996 WIDE Project. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modifications, are permitted provided that the above copyright notice
# and this paragraph are duplicated in all such forms and that any
# documentation, advertising materials, and other materials related to
# such distribution and use acknowledge that the software was developed
# by the WIDE Project, Japan. The name of the Project may not be used to
# endorse or promote products derived from this software without
# specific prior written permission. THIS SOFTWARE IS PROVIDED ``AS IS''
# AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
# LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE.
# $FreeBSD$
.PATH: ${.CURDIR}/../../contrib/tcpdump
PROG= ndp
SRCS= ndp.c gmt2local.c
MAN8= ndp.8
CFLAGS+=-DINET6
CFLAGS+=-I. -I${.CURDIR} -I${.CURDIR}/../../contrib/tcpdump
.include <bsd.prog.mk>

2
usr.sbin/ndp/gnuc.h Normal file
View File

@ -0,0 +1,2 @@
/* $FreeBSD$ */
/* this is dummy to pacify gmt2local.c. */

138
usr.sbin/ndp/ndp.8 Normal file
View File

@ -0,0 +1,138 @@
.\" 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.
.\"
.\" $Id: ndp.8,v 1.2 1999/10/07 05:26:13 itojun Exp $
.\" $FreeBSD$
.\"
.Dd May 17, 1998
.Dt NDP 8
.Os KAME
.\"
.Sh NAME
.Nm ndp
.Nd control/diagnose IPv6 neighbor discovery protocol
.\"
.Sh SYNOPSIS
.Nm ndp
.Fl a
.Op Fl ntl
.Nm ndp
.Fl A Ar wait
.Op Fl ntl
.Nm ndp
.Fl c
.Op Fl nt
.Nm ndp
.Fl d
.Op Fl nt
.Ar hostname
.Nm ndp
.Fl f
.Op Fl nt
.Ar filename
.Nm ndp
.Fl H
.Nm ndp
.Fl i
.Ar interface
.Nm ndp
.Fl p
.Nm ndp
.Fl P
.Nm ndp
.Fl r
.Nm ndp
.Fl R
.Nm ndp
.Fl s
.Op Fl nt
.Ar nodename
.Ar ether_addr
.Op temp
.\"
.Sh DESCRIPTION
.Nm
command manipulates the address mapping table
used by Neighbor Discovery Protocol (NDP).
.Bl -tag -width Ds
.It Fl a
Dump the currently existing NDP entries.
.It Fl A Ar wait
Repeat
.Fl a
.Pq dump NDP entries
every
.Ar wait
seconds.
.It Fl c
Erase all the NDP entries.
.It Fl d
Delete specified NDP entry.
.It Fl f
Parse the file specified by
.Ar filename .
.It Fl H
Harmonize consistency between the routing table and the default router
list; install the top entry of the list into the kernel routing table.
.It Fl i
view ND information for specified interface.
.It Fl l
Do not truncate numeric IPv6 address.
.It Fl n
Do not try to resolve numeric address to hostname.
.It Fl p
Show prefix list.
.It Fl P
Flush all the entries in the prefix list.
.It Fl r
Show default router list.
.It Fl R
Flush all the entries in the default router list.
.It Fl s
Register a NDP entry for a node.
.It Fl t
Print timestamp on each entries,
to make it possible to merge output with
.Xr tcpdump 1 .
Most useful when used with
.Fl A .
.El
.\"
.Sh RETURN VALUES
.Nm Ndp
will exit with 0 on success, and non-zero on errors.
.\"
.Sh SEE ALSO
.Xr arp 8
.\"
.Sh HISTORY
The
.Nm
command first appeared in WIDE Hydrangea IPv6 protocol stack kit.
.\"
.\" .Sh BUGS
.\" (to be written)

1028
usr.sbin/ndp/ndp.c Normal file

File diff suppressed because it is too large Load Diff

41
usr.sbin/rrenumd/Makefile Normal file
View File

@ -0,0 +1,41 @@
# Copyright (c) 1996 WIDE Project. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modifications, are permitted provided that the above copyright notice
# and this paragraph are duplicated in all such forms and that any
# documentation, advertising materials, and other materials related to
# such distribution and use acknowledge that the software was developed
# by the WIDE Project, Japan. The name of the Project may not be used to
# endorse or promote products derived from this software without
# specific prior written permission. THIS SOFTWARE IS PROVIDED ``AS IS''
# AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
# LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE.
# $FreeBSD$
PROG= rrenumd
SRCS= rrenumd.c parser.y lexer.l
YFLAGS+= -d
CC= gcc
CFLAGS+= -DINET6 -DIPSEC -I${.OBJDIR}
LDADD+= -lipsec -lcompat
DPADD+= ${LIBIPSEC} ${LIBCOMPAT}
LDADD+= -ll -ly
DPADD+= ${LIBL} ${LIBY}
MAN5= rrenumd.conf.5
MAN8= rrenumd.8
SRCS+=y.tab.h
y.tab.h: parser.y
.if defined(YACCDEBUG)
CFLAGS+= -DYYDEBUG
YFLAGS+= -t -v
.endif
.include <bsd.prog.mk>
CLEANFILES+= y.tab.h

248
usr.sbin/rrenumd/lexer.l Normal file
View File

@ -0,0 +1,248 @@
/*
* 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.
*
* $FreeBSD$
*/
%{
#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <string.h>
#include <net/if.h>
#include <net/if_var.h>
#include <netinet/in.h>
#include <netinet/in_var.h>
#include <netinet/icmp6.h>
#include "y.tab.h"
int lineno = 1;
#define LINEBUF_SIZE 1000
char linebuf[LINEBUF_SIZE];
%}
/* common section */
nl \n
ws [ \t]+
digit [0-9]
letter [0-9A-Za-z]
hexdigit [0-9A-Fa-f]
special [()+\|\?\*,]
dot \.
hyphen \-
colon \:
slash \/
bcl \{
ecl \}
semi \;
usec {dot}{digit}{1,6}
comment \#.*
qstring \"[^"]*\"
decstring {digit}+
hexpair {hexdigit}{hexdigit}
hexstring 0[xX]{hexdigit}+
octetstring {octet}({dot}{octet})+
ipv4addr {digit}{1,3}({dot}{digit}{1,3}){0,3}
ipv6addr {hexdigit}{0,4}({colon}{hexdigit}{0,4}){2,7}
ipaddrmask {slash}{digit}{1,3}
keyword {letter}{letter}+
name {letter}(({letter}|{digit}|{hyphen})*({letter}|{digit}))*
hostname {name}(({dot}{name})+{dot}?)?
timeval {digit}{0,2}
days d{timeval}
hours h{timeval}
minutes m{timeval}
seconds s{timeval}
mprefix match_prefix|match-prefix
uprefix use_prefix|use-prefix
%%
/* rrenumd keywords */
debug {
return(DEBUG_CMD);
}
dest {
return(DEST_CMD);
}
retry {
return(RETRY_CMD);
}
seqnum {
return(SEQNUM_CMD);
}
add {
yylval.num = RPM_PCO_ADD;
return(ADD);
}
change {
yylval.num = RPM_PCO_CHANGE;
return(CHANGE);
}
setglobal {
yylval.num = RPM_PCO_SETGLOBAL;
return(SETGLOBAL);
}
{mprefix} {
return(MATCH_PREFIX_CMD);
}
maxlen {
return(MAXLEN_CMD);
}
minlen {
return(MINLEN_CMD);
}
{uprefix} {
return(USE_PREFIX_CMD);
}
keeplen {
return(KEEPLEN_CMD);
}
vltime {
return(VLTIME_CMD);
}
pltime {
return(PLTIME_CMD);
}
raf_onlink {
return(RAF_ONLINK_CMD);
}
raf_auto {
return(RAF_AUTO_CMD);
}
rrf_decrvalid {
return(RAF_DECRVALID_CMD);
}
rrf_decrprefd {
return(RAF_DECRPREFD_CMD);
}
{days} {
yytext++;
yylval.num = atoi(yytext);
return(DAYS);
}
{hours} {
yytext++;
yylval.num = atoi(yytext);
return(HOURS);
}
{minutes} {
yytext++;
yylval.num = atoi(yytext);
return(MINUTES);
}
{seconds} {
yytext++;
yylval.num = atoi(yytext);
return(SECONDS);
}
infinity {
return(INFINITY);
}
on {
yylval.num = 1;
return(ON);
}
off {
yylval.num = 0;
return(OFF);
}
/* basic rules */
{ws} ;
{nl} {
lineno++;
}
{semi} {
return EOS;
}
{bcl} {
return BCL;
}
{ecl} {
return ECL;
}
{qstring} {
yylval.cs.cp = yytext;
yylval.cs.len = yyleng;
return QSTRING;
}
{decstring} {
yylval.cs.cp = yytext;
yylval.cs.len = yyleng;
return DECSTRING;
}
{name} {
yylval.cs.cp = yytext;
yylval.cs.len = yyleng;
return NAME;
}
{ipv6addr} {
memset(&yylval.addr6, 0, sizeof(struct in6_addr));
if (inet_pton(AF_INET6, yytext,
&yylval.addr6) == 1) {
return IPV6ADDR;
} else {
return ERROR;
}
}
{ipaddrmask} {
yytext++;
yylval.num = atoi(yytext);
return(PREFIXLEN);
}
{hostname} {
yylval.cs.cp = yytext;
yylval.cs.len = yyleng;
return HOSTNAME;
}
%%
int parse(FILE **fp)
{
yyin = *fp;
if(yyparse())
return(-1);
return(0);
}
void
yyerror(const char *s)
{
printf("%s: at %s in line %d\n", s, yytext, lineno);
}

637
usr.sbin/rrenumd/parser.y Normal file
View File

@ -0,0 +1,637 @@
/*
* 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.
*
* $FreeBSD$
*/
%{
#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/uio.h>
#include <net/if.h>
#include <net/if_var.h>
#include <netinet/in.h>
#include <netinet/in_var.h>
#include <netinet/icmp6.h>
#include <netdb.h>
#include <string.h>
#include "rrenumd.h"
struct config_is_set {
u_short cis_dest : 1;
} cis;
struct dst_list *dl_head;
struct payload_list *pl_head, ple_cur;
u_int retry;
char errbuf[LINE_MAX];
extern int lineno;
extern void yyerror __P((const char *s));
static struct payload_list * pllist_lookup __P((int seqnum));
static void pllist_enqueue __P((struct payload_list *pl_entry));
#define MAX_RETRYNUM 10 /* upper limit of retry in this rrenumd program */
#define MAX_SEQNUM 256 /* upper limit of seqnum in this rrenumd program */
#define NOSPEC -1
%}
%union {
u_long num;
struct {
char *cp;
int len;
} cs;
struct in_addr addr4;
struct in6_addr addr6;
struct {
struct in6_addr addr;
u_char plen;
} prefix;
struct dst_list *dl;
struct payload_list *pl;
struct sockaddr *sa;
}
%token <num> ADD CHANGE SETGLOBAL
%token DEBUG_CMD DEST_CMD RETRY_CMD SEQNUM_CMD
%token MATCH_PREFIX_CMD MAXLEN_CMD MINLEN_CMD
%token USE_PREFIX_CMD KEEPLEN_CMD
%token VLTIME_CMD PLTIME_CMD
%token RAF_ONLINK_CMD RAF_AUTO_CMD RAF_DECRVALID_CMD RAF_DECRPREFD_CMD
%token <num> DAYS HOURS MINUTES SECONDS INFINITY
%token <num> ON OFF
%token BCL ECL EOS ERROR
%token <cs> NAME HOSTNAME QSTRING DECSTRING
%token <addr4> IPV4ADDR
%token <addr6> IPV6ADDR
%token <num> PREFIXLEN
%type <num> retrynum seqnum rrenum_cmd
%type <num> prefixlen maxlen minlen keeplen vltime pltime
%type <num> lifetime days hours minutes seconds
%type <num> decstring
%type <num> raf_onlink raf_auto raf_decrvalid raf_decrprefd flag
%type <dl> dest_addrs dest_addr sin6
%type <pl> rrenum_statement
%type <cs> ifname
%type <prefix> prefixval
%%
config:
/* empty */
| statements
;
statements:
statement
| statements statement
;
statement:
debug_statement
| destination_statement
| rrenum_statement_without_seqnum
| rrenum_statement_with_seqnum
| error EOS
{
yyerrok;
}
| EOS
;
debug_statement:
DEBUG_CMD flag EOS
{
#ifdef YYDEBUG
yydebug = $2;
#endif /* YYDEBUG */
}
;
destination_statement:
DEST_CMD dest_addrs retrynum EOS
{
dl_head = $2;
retry = $3;
}
;
dest_addrs:
dest_addr
| dest_addrs dest_addr
{
$2->dl_next = $1;
$$ = $2;
}
;
dest_addr :
sin6
{
with_v6dest = 1;
}
| sin6 ifname
{
struct sockaddr_in6 *sin6;
sin6 = (struct sockaddr_in6 *)$1->dl_dst;
sin6->sin6_scope_id = if_nametoindex($2.cp);
with_v6dest = 1;
$$ = $1;
}
| HOSTNAME
{
struct sockaddr_storage *ss;
struct addrinfo hints, *res;
int error;
memset(&hints, 0, sizeof(hints));
hints.ai_flags = AI_CANONNAME;
hints.ai_family = AF_INET6;
hints.ai_socktype = SOCK_RAW;
hints.ai_protocol = 0;
error = getaddrinfo($1.cp, 0, &hints, &res);
if (error) {
sprintf(errbuf, "name resolution failed for %s"
":%s", $1, gai_strerror(error));
yyerror(errbuf);
}
ss = (struct sockaddr_storage *)malloc(sizeof(*ss));
memset(ss, 0, sizeof(*ss));
memcpy(ss, res->ai_addr, res->ai_addr->sa_len);
freeaddrinfo(res);
$$ = (struct dst_list *)
malloc(sizeof(struct dst_list));
memset($$, 0, sizeof(struct dst_list));
$$->dl_dst = (struct sockaddr *)ss;
}
;
sin6:
IPV6ADDR
{
struct sockaddr_in6 *sin6;
sin6 = (struct sockaddr_in6 *)malloc(sizeof(*sin6));
memset(sin6, 0, sizeof(*sin6));
sin6->sin6_len = sizeof(*sin6);
sin6->sin6_family = AF_INET6;
sin6->sin6_addr = $1;
$$ = (struct dst_list *)
malloc(sizeof(struct dst_list));
memset($$, 0, sizeof(struct dst_list));
$$->dl_dst = (struct sockaddr *)sin6;
}
ifname:
NAME
{
$$.cp = strdup($1.cp);
$$.len = $1.len;
}
| QSTRING
{
$1.cp[$1.len - 1] = 0;
$$.cp = strdup(&$1.cp[1]);
$$.len = $1.len - 2;
}
;
retrynum:
/* empty */
{
$$ = 2;
}
| RETRY_CMD decstring
{
if ($2 > MAX_RETRYNUM)
$2 = MAX_RETRYNUM;
$$ = $2;
}
;
rrenum_statement_with_seqnum:
SEQNUM_CMD seqnum
{
if (pllist_lookup($2)) {
sprintf(errbuf, "duplicate seqnum %d specified"
" at %d", $2, lineno);
yyerror(errbuf);
}
}
BCL rrenum_statement EOS ECL EOS
{
$5->pl_irr.rr_seqnum = $2;
pllist_enqueue($5);
}
;
seqnum:
/* empty */
{
$$ = 0;
}
| decstring
{
if ($1 > MAX_SEQNUM) {
sprintf(errbuf, "seqnum %d is illegal for this"
" program. should be between 0 and %d",
$1, MAX_SEQNUM);
yyerror(errbuf);
}
$$ = $1;
}
;
rrenum_statement_without_seqnum:
rrenum_statement EOS
{
if (pllist_lookup(0)) {
sprintf(errbuf, "duplicate seqnum %d specified"
" at %d", 0, lineno);
yyerror(errbuf);
}
$1->pl_irr.rr_seqnum = 0;
pllist_enqueue($1);
}
;
rrenum_statement:
match_prefix_definition use_prefix_definition
{
$$ = (struct payload_list *)
malloc(sizeof(struct payload_list));
memcpy($$, &ple_cur, sizeof(ple_cur));
}
;
match_prefix_definition:
rrenum_cmd MATCH_PREFIX_CMD prefixval maxlen minlen
{
struct icmp6_router_renum *irr;
struct rr_pco_match *rpm;
irr = (struct icmp6_router_renum *)&ple_cur.pl_irr;
rpm = (struct rr_pco_match *)(irr + 1);
memset(rpm, 0, sizeof(*rpm));
rpm->rpm_code = $1;
rpm->rpm_prefix = $3.addr;
rpm->rpm_matchlen = $3.plen;
rpm->rpm_maxlen = $4;
rpm->rpm_minlen = $5;
}
;
rrenum_cmd:
/* empty */
{
$$ = RPM_PCO_ADD;
}
| ADD
| CHANGE
| SETGLOBAL
;
prefixval:
IPV6ADDR prefixlen
{
$$.addr = $1;
$$.plen = $2;
}
;
prefixlen:
/* empty */
{
$$ = 64;
}
| PREFIXLEN
;
maxlen:
/* empty */
{
$$ = 128;
}
| MAXLEN_CMD decstring
{
if ($2 > 128)
$2 = 128;
$$ = $2;
}
;
minlen:
/* empty */
{
$$ = 0;
}
| MINLEN_CMD decstring
{
if ($2 > 128)
$2 = 128;
$$ = $2;
}
;
use_prefix_definition:
/* empty */
{
struct icmp6_router_renum *irr;
struct rr_pco_match *rpm;
struct rr_pco_use *rpu;
irr = (struct icmp6_router_renum *)&ple_cur.pl_irr;
rpm = (struct rr_pco_match *)(irr + 1);
rpu = (struct rr_pco_use *)(rpm + 1);
memset(rpu, 0, sizeof(*rpu));
}
| USE_PREFIX_CMD prefixval keeplen use_prefix_values
{
struct icmp6_router_renum *irr;
struct rr_pco_match *rpm;
struct rr_pco_use *rpu;
irr = (struct icmp6_router_renum *)&ple_cur.pl_irr;
rpm = (struct rr_pco_match *)(irr + 1);
rpu = (struct rr_pco_use *)(rpm + 1);
rpu->rpu_prefix = $2.addr;
rpu->rpu_uselen = $2.plen;
rpu->rpu_keeplen = $3;
}
;
use_prefix_values:
/* empty */
{
struct icmp6_router_renum *irr;
struct rr_pco_match *rpm;
struct rr_pco_use *rpu;
irr = (struct icmp6_router_renum *)&ple_cur.pl_irr;
rpm = (struct rr_pco_match *)(irr + 1);
rpu = (struct rr_pco_use *)(rpm + 1);
memset(rpu, 0, sizeof(*rpu));
rpu->rpu_vltime = DEF_VLTIME;
rpu->rpu_pltime = DEF_PLTIME;
rpu->rpu_ramask = 0;
rpu->rpu_flags = 0;
}
| BCL vltime pltime raf_onlink raf_auto raf_decrvalid raf_decrprefd ECL
{
struct icmp6_router_renum *irr;
struct rr_pco_match *rpm;
struct rr_pco_use *rpu;
irr = (struct icmp6_router_renum *)&ple_cur.pl_irr;
rpm = (struct rr_pco_match *)(irr + 1);
rpu = (struct rr_pco_use *)(rpm + 1);
memset(rpu, 0, sizeof(*rpu));
rpu->rpu_vltime = $2;
rpu->rpu_pltime = $3;
if ($4 == NOSPEC)
rpu->rpu_ramask &=
~ICMP6_RR_PCOUSE_RAFLAGS_ONLINK;
else {
rpu->rpu_ramask |=
ICMP6_RR_PCOUSE_RAFLAGS_ONLINK;
if ($4 == ON)
rpu->rpu_raflags |=
ICMP6_RR_PCOUSE_RAFLAGS_ONLINK;
else
rpu->rpu_raflags &=
~ICMP6_RR_PCOUSE_RAFLAGS_ONLINK;
}
if ($5 == NOSPEC)
rpu->rpu_ramask &=
ICMP6_RR_PCOUSE_RAFLAGS_AUTO;
else {
rpu->rpu_ramask |=
ICMP6_RR_PCOUSE_RAFLAGS_AUTO;
if ($5 == ON)
rpu->rpu_raflags |=
ICMP6_RR_PCOUSE_RAFLAGS_AUTO;
else
rpu->rpu_raflags &=
~ICMP6_RR_PCOUSE_RAFLAGS_AUTO;
}
rpu->rpu_flags = 0;
if ($6 == ON)
rpu->rpu_flags |=
ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME;
if ($7 == ON)
rpu->rpu_flags |=
ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME;
}
;
keeplen:
/* empty */
{
$$ = 0;
}
| KEEPLEN_CMD decstring
{
if ($2 > 128)
$2 = 128;
$$ = $2;
}
;
vltime:
/* empty */
{
$$ = DEF_VLTIME;
}
| VLTIME_CMD lifetime
{
$$ = htonl($2);
}
;
pltime:
/* empty */
{
$$ = DEF_PLTIME;
}
| PLTIME_CMD lifetime
{
$$ = htonl($2);
}
raf_onlink:
/* empty */
{
$$ = NOSPEC;
}
| RAF_ONLINK_CMD flag
{
$$ = $2;
}
;
raf_auto:
/* empty */
{
$$ = NOSPEC;
}
| RAF_AUTO_CMD flag
{
$$ = $2;
}
;
raf_decrvalid:
/* empty */
{
$$ = NOSPEC;
}
| RAF_DECRVALID_CMD flag
{
$$ = $2;
}
;
raf_decrprefd:
/* empty */
{
$$ = NOSPEC;
}
| RAF_DECRPREFD_CMD flag
{
$$ = $2;
}
;
flag:
ON
| OFF
;
lifetime:
decstring
| INFINITY
{
$$ = 0xffffffff;
}
| days hours minutes seconds
{
int d, h, m, s;
d = $1 * 24 * 60 * 60;
h = $2 * 60 * 60;
m = $3 * 60;
s = $4;
$$ = d + h + m + s;
}
;
days:
/* empty */
{
$$ = 0;
}
| DAYS
;
hours:
/* empty */
{
$$ = 0;
}
| HOURS
;
minutes:
/* empty */
{
$$ = 0;
}
| MINUTES
;
seconds:
/* empty */
{
$$ = 0;
}
| SECONDS
;
decstring:
DECSTRING
{
int dval;
dval = atoi($1.cp);
$$ = dval;
}
;
%%
static struct payload_list *
pllist_lookup(int seqnum)
{
struct payload_list *pl;
for (pl = pl_head; pl && pl->pl_irr.rr_seqnum != seqnum;
pl = pl->pl_next)
continue;
return (pl);
}
static void
pllist_enqueue(struct payload_list *pl_entry)
{
struct payload_list *pl, *pl_last;
if (pl_head == NULL) {
pl_head = pl_entry;
return;
}
for (pl = pl_head;
pl && pl->pl_irr.rr_seqnum < pl_entry->pl_irr.rr_seqnum;
pl_last = pl, pl = pl->pl_next)
continue;
pl_last->pl_next = pl_entry;
return;
}

View File

@ -0,0 +1,95 @@
.\" 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.
.\"
.\" $Id: rrenumd.8,v 1.1.1.1 1999/08/08 23:31:38 itojun Exp $
.\" $FreeBSD$
.\"
.Dd Sep 7, 1998
.Dt RRENUMD 8
.Os KAME
.Sh NAME
.Nm rrenumd
.Nd router renumbering daemon
.Sh SYNOPSIS
.Nm
.Oo
.Fl c Ar conf_file | Fl s
.Oc
.Op Fl P Ar policy
.Op Fl df
.Sh DESCRIPTION
.Nm Rrenumd
assigns prefixes to subnets inside the site, or renumbers them.
.Pp
The program will daemonize itself on invocation.
It reads configuration information from standard input if
.Fl s
is specified, or from
.Ar conf_file
if
.Fl c Ar conf_file
is specified.
.Pp
The contents of configuration information are described in
.Xr rrenumd.conf 5 .
.Pp
After successful configuration,
.Nm
sends router renumbering
messages periodically to configured destinations.
Messages contain prefixes configured to be renumbered.
.Bl -tag -width indent
.\"
.It Fl d
Debug mode.
.It Fl f
Foreground mode.
Do not become daemon.
.It Fl s
Script mode.
Configuration information is obtained from standard input.
.It Fl P Ar policy
.Ar policy
specifies IPsec policy for the rrenumd session.
For details please refer to
.Xr ipsec 4
and
.Xr ipsec_set_policy 3 .
.It Fl c Ar conf_file
Specify a configuration file where configuration information is kept.
.Sh RETURN VALUES
The program exits with 0 on success, and non-zero on failures.
.El
.Sh SEE ALSO
.Xr daemon 3
.Xr rrenumd.conf 5 ,
.Sh HISTORY
The
.Nm
command first appeared in KAME IPv6 protocol stack kit.
.\" .Sh BUGS
.\" (to be written)

460
usr.sbin/rrenumd/rrenumd.c Normal file
View File

@ -0,0 +1,460 @@
/*
* 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.
*
* $FreeBSD$
*/
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/uio.h>
#include <sys/time.h>
#include <string.h>
#include <net/route.h>
#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip6.h>
#include <netinet/icmp6.h>
#ifdef IPSEC
#include <netinet6/ipsec.h>
#endif
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <syslog.h>
#include "rrenumd.h"
#define LL_ALLROUTERS "ff02::2"
#define SL_ALLROUTERS "ff05::2"
#ifndef IN6_IS_SCOPE_LINKLOCAL
#define IN6_IS_SCOPE_LINKLOCAL(a) \
((IN6_IS_ADDR_LINKLOCAL(a)) || \
(IN6_IS_ADDR_MC_LINKLOCAL(a)))
#endif /* IN6_IS_SCOPE_LINKLOCAL */
struct flags {
u_long debug : 1;
u_long fg : 1;
#ifdef IPSEC
#ifdef IPSEC_POLICY_IPSEC
u_long policy : 1;
#endif /* IPSEC_POLICY_IPSEC */
#endif /*IPSEC*/
};
struct msghdr sndmhdr;
struct msghdr rcvmhdr;
struct sockaddr_in6 from;
struct sockaddr_in6 sin6_ll_allrouters;
int s6;
int with_v6dest;
struct in6_addr prefix; /* ADHOC */
int prefixlen = 64; /* ADHOC */
extern int parse(FILE **fp);
/* Print usage. Don't call this after daemonized. */
static void
show_usage()
{
fprintf(stderr, "usage: rrenumd [-c conf_file|-s] [-df"
#ifdef IPSEC
#ifdef IPSEC_POLICY_IPSEC
"] [-P policy"
#endif /* IPSEC_POLICY_IPSEC */
#endif /* IPSEC */
"]\n");
exit(1);
}
void
init_sin6(struct sockaddr_in6 *sin6, const char *addr_ascii)
{
memset(sin6, 0, sizeof(*sin6));
sin6->sin6_len = sizeof(*sin6);
sin6->sin6_family = AF_INET6;
if (inet_pton(AF_INET6, addr_ascii, &sin6->sin6_addr) != 1)
; /* XXX do something */
}
void
init_globals()
{
static struct iovec rcviov;
static u_char rprdata[4500]; /* maximal MTU of connected links */
static u_char rcvcmsgbuf[CMSG_SPACE(sizeof(struct in6_pktinfo)) +
CMSG_SPACE(sizeof(int))];
static u_char sndcmsgbuf[CMSG_SPACE(sizeof(struct in6_pktinfo)) +
CMSG_SPACE(sizeof(int))];
/* init ll_allrouters */
init_sin6(&sin6_ll_allrouters, LL_ALLROUTERS);
/* initialize msghdr for receiving packets */
rcviov.iov_base = (caddr_t)rprdata;
rcviov.iov_len = sizeof(rprdata);
rcvmhdr.msg_namelen = sizeof(struct sockaddr_in6);
rcvmhdr.msg_iov = &rcviov;
rcvmhdr.msg_iovlen = 1;
rcvmhdr.msg_control = (caddr_t)rcvcmsgbuf;
rcvmhdr.msg_controllen = sizeof(rcvcmsgbuf);
/* initialize msghdr for sending packets */
sndmhdr.msg_namelen = sizeof(struct sockaddr_in6);
sndmhdr.msg_iovlen = 1;
sndmhdr.msg_control = (caddr_t)sndcmsgbuf;
sndmhdr.msg_controllen = sizeof(sndcmsgbuf);
}
void
config(FILE **fpp)
{
struct payload_list *pl;
struct iovec *iov;
struct icmp6_router_renum *irr;
struct rr_pco_match *rpm;
if (parse(fpp) < 0) {
syslog(LOG_ERR, "<%s> parse failed", __FUNCTION__);
exit(1);
}
/* initialize fields not configured by parser */
for (pl = pl_head; pl; pl = pl->pl_next) {
iov = (struct iovec *)&pl->pl_sndiov;
irr = (struct icmp6_router_renum *)&pl->pl_irr;
rpm = (struct rr_pco_match *)&pl->pl_rpm;
irr->rr_type = ICMP6_ROUTER_RENUMBERING;
irr->rr_code = 0;
/*
* now we don't support multiple PCOs in a rr message.
* so segment number is not supported.
*/
/* TODO: rr flags config in parser */
irr->rr_flags |= ICMP6_RR_FLAGS_SPECSITE;
/* TODO: max delay config in parser */
/*
* means only 1 use_prefix is contained as router-renum-05.txt.
* now we don't support multiple PCOs in a rr message,
* nor multiple use_prefix in one PCO.
*/
rpm->rpm_len = 4*1 +3;
rpm->rpm_ordinal = 0;
iov->iov_base = (caddr_t)irr;
iov->iov_len = sizeof(struct icmp6_router_renum)
+ sizeof(struct rr_pco_match)
+ sizeof(struct rr_pco_use);
}
}
void
sock6_open(struct flags *flags
#ifdef IPSEC_POLICY_IPSEC
, char *policy
#endif /* IPSEC_POLICY_IPSEC */
)
{
struct icmp6_filter filt;
int on, optval;
if (with_v6dest == 0)
return;
if (with_v6dest &&
(s6 = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) < 0) {
syslog(LOG_ERR, "<%s> socket(v6): %s", __FUNCTION__,
strerror(errno));
exit(1);
}
/* join all routers multicast addresses, not necessary? */
/* set icmpv6 filter */
ICMP6_FILTER_SETBLOCKALL(&filt);
ICMP6_FILTER_SETPASS(ICMP6_ROUTER_RENUMBERING, &filt);
if (setsockopt(s6, IPPROTO_ICMPV6, ICMP6_FILTER, &filt,
sizeof(filt)) < 0) {
syslog(LOG_ERR, "<%s> IICMP6_FILTER: %s",
__FUNCTION__, strerror(errno));
exit(1);
}
/* specify to tell receiving interface */
on = 1;
if (setsockopt(s6, IPPROTO_IPV6, IPV6_PKTINFO, &on,
sizeof(on)) < 0) {
syslog(LOG_ERR, "<%s> IPV6_PKTINFO: %s",
__FUNCTION__, strerror(errno));
exit(1);
}
#ifdef IPSEC
#ifdef IPSEC_POLICY_IPSEC
if (flags->policy) {
char *buf;
buf = ipsec_set_policy(policy, strlen(policy));
if (buf == NULL)
errx(1, ipsec_strerror());
/* XXX should handle in/out bound policy. */
if (setsockopt(s6, IPPROTO_IPV6, IPV6_IPSEC_POLICY,
buf, ipsec_get_policylen(buf)) < 0)
err(1, NULL);
free(buf);
}
#endif /* IPSEC_POLICY_IPSEC */
#endif /* IPSEC */
return;
}
void
rrenum_output(struct payload_list *pl, struct dst_list *dl)
{
int i, msglen = 0;
struct cmsghdr *cm;
struct in6_pktinfo *pi;
struct icmp6_router_renum *rr;
struct sockaddr_in6 *sin6 = NULL;
sndmhdr.msg_name = (caddr_t)dl->dl_dst;
if (dl->dl_dst->sa_family == AF_INET6)
sin6 = (struct sockaddr_in6 *)dl->dl_dst;
if (sin6 != NULL &&
IN6_IS_SCOPE_LINKLOCAL(&sin6->sin6_addr)) {
int hoplimit = 255;
cm = CMSG_FIRSTHDR(&sndmhdr);
/* specify the outgoing interface */
cm->cmsg_level = IPPROTO_IPV6;
cm->cmsg_type = IPV6_PKTINFO;
cm->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
pi = (struct in6_pktinfo *)CMSG_DATA(cm);
memset(&pi->ipi6_addr, 0, sizeof(pi->ipi6_addr)); /*XXX*/
pi->ipi6_ifindex = sin6->sin6_scope_id;
msglen += CMSG_SPACE(sizeof(struct in6_pktinfo));
/* specify the hop limit of the packet if dest is link local */
/* not defined by router-renum-05.txt, but maybe its OK */
cm = CMSG_NXTHDR(&sndmhdr, cm);
cm->cmsg_level = IPPROTO_IPV6;
cm->cmsg_type = IPV6_HOPLIMIT;
cm->cmsg_len = CMSG_LEN(sizeof(int));
memcpy(CMSG_DATA(cm), &hoplimit, sizeof(int));
msglen += CMSG_SPACE(sizeof(int));
}
sndmhdr.msg_controllen = msglen;
if (sndmhdr.msg_controllen == 0)
sndmhdr.msg_control = 0;
sndmhdr.msg_iov = &pl->pl_sndiov;
i = sendmsg(s6, &sndmhdr, 0);
if (i < 0 || i != sndmhdr.msg_iov->iov_len)
syslog(LOG_ERR, "<%s> sendmsg: %s", __FUNCTION__,
strerror(errno));
}
void
rrenum_snd_eachdst(struct payload_list *pl)
{
struct dst_list *dl;
for (dl = dl_head; dl; dl = dl->dl_next) {
rrenum_output(pl, dl);
}
}
void
rrenum_snd_fullsequence()
{
struct payload_list *pl;
for (pl = pl_head; pl; pl = pl->pl_next) {
rrenum_snd_eachdst(pl);
}
}
void
rrenum_input(int s)
{
int i;
struct icmp6_router_renum *rr;
/* get message */
if ((i = recvmsg(s, &rcvmhdr, 0)) < 0) {
syslog(LOG_ERR, "<%s> recvmsg: %s", __FUNCTION__,
strerror(errno));
return;
}
if (i < sizeof(struct icmp6_router_renum)) {
syslog(LOG_ERR, "<%s> packet size(%d) is too short",
__FUNCTION__, i);
return;
}
rr = (struct icmp6_router_renum *)rcvmhdr.msg_iov->iov_base;
switch(rr->rr_code) {
case ICMP6_ROUTER_RENUMBERING_COMMAND:
/* COMMAND will be processed by rtadvd */
break;
case ICMP6_ROUTER_RENUMBERING_RESULT:
/* TODO: receiving result message */
break;
default:
syslog(LOG_ERR, "<%s> received unknown code %d"
__FUNCTION__, rr->rr_code);
break;
}
}
int
main(int argc, char *argv[])
{
char *cfile = NULL;
FILE *fp = stdin;
fd_set fdset;
struct timeval timeout;
int ch, i, maxfd = 0, send_counter = 0;
struct flags flags;
struct payload_list *pl;
#ifdef IPSEC_POLICY_IPSEC
char *policy = NULL;
#endif
memset(&flags, 0, sizeof(flags));
openlog(*argv, LOG_PID, LOG_DAEMON);
/* get options */
while ((ch = getopt(argc, argv, "c:sdf"
#ifdef IPSEC
#ifdef IPSEC_POLICY_IPSEC
"P:"
#endif /* IPSEC_POLICY_IPSEC */
#endif /* IPSEC */
)) != -1){
switch (ch) {
case 'c':
if((fp = fopen(optarg, "r")) == NULL) {
syslog(LOG_ERR,
"<%s> config file %s open failed",
__FUNCTION__, optarg);
exit(1);
}
break;
case 's':
fp = stdin;
break;
case 'd':
flags.debug = 1;
break;
case 'f':
flags.fg = 1;
break;
#ifdef IPSEC
#ifdef IPSEC_POLICY_IPSEC
case 'P':
flags.policy = 1;
policy = strdup(optarg);
break;
#endif /* IPSEC_POLICY_IPSEC */
#endif /*IPSEC*/
default:
show_usage();
}
}
argc -= optind;
argv += optind;
/* set log level */
if (flags.debug == 0)
(void)setlogmask(LOG_UPTO(LOG_ERR));
if (flags.debug == 1)
(void)setlogmask(LOG_UPTO(LOG_INFO));
/* init global variables */
init_globals();
config(&fp);
sock6_open(&flags
#ifdef IPSEC_POLICY_IPSEC
, policy
#endif /* IPSEC_POLICY_IPSEC */
);
if (!flags.fg)
daemon(0, 0);
FD_ZERO(&fdset);
if (with_v6dest) {
FD_SET(s6, &fdset);
if (s6 > maxfd)
maxfd = s6;
}
/* ADHOC: timeout each 30seconds */
memset(&timeout, 0, sizeof(timeout));
timeout.tv_sec = 30;
/* init temporal payload_list and send_counter*/
pl = pl_head;
send_counter = retry + 1;
while (1) {
struct fd_set select_fd = fdset; /* reinitialize */
if ((i = select(maxfd + 1, &select_fd, NULL, NULL,
&timeout)) < 0){
syslog(LOG_ERR, "<%s> select: %s",
__FUNCTION__, strerror(errno));
continue;
}
if (i == 0) { /* timeout */
if (pl == NULL)
exit(0);
rrenum_snd_eachdst(pl);
send_counter--;
if (send_counter == 0) {
pl = pl->pl_next;
send_counter = retry + 1;
}
}
if (FD_ISSET(s6, &select_fd))
rrenum_input(s6);
}
}

View File

@ -0,0 +1,330 @@
.\" 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.
.\"
.\" $Id: rrenumd.conf.5,v 1.1.1.1 1999/08/08 23:31:39 itojun Exp $
.\" $FreeBSD$
.\"
.Dd Nov 5, 1998
.Dt RRENUMD.CONF 5
.Os KAME
.Sh NAME
.\"
.Nm rrenumd.conf
.Nd configuration file for router renumbering daemon
.\"
.Sh DESCRIPTION
The rrenumd config file describes how the router renumbering packet
must be constructed and to which destinations it should be sent.
This file consists of a sequence of statements terminated by a semi-colon (`;').
Statements are composed of tokens
separated by white space, which can be any combination of blanks, tabs
and newlines.
This structure simplifies identification of
the parts of the configuration associated with each other.
Lines beginning with
.Ql #
are comments.
.\"
.Sh Meta Syntax
Keywords and special characters that the parser expects exactly are
displayed using the
.Ic bold
font.
Parameters are specifying with
.Ar underline .
Parameters shown in
square brackets (`[' and `]') are used to show optional
keywords and parameters.
The vertical bar (`|') is used to indicate
between a choice of optional parameters.
Parentheses (`(' and
`)') are used to group keywords and parameters when necessary.
.\"
.Sh Interface specification
There are some statements that may or have to specify interface.
Interfaces are specified in the form of "name unit", such as
.Ar lo0
and
.Ar ep1.
.\"
.Sh Configuration Statements
.Bl -tag -width Ds
.\"
.It Ic debug on|off ;
Enables configuration file parser debugging.
If
.Ic on
is specified,
then debugging is enabled,
If
.Ic off
is specified,
then debugging is disabled. It is disabled by default.
.\"
.It Ic dest Ar dest-list Op Ar retrycmd ;
Specifies destinations to which router renumbering messages should be
sent.
.Ar dest-list
can be any combination of single or multiple numerical IPv6 addrs,
or Full Qualified Domain Names.
.Ar retrycmd
has following syntax.
.\"
.Bl -tag -width Ds -compact
.It Ic retry Ar retry-num
.Ar retry-num
specifies how many router renumbering messages are sent repeatedly.
.El
.It Op Ic add|change|setglobal
.Cm match-prefix Ar match-prefix-val
.Op /match-prefix-len
.Op Cm maxlen Ar maxlen-val
.Op Cm minlen Ar minlen-val
.Op Cm use-prefix Ar use-prefix-val
.Op /use-prefix-len
.Op Cm keeplen Ar keeplen-val
.Op Ar use-prefix-values ;
.Pp
Specifies contents of sending router renumbering message with seqnum 0.
If
.Cm add|change|setglobal
is not specified, then
.Cm add
is assumed.
.Ar use-prefix-values
has following syntax.
.Pp
{
.Op Cm vltime Ar vltime-val
.Op Cm pltime Ar pltime-val
.Op Cm raf_onlink Cm on|off
.Op Cm raf_auto Cm on|off
.Op Cm rrf_decrprefd Cm on|off
.Op Cm rrf_decrvalid Cm on|off
}
.Pp
Each value has following meaning.
.Pp
.Bl -tag -width Ds -compact
.It Cm match-prefix Ar match-prefix-val Op /match-prefix-len
Specify
.Ar match-prefix-val
that is used for matching with preassigned prefixes to which
.Cm add|change|setglobal
command should be applied.
.Ar /match-prefix-len
Specify the starting part of
.Ar match-prefix-val
to be used for matching with preassigned prefixes, as decimal bit number.
.It Cm maxlen Ar maxlen-val
Specify the maximum length of prefixes which is allowed to be
matched to
.Ar match-prefix-val ,
as decimal bit number.
.It Cm minlen Ar minlen-val
Specify the minimum length of prefixes which is allowed to be matched to
.Ar match-prefix-val ,
as decimal bit number.
.It Cm use-prefix Ar use-prefix-val Op /usr-prefix-len
Specify
.Ar use-prefix-val
that is used for prefixes to be added on
.Cm add|change|setglobal
command.
.Ar /use-prefix-len
Specify the starting part of
.Ar use-prefix-val
copied to the starting part of prefixes to be added on
.Cm add|change|setglobal
command, as decimal bit number.
.It Cm keeplen Ar keeplen-val
Specify the midium part of
.Ar use-prefix-val
just next to the starting part specified by
.Ar use-prefix-len
, as decimal bit number.
Contiguous bits part in the same bit position of an existent prefix
matched with
.Ar match-prefix-val
is copied to the same bit position of prefixes to be added.
.It Cm vltime Ar vmtime-val
Assign an
.Ar time
as prefix valid life time for a prefix to be added.
Valid value for
.Ar time
is decimal seconds number or special format as "d00h00m00s00",
where 00 can take any decimal number, and "d" means days, "h" means hours,
"m" means minutes, "s" means seconds. And alternatively, special keyword
"infinity" can be also be specified.
.It Cm pltime Ar pltime-val
Assign an
.Ar time
as prefix preferred life time for a prefix to be added.
Valid value for
.Ar time
is same as for
.Ar vltime-val .
.It Cm raf_onlink Cm on|off
Let the prefix to be added to have on-link or off-link nature
for the assigned interface. If
.Cm on
is specified, the prefix have on-link nature. (e.g. the prefix
belong to the link) If
.Cm off
is specified, the prefix have off-link nature. (e.g. the
prefix does not belong to the link)
.It Cm raf_auto Cm on|off
Enable or disable the autonomous address auto configuration
for the prefix to be added. If
.Cm on
is specified, autonomous address auto configuration is
enabled. If
.Cm off
is specified, it is disabled.
.It Cm rrf_decrprefd Cm on|off
Enable or disable the decrementation of the pltime. If
.Cm on
is specified, decrementation of the pltime is enabled. If
.Cm off
is specified, decrementation of the pltime is disabled.
.It Cm rrf_decrvalid Cm on|off
Enable or disable the decrementation of the vltime. If
.Cm on
is specified, decrementation of the vltime is enabled. If
.Cm off
is specified, decrementation of the vltime is disabled.
.El
.\"
.It seqnum Ar seqnum-val { Ar rrenum-cmd } ;
Specifies contents of sending router renumbering message with some
specific seqnum. Multiple of this statement can be specified if they
have different
.Ar seqnum-val
each other.
.Ar rrenum-cmd
has just same syntax with above add|change|setglobal statement.
.El
.\"
.Sh EXAMPLE
For each configuration file example shown below, we suppose
every IPv6 subnet has its own prefix beginning with
fec0:0:0::/48 and with its own subnet number. (in this case,
subnet number is 7th and 8th octet value of the prefix)
.Pp
If you want to assigne prefixes beginning with fec0:1:1::/48
to each subnet, then following configuration will be enough,
if each of your routers supports IPv6 multicast forwarding.
The subnet number of the existing fec0:0:0::/48 prefix and the
newly assigned fec0:1:1::/48 prefix will be same.
.\"
.Bd -literal -offset indent
dest ff05::2;
add match-prefix fec0:0:0:: /48 use-prefix fec0:1:1:: /48 keeplen 16;
.Ed
.\"
If your routers don't support IPv6 multicast forwarding,
you'll need to specify each destination at
.Cm dest
command.
.\"
.Bd -literal -offset indent
dest fec0:0:0:1:260:8ff:fe24:fb3a fec0:0:0:2:200:eff:fe2e:dfe1 fec0:0:0:3:5254:ff:fedc:5217;
add match-prefix fec0:0:0:: /48 use-prefix fec0:1:1:: /48 keeplen 16;
.Ed
.\"
If you are going to do renumbering, then following procedure will be natural.
.Bl -enum -offset indent
.It
Assigne new prefix.
.It
Set old prefix lifetimes to some appropriate transition
period. In the followng example we use 1 week for valid
lifetime, and 0 for preferred lifetime.
Also, enable old prefix lifetime expiration.
(By default, it is static and does not expire)
.It
After the transition period, old prefixes should become
invalid, and may have been deleted.
To make sure that they are deleted, send new router
renumbering message, which specifies old prefixes as match
prefix, and no use prefix.
.El
.\"
The following configuration file will do 1 and 2.
.\"
.Bd -literal -offset indent
dest ff05::2;
seqnum 0 {
add match-prefix fec0:0:0:: /48 use-prefix fec0:2:2:: /48 keeplen 16;
};
seqnum 1 {
change match-prefix fec0:1:1:: /48 use-prefix fec0:1:1:: /48 keeplen 16 vltime d7 pltime 0 rrf_decrvalid on rrf_decrprefd on;
};
.Ed
.\"
And the following configuration file will do 3. (should be
used for the router renumbering message to be sent 1 week
afterward)
.\"
.Bd -literal -offset indent
dest ff05::2;
change match-prefix fec0:1:1:: /48;
.Ed
.\"
In the above example, only
.Cm add
and
.Cm change
commands are used, and there is no example for
.Cm setglobal
command.
.Cm setglobal
command is almost same with
.Cm change
command except that it deletes all pre-defined IPv6 global address.
.Sh SEE ALSO
.Xr rrenumd 8
.Xr prefix 8
.Sh HISTORY
The
.Nm
configuration file was first appeared in KAME IPv6 protocol stack kit.
.\" .Sh BUGS
.\" (to be written)

View File

@ -0,0 +1,57 @@
/*
* Copyright (C) 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by WIDE Project and
* its contributors.
* 4. 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$
*/
struct dst_list {
struct dst_list *dl_next;
struct sockaddr *dl_dst;
};
extern struct dst_list *dl_head;
struct payload_list {
struct payload_list *pl_next;
struct iovec pl_sndiov;
struct icmp6_router_renum pl_irr;
struct rr_pco_match pl_rpm;
/* currently, support only 1 rr_pco_use field per packet */
struct rr_pco_use pl_rpu;
};
extern struct payload_list *pl_head;
extern u_int retry;
extern int with_v4dest, with_v6dest;
#define DEF_VLTIME 2592000
#define DEF_PLTIME 604800

26
usr.sbin/rtadvd/Makefile Normal file
View File

@ -0,0 +1,26 @@
# Copyright (c) 1996 WIDE Project. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modifications, are permitted provided that the above copyright notice
# and this paragraph are duplicated in all such forms and that any
# documentation, advertising materials, and other materials related to
# such distribution and use acknowledge that the software was developed
# by the WIDE Project, Japan. The name of the Project may not be used to
# endorse or promote products derived from this software without
# specific prior written permission. THIS SOFTWARE IS PROVIDED ``AS IS''
# AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
# LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE.
# $FreeBSD$
PROG= rtadvd
SRCS= rtadvd.c rrenum.c advcap.c if.c config.c timer.c
CFLAGS+=-DINET6 -DIPSEC
LDADD+= -lcompat -lipsec
DPADD+= ${LIBCOMPAT} ${LIBIPSEC}
MAN5= rtadvd.conf.5
MAN8= rtadvd.8
.include <bsd.prog.mk>

452
usr.sbin/rtadvd/advcap.c Normal file
View File

@ -0,0 +1,452 @@
/*
* Copyright (c) 1983 The Regents of the University of California.
* 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University 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 REGENTS 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 REGENTS 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 sccsid[] = "@(#)remcap.c 5.5 (Berkeley) 2/2/91";
#endif /* not lint */
/*
* remcap - routines for dealing with the remote host data base
*
* derived from termcap
*/
#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>
#include <fcntl.h>
#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#include <syslog.h>
#include <errno.h>
#include <string.h>
#include "pathnames.h"
#ifndef BUFSIZ
#define BUFSIZ 1024
#endif
#define MAXHOP 32 /* max number of tc= indirections */
#define tgetent agetent
#define tnchktc anchktc
#define tnamatch anamatch
#define tgetnum agetnum
#define tgetflag agetflag
#define tgetstr agetstr
char *RM;
/*
* termcap - routines for dealing with the terminal capability data base
*
* BUG: Should use a "last" pointer in tbuf, so that searching
* for capabilities alphabetically would not be a n**2/2
* process when large numbers of capabilities are given.
* Note: If we add a last pointer now we will screw up the
* tc capability. We really should compile termcap.
*
* Essentially all the work here is scanning and decoding escapes
* in string capabilities. We don't use stdio because the editor
* doesn't, and because living w/o it is not hard.
*/
static char *tbuf;
static int hopcount; /* detect infinite loops in termcap, init 0 */
static char *remotefile;
extern char *conffile;
int tgetent __P((char *, char *));
int getent __P((char *, char *, char *));
int tnchktc __P((void));
int tnamatch __P((char *));
static char *tskip __P((char *));
int tgetnum __P((char *));
int tgetflag __P((char *));
char *tgetstr __P((char *, char **));
static char *tdecode __P((char *, char **));
/*
* Get an entry for terminal name in buffer bp,
* from the termcap file. Parse is very rudimentary;
* we just notice escaped newlines.
*/
int
tgetent(bp, name)
char *bp, *name;
{
char *cp;
remotefile = cp = conffile ? conffile : _PATH_RTADVDCONF;
return (getent(bp, name, cp));
}
int
getent(bp, name, cp)
char *bp, *name, *cp;
{
register int c;
register int i = 0, cnt = 0;
char ibuf[BUFSIZ];
int tf;
tbuf = bp;
tf = 0;
/*
* TERMCAP can have one of two things in it. It can be the
* name of a file to use instead of /etc/termcap. In this
* case it better start with a "/". Or it can be an entry to
* use so we don't have to read the file. In this case it
* has to already have the newlines crunched out.
*/
if (cp && *cp) {
tf = open(RM = cp, O_RDONLY);
}
if (tf < 0) {
syslog(LOG_WARNING,
"<%s> open: %s", __FUNCTION__, strerror(errno));
return (-2);
}
for (;;) {
cp = bp;
for (;;) {
if (i == cnt) {
cnt = read(tf, ibuf, BUFSIZ);
if (cnt <= 0) {
close(tf);
return (0);
}
i = 0;
}
c = ibuf[i++];
if (c == '\n') {
if (cp > bp && cp[-1] == '\\') {
cp--;
continue;
}
break;
}
if (cp >= bp+BUFSIZ) {
write(2,"Remcap entry too long\n", 23);
break;
} else
*cp++ = c;
}
*cp = 0;
/*
* The real work for the match.
*/
if (tnamatch(name)) {
close(tf);
return (tnchktc());
}
}
}
/*
* tnchktc: check the last entry, see if it's tc=xxx. If so,
* recursively find xxx and append that entry (minus the names)
* to take the place of the tc=xxx entry. This allows termcap
* entries to say "like an HP2621 but doesn't turn on the labels".
* Note that this works because of the left to right scan.
*/
int
tnchktc()
{
register char *p, *q;
char tcname[16]; /* name of similar terminal */
char tcbuf[BUFSIZ];
char *holdtbuf = tbuf;
int l;
p = tbuf + strlen(tbuf) - 2; /* before the last colon */
while (*--p != ':')
if (p<tbuf) {
write(2, "Bad remcap entry\n", 18);
return (0);
}
p++;
/* p now points to beginning of last field */
if (p[0] != 't' || p[1] != 'c')
return (1);
strcpy(tcname, p+3);
q = tcname;
while (*q && *q != ':')
q++;
*q = 0;
if (++hopcount > MAXHOP) {
write(2, "Infinite tc= loop\n", 18);
return (0);
}
if (getent(tcbuf, tcname, remotefile) != 1) {
return (0);
}
for (q = tcbuf; *q++ != ':'; )
;
l = p - holdtbuf + strlen(q);
if (l > BUFSIZ) {
write(2, "Remcap entry too long\n", 23);
q[BUFSIZ - (p-holdtbuf)] = 0;
}
strcpy(p, q);
tbuf = holdtbuf;
return (1);
}
/*
* Tnamatch deals with name matching. The first field of the termcap
* entry is a sequence of names separated by |'s, so we compare
* against each such name. The normal : terminator after the last
* name (before the first field) stops us.
*/
int
tnamatch(np)
char *np;
{
register char *Np, *Bp;
Bp = tbuf;
if (*Bp == '#')
return (0);
for (;;) {
for (Np = np; *Np && *Bp == *Np; Bp++, Np++)
continue;
if (*Np == 0 && (*Bp == '|' || *Bp == ':' || *Bp == 0))
return (1);
while (*Bp && *Bp != ':' && *Bp != '|')
Bp++;
if (*Bp == 0 || *Bp == ':')
return (0);
Bp++;
}
}
/*
* Skip to the next field. Notice that this is very dumb, not
* knowing about \: escapes or any such. If necessary, :'s can be put
* into the termcap file in octal.
*/
static char *
tskip(bp)
register char *bp;
{
int dquote;
dquote = 0;
while (*bp) {
switch (*bp) {
case ':':
if (!dquote)
goto breakbreak;
else
bp++;
break;
case '\\':
bp++;
if (isdigit(*bp)) {
while (isdigit(*bp++))
;
} else
bp++;
case '"':
dquote = (dquote ? 1 : 0);
bp++;
break;
default:
bp++;
break;
}
}
breakbreak:
if (*bp == ':')
bp++;
return (bp);
}
/*
* Return the (numeric) option id.
* Numeric options look like
* li#80
* i.e. the option string is separated from the numeric value by
* a # character. If the option is not found we return -1.
* Note that we handle octal numbers beginning with 0.
*/
int
tgetnum(id)
char *id;
{
register long int i;
register int base;
register char *bp = tbuf;
for (;;) {
bp = tskip(bp);
if (*bp == 0)
return (-1);
if (strncmp(bp, id, strlen(id)) != 0)
continue;
bp += strlen(id);
if (*bp == '@')
return (-1);
if (*bp != '#')
continue;
bp++;
base = 10;
if (*bp == '0')
base = 8;
i = 0;
while (isdigit(*bp))
i *= base, i += *bp++ - '0';
return (i);
}
}
/*
* Handle a flag option.
* Flag options are given "naked", i.e. followed by a : or the end
* of the buffer. Return 1 if we find the option, or 0 if it is
* not given.
*/
int
tgetflag(id)
char *id;
{
register char *bp = tbuf;
for (;;) {
bp = tskip(bp);
if (!*bp)
return (0);
if (strncmp(bp, id, strlen(id)) == 0) {
bp += strlen(id);
if (!*bp || *bp == ':')
return (1);
else if (*bp == '@')
return (0);
}
}
}
/*
* Get a string valued option.
* These are given as
* cl=^Z
* Much decoding is done on the strings, and the strings are
* placed in area, which is a ref parameter which is updated.
* No checking on area overflow.
*/
char *
tgetstr(id, area)
char *id, **area;
{
register char *bp = tbuf;
for (;;) {
bp = tskip(bp);
if (!*bp)
return (0);
if (strncmp(bp, id, strlen(id)) != 0)
continue;
bp += strlen(id);
if (*bp == '@')
return (0);
if (*bp != '=')
continue;
bp++;
return (tdecode(bp, area));
}
}
/*
* Tdecode does the grung work to decode the
* string capability escapes.
*/
static char *
tdecode(str, area)
register char *str;
char **area;
{
register char *cp;
register int c;
register char *dp;
int i;
char term;
term = ':';
cp = *area;
again:
if (*str == '"') {
term = '"';
str++;
}
while ((c = *str++) && c != term) {
switch (c) {
case '^':
c = *str++ & 037;
break;
case '\\':
dp = "E\033^^\\\\::n\nr\rt\tb\bf\f\"\"";
c = *str++;
nextc:
if (*dp++ == c) {
c = *dp++;
break;
}
dp++;
if (*dp)
goto nextc;
if (isdigit(c)) {
c -= '0', i = 2;
do
c <<= 3, c |= *str++ - '0';
while (--i && isdigit(*str));
}
break;
}
*cp++ = c;
}
if (c == term && term != ':') {
term = ':';
goto again;
}
*cp++ = 0;
str = *area;
*area = cp;
return (str);
}

45
usr.sbin/rtadvd/advcap.h Normal file
View File

@ -0,0 +1,45 @@
/*
* Copyright (C) 1994,1995 by Andrey A. Chernov, Moscow, Russia.
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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$
*/
/* Based on Id: termcap.h,v 1.8 1996/09/10 12:42:10 peter Exp */
#ifndef _ADVCAP_H_
#define _ADVCAP_H_
#include <sys/cdefs.h>
__BEGIN_DECLS
extern int agetent __P((char *, const char *));
extern int agetflag __P((const char *));
extern int agetnum __P((const char *));
extern char *agetstr __P((const char *, char **));
__END_DECLS
#endif /* _ADVCAP_H_ */

639
usr.sbin/rtadvd/config.c Normal file
View File

@ -0,0 +1,639 @@
/*
* Copyright (C) 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.
*
* $FreeBSD$
*/
#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <net/if.h>
#include <net/if_var.h>
#include <net/route.h>
#include <net/if_dl.h>
#include <netinet/in.h>
#include <netinet/in_var.h>
#include <netinet6/ip6.h>
#include <netinet6/ip6_var.h>
#include <netinet6/icmp6.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <syslog.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include "rtadvd.h"
#include "advcap.h"
#include "timer.h"
#include "if.h"
#include "config.h"
static void makeentry __P((char *, int, char *, int));
static void make_packet __P((struct rainfo *));
static void get_prefix __P((struct rainfo *));
extern struct rainfo *ralist;
void
getconfig(intface)
char *intface;
{
int stat, pfxs, i;
char tbuf[BUFSIZ];
struct rainfo *tmp;
long val;
char buf[BUFSIZ];
char *bp = buf;
char *addr;
#define MUSTHAVE(var, cap) \
{ \
int t; \
if ((t = agetnum(cap)) < 0) { \
fprintf(stderr, "rtadvd: need %s for interface %s\n", \
cap, intface); \
exit(1); \
} \
var = t; \
}
#define MAYHAVE(var, cap, def) \
{ \
if ((var = agetnum(cap)) < 0) \
var = def; \
}
if ((stat = agetent(tbuf, intface)) <= 0) {
memset(tbuf, 0, sizeof(tbuf));
syslog(LOG_INFO,
"<%s> %s isn't defined in the configuration file"
" or the configuration file doesn't exist."
" Treat it as default",
__FUNCTION__, intface);
}
tmp = (struct rainfo *)malloc(sizeof(*ralist));
memset(tmp, 0, sizeof(*tmp));
tmp->prefix.next = tmp->prefix.prev = &tmp->prefix;
/* get interface information */
if (agetflag("nolladdr"))
tmp->advlinkopt = 0;
else
tmp->advlinkopt = 1;
if (tmp->advlinkopt) {
if ((tmp->sdl = if_nametosdl(intface)) == NULL) {
syslog(LOG_ERR,
"<%s> can't get information of %s",
__FUNCTION__, intface);
exit(1);
}
tmp->ifindex = tmp->sdl->sdl_index;
} else
tmp->ifindex = if_nametoindex(intface);
strncpy(tmp->ifname, intface, sizeof(tmp->ifname));
if ((tmp->phymtu = if_getmtu(intface)) == 0) {
tmp->phymtu = IPV6_MMTU;
syslog(LOG_WARNING,
"<%s> can't get interface mtu of %s. Treat as %d",
__FUNCTION__, intface, IPV6_MMTU);
}
/*
* set router configuration variables.
*/
MAYHAVE(val, "maxinterval", DEF_MAXRTRADVINTERVAL);
if (val < MIN_MAXINTERVAL || val > MAX_MAXINTERVAL) {
syslog(LOG_ERR,
"<%s> maxinterval must be between %d and %d",
__FUNCTION__, MIN_MAXINTERVAL, MAX_MAXINTERVAL);
exit(1);
}
tmp->maxinterval = (u_int)val;
MAYHAVE(val, "mininterval", tmp->maxinterval/3);
if (val < MIN_MININTERVAL || val > (tmp->maxinterval * 3) / 4) {
syslog(LOG_ERR,
"<%s> mininterval must be between %d and %d",
__FUNCTION__,
MIN_MININTERVAL,
(tmp->maxinterval * 3) / 4);
exit(1);
}
tmp->mininterval = (u_int)val;
MAYHAVE(val, "chlim", DEF_ADVCURHOPLIMIT);
tmp->hoplimit = val & 0xff;
MAYHAVE(val, "raflags", 0);
tmp->managedflg= val & ND_RA_FLAG_MANAGED;
tmp->otherflg = val & ND_RA_FLAG_OTHER;
MAYHAVE(val, "rltime", tmp->maxinterval * 3);
if (val && (val < tmp->maxinterval || val > MAXROUTERLIFETIME)) {
syslog(LOG_ERR,
"<%s> router lifetime on %s must be 0 or"
" between %d and %d",
__FUNCTION__, intface,
tmp->maxinterval, MAXROUTERLIFETIME);
exit(1);
}
tmp->lifetime = val & 0xffff;
MAYHAVE(val, "rtime", DEF_ADVREACHABLETIME);
if (val > MAXREACHABLETIME) {
syslog(LOG_ERR,
"<%s> reachable time must be no greater than %d",
__FUNCTION__, MAXREACHABLETIME);
exit(1);
}
tmp->reachabletime = (u_int32_t)val;
MAYHAVE(val, "retrans", DEF_ADVRETRANSTIMER);
if (val < 0 || val > 0xffffffff) {
syslog(LOG_ERR,
"<%s> retrans time out of range", __FUNCTION__);
exit(1);
}
tmp->retranstimer = (u_int32_t)val;
/* prefix information */
if ((pfxs = agetnum("addrs")) < 0) {
/* auto configure prefix information */
if (agetstr("addr", &bp) || agetstr("addr1", &bp)) {
syslog(LOG_ERR,
"<%s> conflicting prefix configuration for %s: "
"automatic and manual config at the same time",
__FUNCTION__, intface);
exit(1);
}
get_prefix(tmp);
}
else {
tmp->pfxs = pfxs;
for (i = 0; i < pfxs; i++) {
struct prefix *pfx;
char entbuf[256];
int added = (pfxs > 1) ? 1 : 0;
/* allocate memory to store prefix information */
if ((pfx = malloc(sizeof(struct prefix))) == NULL) {
syslog(LOG_ERR,
"<%s> can't allocate enough memory",
__FUNCTION__);
exit(1);
}
/* link into chain */
insque(pfx, &tmp->prefix);
makeentry(entbuf, i, "prefixlen", added);
MAYHAVE(val, entbuf, 64);
if (val < 0 || val > 128) {
syslog(LOG_ERR,
"<%s> prefixlen out of range",
__FUNCTION__);
exit(1);
}
pfx->prefixlen = (int)val;
makeentry(entbuf, i, "pinfoflags", added);
MAYHAVE(val, entbuf,
(ND_OPT_PI_FLAG_ONLINK|ND_OPT_PI_FLAG_AUTO));
pfx->onlinkflg = val & ND_OPT_PI_FLAG_ONLINK;
pfx->autoconfflg = val & ND_OPT_PI_FLAG_AUTO;
makeentry(entbuf, i, "vltime", added);
MAYHAVE(val, entbuf, DEF_ADVVALIDLIFETIME);
if (val < 0 || val > 0xffffffff) {
syslog(LOG_ERR,
"<%s> vltime out of range",
__FUNCTION__);
exit(1);
}
pfx->validlifetime = (u_int32_t)val;
makeentry(entbuf, i, "pltime", added);
MAYHAVE(val, entbuf, DEF_ADVPREFERREDLIFETIME);
if (val < 0 || val > 0xffffffff) {
syslog(LOG_ERR,
"<%s> pltime out of range",
__FUNCTION__);
exit(1);
}
pfx->preflifetime = (u_int32_t)val;
makeentry(entbuf, i, "addr", added);
addr = (char *)agetstr(entbuf, &bp);
if (addr == NULL) {
syslog(LOG_ERR,
"<%s> need %s as an prefix for "
"interface %s",
__FUNCTION__, entbuf, intface);
exit(1);
}
if (inet_pton(AF_INET6, addr,
&pfx->prefix) != 1) {
syslog(LOG_ERR,
"<%s> inet_pton failed for %s",
__FUNCTION__, addr);
exit(1);
}
if (IN6_IS_ADDR_MULTICAST(&pfx->prefix)) {
syslog(LOG_ERR,
"<%s> multicast prefix(%s) must "
"not be advertised (IF=%s)",
__FUNCTION__, addr, intface);
exit(1);
}
if (IN6_IS_ADDR_LINKLOCAL(&pfx->prefix))
syslog(LOG_NOTICE,
"<%s> link-local prefix(%s) will be"
" advertised on %s",
__FUNCTION__, addr, intface);
}
}
MAYHAVE(val, "mtu", 0);
if (val < 0 || val > 0xffffffff) {
syslog(LOG_ERR,
"<%s> mtu out of range", __FUNCTION__);
exit(1);
}
tmp->linkmtu = (u_int32_t)val;
if (tmp->linkmtu == 0) {
char *mtustr;
if ((mtustr = (char *)agetstr("mtu", &bp)) &&
strcmp(mtustr, "auto") == 0)
tmp->linkmtu = tmp->phymtu;
}
else if (tmp->linkmtu < IPV6_MMTU || tmp->linkmtu > tmp->phymtu) {
syslog(LOG_ERR,
"<%s> advertised link mtu must be between"
" least MTU and physical link MTU",
__FUNCTION__);
exit(1);
}
/* okey */
tmp->next = ralist;
ralist = tmp;
/* construct the sending packet */
make_packet(tmp);
/* set timer */
tmp->timer = rtadvd_add_timer(ra_timeout, ra_timer_update,
tmp, tmp);
ra_timer_update((void *)tmp, &tmp->timer->tm);
rtadvd_set_timer(&tmp->timer->tm, tmp->timer);
}
static void
get_prefix(struct rainfo *rai)
{
size_t len;
u_char *buf, *lim, *next;
u_char ntopbuf[INET6_ADDRSTRLEN];
if ((len = rtbuf_len()) < 0) {
syslog(LOG_ERR,
"<%s> can't get buffer length for routing info",
__FUNCTION__);
exit(1);
}
if ((buf = malloc(len)) == NULL) {
syslog(LOG_ERR,
"<%s> can't allocate buffer", __FUNCTION__);
exit(1);
}
if (get_rtinfo(buf, &len) < 0) {
syslog(LOG_ERR,
"<%s> can't get routing inforamtion", __FUNCTION__);
exit(1);
}
lim = buf + len;
next = get_next_msg(buf, lim, rai->ifindex, &len,
RTADV_TYPE2BITMASK(RTM_GET));
while (next < lim) {
struct prefix *pp;
struct in6_addr *a;
/* allocate memory to store prefix info. */
if ((pp = malloc(sizeof(*pp))) == NULL) {
syslog(LOG_ERR,
"<%s> can't get allocate buffer for prefix",
__FUNCTION__);
exit(1);
}
memset(pp, 0, sizeof(*pp));
/* set prefix and its length */
a = get_addr(next);
memcpy(&pp->prefix, a, sizeof(*a));
if ((pp->prefixlen = get_prefixlen(next)) < 0) {
syslog(LOG_ERR,
"<%s> failed to get prefixlen "
"or prefixl is invalid",
__FUNCTION__);
exit(1);
}
syslog(LOG_DEBUG,
"<%s> add %s/%d to prefix list on %s",
__FUNCTION__,
inet_ntop(AF_INET6, a, ntopbuf, INET6_ADDRSTRLEN),
pp->prefixlen, rai->ifname);
/* set other fields with protocol defaults */
pp->validlifetime = DEF_ADVVALIDLIFETIME;
pp->preflifetime = DEF_ADVPREFERREDLIFETIME;
pp->onlinkflg = 1;
pp->autoconfflg = 1;
/* link into chain */
insque(pp, &rai->prefix);
/* counter increment */
rai->pfxs++;
/* forward pointer and get next prefix(if any) */
next += len;
next = get_next_msg(next, lim, rai->ifindex,
&len, RTADV_TYPE2BITMASK(RTM_GET));
}
free(buf);
}
static void
makeentry(buf, id, string, add)
char *buf, *string;
int id, add;
{
strcpy(buf, string);
if (add) {
char *cp;
cp = (char *)index(buf, '\0');
cp += sprintf(cp, "%d", id);
*cp = '\0';
}
}
/*
* Add a prefix to the list of specified interface and reconstruct
* the outgoing packet.
* The prefix must not be in the list.
* XXX: other parameter of the prefix(e.g. lifetime) shoule be
* able to be specified.
*/
static void
add_prefix(struct rainfo *rai, struct in6_prefixreq *ipr)
{
struct prefix *prefix;
u_char ntopbuf[INET6_ADDRSTRLEN];
if ((prefix = malloc(sizeof(*prefix))) == NULL) {
syslog(LOG_ERR, "<%s> memory allocation failed",
__FUNCTION__);
return; /* XXX: error or exit? */
}
prefix->prefix = ipr->ipr_prefix.sin6_addr;
prefix->prefixlen = ipr->ipr_plen;
prefix->validlifetime = ipr->ipr_vltime;
prefix->preflifetime = ipr->ipr_pltime;
prefix->onlinkflg = ipr->ipr_raf_onlink;
prefix->autoconfflg = ipr->ipr_raf_auto;
insque(prefix, &rai->prefix);
syslog(LOG_DEBUG, "<%s> new prefix %s/%d was added on %s",
__FUNCTION__, inet_ntop(AF_INET6, &ipr->ipr_prefix.sin6_addr,
ntopbuf, INET6_ADDRSTRLEN),
ipr->ipr_plen, rai->ifname);
/* free the previous packet */
free(rai->ra_data);
rai->ra_data = 0;
/* reconstruct the packet */
rai->pfxs++;
make_packet(rai);
/*
* reset the timer so that the new prefix will be advertised quickly.
*/
rai->initcounter = 0;
ra_timer_update((void *)rai, &rai->timer->tm);
rtadvd_set_timer(&rai->timer->tm, rai->timer);
}
/*
* Delete a prefix to the list of specified interface and reconstruct
* the outgoing packet.
* The prefix must be in the list
*/
void
delete_prefix(struct rainfo *rai, struct prefix *prefix)
{
u_char ntopbuf[INET6_ADDRSTRLEN];
remque(prefix);
syslog(LOG_DEBUG, "<%s> prefix %s/%d was deleted on %s",
__FUNCTION__, inet_ntop(AF_INET6, &prefix->prefix,
ntopbuf, INET6_ADDRSTRLEN),
prefix->prefixlen, rai->ifname);
free(prefix);
rai->pfxs--;
make_packet(rai);
}
/*
* Try to get an in6_prefixreq contents for a prefix which matches
* ipr->ipr_prefix and ipr->ipr_plen and belongs to
* the interface whose name is ipr->ipr_name[].
*/
static int
init_prefix(struct in6_prefixreq *ipr)
{
int s;
if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
syslog(LOG_ERR, "<%s> socket: %s", __FUNCTION__,
strerror(errno));
exit(1);
}
if (ioctl(s, SIOCGIFPREFIX_IN6, (caddr_t)ipr) < 0) {
syslog(LOG_INFO, "<%s> ioctl:SIOCGIFPREFIX %s", __FUNCTION__,
strerror(errno));
ipr->ipr_vltime = DEF_ADVVALIDLIFETIME;
ipr->ipr_pltime = DEF_ADVPREFERREDLIFETIME;
ipr->ipr_raf_onlink = 1;
ipr->ipr_raf_auto = 1;
/* omit other field initialization */
}
else if (ipr->ipr_origin < PR_ORIG_RR) {
u_char ntopbuf[INET6_ADDRSTRLEN];
syslog(LOG_WARNING, "<%s> Added prefix(%s)'s origin %d is"
"lower than PR_ORIG_RR(router renumbering)."
"This should not happen if I am router", __FUNCTION__,
inet_ntop(AF_INET6, &ipr->ipr_prefix.sin6_addr, ntopbuf,
sizeof(ntopbuf)), ipr->ipr_origin);
return 1;
}
close(s);
return 0;
}
void
make_prefix(struct rainfo *rai, int ifindex, struct in6_addr *addr, int plen)
{
struct in6_prefixreq ipr;
memset(&ipr, 0, sizeof(ipr));
if (if_indextoname(ifindex, ipr.ipr_name) == NULL) {
syslog(LOG_ERR, "<%s> Prefix added interface No.%d doesn't"
"exist. This should not happen! %s", __FUNCTION__,
ifindex, strerror(errno));
exit(1);
}
ipr.ipr_prefix.sin6_len = sizeof(ipr.ipr_prefix);
ipr.ipr_prefix.sin6_family = AF_INET6;
ipr.ipr_prefix.sin6_addr = *addr;
ipr.ipr_plen = plen;
if (init_prefix(&ipr))
return; /* init failed by some error */
add_prefix(rai, &ipr);
}
static void
make_packet(struct rainfo *rainfo)
{
size_t packlen, lladdroptlen = 0;
char *buf;
struct nd_router_advert *ra;
struct nd_opt_prefix_info *ndopt_pi;
struct nd_opt_mtu *ndopt_mtu;
struct prefix *pfx;
/* calculate total length */
packlen = sizeof(struct nd_router_advert);
if (rainfo->advlinkopt) {
if ((lladdroptlen = lladdropt_length(rainfo->sdl)) == 0) {
syslog(LOG_INFO,
"<%s> link-layer address option has"
" null length on %s."
" Treat as not included.",
__FUNCTION__, rainfo->ifname);
rainfo->advlinkopt = 0;
}
packlen += lladdroptlen;
}
if (rainfo->pfxs)
packlen += sizeof(struct nd_opt_prefix_info) * rainfo->pfxs;
if (rainfo->linkmtu)
packlen += sizeof(struct nd_opt_mtu);
/* allocate memory for the packet */
if ((buf = malloc(packlen)) == NULL) {
syslog(LOG_ERR,
"<%s> can't get enough memory for an RA packet",
__FUNCTION__);
exit(1);
}
rainfo->ra_data = buf;
/* XXX: what if packlen > 576? */
rainfo->ra_datalen = packlen;
/*
* construct the packet
*/
ra = (struct nd_router_advert *)buf;
ra->nd_ra_type = ND_ROUTER_ADVERT;
ra->nd_ra_code = 0;
ra->nd_ra_cksum = 0;
ra->nd_ra_curhoplimit = (u_int8_t)(0xff & rainfo->hoplimit);
ra->nd_ra_flags_reserved = 0;
ra->nd_ra_flags_reserved |=
rainfo->managedflg ? ND_RA_FLAG_MANAGED : 0;
ra->nd_ra_flags_reserved |=
rainfo->otherflg ? ND_RA_FLAG_OTHER : 0;
ra->nd_ra_router_lifetime = htons(rainfo->lifetime);
ra->nd_ra_reachable = htonl(rainfo->reachabletime);
ra->nd_ra_retransmit = htonl(rainfo->retranstimer);
buf += sizeof(*ra);
if (rainfo->advlinkopt) {
lladdropt_fill(rainfo->sdl, (struct nd_opt_hdr *)buf);
buf += lladdroptlen;
}
if (rainfo->linkmtu) {
ndopt_mtu = (struct nd_opt_mtu *)buf;
ndopt_mtu->nd_opt_mtu_type = ND_OPT_MTU;
ndopt_mtu->nd_opt_mtu_len = 1;
ndopt_mtu->nd_opt_mtu_reserved = 0;
ndopt_mtu->nd_opt_mtu_mtu = ntohl(rainfo->linkmtu);
buf += sizeof(struct nd_opt_mtu);
}
for (pfx = rainfo->prefix.next;
pfx != &rainfo->prefix; pfx = pfx->next) {
ndopt_pi = (struct nd_opt_prefix_info *)buf;
ndopt_pi->nd_opt_pi_type = ND_OPT_PREFIX_INFORMATION;
ndopt_pi->nd_opt_pi_len = 4;
ndopt_pi->nd_opt_pi_prefix_len = pfx->prefixlen;
ndopt_pi->nd_opt_pi_flags_reserved = 0;
if (pfx->onlinkflg)
ndopt_pi->nd_opt_pi_flags_reserved |=
ND_OPT_PI_FLAG_ONLINK;
if (pfx->autoconfflg)
ndopt_pi->nd_opt_pi_flags_reserved |=
ND_OPT_PI_FLAG_AUTO;
ndopt_pi->nd_opt_pi_valid_time = ntohl(pfx->validlifetime);
ndopt_pi->nd_opt_pi_preferred_time =
ntohl(pfx->preflifetime);
ndopt_pi->nd_opt_pi_reserved2 = 0;
ndopt_pi->nd_opt_pi_prefix = pfx->prefix;
buf += sizeof(struct nd_opt_prefix_info);
}
return;
}

34
usr.sbin/rtadvd/config.h Normal file
View File

@ -0,0 +1,34 @@
/*
* 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 void getconfig __P((char *));
extern void delete_prefix __P((struct rainfo *, struct prefix *));
extern void make_prefix __P((struct rainfo *, int, struct in6_addr *, int));

556
usr.sbin/rtadvd/if.c Normal file
View File

@ -0,0 +1,556 @@
/*
* 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.
*
* $FreeBSD$
*/
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/sysctl.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <net/if_types.h>
#include <net/ethernet.h>
#include <net/route.h>
#include <net/if_dl.h>
#include <netinet/in.h>
#include <netinet/icmp6.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include "rtadvd.h"
#include "if.h"
#define ROUNDUP(a, size) \
(((a) & ((size)-1)) ? (1 + ((a) | ((size)-1))) : (a))
#define NEXT_SA(ap) (ap) = (struct sockaddr *) \
((caddr_t)(ap) + ((ap)->sa_len ? ROUNDUP((ap)->sa_len,\
sizeof(u_long)) :\
sizeof(u_long)))
struct if_msghdr **iflist;
int iflist_init_ok;
size_t ifblock_size;
char *ifblock;
static void get_iflist __P((char **buf, size_t *size));
static void parse_iflist __P((struct if_msghdr ***ifmlist_p, char *buf,
size_t bufsize));
static void
get_rtaddrs(int addrs, struct sockaddr *sa, struct sockaddr **rti_info)
{
int i;
for (i = 0; i < RTAX_MAX; i++) {
if (addrs & (1 << i)) {
rti_info[i] = sa;
NEXT_SA(sa);
}
else
rti_info[i] = NULL;
}
}
struct sockaddr_dl *
if_nametosdl(char *name)
{
int mib[6] = {CTL_NET, AF_ROUTE, 0, 0, NET_RT_IFLIST, 0};
char *buf, *next, *lim;
size_t len;
struct if_msghdr *ifm;
struct sockaddr *sa, *rti_info[RTAX_MAX];
struct sockaddr_dl *sdl = NULL, *ret_sdl;
if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0)
return(NULL);
if ((buf = malloc(len)) == NULL)
return(NULL);
if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) {
free(buf);
return(NULL);
}
lim = buf + len;
for (next = buf; next < lim; next += ifm->ifm_msglen) {
ifm = (struct if_msghdr *)next;
if (ifm->ifm_type == RTM_IFINFO) {
sa = (struct sockaddr *)(ifm + 1);
get_rtaddrs(ifm->ifm_addrs, sa, rti_info);
if ((sa = rti_info[RTAX_IFP]) != NULL) {
if (sa->sa_family == AF_LINK) {
sdl = (struct sockaddr_dl *)sa;
if (strncmp(&sdl->sdl_data[0],
name,
sdl->sdl_nlen) == 0) {
break;
}
}
}
}
}
if (next == lim) {
/* search failed */
free(buf);
return(NULL);
}
if ((ret_sdl = malloc(sdl->sdl_len)) == NULL)
return(NULL);
memcpy((caddr_t)ret_sdl, (caddr_t)sdl, sdl->sdl_len);
return(ret_sdl);
}
int
if_getmtu(char *name)
{
struct ifreq ifr;
int s;
if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0)
return(0);
ifr.ifr_addr.sa_family = AF_INET6;
strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
if (ioctl(s, SIOCGIFMTU, (caddr_t)&ifr) < 0) {
close(s);
return(0);
}
close(s);
return(ifr.ifr_mtu);
}
/* give interface index and its old flags, then new flags returned */
int
if_getflags(int ifindex, int oifflags)
{
struct ifreq ifr;
int s;
if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
syslog(LOG_ERR, "<%s> socket: %s", __FUNCTION__,
strerror(errno));
return (oifflags & ~IFF_UP);
}
if_indextoname(ifindex, ifr.ifr_name);
if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) {
syslog(LOG_ERR, "<%s> ioctl:SIOCGIFFLAGS: failed for %s",
__FUNCTION__, ifr.ifr_name);
close(s);
return (oifflags & ~IFF_UP);
}
return (ifr.ifr_flags);
}
#define ROUNDUP8(a) (1 + (((a) - 1) | 7))
int
lladdropt_length(struct sockaddr_dl *sdl)
{
switch(sdl->sdl_type) {
case IFT_ETHER:
return(ROUNDUP8(ETHER_ADDR_LEN + 2));
default:
return(0);
}
}
void
lladdropt_fill(struct sockaddr_dl *sdl, struct nd_opt_hdr *ndopt)
{
char *addr;
ndopt->nd_opt_type = ND_OPT_SOURCE_LINKADDR; /* fixed */
switch(sdl->sdl_type) {
case IFT_ETHER:
ndopt->nd_opt_len = (ROUNDUP8(ETHER_ADDR_LEN + 2)) >> 3;
addr = (char *)(ndopt + 1);
memcpy(addr, LLADDR(sdl), ETHER_ADDR_LEN);
break;
default:
syslog(LOG_ERR,
"<%s> unsupported link type(%d)",
__FUNCTION__, sdl->sdl_type);
exit(1);
}
return;
}
int
rtbuf_len()
{
size_t len;
int mib[6] = {CTL_NET, AF_ROUTE, 0, AF_INET6, NET_RT_DUMP, 0};
if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0)
return(-1);
return(len);
}
int
get_rtinfo(char *buf, size_t *len)
{
int mib[6] = {CTL_NET, AF_ROUTE, 0, AF_INET6, NET_RT_DUMP, 0};
if (sysctl(mib, 6, buf, len, NULL, 0) < 0)
return(-1);
return(0);
}
#define FILTER_MATCH(type, filter) ((0x1 << type) & filter)
#define SIN6(s) ((struct sockaddr_in6 *)(s))
#define SDL(s) ((struct sockaddr_dl *)(s))
char *
get_next_msg(char *buf, char *lim, int ifindex, size_t *lenp, int filter)
{
struct rt_msghdr *rtm;
struct ifa_msghdr *ifam;
struct sockaddr *sa, *dst, *gw, *ifa, *rti_info[RTAX_MAX];
*lenp = 0;
for (rtm = (struct rt_msghdr *)buf;
rtm < (struct rt_msghdr *)lim;
rtm = (struct rt_msghdr *)(((char *)rtm) + rtm->rtm_msglen)) {
/* just for safety */
if (!rtm->rtm_msglen) {
syslog(LOG_WARNING, "<%s> rtm_msglen is 0 "
"(buf=%p lim=%p rtm=%p)", __FUNCTION__,
buf, lim, rtm);
break;
}
if (FILTER_MATCH(rtm->rtm_type, filter) == 0) {
continue;
}
switch (rtm->rtm_type) {
case RTM_GET:
case RTM_ADD:
case RTM_DELETE:
/* address related checks */
sa = (struct sockaddr *)(rtm + 1);
get_rtaddrs(rtm->rtm_addrs, sa, rti_info);
if ((dst = rti_info[RTAX_DST]) == NULL ||
dst->sa_family != AF_INET6)
continue;
if (IN6_IS_ADDR_LINKLOCAL(&SIN6(dst)->sin6_addr) ||
IN6_IS_ADDR_MULTICAST(&SIN6(dst)->sin6_addr))
continue;
if ((gw = rti_info[RTAX_GATEWAY]) == NULL ||
gw->sa_family != AF_LINK)
continue;
if (ifindex && SDL(gw)->sdl_index != ifindex)
continue;
if (rti_info[RTAX_NETMASK] == NULL)
continue;
/* found */
*lenp = rtm->rtm_msglen;
return (char *)rtm;
/* NOTREACHED */
case RTM_NEWADDR:
case RTM_DELADDR:
ifam = (struct ifa_msghdr *)rtm;
/* address related checks */
sa = (struct sockaddr *)(ifam + 1);
get_rtaddrs(ifam->ifam_addrs, sa, rti_info);
if ((ifa = rti_info[RTAX_IFA]) == NULL ||
(ifa->sa_family != AF_INET &&
ifa->sa_family != AF_INET6))
continue;
if (ifa->sa_family == AF_INET6 &&
(IN6_IS_ADDR_LINKLOCAL(&SIN6(ifa)->sin6_addr) ||
IN6_IS_ADDR_MULTICAST(&SIN6(ifa)->sin6_addr)))
continue;
if (ifindex && ifam->ifam_index != ifindex)
continue;
/* found */
*lenp = ifam->ifam_msglen;
return (char *)rtm;
/* NOTREACHED */
case RTM_IFINFO:
/* found */
*lenp = rtm->rtm_msglen;
return (char *)rtm;
/* NOTREACHED */
}
}
return (char *)rtm;
}
#undef FILTER_MATCH(type, filter)
struct in6_addr *
get_addr(char *buf)
{
struct rt_msghdr *rtm = (struct rt_msghdr *)buf;
struct sockaddr *sa, *rti_info[RTAX_MAX];
sa = (struct sockaddr *)(rtm + 1);
get_rtaddrs(rtm->rtm_addrs, sa, rti_info);
return(&SIN6(rti_info[RTAX_DST])->sin6_addr);
}
int
get_rtm_ifindex(char *buf)
{
struct rt_msghdr *rtm = (struct rt_msghdr *)buf;
struct sockaddr *sa, *rti_info[RTAX_MAX];
sa = (struct sockaddr *)(rtm + 1);
get_rtaddrs(rtm->rtm_addrs, sa, rti_info);
return(((struct sockaddr_dl *)rti_info[RTAX_GATEWAY])->sdl_index);
}
int
get_ifm_ifindex(char *buf)
{
struct if_msghdr *ifm = (struct if_msghdr *)buf;
return ((int)ifm->ifm_index);
}
int
get_ifam_ifindex(char *buf)
{
struct ifa_msghdr *ifam = (struct ifa_msghdr *)buf;
return ((int)ifam->ifam_index);
}
int
get_ifm_flags(char *buf)
{
struct if_msghdr *ifm = (struct if_msghdr *)buf;
return (ifm->ifm_flags);
}
int
get_prefixlen(char *buf)
{
struct rt_msghdr *rtm = (struct rt_msghdr *)buf;
struct sockaddr *sa, *rti_info[RTAX_MAX];
int masklen;
u_char *p, *lim;
sa = (struct sockaddr *)(rtm + 1);
get_rtaddrs(rtm->rtm_addrs, sa, rti_info);
sa = rti_info[RTAX_NETMASK];
p = (u_char *)(&SIN6(sa)->sin6_addr);
lim = (u_char *)sa + sa->sa_len;
for (masklen = 0; p < lim; p++) {
switch (*p) {
case 0xff:
masklen += 8;
break;
case 0xfe:
masklen += 7;
break;
case 0xfc:
masklen += 6;
break;
case 0xf8:
masklen += 5;
break;
case 0xf0:
masklen += 4;
break;
case 0xe0:
masklen += 3;
break;
case 0xc0:
masklen += 2;
break;
case 0x80:
masklen += 1;
break;
case 0x00:
break;
default:
return(-1);
}
}
return(masklen);
}
int
rtmsg_type(char *buf)
{
struct rt_msghdr *rtm = (struct rt_msghdr *)buf;
return(rtm->rtm_type);
}
int
rtmsg_len(char *buf)
{
struct rt_msghdr *rtm = (struct rt_msghdr *)buf;
return(rtm->rtm_msglen);
}
int
ifmsg_len(char *buf)
{
struct if_msghdr *ifm = (struct if_msghdr *)buf;
return(ifm->ifm_msglen);
}
/*
* alloc buffer and get if_msghdrs block from kernel,
* and put them into the buffer
*/
static void
get_iflist(char **buf, size_t *size)
{
int mib[6];
mib[0] = CTL_NET;
mib[1] = PF_ROUTE;
mib[2] = 0;
mib[3] = AF_INET6;
mib[4] = NET_RT_IFLIST;
mib[5] = 0;
if (sysctl(mib, 6, NULL, size, NULL, 0) < 0) {
syslog(LOG_ERR, "<%s> sysctl: iflist size get failed",
__FUNCTION__);
exit(1);
}
if ((*buf = malloc(*size)) == NULL) {
syslog(LOG_ERR, "<%s> malloc failed", __FUNCTION__);
exit(1);
}
if (sysctl(mib, 6, *buf, size, NULL, 0) < 0) {
syslog(LOG_ERR, "<%s> sysctl: iflist get failed",
__FUNCTION__);
exit(1);
}
return;
}
/*
* alloc buffer and parse if_msghdrs block passed as arg,
* and init the buffer as list of pointers ot each of the if_msghdr.
*/
static void
parse_iflist(struct if_msghdr ***ifmlist_p, char *buf, size_t bufsize)
{
int iflentry_size, malloc_size;
struct if_msghdr *ifm;
struct ifa_msghdr *ifam;
char *lim;
/*
* Estimate least size of an iflist entry, to be obtained from kernel.
* Should add sizeof(sockaddr) ??
*/
iflentry_size = sizeof(struct if_msghdr);
/* roughly estimate max list size of pointers to each if_msghdr */
malloc_size = (bufsize/iflentry_size) * sizeof(size_t);
if ((*ifmlist_p = (struct if_msghdr **)malloc(malloc_size)) == NULL) {
syslog(LOG_ERR, "<%s> malloc failed", __FUNCTION__);
exit(1);
}
lim = buf + bufsize;
for (ifm = (struct if_msghdr *)buf; ifm < (struct if_msghdr *)lim;) {
if (ifm->ifm_msglen == 0) {
syslog(LOG_WARNING, "<%s> ifm_msglen is 0 "
"(buf=%p lim=%p ifm=%p)", __FUNCTION__,
buf, lim, ifm);
return;
}
if (ifm->ifm_type == RTM_IFINFO) {
(*ifmlist_p)[ifm->ifm_index] = ifm;
} else {
syslog(LOG_ERR, "out of sync parsing NET_RT_IFLIST\n"
"expected %d, got %d\n msglen = %d\n"
"buf:%p, ifm:%p, lim:%p\n",
RTM_IFINFO, ifm->ifm_type, ifm->ifm_msglen,
buf, ifm, lim);
exit (1);
}
for (ifam = (struct ifa_msghdr *)
((char *)ifm + ifm->ifm_msglen);
ifam < (struct ifa_msghdr *)lim;
ifam = (struct ifa_msghdr *)
((char *)ifam + ifam->ifam_msglen)) {
/* just for safety */
if (!ifam->ifam_msglen) {
syslog(LOG_WARNING, "<%s> ifa_msglen is 0 "
"(buf=%p lim=%p ifam=%p)", __FUNCTION__,
buf, lim, ifam);
return;
}
if (ifam->ifam_type != RTM_NEWADDR)
break;
}
ifm = (struct if_msghdr *)ifam;
}
}
void
init_iflist()
{
if (ifblock) {
free(ifblock);
ifblock_size = 0;
}
if (iflist)
free(iflist);
/* get iflist block from kernel */
get_iflist(&ifblock, &ifblock_size);
/* make list of pointers to each if_msghdr */
parse_iflist(&iflist, ifblock, ifblock_size);
}

57
usr.sbin/rtadvd/if.h Normal file
View File

@ -0,0 +1,57 @@
/*
* 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$
*/
#define RTADV_TYPE2BITMASK(type) (0x1 << type)
extern struct if_msghdr **iflist;
extern size_t ifblock_size;
extern char *ifblock;
struct sockaddr_dl *if_nametosdl __P((char *name));
int if_getmtu __P((char *name));
int if_getflags __P((int ifindex, int oifflags));
int lladdropt_length __P((struct sockaddr_dl *sdl));
void lladdropt_fill __P((struct sockaddr_dl *sdl, struct nd_opt_hdr *ndopt));
int rtbuf_len __P((void));
int get_rtinfo __P((char *buf, size_t *len));
char *get_next_msg __P((char *buf, char *lim, int ifindex, size_t *lenp,
int filter));
struct in6_addr *get_addr __P((char *buf));
int get_rtm_ifindex __P((char *buf));
int get_ifm_ifindex __P((char *buf));
int get_ifam_ifindex __P((char *buf));
int get_ifm_flags __P((char *buf));
int get_prefixlen __P((char *buf));
int rtmsg_type __P((char *buf));
int ifmsg_type __P((char *buf));
int rtmsg_len __P((char *buf));
int ifmsg_len __P((char *buf));
void init_iflist __P((void));

View File

@ -0,0 +1,2 @@
/* $FreeBSD$ */
#define _PATH_RTADVDCONF "/usr/local/v6/etc/rtadvd.conf"

414
usr.sbin/rtadvd/rrenum.c Normal file
View File

@ -0,0 +1,414 @@
/*
* 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.
*
* $FreeBSD$
*/
#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/sysctl.h>
#include <net/if.h>
#include <net/if_var.h>
#include <net/route.h>
#include <netinet/in.h>
#include <netinet/in_var.h>
#include <netinet/icmp6.h>
#include <arpa/inet.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <syslog.h>
#include "rrenum.h"
#include "if.h"
#define RR_ISSET_SEGNUM(segnum_bits, segnum) \
((((segnum_bits)[(segnum) >> 5]) & (1 << ((segnum) & 31))) != 0)
#define RR_SET_SEGNUM(segnum_bits, segnum) \
(((segnum_bits)[(segnum) >> 5]) |= (1 << ((segnum) & 31)))
struct rr_operation {
u_long rro_seqnum;
u_long rro_segnum_bits[8];
};
static struct rr_operation rro;
static int rr_rcvifindex;
static int rrcmd2pco[4] = {0,
SIOCAIFPREFIX_IN6,
SIOCCIFPREFIX_IN6,
SIOCSGIFPREFIX_IN6
};
static int s;
/*
* Check validity of a Prefix Control Operation(PCO).
* Return 0 on success, 1 on failure.
*/
static int
rr_pco_check(int len, struct rr_pco_match *rpm)
{
struct rr_pco_use *rpu, *rpulim;
int checklen;
/* rpm->rpm_len must be (4N * 3) as router-renum-05.txt */
if ((rpm->rpm_len - 3) < 0 || /* must be at least 3 */
(rpm->rpm_len - 3) & 0x3) { /* must be multiple of 4 */
syslog(LOG_WARNING, "<%s> rpm_len %d is not 4N * 3",
__FUNCTION__, rpm->rpm_len);
return 1;
}
/* rpm->rpm_code must be valid value */
switch(rpm->rpm_code) {
case RPM_PCO_ADD:
case RPM_PCO_CHANGE:
case RPM_PCO_SETGLOBAL:
break;
default:
syslog(LOG_WARNING, "<%s> unknown rpm_code %d", __FUNCTION__,
rpm->rpm_code);
return 1;
}
/* rpm->rpm_matchlen must be 0 to 128 inclusive */
if (rpm->rpm_matchlen > 128) {
syslog(LOG_WARNING, "<%s> rpm_matchlen %d is over 128",
__FUNCTION__, rpm->rpm_matchlen);
return 1;
}
/*
* rpu->rpu_uselen, rpu->rpu_keeplen, and sum of them must be
* between 0 and 128 inclusive
*/
for (rpu = (struct rr_pco_use *)(rpm + 1),
rpulim = (struct rr_pco_use *)((char *)rpm + len);
rpu < rpulim;
rpu += 1) {
checklen = rpu->rpu_uselen;
checklen += rpu->rpu_keeplen;
/*
* omit these check, because either of rpu_uselen
* and rpu_keeplen is unsigned char
* (128 > rpu_uselen > 0)
* (128 > rpu_keeplen > 0)
* (rpu_uselen + rpu_keeplen > 0)
*/
if (checklen > 128) {
syslog(LOG_WARNING, "<%s> sum of rpu_uselen %d and"
" rpu_keeplen %d is %d(over 128)",
__FUNCTION__, rpu->rpu_uselen,
rpu->rpu_keeplen,
rpu->rpu_uselen + rpu->rpu_keeplen);
return 1;
}
}
return 0;
}
static void
do_use_prefix(int len, struct rr_pco_match *rpm, struct in6_rrenumreq *irr) {
struct rr_pco_use *rpu, *rpulim;
rpu = (struct rr_pco_use *)(rpm + 1);
rpulim = (struct rr_pco_use *)((char *)rpm + len);
if (rpu == rpulim) {
if (rpm->rpm_code == RPM_PCO_ADD)
return;
irr->irr_u_uselen = 0;
irr->irr_u_keeplen = 0;
irr->irr_raf_mask_onlink = 0;
irr->irr_raf_mask_auto = 0;
irr->irr_vltime = 0;
irr->irr_pltime = 0;
memset(&irr->irr_flags, 0, sizeof(irr->irr_flags));
irr->irr_useprefix.sin6_len = 0; /* let it mean, no addition */
irr->irr_useprefix.sin6_family = 0;
irr->irr_useprefix.sin6_addr = in6addr_any;
if (ioctl(s, rrcmd2pco[rpm->rpm_code], (caddr_t)irr) < 0 &&
errno != EADDRNOTAVAIL)
syslog(LOG_ERR, "<%s> ioctl: %s", __FUNCTION__,
strerror(errno));
return;
}
for (rpu = (struct rr_pco_use *)(rpm + 1),
rpulim = (struct rr_pco_use *)((char *)rpm + len);
rpu < rpulim;
rpu += 1) {
/* init in6_rrenumreq fields */
irr->irr_u_uselen = rpu->rpu_uselen;
irr->irr_u_keeplen = rpu->rpu_keeplen;
irr->irr_raf_mask_onlink =
(rpu->rpu_ramask & ICMP6_RR_PCOUSE_RAFLAGS_ONLINK);
irr->irr_raf_mask_auto =
(rpu->rpu_ramask & ICMP6_RR_PCOUSE_RAFLAGS_AUTO);
irr->irr_vltime = rpu->rpu_vltime;
irr->irr_pltime = rpu->rpu_pltime;
irr->irr_raf_onlink =
(rpu->rpu_raflags & ICMP6_RR_PCOUSE_RAFLAGS_ONLINK);
irr->irr_raf_auto =
(rpu->rpu_raflags & ICMP6_RR_PCOUSE_RAFLAGS_AUTO);
irr->irr_rrf_decrvalid =
(rpu->rpu_flags & ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME);
irr->irr_rrf_decrprefd =
(rpu->rpu_flags & ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME);
irr->irr_useprefix.sin6_len = sizeof(irr->irr_useprefix);
irr->irr_useprefix.sin6_family = AF_INET6;
irr->irr_useprefix.sin6_addr = rpu->rpu_prefix;
if (ioctl(s, rrcmd2pco[rpm->rpm_code], (caddr_t)irr) < 0 &&
errno != EADDRNOTAVAIL)
syslog(LOG_ERR, "<%s> ioctl: %s", __FUNCTION__,
strerror(errno));
}
}
/*
* process a Prefix Control Operation(PCO).
* return 0 on success, 1 on failure
*/
static int
do_pco(struct icmp6_router_renum *rr, int len, struct rr_pco_match *rpm)
{
int ifindex = 0;
struct in6_rrenumreq irr;
if ((rr_pco_check(len, rpm) != NULL))
return 1;
if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
syslog(LOG_ERR, "<%s> socket: %s", __FUNCTION__,
strerror(errno));
exit(1);
}
memset(&irr, 0, sizeof(irr));
irr.irr_origin = PR_ORIG_RR;
irr.irr_m_len = rpm->rpm_matchlen;
irr.irr_m_minlen = rpm->rpm_minlen;
irr.irr_m_maxlen = rpm->rpm_maxlen;
irr.irr_matchprefix.sin6_len = sizeof(irr.irr_matchprefix);
irr.irr_matchprefix.sin6_family = AF_INET6;
irr.irr_matchprefix.sin6_addr = rpm->rpm_prefix;
while (if_indextoname(++ifindex, irr.irr_name)) {
/*
* if ICMP6_RR_FLAGS_FORCEAPPLY(A flag) is 0 and IFF_UP is off,
* the interface is not applied
*/
if ((rr->rr_flags & ICMP6_RR_FLAGS_FORCEAPPLY) == 0 &&
(iflist[ifindex]->ifm_flags & IFF_UP) == 0)
continue;
/* TODO: interface scope check */
do_use_prefix(len, rpm, &irr);
}
if (errno == ENXIO)
return 0;
else if (errno) {
syslog(LOG_ERR, "<%s> if_indextoname: %s", __FUNCTION__,
strerror(errno));
return 1;
}
return 0;
}
/*
* call do_pco() for each Prefix Control Operations(PCOs) in a received
* Router Renumbering Command packet.
* return 0 on success, 1 on failure
*/
static int
do_rr(int len, struct icmp6_router_renum *rr)
{
struct rr_pco_match *rpm;
char *cp, *lim;
lim = (char *)rr + len;
cp = (char *)(rr + 1);
len -= sizeof(struct icmp6_router_renum);
/* get iflist block from kernel again, to get up-to-date information */
init_iflist();
while (cp < lim) {
int rpmlen;
rpm = (struct rr_pco_match *)cp;
if (len < sizeof(struct rr_pco_match)) {
tooshort:
syslog(LOG_ERR, "<%s> pkt too short. left len = %d. "
"gabage at end of pkt?", __FUNCTION__, len);
return 1;
}
rpmlen = rpm->rpm_len << 3;
if (len < rpmlen)
goto tooshort;
if (do_pco(rr, rpmlen, rpm)) {
syslog(LOG_WARNING, "<%s> invalid PCO", __FUNCTION__);
goto next;
}
next:
cp += rpmlen;
len -= rpmlen;
}
return 0;
}
/*
* check validity of a router renumbering command packet
* return 0 on success, 1 on failure
*/
static int
rr_command_check(int len, struct icmp6_router_renum *rr, struct in6_addr *from,
struct in6_addr *dst)
{
u_char ntopbuf[INET6_ADDRSTRLEN];
/* omit rr minimal length check. hope kernel have done it. */
/* rr_command length check */
if (len < (sizeof(struct icmp6_router_renum) +
sizeof(struct rr_pco_match))) {
syslog(LOG_ERR, "<%s> rr_command len %d is too short",
__FUNCTION__, len);
return 1;
}
/* destination check. only for multicast. omit unicast check. */
if (IN6_IS_ADDR_MULTICAST(dst) && !IN6_IS_ADDR_MC_LINKLOCAL(dst) &&
!IN6_IS_ADDR_MC_SITELOCAL(dst)) {
syslog(LOG_ERR, "<%s> dst mcast addr %s is illegal",
__FUNCTION__,
inet_ntop(AF_INET6, dst, ntopbuf, INET6_ADDRSTRLEN));
return 1;
}
/* seqnum and segnum check */
if (rro.rro_seqnum > rr->rr_seqnum) {
syslog(LOG_WARNING,
"<%s> rcvd old seqnum %d from %s",
__FUNCTION__, (u_int32_t)ntohl(rr->rr_seqnum),
inet_ntop(AF_INET6, from, ntopbuf, INET6_ADDRSTRLEN));
return 1;
}
if (rro.rro_seqnum == rr->rr_seqnum &&
(rr->rr_flags & ICMP6_RR_FLAGS_TEST) == 0 &&
RR_ISSET_SEGNUM(rro.rro_segnum_bits, rr->rr_segnum)) {
if ((rr->rr_flags & ICMP6_RR_FLAGS_REQRESULT) != 0)
syslog(LOG_WARNING,
"<%s> rcvd duped segnum %d from %s",
__FUNCTION__, rr->rr_segnum,
inet_ntop(AF_INET6, from, ntopbuf,
INET6_ADDRSTRLEN));
return 0;
}
/* update seqnum */
if (rro.rro_seqnum != rr->rr_seqnum) {
/* then must be "<" */
/* init rro_segnum_bits */
memset(rro.rro_segnum_bits, 0,
sizeof(rro.rro_segnum_bits));
}
rro.rro_seqnum = rr->rr_seqnum;
return 0;
}
static void
rr_command_input(int len, struct icmp6_router_renum *rr,
struct in6_addr *from, struct in6_addr *dst)
{
/* rr_command validity check */
if (rr_command_check(len, rr, from, dst))
goto failed;
if ((rr->rr_flags & (ICMP6_RR_FLAGS_TEST|ICMP6_RR_FLAGS_REQRESULT)) ==
ICMP6_RR_FLAGS_TEST)
return;
/* do router renumbering */
if (do_rr(len, rr)) {
goto failed;
}
/* update segnum */
RR_SET_SEGNUM(rro.rro_segnum_bits, rr->rr_segnum);
return;
failed:
syslog(LOG_ERR, "<%s> received RR was invalid", __FUNCTION__);
return;
}
void
rr_input(int len, struct icmp6_router_renum *rr, struct in6_pktinfo *pi,
struct sockaddr_in6 *from, struct in6_addr *dst)
{
u_char ntopbuf[2][INET6_ADDRSTRLEN], ifnamebuf[IFNAMSIZ];
syslog(LOG_DEBUG,
"<%s> RR received from %s to %s on %s",
__FUNCTION__,
inet_ntop(AF_INET6, &from->sin6_addr,
ntopbuf[0], INET6_ADDRSTRLEN),
inet_ntop(AF_INET6, &dst, ntopbuf[1], INET6_ADDRSTRLEN),
if_indextoname(pi->ipi6_ifindex, ifnamebuf));
rr_rcvifindex = pi->ipi6_ifindex;
/* TODO: some consistency check. */
switch (rr->rr_code) {
case ICMP6_ROUTER_RENUMBERING_COMMAND:
rr_command_input(len, rr, &from->sin6_addr, dst);
/* TODO: send reply msg */
break;
case ICMP6_ROUTER_RENUMBERING_RESULT:
/* RESULT will be processed by rrenumd */
break;
case ICMP6_ROUTER_RENUMBERING_SEQNUM_RESET:
/* TODO: sequence number reset */
break;
default:
syslog(LOG_ERR, "<%s> received unknown code %d",
__FUNCTION__, rr->rr_code);
break;
}
return;
}

34
usr.sbin/rtadvd/rrenum.h Normal file
View File

@ -0,0 +1,34 @@
/*
* Copyright (C) 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.
*
* $FreeBSD$
*/
void rr_input __P((int len, struct icmp6_router_renum *rr,
struct in6_pktinfo *pi, struct sockaddr_in6 *from,
struct in6_addr *dst));

134
usr.sbin/rtadvd/rtadvd.8 Normal file
View File

@ -0,0 +1,134 @@
.\" 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.
.\"
.\" $Id: rtadvd.8,v 1.1.1.1 1999/08/08 23:31:42 itojun Exp $
.\" $FreeBSD$
.\"
.Dd May 17, 1998
.Dt RTADVD 8
.Os KAME
.Sh NAME
.Nm rtadvd
.Nd router advertisement daemon
.Sh SYNOPSIS
.Nm
.Op Fl c Ar configfile
.Op Fl P Ar policy
.Op Fl dDfs
.Ar interface ...
.Sh DESCRIPTION
.Nm Rtadvd
advertises router advertisement packet to the specified
.Ar interfaces .
.Pp
The program will daemonize itself on invocation.
Then, it will voluntarily send router advertisement packet periodically.
If a router solicitation packet from host has reached the program,
the program will respond by router advertisement packet.
.Pp
For each interface, which is called advertising interface,
content of router advertisement can be described in
.Xr rtadvd.conf 5 .
.Pp
If there is no description for the interface in the configuration file
or if the configuration file does not exist,
.Nm
sets all the parameters to their default values.
In particular,
.Nm
gets all the interface routes from the routing table and advertises
them as on-link prefixes.
.Pp
.Nm Rtadvd
watches the routing table.
By default, if an interface direct route is
added/deleted on an advertising interface,
.Nm
adds/deletes the corresponding prefix to/from its advertising list,
respectively.
If you do not want to enable this feature, you should specify the
.Ic Fl s
command line option when advocation.
.Pp
.Nm Rtadvd
can also receive router renumbering packets, and can do router
renumbering for the system it runs on, as the contents of those
packets.
.Bl -tag -width indent
.\"
.It Fl c
Specify an alternate location,
.Ar configfile ,
for the configuration file.
By default,
.Pa /usr/local/v6/etc/rtadvd.conf
is used.
.It Fl P
Specifies that
.Nm
receives router renumbering messages. Also, specifies IPsec policy for
rrenumd sessions. Because router renumbering can change the system's
IPv6 prefix, its messages must be protected by IPsec. For details about
.Ar policy ,
please refer to
.Xr ipsec 4
and
.Xr ipsec_set_policy 3 .
.It Fl d
Debug.
.It Fl D
More debug.
.It Fl f
Foreground mode.
Do not become daemon.
.It Fl s
Static prefix.
Do not watch the routing table.
.El
.Sh RETURN VALUES
The program exits with 0 on success, and non-zero on failures.
.Sh FILES
.Bl -tag -width /usr/local/v6/etc/rtadvd.conf -compact
.It Pa /usr/local/v6/etc/rtadvd.conf
The default configuration file.
.El
.Sh SEE ALSO
.Xr daemon 3 ,
.Xr rtadvd.conf 5 ,
.Xr rtsol 8
.Sh HISTORY
The
.Nm
command first appeared in WIDE Hydrangea IPv6 protocol stack kit.
.Sh CAVEAT
Do not perform router advertisement toward upstream direction,
you should only advertise to downstream direction.
If you advertise toward upstream by mistake,
you will see icmp6 redirect storm on that subnet.
This is because of the specification,
which says that advertising router is assumed to become
the default outgoing router for end hosts in the subnet.

1239
usr.sbin/rtadvd/rtadvd.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,14 @@
# $FreeBSD$
#
# common definitions.
#
default:\
:chlim#64:raflags#0:rltime#1800:rtime#30000:retrans#1000:\
:pinfoflags#192:vltime#3600000:pltime#3600000:mtu#1500:
ether:\
:mtu#1500:tc=default:
#
# interfaces.
#
ef0:\
:addrs#1:addr="fec0:0:0:1000::":prefixlen#64:tc=ether:

View File

@ -0,0 +1,250 @@
.\" 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.
.\"
.\" $Id: rtadvd.conf.5,v 1.1.1.1 1999/08/08 23:31:42 itojun Exp $
.\" $FreeBSD$
.\"
.Dd May 17, 1998
.Dt RTADVD.CONF 5
.Os KAME
.Sh NAME
.Nm rtadvd.conf
.Nd config file for router advertisement daemon
.Sh DESCRIPTION
The file describes how the router advertisement packet must be constructed
for each of the interfaces.
.Pp
It obeys famous
.Xr termcap 5
file format.
Each line in the file describes a network interface.
Fields are separated by a colon
.Po
.Dq \&:
.Pc ,
and each field contains one capability description.
Lines may be concatenated by \e character.
The comment marker is `#' character.
.Pp
.Sh CAPABILITIES
Capabilities describe the value to be filled into ICMPv6 router
advertisement message and to control
.Xr rtadvd 8
behavior.
Therefore, you are encouraged to read IETF neighbor discovery documents
if you would like to modify sample configuration file.
.Pp
Note that almost all items have default values.
If you omit an item, the default value of the item will be used.
.Pp
There are two items to control interval of sending router advertisements.
.Bl -tag -width indent
.It Cm \&maxinterval
(num) The maximum time allowed between sending unsolicited
multicast router advertisements
.Pq unit: seconds .
The default value is 600. Its value must be no less than 4 seconds
and no greater than 1800 seconds.
.It Cm \&mininterval
(num) The minimum time allowed between sending unsolicited multicast
router advertisements
.Pq unit: seconds .
The default value is the one third of value of
.Ic maxinterval.
Its value must be no less than 3 seconds and no greater than .75 *
the value of
.Ic maxinterval.
.El
.Pp
The following items are for ICMPv6 router advertisement message
header.
.Bl -tag -width indent
.It Cm \&chlim
(num) The value for Cur Hop Limit field.
The default value is 64.
.It Cm \&raflags
(num) Flags field in router advertisement message header.
Bit 7
.Po
.Li 0x80
.Pc
means Managed address configuration flag bit,
and Bit 6
.Po
.Li 0x40
.Pc
means Other stateful configuration flag bit.
The default value is 0.
.It Cm \&rltime
(num) Router lifetime field
.Pq unit: seconds .
Its value must be no greater than 3600000.
The default value is 1800.
.It Cm \&rtime
(num) Reachable time field
.Pq unit: milliseconds .
The default value is 0, which means unspecified by this router.
.It Cm \&retrans
(num) Retrans Timer field
.Pq unit: milliseconds .
The default value is 0, which means unspecified by this router.
.El
.Pp
The following items are for ICMPv6 prefix information option,
which will be attached to router advertisement header.
.Bl -tag -width indent
.It Cm \&addrs
(num) Number of prefixes.
Its default is 0, so it must explicitly be set to positve values
if you want to specify any prefix information option.
If its value is 0,
.Xr rtadvd 8
looks up the system routing table and
advertise the prefixes corresponding to interface routes
on the interface.
If its value is more than 1, you must specify the index of the prefix
for each item below.
Indices vary from 0 to N-1, where N is the
value of
.Ic addrs.
Each index shall follows the name of each item, e.g.
.Dq prefixlen2 .
.It Cm \&prefixlen
(num) Prefix length field.
The default value is 64.
.It Cm \&pinfoflags
(num) Flags field in prefix information option.
Bit 7
.Po
.Li 0x80
.Pc
means On-link flag bit,
and Bit 6
.Po
.Li 0x40
.Pc
means Autonomous address-configuration flag bit.
The default value is 0xc0, i.e. both bits are set.
.It Cm \&addr
(str) The address filled into Prefix field.
Since
.Dq \&:
is used for
.Xr termcap 5
file format as well as IPv6 numeric address, the field MUST be quoted by
doublequote character.
This field cannot be
omitted if the value of
.Ic addrs
is more than 0.
.It Cm \&vltime
(num) Valid lifetime field
.Pq unit: seconds .
The default value is 2592000(30 days).
.It Cm \&pltime
(num) Preferred lifetime field
.Pq unit: seconds .
The default value is 604800(7 days).
.El
.Pp
The following items are for ICMPv6 MTU option,
which will be attached to router advertisement header.
.Bl -tag -width indent
.It Cm \&mtu
(num or str) MTU (maximum transmission unit) field.
If 0 is specified, it means that the option will not be included.
The default value is 0. If the special string
.Dq auto
is specified for this item, MTU option will be included and its value
will be set to the interface MTU automatically.
.El
.Pp
The following item controls ICMPv6 source link-layer address option,
which will be attached to router advertisement header.
.Bl -tag -width indent
.It Cm \&nolladdr
(bool) By default
.Po
if
.Cm \&nolladdr
is not specified
.Pc ,
.Xr rtadvd 8
will try to get link-layer address for the interface from the kernel,
and attach that in source link-layer address option.
If this capability exists,
.Xr rtadvd 8
will not attach source link-layer address option to
router advertisement packets.
.El
.Pp
You can also refer one line from another by using
.Cm tc
capability.
See
.Xr termcap 5
for details on the capability.
.Sh EXAMPLE
.Bd -literal -offset
#
# common definitions.
#
default:\\
:raflags#0:rltime#3600:\\
:pinfoflags#64:vltime#360000:pltime#360000:mtu#1500:
ether:\\
:mtu#1280:tc=default:
#
# interfaces.
#
ef0:\\
:addrs#1:\\
:addr="3ffe:501:4819:1000::":tc=ether:
ef1:\\
:addrs#2:addr0="3ffe:501:4819:2000::":\\
:addr1="3ffe:501:4819:3000::":tc=ether:
.Ed
.Sh SEE ALSO
.Xr termcap 5 ,
.Xr rtadvd 8 ,
.Xr rtsol 8
.Pp
Thomas Narten, Erik Nordmark and W. A. Simpson,
.Do
Neighbor Discovery for IP version 6 (IPv6)
.Dc ,
RFC 2461
.Sh HISTORY
The
.Xr rtadvd 8
and the configuration file
.Nm
first appeared in WIDE Hydrangea IPv6 protocol stack kit.
.\" .Sh BUGS
.\" (to be written)

107
usr.sbin/rtadvd/rtadvd.h Normal file
View File

@ -0,0 +1,107 @@
/*
* Copyright (C) 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.
*
* $FreeBSD$
*/
#define ALLNODES "ff02::1"
#define ALLROUTERS "ff02::2"
#define ALLSITEROUTERS "ff05::2"
#define ANY "::"
#define RTSOLLEN 8
/* protocol constants and default values */
#define DEF_MAXRTRADVINTERVAL 600
#define DEF_ADVLINKMTU 0
#define DEF_ADVREACHABLETIME 0
#define DEF_ADVRETRANSTIMER 0
#define DEF_ADVCURHOPLIMIT 64
#define DEF_ADVVALIDLIFETIME 2592000
#define DEF_ADVPREFERREDLIFETIME 604800
#define MAXROUTERLIFETIME 9000
#define MIN_MAXINTERVAL 4
#define MAX_MAXINTERVAL 1800
#define MIN_MININTERVAL 3
#define MAXREACHABLETIME 3600000
#define MAX_INITIAL_RTR_ADVERT_INTERVAL 16
#define MAX_INITIAL_RTR_ADVERTISEMENTS 3
#define MAX_FINAL_RTR_ADVERTISEMENTS 3
#define MIN_DELAY_BETWEEN_RAS 3
#define MAX_RA_DELAY_TIME 500000 /* usec */
struct prefix {
struct prefix *next; /* forward link */
struct prefix *prev; /* previous link */
u_int32_t validlifetime; /* AdvValidLifetime */
u_int32_t preflifetime; /* AdvPreferredLifetime */
u_int onlinkflg; /* bool: AdvOnLinkFlag */
u_int autoconfflg; /* bool: AdvAutonomousFlag */
int prefixlen;
struct in6_addr prefix;
};
struct rainfo {
/* pointer for list */
struct rainfo *next;
/* timer related parameters */
struct rtadvd_timer *timer;
int initcounter; /* counter for the first few advertisements */
struct timeval lastsent; /* timestamp when the lates RA was sent */
int waiting; /* number of RS waiting for RA */
/* interface information */
int ifindex;
int advlinkopt; /* bool: whether include link-layer addr opt */
struct sockaddr_dl *sdl;
char ifname[16];
int phymtu; /* mtu of the physical interface */
/* Router configuration variables */
u_short lifetime; /* AdvDefaultLifetime */
u_int maxinterval; /* MaxRtrAdvInterval */
u_int mininterval; /* MinRtrAdvInterval */
int managedflg; /* AdvManagedFlag */
int otherflg; /* AdvOtherConfigFlag */
u_int32_t linkmtu; /* AdvLinkMTU */
u_int32_t reachabletime; /* AdvReachableTime */
u_int32_t retranstimer; /* AdvRetransTimer */
u_int hoplimit; /* AdvCurHopLimit */
struct prefix prefix; /* AdvPrefixList(link head) */
int pfxs; /* number of prefixes */
/* actual RA packet data and its length */
size_t ra_datalen;
u_char *ra_data;
};
void ra_timeout __P((void *));
void ra_timer_update __P((void *, struct timeval *));

201
usr.sbin/rtadvd/timer.c Normal file
View File

@ -0,0 +1,201 @@
/*
* Copyright (C) 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.
*
* $FreeBSD$
*/
#include <sys/time.h>
#include <unistd.h>
#include <syslog.h>
#include <stdlib.h>
#include <string.h>
#ifdef __NetBSD__
#include <search.h>
#endif
#include "timer.h"
static struct rtadvd_timer timer_head;
#define MILLION 1000000
static struct timeval tm_max = {0x7fffffff, 0x7fffffff};
void
rtadvd_timer_init()
{
memset(&timer_head, 0, sizeof(timer_head));
timer_head.next = timer_head.prev = &timer_head;
timer_head.tm = tm_max;
}
struct rtadvd_timer *
rtadvd_add_timer(void (*timeout) __P((void *)),
void (*update) __P((void *, struct timeval *)),
void *timeodata, void *updatedata)
{
struct rtadvd_timer *newtimer;
if ((newtimer = malloc(sizeof(*newtimer))) == NULL) {
syslog(LOG_ERR,
"<%s> can't allocate memory", __FUNCTION__);
exit(1);
}
memset(newtimer, 0, sizeof(*newtimer));
if (timeout == NULL) {
syslog(LOG_ERR,
"<%s> timeout function unspecfied", __FUNCTION__);
exit(1);
}
if (update == NULL) {
syslog(LOG_ERR,
"<%s> update function unspecfied", __FUNCTION__);
exit(1);
}
newtimer->expire = timeout;
newtimer->update = update;
newtimer->expire_data = timeodata;
newtimer->update_data = updatedata;
newtimer->tm = tm_max;
/* link into chain */
insque(newtimer, &timer_head);
return(newtimer);
}
void
rtadvd_set_timer(struct timeval *tm, struct rtadvd_timer *timer)
{
struct timeval now;
/* reset the timer */
gettimeofday(&now, NULL);
TIMEVAL_ADD(&now, tm, &timer->tm);
/* update the next expiration time */
if (TIMEVAL_LT(timer->tm, timer_head.tm))
timer_head.tm = timer->tm;
return;
}
/*
* Check expiration for each timer. If a timer is expired,
* call the expire function for the timer and update the timer.
* Return the next interval for select() call.
*/
struct timeval *
rtadvd_check_timer()
{
static struct timeval returnval;
struct timeval now;
struct rtadvd_timer *tm = timer_head.next;
gettimeofday(&now, NULL);
timer_head.tm = tm_max;
while(tm != &timer_head) {
if (TIMEVAL_LEQ(tm->tm, now)) {
(*tm->expire)(tm->expire_data);
(*tm->update)(tm->update_data, &tm->tm);
TIMEVAL_ADD(&tm->tm, &now, &tm->tm);
}
if (TIMEVAL_LT(tm->tm, timer_head.tm))
timer_head.tm = tm->tm;
tm = tm->next;
}
if (TIMEVAL_LT(timer_head.tm, now)) {
/* this may occur when the interval is too small */
returnval.tv_sec = returnval.tv_usec = 0;
}
else
TIMEVAL_SUB(&timer_head.tm, &now, &returnval);
return(&returnval);
}
struct timeval *
rtadvd_timer_rest(struct rtadvd_timer *timer)
{
static struct timeval returnval, now;
gettimeofday(&now, NULL);
if (TIMEVAL_LEQ(timer->tm, now)) {
syslog(LOG_DEBUG,
"<%s> a timer must be expired, but not yet",
__FUNCTION__);
returnval.tv_sec = returnval.tv_usec = 0;
}
else
TIMEVAL_SUB(&timer->tm, &now, &returnval);
return(&returnval);
}
/* result = a + b */
void
TIMEVAL_ADD(struct timeval *a, struct timeval *b, struct timeval *result)
{
long l;
if ((l = a->tv_usec + b->tv_usec) < MILLION) {
result->tv_usec = l;
result->tv_sec = a->tv_sec + b->tv_sec;
}
else {
result->tv_usec = l - MILLION;
result->tv_sec = a->tv_sec + b->tv_sec + 1;
}
}
/*
* result = a - b
* XXX: this function assumes that a >= b.
*/
void
TIMEVAL_SUB(struct timeval *a, struct timeval *b, struct timeval *result)
{
long l;
if ((l = a->tv_usec - b->tv_usec) >= 0) {
result->tv_usec = l;
result->tv_sec = a->tv_sec - b->tv_sec;
}
else {
result->tv_usec = MILLION + l;
result->tv_sec = a->tv_sec - b->tv_sec - 1;
}
}

63
usr.sbin/rtadvd/timer.h Normal file
View File

@ -0,0 +1,63 @@
/*
* Copyright (C) 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.
*
* $FreeBSD$
*/
/* a < b */
#define TIMEVAL_LT(a, b) (((a).tv_sec < (b).tv_sec) ||\
(((a).tv_sec == (b).tv_sec) && \
((a).tv_usec < (b).tv_usec)))
/* a <= b */
#define TIMEVAL_LEQ(a, b) (((a).tv_sec < (b).tv_sec) ||\
(((a).tv_sec == (b).tv_sec) &&\
((a).tv_usec <= (b).tv_usec)))
struct rtadvd_timer {
struct rtadvd_timer *next;
struct rtadvd_timer *prev;
struct rainfo *rai;
struct timeval tm;
void (*expire) __P((void *)); /* expiration function */
void *expire_data;
void (*update) __P((void *, struct timeval *)); /* update function */
void *update_data;
};
void rtadvd_timer_init __P((void));
struct rtadvd_timer *rtadvd_add_timer __P((void (*) __P((void *)),
void (*) __P((void *, struct timeval *)), void *, void *));
void rtadvd_set_timer __P((struct timeval *, struct rtadvd_timer *));
struct timeval * rtadvd_check_timer __P((void));
struct timeval * rtadvd_timer_rest __P((struct rtadvd_timer *));
void TIMEVAL_ADD __P((struct timeval *, struct timeval *,
struct timeval *));
void TIMEVAL_SUB __P((struct timeval *, struct timeval *,
struct timeval *));

56
usr.sbin/setkey/Makefile Normal file
View File

@ -0,0 +1,56 @@
# 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
LDADD+= -ll -ly
CLEANFILES+= y.tab.c y.tab.h key_test.o keytest
YFLAGS+=-d
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}
LDADD+= -lipsec
CLEANFILES+= scriptdump y.tab.h
MAN8= setkey.8
LOCALPREFIX= /usr/local
scriptdump: scriptdump.pl
sed -e 's#@LOCALPREFIX@#${LOCALPREFIX}#' < $> > scriptdump
.include <bsd.prog.mk>

787
usr.sbin/setkey/parse.y Normal file
View File

@ -0,0 +1,787 @@
/*
* 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 <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <net/route.h>
#include <netinet/in.h>
#include <net/pfkeyv2.h>
#include <netkey/key_var.h>
#include <netinet6/ipsec.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <ctype.h>
#include <errno.h>
#include <netdb.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_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;
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));
extern int setkeymsg __P((void));
extern int sendkeymsg __P((void));
extern int yylex __P((void));
extern void yyerror __P((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 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 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
%%
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
;
/* get command */
get_command
: GET { p_type = SADB_GET; }
sa_selector_spec extension_spec 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)
p_ext |= SADB_X_EXT_OLD;
else
p_ext &= ~SADB_X_EXT_OLD;
}
| PR_AH
{
p_satype = SADB_SATYPE_AH;
if ($1.num == 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; }
| HEXSTRING
{
caddr_t bp;
caddr_t yp = $1.val.buf;
char buf0[4], buf[4];
int i, j;
/* sanity check */
if ($1.val.len > 4) {
yyerror("SPI too big.");
free($1.val.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--)
buf[i] = buf0[j];
/* XXX: endian */
p_spi = ntohl(*(u_int32_t *)buf);
free($1.val.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_RAWCPI { p_ext |= SADB_X_EXT_RAWCPI; }
;
enc_alg
: ALG_ENC { p_alg_enc = $1.num; }
| ALG_ENC_DESDERIV
{
p_alg_enc = $1.num;
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;
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 = 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; }
;
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 = 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;
/* free pp_key later */
}
| HEXSTRING
{
caddr_t bp;
caddr_t yp = $1.val.buf;
if ((pp_key = malloc($1.val.len)) == 0) {
free($1.val.buf);
yyerror(strerror(errno));
return -1;
}
memset(pp_key, 0, $1.val.len);
bp = pp_key;
while (*yp) {
*bp = (ATOX(yp[0]) << 4) | ATOX(yp[1]);
yp += 2, bp++;
}
free($1.val.buf);
}
;
extension_spec
: /*NOTHING*/
| extension_spec extension
;
extension
: F_EXT EXTENSION { p_ext |= $1.num; }
| F_MODE MODE { p_mode = $2.num; }
| F_MODE ANY { p_mode = IPSEC_MODE_ANY; }
| F_REPLAY DECSTRING
{
if (p_ext & SADB_X_EXT_OLD) {
yyerror("replay prevention "
"only use on new spec.");
return -1;
}
p_replay = $2.num;
}
| F_LIFETIME_HARD DECSTRING { p_lt_hard = $2.num; }
| F_LIFETIME_SOFT DECSTRING { p_lt_soft = $2.num; }
;
/* 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
;
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); }
ipaddress { p_dst = pp_addr; }
prefix { p_prefd = pp_prefix; }
port { _INPORTBYSA(p_dst) = htons(pp_port); }
upper_spec
;
ipaddress
: IP4_ADDRESS
{
struct sockaddr_in *in;
u_int sa_len = $1.val.len;
if ((in = (struct sockaddr_in *)malloc(sa_len)) == 0) {
yyerror(strerror(errno));
free($1.val.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;
}
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);
freeaddrinfo(res);
pp_addr = (struct sockaddr *)in6;
#else
yyerror("IPv6 address not supported");
#endif
free($1.val.buf);
}
;
prefix
: /*NOTHING*/ { pp_prefix = ~0; }
| PREFIX { pp_prefix = $1.num; }
;
port
: /*NOTHING*/ { pp_port = IPSEC_PORT_ANY; }
| PORT { pp_port = $1.num; }
| PORTANY { pp_port = IPSEC_PORT_ANY; }
;
upper_spec
: DECSTRING { p_upper = $1.num; }
| UP_PROTO { p_upper = $1.num; }
| 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);
if (p_policy == NULL) {
free($2.val.buf);
p_policy = NULL;
yyerror(ipsec_strerror());
return -1;
}
p_policy_len = ipsec_get_policylen(p_policy);
free($2.val.buf);
}
;
policy_requests:
/*NOTHING*/
| 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_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;
/* 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;
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;
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:
{
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;
m_addr.sadb_address_prefixlen =
(p_prefs != ~0 ? p_prefs :
_INALENBYAF(p_src->sa_family) << 3);
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;
m_addr.sadb_address_prefixlen =
(p_prefd != ~0 ? p_prefd :
_INALENBYAF(p_dst->sa_family) << 3);
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 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_alg_enc = SADB_EALG_NONE;
p_alg_auth = SADB_AALG_NONE;
p_mode = IPSEC_MODE_ANY;
p_replay = 4;
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;
}

219
usr.sbin/setkey/sample.cf Normal file
View File

@ -0,0 +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 ;
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 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.

View File

@ -0,0 +1,54 @@
#! @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 $_ (<IN>) {
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 (/^\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=/) {
print "$mode $src $dst $proto $spi -m $ipsecmode";
print " -r $replay" if $replay;
if ($mode eq 'add') {
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;

550
usr.sbin/setkey/setkey.8 Normal file
View File

@ -0,0 +1,550 @@
.\" 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 KAME
.\"
.Sh NAME
.Nm setkey
.Nd manually manipulate the 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.
.Pp
.Nm
takes a series of operation from standard input
.Po
if invoked with
.Fl c
.Pc
or 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.
If with
.Fl P ,
the SPD are flushed.
.It Fl a
.Nm
usually do not display dead SAD entries on
.Fl D .
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.
.It Fl d
Enable debugging messages.
.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.
.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.
.\"
.It Xo
.Li get
.Ar src Ar dst Ar protocol Ar spi
.Op Ar mode
.Li ;
.Xc
Show a SAD entry.
.\"
.It Xo
.Li delete
.Ar src Ar dst Ar protocol Ar spi
.Op Ar mode
.Li ;
.Xc
Remove a SAD entry.
.\"
.It Xo
.Li flush
.Op Ar protocol
.Li ;
.Xc
Clear all SAD entries that matches the options.
.\"
.It Xo
.Li dump
.Op Ar protocol
.Li ;
.Xc
Dumps all SAD entries that matches the options.
.\"
.It Xo
.Li spdadd
.Ar src_range Ar dst_range Ar upperspec Ar policy
.Li ;
.Xc
Add a SPD entry.
.\"
.It Xo
.Li spddelete
.Ar src_range Ar dst_range Ar upperspec
.Li ;
.Xc
Delete a SPD entry.
.\"
.It Xo
.Li spdflush
.Li ;
.Xc
Clear all SPD entries.
.\"
.It Xo
.Li spddump
.Li ;
.Xc
Dumps all SAD 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.
It must be decimal number or hexadecimal number
.Po
with
.Li 0x
attached
.Pc .
.\"
.Pp
.It Ar extensions
takes 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 .
.Ar mode
is one of following:
.Li transport , tunnel
or
.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 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 lh Ar time
.It Fl ls Ar time
Specify hard/soft lifetime.
.El
.\"
.Pp
.It Ar algorithm
.Bl -tag -width Fl -compact
.It Fl E Ar ealgo Ar key
Specify encryption algorithm.
.It Fl A Ar ealgo 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
.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,
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.
.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
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 .
.\"
.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
specified, e.g.
.Li esp_trans_deflev
sysctl variable, when kernel processes the packet.
.Li use
means that kernel use a SA if it's available,
otherwise kernel keeps normal operation.
.Li require
means SA is required whenever 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
.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
.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
.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.
.\"
.\" .Sh BUGS

566
usr.sbin/setkey/setkey.c Normal file
View File

@ -0,0 +1,566 @@
/*
* 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 <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <err.h>
#include <net/route.h>
#include <netinet/in.h>
#include <net/pfkeyv2.h>
#include <netkey/keydb.h>
#include <netkey/key_debug.h>
#include <netinet6/ipsec.h>
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <errno.h>
#include <netdb.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
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;
u_char m_buf[BUFSIZ];
u_int m_len;
extern int lineno;
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);
}
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*/
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);
break;
default:
Usage();
}
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)
kdebug_sadb((struct sadb_msg *)m_buf);
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)
kdebug_sadb((struct sadb_msg *)rbuf);
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)
kdebug_sadb((struct sadb_msg *)msg);
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)
kdebug_sadb((struct sadb_msg *)msg);
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");
}

View File

@ -0,0 +1,480 @@
/*
* 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 <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <net/route.h>
#include <net/pfkeyv2.h>
#include <netinet/in.h>
#include <netkey/keydb.h>
#include <netkey/key_var.h>
#include <netkey/key_debug.h>
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <errno.h>
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()
{
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;
}
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;
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;
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 (type) {
case SADB_GETSPI:
/*<base, address(SD), SPI range>*/
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();
/*<base, SA(*), address(SD)>*/
break;
case SADB_ADD:
/* <base, SA, (lifetime(HSC),) address(SD), (address(P),)
key(AE), (identity(SD),) (sensitivity)> */
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();
/* <base, SA, (lifetime(HSC),) address(SD), (address(P),)
(identity(SD),) (sensitivity)> */
break;
case SADB_DELETE:
/* <base, SA(*), address(SDP)> */
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");
/* <base, SA(*), address(SDP)> */
break;
case SADB_GET:
/* <base, SA(*), address(SDP)> */
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");
/* <base, SA, (lifetime(HSC),) address(SD), (address(P),)
key(AE), (identity(SD),) (sensitivity)> */
break;
case SADB_ACQUIRE:
/* <base, address(SD), (address(P),) (identity(SD),)
(sensitivity,) proposal> */
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();
/* <base, address(SD), (address(P),) (identity(SD),)
(sensitivity,) proposal> */
break;
case SADB_REGISTER:
/* <base> */
/* <base, supported> */
break;
case SADB_EXPIRE:
case SADB_FLUSH:
break;
case SADB_DUMP:
break;
case SADB_X_PROMISC:
/* <base> */
/* <base, base(, others)> */
break;
case SADB_X_PCHANGE:
break;
/* for SPD management */
case SADB_X_SPDFLUSH:
case SADB_X_SPDDUMP:
break;
case SADB_X_SPDADD:
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;
/* 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 */
len = sizeof(struct sadb_address) + PFKEY_ALIGN8(a->sa_len);
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_reserved = 0;
key_setsadbextbuf(m_buf, m_len,
(caddr_t)&m_addr, sizeof(struct sadb_address),
abuf, a->sa_len);
m_len += len;
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;
}

View File

@ -0,0 +1,161 @@
/*
* 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 <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet6/in6.h>
#include <netkey/keyv2.h>
#include <stdlib.h>
#include <string.h>
#include <netinet6/ipsec.h>
char *requests[] = {
"must_error", /* must be error */
"ipsec must_error", /* must be error */
"ipsec esp/must_error", /* must be error */
"discard",
"none",
"entrust",
"bypass", /* may be error */
"ipsec esp", /* must be error */
"ipsec ah/require",
"ipsec ah/use/",
"ipsec esp/require ah/default/203.178.141.194",
"ipsec ah/use/203.178.141.195 esp/use/203.178.141.194",
"ipsec esp/elf.wide.ydc.co.jp esp/www.wide.ydc.co.jp"
"
ipsec esp/require ah/use esp/require/10.0.0.1
ah/use/3ffe:501:481d::1 ah/use/3ffe:501:481d::1 ah/use/3ffe:501:481d::1
ah/use/3ffe:501:481d::1 ah/use/3ffe:501:481d::1 ah/use/3ffe:501:481d::1
ah/use/3ffe:501:481d::1 ah/use/3ffe:501:481d::1 ah/use/3ffe:501:481d::1
ah/use/3ffe:501:481d::1 ah/use/3ffe:501:481d::1 ah/use/3ffe:501:481d::1
ah/use/3ffe:501:481d::1 ah/use/3ffe:501:481d::1 ah/use/3ffe:501:481d::1
ah/use/3ffe:501:481d::1 ah/use/3ffe:501:481d::1 ah/use/3ffe:501:481d::1
ah/use/3ffe:501:481d::1 ah/use/3ffe:501:481d::1 ah/use/3ffe:501:481d::1
ah/use/3ffe:501:481d::1 ah/use/3ffe:501:481d::1ah/use/3ffe:501:481d::1
",
};
u_char *p_secpolicy;
int test(char *buf, int family);
char *setpolicy(char *req);
main()
{
int i;
char *buf;
for (i = 0; i < sizeof(requests)/sizeof(requests[0]); i++) {
printf("* requests:[%s]\n", requests[i]);
if ((buf = setpolicy(requests[i])) == NULL)
continue;
printf("\tsetlen:%d\n", PFKEY_EXTLEN(buf));
printf("\tPF_INET:\n");
test(buf, PF_INET);
printf("\tPF_INET6:\n");
test(buf, PF_INET6);
free(buf);
}
}
int test(char *policy, int family)
{
int so, proto, optname;
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)
perror("socket");
if (setsockopt(so, proto, optname, policy, PFKEY_EXTLEN(policy)) < 0)
perror("setsockopt");
len = sizeof(getbuf);
memset(getbuf, 0, sizeof(getbuf));
if (getsockopt(so, proto, optname, getbuf, &len) < 0)
perror("getsockopt");
{
char *buf = NULL;
printf("\tgetlen:%d\n", len);
if ((buf = ipsec_dump_policy(getbuf, NULL)) == NULL)
ipsec_strerror();
else
printf("\t[%s]\n", buf);
free(buf);
}
close (so);
}
char *setpolicy(char *req)
{
int len;
char *buf;
if ((len = ipsec_get_policylen(req)) < 0) {
printf("ipsec_get_policylen: %s\n", ipsec_strerror());
return NULL;
}
if ((buf = malloc(len)) == NULL) {
perror("malloc");
return NULL;
}
if ((len = ipsec_set_policy(buf, len, req)) < 0) {
printf("ipsec_set_policy: %s\n", ipsec_strerror());
free(buf);
return NULL;
}
return buf;
}

322
usr.sbin/setkey/token.l Normal file
View File

@ -0,0 +1,322 @@
/*
* 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 <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <net/route.h>
#include <net/pfkeyv2.h>
#include <netkey/keydb.h>
#include <netkey/key_debug.h>
#include <netinet/in.h>
#include <netinet6/ipsec.h>
#include <stdlib.h>
#include <limits.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#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 ? */
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));
%}
/* 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}+)?
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); }
<S_PL>[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);
}
<S_PL>{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}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); }
{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);
return(DECSTRING);
}
{ipv4addr} {
/*
* I can't supprt the type without dot,
* because it's umbiguous against {decstring}.
* e.g. 127
*/
PREPROC;
yylval.val.len = sizeof(struct sockaddr_in);
yylval.val.buf = strdup(yytext);
return(IP4_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"); }
%%
void
yyerror(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);
}

35
usr.sbin/setkey/vchar.h Normal file
View File

@ -0,0 +1,35 @@
/*
* 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;
} vchar_t;

View File

@ -19,7 +19,9 @@ BINOWN= root
BINGRP= bin
BINMODE=4555
CFLAGS+=-DINET6
CFLAGS+=-DINET6 -DIPSEC
DPADD= ${LIBIPSEC}
LDADD= -lipsec
MAN8= traceroute6.8