git: 4dbba5ab609c - stable/13 - ifconfig: warn if setting an Internet address without mask

From: Mike Karels <karels_at_FreeBSD.org>
Date: Fri, 10 Dec 2021 16:29:10 UTC
The branch stable/13 has been updated by karels:

URL: https://cgit.FreeBSD.org/src/commit/?id=4dbba5ab609c9285d734a147e5d876fa393d1403

commit 4dbba5ab609c9285d734a147e5d876fa393d1403
Author:     Mike Karels <karels@FreeBSD.org>
AuthorDate: 2021-10-28 14:32:31 +0000
Commit:     Mike Karels <karels@FreeBSD.org>
CommitDate: 2021-12-10 16:24:51 +0000

    ifconfig: warn if setting an Internet address without mask
    
    Add a postproc function for af_inet, and add interface flags as a
    parameter.  Check there if setting an address without a mask unless
    the interface is loopback or point-to-point, where mask is not really
    meaningful; warn if so.  This will hopefully be an error in the future.
    
    (cherry picked from commit d8237b95552807e937fc389c7e2237679ef0c984)
---
 sbin/ifconfig/af_inet.c  | 11 +++++++++++
 sbin/ifconfig/af_inet6.c |  3 ++-
 sbin/ifconfig/ifconfig.c | 16 +++++++++-------
 sbin/ifconfig/ifconfig.h |  3 ++-
 4 files changed, 24 insertions(+), 9 deletions(-)

diff --git a/sbin/ifconfig/af_inet.c b/sbin/ifconfig/af_inet.c
index 3d44a4c0b992..c5c40de155d6 100644
--- a/sbin/ifconfig/af_inet.c
+++ b/sbin/ifconfig/af_inet.c
@@ -175,6 +175,16 @@ in_getaddr(const char *s, int which)
 		errx(1, "%s: bad value", s);
 }
 
+static void
+in_postproc(int s, const struct afswtch *afp, int newaddr, int ifflags)
+{
+	if (sintab[ADDR]->sin_len != 0 && sintab[MASK]->sin_len == 0 &&
+	    newaddr && (ifflags & (IFF_POINTOPOINT | IFF_LOOPBACK)) == 0) {
+		warnx("WARNING: setting interface address without mask "
+		    "is deprecated,\ndefault mask may not be correct.");
+	}
+}
+
 static void
 in_status_tunnel(int s)
 {
@@ -222,6 +232,7 @@ static struct afswtch af_inet = {
 	.af_af		= AF_INET,
 	.af_status	= in_status,
 	.af_getaddr	= in_getaddr,
+	.af_postproc	= in_postproc,
 	.af_status_tunnel = in_status_tunnel,
 	.af_settunnel	= in_set_tunnel,
 	.af_difaddr	= SIOCDIFADDR,
diff --git a/sbin/ifconfig/af_inet6.c b/sbin/ifconfig/af_inet6.c
index 50568de4f148..08902b934ad8 100644
--- a/sbin/ifconfig/af_inet6.c
+++ b/sbin/ifconfig/af_inet6.c
@@ -419,7 +419,8 @@ sec2str(time_t total)
 }
 
 static void
-in6_postproc(int s, const struct afswtch *afp)
+in6_postproc(int s, const struct afswtch *afp, int newaddr __unused,
+    int ifflags __unused)
 {
 	if (explicit_prefix == 0) {
 		/* Aggregatable address architecture defines all prefixes
diff --git a/sbin/ifconfig/ifconfig.c b/sbin/ifconfig/ifconfig.c
index 5e114b43c126..0423b3593504 100644
--- a/sbin/ifconfig/ifconfig.c
+++ b/sbin/ifconfig/ifconfig.c
@@ -116,7 +116,7 @@ static	void status(const struct afswtch *afp, const struct sockaddr_dl *sdl,
 static	void tunnel_status(int s);
 static _Noreturn void usage(void);
 
-static int getifflags(const char *ifname, int us);
+static int getifflags(const char *ifname, int us, bool err_ok);
 
 static struct afswtch *af_getbyname(const char *name);
 static struct afswtch *af_getbyfamily(int af);
@@ -603,7 +603,7 @@ main(int argc, char *argv[])
 		if (iflen >= sizeof(name)) {
 			warnx("%s: interface name too long, skipping", ifname);
 		} else {
-			flags = getifflags(name, -1);
+			flags = getifflags(name, -1, false);
 			if (!(((flags & IFF_CANTCONFIG) != 0) ||
 				(downonly && (flags & IFF_UP) != 0) ||
 				(uponly && (flags & IFF_UP) == 0)))
@@ -1000,7 +1000,7 @@ top:
 	 * Do any post argument processing required by the address family.
 	 */
 	if (afp->af_postproc != NULL)
-		afp->af_postproc(s, afp);
+		afp->af_postproc(s, afp, newaddr, getifflags(name, s, true));
 	/*
 	 * Do deferred callbacks registered while processing
 	 * command-line arguments.
@@ -1179,7 +1179,7 @@ setifdstaddr(const char *addr, int param __unused, int s,
 }
 
 static int
-getifflags(const char *ifname, int us)
+getifflags(const char *ifname, int us, bool err_ok)
 {
 	struct ifreq my_ifr;
 	int s;
@@ -1192,8 +1192,10 @@ getifflags(const char *ifname, int us)
 	} else
 		s = us;
  	if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&my_ifr) < 0) {
- 		Perror("ioctl (SIOCGIFFLAGS)");
- 		exit(1);
+		if (!err_ok) {
+			Perror("ioctl (SIOCGIFFLAGS)");
+			exit(1);
+		}
  	}
 	if (us < 0)
 		close(s);
@@ -1211,7 +1213,7 @@ setifflags(const char *vname, int value, int s, const struct afswtch *afp)
 	struct ifreq		my_ifr;
 	int flags;
 
-	flags = getifflags(name, s);
+	flags = getifflags(name, s, false);
 	if (value < 0) {
 		value = -value;
 		flags &= ~value;
diff --git a/sbin/ifconfig/ifconfig.h b/sbin/ifconfig/ifconfig.h
index ea541c5e9257..2c0b8a100b0d 100644
--- a/sbin/ifconfig/ifconfig.h
+++ b/sbin/ifconfig/ifconfig.h
@@ -110,7 +110,8 @@ struct afswtch {
 	void		(*af_getaddr)(const char *, int);
 					/* parse prefix method (IPv6) */
 	void		(*af_getprefix)(const char *, int);
-	void		(*af_postproc)(int s, const struct afswtch *);
+	void		(*af_postproc)(int s, const struct afswtch *,
+			    int newaddr, int ifflags);
 	u_long		af_difaddr;	/* set dst if address ioctl */
 	u_long		af_aifaddr;	/* set if address ioctl */
 	void		*af_ridreq;	/* */