This patch from Fabio Ferrari <fabio.ferrari@digitro.com.br> enables
"broadcast +" for deriving the broadcast address automagically.
diff --git a/ifconfig.c b/ifconfig.c
index 61d73f5..7f3978a 100644
--- a/ifconfig.c
+++ b/ifconfig.c
@@ -15,7 +15,7 @@
  * Foundation;  either  version 2 of the License, or  (at
  * your option) any later version.
  *
- * $Id: ifconfig.c,v 1.10 2001/03/26 16:26:16 mjn3 Exp $
+ * $Id: ifconfig.c,v 1.11 2001/07/07 05:19:52 andersen Exp $
  *
  */
 
@@ -110,6 +110,8 @@
 #define A_NETMASK        0x20	/* Set if netmask (check for multiple sets). */
 #define A_SET_AFTER      0x40	/* Set a flag at the end. */
 #define A_COLON_CHK      0x80	/* Is this needed?  See below. */
+#define A_HOSTNAME      0x100	/* Set if it is ip addr. */
+#define A_BROADCAST     0x200	/* Set if it is broadcast addr. */
 
 /*
  * These defines are for dealing with the A_CAST_TYPE field.
@@ -139,12 +141,12 @@
 #define ARG_IRQ          (A_ARG_REQ | A_MAP_UCHAR)
 #define ARG_DSTADDR      (A_ARG_REQ | A_CAST_HOST_COPY_RESOLVE)
 #define ARG_NETMASK      (A_ARG_REQ | A_CAST_HOST_COPY_RESOLVE | A_NETMASK)
-#define ARG_BROADCAST    (A_ARG_REQ | A_CAST_HOST_COPY_RESOLVE | A_SET_AFTER)
+#define ARG_BROADCAST    (A_ARG_REQ | A_CAST_HOST_COPY_RESOLVE | A_SET_AFTER | A_BROADCAST)
 #define ARG_HW           (A_ARG_REQ | A_CAST_HOST_COPY_IN_ETHER)
 #define ARG_POINTOPOINT  (A_CAST_HOST_COPY_RESOLVE | A_SET_AFTER)
 #define ARG_KEEPALIVE    (A_ARG_REQ | A_CAST_CHAR_PTR)
 #define ARG_OUTFILL      (A_ARG_REQ | A_CAST_CHAR_PTR)
-#define ARG_HOSTNAME     (A_CAST_HOST_COPY_RESOLVE | A_SET_AFTER | A_COLON_CHK)
+#define ARG_HOSTNAME     (A_CAST_HOST_COPY_RESOLVE | A_SET_AFTER | A_COLON_CHK | A_HOSTNAME)
 
 
 /*
@@ -160,7 +162,7 @@
 struct options {
 	const char *name;
 	const unsigned char flags;
-	const unsigned char arg_flags;
+	const unsigned int arg_flags;
 	const unsigned short selector;
 };
 
@@ -246,6 +248,7 @@
 {
 	struct ifreq ifr;
 	struct sockaddr_in sai;
+	struct sockaddr_in sai_hostname, sai_netmask;
 #ifdef BB_FEATURE_IFCONFIG_HW
 	struct sockaddr sa;
 #endif
@@ -256,8 +259,8 @@
 	int selector;
 	char *p;
 	char host[128];
-	unsigned char mask;
-	unsigned char did_flags;
+	unsigned int mask;
+	unsigned int did_flags;
 
 	goterr = 0;
 	did_flags = 0;
@@ -331,7 +334,7 @@
 				}
 			} else {			/* got an arg so process it */
 			HOSTNAME:
