bin/72381: ifconfig lladdr does not set interface MAC address

Larry Chang larry.chang at utstar.com
Wed Oct 6 06:00:23 PDT 2004


>Number:         72381
>Category:       bin
>Synopsis:       ifconfig lladdr does not set interface MAC address
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Oct 06 13:00:23 GMT 2004
>Closed-Date:
>Last-Modified:
>Originator:     Larry Chang
>Release:        FreeBSD 4.9 RELEASE
>Organization:
UTStarcom
>Environment:
FreeBSD mobomom.nj.us.utstar.com 4.9-RELEASE FreeBSD 4.9-RELEASE #0: Mon Dec  8 19:07:51 EST 2003     root at x7.nj.us.utstar.com:/usr/src/sys/compile/GENERIC_ROCKETPORT  i386
>Description:
      The ifconfig does not set MAC address (lladdr) as specified. The
implementation changed between 4.1.1 and 4.9. For R4.9, ifconfig(8) states
addr_family 'link' is synonyms for 'ether' and 'lladdr'. It also states the link-level
address can be set.
      For R4.1.1, the lladdr is handled as a command parameter instead as
addr_family.
>How-To-Repeat:
      On R4.9 system, change MAC address using commands of the form
"ifconfig em0 lladdr 0:1:2:3:4:5" and read it back w/ "ifconfig em0". No changes
in MAC address value.

Same sequences on R4.1.1 should result in new MAC address for the
interface.
>Fix:
FILE: /usr/src/sbin/ifconfig/ifconfig.c

Remove the entry from struct afswtch afs[]
         { "lladdr", AF_LINK, link_status, link_getaddr, NULL,
         0, SIOCSIFLLADDR, NULL, C(ridreq) },

Add new entry to struct cmd cmds[]
         { "lladdr", NEXTARG,    setiflladdr },

Also, add the following lines as in R4.1.1 ifconfig.c

c_func setiflladdr;     /** after the c_func setifmtu **/

void
setiflladdr(val, dummy, s, afp)
    const char *val;
    int dummy __unused;
    int s;
    const struct afswtch *afp;
{
    struct ether_addr   *ea;

    printf("lhc: entered setiflladdr()\n");

    ea = ether_aton(val);
    if (ea == NULL) {
        warn("malformed link-level address");
        return;
    }
    strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
    ifr.ifr_addr.sa_len = ETHER_ADDR_LEN;
    ifr.ifr_addr.sa_family = AF_LINK;
    bcopy(ea, ifr.ifr_addr.sa_data, ETHER_ADDR_LEN);
    if (ioctl(s, SIOCSIFLLADDR, (caddr_t)&ifr) < 0)
        warn("ioctl (set lladdr)");

    return;
}

Another way to fix the problem is increment both newaddr and setaddr in
link_getaddr(). This should invoke ioctl() after parsing lladdr. I tried it, the
command prints a "Network is unreachable" message. There was an automatic
ARP and ping does work.

>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list