dhcpcd-discuss

Re: Static IP config feature request: broadcast address

Roy Marples

Tue Jan 02 15:36:56 2018

Hi Yegor

On 22/12/2017 13:04, Yegor Yefremov wrote:
So far one can setup IP address, netmask, routers etc,, but a way to
setup a non-standard broadcast address is missing. It would be a nice
to have feature.

Can you test the attached patch please?
How to configure the broadcast address should be clear in the patched man pages.

Let me know how it works for you!

Roy
diff --git a/src/dhcp.c b/src/dhcp.c
index ed1b0a6d..cc2f1dff 100644
--- a/src/dhcp.c
+++ b/src/dhcp.c
@@ -1462,8 +1462,11 @@ get_lease(struct interface *ifp,
 	if (ifp->options->options & (DHCPCD_STATIC | DHCPCD_INFORM)) {
 		if (ifp->options->req_addr.s_addr != INADDR_ANY) {
 			lease->mask = ifp->options->req_mask;
-			lease->brd.s_addr =
-			    lease->addr.s_addr | ~lease->mask.s_addr;
+			if (ifp->options->req_brd.s_addr != INADDR_ANY)
+				lease->brd = ifp->options->req_brd;
+			else
+				lease->brd.s_addr =
+				    lease->addr.s_addr | ~lease->mask.s_addr;
 		} else {
 			const struct ipv4_addr *ia;
 
diff --git a/src/dhcpcd.8.in b/src/dhcpcd.8.in
index 53e6b3c6..27a149e7 100644
--- a/src/dhcpcd.8.in
+++ b/src/dhcpcd.8.in
@@ -47,7 +47,7 @@
 .Op Fl Q , Fl Fl require Ar option
 .Op Fl r , Fl Fl request Ar address
 .Op Fl S , Fl Fl static Ar value
-.Op Fl s , Fl Fl inform Ar address Ns Op Ar /cidr
+.Op Fl s , Fl Fl inform Ar address Ns Op Ar /cidr Ns Op Ar /broadcast_address
 .Op Fl Fl inform6
 .Op Fl t , Fl Fl timeout Ar seconds
 .Op Fl u , Fl Fl userclass Ar class
@@ -444,7 +444,7 @@ If no
 is given then the first address currently assigned to the
 .Ar interface
 is used.
-.It Fl s , Fl Fl inform Ar address Ns Op Ar /cidr
+.It Fl s , Fl Fl inform Ar address Ns Op Ar /cidr Ns Op Ar /broadcast_address
 Behaves like
 .Fl r , Fl Fl request
 as above, but sends a DHCP INFORM instead of DISCOVER/REQUEST.
diff --git a/src/dhcpcd.conf.5.in b/src/dhcpcd.conf.5.in
index 9bc8fad0..40730231 100644
--- a/src/dhcpcd.conf.5.in
+++ b/src/dhcpcd.conf.5.in
@@ -225,7 +225,7 @@ If no
 is given then the first address currently assigned to the
 .Ar interface
 is used.
-.It Ic inform Op Ar address Ns Op Ar /cidr
+.It Ic inform Op Ar address Ns Op Ar /cidr Ns Op Ar /broadcast_address
 Behaves like
 .Ic request
 as above, but sends a DHCP INFORM instead of DISCOVER/REQUEST.
@@ -602,8 +602,8 @@ If you set
 .Nm dhcpcd
 will continue auto-configuation as normal.
 .Pp
-Here is an example which configures two static address, an IPv4 router, DNS
-and disables IPv6 auto-configuration.
+Here is an example which configures two static address, overriding the default
+IPv4 broadcast address, an IPv4 router, DNS and disables IPv6 auto-configuration.
 You could also use the
 .Ic inform6
 command here if you wished to obtain more information via DHCPv6.
@@ -613,6 +613,7 @@ option instead of setting a static address.
 .D1 interface eth0
 .D1 noipv6rs
 .D1 static ip_address=192.168.0.10/24
+.D1 static broadcast_address=192.168.0.63
 .D1 static ip6_address=fd51:42f8:caae:d92e::ff/64
 .D1 static routers=192.168.0.1
 .D1 static domain_name_servers=192.168.0.1 fd51:42f8:caae:d92e::1
diff --git a/src/if-options.c b/src/if-options.c
index c7416ea5..40a7e7a5 100644
--- a/src/if-options.c
+++ b/src/if-options.c
@@ -815,8 +815,21 @@ parse_option(struct dhcpcd_ctx *ctx, const char *ifname, struct if_options *ifo,
 		break;
 	case 's':
 		if (arg && *arg != '\0') {
-			if (parse_addr(&ifo->req_addr, &ifo->req_mask, arg)
-			    != 0)
+			/* Strip out a broadcast address */
+			p = strchr(arg, '/');
+			if (p != NULL) {
+				p = strchr(p + 1, '/');
+				if (p != NULL)
+					*p = '\0';
+			}
+			i = parse_addr(&ifo->req_addr, &ifo->req_mask, arg);
+			if (p != NULL) {
+				/* Ensure the original string is preserved */
+				*p++ = '/';
+				if (i == 0)
+					i = parse_addr(&ifo->req_brd, NULL, p);
+			}
+			if (i != 0)
 				return -1;
 		} else {
 			ifo->req_addr.s_addr = 0;
@@ -1060,6 +1073,11 @@ parse_option(struct dhcpcd_ctx *ctx, const char *ifname, struct if_options *ifo,
 		{
 			if (parse_addr(&ifo->req_mask, NULL, p) != 0)
 				return -1;
+		} else if (strncmp(arg, "broadcast_address=",
+		    strlen("broadcast_address=")) == 0)
+		{
+			if (parse_addr(&ifo->req_brd, NULL, p) != 0)
+				return -1;
 		} else if (strncmp(arg, "routes=", strlen("routes=")) == 0 ||
 		    strncmp(arg, "static_routes=",
 		        strlen("static_routes=")) == 0 ||
diff --git a/src/if-options.h b/src/if-options.h
index 164ad593..4852d4b7 100644
--- a/src/if-options.h
+++ b/src/if-options.h
@@ -180,6 +180,7 @@ struct if_options {
 
 	struct in_addr req_addr;
 	struct in_addr req_mask;
+	struct in_addr req_brd;
 	struct rt_head routes;
 	struct in6_addr req_addr6;
 	uint8_t req_prefix_len;

Follow-Ups:
Re: Static IP config feature request: broadcast addressYegor Yefremov
References:
Static IP config feature request: broadcast addressYegor Yefremov
Archive administrator: postmaster@marples.name