Make ifconfig(8) set and display preference numbers for IPv6

addresses.  Make the kernel support SIOC[SG]IFADDRPREF for IPv6
interface addresses.

In in6ifa_ifpforlinklocal(), consult preference numbers before
making an otherwise arbitrary choice of in6_ifaddr.  Otherwise,
preference numbers are *not* consulted by the kernel, but that will
be rather easy for somebody with a little bit of free time to fix.

Please note that setting the preference number for a link-local
IPv6 address does not work right, yet, but that ought to be fixed
soon.

In support of the changes above,

1 Add a method to struct domain for "externalizing" a sockaddr, and
  provide an implementation for IPv6.  Expect more work in this area: it
  may be more proper to say that the IPv6 implementation "internalizes"
  a sockaddr.  Add sockaddr_externalize().

2 Add a subroutine, sofamily(), that returns a struct socket's address
  family or AF_UNSPEC.

3 Make a lot of IPv4-specific code generic, and move it from
  sys/netinet/ to sys/net/ for re-use by IPv6 parts of the kernel and
  ifconfig(8).
This commit is contained in:
dyoung 2009-09-11 22:06:29 +00:00
parent e72611bc37
commit c5d5f7697a
16 changed files with 231 additions and 155 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: af_inet.c,v 1.13 2009/08/07 19:35:55 dyoung Exp $ */
/* $NetBSD: af_inet.c,v 1.14 2009/09/11 22:06:29 dyoung Exp $ */
/*
* Copyright (c) 1983, 1993
@ -31,7 +31,7 @@
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: af_inet.c,v 1.13 2009/08/07 19:35:55 dyoung Exp $");
__RCSID("$NetBSD: af_inet.c,v 1.14 2009/09/11 22:06:29 dyoung Exp $");
#endif /* not lint */
#include <sys/param.h>
@ -63,7 +63,6 @@ static void in_status(prop_dictionary_t, prop_dictionary_t, bool);
static void in_commit_address(prop_dictionary_t, prop_dictionary_t);
static void in_alias(const char *, prop_dictionary_t, prop_dictionary_t,
struct in_aliasreq *);
static void in_preference(const char *, const struct sockaddr *);
static struct afswtch af = {
.af_name = "inet", .af_af = AF_INET, .af_status = in_status,
@ -139,46 +138,12 @@ in_alias(const char *ifname, prop_dictionary_t env, prop_dictionary_t oenv,
}
}
static int16_t
in_get_preference(const char *ifname, const struct sockaddr *sa)
{
struct if_addrprefreq ifap;
int s;
if ((s = getsock(AF_INET)) == -1) {
if (errno == EPROTONOSUPPORT)
return 0;
err(EXIT_FAILURE, "socket");
}
memset(&ifap, 0, sizeof(ifap));
estrlcpy(ifap.ifap_name, ifname, sizeof(ifap.ifap_name));
memcpy(&ifap.ifap_addr, sa, MIN(sizeof(ifap.ifap_addr), sa->sa_len));
if (ioctl(s, SIOCGIFADDRPREF, &ifap) == -1) {
if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT)
return 0;
warn("SIOCGIFADDRPREF");
}
return ifap.ifap_preference;
}
static void
in_preference(const char *ifname, const struct sockaddr *sa)
{
int16_t preference;
if (lflag)
return;
preference = in_get_preference(ifname, sa);
printf(" preference %" PRId16, preference);
}
static void
in_status(prop_dictionary_t env, prop_dictionary_t oenv, bool force)
{
struct ifaddrs *ifap, *ifa;
struct in_aliasreq ifra;
int printprefs = 0;
bool printprefs = false;
const char *ifname;
if ((ifname = getifname(env)) == NULL)
@ -187,19 +152,8 @@ in_status(prop_dictionary_t env, prop_dictionary_t oenv, bool force)
if (getifaddrs(&ifap) != 0)
err(EXIT_FAILURE, "getifaddrs");
/* Print address preference numbers if any address has a non-zero
* preference assigned.
*/
for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
if (strcmp(ifname, ifa->ifa_name) != 0)
continue;
if (ifa->ifa_addr->sa_family != AF_INET)
continue;
if (in_get_preference(ifa->ifa_name, ifa->ifa_addr) != 0) {
printprefs = 1;
break;
}
}
printprefs = ifa_any_preferences(ifname, ifap, AF_INET);
for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
if (strcmp(ifname, ifa->ifa_name) != 0)
continue;
@ -213,7 +167,7 @@ in_status(prop_dictionary_t env, prop_dictionary_t oenv, bool force)
memcpy(&ifra.ifra_addr, ifa->ifa_addr, ifa->ifa_addr->sa_len);
in_alias(ifa->ifa_name, env, oenv, &ifra);
if (printprefs)
in_preference(ifa->ifa_name, ifa->ifa_addr);
ifa_print_preference(ifa->ifa_name, ifa->ifa_addr);
printf("\n");
}
freeifaddrs(ifap);

