aboutsummaryrefslogtreecommitdiffstats
path: root/ggsn
diff options
context:
space:
mode:
authorjjako <jjako>2004-01-28 09:27:34 +0000
committerjjako <jjako>2004-01-28 09:27:34 +0000
commit1ea66348518ad1d438ea14bc7a16244bbb49b9a0 (patch)
tree7811c242f39999321b4efd8c0fcacbda8bc511f3 /ggsn
parent3eaf453e06109e6117ce95dfb3c0fd37f5dc0471 (diff)
Added FreeBSD route capability
Diffstat (limited to 'ggsn')
-rw-r--r--ggsn/tun.c100
1 files changed, 49 insertions, 51 deletions
diff --git a/ggsn/tun.c b/ggsn/tun.c
index 66ba4c4..a19fd5b 100644
--- a/ggsn/tun.c
+++ b/ggsn/tun.c
@@ -421,7 +421,17 @@ int tun_setaddr(struct tun_t *this,
close(fd);
this->addrs++;
- return tun_sifflags(this, IFF_UP | IFF_RUNNING);
+
+ /* On linux the route to the interface is set automatically
+ on FreeBSD we have to do this manually */
+
+#if defined(__FreeBSD__)
+ tun_sifflags(this, IFF_UP | IFF_RUNNING); /* TODO */
+ return tun_addroute(this, addr, addr, netmask);
+#else
+ return tun_sifflags(this, IFF_UP | IFF_RUNNING);
+#endif
+
}
int tun_addroute(struct tun_t *this,
@@ -430,7 +440,8 @@ int tun_addroute(struct tun_t *this,
struct in_addr *mask)
{
- /* TODO: Learn how to set routing table on sun and FreeBSD */
+
+ /* TODO: Learn how to set routing table on sun */
#ifdef __linux__
struct rtentry r;
@@ -463,67 +474,53 @@ int tun_addroute(struct tun_t *this,
#elif defined(__FreeBSD__)
-struct my_rt
-{
- struct rt_msghdr rt;
- struct sockaddr_in dst;
- struct sockaddr_in gate;
- struct sockaddr_in mask;
-} my_rt;
+struct {
+ struct rt_msghdr rt;
+ struct sockaddr_in dst;
+ struct sockaddr_in gate;
+ struct sockaddr_in mask;
+} req;
- int s;
+ int fd;
struct rt_msghdr *rtm;
- struct sockaddr_in *dst, *gate, *mask;
-
- if((s = socket(AF_ROUTE, SOCK_RAW, 0)) == -1)
- {
- sys_err(LOG_ERR, __FILE__, __LINE__, errno,
- "socket() failed");
- return -1;
- }
- memset(&my_rt, 0x00, sizeof(my_rt));
+ if((fd = socket(AF_ROUTE, SOCK_RAW, 0)) == -1) {
+ sys_err(LOG_ERR, __FILE__, __LINE__, errno,
+ "socket() failed");
+ return -1;
+ }
- rtm = &my_rt.rt;
+ memset(&req, 0x00, sizeof(req));
- dst = &my_rt.dst;
- gate = &my_rt.gate;
- mask = &my_rt.mask;
+ rtm = &req.rt;
+ rtm->rtm_msglen = sizeof(req);
+ rtm->rtm_version = RTM_VERSION;
rtm->rtm_type = RTM_ADD;
rtm->rtm_flags = RTF_UP | RTF_GATEWAY | RTF_STATIC; /* TODO */
- rtm->rtm_msglen = sizeof(my_rt);
- rtm->rtm_version = RTM_VERSION;
- rtm->rtm_seq = 1234; /* TODO */
rtm->rtm_addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK;
rtm->rtm_pid = getpid();
+ rtm->rtm_seq = 0044; /* TODO */
- dst->sin_family = AF_INET;
- dst->sin_len = sizeof(*dst);
- dst->sin_addr.s_addr = dst->s_addr;
-
- mask->sin_family = AF_INET;
- mask->sin_len = sizeof(*mask);
- mask->sin_addr.s_addr = mask->s_addr;
-
- gate->sin_family = AF_INET;
- gate->sin_len = sizeof(*gate);
- gate->sin_addr.s_addr = gateway->s_addr;
-
- AGAIN:
- if(write(s, rtm, rtm->rtm_msglen) < 0)
- {
- if(errno == EEXIST && rtm->rtm_type == RTM_ADD)
- {
- rtm->rtm_type = RTM_CHANGE;
- goto AGAIN;
- }
- sys_err(LOG_ERR, __FILE__, __LINE__, errno,
- "write() failed");
- return -1;
- }
- return 0;
+ req.dst.sin_family = AF_INET;
+ req.dst.sin_len = sizeof(req.dst);
+ req.mask.sin_family = AF_INET;
+ req.mask.sin_len = sizeof(req.mask);
+ req.gate.sin_family = AF_INET;
+ req.gate.sin_len = sizeof(req.gate);
+
+ req.dst.sin_addr.s_addr = dst->s_addr;
+ req.mask.sin_addr.s_addr = mask->s_addr;
+ req.gate.sin_addr.s_addr = gateway->s_addr;
+ if(write(fd, rtm, rtm->rtm_msglen) < 0) {
+ sys_err(LOG_ERR, __FILE__, __LINE__, errno,
+ "write() failed");
+ close(fd);
+ return -1;
+ }
+ close(fd);
+
#endif
return 0;
@@ -636,6 +633,7 @@ int tun_new(struct tun_t **tun)
snprintf((*tun)->devname, sizeof((*tun)->devname), "tun%d", devnum);
(*tun)->devname[sizeof((*tun)->devname)] = 0;
+
#endif
return 0;