Fixed compiler warning
[olsrd.git] / src / linux / net.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.c,v 1.14 2005/02/13 11:00:51 kattemat Exp $
40  */
41
42
43 /*
44  * Linux spesific code
45  */
46
47 #include "net.h"
48 #include "../defs.h"
49 #include "../net_os.h"
50 #include "../parser.h"
51
52
53 extern struct olsr_netbuf *netbufs[];
54 static char inbuf[MAXMESSAGESIZE+1];
55
56
57 /**
58  *Bind a socket to a device
59  *
60  *@param sock the socket to bind
61  *@param dev_name name of the device
62  *
63  *@return negative if error
64  */
65
66 int
67 bind_socket_to_device(int sock, char *dev_name)
68 {
69   /*
70    *Bind to device using the SO_BINDTODEVICE flag
71    */
72   olsr_printf(3, "Binding socket %d to device %s\n", sock, dev_name);
73   return setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, dev_name, strlen(dev_name)+1);
74
75 }
76
77
78
79
80 /**
81  *Enable IP forwarding.
82  *Just writing "1" to the /proc/sys/net/ipv4/ip_forward
83  *if using IPv4 or /proc/sys/net/ipv6/conf/all/forwarding
84  *if using IPv6.
85  *Could probably drop the check for
86  *"0" here and write "1" anyways.
87  *
88  *@param version IP version.
89  *
90  *@return 1 on sucess 0 on failiure
91  */ 
92 int
93 enable_ip_forwarding(int version)
94 {
95   FILE *proc_fwd;
96   char procfile[FILENAME_MAX];
97
98   if(version == AF_INET)
99     {
100       strcpy(procfile, "/proc/sys/net/ipv4/ip_forward");
101     }
102   else
103     if(version == AF_INET6)
104       {
105         strcpy(procfile, "/proc/sys/net/ipv6/conf/all/forwarding");
106       }
107     else
108       return -1;
109
110
111   if ((proc_fwd=fopen(procfile, "r"))==NULL)
112     {
113       /* IPv4 */
114       if(version == AF_INET)
115         fprintf(stderr, "WARNING! Could not open the %s file to check/enable IP forwarding!\nAre you using the procfile filesystem?\nDoes your system support IPv4?\nI will continue(in 3 sec) - but you should mannually ensure that IP forwarding is enabeled!\n\n", procfile);
116       /* IPv6 */
117       else
118         fprintf(stderr, "WARNING! Could not open the %s file to check/enable IP forwarding!\nAre you using the procfile filesystem?\nDoes your system support IPv6?\nI will continue(in 3 sec) - but you should mannually ensure that IP forwarding is enabeled!\n\n", procfile);
119       
120       sleep(3);
121       return 0;
122     }
123   
124   else
125     {
126       orig_fwd_state = fgetc(proc_fwd);
127       fclose(proc_fwd);
128       if(orig_fwd_state == '1')
129         {
130           olsr_printf(3, "\nIP forwarding is enabled on this system\n");
131         }
132       else
133         {
134           if ((proc_fwd=fopen(procfile, "w"))==NULL)
135             {
136               fprintf(stderr, "Could not open %s for writing!\n", procfile);
137               fprintf(stderr, "I will continue(in 3 sec) - but you should mannually ensure that IP forwarding is enabeled!\n\n");
138               sleep(3);
139               return 0;
140             }
141           else
142             {
143               syslog(LOG_INFO, "Writing \"1\" to %s\n", procfile);
144               fputs("1", proc_fwd);
145             }
146           fclose(proc_fwd);
147
148         }
149     }
150   return 1;
151       
152 }
153
154
155 /**
156  *
157  *@return 1 on sucess 0 on failiure
158  */ 
159 int
160 disable_redirects(char *if_name, int index, int version)
161 {
162   FILE *proc_redirect;
163   char procfile[FILENAME_MAX];
164
165   if(version == AF_INET6)
166     return -1;
167
168   /* Generate the procfile name */
169   sprintf(procfile, REDIRECT_PROC, if_name);
170
171
172   if((proc_redirect = fopen(procfile, "r")) == NULL)
173     {
174       fprintf(stderr, "WARNING! Could not open the %s file to check/disable ICMP redirects!\nAre you using the procfile filesystem?\nDoes your system support IPv4?\nI will continue(in 3 sec) - but you should mannually ensure that ICMP redirects are disabled!\n\n", procfile);
175       
176       sleep(3);
177       return 0;
178     }
179   else
180     {
181       nic_states[index].redirect = fgetc(proc_redirect);
182       fclose(proc_redirect);
183       
184     }
185
186   if ((proc_redirect = fopen(procfile, "w"))==NULL)
187     {
188       fprintf(stderr, "Could not open %s for writing!\n", procfile);
189       fprintf(stderr, "I will continue(in 3 sec) - but you should mannually ensure that ICMP redirect is disabeled!\n\n");
190       sleep(3);
191       return 0;
192     }
193   else
194     {
195       syslog(LOG_INFO, "Writing \"0\" to %s", procfile);
196       fputs("0", proc_redirect);
197     }
198   fclose(proc_redirect);
199
200   return 1;
201 }
202
203
204
205 /**
206  *
207  *@return 1 on sucess 0 on failiure
208  */ 
209 int
210 deactivate_spoof(char *if_name, int index, int version)
211 {
212   FILE *proc_spoof;
213   char procfile[FILENAME_MAX];
214
215   if(version == AF_INET6)
216     return -1;
217
218
219   /* Generate the procfile name */
220   sprintf(procfile, SPOOF_PROC, if_name);
221
222
223   if((proc_spoof = fopen(procfile, "r")) == NULL)
224     {
225       fprintf(stderr, "WARNING! Could not open the %s file to check/disable the IP spoof filter!\nAre you using the procfile filesystem?\nDoes your system support IPv4?\nI will continue(in 3 sec) - but you should mannually ensure that IP spoof filtering is disabled!\n\n", procfile);
226       
227       sleep(3);
228       return 0;
229     }
230   else
231     {
232       nic_states[index].spoof = fgetc(proc_spoof);
233       fclose(proc_spoof);
234       
235     }
236
237   if ((proc_spoof = fopen(procfile, "w")) == NULL)
238     {
239       fprintf(stderr, "Could not open %s for writing!\n", procfile);
240       fprintf(stderr, "I will continue(in 3 sec) - but you should mannually ensure that IP spoof filtering is disabeled!\n\n");
241       sleep(3);
242       return 0;
243     }
244   else
245     {
246       syslog(LOG_INFO, "Writing \"0\" to %s", procfile);
247       fputs("0", proc_spoof);
248     }
249   fclose(proc_spoof);
250
251   return 1;
252 }
253
254
255
256 /**
257  *Resets the spoof filter and ICMP redirect settings
258  */
259
260 int
261 restore_settings(int version)
262 {
263   FILE *proc_fd;
264   char procfile[FILENAME_MAX];
265   struct interface *ifs;
266
267   olsr_printf(1, "Restoring network state\n");
268
269   /* Restore IP forwarding to "off" */
270   if(orig_fwd_state == '0')
271     {
272       if(version == AF_INET)
273         {
274           strcpy(procfile, "/proc/sys/net/ipv4/ip_forward");
275         }
276       else if(version == AF_INET6)
277         {
278           strcpy(procfile, "/proc/sys/net/ipv6/conf/all/forwarding");
279         }
280
281       if ((proc_fd = fopen(procfile, "w")) == NULL)
282         {
283           fprintf(stderr, "Could not open %s for writing!\nSettings not restored!\n", procfile);
284         }
285       else
286         {
287           syslog(LOG_INFO, "Resetting %s to %c\n", procfile, orig_fwd_state);
288           fputc(orig_fwd_state, proc_fd);
289           fclose(proc_fd);
290         }
291
292     }
293
294   if(version == AF_INET6)
295     return 0;
296
297   for(ifs = ifnet; ifs != NULL; ifs = ifs->int_next)
298     {
299       /* ICMP redirects */
300       
301       /* Generate the procfile name */
302       sprintf(procfile, REDIRECT_PROC, ifs->int_name);
303       
304       if ((proc_fd = fopen(procfile, "w")) == NULL)
305         {
306           fprintf(stderr, "Could not open %s for writing!\nSettings not restored!\n", procfile);
307         }
308       else
309         {
310           syslog(LOG_INFO, "Resetting %s to %c\n", procfile, nic_states[ifs->if_nr].redirect);
311
312           fputc(nic_states[ifs->if_nr].redirect, proc_fd);
313           fclose(proc_fd);
314         }
315
316       
317       /* Spoof filter */
318       
319       /* Generate the procfile name */
320       sprintf(procfile, SPOOF_PROC, ifs->int_name);
321
322       if ((proc_fd = fopen(procfile, "w")) == NULL)
323         {
324           fprintf(stderr, "Could not open %s for writing!\nSettings not restored!\n", procfile);
325         }
326       else
327         {
328           syslog(LOG_INFO, "Resetting %s to %c\n", procfile, nic_states[ifs->if_nr].spoof);
329
330           fputc(nic_states[ifs->if_nr].spoof, proc_fd);
331           fclose(proc_fd);
332         }
333
334     }
335   return 1;
336
337 }
338
339
340
341 /**
342  *Creates a nonblocking broadcast socket.
343  *@param sa sockaddr struct. Used for bind(2).
344  *@return the FD of the socket or -1 on error.
345  */
346 int
347 getsocket(struct sockaddr *sa, int bufspace, char *int_name)
348 {
349   struct sockaddr_in *sin=(struct sockaddr_in *)sa;
350   int sock, on = 1;
351
352
353
354   if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) 
355     {
356       perror("socket");
357       syslog(LOG_ERR, "socket: %m");
358       return (-1);
359     }
360
361
362
363 #ifdef SO_BROADCAST
364   if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0)
365     {
366       perror("setsockopt");
367       syslog(LOG_ERR, "setsockopt SO_BROADCAST: %m");
368       close(sock);
369       return (-1);
370     }
371 #endif
372
373   if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) 
374     {
375       perror("SO_REUSEADDR failed");
376       return (-1);
377     }
378
379
380
381 #ifdef SO_RCVBUF
382
383   for (on = bufspace; ; on -= 1024) 
384     {
385       if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF,
386                      &on, sizeof (on)) == 0)
387         break;
388       if (on <= 8*1024) 
389         {
390           perror("setsockopt");
391           syslog(LOG_ERR, "setsockopt SO_RCVBUF: %m");
392           break;
393         }
394     }
395
396
397 #endif
398
399
400   /*
401    * WHEN USING KERNEL 2.6 THIS MUST HAPPEN PRIOR TO THE PORT BINDING!!!!
402    */
403
404   /* Bind to device */
405   if(bind_socket_to_device(sock, int_name) < 0)
406     {
407       fprintf(stderr, "Could not bind socket to device... exiting!\n\n");
408       syslog(LOG_ERR, "Could not bind socket to device... exiting!\n\n");
409       return -1;
410     }
411
412
413   if (bind(sock, (struct sockaddr *)sin, sizeof (*sin)) < 0) 
414     {
415       perror("bind");
416       syslog(LOG_ERR, "bind: %m");
417       close(sock);
418       return (-1);
419     }
420
421   /*
422    *One should probably fetch the flags first
423    *using F_GETFL....
424    */
425   if (fcntl(sock, F_SETFL, O_NONBLOCK) == -1)
426     syslog(LOG_ERR, "fcntl O_NONBLOCK: %m\n");
427
428   return (sock);
429 }
430
431
432 /**
433  *Creates a nonblocking IPv6 socket
434  *@param sin sockaddr_in6 struct. Used for bind(2).
435  *@return the FD of the socket or -1 on error.
436  */
437 int
438 getsocket6(struct sockaddr_in6 *sin, int bufspace, char *int_name)
439 {
440   int sock, on = 1;
441
442
443
444   if ((sock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) 
445     {
446       perror("socket");
447       syslog(LOG_ERR, "socket: %m");
448       return (-1);
449     }
450
451
452
453   //#ifdef SO_BROADCAST
454   /*
455   if (setsockopt(sock, SOL_SOCKET, SO_MULTICAST, &on, sizeof (on)) < 0)
456     {
457       perror("setsockopt");
458       syslog(LOG_ERR, "setsockopt SO_BROADCAST: %m");
459       close(sock);
460       return (-1);
461     }
462   */
463   //#endif
464
465
466
467
468 #ifdef SO_RCVBUF
469   for (on = bufspace; ; on -= 1024) 
470     {
471       if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF,
472                      &on, sizeof (on)) == 0)
473         break;
474       if (on <= 8*1024) 
475         {
476           perror("setsockopt");
477           syslog(LOG_ERR, "setsockopt SO_RCVBUF: %m");
478           break;
479         }
480     }
481
482
483 #endif
484
485   if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) 
486     {
487       perror("SO_REUSEADDR failed");
488       return (-1);
489     }
490
491
492   /*
493    * WHEN USING KERNEL 2.6 THIS MUST HAPPEN PRIOR TO THE PORT BINDING!!!!
494    */
495
496   /* Bind to device */
497   if(bind_socket_to_device(sock, int_name) < 0)
498     {
499       fprintf(stderr, "Could not bind socket to device... exiting!\n\n");
500       syslog(LOG_ERR, "Could not bind socket to device... exiting!\n\n");
501       return -1;
502     }
503
504
505   if (bind(sock, (struct sockaddr *)sin, sizeof (*sin)) < 0) 
506     {
507       perror("bind");
508       syslog(LOG_ERR, "bind: %m");
509       close(sock);
510       return (-1);
511     }
512
513   /*
514    *One should probably fetch the flags first
515    *using F_GETFL....
516    */
517   if (fcntl(sock, F_SETFL, O_NONBLOCK) == -1)
518     syslog(LOG_ERR, "fcntl O_NONBLOCK: %m\n");
519
520
521
522   return (sock);
523 }
524
525
526 /*
527  *From net-tools lib/interface.c
528  *
529  */
530
531 int
532 get_ipv6_address(char *ifname, struct sockaddr_in6 *saddr6, int scope_in)
533 {
534   char addr6[40], devname[IFNAMSIZ];
535   char addr6p[8][5];
536   int plen, scope, dad_status, if_idx;
537   FILE *f;
538   struct sockaddr_in6 tmp_sockaddr6;
539
540   if ((f = fopen(_PATH_PROCNET_IFINET6, "r")) != NULL) 
541     {
542       while (fscanf(f, "%4s%4s%4s%4s%4s%4s%4s%4s %02x %02x %02x %02x %20s\n",
543                     addr6p[0], addr6p[1], addr6p[2], addr6p[3],
544                     addr6p[4], addr6p[5], addr6p[6], addr6p[7],
545                     &if_idx, &plen, &scope, &dad_status, devname) != EOF) 
546         {
547           if (!strcmp(devname, ifname)) 
548             {
549               sprintf(addr6, "%s:%s:%s:%s:%s:%s:%s:%s",
550                       addr6p[0], addr6p[1], addr6p[2], addr6p[3],
551                       addr6p[4], addr6p[5], addr6p[6], addr6p[7]);
552               olsr_printf(5, "\tinet6 addr: %s\n", addr6);
553               olsr_printf(5, "\tScope: %d", scope);
554               if(scope == scope_in)
555                 {
556                   olsr_printf(4, "IPv6 addr:\n");
557                   inet_pton(AF_INET6,addr6,&tmp_sockaddr6);
558                   memcpy(&saddr6->sin6_addr, &tmp_sockaddr6, sizeof(struct in6_addr));    
559                   fclose(f);
560                   return 1;
561                 }
562             }
563         }
564       fclose(f);
565     }
566   
567   return 0;
568 }
569
570 /**
571  *Sends a packet on a given interface.
572  *
573  *@param ifp the interface to send on.
574  *
575  *@return negative on error
576  */
577 int
578 net_output(struct interface *ifp)
579 {
580   struct sockaddr_in *sin;  
581   struct sockaddr_in dst;
582   struct sockaddr_in6 *sin6;  
583   struct sockaddr_in6 dst6;
584   struct ptf *tmp_ptf_list;
585   int i, x;
586   union olsr_packet *outmsg;
587
588   sin = NULL;
589   sin6 = NULL;
590
591   if(!netbufs[ifp->if_nr])
592     return -1;
593
594   if(!netbufs[ifp->if_nr]->pending)
595     return 0;
596
597   netbufs[ifp->if_nr]->pending += OLSR_HEADERSIZE;
598
599   outmsg = (union olsr_packet *)netbufs[ifp->if_nr]->buff;
600   /* Add the Packet seqno */
601   outmsg->v4.olsr_seqno = htons(ifp->olsr_seqnum++);
602   /* Set the packetlength */
603   outmsg->v4.olsr_packlen = htons(netbufs[ifp->if_nr]->pending);
604
605   if(olsr_cnf->ip_version == AF_INET)
606     {
607       /* IP version 4 */
608       sin = (struct sockaddr_in *)&ifp->int_broadaddr;
609
610       /* Copy sin */
611       dst = *sin;
612       sin = &dst;
613
614       if (sin->sin_port == 0)
615         sin->sin_port = olsr_udp_port;
616     }
617   else
618     {
619       /* IP version 6 */
620       sin6 = (struct sockaddr_in6 *)&ifp->int6_multaddr;
621       /* Copy sin */
622       dst6 = *sin6;
623       sin6 = &dst6;
624     }
625
626   /*
627    *Call possible packet transform functions registered by plugins  
628    */
629   tmp_ptf_list = ptf_list;
630   while(tmp_ptf_list != NULL)
631     {
632       tmp_ptf_list->function(netbufs[ifp->if_nr]->buff, &netbufs[ifp->if_nr]->pending);
633       tmp_ptf_list = tmp_ptf_list->next;
634     }
635
636   /*
637    *if the -dispout option was given
638    *we print the contetnt of the packets
639    */
640   if(disp_pack_out)
641     {
642       switch(netbufs[ifp->if_nr]->buff[4])
643         {
644         case(HELLO_MESSAGE):printf("\n\tHELLO ");break;
645         case(TC_MESSAGE):printf("\n\tTC ");break;
646         case(MID_MESSAGE):printf("\n\tMID ");break;
647         case(HNA_MESSAGE):printf("\n\tHNA ");break;
648         default:printf("\n\tTYPE: %d ", netbufs[ifp->if_nr]->buff[4]); break;
649         }
650       if(olsr_cnf->ip_version == AF_INET)
651         printf("to %s size: %d\n\t", ip_to_string((olsr_u32_t *)&sin->sin_addr.s_addr), netbufs[ifp->if_nr]->pending);
652       else
653         printf("to %s size: %d\n\t", ip6_to_string(&sin6->sin6_addr), netbufs[ifp->if_nr]->pending);
654
655       x = 0;
656
657       for(i = 0; i < netbufs[ifp->if_nr]->pending;i++)
658         {
659           if(x == 4)
660             {
661               x = 0;
662               printf("\n\t");
663             }
664           x++;
665           if(olsr_cnf->ip_version == AF_INET)
666             printf(" %3i", (u_char) netbufs[ifp->if_nr]->buff[i]);
667           else
668             printf(" %2x", (u_char) netbufs[ifp->if_nr]->buff[i]);
669         }
670       
671       printf("\n");
672     }
673   
674   if(olsr_cnf->ip_version == AF_INET)
675     {
676       /* IP version 4 */
677       if(sendto(ifp->olsr_socket, 
678                 netbufs[ifp->if_nr]->buff, 
679                 netbufs[ifp->if_nr]->pending, 
680                 MSG_DONTROUTE, 
681                 (struct sockaddr *)sin, 
682                 sizeof (*sin)) 
683          < 0)
684         {
685           perror("sendto(v4)");
686           olsr_syslog(OLSR_LOG_ERR, "OLSR: sendto IPv4 %m");
687           netbufs[ifp->if_nr]->pending = 0;
688           return -1;
689         }
690     }
691   else
692     {
693       /* IP version 6 */
694       if(sendto(ifp->olsr_socket, 
695                 netbufs[ifp->if_nr]->buff,
696                 netbufs[ifp->if_nr]->pending, 
697                 MSG_DONTROUTE, 
698                 (struct sockaddr *)sin6, 
699                 sizeof (*sin6)) 
700          < 0)
701         {
702           perror("sendto(v6)");
703           olsr_syslog(OLSR_LOG_ERR, "OLSR: sendto IPv6 %m");
704           fprintf(stderr, "Socket: %d interface: %d\n", ifp->olsr_socket, ifp->if_nr);
705           fprintf(stderr, "To: %s (size: %d)\n", ip6_to_string(&sin6->sin6_addr), (int)sizeof(*sin6));
706           fprintf(stderr, "Outputsize: %d\n", netbufs[ifp->if_nr]->pending);
707           netbufs[ifp->if_nr]->pending = 0;
708           return -1;
709         }
710     }
711   
712   netbufs[ifp->if_nr]->pending = 0;
713
714   return 1;
715 }
716
717 /**
718  *Processing OLSR data from socket. Reading data, setting 
719  *wich interface recieved the message, Sends IPC(if used) 
720  *and passes the packet on to parse_packet().
721  *
722  *@param fd the filedescriptor that data should be read from.
723  *@return nada
724  */
725 void
726 olsr_input(int fd)
727 {
728   /* sockaddr_in6 is bigger than sockaddr !!!! */
729   struct sockaddr_storage from;
730   size_t fromlen;
731   int cc;
732   struct interface *olsr_in_if;
733   union olsr_ip_addr from_addr;
734
735
736   for (;;) 
737     {
738       fromlen = sizeof(struct sockaddr_storage);
739
740       cc = recvfrom(fd, 
741                     inbuf, 
742                     sizeof (inbuf), 
743                     0, 
744                     (struct sockaddr *)&from, 
745                     &fromlen);
746
747       if (cc <= 0) 
748         {
749           if (cc < 0 && errno != EWOULDBLOCK)
750             {
751               olsr_printf(1, "error recvfrom: %s", strerror(errno));
752               olsr_syslog(OLSR_LOG_ERR, "error recvfrom: %m");
753             }
754           break;
755         }
756
757       if(olsr_cnf->ip_version == AF_INET)
758         {
759           /* IPv4 sender address */
760           COPY_IP(&from_addr, &((struct sockaddr_in *)&from)->sin_addr.s_addr);
761         }
762       else
763         {
764           /* IPv6 sender address */
765           COPY_IP(&from_addr, &((struct sockaddr_in6 *)&from)->sin6_addr);
766         }
767
768       /* are we talking to ourselves? */
769       if(if_ifwithaddr(&from_addr) != NULL)
770         return;
771
772 #ifdef DEBUG
773       olsr_printf(5, "Recieved a packet from %s\n", olsr_ip_to_string((union olsr_ip_addr *)&((struct sockaddr_in *)&from)->sin_addr.s_addr));
774 #endif
775       //printf("\nCC: %d FROMLEN: %d\n\n", cc, fromlen);
776       if ((olsr_cnf->ip_version == AF_INET) && (fromlen != sizeof (struct sockaddr_in)))
777         break;
778       else if ((olsr_cnf->ip_version == AF_INET6) && (fromlen != sizeof (struct sockaddr_in6)))
779         break;
780
781       //printf("Recieved data on socket %d\n", socknr);
782
783
784       if((olsr_in_if = if_ifwithsock(fd)) == NULL)
785         {
786           olsr_printf(1, "Could not find input interface for message from %s size %d\n",
787                       olsr_ip_to_string(&from_addr),
788                       cc);
789           olsr_syslog(OLSR_LOG_ERR, "Could not find input interface for message from %s size %d\n",
790                  olsr_ip_to_string(&from_addr),
791                  cc);
792           return ;
793         }
794
795       /*
796        * &from - sender
797        * &inbuf.olsr 
798        * cc - bytes read
799        */
800       parse_packet((struct olsr *)inbuf, cc, olsr_in_if, &from_addr);
801     
802     }
803 }
804
805