View File

@ -1,4 +1,4 @@
/* $NetBSD: af_inet6.c,v 1.24 2009/08/07 18:53:37 dyoung Exp $ */
/* $NetBSD: af_inet6.c,v 1.25 2009/09/11 22:06:29 dyoung Exp $ */
/*
* Copyright (c) 1983, 1993
@ -31,7 +31,7 @@
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: af_inet6.c,v 1.24 2009/08/07 18:53:37 dyoung Exp $");
__RCSID("$NetBSD: af_inet6.c,v 1.25 2009/09/11 22:06:29 dyoung Exp $");
#endif /* not lint */
#include <sys/param.h>
@ -374,8 +374,6 @@ in6_alias(const char *ifname, prop_dictionary_t env, prop_dictionary_t oenv,
printf("infty");
}
}
printf("\n");
}
static void
@ -384,12 +382,14 @@ in6_status(prop_dictionary_t env, prop_dictionary_t oenv, bool force)
struct ifaddrs *ifap, *ifa;
struct in6_ifreq ifr;
const char *ifname;
bool printprefs = false;
if ((ifname = getifname(env)) == NULL)
err(EXIT_FAILURE, "%s: getifname", __func__);
if (getifaddrs(&ifap) != 0)
err(EXIT_FAILURE, "getifaddrs");
printprefs = ifa_any_preferences(ifname, ifap, AF_INET6);
for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
if (strcmp(ifname, ifa->ifa_name) != 0)
continue;
@ -402,6 +402,9 @@ in6_status(prop_dictionary_t env, prop_dictionary_t oenv, bool force)
estrlcpy(ifr.ifr_name, ifa->ifa_name, sizeof(ifr.ifr_name));
memcpy(&ifr.ifr_addr, ifa->ifa_addr, ifa->ifa_addr->sa_len);
in6_alias(ifname, env, oenv, &ifr);
if (printprefs)
ifa_print_preference(ifa->ifa_name, ifa->ifa_addr);
printf("\n");
}
freeifaddrs(ifap);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: util.c,v 1.12 2009/08/07 18:53:37 dyoung Exp $ */
/* $NetBSD: util.c,v 1.13 2009/09/11 22:06:29 dyoung Exp $ */
/*-
* Copyright (c) 2008 David Young. All rights reserved.
@ -27,7 +27,7 @@
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: util.c,v 1.12 2009/08/07 18:53:37 dyoung Exp $");
__RCSID("$NetBSD: util.c,v 1.13 2009/09/11 22:06:29 dyoung Exp $");
#endif /* not lint */
#include <ctype.h>
@ -290,6 +290,60 @@ print_link_addresses(prop_dictionary_t env, bool print_active_only)
freeifaddrs(ifap);
}
int16_t
ifa_get_preference(const char *ifname, const struct sockaddr *sa)
{
struct if_addrprefreq ifap;
int s;
if ((s = getsock(sa->sa_family)) == -1) {
if (errno == EPROTONOSUPPORT)
return 0;
err(EXIT_FAILURE, "socket");
}
memset(&ifap, 0, sizeof(ifap));
estrlcpy(ifap.ifap_name, ifname, sizeof(ifap.ifap_name));
memcpy(&ifap.ifap_addr, sa, MIN(sizeof(ifap.ifap_addr), sa->sa_len));
if (ioctl(s, SIOCGIFADDRPREF, &ifap) == -1) {
if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT)
return 0;
warn("SIOCGIFADDRPREF");
}
return ifap.ifap_preference;
}
void
ifa_print_preference(const char *ifname, const struct sockaddr *sa)
{
int16_t preference;
if (lflag)
return;
preference = ifa_get_preference(ifname, sa);
printf(" preference %" PRId16, preference);
}
bool
ifa_any_preferences(const char *ifname, struct ifaddrs *ifap, int family)
{
struct ifaddrs *ifa;
/* Print address preference numbers if any address has a non-zero
* preference assigned.
*/
for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
if (strcmp(ifname, ifa->ifa_name) != 0)
continue;
if (ifa->ifa_addr->sa_family != family)
continue;
if (ifa_get_preference(ifa->ifa_name, ifa->ifa_addr) != 0)
return true;
}
return false;
}
#ifdef INET6
/* KAME idiosyncrasy */
void

