Florian Obser <flor...@openbsd.org> wrote:

> On 2022-11-22 18:06 +10, David Gwynne <da...@gwynne.id.au> wrote:
> >
> > There are a few things to keep in mind if we're going to use lladdrs like 
> > this.
> >
> > vlan interfaces start with their lladdr as 00:00:00:00:00:00 and then 
> > assume the lladdr of the parent interface when that is configured.
> >
> > Clonable devices (eg, egre, vport, aggr, etc) tend to generate random
> > lladdrs when they're created. If you want a consistent lladdr for
> > these you configure that in /etc/hostname.vportX or whatever you're
> > using.
> 
> ifconfig(8) already knows about these (see -C option). Which made me
> think, it might be easier to just ask ifconfig(8).
> 
> $ ifconfig -Q 00:80:41:7b:f3:c3
> vio0
> 
> Would that be helpful?

I'm unsure about the rest of your proposal, where MAC works in place if
the IF argument.  Let's say we do this in ifcconfig.  Do we do it in route?
Or ten other commands?  I think that is the wrong way to go.

But this first idea is valid. We've now seen 3 monster functions trying to
do this task of convering MAC to IF in shell.  Here's code to do it in
ifconfig.

I've done it as -M

It fails if the same MAC is on multiple interfaces.  Go back to using
hostname.if# files, you heathen.

Index: ifconfig.8
===================================================================
RCS file: /cvs/src/sbin/ifconfig/ifconfig.8,v
retrieving revision 1.385
diff -u -p -u -r1.385 ifconfig.8
--- ifconfig.8  26 Oct 2022 17:06:31 -0000      1.385
+++ ifconfig.8  22 Nov 2022 15:04:09 -0000
@@ -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 ar
 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 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
Index: ifconfig.c
===================================================================
RCS file: /cvs/src/sbin/ifconfig/ifconfig.c,v
retrieving revision 1.457
diff -u -p -u -r1.457 ifconfig.c
--- ifconfig.c  26 Oct 2022 17:06:31 -0000      1.457
+++ ifconfig.c  22 Nov 2022 15:02:20 -0000
@@ -368,6 +368,8 @@ void        wg_status(int);
 void   setignore(const char *, int);
 #endif
 
+void   findmac(char *);
+
 /*
  * Media stuff.  Whenever a media command is first performed, the
  * currently select media is grabbed for this interface.  If `media'
@@ -759,6 +761,7 @@ main(int argc, char *argv[])
        int create = 0;
        int Cflag = 0;
        int gflag = 0;
+       int Mflag = 0;
        int found_rulefile = 0;
        int i;
 
@@ -795,6 +798,12 @@ main(int argc, char *argv[])
                                Cflag = 1;
                                nomore = 1;
                                break;
+                       case 'M':
+                               if (argv[1] == NULL)
+                                       usage();
+                               findmac(argv[1]);
+                               exit(1);
+                               break;
                        default:
                                usage();
                                break;
@@ -6614,7 +6623,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 +6791,30 @@ setignore(const char *id, int param)
        /* just digest the command */
 }
 #endif
+
+void
+findmac(char *mac)
+{
+       struct ifaddrs *ifap, *ifa;
+       char *ifnam = NULL;
+
+       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) {
+                               if (ifnam)      /* same MAC on multiple ifp */
+                                       exit(1);
+                               ifnam = ifa->ifa_name;
+                       }
+               }
+       }
+       if (ifnam)
+               printf("%s\n", ifnam);
+       exit(0);
+}

Reply via email to