Subject: bin/8566: [rkb] Make 'arp(8)' output interface associated with each ARP entry
To: None <gnats-bugs@gnats.netbsd.org>
From: None <rafal@mediaone.net>
List: netbsd-bugs
Date: 10/06/1999 04:36:45
>Number: 8566
>Category: bin
>Synopsis: an option to print the interface name for ARP entries is added
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: bin-bug-people (Utility Bug People)
>State: open
>Class: change-request
>Submitter-Id: net
>Arrival-Date: Wed Oct 6 04:35:00 1999
>Last-Modified:
>Originator: Rafal Boni
>Organization:
...me organized? Ha!
>Release: -current as of 10/4
>Environment:
System: NetBSD groo-the-wanderer.waterside.net 1.4K NetBSD 1.4K (GROO) #2: Mon Aug 30 07:10:25 EDT 1999 root@groo-the-wanderer.waterside.net:/usr/src/sys/arch/i386/compile/GROO i386
>Description:
arp(8) does not print which interface an ARP entry is associated with.
On machines multihomed machines, it's often useful to know which
interface the ARP entry is associated with (for debugging network
topologies, etc.)
>How-To-Repeat:
Run arp. See that no interface is printed.
>Fix:
Index: arp.c
===================================================================
RCS file: /cvsroot/basesrc/usr.sbin/arp/arp.c,v
retrieving revision 1.23
diff -b -u -r1.23 arp.c
--- arp.c 1998/02/10 03:45:06 1.23
+++ arp.c 1999/10/06 11:17:56
@@ -58,6 +58,7 @@
#include <sys/file.h>
#include <sys/socket.h>
#include <sys/sysctl.h>
+#include <sys/ioctl.h>
#include <net/if.h>
#include <net/if_dl.h>
@@ -81,6 +82,7 @@
int delete __P((const char *, const char *));
void dump __P((u_long));
void sdl_print __P((const struct sockaddr_dl *));
+int getifname __P((u_int16_t, char *));
int atosdl __P((const char *s, struct sockaddr_dl *sdl));
int file __P((char *));
void get __P((const char *));
@@ -94,7 +96,11 @@
static int pid;
static int nflag, vflag;
static int s = -1;
+static int is = -1;
+static struct ifconf ifc;
+static char ifconfbuf[8192];
+
int delete __P((const char *, const char *));
void dump __P((u_long));
void ether_print __P((const u_char *));
@@ -390,6 +396,7 @@
{
int mib[6];
size_t needed;
+ char ifname[IF_NAMESIZE];
char *host, *lim, *buf, *next;
struct rt_msghdr *rtm;
struct sockaddr_inarp *sin;
@@ -438,6 +445,12 @@
sdl_print(sdl);
else
(void)printf("(incomplete)");
+
+ if (sdl->sdl_index) {
+ if (getifname(sdl->sdl_index, ifname) == 0)
+ printf(" on %s", ifname);
+ }
+
if (rtm->rtm_rmx.rmx_expire == 0)
(void)printf(" permanent");
if (sin->sin_other & SIN_PROXY)
@@ -607,4 +620,58 @@
}
(void)memcpy(inap, hp->h_addr, sizeof(*inap));
return (0);
+}
+
+int
+getifname(ifindex, ifname)
+ u_int16_t ifindex;
+ char* ifname;
+{
+ int i, idx, siz;
+ char ifrbuf[8192];
+ struct ifreq ifreq, *ifr;
+ const struct sockaddr_dl *sdl = NULL;
+
+ if (is < 0) {
+ is = socket(PF_INET, SOCK_DGRAM, 0);
+ if (is < 0)
+ err(1, "socket");
+
+ ifc.ifc_len = sizeof(ifconfbuf);
+ ifc.ifc_buf = ifconfbuf;
+
+ if (ioctl(is, SIOCGIFCONF, &ifc) < 0) {
+ close(is);
+ err(1, "SIOCGIFCONF");
+ is = -1;
+ }
+ }
+
+ ifr = ifc.ifc_req;
+ ifreq.ifr_name[0] = '\0';
+ for (i = 0, idx = 0; i < ifc.ifc_len; ) {
+ ifr = (struct ifreq *)((caddr_t)ifc.ifc_req + i);
+ siz = sizeof(ifr->ifr_name) +
+ (ifr->ifr_addr.sa_len > sizeof(struct sockaddr)
+ ? ifr->ifr_addr.sa_len
+ : sizeof(struct sockaddr));
+ i += siz;
+ /* avoid alignment issue */
+ if (sizeof(ifrbuf) < siz)
+ errx(1, "ifr too big");
+
+ memcpy(ifrbuf, ifr, siz);
+ ifr = (struct ifreq *)ifrbuf;
+
+ if (ifr->ifr_addr.sa_family != AF_LINK)
+ continue;
+
+ sdl = (const struct sockaddr_dl *) &ifr->ifr_addr;
+ if (sdl && sdl->sdl_index == ifindex) {
+ (void) strncpy(ifname, ifr->ifr_name, IF_NAMESIZE);
+ return 0;
+ }
+ }
+
+ return -1;
}
>Audit-Trail:
>Unformatted: