Sync with recent KAME.

This work was based on kame-20010528-freebsd43-snap.tgz and some
critical problem after the snap was out were fixed.
There are many many changes since last KAME merge.

TODO:
  - The definitions of SADB_* in sys/net/pfkeyv2.h are still different
    from RFC2407/IANA assignment because of binary compatibility
    issue.  It should be fixed under 5-CURRENT.
  - ip6po_m member of struct ip6_pktopts is no longer used.  But, it
    is still there because of binary compatibility issue.  It should
    be removed under 5-CURRENT.

Reviewed by:	itojun
Obtained from:	KAME
MFC after:	3 weeks
This commit is contained in:
Hajimu UMEMOTO 2001-06-11 12:39:29 +00:00
parent 52ebde4fba
commit 3384154590
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=78064
247 changed files with 20466 additions and 12044 deletions

View file

@ -766,7 +766,7 @@ network_gif_setup() {
continue
;;
*)
gifconfig $i ${peers}
ifconfig $i tunnel ${peers}
;;
esac
done

View file

@ -766,7 +766,7 @@ network_gif_setup() {
continue
;;
*)
gifconfig $i ${peers}
ifconfig $i tunnel ${peers}
;;
esac
done

View file

@ -766,7 +766,7 @@ network_gif_setup() {
continue
;;
*)
gifconfig $i ${peers}
ifconfig $i tunnel ${peers}
;;
esac
done

View file

@ -766,7 +766,7 @@ network_gif_setup() {
continue
;;
*)
gifconfig $i ${peers}
ifconfig $i tunnel ${peers}
;;
esac
done

View file

@ -766,7 +766,7 @@ network_gif_setup() {
continue
;;
*)
gifconfig $i ${peers}
ifconfig $i tunnel ${peers}
;;
esac
done

View file

@ -232,11 +232,11 @@ network6_pass1() {
case ${ipv6_ipv4mapping} in
[Yy][Ee][Ss])
echo -n ' IPv4 mapped IPv6 address support=YES'
sysctl -w net.inet6.ip6.mapped_addr=1 >/dev/null
sysctl -w net.inet6.ip6.v6only=0 >/dev/null
;;
'' | *)
echo -n ' IPv4 mapped IPv6 address support=NO'
sysctl -w net.inet6.ip6.mapped_addr=0 >/dev/null
sysctl -w net.inet6.ip6.v6only=1 >/dev/null
;;
esac
@ -256,7 +256,6 @@ network6_interface_setup() {
;;
*)
rtsol_available=yes
prefixcmd_enable=NO
;;
esac
for i in $interfaces; do
@ -265,24 +264,11 @@ network6_interface_setup() {
if [ -n "${prefix}" ]; then
rtsol_available=no
rtsol_interface=no
laddr=`network6_getladdr $i`
hostid=`expr "${laddr}" : 'fe80::\(.*\)%\(.*\)'`
for j in ${prefix}; do
case ${prefixcmd_enable} in
[Yy][Ee][Ss])
prefix $i $j::
;;
*)
laddr=`network6_getladdr $i`
hostid=`expr "${laddr}" : \
'fe80::\(.*\)%\(.*\)'`
address=$j\:${hostid}
eval hostid_$i=${hostid}
eval address_$i=${address}
ifconfig $i inet6 ${address} \
prefixlen 64 alias
;;
esac
address=$j\:${hostid}
ifconfig $i inet6 ${address} prefixlen 64 alias
case ${ipv6_gateway_enable} in
[Yy][Ee][Ss])

View file

@ -766,7 +766,7 @@ network_gif_setup() {
continue
;;
*)
gifconfig $i ${peers}
ifconfig $i tunnel ${peers}
;;
esac
done

View file

@ -766,7 +766,7 @@ network_gif_setup() {
continue
;;
*)
gifconfig $i ${peers}
ifconfig $i tunnel ${peers}
;;
esac
done

View file

@ -232,11 +232,11 @@ network6_pass1() {
case ${ipv6_ipv4mapping} in
[Yy][Ee][Ss])
echo -n ' IPv4 mapped IPv6 address support=YES'
sysctl -w net.inet6.ip6.mapped_addr=1 >/dev/null
sysctl -w net.inet6.ip6.v6only=0 >/dev/null
;;
'' | *)
echo -n ' IPv4 mapped IPv6 address support=NO'
sysctl -w net.inet6.ip6.mapped_addr=0 >/dev/null
sysctl -w net.inet6.ip6.v6only=1 >/dev/null
;;
esac
@ -256,7 +256,6 @@ network6_interface_setup() {
;;
*)
rtsol_available=yes
prefixcmd_enable=NO
;;
esac
for i in $interfaces; do
@ -265,24 +264,11 @@ network6_interface_setup() {
if [ -n "${prefix}" ]; then
rtsol_available=no
rtsol_interface=no
laddr=`network6_getladdr $i`
hostid=`expr "${laddr}" : 'fe80::\(.*\)%\(.*\)'`
for j in ${prefix}; do
case ${prefixcmd_enable} in
[Yy][Ee][Ss])
prefix $i $j::
;;
*)
laddr=`network6_getladdr $i`
hostid=`expr "${laddr}" : \
'fe80::\(.*\)%\(.*\)'`
address=$j\:${hostid}
eval hostid_$i=${hostid}
eval address_$i=${address}
ifconfig $i inet6 ${address} \
prefixlen 64 alias
;;
esac
address=$j\:${hostid}
ifconfig $i inet6 ${address} prefixlen 64 alias
case ${ipv6_gateway_enable} in
[Yy][Ee][Ss])

View file

@ -1,7 +1,7 @@
.\" Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
.\" $KAME: ipsec_set_policy.3,v 1.14 2001/04/06 07:00:46 itojun Exp $
.\" $FreeBSD$
.\" $KAME: ipsec_set_policy.3,v 1.10 2000/05/07 05:25:03 itojun Exp $
.\"
.\" Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
@ -92,7 +92,7 @@ It is caller's responsibility to reclaim the region, by using
.Fa policy
is formatted as either of the following:
.Bl -tag -width "discard"
.It Ar direction Li entrust
.It Ar direction Li discard
.Ar direction
must be
.Li in
@ -100,6 +100,10 @@ or
.Li out .
.Ar direction
specifies which direction the policy needs to be applied.
With
.Li discard
policy, packets will be dropped if they match the policy.
.It Ar direction Li entrust
.Li entrust
means to consult to SPD defined by
.Xr setkey 8 .
@ -164,6 +168,15 @@ and
.Ar src
is the other node
.Pq peer .
If
.Ar mode
is
.Li transport ,
Both
.Ar src
and
.Ar dst
can be omited.
.Pp
.Ar level
must be set to one of the following:
@ -222,7 +235,8 @@ 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
both entrust and bypass are not used.
Refer to
.Xr setkey 8
for detail.
.Pp
@ -230,12 +244,11 @@ 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
out ipsec esp/transport/10.1.1.2-10.1.1.1/use
ah/tunnel/10.1.1.2-10.1.1.1/unique:1000
in ipsec ipcomp/transport/10.1.1.2-10.1.1.1/use
esp/transport/10.1.1.2-10.1.1.1/use
out ipsec esp/transport//require
in ipsec ah/transport//require
out ipsec esp/tunnel/10.1.1.2-10.1.1.1/use
in ipsec ipcomp/transport//use
esp/transport//use
.Ed
.Sh RETURN VALUES
.Fn ipsec_set_policy
@ -255,3 +268,7 @@ on errors.
.Xr setkey 8
.Sh HISTORY
The functions first appeared in WIDE/KAME IPv6 protocol stack kit.
.Pp
IPv6 and IPsec support based on the KAME Project (http://www.kame.net/) stack
was initially integrated into
.Fx 4.0

View file

@ -1,7 +1,7 @@
.\" Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
.\" $KAME: ipsec_strerror.3,v 1.8 2000/11/20 00:35:14 sakane Exp $
.\" $FreeBSD$
.\" $KAME: ipsec_strerror.3,v 1.6 2000/05/07 05:25:03 itojun Exp $
.\"
.\" Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
@ -34,24 +34,23 @@
.\"
.Sh NAME
.Nm ipsec_strerror
.Nd error code for IPsec policy manipulation library
.Nd error message for IPsec policy manipulation library
.\"
.Sh SYNOPSIS
.Fd #include <netinet6/ipsec.h>
.Ft "char *"
.Ft "const char *"
.Fn ipsec_strerror
.\"
.Sh DESCRIPTION
.Pa netinet6/ipsec.h
declares
.Bd -ragged -offset indent
.Vt extern int ipsec_errcode ;
.Ed
.Pp
which is used to pass error code from IPsec policy manipulation library
to user program.
.Dl extern int ipsec_errcode;
.Pp
which is used to pass an error code from IPsec policy manipulation library
to an user program.
.Fn ipsec_strerror
can be used to obtain error message string for the error code.
can be used to obtain the error message string for the error code.
.Pp
The array pointed to is not to be modified by the program.
Since
@ -75,7 +74,9 @@ The C string must not be overwritten by user programs.
.Xr ipsec_set_policy 3
.\"
.Sh HISTORY
The functions first appeared in WIDE/KAME IPv6 protocol stack kit.
.Fn ipsec_strerror
first appeared in WIDE/KAME IPv6 protocol stack kit.
.\"
.\" .Sh BUGS
.\" (to be written)
.Sh BUGS
.Fn ipsec_strerror
will return its result which may be overwritten by subsequent calls.

View file

@ -1,5 +1,5 @@
/* $FreeBSD$ */
/* $KAME: ipsec_strerror.c,v 1.6 2000/05/07 05:25:03 itojun Exp $ */
/* $KAME: ipsec_strerror.c,v 1.7 2000/07/30 00:45:12 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
@ -40,7 +40,7 @@
int __ipsec_errcode;
static char *ipsec_errlist[] = {
static const char *ipsec_errlist[] = {
"Success", /*EIPSEC_NO_ERROR*/
"Not supported", /*EIPSEC_NOT_SUPPORTED*/
"Invalid argument", /*EIPSEC_INVAL_ARGUMENT*/
@ -71,7 +71,7 @@ NULL, /*EIPSEC_SYSTEM_ERROR*/
"Unknown error", /*EIPSEC_MAX*/
};
char *ipsec_strerror(void)
const char *ipsec_strerror(void)
{
if (__ipsec_errcode < 0 || __ipsec_errcode > EIPSEC_MAX)
__ipsec_errcode = EIPSEC_MAX;
@ -79,7 +79,7 @@ char *ipsec_strerror(void)
return ipsec_errlist[__ipsec_errcode];
}
void __ipsec_set_strerror(char *str)
void __ipsec_set_strerror(const char *str)
{
__ipsec_errcode = EIPSEC_SYSTEM_ERROR;
ipsec_errlist[EIPSEC_SYSTEM_ERROR] = str;

View file

@ -1,5 +1,5 @@
/* $FreeBSD$ */
/* $KAME: ipsec_strerror.h,v 1.7 2000/05/07 05:25:03 itojun Exp $ */
/* $KAME: ipsec_strerror.h,v 1.8 2000/07/30 00:45:12 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
@ -31,7 +31,7 @@
*/
extern int __ipsec_errcode;
extern void __ipsec_set_strerror __P((char *));
extern void __ipsec_set_strerror __P((const char *));
#define EIPSEC_NO_ERROR 0 /*success*/
#define EIPSEC_NOT_SUPPORTED 1 /*not supported*/

View file

@ -1,5 +1,5 @@
/* $FreeBSD$ */
/* $KAME: libpfkey.h,v 1.1 2000/06/08 21:28:32 itojun Exp $ */
/* $KAME: libpfkey.h,v 1.6 2001/03/05 18:22:17 thorpej Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -30,11 +30,15 @@
* SUCH DAMAGE.
*/
struct sadb_msg;
extern void pfkey_sadump __P((struct sadb_msg *));
extern void pfkey_spdump __P((struct sadb_msg *));
struct sockaddr;
struct sadb_alg;
int ipsec_check_keylen __P((u_int, u_int, u_int));
int ipsec_check_keylen2 __P((u_int, u_int, u_int));
int ipsec_get_keylen __P((u_int, u_int, struct sadb_alg *));
u_int pfkey_set_softrate __P((u_int, u_int));
u_int pfkey_get_softrate __P((u_int));
int pfkey_send_getspi __P((int, u_int, u_int, struct sockaddr *,
@ -49,17 +53,26 @@ int pfkey_send_add __P((int, u_int, u_int, struct sockaddr *,
u_int64_t, u_int64_t, u_int32_t));
int pfkey_send_delete __P((int, u_int, u_int,
struct sockaddr *, struct sockaddr *, u_int32_t));
int pfkey_send_delete_all __P((int, u_int, u_int,
struct sockaddr *, struct sockaddr *));
int pfkey_send_get __P((int, u_int, u_int,
struct sockaddr *, struct sockaddr *, u_int32_t));
int pfkey_send_register __P((int, u_int));
int pfkey_recv_register __P((int));
int pfkey_set_supported __P((struct sadb_msg *, int));
int pfkey_send_flush __P((int, u_int));
int pfkey_send_dump __P((int, u_int));
int pfkey_send_promisc_toggle __P((int, int));
int pfkey_send_spdadd __P((int, struct sockaddr *, u_int,
struct sockaddr *, u_int, u_int, caddr_t, int, u_int32_t));
int pfkey_send_spdadd2 __P((int, struct sockaddr *, u_int,
struct sockaddr *, u_int, u_int, u_int64_t, u_int64_t,
caddr_t, int, u_int32_t));
int pfkey_send_spdupdate __P((int, struct sockaddr *, u_int,
struct sockaddr *, u_int, u_int, caddr_t, int, u_int32_t));
int pfkey_send_spdupdate2 __P((int, struct sockaddr *, u_int,
struct sockaddr *, u_int, u_int, u_int64_t, u_int64_t,
caddr_t, int, u_int32_t));
int pfkey_send_spddelete __P((int, struct sockaddr *, u_int,
struct sockaddr *, u_int, u_int, caddr_t, int, u_int32_t));
int pfkey_send_spddelete2 __P((int, u_int32_t));

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,5 @@
/* $FreeBSD$ */
/* $KAME: pfkey_dump.c,v 1.19 2000/06/10 06:47:11 sakane Exp $ */
/* $KAME: pfkey_dump.c,v 1.27 2001/03/12 09:03:38 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
@ -52,6 +52,29 @@
#include "ipsec_strerror.h"
#include "libpfkey.h"
/* cope with old kame headers - ugly */
#ifndef SADB_X_AALG_MD5
#define SADB_X_AALG_MD5 SADB_AALG_MD5
#endif
#ifndef SADB_X_AALG_SHA
#define SADB_X_AALG_SHA SADB_AALG_SHA
#endif
#ifndef SADB_X_AALG_NULL
#define SADB_X_AALG_NULL SADB_AALG_NULL
#endif
#ifndef SADB_X_EALG_BLOWFISHCBC
#define SADB_X_EALG_BLOWFISHCBC SADB_EALG_BLOWFISHCBC
#endif
#ifndef SADB_X_EALG_CAST128CBC
#define SADB_X_EALG_CAST128CBC SADB_EALG_CAST128CBC
#endif
#ifndef SADB_X_EALG_RC5CBC
#ifdef SADB_EALG_RC5CBC
#define SADB_X_EALG_RC5CBC SADB_EALG_RC5CBC
#endif
#endif
#define GETMSGSTR(str, num) \
do { \
if (sizeof((str)[0]) == 0 \
@ -63,15 +86,33 @@ do { \
printf("%s ", (str)[(num)]); \
} while (0)
#define GETMSGV2S(v2s, num) \
do { \
struct val2str *p; \
for (p = (v2s); p && p->str; p++) { \
if (p->val == (num)) \
break; \
} \
if (p && p->str) \
printf("%s ", p->str); \
else \
printf("%d ", (num)); \
} while (0)
static char *str_ipaddr __P((struct sockaddr *));
static char *str_prefport __P((u_int, u_int, u_int));
static char *str_time __P((time_t));
static void str_lifetime_byte __P((struct sadb_lifetime *, char *));
struct val2str {
int val;
const char *str;
};
/*
* Must to be re-written about following strings.
*/
static char *_str_satype[] = {
static char *str_satype[] = {
"unspec",
"unknown",
"ah",
@ -84,13 +125,13 @@ static char *_str_satype[] = {
"ipcomp",
};
static char *_str_mode[] = {
static char *str_mode[] = {
"any",
"transport",
"tunnel",
};
static char *_str_upper[] = {
static char *str_upper[] = {
/*0*/ "ip", "icmp", "igmp", "ggp", "ip4",
"", "tcp", "", "egp", "",
/*10*/ "", "", "", "", "",
@ -106,37 +147,57 @@ static char *_str_upper[] = {
/*60*/ "dst6",
};
static char *_str_state[] = {
static char *str_state[] = {
"larval",
"mature",
"dying",
"dead",
};
static char *_str_alg_auth[] = {
"none",
"hmac-md5",
"hmac-sha1",
"md5",
"sha",
"null",
static struct val2str str_alg_auth[] = {
{ SADB_AALG_NONE, "none", },
{ SADB_AALG_MD5HMAC, "hmac-md5", },
{ SADB_AALG_SHA1HMAC, "hmac-sha1", },
{ SADB_X_AALG_MD5, "md5", },
{ SADB_X_AALG_SHA, "sha", },
{ SADB_X_AALG_NULL, "null", },
#ifdef SADB_X_AALG_SHA2_256
{ SADB_X_AALG_SHA2_256, "hmac-sha2-256", },
#endif
#ifdef SADB_X_AALG_SHA2_384
{ SADB_X_AALG_SHA2_384, "hmac-sha2-384", },
#endif
#ifdef SADB_X_AALG_SHA2_512
{ SADB_X_AALG_SHA2_512, "hmac-sha2-512", },
#endif
{ -1, NULL, },
};
static char *_str_alg_enc[] = {
"none",
"des-cbc",
"3des-cbc",
"null",
"blowfish-cbc",
"cast128-cbc",
"rc5-cbc",
static struct val2str str_alg_enc[] = {
{ SADB_EALG_NONE, "none", },
{ SADB_EALG_DESCBC, "des-cbc", },
{ SADB_EALG_3DESCBC, "3des-cbc", },
{ SADB_EALG_NULL, "null", },
#ifdef SADB_X_EALG_RC5CBC
{ SADB_X_EALG_RC5CBC, "rc5-cbc", },
#endif
{ SADB_X_EALG_CAST128CBC, "cast128-cbc", },
{ SADB_X_EALG_BLOWFISHCBC, "blowfish-cbc", },
#ifdef SADB_X_EALG_RIJNDAELCBC
{ SADB_X_EALG_RIJNDAELCBC, "rijndael-cbc", },
#endif
#ifdef SADB_X_EALG_TWOFISHCBC
{ SADB_X_EALG_TWOFISHCBC, "twofish-cbc", },
#endif
{ -1, NULL, },
};
static char *_str_alg_comp[] = {
"none",
"oui",
"deflate",
"lzs",
static struct val2str str_alg_comp[] = {
{ SADB_X_CALG_NONE, "none", },
{ SADB_X_CALG_OUI, "oui", },
{ SADB_X_CALG_DEFLATE, "deflate", },
{ SADB_X_CALG_LZS, "lzs", },
{ -1, NULL, },
};
/*
@ -204,10 +265,10 @@ pfkey_sadump(m)
}
printf("\n\t");
GETMSGSTR(_str_satype, m->sadb_msg_satype);
GETMSGSTR(str_satype, m->sadb_msg_satype);
printf("mode=");
GETMSGSTR(_str_mode, m_sa2->sadb_x_sa2_mode);
GETMSGSTR(str_mode, m_sa2->sadb_x_sa2_mode);
printf("spi=%u(0x%08x) reqid=%u(0x%08x)\n",
(u_int32_t)ntohl(m_sa->sadb_sa_spi),
@ -218,11 +279,11 @@ pfkey_sadump(m)
/* encryption key */
if (m->sadb_msg_satype == SADB_X_SATYPE_IPCOMP) {
printf("\tC: ");
GETMSGSTR(_str_alg_comp, m_sa->sadb_sa_encrypt);
GETMSGV2S(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);
GETMSGV2S(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");
@ -232,7 +293,7 @@ pfkey_sadump(m)
/* authentication key */
if (m_auth != NULL) {
printf("\tA: ");
GETMSGSTR(_str_alg_auth, m_sa->sadb_sa_auth);
GETMSGV2S(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");
@ -245,7 +306,7 @@ pfkey_sadump(m)
/* state */
printf("state=");
GETMSGSTR(_str_state, m_sa->sadb_sa_state);
GETMSGSTR(str_state, m_sa->sadb_sa_state);
printf("seq=%lu pid=%lu\n",
(u_long)m->sadb_msg_seq,
@ -307,6 +368,7 @@ pfkey_spdump(m)
caddr_t mhp[SADB_EXT_MAX + 1];
struct sadb_address *m_saddr, *m_daddr;
struct sadb_x_policy *m_xpl;
struct sadb_lifetime *m_lft = NULL;
struct sockaddr *sa;
u_int16_t port;
@ -323,6 +385,7 @@ pfkey_spdump(m)
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];
m_lft = (struct sadb_lifetime *)mhp[SADB_EXT_LIFETIME_HARD];
/* source address */
if (m_saddr == NULL) {
@ -378,7 +441,7 @@ pfkey_spdump(m)
if (m_saddr->sadb_address_proto == IPSEC_ULPROTO_ANY)
printf("any");
else
GETMSGSTR(_str_upper, m_saddr->sadb_address_proto);
GETMSGSTR(str_upper, m_saddr->sadb_address_proto);
/* policy */
{
@ -395,6 +458,13 @@ pfkey_spdump(m)
free(d_xpl);
}
/* lifetime */
if (m_lft) {
printf("\tlifetime:%lu validtime:%lu\n",
(u_long)m_lft->sadb_lifetime_addtime,
(u_long)m_lft->sadb_lifetime_usetime);
}
printf("\tspid=%ld seq=%ld pid=%ld\n",
(u_long)m_xpl->sadb_x_policy_id,
(u_long)m->sadb_msg_seq,

View file

@ -1,5 +1,5 @@
/* $FreeBSD$ */
/* $KAME: policy_token.l,v 1.9 2000/05/07 05:25:03 itojun Exp $ */
/* $KAME: policy_token.l,v 1.11 2000/12/01 10:08:29 sakane Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
@ -37,7 +37,6 @@
#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>
@ -58,6 +57,7 @@ int yylex __P((void));
%}
%option noyywrap
%option nounput
/* common section */
nl \n

View file

@ -1,5 +1,5 @@
/* $FreeBSD$ */
/* $KAME: test-policy.c,v 1.13 2000/05/07 05:25:03 itojun Exp $ */
/* $KAME: test-policy.c,v 1.14 2000/12/27 11:38:11 sakane Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
@ -46,6 +46,8 @@
#include <errno.h>
#include <err.h>
#include "libpfkey.h"
struct req_t {
int result; /* expected result; 0:ok 1:ng */
char *str;
@ -111,9 +113,9 @@ test1()
result = test1sub1(&reqs[i]);
if (result == 0 && reqs[i].result == 1) {
errx(1, "ERROR: expecting failure.\n");
warnx("ERROR: expecting failure.\n");
} else if (result == 1 && reqs[i].result == 0) {
errx(1, "ERROR: expecting success.\n");
warnx("ERROR: expecting success.\n");
}
}
@ -245,7 +247,8 @@ test2()
errx(1, "ERROR: %s\n", ipsec_strerror());
m = pfkey_recv(so);
free(m);
#if 0
printf("spdsetidx()\n");
if (pfkey_send_spdsetidx(so, (struct sockaddr *)addr, 128,
(struct sockaddr *)addr, 128,
@ -262,6 +265,8 @@ test2()
m = pfkey_recv(so);
free(m);
sleep(4);
printf("spddelete()\n");
if (pfkey_send_spddelete(so, (struct sockaddr *)addr, 128,
(struct sockaddr *)addr, 128,
@ -283,19 +288,31 @@ test2()
m = pfkey_recv(so);
free(m);
sleep(4);
printf("spddelete2()\n");
if (pfkey_send_spddelete2(so, spid) < 0)
errx(1, "ERROR: %s\n", ipsec_strerror());
m = pfkey_recv(so);
free(m);
#endif
printf("spdadd() with lifetime's 10(s)\n");
if (pfkey_send_spdadd2(so, (struct sockaddr *)addr, 128,
(struct sockaddr *)addr, 128,
255, 0, 10, sp2, splen2, 0) < 0)
errx(1, "ERROR: %s\n", ipsec_strerror());
spid = test2sub(so);
#if 0
/* expecting failure */
printf("spdupdate()\n");
if (pfkey_send_spdupdate(so, (struct sockaddr *)addr, 128,
(struct sockaddr *)addr, 128,
255, sp2, splen2, 0) == 0) {
errx(1, "ERROR: expecting failure.\n");
warnx("ERROR: expecting failure.\n");
}
#endif
return 0;
}

View file

@ -256,6 +256,19 @@ list of available options.
.It Fl mediaopt Ar opts
If the driver supports the media selection system, disable the
specified media options on the interface.
.It Cm tunnel Ar src_addr Ar dest_addr
(IP tunnel devices only)
Configure the physical source and destination address for IP tunnel
interfaces (gif). The arguments
.Ar src_addr
and
.Ar dest_addr
are interpreted as the outer source/destination for the encapsulating
IPv4/IPv6 header.
.It Cm deletetunnel
Unconfigure the physical source and destination address for IP tunnel
interfaces previously configured with
.Cm tunnel .
.It Cm vlan Ar vlan_tag
If the interface is a vlan pseudo interface, set the vlan tag value
to

View file

@ -149,35 +149,43 @@ void rt_xaddrs __P((caddr_t, caddr_t, struct rt_addrinfo *));
void status __P((const struct afswtch *afp, int addrcount,
struct sockaddr_dl *sdl, struct if_msghdr *ifm,
struct ifa_msghdr *ifam));
void tunnel_status __P((int s));
void usage __P((void));
void ifmaybeload __P((char *name));
#ifdef INET6
void in6_fillscopeid __P((struct sockaddr_in6 *sin6));
int prefix __P((void *, int));
static char *sec2str __P((time_t));
int explicit_prefix = 0;
#endif
typedef void c_func __P((const char *cmd, int arg, int s, const struct afswtch *afp));
typedef void c_func2 __P((const char *arg, const char *arg2, int s, const struct afswtch *afp));
c_func setatphase, setatrange;
c_func setifaddr, setifbroadaddr, setifdstaddr, setifnetmask;
c_func2 settunnel;
c_func deletetunnel;
#ifdef INET6
c_func setifprefixlen;
c_func setip6flags;
c_func setip6vltime;
c_func setip6pltime;
c_func setip6vltime;
c_func2 setip6lifetime;
#endif
c_func setifipdst;
c_func setifflags, setifmetric, setifmtu, setiflladdr;
#define NEXTARG 0xffffff
#define NEXTARG2 0xfffffe
const
struct cmd {
const char *c_name;
int c_parameter; /* NEXTARG means next argv */
void (*c_func) __P((const char *, int, int, const struct afswtch *afp));
void (*c_func2) __P((const char *, const char *, int, const struct afswtch *afp));
} cmds[] = {
{ "up", IFF_UP, setifflags } ,
{ "down", -IFF_UP, setifflags },
@ -201,14 +209,20 @@ struct cmd {
{ "anycast", IN6_IFF_ANYCAST, setip6flags },
{ "tentative", IN6_IFF_TENTATIVE, setip6flags },
{ "-tentative", -IN6_IFF_TENTATIVE, setip6flags },
{ "vltime", NEXTARG, setip6vltime },
{ "deprecated", IN6_IFF_DEPRECATED, setip6flags },
{ "-deprecated", -IN6_IFF_DEPRECATED, setip6flags },
{ "autoconf", IN6_IFF_AUTOCONF, setip6flags },
{ "-autoconf", -IN6_IFF_AUTOCONF, setip6flags },
{ "pltime", NEXTARG, setip6pltime },
{ "vltime", NEXTARG, setip6vltime },
#endif
{ "range", NEXTARG, setatrange },
{ "phase", NEXTARG, setatphase },
{ "metric", NEXTARG, setifmetric },
{ "broadcast", NEXTARG, setifbroadaddr },
{ "ipdst", NEXTARG, setifipdst },
{ "tunnel", NEXTARG2, NULL, settunnel },
{ "deletetunnel", 0, deletetunnel },
{ "link0", IFF_LINK0, setifflags },
{ "-link0", -IFF_LINK0, setifflags },
{ "link1", IFF_LINK1, setifflags },
@ -600,13 +614,19 @@ ifconfig(argc, argv, afp)
break;
if (p->c_name == 0 && setaddr)
p++; /* got src, do dst */
if (p->c_func) {
if (p->c_func || p->c_func2) {
if (p->c_parameter == NEXTARG) {
if (argv[1] == NULL)
errx(1, "'%s' requires argument",
p->c_name);
(*p->c_func)(argv[1], 0, s, afp);
argc--, argv++;
} else if (p->c_parameter == NEXTARG2) {
if (argc < 3)
errx(1, "'%s' requires 2 arguments",
p->c_name);
(*p->c_func2)(argv[1], argv[2], s, afp);
argc -= 2, argv += 2;
} else
(*p->c_func)(*argv, p->c_parameter, s, afp);
}
@ -703,6 +723,82 @@ setifaddr(addr, param, s, afp)
(*afp->af_getaddr)(addr, (doalias >= 0 ? ADDR : RIDADDR));
}
void
settunnel(src, dst, s, afp)
const char *src, *dst;
int s;
const struct afswtch *afp;
{
struct addrinfo hints, *srcres, *dstres;
struct ifaliasreq addreq;
int ecode;
#ifdef INET6
struct in6_aliasreq in6_addreq;
#endif
memset(&hints, 0, sizeof(hints));
hints.ai_family = afp->af_af;
if ((ecode = getaddrinfo(src, NULL, NULL, &srcres)) != 0)
errx(1, "error in parsing address string: %s",
gai_strerror(ecode));
if ((ecode = getaddrinfo(dst, NULL, NULL, &dstres)) != 0)
errx(1, "error in parsing address string: %s",
gai_strerror(ecode));
if (srcres->ai_addr->sa_family != dstres->ai_addr->sa_family)
errx(1,
"source and destination address families do not match");
switch (srcres->ai_addr->sa_family) {
case AF_INET:
memset(&addreq, 0, sizeof(addreq));
strncpy(addreq.ifra_name, name, IFNAMSIZ);
memcpy(&addreq.ifra_addr, srcres->ai_addr,
srcres->ai_addr->sa_len);
memcpy(&addreq.ifra_dstaddr, dstres->ai_addr,
dstres->ai_addr->sa_len);
if (ioctl(s, SIOCSIFPHYADDR, &addreq) < 0)
warn("SIOCSIFPHYADDR");
break;
#ifdef INET6
case AF_INET6:
memset(&in6_addreq, 0, sizeof(in6_addreq));
strncpy(in6_addreq.ifra_name, name, IFNAMSIZ);
memcpy(&in6_addreq.ifra_addr, srcres->ai_addr,
srcres->ai_addr->sa_len);
memcpy(&in6_addreq.ifra_dstaddr, dstres->ai_addr,
dstres->ai_addr->sa_len);
if (ioctl(s, SIOCSIFPHYADDR_IN6, &in6_addreq) < 0)
warn("SIOCSIFPHYADDR_IN6");
break;
#endif /* INET6 */
default:
warn("address family not supported");
}
freeaddrinfo(srcres);
freeaddrinfo(dstres);
}
/* ARGSUSED */
void
deletetunnel(vname, param, s, afp)
const char *vname;
int param;
int s;
const struct afswtch *afp;
{
if (ioctl(s, SIOCDIFPHYADDR, &ifr) < 0)
err(1, "SIOCDIFPHYADDR");
}
void
setifnetmask(addr, dummy, s, afp)
const char *addr;
@ -744,16 +840,6 @@ setip6flags(dummyaddr, flag, dummysoc, afp)
in6_addreq.ifra_flags |= flag;
}
void
setip6vltime(seconds, dummy, s, afp)
const char *seconds;
int dummy __unused;
int s;
const struct afswtch *afp;
{
in6_addreq.ifra_lifetime.ia6t_vltime = atoi(seconds);
}
void
setip6pltime(seconds, dummy, s, afp)
const char *seconds;
@ -761,7 +847,42 @@ setip6pltime(seconds, dummy, s, afp)
int s;
const struct afswtch *afp;
{
in6_addreq.ifra_lifetime.ia6t_pltime = atoi(seconds);
setip6lifetime("pltime", seconds, s, afp);
}
void
setip6vltime(seconds, dummy, s, afp)
const char *seconds;
int dummy __unused;
int s;
const struct afswtch *afp;
{
setip6lifetime("vltime", seconds, s, afp);
}
void
setip6lifetime(cmd, val, s, afp)
const char *cmd;
const char *val;
int s;
const struct afswtch *afp;
{
time_t newval, t;
char *ep;
t = time(NULL);
newval = (time_t)strtoul(val, &ep, 0);
if (val == ep)
errx(1, "invalid %s", cmd);
if (afp->af_af != AF_INET6)
errx(1, "%s not allowed for the AF", cmd);
if (strcmp(cmd, "vltime") == 0) {
in6_addreq.ifra_lifetime.ia6t_expire = t + newval;
in6_addreq.ifra_lifetime.ia6t_vltime = newval;
} else if (strcmp(cmd, "pltime") == 0) {
in6_addreq.ifra_lifetime.ia6t_preferred = t + newval;
in6_addreq.ifra_lifetime.ia6t_pltime = newval;
}
}
#endif
@ -964,6 +1085,8 @@ status(afp, addrcount, sdl, ifm, ifam)
printf(" mtu %d", mtu);
putchar('\n');
tunnel_status(s);
while (addrcount > 0) {
info.rti_addrs = ifam->ifam_addrs;
@ -1014,6 +1137,73 @@ status(afp, addrcount, sdl, ifm, ifam)
return;
}
void
tunnel_status(s)
int s;
{
char psrcaddr[NI_MAXHOST];
char pdstaddr[NI_MAXHOST];
u_long srccmd, dstcmd;
struct ifreq *ifrp;
const char *ver = "";
#ifdef NI_WITHSCOPEID
const int niflag = NI_NUMERICHOST | NI_WITHSCOPEID;
#else
const int niflag = NI_NUMERICHOST;
#endif
#ifdef INET6
struct in6_ifreq in6_ifr;
int s6;
#endif /* INET6 */
psrcaddr[0] = pdstaddr[0] = '\0';
#ifdef INET6
memset(&in6_ifr, 0, sizeof(in6_ifr));
strncpy(in6_ifr.ifr_name, name, IFNAMSIZ);
s6 = socket(AF_INET6, SOCK_DGRAM, 0);
if (s6 < 0) {
srccmd = SIOCGIFPSRCADDR;
dstcmd = SIOCGIFPDSTADDR;
ifrp = &ifr;
} else {
close(s6);
srccmd = SIOCGIFPSRCADDR_IN6;
dstcmd = SIOCGIFPDSTADDR_IN6;
ifrp = (struct ifreq *)&in6_ifr;
}
#else /* INET6 */
srccmd = SIOCGIFPSRCADDR;
dstcmd = SIOCGIFPDSTADDR;
ifrp = &ifr;
#endif /* INET6 */
if (ioctl(s, srccmd, (caddr_t)ifrp) < 0)
return;
#ifdef INET6
if (ifrp->ifr_addr.sa_family == AF_INET6)
in6_fillscopeid((struct sockaddr_in6 *)&ifrp->ifr_addr);
#endif
getnameinfo(&ifrp->ifr_addr, ifrp->ifr_addr.sa_len,
psrcaddr, sizeof(psrcaddr), 0, 0, niflag);
#ifdef INET6
if (ifrp->ifr_addr.sa_family == AF_INET6)
ver = "6";
#endif
if (ioctl(s, dstcmd, (caddr_t)ifrp) < 0)
return;
#ifdef INET6
if (ifrp->ifr_addr.sa_family == AF_INET6)
in6_fillscopeid((struct sockaddr_in6 *)&ifrp->ifr_addr);
#endif
getnameinfo(&ifrp->ifr_addr, ifrp->ifr_addr.sa_len,
pdstaddr, sizeof(pdstaddr), 0, 0, niflag);
printf("\ttunnel inet%s %s --> %s\n", ver,
psrcaddr, pdstaddr);
}
void
in_status(s, info)
int s __unused;
@ -1049,6 +1239,19 @@ in_status(s, info)
}
#ifdef INET6
void
in6_fillscopeid(sin6)
struct sockaddr_in6 *sin6;
{
#if defined(__KAME__) && defined(KAME_SCOPEID)
if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
sin6->sin6_scope_id =
ntohs(*(u_int16_t *)&sin6->sin6_addr.s6_addr[2]);
sin6->sin6_addr.s6_addr[2] = sin6->sin6_addr.s6_addr[3] = 0;
}
#endif
}
void
in6_status(s, info)
int s __unused;
@ -1146,16 +1349,20 @@ in6_status(s, info)
printf("prefixlen %d ", prefix(&sin->sin6_addr,
sizeof(struct in6_addr)));
if (flags6 & IN6_IFF_ANYCAST)
if ((flags6 & IN6_IFF_ANYCAST) != 0)
printf("anycast ");
if (flags6 & IN6_IFF_TENTATIVE)
if ((flags6 & IN6_IFF_TENTATIVE) != 0)
printf("tentative ");
if (flags6 & IN6_IFF_DUPLICATED)
if ((flags6 & IN6_IFF_DUPLICATED) != 0)
printf("duplicated ");
if (flags6 & IN6_IFF_DETACHED)
if ((flags6 & IN6_IFF_DETACHED) != 0)
printf("detached ");
if (flags6 & IN6_IFF_DEPRECATED)
if ((flags6 & IN6_IFF_DEPRECATED) != 0)
printf("deprecated ");
if ((flags6 & IN6_IFF_AUTOCONF) != 0)
printf("autoconf ");
if ((flags6 & IN6_IFF_TEMPORARY) != 0)
printf("temporary ");
if (scopeid)
printf("scopeid 0x%x ", scopeid);

View file

@ -1,4 +1,4 @@
.\" $KAME: ping6.8,v 1.22 2000/05/31 17:00:07 itojun Exp $
.\" $KAME: ping6.8,v 1.39 2001/04/04 00:08:34 itojun Exp $
.\"
.\" Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
.\" All rights reserved.
@ -40,9 +40,9 @@ packets to network hosts
.Sh SYNOPSIS
.Nm
.\" without ipsec, or new ipsec
.Op Fl dfHnNqRvw
.Op Fl dfHnNqRtvw
.\" old ipsec
.\" .Op Fl AdEfnNqRvw
.\" .Op Fl AdEfnNqRtvw
.Bk -words
.Op Fl a Ar addrtype
.Ek
@ -184,13 +184,13 @@ option.
If
.Ar preload
is specified,
.Nm ping
.Nm
sends that many packets as fast as possible before falling into its normal
mode of behavior.
Only the super-user may use this option.
.It Fl n
Numeric output only.
No attempt will be made to lookup symbolic names for host addresses.
No attempt will be made to lookup symbolic names from addresses in the reply.
.It Fl N
Probe node information multicast group
.Pq Li ff02::2:xxxx:xxxx .
@ -213,11 +213,6 @@ For example,
.Dq Li \-p ff
will cause the sent packet to be filled with all
ones.
.Fl Q
flag,
.Nm
prints out any ICMP error messages caused by its own ECHO_REQUEST
messages.
.\" new ipsec
.It Fl P Ar policy
.Ar policy
@ -259,6 +254,13 @@ header data.
You may need to specify
.Fl b
as well to extend socket buffer size.
.It Fl t
Generate ICMPv6 Node Information supported query types query,
rather than echo-request.
.Fl s
has no effect if
.Fl t
is specified.
.It Fl v
Verbose output.
.Tn ICMP
@ -266,7 +268,7 @@ packets other than
.Tn ECHO_RESPONSE
that are received are listed.
.It Fl w
Generate ICMPv6 Node Information FQDN query, rather than echo-request.
Generate ICMPv6 Node Information DNS Name query, rather than echo-request.
.Fl s
has no effect if
.Fl w
@ -335,7 +337,7 @@ during normal operations or from automated scripts.
.\" If less than eight bytes of pad are specified, no round trip times are
.\" given.
.Sh DUPLICATE AND DAMAGED PACKETS
.Nm Ping6
.Nm
will report duplicate and damaged packets.
Duplicate packets should never occur when pinging a unicast address,
and seem to be caused by
@ -350,7 +352,7 @@ to the same request.
.Pp
Damaged packets are obviously serious cause for alarm and often
indicate broken hardware somewhere in the
.Nm ping
.Nm
packet's path
.Pq in the network or in the hosts .
.Sh TRYING DIFFERENT DATA PATTERNS
@ -386,8 +388,39 @@ option of
.Nm
returns 0 on success (the host is alive),
and non-zero if the arguments are incorrect or the host is not responding.
.Sh EXAMPLES
Normally,
.Xr ping6 8
works just like
.Xr ping 8
would work; the following will send ICMPv6 echo request to
.Li dst.foo.com .
.Bd -literal -offset indent
ping6 -n dst.foo.com
.Ed
.Pp
The following will probe hostnames for all nodes on the network link attached to
.Li wi0
interface.
The address
.Li ff02::1
is named the link-local all-node multicast address, and the packet would
reach every node on the network link.
.Bd -literal -offset indent
ping6 -w ff02::1%wi0
.Ed
.Pp
The following will probe addresses assigned to the destination node,
.Li dst.foo.com .
.Bd -literal -offset indent
ping6 -a agl dst.foo.com
.Ed
.Pp
.Sh SEE ALSO
.Xr netstat 1 ,
.Xr icmp6 4 ,
.Xr inet6 4 ,
.Xr ip6 4 ,
.Xr ifconfig 8 ,
.Xr ping 8 ,
.Xr routed 8 ,
@ -403,8 +436,8 @@ and non-zero if the arguments are incorrect or the host is not responding.
.Rs
.%A Matt Crawford
.%T "IPv6 Node Information Queries"
.%N draft-ietf-ipngwg-icmp-name-lookups-05.txt
.%D October 22, 1999
.%N draft-ietf-ipngwg-icmp-name-lookups-07.txt
.%D August 2000
.%O work in progress material
.Re
.Sh BUGS
@ -438,7 +471,7 @@ option (or something like those) to specify the particular address family.
This essentially means that we have two different commands.
.Sh HISTORY
The
.Nm ping
.Xr ping 8
command appeared in
.Bx 4.3 .
The

File diff suppressed because it is too large Load diff

View file

@ -72,11 +72,7 @@ static const char rcsid[] =
#include <string.h>
#include <sysexits.h>
#include <unistd.h>
/* wrapper for KAME-special getnameinfo() */
#ifndef NI_WITHSCOPEID
#define NI_WITHSCOPEID 0
#endif
#include <ifaddrs.h>
struct keytab {
char *kt_cp;
@ -98,6 +94,7 @@ union sockunion {
struct sockaddr_ns sns;
#endif
struct sockaddr_dl sdl;
struct sockaddr_storage ss; /* added to avoid memory overrun */
} so_dst, so_gate, so_mask, so_genmask, so_ifa, so_ifp;
typedef union sockunion *sup;
@ -110,10 +107,7 @@ struct rt_metrics rt_metrics;
u_long rtm_inits;
int atalk_aton __P((const char *, struct at_addr *));
char *atalk_ntoa __P((struct at_addr));
#ifdef INET6
char *inet6_ntoa __P((struct sockaddr *sa));
#endif
char *routename(), *netname();
const char *routename(), *netname();
void flushroutes(), newroute(), monitor(), sockaddr(), sodump(), bprintf();
void print_getmsg(), print_rtmsg(), pmsg_common(), pmsg_addrs(), mask_addr();
int getaddr(), rtmsg(), x25_makemask();
@ -122,10 +116,6 @@ extern char *iso_ntoa();
void usage __P((const char *)) __dead2;
#ifdef INET6
char name_buf[MAXHOSTNAMELEN * 2 + 1]; /*for getnameinfo()*/
#endif
void
usage(cp)
const char *cp;
@ -303,14 +293,14 @@ bad: usage(*argv);
struct sockaddr *sa = (struct sockaddr *)(rtm + 1);
(void) printf("%-20.20s ", rtm->rtm_flags & RTF_HOST ?
routename(sa) : netname(sa));
sa = (struct sockaddr *)(sa->sa_len + (char *)sa);
sa = (struct sockaddr *)(ROUNDUP(sa->sa_len) + (char *)sa);
(void) printf("%-20.20s ", routename(sa));
(void) printf("done\n");
}
}
}
char *
const char *
routename(sa)
struct sockaddr *sa;
{
@ -364,8 +354,36 @@ routename(sa)
#ifdef INET6
case AF_INET6:
(void) snprintf(line, sizeof(line), "%s", inet6_ntoa(sa));
break;
{
struct sockaddr_in6 sin6; /* use static var for safety */
int niflags = 0;
#ifdef NI_WITHSCOPEID
niflags = NI_WITHSCOPEID;
#endif
memset(&sin6, 0, sizeof(sin6));
memcpy(&sin6, sa, sa->sa_len);
sin6.sin6_len = sizeof(struct sockaddr_in6);
sin6.sin6_family = AF_INET6;
#ifdef __KAME__
if (sa->sa_len == sizeof(struct sockaddr_in6) &&
(IN6_IS_ADDR_LINKLOCAL(&sin6.sin6_addr) ||
IN6_IS_ADDR_MC_LINKLOCAL(&sin6.sin6_addr)) &&
sin6.sin6_scope_id == 0) {
sin6.sin6_scope_id =
ntohs(*(u_int16_t *)&sin6.sin6_addr.s6_addr[2]);
sin6.sin6_addr.s6_addr[2] = 0;
sin6.sin6_addr.s6_addr[3] = 0;
}
#endif
if (nflag)
niflags |= NI_NUMERICHOST;
if (getnameinfo((struct sockaddr *)&sin6, sin6.sin6_len,
line, sizeof(line), NULL, 0, niflags) != 0)
strncpy(line, "invalid", sizeof(line));
return(line);
}
#endif
case AF_APPLETALK:
@ -399,7 +417,7 @@ routename(sa)
* Return the name of the network whose address is given.
* The address is assumed to be that of a net or subnet, not a host.
*/
char *
const char *
netname(sa)
struct sockaddr *sa;
{
@ -469,8 +487,36 @@ netname(sa)
#ifdef INET6
case AF_INET6:
(void) snprintf(line, sizeof(line), "%s", inet6_ntoa(sa));
break;
{
struct sockaddr_in6 sin6; /* use static var for safety */
int niflags = 0;
#ifdef NI_WITHSCOPEID
niflags = NI_WITHSCOPEID;
#endif
memset(&sin6, 0, sizeof(sin6));
memcpy(&sin6, sa, sa->sa_len);
sin6.sin6_len = sizeof(struct sockaddr_in6);
sin6.sin6_family = AF_INET6;
#ifdef __KAME__
if (sa->sa_len == sizeof(struct sockaddr_in6) &&
(IN6_IS_ADDR_LINKLOCAL(&sin6.sin6_addr) ||
IN6_IS_ADDR_MC_LINKLOCAL(&sin6.sin6_addr)) &&
sin6.sin6_scope_id == 0) {
sin6.sin6_scope_id =
ntohs(*(u_int16_t *)&sin6.sin6_addr.s6_addr[2]);
sin6.sin6_addr.s6_addr[2] = 0;
sin6.sin6_addr.s6_addr[3] = 0;
}
#endif
if (nflag)
niflags |= NI_NUMERICHOST;
if (getnameinfo((struct sockaddr *)&sin6, sin6.sin6_len,
line, sizeof(line), NULL, 0, niflags) != 0)
strncpy(line, "invalid", sizeof(line));
return(line);
}
#endif
case AF_APPLETALK:
@ -827,47 +873,35 @@ getaddr(which, s, hpp)
case RTA_GATEWAY:
su = &so_gate;
if (iflag) {
#define MAX_IFACES 400
int sock;
struct ifreq iflist[MAX_IFACES];
struct ifconf ifconf;
struct ifreq *ifr, *ifr_end;
struct sockaddr_dl *dl, *sdl = NULL;
struct ifaddrs *ifap, *ifa;
struct sockaddr_dl *sdl = NULL;
/* Get socket */
if ((sock = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
err(1, "socket");
if (getifaddrs(&ifap))
err(1, "getifaddrs");
/* Get interface list */
ifconf.ifc_req = iflist;
ifconf.ifc_len = sizeof(iflist);
if (ioctl(sock, SIOCGIFCONF, &ifconf) < 0)
err(1, "ioctl(SIOCGIFCONF)");
close(sock);
for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
if (ifa->ifa_addr->sa_family != AF_LINK)
continue;
/* Look for this interface in the list */
for (ifr = ifconf.ifc_req,
ifr_end = (struct ifreq *)
(ifconf.ifc_buf + ifconf.ifc_len);
ifr < ifr_end;
ifr = (struct ifreq *) ((char *) &ifr->ifr_addr
+ MAX(ifr->ifr_addr.sa_len,
sizeof(ifr->ifr_addr)))) {
dl = (struct sockaddr_dl *)&ifr->ifr_addr;
if (ifr->ifr_addr.sa_family == AF_LINK
&& (ifr->ifr_flags & IFF_POINTOPOINT)
&& !strncmp(s, dl->sdl_data, dl->sdl_nlen)
&& s[dl->sdl_nlen] == 0) {
sdl = dl;
break;
}
if (strcmp(s, ifa->ifa_name) ||
(ifa->ifa_flags & IFF_POINTOPOINT) == 0)
continue;
sdl = (struct sockaddr_dl *)ifa->ifa_addr;
}
/* If we found it, then use it */
if (sdl) {
su->sdl = *sdl;
return(1);
/*
* Copy is safe since we have a
* sockaddr_storage member in sockunion{}.
* Note that we need to copy before calling
* freeifaddrs().
*/
memcpy(&su->sdl, sdl, sdl->sdl_len);
}
freeifaddrs(ifap);
if (sdl)
return(1);
}
break;
case RTA_NETMASK:
@ -908,31 +942,33 @@ getaddr(which, s, hpp)
switch (afamily) {
#ifdef INET6
case AF_INET6:
{
{
struct addrinfo hints, *res;
int error;
bzero(&hints, sizeof(struct addrinfo));
hints.ai_family = AF_INET6;
error = getaddrinfo(s, NULL, &hints, &res);
if (error != 0) {
(void) fprintf(stderr, "%s: bad value\n",
gai_strerror(error));
if (error == EAI_SYSTEM)
(void) fprintf(stderr, "%s\n",
strerror(errno));
memset(&hints, 0, sizeof(hints));
hints.ai_family = afamily; /*AF_INET6*/
hints.ai_flags = AI_NUMERICHOST;
hints.ai_socktype = SOCK_DGRAM; /*dummy*/
if (getaddrinfo(s, "0", &hints, &res) != 0 ||
res->ai_family != AF_INET6 ||
res->ai_addrlen != sizeof(su->sin6)) {
(void) fprintf(stderr, "%s: bad value\n", s);
exit(1);
}
bcopy(res->ai_addr, &su->sa, res->ai_addrlen);
/* XXX: embedded link local addr check */
if (IN6_IS_ADDR_LINKLOCAL(&su->sin6.sin6_addr))
*(u_short *)&su->sin6.sin6_addr.s6_addr[2] =
ntohs(su->sin6.sin6_scope_id);
su->sin6.sin6_scope_id = 0;
return 0;
}
memcpy(&su->sin6, res->ai_addr, sizeof(su->sin6));
#ifdef __KAME__
if ((IN6_IS_ADDR_LINKLOCAL(&su->sin6.sin6_addr) ||
IN6_IS_ADDR_LINKLOCAL(&su->sin6.sin6_addr)) &&
su->sin6.sin6_scope_id) {
*(u_int16_t *)&su->sin6.sin6_addr.s6_addr[2] =
htons(su->sin6.sin6_scope_id);
su->sin6.sin6_scope_id = 0;
}
#endif
freeaddrinfo(res);
return (0);
}
#endif /* INET6 */
#ifdef NS
case AF_NS:
@ -1624,45 +1660,3 @@ atalk_ntoa(struct at_addr at)
(void) snprintf(buf, sizeof(buf), "%u.%u", ntohs(at.s_net), at.s_node);
return(buf);
}
#ifdef INET6
char *
inet6_ntoa(struct sockaddr *sa)
{
char *cp;
struct sockaddr_in6 *sin6;
int error = -1, gap;
cp = NULL;
sin6 = (struct sockaddr_in6 *)sa;
gap = sizeof(struct sockaddr_in6) - sin6->sin6_len;
if (gap > 0)
bzero((char *)(sin6) + sin6->sin6_len, gap);
/* XXX: embedded link local addr check */
if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) &&
*(u_short *)&sin6->sin6_addr.s6_addr[2] != 0) {
u_short index;
index = *(u_short *)&sin6->sin6_addr.s6_addr[2];
*(u_short *)&sin6->sin6_addr.s6_addr[2] = 0;
if (sin6->sin6_scope_id == 0)
sin6->sin6_scope_id = ntohs(index);
}
if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) || sa->sa_len < 4)
cp = "default";
if (cp == 0 && !nflag)
error = getnameinfo(sa, sa->sa_len, name_buf, sizeof(name_buf),
NULL, 0, NI_NAMEREQD);
if (error != 0)
error = getnameinfo(sa, sa->sa_len, name_buf,
sizeof(name_buf), NULL, 0,
NI_NUMERICHOST|NI_WITHSCOPEID);
if (error != 0)
inet_ntop(AF_INET6, &sin6->sin6_addr, name_buf,
sizeof(name_buf));
return (cp != NULL) ? cp : name_buf;
}
#endif

View file

@ -16,11 +16,9 @@
SRCDIR= ${.CURDIR}/../../usr.sbin/rtsold
PROG= rtsol
SRCS= rtsold.c rtsol.c if.c probe.c dump.c
SRCS= rtsold.c rtsol.c if.c probe.c dump.c rtsock.c
CFLAGS+=-DINET6 -DHAVE_GETIFADDRS
LDADD= -lkvm
DPADD= ${LIBKVM}
NOMAN= yes

View file

@ -1,5 +1,5 @@
/* $FreeBSD$ */
/* $KAME: parse.y,v 1.29 2000/06/10 14:17:44 sakane Exp $ */
/* $KAME: kame/kame/kame/setkey/parse.y,v 1.36 2001/06/07 15:53:12 sakane Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
@ -57,6 +57,7 @@
u_int p_type;
u_int32_t p_spi;
int p_no_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;
@ -79,7 +80,6 @@ extern int m_len;
extern char cmdarg[8192];
extern int f_debug;
int setkeymsg __P((void));
static struct addrinfo *parse_addr __P((char *, char *, int));
static int setvarbuf __P((int *, struct sadb_ext *, int, caddr_t, int));
void parse_init __P((void));
@ -107,7 +107,7 @@ extern void yyerror __P((const char *));
%token F_EXT EXTENSION NOCYCLICSEQ
%token ALG_AUTH ALG_ENC ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_COMP
%token F_LIFETIME_HARD F_LIFETIME_SOFT
%token DECSTRING QUOTEDSTRING HEXSTRING ANY
%token DECSTRING QUOTEDSTRING HEXSTRING STRING ANY
/* SPD management */
%token SPDADD SPDDELETE SPDDUMP SPDFLUSH
%token F_POLICY PL_REQUESTS
@ -118,7 +118,7 @@ extern void yyerror __P((const char *));
%type <num> DECSTRING
%type <val> ADDRESS PL_REQUESTS
%type <val> key_string policy_requests
%type <val> QUOTEDSTRING HEXSTRING
%type <val> QUOTEDSTRING HEXSTRING STRING
%%
commands
@ -140,6 +140,7 @@ command
: add_command
| get_command
| delete_command
| deleteall_command
| flush_command
| dump_command
| spdadd_command
@ -166,6 +167,16 @@ delete_command
EOT
;
/* deleteall command */
deleteall_command
: DELETEALL { p_type = SADB_DELETE; }
ipaddress { p_src = pp_addr; }
ipaddress { p_dst = pp_addr; }
protocol_spec
{ p_no_spi = 1; }
EOT
;
/* get command */
get_command
: GET { p_type = SADB_GET; }
@ -327,7 +338,7 @@ auth_alg
auth_key
: /*NOTHING*/
{
if (p_alg_auth != SADB_AALG_NULL) {
if (p_alg_auth != SADB_X_AALG_NULL) {
yyerror("no key found.");
return -1;
}
@ -541,10 +552,27 @@ port
upper_spec
: DECSTRING { p_upper = $1; }
| UP_PROTO { p_upper = $1; }
| PR_ESP { p_upper = IPPROTO_ESP; };
| PR_AH { p_upper = IPPROTO_AH; };
| PR_IPCOMP { p_upper = IPPROTO_IPCOMP; };
| ANY { p_upper = IPSEC_ULPROTO_ANY; }
| STRING
{
struct protoent *ent;
ent = getprotobyname($1.buf);
if (ent)
p_upper = ent->p_proto;
else {
if (strcmp("icmp6", $1.buf) == 0) {
p_upper = IPPROTO_ICMPV6;
} else if(strcmp("ip4", $1.buf) == 0) {
p_upper = IPPROTO_IPV4;
} else {
yyerror("invalid upper layer protocol");
free($1.buf);
return -1;
}
}
free($1.buf);
}
;
policy_spec
@ -665,27 +693,29 @@ setkeymsg()
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;
if (p_no_spi == 0) {
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;
memcpy(m_buf + m_len, &m_sa, len);
m_len += len;
len = sizeof(struct sadb_x_sa2);
m_sa2.sadb_x_sa2_len = PFKEY_UNIT64(len);
m_sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2;
m_sa2.sadb_x_sa2_mode = p_mode;
m_sa2.sadb_x_sa2_reqid = p_reqid;
len = sizeof(struct sadb_x_sa2);
m_sa2.sadb_x_sa2_len = PFKEY_UNIT64(len);
m_sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2;
m_sa2.sadb_x_sa2_mode = p_mode;
m_sa2.sadb_x_sa2_reqid = p_reqid;
memcpy(m_buf + m_len, &m_sa2, len);
m_len += len;
memcpy(m_buf + m_len, &m_sa2, len);
m_len += len;
}
/* set src */
m_addr.sadb_address_len =
@ -864,6 +894,7 @@ parse_init()
{
p_type = 0;
p_spi = 0;
p_no_spi = 0;
p_src = 0, p_dst = 0;
pp_prefix = p_prefs = p_prefd = ~0;

View file

@ -33,11 +33,11 @@ foreach $_ (<IN>) {
$akey =~ s/\s//g;
$akey =~ s/^/0x/g;
} elsif (/^\treplay=(\d+) flags=(0x\d+) state=/) {
print "$mode $src $dst $proto $spi -m $ipsecmode";
print "$mode $src $dst $proto $spi";
$replay = $1;
print " -u $reqid" if $reqid;
if ($mode eq 'add') {
print " -r $replay" if $replay;
print " -m $ipsecmode -r $replay" if $replay;
if ($proto eq 'esp') {
print " -E $ealgo $ekey" if $ealgo;
print " -A $aalgo $akey" if $aalgo;

View file

@ -1,5 +1,5 @@
.\" $FreeBSD$
.\" $KAME: setkey.8,v 1.28 2000/06/16 12:03:46 sakane Exp $
.\" $KAME: setkey.8,v 1.49 2001/05/18 05:49:51 sakane Exp $
.\" $FreeBSD$
.\"
.\" Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
.\" All rights reserved.
@ -28,9 +28,9 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.Dd May 17, 1998
.Dd November 20, 2000
.Dt SETKEY 8
.Os KAME
.Os
.\"
.Sh NAME
.Nm setkey
@ -55,7 +55,7 @@
.\"
.Sh DESCRIPTION
.Nm
addes, updates, dumpes, or flushes
adds, updates, dumps, or flushes
Security Association Database (SAD) entries
as well as Security Policy Database (SPD) entries in the kernel.
.Pp
@ -94,11 +94,14 @@ it has been expired but remains
because it is referenced by SPD entries.
.It Fl d
Enable to print debugging messages for command parser,
without talking to kernel. It is not used usually.
without talking to kernel.
It is not used usually.
.It Fl x
Loop forever and dump all the messages transmitted to
.Dv PF_KEY
socket.
.Fl xx
makes each timestamps unformatted.
.It Fl h
Add hexadecimal dump on
.Fl x
@ -108,14 +111,13 @@ Loop forever with short output on
.Fl D .
.It Fl v
Be verbose.
The program will dump messages exchanged on
.Dv PF_KEY
socket
.Po
including messages sent from other processes
.Pc .
socket, including messages sent from other processes to the kernel.
.El
.Pp
Operations have the following grammar. Note that lines starting with
Operations have the following grammar.
Note that lines starting with
hashmarks ('#') are treated as comment lines.
.Bl -tag -width Ds
.It Xo
@ -142,6 +144,13 @@ Show an SAD entry.
Remove an SAD entry.
.\"
.It Xo
.Li deleteall
.Ar src Ar dst Ar protocol
.Li ;
.Xc
Remove all SAD entries that match the specification.
.\"
.It Xo
.Li flush
.Op Ar protocol
.Li ;
@ -227,7 +236,7 @@ attached
.\"
.Pp
.It Ar extensions
take some of the following:
takes some of the following:
.Bl -tag -width Fl -compact
.\"
.It Fl m Ar mode
@ -243,39 +252,49 @@ The default value is
.It Fl r Ar size
Specify window size of bytes for replay prevention.
.Ar size
must be decimal number in 32-bit word. If
must be decimal number in 32-bit word.
If
.Ar size
is zero or not specified, replay check don't take place.
.\"
.It Fl u Ar id
Specify the identifier of policy. See also
.Xr ipsec_set_policy 3 .
Specify the identifier of the policy entry in SPD.
See
.Ar policy .
.\"
.It Fl f Ar pad_option
defines the content of the ESP padding.
.Ar pad_option
is one of following:
.Li zero-pad , random-pad
or
.Li seq-pad
.Bl -tag -width random-pad -compact
.It Li zero-pad
All of the padding are zero.
.It Li random-pad
A series of randomized values are set.
.It Li seq-pad
A series of sequential increasing numbers started from 1 are set.
.El
.\"
.It Fl f Li nocyclic-seq
Don't allow cyclic sequence number.
.\"
.It Fl lh Ar time
.It Fl ls Ar time
Specify hard/soft lifetime.
Specify hard/soft life time duration of the SA.
.El
.\"
.Pp
.It Ar algorithm
.Bl -tag -width Fl -compact
.It Fl E Ar ealgo Ar key
Specify encryption algorithm.
Specify a encryption algorithm.
.It Fl A Ar aalgo Ar key
Specify authentication algorithm.
Specify a authentication algorithm.
If
.Fl A
is used for esp, it will be treated as ESP payload authentication algorithm.
is used with
.Ar protocol Li esp ,
it will be treated as ESP payload authentication algorithm.
.It Fl C Ar calgo Op Fl R
Specify compression algorithm.
If
@ -302,23 +321,23 @@ field needs to be smaller than
in this case.
.El
.Pp
.Li esp
SAs accept
.Ar protocol Li esp
accepts
.Fl E
and
.Fl A .
.Li esp-old
SAs accept
.Ar protocol Li esp-old
accepts
.Fl E
only.
.Li ah
.Ar protocol Li ah
and
.Li ah-old
SAs accept
accept
.Fl A
only.
.Li ipcomp
SAs accept
.Ar protocol Li ipcomp
accepts
.Fl C
only.
.Pp
@ -365,45 +384,57 @@ They must be in numeric form.
.Pp
.It Ar upperspec
Upper-layer protocol to be used.
Currently
.Li icmp ,
You can use one of words in
.Pa /etc/protocols
as
.Ar upperspec .
Or
.Li icmp6 ,
.Li ip4 ,
.Li tcp ,
.Li udp
and
.Li any
can be specified.
.Li any
stands for
.Dq any protocol .
Also you can use the protocol number.
.Pp
NOTE:
.Ar upperspec
does not work against forwarding case at this moment,
as it requires extra reassembly at forwarding node
.Pq not implemented at this moment .
We have many protocols in
.Pa /etc/protocols ,
but protocols except of TCP, UDP and ICMP may not be suitable to use with IPSec.
You have to consider and be careful to use them.
.Li icmp
.Li tcp
.Li udp
all protocols
.\"
.Pp
.It Ar policy
.Ar policy
is the one of following:
.Pp
.Bl -item -compact
.It
.Bd -literal -offset
.Xo
.Fl P
.Ar direction
.Li discard
.It
.Xc
.Xo
.Fl P
.Ar direction
.Li none
.It
.Xc
.Xo
.Fl P
.Ar direction
.Li ipsec
.Ar protocol/mode/src-dst/level
.El
.Xc
.Ed
.Pp
You must specify the direction of its policy as
.Ar direction .
@ -430,18 +461,33 @@ is either
.Li transport
or
.Li tunnel .
You must specify the end-points addresses of the SA as
If
.Ar mode
is
.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.
If
.Ar mode
is
.Li transport ,
both
.Ar src
and
.Ar dst
can be omited.
.Ar level
is to be one of the following:
.Li default , use
.Li default , use , require
or
.Li require .
.Li unique .
If the SA is not available in every level, the kernel will request
getting SA to the key exchange daemon.
.Li default
means the kernel consults to the system wide default against protocol you
specified, e.g.
@ -451,7 +497,23 @@ sysctl variable, when the kernel processes the packet.
means that the kernel use a SA if it's available,
otherwise the kernel keeps normal operation.
.Li require
means SA is required whenever the kernel deals with the packet.
means SA is required whenever the kernel sends a packet matched
with the policy.
.Li unique
is the same to require.
In addition, it allows the policy to bind with the unique out-bound SA.
If you use the SA by manual keying,
you can put the decimal number as the policy identifier after
.Li unique
separated by colon
.Sq \:
like the following;
.Li unique:number .
.Li number
must be between 1 and 32767.
It corresponds to
.Ar extensions Fl u .
.Pp
Note that
.Dq Li discard
and
@ -491,6 +553,12 @@ keyed-md5 128 ah: 96bit ICV (no document)
keyed-sha1 160 ah: 96bit ICV (no document)
160 ah-old: 128bit ICV (no document)
null 0 to 2048 for debugging
hmac-sha2-256 256 ah: 96bit ICV (no document)
256 ah-old: 128bit ICV (no document)
hmac-sha2-384 384 ah: 96bit ICV (no document)
384 ah-old: 128bit ICV (no document)
hmac-sha2-512 512 ah: 96bit ICV (no document)
512 ah-old: 128bit ICV (no document)
.Ed
.Pp
Followings are the list of encryption algorithms that can be used as
@ -508,9 +576,9 @@ des-cbc 64 esp-old: rfc1829, esp: rfc2405
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
rijndael-cbc 128/192/256 draft-ietf-ipsec-ciph-aes-cbc-00
.Ed
.Pp
Followings are the list of compression algorithms that can be used as
@ -555,7 +623,8 @@ The command exits with 0 on success, and non-zero on errors.
.\"
.Sh SEE ALSO
.Xr ipsec_set_policy 3 ,
.Xr sysctl 8
.Xr sysctl 8 ,
.Xr racoon 8
.\"
.Sh HISTORY
The

View file

@ -1,5 +1,5 @@
/* $FreeBSD$ */
/* $KAME: setkey.c,v 1.14 2000/06/10 06:47:09 sakane Exp $ */
/* $KAME: setkey.c,v 1.18 2001/05/08 04:36:39 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
@ -63,6 +63,8 @@ int postproc __P((struct sadb_msg *, int));
const char *numstr __P((int));
void shortdump_hdr __P((void));
void shortdump __P((struct sadb_msg *));
static void printdate __P((void));
static int32_t gmt2local __P((time_t));
#define MODE_SCRIPT 1
#define MODE_CMDDUMP 2
@ -79,11 +81,14 @@ int f_mode = 0;
int f_cmddump = 0;
int f_policy = 0;
int f_hexdump = 0;
int f_tflag = 0;
char *pname;
u_char m_buf[BUFSIZ];
u_int m_len;
static time_t thiszone;
extern int lineno;
extern int parse __P((FILE **));
@ -112,7 +117,9 @@ main(ac, av)
if (ac == 1) Usage();
while ((c = getopt(ac, av, "acdf:hlvxDFP")) != EOF) {
thiszone = gmt2local(0);
while ((c = getopt(ac, av, "acdf:hlvxDFP")) != -1) {
switch (c) {
case 'c':
f_mode = MODE_SCRIPT;
@ -142,6 +149,7 @@ main(ac, av)
break;
case 'x':
f_mode = MODE_PROMISC;
f_tflag++;
break;
case 'P':
f_policy = 1;
@ -199,7 +207,7 @@ get_supported()
if (f_debug)
return 0;
if (pfkey_send_register(so, PF_UNSPEC) < 0)
if (pfkey_send_register(so, SADB_SATYPE_UNSPEC) < 0)
return -1;
if (pfkey_recv_register(so) < 0)
@ -275,6 +283,7 @@ promisc()
err(1, "recv");
/*NOTREACHED*/
}
printdate();
if (f_hexdump) {
int i;
for (i = 0; i < len; i++) {
@ -541,7 +550,7 @@ shortdump(msg)
snprintf(buf, sizeof(buf), "%-3lu", (u_long)t);
printf("%s", buf);
} else
printf(" ???/???");
printf(" ??\?/???"); /* backslash to avoid trigraph ??/ */
printf(" ");
@ -576,3 +585,64 @@ shortdump(msg)
printf("\n");
}
/* From: tcpdump(1):gmt2local.c and util.c */
/*
* Print the timestamp
*/
static void
printdate()
{
struct timeval tp;
int s;
if (gettimeofday(&tp, NULL) == -1) {
perror("gettimeofday");
return;
}
if (f_tflag == 1) {
/* Default */
s = (tp.tv_sec + thiszone ) % 86400;
(void)printf("%02d:%02d:%02d.%06u ",
s / 3600, (s % 3600) / 60, s % 60, (u_int32_t)tp.tv_usec);
} else if (f_tflag > 1) {
/* Unix timeval style */
(void)printf("%u.%06u ",
(u_int32_t)tp.tv_sec, (u_int32_t)tp.tv_usec);
}
printf("\n");
}
/*
* Returns the difference between gmt and local time in seconds.
* Use gmtime() and localtime() to keep things simple.
*/
int32_t
gmt2local(time_t t)
{
register int dt, dir;
register struct tm *gmt, *loc;
struct tm sgmt;
if (t == 0)
t = time(NULL);
gmt = &sgmt;
*gmt = *gmtime(&t);
loc = localtime(&t);
dt = (loc->tm_hour - gmt->tm_hour) * 60 * 60 +
(loc->tm_min - gmt->tm_min) * 60;
/*
* If the year or julian day is different, we span 00:00 GMT
* and must add or subtract a day. Check the year first to
* avoid problems when the julian day wraps.
*/
dir = loc->tm_year - gmt->tm_year;
if (dir == 0)
dir = loc->tm_yday - gmt->tm_yday;
dt += dir * 24 * 60 * 60;
return (dt);
}

View file

@ -1,5 +1,5 @@
/* $FreeBSD$ */
/* $KAME: token.l,v 1.13 2000/06/07 00:29:14 itojun Exp $ */
/* $KAME: token.l,v 1.21 2001/05/18 05:35:01 sakane Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
@ -47,7 +47,11 @@
#include <unistd.h>
#include <errno.h>
#include "vchar.h"
#ifdef __NetBSD__
#include "parse.h"
#else
#include "y.tab.h"
#endif
#define DECHO \
if (f_debug) {printf("<%d>", yy_start); ECHO ; printf("\n"); }
@ -121,6 +125,7 @@ hostname {name}(({dot}{name})+{dot}?)?
add { PREPROC; return(ADD); }
delete { PREPROC; return(DELETE); }
deleteall { PREPROC; return(DELETEALL); }
get { PREPROC; return(GET); }
flush { PREPROC; return(FLUSH); }
dump { PREPROC; return(DUMP); }
@ -160,20 +165,23 @@ ipcomp { PREPROC; yylval.num = 0; return(PR_IPCOMP); }
{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); }
keyed-md5 { PREPROC; yylval.num = SADB_X_AALG_MD5; return(ALG_AUTH); }
keyed-sha1 { PREPROC; yylval.num = SADB_X_AALG_SHA; return(ALG_AUTH); }
hmac-sha2-256 { PREPROC; yylval.num = SADB_X_AALG_SHA2_256; return(ALG_AUTH); }
hmac-sha2-384 { PREPROC; yylval.num = SADB_X_AALG_SHA2_384; return(ALG_AUTH); }
hmac-sha2-512 { PREPROC; yylval.num = SADB_X_AALG_SHA2_512; return(ALG_AUTH); }
null { PREPROC; yylval.num = SADB_X_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); }
blowfish-cbc { PREPROC; yylval.num = SADB_X_EALG_BLOWFISHCBC; return(ALG_ENC); }
cast128-cbc { PREPROC; yylval.num = SADB_X_EALG_CAST128CBC; 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); }
rijndael-cbc { PREPROC; yylval.num = SADB_X_EALG_RIJNDAELCBC; return(ALG_ENC); }
/* compression algorithms */
{hyphen}C { PREPROC; return(F_COMP); }
@ -196,14 +204,6 @@ nocyclic-seq { PREPROC; return(NOCYCLICSEQ); }
{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); }
ip4 { PREPROC; yylval.num = IPPROTO_IPV4; 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; }
@ -277,6 +277,12 @@ any { PREPROC; return(ANY); }
return(QUOTEDSTRING);
}
[a-z0-9.\-]* {
yylval.val.len = yyleng;
yylval.val.buf = strdup(yytext);
return(STRING);
}
. {
yyfatal("Syntax error");
/*NOTREACHED*/

View file

@ -2,11 +2,12 @@
# Some portion of this document is not applicable to the code merged into
# FreeBSD-current (for example, section 5).
Implementation Note
Implementation Note
KAME Project
http://www.kame.net/
$FreeBSD$
KAME Project
http://www.kame.net/
$KAME: IMPLEMENTATION,v 1.216 2001/05/25 07:43:01 jinmei Exp $
$FreeBSD$
1. IPv6
@ -27,12 +28,7 @@ RFC1639: FTP Operation Over Big Address Records (FOOBAR)
* RFC2428 is preferred over RFC1639. ftp clients will first try RFC2428,
then RFC1639 if failed.
RFC1886: DNS Extensions to support IPv6
RFC1933: Transition Mechanisms for IPv6 Hosts and Routers
* IPv4 compatible address is not supported.
* automatic tunneling (4.3) is not supported.
* "gif" interface implements IPv[46]-over-IPv[46] tunnel in a generic way,
and it covers "configured tunnel" described in the spec.
See 1.5 in this document for details.
RFC1933: (see RFC2893)
RFC1981: Path MTU Discovery for IPv6
RFC2080: RIPng for IPv6
* KAME-supplied route6d, bgpd and hroute6d support this.
@ -42,8 +38,7 @@ RFC2283: Multiprotocol Extensions for BGP-4
RFC2292: Advanced Sockets API for IPv6
* For supported library functions/kernel APIs, see sys/netinet6/ADVAPI.
RFC2362: Protocol Independent Multicast-Sparse Mode (PIM-SM)
* RFC2362 defines packet formats for PIM-SM. draft-ietf-pim-ipv6-01.txt
is written based on this.
* RFC2362 defines the packet formats and the protcol of PIM-SM.
RFC2373: IPv6 Addressing Architecture
* KAME supports node required addresses, and conforms to the scope
requirement.
@ -82,6 +77,13 @@ RFC2553: Basic Socket Interface Extensions for IPv6
- supported but turned off by default on KAME/NetBSD,
- not supported on KAME/FreeBSD228, KAME/OpenBSD and KAME/BSDI3.
see 1.12 in this document for details.
RFC2671: Extension Mechanisms for DNS (EDNS0)
* see USAGE for how to use it.
* not supported on kame/freebsd4 and kame/bsdi4.
RFC2673: Binary Labels in the Domain Name System
* KAME/bsdi4 supports A6, DNAME and binary label to some extent.
* KAME apps/bind8 repository has resolver library with partial A6, DNAME
and binary label support.
RFC2675: IPv6 Jumbograms
* See 1.7 in this document for details.
RFC2710: Multicast Listener Discovery for IPv6
@ -89,35 +91,74 @@ RFC2711: IPv6 router alert option
RFC2732: Format for Literal IPv6 Addresses in URL's
* The spec is implemented in programs that handle URLs
(like freebsd ftpio(3) and fetch(1), or netbsd ftp(1))
draft-ietf-ipngwg-router-renum-10: Router renumbering for IPv6
draft-ietf-ipngwg-icmp-name-lookups-05: IPv6 Name Lookups Through ICMP
draft-ietf-pim-ipv6-03.txt: PIM for IPv6
* pim6dd implements dense mode. pim6sd implements sparse mode.
RFC2766: Network Address Translation - Protocol Translation (NAT-PT)
* Section 4.2 is implemented by totd (see ports/totd, or pkgsrc/net/totd).
RFC2874: DNS Extensions to Support IPv6 Address Aggregation and Renumbering
* KAME/bsdi4 supports A6, DNAME and binary label to some extent.
* KAME apps/bind8 repository has resolver library with partial A6, DNAME
and binary label support.
RFC2893: Transition Mechanisms for IPv6 Hosts and Routers
* IPv4 compatible address is not supported.
* automatic tunneling (4.3) is not supported.
* "gif" interface implements IPv[46]-over-IPv[46] tunnel in a generic way,
and it covers "configured tunnel" described in the spec.
See 1.5 in this document for details.
RFC2894: Router renumbering for IPv6
RFC3041: Privacy Extensions for Stateless Address Autoconfiguration in IPv6
RFC3056: Connection of IPv6 Domains via IPv4 Clouds
* So-called "6to4".
* "stf" interface implements it. Be sure to read
draft-itojun-ipv6-transition-abuse-01.txt
below before configuring it, there can be security issues.
draft-ietf-ipngwg-icmp-name-lookups-07: IPv6 Name Lookups Through ICMP
draft-ietf-dhc-dhcpv6-15.txt: DHCPv6
draft-ietf-dhc-dhcpv6exts-12.txt: Extensions for DHCPv6
* kame/dhcp6 has test implementation, which will not be compiled in
default compilation.
* 15/12 drafts are not explicit about padding and string termination.
at IETF48, the author confirmed that there's no padding/termination
(and extensions can appear unaligned). our code follows the comment.
draft-itojun-ipv6-tcp-to-anycast-00.txt:
Disconnecting TCP connection toward IPv6 anycast address
draft-ietf-ipngwg-scopedaddr-format-02.txt:
An Extension of Format for IPv6 Scoped Addresses
draft-ietf-ngtrans-tcpudp-relay-01.txt:
draft-ietf-ipngwg-rfc2553bis-03.txt:
Basic Socket Interface Extensions for IPv6 (revised)
draft-ietf-ipngwg-rfc2292bis-02.txt:
Advanced Sockets API for IPv6 (revised)
* Some of the updates in the draft are not implemented yet. See
TODO.2292bis for more details.
draft-ietf-mobileip-ipv6-13.txt: Mobility Support in IPv6
* See section 6.
draft-ietf-ngtrans-tcpudp-relay-04.txt:
An IPv6-to-IPv4 transport relay translator
* FAITH tcp relay translator (faithd) implements this. See 3.1 for more
details.
draft-ietf-ngtrans-6to4-06.txt:
Connection of IPv6 Domains via IPv4 Clouds without Explicit Tunnels
* "stf" interface implements it. Be sure to read the next item before
configuring it, there are security issues.
http://playground.iijlab.net/i-d/draft-itojun-ipv6-transition-abuse-00.txt:
Possible abuse against IPv6 transition technologies
* KAME does not implement RFC1933 automatic tunnel.
draft-ietf-ipngwg-router-selection-01.txt:
Default Router Preferences and More-Specific Routes
* router-side only.
draft-ietf-ipngwg-scoping-arch-02.txt:
The architecture, text representation, and usage of IPv6
scoped addresses.
* some part of the documentation (especially about the routing
model) is not supported yet.
draft-ietf-pim-sm-v2-new-02.txt
A revised version of RFC2362, which includes the IPv6 specific
packet format and protocol descriptions.
draft-ietf-dnsext-mdns-00.txt: Multicast DNS
* kame/mdnsd has test implementation, which will not be built in
default compilation. The draft will experience a major change in the
near future, so don't rely upon it.
draft-itojun-ipv6-transition-abuse-02.txt:
Possible abuse against IPv6 transition technologies (expired)
* KAME does not implement RFC1933/2893 automatic tunnel.
* "stf" interface implements some address filters. Refer to stf(4)
for details. Since there's no way to make 6to4 interface 100% secure,
we do not include "stf" interface into GENERIC.v6 compilation.
* kame/openbsd completely disables IPv4 mapped address support.
* kame/netbsd makes IPv4 mapped address support off by default.
* See section 12.6 and 14 for more details.
* See section 1.12.6 and 1.14 for more details.
draft-itojun-ipv6-tclass-api-02.txt: Socket API for IPv6 traffic class field
draft-itojun-ipv6-flowlabel-api-01.txt: Socket API for IPv6 flow label field
* no consideration is made against the use of routing headers and such.
1.2 Neighbor Discovery
@ -145,7 +186,10 @@ Some of network drivers loop multicast packets back to themselves,
even if instructed not to do so (especially in promiscuous mode).
In such cases DAD may fail, because DAD engine sees inbound NS packet
(actually from the node itself) and considers it as a sign of duplicate.
You may want to look at #if condition marked "heuristics" in
In this case, drivers should be corrected to honor IFF_SIMPLEX behavior.
For example, you may need to check source MAC address on a inbound packet,
and reject it if it is from the node itself.
You may also want to look at #if condition marked "heuristics" in
sys/netinet6/nd6_nbr.c:nd6_dad_timer() as workaround (note that the code
fragment in "heuristics" section is not spec conformant).
@ -218,84 +262,157 @@ upper-layer hints to be accepted.
non-root process - after local discussion, it looks that hints are not
that trustworthy even if they are from privileged processes)
1.3 Scope Index
If inbound ND packets carry invalid values, the KAME kernel will
drop these packet and increment statistics variable. See
"netstat -sn", icmp6 section. For detailed debugging session, you can
turn on syslog output from the kernel on errors, by turning on sysctl MIB
net.inet6.icmp6.nd6_debug. nd6_debug can be turned on at bootstrap
time, by defining ND6_DEBUG kernel compilation option (so you can
debug behavior during bootstrap). nd6_debug configuration should
only be used for test/debug purposes - for production environment,
nd6_debug must be set to 0. If you leave it to 1, malicious parties
can inject broken packet and fill up /var/log partition.
1.3 Scope Zone Index
IPv6 uses scoped addresses. It is therefore very important to
specify scope index (interface index for link-local address, or
site index for site-local address) with an IPv6 address. Without
scope index, a scoped IPv6 address is ambiguous to the kernel, and
the kernel will not be able to determine the outbound interface for a
packet. KAME code tries to address the issue in several ways.
specify the scope zone index (link index for a link-local address, or
site index for a site-local address) with an IPv6 address. Without a
zone index, a scoped IPv6 address is ambiguous to the kernel, and
the kernel would not be able to determine the outbound link for a
packet to the scoped address. KAME code tries to address the issue in
several ways.
Site-local address is very vaguely defined in the specs, and both specification
and KAME code need tons of improvements to enable its actual use.
For example, it is still very unclear how we define a site, or how we resolve
hostnames in a site. There are work underway to define behavior of routers
at site border, however, we have almost no code for site boundary node support
(both forwarding nor routing) and we bet almost noone has.
We recommend, at this moment, you to use global addresses for experiments -
there are way too many pitfalls if you use site-local addresses.
The entire architecture of scoped addresses is documented in
draft-ietf-ipngwg-scoping-arch-xx.txt. One non-trivial point of the
architecture is that the link scope is (theoretically) larger than the
interface scope. That is, two different interfaces can belong to a
same single link. However, in a normal operation, we can assume that
there is 1-to-1 relationship between links and interfaces. In
other words, we can usually put links and interfaces in the same scope
type. The current KAME implementation assumes the 1-to-1
relationship. In particular, we use interface names such as "ne1" as
unique link identifiers. This would be much more human-readable and
intuitive than numeric identifiers, but please keep your mind on the
theoretical difference between links and interfaces.
Site-local addresses are very vaguely defined in the specs, and both
the specification and the KAME code need tons of improvements to
enable its actual use. For example, it is still very unclear how we
define a site, or how we resolve host names in a site. There is work
underway to define behavior of routers at site border, but, we have
almost no code for site boundary node support (both forwarding nor
routing) and we bet almost noone has. We recommend, at this moment,
you to use global addresses for experiments - there are way too many
pitfalls if you use site-local addresses.
1.3.1 Kernel internal
In the kernel, the interface index for a link-local scope address is
In the kernel, the link index for a link-local scope address is
embedded into the 2nd 16bit-word (the 3rd and 4th bytes) in the IPv6
address.
For example, you may see something like:
fe80:1::200:f8ff:fe01:6317
in the routing table and interface address structure (struct
in6_ifaddr). The address above is a link-local unicast address
which belongs to a network interface whose interface identifier is 1.
The embedded index enables us to identify IPv6 link local
addresses over multiple interfaces effectively and with only a
in the routing table and the interface address structure (struct
in6_ifaddr). The address above is a link-local unicast address which
belongs to a network link whose link identifier is 1 (note that it
eqauls to the interface index by the assumption of our
implementation). The embedded index enables us to identify IPv6
link-local addresses over multiple links effectively and with only a
little code change.
1.3.2 Interaction with API
Ordinary userland applications should use the advanced API (RFC2292)
to specify scope index, or interface index. For the similar purpose,
the sin6_scope_id member in the sockaddr_in6 structure is defined in
RFC2553. However, the semantics for sin6_scope_id is rather vague.
If you care about portability of your application, we suggest you to
use the advanced API rather than sin6_scope_id.
There are several candidates of API to deal with scoped addresses
without ambiguity.
Routing daemons and configuration programs, like route6d and
ifconfig, will need to manipulate the "embedded" scope index.
These programs use routing sockets and ioctls (like SIOCGIFADDR_IN6)
and the kernel API will return IPv6 addresses with 2nd 16bit-word
filled in. The APIs are for manipulating kernel internal structure.
Programs that use these APIs have to be prepared about differences
in kernels anyway.
The IPV6_PKTINFO ancillary data type or socket option defined in the
advanced API (RFC2292 or draft-ietf-ipngwg-rfc2292bis-xx) can specify
the outgoing interface of a packet. Similarly, the IPV6_PKTINFO or
IPV6_RECVPKTINFO socket options tell kernel to pass the incoming
interface to user applications.
getaddrinfo(3) and getnameinfo(3) are modified to support extended numeric
IPv6 syntax, as documented in draft-ietf-ipngwg-scopedaddr-format-xx.txt.
You can specify outgoing link, by using name of the outgoing interface
like "fe80::1%ne0". This way you will be able to specify link-local scoped
address without much trouble.
To use this extension in your program, you'll need to use getaddrinfo(3),
and getnameinfo(3) with NI_WITHSCOPEID.
The implementation currently assumes 1-to-1 relationship between a link and an
interface, which is stronger than what IPv6 specs say.
Other APIs like inet_pton(3) or getipnodebyname(3) are inherently unfriendly
with scoped addresses, since they are unable to annotate addresses with
scope identifier.
These options are enough to disambiguate scoped addresses of an
incoming packet, because we can uniquely identify the corresponding
zone of the scoped address(es) by the incoming interface. However,
they are too strong for outgoing packets. For example, consider a
multi-sited node and suppose that more than one interface of the node
belongs to a same site. When we want to send a packet to the site,
we can only specify one of the interfaces for the outgoing packet with
these options; we cannot just say "send the packet to (one of the
interfaces of) the site."
Another kind of candidates is to use the sin6_scope_id member in the
sockaddr_in6 structure, defined in RFC2553 and
draft-ietf-ipngwg-rfc2553bis-xx.txt. The KAME kernel interprets the
sin6_scope_id field properly in order to disambiguate scoped
addresses. For example, if an application passes a sockaddr_in6
structure that has a non-zero sin6_scope_id value to the sendto(2)
system call, the kernel should send the packet to the appropriate zone
according to the sin6_scope_id field. Similarly, when the source or
the destination address of an incoming packet is a scoped one, the
kernel should detect the correct zone identifier based on the address
and the receiving interface, fill the identifier in the sin6_scope_id
field of a sockaddr_in6 structure, and then pass the packet to an
application via the recvfrom(2) system call, etc.
However, the semantics of the sin6_scope_id is still vague and on the
way to standardization. Additionally, not so many operating systems
support the behavior above at this moment.
In summary,
- If your target system is limited to KAME based ones (i.e. BSD
variants and KAME snaps), use the sin6_scope_id field assuming the
kernel behavior described above.
- Otherwise, (i.e. if your program should be portable on other systems
than BSDs)
+ Use the advanced API to disambiguate scoped addresses of incoming
packets.
+ To disambiguate scoped addresses of outgoing packets,
* if it is okay to just specify the outgoing interface, use the
advanced API. This would be the case, for example, when you
should only consider link-local addresses and your system
assumes 1-to-1 relationship between links and interfaces.
* otherwise, sorry but you lose. Please rush the IETF IPv6
community into standardizing the semantics of the sin6_scope_id
field.
Routing daemons and configuration programs, like route6d and ifconfig,
will need to manipulate the "embedded" zone index. These programs use
routing sockets and ioctls (like SIOCGIFADDR_IN6) and the kernel API
will return IPv6 addresses with the 2nd 16bit-word filled in. The
APIs are for manipulating kernel internal structure. Programs that
use these APIs have to be prepared about differences in kernels
anyway.
getaddrinfo(3) and getnameinfo(3) support an extended numeric IPv6
syntax, as documented in draft-ietf-ipngwg-rfc2553bis-xx.txt. You can
specify the outgoing link, by using the name of the outgoing interface
as the link, like "fe80::1%ne0" (again, note that we assume there is
1-to-1 relationship between links and interfaces.) This way you will
be able to specify a link-local scoped address without much trouble.
Other APIs like inet_pton(3) and inet_ntop(3) are inherently
unfriendly with scoped addresses, since they are unable to annotate
addresses with zone identifier.
1.3.3 Interaction with users (command line)
Most of user applications now support an extended numeric IPv6 syntax,
as documented in draft-ietf-ipngwg-scopedaddr-format-xx.txt. In this
case, you can specify outgoing link, by using the name of the outgoing
interface like "fe80::1%ne0". This is the case for some management
tools such as route(8) or ndp(8). For example, to install the IPv6
default route by hand, you can type like
Most of user applications now support the extended numeric IPv6
syntax. In this case, you can specify outgoing link, by using the name
of the outgoing interface like "fe80::1%ne0" (sorry for the duplicated
notice, but please recall again that we assume 1-to-1 relationship
between links and interfaces). This is even the case for some
management tools such as route(8) or ndp(8). For example, to install
the IPv6 default route by hand, you can type like
# route add -inet6 default fe80::9876:5432:1234:abcd%ne0
(Although we suggest you to run dynamic routing instead of static
routes, in order to avoid configuration mistakes.)
Some applications have command line options for specifying an
appropriate zone of a scoped address (like "ping6 -I ne0 ff02::1" to
specify the outgoing interface). However, you can't always expect such
options. Thus, we recommend you to use the extended format described
specify the outgoing interface). However, you can't always expect such
options. Thus, we recommend you to use the extended format described
above.
In any case, when you specify a scoped address to the command line,
@ -401,12 +518,6 @@ To summarize the sysctl knob:
1 1 invalid, or experimental
(out-of-scope of spec)
RFC2462 has validation rules against incoming RA prefix information option,
in 5.5.3 (e). This is to protect hosts from malicious (or misconfigured)
routers that advertise very short prefix lifetime.
There was an update from Jim Bound to ipngwg mailing list (look
for "(ipng 6712)" in the archive) and KAME implements Jim's update.
See 1.2 in the document for relationship between DAD and autoconfiguration.
1.4.3 DHCPv6
@ -450,22 +561,25 @@ automatically assigned to the gif interface.
KAME's source address selection takes care of the following
conditions:
- address scope
- prefix matching against the destination
- outgoing interface
- whether an address is deprecated
- whether an address is temporary (in terms of RFC 3041)
- prefix matching against the destination
Roughly speaking, the selection policy is as follows:
- always use an address that belongs to the same scope zone as the
destination.
- addresses that have equal or larger scope than the scope of the
destination are preferred.
- if multiple addresses have the equal scope, one which is longest
prefix matching against the destination is preferred.
- a deprecated address is not used in new communications if an
alternate (non-deprecated) address is available and has sufficient
scope.
- a temporary address (in terms of RFC 3041 privacy extension) are
preferred to a public address.
- if none of above conditions tie-breaks, addresses assigned on the
outgoing interface are preferred.
- if none of above conditions tie-breaks, one which is longest prefix
matching against the destination is preferred as the last resort.
For instance, ::1 is selected for ff01::1,
fe80::200:f8ff:fe01:6317%ne0 for fe80::2a0:24ff:feab:839b%ne0.
@ -484,47 +598,68 @@ The precise desripction of the algorithm is quite complicated. To
describe the algorithm, we introduce the following notation:
For a given destination D,
samescope(D): A set of addresses that have the same scope as D.
largerscope(D): A set of addresses that have a larger scope than D.
smallerscope(D): A set of addresses that have a smaller scope than D.
samescope(D): The set of addresses that have the same scope as D.
largerscope(D): The set of addresses that have a larger scope than D.
smallerscope(D): The set of addresses that have a smaller scope than D.
For a given set of addresses A,
DEP(A): a set of deprecated addresses in A.
DEP(A): the set of deprecated addresses in A.
nonDEP(A): A - DEP(A).
For a given set of addresses A,
tmp(A): the set of preferred temporary-autoconfigured or
manually-configure addresses in A.
Also, the algorithm assumes that the outgoing interface for the
destination D is determined. We call the interface "I".
The algorithm is as follows. Selection proceeds step by step as
described; For example, if an address is selected by item 1, item 2 or
described; For example, if an address is selected by item 1, item 2 and
later are not considered at all.
0. If there is no address in the same scope zone as D, just give up;
the packet will not be sent.
1. If nonDEP(samescope(D)) is not empty,
choose a longest matching address against D. If more than one
address is longest matching, choose arbitrary one provided that
an address on I is always preferred.
2. If nonDEP(largerscope(D)) is not empty,
choose an address that has the smallest scope. If more than one
address has the smallest scope, choose arbitrary one provided
1. If we do not prefer temporary addresses, go to 3.
Otherwise, and if tmp(samescope(D)) is not empty,
then choose an address that is on the interface I. If every
address is on I, or every address is on a different interface
from I, choose an arbitrary one provided that an address longest
matching against D is always preferred.
2. If tmp(largerscope(D)) is not empty,
then choose an address that has the smallest scope. If more than one
address has the smallest scope, choose an arbitrary one provided
that addresses on I are always preferred.
3. If nonDEP(samescope(D)) is not empty,
then apply the same logic as of 1.
4. If nonDEP(largerscope(D)) is not empty,
then apply the same logic as of 2.
5. If we do not prefer temporary addresses, go to 7.
Otherwise, and if tmp(DEP(samescope(D))) is not empty,
then choose an address that is on the interface I. If every
address is on I, or every address is on a different interface
from I, choose an arbitrary one provided that an address longest
matching against D is always preferred.
6. If tmp(DEP(largerscope(D))) is not empty,
then choose an address that has the smallest scope. If more than
one address has the smallest scope, choose an arbitrary one provided
that an address on I is always preferred.
3. If DEP(samescope(D)) is not empty,
choose a longest matching address against D. If more than one
address is longest matching, choose arbitrary one provided that
an address on I is always preferred.
4. If DEP(largerscope(D)) is not empty,
choose an address that has the smallest scope. If more than one
address has the smallest scope, choose arbitrary one provided
7. If DEP(samescope(D)) is not empty,
then apply the same logic as of 5.
8. If DEP(largerscope(D)) is not empty,
then apply the same logic as of 6.
9. If we do not prefer temporary addresses, go to 11.
Otherwise, and if tmp(nonDEP(smallerscope(D))) is not empty,
then choose an address that has the largest scope. If more than
one address has the largest scope, choose an arbitrary one provided
that an address on I is always preferred.
5. if nonDEP(smallerscope(D)) is not empty,
choose an address that has the largest scope. If more than one
address has the largest scope, choose arbitrary one provided
that an address on I is always preferred.
6. if DEP(smallerscope(D)) is not empty,
choose an address that has the largest scope. If more than one
address has the largest scope, choose arbitrary one provided
10. If tmp(DEP(smallerscope(D))) is not empty,
then choose an address that has the largest scope. If more than
one address has the largest scope, choose an arbitrary one provided
that an address on I is always preferred.
11. If nonDEP(smallerscope(D)) is not empty,
then apply the same logic as of 9.
12. If DEP(smallerscope(D)) is not empty,
then apply the same logic as of 10.
There exists a document about source address selection
(draft-ietf-ipngwg-default-addr-select-xx.txt). KAME's algorithm
@ -622,6 +757,15 @@ overflow due to long function call chain. KAME sys/netinet6 code
is carefully designed to avoid kernel stack overflow. Because of
this, KAME sys/netinet6 code defines its own protocol switch
structure, as "struct ip6protosw" (see netinet6/ip6protosw.h).
In addition to this, we restrict the number of extension headers
(including the IPv6 header) in each incoming packet, in order to
prevent a DoS attack that tries to send packets with a massive number
of extension headers. The upper limit can be configured by the sysctl
value net.inet6.ip6.hdrnestlimit. In particular, if the value is 0,
the node will allow an arbitrary number of headers. As of writing this
document, the default value is 50.
IPv4 part (sys/netinet) remains untouched for compatibility.
Because of this, if you receive IPsec-over-IPv4 packet with massive
number of IPsec headers, kernel stack may blow up. IPsec-over-IPv6 is okay.
@ -823,6 +967,9 @@ and initiating side). AF_INET6 and AF_INET sockets are totally separated.
Port number space is totally separate between AF_INET and AF_INET6 sockets.
It should be noted that KAME/BSDI3 and KAME/FreeBSD228 are not conformant
to RFC2553 section 3.7 and 3.8. It is due to code sharing reasons.
1.12.2 KAME/FreeBSD[34]x
KAME/FreeBSD3x and KAME/FreeBSD4x use shared tcp4/6 code (from
@ -840,7 +987,7 @@ Wildcard AF_INET6 socket grabs IPv4 connection if and only if the following
conditions are satisfied:
- there's no AF_INET socket that matches the IPv4 connection
- the AF_INET6 socket is configured to accept IPv4 traffic, i.e.
getsockopt(IPV6_BINDV6ONLY) returns 0.
getsockopt(IPV6_V6ONLY) returns 0.
(XXX need checking)
@ -859,15 +1006,19 @@ udp4/6 code (from sys/netinet/udp*). The implementation is made differently
from KAME/FreeBSD[34]x. KAME/NetBSD uses separate inpcb/in6pcb structures,
while KAME/FreeBSD[34]x uses merged inpcb structure.
It should be noted that the default configuration of KAME/NetBSD is not
conformant to RFC2553 section 3.8. It is intentionally turned off by default
for security reasons.
1.12.3.1 KAME/NetBSD, listening side
The platform can be configured to support IPv4 mapped address/special AF_INET6
wildcard bind (disabled by default). Kernel behavior can be summarized as
follows:
- default: special support code will be compiled in, but is disabled by
default. It can be controlled by sysctl (net.inet6.ip6.bindv6only),
or setsockopt(IPV6_BINDV6ONLY).
- add "INET6_BINDV6ONLY": No special support code for AF_INET6 wildcard socket
default. It can be controlled by sysctl (net.inet6.ip6.v6only),
or setsockopt(IPV6_V6ONLY).
- add "INET6_V6ONLY": No special support code for AF_INET6 wildcard socket
will be compiled in. AF_INET6 sockets and AF_INET sockets are totally
separate. The behavior is similar to what described in 1.12.1.
@ -881,7 +1032,7 @@ Wildcard AF_INET6 socket grabs IPv4 connection if and only if the following
conditions are satisfied:
- there's no AF_INET socket that matches the IPv4 connection
- the AF_INET6 socket is configured to accept IPv4 traffic, i.e.
getsockopt(IPV6_BINDV6ONLY) returns 0.
getsockopt(IPV6_V6ONLY) returns 0.
You cannot bind(2) with IPv4 mapped address. This is a workaround for port
number duplicate and other twists.
@ -919,6 +1070,9 @@ KAME/BSDi4 supports connection initiation to IPv4 mapped address
KAME/OpenBSD uses NRL-based TCP/UDP stack and inpcb source code,
which was derived from NRL IPv6/IPsec stack.
It should be noted that KAME/OpenBSD is not conformant to RFC2553 section 3.7
and 3.8. It is intentionally omitted for security reasons.
1.12.5.1 KAME/OpenBSD, listening side
KAME/OpenBSD disables special behavior on AF_INET6 wildcard bind for
@ -955,7 +1109,7 @@ mapped address or not. This adds many twists:
use EPSV/EPRT or LPSV/LPRT; /*IPv6*/
else
error;
Under SIIT environment, the correct code would be:
The correct code, with consideration to IPv4 mapped address, would be:
if (sa_family == AF_INET)
use EPSV/EPRT or PASV/PORT; /*IPv4*/
else if (sa_family == AF_INET6 && IPv4 mapped address)
@ -970,17 +1124,40 @@ mapped address or not. This adds many twists:
- By enabling kernel support for IPv4 mapped address (outgoing direction),
servers on the kernel can be hosed by IPv6 native packet that has IPv4
mapped address in IPv6 header source, and can generate unwanted IPv4 packets.
http://playground.iijlab.net/i-d/draft-itojun-ipv6-transition-abuse-00.txt
talks more about this scenario.
draft-itojun-ipv6-transition-abuse-01.txt talks more about this scenario.
Due to the above twists, some of KAME userland programs has restrictions on
the use of IPv4 mapped addresses:
- rshd/rlogind do not accept connections from IPv4 mapped address.
This is to avoid malicious use of IPv4 mapped address in IPv6 native
packet, to bypass source-address based authentication.
- ftp/ftpd does not support SIIT environment. IPv4 mapped address will be
decoded in userland, and will be passed to AF_INET sockets
(SIIT client should pass IPv4 mapped address as is, to AF_INET6 sockets).
- ftp/ftpd assume that you are on dual stack network. IPv4 mapped address
will be decoded in userland, and will be passed to AF_INET sockets
(in other words, ftp/ftpd do not support SIIT environment).
1.12.7 Interaction with SIIT translator
SIIT translator is specified in RFC2765. KAME node cannot become a SIIT
translator box, nor SIIT end node (a node in SIIT cloud).
To become a SIIT translator box, we need to put additional code for that.
We do not have the code in our tree at this moment.
There are multiple reasons that we are unable to become SIIT end node.
(1) SIIT translators require end nodes in the SIIT cloud to be IPv6-only.
Since we are unable to compile INET-less kernel, we are unable to become
SIIT end node. (2) As presented in 1.12.6, some of our userland code assumes
dual stack network. (3) KAME stack filters out IPv6 packets with IPv4
mapped address in the header, to secure non-SIIT case (which is much more
common). Effectively KAME node will reject any packets via SIIT translator
box. See section 1.14 for more detail about the last item.
There are documentation issues too - SIIT document requires very strange
things. For example, SIIT document asks IPv6-only (meaning no IPv4 code)
node to be able to construct IPv4 IPsec headers. If a node knows how to
construct IPv4 IPsec headers, that is not an IPv6-only node, it is a dual-stack
node. The requirements imposed in SIIT document contradict with the other
part of the document itself.
1.13 sockaddr_storage
@ -1036,22 +1213,45 @@ or bypass security controls:
IPv4 address (if they are in IPv6 native packet header, they are malicious)
::ffff:0.0.0.0/104 ::ffff:127.0.0.0/104
::ffff:224.0.0.0/100 ::ffff:255.0.0.0/104
- 6to4 prefix generated from unspecified/multicast/loopback/broadcast/private
IPv4 address
- 6to4 (RFC3056) prefix generated from unspecified/multicast/loopback/
broadcast/private IPv4 address
2002:0000::/24 2002:7f00::/24 2002:e000::/24
2002:ff00::/24 2002:0a00::/24 2002:ac10::/28
2002:c0a8::/32
- IPv4 compatible address that embeds unspecified/multicast/loopback/broadcast
IPv4 address (if they are in IPv6 native packet header, they are malicious).
Note that, since KAME doe snot support RFC1933/2893 auto tunnels, KAME nodes
are not vulnerable to these packets.
::0.0.0.0/104 ::127.0.0.0/104 ::224.0.0.0/100 ::255.0.0.0/104
Also, since KAME does not support RFC1933 auto tunnels, seeing IPv4 compatible
is very rare. You should take caution if you see those on the wire.
Also, since KAME does not support RFC1933/2893 auto tunnels, seeing IPv4
compatible is very rare. You should take caution if you see those on the wire.
If we see IPv6 packets with IPv4 mapped address (::ffff:0.0.0.0/96) in the
header in dual-stack environment (not in SIIT environment), they indicate
that someone is trying to inpersonate IPv4 peer. The packet should be dropped.
IPv6 specifications do not talk very much about IPv6 unspecified address (::)
in the IPv6 source address field. Clarification is in progress.
Here are couple of comments:
- IPv6 unspecified address can be used in IPv6 source address field, if and
only if we have no legal source address for the node. The legal situations
include, but may not be limited to, (1) MLD while no IPv6 address is assigned
to the node and (2) DAD.
- If IPv6 TCP packet has IPv6 unspecified address, it is an attack attempt.
The form can be used as a trigger for TCP DoS attack. KAME code already
filters them out.
- The following examples are seemingly illegal. It seems that there's general
consensus among ipngwg for those. (1) mobile-ip6 home address option,
(2) offlink packets (so routers should not forward them).
KAME implmements (2) already.
KAME code is carefully written to avoid such incidents. More specifically,
KAME kernel will reject packets with certain source/dstination address in IPv6
base header, or IPv6 routing header. Also, KAME default configuration file
is written carefully, to avoid those attacks.
http://playground.iijlab.net/i-d/draft-itojun-ipv6-transition-abuse-00.txt
talks about more about this.
draft-itojun-ipv6-transition-abuse-01.txt talks about more about this.
1.15 Node's required addresses
@ -1098,6 +1298,38 @@ like ff02::9 for RIPng.
Users can join groups by using appropriate system calls like setsockopt(2).
1.16 Advanced API
Current KAME kernel implements 2292bis API, documented in
draft-ietf-ipngwg-rfc2292bis-xx.txt. It also implements RFC2292 API,
for backward compatibility purposes with *BSD-integrated codebase.
KAME tree ships with 2292bis headers.
*BSD-integrated codebase implements either RFC2292, or 2292bis, API.
see "COVERAGE" document for detailed implementation status.
Here are couple of issues to mention:
- *BSD-integrated binaries, compiled for RFC2292, will work on KAME kernel.
For example, OpenBSD 2.7 /sbin/rtsol will work on KAME/openbsd kernel.
- KAME binaries, compiled using 2292bis, will not work on *BSD-integrated
kenrel. For example, KAME /usr/local/v6/sbin/rtsol will not work on
OpenBSD 2.7 kernel.
- 2292bis API is not compatible with RFC2292 API. 2292bis #define symbols
conflict with RFC2292 symbols. Therefore, if you compile programs that
assume RFC2292 API, the compilation itself goes fine, however, the compiled
binary will not work correctly. The problem is not KAME issue, but API
issue. For example, Solaris 8 implements 2292bis API. If you compile
RFC2292-based code on Solaris 8, the binary can behave strange.
There are few (or couple of) incompatible behavior in RFC2292 binary backward
compatibility support in KAME tree. To enumerate:
- Type 0 routing header lacks support for strict/loose bitmap.
Even if we see packets with "strict" bit set, those bits will not be made
visible to the userland.
Background: RFC2292 document is based on RFC1883 IPv6, and it uses
strict/loose bitmap. 2292bis document is based on RFC2460 IPv6, and it has
no strict/loose bitmap (it was removed from RFC2460). KAME tree obeys
RFC2460 IPv6, and lacks support for strict/loose bitmap.
2. Network Drivers
KAME requires three items to be added into the standard drivers:
@ -1228,7 +1460,16 @@ Here is a list of FreeBSD 3.x-RELEASE drivers and its conditions:
More drivers will just simply work on KAME FreeBSD 3.x-RELEASE but have not
been checked yet.
2.5 OpenBSD 2.x
2.5 FreeBSD 4.x-RELEASE
Here is a list of FreeBSD 4.x-RELEASE drivers and its conditions:
driver multicast
--- ---
(Ethernet)
lnc/vmware ok
2.6 OpenBSD 2.x
Here is a list of OpenBSD 2.x drivers and its conditions:
@ -1246,7 +1487,7 @@ Here is a list of OpenBSD 2.x drivers and its conditions:
configuration. This happens with certain revision of chipset on the card.
Should be fixed by now by workaround in sys/net/if.c, but still not sure.
2.6 BSD/OS 4.x
2.7 BSD/OS 4.x
The following lists BSD/OS 4.x device drivers and its conditions:
@ -1306,11 +1547,11 @@ the connection will be relayed toward IPv4 destination 163.221.202.12.
faithd must be invoked on FAITH-relay dual stack node.
For more details, consult kame/kame/faithd/README and
draft-ietf-ngtrans-tcpudp-relay-01.txt.
draft-ietf-ngtrans-tcpudp-relay-04.txt.
3.2 IPv6-to-IPv4 header translator
# removed since it is not imported to FreeBSD-current
(to be written)
4. IPsec
@ -1324,6 +1565,9 @@ Note that KAME/OpenBSD does NOT include support for KAME IPsec code,
as OpenBSD team has their home-brew IPsec stack and they have no plan
to replace it. IPv6 support for IPsec is, therefore, lacking on KAME/OpenBSD.
http://www.netbsd.org/Documentation/network/ipsec/ has more information
including usage examples.
4.1 Policy Management
The kernel implements experimental policy management code. There are two way
@ -1383,10 +1627,8 @@ Tunnel mode works basically fine, but comes with the following restrictions:
IPsec tunnel as pseudo interfaces.
- Authentication model for AH tunnel must be revisited. We'll need to
improve the policy management engine, eventually.
- Tunnelling for IPv6 IPsec is still incomplete. This is disabled by default.
If you need to perform experiments, add "options IPSEC_IPV6FWD" into
the kernel configuration file. Note that path MTU discovery does not work
across IPv6 IPsec tunnel gateway due to insufficient code.
- Path MTU discovery does not work across IPv6 IPsec tunnel gateway due to
insufficient code.
AH specificaton does not talk much about "multiple AH on a packet" case.
We incrementally compute AH checksum, from inside to outside. Also, we
@ -1401,6 +1643,16 @@ we do it incrementally. As a result, we get crypto checksums like below:
Also note that AH3 has the smallest sequence number, and AH1 has the largest
sequence number.
To avoid traffic analysis on shorter packets, ESP output logic supports
random length padding. By setting net.inet.ipsec.esp_randpad (or
net.inet6.ipsec6.esp_randpad) to positive value N, you can ask the kernel
to randomly pad packets shorter than N bytes, to random length smaller than
or equal to N. Note that N does not include ESP authentication data length.
Also note that the random padding is not included in TCP segment
size computation. Negative value will turn off the functionality.
Recommeded value for N is like 128, or 256. If you use a too big number
as N, you may experience inefficiency due to fragmented packtes.
4.4 IPComp handling
IPComp stands for IP payload compression protocol. This is aimed for
@ -1448,13 +1700,15 @@ Here are some points to be noted:
The IPsec code in the kernel conforms (or, tries to conform) to the
following standards:
"old IPsec" specification documented in rfc182[5-9].txt
"new IPsec" specification documented in rfc240[1-6].txt, rfc241[01].txt,
rfc2451.txt and draft-mcdonald-simple-ipsec-api-01.txt (draft expired,
but you can take from ftp://ftp.kame.net/pub/internet-drafts/).
(NOTE: IKE specifications, rfc240[7-9].txt are implemented in userland,
as "racoon" IKE daemon)
"new IPsec" specification documented in:
rfc240[1-6].txt rfc241[01].txt rfc2451.txt
draft-mcdonald-simple-ipsec-api-01.txt
(expired, available in ftp://ftp.kame.net/pub/internet-drafts/)
draft-ietf-ipsec-ciph-aes-cbc-00.txt
IPComp:
RFC2393: IP Payload Compression Protocol (IPComp)
IKE specifications (rfc240[7-9].txt) are implemented in userland
as "racoon" IKE daemon.
Currently supported algorithms are:
old IPsec AH
@ -1472,6 +1726,9 @@ Currently supported algorithms are:
keyed SHA1 with 96bit crypto checksum (no document)
HMAC MD5 with 96bit crypto checksum (rfc2403.txt
HMAC SHA1 with 96bit crypto checksum (rfc2404.txt)
HMAC SHA2-256 with 96bit crypto checksum (no document)
HMAC SHA2-384 with 96bit crypto checksum (no document)
HMAC SHA2-512 with 96bit crypto checksum (no document)
new IPsec ESP
null encryption (rfc2410.txt)
DES-CBC with derived IV
@ -1480,7 +1737,9 @@ Currently supported algorithms are:
3DES-CBC with explicit IV (rfc2451.txt)
BLOWFISH CBC (rfc2451.txt)
CAST128 CBC (rfc2451.txt)
RC5 CBC (rfc2451.txt)
RIJNDAEL/AES CBC (draft-ietf-ipsec-ciph-aes-cbc-00.txt,
uses IANA-assigned protocol number)
TWOFISH CBC (draft-ietf-ipsec-ciph-aes-cbc-00.txt)
each of the above can be combined with:
ESP authentication with HMAC-MD5(96bit)
ESP authentication with HMAC-SHA1(96bit)
@ -1560,26 +1819,104 @@ coverage for IPsec crypto algorithms documented in RFC (we do not cover
algorithms with intellectual property issues, though).
Here are (some of) platforms we have tested IPsec/IKE interoperability
in the past, in no particular order. Note that both ends (KAME and
in the past, no particular order. Note that both ends (KAME and
others) may have modified their implementation, so use the following
list just for reference purposes.
Altiga, Ashley-laurent (vpcom.com), Data Fellows (F-Secure),
BlueSteel, CISCO, Ericsson, ACC, Fitel, FreeS/WAN, HITACHI, IBM
AIX, IIJ, Intel, Microsoft WinNT, NAI PGPnet,
NIST (linux IPsec + plutoplus), Netscreen, OpenBSD isakmpd, Radguard,
RedCreek, Routerware, SSH, Secure Computing, Soliton, Toshiba,
TIS/NAI Gauntret, VPNet, Yamaha RT100i
ACC, allied-telesis, Altiga, Ashley-laurent (vpcom.com), BlueSteel,
CISCO IOS, Cryptek, Checkpoint FW-1, Data Fellows (F-Secure),
Ericsson, Fitel, FreeS/WAN, HiFn, HITACHI, IBM AIX, IIJ, Intel Canada,
Intel Packet Protect, MEW NetCocoon, MGCS, Microsoft WinNT/2000,
NAI PGPnet, NetLock, NIST (linux IPsec + plutoplus), NEC IX5000,
Netscreen, NxNetworks, OpenBSD isakmpd, Pivotal, Radguard, RapidStream,
RedCreek, Routerware, RSA, SSH (both IPv4/IPv6), Secure Computing,
Soliton, Sun Solaris8, TIS/NAI Gauntret, Toshiba, VPNet,
Yamaha RT series
Here are (some of) platforms we have tested IPComp/IKE interoperability
in the past, in no particular order.
IRE
IRE, SSH (both IPv4/IPv6), NetLock
VPNC (vpnc.org) provides IPsec conformance tests, using KAME and OpenBSD
IPsec/IKE implementations. Their test results are available at
http://www.vpnc.org/conformance.html, and it may give you more idea
about which implementation interoperates with KAME IPsec/IKE implementation.
5. ALTQ
# removed since it is not imported to FreeBSD-current
KAME kit includes ALTQ 2.1 code, which supports FreeBSD2, FreeBSD3,
NetBSD and OpenBSD. For BSD/OS, ALTQ does not work.
ALTQ in KAME supports (or tries to support) IPv6.
(actually, ALTQ is developed on KAME repository since ALTQ 2.1 - Jan 2000)
ALTQ occupies single character device number. For FreeBSD, it is officially
allocated. For OpenBSD and NetBSD, we use the number which is not
currently allocated (will eventually get an official number).
The character device is enabled for i386 architecture only. To enable and
compile ALTQ-ready kernel for other archititectures, take the following steps:
- assume that your architecture is FOOBAA.
- modify sys/arch/FOOBAA/FOOBAA/conf.c (or somewhere that defines cdevsw),
to include a line for ALTQ. look at sys/arch/i386/i386/conf.c for
example. The major number must be same as i386 case.
- copy kernel configuration file (like ALTQ.v6 or GENERIC.v6) from i386,
and modify accordingly.
- build a kernel.
- before building userland, change netbsd/{lib,usr.sbin,usr.bin}/Makefile
(or openbsd/foobaa) so that it will visit altq-related sub directories.
6. mobile-ip6
# removed since it is not imported to FreeBSD-current
6.1 KAME node as correspondent node
Default installation recognizes home address option (in destination
options header). No sub-options are supported. interaction with
IPsec, and/or 2292bis API, needs further study.
6.2 KAME node as home agent/mobile node
KAME kit includes Ericsson mobile-ip6 code. The integration is just started
(in Feb 2000), and we will need some more time to integrate it better.
See kame/mip6config/{QUICKSTART,README_MIP6.txt} for more details.
The Ericsson code implements revision 09 of the mobile-ip6 draft. There
are other implementations available:
NEC: http://www.6bone.nec.co.jp/mipv6/internal-dist/ (-13 draft)
SFC: http://neo.sfc.wide.ad.jp/~mip6/ (-13 draft)
7. Coding style
The KAME developers basically do not make a bother about coding
style. However, there is still some agreement on the style, in order
to make the distributed develoment smooth.
- the tab character should be 8 columns wide (tabstops are at 8, 16, 24, ...
column). With vi, use ":set ts=8 sw=8".
- each line should be within 80 characters.
- keep a single open/close bracket in a comment such as in the following
line:
putchar('('); /* ) */
without this, some vi users would have a hard time to match a pair of
brackets. Although this type of bracket seems clumsy and is even
harmful for some other type of vi users and Emacs users, the
agreement in the KAME developers is to allow it.
- add the following line to the head of every KAME-derived file:
/* (dollar)KAME(dollar) */
where "(dollar)" is the dollar character ($), and around "$" are tabs.
(this is for C. For other language, you should use its own comment
line.)
Once commited to the CVS repository, this line will contain its
version number (see, for example, at the top of this file). This
would make it easy to report a bug.
- when creating a new file with the WIDE copyright, tap "make copyright.c" at
the top-level, and use copyright.c as a template. KAME RCS tag will be
included automatically.
- when editting a third-party package, keep its own coding style as
much as possible, even if the style does not follow the items above.
When you want to contribute something to the KAME project, and if *you
do not mind* the agreement, it would be helpful for the project to
keep these rules. Note, however, that we would never intend to force
you to adopt our rules. We would rather regard your own style,
especially when you have a policy about the style.
<end of IMPLEMENTATION>

View file

@ -1,12 +1,12 @@
USAGE
KAME Project
http://www.kame.net/newsletter/
$FreeBSD$
USAGE
KAME Project
$KAME: USAGE,v 1.33 2000/11/22 10:22:57 itojun Exp $
$FreeBSD$
This is a introduction of how to use the commands provided in the KAME
kit. For more information, please refer to each man page.
<<<ifconfig>>>
A link-local address is automatically assigned to each interface, when
@ -14,6 +14,11 @@ the interface becomes up for the first time. Even if you find an interface
without a link-local address, do not panic. The link-local address will be
assigned when it becomes up (with "ifconfig IF up").
If you do not see a link-local address assigned to an interface on "ifconfig
up", the interface does not support IPv6 for some reasons - for example,
if the interface does not support link-layer multicast (IFF_MULTICAST is not
set), the interface cannot be used for IPv6.
Some network drivers allow an interface to become up even without a
hardware address (for example, PCMCIA network cards). In such cases, it is
possible that an interface has no link-local address even if the
@ -21,190 +26,187 @@ interface is up. If you see such situation, please disable the
interface once and then re-enable it (i.e. do `ifconfig IF down;
ifconfig IF up').
Pseudo interfaces (like "gif" tunnel device) will borrow IPv6 interface
identifier (lowermost 64bit of the address) from EUI64/IEEE802 sources,
like ethernet cards. Pseudo interfaces will be able to get IPv6 link-local
address, if you have other "real" interface configured beforehand.
If you have no EUI64/IEEE802 sources on the node, you may need to configure
link-local address manually. Though we have last-resort code in the kernel,
which generates interface identifier from MD5(hostname), it may not suitable
for your usage (for example, if you configure same hostname on both sides
of gif tunnel, you will be doomed).
Pseudo interfaces (like "gif" tunnel device) will borrow IPv6
interface identifier (lowermost 64bit of the address) from
EUI64/IEEE802 sources, like ethernet cards. Pseudo interfaces will be
able to get an IPv6 link-local address, if you have other "real"
interface configured beforehand. If you have no EUI64/IEEE802 sources
on the node, we have last-resort code in the kernel, which generates
interface identifier from MD5(hostname). MD5(hostname) may not be suitable
for your usage (for example, if you configure same hostname on both sides of
gif tunnel, you will be doomed), and if so, you may need to configure
link-local address manually.
See RFC2472 for more discussion on how to generate an interface ID for
pseudo interfaces.
If you have a router announcing Router Advertisement,
global addresses will be assigned automatically. So, "ifconfig" is not
necessary for your *host*. (Please refer to "sysctl" section for configuring
a host to accept Router Advertisement.)
global addresses will be assigned automatically. So, neither
"ifconfig" nor "prefix" is necessary for your *host* (non-router node).
(Please refer to "sysctl" section for configuring a host to accept
Router Advertisement.)
If you want to set up a router, you need to assign global addresses
for two or more interfaces by "ifconfig" or "prefix". (prefix command
is described at next section)
for two or more interfaces by "ifconfig" or "prefix" (prefix command
is described at next section).
If you want to assign a global address by "ifconfig", don't forget to
specify the "alias" argument to keep the link-local address.
# ifconfig de0 inet6 fec0:0:0:1000:200:f8ff:fe01:6317 alias
# ifconfig de0 inet6 3ffe:501:808:1:200:f8ff:fe01:6317 prefixlen 64 alias
# ifconfig de0
de0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
inet 172.16.202.12 netmask 0xffffff00 broadcast 172.16.202.255
inet6 fe80::200:f8ff:fe01:6317%de0 prefixlen 64
inet6 fec0:0:0:1000:200:f8ff:fe01:6317 prefixlen 64
inet6 fec0:0:0:1000:: prefixlen 64 anycast
ether 00:00:f8:01:63:17
media: autoselect (10baseT/UTP) status: active
supported media: autoselect 100baseTX <full-duplex> 100baseTX 10baseT/UTP <full-duplex> 10baseT/UTP
inet6 fe80::200:f8ff:fe01:6317%de0 prefixlen 64 scopeid 0x1
inet 163.221.202.12 netmask 0xffffff00 broadcast 163.221.202.255
inet6 3ffe:501:808:1:200:f8ff:fe01:6317 prefixlen 64
ether 00:00:f8:01:63:17
media: 100baseTX status: active
See also "/etc/rc.network6" for actual examples.
<<prefix>>
In IPv6 architecture, an IPv6 address of an interface can be generated
from a prefix assigned to it, and a link-dependent identifier for the
interface. Assigning a full IPv6 address by ifconfig is not
necessary anymore, because, user can only take care of prefix, by letting
system take care of interface identifier.
In the IPv6 architecture, an IPv6 address of an interface can be
generated from a prefix assigned to the interface, and a
link-dependent identifier for the interface. So assigning a full IPv6
address by ifconfig is not necessary anymore, because user can only
take care of prefix, by letting system take care of interface
identifier.
The newly added "prefix" command enables user to just assign prefixes
for interfaces, and let your system automatically generate IPv6
addresses. Prefixes added by the "prefix" command is maintained in
the kernel consistently with prefixes assigned by Router
Renumbering(in case of routers).
Advertisement (in case of hosts) and with prefixes assigned by Router
Renumbering (in case of routers). Manual assignment of prefixes or
change of prefix properties take precedence over ones assigned by
Router Advertisement or Router Renumbering.
But "prefix" command can only be used on router, because host should be
able to configure its addr automatically. Prefixes added by the "prefix"
command are maintained independently from prefixes assigned by
Router Advertisement. Those two type of prefixes should not coexist on
a machine at the same time, and when it happens, it is considered to be
miss configuration.
prefix command works only on routers.
Manual assignment of prefixes or change of prefix properties take
precedence over ones assigned by Router Renumbering.
If you want to assign a prefix(and consequently an address) manually, do
If you want to assign a prefix (and consequently address) manually, do
as follows:
# prefix de0 fec0:0:0:1000::
# ifconfig de0
de0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
inet 172.16.202.12 netmask 0xffffff00 broadcast 172.16.202.255
inet6 fe80:1::200:f8ff:fe01:6317 prefixlen 64
inet6 fec0:0:0:1000:200:f8ff:fe01:6317 prefixlen 64
inet6 fec0:0:0:1000:: prefixlen 64 anycast
ether 00:00:f8:01:63:17
media: autoselect (10baseT/UTP) status: active
supported media: autoselect 100baseTX <full-duplex> 100baseTX 10baseT/UTP <full-duplex> 10baseT/UTP
inet6 fe80::200:f8ff:fe01:6317%de0 prefixlen 64 scopeid 0x1
inet 163.221.202.12 netmask 0xffffff00 broadcast 163.221.202.255
ether 00:00:f8:01:63:17
media: 100baseTX status: active
# prefix de0 3ffe:501:808:1::
# ifconfig de0
de0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
inet6 fe80::200:f8ff:fe01:6317%de0 prefixlen 64 scopeid 0x1
inet 163.221.202.12 netmask 0xffffff00 broadcast 163.221.202.255
inet6 3ffe:501:808:1:200:f8ff:fe01:6317 prefixlen 64
ether 00:00:f8:01:63:17
media: 100baseTX status: active
To check assigned prefix, use the "ndp" command. (See description of
ndp command about its usage)
To check assigned prefix, use the "ndp" command (See description of
ndp command about its usage).
# ndp -p
fec0:0:0:1000::/64 if=de0
flags=LA, vltime=2592000, pltime=604800, expire=Never
3ffe:501:808:1::/64 if=de0
flags=LA, vltime=2592000, pltime=604800, expire=Never, origin=RR
No advertising router
The "prefix" command also has node internal prefix renumbering
ability.
If you have multiple prefixes which have fec0:0:0:1000:/56 at the top,
and would like to renumber them to fec0:0:0:2000:/56, then use the
If you have multiple prefixes which have 3ffe:501:808:/48 at the top,
and would like to renumber them to 3ffe:501:4819:/48, then use the
"prefix" command with the "matchpr" argument and the "usepr" argument.
Suppose that current state of before renumbering as follows:
# ifconfig de0
de0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
inet 172.16.202.12 netmask 0xffffff00 broadcast 172.16.202.255
inet6 fe80:1::200:f8ff:fe01:6317 prefixlen 64
inet6 fec0:0:0:1000:200:f8ff:fe01:6317 prefixlen 64
inet6 fec0:0:0:1000:: prefixlen 64 anycast
ether 00:00:f8:01:63:17
media: autoselect (10baseT/UTP) status: active
supported media: autoselect 100baseTX <full-duplex> 100baseTX 10baseT/UTP <full-duplex> 10baseT/UTP
inet6 fe80::200:f8ff:fe01:6317%de0 prefixlen 64 scopeid 0x1
inet 163.221.202.12 netmask 0xffffff00 broadcast 163.221.202.255
inet6 3ffe:501:808:1:200:f8ff:fe01:6317 prefixlen 64
ether 00:00:f8:01:63:17
media: 100baseTX status: active
# ifconfig de1
de1: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
inet 172.16.203.12 netmask 0xffffff00 broadcast 172.16.203.255
inet6 fe80:1::200:f8ff:fe55:7011 prefixlen 64
inet6 fec0:0:0:1001:200:f8ff:fe55:7011 prefixlen 64
inet6 fec0:0:0:1001:: prefixlen 64 anycast
inet6 fe80::200:f8ff:fe55:7011%de1 prefixlen 64 scopeid 0x2
inet 163.221.203.12 netmask 0xffffff00 broadcast 163.221.203.255
inet6 3ffe:501:808:2:200:f8ff:fe55:7011 prefixlen 64
ether 00:00:f8:55:70:11
media: autoselect (10baseT/UTP) status: active
supported media: autoselect 100baseTX <full-duplex> 100baseTX 10baseT/UTP <full-duplex> 10baseT/UTP
media: 100baseTX status: active
# ndp -p
fec0:0:0:1000::/64 if=de0
flags=LA, vltime=2592000, pltime=604800, expire=Never
3ffe:501:808:1::/64 if=de0
flags=LA, vltime=2592000, pltime=604800, expire=Never, origin=RR
No advertising router
fec0:0:0:1001::/64 if=de1
flags=LA, vltime=2592000, pltime=604800, expire=Never
3ffe:501:808:2::/64 if=de1
flags=LA, vltime=2592000, pltime=604800, expire=Never, origin=RR
No advertising router
Then do as follows:
# prefix -a matchpr fec0:0:0:1000:: mp_len 56 usepr fec0:0:0:2000:: up_uselen 56 change
# prefix -a matchpr 3ffe:501:808:: mp_len 48 usepr 3ffe:501:4819:: up_uselen 48 change
If command is successful, prefixes and addresses will be renumbered as
follows.
# ifconfig de0
de0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
inet 172.16.202.12 netmask 0xffffff00 broadcast 172.16.202.255
inet6 fe80:1::200:f8ff:fe01:6317 prefixlen 64
inet6 fec0:0:0:2000:200:f8ff:fe01:6317 prefixlen 64
inet6 fec0:0:0:2000:: prefixlen 64 anycast
ether 00:00:f8:01:63:17
media: autoselect (10baseT/UTP) status: active
supported media: autoselect 100baseTX <full-duplex> 100baseTX 10baseT/UTP <full-duplex> 10baseT/UTP
inet6 fe80::200:f8ff:fe01:6317%de0 prefixlen 64 scopeid 0x1
inet 163.221.202.12 netmask 0xffffff00 broadcast 163.221.202.255
inet6 3ffe:501:4819:1:200:f8ff:fe01:6317 prefixlen 64
ether 00:00:f8:01:63:17
media: 100baseTX status: active
# ifconfig de1
de1: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
inet 172.16.203.12 netmask 0xffffff00 broadcast 172.16.203.255
inet6 fe80:1::200:f8ff:fe55:7011 prefixlen 64
inet6 fec0:0:0:2001:200:f8ff:fe55:7011 prefixlen 64
inet6 fec0:0:0:2001:: prefixlen 64 anycast
inet6 fe80::200:f8ff:fe55:7011%de0 prefixlen 64 scopeid 0x2
inet 163.221.203.12 netmask 0xffffff00 broadcast 163.221.203.255
inet6 3ffe:501:4819:2:200:f8ff:fe55:7011 prefixlen 64
ether 00:00:f8:55:70:11
media: autoselect (10baseT/UTP) status: active
supported media: autoselect 100baseTX <full-duplex> 100baseTX 10baseT/UTP <full-duplex> 10baseT/UTP
media: 100baseTX status: active
# ndp -p
fec0:0:0:2000::/64 if=de0
flags=LA, vltime=2592000, pltime=604800, expire=Never
3ffe:501:4819:1::/64 if=de0
flags=LA, vltime=2592000, pltime=604800, expire=Never, origin=RR
No advertising router
fec0:0:0:2001::/64 if=de1
flags=LA, vltime=2592000, pltime=604800, expire=Never
3ffe:501:4819:2::/64 if=de1
flags=LA, vltime=2592000, pltime=604800, expire=Never, origin=RR
No advertising router
See also "/etc/rc.network6" for actual examples.
<<<route>>>
If there is a router announcing Router Advertisement on the subnet,
you don't need to add a default route for your host by yourself.
(Please refer to "sysctl" section to accept Router Advertisement.)
If there is a router announcing Router Advertisement on a subnet,
you need not to add a default route for your host by hand
(Please refer to "sysctl" section to accept Router Advertisement).
If you want to add a default route manually, do as follows:
If you want to add a default route manually, do like:
# route add -inet6 default fe80::200:a2ff:fe0e:7543%de0
# route add -inet6 default fe80::200:a2ff:fe0e:7543%ed0
"default" means ::/0.
"default" means ::/0. In other cases, if "prefixlen" is omitted, 64
is assumed for "prefixlen" to get along with the aggregatable address.
Note that, in IPv6, link-local address should be used as gateway
("fe80::200:a2ff:fe0e:7543%de1" in the above). If you use global addresses,
icmp6 redirect may not work properly. For ease of configuration we recommend
you to avoid static routes and run a routing daemon (route6d for example)
instead.
Note that, in IPv6, a link-local address should be used as gateway
("fe80::200:a2ff:fe0e:7543%ed0" in the above). If you use global addresses,
ICMPv6 redirect will not work properly. Also note that we use a special form
of link-local address as gateway. See Section 1.3 of IMPLEMENTATION for
more details.
For ease of configuration we recommend you to avoid static routes and run
a routing daemon (route6d for example) instead.
<<<ping6>>> (This might be integrated into "ping" as "ping -6" in the future.)
<<<ping6>>>
Reachability can be checked by "ping6". This "ping6" allows multicast
for its argument.
% ping6 -I xl0 ff02::1
or
% ping6 ff02::1%xl0
% ping6 -n -I ed0 ff02::1
PING6(56=40+8+8 bytes) fe80::5254:ff:feda:cb7d --> ff02::1%ed0
56 bytes from fe80::5254:ff:feda:cb7d%lo0, icmp_seq=0 hlim=64 time=0.25 ms
56 bytes from fe80::2a0:c9ff:fe84:ed6c%ed0, icmp_seq=0 hlim=64 time=1.333 ms(DUP!)
56 bytes from fe80::5254:ff:feda:d161%ed0, icmp_seq=0 hlim=64 time=1.459 ms(DUP!)
56 bytes from fe80::260:97ff:fec2:80bf%ed0, icmp_seq=0 hlim=64 time=1.538 ms(DUP!)
56 bytes from 3ffe:501:4819:2000:5054:ff:fedb:aa46, icmp_seq=0 hlim=255 time=1.615 ms(DUP!)
PING6(56=40+8+8 bytes) fe80::5254:ff:feda:cb7d --> ff02::1
56 bytes from fe80::5254:ff:feda:cb7d, icmp_seq=0 hlim=64 time=0.25 ms
56 bytes from fe80::2a0:c9ff:fe84:ed6c, icmp_seq=0 hlim=64 time=1.333 ms(DUP!)
56 bytes from fe80::5254:ff:feda:d161, icmp_seq=0 hlim=64 time=1.459 ms(DUP!)
56 bytes from fe80::260:97ff:fec2:80bf, icmp_seq=0 hlim=64 time=1.538 ms(DUP!)
<<<ping6 -w>>>
@ -212,13 +214,14 @@ Name resolution is possible by ICMPv6 node information query message.
This is very convenient for link-local addresses whose host name cannot be
resolved by DNS. Specify the "-w" option to "ping6".
% ping6 -I xl0 -w ff02::1
% ping6 -n -I ed0 -w ff02::1
64 bytes from fe80::5254:ff:feda:cb7d: fto.kame.net
67 bytes from fe80::5254:ff:feda:d161: banana.kame.net
69 bytes from fe80::2a0:c9ff:fe84:ebd9: paradise.kame.net
66 bytes from fe80::260:8ff:fe8b:447f: taroh.kame.net
66 bytes from fe80::2a0:c9ff:fe84:ed6c: ayame.kame.net
64 bytes from fe80::5254:ff:feda:cb7d%lo0: fto.kame.net
67 bytes from fe80::5254:ff:feda:d161%ed0: banana.kame.net
69 bytes from fe80::2a0:c9ff:fe84:ebd9%ed0: paradise.kame.net
66 bytes from fe80::260:8ff:fe8b:447f%ed0: taroh.kame.net
66 bytes from fe80::2a0:c9ff:fe84:ed6c%ed0: ayame.kame.net
<<<traceroute6>>>
@ -239,60 +242,59 @@ traceroute to tokyo.v6.wide.ad.jp (3ffe:501:0:401:200:e8ff:fed5:8923), 30 hops m
2 otemachi.v6.wide.ad.jp (3ffe:501:0:1802:260:97ff:feb6:7ff0) 27.345 ms 26.706 ms 26.563 ms
3 tokyo.v6.wide.ad.jp (3ffe:501:0:401:200:e8ff:fed5:8923) 26.329 ms 26.36 ms 28.63 ms
<<<ndp>>>
To display the current Neighbor cache, use "ndp":
% ndp -a
Neighbor Linklayer Address Netif Expire St Flgs Prbs
nr60.v6.kame.net 0:60:97:c2:80:bf xl0 expired S R
fec0:0:0:1000:2c0:cff:fe10 0:c0:c:10:3a:53 xl0 permanent R
paradise.v6.kame.net 52:54:0:dc:52:17 xl0 expired S R
fe80:1::200:eff:fe49:f929 0:0:e:49:f9:29 xl0 expired S R
fe80:1::200:86ff:fe05:80da 0:0:86:5:80:da xl0 expired S
fe80:1::200:86ff:fe05:c2d8 0:0:86:5:c2:d8 xl0 9s R
nr60.v6.kame.net 0:60:97:c2:80:bf ed0 expired S R
3ffe:501:4819:2000:2c0:cff:fe 0:c0:c:10:3a:53 ed0 permanent R
paradise.v6.kame.net 52:54:0:dc:52:17 ed0 expired S R
fe80::200:eff:fe49:f929%ed0 0:0:e:49:f9:29 ed0 expired S R
fe80::200:86ff:fe05:80da%ed0 0:0:86:5:80:da ed0 expired S
fe80::200:86ff:fe05:c2d8%ed0 0:0:86:5:c2:d8 ed0 9s R
To flush the all NDP cache, execute the following by root.
To flush all of the NDP cache entries, execute the following as root.
# ndp -c
To display the prefix list.
To display the prefix list:
% ndp -p
fec0:0:0::1000::/64 if=xl0
flags=LA, vltime=2592000, pltime=604800, expire=29d23h59m58s
3ffe:501:4819:2000::/64 if=ed0
flags=LA, vltime=2592000, pltime=604800, expire=29d23h59m58s, origin=RA
advertised by
fe80::5254:ff:fedc:5217
fe80::260:97ff:fec2:80bf
fe80::200:eff:fe49:f929
fe80::5254:ff:fedc:5217%ed0 (reachable)
fe80::260:97ff:fec2:80bf%ed0 (reachable)
fe80::200:eff:fe49:f929%ed0 (no neighbor state)
To display the default router list.
To display the default router list:
% ndp -r
fe80::260:97ff:fec2:80bf if=xl0, flags=, expire=29m55s
fe80::5254:ff:fedc:5217 if=xl0, flags=, expire=29m7s
fe80::200:eff:fe49:f929 if=xl0, flags=, expire=28m47s
fe80::260:97ff:fec2:80bf if=ed0, flags=, expire=29m55s
fe80::5254:ff:fedc:5217 if=ed0, flags=, expire=29m7s
fe80::200:eff:fe49:f929 if=ed0, flags=, expire=28m47s
<<<rtsol>>>
To generate a Router Solicitation message right now to get global
addresses, use "rtsol".
# ifconfig xl0
xl0: flags=8a43<UP,BROADCAST,RUNNING,ALLMULTI,SIMPLEX,MULTICAST> mtu 1500
inet6 fe80:2::2a0:24ff:feab:839b%xl0 prefixlen 64
ether 0:a0:24:ab:83:9b
media: autoselect (10baseT/UTP) status: active
supported media: autoselect 100baseTX <full-duplex> 100baseTX 10baseT/UTP <full-duplex> 10baseT/UTP 100baseTX <hw-loopback>
# rtsol xl0
# ifconfig xl0
xl0: flags=8a43<UP,BROADCAST,RUNNING,ALLMULTI,SIMPLEX,MULTICAST> mtu 1500
inet6 fe80:2::2a0:24ff:feab:839b%xl0 prefixlen 64
inet6 fec0:0:0:1000:2a0:24ff:feab:839b prefixlen 64
ether 0:a0:24:ab:83:9b
media: autoselect (10baseT/UTP) status: active
supported media: autoselect 100baseTX <full-duplex> 100baseTX 10baseT/UTP <full-duplex> 10baseT/UTP 100baseTX <hw-loopback>
# ifconfig ef0
ef0: flags=8863<UP,BROADCAST,NOTRAILERS,RUNNING,SIMPLEX,MULTICAST>
link type ether 0:a0:24:ab:83:9b mtu 1500 speed 10Mbps
media 10baseT status active
inet6 fe80::2a0:24ff:feab:839b%ef0 prefixlen 64 scopeid 0x2
# rtsol ef0
# ifconfig ef0
ef0: flags=8863<UP,BROADCAST,NOTRAILERS,RUNNING,SIMPLEX,MULTICAST>
link type ether 0:a0:24:ab:83:9b mtu 1500 speed 10Mbps
media 10baseT status active
inet6 fe80::2a0:24ff:feab:839b%ef0 prefixlen 64 scopeid 0x2
inet6 3ffe:501:4819:2000:2a0:24ff:feab:839b prefixlen 64
<<<rtsold>>>
@ -301,18 +303,23 @@ rtsold is a daemon version of rtsol. If you run KAME IPv6 on a laptop
computer and frequently move with it, the daemon is useful since it watches
the interface and sends router solicitations when the status of the interface
changes. Note, however, that the feature is disabled by default. Please
add -m option at invocation of rtsold.
add -m option when invocation of rtsold.
rtsold also supports multiple interfaces. For example, you can
invoke the daemon as follows:
# rtsold -m ep0 cnw0
<<<netstat>>>
To see routing table:
# netstat -nr
# netstat -nrl (long format with Ref and Use)
# netstat -nrl
long format with Ref and Use. Note that bsdi4 does not support the
-l option. You should use the -O option instead.
<<<sysctl>>>
@ -324,13 +331,14 @@ as follows:
# sysctl -w net.inet6.ip6.accept_rtadv=1
<<<gifconfig>>>
"gif" interface enables you to perform IPv{4,6} over IPv{4,6}
protocol tunneling. To use this interface, you must specify the
outer IPv{4,6} address by using gifconfig, like:
# gifconfig gif0 172.16.198.61 172.16.11.21
# gifconfig gif0 163.221.198.61 163.221.11.21
"ifconfig gif0" will configure the address pair used for inner
IPv{4,6} header.
@ -345,15 +353,14 @@ The following example configures un-numbered IPv6-over-IPv4 tunnel:
The following example configures numbered IPv6-over-IPv4 tunnel:
# gifconfig gif0 10.0.0.1 10.0.0.1 netmask 255.255.255.0
# ifconfig gif0 inet6 fec0:0:0:3000::1 fec0:0:0:3000::2 prefixlen 64 alias
# ifconfig gif0 inet6 3ffe:501:808:5::1 3ffe:501:808:5::2 prefixlen 64 alias
IPv6 spec allows you to use point-to-point link without global IPv6
address assigned to the interface. Routing protocol (such as RIPng)
uses link-local addresses only. If you are to configure IPv6-over-IPv4
tunnel, you need not to configure an address pair for inner IPv6
header. We suggest you to use the former example (un-numbered
IPv6-over-IPv4 tunnel) to connect to 6bone for simplicity,
for router to router connection.
IPv6-over-IPv4 tunnel) to connect to 6bone for simplicity.
Note that it is so easy to make an infinite routing loop using gif
interface, if you configure a tunnel using the same protocol family
@ -361,6 +368,16 @@ for inner and outer header (i.e. IPv4-over-IPv4).
Refer to gifconfig(8) for more details.
<<<6to4>>>
WARNING: malicious party can abuse 6to4 relay routers/sites, read through
internet draft draft-itojun-ipv6-transition-abuse-xx.txt before configuring it.
"stf" interface enables you to perform 6to4 IPv6-over-IPv4 encapsulation,
as documented in draft-ietf-ngtrans-6to4-06.txt. See stf(4) for details.
<<<inetd>>>
Inetd supports AF_INET and AF_INET6 sockets, with IPsec policy
@ -368,17 +385,18 @@ configuration support.
Refer to inetd(8) for more details.
<<<IPsec>>>
The current KAME supports both transport mode and tunnel mode.
However, tunnel mode comes with some restrictions.
http://www.kame.net/newsletter/ has more comprehensive examples.
IPsec requires fairly complex configuration, so here we show transport
mode only. http://www.kame.net/newsletter/ has more comprehensive
examples.
Let's setup security association to deploy a secure channel between
Let us setup security association to deploy a secure channel between
HOST A (10.2.3.4) and HOST B (10.6.7.8). Here we show a little
complicated example. From HOST A to HOST B, only old AH is used.
From HOST B to HOST A, new AH and new ESP are combined.
Now we should choose algorithm to be used corresponding to "AH"/"new
AH"/"ESP"/"new ESP". Please refer to the "setkey" man page to know
algorithm names. Our choice is MD5 for AH, new-HMAC-SHA1 for new AH,
@ -389,7 +407,7 @@ length must be equal to 16 bytes for MD5, 20 for new-HMAC-SHA1,
and 8 for new-DES-expIV. Now we choose "MYSECRETMYSECRET",
"KAMEKAMEKAMEKAMEKAME", "PASSWORD", respectively.
OK, let's assign SPI (Security Parameter Index) for each protocol.
OK, let us assign SPI (Security Parameter Index) for each protocol.
Please note that we need 3 SPIs for this secure channel since three
security headers are produced (one for from HOST A to HOST B, two for
from HOST B to HOST A). Please also note that SPI MUST be greater
@ -407,7 +425,7 @@ than or equal to 256. We choose, 1000, 2000, and 3000, respectively.
(2.1)
HOST A <------ HOST B
<------
(2.2)
(2.2)
(2.1)
PROTO=AH
@ -422,7 +440,7 @@ than or equal to 256. We choose, 1000, 2000, and 3000, respectively.
KEY=PASSWORD
SPI=3000
Now, let's setup security association. Execute "setkey" on both HOST
Now, let us setup security association. Execute "setkey" on both HOST
A and B:
# setkey -c
@ -442,9 +460,8 @@ spdadd 10.2.3.4 10.6.7.8 any -P out ipsec
At B:
spdadd 10.6.7.8 10.2.3.4 any -P out ipsec
esp/transport/10.6.7.8-10.2.3.4/require ;
spdadd 10.6.7.8 10.2.3.4 any -P out ipsec
ah/transport/10.6.7.8-10.2.3.4/require ;
esp/transport//require
ah/transport//require ;
^D
To utilize the security associations installed into the kernel, you
@ -454,7 +471,7 @@ the "ping" command has the -P option with parameter to enable AH and/or ESP.
For example:
% ping -P "out ipsec \
ah/transport/10.0.1.1-10.0.2.2/use \
ah/transport//use \
esp/tunnel/10.0.1.1-10.0.1.2/require" 10.0.2.2
If there are proper SAs, this policy specification causes ICMP packet
@ -467,165 +484,6 @@ to be AH transport mode inner ESP tunnel mode like below.
==================== AH ==================
Another example using IPv6.
ESP transport mode is recommended for TCP port number 110 between Host-A and
Host-B.
============ ESP ============
| |
Host-A Host-B
fec0::10 -------------------- fec0::11
Encryption algorithm is blowfish-cbc whose key is "kamekame", and
authentication algorithm is hmac-sha1 whose key is "this is the test key".
Configuration at Host-A:
# setkey -c <<EOF
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" ;
EOF
and at Host-B:
# setkey -c <<EOF
spdadd fec0::11[110] fec0::10[any] tcp -P out ipsec
esp/transport/fec0::11-fec0::10/use ;
spdadd fec0::10[any] fec0::11[110] tcp -P in ipsec
esp/transport/fec0::10-fec0::11/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" ;
EOF
Note the direction of SP.
Tunnel mode between two security gateways
Security protocol is old AH tunnel mode, i.e. specified by RFC1826, with
keyed-md5 whose key is "this is the test" as authentication algorithm.
======= 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
Configuration at Gateway-A:
# setkey -c <<EOF
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 wild-card of mode of
security protocol. You can use this SA for both tunnel and transport mode.
and at Gateway-B:
# setkey -c <<EOF
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 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" ;
Making SA bundle between two security gateways
AH transport mode and ESP tunnel mode is required between Gateway-A and
Gateway-B. In this case, ESP tunnel mode is applied first, and AH transport
mode is next.
========== 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
Encryption algorithm is 3des-cbc, and authentication algorithm for ESP is
hmac-sha1. Authentication algorithm for AH is hmac-md5.
Configuration at Gateway-A:
# setkey -c <<EOF
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" ;
Making SAs with the different end
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
Configuration at Host-A:
# setkey -c <<EOF
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:l::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" ;
<<<EDNS0>>>
EDNS0 is defined in RFC2671. With EDNS0, the resolver library can tell DNS
@ -660,4 +518,12 @@ Caveats:
- Some of our platforms do not use our extended resolver code in libinet6.
See COVERAGE for detail.
<<Further readings>>
http://www.netbsd.org/Documentation/network/ipv6/
Even if you are on non-netbsd operating system, the URL should be
useful.
http://www.kame.net/
<end of USAGE>

View file

@ -1,3 +1,5 @@
.\" $KAME: faith.4,v 1.9 2001/04/27 17:26:35 itojun Exp $
.\"
.\" Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
.\" All rights reserved.
.\"
@ -25,7 +27,6 @@
.\" 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
@ -33,33 +34,31 @@
.Os
.Sh NAME
.Nm faith
.Nd
.Tn IPv6-to-IPv4 TCP
relay capturing interface
.Nd IPv6-to-IPv4 TCP relay capturing interface
.Sh SYNOPSIS
.Cd "device faith 1"
.Cd "device faith" Op Ar count
.Sh DESCRIPTION
The
.Nm
interface captures IPv6 TCP traffic
for implementing userland IPv6-to-IPv4 TCP relays
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 the routing table suggests to route it to the
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 the list of IPv6 interface addresses assigned to the router.
The packet will be captured by an IPv6 TCP socket if it has the
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.
As a result,
In result,
.Nm
will let you divert IPv6 TCP traffic to some specific destination addresses.
will let you capture IPv6 TCP traffic to some specific destination addresses.
Userland programs, such as
.Xr faithd 8 ,
.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 2
@ -68,33 +67,29 @@ and perform application-specific address mapping to relay IPv6 TCP to IPv4 TCP.
.Pp
The
.Dv IN6P_FAITH
flag on an IPv6 TCP socket can be set by using
flag on IPv6 TCP socket can be set by using
.Xr setsockopt 2 ,
with
.Fa level
set to
with level equals to
.Dv IPPROTO_IPV6
and
.Fa optname
set to
and optname equals to
.Dv IPv6_FAITH .
.Pp
To handle error reports by ICMPv6 some of the ICMPv6 packets routed to the
To handle error reports by ICMPv6, some of ICMPv6 packets routed to
.Nm
interface will need be delivered to IPv6 TCP as well.
interface will be delivered to IPv6 TCP, as well.
.Pp
To understand how
.Nm
can be used take a look at the source code of
can be used, take a look at source code of
.Xr faithd 8 .
.Pp
As the
As
.Nm
interface implements potentially dangerous operations,
great care must be taken when configuring the
interface implements potentially dangerous operation,
great care must be taken when configuring
.Nm
interface.
To avoid possible misuse the
To avoid possible misuse,
.Xr sysctl 8
variable
.Li net.inet6.ip6.keepfaith
@ -103,13 +98,12 @@ must be set to
prior to the use of the interface.
When
.Li net.inet6.ip6.keepfaith
is set to
is
.Li 0 ,
no packets will be captured by the
no packet will be captured by
.Nm
interface.
.Pp
The
.Nm
interface is intended to be used on routers, not on hosts.
.\"
@ -117,13 +111,14 @@ interface is intended to be used on routers, not on hosts.
.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
.\"
.Rs
.%A Jun-ichiro itojun Hagino
.%A Kazu Yamamoto
.%T "An IPv6-to-IPv4 transport relay translator"
.%R internet draft
.%N draft-ietf-ngtrans-tcpudp-relay-04.txt
.%O work in progress material
.Re
.Sh HISTORY
The FAITH IPv6-to-IPv4 TCP relay translator first appeared in
The FAITH IPv6-to-IPv4 TCP relay translator was first appeared in
WIDE hydrangea IPv6 stack.

View file

@ -1,5 +1,5 @@
.\" $FreeBSD$
.\" $KAME: gif.4,v 1.17 2000/06/30 18:31:27 itojun Exp $
.\" $KAME: gif.4,v 1.28 2001/05/18 13:15:56 itojun Exp $
.\"
.\" Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
.\" All rights reserved.
@ -44,7 +44,11 @@ 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.
is mainly based on RFC2893 IPv6-over-IPv4 configured tunnel.
On
.Nx ,
.Nm
can also tunnel ISO traffic over IPv[46] using EON encapsulation.
.Pp
To use
.Nm ,
@ -70,79 +74,9 @@ Finally, use routing table to route the packets toward
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 Li 0.0.0.0
or IPv6 unspecified address
.Pq Li 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
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
@ -155,7 +89,7 @@ interface flag.
Without
.Dv IFF_LINK1 ,
.Nm
will show a normal behavior, like described in RFC1933.
will show a normal behavior, like described in RFC2893.
This can be summarized as follows:
.Bl -tag -width "Ingress" -offset indent
.It Ingress
@ -194,7 +128,7 @@ If outer ECN CE bit is
enable ECN CE bit on the inner.
.El
.Pp
Note that the ECN friendly behavior violates RFC1933.
Note that the ECN friendly behavior violates RFC2893.
This should be used in mutual agreement with the peer.
.Pp
.Ss Security
@ -206,10 +140,9 @@ performs martian filter and ingress filter against outer source address,
on egress.
Note that martian/ingress filters are no way complete.
You may want to secure your node by using packet filters.
.Pp
As mentioned above, multi-destination mode
.Pq Dv IFF_LINK0
is far less secure than bidirectional mode.
Ingress filter can be turned off by
.Dv IFF_LINK2
bit.
.\"
.Sh SEE ALSO
.Xr inet 4 ,
@ -218,10 +151,10 @@ is far less secure than bidirectional mode.
.Rs
.%A R. Gilligan
.%A E. Nordmark
.%B RFC1933
.%B RFC2893
.%T Transition Mechanisms for IPv6 Hosts and Routers
.%D April 1996
.%O ftp://ftp.isi.edu/in-notes/rfc1933.txt
.%D August 2000
.%O ftp://ftp.isi.edu/in-notes/rfc2893.txt
.Re
.Rs
.%A Sally Floyd
@ -256,7 +189,24 @@ Make sure to configure an address which belongs to your node.
Otherwise, your node will not be able to receive packets from the peer,
and your node will generate packets with a spoofed source address.
.Pp
.Xr gif 4
is an
.Dv IFF_POINTOPOINT
device, however, it supports NBMA behavior in multi-destination mode.
If the outer protocol is IPv4,
.Nm
does not try to perform path MTU discovery for the encapsulated packet
.Pq DF bit is set to 0 .
.Pp
If the outer protocol is IPv6, path MTU discovery for encapsulated packet
may affect communication over the interface.
The first bigger-than-pmtu packet may be lost.
To avoid the problem, you may want to set the interface MTU for
.Nm
to 1240 or smaller, when outer header is IPv6 and inner header is IPv4.
.Pp
.Nm
does not translate ICMP messages for outer header into inner header.
.Pp
In the past,
.Nm
had a multi-destination behavior, configurable via
.Dv IFF_LINK0
flag.
The behavior was obsoleted and is no longer supported.

View file

@ -1,5 +1,5 @@
.\" $FreeBSD$
.\" $KAME: inet6.4,v 1.16 2000/07/05 08:18:42 itojun Exp $
.\" $KAME: inet6.4,v 1.21 2001/04/05 01:00:18 itojun Exp $
.\"
.\" Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
.\" All rights reserved.
@ -74,7 +74,7 @@ as a discriminated union.
.Pp
Sockets bound to the
.Nm
family utilize the following addressing structure,
family utilize the following addressing structure:
.Bd -literal -offset indent
struct sockaddr_in6 {
u_int8_t sin6_len;
@ -95,34 +95,21 @@ which is equal to IPv6 address
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 specification defines scoped address,
like link-local or site-local address.
The IPv6 specification defines scoped addresses,
like link-local or site-local addresses.
A scoped address is ambiguous to the kernel,
if it is specified without scope identifier.
if it is specified without a scope identifier.
To manipulate scoped addresses properly from the userland,
programs must use advanced API defined in RFC2292.
Compact description on the advanced API is available in
programs must use the advanced API defined in RFC2292.
A compact description of the advanced API is available in
.Xr ip6 4 .
If scoped addresses are specified without explicit scope,
the kernel may raise error.
If a scoped address is specified without an explicit scope,
the kernel may raise an error.
Note that scoped addresses are not for daily use at this moment,
both from specification and implementation point of view.
both from a specification and an implementation point of view.
.Pp
KAME implementation supports extended numeric IPv6 address notation
The KAME implementation supports an extended numeric IPv6 address notation
for link-local addresses,
like
.Dq Li fe80::1%de0
@ -133,7 +120,7 @@ on
.Li de0
interface
.Dc .
The notation is supported by
This notation is supported by
.Xr getaddrinfo 3
and
.Xr getnameinfo 3 .
@ -141,23 +128,23 @@ Some of normal userland programs, such as
.Xr telnet 1
or
.Xr ftp 1 ,
are able to use the notation.
are able to use this notation.
With special programs
like
.Xr ping6 8 ,
you can specify outgoing interface by extra command line option
you can specify the outgoing interface by an extra command line option
to disambiguate scoped addresses.
.Pp
Scoped addresses are handled specially in the kernel.
In the kernel structures like routing tables or interface structure,
scoped addresses will have its interface index embedded into the address.
In kernel structures like routing tables or interface structures,
a scoped address will have its interface index embedded into the address.
Therefore,
the address on some of the kernel structure is not the same as that on the wire.
The embedded index will become visible on
the address in some kernel structures is not the same as that on the wire.
The embedded index will become visible through a
.Dv PF_ROUTE
socket, kernel memory accesses via
.Xr kvm 3
and some other occasions.
and on some other occasions.
HOWEVER, users should never use the embedded form.
For details please consult
.Pa IMPLEMENTATION
@ -431,20 +418,20 @@ which initiates dynamic adaptation (default 128).
The behavior of
.Dv AF_INET6
TCP/UDP socket is documented in RFC2553.
Basically, it says as follows:
Basically, it says this:
.Bl -bullet -compact
.It
Specific bind on
A specific bind on an
.Dv AF_INET6
socket
.Po
.Xr bind 2
with address specified
with an address specified
.Pc
should accept IPv6 traffic to that address only.
.It
If you perform wildcard bind
on
If you perform a wildcard bind
on an
.Dv AF_INET6
socket
.Po
@ -458,33 +445,33 @@ socket on that TCP/UDP port, IPv6 traffic as well as IPv4 traffic
should be routed to that
.Dv AF_INET6
socket.
IPv4 traffic should be seen as if it came from IPv6 address like
IPv4 traffic should be seen as if it came from an IPv6 address like
.Li ::ffff:10.1.1.1 .
This is called IPv4 mapped address.
This is called an IPv4 mapped address.
.It
If there are both wildcard bind
If there are both a wildcard bind
.Dv AF_INET
socket and wildcard bind
socket and a wildcard bind
.Dv AF_INET6
socket on one TCP/UDP port, they should behave separately.
IPv4 traffic should be routed to
IPv4 traffic should be routed to the
.Dv AF_INET
socket and IPv6 should be routed to
socket and IPv6 should be routed to the
.Dv AF_INET6
socket.
.El
.Pp
However, RFC2553 does not define the constraint between the order of
However, RFC2553 does not define the ordering constraint between calls to
.Xr bind 2 ,
nor how IPv4 TCP/UDP port number and IPv6 TCP/UDP port number
relate each other
nor how IPv4 TCP/UDP port numbers and IPv6 TCP/UDP port numbers
relate to each other
.Po
should they be integrated or separated
.Pc .
Implemented behavior is very different across kernel to kernel.
Implemented behavior is very different from kernel to kernel.
Therefore, it is unwise to rely too much upon the behavior of
.Dv AF_INET6
wildcard bind socket.
wildcard bind sockets.
It is recommended to listen to two sockets, one for
.Dv AF_INET
and another for
@ -497,7 +484,7 @@ and are able to bypass access control,
if the target node routes IPv4 traffic to
.Dv AF_INET6
socket.
Users are advised to take caution handling connections
Users are advised to take care handling connections
from IPv4 mapped address to
.Dv AF_INET6
sockets.
@ -506,7 +493,7 @@ sockets.
.\"KAME/NetBSD and KAME/OpenBSD
.\"does not route IPv4 traffic to
.\".Dv AF_INET6
.\"socket.
.\"sockets.
.\"Listen to two sockets if you want to accept both IPv4 and IPv6 traffic.
.\"On KAME/NetBSD, IPv4 traffic may be routed with certain
.\"per-socket/per-node configuration, however, it is not recommended.
@ -536,8 +523,8 @@ sockets.
.Sh HISTORY
The
.Nm
protocol interface are defined in RFC2553 and RFC2292.
The implementation described herein appeared in WIDE/KAME project.
protocol interfaces are defined in RFC2553 and RFC2292.
The implementation described herein appeared in the WIDE/KAME project.
.Sh BUGS
The IPv6 support is subject to change as the Internet protocols develop.
Users should not depend on details of the current implementation,

View file

@ -1,6 +1,8 @@
.\" $KAME: ip6.4,v 1.14 2001/02/26 09:31:39 itojun Exp $
.\"
.\" Copyright (C) 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:
@ -12,7 +14,7 @@
.\" 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
@ -56,7 +58,6 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" KAME $Id: ip6.4,v 1.7 2000/01/06 06:00:30 itojun Exp $
.\" $FreeBSD$
.\"
.Dd March 13, 2000
@ -241,14 +242,14 @@ int range = IPV6_PORTRANGE_LOW; /* see <netinet/in.h> */
setsockopt(s, IPPROTO_IPV6, IPV6_PORTRANGE, &range, sizeof(range));
.Ed
.Pp
.Dv IPV6_BINDV6ONLY
.Dv IPV6_V6ONLY
controls behavior of
.Dv AF_INET6
wildcard listening socket.
The following example sets the option to 1:
.Bd -literal -offset indent
int on = 1;
setsockopt(s, IPPROTO_IPV6, IPV6_BINDV6ONLY, &on, sizeof(on));
setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on));
.Ed
.Pp
If set to 1,
@ -258,21 +259,20 @@ If set to 0, it will accept IPv4 traffic as well,
as if it was from IPv4 mapped address like
.Li ::ffff:10.1.1.1 .
.\" RFC2553 defines the behavior when the variable is set to 0.
Note that if you set this to 0,
you need to care IPv4 access control also on the AF_INET6 socket.
Note that if you set it this to 0,
IPv4 access control gets much more complicated.
For example, even if you have no listening
.Dv AF_INET
listening socket on port
.Li X ,
you will be accepting IPv4 traffic by
you will end up accepting IPv4 traffic by
.Dv AF_INET6
listening socket on the same port.
.\"(net.inet6.ip6.bindv6only is not implemented yet.)
.\"The default value for this flag is copied at socket instantiation time,
.\"from
.\".Li net.inet6.ip6.bindv6only
.\".Xr sysctl 3
.\"variable.
The default value for this flag is copied at socket instantiation time,
from
.Li net.inet6.ip6.v6only
.Xr sysctl 3
variable.
The option affects
.Tn TCP
and
@ -344,7 +344,7 @@ and
.Dv IPV6_DSTOPTS .
Similarly,
.Xr inet6_rthdr_space 3
and friends will help you parse ancillary data items for
and friends will help you parse ancillary data items for
.Dv IPV6_RTHDR .
.Pp
.Dv IPV6_HOPOPTS
@ -686,12 +686,14 @@ The ancillary data items were improperly formed, or option name was unknown.
.Sh STANDARDS
Most of the socket options are defined in
RFC2292 and/or RFC2553.
.Dv IPV6_PORTRANGE ,
.Dv IPV6_BINDV6ONLY
.Pp
.Dv IPV6_V6ONLY
socket option is defined in draft-ietf-ipngwg-rfc2553bis-03.
.Dv IPV6_PORTRANGE
socket option
and
conflict resolution rule
are not defined in the RFCs and should be considered implementation dependent.
However, KAME/NetBSD also supports them.
.\"
.Sh HISTORY
The implementation is based on KAME stack

View file

@ -1,5 +1,5 @@
.\" $FreeBSD$
.\" $KAME: ipsec.4,v 1.13 2000/06/15 04:08:54 itojun Exp $
.\" $KAME: ipsec.4,v 1.15 2001/04/05 01:00:45 itojun Exp $
.\"
.\" Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
.\" All rights reserved.
@ -213,7 +213,7 @@ The variable configures the kernel behavior on IPv4 IPsec tunnel encapsulation.
If set to 0, DF bit on the outer IPv4 header will be cleared.
1 means that the outer DF bit is set regardless from the inner DF bit.
2 means that the DF bit is copied from the inner header to the outer.
The variable is supplied to conform to RFC2403 chapter 6.1.
The variable is supplied to conform to RFC2401 chapter 6.1.
.It Li ipsec.ecn
If set to non-zero, IPv4 IPsec tunnel encapsulation/decapsulation behavior will
be friendly to ECN

View file

@ -148,6 +148,11 @@ You also can check out the IPv6 and IPsec chapters in the
handbook.
Also check latest status of project at web page:
.Pa http://www.kame.net/ .
.Po
Hope you can see a
.Dq Dancing Turtle
.Li :-)
.Pc
.\"
.Ss APIs introduced or modified
.Xr if_indextoname 3 ,

View file

@ -1,5 +1,5 @@
.\" $FreeBSD$
.\" $KAME: stf.4,v 1.24 2000/06/07 23:35:18 itojun Exp $
.\" $KAME: stf.4,v 1.35 2001/05/02 06:24:49 itojun Exp $
.\"
.\" Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
.\" All rights reserved.
@ -28,7 +28,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.Dd March 6, 2000
.Dd April 27, 2001
.Dt STF 4
.Os
.Sh NAME
@ -45,7 +45,7 @@ interface supports
.Dq 6to4
IPv6 in IPv4 encapsulation.
It can tunnel IPv6 traffic over IPv4, as specified in
.Li draft-ietf-ngtrans-6to4-06.txt .
.Li RFC3056 .
.Pp
For ordinary nodes in 6to4 site, you do not need
.Nm
@ -142,6 +142,9 @@ all of the directly connected subnets.
.It
Packets that does not pass ingress filtering.
Outer IPv4 source address must meet the IPv4 topology on the routing table.
Ingress filter can be turned off by
.Dv IFF_LINK2
bit.
.It
The same set of rules are appplied against the IPv4 address embedded into
inner IPv6 address, if the IPv6 address matches 6to4 prefix.
@ -152,6 +155,16 @@ incoming IPv4 packet with IP protocol number 41, as necessary.
It is also recommended to filter/audit encapsulated IPv6 packets as well.
You may also want to run normal ingress filter against inner IPv6 address
to avoid spoofing.
.Pp
By setting the
.Dv IFF_LINK0
flag on the
.Nm
interface, it is possible to disable the input path,
making the direct attacks from the outside impossible.
Note, however, there are other security risks exist.
If you wish to use the configuration,
you must not advertise your 6to4 address to others.
.\"
.Sh EXAMPLES
Note that
@ -175,28 +188,65 @@ It emits 6to4 packet only for IPv6 destination 2002:0901::/32
# ifconfig stf0 inet6 2002:0901:0203:0000:a00:5aff:fe38:6f86 \\
prefixlen 32 alias
.Ed
.Pp
The following configuration uses the
.Nm
interface as an output-only device.
You need to have alternative IPv6 connectivity
.Pq other than 6to4
to use this configuration.
For outbound traffic, you can reach other 6to4 networks efficiently via
.Nm stf .
For inbound traffic, you will not receive any 6to4-tunneled packets
.Pq less security drawbacks .
Be careful not to advertise your 6to4 prefix to others
.Pq Li 2002:8504:0506::/48 ,
and not to use your 6to4 prefix as a source.
.Bd -literal
# ifconfig ne0 inet 133.4.5.6 netmask 0xffffff00
# ifconfig stf0 inet6 2002:8504:0506:0000:a00:5aff:fe38:6f86 \\
prefixlen 16 alias deprecated link0
# route add -inet6 2002:: -prefixlen 16 ::1
# route change -inet6 2002:: -prefixlen 16 ::1 -ifp stf0
.Ed
.\"
.Sh SEE ALSO
.Xr gif 4 ,
.Xr inet 4 ,
.Xr inet6 4
.Pp
.Pa http://www.6bone.net/6bone_6to4.html
.Rs
.%A Brian Carpenter
.%A Keith Moore
.%T "Connection of IPv6 Domains via IPv4 Clouds without Explicit Tunnels"
.%D June 2000
.%N draft-ietf-ngtrans-6to4-06.txt
.%O work in progress
.%T "Connection of IPv6 Domains via IPv4 Clouds"
.%D February 2001
.%R RFC
.%N 3056
.Re
.Rs
.%A Jun-ichiro itojun Hagino
.%T "Possible abuse against IPv6 transition technologies"
.%D March 2000
.%N draft-itojun-ipv6-transition-abuse-00.txt
.%O work in progress, http://playground.iijlab.net/i-d/draft-itojun-ipv6-transition-abuse-00.txt
.%D July 2000
.%N draft-itojun-ipv6-transition-abuse-01.txt
.%O work in progress
.Re
.\"
.Sh HISTORY
The
.Nm
device first appeared in WIDE/KAME IPv6 stack.
.\"
.Sh BUGS
No more than one
.Nm
interface is allowed for a node,
and no more than one IPv6 interface address is allowed for an
.Nm
interface.
It is to avoid source address selection conflicts
between IPv6 layer and IPv4 layer,
and to cope with ingress filtering rule on the other side.
This is a feature to make
.Nm
work right for all occasions.

View file

@ -163,19 +163,15 @@ contrib/ipfilter/netinet/ip_nat.c optional ipfilter inet
contrib/ipfilter/netinet/ip_proxy.c optional ipfilter inet
contrib/ipfilter/netinet/ip_state.c optional ipfilter inet
contrib/ipfilter/netinet/mlfk_ipl.c optional ipfilter inet
crypto/blowfish/bf_cbc.c optional ipsec ipsec_esp
crypto/blowfish/bf_cbc_m.c optional ipsec ipsec_esp
crypto/blowfish/bf_enc.c optional ipsec ipsec_esp
crypto/blowfish/bf_skey.c optional ipsec ipsec_esp
crypto/cast128/cast128.c optional ipsec ipsec_esp
crypto/cast128/cast128_cbc.c optional ipsec ipsec_esp
crypto/des/des_3cbc.c optional ipsec ipsec_esp
crypto/des/des_cbc.c optional ipsec ipsec_esp
crypto/des/des_ecb.c optional ipsec ipsec_esp
crypto/des/des_setkey.c optional ipsec ipsec_esp
crypto/rc5/rc5.c optional ipsec ipsec_esp
crypto/rc5/rc5_cbc.c optional ipsec ipsec_esp
crypto/rijndael/rijndael-alg-fst.c optional ipsec ipsec_esp
crypto/rijndael/rijndael-api-fst.c optional ipsec ipsec_esp
crypto/sha1.c optional ipsec
crypto/sha2/sha2.c optional ipsec
ddb/db_access.c optional ddb
ddb/db_break.c optional ddb
ddb/db_command.c optional ddb
@ -1083,6 +1079,7 @@ netinet6/dest6.c optional inet6
netinet6/esp_core.c optional ipsec ipsec_esp
netinet6/esp_input.c optional ipsec ipsec_esp
netinet6/esp_output.c optional ipsec ipsec_esp
netinet6/esp_rijndael.c optional ipsec ipsec_esp
netinet6/frag6.c optional inet6
netinet6/icmp6.c optional inet6
netinet6/in6.c optional inet6
@ -1124,8 +1121,8 @@ netipx/ipx_usrreq.c optional ipx
netipx/spx_debug.c optional ipx
netipx/spx_usrreq.c optional ipx
netkey/key.c optional ipsec
netkey/keydb.c optional ipsec
netkey/key_debug.c optional ipsec
netkey/keydb.c optional ipsec
netkey/keysock.c optional ipsec
netnatm/natm.c optional natm
netnatm/natm_pcb.c optional natm

View file

@ -1,151 +0,0 @@
/* $FreeBSD$ */
/* $KAME: bf_cbc.c,v 1.3 2000/03/27 04:36:25 sumikawa Exp $ */
/* crypto/bf/bf_cbc.c */
/* Copyright (C) 1995-1997 Eric Young (eay@mincom.oz.au)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@mincom.oz.au).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@mincom.oz.au).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* 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 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 cryptographic software written by
* Eric Young (eay@mincom.oz.au)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@mincom.oz.au)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 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.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <crypto/blowfish/blowfish.h>
#include <crypto/blowfish/bf_locl.h>
void BF_cbc_encrypt(in, out, length, ks, iv, encrypt)
unsigned char *in;
unsigned char *out;
long length;
BF_KEY *ks;
unsigned char *iv;
int encrypt;
{
register BF_LONG tin0,tin1;
register BF_LONG tout0,tout1,xor0,xor1;
register long l=length;
BF_LONG tin[2];
if (encrypt)
{
n2l(iv,tout0);
n2l(iv,tout1);
iv-=8;
for (l-=8; l>=0; l-=8)
{
n2l(in,tin0);
n2l(in,tin1);
tin0^=tout0;
tin1^=tout1;
tin[0]=tin0;
tin[1]=tin1;
BF_encrypt(tin,ks,BF_ENCRYPT);
tout0=tin[0];
tout1=tin[1];
l2n(tout0,out);
l2n(tout1,out);
}
if (l != -8)
{
n2ln(in,tin0,tin1,l+8);
tin0^=tout0;
tin1^=tout1;
tin[0]=tin0;
tin[1]=tin1;
BF_encrypt(tin,ks,BF_ENCRYPT);
tout0=tin[0];
tout1=tin[1];
l2n(tout0,out);
l2n(tout1,out);
}
l2n(tout0,iv);
l2n(tout1,iv);
}
else
{
n2l(iv,xor0);
n2l(iv,xor1);
iv-=8;
for (l-=8; l>=0; l-=8)
{
n2l(in,tin0);
n2l(in,tin1);
tin[0]=tin0;
tin[1]=tin1;
BF_encrypt(tin,ks,BF_DECRYPT);
tout0=tin[0]^xor0;
tout1=tin[1]^xor1;
l2n(tout0,out);
l2n(tout1,out);
xor0=tin0;
xor1=tin1;
}
if (l != -8)
{
n2l(in,tin0);
n2l(in,tin1);
tin[0]=tin0;
tin[1]=tin1;
BF_encrypt(tin,ks,BF_DECRYPT);
tout0=tin[0]^xor0;
tout1=tin[1]^xor1;
l2nn(tout0,tout1,out,l+8);
xor0=tin0;
xor1=tin1;
}
l2n(xor0,iv);
l2n(xor1,iv);
}
tin0=tin1=tout0=tout1=xor0=xor1=0;
tin[0]=tin[1]=0;
}

View file

@ -1,343 +0,0 @@
/* $FreeBSD$ */
/* $KAME: bf_cbc_m.c,v 1.4 2000/06/14 10:41:16 itojun Exp $ */
/*
* heavily modified to accept mbuf, by Jun-ichiro itojun Itoh
* <itojun@itojun.org>, 1997.
*/
/* crypto/bf/bf_cbc.c */
/* Copyright (C) 1995-1997 Eric Young (eay@mincom.oz.au)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@mincom.oz.au).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@mincom.oz.au).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* 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 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 cryptographic software written by
* Eric Young (eay@mincom.oz.au)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@mincom.oz.au)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 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.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <sys/param.h>
#include <sys/mbuf.h>
#include <sys/systm.h>
#include <crypto/blowfish/blowfish.h>
#include <crypto/blowfish/bf_locl.h>
#define panic(x) do { printf(x); return EINVAL; } while (0)
int BF_cbc_encrypt_m(m0, skip, length, key, iv, mode)
struct mbuf *m0;
int skip;
int length;
BF_KEY *key;
unsigned char *iv;
int mode;
{
u_int8_t inbuf[8], outbuf[8];
struct mbuf *m;
size_t off;
register BF_LONG tin0, tin1;
register BF_LONG tout0, tout1;
BF_LONG tin[2];
/* sanity checks */
if (m0->m_pkthdr.len < skip) {
printf("mbuf length < skip\n");
return EINVAL;
}
if (m0->m_pkthdr.len < length) {
printf("mbuf length < encrypt length\n");
return EINVAL;
}
if (m0->m_pkthdr.len < skip + length) {
printf("mbuf length < skip + encrypt length\n");
return EINVAL;
}
if (length % 8) {
printf("length is not multiple of 8\n");
return EINVAL;
}
m = m0;
off = 0;
/* skip over the header */
while (skip) {
if (!m)
panic("mbuf chain?\n");
if (m->m_len <= skip) {
skip -= m->m_len;
m = m->m_next;
off = 0;
} else {
off = skip;
skip = 0;
}
}
/* initialize */
tin0 = tin1 = tout0 = tout1 = 0;
tin[0] = tin[1] = 0;
if (mode == BF_ENCRYPT) {
u_int8_t *in, *out;
n2l(iv, tout0);
n2l(iv, tout1);
while (0 < length) {
if (!m)
panic("mbuf chain?\n");
/*
* copy the source into input buffer.
* don't update off or m, since we need to use them * later.
*/
if (off + 8 <= m->m_len)
bcopy(mtod(m, u_int8_t *) + off, &inbuf[0], 8);
else {
struct mbuf *n;
size_t noff;
u_int8_t *p;
u_int8_t *in;
n = m;
noff = off;
p = mtod(n, u_int8_t *) + noff;
in = &inbuf[0];
while (in - &inbuf[0] < 8) {
if (!p)
panic("mbuf chain?\n");
*in++ = *p++;
noff++;
if (noff < n->m_len)
continue;
do {
n = n->m_next;
} while (n && ! n->m_len);
noff = 0;
if (n)
p = mtod(n, u_int8_t *) + noff;
else
p = NULL;
}
}
in = &inbuf[0];
out = &outbuf[0];
n2l(in, tin0);
n2l(in, tin1);
tin0 ^= tout0; tin[0] = tin0;
tin1 ^= tout1; tin[1] = tin1;
BF_encrypt(tin, key, BF_ENCRYPT);
tout0 = tin[0]; l2n(tout0, out);
tout1 = tin[1]; l2n(tout1, out);
/*
* copy the output buffer into the result.
* need to update off and m.
*/
if (off + 8 < m->m_len) {
bcopy(&outbuf[0], mtod(m, u_int8_t *) + off, 8);
off += 8;
} else if (off + 8 == m->m_len) {
bcopy(&outbuf[0], mtod(m, u_int8_t *) + off, 8);
do {
m = m->m_next;
} while (m && ! m->m_len);
off = 0;
} else {
struct mbuf *n;
size_t noff;
u_int8_t *p;
u_int8_t *out;
n = m;
noff = off;
p = mtod(n, u_int8_t *) + noff;
out = &outbuf[0];
while (out - &outbuf[0] < 8) {
if (!p)
panic("mbuf chain?");
*p++ = *out++;
noff++;
if (noff < n->m_len)
continue;
do {
n = n->m_next;
} while (n && ! n->m_len);
noff = 0;
if (n)
p = mtod(n, u_int8_t *) + noff;
else
p = NULL;
}
m = n;
off = noff;
}
length -= 8;
}
} else if (mode == BF_DECRYPT) {
register BF_LONG xor0, xor1;
u_int8_t *in, *out;
xor0 = xor1 = 0;
n2l(iv, xor0);
n2l(iv, xor1);
while (0 < length) {
if (!m)
panic("mbuf chain?\n");
/*
* copy the source into input buffer.
* don't update off or m, since we need to use them * later.
*/
if (off + 8 <= m->m_len)
bcopy(mtod(m, u_int8_t *) + off, &inbuf[0], 8);
else {
struct mbuf *n;
size_t noff;
u_int8_t *p;
u_int8_t *in;
n = m;
noff = off;
p = mtod(n, u_int8_t *) + noff;
in = &inbuf[0];
while (in - &inbuf[0] < 8) {
if (!p)
panic("mbuf chain?\n");
*in++ = *p++;
noff++;
if (noff < n->m_len)
continue;
do {
n = n->m_next;
} while (n && ! n->m_len);
noff = 0;
if (n)
p = mtod(n, u_int8_t *) + noff;
else
p = NULL;
}
}
in = &inbuf[0];
out = &outbuf[0];
n2l(in, tin0); tin[0] = tin0;
n2l(in, tin1); tin[1] = tin1;
BF_encrypt(tin, key, BF_DECRYPT);
tout0 = tin[0] ^ xor0;
tout1 = tin[1] ^ xor1;
l2n(tout0, out);
l2n(tout1, out);
xor0 = tin0;
xor1 = tin1;
/*
* copy the output buffer into the result.
* need to update off and m.
*/
if (off + 8 < m->m_len) {
bcopy(&outbuf[0], mtod(m, u_int8_t *) + off, 8);
off += 8;
} else if (off + 8 == m->m_len) {
bcopy(&outbuf[0], mtod(m, u_int8_t *) + off, 8);
do {
m = m->m_next;
} while (m && ! m->m_len);
off = 0;
} else {
struct mbuf *n;
size_t noff;
u_int8_t *p;
u_int8_t *out;
n = m;
noff = off;
p = mtod(n, u_int8_t *) + noff;
out = &outbuf[0];
while (out - &outbuf[0] < 8) {
if (!p)
panic("mbuf chain?\n");
*p++ = *out++;
noff++;
if (noff < n->m_len)
continue;
do {
n = n->m_next;
} while (n && ! n->m_len);
noff = 0;
if (n)
p = mtod(n, u_int8_t *) + noff;
else
p = NULL;
}
m = n;
off = noff;
}
length -= 8;
}
}
return 0;
}

View file

@ -1,5 +1,5 @@
/* $FreeBSD$ */
/* $KAME: bf_enc.c,v 1.3 2000/03/27 04:36:26 sumikawa Exp $ */
/* $KAME: bf_enc.c,v 1.5 2000/09/18 21:21:19 itojun Exp $ */
/* crypto/bf/bf_enc.c */
/* Copyright (C) 1995-1997 Eric Young (eay@mincom.oz.au)
@ -59,6 +59,7 @@
* [including the GNU Public Licence.]
*/
#include <sys/types.h>
#include <crypto/blowfish/blowfish.h>
#include <crypto/blowfish/bf_locl.h>
@ -72,72 +73,71 @@ If you set BF_ROUNDS to some value other than 16 or 20, you will have
to modify the code.
#endif
void BF_encrypt(data,key,encrypt)
BF_LONG *data;
BF_KEY *key;
int encrypt;
{
register BF_LONG l,r,*p,*s;
/* XXX "data" is host endian */
void
BF_encrypt(data, key, encrypt)
BF_LONG *data;
BF_KEY *key;
int encrypt;
{
register BF_LONG l, r, *p, *s;
p=key->P;
s= &(key->S[0]);
l=data[0];
r=data[1];
p = key->P;
s= &key->S[0];
l = data[0];
r = data[1];
if (encrypt)
{
if (encrypt) {
l^=p[0];
BF_ENC(r,l,s,p[ 1]);
BF_ENC(l,r,s,p[ 2]);
BF_ENC(r,l,s,p[ 3]);
BF_ENC(l,r,s,p[ 4]);
BF_ENC(r,l,s,p[ 5]);
BF_ENC(l,r,s,p[ 6]);
BF_ENC(r,l,s,p[ 7]);
BF_ENC(l,r,s,p[ 8]);
BF_ENC(r,l,s,p[ 9]);
BF_ENC(l,r,s,p[10]);
BF_ENC(r,l,s,p[11]);
BF_ENC(l,r,s,p[12]);
BF_ENC(r,l,s,p[13]);
BF_ENC(l,r,s,p[14]);
BF_ENC(r,l,s,p[15]);
BF_ENC(l,r,s,p[16]);
BF_ENC(r, l, s, p[ 1]);
BF_ENC(l, r, s, p[ 2]);
BF_ENC(r, l, s, p[ 3]);
BF_ENC(l, r, s, p[ 4]);
BF_ENC(r, l, s, p[ 5]);
BF_ENC(l, r, s, p[ 6]);
BF_ENC(r, l, s, p[ 7]);
BF_ENC(l, r, s, p[ 8]);
BF_ENC(r, l, s, p[ 9]);
BF_ENC(l, r, s, p[10]);
BF_ENC(r, l, s, p[11]);
BF_ENC(l, r, s, p[12]);
BF_ENC(r, l, s, p[13]);
BF_ENC(l, r, s, p[14]);
BF_ENC(r, l, s, p[15]);
BF_ENC(l, r, s, p[16]);
#if BF_ROUNDS == 20
BF_ENC(r,l,s,p[17]);
BF_ENC(l,r,s,p[18]);
BF_ENC(r,l,s,p[19]);
BF_ENC(l,r,s,p[20]);
BF_ENC(r, l, s, p[17]);
BF_ENC(l, r, s, p[18]);
BF_ENC(r, l, s, p[19]);
BF_ENC(l, r, s, p[20]);
#endif
r^=p[BF_ROUNDS+1];
}
else
{
l^=p[BF_ROUNDS+1];
r ^= p[BF_ROUNDS + 1];
} else {
l ^= p[BF_ROUNDS + 1];
#if BF_ROUNDS == 20
BF_ENC(r,l,s,p[20]);
BF_ENC(l,r,s,p[19]);
BF_ENC(r,l,s,p[18]);
BF_ENC(l,r,s,p[17]);
BF_ENC(r, l, s, p[20]);
BF_ENC(l, r, s, p[19]);
BF_ENC(r, l, s, p[18]);
BF_ENC(l, r, s, p[17]);
#endif
BF_ENC(r,l,s,p[16]);
BF_ENC(l,r,s,p[15]);
BF_ENC(r,l,s,p[14]);
BF_ENC(l,r,s,p[13]);
BF_ENC(r,l,s,p[12]);
BF_ENC(l,r,s,p[11]);
BF_ENC(r,l,s,p[10]);
BF_ENC(l,r,s,p[ 9]);
BF_ENC(r,l,s,p[ 8]);
BF_ENC(l,r,s,p[ 7]);
BF_ENC(r,l,s,p[ 6]);
BF_ENC(l,r,s,p[ 5]);
BF_ENC(r,l,s,p[ 4]);
BF_ENC(l,r,s,p[ 3]);
BF_ENC(r,l,s,p[ 2]);
BF_ENC(l,r,s,p[ 1]);
r^=p[0];
}
data[1]=l&0xffffffff;
data[0]=r&0xffffffff;
BF_ENC(r, l, s, p[16]);
BF_ENC(l, r, s, p[15]);
BF_ENC(r, l, s, p[14]);
BF_ENC(l, r, s, p[13]);
BF_ENC(r, l, s, p[12]);
BF_ENC(l, r, s, p[11]);
BF_ENC(r, l, s, p[10]);
BF_ENC(l, r, s, p[ 9]);
BF_ENC(r, l, s, p[ 8]);
BF_ENC(l, r, s, p[ 7]);
BF_ENC(r, l, s, p[ 6]);
BF_ENC(l, r, s, p[ 5]);
BF_ENC(r, l, s, p[ 4]);
BF_ENC(l, r, s, p[ 3]);
BF_ENC(r, l, s, p[ 2]);
BF_ENC(l, r, s, p[ 1]);
r ^= p[0];
}
data[1] = l & 0xffffffff;
data[0] = r & 0xffffffff;
}

View file

@ -1,5 +1,5 @@
/* $FreeBSD$ */
/* $KAME: bf_locl.h,v 1.3 2000/03/27 04:36:26 sumikawa Exp $ */
/* $KAME: bf_locl.h,v 1.5 2000/08/31 06:03:48 itojun Exp $ */
/* crypto/bf/bf_local.h */
/* Copyright (C) 1995-1997 Eric Young (eay@mincom.oz.au)
@ -67,10 +67,10 @@
*/
#undef c2l
#define c2l(c,l) (l =((unsigned long)(*((c)++))) , \
l|=((unsigned long)(*((c)++)))<< 8L, \
l|=((unsigned long)(*((c)++)))<<16L, \
l|=((unsigned long)(*((c)++)))<<24L)
#define c2l(c,l) (l =((BF_LONG)(*((c)++))) , \
l|=((BF_LONG)(*((c)++)))<< 8L, \
l|=((BF_LONG)(*((c)++)))<<16L, \
l|=((BF_LONG)(*((c)++)))<<24L)
/* NOTE - c is not incremented as per c2l */
#undef c2ln
@ -78,14 +78,14 @@
c+=n; \
l1=l2=0; \
switch (n) { \
case 8: l2 =((unsigned long)(*(--(c))))<<24L; \
case 7: l2|=((unsigned long)(*(--(c))))<<16L; \
case 6: l2|=((unsigned long)(*(--(c))))<< 8L; \
case 5: l2|=((unsigned long)(*(--(c)))); \
case 4: l1 =((unsigned long)(*(--(c))))<<24L; \
case 3: l1|=((unsigned long)(*(--(c))))<<16L; \
case 2: l1|=((unsigned long)(*(--(c))))<< 8L; \
case 1: l1|=((unsigned long)(*(--(c)))); \
case 8: l2 =((BF_LONG)(*(--(c))))<<24L; \
case 7: l2|=((BF_LONG)(*(--(c))))<<16L; \
case 6: l2|=((BF_LONG)(*(--(c))))<< 8L; \
case 5: l2|=((BF_LONG)(*(--(c)))); \
case 4: l1 =((BF_LONG)(*(--(c))))<<24L; \
case 3: l1|=((BF_LONG)(*(--(c))))<<16L; \
case 2: l1|=((BF_LONG)(*(--(c))))<< 8L; \
case 1: l1|=((BF_LONG)(*(--(c)))); \
} \
}
@ -116,14 +116,14 @@
c+=n; \
l1=l2=0; \
switch (n) { \
case 8: l2 =((unsigned long)(*(--(c)))) ; \
case 7: l2|=((unsigned long)(*(--(c))))<< 8; \
case 6: l2|=((unsigned long)(*(--(c))))<<16; \
case 5: l2|=((unsigned long)(*(--(c))))<<24; \
case 4: l1 =((unsigned long)(*(--(c)))) ; \
case 3: l1|=((unsigned long)(*(--(c))))<< 8; \
case 2: l1|=((unsigned long)(*(--(c))))<<16; \
case 1: l1|=((unsigned long)(*(--(c))))<<24; \
case 8: l2 =((BF_LONG)(*(--(c)))) ; \
case 7: l2|=((BF_LONG)(*(--(c))))<< 8; \
case 6: l2|=((BF_LONG)(*(--(c))))<<16; \
case 5: l2|=((BF_LONG)(*(--(c))))<<24; \
case 4: l1 =((BF_LONG)(*(--(c)))) ; \
case 3: l1|=((BF_LONG)(*(--(c))))<< 8; \
case 2: l1|=((BF_LONG)(*(--(c))))<<16; \
case 1: l1|=((BF_LONG)(*(--(c))))<<24; \
} \
}
@ -143,10 +143,10 @@
}
#undef n2l
#define n2l(c,l) (l =((unsigned long)(*((c)++)))<<24L, \
l|=((unsigned long)(*((c)++)))<<16L, \
l|=((unsigned long)(*((c)++)))<< 8L, \
l|=((unsigned long)(*((c)++))))
#define n2l(c,l) (l =((BF_LONG)(*((c)++)))<<24L, \
l|=((BF_LONG)(*((c)++)))<<16L, \
l|=((BF_LONG)(*((c)++)))<< 8L, \
l|=((BF_LONG)(*((c)++))))
#undef l2n
#define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
@ -161,9 +161,17 @@
* BF_PTR for sparc and MIPS/SGI
* use nothing for Alpha and HP.
*/
#if !defined(BF_PTR) && !defined(BF_PTR2)
#undef BF_PTR
#undef BF_PTR
#undef BF_PTR2
#ifdef __NetBSD__
#ifdef __i386__
#define BF_PTR2
#else
#ifdef __mips__
#define BF_PTR
#endif
#endif
#endif /*NetBSD*/
#define BF_M 0x3fc
#define BF_0 22L

View file

@ -1,5 +1,5 @@
/* $FreeBSD$ */
/* $KAME: bf_skey.c,v 1.3 2000/03/27 04:36:27 sumikawa Exp $ */
/* $KAME: bf_skey.c,v 1.5 2000/11/06 13:58:08 itojun Exp $ */
/* crypto/bf/bf_skey.c */
/* Copyright (C) 1995-1997 Eric Young (eay@mincom.oz.au)
@ -66,58 +66,55 @@
#include <crypto/blowfish/bf_locl.h>
#include <crypto/blowfish/bf_pi.h>
void BF_set_key(key,len,data)
BF_KEY *key;
int len;
unsigned char *data;
{
void
BF_set_key(key, len, data)
BF_KEY *key;
int len;
unsigned char *data;
{
int i;
BF_LONG *p,ri,in[2];
unsigned char *d,*end;
BF_LONG *p, ri, in[2];
unsigned char *d, *end;
memcpy((char *)key, (char *)&bf_init, sizeof(BF_KEY));
p = key->P;
memcpy((char *)key,(char *)&bf_init,sizeof(BF_KEY));
p=key->P;
if (len > ((BF_ROUNDS + 2) * 4))
len = (BF_ROUNDS + 2) * 4;
if (len > ((BF_ROUNDS+2)*4)) len=(BF_ROUNDS+2)*4;
d=data;
d = data;
end= &(data[len]);
for (i=0; i<(BF_ROUNDS+2); i++)
{
ri= *(d++);
if (d >= end) d=data;
for (i = 0; i < BF_ROUNDS + 2; i++) {
ri = *(d++);
if (d >= end) d = data;
ri<<=8;
ri|= *(d++);
if (d >= end) d=data;
ri <<= 8;
ri |= *(d++);
if (d >= end) d = data;
ri<<=8;
ri|= *(d++);
if (d >= end) d=data;
ri <<= 8;
ri |= *(d++);
if (d >= end) d = data;
ri<<=8;
ri|= *(d++);
if (d >= end) d=data;
ri <<= 8;
ri |= *(d++);
if (d >= end) d = data;
p[i]^=ri;
}
in[0]=0L;
in[1]=0L;
for (i=0; i<(BF_ROUNDS+2); i+=2)
{
BF_encrypt(in,key,BF_ENCRYPT);
p[i ]=in[0];
p[i+1]=in[1];
}
p=key->S;
for (i=0; i<4*256; i+=2)
{
BF_encrypt(in,key,BF_ENCRYPT);
p[i ]=in[0];
p[i+1]=in[1];
}
p[i] ^= ri;
}
in[0] = 0L;
in[1] = 0L;
for (i = 0; i < BF_ROUNDS + 2; i += 2) {
BF_encrypt(in, key, BF_ENCRYPT);
p[i ] = in[0];
p[i+1] = in[1];
}
p = key->S;
for (i = 0; i < 4 * 256; i += 2) {
BF_encrypt(in, key, BF_ENCRYPT);
p[i ] = in[0];
p[i+1] = in[1];
}
}

View file

@ -1,5 +1,5 @@
/* $FreeBSD$ */
/* $KAME: blowfish.h,v 1.4 2000/06/14 10:41:16 itojun Exp $ */
/* $KAME: blowfish.h,v 1.10 2000/09/18 21:21:20 itojun Exp $ */
/* crypto/bf/blowfish.h */
/* Copyright (C) 1995-1997 Eric Young (eay@mincom.oz.au)
@ -69,54 +69,19 @@ extern "C" {
#define BF_ENCRYPT 1
#define BF_DECRYPT 0
/* If you make this 'unsigned int' the pointer variants will work on
* the Alpha, otherwise they will not. Strangly using the '8 byte'
* BF_LONG and the default 'non-pointer' inner loop is the best configuration
* for the Alpha */
#define BF_LONG unsigned long
/* must be 32bit quantity */
#define BF_LONG u_int32_t
#define BF_ROUNDS 16
#define BF_BLOCK 8
typedef struct bf_key_st
{
typedef struct bf_key_st {
BF_LONG P[BF_ROUNDS+2];
BF_LONG S[4*256];
} BF_KEY;
#ifndef NOPROTO
void BF_set_key(BF_KEY *key, int len, unsigned char *data);
void BF_ecb_encrypt(unsigned char *in,unsigned char *out,BF_KEY *key,
int encrypt);
void BF_encrypt(BF_LONG *data,BF_KEY *key,int encrypt);
void BF_cbc_encrypt(unsigned char *in, unsigned char *out, long length,
BF_KEY *ks, unsigned char *iv, int encrypt);
void BF_cfb64_encrypt(unsigned char *in, unsigned char *out, long length,
BF_KEY *schedule, unsigned char *ivec, int *num, int encrypt);
void BF_ofb64_encrypt(unsigned char *in, unsigned char *out, long length,
BF_KEY *schedule, unsigned char *ivec, int *num);
char *BF_options(void);
/* added by itojun */
struct mbuf;
int BF_cbc_encrypt_m(struct mbuf *, int, int, BF_KEY *, unsigned char *, int);
#else
void BF_set_key();
void BF_ecb_encrypt();
void BF_encrypt();
void BF_cbc_encrypt();
void BF_cfb64_encrypt();
void BF_ofb64_encrypt();
char *BF_options();
/* added by itojun */
void BF_cbc_encrypt_m();
#endif
} BF_KEY;
void BF_set_key __P((BF_KEY *, int, unsigned char *));
void BF_encrypt __P((BF_LONG *, BF_KEY *, int));
#ifdef __cplusplus
}
#endif

View file

@ -1,5 +1,5 @@
/* $FreeBSD$ */
/* $KAME: cast128.c,v 1.3 2000/03/27 04:36:29 sumikawa Exp $ */
/* $KAME: cast128.c,v 1.4 2000/11/06 13:58:08 itojun Exp $ */
/*
* heavily modified by Tomomi Suzuki <suzuki@grelot.elec.ryukoku.ac.jp>

View file

@ -1,5 +1,5 @@
/* $FreeBSD$ */
/* $KAME: cast128.h,v 1.4 2000/06/14 10:41:16 itojun Exp $ */
/* $KAME: cast128.h,v 1.6 2000/09/18 20:59:20 itojun Exp $ */
/*
* heavily modified by Tomomi Suzuki <suzuki@grelot.elec.ryukoku.ac.jp>
@ -40,7 +40,6 @@
#define RFC2144_CAST_128_H
#include <sys/param.h>
#include <sys/mbuf.h>
#define CAST128_ENCRYPT 1
@ -56,8 +55,5 @@ extern void cast128_encrypt_round12 __P((u_int8_t *, const u_int8_t *,
u_int32_t *));
extern void cast128_decrypt_round12 __P((u_int8_t *, const u_int8_t *,
u_int32_t *));
extern int cast128_cbc_process __P((struct mbuf *, size_t, size_t,
u_int32_t *, u_int8_t *, size_t, int));
#endif

View file

@ -1,222 +0,0 @@
/* $FreeBSD$ */
/* $KAME: cast128_cbc.c,v 1.4 2000/06/14 10:41:17 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* based on sys/crypto/des/des_cbc.c, rewrote by Tomomi Suzuki
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <crypto/cast128/cast128.h>
#define panic(x) do { printf(x); return EINVAL; } while (0)
int
cast128_cbc_process(m0, skip, length, subkey, iv, keylen, mode)
struct mbuf *m0;
size_t skip;
size_t length;
u_int32_t *subkey;
u_int8_t *iv;
size_t keylen;
int mode;
{
struct mbuf *m;
u_int8_t inbuf[8], outbuf[8];
size_t off;
/* sanity check */
if (m0->m_pkthdr.len < skip) {
printf("cast128_cbc_process: mbuf length < skip\n");
return EINVAL;
}
if (m0->m_pkthdr.len < length) {
printf("cast128_cbc_process: mbuf length < encrypt length\n");
return EINVAL;
}
if (m0->m_pkthdr.len < skip + length) {
printf("cast128_cbc_process: "
"mbuf length < skip + encrypt length\n");
return EINVAL;
}
if (length % 8) {
printf("cast128_cbc_process: length is not multiple of 8\n");
return EINVAL;
}
m = m0;
off = 0;
/* skip over the header */
while (skip) {
if (!m)
panic("cast128_cbc_process: mbuf chain?\n");
if (m->m_len <= skip) {
skip -= m->m_len;
m = m->m_next;
off = 0;
} else {
off = skip;
skip = 0;
}
}
/* copy iv into outbuf for XOR (encrypt) */
bcopy(iv, outbuf, 8);
/*
* encrypt/decrypt packet
*/
while (length > 0) {
int i;
if (!m)
panic("cast128_cbc_process: mbuf chain?\n");
/*
* copy the source into input buffer.
* don't update off or m, since we need to use them
* later.
*/
if (off + 8 <= m->m_len)
bcopy(mtod(m, u_int8_t *)+off, inbuf, 8);
else {
struct mbuf *n;
size_t noff;
u_int8_t *p, *in;
n = m;
noff = off;
p = mtod(n, u_int8_t *) + noff;
in = inbuf;
while (in - inbuf < 8) {
if (!p) {
panic("cast128_cbc_process: "
"mbuf chain?\n");
}
*in++ = *p++;
noff++;
if (noff < n->m_len)
continue;
do {
n = n->m_next;
} while (n && !n->m_len);
noff = 0;
if (n)
p = mtod(n, u_int8_t *);
else
p = NULL;
}
}
/* encrypt/decrypt */
switch (mode) {
case CAST128_ENCRYPT:
/* XOR */
for (i = 0; i < 8; i++)
inbuf[i] ^= outbuf[i];
/* encrypt */
if (keylen <= 80/8)
cast128_encrypt_round12(outbuf, inbuf, subkey);
else
cast128_encrypt_round16(outbuf, inbuf, subkey);
break;
case CAST128_DECRYPT:
/* decrypt */
if (keylen <= 80/8)
cast128_decrypt_round12(outbuf, inbuf, subkey);
else
cast128_decrypt_round16(outbuf, inbuf, subkey);
/* XOR */
for (i = 0; i < 8; i++)
outbuf[i] ^= iv[i];
/* copy inbuf into iv for next XOR */
bcopy(inbuf, iv, 8);
break;
}
/*
* copy the output buffer into the result.
* need to update off and m.
*/
if (off + 8 < m->m_len) {
bcopy(outbuf, mtod(m, u_int8_t *) + off, 8);
off += 8;
} else if (off + 8 == m->m_len) {
bcopy(outbuf, mtod(m, u_int8_t *) + off, 8);
do {
m = m->m_next;
} while (m && !m->m_len);
off = 0;
} else {
struct mbuf *n;
size_t noff;
u_int8_t *p, *out;
n = m;
noff = off;
p = mtod(n, u_int8_t *) + noff;
out = outbuf;
while (out - outbuf < 8) {
if (!p) {
panic("cast128_cbc_process: "
"mbuf chain?\n");
}
*p++ = *out++;
noff++;
if (noff < n->m_len)
continue;
do {
n = n->m_next;
} while (n && !n->m_len);
noff = 0;
if (n)
p = mtod(n, u_int8_t *);
else
p = NULL;
}
m = n;
off = noff;
}
length -= 8;
}
return 0;
}

View file

@ -1,5 +1,5 @@
/* $FreeBSD$ */
/* $KAME: des.h,v 1.4 2000/06/14 10:41:17 itojun Exp $ */
/* $KAME: des.h,v 1.7 2000/09/18 20:59:21 itojun Exp $ */
/* lib/des/des.h */
/* Copyright (C) 1995-1996 Eric Young (eay@mincom.oz.au)
@ -55,11 +55,8 @@
extern "C" {
#endif
/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a
* %20 speed up (longs are 8 bytes, int's are 4). */
#ifndef DES_LONG
#define DES_LONG unsigned long
#endif
/* must be 32bit quantity */
#define DES_LONG u_int32_t
typedef unsigned char des_cblock[8];
typedef struct des_ks_struct
@ -83,196 +80,18 @@ typedef struct des_ks_struct
#define DES_CBC_MODE 0
#define DES_PCBC_MODE 1
#define des_ecb2_encrypt(i,o,k1,k2,e) \
des_ecb3_encrypt((i),(o),(k1),(k2),(k1),(e))
#define des_ede2_cbc_encrypt(i,o,l,k1,k2,iv,e) \
des_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(e))
#define des_ede2_cfb64_encrypt(i,o,l,k1,k2,iv,n,e) \
des_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n),(e))
#define des_ede2_ofb64_encrypt(i,o,l,k1,k2,iv,n) \
des_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n))
#define C_Block des_cblock
#define Key_schedule des_key_schedule
#ifdef KERBEROS
#define ENCRYPT DES_ENCRYPT
#define DECRYPT DES_DECRYPT
#endif
#define KEY_SZ DES_KEY_SZ
#define string_to_key des_string_to_key
#define read_pw_string des_read_pw_string
#define random_key des_random_key
#define pcbc_encrypt des_pcbc_encrypt
#define set_key des_set_key
#define key_sched des_key_sched
#define ecb_encrypt des_ecb_encrypt
#define cbc_encrypt des_cbc_encrypt
#define ncbc_encrypt des_ncbc_encrypt
#define xcbc_encrypt des_xcbc_encrypt
#define cbc_cksum des_cbc_cksum
#define quad_cksum des_quad_cksum
/* For compatibility with the MIT lib - eay 20/05/92 */
typedef des_key_schedule bit_64;
#define des_fixup_key_parity des_set_odd_parity
#define des_check_key_parity check_parity
extern int des_check_key; /* defaults to false */
extern int des_rw_mode; /* defaults to DES_PCBC_MODE */
/* The next line is used to disable full ANSI prototypes, if your
* compiler has problems with the prototypes, make sure this line always
* evaluates to true :-) */
#if defined(MSDOS) || defined(__STDC__)
#undef NOPROTO
#endif
#ifndef NOPROTO
char *des_options(void);
void des_ecb3_encrypt(des_cblock *input,des_cblock *output,
des_key_schedule ks1,des_key_schedule ks2,
des_key_schedule ks3, int enc);
DES_LONG des_cbc_cksum(des_cblock *input,des_cblock *output,
long length,des_key_schedule schedule,des_cblock *ivec);
/*
void des_cbc_encrypt(des_cblock *input,des_cblock *output,long length,
des_key_schedule schedule,des_cblock *ivec,int enc);
*/
int des_cbc_encrypt(struct mbuf *, size_t, size_t,
des_key_schedule schedule,des_cblock *ivec, int enc);
void des_ncbc_encrypt(des_cblock *input,des_cblock *output,long length,
des_key_schedule schedule,des_cblock *ivec,int enc);
void des_xcbc_encrypt(des_cblock *input,des_cblock *output,long length,
des_key_schedule schedule,des_cblock *ivec,
des_cblock *inw,des_cblock *outw,int enc);
void des_3cbc_encrypt(des_cblock *input,des_cblock *output,long length,
des_key_schedule sk1,des_key_schedule sk2,
des_cblock *ivec1,des_cblock *ivec2,int enc);
extern int des_3cbc_process(struct mbuf *, size_t, size_t,
des_key_schedule *schedule, des_cblock *ivec, int mode);
void des_cfb_encrypt(unsigned char *in,unsigned char *out,int numbits,
long length,des_key_schedule schedule,des_cblock *ivec,int enc);
void des_ecb_encrypt(des_cblock *input,des_cblock *output,
des_key_schedule ks,int enc);
void des_encrypt(DES_LONG *data,des_key_schedule ks, int enc);
void des_encrypt2(DES_LONG *data,des_key_schedule ks, int enc);
void des_ede3_cbc_encrypt(des_cblock *input, des_cblock *output,
long length, des_key_schedule ks1, des_key_schedule ks2,
des_key_schedule ks3, des_cblock *ivec, int enc);
void des_ede3_cfb64_encrypt(unsigned char *in, unsigned char *out,
long length, des_key_schedule ks1, des_key_schedule ks2,
des_key_schedule ks3, des_cblock *ivec, int *num, int encrypt);
void des_ede3_ofb64_encrypt(unsigned char *in, unsigned char *out,
long length, des_key_schedule ks1, des_key_schedule ks2,
des_key_schedule ks3, des_cblock *ivec, int *num);
char *des_options __P((void));
void des_ecb_encrypt __P((des_cblock *, des_cblock *,
des_key_schedule, int));
void des_encrypt __P((DES_LONG *, des_key_schedule, int));
void des_encrypt2 __P((DES_LONG *, des_key_schedule, int));
int des_enc_read(int fd,char *buf,int len,des_key_schedule sched,
des_cblock *iv);
int des_enc_write(int fd,char *buf,int len,des_key_schedule sched,
des_cblock *iv);
#ifdef PERL5
char *des_crypt(const char *buf,const char *salt);
#else
/* some stupid compilers complain because I have declared char instead
* of const char */
#if 1
char *crypt(const char *buf,const char *salt);
#else
char *crypt();
#endif
#endif
void des_ofb_encrypt(unsigned char *in,unsigned char *out,
int numbits,long length,des_key_schedule schedule,des_cblock *ivec);
void des_pcbc_encrypt(des_cblock *input,des_cblock *output,long length,
des_key_schedule schedule,des_cblock *ivec,int enc);
DES_LONG des_quad_cksum(des_cblock *input,des_cblock *output,
long length,int out_count,des_cblock *seed);
void des_random_seed(des_cblock key);
void des_random_key(des_cblock ret);
int des_read_password(des_cblock *key,char *prompt,int verify);
int des_read_2passwords(des_cblock *key1,des_cblock *key2,
char *prompt,int verify);
int des_read_pw_string(char *buf,int length,char *prompt,int verify);
void des_set_odd_parity(des_cblock *key);
int des_is_weak_key(des_cblock *key);
int des_set_key(des_cblock *key,des_key_schedule schedule);
int des_key_sched(des_cblock *key,des_key_schedule schedule);
void des_string_to_key(char *str,des_cblock *key);
void des_string_to_2keys(char *str,des_cblock *key1,des_cblock *key2);
void des_cfb64_encrypt(unsigned char *in, unsigned char *out, long length,
des_key_schedule schedule, des_cblock *ivec, int *num, int enc);
void des_ofb64_encrypt(unsigned char *in, unsigned char *out, long length,
des_key_schedule schedule, des_cblock *ivec, int *num);
/* Extra functions from Mark Murray <mark@grondar.za> */
/*
void des_cblock_print_file(des_cblock *cb, FILE *fp);
*/
/* The following functions are not in the normal unix build or the
* SSLeay build. When using the SSLeay build, use RAND_seed()
* and RAND_bytes() instead. */
int des_new_random_key(des_cblock *key);
void des_init_random_number_generator(des_cblock *key);
void des_set_random_generator_seed(des_cblock *key);
void des_set_sequence_number(des_cblock new_sequence_number);
void des_generate_random_block(des_cblock *block);
#else
char *des_options();
void des_ecb3_encrypt();
DES_LONG des_cbc_cksum();
void des_cbc_encrypt();
void des_ncbc_encrypt();
void des_xcbc_encrypt();
void des_3cbc_encrypt();
void des_cfb_encrypt();
void des_ede3_cfb64_encrypt();
void des_ede3_ofb64_encrypt();
void des_ecb_encrypt();
void des_encrypt();
void des_encrypt2();
void des_ede3_cbc_encrypt();
int des_enc_read();
int des_enc_write();
#ifdef PERL5
char *des_crypt();
#else
char *crypt();
#endif
void des_ofb_encrypt();
void des_pcbc_encrypt();
DES_LONG des_quad_cksum();
void des_random_seed();
void des_random_key();
int des_read_password();
int des_read_2passwords();
int des_read_pw_string();
void des_set_odd_parity();
int des_is_weak_key();
int des_set_key();
int des_key_sched();
void des_string_to_key();
void des_string_to_2keys();
void des_cfb64_encrypt();
void des_ofb64_encrypt();
/* Extra functions from Mark Murray <mark@grondar.za> */
void des_cblock_print_file();
/* The following functions are not in the normal unix build or the
* SSLeay build. When using the SSLeay build, use RAND_seed()
* and RAND_bytes() instead. */
#ifdef FreeBSD
int des_new_random_key();
void des_init_random_number_generator();
void des_set_random_generator_seed();
void des_set_sequence_number();
void des_generate_random_block();
#endif
#endif
void des_set_odd_parity __P((des_cblock *));
int des_is_weak_key __P((des_cblock *));
int des_set_key __P((des_cblock *, des_key_schedule));
int des_key_sched __P((des_cblock *, des_key_schedule));
#ifdef __cplusplus
}

View file

@ -1,250 +0,0 @@
/* $FreeBSD$ */
/* $KAME: des_3cbc.c,v 1.4 2000/06/14 10:41:17 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* based on sys/crypto/des/des_cbc.c, rewrote by Tomomi Suzuki
*/
#include <crypto/des/des_locl.h>
#define panic(x) do { printf(x); return EINVAL; } while (0)
int des_3cbc_process(m0, skip, length, schedule, ivec, mode)
struct mbuf *m0;
size_t skip;
size_t length;
des_key_schedule *schedule;
des_cblock (*ivec);
int mode;
{
u_int8_t inbuf[8], outbuf[8];
struct mbuf *m;
size_t off;
DES_LONG tin0, tin1;
DES_LONG tout0, tout1;
DES_LONG tin[2];
DES_LONG xor0 = 0, xor1 = 0;
u_int8_t *iv;
u_int8_t *in, *out;
/* sanity check */
if (m0->m_pkthdr.len < skip) {
printf("des_3cbc_process: mbuf length < skip\n");
return EINVAL;
}
if (m0->m_pkthdr.len < length) {
printf("des_3cbc_process: mbuf length < encrypt length\n");
return EINVAL;
}
if (m0->m_pkthdr.len < skip + length) {
printf("des_3cbc_process: mbuf length < "
"skip + encrypt length\n");
return EINVAL;
}
if (length % 8) {
printf("des_3cbc_process: length(%lu) is not multiple of 8\n",
(u_long)length);
return EINVAL;
}
m = m0;
off = 0;
/* skip over the header */
while (skip) {
if (!m)
panic("des_3cbc_process: mbuf chain?\n");
if (m->m_len <= skip) {
skip -= m->m_len;
m = m->m_next;
off = 0;
} else {
off = skip;
skip = 0;
}
}
/* initialize */
tin0 = tin1 = tout0 = tout1 = 0;
tin[0] = tin[1] = 0;
switch (mode) {
case DES_ENCRYPT:
iv = (u_int8_t *)ivec;
c2l(iv, tout0);
c2l(iv, tout1);
break;
case DES_DECRYPT:
xor0 = xor1 = 0;
iv = (u_int8_t *)ivec;
c2l(iv, xor0);
c2l(iv, xor1);
break;
}
/*
* encrypt/decrypt packet
*/
while (length > 0) {
if (!m)
panic("des_3cbc_process: mbuf chain?\n");
/*
* copy the source into input buffer.
* don't update off or m, since we need to use them
* later.
*/
if (off + 8 <= m->m_len)
bcopy(mtod(m, u_int8_t *) + off, &inbuf[0], 8);
else {
struct mbuf *n;
size_t noff;
u_int8_t *p;
u_int8_t *in;
n = m;
noff = off;
p = mtod(n, u_int8_t *) + noff;
in = &inbuf[0];
while (in - &inbuf[0] < 8) {
if (!p) {
panic("des_3cbc_process: "
"mbuf chain?\n");
}
*in++ = *p++;
noff++;
if (noff < n->m_len)
continue;
do {
n = n->m_next;
} while (n && !n->m_len);
noff = 0;
if (n)
p = mtod(n, u_int8_t *) + noff;
else
p = NULL;
}
}
/* encrypt/decrypt */
switch (mode) {
case DES_ENCRYPT:
in = &inbuf[0];
out = &outbuf[0];
c2l(in, tin0);
c2l(in, tin1);
/* XOR */
tin0 ^= tout0; tin[0] = tin0;
tin1 ^= tout1; tin[1] = tin1;
des_encrypt((DES_LONG *)tin, schedule[0], DES_ENCRYPT);
des_encrypt((DES_LONG *)tin, schedule[1], DES_DECRYPT);
des_encrypt((DES_LONG *)tin, schedule[2], DES_ENCRYPT);
tout0 = tin[0]; l2c(tout0, out);
tout1 = tin[1]; l2c(tout1, out);
break;
case DES_DECRYPT:
in = &inbuf[0];
out = &outbuf[0];
c2l(in, tin0); tin[0] = tin0;
c2l(in, tin1); tin[1] = tin1;
des_encrypt((DES_LONG *)tin, schedule[2], DES_DECRYPT);
des_encrypt((DES_LONG *)tin, schedule[1], DES_ENCRYPT);
des_encrypt((DES_LONG *)tin, schedule[0], DES_DECRYPT);
/* XOR */
tout0 = tin[0] ^ xor0;
tout1 = tin[1] ^ xor1;
l2c(tout0, out);
l2c(tout1, out);
/* for next iv */
xor0 = tin0;
xor1 = tin1;
break;
}
/*
* copy the output buffer int the result.
* need to update off and m.
*/
if (off + 8 < m->m_len) {
bcopy(&outbuf[0], mtod(m, u_int8_t *) + off, 8);
off += 8;
} else if (off + 8 == m->m_len) {
bcopy(&outbuf[0], mtod(m, u_int8_t *) + off, 8);
do {
m = m->m_next;
} while (m && !m->m_len);
off = 0;
} else {
struct mbuf *n;
size_t noff;
u_int8_t *p;
u_int8_t *out;
n = m;
noff = off;
p = mtod(n, u_int8_t *) + noff;
out = &outbuf[0];
while (out - &outbuf[0] < 8) {
if (!p) {
panic("des_3cbc_process: "
"mbuf chain?\n");
}
*p++ = *out++;
noff++;
if (noff < n->m_len)
continue;
do {
n = n->m_next;
} while (n && !n->m_len);
noff = 0;
if (n)
p = mtod(n, u_int8_t *) + noff;
else
p = NULL;
}
m = n;
off = noff;
}
length -= 8;
}
return 0;
}

View file

@ -1,331 +0,0 @@
/* $FreeBSD$ */
/* $KAME: des_cbc.c,v 1.4 2000/06/14 10:41:17 itojun Exp $ */
/*
* heavily modified by Yoshifumi Nishida <nishida@sfc.wide.ad.jp>.
* then, completely rewrote by Jun-ichiro itojun Itoh <itojun@itojun.org>,
* 1997.
*/
/* crypto/des/cbc_enc.c */
/* Copyright (C) 1995-1996 Eric Young (eay@mincom.oz.au)
* All rights reserved.
*
* This file is part of an SSL implementation written
* by Eric Young (eay@mincom.oz.au).
* The implementation was written so as to conform with Netscapes SSL
* specification. This library and applications are
* FREE FOR COMMERCIAL AND NON-COMMERCIAL USE
* as long as the following conditions are aheared to.
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed. If this code is used in a product,
* Eric Young should be given attribution as the author of the parts used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* 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 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 Eric Young (eay@mincom.oz.au)
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 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.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <crypto/des/des_locl.h>
#define panic(x) do {printf(x); return EINVAL;} while (0)
int des_cbc_encrypt(m0, skip, length, schedule, ivec, mode)
struct mbuf *m0;
size_t skip;
size_t length;
des_key_schedule schedule;
des_cblock (*ivec);
int mode;
{
u_int8_t inbuf[8], outbuf[8];
struct mbuf *m;
size_t off;
register DES_LONG tin0, tin1;
register DES_LONG tout0, tout1;
DES_LONG tin[2];
u_int8_t *iv;
/* sanity checks */
if (m0->m_pkthdr.len < skip) {
printf("mbuf length < skip\n");
return EINVAL;
}
if (m0->m_pkthdr.len < length) {
printf("mbuf length < encrypt length\n");
return EINVAL;
}
if (m0->m_pkthdr.len < skip + length) {
printf("mbuf length < skip + encrypt length\n");
return EINVAL;
}
if (length % 8) {
printf("length is not multiple of 8\n");
return EINVAL;
}
m = m0;
off = 0;
/* skip over the header */
while (skip) {
if (!m)
panic("mbuf chain?\n");
if (m->m_len <= skip) {
skip -= m->m_len;
m = m->m_next;
off = 0;
} else {
off = skip;
skip = 0;
}
}
/* initialize */
tin0 = tin1 = tout0 = tout1 = 0;
tin[0] = tin[1] = 0;
if (mode == DES_ENCRYPT) {
u_int8_t *in, *out;
iv = (u_int8_t *)ivec;
c2l(iv, tout0);
c2l(iv, tout1);
while (0 < length) {
if (!m)
panic("mbuf chain?\n");
/*
* copy the source into input buffer.
* don't update off or m, since we need to use them * later.
*/
if (off + 8 <= m->m_len)
bcopy(mtod(m, u_int8_t *) + off, &inbuf[0], 8);
else {
struct mbuf *n;
size_t noff;
u_int8_t *p;
u_int8_t *in;
n = m;
noff = off;
p = mtod(n, u_int8_t *) + noff;
in = &inbuf[0];
while (in - &inbuf[0] < 8) {
if (!p)
panic("mbuf chain?\n");
*in++ = *p++;
noff++;
if (noff < n->m_len)
continue;
do {
n = n->m_next;
} while (n && ! n->m_len);
noff = 0;
if (n)
p = mtod(n, u_int8_t *) + noff;
else
p = NULL;
}
}
in = &inbuf[0];
out = &outbuf[0];
c2l(in, tin0);
c2l(in, tin1);
tin0 ^= tout0; tin[0] = tin0;
tin1 ^= tout1; tin[1] = tin1;
des_encrypt((DES_LONG *)tin, schedule, DES_ENCRYPT);
tout0 = tin[0]; l2c(tout0, out);
tout1 = tin[1]; l2c(tout1, out);
/*
* copy the output buffer into the result.
* need to update off and m.
*/
if (off + 8 < m->m_len) {
bcopy(&outbuf[0], mtod(m, u_int8_t *) + off, 8);
off += 8;
} else if (off + 8 == m->m_len) {
bcopy(&outbuf[0], mtod(m, u_int8_t *) + off, 8);
do {
m = m->m_next;
} while (m && ! m->m_len);
off = 0;
} else {
struct mbuf *n;
size_t noff;
u_int8_t *p;
u_int8_t *out;
n = m;
noff = off;
p = mtod(n, u_int8_t *) + noff;
out = &outbuf[0];
while (out - &outbuf[0] < 8) {
if (!p)
panic("mbuf chain?");
*p++ = *out++;
noff++;
if (noff < n->m_len)
continue;
do {
n = n->m_next;
} while (n && ! n->m_len);
noff = 0;
if (n)
p = mtod(n, u_int8_t *) + noff;
else
p = NULL;
}
m = n;
off = noff;
}
length -= 8;
}
} else if (mode == DES_DECRYPT) {
register DES_LONG xor0, xor1;
u_int8_t *in, *out;
xor0 = xor1 = 0;
iv = (u_int8_t *)ivec;
c2l(iv, xor0);
c2l(iv, xor1);
while (0 < length) {
if (!m)
panic("mbuf chain?\n");
/*
* copy the source into input buffer.
* don't update off or m, since we need to use them * later.
*/
if (off + 8 <= m->m_len)
bcopy(mtod(m, u_int8_t *) + off, &inbuf[0], 8);
else {
struct mbuf *n;
size_t noff;
u_int8_t *p;
u_int8_t *in;
n = m;
noff = off;
p = mtod(n, u_int8_t *) + noff;
in = &inbuf[0];
while (in - &inbuf[0] < 8) {
if (!p)
panic("mbuf chain?\n");
*in++ = *p++;
noff++;
if (noff < n->m_len)
continue;
do {
n = n->m_next;
} while (n && ! n->m_len);
noff = 0;
if (n)
p = mtod(n, u_int8_t *) + noff;
else
p = NULL;
}
}
in = &inbuf[0];
out = &outbuf[0];
c2l(in, tin0); tin[0] = tin0;
c2l(in, tin1); tin[1] = tin1;
des_encrypt((DES_LONG *)tin, schedule, DES_DECRYPT);
tout0 = tin[0] ^ xor0;
tout1 = tin[1] ^ xor1;
l2c(tout0, out);
l2c(tout1, out);
xor0 = tin0;
xor1 = tin1;
/*
* copy the output buffer into the result.
* need to update off and m.
*/
if (off + 8 < m->m_len) {
bcopy(&outbuf[0], mtod(m, u_int8_t *) + off, 8);
off += 8;
} else if (off + 8 == m->m_len) {
bcopy(&outbuf[0], mtod(m, u_int8_t *) + off, 8);
do {
m = m->m_next;
} while (m && ! m->m_len);
off = 0;
} else {
struct mbuf *n;
size_t noff;
u_int8_t *p;
u_int8_t *out;
n = m;
noff = off;
p = mtod(n, u_int8_t *) + noff;
out = &outbuf[0];
while (out - &outbuf[0] < 8) {
if (!p)
panic("mbuf chain?\n");
*p++ = *out++;
noff++;
if (noff < n->m_len)
continue;
do {
n = n->m_next;
} while (n && ! n->m_len);
noff = 0;
if (n)
p = mtod(n, u_int8_t *) + noff;
else
p = NULL;
}
m = n;
off = noff;
}
length -= 8;
}
}
return 0;
}

View file

@ -1,5 +1,5 @@
/* $FreeBSD$ */
/* $KAME: des_ecb.c,v 1.3 2000/03/27 04:36:33 sumikawa Exp $ */
/* $KAME: des_ecb.c,v 1.5 2000/11/06 13:58:08 itojun Exp $ */
/* crypto/des/ecb_enc.c */
/* Copyright (C) 1995-1996 Eric Young (eay@mincom.oz.au)
@ -48,6 +48,8 @@
* [including the GNU Public Licence.]
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <crypto/des/des_locl.h>
#include <crypto/des/spr.h>

View file

@ -1,5 +1,5 @@
/* $FreeBSD$ */
/* $KAME: des_locl.h,v 1.4 2000/03/27 04:43:46 sumikawa Exp $ */
/* $KAME: des_locl.h,v 1.6 2000/11/06 13:58:09 itojun Exp $ */
/* lib/des/des_locl.h */
/* Copyright (C) 1995-1996 Eric Young (eay@mincom.oz.au)
@ -55,83 +55,17 @@
* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
*/
#include <sys/param.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/systm.h>
#ifndef HEADER_DES_LOCL_H
#define HEADER_DES_LOCL_H
#if defined(WIN32) || defined(WIN16)
#ifndef MSDOS
#define MSDOS
#endif
#endif
/*
#include <stdio.h>
#include <stdlib.h>
#ifndef MSDOS
#include <unistd.h>
#endif
*/
#include <crypto/des/des.h>
/* the following is tweaked from a config script, that is why it is a
* protected undef/define */
#ifndef DES_PTR
#undef DES_PTR
#endif
#ifdef MSDOS /* Visual C++ 2.1 (Windows NT/95) */
#include <stdlib.h>
#include <errno.h>
#include <time.h>
#include <io.h>
#ifndef RAND
#define RAND
#endif
#undef NOPROTO
#endif
#if !defined(_KERNEL) && (defined(__STDC__) || defined(VMS) || defined(M_XENIX) || defined(MSDOS))
#ifndef __NetBSD__
#include <string.h>
#endif
#endif
#ifdef __NetBSD__
#include <sys/systm.h>
#endif
#ifndef RAND
#define RAND
#endif
#ifdef linux
#undef RAND
#endif
#ifdef MSDOS
#define getpid() 2
#define RAND
#undef NOPROTO
#endif
#if defined(NOCONST)
#define const
#endif
#ifdef __STDC__
#undef NOPROTO
#endif
#ifdef RAND
#define srandom(s) srand(s)
#define random rand
#endif
#define ITERATIONS 16
#define HALF_ITERATIONS 8
@ -194,11 +128,7 @@
} \
}
#if defined(WIN32)
#define ROTATE(a,n) (_lrotr(a,n))
#else
#define ROTATE(a,n) (((a)>>(n))+((a)<<(32-(n))))
#endif
/* The changes to this macro may help or hinder, depending on the
* compiler and the achitecture. gcc2 always seems to do well :-).
@ -313,36 +243,3 @@
PERM_OP(l,r,tt, 4,0x0f0f0f0fL); \
}
#endif
/*
#define mbuf2char(i_mbuf, i_index, in) \
{ \
register int i; \
struct mbuf *m; \
char *buf; \
m = i_mbuf; \
for (i = 0; i < 8; i ++){ \
if (i_index + i == m->m_len){ \
m = m->m_next; \
} \
buf = mtod(m, char *); \
in[i] = *(buf + i); \
}
#define char2mbuf(o_mbuf, o_index, out) \
{ \
register int i; \
struct mbuf *m; \
char *buf; \
m = o_mbuf; \
for (i = 0; i < 8; i ++){ \
if (i_index + i == m->m_len){ \
m = m->m_next; \
} \
buf = mtod(m, char *); \
*(buf + i) = out[i]; \
}
*/

View file

@ -1,5 +1,5 @@
/* $FreeBSD$ */
/* $KAME: des_setkey.c,v 1.3 2000/03/27 04:36:33 sumikawa Exp $ */
/* $KAME: des_setkey.c,v 1.5 2000/11/06 13:58:09 itojun Exp $ */
/* crypto/des/set_key.c */
/* Copyright (C) 1995-1996 Eric Young (eay@mincom.oz.au)
@ -55,15 +55,13 @@
* 1.1 added norm_expand_bits
* 1.0 First working version
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <crypto/des/des_locl.h>
#include <crypto/des/podd.h>
#include <crypto/des/sk.h>
#ifndef NOPROTO
static int check_parity(des_cblock (*key));
#else
static int check_parity();
#endif
static int check_parity __P((des_cblock (*)));
int des_check_key=0;

View file

@ -1,5 +1,5 @@
/* $FreeBSD$ */
/* $KAME: md5.c,v 1.4 2000/03/27 04:36:22 sumikawa Exp $ */
/* $KAME: md5.c,v 1.5 2000/11/08 06:13:08 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.

View file

@ -1,219 +0,0 @@
/* $FreeBSD$ */
/* $KAME: rc5.c,v 1.3 2000/03/27 04:36:36 sumikawa Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <crypto/rc5/rc5.h>
void
set_rc5_expandkey(e_key, key, keylen, rounds)
RC5_WORD *e_key;
u_int8_t *key;
size_t keylen;
int rounds;
{
int i, j, k, LL, t, T;
RC5_WORD L[256/WW];
RC5_WORD A, B;
LL = (keylen + WW - 1) / WW;
bzero(L, sizeof(RC5_WORD)*LL);
for (i = 0; i < keylen; i++) {
t = (key[i] & 0xff) << (8*(i%4));
L[i/WW] = L[i/WW] + t;
}
T = 2 * (rounds + 1);
e_key[0] = Pw;
for (i = 1; i < T; i++)
e_key[i] = e_key[i-1] + Qw;
i = j = 0;
A = B = 0;
if (LL > T)
k = 3 * LL;
else
k = 3 * T;
for (; k > 0; k--) {
A = ROTL(e_key[i]+A+B, 3, W);
e_key[i] = A;
B = ROTL(L[j]+A+B, A+B, W);
L[j] = B;
i = (i + 1) % T;
j = (j + 1) % LL;
}
}
/*
*
*/
void
rc5_encrypt_round16(out, in, e_key)
u_int8_t *out;
const u_int8_t *in;
const RC5_WORD *e_key;
{
RC5_WORD A, B;
const RC5_WORD *e_keyA, *e_keyB;
A = in[0] & 0xff;
A += (in[1] & 0xff) << 8;
A += (in[2] & 0xff) << 16;
A += (in[3] & 0xff) << 24;
B = in[4] & 0xff;
B += (in[5] & 0xff) << 8;
B += (in[6] & 0xff) << 16;
B += (in[7] & 0xff) << 24;
e_keyA = e_key;
e_keyB = e_key + 1;
A += *e_keyA; e_keyA += 2;
B += *e_keyB; e_keyB += 2;
A = ROTL(A^B, B, W) + *e_keyA; e_keyA += 2;
B = ROTL(B^A, A, W) + *e_keyB; e_keyB += 2;
A = ROTL(A^B, B, W) + *e_keyA; e_keyA += 2;
B = ROTL(B^A, A, W) + *e_keyB; e_keyB += 2;
A = ROTL(A^B, B, W) + *e_keyA; e_keyA += 2;
B = ROTL(B^A, A, W) + *e_keyB; e_keyB += 2;
A = ROTL(A^B, B, W) + *e_keyA; e_keyA += 2;
B = ROTL(B^A, A, W) + *e_keyB; e_keyB += 2; /* round 4 */
A = ROTL(A^B, B, W) + *e_keyA; e_keyA += 2;
B = ROTL(B^A, A, W) + *e_keyB; e_keyB += 2;
A = ROTL(A^B, B, W) + *e_keyA; e_keyA += 2;
B = ROTL(B^A, A, W) + *e_keyB; e_keyB += 2;
A = ROTL(A^B, B, W) + *e_keyA; e_keyA += 2;
B = ROTL(B^A, A, W) + *e_keyB; e_keyB += 2;
A = ROTL(A^B, B, W) + *e_keyA; e_keyA += 2;
B = ROTL(B^A, A, W) + *e_keyB; e_keyB += 2; /* round 8 */
A = ROTL(A^B, B, W) + *e_keyA; e_keyA += 2;
B = ROTL(B^A, A, W) + *e_keyB; e_keyB += 2;
A = ROTL(A^B, B, W) + *e_keyA; e_keyA += 2;
B = ROTL(B^A, A, W) + *e_keyB; e_keyB += 2;
A = ROTL(A^B, B, W) + *e_keyA; e_keyA += 2;
B = ROTL(B^A, A, W) + *e_keyB; e_keyB += 2;
A = ROTL(A^B, B, W) + *e_keyA; e_keyA += 2;
B = ROTL(B^A, A, W) + *e_keyB; e_keyB += 2; /* round 12 */
A = ROTL(A^B, B, W) + *e_keyA; e_keyA += 2;
B = ROTL(B^A, A, W) + *e_keyB; e_keyB += 2;
A = ROTL(A^B, B, W) + *e_keyA; e_keyA += 2;
B = ROTL(B^A, A, W) + *e_keyB; e_keyB += 2;
A = ROTL(A^B, B, W) + *e_keyA; e_keyA += 2;
B = ROTL(B^A, A, W) + *e_keyB; e_keyB += 2;
A = ROTL(A^B, B, W) + *e_keyA; e_keyA += 2;
B = ROTL(B^A, A, W) + *e_keyB; e_keyB += 2; /* round 16 */
out[0] = A & 0xff;
out[1] = (A >> 8) & 0xff;
out[2] = (A >> 16) & 0xff;
out[3] = (A >> 24) & 0xff;
out[4] = B & 0xff;
out[5] = (B >> 8) & 0xff;
out[6] = (B >> 16) & 0xff;
out[7] = (B >> 24) & 0xff;
}
/*
*
*/
void
rc5_decrypt_round16(out, in, e_key)
u_int8_t *out;
const u_int8_t *in;
const RC5_WORD *e_key;
{
RC5_WORD A, B;
const RC5_WORD *e_keyA, *e_keyB;
A = in[0] & 0xff;
A += (in[1] & 0xff) << 8;
A += (in[2] & 0xff) << 16;
A += (in[3] & 0xff) << 24;
B = in[4] & 0xff;
B += (in[5] & 0xff) << 8;
B += (in[6] & 0xff) << 16;
B += (in[7] & 0xff) << 24;
e_keyA = e_key + 2*16;
e_keyB = e_key + 2*16 + 1;
B = ROTR(B-*e_keyB, A, W) ^ A; e_keyB -= 2;
A = ROTR(A-*e_keyA, B, W) ^ B; e_keyA -= 2;
B = ROTR(B-*e_keyB, A, W) ^ A; e_keyB -= 2;
A = ROTR(A-*e_keyA, B, W) ^ B; e_keyA -= 2;
B = ROTR(B-*e_keyB, A, W) ^ A; e_keyB -= 2;
A = ROTR(A-*e_keyA, B, W) ^ B; e_keyA -= 2;
B = ROTR(B-*e_keyB, A, W) ^ A; e_keyB -= 2;
A = ROTR(A-*e_keyA, B, W) ^ B; e_keyA -= 2; /* round 4 */
B = ROTR(B-*e_keyB, A, W) ^ A; e_keyB -= 2;
A = ROTR(A-*e_keyA, B, W) ^ B; e_keyA -= 2;
B = ROTR(B-*e_keyB, A, W) ^ A; e_keyB -= 2;
A = ROTR(A-*e_keyA, B, W) ^ B; e_keyA -= 2;
B = ROTR(B-*e_keyB, A, W) ^ A; e_keyB -= 2;
A = ROTR(A-*e_keyA, B, W) ^ B; e_keyA -= 2;
B = ROTR(B-*e_keyB, A, W) ^ A; e_keyB -= 2;
A = ROTR(A-*e_keyA, B, W) ^ B; e_keyA -= 2; /* round 8 */
B = ROTR(B-*e_keyB, A, W) ^ A; e_keyB -= 2;
A = ROTR(A-*e_keyA, B, W) ^ B; e_keyA -= 2;
B = ROTR(B-*e_keyB, A, W) ^ A; e_keyB -= 2;
A = ROTR(A-*e_keyA, B, W) ^ B; e_keyA -= 2;
B = ROTR(B-*e_keyB, A, W) ^ A; e_keyB -= 2;
A = ROTR(A-*e_keyA, B, W) ^ B; e_keyA -= 2;
B = ROTR(B-*e_keyB, A, W) ^ A; e_keyB -= 2;
A = ROTR(A-*e_keyA, B, W) ^ B; e_keyA -= 2; /* round 12 */
B = ROTR(B-*e_keyB, A, W) ^ A; e_keyB -= 2;
A = ROTR(A-*e_keyA, B, W) ^ B; e_keyA -= 2;
B = ROTR(B-*e_keyB, A, W) ^ A; e_keyB -= 2;
A = ROTR(A-*e_keyA, B, W) ^ B; e_keyA -= 2;
B = ROTR(B-*e_keyB, A, W) ^ A; e_keyB -= 2;
A = ROTR(A-*e_keyA, B, W) ^ B; e_keyA -= 2;
B = ROTR(B-*e_keyB, A, W) ^ A; e_keyB -= 2;
A = ROTR(A-*e_keyA, B, W) ^ B; e_keyA -= 2; /* round 16 */
B = B - *e_keyB;
A = A - *e_keyA;
out[0] = A & 0xff;
out[1] = (A >> 8) & 0xff;
out[2] = (A >> 16) & 0xff;
out[3] = (A >> 24) & 0xff;
out[4] = B & 0xff;
out[5] = (B >> 8) & 0xff;
out[6] = (B >> 16) & 0xff;
out[7] = (B >> 24) & 0xff;
}

View file

@ -1,215 +0,0 @@
/* $FreeBSD$ */
/* $KAME: rc5_cbc.c,v 1.4 2000/06/14 10:41:17 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* based on sys/crypto/des/des_cbc.c, rewrote by Tomomi Suzuki
*/
#include <crypto/rc5/rc5.h>
#define panic(x) do { printf(x); return EINVAL; } while (0)
int
rc5_cbc_process(m0, skip, length, e_key, iv, mode)
struct mbuf *m0;
size_t skip;
size_t length;
RC5_WORD *e_key;
u_int8_t *iv;
int mode;
{
u_int8_t inbuf[8], outbuf[8];
struct mbuf *m;
size_t off;
/* sanity check */
if (m0->m_pkthdr.len < skip) {
printf("rc5_cbc_process: mbuf length < skip\n");
return EINVAL;
}
if (m0->m_pkthdr.len < length) {
printf("rc5_cbc_process: mbuf length < encrypt length\n");
return EINVAL;
}
if (m0->m_pkthdr.len < skip + length) {
printf("rc5_cbc_process: mbuf length < "
"skip + encrypt length\n");
return EINVAL;
}
if (length % 8) {
printf("rc5_cbc_process: length(%lu)is not multipleof 8\n",
(u_long)length);
return EINVAL;
}
m = m0;
off = 0;
/* skip over the header */
while (skip) {
if (!m)
panic("rc5_cbc_process: mbuf chain?\n");
if (m->m_len <= skip) {
skip -= m->m_len;
m = m->m_next;
off = 0;
} else {
off = skip;
skip = 0;
}
}
/* copy iv into outbuf for XOR (encrypt) */
bcopy(iv, outbuf, 8);
/*
* encrypt/decrypt packet
*/
while (length > 0) {
int i;
if (!m)
panic("rc5_cbc_process: mbuf chain?\n");
/*
* copy the source into input buffer.
* don't update off or m, since we need to use them
* later.
*/
if (off + 8 <= m->m_len)
bcopy(mtod(m, u_int8_t *) + off, &inbuf[0], 8);
else {
struct mbuf *n;
size_t noff;
u_int8_t *p;
u_int8_t *in;
n = m;
noff = off;
p = mtod(n, u_int8_t *) + noff;
in = &inbuf[0];
while (in - &inbuf[0] < 8) {
if (!p) {
panic("rc5_cbc_process: "
"mbuf chain?\n");
}
*in++ = *p++;
noff++;
if (noff < n->m_len)
continue;
do {
n = n->m_next;
} while (n && !n->m_len);
noff = 0;
if (n)
p = mtod(n, u_int8_t *) + noff;
else
p = NULL;
}
}
/* encrypt/decrypt */
switch (mode) {
case RC5_ENCRYPT:
/* XOR */
for (i = 0; i < 8; i++)
inbuf[i] ^= outbuf[i];
/* encrypt */
rc5_encrypt_round16(outbuf, inbuf, e_key);
break;
case RC5_DECRYPT:
/* decrypt */
rc5_decrypt_round16(outbuf, inbuf, e_key);
/* XOR */
for (i = 0; i < 8; i++)
outbuf[i] ^= iv[i];
/* copy inbuf into iv for next XOR */
bcopy(inbuf, iv, 8);
break;
}
/*
* copy the output buffer into the result.
* need to update off and m.
*/
if (off + 8 < m->m_len) {
bcopy(&outbuf[0], mtod(m, u_int8_t *) + off, 8);
off += 8;
} else if (off + 8 == m->m_len) {
bcopy(&outbuf[0], mtod(m, u_int8_t *) + off, 8);
do {
m = m->m_next;
} while (m && !m->m_len);
off = 0;
} else {
struct mbuf *n;
size_t noff;
u_int8_t *p;
u_int8_t *out;
n = m;
noff = off;
p = mtod(n, u_int8_t *) + noff;
out = &outbuf[0];
while (out - &outbuf[0] < 8) {
if (!p) {
panic("rc5_cbc_process: "
"mbuf chain?\n");
}
*p++ = *out++;
noff++;
if (noff < n->m_len)
continue;
do {
n = n->m_next;
} while (n && !n->m_len);
noff = 0;
if (n)
p = mtod(n, u_int8_t *) + noff;
else
p = NULL;
}
m = n;
off = noff;
}
length -= 8;
}
return 0;
}

View file

@ -1,6 +1,7 @@
/* $KAME$ */
/* $FreeBSD$ */
/* $KAME: boxes-fst.dat,v 1.6 2001/05/27 00:23:22 itojun Exp $ */
word8 S[256] = {
const word8 S[256] = {
99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215, 171, 118,
202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175, 156, 164, 114, 192,
183, 253, 147, 38, 54, 63, 247, 204, 52, 165, 229, 241, 113, 216, 49, 21,
@ -20,7 +21,7 @@ word8 S[256] = {
};
#ifdef INTERMEDIATE_VALUE_KAT
static word8 Si[256] = {
static const word8 Si[256] = {
82, 9, 106, 213, 48, 54, 165, 56, 191, 64, 163, 158, 129, 243, 215, 251,
124, 227, 57, 130, 155, 47, 255, 135, 52, 142, 67, 68, 196, 222, 233, 203,
84, 123, 148, 50, 166, 194, 35, 61, 238, 76, 149, 11, 66, 250, 195, 78,
@ -40,7 +41,13 @@ static word8 Si[256] = {
};
#endif /* INTERMEDIATE_VALUE_KAT */
static word8 T1[256][4] = {
union xtab {
word32 xt32[256];
word8 xt8[256][4];
};
static const union xtab xT1 = {
.xt8 = {
{0xc6,0x63,0x63,0xa5}, {0xf8,0x7c,0x7c,0x84}, {0xee,0x77,0x77,0x99}, {0xf6,0x7b,0x7b,0x8d},
{0xff,0xf2,0xf2,0x0d}, {0xd6,0x6b,0x6b,0xbd}, {0xde,0x6f,0x6f,0xb1}, {0x91,0xc5,0xc5,0x54},
{0x60,0x30,0x30,0x50}, {0x02,0x01,0x01,0x03}, {0xce,0x67,0x67,0xa9}, {0x56,0x2b,0x2b,0x7d},
@ -105,9 +112,12 @@ static word8 T1[256][4] = {
{0x65,0xbf,0xbf,0xda}, {0xd7,0xe6,0xe6,0x31}, {0x84,0x42,0x42,0xc6}, {0xd0,0x68,0x68,0xb8},
{0x82,0x41,0x41,0xc3}, {0x29,0x99,0x99,0xb0}, {0x5a,0x2d,0x2d,0x77}, {0x1e,0x0f,0x0f,0x11},
{0x7b,0xb0,0xb0,0xcb}, {0xa8,0x54,0x54,0xfc}, {0x6d,0xbb,0xbb,0xd6}, {0x2c,0x16,0x16,0x3a}
}
};
#define T1 xT1.xt8
static word8 T2[256][4] = {
static const union xtab xT2 = {
.xt8 = {
{0xa5,0xc6,0x63,0x63}, {0x84,0xf8,0x7c,0x7c}, {0x99,0xee,0x77,0x77}, {0x8d,0xf6,0x7b,0x7b},
{0x0d,0xff,0xf2,0xf2}, {0xbd,0xd6,0x6b,0x6b}, {0xb1,0xde,0x6f,0x6f}, {0x54,0x91,0xc5,0xc5},
{0x50,0x60,0x30,0x30}, {0x03,0x02,0x01,0x01}, {0xa9,0xce,0x67,0x67}, {0x7d,0x56,0x2b,0x2b},
@ -172,9 +182,12 @@ static word8 T2[256][4] = {
{0xda,0x65,0xbf,0xbf}, {0x31,0xd7,0xe6,0xe6}, {0xc6,0x84,0x42,0x42}, {0xb8,0xd0,0x68,0x68},
{0xc3,0x82,0x41,0x41}, {0xb0,0x29,0x99,0x99}, {0x77,0x5a,0x2d,0x2d}, {0x11,0x1e,0x0f,0x0f},
{0xcb,0x7b,0xb0,0xb0}, {0xfc,0xa8,0x54,0x54}, {0xd6,0x6d,0xbb,0xbb}, {0x3a,0x2c,0x16,0x16}
}
};
#define T2 xT2.xt8
static word8 T3[256][4] = {
static const union xtab xT3 = {
.xt8 = {
{0x63,0xa5,0xc6,0x63}, {0x7c,0x84,0xf8,0x7c}, {0x77,0x99,0xee,0x77}, {0x7b,0x8d,0xf6,0x7b},
{0xf2,0x0d,0xff,0xf2}, {0x6b,0xbd,0xd6,0x6b}, {0x6f,0xb1,0xde,0x6f}, {0xc5,0x54,0x91,0xc5},
{0x30,0x50,0x60,0x30}, {0x01,0x03,0x02,0x01}, {0x67,0xa9,0xce,0x67}, {0x2b,0x7d,0x56,0x2b},
@ -239,9 +252,12 @@ static word8 T3[256][4] = {
{0xbf,0xda,0x65,0xbf}, {0xe6,0x31,0xd7,0xe6}, {0x42,0xc6,0x84,0x42}, {0x68,0xb8,0xd0,0x68},
{0x41,0xc3,0x82,0x41}, {0x99,0xb0,0x29,0x99}, {0x2d,0x77,0x5a,0x2d}, {0x0f,0x11,0x1e,0x0f},
{0xb0,0xcb,0x7b,0xb0}, {0x54,0xfc,0xa8,0x54}, {0xbb,0xd6,0x6d,0xbb}, {0x16,0x3a,0x2c,0x16}
}
};
#define T3 xT3.xt8
static word8 T4[256][4] = {
static const union xtab xT4 = {
.xt8 = {
{0x63,0x63,0xa5,0xc6}, {0x7c,0x7c,0x84,0xf8}, {0x77,0x77,0x99,0xee}, {0x7b,0x7b,0x8d,0xf6},
{0xf2,0xf2,0x0d,0xff}, {0x6b,0x6b,0xbd,0xd6}, {0x6f,0x6f,0xb1,0xde}, {0xc5,0xc5,0x54,0x91},
{0x30,0x30,0x50,0x60}, {0x01,0x01,0x03,0x02}, {0x67,0x67,0xa9,0xce}, {0x2b,0x2b,0x7d,0x56},
@ -306,9 +322,12 @@ static word8 T4[256][4] = {
{0xbf,0xbf,0xda,0x65}, {0xe6,0xe6,0x31,0xd7}, {0x42,0x42,0xc6,0x84}, {0x68,0x68,0xb8,0xd0},
{0x41,0x41,0xc3,0x82}, {0x99,0x99,0xb0,0x29}, {0x2d,0x2d,0x77,0x5a}, {0x0f,0x0f,0x11,0x1e},
{0xb0,0xb0,0xcb,0x7b}, {0x54,0x54,0xfc,0xa8}, {0xbb,0xbb,0xd6,0x6d}, {0x16,0x16,0x3a,0x2c}
}
};
#define T4 xT4.xt8
static word8 T5[256][4] = {
static const union xtab xT5 = {
.xt8 = {
{0x51,0xf4,0xa7,0x50}, {0x7e,0x41,0x65,0x53}, {0x1a,0x17,0xa4,0xc3}, {0x3a,0x27,0x5e,0x96},
{0x3b,0xab,0x6b,0xcb}, {0x1f,0x9d,0x45,0xf1}, {0xac,0xfa,0x58,0xab}, {0x4b,0xe3,0x03,0x93},
{0x20,0x30,0xfa,0x55}, {0xad,0x76,0x6d,0xf6}, {0x88,0xcc,0x76,0x91}, {0xf5,0x02,0x4c,0x25},
@ -373,9 +392,12 @@ static word8 T5[256][4] = {
{0x16,0x1d,0xc3,0x72}, {0xbc,0xe2,0x25,0x0c}, {0x28,0x3c,0x49,0x8b}, {0xff,0x0d,0x95,0x41},
{0x39,0xa8,0x01,0x71}, {0x08,0x0c,0xb3,0xde}, {0xd8,0xb4,0xe4,0x9c}, {0x64,0x56,0xc1,0x90},
{0x7b,0xcb,0x84,0x61}, {0xd5,0x32,0xb6,0x70}, {0x48,0x6c,0x5c,0x74}, {0xd0,0xb8,0x57,0x42}
}
};
#define T5 xT5.xt8
static word8 T6[256][4] = {
static const union xtab xT6 = {
.xt8 = {
{0x50,0x51,0xf4,0xa7}, {0x53,0x7e,0x41,0x65}, {0xc3,0x1a,0x17,0xa4}, {0x96,0x3a,0x27,0x5e},
{0xcb,0x3b,0xab,0x6b}, {0xf1,0x1f,0x9d,0x45}, {0xab,0xac,0xfa,0x58}, {0x93,0x4b,0xe3,0x03},
{0x55,0x20,0x30,0xfa}, {0xf6,0xad,0x76,0x6d}, {0x91,0x88,0xcc,0x76}, {0x25,0xf5,0x02,0x4c},
@ -440,9 +462,12 @@ static word8 T6[256][4] = {
{0x72,0x16,0x1d,0xc3}, {0x0c,0xbc,0xe2,0x25}, {0x8b,0x28,0x3c,0x49}, {0x41,0xff,0x0d,0x95},
{0x71,0x39,0xa8,0x01}, {0xde,0x08,0x0c,0xb3}, {0x9c,0xd8,0xb4,0xe4}, {0x90,0x64,0x56,0xc1},
{0x61,0x7b,0xcb,0x84}, {0x70,0xd5,0x32,0xb6}, {0x74,0x48,0x6c,0x5c}, {0x42,0xd0,0xb8,0x57}
}
};
#define T6 xT6.xt8
static word8 T7[256][4] = {
static const union xtab xT7 = {
.xt8 = {
{0xa7,0x50,0x51,0xf4}, {0x65,0x53,0x7e,0x41}, {0xa4,0xc3,0x1a,0x17}, {0x5e,0x96,0x3a,0x27},
{0x6b,0xcb,0x3b,0xab}, {0x45,0xf1,0x1f,0x9d}, {0x58,0xab,0xac,0xfa}, {0x03,0x93,0x4b,0xe3},
{0xfa,0x55,0x20,0x30}, {0x6d,0xf6,0xad,0x76}, {0x76,0x91,0x88,0xcc}, {0x4c,0x25,0xf5,0x02},
@ -507,9 +532,12 @@ static word8 T7[256][4] = {
{0xc3,0x72,0x16,0x1d}, {0x25,0x0c,0xbc,0xe2}, {0x49,0x8b,0x28,0x3c}, {0x95,0x41,0xff,0x0d},
{0x01,0x71,0x39,0xa8}, {0xb3,0xde,0x08,0x0c}, {0xe4,0x9c,0xd8,0xb4}, {0xc1,0x90,0x64,0x56},
{0x84,0x61,0x7b,0xcb}, {0xb6,0x70,0xd5,0x32}, {0x5c,0x74,0x48,0x6c}, {0x57,0x42,0xd0,0xb8}
}
};
#define T7 xT7.xt8
static word8 T8[256][4] = {
static const union xtab xT8 = {
.xt8 = {
{0xf4,0xa7,0x50,0x51}, {0x41,0x65,0x53,0x7e}, {0x17,0xa4,0xc3,0x1a}, {0x27,0x5e,0x96,0x3a},
{0xab,0x6b,0xcb,0x3b}, {0x9d,0x45,0xf1,0x1f}, {0xfa,0x58,0xab,0xac}, {0xe3,0x03,0x93,0x4b},
{0x30,0xfa,0x55,0x20}, {0x76,0x6d,0xf6,0xad}, {0xcc,0x76,0x91,0x88}, {0x02,0x4c,0x25,0xf5},
@ -574,9 +602,11 @@ static word8 T8[256][4] = {
{0x1d,0xc3,0x72,0x16}, {0xe2,0x25,0x0c,0xbc}, {0x3c,0x49,0x8b,0x28}, {0x0d,0x95,0x41,0xff},
{0xa8,0x01,0x71,0x39}, {0x0c,0xb3,0xde,0x08}, {0xb4,0xe4,0x9c,0xd8}, {0x56,0xc1,0x90,0x64},
{0xcb,0x84,0x61,0x7b}, {0x32,0xb6,0x70,0xd5}, {0x6c,0x5c,0x74,0x48}, {0xb8,0x57,0x42,0xd0}
}
};
#define T8 xT8.xt8
static word8 S5[256] = {
static const word8 S5[256] = {
0x52,0x09,0x6a,0xd5,
0x30,0x36,0xa5,0x38,
0xbf,0x40,0xa3,0x9e,
@ -643,7 +673,8 @@ static word8 S5[256] = {
0x55,0x21,0x0c,0x7d
};
static word8 U1[256][4] = {
static const union xtab xU1 = {
.xt8 = {
{0x00,0x00,0x00,0x00}, {0x0e,0x09,0x0d,0x0b}, {0x1c,0x12,0x1a,0x16}, {0x12,0x1b,0x17,0x1d},
{0x38,0x24,0x34,0x2c}, {0x36,0x2d,0x39,0x27}, {0x24,0x36,0x2e,0x3a}, {0x2a,0x3f,0x23,0x31},
{0x70,0x48,0x68,0x58}, {0x7e,0x41,0x65,0x53}, {0x6c,0x5a,0x72,0x4e}, {0x62,0x53,0x7f,0x45},
@ -708,9 +739,12 @@ static word8 U1[256][4] = {
{0xef,0x15,0xe8,0xe6}, {0xe1,0x1c,0xe5,0xed}, {0xf3,0x07,0xf2,0xf0}, {0xfd,0x0e,0xff,0xfb},
{0xa7,0x79,0xb4,0x92}, {0xa9,0x70,0xb9,0x99}, {0xbb,0x6b,0xae,0x84}, {0xb5,0x62,0xa3,0x8f},
{0x9f,0x5d,0x80,0xbe}, {0x91,0x54,0x8d,0xb5}, {0x83,0x4f,0x9a,0xa8}, {0x8d,0x46,0x97,0xa3}
}
};
#define U1 xU1.xt8
static word8 U2[256][4] = {
static const union xtab xU2 = {
.xt8 = {
{0x00,0x00,0x00,0x00}, {0x0b,0x0e,0x09,0x0d}, {0x16,0x1c,0x12,0x1a}, {0x1d,0x12,0x1b,0x17},
{0x2c,0x38,0x24,0x34}, {0x27,0x36,0x2d,0x39}, {0x3a,0x24,0x36,0x2e}, {0x31,0x2a,0x3f,0x23},
{0x58,0x70,0x48,0x68}, {0x53,0x7e,0x41,0x65}, {0x4e,0x6c,0x5a,0x72}, {0x45,0x62,0x53,0x7f},
@ -775,9 +809,12 @@ static word8 U2[256][4] = {
{0xe6,0xef,0x15,0xe8}, {0xed,0xe1,0x1c,0xe5}, {0xf0,0xf3,0x07,0xf2}, {0xfb,0xfd,0x0e,0xff},
{0x92,0xa7,0x79,0xb4}, {0x99,0xa9,0x70,0xb9}, {0x84,0xbb,0x6b,0xae}, {0x8f,0xb5,0x62,0xa3},
{0xbe,0x9f,0x5d,0x80}, {0xb5,0x91,0x54,0x8d}, {0xa8,0x83,0x4f,0x9a}, {0xa3,0x8d,0x46,0x97}
}
};
#define U2 xU2.xt8
static word8 U3[256][4] = {
static const union xtab xU3 = {
.xt8 = {
{0x00,0x00,0x00,0x00}, {0x0d,0x0b,0x0e,0x09}, {0x1a,0x16,0x1c,0x12}, {0x17,0x1d,0x12,0x1b},
{0x34,0x2c,0x38,0x24}, {0x39,0x27,0x36,0x2d}, {0x2e,0x3a,0x24,0x36}, {0x23,0x31,0x2a,0x3f},
{0x68,0x58,0x70,0x48}, {0x65,0x53,0x7e,0x41}, {0x72,0x4e,0x6c,0x5a}, {0x7f,0x45,0x62,0x53},
@ -842,9 +879,12 @@ static word8 U3[256][4] = {
{0xe8,0xe6,0xef,0x15}, {0xe5,0xed,0xe1,0x1c}, {0xf2,0xf0,0xf3,0x07}, {0xff,0xfb,0xfd,0x0e},
{0xb4,0x92,0xa7,0x79}, {0xb9,0x99,0xa9,0x70}, {0xae,0x84,0xbb,0x6b}, {0xa3,0x8f,0xb5,0x62},
{0x80,0xbe,0x9f,0x5d}, {0x8d,0xb5,0x91,0x54}, {0x9a,0xa8,0x83,0x4f}, {0x97,0xa3,0x8d,0x46}
}
};
#define U3 xU3.xt8
static word8 U4[256][4] = {
static const union xtab xU4 = {
.xt8 = {
{0x00,0x00,0x00,0x00}, {0x09,0x0d,0x0b,0x0e}, {0x12,0x1a,0x16,0x1c}, {0x1b,0x17,0x1d,0x12},
{0x24,0x34,0x2c,0x38}, {0x2d,0x39,0x27,0x36}, {0x36,0x2e,0x3a,0x24}, {0x3f,0x23,0x31,0x2a},
{0x48,0x68,0x58,0x70}, {0x41,0x65,0x53,0x7e}, {0x5a,0x72,0x4e,0x6c}, {0x53,0x7f,0x45,0x62},
@ -909,8 +949,10 @@ static word8 U4[256][4] = {
{0x15,0xe8,0xe6,0xef}, {0x1c,0xe5,0xed,0xe1}, {0x07,0xf2,0xf0,0xf3}, {0x0e,0xff,0xfb,0xfd},
{0x79,0xb4,0x92,0xa7}, {0x70,0xb9,0x99,0xa9}, {0x6b,0xae,0x84,0xbb}, {0x62,0xa3,0x8f,0xb5},
{0x5d,0x80,0xbe,0x9f}, {0x54,0x8d,0xb5,0x91}, {0x4f,0x9a,0xa8,0x83}, {0x46,0x97,0xa3,0x8d}
}
};
#define U4 xU4.xt8
static word32 rcon[30] = {
static const word32 rcon[30] = {
0x01,0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91
};

View file

@ -1,4 +1,5 @@
/* $KAME$ */
/* $FreeBSD$ */
/* $KAME: rijndael-alg-fst.c,v 1.7 2001/05/27 00:23:23 itojun Exp $ */
/*
* rijndael-alg-fst.c v2.3 April '2000
@ -14,6 +15,11 @@
#include <sys/cdefs.h>
#include <sys/types.h>
#ifdef _KERNEL
#include <sys/systm.h>
#else
#include <string.h>
#endif
#include <crypto/rijndael/rijndael-alg-fst.h>
#include <crypto/rijndael/rijndael_local.h>
@ -24,7 +30,11 @@ int rijndaelKeySched(word8 k[MAXKC][4], word8 W[MAXROUNDS+1][4][4], int ROUNDS)
* The number of calculations depends on keyBits and blockBits
*/
int j, r, t, rconpointer = 0;
word8 tk[MAXKC][4];
union {
word8 x8[MAXKC][4];
word32 x32[MAXKC];
} xtk;
#define tk xtk.x8
int KC = ROUNDS - 6;
for (j = KC-1; j >= 0; j--) {
@ -79,6 +89,7 @@ int rijndaelKeySched(word8 k[MAXKC][4], word8 W[MAXROUNDS+1][4][4], int ROUNDS)
}
}
return 0;
#undef tk
}
int rijndaelKeyEncToDec(word8 W[MAXROUNDS+1][4][4], int ROUNDS) {
@ -120,9 +131,21 @@ int rijndaelKeyEncToDec(word8 W[MAXROUNDS+1][4][4], int ROUNDS) {
/**
* Encrypt a single block.
*/
int rijndaelEncrypt(word8 a[16], word8 b[16], word8 rk[MAXROUNDS+1][4][4], int ROUNDS) {
int rijndaelEncrypt(word8 in[16], word8 out[16], word8 rk[MAXROUNDS+1][4][4], int ROUNDS) {
int r;
word8 temp[4][4];
union {
word8 x8[16];
word32 x32[4];
} xa, xb;
#define a xa.x8
#define b xb.x8
union {
word8 x8[4][4];
word32 x32[4];
} xtemp;
#define temp xtemp.x8
memcpy(a, in, sizeof a);
*((word32*)temp[0]) = *((word32*)(a )) ^ *((word32*)rk[0][0]);
*((word32*)temp[1]) = *((word32*)(a+ 4)) ^ *((word32*)rk[0][1]);
@ -193,7 +216,12 @@ int rijndaelEncrypt(word8 a[16], word8 b[16], word8 rk[MAXROUNDS+1][4][4], int R
*((word32*)(b+ 8)) ^= *((word32*)rk[ROUNDS][2]);
*((word32*)(b+12)) ^= *((word32*)rk[ROUNDS][3]);
memcpy(out, b, sizeof b /* XXX out */);
return 0;
#undef a
#undef b
#undef temp
}
#ifdef INTERMEDIATE_VALUE_KAT
@ -268,10 +296,22 @@ int rijndaelEncryptRound(word8 a[4][4], word8 rk[MAXROUNDS+1][4][4], int ROUNDS,
/**
* Decrypt a single block.
*/
int rijndaelDecrypt(word8 a[16], word8 b[16], word8 rk[MAXROUNDS+1][4][4], int ROUNDS) {
int rijndaelDecrypt(word8 in[16], word8 out[16], word8 rk[MAXROUNDS+1][4][4], int ROUNDS) {
int r;
word8 temp[4][4];
union {
word8 x8[16];
word32 x32[4];
} xa, xb;
#define a xa.x8
#define b xb.x8
union {
word8 x8[4][4];
word32 x32[4];
} xtemp;
#define temp xtemp.x8
memcpy(a, in, sizeof a);
*((word32*)temp[0]) = *((word32*)(a )) ^ *((word32*)rk[ROUNDS][0]);
*((word32*)temp[1]) = *((word32*)(a+ 4)) ^ *((word32*)rk[ROUNDS][1]);
*((word32*)temp[2]) = *((word32*)(a+ 8)) ^ *((word32*)rk[ROUNDS][2]);
@ -341,7 +381,12 @@ int rijndaelDecrypt(word8 a[16], word8 b[16], word8 rk[MAXROUNDS+1][4][4], int R
*((word32*)(b+ 8)) ^= *((word32*)rk[0][2]);
*((word32*)(b+12)) ^= *((word32*)rk[0][3]);
memcpy(out, b, sizeof b /* XXX out */);
return 0;
#undef a
#undef b
#undef temp
}

View file

@ -1,4 +1,5 @@
/* $KAME$ */
/* $FreeBSD$ */
/* $KAME: rijndael-alg-fst.h,v 1.4 2000/10/02 17:14:26 itojun Exp $ */
/*
* rijndael-alg-fst.h v2.3 April '2000

View file

@ -1,4 +1,5 @@
/* $KAME: $ */
/* $FreeBSD$ */
/* $KAME: rijndael-api-fst.c,v 1.10 2001/05/27 09:34:18 itojun Exp $ */
/*
* rijndael-api-fst.c v2.3 April '2000
@ -16,8 +17,12 @@
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/types.h>
#ifdef _KERNEL
#include <sys/systm.h>
#else
#include <string.h>
#endif
#include <crypto/rijndael/rijndael-alg-fst.h>
#include <crypto/rijndael/rijndael-api-fst.h>
#include <crypto/rijndael/rijndael_local.h>
@ -44,36 +49,16 @@ int rijndael_makeKey(keyInstance *key, BYTE direction, int keyLen, char *keyMate
}
if (keyMaterial != NULL) {
strncpy(key->keyMaterial, keyMaterial, keyLen/4);
bcopy(keyMaterial, key->keyMaterial, keyLen/8);
}
key->ROUNDS = keyLen/32 + 6;
/* initialize key schedule: */
keyMat = key->keyMaterial;
#ifndef BINARY_KEY_MATERIAL
for (i = 0; i < key->keyLen/8; i++) {
int t, j;
t = *keyMat++;
if ((t >= '0') && (t <= '9')) j = (t - '0') << 4;
else if ((t >= 'a') && (t <= 'f')) j = (t - 'a' + 10) << 4;
else if ((t >= 'A') && (t <= 'F')) j = (t - 'A' + 10) << 4;
else return BAD_KEY_MAT;
t = *keyMat++;
if ((t >= '0') && (t <= '9')) j ^= (t - '0');
else if ((t >= 'a') && (t <= 'f')) j ^= (t - 'a' + 10);
else if ((t >= 'A') && (t <= 'F')) j ^= (t - 'A' + 10);
else return BAD_KEY_MAT;
k[i >> 2][i & 3] = (word8)j;
}
#else
for (i = 0; i < key->keyLen/8; i++) {
k[i >> 2][i & 3] = (word8)keyMat[i];
}
#endif /* ?BINARY_KEY_MATERIAL */
rijndaelKeySched(k, key->keySched, key->ROUNDS);
if (direction == DIR_DECRYPT) {
rijndaelKeyEncToDec(key->keySched, key->ROUNDS);
@ -89,28 +74,7 @@ int rijndael_cipherInit(cipherInstance *cipher, BYTE mode, char *IV) {
return BAD_CIPHER_MODE;
}
if (IV != NULL) {
#ifndef BINARY_KEY_MATERIAL
int i;
for (i = 0; i < MAX_IV_SIZE; i++) {
int t, j;
t = IV[2*i];
if ((t >= '0') && (t <= '9')) j = (t - '0') << 4;
else if ((t >= 'a') && (t <= 'f')) j = (t - 'a' + 10) << 4;
else if ((t >= 'A') && (t <= 'F')) j = (t - 'A' + 10) << 4;
else return BAD_CIPHER_INSTANCE;
t = IV[2*i+1];
if ((t >= '0') && (t <= '9')) j ^= (t - '0');
else if ((t >= 'a') && (t <= 'f')) j ^= (t - 'a' + 10);
else if ((t >= 'A') && (t <= 'F')) j ^= (t - 'A' + 10);
else return BAD_CIPHER_INSTANCE;
cipher->IV[i] = (word8)j;
}
#else
bcopy(IV, cipher->IV, MAX_IV_SIZE);
#endif /* ?BINARY_KEY_MATERIAL */
} else {
bzero(cipher->IV, MAX_IV_SIZE);
}

View file

@ -1,4 +1,5 @@
/* $KAME$ */
/* $FreeBSD$ */
/* $KAME: rijndael-api-fst.h,v 1.6 2001/05/27 00:23:23 itojun Exp $ */
/*
* rijndael-api-fst.h v2.3 April '2000
@ -55,7 +56,11 @@ typedef struct {
/* The following parameters are algorithm dependent, replace or add as necessary */
int ROUNDS; /* key-length-dependent number of rounds */
int blockLen; /* block length */
u_int8_t keySched[RIJNDAEL_MAXROUNDS+1][4][4]; /* key schedule */
union {
u_int8_t xkS8[RIJNDAEL_MAXROUNDS+1][4][4]; /* key schedule */
u_int32_t xkS32[RIJNDAEL_MAXROUNDS+1][4]; /* key schedule */
} xKeySched;
#define keySched xKeySched.xkS8
} keyInstance;
/* The structure for cipher information */

View file

@ -9,5 +9,3 @@ typedef u_int32_t word32;
#define MAXKC RIJNDAEL_MAXKC
#define MAXROUNDS RIJNDAEL_MAXROUNDS
#define BINARY_KEY_MATERIAL 1

View file

@ -1,5 +1,5 @@
/* $FreeBSD$ */
/* $KAME: sha1.c,v 1.4 2000/03/27 04:36:23 sumikawa Exp $ */
/* $KAME: sha1.c,v 1.5 2000/11/08 06:13:08 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.

1048
sys/crypto/sha2/sha2.c Normal file

File diff suppressed because it is too large Load diff

141
sys/crypto/sha2/sha2.h Normal file
View file

@ -0,0 +1,141 @@
/* $FreeBSD$ */
/* $KAME: sha2.h,v 1.3 2001/03/12 08:27:48 itojun Exp $ */
/*
* sha2.h
*
* Version 1.0.0beta1
*
* Written by Aaron D. Gifford <me@aarongifford.com>
*
* Copyright 2000 Aaron D. Gifford. 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 copyright holder nor the names of contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTOR(S) ``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(S) OR CONTRIBUTOR(S) 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.
*
*/
#ifndef __SHA2_H__
#define __SHA2_H__
#ifdef __cplusplus
extern "C" {
#endif
/*** SHA-256/384/512 Various Length Definitions ***********************/
#define SHA256_BLOCK_LENGTH 64
#define SHA256_DIGEST_LENGTH 32
#define SHA256_DIGEST_STRING_LENGTH (SHA256_DIGEST_LENGTH * 2 + 1)
#define SHA384_BLOCK_LENGTH 128
#define SHA384_DIGEST_LENGTH 48
#define SHA384_DIGEST_STRING_LENGTH (SHA384_DIGEST_LENGTH * 2 + 1)
#define SHA512_BLOCK_LENGTH 128
#define SHA512_DIGEST_LENGTH 64
#define SHA512_DIGEST_STRING_LENGTH (SHA512_DIGEST_LENGTH * 2 + 1)
/*** SHA-256/384/512 Context Structures *******************************/
/* NOTE: If your architecture does not define either u_intXX_t types or
* uintXX_t (from inttypes.h), you may need to define things by hand
* for your system:
*/
#if 0
typedef unsigned char u_int8_t; /* 1-byte (8-bits) */
typedef unsigned int u_int32_t; /* 4-bytes (32-bits) */
typedef unsigned long long u_int64_t; /* 8-bytes (64-bits) */
#endif
/*
* Most BSD systems already define u_intXX_t types, as does Linux.
* Some systems, however, like Compaq's Tru64 Unix instead can use
* uintXX_t types defined by very recent ANSI C standards and included
* in the file:
*
* #include <inttypes.h>
*
* If you choose to use <inttypes.h> then please define:
*
* #define SHA2_USE_INTTYPES_H
*
* Or on the command line during compile:
*
* cc -DSHA2_USE_INTTYPES_H ...
*/
#if 0 /*def SHA2_USE_INTTYPES_H*/
typedef struct _SHA256_CTX {
uint32_t state[8];
uint64_t bitcount;
uint8_t buffer[SHA256_BLOCK_LENGTH];
} SHA256_CTX;
typedef struct _SHA512_CTX {
uint64_t state[8];
uint64_t bitcount[2];
uint8_t buffer[SHA512_BLOCK_LENGTH];
} SHA512_CTX;
#else /* SHA2_USE_INTTYPES_H */
typedef struct _SHA256_CTX {
u_int32_t state[8];
u_int64_t bitcount;
u_int8_t buffer[SHA256_BLOCK_LENGTH];
} SHA256_CTX;
typedef struct _SHA512_CTX {
u_int64_t state[8];
u_int64_t bitcount[2];
u_int8_t buffer[SHA512_BLOCK_LENGTH];
} SHA512_CTX;
#endif /* SHA2_USE_INTTYPES_H */
typedef SHA512_CTX SHA384_CTX;
/*** SHA-256/384/512 Function Prototypes ******************************/
void SHA256_Init __P((SHA256_CTX *));
void SHA256_Update __P((SHA256_CTX*, const u_int8_t*, size_t));
void SHA256_Final __P((u_int8_t[SHA256_DIGEST_LENGTH], SHA256_CTX*));
char* SHA256_End __P((SHA256_CTX*, char[SHA256_DIGEST_STRING_LENGTH]));
char* SHA256_Data __P((const u_int8_t*, size_t, char[SHA256_DIGEST_STRING_LENGTH]));
void SHA384_Init __P((SHA384_CTX*));
void SHA384_Update __P((SHA384_CTX*, const u_int8_t*, size_t));
void SHA384_Final __P((u_int8_t[SHA384_DIGEST_LENGTH], SHA384_CTX*));
char* SHA384_End __P((SHA384_CTX*, char[SHA384_DIGEST_STRING_LENGTH]));
char* SHA384_Data __P((const u_int8_t*, size_t, char[SHA384_DIGEST_STRING_LENGTH]));
void SHA512_Init __P((SHA512_CTX*));
void SHA512_Update __P((SHA512_CTX*, const u_int8_t*, size_t));
void SHA512_Final __P((u_int8_t[SHA512_DIGEST_LENGTH], SHA512_CTX*));
char* SHA512_End __P((SHA512_CTX*, char[SHA512_DIGEST_STRING_LENGTH]));
char* SHA512_Data __P((const u_int8_t*, size_t, char[SHA512_DIGEST_STRING_LENGTH]));
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __SHA2_H__ */

View file

@ -209,6 +209,32 @@ pfctlinput(cmd, sa)
(*pr->pr_ctlinput)(cmd, sa, (void *)0);
}
void
pfctlinput2(cmd, sa, ctlparam)
int cmd;
struct sockaddr *sa;
void *ctlparam;
{
struct domain *dp;
struct protosw *pr;
if (!sa)
return;
for (dp = domains; dp; dp = dp->dom_next) {
/*
* the check must be made by xx_ctlinput() anyways, to
* make sure we use data item pointed to by ctlparam in
* correct way. the following check is made just for safety.
*/
if (dp->dom_family != sa->sa_family)
continue;
for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
if (pr->pr_ctlinput)
(*pr->pr_ctlinput)(cmd, sa, ctlparam);
}
}
static void
pfslowtimo(arg)
void *arg;

View file

@ -570,15 +570,6 @@ m_freem(struct mbuf *m)
if (m == NULL)
return;
do {
/*
* we do need to check non-first mbuf, since some of existing
* code does not call M_PREPEND properly.
* (example: call to bpf_mtap from drivers)
*/
if ((m->m_flags & M_PKTHDR) != 0 && m->m_pkthdr.aux) {
m_freem(m->m_pkthdr.aux);
m->m_pkthdr.aux = NULL;
}
MFREE(m, n);
m = n;
} while (m);

View file

@ -1,5 +1,5 @@
/* $FreeBSD$ */
/* $KAME: uipc_mbuf2.c,v 1.15 2000/02/22 14:01:37 itojun Exp $ */
/* $KAME: uipc_mbuf2.c,v 1.29 2001/02/14 13:42:10 itojun Exp $ */
/* $NetBSD: uipc_mbuf.c,v 1.40 1999/04/01 00:23:25 thorpej Exp $ */
/*
@ -75,6 +75,9 @@
#include <sys/mbuf.h>
#include <sys/mutex.h>
/* can't call it m_dup(), as freebsd[34] uses m_dup() with different arg */
static struct mbuf *m_dup1 __P((struct mbuf *, int, int, int));
/*
* ensure that [off, off + len) is contiguous on the mbuf chain "m".
* packet chain before "off" is kept untouched.
@ -124,21 +127,48 @@ m_pulldown(struct mbuf *m, int off, int len, int *offp)
return NULL; /* mbuf chain too short */
}
/*
* XXX: This code is flawed because it considers a "writable" mbuf
* data region to require all of the following:
* (i) mbuf _has_ to have M_EXT set; if it is just a regular
* mbuf, it is still not considered "writable."
* (ii) since mbuf has M_EXT, the ext_type _has_ to be
* EXT_CLUSTER. Anything else makes it non-writable.
* (iii) M_WRITABLE() must evaluate true.
* Ideally, the requirement should only be (iii).
*
* If we're writable, we're sure we're writable, because the ref. count
* cannot increase from 1, as that would require posession of mbuf
* n by someone else (which is impossible). However, if we're _not_
* writable, we may eventually become writable )if the ref. count drops
* to 1), but we'll fail to notice it unless we re-evaluate
* M_WRITABLE(). For now, we only evaluate once at the beginning and
* live with this.
*/
/*
* XXX: This is dumb. If we're just a regular mbuf with no M_EXT,
* then we're not "writable," according to this code.
*/
writable = 0;
if ((n->m_flags & M_EXT) == 0 ||
(n->m_ext.ext_type == EXT_CLUSTER && M_WRITABLE(n)))
writable = 1;
/*
* the target data is on <n, off>.
* if we got enough data on the mbuf "n", we're done.
*/
if ((off == 0 || offp) && len <= n->m_len - off)
if ((off == 0 || offp) && len <= n->m_len - off && writable)
goto ok;
/*
* when len < n->m_len - off and off != 0, it is a special case.
* when len <= n->m_len - off and off != 0, it is a special case.
* len bytes from <n, off> sits in single mbuf, but the caller does
* not like the starting position (off).
* chop the current mbuf into two pieces, set off to 0.
*/
if (len < n->m_len - off) {
o = m_copym(n, off, n->m_len - off, M_DONTWAIT);
if (len <= n->m_len - off) {
o = m_dup1(n, off, n->m_len - off, M_DONTWAIT);
if (o == NULL) {
m_freem(m);
return NULL; /* ENOBUFS */
@ -175,33 +205,6 @@ m_pulldown(struct mbuf *m, int off, int len, int *offp)
* easy cases first.
* we need to use m_copydata() to get data from <n->m_next, 0>.
*/
/*
* XXX: This code is flawed because it considers a "writable" mbuf
* data region to require all of the following:
* (i) mbuf _has_ to have M_EXT set; if it is just a regular
* mbuf, it is still not considered "writable."
* (ii) since mbuf has M_EXT, the ext_type _has_ to be
* EXT_CLUSTER. Anything else makes it non-writable.
* (iii) M_WRITABLE() must evaluate true.
* Ideally, the requirement should only be (iii).
*
* If we're writable, we're sure we're writable, because the ref. count
* cannot increase from 1, as that would require posession of mbuf
* n by someone else (which is impossible). However, if we're _not_
* writable, we may eventually become writable )if the ref. count drops
* to 1), but we'll fail to notice it unless we re-evaluate
* M_WRITABLE(). For now, we only evaluate once at the beginning and
* live with this.
*/
/*
* XXX: This is dumb. If we're just a regular mbuf with no M_EXT,
* then we're not "writable," according to this code.
*/
writable = 0;
if ((n->m_flags & M_EXT) && (n->m_ext.ext_type == EXT_CLUSTER) &&
M_WRITABLE(n))
writable = 1;
if ((off == 0 || offp) && M_TRAILINGSPACE(n) >= tlen
&& writable) {
m_copydata(n->m_next, 0, tlen, mtod(n, caddr_t) + n->m_len);
@ -225,18 +228,17 @@ m_pulldown(struct mbuf *m, int off, int len, int *offp)
* on both end.
*/
MGET(o, M_DONTWAIT, m->m_type);
if (o == NULL) {
m_freem(m);
return NULL; /* ENOBUFS */
}
if (len > MHLEN) { /* use MHLEN just for safety */
if (o && len > MLEN) {
MCLGET(o, M_DONTWAIT);
if ((o->m_flags & M_EXT) == 0) {
m_freem(m);
m_free(o);
return NULL; /* ENOBUFS */
o = NULL;
}
}
if (!o) {
m_freem(m);
return NULL; /* ENOBUFS */
}
/* get hlen from <n, off> into <o, 0> */
o->m_len = hlen;
bcopy(mtod(n, caddr_t) + off, mtod(o, caddr_t), hlen);
@ -265,12 +267,46 @@ m_pulldown(struct mbuf *m, int off, int len, int *offp)
return n;
}
static struct mbuf *
m_dup1(struct mbuf *m, int off, int len, int wait)
{
struct mbuf *n;
int l;
int copyhdr;
if (len > MCLBYTES)
return NULL;
if (off == 0 && (m->m_flags & M_PKTHDR) != 0) {
copyhdr = 1;
MGETHDR(n, wait, m->m_type);
l = MHLEN;
} else {
copyhdr = 0;
MGET(n, wait, m->m_type);
l = MLEN;
}
if (n && len > l) {
MCLGET(n, wait);
if ((n->m_flags & M_EXT) == 0) {
m_free(n);
n = NULL;
}
}
if (!n)
return NULL;
if (copyhdr)
M_COPY_PKTHDR(n, m);
m_copydata(m, off, len, mtod(n, caddr_t));
return n;
}
/*
* pkthdr.aux chain manipulation.
* we don't allow clusters at this moment.
*/
struct mbuf *
m_aux_add(struct mbuf *m, int af, int type)
m_aux_add2(struct mbuf *m, int af, int type, void *p)
{
struct mbuf *n;
struct mauxtag *t;
@ -287,8 +323,10 @@ m_aux_add(struct mbuf *m, int af, int type)
return NULL;
t = mtod(n, struct mauxtag *);
bzero(t, sizeof(*t));
t->af = af;
t->type = type;
t->p = p;
n->m_data += sizeof(struct mauxtag);
n->m_len = 0;
n->m_next = m->m_pkthdr.aux;
@ -297,7 +335,7 @@ m_aux_add(struct mbuf *m, int af, int type)
}
struct mbuf *
m_aux_find(struct mbuf *m, int af, int type)
m_aux_find2(struct mbuf *m, int af, int type, void *p)
{
struct mbuf *n;
struct mauxtag *t;
@ -307,12 +345,30 @@ m_aux_find(struct mbuf *m, int af, int type)
for (n = m->m_pkthdr.aux; n; n = n->m_next) {
t = (struct mauxtag *)n->m_dat;
if (t->af == af && t->type == type)
if (n->m_data != ((caddr_t)t) + sizeof(struct mauxtag)) {
printf("m_aux_find: invalid m_data for mbuf=%p (%p %p)\n", n, t, n->m_data);
continue;
}
if (t->af == af && t->type == type && t->p == p)
return n;
}
return NULL;
}
struct mbuf *
m_aux_find(struct mbuf *m, int af, int type)
{
return m_aux_find2(m, af, type, NULL);
}
struct mbuf *
m_aux_add(struct mbuf *m, int af, int type)
{
return m_aux_add2(m, af, type, NULL);
}
void
m_aux_delete(struct mbuf *m, struct mbuf *victim)
{
@ -327,6 +383,12 @@ m_aux_delete(struct mbuf *m, struct mbuf *victim)
while (n) {
t = (struct mauxtag *)n->m_dat;
next = n->m_next;
if (n->m_data != ((caddr_t)t) + sizeof(struct mauxtag)) {
printf("m_aux_delete: invalid m_data for mbuf=%p (%p %p)\n", n, t, n->m_data);
prev = n;
n = next;
continue;
}
if (n == victim) {
if (prev)
prev->m_next = n->m_next;

View file

@ -269,7 +269,7 @@ if_detach(ifp)
#endif /* INET */
#ifdef INET6
if (ifa->ifa_addr && ifa->ifa_addr->sa_family == AF_INET6) {
in6_purgeaddr(ifa, ifp);
in6_purgeaddr(ifa);
/* ifp_addrhead is already updated */
continue;
}
@ -278,6 +278,16 @@ if_detach(ifp)
IFAFREE(ifa);
}
#ifdef INET6
/*
* Remove all IPv6 kernel structs related to ifp. This should be done
* before removing routing entries below, since IPv6 interface direct
* routes are expected to be removed by the IPv6-specific kernel API.
* Otherwise, the kernel will detect some inconsistency and bark it.
*/
in6_ifdetach(ifp);
#endif
/*
* Delete all remaining routes using this interface
* Unfortuneatly the only way to do this is to slog through
@ -290,11 +300,6 @@ if_detach(ifp)
(void) rnh->rnh_walktree(rnh, if_rtdel, ifp);
}
#ifdef INET6
/* nuke all IPv6 kernel structs related to ifp */
in6_ifdetach(ifp);
#endif
TAILQ_REMOVE(&ifnet, ifp, if_link);
mtx_destroy(&ifp->if_snd.ifq_mtx);
splx(s);
@ -897,6 +902,7 @@ ifioctl(so, cmd, data, p)
#ifdef INET6
case SIOCSIFPHYADDR_IN6:
#endif
case SIOCSLIFPHYADDR:
case SIOCSIFMEDIA:
case SIOCSIFGENERIC:
error = suser(p);
@ -913,6 +919,9 @@ ifioctl(so, cmd, data, p)
ifs = (struct ifstat *)data;
ifs->ascii[0] = '\0';
case SIOCGIFPSRCADDR:
case SIOCGIFPDSTADDR:
case SIOCGLIFPHYADDR:
case SIOCGIFMEDIA:
case SIOCGIFGENERIC:
if (ifp->if_ioctl == 0)

View file

@ -1,3 +1,5 @@
/* $KAME: if_faith.c,v 1.21 2001/02/20 07:59:26 itojun Exp $ */
/*
* Copyright (c) 1982, 1986, 1993
* The Regents of the University of California. All rights reserved.
@ -41,30 +43,58 @@
/*
* Loopback interface driver for protocol testing and timing.
*/
#include "opt_inet.h"
#include "opt_inet6.h"
#include "faith.h"
#if NFAITH > 0
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <sys/errno.h>
#include <sys/sockio.h>
#include <sys/time.h>
#include <sys/queue.h>
#include <net/if.h>
#include <net/if_types.h>
#include <net/netisr.h>
#include <net/route.h>
#include <net/bpf.h>
#include <net/if_faith.h>
#ifdef INET
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/in_var.h>
#include <netinet/ip.h>
#endif
#ifdef INET6
#ifndef INET
#include <netinet/in.h>
#endif
#include <netinet6/in6_var.h>
#include <netinet/ip6.h>
#include <netinet6/ip6_var.h>
#endif
#include "bpf.h"
#define NBPFILTER NBPF
#include <net/net_osdep.h>
extern int loioctl __P((struct ifnet *, u_long, caddr_t));
extern int looutput __P((struct ifnet *ifp,
struct mbuf *m, struct sockaddr *dst, struct rtentry *rt));
static int faithioctl __P((struct ifnet *, u_long, caddr_t));
int faithoutput __P((struct ifnet *, struct mbuf *, struct sockaddr *,
struct rtentry *));
static void faithrtrequest __P((int, struct rtentry *, struct sockaddr *));
void faithattach __P((void *));
PSEUDO_SET(faithattach, if_faith);
static struct ifnet faithif[NFAITH];
#define FAITHMTU 1500
@ -74,8 +104,8 @@ void
faithattach(faith)
void *faith;
{
register struct ifnet *ifp;
register int i;
struct ifnet *ifp;
int i;
for (i = 0; i < NFAITH; i++) {
ifp = &faithif[i];
@ -85,13 +115,210 @@ faithattach(faith)
ifp->if_mtu = FAITHMTU;
/* LOOPBACK commented out to announce IPv6 routes to faith */
ifp->if_flags = /* IFF_LOOPBACK | */ IFF_MULTICAST;
ifp->if_ioctl = loioctl;
ifp->if_output = looutput;
ifp->if_ioctl = faithioctl;
ifp->if_output = faithoutput;
ifp->if_type = IFT_FAITH;
ifp->if_snd.ifq_maxlen = ifqmaxlen;
ifp->if_hdrlen = 0;
ifp->if_addrlen = 0;
if_attach(ifp);
#if NBPFILTER > 0
#ifdef HAVE_OLD_BPF
bpfattach(ifp, DLT_NULL, sizeof(u_int));
#else
bpfattach(&ifp->if_bpf, ifp, DLT_NULL, sizeof(u_int));
#endif
#endif
}
}
int
faithoutput(ifp, m, dst, rt)
struct ifnet *ifp;
struct mbuf *m;
struct sockaddr *dst;
struct rtentry *rt;
{
int isr;
struct ifqueue *ifq = 0;
if ((m->m_flags & M_PKTHDR) == 0)
panic("faithoutput no HDR");
#if NBPFILTER > 0
/* BPF write needs to be handled specially */
if (dst->sa_family == AF_UNSPEC) {
dst->sa_family = *(mtod(m, int *));
m->m_len -= sizeof(int);
m->m_pkthdr.len -= sizeof(int);
m->m_data += sizeof(int);
}
if (ifp->if_bpf) {
/*
* We need to prepend the address family as
* a four byte field. Cons up a faith header
* to pacify bpf. This is safe because bpf
* will only read from the mbuf (i.e., it won't
* try to free it or keep a pointer a to it).
*/
struct mbuf m0;
u_int32_t af = dst->sa_family;
m0.m_next = m;
m0.m_len = 4;
m0.m_data = (char *)&af;
#ifdef HAVE_OLD_BPF
bpf_mtap(ifp, &m0);
#else
bpf_mtap(ifp->if_bpf, &m0);
#endif
}
#endif
if (rt && rt->rt_flags & (RTF_REJECT|RTF_BLACKHOLE)) {
m_freem(m);
return (rt->rt_flags & RTF_BLACKHOLE ? 0 :
rt->rt_flags & RTF_HOST ? EHOSTUNREACH : ENETUNREACH);
}
ifp->if_opackets++;
ifp->if_obytes += m->m_pkthdr.len;
switch (dst->sa_family) {
#ifdef INET
case AF_INET:
ifq = &ipintrq;
isr = NETISR_IP;
break;
#endif
#ifdef INET6
case AF_INET6:
ifq = &ip6intrq;
isr = NETISR_IPV6;
break;
#endif
default:
m_freem(m);
return EAFNOSUPPORT;
}
/* XXX do we need more sanity checks? */
m->m_pkthdr.rcvif = ifp;
ifp->if_ipackets++;
ifp->if_ibytes += m->m_pkthdr.len;
(void) IF_HANDOFF(ifq, m, NULL);
schednetisr(isr);
return (0);
}
/* ARGSUSED */
static void
faithrtrequest(cmd, rt, sa)
int cmd;
struct rtentry *rt;
struct sockaddr *sa;
{
if (rt) {
rt->rt_rmx.rmx_mtu = rt->rt_ifp->if_mtu; /* for ISO */
/*
* For optimal performance, the send and receive buffers
* should be at least twice the MTU plus a little more for
* overhead.
*/
rt->rt_rmx.rmx_recvpipe =
rt->rt_rmx.rmx_sendpipe = 3 * FAITHMTU;
}
}
/*
* Process an ioctl request.
*/
/* ARGSUSED */
static int
faithioctl(ifp, cmd, data)
struct ifnet *ifp;
u_long cmd;
caddr_t data;
{
struct ifaddr *ifa;
struct ifreq *ifr = (struct ifreq *)data;
int error = 0;
switch (cmd) {
case SIOCSIFADDR:
ifp->if_flags |= IFF_UP | IFF_RUNNING;
ifa = (struct ifaddr *)data;
ifa->ifa_rtrequest = faithrtrequest;
/*
* Everything else is done at a higher level.
*/
break;
case SIOCADDMULTI:
case SIOCDELMULTI:
if (ifr == 0) {
error = EAFNOSUPPORT; /* XXX */
break;
}
switch (ifr->ifr_addr.sa_family) {
#ifdef INET
case AF_INET:
break;
#endif
#ifdef INET6
case AF_INET6:
break;
#endif
default:
error = EAFNOSUPPORT;
break;
}
break;
#ifdef SIOCSIFMTU
case SIOCSIFMTU:
ifp->if_mtu = ifr->ifr_mtu;
break;
#endif
case SIOCSIFFLAGS:
break;
default:
error = EINVAL;
}
return (error);
}
/*
* XXX could be slow
* XXX could be layer violation to call sys/net from sys/netinet6
*/
int
faithprefix(in6)
struct in6_addr *in6;
{
struct rtentry *rt;
struct sockaddr_in6 sin6;
int ret;
if (ip6_keepfaith == 0)
return 0;
bzero(&sin6, sizeof(sin6));
sin6.sin6_family = AF_INET6;
sin6.sin6_len = sizeof(struct sockaddr_in6);
sin6.sin6_addr = *in6;
rt = rtalloc1((struct sockaddr *)&sin6, 0, 0UL);
if (rt && rt->rt_ifp && rt->rt_ifp->if_type == IFT_FAITH &&
(rt->rt_ifp->if_flags & IFF_UP) != 0)
ret = 1;
else
ret = 0;
if (rt)
RTFREE(rt);
return ret;
}
#endif /* NFAITH > 0 */

41
sys/net/if_faith.h Normal file
View file

@ -0,0 +1,41 @@
/* $FreeBSD$ */
/* $KAME: if_faith.h,v 1.1 2000/07/26 05:49:21 itojun Exp $ */
/*
* Copyright (C) 2000 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.
*/
#ifndef _NET_IF_FAITH_H_
#define _NET_IF_FAITH_H_
#ifdef _KERNEL
struct in6_addr;
int faithprefix __P((struct in6_addr *));
#endif
#endif /* _NET_IF_FAITH_H_ */

View file

@ -1,5 +1,5 @@
/* $FreeBSD$ */
/* $KAME: if_gif.c,v 1.28 2000/06/20 12:30:03 jinmei Exp $ */
/* $KAME: if_gif.c,v 1.47 2001/05/01 05:28:42 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -52,11 +52,11 @@
#include <net/route.h>
#include <net/bpf.h>
#ifdef INET
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/in_var.h>
#include <netinet/ip.h>
#ifdef INET
#include <netinet/in_var.h>
#include <netinet/in_gif.h>
#endif /* INET */
@ -114,11 +114,11 @@ void
gifattach(dummy)
void *dummy;
{
register struct gif_softc *sc;
register int i;
struct gif_softc *sc;
int i;
ngif = NGIF;
gif = sc = malloc (ngif * sizeof(struct gif_softc), M_DEVBUF, M_WAITOK);
gif = sc = malloc(ngif * sizeof(struct gif_softc), M_DEVBUF, M_WAITOK);
bzero(sc, ngif * sizeof(struct gif_softc));
for (i = 0; i < ngif; sc++, i++) {
sc->gif_if.if_name = "gif";
@ -148,6 +148,10 @@ gifattach(dummy)
sc->gif_if.if_mtu = GIF_MTU;
sc->gif_if.if_flags = IFF_POINTOPOINT | IFF_MULTICAST;
#if 0
/* turn off ingress filter */
sc->gif_if.if_flags |= IFF_LINK2;
#endif
sc->gif_if.if_ioctl = gif_ioctl;
sc->gif_if.if_output = gif_output;
sc->gif_if.if_type = IFT_GIF;
@ -229,7 +233,7 @@ gif_output(ifp, m, dst, rt)
struct sockaddr *dst;
struct rtentry *rt; /* added in net2 */
{
register struct gif_softc *sc = (struct gif_softc*)ifp;
struct gif_softc *sc = (struct gif_softc*)ifp;
int error = 0;
static int called = 0; /* XXX: MUTEX */
@ -268,7 +272,7 @@ gif_output(ifp, m, dst, rt)
* try to free it or keep a pointer a to it).
*/
struct mbuf m0;
u_int af = dst->sa_family;
u_int32_t af = dst->sa_family;
m0.m_next = m;
m0.m_len = 4;
@ -284,8 +288,11 @@ gif_output(ifp, m, dst, rt)
ifp->if_opackets++;
ifp->if_obytes += m->m_pkthdr.len;
/* inner AF-specific encapsulation */
/* XXX should we check if our outer source is legal? */
/* dispatch to output logic based on outer AF */
switch (sc->gif_psrc->sa_family) {
#ifdef INET
case AF_INET:
@ -300,11 +307,13 @@ gif_output(ifp, m, dst, rt)
default:
m_freem(m);
error = ENETDOWN;
goto end;
}
end:
called = 0; /* reset recursion counter */
if (error) ifp->if_oerrors++;
if (error)
ifp->if_oerrors++;
return error;
}
@ -315,7 +324,7 @@ gif_input(m, af, gifp)
struct ifnet *gifp;
{
int isr;
register struct ifqueue *ifq = 0;
struct ifqueue *ifq = 0;
if (gifp == NULL) {
/* just in case */
@ -335,11 +344,11 @@ gif_input(m, af, gifp)
* try to free it or keep a pointer a to it).
*/
struct mbuf m0;
u_int af = AF_INET6;
u_int32_t af1 = af;
m0.m_next = m;
m0.m_len = 4;
m0.m_data = (char *)&af;
m0.m_data = (char *)&af1;
#ifdef HAVE_OLD_BPF
bpf_mtap(gifp, &m0);
@ -435,13 +444,16 @@ gif_ioctl(ifp, cmd, data)
#ifdef INET6
case SIOCSIFPHYADDR_IN6:
#endif /* INET6 */
case SIOCSLIFPHYADDR:
switch (cmd) {
#ifdef INET
case SIOCSIFPHYADDR:
src = (struct sockaddr *)
&(((struct in_aliasreq *)data)->ifra_addr);
dst = (struct sockaddr *)
&(((struct in_aliasreq *)data)->ifra_dstaddr);
break;
#endif
#ifdef INET6
case SIOCSIFPHYADDR_IN6:
src = (struct sockaddr *)
@ -450,6 +462,66 @@ gif_ioctl(ifp, cmd, data)
&(((struct in6_aliasreq *)data)->ifra_dstaddr);
break;
#endif
case SIOCSLIFPHYADDR:
src = (struct sockaddr *)
&(((struct if_laddrreq *)data)->addr);
dst = (struct sockaddr *)
&(((struct if_laddrreq *)data)->dstaddr);
}
/* sa_family must be equal */
if (src->sa_family != dst->sa_family)
return EINVAL;
/* validate sa_len */
switch (src->sa_family) {
#ifdef INET
case AF_INET:
if (src->sa_len != sizeof(struct sockaddr_in))
return EINVAL;
break;
#endif
#ifdef INET6
case AF_INET6:
if (src->sa_len != sizeof(struct sockaddr_in6))
return EINVAL;
break;
#endif
default:
return EAFNOSUPPORT;
}
switch (dst->sa_family) {
#ifdef INET
case AF_INET:
if (dst->sa_len != sizeof(struct sockaddr_in))
return EINVAL;
break;
#endif
#ifdef INET6
case AF_INET6:
if (dst->sa_len != sizeof(struct sockaddr_in6))
return EINVAL;
break;
#endif
default:
return EAFNOSUPPORT;
}
/* check sa_family looks sane for the cmd */
switch (cmd) {
case SIOCSIFPHYADDR:
if (src->sa_family == AF_INET)
break;
return EAFNOSUPPORT;
#ifdef INET6
case SIOCSIFPHYADDR_IN6:
if (src->sa_family == AF_INET6)
break;
return EAFNOSUPPORT;
#endif /* INET6 */
case SIOCSLIFPHYADDR:
/* checks done in the above */
break;
}
for (i = 0; i < ngif; i++) {
@ -493,41 +565,16 @@ gif_ioctl(ifp, cmd, data)
#endif
}
if (src->sa_family != dst->sa_family ||
src->sa_len != dst->sa_len) {
error = EINVAL;
break;
}
switch (src->sa_family) {
#ifdef INET
case AF_INET:
size = sizeof(struct sockaddr_in);
break;
#endif
#ifdef INET6
case AF_INET6:
size = sizeof(struct sockaddr_in6);
break;
#endif
default:
error = EAFNOSUPPORT;
goto bad;
}
if (src->sa_len != size) {
error = EINVAL;
break;
}
if (sc->gif_psrc)
free((caddr_t)sc->gif_psrc, M_IFADDR);
sa = (struct sockaddr *)malloc(size, M_IFADDR, M_WAITOK);
bcopy((caddr_t)src, (caddr_t)sa, size);
sa = (struct sockaddr *)malloc(src->sa_len, M_IFADDR, M_WAITOK);
bcopy((caddr_t)src, (caddr_t)sa, src->sa_len);
sc->gif_psrc = sa;
if (sc->gif_pdst)
free((caddr_t)sc->gif_pdst, M_IFADDR);
sa = (struct sockaddr *)malloc(size, M_IFADDR, M_WAITOK);
bcopy((caddr_t)dst, (caddr_t)sa, size);
sa = (struct sockaddr *)malloc(dst->sa_len, M_IFADDR, M_WAITOK);
bcopy((caddr_t)dst, (caddr_t)sa, dst->sa_len);
sc->gif_pdst = sa;
ifp->if_flags |= IFF_RUNNING;
@ -548,7 +595,7 @@ gif_ioctl(ifp, cmd, data)
free((caddr_t)sc->gif_pdst, M_IFADDR);
sc->gif_pdst = NULL;
}
/* change the IFF_UP flag as well? */
/* change the IFF_{UP, RUNNING} flag as well? */
break;
#endif
@ -561,25 +608,27 @@ gif_ioctl(ifp, cmd, data)
goto bad;
}
src = sc->gif_psrc;
switch (sc->gif_psrc->sa_family) {
switch (cmd) {
#ifdef INET
case AF_INET:
case SIOCGIFPSRCADDR:
dst = &ifr->ifr_addr;
size = sizeof(struct sockaddr_in);
size = sizeof(ifr->ifr_addr);
break;
#endif /* INET */
#ifdef INET6
case AF_INET6:
case SIOCGIFPSRCADDR_IN6:
dst = (struct sockaddr *)
&(((struct in6_ifreq *)data)->ifr_addr);
size = sizeof(struct sockaddr_in6);
size = sizeof(((struct in6_ifreq *)data)->ifr_addr);
break;
#endif /* INET6 */
default:
error = EADDRNOTAVAIL;
goto bad;
}
bcopy((caddr_t)src, (caddr_t)dst, size);
if (src->sa_len > size)
return EINVAL;
bcopy((caddr_t)src, (caddr_t)dst, src->sa_len);
break;
case SIOCGIFPDSTADDR:
@ -591,25 +640,52 @@ gif_ioctl(ifp, cmd, data)
goto bad;
}
src = sc->gif_pdst;
switch (sc->gif_pdst->sa_family) {
switch (cmd) {
#ifdef INET
case AF_INET:
case SIOCGIFPDSTADDR:
dst = &ifr->ifr_addr;
size = sizeof(struct sockaddr_in);
size = sizeof(ifr->ifr_addr);
break;
#endif /* INET */
#ifdef INET6
case AF_INET6:
case SIOCGIFPDSTADDR_IN6:
dst = (struct sockaddr *)
&(((struct in6_ifreq *)data)->ifr_addr);
size = sizeof(struct sockaddr_in6);
size = sizeof(((struct in6_ifreq *)data)->ifr_addr);
break;
#endif /* INET6 */
default:
error = EADDRNOTAVAIL;
goto bad;
}
bcopy((caddr_t)src, (caddr_t)dst, size);
if (src->sa_len > size)
return EINVAL;
bcopy((caddr_t)src, (caddr_t)dst, src->sa_len);
break;
case SIOCGLIFPHYADDR:
if (sc->gif_psrc == NULL || sc->gif_pdst == NULL) {
error = EADDRNOTAVAIL;
goto bad;
}
/* copy src */
src = sc->gif_psrc;
dst = (struct sockaddr *)
&(((struct if_laddrreq *)data)->addr);
size = sizeof(((struct if_laddrreq *)data)->addr);
if (src->sa_len > size)
return EINVAL;
bcopy((caddr_t)src, (caddr_t)dst, src->sa_len);
/* copy dst */
src = sc->gif_pdst;
dst = (struct sockaddr *)
&(((struct if_laddrreq *)data)->dstaddr);
size = sizeof(((struct if_laddrreq *)data)->dstaddr);
if (src->sa_len > size)
return EINVAL;
bcopy((caddr_t)src, (caddr_t)dst, src->sa_len);
break;
case SIOCSIFFLAGS:

View file

@ -1,5 +1,5 @@
/* $FreeBSD$ */
/* $KAME: if_gif.h,v 1.13 2000/06/17 20:34:24 itojun Exp $ */
/* $KAME: if_gif.h,v 1.17 2000/09/11 11:36:41 sumikawa Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -38,11 +38,9 @@
#define _NET_IF_GIF_H_
#if (defined(__FreeBSD__) && __FreeBSD__ >= 3) || defined(__NetBSD__)
#if defined(_KERNEL) && !defined(_LKM)
#include "opt_inet.h"
#endif
#endif
#include <netinet/in.h>
/* xxx sigh, why route have struct route instead of pointer? */

View file

@ -58,6 +58,7 @@
#include <net/netisr.h>
#include <net/route.h>
#include <net/bpf.h>
#include <net/bpfdesc.h>
#ifdef INET
#include <netinet/in.h>
@ -236,6 +237,8 @@ looutput(ifp, m, dst, rt)
m_copydata(m, 0, m->m_pkthdr.len, mtod(n, caddr_t));
n->m_pkthdr = m->m_pkthdr;
n->m_len = m->m_pkthdr.len;
n->m_pkthdr.aux = m->m_pkthdr.aux;
m->m_pkthdr.aux = (struct mbuf *)NULL;
m_freem(m);
m = n;
}
@ -277,7 +280,7 @@ looutput(ifp, m, dst, rt)
int
if_simloop(ifp, m, af, hlen)
struct ifnet *ifp;
register struct mbuf *m;
struct mbuf *m;
int af;
int hlen;
{
@ -300,17 +303,19 @@ if_simloop(ifp, m, af, hlen)
if (ifp->if_bpf) {
struct mbuf m0, *n = m;
/*
* We need to prepend the address family as
* a four byte field. Cons up a dummy header
* to pacify bpf. This is safe because bpf
* will only read from the mbuf (i.e., it won't
* try to free it or keep a pointer a to it).
*/
m0.m_next = m;
m0.m_len = 4;
m0.m_data = (char *)&af;
n = &m0;
if (ifp->if_bpf->bif_dlt == DLT_NULL) {
/*
* We need to prepend the address family as
* a four byte field. Cons up a dummy header
* to pacify bpf. This is safe because bpf
* will only read from the mbuf (i.e., it won't
* try to free it or keep a pointer a to it).
*/
m0.m_next = m;
m0.m_len = 4;
m0.m_data = (char *)&af;
n = &m0;
}
bpf_mtap(ifp, n);
}

View file

@ -39,6 +39,7 @@ struct slcp {
};
#define IDX_IPCP 1 /* idx into state table */
#define IDX_IPV6CP 2 /* idx into state table */
struct sipcp {
u_long opts; /* IPCP options to send (bitfield) */
@ -46,6 +47,10 @@ struct sipcp {
#define IPCP_HISADDR_SEEN 1 /* have seen his address already */
#define IPCP_MYADDR_DYN 2 /* my address is dynamically assigned */
#define IPCP_MYADDR_SEEN 4 /* have seen his address already */
#ifdef notdef
#define IPV6CP_MYIFID_DYN 2 /* my ifid is dynamically assigned */
#endif
#define IPV6CP_MYIFID_SEEN 4 /* have seen his ifid already */
};
#define AUTHNAMELEN 32
@ -62,8 +67,8 @@ struct sauth {
u_char challenge[AUTHKEYLEN]; /* random challenge */
};
#define IDX_PAP 2
#define IDX_CHAP 3
#define IDX_PAP 3
#define IDX_CHAP 4
#define IDX_COUNT (IDX_CHAP + 1) /* bump this when adding cp's! */
@ -87,8 +92,8 @@ struct sppp {
u_int pp_flags; /* sub modes */
u_short pp_alivecnt; /* keepalive packets counter */
u_short pp_loopcnt; /* loopback detection counter */
u_long pp_seq; /* local sequence number */
u_long pp_rseq; /* remote sequence number */
u_long pp_seq[IDX_COUNT]; /* local sequence number */
u_long pp_rseq[IDX_COUNT]; /* remote sequence number */
enum ppp_phase pp_phase; /* phase we're currently in */
int state[IDX_COUNT]; /* state machine */
u_char confid[IDX_COUNT]; /* id of last configuration request */
@ -98,6 +103,7 @@ struct sppp {
struct callout_handle pap_my_to_ch; /* PAP needs one more... */
struct slcp lcp; /* LCP params */
struct sipcp ipcp; /* IPCP params */
struct sipcp ipv6cp; /* IPv6CP params */
struct sauth myauth; /* auth params, i'm peer */
struct sauth hisauth; /* auth params, i'm authenticator */
/*

View file

@ -135,10 +135,12 @@
#define PPP_ISO 0x0023 /* ISO OSI Protocol */
#define PPP_XNS 0x0025 /* Xerox NS Protocol */
#define PPP_IPX 0x002b /* Novell IPX Protocol */
#define PPP_IPV6 0x0057 /* Internet Protocol Version 6 */
#define PPP_LCP 0xc021 /* Link Control Protocol */
#define PPP_PAP 0xc023 /* Password Authentication Protocol */
#define PPP_CHAP 0xc223 /* Challenge-Handshake Auth Protocol */
#define PPP_IPCP 0x8021 /* Internet Protocol Control Protocol */
#define PPP_IPV6CP 0x8057 /* IPv6 Control Protocol */
#define CONF_REQ 1 /* PPP configure request */
#define CONF_ACK 2 /* PPP configure acknowledge */
@ -165,6 +167,9 @@
#define IPCP_OPT_COMPRESSION 2 /* IP compression protocol (VJ) */
#define IPCP_OPT_ADDRESS 3 /* local IP address */
#define IPV6CP_OPT_IFID 1 /* interface identifier */
#define IPV6CP_OPT_COMPRESSION 2 /* IPv6 compression protocol */
#define PAP_REQ 1 /* PAP name/password request */
#define PAP_ACK 2 /* PAP acknowledge */
#define PAP_NAK 3 /* PAP fail */
@ -340,6 +345,21 @@ static void sppp_ipcp_tls(struct sppp *sp);
static void sppp_ipcp_tlf(struct sppp *sp);
static void sppp_ipcp_scr(struct sppp *sp);
static void sppp_ipv6cp_init(struct sppp *sp);
static void sppp_ipv6cp_up(struct sppp *sp);
static void sppp_ipv6cp_down(struct sppp *sp);
static void sppp_ipv6cp_open(struct sppp *sp);
static void sppp_ipv6cp_close(struct sppp *sp);
static void sppp_ipv6cp_TO(void *sp);
static int sppp_ipv6cp_RCR(struct sppp *sp, struct lcp_header *h, int len);
static void sppp_ipv6cp_RCN_rej(struct sppp *sp, struct lcp_header *h, int len);
static void sppp_ipv6cp_RCN_nak(struct sppp *sp, struct lcp_header *h, int len);
static void sppp_ipv6cp_tlu(struct sppp *sp);
static void sppp_ipv6cp_tld(struct sppp *sp);
static void sppp_ipv6cp_tls(struct sppp *sp);
static void sppp_ipv6cp_tlf(struct sppp *sp);
static void sppp_ipv6cp_scr(struct sppp *sp);
static void sppp_pap_input(struct sppp *sp, struct mbuf *m);
static void sppp_pap_init(struct sppp *sp);
static void sppp_pap_open(struct sppp *sp);
@ -363,6 +383,9 @@ static const char *sppp_auth_type_name(u_short proto, u_char type);
static const char *sppp_cp_type_name(u_char type);
static const char *sppp_dotted_quad(u_long addr);
static const char *sppp_ipcp_opt_name(u_char opt);
#ifdef INET6
static const char *sppp_ipv6cp_opt_name(u_char opt);
#endif
static const char *sppp_lcp_opt_name(u_char opt);
static const char *sppp_phase_name(enum ppp_phase phase);
static const char *sppp_proto_name(u_short proto);
@ -377,6 +400,15 @@ static void sppp_print_bytes(const u_char *p, u_short len);
static void sppp_print_string(const char *p, u_short len);
static void sppp_qflush(struct ifqueue *ifq);
static void sppp_set_ip_addr(struct sppp *sp, u_long src);
#ifdef INET6
static void sppp_get_ip6_addrs(struct sppp *sp, struct in6_addr *src,
struct in6_addr *dst, struct in6_addr *srcmask);
#ifdef IPV6CP_MYIFID_DYN
static void sppp_set_ip6_addr(struct sppp *sp, const struct in6_addr *src);
static void sppp_gen_ip6_addr(struct sppp *sp, const struct in6_addr *src);
#endif
static void sppp_suggest_ip6_addr(struct sppp *sp, struct in6_addr *src);
#endif
/* our control protocol descriptors */
static const struct cp lcp = {
@ -395,6 +427,20 @@ static const struct cp ipcp = {
sppp_ipcp_scr
};
static const struct cp ipv6cp = {
PPP_IPV6CP, IDX_IPV6CP,
#ifdef INET6 /*don't run IPv6CP if there's no IPv6 support*/
CP_NCP,
#else
0,
#endif
"ipv6cp",
sppp_ipv6cp_up, sppp_ipv6cp_down, sppp_ipv6cp_open, sppp_ipv6cp_close,
sppp_ipv6cp_TO, sppp_ipv6cp_RCR, sppp_ipv6cp_RCN_rej, sppp_ipv6cp_RCN_nak,
sppp_ipv6cp_tlu, sppp_ipv6cp_tld, sppp_ipv6cp_tls, sppp_ipv6cp_tlf,
sppp_ipv6cp_scr
};
static const struct cp pap = {
PPP_PAP, IDX_PAP, CP_AUTH, "pap",
sppp_null, sppp_null, sppp_pap_open, sppp_pap_close,
@ -414,6 +460,7 @@ static const struct cp chap = {
static const struct cp *cps[IDX_COUNT] = {
&lcp, /* IDX_LCP */
&ipcp, /* IDX_IPCP */
&ipv6cp, /* IDX_IPV6CP */
&pap, /* IDX_PAP */
&chap, /* IDX_CHAP */
};
@ -499,7 +546,7 @@ sppp_input(struct ifnet *ifp, struct mbuf *m)
h->address, h->control, ntohs(h->protocol));
if (sp->state[IDX_LCP] == STATE_OPENED)
sppp_cp_send (sp, PPP_LCP, PROTO_REJ,
++sp->pp_seq, m->m_pkthdr.len + 2,
++sp->pp_seq[IDX_LCP], m->m_pkthdr.len + 2,
&h->protocol);
++ifp->if_noproto;
goto drop;
@ -530,6 +577,20 @@ sppp_input(struct ifnet *ifp, struct mbuf *m)
}
break;
#endif
#ifdef INET6
case PPP_IPV6CP:
if (sp->pp_phase == PHASE_NETWORK)
sppp_cp_input(&ipv6cp, sp, m);
m_freem (m);
return;
case PPP_IPV6:
if (sp->state[IDX_IPV6CP] == STATE_OPENED) {
schednetisr (NETISR_IPV6);
inq = &ip6intrq;
}
break;
#endif
#ifdef IPX
case PPP_IPX:
/* IPX IPXCP not implemented yet */
@ -628,7 +689,7 @@ sppp_output(struct ifnet *ifp, struct mbuf *m,
{
struct sppp *sp = (struct sppp*) ifp;
struct ppp_header *h;
struct ifqueue *ifq;
struct ifqueue *ifq = NULL;
int s, rv = 0;
int debug = ifp->if_flags & IFF_DEBUG;
@ -652,7 +713,6 @@ sppp_output(struct ifnet *ifp, struct mbuf *m,
s = splimp();
}
ifq = &ifp->if_snd;
#ifdef INET
if (dst->sa_family == AF_INET) {
/* XXX Check mbuf length here? */
@ -699,6 +759,12 @@ sppp_output(struct ifnet *ifp, struct mbuf *m,
}
#endif
#ifdef INET6
if (dst->sa_family == AF_INET6) {
/* XXX do something tricky here? */
}
#endif
/*
* Prepend general data packet PPP header. For now, IP only.
*/
@ -750,7 +816,18 @@ sppp_output(struct ifnet *ifp, struct mbuf *m,
if (sp->pp_mode == IFF_CISCO)
h->protocol = htons (ETHERTYPE_IPV6);
else {
goto nosupport;
/*
* Don't choke with an ENETDOWN early. It's
* possible that we just started dialing out,
* so don't drop the packet immediately. If
* we notice that we run out of buffer space
* below, we will however remember that we are
* not ready to carry IP packets, and return
* ENETDOWN, as opposed to ENOBUFS.
*/
h->protocol = htons(PPP_IPV6);
if (sp->state[IDX_IPV6CP] != STATE_OPENED)
rv = ENETDOWN;
}
break;
#endif
@ -812,8 +889,8 @@ sppp_attach(struct ifnet *ifp)
sp->pp_cpq.ifq_maxlen = 20;
sp->pp_loopcnt = 0;
sp->pp_alivecnt = 0;
sp->pp_seq = 0;
sp->pp_rseq = 0;
bzero(&sp->pp_seq[0], sizeof(sp->pp_seq));
bzero(&sp->pp_rseq[0], sizeof(sp->pp_rseq));
sp->pp_phase = PHASE_DEAD;
sp->pp_up = lcp.Up;
sp->pp_down = lcp.Down;
@ -822,6 +899,7 @@ sppp_attach(struct ifnet *ifp)
sppp_lcp_init(sp);
sppp_ipcp_init(sp);
sppp_ipv6cp_init(sp);
sppp_pap_init(sp);
sppp_chap_init(sp);
}
@ -1079,8 +1157,8 @@ sppp_cisco_input(struct sppp *sp, struct mbuf *m)
break;
case CISCO_KEEPALIVE_REQ:
sp->pp_alivecnt = 0;
sp->pp_rseq = ntohl (h->par1);
if (sp->pp_seq == sp->pp_rseq) {
sp->pp_rseq[IDX_LCP] = ntohl (h->par1);
if (sp->pp_seq[IDX_LCP] == sp->pp_rseq[IDX_LCP]) {
/* Local and remote sequence numbers are equal.
* Probably, the line is in loopback mode. */
if (sp->pp_loopcnt >= MAXALIVECNT) {
@ -1096,9 +1174,9 @@ sppp_cisco_input(struct sppp *sp, struct mbuf *m)
/* Generate new local sequence number */
#if defined(__FreeBSD__) && __FreeBSD__ >= 3
sp->pp_seq = random();
sp->pp_seq[IDX_LCP] = random();
#else
sp->pp_seq ^= time.tv_sec ^ time.tv_usec;
sp->pp_seq[IDX_LCP] ^= time.tv_sec ^ time.tv_usec;
#endif
break;
}
@ -1574,8 +1652,8 @@ sppp_cp_input(const struct cp *cp, struct sppp *sp, struct mbuf *m)
if (debug)
log(-1, SPP_FMT "%s send code-rej for 0x%x\n",
SPP_ARGS(ifp), cp->name, h->type);
sppp_cp_send(sp, cp->proto, CODE_REJ, ++sp->pp_seq,
m->m_pkthdr.len, h);
sppp_cp_send(sp, cp->proto, CODE_REJ,
++sp->pp_seq[cp->protoidx], m->m_pkthdr.len, h);
++ifp->if_ierrors;
}
}
@ -1730,7 +1808,8 @@ sppp_close_event(const struct cp *cp, struct sppp *sp)
case STATE_ACK_RCVD:
case STATE_ACK_SENT:
sp->rst_counter[cp->protoidx] = sp->lcp.max_terminate;
sppp_cp_send(sp, cp->proto, TERM_REQ, ++sp->pp_seq, 0, 0);
sppp_cp_send(sp, cp->proto, TERM_REQ,
++sp->pp_seq[cp->protoidx], 0, 0);
sppp_cp_change_state(cp, sp, STATE_CLOSING);
break;
}
@ -1772,8 +1851,8 @@ sppp_to_event(const struct cp *cp, struct sppp *sp)
switch (sp->state[cp->protoidx]) {
case STATE_CLOSING:
case STATE_STOPPING:
sppp_cp_send(sp, cp->proto, TERM_REQ, ++sp->pp_seq,
0, 0);
sppp_cp_send(sp, cp->proto, TERM_REQ,
++sp->pp_seq[cp->protoidx], 0, 0);
TIMEOUT(cp->TO, (void *)sp, sp->lcp.timeout,
sp->ch[cp->protoidx]);
break;
@ -1835,6 +1914,8 @@ sppp_lcp_init(struct sppp *sp)
sp->lcp.magic = 0;
sp->state[IDX_LCP] = STATE_INITIAL;
sp->fail_counter[IDX_LCP] = 0;
sp->pp_seq[IDX_LCP] = 0;
sp->pp_rseq[IDX_LCP] = 0;
sp->lcp.protos = 0;
sp->lcp.mru = sp->lcp.their_mru = PP_MTU;
@ -2468,7 +2549,7 @@ sppp_lcp_scr(struct sppp *sp)
opt[i++] = CHAP_MD5;
}
sp->confid[IDX_LCP] = ++sp->pp_seq;
sp->confid[IDX_LCP] = ++sp->pp_seq[IDX_LCP];
sppp_cp_send (sp, PPP_LCP, CONF_REQ, sp->confid[IDX_LCP], i, &opt);
}
@ -2519,6 +2600,8 @@ sppp_ipcp_init(struct sppp *sp)
sp->ipcp.flags = 0;
sp->state[IDX_IPCP] = STATE_INITIAL;
sp->fail_counter[IDX_IPCP] = 0;
sp->pp_seq[IDX_IPCP] = 0;
sp->pp_rseq[IDX_IPCP] = 0;
#if defined(__FreeBSD__) && __FreeBSD__ >= 3
callout_handle_init(&sp->ch[IDX_IPCP]);
#endif
@ -2894,10 +2977,513 @@ sppp_ipcp_scr(struct sppp *sp)
opt[i++] = ouraddr;
}
sp->confid[IDX_IPCP] = ++sp->pp_seq;
sp->confid[IDX_IPCP] = ++sp->pp_seq[IDX_IPCP];
sppp_cp_send(sp, PPP_IPCP, CONF_REQ, sp->confid[IDX_IPCP], i, &opt);
}
/*
*--------------------------------------------------------------------------*
* *
* The IPv6CP implementation. *
* *
*--------------------------------------------------------------------------*
*/
#ifdef INET6
static void
sppp_ipv6cp_init(struct sppp *sp)
{
sp->ipv6cp.opts = 0;
sp->ipv6cp.flags = 0;
sp->state[IDX_IPV6CP] = STATE_INITIAL;
sp->fail_counter[IDX_IPV6CP] = 0;
sp->pp_seq[IDX_IPV6CP] = 0;
sp->pp_rseq[IDX_IPV6CP] = 0;
#if defined(__NetBSD__)
callout_init(&sp->ch[IDX_IPV6CP]);
#endif
#if defined(__FreeBSD__) && __FreeBSD__ >= 3
callout_handle_init(&sp->ch[IDX_IPV6CP]);
#endif
}
static void
sppp_ipv6cp_up(struct sppp *sp)
{
sppp_up_event(&ipv6cp, sp);
}
static void
sppp_ipv6cp_down(struct sppp *sp)
{
sppp_down_event(&ipv6cp, sp);
}
static void
sppp_ipv6cp_open(struct sppp *sp)
{
STDDCL;
struct in6_addr myaddr, hisaddr;
#ifdef IPV6CP_MYIFID_DYN
sp->ipv6cp.flags &= ~(IPV6CP_MYIFID_SEEN|IPV6CP_MYIFID_DYN);
#else
sp->ipv6cp.flags &= ~IPV6CP_MYIFID_SEEN;
#endif
sppp_get_ip6_addrs(sp, &myaddr, &hisaddr, 0);
/*
* If we don't have our address, this probably means our
* interface doesn't want to talk IPv6 at all. (This could
* be the case if somebody wants to speak only IPX, for
* example.) Don't open IPv6CP in this case.
*/
if (IN6_IS_ADDR_UNSPECIFIED(&myaddr)) {
/* XXX this message should go away */
if (debug)
log(LOG_DEBUG, SPP_FMT "ipv6cp_open(): no IPv6 interface\n",
SPP_ARGS(ifp));
return;
}
sp->ipv6cp.flags |= IPV6CP_MYIFID_SEEN;
sp->ipv6cp.opts |= (1 << IPV6CP_OPT_IFID);
sppp_open_event(&ipv6cp, sp);
}
static void
sppp_ipv6cp_close(struct sppp *sp)
{
sppp_close_event(&ipv6cp, sp);
}
static void
sppp_ipv6cp_TO(void *cookie)
{
sppp_to_event(&ipv6cp, (struct sppp *)cookie);
}
/*
* Analyze a configure request. Return true if it was agreeable, and
* caused action sca, false if it has been rejected or nak'ed, and
* caused action scn. (The return value is used to make the state
* transition decision in the state automaton.)
*/
static int
sppp_ipv6cp_RCR(struct sppp *sp, struct lcp_header *h, int len)
{
u_char *buf, *r, *p;
struct ifnet *ifp = &sp->pp_if;
int rlen, origlen, debug = ifp->if_flags & IFF_DEBUG;
struct in6_addr myaddr, desiredaddr, suggestaddr;
int ifidcount;
int type;
int collision, nohisaddr;
len -= 4;
origlen = len;
/*
* Make sure to allocate a buf that can at least hold a
* conf-nak with an `address' option. We might need it below.
*/
buf = r = malloc ((len < 6? 6: len), M_TEMP, M_NOWAIT);
if (! buf)
return (0);
/* pass 1: see if we can recognize them */
if (debug)
log(LOG_DEBUG, SPP_FMT "ipv6cp parse opts:",
SPP_ARGS(ifp));
p = (void*) (h+1);
ifidcount = 0;
for (rlen=0; len>1 && p[1]; len-=p[1], p+=p[1]) {
if (debug)
addlog(" %s", sppp_ipv6cp_opt_name(*p));
switch (*p) {
case IPV6CP_OPT_IFID:
if (len >= 10 && p[1] == 10 && ifidcount == 0) {
/* correctly formed address option */
ifidcount++;
continue;
}
if (debug)
addlog(" [invalid]");
break;
#ifdef notyet
case IPV6CP_OPT_COMPRESSION:
if (len >= 4 && p[1] >= 4) {
/* correctly formed compress option */
continue;
}
if (debug)
addlog(" [invalid]");
break;
#endif
default:
/* Others not supported. */
if (debug)
addlog(" [rej]");
break;
}
/* Add the option to rejected list. */
bcopy (p, r, p[1]);
r += p[1];
rlen += p[1];
}
if (rlen) {
if (debug)
addlog(" send conf-rej\n");
sppp_cp_send (sp, PPP_IPV6CP, CONF_REJ, h->ident, rlen, buf);
goto end;
} else if (debug)
addlog("\n");
/* pass 2: parse option values */
sppp_get_ip6_addrs(sp, &myaddr, 0, 0);
if (debug)
log(LOG_DEBUG, SPP_FMT "ipv6cp parse opt values: ",
SPP_ARGS(ifp));
p = (void*) (h+1);
len = origlen;
type = CONF_ACK;
for (rlen=0; len>1 && p[1]; len-=p[1], p+=p[1]) {
if (debug)
addlog(" %s", sppp_ipv6cp_opt_name(*p));
switch (*p) {
#ifdef notyet
case IPV6CP_OPT_COMPRESSION:
continue;
#endif
case IPV6CP_OPT_IFID:
bzero(&desiredaddr, sizeof(desiredaddr));
bcopy(&p[2], &desiredaddr.s6_addr[8], 8);
collision = (bcmp(&desiredaddr.s6_addr[8],
&myaddr.s6_addr[8], 8) == 0);
nohisaddr = IN6_IS_ADDR_UNSPECIFIED(&desiredaddr);
desiredaddr.s6_addr16[0] = htons(0xfe80);
desiredaddr.s6_addr16[1] = htons(sp->pp_if.if_index);
if (!collision && !nohisaddr) {
/* no collision, hisaddr known - Conf-Ack */
type = CONF_ACK;
if (debug) {
addlog(" %s [%s]",
ip6_sprintf(&desiredaddr),
sppp_cp_type_name(type));
}
continue;
}
bzero(&suggestaddr, sizeof(&suggestaddr));
if (collision && nohisaddr) {
/* collision, hisaddr unknown - Conf-Rej */
type = CONF_REJ;
bzero(&p[2], 8);
} else {
/*
* - no collision, hisaddr unknown, or
* - collision, hisaddr known
* Conf-Nak, suggest hisaddr
*/
type = CONF_NAK;
sppp_suggest_ip6_addr(sp, &suggestaddr);
bcopy(&suggestaddr.s6_addr[8], &p[2], 8);
}
if (debug)
addlog(" %s [%s]", ip6_sprintf(&desiredaddr),
sppp_cp_type_name(type));
break;
}
/* Add the option to nak'ed list. */
bcopy (p, r, p[1]);
r += p[1];
rlen += p[1];
}
if (rlen == 0 && type == CONF_ACK) {
if (debug)
addlog(" send %s\n", sppp_cp_type_name(type));
sppp_cp_send (sp, PPP_IPV6CP, type, h->ident, origlen, h+1);
} else {
#ifdef DIAGNOSTIC
if (type == CONF_ACK)
panic("IPv6CP RCR: CONF_ACK with non-zero rlen");
#endif
if (debug) {
addlog(" send %s suggest %s\n",
sppp_cp_type_name(type), ip6_sprintf(&suggestaddr));
}
sppp_cp_send (sp, PPP_IPV6CP, type, h->ident, rlen, buf);
}
end:
free (buf, M_TEMP);
return (rlen == 0);
}
/*
* Analyze the IPv6CP Configure-Reject option list, and adjust our
* negotiation.
*/
static void
sppp_ipv6cp_RCN_rej(struct sppp *sp, struct lcp_header *h, int len)
{
u_char *buf, *p;
struct ifnet *ifp = &sp->pp_if;
int debug = ifp->if_flags & IFF_DEBUG;
len -= 4;
buf = malloc (len, M_TEMP, M_NOWAIT);
if (!buf)
return;
if (debug)
log(LOG_DEBUG, SPP_FMT "ipv6cp rej opts:",
SPP_ARGS(ifp));
p = (void*) (h+1);
for (; len > 1 && p[1]; len -= p[1], p += p[1]) {
if (debug)
addlog(" %s", sppp_ipv6cp_opt_name(*p));
switch (*p) {
case IPV6CP_OPT_IFID:
/*
* Peer doesn't grok address option. This is
* bad. XXX Should we better give up here?
*/
sp->ipv6cp.opts &= ~(1 << IPV6CP_OPT_IFID);
break;
#ifdef notyet
case IPV6CP_OPT_COMPRESS:
sp->ipv6cp.opts &= ~(1 << IPV6CP_OPT_COMPRESS);
break;
#endif
}
}
if (debug)
addlog("\n");
free (buf, M_TEMP);
return;
}
/*
* Analyze the IPv6CP Configure-NAK option list, and adjust our
* negotiation.
*/
static void
sppp_ipv6cp_RCN_nak(struct sppp *sp, struct lcp_header *h, int len)
{
u_char *buf, *p;
struct ifnet *ifp = &sp->pp_if;
int debug = ifp->if_flags & IFF_DEBUG;
struct in6_addr suggestaddr;
len -= 4;
buf = malloc (len, M_TEMP, M_NOWAIT);
if (!buf)
return;
if (debug)
log(LOG_DEBUG, SPP_FMT "ipv6cp nak opts:",
SPP_ARGS(ifp));
p = (void*) (h+1);
for (; len > 1 && p[1]; len -= p[1], p += p[1]) {
if (debug)
addlog(" %s", sppp_ipv6cp_opt_name(*p));
switch (*p) {
case IPV6CP_OPT_IFID:
/*
* Peer doesn't like our local ifid. See
* if we can do something for him. We'll drop
* him our address then.
*/
if (len < 10 || p[1] != 10)
break;
bzero(&suggestaddr, sizeof(suggestaddr));
suggestaddr.s6_addr16[0] = htons(0xfe80);
suggestaddr.s6_addr16[1] = htons(sp->pp_if.if_index);
bcopy(&p[2], &suggestaddr.s6_addr[8], 8);
sp->ipv6cp.opts |= (1 << IPV6CP_OPT_IFID);
if (debug)
addlog(" [suggestaddr %s]",
ip6_sprintf(&suggestaddr));
#ifdef IPV6CP_MYIFID_DYN
/*
* When doing dynamic address assignment,
* we accept his offer.
*/
if (sp->ipv6cp.flags & IPV6CP_MYIFID_DYN) {
struct in6_addr lastsuggest;
/*
* If <suggested myaddr from peer> equals to
* <hisaddr we have suggested last time>,
* we have a collision. generate new random
* ifid.
*/
sppp_suggest_ip6_addr(&lastsuggest);
if (IN6_ARE_ADDR_EQUAL(&suggestaddr,
lastsuggest)) {
if (debug)
addlog(" [random]");
sppp_gen_ip6_addr(sp, &suggestaddr);
}
sppp_set_ip6_addr(sp, &suggestaddr, 0);
if (debug)
addlog(" [agree]");
sp->ipv6cp.flags |= IPV6CP_MYIFID_SEEN;
}
#else
/*
* Since we do not do dynamic address assignment,
* we ignore it and thus continue to negotiate
* our already existing value. This can possibly
* go into infinite request-reject loop.
*
* This is not likely because we normally use
* ifid based on MAC-address.
* If you have no ethernet card on the node, too bad.
* XXX should we use fail_counter?
*/
#endif
break;
#ifdef notyet
case IPV6CP_OPT_COMPRESS:
/*
* Peer wants different compression parameters.
*/
break;
#endif
}
}
if (debug)
addlog("\n");
free (buf, M_TEMP);
return;
}
static void
sppp_ipv6cp_tlu(struct sppp *sp)
{
/* we are up - notify isdn daemon */
if (sp->pp_con)
sp->pp_con(sp);
}
static void
sppp_ipv6cp_tld(struct sppp *sp)
{
}
static void
sppp_ipv6cp_tls(struct sppp *sp)
{
/* indicate to LCP that it must stay alive */
sp->lcp.protos |= (1 << IDX_IPV6CP);
}
static void
sppp_ipv6cp_tlf(struct sppp *sp)
{
#if 0 /* need #if 0 to close IPv6CP properly */
/* we no longer need LCP */
sp->lcp.protos &= ~(1 << IDX_IPV6CP);
sppp_lcp_check_and_close(sp);
#endif
}
static void
sppp_ipv6cp_scr(struct sppp *sp)
{
char opt[10 /* ifid */ + 4 /* compression, minimum */];
struct in6_addr ouraddr;
int i = 0;
if (sp->ipv6cp.opts & (1 << IPV6CP_OPT_IFID)) {
sppp_get_ip6_addrs(sp, &ouraddr, 0, 0);
opt[i++] = IPV6CP_OPT_IFID;
opt[i++] = 10;
bcopy(&ouraddr.s6_addr[8], &opt[i], 8);
i += 8;
}
#ifdef notyet
if (sp->ipv6cp.opts & (1 << IPV6CP_OPT_COMPRESSION)) {
opt[i++] = IPV6CP_OPT_COMPRESSION;
opt[i++] = 4;
opt[i++] = 0; /* TBD */
opt[i++] = 0; /* TBD */
/* variable length data may follow */
}
#endif
sp->confid[IDX_IPV6CP] = ++sp->pp_seq[IDX_IPV6CP];
sppp_cp_send(sp, PPP_IPV6CP, CONF_REQ, sp->confid[IDX_IPV6CP], i, &opt);
}
#else /*INET6*/
static void sppp_ipv6cp_init(struct sppp *sp)
{
}
static void sppp_ipv6cp_up(struct sppp *sp)
{
}
static void sppp_ipv6cp_down(struct sppp *sp)
{
}
static void sppp_ipv6cp_open(struct sppp *sp)
{
}
static void sppp_ipv6cp_close(struct sppp *sp)
{
}
static void sppp_ipv6cp_TO(void *sp)
{
}
static int sppp_ipv6cp_RCR(struct sppp *sp, struct lcp_header *h, int len)
{
return 0;
}
static void sppp_ipv6cp_RCN_rej(struct sppp *sp, struct lcp_header *h, int len)
{
}
static void sppp_ipv6cp_RCN_nak(struct sppp *sp, struct lcp_header *h, int len)
{
}
static void sppp_ipv6cp_tlu(struct sppp *sp)
{
}
static void sppp_ipv6cp_tld(struct sppp *sp)
{
}
static void sppp_ipv6cp_tls(struct sppp *sp)
{
}
static void sppp_ipv6cp_tlf(struct sppp *sp)
{
}
static void sppp_ipv6cp_scr(struct sppp *sp)
{
}
#endif /*INET6*/
/*
*--------------------------------------------------------------------------*
* *
@ -3213,6 +3799,8 @@ sppp_chap_init(struct sppp *sp)
/* Chap doesn't have STATE_INITIAL at all. */
sp->state[IDX_CHAP] = STATE_CLOSED;
sp->fail_counter[IDX_CHAP] = 0;
sp->pp_seq[IDX_CHAP] = 0;
sp->pp_rseq[IDX_CHAP] = 0;
#if defined(__FreeBSD__) && __FreeBSD__ >= 3
callout_handle_init(&sp->ch[IDX_CHAP]);
#endif
@ -3371,7 +3959,7 @@ sppp_chap_scr(struct sppp *sp)
ch[3] = seed ^ random();
clen = AUTHKEYLEN;
sp->confid[IDX_CHAP] = ++sp->pp_seq;
sp->confid[IDX_CHAP] = ++sp->pp_seq[IDX_CHAP];
sppp_auth_send(&chap, sp, CHAP_CHALLENGE, sp->confid[IDX_CHAP],
sizeof clen, (const char *)&clen,
@ -3544,6 +4132,8 @@ sppp_pap_init(struct sppp *sp)
/* PAP doesn't have STATE_INITIAL at all. */
sp->state[IDX_PAP] = STATE_CLOSED;
sp->fail_counter[IDX_PAP] = 0;
sp->pp_seq[IDX_PAP] = 0;
sp->pp_rseq[IDX_PAP] = 0;
#if defined(__FreeBSD__) && __FreeBSD__ >= 3
callout_handle_init(&sp->ch[IDX_PAP]);
callout_handle_init(&sp->pap_my_to_ch);
@ -3678,7 +4268,7 @@ sppp_pap_scr(struct sppp *sp)
{
u_char idlen, pwdlen;
sp->confid[IDX_PAP] = ++sp->pp_seq;
sp->confid[IDX_PAP] = ++sp->pp_seq[IDX_PAP];
pwdlen = sppp_strnlen(sp->myauth.secret, AUTHKEYLEN);
idlen = sppp_strnlen(sp->myauth.name, AUTHNAMELEN);
@ -3824,11 +4414,11 @@ sppp_keepalive(void *dummy)
if (sp->pp_alivecnt <= MAXALIVECNT)
++sp->pp_alivecnt;
if (sp->pp_mode == IFF_CISCO)
sppp_cisco_send (sp, CISCO_KEEPALIVE_REQ, ++sp->pp_seq,
sp->pp_rseq);
sppp_cisco_send (sp, CISCO_KEEPALIVE_REQ,
++sp->pp_seq[IDX_LCP], sp->pp_rseq[IDX_LCP]);
else if (sp->pp_phase >= PHASE_AUTHENTICATE) {
long nmagic = htonl (sp->lcp.magic);
sp->lcp.echoid = ++sp->pp_seq;
sp->lcp.echoid = ++sp->pp_seq[IDX_LCP];
sppp_cp_send (sp, PPP_LCP, ECHO_REQ,
sp->lcp.echoid, 4, &nmagic);
}
@ -3957,8 +4547,154 @@ sppp_set_ip_addr(struct sppp *sp, u_long src)
}
#endif
}
}
#ifdef INET6
/*
* Get both IPv6 addresses.
*/
static void
sppp_get_ip6_addrs(struct sppp *sp, struct in6_addr *src, struct in6_addr *dst,
struct in6_addr *srcmask)
{
struct ifnet *ifp = &sp->pp_if;
struct ifaddr *ifa;
struct sockaddr_in6 *si, *sm;
struct in6_addr ssrc, ddst;
sm = NULL;
bzero(&ssrc, sizeof(ssrc));
bzero(&ddst, sizeof(ddst));
/*
* Pick the first link-local AF_INET6 address from the list,
* aliases don't make any sense on a p2p link anyway.
*/
#if defined(__FreeBSD__) && __FreeBSD__ >= 3
for (ifa = ifp->if_addrhead.tqh_first, si = 0;
ifa;
ifa = ifa->ifa_link.tqe_next)
#elif defined(__NetBSD__) || defined (__OpenBSD__)
for (ifa = ifp->if_addrlist.tqh_first, si = 0;
ifa;
ifa = ifa->ifa_list.tqe_next)
#else
for (ifa = ifp->if_addrlist, si = 0;
ifa;
ifa = ifa->ifa_next)
#endif
if (ifa->ifa_addr->sa_family == AF_INET6) {
si = (struct sockaddr_in6 *)ifa->ifa_addr;
sm = (struct sockaddr_in6 *)ifa->ifa_netmask;
if (si && IN6_IS_ADDR_LINKLOCAL(&si->sin6_addr))
break;
}
if (ifa) {
if (si && !IN6_IS_ADDR_UNSPECIFIED(&si->sin6_addr)) {
bcopy(&si->sin6_addr, &ssrc, sizeof(ssrc));
if (srcmask) {
bcopy(&sm->sin6_addr, srcmask,
sizeof(*srcmask));
}
}
si = (struct sockaddr_in6 *)ifa->ifa_dstaddr;
if (si && !IN6_IS_ADDR_UNSPECIFIED(&si->sin6_addr))
bcopy(&si->sin6_addr, &ddst, sizeof(ddst));
}
if (dst)
bcopy(&ddst, dst, sizeof(*dst));
if (src)
bcopy(&ssrc, src, sizeof(*src));
}
#ifdef IPV6CP_MYIFID_DYN
/*
* Generate random ifid.
*/
static void
sppp_gen_ip6_addr(struct sppp *sp, struct in6_addr *addr)
{
/* TBD */
}
/*
* Set my IPv6 address. Must be called at splimp.
*/
static void
sppp_set_ip6_addr(struct sppp *sp, const struct in6_addr *src)
{
STDDCL;
struct ifaddr *ifa;
struct sockaddr_in6 *sin6;
/*
* Pick the first link-local AF_INET6 address from the list,
* aliases don't make any sense on a p2p link anyway.
*/
sin6 = NULL;
#if defined(__FreeBSD__) && __FreeBSD__ >= 3
for (ifa = ifp->if_addrhead.tqh_first;
ifa;
ifa = ifa->ifa_link.tqe_next)
#elif defined(__NetBSD__) || defined (__OpenBSD__)
for (ifa = ifp->if_addrlist.tqh_first;
ifa;
ifa = ifa->ifa_list.tqe_next)
#else
for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next)
#endif
{
if (ifa->ifa_addr->sa_family == AF_INET6)
{
sin6 = (struct sockaddr_in6 *)ifa->ifa_addr;
if (sin6 && IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))
break;
}
}
if (ifa && sin6)
{
int error;
struct sockaddr_in6 new_sin6 = *sin6;
bcopy(src, &new_sin6.sin6_addr, sizeof(new_sin6.sin6_addr));
error = in6_ifinit(ifp, ifatoia6(ifa), &new_sin6, 1);
if (debug && error)
{
log(LOG_DEBUG, SPP_FMT "sppp_set_ip6_addr: in6_ifinit "
" failed, error=%d\n", SPP_ARGS(ifp), error);
}
}
}
#endif
/*
* Suggest a candidate address to be used by peer.
*/
static void
sppp_suggest_ip6_addr(struct sppp *sp, struct in6_addr *suggest)
{
struct in6_addr myaddr;
struct timeval tv;
sppp_get_ip6_addrs(sp, &myaddr, 0, 0);
myaddr.s6_addr[8] &= ~0x02; /* u bit to "local" */
microtime(&tv);
if ((tv.tv_usec & 0xff) == 0 && (tv.tv_sec & 0xff) == 0) {
myaddr.s6_addr[14] ^= 0xff;
myaddr.s6_addr[15] ^= 0xff;
} else {
myaddr.s6_addr[14] ^= (tv.tv_usec & 0xff);
myaddr.s6_addr[15] ^= (tv.tv_sec & 0xff);
}
if (suggest)
bcopy(&myaddr, suggest, sizeof(myaddr));
}
#endif /*INET6*/
static int
sppp_params(struct sppp *sp, u_long cmd, void *data)
{
@ -4165,6 +4901,20 @@ sppp_ipcp_opt_name(u_char opt)
return buf;
}
#ifdef INET6
static const char *
sppp_ipv6cp_opt_name(u_char opt)
{
static char buf[12];
switch (opt) {
case IPV6CP_OPT_IFID: return "ifid";
case IPV6CP_OPT_COMPRESSION: return "compression";
}
sprintf (buf, "0x%x", opt);
return buf;
}
#endif
static const char *
sppp_state_name(int state)
{
@ -4205,6 +4955,7 @@ sppp_proto_name(u_short proto)
case PPP_IPCP: return "ipcp";
case PPP_PAP: return "pap";
case PPP_CHAP: return "chap";
case PPP_IPV6CP: return "ipv6cp";
}
snprintf(buf, sizeof(buf), "proto/0x%x", (unsigned)proto);
return buf;

View file

@ -1,5 +1,5 @@
/* $FreeBSD$ */
/* $KAME: if_stf.c,v 1.42 2000/08/15 07:24:23 itojun Exp $ */
/* $KAME: if_stf.c,v 1.60 2001/05/03 14:51:47 itojun Exp $ */
/*
* Copyright (C) 2000 WIDE Project.
@ -31,7 +31,7 @@
*/
/*
* 6to4 interface, based on draft-ietf-ngtrans-6to4-06.txt.
* 6to4 interface, based on RFC3056.
*
* 6to4 interface is NOT capable of link-layer (I mean, IPv4) multicasting.
* There is no address mapping defined from IPv6 multicast address to IPv4
@ -60,12 +60,13 @@
* ICMPv6:
* - Redirects cannot be used due to the lack of link-local address.
*
* Starting from 04 draft, the specification suggests how to construct
* link-local address for 6to4 interface.
* However, it seems to have no real use and does not help the above symptom
* much. Even if we assign link-locals to interface, we cannot really
* use link-local unicast/multicast on top of 6to4 cloud, and the above
* analysis does not change.
* stf interface does not have, and will not need, a link-local address.
* It seems to have no real benefit and does not help the above symptoms much.
* Even if we assign link-locals to interface, we cannot really
* use link-local unicast/multicast on top of 6to4 cloud (since there's no
* encapsulation defined for link-local address), and the above analysis does
* not change. RFC3056 does not mandate the assignment of link-local address
* either.
*
* 6to4 interface has security issues. Refer to
* http://playground.iijlab.net/i-d/draft-itojun-ipv6-transition-abuse-00.txt
@ -159,8 +160,10 @@ static int stf_encapcheck __P((const struct mbuf *, int, int, void *));
static struct in6_ifaddr *stf_getsrcifa6 __P((struct ifnet *));
static int stf_output __P((struct ifnet *, struct mbuf *, struct sockaddr *,
struct rtentry *));
static int stf_checkaddr4 __P((struct in_addr *, struct ifnet *));
static int stf_checkaddr6 __P((struct in6_addr *, struct ifnet *));
static int stf_checkaddr4 __P((struct stf_softc *, struct in_addr *,
struct ifnet *));
static int stf_checkaddr6 __P((struct stf_softc *, struct in6_addr *,
struct ifnet *));
static void stf_rtrequest __P((int, struct rtentry *, struct sockaddr *));
static int stf_ioctl __P((struct ifnet *, u_long, caddr_t));
@ -197,6 +200,10 @@ stfattach(dummy)
sc->sc_if.if_ioctl = stf_ioctl;
sc->sc_if.if_output = stf_output;
sc->sc_if.if_type = IFT_STF;
#if 0
/* turn off ingress filter */
sc->sc_if.if_flags |= IFF_LINK2;
#endif
sc->sc_if.if_snd.ifq_maxlen = IFQ_MAXLEN;
if_attach(&sc->sc_if);
#if NBPFILTER > 0
@ -230,6 +237,10 @@ stf_encapcheck(m, off, proto, arg)
if ((sc->sc_if.if_flags & IFF_UP) == 0)
return 0;
/* IFF_LINK0 means "no decapsulation" */
if ((sc->sc_if.if_flags & IFF_LINK0) != 0)
return 0;
if (proto != IPPROTO_IPV6)
return 0;
@ -317,6 +328,7 @@ stf_output(ifp, m, dst, rt)
{
struct stf_softc *sc;
struct sockaddr_in6 *dst6;
struct in_addr *in4;
struct sockaddr_in *dst4;
u_int8_t tos;
struct ip *ip;
@ -351,6 +363,19 @@ stf_output(ifp, m, dst, rt)
ip6 = mtod(m, struct ip6_hdr *);
tos = (ntohl(ip6->ip6_flow) >> 20) & 0xff;
/*
* Pickup the right outer dst addr from the list of candidates.
* ip6_dst has priority as it may be able to give us shorter IPv4 hops.
*/
if (IN6_IS_ADDR_6TO4(&ip6->ip6_dst))
in4 = GET_V4(&ip6->ip6_dst);
else if (IN6_IS_ADDR_6TO4(&dst6->sin6_addr))
in4 = GET_V4(&dst6->sin6_addr);
else {
m_freem(m);
return ENETUNREACH;
}
M_PREPEND(m, sizeof(struct ip), M_DONTWAIT);
if (m && m->m_len < sizeof(struct ip))
m = m_pullup(m, sizeof(struct ip));
@ -362,12 +387,14 @@ stf_output(ifp, m, dst, rt)
bcopy(GET_V4(&((struct sockaddr_in6 *)&ia6->ia_addr)->sin6_addr),
&ip->ip_src, sizeof(ip->ip_src));
bcopy(GET_V4(&dst6->sin6_addr), &ip->ip_dst, sizeof(ip->ip_dst));
bcopy(in4, &ip->ip_dst, sizeof(ip->ip_dst));
ip->ip_p = IPPROTO_IPV6;
ip->ip_ttl = ip_gif_ttl; /*XXX*/
ip->ip_len = m->m_pkthdr.len; /*host order*/
if (ifp->if_flags & IFF_LINK1)
ip_ecn_ingress(ECN_ALLOWED, &ip->ip_tos, &tos);
else
ip_ecn_ingress(ECN_NOCARE, &ip->ip_tos, &tos);
dst4 = (struct sockaddr_in *)&sc->sc_ro.ro_dst;
if (dst4->sin_family != AF_INET ||
@ -394,9 +421,10 @@ stf_output(ifp, m, dst, rt)
}
static int
stf_checkaddr4(in, ifp)
stf_checkaddr4(sc, in, inifp)
struct stf_softc *sc;
struct in_addr *in;
struct ifnet *ifp; /* incoming interface */
struct ifnet *inifp; /* incoming interface */
{
struct in_ifaddr *ia4;
@ -427,7 +455,7 @@ stf_checkaddr4(in, ifp)
/*
* perform ingress filter
*/
if (ifp) {
if (sc && (sc->sc_if.if_flags & IFF_LINK2) == 0 && inifp) {
struct sockaddr_in sin;
struct rtentry *rt;
@ -436,10 +464,14 @@ stf_checkaddr4(in, ifp)
sin.sin_len = sizeof(struct sockaddr_in);
sin.sin_addr = *in;
rt = rtalloc1((struct sockaddr *)&sin, 0, 0UL);
if (!rt)
return -1;
if (rt->rt_ifp != ifp) {
rtfree(rt);
if (!rt || rt->rt_ifp != inifp) {
#if 0
log(LOG_WARNING, "%s: packet from 0x%x dropped "
"due to ingress filter\n", if_name(&sc->sc_if),
(u_int32_t)ntohl(sin.sin_addr.s_addr));
#endif
if (rt)
rtfree(rt);
return -1;
}
rtfree(rt);
@ -449,15 +481,16 @@ stf_checkaddr4(in, ifp)
}
static int
stf_checkaddr6(in6, ifp)
stf_checkaddr6(sc, in6, inifp)
struct stf_softc *sc;
struct in6_addr *in6;
struct ifnet *ifp; /* incoming interface */
struct ifnet *inifp; /* incoming interface */
{
/*
* check 6to4 addresses
*/
if (IN6_IS_ADDR_6TO4(in6))
return stf_checkaddr4(GET_V4(in6), ifp);
return stf_checkaddr4(sc, GET_V4(in6), inifp);
/*
* reject anything that look suspicious. the test is implemented
@ -476,7 +509,7 @@ void
in_stf_input(struct mbuf *m, ...)
#else
in_stf_input(m, va_alist)
register struct mbuf *m;
struct mbuf *m;
#endif
{
int off, proto;
@ -514,8 +547,8 @@ in_stf_input(m, va_alist)
* perform sanity check against outer src/dst.
* for source, perform ingress filter as well.
*/
if (stf_checkaddr4(&ip->ip_dst, NULL) < 0 ||
stf_checkaddr4(&ip->ip_src, m->m_pkthdr.rcvif) < 0) {
if (stf_checkaddr4(sc, &ip->ip_dst, NULL) < 0 ||
stf_checkaddr4(sc, &ip->ip_src, m->m_pkthdr.rcvif) < 0) {
m_freem(m);
return;
}
@ -534,8 +567,8 @@ in_stf_input(m, va_alist)
* perform sanity check against inner src/dst.
* for source, perform ingress filter as well.
*/
if (stf_checkaddr6(&ip6->ip6_dst, NULL) < 0 ||
stf_checkaddr6(&ip6->ip6_src, m->m_pkthdr.rcvif) < 0) {
if (stf_checkaddr6(sc, &ip6->ip6_dst, NULL) < 0 ||
stf_checkaddr6(sc, &ip6->ip6_src, m->m_pkthdr.rcvif) < 0) {
m_freem(m);
return;
}
@ -543,6 +576,8 @@ in_stf_input(m, va_alist)
itos = (ntohl(ip6->ip6_flow) >> 20) & 0xff;
if ((ifp->if_flags & IFF_LINK1) != 0)
ip_ecn_egress(ECN_ALLOWED, &otos, &itos);
else
ip_ecn_egress(ECN_NOCARE, &otos, &itos);
ip6->ip6_flow &= ~htonl(0xff << 20);
ip6->ip6_flow |= htonl((u_int32_t)itos << 20);
@ -558,7 +593,7 @@ in_stf_input(m, va_alist)
* try to free it or keep a pointer a to it).
*/
struct mbuf m0;
u_int af = AF_INET6;
u_int32_t af = AF_INET6;
m0.m_next = m;
m0.m_len = 4;
@ -594,11 +629,7 @@ static void
stf_rtrequest(cmd, rt, sa)
int cmd;
struct rtentry *rt;
#if defined(__bsdi__) && _BSDI_VERSION >= 199802
struct rt_addrinfo *sa;
#else
struct sockaddr *sa;
#endif
{
if (rt)

View file

@ -1,5 +1,5 @@
/* $FreeBSD$ */
/* $KAME: net_osdep.c,v 1.4 2000/03/25 07:23:34 sumikawa Exp $ */
/* $KAME: net_osdep.c,v 1.9 2001/04/06 09:22:05 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -32,6 +32,7 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <sys/sockio.h>
@ -52,8 +53,15 @@ const char *
if_name(ifp)
struct ifnet *ifp;
{
static char nam[IFNAMSIZ + 10]; /*enough?*/
#define MAXNUMBUF 8
static char nam[MAXNUMBUF][IFNAMSIZ + 10]; /*enough?*/
static int ifbufround = 0;
char *cp;
snprintf(nam, sizeof(nam), "%s%d", ifp->if_name, ifp->if_unit);
return nam;
ifbufround = (ifbufround + 1) % MAXNUMBUF;
cp = nam[ifbufround];
snprintf(cp, sizeof(nam), "%s%d", ifp->if_name, ifp->if_unit);
return((const char *)cp);
#undef MAXNUMBUF
}

View file

@ -1,5 +1,5 @@
/* $FreeBSD$ */
/* $KAME: net_osdep.h,v 1.22 2000/08/15 07:23:10 itojun Exp $ */
/* $KAME: net_osdep.h,v 1.44 2001/05/16 03:13:40 jinmei Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -36,16 +36,40 @@
/*
* OS dependencies:
*
* - struct rt_addrinfo
* all *BSDs except bsdi4 only have two members; rti_addrs and rti_info[].
* bsdi4 has additional members; rti_flags, rti_ifa, rti_ifp, and rti_rtm.
* - whether the IPv4 input routine convert the byte order of some fileds
* of the IP header (x: convert to the host byte order, s: strip the header
* length for possible reassembly)
* ip_len ip_id ip_off
* bsdi3: xs x x
* bsdi4: xs x
* FreeBSD: xs x
* NetBSD: x x
* OpenBSD: xs x x
*
* - side effects of rtrequest[1](RTM_DELETE)
* - ifa_ifwithaf()
* bsdi[34], netbsd, and openbsd define it in sys/net/if.c
* freebsd (all versions) does not have it.
*
* - struct rt_addrinfo
* bsdi4, netbsd 1.5R and beyond: rti_addrs, rti_info[], rti_flags, rti_ifa,
* rti_ifp, and rti_rtm.
* others: rti_addrs and rti_info[] only.
*
* - ifa->ifa_rtrequest
* bsdi4, netbsd 1.5R and beyond: rt_addrinfo *
* others: sockaddr * (note that sys/net/route.c:rtrequest() has an unsafe
* typecast code, from 4.3BSD-reno)
*
* - side effects of rtrequest{,1}(RTM_DELETE)
* BSDI[34]: delete all cloned routes underneath the route.
* FreeBSD[234]: delete all protocol-cloned routes underneath the route.
* note that cloned routes from an interface direct route
* still remain.
* NetBSD, OpenBSD: no side effects.
* NetBSD: 1.5 have no side effects. KAME/netbsd15, and post-1.5R, have
* the same effects as of BSDI.
* OpenBSD: have no side effects. KAME/openbsd has the same effects as
* of BSDI (the change is not merged - yet).
*
* - privileged process
* NetBSD, FreeBSD 3
* struct proc *p;
@ -64,11 +88,13 @@
* needs to give struct proc * as argument
* OpenBSD, BSDI [34], FreeBSD 2
* do not need struct proc *
*
* - bpf:
* OpenBSD, NetBSD, BSDI [34]
* OpenBSD, NetBSD 1.5, BSDI [34]
* need caddr_t * (= if_bpf **) and struct ifnet *
* FreeBSD 2, FreeBSD 3
* FreeBSD 2, FreeBSD 3, NetBSD post-1.5N
* need only struct ifnet * as argument
*
* - struct ifnet
* use queue.h? member names if name
* --- --- ---
@ -77,34 +103,57 @@
* OpenBSD yes standard if_xname
* NetBSD yes standard if_xname
* BSDI [34] no old standard if_name+unit
*
* - usrreq
* NetBSD, OpenBSD, BSDI [34], FreeBSD 2
* single function with PRU_xx, arguments are mbuf
* FreeBSD 3
* separates functions, non-mbuf arguments
*
* - {set,get}sockopt
* NetBSD, OpenBSD, BSDI [34], FreeBSD 2
* manipulation based on mbuf
* FreeBSD 3
* non-mbuf manipulation using sooptcopy{in,out}()
*
* - timeout() and untimeout()
* NetBSD, OpenBSD, BSDI [34], FreeBSD 2
* NetBSD 1.4.x, OpenBSD, BSDI [34], FreeBSD 2
* timeout() is a void function
* FreeBSD 3
* timeout() is non-void, must keep returned value for untimeout()
* callout_xx is also available (sys/callout.h)
* NetBSD 1.5
* timeout() is obsoleted, use callout_xx (sys/callout.h)
* OpenBSD 2.8
* timeout_{add,set,del} is encouraged (sys/timeout.h)
*
* - sysctl
* NetBSD, OpenBSD
* foo_sysctl()
* BSDI [34]
* foo_sysctl() but with different style
* FreeBSD 2, FreeBSD 3
* linker hack
* foo_sysctl() but with different style. sysctl_int_arr() takes
* care of most of the cases.
* FreeBSD
* linker hack. however, there are freebsd version differences
* (how wonderful!).
* on FreeBSD[23] function arg #define includes paren.
* int foo SYSCTL_HANDLER_ARGS;
* on FreeBSD4, function arg #define does not include paren.
* int foo(SYSCTL_HANDLER_ARGS);
* on some versions, forward reference to the tree is okay.
* on some versions, you need SYSCTL_DECL(). you need things
* like this.
* #ifdef SYSCTL_DECL
* SYSCTL_DECL(net_inet_ip6);
* #endif
* it is hard to share functions between freebsd and non-freebsd.
*
* - if_ioctl
* NetBSD, FreeBSD 3, BSDI [34]
* 2nd argument is u_long cmd
* FreeBSD 2
* 2nd argument is int cmd
*
* - if attach routines
* NetBSD
* void xxattach(int);
@ -115,6 +164,7 @@
* - ovbcopy()
* in NetBSD 1.4 or later, ovbcopy() is not supplied in the kernel.
* bcopy() is safe against overwrites.
*
* - splnet()
* NetBSD 1.4 or later requires splsoftnet().
* other operating systems use splnet().
@ -125,7 +175,8 @@
* - struct ifnet for loopback interface
* BSDI3: struct ifnet loif;
* BSDI4: struct ifnet *loifp;
* NetBSD, OpenBSD, FreeBSD2: struct ifnet loif[NLOOP];
* NetBSD, OpenBSD 2.8, FreeBSD2: struct ifnet loif[NLOOP];
* OpenBSD 2.9: struct ifnet *lo0ifp;
*
* odd thing is that many of them refers loif as ifnet *loif,
* not loif[NLOOP], from outside of if_loop.c.
@ -145,6 +196,12 @@
* FreeBSD4: struct ipprotosw in netinet/ipprotosw.h
* others: struct protosw in sys/protosw.h
*
* - protosw in general.
* NetBSD 1.5 has extra member for ipfilter (netbsd-current dropped
* it so it will go away in 1.6).
* NetBSD 1.5 requires PR_LISTEN flag bit with protocols that permit
* listen/accept (like tcp).
*
* - header files with defopt (opt_xx.h)
* FreeBSD3: opt_{inet,ipsec,ip6fw,altq}.h
* FreeBSD4: opt_{inet,inet6,ipsec,ip6fw,altq}.h
@ -154,6 +211,23 @@
* - IN_MULTICAST/IN_CLASS[A-D] macro.
* OpenBSD and NetBSD: net endian (kernel) or host endian (userland)
* others: always host endian
*
* - (m->m_flags & M_EXT) != 0 does *not* mean that the max data length of
* the mbuf == MCLBYTES.
*
* - sys/kern/uipc_mbuf.c:m_dup()
* freebsd[34]: copies the whole mbuf chain.
* netbsd: similar arg with m_copym().
* others: no m_dup().
*
* - ifa_refcnt (struct ifaddr) management (IFAREF/IFAFREE).
* NetBSD 1.5: always use IFAREF whenever reference gets added.
* always use IFAFREE whenever reference gets freed.
* IFAFREE frees ifaddr when ifa_refcnt reaches 0.
* others: do not increase refcnt for ifp->if_addrlist and in_ifaddr.
* use IFAFREE once when ifaddr is disconnected from
* ifp->if_addrlist and in_ifaddr. IFAFREE frees ifaddr when
* ifa_refcnt goes negative.
*/
#ifndef __NET_NET_OSDEP_H_DEFINED_
@ -165,6 +239,19 @@ extern const char *if_name __P((struct ifnet *));
#define HAVE_OLD_BPF
#define ifa_list ifa_link
#define if_addrlist if_addrhead
#define if_list if_link
/* sys/net/if.h */
#define IFAREF(ifa) do { ++(ifa)->ifa_refcnt; } while (0)
#define WITH_CONVERT_AND_STRIP_IP_LEN
#if 1 /* at this moment, all OSes do this */
#define WITH_CONVERT_IP_OFF
#endif
/*
* Deprecated.
*/

View file

@ -1,5 +1,5 @@
/* $FreeBSD$ */
/* $KAME: pfkeyv2.h,v 1.17 2000/06/22 08:38:33 sakane Exp $ */
/* $KAME: pfkeyv2.h,v 1.25 2001/03/12 08:34:06 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -73,7 +73,7 @@ you leave this credit intact on any copies of this file.
#define SADB_X_SPDDUMP 18
#define SADB_X_SPDFLUSH 19
#define SADB_X_SPDSETIDX 20
#define SADB_X_SPDEXPIRE 21 /* not yet */
#define SADB_X_SPDEXPIRE 21
#define SADB_X_SPDDELETE2 22 /* by policy id */
#define SADB_MAX 22
@ -298,22 +298,32 @@ struct sadb_x_ipsecrequest {
#define SADB_SAFLAGS_PFS 1
#define SADB_AALG_NONE 0
#define SADB_AALG_MD5HMAC 1 /* 2 */
#define SADB_AALG_SHA1HMAC 2 /* 3 */
#define SADB_AALG_MD5 3 /* Keyed MD5 */
#define SADB_AALG_SHA 4 /* Keyed SHA */
#define SADB_AALG_NULL 5 /* null authentication */
#define SADB_AALG_MAX 6
/* RFC2367 numbers - meets RFC2407 */
#define SADB_AALG_NONE 0
#define SADB_AALG_MD5HMAC 1 /*2*/
#define SADB_AALG_SHA1HMAC 2 /*3*/
#define SADB_AALG_MAX 8
/* private allocations - based on RFC2407/IANA assignment */
#define SADB_X_AALG_SHA2_256 6 /*5*/
#define SADB_X_AALG_SHA2_384 7 /*6*/
#define SADB_X_AALG_SHA2_512 8 /*7*/
/* private allocations should use 249-255 (RFC2407) */
#define SADB_X_AALG_MD5 3 /*249*/ /* Keyed MD5 */
#define SADB_X_AALG_SHA 4 /*250*/ /* Keyed SHA */
#define SADB_X_AALG_NULL 5 /*251*/ /* null authentication */
#define SADB_EALG_NONE 0
#define SADB_EALG_DESCBC 1 /* 2 */
#define SADB_EALG_3DESCBC 2 /* 3 */
#define SADB_EALG_NULL 3 /* 11 */
#define SADB_EALG_BLOWFISHCBC 4
#define SADB_EALG_CAST128CBC 5
#define SADB_EALG_RC5CBC 6
#define SADB_EALG_MAX 7
/* RFC2367 numbers - meets RFC2407 */
#define SADB_EALG_NONE 0
#define SADB_EALG_DESCBC 1 /*2*/
#define SADB_EALG_3DESCBC 2 /*3*/
#define SADB_EALG_NULL 3 /*11*/
#define SADB_EALG_MAX 12
/* private allocations - based on RFC2407/IANA assignment */
#define SADB_X_EALG_CAST128CBC 5 /*6*/
#define SADB_X_EALG_BLOWFISHCBC 4 /*7*/
#define SADB_X_EALG_RIJNDAELCBC 12
#define SADB_X_EALG_AES 12
/* private allocations should use 249-255 (RFC2407) */
#if 1 /*nonstandard */
#define SADB_X_CALG_NONE 0

View file

@ -69,6 +69,8 @@
#define PPP_LQR 0xc025 /* Link Quality Report protocol */
#define PPP_CHAP 0xc223 /* Cryptographic Handshake Auth. Protocol */
#define PPP_CBCP 0xc029 /* Callback Control Protocol */
#define PPP_IPV6 0x57 /* Internet Protocol version 6*/
#define PPP_IPV6CP 0x8057 /* IPv6 Control Protocol */
/*
* Values for FCS calculations.

View file

@ -573,9 +573,6 @@ rt_msg1(type, rtinfo)
register struct sockaddr *sa;
int len, dlen;
m = m_gethdr(M_DONTWAIT, MT_DATA);
if (m == 0)
return (m);
switch (type) {
case RTM_DELADDR:
@ -595,8 +592,18 @@ rt_msg1(type, rtinfo)
default:
len = sizeof(struct rt_msghdr);
}
if (len > MHLEN)
if (len > MCLBYTES)
panic("rt_msg1");
m = m_gethdr(M_DONTWAIT, MT_DATA);
if (m && len > MHLEN) {
MCLGET(m, M_DONTWAIT);
if ((m->m_flags & M_EXT) == 0) {
m_free(m);
m = NULL;
}
}
if (m == 0)
return (m);
m->m_pkthdr.len = m->m_len = len;
m->m_pkthdr.rcvif = 0;
rtm = mtod(m, struct rt_msghdr *);

View file

@ -1,5 +1,5 @@
/* $FreeBSD$ */
/* $KAME: icmp6.h,v 1.18 2000/07/03 02:51:08 itojun Exp $ */
/* $KAME: icmp6.h,v 1.46 2001/04/27 15:09:48 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -80,7 +80,7 @@ struct icmp6_hdr {
u_int16_t icmp6_un_data16[2]; /* type-specific field */
u_int8_t icmp6_un_data8[4]; /* type-specific field */
} icmp6_dataun;
};
} __attribute__((__packed__));
#define icmp6_data32 icmp6_dataun.icmp6_un_data32
#define icmp6_data16 icmp6_dataun.icmp6_un_data16
@ -124,7 +124,10 @@ struct icmp6_hdr {
#define MLD6_MTRACE_RESP 141 /* mtrace response(to sender) */
#define MLD6_MTRACE 142 /* mtrace messages */
#define ICMP6_MAXTYPE 142
#define ICMP6_HADISCOV_REQUEST 143 /* XXX To be defined */
#define ICMP6_HADISCOV_REPLY 144 /* XXX To be defined */
#define ICMP6_MAXTYPE 144
#define ICMP6_DST_UNREACH_NOROUTE 0 /* no route to destination */
#define ICMP6_DST_UNREACH_ADMIN 1 /* administratively prohibited */
@ -146,7 +149,7 @@ struct icmp6_hdr {
#define ICMP6_NI_SUBJ_FQDN 1 /* Query Subject is a Domain name */
#define ICMP6_NI_SUBJ_IPV4 2 /* Query Subject is an IPv4 address */
#define ICMP6_NI_SUCESS 0 /* node information successful reply */
#define ICMP6_NI_SUCCESS 0 /* node information successful reply */
#define ICMP6_NI_REFUSED 1 /* node information request is refused */
#define ICMP6_NI_UNKNOWN 2 /* unknown Qtype */
@ -164,7 +167,7 @@ struct icmp6_hdr {
struct mld6_hdr {
struct icmp6_hdr mld6_hdr;
struct in6_addr mld6_addr; /* multicast address */
};
} __attribute__((__packed__));
#define mld6_type mld6_hdr.icmp6_type
#define mld6_code mld6_hdr.icmp6_code
@ -179,7 +182,7 @@ struct mld6_hdr {
struct nd_router_solicit { /* router solicitation */
struct icmp6_hdr nd_rs_hdr;
/* could be followed by options */
};
} __attribute__((__packed__));
#define nd_rs_type nd_rs_hdr.icmp6_type
#define nd_rs_code nd_rs_hdr.icmp6_code
@ -191,7 +194,7 @@ struct nd_router_advert { /* router advertisement */
u_int32_t nd_ra_reachable; /* reachable time */
u_int32_t nd_ra_retransmit; /* retransmit timer */
/* could be followed by options */
};
} __attribute__((__packed__));
#define nd_ra_type nd_ra_hdr.icmp6_type
#define nd_ra_code nd_ra_hdr.icmp6_code
@ -200,13 +203,26 @@ struct nd_router_advert { /* router advertisement */
#define nd_ra_flags_reserved nd_ra_hdr.icmp6_data8[1]
#define ND_RA_FLAG_MANAGED 0x80
#define ND_RA_FLAG_OTHER 0x40
#define ND_RA_FLAG_HA 0x20
/*
* Router preference values based on draft-draves-ipngwg-router-selection-01.
* These are non-standard definitions.
*/
#define ND_RA_FLAG_RTPREF_MASK 0x18 /* 00011000 */
#define ND_RA_FLAG_RTPREF_HIGH 0x08 /* 00001000 */
#define ND_RA_FLAG_RTPREF_MEDIUM 0x00 /* 00000000 */
#define ND_RA_FLAG_RTPREF_LOW 0x18 /* 00011000 */
#define ND_RA_FLAG_RTPREF_RSV 0x10 /* 00010000 */
#define nd_ra_router_lifetime nd_ra_hdr.icmp6_data16[1]
struct nd_neighbor_solicit { /* neighbor solicitation */
struct icmp6_hdr nd_ns_hdr;
struct in6_addr nd_ns_target; /*target address */
/* could be followed by options */
};
} __attribute__((__packed__));
#define nd_ns_type nd_ns_hdr.icmp6_type
#define nd_ns_code nd_ns_hdr.icmp6_code
@ -217,7 +233,7 @@ struct nd_neighbor_advert { /* neighbor advertisement */
struct icmp6_hdr nd_na_hdr;
struct in6_addr nd_na_target; /* target address */
/* could be followed by options */
};
} __attribute__((__packed__));
#define nd_na_type nd_na_hdr.icmp6_type
#define nd_na_code nd_na_hdr.icmp6_code
@ -240,7 +256,7 @@ struct nd_redirect { /* redirect */
struct in6_addr nd_rd_target; /* target address */
struct in6_addr nd_rd_dst; /* destination address */
/* could be followed by options */
};
} __attribute__((__packed__));
#define nd_rd_type nd_rd_hdr.icmp6_type
#define nd_rd_code nd_rd_hdr.icmp6_code
@ -251,13 +267,14 @@ struct nd_opt_hdr { /* Neighbor discovery option header */
u_int8_t nd_opt_type;
u_int8_t nd_opt_len;
/* followed by option specific data*/
};
} __attribute__((__packed__));
#define ND_OPT_SOURCE_LINKADDR 1
#define ND_OPT_TARGET_LINKADDR 2
#define ND_OPT_PREFIX_INFORMATION 3
#define ND_OPT_REDIRECTED_HEADER 4
#define ND_OPT_MTU 5
#define ND_OPT_ROUTE_INFO 9 /* draft-draves-router-preference, not officially assigned yet */
struct nd_opt_prefix_info { /* prefix information */
u_int8_t nd_opt_pi_type;
@ -268,7 +285,7 @@ struct nd_opt_prefix_info { /* prefix information */
u_int32_t nd_opt_pi_preferred_time;
u_int32_t nd_opt_pi_reserved2;
struct in6_addr nd_opt_pi_prefix;
};
} __attribute__((__packed__));
#define ND_OPT_PI_FLAG_ONLINK 0x80
#define ND_OPT_PI_FLAG_AUTO 0x40
@ -279,15 +296,23 @@ struct nd_opt_rd_hdr { /* redirected header */
u_int16_t nd_opt_rh_reserved1;
u_int32_t nd_opt_rh_reserved2;
/* followed by IP header and data */
};
} __attribute__((__packed__));
struct nd_opt_mtu { /* MTU option */
u_int8_t nd_opt_mtu_type;
u_int8_t nd_opt_mtu_len;
u_int16_t nd_opt_mtu_reserved;
u_int32_t nd_opt_mtu_mtu;
};
} __attribute__((__packed__));
struct nd_opt_route_info { /* route info */
u_int8_t nd_opt_rti_type;
u_int8_t nd_opt_rti_len;
u_int8_t nd_opt_rti_prefixlen;
u_int8_t nd_opt_rti_flags;
u_int32_t nd_opt_rti_lifetime;
/* followed by prefix */
} __attribute__((__packed__));
/*
* icmp6 namelookup
*/
@ -301,7 +326,7 @@ struct icmp6_namelookup {
u_int8_t icmp6_nl_name[3];
#endif
/* could be followed by options */
};
} __attribute__((__packed__));
/*
* icmp6 node information
@ -310,7 +335,7 @@ struct icmp6_nodeinfo {
struct icmp6_hdr icmp6_ni_hdr;
u_int8_t icmp6_ni_nonce[8];
/* could be followed by reply data */
};
} __attribute__((__packed__));
#define ni_type icmp6_ni_hdr.icmp6_type
#define ni_code icmp6_ni_hdr.icmp6_code
@ -320,8 +345,10 @@ struct icmp6_nodeinfo {
#define NI_QTYPE_NOOP 0 /* NOOP */
#define NI_QTYPE_SUPTYPES 1 /* Supported Qtypes */
#define NI_QTYPE_FQDN 2 /* FQDN */
#define NI_QTYPE_NODEADDR 3 /* Node Addresses. XXX: spec says 2, but it may be a typo... */
#define NI_QTYPE_FQDN 2 /* FQDN (draft 04) */
#define NI_QTYPE_DNSNAME 2 /* DNS Name */
#define NI_QTYPE_NODEADDR 3 /* Node Addresses */
#define NI_QTYPE_IPV4ADDR 4 /* IPv4 Addresses */
#if BYTE_ORDER == BIG_ENDIAN
#define NI_SUPTYPE_FLAG_COMPRESS 0x1
@ -371,7 +398,7 @@ struct ni_reply_fqdn {
u_int32_t ni_fqdn_ttl; /* TTL */
u_int8_t ni_fqdn_namelen; /* length in octets of the FQDN */
u_int8_t ni_fqdn_name[3]; /* XXX: alignment */
};
} __attribute__((__packed__));
/*
* Router Renumbering. as router-renum-08.txt
@ -382,13 +409,13 @@ struct icmp6_router_renum { /* router renumbering header */
u_int8_t rr_flags;
u_int16_t rr_maxdelay;
u_int32_t rr_reserved;
};
#define ICMP6_RR_FLAGS_SEGNUM 0x80
#define ICMP6_RR_FLAGS_TEST 0x40
#define ICMP6_RR_FLAGS_REQRESULT 0x20
#define ICMP6_RR_FLAGS_FORCEAPPLY 0x10
#define ICMP6_RR_FLAGS_SPECSITE 0x08
#define ICMP6_RR_FLAGS_PREVDONE 0x04
} __attribute__((__packed__));
#define ICMP6_RR_FLAGS_TEST 0x80
#define ICMP6_RR_FLAGS_REQRESULT 0x40
#define ICMP6_RR_FLAGS_FORCEAPPLY 0x20
#define ICMP6_RR_FLAGS_SPECSITE 0x10
#define ICMP6_RR_FLAGS_PREVDONE 0x08
#define rr_type rr_hdr.icmp6_type
#define rr_code rr_hdr.icmp6_code
@ -404,7 +431,7 @@ struct rr_pco_match { /* match prefix part */
u_int8_t rpm_maxlen;
u_int16_t rpm_reserved;
struct in6_addr rpm_prefix;
};
} __attribute__((__packed__));
#define RPM_PCO_ADD 1
#define RPM_PCO_CHANGE 2
@ -420,7 +447,7 @@ struct rr_pco_use { /* use prefix part */
u_int32_t rpu_pltime;
u_int32_t rpu_flags;
struct in6_addr rpu_prefix;
};
} __attribute__((__packed__));
#define ICMP6_RR_PCOUSE_RAFLAGS_ONLINK 0x80
#define ICMP6_RR_PCOUSE_RAFLAGS_AUTO 0x40
@ -438,13 +465,13 @@ struct rr_result { /* router renumbering result message */
u_int8_t rrr_matchedlen;
u_int32_t rrr_ifid;
struct in6_addr rrr_prefix;
};
} __attribute__((__packed__));
#if BYTE_ORDER == BIG_ENDIAN
#define ICMP6_RR_RESULT_FLAGS_OOB 0x0002
#define ICMP6_RR_RESULT_FLAGS_FORBIDDEN 0x0001
#elif BYTE_ORDER == LITTLE_ENDIAN
#define ICMP6_RR_RESULT_FLAGS_OOB 0x02
#define ICMP6_RR_RESULT_FLAGS_FORBIDDEN 0x01
#define ICMP6_RR_RESULT_FLAGS_OOB 0x0200
#define ICMP6_RR_RESULT_FLAGS_FORBIDDEN 0x0100
#endif
/*
@ -534,6 +561,13 @@ struct icmp6stat {
#define icp6s_oparamprob_option icp6s_outerrhist.icp6errs_paramprob_option
#define icp6s_oredirect icp6s_outerrhist.icp6errs_redirect
#define icp6s_ounknown icp6s_outerrhist.icp6errs_unknown
u_quad_t icp6s_pmtuchg; /* path MTU changes */
u_quad_t icp6s_nd_badopt; /* bad ND options */
u_quad_t icp6s_badns; /* bad neighbor solicitation */
u_quad_t icp6s_badna; /* bad neighbor advertisement */
u_quad_t icp6s_badrs; /* bad router advertisement */
u_quad_t icp6s_badra; /* bad router advertisement */
u_quad_t icp6s_badredirect; /* bad redirect message */
};
/*
@ -542,7 +576,9 @@ struct icmp6stat {
#define ICMPV6CTL_STATS 1
#define ICMPV6CTL_REDIRACCEPT 2 /* accept/process redirects */
#define ICMPV6CTL_REDIRTIMEOUT 3 /* redirect cache time */
#if 0 /*obsoleted*/
#define ICMPV6CTL_ERRRATELIMIT 5 /* ICMPv6 error rate limitation */
#endif
#define ICMPV6CTL_ND6_PRUNE 6
#define ICMPV6CTL_ND6_DELAY 8
#define ICMPV6CTL_ND6_UMAXTRIES 9
@ -552,7 +588,12 @@ struct icmp6stat {
#define ICMPV6CTL_NODEINFO 13
#define ICMPV6CTL_ERRPPSLIMIT 14 /* ICMPv6 error pps limitation */
#define ICMPV6CTL_ND6_MAXNUDHINT 15
#define ICMPV6CTL_MAXID 16
#define ICMPV6CTL_MTUDISC_HIWAT 16
#define ICMPV6CTL_MTUDISC_LOWAT 17
#define ICMPV6CTL_ND6_DEBUG 18
#define ICMPV6CTL_ND6_DRLIST 19
#define ICMPV6CTL_ND6_PRLIST 20
#define ICMPV6CTL_MAXID 21
#define ICMPV6CTL_NAMES { \
{ 0, 0 }, \
@ -560,7 +601,7 @@ struct icmp6stat {
{ "rediraccept", CTLTYPE_INT }, \
{ "redirtimeout", CTLTYPE_INT }, \
{ 0, 0 }, \
{ "errratelimit", CTLTYPE_INT }, \
{ 0, 0 }, \
{ "nd6_prune", CTLTYPE_INT }, \
{ 0, 0 }, \
{ "nd6_delay", CTLTYPE_INT }, \
@ -571,6 +612,11 @@ struct icmp6stat {
{ "nodeinfo", CTLTYPE_INT }, \
{ "errppslimit", CTLTYPE_INT }, \
{ "nd6_maxnudhint", CTLTYPE_INT }, \
{ "mtudisc_hiwat", CTLTYPE_INT }, \
{ "mtudisc_lowat", CTLTYPE_INT }, \
{ "nd6_debug", CTLTYPE_INT }, \
{ 0, 0 }, \
{ 0, 0 }, \
}
#define RTF_PROBEMTU RTF_PROTO1
@ -591,6 +637,9 @@ void icmp6_prepare __P((struct mbuf *));
void icmp6_redirect_input __P((struct mbuf *, int));
void icmp6_redirect_output __P((struct mbuf *, struct rtentry *));
struct ip6ctlparam;
void icmp6_mtudisc_update __P((struct ip6ctlparam *, int));
/* XXX: is this the right place for these macros? */
#define icmp6_ifstat_inc(ifp, tag) \
do { \

View file

@ -51,11 +51,6 @@
#include <netinet/igmp_var.h>
#include "gif.h"
#if NGIF > 0
#include <net/if_gif.h>
#endif
static MALLOC_DEFINE(M_IPMADDR, "in_multi", "internet multicast address");
static int in_mask2len __P((struct in_addr *));
@ -200,21 +195,6 @@ in_control(so, cmd, data, ifp, p)
int error, hostIsNew, maskIsNew, s;
u_long i;
#if NGIF > 0
if (ifp && ifp->if_type == IFT_GIF) {
switch (cmd) {
case SIOCSIFPHYADDR:
case SIOCDIFPHYADDR:
if (p &&
(error = suser(p)) != 0)
return(error);
case SIOCGIFPSRCADDR:
case SIOCGIFPDSTADDR:
return gif_ioctl(ifp, cmd, data);
}
}
#endif
switch (cmd) {
case SIOCALIFADDR:
case SIOCDLIFADDR:
@ -713,6 +693,9 @@ in_ifinit(ifp, ia, sin, scrub)
}
if ((error = rtinit(&(ia->ia_ifa), (int)RTM_ADD, flags)) == 0)
ia->ia_flags |= IFA_ROUTE;
/* XXX check if the subnet route points to the same interface */
if (error == EEXIST)
error = 0;
/*
* If the interface supports multicast, join the "all hosts"

View file

@ -1,5 +1,5 @@
/* $FreeBSD$ */
/* $KAME: in_gif.c,v 1.44 2000/08/15 07:24:24 itojun Exp $ */
/* $KAME: in_gif.c,v 1.54 2001/05/14 14:02:16 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -88,7 +88,7 @@ in_gif_output(ifp, family, m, rt)
struct mbuf *m;
struct rtentry *rt;
{
register struct gif_softc *sc = (struct gif_softc*)ifp;
struct gif_softc *sc = (struct gif_softc*)ifp;
struct sockaddr_in *dst = (struct sockaddr_in *)&sc->gif_ro.ro_dst;
struct sockaddr_in *sin_src = (struct sockaddr_in *)sc->gif_psrc;
struct sockaddr_in *sin_dst = (struct sockaddr_in *)sc->gif_pdst;
@ -146,29 +146,12 @@ in_gif_output(ifp, family, m, rt)
bzero(&iphdr, sizeof(iphdr));
iphdr.ip_src = sin_src->sin_addr;
if (ifp->if_flags & IFF_LINK0) {
/* multi-destination mode */
if (sin_dst->sin_addr.s_addr != INADDR_ANY)
iphdr.ip_dst = sin_dst->sin_addr;
else if (rt) {
if (family != AF_INET) {
m_freem(m);
return EINVAL; /*XXX*/
}
iphdr.ip_dst = ((struct sockaddr_in *)
(rt->rt_gateway))->sin_addr;
} else {
m_freem(m);
return ENETUNREACH;
}
} else {
/* bidirectional configured tunnel mode */
if (sin_dst->sin_addr.s_addr != INADDR_ANY)
iphdr.ip_dst = sin_dst->sin_addr;
else {
m_freem(m);
return ENETUNREACH;
}
/* bidirectional configured tunnel mode */
if (sin_dst->sin_addr.s_addr != INADDR_ANY)
iphdr.ip_dst = sin_dst->sin_addr;
else {
m_freem(m);
return ENETUNREACH;
}
iphdr.ip_p = proto;
/* version will be set in ip_output() */
@ -176,6 +159,8 @@ in_gif_output(ifp, family, m, rt)
iphdr.ip_len = m->m_pkthdr.len + sizeof(struct ip);
if (ifp->if_flags & IFF_LINK1)
ip_ecn_ingress(ECN_ALLOWED, &iphdr.ip_tos, &tos);
else
ip_ecn_ingress(ECN_NOCARE, &iphdr.ip_tos, &tos);
/* prepend new IP header */
M_PREPEND(m, sizeof(struct ip), M_DONTWAIT);
@ -272,6 +257,8 @@ in_gif_input(m, va_alist)
ip = mtod(m, struct ip *);
if (gifp->if_flags & IFF_LINK1)
ip_ecn_egress(ECN_ALLOWED, &otos, &ip->ip_tos);
else
ip_ecn_egress(ECN_NOCARE, &otos, &ip->ip_tos);
break;
}
#endif
@ -290,6 +277,8 @@ in_gif_input(m, va_alist)
itos = (ntohl(ip6->ip6_flow) >> 20) & 0xff;
if (gifp->if_flags & IFF_LINK1)
ip_ecn_egress(ECN_ALLOWED, &otos, &itos);
else
ip_ecn_egress(ECN_NOCARE, &otos, &itos);
ip6->ip6_flow &= ~htonl(0xff << 20);
ip6->ip6_flow |= htonl((u_int32_t)itos << 20);
break;
@ -335,10 +324,6 @@ gif_encapcheck4(m, off, proto, arg)
addrmatch |= 1;
if (dst->sin_addr.s_addr == ip.ip_src.s_addr)
addrmatch |= 2;
else if ((sc->gif_if.if_flags & IFF_LINK0) != 0 &&
dst->sin_addr.s_addr == INADDR_ANY) {
addrmatch |= 2; /* we accept any source */
}
if (addrmatch != 3)
return 0;
@ -359,7 +344,8 @@ gif_encapcheck4(m, off, proto, arg)
}
/* ingress filters on outer source */
if ((m->m_flags & M_PKTHDR) != 0 && m->m_pkthdr.rcvif) {
if ((sc->gif_if.if_flags & IFF_LINK2) == 0 &&
(m->m_flags & M_PKTHDR) != 0 && m->m_pkthdr.rcvif) {
struct sockaddr_in sin;
struct rtentry *rt;
@ -368,15 +354,18 @@ gif_encapcheck4(m, off, proto, arg)
sin.sin_len = sizeof(struct sockaddr_in);
sin.sin_addr = ip.ip_src;
rt = rtalloc1((struct sockaddr *)&sin, 0, 0UL);
if (!rt)
return 0;
if (rt->rt_ifp != m->m_pkthdr.rcvif) {
rtfree(rt);
if (!rt || rt->rt_ifp != m->m_pkthdr.rcvif) {
#if 0
log(LOG_WARNING, "%s: packet from 0x%x dropped "
"due to ingress filter\n", if_name(&sc->gif_if),
(u_int32_t)ntohl(sin.sin_addr.s_addr));
#endif
if (rt)
rtfree(rt);
return 0;
}
rtfree(rt);
}
/* prioritize: IFF_LINK0 mode is less preferred */
return (sc->gif_if.if_flags & IFF_LINK0) ? 32 : 32 * 2;
return 32 * 2;
}

View file

@ -151,14 +151,16 @@ in_pcballoc(so, pcbinfo, p)
inp->inp_pcbinfo = pcbinfo;
inp->inp_socket = so;
#if defined(INET6)
if (ip6_mapped_addr_on)
inp->inp_flags &= ~IN6P_BINDV6ONLY;
else
inp->inp_flags |= IN6P_BINDV6ONLY;
if (INP_SOCKAF(so) == AF_INET6 && !ip6_mapped_addr_on)
inp->inp_flags |= IN6P_IPV6_V6ONLY;
#endif
LIST_INSERT_HEAD(pcbinfo->listhead, inp, inp_list);
pcbinfo->ipi_count++;
so->so_pcb = (caddr_t)inp;
#ifdef INET6
if (ip6_auto_flowlabel)
inp->inp_flags |= IN6P_AUTOFLOWLABEL;
#endif
return (0);
}
@ -234,9 +236,7 @@ in_pcbbind(inp, nam, p)
(so->so_cred->cr_uid !=
t->inp_socket->so_cred->cr_uid)) {
#if defined(INET6)
if ((inp->inp_flags &
IN6P_BINDV6ONLY) != 0 ||
ntohl(sin->sin_addr.s_addr) !=
if (ntohl(sin->sin_addr.s_addr) !=
INADDR_ANY ||
ntohl(t->inp_laddr.s_addr) !=
INADDR_ANY ||
@ -254,8 +254,7 @@ in_pcbbind(inp, nam, p)
if (t &&
(reuseport & t->inp_socket->so_options) == 0) {
#if defined(INET6)
if ((inp->inp_flags & IN6P_BINDV6ONLY) != 0 ||
ntohl(sin->sin_addr.s_addr) !=
if (ntohl(sin->sin_addr.s_addr) !=
INADDR_ANY ||
ntohl(t->inp_laddr.s_addr) !=
INADDR_ANY ||

View file

@ -226,25 +226,27 @@ struct inpcbinfo { /* XXX documentation, prefixes */
#define INP_RECVIF 0x80 /* receive incoming interface */
#define INP_MTUDISC 0x100 /* user can do MTU discovery */
#define INP_FAITH 0x200 /* accept FAITH'ed connections */
#define IN6P_PKTINFO 0x010000
#define IN6P_HOPLIMIT 0x020000
#define IN6P_NEXTHOP 0x040000
#define IN6P_HOPOPTS 0x080000
#define IN6P_DSTOPTS 0x100000
#define IN6P_RTHDR 0x200000
#define IN6P_BINDV6ONLY 0x400000
#define IN6P_IPV6_V6ONLY 0x008000 /* restrict AF_INET6 socket for v6 */
#define IN6P_PKTINFO 0x010000 /* receive IP6 dst and I/F */
#define IN6P_HOPLIMIT 0x020000 /* receive hoplimit */
#define IN6P_HOPOPTS 0x040000 /* receive hop-by-hop options */
#define IN6P_DSTOPTS 0x080000 /* receive dst options after rthdr */
#define IN6P_RTHDR 0x100000 /* receive routing header */
#define IN6P_RTHDRDSTOPTS 0x200000 /* receive dstoptions before rthdr */
#define IN6P_AUTOFLOWLABEL 0x800000 /* attach flowlabel automatically */
#define IN6P_BINDV6ONLY 0x10000000 /* do not grab IPv4 traffic */
#define INP_CONTROLOPTS (INP_RECVOPTS|INP_RECVRETOPTS|INP_RECVDSTADDR|\
INP_RECVIF|\
IN6P_PKTINFO|IN6P_HOPLIMIT|IN6P_NEXTHOP|\
IN6P_HOPOPTS|IN6P_DSTOPTS|IN6P_RTHDR)
#define INP_UNMAPPABLEOPTS (IN6P_HOPOPTS|IN6P_DSTOPTS|IN6P_RTHDR)
IN6P_PKTINFO|IN6P_HOPLIMIT|IN6P_HOPOPTS|\
IN6P_DSTOPTS|IN6P_RTHDR|IN6P_RTHDRDSTOPTS|\
IN6P_AUTOFLOWLABEL)
#define INP_UNMAPPABLEOPTS (IN6P_HOPOPTS|IN6P_DSTOPTS|IN6P_RTHDR|\
IN6P_AUTOFLOWLABEL)
/* for KAME src sync over BSD*'s */
#define IN6P_RECVOPTS INP_RECVOPTS
#define IN6P_RECVRETOPTS INP_RECVRETOPTS
#define IN6P_RECVDSTADDR INP_RECVDSTADDR
#define IN6P_HDRINCL INP_HDRINCL
#define IN6P_HIGHPORT INP_HIGHPORT
#define IN6P_LOWPORT INP_LOWPORT
#define IN6P_ANONPORT INP_ANONPORT

View file

@ -75,6 +75,7 @@
#ifdef IPSEC_ESP
#include <netinet6/esp.h>
#endif
#include <netinet6/ipcomp.h>
#endif /* IPSEC */
#include "gif.h"
@ -125,19 +126,19 @@ struct ipprotosw inetsw[] = {
0, 0, 0, 0,
&rip_usrreqs
},
{ SOCK_RAW, &inetdomain, IPPROTO_ICMP, PR_ATOMIC|PR_ADDR,
{ SOCK_RAW, &inetdomain, IPPROTO_ICMP, PR_ATOMIC|PR_ADDR|PR_LASTHDR,
icmp_input, 0, 0, rip_ctloutput,
0,
0, 0, 0, 0,
&rip_usrreqs
},
{ SOCK_RAW, &inetdomain, IPPROTO_IGMP, PR_ATOMIC|PR_ADDR,
{ SOCK_RAW, &inetdomain, IPPROTO_IGMP, PR_ATOMIC|PR_ADDR|PR_LASTHDR,
igmp_input, 0, 0, rip_ctloutput,
0,
igmp_init, igmp_fasttimo, igmp_slowtimo, 0,
&rip_usrreqs
},
{ SOCK_RAW, &inetdomain, IPPROTO_RSVP, PR_ATOMIC|PR_ADDR,
{ SOCK_RAW, &inetdomain, IPPROTO_RSVP, PR_ATOMIC|PR_ADDR|PR_LASTHDR,
rsvp_input, 0, 0, rip_ctloutput,
0,
0, 0, 0, 0,
@ -158,19 +159,25 @@ struct ipprotosw inetsw[] = {
&nousrreqs
},
#endif
{ SOCK_RAW, &inetdomain, IPPROTO_IPCOMP, PR_ATOMIC|PR_ADDR,
ipcomp4_input, 0, 0, 0,
0,
0, 0, 0, 0,
&nousrreqs
},
#endif /* IPSEC */
{ SOCK_RAW, &inetdomain, IPPROTO_IPV4, PR_ATOMIC|PR_ADDR,
{ SOCK_RAW, &inetdomain, IPPROTO_IPV4, PR_ATOMIC|PR_ADDR|PR_LASTHDR,
encap4_input, 0, 0, rip_ctloutput,
0,
encap_init, 0, 0, 0,
&nousrreqs
&rip_usrreqs
},
# ifdef INET6
{ SOCK_RAW, &inetdomain, IPPROTO_IPV6, PR_ATOMIC|PR_ADDR,
{ SOCK_RAW, &inetdomain, IPPROTO_IPV6, PR_ATOMIC|PR_ADDR|PR_LASTHDR,
encap4_input, 0, 0, rip_ctloutput,
0,
0, 0, 0, 0,
&nousrreqs
encap_init, 0, 0, 0,
&rip_usrreqs
},
#endif
#ifdef IPDIVERT
@ -182,7 +189,7 @@ struct ipprotosw inetsw[] = {
},
#endif
#ifdef IPXIP
{ SOCK_RAW, &inetdomain, IPPROTO_IDP, PR_ATOMIC|PR_ADDR,
{ SOCK_RAW, &inetdomain, IPPROTO_IDP, PR_ATOMIC|PR_ADDR|PR_LASTHDR,
ipxip_input, 0, ipxip_ctlinput, 0,
0,
0, 0, 0, 0,
@ -190,7 +197,7 @@ struct ipprotosw inetsw[] = {
},
#endif
#ifdef NSIP
{ SOCK_RAW, &inetdomain, IPPROTO_IDP, PR_ATOMIC|PR_ADDR,
{ SOCK_RAW, &inetdomain, IPPROTO_IDP, PR_ATOMIC|PR_ADDR|PR_LASTHDR,
idpip_input, 0, nsip_ctlinput, 0,
0,
0, 0, 0, 0,

View file

@ -1,5 +1,5 @@
/* $FreeBSD$ */
/* $KAME: ip6.h,v 1.9 2000/07/02 21:01:32 itojun Exp $ */
/* $KAME: ip6.h,v 1.18 2001/03/29 05:34:30 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -85,7 +85,7 @@ struct ip6_hdr {
} ip6_ctlun;
struct in6_addr ip6_src; /* source address */
struct in6_addr ip6_dst; /* destination address */
};
} __attribute__((__packed__));
#define ip6_vfc ip6_ctlun.ip6_un2_vfc
#define ip6_flow ip6_ctlun.ip6_un1.ip6_un1_flow
@ -106,18 +106,20 @@ struct ip6_hdr {
#define IPV6_FLOWLABEL_MASK 0xffff0f00 /* flow label (20 bits) */
#endif /* LITTLE_ENDIAN */
#endif
#if 1
/* ECN bits proposed by Sally Floyd */
#define IP6TOS_CE 0x01 /* congestion experienced */
#define IP6TOS_ECT 0x02 /* ECN-capable transport */
#endif
/*
* Extension Headers
*/
struct ip6_ext {
u_char ip6e_nxt;
u_char ip6e_len;
};
u_int8_t ip6e_nxt;
u_int8_t ip6e_len;
} __attribute__((__packed__));
/* Hop-by-Hop options header */
/* XXX should we pad it to force alignment on an 8-byte boundary? */
@ -125,7 +127,7 @@ struct ip6_hbh {
u_int8_t ip6h_nxt; /* next header */
u_int8_t ip6h_len; /* length in units of 8 octets */
/* followed by options */
};
} __attribute__((__packed__));
/* Destination options header */
/* XXX should we pad it to force alignment on an 8-byte boundary? */
@ -133,20 +135,28 @@ struct ip6_dest {
u_int8_t ip6d_nxt; /* next header */
u_int8_t ip6d_len; /* length in units of 8 octets */
/* followed by options */
};
} __attribute__((__packed__));
/* Option types and related macros */
#define IP6OPT_PAD1 0x00 /* 00 0 00000 */
#define IP6OPT_PADN 0x01 /* 00 0 00001 */
#define IP6OPT_JUMBO 0xC2 /* 11 0 00010 = 194 */
#define IP6OPT_JUMBO_LEN 6
#define IP6OPT_RTALERT 0x05 /* 00 0 00101 */
#define IP6OPT_NSAP_ADDR 0xC3 /* 11 0 00011 */
#define IP6OPT_TUNNEL_LIMIT 0x04 /* 00 0 00100 */
#define IP6OPT_RTALERT 0x05 /* 00 0 00101 (KAME definition) */
#define IP6OPT_RTALERT_LEN 4
#define IP6OPT_RTALERT_MLD 0 /* Datagram contains an MLD message */
#define IP6OPT_RTALERT_RSVP 1 /* Datagram contains an RSVP message */
#define IP6OPT_RTALERT_ACTNET 2 /* contains an Active Networks msg */
#define IP6OPT_MINLEN 2
#define IP6OPT_BINDING_UPDATE 0xc6 /* 11 0 00110 */
#define IP6OPT_BINDING_ACK 0x07 /* 00 0 00111 */
#define IP6OPT_BINDING_REQ 0x08 /* 00 0 01000 */
#define IP6OPT_HOME_ADDRESS 0xc9 /* 11 0 01001 */
#define IP6OPT_EID 0x8a /* 10 0 01010 */
#define IP6OPT_TYPE(o) ((o) & 0xC0)
#define IP6OPT_TYPE_SKIP 0x00
#define IP6OPT_TYPE_DISCARD 0x40
@ -155,6 +165,8 @@ struct ip6_dest {
#define IP6OPT_MUTABLE 0x20
#define IP6OPT_JUMBO_LEN 6
/* Routing header */
struct ip6_rthdr {
u_int8_t ip6r_nxt; /* next header */
@ -162,7 +174,7 @@ struct ip6_rthdr {
u_int8_t ip6r_type; /* routing type */
u_int8_t ip6r_segleft; /* segments left */
/* followed by routing type specific data */
};
} __attribute__((__packed__));
/* Type 0 Routing header */
struct ip6_rthdr0 {
@ -173,7 +185,7 @@ struct ip6_rthdr0 {
u_int8_t ip6r0_reserved; /* reserved field */
u_int8_t ip6r0_slmap[3]; /* strict/loose bit map */
struct in6_addr ip6r0_addr[1]; /* up to 23 addresses */
};
} __attribute__((__packed__));
/* Fragment header */
struct ip6_frag {
@ -181,7 +193,7 @@ struct ip6_frag {
u_int8_t ip6f_reserved; /* reserved field */
u_int16_t ip6f_offlg; /* offset, reserved, and flag */
u_int32_t ip6f_ident; /* identification */
};
} __attribute__((__packed__));
#if BYTE_ORDER == BIG_ENDIAN
#define IP6F_OFF_MASK 0xfff8 /* mask out offset from _offlg */

View file

@ -1,5 +1,5 @@
/* $FreeBSD$ */
/* $KAME: ip_ecn.c,v 1.7 2000/05/05 11:00:56 sumikawa Exp $ */
/* $KAME: ip_ecn.c,v 1.11 2001/05/03 16:09:29 itojun Exp $ */
/*
* Copyright (C) 1999 WIDE Project.
@ -43,16 +43,10 @@
#include <sys/mbuf.h>
#include <sys/errno.h>
#ifdef INET
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#endif
#ifdef INET6
#ifndef INET
#include <netinet/in.h>
#endif
#include <netinet/ip6.h>
#endif
@ -63,17 +57,17 @@
/*
* modify outer ECN (TOS) field on ingress operation (tunnel encapsulation).
* call it after you've done the default initialization/copy for the outer.
*/
void
ip_ecn_ingress(mode, outer, inner)
int mode;
u_int8_t *outer;
u_int8_t *inner;
const u_int8_t *inner;
{
if (!outer || !inner)
panic("NULL pointer passed to ip_ecn_ingress");
*outer = *inner;
switch (mode) {
case ECN_ALLOWED: /* ECN allowed */
*outer &= ~IPTOS_CE;
@ -88,12 +82,11 @@ ip_ecn_ingress(mode, outer, inner)
/*
* modify inner ECN (TOS) field on egress operation (tunnel decapsulation).
* call it after you've done the default initialization/copy for the inner.
*/
void
ip_ecn_egress(mode, outer, inner)
int mode;
u_int8_t *outer;
const u_int8_t *outer;
u_int8_t *inner;
{
if (!outer || !inner)
@ -115,14 +108,13 @@ void
ip6_ecn_ingress(mode, outer, inner)
int mode;
u_int32_t *outer;
u_int32_t *inner;
const u_int32_t *inner;
{
u_int8_t outer8, inner8;
if (!outer || !inner)
panic("NULL pointer passed to ip6_ecn_ingress");
outer8 = (ntohl(*outer) >> 20) & 0xff;
inner8 = (ntohl(*inner) >> 20) & 0xff;
ip_ecn_ingress(mode, &outer8, &inner8);
*outer &= ~htonl(0xff << 20);
@ -132,7 +124,7 @@ ip6_ecn_ingress(mode, outer, inner)
void
ip6_ecn_egress(mode, outer, inner)
int mode;
u_int32_t *outer;
const u_int32_t *outer;
u_int32_t *inner;
{
u_int8_t outer8, inner8;
@ -141,7 +133,6 @@ ip6_ecn_egress(mode, outer, inner)
panic("NULL pointer passed to ip6_ecn_egress");
outer8 = (ntohl(*outer) >> 20) & 0xff;
inner8 = (ntohl(*inner) >> 20) & 0xff;
ip_ecn_egress(mode, &outer8, &inner8);
*inner &= ~htonl(0xff << 20);
*inner |= htonl((u_int32_t)inner8 << 20);

View file

@ -1,5 +1,5 @@
/* $FreeBSD$ */
/* $KAME: ip_ecn.h,v 1.5 2000/03/27 04:58:38 sumikawa Exp $ */
/* $KAME: ip_ecn.h,v 1.6 2001/05/03 14:51:48 itojun Exp $ */
/*
* Copyright (C) 1999 WIDE Project.
@ -35,11 +35,15 @@
* http://www.aciri.org/floyd/papers/draft-ipsec-ecn-00.txt
*/
#if defined(_KERNEL) && !defined(_LKM)
#include "opt_inet.h"
#endif
#define ECN_ALLOWED 1 /* ECN allowed */
#define ECN_FORBIDDEN 0 /* ECN forbidden */
#define ECN_NOCARE (-1) /* no consideration to ECN */
#ifdef _KERNEL
extern void ip_ecn_ingress __P((int, u_int8_t *, u_int8_t *));
extern void ip_ecn_egress __P((int, u_int8_t *, u_int8_t *));
extern void ip_ecn_ingress __P((int, u_int8_t *, const u_int8_t *));
extern void ip_ecn_egress __P((int, const u_int8_t *, u_int8_t *));
#endif

View file

@ -1,5 +1,5 @@
/* $FreeBSD$ */
/* $KAME: ip_encap.c,v 1.36 2000/06/17 20:34:24 itojun Exp $ */
/* $KAME: ip_encap.c,v 1.41 2001/03/15 08:35:08 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -67,6 +67,7 @@
#include <sys/mbuf.h>
#include <sys/errno.h>
#include <sys/protosw.h>
#include <sys/queue.h>
#include <net/if.h>
#include <net/route.h>
@ -100,12 +101,21 @@ static int mask_match __P((const struct encaptab *, const struct sockaddr *,
const struct sockaddr *));
static void encap_fillarg __P((struct mbuf *, const struct encaptab *));
#ifndef LIST_HEAD_INITIALIZER
/* rely upon BSS initialization */
LIST_HEAD(, encaptab) encaptab;
#else
LIST_HEAD(, encaptab) encaptab = LIST_HEAD_INITIALIZER(&encaptab);
#endif
void
encap_init()
{
static int initialized = 0;
if (initialized)
return;
initialized++;
#if 0
/*
* we cannot use LIST_INIT() here, since drivers may want to call
@ -118,6 +128,7 @@ encap_init()
#endif
}
#ifdef INET
void
#if __STDC__
encap4_input(struct mbuf *m, ...)
@ -221,6 +232,7 @@ encap4_input(m, va_alist)
/* last resort: inject to raw socket */
rip_input(m, off, proto);
}
#endif
#ifdef INET6
int

View file

@ -296,15 +296,6 @@ icmp_input(m, off, proto)
icp->icmp_code);
#endif
#ifdef IPSEC
/* drop it if it does not match the policy */
/* XXX Is there meaning of check in here ? */
if (ipsec4_in_reject(m, NULL)) {
ipsecstat.in_polvio++;
goto freeit;
}
#endif
/*
* Message type specific processing.
*/

View file

@ -350,6 +350,16 @@ ip_input(struct mbuf *m)
}
ip = mtod(m, struct ip *);
}
/* 127/8 must not appear on wire - RFC1122 */
if ((ntohl(ip->ip_dst.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET ||
(ntohl(ip->ip_src.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET) {
if ((m->m_pkthdr.rcvif->if_flags & IFF_LOOPBACK) == 0) {
ipstat.ips_badaddr++;
goto bad;
}
}
if (m->m_pkthdr.csum_flags & CSUM_IP_CHECKED) {
sum = !(m->m_pkthdr.csum_flags & CSUM_IP_VALID);
} else {
@ -393,15 +403,10 @@ ip_input(struct mbuf *m)
m_adj(m, ip->ip_len - m->m_pkthdr.len);
}
/*
* Don't accept packets with a loopback destination address
* unless they arrived via the loopback interface.
*/
if ((ntohl(ip->ip_dst.s_addr) & IN_CLASSA_NET) ==
(IN_LOOPBACKNET << IN_CLASSA_NSHIFT) &&
(m->m_pkthdr.rcvif->if_flags & IFF_LOOPBACK) == 0) {
goto bad;
}
#ifdef IPSEC
if (ipsec_gethist(m, NULL))
goto pass;
#endif
/*
* IpHack's section.
@ -796,6 +801,19 @@ ip_input(struct mbuf *m)
}
#endif
#ifdef IPSEC
/*
* enforce IPsec policy checking if we are seeing last header.
* note that we do not visit this with protocols with pcb layer
* code - like udp/tcp/raw ip.
*/
if ((inetsw[ip_protox[ip->ip_p]].pr_flags & PR_LASTHDR) != 0 &&
ipsec4_in_reject(m, NULL)) {
ipsecstat.in_polvio++;
goto bad;
}
#endif
/*
* Switch out to protocol's input routine.
*/
@ -1189,6 +1207,10 @@ ip_dooptions(m)
*/
case IPOPT_LSRR:
case IPOPT_SSRR:
if (optlen < IPOPT_OFFSET + sizeof(*cp)) {
code = &cp[IPOPT_OLEN] - (u_char *)ip;
goto bad;
}
if ((off = cp[IPOPT_OFFSET]) < IPOPT_MINOFF) {
code = &cp[IPOPT_OFFSET] - (u_char *)ip;
goto bad;
@ -1308,12 +1330,21 @@ ip_dooptions(m)
case IPOPT_TS:
code = cp - (u_char *)ip;
ipt = (struct ip_timestamp *)cp;
if (ipt->ipt_len < 5)
if (ipt->ipt_len < 4 || ipt->ipt_len > 40) {
code = (u_char *)&ipt->ipt_len - (u_char *)ip;
goto bad;
}
if (ipt->ipt_ptr < 5) {
code = (u_char *)&ipt->ipt_ptr - (u_char *)ip;
goto bad;
}
if (ipt->ipt_ptr >
ipt->ipt_len - (int)sizeof(int32_t)) {
if (++ipt->ipt_oflw == 0)
if (++ipt->ipt_oflw == 0) {
code = (u_char *)&ipt->ipt_ptr -
(u_char *)ip;
goto bad;
}
break;
}
sin = (struct in_addr *)(cp + ipt->ipt_ptr - 1);
@ -1324,8 +1355,11 @@ ip_dooptions(m)
case IPOPT_TS_TSANDADDR:
if (ipt->ipt_ptr - 1 + sizeof(n_time) +
sizeof(struct in_addr) > ipt->ipt_len)
sizeof(struct in_addr) > ipt->ipt_len) {
code = (u_char *)&ipt->ipt_ptr -
(u_char *)ip;
goto bad;
}
ipaddr.sin_addr = dst;
ia = (INA)ifaof_ifpforaddr((SA)&ipaddr,
m->m_pkthdr.rcvif);
@ -1338,8 +1372,11 @@ ip_dooptions(m)
case IPOPT_TS_PRESPEC:
if (ipt->ipt_ptr - 1 + sizeof(n_time) +
sizeof(struct in_addr) > ipt->ipt_len)
sizeof(struct in_addr) > ipt->ipt_len) {
code = (u_char *)&ipt->ipt_ptr -
(u_char *)ip;
goto bad;
}
(void)memcpy(&ipaddr.sin_addr, sin,
sizeof(struct in_addr));
if (ifa_ifwithaddr((SA)&ipaddr) == 0)
@ -1348,6 +1385,9 @@ ip_dooptions(m)
break;
default:
/* XXX can't take &ipt->ipt_flg */
code = (u_char *)&ipt->ipt_ptr -
(u_char *)ip + 1;
goto bad;
}
ntime = iptime();

View file

@ -95,6 +95,7 @@ static MALLOC_DEFINE(M_IPMOPTS, "ip_moptions", "internet multicast options");
u_short ip_id;
static struct mbuf *ip_insertoptions __P((struct mbuf *, struct mbuf *, int *));
static struct ifnet *ip_multicast_if __P((struct in_addr *, int *));
static void ip_mloopback
__P((struct ifnet *, struct mbuf *, struct sockaddr_in *, int));
static int ip_getmoptions
@ -177,7 +178,7 @@ ip_output(m0, opt, ro, flags, imo)
m0 = m = m->m_next ;
#ifdef IPSEC
so = ipsec_getsocket(m);
ipsec_setsocket(m, NULL);
(void)ipsec_setsocket(m, NULL);
#endif
ip = mtod(m, struct ip *);
hlen = IP_VHL_HL(ip->ip_vhl) << 2 ;
@ -188,7 +189,7 @@ ip_output(m0, opt, ro, flags, imo)
#endif
#ifdef IPSEC
so = ipsec_getsocket(m);
ipsec_setsocket(m, NULL);
(void)ipsec_setsocket(m, NULL);
#endif
#ifdef DIAGNOSTIC
@ -430,6 +431,133 @@ ip_output(m0, opt, ro, flags, imo)
}
sendit:
#ifdef IPSEC
/* get SP for this packet */
if (so == NULL)
sp = ipsec4_getpolicybyaddr(m, IPSEC_DIR_OUTBOUND, flags, &error);
else
sp = ipsec4_getpolicybysock(m, IPSEC_DIR_OUTBOUND, so, &error);
if (sp == NULL) {
ipsecstat.out_inval++;
goto bad;
}
error = 0;
/* check policy */
switch (sp->policy) {
case IPSEC_POLICY_DISCARD:
/*
* This packet is just discarded.
*/
ipsecstat.out_polvio++;
goto bad;
case IPSEC_POLICY_BYPASS:
case IPSEC_POLICY_NONE:
/* no need to do IPsec. */
goto skip_ipsec;
case IPSEC_POLICY_IPSEC:
if (sp->req == NULL) {
/* acquire a policy */
error = key_spdacquire(sp);
goto bad;
}
break;
case IPSEC_POLICY_ENTRUST:
default:
printf("ip_output: Invalid policy found. %d\n", sp->policy);
}
{
struct ipsec_output_state state;
bzero(&state, sizeof(state));
state.m = m;
if (flags & IP_ROUTETOIF) {
state.ro = &iproute;
bzero(&iproute, sizeof(iproute));
} else
state.ro = ro;
state.dst = (struct sockaddr *)dst;
ip->ip_sum = 0;
/*
* XXX
* delayed checksums are not currently compatible with IPsec
*/
if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA) {
in_delayed_cksum(m);
m->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA;
}
HTONS(ip->ip_len);
HTONS(ip->ip_off);
error = ipsec4_output(&state, sp, flags);
m = state.m;
if (flags & IP_ROUTETOIF) {
/*
* if we have tunnel mode SA, we may need to ignore
* IP_ROUTETOIF.
*/
if (state.ro != &iproute || state.ro->ro_rt != NULL) {
flags &= ~IP_ROUTETOIF;
ro = state.ro;
}
} else
ro = state.ro;
dst = (struct sockaddr_in *)state.dst;
if (error) {
/* mbuf is already reclaimed in ipsec4_output. */
m0 = NULL;
switch (error) {
case EHOSTUNREACH:
case ENETUNREACH:
case EMSGSIZE:
case ENOBUFS:
case ENOMEM:
break;
default:
printf("ip4_output (ipsec): error code %d\n", error);
/*fall through*/
case ENOENT:
/* don't show these error codes to the user */
error = 0;
break;
}
goto bad;
}
}
/* be sure to update variables that are affected by ipsec4_output() */
ip = mtod(m, struct ip *);
#ifdef _IP_VHL
hlen = IP_VHL_HL(ip->ip_vhl) << 2;
#else
hlen = ip->ip_hl << 2;
#endif
if (ro->ro_rt == NULL) {
if ((flags & IP_ROUTETOIF) == 0) {
printf("ip_output: "
"can't update route after IPsec processing\n");
error = EHOSTUNREACH; /*XXX*/
goto bad;
}
} else {
ia = ifatoia(ro->ro_rt->rt_ifa);
ifp = ro->ro_rt->rt_ifp;
}
/* make it flipped, again. */
NTOHS(ip->ip_len);
NTOHS(ip->ip_off);
skip_ipsec:
#endif /*IPSEC*/
/*
* IpHack's section.
* - Xlate: translate packet's addr/port (NAT).
@ -661,134 +789,6 @@ ip_output(m0, opt, ro, flags, imo)
}
pass:
#ifdef IPSEC
/* get SP for this packet */
if (so == NULL)
sp = ipsec4_getpolicybyaddr(m, IPSEC_DIR_OUTBOUND, flags, &error);
else
sp = ipsec4_getpolicybysock(m, IPSEC_DIR_OUTBOUND, so, &error);
if (sp == NULL) {
ipsecstat.out_inval++;
goto bad;
}
error = 0;
/* check policy */
switch (sp->policy) {
case IPSEC_POLICY_DISCARD:
/*
* This packet is just discarded.
*/
ipsecstat.out_polvio++;
goto bad;
case IPSEC_POLICY_BYPASS:
case IPSEC_POLICY_NONE:
/* no need to do IPsec. */
goto skip_ipsec;
case IPSEC_POLICY_IPSEC:
if (sp->req == NULL) {
/* XXX should be panic ? */
printf("ip_output: No IPsec request specified.\n");
error = EINVAL;
goto bad;
}
break;
case IPSEC_POLICY_ENTRUST:
default:
printf("ip_output: Invalid policy found. %d\n", sp->policy);
}
{
struct ipsec_output_state state;
bzero(&state, sizeof(state));
state.m = m;
if (flags & IP_ROUTETOIF) {
state.ro = &iproute;
bzero(&iproute, sizeof(iproute));
} else
state.ro = ro;
state.dst = (struct sockaddr *)dst;
ip->ip_sum = 0;
/*
* XXX
* delayed checksums are not currently compatible with IPsec
*/
if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA) {
in_delayed_cksum(m);
m->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA;
}
HTONS(ip->ip_len);
HTONS(ip->ip_off);
error = ipsec4_output(&state, sp, flags);
m = state.m;
if (flags & IP_ROUTETOIF) {
/*
* if we have tunnel mode SA, we may need to ignore
* IP_ROUTETOIF.
*/
if (state.ro != &iproute || state.ro->ro_rt != NULL) {
flags &= ~IP_ROUTETOIF;
ro = state.ro;
}
} else
ro = state.ro;
dst = (struct sockaddr_in *)state.dst;
if (error) {
/* mbuf is already reclaimed in ipsec4_output. */
m0 = NULL;
switch (error) {
case EHOSTUNREACH:
case ENETUNREACH:
case EMSGSIZE:
case ENOBUFS:
case ENOMEM:
break;
default:
printf("ip4_output (ipsec): error code %d\n", error);
/*fall through*/
case ENOENT:
/* don't show these error codes to the user */
error = 0;
break;
}
goto bad;
}
}
/* be sure to update variables that are affected by ipsec4_output() */
ip = mtod(m, struct ip *);
#ifdef _IP_VHL
hlen = IP_VHL_HL(ip->ip_vhl) << 2;
#else
hlen = ip->ip_hl << 2;
#endif
if (ro->ro_rt == NULL) {
if ((flags & IP_ROUTETOIF) == 0) {
printf("ip_output: "
"can't update route after IPsec processing\n");
error = EHOSTUNREACH; /*XXX*/
goto bad;
}
} else {
ia = ifatoia(ro->ro_rt->rt_ifa);
ifp = ro->ro_rt->rt_ifp;
}
/* make it flipped, again. */
NTOHS(ip->ip_len);
NTOHS(ip->ip_off);
skip_ipsec:
#endif /*IPSEC*/
m->m_pkthdr.csum_flags |= CSUM_IP;
sw_csum = m->m_pkthdr.csum_flags & ~ifp->if_hwassist;
if (sw_csum & CSUM_DELAY_DATA) {
@ -820,6 +820,11 @@ ip_output(m0, opt, ro, flags, imo)
ia->ia_ifa.if_obytes += m->m_pkthdr.len;
}
#ifdef IPSEC
/* clean ipsec history once it goes out of the node */
ipsec_delaux(m);
#endif
error = (*ifp->if_output)(ifp, m,
(struct sockaddr *)dst, ro->ro_rt);
goto done;
@ -946,6 +951,10 @@ ip_output(m0, opt, ro, flags, imo)
for (m = m0; m; m = m0) {
m0 = m->m_nextpkt;
m->m_nextpkt = 0;
#ifdef IPSEC
/* clean ipsec history once it goes out of the node */
ipsec_delaux(m);
#endif
if (error == 0) {
/* Record statistics for this interface address. */
ia->ia_ifa.if_opackets++;
@ -1480,6 +1489,33 @@ ip_pcbopts(optname, pcbopt, m)
* transmission, and one (IP_MULTICAST_TTL) totally duplicates a
* standard option (IP_TTL).
*/
/*
* following RFC1724 section 3.3, 0.0.0.0/8 is interpreted as interface index.
*/
static struct ifnet *
ip_multicast_if(a, ifindexp)
struct in_addr *a;
int *ifindexp;
{
int ifindex;
struct ifnet *ifp;
if (ifindexp)
*ifindexp = 0;
if (ntohl(a->s_addr) >> 24 == 0) {
ifindex = ntohl(a->s_addr) & 0xffffff;
if (ifindex < 0 || if_index < ifindex)
return NULL;
ifp = ifindex2ifnet[ifindex];
if (ifindexp)
*ifindexp = ifindex;
} else {
INADDR_TO_IFP(*a, ifp);
}
return ifp;
}
/*
* Set the IP multicast options in response to user setsockopt().
*/
@ -1496,6 +1532,7 @@ ip_setmoptions(sopt, imop)
struct ip_moptions *imo = *imop;
struct route ro;
struct sockaddr_in *dst;
int ifindex;
int s;
if (imo == NULL) {
@ -1510,6 +1547,7 @@ ip_setmoptions(sopt, imop)
return (ENOBUFS);
*imop = imo;
imo->imo_multicast_ifp = NULL;
imo->imo_multicast_addr.s_addr = INADDR_ANY;
imo->imo_multicast_vif = -1;
imo->imo_multicast_ttl = IP_DEFAULT_MULTICAST_TTL;
imo->imo_multicast_loop = IP_DEFAULT_MULTICAST_LOOP;
@ -1555,13 +1593,17 @@ ip_setmoptions(sopt, imop)
* it supports multicasting.
*/
s = splimp();
INADDR_TO_IFP(addr, ifp);
ifp = ip_multicast_if(&addr, &ifindex);
if (ifp == NULL || (ifp->if_flags & IFF_MULTICAST) == 0) {
splx(s);
error = EADDRNOTAVAIL;
break;
}
imo->imo_multicast_ifp = ifp;
if (ifindex)
imo->imo_multicast_addr = addr;
else
imo->imo_multicast_addr.s_addr = INADDR_ANY;
splx(s);
break;
@ -1648,7 +1690,7 @@ ip_setmoptions(sopt, imop)
rtfree(ro.ro_rt);
}
else {
INADDR_TO_IFP(mreq.imr_interface, ifp);
ifp = ip_multicast_if(&mreq.imr_interface, NULL);
}
/*
@ -1716,7 +1758,7 @@ ip_setmoptions(sopt, imop)
if (mreq.imr_interface.s_addr == INADDR_ANY)
ifp = NULL;
else {
INADDR_TO_IFP(mreq.imr_interface, ifp);
ifp = ip_multicast_if(&mreq.imr_interface, NULL);
if (ifp == NULL) {
error = EADDRNOTAVAIL;
splx(s);
@ -1798,7 +1840,10 @@ ip_getmoptions(sopt, imo)
case IP_MULTICAST_IF:
if (imo == NULL || imo->imo_multicast_ifp == NULL)
addr.s_addr = INADDR_ANY;
else {
else if (imo->imo_multicast_addr.s_addr) {
/* return the value user has set */
addr = imo->imo_multicast_addr;
} else {
IFP_TO_IA(imo->imo_multicast_ifp, ia);
addr.s_addr = (ia == NULL) ? INADDR_ANY
: IA_SIN(ia)->sin_addr.s_addr;

View file

@ -37,6 +37,8 @@
#ifndef _NETINET_IP_VAR_H_
#define _NETINET_IP_VAR_H_
#include <sys/queue.h>
/*
* Overlay for ip header used by other protocols (tcp, udp).
*/
@ -86,6 +88,7 @@ struct ipoption {
*/
struct ip_moptions {
struct ifnet *imo_multicast_ifp; /* ifp for outgoing multicasts */
struct in_addr imo_multicast_addr; /* ifindex/addr on MULTICAST_IF */
u_char imo_multicast_ttl; /* TTL for outgoing multicasts */
u_char imo_multicast_loop; /* 1 => hear sends if a member */
u_short imo_num_memberships; /* no. memberships this socket */
@ -122,6 +125,7 @@ struct ipstat {
u_long ips_toolong; /* ip length > max ip packet size */
u_long ips_notmember; /* multicasts for unregistered grps */
u_long ips_nogif; /* no match gif found */
u_long ips_badaddr; /* invalid address on header */
};
#ifdef _KERNEL

View file

@ -137,6 +137,15 @@ rip_input(m, off, proto)
continue;
if (last) {
struct mbuf *n = m_copy(m, 0, (int)M_COPYALL);
#ifdef IPSEC
/* check AH/ESP integrity. */
if (n && ipsec4_in_reject_so(n, last->inp_socket)) {
m_freem(n);
ipsecstat.in_polvio++;
/* do not inject data to pcb */
} else
#endif /*IPSEC*/
if (n) {
if (last->inp_flags & INP_CONTROLOPTS ||
last->inp_socket->so_options & SO_TIMESTAMP)
@ -155,6 +164,15 @@ rip_input(m, off, proto)
}
last = inp;
}
#ifdef IPSEC
/* check AH/ESP integrity. */
if (last && ipsec4_in_reject_so(m, last->inp_socket)) {
m_freem(m);
ipsecstat.in_polvio++;
ipstat.ips_delivered--;
/* do not inject data to pcb */
} else
#endif /*IPSEC*/
if (last) {
if (last->inp_flags & INP_CONTROLOPTS ||
last->inp_socket->so_options & SO_TIMESTAMP)
@ -168,9 +186,9 @@ rip_input(m, off, proto)
sorwakeup(last->inp_socket);
} else {
m_freem(m);
ipstat.ips_noproto++;
ipstat.ips_delivered--;
}
ipstat.ips_noproto++;
ipstat.ips_delivered--;
}
}
/*
@ -232,7 +250,10 @@ rip_output(m, so, dst)
}
#ifdef IPSEC
ipsec_setsocket(m, so);
if (ipsec_setsocket(m, so) != 0) {
m_freem(m);
return ENOBUFS;
}
#endif /*IPSEC*/
return (ip_output(m, inp->inp_options, &inp->inp_route, flags,

View file

@ -305,6 +305,7 @@ tcp6_input(mp, offp, proto)
int *offp, proto;
{
register struct mbuf *m = *mp;
struct in6_ifaddr *ia6;
IP6_EXTHDR_CHECK(m, *offp, sizeof(struct tcphdr), IPPROTO_DONE);
@ -312,7 +313,8 @@ tcp6_input(mp, offp, proto)
* draft-itojun-ipv6-tcp-to-anycast
* better place to put this in?
*/
if (m->m_flags & M_ANYCAST6) {
ia6 = ip6_getdstifaddr(m);
if (ia6 && (ia6->ia6_flags & IN6_IFF_ANYCAST)) {
struct ip6_hdr *ip6;
ip6 = mtod(m, struct ip6_hdr *);
@ -379,6 +381,19 @@ tcp_input(m, off0, proto)
goto drop;
}
th = (struct tcphdr *)((caddr_t)ip6 + off0);
/*
* Be proactive about unspecified IPv6 address in source.
* As we use all-zero to indicate unbounded/unconnected pcb,
* unspecified IPv6 address can be used to confuse us.
*
* Note that packets with unspecified IPv6 destination is
* already dropped in ip6_input.
*/
if (IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_src)) {
/* XXX stat */
goto drop;
}
} else
#endif /* INET6 */
{
@ -627,18 +642,6 @@ tcp_input(m, off0, proto)
else
tiwin = th->th_win;
#ifdef INET6
/* save packet options if user wanted */
if (isipv6 && inp->in6p_flags & INP_CONTROLOPTS) {
if (inp->in6p_options) {
m_freem(inp->in6p_options);
inp->in6p_options = 0;
}
ip6_savecontrol(inp, &inp->in6p_options, ip6, m);
}
/* else, should also do ip_srcroute() here? */
#endif /* INET6 */
so = inp->inp_socket;
if (so->so_options & (SO_DEBUG|SO_ACCEPTCONN)) {
#ifdef TCPDEBUG
@ -683,6 +686,50 @@ tcp_input(m, off0, proto)
goto drop;
}
#endif
#ifdef INET6
/*
* If deprecated address is forbidden,
* we do not accept SYN to deprecated interface
* address to prevent any new inbound connection from
* getting established.
* When we do not accept SYN, we send a TCP RST,
* with deprecated source address (instead of dropping
* it). We compromise it as it is much better for peer
* to send a RST, and RST will be the final packet
* for the exchange.
*
* If we do not forbid deprecated addresses, we accept
* the SYN packet. RFC2462 does not suggest dropping
* SYN in this case.
* If we decipher RFC2462 5.5.4, it says like this:
* 1. use of deprecated addr with existing
* communication is okay - "SHOULD continue to be
* used"
* 2. use of it with new communication:
* (2a) "SHOULD NOT be used if alternate address
* with sufficient scope is available"
* (2b) nothing mentioned otherwise.
* Here we fall into (2b) case as we have no choice in
* our source address selection - we must obey the peer.
*
* The wording in RFC2462 is confusing, and there are
* multiple description text for deprecated address
* handling - worse, they are not exactly the same.
* I believe 5.5.4 is the best one, so we follow 5.5.4.
*/
if (isipv6 && !ip6_use_deprecated) {
struct in6_ifaddr *ia6;
if ((ia6 = ip6_getdstifaddr(m)) &&
(ia6->ia6_flags & IN6_IFF_DEPRECATED)) {
tp = NULL;
rstreason = BANDLIM_RST_OPENPORT;
goto dropwithreset;
}
}
#endif
so2 = sonewconn(so, 0);
if (so2 == 0) {
/*
@ -731,10 +778,8 @@ tcp_input(m, off0, proto)
if (isipv6)
inp->in6p_laddr = ip6->ip6_dst;
else {
if ((inp->inp_flags & IN6P_BINDV6ONLY) == 0) {
inp->inp_vflag &= ~INP_IPV6;
inp->inp_vflag |= INP_IPV4;
}
inp->inp_vflag &= ~INP_IPV6;
inp->inp_vflag |= INP_IPV4;
#endif /* INET6 */
inp->inp_laddr = ip->ip_dst;
#ifdef INET6
@ -779,21 +824,25 @@ tcp_input(m, off0, proto)
#endif
#ifdef INET6
if (isipv6) {
/*
* inherit socket options from the listening
* socket.
*/
/*
* Inherit socket options from the listening
* socket.
* Note that in6p_inputopts are not (even
* should not be) copied, since it stores
* previously received options and is used to
* detect if each new option is different than
* the previous one and hence should be passed
* to a user.
* If we copied in6p_inputopts, a user would
* not be able to receive options just after
* calling the accept system call.
*/
inp->inp_flags |=
oinp->inp_flags & INP_CONTROLOPTS;
if (inp->inp_flags & INP_CONTROLOPTS) {
if (inp->in6p_options) {
m_freem(inp->in6p_options);
inp->in6p_options = 0;
}
ip6_savecontrol(inp,
&inp->in6p_options,
ip6, m);
}
if (oinp->in6p_outputopts)
inp->in6p_outputopts =
ip6_copypktopts(oinp->in6p_outputopts,
M_NOWAIT);
} else
#endif /* INET6 */
inp->inp_options = ip_srcroute();

View file

@ -376,7 +376,7 @@ tcp_output(tp)
* NOTE: we assume that the IP/TCP header plus TCP options
* always fit in a single mbuf, leaving room for a maximum
* link header, i.e.
* max_linkhdr + sizeof (struct tcpiphdr) + optlen <= MHLEN
* max_linkhdr + sizeof (struct tcpiphdr) + optlen <= MCLBYTES
*/
optlen = 0;
#ifdef INET6
@ -823,7 +823,11 @@ tcp_output(tp)
/* TODO: IPv6 IP6TOS_ECT bit on */
#ifdef IPSEC
ipsec_setsocket(m, so);
if (ipsec_setsocket(m, so) != 0) {
m_freem(m);
error = ENOBUFS;
goto out;
}
#endif /*IPSEC*/
error = ip6_output(m,
tp->t_inpcb->in6p_outputopts,

Some files were not shown because too many files have changed in this diff Show more