Overhaul to cleanup some of the tangled logic that's grown over the years.

o break per-address family support out into separate files
o modularize per-address family and functional operations using
  a registration mechanism; this permits configuration according
  to which files you include (but beware that order of the files
  is important to insure backwards compatibility)
o many cleanups to eliminate incestuous behaviour, global variables,
  and poor coding practices (still much more to fix)

The original motivation of this work was to support dynamic addition
of functionality based on the interface so we can eliminate the various
little control programs and so that vendors can distribute ifconfig
plugins that support their in-kernel code.  That work is still to be
completed.

o Update 802.11 support for all the new net80211 functionality; some
  of these operations (e.g. list *) may be better suited in a different
  program
This commit is contained in:
Sam Leffler 2004-12-08 19:18:07 +00:00
parent 5ad5504c14
commit 5faf8dcb55
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=138593
14 changed files with 3344 additions and 1540 deletions

View File

@ -2,35 +2,36 @@
# $FreeBSD$
PROG= ifconfig
SRCS= ifconfig.c
#comment out to exclude SIOC[GS]IFMEDIA support
SRCS+= ifmedia.c
CFLAGS+=-DUSE_IF_MEDIA
CFLAGS+=-DINET6
SRCS= ifconfig.c # base support
#comment out to exclude SIOC[GS]ETVLAN support
SRCS+= ifvlan.c
CFLAGS+=-DUSE_VLANS
#
# NB: The order here defines the order in which the constructors
# are called. This in turn defines the default order in which
# status is displayed. Probably should add a priority mechanism
# to the registration process so we don't depend on this aspect
# of the toolchain.
#
SRCS+= af_link.c # LLC support
SRCS+= af_inet.c # IPv4 support
SRCS+= af_inet6.c # IPv6 support
SRCS+= af_atalk.c # AppleTalk support
#comment out to exclude SIOC[GS]IEEE80211 support
SRCS+= ifieee80211.c
CFLAGS+=-DUSE_IEEE80211
SRCS+= ifclone.c # clone device support
SRCS+= ifmac.c # MAC support
SRCS+= ifmedia.c # SIOC[GS]IFMEDIA support
SRCS+= ifvlan.c # SIOC[GS]ETVLAN support
SRCS+= ifieee80211.c # SIOC[GS]IEEE80211 support
#comment out to exclude MAC support
SRCS+= ifmac.c
CFLAGS+=-DUSE_MAC
MAN= ifconfig.8
.if defined(RELEASE_CRUNCH)
CFLAGS+=-DNO_IPX
.else
.if !defined(RELEASE_CRUNCH)
SRCS+= af_ipx.c # IPX support
DPADD= ${LIBIPX}
LDADD= -lipx
.endif
CFLAGS+=-DNS -Wall -Wmissing-prototypes -Wcast-qual -Wwrite-strings \
MAN= ifconfig.8
CFLAGS+= -g -Wall -Wmissing-prototypes -Wcast-qual -Wwrite-strings \
-Wnested-externs -I..
WARNS?= 0

184
sbin/ifconfig/af_atalk.c Normal file
View File

@ -0,0 +1,184 @@
/*
* 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.
*/
#ifndef lint
static const char rcsid[] =
"$FreeBSD$";
#endif /* not lint */
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
#include <net/route.h> /* for RTX_IFA */
#include <netatalk/at.h>
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include "ifconfig.h"
static struct netrange at_nr; /* AppleTalk net range */
static struct ifaliasreq at_addreq;
/* XXX FIXME -- should use strtoul for better parsing. */
static void
setatrange(const char *range, int dummy __unused, int s,
const struct afswtch *afp)
{
u_int first = 123, last = 123;
if (sscanf(range, "%u-%u", &first, &last) != 2
|| first == 0 || first > 0xffff
|| last == 0 || last > 0xffff || first > last)
errx(1, "%s: illegal net range: %u-%u", range, first, last);
at_nr.nr_firstnet = htons(first);
at_nr.nr_lastnet = htons(last);
}
static void
setatphase(const char *phase, int dummy __unused, int s,
const struct afswtch *afp)
{
if (!strcmp(phase, "1"))
at_nr.nr_phase = 1;
else if (!strcmp(phase, "2"))
at_nr.nr_phase = 2;
else
errx(1, "%s: illegal phase", phase);
}
static void
at_status(int s __unused, const struct rt_addrinfo * info)
{
struct sockaddr_at *sat, null_sat;
struct netrange *nr;
memset(&null_sat, 0, sizeof(null_sat));
sat = (struct sockaddr_at *)info->rti_info[RTAX_IFA];
if (sat == NULL)
return;
nr = &sat->sat_range.r_netrange;
printf("\tatalk %d.%d range %d-%d phase %d",
ntohs(sat->sat_addr.s_net), sat->sat_addr.s_node,
ntohs(nr->nr_firstnet), ntohs(nr->nr_lastnet), nr->nr_phase);
if (flags & IFF_POINTOPOINT) {
/* note RTAX_BRD overlap with IFF_BROADCAST */
sat = (struct sockaddr_at *)info->rti_info[RTAX_BRD];
if (!sat)
sat = &null_sat;
printf("--> %d.%d",
ntohs(sat->sat_addr.s_net), sat->sat_addr.s_node);
}
if (flags & IFF_BROADCAST) {
/* note RTAX_BRD overlap with IFF_POINTOPOINT */
sat = (struct sockaddr_at *)info->rti_info[RTAX_BRD];
if (sat)
printf(" broadcast %d.%d",
ntohs(sat->sat_addr.s_net),
sat->sat_addr.s_node);
}
putchar('\n');
}
static void
at_getaddr(const char *addr, int which)
{
struct sockaddr_at *sat = (struct sockaddr_at *) &at_addreq.ifra_addr;
u_int net, node;
sat->sat_family = AF_APPLETALK;
sat->sat_len = sizeof(*sat);
if (which == MASK)
errx(1, "AppleTalk does not use netmasks");
if (sscanf(addr, "%u.%u", &net, &node) != 2
|| net > 0xffff || node > 0xfe)
errx(1, "%s: illegal address", addr);
sat->sat_addr.s_net = htons(net);
sat->sat_addr.s_node = node;
}
static void
at_postproc(int s, const struct afswtch *afp)
{
struct sockaddr_at *sat = (struct sockaddr_at *) &at_addreq.ifra_addr;
if (at_nr.nr_phase == 0)
at_nr.nr_phase = 2; /* Default phase 2 */
if (at_nr.nr_firstnet == 0)
at_nr.nr_firstnet = /* Default range of one */
at_nr.nr_lastnet = sat->sat_addr.s_net;
printf("\tatalk %d.%d range %d-%d phase %d\n",
ntohs(sat->sat_addr.s_net), sat->sat_addr.s_node,
ntohs(at_nr.nr_firstnet), ntohs(at_nr.nr_lastnet),
at_nr.nr_phase);
if ((u_short) ntohs(at_nr.nr_firstnet) >
(u_short) ntohs(sat->sat_addr.s_net)
|| (u_short) ntohs(at_nr.nr_lastnet) <
(u_short) ntohs(sat->sat_addr.s_net))
errx(1, "AppleTalk address is not in range");
sat->sat_range.r_netrange = at_nr;
}
static struct cmd atalk_cmds[] = {
DEF_CMD_ARG("range", setatrange),
DEF_CMD_ARG("phase", setatphase),
};
static struct afswtch af_atalk = {
.af_name = "atalk",
.af_af = AF_APPLETALK,
.af_status = at_status,
.af_getaddr = at_getaddr,
.af_postproc = at_postproc,
.af_difaddr = SIOCDIFADDR,
.af_aifaddr = SIOCAIFADDR,
.af_ridreq = &at_addreq,
.af_addreq = &at_addreq,
};
static __constructor void
atalk_ctor(void)
{
#define N(a) (sizeof(a) / sizeof(a[0]))
int i;
for (i = 0; i < N(atalk_cmds); i++)
cmd_register(&atalk_cmds[i]);
af_register(&af_atalk);
#undef N
}

