Subject: Re: ifconfig and aliases
To: Darren Reed <darrenr@reed.wattle.id.au>
From: Jun Xie <jun@qnx.com>
List: tech-net
Date: 07/19/1999 12:21:09
> Today I had the unfortunate displeasure of discovering how IP aliases
> attempt to work within NetBSD.  I'm not sure where the problems actually
> are, yet, but this is an extract of my experiences:
>
> [snip]
> 
> How much of the above is deliberate and if it is, can I bite those who
> decreed that it should be that way ? >:>

I'd like to share my unfortunate experiences w.r.t ifconfig/aliases
with you too. :)

1. The ifconfig man page suggests it can handle more than one IP address 
in one ifconfig command. For example, you can run
ifconfig we1 10.4.0.254 alias 10.4.0.1
ifconfig we1 10.4.0.254 -alias 10.4.0.1
ifconfig we1 10.4.0.254 delete 10.4.0.1
But it's not true. If you run "ifconfig we1 10.4.0.254 alias 10.4.0.1",
ifconfig thinks "10.4.0.1" is a broadcast address. A simple fix is
to change the docs and to check if "setaddr" is set at the beginning of
notealias() in ifconfig. If it's set, ifconfig complains and exits.

2. If an interface has an alias and it's up, "ifconfig -a -A -d"
still displays the alias. For example,
# ifconfig -a
we1: flags=8863<UP,BROADCAST,NOTRAILERS,RUNNING,SIMPLEX,MULTICAST> mtu 1500
        address: 00:c0:93:01:f5:e2
        media: Ethernet manual
        inet 10.4.0.254 netmask 0xff000000 broadcast 10.255.255.255
lo0: flags=8009<UP,LOOPBACK,MULTICAST> mtu 32976
        inet 127.0.0.1 netmask 0xff000000
ppp0: flags=8010<POINTOPOINT,MULTICAST> mtu 1500
[...]
# ifconfig -a -A -d
        inet alias 10.4.0.1 netmask 0xff000000 broadcast 10.255.255.255
ppp0: flags=8010<POINTOPOINT,MULTICAST> mtu 1500
[...]

A possible fix is to move
    if (Aflag && ifr->ifr_addr.sa_family == AF_INET)
        in_alias(ifr);
down to just below
    if (uflag && (flags & IFF_UP) == 0)
        continue;
and set a flag in its original place in printall() of ifconfig.

3. ioctl(SIOCGIFALIAS) can crash NetBSD kernal, if the interface
in the request exists but the alias is invalid.

#include <stdio.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <string.h>

main()
{
	int s;
	struct ifaliasreq addreq;

	s = socket(AF_INET, SOCK_DGRAM, 0);

	(void) memset(&addreq, 0, sizeof(addreq));
	(void) strncpy(addreq.ifra_name, "lo0", sizeof(addreq.ifra_name));
	addreq.ifra_addr.sa_family = AF_INET;
	if (ioctl(s, SIOCGIFALIAS, (caddr_t)&addreq) < 0)
		perror("SIOCGIFALIAS");
}

The fix is simple:
In sys/netinet/in.c in_control(), change
    if (cmd == SIOCDIFADDR && ia == 0)
        return (EADDRNOTAVAIL);
to
    if ((cmd == SIOCDIFADDR || cmd == SIOCGIFALIAS) && ia == 0)
        return (EADDRNOTAVAIL);

I'm using NetBSD1.4 i386.

Jun Xie