Date: Fri, 30 Dec 1994 02:32:47 -0500 From: Wankle Rotary Engine <wpaul@skynet.ctr.columbia.edu> To: freebsd-hackers@freebsd.org Subject: You want ifconfig -a? You got ifconfig -a. Message-ID: <199412300732.CAA03841@skynet.ctr.columbia.edu>
next in thread | raw e-mail | index | archive | help
Okay Jordan: you asked for it, you got it. Enclosed is a patch for
/usr/src/sbin/ifconfig.c in FreeBSD 2.0 to add the following features:
- The -a flag now works just as it does in SunOS: '-a' is actually
handled like a wildcard for all interfaces. 'ifconfig -a' displays
the status of all interfaces, 'ifconfig -a netmask 0xffffff00' sets
the netmask of all interfaces, and so forth. I don't know if many
people really need to be able to set the netmasks of all interfaces
at once, but the SunOS ifconfig seems to allow this, so there you
have it.
- An 'ether_status' function has been added to display the ethernet
address of all ethernet interfaces. Again, as in SunOS, you must
be root in order for this to work. The ethernet address is read
from /dev/kmem using kvm_open() and kvm_read(), much in the same
was as it's done with netstat. If you choose to install ifconfig
set-gid kmem then normal users will be able to see the ethernet
address as well, though this may not be desireable. This feature
requires a small change to the ifconfig Makefile: you need to link
with -lkvm in order to use the kvm_*() functions.
Here's some sample output on a machine with two ethernet cards, two
SLIP interfaces, two PPP interfaces, and the parallel port IP interface:
# ifconfig -a
ed0: flags=8822<BROADCAST,NOTRAILERS,SIMPLEX,MULTICAST> mtu 1500
ether 02:60:8c:a8:27:da
ed1: flags=8863<UP,BROADCAST,NOTRAILERS,RUNNING,SIMPLEX,MULTICAST> mtu 1500
inet 128.59.64.56 netmask 0xffffff00 broadcast 128.59.64.255
ether 02:60:8c:3f:34:65
lp0: flags=810<POINTOPOINT,SIMPLEX> mtu 1500
lo0: flags=8009<UP,LOOPBACK,MULTICAST> mtu 65532
inet 127.0.0.1 netmask 0xff000000
ppp0: flags=10<POINTOPOINT> mtu 1500
ppp1: flags=10<POINTOPOINT> mtu 1500
sl0: flags=8010<POINTOPOINT,MULTICAST> mtu 552
sl1: flags=8010<POINTOPOINT,MULTICAST> mtu 552
#
The interfaces are displayed in the order in which SIOCGIFCONF returns them.
Share and enjoy!
-Bill
PS: Jordan, I'll be sending some other stuff your way inder seperate
cover. :)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Bill Paul System Manager
wpaul@ctr.columbia.edu Center for Telecommunications Research
(212) 854-6020 Columbia University, New York City
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The Møøse Illuminati: ignore it and be confused, or join it and be confusing!
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*** Makefile.orig Thu Dec 29 21:45:13 1994
--- Makefile Thu Dec 29 20:17:11 1994
***************
*** 2,6 ****
--- 2,8 ----
PROG= ifconfig
MAN8= ifconfig.8
+ LDADD= -lkvm
+ DPADD= ${LIBKVM}
.include <bsd.prog.mk>
*** ifconfig.c.orig Fri Dec 30 01:53:29 1994
--- ifconfig.c Fri Dec 30 02:01:23 1994
***************
*** 46,52 ****
--- 46,54 ----
#include <sys/ioctl.h>
#include <net/if.h>
+ #include <net/if_dl.h>
#include <netinet/in.h>
+ #include <netinet/in_var.h>
#include <arpa/inet.h>
#define NSIP
***************
*** 66,71 ****
--- 68,76 ----
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+ #include <nlist.h>
+ #include <kvm.h>
+ #include <fcntl.h>
struct ifreq ifr, ridreq;
struct ifaliasreq addreq;
***************
*** 84,89 ****
--- 89,95 ----
int clearaddr;
int newaddr = 1;
int s;
+ kvm_t *kvmd;
extern int errno;
int setifflags(), setifaddr(), setifdstaddr(), setifnetmask();
***************
*** 140,145 ****
--- 146,152 ----
int in_status(), in_getaddr();
int xns_status(), xns_getaddr();
int iso_status(), iso_getaddr();
+ int ether_status();
/* Known address families */
struct afswtch {
***************
*** 159,164 ****
--- 166,172 ----
SIOCDIFADDR, SIOCAIFADDR, C(ridreq), C(addreq) },
{ "iso", AF_ISO, iso_status, iso_getaddr,
SIOCDIFADDR_ISO, SIOCAIFADDR_ISO, C(iso_ridreq), C(iso_addreq) },
+ { "ether", AF_INET, ether_status, NULL },
{ 0, 0, 0, 0 }
};
***************
*** 199,204 ****
--- 207,259 ----
perror("ifconfig: socket");
exit(1);
}
+ if (!strcmp(name, "-a")) {
+ struct ifconf ifc;
+ #define MAX_INTERFACES 50 /* Yeah right. */
+ char buffer[MAX_INTERFACES * sizeof(struct ifreq)];
+ struct ifreq *ifptr, *end;
+ int ifflags;
+
+ ifc.ifc_len = sizeof(buffer);
+ ifc.ifc_buf = buffer;
+ if (ioctl(s, SIOCGIFCONF, (char *) &ifc) < 0) {
+ perror("ifconfig (SIOCGIFCONF)");
+ exit (1);
+ }
+ ifflags = ifc.ifc_req->ifr_flags;
+ end = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
+ ifptr = ifc.ifc_req;
+ while (ifptr < end) {
+ sprintf(ifr.ifr_name,"%s",ifptr->ifr_name);
+ sprintf(name,"%s",ifptr->ifr_name);
+ close(s);
+ s = socket(af, SOCK_DGRAM, 0);
+ if (s < 0) {
+ perror("ifconfig: socket");
+ exit(1);
+ }
+ if (ifptr->ifr_flags == ifflags)
+ ifconfig(argc,argv,af,rafp);
+ if(ifptr->ifr_addr.sa_len) /* Dohw! */
+ ifptr = (struct ifreq *) ((caddr_t) ifptr +
+ ifptr->ifr_addr.sa_len -
+ sizeof(struct sockaddr));
+ ifptr++;
+ }
+ } else
+ ifconfig(argc,argv,af,rafp);
+
+ exit (0);
+ }
+
+
+
+ ifconfig(argc,argv,af,rafp)
+ int argc;
+ char *argv[];
+ int af;
+ struct afswtch *rafp;
+ {
if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) {
Perror("ioctl (SIOCGIFFLAGS)");
exit(1);
***************
*** 213,221 ****
perror("ioctl (SIOCGIFMTU)");
else
mtu = ifr.ifr_mtu;
! if (argc == 0) {
status();
! exit(0);
}
while (argc > 0) {
register struct cmd *p;
--- 268,276 ----
perror("ioctl (SIOCGIFMTU)");
else
mtu = ifr.ifr_mtu;
! if (argc == 0) {
status();
! return(0);
}
while (argc > 0) {
register struct cmd *p;
***************
*** 264,270 ****
if (ioctl(s, rafp->af_aifaddr, rafp->af_addreq) < 0)
Perror("ioctl (SIOCAIFADDR)");
}
! exit(0);
}
#define RIDADDR 0
#define ADDR 1
--- 319,325 ----
if (ioctl(s, rafp->af_aifaddr, rafp->af_addreq) < 0)
Perror("ioctl (SIOCAIFADDR)");
}
! return(0);
}
#define RIDADDR 0
#define ADDR 1
***************
*** 553,558 ****
--- 608,697 ----
putchar('\n');
}
+ kread(addr, buf, size)
+ u_long addr;
+ char *buf;
+ int size;
+ {
+
+ if (kvm_read(kvmd, addr, buf, size) != size)
+ return (-1);
+ return (0);
+ }
+
+ /* Unashamedly stolen from netstat -- maybe someday we can us sysctl() */
+ ether_status()
+ {
+ struct nlist nl[] = { { "_ifnet" } , "" };
+ u_long addr, addr2;
+ struct ifnet ifnet;
+ union {
+ struct ifaddr ifa;
+ struct in_ifaddr in;
+ struct ns_ifaddr ns;
+ struct iso_ifaddr iso;
+ } ifaddr;
+ char *cp;
+ struct sockaddr *sa;
+ struct sockaddr_dl *sdl;
+ int n,m;
+ char ifacename[IFNAMSIZ];
+
+ /*
+ * If we fail here it probably means we don't have permission to
+ * read /dev/kmem. Best to just silently bail out. If we have
+ * an error *after* we succeed in opening /dev/kmem, then we
+ * should report it.
+ */
+ if ((kvmd = kvm_open(NULL,NULL,NULL,O_RDONLY,NULL)) == NULL)
+ return;
+ if (kvm_nlist(kvmd, nl) < 0 || nl[0].n_type == 0) {
+ perror("ifconfig: kvm_nlist()");
+ return;
+ }
+ if (kread(nl[0].n_value, (char *)&addr, sizeof(addr))) {
+ perror("_ifnet");
+ return;
+ }
+ addr2 = 0;
+ while (addr || addr2) {
+ if (addr2 == 0) {
+ if (kread(addr, (char *)&ifnet, sizeof ifnet) ||
+ kread((u_long)ifnet.if_name, ifacename, IFNAMSIZ)){
+ perror("ifconfig: kvm_read()");
+ return;
+ }
+ addr = (u_long)ifnet.if_next;
+ addr2 = (u_long)ifnet.if_addrlist;
+ }
+ if (kread(addr2, (char *)&ifaddr, sizeof ifaddr)) {
+ addr2 = 0;
+ continue;
+ }
+ sprintf(ifacename,"%s%d",ifacename, ifnet.if_unit);
+ if (!strncmp(name, ifacename, strlen(name))) {
+ #define CP(x) ((char *)(x))
+ cp = (CP(ifaddr.ifa.ifa_addr) - CP(addr2)) +
+ CP(&ifaddr); sa = (struct sockaddr *)cp;
+ if (sa->sa_family == AF_LINK) {
+ sdl = (struct sockaddr_dl *)sa;
+ cp = (char *)LLADDR(sdl);
+ if ((n = sdl->sdl_alen) > 0) {
+ printf ("\tether ");
+ while (--n >= 0)
+ m += printf("%02x%c",
+ *cp++ & 0xff,
+ n > 0 ? ':' : ' ');
+ putchar('\n');
+ }
+ break;
+ }
+ }
+ addr2 = (u_long)ifaddr.ifa.ifa_next;
+ }
+ kvm_close(kvmd);
+ }
+
Perror(cmd)
char *cmd;
{
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199412300732.CAA03841>
