From owner-freebsd-net Fri Aug 11 17:22:13 2000 Delivered-To: freebsd-net@freebsd.org Received: from gatekeeper.whistle.com (gatekeeper.whistle.com [207.76.204.2]) by hub.freebsd.org (Postfix) with ESMTP id 8E2EB37BD44; Fri, 11 Aug 2000 17:21:59 -0700 (PDT) (envelope-from archie@whistle.com) Received: from bubba.whistle.com (bubba.whistle.com [207.76.205.7]) by gatekeeper.whistle.com (8.9.3/8.9.3) with ESMTP id RAA13624; Fri, 11 Aug 2000 17:21:57 -0700 (PDT) (envelope-from archie@whistle.com) Received: (from archie@localhost) by bubba.whistle.com (8.9.3/8.9.3) id RAA51816; Fri, 11 Aug 2000 17:21:57 -0700 (PDT) (envelope-from archie) From: Archie Cobbs Message-Id: <200008120021.RAA51816@bubba.whistle.com> Subject: SIOCSIFLLADDR ioctl() patch To: freebsd-net@freebsd.org Date: Fri, 11 Aug 2000 17:21:57 -0700 (PDT) Cc: wpaul@freebsd.org, rwatson@freebsd.org X-Mailer: ELM [version 2.4ME+ PL68 (25)] MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Sender: owner-freebsd-net@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org Anyone care to review this patch? I've tried to block a couple of things that would crash the kernel, e.g., calling SIOCSIFLLADDR on an interface type that doesn't use struct arpcom in ifp->if_softc. The ulterior motive is to export if_setlladdr() so that ng_ether(4) can hook into it. Thanks, -Archie P.S. Is IFT_8021_VLAN ever going to get promoted from if_vlan_var.h to if_types.h? ___________________________________________________________________________ Archie Cobbs * Whistle Communications, Inc. * http://www.whistle.com Index: if.c =================================================================== RCS file: /home/ncvs/src/sys/net/if.c,v retrieving revision 1.91 diff -u -r1.91 if.c --- if.c 2000/07/16 01:46:42 1.91 +++ if.c 2000/08/12 00:20:14 @@ -54,6 +54,7 @@ #include #include #include +#include #include #include @@ -762,8 +763,6 @@ { register struct ifnet *ifp; register struct ifreq *ifr; - register struct ifaddr *ifa; - struct sockaddr_dl *sdl; struct ifstat *ifs; int error; short oif_flags; @@ -917,29 +916,9 @@ error = suser(p); if (error) return (error); - ifa = ifnet_addrs[ifp->if_index - 1]; - if (ifa == NULL) - return(EINVAL); - sdl = (struct sockaddr_dl *)ifa->ifa_addr; - if (sdl == NULL) - return(EINVAL); - bcopy(ifr->ifr_addr.sa_data, - ((struct arpcom *)ifp->if_softc)->ac_enaddr, - ifr->ifr_addr.sa_len); - bcopy(ifr->ifr_addr.sa_data, LLADDR(sdl), - ifr->ifr_addr.sa_len); - /* - * If the interface is already up, we need - * to re-init it in order to reprogram its - * address filter. - */ - if (ifp->if_flags & IFF_UP) { - ifp->if_flags &= ~IFF_UP; - (*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, NULL); - ifp->if_flags |= IFF_UP; - (*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, NULL); - } - return(0); + return if_setlladdr(ifp, + ifr->ifr_addr.sa_data, ifr->ifr_addr.sa_len); + default: oif_flags = ifp->if_flags; if (so->so_proto == 0) @@ -1337,6 +1316,52 @@ free(ifma, M_IFMADDR); return 0; +} + +/* + * Set the link layer address on an interface. + * + * At this time we only support certain types of interfaces, + * and we don't allow the length of the address to change. + */ +int +if_setlladdr(struct ifnet *ifp, const u_char *lladdr, int len) +{ + struct sockaddr_dl *sdl; + struct ifaddr *ifa; + + ifa = ifnet_addrs[ifp->if_index - 1]; + if (ifa == NULL) + return (EINVAL); + sdl = (struct sockaddr_dl *)ifa->ifa_addr; + if (sdl == NULL) + return (EINVAL); + if (len != sdl->sdl_alen) /* don't allow length to change */ + return (EINVAL); + switch (ifp->if_type) { + case IFT_ETHER: /* these types use struct arpcom */ + case IFT_FDDI: + case IFT_XETHER: + case IFT_ISO88025: + case IFT_PROPVIRTUAL: /* XXX waiting for IFT_8021_VLAN */ + bcopy(lladdr, ((struct arpcom *)ifp->if_softc)->ac_enaddr, len); + bcopy(lladdr, LLADDR(sdl), len); + break; + default: + return (ENODEV); + } + /* + * If the interface is already up, we need + * to re-init it in order to reprogram its + * address filter. + */ + if ((ifp->if_flags & IFF_UP) != 0) { + ifp->if_flags &= ~IFF_UP; + (*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, NULL); + ifp->if_flags |= IFF_UP; + (*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, NULL); + } + return (0); } struct ifmultiaddr * Index: if_var.h =================================================================== RCS file: /home/ncvs/src/sys/net/if_var.h,v retrieving revision 1.25 diff -u -r1.25 if_var.h --- if_var.h 2000/07/13 22:54:30 1.25 +++ if_var.h 2000/08/12 00:20:14 @@ -340,6 +340,7 @@ void if_detach __P((struct ifnet *)); void if_down __P((struct ifnet *)); void if_route __P((struct ifnet *, int flag, int fam)); +int if_setlladdr __P((struct ifnet *, const u_char *, int)); void if_unroute __P((struct ifnet *, int flag, int fam)); void if_up __P((struct ifnet *)); /*void ifinit __P((void));*/ /* declared in systm.h for main() */ To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-net" in the body of the message