summaryrefslogtreecommitdiff
path: root/sbin
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2022-11-25 23:09:21 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2022-11-25 23:09:21 +0000
commit11de5446e547356b6a008fd117d33a972e2e6199 (patch)
tree4864939c15de7e9ea5c00f1e8cfcce6a87844e7a /sbin
parenta6e7e6e1d05cd78cf79b7edc3755035fa2e84a9a (diff)
ifconfig -M <mac> finds the address on an interface and prints it.
cloned (virtual) interfaces are skipped, and if the MAC is on more than 1 interface, no answer either. The mac must be in same format as the ifconfig lladdr output (complete lowercase with :) idea from florian, ok afresh1
Diffstat (limited to 'sbin')
-rw-r--r--sbin/ifconfig/ifconfig.810
-rw-r--r--sbin/ifconfig/ifconfig.c98
2 files changed, 92 insertions, 16 deletions
diff --git a/sbin/ifconfig/ifconfig.8 b/sbin/ifconfig/ifconfig.8
index 8ade4a90ae6..678c87c8588 100644
--- a/sbin/ifconfig/ifconfig.8
+++ b/sbin/ifconfig/ifconfig.8
@@ -1,4 +1,4 @@
-.\" $OpenBSD: ifconfig.8,v 1.385 2022/10/26 17:06:31 kn Exp $
+.\" $OpenBSD: ifconfig.8,v 1.386 2022/11/25 23:09:20 deraadt Exp $
.\" $NetBSD: ifconfig.8,v 1.11 1996/01/04 21:27:29 pk Exp $
.\" $FreeBSD: ifconfig.8,v 1.16 1998/02/01 07:03:29 steve Exp $
.\"
@@ -31,7 +31,7 @@
.\"
.\" @(#)ifconfig.8 8.4 (Berkeley) 6/1/94
.\"
-.Dd $Mdocdate: October 26 2022 $
+.Dd $Mdocdate: November 25 2022 $
.Dt IFCONFIG 8
.Os
.Sh NAME
@@ -40,6 +40,7 @@
.Sh SYNOPSIS
.Nm ifconfig
.Op Fl AaC
+.Op Fl M Ar lladdr
.Op Ar interface
.Op Ar address_family
.Oo
@@ -88,6 +89,11 @@ This is the default, if no parameters are given to
Print the names of all network pseudo-devices that
can be created dynamically at runtime using
.Nm Cm create .
+.It Fl M Ar lladdr
+Scan the non-cloned interface list for the MAC address
+.Ar lladdr
+and print the name of that interface.
+If the MAC address is found on multiple interfaces, print nothing.
.It Ar interface
The
.Ar interface
diff --git a/sbin/ifconfig/ifconfig.c b/sbin/ifconfig/ifconfig.c
index 2d0a09a254d..2ba0bc39f16 100644
--- a/sbin/ifconfig/ifconfig.c
+++ b/sbin/ifconfig/ifconfig.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ifconfig.c,v 1.457 2022/10/26 17:06:31 kn Exp $ */
+/* $OpenBSD: ifconfig.c,v 1.458 2022/11/25 23:09:20 deraadt Exp $ */
/* $NetBSD: ifconfig.c,v 1.40 1997/10/01 02:19:43 enami Exp $ */
/*
@@ -368,6 +368,9 @@ void wg_status(int);
void setignore(const char *, int);
#endif
+struct if_clonereq *get_cloners(void);
+int findmac(const char *);
+
/*
* Media stuff. Whenever a media command is first performed, the
* currently select media is grabbed for this interface. If `media'
@@ -795,6 +798,11 @@ main(int argc, char *argv[])
Cflag = 1;
nomore = 1;
break;
+ case 'M':
+ if (argv[1] == NULL)
+ usage();
+ exit(findmac(argv[1]));
+ break;
default:
usage();
break;
@@ -1255,12 +1263,10 @@ clone_destroy(const char *addr, int param)
err(1, "SIOCIFDESTROY");
}
-void
-list_cloners(void)
+struct if_clonereq *
+get_cloners(void)
{
- struct if_clonereq ifcr;
- char *cp, *buf;
- int idx;
+ static struct if_clonereq ifcr;
memset(&ifcr, 0, sizeof(ifcr));
@@ -1269,12 +1275,9 @@ list_cloners(void)
if (ioctl(sock, SIOCIFGCLONERS, &ifcr) == -1)
err(1, "SIOCIFGCLONERS for count");
- buf = calloc(ifcr.ifcr_total, IFNAMSIZ);
- if (buf == NULL)
+ if ((ifcr.ifcr_buffer = calloc(ifcr.ifcr_total, IFNAMSIZ)) == NULL)
err(1, "unable to allocate cloner name buffer");
-
ifcr.ifcr_count = ifcr.ifcr_total;
- ifcr.ifcr_buffer = buf;
if (ioctl(sock, SIOCIFGCLONERS, &ifcr) == -1)
err(1, "SIOCIFGCLONERS for names");
@@ -1285,17 +1288,30 @@ list_cloners(void)
if (ifcr.ifcr_count > ifcr.ifcr_total)
ifcr.ifcr_count = ifcr.ifcr_total;
- qsort(buf, ifcr.ifcr_count, IFNAMSIZ,
+ return &ifcr;
+}
+
+void
+list_cloners(void)
+{
+ struct if_clonereq *ifcr;
+ char *cp, *buf;
+ int idx;
+
+ ifcr = get_cloners();
+ buf = ifcr->ifcr_buffer;
+
+ qsort(buf, ifcr->ifcr_count, IFNAMSIZ,
(int(*)(const void *, const void *))strcmp);
- for (cp = buf, idx = 0; idx < ifcr.ifcr_count; idx++, cp += IFNAMSIZ) {
+ for (cp = buf, idx = 0; idx < ifcr->ifcr_count; idx++, cp += IFNAMSIZ) {
if (idx > 0)
putchar(' ');
printf("%s", cp);
}
putchar('\n');
- free(buf);
+ free(ifcr->ifcr_buffer);
}
#define RIDADDR 0
@@ -6614,7 +6630,7 @@ __dead void
usage(void)
{
fprintf(stderr,
- "usage: ifconfig [-AaC] [interface] [address_family] "
+ "usage: ifconfig [-AaC] [-M lladdr] [interface] [address_family] "
"[address [dest_address]]\n"
"\t\t[parameters]\n");
exit(1);
@@ -6782,3 +6798,57 @@ setignore(const char *id, int param)
/* just digest the command */
}
#endif
+
+int
+findmac(const char *mac)
+{
+ struct ifaddrs *ifap, *ifa;
+ const char *ifnam = NULL;
+ struct if_clonereq *ifcr;
+ int ret = 0;
+
+ ifcr = get_cloners();
+ if (getifaddrs(&ifap) != 0)
+ err(1, "getifaddrs");
+
+ for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
+ struct sockaddr_dl *sdl = (struct sockaddr_dl *)ifa->ifa_addr;
+
+ if (sdl != NULL && sdl->sdl_alen &&
+ (sdl->sdl_type == IFT_ETHER || sdl->sdl_type == IFT_CARP)) {
+ if (strcmp(ether_ntoa((struct ether_addr *)LLADDR(sdl)),
+ mac) == 0) {
+ char *cp, *nam = ifa->ifa_name;
+ int idx, skip = 0;
+ size_t len;
+
+ /* MACs on cloned devices are ignored */
+ for (len = 0; nam[len]; len++)
+ if (isdigit((unsigned char)nam[len]))
+ break;
+ for (cp = ifcr->ifcr_buffer, idx = 0;
+ idx < ifcr->ifcr_count;
+ idx++, cp += IFNAMSIZ) {
+ if (strncmp(nam, cp, len) == 0) {
+ skip = 1;
+ break;
+ }
+ }
+ if (skip)
+ continue;
+
+ if (ifnam) { /* same MAC on multiple ifp */
+ ret = 1;
+ goto done;
+ }
+ ifnam = nam;
+ }
+ }
+ }
+ if (ifnam)
+ printf("%s\n", ifnam);
+done:
+ free(ifcr->ifcr_buffer);
+ freeifaddrs(ifap);
+ return ret;
+}