version 1.173, 2016/08/01 03:15:31 |
version 1.174, 2016/09/15 18:25:45 |
Line 77 __KERNEL_RCSID(0, "$NetBSD$"); |
|
Line 77 __KERNEL_RCSID(0, "$NetBSD$"); |
|
#include <sys/protosw.h> |
#include <sys/protosw.h> |
#include <sys/socket.h> |
#include <sys/socket.h> |
#include <sys/socketvar.h> |
#include <sys/socketvar.h> |
|
#include <sys/syslog.h> |
#include <sys/systm.h> |
#include <sys/systm.h> |
#include <sys/proc.h> |
#include <sys/proc.h> |
#include <sys/kauth.h> |
#include <sys/kauth.h> |
Line 135 static int ip6_splithdr(struct mbuf *, s |
|
Line 136 static int ip6_splithdr(struct mbuf *, s |
|
static int ip6_getpmtu(struct route *, struct route *, struct ifnet *, |
static int ip6_getpmtu(struct route *, struct route *, struct ifnet *, |
const struct in6_addr *, u_long *, int *); |
const struct in6_addr *, u_long *, int *); |
static int copypktopts(struct ip6_pktopts *, struct ip6_pktopts *, int); |
static int copypktopts(struct ip6_pktopts *, struct ip6_pktopts *, int); |
|
static int ip6_ifaddrvalid(const struct in6_addr *); |
|
|
#ifdef RFC2292 |
#ifdef RFC2292 |
static int ip6_pcbopts(struct ip6_pktopts **, struct socket *, struct sockopt *); |
static int ip6_pcbopts(struct ip6_pktopts **, struct socket *, struct sockopt *); |
|
|
|
|
/* scope check is done. */ |
/* scope check is done. */ |
|
|
|
/* Ensure we only sent from a valid address. */ |
|
if ((error = ip6_ifaddrvalid(&src0)) != 0) { |
|
nd6log(LOG_ERR, |
|
"refusing to send from invalid address %s (pid %d)\n", |
|
ip6_sprintf(&src0), curproc->p_pid); |
|
if (error == 1 && ip6->ip6_nxt == IPPROTO_TCP) |
|
/* Address exists, but is tentative or detached. |
|
* We can't send from it because it's invalid, |
|
* so we drop the packet and continue ... |
|
* TCP will timeout eventually. */ |
|
error = 0; |
|
else |
|
error = EADDRNOTAVAIL; |
|
goto bad; |
|
} |
|
|
if (rt == NULL || IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) { |
if (rt == NULL || IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) { |
dst = satocsin6(rtcache_getdst(ro)); |
dst = satocsin6(rtcache_getdst(ro)); |
KASSERT(dst != NULL); |
KASSERT(dst != NULL); |
Line 3250 ip6_optlen(struct in6pcb *in6p) |
|
Line 3268 ip6_optlen(struct in6pcb *in6p) |
|
return len; |
return len; |
#undef elen |
#undef elen |
} |
} |
|
|
|
/* |
|
* Ensure sending address is valid. |
|
* Returns 0 on success, -1 if an error should be sent back or 1 |
|
* if the packet could be dropped without error (protocol dependent). |
|
*/ |
|
static int |
|
ip6_ifaddrvalid(const struct in6_addr *addr) |
|
{ |
|
struct sockaddr_in6 sin6; |
|
int s, error; |
|
struct ifaddr *ifa; |
|
struct in6_ifaddr *ia6; |
|
|
|
if (IN6_IS_ADDR_UNSPECIFIED(addr)) |
|
return 0; |
|
|
|
memset(&sin6, 0, sizeof(sin6)); |
|
sin6.sin6_family = AF_INET6; |
|
sin6.sin6_len = sizeof(sin6); |
|
sin6.sin6_addr = *addr; |
|
|
|
s = pserialize_read_enter(); |
|
ifa = ifa_ifwithaddr(sin6tosa(&sin6)); |
|
if ((ia6 = ifatoia6(ifa)) == NULL || |
|
ia6->ia6_flags & (IN6_IFF_ANYCAST | IN6_IFF_DUPLICATED)) |
|
error = -1; |
|
else if (ia6->ia6_flags & (IN6_IFF_TENTATIVE | IN6_IFF_DETACHED)) |
|
error = 1; |
|
else |
|
error = 0; |
|
pserialize_read_exit(s); |
|
|
|
return error; |
|
} |