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