+ if (in_pcb_checkstate(inp, WNT_STOPUSING, 1) != WNT_STOPUSING)
+ printf("in6_pcbdetach so=%x can't be marked dead ok\n", so);
+
+ inp->inp_state = INPCB_STATE_DEAD;
+
+ if ((so->so_flags & SOF_PCBCLEARING) == 0) {
+ inp->inp_vflag = 0;
+ so->so_flags |= SOF_PCBCLEARING;
+ inp->inp_gencnt = ++ipi->ipi_gencnt;
+ if (inp->in6p_options)
+ m_freem(inp->in6p_options);
+ ip6_freepcbopts(inp->in6p_outputopts);
+ ip6_freemoptions(inp->in6p_moptions);
+ if (inp->in6p_route.ro_rt)
+ rtfree(inp->in6p_route.ro_rt);
+ /* Check and free IPv4 related resources in case of mapped addr */
+ if (inp->inp_options)
+ (void)m_free(inp->inp_options);
+ ip_freemoptions(inp->inp_moptions);
+ inp->inp_moptions = NULL;
+
+ }
+}
+
+struct sockaddr *
+in6_sockaddr(port, addr_p)
+ in_port_t port;
+ struct in6_addr *addr_p;
+{
+ struct sockaddr_in6 *sin6;
+
+ MALLOC(sin6, struct sockaddr_in6 *, sizeof *sin6, M_SONAME, M_WAITOK);
+ bzero(sin6, sizeof *sin6);
+ sin6->sin6_family = AF_INET6;
+ sin6->sin6_len = sizeof(*sin6);
+ sin6->sin6_port = port;
+ sin6->sin6_addr = *addr_p;
+ if (IN6_IS_SCOPE_LINKLOCAL(&sin6->sin6_addr))
+ sin6->sin6_scope_id = ntohs(sin6->sin6_addr.s6_addr16[1]);
+ else
+ sin6->sin6_scope_id = 0; /*XXX*/
+ if (IN6_IS_SCOPE_LINKLOCAL(&sin6->sin6_addr))
+ sin6->sin6_addr.s6_addr16[1] = 0;
+
+ return (struct sockaddr *)sin6;
+}
+
+struct sockaddr *
+in6_v4mapsin6_sockaddr(port, addr_p)
+ in_port_t port;
+ struct in_addr *addr_p;
+{
+ struct sockaddr_in sin;
+ struct sockaddr_in6 *sin6_p;
+
+ bzero(&sin, sizeof sin);
+ sin.sin_family = AF_INET;
+ sin.sin_len = sizeof(sin);
+ sin.sin_port = port;
+ sin.sin_addr = *addr_p;
+
+ MALLOC(sin6_p, struct sockaddr_in6 *, sizeof *sin6_p, M_SONAME,
+ M_WAITOK);
+ in6_sin_2_v4mapsin6(&sin, sin6_p);
+
+ return (struct sockaddr *)sin6_p;