#include "netlink.h"
#include <stdio.h>
#include <string.h>
+#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
}
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;
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;
static void tun_deliver_to_kernel(void *sst, struct buffer_if *buf)
{
struct tun *st=sst;
+ ssize_t rc;
BUF_ASSERT_USED(buf);
- /* No error checking, because we'd just throw the packet away
- anyway if it didn't work. */
- write(st->fd,buf->start,buf->size);
+
+ /* Log errors, so we can tell what's going on, but only once a
+ minute, so we don't flood the logs. Short writes count as
+ errors. */
+ rc = write(st->fd,buf->start,buf->size);
+ if(rc != buf->size) {
+ static struct timeval last_report;
+ if(tv_now_global.tv_sec >= last_report.tv_sec + 60) {
+ if(rc < 0)
+ Message(M_WARNING,
+ "failed to deliver packet to tun device: %s\n",
+ strerror(errno));
+ else
+ Message(M_WARNING,
+ "truncated packet delivered to tun device\n");
+ last_report = tv_now_global;
+ }
+ }
BUF_FREE(buf);
}
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->ifconfig_type) {
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