From owner-freebsd-net@FreeBSD.ORG Thu May 20 09:29:22 2004 Return-Path: Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 7707C16A4CE for ; Thu, 20 May 2004 09:29:22 -0700 (PDT) Received: from gandalf.online.bg (gandalf.online.bg [217.75.128.9]) by mx1.FreeBSD.org (Postfix) with SMTP id ACEBD43D1F for ; Thu, 20 May 2004 09:29:20 -0700 (PDT) (envelope-from roam@ringlet.net) Received: (qmail 8219 invoked from network); 20 May 2004 16:20:40 -0000 Received: from install.online.bg (HELO straylight.m.ringlet.net) (217.75.128.4) by gandalf.online.bg with SMTP; 20 May 2004 16:20:40 -0000 Received: (qmail 8217 invoked by uid 1000); 20 May 2004 16:29:19 -0000 Date: Thu, 20 May 2004 19:29:19 +0300 From: Peter Pentchev To: freebsd-net@FreeBSD.org Message-ID: <20040520162919.GA1971@straylight.m.ringlet.net> Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="vGgW1X5XWziG23Ko" Content-Disposition: inline User-Agent: Mutt/1.5.6i Subject: [RFC] ifconfig: match by link-level address X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 20 May 2004 16:29:22 -0000 --vGgW1X5XWziG23Ko Content-Type: multipart/mixed; boundary="5mCyUwZo2JvN/JJP" Content-Disposition: inline --5mCyUwZo2JvN/JJP Content-Type: text/plain; charset=windows-1251 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable Hi, I found out recently that the Linux (or at least recent RedHat) startup scripts could be configured to not bring up an Ethernet interface unless it has a specified MAC address. This, combined with the wonderful interface renaming functionality recently committed to -CURRENT, led me to the idea of interface renaming on boot-up, by hardware addresses - something like 'I don't care how you detected this network card, or how many others like it are there, but the card with MAC address 00:03:0d:08:dc:a7 will be known as sis0int from now on'. The main missing piece was the ability to find an interface by MAC address; hence the attached patch, also available at http://www.ringlet.net/~roam/bsd-patches/src5/sbin-ifconfig-hwmatch.patch http://people.FreeBSD.org/~roam/bsd-patches/src5/sbin-ifconfig-hwmatch.patch It teaches ifconfig(8) to treat interface "names" beginning with 'hw-' as link-level addresses; ifconfig tries to find an interface with this address and behaves as if its name was specified on the command line: [roam@straylight ~/fbsd/r/src/sbin/ifconfig]> ./ifconfig hw-00:03:0d:08:dc:= a7 sis0: flags=3D8843 mtu 1500 options=3D8 inet 10.0.8.129 netmask 0xffff0000 broadcast 10.0.255.255 inet 192.168.1.13 netmask 0xffffff00 broadcast 192.168.1.255 ether 00:03:0d:08:dc:a7 media: Ethernet autoselect (100baseTX ) status: active [roam@straylight ~/fbsd/r/src/sbin/ifconfig]> This could be the first step towards teaching rc.conf about something like network_interfaces_rename=3D"hw-00:03:0d:08:dc:a7 sis0int" I had initially written my own function for parsing the user-supplied address into a sequence of bytes instead of using ether_aton(); it would have the advantage of being able to specify 'hw-' to match lo0's empty link-level "address". However, the odds of somebody actually wishing to rename lo0 don't seem to be so high :) G'luck, Peter --=20 Peter Pentchev roam@ringlet.net roam@sbnd.net roam@FreeBSD.org PGP key: http://people.FreeBSD.org/~roam/roam.key.asc Key fingerprint FDBA FD79 C26F 3C51 C95E DF9E ED18 B68D 1619 4553 You have, of course, just begun reading the sentence that you have just fin= ished reading. --5mCyUwZo2JvN/JJP Content-Type: text/plain; charset=windows-1251 Content-Disposition: attachment; filename="sbin-ifconfig-hwmatch.patch" Content-Transfer-Encoding: quoted-printable Index: src/sbin/ifconfig/ifconfig.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /home/ncvs/src/sbin/ifconfig/ifconfig.c,v retrieving revision 1.104 diff -u -r1.104 ifconfig.c --- src/sbin/ifconfig/ifconfig.c 30 Apr 2004 22:34:12 -0000 1.104 +++ src/sbin/ifconfig/ifconfig.c 20 May 2004 16:02:44 -0000 @@ -145,6 +145,9 @@ void usage(void); void ifmaybeload(char *name); =20 +static char *findifname(const char *); +static void parseaddr(const char *, struct sockaddr_dl *); + #ifdef INET6 void in6_fillscopeid(struct sockaddr_in6 *sin6); int prefix(void *, int); @@ -509,6 +512,14 @@ if (argc < 1) usage(); =20 + if (!strncmp(*argv, "hw-", 3)) { + char *tmp; + =09 + tmp =3D findifname(*argv + 3); + if (tmp =3D=3D NULL) + errx(1, "no interface with address %s", *argv); + *argv =3D tmp; + } strncpy(name, *argv, sizeof(name)); argc--, argv++; =20 @@ -1947,3 +1958,57 @@ */ printname =3D 0; } + +/* + * Return the name of the interface with this link-level address, or NULL + */ +char * +findifname(const char *addr) +{ + struct ifaddrs *l, *c; + struct sockaddr_dl *sdl, templ; + char *name; +=09 + parseaddr(addr, &templ); + + if (getifaddrs(&l) =3D=3D -1) + err(1, "getifaddrs"); + name =3D NULL; + for (c =3D l; c !=3D NULL; c =3D c->ifa_next) { + if (c->ifa_addr =3D=3D NULL || c->ifa_addr->sa_family !=3D AF_LINK) + continue; + sdl =3D (struct sockaddr_dl *)c->ifa_addr; + if (sdl->sdl_alen =3D=3D templ.sdl_alen && + memcmp(sdl->sdl_data + sdl->sdl_nlen, + templ.sdl_data + templ.sdl_nlen, + sdl->sdl_alen) =3D=3D 0) { + name =3D strdup(c->ifa_name); + break; + } + } + freeifaddrs(l); + return (name); +} + +/* + * Parse the interface address into a sockaddr_dl structure + */ +static void +parseaddr(const char *addr, struct sockaddr_dl *dst) +{ + struct sockaddr_dl sdl; + struct ether_addr *e; + + /* Init the sockaddr_dl structure */ + memset(&sdl, 0, sizeof(sdl)); + sdl.sdl_len =3D sizeof(sdl); + sdl.sdl_family =3D AF_LINK; + sdl.sdl_nlen =3D 0; + e =3D ether_aton(addr); + if (e =3D=3D NULL) + errx(1, "Invalid link-level address format: %s", addr); + memcpy(sdl.sdl_data, e, sizeof(*e)); + sdl.sdl_alen =3D 6; + sdl.sdl_slen =3D 0; + memcpy(dst, &sdl, sizeof(*dst)); +} --5mCyUwZo2JvN/JJP-- --vGgW1X5XWziG23Ko Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.4 (FreeBSD) iD8DBQFArNzf7Ri2jRYZRVMRAqQAAJ9PRsutVwA1MbubrwFoM1Io3wNGvgCfYaBP SMiecWpec8Iga+Hg32tPqsU= =vUEg -----END PGP SIGNATURE----- --vGgW1X5XWziG23Ko--