Subject: Re: arp problem
To: Eric Haszlakiewicz <erh@nimenees.com>
From: enami tsugutomo <enami@sm.sony.co.jp>
List: tech-net
Date: 10/02/2000 12:00:51
Eric Haszlakiewicz <erh@nimenees.com> writes:

> 	Could you please update to arp.c:1.25 and rtsock.c:1.42 and make sure
> I didn't break anything?

This breaks routed, since routed may not pad the last sockaddr.  Also,
IMHO, if the padding is a part of protocol, then the macro ROUNDUP
should be exported via an appropriate header file.

enami.

Index: sys/net/route.h
===================================================================
RCS file: /cvsroot/syssrc/sys/net/route.h,v
retrieving revision 1.22
diff -u -r1.22 route.h
--- sys/net/route.h	2000/05/04 17:33:03	1.22
+++ sys/net/route.h	2000/10/02 02:54:48
@@ -210,6 +210,10 @@
 #define RTA_AUTHOR	0x40	/* sockaddr for author of redirect */
 #define RTA_BRD		0x80	/* for NEWADDR, broadcast or p-p dest addr */
 
+#define	RTA_ROUNDUP(a) \
+	((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
+#define	RTA_ADVANCE(x, n) (x += RTA_ROUNDUP((n)->sa_len))
+
 /*
  * Index offsets for sockaddr array for alternate internal encoding.
  */
Index: sys/net/rtsock.c
===================================================================
RCS file: /cvsroot/syssrc/sys/net/rtsock.c,v
retrieving revision 1.42
diff -u -r1.42 rtsock.c
--- sys/net/rtsock.c	2000/09/28 01:14:06	1.42
+++ sys/net/rtsock.c	2000/10/02 02:54:49
@@ -65,6 +65,7 @@
  */
 
 #include "opt_inet.h"
+#include "opt_compat_netbsd.h"
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -449,10 +450,6 @@
 #undef metric
 }
 
-#define ROUNDUP(a) \
-	((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
-#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
-
 static int
 rt_xaddrs(cp, cplim, rtinfo)
 	caddr_t cp, cplim;
@@ -466,12 +463,19 @@
 		if ((rtinfo->rti_addrs & (1 << i)) == 0)
 			continue;
 		rtinfo->rti_info[i] = sa = (struct sockaddr *)cp;
-		ADVANCE(cp, sa);
+		RTA_ADVANCE(cp, sa);
 	}
 	/* Check for bad data length, or extra addresses specified */
-	if ( (cp != cplim) || (rtinfo->rti_addrs & (~0 << i)) )
-		return 1;
-	return 0;
+#ifdef COMPAT_15		/* or COMPAT_14 */
+	if (rtinfo->rti_addrs == (RTA_DST|RTA_GATEWAY|RTA_NETMASK) &&
+	    1 << (i - 1) == RTA_NETMASK &&
+	    cp - RTA_ROUNDUP(rtinfo->rti_info[RTAX_NETMASK]->sa_len) +
+	    rtinfo->rti_info[RTAX_NETMASK]->sa_len == cplim)
+		return (0);
+#endif
+	if ((cp != cplim) || (rtinfo->rti_addrs & (~0 << i)))
+		return (1);
+	return (0);
 }
 
 static struct mbuf *
@@ -535,7 +539,7 @@
 		if ((sa = rtinfo->rti_info[i]) == NULL)
 			continue;
 		rtinfo->rti_addrs |= (1 << i);
-		dlen = ROUNDUP(sa->sa_len);
+		dlen = RTA_ROUNDUP(sa->sa_len);
 		m_copyback(m, len, dlen, (caddr_t)sa);
 		len += dlen;
 	}
@@ -599,7 +603,7 @@
 		if ((sa = rtinfo->rti_info[i]) == 0)
 			continue;
 		rtinfo->rti_addrs |= (1 << i);
