cleanup, 1. step (to get some local changes away):
[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  * $Id: net_olsr.c,v 1.21 2007/04/20 13:46:04 bernd67 Exp $
40  */
41
42 #include "net_olsr.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 <stdlib.h>
49 #include <assert.h>
50
51 extern olsr_bool lq_tc_pending;
52
53 static olsr_bool disp_pack_out = OLSR_FALSE;
54
55
56 #ifdef WIN32
57 #define perror(x) WinSockPError(x)
58 void
59 WinSockPError(char *);
60 #endif
61
62
63 struct deny_address_entry
64 {
65   union olsr_ip_addr        addr;
66   struct deny_address_entry *next;
67 };
68
69
70 /* Packet transform functions */
71
72 struct ptf
73 {
74   packet_transform_function function;
75   struct ptf *next;
76 };
77
78 static struct ptf *ptf_list;
79
80 static struct deny_address_entry *deny_entries;
81
82 static const char * const deny_ipv4_defaults[] =
83   {
84     "0.0.0.0",
85     "127.0.0.1",
86     NULL
87   };
88
89 static const char * const deny_ipv6_defaults[] =
90   {
91     "0::0",
92     "0::1",
93     NULL
94   };
95
96 void
97 net_set_disp_pack_out(olsr_bool val)
98 {
99   disp_pack_out = val;
100 }
101
102 void
103 init_net(void)
104 {
105   /* Block invalid addresses */
106   if(olsr_cnf->ip_version == AF_INET)
107     {
108       union olsr_ip_addr addr;
109       int i;
110       /* IPv4 */
111       for(i = 0; deny_ipv4_defaults[i] != NULL; i++)
112         {
113           if(inet_pton(olsr_cnf->ip_version, deny_ipv4_defaults[i], &addr) <= 0)
114             {
115               fprintf(stderr, "Error converting fixed IP %s for deny rule!!\n",
116                       deny_ipv4_defaults[i]);
117               continue;
118             }
119           olsr_add_invalid_address(&addr);
120         }
121     }
122   else 
123     {
124       union olsr_ip_addr addr;
125       int i;
126       /* IPv6 */
127       for(i = 0; deny_ipv6_defaults[i] != NULL; i++)
128         {
129           if(inet_pton(olsr_cnf->ip_version, deny_ipv6_defaults[i], &addr) <= 0)
130             {
131               fprintf(stderr, "Error converting fixed IP %s for deny rule!!\n",
132                       deny_ipv6_defaults[i]);
133               continue;
134             }
135           olsr_add_invalid_address(&addr);
136         }
137
138     }
139 }
140
141 /**
142  * Create a outputbuffer for the given interface. This
143  * function will allocate the needed storage according 
144  * to the MTU of the interface.
145  *
146  * @param ifp the interface to create a buffer for
147  *
148  * @return 0 on success, negative if a buffer already existed
149  *  for the given interface
150  */ 
151 int
152 net_add_buffer(struct interface *ifp)
153 {
154   /* Can the interfaces MTU actually change? If not, we can elimiate
155    * the "bufsize" field in "struct olsr_netbuf".
156    */
157   if (ifp->netbuf.bufsize != ifp->int_mtu && ifp->netbuf.buff != NULL) {
158     free(ifp->netbuf.buff);
159     ifp->netbuf.buff = NULL;
160   }
161   
162   if (ifp->netbuf.buff == NULL) {
163     ifp->netbuf.buff = olsr_malloc(ifp->int_mtu, "add_netbuff");
164   }
165
166   /* Fill struct */
167   ifp->netbuf.bufsize = ifp->int_mtu;
168   ifp->netbuf.maxsize = ifp->int_mtu - OLSR_HEADERSIZE;
169
170   ifp->netbuf.pending = 0;
171   ifp->netbuf.reserved = 0;
172
173   return 0;
174 }
175
176 /**
177  * Remove a outputbuffer. Frees the allocated memory.
178  *
179  * @param ifp the interface corresponding to the buffer
180  * to remove
181  *
182  * @return 0 on success, negative if no buffer is found
183  */
184 int
185 net_remove_buffer(struct interface *ifp)
186 {
187   /* Flush pending data */
188   if(ifp->netbuf.pending)
189     net_output(ifp);
190
191   free(ifp->netbuf.buff);
192   ifp->netbuf.buff = NULL;
193
194   return 0;
195 }
196
197
198 /**
199  * Reserve space in a outputbuffer. This should only be needed
200  * in very special cases. This will decrease the reported size
201  * of the buffer so that there is always <i>size</i> bytes
202  * of data available in the buffer. To add data in the reserved
203  * area one must use the net_outbuffer_push_reserved function.
204  *
205  * @param ifp the interface corresponding to the buffer
206  * to reserve space on
207  * @param size the number of bytes to reserve
208  *
209  * @return 0 on success, negative if there was not enough
210  *  bytes to reserve
211  */
212 int
213 net_reserve_bufspace(struct interface *ifp, int size)
214 {
215   if(size > ifp->netbuf.maxsize)
216     return -1;
217   
218   ifp->netbuf.reserved = size;
219   ifp->netbuf.maxsize -= size;
220   
221   return 0;
222 }
223
224 /**
225  * Returns the number of bytes pending in the buffer. That
226  * is the number of bytes added but not sent.
227  *
228  * @param ifp the interface corresponding to the buffer
229  *
230  * @return the number of bytes currently pending
231  */
232 olsr_u16_t
233 net_output_pending(struct interface *ifp)
234 {
235   return ifp->netbuf.pending;
236 }
237
238
239
240 /**
241  * Add data to a buffer.
242  *
243  * @param ifp the interface corresponding to the buffer
244  * @param data a pointer to the data to add
245  * @param size the number of byte to copy from data
246  *
247  * @return -1 if no buffer was found, 0 if there was not 
248  *  enough room in buffer or the number of bytes added on 
249  *  success
250  */
251 int
252 net_outbuffer_push(struct interface *ifp, olsr_u8_t *data, olsr_u16_t size)
253 {
254   if((ifp->netbuf.pending + size) > ifp->netbuf.maxsize)
255     return 0;
256
257   memcpy(&ifp->netbuf.buff[ifp->netbuf.pending + OLSR_HEADERSIZE], data, size);
258   ifp->netbuf.pending += size;
259
260   return size;
261 }
262
263
264 /**
265  * Add data to the reserved part of a buffer
266  *
267  * @param ifp the interface corresponding to the buffer
268  * @param data a pointer to the data to add
269  * @param size the number of byte to copy from data
270  *
271  * @return -1 if no buffer was found, 0 if there was not 
272  *  enough room in buffer or the number of bytes added on 
273  *  success
274  */
275 int
276 net_outbuffer_push_reserved(struct interface *ifp, olsr_u8_t *data, olsr_u16_t size)
277 {
278   if((ifp->netbuf.pending + size) > (ifp->netbuf.maxsize + ifp->netbuf.reserved))
279     return 0;
280
281   memcpy(&ifp->netbuf.buff[ifp->netbuf.pending + OLSR_HEADERSIZE], data, size);
282   ifp->netbuf.pending += size;
283
284   return size;
285 }
286
287 /**
288  * Report the number of bytes currently available in the buffer
289  * (not including possible reserved bytes)
290  *
291  * @param ifp the interface corresponding to the buffer
292  *
293  * @return the number of bytes available in the buffer or
294  */
295 int
296 net_outbuffer_bytes_left(struct interface *ifp)
297 {
298   return ifp->netbuf.maxsize - ifp->netbuf.pending;
299 }
300
301
302 /**
303  * Add a packet transform function. Theese are functions
304  * called just prior to sending data in a buffer.
305  *
306  * @param f the function pointer
307  *
308  * @returns 1
309  */
310 int
311 add_ptf(packet_transform_function f)
312 {
313
314   struct ptf *new_ptf;
315
316   new_ptf = olsr_malloc(sizeof(struct ptf), "Add PTF");
317
318   new_ptf->next = ptf_list;
319   new_ptf->function = f;
320
321   ptf_list = new_ptf;
322
323   return 1;
324 }
325
326 /**
327  * Remove a packet transform function
328  *
329  * @param f the function pointer
330  *
331  * @returns 1 if a functionpointer was removed
332  *  0 if not
333  */
334 int
335 del_ptf(packet_transform_function f)
336 {
337   struct ptf *tmp_ptf, *prev;
338
339   tmp_ptf = ptf_list;
340   prev = NULL;
341
342   while(tmp_ptf)
343     {
344       if(tmp_ptf->function == f)
345         {
346           /* Remove entry */
347           if(prev == NULL)
348               ptf_list = tmp_ptf->next;
349           else
350               prev->next = tmp_ptf->next;
351           free(tmp_ptf);
352           return 1;
353         }
354       prev = tmp_ptf;
355       tmp_ptf = tmp_ptf->next;
356     }
357
358   return 0;
359 }
360
361 /**
362  *Sends a packet on a given interface.
363  *
364  *@param ifp the interface to send on.
365  *
366  *@return negative on error
367  */
368 int
369 net_output(struct interface *ifp)
370 {
371   struct sockaddr_in *sin;  
372   struct sockaddr_in dst;
373   struct sockaddr_in6 *sin6;  
374   struct sockaddr_in6 dst6;
375   struct ptf *tmp_ptf_list;
376   union olsr_packet *outmsg;
377   int retval;
378
379   sin = NULL;
380   sin6 = NULL;
381
382   if(!ifp->netbuf.pending)
383     return 0;
384
385   ifp->netbuf.pending += OLSR_HEADERSIZE;
386
387   retval = ifp->netbuf.pending;
388
389   outmsg = (union olsr_packet *)ifp->netbuf.buff;
390   /* Add the Packet seqno */
391   outmsg->v4.olsr_seqno = htons(ifp->olsr_seqnum++);
392   /* Set the packetlength */
393   outmsg->v4.olsr_packlen = htons(ifp->netbuf.pending);
394
395   if(olsr_cnf->ip_version == AF_INET)
396     {
397       /* IP version 4 */
398       sin = (struct sockaddr_in *)&ifp->int_broadaddr;
399
400       /* Copy sin */
401       dst = *sin;
402       sin = &dst;
403
404       if (sin->sin_port == 0)
405         sin->sin_port = htons(OLSRPORT);
406     }
407   else
408     {
409       /* IP version 6 */
410       sin6 = (struct sockaddr_in6 *)&ifp->int6_multaddr;
411       /* Copy sin */
412       dst6 = *sin6;
413       sin6 = &dst6;
414     }
415
416   /*
417    *Call possible packet transform functions registered by plugins  
418    */
419   for (tmp_ptf_list = ptf_list; tmp_ptf_list != NULL; tmp_ptf_list = tmp_ptf_list->next)
420     {
421       tmp_ptf_list->function(ifp->netbuf.buff, &ifp->netbuf.pending);
422     }
423
424   /*
425    *if the -dispout option was given
426    *we print the content of the packets
427    */
428   if(disp_pack_out)
429     print_olsr_serialized_packet(stdout, (union olsr_packet *)ifp->netbuf.buff, 
430                                  ifp->netbuf.pending, &ifp->ip_addr); 
431   
432   if(olsr_cnf->ip_version == AF_INET)
433     {
434       /* IP version 4 */
435       if(olsr_sendto(ifp->olsr_socket, 
436                      ifp->netbuf.buff, 
437                      ifp->netbuf.pending, 
438                      MSG_DONTROUTE, 
439                      (struct sockaddr *)sin, 
440                      sizeof (*sin))
441          < 0)
442         {
443           perror("sendto(v4)");
444           olsr_syslog(OLSR_LOG_ERR, "OLSR: sendto IPv4 %m");
445           retval = -1;
446         }
447     }
448   else
449     {
450       /* IP version 6 */
451       if(olsr_sendto(ifp->olsr_socket, 
452                      ifp->netbuf.buff,
453                      ifp->netbuf.pending, 
454                      MSG_DONTROUTE, 
455                      (struct sockaddr *)sin6, 
456                      sizeof (*sin6))
457          < 0)
458         {
459           perror("sendto(v6)");
460           olsr_syslog(OLSR_LOG_ERR, "OLSR: sendto IPv6 %m");
461           fprintf(stderr, "Socket: %d interface: %d\n", ifp->olsr_socket, ifp->if_nr);
462           fprintf(stderr, "To: %s (size: %d)\n", ip6_to_string(&sin6->sin6_addr), (int)sizeof(*sin6));
463           fprintf(stderr, "Outputsize: %d\n", ifp->netbuf.pending);
464           retval = -1;
465         }
466     }
467   
468   ifp->netbuf.pending = 0;
469
470   // if we've just transmitted a TC message, let Dijkstra use the current
471   // link qualities for the links to our neighbours
472
473   olsr_update_dijkstra_link_qualities();
474   lq_tc_pending = OLSR_FALSE;
475
476   return retval;
477 }
478
479
480 /**
481  * Create a IPv6 netmask based on a prefix length
482  *
483  * @param allocated address to build the netmask in
484  * @param prefix the prefix length
485  *
486  * @returns 1 on success 0 on failure
487  */
488 int
489 olsr_prefix_to_netmask(union olsr_ip_addr *adr, olsr_u16_t prefix)
490 {
491   int p, i;
492
493   if(adr == NULL)
494     return 0;
495
496   p = prefix;
497   i = 0;
498
499   memset(adr, 0, olsr_cnf->ipsize);
500
501   for(;p > 0; p -= 8)
502     {
503       adr->v6.s6_addr[i] = (p < 8) ? 0xff ^ (0xff >> p) : 0xff;
504       i++;
505     }
506
507 #ifdef DEBUG
508   OLSR_PRINTF(3, "Prefix %d = Netmask: %s\n", prefix, olsr_ip_to_string(adr))
509 #endif
510
511   return 1;
512 }
513
514
515
516 /**
517  * Calculate prefix length based on a netmask
518  *
519  * @param adr the address to use to calculate the prefix length
520  *
521  * @return the prefix length
522  */
523 olsr_u16_t
524 olsr_netmask_to_prefix(union olsr_ip_addr *adr)
525 {
526   olsr_u16_t prefix;
527   int i, tmp;
528
529   prefix = 0;
530
531   for(i = 0; i < 16; i++)
532     {
533       if(adr->v6.s6_addr[i] == 0xff)
534         {
535           prefix += 8;
536         }
537       else
538         {
539           for(tmp = adr->v6.s6_addr[i];
540               tmp > 0;
541               tmp = (tmp << 1) & 0xff)
542             prefix++;
543         }
544     }
545
546 #ifdef DEBUG
547   OLSR_PRINTF(3, "Netmask: %s = Prefix %d\n", olsr_ip_to_string(adr), prefix)
548 #endif
549
550   return prefix;
551 }
552
553
554
555 /**
556  *Converts a sockaddr struct to a string representing
557  *the IP address from the sockaddr struct
558  *
559  *<b>NON REENTRANT!!!!</b>
560  *
561  *@param address_to_convert the sockaddr struct to "convert"
562  *@return a char pointer to the string containing the IP
563  */
564 char *
565 sockaddr_to_string(struct sockaddr *address_to_convert)
566 {
567   struct sockaddr_in           *address;
568   
569   address=(struct sockaddr_in *)address_to_convert; 
570   return(inet_ntoa(address->sin_addr));
571   
572 }
573
574
575 /**
576  *Converts the 32bit olsr_u32_t datatype to
577  *a char array.
578  *
579  *<b>NON REENTRANT!!!!</b>
580  *
581  *@param address the olsr_u32_t to "convert"
582  *@return a char pointer to the string containing the IP
583  */
584
585 const char *
586 ip_to_string(const olsr_u32_t *address)
587 {
588   struct in_addr in;
589   in.s_addr=*address;
590   return(inet_ntoa(in));
591   
592 }
593
594 /**
595  *Converts the 32bit olsr_u32_t datatype to
596  *a char array.
597  *
598  *<b>NON REENTRANT</b>
599  *
600  *@param addr6 the address to "convert"
601  *@return a char pointer to the string containing the IP
602  */
603
604 const char *
605 ip6_to_string(const struct in6_addr *addr6)
606 {
607   static char ipv6_buf[INET6_ADDRSTRLEN]; /* for address coversion */
608   return inet_ntop(AF_INET6, addr6, ipv6_buf, sizeof(ipv6_buf));
609 }
610
611
612 const char *
613 olsr_ip_to_string(const union olsr_ip_addr *addr)
614 {
615   static int index = 0;
616   static char buff[4][INET6_ADDRSTRLEN > INET_ADDRSTRLEN ? INET6_ADDRSTRLEN : INET_ADDRSTRLEN];
617   const char *ret;
618   
619   if(olsr_cnf->ip_version == AF_INET)
620     {
621 #if 0
622       struct in_addr in;
623       in.s_addr = addr->v4;
624       ret = inet_ntop(AF_INET, &in, buff[index], sizeof(buff[index]));
625 #else
626       ret = inet_ntop(AF_INET, &addr->v6, buff[index], sizeof(buff[index]));
627 #endif
628     }
629   else
630     {
631       /* IPv6 */
632       ret = inet_ntop(AF_INET6, &addr->v6, buff[index], sizeof(buff[index]));
633     }
634   index = (index + 1) & 3;
635
636   return ret;
637 }
638
639
640 void
641 olsr_add_invalid_address(union olsr_ip_addr *adr)
642 {
643   struct deny_address_entry *new_entry;
644
645   new_entry = olsr_malloc(sizeof(struct deny_address_entry), "Add deny address");
646
647   new_entry->next = deny_entries;
648   COPY_IP(&new_entry->addr, adr);
649
650   deny_entries = new_entry;
651
652   OLSR_PRINTF(1, "Added %s to IP deny set\n", olsr_ip_to_string(&new_entry->addr))
653   return;
654 }
655
656 /**
657  *Converts the 32bit olsr_u32_t datatype to
658  *a char array.
659  *
660  *<b>NON REENTRANT</b>
661  *
662  *@param addr6 the address to "convert"
663  *@return a char pointer to the string containing the IP
664  */
665 olsr_bool
666 olsr_validate_address(union olsr_ip_addr *adr)
667 {
668   struct deny_address_entry *deny_entry = deny_entries;
669
670   while(deny_entry)
671     {
672       if(COMP_IP(adr, &deny_entry->addr))
673         {
674           OLSR_PRINTF(1, "Validation of address %s failed!\n",
675                       olsr_ip_to_string(adr))
676           return OLSR_FALSE;
677         }
678
679       deny_entry = deny_entry->next;
680     }
681
682   return OLSR_TRUE;
683 }