$OpenBSD: patch-src_forward_c,v 1.2 2019/01/17 10:14:33 jca Exp $

Don't mix up msg_controllen and cmsg_len.
Don't ignore EINVAL unless on Linux.

Index: src/forward.c
--- src/forward.c.orig
+++ src/forward.c
@@ -68,12 +68,14 @@ int send_from(int fd, int nowild, char *packet, size_t
 	  p.ipi_ifindex = 0;
 	  p.ipi_spec_dst = source->addr.addr4;
 	  memcpy(CMSG_DATA(cmptr), &p, sizeof(p));
-	  msg.msg_controllen = cmptr->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
+	  msg.msg_controllen = CMSG_SPACE(sizeof(struct in_pktinfo));
+	  cmptr->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
 	  cmptr->cmsg_level = IPPROTO_IP;
 	  cmptr->cmsg_type = IP_PKTINFO;
 #elif defined(IP_SENDSRCADDR)
 	  memcpy(CMSG_DATA(cmptr), &(source->addr.addr4), sizeof(source->addr.addr4));
-	  msg.msg_controllen = cmptr->cmsg_len = CMSG_LEN(sizeof(struct in_addr));
+	  msg.msg_controllen = CMSG_SPACE(sizeof(struct in_addr));
+	  cmptr->cmsg_len = CMSG_LEN(sizeof(struct in_addr));
 	  cmptr->cmsg_level = IPPROTO_IP;
 	  cmptr->cmsg_type = IP_SENDSRCADDR;
 #endif
@@ -85,7 +87,8 @@ int send_from(int fd, int nowild, char *packet, size_t
 	  p.ipi6_ifindex = iface; /* Need iface for IPv6 to handle link-local addrs */
 	  p.ipi6_addr = source->addr.addr6;
 	  memcpy(CMSG_DATA(cmptr), &p, sizeof(p));
-	  msg.msg_controllen = cmptr->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
+	  msg.msg_controllen = CMSG_SPACE(sizeof(struct in6_pktinfo));
+	  cmptr->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
 	  cmptr->cmsg_type = daemon->v6pktinfo;
 	  cmptr->cmsg_level = IPPROTO_IPV6;
 	}
@@ -96,10 +99,13 @@ int send_from(int fd, int nowild, char *packet, size_t
   
   while (retry_send(sendmsg(fd, &msg, 0)));
 
-  /* If interface is still in DAD, EINVAL results - ignore that. */
-  if (errno != 0 && errno != EINVAL)
+  if (errno != 0)
     {
-      my_syslog(LOG_ERR, _("failed to send packet: %s"), strerror(errno));
+#ifdef __linux__
+      /* If interface is still in DAD, EINVAL results - ignore that. */
+      if (errno != EINVAL)
+#endif
+        my_syslog(LOG_ERR, _("failed to send packet: %s"), strerror(errno));
       return 0;
     }
   
