Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet6/in6_pcb.c
Show First 20 Lines • Show All 126 Lines • ▼ Show 20 Lines | in6_pcbbind(register struct inpcb *inp, struct sockaddr *nam, | ||||
INP_HASH_WLOCK_ASSERT(pcbinfo); | INP_HASH_WLOCK_ASSERT(pcbinfo); | ||||
if (TAILQ_EMPTY(&V_in6_ifaddrhead)) /* XXX broken! */ | if (TAILQ_EMPTY(&V_in6_ifaddrhead)) /* XXX broken! */ | ||||
return (EADDRNOTAVAIL); | return (EADDRNOTAVAIL); | ||||
if (inp->inp_lport || !IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr)) | if (inp->inp_lport || !IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr)) | ||||
return (EINVAL); | return (EINVAL); | ||||
if ((so->so_options & (SO_REUSEADDR|SO_REUSEPORT)) == 0) | if ((so->so_options & (SO_REUSEADDR|SO_REUSEPORT)) == 0) | ||||
lookupflags = INPLOOKUP_WILDCARD; | lookupflags = INPLOOKUP_WILDCARD; | ||||
if (nam == NULL) { | if (nam == NULL || (inp->inp_flags & INP_ANONPORT)) { | ||||
if ((error = prison_local_ip6(cred, &inp->in6p_laddr, | if ((error = prison_local_ip6(cred, &inp->in6p_laddr, | ||||
((inp->inp_flags & IN6P_IPV6_V6ONLY) != 0))) != 0) | ((inp->inp_flags & IN6P_IPV6_V6ONLY) != 0))) != 0) | ||||
return (error); | return (error); | ||||
} else { | } else { | ||||
sin6 = (struct sockaddr_in6 *)nam; | sin6 = (struct sockaddr_in6 *)nam; | ||||
if (nam->sa_len != sizeof(*sin6)) | if (nam->sa_len != sizeof(*sin6)) | ||||
return (EINVAL); | return (EINVAL); | ||||
/* | /* | ||||
▲ Show 20 Lines • Show All 147 Lines • ▼ Show 20 Lines | #ifdef INET | ||||
(t->inp_vflag & INP_IPV6PROTO) != 0)) | (t->inp_vflag & INP_IPV6PROTO) != 0)) | ||||
return (EADDRINUSE); | return (EADDRINUSE); | ||||
} | } | ||||
#endif | #endif | ||||
} | } | ||||
inp->in6p_laddr = sin6->sin6_addr; | inp->in6p_laddr = sin6->sin6_addr; | ||||
} | } | ||||
if (lport == 0) { | if (lport == 0) { | ||||
if ((error = in6_pcbsetport(&inp->in6p_laddr, inp, cred)) != 0) { | if ((error = in6_pcbsetport(nam, &inp->in6p_laddr, inp, cred)) != 0) { | ||||
garga: style(9): Line too long | |||||
/* Undo an address bind that may have occurred. */ | /* Undo an address bind that may have occurred. */ | ||||
inp->in6p_laddr = in6addr_any; | inp->in6p_laddr = in6addr_any; | ||||
return (error); | return (error); | ||||
} | } | ||||
} else { | } else { | ||||
inp->inp_lport = lport; | inp->inp_lport = lport; | ||||
if (in_pcbinshash(inp) != 0) { | if (in_pcbinshash(inp) != 0) { | ||||
inp->in6p_laddr = in6addr_any; | inp->in6p_laddr = in6addr_any; | ||||
▲ Show 20 Lines • Show All 103 Lines • ▼ Show 20 Lines | if (in6_pcblookup_hash_locked(pcbinfo, &sin6->sin6_addr, | ||||
sin6->sin6_port, | sin6->sin6_port, | ||||
IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr) | IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr) | ||||
? &addr6 : &inp->in6p_laddr, | ? &addr6 : &inp->in6p_laddr, | ||||
inp->inp_lport, 0, NULL) != NULL) { | inp->inp_lport, 0, NULL) != NULL) { | ||||
return (EADDRINUSE); | return (EADDRINUSE); | ||||
} | } | ||||
if (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr)) { | if (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr)) { | ||||
if (inp->inp_lport == 0) { | if (inp->inp_lport == 0) { | ||||
error = in6_pcbbind(inp, (struct sockaddr *)0, cred); | inp->inp_flags |= INP_ANONPORT; | ||||
if (error) | error = in6_pcbbind(inp, nam, cred); | ||||
if (error) { | |||||
inp->inp_flags &= ~INP_ANONPORT; | |||||
return (error); | return (error); | ||||
} | |||||
} | } | ||||
inp->in6p_laddr = addr6; | inp->in6p_laddr = addr6; | ||||
} | } | ||||
inp->in6p_faddr = sin6->sin6_addr; | inp->in6p_faddr = sin6->sin6_addr; | ||||
inp->inp_fport = sin6->sin6_port; | inp->inp_fport = sin6->sin6_port; | ||||
/* update flowinfo - draft-itojun-ipv6-flowlabel-api-00 */ | /* update flowinfo - draft-itojun-ipv6-flowlabel-api-00 */ | ||||
inp->inp_flow &= ~IPV6_FLOWLABEL_MASK; | inp->inp_flow &= ~IPV6_FLOWLABEL_MASK; | ||||
if (inp->inp_flags & IN6P_AUTOFLOWLABEL) | if (inp->inp_flags & IN6P_AUTOFLOWLABEL) | ||||
▲ Show 20 Lines • Show All 854 Lines • Show Last 20 Lines |
style(9): Line too long