]> git.puffer.fish Git - matthieu/frr.git/commitdiff
2004-08-11 Greg Troxel <gdt@fnord.ir.bbn.com>
authorgdt <gdt>
Wed, 11 Aug 2004 18:06:38 +0000 (18:06 +0000)
committergdt <gdt>
Wed, 11 Aug 2004 18:06:38 +0000 (18:06 +0000)
* rtadv.c (rtadv_send_packet): Allocate space for control messages
more carefully; it was wrong on NetBSD/sparc where CMSG alignment
is to 8 bytes instead of 4, and overwriting the address.  Use the
provided macros for determining lengths.

zebra/ChangeLog
zebra/rtadv.c

index 718de62591f1261427e2d343cb17b227c3b36f08..5adcbceecbb4ff6a611819db311e0fa6b3cdd393 100644 (file)
@@ -1,3 +1,10 @@
+2004-08-11  Greg Troxel  <gdt@fnord.ir.bbn.com>
+
+       * rtadv.c (rtadv_send_packet): Allocate space for control messages
+       more carefully; it was wrong on NetBSD/sparc where CMSG alignment
+       is to 8 bytes instead of 4, and overwriting the address.  Use the
+       provided macros for determining lengths.
+
 2004-07-23 Sowmini Varadhan <Sowmini.Varadhan@Sun.COM>
 
         * if_ioctl_solaris.c: HAVE_IPV6 ifdef fixups
index c95e75d8a6a07892697df50d3ae9554e44be40b8..082a1b362f1043cbfbbf28e48742d773bc7738e6 100644 (file)
@@ -157,14 +157,7 @@ rtadv_send_packet (int sock, struct interface *ifp)
 #ifdef HAVE_SOCKADDR_DL
   struct sockaddr_dl *sdl;
 #endif /* HAVE_SOCKADDR_DL */
-  /*
-   * XXX: Alignment padding follows cmsghdr, and there is not
-   * necessarily a portable way to determine this.  Add 16 bytes as a
-   * pessimistic assumption.  (NetBSD/i386 aligns to 4, and
-   * NetBSD/sparc to 8.)  Note check below that buf is not
-   * overwritten.  A better fix is needed.
-   */
-  char adata [sizeof (struct cmsghdr) + 16 + sizeof (struct in6_pktinfo)];
+  static void *adata = NULL;
   unsigned char buf[RTADV_MSG_SIZE];
   struct nd_router_advert *rtadv;
   int ret;
@@ -173,6 +166,21 @@ rtadv_send_packet (int sock, struct interface *ifp)
   u_char all_nodes_addr[] = {0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,1};
   listnode node;
 
+  /*
+   * Allocate control message bufffer.  This is dynamic because
+   * CMSG_SPACE is not guaranteed not to call a function.  Note that
+   * the size will be different on different architectures due to
+   * differing alignment rules.
+   */
+  if (adata == NULL)
+    {
+      /* XXX Free on shutdown. */
+      adata = malloc(CMSG_SPACE(sizeof(struct in6_pktinfo)));
+          
+      if (adata == NULL)
+       zlog_err("rtadv_send_packet: can't malloc control data\n");
+    }
+
   /* Logging of packet. */
   if (IS_ZEBRA_DEBUG_PACKET)
     zlog_info ("Router advertisement send to %s", ifp->name);
@@ -275,25 +283,17 @@ rtadv_send_packet (int sock, struct interface *ifp)
   msg.msg_iov = &iov;
   msg.msg_iovlen = 1;
   msg.msg_control = (void *) adata;
-  msg.msg_controllen = sizeof adata;
-  msg.msg_flags = MSG_DONTROUTE;
+  msg.msg_controllen = CMSG_LEN(sizeof(struct in6_pktinfo));
+  msg.msg_flags = 0;
   iov.iov_base = buf;
   iov.iov_len = len;
 
-  cmsgptr = (struct cmsghdr *)adata;
-  cmsgptr->cmsg_len = sizeof adata;
+  cmsgptr = CMSG_FIRSTHDR(&msg);
+  cmsgptr->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
   cmsgptr->cmsg_level = IPPROTO_IPV6;
   cmsgptr->cmsg_type = IPV6_PKTINFO;
 
-  /* XXX Check that we do not overwrite buf. */
   pkt = (struct in6_pktinfo *) CMSG_DATA (cmsgptr);
-  if ((void *) &pkt->ipi6_ifindex + sizeof(pkt->ipi6_ifindex)
-      > (void *) &addr)
-    {
-      zlog_err ("rtadv_send_packet: NOT overwriting address\n");
-      return;
-    }
-
   memset (&pkt->ipi6_addr, 0, sizeof (struct in6_addr));
   pkt->ipi6_ifindex = ifp->ifindex;