Subject: support for int option value in setsockopt(, IPPROTO_IP, IP_MULTICAST_TTL,,)
To: None <tech-kern@NetBSD.org>
From: Stoned Elipot <seb@ssr.univ-paris7.fr>
List: tech-kern
Date: 09/11/2005 00:11:44
--U+BazGySraz5kW0T
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Hi,
I've been wondering why ntpd stopped working in my usual multicast
setup since ntp 4.x import. Yes it had been quite some time since then :)

Anyway, ntpd in src/dist/ntp/ntpd/ntp_io.c sets the TTL of outgoing multicast
packets via an int option value argument to setsockopt(), search for
IP_MULTICAST_TTL in this source file... This fail because
netinet/ip_output.c:ip_setmoptions() check that the option value
for IP_MULTICAST_TTL is one byte long, it bails out otherwise.

Then I noticed that FreeBSD's code allows for an int type option value
in the same situation, see the same fonction in the same source file of
FreeBSD's kernel.

So instead of "fixing" ntpd's sources I had a try to make a similar change
in NetBSD's ip_setmoptions().

The attached patch contains this change, I tested it successfully on
i386 3.99.8 current and sparc64 2.0_STABLE.

I'd like to hear your opinions on this as I'd like to commit such a change.

Cheers, Stoned.

--U+BazGySraz5kW0T
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="ip_output.c-diff"

Index: ip_output.c
===================================================================
RCS file: /cvsroot/src/sys/netinet/ip_output.c,v
retrieving revision 1.155
diff -u -r1.155 ip_output.c
--- ip_output.c	18 Aug 2005 00:30:59 -0000	1.155
+++ ip_output.c	10 Sep 2005 21:30:30 -0000
@@ -1702,11 +1702,21 @@
 		/*
 		 * Set the IP time-to-live for outgoing multicast packets.
 		 */
-		if (m == NULL || m->m_len != 1) {
+		if (m == NULL) {
 			error = EINVAL;
 			break;
 		}
-		imo->imo_multicast_ttl = *(mtod(m, u_char *));
+		if (m->m_len == 1)
+			imo->imo_multicast_ttl = *(mtod(m, u_char *));
+		else if (m->m_len == sizeof(unsigned int)) {
+			unsigned int uttl;
+			uttl = *(mtod(m, unsigned int *));
+			if (uttl > 255)
+				error = EINVAL;
+			else
+				imo->imo_multicast_ttl = (u_int8_t) uttl;
+		} else
+			error = EINVAL;
 		break;
 
 	case IP_MULTICAST_LOOP:

--U+BazGySraz5kW0T--