NetBSD Problem Report #10911

Received: (qmail 13996 invoked from network); 30 Aug 2000 01:09:29 -0000
Message-Id: <200008292055.e7TKtc726575@zorkmid.mit.edu>
Date: Tue, 29 Aug 2000 16:55:39 -0400 (EDT)
From: John Hawkinson <jhawk@mit.edu>
Reply-To: jhawk@mit.edu
To: gnats-bugs@gnats.netbsd.org
Cc: Angie Kelic <sly@mit.edu>
Subject: ifconfig requires address to set netmask, broadcast
X-Send-Pr-Version: 3.95

>Number:         10911
>Category:       bin
>Synopsis:       ifconfig requires address to set netmask, broadcast
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Wed Aug 30 01:10:01 +0000 2000
>Closed-Date:    
>Last-Modified:  Thu Aug 18 15:05:01 +0000 2022
>Originator:     John Hawkinson
>Release:        -current of 28 Aug 2000
>Organization:
MIT
>Environment:

System: NetBSD zorkmid.mit.edu 1.5E NetBSD 1.5E (ZORKMID-$Revision: 1.2 $) #54: Fri Aug 18 01:53:49 EDT 2000 jhawk@zorkmid.mit.edu:/usr/local/netbsd-current/src/sys/arch/i386/compile/ZORKMID i386


>Description:
	ifconfig(8) requires the IP address of an interface to be
specified (or changed) in order to set the netmask or broadcast
address. If unspecified, it silently fails.

>How-To-Repeat:

zorkmid# ifconfig wi0
wi0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
        nwid "NetBSD IBSS"
        media: IEEE802.11 autoselect
        status: active
        inet 1.2.3.4 netmask 0xff000000 broadcast 1.255.255.255
        inet6 fe80::260:1dff:fe1e:73c9%wi0 prefixlen 64 scopeid 0x15
zorkmid# ifconfig wi0 netmask 0xffff0000
zorkmid# ifconfig wi0
wi0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
        nwid "NetBSD IBSS"
        media: IEEE802.11 autoselect
        status: active
        inet 1.2.3.4 netmask 0xff000000 broadcast 1.255.255.255
        inet6 fe80::260:1dff:fe1e:73c9%wi0 prefixlen 64 scopeid 0x15
zorkmid# ifconfig wi0 1.2.3.4 netmask 0xffff0000
zorkmid# ifconfig wi0
wi0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
        nwid "NetBSD IBSS"
        media: IEEE802.11 autoselect
        status: active
        inet 1.2.3.4 netmask 0xffff0000 broadcast 1.2.255.255
        inet6 fe80::260:1dff:fe1e:73c9%wi0 prefixlen 64 scopeid 0x15

>Fix:
	Workaround: always respecifiy the IP address when configuring the netmask.


	Fix: ifconfig is a festering pile of ooze. This bug appears to have been
	present back in 4.4lite, and probably some time previous. It apalls me that
	no one seems to have noticed, though.

	Unfortunately, the non-deprecated for changing interface characteristics,
	SIOCAIFADDR requires the caller to specify the IP address to change the
	mask of, so ifconfig needs to SIOCGIFCONF the interface, in this case where
	no IP address is specified. Perhaps it should do so in all cases...
>Release-Note:
>Audit-Trail:
From: Nat Sloss <nathanialsloss@yahoo.com.au>
To: "gnats-bugs" <gnats-bugs@netbsd.org>
Cc: 
Subject: Re: bin/10911 - ifconfig requires address to set netmask, broadcast
Date: Sun, 13 Apr 2014 01:43:15 +1000

 Hi,

 I've found a way to solve this by falling back to the existing address of the 
 interface if an address is not specified.  This allows setting the broadcast 
 address and netmask without specifying an address.

 Here is my patch:
 Index: src/sbin/ifconfig/af_inetany.c
 ===================================================================
 RCS file: /cvsroot/src/sbin/ifconfig/af_inetany.c,v
 retrieving revision 1.17
 diff -u -r1.17 af_inetany.c
 --- src/sbin/ifconfig/af_inetany.c	30 Dec 2012 22:52:35 -0000	1.17
 +++ src/sbin/ifconfig/af_inetany.c	12 Apr 2014 15:30:28 -0000
 @@ -68,12 +68,15 @@
      const struct afparam *param)
  {
  	const char *ifname;
 +	struct ifreq ifr;
  	int af, rc, s;
  	bool alias, delete, replace;
  	prop_data_t d;
  	const struct paddr_prefix *addr, *brd, *dst, *mask;
  	unsigned short flags;

 +	addr = NULL;
 +
  	if ((af = getaf(env)) == -1)
  		af = AF_INET;

 @@ -89,8 +92,22 @@
  	if ((d = (prop_data_t)prop_dictionary_get(env, "address")) != NULL)
  		addr = prop_data_data_nocopy(d);
  	else if (!prop_dictionary_get_bool(env, "alias", &alias) || alias ||
 -	    param->gifaddr.cmd == 0)
 -		return;
 +	    param->gifaddr.cmd == 0) {
 +		if (addr == NULL) {
 +			static struct paddr_prefix existingaddr;
 +
 +			memset(&ifr, 0, sizeof(ifr));
 +			estrlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
 +			if (prog_ioctl(s, SIOCGIFADDR, &ifr) == -1) {
 +				if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT)
 +					return;
 +				err(EXIT_FAILURE,"SIOCGIFADDR");
 +			}
 +
 +			existingaddr.pfx_addr = ifr.ifr_addr;
 +			addr = &existingaddr;
 +		}
 +	}
  	else if (prog_ioctl(s, param->gifaddr.cmd, param->dgreq.buf) == -1)
  		err(EXIT_FAILURE, "%s", param->gifaddr.desc);
  	else if (prog_ioctl(s, param->difaddr.cmd, param->dgreq.buf) == -1)

 Regards,

 Nat.

 This also applies to bin/31940 - ifconfig behaves unexpectedly, one part of it 
 not the rest of #31940, still investigating.

