diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 1995-10-18 08:53:40 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 1995-10-18 08:53:40 +0000 |
commit | d6583bb2a13f329cf0332ef2570eb8bb8fc0e39c (patch) | |
tree | ece253b876159b39c620e62b6c9b1174642e070e /sbin/ifconfig |
initial import of NetBSD tree
Diffstat (limited to 'sbin/ifconfig')
-rw-r--r-- | sbin/ifconfig/Makefile | 7 | ||||
-rw-r--r-- | sbin/ifconfig/ifconfig.8 | 284 | ||||
-rw-r--r-- | sbin/ifconfig/ifconfig.c | 796 |
3 files changed, 1087 insertions, 0 deletions
diff --git a/sbin/ifconfig/Makefile b/sbin/ifconfig/Makefile new file mode 100644 index 00000000000..cfc07b3fd2d --- /dev/null +++ b/sbin/ifconfig/Makefile @@ -0,0 +1,7 @@ +# $NetBSD: Makefile,v 1.7 1995/03/18 14:56:21 cgd Exp $ +# @(#)Makefile 8.1 (Berkeley) 6/5/93 + +PROG= ifconfig +MAN= ifconfig.8 + +.include <bsd.prog.mk> diff --git a/sbin/ifconfig/ifconfig.8 b/sbin/ifconfig/ifconfig.8 new file mode 100644 index 00000000000..4b11a6ff9ee --- /dev/null +++ b/sbin/ifconfig/ifconfig.8 @@ -0,0 +1,284 @@ +.\" $NetBSD: ifconfig.8,v 1.10 1995/03/18 14:56:23 cgd Exp $ +.\" +.\" Copyright (c) 1983, 1991, 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. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 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. +.\" +.\" @(#)ifconfig.8 8.3 (Berkeley) 1/5/94 +.\" +.Dd January 5, 1994 +.Dt IFCONFIG 8 +.Os BSD 4.2 +.Sh NAME +.Nm ifconfig +.Nd configure network interface parameters +.Sh SYNOPSIS +.Nm ifconfig +.Ar interface address_family +.Oo +.Ar address +.Op Ar dest_address +.Oc +.Op Ar parameters +.Nm ifconfig +.Ar interface +.Op Ar protocol_family +.Sh DESCRIPTION +.Nm Ifconfig +is used to assign an address +to a network interface and/or configure +network interface parameters. +.Nm Ifconfig +must be used at boot time to define the network address +of each interface present on a machine; it may also be used at +a later time to redefine an interface's address +or other operating parameters. +.Pp +Available operands for +.Nm ifconfig: +.Bl -tag -width Ds +.It Ar Address +For the +.Tn DARPA-Internet +family, +the address is either a host name present in the host name data +base, +.Xr hosts 5 , +or a +.Tn DARPA +Internet address expressed in the Internet standard +.Dq dot notation . +For the Xerox Network Systems(tm) family, +addresses are +.Ar net:a.b.c.d.e.f , +where +.Ar net +is the assigned network number (in decimal), +and each of the six bytes of the host number, +.Ar a +through +.Ar f , +are specified in hexadecimal. +The host number may be omitted on 10Mb/s Ethernet interfaces, +which use the hardware physical address, +and on interfaces other than the first. +For the +.Tn ISO +family, addresses are specified as a long hexadecimal string, +as in the Xerox family. However, two consecutive dots imply a zero +byte, and the dots are optional, if the user wishes to (carefully) +count out long strings of digits in network byte order. +.It Ar address_family +Specifies the +.Ar address family +which affects interpretation of the remaining parameters. +Since an interface can receive transmissions in differing protocols +with different naming schemes, specifying the address family is recommended. +The address or protocol families currently +supported are +.Dq inet , +.Dq iso , +and +.Dq ns . +.It Ar Interface +The +.Ar interface +parameter is a string of the form +.Dq name unit , +for example, +.Dq en0 +.El +.Pp +The following parameters may be set with +.Nm ifconfig : +.Bl -tag -width dest_addressxx +.It Cm alias +Establish an additional network address for this interface. +This is sometimes useful when changing network numbers, and +one wishes to accept packets addressed to the old interface. +.It Cm arp +Enable the use of the Address Resolution Protocol in mapping +between network level addresses and link level addresses (default). +This is currently implemented for mapping between +.Tn DARPA +Internet +addresses and 10Mb/s Ethernet addresses. +.It Fl arp +Disable the use of the Address Resolution Protocol. +.It Cm broadcast +(Inet only) +Specify the address to use to represent broadcasts to the +network. +The default broadcast address is the address with a host part of all 1's. +.It Cm debug +Enable driver dependent debugging code; usually, this turns on +extra console error logging. +.It Fl debug +Disable driver dependent debugging code. +.It Cm delete +Remove the network address specified. +This would be used if you incorrectly specified an alias, or it +was no longer needed. +If you have incorrectly set an NS address having the side effect +of specifying the host portion, removing all NS addresses will +allow you to respecify the host portion. +.It Cm dest_address +Specify the address of the correspondent on the other end +of a point to point link. +.It Cm down +Mark an interface ``down''. When an interface is +marked ``down'', the system will not attempt to +transmit messages through that interface. +If possible, the interface will be reset to disable reception as well. +This action does not automatically disable routes using the interface. +.It Cm ipdst +This is used to specify an Internet host who is willing to receive +ip packets encapsulating NS packets bound for a remote network. +An apparent point to point link is constructed, and +the address specified will be taken as the NS address and network +of the destination. +IP encapsulation of +.Tn CLNP +packets is done differently. +.It Cm metric Ar n +Set the routing metric of the interface to +.Ar n , +default 0. +The routing metric is used by the routing protocol +.Pq Xr routed 8 . +Higher metrics have the effect of making a route +less favorable; metrics are counted as addition hops +to the destination network or host. +.It Cm netmask Ar mask +(Inet and ISO) +Specify how much of the address to reserve for subdividing +networks into sub-networks. +The mask includes the network part of the local address +and the subnet part, which is taken from the host field of the address. +The mask can be specified as a single hexadecimal number +with a leading 0x, with a dot-notation Internet address, +or with a pseudo-network name listed in the network table +.Xr networks 5 . +The mask contains 1's for the bit positions in the 32-bit address +which are to be used for the network and subnet parts, +and 0's for the host part. +The mask should contain at least the standard network portion, +and the subnet field should be contiguous with the network +portion. +.\" see +.\" Xr eon 5 . +.It Cm nsellength Ar n +.Pf ( Tn ISO +only) +This specifies a trailing number of bytes for a received +.Tn NSAP +used for local identification, the remaining leading part of which is +taken to be the +.Tn NET +(Network Entity Title). +The default value is 1, which is conformant to US +.Tn GOSIP . +When an ISO address is set in an ifconfig command, +it is really the +.Tn NSAP +which is being specified. +For example, in +.Tn US GOSIP , +20 hex digits should be +specified in the +.Tn ISO NSAP +to be assigned to the interface. +There is some evidence that a number different from 1 may be useful +for +.Tn AFI +37 type addresses. +.It Cm trailers +Request the use of a ``trailer'' link level encapsulation when +sending (default). +If a network interface supports +.Cm trailers , +the system will, when possible, encapsulate outgoing +messages in a manner which minimizes the number of +memory to memory copy operations performed by the receiver. +On networks that support the Address Resolution Protocol (see +.Xr arp 4 ; +currently, only 10 Mb/s Ethernet), +this flag indicates that the system should request that other +systems use trailers when sending to this host. +Similarly, trailer encapsulations will be sent to other +hosts that have made such requests. +Currently used by Internet protocols only. +.It Fl trailers +Disable the use of a ``trailer'' link level encapsulation. +.It Cm link[0-2] +Enable special processing of the link level of the interface. +These three options are interface specific in actual effect, however, +they are in general used to select special modes of operation. An example +of this is to enable SLIP compression, or to select the connector type +for some ethernet cards. Refer to the man page for the specific driver +for more information. +.It Fl link[0-2] +Disable special processing at the link level with the specified interface. +.It Cm up +Mark an interface ``up''. +This may be used to enable an interface after an ``ifconfig down.'' +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. +.El +.Pp +.Pp +.Nm Ifconfig +displays the current configuration for a network interface +when no optional parameters are supplied. +If a protocol family is specified, +Ifconfig will report only the details specific to that protocol family. +.Pp +The interface name +.Ar -a +is reserved, and causes information on all interfaces to be displayed. +The protocol family may be specified as well. +.Pp +Only the super-user may modify the configuration of a network interface. +.Sh DIAGNOSTICS +Messages indicating the specified interface does not exit, the +requested address is unknown, or the user is not privileged and +tried to alter an interface's configuration. +.Sh SEE ALSO +.Xr netstat 1 , +.Xr netintro 4 , +.Xr rc 8 , +.Xr routed 8 , +.\" .Xr eon 5 +.Sh HISTORY +The +.Nm +command appeared in +.Bx 4.2 . diff --git a/sbin/ifconfig/ifconfig.c b/sbin/ifconfig/ifconfig.c new file mode 100644 index 00000000000..083568e85d9 --- /dev/null +++ b/sbin/ifconfig/ifconfig.c @@ -0,0 +1,796 @@ +/* $NetBSD: ifconfig.c,v 1.21 1995/10/08 23:03:54 gwr Exp $ */ + +/* + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 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 char copyright[] = +"@(#) Copyright (c) 1983, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +#if 0 +static char sccsid[] = "@(#)ifconfig.c 8.2 (Berkeley) 2/16/94"; +#else +static char rcsid[] = "$NetBSD: ifconfig.c,v 1.21 1995/10/08 23:03:54 gwr Exp $"; +#endif +#endif /* not lint */ + +#include <sys/param.h> +#include <sys/socket.h> +#include <sys/ioctl.h> + +#include <net/if.h> +#include <netinet/in.h> +#include <arpa/inet.h> + +#define NSIP +#include <netns/ns.h> +#include <netns/ns_if.h> +#include <netdb.h> + +#define EON +#include <netiso/iso.h> +#include <netiso/iso_var.h> +#include <sys/protosw.h> + +#include <ctype.h> +#include <err.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +struct ifreq ifr, ridreq; +struct ifaliasreq addreq; +struct iso_ifreq iso_ridreq; +struct iso_aliasreq iso_addreq; +struct sockaddr_in netmask; +char name[30]; +int flags, metric, setaddr, setipdst, doalias; +int clearaddr, s; +int newaddr = 1; +int nsellength = 1; +int af = AF_INET; + +void notealias __P((char *, int)); +void notrailers __P((char *, int)); +void setifaddr __P((char *, int)); +void setifdstaddr __P((char *, int)); +void setifflags __P((char *, int)); +void setifbroadaddr __P((char *)); +void setifipdst __P((char *)); +void setifmetric __P((char *)); +void setifnetmask __P((char *)); +void setnsellength __P((char *)); +void setsnpaoffset __P((char *)); + +#define NEXTARG 0xffffff + +struct cmd { + char *c_name; + int c_parameter; /* NEXTARG means next argv */ + void (*c_func)(); +} cmds[] = { + { "up", IFF_UP, setifflags } , + { "down", -IFF_UP, setifflags }, + { "trailers", -1, notrailers }, + { "-trailers", 1, notrailers }, + { "arp", -IFF_NOARP, setifflags }, + { "-arp", IFF_NOARP, setifflags }, + { "debug", IFF_DEBUG, setifflags }, + { "-debug", -IFF_DEBUG, setifflags }, + { "alias", IFF_UP, notealias }, + { "-alias", -IFF_UP, notealias }, + { "delete", -IFF_UP, notealias }, +#ifdef notdef +#define EN_SWABIPS 0x1000 + { "swabips", EN_SWABIPS, setifflags }, + { "-swabips", -EN_SWABIPS, setifflags }, +#endif + { "netmask", NEXTARG, setifnetmask }, + { "metric", NEXTARG, setifmetric }, + { "broadcast", NEXTARG, setifbroadaddr }, + { "ipdst", NEXTARG, setifipdst }, +#ifndef INET_ONLY + { "snpaoffset", NEXTARG, setsnpaoffset }, + { "nsellength", NEXTARG, setnsellength }, +#endif /* INET_ONLY */ + { "link0", IFF_LINK0, setifflags } , + { "-link0", -IFF_LINK0, setifflags } , + { "link1", IFF_LINK1, setifflags } , + { "-link1", -IFF_LINK1, setifflags } , + { "link2", IFF_LINK2, setifflags } , + { "-link2", -IFF_LINK2, setifflags } , + { 0, 0, setifaddr }, + { 0, 0, setifdstaddr }, +}; + +void adjust_nsellength(); +int getinfo __P((struct ifreq *)); +void getsock __P((int)); +void printall __P((void)); +void printb __P((char *, unsigned short, char *)); +void status(); +void usage(); + +/* + * XNS support liberally adapted from code written at the University of + * Maryland principally by James O'Toole and Chris Torek. + */ +void in_status __P((int)); +void in_getaddr __P((char *, int)); +void xns_status __P((int)); +void xns_getaddr __P((char *, int)); +void iso_status __P((int)); +void iso_getaddr __P((char *, int)); + +/* Known address families */ +struct afswtch { + char *af_name; + short af_af; + void (*af_status)(); + void (*af_getaddr)(); + u_long af_difaddr; + u_long af_aifaddr; + caddr_t af_ridreq; + caddr_t af_addreq; +} afs[] = { +#define C(x) ((caddr_t) &x) + { "inet", AF_INET, in_status, in_getaddr, + SIOCDIFADDR, SIOCAIFADDR, C(ridreq), C(addreq) }, +#ifndef INET_ONLY /* small version, for boot media */ + { "ns", AF_NS, xns_status, xns_getaddr, + SIOCDIFADDR, SIOCAIFADDR, C(ridreq), C(addreq) }, + { "iso", AF_ISO, iso_status, iso_getaddr, + SIOCDIFADDR_ISO, SIOCAIFADDR_ISO, C(iso_ridreq), C(iso_addreq) }, +#endif /* INET_ONLY */ + { 0, 0, 0, 0 } +}; + +struct afswtch *afp; /*the address family being set or asked about*/ + +int +main(argc, argv) + int argc; + char *argv[]; +{ + register struct afswtch *rafp; + int aflag = 0; + + if (argc < 2) + usage(); + argc--, argv++; + if (!strcmp(*argv, "-a")) + aflag = 1; + else + strncpy(name, *argv, sizeof(name)); + argc--, argv++; + if (argc > 0) { + for (afp = rafp = afs; rafp->af_name; rafp++) + if (strcmp(rafp->af_name, *argv) == 0) { + afp = rafp; argc--; argv++; + break; + } + rafp = afp; + af = ifr.ifr_addr.sa_family = rafp->af_af; + } + if (aflag) { + if (argc > 0) + usage(); + printall(); + exit(0); + } + strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); + if (getinfo(&ifr) < 0) + exit(1); + if (argc == 0) { + status(); + exit(0); + } + while (argc > 0) { + register struct cmd *p; + + for (p = cmds; p->c_name; p++) + if (strcmp(*argv, p->c_name) == 0) + break; + if (p->c_name == 0 && setaddr) + p++; /* got src, do dst */ + if (p->c_func) { + if (p->c_parameter == NEXTARG) { + if (argv[1] == NULL) + errx(1, "'%s' requires argument", + p->c_name); + (*p->c_func)(argv[1]); + argc--, argv++; + } else + (*p->c_func)(*argv, p->c_parameter); + } + argc--, argv++; + } + +#ifndef INET_ONLY + + if (af == AF_ISO) + adjust_nsellength(); + if (setipdst && af==AF_NS) { + struct nsip_req rq; + int size = sizeof(rq); + + rq.rq_ns = addreq.ifra_addr; + rq.rq_ip = addreq.ifra_dstaddr; + + if (setsockopt(s, 0, SO_NSIP_ROUTE, &rq, size) < 0) + warn("encapsulation routing"); + } + +#endif /* INET_ONLY */ + + if (clearaddr) { + int ret; + strncpy(rafp->af_ridreq, name, sizeof ifr.ifr_name); + if ((ret = ioctl(s, rafp->af_difaddr, rafp->af_ridreq)) < 0) { + if (errno == EADDRNOTAVAIL && (doalias >= 0)) { + /* means no previous address for interface */ + } else + warn("SIOCDIFADDR"); + } + } + if (newaddr) { + strncpy(rafp->af_addreq, name, sizeof ifr.ifr_name); + if (ioctl(s, rafp->af_aifaddr, rafp->af_addreq) < 0) + warn("SIOCAIFADDR"); + } + exit(0); +} + +void +getsock(naf) + int naf; +{ + static int oaf = -1; + + if (oaf == naf) + return; + if (oaf != -1) + close(s); + s = socket(naf, SOCK_DGRAM, 0); + if (s < 0) + oaf = -1; + else + oaf = naf; +} + +int +getinfo(ifr) + struct ifreq *ifr; +{ + + getsock(af); + if (s < 0) + err(1, "socket"); + if (ioctl(s, SIOCGIFFLAGS, (caddr_t)ifr) < 0) { + warn("SIOCGIFFLAGS"); + return (-1); + } + flags = ifr->ifr_flags; + if (ioctl(s, SIOCGIFMETRIC, (caddr_t)ifr) < 0) { + warn("SIOCGIFMETRIC"); + metric = 0; + } else + metric = ifr->ifr_metric; + return (0); +} + +void +printall() +{ + char inbuf[8192]; + struct ifconf ifc; + struct ifreq ifreq, *ifr; + int i; + + ifc.ifc_len = sizeof(inbuf); + ifc.ifc_buf = inbuf; + getsock(af); + if (s < 0) + err(1, "socket"); + if (ioctl(s, SIOCGIFCONF, &ifc) < 0) + err(1, "SIOCGIFCONF"); + ifr = ifc.ifc_req; + ifreq.ifr_name[0] = '\0'; + for (i = 0; i < ifc.ifc_len; ) { + ifr = (struct ifreq *)((caddr_t)ifc.ifc_req + i); + i += sizeof(ifr->ifr_name) + ifr->ifr_addr.sa_len; + if (!strncmp(ifreq.ifr_name, ifr->ifr_name, + sizeof(ifr->ifr_name))) + continue; + strncpy(name, ifr->ifr_name, sizeof(ifr->ifr_name)); + ifreq = *ifr; + if (getinfo(&ifreq) < 0) + continue; + status(); + } +} + +#define RIDADDR 0 +#define ADDR 1 +#define MASK 2 +#define DSTADDR 3 + +/*ARGSUSED*/ +void +setifaddr(addr, param) + char *addr; + int param; +{ + /* + * Delay the ioctl to set the interface addr until flags are all set. + * The address interpretation may depend on the flags, + * and the flags may change when the address is set. + */ + setaddr++; + if (doalias == 0) + clearaddr = 1; + (*afp->af_getaddr)(addr, (doalias >= 0 ? ADDR : RIDADDR)); +} + +void +setifnetmask(addr) + char *addr; +{ + (*afp->af_getaddr)(addr, MASK); +} + +void +setifbroadaddr(addr) + char *addr; +{ + (*afp->af_getaddr)(addr, DSTADDR); +} + +void +setifipdst(addr) + char *addr; +{ + in_getaddr(addr, DSTADDR); + setipdst++; + clearaddr = 0; + newaddr = 0; +} + +#define rqtosa(x) (&(((struct ifreq *)(afp->x))->ifr_addr)) +/*ARGSUSED*/ +void +notealias(addr, param) + char *addr; + int param; +{ + if (setaddr && doalias == 0 && param < 0) + memcpy(rqtosa(af_ridreq), + rqtosa(af_addreq), + rqtosa(af_addreq)->sa_len); + doalias = param; + if (param < 0) { + clearaddr = 1; + newaddr = 0; + } else + clearaddr = 0; +} + +/*ARGSUSED*/ +void +notrailers(vname, value) + char *vname; + int value; +{ + printf("Note: trailers are no longer sent, but always received\n"); +} + +/*ARGSUSED*/ +void +setifdstaddr(addr, param) + char *addr; + int param; +{ + (*afp->af_getaddr)(addr, DSTADDR); +} + +void +setifflags(vname, value) + char *vname; + int value; +{ + if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) + err(1, "SIOCGIFFLAGS"); + strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name)); + flags = ifr.ifr_flags; + + if (value < 0) { + value = -value; + flags &= ~value; + } else + flags |= value; + ifr.ifr_flags = flags; + if (ioctl(s, SIOCSIFFLAGS, (caddr_t)&ifr) < 0) + err(1, "SIOCSIFFLAGS"); +} + +void +setifmetric(val) + char *val; +{ + strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name)); + ifr.ifr_metric = atoi(val); + if (ioctl(s, SIOCSIFMETRIC, (caddr_t)&ifr) < 0) + warn("SIOCSIFMETRIC"); +} + +#define IFFBITS \ +"\020\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5POINTOPOINT\6NOTRAILERS\7RUNNING\10NOARP\ +\11PROMISC\12ALLMULTI\13OACTIVE\14SIMPLEX\15LINK0\16LINK1\17LINK2\20MULTICAST" + +/* + * Print the status of the interface. If an address family was + * specified, show it and it only; otherwise, show them all. + */ +void +status() +{ + register struct afswtch *p = afp; + + printf("%s: ", name); + printb("flags", flags, IFFBITS); + if (metric) + printf(" metric %d", metric); + putchar('\n'); + if ((p = afp) != NULL) { + (*p->af_status)(1); + } else for (p = afs; p->af_name; p++) { + ifr.ifr_addr.sa_family = p->af_af; + (*p->af_status)(0); + } +} + +void +in_status(force) + int force; +{ + struct sockaddr_in *sin; + char *inet_ntoa(); + + getsock(AF_INET); + if (s < 0) { + if (errno == EPROTONOSUPPORT) + return; + err(1, "socket"); + } + memset(&ifr, 0, sizeof(ifr)); + strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); + if (ioctl(s, SIOCGIFADDR, (caddr_t)&ifr) < 0) { + if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT) { + if (!force) + return; + memset(&ifr.ifr_addr, 0, sizeof(ifr.ifr_addr)); + } else + warn("SIOCGIFADDR"); + } + strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name)); + sin = (struct sockaddr_in *)&ifr.ifr_addr; + printf("\tinet %s ", inet_ntoa(sin->sin_addr)); + strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name)); + if (ioctl(s, SIOCGIFNETMASK, (caddr_t)&ifr) < 0) { + if (errno != EADDRNOTAVAIL) + warn("SIOCGIFNETMASK"); + memset(&ifr.ifr_addr, 0, sizeof(ifr.ifr_addr)); + } else + netmask.sin_addr = + ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr; + if (flags & IFF_POINTOPOINT) { + if (ioctl(s, SIOCGIFDSTADDR, (caddr_t)&ifr) < 0) { + if (errno == EADDRNOTAVAIL) + memset(&ifr.ifr_addr, 0, sizeof(ifr.ifr_addr)); + else + warn("SIOCGIFDSTADDR"); + } + strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name)); + sin = (struct sockaddr_in *)&ifr.ifr_dstaddr; + printf("--> %s ", inet_ntoa(sin->sin_addr)); + } + printf("netmask 0x%x ", ntohl(netmask.sin_addr.s_addr)); + if (flags & IFF_BROADCAST) { + if (ioctl(s, SIOCGIFBRDADDR, (caddr_t)&ifr) < 0) { + if (errno == EADDRNOTAVAIL) + memset(&ifr.ifr_addr, 0, sizeof(ifr.ifr_addr)); + else + warn("SIOCGIFBRDADDR"); + } + strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name)); + sin = (struct sockaddr_in *)&ifr.ifr_addr; + if (sin->sin_addr.s_addr != 0) + printf("broadcast %s", inet_ntoa(sin->sin_addr)); + } + putchar('\n'); +} + +#ifndef INET_ONLY + +void +xns_status(force) + int force; +{ + struct sockaddr_ns *sns; + + getsock(AF_NS); + if (s < 0) { + if (errno == EPROTONOSUPPORT) + return; + err(1, "socket"); + } + memset(&ifr, 0, sizeof(ifr)); + strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); + if (ioctl(s, SIOCGIFADDR, (caddr_t)&ifr) < 0) { + if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT) { + if (!force) + return; + memset(&ifr.ifr_addr, 0, sizeof(ifr.ifr_addr)); + } else + warn("SIOCGIFADDR"); + } + strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name); + sns = (struct sockaddr_ns *)&ifr.ifr_addr; + printf("\tns %s ", ns_ntoa(sns->sns_addr)); + if (flags & IFF_POINTOPOINT) { /* by W. Nesheim@Cornell */ + if (ioctl(s, SIOCGIFDSTADDR, (caddr_t)&ifr) < 0) { + if (errno == EADDRNOTAVAIL) + memset(&ifr.ifr_addr, 0, sizeof(ifr.ifr_addr)); + else + warn("SIOCGIFDSTADDR"); + } + strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name)); + sns = (struct sockaddr_ns *)&ifr.ifr_dstaddr; + printf("--> %s ", ns_ntoa(sns->sns_addr)); + } + putchar('\n'); +} + +void +iso_status(force) + int force; +{ + struct sockaddr_iso *siso; + struct iso_ifreq ifr; + + getsock(AF_ISO); + if (s < 0) { + if (errno == EPROTONOSUPPORT) + return; + err(1, "socket"); + } + memset(&ifr, 0, sizeof(ifr)); + strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); + if (ioctl(s, SIOCGIFADDR_ISO, (caddr_t)&ifr) < 0) { + if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT) { + if (!force) + return; + memset(&ifr.ifr_Addr, 0, sizeof(ifr.ifr_Addr)); + } else + warn("SIOCGIFADDR_ISO"); + } + strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name); + siso = &ifr.ifr_Addr; + printf("\tiso %s ", iso_ntoa(&siso->siso_addr)); + if (ioctl(s, SIOCGIFNETMASK_ISO, (caddr_t)&ifr) < 0) { + if (errno == EADDRNOTAVAIL) + memset(&ifr.ifr_Addr, 0, sizeof(ifr.ifr_Addr)); + else + warn("SIOCGIFNETMASK_ISO"); + } else { + printf(" netmask %s ", iso_ntoa(&siso->siso_addr)); + } + if (flags & IFF_POINTOPOINT) { + if (ioctl(s, SIOCGIFDSTADDR_ISO, (caddr_t)&ifr) < 0) { + if (errno == EADDRNOTAVAIL) + memset(&ifr.ifr_Addr, 0, sizeof(ifr.ifr_Addr)); + else + warn("SIOCGIFDSTADDR_ISO"); + } + strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name)); + siso = &ifr.ifr_Addr; + printf("--> %s ", iso_ntoa(&siso->siso_addr)); + } + putchar('\n'); +} + +#endif /* INET_ONLY */ + +struct in_addr inet_makeaddr(); + +#define SIN(x) ((struct sockaddr_in *) &(x)) +struct sockaddr_in *sintab[] = { +SIN(ridreq.ifr_addr), SIN(addreq.ifra_addr), +SIN(addreq.ifra_mask), SIN(addreq.ifra_broadaddr)}; + +void +in_getaddr(s, which) + char *s; + int which; +{ + register 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 (inet_aton(s, &sin->sin_addr) == 0) { + if (hp = gethostbyname(s)) + memcpy(&sin->sin_addr, hp->h_addr, hp->h_length); + else if (np = getnetbyname(s)) + sin->sin_addr = inet_makeaddr(np->n_net, INADDR_ANY); + else + errx(1, "%s: bad value", s); + } +} + +/* + * Print a value a la the %b format of the kernel's printf + */ +void +printb(s, v, bits) + char *s; + register char *bits; + register unsigned short v; +{ + register int i, any = 0; + register char c; + + if (bits && *bits == 8) + printf("%s=%o", s, v); + else + printf("%s=%x", s, v); + bits++; + if (bits) { + putchar('<'); + while (i = *bits++) { + if (v & (1 << (i-1))) { + if (any) + putchar(','); + any = 1; + for (; (c = *bits) > 32; bits++) + putchar(c); + } else + for (; *bits > 32; bits++) + ; + } + putchar('>'); + } +} + +#ifndef INET_ONLY + +#define SNS(x) ((struct sockaddr_ns *) &(x)) +struct sockaddr_ns *snstab[] = { +SNS(ridreq.ifr_addr), SNS(addreq.ifra_addr), +SNS(addreq.ifra_mask), SNS(addreq.ifra_broadaddr)}; + +void +xns_getaddr(addr, which) + char *addr; + int which; +{ + struct sockaddr_ns *sns = snstab[which]; + struct ns_addr ns_addr(); + + sns->sns_family = AF_NS; + sns->sns_len = sizeof(*sns); + sns->sns_addr = ns_addr(addr); + if (which == MASK) + printf("Attempt to set XNS netmask will be ineffectual\n"); +} + +#define SISO(x) ((struct sockaddr_iso *) &(x)) +struct sockaddr_iso *sisotab[] = { +SISO(iso_ridreq.ifr_Addr), SISO(iso_addreq.ifra_addr), +SISO(iso_addreq.ifra_mask), SISO(iso_addreq.ifra_dstaddr)}; + +void +iso_getaddr(addr, which) + char *addr; + int which; +{ + register struct sockaddr_iso *siso = sisotab[which]; + struct iso_addr *iso_addr(); + siso->siso_addr = *iso_addr(addr); + + if (which == MASK) { + siso->siso_len = TSEL(siso) - (caddr_t)(siso); + siso->siso_nlen = 0; + } else { + siso->siso_len = sizeof(*siso); + siso->siso_family = AF_ISO; + } +} + +void +setsnpaoffset(val) + char *val; +{ + iso_addreq.ifra_snpaoffset = atoi(val); +} + +void +setnsellength(val) + char *val; +{ + nsellength = atoi(val); + if (nsellength < 0) + errx(1, "Negative NSEL length is absurd"); + if (afp == 0 || afp->af_af != AF_ISO) + errx(1, "Setting NSEL length valid only for iso"); +} + +void +fixnsel(s) + register struct sockaddr_iso *s; +{ + if (s->siso_family == 0) + return; + s->siso_tlen = nsellength; +} + +void +adjust_nsellength() +{ + fixnsel(sisotab[RIDADDR]); + fixnsel(sisotab[ADDR]); + fixnsel(sisotab[DSTADDR]); +} + +#endif /* INET_ONLY */ + +void +usage() +{ + fprintf(stderr, "usage: ifconfig interface\n%s%s%s%s%s%s", + "\t[ af [ address [ dest_addr ] ] [ up ] [ down ] ", + "[ netmask mask ] ]\n", + "\t[ metric n ]\n", + "\t[ arp | -arp ]\n", + "\t[ link0 | -link0 ] [ link1 | -link1 ] [ link2 | -link2 ]\n", + " ifconfig -a [ af ]\n"); + exit(1); +} |