View File

@ -2,6 +2,9 @@
#define _IFCONFIG_UTIL_H
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <ifaddrs.h>
#include "parse.h"
@ -25,5 +28,8 @@ int indirect_ioctl(prop_dictionary_t, unsigned long, void *);
#ifdef INET6
void in6_fillscopeid(struct sockaddr_in6 *sin6);
#endif /* INET6 */
bool ifa_any_preferences(const char *, struct ifaddrs *, int);
void ifa_print_preference(const char *, const struct sockaddr *);
int16_t ifa_get_preference(const char *, const struct sockaddr *);
#endif /* _IFCONFIG_UTIL_H */

View File

@ -1,4 +1,4 @@
/* $NetBSD: uipc_domain.c,v 1.83 2009/09/08 18:01:34 dyoung Exp $ */
/* $NetBSD: uipc_domain.c,v 1.84 2009/09/11 22:06:29 dyoung Exp $ */
/*
* Copyright (c) 1982, 1986, 1993
@ -32,7 +32,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: uipc_domain.c,v 1.83 2009/09/08 18:01:34 dyoung Exp $");
__KERNEL_RCSID(0, "$NetBSD: uipc_domain.c,v 1.84 2009/09/11 22:06:29 dyoung Exp $");
#include <sys/param.h>
#include <sys/socket.h>
@ -268,6 +268,20 @@ sockaddr_copy(struct sockaddr *dst, socklen_t socklen,
return memcpy(dst, src, src->sa_len);
}
struct sockaddr *
sockaddr_externalize(struct sockaddr *dst, socklen_t socklen,
const struct sockaddr *src)
{
struct domain *dom;
dom = pffinddomain(src->sa_family);
if (dom != NULL && dom->dom_sockaddr_externalize != NULL)
return (*dom->dom_sockaddr_externalize)(dst, socklen, src);
return sockaddr_copy(dst, socklen, src);
}
int
sockaddr_cmp(const struct sockaddr *sa1, const struct sockaddr *sa2)
{

View File

@ -1,4 +1,4 @@
/* $NetBSD: uipc_socket.c,v 1.189 2009/04/30 20:41:33 ad Exp $ */
/* $NetBSD: uipc_socket.c,v 1.190 2009/09/11 22:06:29 dyoung Exp $ */
/*-
* Copyright (c) 2002, 2007, 2008, 2009 The NetBSD Foundation, Inc.
@ -63,7 +63,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: uipc_socket.c,v 1.189 2009/04/30 20:41:33 ad Exp $");
__KERNEL_RCSID(0, "$NetBSD: uipc_socket.c,v 1.190 2009/09/11 22:06:29 dyoung Exp $");
#include "opt_compat_netbsd.h"
#include "opt_sock_counters.h"
@ -554,6 +554,19 @@ fsocreate(int domain, struct socket **sop, int type, int protocol,
return error;
}
int
sofamily(const struct socket *so)
{
const struct protosw *pr;
const struct domain *dom;
if ((pr = so->so_proto) == NULL)
return AF_UNSPEC;
if ((dom = pr->pr_domain) == NULL)
return AF_UNSPEC;
return dom->dom_family;
}
int
sobind(struct socket *so, struct mbuf *nam, struct lwp *l)
{

View File

@ -1,4 +1,4 @@
/* $NetBSD: if.c,v 1.234 2009/08/13 00:23:31 dyoung Exp $ */
/* $NetBSD: if.c,v 1.235 2009/09/11 22:06:29 dyoung Exp $ */
/*-
* Copyright (c) 1999, 2000, 2001, 2008 The NetBSD Foundation, Inc.
@ -90,7 +90,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.234 2009/08/13 00:23:31 dyoung Exp $");
__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.235 2009/09/11 22:06:29 dyoung Exp $");
#include "opt_inet.h"
@ -1573,6 +1573,68 @@ ifioctl_common(struct ifnet *ifp, u_long cmd, void *data)
return 0;
}
int
ifaddrpref_ioctl(struct socket *so, u_long cmd, void *data, struct ifnet *ifp,
lwp_t *l)
{
struct if_addrprefreq *ifap = (struct if_addrprefreq *)data;
struct ifaddr *ifa;
const struct sockaddr *any, *sa;
union {
struct sockaddr sa;
struct sockaddr_storage ss;
} u;
switch (cmd) {
case SIOCSIFADDRPREF:
if (kauth_authorize_network(l->l_cred, KAUTH_NETWORK_INTERFACE,
KAUTH_REQ_NETWORK_INTERFACE_SETPRIV, ifp, (void *)cmd,
NULL) != 0)
return EPERM;
case SIOCGIFADDRPREF:
break;
default:
return EOPNOTSUPP;
}
/* sanity checks */
if (data == NULL || ifp == NULL) {
panic("invalid argument to %s", __func__);
/*NOTREACHED*/
}
/* address must be specified on ADD and DELETE */
sa = sstocsa(&ifap->ifap_addr);
if (sa->sa_family != sofamily(so))
return EINVAL;
if ((any = sockaddr_any(sa)) == NULL || sa->sa_len != any->sa_len)
return EINVAL;
IFADDR_FOREACH(ifa, ifp) {
if (ifa->ifa_addr->sa_family != sa->sa_family)
continue;
sockaddr_externalize(&u.sa, sizeof(u.ss), ifa->ifa_addr);
if (sockaddr_cmp(&u.sa, sa) == 0)
break;
}
if (ifa == NULL)
return EADDRNOTAVAIL;
switch (cmd) {
case SIOCSIFADDRPREF:
ifa->ifa_preference = ifap->ifap_preference;
return 0;
case SIOCGIFADDRPREF:
/* fill in the if_laddrreq structure */
(void)sockaddr_copy(sstosa(&ifap->ifap_addr),
sizeof(ifap->ifap_addr), ifa->ifa_addr);
ifap->ifap_preference = ifa->ifa_preference;
return 0;
default:
return EOPNOTSUPP;
}
}
/*
* Interface ioctls.
*/

