1997-05-04 06:22:27 +00:00
|
|
|
/* $NetBSD: ifconfig.c,v 1.34 1997/04/21 01:17:58 lukem Exp $ */
|
1999-08-28 00:22:10 +00:00
|
|
|
/* $FreeBSD$ */
|
1997-05-04 06:22:27 +00:00
|
|
|
|
2017-11-18 14:26:50 +00:00
|
|
|
/*-
|
|
|
|
* SPDX-License-Identifier: BSD-4-Clause
|
|
|
|
*
|
1997-05-04 06:22:27 +00:00
|
|
|
* Copyright (c) 1997 Jason R. Thorpe.
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
* 3. All advertising materials mentioning features or use of this software
|
|
|
|
* must display the following acknowledgement:
|
|
|
|
* This product includes software developed for the NetBSD Project
|
|
|
|
* by Jason R. Thorpe.
|
|
|
|
* 4. The name of the author may not be used to endorse or promote products
|
|
|
|
* derived from this software without specific prior written permission.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
|
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
|
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
|
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
|
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
|
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
|
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
|
|
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
|
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
|
|
* SUCH DAMAGE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Copyright (c) 1983, 1993
|
|
|
|
* The Regents of the University of California. All rights reserved.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
* 4. Neither the name of the University nor the names of its contributors
|
|
|
|
* may be used to endorse or promote products derived from this software
|
|
|
|
* without specific prior written permission.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
|
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
|
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
|
|
* SUCH DAMAGE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <sys/param.h>
|
|
|
|
#include <sys/ioctl.h>
|
|
|
|
#include <sys/socket.h>
|
|
|
|
#include <sys/sysctl.h>
|
|
|
|
#include <sys/time.h>
|
|
|
|
|
|
|
|
#include <net/if.h>
|
|
|
|
#include <net/if_dl.h>
|
|
|
|
#include <net/if_types.h>
|
|
|
|
#include <net/if_media.h>
|
|
|
|
#include <net/route.h>
|
|
|
|
|
|
|
|
#include <ctype.h>
|
|
|
|
#include <err.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <fcntl.h>
|
ifconfig: add report of the string from SIOCGIFDOWNREASON.
Sample output:
# ifconfig mce0
mce0: flags=8802<BROADCAST,SIMPLEX,MULTICAST> metric 0 mtu 1500
options=3ed07bb<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU,VLAN_HWCSUM,TSO4,TSO6,LRO,VLAN_HWFILTER,VLAN_HWTSO,LINKSTATE,RXCSUM_IPV6,TXCSUM_IPV6,TXRTLMT,HWRXTSTMP>
ether e4:1d:2d:e7:10:0a
media: Ethernet autoselect <full-duplex,rxpause,txpause>
status: no carrier (Negotiation failure)
nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
Reviewed by: hselasky, rrs
Sponsored by: Mellanox Technologies
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D21527
2019-09-17 18:51:10 +00:00
|
|
|
#include <stdbool.h>
|
1997-05-04 06:22:27 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
|
2021-02-28 20:27:28 +00:00
|
|
|
#include <libifconfig.h>
|
|
|
|
|
1997-05-04 06:22:27 +00:00
|
|
|
#include "ifconfig.h"
|
|
|
|
|
2021-02-28 20:27:28 +00:00
|
|
|
static void domediaopt(const char *, bool, int);
|
|
|
|
static ifmedia_t get_media_subtype(ifmedia_t, const char *);
|
|
|
|
static ifmedia_t get_media_mode(ifmedia_t, const char *);
|
|
|
|
static ifmedia_t get_media_options(ifmedia_t, const char *);
|
|
|
|
static void print_media(ifmedia_t, bool);
|
|
|
|
static void print_media_ifconfig(ifmedia_t);
|
2008-04-20 20:35:46 +00:00
|
|
|
|
2004-12-08 19:18:07 +00:00
|
|
|
static void
|
2004-12-31 19:46:27 +00:00
|
|
|
media_status(int s)
|
1997-05-04 06:22:27 +00:00
|
|
|
{
|
2021-02-28 20:27:28 +00:00
|
|
|
struct ifmediareq *ifmr;
|
1997-05-04 06:22:27 +00:00
|
|
|
|
2021-02-28 20:27:28 +00:00
|
|
|
if (ifconfig_media_get_mediareq(lifh, name, &ifmr) == -1)
|
1997-05-04 06:22:27 +00:00
|
|
|
return;
|
|
|
|
|
2021-02-28 20:27:28 +00:00
|
|
|
if (ifmr->ifm_count == 0) {
|
1997-05-04 06:22:27 +00:00
|
|
|
warnx("%s: no media types?", name);
|
2021-02-28 20:27:28 +00:00
|
|
|
goto free;
|
2015-04-07 21:31:17 +00:00
|
|
|
}
|
1997-05-04 06:22:27 +00:00
|
|
|
|
|
|
|
printf("\tmedia: ");
|
2021-02-28 20:27:28 +00:00
|
|
|
print_media(ifmr->ifm_current, true);
|
|
|
|
if (ifmr->ifm_active != ifmr->ifm_current) {
|
1997-05-04 06:22:27 +00:00
|
|
|
putchar(' ');
|
|
|
|
putchar('(');
|
2021-02-28 20:27:28 +00:00
|
|
|
print_media(ifmr->ifm_active, false);
|
1997-05-04 06:22:27 +00:00
|
|
|
putchar(')');
|
|
|
|
}
|
|
|
|
|
2001-05-29 09:13:44 +00:00
|
|
|
putchar('\n');
|
|
|
|
|
2021-02-28 20:27:28 +00:00
|
|
|
if (ifmr->ifm_status & IFM_AVALID) {
|
|
|
|
struct ifdownreason ifdr;
|
|
|
|
const char *status;
|
|
|
|
|
|
|
|
status = ifconfig_media_get_status(ifmr);
|
|
|
|
printf("\tstatus: %s", status);
|
|
|
|
if (strcmp(status, "no carrier") == 0 &&
|
|
|
|
ifconfig_media_get_downreason(lifh, name, &ifdr) == 0) {
|
|
|
|
switch (ifdr.ifdr_reason) {
|
|
|
|
case IFDR_REASON_MSG:
|
|
|
|
printf(" (%s)", ifdr.ifdr_msg);
|
|
|
|
break;
|
|
|
|
case IFDR_REASON_VENDOR:
|
|
|
|
printf(" (vendor code %d)",
|
|
|
|
ifdr.ifdr_vendor);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
ifconfig: add report of the string from SIOCGIFDOWNREASON.
Sample output:
# ifconfig mce0
mce0: flags=8802<BROADCAST,SIMPLEX,MULTICAST> metric 0 mtu 1500
options=3ed07bb<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU,VLAN_HWCSUM,TSO4,TSO6,LRO,VLAN_HWFILTER,VLAN_HWTSO,LINKSTATE,RXCSUM_IPV6,TXCSUM_IPV6,TXRTLMT,HWRXTSTMP>
ether e4:1d:2d:e7:10:0a
media: Ethernet autoselect <full-duplex,rxpause,txpause>
status: no carrier (Negotiation failure)
nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
Reviewed by: hselasky, rrs
Sponsored by: Mellanox Technologies
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D21527
2019-09-17 18:51:10 +00:00
|
|
|
}
|
|
|
|
}
|
2001-11-02 02:20:21 +00:00
|
|
|
putchar('\n');
|
1997-05-04 06:22:27 +00:00
|
|
|
}
|
|
|
|
|
2021-02-28 20:27:28 +00:00
|
|
|
if (supmedia) {
|
2001-05-29 09:13:44 +00:00
|
|
|
printf("\tsupported media:\n");
|
2021-02-28 20:27:28 +00:00
|
|
|
for (size_t i = 0; i < ifmr->ifm_count; ++i) {
|
2001-05-29 09:13:44 +00:00
|
|
|
printf("\t\t");
|
2021-02-28 20:27:28 +00:00
|
|
|
print_media_ifconfig(ifmr->ifm_ulist[i]);
|
2001-05-29 09:13:44 +00:00
|
|
|
putchar('\n');
|
1997-05-04 06:22:27 +00:00
|
|
|
}
|
|
|
|
}
|
2021-02-28 20:27:28 +00:00
|
|
|
free:
|
|
|
|
free(ifmr);
|
1997-05-04 06:22:27 +00:00
|
|
|
}
|
|
|
|
|
Update for revised 802.11 support:
o revised channel handling support; ifconfig now queries the kernel to
find the list of available channels and handles channel promotion;
channel attributes can be specified as part of the channel; e.g. 36:a
for channel 36 in 11a (as opposed to turbo A or HT A)
o use channel list to map between freq and IEEE channel #; this eliminates
all knowledge of how the mapping is done and fixes handling of cases
where channels overlap in the IEEE channel # space but are distinct in
the frequency+attributes space (e.g. PSB)
o add new knobs: bgscan, ff (Atheors fast frames), dturbo (Atheros
Dynamic Turbo mode), bgscanidle, bgscanintvl, scanvalid, roam:rssi11a,
roam:rssi11b, roam:rssi11g, roam:rate11a, roam:rate11b, roam:rate11g
(roaming parameters), burst, doth (forthcoming 11h support)
o print contents of WME, ATH, WPA, RSN, information elements with -v option
o print signal strength in dBm
o print noise floor in dBm
o add list txpow to print tx power caps/channel
o change default channel display in status to be more informative
2007-06-11 03:56:33 +00:00
|
|
|
struct ifmediareq *
|
2021-02-28 20:27:28 +00:00
|
|
|
ifmedia_getstate(void)
|
1997-05-04 06:22:27 +00:00
|
|
|
{
|
2021-04-16 02:32:25 +00:00
|
|
|
static struct ifmediareq *ifmr = NULL;
|
|
|
|
|
|
|
|
if (ifmr != NULL)
|
|
|
|
return (ifmr);
|
2005-01-27 16:40:12 +00:00
|
|
|
|
2021-02-28 20:27:28 +00:00
|
|
|
if (ifconfig_media_get_mediareq(lifh, name, &ifmr) == -1)
|
|
|
|
errc(1, ifconfig_err_errno(lifh),
|
|
|
|
"%s: ifconfig_media_get_mediareq", name);
|
1997-05-04 06:22:27 +00:00
|
|
|
|
2021-02-28 20:27:28 +00:00
|
|
|
if (ifmr->ifm_count == 0)
|
|
|
|
errx(1, "%s: no media types?", name);
|
|
|
|
|
|
|
|
return (ifmr);
|
2005-01-27 16:40:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
setifmediacallback(int s, void *arg)
|
|
|
|
{
|
|
|
|
struct ifmediareq *ifmr = (struct ifmediareq *)arg;
|
2021-02-28 20:27:28 +00:00
|
|
|
static bool did_it = false;
|
2005-01-27 16:40:12 +00:00
|
|
|
|
|
|
|
if (!did_it) {
|
2006-01-11 22:37:59 +00:00
|
|
|
ifr.ifr_media = ifmr->ifm_current;
|
2005-01-27 16:40:12 +00:00
|
|
|
if (ioctl(s, SIOCSIFMEDIA, (caddr_t)&ifr) < 0)
|
|
|
|
err(1, "SIOCSIFMEDIA (media)");
|
|
|
|
free(ifmr);
|
2021-02-28 20:27:28 +00:00
|
|
|
did_it = true;
|
2005-01-27 16:40:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
setmedia(const char *val, int d, int s, const struct afswtch *afp)
|
|
|
|
{
|
|
|
|
struct ifmediareq *ifmr;
|
|
|
|
int subtype;
|
|
|
|
|
2021-02-28 20:27:28 +00:00
|
|
|
ifmr = ifmedia_getstate();
|
1997-05-04 06:22:27 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* We are primarily concerned with the top-level type.
|
|
|
|
* However, "current" may be only IFM_NONE, so we just look
|
|
|
|
* for the top-level type in the first "supported type"
|
|
|
|
* entry.
|
|
|
|
*
|
|
|
|
* (I'm assuming that all supported media types for a given
|
|
|
|
* interface will be the same top-level type..)
|
|
|
|
*/
|
2021-02-28 20:27:28 +00:00
|
|
|
subtype = get_media_subtype(ifmr->ifm_ulist[0], val);
|
1997-05-04 06:22:27 +00:00
|
|
|
|
Use strlcpy() instead of strncpy() when copying ifname to ensure
that it is NUL terminated. Additional NUL padding is not required
for short names.
Use sizeof(destination) in a few places instead of IFNAMSIZ.
Cast afp->af_ridreq and afp->af_addreq to make the intent of
the code more obvious.
Reported by: Coverity
CID: 1009628, 1009630, 1009631, 1009632, 1009633, 1009635, 1009638
CID: 1009639, 1009640, 1009641, 1009642, 1009643, 1009644, 1009645
CID: 1009646, 1009647, 1010049, 1010050, 1010051, 1010052, 1010053
CID: 1010054, 1011293, 1011294, 1011295, 1011296, 1011297, 1011298
CID: 1011299, 1305821, 1351720, 1351721
MFC after: 1 week
2016-05-16 00:25:24 +00:00
|
|
|
strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
|
2011-05-15 12:51:00 +00:00
|
|
|
ifr.ifr_media = (ifmr->ifm_current & IFM_IMASK) |
|
2005-01-27 16:40:12 +00:00
|
|
|
IFM_TYPE(ifmr->ifm_ulist[0]) | subtype;
|
|
|
|
|
|
|
|
ifmr->ifm_current = ifr.ifr_media;
|
|
|
|
callback_register(setifmediacallback, (void *)ifmr);
|
1997-05-04 06:22:27 +00:00
|
|
|
}
|
|
|
|
|
2004-12-08 19:18:07 +00:00
|
|
|
static void
|
2002-04-18 17:14:09 +00:00
|
|
|
setmediaopt(const char *val, int d, int s, const struct afswtch *afp)
|
1997-05-04 06:22:27 +00:00
|
|
|
{
|
|
|
|
|
2021-02-28 20:27:28 +00:00
|
|
|
domediaopt(val, false, s);
|
1997-05-04 06:22:27 +00:00
|
|
|
}
|
|
|
|
|
2004-12-08 19:18:07 +00:00
|
|
|
static void
|
2002-04-18 17:14:09 +00:00
|
|
|
unsetmediaopt(const char *val, int d, int s, const struct afswtch *afp)
|
1997-05-04 06:22:27 +00:00
|
|
|
{
|
|
|
|
|
2021-02-28 20:27:28 +00:00
|
|
|
domediaopt(val, true, s);
|
1997-05-04 06:22:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2021-02-28 20:27:28 +00:00
|
|
|
domediaopt(const char *val, bool clear, int s)
|
1997-05-04 06:22:27 +00:00
|
|
|
{
|
2005-01-27 16:40:12 +00:00
|
|
|
struct ifmediareq *ifmr;
|
2021-02-28 20:27:28 +00:00
|
|
|
ifmedia_t options;
|
1997-05-04 06:22:27 +00:00
|
|
|
|
2021-02-28 20:27:28 +00:00
|
|
|
ifmr = ifmedia_getstate();
|
1997-05-04 06:22:27 +00:00
|
|
|
|
2021-02-28 20:27:28 +00:00
|
|
|
options = get_media_options(ifmr->ifm_ulist[0], val);
|
1997-05-04 06:22:27 +00:00
|
|
|
|
Use strlcpy() instead of strncpy() when copying ifname to ensure
that it is NUL terminated. Additional NUL padding is not required
for short names.
Use sizeof(destination) in a few places instead of IFNAMSIZ.
Cast afp->af_ridreq and afp->af_addreq to make the intent of
the code more obvious.
Reported by: Coverity
CID: 1009628, 1009630, 1009631, 1009632, 1009633, 1009635, 1009638
CID: 1009639, 1009640, 1009641, 1009642, 1009643, 1009644, 1009645
CID: 1009646, 1009647, 1010049, 1010050, 1010051, 1010052, 1010053
CID: 1010054, 1011293, 1011294, 1011295, 1011296, 1011297, 1011298
CID: 1011299, 1305821, 1351720, 1351721
MFC after: 1 week
2016-05-16 00:25:24 +00:00
|
|
|
strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
|
2005-01-27 16:40:12 +00:00
|
|
|
ifr.ifr_media = ifmr->ifm_current;
|
1997-05-04 06:22:27 +00:00
|
|
|
if (clear)
|
|
|
|
ifr.ifr_media &= ~options;
|
2006-12-19 22:50:49 +00:00
|
|
|
else {
|
|
|
|
if (options & IFM_HDX) {
|
|
|
|
ifr.ifr_media &= ~IFM_FDX;
|
|
|
|
options &= ~IFM_HDX;
|
|
|
|
}
|
1997-05-04 06:22:27 +00:00
|
|
|
ifr.ifr_media |= options;
|
2006-12-19 22:50:49 +00:00
|
|
|
}
|
2005-01-27 16:40:12 +00:00
|
|
|
ifmr->ifm_current = ifr.ifr_media;
|
|
|
|
callback_register(setifmediacallback, (void *)ifmr);
|
2003-04-28 16:37:38 +00:00
|
|
|
}
|
|
|
|
|
2007-01-20 00:56:49 +00:00
|
|
|
static void
|
|
|
|
setmediainst(const char *val, int d, int s, const struct afswtch *afp)
|
|
|
|
{
|
|
|
|
struct ifmediareq *ifmr;
|
|
|
|
int inst;
|
|
|
|
|
2021-02-28 20:27:28 +00:00
|
|
|
ifmr = ifmedia_getstate();
|
2007-01-20 00:56:49 +00:00
|
|
|
|
|
|
|
inst = atoi(val);
|
2009-06-23 23:49:52 +00:00
|
|
|
if (inst < 0 || inst > (int)IFM_INST_MAX)
|
2007-01-20 00:56:49 +00:00
|
|
|
errx(1, "invalid media instance: %s", val);
|
|
|
|
|
Use strlcpy() instead of strncpy() when copying ifname to ensure
that it is NUL terminated. Additional NUL padding is not required
for short names.
Use sizeof(destination) in a few places instead of IFNAMSIZ.
Cast afp->af_ridreq and afp->af_addreq to make the intent of
the code more obvious.
Reported by: Coverity
CID: 1009628, 1009630, 1009631, 1009632, 1009633, 1009635, 1009638
CID: 1009639, 1009640, 1009641, 1009642, 1009643, 1009644, 1009645
CID: 1009646, 1009647, 1010049, 1010050, 1010051, 1010052, 1010053
CID: 1010054, 1011293, 1011294, 1011295, 1011296, 1011297, 1011298
CID: 1011299, 1305821, 1351720, 1351721
MFC after: 1 week
2016-05-16 00:25:24 +00:00
|
|
|
strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
|
2007-01-20 00:56:49 +00:00
|
|
|
ifr.ifr_media = (ifmr->ifm_current & ~IFM_IMASK) | inst << IFM_ISHIFT;
|
|
|
|
|
|
|
|
ifmr->ifm_current = ifr.ifr_media;
|
|
|
|
callback_register(setifmediacallback, (void *)ifmr);
|
|
|
|
}
|
2003-04-28 16:37:38 +00:00
|
|
|
|
2004-12-08 19:18:07 +00:00
|
|
|
static void
|
2003-04-28 16:37:38 +00:00
|
|
|
setmediamode(const char *val, int d, int s, const struct afswtch *afp)
|
|
|
|
{
|
2005-01-27 16:40:12 +00:00
|
|
|
struct ifmediareq *ifmr;
|
|
|
|
int mode;
|
2003-04-28 16:37:38 +00:00
|
|
|
|
2021-02-28 20:27:28 +00:00
|
|
|
ifmr = ifmedia_getstate();
|
2003-04-28 16:37:38 +00:00
|
|
|
|
2021-02-28 20:27:28 +00:00
|
|
|
mode = get_media_mode(ifmr->ifm_ulist[0], val);
|
2003-04-28 16:37:38 +00:00
|
|
|
|
Use strlcpy() instead of strncpy() when copying ifname to ensure
that it is NUL terminated. Additional NUL padding is not required
for short names.
Use sizeof(destination) in a few places instead of IFNAMSIZ.
Cast afp->af_ridreq and afp->af_addreq to make the intent of
the code more obvious.
Reported by: Coverity
CID: 1009628, 1009630, 1009631, 1009632, 1009633, 1009635, 1009638
CID: 1009639, 1009640, 1009641, 1009642, 1009643, 1009644, 1009645
CID: 1009646, 1009647, 1010049, 1010050, 1010051, 1010052, 1010053
CID: 1010054, 1011293, 1011294, 1011295, 1011296, 1011297, 1011298
CID: 1011299, 1305821, 1351720, 1351721
MFC after: 1 week
2016-05-16 00:25:24 +00:00
|
|
|
strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
|
2005-01-27 16:40:12 +00:00
|
|
|
ifr.ifr_media = (ifmr->ifm_current & ~IFM_MMASK) | mode;
|
2003-04-28 16:37:38 +00:00
|
|
|
|
2005-01-27 16:40:12 +00:00
|
|
|
ifmr->ifm_current = ifr.ifr_media;
|
|
|
|
callback_register(setifmediacallback, (void *)ifmr);
|
1997-05-04 06:22:27 +00:00
|
|
|
}
|
|
|
|
|
2021-02-28 20:27:28 +00:00
|
|
|
static ifmedia_t
|
|
|
|
get_media_subtype(ifmedia_t media, const char *val)
|
1997-05-04 06:22:27 +00:00
|
|
|
{
|
2021-02-28 20:27:28 +00:00
|
|
|
ifmedia_t subtype;
|
|
|
|
|
|
|
|
subtype = ifconfig_media_lookup_subtype(media, val);
|
|
|
|
if (subtype != INVALID_IFMEDIA)
|
|
|
|
return (subtype);
|
|
|
|
switch (errno) {
|
|
|
|
case EINVAL:
|
|
|
|
errx(EXIT_FAILURE, "unknown media type 0x%x", media);
|
|
|
|
case ENOENT:
|
|
|
|
errx(EXIT_FAILURE, "unknown media subtype: %s", val);
|
|
|
|
default:
|
|
|
|
err(EXIT_FAILURE, "ifconfig_media_lookup_subtype");
|
1997-05-04 06:22:27 +00:00
|
|
|
}
|
2003-04-28 16:37:38 +00:00
|
|
|
/*NOTREACHED*/
|
|
|
|
}
|
|
|
|
|
2021-02-28 20:27:28 +00:00
|
|
|
static ifmedia_t
|
|
|
|
get_media_mode(ifmedia_t media, const char *val)
|
2003-04-28 16:37:38 +00:00
|
|
|
{
|
2021-02-28 20:27:28 +00:00
|
|
|
ifmedia_t mode;
|
|
|
|
|
|
|
|
mode = ifconfig_media_lookup_mode(media, val);
|
|
|
|
if (mode != INVALID_IFMEDIA)
|
|
|
|
return (mode);
|
|
|
|
switch (errno) {
|
|
|
|
case EINVAL:
|
|
|
|
errx(EXIT_FAILURE, "unknown media type 0x%x", media);
|
|
|
|
case ENOENT:
|
|
|
|
return (INVALID_IFMEDIA);
|
|
|
|
default:
|
|
|
|
err(EXIT_FAILURE, "ifconfig_media_lookup_subtype");
|
2003-04-28 16:37:38 +00:00
|
|
|
}
|
2021-02-28 20:27:28 +00:00
|
|
|
/*NOTREACHED*/
|
1997-05-04 06:22:27 +00:00
|
|
|
}
|
|
|
|
|
2021-02-28 20:27:28 +00:00
|
|
|
static ifmedia_t
|
|
|
|
get_media_options(ifmedia_t media, const char *val)
|
1997-05-04 06:22:27 +00:00
|
|
|
{
|
2021-02-28 20:27:28 +00:00
|
|
|
ifmedia_t *options;
|
|
|
|
const char **optnames;
|
|
|
|
char *opts, *opt;
|
|
|
|
size_t nopts;
|
|
|
|
int rval;
|
1997-05-04 06:22:27 +00:00
|
|
|
|
|
|
|
/*
|
2021-02-28 20:27:28 +00:00
|
|
|
* We muck with the string, so copy it.
|
1997-05-04 06:22:27 +00:00
|
|
|
*/
|
2021-02-28 20:27:28 +00:00
|
|
|
opts = strdup(val);
|
|
|
|
if (opts == NULL)
|
|
|
|
err(EXIT_FAILURE, "strdup");
|
2001-05-29 09:13:44 +00:00
|
|
|
|
2021-02-28 20:27:28 +00:00
|
|
|
/*
|
|
|
|
* Split the comma-delimited list into separate strings.
|
|
|
|
*/
|
|
|
|
nopts = 0;
|
|
|
|
for (opt = opts; (opt = strtok(opt, ",")) != NULL; opt = NULL)
|
|
|
|
++nopts;
|
|
|
|
if (nopts == 0) {
|
|
|
|
free(opts);
|
|
|
|
return (0);
|
2001-05-29 09:13:44 +00:00
|
|
|
}
|
2021-02-28 20:27:28 +00:00
|
|
|
optnames = calloc(nopts, sizeof(*optnames));
|
|
|
|
if (optnames == NULL)
|
|
|
|
err(EXIT_FAILURE, "calloc");
|
|
|
|
opt = opts;
|
|
|
|
for (size_t i = 0; i < nopts; ++i) {
|
|
|
|
optnames[i] = opt;
|
|
|
|
opt = strchr(opt, '\0') + 1;
|
2003-04-28 16:37:38 +00:00
|
|
|
}
|
|
|
|
|
2021-02-28 20:27:28 +00:00
|
|
|
/*
|
|
|
|
* Look up the options in the user-provided list.
|
|
|
|
*/
|
|
|
|
options = ifconfig_media_lookup_options(media, optnames, nopts);
|
|
|
|
if (options == NULL)
|
|
|
|
err(EXIT_FAILURE, "ifconfig_media_lookup_options");
|
|
|
|
rval = 0;
|
|
|
|
for (size_t i = 0; i < nopts; ++i) {
|
|
|
|
if (options[i] == INVALID_IFMEDIA)
|
|
|
|
errx(EXIT_FAILURE, "unknown option: %s", optnames[i]);
|
|
|
|
rval |= options[i];
|
|
|
|
}
|
|
|
|
free(options);
|
|
|
|
free(optnames);
|
|
|
|
free(opts);
|
|
|
|
return (rval);
|
2003-04-28 16:37:38 +00:00
|
|
|
}
|
|
|
|
|
2001-05-29 09:13:44 +00:00
|
|
|
static void
|
2021-02-28 20:27:28 +00:00
|
|
|
print_media(ifmedia_t media, bool print_toptype)
|
2001-05-29 09:13:44 +00:00
|
|
|
{
|
2021-02-28 20:27:28 +00:00
|
|
|
const char *val, **options;
|
|
|
|
|
|
|
|
val = ifconfig_media_get_type(media);
|
|
|
|
if (val == NULL) {
|
1997-05-04 06:22:27 +00:00
|
|
|
printf("<unknown type>");
|
|
|
|
return;
|
2001-05-29 09:13:44 +00:00
|
|
|
} else if (print_toptype) {
|
2021-02-28 20:27:28 +00:00
|
|
|
printf("%s", val);
|
1997-05-04 06:22:27 +00:00
|
|
|
}
|
|
|
|
|
2021-02-28 20:27:28 +00:00
|
|
|
val = ifconfig_media_get_subtype(media);
|
|
|
|
if (val == NULL) {
|
2006-08-22 23:49:36 +00:00
|
|
|
printf("<unknown subtype>");
|
|
|
|
return;
|
|
|
|
}
|
1997-05-04 06:22:27 +00:00
|
|
|
|
2001-05-29 09:13:44 +00:00
|
|
|
if (print_toptype)
|
|
|
|
putchar(' ');
|
|
|
|
|
2021-02-28 20:27:28 +00:00
|
|
|
printf("%s", val);
|
1997-05-04 06:22:27 +00:00
|
|
|
|
2003-04-28 16:37:38 +00:00
|
|
|
if (print_toptype) {
|
2021-02-28 20:27:28 +00:00
|
|
|
val = ifconfig_media_get_mode(media);
|
|
|
|
if (val != NULL && strcasecmp("autoselect", val) != 0)
|
|
|
|
printf(" mode %s", val);
|
2003-04-28 16:37:38 +00:00
|
|
|
}
|
|
|
|
|
2021-02-28 20:27:28 +00:00
|
|
|
options = ifconfig_media_get_options(media);
|
|
|
|
if (options != NULL && options[0] != NULL) {
|
|
|
|
printf(" <%s", options[0]);
|
|
|
|
for (size_t i = 1; options[i] != NULL; ++i)
|
|
|
|
printf(",%s", options[i]);
|
|
|
|
printf(">");
|
1997-05-04 06:22:27 +00:00
|
|
|
}
|
2021-02-28 20:27:28 +00:00
|
|
|
free(options);
|
2007-01-20 00:56:49 +00:00
|
|
|
|
2021-02-28 20:27:28 +00:00
|
|
|
if (print_toptype && IFM_INST(media) != 0)
|
|
|
|
printf(" instance %d", IFM_INST(media));
|
1997-05-04 06:22:27 +00:00
|
|
|
}
|
|
|
|
|
2001-05-29 09:13:44 +00:00
|
|
|
static void
|
2021-02-28 20:27:28 +00:00
|
|
|
print_media_ifconfig(ifmedia_t media)
|
2001-05-29 09:13:44 +00:00
|
|
|
{
|
2021-02-28 20:27:28 +00:00
|
|
|
const char *val, **options;
|
|
|
|
|
|
|
|
val = ifconfig_media_get_type(media);
|
|
|
|
if (val == NULL) {
|
2001-05-29 09:13:44 +00:00
|
|
|
printf("<unknown type>");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Don't print the top-level type; it's not like we can
|
|
|
|
* change it, or anything.
|
|
|
|
*/
|
|
|
|
|
2021-02-28 20:27:28 +00:00
|
|
|
val = ifconfig_media_get_subtype(media);
|
|
|
|
if (val == NULL) {
|
2006-08-22 23:49:36 +00:00
|
|
|
printf("<unknown subtype>");
|
|
|
|
return;
|
|
|
|
}
|
2001-05-29 09:13:44 +00:00
|
|
|
|
2021-02-28 20:27:28 +00:00
|
|
|
printf("media %s", val);
|
|
|
|
|
|
|
|
val = ifconfig_media_get_mode(media);
|
|
|
|
if (val != NULL)
|
|
|
|
printf(" mode %s", val);
|
|
|
|
|
|
|
|
options = ifconfig_media_get_options(media);
|
|
|
|
if (options != NULL && options[0] != NULL) {
|
|
|
|
printf(" mediaopt %s", options[0]);
|
|
|
|
for (size_t i = 1; options[i] != NULL; ++i)
|
|
|
|
printf(",%s", options[i]);
|
2001-05-29 09:13:44 +00:00
|
|
|
}
|
2021-02-28 20:27:28 +00:00
|
|
|
free(options);
|
2007-01-20 00:56:49 +00:00
|
|
|
|
2021-02-28 20:27:28 +00:00
|
|
|
if (IFM_INST(media) != 0)
|
|
|
|
printf(" instance %d", IFM_INST(media));
|
2001-05-29 09:13:44 +00:00
|
|
|
}
|
|
|
|
|
1997-05-04 06:22:27 +00:00
|
|
|
/**********************************************************************
|
|
|
|
* ...until here.
|
|
|
|
**********************************************************************/
|
2004-12-08 19:18:07 +00:00
|
|
|
|
|
|
|
static struct cmd media_cmds[] = {
|
|
|
|
DEF_CMD_ARG("media", setmedia),
|
|
|
|
DEF_CMD_ARG("mode", setmediamode),
|
|
|
|
DEF_CMD_ARG("mediaopt", setmediaopt),
|
|
|
|
DEF_CMD_ARG("-mediaopt",unsetmediaopt),
|
2007-01-20 00:56:49 +00:00
|
|
|
DEF_CMD_ARG("inst", setmediainst),
|
|
|
|
DEF_CMD_ARG("instance", setmediainst),
|
2004-12-08 19:18:07 +00:00
|
|
|
};
|
|
|
|
static struct afswtch af_media = {
|
|
|
|
.af_name = "af_media",
|
|
|
|
.af_af = AF_UNSPEC,
|
2004-12-31 19:46:27 +00:00
|
|
|
.af_other_status = media_status,
|
2004-12-08 19:18:07 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static __constructor void
|
|
|
|
ifmedia_ctor(void)
|
|
|
|
{
|
2009-06-23 23:49:52 +00:00
|
|
|
size_t i;
|
2004-12-08 19:18:07 +00:00
|
|
|
|
2015-09-27 07:51:18 +00:00
|
|
|
for (i = 0; i < nitems(media_cmds); i++)
|
2004-12-08 19:18:07 +00:00
|
|
|
cmd_register(&media_cmds[i]);
|
|
|
|
af_register(&af_media);
|
|
|
|
}
|