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