diff options
Diffstat (limited to 'sysdep/unix')
-rw-r--r-- | sysdep/unix/io.c | 45 | ||||
-rw-r--r-- | sysdep/unix/krt-iface.c | 54 | ||||
-rw-r--r-- | sysdep/unix/krt-set.c | 9 | ||||
-rw-r--r-- | sysdep/unix/main.c | 2 | ||||
-rw-r--r-- | sysdep/unix/unix.h | 2 |
5 files changed, 58 insertions, 54 deletions
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); |