198
sbin/ifconfig/af_inet.c Normal file
View File

@ -0,0 +1,198 @@
/*
* 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.
*/
#ifndef lint
static const char rcsid[] =
"$FreeBSD$";
#endif /* not lint */
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
#include <net/route.h> /* for RTX_IFA */
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <net/if_var.h> /* for struct ifaddr */
#include <netinet/in_var.h>
#include <arpa/inet.h>
#include <netdb.h>
#include "ifconfig.h"
static struct ifaliasreq in_addreq;
static struct ifreq in_ridreq;
static void
in_status(int s __unused, const struct rt_addrinfo * info)
{
struct sockaddr_in *sin, null_sin;
memset(&null_sin, 0, sizeof(null_sin));
sin = (struct sockaddr_in *)info->rti_info[RTAX_IFA];
if (sin == NULL)
return;
printf("\tinet %s ", inet_ntoa(sin->sin_addr));
if (flags & IFF_POINTOPOINT) {
/* note RTAX_BRD overlap with IFF_BROADCAST */
sin = (struct sockaddr_in *)info->rti_info[RTAX_BRD];
if (!sin)
sin = &null_sin;
printf("--> %s ", inet_ntoa(sin->sin_addr));
}
sin = (struct sockaddr_in *)info->rti_info[RTAX_NETMASK];
if (!sin)
sin = &null_sin;
printf("netmask 0x%lx ", (unsigned long)ntohl(sin->sin_addr.s_addr));
if (flags & IFF_BROADCAST) {
/* note RTAX_BRD overlap with IFF_POINTOPOINT */
sin = (struct sockaddr_in *)info->rti_info[RTAX_BRD];
if (sin && sin->sin_addr.s_addr != 0)
printf("broadcast %s", inet_ntoa(sin->sin_addr));
}
putchar('\n');
}
#define SIN(x) ((struct sockaddr_in *) &(x))
static struct sockaddr_in *sintab[] = {
SIN(in_ridreq.ifr_addr), SIN(in_addreq.ifra_addr),
SIN(in_addreq.ifra_mask), SIN(in_addreq.ifra_broadaddr)
};
static void
in_getaddr(const char *s, int which)
{
#define MIN(a,b) ((a)<(b)?(a):(b))
struct sockaddr_in *sin = sintab[which];
struct hostent *hp;
struct netent *np;
sin->sin_len = sizeof(*sin);
if (which != MASK)
sin->sin_family = AF_INET;
if (which == ADDR) {
char *p = NULL;
if((p = strrchr(s, '/')) != NULL) {
/* address is `name/masklen' */
int masklen;
int ret;
struct sockaddr_in *min = sintab[MASK];
*p = '\0';
ret = sscanf(p+1, "%u", &masklen);
if(ret != 1 || (masklen < 0 || masklen > 32)) {
*p = '/';
errx(1, "%s: bad value", s);
}
min->sin_len = sizeof(*min);
min->sin_addr.s_addr = htonl(~((1LL << (32 - masklen)) - 1) &
0xffffffff);
}
}
if (inet_aton(s, &sin->sin_addr))
return;
if ((hp = gethostbyname(s)) != 0)
bcopy(hp->h_addr, (char *)&sin->sin_addr,
MIN(hp->h_length, sizeof(sin->sin_addr)));
else if ((np = getnetbyname(s)) != 0)
sin->sin_addr = inet_makeaddr(np->n_net, INADDR_ANY);
else
errx(1, "%s: bad value", s);
#undef MIN
}
static void
in_status_tunnel(int s)
{
char src[NI_MAXHOST];
char dst[NI_MAXHOST];
struct ifreq ifr;
const struct sockaddr *sa = (const struct sockaddr *) &ifr.ifr_addr;
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, name, IFNAMSIZ);
if (ioctl(s, SIOCGIFPSRCADDR, (caddr_t)&ifr) < 0)
return;
if (getnameinfo(sa, sa->sa_len, src, sizeof(src), 0, 0, NI_NUMERICHOST) != 0)
src[0] = '\0';
if (ioctl(s, SIOCGIFPDSTADDR, (caddr_t)&ifr) < 0)
return;
if (getnameinfo(sa, sa->sa_len, dst, sizeof(dst), 0, 0, NI_NUMERICHOST) != 0)
dst[0] = '\0';
printf("\ttunnel inet %s --> %s\n", src, dst);
}
static void
in_set_tunnel(int s, struct addrinfo *srcres, struct addrinfo *dstres)
{
struct ifaliasreq addreq;
memset(&addreq, 0, sizeof(addreq));
strncpy(addreq.ifra_name, name, IFNAMSIZ);
memcpy(&addreq.ifra_addr, srcres->ai_addr, srcres->ai_addr->sa_len);
memcpy(&addreq.ifra_dstaddr, dstres->ai_addr, dstres->ai_addr->sa_len);
if (ioctl(s, SIOCSIFPHYADDR, &addreq) < 0)
warn("SIOCSIFPHYADDR");
}
static struct afswtch af_inet = {
.af_name = "inet",
.af_af = AF_INET,
.af_status = in_status,
.af_getaddr = in_getaddr,
.af_status_tunnel = in_status_tunnel,
.af_settunnel = in_set_tunnel,
.af_difaddr = SIOCDIFADDR,
.af_aifaddr = SIOCAIFADDR,
.af_ridreq = &in_ridreq,
.af_addreq = &in_addreq,
};
static __constructor void
inet_ctor(void)
{
af_register(&af_inet);
}

547
sbin/ifconfig/af_inet6.c Normal file
View File

