Commit b1a1faba authored by Ondřej Filip's avatar Ondřej Filip

*BSD port added. (Tested on FreeBSD and NetBSD)

parent 781aa475
......@@ -41,5 +41,15 @@
/* We have <syslog.h> and syslog() */
#undef HAVE_SYSLOG
/* We have <alloca.h> */
#undef HAVE_ALLOCA_H
/* Are we using dmalloc? */
#undef HAVE_LIBDMALLOC
/* Readline stuff */
#undef HAVE_RL_CRLF
#undef HAVE_RL_DING
/* struct sockaddr_in(6) */
#undef HAVE_SIN_LEN
krt-scan.h
krt-iface.h
sysio.h
krt-set.h
krt-sock.c
krt-sock.h
/*
* BIRD -- Unix Kernel Socket Route Syncer -- Dummy Include File
*
* (c) 2004 Ondrej Filip <feela@network.cz>
*
* Can be freely distributed and used under the terms of the GNU GPL.
*/
#ifndef _BIRD_KRT_IFACE_H_
#define _BIRD_KRT_IFACE_H_
/*
* We don't have split iface/scan/set parts. See krt-sock.h.
*/
static inline int kif_params_same(struct krt_if_params *old, struct krt_if_params *new) { return 1; }
#endif
/*
* BIRD -- *BSD Table Scanning
*
* (c) 2004 Ondrej Filip <feela@network.cz>
*
* Can be freely distributed and used under the terms of the GNU GPL.
*/
#include <stdio.h>
#include <ctype.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/sysctl.h>
#include <sys/socket.h>
#include <net/route.h>
#undef LOCAL_DEBUG
#define LOCAL_DEBUG
#include "nest/bird.h"
#include "nest/route.h"
#include "nest/protocol.h"
#include "nest/iface.h"
#include "lib/timer.h"
#include "lib/unix.h"
#include "lib/krt.h"
#include "lib/string.h"
static int krt_scan_fd = -1;
struct iface *
krt_temp_iface(struct krt_proto *p, char *name)
{
struct iface *i;
WALK_LIST(i, p->scan.temp_ifs)
if (!strcmp(i->name, name))
return i;
i = mb_allocz(p->p.pool, sizeof(struct iface));
strcpy(i->name, name);
add_tail(&p->scan.temp_ifs, &i->n);
return i;
}
void
krt_scan_construct(struct krt_config *c)
{
}
void
krt_scan_preconfig(struct config *c)
{
}
void
krt_scan_postconfig(struct krt_config *c)
{
}
void
krt_scan_start(struct krt_proto *x, int first)
{
init_list(&x->scan.temp_ifs);
}
void
krt_scan_shutdown(struct krt_proto *x, int last)
{
}
void
krt_sysctl_scan(struct proto *p, pool *pool, byte **buf, int *bl, int cmd)
{
byte *next;
int obl, needed, mib[6], on;
struct ks_msg *m;
mib[0] = CTL_NET;
mib[1] = PF_ROUTE;
mib[2] = 0;
mib[3] = BIRD_PF;
mib[4] = cmd;
mib[5] = 0;
if( sysctl(mib, 6 , NULL , &needed, NULL, 0) < 0)
{
die("RT scan...");
}
obl = *bl;
while(needed > *bl) *bl *= 2;
while(needed < (*bl/2)) *bl /= 2;
if( (obl!=*bl) || !*buf)
{
if(*buf) mb_free(*buf);
if( (*buf = mb_alloc(pool, *bl)) == NULL ) die("RT scan buf alloc");
}
on = needed;
if( sysctl(mib, 6 , *buf, &needed, NULL, 0) < 0)
{
if(on != needed) return; /* The buffer size changed since last sysctl */
die("RT scan 2");
}
for (next = *buf; next < (*buf + needed); next += m->rtm.rtm_msglen)
{
m = (struct ks_msg *)next;
krt_read_msg(p, m, 1);
}
}
void
krt_scan_fire(struct krt_proto *p)
{
static byte *buf = NULL;
static int bl = 32768;
krt_sysctl_scan((struct proto *)p , p->krt_pool, &buf, &bl, NET_RT_DUMP);
}
void
krt_if_scan(struct kif_proto *p)
{
static byte *buf = NULL;
static int bl = 4096;
struct proto *P = (struct proto *)p;
if_start_update();
krt_sysctl_scan(P, P->pool, &buf, &bl, NET_RT_IFLIST);
if_end_update();
}
/*
* BIRD -- *BSD Kernel Route Syncer -- Scanning
*
* (c) 2004 Ondrej Filip <feela@network.cz>
*
* Can be freely distributed and used under the terms of the GNU GPL.
*/
#ifndef _BIRD_KRT_SCAN_H_
#define _BIRD_KRT_SCAN_H_
struct krt_scan_params {
};
struct krt_scan_status {
list temp_ifs; /* Temporary interfaces */
};
static inline int krt_scan_params_same(struct krt_scan_params *o, struct krt_scan_params *n) { return 1; }
#endif
/*
* BIRD -- Unix Kernel Socket Route Syncer -- Dummy Include File
*
* (c) 2004 Ondrej Filip <feela@network.cz>
*
* Can be freely distributed and used under the terms of the GNU GPL.
*/
#ifndef _BIRD_KRT_SET_H_
#define _BIRD_KRT_SET_H_
/*
* We don't have split iface/scan/set parts. See krt-sock.h.
*/
#include "lib/krt-sock.h"
#endif
This diff is collapsed.
/*
* BIRD -- Unix Kernel Route Syncer -- Setting
*
* (c) 2004 Ondrej Filip <feela@network.cz>
*
* Can be freely distributed and used under the terms of the GNU GPL.
*/
#ifndef _BIRD_KRT_SOCK_H_
#define _BIRD_KRT_SOCK_H_
#include <sys/socket.h>
#include <net/route.h>
#include "lib/socket.h"
#ifndef RTAX_MAX
#define RTAX_MAX 8
#endif
struct ks_msg
{
struct rt_msghdr rtm;
struct sockaddr_storage buf[RTAX_MAX];
};
extern int krt_set_sock;
struct krt_set_params {
};
struct krt_set_status {
};
struct krt_if_params {
};
struct krt_if_status {
};
static int krt_set_hook(sock *sk, int size);
static inline int krt_set_params_same(struct krt_set_params *o, struct krt_set_params *n) { return 1; }
void krt_read_msg(struct proto *p, struct ks_msg *msg, int scan);
#endif
/*
* BIRD Internet Routing Daemon -- NetBSD Multicasting and Network Includes
*
* (c) 2004 Ondrej Filip <feela@network.cz>
*
* Can be freely distributed and used under the terms of the GNU GPL.
*/
#ifdef IPV6
static inline void
set_inaddr(struct in6_addr * ia, ip_addr a)
{
ipa_hton(a);
memcpy(ia, &a, sizeof(a));
}
#else
#include <net/if.h>
static inline void
set_inaddr(struct in_addr * ia, ip_addr a)
{
ipa_hton(a);
memcpy(&ia->s_addr, &a, sizeof(a));
}
static inline char *
sysio_mcast_setup(sock * s)
{
u8 zero = 0;
u8 one = 1;
if (ipa_nonzero(s->daddr)) {
if (setsockopt(s->fd, IPPROTO_IP, IP_MULTICAST_LOOP, &zero, sizeof(zero)) < 0) {
log("IP_MULTICAST_LOOP");
return "IP_MULTICAST_LOOP";
}
if (setsockopt(s->fd, IPPROTO_IP, IP_MULTICAST_TTL, &one, sizeof(one)) < 0) {
log("IP_MULTICAST_TTL");
return "IP_MULTICAST_TTL";
}
}
return NULL;
}
static inline char *
sysio_mcast_join(sock * s)
{
struct in_addr m;
struct ip_mreq mreq;
char *err;
set_inaddr(&m, s->iface->addr->ip );
memset(&mreq, 0, sizeof(mreq));
set_inaddr(&mreq.imr_interface, s->iface->addr->ip);
set_inaddr(&mreq.imr_multiaddr, s->daddr);
/* And this one sets interface for _receiving_ multicasts from */
if (ipa_nonzero(s->daddr) && setsockopt(s->fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) {
log("IP_ADD_MEMBERSHIP");
return "IP_ADD_MEMBERSHIP";
}
/* This defines where should we send _outgoing_ multicasts */
if (ipa_nonzero(s->daddr) && setsockopt(s->fd, IPPROTO_IP, IP_MULTICAST_IF, &m, sizeof(m)) < 0) {
log("IP_MULTICAST_IF");
return "IP_MULTICAST_IF";
}
if (err = sysio_mcast_setup(s))
return err;
return NULL;
}
#endif
/*
* Configuration for *BSD based systems (tested on FreeBSD and NetBSD)
*
* (c) 2004 Ondrej Filip <feela@network.cz>
*
* Can be freely distributed and used under the terms of the GNU GPL.
*/
#define IPV6
#define CONFIG_AUTO_ROUTES
#undef CONFIG_SELF_CONSCIOUS
#undef CONFIG_MULTIPLE_TABLES
#undef CONFIG_UNIX_IFACE
#undef CONFIG_UNIX_SET
#define CONFIG_ALL_MULTICAST
#define CONFIG_UNNUM_MULTICAST
/*
Link: sysdep/unix
Link: sysdep/bsd
*/
/*
* Configuration for *BSD based systems (tested on FreeBSD and NetBSD)
*
* (c) 2004 Ondrej Filip <feela@network.cz>
*
* Can be freely distributed and used under the terms of the GNU GPL.
*/
#define CONFIG_AUTO_ROUTES
#undef CONFIG_SELF_CONSCIOUS
#undef CONFIG_MULTIPLE_TABLES
#undef CONFIG_UNIX_IFACE
#undef CONFIG_UNIX_SET
#define CONFIG_ALL_MULTICAST
#define CONFIG_UNNUM_MULTICAST
/*
Link: sysdep/unix
Link: sysdep/bsd
*/
......@@ -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;
}
......
......@@ -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");
}
......@@ -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:
......
......@@ -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"
......
......@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment