implement IPV6_V6ONLY socket option from draft-ietf-ipngwg-rfc2553bis-03.txt.
IPV6_BINDV6ONLY (netbsd only) is deprecated, but still work just like before.
This commit is contained in:
parent
d76f074387
commit
91498ffec5
@ -1,4 +1,4 @@
|
||||
.\" $NetBSD: ip6.4,v 1.8 2001/09/22 00:57:41 wiz Exp $
|
||||
.\" $NetBSD: ip6.4,v 1.9 2001/10/15 09:51:16 itojun Exp $
|
||||
.\" $KAME: ip6.4,v 1.11 2000/05/07 06:21:41 itojun Exp $
|
||||
.\"
|
||||
.\" Copyright (C) 1999 WIDE Project.
|
||||
@ -240,14 +240,14 @@ int range = IPV6_PORTRANGE_LOW; /* see <netinet/in.h> */
|
||||
setsockopt(s, IPPROTO_IPV6, IPV6_PORTRANGE, &range, sizeof(range));
|
||||
.Ed
|
||||
.Pp
|
||||
.Dv IPV6_BINDV6ONLY
|
||||
.Dv IPV6_V6ONLY
|
||||
controls behavior of
|
||||
.Dv AF_INET6
|
||||
wildcard listening socket.
|
||||
The following example sets the option to 1:
|
||||
.Bd -literal -offset indent
|
||||
int on = 1;
|
||||
setsockopt(s, IPPROTO_IPV6, IPV6_BINDV6ONLY, &on, sizeof(on));
|
||||
setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on));
|
||||
.Ed
|
||||
.Pp
|
||||
If set to 1,
|
||||
@ -684,8 +684,7 @@ The ancillary data items were improperly formed, or option name was unknown.
|
||||
.Sh STANDARDS
|
||||
Most of the socket options are defined in
|
||||
RFC2292 and/or RFC2553.
|
||||
.Dv IPV6_PORTRANGE ,
|
||||
.Dv IPV6_BINDV6ONLY
|
||||
.Dv IPV6_PORTRANGE
|
||||
and
|
||||
conflict resolution rule
|
||||
are not defined in the RFCs and should be considered implementation dependent.
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: udp_usrreq.c,v 1.84 2001/09/17 17:27:01 thorpej Exp $ */
|
||||
/* $NetBSD: udp_usrreq.c,v 1.85 2001/10/15 09:51:15 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
@ -778,25 +778,21 @@ udp6_realinput(af, src, dst, m, off)
|
||||
!in6_mcmatch(in6p, &dst6, m->m_pkthdr.rcvif))
|
||||
continue;
|
||||
}
|
||||
#ifndef INET6_BINDV6ONLY
|
||||
else {
|
||||
if (IN6_IS_ADDR_V4MAPPED(&dst6) &&
|
||||
(in6p->in6p_flags & IN6P_BINDV6ONLY))
|
||||
(in6p->in6p_flags & IN6P_IPV6_V6ONLY))
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_faddr)) {
|
||||
if (!IN6_ARE_ADDR_EQUAL(&in6p->in6p_faddr,
|
||||
&src6) || in6p->in6p_fport != sport)
|
||||
continue;
|
||||
}
|
||||
#ifndef INET6_BINDV6ONLY
|
||||
else {
|
||||
if (IN6_IS_ADDR_V4MAPPED(&src6) &&
|
||||
(in6p->in6p_flags & IN6P_BINDV6ONLY))
|
||||
(in6p->in6p_flags & IN6P_IPV6_V6ONLY))
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
last = in6p;
|
||||
udp6_sendup(m, off, (struct sockaddr *)src,
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: in6.h,v 1.27 2001/07/24 00:44:36 itojun Exp $ */
|
||||
/* $NetBSD: in6.h,v 1.28 2001/10/15 09:51:16 itojun Exp $ */
|
||||
/* $KAME: in6.h,v 1.83 2001/03/29 02:55:07 jinmei Exp $ */
|
||||
|
||||
/*
|
||||
@ -402,7 +402,7 @@ struct route_in6 {
|
||||
#define IPV6_RTHDR 24 /* bool; routing header */
|
||||
#define IPV6_PKTOPTIONS 25 /* buf/cmsghdr; set/get IPv6 options */
|
||||
#define IPV6_CHECKSUM 26 /* int; checksum offset for raw socket */
|
||||
#define IPV6_BINDV6ONLY 27 /* bool; only bind INET6 at null bind */
|
||||
#define IPV6_V6ONLY 27 /* bool; only bind INET6 at null bind */
|
||||
|
||||
#if 1 /*IPSEC*/
|
||||
#define IPV6_IPSEC_POLICY 28 /* struct; get/set security policy */
|
||||
@ -527,7 +527,7 @@ struct in6_pktinfo {
|
||||
#define IPV6CTL_KAME_VERSION 20
|
||||
#define IPV6CTL_USE_DEPRECATED 21 /* use deprecated addr (RFC2462 5.5.4) */
|
||||
#define IPV6CTL_RR_PRUNE 22 /* walk timer for router renumbering */
|
||||
#define IPV6CTL_BINDV6ONLY 24
|
||||
#define IPV6CTL_V6ONLY 24
|
||||
/* 25 to 27: reserved */
|
||||
#define IPV6CTL_ANONPORTMIN 28 /* minimum ephemeral port */
|
||||
#define IPV6CTL_ANONPORTMAX 29 /* maximum ephemeral port */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: in6_pcb.c,v 1.40 2001/08/06 10:25:01 itojun Exp $ */
|
||||
/* $NetBSD: in6_pcb.c,v 1.41 2001/10/15 09:51:16 itojun Exp $ */
|
||||
/* $KAME: in6_pcb.c,v 1.84 2001/02/08 18:02:08 itojun Exp $ */
|
||||
|
||||
/*
|
||||
@ -137,12 +137,8 @@ in6_pcballoc(so, head)
|
||||
head->in6p_next = in6p;
|
||||
in6p->in6p_prev = head;
|
||||
in6p->in6p_next->in6p_prev = in6p;
|
||||
#ifndef INET6_BINDV6ONLY
|
||||
if (ip6_bindv6only)
|
||||
in6p->in6p_flags |= IN6P_BINDV6ONLY;
|
||||
#else
|
||||
in6p->in6p_flags |= IN6P_BINDV6ONLY; /*just for safety*/
|
||||
#endif
|
||||
if (ip6_v6only)
|
||||
in6p->in6p_flags |= IN6P_IPV6_V6ONLY;
|
||||
so->so_pcb = (caddr_t)in6p;
|
||||
return(0);
|
||||
}
|
||||
@ -201,7 +197,8 @@ in6_pcbbind(in6p, nam, p)
|
||||
*/
|
||||
if (so->so_options & SO_REUSEADDR)
|
||||
reuseport = SO_REUSEADDR|SO_REUSEPORT;
|
||||
} else if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
|
||||
}
|
||||
else if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
|
||||
struct sockaddr_in sin;
|
||||
|
||||
bzero(&sin, sizeof(sin));
|
||||
@ -211,7 +208,8 @@ in6_pcbbind(in6p, nam, p)
|
||||
sizeof(sin.sin_addr));
|
||||
if (ifa_ifwithaddr((struct sockaddr *)&sin) == 0)
|
||||
return EADDRNOTAVAIL;
|
||||
} else if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
|
||||
}
|
||||
else if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
|
||||
struct ifaddr *ia = NULL;
|
||||
|
||||
sin6->sin6_port = 0; /* yech... */
|
||||
@ -310,11 +308,14 @@ in6_pcbconnect(in6p, nam)
|
||||
|
||||
/* sanity check for mapped address case */
|
||||
if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
|
||||
if ((in6p->in6p_flags & IN6P_IPV6_V6ONLY) != 0)
|
||||
return EINVAL;
|
||||
if (IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_laddr))
|
||||
in6p->in6p_laddr.s6_addr16[5] = htons(0xffff);
|
||||
if (!IN6_IS_ADDR_V4MAPPED(&in6p->in6p_laddr))
|
||||
return EINVAL;
|
||||
} else {
|
||||
} else
|
||||
{
|
||||
if (IN6_IS_ADDR_V4MAPPED(&in6p->in6p_laddr))
|
||||
return EINVAL;
|
||||
}
|
||||
@ -352,7 +353,8 @@ in6_pcbconnect(in6p, nam)
|
||||
#else
|
||||
return EADDRNOTAVAIL;
|
||||
#endif
|
||||
} else {
|
||||
} else
|
||||
{
|
||||
/*
|
||||
* XXX: in6_selectsrc might replace the bound local address
|
||||
* with the address specified by setsockopt(IPV6_PKTINFO).
|
||||
@ -383,7 +385,14 @@ in6_pcbconnect(in6p, nam)
|
||||
return(EADDRINUSE);
|
||||
if (IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_laddr)
|
||||
|| (IN6_IS_ADDR_V4MAPPED(&in6p->in6p_laddr)
|
||||
&& in6p->in6p_laddr.s6_addr32[3] == 0)) {
|
||||
&& in6p->in6p_laddr.s6_addr32[3] == 0))
|
||||
{
|
||||
/*
|
||||
* XXX in IPv4 mapped address case, we should grab fresh
|
||||
* local port number by in_pcbbind, not in6_pcbbind.
|
||||
* if we are in bad luck, we may assign conflicting port number
|
||||
* between IPv4 and IPv6 unwillingly.
|
||||
*/
|
||||
if (in6p->in6p_lport == 0) {
|
||||
(void)in6_pcbbind(in6p, (struct mbuf *)0,
|
||||
(struct proc *)0);
|
||||
@ -758,14 +767,10 @@ in6_pcblookup(head, faddr6, fport_arg, laddr6, lport_arg, flags)
|
||||
}
|
||||
else {
|
||||
if (IN6_IS_ADDR_V4MAPPED(laddr6)) {
|
||||
#ifndef INET6_BINDV6ONLY
|
||||
if (in6p->in6p_flags & IN6P_BINDV6ONLY)
|
||||
if (in6p->in6p_flags & IN6P_IPV6_V6ONLY)
|
||||
continue;
|
||||
else
|
||||
wildcard++;
|
||||
#else
|
||||
continue;
|
||||
#endif
|
||||
} else if (!IN6_IS_ADDR_UNSPECIFIED(laddr6))
|
||||
wildcard++;
|
||||
}
|
||||
@ -787,14 +792,10 @@ in6_pcblookup(head, faddr6, fport_arg, laddr6, lport_arg, flags)
|
||||
}
|
||||
else {
|
||||
if (IN6_IS_ADDR_V4MAPPED(faddr6)) {
|
||||
#ifndef INET6_BINDV6ONLY
|
||||
if (in6p->in6p_flags & IN6P_BINDV6ONLY)
|
||||
if (in6p->in6p_flags & IN6P_IPV6_V6ONLY)
|
||||
continue;
|
||||
else
|
||||
wildcard++;
|
||||
#else
|
||||
continue;
|
||||
#endif
|
||||
} else if (!IN6_IS_ADDR_UNSPECIFIED(faddr6))
|
||||
wildcard++;
|
||||
}
|
||||
@ -860,6 +861,10 @@ in6_pcblookup_connect(head, faddr6, fport_arg, laddr6, lport_arg, faith)
|
||||
continue;
|
||||
if (!IN6_ARE_ADDR_EQUAL(&in6p->in6p_laddr, laddr6))
|
||||
continue;
|
||||
if ((IN6_IS_ADDR_V4MAPPED(laddr6) ||
|
||||
IN6_IS_ADDR_V4MAPPED(faddr6)) &&
|
||||
(in6p->in6p_flags & IN6P_IPV6_V6ONLY))
|
||||
continue;
|
||||
return in6p;
|
||||
}
|
||||
return NULL;
|
||||
@ -889,18 +894,15 @@ in6_pcblookup_bind(head, laddr6, lport_arg, faith)
|
||||
continue;
|
||||
if (IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_laddr)) {
|
||||
if (IN6_IS_ADDR_V4MAPPED(laddr6)) {
|
||||
#ifndef INET6_BINDV6ONLY
|
||||
if (in6p->in6p_flags & IN6P_BINDV6ONLY)
|
||||
if ((in6p->in6p_flags & IN6P_IPV6_V6ONLY))
|
||||
continue;
|
||||
else
|
||||
match = in6p;
|
||||
#else
|
||||
continue;
|
||||
#endif
|
||||
} else
|
||||
match = in6p;
|
||||
}
|
||||
else if (IN6_IS_ADDR_V4MAPPED(&in6p->in6p_laddr) &&
|
||||
!(in6p->in6p_flags & IN6P_IPV6_V6ONLY) &&
|
||||
in6p->in6p_laddr.s6_addr32[3] == 0) {
|
||||
if (IN6_IS_ADDR_V4MAPPED(laddr6) &&
|
||||
laddr6->s6_addr32[3] != 0)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: in6_pcb.h,v 1.17 2001/07/02 15:25:36 itojun Exp $ */
|
||||
/* $NetBSD: in6_pcb.h,v 1.18 2001/10/15 09:51:16 itojun Exp $ */
|
||||
/* $KAME: in6_pcb.h,v 1.45 2001/02/09 05:59:46 itojun Exp $ */
|
||||
|
||||
/*
|
||||
@ -122,6 +122,7 @@ struct in6pcb {
|
||||
#define IN6P_RECVOPTS 0x001000 /* receive incoming IP6 options */
|
||||
#define IN6P_RECVRETOPTS 0x002000 /* receive IP6 options for reply */
|
||||
#define IN6P_RECVDSTADDR 0x004000 /* receive IP6 dst address */
|
||||
#define IN6P_IPV6_V6ONLY 0x008000 /* restrict AF_INET6 socket for v6 */
|
||||
#define IN6P_PKTINFO 0x010000 /* receive IP6 dst and I/F */
|
||||
#define IN6P_HOPLIMIT 0x020000 /* receive hoplimit */
|
||||
#define IN6P_HOPOPTS 0x040000 /* receive hop-by-hop options */
|
||||
@ -133,7 +134,9 @@ struct in6pcb {
|
||||
#define IN6P_LOWPORT 0x2000000 /* user wants "low" port binding */
|
||||
#define IN6P_ANONPORT 0x4000000 /* port chosen for user */
|
||||
#define IN6P_FAITH 0x8000000 /* accept FAITH'ed connections */
|
||||
#if 0 /* obsoleted */
|
||||
#define IN6P_BINDV6ONLY 0x10000000 /* do not grab IPv4 traffic */
|
||||
#endif
|
||||
|
||||
#define IN6P_CONTROLOPTS (IN6P_PKTINFO|IN6P_HOPLIMIT|IN6P_HOPOPTS|\
|
||||
IN6P_DSTOPTS|IN6P_RTHDR|IN6P_RTHDRDSTOPTS)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: in6_proto.c,v 1.29 2001/03/21 19:22:28 thorpej Exp $ */
|
||||
/* $NetBSD: in6_proto.c,v 1.30 2001/10/15 09:51:17 itojun Exp $ */
|
||||
/* $KAME: in6_proto.c,v 1.66 2000/10/10 15:35:47 itojun Exp $ */
|
||||
|
||||
/*
|
||||
@ -292,9 +292,7 @@ int ip6_gif_hlim = 0;
|
||||
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. */
|
||||
#ifndef INET6_BINDV6ONLY
|
||||
int ip6_bindv6only = 1;
|
||||
#endif
|
||||
int ip6_v6only = 1;
|
||||
|
||||
u_int32_t ip6_id = 0UL;
|
||||
int ip6_keepfaith = 0;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: ip6_input.c,v 1.42 2001/08/06 10:25:01 itojun Exp $ */
|
||||
/* $NetBSD: ip6_input.c,v 1.43 2001/10/15 09:51:17 itojun Exp $ */
|
||||
/* $KAME: ip6_input.c,v 1.188 2001/03/29 05:34:31 itojun Exp $ */
|
||||
|
||||
/*
|
||||
@ -1453,10 +1453,11 @@ ip6_sysctl(name, namelen, oldp, oldlenp, newp, newlen)
|
||||
&ip6_use_deprecated);
|
||||
case IPV6CTL_RR_PRUNE:
|
||||
return sysctl_int(oldp, oldlenp, newp, newlen, &ip6_rr_prune);
|
||||
#ifndef INET6_BINDV6ONLY
|
||||
case IPV6CTL_BINDV6ONLY:
|
||||
return sysctl_int(oldp, oldlenp, newp, newlen,
|
||||
&ip6_bindv6only);
|
||||
case IPV6CTL_V6ONLY:
|
||||
#ifdef INET6_BINDV6ONLY
|
||||
return sysctl_rdint(oldp, oldlenp, newp, ip6_v6only);
|
||||
#else
|
||||
return sysctl_int(oldp, oldlenp, newp, newlen, &ip6_v6only);
|
||||
#endif
|
||||
case IPV6CTL_ANONPORTMIN:
|
||||
old = ip6_anonportmin;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: ip6_output.c,v 1.36 2001/06/11 13:49:18 itojun Exp $ */
|
||||
/* $NetBSD: ip6_output.c,v 1.37 2001/10/15 09:51:17 itojun Exp $ */
|
||||
/* $KAME: ip6_output.c,v 1.172 2001/03/25 09:55:56 itojun Exp $ */
|
||||
|
||||
/*
|
||||
@ -1257,75 +1257,87 @@ ip6_ctloutput(op, so, level, optname, mp)
|
||||
case IPV6_RTHDR:
|
||||
case IPV6_CHECKSUM:
|
||||
case IPV6_FAITH:
|
||||
#ifndef INET6_BINDV6ONLY
|
||||
case IPV6_BINDV6ONLY:
|
||||
#endif
|
||||
if (!m || m->m_len != sizeof(int))
|
||||
case IPV6_V6ONLY:
|
||||
if (!m || m->m_len != sizeof(int)) {
|
||||
error = EINVAL;
|
||||
else {
|
||||
optval = *mtod(m, int *);
|
||||
switch (optname) {
|
||||
break;
|
||||
}
|
||||
optval = *mtod(m, int *);
|
||||
switch (optname) {
|
||||
|
||||
case IPV6_UNICAST_HOPS:
|
||||
if (optval < -1 || optval >= 256)
|
||||
error = EINVAL;
|
||||
else {
|
||||
/* -1 = kernel default */
|
||||
in6p->in6p_hops = optval;
|
||||
}
|
||||
break;
|
||||
#define OPTSET(bit) \
|
||||
if (optval) \
|
||||
in6p->in6p_flags |= bit; \
|
||||
else \
|
||||
in6p->in6p_flags &= ~bit;
|
||||
|
||||
case IPV6_RECVOPTS:
|
||||
OPTSET(IN6P_RECVOPTS);
|
||||
break;
|
||||
|
||||
case IPV6_RECVRETOPTS:
|
||||
OPTSET(IN6P_RECVRETOPTS);
|
||||
break;
|
||||
|
||||
case IPV6_RECVDSTADDR:
|
||||
OPTSET(IN6P_RECVDSTADDR);
|
||||
break;
|
||||
|
||||
case IPV6_PKTINFO:
|
||||
OPTSET(IN6P_PKTINFO);
|
||||
break;
|
||||
|
||||
case IPV6_HOPLIMIT:
|
||||
OPTSET(IN6P_HOPLIMIT);
|
||||
break;
|
||||
|
||||
case IPV6_HOPOPTS:
|
||||
OPTSET(IN6P_HOPOPTS);
|
||||
break;
|
||||
|
||||
case IPV6_DSTOPTS:
|
||||
OPTSET(IN6P_DSTOPTS);
|
||||
break;
|
||||
|
||||
case IPV6_RTHDR:
|
||||
OPTSET(IN6P_RTHDR);
|
||||
break;
|
||||
|
||||
case IPV6_CHECKSUM:
|
||||
in6p->in6p_cksum = optval;
|
||||
break;
|
||||
|
||||
case IPV6_FAITH:
|
||||
OPTSET(IN6P_FAITH);
|
||||
break;
|
||||
|
||||
#ifndef INET6_BINDV6ONLY
|
||||
case IPV6_BINDV6ONLY:
|
||||
OPTSET(IN6P_BINDV6ONLY);
|
||||
break;
|
||||
#endif
|
||||
case IPV6_UNICAST_HOPS:
|
||||
if (optval < -1 || optval >= 256)
|
||||
error = EINVAL;
|
||||
else {
|
||||
/* -1 = kernel default */
|
||||
in6p->in6p_hops = optval;
|
||||
}
|
||||
break;
|
||||
#define OPTSET(bit) \
|
||||
if (optval) \
|
||||
in6p->in6p_flags |= bit; \
|
||||
else \
|
||||
in6p->in6p_flags &= ~bit;
|
||||
|
||||
case IPV6_RECVOPTS:
|
||||
OPTSET(IN6P_RECVOPTS);
|
||||
break;
|
||||
|
||||
case IPV6_RECVRETOPTS:
|
||||
OPTSET(IN6P_RECVRETOPTS);
|
||||
break;
|
||||
|
||||
case IPV6_RECVDSTADDR:
|
||||
OPTSET(IN6P_RECVDSTADDR);
|
||||
break;
|
||||
|
||||
case IPV6_PKTINFO:
|
||||
OPTSET(IN6P_PKTINFO);
|
||||
break;
|
||||
|
||||
case IPV6_HOPLIMIT:
|
||||
OPTSET(IN6P_HOPLIMIT);
|
||||
break;
|
||||
|
||||
case IPV6_HOPOPTS:
|
||||
OPTSET(IN6P_HOPOPTS);
|
||||
break;
|
||||
|
||||
case IPV6_DSTOPTS:
|
||||
OPTSET(IN6P_DSTOPTS);
|
||||
break;
|
||||
|
||||
case IPV6_RTHDR:
|
||||
OPTSET(IN6P_RTHDR);
|
||||
break;
|
||||
|
||||
case IPV6_CHECKSUM:
|
||||
in6p->in6p_cksum = optval;
|
||||
break;
|
||||
|
||||
case IPV6_FAITH:
|
||||
OPTSET(IN6P_FAITH);
|
||||
break;
|
||||
|
||||
case IPV6_V6ONLY:
|
||||
/*
|
||||
* make setsockopt(IPV6_V6ONLY)
|
||||
* available only prior to bind(2).
|
||||
* see ipng mailing list, Jun 22 2001.
|
||||
*/
|
||||
if (in6p->in6p_lport ||
|
||||
!IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_laddr))
|
||||
{
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
#ifdef INET6_BINDV6ONLY
|
||||
if (!optval)
|
||||
error = EINVAL;
|
||||
#else
|
||||
OPTSET(IN6P_IPV6_V6ONLY);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
break;
|
||||
#undef OPTSET
|
||||
@ -1439,9 +1451,7 @@ ip6_ctloutput(op, so, level, optname, mp)
|
||||
case IPV6_RTHDR:
|
||||
case IPV6_CHECKSUM:
|
||||
case IPV6_FAITH:
|
||||
#ifndef INET6_BINDV6ONLY
|
||||
case IPV6_BINDV6ONLY:
|
||||
#endif
|
||||
case IPV6_V6ONLY:
|
||||
*mp = m = m_get(M_WAIT, MT_SOOPTS);
|
||||
m->m_len = sizeof(int);
|
||||
switch (optname) {
|
||||
@ -1505,11 +1515,9 @@ ip6_ctloutput(op, so, level, optname, mp)
|
||||
optval = OPTBIT(IN6P_FAITH);
|
||||
break;
|
||||
|
||||
#ifndef INET6_BINDV6ONLY
|
||||
case IPV6_BINDV6ONLY:
|
||||
optval = OPTBIT(IN6P_BINDV6ONLY);
|
||||
case IPV6_V6ONLY:
|
||||
optval = OPTBIT(IN6P_IPV6_V6ONLY);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
*mtod(m, int *) = optval;
|
||||
break;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: ip6_var.h,v 1.15 2000/08/26 11:03:46 itojun Exp $ */
|
||||
/* $NetBSD: ip6_var.h,v 1.16 2001/10/15 09:51:17 itojun Exp $ */
|
||||
/* $KAME: ip6_var.h,v 1.33 2000/06/11 14:59:20 jinmei Exp $ */
|
||||
|
||||
/*
|
||||
@ -214,9 +214,7 @@ 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. */
|
||||
#ifndef INET6_BINDV6ONLY
|
||||
extern int ip6_bindv6only;
|
||||
#endif
|
||||
extern int ip6_v6only;
|
||||
|
||||
extern struct socket *ip6_mrouter; /* multicast routing daemon */
|
||||
extern int ip6_sendredirects; /* send IP redirects when forwarding? */
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* $NetBSD: udp6_output.c,v 1.1 2001/02/08 16:48:02 itojun Exp $ */
|
||||
/* $KAME: udp6_output.c,v 1.21 2001/02/07 11:51:54 itojun Exp $ */
|
||||
/* $NetBSD: udp6_output.c,v 1.2 2001/10/15 09:51:17 itojun Exp $ */
|
||||
/* $KAME: udp6_output.c,v 1.43 2001/10/15 09:19:52 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
@ -123,14 +123,16 @@ udp6_output(in6p, m, addr6, control, p)
|
||||
u_int32_t plen = sizeof(struct udphdr) + ulen;
|
||||
struct ip6_hdr *ip6;
|
||||
struct udphdr *udp6;
|
||||
struct in6_addr *laddr, *faddr;
|
||||
struct in6_addr *laddr, *faddr;
|
||||
struct in6_addr laddr_mapped; /* XXX ugly */
|
||||
u_short fport;
|
||||
int error = 0;
|
||||
struct ip6_pktopts opt, *stickyopt = in6p->in6p_outputopts;
|
||||
int priv;
|
||||
int af, hlen;
|
||||
int af = AF_INET6, hlen = sizeof(struct ip6_hdr);
|
||||
#ifdef INET
|
||||
struct ip *ip;
|
||||
struct udpiphdr *ui;
|
||||
#endif
|
||||
int flags;
|
||||
struct sockaddr_in6 tmp;
|
||||
@ -169,6 +171,7 @@ udp6_output(in6p, m, addr6, control, p)
|
||||
}
|
||||
|
||||
if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_faddr)) {
|
||||
/* how about ::ffff:0.0.0.0 case? */
|
||||
error = EISCONN;
|
||||
goto release;
|
||||
}
|
||||
@ -180,6 +183,37 @@ udp6_output(in6p, m, addr6, control, p)
|
||||
faddr = &sin6->sin6_addr;
|
||||
fport = sin6->sin6_port; /* allow 0 port */
|
||||
|
||||
if (IN6_IS_ADDR_V4MAPPED(faddr)) {
|
||||
if ((in6p->in6p_flags & IN6P_IPV6_V6ONLY))
|
||||
{
|
||||
/*
|
||||
* I believe we should explicitly discard the
|
||||
* packet when mapped addresses are disabled,
|
||||
* rather than send the packet as an IPv6 one.
|
||||
* If we chose the latter approach, the packet
|
||||
* might be sent out on the wire based on the
|
||||
* default route, the situation which we'd
|
||||
* probably want to avoid.
|
||||
* (20010421 jinmei@kame.net)
|
||||
*/
|
||||
error = EINVAL;
|
||||
goto release;
|
||||
}
|
||||
if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_laddr)
|
||||
&& !IN6_IS_ADDR_V4MAPPED(&in6p->in6p_laddr)) {
|
||||
/*
|
||||
* when remote addr is an IPv4-mapped address,
|
||||
* local addr should not be an IPv6 address,
|
||||
* since you cannot determine how to map IPv6
|
||||
* source address to IPv4.
|
||||
*/
|
||||
error = EINVAL;
|
||||
goto release;
|
||||
}
|
||||
|
||||
af = AF_INET;
|
||||
}
|
||||
|
||||
/* KAME hack: embed scopeid */
|
||||
if (in6_embedscope(&sin6->sin6_addr, sin6, in6p, NULL) != 0) {
|
||||
error = EINVAL;
|
||||
@ -191,8 +225,41 @@ udp6_output(in6p, m, addr6, control, p)
|
||||
in6p->in6p_moptions,
|
||||
&in6p->in6p_route,
|
||||
&in6p->in6p_laddr, &error);
|
||||
} else
|
||||
laddr = &in6p->in6p_laddr; /*XXX*/
|
||||
} else {
|
||||
/*
|
||||
* XXX: freebsd[34] does not have in_selectsrc, but
|
||||
* we can omit the whole part because freebsd4 calls
|
||||
* udp_output() directly in this case, and thus we'll
|
||||
* never see this path.
|
||||
*/
|
||||
if (IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_laddr)) {
|
||||
struct sockaddr_in *sinp, sin_dst;
|
||||
|
||||
bzero(&sin_dst, sizeof(sin_dst));
|
||||
sin_dst.sin_family = AF_INET;
|
||||
sin_dst.sin_len = sizeof(sin_dst);
|
||||
bcopy(&faddr->s6_addr[12], &sin_dst.sin_addr,
|
||||
sizeof(sin_dst.sin_addr));
|
||||
sinp = in_selectsrc(&sin_dst,
|
||||
(struct route *)&in6p->in6p_route,
|
||||
in6p->in6p_socket->so_options,
|
||||
NULL, &error);
|
||||
if (sinp == NULL) {
|
||||
if (error == 0)
|
||||
error = EADDRNOTAVAIL;
|
||||
goto release;
|
||||
}
|
||||
bzero(&laddr_mapped, sizeof(laddr_mapped));
|
||||
laddr_mapped.s6_addr16[5] = 0xffff; /* ugly */
|
||||
bcopy(&sinp->sin_addr,
|
||||
&laddr_mapped.s6_addr[12],
|
||||
sizeof(sinp->sin_addr));
|
||||
laddr = &laddr_mapped;
|
||||
} else
|
||||
{
|
||||
laddr = &in6p->in6p_laddr; /* XXX */
|
||||
}
|
||||
}
|
||||
if (laddr == NULL) {
|
||||
if (error == 0)
|
||||
error = EADDRNOTAVAIL;
|
||||
@ -206,18 +273,30 @@ udp6_output(in6p, m, addr6, control, p)
|
||||
error = ENOTCONN;
|
||||
goto release;
|
||||
}
|
||||
if (IN6_IS_ADDR_V4MAPPED(&in6p->in6p_faddr)) {
|
||||
if ((in6p->in6p_flags & IN6P_IPV6_V6ONLY))
|
||||
{
|
||||
/*
|
||||
* XXX: this case would happen when the
|
||||
* application sets the V6ONLY flag after
|
||||
* connecting the foreign address.
|
||||
* Such applications should be fixed,
|
||||
* so we bark here.
|
||||
*/
|
||||
log(LOG_INFO, "udp6_output: IPV6_V6ONLY "
|
||||
"option was set for a connected socket\n");
|
||||
error = EINVAL;
|
||||
goto release;
|
||||
} else
|
||||
af = AF_INET;
|
||||
}
|
||||
laddr = &in6p->in6p_laddr;
|
||||
faddr = &in6p->in6p_faddr;
|
||||
fport = in6p->in6p_fport;
|
||||
}
|
||||
|
||||
if (!IN6_IS_ADDR_V4MAPPED(faddr)) {
|
||||
af = AF_INET6;
|
||||
hlen = sizeof(struct ip6_hdr);
|
||||
} else {
|
||||
af = AF_INET;
|
||||
if (af == AF_INET)
|
||||
hlen = sizeof(struct ip);
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate data length and get a mbuf
|
||||
@ -274,7 +353,7 @@ udp6_output(in6p, m, addr6, control, p)
|
||||
error = ENOBUFS;
|
||||
goto release;
|
||||
}
|
||||
#endif /*IPSEC*/
|
||||
#endif /* IPSEC */
|
||||
error = ip6_output(m, in6p->in6p_outputopts, &in6p->in6p_route,
|
||||
flags, in6p->in6p_moptions, NULL);
|
||||
break;
|
||||
@ -287,23 +366,31 @@ udp6_output(in6p, m, addr6, control, p)
|
||||
}
|
||||
|
||||
ip = mtod(m, struct ip *);
|
||||
ui = (struct udpiphdr *)ip;
|
||||
bzero(ui->ui_x1, sizeof ui->ui_x1);
|
||||
ui->ui_pr = IPPROTO_UDP;
|
||||
ui->ui_len = htons(plen);
|
||||
bcopy(&faddr->s6_addr[12], &ui->ui_dst, sizeof(ui->ui_dst));
|
||||
ui->ui_ulen = ui->ui_len;
|
||||
|
||||
ip->ip_len = plen;
|
||||
ip->ip_p = IPPROTO_UDP;
|
||||
ip->ip_ttl = in6_selecthlim(in6p, NULL); /*XXX*/
|
||||
ip->ip_tos = 0; /*XXX*/
|
||||
bcopy(&laddr->s6_addr[12], &ip->ip_src, sizeof(ip->ip_src));
|
||||
bcopy(&faddr->s6_addr[12], &ip->ip_dst, sizeof(ip->ip_dst));
|
||||
|
||||
udp6->uh_sum = 0;
|
||||
if ((udp6->uh_sum = in_cksum(m, ulen)) == 0)
|
||||
flags = (in6p->in6p_socket->so_options &
|
||||
(SO_DONTROUTE | SO_BROADCAST));
|
||||
bcopy(&laddr->s6_addr[12], &ui->ui_src, sizeof(ui->ui_src));
|
||||
udp6->uh_sum = in_cksum(m, hlen + plen);
|
||||
if (udp6->uh_sum == 0)
|
||||
udp6->uh_sum = 0xffff;
|
||||
|
||||
ip->ip_len = hlen + plen;
|
||||
ip->ip_ttl = in6_selecthlim(in6p, NULL); /* XXX */
|
||||
ip->ip_tos = 0; /* XXX */
|
||||
|
||||
ip->ip_len = hlen + plen; /* XXX */
|
||||
|
||||
udpstat.udps_opackets++;
|
||||
#ifdef IPSEC
|
||||
(void)ipsec_setsocket(m, NULL); /*XXX*/
|
||||
#endif /*IPSEC*/
|
||||
error = ip_output(m, NULL, &in6p->in6p_route, 0 /*XXX*/);
|
||||
(void)ipsec_setsocket(m, NULL); /* XXX */
|
||||
#endif /* IPSEC */
|
||||
error = ip_output(m, NULL, &in6p->in6p_route, flags /* XXX */);
|
||||
break;
|
||||
#else
|
||||
error = EAFNOSUPPORT;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: udp6_usrreq.c,v 1.45 2001/07/25 23:28:04 itojun Exp $ */
|
||||
/* $NetBSD: udp6_usrreq.c,v 1.46 2001/10/15 09:51:17 itojun Exp $ */
|
||||
/* $KAME: udp6_usrreq.c,v 1.86 2001/05/27 17:33:00 itojun Exp $ */
|
||||
|
||||
/*
|
||||
@ -266,7 +266,7 @@ udp6_input(mp, offp, proto)
|
||||
m->m_pkthdr.rcvif);
|
||||
|
||||
/*
|
||||
* KAME note: usually we drop udphdr from mbuf here.
|
||||
* KAME note: traditionally we dropped udpiphdr from mbuf here.
|
||||
* We need udphdr for IPsec processing so we do that later.
|
||||
*/
|
||||
|
||||
@ -557,7 +557,7 @@ udp6_ctlinput(cmd, sa, d)
|
||||
/*
|
||||
* Depending on the value of "valid" and routing table
|
||||
* size (mtudisc_{hi,lo}wat), we will:
|
||||
* - recalcurate the new MTU and create the
|
||||
* - recalculate the new MTU and create the
|
||||
* corresponding routing entry, or
|
||||
* - ignore the MTU change notification.
|
||||
*/
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: udp6_var.h,v 1.9 2000/06/05 06:38:23 itojun Exp $ */
|
||||
/* $NetBSD: udp6_var.h,v 1.10 2001/10/15 09:51:17 itojun Exp $ */
|
||||
/* $KAME: udp6_var.h,v 1.11 2000/06/05 00:14:31 itojun Exp $ */
|
||||
|
||||
/*
|
||||
@ -114,4 +114,4 @@ int udp6_usrreq __P((struct socket *,
|
||||
struct proc *));
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#endif /*_NETINET6_UDP6_VAR_H_*/
|
||||
#endif /* _NETINET6_UDP6_VAR_H_ */
|
||||
|
Loading…
Reference in New Issue
Block a user