diff --git a/sbin/ifconfig/ifconfig.8 b/sbin/ifconfig/ifconfig.8 index fb8b7ea41ec2..11532038ba95 100644 --- a/sbin/ifconfig/ifconfig.8 +++ b/sbin/ifconfig/ifconfig.8 @@ -1,4 +1,4 @@ -.\" $NetBSD: ifconfig.8,v 1.101 2009/09/14 10:36:49 degroote Exp $ +.\" $NetBSD: ifconfig.8,v 1.102 2010/11/15 22:42:37 pooka Exp $ .\" .\" Copyright (c) 1983, 1991, 1993 .\" The Regents of the University of California. All rights reserved. @@ -29,7 +29,7 @@ .\" .\" @(#)ifconfig.8 8.4 (Berkeley) 6/1/94 .\" -.Dd August 7, 2009 +.Dd November 15, 2010 .Dt IFCONFIG 8 .Os .Sh NAME @@ -569,6 +569,13 @@ Refer to the man page for the specific driver for more information. .It Fl link[0-2] Disable special processing at the link level with the specified interface. +.It Cm linkstr +Set a link-level string parameter for the interface. +This functionality varies from interface to interface. +Refer to the man page for the specific driver +for more information. +.It Fl linkstr +Remove an interface link-level string parameter. .It Cm up Mark an interface ``up''. This may be used to enable an interface after an ``ifconfig down.'' diff --git a/sbin/ifconfig/ifconfig.c b/sbin/ifconfig/ifconfig.c index 6bda021bcb46..3b410e80533e 100644 --- a/sbin/ifconfig/ifconfig.c +++ b/sbin/ifconfig/ifconfig.c @@ -1,4 +1,4 @@ -/* $NetBSD: ifconfig.c,v 1.222 2010/11/05 13:52:41 pooka Exp $ */ +/* $NetBSD: ifconfig.c,v 1.223 2010/11/15 22:42:37 pooka Exp $ */ /*- * Copyright (c) 1997, 1998, 2000 The NetBSD Foundation, Inc. @@ -63,7 +63,7 @@ #ifndef lint __COPYRIGHT("@(#) Copyright (c) 1983, 1993\ The Regents of the University of California. All rights reserved."); -__RCSID("$NetBSD: ifconfig.c,v 1.222 2010/11/05 13:52:41 pooka Exp $"); +__RCSID("$NetBSD: ifconfig.c,v 1.223 2010/11/15 22:42:37 pooka Exp $"); #endif /* not lint */ #include @@ -126,6 +126,8 @@ static int setifmetric(prop_dictionary_t, prop_dictionary_t); static int setifmtu(prop_dictionary_t, prop_dictionary_t); static int setifnetmask(prop_dictionary_t, prop_dictionary_t); static int setifprefixlen(prop_dictionary_t, prop_dictionary_t); +static int setlinkstr(prop_dictionary_t, prop_dictionary_t); +static int unsetlinkstr(prop_dictionary_t, prop_dictionary_t); static void status(const struct sockaddr *, prop_dictionary_t, prop_dictionary_t); static void usage(void); @@ -164,6 +166,7 @@ extern struct pbranch command_root; extern struct pbranch opt_command; extern struct pbranch opt_family, opt_silent_family; extern struct pkw cloning, silent_family, family, ifcaps, ifflags, misc; +extern struct pstr parse_linkstr; struct pinteger parse_metric = PINTEGER_INITIALIZER(&parse_metric, "metric", 10, setifmetric, "metric", &command_root.pb_parser); @@ -202,6 +205,9 @@ static const struct kwinst misckw[] = { , {.k_word = "prefixlen", .k_nextparser = &parse_prefixlen.pi_parser} , {.k_word = "trailers", .k_neg = true, .k_exec = notrailers, .k_nextparser = &command_root.pb_parser} + , {.k_word = "linkstr", .k_nextparser = &parse_linkstr.ps_parser } + , {.k_word = "-linkstr", .k_exec = unsetlinkstr, + .k_nextparser = &command_root.pb_parser } }; /* key: clonecmd */ @@ -237,6 +243,9 @@ struct paddr broadcast = PADDR_INITIALIZER(&broadcast, setifbroadaddr, "broadcast", NULL, "dstormask", "broadcast", &command_root.pb_parser); +struct pstr parse_linkstr = PSTR_INITIALIZER(&parse_linkstr, "linkstr", + setlinkstr, "linkstr", &command_root.pb_parser); + static SIMPLEQ_HEAD(, afswtch) aflist = SIMPLEQ_HEAD_INITIALIZER(aflist); static SIMPLEQ_HEAD(, usage_func) usage_funcs = @@ -1159,6 +1168,7 @@ status(const struct sockaddr *sdl, prop_dictionary_t env, statistics_func_t *statistics_f; struct ifdatareq ifdr; struct ifreq ifr; + struct ifdrv ifdrv; char fbuf[BUFSIZ]; int af, s; const char *ifname; @@ -1210,6 +1220,25 @@ status(const struct sockaddr *sdl, prop_dictionary_t env, print_link_addresses(env, true); + estrlcpy(ifdrv.ifd_name, ifname, sizeof(ifdrv.ifd_name)); + ifdrv.ifd_cmd = IFLINKSTR_QUERYLEN; + ifdrv.ifd_len = 0; + ifdrv.ifd_data = NULL; + /* interface supports linkstr? */ + if (ioctl(s, SIOCGLINKSTR, &ifdrv) != -1) { + char *p; + + p = malloc(ifdrv.ifd_len); + if (p == NULL) + err(EXIT_FAILURE, "malloc linkstr buf failed"); + ifdrv.ifd_data = p; + ifdrv.ifd_cmd = 0; + if (ioctl(s, SIOCGLINKSTR, &ifdrv) == -1) + err(EXIT_FAILURE, "failed to query linkstr"); + printf("\tlinkstr: %s\n", (char *)ifdrv.ifd_data); + free(p); + } + media_status(env, oenv); if (!vflag && !zflag) @@ -1283,6 +1312,46 @@ setifprefixlen(prop_dictionary_t env, prop_dictionary_t oenv) return 0; } +static int +setlinkstr(prop_dictionary_t env, prop_dictionary_t oenv) +{ + struct ifdrv ifdrv; + const char *linkstr; + size_t linkstrlen; + prop_data_t data; + + data = (prop_data_t)prop_dictionary_get(env, "linkstr"); + if (data == NULL) { + errno = ENOENT; + return -1; + } + linkstrlen = prop_data_size(data)+1; + linkstr = prop_data_data_nocopy(data); + + ifdrv.ifd_cmd = 0; + ifdrv.ifd_len = linkstrlen; + ifdrv.ifd_data = __UNCONST(linkstr); + + if (direct_ioctl(env, SIOCSLINKSTR, &ifdrv) == -1) + err(EXIT_FAILURE, "SIOCSLINKSTR"); + + return 0; +} + +static int +unsetlinkstr(prop_dictionary_t env, prop_dictionary_t oenv) +{ + struct ifdrv ifdrv; + + memset(&ifdrv, 0, sizeof(ifdrv)); + ifdrv.ifd_cmd = IFLINKSTR_UNSET; + + if (direct_ioctl(env, SIOCSLINKSTR, &ifdrv) == -1) + err(EXIT_FAILURE, "SIOCSLINKSTR"); + + return 0; +} + static void usage(void) { diff --git a/sys/net/if.c b/sys/net/if.c index 2485125a2a71..6139864af4c8 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -1,4 +1,4 @@ -/* $NetBSD: if.c,v 1.248 2010/11/06 23:28:58 christos Exp $ */ +/* $NetBSD: if.c,v 1.249 2010/11/15 22:42:36 pooka Exp $ */ /*- * Copyright (c) 1999, 2000, 2001, 2008 The NetBSD Foundation, Inc. @@ -90,7 +90,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.248 2010/11/06 23:28:58 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.249 2010/11/15 22:42:36 pooka Exp $"); #include "opt_inet.h" @@ -1775,6 +1775,7 @@ ifioctl(struct socket *so, u_long cmd, void *data, struct lwp *l) case SIOCS80211POWER: case SIOCS80211BSSID: case SIOCS80211CHANNEL: + case SIOCSLINKSTR: if (l != NULL) { error = kauth_authorize_network(l->l_cred, KAUTH_NETWORK_INTERFACE, diff --git a/sys/net/if.h b/sys/net/if.h index eb6f007e8912..217a0b10d8e3 100644 --- a/sys/net/if.h +++ b/sys/net/if.h @@ -1,4 +1,4 @@ -/* $NetBSD: if.h,v 1.147 2010/10/20 15:02:17 pooka Exp $ */ +/* $NetBSD: if.h,v 1.148 2010/11/15 22:42:36 pooka Exp $ */ /*- * Copyright (c) 1999, 2000, 2001 The NetBSD Foundation, Inc. @@ -603,6 +603,8 @@ struct ifdrv { size_t ifd_len; void *ifd_data; }; +#define IFLINKSTR_QUERYLEN 0x01 +#define IFLINKSTR_UNSET 0x02 /* * Structure used in SIOCGIFCONF request. diff --git a/sys/sys/sockio.h b/sys/sys/sockio.h index ce1d0380b6e0..3e97c9fcef60 100644 --- a/sys/sys/sockio.h +++ b/sys/sys/sockio.h @@ -1,4 +1,4 @@ -/* $NetBSD: sockio.h,v 1.29 2009/09/14 10:36:50 degroote Exp $ */ +/* $NetBSD: sockio.h,v 1.30 2010/11/15 22:42:36 pooka Exp $ */ /*- * Copyright (c) 1982, 1986, 1990, 1993, 1994 @@ -129,6 +129,9 @@ #define SIOCZIFDATA _IOWR('i', 134, struct ifdatareq) /* get if_data then zero ctrs*/ +#define SIOCGLINKSTR _IOWR('i', 135, struct ifdrv) +#define SIOCSLINKSTR _IOW('i', 136, struct ifdrv) + #define SIOCSETPFSYNC _IOW('i', 247, struct ifreq) #define SIOCGETPFSYNC _IOWR('i', 248, struct ifreq)