From 163b455be869f6aef36f2fedf6913e1a38d64ad5 Mon Sep 17 00:00:00 2001 From: jjako Date: Thu, 30 Dec 2004 15:33:58 +0000 Subject: Fixed delete route on freebsd et. al. --- sgsnemu/tun.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++------------- sgsnemu/tun.h | 1 + 2 files changed, 57 insertions(+), 16 deletions(-) (limited to 'sgsnemu') diff --git a/sgsnemu/tun.c b/sgsnemu/tun.c index 576e32e..365aec0 100644 --- a/sgsnemu/tun.c +++ b/sgsnemu/tun.c @@ -492,19 +492,21 @@ int tun_setaddr(struct tun_t *this, /* TODO: How does it work on Solaris? */ + tun_sifflags(this, IFF_UP | IFF_RUNNING); + #if defined(__FreeBSD__) || defined (__APPLE__) - tun_sifflags(this, IFF_UP | IFF_RUNNING); /* TODO */ - return tun_addroute(this, addr, addr, netmask); -#else - return tun_sifflags(this, IFF_UP | IFF_RUNNING); + tun_addroute(this, dstaddr, addr, netmask); + this->routes = 1; #endif + return 0; } -int tun_addroute(struct tun_t *this, - struct in_addr *dst, - struct in_addr *gateway, - struct in_addr *mask) +int tun_route(struct tun_t *this, + struct in_addr *dst, + struct in_addr *gateway, + struct in_addr *mask, + int delete) { @@ -531,16 +533,26 @@ int tun_addroute(struct tun_t *this, ((struct sockaddr_in *) &r.rt_dst)->sin_addr.s_addr = dst->s_addr; ((struct sockaddr_in *) &r.rt_gateway)->sin_addr.s_addr = gateway->s_addr; ((struct sockaddr_in *) &r.rt_genmask)->sin_addr.s_addr = mask->s_addr; - - if (ioctl(fd, SIOCADDRT, (void *) &r) < 0) { /* SIOCDELRT */ - sys_err(LOG_ERR, __FILE__, __LINE__, errno, - "ioctl(SIOCADDRT) failed"); - close(fd); - return -1; + + if (delete) { + if (ioctl(fd, SIOCDELRT, (void *) &r) < 0) { + sys_err(LOG_ERR, __FILE__, __LINE__, errno, + "ioctl(SIOCDELRT) failed"); + close(fd); + return -1; + } + } + else { + if (ioctl(fd, SIOCADDRT, (void *) &r) < 0) { + sys_err(LOG_ERR, __FILE__, __LINE__, errno, + "ioctl(SIOCADDRT) failed"); + close(fd); + return -1; + } } close(fd); return 0; - + #elif defined(__FreeBSD__) || defined (__APPLE__) struct { @@ -565,7 +577,12 @@ struct { rtm->rtm_msglen = sizeof(req); rtm->rtm_version = RTM_VERSION; - rtm->rtm_type = RTM_ADD; + if (delete) { + rtm->rtm_type = RTM_DELETE; + } + else { + rtm->rtm_type = RTM_ADD; + } rtm->rtm_flags = RTF_UP | RTF_GATEWAY | RTF_STATIC; /* TODO */ rtm->rtm_addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK; rtm->rtm_pid = getpid(); @@ -602,6 +619,23 @@ struct { } +int tun_addroute(struct tun_t *this, + struct in_addr *dst, + struct in_addr *gateway, + struct in_addr *mask) +{ + return tun_route(this, dst, gateway, mask, 0); +} + +int tun_delroute(struct tun_t *this, + struct in_addr *dst, + struct in_addr *gateway, + struct in_addr *mask) +{ + return tun_route(this, dst, gateway, mask, 1); +} + + int tun_new(struct tun_t **tun) { @@ -631,6 +665,7 @@ int tun_new(struct tun_t **tun) (*tun)->cb_ind = NULL; (*tun)->addrs = 0; + (*tun)->routes = 0; #if defined(__linux__) /* Open the actual tun device */ @@ -761,6 +796,11 @@ int tun_new(struct tun_t **tun) int tun_free(struct tun_t *tun) { + + if (tun->routes) { + tun_delroute(tun, &tun->dstaddr, &tun->addr, &tun->netmask); + } + if (close(tun->fd)) { sys_err(LOG_ERR, __FILE__, __LINE__, errno, "close() failed"); } diff --git a/sgsnemu/tun.h b/sgsnemu/tun.h index eb82162..7972c53 100644 --- a/sgsnemu/tun.h +++ b/sgsnemu/tun.h @@ -44,6 +44,7 @@ struct tun_t { struct in_addr dstaddr; struct in_addr netmask; int addrs; /* Number of allocated IP addresses */ + int routes; /* One if we allocated an automatic route */ char devname[IFNAMSIZ];/* Name of the tun device */ int (*cb_ind) (struct tun_t *tun, void *pack, unsigned len); }; -- cgit v1.2.3