@ -0,0 +1,547 @@
/*
* 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.
*/
#ifndef lint
static const char rcsid[] =
"$FreeBSD$";
#endif /* not lint */
#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
#include <net/route.h> /* for RTX_IFA */
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <ifaddrs.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <net/if_var.h> /* for struct ifaddr */
#include <netinet/in_var.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <netinet6/nd6.h> /* Define ND6_INFINITE_LIFETIME */
#include "ifconfig.h"
/* wrapper for KAME-special getnameinfo() */
#ifndef NI_WITHSCOPEID
#define NI_WITHSCOPEID 0
#endif
static struct in6_ifreq in6_ridreq;
static struct in6_aliasreq in6_addreq =
{ { 0 },
{ 0 },
{ 0 },
{ 0 },
0,
{ 0, 0, ND6_INFINITE_LIFETIME, ND6_INFINITE_LIFETIME } };
static int ip6lifetime;
static void in6_fillscopeid(struct sockaddr_in6 *sin6);
static int prefix(void *, int);
static char *sec2str(time_t);
static int explicit_prefix = 0;
static char addr_buf[MAXHOSTNAMELEN *2 + 1]; /*for getnameinfo()*/
static void
setifprefixlen(const char *addr, int dummy __unused, int s,
const struct afswtch *afp)
{
if (afp->af_getprefix != NULL)
afp->af_getprefix(addr, MASK);
explicit_prefix = 1;
}
static void
setip6flags(const char *dummyaddr __unused, int flag, int dummysoc __unused,
const struct afswtch *afp)
{
if (afp->af_af != AF_INET6)
err(1, "address flags can be set only for inet6 addresses");
if (flag < 0)
in6_addreq.ifra_flags &= ~(-flag);
else
in6_addreq.ifra_flags |= flag;
}
static void
setip6lifetime(const char *cmd, const char *val, int s,
const struct afswtch *afp)
{
time_t newval, t;
char *ep;
t = time(NULL);
newval = (time_t)strtoul(val, &ep, 0);
if (val == ep)
errx(1, "invalid %s", cmd);
if (afp->af_af != AF_INET6)
errx(1, "%s not allowed for the AF", cmd);
if (strcmp(cmd, "vltime") == 0) {
in6_addreq.ifra_lifetime.ia6t_expire = t + newval;
in6_addreq.ifra_lifetime.ia6t_vltime = newval;
} else if (strcmp(cmd, "pltime") == 0) {
in6_addreq.ifra_lifetime.ia6t_preferred = t + newval;
in6_addreq.ifra_lifetime.ia6t_pltime = newval;
}
}
static void
setip6pltime(const char *seconds, int dummy __unused, int s,
const struct afswtch *afp)
{
setip6lifetime("pltime", seconds, s, afp);
}
static void
setip6vltime(const char *seconds, int dummy __unused, int s,
const struct afswtch *afp)
{
setip6lifetime("vltime", seconds, s, afp);
}
static void
setip6eui64(const char *cmd, int dummy __unused, int s,
const struct afswtch *afp)
{
struct ifaddrs *ifap, *ifa;
const struct sockaddr_in6 *sin6 = NULL;
const struct in6_addr *lladdr = NULL;
struct in6_addr *in6;
if (afp->af_af != AF_INET6)
errx(EXIT_FAILURE, "%s not allowed for the AF", cmd);
in6 = (struct in6_addr *)&in6_addreq.ifra_addr.sin6_addr;
if (memcmp(&in6addr_any.s6_addr[8], &in6->s6_addr[8], 8) != 0)
errx(EXIT_FAILURE, "interface index is already filled");
if (getifaddrs(&ifap) != 0)
err(EXIT_FAILURE, "getifaddrs");
for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
if (ifa->ifa_addr->sa_family == AF_INET6 &&
strcmp(ifa->ifa_name, name) == 0) {
sin6 = (const struct sockaddr_in6 *)ifa->ifa_addr;
if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
lladdr = &sin6->sin6_addr;
break;
}
}
}
if (!lladdr)
errx(EXIT_FAILURE, "could not determine link local address");
memcpy(&in6->s6_addr[8], &lladdr->s6_addr[8], 8);
freeifaddrs(ifap);
}
static void
in6_fillscopeid(struct sockaddr_in6 *sin6)
{
#if defined(__KAME__) && defined(KAME_SCOPEID)
if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
sin6->sin6_scope_id =
ntohs(*(u_int16_t *)&sin6->sin6_addr.s6_addr[2]);
sin6->sin6_addr.s6_addr[2] = sin6->sin6_addr.s6_addr[3] = 0;
}
#endif
}
static void
in6_status(int s __unused, const struct rt_addrinfo * info)
{
struct sockaddr_in6 *sin, null_sin;
struct in6_ifreq ifr6;
int s6;
u_int32_t flags6;
struct in6_addrlifetime lifetime;
time_t t = time(NULL);
int error;
u_int32_t scopeid;
memset(&null_sin, 0, sizeof(null_sin));
sin = (struct sockaddr_in6 *)info->rti_info[RTAX_IFA];
if (sin == NULL)
return;
strncpy(ifr6.ifr_name, ifr.ifr_name, sizeof(ifr.ifr_name));
if ((s6 = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
warn("socket(AF_INET6,SOCK_DGRAM)");
return;
}
ifr6.ifr_addr = *sin;
if (ioctl(s6, SIOCGIFAFLAG_IN6, &ifr6) < 0) {
warn("ioctl(SIOCGIFAFLAG_IN6)");
close(s6);
return;
}
flags6 = ifr6.ifr_ifru.ifru_flags6;
memset(&lifetime, 0, sizeof(lifetime));
ifr6.ifr_addr = *sin;
if (ioctl(s6, SIOCGIFALIFETIME_IN6, &ifr6) < 0) {
warn("ioctl(SIOCGIFALIFETIME_IN6)");
close(s6);
return;
}
lifetime = ifr6.ifr_ifru.ifru_lifetime;
close(s6);
/* XXX: embedded link local addr check */
if (IN6_IS_ADDR_LINKLOCAL(&sin->sin6_addr) &&
*(u_short *)&sin->sin6_addr.s6_addr[2] != 0) {
u_short index;
index = *(u_short *)&sin->sin6_addr.s6_addr[2];
*(u_short *)&sin->sin6_addr.s6_addr[2] = 0;
if (sin->sin6_scope_id == 0)
sin->sin6_scope_id = ntohs(index);
}
scopeid = sin->sin6_scope_id;
error = getnameinfo((struct sockaddr *)sin, sin->sin6_len, addr_buf,
sizeof(addr_buf), NULL, 0,
NI_NUMERICHOST|NI_WITHSCOPEID);
if (error != 0)
inet_ntop(AF_INET6, &sin->sin6_addr, addr_buf,
sizeof(addr_buf));
printf("\tinet6 %s ", addr_buf);
if (flags & IFF_POINTOPOINT) {
/* note RTAX_BRD overlap with IFF_BROADCAST */
sin = (struct sockaddr_in6 *)info->rti_info[RTAX_BRD];
/*
* some of the interfaces do not have valid destination
* address.
*/
if (sin && sin->sin6_family == AF_INET6) {
int error;
/* XXX: embedded link local addr check */
if (IN6_IS_ADDR_LINKLOCAL(&sin->sin6_addr) &&
*(u_short *)&sin->sin6_addr.s6_addr[2] != 0) {
u_short index;
index = *(u_short *)&sin->sin6_addr.s6_addr[2];
*(u_short *)&sin->sin6_addr.s6_addr[2] = 0;
if (sin->sin6_scope_id == 0)
sin->sin6_scope_id = ntohs(index);
}
error = getnameinfo((struct sockaddr *)sin,
sin->sin6_len, addr_buf,
sizeof(addr_buf), NULL, 0,
NI_NUMERICHOST|NI_WITHSCOPEID);
if (error != 0)
inet_ntop(AF_INET6, &sin->sin6_addr, addr_buf,
sizeof(addr_buf));
printf("--> %s ", addr_buf);
}
}
sin = (struct sockaddr_in6 *)info->rti_info[RTAX_NETMASK];
if (!sin)
sin = &null_sin;
printf("prefixlen %d ", prefix(&sin->sin6_addr,
sizeof(struct in6_addr)));
if ((flags6 & IN6_IFF_ANYCAST) != 0)
printf("anycast ");
if ((flags6 & IN6_IFF_TENTATIVE) != 0)
printf("tentative ");
if ((flags6 & IN6_IFF_DUPLICATED) != 0)
printf("duplicated ");
if ((flags6 & IN6_IFF_DETACHED) != 0)
printf("detached ");
if ((flags6 & IN6_IFF_DEPRECATED) != 0)
printf("deprecated ");
if ((flags6 & IN6_IFF_AUTOCONF) != 0)
printf("autoconf ");
if ((flags6 & IN6_IFF_TEMPORARY) != 0)
printf("temporary ");
if (scopeid)
printf("scopeid 0x%x ", scopeid);
if (ip6lifetime && (lifetime.ia6t_preferred || lifetime.ia6t_expire)) {
printf("pltime ");
if (lifetime.ia6t_preferred) {
printf("%s ", lifetime.ia6t_preferred < t
? "0" : sec2str(lifetime.ia6t_preferred - t));
} else
printf("infty ");
printf("vltime ");
if (lifetime.ia6t_expire) {
printf("%s ", lifetime.ia6t_expire < t
? "0" : sec2str(lifetime.ia6t_expire - t));
} else
printf("infty ");
}
putchar('\n');
}
#define SIN6(x) ((struct sockaddr_in6 *) &(x))
static struct sockaddr_in6 *sin6tab[] = {
SIN6(in6_ridreq.ifr_addr), SIN6(in6_addreq.ifra_addr),
SIN6(in6_addreq.ifra_prefixmask), SIN6(in6_addreq.ifra_dstaddr)
};
static void
in6_getprefix(const char *plen, int which)
{
struct sockaddr_in6 *sin = sin6tab[which];
u_char *cp;
int len = atoi(plen);
if ((len < 0) || (len > 128))
errx(1, "%s: bad value", plen);
sin->sin6_len = sizeof(*sin);
if (which != MASK)
sin->sin6_family = AF_INET6;
if ((len == 0) || (len == 128)) {
memset(&sin->sin6_addr, 0xff, sizeof(struct in6_addr));
return;
}
memset((void *)&sin->sin6_addr, 0x00, sizeof(sin->sin6_addr));
for (cp = (u_char *)&sin->sin6_addr; len > 7; len -= 8)
*cp++ = 0xff;
*cp = 0xff << (8 - len);
}
static void
in6_getaddr(const char *s, int which)
{
struct sockaddr_in6 *sin = sin6tab[which];
struct addrinfo hints, *res;
int error = -1;
newaddr &= 1;
sin->sin6_len = sizeof(*sin);
if (which != MASK)
sin->sin6_family = AF_INET6;
if (which == ADDR) {
char *p = NULL;
if((p = strrchr(s, '/')) != NULL) {
*p = '\0';
in6_getprefix(p + 1, MASK);
explicit_prefix = 1;
}
}
if (sin->sin6_family == AF_INET6) {
bzero(&hints, sizeof(struct addrinfo));
hints.ai_family = AF_INET6;
error = getaddrinfo(s, NULL, &hints, &res);
}
if (error != 0) {
if (inet_pton(AF_INET6, s, &sin->sin6_addr) != 1)
errx(1, "%s: bad value", s);
} else
bcopy(res->ai_addr, sin, res->ai_addrlen);
}
static int
prefix(void *val, int size)
{
u_char *name = (u_char *)val;
int byte, bit, plen = 0;
for (byte = 0; byte < size; byte++, plen += 8)
if (name[byte] != 0xff)
break;
if (byte == size)
return (plen);
for (bit = 7; bit != 0; bit--, plen++)
if (!(name[byte] & (1 << bit)))
break;
for (; bit != 0; bit--)
if (name[byte] & (1 << bit))
return(0);
byte++;
for (; byte < size; byte++)
if (name[byte])
return(0);
return (plen);
}
static char *
sec2str(time_t total)
{
static char result[256];
int days, hours, mins, secs;
int first = 1;
char *p = result;
if (0) {
days = total / 3600 / 24;
hours = (total / 3600) % 24;
mins = (total / 60) % 60;
secs = total % 60;
if (days) {
first = 0;
p += sprintf(p, "%dd", days);
}
if (!first || hours) {
first = 0;
p += sprintf(p, "%dh", hours);
}
if (!first || mins) {
first = 0;
p += sprintf(p, "%dm", mins);
}
sprintf(p, "%ds", secs);
} else
sprintf(result, "%lu", (unsigned long)total);
return(result);
}
static void
in6_postproc(int s, const struct afswtch *afp)
{
if (explicit_prefix == 0) {
/* Aggregatable address architecture defines all prefixes
are 64. So, it is convenient to set prefixlen to 64 if
it is not specified. */
setifprefixlen("64", 0, s, afp);
/* in6_getprefix("64", MASK) if MASK is available here... */
}
}
static void
in6_status_tunnel(int s)
{
char src[NI_MAXHOST];
char dst[NI_MAXHOST];
#ifdef NI_WITHSCOPEID
const int niflag = NI_NUMERICHOST | NI_WITHSCOPEID;
#else
const int niflag = NI_NUMERICHOST;
#endif
struct in6_ifreq in6_ifr;
const struct sockaddr *sa = (const struct sockaddr *) &in6_ifr.ifr_addr;
memset(&in6_ifr, 0, sizeof(in6_ifr));
strncpy(in6_ifr.ifr_name, name, IFNAMSIZ);
if (ioctl(s, SIOCGIFPSRCADDR_IN6, (caddr_t)&in6_ifr) < 0)
return;
if (sa->sa_family == AF_INET6)
in6_fillscopeid(&in6_ifr.ifr_addr);
if (getnameinfo(sa, sa->sa_len, src, sizeof(src), 0, 0, niflag) != 0)
src[0] = '\0';
if (ioctl(s, SIOCGIFPDSTADDR_IN6, (caddr_t)&in6_ifr) < 0)
return;
if (sa->sa_family == AF_INET6)
in6_fillscopeid(&in6_ifr.ifr_addr);
if (getnameinfo(sa, sa->sa_len, dst, sizeof(dst), 0, 0, niflag) != 0)
dst[0] = '\0';
printf("\ttunnel inet6 %s --> %s\n", src, dst);
}
static void
in6_set_tunnel(int s, struct addrinfo *srcres, struct addrinfo *dstres)
{
struct in6_aliasreq in6_addreq;
memset(&in6_addreq, 0, sizeof(in6_addreq));
strncpy(in6_addreq.ifra_name, name, IFNAMSIZ);
memcpy(&in6_addreq.ifra_addr, srcres->ai_addr, srcres->ai_addr->sa_len);
memcpy(&in6_addreq.ifra_dstaddr, dstres->ai_addr,
dstres->ai_addr->sa_len);
if (ioctl(s, SIOCSIFPHYADDR_IN6, &in6_addreq) < 0)
warn("SIOCSIFPHYADDR_IN6");
}
static struct cmd inet6_cmds[] = {
DEF_CMD_ARG("prefixlen", setifprefixlen),
DEF_CMD("anycast", IN6_IFF_ANYCAST, setip6flags),
DEF_CMD("tentative", IN6_IFF_TENTATIVE, setip6flags),
DEF_CMD("-tentative", -IN6_IFF_TENTATIVE, setip6flags),
DEF_CMD("deprecated", IN6_IFF_DEPRECATED, setip6flags),
DEF_CMD("-deprecated", -IN6_IFF_DEPRECATED, setip6flags),
DEF_CMD("autoconf", IN6_IFF_AUTOCONF, setip6flags),
DEF_CMD("-autoconf", -IN6_IFF_AUTOCONF, setip6flags),
DEF_CMD_ARG("pltime", setip6pltime),
DEF_CMD_ARG("vltime", setip6vltime),
DEF_CMD("eui64", 0, setip6eui64),
};
static struct afswtch af_inet6 = {
.af_name = "inet6",
.af_af = AF_INET6,
.af_status = in6_status,
.af_getaddr = in6_getaddr,
.af_getprefix = in6_getprefix,
.af_postproc = in6_postproc,
.af_status_tunnel = in6_status_tunnel,
.af_settunnel = in6_set_tunnel,
.af_difaddr = SIOCDIFADDR_IN6,
.af_aifaddr = SIOCAIFADDR_IN6,
.af_ridreq = &in6_addreq,
.af_addreq = &in6_addreq,
};
static void
in6_Lopt_cb(const char *optarg __unused)
{
ip6lifetime++; /* print IPv6 address lifetime */
}
static struct option in6_Lopt = { "L", "[-L]", in6_Lopt_cb };
static __constructor void
inet6_ctor(void)
{
#define N(a) (sizeof(a) / sizeof(a[0]))
int i;
for (i = 0; i < N(inet6_cmds); i++)
cmd_register(&inet6_cmds[i]);
af_register(&af_inet6);
opt_register(&in6_Lopt);
#undef N
}

128
sbin/ifconfig/af_ipx.c Normal file
View File

@ -0,0 +1,128 @@
/*
* 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.
*/
#ifndef lint
static const char rcsid[] =
"$FreeBSD$";
#endif /* not lint */
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
#include <net/route.h>
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <net/if_var.h>
#define IPXIP
#define IPTUNNEL
#include <netipx/ipx.h>
#include <netipx/ipx_if.h>
#include "ifconfig.h"
static struct ifaliasreq ipx_addreq;
static struct ifreq ipx_ridreq;
static void
ipx_status(int s __unused, const struct rt_addrinfo * info)
{
struct sockaddr_ipx *sipx, null_sipx;
sipx = (struct sockaddr_ipx *)info->rti_info[RTAX_IFA];
if (sipx == NULL)
return;
printf("\tipx %s ", ipx_ntoa(sipx->sipx_addr));
if (flags & IFF_POINTOPOINT) {
sipx = (struct sockaddr_ipx *)info->rti_info[RTAX_BRD];
if (!sipx) {
memset(&null_sipx, 0, sizeof(null_sipx));
sipx = &null_sipx;
}
printf("--> %s ", ipx_ntoa(sipx->sipx_addr));
}
putchar('\n');
}
#define SIPX(x) ((struct sockaddr_ipx *) &(x))
struct sockaddr_ipx *sipxtab[] = {
SIPX(ipx_ridreq.ifr_addr), SIPX(ipx_addreq.ifra_addr),
SIPX(ipx_addreq.ifra_mask), SIPX(ipx_addreq.ifra_broadaddr)
};
static void
ipx_getaddr(const char *addr, int which)
{
struct sockaddr_ipx *sipx = sipxtab[which];
sipx->sipx_family = AF_IPX;
sipx->sipx_len = sizeof(*sipx);
sipx->sipx_addr = ipx_addr(addr);
if (which == MASK)
printf("Attempt to set IPX netmask will be ineffectual\n");
}
static void
ipx_postproc(int s, const struct afswtch *afp)
{
if (setipdst) {
struct ipxip_req rq;
int size = sizeof(rq);
rq.rq_ipx = ipx_addreq.ifra_addr;
rq.rq_ip = ipx_addreq.ifra_dstaddr;
if (setsockopt(s, 0, SO_IPXIP_ROUTE, &rq, size) < 0)
Perror("Encapsulation Routing");
}
}
static struct afswtch af_ipx = {
.af_name = "ipx",
.af_af = AF_IPX,
.af_status = ipx_status,
.af_getaddr = ipx_getaddr,
.af_postproc = ipx_postproc,
.af_difaddr = SIOCDIFADDR,
.af_aifaddr = SIOCAIFADDR,
.af_ridreq = &ipx_ridreq,
.af_addreq = &ipx_addreq,
};
static __constructor void
ipx_ctor(void)
{
af_register(&af_ipx);
}

125
sbin/ifconfig/af_link.c Normal file
View File

@ -0,0 +1,125 @@
/*
* 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.
*/
#ifndef lint
static const char rcsid[] =
"$FreeBSD$";
#endif /* not lint */
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <net/if_dl.h>
#include <net/if_types.h>
#include <net/ethernet.h>
#include "ifconfig.h"
static struct ifreq link_ridreq;
static void
link_status(int s __unused, const struct rt_addrinfo *info)
{
const struct sockaddr_dl *sdl = (const struct sockaddr_dl *)info;
if (sdl->sdl_alen > 0) {
if (sdl->sdl_type == IFT_ETHER &&
sdl->sdl_alen == ETHER_ADDR_LEN)
printf("\tether %s\n",
ether_ntoa((const struct ether_addr *)LLADDR(sdl)));
else {
int n = sdl->sdl_nlen > 0 ? sdl->sdl_nlen + 1 : 0;
printf("\tlladdr %s\n", link_ntoa(sdl) + n);
}
}
}
static void
link_getaddr(const char *addr, int which)
{
char *temp;
struct sockaddr_dl sdl;
struct sockaddr *sa = &link_ridreq.ifr_addr;
if (which != ADDR)
errx(1, "can't set link-level netmask or broadcast");
if ((temp = malloc(strlen(addr) + 1)) == NULL)
errx(1, "malloc failed");
temp[0] = ':';
strcpy(temp + 1, addr);
sdl.sdl_len = sizeof(sdl);
link_addr(temp, &sdl);
free(temp);
if (sdl.sdl_alen > sizeof(sa->sa_data))
errx(1, "malformed link-level address");
sa->sa_family = AF_LINK;
sa->sa_len = sdl.sdl_alen;
bcopy(LLADDR(&sdl), sa->sa_data, sdl.sdl_alen);
}
static struct afswtch af_link = {
.af_name = "link",
.af_af = AF_LINK,
.af_status = link_status,
.af_getaddr = link_getaddr,
.af_aifaddr = SIOCSIFLLADDR,
.af_addreq = &link_ridreq,
};
static struct afswtch af_ether = {
.af_name = "ether",
.af_af = AF_LINK,
.af_status = link_status,
.af_getaddr = link_getaddr,
.af_aifaddr = SIOCSIFLLADDR,
.af_addreq = &link_ridreq,
};
static struct afswtch af_lladdr = {
.af_name = "lladdr",
.af_af = AF_LINK,
.af_status = link_status,
.af_getaddr = link_getaddr,
.af_aifaddr = SIOCSIFLLADDR,
.af_addreq = &link_ridreq,
};
static __constructor void
link_ctor(void)
{
af_register(&af_link);
af_register(&af_ether);
af_register(&af_lladdr);
}

155
sbin/ifconfig/ifclone.c Normal file
View File

@ -0,0 +1,155 @@
/*
* 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.
*/
#ifndef lint
static const char rcsid[] =
"$FreeBSD$";
#endif /* not lint */
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "ifconfig.h"
static void
list_cloners(void)
{
struct if_clonereq ifcr;
char *cp, *buf;
int idx;
int s;
s = socket(AF_INET, SOCK_DGRAM, 0);
if (s == -1)
err(1, "socket(AF_INET,SOCK_DGRAM)");
memset(&ifcr, 0, sizeof(ifcr));
if (ioctl(s, SIOCIFGCLONERS, &ifcr) < 0)
err(1, "SIOCIFGCLONERS for count");
buf = malloc(ifcr.ifcr_total * IFNAMSIZ);
if (buf == NULL)
err(1, "unable to allocate cloner name buffer");
ifcr.ifcr_count = ifcr.ifcr_total;
ifcr.ifcr_buffer = buf;
if (ioctl(s, SIOCIFGCLONERS, &ifcr) < 0)
err(1, "SIOCIFGCLONERS for names");
/*
* In case some disappeared in the mean time, clamp it down.
*/
if (ifcr.ifcr_count > ifcr.ifcr_total)
ifcr.ifcr_count = ifcr.ifcr_total;
for (cp = buf, idx = 0; idx < ifcr.ifcr_count; idx++, cp += IFNAMSIZ) {
if (idx > 0)
putchar(' ');
printf("%s", cp);
}
putchar('\n');
free(buf);
}
void
clone_create(void)
{
int s;
s = socket(AF_INET, SOCK_DGRAM, 0);
if (s == -1)
err(1, "socket(AF_INET,SOCK_DGRAM)");
memset(&ifr, 0, sizeof(ifr));
(void) strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
if (ioctl(s, SIOCIFCREATE, &ifr) < 0)
err(1, "SIOCIFCREATE");
/*
* If we get a different name back then we put in, we probably
* want to print it out, but we might change our mind later so
* we just signal our intrest and leave the printout for later.
*/
if (strcmp(name, ifr.ifr_name) != 0) {
printname = 1;
strlcpy(name, ifr.ifr_name, sizeof(name));
}
close(s);
}
static void
clone_destroy(const char *val, int d, int s, const struct afswtch *rafp)
{
(void) strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
if (ioctl(s, SIOCIFDESTROY, &ifr) < 0)
err(1, "SIOCIFDESTROY");
/*
* If we create and destroy an interface in the same command,
* there isn't any reason to print it's name.
*/
printname = 0;
}
static struct cmd clone_cmds[] = {
DEF_CMD("destroy", 0, clone_destroy),
DEF_CMD("unplumb", 0, clone_destroy),
};
static void
clone_Copt_cb(const char *optarg __unused)
{
list_cloners();
exit(0);
}
static struct option clone_Copt = { "C", "[-C]", clone_Copt_cb };
static __constructor void
clone_ctor(void)
{
#define N(a) (sizeof(a) / sizeof(a[0]))
int i;
for (i = 0; i < N(clone_cmds); i++)
cmd_register(&clone_cmds[i]);
opt_register(&clone_Copt);
#undef N
}

View File

@ -28,7 +28,7 @@
.\" From: @(#)ifconfig.8 8.3 (Berkeley) 1/5/94
.\" $FreeBSD$
.\"
.Dd July 26, 2004
.Dd Nov 2, 2004
.Dt IFCONFIG 8
.Os
.Sh NAME
@ -55,6 +55,7 @@
.Op Fl d
.Op Fl m
.Op Fl u
.Op Fl v
.Op Ar address_family
.Nm
.Fl l
@ -66,6 +67,7 @@
.Op Fl d
.Op Fl m
.Op Fl u
.Op Fl v
.Op Fl C
.Sh DESCRIPTION
The
@ -596,64 +598,101 @@ This may be used to enable an interface after an
It happens automatically when setting the first address on an interface.
If the interface was reset when previously marked down,
the hardware will be re-initialized.
.It Cm ssid Ar ssid
For IEEE 802.11 wireless interfaces, set the desired Service Set
Identifier (aka network name).
The SSID is a string up to 32 characters
in length and may be specified as either a normal string or in
hexadecimal when proceeded by
.Ql 0x .
Additionally, the SSID may be cleared by setting it to
.Ql - .
.It Cm nwid Ar ssid
Another name for the
.Cm ssid
parameter.
Included for
.Nx
compatibility.
.It Cm stationname Ar name
For IEEE 802.11 wireless interfaces, set the name of this station.
It appears that the station name is not really part of the IEEE 802.11
protocol though all interfaces seem to support it.
As such it only
seems to be meaningful to identical or virtually identical equipment.
Setting the station name is identical in syntax to setting the SSID.
.It Cm station Ar name
Another name for the
.Cm stationname
parameter.
Included for
.Bsx
compatibility.
.It Cm channel Ar number
For IEEE 802.11 wireless interfaces, set the desired channel.
Channels range from 1 to 14, but the exact selection available
depends on the region your adaptor was manufactured for.
Setting
the channel to 0 will give you the default for your adaptor.
Many
adaptors ignore this setting unless you are in ad-hoc mode.
.El
.Pp
The following parameters are specific to IEEE 802.11 wireless interfaces:
.Bl -tag -width indent
.It Cm apbridge
When operating as an access point pass packets between
wireless clients directly (default).
To instead let them pass up through the
system and be forwarded using some other mechanism use
.Dq Li -apbridge.
Disabling the internal bridging
is useful when traffic is to be processed with
packet filtering.
.It Cm authmode Ar mode
For IEEE 802.11 wireless interfaces, set the desired authentication mode
in infrastructure mode.
Set the desired authentication mode in infrastructure mode.
Not all adaptors support all modes.
The set of
valid modes is
.Dq Li none ,
.Dq Li open ,
.Dq Li shared (shared key),
.Dq Li 8021x (IEEE 802.1x),
or
.Dq Li wpa (IEEE WPA/WPA2/802.11i).
The
.Dq Li 8021x
and
.Dq Li shared .
.Dq Li wpa
modes are only useful when used an authentication service
(a supplicant for client operation or an authenticator when
operating as an access point).
Modes are case insensitive.
.It Cm bssid Ar address
Specify the MAC address of the access point to use when operating
as a station in a BSS network.
This overrides any automatic selection done by the system.
To disable a previously selected access point supply
.Dq Li any ,
.Dq Li none ,
or
.Dq Li -
for the address.
This option is useful when more than one access points have the same SSID.
Another name for the
.Cm bssid
parameter is
.Cm ap .
.It Cm chanlist Ar channels
Set the desired channels to use when scanning for access
points, neighbors in an IBSS network, or looking for unoccupied
channels when operating as an access point.
The set of channels is specified as a comma-separated list with
each element in the list either a single channel number of a range
of the form
.Dq Li a-b .
Channel numbers must be in the range 1 to 255 and be permissible
according to the operating characteristics of the device.
.It Cm channel Ar number
Set a single desired channel.
Channels range from 1 to 255, but the exact selection available
depends on the region your adaptor was manufactured for.
Setting
the channel to
.Dq Li 0 ,
.Dq Li any ,
or
.Dq Li -
will give you the default for your adaptor.
Many
adaptors ignore this setting unless you are in ad-hoc mode.
Alternatively the frequency, in megahertz, may be specified
instead of the channel number.
.It Cm hidessid
When operating as an access point do not broadcast the SSID
in beacon frames.
By default the SSID is included in beacon frames.
To re-enable the broadcast of the SSID use
.Fl hidessid .
.It Cm powersave
For IEEE 802.11 wireless interfaces, enable powersave mode.
.It Fl powersave
For IEEE 802.11 wireless interfaces, disable powersave mode.
Enable powersave operation.
When operating as a client the station will conserve power by
periodically turning off the radio and listening for
messages from the access point telling it there are packets waiting.
The station must then retrieve the packets.
When operating as an access point the station must honor power
save operation of associated clients.
Not all devices support power save operation, either as a client
or as an access point.
Use
.Fl powersave
to disable powersave operation.
.It Cm powersavesleep Ar sleep
For IEEE 802.11 wireless interfaces, set the desired max powersave sleep
time in milliseconds.
Set the desired max powersave sleep time in milliseconds.
.It Cm protmode Ar technique
For IEEE 802.11 wireless interfaces operating in 11g, use the specified
For interfaces operating in 802.11g, use the specified
.Ar technique
for protecting OFDM frames in a mixed 11b/11g network.
The set of valid techniques is
@ -664,8 +703,25 @@ and
.Dq Li rtscts
(RTS/CTS).
Technique names are case insensitive.
.It Cm roaming Ar mode
When operating as a station, control how the system will
behave when communication with the current access point
is broken.
.I Mode
may be one of
.Dq Li device
(leave it to the hardware device to decide),
.Dq Li auto
(handle either in the device or the operating system--as appropriate),
.Dq Li manual
(do nothing until explicitly instructed).
By the default the device is left to handle this if it is
capable; otherwise the operating system will automatically
attempt to reestablish communication.
Manual mode is mostly useful when an application wants to
control the selection of an access point.
.It Cm rtsthreshold Ar length
For IEEE 802.11 wireless interfaces, set the threshold for which
Set the threshold for which
transmitted frames are preceded by transmission of an
RTS
control frame.
@ -674,8 +730,26 @@ The
argument
is the frame size in bytes and must be in the range 1 to 2312.
Not all adaptors support setting the RTS threshold.
.It Cm ssid Ar ssid
Set the desired Service Set Identifier (aka network name).
The SSID is a string up to 32 characters
in length and may be specified as either a normal string or in
hexadecimal when proceeded by
.Ql 0x .
Additionally, the SSID may be cleared by setting it to
.Ql - .
.It Cm scan
Display the current set of scanned neighbors and/or trigger a new scan.
Only the super-user can trigger a scan.
.It Cm stationname Ar name
Set the name of this station.
It appears that the station name is not really part of the IEEE 802.11
protocol though all interfaces seem to support it.
As such it only
seems to be meaningful to identical or virtually identical equipment.
Setting the station name is identical in syntax to setting the SSID.
.It Cm txpower Ar power
For IEEE 802.11 wireless interfaces, set the power used to transmit frames.
Set the power used to transmit frames.
The
.Ar power
argument
@ -686,7 +760,7 @@ Typically only a few discreet power settings are available and
the driver will use the setting closest to the specified value.
Not all adaptors support changing the transmit power.
.It Cm wepmode Ar mode
For IEEE 802.11 wireless interfaces, set the desired WEP mode.
Set the desired WEP mode.
Not all adaptors support all modes.
The set of valid modes is
.Dq Li off ,
@ -706,10 +780,9 @@ is generally another name for
.Dq Li mixed .
Modes are case insensitive.
.It Cm weptxkey Ar index
For IEEE 802.11 wireless interfaces, set the WEP key to be used for
transmission.
Set the WEP key to be used for transmission.
.It Cm wepkey Ar key Ns | Ns Ar index : Ns Ar key
For IEEE 802.11 wireless interfaces, set the selected WEP key.
Set the selected WEP key.
If an
.Ar index
is not given, key 1 is set.
@ -732,6 +805,31 @@ Some adaptors support more than four keys.
If that is the case, then the first four keys
(1-4) will be the standard temporary keys and any others will be adaptor
specific keys such as permanent keys stored in NVRAM.
.It Cm wme
Enable Wireless Media Extensions (WME) support, if available,
for the specified interface.
WME is a subset of the IEEE 802.11e standard to support the
efficient communication of realtime and multimedia data.
To disable WME support use
.Fl wme .
.El
.Pp
The following parameters are support for compatibility with other systems:
.Bl -tag -width indent
.It Cm nwid Ar ssid
Another name for the
.Cm ssid
parameter.
Included for
.Nx
compatibility.
.It Cm station Ar name
Another name for the
.Cm stationname
parameter.
Included for
.Bsx
compatibility.
.It Cm wep
Another way of saying
.Cm wepmode on .
@ -746,9 +844,7 @@ Included for
compatibility.
.It Cm nwkey key
Another way of saying:
.Pp
.Dq Li "wepmode on weptxkey 1 wepkey 1:key wepkey 2:- wepkey 3:- wepkey 4:-" .
.Pp
Included for
.Nx
compatibility.
@ -758,16 +854,13 @@ compatibility.
.Sm on
.Xc
Another way of saying
.Pp
.Dq Li "wepmode on weptxkey n wepkey 1:k1 wepkey 2:k2 wepkey 3:k3 wepkey 4:k4" .
.Pp
Included for
.Nx
compatibility.
.It Fl nwkey
Another way of saying
.Cm wepmode off .
.Pp
Included for
.Nx
compatibility.
@ -820,6 +913,10 @@ and
(only list interfaces that are up).
.Pp
The
.Fl v
flag may be used to get more verbose status for an interface.
.Pp
The
.Fl C
flag may be used to list all of the interface cloners available on
the system, with no additional information.

File diff suppressed because it is too large Load Diff

View File

@ -34,39 +34,97 @@
* $FreeBSD$
*/
extern struct ifreq ifr;
#define __constructor __attribute__((constructor))
extern char name[IFNAMSIZ]; /* name of interface */
extern int allmedia;
extern int supmedia;
struct afswtch;
struct cmd;
extern void setmedia(const char *, int, int, const struct afswtch *rafp);
extern void setmediamode(const char *, int, int, const struct afswtch *rafp);
extern void setmediaopt(const char *, int, int, const struct afswtch *rafp);
extern void unsetmediaopt(const char *, int, int, const struct afswtch *rafp);
extern void media_status(int s, struct rt_addrinfo *);
typedef void c_func(const char *cmd, int arg, int s, const struct afswtch *afp);
typedef void c_func2(const char *arg1, const char *arg2, int s, const struct afswtch *afp);
extern void setvlantag(const char *, int, int, const struct afswtch *rafp);
extern void setvlandev(const char *, int, int, const struct afswtch *rafp);
extern void unsetvlandev(const char *, int, int, const struct afswtch *rafp);
extern void vlan_status(int s, struct rt_addrinfo *);
struct cmd {
const char *c_name;
int c_parameter;
#define NEXTARG 0xffffff /* has following arg */
#define NEXTARG2 0xfffffe /* has 2 following args */
#define OPTARG 0xfffffd /* has optional following arg */
union {
c_func *c_func;
c_func2 *c_func2;
};
struct cmd *c_next;
};
void cmd_register(struct cmd *);
extern void set80211ssid(const char *, int, int, const struct afswtch *rafp);
extern void set80211stationname(const char *, int, int, const struct afswtch *rafp);
extern void set80211channel(const char *, int, int, const struct afswtch *rafp);
extern void set80211authmode(const char *, int, int, const struct afswtch *rafp);
extern void set80211powersave(const char *, int, int, const struct afswtch *rafp);
extern void set80211powersavemode(const char *, int, int, const struct afswtch *rafp);
extern void set80211powersavesleep(const char *, int, int, const struct afswtch *rafp);
extern void set80211wepmode(const char *, int, int, const struct afswtch *rafp);
extern void set80211wep(const char *, int, int, const struct afswtch *rafp);
extern void set80211weptxkey(const char *, int, int, const struct afswtch *rafp);
extern void set80211wepkey(const char *, int, int, const struct afswtch *rafp);
extern void set80211nwkey(const char *, int, int, const struct afswtch *rafp);
extern void set80211rtsthreshold(const char *, int, int, const struct afswtch *rafp);
extern void set80211protmode(const char *, int, int, const struct afswtch *rafp);
extern void set80211txpower(const char *, int, int, const struct afswtch *rafp);
extern void ieee80211_status(int s, struct rt_addrinfo *);
extern void maclabel_status(int s, struct rt_addrinfo *);
extern void setifmaclabel(const char *, int, int, const struct afswtch *rafp);
/*
* Macros for declaring command functions and initializing entries.
*/
#define DECL_CMD_FUNC(name, cmd, arg) \
void name(const char *cmd, int arg, int s, const struct afswtch *afp)
#define DECL_CMD_FUNC2(name, arg1, arg2) \
void name(const char *arg1, const char *arg2, int s, const struct afswtch *afp)
#define DEF_CMD(name, param, func) { name, param, { .c_func = func } }
#define DEF_CMD_ARG(name, func) { name, NEXTARG, { .c_func = func } }
#define DEF_CMD_OPTARG(name, func) { name, OPTARG, { .c_func = func } }
#define DEF_CMD_ARG2(name, func) { name, NEXTARG2, { .c_func2 = func } }
struct rt_addrinfo;
struct addrinfo;
enum {
RIDADDR,
ADDR,
MASK,
DSTADDR,
};
struct afswtch {
const char *af_name; /* as given on cmd line, e.g. "inet" */
short af_af; /* AF_* */
/* print status method */
void (*af_status)(int, const struct rt_addrinfo *);
/* parse address method */
void (*af_getaddr)(const char *, int);
/* parse prefix method (IPv6) */
void (*af_getprefix)(const char *, int);
void (*af_postproc)(int s, const struct afswtch *);
u_long af_difaddr; /* set dst if address ioctl */
u_long af_aifaddr; /* set if address ioctl */
void *af_ridreq; /* */
void *af_addreq; /* */
struct afswtch *af_next;
/* XXX doesn't fit model */
void (*af_status_tunnel)(int);
void (*af_settunnel)(int s, struct addrinfo *srcres,
struct addrinfo *dstres);
};
void af_register(struct afswtch *);
struct option {
const char *opt;
const char *opt_usage;
void (*cb)(const char *arg);
struct option *next;
};
void opt_register(struct option *);
extern struct ifreq ifr;
extern char name[IFNAMSIZ]; /* name of interface */
extern int allmedia;
extern int supmedia;
extern int printname;
extern int flags;
extern int newaddr;
extern int verbose;
extern int setipdst;
void setifcap(const char *, int value, int s, const struct afswtch *);
void Perror(const char *cmd);
void printb(const char *s, unsigned value, const char *bits);
void ifmaybeload(char *name);
void clone_create(void);

File diff suppressed because it is too large Load Diff

View File

@ -49,8 +49,8 @@
#include "ifconfig.h"
void
maclabel_status(int s, struct rt_addrinfo *info)
static void
maclabel_status(int s, const struct rt_addrinfo *info)
{
struct ifreq ifr;
mac_t label;
@ -77,7 +77,7 @@ maclabel_status(int s, struct rt_addrinfo *info)
mac_free(label);
}
void
static void
setifmaclabel(const char *val, int d, int s, const struct afswtch *rafp)
{
struct ifreq ifr;
@ -98,3 +98,24 @@ setifmaclabel(const char *val, int d, int s, const struct afswtch *rafp)
if (error == -1)
perror("setifmac");
}
static struct cmd mac_cmds[] = {
DEF_CMD_ARG("maclabel", setifmaclabel),
};
static struct afswtch af_mac = {
.af_name = "af_maclabel",
.af_af = AF_UNSPEC,
.af_status = maclabel_status,
};
static __constructor void
mac_ctor(void)
{
#define N(a) (sizeof(a) / sizeof(a[0]))
int i;
for (i = 0; i < N(mac_cmds); i++)
cmd_register(&mac_cmds[i]);
af_register(&af_mac);
#undef N
}

View File

@ -102,8 +102,8 @@ static struct ifmedia_type_to_subtype *get_toptype_ttos(int);
static struct ifmedia_description *get_subtype_desc(int,
struct ifmedia_type_to_subtype *ttos);
void
media_status(int s, struct rt_addrinfo *info __unused)
static void
media_status(int s, const struct rt_addrinfo *info __unused)
{
struct ifmediareq ifmr;
int *media_list, i;
@ -190,7 +190,7 @@ media_status(int s, struct rt_addrinfo *info __unused)
free(media_list);
}
void
static void
setmedia(const char *val, int d, int s, const struct afswtch *afp)
{
struct ifmediareq ifmr;
@ -232,14 +232,14 @@ setmedia(const char *val, int d, int s, const struct afswtch *afp)
err(1, "SIOCSIFMEDIA (media)");
}
void
static void
setmediaopt(const char *val, int d, int s, const struct afswtch *afp)
{
domediaopt(val, 0, s);
}
void
static void
unsetmediaopt(const char *val, int d, int s, const struct afswtch *afp)
{
@ -291,7 +291,7 @@ domediaopt(const char *val, int clear, int s)
}
void
static void
setmediamode(const char *val, int d, int s, const struct afswtch *afp)
{
struct ifmediareq ifmr;
@ -777,3 +777,27 @@ print_media_word_ifconfig(int ifmw)
/**********************************************************************
* ...until here.
**********************************************************************/
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),
};
static struct afswtch af_media = {
.af_name = "af_media",
.af_af = AF_UNSPEC,
.af_status = media_status,
};
static __constructor void
ifmedia_ctor(void)
{
#define N(a) (sizeof(a) / sizeof(a[0]))
int i;
for (i = 0; i < N(media_cmds); i++)
cmd_register(&media_cmds[i]);
af_register(&af_media);
#undef N
}

