aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Makefile.am2
-rw-r--r--lib/tun.c91
-rw-r--r--lib/tun6.c96
3 files changed, 101 insertions, 88 deletions
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 632990c..6eb2a0f 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -4,4 +4,4 @@ noinst_HEADERS = gnugetopt.h ippool.h lookup.h syserr.h tun.h in46_addr.h
AM_CFLAGS = -O2 -fno-builtin -Wall -DSBINDIR='"$(sbindir)"' -ggdb $(LIBOSMOCORE_CFLAGS)
-libmisc_a_SOURCES = getopt1.c getopt.c ippool.c lookup.c tun.c debug.c in46_addr.c
+libmisc_a_SOURCES = getopt1.c getopt.c ippool.c lookup.c tun.c tun6.c debug.c in46_addr.c
diff --git a/lib/tun.c b/lib/tun.c
index d8e4b62..4052672 100644
--- a/lib/tun.c
+++ b/lib/tun.c
@@ -61,9 +61,6 @@
#include "syserr.h"
#if defined(__linux__)
-
-#include <linux/ipv6.h>
-
static int tun_nlattr(struct nlmsghdr *n, int nsize, int type, void *d, int dlen)
{
int len = RTA_LENGTH(dlen);
@@ -79,7 +76,7 @@ static int tun_nlattr(struct nlmsghdr *n, int nsize, int type, void *d, int dlen
}
#endif
-static int tun_sifflags(struct tun_t *this, int flags)
+int tun_sifflags(struct tun_t *this, int flags)
{
struct ifreq ifr;
int fd;
@@ -197,89 +194,9 @@ static int tun_setaddr4(struct tun_t *this, struct in_addr *addr,
return 0;
}
-static int tun_setaddr6(struct tun_t *this, struct in6_addr *addr, struct in6_addr *dstaddr,
- size_t prefixlen)
-{
- struct in6_ifreq ifr;
- int fd;
-
- memset(&ifr, 0, sizeof(ifr));
-
-#if defined(__linux__)
- ifr.ifr6_prefixlen = prefixlen;
- ifr.ifr6_ifindex = if_nametoindex(this->devname);
- if (ifr.ifr6_ifindex == 0) {
- SYS_ERR(DTUN, LOGL_ERROR, 0, "Error getting ifindex for %s\n", this->devname);
- return -1;
- }
-#elif defined(__FreeBSD__) || defined (__APPLE__)
- strncpy(ifr.ifr_name, this->devname, IFNAMSIZ);
-#endif
-
- /* Create a channel to the NET kernel */
- if ((fd = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
- SYS_ERR(DTUN, LOGL_ERROR, 0, "socket() failed");
- return -1;
- }
-
-#if defined(__linux__)
- if (addr) {
- memcpy(&ifr.ifr6_addr, addr, sizeof(*addr));
- if (ioctl(fd, SIOCSIFADDR, (void *) &ifr) < 0) {
- if (errno != EEXIST) {
- SYS_ERR(DTUN, LOGL_ERROR, 0, "ioctl(SIOCSIFADDR) failed");
- } else {
- SYS_ERR(DTUN, LOGL_NOTICE, 0, "ioctl(SIOCSIFADDR): Address already exists");
- }
- close(fd);
- return -1;
- }
- }
-
-#if 0
- /* FIXME: looks like this is not possible/necessary for IPv6? */
- if (dstaddr) {
- memcpy(&this->dstaddr, dstaddr, sizeof(*dstaddr));
- memcpy(&ifr.ifr6_addr, dstaddr, sizeof(*dstaddr));
- if (ioctl(fd, SIOCSIFDSTADDR, (caddr_t *) &ifr) < 0) {
- SYS_ERR(DTUN, LOGL_ERROR, "ioctl(SIOCSIFDSTADDR) failed");
- close(fd);
- return -1;
- }
- }
-#endif
-
-#elif defined(__FreeBSD__) || defined (__APPLE__)
- if (addr)
- memcpy(&ifr.ifr_ifru.ifru_addr, addr, sizeof(ifr.ifr_ifru.ifru_addr));
- if (dstaddr)
- memcpy(&ifr.ifr_ifru.ifru_dstaddr, dstaddr, sizeof(ifr.ifr_ifru.ifru_dstaddr));
-
- if (ioctl(fd, SIOCSIFADDR_IN6, (struct ifreq *)&ifr) < 0) {
- SYS_ERR(DTUN, LOGL_ERROR, 0, "ioctl(SIOCSIFADDR_IN6) failed");
- close(fd);
- return -1;
- }
-#endif
-
- close(fd);
- this->addrs++;
-
- /* On linux the route to the interface is set automatically
- on FreeBSD we have to do this manually */
-
- /* TODO: How does it work on Solaris? */
-
- tun_sifflags(this, IFF_UP | IFF_RUNNING);
-
-#if 0 /* FIXME */
-//#if defined(__FreeBSD__) || defined (__APPLE__)
- tun_addroute6(this, dstaddr, addr, prefixlen);
- this->routes = 1;
-#endif
-
- return 0;
-}
+/* Implemented in tun6.c due to include issues between ip6.h/in6.h and in.h in some systems */
+int tun_setaddr6(struct tun_t *this, struct in6_addr *addr, struct in6_addr *dstaddr,
+ size_t prefixlen);
int tun_setaddr(struct tun_t *this, struct in46_addr *addr, struct in46_addr *dstaddr, size_t prefixlen)
{
diff --git a/lib/tun6.c b/lib/tun6.c
new file mode 100644
index 0000000..85139e5
--- /dev/null
+++ b/lib/tun6.c
@@ -0,0 +1,96 @@
+#include <unistd.h>
+#include <string.h>
+#include <stropts.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <linux/ipv6.h>
+
+#include "tun.h"
+#include "syserr.h"
+
+/* Defined in tun.c */
+int tun_sifflags(struct tun_t *this, int flags);
+
+int tun_setaddr6(struct tun_t *this, struct in6_addr *addr, struct in6_addr *dstaddr,
+ size_t prefixlen)
+{
+ struct in6_ifreq ifr;
+ int fd;
+
+ memset(&ifr, 0, sizeof(ifr));
+
+#if defined(__linux__)
+ ifr.ifr6_prefixlen = prefixlen;
+ ifr.ifr6_ifindex = if_nametoindex(this->devname);
+ if (ifr.ifr6_ifindex == 0) {
+ SYS_ERR(DTUN, LOGL_ERROR, 0, "Error getting ifindex for %s\n", this->devname);
+ return -1;
+ }
+#elif defined(__FreeBSD__) || defined (__APPLE__)
+ strncpy(ifr.ifr_name, this->devname, IFNAMSIZ);
+#endif
+
+ /* Create a channel to the NET kernel */
+ if ((fd = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
+ SYS_ERR(DTUN, LOGL_ERROR, 0, "socket() failed");
+ return -1;
+ }
+
+#if defined(__linux__)
+ if (addr) {
+ memcpy(&ifr.ifr6_addr, addr, sizeof(*addr));
+ if (ioctl(fd, SIOCSIFADDR, (void *) &ifr) < 0) {
+ if (errno != EEXIST) {
+ SYS_ERR(DTUN, LOGL_ERROR, 0, "ioctl(SIOCSIFADDR) failed");
+ } else {
+ SYS_ERR(DTUN, LOGL_NOTICE, 0, "ioctl(SIOCSIFADDR): Address already exists");
+ }
+ close(fd);
+ return -1;
+ }
+ }
+
+#if 0
+ /* FIXME: looks like this is not possible/necessary for IPv6? */
+ if (dstaddr) {
+ memcpy(&this->dstaddr, dstaddr, sizeof(*dstaddr));
+ memcpy(&ifr.ifr6_addr, dstaddr, sizeof(*dstaddr));
+ if (ioctl(fd, SIOCSIFDSTADDR, (caddr_t *) &ifr) < 0) {
+ SYS_ERR(DTUN, LOGL_ERROR, "ioctl(SIOCSIFDSTADDR) failed");
+ close(fd);
+ return -1;
+ }
+ }
+#endif
+
+#elif defined(__FreeBSD__) || defined (__APPLE__)
+ if (addr)
+ memcpy(&ifr.ifr_ifru.ifru_addr, addr, sizeof(ifr.ifr_ifru.ifru_addr));
+ if (dstaddr)
+ memcpy(&ifr.ifr_ifru.ifru_dstaddr, dstaddr, sizeof(ifr.ifr_ifru.ifru_dstaddr));
+
+ if (ioctl(fd, SIOCSIFADDR_IN6, (struct ifreq *)&ifr) < 0) {
+ SYS_ERR(DTUN, LOGL_ERROR, 0, "ioctl(SIOCSIFADDR_IN6) failed");
+ close(fd);
+ return -1;
+ }
+#endif
+
+ close(fd);
+ this->addrs++;
+
+ /* On linux the route to the interface is set automatically
+ on FreeBSD we have to do this manually */
+
+ /* TODO: How does it work on Solaris? */
+
+ tun_sifflags(this, IFF_UP | IFF_RUNNING);
+
+#if 0 /* FIXME */
+//#if defined(__FreeBSD__) || defined (__APPLE__)
+ tun_addroute6(this, dstaddr, addr, prefixlen);
+ this->routes = 1;
+#endif
+
+ return 0;
+}