View File

@ -1,4 +1,4 @@
/* $NetBSD: if.h,v 1.143 2009/08/13 00:23:32 dyoung Exp $ */
/* $NetBSD: if.h,v 1.144 2009/09/11 22:06:29 dyoung Exp $ */
/*-
* Copyright (c) 1999, 2000, 2001 The NetBSD Foundation, Inc.
@ -829,6 +829,8 @@ void if_up(struct ifnet *);
int ifconf(u_long, void *);
void ifinit(void);
void ifinit1(void);
int ifaddrpref_ioctl(struct socket *, u_long, void *, struct ifnet *,
lwp_t *);
int ifioctl(struct socket *, u_long, void *, struct lwp *);
int ifioctl_common(struct ifnet *, u_long, void *);
int ifpromisc(struct ifnet *, int);

View File

@ -1,4 +1,4 @@
/* $NetBSD: in.c,v 1.134 2009/04/18 14:58:05 tsutsui Exp $ */
/* $NetBSD: in.c,v 1.135 2009/09/11 22:06:29 dyoung Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -91,7 +91,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: in.c,v 1.134 2009/04/18 14:58:05 tsutsui Exp $");
__KERNEL_RCSID(0, "$NetBSD: in.c,v 1.135 2009/09/11 22:06:29 dyoung Exp $");
#include "opt_inet.h"
#include "opt_inet_conf.h"
@ -139,8 +139,6 @@ static void in_len2mask(struct in_addr *, u_int);
static int in_lifaddr_ioctl(struct socket *, u_long, void *,
struct ifnet *, struct lwp *);
static int in_ifaddrpref_ioctl(struct socket *, u_long, void *,
struct ifnet *);
static int in_addprefix(struct in_ifaddr *, int);
static int in_scrubprefix(struct in_ifaddr *);
@ -321,15 +319,15 @@ in_control(struct socket *so, u_long cmd, void *data, struct ifnet *ifp,
switch (cmd) {
case SIOCALIFADDR:
case SIOCDLIFADDR:
case SIOCSIFADDRPREF:
case SIOCGIFADDRPREF:
case SIOCGLIFADDR:
if (ifp == NULL)
return EINVAL;
if (cmd == SIOCGIFADDRPREF || cmd == SIOCSIFADDRPREF)
return in_ifaddrpref_ioctl(so, cmd, data, ifp);
else
return in_lifaddr_ioctl(so, cmd, data, ifp, l);
return in_lifaddr_ioctl(so, cmd, data, ifp, l);
case SIOCGIFADDRPREF:
case SIOCSIFADDRPREF:
if (ifp == NULL)
return EINVAL;
return ifaddrpref_ioctl(so, cmd, data, ifp, l);
}
/*
@ -339,7 +337,6 @@ in_control(struct socket *so, u_long cmd, void *data, struct ifnet *ifp,
IFP_TO_IA(ifp, ia);
switch (cmd) {
case SIOCAIFADDR:
case SIOCDIFADDR:
case SIOCGIFALIAS:
@ -777,66 +774,6 @@ in_lifaddr_ioctl(struct socket *so, u_long cmd, void *data,
return EOPNOTSUPP; /*just for safety*/
}
static int
in_ifaddrpref_ioctl(struct socket *so, u_long cmd, void *data,
struct ifnet *ifp)
{
struct if_addrprefreq *ifap = (struct if_addrprefreq *)data;
struct ifaddr *ifa;
struct sockaddr *sa;
struct in_ifaddr *ia = NULL; /* appease gcc -Wuninitialized */
struct in_addr match;
struct sockaddr_in *sin;
/* sanity checks */
if (data == NULL || ifp == NULL) {
panic("invalid argument to %s", __func__);
/*NOTREACHED*/
}
/* address must be specified on ADD and DELETE */
sa = (struct sockaddr *)&ifap->ifap_addr;
if (sa->sa_family != AF_INET)
return EINVAL;
if (sa->sa_len != sizeof(struct sockaddr_in))
return EINVAL;
switch (cmd) {
case SIOCSIFADDRPREF:
case SIOCGIFADDRPREF:
break;
default:
return EOPNOTSUPP;
}
sin = (struct sockaddr_in *)&ifap->ifap_addr;
match.s_addr = sin->sin_addr.s_addr;
IFADDR_FOREACH(ifa, ifp) {
ia = (struct in_ifaddr *)ifa;
if (ia->ia_addr.sin_family != AF_INET)
continue;
if (ia->ia_addr.sin_addr.s_addr == match.s_addr)
break;
}
if (ifa == NULL)
return EADDRNOTAVAIL;
switch (cmd) {
case SIOCSIFADDRPREF:
ifa->ifa_preference = ifap->ifap_preference;
return 0;
case SIOCGIFADDRPREF:
/* fill in the if_laddrreq structure */
(void)memcpy(&ifap->ifap_addr, &ia->ia_addr,
ia->ia_addr.sin_len);
ifap->ifap_preference = ifa->ifa_preference;
return 0;
default:
return EOPNOTSUPP;
}
}
/*
* Delete any existing route for an interface.
*/