View File

@ -61,8 +61,8 @@ static const char rcsid[] =
static int __tag = 0;
static int __have_tag = 0;
void
vlan_status(int s, struct rt_addrinfo *info __unused)
static void
vlan_status(int s, const struct rt_addrinfo *info __unused)
{
struct vlanreq vreq;
@ -79,7 +79,7 @@ vlan_status(int s, struct rt_addrinfo *info __unused)
return;
}
void
static void
setvlantag(const char *val, int d, int s, const struct afswtch *afp)
{
u_int16_t tag;
@ -102,7 +102,7 @@ setvlantag(const char *val, int d, int s, const struct afswtch *afp)
return;
}
void
static void
setvlandev(const char *val, int d, int s, const struct afswtch *afp)
{
struct vlanreq vreq;
@ -125,7 +125,7 @@ setvlandev(const char *val, int d, int s, const struct afswtch *afp)
return;
}
void
static void
unsetvlandev(const char *val, int d, int s, const struct afswtch *afp)
{
struct vlanreq vreq;
@ -144,3 +144,30 @@ unsetvlandev(const char *val, int d, int s, const struct afswtch *afp)
return;
}
static struct cmd vlan_cmds[] = {
DEF_CMD_ARG("vlan", setvlantag),
DEF_CMD_ARG("vlandev", setvlandev),
DEF_CMD_ARG("-vlandev", unsetvlandev),
DEF_CMD("vlanmtu", IFCAP_VLAN_MTU, setifcap),
DEF_CMD("-vlanmtu", -IFCAP_VLAN_MTU, setifcap),
DEF_CMD("vlanhwtag", IFCAP_VLAN_HWTAGGING, setifcap),
DEF_CMD("-vlanhwtag", -IFCAP_VLAN_HWTAGGING, setifcap),
};
static struct afswtch af_vlan = {
.af_name = "af_vlan",
.af_af = AF_UNSPEC,
.af_status = vlan_status,
};
static __constructor void
vlan_ctor(void)
{
#define N(a) (sizeof(a) / sizeof(a[0]))
int i;
for (i = 0; i < N(vlan_cmds); i++)
cmd_register(&vlan_cmds[i]);
af_register(&af_vlan);
#undef N
}