On Tue, Nov 22, 2022 at 08:09:11AM -0700, Theo de Raadt wrote:
> 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

Better than [Q]uery.

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

This reads like a viable approach, much cleaner than the netstart
globbing attempts.

Using ifconfig -M, I can give the shell bits a try later this week.

Nits inline.

> 
> 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);

Above main() already uses return, no need for exit here, I think:

                                return findmac(argv[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;

Both *mac and *ifnam can be const.

> +
> +     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);

And these exit()s can be return to fold the call as above.

> +}
> 

Reply via email to