summaryrefslogtreecommitdiffstats
path: root/sysdep/unix
diff options
context:
space:
mode:
Diffstat (limited to 'sysdep/unix')
-rw-r--r--sysdep/unix/io.c45
-rw-r--r--sysdep/unix/krt-iface.c54
-rw-r--r--sysdep/unix/krt-set.c9
-rw-r--r--sysdep/unix/main.c2
-rw-r--r--sysdep/unix/unix.h2
5 files changed, 58 insertions, 54 deletions
diff --git a/sysdep/unix/io.c b/sysdep/unix/io.c
index cec1c20..f667801 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 ddd70e9..5cc7880 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 bd56448..67f32b8 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 2e10521..e16eb69 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 da06345..72b6ef5 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);