From b1a1fabac70201e9b05aeb9fd6af703f0fbffdb4 Mon Sep 17 00:00:00 2001
From: Ondrej Filip <feela@network.cz>
Date: Mon, 31 May 2004 13:25:00 +0000
Subject: *BSD port added. (Tested on FreeBSD and NetBSD)

---
 sysdep/unix/io.c        | 45 ++++++++++++++++++++++++++++++-----------
 sysdep/unix/krt-iface.c | 54 +++++++++++++++++--------------------------------
 sysdep/unix/krt-set.c   |  9 +++++----
 sysdep/unix/main.c      |  2 +-
 sysdep/unix/unix.h      |  2 +-
 5 files changed, 58 insertions(+), 54 deletions(-)

(limited to 'sysdep/unix')

diff --git a/sysdep/unix/io.c b/sysdep/unix/io.c
index cec1c20a..f667801f 100644
--- a/sysdep/unix/io.c
+++ b/sysdep/unix/io.c
@@ -2,6 +2,7 @@
  *	BIRD Internet Routing Daemon -- Unix I/O
  *
  *	(c) 1998--2000 Martin Mares <mj@ucw.cz>
+ *      (c) 2004       Ondrej Filip <feela@network.cz>
  *
  *	Can be freely distributed and used under the terms of the GNU GPL.
  */
@@ -29,6 +30,7 @@
 #include "lib/unix.h"
 #include "lib/sysio.h"
 
+#define LOCAL_DEBUG
 /*
  *	Tracked Files
  */
@@ -399,6 +401,14 @@ tm_format_reltime(char *x, bird_clock_t t)
 #define SOL_IP IPPROTO_IP
 #endif
 
+#ifndef SOL_IPV6
+#define SOL_IPV6 IPPROTO_IPV6
+#endif
+
+#ifndef IPV6_ADD_MEMBERSHIP
+#define IPV6_ADD_MEMBERSHIP IP_ADD_MEMBERSHIP
+#endif
+
 static list sock_list;
 
 static void
@@ -476,17 +486,21 @@ sk_new(pool *p)
 void
 fill_in_sockaddr(sockaddr *sa, ip_addr a, unsigned port)
 {
+  memset (sa, 0, sizeof (struct sockaddr_in6));
   sa->sin6_family = AF_INET6;
   sa->sin6_port = htons(port);
   sa->sin6_flowinfo = 0;
+#ifdef HAVE_SIN_LEN
+  sa->sin6_len = sizeof(struct sockaddr_in6);
+#endif
   set_inaddr(&sa->sin6_addr, a);
 }
 
 void