-		dlen = ROUNDUP(sa->sa_len);
+		dlen = RTA_ROUNDUP(sa->sa_len);
 		if (cp) {
 			bcopy(sa, cp, (unsigned)dlen);
 			cp += dlen;
Index: usr.sbin/arp/arp.c
===================================================================
RCS file: /cvsroot/basesrc/usr.sbin/arp/arp.c,v
retrieving revision 1.25
diff -u -r1.25 arp.c
--- usr.sbin/arp/arp.c	2000/09/28 01:11:31	1.25
+++ usr.sbin/arp/arp.c	2000/10/02 02:54:49
@@ -54,10 +54,6 @@
  * arp - display, set, and delete arp table entries
  */
 
-/* Roundup the same way rt_xaddrs does */
-#define ROUNDUP(a) \
-	((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
-
 #include <sys/param.h>
 #include <sys/file.h>
 #include <sys/socket.h>
@@ -260,7 +256,7 @@
 		return (1);
 	}
 	sin = (struct sockaddr_inarp *)(rtm + 1);
-	sdl = (struct sockaddr_dl *)(ROUNDUP(sin->sin_len) + (char *)sin);
+	sdl = (struct sockaddr_dl *)(RTA_ROUNDUP(sin->sin_len) + (char *)sin);
 	if (sin->sin_addr.s_addr == sin_m.sin_addr.s_addr) {
 		if (sdl->sdl_family == AF_LINK &&
 		    (rtm->rtm_flags & RTF_LLINFO) &&
@@ -344,7 +340,7 @@
 		return (1);
 	}
 	sin = (struct sockaddr_inarp *)(rtm + 1);
-	sdl = (struct sockaddr_dl *)(ROUNDUP(sin->sin_len) + (char *)sin);
+	sdl = (struct sockaddr_dl *)(RTA_ROUNDUP(sin->sin_len) + (char *)sin);
 	if (sin->sin_addr.s_addr == sin_m.sin_addr.s_addr) {
 		if (sdl->sdl_family == AF_LINK &&
 		    (rtm->rtm_flags & RTF_LLINFO) &&
@@ -409,7 +405,7 @@
 		rtm = (struct rt_msghdr *)next;
 		sin = (struct sockaddr_inarp *)(rtm + 1);
 		sdl = (struct sockaddr_dl *)
-		    (ROUNDUP(sin->sin_len) + (char *)sin);
+		    (RTA_ROUNDUP(sin->sin_len) + (char *)sin);
 		if (addr) {
 			if (addr != sin->sin_addr.s_addr)
 				continue;
@@ -438,7 +434,7 @@
 			(void)printf(" published (proxy only)");
 		if (rtm->rtm_addrs & RTA_NETMASK) {
 			sin = (struct sockaddr_inarp *)
-				(ROUNDUP(sdl->sdl_len) + (char *)sdl);
+			    (RTA_ROUNDUP(sdl->sdl_len) + (char *)sdl);
 			if (sin->sin_addr.s_addr == 0xffffffff)
 				(void)printf(" published");
 			if (sin->sin_len != 8)
@@ -563,7 +559,7 @@
 #define NEXTADDR(w, s) \
 	if (rtm->rtm_addrs & (w)) { \
 		(void)memcpy(cp, &s, ((struct sockaddr *)&s)->sa_len); \
-		cp += ROUNDUP(((struct sockaddr *)&s)->sa_len); \
+		RTA_ADVANCE(cp, (struct sockaddr *)&s); \
 	}
 
 	NEXTADDR(RTA_DST, sin_m);
Index: sbin/routed/table.c
===================================================================
RCS file: /cvsroot/basesrc/sbin/routed/table.c,v
retrieving revision 1.13
diff -u -r1.13 table.c
--- sbin/routed/table.c	2000/03/02 21:01:34	1.13
+++ sbin/routed/table.c	2000/10/02 02:54:49
@@ -730,8 +730,10 @@
 #ifdef _HAVE_SA_LEN
 		masktrim(&w.w_mask);
 		if (w.w_mask.sin_len == 0)
-			w.w_mask.sin_len = sizeof(long);
-		w.w_rtm.rtm_msglen -= (sizeof(w.w_mask) - w.w_mask.sin_len);
+			w.w_mask.sin_len = (caddr_t)&w.w_mask.sin_addr -
+			    (caddr_t)&w.w_mask;
+		w.w_rtm.rtm_msglen -= sizeof(w.w_mask);
+		w.w_rtm.rtm_msglen += RTA_ROUNDUP(w.w_mask.sin_len);
 #endif
 	}