diff options
author | Ondrej Filip <feela@network.cz> | 2004-05-31 13:25:00 +0000 |
---|---|---|
committer | Ondrej Filip <feela@network.cz> | 2004-05-31 13:25:00 +0000 |
commit | b1a1fabac70201e9b05aeb9fd6af703f0fbffdb4 (patch) | |
tree | c03705e3b77b1fd2d39e2179eea9f85932f3af61 /sysdep/bsd/sysio.h | |
parent | 781aa475aaa7503d4a86f0d4b8771cd027d30c04 (diff) |
*BSD port added. (Tested on FreeBSD and NetBSD)
Diffstat (limited to 'sysdep/bsd/sysio.h')
-rw-r--r-- | sysdep/bsd/sysio.h | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/sysdep/bsd/sysio.h b/sysdep/bsd/sysio.h new file mode 100644 index 00000000..db69b97d --- /dev/null +++ b/sysdep/bsd/sysio.h @@ -0,0 +1,83 @@ +/* + * 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 |