aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjjako <jjako>2004-01-27 19:47:49 +0000
committerjjako <jjako>2004-01-27 19:47:49 +0000
commit3eaf453e06109e6117ce95dfb3c0fd37f5dc0471 (patch)
treeac18b8da312384138910eb6efbf6f0f63c2b1e9e
parent243bfe643f4ebd0e6437540e540cd4543e594676 (diff)
FreeBSD route
-rw-r--r--ggsn/tun.c63
1 files changed, 63 insertions, 0 deletions
diff --git a/ggsn/tun.c b/ggsn/tun.c
index 06397d1..66ba4c4 100644
--- a/ggsn/tun.c
+++ b/ggsn/tun.c
@@ -461,6 +461,69 @@ int tun_addroute(struct tun_t *this,
}
close(fd);
+#elif defined(__FreeBSD__)
+
+struct my_rt
+{
+ struct rt_msghdr rt;
+ struct sockaddr_in dst;
+ struct sockaddr_in gate;
+ struct sockaddr_in mask;
+} my_rt;
+
+ int s;
+ 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));
+
+ rtm = &my_rt.rt;
+
+ dst = &my_rt.dst;
+ gate = &my_rt.gate;
+ mask = &my_rt.mask;
+
+ 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();
+
+ 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;
+
#endif
return 0;