-get_sockaddr(sockaddr *sa, ip_addr *a, unsigned *port)
+get_sockaddr(struct sockaddr_in6 *sa, ip_addr *a, unsigned *port, int check)
 {
-  if (sa->sin6_family != AF_INET6)
-    bug("get_sockaddr called for wrong address family");
+  if (check && sa->sin6_family != AF_INET6)
+    bug("get_sockaddr called for wrong address family (%d)", sa->sin6_family);
   if (port)
     *port = ntohs(sa->sin6_port);
   memcpy(a, &sa->sin6_addr, sizeof(*a));
@@ -498,16 +512,20 @@ get_sockaddr(sockaddr *sa, ip_addr *a, unsigned *port)
 void
 fill_in_sockaddr(sockaddr *sa, ip_addr a, unsigned port)
 {
+  memset (sa, 0, sizeof (struct sockaddr_in));
   sa->sin_family = AF_INET;
   sa->sin_port = htons(port);
+#ifdef HAVE_SIN_LEN
+  sa->sin_len = sizeof(struct sockaddr_in);
+#endif
   set_inaddr(&sa->sin_addr, a);
 }
 
 void
-get_sockaddr(sockaddr *sa, ip_addr *a, unsigned *port)
+get_sockaddr(struct sockaddr_in *sa, ip_addr *a, unsigned *port, int check)
 {
-  if (sa->sin_family != AF_INET)
-    bug("get_sockaddr called for wrong address family");
+  if (check && sa->sin_family != AF_INET)
+    bug("get_sockaddr called for wrong address family (%d)", sa->sin_family);
   if (port)
     *port = ntohs(sa->sin_port);
   memcpy(a, &sa->sin_addr.s_addr, sizeof(*a));
@@ -536,8 +554,8 @@ sk_setup(sock *s)
     WARN("IP_TOS");
   if (s->ttl >= 0 && setsockopt(fd, SOL_IP, IP_TTL, &s->ttl, sizeof(s->ttl)) < 0)
     ERR("IP_TTL");
-  if (s->ttl == 1 && setsockopt(fd, SOL_SOCKET, SO_DONTROUTE, &one, sizeof(one)) < 0)
-    ERR("SO_DONTROUTE");
+  //if (s->ttl == 1 && setsockopt(fd, SOL_SOCKET, SO_DONTROUTE, &one, sizeof(one)) < 0)
+  //  ERR("SO_DONTROUTE");
 #endif
   err = NULL;
 bad:
@@ -578,7 +596,7 @@ sk_passive_connected(sock *s, struct sockaddr *sa, int al, int type)
       t->rbsize = s->rbsize;
       t->tbsize = s->tbsize;
       if (type == SK_TCP)
-	get_sockaddr((sockaddr *) sa, &t->daddr, &t->dport);
+	get_sockaddr((sockaddr *) sa, &t->daddr, &t->dport, 1);
       add_tail(&sock_list, &t->n);
       if (err = sk_setup(t))
 	{
@@ -645,7 +663,9 @@ sk_open(sock *s)
   s->fd = fd;
 
   if (err = sk_setup(s))
+  {
     goto bad;
+  }
   switch (type)
     {
     case SK_UDP:
@@ -683,7 +703,7 @@ sk_open(sock *s)
 	    mreq.ipv6mr_ifindex = s->iface->index;
 #else
 	    mreq.ipv6mr_interface = s->iface->index;
-#endif
+#endif /* CONFIG_IPV6_GLIBC_20 */
 	    if (setsockopt(fd, SOL_IPV6, IPV6_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)
 	      ERR("IPV6_ADD_MEMBERSHIP");
 	  }
@@ -692,7 +712,7 @@ sk_open(sock *s)
 	ASSERT(s->iface && s->iface->addr);
 	if (err = sysio_mcast_join(s))
 	  goto bad;
-#endif
+#endif /* IPV6 */
       break;
       }
     }
@@ -842,6 +862,7 @@ sk_maybe_write(sock *s)
 	if (s->tbuf == s->tpos)
 	  return 1;
 	fill_in_sockaddr(&sa, s->faddr, s->fport);
+
 	e = sendto(s->fd, s->tbuf, s->tpos - s->tbuf, 0, (struct sockaddr *) &sa, sizeof(sa));
 	if (e < 0)
 	  {
@@ -955,7 +976,7 @@ sk_read(sock *s)
 	    return 0;
 	  }
 	s->rpos = s->rbuf + e;
-	get_sockaddr(&sa, &s->faddr, &s->fport);
+	get_sockaddr(&sa, &s->faddr, &s->fport, 1);
 	s->rx_hook(s, e);
 	return 1;
       }
diff --git a/sysdep/unix/krt-iface.c b/sysdep/unix/krt-iface.c
index ddd70e99..5cc78807 100644
--- a/sysdep/unix/krt-iface.c
+++ b/sysdep/unix/krt-iface.c
@@ -2,6 +2,7 @@
  *	BIRD -- Unix Interface Scanning and Syncing
  *
  *	(c) 1998--2000 Martin Mares <mj@ucw.cz>
+ *      (c) 2004       Ondrej Filip <feela@network.cz>
  *
  *	Can be freely distributed and used under the terms of the GNU GPL.
  */
@@ -36,6 +37,7 @@ scan_ifs(struct ifreq *r, int cnt)
   unsigned fl;
   ip_addr netmask;
   int l, scope;
+  sockaddr *sa;
 
   if_start_update();
   for (cnt /= sizeof(struct ifreq); cnt; cnt--, r++)
@@ -43,7 +45,6 @@ scan_ifs(struct ifreq *r, int cnt)
       int sec = 0;
       bzero(&i, sizeof(i));
       bzero(&a, sizeof(a));
-      DBG("%s\n", r->ifr_name);
       if (colon = strchr(r->ifr_name, ':'))
 	{
 	  /* It's an alias -- let's interpret it as a secondary interface address */
@@ -51,7 +52,10 @@ scan_ifs(struct ifreq *r, int cnt)
 	  *colon = 0;
 	}
       strncpy(i.name, r->ifr_name, sizeof(i.name) - 1);
-      get_sockaddr((struct sockaddr_in *) &r->ifr_addr, &a.ip, NULL);
+
+      if(ioctl(if_scan_sock, SIOCGIFADDR,r)<0) continue;
+
+      get_sockaddr((struct sockaddr_in *) &r->ifr_addr, &a.ip, NULL, 1);
       if (ipa_nonzero(a.ip))
 	{
 	  l = ipa_classify(a.ip);
@@ -83,11 +87,11 @@ scan_ifs(struct ifreq *r, int cnt)
 
       if (ioctl(if_scan_sock, SIOCGIFNETMASK, r) < 0)
 	{ err = "SIOCGIFNETMASK"; goto faulty; }
-      get_sockaddr((struct sockaddr_in *) &r->ifr_addr, &netmask, NULL);
+      get_sockaddr((struct sockaddr_in *) &r->ifr_addr, &netmask, NULL, 0);
       l = ipa_mklen(netmask);
       if (l < 0 || l == 31)
 	{
-	  log(L_ERR "%s: Invalid netmask", i.name);
+	  log(L_ERR "%s: Invalid netmask (%x)", i.name, netmask);
 	  goto bad;
 	}
       a.pxlen = l;
@@ -97,7 +101,7 @@ scan_ifs(struct ifreq *r, int cnt)
 	  a.flags |= IA_UNNUMBERED;
 	  if (ioctl(if_scan_sock, SIOCGIFDSTADDR, r) < 0)
 	    { err = "SIOCGIFDSTADDR"; goto faulty; }
-	  get_sockaddr((struct sockaddr_in *) &r->ifr_addr, &a.opposite, NULL);
+	  get_sockaddr((struct sockaddr_in *) &r->ifr_addr, &a.opposite, NULL, 1);
 	  a.prefix = a.opposite;
 	  a.pxlen = BITS_PER_IP_ADDRESS;
 	}
@@ -188,40 +192,17 @@ krt_if_scan(struct kif_proto *p)
 
   for(;;)
     {
-      if (last_ifbuf_size)
-	{
-	  struct ifreq *r = alloca(last_ifbuf_size);
-	  ic.ifc_ifcu.ifcu_req = r;
-	  ic.ifc_len = last_ifbuf_size;
-	  res = ioctl(if_scan_sock, SIOCGIFCONF, &ic);
-	  if (res < 0 && errno != EFAULT)
-	    die("SIOCCGIFCONF: %m");
-	  if (res >= 0 && ic.ifc_len < last_ifbuf_size)
-	    {
-	      scan_ifs(r, ic.ifc_len);
-	      break;
-	    }
-	}
-#if 0
-      /*
-       *  Linux 2.1 and higher supports this, but it's not needed since
-       *  we prefer to use Netlink there anyway.
-       */
-      ic.ifc_req = NULL;
-      ic.ifc_len = 999999999;
-      if (ioctl(if_scan_sock, SIOCGIFCONF, &ic) < 0)
-	die("SIOCIFCONF: %m");
-      ic.ifc_len += sizeof(struct ifreq);
-      if (last_ifbuf_size < ic.ifc_len)
-	{
-	  last_ifbuf_size = ic.ifc_len;
-	  DBG("Increased ifconf buffer size to %d\n", last_ifbuf_size);
-	}
-#else
+      ic.ifc_buf = alloca(last_ifbuf_size);
+      ic.ifc_len = last_ifbuf_size;
+      res = ioctl(if_scan_sock, SIOCGIFCONF, &ic);
+      if (res < 0 && errno != EFAULT)
+        die("SIOCCGIFCONF: %m");
+      if (res >= 0 && ic.ifc_len <= last_ifbuf_size)
+        break;
       last_ifbuf_size *= 2;
       DBG("Increased ifconf buffer size to %d\n", last_ifbuf_size);
-#endif
     }
+  scan_ifs(ic.ifc_req, ic.ifc_len);
 }
 
 void
