diff options
author | Angelos D. Keromytis <angelos@cvs.openbsd.org> | 1999-12-08 11:28:36 +0000 |
---|---|---|
committer | Angelos D. Keromytis <angelos@cvs.openbsd.org> | 1999-12-08 11:28:36 +0000 |
commit | eb04098957140766fbf8dd44e8c49f3fbd28bd68 (patch) | |
tree | b60d10ceceb0f4fca061968757b58bd77343cd03 /sys/netinet6 | |
parent | 179bee8ee78efdd23100a699f96fe1f8da8799f7 (diff) |
Removed about 24KB of ifdef'ed code. It's nice to be able to see what
other OSes do, but not if I can't read our code.
Diffstat (limited to 'sys/netinet6')
-rw-r--r-- | sys/netinet6/in6_pcb.c | 948 |
1 files changed, 3 insertions, 945 deletions
diff --git a/sys/netinet6/in6_pcb.c b/sys/netinet6/in6_pcb.c index f101e229833..22322457a00 100644 --- a/sys/netinet6/in6_pcb.c +++ b/sys/netinet6/in6_pcb.c @@ -43,10 +43,6 @@ didn't get a copy, you may request one from <license@ipv6.nrl.navy.mil>. * */ -#if __FreeBSD__ -#include <sys/queue.h> -#endif /* __FreeBSD__ */ - #include <sys/param.h> #include <sys/systm.h> #include <sys/malloc.h> @@ -55,7 +51,6 @@ didn't get a copy, you may request one from <license@ipv6.nrl.navy.mil>. #include <sys/protosw.h> #include <sys/socket.h> #include <sys/socketvar.h> -/*#include <sys/ioctl.h>*/ #include <sys/errno.h> #include <sys/time.h> #include <sys/proc.h> @@ -72,74 +67,25 @@ didn't get a copy, you may request one from <license@ipv6.nrl.navy.mil>. #include <netinet6/ip6.h> #include <netinet6/ip6_var.h> -#if __OpenBSD__ -#undef IPSEC -#ifdef NRL_IPSEC -#define IPSEC 1 -#endif /* NRL_IPSEC */ -#endif /* __OpenBSD__ */ - -#ifdef IPSEC -#include <sys/osdep.h> -#include <net/netproc.h> -#include <net/netproc_var.h> -#endif /* IPSEC */ - -#if defined(_BSDI_VERSION) && (_BSDI_VERSION >= 199802) -#include <machine/pcpu.h> -#endif /* defined(_BSDI_VERSION) && (_BSDI_VERSION >= 199802) */ - -#ifdef DEBUG_NRL -#include <sys/debug.h> -#else /* DEBUG_NRL */ -#if __OpenBSD__ -#include <netinet6/debug.h> -#else /* __OpenBSD__ */ -#include <sys/debug.h> -#endif /* __OpenBSD__ */ -#endif /* DEBUG_NRL */ - /* * External globals */ -#if __OpenBSD__ #include <dev/rndvar.h> -#endif /* __OpenBSD__ */ - -#if __FreeBSD__ -/* - * 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 */ -extern void in_rtchange(struct inpcb *, int); -#endif /* __FreeBSD__ */ extern struct in6_ifaddr *in6_ifaddr; -#if __FreeBSD__ -int in6_pcbladdr(register struct inpcb *, struct sockaddr *, struct sockaddr **); -extern TAILQ_HEAD(in_ifaddrhead, in_ifaddr) in_ifaddrhead; -#else /* __FreeBSD__ */ extern struct in_ifaddr *in_ifaddr; -#endif /* __FreeBSD__ */ + /* * Globals */ struct in6_addr zeroin6_addr; -#if __OpenBSD__ extern int ipport_firstauto; extern int ipport_lastauto; extern int ipport_hifirstauto; extern int ipport_hilastauto; -#endif /* __OpenBSD__ */ /* * Keep separate inet6ctlerrmap, because I may remap some of these. @@ -163,29 +109,13 @@ u_char inet6ctlerrmap[PRC_NCMDS] = { int in6_pcbbind(inp, nam) register struct inpcb *inp; -#if __FreeBSD__ - struct sockaddr *nam; -#else /* __FreeBSD__ */ struct mbuf *nam; -#endif /* __FreeBSD__ */ { register struct socket *so = inp->inp_socket; -#if __NetBSD__ || __OpenBSD__ register struct inpcbtable *head = inp->inp_table; -#else /* __OpenBSD__ */ -#ifndef __FreeBSD__ - register struct inpcb *head = inp->inp_head; -#else /* __FreeBSD__ */ - struct inpcbinfo *pcbinfo = inp->inp_pcbinfo; -#endif /* __FreeBSD__ */ -#endif /* __NetBSD__ || __OpenBSD__ */ register struct sockaddr_in6 *sin6; -#if !defined(_BSDI_VERSION) || (_BSDI_VERSION < 199802) struct proc *p = curproc; /* XXX */ -#else /* !defined(_BSDI_VERSION) || (_BSDI_VERSION < 199802) */ - struct proc *p = PCPU(curproc); /* XXX */ -#endif /* !defined(_BSDI_VERSION) || (_BSDI_VERSION < 199802) */ u_short lport = 0; int wild = INPLOOKUP_IPV6, reuseport = (so->so_options & SO_REUSEPORT); int error; @@ -195,13 +125,9 @@ in6_pcbbind(inp, nam) * too. (Same with in6_pcbconnect.) */ -#if __FreeBSD__ - if (in6_ifaddr == 0 || in_ifaddrhead.tqh_first == 0) - return EADDRNOTAVAIL; -#else /* __FreeBSD__ */ if (in6_ifaddr == 0 || in_ifaddr == 0) return EADDRNOTAVAIL; -#endif/* __FreeBSD__ */ + if (inp->inp_lport != 0 || !IN6_IS_ADDR_UNSPECIFIED(&inp->inp_laddr6)) return EINVAL; /* If already bound, EINVAL! */ @@ -215,15 +141,9 @@ in6_pcbbind(inp, nam) */ if (nam) { -#if __FreeBSD__ - sin6 = (struct sockaddr_in6 *)nam; - if (nam->sa_len != sizeof (*sin6)) - return EINVAL; -#else /* __FreeBSD__ */ sin6 = mtod(nam, struct sockaddr_in6 *); if (nam->m_len != sizeof (*sin6)) return EINVAL; -#endif /* __FreeBSD__ */ /* * Unlike v4, I have no qualms about EAFNOSUPPORT if the @@ -288,34 +208,13 @@ in6_pcbbind(inp, nam) la.s_addr = sin6->sin6_addr.s6_addr32[3]; wild &= ~INPLOOKUP_IPV6; -#if __FreeBSD__ - t = in_pcblookup_local(inp->inp_pcbinfo, - (struct in_addr *)&la, lport, wild); -#else /* __FreeBSD__ */ -#if __NetBSD__ - t = in_pcblookup_port(inp->inp_table, (struct in_addr *)&la, - lport, wild); -#else /* __NetBSD__ */ t = in_pcblookup(head, (struct in_addr *)&fa, 0, (struct in_addr *)&la, lport, wild); -#endif /* __NetBSD__ */ -#endif /* __FreeBSD__ */ - } else { -#if __FreeBSD__ - t = in_pcblookup_local(inp->inp_pcbinfo, - (struct in_addr *)&sin6->sin6_addr, lport, wild); -#else /* __FreeBSD__ */ -#if __NetBSD__ - t = in_pcblookup_port(inp->inp_table, - (struct in_addr *)&in6addr_any, lport, wild); -#else /* __NetBSD__ */ t = in_pcblookup(head, (struct in_addr *)&zeroin6_addr, 0, (struct in_addr *)&sin6->sin6_addr, lport, wild); -#endif /* __NetBSD__ */ -#endif /* __FreeBSD__ */ } if (t && (reuseport & t->inp_socket->so_options) == 0) @@ -356,14 +255,8 @@ in6_pcbbind(inp, nam) int loopcount = 0; struct in_addr fa, la; u_int16_t *lastport; -#if defined(_BSDI_VERSION) && (_BSDI_VERSION >= 199802) - u_int16_t last_port = head->inp_lport; - lastport = &last_port; -#endif /* defined(_BSDI_VERSION) && (_BSDI_VERSION >= 199802) */ -#if __NetBSD__ || __OpenBSD__ lastport = &inp->inp_table->inpt_lastport; -#endif /* __NetBSD__ || __OpenBSD__ */ if (inp->inp_flags & INP_IPV6_MAPPED) { la.s_addr = inp->inp_laddr6.s6_addr32[3]; @@ -371,44 +264,19 @@ in6_pcbbind(inp, nam) wild &= ~INPLOOKUP_IPV6; }; -#if __OpenBSD__ || __FreeBSD__ -#if __FreeBSD__ - inp->inp_flags |= INP_ANONPORT; -#endif /* __FreeBSD__ */ - if (inp->inp_flags & INP_HIGHPORT) { first = ipport_hifirstauto; /* sysctl */ last = ipport_hilastauto; -#if __FreeBSD__ - lastport = &pcbinfo->lasthi; -#endif /* __FreeBSD__ */ } else if (inp->inp_flags & INP_LOWPORT) { if ((error = suser(p->p_ucred, &p->p_acflag))) return (EACCES); -#if __FreeBSD__ - first = ipport_lowfirstauto; - last = ipport_lowlastauto; - lastport = &pcbinfo->lastlow; -#else /* __FreeBSD__ */ + first = IPPORT_RESERVED-1; /* 1023 */ last = 600; /* not IPPORT_RESERVED/2 */ -#endif /* __FreeBSD__ */ } else { first = ipport_firstauto; /* sysctl */ last = ipport_lastauto; -#if __FreeBSD__ - lastport = &pcbinfo->lastport; -#endif /* __FreeBSD__ */ } -#else /* __OpenBSD__ */ -#if __bsdi__ - first = IPPORT_DYNAMIC; - last = IPPORT_DYNAMIC_LAST; -#else /* __bsdi__ */ - first = IPPORT_RESERVED; - last = IPPORT_USERRESERVED; -#endif /* __bsdi__ */ -#endif /* __OpenBSD__ */ /* * Simple check to ensure all ports are not used up causing @@ -425,11 +293,7 @@ portloop: */ if (loopcount == 0) { /* only do this once. */ old = first; -#if __OpenBSD__ first -= (arc4random() % (first - last)); -#else /* __OpenBSD__ */ - first -= (random() % (first - last)); -#endif /* __OpenBSD__ */ } count = first - last; *lastport = first; /* restart each time */ @@ -447,40 +311,19 @@ portloop: if (*lastport > first || *lastport < last) *lastport = first; lport = htons(*lastport); -#if __OpenBSD__ } while (in_baddynamic(*lastport, so->so_proto->pr_protocol) || -#else /* __OpenBSD__ */ - } while ( -#endif /* __OpenBSD__ */ ((wild & INPLOOKUP_IPV6) ? -#ifdef __FreeBSD__ - in_pcblookup_local(pcbinfo, - (struct in_addr *)&inp->inp_laddr6, lport, wild) : - in_pcblookup_local(pcbinfo, - (struct in_addr *)&la, lport, wild))); -#else /* __FreeBSD__ */ -#if __NetBSD__ - in_pcblookup_port(head, (struct in_addr *)&inp->inp_laddr6, - lport, wild) : - in_pcblookup_port(head, (struct in_addr *)&la, lport, wild))); -#else /* __NetBSD__ */ in_pcblookup(head, (struct in_addr *)&zeroin6_addr, 0, (struct in_addr *)&inp->inp_laddr6, lport, wild) : in_pcblookup(head, (struct in_addr *)&fa, 0, (struct in_addr *)&la, lport, wild))); -#endif /* __NetBSD__ */ -#endif /* __FreeBSD__ */ } else { /* * counting up */ if (loopcount == 0) { /* only do this once. */ old = first; -#if __OpenBSD__ first += (arc4random() % (last - first)); -#else /* __OpenBSD__ */ - first += (random() % (last - first)); -#endif /* __OpenBSD__ */ } count = last - first; *lastport = first; /* restart each time */ @@ -498,331 +341,22 @@ portloop: if (*lastport < first || *lastport > last) *lastport = first; lport = htons(*lastport); -#if __OpenBSD__ } while (in_baddynamic(*lastport, so->so_proto->pr_protocol) || -#else /* __OpenBSD__ */ - } while ( -#endif /* __OpenBSD__ */ ((wild & INPLOOKUP_IPV6) ? -#ifdef __FreeBSD__ - in_pcblookup_local(pcbinfo, - (struct in_addr *)&inp->inp_laddr6, lport, wild) : - in_pcblookup_local(pcbinfo, - (struct in_addr *)&la, lport, wild))); -#else /* __FreeBSD__ */ -#if __NetBSD__ - in_pcblookup_port(head, (struct in_addr *)&inp->inp_laddr6, - lport, wild) : - in_pcblookup_port(head, (struct in_addr *)&la, lport, wild))); -#else /* __NetBSD__ */ in_pcblookup(head, (struct in_addr *)&zeroin6_addr, 0, (struct in_addr *)&inp->inp_laddr6, lport, wild) : in_pcblookup(head, (struct in_addr *)&fa, 0, (struct in_addr *)&la, lport, wild))); -#endif /* __NetBSD__ */ -#endif /* __FreeBSD__ */ } } inp->inp_lport = lport; -#if __FreeBSD__ -#if 0 - inp->inp_laddr.s_addr = inp->inp_laddr6.s6_addr32[3] - ^ inp->inp_laddr6.s6_addr32[1]; - /* - * If this is FreeBSD then it requires the inpcb structure to be - * inserted into various hash-tables. Right now this is copies - * directly from FreeBSD's source, but this will have to change for - * v6 addresses soon I think. We're still not sure if word2 XOR word4 - * is a good subject for the hash function. - */ -#endif /* 0 */ - if (in_pcbinshash(inp) != 0) { - bzero(&inp->inp_laddru, sizeof(inp->inp_laddru)); - inp->inp_lport = 0; - return (EAGAIN); - } -#endif /* __FreeBSD__ */ -#if __NetBSD__ - in_pcbstate(inp, INP_BOUND); -#endif /* __NetBSD__ */ - /* XXX hash */ return 0; } /*---------------------------------------------------------------------- - * This is maximum suckage point value. This function is the first - * half or so of in6_pcbconnect. It exists because FreeBSD's code - * supports this function for T/TCP. If we want TCP to work with our - * code it must be supported. - ----------------------------------------------------------------------*/ -#if __FreeBSD__ -int -in6_pcbladdr(inp, nam, plocal_sin) - register struct inpcb *inp; - struct sockaddr *nam; - struct sockaddr **plocal_sin; -{ - - struct in6_ifaddr *i6a; - struct sockaddr_in *ifaddr = NULL; - - register struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)nam; - if (nam->sa_len != sizeof(struct sockaddr_in6)) - return (EINVAL); - - if (sin6->sin6_family != AF_INET6) - return (EAFNOSUPPORT); - if (sin6->sin6_port == 0) - return (EADDRNOTAVAIL); - - - if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) - { - struct domain hackdomain, *save; - struct sockaddr_in *sin; - int rc; - - /* - * FreeBSD doesn't want an mbuf to pcbconnect. - */ - struct sockaddr_in hacksin; - - /* - * Hmmm, if this is a v4-mapped v6 address, re-call in_pcbconnect - * with a fake domain for now. Then re-adjust the socket, and - * return out of here. Since this is called at splnet(), I don't - * think temporarily altering the socket will matter. XXX - */ - - /* - * Can't have v6 talking to v4, now can we! - */ - if (!IN6_IS_ADDR_UNSPECIFIED(&inp->inp_laddr6) && - !IN6_IS_ADDR_V4MAPPED(&inp->inp_laddr6)) - return EINVAL; - - bzero(&hackdomain,sizeof(hackdomain)); - save = inp->inp_socket->so_proto->pr_domain; - inp->inp_socket->so_proto->pr_domain = &hackdomain; - hackdomain.dom_family = PF_INET; - - sin = &hacksin; - sin->sin_len = sizeof(*sin); - sin->sin_family = AF_INET; - sin->sin_port = sin6->sin6_port; - sin->sin_addr.s_addr = sin6->sin6_addr.s6_addr32[3]; - - /* CHANGE */ - rc = in_pcbladdr(inp, (struct sockaddr *) sin, &ifaddr); - - inp->inp_socket->so_proto->pr_domain = save; - - if (rc == 0) - { - inp->inp_laddr6.s6_addr32[2] = htonl(0xffff); - inp->inp_faddr6.s6_addr32[2] = htonl(0xffff); - inp->inp_flags |= INP_IPV6_MAPPED; - inp->inp_flags &= ~INP_IPV6_UNDEC; - } - *plocal_sin = (struct sockaddr *)ifaddr; - - return rc; - } - - if (in6_ifaddr && IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) - { - /* - * If the destination address is all 0's, - * use the first non-loopback (and if possibly, non-link-local, else - * use the LAST link-local, non-loopback) address as the destination. - */ -#define satosin6(sa) ((struct sockaddr_in6 *)(sa)) -#define sin6tosa(sin6) ((struct sockaddr *)(sin6)) -#define ifatoi6a(ifa) ((struct in6_ifaddr *)(ifa)) - struct in6_ifaddr *ti6a = NULL; - - for (i6a = in6_ifaddr; i6a; i6a = i6a->ia_next) - { - /* Find first (non-link-local if possible) address for - source usage. If multiple link-locals, use last one found. */ - if (IN6_IS_ADDR_LINKLOCAL(&IA6_SIN6(i6a)->sin6_addr)) - ti6a=i6a; - else if (!IN6_IS_ADDR_LOOPBACK(&IA6_SIN6(i6a)->sin6_addr)) - break; - } - if (i6a == NULL && ti6a != NULL) - i6a = ti6a; - } - - if (IN6_IS_ADDR_UNSPECIFIED(&inp->inp_laddr6)) - { - register struct route_in6 *ro; - - i6a = NULL; - /* - * If route is known or can be allocated now, - * our src addr is taken from the rt_ifa, else punt. - */ - ro = &inp->inp_route6; - if (ro->ro_rt && - (ro->ro_dst.sin6_family != sin6->sin6_family || - rt_key(ro->ro_rt)->sa_family != sin6->sin6_family || - !IN6_ARE_ADDR_EQUAL(&ro->ro_dst.sin6_addr, &sin6->sin6_addr) || - inp->inp_socket->so_options & SO_DONTROUTE)) - { - RTFREE(ro->ro_rt); - ro->ro_rt = NULL; - } - if ((inp->inp_socket->so_options & SO_DONTROUTE) == 0 && /*XXX*/ - (ro->ro_rt == NULL || ro->ro_rt->rt_ifp == NULL)) - { - /* No route yet, try and acquire one. */ - ro->ro_dst.sin6_family = AF_INET6; /* Is ro blanked out? */ - ro->ro_dst.sin6_len = sizeof(struct sockaddr_in6); - ro->ro_dst.sin6_addr = sin6->sin6_addr; - /* - * Need to wipe out the flowlabel for ifa_ifwith* - * but don't need to for rtalloc. - */ - rtalloc((struct route *)ro); - } - -#if 0 /* NRL IPv6*/ - if (ro->ro_rt == NULL) - { - /* - * No route of any kind, so spray neighbor solicits out all - * interfaces, unless it's a multicast address. - */ - if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) - return ENETUNREACH; - ipv6_onlink_query((struct sockaddr_in6 *)&ro->ro_dst); - rtalloc((struct route *)ro); - } -#endif - if (ro->ro_rt == NULL) - { - /* - * ipv6_onlink_query() should've added a route. It probably - * failed. - */ - DPRINTF(IDL_GROSS_EVENT, ("v6_output: onlink_query didn't add route!\n")); - return ENETUNREACH; - } - - if (ro->ro_rt->rt_ifa == NULL) - { - /* - * We have a route where we don't quite know which interface - * the neighbor belongs to yet. If I get here, I know that this - * route is not pre-allocated (such as done by in6_pcbconnect()), - * because those pre-allocators will do the same ipv6_onlink_query() - * and ipv6_verify_onlink() in advance. - * - * I can therefore free the route, and get it again. - */ - int error; - - RTFREE(ro->ro_rt); - ro->ro_rt = NULL; - switch (error = ipv6_verify_onlink(&ro->ro_dst)) - { - case -1: - return ENETUNREACH; - case 0: - break; - default: - return error; - } - rtalloc((struct route *)ro); - if (ro->ro_rt == NULL || ro->ro_rt->rt_ifa == NULL) - panic("Oops2, I'm forgetting something after verify_onlink()."); - } - - - /* - * If we found a route, use the address - * corresponding to the outgoing interface - * unless it is the loopback (in case a route - * to our address on another net goes to loopback). - * - * This code may be simplified if the above gyrations work. - */ - if (ro->ro_rt && ro->ro_rt->rt_ifp && - !(ro->ro_rt->rt_ifp->if_flags & IFF_LOOPBACK)) - i6a = ifatoi6a(ro->ro_rt->rt_ifa); - if (i6a == NULL) - { - u_short fport = sin6->sin6_port; - - /* - * Source address selection when there is no route. - * - * If ND out all if's is to be used, this is the point to do it. - * (Similar to when the route lookup fails in ipv6_output.c, and - * the 'on-link' assumption kicks in.) - * - * For multicast, use i6a of mcastdef. - */ - - sin6->sin6_port = 0; - i6a = ifatoi6a(ifa_ifwithdstaddr(sin6tosa(sin6))); - if (i6a == NULL) - i6a = ifatoi6a(ifa_ifwithnet(sin6tosa(sin6))); - sin6->sin6_port = fport; - if (i6a == NULL) - { - struct in6_ifaddr *ti6a = NULL; - - for (i6a = in6_ifaddr; i6a; i6a = i6a->ia_next) - { - /* Find first (non-local if possible) address for - source usage. If multiple locals, use last one found. */ - if (IN6_IS_ADDR_LINKLOCAL(&IA6_SIN6(i6a)->sin6_addr)) - ti6a=i6a; - else if (!IN6_IS_ADDR_LOOPBACK(&IA6_SIN6(i6a)->sin6_addr)) - break; - } - if (i6a == NULL && ti6a != NULL) - i6a = ti6a; - } - if (i6a == NULL) - return EADDRNOTAVAIL; - } - - /* - * If I'm "connecting" to a multicast address, gyrate properly to - * get a source address based upon the user-requested mcast interface. - */ - if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr) && inp->inp_moptions6 != NULL && - (inp->inp_flags & INP_IPV6_MCAST)) - { - struct ip6_hdr_moptions *im6o; - struct ifnet *ifp; - - im6o = inp->inp_moptions6; - if (im6o->im6o_multicast_ifp != NULL) - { - ifp = im6o->im6o_multicast_ifp; - for (i6a = in6_ifaddr; i6a; i6a = i6a->ia_next) - if (i6a->ia_ifp == ifp) /* Linkloc vs. global? */ - break; - if (i6a == NULL) - return EADDRNOTAVAIL; - } - } - - *plocal_sin = (struct sockaddr *)&i6a->i6a_addr; - } - - return (0); -} -#endif /* __FreeBSD__ */ - -/*---------------------------------------------------------------------- * Connect from a socket to a specified address. * Both address and port must be specified in argument sin6. * Eventually, flow labels will have to be dealt with here, as well. @@ -836,353 +370,7 @@ in6_pcbladdr(inp, nam, plocal_sin) int in6_pcbconnect(inp, nam) register struct inpcb *inp; -#if __FreeBSD__ - struct sockaddr *nam; -#else /* __FreeBSD__ */ struct mbuf *nam; -#endif /* __FreeBSD__ */ -#if 0 -{ - struct in6_ifaddr *i6a; - struct sockaddr_in6 *ifaddr = NULL; - -#if __FreeBSD__ - register struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)nam; -#else /* __FreeBSD__ */ - register struct sockaddr_in6 *sin6 = mtod(nam, struct sockaddr_in6 *); - if (nam->m_len != sizeof(struct sockaddr_in6)) - return (EINVAL); -#endif /* __FreeBSD__ */ - - if (sin6->sin6_len != sizeof(struct sockaddr_in6)) - return (EINVAL); - if (sin6->sin6_family != AF_INET6) - return (EAFNOSUPPORT); - if (sin6->sin6_port == 0) - return (EADDRNOTAVAIL); - - if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) - { - struct domain hackdomain, *save; - struct mbuf hackmbuf; - struct sockaddr_in *sin; - int rc; - -#if __FreeBSD__ - /* - * FreeBSD doesn't want an mbuf to pcbconnect. - */ - struct sockaddr_in hacksin; -#endif /* __FreeBSD__ */ - - /* - * Hmmm, if this is a v4-mapped v6 address, re-call in_pcbconnect - * with a fake domain for now. Then re-adjust the socket, and - * return out of here. Since this is called at splnet(), I don't - * think temporarily altering the socket will matter. XXX - */ - - /* - * Can't have v6 talking to v4, now can we! - */ - if (!IN6_IS_ADDR_UNSPECIFIED(&inp->inp_laddr6) && - !IN6_IS_ADDR_V4MAPPED(&inp->inp_laddr6)) - return EINVAL; - - bzero(&hackdomain,sizeof(hackdomain)); - bzero(&hackmbuf,sizeof(hackmbuf)); - save = inp->inp_socket->so_proto->pr_domain; - inp->inp_socket->so_proto->pr_domain = &hackdomain; - hackdomain.dom_family = PF_INET; -#ifndef __FreeBSD__ - hackmbuf.m_hdr = nam->m_hdr; -#endif /* __FreeBSD__ */ - hackmbuf.m_len = sizeof(*sin); - hackmbuf.m_data = hackmbuf.m_dat; - -#if __FreeBSD__ - sin = &hacksin; -#else /* __FreeBSD__ */ - sin = mtod(&hackmbuf,struct sockaddr_in *); -#endif /* __FreeBSD__ */ - sin->sin_len = sizeof(*sin); - sin->sin_family = AF_INET; - sin->sin_port = sin6->sin6_port; - sin->sin_addr.s_addr = sin6->sin6_addr.s6_addr32[3]; - -#if __FreeBSD__ - { -#if !defined(_BSDI_VERSION) || (_BSDI_VERSION < 199802) - struct proc *p = curproc; /* XXX */ -#else /* !defined(_BSDI_VERSION) || (_BSDI_VERSION < 199802) */ - struct proc *p = PCPU(curproc); /* XXX */ -#endif /* !defined(_BSDI_VERSION) || (_BSDI_VERSION < 199802) */ - rc = in_pcbconnect(inp, (struct sockaddr *) sin, p); - } -#else /* __FreeBSD__ */ - rc = in_pcbconnect(inp,&hackmbuf); -#endif /* __FreeBSD__ */ - - inp->inp_socket->so_proto->pr_domain = save; - - if (rc == 0) - { - inp->inp_laddr6.s6_addr32[2] = htonl(0xffff); - inp->inp_faddr6.s6_addr32[2] = htonl(0xffff); - inp->inp_flags |= INP_IPV6_MAPPED; - inp->inp_flags &= ~INP_IPV6_UNDEC; - } - - return rc; - } - - if (in6_ifaddr && IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) - { - /* - * If the destination address is all 0's, - * use the first non-loopback (and if possibly, non-link-local, else - * use the LAST link-local, non-loopback) address as the destination. - */ -#define satosin6(sa) ((struct sockaddr_in6 *)(sa)) -#define sin6tosa(sin6) ((struct sockaddr *)(sin6)) -#define ifatoi6a(ifa) ((struct in6_ifaddr *)(ifa)) - struct in6_ifaddr *ti6a = NULL; - - for (i6a = in6_ifaddr; i6a; i6a = i6a->ia_next) - { - /* Find first (non-link-local if possible) address for - source usage. If multiple link-locals, use last one found. */ - if (IN6_IS_ADDR_LINKLOCAL(&IA6_SIN6(i6a)->sin6_addr)) - ti6a=i6a; - else if (!IN6_IS_ADDR_LOOPBACK(&IA6_SIN6(i6a)->sin6_addr)) - break; - } - if (i6a == NULL && ti6a != NULL) - i6a = ti6a; - } - - if (IN6_IS_ADDR_UNSPECIFIED(&inp->inp_laddr6)) - { - register struct route_in6 *ro; - - i6a = NULL; - /* - * If route is known or can be allocated now, - * our src addr is taken from the rt_ifa, else punt. - */ - ro = &inp->inp_route6; - if (ro->ro_rt && - (ro->ro_dst.sin6_family != sin6->sin6_family || - rt_key(ro->ro_rt)->sa_family != sin6->sin6_family || - !IN6_ARE_ADDR_EQUAL(&ro->ro_dst.sin6_addr, &sin6->sin6_addr) || - inp->inp_socket->so_options & SO_DONTROUTE)) - { - RTFREE(ro->ro_rt); - ro->ro_rt = NULL; - } - if ((inp->inp_socket->so_options & SO_DONTROUTE) == 0 && /*XXX*/ - (ro->ro_rt == NULL || ro->ro_rt->rt_ifp == NULL)) - { - /* No route yet, try and acquire one. */ - ro->ro_dst.sin6_family = AF_INET6; /* Is ro blanked out? */ - ro->ro_dst.sin6_len = sizeof(struct sockaddr_in6); - ro->ro_dst.sin6_addr = sin6->sin6_addr; - /* - * Need to wipe out the flowlabel for ifa_ifwith* - * but don't need to for rtalloc. - */ - rtalloc((struct route *)ro); - } - -#if 0 /* NRL IPv6*/ - if (ro->ro_rt == NULL) - { - /* - * No route of any kind, so spray neighbor solicits out all - * interfaces, unless it's a multicast address. - */ - if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) - return ENETUNREACH; - ipv6_onlink_query((struct sockaddr_in6 *)&ro->ro_dst); - rtalloc((struct route *)ro); - } -#endif - if (ro->ro_rt == NULL) - { - /* - * ipv6_onlink_query() should've added a route. It probably - * failed. - */ - DPRINTF(GROSSEVENT, ("v6_output: onlink_query didn't add route!\n")); - return ENETUNREACH; - } - -#if 0 /*NRL IPv6*/ - if (ro->ro_rt->rt_ifa == NULL) - { - /* - * We have a route where we don't quite know which interface - * the neighbor belongs to yet. If I get here, I know that this - * route is not pre-allocated (such as done by in6_pcbconnect()), - * because those pre-allocators will do the same ipv6_onlink_query() - * and ipv6_verify_onlink() in advance. - * - * I can therefore free the route, and get it again. - */ - int error; - - RTFREE(ro->ro_rt); - ro->ro_rt = NULL; - switch (error = ipv6_verify_onlink(&ro->ro_dst)) - { - case -1: - return ENETUNREACH; - case 0: - break; - default: - return error; - } - rtalloc((struct route *)ro); - if (ro->ro_rt == NULL || ro->ro_rt->rt_ifa == NULL) - panic("Oops2, I'm forgetting something after verify_onlink()."); - } -#endif - - - /* - * If we found a route, use the address - * corresponding to the outgoing interface - * unless it is the loopback (in case a route - * to our address on another net goes to loopback). - * - * This code may be simplified if the above gyrations work. - */ - if (ro->ro_rt && ro->ro_rt->rt_ifp && - !(ro->ro_rt->rt_ifp->if_flags & IFF_LOOPBACK)) - i6a = ifatoi6a(ro->ro_rt->rt_ifa); - if (i6a == NULL) - { - u_short fport = sin6->sin6_port; - - /* - * Source address selection when there is no route. - * - * If ND out all if's is to be used, this is the point to do it. - * (Similar to when the route lookup fails in ipv6_output.c, and - * the 'on-link' assumption kicks in.) - * - * For multicast, use i6a of mcastdef. - */ - - sin6->sin6_port = 0; - i6a = ifatoi6a(ifa_ifwithdstaddr(sin6tosa(sin6))); - if (i6a == NULL) - i6a = ifatoi6a(ifa_ifwithnet(sin6tosa(sin6))); - sin6->sin6_port = fport; - if (i6a == NULL) - { - struct in6_ifaddr *ti6a = NULL; - - for (i6a = in6_ifaddr; i6a; i6a = i6a->ia_next) - { - /* Find first (non-local if possible) address for - source usage. If multiple locals, use last one found. */ - if (IN6_IS_ADDR_LINKLOCAL(&IA6_SIN6(i6a)->sin6_addr)) - ti6a=i6a; - else if (!IN6_IS_ADDR_LOOPBACK(&IA6_SIN6(i6a)->sin6_addr)) - break; - } - if (i6a == NULL && ti6a != NULL) - i6a = ti6a; - } - if (i6a == NULL) - return EADDRNOTAVAIL; - } - - /* - * If I'm "connecting" to a multicast address, gyrate properly to - * get a source address based upon the user-requested mcast interface. - */ - if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr) && inp->inp_moptions6 != NULL && - (inp->inp_flags & INP_IPV6_MCAST)) - { - struct ip6_moptions *im6o; - struct ifnet *ifp; - - im6o = inp->inp_moptions6; - if (im6o->im6o_multicast_ifp != NULL) - { - ifp = im6o->im6o_multicast_ifp; - for (i6a = in6_ifaddr; i6a; i6a = i6a->ia_next) - if (i6a->ia_ifp == ifp) /* Linkloc vs. global? */ - break; - if (i6a == NULL) - return EADDRNOTAVAIL; - } - } - - ifaddr = (struct sockaddr_in6 *)&i6a->ia_addr; - } - -#if __FreeBSD__ - if (in_pcblookup_hash(inp->inp_pcbinfo, - ((IN6_IS_ADDR_UNSPECIFIED(&inp->inp_laddr6)) ? - (struct in_addr *)&ifaddr->sin6_addr : - (struct in_addr *)&inp->inp_laddr6), - sin6->sin6_port, (struct in_addr *)&sin6->sin6_addr, - inp->inp_lport, INPLOOKUP_IPV6)) return EADDRINUSE; -#else /* __FreeBSD__ */ -#if __NetBSD__ - if (in6_pcblookup_connect(inp->inp_table, - ((IN6_IS_ADDR_UNSPECIFIED(&inp->inp_laddr6)) ? &ifaddr->sin6_addr : - &inp->inp_laddr6), sin6->sin6_port, &sin6->sin6_addr, inp->inp_lport)) - return EADDRINUSE; -#else /* __NetBSD__ */ -#ifdef __OpenBSD__ - if (in_pcblookup(inp->inp_table, ((IN6_IS_ADDR_UNSPECIFIED(&inp->inp_laddr6)) ? -#else /* __OpenBSD__ */ - if (in_pcblookup(inp->inp_head, ((IN6_IS_ADDR_UNSPECIFIED(&inp->inp_laddr6)) ? -#endif /* __OpenBSD__ */ - (struct in_addr *)&ifaddr->sin6_addr : - (struct in_addr *)&inp->inp_laddr6), - sin6->sin6_port, (struct in_addr *)&sin6->sin6_addr, - inp->inp_lport, INPLOOKUP_IPV6)) return EADDRINUSE; -#endif /* __NetBSD__ */ -#endif /* __FreeBSD__ */ - - if (IN6_IS_ADDR_UNSPECIFIED(&inp->inp_laddr6)) - { - if (inp->inp_lport == 0) - (void)in6_pcbbind(inp, NULL); /* To find free port & bind to it. */ - inp->inp_laddr6 = ifaddr->sin6_addr; - } - inp->inp_faddr6 = sin6->sin6_addr; - inp->inp_fport = sin6->sin6_port; - - /* - * Assumes user specify flowinfo in network order. - */ - inp->inp_ipv6.ip6_flow = htonl(0x60000000) | - (sin6->sin6_flowinfo & htonl(0x0fffffff)); - -#if __NetBSD__ - in_pcbstate(inp, INP_CONNECTED); -#endif /* __NetBSD__ */ - -#if __FreeBSD__ - /* - * See pcbbind near the end for reasoning on setting this for a value to - * hash on. - */ -#if 0 - inp->inp_laddr.s_addr = inp->inp_laddr6.s6_addr32[3] - ^ inp->inp_laddr6.s6_addr32[1]; -#endif /* 0 */ - in_pcbrehash(inp); -#endif /* __FreeBSD__ */ - return 0; -} -#else { struct in6_addr *in6a = NULL; struct sockaddr_in6 *sin6 = mtod(nam, struct sockaddr_in6 *); @@ -1314,7 +502,6 @@ in6_pcbconnect(inp, nam) in_pcbrehash(inp); return(0); } -#endif /*---------------------------------------------------------------------- * Pass some notification to all connections of a protocol @@ -1332,44 +519,19 @@ in6_pcbconnect(inp, nam) ----------------------------------------------------------------------*/ int -#ifdef IPSEC -in6_pcbnotify(head, dst, fport_arg, la, lport_arg, cmd, notify, m, nexthdr) -#else /* IPSEC */ in6_pcbnotify(head, dst, fport_arg, la, lport_arg, cmd, notify) -#endif /* IPSEC */ -#if __NetBSD__ || __OpenBSD__ struct inpcbtable *head; -#else /* __NetBSD__ || __OpenBSD__ */ -#if __FreeBSD__ - struct inpcbhead *head; -#else /* __FreeBSD__ */ - struct inpcb *head; -#endif /* __FreeBSD__ */ -#endif /* __NetBSD__ || __OpenBSD__ */ struct sockaddr *dst; uint fport_arg; struct in6_addr *la; uint lport_arg; int cmd; void (*notify) __P((struct inpcb *, int)); -#ifdef IPSEC - struct mbuf *m; - int nexthdr; -#endif /* IPSEC */ { register struct inpcb *inp, *oinp; struct in6_addr *faddr,laddr = *la; u_short fport = fport_arg, lport = lport_arg; int errno; -#ifdef IPSEC - struct sockaddr_in6 srcsa, dstsa; -#endif /* IPSEC */ - - DPRINTF(IDL_EVENT,("Entering in6_pcbnotify. head = 0x%lx, dst is\n", (unsigned long)head)); - DDO(IDL_EVENT,dump_smart_sockaddr(dst)); - DPRINTF(IDL_EVENT,("fport_arg = %d, lport_arg = %d, cmd = %d\n",\ - fport_arg, lport_arg, cmd)); - DDO(IDL_EVENT,printf("la is ");dump_in6_addr(la)); if ((unsigned)cmd > PRC_NCMDS || dst->sa_family != AF_INET6) return 1; @@ -1399,33 +561,8 @@ in6_pcbnotify(head, dst, fport_arg, la, lport_arg, cmd, notify) } errno = inet6ctlerrmap[cmd]; -#ifdef IPSEC - /* Build these again because args aren't necessarily correctly formed - sockaddrs, and the policy code will eventually need that. -cmetz */ - - memset(&srcsa, 0, sizeof(struct sockaddr_in6)); - srcsa.sin6_len = sizeof(struct sockaddr_in6); - srcsa.sin6_family = AF_INET6; - /* defer port */ - srcsa.sin6_addr = *faddr; - - memset(&dstsa, 0, sizeof(struct sockaddr_in6)); - dstsa.sin6_len = sizeof(struct sockaddr_in6); - dstsa.sin6_family = AF_INET6; - /* defer port */ - dstsa.sin6_addr = laddr; -#endif /* IPSEC */ - -#if __NetBSD__ || __OpenBSD__ for (inp = head->inpt_queue.cqh_first; inp != (struct inpcb *)&head->inpt_queue;) -#else /* __NetBSD__ || __OpenBSD__ */ -#if __FreeBSD__ - for (inp = head->lh_first; inp != NULL;) -#else /* __FreeBSD__ */ - for (inp = head->inp_next; inp != head;) -#endif /* __FreeBSD__ */ -#endif /* __NetBSD__ || __OpenBSD__ */ { if (!IN6_ARE_ADDR_EQUAL(&inp->inp_faddr6, faddr) || !inp->inp_socket || @@ -1433,49 +570,14 @@ in6_pcbnotify(head, dst, fport_arg, la, lport_arg, cmd, notify) (!IN6_IS_ADDR_UNSPECIFIED(&laddr) && !IN6_ARE_ADDR_EQUAL(&inp->inp_laddr6, &laddr)) || (fport && inp->inp_fport != fport)) { -#if __NetBSD__ || __OpenBSD__ inp = inp->inp_queue.cqe_next; -#else /* __NetBSD__ || __OpenBSD__ */ -#if __FreeBSD__ - inp = inp->inp_list.le_next; -#else /* __FreeBSD__ */ - inp = inp->inp_next; -#endif /* __FreeBSD__ */ -#endif /* __NetBSD__ || __OpenBSD__ */ continue; } oinp = inp; -#if __NetBSD__ || __OpenBSD__ inp = inp->inp_queue.cqe_next; -#else /* __NetBSD__ || __OpenBSD__ */ -#if __FreeBSD__ - inp = inp->inp_list.le_next; -#else /* __FreeBSD__ */ - inp = inp->inp_next; -#endif /* __FreeBSD__ */ -#endif /* __NetBSD__ || __OpenBSD__ */ - if (notify) -#ifdef IPSEC - { - /* Pretend the packet came in for this source/destination port pair, - since that's what we care about for policy. If the passed in - fport and/or lport were nonzero, the comparison will make sure - they match that of the PCB and the right thing will happen. - -cmetz */ - srcsa.sin6_port = oinp->inp_fport; - dstsa.sin6_port = oinp->inp_lport; - - /* XXX - state arg should not be NULL */ - if (!netproc_inputpolicy(oinp->inp_socket, (struct sockaddr *)&srcsa, - (struct sockaddr *)&dstsa, nexthdr, m, NULL, - NULL)) -#endif /* IPSEC */ (*notify)(oinp, errno); -#ifdef IPSEC - } -#endif /* IPSEC */ } return 0; } @@ -1488,40 +590,18 @@ in6_pcbnotify(head, dst, fport_arg, la, lport_arg, cmd, notify) int in6_setsockaddr(inp, nam) register struct inpcb *inp; -#if __FreeBSD__ - struct sockaddr **nam; -#else /* __FreeBSD__ */ struct mbuf *nam; -#endif /* __FreeBSD__ */ { register struct sockaddr_in6 *sin6; -#if __FreeBSD__ - /* - * In FreeBSD we have to allocate the sockaddr_in6 structure since we aren't - * given an mbuf, but a sockaddr ** as the second argument. (i.e. a location - * to reference the space this routine allocates. - */ - if (!(sin6 = (struct sockaddr_in6 *)malloc(sizeof(struct sockaddr_in6),M_SONAME, M_DONTWAIT))) - return ENOBUFS; /* XXX */ - -#else /* __FreeBSD__ */ - nam->m_len = sizeof(struct sockaddr_in6); sin6 = mtod(nam,struct sockaddr_in6 *); -#endif /* __FreeBSD__ */ - bzero ((caddr_t)sin6,sizeof(struct sockaddr_in6)); sin6->sin6_family = AF_INET6; sin6->sin6_len = sizeof(struct sockaddr_in6); sin6->sin6_port = inp->inp_lport; sin6->sin6_addr = inp->inp_laddr6; - -#if __FreeBSD__ - *nam = (struct sockaddr *) sin6; -#endif /* __FreeBSD__ */ - return 0; } @@ -1533,40 +613,18 @@ in6_setsockaddr(inp, nam) int in6_setpeeraddr(inp, nam) register struct inpcb *inp; -#if __FreeBSD__ - struct sockaddr **nam; -#else /* __FreeBSD__ */ struct mbuf *nam; -#endif /* __FreeBSD__ */ { register struct sockaddr_in6 *sin6; -#if __FreeBSD__ - /* - * In FreeBSD we have to allocate the sockaddr_in6 structure since we aren't - * given an mbuf, but a sockaddr ** as the second argument. (i.e. a location - * to reference the space this routine allocates. - */ - if (!(sin6 = (struct sockaddr_in6 *)malloc(sizeof(struct sockaddr_in6),M_SONAME, M_DONTWAIT))) - return ENOBUFS; /* XXX */ - -#else /* __FreeBSD__ */ - nam->m_len = sizeof(struct sockaddr_in6); sin6 = mtod(nam,struct sockaddr_in6 *); -#endif /* __FreeBSD__ */ - bzero ((caddr_t)sin6,sizeof(struct sockaddr_in6)); sin6->sin6_family = AF_INET6; sin6->sin6_len = sizeof(struct sockaddr_in6); sin6->sin6_port = inp->inp_fport; sin6->sin6_addr = inp->inp_faddr6; sin6->sin6_flowinfo = inp->inp_fflowinfo; - -#if __FreeBSD__ - *nam = (struct sockaddr *) sin6; -#endif /* __FreeBSD__ */ - return 0; } |