struct tun {
struct netlink nl;
int fd;
- string_t device_path;
- string_t ip_path;
+ cstring_t device_path;
+ cstring_t ip_path;
string_t interface_name;
- string_t ifconfig_path;
+ cstring_t ifconfig_path;
uint32_t ifconfig_type;
- string_t route_path;
+ cstring_t route_path;
uint32_t route_type;
uint32_t tun_flavour;
bool_t search_for_if; /* Applies to tun-BSD only */
uint32_t local_address; /* host interface address */
};
-static string_t tun_flavour_str(uint32_t flavour)
+static cstring_t tun_flavour_str(uint32_t flavour)
{
switch (flavour) {
case TUN_FLAVOUR_GUESS: return "guess";
}
static int tun_beforepoll(void *sst, struct pollfd *fds, int *nfds_io,
- int *timeout_io, const struct timeval *tv_now,
- uint64_t *now)
+ int *timeout_io)
{
struct tun *st=sst;
*nfds_io=1;
fds[0].fd=st->fd;
- fds[0].events=POLLIN|POLLERR|POLLHUP;
+ fds[0].events=POLLIN;
return 0;
}
-static void tun_afterpoll(void *sst, struct pollfd *fds, int nfds,
- const struct timeval *tv_now, uint64_t *now)
+static void tun_afterpoll(void *sst, struct pollfd *fds, int nfds)
{
struct tun *st=sst;
int l;
fatal_perror("tun_afterpoll: read()");
}
if (l==0) {
- fatal("tun_afterpoll: read()=0; device gone away?\n");
+ fatal("tun_afterpoll: read()=0; device gone away?");
}
if (l>0) {
st->buff->size=l;
struct tun *st=sst;
string_t network, mask, secnetaddr;
struct subnet_list *nets;
- uint32_t i;
+ int32_t i;
int fd=-1;
if (routes->up == routes->kup) return False;
break;
case TUN_CONFIG_IOCTL:
{
-#ifdef HAVE_NET_ROUTE_H
+ /* darwin rtentry has a different format, use /sbin/route instead */
+#if HAVE_NET_ROUTE_H && ! __APPLE__
struct rtentry rt;
struct sockaddr_in *sa;
int action;
fatal_perror("tun_set_route: ioctl()");
}
#else
- fatal("tun_set_route: ioctl method not supported\n");
+ fatal("tun_set_route: ioctl method not supported");
#endif
}
break;
default:
- fatal("tun_set_route: unsupported route command type\n");
+ fatal("tun_set_route: unsupported route command type");
break;
}
free(network); free(mask);
{
struct tun *st=sst;
string_t hostaddr,secnetaddr;
- uint8_t mtu[6];
+ char mtu[6];
struct netlink_client *r;
if (st->tun_flavour==TUN_FLAVOUR_BSD) {
}
}
if (st->fd==-1) {
- fatal("%s: unable to open any TUN device (%s...)\n",
+ fatal("%s: unable to open any TUN device (%s...)",
st->nl.name,st->device_path);
}
} else {
st->interface_name);
}
#else
- fatal("tun_phase_hook: TUN_FLAVOUR_LINUX unexpected\n");
+ fatal("tun_phase_hook: TUN_FLAVOUR_LINUX unexpected");
#endif /* LINUX_TUN_SUPPORTED */
} else if (st->tun_flavour==TUN_FLAVOUR_STREAMS) {
#ifdef HAVE_TUN_STREAMS
sprintf(st->interface_name,"tun%d",ppa);
st->fd=tun_fd;
#else
- fatal("tun_phase_hook: TUN_FLAVOUR_STREAMS unexpected\n");
+ fatal("tun_phase_hook: TUN_FLAVOUR_STREAMS unexpected");
#endif /* HAVE_TUN_STREAMS */
} else {
- fatal("tun_phase_hook: unknown flavour of TUN\n");
+ fatal("tun_phase_hook: unknown flavour of TUN");
}
/* All the networks we'll be using have been registered. Invoke ifconfig
to set the TUN device's address, and route to add routes to all
hostaddr=ipaddr_to_string(st->local_address);
secnetaddr=ipaddr_to_string(st->nl.secnet_address);
- snprintf(mtu,6,"%d",st->nl.mtu);
+ snprintf(mtu,sizeof(mtu),"%d",st->nl.mtu);
mtu[5]=0;
- switch (st->route_type) {
+ switch (st->ifconfig_type) {
case TUN_CONFIG_LINUX:
sys_cmd(st->ifconfig_path,"ifconfig",st->interface_name,
hostaddr,"netmask","255.255.255.255","-broadcast",
hostaddr,secnetaddr,"mtu",mtu,"up",(char *)0);
break;
case TUN_CONFIG_IOCTL:
-#ifdef HAVE_NET_IF_H
+#if HAVE_NET_IF_H && ! __APPLE__
{
int fd;
struct ifreq ifr;
close(fd);
}
#else
- fatal("tun_apply: ifconfig by ioctl() not supported\n");
+ fatal("tun_apply: ifconfig by ioctl() not supported");
#endif /* HAVE_NET_IF_H */
break;
default:
- fatal("tun_apply: unsupported ifconfig method\n");
+ fatal("tun_apply: unsupported ifconfig method");
break;
}
fatal_perror("tun_create: uname");
}
if (strcmp(u.sysname,"Linux")==0) {
- if (u.release[0]=='2' && u.release[1]=='.' && u.release[3]=='.') {
- if (u.release[2]=='2') st->tun_flavour=TUN_FLAVOUR_BSD;
- else if (u.release[2]=='4') st->tun_flavour=TUN_FLAVOUR_LINUX;
- }
+ st->tun_flavour=TUN_FLAVOUR_LINUX;
} else if (strcmp(u.sysname,"SunOS")==0) {
st->tun_flavour=TUN_FLAVOUR_STREAMS;
- } else if (strcmp(u.sysname,"FreeBSD")==0) {
+ } else if (strcmp(u.sysname,"FreeBSD")==0
+ || strcmp(u.sysname,"Darwin")==0) {
st->tun_flavour=TUN_FLAVOUR_BSD;
}
}
st->ifconfig_type=TUN_CONFIG_IOCTL;
break;
case TUN_FLAVOUR_BSD:
+#if __linux__
+ /* XXX on Linux we still want TUN_CONFIG_IOCTL. Perhaps we can
+ use this on BSD too. */
+ st->ifconfig_type=TUN_CONFIG_IOCTL;
+#else
st->ifconfig_type=TUN_CONFIG_BSD;
+#endif
break;
case TUN_FLAVOUR_STREAMS:
st->ifconfig_type=TUN_CONFIG_BSD;
return tun_create(self,loc,context,args,TUN_FLAVOUR_BSD);
}
-init_module tun_module;
void tun_module(dict_t *dict)
{
add_closure(dict,"tun",tun_apply);