Responsible-Changed-From-To: bin-bug-people->nat
Responsible-Changed-By: dholland@NetBSD.org
Responsible-Changed-When: Fri, 21 May 2021 23:29:25 +0000
Responsible-Changed-Why:
If your patch here is still good (it looks reasonable but I don't know the
code), want to commit it?
(if not, set this back to kern-bug-people)


From: David Holland <dholland-bugs@netbsd.org>
To: gnats-bugs@netbsd.org
Cc: 
Subject: Re: bin/10911 (ifconfig requires address to set netmask, broadcast)
Date: Fri, 21 May 2021 23:29:55 +0000

 On Fri, May 21, 2021 at 11:29:26PM +0000, dholland@NetBSD.org wrote:
  > Synopsis: ifconfig requires address to set netmask, broadcast
  > 
  > Responsible-Changed-From-To: bin-bug-people->nat
  > Responsible-Changed-By: dholland@NetBSD.org
  > Responsible-Changed-When: Fri, 21 May 2021 23:29:25 +0000
  > Responsible-Changed-Why:
  > If your patch here is still good (it looks reasonable but I don't know the
  > code), want to commit it?
  > (if not, set this back to kern-bug-people)

 er, bin-bug-people, right

 -- 
 David A. Holland
 dholland@netbsd.org

State-Changed-From-To: open->closed
State-Changed-By: nat@NetBSD.org
State-Changed-When: Tue, 16 Aug 2022 10:48:58 +0000
State-Changed-Why:
Patch applied.


Responsible-Changed-From-To: nat->bin-bug-people
Responsible-Changed-By: nat@NetBSD.org
Responsible-Changed-When: Wed, 17 Aug 2022 23:48:10 +0000
Responsible-Changed-Why:
Patch from PR is wrong.  Handing this back to bin-bug-people.


State-Changed-From-To: closed->open
State-Changed-By: nat@NetBSD.org
State-Changed-When: Wed, 17 Aug 2022 23:48:10 +0000
State-Changed-Why:
Not fixed yet.  Reopening.


