1 /*
2 * The olsr.org Optimized Link-State Routing daemon (olsrd)
3 *
4 * (c) by the OLSR project
5 *
6 * See our Git repository to find out who worked on this file
7 * and thus is a copyright holder on it.
8 *
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 *
15 * * Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * * Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in
19 * the documentation and/or other materials provided with the
20 * distribution.
21 * * Neither the name of olsr.org, olsrd nor the names of its
22 * contributors may be used to endorse or promote products derived
23 * from this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
28 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
29 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
30 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
31 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
32 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
33 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
35 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
37 *
38 * Visit http://www.olsr.org for more information.
39 *
40 * If you find this software useful feel free to make a donation
41 * to the project. For more information see the website or contact
42 * the copyright holders.
43 *
44 */
45
46 #include "net_olsr.h"
47 #include "ipcalc.h"
48 #include "log.h"
49 #include "olsr.h"
50 #include "net_os.h"
51 #include "link_set.h"
52 #include "lq_packet.h"
53
54 #include <stdlib.h>
55 #include <assert.h>
56 #include <limits.h>
57
58 #ifdef _WIN32
59 #define perror(x) WinSockPError(x)
60 void WinSockPError(const char *);
61 #endif /* _WIN32 */
62
63 struct deny_address_entry {
64 union olsr_ip_addr addr;
65 struct deny_address_entry *next;
66 };
67
68 /* Packet transform functions */
69
70 struct ptf {
71 packet_transform_function function;
72 struct ptf *next;
73 };
74
75 static struct ptf *ptf_list;
76
77 static struct deny_address_entry *deny_entries;
78
79 static const char *const deny_ipv4_defaults[] = {
80 "0.0.0.0",
81 "127.0.0.1",
82 NULL
83 };
84
85 static const char *const deny_ipv6_defaults[] = {
86 "0::0",
87 "0::1",
88 NULL
89 };
90
91 /*
92 * Converts each invalid IP-address from string to network byte order
93 * and adds it to the invalid list.
94 *
95 * TODO: rename function
96 */
97 void
init_net(void)98 init_net(void)
99 {
100 const char *const *defaults = (olsr_cnf->ip_version == AF_INET) ? deny_ipv4_defaults : deny_ipv6_defaults;
101
102 for (; *defaults != NULL; defaults++) {
103 union olsr_ip_addr addr;
104 if (inet_pton(olsr_cnf->ip_version, *defaults, &addr) <= 0) {
105 fprintf(stderr, "Error converting fixed IP %s for deny rule!!\n", *defaults);
106 continue;
107 }
108 olsr_add_invalid_address(&addr);
109 }
110 }
111
112 /**
113 * Create an outputbuffer for the given interface. This
114 * function will allocate the needed storage according
115 * to the MTU of the interface.
116 *
117 * @param ifp the interface to create a buffer for
118 *
119 * @return 0 on success, negative if a buffer already existed
120 * for the given interface
121 */
122 int
net_add_buffer(struct interface_olsr * ifp)123 net_add_buffer(struct interface_olsr *ifp)
124 {
125 /* Can the interfaces MTU actually change? If not, we can elimiate
126 * the "bufsize" field in "struct olsr_netbuf".
127 */
128 if (ifp->netbuf.bufsize != ifp->int_mtu && ifp->netbuf.buff != NULL) {
129 free(ifp->netbuf.buff);
130 ifp->netbuf.buff = NULL;
131 }
132
133 if (ifp->netbuf.buff == NULL) {
134 ifp->netbuf.buff = olsr_malloc(ifp->int_mtu, "add_netbuff");
135 }
136
137 /* Fill struct */
138 ifp->netbuf.bufsize = ifp->int_mtu;
139 ifp->netbuf.maxsize = ifp->int_mtu - OLSR_HEADERSIZE;
140
141 ifp->netbuf.pending = 0;
142 ifp->netbuf.reserved = 0;
143
144 return 0;
145 }
146
147 /**
148 * Remove a outputbuffer. Frees the allocated memory.
149 *
150 * @param ifp the interface corresponding to the buffer
151 * to remove
152 *
153 * @return 0 on success, negative if no buffer is found
154 */
155 int
net_remove_buffer(struct interface_olsr * ifp)156 net_remove_buffer(struct interface_olsr *ifp)
157 {
158 /* Flush pending data */
159 if (ifp->netbuf.pending)
160 net_output(ifp);
161
162 free(ifp->netbuf.buff);
163 ifp->netbuf.buff = NULL;
164
165 return 0;
166 }
167
168 /**
169 * Reserve space in a outputbuffer. This should only be needed
170 * in very special cases. This will decrease the reported size
171 * of the buffer so that there is always <i>size</i> bytes
172 * of data available in the buffer. To add data in the reserved
173 * area one must use the net_outbuffer_push_reserved function.
174 *
175 * @param ifp the interface corresponding to the buffer
176 * to reserve space on
177 * @param size the number of bytes to reserve
178 *
179 * @return 0 on success, negative if there was not enough
180 * bytes to reserve
181 */
182 int
net_reserve_bufspace(struct interface_olsr * ifp,int size)183 net_reserve_bufspace(struct interface_olsr *ifp, int size)
184 {
185 if (size > ifp->netbuf.maxsize)
186 return -1;
187
188 ifp->netbuf.reserved = size;
189 ifp->netbuf.maxsize -= size;
190
191 return 0;
192 }
193
194 /**
195 * Returns the number of bytes pending in the buffer. That
196 * is the number of bytes added but not sent.
197 *
198 * @param ifp the interface corresponding to the buffer
199 *
200 * @return the number of bytes currently pending
201 */
202 uint16_t
net_output_pending(const struct interface_olsr * ifp)203 net_output_pending(const struct interface_olsr * ifp)
204 {
205 return ifp->netbuf.pending;
206 }
207
208 /**
209 * Add data to a buffer.
210 *
211 * @param ifp the interface corresponding to the buffer
212 * @param data a pointer to the data to add
213 * @param size the number of byte to copy from data
214 *
215 * @return -1 if no buffer was found, 0 if there was not
216 * enough room in buffer or the number of bytes added on
217 * success
218 */
219 int
net_outbuffer_push(struct interface_olsr * ifp,const void * data,const uint16_t size)220 net_outbuffer_push(struct interface_olsr *ifp, const void *data, const uint16_t size)
221 {
222 if ((ifp->netbuf.pending + size) > ifp->netbuf.maxsize)
223 return 0;
224
225 memcpy(&ifp->netbuf.buff[ifp->netbuf.pending + OLSR_HEADERSIZE], data, size);
226 ifp->netbuf.pending += size;
227
228 return size;
229 }
230
231 /**
232 * Add data to the reserved part of a buffer
233 *
234 * @param ifp the interface corresponding to the buffer
235 * @param data a pointer to the data to add
236 * @param size the number of byte to copy from data
237 *
238 * @return -1 if no buffer was found, 0 if there was not
239 * enough room in buffer or the number of bytes added on
240 * success
241 */
242 int
net_outbuffer_push_reserved(struct interface_olsr * ifp,const void * data,const uint16_t size)243 net_outbuffer_push_reserved(struct interface_olsr *ifp, const void *data, const uint16_t size)
244 {
245 if ((ifp->netbuf.pending + size) > (ifp->netbuf.maxsize + ifp->netbuf.reserved))
246 return 0;
247
248 memcpy(&ifp->netbuf.buff[ifp->netbuf.pending + OLSR_HEADERSIZE], data, size);
249 ifp->netbuf.pending += size;
250
251 return size;
252 }
253
254 /**
255 * Report the number of bytes currently available in the buffer
256 * (not including possible reserved bytes)
257 *
258 * @param ifp the interface corresponding to the buffer
259 *
260 * @return the number of bytes available in the buffer or
261 */
262 int
net_outbuffer_bytes_left(const struct interface_olsr * ifp)263 net_outbuffer_bytes_left(const struct interface_olsr *ifp)
264 {
265 /* IPv6 minimum MTU - IPv6 header - UDP header - VLAN-Tag */
266 static int MAX_REMAINING = 1280 - 40 - 8 - 4;
267 int remaining = ifp->netbuf.maxsize - ifp->netbuf.pending;
268
269 if (remaining > MAX_REMAINING) {
270 return MAX_REMAINING;
271 }
272 return remaining;
273 }
274
275 /**
276 * Add a packet transform function. Theese are functions
277 * called just prior to sending data in a buffer.
278 *
279 * @param f the function pointer
280 *
281 * @returns 1
282 */
283 int
add_ptf(packet_transform_function f)284 add_ptf(packet_transform_function f)
285 {
286
287 struct ptf *new_ptf;
288
289 new_ptf = olsr_malloc(sizeof(struct ptf), "Add PTF");
290
291 new_ptf->next = ptf_list;
292 new_ptf->function = f;
293
294 ptf_list = new_ptf;
295
296 return 1;
297 }
298
299 /**
300 * Remove a packet transform function
301 *
302 * @param f the function pointer
303 *
304 * @returns 1 if a functionpointer was removed
305 * 0 if not
306 */
307 int
del_ptf(packet_transform_function f)308 del_ptf(packet_transform_function f)
309 {
310 struct ptf *prev = NULL;
311 struct ptf *tmp_ptf = ptf_list;
312 while (tmp_ptf) {
313 if (tmp_ptf->function == f) {
314 /* Remove entry */
315 if (prev == NULL)
316 ptf_list = tmp_ptf->next;
317 else
318 prev->next = tmp_ptf->next;
319 free(tmp_ptf);
320 return 1;
321 }
322 prev = tmp_ptf;
323 tmp_ptf = tmp_ptf->next;
324 }
325
326 return 0;
327 }
328
329 /**
330 *Sends a packet on a given interface.
331 *
332 *@param ifp the interface to send on.
333 *
334 *@return negative on error
335 */
336 int
net_output(struct interface_olsr * ifp)337 net_output(struct interface_olsr *ifp)
338 {
339 struct sockaddr_in *sin = NULL;
340 struct sockaddr_in6 *sin6 = NULL;
341 struct sockaddr_in dst;
342 struct sockaddr_in6 dst6;
343 struct ptf *tmp_ptf_list;
344 union olsr_packet *outmsg;
345 int retval;
346
347 if (!ifp->netbuf.pending)
348 return 0;
349
350 ifp->netbuf.pending += OLSR_HEADERSIZE;
351
352 retval = ifp->netbuf.pending;
353
354 outmsg = (union olsr_packet *)ifp->netbuf.buff;
355 /* Add the Packet seqno */
356 outmsg->v4.olsr_seqno = htons(ifp->olsr_seqnum++);
357 /* Set the packetlength */
358 outmsg->v4.olsr_packlen = htons(ifp->netbuf.pending);
359
360 if (olsr_cnf->ip_version == AF_INET) {
361 /* IP version 4 */
362 sin = (struct sockaddr_in *)&ifp->int_broadaddr;
363
364 /* Copy sin */
365 dst = *sin;
366 sin = &dst;
367
368 if (sin->sin_port == 0)
369 sin->sin_port = htons(olsr_cnf->olsrport);
370 } else {
371 /* IP version 6 */
372 sin6 = (struct sockaddr_in6 *)&ifp->int6_multaddr;
373 /* Copy sin */
374 dst6 = *sin6;
375 sin6 = &dst6;
376 }
377
378 /*
379 *Call possible packet transform functions registered by plugins
380 */
381 for (tmp_ptf_list = ptf_list; tmp_ptf_list != NULL; tmp_ptf_list = tmp_ptf_list->next) {
382 tmp_ptf_list->function(ifp->netbuf.buff, &ifp->netbuf.pending);
383 }
384
385 if (olsr_cnf->ip_version == AF_INET) {
386 /* IP version 4 */
387 if (olsr_sendto(ifp->send_socket, ifp->netbuf.buff, ifp->netbuf.pending, MSG_DONTROUTE, (struct sockaddr *)sin, sizeof(*sin)) <
388 0) {
389 perror("sendto(v4)");
390 #ifndef _WIN32
391 olsr_syslog(OLSR_LOG_ERR, "OLSR: sendto IPv4 '%s' on interface %s", strerror(errno), ifp->int_name);
392 #endif /* _WIN32 */
393 retval = -1;
394 }
395 } else {
396 /* IP version 6 */
397 if (olsr_sendto(ifp->send_socket, ifp->netbuf.buff, ifp->netbuf.pending, MSG_DONTROUTE, (struct sockaddr *)sin6, sizeof(*sin6))
398 < 0) {
399 struct ipaddr_str buf;
400 perror("sendto(v6)");
401 #ifndef _WIN32
402 olsr_syslog(OLSR_LOG_ERR, "OLSR: sendto IPv6 '%s' on interface %s", strerror(errno), ifp->int_name);
403 #endif /* _WIN32 */
404 fprintf(stderr, "Socket: %d interface: %d\n", ifp->olsr_socket, ifp->if_index);
405 fprintf(stderr, "To: %s (size: %u)\n", ip6_to_string(&buf, &sin6->sin6_addr), (unsigned int)sizeof(*sin6));
406 fprintf(stderr, "Outputsize: %d\n", ifp->netbuf.pending);
407 retval = -1;
408 }
409 }
410
411 ifp->netbuf.pending = 0;
412
413 /*
414 * if we've just transmitted a TC message, let Dijkstra use the current
415 * link qualities for the links to our neighbours
416 */
417
418 lq_tc_pending = false;
419
420 return retval;
421 }
422
423 /*
424 * Adds the given IP-address to the invalid list.
425 */
426 void
olsr_add_invalid_address(const union olsr_ip_addr * adr)427 olsr_add_invalid_address(const union olsr_ip_addr *adr)
428 {
429 struct ipaddr_str buf;
430 struct deny_address_entry *new_entry = olsr_malloc(sizeof(struct deny_address_entry), "Add deny address");
431
432 new_entry->addr = *adr;
433 new_entry->next = deny_entries;
434 deny_entries = new_entry;
435 OLSR_PRINTF(1, "Added %s to IP deny set\n", olsr_ip_to_string(&buf, &new_entry->addr));
436 }
437
438 bool
olsr_validate_address(const union olsr_ip_addr * adr)439 olsr_validate_address(const union olsr_ip_addr *adr)
440 {
441 const struct deny_address_entry *deny_entry;
442
443 for (deny_entry = deny_entries; deny_entry != NULL; deny_entry = deny_entry->next) {
444 if (ipequal(adr, &deny_entry->addr)) {
445 struct ipaddr_str buf;
446 OLSR_PRINTF(1, "Validation of address %s failed!\n", olsr_ip_to_string(&buf, adr));
447 return false;
448 }
449 if (&deny_entry->addr == &olsr_cnf->main_addr)
450 break;
451 }
452 return true;
453 }
454
455 /*
456 * Local Variables:
457 * c-basic-offset: 2
458 * indent-tabs-mode: nil
459 * End:
460 */
461