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:
parent
5ad5504c14
commit
5faf8dcb55
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=138593
@ -2,35 +2,36 @@
|
|||||||
# $FreeBSD$
|
# $FreeBSD$
|
||||||
|
|
||||||
PROG= ifconfig
|
PROG= ifconfig
|
||||||
SRCS= ifconfig.c
|
|
||||||
|
|
||||||
#comment out to exclude SIOC[GS]IFMEDIA support
|
SRCS= ifconfig.c # base support
|
||||||
SRCS+= ifmedia.c
|
|
||||||
CFLAGS+=-DUSE_IF_MEDIA
|
|
||||||
CFLAGS+=-DINET6
|
|
||||||
|
|
||||||
#comment out to exclude SIOC[GS]ETVLAN support
|
#
|
||||||
SRCS+= ifvlan.c
|
# NB: The order here defines the order in which the constructors
|
||||||
CFLAGS+=-DUSE_VLANS
|
# 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+= ifclone.c # clone device support
|
||||||
SRCS+= ifieee80211.c
|
SRCS+= ifmac.c # MAC support
|
||||||
CFLAGS+=-DUSE_IEEE80211
|
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
|
.if !defined(RELEASE_CRUNCH)
|
||||||
SRCS+= ifmac.c
|
SRCS+= af_ipx.c # IPX support
|
||||||
CFLAGS+=-DUSE_MAC
|
|
||||||
|
|
||||||
MAN= ifconfig.8
|
|
||||||
|
|
||||||
.if defined(RELEASE_CRUNCH)
|
|
||||||
CFLAGS+=-DNO_IPX
|
|
||||||
.else
|
|
||||||
DPADD= ${LIBIPX}
|
DPADD= ${LIBIPX}
|
||||||
LDADD= -lipx
|
LDADD= -lipx
|
||||||
.endif
|
.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..
|
-Wnested-externs -I..
|
||||||
WARNS?= 0
|
WARNS?= 0
|
||||||
|
|
||||||
|
184
sbin/ifconfig/af_atalk.c
Normal file
184
sbin/ifconfig/af_atalk.c
Normal 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
198
sbin/ifconfig/af_inet.c
Normal 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
547
sbin/ifconfig/af_inet6.c
Normal 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
128
sbin/ifconfig/af_ipx.c
Normal 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
125
sbin/ifconfig/af_link.c
Normal 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
155
sbin/ifconfig/ifclone.c
Normal 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
|
||||||
|
}
|
@ -28,7 +28,7 @@
|
|||||||
.\" From: @(#)ifconfig.8 8.3 (Berkeley) 1/5/94
|
.\" From: @(#)ifconfig.8 8.3 (Berkeley) 1/5/94
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd July 26, 2004
|
.Dd Nov 2, 2004
|
||||||
.Dt IFCONFIG 8
|
.Dt IFCONFIG 8
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -55,6 +55,7 @@
|
|||||||
.Op Fl d
|
.Op Fl d
|
||||||
.Op Fl m
|
.Op Fl m
|
||||||
.Op Fl u
|
.Op Fl u
|
||||||
|
.Op Fl v
|
||||||
.Op Ar address_family
|
.Op Ar address_family
|
||||||
.Nm
|
.Nm
|
||||||
.Fl l
|
.Fl l
|
||||||
@ -66,6 +67,7 @@
|
|||||||
.Op Fl d
|
.Op Fl d
|
||||||
.Op Fl m
|
.Op Fl m
|
||||||
.Op Fl u
|
.Op Fl u
|
||||||
|
.Op Fl v
|
||||||
.Op Fl C
|
.Op Fl C
|
||||||
.Sh DESCRIPTION
|
.Sh DESCRIPTION
|
||||||
The
|
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.
|
It happens automatically when setting the first address on an interface.
|
||||||
If the interface was reset when previously marked down,
|
If the interface was reset when previously marked down,
|
||||||
the hardware will be re-initialized.
|
the hardware will be re-initialized.
|
||||||
.It Cm ssid Ar ssid
|
.El
|
||||||
For IEEE 802.11 wireless interfaces, set the desired Service Set
|
.Pp
|
||||||
Identifier (aka network name).
|
The following parameters are specific to IEEE 802.11 wireless interfaces:
|
||||||
The SSID is a string up to 32 characters
|
.Bl -tag -width indent
|
||||||
in length and may be specified as either a normal string or in
|
.It Cm apbridge
|
||||||
hexadecimal when proceeded by
|
When operating as an access point pass packets between
|
||||||
.Ql 0x .
|
wireless clients directly (default).
|
||||||
Additionally, the SSID may be cleared by setting it to
|
To instead let them pass up through the
|
||||||
.Ql - .
|
system and be forwarded using some other mechanism use
|
||||||
.It Cm nwid Ar ssid
|
.Dq Li -apbridge.
|
||||||
Another name for the
|
Disabling the internal bridging
|
||||||
.Cm ssid
|
is useful when traffic is to be processed with
|
||||||
parameter.
|
packet filtering.
|
||||||
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.
|
|
||||||
.It Cm authmode Ar mode
|
.It Cm authmode Ar mode
|
||||||
For IEEE 802.11 wireless interfaces, set the desired authentication mode
|
Set the desired authentication mode in infrastructure mode.
|
||||||
in infrastructure mode.
|
|
||||||
Not all adaptors support all modes.
|
Not all adaptors support all modes.
|
||||||
The set of
|
The set of
|
||||||
valid modes is
|
valid modes is
|
||||||
.Dq Li none ,
|
.Dq Li none ,
|
||||||
.Dq Li open ,
|
.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
|
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.
|
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
|
.It Cm powersave
|
||||||
For IEEE 802.11 wireless interfaces, enable powersave mode.
|
Enable powersave operation.
|
||||||
.It Fl powersave
|
When operating as a client the station will conserve power by
|
||||||
For IEEE 802.11 wireless interfaces, disable powersave mode.
|
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
|
.It Cm powersavesleep Ar sleep
|
||||||
For IEEE 802.11 wireless interfaces, set the desired max powersave sleep
|
Set the desired max powersave sleep time in milliseconds.
|
||||||
time in milliseconds.
|
|
||||||
.It Cm protmode Ar technique
|
.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
|
.Ar technique
|
||||||
for protecting OFDM frames in a mixed 11b/11g network.
|
for protecting OFDM frames in a mixed 11b/11g network.
|
||||||
The set of valid techniques is
|
The set of valid techniques is
|
||||||
@ -664,8 +703,25 @@ and
|
|||||||
.Dq Li rtscts
|
.Dq Li rtscts
|
||||||
(RTS/CTS).
|
(RTS/CTS).
|
||||||
Technique names are case insensitive.
|
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
|
.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
|
transmitted frames are preceded by transmission of an
|
||||||
RTS
|
RTS
|
||||||
control frame.
|
control frame.
|
||||||
@ -674,8 +730,26 @@ The
|
|||||||
argument
|
argument
|
||||||
is the frame size in bytes and must be in the range 1 to 2312.
|
is the frame size in bytes and must be in the range 1 to 2312.
|
||||||
Not all adaptors support setting the RTS threshold.
|
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
|
.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
|
The
|
||||||
.Ar power
|
.Ar power
|
||||||
argument
|
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.
|
the driver will use the setting closest to the specified value.
|
||||||
Not all adaptors support changing the transmit power.
|
Not all adaptors support changing the transmit power.
|
||||||
.It Cm wepmode Ar mode
|
.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.
|
Not all adaptors support all modes.
|
||||||
The set of valid modes is
|
The set of valid modes is
|
||||||
.Dq Li off ,
|
.Dq Li off ,
|
||||||
@ -706,10 +780,9 @@ is generally another name for
|
|||||||
.Dq Li mixed .
|
.Dq Li mixed .
|
||||||
Modes are case insensitive.
|
Modes are case insensitive.
|
||||||
.It Cm weptxkey Ar index
|
.It Cm weptxkey Ar index
|
||||||
For IEEE 802.11 wireless interfaces, set the WEP key to be used for
|
Set the WEP key to be used for transmission.
|
||||||
transmission.
|
|
||||||
.It Cm wepkey Ar key Ns | Ns Ar index : Ns Ar key
|
.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
|
If an
|
||||||
.Ar index
|
.Ar index
|
||||||
is not given, key 1 is set.
|
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
|
If that is the case, then the first four keys
|
||||||
(1-4) will be the standard temporary keys and any others will be adaptor
|
(1-4) will be the standard temporary keys and any others will be adaptor
|
||||||
specific keys such as permanent keys stored in NVRAM.
|
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
|
.It Cm wep
|
||||||
Another way of saying
|
Another way of saying
|
||||||
.Cm wepmode on .
|
.Cm wepmode on .
|
||||||
@ -746,9 +844,7 @@ Included for
|
|||||||
compatibility.
|
compatibility.
|
||||||
.It Cm nwkey key
|
.It Cm nwkey key
|
||||||
Another way of saying:
|
Another way of saying:
|
||||||
.Pp
|
|
||||||
.Dq Li "wepmode on weptxkey 1 wepkey 1:key wepkey 2:- wepkey 3:- wepkey 4:-" .
|
.Dq Li "wepmode on weptxkey 1 wepkey 1:key wepkey 2:- wepkey 3:- wepkey 4:-" .
|
||||||
.Pp
|
|
||||||
Included for
|
Included for
|
||||||
.Nx
|
.Nx
|
||||||
compatibility.
|
compatibility.
|
||||||
@ -758,16 +854,13 @@ compatibility.
|
|||||||
.Sm on
|
.Sm on
|
||||||
.Xc
|
.Xc
|
||||||
Another way of saying
|
Another way of saying
|
||||||
.Pp
|
|
||||||
.Dq Li "wepmode on weptxkey n wepkey 1:k1 wepkey 2:k2 wepkey 3:k3 wepkey 4:k4" .
|
.Dq Li "wepmode on weptxkey n wepkey 1:k1 wepkey 2:k2 wepkey 3:k3 wepkey 4:k4" .
|
||||||
.Pp
|
|
||||||
Included for
|
Included for
|
||||||
.Nx
|
.Nx
|
||||||
compatibility.
|
compatibility.
|
||||||
.It Fl nwkey
|
.It Fl nwkey
|
||||||
Another way of saying
|
Another way of saying
|
||||||
.Cm wepmode off .
|
.Cm wepmode off .
|
||||||
.Pp
|
|
||||||
Included for
|
Included for
|
||||||
.Nx
|
.Nx
|
||||||
compatibility.
|
compatibility.
|
||||||
@ -820,6 +913,10 @@ and
|
|||||||
(only list interfaces that are up).
|
(only list interfaces that are up).
|
||||||
.Pp
|
.Pp
|
||||||
The
|
The
|
||||||
|
.Fl v
|
||||||
|
flag may be used to get more verbose status for an interface.
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
.Fl C
|
.Fl C
|
||||||
flag may be used to list all of the interface cloners available on
|
flag may be used to list all of the interface cloners available on
|
||||||
the system, with no additional information.
|
the system, with no additional information.
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -34,39 +34,97 @@
|
|||||||
* $FreeBSD$
|
* $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 afswtch;
|
||||||
|
struct cmd;
|
||||||
|
|
||||||
extern void setmedia(const char *, int, int, const struct afswtch *rafp);
|
typedef void c_func(const char *cmd, int arg, int s, const struct afswtch *afp);
|
||||||
extern void setmediamode(const char *, int, int, const struct afswtch *rafp);
|
typedef void c_func2(const char *arg1, const char *arg2, int s, const struct afswtch *afp);
|
||||||
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 *);
|
|
||||||
|
|
||||||
extern void setvlantag(const char *, int, int, const struct afswtch *rafp);
|
struct cmd {
|
||||||
extern void setvlandev(const char *, int, int, const struct afswtch *rafp);
|
const char *c_name;
|
||||||
extern void unsetvlandev(const char *, int, int, const struct afswtch *rafp);
|
int c_parameter;
|
||||||
extern void vlan_status(int s, struct rt_addrinfo *);
|
#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);
|
* Macros for declaring command functions and initializing entries.
|
||||||
extern void set80211channel(const char *, int, int, const struct afswtch *rafp);
|
*/
|
||||||
extern void set80211authmode(const char *, int, int, const struct afswtch *rafp);
|
#define DECL_CMD_FUNC(name, cmd, arg) \
|
||||||
extern void set80211powersave(const char *, int, int, const struct afswtch *rafp);
|
void name(const char *cmd, int arg, int s, const struct afswtch *afp)
|
||||||
extern void set80211powersavemode(const char *, int, int, const struct afswtch *rafp);
|
#define DECL_CMD_FUNC2(name, arg1, arg2) \
|
||||||
extern void set80211powersavesleep(const char *, int, int, const struct afswtch *rafp);
|
void name(const char *arg1, const char *arg2, int s, const struct afswtch *afp)
|
||||||
extern void set80211wepmode(const char *, int, int, const struct afswtch *rafp);
|
|
||||||
extern void set80211wep(const char *, int, int, const struct afswtch *rafp);
|
#define DEF_CMD(name, param, func) { name, param, { .c_func = func } }
|
||||||
extern void set80211weptxkey(const char *, int, int, const struct afswtch *rafp);
|
#define DEF_CMD_ARG(name, func) { name, NEXTARG, { .c_func = func } }
|
||||||
extern void set80211wepkey(const char *, int, int, const struct afswtch *rafp);
|
#define DEF_CMD_OPTARG(name, func) { name, OPTARG, { .c_func = func } }
|
||||||
extern void set80211nwkey(const char *, int, int, const struct afswtch *rafp);
|
#define DEF_CMD_ARG2(name, func) { name, NEXTARG2, { .c_func2 = func } }
|
||||||
extern void set80211rtsthreshold(const char *, int, int, const struct afswtch *rafp);
|
|
||||||
extern void set80211protmode(const char *, int, int, const struct afswtch *rafp);
|
struct rt_addrinfo;
|
||||||
extern void set80211txpower(const char *, int, int, const struct afswtch *rafp);
|
struct addrinfo;
|
||||||
extern void ieee80211_status(int s, struct rt_addrinfo *);
|
|
||||||
extern void maclabel_status(int s, struct rt_addrinfo *);
|
enum {
|
||||||
extern void setifmaclabel(const char *, int, int, const struct afswtch *rafp);
|
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
@ -49,8 +49,8 @@
|
|||||||
|
|
||||||
#include "ifconfig.h"
|
#include "ifconfig.h"
|
||||||
|
|
||||||
void
|
static void
|
||||||
maclabel_status(int s, struct rt_addrinfo *info)
|
maclabel_status(int s, const struct rt_addrinfo *info)
|
||||||
{
|
{
|
||||||
struct ifreq ifr;
|
struct ifreq ifr;
|
||||||
mac_t label;
|
mac_t label;
|
||||||
@ -77,7 +77,7 @@ maclabel_status(int s, struct rt_addrinfo *info)
|
|||||||
mac_free(label);
|
mac_free(label);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
setifmaclabel(const char *val, int d, int s, const struct afswtch *rafp)
|
setifmaclabel(const char *val, int d, int s, const struct afswtch *rafp)
|
||||||
{
|
{
|
||||||
struct ifreq ifr;
|
struct ifreq ifr;
|
||||||
@ -98,3 +98,24 @@ setifmaclabel(const char *val, int d, int s, const struct afswtch *rafp)
|
|||||||
if (error == -1)
|
if (error == -1)
|
||||||
perror("setifmac");
|
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
|
||||||
|
}
|
||||||
|
@ -102,8 +102,8 @@ static struct ifmedia_type_to_subtype *get_toptype_ttos(int);
|
|||||||
static struct ifmedia_description *get_subtype_desc(int,
|
static struct ifmedia_description *get_subtype_desc(int,
|
||||||
struct ifmedia_type_to_subtype *ttos);
|
struct ifmedia_type_to_subtype *ttos);
|
||||||
|
|
||||||
void
|
static void
|
||||||
media_status(int s, struct rt_addrinfo *info __unused)
|
media_status(int s, const struct rt_addrinfo *info __unused)
|
||||||
{
|
{
|
||||||
struct ifmediareq ifmr;
|
struct ifmediareq ifmr;
|
||||||
int *media_list, i;
|
int *media_list, i;
|
||||||
@ -190,7 +190,7 @@ media_status(int s, struct rt_addrinfo *info __unused)
|
|||||||
free(media_list);
|
free(media_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
setmedia(const char *val, int d, int s, const struct afswtch *afp)
|
setmedia(const char *val, int d, int s, const struct afswtch *afp)
|
||||||
{
|
{
|
||||||
struct ifmediareq ifmr;
|
struct ifmediareq ifmr;
|
||||||
@ -232,14 +232,14 @@ setmedia(const char *val, int d, int s, const struct afswtch *afp)
|
|||||||
err(1, "SIOCSIFMEDIA (media)");
|
err(1, "SIOCSIFMEDIA (media)");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
setmediaopt(const char *val, int d, int s, const struct afswtch *afp)
|
setmediaopt(const char *val, int d, int s, const struct afswtch *afp)
|
||||||
{
|
{
|
||||||
|
|
||||||
domediaopt(val, 0, s);
|
domediaopt(val, 0, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
unsetmediaopt(const char *val, int d, int s, const struct afswtch *afp)
|
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)
|
setmediamode(const char *val, int d, int s, const struct afswtch *afp)
|
||||||
{
|
{
|
||||||
struct ifmediareq ifmr;
|
struct ifmediareq ifmr;
|
||||||
@ -777,3 +777,27 @@ print_media_word_ifconfig(int ifmw)
|
|||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* ...until here.
|
* ...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
|
||||||
|
}
|
||||||
|
@ -61,8 +61,8 @@ static const char rcsid[] =
|
|||||||
static int __tag = 0;
|
static int __tag = 0;
|
||||||
static int __have_tag = 0;
|
static int __have_tag = 0;
|
||||||
|
|
||||||
void
|
static void
|
||||||
vlan_status(int s, struct rt_addrinfo *info __unused)
|
vlan_status(int s, const struct rt_addrinfo *info __unused)
|
||||||
{
|
{
|
||||||
struct vlanreq vreq;
|
struct vlanreq vreq;
|
||||||
|
|
||||||
@ -79,7 +79,7 @@ vlan_status(int s, struct rt_addrinfo *info __unused)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
setvlantag(const char *val, int d, int s, const struct afswtch *afp)
|
setvlantag(const char *val, int d, int s, const struct afswtch *afp)
|
||||||
{
|
{
|
||||||
u_int16_t tag;
|
u_int16_t tag;
|
||||||
@ -102,7 +102,7 @@ setvlantag(const char *val, int d, int s, const struct afswtch *afp)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
setvlandev(const char *val, int d, int s, const struct afswtch *afp)
|
setvlandev(const char *val, int d, int s, const struct afswtch *afp)
|
||||||
{
|
{
|
||||||
struct vlanreq vreq;
|
struct vlanreq vreq;
|
||||||
@ -125,7 +125,7 @@ setvlandev(const char *val, int d, int s, const struct afswtch *afp)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
unsetvlandev(const char *val, int d, int s, const struct afswtch *afp)
|
unsetvlandev(const char *val, int d, int s, const struct afswtch *afp)
|
||||||
{
|
{
|
||||||
struct vlanreq vreq;
|
struct vlanreq vreq;
|
||||||
@ -144,3 +144,30 @@ unsetvlandev(const char *val, int d, int s, const struct afswtch *afp)
|
|||||||
|
|
||||||
return;
|
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
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user