mirror of
https://github.com/opnsense/src.git
synced 2026-02-20 08:21:05 -05:00
KAME netinet6 basic part(no IPsec,no V6 Multicast Forwarding, no UDP/TCP
for IPv6 yet) With this patch, you can assigne IPv6 addr automatically, and can reply to IPv6 ping. Reviewed by: freebsd-arch, cvs-committers Obtained from: KAME project
This commit is contained in:
parent
a7a9b4714d
commit
82cd038d51
66 changed files with 21626 additions and 223 deletions
|
|
@ -29,6 +29,7 @@ maxusers 32
|
|||
|
||||
options MATH_EMULATE #Support for x87 emulation
|
||||
options INET #InterNETworking
|
||||
#options "INET6" #IPv6
|
||||
options FFS #Berkeley Fast Filesystem
|
||||
options FFS_ROOT #FFS usable as root device [keep this!]
|
||||
options MFS #Memory Filesystem
|
||||
|
|
|
|||
|
|
@ -41,7 +41,9 @@ INCLUDES+= -I$S/../include
|
|||
.else
|
||||
INCLUDES+= -I/usr/include
|
||||
.endif
|
||||
COPTS= ${INCLUDES} ${IDENT} -DKERNEL -include opt_global.h
|
||||
COPTS= ${INCLUDES} ${IDENT} -DKERNEL -include opt_global.h
|
||||
# KAME mandatory flags
|
||||
COPTS+= -D_KERNEL
|
||||
CFLAGS= ${COPTFLAGS} ${CWARNFLAGS} ${DEBUG} ${COPTS}
|
||||
|
||||
# XXX LOCORE means "don't declare C stuff" not "for locore.s".
|
||||
|
|
|
|||
|
|
@ -41,7 +41,9 @@ INCLUDES+= -I$S/../include
|
|||
.else
|
||||
INCLUDES+= -I/usr/include
|
||||
.endif
|
||||
COPTS= ${INCLUDES} ${IDENT} -DKERNEL -include opt_global.h
|
||||
COPTS= ${INCLUDES} ${IDENT} -DKERNEL -include opt_global.h
|
||||
# KAME mandatory flags
|
||||
COPTS+= -D_KERNEL
|
||||
CFLAGS= ${COPTFLAGS} ${CWARNFLAGS} ${DEBUG} ${COPTS}
|
||||
|
||||
# XXX LOCORE means "don't declare C stuff" not "for locore.s".
|
||||
|
|
|
|||
|
|
@ -483,6 +483,7 @@ net/rtsock.c standard
|
|||
net/slcompress.c optional ppp
|
||||
net/slcompress.c optional sl
|
||||
net/zlib.c optional ppp_deflate
|
||||
net/net_osdep.c standard
|
||||
netatalk/aarp.c optional netatalk
|
||||
netatalk/at_control.c optional netatalk
|
||||
netatalk/at_proto.c optional netatalk
|
||||
|
|
@ -612,6 +613,25 @@ netinet/tcp_subr.c optional inet
|
|||
netinet/tcp_timer.c optional inet
|
||||
netinet/tcp_usrreq.c optional inet
|
||||
netinet/udp_usrreq.c optional inet
|
||||
netinet6/in6.c optional inet6
|
||||
netinet6/in6_ifattach.c optional inet6
|
||||
netinet6/in6_cksum.c optional inet6
|
||||
netinet6/in6_pcb.c optional inet6
|
||||
netinet6/in6_proto.c optional inet6
|
||||
netinet6/in6_rmx.c optional inet6
|
||||
netinet6/in6_prefix.c optional inet6
|
||||
netinet6/dest6.c optional inet6
|
||||
netinet6/frag6.c optional inet6
|
||||
netinet6/icmp6.c optional inet6
|
||||
netinet6/ip6_input.c optional inet6
|
||||
netinet6/ip6_forward.c optional inet6
|
||||
netinet6/ip6_output.c optional inet6
|
||||
netinet6/route6.c optional inet6
|
||||
netinet6/mld6.c optional inet6
|
||||
netinet6/nd6.c optional inet6
|
||||
netinet6/nd6_nbr.c optional inet6
|
||||
netinet6/nd6_rtr.c optional inet6
|
||||
netinet6/raw_ip6.c optional inet6
|
||||
netipx/ipx.c optional ipx
|
||||
netipx/ipx_cksum.c optional ipx
|
||||
netipx/ipx_input.c optional ipx
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# $FreeBSD$
|
||||
#
|
||||
# On the handling of kernel options
|
||||
#
|
||||
#
|
||||
# All kernel options should be listed in LINT, with suitable
|
||||
# descriptions. Negative options (options that make some code not
|
||||
# compile) should be commented out; LINT should compile as much code
|
||||
|
|
@ -10,7 +10,7 @@
|
|||
# possible to have a full compile-test. If necessary, you can include
|
||||
# "opt_lint.h" and check for COMPILING_LINT to get maximum code
|
||||
# coverage.
|
||||
#
|
||||
#
|
||||
# All new options shall also be listed in either "conf/options" or
|
||||
# "<machine>/conf/options.<machine>". Options that affect a single
|
||||
# source-file <xxx>.[c|s] should be directed into "opt_<xxx>.h", while
|
||||
|
|
@ -20,7 +20,7 @@
|
|||
# only some files. Note that the effect of listing only an option
|
||||
# without a header-file-name in conf/options (and cousins) is that the
|
||||
# last convention is followed.
|
||||
#
|
||||
#
|
||||
# This handling scheme is not yet fully implemented.
|
||||
#
|
||||
#
|
||||
|
|
@ -103,8 +103,8 @@ FFS
|
|||
NFS
|
||||
NWFS
|
||||
|
||||
# If you are following the conditions in the copyright,
|
||||
# you can enable soft-updates which will speed up a lot of thigs
|
||||
# If you are following the conditions in the copyright,
|
||||
# you can enable soft-updates which will speed up a lot of thigs
|
||||
# and make the system safer from crashes at the same time.
|
||||
# otherwise a STUB module will be compiled in.
|
||||
SOFTUPDATES opt_ffs.h
|
||||
|
|
@ -216,6 +216,10 @@ BRIDGE opt_bdg.h
|
|||
MROUTING opt_mrouting.h
|
||||
INET opt_inet.h
|
||||
INET6 opt_inet.h
|
||||
IPSEC opt_ipsec.h
|
||||
IPSEC_ESP opt_ipsec.h
|
||||
IPSEC_DEBUG opt_ipsec.h
|
||||
IPSEC_IPV6FWD opt_ipsec.h
|
||||
IPDIVERT
|
||||
DUMMYNET opt_ipdn.h
|
||||
IPFILTER_LKM opt_ipfilter.h
|
||||
|
|
@ -224,6 +228,10 @@ IPFIREWALL_VERBOSE opt_ipfw.h
|
|||
IPFIREWALL_VERBOSE_LIMIT opt_ipfw.h
|
||||
IPFIREWALL_DEFAULT_TO_ACCEPT opt_ipfw.h
|
||||
IPFIREWALL_FORWARD opt_ipfw.h
|
||||
IPV6FIREWALL opt_ip6fw.h
|
||||
IPV6FIREWALL_VERBOSE opt_ip6fw.h
|
||||
IPV6FIREWALL_VERBOSE_LIMIT opt_ip6fw.h
|
||||
IPV6FIREWALL_DEFAULT_TO_ACCEPT opt_ip6fw.h
|
||||
IPSTEALTH
|
||||
IPX opt_ipx.h
|
||||
IPXIP opt_ipx.h
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ maxusers 32
|
|||
|
||||
options MATH_EMULATE #Support for x87 emulation
|
||||
options INET #InterNETworking
|
||||
#options "INET6" #IPv6
|
||||
options FFS #Berkeley Fast Filesystem
|
||||
options FFS_ROOT #FFS usable as root device [keep this!]
|
||||
options MFS #Memory Filesystem
|
||||
|
|
|
|||
|
|
@ -41,7 +41,9 @@ INCLUDES+= -I$S/../include
|
|||
.else
|
||||
INCLUDES+= -I/usr/include
|
||||
.endif
|
||||
COPTS= ${INCLUDES} ${IDENT} -DKERNEL -include opt_global.h
|
||||
COPTS= ${INCLUDES} ${IDENT} -DKERNEL -include opt_global.h
|
||||
# KAME mandatory flags
|
||||
COPTS+= -D_KERNEL
|
||||
CFLAGS= ${COPTFLAGS} ${CWARNFLAGS} ${DEBUG} ${COPTS}
|
||||
|
||||
# XXX LOCORE means "don't declare C stuff" not "for locore.s".
|
||||
|
|
|
|||
|
|
@ -59,6 +59,9 @@ MALLOC_DEFINE(M_CACHE, "cache", "Various Dynamically allocated caches");
|
|||
MALLOC_DEFINE(M_DEVBUF, "devbuf", "device driver memory");
|
||||
MALLOC_DEFINE(M_TEMP, "temp", "misc temporary data buffers");
|
||||
|
||||
MALLOC_DEFINE(M_IP6OPT, "ip6opt", "IPv6 options");
|
||||
MALLOC_DEFINE(M_IP6NDP, "ip6ndp", "IPv6 Neighbor Discovery");
|
||||
|
||||
static void kmeminit __P((void *));
|
||||
SYSINIT(kmem, SI_SUB_KMEM, SI_ORDER_FIRST, kmeminit, NULL)
|
||||
|
||||
|
|
@ -473,7 +476,7 @@ malloc_init(data)
|
|||
{
|
||||
struct malloc_type *type = (struct malloc_type *)data;
|
||||
|
||||
if (type->ks_magic != M_MAGIC)
|
||||
if (type->ks_magic != M_MAGIC)
|
||||
panic("malloc type lacks magic");
|
||||
|
||||
if (type->ks_limit != 0)
|
||||
|
|
@ -498,7 +501,7 @@ malloc_uninit(data)
|
|||
struct malloc_type *type = (struct malloc_type *)data;
|
||||
struct malloc_type *t;
|
||||
|
||||
if (type->ks_magic != M_MAGIC)
|
||||
if (type->ks_magic != M_MAGIC)
|
||||
panic("malloc type lacks magic");
|
||||
|
||||
if (cnt.v_page_count == 0)
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ MALLOC_DEFINE(M_PCB, "pcb", "protocol control block");
|
|||
SYSCTL_DECL(_kern_ipc);
|
||||
|
||||
static int somaxconn = SOMAXCONN;
|
||||
SYSCTL_INT(_kern_ipc, KIPC_SOMAXCONN, somaxconn, CTLFLAG_RW,
|
||||
SYSCTL_INT(_kern_ipc, KIPC_SOMAXCONN, somaxconn, CTLFLAG_RW,
|
||||
&somaxconn, 0, "Maximum pending socket connection queue size");
|
||||
|
||||
/*
|
||||
|
|
@ -1218,6 +1218,117 @@ integer:
|
|||
}
|
||||
}
|
||||
|
||||
/* XXX; prepare mbuf for (__FreeBSD__ < 3) routines. */
|
||||
int
|
||||
soopt_getm(struct sockopt *sopt, struct mbuf **mp)
|
||||
{
|
||||
struct mbuf *m, *m_prev;
|
||||
int sopt_size = sopt->sopt_valsize;
|
||||
|
||||
MGET(m, sopt->sopt_p ? M_WAIT : M_DONTWAIT, MT_DATA);
|
||||
if (m == 0)
|
||||
return ENOBUFS;
|
||||
if (sopt_size > MLEN) {
|
||||
MCLGET(m, sopt->sopt_p ? M_WAIT : M_DONTWAIT);
|
||||
if ((m->m_flags & M_EXT) == 0) {
|
||||
m_free(m);
|
||||
return ENOBUFS;
|
||||
}
|
||||
m->m_len = min(MCLBYTES, sopt_size);
|
||||
} else {
|
||||
m->m_len = min(MLEN, sopt_size);
|
||||
}
|
||||
sopt_size -= m->m_len;
|
||||
*mp = m;
|
||||
m_prev = m;
|
||||
|
||||
while (sopt_size) {
|
||||
MGET(m, sopt->sopt_p ? M_WAIT : M_DONTWAIT, MT_DATA);
|
||||
if (m == 0) {
|
||||
m_freem(*mp);
|
||||
return ENOBUFS;
|
||||
}
|
||||
if (sopt_size > MLEN) {
|
||||
MCLGET(m, sopt->sopt_p ? M_WAIT : M_DONTWAIT);
|
||||
if ((m->m_flags & M_EXT) == 0) {
|
||||
m_freem(*mp);
|
||||
return ENOBUFS;
|
||||
}
|
||||
m->m_len = min(MCLBYTES, sopt_size);
|
||||
} else {
|
||||
m->m_len = min(MLEN, sopt_size);
|
||||
}
|
||||
sopt_size -= m->m_len;
|
||||
m_prev->m_next = m;
|
||||
m_prev = m;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* XXX; copyin sopt data into mbuf chain for (__FreeBSD__ < 3) routines. */
|
||||
int
|
||||
soopt_mcopyin(struct sockopt *sopt, struct mbuf *m)
|
||||
{
|
||||
struct mbuf *m0 = m;
|
||||
|
||||
if (sopt->sopt_val == NULL)
|
||||
return 0;
|
||||
while (m != NULL && sopt->sopt_valsize >= m->m_len) {
|
||||
if (sopt->sopt_p != NULL) {
|
||||
int error;
|
||||
|
||||
error = copyin(sopt->sopt_val, mtod(m, char *),
|
||||
m->m_len);
|
||||
if (error != 0) {
|
||||
m_freem(m0);
|
||||
return(error);
|
||||
}
|
||||
} else
|
||||
bcopy(sopt->sopt_val, mtod(m, char *), m->m_len);
|
||||
sopt->sopt_valsize -= m->m_len;
|
||||
(caddr_t)sopt->sopt_val += m->m_len;
|
||||
m = m->m_next;
|
||||
}
|
||||
if (m != NULL) /* should be allocated enoughly at ip6_sooptmcopyin() */
|
||||
panic("ip6_sooptmcopyin");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* XXX; copyout mbuf chain data into soopt for (__FreeBSD__ < 3) routines. */
|
||||
int
|
||||
soopt_mcopyout(struct sockopt *sopt, struct mbuf *m)
|
||||
{
|
||||
struct mbuf *m0 = m;
|
||||
size_t valsize = 0;
|
||||
|
||||
if (sopt->sopt_val == NULL)
|
||||
return 0;
|
||||
while (m != NULL && sopt->sopt_valsize >= m->m_len) {
|
||||
if (sopt->sopt_p != NULL) {
|
||||
int error;
|
||||
|
||||
error = copyout(mtod(m, char *), sopt->sopt_val,
|
||||
m->m_len);
|
||||
if (error != 0) {
|
||||
m_freem(m0);
|
||||
return(error);
|
||||
}
|
||||
} else
|
||||
bcopy(mtod(m, char *), sopt->sopt_val, m->m_len);
|
||||
sopt->sopt_valsize -= m->m_len;
|
||||
(caddr_t)sopt->sopt_val += m->m_len;
|
||||
valsize += m->m_len;
|
||||
m = m->m_next;
|
||||
}
|
||||
if (m != NULL) {
|
||||
/* enough soopt buffer should be given from user-land */
|
||||
m_freem(m0);
|
||||
return(EINVAL);
|
||||
}
|
||||
sopt->sopt_valsize = valsize;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
sohasoutofband(so)
|
||||
register struct socket *so;
|
||||
|
|
|
|||
139
sys/net/if.c
139
sys/net/if.c
|
|
@ -35,6 +35,7 @@
|
|||
*/
|
||||
|
||||
#include "opt_compat.h"
|
||||
#include "opt_inet.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/malloc.h>
|
||||
|
|
@ -53,6 +54,11 @@
|
|||
#include <net/if_dl.h>
|
||||
#include <net/radix.h>
|
||||
|
||||
#ifdef INET6
|
||||
/*XXX*/
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* System initialization
|
||||
*/
|
||||
|
|
@ -71,6 +77,14 @@ MALLOC_DEFINE(M_IFMADDR, "ether_multi", "link-level multicast address");
|
|||
int ifqmaxlen = IFQ_MAXLEN;
|
||||
struct ifnethead ifnet; /* depend on static init XXX */
|
||||
|
||||
#ifdef INET6
|
||||
/*
|
||||
* XXX: declare here to avoid to include many inet6 related files..
|
||||
* should be more generalized?
|
||||
*/
|
||||
extern void nd6_setmtu __P((struct ifnet *));
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Network interface utility routines.
|
||||
*
|
||||
|
|
@ -98,6 +112,7 @@ ifinit(dummy)
|
|||
|
||||
int if_index = 0;
|
||||
struct ifaddr **ifnet_addrs;
|
||||
struct ifnet **ifindex2ifnet = NULL;
|
||||
|
||||
|
||||
/*
|
||||
|
|
@ -131,19 +146,32 @@ if_attach(ifp)
|
|||
* this unlikely case.
|
||||
*/
|
||||
TAILQ_INIT(&ifp->if_addrhead);
|
||||
TAILQ_INIT(&ifp->if_prefixhead);
|
||||
LIST_INIT(&ifp->if_multiaddrs);
|
||||
getmicrotime(&ifp->if_lastchange);
|
||||
if (ifnet_addrs == 0 || if_index >= if_indexlim) {
|
||||
unsigned n = (if_indexlim <<= 1) * sizeof(ifa);
|
||||
struct ifaddr **q = (struct ifaddr **)
|
||||
malloc(n, M_IFADDR, M_WAITOK);
|
||||
bzero((caddr_t)q, n);
|
||||
caddr_t q = malloc(n, M_IFADDR, M_WAITOK);
|
||||
bzero(q, n);
|
||||
if (ifnet_addrs) {
|
||||
bcopy((caddr_t)ifnet_addrs, (caddr_t)q, n/2);
|
||||
free((caddr_t)ifnet_addrs, M_IFADDR);
|
||||
}
|
||||
ifnet_addrs = q;
|
||||
ifnet_addrs = (struct ifaddr **)q;
|
||||
|
||||
/* grow ifindex2ifnet */
|
||||
n = if_indexlim * sizeof(struct ifnet *);
|
||||
q = malloc(n, M_IFADDR, M_WAITOK);
|
||||
bzero(q, n);
|
||||
if (ifindex2ifnet) {
|
||||
bcopy((caddr_t)ifindex2ifnet, q, n/2);
|
||||
free((caddr_t)ifindex2ifnet, M_IFADDR);
|
||||
}
|
||||
ifindex2ifnet = (struct ifnet **)q;
|
||||
}
|
||||
|
||||
ifindex2ifnet[if_index] = ifp;
|
||||
|
||||
/*
|
||||
* create a Link Level name for this device
|
||||
*/
|
||||
|
|
@ -207,7 +235,7 @@ if_detach(ifp)
|
|||
ifa = TAILQ_FIRST(&ifp->if_addrhead)) {
|
||||
TAILQ_REMOVE(&ifp->if_addrhead, ifa, ifa_link);
|
||||
IFAFREE(ifa);
|
||||
}
|
||||
}
|
||||
|
||||
TAILQ_REMOVE(&ifnet, ifp, if_link);
|
||||
}
|
||||
|
|
@ -226,13 +254,15 @@ ifa_ifwithaddr(addr)
|
|||
#define equal(a1, a2) \
|
||||
(bcmp((caddr_t)(a1), (caddr_t)(a2), ((struct sockaddr *)(a1))->sa_len) == 0)
|
||||
for (ifp = ifnet.tqh_first; ifp; ifp = ifp->if_link.tqe_next)
|
||||
for (ifa = ifp->if_addrhead.tqh_first; ifa;
|
||||
for (ifa = ifp->if_addrhead.tqh_first; ifa;
|
||||
ifa = ifa->ifa_link.tqe_next) {
|
||||
if (ifa->ifa_addr->sa_family != addr->sa_family)
|
||||
continue;
|
||||
if (equal(addr, ifa->ifa_addr))
|
||||
return (ifa);
|
||||
if ((ifp->if_flags & IFF_BROADCAST) && ifa->ifa_broadaddr &&
|
||||
/* IP6 doesn't have broadcast */
|
||||
ifa->ifa_broadaddr->sa_len != 0 &&
|
||||
equal(ifa->ifa_broadaddr, addr))
|
||||
return (ifa);
|
||||
}
|
||||
|
|
@ -251,7 +281,7 @@ ifa_ifwithdstaddr(addr)
|
|||
|
||||
for (ifp = ifnet.tqh_first; ifp; ifp = ifp->if_link.tqe_next)
|
||||
if (ifp->if_flags & IFF_POINTOPOINT)
|
||||
for (ifa = ifp->if_addrhead.tqh_first; ifa;
|
||||
for (ifa = ifp->if_addrhead.tqh_first; ifa;
|
||||
ifa = ifa->ifa_link.tqe_next) {
|
||||
if (ifa->ifa_addr->sa_family != addr->sa_family)
|
||||
continue;
|
||||
|
|
@ -285,7 +315,7 @@ ifa_ifwithnet(addr)
|
|||
return (ifnet_addrs[sdl->sdl_index - 1]);
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* Scan though each interface, looking for ones that have
|
||||
* addresses in this address family.
|
||||
*/
|
||||
|
|
@ -296,13 +326,17 @@ ifa_ifwithnet(addr)
|
|||
|
||||
if (ifa->ifa_addr->sa_family != af)
|
||||
next: continue;
|
||||
if (ifp->if_flags & IFF_POINTOPOINT) {
|
||||
if (
|
||||
#ifdef INET6 /* XXX: for maching gif tunnel dst as routing entry gateway */
|
||||
addr->sa_family != AF_INET6 &&
|
||||
#endif
|
||||
ifp->if_flags & IFF_POINTOPOINT) {
|
||||
/*
|
||||
* This is a bit broken as it doesn't
|
||||
* take into account that the remote end may
|
||||
* This is a bit broken as it doesn't
|
||||
* take into account that the remote end may
|
||||
* be a single node in the network we are
|
||||
* looking for.
|
||||
* The trouble is that we don't know the
|
||||
* The trouble is that we don't know the
|
||||
* netmask for the remote end.
|
||||
*/
|
||||
if (ifa->ifa_dstaddr != 0
|
||||
|
|
@ -372,7 +406,7 @@ ifaof_ifpforaddr(addr, ifp)
|
|||
|
||||
if (af >= AF_MAX)
|
||||
return (0);
|
||||
for (ifa = ifp->if_addrhead.tqh_first; ifa;
|
||||
for (ifa = ifp->if_addrhead.tqh_first; ifa;
|
||||
ifa = ifa->ifa_link.tqe_next) {
|
||||
if (ifa->ifa_addr->sa_family != af)
|
||||
continue;
|
||||
|
|
@ -471,6 +505,9 @@ if_route(ifp, flag, fam)
|
|||
if (fam == PF_UNSPEC || (fam == ifa->ifa_addr->sa_family))
|
||||
pfctlinput(PRC_IFUP, ifa->ifa_addr);
|
||||
rt_ifmsg(ifp);
|
||||
#ifdef INET6
|
||||
in6_if_up(ifp);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -559,9 +596,9 @@ ifunit(name)
|
|||
/*
|
||||
* Look for a non numeric part
|
||||
*/
|
||||
end = name + IFNAMSIZ;
|
||||
end = name + IFNAMSIZ;
|
||||
cp2 = namebuf;
|
||||
cp = name;
|
||||
cp = name;
|
||||
while ((cp < end) && (c = *cp)) {
|
||||
if (c >= '0' && c <= '9')
|
||||
break;
|
||||
|
|
@ -576,7 +613,7 @@ ifunit(name)
|
|||
*/
|
||||
len = cp - name + 1;
|
||||
for (unit = 0;
|
||||
((c = *cp) >= '0') && (c <= '9') && (unit < 1000000); cp++ )
|
||||
((c = *cp) >= '0') && (c <= '9') && (unit < 1000000); cp++ )
|
||||
unit = (unit * 10) + (c - '0');
|
||||
if (*cp != '\0')
|
||||
return 0; /* no trailing garbage allowed */
|
||||
|
|
@ -592,6 +629,35 @@ ifunit(name)
|
|||
return (ifp);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Map interface name in a sockaddr_dl to
|
||||
* interface structure pointer.
|
||||
*/
|
||||
struct ifnet *
|
||||
if_withname(sa)
|
||||
struct sockaddr *sa;
|
||||
{
|
||||
char ifname[IFNAMSIZ+1];
|
||||
struct sockaddr_dl *sdl = (struct sockaddr_dl *)sa;
|
||||
|
||||
if ( (sa->sa_family != AF_LINK) || (sdl->sdl_nlen == 0) ||
|
||||
(sdl->sdl_nlen > IFNAMSIZ) )
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* ifunit wants a null-terminated name. It may not be null-terminated
|
||||
* in the sockaddr. We don't want to change the caller's sockaddr,
|
||||
* and there might not be room to put the trailing null anyway, so we
|
||||
* make a local copy that we know we can null terminate safely.
|
||||
*/
|
||||
|
||||
bcopy(sdl->sdl_data, ifname, sdl->sdl_nlen);
|
||||
ifname[sdl->sdl_nlen] = '\0';
|
||||
return ifunit(ifname);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Interface ioctls.
|
||||
*/
|
||||
|
|
@ -606,6 +672,7 @@ ifioctl(so, cmd, data, p)
|
|||
register struct ifreq *ifr;
|
||||
struct ifstat *ifs;
|
||||
int error;
|
||||
short oif_flags;
|
||||
|
||||
switch (cmd) {
|
||||
|
||||
|
|
@ -680,6 +747,9 @@ ifioctl(so, cmd, data, p)
|
|||
return(error);
|
||||
|
||||
case SIOCSIFMTU:
|
||||
{
|
||||
u_long oldmtu = ifp->if_mtu;
|
||||
|
||||
error = suser(p);
|
||||
if (error)
|
||||
return (error);
|
||||
|
|
@ -690,7 +760,16 @@ ifioctl(so, cmd, data, p)
|
|||
error = (*ifp->if_ioctl)(ifp, cmd, data);
|
||||
if (error == 0)
|
||||
getmicrotime(&ifp->if_lastchange);
|
||||
return(error);
|
||||
/*
|
||||
* If the link MTU changed, do network layer specific procedure.
|
||||
*/
|
||||
if (ifp->if_mtu != oldmtu) {
|
||||
#ifdef INET6
|
||||
nd6_setmtu(ifp);
|
||||
#endif
|
||||
}
|
||||
return (error);
|
||||
}
|
||||
|
||||
case SIOCADDMULTI:
|
||||
case SIOCDELMULTI:
|
||||
|
|
@ -739,10 +818,11 @@ ifioctl(so, cmd, data, p)
|
|||
return ((*ifp->if_ioctl)(ifp, cmd, data));
|
||||
|
||||
default:
|
||||
oif_flags = ifp->if_flags;
|
||||
if (so->so_proto == 0)
|
||||
return (EOPNOTSUPP);
|
||||
#ifndef COMPAT_43
|
||||
return ((*so->so_proto->pr_usrreqs->pru_control)(so, cmd,
|
||||
error = ((*so->so_proto->pr_usrreqs->pru_control)(so, cmd,
|
||||
data,
|
||||
ifp, p));
|
||||
#else
|
||||
|
|
@ -793,11 +873,22 @@ ifioctl(so, cmd, data, p)
|
|||
case OSIOCGIFBRDADDR:
|
||||
case OSIOCGIFNETMASK:
|
||||
*(u_short *)&ifr->ifr_addr = ifr->ifr_addr.sa_family;
|
||||
|
||||
}
|
||||
}
|
||||
#endif /* COMPAT_43 */
|
||||
|
||||
if ((oif_flags ^ ifp->if_flags) & IFF_UP) {
|
||||
#ifdef INET6
|
||||
if (ifp->if_flags & IFF_UP) {
|
||||
int s = splimp();
|
||||
in6_if_up(ifp);
|
||||
splx(s);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return (error);
|
||||
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
|
@ -960,7 +1051,7 @@ if_allmulti(ifp, onswitch)
|
|||
|
||||
/*
|
||||
* Add a multicast listenership to the interface in question.
|
||||
* The link layer provides a routine which converts
|
||||
* The link layer provides a routine which converts
|
||||
*/
|
||||
int
|
||||
if_addmulti(ifp, sa, retifma)
|
||||
|
|
@ -976,7 +1067,7 @@ if_addmulti(ifp, sa, retifma)
|
|||
* If the matching multicast address already exists
|
||||
* then don't add a new one, just add a reference
|
||||
*/
|
||||
for (ifma = ifp->if_multiaddrs.lh_first; ifma;
|
||||
for (ifma = ifp->if_multiaddrs.lh_first; ifma;
|
||||
ifma = ifma->ifma_link.le_next) {
|
||||
if (equal(sa, ifma->ifma_addr)) {
|
||||
ifma->ifma_refcount++;
|
||||
|
|
@ -1063,7 +1154,7 @@ if_delmulti(ifp, sa)
|
|||
struct ifmultiaddr *ifma;
|
||||
int s;
|
||||
|
||||
for (ifma = ifp->if_multiaddrs.lh_first; ifma;
|
||||
for (ifma = ifp->if_multiaddrs.lh_first; ifma;
|
||||
ifma = ifma->ifma_link.le_next)
|
||||
if (equal(sa, ifma->ifma_addr))
|
||||
break;
|
||||
|
|
@ -1096,7 +1187,7 @@ if_delmulti(ifp, sa)
|
|||
* in the record for the link-layer address. (So we don't complain
|
||||
* in that case.)
|
||||
*/
|
||||
for (ifma = ifp->if_multiaddrs.lh_first; ifma;
|
||||
for (ifma = ifp->if_multiaddrs.lh_first; ifma;
|
||||
ifma = ifma->ifma_link.le_next)
|
||||
if (equal(sa, ifma->ifma_addr))
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -56,11 +56,15 @@
|
|||
#include <net/if_dl.h>
|
||||
#include <net/if_types.h>
|
||||
|
||||
#ifdef INET
|
||||
#if defined(INET) || defined(INET6)
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_var.h>
|
||||
#include <netinet/if_ether.h>
|
||||
#endif
|
||||
#ifdef INET6
|
||||
#include <netinet6/nd6.h>
|
||||
#include <netinet6/in6_ifattach.h>
|
||||
#endif
|
||||
|
||||
#ifdef IPX
|
||||
#include <netipx/ipx.h>
|
||||
|
|
@ -112,7 +116,7 @@ extern u_char aarp_org_code[3];
|
|||
#include <net/if_vlan_var.h>
|
||||
#endif /* NVLAN > 0 */
|
||||
|
||||
static int ether_resolvemulti __P((struct ifnet *, struct sockaddr **,
|
||||
static int ether_resolvemulti __P((struct ifnet *, struct sockaddr **,
|
||||
struct sockaddr *));
|
||||
u_char etherbroadcastaddr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
|
||||
#define senderr(e) do { error = (e); goto bad;} while (0)
|
||||
|
|
@ -146,7 +150,7 @@ static struct ng_type typestruct = {
|
|||
ngether_connect,
|
||||
ngether_rcvdata,
|
||||
ngether_rcvdata,
|
||||
ngether_disconnect
|
||||
ngether_disconnect
|
||||
};
|
||||
|
||||
#define AC2NG(AC) ((node_p)((AC)->ac_ng))
|
||||
|
|
@ -214,6 +218,17 @@ ether_output(ifp, m0, dst, rt0)
|
|||
type = htons(ETHERTYPE_IP);
|
||||
break;
|
||||
#endif
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
if (!nd6_storelladdr(&ac->ac_if, rt, m, dst, (u_char *)edst)) {
|
||||
/* this must be impossible, so we bark */
|
||||
printf("nd6_storelladdr failed\n");
|
||||
return(0);
|
||||
}
|
||||
off = m->m_pkthdr.len - m->m_len;
|
||||
type = htons(ETHERTYPE_IPV6);
|
||||
break;
|
||||
#endif
|
||||
#ifdef IPX
|
||||
case AF_IPX:
|
||||
type = htons(ETHERTYPE_IPX);
|
||||
|
|
@ -530,6 +545,12 @@ ether_input(ifp, eh, m)
|
|||
inq = &ipxintrq;
|
||||
break;
|
||||
#endif
|
||||
#ifdef INET6
|
||||
case ETHERTYPE_IPV6:
|
||||
schednetisr(NETISR_IPV6);
|
||||
inq = &ip6intrq;
|
||||
break;
|
||||
#endif
|
||||
#ifdef NS
|
||||
case 0x8137: /* Novell Ethernet_II Ethernet TYPE II */
|
||||
schednetisr(NETISR_NS);
|
||||
|
|
@ -741,6 +762,9 @@ ether_ifattach(ifp)
|
|||
#ifdef NETGRAPH
|
||||
ngether_init(ifp);
|
||||
#endif /* NETGRAPH */
|
||||
#ifdef INET6
|
||||
in6_ifattach_getifid(ifp);
|
||||
#endif
|
||||
}
|
||||
|
||||
SYSCTL_DECL(_net_link);
|
||||
|
|
@ -778,7 +802,7 @@ ether_ioctl(ifp, command, data)
|
|||
|
||||
if (ipx_nullhost(*ina))
|
||||
ina->x_host =
|
||||
*(union ipx_host *)
|
||||
*(union ipx_host *)
|
||||
ac->ac_enaddr;
|
||||
else {
|
||||
bcopy((caddr_t) ina->x_host.c_host,
|
||||
|
|
@ -856,11 +880,14 @@ ether_resolvemulti(ifp, llsa, sa)
|
|||
{
|
||||
struct sockaddr_dl *sdl;
|
||||
struct sockaddr_in *sin;
|
||||
#ifdef INET6
|
||||
struct sockaddr_in6 *sin6;
|
||||
#endif
|
||||
u_char *e_addr;
|
||||
|
||||
switch(sa->sa_family) {
|
||||
case AF_LINK:
|
||||
/*
|
||||
/*
|
||||
* No mapping needed. Just check that it's a valid MC address.
|
||||
*/
|
||||
sdl = (struct sockaddr_dl *)sa;
|
||||
|
|
@ -889,9 +916,28 @@ ether_resolvemulti(ifp, llsa, sa)
|
|||
*llsa = (struct sockaddr *)sdl;
|
||||
return 0;
|
||||
#endif
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
sin6 = (struct sockaddr_in6 *)sa;
|
||||
if (!IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr))
|
||||
return EADDRNOTAVAIL;
|
||||
MALLOC(sdl, struct sockaddr_dl *, sizeof *sdl, M_IFMADDR,
|
||||
M_WAITOK);
|
||||
sdl->sdl_len = sizeof *sdl;
|
||||
sdl->sdl_family = AF_LINK;
|
||||
sdl->sdl_index = ifp->if_index;
|
||||
sdl->sdl_type = IFT_ETHER;
|
||||
sdl->sdl_nlen = 0;
|
||||
sdl->sdl_alen = ETHER_ADDR_LEN;
|
||||
sdl->sdl_slen = 0;
|
||||
e_addr = LLADDR(sdl);
|
||||
ETHER_MAP_IPV6_MULTICAST(&sin6->sin6_addr, e_addr);
|
||||
*llsa = (struct sockaddr *)sdl;
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
default:
|
||||
/*
|
||||
/*
|
||||
* Well, the text isn't quite right, but it's the name
|
||||
* that counts...
|
||||
*/
|
||||
|
|
@ -976,8 +1022,8 @@ ngether_constructor(node_p *nodep)
|
|||
|
||||
/*
|
||||
* Give our ok for a hook to be added...
|
||||
*
|
||||
* Allow one hook at a time (rawdata).
|
||||
*
|
||||
* Allow one hook at a time (rawdata).
|
||||
* It can eiteh rdivert everything or only unclaimed packets.
|
||||
*/
|
||||
static int
|
||||
|
|
@ -1014,10 +1060,10 @@ ngether_rcvmsg(node_p node,
|
|||
|
||||
ifp = node->private;
|
||||
switch (msg->header.typecookie) {
|
||||
case NGM_ETHER_COOKIE:
|
||||
case NGM_ETHER_COOKIE:
|
||||
error = EINVAL;
|
||||
break;
|
||||
case NGM_GENERIC_COOKIE:
|
||||
case NGM_GENERIC_COOKIE:
|
||||
switch(msg->header.cmd) {
|
||||
case NGM_TEXT_STATUS: {
|
||||
char *arg;
|
||||
|
|
@ -1025,10 +1071,10 @@ ngether_rcvmsg(node_p node,
|
|||
int resplen = sizeof(struct ng_mesg) + 512;
|
||||
MALLOC(*resp, struct ng_mesg *, resplen,
|
||||
M_NETGRAPH, M_NOWAIT);
|
||||
if (*resp == NULL) {
|
||||
if (*resp == NULL) {
|
||||
error = ENOMEM;
|
||||
break;
|
||||
}
|
||||
}
|
||||
bzero(*resp, resplen);
|
||||
arg = (*resp)->data;
|
||||
|
||||
|
|
@ -1135,10 +1181,10 @@ bad:
|
|||
* pass an mbuf out to the connected hook
|
||||
* More complicated than just an m_prepend, as it tries to save later nodes
|
||||
* from needing to do lots of m_pullups.
|
||||
*/
|
||||
*/
|
||||
static void
|
||||
ngether_send(struct arpcom *ac, struct ether_header *eh, struct mbuf *m)
|
||||
{
|
||||
{
|
||||
int room;
|
||||
node_p node = AC2NG(ac);
|
||||
struct ether_header *eh2;
|
||||
|
|
@ -1150,15 +1196,15 @@ ngether_send(struct arpcom *ac, struct ether_header *eh, struct mbuf *m)
|
|||
eh2 = mtod(m, struct ether_header *) - 1;
|
||||
if ( eh == eh2) {
|
||||
/*
|
||||
* This is the case so just move the markers back to
|
||||
* This is the case so just move the markers back to
|
||||
* re-include it. We lucked out.
|
||||
* This allows us to avoid a yucky m_pullup
|
||||
* in later nodes if it works.
|
||||
*/
|
||||
m->m_len += sizeof(*eh);
|
||||
*/
|
||||
m->m_len += sizeof(*eh);
|
||||
m->m_data -= sizeof(*eh);
|
||||
m->m_pkthdr.len += sizeof(*eh);
|
||||
} else {
|
||||
} else {
|
||||
/*
|
||||
* Alternatively there may be room even though
|
||||
* it is stored somewhere else. If so, copy it in.
|
||||
|
|
@ -1170,7 +1216,7 @@ ngether_send(struct arpcom *ac, struct ether_header *eh, struct mbuf *m)
|
|||
* that fall into these cases. So we are not optimising
|
||||
* contorted cases.
|
||||
*/
|
||||
|
||||
|
||||
if (m->m_flags & M_EXT) {
|
||||
room = (mtod(m, caddr_t) - m->m_ext.ext_buf);
|
||||
if (room > m->m_ext.ext_size) /* garbage */
|
||||
|
|
@ -1178,14 +1224,14 @@ ngether_send(struct arpcom *ac, struct ether_header *eh, struct mbuf *m)
|
|||
} else {
|
||||
room = (mtod(m, caddr_t) - m->m_pktdat);
|
||||
}
|
||||
if (room > sizeof (*eh)) {
|
||||
if (room > sizeof (*eh)) {
|
||||
/* we have room, just copy it and adjust */
|
||||
m->m_len += sizeof(*eh);
|
||||
m->m_data -= sizeof(*eh);
|
||||
m->m_pkthdr.len += sizeof(*eh);
|
||||
} else {
|
||||
/*
|
||||
* Doing anything more is likely to get more
|
||||
* Doing anything more is likely to get more
|
||||
* expensive than it's worth..
|
||||
* it's probable that everything else is in one
|
||||
* big lump. The next node will do an m_pullup()
|
||||
|
|
@ -1230,7 +1276,7 @@ ngether_connect(hook_p hook)
|
|||
/*
|
||||
* notify on hook disconnection (destruction)
|
||||
*
|
||||
* For this type, removal of the last lins no effect. The interface can run
|
||||
* For this type, removal of the last lins no effect. The interface can run
|
||||
* independently.
|
||||
* Since we have no per-hook information, this is rather simple.
|
||||
*/
|
||||
|
|
|
|||
71
sys/net/if_gif.h
Normal file
71
sys/net/if_gif.h
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* if_gif.h
|
||||
*/
|
||||
|
||||
#ifndef _NET_IF_GIF_H_
|
||||
#define _NET_IF_GIF_H_
|
||||
|
||||
#include <netinet/in.h>
|
||||
/* xxx sigh, why route have struct route instead of pointer? */
|
||||
|
||||
struct gif_softc {
|
||||
struct ifnet gif_if; /* common area */
|
||||
struct sockaddr *gif_psrc; /* Physical src addr */
|
||||
struct sockaddr *gif_pdst; /* Physical dst addr */
|
||||
union {
|
||||
struct route gifscr_ro; /* xxx */
|
||||
struct route_in6 gifscr_ro6; /* xxx */
|
||||
} gifsc_gifscr;
|
||||
int gif_flags;
|
||||
};
|
||||
|
||||
#define gif_ro gifsc_gifscr.gifscr_ro
|
||||
#define gif_ro6 gifsc_gifscr.gifscr_ro6
|
||||
|
||||
#define GIFF_INUSE 0x1 /* gif is in use */
|
||||
|
||||
#define GIF_MTU (1280) /* Default MTU */
|
||||
#define GIF_MTU_MIN (1280) /* Minimum MTU */
|
||||
#define GIF_MTU_MAX (8192) /* Maximum MTU */
|
||||
|
||||
extern int ngif;
|
||||
extern struct gif_softc *gif;
|
||||
|
||||
/* Prototypes */
|
||||
void gif_input __P((struct mbuf *, int, struct ifnet *));
|
||||
int gif_output __P((struct ifnet *, struct mbuf *,
|
||||
struct sockaddr *, struct rtentry *));
|
||||
int gif_ioctl __P((struct ifnet *, u_long, caddr_t));
|
||||
|
||||
#endif /* _NET_IF_GIF_H_ */
|
||||
|
|
@ -67,6 +67,14 @@
|
|||
#include <netipx/ipx_if.h>
|
||||
#endif
|
||||
|
||||
#ifdef INET6
|
||||
#ifndef INET
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#include <netinet6/in6_var.h>
|
||||
#include <netinet6/ip6.h>
|
||||
#endif
|
||||
|
||||
#ifdef NS
|
||||
#include <netns/ns.h>
|
||||
#include <netns/ns_if.h>
|
||||
|
|
@ -93,6 +101,8 @@ static int looutput __P((struct ifnet *ifp,
|
|||
|
||||
#ifdef TINY_LOMTU
|
||||
#define LOMTU (1024+512)
|
||||
#elif defined(LARGE_LOMTU)
|
||||
#define LOMTU 131072
|
||||
#else
|
||||
#define LOMTU 16384
|
||||
#endif
|
||||
|
|
@ -136,11 +146,41 @@ looutput(ifp, m, dst, rt)
|
|||
return (rt->rt_flags & RTF_BLACKHOLE ? 0 :
|
||||
rt->rt_flags & RTF_HOST ? EHOSTUNREACH : ENETUNREACH);
|
||||
}
|
||||
/*
|
||||
* KAME requires that the packet to be contiguous on the
|
||||
* mbuf. We need to make that sure.
|
||||
* this kind of code should be avoided.
|
||||
* XXX: fails to join if interface MTU > MCLBYTES. jumbogram?
|
||||
*/
|
||||
if (m && m->m_next != NULL && m->m_pkthdr.len < MCLBYTES) {
|
||||
struct mbuf *n;
|
||||
|
||||
MGETHDR(n, M_DONTWAIT, MT_HEADER);
|
||||
if (!n)
|
||||
goto contiguousfail;
|
||||
MCLGET(n, M_DONTWAIT);
|
||||
if (! (n->m_flags & M_EXT)) {
|
||||
m_freem(n);
|
||||
goto contiguousfail;
|
||||
}
|
||||
|
||||
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;
|
||||
m_freem(m);
|
||||
m = n;
|
||||
}
|
||||
if (0) {
|
||||
contiguousfail:
|
||||
printf("looutput: mbuf allocation failed\n");
|
||||
}
|
||||
|
||||
ifp->if_opackets++;
|
||||
ifp->if_obytes += m->m_pkthdr.len;
|
||||
#if 1 /* XXX */
|
||||
switch (dst->sa_family) {
|
||||
case AF_INET:
|
||||
case AF_INET6:
|
||||
case AF_IPX:
|
||||
case AF_NS:
|
||||
case AF_ISO:
|
||||
|
|
@ -227,6 +267,13 @@ if_simloop(ifp, m, dst, hlen)
|
|||
isr = NETISR_IP;
|
||||
break;
|
||||
#endif
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
m->m_flags |= M_LOOP;
|
||||
ifq = &ip6intrq;
|
||||
isr = NETISR_IPV6;
|
||||
break;
|
||||
#endif
|
||||
#ifdef IPX
|
||||
case AF_IPX:
|
||||
ifq = &ipxintrq;
|
||||
|
|
@ -285,7 +332,7 @@ lortrequest(cmd, rt, sa)
|
|||
* should be at least twice the MTU plus a little more for
|
||||
* overhead.
|
||||
*/
|
||||
rt->rt_rmx.rmx_recvpipe =
|
||||
rt->rt_rmx.rmx_recvpipe =
|
||||
rt->rt_rmx.rmx_sendpipe = 3 * LOMTU;
|
||||
}
|
||||
}
|
||||
|
|
@ -327,6 +374,10 @@ loioctl(ifp, cmd, data)
|
|||
case AF_INET:
|
||||
break;
|
||||
#endif
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
error = EAFNOSUPPORT;
|
||||
|
|
|
|||
|
|
@ -166,6 +166,10 @@ typedef void if_init_f_t __P((void *));
|
|||
#define if_xmitquota if_data.ifi_xmitquota
|
||||
#define if_rawoutput(if, m, sa) if_output(if, m, sa, (struct rtentry *)0)
|
||||
|
||||
/* for compatibility with other BSDs */
|
||||
#define if_addrlist if_addrhead
|
||||
#define if_list if_link
|
||||
|
||||
/*
|
||||
* Bit values in if_ipending
|
||||
*/
|
||||
|
|
@ -270,16 +274,19 @@ struct ifaddr {
|
|||
};
|
||||
#define IFA_ROUTE RTF_UP /* route installed */
|
||||
|
||||
/* for compatibility with other BSDs */
|
||||
#define ifa_list ifa_link
|
||||
|
||||
/*
|
||||
* The prefix structure contains information about one prefix
|
||||
* of an interface. They are maintained by the different address families,
|
||||
* are allocated and attached when an prefix or an address is set,
|
||||
* and are linked together so all prfefixes for an interface can be located.
|
||||
* and are linked together so all prefixes for an interface can be located.
|
||||
*/
|
||||
struct ifprefix {
|
||||
struct sockaddr *ifpr_prefix; /* prefix of interface */
|
||||
struct ifnet *ifpr_ifp; /* back-pointer to interface */
|
||||
TAILQ_ENTRY(ifprefix) *ifpr_list; /* queue macro glue */
|
||||
TAILQ_ENTRY(ifprefix) ifpr_list; /* queue macro glue */
|
||||
u_char ifpr_plen; /* prefix length in bits */
|
||||
u_char ifpr_type; /* protocol dependent prefix type */
|
||||
};
|
||||
|
|
@ -321,7 +328,7 @@ int ether_output __P((struct ifnet *,
|
|||
struct mbuf *, struct sockaddr *, struct rtentry *));
|
||||
int ether_ioctl __P((struct ifnet *, int, caddr_t));
|
||||
|
||||
int if_addmulti __P((struct ifnet *, struct sockaddr *,
|
||||
int if_addmulti __P((struct ifnet *, struct sockaddr *,
|
||||
struct ifmultiaddr **));
|
||||
int if_allmulti __P((struct ifnet *, int));
|
||||
void if_attach __P((struct ifnet *));
|
||||
|
|
@ -352,7 +359,7 @@ struct ifaddr *ifa_ifwithroute __P((int, struct sockaddr *,
|
|||
struct ifaddr *ifaof_ifpforaddr __P((struct sockaddr *, struct ifnet *));
|
||||
void ifafree __P((struct ifaddr *));
|
||||
|
||||
struct ifmultiaddr *ifmaof_ifpforaddr __P((struct sockaddr *,
|
||||
struct ifmultiaddr *ifmaof_ifpforaddr __P((struct sockaddr *,
|
||||
struct ifnet *));
|
||||
int if_simloop __P((struct ifnet *ifp, struct mbuf *m,
|
||||
struct sockaddr *dst, int hlen));
|
||||
|
|
|
|||
58
sys/net/net_osdep.c
Normal file
58
sys/net/net_osdep.c
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sockio.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/syslog.h>
|
||||
#include <machine/cpu.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_types.h>
|
||||
#include <net/netisr.h>
|
||||
#include <net/route.h>
|
||||
#include <net/bpf.h>
|
||||
#include <net/net_osdep.h>
|
||||
|
||||
const char *
|
||||
if_name(ifp)
|
||||
struct ifnet *ifp;
|
||||
{
|
||||
static char nam[IFNAMSIZ + 10]; /*enough?*/
|
||||
|
||||
snprintf(nam, sizeof(nam), "%s%d", ifp->if_name, ifp->if_unit);
|
||||
return nam;
|
||||
}
|
||||
121
sys/net/net_osdep.h
Normal file
121
sys/net/net_osdep.h
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
/*
|
||||
* glue for kernel code programming differences.
|
||||
*/
|
||||
|
||||
/*
|
||||
* OS dependencies:
|
||||
*
|
||||
* - privileged process
|
||||
* NetBSD, FreeBSD 3
|
||||
* struct proc *p;
|
||||
* if (p && !suser(p->p_ucred, &p->p_acflag))
|
||||
* privileged;
|
||||
* OpenBSD, BSDI [34], FreeBSD 2
|
||||
* struct socket *so;
|
||||
* if (so->so_state & SS_PRIV)
|
||||
* privileged;
|
||||
* - foo_control
|
||||
* NetBSD, FreeBSD 3
|
||||
* needs to give struct proc * as argument
|
||||
* OpenBSD, BSDI [34], FreeBSD 2
|
||||
* do not need struct proc *
|
||||
* - bpf:
|
||||
* OpenBSD, NetBSD, BSDI [34]
|
||||
* need caddr_t * (= if_bpf **) and struct ifnet *
|
||||
* FreeBSD 2, FreeBSD 3
|
||||
* need only struct ifnet * as argument
|
||||
* - struct ifnet
|
||||
* use queue.h? member names if name
|
||||
* --- --- ---
|
||||
* FreeBSD 2 no old standard if_name+unit
|
||||
* FreeBSD 3 yes strange if_name+unit
|
||||
* 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
|
||||
* timeout() is a void function
|
||||
* FreeBSD 3
|
||||
* timeout() is non-void, must keep returned value for untimeuot()
|
||||
* - sysctl
|
||||
* NetBSD, OpenBSD
|
||||
* foo_sysctl()
|
||||
* BSDI [34]
|
||||
* foo_sysctl() but with different style
|
||||
* FreeBSD 2, FreeBSD 3
|
||||
* linker hack
|
||||
*
|
||||
* - 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);
|
||||
* FreeBSD 2, FreeBSD 3
|
||||
* void xxattach(void *);
|
||||
* PSEUDO_SET(xxattach, if_xx);
|
||||
*
|
||||
* - 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().
|
||||
*
|
||||
* - dtom()
|
||||
* NEVER USE IT!
|
||||
*/
|
||||
|
||||
#ifndef __NET_NET_OSDEP_H_DEFINED_
|
||||
#define __NET_NET_OSDEP_H_DEFINED_
|
||||
#ifdef _KERNEL
|
||||
|
||||
struct ifnet;
|
||||
extern const char *if_name __P((struct ifnet *));
|
||||
|
||||
#define HAVE_OLD_BPF
|
||||
|
||||
#endif /*_KERNEL*/
|
||||
#endif /*__NET_NET_OSDEP_H_DEFINED_ */
|
||||
420
sys/net/pfkeyv2.h
Normal file
420
sys/net/pfkeyv2.h
Normal file
|
|
@ -0,0 +1,420 @@
|
|||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/* $Id: keyv2.h,v 1.1.6.1.6.4 1999/06/08 05:33:39 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* This file has been derived rfc 2367,
|
||||
* And added some flags of SADB_KEY_FLAGS_ as SADB_X_EXT_.
|
||||
* sakane@ydc.co.jp
|
||||
*/
|
||||
|
||||
#ifndef _NET_PFKEYV2_H_
|
||||
#define _NET_PFKEYV2_H_
|
||||
|
||||
/*
|
||||
This file defines structures and symbols for the PF_KEY Version 2
|
||||
key management interface. It was written at the U.S. Naval Research
|
||||
Laboratory. This file is in the public domain. The authors ask that
|
||||
you leave this credit intact on any copies of this file.
|
||||
*/
|
||||
#ifndef __PFKEY_V2_H
|
||||
#define __PFKEY_V2_H 1
|
||||
|
||||
#define PF_KEY_V2 2
|
||||
#define PFKEYV2_REVISION 199806L
|
||||
|
||||
#define SADB_RESERVED 0
|
||||
#define SADB_GETSPI 1
|
||||
#define SADB_UPDATE 2
|
||||
#define SADB_ADD 3
|
||||
#define SADB_DELETE 4
|
||||
#define SADB_GET 5
|
||||
#define SADB_ACQUIRE 6
|
||||
#define SADB_REGISTER 7
|
||||
#define SADB_EXPIRE 8
|
||||
#define SADB_FLUSH 9
|
||||
#define SADB_DUMP 10
|
||||
#define SADB_X_PROMISC 11
|
||||
#define SADB_X_PCHANGE 12
|
||||
|
||||
#define SADB_X_SPDUPDATE 13 /* not yet */
|
||||
#define SADB_X_SPDADD 14
|
||||
#define SADB_X_SPDDELETE 15
|
||||
#define SADB_X_SPDGET 16 /* not yet */
|
||||
#define SADB_X_SPDACQUIRE 17 /* not yet */
|
||||
#define SADB_X_SPDDUMP 18
|
||||
#define SADB_X_SPDFLUSH 19
|
||||
#define SADB_MAX 19
|
||||
|
||||
struct sadb_msg {
|
||||
u_int8_t sadb_msg_version;
|
||||
u_int8_t sadb_msg_type;
|
||||
u_int8_t sadb_msg_errno;
|
||||
u_int8_t sadb_msg_satype;
|
||||
u_int16_t sadb_msg_len;
|
||||
u_int8_t sadb_msg_mode; /* XXX */
|
||||
u_int8_t sadb_msg_reserved;
|
||||
u_int32_t sadb_msg_seq;
|
||||
u_int32_t sadb_msg_pid;
|
||||
};
|
||||
|
||||
struct sadb_ext {
|
||||
u_int16_t sadb_ext_len;
|
||||
u_int16_t sadb_ext_type;
|
||||
};
|
||||
|
||||
struct sadb_sa {
|
||||
u_int16_t sadb_sa_len;
|
||||
u_int16_t sadb_sa_exttype;
|
||||
u_int32_t sadb_sa_spi;
|
||||
u_int8_t sadb_sa_replay;
|
||||
u_int8_t sadb_sa_state;
|
||||
u_int8_t sadb_sa_auth;
|
||||
u_int8_t sadb_sa_encrypt;
|
||||
u_int32_t sadb_sa_flags;
|
||||
};
|
||||
|
||||
struct sadb_lifetime {
|
||||
u_int16_t sadb_lifetime_len;
|
||||
u_int16_t sadb_lifetime_exttype;
|
||||
u_int32_t sadb_lifetime_allocations;
|
||||
u_int64_t sadb_lifetime_bytes;
|
||||
u_int64_t sadb_lifetime_addtime;
|
||||
u_int64_t sadb_lifetime_usetime;
|
||||
};
|
||||
|
||||
struct sadb_address {
|
||||
u_int16_t sadb_address_len;
|
||||
u_int16_t sadb_address_exttype;
|
||||
u_int8_t sadb_address_proto;
|
||||
u_int8_t sadb_address_prefixlen;
|
||||
u_int16_t sadb_address_reserved;
|
||||
};
|
||||
|
||||
struct sadb_key {
|
||||
u_int16_t sadb_key_len;
|
||||
u_int16_t sadb_key_exttype;
|
||||
u_int16_t sadb_key_bits;
|
||||
u_int16_t sadb_key_reserved;
|
||||
};
|
||||
|
||||
struct sadb_ident {
|
||||
u_int16_t sadb_ident_len;
|
||||
u_int16_t sadb_ident_exttype;
|
||||
u_int16_t sadb_ident_type;
|
||||
u_int16_t sadb_ident_reserved;
|
||||
u_int64_t sadb_ident_id;
|
||||
};
|
||||
/* in order to use to divide sadb_ident.sadb_ident_id */
|
||||
union sadb_x_ident_id {
|
||||
u_int64_t sadb_x_ident_id;
|
||||
struct _sadb_x_ident_id_addr {
|
||||
u_int16_t prefix;
|
||||
u_int16_t ul_proto;
|
||||
u_int32_t reserved;
|
||||
} sadb_x_ident_id_addr;
|
||||
};
|
||||
|
||||
struct sadb_sens {
|
||||
u_int16_t sadb_sens_len;
|
||||
u_int16_t sadb_sens_exttype;
|
||||
u_int32_t sadb_sens_dpd;
|
||||
u_int8_t sadb_sens_sens_level;
|
||||
u_int8_t sadb_sens_sens_len;
|
||||
u_int8_t sadb_sens_integ_level;
|
||||
u_int8_t sadb_sens_integ_len;
|
||||
u_int32_t sadb_sens_reserved;
|
||||
};
|
||||
|
||||
struct sadb_prop {
|
||||
u_int16_t sadb_prop_len;
|
||||
u_int16_t sadb_prop_exttype;
|
||||
u_int8_t sadb_prop_replay;
|
||||
u_int8_t sadb_prop_reserved[3];
|
||||
};
|
||||
|
||||
struct sadb_comb {
|
||||
u_int8_t sadb_comb_auth;
|
||||
u_int8_t sadb_comb_encrypt;
|
||||
u_int16_t sadb_comb_flags;
|
||||
u_int16_t sadb_comb_auth_minbits;
|
||||
u_int16_t sadb_comb_auth_maxbits;
|
||||
u_int16_t sadb_comb_encrypt_minbits;
|
||||
u_int16_t sadb_comb_encrypt_maxbits;
|
||||
u_int32_t sadb_comb_reserved;
|
||||
u_int32_t sadb_comb_soft_allocations;
|
||||
u_int32_t sadb_comb_hard_allocations;
|
||||
u_int64_t sadb_comb_soft_bytes;
|
||||
u_int64_t sadb_comb_hard_bytes;
|
||||
u_int64_t sadb_comb_soft_addtime;
|
||||
u_int64_t sadb_comb_hard_addtime;
|
||||
u_int64_t sadb_comb_soft_usetime;
|
||||
u_int64_t sadb_comb_hard_usetime;
|
||||
};
|
||||
|
||||
struct sadb_supported {
|
||||
u_int16_t sadb_supported_len;
|
||||
u_int16_t sadb_supported_exttype;
|
||||
u_int32_t sadb_supported_reserved;
|
||||
};
|
||||
|
||||
struct sadb_alg {
|
||||
u_int8_t sadb_alg_id;
|
||||
u_int8_t sadb_alg_ivlen;
|
||||
u_int16_t sadb_alg_minbits;
|
||||
u_int16_t sadb_alg_maxbits;
|
||||
u_int16_t sadb_alg_reserved;
|
||||
};
|
||||
|
||||
struct sadb_spirange {
|
||||
u_int16_t sadb_spirange_len;
|
||||
u_int16_t sadb_spirange_exttype;
|
||||
u_int32_t sadb_spirange_min;
|
||||
u_int32_t sadb_spirange_max;
|
||||
u_int32_t sadb_spirange_reserved;
|
||||
};
|
||||
|
||||
struct sadb_x_kmprivate {
|
||||
u_int16_t sadb_x_kmprivate_len;
|
||||
u_int16_t sadb_x_kmprivate_exttype;
|
||||
u_int32_t sadb_x_kmprivate_reserved;
|
||||
};
|
||||
|
||||
/* XXX Policy Extension */
|
||||
/* sizeof(struct sadb_x_policy) == 8 */
|
||||
struct sadb_x_policy {
|
||||
u_int16_t sadb_x_policy_len;
|
||||
u_int16_t sadb_x_policy_exttype;
|
||||
/* See policy type of ipsec.h */
|
||||
u_int16_t sadb_x_policy_type;
|
||||
u_int8_t sadb_x_policy_dir; /* direction, see ipsec.h */
|
||||
u_int8_t sadb_x_policy_reserved;
|
||||
};
|
||||
/*
|
||||
* When policy_type == IPSEC, it is followed by some of
|
||||
* the ipsec policy request.
|
||||
* [total length of ipsec policy requests]
|
||||
* = (sadb_x_policy_len * sizeof(uint64_t) - sizeof(struct sadb_x_policy))
|
||||
*/
|
||||
|
||||
/* XXX IPsec Policy Request Extension */
|
||||
/*
|
||||
* This structure is aligned 8 bytes.
|
||||
*/
|
||||
struct sadb_x_ipsecrequest {
|
||||
u_int16_t sadb_x_ipsecrequest_len;
|
||||
/* structure length aligned to 8 bytes.
|
||||
* This value is true length of bytes.
|
||||
* Not in units of 64 bits. */
|
||||
u_int16_t sadb_x_ipsecrequest_proto; /* See ipsec.h */
|
||||
/* See ipsec.h. Not SADB_SATYPE_XX */
|
||||
u_int16_t sadb_x_ipsecrequest_mode;
|
||||
u_int16_t sadb_x_ipsecrequest_level; /* See ipsec.h */
|
||||
|
||||
/*
|
||||
* followed by source IP address of SA, and immediately followed by
|
||||
* destination IP address of SA. These encoded into two of sockaddr
|
||||
* structure without any padding. Must set each sa_len exactly.
|
||||
* Each of length of the sockaddr structure are not aligned to 64bits,
|
||||
* but sum of x_request and addresses is aligned to 64bits.
|
||||
*/
|
||||
};
|
||||
|
||||
#define SADB_EXT_RESERVED 0
|
||||
#define SADB_EXT_SA 1
|
||||
#define SADB_EXT_LIFETIME_CURRENT 2
|
||||
#define SADB_EXT_LIFETIME_HARD 3
|
||||
#define SADB_EXT_LIFETIME_SOFT 4
|
||||
#define SADB_EXT_ADDRESS_SRC 5
|
||||
#define SADB_EXT_ADDRESS_DST 6
|
||||
#define SADB_EXT_ADDRESS_PROXY 7
|
||||
#define SADB_EXT_KEY_AUTH 8
|
||||
#define SADB_EXT_KEY_ENCRYPT 9
|
||||
#define SADB_EXT_IDENTITY_SRC 10
|
||||
#define SADB_EXT_IDENTITY_DST 11
|
||||
#define SADB_EXT_SENSITIVITY 12
|
||||
#define SADB_EXT_PROPOSAL 13
|
||||
#define SADB_EXT_SUPPORTED_AUTH 14
|
||||
#define SADB_EXT_SUPPORTED_ENCRYPT 15
|
||||
#define SADB_EXT_SPIRANGE 16
|
||||
#define SADB_X_EXT_KMPRIVATE 17
|
||||
#define SADB_X_EXT_POLICY 18
|
||||
#define SADB_EXT_MAX 18
|
||||
|
||||
#define SADB_SATYPE_UNSPEC 0
|
||||
#define SADB_SATYPE_AH 2
|
||||
#define SADB_SATYPE_ESP 3
|
||||
#define SADB_SATYPE_RSVP 5
|
||||
#define SADB_SATYPE_OSPFV2 6
|
||||
#define SADB_SATYPE_RIPV2 7
|
||||
#define SADB_SATYPE_MIP 8
|
||||
#define SADB_X_SATYPE_IPCOMP 9
|
||||
#define SADB_SATYPE_MAX 9
|
||||
|
||||
#define SADB_SASTATE_LARVAL 0
|
||||
#define SADB_SASTATE_MATURE 1
|
||||
#define SADB_SASTATE_DYING 2
|
||||
#define SADB_SASTATE_DEAD 3
|
||||
#define SADB_SASTATE_MAX 3
|
||||
#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
|
||||
|
||||
#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
|
||||
|
||||
/*nonstandard */
|
||||
#define SADB_X_CALG_NONE 0
|
||||
#define SADB_X_CALG_OUI 1
|
||||
#define SADB_X_CALG_DEFLATE 2
|
||||
#define SADB_X_CALG_LZS 3
|
||||
|
||||
#define SADB_IDENTTYPE_RESERVED 0
|
||||
#define SADB_IDENTTYPE_PREFIX 1
|
||||
#define SADB_IDENTTYPE_FQDN 2
|
||||
#define SADB_IDENTTYPE_USERFQDN 3
|
||||
#define SADB_X_IDENTTYPE_ADDR 4
|
||||
#define SADB_IDENTTYPE_MAX 4
|
||||
|
||||
/* `flags' in sadb_sa structure holds followings */
|
||||
#define SADB_X_EXT_NONE 0x0000 /* i.e. new format. */
|
||||
#define SADB_X_EXT_OLD 0x0001 /* old format. */
|
||||
|
||||
#define SADB_X_EXT_IV4B 0x0010 /* IV length of 4 bytes in use */
|
||||
#define SADB_X_EXT_DERIV 0x0020 /* DES derived */
|
||||
#define SADB_X_EXT_CYCSEQ 0x0040 /* allowing to cyclic sequence. */
|
||||
|
||||
/* three of followings are exclusive flags each them */
|
||||
#define SADB_X_EXT_PSEQ 0x0000 /* sequencial padding for ESP */
|
||||
#define SADB_X_EXT_PRAND 0x0100 /* random padding for ESP */
|
||||
#define SADB_X_EXT_PZERO 0x0200 /* zero padding for ESP */
|
||||
#define SADB_X_EXT_PMASK 0x0300 /* mask for padding flag */
|
||||
|
||||
#define SADB_X_EXT_RAWCPI 0x0080 /* use well known CPI (IPComp) */
|
||||
|
||||
#define SADB_KEY_FLAGS_MAX 0x0fff
|
||||
|
||||
/* SPI size for PF_KEYv2 */
|
||||
#define PFKEY_SPI_SIZE sizeof(u_int32_t)
|
||||
|
||||
/* Identifier for menber of lifetime structure */
|
||||
#define SADB_X_LIFETIME_ALLOCATIONS 0
|
||||
#define SADB_X_LIFETIME_BYTES 1
|
||||
#define SADB_X_LIFETIME_ADDTIME 2
|
||||
#define SADB_X_LIFETIME_USETIME 3
|
||||
|
||||
/* The rate for SOFT lifetime against HARD one. */
|
||||
#define PFKEY_SOFT_LIFETIME_RATE 80
|
||||
|
||||
/* Utilities */
|
||||
#define PFKEY_ALIGN8(a) (1 + (((a) - 1) | (8 - 1)))
|
||||
#define PFKEY_EXTLEN(msg) \
|
||||
PFKEY_UNUNIT64(((struct sadb_ext *)(msg))->sadb_ext_len)
|
||||
#define PFKEY_ADDR_PREFIX(ext) \
|
||||
(((struct sadb_address *)(ext))->sadb_address_prefixlen)
|
||||
#define PFKEY_ADDR_PROTO(ext) \
|
||||
(((struct sadb_address *)(ext))->sadb_address_proto)
|
||||
#define PFKEY_ADDR_SADDR(ext) \
|
||||
((struct sockaddr *)((caddr_t)(ext) + sizeof(struct sadb_address)))
|
||||
|
||||
/* in 64bits */
|
||||
#define PFKEY_UNUNIT64(a) ((a) << 3)
|
||||
#define PFKEY_UNIT64(a) ((a) >> 3)
|
||||
|
||||
#ifndef KERNEL
|
||||
extern void pfkey_sadump(struct sadb_msg *m);
|
||||
extern void pfkey_spdump(struct sadb_msg *m);
|
||||
|
||||
struct sockaddr;
|
||||
int ipsec_check_keylen __P((u_int supported, u_int alg_id, u_int keylen));
|
||||
u_int pfkey_set_softrate __P((u_int type, u_int rate));
|
||||
u_int pfkey_get_softrate __P((u_int type));
|
||||
int pfkey_send_getspi __P((int so, u_int satype, u_int mode,
|
||||
struct sockaddr *src, struct sockaddr *dst,
|
||||
u_int32_t min, u_int32_t max, u_int32_t seq));
|
||||
int pfkey_send_update __P((int so, u_int satype, u_int mode,
|
||||
struct sockaddr *src, struct sockaddr *dst,
|
||||
u_int32_t spi, u_int wsize, caddr_t keymat,
|
||||
u_int e_type, u_int e_keylen, u_int a_type,
|
||||
u_int a_keylen, u_int flags, u_int32_t l_alloc,
|
||||
u_int64_t l_bytes, u_int64_t l_addtime,
|
||||
u_int64_t l_usetime, u_int32_t seq));
|
||||
int pfkey_send_add __P((int so, u_int satype, u_int mode,
|
||||
struct sockaddr *src, struct sockaddr *dst,
|
||||
u_int32_t spi, u_int wsize, caddr_t keymat,
|
||||
u_int e_type, u_int e_keylen, u_int a_type,
|
||||
u_int a_keylen, u_int flags, u_int32_t l_alloc,
|
||||
u_int64_t l_bytes, u_int64_t l_addtime,
|
||||
u_int64_t l_usetime, u_int32_t seq));
|
||||
int pfkey_send_delete __P((int so, u_int satype, u_int mode,
|
||||
struct sockaddr *src, struct sockaddr *dst,
|
||||
u_int32_t spi));
|
||||
int pfkey_send_get __P((int so, u_int satype, u_int mode,
|
||||
struct sockaddr *src, struct sockaddr *dst,
|
||||
u_int32_t spi));
|
||||
int pfkey_send_register __P((int so, u_int satype));
|
||||
int pfkey_recv_register __P((int so));
|
||||
int pfkey_send_flush __P((int so, u_int satype));
|
||||
int pfkey_send_dump __P((int so, u_int satype));
|
||||
int pfkey_send_promisc_toggle __P((int so, int flag));
|
||||
int pfkey_send_spdadd __P((int so, struct sockaddr *src, u_int prefs,
|
||||
struct sockaddr *dst, u_int prefd, u_int proto,
|
||||
caddr_t policy, int policylen, u_int32_t seq));
|
||||
int pfkey_send_spddelete __P((int so, struct sockaddr *src, u_int prefs,
|
||||
struct sockaddr *dst, u_int prefd, u_int proto, u_int32_t seq));
|
||||
int pfkey_send_spdflush __P((int so));
|
||||
int pfkey_send_spddump __P((int so));
|
||||
|
||||
int pfkey_open __P((void));
|
||||
void pfkey_close __P((int so));
|
||||
struct sadb_msg *pfkey_recv __P((int so));
|
||||
int pfkey_send __P((int so, struct sadb_msg *msg, int len));
|
||||
int pfkey_align __P((struct sadb_msg *msg, caddr_t *mhp));
|
||||
int pfkey_check __P((caddr_t *mhp));
|
||||
|
||||
#endif /*!KERNEL*/
|
||||
|
||||
#endif /* __PFKEY_V2_H */
|
||||
|
||||
#endif /* _NET_PFKEYV2_H_ */
|
||||
|
|
@ -103,6 +103,16 @@ rtalloc_ign(ro, ignore)
|
|||
ro->ro_rt = rtalloc1(&ro->ro_dst, 1, ignore);
|
||||
}
|
||||
|
||||
/* for INET6 */
|
||||
void
|
||||
rtcalloc(ro)
|
||||
register struct route *ro;
|
||||
{
|
||||
if (ro->ro_rt && ro->ro_rt->rt_ifp && (ro->ro_rt->rt_flags & RTF_UP))
|
||||
return; /* XXX */
|
||||
ro->ro_rt = rtalloc1(&ro->ro_dst, RTF_CLONING, 0UL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Look up the route that matches the address given
|
||||
* Or, at least try.. Create a cloned route if needed.
|
||||
|
|
@ -121,7 +131,7 @@ rtalloc1(dst, report, ignflags)
|
|||
u_long nflags;
|
||||
int s = splnet(), err = 0, msgtype = RTM_MISS;
|
||||
|
||||
/*
|
||||
/*
|
||||
* Look up the address in the table for that Address Family
|
||||
*/
|
||||
if (rnh && (rn = rnh->rnh_matchaddr((caddr_t)dst, rnh)) &&
|
||||
|
|
@ -151,7 +161,7 @@ rtalloc1(dst, report, ignflags)
|
|||
}
|
||||
if ((rt = newrt) && (rt->rt_flags & RTF_XRESOLVE)) {
|
||||
/*
|
||||
* If the new route specifies it be
|
||||
* If the new route specifies it be
|
||||
* externally resolved, then go do that.
|
||||
*/
|
||||
msgtype = RTM_RESOLVE;
|
||||
|
|
@ -216,7 +226,7 @@ rtfree(rt)
|
|||
if (rt->rt_refcnt <= 0 && (rt->rt_flags & RTF_UP) == 0) {
|
||||
if (rt->rt_nodes->rn_flags & (RNF_ACTIVE | RNF_ROOT))
|
||||
panic ("rtfree 2");
|
||||
/*
|
||||
/*
|
||||
* the rtentry must have been removed from the routing table
|
||||
* so it is represented in rttrash.. remove that now.
|
||||
*/
|
||||
|
|
@ -229,7 +239,7 @@ rtfree(rt)
|
|||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
/*
|
||||
* release references on items we hold them on..
|
||||
* e.g other routes and ifaddrs.
|
||||
*/
|
||||
|
|
@ -513,7 +523,7 @@ rtrequest(req, dst, gateway, netmask, flags, ret_nrt)
|
|||
*/
|
||||
rt->rt_flags &= ~RTF_UP;
|
||||
|
||||
/*
|
||||
/*
|
||||
* give the protocol a chance to keep things in sync.
|
||||
*/
|
||||
if ((ifa = rt->rt_ifa) && ifa->ifa_rtrequest)
|
||||
|
|
@ -593,6 +603,7 @@ rtrequest(req, dst, gateway, netmask, flags, ret_nrt)
|
|||
ifa->ifa_refcnt++;
|
||||
rt->rt_ifa = ifa;
|
||||
rt->rt_ifp = ifa->ifa_ifp;
|
||||
/* XXX mtu manipulation will be done in rnh_addaddr -- itojun */
|
||||
|
||||
rn = rnh->rnh_addaddr((caddr_t)ndst, (caddr_t)netmask,
|
||||
rnh, rt->rt_nodes);
|
||||
|
|
@ -607,7 +618,7 @@ rtrequest(req, dst, gateway, netmask, flags, ret_nrt)
|
|||
*/
|
||||
rt2 = rtalloc1(dst, 0, RTF_PRCLONING);
|
||||
if (rt2 && rt2->rt_parent) {
|
||||
rtrequest(RTM_DELETE,
|
||||
rtrequest(RTM_DELETE,
|
||||
(struct sockaddr *)rt_key(rt2),
|
||||
rt2->rt_gateway,
|
||||
rt_mask(rt2), rt2->rt_flags, 0);
|
||||
|
|
@ -638,9 +649,9 @@ rtrequest(req, dst, gateway, netmask, flags, ret_nrt)
|
|||
|
||||
rt->rt_parent = 0;
|
||||
|
||||
/*
|
||||
/*
|
||||
* If we got here from RESOLVE, then we are cloning
|
||||
* so clone the rest, and note that we
|
||||
* so clone the rest, and note that we
|
||||
* are a clone (and increment the parent's references)
|
||||
*/
|
||||
if (req == RTM_RESOLVE) {
|
||||
|
|
@ -846,8 +857,8 @@ rt_setgate(rt0, dst, gate)
|
|||
*/
|
||||
Bcopy(gate, (rt->rt_gateway = (struct sockaddr *)(new + dlen)), glen);
|
||||
|
||||
/*
|
||||
* if we are replacing the chunk (or it's new) we need to
|
||||
/*
|
||||
* if we are replacing the chunk (or it's new) we need to
|
||||
* replace the dst as well
|
||||
*/
|
||||
if (old) {
|
||||
|
|
@ -941,13 +952,15 @@ rtinit(ifa, cmd, flags)
|
|||
* be confusing at best and possibly worse.
|
||||
*/
|
||||
if (cmd == RTM_DELETE) {
|
||||
/*
|
||||
/*
|
||||
* It's a delete, so it should already exist..
|
||||
* If it's a net, mask off the host bits
|
||||
* (Assuming we have a mask)
|
||||
*/
|
||||
if ((flags & RTF_HOST) == 0 && ifa->ifa_netmask) {
|
||||
m = m_get(M_WAIT, MT_SONAME);
|
||||
m = m_get(M_DONTWAIT, MT_SONAME);
|
||||
if (m == NULL)
|
||||
return(ENOBUFS);
|
||||
deldst = mtod(m, struct sockaddr *);
|
||||
rt_maskedcopy(dst, deldst, ifa->ifa_netmask);
|
||||
dst = deldst;
|
||||
|
|
@ -971,7 +984,7 @@ rtinit(ifa, cmd, flags)
|
|||
* If the interface in the rtentry doesn't match
|
||||
* the interface we are using, then we don't
|
||||
* want to delete it, so return an error.
|
||||
* This seems to be the only point of
|
||||
* This seems to be the only point of
|
||||
* this whole RTM_DELETE clause.
|
||||
*/
|
||||
if (m)
|
||||
|
|
@ -983,7 +996,7 @@ rtinit(ifa, cmd, flags)
|
|||
/* XXX */
|
||||
#if 0
|
||||
else {
|
||||
/*
|
||||
/*
|
||||
* One would think that as we are deleting, and we know
|
||||
* it doesn't exist, we could just return at this point
|
||||
* with an "ELSE" clause, but apparently not..
|
||||
|
|
@ -1025,7 +1038,7 @@ rtinit(ifa, cmd, flags)
|
|||
*/
|
||||
rt->rt_refcnt--;
|
||||
/*
|
||||
* If it came back with an unexpected interface, then it must
|
||||
* If it came back with an unexpected interface, then it must
|
||||
* have already existed or something. (XXX)
|
||||
*/
|
||||
if (rt->rt_ifa != ifa) {
|
||||
|
|
@ -1038,7 +1051,7 @@ rtinit(ifa, cmd, flags)
|
|||
*/
|
||||
if (rt->rt_ifa->ifa_rtrequest)
|
||||
rt->rt_ifa->ifa_rtrequest(RTM_DELETE, rt, SA(0));
|
||||
/*
|
||||
/*
|
||||
* Remove the referenve to the it's ifaddr.
|
||||
*/
|
||||
IFAFREE(rt->rt_ifa);
|
||||
|
|
@ -1048,6 +1061,7 @@ rtinit(ifa, cmd, flags)
|
|||
*/
|
||||
rt->rt_ifa = ifa;
|
||||
rt->rt_ifp = ifa->ifa_ifp;
|
||||
rt->rt_rmx.rmx_mtu = ifa->ifa_ifp->if_mtu; /*XXX*/
|
||||
ifa->ifa_refcnt++;
|
||||
/*
|
||||
* Now ask the protocol to check if it needs
|
||||
|
|
|
|||
37
sys/netinet/icmp6.h
Normal file
37
sys/netinet/icmp6.h
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _NETINET_ICMP6_H_
|
||||
#define _NETINET_ICMP6_H_
|
||||
|
||||
#include <netinet6/icmp6.h>
|
||||
|
||||
#endif /* !_NETINET_ICMP6_H_ */
|
||||
|
|
@ -66,12 +66,12 @@ static void in_rtchange __P((struct inpcb *, int));
|
|||
* These configure the range of local port addresses assigned to
|
||||
* "unspecified" outgoing connections/packets/whatever.
|
||||
*/
|
||||
static int ipport_lowfirstauto = IPPORT_RESERVED - 1; /* 1023 */
|
||||
static int ipport_lowlastauto = IPPORT_RESERVEDSTART; /* 600 */
|
||||
static int ipport_firstauto = IPPORT_RESERVED; /* 1024 */
|
||||
static int ipport_lastauto = IPPORT_USERRESERVED; /* 5000 */
|
||||
static int ipport_hifirstauto = IPPORT_HIFIRSTAUTO; /* 49152 */
|
||||
static int ipport_hilastauto = IPPORT_HILASTAUTO; /* 65535 */
|
||||
int ipport_lowfirstauto = IPPORT_RESERVED - 1; /* 1023 */
|
||||
int ipport_lowlastauto = IPPORT_RESERVEDSTART; /* 600 */
|
||||
int ipport_firstauto = IPPORT_RESERVED; /* 1024 */
|
||||
int ipport_lastauto = IPPORT_USERRESERVED; /* 5000 */
|
||||
int ipport_hifirstauto = IPPORT_HIFIRSTAUTO; /* 49152 */
|
||||
int ipport_hilastauto = IPPORT_HILASTAUTO; /* 65535 */
|
||||
|
||||
#define RANGECHK(var, min, max) \
|
||||
if ((var) < (min)) { (var) = (min); } \
|
||||
|
|
@ -204,7 +204,7 @@ in_pcbbind(inp, nam, p)
|
|||
if (so->so_cred->cr_uid != 0 &&
|
||||
!IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) {
|
||||
t = in_pcblookup_local(inp->inp_pcbinfo,
|
||||
sin->sin_addr, lport,
|
||||
sin->sin_addr, lport,
|
||||
prison ? 0 : INPLOOKUP_WILDCARD);
|
||||
if (t &&
|
||||
(ntohl(sin->sin_addr.s_addr) != INADDR_ANY ||
|
||||
|
|
@ -409,7 +409,7 @@ in_pcbladdr(inp, nam, plocal_sin)
|
|||
imo = inp->inp_moptions;
|
||||
if (imo->imo_multicast_ifp != NULL) {
|
||||
ifp = imo->imo_multicast_ifp;
|
||||
for (ia = in_ifaddrhead.tqh_first; ia;
|
||||
for (ia = in_ifaddrhead.tqh_first; ia;
|
||||
ia = ia->ia_link.tqe_next)
|
||||
if (ia->ia_ifp == ifp)
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -39,6 +39,12 @@
|
|||
|
||||
#include <sys/queue.h>
|
||||
|
||||
|
||||
#include <netinet6/ipsec.h> /* for IPSEC */
|
||||
|
||||
#define in6pcb inpcb /* for KAME src sync over BSD*'s */
|
||||
#define in6p_sp inp_sp /* for KAME src sync over BSD*'s */
|
||||
|
||||
/*
|
||||
* Common structure pcb for internet protocol implementation.
|
||||
* Here are stored pointers to local and foreign host table
|
||||
|
|
@ -50,33 +56,112 @@ LIST_HEAD(inpcbhead, inpcb);
|
|||
LIST_HEAD(inpcbporthead, inpcbport);
|
||||
typedef u_quad_t inp_gen_t;
|
||||
|
||||
/*
|
||||
* PCB with AF_INET6 null bind'ed laddr can receive AF_INET input packet.
|
||||
* So, AF_INET6 null laddr is also used as AF_INET null laddr,
|
||||
* by utilize following structure. (At last, same as INRIA)
|
||||
*/
|
||||
struct in_addr_4in6 {
|
||||
u_int32_t ia46_pad32[3];
|
||||
struct in_addr ia46_addr4;
|
||||
};
|
||||
|
||||
/*
|
||||
* NB: the zone allocator is type-stable EXCEPT FOR THE FIRST TWO LONGS
|
||||
* of the structure. Therefore, it is important that the members in
|
||||
* that position not contain any information which is required to be
|
||||
* stable.
|
||||
*/
|
||||
struct icmp6_filter;
|
||||
|
||||
struct inpcb {
|
||||
LIST_ENTRY(inpcb) inp_hash; /* hash list */
|
||||
struct in_addr inp_faddr; /* foreign host table entry */
|
||||
struct in_addr inp_laddr; /* local host table entry */
|
||||
LIST_ENTRY(inpcb) inp_hash; /* hash list */
|
||||
u_short inp_fport; /* foreign port */
|
||||
u_short inp_lport; /* local port */
|
||||
LIST_ENTRY(inpcb) inp_list; /* list for all PCBs of this proto */
|
||||
LIST_ENTRY(inpcb) inp_list; /* list for all PCBs of this proto */
|
||||
u_int32_t inp_flow;
|
||||
|
||||
/* protocol dependent part, local and foreign addr */
|
||||
union {
|
||||
/* foreign host table entry */
|
||||
struct in_addr_4in6 inp46_foreign;
|
||||
struct in6_addr inp6_foreign;
|
||||
} inp_dependfaddr;
|
||||
union {
|
||||
/* local host table entry */
|
||||
struct in_addr_4in6 inp46_local;
|
||||
struct in6_addr inp6_local;
|
||||
} inp_dependladdr;
|
||||
|
||||
caddr_t inp_ppcb; /* pointer to per-protocol pcb */
|
||||
struct inpcbinfo *inp_pcbinfo; /* PCB list info */
|
||||
struct socket *inp_socket; /* back pointer to socket */
|
||||
struct mbuf *inp_options; /* IP options */
|
||||
struct route inp_route; /* placeholder for routing entry */
|
||||
/* list for this PCB's local port */
|
||||
int inp_flags; /* generic IP/datagram flags */
|
||||
u_char inp_ip_tos; /* type of service proto */
|
||||
|
||||
/* protocol dependent part; cached route */
|
||||
union {
|
||||
/* placeholder for routing entry */
|
||||
struct route inp4_route;
|
||||
struct route_in6 inp6_route;
|
||||
} inp_dependroute;
|
||||
|
||||
struct inpcbpolicy *inp_sp; /* for IPSEC */
|
||||
u_char inp_vflag;
|
||||
#define INP_IPV4 0x1
|
||||
#define INP_IPV6 0x2
|
||||
u_char inp_ip_ttl; /* time to live proto */
|
||||
u_char inp_ip_p; /* protocol proto */
|
||||
u_char pad[1]; /* alignment */
|
||||
struct ip_moptions *inp_moptions; /* IP multicast options */
|
||||
LIST_ENTRY(inpcb) inp_portlist; /* list for this PCB's local port */
|
||||
|
||||
/* protocol dependent part; options */
|
||||
struct {
|
||||
u_char inp4_ip_tos; /* type of service proto */
|
||||
struct mbuf *inp4_options; /* IP options */
|
||||
struct ip_moptions *inp4_moptions; /* IP multicast options */
|
||||
} inp_depend4;
|
||||
#define inp_faddr inp_dependfaddr.inp46_foreign.ia46_addr4
|
||||
#define inp_laddr inp_dependladdr.inp46_local.ia46_addr4
|
||||
#define inp_route inp_dependroute.inp4_route
|
||||
#define inp_ip_tos inp_depend4.inp4_ip_tos
|
||||
#define inp_options inp_depend4.inp4_options
|
||||
#define inp_moptions inp_depend4.inp4_moptions
|
||||
struct {
|
||||
/* IP options */
|
||||
struct mbuf *inp6_options;
|
||||
/* IP6 options for outgoing packets */
|
||||
struct ip6_pktopts *inp6_outputopts;
|
||||
/* IP multicast options */
|
||||
struct ip6_moptions *inp6_moptions;
|
||||
/* ICMPv6 code type filter */
|
||||
struct icmp6_filter *inp6_icmp6filt;
|
||||
/* IPV6_CHECKSUM setsockopt */
|
||||
int inp6_cksum;
|
||||
u_short inp6_ifindex;
|
||||
short inp6_hops;
|
||||
u_int8_t inp6_hlim;
|
||||
} inp_depend6;
|
||||
LIST_ENTRY(inpcb) inp_portlist;
|
||||
struct inpcbport *inp_phd; /* head of this list */
|
||||
inp_gen_t inp_gencnt; /* generation count of this instance */
|
||||
inp_gen_t inp_gencnt; /* generation count of this instance */
|
||||
#define in6p_faddr inp_dependfaddr.inp6_foreign
|
||||
#define in6p_laddr inp_dependladdr.inp6_local
|
||||
#define in6p_route inp_dependroute.inp6_route
|
||||
#define in6p_ip6_hlim inp_depend6.inp6_hlim
|
||||
#define in6p_hops inp_depend6.inp6_hops /* default hop limit */
|
||||
#define in6p_ip6_nxt inp_ip_p
|
||||
#define in6p_flowinfo inp_flow
|
||||
#define in6p_vflag inp_vflag
|
||||
#define in6p_options inp_depend6.inp6_options
|
||||
#define in6p_outputopts inp_depend6.inp6_outputopts
|
||||
#define in6p_moptions inp_depend6.inp6_moptions
|
||||
#define in6p_icmp6filt inp_depend6.inp6_icmp6filt
|
||||
#define in6p_cksum inp_depend6.inp6_cksum
|
||||
#define inp6_ifindex inp_depend6.inp6_ifindex
|
||||
#define in6p_flags inp_flags /* for KAME src sync over BSD*'s */
|
||||
#define in6p_socket inp_socket /* for KAME src sync over BSD*'s */
|
||||
#define in6p_lport inp_lport /* for KAME src sync over BSD*'s */
|
||||
#define in6p_fport inp_fport /* for KAME src sync over BSD*'s */
|
||||
#define in6p_ppcb inp_ppcb /* for KAME src sync over BSD*'s */
|
||||
};
|
||||
/*
|
||||
* The range of the generation count, as used in this implementation,
|
||||
|
|
@ -140,14 +225,54 @@ struct inpcbinfo { /* XXX documentation, prefixes */
|
|||
#define INP_ANONPORT 0x40 /* port chosen for user */
|
||||
#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 INP_CONTROLOPTS (INP_RECVOPTS|INP_RECVRETOPTS|INP_RECVDSTADDR|\
|
||||
INP_RECVIF)
|
||||
INP_RECVIF|\
|
||||
IN6P_PKTINFO|IN6P_HOPLIMIT|IN6P_NEXTHOP|\
|
||||
IN6P_HOPOPTS|IN6P_DSTOPTS|IN6P_RTHDR)
|
||||
|
||||
#define INP_UNMAPPABLEOPTS (IN6P_HOPOPTS|IN6P_DSTOPTS|IN6P_RTHDR)
|
||||
|
||||
/* 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
|
||||
#define IN6P_RECVIF INP_RECVIF
|
||||
#define IN6P_MTUDISC INP_MTUDISC
|
||||
#define IN6P_FAITH INP_FAITH
|
||||
#define IN6P_CONTROLOPTS INP_CONTROLOPTS
|
||||
/*
|
||||
* socket AF version is {newer than,or include}
|
||||
* actual datagram AF version
|
||||
*/
|
||||
|
||||
#define INPLOOKUP_WILDCARD 1
|
||||
|
||||
#define sotoinpcb(so) ((struct inpcb *)(so)->so_pcb)
|
||||
#define sotoin6pcb(so) sotoinpcb(so) /* for KAME src sync over BSD*'s */
|
||||
|
||||
#define INP_SOCKAF(so) so->so_proto->pr_domain->dom_family
|
||||
|
||||
#define INP_CHECK_SOCKAF(so, af) (INP_SOCKAF(so) == af)
|
||||
|
||||
#ifdef KERNEL
|
||||
extern int ipport_lowfirstauto;
|
||||
extern int ipport_lowlastauto;
|
||||
extern int ipport_firstauto;
|
||||
extern int ipport_lastauto;
|
||||
extern int ipport_hifirstauto;
|
||||
extern int ipport_hilastauto;
|
||||
|
||||
void in_losing __P((struct inpcb *));
|
||||
int in_pcballoc __P((struct socket *, struct inpcbinfo *, struct proc *));
|
||||
int in_pcbbind __P((struct inpcb *, struct sockaddr *, struct proc *));
|
||||
|
|
|
|||
32
sys/netinet/ip6.h
Normal file
32
sys/netinet/ip6.h
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <netinet6/ip6.h>
|
||||
|
|
@ -66,8 +66,8 @@
|
|||
#include <netinet/ip_dummynet.h>
|
||||
#endif
|
||||
|
||||
static struct inpcbhead ripcb;
|
||||
static struct inpcbinfo ripcbinfo;
|
||||
struct inpcbhead ripcb;
|
||||
struct inpcbinfo ripcbinfo;
|
||||
|
||||
/*
|
||||
* Nominal space allocated to a raw ip socket.
|
||||
|
|
@ -202,7 +202,7 @@ rip_output(m, so, dst)
|
|||
ip = mtod(m, struct ip *);
|
||||
/* don't allow both user specified and setsockopt options,
|
||||
and don't allow packet length sizes that will crash */
|
||||
if (((IP_VHL_HL(ip->ip_vhl) != (sizeof (*ip) >> 2))
|
||||
if (((IP_VHL_HL(ip->ip_vhl) != (sizeof (*ip) >> 2))
|
||||
&& inp->inp_options)
|
||||
|| (ip->ip_len > m->m_pkthdr.len)
|
||||
|| (ip->ip_len < (IP_VHL_HL(ip->ip_vhl) << 2))) {
|
||||
|
|
@ -411,12 +411,12 @@ rip_ctlinput(cmd, sa, vip)
|
|||
}
|
||||
}
|
||||
|
||||
static u_long rip_sendspace = RIPSNDQ;
|
||||
static u_long rip_recvspace = RIPRCVQ;
|
||||
u_long rip_sendspace = RIPSNDQ;
|
||||
u_long rip_recvspace = RIPRCVQ;
|
||||
|
||||
SYSCTL_INT(_net_inet_raw, OID_AUTO, maxdgram, CTLFLAG_RW,
|
||||
SYSCTL_INT(_net_inet_raw, OID_AUTO, maxdgram, CTLFLAG_RW,
|
||||
&rip_sendspace, 0, "Maximum outgoing raw IP datagram size");
|
||||
SYSCTL_INT(_net_inet_raw, OID_AUTO, recvspace, CTLFLAG_RW,
|
||||
SYSCTL_INT(_net_inet_raw, OID_AUTO, recvspace, CTLFLAG_RW,
|
||||
&rip_recvspace, 0, "Maximum incoming raw IP datagram size");
|
||||
|
||||
static int
|
||||
|
|
@ -632,6 +632,6 @@ struct pr_usrreqs rip_usrreqs = {
|
|||
rip_abort, pru_accept_notsupp, rip_attach, rip_bind, rip_connect,
|
||||
pru_connect2_notsupp, in_control, rip_detach, rip_disconnect,
|
||||
pru_listen_notsupp, in_setpeeraddr, pru_rcvd_notsupp,
|
||||
pru_rcvoob_notsupp, rip_send, pru_sense_null, rip_shutdown,
|
||||
pru_rcvoob_notsupp, rip_send, pru_sense_null, rip_shutdown,
|
||||
in_setsockaddr, sosend, soreceive, sopoll
|
||||
};
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
*/
|
||||
|
||||
#include "opt_compat.h"
|
||||
#include "opt_inet.h"
|
||||
#include "opt_tcpdebug.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
*/
|
||||
|
||||
#include "opt_compat.h"
|
||||
#include "opt_inet.h"
|
||||
#include "opt_tcpdebug.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
|
|
|
|||
108
sys/netinet6/dest6.c
Normal file
108
sys/netinet6/dest6.c
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/domain.h>
|
||||
#include <sys/protosw.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/kernel.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/route.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_var.h>
|
||||
#include <netinet6/ip6.h>
|
||||
#include <netinet6/ip6_var.h>
|
||||
#include <netinet6/icmp6.h>
|
||||
|
||||
/*
|
||||
* Destination options header processing.
|
||||
*/
|
||||
int
|
||||
dest6_input(mp, offp, proto)
|
||||
struct mbuf **mp;
|
||||
int *offp, proto;
|
||||
{
|
||||
register struct mbuf *m = *mp;
|
||||
int off = *offp, dstoptlen, optlen;
|
||||
struct ip6_dest *dstopts;
|
||||
u_int8_t *opt;
|
||||
|
||||
/* validation of the length of the header */
|
||||
IP6_EXTHDR_CHECK(m, off, sizeof(*dstopts), IPPROTO_DONE);
|
||||
dstopts = (struct ip6_dest *)(mtod(m, caddr_t) + off);
|
||||
dstoptlen = (dstopts->ip6d_len + 1) << 3;
|
||||
|
||||
IP6_EXTHDR_CHECK(m, off, dstoptlen, IPPROTO_DONE);
|
||||
dstopts = (struct ip6_dest *)(mtod(m, caddr_t) + off);
|
||||
off += dstoptlen;
|
||||
dstoptlen -= sizeof(struct ip6_dest);
|
||||
opt = (u_int8_t *)dstopts + sizeof(struct ip6_dest);
|
||||
|
||||
/* search header for all options. */
|
||||
for (optlen = 0; dstoptlen > 0; dstoptlen -= optlen, opt += optlen) {
|
||||
switch(*opt) {
|
||||
case IP6OPT_PAD1:
|
||||
optlen = 1;
|
||||
break;
|
||||
case IP6OPT_PADN:
|
||||
if (dstoptlen < IP6OPT_MINLEN) {
|
||||
ip6stat.ip6s_toosmall++;
|
||||
goto bad;
|
||||
}
|
||||
optlen = *(opt + 1) + 2;
|
||||
break;
|
||||
default: /* unknown option */
|
||||
if (dstoptlen < IP6OPT_MINLEN) {
|
||||
ip6stat.ip6s_toosmall++;
|
||||
goto bad;
|
||||
}
|
||||
if ((optlen = ip6_unknown_opt(opt, m,
|
||||
opt-mtod(m, u_int8_t *))) == -1)
|
||||
return(IPPROTO_DONE);
|
||||
optlen += 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*offp = off;
|
||||
return(dstopts->ip6d_nxt);
|
||||
|
||||
bad:
|
||||
m_freem(m);
|
||||
return(IPPROTO_DONE);
|
||||
}
|
||||
573
sys/netinet6/frag6.c
Normal file
573
sys/netinet6/frag6.c
Normal file
|
|
@ -0,0 +1,573 @@
|
|||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/domain.h>
|
||||
#include <sys/protosw.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/syslog.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/route.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_var.h>
|
||||
#include <netinet6/ip6.h>
|
||||
#include <netinet6/ip6_var.h>
|
||||
#include <netinet6/icmp6.h>
|
||||
|
||||
#include <net/net_osdep.h>
|
||||
|
||||
/*
|
||||
* Define it to get a correct behavior on per-interface statistics.
|
||||
* You will need to perform an extra routing table lookup, per fragment,
|
||||
* to do it. This may, or may not be, a performance hit.
|
||||
*/
|
||||
#define IN6_IFSTAT_STRICT
|
||||
|
||||
static void frag6_enq __P((struct ip6asfrag *, struct ip6asfrag *));
|
||||
static void frag6_deq __P((struct ip6asfrag *));
|
||||
static void frag6_insque __P((struct ip6q *, struct ip6q *));
|
||||
static void frag6_remque __P((struct ip6q *));
|
||||
static void frag6_freef __P((struct ip6q *));
|
||||
|
||||
int frag6_doing_reass;
|
||||
u_int frag6_nfragpackets;
|
||||
struct ip6q ip6q; /* ip6 reassemble queue */
|
||||
|
||||
#if !defined(M_FTABLE)
|
||||
MALLOC_DEFINE(M_FTABLE, "fragment", "fragment reassembly header");
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Initialise reassembly queue and fragment identifier.
|
||||
*/
|
||||
void
|
||||
frag6_init()
|
||||
{
|
||||
struct timeval tv;
|
||||
|
||||
/*
|
||||
* in many cases, random() here does NOT return random number
|
||||
* as initialization during bootstrap time occur in fixed order.
|
||||
*/
|
||||
microtime(&tv);
|
||||
ip6q.ip6q_next = ip6q.ip6q_prev = &ip6q;
|
||||
ip6_id = random() ^ tv.tv_usec;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fragment input
|
||||
*/
|
||||
int
|
||||
frag6_input(mp, offp, proto)
|
||||
struct mbuf **mp;
|
||||
int *offp, proto;
|
||||
{
|
||||
struct mbuf *m = *mp, *t;
|
||||
struct ip6_hdr *ip6;
|
||||
struct ip6_frag *ip6f;
|
||||
struct ip6q *q6;
|
||||
struct ip6asfrag *af6, *ip6af;
|
||||
int offset = *offp, nxt, i, next;
|
||||
int first_frag = 0;
|
||||
u_short fragoff, frgpartlen;
|
||||
struct ifnet *dstifp;
|
||||
#ifdef IN6_IFSTAT_STRICT
|
||||
static struct route_in6 ro;
|
||||
struct sockaddr_in6 *dst;
|
||||
#endif
|
||||
|
||||
IP6_EXTHDR_CHECK(m, offset, sizeof(struct ip6_frag), IPPROTO_DONE);
|
||||
|
||||
ip6 = mtod(m, struct ip6_hdr *);
|
||||
ip6f = (struct ip6_frag *)((caddr_t)ip6 + offset);
|
||||
|
||||
dstifp = NULL;
|
||||
#ifdef IN6_IFSTAT_STRICT
|
||||
/* find the destination interface of the packet. */
|
||||
dst = (struct sockaddr_in6 *)&ro.ro_dst;
|
||||
if (ro.ro_rt
|
||||
&& ((ro.ro_rt->rt_flags & RTF_UP) == 0
|
||||
|| !IN6_ARE_ADDR_EQUAL(&dst->sin6_addr, &ip6->ip6_dst))) {
|
||||
RTFREE(ro.ro_rt);
|
||||
ro.ro_rt = (struct rtentry *)0;
|
||||
}
|
||||
if (ro.ro_rt == NULL) {
|
||||
bzero(dst, sizeof(*dst));
|
||||
dst->sin6_family = AF_INET6;
|
||||
dst->sin6_len = sizeof(struct sockaddr_in6);
|
||||
dst->sin6_addr = ip6->ip6_dst;
|
||||
}
|
||||
rtcalloc((struct route *)&ro);
|
||||
if (ro.ro_rt != NULL && ro.ro_rt->rt_ifa != NULL)
|
||||
dstifp = ((struct in6_ifaddr *)ro.ro_rt->rt_ifa)->ia_ifp;
|
||||
#else
|
||||
/* we are violating the spec, this is not the destination interface */
|
||||
if ((m->m_flags & M_PKTHDR) != 0)
|
||||
dstifp = m->m_pkthdr.rcvif;
|
||||
#endif
|
||||
|
||||
/* jumbo payload can't contain a fragment header */
|
||||
if (ip6->ip6_plen == 0) {
|
||||
icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER, offset);
|
||||
in6_ifstat_inc(dstifp, ifs6_reass_fail);
|
||||
return IPPROTO_DONE;
|
||||
}
|
||||
|
||||
/*
|
||||
* check whether fragment packet's fragment length is
|
||||
* multiple of 8 octets.
|
||||
* sizeof(struct ip6_frag) == 8
|
||||
* sizeof(struct ip6_hdr) = 40
|
||||
*/
|
||||
if ((ip6f->ip6f_offlg & IP6F_MORE_FRAG) &&
|
||||
(((ntohs(ip6->ip6_plen) - offset) & 0x7) != 0)) {
|
||||
icmp6_error(m, ICMP6_PARAM_PROB,
|
||||
ICMP6_PARAMPROB_HEADER,
|
||||
(caddr_t)&ip6->ip6_plen - (caddr_t)ip6);
|
||||
in6_ifstat_inc(dstifp, ifs6_reass_fail);
|
||||
return IPPROTO_DONE;
|
||||
}
|
||||
|
||||
ip6stat.ip6s_fragments++;
|
||||
in6_ifstat_inc(dstifp, ifs6_reass_reqd);
|
||||
|
||||
/*
|
||||
* Presence of header sizes in mbufs
|
||||
* would confuse code below.
|
||||
*/
|
||||
|
||||
offset += sizeof(struct ip6_frag);
|
||||
m->m_data += offset;
|
||||
m->m_len -= offset;
|
||||
|
||||
for (q6 = ip6q.ip6q_next; q6 != &ip6q; q6 = q6->ip6q_next)
|
||||
if (ip6f->ip6f_ident == q6->ip6q_ident &&
|
||||
IN6_ARE_ADDR_EQUAL(&ip6->ip6_src, &q6->ip6q_src) &&
|
||||
IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst, &q6->ip6q_dst))
|
||||
break;
|
||||
|
||||
if (q6 == &ip6q) {
|
||||
/*
|
||||
* the first fragment to arrive, create a reassembly queue.
|
||||
*/
|
||||
first_frag = 1;
|
||||
frag6_nfragpackets++;
|
||||
|
||||
/*
|
||||
* Enforce upper bound on number of fragmented packets
|
||||
* for which we attempt reassembly;
|
||||
* If maxfrag is 0, never accept fragments.
|
||||
* If maxfrag is -1, accept all fragments without limitation.
|
||||
*/
|
||||
if (frag6_nfragpackets >= (u_int)ip6_maxfragpackets) {
|
||||
ip6stat.ip6s_fragoverflow++;
|
||||
in6_ifstat_inc(dstifp, ifs6_reass_fail);
|
||||
frag6_freef(ip6q.ip6q_prev);
|
||||
}
|
||||
q6 = (struct ip6q *)malloc(sizeof(struct ip6q), M_FTABLE,
|
||||
M_DONTWAIT);
|
||||
if (q6 == NULL)
|
||||
goto dropfrag;
|
||||
|
||||
frag6_insque(q6, &ip6q);
|
||||
|
||||
q6->ip6q_down = q6->ip6q_up = (struct ip6asfrag *)q6;
|
||||
q6->ip6q_ident = ip6f->ip6f_ident;
|
||||
q6->ip6q_arrive = 0; /* Is it used anywhere? */
|
||||
q6->ip6q_ttl = IPV6_FRAGTTL;
|
||||
q6->ip6q_src = ip6->ip6_src;
|
||||
q6->ip6q_dst = ip6->ip6_dst;
|
||||
q6->ip6q_unfrglen = -1; /* The 1st fragment has not arrived. */
|
||||
}
|
||||
|
||||
/*
|
||||
* If it's the 1st fragment, record the length of the
|
||||
* unfragmentable part and the next header of the fragment header.
|
||||
*/
|
||||
fragoff = ntohs(ip6f->ip6f_offlg & IP6F_OFF_MASK);
|
||||
if (fragoff == 0) {
|
||||
q6->ip6q_unfrglen = offset - sizeof(struct ip6_hdr)
|
||||
- sizeof(struct ip6_frag);
|
||||
q6->ip6q_nxt = ip6f->ip6f_nxt;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that the reassembled packet would not exceed 65535 bytes
|
||||
* in size.
|
||||
* If it would exceed, discard the fragment and return an ICMP error.
|
||||
*/
|
||||
frgpartlen = sizeof(struct ip6_hdr) + ntohs(ip6->ip6_plen) - offset;
|
||||
if (q6->ip6q_unfrglen >= 0) {
|
||||
/* The 1st fragment has already arrived. */
|
||||
if (q6->ip6q_unfrglen + fragoff + frgpartlen > IPV6_MAXPACKET) {
|
||||
m->m_data -= offset;
|
||||
m->m_len += offset;
|
||||
icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER,
|
||||
offset - sizeof(struct ip6_frag) + 2);
|
||||
return(IPPROTO_DONE);
|
||||
}
|
||||
}
|
||||
else if (fragoff + frgpartlen > IPV6_MAXPACKET) {
|
||||
m->m_data -= offset;
|
||||
m->m_len += offset;
|
||||
icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER,
|
||||
offset - sizeof(struct ip6_frag) + 2);
|
||||
return(IPPROTO_DONE);
|
||||
}
|
||||
/*
|
||||
* If it's the first fragment, do the above check for each
|
||||
* fragment already stored in the reassembly queue.
|
||||
*/
|
||||
if (fragoff == 0) {
|
||||
struct ip6asfrag *af6dwn;
|
||||
|
||||
for (af6 = q6->ip6q_down; af6 != (struct ip6asfrag *)q6;
|
||||
af6 = af6dwn) {
|
||||
af6dwn = af6->ip6af_down;
|
||||
|
||||
if (q6->ip6q_unfrglen + af6->ip6af_off + af6->ip6af_frglen >
|
||||
IPV6_MAXPACKET) {
|
||||
struct mbuf *merr = IP6_REASS_MBUF(af6);
|
||||
struct ip6_hdr *ip6err;
|
||||
int erroff = af6->ip6af_offset;
|
||||
|
||||
/* dequeue the fragment. */
|
||||
frag6_deq(af6);
|
||||
|
||||
/* adjust pointer. */
|
||||
merr->m_data -= af6->ip6af_offset;
|
||||
merr->m_len += af6->ip6af_offset;
|
||||
ip6err = mtod(merr, struct ip6_hdr *);
|
||||
|
||||
/*
|
||||
* Restore source and destination addresses
|
||||
* in the erroneous IPv6 header.
|
||||
*/
|
||||
ip6err->ip6_src = q6->ip6q_src;
|
||||
ip6err->ip6_dst = q6->ip6q_dst;
|
||||
|
||||
icmp6_error(merr, ICMP6_PARAM_PROB,
|
||||
ICMP6_PARAMPROB_HEADER,
|
||||
erroff - sizeof(struct ip6_frag) + 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Override the IPv6 header */
|
||||
ip6af = (struct ip6asfrag *)ip6;
|
||||
ip6af->ip6af_mff = ip6f->ip6f_offlg & IP6F_MORE_FRAG;
|
||||
ip6af->ip6af_off = fragoff;
|
||||
ip6af->ip6af_frglen = frgpartlen;
|
||||
ip6af->ip6af_offset = offset;
|
||||
IP6_REASS_MBUF(ip6af) = m;
|
||||
|
||||
if (first_frag) {
|
||||
af6 = (struct ip6asfrag *)q6;
|
||||
goto insert;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find a segment which begins after this one does.
|
||||
*/
|
||||
for (af6 = q6->ip6q_down; af6 != (struct ip6asfrag *)q6;
|
||||
af6 = af6->ip6af_down)
|
||||
if (af6->ip6af_off > ip6af->ip6af_off)
|
||||
break;
|
||||
|
||||
/*
|
||||
* If the incoming framgent overlaps some existing fragments in
|
||||
* the reassembly queue, drop it, since it is dangerous to override
|
||||
* existing fragments from a security point of view.
|
||||
*/
|
||||
if (af6->ip6af_up != (struct ip6asfrag *)q6) {
|
||||
i = af6->ip6af_up->ip6af_off + af6->ip6af_up->ip6af_frglen
|
||||
- ip6af->ip6af_off;
|
||||
if (i > 0) {
|
||||
log(LOG_ERR, "%d bytes of a fragment from %s "
|
||||
"overlaps the previous fragment\n",
|
||||
i, ip6_sprintf(&q6->ip6q_src));
|
||||
goto dropfrag;
|
||||
}
|
||||
}
|
||||
if (af6 != (struct ip6asfrag *)q6) {
|
||||
i = (ip6af->ip6af_off + ip6af->ip6af_frglen) - af6->ip6af_off;
|
||||
if (i > 0) {
|
||||
log(LOG_ERR, "%d bytes of a fragment from %s "
|
||||
"overlaps the succeeding fragment",
|
||||
i, ip6_sprintf(&q6->ip6q_src));
|
||||
goto dropfrag;
|
||||
}
|
||||
}
|
||||
|
||||
insert:
|
||||
|
||||
/*
|
||||
* Stick new segment in its place;
|
||||
* check for complete reassembly.
|
||||
* Move to front of packet queue, as we are
|
||||
* the most recently active fragmented packet.
|
||||
*/
|
||||
frag6_enq(ip6af, af6->ip6af_up);
|
||||
next = 0;
|
||||
for (af6 = q6->ip6q_down; af6 != (struct ip6asfrag *)q6;
|
||||
af6 = af6->ip6af_down) {
|
||||
if (af6->ip6af_off != next) {
|
||||
frag6_doing_reass = 0;
|
||||
return IPPROTO_DONE;
|
||||
}
|
||||
next += af6->ip6af_frglen;
|
||||
}
|
||||
if (af6->ip6af_up->ip6af_mff) {
|
||||
frag6_doing_reass = 0;
|
||||
return IPPROTO_DONE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reassembly is complete; concatenate fragments.
|
||||
*/
|
||||
|
||||
ip6af = q6->ip6q_down;
|
||||
t = m = IP6_REASS_MBUF(ip6af);
|
||||
af6 = ip6af->ip6af_down;
|
||||
while (af6 != (struct ip6asfrag *)q6) {
|
||||
while (t->m_next)
|
||||
t = t->m_next;
|
||||
t->m_next = IP6_REASS_MBUF(af6);
|
||||
af6 = af6->ip6af_down;
|
||||
}
|
||||
|
||||
/* adjust offset to point where the original next header starts */
|
||||
offset = ip6af->ip6af_offset - sizeof(struct ip6_frag);
|
||||
ip6 = (struct ip6_hdr *)ip6af;
|
||||
ip6->ip6_plen = htons((u_short)next + offset - sizeof(struct ip6_hdr));
|
||||
ip6->ip6_src = q6->ip6q_src;
|
||||
ip6->ip6_dst = q6->ip6q_dst;
|
||||
nxt = q6->ip6q_nxt;
|
||||
|
||||
/*
|
||||
* Delete frag6 header with as a few cost as possible.
|
||||
*/
|
||||
|
||||
if (offset < m->m_len)
|
||||
ovbcopy((caddr_t)ip6, (caddr_t)ip6 + sizeof(struct ip6_frag),
|
||||
offset);
|
||||
else {
|
||||
ovbcopy(mtod(m, caddr_t), (caddr_t)ip6 + offset, m->m_len);
|
||||
m->m_data -= sizeof(struct ip6_frag);
|
||||
}
|
||||
m->m_data -= offset;
|
||||
m->m_len += offset;
|
||||
|
||||
/*
|
||||
* Store NXT to the original.
|
||||
*/
|
||||
{
|
||||
char *prvnxtp = ip6_get_prevhdr(m, offset); /* XXX */
|
||||
*prvnxtp = nxt;
|
||||
}
|
||||
|
||||
frag6_remque(q6);
|
||||
free(q6, M_FTABLE);
|
||||
frag6_nfragpackets--;
|
||||
|
||||
if (m->m_flags & M_PKTHDR) { /* Isn't it always true? */
|
||||
int plen = 0;
|
||||
for (t = m; t; t = t->m_next)
|
||||
plen += t->m_len;
|
||||
m->m_pkthdr.len = plen;
|
||||
}
|
||||
|
||||
ip6stat.ip6s_reassembled++;
|
||||
in6_ifstat_inc(dstifp, ifs6_reass_ok);
|
||||
|
||||
/*
|
||||
* Tell launch routine the next header
|
||||
*/
|
||||
|
||||
*mp = m;
|
||||
*offp = offset;
|
||||
|
||||
frag6_doing_reass = 0;
|
||||
return nxt;
|
||||
|
||||
dropfrag:
|
||||
in6_ifstat_inc(dstifp, ifs6_reass_fail);
|
||||
ip6stat.ip6s_fragdropped++;
|
||||
m_freem(m);
|
||||
return IPPROTO_DONE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Free a fragment reassembly header and all
|
||||
* associated datagrams.
|
||||
*/
|
||||
void
|
||||
frag6_freef(q6)
|
||||
struct ip6q *q6;
|
||||
{
|
||||
struct ip6asfrag *af6, *down6;
|
||||
|
||||
for (af6 = q6->ip6q_down; af6 != (struct ip6asfrag *)q6;
|
||||
af6 = down6) {
|
||||
struct mbuf *m = IP6_REASS_MBUF(af6);
|
||||
|
||||
down6 = af6->ip6af_down;
|
||||
frag6_deq(af6);
|
||||
|
||||
/*
|
||||
* Return ICMP time exceeded error for the 1st fragment.
|
||||
* Just free other fragments.
|
||||
*/
|
||||
if (af6->ip6af_off == 0) {
|
||||
struct ip6_hdr *ip6;
|
||||
|
||||
/* adjust pointer */
|
||||
m->m_data -= af6->ip6af_offset;
|
||||
m->m_len += af6->ip6af_offset;
|
||||
ip6 = mtod(m, struct ip6_hdr *);
|
||||
|
||||
/* restoure source and destination addresses */
|
||||
ip6->ip6_src = q6->ip6q_src;
|
||||
ip6->ip6_dst = q6->ip6q_dst;
|
||||
|
||||
icmp6_error(m, ICMP6_TIME_EXCEEDED,
|
||||
ICMP6_TIME_EXCEED_REASSEMBLY, 0);
|
||||
}
|
||||
else
|
||||
m_freem(m);
|
||||
}
|
||||
frag6_remque(q6);
|
||||
free(q6, M_FTABLE);
|
||||
frag6_nfragpackets--;
|
||||
}
|
||||
|
||||
/*
|
||||
* Put an ip fragment on a reassembly chain.
|
||||
* Like insque, but pointers in middle of structure.
|
||||
*/
|
||||
void
|
||||
frag6_enq(af6, up6)
|
||||
struct ip6asfrag *af6, *up6;
|
||||
{
|
||||
af6->ip6af_up = up6;
|
||||
af6->ip6af_down = up6->ip6af_down;
|
||||
up6->ip6af_down->ip6af_up = af6;
|
||||
up6->ip6af_down = af6;
|
||||
}
|
||||
|
||||
/*
|
||||
* To frag6_enq as remque is to insque.
|
||||
*/
|
||||
void
|
||||
frag6_deq(af6)
|
||||
struct ip6asfrag *af6;
|
||||
{
|
||||
af6->ip6af_up->ip6af_down = af6->ip6af_down;
|
||||
af6->ip6af_down->ip6af_up = af6->ip6af_up;
|
||||
}
|
||||
|
||||
void
|
||||
frag6_insque(new, old)
|
||||
struct ip6q *new, *old;
|
||||
{
|
||||
new->ip6q_prev = old;
|
||||
new->ip6q_next = old->ip6q_next;
|
||||
old->ip6q_next->ip6q_prev= new;
|
||||
old->ip6q_next = new;
|
||||
}
|
||||
|
||||
void
|
||||
frag6_remque(p6)
|
||||
struct ip6q *p6;
|
||||
{
|
||||
p6->ip6q_prev->ip6q_next = p6->ip6q_next;
|
||||
p6->ip6q_next->ip6q_prev = p6->ip6q_prev;
|
||||
}
|
||||
|
||||
/*
|
||||
* IP timer processing;
|
||||
* if a timer expires on a reassembly
|
||||
* queue, discard it.
|
||||
*/
|
||||
void
|
||||
frag6_slowtimo()
|
||||
{
|
||||
struct ip6q *q6;
|
||||
int s = splnet();
|
||||
|
||||
frag6_doing_reass = 1;
|
||||
q6 = ip6q.ip6q_next;
|
||||
if (q6)
|
||||
while (q6 != &ip6q) {
|
||||
--q6->ip6q_ttl;
|
||||
q6 = q6->ip6q_next;
|
||||
if (q6->ip6q_prev->ip6q_ttl == 0) {
|
||||
ip6stat.ip6s_fragtimeout++;
|
||||
/* XXX in6_ifstat_inc(ifp, ifs6_reass_fail) */
|
||||
frag6_freef(q6->ip6q_prev);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* If we are over the maximum number of fragments
|
||||
* (due to the limit being lowered), drain off
|
||||
* enough to get down to the new limit.
|
||||
*/
|
||||
while (frag6_nfragpackets > (u_int)ip6_maxfragpackets) {
|
||||
ip6stat.ip6s_fragoverflow++;
|
||||
/* XXX in6_ifstat_inc(ifp, ifs6_reass_fail) */
|
||||
frag6_freef(ip6q.ip6q_prev);
|
||||
}
|
||||
frag6_doing_reass = 0;
|
||||
splx(s);
|
||||
}
|
||||
|
||||
/*
|
||||
* Drain off all datagram fragments.
|
||||
*/
|
||||
void
|
||||
frag6_drain()
|
||||
{
|
||||
if (frag6_doing_reass)
|
||||
return;
|
||||
while (ip6q.ip6q_next != &ip6q) {
|
||||
ip6stat.ip6s_fragdropped++;
|
||||
/* XXX in6_ifstat_inc(ifp, ifs6_reass_fail) */
|
||||
frag6_freef(ip6q.ip6q_next);
|
||||
}
|
||||
}
|
||||
1868
sys/netinet6/icmp6.c
Normal file
1868
sys/netinet6/icmp6.c
Normal file
File diff suppressed because it is too large
Load diff
602
sys/netinet6/icmp6.h
Normal file
602
sys/netinet6/icmp6.h
Normal file
|
|
@ -0,0 +1,602 @@
|
|||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1982, 1986, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)ip_icmp.h 8.1 (Berkeley) 6/10/93
|
||||
*/
|
||||
|
||||
#ifndef _NETINET6_ICMPV6_H_
|
||||
#define _NETINET6_ICMPV6_H_
|
||||
|
||||
#define ICMPV6_PLD_MAXLEN 1232 /* IPV6_MMTU - sizeof(struct ip6_hdr)
|
||||
- sizeof(struct icmp6_hdr) */
|
||||
|
||||
struct icmp6_hdr {
|
||||
u_int8_t icmp6_type; /* type field */
|
||||
u_int8_t icmp6_code; /* code field */
|
||||
u_int16_t icmp6_cksum; /* checksum field */
|
||||
union {
|
||||
u_int32_t icmp6_un_data32[1]; /* type-specific field */
|
||||
u_int16_t icmp6_un_data16[2]; /* type-specific field */
|
||||
u_int8_t icmp6_un_data8[4]; /* type-specific field */
|
||||
} icmp6_dataun;
|
||||
};
|
||||
|
||||
#define icmp6_data32 icmp6_dataun.icmp6_un_data32
|
||||
#define icmp6_data16 icmp6_dataun.icmp6_un_data16
|
||||
#define icmp6_data8 icmp6_dataun.icmp6_un_data8
|
||||
#define icmp6_pptr icmp6_data32[0] /* parameter prob */
|
||||
#define icmp6_mtu icmp6_data32[0] /* packet too big */
|
||||
#define icmp6_id icmp6_data16[0] /* echo request/reply */
|
||||
#define icmp6_seq icmp6_data16[1] /* echo request/reply */
|
||||
#define icmp6_maxdelay icmp6_data16[0] /* mcast group membership */
|
||||
|
||||
#define ICMP6_DST_UNREACH 1 /* dest unreachable, codes: */
|
||||
#define ICMP6_PACKET_TOO_BIG 2 /* packet too big */
|
||||
#define ICMP6_TIME_EXCEEDED 3 /* time exceeded, code: */
|
||||
#define ICMP6_PARAM_PROB 4 /* ip6 header bad */
|
||||
|
||||
#define ICMP6_ECHO_REQUEST 128 /* echo service */
|
||||
#define ICMP6_ECHO_REPLY 129 /* echo reply */
|
||||
#define ICMP6_MEMBERSHIP_QUERY 130 /* group membership query */
|
||||
#define MLD6_LISTENER_QUERY 130 /* multicast listener query */
|
||||
#define ICMP6_MEMBERSHIP_REPORT 131 /* group membership report */
|
||||
#define MLD6_LISTENER_REPORT 131 /* multicast listener report */
|
||||
#define ICMP6_MEMBERSHIP_REDUCTION 132 /* group membership termination */
|
||||
#define MLD6_LISTENER_DONE 132 /* multicast listener done */
|
||||
|
||||
#define ND_ROUTER_SOLICIT 133 /* router solicitation */
|
||||
#define ND_ROUTER_ADVERT 134 /* router advertisment */
|
||||
#define ND_NEIGHBOR_SOLICIT 135 /* neighbor solicitation */
|
||||
#define ND_NEIGHBOR_ADVERT 136 /* neighbor advertisment */
|
||||
#define ND_REDIRECT 137 /* redirect */
|
||||
|
||||
#define ICMP6_ROUTER_RENUMBERING 138 /* router renumbering */
|
||||
|
||||
#define ICMP6_WRUREQUEST 139 /* who are you request */
|
||||
#define ICMP6_WRUREPLY 140 /* who are you reply */
|
||||
#define ICMP6_FQDN_QUERY 139 /* FQDN query */
|
||||
#define ICMP6_FQDN_REPLY 140 /* FQDN reply */
|
||||
#define ICMP6_NI_QUERY 139 /* node information request */
|
||||
#define ICMP6_NI_REPLY 140 /* node information reply */
|
||||
|
||||
/* The definitions below are experimental. TBA */
|
||||
#define MLD6_MTRACE_RESP 141 /* mtrace response(to sender) */
|
||||
#define MLD6_MTRACE 142 /* mtrace messages */
|
||||
|
||||
#define ICMP6_MAXTYPE 142
|
||||
|
||||
#define ICMP6_DST_UNREACH_NOROUTE 0 /* no route to destination */
|
||||
#define ICMP6_DST_UNREACH_ADMIN 1 /* administratively prohibited */
|
||||
#define ICMP6_DST_UNREACH_NOTNEIGHBOR 2 /* not a neighbor(obsolete) */
|
||||
#define ICMP6_DST_UNREACH_BEYONDSCOPE 2 /* beyond scope of source address */
|
||||
#define ICMP6_DST_UNREACH_ADDR 3 /* address unreachable */
|
||||
#define ICMP6_DST_UNREACH_NOPORT 4 /* port unreachable */
|
||||
|
||||
#define ICMP6_TIME_EXCEED_TRANSIT 0 /* ttl==0 in transit */
|
||||
#define ICMP6_TIME_EXCEED_REASSEMBLY 1 /* ttl==0 in reass */
|
||||
|
||||
#define ICMP6_PARAMPROB_HEADER 0 /* erroneous header field */
|
||||
#define ICMP6_PARAMPROB_NEXTHEADER 1 /* unrecognized next header */
|
||||
#define ICMP6_PARAMPROB_OPTION 2 /* unrecognized option */
|
||||
|
||||
#define ICMP6_INFOMSG_MASK 0x80 /* all informational messages */
|
||||
|
||||
#define ICMP6_NI_SUCESS 0 /* node information successful reply */
|
||||
#define ICMP6_NI_REFUSED 1 /* node information request is refused */
|
||||
#define ICMP6_NI_UNKNOWN 2 /* unknown Qtype */
|
||||
|
||||
#define ICMP6_ROUTER_RENUMBERING_COMMAND 0 /* rr command */
|
||||
#define ICMP6_ROUTER_RENUMBERING_RESULT 1 /* rr result */
|
||||
#define ICMP6_ROUTER_RENUMBERING_SEQNUM_RESET 255 /* rr seq num reset */
|
||||
|
||||
/* Used in kernel only */
|
||||
#define ND_REDIRECT_ONLINK 0 /* redirect to an on-link node */
|
||||
#define ND_REDIRECT_ROUTER 1 /* redirect to a better router */
|
||||
|
||||
/*
|
||||
* Multicast Listener Discovery
|
||||
*/
|
||||
struct mld6_hdr {
|
||||
struct icmp6_hdr mld6_hdr;
|
||||
struct in6_addr mld6_addr; /* multicast address */
|
||||
};
|
||||
|
||||
#define mld6_type mld6_hdr.icmp6_type
|
||||
#define mld6_code mld6_hdr.icmp6_code
|
||||
#define mld6_cksum mld6_hdr.icmp6_cksum
|
||||
#define mld6_maxdelay mld6_hdr.icmp6_data16[0]
|
||||
#define mld6_reserved mld6_hdr.icmp6_data16[1]
|
||||
|
||||
/*
|
||||
* Neighbor Discovery
|
||||
*/
|
||||
|
||||
struct nd_router_solicit { /* router solicitation */
|
||||
struct icmp6_hdr nd_rs_hdr;
|
||||
/* could be followed by options */
|
||||
};
|
||||
|
||||
#define nd_rs_type nd_rs_hdr.icmp6_type
|
||||
#define nd_rs_code nd_rs_hdr.icmp6_code
|
||||
#define nd_rs_cksum nd_rs_hdr.icmp6_cksum
|
||||
#define nd_rs_reserved nd_rs_hdr.icmp6_data32[0]
|
||||
|
||||
struct nd_router_advert { /* router advertisement */
|
||||
struct icmp6_hdr nd_ra_hdr;
|
||||
u_int32_t nd_ra_reachable; /* reachable time */
|
||||
u_int32_t nd_ra_retransmit; /* retransmit timer */
|
||||
/* could be followed by options */
|
||||
};
|
||||
|
||||
#define nd_ra_type nd_ra_hdr.icmp6_type
|
||||
#define nd_ra_code nd_ra_hdr.icmp6_code
|
||||
#define nd_ra_cksum nd_ra_hdr.icmp6_cksum
|
||||
#define nd_ra_curhoplimit nd_ra_hdr.icmp6_data8[0]
|
||||
#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_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 */
|
||||
};
|
||||
|
||||
#define nd_ns_type nd_ns_hdr.icmp6_type
|
||||
#define nd_ns_code nd_ns_hdr.icmp6_code
|
||||
#define nd_ns_cksum nd_ns_hdr.icmp6_cksum
|
||||
#define nd_ns_reserved nd_ns_hdr.icmp6_data32[0]
|
||||
|
||||
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 */
|
||||
};
|
||||
|
||||
#define nd_na_type nd_na_hdr.icmp6_type
|
||||
#define nd_na_code nd_na_hdr.icmp6_code
|
||||
#define nd_na_cksum nd_na_hdr.icmp6_cksum
|
||||
#define nd_na_flags_reserved nd_na_hdr.icmp6_data32[0]
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
#define ND_NA_FLAG_ROUTER 0x80000000
|
||||
#define ND_NA_FLAG_SOLICITED 0x40000000
|
||||
#define ND_NA_FLAG_OVERRIDE 0x20000000
|
||||
#elif BYTE_ORDER == LITTLE_ENDIAN
|
||||
#define ND_NA_FLAG_ROUTER 0x80
|
||||
#define ND_NA_FLAG_SOLICITED 0x40
|
||||
#define ND_NA_FLAG_OVERRIDE 0x20
|
||||
#endif
|
||||
|
||||
struct nd_redirect { /* redirect */
|
||||
struct icmp6_hdr nd_rd_hdr;
|
||||
struct in6_addr nd_rd_target; /* target address */
|
||||
struct in6_addr nd_rd_dst; /* destination address */
|
||||
/* could be followed by options */
|
||||
};
|
||||
|
||||
#define nd_rd_type nd_rd_hdr.icmp6_type
|
||||
#define nd_rd_code nd_rd_hdr.icmp6_code
|
||||
#define nd_rd_cksum nd_rd_hdr.icmp6_cksum
|
||||
#define nd_rd_reserved nd_rd_hdr.icmp6_data32[0]
|
||||
|
||||
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*/
|
||||
};
|
||||
|
||||
#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
|
||||
|
||||
struct nd_opt_prefix_info { /* prefix information */
|
||||
u_int8_t nd_opt_pi_type;
|
||||
u_int8_t nd_opt_pi_len;
|
||||
u_int8_t nd_opt_pi_prefix_len;
|
||||
u_int8_t nd_opt_pi_flags_reserved;
|
||||
u_int32_t nd_opt_pi_valid_time;
|
||||
u_int32_t nd_opt_pi_preferred_time;
|
||||
u_int32_t nd_opt_pi_reserved2;
|
||||
struct in6_addr nd_opt_pi_prefix;
|
||||
};
|
||||
|
||||
#define ND_OPT_PI_FLAG_ONLINK 0x80
|
||||
#define ND_OPT_PI_FLAG_AUTO 0x40
|
||||
|
||||
struct nd_opt_rd_hdr { /* redirected header */
|
||||
u_int8_t nd_opt_rh_type;
|
||||
u_int8_t nd_opt_rh_len;
|
||||
u_int16_t nd_opt_rh_reserved1;
|
||||
u_int32_t nd_opt_rh_reserved2;
|
||||
/* followed by IP header and data */
|
||||
};
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
/*
|
||||
* icmp6 namelookup
|
||||
*/
|
||||
|
||||
struct icmp6_namelookup {
|
||||
struct icmp6_hdr icmp6_nl_hdr;
|
||||
u_int64_t icmp6_nl_nonce;
|
||||
u_int32_t icmp6_nl_ttl;
|
||||
/* could be followed by options */
|
||||
};
|
||||
|
||||
/*
|
||||
* icmp6 node information
|
||||
*/
|
||||
struct icmp6_nodeinfo {
|
||||
struct icmp6_hdr icmp6_ni_hdr;
|
||||
u_int64_t icmp6_ni_nonce;
|
||||
/* could be followed by reply data */
|
||||
};
|
||||
|
||||
#define ni_type icmp6_ni_hdr.icmp6_type
|
||||
#define ni_code icmp6_ni_hdr.icmp6_code
|
||||
#define ni_cksum icmp6_ni_hdr.icmp6_cksum
|
||||
#define ni_qtype icmp6_ni_hdr.icmp6_data16[0]
|
||||
#define ni_flags icmp6_ni_hdr.icmp6_data16[1]
|
||||
|
||||
|
||||
#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... */
|
||||
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
#define NI_SUPTYPE_FLAG_COMPRESS 0x1
|
||||
#define NI_FQDN_FLAG_VALIDTTL 0x1
|
||||
#define NI_NODEADDR_FLAG_LINKLOCAL 0x1
|
||||
#define NI_NODEADDR_FLAG_SITELOCAL 0x2
|
||||
#define NI_NODEADDR_FLAG_GLOBAL 0x4
|
||||
#define NI_NODEADDR_FLAG_ALL 0x8
|
||||
#define NI_NODEADDR_FLAG_TRUNCATE 0x10
|
||||
#define NI_NODEADDR_FLAG_ANYCAST 0x20 /* just experimental. not in spec */
|
||||
#elif BYTE_ORDER == LITTLE_ENDIAN
|
||||
#define NI_SUPTYPE_FLAG_COMPRESS 0x0100
|
||||
#define NI_FQDN_FLAG_VALIDTTL 0x0100
|
||||
#define NI_NODEADDR_FLAG_LINKLOCAL 0x0100
|
||||
#define NI_NODEADDR_FLAG_SITELOCAL 0x0200
|
||||
#define NI_NODEADDR_FLAG_GLOBAL 0x0400
|
||||
#define NI_NODEADDR_FLAG_ALL 0x0800
|
||||
#define NI_NODEADDR_FLAG_TRUNCATE 0x1000
|
||||
#define NI_NODEADDR_FLAG_ANYCAST 0x2000 /* just experimental. not in spec */
|
||||
#endif
|
||||
|
||||
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 */
|
||||
};
|
||||
|
||||
/*
|
||||
* Router Renumbering. as router-renum-08.txt
|
||||
*/
|
||||
struct icmp6_router_renum { /* router renumbering header */
|
||||
struct icmp6_hdr rr_hdr;
|
||||
u_int8_t rr_segnum;
|
||||
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
|
||||
|
||||
#define rr_type rr_hdr.icmp6_type
|
||||
#define rr_code rr_hdr.icmp6_code
|
||||
#define rr_cksum rr_hdr.icmp6_cksum
|
||||
#define rr_seqnum rr_hdr.icmp6_data32[0]
|
||||
|
||||
struct rr_pco_match { /* match prefix part */
|
||||
u_int8_t rpm_code;
|
||||
u_int8_t rpm_len;
|
||||
u_int8_t rpm_ordinal;
|
||||
u_int8_t rpm_matchlen;
|
||||
u_int8_t rpm_minlen;
|
||||
u_int8_t rpm_maxlen;
|
||||
u_int16_t rpm_reserved;
|
||||
struct in6_addr rpm_prefix;
|
||||
};
|
||||
|
||||
#define RPM_PCO_ADD 1
|
||||
#define RPM_PCO_CHANGE 2
|
||||
#define RPM_PCO_SETGLOBAL 3
|
||||
|
||||
struct rr_pco_use { /* use prefix part */
|
||||
u_int8_t rpu_uselen;
|
||||
u_int8_t rpu_keeplen;
|
||||
u_int8_t rpu_ramask;
|
||||
u_int8_t rpu_raflags;
|
||||
u_int32_t rpu_vltime;
|
||||
u_int32_t rpu_pltime;
|
||||
u_int32_t rpu_flags;
|
||||
struct in6_addr rpu_prefix;
|
||||
};
|
||||
#define ICMP6_RR_PCOUSE_RAFLAGS_ONLINK 0x20
|
||||
#define ICMP6_RR_PCOUSE_RAFLAGS_AUTO 0x10
|
||||
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
#define ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME 0x80000000
|
||||
#define ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME 0x40000000
|
||||
#elif BYTE_ORDER == LITTLE_ENDIAN
|
||||
#define ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME 0x80
|
||||
#define ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME 0x40
|
||||
#endif
|
||||
|
||||
struct rr_result { /* router renumbering result message */
|
||||
u_int16_t rrr_flags;
|
||||
u_int8_t rrr_ordinal;
|
||||
u_int8_t rrr_matchedlen;
|
||||
u_int32_t rrr_ifid;
|
||||
struct in6_addr rrr_prefix;
|
||||
};
|
||||
#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
|
||||
#endif
|
||||
|
||||
/*
|
||||
* icmp6 filter structures.
|
||||
*/
|
||||
|
||||
struct icmp6_filter {
|
||||
u_int32_t icmp6_filter[8];
|
||||
};
|
||||
|
||||
#ifdef _KERNEL
|
||||
#define ICMP6_FILTER_SETPASSALL(filterp) \
|
||||
{ \
|
||||
int i; u_char *p; \
|
||||
p = (u_char *)filterp; \
|
||||
for (i = 0; i < sizeof(struct icmp6_filter); i++) \
|
||||
p[i] = 0xff; \
|
||||
}
|
||||
#define ICMP6_FILTER_SETBLOCKALL(filterp) \
|
||||
bzero(filterp, sizeof(struct icmp6_filter))
|
||||
#else /* _KERNEL */
|
||||
#define ICMP6_FILTER_SETPASSALL(filterp) \
|
||||
memset(filterp, 0xff, sizeof(struct icmp6_filter))
|
||||
#define ICMP6_FILTER_SETBLOCKALL(filterp) \
|
||||
memset(filterp, 0x00, sizeof(struct icmp6_filter))
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#define ICMP6_FILTER_SETPASS(type, filterp) \
|
||||
(((filterp)->icmp6_filter[(type) >> 5]) |= (1 << ((type) & 31)))
|
||||
#define ICMP6_FILTER_SETBLOCK(type, filterp) \
|
||||
(((filterp)->icmp6_filter[(type) >> 5]) &= ~(1 << ((type) & 31)))
|
||||
#define ICMP6_FILTER_WILLPASS(type, filterp) \
|
||||
((((filterp)->icmp6_filter[(type) >> 5]) & (1 << ((type) & 31))) != 0)
|
||||
#define ICMP6_FILTER_WILLBLOCK(type, filterp) \
|
||||
((((filterp)->icmp6_filter[(type) >> 5]) & (1 << ((type) & 31))) == 0)
|
||||
|
||||
/*
|
||||
* Variables related to this implementation
|
||||
* of the internet control message protocol version 6.
|
||||
*/
|
||||
struct icmp6stat {
|
||||
/* statistics related to icmp6 packets generated */
|
||||
u_long icp6s_error; /* # of calls to icmp6_error */
|
||||
u_long icp6s_canterror; /* no error 'cuz old was icmp */
|
||||
u_long icp6s_toofreq; /* no error 'cuz rate limitation */
|
||||
u_long icp6s_outhist[256];
|
||||
/* statistics related to input messages proccesed */
|
||||
u_long icp6s_badcode; /* icmp6_code out of range */
|
||||
u_long icp6s_tooshort; /* packet < sizeof(struct icmp6_hdr) */
|
||||
u_long icp6s_checksum; /* bad checksum */
|
||||
u_long icp6s_badlen; /* calculated bound mismatch */
|
||||
u_long icp6s_reflect; /* number of responses */
|
||||
u_long icp6s_inhist[256];
|
||||
};
|
||||
|
||||
/*
|
||||
* Names for ICMP sysctl objects
|
||||
*/
|
||||
#define ICMPV6CTL_STATS 1
|
||||
#define ICMPV6CTL_REDIRACCEPT 2 /* accept/process redirects */
|
||||
#define ICMPV6CTL_REDIRTIMEOUT 3 /* redirect cache time */
|
||||
#define ICMPV6CTL_ERRRATELIMIT 5 /* ICMPv6 error rate limitation */
|
||||
#define ICMPV6CTL_ND6_PRUNE 6
|
||||
#define ICMPV6CTL_ND6_DELAY 8
|
||||
#define ICMPV6CTL_ND6_UMAXTRIES 9
|
||||
#define ICMPV6CTL_ND6_MMAXTRIES 10
|
||||
#define ICMPV6CTL_ND6_USELOOPBACK 11
|
||||
#define ICMPV6CTL_ND6_PROXYALL 12
|
||||
#define ICMPV6CTL_MAXID 13
|
||||
|
||||
#define ICMPV6CTL_NAMES { \
|
||||
{ 0, 0 }, \
|
||||
{ 0, 0 }, \
|
||||
{ "rediraccept", CTLTYPE_INT }, \
|
||||
{ "redirtimeout", CTLTYPE_INT }, \
|
||||
{ 0, 0 }, \
|
||||
{ "errratelimit", CTLTYPE_INT }, \
|
||||
{ "nd6_prune", CTLTYPE_INT }, \
|
||||
{ 0, 0 }, \
|
||||
{ "nd6_delay", CTLTYPE_INT }, \
|
||||
{ "nd6_umaxtries", CTLTYPE_INT }, \
|
||||
{ "nd6_mmaxtries", CTLTYPE_INT }, \
|
||||
{ "nd6_useloopback", CTLTYPE_INT }, \
|
||||
{ "nd6_proxyall", CTLTYPE_INT }, \
|
||||
}
|
||||
|
||||
#define ICMPV6CTL_VARS { \
|
||||
0, \
|
||||
0, \
|
||||
&icmp6_rediraccept, \
|
||||
&icmp6_redirtimeout, \
|
||||
0, \
|
||||
0, \
|
||||
&icmp6errratelim, \
|
||||
&nd6_prune, \
|
||||
0, \
|
||||
&nd6_delay, \
|
||||
&nd6_umaxtries, \
|
||||
&nd6_mmaxtries, \
|
||||
&nd6_useloopback, \
|
||||
&nd6_proxyall, \
|
||||
}
|
||||
|
||||
#define RTF_PROBEMTU RTF_PROTO1
|
||||
|
||||
#ifdef _KERNEL
|
||||
# ifdef __STDC__
|
||||
struct rtentry;
|
||||
struct rttimer;
|
||||
struct in6_multi;
|
||||
# endif
|
||||
void icmp6_init __P((void));
|
||||
void icmp6_paramerror __P((struct mbuf *, int));
|
||||
void icmp6_error __P((struct mbuf *, int, int, int));
|
||||
int icmp6_input __P((struct mbuf **, int *, int));
|
||||
void icmp6_fasttimo __P((void));
|
||||
void icmp6_reflect __P((struct mbuf *, size_t));
|
||||
void icmp6_prepare __P((struct mbuf *));
|
||||
void icmp6_redirect_input __P((struct mbuf *, int));
|
||||
void icmp6_redirect_output __P((struct mbuf *, struct rtentry *));
|
||||
|
||||
/* XXX: is this the right place for these macros? */
|
||||
#define icmp6_ifstat_inc(ifp, tag) \
|
||||
do { \
|
||||
if ((ifp) && (ifp)->if_index <= if_index \
|
||||
&& (ifp)->if_index < icmp6_ifstatmax \
|
||||
&& icmp6_ifstat && icmp6_ifstat[(ifp)->if_index]) { \
|
||||
icmp6_ifstat[(ifp)->if_index]->tag++; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define icmp6_ifoutstat_inc(ifp, type, code) \
|
||||
do { \
|
||||
icmp6_ifstat_inc(ifp, ifs6_out_msg); \
|
||||
if (type < ICMP6_INFOMSG_MASK) \
|
||||
icmp6_ifstat_inc(ifp, ifs6_out_error); \
|
||||
switch(type) { \
|
||||
case ICMP6_DST_UNREACH: \
|
||||
icmp6_ifstat_inc(ifp, ifs6_out_dstunreach); \
|
||||
if (code == ICMP6_DST_UNREACH_ADMIN) \
|
||||
icmp6_ifstat_inc(ifp, ifs6_out_adminprohib); \
|
||||
break; \
|
||||
case ICMP6_PACKET_TOO_BIG: \
|
||||
icmp6_ifstat_inc(ifp, ifs6_out_pkttoobig); \
|
||||
break; \
|
||||
case ICMP6_TIME_EXCEEDED: \
|
||||
icmp6_ifstat_inc(ifp, ifs6_out_timeexceed); \
|
||||
break; \
|
||||
case ICMP6_PARAM_PROB: \
|
||||
icmp6_ifstat_inc(ifp, ifs6_out_paramprob); \
|
||||
break; \
|
||||
case ICMP6_ECHO_REQUEST: \
|
||||
icmp6_ifstat_inc(ifp, ifs6_out_echo); \
|
||||
break; \
|
||||
case ICMP6_ECHO_REPLY: \
|
||||
icmp6_ifstat_inc(ifp, ifs6_out_echoreply); \
|
||||
break; \
|
||||
case MLD6_LISTENER_QUERY: \
|
||||
icmp6_ifstat_inc(ifp, ifs6_out_mldquery); \
|
||||
break; \
|
||||
case MLD6_LISTENER_REPORT: \
|
||||
icmp6_ifstat_inc(ifp, ifs6_out_mldreport); \
|
||||
break; \
|
||||
case MLD6_LISTENER_DONE: \
|
||||
icmp6_ifstat_inc(ifp, ifs6_out_mlddone); \
|
||||
break; \
|
||||
case ND_ROUTER_SOLICIT: \
|
||||
icmp6_ifstat_inc(ifp, ifs6_out_routersolicit); \
|
||||
break; \
|
||||
case ND_ROUTER_ADVERT: \
|
||||
icmp6_ifstat_inc(ifp, ifs6_out_routeradvert); \
|
||||
break; \
|
||||
case ND_NEIGHBOR_SOLICIT: \
|
||||
icmp6_ifstat_inc(ifp, ifs6_out_neighborsolicit); \
|
||||
break; \
|
||||
case ND_NEIGHBOR_ADVERT: \
|
||||
icmp6_ifstat_inc(ifp, ifs6_out_neighboradvert); \
|
||||
break; \
|
||||
case ND_REDIRECT: \
|
||||
icmp6_ifstat_inc(ifp, ifs6_out_redirect); \
|
||||
break; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
extern int icmp6_rediraccept; /* accept/process redirects */
|
||||
extern int icmp6_redirtimeout; /* cache time for redirect routes */
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#endif /* not _NETINET6_ICMPV6_H_ */
|
||||
|
||||
1879
sys/netinet6/in6.c
Normal file
1879
sys/netinet6/in6.c
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* 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:
|
||||
|
|
@ -13,7 +13,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
|
||||
|
|
@ -516,22 +516,10 @@ struct in6_pktinfo {
|
|||
#define IPV6CTL_GIF_HLIM 19 /* default HLIM for gif encap packet */
|
||||
#define IPV6CTL_USE_DEPRECATED 21 /* use deprecated addr (RFC2462 5.5.4) */
|
||||
#define IPV6CTL_RR_PRUNE 22 /* walk timer for router renumbering */
|
||||
#ifdef MAPPED_ADDR_ENABLED
|
||||
#define IPV6CTL_MAPPED_ADDR 23
|
||||
#endif /* MAPPED_ADDR_ENABLED */
|
||||
/* New entries should be added here from current IPV6CTL_MAXID value. */
|
||||
#define IPV6CTL_MAXID 24
|
||||
|
||||
#ifdef MAPPED_ADDR_ENABLED
|
||||
#define IPV6CTL_NAMES_MAPPED_ADDR "mapped_addr"
|
||||
#define IPV6CTL_TYPE_MAPPED_ADDR CTLTYPE_INT
|
||||
#define IPV6CTL_VARS_MAPPED_ADDR &ip6_mapped_addr_on
|
||||
#else /* MAPPED_ADDR_ENABLED */
|
||||
#define IPV6CTL_NAMES_MAPPED_ADDR 0
|
||||
#define IPV6CTL_TYPE_MAPPED_ADDR 0
|
||||
#define IPV6CTL_VARS_MAPPED_ADDR 0
|
||||
#endif /* MAPPED_ADDR_ENABLED */
|
||||
|
||||
#define IPV6CTL_NAMES { \
|
||||
{ 0, 0 }, \
|
||||
{ "forwarding", CTLTYPE_INT }, \
|
||||
|
|
@ -556,7 +544,7 @@ struct in6_pktinfo {
|
|||
{ 0, 0 }, \
|
||||
{ "use_deprecated", CTLTYPE_INT }, \
|
||||
{ "rr_prune", CTLTYPE_INT }, \
|
||||
{ IPV6CTL_NAMES_MAPPED_ADDR, IPV6CTL_TYPE_MAPPED_ADDR }, \
|
||||
{ "mapped_addr", CTLTYPE_INT }, \
|
||||
}
|
||||
|
||||
#define IPV6CTL_VARS { \
|
||||
|
|
@ -583,12 +571,23 @@ struct in6_pktinfo {
|
|||
0, \
|
||||
&ip6_use_deprecated, \
|
||||
&ip6_rr_prune, \
|
||||
IPV6CTL_VARS_MAPPED_ADDR, \
|
||||
&ip6_mapped_addr_on, \
|
||||
}
|
||||
#endif /* !_XOPEN_SOURCE */
|
||||
|
||||
/*
|
||||
* Redefinition of mbuf flags
|
||||
*/
|
||||
#define M_ANYCAST6 M_PROTO1
|
||||
#define M_AUTHIPHDR M_PROTO2
|
||||
#define M_DECRYPTED M_PROTO3
|
||||
#define M_LOOP M_PROTO4
|
||||
#define M_AUTHIPDGM M_PROTO5
|
||||
|
||||
#ifdef _KERNEL
|
||||
struct cmsghdr;
|
||||
struct cmsghdr;
|
||||
struct mbuf;
|
||||
struct ifnet;
|
||||
|
||||
int in6_canforward __P((struct in6_addr *, struct in6_addr *));
|
||||
int in6_cksum __P((struct mbuf *, u_int8_t, int, int));
|
||||
|
|
@ -597,7 +596,6 @@ int in6_addrscope __P((struct in6_addr *));
|
|||
struct in6_ifaddr *in6_ifawithscope __P((struct ifnet *, struct in6_addr *));
|
||||
struct in6_ifaddr *in6_ifawithifp __P((struct ifnet *, struct in6_addr *));
|
||||
extern void in6_if_up __P((struct ifnet *));
|
||||
#ifdef MAPPED_ADDR_ENABLED
|
||||
struct sockaddr;
|
||||
|
||||
void in6_sin6_2_sin __P((struct sockaddr_in *sin,
|
||||
|
|
@ -606,7 +604,6 @@ void in6_sin_2_v4mapsin6 __P((struct sockaddr_in *sin,
|
|||
struct sockaddr_in6 *sin6));
|
||||
void in6_sin6_2_sin_in_sock __P((struct sockaddr *nam));
|
||||
void in6_sin_2_v4mapsin6_in_sock __P((struct sockaddr **nam));
|
||||
#endif /* MAPPED_ADDR_ENABLED */
|
||||
|
||||
#define satosin6(sa) ((struct sockaddr_in6 *)(sa))
|
||||
#define sin6tosa(sin6) ((struct sockaddr *)(sin6))
|
||||
|
|
|
|||
301
sys/netinet6/in6_cksum.c
Normal file
301
sys/netinet6/in6_cksum.c
Normal file
|
|
@ -0,0 +1,301 @@
|
|||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1992, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)in_cksum.c 8.1 (Berkeley) 6/10/93
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/systm.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet6/ip6.h>
|
||||
|
||||
#include <net/net_osdep.h>
|
||||
|
||||
/*
|
||||
* Checksum routine for Internet Protocol family headers (Portable Version).
|
||||
*
|
||||
* This routine is very heavily used in the network
|
||||
* code and should be modified for each CPU to be as fast as possible.
|
||||
*/
|
||||
|
||||
#define ADDCARRY(x) (x > 65535 ? x -= 65535 : x)
|
||||
#define REDUCE {l_util.l = sum; sum = l_util.s[0] + l_util.s[1]; ADDCARRY(sum);}
|
||||
|
||||
static union {
|
||||
u_int16_t phs[4];
|
||||
struct {
|
||||
u_int32_t ph_len;
|
||||
u_int8_t ph_zero[3];
|
||||
u_int8_t ph_nxt;
|
||||
} ph;
|
||||
} uph;
|
||||
|
||||
/*
|
||||
* m MUST contain a continuous IP6 header.
|
||||
* off is a offset where TCP/UDP/ICMP6 header starts.
|
||||
* len is a total length of a transport segment.
|
||||
* (e.g. TCP header + TCP payload)
|
||||
*/
|
||||
|
||||
int
|
||||
in6_cksum(m, nxt, off, len)
|
||||
register struct mbuf *m;
|
||||
u_int8_t nxt;
|
||||
register int off, len;
|
||||
{
|
||||
register u_int16_t *w;
|
||||
register int sum = 0;
|
||||
register int mlen = 0;
|
||||
int byte_swapped = 0;
|
||||
struct ip6_hdr *ip6;
|
||||
|
||||
union {
|
||||
u_int8_t c[2];
|
||||
u_int16_t s;
|
||||
} s_util;
|
||||
union {
|
||||
u_int16_t s[2];
|
||||
u_int32_t l;
|
||||
} l_util;
|
||||
|
||||
/* sanity check */
|
||||
if (m->m_pkthdr.len < off + len) {
|
||||
panic("in6_cksum: mbuf len (%d) < off+len (%d+%d)\n",
|
||||
m->m_pkthdr.len, off, len);
|
||||
}
|
||||
|
||||
/*
|
||||
* First create IP6 pseudo header and calculate a summary.
|
||||
*/
|
||||
ip6 = mtod(m, struct ip6_hdr *);
|
||||
w = (u_int16_t *)&ip6->ip6_src;
|
||||
uph.ph.ph_len = htonl(len);
|
||||
uph.ph.ph_nxt = nxt;
|
||||
|
||||
/* IPv6 source address */
|
||||
sum += w[0];
|
||||
if (!IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src))
|
||||
sum += w[1];
|
||||
sum += w[2]; sum += w[3]; sum += w[4]; sum += w[5];
|
||||
sum += w[6]; sum += w[7];
|
||||
/* IPv6 destination address */
|
||||
sum += w[8];
|
||||
if (!IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst))
|
||||
sum += w[9];
|
||||
sum += w[10]; sum += w[11]; sum += w[12]; sum += w[13];
|
||||
sum += w[14]; sum += w[15];
|
||||
/* Payload length and upper layer identifier */
|
||||
sum += uph.phs[0]; sum += uph.phs[1];
|
||||
sum += uph.phs[2]; sum += uph.phs[3];
|
||||
|
||||
/*
|
||||
* Secondly calculate a summary of the first mbuf excluding offset.
|
||||
*/
|
||||
while (m != NULL && off > 0) {
|
||||
if (m->m_len <= off)
|
||||
off -= m->m_len;
|
||||
else
|
||||
break;
|
||||
m = m->m_next;
|
||||
}
|
||||
w = (u_int16_t *)(mtod(m, u_char *) + off);
|
||||
mlen = m->m_len - off;
|
||||
if (len < mlen)
|
||||
mlen = len;
|
||||
len -= mlen;
|
||||
/*
|
||||
* Force to even boundary.
|
||||
*/
|
||||
if ((1 & (long) w) && (mlen > 0)) {
|
||||
REDUCE;
|
||||
sum <<= 8;
|
||||
s_util.c[0] = *(u_char *)w;
|
||||
w = (u_int16_t *)((char *)w + 1);
|
||||
mlen--;
|
||||
byte_swapped = 1;
|
||||
}
|
||||
/*
|
||||
* Unroll the loop to make overhead from
|
||||
* branches &c small.
|
||||
*/
|
||||
while ((mlen -= 32) >= 0) {
|
||||
sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3];
|
||||
sum += w[4]; sum += w[5]; sum += w[6]; sum += w[7];
|
||||
sum += w[8]; sum += w[9]; sum += w[10]; sum += w[11];
|
||||
sum += w[12]; sum += w[13]; sum += w[14]; sum += w[15];
|
||||
w += 16;
|
||||
}
|
||||
mlen += 32;
|
||||
while ((mlen -= 8) >= 0) {
|
||||
sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3];
|
||||
w += 4;
|
||||
}
|
||||
mlen += 8;
|
||||
if (mlen == 0 && byte_swapped == 0)
|
||||
goto next;
|
||||
REDUCE;
|
||||
while ((mlen -= 2) >= 0) {
|
||||
sum += *w++;
|
||||
}
|
||||
if (byte_swapped) {
|
||||
REDUCE;
|
||||
sum <<= 8;
|
||||
byte_swapped = 0;
|
||||
if (mlen == -1) {
|
||||
s_util.c[1] = *(char *)w;
|
||||
sum += s_util.s;
|
||||
mlen = 0;
|
||||
} else
|
||||
mlen = -1;
|
||||
} else if (mlen == -1)
|
||||
s_util.c[0] = *(char *)w;
|
||||
next:
|
||||
m = m->m_next;
|
||||
|
||||
/*
|
||||
* Lastly calculate a summary of the rest of mbufs.
|
||||
*/
|
||||
|
||||
for (;m && len; m = m->m_next) {
|
||||
if (m->m_len == 0)
|
||||
continue;
|
||||
w = mtod(m, u_int16_t *);
|
||||
if (mlen == -1) {
|
||||
/*
|
||||
* The first byte of this mbuf is the continuation
|
||||
* of a word spanning between this mbuf and the
|
||||
* last mbuf.
|
||||
*
|
||||
* s_util.c[0] is already saved when scanning previous
|
||||
* mbuf.
|
||||
*/
|
||||
s_util.c[1] = *(char *)w;
|
||||
sum += s_util.s;
|
||||
w = (u_int16_t *)((char *)w + 1);
|
||||
mlen = m->m_len - 1;
|
||||
len--;
|
||||
} else
|
||||
mlen = m->m_len;
|
||||
if (len < mlen)
|
||||
mlen = len;
|
||||
len -= mlen;
|
||||
/*
|
||||
* Force to even boundary.
|
||||
*/
|
||||
if ((1 & (long) w) && (mlen > 0)) {
|
||||
REDUCE;
|
||||
sum <<= 8;
|
||||
s_util.c[0] = *(u_char *)w;
|
||||
w = (u_int16_t *)((char *)w + 1);
|
||||
mlen--;
|
||||
byte_swapped = 1;
|
||||
}
|
||||
/*
|
||||
* Unroll the loop to make overhead from
|
||||
* branches &c small.
|
||||
*/
|
||||
while ((mlen -= 32) >= 0) {
|
||||
sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3];
|
||||
sum += w[4]; sum += w[5]; sum += w[6]; sum += w[7];
|
||||
sum += w[8]; sum += w[9]; sum += w[10]; sum += w[11];
|
||||
sum += w[12]; sum += w[13]; sum += w[14]; sum += w[15];
|
||||
w += 16;
|
||||
}
|
||||
mlen += 32;
|
||||
while ((mlen -= 8) >= 0) {
|
||||
sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3];
|
||||
w += 4;
|
||||
}
|
||||
mlen += 8;
|
||||
if (mlen == 0 && byte_swapped == 0)
|
||||
continue;
|
||||
REDUCE;
|
||||
while ((mlen -= 2) >= 0) {
|
||||
sum += *w++;
|
||||
}
|
||||
if (byte_swapped) {
|
||||
REDUCE;
|
||||
sum <<= 8;
|
||||
byte_swapped = 0;
|
||||
if (mlen == -1) {
|
||||
s_util.c[1] = *(char *)w;
|
||||
sum += s_util.s;
|
||||
mlen = 0;
|
||||
} else
|
||||
mlen = -1;
|
||||
} else if (mlen == -1)
|
||||
s_util.c[0] = *(char *)w;
|
||||
}
|
||||
if (len)
|
||||
panic("in6_cksum: out of data\n");
|
||||
if (mlen == -1) {
|
||||
/* The last mbuf has odd # of bytes. Follow the
|
||||
standard (the odd byte may be shifted left by 8 bits
|
||||
or not as determined by endian-ness of the machine) */
|
||||
s_util.c[1] = 0;
|
||||
sum += s_util.s;
|
||||
}
|
||||
REDUCE;
|
||||
return (~sum & 0xffff);
|
||||
}
|
||||
690
sys/netinet6/in6_ifattach.c
Normal file
690
sys/netinet6/in6_ifattach.c
Normal file
|
|
@ -0,0 +1,690 @@
|
|||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sockio.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/md5.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <net/if_types.h>
|
||||
#include <net/route.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_var.h>
|
||||
#include <netinet/if_ether.h>
|
||||
|
||||
#include <netinet6/in6.h>
|
||||
#include <netinet6/ip6.h>
|
||||
#include <netinet6/ip6_var.h>
|
||||
#include <netinet6/in6_ifattach.h>
|
||||
#include <netinet6/ip6.h>
|
||||
#include <netinet6/ip6_var.h>
|
||||
#include <netinet6/nd6.h>
|
||||
|
||||
#include <net/net_osdep.h>
|
||||
|
||||
static struct in6_addr llsol;
|
||||
|
||||
struct in6_ifstat **in6_ifstat = NULL;
|
||||
struct icmp6_ifstat **icmp6_ifstat = NULL;
|
||||
size_t in6_ifstatmax = 0;
|
||||
size_t icmp6_ifstatmax = 0;
|
||||
unsigned long in6_maxmtu = 0;
|
||||
|
||||
int found_first_ifid = 0;
|
||||
#define IFID_LEN 8
|
||||
static char first_ifid[IFID_LEN];
|
||||
|
||||
static int laddr_to_eui64 __P((u_int8_t *, u_int8_t *, size_t));
|
||||
static int gen_rand_eui64 __P((u_int8_t *));
|
||||
|
||||
static int
|
||||
laddr_to_eui64(dst, src, len)
|
||||
u_int8_t *dst;
|
||||
u_int8_t *src;
|
||||
size_t len;
|
||||
{
|
||||
static u_int8_t zero[8];
|
||||
|
||||
bzero(zero, sizeof(zero));
|
||||
|
||||
switch (len) {
|
||||
case 6:
|
||||
if (bcmp(zero, src, 6) == 0)
|
||||
return EINVAL;
|
||||
dst[0] = src[0];
|
||||
dst[1] = src[1];
|
||||
dst[2] = src[2];
|
||||
dst[3] = 0xff;
|
||||
dst[4] = 0xfe;
|
||||
dst[5] = src[3];
|
||||
dst[6] = src[4];
|
||||
dst[7] = src[5];
|
||||
break;
|
||||
case 8:
|
||||
if (bcmp(zero, src, 8) == 0)
|
||||
return EINVAL;
|
||||
bcopy(src, dst, len);
|
||||
break;
|
||||
default:
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate a last-resort interface identifier, when the machine has no
|
||||
* IEEE802/EUI64 address sources.
|
||||
* The address should be random, and should not change across reboot.
|
||||
*/
|
||||
static int
|
||||
gen_rand_eui64(dst)
|
||||
u_int8_t *dst;
|
||||
{
|
||||
MD5_CTX ctxt;
|
||||
u_int8_t digest[16];
|
||||
int hostnamelen = strlen(hostname);
|
||||
|
||||
/* generate 8bytes of pseudo-random value. */
|
||||
bzero(&ctxt, sizeof(ctxt));
|
||||
MD5Init(&ctxt);
|
||||
MD5Update(&ctxt, hostname, hostnamelen);
|
||||
MD5Final(digest, &ctxt);
|
||||
|
||||
/* assumes sizeof(digest) > sizeof(first_ifid) */
|
||||
bcopy(digest, dst, 8);
|
||||
|
||||
/* make sure to set "u" bit to local, and "g" bit to individual. */
|
||||
dst[0] &= 0xfe;
|
||||
dst[0] |= 0x02; /* EUI64 "local" */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find first ifid on list of interfaces.
|
||||
* This is assumed that ifp0's interface token (for example, IEEE802 MAC)
|
||||
* is globally unique. We may need to have a flag parameter in the future.
|
||||
*/
|
||||
int
|
||||
in6_ifattach_getifid(ifp0)
|
||||
struct ifnet *ifp0;
|
||||
{
|
||||
struct ifnet *ifp;
|
||||
struct ifaddr *ifa;
|
||||
u_int8_t *addr = NULL;
|
||||
int addrlen = 0;
|
||||
struct sockaddr_dl *sdl;
|
||||
|
||||
if (found_first_ifid)
|
||||
return 0;
|
||||
|
||||
for (ifp = ifnet.tqh_first; ifp; ifp = ifp->if_list.tqe_next)
|
||||
{
|
||||
if (ifp0 != NULL && ifp0 != ifp)
|
||||
continue;
|
||||
for (ifa = ifp->if_addrlist.tqh_first;
|
||||
ifa;
|
||||
ifa = ifa->ifa_list.tqe_next)
|
||||
{
|
||||
if (ifa->ifa_addr->sa_family != AF_LINK)
|
||||
continue;
|
||||
sdl = (struct sockaddr_dl *)ifa->ifa_addr;
|
||||
if (sdl == NULL)
|
||||
continue;
|
||||
if (sdl->sdl_alen == 0)
|
||||
continue;
|
||||
switch (ifp->if_type) {
|
||||
case IFT_ETHER:
|
||||
case IFT_FDDI:
|
||||
case IFT_ATM:
|
||||
/* IEEE802/EUI64 cases - what others? */
|
||||
addr = LLADDR(sdl);
|
||||
addrlen = sdl->sdl_alen;
|
||||
/*
|
||||
* to copy ifid from IEEE802/EUI64 interface,
|
||||
* u bit of the source needs to be 0.
|
||||
*/
|
||||
if ((addr[0] & 0x02) != 0)
|
||||
break;
|
||||
goto found;
|
||||
case IFT_ARCNET:
|
||||
/*
|
||||
* ARCnet interface token cannot be used as
|
||||
* globally unique identifier due to its
|
||||
* small bitwidth.
|
||||
*/
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG
|
||||
printf("in6_ifattach_getifid: failed to get EUI64");
|
||||
#endif
|
||||
return EADDRNOTAVAIL;
|
||||
|
||||
found:
|
||||
if (laddr_to_eui64(first_ifid, addr, addrlen) == 0)
|
||||
found_first_ifid = 1;
|
||||
|
||||
if (found_first_ifid) {
|
||||
printf("%s: supplying EUI64: "
|
||||
"%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
if_name(ifp),
|
||||
first_ifid[0] & 0xff, first_ifid[1] & 0xff,
|
||||
first_ifid[2] & 0xff, first_ifid[3] & 0xff,
|
||||
first_ifid[4] & 0xff, first_ifid[5] & 0xff,
|
||||
first_ifid[6] & 0xff, first_ifid[7] & 0xff);
|
||||
|
||||
/* invert u bit to convert EUI64 to RFC2373 interface ID. */
|
||||
first_ifid[0] ^= 0x02;
|
||||
|
||||
return 0;
|
||||
} else {
|
||||
#ifdef DEBUG
|
||||
printf("in6_ifattach_getifid: failed to get EUI64");
|
||||
#endif
|
||||
return EADDRNOTAVAIL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* add link-local address to *pseudo* p2p interfaces.
|
||||
* get called when the first MAC address is made available in in6_ifattach().
|
||||
*
|
||||
* XXX I start considering this loop as a bad idea. (itojun)
|
||||
*/
|
||||
void
|
||||
in6_ifattach_p2p()
|
||||
{
|
||||
struct ifnet *ifp;
|
||||
|
||||
/* prevent infinite loop. just in case. */
|
||||
if (found_first_ifid == 0)
|
||||
return;
|
||||
|
||||
for (ifp = ifnet.tqh_first; ifp; ifp = ifp->if_list.tqe_next)
|
||||
{
|
||||
switch (ifp->if_type) {
|
||||
case IFT_GIF:
|
||||
/* pseudo interfaces - safe to initialize here */
|
||||
in6_ifattach(ifp, IN6_IFT_P2P, 0, 0);
|
||||
break;
|
||||
#ifdef IFT_DUMMY
|
||||
case IFT_DUMMY:
|
||||
#endif
|
||||
case IFT_FAITH:
|
||||
/* this mistakingly becomes IFF_UP */
|
||||
break;
|
||||
case IFT_SLIP:
|
||||
/* IPv6 is not supported */
|
||||
break;
|
||||
case IFT_PPP:
|
||||
/* this is not a pseudo interface, skip it */
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
in6_ifattach(ifp, type, laddr, noloop)
|
||||
struct ifnet *ifp;
|
||||
u_int type;
|
||||
caddr_t laddr;
|
||||
/* size_t laddrlen; */
|
||||
int noloop;
|
||||
{
|
||||
static size_t if_indexlim = 8;
|
||||
struct sockaddr_in6 mltaddr;
|
||||
struct sockaddr_in6 mltmask;
|
||||
struct sockaddr_in6 gate;
|
||||
struct sockaddr_in6 mask;
|
||||
|
||||
struct in6_ifaddr *ia, *ib, *oia;
|
||||
struct ifaddr *ifa;
|
||||
int rtflag = 0;
|
||||
|
||||
if (type == IN6_IFT_P2P && found_first_ifid == 0) {
|
||||
printf("%s: no ifid available for IPv6 link-local address\n",
|
||||
if_name(ifp));
|
||||
/* last resort */
|
||||
if (gen_rand_eui64(first_ifid) == 0) {
|
||||
printf("%s: using random value as EUI64: "
|
||||
"%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
if_name(ifp),
|
||||
first_ifid[0] & 0xff, first_ifid[1] & 0xff,
|
||||
first_ifid[2] & 0xff, first_ifid[3] & 0xff,
|
||||
first_ifid[4] & 0xff, first_ifid[5] & 0xff,
|
||||
first_ifid[6] & 0xff, first_ifid[7] & 0xff);
|
||||
/*
|
||||
* invert u bit to convert EUI64 to RFC2373 interface
|
||||
* ID.
|
||||
*/
|
||||
first_ifid[0] ^= 0x02;
|
||||
|
||||
found_first_ifid = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ((ifp->if_flags & IFF_MULTICAST) == 0) {
|
||||
printf("%s: not multicast capable, IPv6 not enabled\n",
|
||||
if_name(ifp));
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* We have some arrays that should be indexed by if_index.
|
||||
* since if_index will grow dynamically, they should grow too.
|
||||
* struct in6_ifstat **in6_ifstat
|
||||
* struct icmp6_ifstat **icmp6_ifstat
|
||||
*/
|
||||
if (in6_ifstat == NULL || icmp6_ifstat == NULL
|
||||
|| if_index >= if_indexlim) {
|
||||
size_t n;
|
||||
caddr_t q;
|
||||
size_t olim;
|
||||
|
||||
olim = if_indexlim;
|
||||
while (if_index >= if_indexlim)
|
||||
if_indexlim <<= 1;
|
||||
|
||||
/* grow in6_ifstat */
|
||||
n = if_indexlim * sizeof(struct in6_ifstat *);
|
||||
q = (caddr_t)malloc(n, M_IFADDR, M_WAITOK);
|
||||
bzero(q, n);
|
||||
if (in6_ifstat) {
|
||||
bcopy((caddr_t)in6_ifstat, q,
|
||||
olim * sizeof(struct in6_ifstat *));
|
||||
free((caddr_t)in6_ifstat, M_IFADDR);
|
||||
}
|
||||
in6_ifstat = (struct in6_ifstat **)q;
|
||||
in6_ifstatmax = if_indexlim;
|
||||
|
||||
/* grow icmp6_ifstat */
|
||||
n = if_indexlim * sizeof(struct icmp6_ifstat *);
|
||||
q = (caddr_t)malloc(n, M_IFADDR, M_WAITOK);
|
||||
bzero(q, n);
|
||||
if (icmp6_ifstat) {
|
||||
bcopy((caddr_t)icmp6_ifstat, q,
|
||||
olim * sizeof(struct icmp6_ifstat *));
|
||||
free((caddr_t)icmp6_ifstat, M_IFADDR);
|
||||
}
|
||||
icmp6_ifstat = (struct icmp6_ifstat **)q;
|
||||
icmp6_ifstatmax = if_indexlim;
|
||||
}
|
||||
|
||||
/*
|
||||
* To prevent to assign link-local address to PnP network
|
||||
* cards multiple times.
|
||||
* This is lengthy for P2P and LOOP but works.
|
||||
*/
|
||||
ifa = TAILQ_FIRST(&ifp->if_addrlist);
|
||||
if (ifa != NULL) {
|
||||
for ( ; ifa; ifa = TAILQ_NEXT(ifa, ifa_list)) {
|
||||
if (ifa->ifa_addr->sa_family != AF_INET6)
|
||||
continue;
|
||||
if (IN6_IS_ADDR_LINKLOCAL(&satosin6(ifa->ifa_addr)->sin6_addr))
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
TAILQ_INIT(&ifp->if_addrlist);
|
||||
}
|
||||
|
||||
/*
|
||||
* link-local address
|
||||
*/
|
||||
ia = (struct in6_ifaddr *)malloc(sizeof(*ia), M_IFADDR, M_WAITOK);
|
||||
bzero((caddr_t)ia, sizeof(*ia));
|
||||
ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr;
|
||||
ia->ia_ifa.ifa_dstaddr = (struct sockaddr *)&ia->ia_dstaddr;
|
||||
ia->ia_ifa.ifa_netmask = (struct sockaddr *)&ia->ia_prefixmask;
|
||||
ia->ia_ifp = ifp;
|
||||
TAILQ_INSERT_TAIL(&ifp->if_addrlist, (struct ifaddr *)ia, ifa_list);
|
||||
/*
|
||||
* Also link into the IPv6 address chain beginning with in6_ifaddr.
|
||||
* kazu opposed it, but itojun & jinmei wanted.
|
||||
*/
|
||||
if ((oia = in6_ifaddr) != NULL) {
|
||||
for (; oia->ia_next; oia = oia->ia_next)
|
||||
continue;
|
||||
oia->ia_next = ia;
|
||||
} else
|
||||
in6_ifaddr = ia;
|
||||
|
||||
ia->ia_prefixmask.sin6_len = sizeof(struct sockaddr_in6);
|
||||
ia->ia_prefixmask.sin6_family = AF_INET6;
|
||||
ia->ia_prefixmask.sin6_addr = in6mask64;
|
||||
|
||||
bzero(&ia->ia_addr, sizeof(struct sockaddr_in6));
|
||||
ia->ia_addr.sin6_len = sizeof(struct sockaddr_in6);
|
||||
ia->ia_addr.sin6_family = AF_INET6;
|
||||
ia->ia_addr.sin6_addr.s6_addr16[0] = htons(0xfe80);
|
||||
ia->ia_addr.sin6_addr.s6_addr16[1] = htons(ifp->if_index);
|
||||
ia->ia_addr.sin6_addr.s6_addr32[1] = 0;
|
||||
|
||||
switch (type) {
|
||||
case IN6_IFT_LOOP:
|
||||
ia->ia_addr.sin6_addr.s6_addr32[2] = 0;
|
||||
ia->ia_addr.sin6_addr.s6_addr32[3] = htonl(1);
|
||||
break;
|
||||
case IN6_IFT_802:
|
||||
ia->ia_ifa.ifa_rtrequest = nd6_rtrequest;
|
||||
ia->ia_ifa.ifa_flags |= RTF_CLONING;
|
||||
rtflag = RTF_CLONING;
|
||||
/* fall through */
|
||||
case IN6_IFT_P2P802:
|
||||
if (laddr == NULL)
|
||||
break;
|
||||
/* XXX use laddrlen */
|
||||
if (laddr_to_eui64(&ia->ia_addr.sin6_addr.s6_addr8[8],
|
||||
laddr, 6) != 0) {
|
||||
break;
|
||||
}
|
||||
/* invert u bit to convert EUI64 to RFC2373 interface ID. */
|
||||
ia->ia_addr.sin6_addr.s6_addr8[8] ^= 0x02;
|
||||
if (found_first_ifid == 0) {
|
||||
if (in6_ifattach_getifid(ifp) == 0)
|
||||
in6_ifattach_p2p();
|
||||
}
|
||||
break;
|
||||
case IN6_IFT_P2P:
|
||||
bcopy((caddr_t)first_ifid,
|
||||
(caddr_t)&ia->ia_addr.sin6_addr.s6_addr8[8],
|
||||
IFID_LEN);
|
||||
break;
|
||||
case IN6_IFT_ARCNET:
|
||||
ia->ia_ifa.ifa_rtrequest = nd6_rtrequest;
|
||||
ia->ia_ifa.ifa_flags |= RTF_CLONING;
|
||||
rtflag = RTF_CLONING;
|
||||
if (laddr == NULL)
|
||||
break;
|
||||
|
||||
/* make non-global IF id out of link-level address */
|
||||
bzero(&ia->ia_addr.sin6_addr.s6_addr8[8], 7);
|
||||
ia->ia_addr.sin6_addr.s6_addr8[15] = *laddr;
|
||||
}
|
||||
|
||||
ia->ia_ifa.ifa_metric = ifp->if_metric;
|
||||
|
||||
if (ifp->if_ioctl != NULL) {
|
||||
int s;
|
||||
int error;
|
||||
|
||||
/*
|
||||
* give the interface a chance to initialize, in case this
|
||||
* is the first address to be added.
|
||||
*/
|
||||
s = splimp();
|
||||
error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, (caddr_t)ia);
|
||||
splx(s);
|
||||
|
||||
if (error) {
|
||||
switch (error) {
|
||||
case EAFNOSUPPORT:
|
||||
printf("%s: IPv6 not supported\n",
|
||||
if_name(ifp));
|
||||
break;
|
||||
default:
|
||||
printf("%s: SIOCSIFADDR error %d\n",
|
||||
if_name(ifp), error);
|
||||
break;
|
||||
}
|
||||
|
||||
/* undo changes */
|
||||
TAILQ_REMOVE(&ifp->if_addrlist, (struct ifaddr *)ia, ifa_list);
|
||||
if (oia)
|
||||
oia->ia_next = ia->ia_next;
|
||||
else
|
||||
in6_ifaddr = ia->ia_next;
|
||||
free(ia, M_IFADDR);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* add route to the interface. */
|
||||
rtrequest(RTM_ADD,
|
||||
(struct sockaddr *)&ia->ia_addr,
|
||||
(struct sockaddr *)&ia->ia_addr,
|
||||
(struct sockaddr *)&ia->ia_prefixmask,
|
||||
RTF_UP|rtflag,
|
||||
(struct rtentry **)0);
|
||||
ia->ia_flags |= IFA_ROUTE;
|
||||
|
||||
if (type == IN6_IFT_P2P || type == IN6_IFT_P2P802) {
|
||||
/*
|
||||
* route local address to loopback
|
||||
*/
|
||||
bzero(&gate, sizeof(gate));
|
||||
gate.sin6_len = sizeof(struct sockaddr_in6);
|
||||
gate.sin6_family = AF_INET6;
|
||||
gate.sin6_addr = in6addr_loopback;
|
||||
bzero(&mask, sizeof(mask));
|
||||
mask.sin6_len = sizeof(struct sockaddr_in6);
|
||||
mask.sin6_family = AF_INET6;
|
||||
mask.sin6_addr = in6mask64;
|
||||
rtrequest(RTM_ADD,
|
||||
(struct sockaddr *)&ia->ia_addr,
|
||||
(struct sockaddr *)&gate,
|
||||
(struct sockaddr *)&mask,
|
||||
RTF_UP|RTF_HOST,
|
||||
(struct rtentry **)0);
|
||||
}
|
||||
|
||||
/*
|
||||
* loopback address
|
||||
*/
|
||||
ib = (struct in6_ifaddr *)NULL;
|
||||
if (type == IN6_IFT_LOOP) {
|
||||
ib = (struct in6_ifaddr *)
|
||||
malloc(sizeof(*ib), M_IFADDR, M_WAITOK);
|
||||
bzero((caddr_t)ib, sizeof(*ib));
|
||||
ib->ia_ifa.ifa_addr = (struct sockaddr *)&ib->ia_addr;
|
||||
ib->ia_ifa.ifa_dstaddr = (struct sockaddr *)&ib->ia_dstaddr;
|
||||
ib->ia_ifa.ifa_netmask = (struct sockaddr *)&ib->ia_prefixmask;
|
||||
ib->ia_ifp = ifp;
|
||||
|
||||
ia->ia_next = ib;
|
||||
TAILQ_INSERT_TAIL(&ifp->if_addrlist, (struct ifaddr *)ib,
|
||||
ifa_list);
|
||||
|
||||
ib->ia_prefixmask.sin6_len = sizeof(struct sockaddr_in6);
|
||||
ib->ia_prefixmask.sin6_family = AF_INET6;
|
||||
ib->ia_prefixmask.sin6_addr = in6mask128;
|
||||
ib->ia_addr.sin6_len = sizeof(struct sockaddr_in6);
|
||||
ib->ia_addr.sin6_family = AF_INET6;
|
||||
ib->ia_addr.sin6_addr = in6addr_loopback;
|
||||
ib->ia_ifa.ifa_metric = ifp->if_metric;
|
||||
|
||||
rtrequest(RTM_ADD,
|
||||
(struct sockaddr *)&ib->ia_addr,
|
||||
(struct sockaddr *)&ib->ia_addr,
|
||||
(struct sockaddr *)&ib->ia_prefixmask,
|
||||
RTF_UP|RTF_HOST,
|
||||
(struct rtentry **)0);
|
||||
|
||||
ib->ia_flags |= IFA_ROUTE;
|
||||
}
|
||||
|
||||
/*
|
||||
* join multicast
|
||||
*/
|
||||
if (ifp->if_flags & IFF_MULTICAST) {
|
||||
int error; /* not used */
|
||||
|
||||
bzero(&mltmask, sizeof(mltmask));
|
||||
mltmask.sin6_len = sizeof(struct sockaddr_in6);
|
||||
mltmask.sin6_family = AF_INET6;
|
||||
mltmask.sin6_addr = in6mask32;
|
||||
|
||||
/*
|
||||
* join link-local all-nodes address
|
||||
*/
|
||||
bzero(&mltaddr, sizeof(mltaddr));
|
||||
mltaddr.sin6_len = sizeof(struct sockaddr_in6);
|
||||
mltaddr.sin6_family = AF_INET6;
|
||||
mltaddr.sin6_addr = in6addr_linklocal_allnodes;
|
||||
mltaddr.sin6_addr.s6_addr16[1] = htons(ifp->if_index);
|
||||
rtrequest(RTM_ADD,
|
||||
(struct sockaddr *)&mltaddr,
|
||||
(struct sockaddr *)&ia->ia_addr,
|
||||
(struct sockaddr *)&mltmask,
|
||||
RTF_UP|RTF_CLONING, /* xxx */
|
||||
(struct rtentry **)0);
|
||||
(void)in6_addmulti(&mltaddr.sin6_addr, ifp, &error);
|
||||
|
||||
if (type == IN6_IFT_LOOP) {
|
||||
/*
|
||||
* join node-local all-nodes address
|
||||
*/
|
||||
mltaddr.sin6_addr = in6addr_nodelocal_allnodes;
|
||||
rtrequest(RTM_ADD,
|
||||
(struct sockaddr *)&mltaddr,
|
||||
(struct sockaddr *)&ib->ia_addr,
|
||||
(struct sockaddr *)&mltmask,
|
||||
RTF_UP,
|
||||
(struct rtentry **)0);
|
||||
(void)in6_addmulti(&mltaddr.sin6_addr, ifp, &error);
|
||||
} else {
|
||||
/*
|
||||
* join solicited multicast address
|
||||
*/
|
||||
bzero(&llsol, sizeof(llsol));
|
||||
llsol.s6_addr16[0] = htons(0xff02);
|
||||
llsol.s6_addr16[1] = htons(ifp->if_index);
|
||||
llsol.s6_addr32[1] = 0;
|
||||
llsol.s6_addr32[2] = htonl(1);
|
||||
llsol.s6_addr32[3] = ia->ia_addr.sin6_addr.s6_addr32[3];
|
||||
llsol.s6_addr8[12] = 0xff;
|
||||
(void)in6_addmulti(&llsol, ifp, &error);
|
||||
}
|
||||
}
|
||||
|
||||
/* update dynamically. */
|
||||
if (in6_maxmtu < ifp->if_mtu)
|
||||
in6_maxmtu = ifp->if_mtu;
|
||||
|
||||
if (in6_ifstat[ifp->if_index] == NULL) {
|
||||
in6_ifstat[ifp->if_index] = (struct in6_ifstat *)
|
||||
malloc(sizeof(struct in6_ifstat), M_IFADDR, M_WAITOK);
|
||||
bzero(in6_ifstat[ifp->if_index], sizeof(struct in6_ifstat));
|
||||
}
|
||||
if (icmp6_ifstat[ifp->if_index] == NULL) {
|
||||
icmp6_ifstat[ifp->if_index] = (struct icmp6_ifstat *)
|
||||
malloc(sizeof(struct icmp6_ifstat), M_IFADDR, M_WAITOK);
|
||||
bzero(icmp6_ifstat[ifp->if_index], sizeof(struct icmp6_ifstat));
|
||||
}
|
||||
|
||||
/* initialize NDP variables */
|
||||
nd6_ifattach(ifp);
|
||||
|
||||
/* mark the address TENTATIVE, if needed. */
|
||||
switch (ifp->if_type) {
|
||||
case IFT_ARCNET:
|
||||
case IFT_ETHER:
|
||||
case IFT_FDDI:
|
||||
ia->ia6_flags |= IN6_IFF_TENTATIVE;
|
||||
/* nd6_dad_start() will be called in in6_if_up */
|
||||
break;
|
||||
#ifdef IFT_DUMMY
|
||||
case IFT_DUMMY:
|
||||
#endif
|
||||
case IFT_GIF: /*XXX*/
|
||||
case IFT_LOOP:
|
||||
case IFT_FAITH:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
in6_ifdetach(ifp)
|
||||
struct ifnet *ifp;
|
||||
{
|
||||
struct in6_ifaddr *ia, *oia;
|
||||
struct ifaddr *ifa;
|
||||
struct rtentry *rt;
|
||||
short rtflags;
|
||||
|
||||
for (ifa = ifp->if_addrlist.tqh_first; ifa; ifa = ifa->ifa_list.tqe_next)
|
||||
{
|
||||
if (ifa->ifa_addr->sa_family != AF_INET6
|
||||
|| !IN6_IS_ADDR_LINKLOCAL(&satosin6(&ifa->ifa_addr)->sin6_addr)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ia = (struct in6_ifaddr *)ifa;
|
||||
|
||||
/* remove from the routing table */
|
||||
if ((ia->ia_flags & IFA_ROUTE)
|
||||
&& (rt = rtalloc1((struct sockaddr *)&ia->ia_addr, 0, 0UL))) {
|
||||
rtflags = rt->rt_flags;
|
||||
rtfree(rt);
|
||||
rtrequest(RTM_DELETE,
|
||||
(struct sockaddr *)&ia->ia_addr,
|
||||
(struct sockaddr *)&ia->ia_addr,
|
||||
(struct sockaddr *)&ia->ia_prefixmask,
|
||||
rtflags, (struct rtentry **)0);
|
||||
}
|
||||
|
||||
/* remove from the linked list */
|
||||
TAILQ_REMOVE(&ifp->if_addrlist, (struct ifaddr *)ia, ifa_list);
|
||||
|
||||
/* also remove from the IPv6 address chain(itojun&jinmei) */
|
||||
oia = ia;
|
||||
if (oia == (ia = in6_ifaddr))
|
||||
in6_ifaddr = ia->ia_next;
|
||||
else {
|
||||
while (ia->ia_next && (ia->ia_next != oia))
|
||||
ia = ia->ia_next;
|
||||
if (ia->ia_next)
|
||||
ia->ia_next = oia->ia_next;
|
||||
#ifdef DEBUG
|
||||
else
|
||||
printf("%s: didn't unlink in6ifaddr from "
|
||||
"list\n", if_name(ifp));
|
||||
#endif
|
||||
}
|
||||
|
||||
free(ia, M_IFADDR);
|
||||
}
|
||||
}
|
||||
50
sys/netinet6/in6_ifattach.h
Normal file
50
sys/netinet6/in6_ifattach.h
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _NETINET6_IN6_IFATTACH_H_
|
||||
#define _NETINET6_IN6_IFATTACH_H_
|
||||
|
||||
#ifdef _KERNEL
|
||||
extern int found_first_ifid;
|
||||
|
||||
int in6_ifattach_getifid __P((struct ifnet *));
|
||||
void in6_ifattach_p2p __P((void));
|
||||
void in6_ifattach __P((struct ifnet *, u_int, caddr_t, int));
|
||||
void in6_ifdetach __P((struct ifnet *));
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#define IN6_IFT_LOOP 1
|
||||
#define IN6_IFT_P2P 2
|
||||
#define IN6_IFT_802 3
|
||||
#define IN6_IFT_P2P802 4
|
||||
#define IN6_IFT_ARCNET 5
|
||||
|
||||
#endif /* _NETINET6_IN6_IFATTACH_H_ */
|
||||
1131
sys/netinet6/in6_pcb.c
Normal file
1131
sys/netinet6/in6_pcb.c
Normal file
File diff suppressed because it is too large
Load diff
108
sys/netinet6/in6_pcb.h
Normal file
108
sys/netinet6/in6_pcb.h
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1982, 1986, 1990, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)in_pcb.h 8.1 (Berkeley) 6/10/93
|
||||
*/
|
||||
|
||||
#ifndef _NETINET6_IN6_PCB_H_
|
||||
#define _NETINET6_IN6_PCB_H_
|
||||
|
||||
#ifdef KERNEL
|
||||
#define satosin6(sa) ((struct sockaddr_in6 *)(sa))
|
||||
#define sin6tosa(sin6) ((struct sockaddr *)(sin6))
|
||||
#define ifatoia6(ifa) ((struct in6_ifaddr *)(ifa))
|
||||
|
||||
void in6_losing __P((struct inpcb *));
|
||||
int in6_pcballoc __P((struct socket *, struct inpcbinfo *, struct proc *));
|
||||
int in6_pcbbind __P((struct inpcb *, struct sockaddr *, struct proc *));
|
||||
int in6_pcbconnect __P((struct inpcb *, struct sockaddr *, struct proc *));
|
||||
void in6_pcbdetach __P((struct inpcb *));
|
||||
void in6_pcbdisconnect __P((struct inpcb *));
|
||||
int in6_pcbladdr __P((struct inpcb *, struct sockaddr *,
|
||||
struct in6_addr **));
|
||||
struct inpcb *
|
||||
in6_pcblookup_local __P((struct inpcbinfo *,
|
||||
struct in6_addr *, u_int, int));
|
||||
struct inpcb *
|
||||
in6_pcblookup_hash __P((struct inpcbinfo *,
|
||||
struct in6_addr *, u_int, struct in6_addr *,
|
||||
u_int, int, struct ifnet *));
|
||||
void in6_pcbnotify __P((struct inpcbhead *, struct sockaddr *,
|
||||
u_int, struct in6_addr *, u_int, int,
|
||||
void (*)(struct inpcb *, int)));
|
||||
void in6_rtchange __P((struct inpcb *, int));
|
||||
int in6_setpeeraddr __P((struct socket *so, struct sockaddr **nam));
|
||||
int in6_setsockaddr __P((struct socket *so, struct sockaddr **nam));
|
||||
int in6_mapped_sockaddr __P((struct socket *so, struct sockaddr **nam));
|
||||
int in6_mapped_peeraddr __P((struct socket *so, struct sockaddr **nam));
|
||||
struct in6_addr *in6_selectsrc __P((struct sockaddr_in6 *,
|
||||
struct ip6_pktopts *,
|
||||
struct ip6_moptions *,
|
||||
struct route_in6 *,
|
||||
struct in6_addr *, int *));
|
||||
int in6_selecthlim __P((struct inpcb *, struct ifnet *));
|
||||
|
||||
void init_sin6 __P((struct sockaddr_in6 *sin6, struct mbuf *m));
|
||||
#endif /* KERNEL */
|
||||
|
||||
#endif /* !_NETINET6_IN6_PCB_H_ */
|
||||
1106
sys/netinet6/in6_prefix.c
Normal file
1106
sys/netinet6/in6_prefix.c
Normal file
File diff suppressed because it is too large
Load diff
88
sys/netinet6/in6_prefix.h
Normal file
88
sys/netinet6/in6_prefix.h
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, 1998 and 1999 WIDE Project.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
struct rr_prefix {
|
||||
struct ifprefix rp_ifpr;
|
||||
LIST_ENTRY(rr_prefix) rp_entry;
|
||||
LIST_HEAD(rp_addrhead, rp_addr) rp_addrhead;
|
||||
struct sockaddr_in6 rp_prefix; /* prefix */
|
||||
u_int32_t rp_vltime; /* advertised valid lifetime */
|
||||
u_int32_t rp_pltime; /* advertised preferred lifetime */
|
||||
time_t rp_expire; /* expiration time of the prefix */
|
||||
time_t rp_preferred; /* preferred time of the prefix */
|
||||
struct in6_prflags rp_flags;
|
||||
u_char rp_origin; /* from where this prefix info is obtained */
|
||||
struct rp_stateflags {
|
||||
/* if some prefix should be added to this prefix */
|
||||
u_char addmark : 1;
|
||||
u_char delmark : 1; /* if this prefix will be deleted */
|
||||
} rp_stateflags;
|
||||
};
|
||||
|
||||
#define rp_type rp_ifpr.ifpr_type
|
||||
#define rp_ifp rp_ifpr.ifpr_ifp
|
||||
#define rp_plen rp_ifpr.ifpr_plen
|
||||
|
||||
#define rp_raf rp_flags.prf_ra
|
||||
#define rp_raf_onlink rp_flags.prf_ra.onlink
|
||||
#define rp_raf_auto rp_flags.prf_ra.autonomous
|
||||
|
||||
#define rp_statef_addmark rp_stateflags.addmark
|
||||
#define rp_statef_delmark rp_stateflags.delmark
|
||||
|
||||
#define rp_rrf rp_flags.prf_rr
|
||||
#define rp_rrf_decrvalid rp_flags.prf_rr.decrvalid
|
||||
#define rp_rrf_decrprefd rp_flags.prf_rr.decrprefd
|
||||
|
||||
struct rp_addr {
|
||||
LIST_ENTRY(rp_addr) ra_entry;
|
||||
struct in6_addr ra_ifid;
|
||||
struct in6_ifaddr *ra_addr;
|
||||
struct ra_flags {
|
||||
u_char anycast : 1;
|
||||
} ra_flags;
|
||||
};
|
||||
|
||||
#define ifpr2rp(ifpr) ((struct rr_prefix *)(ifpr))
|
||||
#define rp2ifpr(rp) ((struct ifprefix *)(rp))
|
||||
|
||||
#define RP_IN6(rp) (&(rp)->rp_prefix.sin6_addr)
|
||||
|
||||
#define RR_INFINITE_LIFETIME 0xffffffff
|
||||
|
||||
|
||||
LIST_HEAD(rr_prhead, rr_prefix);
|
||||
|
||||
extern struct rr_prhead rr_prefix;
|
||||
|
||||
void in6_rr_timer __P((void *));
|
||||
int delete_each_prefix __P((struct socket *so, struct rr_prefix *rpp,
|
||||
u_char origin));
|
||||
410
sys/netinet6/in6_proto.c
Normal file
410
sys/netinet6/in6_proto.c
Normal file
|
|
@ -0,0 +1,410 @@
|
|||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1982, 1986, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)in_proto.c 8.1 (Berkeley) 6/10/93
|
||||
*/
|
||||
|
||||
#include "opt_inet.h"
|
||||
#include "opt_ipsec.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/socketvar.h>
|
||||
#include <sys/protosw.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/domain.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/radix.h>
|
||||
#include <net/route.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/in_var.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/ip_var.h>
|
||||
#include <netinet6/ip6.h>
|
||||
#include <netinet6/ip6_var.h>
|
||||
#include <netinet6/icmp6.h>
|
||||
|
||||
#include <netinet/tcp.h>
|
||||
#include <netinet/tcp_timer.h>
|
||||
#include <netinet/tcp_var.h>
|
||||
#include <netinet/udp.h>
|
||||
#include <netinet/udp_var.h>
|
||||
#include <netinet6/tcp6_var.h>
|
||||
#include <netinet6/udp6_var.h>
|
||||
|
||||
#include <netinet6/pim6_var.h>
|
||||
|
||||
#include <netinet6/nd6.h>
|
||||
#include <netinet6/in6_prefix.h>
|
||||
|
||||
#ifdef IPSEC
|
||||
#include <netinet6/ipsec.h>
|
||||
#ifdef INET6
|
||||
#include <netinet6/ipsec6.h>
|
||||
#endif /* INET6 */
|
||||
#include <netinet6/ah.h>
|
||||
#ifdef IPSEC_ESP
|
||||
#include <netinet6/esp.h>
|
||||
#endif
|
||||
#include <netinet6/ipcomp.h>
|
||||
#endif /*IPSEC*/
|
||||
|
||||
#include <netinet6/ip6protosw.h>
|
||||
|
||||
/* #include "gif.h" */
|
||||
#if NGIF > 0
|
||||
#include <netinet6/in6_gif.h>
|
||||
#endif
|
||||
|
||||
#include <net/net_osdep.h>
|
||||
|
||||
#define offsetof(type, member) ((size_t)(&((type *)0)->member))
|
||||
|
||||
/*
|
||||
* TCP/IP protocol family: IP6, ICMP6, UDP, TCP.
|
||||
*/
|
||||
|
||||
extern struct domain inet6domain;
|
||||
static struct pr_usrreqs nousrreqs;
|
||||
|
||||
struct ip6protosw inet6sw[] = {
|
||||
{ 0, &inet6domain, IPPROTO_IPV6, 0,
|
||||
0, 0, 0, 0,
|
||||
0,
|
||||
ip6_init, 0, frag6_slowtimo, frag6_drain,
|
||||
&nousrreqs,
|
||||
},
|
||||
{ SOCK_RAW, &inet6domain, IPPROTO_RAW, PR_ATOMIC | PR_ADDR,
|
||||
rip6_input, rip6_output, 0, rip6_ctloutput,
|
||||
0,
|
||||
0, 0, 0, 0,
|
||||
&rip6_usrreqs
|
||||
},
|
||||
{ SOCK_RAW, &inet6domain, IPPROTO_ICMPV6, PR_ATOMIC | PR_ADDR,
|
||||
icmp6_input, rip6_output, 0, rip6_ctloutput,
|
||||
0,
|
||||
icmp6_init, icmp6_fasttimo, 0, 0,
|
||||
&rip6_usrreqs
|
||||
},
|
||||
{ SOCK_RAW, &inet6domain, IPPROTO_DSTOPTS,PR_ATOMIC|PR_ADDR,
|
||||
dest6_input, 0, 0, 0,
|
||||
0,
|
||||
0, 0, 0, 0,
|
||||
&nousrreqs
|
||||
},
|
||||
{ SOCK_RAW, &inet6domain, IPPROTO_ROUTING,PR_ATOMIC|PR_ADDR,
|
||||
route6_input, 0, 0, 0,
|
||||
0,
|
||||
0, 0, 0, 0,
|
||||
&nousrreqs
|
||||
},
|
||||
{ SOCK_RAW, &inet6domain, IPPROTO_FRAGMENT,PR_ATOMIC|PR_ADDR,
|
||||
frag6_input, 0, 0, 0,
|
||||
0,
|
||||
0, 0, 0, 0,
|
||||
&nousrreqs
|
||||
},
|
||||
#ifdef IPSEC
|
||||
{ SOCK_RAW, &inet6domain, IPPROTO_AH, PR_ATOMIC|PR_ADDR,
|
||||
ah6_input, 0, 0, 0,
|
||||
0,
|
||||
0, 0, 0, 0,
|
||||
&nousrreqs,
|
||||
},
|
||||
#ifdef IPSEC_ESP
|
||||
{ SOCK_RAW, &inet6domain, IPPROTO_ESP, PR_ATOMIC|PR_ADDR,
|
||||
esp6_input, 0, 0, 0,
|
||||
0,
|
||||
0, 0, 0, 0,
|
||||
&nousrreqs,
|
||||
},
|
||||
#endif
|
||||
{ SOCK_RAW, &inet6domain, IPPROTO_IPCOMP, PR_ATOMIC|PR_ADDR,
|
||||
ipcomp6_input, 0, 0, 0,
|
||||
0,
|
||||
0, 0, 0, 0,
|
||||
&nousrreqs,
|
||||
},
|
||||
#endif /* IPSEC */
|
||||
#if NGIF > 0
|
||||
{ SOCK_RAW, &inet6domain, IPPROTO_IPV4, PR_ATOMIC|PR_ADDR,
|
||||
in6_gif_input,0, 0, 0,
|
||||
0,
|
||||
0, 0, 0, 0,
|
||||
&nousrreqs
|
||||
},
|
||||
#ifdef INET6
|
||||
{ SOCK_RAW, &inet6domain, IPPROTO_IPV6, PR_ATOMIC|PR_ADDR,
|
||||
in6_gif_input,0, 0, 0,
|
||||
0,
|
||||
0, 0, 0, 0,
|
||||
&nousrreqs
|
||||
},
|
||||
#endif /* INET6 */
|
||||
#endif /* GIF */
|
||||
/* raw wildcard */
|
||||
{ SOCK_RAW, &inet6domain, 0, PR_ATOMIC | PR_ADDR,
|
||||
rip6_input, rip6_output, 0, rip6_ctloutput,
|
||||
0,
|
||||
0, 0, 0, 0,
|
||||
&rip6_usrreqs
|
||||
},
|
||||
};
|
||||
|
||||
extern int in6_inithead __P((void **, int));
|
||||
|
||||
struct domain inet6domain =
|
||||
{ AF_INET6, "internet6", 0, 0, 0,
|
||||
(struct protosw *)inet6sw,
|
||||
(struct protosw *)&inet6sw[sizeof(inet6sw)/sizeof(inet6sw[0])], 0,
|
||||
in6_inithead,
|
||||
offsetof(struct sockaddr_in6, sin6_addr) << 3,
|
||||
sizeof(struct sockaddr_in6) };
|
||||
|
||||
DOMAIN_SET(inet6);
|
||||
|
||||
/*
|
||||
* Internet configuration info
|
||||
*/
|
||||
#ifndef IPV6FORWARDING
|
||||
#ifdef GATEWAY6
|
||||
#define IPV6FORWARDING 1 /* forward IP6 packets not for us */
|
||||
#else
|
||||
#define IPV6FORWARDING 0 /* don't forward IP6 packets not for us */
|
||||
#endif /* GATEWAY6 */
|
||||
#endif /* !IPV6FORWARDING */
|
||||
|
||||
#ifndef IPV6_SENDREDIRECTS
|
||||
#define IPV6_SENDREDIRECTS 1
|
||||
#endif
|
||||
|
||||
int ip6_forwarding = IPV6FORWARDING; /* act as router? */
|
||||
int ip6_sendredirects = IPV6_SENDREDIRECTS;
|
||||
int ip6_defhlim = IPV6_DEFHLIM;
|
||||
int ip6_defmcasthlim = IPV6_DEFAULT_MULTICAST_HOPS;
|
||||
int ip6_accept_rtadv = 0; /* "IPV6FORWARDING ? 0 : 1" is dangerous */
|
||||
int ip6_maxfragpackets = 200;
|
||||
int ip6_log_interval = 5;
|
||||
int ip6_hdrnestlimit = 50; /* appropriate? */
|
||||
int ip6_dad_count = 1; /* DupAddrDetectionTransmits */
|
||||
u_int32_t ip6_flow_seq;
|
||||
int ip6_auto_flowlabel = 1;
|
||||
#if NGIF > 0
|
||||
int ip6_gif_hlim = GIF_HLIM;
|
||||
#else
|
||||
int ip6_gif_hlim = 0;
|
||||
#endif
|
||||
int ip6_use_deprecated = 1; /* allow deprecated addr (RFC2462 5.5.4) */
|
||||
int ip6_rr_prune = 5; /* router renumbering prefix
|
||||
* walk list every 5 sec. */
|
||||
int ip6_mapped_addr_on = 1;
|
||||
|
||||
u_int32_t ip6_id = 0UL;
|
||||
int ip6_keepfaith = 0;
|
||||
time_t ip6_log_time = (time_t)0L;
|
||||
|
||||
/* icmp6 */
|
||||
/*
|
||||
* BSDI4 defines these variables in in_proto.c...
|
||||
* XXX: what if we don't define INET? Should we define pmtu6_expire
|
||||
* or so? (jinmei@kame.net 19990310)
|
||||
*/
|
||||
int pmtu_expire = 60*10;
|
||||
int pmtu_probe = 60*2;
|
||||
|
||||
/* raw IP6 parameters */
|
||||
/*
|
||||
* Nominal space allocated to a raw ip socket.
|
||||
*/
|
||||
#define RIPV6SNDQ 8192
|
||||
#define RIPV6RCVQ 8192
|
||||
|
||||
u_long rip6_sendspace = RIPV6SNDQ;
|
||||
u_long rip6_recvspace = RIPV6RCVQ;
|
||||
|
||||
/* ICMPV6 parameters */
|
||||
int icmp6_rediraccept = 1; /* accept and process redirects */
|
||||
int icmp6_redirtimeout = 10 * 60; /* 10 minutes */
|
||||
u_int icmp6errratelim = 1000; /* 1000usec = 1msec */
|
||||
|
||||
/* UDP on IP6 parameters */
|
||||
int udp6_sendspace = 9216; /* really max datagram size */
|
||||
int udp6_recvspace = 40 * (1024 + sizeof(struct sockaddr_in6));
|
||||
/* 40 1K datagrams */
|
||||
|
||||
/*
|
||||
* sysctl related items.
|
||||
*/
|
||||
SYSCTL_NODE(_net, PF_INET6, inet6, CTLFLAG_RW, 0,
|
||||
"Internet6 Family");
|
||||
|
||||
/* net.inet6 */
|
||||
SYSCTL_NODE(_net_inet6, IPPROTO_IPV6, ip6, CTLFLAG_RW, 0, "IP6");
|
||||
SYSCTL_NODE(_net_inet6, IPPROTO_ICMPV6, icmp6, CTLFLAG_RW, 0, "ICMP6");
|
||||
SYSCTL_NODE(_net_inet6, IPPROTO_UDP, udp6, CTLFLAG_RW, 0, "UDP6");
|
||||
SYSCTL_NODE(_net_inet6, IPPROTO_TCP, tcp6, CTLFLAG_RW, 0, "TCP6");
|
||||
#ifdef IPSEC
|
||||
SYSCTL_NODE(_net_inet6, IPPROTO_ESP, ipsec6, CTLFLAG_RW, 0, "IPSEC6");
|
||||
#endif /* IPSEC */
|
||||
|
||||
/* net.inet6.ip6 */
|
||||
static int
|
||||
sysctl_ip6_forwarding SYSCTL_HANDLER_ARGS
|
||||
{
|
||||
int error = 0;
|
||||
int old_ip6_forwarding;
|
||||
int changed;
|
||||
|
||||
error = SYSCTL_OUT(req, arg1, sizeof(int));
|
||||
if (error || !req->newptr)
|
||||
return (error);
|
||||
old_ip6_forwarding = ip6_forwarding;
|
||||
error = SYSCTL_IN(req, arg1, sizeof(int));
|
||||
if (error != 0)
|
||||
return (error);
|
||||
changed = (ip6_forwarding ? 1 : 0) ^ (old_ip6_forwarding ? 1 : 0);
|
||||
if (changed == 0)
|
||||
return (error);
|
||||
if (ip6_forwarding != 0) { /* host becomes router */
|
||||
int s = splnet();
|
||||
struct nd_prefix *pr, *next;
|
||||
|
||||
for (pr = nd_prefix.lh_first; pr; pr = next) {
|
||||
next = pr->ndpr_next;
|
||||
if (!IN6_IS_ADDR_UNSPECIFIED(&pr->ndpr_addr))
|
||||
in6_ifdel(pr->ndpr_ifp, &pr->ndpr_addr);
|
||||
prelist_remove(pr);
|
||||
}
|
||||
splx(s);
|
||||
} else { /* router becomes host */
|
||||
struct socket so;
|
||||
|
||||
/* XXX: init dummy so */
|
||||
bzero(&so, sizeof(so));
|
||||
while(!LIST_EMPTY(&rr_prefix))
|
||||
delete_each_prefix(&so, LIST_FIRST(&rr_prefix),
|
||||
PR_ORIG_KERNEL);
|
||||
}
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
SYSCTL_OID(_net_inet6_ip6, IPV6CTL_FORWARDING, forwarding,
|
||||
CTLTYPE_INT|CTLFLAG_RW, &ip6_forwarding, 0, sysctl_ip6_forwarding,
|
||||
"I", "");
|
||||
SYSCTL_INT(_net_inet6_ip6, IPV6CTL_SENDREDIRECTS,
|
||||
redirect, CTLFLAG_RW, &ip6_sendredirects, 0, "");
|
||||
SYSCTL_INT(_net_inet6_ip6, IPV6CTL_DEFHLIM,
|
||||
hlim, CTLFLAG_RW, &ip6_defhlim, 0, "");
|
||||
SYSCTL_INT(_net_inet6_ip6, IPV6CTL_MAXFRAGPACKETS,
|
||||
maxfragpackets, CTLFLAG_RW, &ip6_maxfragpackets, 0, "");
|
||||
SYSCTL_INT(_net_inet6_ip6, IPV6CTL_ACCEPT_RTADV,
|
||||
accept_rtadv, CTLFLAG_RW, &ip6_accept_rtadv, 0, "");
|
||||
SYSCTL_INT(_net_inet6_ip6, IPV6CTL_KEEPFAITH,
|
||||
keepfaith, CTLFLAG_RW, &ip6_keepfaith, 0, "");
|
||||
SYSCTL_INT(_net_inet6_ip6, IPV6CTL_LOG_INTERVAL,
|
||||
log_interval, CTLFLAG_RW, &ip6_log_interval, 0, "");
|
||||
SYSCTL_INT(_net_inet6_ip6, IPV6CTL_HDRNESTLIMIT,
|
||||
hdrnestlimit, CTLFLAG_RW, &ip6_hdrnestlimit, 0, "");
|
||||
SYSCTL_INT(_net_inet6_ip6, IPV6CTL_DAD_COUNT,
|
||||
dad_count, CTLFLAG_RW, &ip6_dad_count, 0, "");
|
||||
SYSCTL_INT(_net_inet6_ip6, IPV6CTL_AUTO_FLOWLABEL,
|
||||
auto_flowlabel, CTLFLAG_RW, &ip6_auto_flowlabel, 0, "");
|
||||
SYSCTL_INT(_net_inet6_ip6, IPV6CTL_DEFMCASTHLIM,
|
||||
defmcasthlim, CTLFLAG_RW, &ip6_defmcasthlim, 0, "");
|
||||
SYSCTL_INT(_net_inet6_ip6, IPV6CTL_GIF_HLIM,
|
||||
gifhlim, CTLFLAG_RW, &ip6_gif_hlim, 0, "");
|
||||
SYSCTL_INT(_net_inet6_ip6, IPV6CTL_USE_DEPRECATED,
|
||||
use_deprecated, CTLFLAG_RW, &ip6_use_deprecated, 0, "");
|
||||
SYSCTL_INT(_net_inet6_ip6, IPV6CTL_RR_PRUNE,
|
||||
rr_prune, CTLFLAG_RW, &ip6_rr_prune, 0, "");
|
||||
SYSCTL_INT(_net_inet6_ip6, IPV6CTL_MAPPED_ADDR,
|
||||
mapped_addr, CTLFLAG_RW, &ip6_mapped_addr_on, 0, "");
|
||||
|
||||
/* net.inet6.icmp6 */
|
||||
SYSCTL_INT(_net_inet6_icmp6, ICMPV6CTL_REDIRACCEPT,
|
||||
rediraccept, CTLFLAG_RW, &icmp6_rediraccept, 0, "");
|
||||
SYSCTL_INT(_net_inet6_icmp6, ICMPV6CTL_REDIRTIMEOUT,
|
||||
redirtimeout, CTLFLAG_RW, &icmp6_redirtimeout, 0, "");
|
||||
SYSCTL_STRUCT(_net_inet6_icmp6, ICMPV6CTL_STATS, stats, CTLFLAG_RD,
|
||||
&icmp6stat, icmp6stat, "");
|
||||
SYSCTL_INT(_net_inet6_icmp6, ICMPV6CTL_ERRRATELIMIT,
|
||||
errratelimit, CTLFLAG_RW, &icmp6errratelim, 0, "");
|
||||
SYSCTL_INT(_net_inet6_icmp6, ICMPV6CTL_ND6_PRUNE,
|
||||
nd6_prune, CTLFLAG_RW, &nd6_prune, 0, "");
|
||||
SYSCTL_INT(_net_inet6_icmp6, ICMPV6CTL_ND6_DELAY,
|
||||
nd6_delay, CTLFLAG_RW, &nd6_delay, 0, "");
|
||||
SYSCTL_INT(_net_inet6_icmp6, ICMPV6CTL_ND6_UMAXTRIES,
|
||||
nd6_umaxtries, CTLFLAG_RW, &nd6_umaxtries, 0, "");
|
||||
SYSCTL_INT(_net_inet6_icmp6, ICMPV6CTL_ND6_MMAXTRIES,
|
||||
nd6_mmaxtries, CTLFLAG_RW, &nd6_mmaxtries, 0, "");
|
||||
SYSCTL_INT(_net_inet6_icmp6, ICMPV6CTL_ND6_USELOOPBACK,
|
||||
nd6_useloopback, CTLFLAG_RW, &nd6_useloopback, 0, "");
|
||||
SYSCTL_INT(_net_inet6_icmp6, ICMPV6CTL_ND6_PROXYALL,
|
||||
nd6_proxyall, CTLFLAG_RW, &nd6_proxyall, 0, "");
|
||||
477
sys/netinet6/in6_rmx.c
Normal file
477
sys/netinet6/in6_rmx.c
Normal file
|
|
@ -0,0 +1,477 @@
|
|||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright 1994, 1995 Massachusetts Institute of Technology
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software and
|
||||
* its documentation for any purpose and without fee is hereby
|
||||
* granted, provided that both the above copyright notice and this
|
||||
* permission notice appear in all copies, that both the above
|
||||
* copyright notice and this permission notice appear in all
|
||||
* supporting documentation, and that the name of M.I.T. not be used
|
||||
* in advertising or publicity pertaining to distribution of the
|
||||
* software without specific, written prior permission. M.I.T. makes
|
||||
* no representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied
|
||||
* warranty.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS
|
||||
* ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
|
||||
* SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: in6_rmx.c,v 1.3 1999/08/16 13:42:53 itojun Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
* This code does two things necessary for the enhanced TCP metrics to
|
||||
* function in a useful manner:
|
||||
* 1) It marks all non-host routes as `cloning', thus ensuring that
|
||||
* every actual reference to such a route actually gets turned
|
||||
* into a reference to a host route to the specific destination
|
||||
* requested.
|
||||
* 2) When such routes lose all their references, it arranges for them
|
||||
* to be deleted in some random collection of circumstances, so that
|
||||
* a large quantity of stale routing data is not kept in kernel memory
|
||||
* indefinitely. See in6_rtqtimo() below for the exact mechanism.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/socketvar.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/syslog.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/route.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/ip_var.h>
|
||||
#include <netinet/in_var.h>
|
||||
|
||||
#include <netinet6/ip6.h>
|
||||
#include <netinet6/ip6_var.h>
|
||||
|
||||
#include <netinet6/icmp6.h>
|
||||
|
||||
#include <netinet/tcp.h>
|
||||
#include <netinet/tcp_seq.h>
|
||||
#include <netinet/tcp_timer.h>
|
||||
#include <netinet/tcp_var.h>
|
||||
|
||||
extern int in6_inithead __P((void **head, int off));
|
||||
|
||||
#define RTPRF_OURS RTF_PROTO3 /* set on routes we manage */
|
||||
|
||||
/*
|
||||
* Do what we need to do when inserting a route.
|
||||
*/
|
||||
static struct radix_node *
|
||||
in6_addroute(void *v_arg, void *n_arg, struct radix_node_head *head,
|
||||
struct radix_node *treenodes)
|
||||
{
|
||||
struct rtentry *rt = (struct rtentry *)treenodes;
|
||||
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)rt_key(rt);
|
||||
struct radix_node *ret;
|
||||
|
||||
/*
|
||||
* For IPv6, all unicast non-host routes are automatically cloning.
|
||||
*/
|
||||
if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr))
|
||||
rt->rt_flags |= RTF_MULTICAST;
|
||||
|
||||
if (!(rt->rt_flags & (RTF_HOST | RTF_CLONING | RTF_MULTICAST))) {
|
||||
rt->rt_flags |= RTF_PRCLONING;
|
||||
}
|
||||
|
||||
/*
|
||||
* A little bit of help for both IPv6 output and input:
|
||||
* For local addresses, we make sure that RTF_LOCAL is set,
|
||||
* with the thought that this might one day be used to speed up
|
||||
* ip_input().
|
||||
*
|
||||
* We also mark routes to multicast addresses as such, because
|
||||
* it's easy to do and might be useful (but this is much more
|
||||
* dubious since it's so easy to inspect the address). (This
|
||||
* is done above.)
|
||||
*
|
||||
* XXX
|
||||
* should elaborate the code.
|
||||
*/
|
||||
if (rt->rt_flags & RTF_HOST) {
|
||||
if (IN6_ARE_ADDR_EQUAL(&satosin6(rt->rt_ifa->ifa_addr)
|
||||
->sin6_addr,
|
||||
&sin6->sin6_addr)) {
|
||||
rt->rt_flags |= RTF_LOCAL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We also specify a send and receive pipe size for every
|
||||
* route added, to help TCP a bit. TCP doesn't actually
|
||||
* want a true pipe size, which would be prohibitive in memory
|
||||
* costs and is hard to compute anyway; it simply uses these
|
||||
* values to size its buffers. So, we fill them in with the
|
||||
* same values that TCP would have used anyway, and allow the
|
||||
* installing program or the link layer to override these values
|
||||
* as it sees fit. This will hopefully allow TCP more
|
||||
* opportunities to save its ssthresh value.
|
||||
*/
|
||||
if (!rt->rt_rmx.rmx_sendpipe && !(rt->rt_rmx.rmx_locks & RTV_SPIPE))
|
||||
rt->rt_rmx.rmx_sendpipe = tcp_sendspace;
|
||||
|
||||
if (!rt->rt_rmx.rmx_recvpipe && !(rt->rt_rmx.rmx_locks & RTV_RPIPE))
|
||||
rt->rt_rmx.rmx_recvpipe = tcp_recvspace;
|
||||
|
||||
if (!rt->rt_rmx.rmx_mtu && !(rt->rt_rmx.rmx_locks & RTV_MTU)
|
||||
&& rt->rt_ifp)
|
||||
rt->rt_rmx.rmx_mtu = rt->rt_ifp->if_mtu;
|
||||
|
||||
ret = rn_addroute(v_arg, n_arg, head, treenodes);
|
||||
if (ret == NULL && rt->rt_flags & RTF_HOST) {
|
||||
struct rtentry *rt2;
|
||||
/*
|
||||
* We are trying to add a host route, but can't.
|
||||
* Find out if it is because of an
|
||||
* ARP entry and delete it if so.
|
||||
*/
|
||||
rt2 = rtalloc1((struct sockaddr *)sin6, 0,
|
||||
RTF_CLONING | RTF_PRCLONING);
|
||||
if (rt2) {
|
||||
if (rt2->rt_flags & RTF_LLINFO &&
|
||||
rt2->rt_flags & RTF_HOST &&
|
||||
rt2->rt_gateway &&
|
||||
rt2->rt_gateway->sa_family == AF_LINK) {
|
||||
rtrequest(RTM_DELETE,
|
||||
(struct sockaddr *)rt_key(rt2),
|
||||
rt2->rt_gateway,
|
||||
rt_mask(rt2), rt2->rt_flags, 0);
|
||||
ret = rn_addroute(v_arg, n_arg, head,
|
||||
treenodes);
|
||||
}
|
||||
RTFREE(rt2);
|
||||
}
|
||||
} else if (ret == NULL && rt->rt_flags & RTF_CLONING) {
|
||||
struct rtentry *rt2;
|
||||
/*
|
||||
* We are trying to add a net route, but can't.
|
||||
* The following case should be allowed, so we'll make a
|
||||
* special check for this:
|
||||
* Two IPv6 addresses with the same prefix is assigned
|
||||
* to a single interrface.
|
||||
* # ifconfig if0 inet6 3ffe:0501::1 prefix 64 alias (*1)
|
||||
* # ifconfig if0 inet6 3ffe:0501::2 prefix 64 alias (*2)
|
||||
* In this case, (*1) and (*2) want to add the same
|
||||
* net route entry, 3ffe:0501:: -> if0.
|
||||
* This case should not raise an error.
|
||||
*/
|
||||
rt2 = rtalloc1((struct sockaddr *)sin6, 0,
|
||||
RTF_CLONING | RTF_PRCLONING);
|
||||
if (rt2) {
|
||||
if ((rt2->rt_flags & (RTF_CLONING|RTF_HOST|RTF_GATEWAY))
|
||||
== RTF_CLONING
|
||||
&& rt2->rt_gateway
|
||||
&& rt2->rt_gateway->sa_family == AF_LINK
|
||||
&& rt2->rt_ifp == rt->rt_ifp) {
|
||||
ret = rt2->rt_nodes;
|
||||
}
|
||||
RTFREE(rt2);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* This code is the inverse of in6_clsroute: on first reference, if we
|
||||
* were managing the route, stop doing so and set the expiration timer
|
||||
* back off again.
|
||||
*/
|
||||
static struct radix_node *
|
||||
in6_matroute(void *v_arg, struct radix_node_head *head)
|
||||
{
|
||||
struct radix_node *rn = rn_match(v_arg, head);
|
||||
struct rtentry *rt = (struct rtentry *)rn;
|
||||
|
||||
if (rt && rt->rt_refcnt == 0) { /* this is first reference */
|
||||
if (rt->rt_flags & RTPRF_OURS) {
|
||||
rt->rt_flags &= ~RTPRF_OURS;
|
||||
rt->rt_rmx.rmx_expire = 0;
|
||||
}
|
||||
}
|
||||
return rn;
|
||||
}
|
||||
|
||||
static int rtq_reallyold = 60*60;
|
||||
/* one hour is ``really old'' */
|
||||
SYSCTL_INT(_net_inet_ip, IPCTL_RTEXPIRE, rtexpire,
|
||||
CTLFLAG_RW, &rtq_reallyold , 0, "");
|
||||
|
||||
static int rtq_minreallyold = 10;
|
||||
/* never automatically crank down to less */
|
||||
SYSCTL_INT(_net_inet_ip, IPCTL_RTMINEXPIRE, rtminexpire,
|
||||
CTLFLAG_RW, &rtq_minreallyold , 0, "");
|
||||
|
||||
static int rtq_toomany = 128;
|
||||
/* 128 cached routes is ``too many'' */
|
||||
SYSCTL_INT(_net_inet_ip, IPCTL_RTMAXCACHE, rtmaxcache,
|
||||
CTLFLAG_RW, &rtq_toomany , 0, "");
|
||||
|
||||
|
||||
/*
|
||||
* On last reference drop, mark the route as belong to us so that it can be
|
||||
* timed out.
|
||||
*/
|
||||
static void
|
||||
in6_clsroute(struct radix_node *rn, struct radix_node_head *head)
|
||||
{
|
||||
struct rtentry *rt = (struct rtentry *)rn;
|
||||
|
||||
if (!(rt->rt_flags & RTF_UP))
|
||||
return; /* prophylactic measures */
|
||||
|
||||
if ((rt->rt_flags & (RTF_LLINFO | RTF_HOST)) != RTF_HOST)
|
||||
return;
|
||||
|
||||
if ((rt->rt_flags & (RTF_WASCLONED | RTPRF_OURS))
|
||||
!= RTF_WASCLONED)
|
||||
return;
|
||||
|
||||
/*
|
||||
* As requested by David Greenman:
|
||||
* If rtq_reallyold is 0, just delete the route without
|
||||
* waiting for a timeout cycle to kill it.
|
||||
*/
|
||||
if (rtq_reallyold != 0) {
|
||||
rt->rt_flags |= RTPRF_OURS;
|
||||
rt->rt_rmx.rmx_expire = time_second + rtq_reallyold;
|
||||
} else {
|
||||
rtrequest(RTM_DELETE,
|
||||
(struct sockaddr *)rt_key(rt),
|
||||
rt->rt_gateway, rt_mask(rt),
|
||||
rt->rt_flags, 0);
|
||||
}
|
||||
}
|
||||
|
||||
struct rtqk_arg {
|
||||
struct radix_node_head *rnh;
|
||||
int mode;
|
||||
int updating;
|
||||
int draining;
|
||||
int killed;
|
||||
int found;
|
||||
time_t nextstop;
|
||||
};
|
||||
|
||||
/*
|
||||
* Get rid of old routes. When draining, this deletes everything, even when
|
||||
* the timeout is not expired yet. When updating, this makes sure that
|
||||
* nothing has a timeout longer than the current value of rtq_reallyold.
|
||||
*/
|
||||
static int
|
||||
in6_rtqkill(struct radix_node *rn, void *rock)
|
||||
{
|
||||
struct rtqk_arg *ap = rock;
|
||||
struct rtentry *rt = (struct rtentry *)rn;
|
||||
int err;
|
||||
|
||||
if (rt->rt_flags & RTPRF_OURS) {
|
||||
ap->found++;
|
||||
|
||||
if (ap->draining || rt->rt_rmx.rmx_expire <= time_second) {
|
||||
if (rt->rt_refcnt > 0)
|
||||
panic("rtqkill route really not free");
|
||||
|
||||
err = rtrequest(RTM_DELETE,
|
||||
(struct sockaddr *)rt_key(rt),
|
||||
rt->rt_gateway, rt_mask(rt),
|
||||
rt->rt_flags, 0);
|
||||
if (err) {
|
||||
log(LOG_WARNING, "in6_rtqkill: error %d", err);
|
||||
} else {
|
||||
ap->killed++;
|
||||
}
|
||||
} else {
|
||||
if (ap->updating
|
||||
&& (rt->rt_rmx.rmx_expire - time_second
|
||||
> rtq_reallyold)) {
|
||||
rt->rt_rmx.rmx_expire = time_second
|
||||
+ rtq_reallyold;
|
||||
}
|
||||
ap->nextstop = lmin(ap->nextstop,
|
||||
rt->rt_rmx.rmx_expire);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define RTQ_TIMEOUT 60*10 /* run no less than once every ten minutes */
|
||||
static int rtq_timeout = RTQ_TIMEOUT;
|
||||
|
||||
static void
|
||||
in6_rtqtimo(void *rock)
|
||||
{
|
||||
struct radix_node_head *rnh = rock;
|
||||
struct rtqk_arg arg;
|
||||
struct timeval atv;
|
||||
static time_t last_adjusted_timeout = 0;
|
||||
int s;
|
||||
|
||||
arg.found = arg.killed = 0;
|
||||
arg.rnh = rnh;
|
||||
arg.nextstop = time_second + rtq_timeout;
|
||||
arg.draining = arg.updating = 0;
|
||||
s = splnet();
|
||||
rnh->rnh_walktree(rnh, in6_rtqkill, &arg);
|
||||
splx(s);
|
||||
|
||||
/*
|
||||
* Attempt to be somewhat dynamic about this:
|
||||
* If there are ``too many'' routes sitting around taking up space,
|
||||
* then crank down the timeout, and see if we can't make some more
|
||||
* go away. However, we make sure that we will never adjust more
|
||||
* than once in rtq_timeout seconds, to keep from cranking down too
|
||||
* hard.
|
||||
*/
|
||||
if ((arg.found - arg.killed > rtq_toomany)
|
||||
&& (time_second - last_adjusted_timeout >= rtq_timeout)
|
||||
&& rtq_reallyold > rtq_minreallyold) {
|
||||
rtq_reallyold = 2*rtq_reallyold / 3;
|
||||
if (rtq_reallyold < rtq_minreallyold) {
|
||||
rtq_reallyold = rtq_minreallyold;
|
||||
}
|
||||
|
||||
last_adjusted_timeout = time_second;
|
||||
#ifdef DIAGNOSTIC
|
||||
log(LOG_DEBUG, "in6_rtqtimo: adjusted rtq_reallyold to %d",
|
||||
rtq_reallyold);
|
||||
#endif
|
||||
arg.found = arg.killed = 0;
|
||||
arg.updating = 1;
|
||||
s = splnet();
|
||||
rnh->rnh_walktree(rnh, in6_rtqkill, &arg);
|
||||
splx(s);
|
||||
}
|
||||
|
||||
atv.tv_usec = 0;
|
||||
atv.tv_sec = arg.nextstop;
|
||||
timeout(in6_rtqtimo, rock, tvtohz(&atv));
|
||||
}
|
||||
|
||||
/*
|
||||
* Age old PMTUs.
|
||||
*/
|
||||
struct mtuex_arg {
|
||||
struct radix_node_head *rnh;
|
||||
time_t nextstop;
|
||||
};
|
||||
|
||||
static int
|
||||
in6_mtuexpire(struct radix_node *rn, void *rock)
|
||||
{
|
||||
struct rtentry *rt = (struct rtentry *)rn;
|
||||
struct mtuex_arg *ap = rock;
|
||||
|
||||
/* sanity */
|
||||
if (!rt)
|
||||
panic("rt == NULL in in6_mtuexpire");
|
||||
|
||||
if (rt->rt_rmx.rmx_expire && !(rt->rt_flags & RTF_PROBEMTU)) {
|
||||
if (rt->rt_rmx.rmx_expire <= time_second) {
|
||||
rt->rt_flags |= RTF_PROBEMTU;
|
||||
} else {
|
||||
ap->nextstop = lmin(ap->nextstop,
|
||||
rt->rt_rmx.rmx_expire);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define MTUTIMO_DEFAULT (60*1)
|
||||
|
||||
static void
|
||||
in6_mtutimo(void *rock)
|
||||
{
|
||||
struct radix_node_head *rnh = rock;
|
||||
struct mtuex_arg arg;
|
||||
struct timeval atv;
|
||||
int s;
|
||||
|
||||
arg.rnh = rnh;
|
||||
arg.nextstop = time_second + MTUTIMO_DEFAULT;
|
||||
s = splnet();
|
||||
rnh->rnh_walktree(rnh, in6_mtuexpire, &arg);
|
||||
splx(s);
|
||||
|
||||
atv.tv_usec = 0;
|
||||
atv.tv_sec = arg.nextstop;
|
||||
if (atv.tv_sec < time_second) {
|
||||
printf("invalid mtu expiration time on routing table\n");
|
||||
arg.nextstop = time_second + 30; /*last resort*/
|
||||
}
|
||||
timeout(in6_mtutimo, rock, tvtohz(&atv));
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize our routing tree.
|
||||
*/
|
||||
int
|
||||
in6_inithead(void **head, int off)
|
||||
{
|
||||
struct radix_node_head *rnh;
|
||||
|
||||
if (!rn_inithead(head, off))
|
||||
return 0;
|
||||
|
||||
if (head != (void **)&rt_tables[AF_INET6]) /* BOGUS! */
|
||||
return 1; /* only do this for the real routing table */
|
||||
|
||||
rnh = *head;
|
||||
rnh->rnh_addaddr = in6_addroute;
|
||||
rnh->rnh_matchaddr = in6_matroute;
|
||||
rnh->rnh_close = in6_clsroute;
|
||||
in6_rtqtimo(rnh); /* kick off timeout first time */
|
||||
in6_mtutimo(rnh); /* kick off timeout first time */
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* 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:
|
||||
|
|
@ -13,7 +13,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
|
||||
|
|
@ -98,10 +98,6 @@ struct in6_ifaddr {
|
|||
struct sockaddr_in6 ia_prefixmask; /* prefix mask */
|
||||
u_int32_t ia_plen; /* prefix length */
|
||||
struct in6_ifaddr *ia_next; /* next in6 list of IP6 addresses */
|
||||
#if !(defined(__FreeBSD__) && __FreeBSD__ >= 3)
|
||||
LIST_HEAD(in6_multihead, in6_multi) ia6_multiaddrs;
|
||||
/* list of multicast addresses */
|
||||
#endif
|
||||
int ia6_flags;
|
||||
|
||||
struct in6_addrlifetime ia6_lifetime; /* NULL = infty */
|
||||
|
|
@ -189,7 +185,7 @@ struct icmp6_ifstat {
|
|||
u_int64_t ifs6_in_mlddone;
|
||||
|
||||
/*
|
||||
* Output statistics. We should solve unresolved routing problem...
|
||||
* Output statistics. We should solve unresolved routing problem...
|
||||
*/
|
||||
/* ipv6IfIcmpOutMsgs, total # of output messages */
|
||||
u_int64_t ifs6_out_msg;
|
||||
|
|
@ -428,34 +424,14 @@ extern struct ifqueue ip6intrq; /* IP6 packet input queue */
|
|||
extern struct in6_addr zeroin6_addr;
|
||||
extern u_char inet6ctlerrmap[];
|
||||
extern u_long in6_maxmtu;
|
||||
#if defined(__FreeBSD__) && __FreeBSD__ >= 3
|
||||
#ifdef MALLOC_DECLARE
|
||||
MALLOC_DECLARE(M_IPMADDR);
|
||||
#endif /* MALLOC_DECLARE */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Macro for finding the internet address structure (in6_ifaddr) corresponding
|
||||
* to a given interface (ifnet structure).
|
||||
*/
|
||||
#if defined(__bsdi__) || (defined(__FreeBSD__) && __FreeBSD__ < 3)
|
||||
|
||||
#define IFP_TO_IA6(ifp, ia) \
|
||||
/* struct ifnet *ifp; */ \
|
||||
/* struct in6_ifaddr *ia; */ \
|
||||
do { \
|
||||
struct ifaddr *ifa; \
|
||||
for (ifa = (ifp)->if_addrlist; ifa; ifa = ifa->ifa_next) { \
|
||||
if (!ifa->ifa_addr) \
|
||||
continue; \
|
||||
if (ifa->ifa_addr->sa_family == AF_INET6) \
|
||||
break; \
|
||||
} \
|
||||
(ia) = (struct in6_ifaddr *)ifa; \
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
|
||||
#define IFP_TO_IA6(ifp, ia) \
|
||||
/* struct ifnet *ifp; */ \
|
||||
/* struct in6_ifaddr *ia; */ \
|
||||
|
|
@ -471,8 +447,6 @@ do { \
|
|||
} while (0)
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Multi-cast membership entry. One for each group/ifp that a PCB
|
||||
* belongs to.
|
||||
|
|
@ -486,20 +460,14 @@ struct in6_multi {
|
|||
LIST_ENTRY(in6_multi) in6m_entry; /* list glue */
|
||||
struct in6_addr in6m_addr; /* IP6 multicast address */
|
||||
struct ifnet *in6m_ifp; /* back pointer to ifnet */
|
||||
#if !(defined(__FreeBSD__) && __FreeBSD__ >= 3)
|
||||
struct in6_ifaddr *in6m_ia; /* back pointer to in6_ifaddr */
|
||||
#else
|
||||
struct ifmultiaddr *in6m_ifma; /* back pointer to ifmultiaddr */
|
||||
#endif
|
||||
u_int in6m_refcount; /* # membership claims by sockets */
|
||||
u_int in6m_state; /* state of the membership */
|
||||
u_int in6m_timer; /* MLD6 listener report timer */
|
||||
};
|
||||
|
||||
#ifdef _KERNEL
|
||||
#if defined(__FreeBSD__) && __FreeBSD__ >= 3
|
||||
extern LIST_HEAD(in6_multihead, in6_multi) in6_multihead;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Structure used by macros below to remember position when stepping through
|
||||
|
|
@ -516,8 +484,6 @@ struct in6_multistep {
|
|||
* returns NLL.
|
||||
*/
|
||||
|
||||
#if defined(__FreeBSD__) && __FreeBSD__ >= 3
|
||||
|
||||
#define IN6_LOOKUP_MULTI(addr, ifp, in6m) \
|
||||
/* struct in6_addr addr; */ \
|
||||
/* struct ifnet *ifp; */ \
|
||||
|
|
@ -557,61 +523,6 @@ do { \
|
|||
IN6_NEXT_MULTI((step), (in6m)); \
|
||||
} while(0)
|
||||
|
||||
#else /* not FreeBSD3 */
|
||||
|
||||
#define IN6_LOOKUP_MULTI(addr, ifp, in6m) \
|
||||
/* struct in6_addr addr; */ \
|
||||
/* struct ifnet *ifp; */ \
|
||||
/* struct in6_multi *in6m; */ \
|
||||
do { \
|
||||
register struct in6_ifaddr *ia; \
|
||||
\
|
||||
IFP_TO_IA6((ifp), ia); \
|
||||
if (ia == NULL) \
|
||||
(in6m) = NULL; \
|
||||
else \
|
||||
for ((in6m) = ia->ia6_multiaddrs.lh_first; \
|
||||
(in6m) != NULL && \
|
||||
!IN6_ARE_ADDR_EQUAL(&(in6m)->in6m_addr, &(addr)); \
|
||||
(in6m) = in6m->in6m_entry.le_next) \
|
||||
continue; \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Macro to step through all of the in6_multi records, one at a time.
|
||||
* The current position is remembered in "step", which the caller must
|
||||
* provide. IN6_FIRST_MULTI(), below, must be called to initialize "step"
|
||||
* and get the first record. Both macros return a NULL "in6m" when there
|
||||
* are no remaining records.
|
||||
*/
|
||||
#define IN6_NEXT_MULTI(step, in6m) \
|
||||
/* struct in6_multistep step; */ \
|
||||
/* struct in6_multi *in6m; */ \
|
||||
do { \
|
||||
if (((in6m) = (step).i_in6m) != NULL) \
|
||||
(step).i_in6m = (in6m)->in6m_entry.le_next; \
|
||||
else \
|
||||
while ((step).i_ia != NULL) { \
|
||||
(in6m) = (step).i_ia->ia6_multiaddrs.lh_first; \
|
||||
(step).i_ia = (step).i_ia->ia_next; \
|
||||
if ((in6m) != NULL) { \
|
||||
(step).i_in6m = (in6m)->in6m_entry.le_next; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define IN6_FIRST_MULTI(step, in6m) \
|
||||
/* struct in6_multistep step; */ \
|
||||
/* struct in6_multi *in6m */ \
|
||||
do { \
|
||||
(step).i_ia = in6_ifaddr; \
|
||||
(step).i_in6m = NULL; \
|
||||
IN6_NEXT_MULTI((step), (in6m)); \
|
||||
} while (0)
|
||||
|
||||
#endif /* not FreeBSD3 */
|
||||
|
||||
int in6_ifinit __P((struct ifnet *,
|
||||
struct in6_ifaddr *, struct sockaddr_in6 *, int));
|
||||
struct in6_multi *in6_addmulti __P((struct in6_addr *, struct ifnet *,
|
||||
|
|
@ -621,12 +532,8 @@ void in6_ifscrub __P((struct ifnet *, struct in6_ifaddr *));
|
|||
extern int in6_ifindex2scopeid __P((int));
|
||||
extern int in6_mask2len __P((struct in6_addr *));
|
||||
extern void in6_len2mask __P((struct in6_addr *, int));
|
||||
#if !defined(__bsdi__) && !(defined(__FreeBSD__) && __FreeBSD__ < 3)
|
||||
int in6_control __P((struct socket *,
|
||||
u_long, caddr_t, struct ifnet *, struct proc *));
|
||||
#else
|
||||
int in6_control __P((struct socket *, u_long, caddr_t, struct ifnet *));
|
||||
#endif
|
||||
u_long, caddr_t, struct ifnet *, struct proc *));
|
||||
void in6_savemkludge __P((struct in6_ifaddr *));
|
||||
void in6_setmaxmtu __P((void));
|
||||
void in6_restoremkludge __P((struct in6_ifaddr *, struct ifnet *));
|
||||
|
|
|
|||
245
sys/netinet6/ip6.h
Normal file
245
sys/netinet6/ip6.h
Normal file
|
|
@ -0,0 +1,245 @@
|
|||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1982, 1986, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)ip.h 8.1 (Berkeley) 6/10/93
|
||||
*/
|
||||
|
||||
#ifndef _NETINET6_IPV6_H_
|
||||
#define _NETINET6_IPV6_H_
|
||||
|
||||
/*
|
||||
* Definition for internet protocol version 6.
|
||||
* RFC 2460
|
||||
*/
|
||||
|
||||
struct ip6_hdr {
|
||||
union {
|
||||
struct ip6_hdrctl {
|
||||
u_int32_t ip6_un1_flow; /* 20 bits of flow-ID */
|
||||
u_int16_t ip6_un1_plen; /* payload length */
|
||||
u_int8_t ip6_un1_nxt; /* next header */
|
||||
u_int8_t ip6_un1_hlim; /* hop limit */
|
||||
} ip6_un1;
|
||||
u_int8_t ip6_un2_vfc; /* 4 bits version, 4 bits class */
|
||||
} ip6_ctlun;
|
||||
struct in6_addr ip6_src; /* source address */
|
||||
struct in6_addr ip6_dst; /* destination address */
|
||||
};
|
||||
|
||||
#define ip6_vfc ip6_ctlun.ip6_un2_vfc
|
||||
#define ip6_flow ip6_ctlun.ip6_un1.ip6_un1_flow
|
||||
#define ip6_plen ip6_ctlun.ip6_un1.ip6_un1_plen
|
||||
#define ip6_nxt ip6_ctlun.ip6_un1.ip6_un1_nxt
|
||||
#define ip6_hlim ip6_ctlun.ip6_un1.ip6_un1_hlim
|
||||
#define ip6_hops ip6_ctlun.ip6_un1.ip6_un1_hlim
|
||||
|
||||
#define IPV6_VERSION 0x60
|
||||
#define IPV6_VERSION_MASK 0xf0
|
||||
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
#define IPV6_FLOWINFO_MASK 0x0fffffff /* flow info (28 bits) */
|
||||
#define IPV6_FLOWLABEL_MASK 0x000fffff /* flow label (20 bits) */
|
||||
#endif /* BIG_ENDIAN */
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
#define IPV6_FLOWINFO_MASK 0xffffff0f /* flow info (28 bits) */
|
||||
#define IPV6_FLOWLABEL_MASK 0xffff0f00 /* flow label (20 bits) */
|
||||
#endif /* LITTLE_ENDIAN */
|
||||
/* ECN bits proposed by Sally Floyd */
|
||||
#define IP6TOS_CE 0x01 /* congestion experienced */
|
||||
#define IP6TOS_ECT 0x02 /* ECN-capable transport */
|
||||
|
||||
/*
|
||||
* Extension Headers
|
||||
*/
|
||||
|
||||
struct ip6_ext {
|
||||
u_char ip6e_nxt;
|
||||
u_char ip6e_len;
|
||||
};
|
||||
|
||||
/* Hop-by-Hop options header */
|
||||
/* XXX should we pad it to force alignment on an 8-byte boundary? */
|
||||
struct ip6_hbh {
|
||||
u_int8_t ip6h_nxt; /* next header */
|
||||
u_int8_t ip6h_len; /* length in units of 8 octets */
|
||||
/* followed by options */
|
||||
};
|
||||
|
||||
/* Destination options header */
|
||||
/* XXX should we pad it to force alignment on an 8-byte boundary? */
|
||||
struct ip6_dest {
|
||||
u_int8_t ip6d_nxt; /* next header */
|
||||
u_int8_t ip6d_len; /* length in units of 8 octets */
|
||||
/* followed by options */
|
||||
};
|
||||
|
||||
/* 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_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_TYPE(o) ((o) & 0xC0)
|
||||
#define IP6OPT_TYPE_SKIP 0x00
|
||||
#define IP6OPT_TYPE_DISCARD 0x40
|
||||
#define IP6OPT_TYPE_FORCEICMP 0x80
|
||||
#define IP6OPT_TYPE_ICMP 0xC0
|
||||
|
||||
#define IP6OPT_MUTABLE 0x20
|
||||
|
||||
/* Routing header */
|
||||
struct ip6_rthdr {
|
||||
u_int8_t ip6r_nxt; /* next header */
|
||||
u_int8_t ip6r_len; /* length in units of 8 octets */
|
||||
u_int8_t ip6r_type; /* routing type */
|
||||
u_int8_t ip6r_segleft; /* segments left */
|
||||
/* followed by routing type specific data */
|
||||
};
|
||||
|
||||
/* Type 0 Routing header */
|
||||
struct ip6_rthdr0 {
|
||||
u_int8_t ip6r0_nxt; /* next header */
|
||||
u_int8_t ip6r0_len; /* length in units of 8 octets */
|
||||
u_int8_t ip6r0_type; /* always zero */
|
||||
u_int8_t ip6r0_segleft; /* segments left */
|
||||
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 */
|
||||
};
|
||||
|
||||
/* Fragment header */
|
||||
struct ip6_frag {
|
||||
u_int8_t ip6f_nxt; /* next header */
|
||||
u_int8_t ip6f_reserved; /* reserved field */
|
||||
u_int16_t ip6f_offlg; /* offset, reserved, and flag */
|
||||
u_int32_t ip6f_ident; /* identification */
|
||||
};
|
||||
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
#define IP6F_OFF_MASK 0xfff8 /* mask out offset from _offlg */
|
||||
#define IP6F_RESERVED_MASK 0x0006 /* reserved bits in ip6f_offlg */
|
||||
#define IP6F_MORE_FRAG 0x0001 /* more-fragments flag */
|
||||
#else /* BYTE_ORDER == LITTLE_ENDIAN */
|
||||
#define IP6F_OFF_MASK 0xf8ff /* mask out offset from _offlg */
|
||||
#define IP6F_RESERVED_MASK 0x0600 /* reserved bits in ip6f_offlg */
|
||||
#define IP6F_MORE_FRAG 0x0100 /* more-fragments flag */
|
||||
#endif /* BYTE_ORDER == LITTLE_ENDIAN */
|
||||
|
||||
/*
|
||||
* Internet implementation parameters.
|
||||
*/
|
||||
#define IPV6_MAXHLIM 255 /* maximun hoplimit */
|
||||
#define IPV6_DEFHLIM 64 /* default hlim */
|
||||
#define IPV6_FRAGTTL 120 /* ttl for fragment packets, in slowtimo tick */
|
||||
#define IPV6_HLIMDEC 1 /* subtracted when forwaeding */
|
||||
|
||||
#define IPV6_MMTU 1280 /* minimal MTU and reassembly. 1024 + 256 */
|
||||
#define IPV6_MAXPACKET 65535 /* ip6 max packet size without Jumbo payload*/
|
||||
|
||||
/*
|
||||
* IP6_EXTHDR_CHECK ensures that region between the IP6 header and the
|
||||
* target header (including IPv6 itself, extension headers and
|
||||
* TCP/UDP/ICMP6 headers) are continuous. KAME requires drivers
|
||||
* to store incoming data into one internal mbuf or one or more external
|
||||
* mbufs(never into two or more internal mbufs). Thus, the third case is
|
||||
* supposed to never be matched but is prepared just in case.
|
||||
*/
|
||||
|
||||
#define IP6_EXTHDR_CHECK(m, off, hlen, ret) \
|
||||
do { \
|
||||
if ((m)->m_next != NULL) { \
|
||||
if (((m)->m_flags & M_LOOP) && \
|
||||
((m)->m_len < (off) + (hlen)) && \
|
||||
(((m) = m_pullup((m), (off) + (hlen))) == NULL)) { \
|
||||
ip6stat.ip6s_exthdrtoolong++; \
|
||||
return ret; \
|
||||
} else if ((m)->m_flags & M_EXT) { \
|
||||
if ((m)->m_len < (off) + (hlen)) { \
|
||||
ip6stat.ip6s_exthdrtoolong++; \
|
||||
m_freem(m); \
|
||||
return ret; \
|
||||
} \
|
||||
} else { \
|
||||
if ((m)->m_len < (off) + (hlen)) { \
|
||||
ip6stat.ip6s_exthdrtoolong++; \
|
||||
m_freem(m); \
|
||||
return ret; \
|
||||
} \
|
||||
} \
|
||||
} else { \
|
||||
if ((m)->m_len < (off) + (hlen)) { \
|
||||
ip6stat.ip6s_tooshort++; \
|
||||
in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_truncated); \
|
||||
m_freem(m); \
|
||||
return ret; \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#endif /* not _NETINET_IPV6_H_ */
|
||||
391
sys/netinet6/ip6_forward.c
Normal file
391
sys/netinet6/ip6_forward.c
Normal file
|
|
@ -0,0 +1,391 @@
|
|||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include "opt_ip6fw.h"
|
||||
#include "opt_inet.h"
|
||||
#include "opt_ipsec.h"
|
||||
#include "opt_key.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/domain.h>
|
||||
#include <sys/protosw.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/syslog.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/route.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_var.h>
|
||||
#include <netinet6/ip6.h>
|
||||
#include <netinet6/ip6_var.h>
|
||||
#include <netinet6/icmp6.h>
|
||||
#include <netinet6/nd6.h>
|
||||
|
||||
#ifdef IPSEC_IPV6FWD
|
||||
#include <netinet6/ipsec.h>
|
||||
#ifdef INET6
|
||||
#include <netinet6/ipsec6.h>
|
||||
#endif /* INET6 */
|
||||
#include <netkey/key.h>
|
||||
#ifdef KEY_DEBUG
|
||||
#include <netkey/key_debug.h>
|
||||
#ifdef INET6
|
||||
#include <netkey/key_debug6.h>
|
||||
#endif /* INET6 */
|
||||
#else
|
||||
#define DPRINTF(lev,arg)
|
||||
#define DDO(lev, stmt)
|
||||
#define DP(x, y, z)
|
||||
#endif /* KEY_DEBUG */
|
||||
#endif /* IPSEC_IPV6FWD */
|
||||
|
||||
#ifdef IPV6FIREWALL
|
||||
#include <netinet6/ip6_fw.h>
|
||||
#endif
|
||||
|
||||
#include <net/net_osdep.h>
|
||||
|
||||
struct route_in6 ip6_forward_rt;
|
||||
|
||||
/*
|
||||
* Forward a packet. If some error occurs return the sender
|
||||
* an icmp packet. Note we can't always generate a meaningful
|
||||
* icmp message because icmp doesn't have a large enough repertoire
|
||||
* of codes and types.
|
||||
*
|
||||
* If not forwarding, just drop the packet. This could be confusing
|
||||
* if ipforwarding was zero but some routing protocol was advancing
|
||||
* us as a gateway to somewhere. However, we must let the routing
|
||||
* protocol deal with that.
|
||||
*
|
||||
*/
|
||||
|
||||
void
|
||||
ip6_forward(m, srcrt)
|
||||
struct mbuf *m;
|
||||
int srcrt;
|
||||
{
|
||||
struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
|
||||
register struct sockaddr_in6 *dst;
|
||||
register struct rtentry *rt;
|
||||
int error, type = 0, code = 0;
|
||||
struct mbuf *mcopy;
|
||||
#ifdef IPSEC_IPV6FWD
|
||||
struct secpolicy *sp = NULL;
|
||||
#endif
|
||||
|
||||
#ifdef IPSEC_IPV6FWD
|
||||
/*
|
||||
* Check AH/ESP integrity.
|
||||
*/
|
||||
/*
|
||||
* Don't increment ip6s_cantforward because this is the check
|
||||
* before forwarding packet actually.
|
||||
*/
|
||||
if (ipsec6_in_reject(m, NULL)) {
|
||||
ipsec6stat.in_polvio++;
|
||||
m_freem(m);
|
||||
return;
|
||||
}
|
||||
#endif /*IPSEC_IPV6FWD*/
|
||||
|
||||
if (m->m_flags & (M_BCAST|M_MCAST) ||
|
||||
in6_canforward(&ip6->ip6_src, &ip6->ip6_dst) == 0) {
|
||||
ip6stat.ip6s_cantforward++;
|
||||
ip6stat.ip6s_badscope++;
|
||||
/* XXX in6_ifstat_inc(rt->rt_ifp, ifs6_in_discard) */
|
||||
if (ip6_log_time + ip6_log_interval < time_second) {
|
||||
char addr[INET6_ADDRSTRLEN];
|
||||
ip6_log_time = time_second;
|
||||
strncpy(addr, ip6_sprintf(&ip6->ip6_src), sizeof(addr));
|
||||
log(LOG_DEBUG,
|
||||
"cannot forward "
|
||||
"from %s to %s nxt %d received on %s\n",
|
||||
addr, ip6_sprintf(&ip6->ip6_dst),
|
||||
ip6->ip6_nxt,
|
||||
if_name(m->m_pkthdr.rcvif));
|
||||
}
|
||||
m_freem(m);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ip6->ip6_hlim <= IPV6_HLIMDEC) {
|
||||
/* XXX in6_ifstat_inc(rt->rt_ifp, ifs6_in_discard) */
|
||||
icmp6_error(m, ICMP6_TIME_EXCEEDED,
|
||||
ICMP6_TIME_EXCEED_TRANSIT, 0);
|
||||
return;
|
||||
}
|
||||
ip6->ip6_hlim -= IPV6_HLIMDEC;
|
||||
|
||||
#ifdef IPSEC_IPV6FWD
|
||||
/* get a security policy for this packet */
|
||||
sp = ipsec6_getpolicybyaddr(m, IPSEC_DIR_OUTBOUND, 0, &error);
|
||||
if (sp == NULL) {
|
||||
ipsec6stat.out_inval++;
|
||||
ip6stat.ip6s_cantforward++;
|
||||
/* XXX: any icmp ? */
|
||||
m_freem(m);
|
||||
return;
|
||||
}
|
||||
|
||||
error = 0;
|
||||
|
||||
/* check policy */
|
||||
switch (sp->policy) {
|
||||
case IPSEC_POLICY_DISCARD:
|
||||
/*
|
||||
* This packet is just discarded.
|
||||
*/
|
||||
ipsec6stat.out_polvio++;
|
||||
ip6stat.ip6s_cantforward++;
|
||||
key_freesp(sp);
|
||||
/* XXX: any icmp ? */
|
||||
m_freem(m);
|
||||
return;
|
||||
|
||||
case IPSEC_POLICY_BYPASS:
|
||||
case IPSEC_POLICY_NONE:
|
||||
/* no need to do IPsec. */
|
||||
key_freesp(sp);
|
||||
goto skip_ipsec;
|
||||
|
||||
case IPSEC_POLICY_IPSEC:
|
||||
if (sp->req == NULL) {
|
||||
/* XXX should be panic ? */
|
||||
printf("ip6_forward: No IPsec request specified.\n");
|
||||
ip6stat.ip6s_cantforward++;
|
||||
key_freesp(sp);
|
||||
/* XXX: any icmp ? */
|
||||
m_freem(m);
|
||||
return;
|
||||
}
|
||||
/* do IPsec */
|
||||
break;
|
||||
|
||||
case IPSEC_POLICY_ENTRUST:
|
||||
default:
|
||||
/* should be panic ?? */
|
||||
printf("ip6_forward: Invalid policy found. %d\n", sp->policy);
|
||||
key_freesp(sp);
|
||||
goto skip_ipsec;
|
||||
}
|
||||
|
||||
{
|
||||
struct ipsec_output_state state;
|
||||
|
||||
/*
|
||||
* All the extension headers will become inaccessible
|
||||
* (since they can be encrypted).
|
||||
* Don't panic, we need no more updates to extension headers
|
||||
* on inner IPv6 packet (since they are now encapsulated).
|
||||
*
|
||||
* IPv6 [ESP|AH] IPv6 [extension headers] payload
|
||||
*/
|
||||
bzero(&state, sizeof(state));
|
||||
state.m = m;
|
||||
state.ro = NULL; /* update at ipsec6_output_tunnel() */
|
||||
state.dst = NULL; /* update at ipsec6_output_tunnel() */
|
||||
|
||||
error = ipsec6_output_tunnel(&state, sp, 0);
|
||||
|
||||
m = state.m;
|
||||
/* XXX allocate a route (ro, dst) again later */
|
||||
key_freesp(sp);
|
||||
|
||||
if (error) {
|
||||
/* mbuf is already reclaimed in ipsec6_output_tunnel. */
|
||||
switch (error) {
|
||||
case EHOSTUNREACH:
|
||||
case ENETUNREACH:
|
||||
case EMSGSIZE:
|
||||
case ENOBUFS:
|
||||
case ENOMEM:
|
||||
break;
|
||||
default:
|
||||
printf("ip6_output (ipsec): error code %d\n", error);
|
||||
/*fall through*/
|
||||
case ENOENT:
|
||||
/* don't show these error codes to the user */
|
||||
break;
|
||||
}
|
||||
ip6stat.ip6s_cantforward++;
|
||||
/* XXX: any icmp ? */
|
||||
m_freem(m);
|
||||
return;
|
||||
}
|
||||
}
|
||||
skip_ipsec:
|
||||
#endif /* IPSEC_IPV6FWD */
|
||||
|
||||
dst = &ip6_forward_rt.ro_dst;
|
||||
if (!srcrt) {
|
||||
/*
|
||||
* ip6_forward_rt.ro_dst.sin6_addr is equal to ip6->ip6_dst
|
||||
*/
|
||||
if (ip6_forward_rt.ro_rt == 0 ||
|
||||
(ip6_forward_rt.ro_rt->rt_flags & RTF_UP) == 0) {
|
||||
if (ip6_forward_rt.ro_rt) {
|
||||
RTFREE(ip6_forward_rt.ro_rt);
|
||||
ip6_forward_rt.ro_rt = 0;
|
||||
}
|
||||
/* this probably fails but give it a try again */
|
||||
rtalloc_ign((struct route *)&ip6_forward_rt,
|
||||
RTF_PRCLONING);
|
||||
}
|
||||
|
||||
if (ip6_forward_rt.ro_rt == 0) {
|
||||
ip6stat.ip6s_noroute++;
|
||||
/* XXX in6_ifstat_inc(rt->rt_ifp, ifs6_in_noroute) */
|
||||
icmp6_error(m, ICMP6_DST_UNREACH,
|
||||
ICMP6_DST_UNREACH_NOROUTE, 0);
|
||||
return;
|
||||
}
|
||||
} else if ((rt = ip6_forward_rt.ro_rt) == 0 ||
|
||||
!IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst, &dst->sin6_addr)) {
|
||||
if (ip6_forward_rt.ro_rt) {
|
||||
RTFREE(ip6_forward_rt.ro_rt);
|
||||
ip6_forward_rt.ro_rt = 0;
|
||||
}
|
||||
bzero(dst, sizeof(*dst));
|
||||
dst->sin6_len = sizeof(struct sockaddr_in6);
|
||||
dst->sin6_family = AF_INET6;
|
||||
dst->sin6_addr = ip6->ip6_dst;
|
||||
|
||||
rtalloc_ign((struct route *)&ip6_forward_rt, RTF_PRCLONING);
|
||||
if (ip6_forward_rt.ro_rt == 0) {
|
||||
ip6stat.ip6s_noroute++;
|
||||
/* XXX in6_ifstat_inc(rt->rt_ifp, ifs6_in_noroute) */
|
||||
icmp6_error(m, ICMP6_DST_UNREACH,
|
||||
ICMP6_DST_UNREACH_NOROUTE, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
rt = ip6_forward_rt.ro_rt;
|
||||
if (m->m_pkthdr.len > rt->rt_ifp->if_mtu){
|
||||
in6_ifstat_inc(rt->rt_ifp, ifs6_in_toobig);
|
||||
icmp6_error(m, ICMP6_PACKET_TOO_BIG, 0, rt->rt_ifp->if_mtu);
|
||||
return;
|
||||
}
|
||||
|
||||
if (rt->rt_flags & RTF_GATEWAY)
|
||||
dst = (struct sockaddr_in6 *)rt->rt_gateway;
|
||||
/*
|
||||
* Save at most 528 bytes of the packet in case
|
||||
* we need to generate an ICMP6 message to the src.
|
||||
* Thanks to M_EXT, in most cases copy will not occur.
|
||||
*/
|
||||
mcopy = m_copy(m, 0, imin(m->m_pkthdr.len, ICMPV6_PLD_MAXLEN));
|
||||
|
||||
/*
|
||||
* If we are to forward the packet using the same interface
|
||||
* as one we got the packet from, perhaps we should send a redirect
|
||||
* to sender to shortcut a hop.
|
||||
* Only send redirect if source is sending directly to us,
|
||||
* and if packet was not source routed (or has any options).
|
||||
* Also, don't send redirect if forwarding using a route
|
||||
* modified by a redirect.
|
||||
*/
|
||||
if (rt->rt_ifp == m->m_pkthdr.rcvif && !srcrt &&
|
||||
(rt->rt_flags & (RTF_DYNAMIC|RTF_MODIFIED)) == 0)
|
||||
type = ND_REDIRECT;
|
||||
|
||||
#ifdef IPV6FIREWALL
|
||||
/*
|
||||
* Check with the firewall...
|
||||
*/
|
||||
if (ip6_fw_chk_ptr) {
|
||||
u_short port = 0;
|
||||
/* If ipfw says divert, we have to just drop packet */
|
||||
if ((*ip6_fw_chk_ptr)(&ip6, rt->rt_ifp, &port, &m)) {
|
||||
m_freem(m);
|
||||
goto freecopy;
|
||||
}
|
||||
if (!m)
|
||||
goto freecopy;
|
||||
}
|
||||
#endif
|
||||
|
||||
error = nd6_output(rt->rt_ifp, m, dst, rt);
|
||||
if (error) {
|
||||
in6_ifstat_inc(rt->rt_ifp, ifs6_out_discard);
|
||||
ip6stat.ip6s_cantforward++;
|
||||
} else {
|
||||
ip6stat.ip6s_forward++;
|
||||
in6_ifstat_inc(rt->rt_ifp, ifs6_out_forward);
|
||||
if (type)
|
||||
ip6stat.ip6s_redirectsent++;
|
||||
else {
|
||||
if (mcopy)
|
||||
goto freecopy;
|
||||
}
|
||||
}
|
||||
if (mcopy == NULL)
|
||||
return;
|
||||
|
||||
switch (error) {
|
||||
case 0:
|
||||
if (type == ND_REDIRECT) {
|
||||
icmp6_redirect_output(mcopy, rt);
|
||||
return;
|
||||
}
|
||||
goto freecopy;
|
||||
|
||||
case EMSGSIZE:
|
||||
/* xxx MTU is constant in PPP? */
|
||||
goto freecopy;
|
||||
|
||||
case ENOBUFS:
|
||||
/* Tell source to slow down like source quench in IP? */
|
||||
goto freecopy;
|
||||
|
||||
case ENETUNREACH: /* shouldn't happen, checked above */
|
||||
case EHOSTUNREACH:
|
||||
case ENETDOWN:
|
||||
case EHOSTDOWN:
|
||||
default:
|
||||
type = ICMP6_DST_UNREACH;
|
||||
code = ICMP6_DST_UNREACH_ADDR;
|
||||
break;
|
||||
}
|
||||
icmp6_error(mcopy, type, code, 0);
|
||||
return;
|
||||
|
||||
freecopy:
|
||||
m_freem(mcopy);
|
||||
return;
|
||||
}
|
||||
202
sys/netinet6/ip6_fw.h
Normal file
202
sys/netinet6/ip6_fw.h
Normal file
|
|
@ -0,0 +1,202 @@
|
|||
/*
|
||||
* Copyright (c) 1993 Daniel Boulet
|
||||
* Copyright (c) 1994 Ugen J.S.Antsilevich
|
||||
*
|
||||
* Redistribution and use in source forms, with and without modification,
|
||||
* are permitted provided that this entire comment appears intact.
|
||||
*
|
||||
* Redistribution in binary form may occur without any restrictions.
|
||||
* Obviously, it would be nice if you gave credit where credit is due
|
||||
* but requiring it would be too onerous.
|
||||
*
|
||||
* This software is provided ``AS IS'' without any warranties of any kind.
|
||||
*
|
||||
* $Id: ip6_fw.h,v 1.1 1999/08/06 14:10:09 itojun Exp $
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _IP6_FW_H
|
||||
#define _IP6_FW_H
|
||||
|
||||
#include <net/if.h>
|
||||
|
||||
/*
|
||||
* This union structure identifies an interface, either explicitly
|
||||
* by name or implicitly by IP address. The flags IP_FW_F_IIFNAME
|
||||
* and IP_FW_F_OIFNAME say how to interpret this structure. An
|
||||
* interface unit number of -1 matches any unit number, while an
|
||||
* IP address of 0.0.0.0 indicates matches any interface.
|
||||
*
|
||||
* The receive and transmit interfaces are only compared against the
|
||||
* the packet if the corresponding bit (IP_FW_F_IIFACE or IP_FW_F_OIFACE)
|
||||
* is set. Note some packets lack a receive or transmit interface
|
||||
* (in which case the missing "interface" never matches).
|
||||
*/
|
||||
|
||||
union ip6_fw_if {
|
||||
struct in6_addr fu_via_ip6; /* Specified by IPv6 address */
|
||||
struct { /* Specified by interface name */
|
||||
#define FW_IFNLEN IFNAMSIZ
|
||||
char name[FW_IFNLEN];
|
||||
short unit; /* -1 means match any unit */
|
||||
} fu_via_if;
|
||||
};
|
||||
|
||||
/*
|
||||
* Format of an IP firewall descriptor
|
||||
*
|
||||
* fw_src, fw_dst, fw_smsk, fw_dmsk are always stored in network byte order.
|
||||
* fw_flg and fw_n*p are stored in host byte order (of course).
|
||||
* Port numbers are stored in HOST byte order.
|
||||
* Warning: setsockopt() will fail if sizeof(struct ip_fw) > MLEN (108)
|
||||
*/
|
||||
|
||||
struct ip6_fw {
|
||||
u_long fw_pcnt,fw_bcnt; /* Packet and byte counters */
|
||||
struct in6_addr fw_src, fw_dst; /* Source and destination IPv6 addr */
|
||||
/* Mask for src and dest IPv6 addr */
|
||||
struct in6_addr fw_smsk, fw_dmsk;
|
||||
u_short fw_number; /* Rule number */
|
||||
u_short fw_flg; /* Flags word */
|
||||
#define IPV6_FW_MAX_PORTS 10 /* A reasonable maximum */
|
||||
/* Array of port numbers to match */
|
||||
u_short fw_pts[IPV6_FW_MAX_PORTS];
|
||||
u_char fw_ip6opt,fw_ip6nopt; /* IPv6 options set/unset */
|
||||
u_char fw_tcpf,fw_tcpnf; /* TCP flags set/unset */
|
||||
#define IPV6_FW_ICMPTYPES_DIM (32 / (sizeof(unsigned) * 8))
|
||||
/* ICMP types bitmap */
|
||||
unsigned fw_icmp6types[IPV6_FW_ICMPTYPES_DIM];
|
||||
long timestamp; /* timestamp (tv_sec) of last match */
|
||||
/* Incoming and outgoing interfaces */
|
||||
union ip6_fw_if fw_in_if, fw_out_if;
|
||||
union {
|
||||
u_short fu_divert_port; /* Divert/tee port (options IP6DIVERT) */
|
||||
u_short fu_skipto_rule; /* SKIPTO command rule number */
|
||||
u_short fu_reject_code; /* REJECT response code */
|
||||
} fw_un;
|
||||
u_char fw_prot; /* IPv6 protocol */
|
||||
u_char fw_nports; /* N'of src ports and # of dst ports */
|
||||
/* in ports array (dst ports follow */
|
||||
/* src ports; max of 10 ports in all; */
|
||||
/* count of 0 means match all ports) */
|
||||
};
|
||||
|
||||
#define IPV6_FW_GETNSRCP(rule) ((rule)->fw_nports & 0x0f)
|
||||
#define IPV6_FW_SETNSRCP(rule, n) do { \
|
||||
(rule)->fw_nports &= ~0x0f; \
|
||||
(rule)->fw_nports |= (n); \
|
||||
} while (0)
|
||||
#define IPV6_FW_GETNDSTP(rule) ((rule)->fw_nports >> 4)
|
||||
#define IPV6_FW_SETNDSTP(rule, n) do { \
|
||||
(rule)->fw_nports &= ~0xf0; \
|
||||
(rule)->fw_nports |= (n) << 4;\
|
||||
} while (0)
|
||||
|
||||
#define fw_divert_port fw_un.fu_divert_port
|
||||
#define fw_skipto_rule fw_un.fu_skipto_rule
|
||||
#define fw_reject_code fw_un.fu_reject_code
|
||||
|
||||
struct ip6_fw_chain {
|
||||
LIST_ENTRY(ip6_fw_chain) chain;
|
||||
struct ip6_fw *rule;
|
||||
};
|
||||
|
||||
/*
|
||||
* Values for "flags" field .
|
||||
*/
|
||||
#define IPV6_FW_F_IN 0x0001 /* Check inbound packets */
|
||||
#define IPV6_FW_F_OUT 0x0002 /* Check outbound packets */
|
||||
#define IPV6_FW_F_IIFACE 0x0004 /* Apply inbound interface test */
|
||||
#define IPV6_FW_F_OIFACE 0x0008 /* Apply outbound interface test */
|
||||
|
||||
#define IPV6_FW_F_COMMAND 0x0070 /* Mask for type of chain entry: */
|
||||
#define IPV6_FW_F_DENY 0x0000 /* This is a deny rule */
|
||||
#define IPV6_FW_F_REJECT 0x0010 /* Deny and send a response packet */
|
||||
#define IPV6_FW_F_ACCEPT 0x0020 /* This is an accept rule */
|
||||
#define IPV6_FW_F_COUNT 0x0030 /* This is a count rule */
|
||||
#define IPV6_FW_F_DIVERT 0x0040 /* This is a divert rule */
|
||||
#define IPV6_FW_F_TEE 0x0050 /* This is a tee rule */
|
||||
#define IPV6_FW_F_SKIPTO 0x0060 /* This is a skipto rule */
|
||||
|
||||
#define IPV6_FW_F_PRN 0x0080 /* Print if this rule matches */
|
||||
|
||||
#define IPV6_FW_F_SRNG 0x0100 /* The first two src ports are a min *
|
||||
* and max range (stored in host byte *
|
||||
* order). */
|
||||
|
||||
#define IPV6_FW_F_DRNG 0x0200 /* The first two dst ports are a min *
|
||||
* and max range (stored in host byte *
|
||||
* order). */
|
||||
|
||||
/* In interface by name/unit (not IP) */
|
||||
#define IPV6_FW_F_IIFNAME 0x0400
|
||||
/* Out interface by name/unit (not IP) */
|
||||
#define IPV6_FW_F_OIFNAME 0x0800
|
||||
|
||||
#define IPV6_FW_F_INVSRC 0x1000 /* Invert sense of src check */
|
||||
#define IPV6_FW_F_INVDST 0x2000 /* Invert sense of dst check */
|
||||
|
||||
#define IPV6_FW_F_FRAG 0x4000 /* Fragment */
|
||||
|
||||
#define IPV6_FW_F_ICMPBIT 0x8000 /* ICMP type bitmap is valid */
|
||||
|
||||
#define IPV6_FW_F_MASK 0xFFFF /* All possible flag bits mask */
|
||||
|
||||
/*
|
||||
* For backwards compatibility with rules specifying "via iface" but
|
||||
* not restricted to only "in" or "out" packets, we define this combination
|
||||
* of bits to represent this configuration.
|
||||
*/
|
||||
|
||||
#define IF6_FW_F_VIAHACK (IPV6_FW_F_IN|IPV6_FW_F_OUT|IPV6_FW_F_IIFACE|\
|
||||
IPV6_FW_F_OIFACE)
|
||||
|
||||
/*
|
||||
* Definitions for REJECT response codes.
|
||||
* Values less than 256 correspond to ICMP unreachable codes.
|
||||
*/
|
||||
#define IPV6_FW_REJECT_RST 0x0100 /* TCP packets: send RST */
|
||||
|
||||
/*
|
||||
* Definitions for IPv6 option names.
|
||||
*/
|
||||
#define IPV6_FW_IP6OPT_HOPOPT 0x01
|
||||
#define IPV6_FW_IP6OPT_ROUTE 0x02
|
||||
#define IPV6_FW_IP6OPT_FRAG 0x04
|
||||
#define IPV6_FW_IP6OPT_ESP 0x08
|
||||
#define IPV6_FW_IP6OPT_AH 0x10
|
||||
#define IPV6_FW_IP6OPT_NONXT 0x20
|
||||
#define IPV6_FW_IP6OPT_OPTS 0x40
|
||||
|
||||
/*
|
||||
* Definitions for TCP flags.
|
||||
*/
|
||||
#define IPV6_FW_TCPF_FIN TH_FIN
|
||||
#define IPV6_FW_TCPF_SYN TH_SYN
|
||||
#define IPV6_FW_TCPF_RST TH_RST
|
||||
#define IPV6_FW_TCPF_PSH TH_PUSH
|
||||
#define IPV6_FW_TCPF_ACK TH_ACK
|
||||
#define IPV6_FW_TCPF_URG TH_URG
|
||||
#define IPV6_FW_TCPF_ESTAB 0x40
|
||||
|
||||
/*
|
||||
* Main firewall chains definitions and global var's definitions.
|
||||
*/
|
||||
#ifdef _KERNEL
|
||||
|
||||
/*
|
||||
* Function definitions.
|
||||
*/
|
||||
void ip6_fw_init(void);
|
||||
|
||||
/* Firewall hooks */
|
||||
struct ip6_hdr;
|
||||
typedef int ip6_fw_chk_t __P((struct ip6_hdr**, struct ifnet*,
|
||||
u_short *, struct mbuf**));
|
||||
typedef int ip6_fw_ctl_t __P((int, struct mbuf**));
|
||||
extern ip6_fw_chk_t *ip6_fw_chk_ptr;
|
||||
extern ip6_fw_ctl_t *ip6_fw_ctl_ptr;
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#endif /* _IP6_FW_H */
|
||||
1016
sys/netinet6/ip6_input.c
Normal file
1016
sys/netinet6/ip6_input.c
Normal file
File diff suppressed because it is too large
Load diff
2176
sys/netinet6/ip6_output.c
Normal file
2176
sys/netinet6/ip6_output.c
Normal file
File diff suppressed because it is too large
Load diff
251
sys/netinet6/ip6_var.h
Normal file
251
sys/netinet6/ip6_var.h
Normal file
|
|
@ -0,0 +1,251 @@
|
|||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1982, 1986, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)ip_var.h 8.1 (Berkeley) 6/10/93
|
||||
*/
|
||||
|
||||
#ifndef _NETINET6_IP6_VAR_H_
|
||||
#define _NETINET6_IP6_VAR_H_
|
||||
|
||||
/*
|
||||
* IP6 reassembly queue structure. Each fragment
|
||||
* being reassembled is attached to one of these structures.
|
||||
*/
|
||||
struct ip6q {
|
||||
u_long ip6q_head;
|
||||
u_short ip6q_len;
|
||||
u_char ip6q_nxt;
|
||||
u_char ip6q_hlim;
|
||||
struct ip6asfrag *ip6q_down;
|
||||
struct ip6asfrag *ip6q_up;
|
||||
u_long ip6q_ident;
|
||||
u_char ip6q_arrive;
|
||||
u_char ip6q_ttl;
|
||||
struct in6_addr ip6q_src, ip6q_dst;
|
||||
struct ip6q *ip6q_next;
|
||||
struct ip6q *ip6q_prev;
|
||||
int ip6q_unfrglen;
|
||||
};
|
||||
|
||||
struct ip6asfrag {
|
||||
u_long ip6af_head;
|
||||
u_short ip6af_len;
|
||||
u_char ip6af_nxt;
|
||||
u_char ip6af_hlim;
|
||||
/* must not override the above members during reassembling */
|
||||
struct ip6asfrag *ip6af_down;
|
||||
struct ip6asfrag *ip6af_up;
|
||||
u_short ip6af_mff;
|
||||
u_short ip6af_off;
|
||||
struct mbuf *ip6af_m;
|
||||
u_long ip6af_offset; /* offset where next header starts */
|
||||
u_short ip6af_frglen; /* fragmentable part length */
|
||||
u_char ip6af_x1[10];
|
||||
};
|
||||
|
||||
#define IP6_REASS_MBUF(ip6af) (*(struct mbuf **)&((ip6af)->ip6af_m))
|
||||
|
||||
struct ip6_moptions {
|
||||
struct ifnet *im6o_multicast_ifp; /* ifp for outgoing multicasts */
|
||||
u_char im6o_multicast_hlim; /* hoplimit for outgoing multicasts */
|
||||
u_char im6o_multicast_loop; /* 1 >= hear sends if a member */
|
||||
LIST_HEAD(, in6_multi_mship) im6o_memberships;
|
||||
};
|
||||
|
||||
/*
|
||||
* Control options for outgoing packets
|
||||
*/
|
||||
|
||||
/* Routing header related info */
|
||||
struct ip6po_rhinfo {
|
||||
struct ip6_rthdr *ip6po_rhi_rthdr; /* Routing header */
|
||||
struct route_in6 ip6po_rhi_route; /* Route to the 1st hop */
|
||||
};
|
||||
#define ip6po_rthdr ip6po_rhinfo.ip6po_rhi_rthdr
|
||||
#define ip6po_route ip6po_rhinfo.ip6po_rhi_route
|
||||
|
||||
struct ip6_pktopts {
|
||||
struct mbuf *ip6po_m; /* Pointer to mbuf storing the data */
|
||||
int ip6po_hlim; /* Hoplimit for outgoing packets */
|
||||
struct in6_pktinfo *ip6po_pktinfo; /* Outgoing IF/address information */
|
||||
struct sockaddr *ip6po_nexthop; /* Next-hop address */
|
||||
struct ip6_hbh *ip6po_hbh; /* Hop-by-Hop options header */
|
||||
struct ip6_dest *ip6po_dest1; /* Destination options header(1st part) */
|
||||
struct ip6po_rhinfo ip6po_rhinfo; /* Routing header related info. */
|
||||
struct ip6_dest *ip6po_dest2; /* Destination options header(2nd part) */
|
||||
};
|
||||
|
||||
struct ip6stat {
|
||||
u_long ip6s_total; /* total packets received */
|
||||
u_long ip6s_tooshort; /* packet too short */
|
||||
u_long ip6s_toosmall; /* not enough data */
|
||||
u_long ip6s_fragments; /* fragments received */
|
||||
u_long ip6s_fragdropped; /* frags dropped(dups, out of space) */
|
||||
u_long ip6s_fragtimeout; /* fragments timed out */
|
||||
u_long ip6s_fragoverflow; /* fragments that exceeded limit */
|
||||
u_long ip6s_forward; /* packets forwarded */
|
||||
u_long ip6s_cantforward; /* packets rcvd for unreachable dest */
|
||||
u_long ip6s_redirectsent; /* packets forwarded on same net */
|
||||
u_long ip6s_delivered; /* datagrams delivered to upper level*/
|
||||
u_long ip6s_localout; /* total ip packets generated here */
|
||||
u_long ip6s_odropped; /* lost packets due to nobufs, etc. */
|
||||
u_long ip6s_reassembled; /* total packets reassembled ok */
|
||||
u_long ip6s_fragmented; /* datagrams sucessfully fragmented */
|
||||
u_long ip6s_ofragments; /* output fragments created */
|
||||
u_long ip6s_cantfrag; /* don't fragment flag was set, etc. */
|
||||
u_long ip6s_badoptions; /* error in option processing */
|
||||
u_long ip6s_noroute; /* packets discarded due to no route */
|
||||
u_long ip6s_badvers; /* ip6 version != 6 */
|
||||
u_long ip6s_rawout; /* total raw ip packets generated */
|
||||
u_long ip6s_badscope; /* scope error */
|
||||
u_long ip6s_notmember; /* don't join this multicast group */
|
||||
u_long ip6s_nxthist[256]; /* next header history */
|
||||
u_long ip6s_m1; /* one mbuf */
|
||||
u_long ip6s_m2m[32]; /* two or more mbuf */
|
||||
u_long ip6s_mext1; /* one ext mbuf */
|
||||
u_long ip6s_mext2m; /* two or more ext mbuf */
|
||||
u_long ip6s_exthdrtoolong; /* ext hdr are not continuous */
|
||||
u_long ip6s_nogif; /* no match gif found */
|
||||
u_long ip6s_toomanyhdr; /* discarded due to too many headers */
|
||||
};
|
||||
|
||||
#ifdef _KERNEL
|
||||
/* flags passed to ip6_output as last parameter */
|
||||
#define IPV6_DADOUTPUT 0x01 /* DAD */
|
||||
#define IPV6_FORWARDING 0x02 /* most of IPv6 header exists */
|
||||
|
||||
extern struct ip6stat ip6stat; /* statistics */
|
||||
extern u_int32_t ip6_id; /* fragment identifier */
|
||||
extern int ip6_defhlim; /* default hop limit */
|
||||
extern int ip6_defmcasthlim; /* default multicast hop limit */
|
||||
extern int ip6_forwarding; /* act as router? */
|
||||
extern int ip6_forward_srcrt; /* forward src-routed? */
|
||||
extern int ip6_gif_hlim; /* Hop limit for gif encap packet */
|
||||
extern int ip6_use_deprecated; /* allow deprecated addr as source */
|
||||
extern int ip6_rr_prune; /* router renumbering prefix
|
||||
* walk list every 5 sec. */
|
||||
extern int ip6_mapped_addr_on;
|
||||
|
||||
extern struct socket *ip6_mrouter; /* multicast routing daemon */
|
||||
extern int ip6_sendredirects; /* send IP redirects when forwarding? */
|
||||
extern int ip6_maxfragpackets; /* Maximum packets in reassembly queue */
|
||||
extern int ip6_sourcecheck; /* Verify source interface */
|
||||
extern int ip6_sourcecheck_interval; /* Interval between log messages */
|
||||
extern int ip6_accept_rtadv; /* Acts as a host not a router */
|
||||
extern int ip6_keepfaith; /* Firewall Aided Internet Translator */
|
||||
extern int ip6_log_interval;
|
||||
extern time_t ip6_log_time;
|
||||
extern int ip6_hdrnestlimit; /* upper limit of # of extension headers */
|
||||
extern int ip6_dad_count; /* DupAddrDetectionTransmits */
|
||||
|
||||
extern u_int32_t ip6_flow_seq;
|
||||
extern int ip6_auto_flowlabel;
|
||||
|
||||
extern struct pr_usrreqs rip6_usrreqs;
|
||||
struct sockopt;
|
||||
struct inpcb;
|
||||
|
||||
int icmp6_ctloutput __P((struct socket *, struct sockopt *sopt));
|
||||
|
||||
void ip6_init __P((void));
|
||||
void ip6intr __P((void));
|
||||
void ip6_input __P((struct mbuf *));
|
||||
void ip6_freemoptions __P((struct ip6_moptions *));
|
||||
int ip6_unknown_opt __P((u_int8_t *, struct mbuf *, int));
|
||||
char * ip6_get_prevhdr __P((struct mbuf *, int));
|
||||
int ip6_mforward __P((struct ip6_hdr *, struct ifnet *, struct mbuf *));
|
||||
int ip6_process_hopopts __P((struct mbuf *, u_int8_t *, int, u_int32_t *,
|
||||
u_int32_t *));
|
||||
void ip6_savecontrol __P((struct inpcb *, struct mbuf **, struct ip6_hdr *,
|
||||
struct mbuf *));
|
||||
int ip6_sysctl __P((int *, u_int, void *, size_t *, void *, size_t));
|
||||
|
||||
void ip6_forward __P((struct mbuf *, int));
|
||||
|
||||
void ip6_mloopback __P((struct ifnet *, struct mbuf *, struct sockaddr_in6 *));
|
||||
int ip6_output __P((struct mbuf *, struct ip6_pktopts *,
|
||||
struct route_in6 *, int,
|
||||
struct ip6_moptions *, struct ifnet **));
|
||||
int ip6_ctloutput __P((struct socket *, struct sockopt *sopt));
|
||||
int ip6_setpktoptions __P((struct mbuf *, struct ip6_pktopts *, int));
|
||||
int ip6_optlen __P((struct inpcb *));
|
||||
|
||||
int route6_input __P((struct mbuf **, int *, int));
|
||||
|
||||
void frag6_init __P((void));
|
||||
int frag6_input __P((struct mbuf **, int *, int));
|
||||
void frag6_slowtimo __P((void));
|
||||
void frag6_drain __P((void));
|
||||
|
||||
void rip6_init __P((void));
|
||||
int rip6_input __P((struct mbuf **mp, int *offp, int proto));
|
||||
int rip6_ctloutput __P((struct socket *so, struct sockopt *sopt));
|
||||
int rip6_output __P((struct mbuf *, ...));
|
||||
int rip6_usrreq __P((struct socket *,
|
||||
int, struct mbuf *, struct mbuf *, struct mbuf *, struct proc *));
|
||||
|
||||
int dest6_input __P((struct mbuf **, int *, int));
|
||||
int none_input __P((struct mbuf **, int *, int));
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#endif /* !_NETINET6_IP6_VAR_H_ */
|
||||
129
sys/netinet6/ip6protosw.h
Normal file
129
sys/netinet6/ip6protosw.h
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/* BSDI protosw.h,v 2.3 1996/10/11 16:02:40 pjd Exp */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1982, 1986, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)protosw.h 8.1 (Berkeley) 6/2/93
|
||||
*/
|
||||
|
||||
#ifndef _NETINET6_IP6PROTOSW_H_
|
||||
#define _NETINET6_IP6PROTOSW_H_
|
||||
|
||||
/*
|
||||
* Protocol switch table for IPv6.
|
||||
* All other definitions should refer to sys/protosw.h
|
||||
*/
|
||||
|
||||
struct mbuf;
|
||||
struct sockaddr;
|
||||
struct socket;
|
||||
struct domain;
|
||||
struct proc;
|
||||
struct ip6_hdr;
|
||||
struct pr_usrreqs;
|
||||
|
||||
/*
|
||||
* argument type for the last arg of pr_ctlinput().
|
||||
* should be consulted only with AF_INET6 family.
|
||||
*/
|
||||
struct ip6ctlparam {
|
||||
struct mbuf *ip6c_m; /* start of mbuf chain */
|
||||
struct ip6_hdr *ip6c_ip6; /* ip6 header of target packet */
|
||||
int ip6c_off; /* offset of the target proto header */
|
||||
};
|
||||
|
||||
struct ip6protosw {
|
||||
int pr_type; /* socket type used for */
|
||||
struct domain *pr_domain; /* domain protocol a member of */
|
||||
short pr_protocol; /* protocol number */
|
||||
short pr_flags; /* see below */
|
||||
|
||||
/* protocol-protocol hooks */
|
||||
int (*pr_input) /* input to protocol (from below) */
|
||||
__P((struct mbuf **, int *, int));
|
||||
int (*pr_output) /* output to protocol (from above) */
|
||||
__P((struct mbuf *, ...));
|
||||
void (*pr_ctlinput) /* control input (from below) */
|
||||
__P((int, struct sockaddr *, void *));
|
||||
int (*pr_ctloutput) /* control output (from above) */
|
||||
__P((struct socket *, struct sockopt *));
|
||||
|
||||
/* user-protocol hook */
|
||||
int (*pr_usrreq) /* user request: see list below */
|
||||
__P((struct socket *, int, struct mbuf *,
|
||||
struct mbuf *, struct mbuf *, struct proc *));
|
||||
|
||||
/* utility hooks */
|
||||
void (*pr_init) /* initialization hook */
|
||||
__P((void));
|
||||
|
||||
void (*pr_fasttimo) /* fast timeout (200ms) */
|
||||
__P((void));
|
||||
void (*pr_slowtimo) /* slow timeout (500ms) */
|
||||
__P((void));
|
||||
void (*pr_drain) /* flush any excess space possible */
|
||||
__P((void));
|
||||
struct pr_usrreqs *pr_usrreqs; /* supersedes pr_usrreq() */
|
||||
};
|
||||
|
||||
#endif /* !_NETINET6_IP6PROTOSW_H_ */
|
||||
314
sys/netinet6/ipsec.h
Normal file
314
sys/netinet6/ipsec.h
Normal file
|
|
@ -0,0 +1,314 @@
|
|||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* IPsec controller part.
|
||||
*/
|
||||
|
||||
#ifndef _NETINET6_IPSEC_H_
|
||||
#define _NETINET6_IPSEC_H_
|
||||
|
||||
#include <net/pfkeyv2.h>
|
||||
#include <netkey/keydb.h>
|
||||
|
||||
#ifdef KERNEL
|
||||
|
||||
/*
|
||||
* Security Policy Index
|
||||
* NOTE: Encure to be same address family and upper layer protocol.
|
||||
* NOTE: ul_proto, port number, uid, gid:
|
||||
* ANY: reserved for waldcard.
|
||||
* 0 to (~0 - 1): is one of the number of each value.
|
||||
*/
|
||||
struct secpolicyindex {
|
||||
u_int8_t dir; /* direction of packet flow, see blow */
|
||||
struct sockaddr_storage src; /* IP src address for SP */
|
||||
struct sockaddr_storage dst; /* IP dst address for SP */
|
||||
u_int8_t prefs; /* prefix length in bits for src */
|
||||
u_int8_t prefd; /* prefix length in bits for dst */
|
||||
u_int16_t ul_proto; /* upper layer Protocol */
|
||||
};
|
||||
|
||||
/* Security Policy Data Base */
|
||||
struct secpolicy {
|
||||
LIST_ENTRY(secpolicy) chain;
|
||||
|
||||
int refcnt; /* reference count */
|
||||
struct secpolicyindex spidx; /* selector */
|
||||
u_int state; /* 0: dead, others: alive */
|
||||
#define IPSEC_SPSTATE_DEAD 0
|
||||
#define IPSEC_SPSTATE_ALIVE 1
|
||||
|
||||
u_int policy; /* DISCARD, NONE or IPSEC, see keyv2.h */
|
||||
struct ipsecrequest *req;
|
||||
/* pointer to the ipsec request tree, */
|
||||
/* if policy == IPSEC else this value == NULL.*/
|
||||
};
|
||||
|
||||
/* Request for IPsec */
|
||||
struct ipsecrequest {
|
||||
struct ipsecrequest *next;
|
||||
/* pointer to next structure */
|
||||
/* If NULL, it means the end of chain. */
|
||||
struct secasindex saidx;
|
||||
u_int level; /* IPsec level defined below. */
|
||||
|
||||
struct secasvar *sav; /* place holder of SA for use */
|
||||
struct secpolicy *sp; /* back pointer to SP */
|
||||
};
|
||||
|
||||
/* security policy in PCB */
|
||||
struct inpcbpolicy {
|
||||
struct secpolicy *sp_in;
|
||||
struct secpolicy *sp_out;
|
||||
int priv; /* privileged socket ? */
|
||||
};
|
||||
#endif /*KERNEL*/
|
||||
|
||||
#define IPSEC_PORT_ANY 65535
|
||||
#define IPSEC_ULPROTO_ANY 255
|
||||
#define IPSEC_PROTO_ANY 65535
|
||||
|
||||
/* mode of security protocol */
|
||||
/* NOTE: DON'T use IPSEC_MODE_ANY at SPD. It's only use in SAD */
|
||||
#define IPSEC_MODE_ANY 0 /* i.e. wildcard. */
|
||||
#define IPSEC_MODE_TRANSPORT 1
|
||||
#define IPSEC_MODE_TUNNEL 2
|
||||
|
||||
/*
|
||||
* Direction of security policy.
|
||||
* NOTE: Since INVALID is used just as flag.
|
||||
* The other are used for loop counter too.
|
||||
*/
|
||||
#define IPSEC_DIR_ANY 0
|
||||
#define IPSEC_DIR_INBOUND 1
|
||||
#define IPSEC_DIR_OUTBOUND 2
|
||||
#define IPSEC_DIR_MAX 3
|
||||
#define IPSEC_DIR_INVALID 4
|
||||
|
||||
/* Policy level */
|
||||
/*
|
||||
* IPSEC, ENTRUST and BYPASS are allowd for setsockopt() in PCB,
|
||||
* DISCARD, IPSEC and NONE are allowd for setkey() in SPD.
|
||||
* DISCARD and NONE are allowd for system default.
|
||||
*/
|
||||
#define IPSEC_POLICY_DISCARD 0 /* discarding packet */
|
||||
#define IPSEC_POLICY_NONE 1 /* through IPsec engine */
|
||||
#define IPSEC_POLICY_IPSEC 2 /* do IPsec */
|
||||
#define IPSEC_POLICY_ENTRUST 3 /* consulting SPD if present. */
|
||||
#define IPSEC_POLICY_BYPASS 4 /* only for privileged socket. */
|
||||
|
||||
/* Security protocol level */
|
||||
#define IPSEC_LEVEL_DEFAULT 0 /* reference to system default */
|
||||
#define IPSEC_LEVEL_USE 1 /* use SA if present. */
|
||||
#define IPSEC_LEVEL_REQUIRE 2 /* require SA. */
|
||||
#define IPSEC_LEVEL_UNIQUE 3 /* unique SA. */
|
||||
|
||||
#define IPSEC_REPLAYWSIZE 32
|
||||
|
||||
/* statistics for ipsec processing */
|
||||
struct ipsecstat {
|
||||
u_long in_success; /* succeeded inbound process */
|
||||
u_long in_polvio; /* security policy violation for inbound process */
|
||||
u_long in_nosa; /* inbound SA is unavailable */
|
||||
u_long in_inval; /* inbound processing failed due to EINVAL */
|
||||
u_long in_badspi; /* failed getting a SPI */
|
||||
u_long in_ahreplay; /* AH replay check failed */
|
||||
u_long in_espreplay; /* ESP replay check failed */
|
||||
u_long in_ahauthsucc; /* AH authentication success */
|
||||
u_long in_ahauthfail; /* AH authentication failure */
|
||||
u_long in_espauthsucc; /* ESP authentication success */
|
||||
u_long in_espauthfail; /* ESP authentication failure */
|
||||
u_long in_esphist[SADB_EALG_MAX];
|
||||
u_long in_ahhist[SADB_AALG_MAX];
|
||||
u_long out_success; /* succeeded outbound process */
|
||||
u_long out_polvio; /* security policy violation for outbound process */
|
||||
u_long out_nosa; /* outbound SA is unavailable */
|
||||
u_long out_inval; /* outbound process failed due to EINVAL */
|
||||
u_long out_noroute; /* there is no route */
|
||||
u_long out_esphist[SADB_EALG_MAX];
|
||||
u_long out_ahhist[SADB_AALG_MAX];
|
||||
};
|
||||
|
||||
/*
|
||||
* Definitions for IPsec & Key sysctl operations.
|
||||
*/
|
||||
/*
|
||||
* Names for IPsec & Key sysctl objects
|
||||
*/
|
||||
#define IPSECCTL_STATS 1 /* stats */
|
||||
#define IPSECCTL_DEF_POLICY 2
|
||||
#define IPSECCTL_DEF_ESP_TRANSLEV 3 /* int; ESP transport mode */
|
||||
#define IPSECCTL_DEF_ESP_NETLEV 4 /* int; ESP tunnel mode */
|
||||
#define IPSECCTL_DEF_AH_TRANSLEV 5 /* int; AH transport mode */
|
||||
#define IPSECCTL_DEF_AH_NETLEV 6 /* int; AH tunnel mode */
|
||||
#define IPSECCTL_INBOUND_CALL_IKE 7
|
||||
#define IPSECCTL_AH_CLEARTOS 8
|
||||
#define IPSECCTL_AH_OFFSETMASK 9
|
||||
#define IPSECCTL_DFBIT 10
|
||||
#define IPSECCTL_ECN 11
|
||||
#define IPSECCTL_MAXID 12
|
||||
|
||||
#define IPSECCTL_NAMES { \
|
||||
{ 0, 0 }, \
|
||||
{ 0, 0 }, \
|
||||
{ "def_policy", CTLTYPE_INT }, \
|
||||
{ "esp_trans_deflev", CTLTYPE_INT }, \
|
||||
{ "esp_net_deflev", CTLTYPE_INT }, \
|
||||
{ "ah_trans_deflev", CTLTYPE_INT }, \
|
||||
{ "ah_net_deflev", CTLTYPE_INT }, \
|
||||
{ "inbound_call_ike", CTLTYPE_INT }, \
|
||||
{ "ah_cleartos", CTLTYPE_INT }, \
|
||||
{ "ah_offsetmask", CTLTYPE_INT }, \
|
||||
{ "dfbit", CTLTYPE_INT }, \
|
||||
{ "ecn", CTLTYPE_INT }, \
|
||||
}
|
||||
|
||||
#define IPSEC6CTL_NAMES { \
|
||||
{ 0, 0 }, \
|
||||
{ 0, 0 }, \
|
||||
{ "def_policy", CTLTYPE_INT }, \
|
||||
{ "esp_trans_deflev", CTLTYPE_INT }, \
|
||||
{ "esp_net_deflev", CTLTYPE_INT }, \
|
||||
{ "ah_trans_deflev", CTLTYPE_INT }, \
|
||||
{ "ah_net_deflev", CTLTYPE_INT }, \
|
||||
{ "inbound_call_ike", CTLTYPE_INT }, \
|
||||
{ 0, 0 }, \
|
||||
{ 0, 0 }, \
|
||||
{ 0, 0 }, \
|
||||
{ "ecn", CTLTYPE_INT }, \
|
||||
}
|
||||
|
||||
#define IPSECCTL_VARS { \
|
||||
0, \
|
||||
0, \
|
||||
&ip4_def_policy.policy, \
|
||||
&ip4_esp_trans_deflev, \
|
||||
&ip4_esp_net_deflev, \
|
||||
&ip4_ah_trans_deflev, \
|
||||
&ip4_ah_net_deflev, \
|
||||
&ip4_inbound_call_ike, \
|
||||
&ip4_ah_cleartos, \
|
||||
&ip4_ah_offsetmask, \
|
||||
&ip4_ipsec_dfbit, \
|
||||
&ip4_ipsec_ecn, \
|
||||
}
|
||||
|
||||
#define IPSEC6CTL_VARS { \
|
||||
0, \
|
||||
0, \
|
||||
&ip6_def_policy.policy, \
|
||||
&ip6_esp_trans_deflev, \
|
||||
&ip6_esp_net_deflev, \
|
||||
&ip6_ah_trans_deflev, \
|
||||
&ip6_ah_net_deflev, \
|
||||
&ip6_inbound_call_ike, \
|
||||
0, \
|
||||
0, \
|
||||
0, \
|
||||
&ip6_ipsec_ecn, \
|
||||
}
|
||||
|
||||
#ifdef KERNEL
|
||||
struct ipsec_output_state {
|
||||
struct mbuf *m;
|
||||
struct route *ro;
|
||||
struct sockaddr *dst;
|
||||
};
|
||||
|
||||
extern struct ipsecstat ipsecstat;
|
||||
extern struct secpolicy ip4_def_policy;
|
||||
extern int ip4_esp_trans_deflev;
|
||||
extern int ip4_esp_net_deflev;
|
||||
extern int ip4_ah_trans_deflev;
|
||||
extern int ip4_ah_net_deflev;
|
||||
extern int ip4_inbound_call_ike;
|
||||
extern int ip4_ah_cleartos;
|
||||
extern int ip4_ah_offsetmask;
|
||||
extern int ip4_ipsec_dfbit;
|
||||
extern int ip4_ipsec_ecn;
|
||||
|
||||
extern struct secpolicy *ipsec4_getpolicybysock
|
||||
__P((struct mbuf *, u_int, struct socket *, int *));
|
||||
extern struct secpolicy *ipsec4_getpolicybyaddr
|
||||
__P((struct mbuf *, u_int, int, int *));
|
||||
|
||||
struct inpcb;
|
||||
|
||||
extern int ipsec_init_policy __P((struct socket *so, struct inpcbpolicy **));
|
||||
extern int ipsec_copy_policy
|
||||
__P((struct inpcbpolicy *, struct inpcbpolicy *));
|
||||
extern u_int ipsec_get_reqlevel __P((struct ipsecrequest *));
|
||||
|
||||
extern int ipsec4_set_policy __P((struct inpcb *inp, int optname,
|
||||
caddr_t request, int priv));
|
||||
extern int ipsec4_get_policy
|
||||
__P((struct inpcb *inpcb, caddr_t request, struct mbuf **mp));
|
||||
extern int ipsec4_delete_pcbpolicy __P((struct inpcb *));
|
||||
extern int ipsec4_in_reject_so __P((struct mbuf *, struct socket *));
|
||||
extern int ipsec4_in_reject __P((struct mbuf *, struct inpcb *));
|
||||
|
||||
struct secas;
|
||||
struct tcpcb;
|
||||
struct tcp6cb;
|
||||
extern int ipsec_chkreplay __P((u_int32_t, struct secasvar *));
|
||||
extern int ipsec_updatereplay __P((u_int32_t, struct secasvar *));
|
||||
|
||||
extern size_t ipsec4_hdrsiz __P((struct mbuf *, u_int, struct inpcb *));
|
||||
extern size_t ipsec_hdrsiz_tcp __P((struct tcpcb *, int));
|
||||
|
||||
struct ip;
|
||||
|
||||
extern const char *ipsec4_logpacketstr __P((struct ip *, u_int32_t));
|
||||
extern const char *ipsec_logsastr __P((struct secasvar *));
|
||||
|
||||
extern void ipsec_dumpmbuf __P((struct mbuf *));
|
||||
|
||||
extern int ipsec4_output __P((struct ipsec_output_state *, struct secpolicy *,
|
||||
int));
|
||||
|
||||
extern int ipsec4_tunnel_validate __P((struct ip *, u_int,
|
||||
struct secasvar *));
|
||||
|
||||
extern struct mbuf *ipsec_copypkt __P((struct mbuf *));
|
||||
|
||||
#endif /*KERNEL*/
|
||||
|
||||
#ifndef KERNEL
|
||||
extern caddr_t ipsec_set_policy __P((char *policy, int buflen));
|
||||
extern int ipsec_get_policylen __P((caddr_t buf));
|
||||
extern char *ipsec_dump_policy __P((caddr_t buf, char *delimiter));
|
||||
|
||||
extern char *ipsec_strerror __P((void));
|
||||
#endif /*!KERNEL*/
|
||||
|
||||
#endif /*_NETINET6_IPSEC_H_*/
|
||||
|
||||
77
sys/netinet6/ipsec6.h
Normal file
77
sys/netinet6/ipsec6.h
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* IPsec controller part, only IPv6 related
|
||||
*/
|
||||
|
||||
#ifndef _NETINET6_IPSEC6_H_
|
||||
#define _NETINET6_IPSEC6_H_
|
||||
|
||||
#ifdef KERNEL
|
||||
|
||||
extern struct ipsecstat ipsec6stat;
|
||||
extern struct secpolicy ip6_def_policy;
|
||||
extern int ip6_esp_trans_deflev;
|
||||
extern int ip6_esp_net_deflev;
|
||||
extern int ip6_ah_trans_deflev;
|
||||
extern int ip6_ah_net_deflev;
|
||||
extern int ip6_inbound_call_ike;
|
||||
extern int ip6_ipsec_ecn;
|
||||
|
||||
extern struct secpolicy *ipsec6_getpolicybysock
|
||||
__P((struct mbuf *, u_int, struct socket *, int *));
|
||||
extern struct secpolicy *ipsec6_getpolicybyaddr
|
||||
__P((struct mbuf *, u_int, int, int *));
|
||||
|
||||
extern int ipsec6_in_reject_so __P((struct mbuf *, struct socket *));
|
||||
extern int ipsec6_delete_pcbpolicy __P((struct inpcb *));
|
||||
extern int ipsec6_set_policy __P((struct inpcb *inp, int optname,
|
||||
caddr_t request, int priv));
|
||||
extern int ipsec6_get_policy
|
||||
__P((struct inpcb *inp, caddr_t request, struct mbuf **mp));
|
||||
extern int ipsec6_in_reject __P((struct mbuf *, struct inpcb *));
|
||||
|
||||
extern size_t ipsec6_hdrsiz __P((struct mbuf *, u_int, struct inpcb *));
|
||||
|
||||
struct ip6_hdr;
|
||||
|
||||
extern const char *ipsec6_logpacketstr __P((struct ip6_hdr *, u_int32_t));
|
||||
extern int ipsec6_output_trans __P((struct ipsec_output_state *, u_char *,
|
||||
struct mbuf *, struct secpolicy *,
|
||||
int, int *));
|
||||
extern int ipsec6_output_tunnel __P((struct ipsec_output_state *,
|
||||
struct secpolicy *, int));
|
||||
extern int ipsec6_tunnel_validate __P((struct ip6_hdr *, u_int,
|
||||
struct secasvar *));
|
||||
|
||||
#endif /*KERNEL*/
|
||||
#endif /* _NETINET6_IPSEC6_H_ */
|
||||
459
sys/netinet6/mld6.c
Normal file
459
sys/netinet6/mld6.c
Normal file
|
|
@ -0,0 +1,459 @@
|
|||
/*
|
||||
* Copyright (C) 1998 WIDE Project.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988 Stephen Deering.
|
||||
* Copyright (c) 1992, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Stephen Deering of Stanford University.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)igmp.c 8.1 (Berkeley) 7/19/93
|
||||
*/
|
||||
|
||||
#include "opt_inet.h"
|
||||
#include "opt_ipsec.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/protosw.h>
|
||||
#include <sys/syslog.h>
|
||||
|
||||
#include <net/if.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_var.h>
|
||||
#include <netinet6/in6.h>
|
||||
#include <netinet6/ip6.h>
|
||||
#include <netinet6/ip6_var.h>
|
||||
#include <netinet6/icmp6.h>
|
||||
#include <netinet6/mld6_var.h>
|
||||
|
||||
#include <net/net_osdep.h>
|
||||
|
||||
/*
|
||||
* Protocol constants
|
||||
*/
|
||||
|
||||
/* denotes that the MLD max response delay field specifies time in milliseconds */
|
||||
#define MLD6_TIMER_SCALE 1000
|
||||
/*
|
||||
* time between repetitions of a node's initial report of interest in a
|
||||
* multicast address(in seconds)
|
||||
*/
|
||||
#define MLD6_UNSOLICITED_REPORT_INTERVAL 10
|
||||
|
||||
static struct ip6_pktopts ip6_opts;
|
||||
static int mld6_timers_are_running;
|
||||
/* XXX: These are necessary for KAME's link-local hack */
|
||||
static struct in6_addr mld6_all_nodes_linklocal =
|
||||
IN6ADDR_LINKLOCAL_ALLNODES_INIT;
|
||||
static struct in6_addr mld6_all_routers_linklocal =
|
||||
IN6ADDR_LINKLOCAL_ALLROUTERS_INIT;
|
||||
|
||||
static void mld6_sendpkt __P((struct in6_multi *, int,
|
||||
const struct in6_addr *));
|
||||
|
||||
void
|
||||
mld6_init()
|
||||
{
|
||||
static u_int8_t hbh_buf[8];
|
||||
struct ip6_hbh *hbh = (struct ip6_hbh *)hbh_buf;
|
||||
u_int16_t rtalert_code = htons((u_int16_t)IP6OPT_RTALERT_MLD);
|
||||
|
||||
mld6_timers_are_running = 0;
|
||||
|
||||
/* ip6h_nxt will be fill in later */
|
||||
hbh->ip6h_len = 0; /* (8 >> 3) - 1*/
|
||||
|
||||
/* XXX: grotty hard coding... */
|
||||
hbh_buf[2] = IP6OPT_PADN; /* 2 byte padding */
|
||||
hbh_buf[3] = 0;
|
||||
hbh_buf[4] = IP6OPT_RTALERT;
|
||||
hbh_buf[5] = IP6OPT_RTALERT_LEN - 2;
|
||||
bcopy((caddr_t)&rtalert_code, &hbh_buf[6], sizeof(u_int16_t));
|
||||
|
||||
ip6_opts.ip6po_hbh = hbh;
|
||||
/* We will specify the hoplimit by a multicast option. */
|
||||
ip6_opts.ip6po_hlim = -1;
|
||||
}
|
||||
|
||||
void
|
||||
mld6_start_listening(in6m)
|
||||
struct in6_multi *in6m;
|
||||
{
|
||||
int s = splnet();
|
||||
|
||||
/*
|
||||
* (draft-ietf-ipngwg-mld, page 10)
|
||||
* The node never sends a Report or Done for the link-scope all-nodes
|
||||
* address.
|
||||
* MLD messages are never sent for multicast addresses whose scope is 0
|
||||
* (reserved) or 1 (node-local).
|
||||
*/
|
||||
mld6_all_nodes_linklocal.s6_addr16[1] =
|
||||
htons(in6m->in6m_ifp->if_index); /* XXX */
|
||||
if (IN6_ARE_ADDR_EQUAL(&in6m->in6m_addr, &mld6_all_nodes_linklocal) ||
|
||||
IPV6_ADDR_MC_SCOPE(&in6m->in6m_addr) < IPV6_ADDR_SCOPE_LINKLOCAL) {
|
||||
in6m->in6m_timer = 0;
|
||||
in6m->in6m_state = MLD6_OTHERLISTENER;
|
||||
} else {
|
||||
mld6_sendpkt(in6m, MLD6_LISTENER_REPORT, NULL);
|
||||
in6m->in6m_timer = MLD6_RANDOM_DELAY(
|
||||
MLD6_UNSOLICITED_REPORT_INTERVAL * PR_FASTHZ);
|
||||
in6m->in6m_state = MLD6_IREPORTEDLAST;
|
||||
mld6_timers_are_running = 1;
|
||||
}
|
||||
splx(s);
|
||||
}
|
||||
|
||||
void
|
||||
mld6_stop_listening(in6m)
|
||||
struct in6_multi *in6m;
|
||||
{
|
||||
mld6_all_nodes_linklocal.s6_addr16[1] =
|
||||
htons(in6m->in6m_ifp->if_index); /* XXX */
|
||||
mld6_all_routers_linklocal.s6_addr16[1] =
|
||||
htons(in6m->in6m_ifp->if_index); /* XXX: necessary when mrouting */
|
||||
|
||||
if (in6m->in6m_state == MLD6_IREPORTEDLAST &&
|
||||
(!IN6_ARE_ADDR_EQUAL(&in6m->in6m_addr, &mld6_all_nodes_linklocal)) &&
|
||||
IPV6_ADDR_MC_SCOPE(&in6m->in6m_addr) > IPV6_ADDR_SCOPE_NODELOCAL)
|
||||
mld6_sendpkt(in6m, MLD6_LISTENER_DONE,
|
||||
&mld6_all_routers_linklocal);
|
||||
}
|
||||
|
||||
void
|
||||
mld6_input(m, off)
|
||||
struct mbuf *m;
|
||||
int off;
|
||||
{
|
||||
struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
|
||||
struct mld6_hdr *mldh = (struct mld6_hdr *)(mtod(m, caddr_t) + off);
|
||||
struct ifnet *ifp = m->m_pkthdr.rcvif;
|
||||
struct in6_multi *in6m;
|
||||
struct in6_ifaddr *ia;
|
||||
struct ifmultiaddr *ifma;
|
||||
int timer; /* timer value in the MLD query header */
|
||||
|
||||
/* source address validation */
|
||||
if (!IN6_IS_ADDR_LINKLOCAL(&ip6->ip6_src)) {
|
||||
log(LOG_ERR,
|
||||
"mld6_input: src %s is not link-local\n",
|
||||
ip6_sprintf(&ip6->ip6_src));
|
||||
/*
|
||||
* spec(draft-ietf-ipngwg-mld) does not explicitly
|
||||
* specify to discard the packet from a non link-local
|
||||
* source address. But we believe it's expected to do so.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* In the MLD6 specification, there are 3 states and a flag.
|
||||
*
|
||||
* In Non-Listener state, we simply don't have a membership record.
|
||||
* In Delaying Listener state, our timer is running (in6m->in6m_timer)
|
||||
* In Idle Listener state, our timer is not running (in6m->in6m_timer==0)
|
||||
*
|
||||
* The flag is in6m->in6m_state, it is set to MLD6_OTHERLISTENER if
|
||||
* we have heard a report from another member, or MLD6_IREPORTEDLAST
|
||||
* if we sent the last report.
|
||||
*/
|
||||
switch(mldh->mld6_type) {
|
||||
case MLD6_LISTENER_QUERY:
|
||||
if (ifp->if_flags & IFF_LOOPBACK)
|
||||
break;
|
||||
|
||||
if (!IN6_IS_ADDR_UNSPECIFIED(&mldh->mld6_addr) &&
|
||||
!IN6_IS_ADDR_MULTICAST(&mldh->mld6_addr))
|
||||
break; /* print error or log stat? */
|
||||
if (IN6_IS_ADDR_MC_LINKLOCAL(&mldh->mld6_addr))
|
||||
mldh->mld6_addr.s6_addr16[1] =
|
||||
htons(ifp->if_index); /* XXX */
|
||||
|
||||
/*
|
||||
* - Start the timers in all of our membership records
|
||||
* that the query applies to for the interface on
|
||||
* which the query arrived excl. those that belong
|
||||
* to the "all-nodes" group (ff02::1).
|
||||
* - Restart any timer that is already running but has
|
||||
* A value longer than the requested timeout.
|
||||
* - Use the value specified in the query message as
|
||||
* the maximum timeout.
|
||||
*/
|
||||
IFP_TO_IA6(ifp, ia);
|
||||
if (ia == NULL)
|
||||
break;
|
||||
|
||||
/*
|
||||
* XXX: System timer resolution is too low to handle Max
|
||||
* Response Delay, so set 1 to the internal timer even if
|
||||
* the calculated value equals to zero when Max Response
|
||||
* Delay is positive.
|
||||
*/
|
||||
timer = ntohs(mldh->mld6_maxdelay)*PR_FASTHZ/MLD6_TIMER_SCALE;
|
||||
if (timer == 0 && mldh->mld6_maxdelay)
|
||||
timer = 1;
|
||||
mld6_all_nodes_linklocal.s6_addr16[1] =
|
||||
htons(ifp->if_index); /* XXX */
|
||||
|
||||
LIST_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link)
|
||||
{
|
||||
if (ifma->ifma_addr->sa_family != AF_INET6)
|
||||
continue;
|
||||
in6m = (struct in6_multi *)ifma->ifma_protospec;
|
||||
if (IN6_ARE_ADDR_EQUAL(&in6m->in6m_addr,
|
||||
&mld6_all_nodes_linklocal) ||
|
||||
IPV6_ADDR_MC_SCOPE(&in6m->in6m_addr) <
|
||||
IPV6_ADDR_SCOPE_LINKLOCAL)
|
||||
continue;
|
||||
|
||||
if (IN6_IS_ADDR_UNSPECIFIED(&mldh->mld6_addr) ||
|
||||
IN6_ARE_ADDR_EQUAL(&mldh->mld6_addr,
|
||||
&in6m->in6m_addr))
|
||||
{
|
||||
if (timer == 0) {
|
||||
/* send a report immediately */
|
||||
mld6_sendpkt(in6m, MLD6_LISTENER_REPORT,
|
||||
NULL);
|
||||
in6m->in6m_timer = 0; /* reset timer */
|
||||
in6m->in6m_state = MLD6_IREPORTEDLAST;
|
||||
} else if (in6m->in6m_timer == 0 || /*idle state*/
|
||||
in6m->in6m_timer > timer) {
|
||||
in6m->in6m_timer =
|
||||
MLD6_RANDOM_DELAY(timer);
|
||||
mld6_timers_are_running = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (IN6_IS_ADDR_MC_LINKLOCAL(&mldh->mld6_addr))
|
||||
mldh->mld6_addr.s6_addr16[1] = 0; /* XXX */
|
||||
break;
|
||||
case MLD6_LISTENER_REPORT:
|
||||
/*
|
||||
* For fast leave to work, we have to know that we are the
|
||||
* last person to send a report for this group. Reports
|
||||
* can potentially get looped back if we are a multicast
|
||||
* router, so discard reports sourced by me.
|
||||
* Note that it is impossible to check IFF_LOOPBACK flag of
|
||||
* ifp for this purpose, since ip6_mloopback pass the physical
|
||||
* interface to looutput.
|
||||
*/
|
||||
if (m->m_flags & M_LOOP) /* XXX: grotty flag, but efficient */
|
||||
break;
|
||||
|
||||
if (!IN6_IS_ADDR_MULTICAST(&mldh->mld6_addr))
|
||||
break;
|
||||
|
||||
if (IN6_IS_ADDR_MC_LINKLOCAL(&mldh->mld6_addr))
|
||||
mldh->mld6_addr.s6_addr16[1] =
|
||||
htons(ifp->if_index); /* XXX */
|
||||
/*
|
||||
* If we belong to the group being reported, stop
|
||||
* our timer for that group.
|
||||
*/
|
||||
IN6_LOOKUP_MULTI(mldh->mld6_addr, ifp, in6m);
|
||||
if (in6m) {
|
||||
in6m->in6m_timer = 0; /* transit to idle state */
|
||||
in6m->in6m_state = MLD6_OTHERLISTENER; /* clear flag */
|
||||
}
|
||||
|
||||
if (IN6_IS_ADDR_MC_LINKLOCAL(&mldh->mld6_addr))
|
||||
mldh->mld6_addr.s6_addr16[1] = 0; /* XXX */
|
||||
break;
|
||||
default: /* this is impossible */
|
||||
log(LOG_ERR, "mld6_input: illegal type(%d)", mldh->mld6_type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
mld6_fasttimeo()
|
||||
{
|
||||
register struct in6_multi *in6m;
|
||||
struct in6_multistep step;
|
||||
int s;
|
||||
|
||||
/*
|
||||
* Quick check to see if any work needs to be done, in order
|
||||
* to minimize the overhead of fasttimo processing.
|
||||
*/
|
||||
if (!mld6_timers_are_running)
|
||||
return;
|
||||
|
||||
s = splnet();
|
||||
mld6_timers_are_running = 0;
|
||||
IN6_FIRST_MULTI(step, in6m);
|
||||
while (in6m != NULL) {
|
||||
if (in6m->in6m_timer == 0) {
|
||||
/* do nothing */
|
||||
} else if (--in6m->in6m_timer == 0) {
|
||||
mld6_sendpkt(in6m, MLD6_LISTENER_REPORT, NULL);
|
||||
in6m->in6m_state = MLD6_IREPORTEDLAST;
|
||||
} else {
|
||||
mld6_timers_are_running = 1;
|
||||
}
|
||||
IN6_NEXT_MULTI(step, in6m);
|
||||
}
|
||||
splx(s);
|
||||
}
|
||||
|
||||
static void
|
||||
mld6_sendpkt(in6m, type, dst)
|
||||
struct in6_multi *in6m;
|
||||
int type;
|
||||
const struct in6_addr *dst;
|
||||
{
|
||||
struct mbuf *mh, *md;
|
||||
struct mld6_hdr *mldh;
|
||||
struct ip6_hdr *ip6;
|
||||
struct ip6_moptions im6o;
|
||||
struct in6_ifaddr *ia;
|
||||
struct ifnet *ifp = in6m->in6m_ifp;
|
||||
struct ifnet *outif = NULL;
|
||||
|
||||
/*
|
||||
* At first, find a link local address on the outgoing interface
|
||||
* to use as the source address of the MLD packet.
|
||||
*/
|
||||
if ((ia = in6ifa_ifpforlinklocal(ifp)) == NULL)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Allocate mbufs to store ip6 header and MLD header.
|
||||
* We allocate 2 mbufs and make chain in advance because
|
||||
* it is more convenient when inserting the hop-by-hop option later.
|
||||
*/
|
||||
MGETHDR(mh, M_DONTWAIT, MT_HEADER);
|
||||
if (mh == NULL)
|
||||
return;
|
||||
MGET(md, M_DONTWAIT, MT_DATA);
|
||||
if (md == NULL) {
|
||||
m_free(mh);
|
||||
return;
|
||||
}
|
||||
mh->m_next = md;
|
||||
|
||||
#ifdef IPSEC
|
||||
mh->m_pkthdr.rcvif = NULL;
|
||||
#endif
|
||||
mh->m_pkthdr.len = sizeof(struct ip6_hdr) + sizeof(struct mld6_hdr);
|
||||
mh->m_len = sizeof(struct ip6_hdr);
|
||||
MH_ALIGN(mh, sizeof(struct ip6_hdr));
|
||||
|
||||
/* fill in the ip6 header */
|
||||
ip6 = mtod(mh, struct ip6_hdr *);
|
||||
ip6->ip6_flow = 0;
|
||||
ip6->ip6_vfc = IPV6_VERSION;
|
||||
/* ip6_plen will be set later */
|
||||
ip6->ip6_nxt = IPPROTO_ICMPV6;
|
||||
/* ip6_hlim will be set by im6o.im6o_multicast_hlim */
|
||||
ip6->ip6_src = ia->ia_addr.sin6_addr;
|
||||
ip6->ip6_dst = dst ? *dst : in6m->in6m_addr;
|
||||
|
||||
/* fill in the MLD header */
|
||||
md->m_len = sizeof(struct mld6_hdr);
|
||||
mldh = mtod(md, struct mld6_hdr *);
|
||||
mldh->mld6_type = type;
|
||||
mldh->mld6_code = 0;
|
||||
mldh->mld6_cksum = 0;
|
||||
/* XXX: we assume the function will not be called for query messages */
|
||||
mldh->mld6_maxdelay = 0;
|
||||
mldh->mld6_reserved = 0;
|
||||
mldh->mld6_addr = in6m->in6m_addr;
|
||||
if (IN6_IS_ADDR_MC_LINKLOCAL(&mldh->mld6_addr))
|
||||
mldh->mld6_addr.s6_addr16[1] = 0; /* XXX */
|
||||
mldh->mld6_cksum = in6_cksum(mh, IPPROTO_ICMPV6, sizeof(struct ip6_hdr),
|
||||
sizeof(struct mld6_hdr));
|
||||
|
||||
/* construct multicast option */
|
||||
bzero(&im6o, sizeof(im6o));
|
||||
im6o.im6o_multicast_ifp = ifp;
|
||||
im6o.im6o_multicast_hlim = 1;
|
||||
|
||||
/*
|
||||
* Request loopback of the report if we are acting as a multicast
|
||||
* router, so that the process-level routing daemon can hear it.
|
||||
*/
|
||||
im6o.im6o_multicast_loop = 0;
|
||||
|
||||
/* increment output statictics */
|
||||
icmp6stat.icp6s_outhist[type]++;
|
||||
|
||||
ip6_output(mh, &ip6_opts, NULL, 0, &im6o, &outif);
|
||||
if (outif) {
|
||||
icmp6_ifstat_inc(outif, ifs6_out_msg);
|
||||
switch(type) {
|
||||
case MLD6_LISTENER_QUERY:
|
||||
icmp6_ifstat_inc(outif, ifs6_out_mldquery);
|
||||
break;
|
||||
case MLD6_LISTENER_REPORT:
|
||||
icmp6_ifstat_inc(outif, ifs6_out_mldreport);
|
||||
break;
|
||||
case MLD6_LISTENER_DONE:
|
||||
icmp6_ifstat_inc(outif, ifs6_out_mlddone);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
52
sys/netinet6/mld6_var.h
Normal file
52
sys/netinet6/mld6_var.h
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright (C) 1998 WIDE Project.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _NETINET6_MLD6_VAR_H_
|
||||
#define _NETINET6_MLD6_VAR_H_
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
#define MLD6_RANDOM_DELAY(X) (random() % (X) + 1)
|
||||
|
||||
/*
|
||||
* States for MLD stop-listening processing
|
||||
*/
|
||||
#define MLD6_OTHERLISTENER 0
|
||||
#define MLD6_IREPORTEDLAST 1
|
||||
|
||||
void mld6_init __P((void));
|
||||
void mld6_input __P((struct mbuf *, int));
|
||||
void mld6_start_listening __P((struct in6_multi *));
|
||||
void mld6_stop_listening __P((struct in6_multi *));
|
||||
void mld6_fasttimeo __P((void));
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#endif /* _NETINET6_MLD6_VAR_H_ */
|
||||
1531
sys/netinet6/nd6.c
Normal file
1531
sys/netinet6/nd6.c
Normal file
File diff suppressed because it is too large
Load diff
302
sys/netinet6/nd6.h
Normal file
302
sys/netinet6/nd6.h
Normal file
|
|
@ -0,0 +1,302 @@
|
|||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _NETINET6_ND6_H_
|
||||
#define _NETINET6_ND6_H_
|
||||
|
||||
#include <sys/queue.h>
|
||||
|
||||
struct llinfo_nd6 {
|
||||
struct llinfo_nd6 *ln_next;
|
||||
struct llinfo_nd6 *ln_prev;
|
||||
struct rtentry *ln_rt;
|
||||
struct mbuf *ln_hold; /* last packet until resolved/timeout */
|
||||
long ln_asked; /* number of queries already sent for this addr */
|
||||
u_long ln_expire; /* lifetime for NDP state transition */
|
||||
short ln_state; /* reachability state */
|
||||
short ln_router; /* 2^0: ND6 router bit */
|
||||
};
|
||||
|
||||
#define ND6_LLINFO_NOSTATE -2
|
||||
#define ND6_LLINFO_WAITDELETE -1
|
||||
#define ND6_LLINFO_INCOMPLETE 0
|
||||
#define ND6_LLINFO_REACHABLE 1
|
||||
#define ND6_LLINFO_STALE 2
|
||||
#define ND6_LLINFO_DELAY 3
|
||||
#define ND6_LLINFO_PROBE 4
|
||||
|
||||
struct nd_ifinfo {
|
||||
u_int32_t linkmtu; /* LinkMTU */
|
||||
u_int32_t maxmtu; /* Upper bound of LinkMTU */
|
||||
u_int32_t basereachable; /* BaseReachableTime */
|
||||
u_int32_t reachable; /* Reachable Time */
|
||||
u_int32_t retrans; /* Retrans Timer */
|
||||
int recalctm; /* BaseReacable re-calculation timer */
|
||||
u_int8_t chlim; /* CurHopLimit */
|
||||
u_int8_t receivedra;
|
||||
};
|
||||
|
||||
struct in6_nbrinfo {
|
||||
char ifname[IFNAMSIZ]; /* if name, e.g. "en0" */
|
||||
struct in6_addr addr; /* IPv6 address of the neighbor */
|
||||
long asked; /* number of queries already sent for this addr */
|
||||
int isrouter; /* if it acts as a router */
|
||||
int state; /* reachability state */
|
||||
int expire; /* lifetime for NDP state transition */
|
||||
};
|
||||
|
||||
#define DRLSTSIZ 10
|
||||
#define PRLSTSIZ 10
|
||||
struct in6_drlist {
|
||||
char ifname[IFNAMSIZ];
|
||||
struct {
|
||||
struct in6_addr rtaddr;
|
||||
u_char flags;
|
||||
u_short rtlifetime;
|
||||
u_long expire;
|
||||
u_short if_index;
|
||||
} defrouter[DRLSTSIZ];
|
||||
};
|
||||
|
||||
struct in6_prlist {
|
||||
char ifname[IFNAMSIZ];
|
||||
struct {
|
||||
struct in6_addr prefix;
|
||||
struct prf_ra raflags;
|
||||
u_char prefixlen;
|
||||
u_long vltime;
|
||||
u_long pltime;
|
||||
u_long expire;
|
||||
u_short if_index;
|
||||
u_short advrtrs; /* number of advertisement routers */
|
||||
struct in6_addr advrtr[DRLSTSIZ]; /* XXX: explicit limit */
|
||||
} prefix[PRLSTSIZ];
|
||||
};
|
||||
|
||||
struct in6_ndireq {
|
||||
char ifname[IFNAMSIZ];
|
||||
struct nd_ifinfo ndi;
|
||||
};
|
||||
|
||||
/* protocol constants */
|
||||
#define MAX_RTR_SOLICITATION_DELAY 1 /*1sec*/
|
||||
#define RTR_SOLICITATION_INTERVAL 4 /*4sec*/
|
||||
#define MAX_RTR_SOLICITATIONS 3
|
||||
|
||||
#define ND6_INFINITE_LIFETIME 0xffffffff
|
||||
|
||||
#ifdef _KERNEL
|
||||
/* node constants */
|
||||
#define MAX_REACHABLE_TIME 3600000 /* msec */
|
||||
#define REACHABLE_TIME 30000 /* msec */
|
||||
#define RETRANS_TIMER 1000 /* msec */
|
||||
#define MIN_RANDOM_FACTOR 512 /* 1024 * 0.5 */
|
||||
#define MAX_RANDOM_FACTOR 1536 /* 1024 * 1.5 */
|
||||
#define ND_COMPUTE_RTIME(x) \
|
||||
(((MIN_RANDOM_FACTOR * (x >> 10)) + (random() & \
|
||||
((MAX_RANDOM_FACTOR - MIN_RANDOM_FACTOR) * (x >> 10)))) /1000)
|
||||
|
||||
struct nd_defrouter {
|
||||
LIST_ENTRY(nd_defrouter) dr_entry;
|
||||
#define dr_next dr_entry.le_next
|
||||
struct in6_addr rtaddr;
|
||||
u_char flags;
|
||||
u_short rtlifetime;
|
||||
u_long expire;
|
||||
struct ifnet *ifp;
|
||||
};
|
||||
|
||||
struct nd_prefix {
|
||||
struct ifnet *ndpr_ifp;
|
||||
LIST_ENTRY(nd_prefix) ndpr_entry;
|
||||
struct sockaddr_in6 ndpr_prefix; /* prefix */
|
||||
struct in6_addr ndpr_mask; /* netmask derived from the prefix */
|
||||
struct in6_addr ndpr_addr; /* address that is derived from the prefix */
|
||||
u_int32_t ndpr_vltime; /* advertised valid lifetime */
|
||||
u_int32_t ndpr_pltime; /* advertised preferred lifetime */
|
||||
time_t ndpr_expire; /* expiration time of the prefix */
|
||||
time_t ndpr_preferred; /* preferred time of the prefix */
|
||||
struct prf_ra ndpr_flags;
|
||||
/* list of routers that advertise the prefix: */
|
||||
LIST_HEAD(pr_rtrhead, nd_pfxrouter) ndpr_advrtrs;
|
||||
u_char ndpr_plen;
|
||||
struct ndpr_stateflags {
|
||||
/* if this prefix can be regarded as on-link */
|
||||
u_char onlink : 1;
|
||||
} ndpr_stateflags;
|
||||
};
|
||||
|
||||
#define ndpr_next ndpr_entry.le_next
|
||||
|
||||
#define ndpr_raf ndpr_flags
|
||||
#define ndpr_raf_onlink ndpr_flags.onlink
|
||||
#define ndpr_raf_auto ndpr_flags.autonomous
|
||||
|
||||
#define ndpr_statef_onlink ndpr_stateflags.onlink
|
||||
#define ndpr_statef_addmark ndpr_stateflags.addmark
|
||||
|
||||
/*
|
||||
* We keep expired prefix for certain amount of time, for validation purposes.
|
||||
* 1800s = MaxRtrAdvInterval
|
||||
*/
|
||||
#define NDPR_KEEP_EXPIRED (1800 * 2)
|
||||
|
||||
/*
|
||||
* Message format for use in obtaining information about prefixes
|
||||
* from inet6 sysctl function
|
||||
*/
|
||||
struct inet6_ndpr_msghdr {
|
||||
u_short inpm_msglen; /* to skip over non-understood messages */
|
||||
u_char inpm_version; /* future binary compatability */
|
||||
u_char inpm_type; /* message type */
|
||||
struct in6_addr inpm_prefix;
|
||||
u_long prm_vltim;
|
||||
u_long prm_pltime;
|
||||
u_long prm_expire;
|
||||
u_long prm_preferred;
|
||||
struct in6_prflags prm_flags;
|
||||
u_short prm_index; /* index for associated ifp */
|
||||
u_char prm_plen; /* length of prefix in bits */
|
||||
};
|
||||
|
||||
#define prm_raf_onlink prm_flags.prf_ra.onlink
|
||||
#define prm_raf_auto prm_flags.prf_ra.autonomous
|
||||
|
||||
#define prm_statef_onlink prm_flags.prf_state.onlink
|
||||
|
||||
#define prm_rrf_decrvalid prm_flags.prf_rr.decrvalid
|
||||
#define prm_rrf_decrprefd prm_flags.prf_rr.decrprefd
|
||||
|
||||
#define ifpr2ndpr(ifpr) ((struct nd_prefix *)(ifpr))
|
||||
#define ndpr2ifpr(ndpr) ((struct ifprefix *)(ndpr))
|
||||
|
||||
struct nd_pfxrouter {
|
||||
LIST_ENTRY(nd_pfxrouter) pfr_entry;
|
||||
#define pfr_next pfr_entry.le_next
|
||||
struct nd_defrouter *router;
|
||||
};
|
||||
|
||||
LIST_HEAD(nd_drhead, nd_defrouter);
|
||||
LIST_HEAD(nd_prhead, nd_prefix);
|
||||
|
||||
/* nd6.c */
|
||||
extern int nd6_prune;
|
||||
extern int nd6_delay;
|
||||
extern int nd6_umaxtries;
|
||||
extern int nd6_mmaxtries;
|
||||
extern int nd6_useloopback;
|
||||
extern int nd6_proxyall;
|
||||
extern struct llinfo_nd6 llinfo_nd6;
|
||||
extern struct nd_ifinfo *nd_ifinfo;
|
||||
extern struct nd_drhead nd_defrouter;
|
||||
extern struct nd_prhead nd_prefix;
|
||||
|
||||
union nd_opts {
|
||||
struct nd_opt_hdr *nd_opt_array[9];
|
||||
struct {
|
||||
struct nd_opt_hdr *zero;
|
||||
struct nd_opt_hdr *src_lladdr;
|
||||
struct nd_opt_hdr *tgt_lladdr;
|
||||
struct nd_opt_prefix_info *pi_beg;/* multiple opts, start */
|
||||
struct nd_opt_rd_hdr *rh;
|
||||
struct nd_opt_mtu *mtu;
|
||||
struct nd_opt_hdr *search; /* multiple opts */
|
||||
struct nd_opt_hdr *last; /* multiple opts */
|
||||
int done;
|
||||
struct nd_opt_prefix_info *pi_end;/* multiple opts, end */
|
||||
} nd_opt_each;
|
||||
};
|
||||
#define nd_opts_src_lladdr nd_opt_each.src_lladdr
|
||||
#define nd_opts_tgt_lladdr nd_opt_each.tgt_lladdr
|
||||
#define nd_opts_pi nd_opt_each.pi_beg
|
||||
#define nd_opts_pi_end nd_opt_each.pi_end
|
||||
#define nd_opts_rh nd_opt_each.rh
|
||||
#define nd_opts_mtu nd_opt_each.mtu
|
||||
#define nd_opts_search nd_opt_each.search
|
||||
#define nd_opts_last nd_opt_each.last
|
||||
#define nd_opts_done nd_opt_each.done
|
||||
|
||||
/* XXX: need nd6_var.h?? */
|
||||
/* nd6.c */
|
||||
void nd6_init __P((void));
|
||||
void nd6_ifattach __P((struct ifnet *));
|
||||
int nd6_is_addr_neighbor __P((struct in6_addr *, struct ifnet *));
|
||||
void nd6_option_init __P((void *, int, union nd_opts *));
|
||||
struct nd_opt_hdr *nd6_option __P((union nd_opts *));
|
||||
int nd6_options __P((union nd_opts *));
|
||||
struct rtentry *nd6_lookup __P((struct in6_addr *, int, struct ifnet *));
|
||||
void nd6_setmtu __P((struct ifnet *));
|
||||
void nd6_timer __P((void *));
|
||||
void nd6_free __P((struct rtentry *));
|
||||
void nd6_nud_hint __P((struct rtentry *, struct in6_addr *));
|
||||
int nd6_resolve __P((struct ifnet *, struct rtentry *,
|
||||
struct mbuf *, struct sockaddr *, u_char *));
|
||||
void nd6_rtrequest __P((int, struct rtentry *, struct sockaddr *));
|
||||
void nd6_p2p_rtrequest __P((int, struct rtentry *, struct sockaddr *));
|
||||
int nd6_ioctl __P((u_long, caddr_t, struct ifnet *));
|
||||
struct rtentry *nd6_cache_lladdr __P((struct ifnet *, struct in6_addr *,
|
||||
char *, int, int, int));
|
||||
/* for test */
|
||||
int nd6_output __P((struct ifnet *, struct mbuf *, struct sockaddr_in6 *,
|
||||
struct rtentry *));
|
||||
int nd6_storelladdr __P((struct ifnet *, struct rtentry *, struct mbuf *,
|
||||
struct sockaddr *, u_char *));
|
||||
|
||||
/* nd6_nbr.c */
|
||||
void nd6_na_input __P((struct mbuf *, int, int));
|
||||
void nd6_na_output __P((struct ifnet *, struct in6_addr *,
|
||||
struct in6_addr *, u_long, int));
|
||||
void nd6_ns_input __P((struct mbuf *, int, int));
|
||||
void nd6_ns_output __P((struct ifnet *, struct in6_addr *,
|
||||
struct in6_addr *, struct llinfo_nd6 *, int));
|
||||
caddr_t nd6_ifptomac __P((struct ifnet *));
|
||||
void nd6_dad_start __P((struct ifaddr *, int *));
|
||||
void nd6_dad_duplicated __P((struct ifaddr *));
|
||||
|
||||
/* nd6_rtr.c */
|
||||
void nd6_rs_input __P((struct mbuf *, int, int));
|
||||
void nd6_ra_input __P((struct mbuf *, int, int));
|
||||
void prelist_del __P((struct nd_prefix *));
|
||||
void defrouter_addreq __P((struct nd_defrouter *));
|
||||
void defrouter_delreq __P((struct nd_defrouter *, int));
|
||||
void defrtrlist_del __P((struct nd_defrouter *));
|
||||
void prelist_remove __P((struct nd_prefix *));
|
||||
int prelist_update __P((struct nd_prefix *, struct nd_defrouter *,
|
||||
struct mbuf *));
|
||||
struct nd_defrouter *defrouter_lookup __P((struct in6_addr *,
|
||||
struct ifnet *));
|
||||
int in6_ifdel __P((struct ifnet *, struct in6_addr *));
|
||||
int in6_init_prefix_ltimes __P((struct nd_prefix *ndpr));
|
||||
void rt6_flush __P((struct in6_addr *, struct ifnet *));
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#endif /* _NETINET6_ND6_H_ */
|
||||
1123
sys/netinet6/nd6_nbr.c
Normal file
1123
sys/netinet6/nd6_nbr.c
Normal file
File diff suppressed because it is too large
Load diff
1243
sys/netinet6/nd6_rtr.c
Normal file
1243
sys/netinet6/nd6_rtr.c
Normal file
File diff suppressed because it is too large
Load diff
68
sys/netinet6/pim6.h
Normal file
68
sys/netinet6/pim6.h
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Copyright (C) 1998 WIDE Project.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
/*
|
||||
* Protocol Independent Multicast (PIM) definitions
|
||||
*
|
||||
* Written by Ahmed Helmy, SGI, July 1996
|
||||
*
|
||||
* MULTICAST
|
||||
*/
|
||||
|
||||
/*
|
||||
* PIM packet header
|
||||
*/
|
||||
#define PIM_VERSION 2
|
||||
struct pim {
|
||||
#if defined(BYTE_ORDER) && (BYTE_ORDER == LITTLE_ENDIAN)
|
||||
u_char pim_type:4, /* the PIM message type, currently they are:
|
||||
* Hello, Register, Register-Stop, Join/Prune,
|
||||
* Bootstrap, Assert, Graft (PIM-DM only),
|
||||
* Graft-Ack (PIM-DM only), C-RP-Adv
|
||||
*/
|
||||
pim_ver:4; /* PIM version number; 2 for PIMv2 */
|
||||
#else
|
||||
u_char pim_ver:4, /* PIM version */
|
||||
pim_type:4; /* PIM type */
|
||||
#endif
|
||||
u_char pim_rsv; /* Reserved */
|
||||
u_short pim_cksum; /* IP style check sum */
|
||||
};
|
||||
|
||||
#define PIM_MINLEN 8 /* The header min. length is 8 */
|
||||
#define PIM6_REG_MINLEN (PIM_MINLEN+40) /* Register message + inner IP6 header */
|
||||
|
||||
/*
|
||||
* Message types
|
||||
*/
|
||||
#define PIM_REGISTER 1 /* PIM Register type is 1 */
|
||||
|
||||
/* second bit in reg_head is the null bit */
|
||||
#define PIM_NULL_REGISTER 0x40000000
|
||||
71
sys/netinet6/pim6_var.h
Normal file
71
sys/netinet6/pim6_var.h
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Copyright (C) 1998 WIDE Project.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
/* $Id: pim6_var.h,v 1.2 1999/08/01 15:58:13 itojun Exp $ */
|
||||
|
||||
#ifndef _NETINET6_PIM6_VAR_H_
|
||||
#define _NETINET6_PIM6_VAR_H_
|
||||
|
||||
/*
|
||||
* Protocol Independent Multicast (PIM),
|
||||
* implementation-specific definitions.
|
||||
*
|
||||
* Written by George Edmond Eddy (Rusty), ISI, February 1998
|
||||
* Modified by Pavlin Ivanov Radoslavov, USC/ISI, May 1998
|
||||
*/
|
||||
|
||||
struct pim6stat {
|
||||
u_int pim6s_rcv_total; /* total PIM messages received */
|
||||
u_int pim6s_rcv_tooshort; /* received with too few bytes */
|
||||
u_int pim6s_rcv_badsum; /* received with bad checksum */
|
||||
u_int pim6s_rcv_badversion; /* received bad PIM version */
|
||||
u_int pim6s_rcv_registers; /* received registers */
|
||||
u_int pim6s_rcv_badregisters; /* received invalid registers */
|
||||
u_int pim6s_snd_registers; /* sent registers */
|
||||
};
|
||||
|
||||
#if (defined(KERNEL)) || (defined(_KERNEL))
|
||||
extern struct pim6stat pim6stat;
|
||||
|
||||
int pim6_input __P((struct mbuf **, int*, int));
|
||||
#endif /* KERNEL */
|
||||
|
||||
/*
|
||||
* Names for PIM sysctl objects
|
||||
*/
|
||||
#define PIMCTL_STATS 1 /* statistics (read-only) */
|
||||
#define PIMCTL_MAXID 2
|
||||
|
||||
#define PIMCTL_NAMES { \
|
||||
{ 0, 0 }, \
|
||||
{ 0, 0 }, \
|
||||
}
|
||||
|
||||
#endif /* _NETINET6_PIM6_VAR_H_ */
|
||||
612
sys/netinet6/raw_ip6.c
Normal file
612
sys/netinet6/raw_ip6.c
Normal file
|
|
@ -0,0 +1,612 @@
|
|||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1982, 1986, 1988, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)raw_ip.c 8.2 (Berkeley) 1/4/94
|
||||
*/
|
||||
|
||||
#include "opt_inet.h"
|
||||
#include "opt_ipsec.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/protosw.h>
|
||||
#include <sys/socketvar.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/systm.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/route.h>
|
||||
#include <net/if_types.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_var.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet6/ip6.h>
|
||||
#include <netinet6/ip6_var.h>
|
||||
#include <netinet6/icmp6.h>
|
||||
#include <netinet/in_pcb.h>
|
||||
#include <netinet6/in6_pcb.h>
|
||||
#include <netinet6/nd6.h>
|
||||
|
||||
#ifdef IPSEC
|
||||
#include <netinet6/ipsec.h>
|
||||
#ifdef INET6
|
||||
#include <netinet6/ipsec6.h>
|
||||
#endif /* INET6 */
|
||||
#endif /*IPSEC*/
|
||||
|
||||
#include <machine/stdarg.h>
|
||||
|
||||
/* #include "faith.h" */
|
||||
|
||||
#define satosin6(sa) ((struct sockaddr_in6 *)(sa))
|
||||
#define ifatoia6(ifa) ((struct in6_ifaddr *)(ifa))
|
||||
|
||||
/*
|
||||
* Raw interface to IP6 protocol.
|
||||
*/
|
||||
|
||||
extern struct inpcbhead ripcb;
|
||||
extern struct inpcbinfo ripcbinfo;
|
||||
extern u_long rip_sendspace;
|
||||
extern u_long rip_recvspace;
|
||||
|
||||
/*
|
||||
* Setup generic address and protocol structures
|
||||
* for raw_input routine, then pass them along with
|
||||
* mbuf chain.
|
||||
*/
|
||||
int
|
||||
rip6_input(mp, offp, proto)
|
||||
struct mbuf **mp;
|
||||
int *offp, proto;
|
||||
{
|
||||
struct mbuf *m = *mp;
|
||||
register struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
|
||||
register struct inpcb *in6p;
|
||||
struct inpcb *last = 0;
|
||||
struct mbuf *opts = 0;
|
||||
struct sockaddr_in6 rip6src;
|
||||
|
||||
#if defined(NFAITH) && 0 < NFAITH
|
||||
if (m->m_pkthdr.rcvif) {
|
||||
if (m->m_pkthdr.rcvif->if_type == IFT_FAITH) {
|
||||
/* XXX send icmp6 host/port unreach? */
|
||||
m_freem(m);
|
||||
return IPPROTO_DONE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
init_sin6(&rip6src, m); /* general init */
|
||||
|
||||
LIST_FOREACH(in6p, &ripcb, inp_list) {
|
||||
if ((in6p->in6p_vflag & INP_IPV6) == NULL)
|
||||
continue;
|
||||
if (in6p->in6p_ip6_nxt &&
|
||||
in6p->in6p_ip6_nxt != proto)
|
||||
continue;
|
||||
if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_laddr) &&
|
||||
!IN6_ARE_ADDR_EQUAL(&in6p->in6p_laddr, &ip6->ip6_dst))
|
||||
continue;
|
||||
if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_faddr) &&
|
||||
!IN6_ARE_ADDR_EQUAL(&in6p->in6p_faddr, &ip6->ip6_src))
|
||||
continue;
|
||||
if (in6p->in6p_cksum != -1
|
||||
&& in6_cksum(m, ip6->ip6_nxt, *offp,
|
||||
m->m_pkthdr.len - *offp)) {
|
||||
/* XXX bark something */
|
||||
continue;
|
||||
}
|
||||
if (last) {
|
||||
struct mbuf *n = m_copy(m, 0, (int)M_COPYALL);
|
||||
if (n) {
|
||||
if (last->in6p_flags & IN6P_CONTROLOPTS ||
|
||||
last->in6p_socket->so_options & SO_TIMESTAMP)
|
||||
ip6_savecontrol(last, &opts, ip6, n);
|
||||
/* strip intermediate headers */
|
||||
m_adj(n, *offp);
|
||||
if (sbappendaddr(&last->in6p_socket->so_rcv,
|
||||
(struct sockaddr *)&rip6src,
|
||||
n, opts) == 0) {
|
||||
/* should notify about lost packet */
|
||||
m_freem(n);
|
||||
if (opts)
|
||||
m_freem(opts);
|
||||
} else
|
||||
sorwakeup(last->in6p_socket);
|
||||
opts = NULL;
|
||||
}
|
||||
}
|
||||
last = in6p;
|
||||
}
|
||||
if (last) {
|
||||
if (last->in6p_flags & IN6P_CONTROLOPTS ||
|
||||
last->in6p_socket->so_options & SO_TIMESTAMP)
|
||||
ip6_savecontrol(last, &opts, ip6, m);
|
||||
/* strip intermediate headers */
|
||||
m_adj(m, *offp);
|
||||
if (sbappendaddr(&last->in6p_socket->so_rcv,
|
||||
(struct sockaddr *)&rip6src, m, opts) == 0) {
|
||||
m_freem(m);
|
||||
if (opts)
|
||||
m_freem(opts);
|
||||
} else
|
||||
sorwakeup(last->in6p_socket);
|
||||
} else {
|
||||
if (proto == IPPROTO_NONE)
|
||||
m_freem(m);
|
||||
else {
|
||||
char *prvnxtp = ip6_get_prevhdr(m, *offp); /* XXX */
|
||||
icmp6_error(m, ICMP6_PARAM_PROB,
|
||||
ICMP6_PARAMPROB_NEXTHEADER,
|
||||
prvnxtp - mtod(m, char *));
|
||||
}
|
||||
ip6stat.ip6s_delivered--;
|
||||
}
|
||||
return IPPROTO_DONE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate IPv6 header and pass packet to ip6_output.
|
||||
* Tack on options user may have setup with control call.
|
||||
*/
|
||||
int
|
||||
#if __STDC__
|
||||
rip6_output(struct mbuf *m, ...)
|
||||
#else
|
||||
rip6_output(m, va_alist)
|
||||
struct mbuf *m;
|
||||
va_dcl
|
||||
#endif
|
||||
{
|
||||
struct socket *so;
|
||||
struct sockaddr_in6 *dstsock;
|
||||
struct mbuf *control;
|
||||
struct in6_addr *dst;
|
||||
struct ip6_hdr *ip6;
|
||||
struct inpcb *in6p;
|
||||
u_int plen = m->m_pkthdr.len;
|
||||
int error = 0;
|
||||
struct ip6_pktopts opt, *optp = 0;
|
||||
struct ifnet *oifp = NULL;
|
||||
int type = 0, code = 0; /* for ICMPv6 output statistics only */
|
||||
int priv = 0;
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, m);
|
||||
so = va_arg(ap, struct socket *);
|
||||
dstsock = va_arg(ap, struct sockaddr_in6 *);
|
||||
control = va_arg(ap, struct mbuf *);
|
||||
va_end(ap);
|
||||
|
||||
in6p = sotoin6pcb(so);
|
||||
|
||||
priv = 0;
|
||||
if (so->so_cred->cr_uid == 0)
|
||||
priv = 1;
|
||||
dst = &dstsock->sin6_addr;
|
||||
if (control) {
|
||||
if ((error = ip6_setpktoptions(control, &opt, priv)) != 0)
|
||||
goto bad;
|
||||
optp = &opt;
|
||||
} else
|
||||
optp = in6p->in6p_outputopts;
|
||||
|
||||
/*
|
||||
* For an ICMPv6 packet, we should know its type and code
|
||||
* to update statistics.
|
||||
*/
|
||||
if (so->so_proto->pr_protocol == IPPROTO_ICMPV6) {
|
||||
struct icmp6_hdr *icmp6;
|
||||
if (m->m_len < sizeof(struct icmp6_hdr) &&
|
||||
(m = m_pullup(m, sizeof(struct icmp6_hdr))) == NULL) {
|
||||
error = ENOBUFS;
|
||||
goto bad;
|
||||
}
|
||||
icmp6 = mtod(m, struct icmp6_hdr *);
|
||||
type = icmp6->icmp6_type;
|
||||
code = icmp6->icmp6_code;
|
||||
}
|
||||
|
||||
M_PREPEND(m, sizeof(*ip6), M_WAIT);
|
||||
ip6 = mtod(m, struct ip6_hdr *);
|
||||
|
||||
/*
|
||||
* Next header might not be ICMP6 but use its pseudo header anyway.
|
||||
*/
|
||||
ip6->ip6_dst = *dst;
|
||||
|
||||
/*
|
||||
* If the scope of the destination is link-local, embed the interface
|
||||
* index in the address.
|
||||
*
|
||||
* XXX advanced-api value overrides sin6_scope_id
|
||||
*/
|
||||
if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst)) {
|
||||
struct in6_pktinfo *pi;
|
||||
|
||||
/*
|
||||
* XXX Boundary check is assumed to be already done in
|
||||
* ip6_setpktoptions().
|
||||
*/
|
||||
if (optp && (pi = optp->ip6po_pktinfo) && pi->ipi6_ifindex) {
|
||||
ip6->ip6_dst.s6_addr16[1] = htons(pi->ipi6_ifindex);
|
||||
oifp = ifindex2ifnet[pi->ipi6_ifindex];
|
||||
} else if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst) &&
|
||||
in6p->in6p_moptions &&
|
||||
in6p->in6p_moptions->im6o_multicast_ifp) {
|
||||
oifp = in6p->in6p_moptions->im6o_multicast_ifp;
|
||||
ip6->ip6_dst.s6_addr16[1] = htons(oifp->if_index);
|
||||
} else if (dstsock->sin6_scope_id) {
|
||||
/* boundary check */
|
||||
if (dstsock->sin6_scope_id < 0
|
||||
|| if_index < dstsock->sin6_scope_id) {
|
||||
error = ENXIO; /* XXX EINVAL? */
|
||||
goto bad;
|
||||
}
|
||||
ip6->ip6_dst.s6_addr16[1]
|
||||
= htons(dstsock->sin6_scope_id & 0xffff);/*XXX*/
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Source address selection.
|
||||
*/
|
||||
{
|
||||
struct in6_addr *in6a;
|
||||
|
||||
if ((in6a = in6_selectsrc(dstsock, optp,
|
||||
in6p->in6p_moptions,
|
||||
&in6p->in6p_route,
|
||||
&in6p->in6p_laddr,
|
||||
&error)) == 0) {
|
||||
if (error == 0)
|
||||
error = EADDRNOTAVAIL;
|
||||
goto bad;
|
||||
}
|
||||
ip6->ip6_src = *in6a;
|
||||
if (in6p->in6p_route.ro_rt)
|
||||
oifp = ifindex2ifnet[in6p->in6p_route.ro_rt->rt_ifp->if_index];
|
||||
}
|
||||
|
||||
ip6->ip6_flow = in6p->in6p_flowinfo & IPV6_FLOWINFO_MASK;
|
||||
ip6->ip6_vfc = IPV6_VERSION;
|
||||
/* ip6_plen will be filled in ip6_output, so not fill it here. */
|
||||
ip6->ip6_nxt = in6p->in6p_ip6_nxt;
|
||||
ip6->ip6_hlim = in6_selecthlim(in6p, oifp);
|
||||
|
||||
if (so->so_proto->pr_protocol == IPPROTO_ICMPV6 ||
|
||||
in6p->in6p_cksum != -1) {
|
||||
struct mbuf *n;
|
||||
int off;
|
||||
u_int16_t *p;
|
||||
|
||||
#define offsetof(type, member) ((size_t)(&((type *)0)->member)) /* XXX */
|
||||
|
||||
/* compute checksum */
|
||||
if (so->so_proto->pr_protocol == IPPROTO_ICMPV6)
|
||||
off = offsetof(struct icmp6_hdr, icmp6_cksum);
|
||||
else
|
||||
off = in6p->in6p_cksum;
|
||||
if (plen < off + 1) {
|
||||
error = EINVAL;
|
||||
goto bad;
|
||||
}
|
||||
off += sizeof(struct ip6_hdr);
|
||||
|
||||
n = m;
|
||||
while (n && n->m_len <= off) {
|
||||
off -= n->m_len;
|
||||
n = n->m_next;
|
||||
}
|
||||
if (!n)
|
||||
goto bad;
|
||||
p = (u_int16_t *)(mtod(n, caddr_t) + off);
|
||||
*p = 0;
|
||||
*p = in6_cksum(m, ip6->ip6_nxt, sizeof(*ip6), plen);
|
||||
}
|
||||
|
||||
#ifdef IPSEC
|
||||
m->m_pkthdr.rcvif = (struct ifnet *)so;
|
||||
#endif /*IPSEC*/
|
||||
|
||||
error = ip6_output(m, optp, &in6p->in6p_route, 0, in6p->in6p_moptions,
|
||||
&oifp);
|
||||
if (so->so_proto->pr_protocol == IPPROTO_ICMPV6) {
|
||||
if (oifp)
|
||||
icmp6_ifoutstat_inc(oifp, type, code);
|
||||
icmp6stat.icp6s_outhist[type]++;
|
||||
}
|
||||
|
||||
goto freectl;
|
||||
|
||||
bad:
|
||||
if (m)
|
||||
m_freem(m);
|
||||
|
||||
freectl:
|
||||
if (optp == &opt && optp->ip6po_rthdr && optp->ip6po_route.ro_rt)
|
||||
RTFREE(optp->ip6po_route.ro_rt);
|
||||
if (control)
|
||||
m_freem(control);
|
||||
return(error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Raw IPv6 socket option processing.
|
||||
*/
|
||||
int
|
||||
rip6_ctloutput(so, sopt)
|
||||
struct socket *so;
|
||||
struct sockopt *sopt;
|
||||
{
|
||||
int error;
|
||||
|
||||
if (sopt->sopt_level == IPPROTO_ICMPV6)
|
||||
/*
|
||||
* XXX: is it better to call icmp6_ctloutput() directly
|
||||
* from protosw?
|
||||
*/
|
||||
return(icmp6_ctloutput(so, sopt));
|
||||
else if (sopt->sopt_level != IPPROTO_IPV6)
|
||||
return (EINVAL);
|
||||
|
||||
error = 0;
|
||||
|
||||
switch (sopt->sopt_dir) {
|
||||
case SOPT_GET:
|
||||
switch (sopt->sopt_name) {
|
||||
default:
|
||||
error = ip6_ctloutput(so, sopt);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case SOPT_SET:
|
||||
switch (sopt->sopt_name) {
|
||||
default:
|
||||
error = ip6_ctloutput(so, sopt);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
rip6_attach(struct socket *so, int proto, struct proc *p)
|
||||
{
|
||||
struct inpcb *inp;
|
||||
int error, s;
|
||||
|
||||
inp = sotoinpcb(so);
|
||||
if (inp)
|
||||
panic("rip6_attach");
|
||||
if (p && (error = suser(p)) != 0)
|
||||
return error;
|
||||
|
||||
if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) {
|
||||
error = soreserve(so, rip_sendspace, rip_recvspace);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
s = splnet();
|
||||
error = in_pcballoc(so, &ripcbinfo, p);
|
||||
splx(s);
|
||||
if (error)
|
||||
return error;
|
||||
inp = (struct inpcb *)so->so_pcb;
|
||||
inp->inp_vflag |= INP_IPV6;
|
||||
inp->in6p_ip6_nxt = (long)proto;
|
||||
inp->in6p_hops = -1; /* use kernel default */
|
||||
inp->in6p_cksum = -1;
|
||||
#ifdef IPSEC
|
||||
error = ipsec_init_policy(so, &inp->in6p_sp);
|
||||
if (error != 0) {
|
||||
in6_pcbdetach(inp);
|
||||
return (error);
|
||||
}
|
||||
#endif /*IPSEC*/
|
||||
MALLOC(inp->in6p_icmp6filt, struct icmp6_filter *,
|
||||
sizeof(struct icmp6_filter), M_PCB, M_NOWAIT);
|
||||
ICMP6_FILTER_SETPASSALL(inp->in6p_icmp6filt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
rip6_detach(struct socket *so)
|
||||
{
|
||||
struct inpcb *inp;
|
||||
|
||||
inp = sotoinpcb(so);
|
||||
if (inp == 0)
|
||||
panic("rip6_detach");
|
||||
/* xxx: RSVP */
|
||||
if (inp->in6p_icmp6filt) {
|
||||
FREE(inp->in6p_icmp6filt, M_PCB);
|
||||
inp->in6p_icmp6filt = NULL;
|
||||
}
|
||||
in6_pcbdetach(inp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
rip6_abort(struct socket *so)
|
||||
{
|
||||
soisdisconnected(so);
|
||||
return rip6_detach(so);
|
||||
}
|
||||
|
||||
static int
|
||||
rip6_disconnect(struct socket *so)
|
||||
{
|
||||
struct inpcb *inp = sotoinpcb(so);
|
||||
|
||||
if ((so->so_state & SS_ISCONNECTED) == 0)
|
||||
return ENOTCONN;
|
||||
inp->in6p_faddr = in6addr_any;
|
||||
return rip6_abort(so);
|
||||
}
|
||||
|
||||
static int
|
||||
rip6_bind(struct socket *so, struct sockaddr *nam, struct proc *p)
|
||||
{
|
||||
struct inpcb *inp = sotoinpcb(so);
|
||||
struct sockaddr_in6 *addr = (struct sockaddr_in6 *)nam;
|
||||
struct ifaddr *ia = NULL;
|
||||
|
||||
if (nam->sa_len != sizeof(*addr))
|
||||
return EINVAL;
|
||||
|
||||
if (TAILQ_EMPTY(&ifnet) || addr->sin6_family != AF_INET6)
|
||||
return EADDRNOTAVAIL;
|
||||
if (!IN6_IS_ADDR_UNSPECIFIED(&addr->sin6_addr) &&
|
||||
(ia = ifa_ifwithaddr((struct sockaddr *)addr)) == 0)
|
||||
return EADDRNOTAVAIL;
|
||||
if (ia &&
|
||||
((struct in6_ifaddr *)ia)->ia6_flags &
|
||||
(IN6_IFF_ANYCAST|IN6_IFF_NOTREADY|
|
||||
IN6_IFF_DETACHED|IN6_IFF_DEPRECATED)) {
|
||||
return(EADDRNOTAVAIL);
|
||||
}
|
||||
inp->in6p_laddr = addr->sin6_addr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
rip6_connect(struct socket *so, struct sockaddr *nam, struct proc *p)
|
||||
{
|
||||
struct inpcb *inp = sotoinpcb(so);
|
||||
struct sockaddr_in6 *addr = (struct sockaddr_in6 *)nam;
|
||||
struct in6_addr *in6a = NULL;
|
||||
int error = 0;
|
||||
|
||||
if (nam->sa_len != sizeof(*addr))
|
||||
return EINVAL;
|
||||
if (TAILQ_EMPTY(&ifnet))
|
||||
return EADDRNOTAVAIL;
|
||||
if (addr->sin6_family != AF_INET6)
|
||||
return EAFNOSUPPORT;
|
||||
|
||||
/* Source address selection. XXX: need pcblookup? */
|
||||
in6a = in6_selectsrc(addr, inp->in6p_outputopts,
|
||||
inp->in6p_moptions, &inp->in6p_route,
|
||||
&inp->in6p_laddr, &error);
|
||||
if (in6a == NULL)
|
||||
return (error ? error : EADDRNOTAVAIL);
|
||||
inp->in6p_laddr = *in6a;
|
||||
inp->in6p_faddr = addr->sin6_addr;
|
||||
soisconnected(so);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
rip6_shutdown(struct socket *so)
|
||||
{
|
||||
socantsendmore(so);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
rip6_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam,
|
||||
struct mbuf *control, struct proc *p)
|
||||
{
|
||||
struct inpcb *inp = sotoinpcb(so);
|
||||
struct sockaddr_in6 tmp;
|
||||
struct sockaddr_in6 *dst;
|
||||
|
||||
if (so->so_state & SS_ISCONNECTED) {
|
||||
if (nam) {
|
||||
m_freem(m);
|
||||
return EISCONN;
|
||||
}
|
||||
/* XXX */
|
||||
bzero(&tmp, sizeof(tmp));
|
||||
tmp.sin6_family = AF_INET6;
|
||||
tmp.sin6_len = sizeof(struct sockaddr_in6);
|
||||
bcopy(&inp->in6p_faddr, &tmp.sin6_addr,
|
||||
sizeof(struct in6_addr));
|
||||
dst = &tmp;
|
||||
} else {
|
||||
if (nam == NULL) {
|
||||
m_freem(m);
|
||||
return ENOTCONN;
|
||||
}
|
||||
dst = (struct sockaddr_in6 *)nam;
|
||||
}
|
||||
return rip6_output(m, so, dst, control);
|
||||
}
|
||||
|
||||
struct pr_usrreqs rip6_usrreqs = {
|
||||
rip6_abort, pru_accept_notsupp, rip6_attach, rip6_bind, rip6_connect,
|
||||
pru_connect2_notsupp, in6_control, rip6_detach, rip6_disconnect,
|
||||
pru_listen_notsupp, in6_setpeeraddr, pru_rcvd_notsupp,
|
||||
pru_rcvoob_notsupp, rip6_send, pru_sense_null, rip6_shutdown,
|
||||
in6_setsockaddr, sosend, soreceive, sopoll
|
||||
};
|
||||
155
sys/netinet6/route6.c
Normal file
155
sys/netinet6/route6.c
Normal file
|
|
@ -0,0 +1,155 @@
|
|||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <net/if.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet6/in6.h>
|
||||
#include <netinet6/in6_var.h>
|
||||
#include <netinet6/ip6.h>
|
||||
#include <netinet6/ip6_var.h>
|
||||
|
||||
#include <netinet/icmp6.h>
|
||||
|
||||
static int ip6_rthdr0 __P((struct mbuf *, struct ip6_hdr *, struct ip6_rthdr0 *));
|
||||
|
||||
int
|
||||
route6_input(mp, offp, proto)
|
||||
struct mbuf **mp;
|
||||
int *offp, proto; /* proto is unused */
|
||||
{
|
||||
register struct ip6_hdr *ip6;
|
||||
register struct mbuf *m = *mp;
|
||||
register struct ip6_rthdr *rh;
|
||||
int off = *offp, rhlen;
|
||||
|
||||
IP6_EXTHDR_CHECK(m, off, sizeof(*rh), IPPROTO_DONE);
|
||||
ip6 = mtod(m, struct ip6_hdr *);
|
||||
rh = (struct ip6_rthdr *)((caddr_t)ip6 + off);
|
||||
|
||||
switch(rh->ip6r_type) {
|
||||
case IPV6_RTHDR_TYPE_0:
|
||||
rhlen = (rh->ip6r_len + 1) << 3;
|
||||
IP6_EXTHDR_CHECK(m, off, rhlen, IPPROTO_DONE);
|
||||
if (ip6_rthdr0(m, ip6, (struct ip6_rthdr0 *)rh))
|
||||
return(IPPROTO_DONE);
|
||||
break;
|
||||
default:
|
||||
/* unknown routing type */
|
||||
if (rh->ip6r_segleft == 0) {
|
||||
rhlen = (rh->ip6r_len + 1) << 3;
|
||||
break; /* Final dst. Just ignore the header. */
|
||||
}
|
||||
ip6stat.ip6s_badoptions++;
|
||||
icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER,
|
||||
(caddr_t)&rh->ip6r_type - (caddr_t)ip6);
|
||||
return(IPPROTO_DONE);
|
||||
}
|
||||
|
||||
*offp += rhlen;
|
||||
return(rh->ip6r_nxt);
|
||||
}
|
||||
|
||||
/*
|
||||
* Type0 routing header processing
|
||||
*/
|
||||
static int
|
||||
ip6_rthdr0(m, ip6, rh0)
|
||||
struct mbuf *m;
|
||||
struct ip6_hdr *ip6;
|
||||
struct ip6_rthdr0 *rh0;
|
||||
{
|
||||
int addrs, index;
|
||||
struct in6_addr *nextaddr, tmpaddr;
|
||||
|
||||
if (rh0->ip6r0_segleft == 0)
|
||||
return(0);
|
||||
|
||||
if (rh0->ip6r0_len % 2
|
||||
#ifdef COMPAT_RFC1883
|
||||
|| rh0->ip6r0_len > 46
|
||||
#endif
|
||||
) {
|
||||
/*
|
||||
* Type 0 routing header can't contain more than 23 addresses.
|
||||
* RFC 2462: this limitation was removed since stict/loose
|
||||
* bitmap field was deleted.
|
||||
*/
|
||||
ip6stat.ip6s_badoptions++;
|
||||
icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER,
|
||||
(caddr_t)&rh0->ip6r0_len - (caddr_t)ip6);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
if ((addrs = rh0->ip6r0_len / 2) < rh0->ip6r0_segleft) {
|
||||
ip6stat.ip6s_badoptions++;
|
||||
icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER,
|
||||
(caddr_t)&rh0->ip6r0_segleft - (caddr_t)ip6);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
index = addrs - rh0->ip6r0_segleft;
|
||||
rh0->ip6r0_segleft--;
|
||||
nextaddr = rh0->ip6r0_addr + index;
|
||||
|
||||
if (IN6_IS_ADDR_MULTICAST(nextaddr) ||
|
||||
IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) {
|
||||
ip6stat.ip6s_badoptions++;
|
||||
m_freem(m);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Swap the IPv6 destination address and nextaddr. Forward the packet.
|
||||
*/
|
||||
tmpaddr = *nextaddr;
|
||||
*nextaddr = ip6->ip6_dst;
|
||||
if (IN6_IS_ADDR_LINKLOCAL(nextaddr))
|
||||
nextaddr->s6_addr16[1] = 0;
|
||||
ip6->ip6_dst = tmpaddr;
|
||||
if (IN6_IS_ADDR_LINKLOCAL(&ip6->ip6_dst))
|
||||
ip6->ip6_dst.s6_addr16[1] = htons(m->m_pkthdr.rcvif->if_index);
|
||||
|
||||
#ifdef COMPAT_RFC1883
|
||||
if (rh0->ip6r0_slmap[index / 8] & (1 << (7 - (index % 8))))
|
||||
ip6_forward(m, IPV6_SRCRT_NEIGHBOR);
|
||||
else
|
||||
ip6_forward(m, IPV6_SRCRT_NOTNEIGHBOR);
|
||||
#else
|
||||
ip6_forward(m, 1);
|
||||
#endif
|
||||
|
||||
return(-1); /* m would be freed in ip6_forward() */
|
||||
}
|
||||
83
sys/netinet6/tcp6_var.h
Normal file
83
sys/netinet6/tcp6_var.h
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1982, 1986, 1993, 1994, 1995
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)tcp_var.h 8.4 (Berkeley) 5/24/95
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _NETINET_TCP6_VAR_H_
|
||||
#define _NETINET_TCP6_VAR_H_
|
||||
|
||||
#ifdef KERNEL
|
||||
|
||||
struct ip6_hdr;
|
||||
void tcp6_ctlinput __P((int, struct sockaddr *, void *));
|
||||
void tcp6_init __P((void));
|
||||
int tcp6_input __P((struct mbuf **, int *, int));
|
||||
struct rtentry *tcp_rtlookup6 __P((struct inpcb *));
|
||||
|
||||
extern struct pr_usrreqs tcp6_usrreqs;
|
||||
|
||||
#endif /* KERNEL */
|
||||
|
||||
#endif /* _NETINET_TCP6_VAR_H_ */
|
||||
80
sys/netinet6/udp6_var.h
Normal file
80
sys/netinet6/udp6_var.h
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1982, 1986, 1989, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)udp_var.h 8.1 (Berkeley) 6/10/93
|
||||
*/
|
||||
|
||||
#ifndef _NETINET6_UDP6_VAR_H_
|
||||
#define _NETINET6_UDP6_VAR_H_
|
||||
|
||||
#ifdef KERNEL
|
||||
extern struct pr_usrreqs udp6_usrreqs;
|
||||
|
||||
void udp6_ctlinput __P((int, struct sockaddr *, void *));
|
||||
int udp6_input __P((struct mbuf **, int *, int));
|
||||
int udp6_output __P((struct inpcb *inp, struct mbuf *m,
|
||||
struct sockaddr *addr, struct mbuf *control,
|
||||
struct proc *p));
|
||||
#endif /* KERNEL */
|
||||
|
||||
#endif /*_NETINET6_UDP6_VAR_H_*/
|
||||
106
sys/netkey/key_var.h
Normal file
106
sys/netkey/key_var.h
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _NETKEY_KEY_VAR_H_
|
||||
#define _NETKEY_KEY_VAR_H_
|
||||
|
||||
/* sysctl */
|
||||
#define KEYCTL_DEBUG_LEVEL 1
|
||||
#define KEYCTL_SPI_TRY 2
|
||||
#define KEYCTL_SPI_MIN_VALUE 3
|
||||
#define KEYCTL_SPI_MAX_VALUE 4
|
||||
#define KEYCTL_RANDOM_INT 5
|
||||
#define KEYCTL_LARVAL_LIFETIME 6
|
||||
#define KEYCTL_BLOCKACQ_COUNT 7
|
||||
#define KEYCTL_BLOCKACQ_LIFETIME 8
|
||||
#define KEYCTL_MAXID 9
|
||||
|
||||
#define KEYCTL_NAMES { \
|
||||
{ 0, 0 }, \
|
||||
{ "debug", CTLTYPE_INT }, \
|
||||
{ "spi_try", CTLTYPE_INT }, \
|
||||
{ "spi_min_value", CTLTYPE_INT }, \
|
||||
{ "spi_max_value", CTLTYPE_INT }, \
|
||||
{ "random_int", CTLTYPE_INT }, \
|
||||
{ "larval_lifetime", CTLTYPE_INT }, \
|
||||
{ "blockacq_count", CTLTYPE_INT }, \
|
||||
{ "blockacq_lifetime", CTLTYPE_INT }, \
|
||||
}
|
||||
|
||||
#define KEYCTL_VARS { \
|
||||
0, \
|
||||
&key_debug_level, \
|
||||
&key_spi_trycnt, \
|
||||
&key_spi_minval, \
|
||||
&key_spi_maxval, \
|
||||
&key_int_random, \
|
||||
&key_larval_lifetime, \
|
||||
&key_blockacq_count, \
|
||||
&key_blockacq_lifetime, \
|
||||
}
|
||||
|
||||
#define _ARRAYLEN(p) (sizeof(p)/sizeof(p[0]))
|
||||
#define _KEYLEN(key) ((u_int)((key)->sadb_key_bits >> 3))
|
||||
#define _KEYBITS(key) ((u_int)((key)->sadb_key_bits))
|
||||
#define _KEYBUF(key) ((caddr_t)((caddr_t)(key) + sizeof(struct sadb_key)))
|
||||
|
||||
#define _INADDR(in) ((struct sockaddr_in *)(in))
|
||||
|
||||
/* should not ifdef kernel opt in kernel header file */
|
||||
#if !defined(KERNEL) && !defined(_KERNEL)
|
||||
#if defined(INET6)
|
||||
#define _IN6ADDR(in6) ((struct sockaddr_in6 *)(in6))
|
||||
#define _SALENBYAF(family) \
|
||||
(((family) == AF_INET) ? \
|
||||
(u_int)sizeof(struct sockaddr_in) : \
|
||||
(u_int)sizeof(struct sockaddr_in6))
|
||||
#define _INALENBYAF(family) \
|
||||
(((family) == AF_INET) ? \
|
||||
(u_int)sizeof(struct in_addr) : \
|
||||
(u_int)sizeof(struct in6_addr))
|
||||
#define _INADDRBYSA(saddr) \
|
||||
((((struct sockaddr *)(saddr))->sa_family == AF_INET) ? \
|
||||
(caddr_t)&((struct sockaddr_in *)(saddr))->sin_addr : \
|
||||
(caddr_t)&((struct sockaddr_in6 *)(saddr))->sin6_addr)
|
||||
#define _INPORTBYSA(saddr) \
|
||||
((((struct sockaddr *)(saddr))->sa_family == AF_INET) ? \
|
||||
((struct sockaddr_in *)(saddr))->sin_port : \
|
||||
((struct sockaddr_in6 *)(saddr))->sin6_port)
|
||||
#else
|
||||
#define _IN6ADDR(in6) "#error"
|
||||
#define _SALENBYAF(family) sizeof(struct sockaddr_in)
|
||||
#define _INALENBYAF(family) sizeof(struct in_addr)
|
||||
#define _INADDRBYSA(saddr) ((caddr_t)&((struct sockaddr_in *)(saddr))->sin_addr)
|
||||
#define _INPORTBYSA(saddr) (((struct sockaddr_in *)(saddr))->sin_port)
|
||||
#endif /* defined(INET6) */
|
||||
#endif /* !defined(KERNEL) && !defined(_KERNEL) */
|
||||
|
||||
#endif /* _NETKEY_KEY_VAR_H_ */
|
||||
135
sys/netkey/keydb.h
Normal file
135
sys/netkey/keydb.h
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _NETKEY_KEYDB_H_
|
||||
#define _NETKEY_KEYDB_H_
|
||||
|
||||
#ifdef KERNEL
|
||||
|
||||
/* Security Assocciation Index */
|
||||
/* NOTE: Encure to be same address family */
|
||||
struct secasindex {
|
||||
struct sockaddr_storage src; /* srouce address for SA */
|
||||
struct sockaddr_storage dst; /* destination address for SA */
|
||||
u_int16_t proto; /* IPPROTO_ESP or IPPROTO_AH */
|
||||
u_int8_t mode; /* mode of protocol, see ipsec.h */
|
||||
};
|
||||
|
||||
/* Security Association Data Base */
|
||||
struct secashead {
|
||||
LIST_ENTRY(secashead) chain;
|
||||
|
||||
struct secasindex saidx;
|
||||
struct secpolicyindex *owner; /* Indicate it who owned its SA. */
|
||||
/* If NULL then it's shared SA */
|
||||
|
||||
u_int8_t state; /* MATURE or DEAD. */
|
||||
LIST_HEAD(_satree, secasvar) savtree[SADB_SASTATE_MAX+1];
|
||||
/* SA chain */
|
||||
/* The first of this list is newer SA */
|
||||
|
||||
struct route sa_route; /* XXX */
|
||||
};
|
||||
|
||||
/* Security Association */
|
||||
struct secasvar {
|
||||
LIST_ENTRY(secasvar) chain;
|
||||
|
||||
int refcnt; /* reference count */
|
||||
u_int8_t state; /* Status of this Association */
|
||||
|
||||
u_int8_t alg_auth; /* Authentication Algorithm Identifier*/
|
||||
u_int8_t alg_enc; /* Cipher Algorithm Identifier */
|
||||
u_int32_t spi; /* SPI Value, network byte order */
|
||||
u_int32_t flags; /* holder for SADB_KEY_FLAGS */
|
||||
|
||||
struct sadb_key *key_auth; /* Key for Authentication */
|
||||
/* length has been shifted up to 3. */
|
||||
struct sadb_key *key_enc; /* Key for Encryption */
|
||||
/* length has been shifted up to 3. */
|
||||
caddr_t iv; /* Initilization Vector */
|
||||
u_int ivlen; /* length of IV */
|
||||
|
||||
struct secreplay *replay; /* replay prevention */
|
||||
u_int32_t tick; /* for lifetime */
|
||||
|
||||
struct sadb_lifetime *lft_c; /* CURRENT lifetime, it's constant. */
|
||||
struct sadb_lifetime *lft_h; /* HARD lifetime */
|
||||
struct sadb_lifetime *lft_s; /* SOFT lifetime */
|
||||
|
||||
u_int32_t seq; /* sequence number */
|
||||
pid_t pid; /* message's pid */
|
||||
|
||||
struct secashead *sah; /* back pointer to the secashead */
|
||||
};
|
||||
|
||||
/* replay prevention */
|
||||
struct secreplay {
|
||||
u_int32_t count;
|
||||
u_int wsize; /* window size, i.g. 4 bytes */
|
||||
u_int32_t seq; /* used by sender */
|
||||
u_int32_t lastseq; /* used by receiver */
|
||||
caddr_t bitmap; /* used by receiver */
|
||||
};
|
||||
|
||||
/* socket table due to send PF_KEY messages. */
|
||||
struct secreg {
|
||||
LIST_ENTRY(secreg) chain;
|
||||
|
||||
struct socket *so;
|
||||
};
|
||||
|
||||
#ifndef IPSEC_NONBLOCK_ACQUIRE
|
||||
/* acquiring list table. */
|
||||
struct secacq {
|
||||
LIST_ENTRY(secacq) chain;
|
||||
|
||||
struct secasindex saidx;
|
||||
|
||||
u_int32_t seq; /* sequence number */
|
||||
u_int32_t tick; /* for lifetime */
|
||||
int count; /* for lifetime */
|
||||
};
|
||||
#endif
|
||||
|
||||
/* Sensitivity Level Specification */
|
||||
/* nothing */
|
||||
|
||||
#define SADB_KILL_INTERVAL 600 /* six seconds */
|
||||
|
||||
struct key_cb {
|
||||
int key_count;
|
||||
int any_count;
|
||||
};
|
||||
|
||||
#endif /* KERNEL */
|
||||
|
||||
#endif /* _NETKEY_KEYDB_H_ */
|
||||
56
sys/netkey/keysock.h
Normal file
56
sys/netkey/keysock.h
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/* $Id: keysock.h,v 1.1.6.3.6.1 1999/05/17 17:03:19 itojun Exp $ */
|
||||
|
||||
#ifndef _NETKEY_KEYSOCK_H_
|
||||
#define _NETKEY_KEYSOCK_H_
|
||||
|
||||
#if defined(KERNEL)
|
||||
struct keycb {
|
||||
struct rawcb kp_raw; /* rawcb */
|
||||
int kp_promisc; /* promiscuous mode */
|
||||
int kp_registered; /* registered socket */
|
||||
};
|
||||
|
||||
extern int key_output __P((struct mbuf *, ...));
|
||||
extern int key_usrreq __P((struct socket *, int, struct mbuf *,
|
||||
struct mbuf *, struct mbuf *));
|
||||
|
||||
#define KEY_SENDUP_ONE 0
|
||||
#define KEY_SENDUP_ALL 1
|
||||
#define KEY_SENDUP_REGISTERED 2
|
||||
|
||||
extern int key_sendup __P((struct socket *, struct sadb_msg *, u_int,
|
||||
int));
|
||||
#endif /* defined(KERNEL) */
|
||||
|
||||
#endif _NETKEY_KEYSOCK_H_
|
||||
|
|
@ -355,6 +355,12 @@ struct socket *
|
|||
int sooptcopyin __P((struct sockopt *sopt, void *buf, size_t len,
|
||||
size_t minlen));
|
||||
int sooptcopyout __P((struct sockopt *sopt, void *buf, size_t len));
|
||||
|
||||
/* XXX; prepare mbuf for (__FreeBSD__ < 3) routines. */
|
||||
int soopt_getm __P((struct sockopt *sopt, struct mbuf **mp));
|
||||
int soopt_mcopyin __P((struct sockopt *sopt, struct mbuf *m));
|
||||
int soopt_mcopyout __P((struct sockopt *sopt, struct mbuf *m));
|
||||
|
||||
int sopoll __P((struct socket *so, int events, struct ucred *cred,
|
||||
struct proc *p));
|
||||
int soreceive __P((struct socket *so, struct sockaddr **paddr,
|
||||
|
|
|
|||
Loading…
Reference in a new issue