View File

@ -1,4 +1,4 @@
/* $NetBSD: in6.c,v 1.152 2009/08/13 00:34:04 dyoung Exp $ */
/* $NetBSD: in6.c,v 1.153 2009/09/11 22:06:29 dyoung Exp $ */
/* $KAME: in6.c,v 1.198 2001/07/18 09:12:38 itojun Exp $ */
/*
@ -62,7 +62,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: in6.c,v 1.152 2009/08/13 00:34:04 dyoung Exp $");
__KERNEL_RCSID(0, "$NetBSD: in6.c,v 1.153 2009/09/11 22:06:29 dyoung Exp $");
#include "opt_inet.h"
#include "opt_pfil_hooks.h"
@ -350,13 +350,14 @@ in6_mask2len(struct in6_addr *mask, u_char *lim0)
static int
in6_control1(struct socket *so, u_long cmd, void *data, struct ifnet *ifp,
struct lwp *l)
lwp_t *l)
{
struct in6_ifreq *ifr = (struct in6_ifreq *)data;
struct in6_ifaddr *ia = NULL;
struct in6_aliasreq *ifra = (struct in6_aliasreq *)data;
struct sockaddr_in6 *sa6;
int error;
switch (cmd) {
/*
* XXX: Fix me, once we fix SIOCSIFADDR, SIOCIFDSTADDR, etc.
@ -370,6 +371,11 @@ in6_control1(struct socket *so, u_long cmd, void *data, struct ifnet *ifp,
case SIOCGETSGCNT_IN6:
case SIOCGETMIFCNT_IN6:
return mrt6_ioctl(cmd, data);
case SIOCGIFADDRPREF:
case SIOCSIFADDRPREF:
if (ifp == NULL)
return EINVAL;
return ifaddrpref_ioctl(so, cmd, data, ifp, l);
}
if (ifp == NULL)
@ -1793,22 +1799,24 @@ in6_ifinit(struct ifnet *ifp, struct in6_ifaddr *ia,
struct in6_ifaddr *
in6ifa_ifpforlinklocal(const struct ifnet *ifp, const int ignoreflags)
{
struct ifaddr *ifa;
struct ifaddr *best_ifa = NULL, *ifa;
IFADDR_FOREACH(ifa, ifp) {
if (ifa->ifa_addr == NULL)
continue; /* just for safety */
if (ifa->ifa_addr->sa_family != AF_INET6)
continue;
if (IN6_IS_ADDR_LINKLOCAL(IFA_IN6(ifa))) {
if ((((struct in6_ifaddr *)ifa)->ia6_flags &
ignoreflags) != 0)
continue;
break;
}
if (!IN6_IS_ADDR_LINKLOCAL(IFA_IN6(ifa)))
continue;
if ((((struct in6_ifaddr *)ifa)->ia6_flags & ignoreflags) != 0)
continue;
if (best_ifa == NULL)
best_ifa = ifa;
else if (best_ifa->ifa_preference < ifa->ifa_preference)
best_ifa = ifa;
}
return (struct in6_ifaddr *)ifa;
return (struct in6_ifaddr *)best_ifa;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: in6.h,v 1.67 2009/08/19 18:52:48 seanb Exp $ */
/* $NetBSD: in6.h,v 1.68 2009/09/11 22:06:29 dyoung Exp $ */
/* $KAME: in6.h,v 1.83 2001/03/29 02:55:07 jinmei Exp $ */
/*
@ -684,6 +684,8 @@ in6_cksum_phdr(const struct in6_addr *src, const struct in6_addr *dst,
struct mbuf;
struct ifnet;
int sockaddr_in6_cmp(const struct sockaddr *, const struct sockaddr *);
struct sockaddr *sockaddr_in6_externalize(struct sockaddr *, socklen_t,
const struct sockaddr *);
int in6_cksum(struct mbuf *, u_int8_t, u_int32_t, u_int32_t);
void in6_delayed_cksum(struct mbuf *);
int in6_localaddr(const struct in6_addr *);

View File

@ -1,4 +1,4 @@
/* $NetBSD: in6_proto.c,v 1.86 2009/09/11 20:10:06 dyoung Exp $ */
/* $NetBSD: in6_proto.c,v 1.87 2009/09/11 22:06:29 dyoung Exp $ */
/* $KAME: in6_proto.c,v 1.66 2000/10/10 15:35:47 itojun Exp $ */
/*
@ -62,7 +62,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: in6_proto.c,v 1.86 2009/09/11 20:10:06 dyoung Exp $");
__KERNEL_RCSID(0, "$NetBSD: in6_proto.c,v 1.87 2009/09/11 22:06:29 dyoung Exp $");
#include "opt_inet.h"
#include "opt_ipsec.h"
@ -421,6 +421,7 @@ struct domain inet6domain = {
.dom_sa_cmpofs = offsetof(struct sockaddr_in6, sin6_addr),
.dom_sa_cmplen = sizeof(struct in6_addr),
.dom_sa_any = (const struct sockaddr *)&in6_any,
.dom_sockaddr_externalize = sockaddr_in6_externalize,
.dom_rtcache = LIST_HEAD_INITIALIZER(inet6domain.dom_rtcache)
};

View File

@ -1,4 +1,4 @@
/* $NetBSD: scope6.c,v 1.7 2009/03/15 21:26:09 cegger Exp $ */
/* $NetBSD: scope6.c,v 1.8 2009/09/11 22:06:29 dyoung Exp $ */
/* $KAME$ */
/*-
@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: scope6.c,v 1.7 2009/03/15 21:26:09 cegger Exp $");
__KERNEL_RCSID(0, "$NetBSD: scope6.c,v 1.8 2009/09/11 22:06:29 dyoung Exp $");
#include <sys/param.h>
#include <sys/malloc.h>
@ -328,6 +328,20 @@ sa6_embedscope(struct sockaddr_in6 *sin6, int defaultok)
return 0;
}
struct sockaddr *
sockaddr_in6_externalize(struct sockaddr *dst, socklen_t socklen,
const struct sockaddr *src)
{
struct sockaddr_in6 *sin6;
sin6 = satosin6(sockaddr_copy(dst, socklen, src));
if (sin6 == NULL || sa6_recoverscope(sin6) != 0)
return NULL;
return dst;
}
/*
* generate standard sockaddr_in6 from embedded form.
*/

