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