@@ -247,3 +228,4 @@ krt_if_io_init(void)
   if (if_scan_sock < 0)
     die("Cannot create scanning socket: %m");
 }
+
diff --git a/sysdep/unix/krt-set.c b/sysdep/unix/krt-set.c
index bd564486..67f32b89 100644
--- a/sysdep/unix/krt-set.c
+++ b/sysdep/unix/krt-set.c
@@ -13,6 +13,7 @@
 #include <net/route.h>
 
 #undef LOCAL_DEBUG
+#define LOCAL_DEBUG
 
 #include "nest/bird.h"
 #include "nest/iface.h"
@@ -36,7 +37,7 @@ krt_capable(rte *e)
     (a->dest == RTD_ROUTER
      || a->dest == RTD_DEVICE
 #ifdef RTF_REJECT
-     || a->dest == RTD_UNREACHABLE
+     || a->dest == RTD_UNREACHABLE		/* FIXME Blackhole, prohibited?? */
 #endif
      );
 }
@@ -45,12 +46,12 @@ static void
 krt_ioctl(int ioc, rte *e, char *name)
 {
   net *net = e->net;
-  struct rtentry re;
+  struct ortentry re;
   rta *a = e->attrs;
 
   bzero(&re, sizeof(re));
   fill_in_sockaddr((struct sockaddr_in *) &re.rt_dst, net->n.prefix, 0);
-  fill_in_sockaddr((struct sockaddr_in *) &re.rt_genmask, ipa_mkmask(net->n.pxlen), 0);
+  //fill_in_sockaddr((struct sockaddr_in *) &re.rt_genmask, ipa_mkmask(net->n.pxlen), 0);
   re.rt_flags = RTF_UP;
   if (net->n.pxlen == 32)
     re.rt_flags |= RTF_HOST;
@@ -61,7 +62,7 @@ krt_ioctl(int ioc, rte *e, char *name)
       re.rt_flags |= RTF_GATEWAY;
       break;
     case RTD_DEVICE:
-      re.rt_dev = a->iface->name;
+      //re.rt_dev = a->iface->name;
       break;
 #ifdef RTF_REJECT
     case RTD_UNREACHABLE:
diff --git a/sysdep/unix/main.c b/sysdep/unix/main.c
index 2e10521b..e16eb699 100644
--- a/sysdep/unix/main.c
+++ b/sysdep/unix/main.c
@@ -12,7 +12,7 @@
 #include <stdlib.h>
 #include <fcntl.h>
 #include <unistd.h>
-#include <sys/signal.h>
+#include <signal.h>
 
 #include "nest/bird.h"
 #include "lib/lists.h"
diff --git a/sysdep/unix/unix.h b/sysdep/unix/unix.h
index da06345e..72b6ef56 100644
--- a/sysdep/unix/unix.h
+++ b/sysdep/unix/unix.h
@@ -43,7 +43,7 @@ struct birdsock;
 void io_init(void);
 void io_loop(void);
 void fill_in_sockaddr(sockaddr *sa, ip_addr a, unsigned port);
-void get_sockaddr(sockaddr *sa, ip_addr *a, unsigned *port);
+void get_sockaddr(sockaddr *sa, ip_addr *a, unsigned *port, int check);
 int sk_open_unix(struct birdsock *s, char *name);
 void *tracked_fopen(struct pool *, char *name, char *mode);
 
-- 
cgit v1.2.3