View File

@ -1,4 +1,4 @@
/* $NetBSD: domain.h,v 1.28 2009/05/27 23:44:35 pooka Exp $ */
/* $NetBSD: domain.h,v 1.29 2009/09/11 22:06:29 dyoung Exp $ */
/*
* Copyright (c) 1982, 1986, 1993
@ -75,6 +75,9 @@ struct domain {
void *(*dom_sockaddr_addr)(struct sockaddr *, socklen_t *);
int (*dom_sockaddr_cmp)(const struct sockaddr *,
const struct sockaddr *);
struct sockaddr *(*dom_sockaddr_externalize)(struct sockaddr *,
socklen_t,
const struct sockaddr *);
const struct sockaddr *dom_sa_any;
struct ifqueue *dom_ifqueues[2]; /* ifqueue for domain */
STAILQ_ENTRY(domain) dom_link;

View File

@ -1,4 +1,4 @@
/* $NetBSD: socket.h,v 1.95 2009/04/28 20:54:50 dyoung Exp $ */
/* $NetBSD: socket.h,v 1.96 2009/09/11 22:06:29 dyoung Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -573,6 +573,8 @@ sockaddr_getlen(const struct sockaddr *sa)
__BEGIN_DECLS
struct sockaddr *sockaddr_copy(struct sockaddr *, socklen_t,
const struct sockaddr *);
struct sockaddr *sockaddr_externalize(struct sockaddr *, socklen_t,
const struct sockaddr *);
struct sockaddr *sockaddr_alloc(sa_family_t, socklen_t, int);
const void *sockaddr_const_addr(const struct sockaddr *, socklen_t *);
void *sockaddr_addr(struct sockaddr *, socklen_t *);

View File

@ -1,4 +1,4 @@
/* $NetBSD: socketvar.h,v 1.120 2009/09/02 14:56:57 tls Exp $ */
/* $NetBSD: socketvar.h,v 1.121 2009/09/11 22:06:29 dyoung Exp $ */
/*-
* Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@ -281,6 +281,7 @@ void soinit(void);
void soinit2(void);
int soabort(struct socket *);
int soaccept(struct socket *, struct mbuf *);
int sofamily(const struct socket *);
int sobind(struct socket *, struct mbuf *, struct lwp *);
void socantrcvmore(struct socket *);
void socantsendmore(struct socket *);