-				did_flags |= (mask & A_NETMASK);
+				did_flags |= (mask & (A_NETMASK|A_HOSTNAME));
 				if (mask & A_CAST_HOST_COPY) {
 #ifdef BB_FEATURE_IFCONFIG_HW
 					if (mask & A_CAST_RESOLVE) {
@@ -342,11 +345,20 @@
 						if (!strcmp(host, "default")) {
 							/* Default is special, meaning 0.0.0.0. */
 							sai.sin_addr.s_addr = INADDR_ANY;
+						} else if ((!strcmp(host, "+")) && (mask & A_BROADCAST) &&
+								 (did_flags & (A_NETMASK|A_HOSTNAME))) {
+							/* + is special, meaning broadcast is derived. */
+							sai.sin_addr.s_addr = (~sai_netmask.sin_addr.s_addr) |
+								(sai_hostname.sin_addr.s_addr & sai_netmask.sin_addr.s_addr);
 						} else if (inet_aton(host, &sai.sin_addr) == 0) {
 							/* It's not a dotted quad. */
 							++goterr;
 							continue;
 						}
+						if(mask & A_HOSTNAME)
+							sai_hostname = sai;
+						if(mask & A_NETMASK)
+							sai_netmask = sai;
 						p = (char *) &sai;
 #ifdef BB_FEATURE_IFCONFIG_HW
 					} else { /* A_CAST_HOST_COPY_IN_ETHER */
diff --git a/networking/ifconfig.c b/networking/ifconfig.c
index 61d73f5..7f3978a 100644
--- a/networking/ifconfig.c
+++ b/networking/ifconfig.c
@@ -15,7 +15,7 @@
  * Foundation;  either  version 2 of the License, or  (at
  * your option) any later version.
  *
- * $Id: ifconfig.c,v 1.10 2001/03/26 16:26:16 mjn3 Exp $
+ * $Id: ifconfig.c,v 1.11 2001/07/07 05:19:52 andersen Exp $
  *
  */
 
@@ -110,6 +110,8 @@
 #define A_NETMASK        0x20	/* Set if netmask (check for multiple sets). */
 #define A_SET_AFTER      0x40	/* Set a flag at the end. */
 #define A_COLON_CHK      0x80	/* Is this needed?  See below. */
+#define A_HOSTNAME      0x100	/* Set if it is ip addr. */
+#define A_BROADCAST     0x200	/* Set if it is broadcast addr. */
 
 /*
  * These defines are for dealing with the A_CAST_TYPE field.
@@ -139,12 +141,12 @@
 #define ARG_IRQ          (A_ARG_REQ | A_MAP_UCHAR)
 #define ARG_DSTADDR      (A_ARG_REQ | A_CAST_HOST_COPY_RESOLVE)
 #define ARG_NETMASK      (A_ARG_REQ | A_CAST_HOST_COPY_RESOLVE | A_NETMASK)
-#define ARG_BROADCAST    (A_ARG_REQ | A_CAST_HOST_COPY_RESOLVE | A_SET_AFTER)
+#define ARG_BROADCAST    (A_ARG_REQ | A_CAST_HOST_COPY_RESOLVE | A_SET_AFTER | A_BROADCAST)
 #define ARG_HW           (A_ARG_REQ | A_CAST_HOST_COPY_IN_ETHER)
 #define ARG_POINTOPOINT  (A_CAST_HOST_COPY_RESOLVE | A_SET_AFTER)
 #define ARG_KEEPALIVE    (A_ARG_REQ | A_CAST_CHAR_PTR)
 #define ARG_OUTFILL      (A_ARG_REQ | A_CAST_CHAR_PTR)
-#define ARG_HOSTNAME     (A_CAST_HOST_COPY_RESOLVE | A_SET_AFTER | A_COLON_CHK)
+#define ARG_HOSTNAME     (A_CAST_HOST_COPY_RESOLVE | A_SET_AFTER | A_COLON_CHK | A_HOSTNAME)
 
 
 /*
@@ -160,7 +162,7 @@
 struct options {
 	const char *name;
 	const unsigned char flags;
-	const unsigned char arg_flags;
+	const unsigned int arg_flags;
 	const unsigned short selector;
 };
 
@@ -246,6 +248,7 @@
 {
 	struct ifreq ifr;
 	struct sockaddr_in sai;
+	struct sockaddr_in sai_hostname, sai_netmask;
 #ifdef BB_FEATURE_IFCONFIG_HW
 	struct sockaddr sa;
 #endif
@@ -256,8 +259,8 @@
 	int selector;
 	char *p;
 	char host[128];
-	unsigned char mask;
-	unsigned char did_flags;
+	unsigned int mask;
+	unsigned int did_flags;
 
 	goterr = 0;
 	did_flags = 0;
@@ -331,7 +334,7 @@
 				}
 			} else {			/* got an arg so process it */
 			HOSTNAME:
-				did_flags |= (mask & A_NETMASK);
+				did_flags |= (mask & (A_NETMASK|A_HOSTNAME));
 				if (mask & A_CAST_HOST_COPY) {
 #ifdef BB_FEATURE_IFCONFIG_HW
 					if (mask & A_CAST_RESOLVE) {
@@ -342,11 +345,20 @@
 						if (!strcmp(host, "default")) {
 							/* Default is special, meaning 0.0.0.0. */
 							sai.sin_addr.s_addr = INADDR_ANY;
+						} else if ((!strcmp(host, "+")) && (mask & A_BROADCAST) &&
+								 (did_flags & (A_NETMASK|A_HOSTNAME))) {
+							/* + is special, meaning broadcast is derived. */
+							sai.sin_addr.s_addr = (~sai_netmask.sin_addr.s_addr) |
+								(sai_hostname.sin_addr.s_addr & sai_netmask.sin_addr.s_addr);
 						} else if (inet_aton(host, &sai.sin_addr) == 0) {
 							/* It's not a dotted quad. */
 							++goterr;
 							continue;
 						}
+						if(mask & A_HOSTNAME)
+							sai_hostname = sai;
+						if(mask & A_NETMASK)
+							sai_netmask = sai;
 						p = (char *) &sai;
 #ifdef BB_FEATURE_IFCONFIG_HW
 					} else { /* A_CAST_HOST_COPY_IN_ETHER */