Removed tunnel route function stubs. Added clear screen function.
[olsrd.git] / src / bsd / kernel_routes.c
1 /*
2  * OLSR ad-hoc routing table management protocol
3  * Copyright (C) 2004 Thomas Lopatic (thomas@lopatic.de)
4  *
5  * This file is part of olsr.org.
6  *
7  * olsr.org is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * olsr.org is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with olsr.org; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  * 
21  * 
22  * $Id: kernel_routes.c,v 1.3 2004/11/20 15:40:52 tlopatic Exp $
23  *
24  */
25
26 #include "../kernel_routes.h"
27 #include "../olsr.h"
28
29 #include <net/if_dl.h>
30 #include <ifaddrs.h>
31
32 static unsigned int seq = 0;
33
34 static int add_del_route(struct rt_entry *dest, int add)
35 {
36   struct rt_msghdr *rtm;
37   unsigned char buff[512];
38   unsigned char *walker;
39   struct sockaddr_in sin;
40   struct sockaddr_dl *sdl;
41   struct ifaddrs *addrs;
42   struct ifaddrs *awalker;
43   int step, step2;
44   int len;
45   char Str1[16], Str2[16], Str3[16];
46   int flags;
47
48   inet_ntop(AF_INET, &dest->rt_dst.v4, Str1, 16);
49   inet_ntop(AF_INET, &dest->rt_mask.v4, Str2, 16);
50   inet_ntop(AF_INET, &dest->rt_router.v4, Str3, 16);
51
52   olsr_printf(1, "%s IPv4 route to %s/%s via %s.\n",
53     (add != 0) ? "Adding" : "Removing", Str1, Str2, Str3);
54
55   memset(buff, 0, sizeof (buff));
56   memset(&sin, 0, sizeof (sin));
57
58   sin.sin_len = sizeof (sin);
59   sin.sin_family = AF_INET;
60
61   step = 1 + ((sizeof (struct sockaddr_in) - 1) | 3);
62   step2 = 1 + ((sizeof (struct sockaddr_dl) - 1) | 3);
63
64   rtm = (struct rt_msghdr *)buff;
65
66   flags = dest->rt_flags;
67
68   // the host is directly reachable, so use cloning and a /32 net
69   // routing table entry
70
71   if ((flags & RTF_GATEWAY) == 0)
72   {
73     flags |= RTF_CLONING;
74     flags &= ~RTF_HOST;
75   }
76
77   rtm->rtm_version = RTM_VERSION;
78   rtm->rtm_type = (add != 0) ? RTM_ADD : RTM_DELETE;
79   rtm->rtm_index = 0;
80   rtm->rtm_flags = flags;
81   rtm->rtm_addrs = RTA_DST | RTA_NETMASK | RTA_GATEWAY;
82   rtm->rtm_seq = ++seq;
83
84   walker = buff + sizeof (struct rt_msghdr);
85
86   sin.sin_addr.s_addr = dest->rt_dst.v4;
87
88   memcpy(walker, &sin, sizeof (sin));
89   walker += step;
90
91   if ((flags & RTF_GATEWAY) != 0)
92   {
93     sin.sin_addr.s_addr = dest->rt_router.v4;
94
95     memcpy(walker, &sin, sizeof (sin));
96     walker += step;
97   }
98
99   // the host is directly reachable, so add the output interface's
100   // MAC address
101
102   else
103   {
104     if (getifaddrs(&addrs))
105     {
106       fprintf(stderr, "getifaddrs() failed\n");
107       return -1;
108     }
109
110     for (awalker = addrs; awalker != NULL; awalker = awalker->ifa_next)
111       if (awalker->ifa_addr->sa_family == AF_LINK &&
112           strcmp(awalker->ifa_name, dest->rt_if->int_name) == 0)
113         break;
114
115     if (awalker == NULL)
116     {
117       fprintf(stderr, "interface %s not found\n", dest->rt_if->int_name);
118       freeifaddrs(addrs);
119       return -1;
120     }
121
122     sdl = (struct sockaddr_dl *)awalker->ifa_addr;
123
124     memcpy(walker, sdl, sdl->sdl_len);
125     walker += step2;
126
127     freeifaddrs(addrs);
128   }
129
130   sin.sin_addr.s_addr = dest->rt_mask.v4;
131
132   memcpy(walker, &sin, sizeof (sin));
133   walker += step;
134
135   rtm->rtm_msglen = (unsigned short)(walker - buff);
136
137   len = write(rts, buff, rtm->rtm_msglen);
138
139   if (len < rtm->rtm_msglen)
140     fprintf(stderr, "cannot write to routing socket: %s\n", strerror(errno));
141
142   return 0;
143 }
144
145 int olsr_ioctl_add_route(struct rt_entry *dest)
146 {
147   return add_del_route(dest, 1);
148 }
149
150 int olsr_ioctl_del_route(struct rt_entry *dest)
151 {
152   return add_del_route(dest, 0);
153 }
154
155 int olsr_ioctl_add_route6(struct rt_entry *dest)
156 {
157   return 0;
158 }
159
160 int olsr_ioctl_del_route6(struct rt_entry *dest)
161 {
162   return 0;
163 }