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