From: Robert Elz <kre@munnari.OZ.AU>
To: gnats-bugs@netbsd.org
Cc: 
Subject: Re: bin/10911 (ifconfig requires address to set netmask, broadcast)
Date: Thu, 18 Aug 2022 20:17:35 +0700

     Date:        Wed, 17 Aug 2022 23:48:10 +0000 (UTC)
     From:        nat@NetBSD.org
     Message-ID:  <20220817234810.DC3E91A923A@mollari.NetBSD.org>

   | Synopsis: ifconfig requires address to set netmask, broadcast

 I actually doubt that there is any bug here at all.

 The PR text says:

 	This bug appears to have been present back in 4.4lite, and
 	probably some time previous. It apalls me that no one seems
 	to have noticed, though.

 As best I recall it (which doesn't necessarily mean a lot) ifconfig
 (from when it appeared in versions of BSD between 4.1 and 4.2) has
 always worked like this, at least since the concept of a netmask was
 invented) - and that's because in general, any other way makes no sense
 at all.   That is, it isn't a bug.

 Consider an interface (dummy0) with two addresses

 	10.2.3.4
 	192.168.1.7

 If I were now to do

 	ifconfig dummy0 netmask 255.255.0.0

 what is supposed to happen?   What subnet numbers can the system
 conclude are attached to that interface?

 A netmask only means anything when it is applied to a specific
 IP address (or at least, subnet number - since its purpose is to
 mask away the host bits, what they are doesn't matter as much).

 The above interface is likely to have 2 different netmasks, probably
 255.255.255.0 for 192.168.1.7, and almost anything for the network
 10 address (255.0.0.0, 255.192.0.0, 255.255.0.0, 255.255.248.0,
 even possibly 255.255.255.255 indicating an isolated host, or more
 likely 255.255.255.254 (or 252) for a minimalist 2 host subnet).

 The original design simply assumed that the two would be set together,
 always, as the system needs to know both this system's address, and the
 netmask to be applied to it to discover the subnet's subnet number from
 that address.   However, in the early days there were no netmasks, the
 address "class" (a concept now best forgotten) allowed the subnet number
 to be discovered directly from the IP address (for the two addresses
 above, the classful netmasks would be 255.0.0.0 and 255.255.255.0).
 Thus, it was possible to specify an IP address without a netmask, and
 when that happened, the system would use the address class to deduce the
 mask to be applied (either literally, or just conceptually in implementations
 from when all IP addressing used classes).

 While here, note that netmasks long preceded CIDR - they were invented to
 allow a single classful IP network number to be shared amongst multiple LANS
 within an organisation, so don't confuse the introduction of CIDR, and the
 eventual removal of classed addresses at all, as being related to this.
 That's all a much more recent development.

 Broadcast is similar - when BSD first invented the concept (standard IP
 at the time had no notion of broadcast, not multicast either) the address
 used as the broadcast address was always the subnet number.   That is
 (IPADDR & NETMASK) was the broadcast address.    Other systems that also
 implemented broadcast instead used (IPADDR | ~NETMASK).    Originally these
 were not configurable options - but with different implementations using
 different things, config was needed, so the broadcast addr config was added.

 But if you look at the two definitions that had been used, one thing stands
 out - they both use both the IPADDR and the NETMASK.    Now obiously one can
 (as was originally done) simply compute the broadcast addr from those, if you
 know which formula to apply, that's not the point - the point is that the
 broadcast addr applies to a specific subnet on the link, and means nothing
 without that association.   The subnet number comes from the IPADDR and
 NETMASK (though just the IPADDR is enough to identify it).   Hence setting
 the broadcast addr also means nothing without knowing which IP address is
 associated (so the stack can calculate which subnet number it applies to).

 Once upon a time it was considered acceptable to route a broadcast packet
 to an unconnected link (normal IP routing based upon the address) and
 have the router on that link broadcast it there - but this was considered
 rather anti-social, and mostly blocked, and in any case, there was never
 a mechanism defined for anyone not on the link to discover what address to
 use to broadcast on some unconnected link.

 When 255.255.255.255 was defined as an alternate broadcast addr, that changed
 things a little, as that one has no associated subnet number, and simply
 means "broadcast on this link" which has subtly different sematics that a
 subnet broadcast - that one it might be reasonable to allow to be configured
 without an associated IP address.   Personally I'm not sure the special case
 is worth the effort, especially as that kind of broadcase tends to be used
 only early in the system life, before IP addresses are configured, and so
 by special case software that can send IP packets without an associated addr.

 In this, there is the obvious special case - an interface that has only
 one IP address.   In such a case, one might assume that simply setting a
 netmask or broadcast address would apply to that address.   I don't think
 making the kernel treat that as a special case is reasonable - but ifconfig,
 when given just a netmask (or broadcast) param, could go check to see if the
 interface has only one address, and if so, assume that one.

 Personally I don't think that's a good idea - it establishes the wrong
 expectations about the way that things work in the mind of the user.
 Users who are configuring IP manually (which all of this presumes, using
 DHCP will never attempt to set a netmask or broadcast addr without an
 associated IP addr) should learn that the netmask applies to a specific
 IP address, and the way to get that point across is to never allow the
 netmask to be specified alone.

 So, I'd simply close this PR as "not a bug" - the most I believe might be
 done is to have ifconfig object when given a netmask (or broadcast addr)
 without an IP addr to associate it with, rather than just ignoring it.

 kre

From: Martin Husemann <martin@duskware.de>
To: gnats-bugs@netbsd.org
Cc: 
Subject: Re: bin/10911 (ifconfig requires address to set netmask, broadcast)
Date: Thu, 18 Aug 2022 17:04:54 +0200

 I like this suggestion - and it is easy to implement.

 Martin

 Index: ifconfig.c
 ===================================================================
 RCS file: /cvsroot/src/sbin/ifconfig/ifconfig.c,v
 retrieving revision 1.248
 diff -u -p -r1.248 ifconfig.c
 --- ifconfig.c	14 Oct 2020 13:37:14 -0000	1.248
 +++ ifconfig.c	18 Aug 2022 15:02:27 -0000
 @@ -994,6 +994,9 @@ setifnetmask(prop_dictionary_t env, prop
  {
  	prop_data_t d;

 +	if (prop_dictionary_get(env, "address") == NULL)
 +		errx(EXIT_FAILURE, "can not set netmask without address");
 +
  	d = (prop_data_t)prop_dictionary_get(env, "dstormask");
  	assert(d != NULL);

 @@ -1015,6 +1018,9 @@ setifbroadaddr(prop_dictionary_t env, pr
  	if ((flags & IFF_BROADCAST) == 0)
  		errx(EXIT_FAILURE, "not a broadcast interface");

 +	if (prop_dictionary_get(env, "address") == NULL)
 +		errx(EXIT_FAILURE, "can not set broadcast without address");
 +
  	d = (prop_data_t)prop_dictionary_get(env, "broadcast");
  	assert(d != NULL);


>Unformatted:

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.46 2020/01/03 16:35:01 leot Exp $
$NetBSD: gnats_config.sh,v 1.9 2014/08/02 14:16:04 spz Exp $
Copyright © 1994-2020 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.