Added CVS Id to all C and haeder files
[olsrd.git] / src / linux / ifnet.c
1
2 /*
3  * OLSR ad-hoc routing table management protocol
4  * Copyright (C) 2003 Andreas T√łnnesen (andreto@ifi.uio.no)
5  *
6  * This file is part of olsr.org.
7  *
8  * olsr.org is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * olsr.org is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with olsr.org; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  * 
22  * 
23  * $Id: ifnet.c,v 1.6 2004/09/21 19:08:58 kattemat Exp $
24  *
25  */
26
27
28 /*
29  *Wireless definitions for ioctl calls
30  *(from linux/wireless.h)
31  */
32 #define SIOCGIWNAME     0x8B01          /* get name == wireless protocol */
33 #define SIOCSIWNWID     0x8B02          /* set network id (the cell) */
34 #define SIOCGIWNWID     0x8B03          /* get network id */
35 #define SIOCSIWFREQ     0x8B04          /* set channel/frequency (Hz) */
36 #define SIOCGIWFREQ     0x8B05          /* get channel/frequency (Hz) */
37 #define SIOCSIWMODE     0x8B06          /* set operation mode */
38 #define SIOCGIWMODE     0x8B07          /* get operation mode */
39 #define SIOCSIWSENS     0x8B08          /* set sensitivity (dBm) */
40 #define SIOCGIWSENS     0x8B09          /* get sensitivity (dBm) */
41
42
43 #include "../interfaces.h"
44 #include "../ifnet.h"
45 #include "../defs.h"
46 #include "../socket_parser.h"
47 #include "../parser.h"
48 #include <signal.h>
49 #include <net/if.h>
50 #include <net/if_arp.h>
51 #include <asm/types.h>
52 #include <arpa/inet.h>
53 #include <netdb.h>
54
55
56
57 int
58 set_flag(char *ifname, short flag)
59 {
60   struct ifreq ifr;
61
62   strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
63
64   /* Get flags */
65   if (ioctl(ioctl_s, SIOCGIFFLAGS, &ifr) < 0) 
66     {
67       fprintf(stderr,"ioctl (get interface flags)");
68       return -1;
69     }
70
71   strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
72   
73   //printf("Setting flags for if \"%s\"\n", ifr.ifr_name);
74
75   if(!(ifr.ifr_flags & (IFF_UP | IFF_RUNNING)))
76     {
77       /* Add UP */
78       ifr.ifr_flags |= (IFF_UP | IFF_RUNNING);
79       /* Set flags + UP */
80       if(ioctl(ioctl_s, SIOCSIFFLAGS, &ifr) < 0)
81         {
82           fprintf(stderr, "ERROR(%s): %s\n", ifr.ifr_name, strerror(errno));
83           return -1;
84         }
85     }
86   return 1;
87
88 }
89
90
91
92
93 void
94 check_interface_updates()
95 {
96   struct if_name *tmp_if;
97
98 #ifdef DEBUG
99   olsr_printf(3, "Checking for updates in the interface set\n");
100 #endif
101
102   for(tmp_if = if_names; tmp_if != NULL; tmp_if = tmp_if->next)
103     {
104
105       if(tmp_if->configured)
106         chk_if_changed(tmp_if);
107       else
108         chk_if_up(tmp_if, 1);
109     }
110
111   return;
112 }
113
114 /**
115  * Checks if an initialized interface is changed
116  * that is if it has been set down or the address
117  * has been changed.
118  *
119  *@param iface the if_name struct describing the interface
120  */
121 int
122 chk_if_changed(struct if_name *iface)
123 {
124   struct interface *ifp, *tmp_ifp;
125   struct ifreq ifr;
126   struct sockaddr_in6 tmp_saddr6;
127   int if_changes;
128   struct ifchgf *tmp_ifchgf_list;
129   if_changes = 0;
130
131 #ifdef DEBUG
132   olsr_printf(3, "Checking if %s is set down or changed\n", iface->name);
133 #endif
134
135   ifp = iface->interf;
136
137   if(ifp == NULL)
138     {
139       /* Should not happen */
140       iface->configured = 0;
141       return 0;
142     }
143
144   memset(&ifr, 0, sizeof(struct ifreq));
145   strncpy(ifr.ifr_name, iface->name, IFNAMSIZ);
146
147
148   /* Get flags (and check if interface exists) */
149   if (ioctl(ioctl_s, SIOCGIFFLAGS, &ifr) < 0) 
150     {
151       olsr_printf(1, "No such interface: %s\n", iface->name);
152       goto remove_interface;
153     }
154
155   ifp->int_flags = ifr.ifr_flags | IFF_INTERFACE;
156
157   /*
158    * First check if the interface is set DOWN
159    */
160
161   if ((ifp->int_flags & IFF_UP) == 0)
162     {
163       olsr_printf(1, "\tInterface %s not up - removing it...\n", iface->name);
164       goto remove_interface;
165     }
166
167   /*
168    * We do all the interface type checks over.
169    * This is because the interface might be a PCMCIA card. Therefore
170    * It might not be the same physical interface as we configured earlier.
171    */
172
173   /* Check broadcast */
174   if ((ipversion == AF_INET) && (!(ifp->int_flags & IFF_BROADCAST))) 
175     {
176       olsr_printf(1, "\tNo broadcast - removing\n");
177       goto remove_interface;
178     }
179
180   if (ifp->int_flags & IFF_LOOPBACK)
181     {
182       olsr_printf(1, "\tThis is a loopback interface - removing it...\n");
183       goto remove_interface;
184     }
185
186
187   /* trying to detect if interface is wireless. */
188   ifp->is_wireless = check_wireless_interface(&ifr);
189
190   /* Set interface metric */
191   ifp->int_metric = ifp->is_wireless;
192
193   /* Get interface index */
194   ifp->if_index = if_nametoindex(ifr.ifr_name);
195
196   /*
197    * Now check if the IP has changed
198    */
199   
200   /* IP version 6 */
201   if(ipversion == AF_INET6)
202     {
203       /* Get interface address */
204       
205       if(get_ipv6_address(ifr.ifr_name, &tmp_saddr6, ipv6_addrtype) <= 0)
206         {
207           if(ipv6_addrtype == IPV6_ADDR_SITELOCAL)
208             olsr_printf(1, "\tCould not find site-local IPv6 address for %s\n", ifr.ifr_name);
209           else
210             olsr_printf(1, "\tCould not find global IPv6 address for %s\n", ifr.ifr_name);
211           
212           
213           goto remove_interface;
214         }
215       
216 #ifdef DEBUG
217       olsr_printf(3, "\tAddress: %s\n", ip6_to_string(&tmp_saddr6.sin6_addr));
218 #endif
219
220       if(memcmp(&tmp_saddr6.sin6_addr, &ifp->int6_addr.sin6_addr, ipsize) != 0)
221         {
222           olsr_printf(1, "New IP address for %s:\n", ifr.ifr_name);
223           olsr_printf(1, "\tOld: %s\n", ip6_to_string(&ifp->int6_addr.sin6_addr));
224           olsr_printf(1, "\tNew: %s\n", ip6_to_string(&tmp_saddr6.sin6_addr));
225
226           /* Check main addr */
227           if(memcmp(&main_addr, &tmp_saddr6.sin6_addr, ipsize) == 0)
228             {
229               /* Update main addr */
230               memcpy(&main_addr, &tmp_saddr6.sin6_addr, ipsize);
231             }
232
233           /* Update address */
234           memcpy(&ifp->int6_addr.sin6_addr, &tmp_saddr6.sin6_addr, ipsize);
235           memcpy(&ifp->ip_addr, &tmp_saddr6.sin6_addr, ipsize);
236
237           /*
238            *Call possible ifchange functions registered by plugins  
239            */
240           tmp_ifchgf_list = ifchgf_list;
241           while(tmp_ifchgf_list != NULL)
242             {
243               tmp_ifchgf_list->function(ifp, IFCHG_IF_UPDATE);
244               tmp_ifchgf_list = tmp_ifchgf_list->next;
245             }
246
247           return 1;               
248         }
249       return 0;
250
251     }
252   else
253   /* IP version 4 */
254     {
255       /* Check interface address (IPv4)*/
256       if(ioctl(ioctl_s, SIOCGIFADDR, &ifr) < 0) 
257         {
258           olsr_printf(1, "\tCould not get address of interface - removing it\n");
259           goto remove_interface;
260         }
261
262 #ifdef DEBUG
263       olsr_printf(3, "\tAddress:%s\n", sockaddr_to_string(&ifr.ifr_addr));
264 #endif
265
266       if(memcmp(&((struct sockaddr_in *)&ifp->int_addr)->sin_addr.s_addr,
267                 &((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr, 
268                 ipsize) != 0)
269         {
270           /* New address */
271           olsr_printf(1, "IPv4 address changed for %s\n", ifr.ifr_name);
272           olsr_printf(1, "\tOld:%s\n", sockaddr_to_string(&ifp->int_addr));
273           olsr_printf(1, "\tNew:%s\n", sockaddr_to_string(&ifr.ifr_addr));
274           
275           if(memcmp(&main_addr, 
276                     &((struct sockaddr_in *)&ifp->int_addr)->sin_addr.s_addr, 
277                     ipsize) == 0)
278             {
279               olsr_printf(1, "New main address: %s\n", sockaddr_to_string(&ifr.ifr_addr));
280               olsr_syslog(OLSR_LOG_INFO, "New main address: %s\n", sockaddr_to_string(&ifr.ifr_addr));
281               memcpy(&main_addr, 
282                      &((struct sockaddr_in *)&ifp->int_addr)->sin_addr.s_addr, 
283                      ipsize);
284             }
285
286           ifp->int_addr = ifr.ifr_addr;
287           memcpy(&ifp->ip_addr, 
288                  &((struct sockaddr_in *)&ifp->int_addr)->sin_addr.s_addr, 
289                  ipsize);
290
291           if_changes = 1;
292         }
293
294       /* Check netmask */
295       if (ioctl(ioctl_s, SIOCGIFNETMASK, &ifr) < 0) 
296         {
297           olsr_syslog(OLSR_LOG_ERR, "%s: ioctl (get broadaddr)", ifr.ifr_name);
298           goto remove_interface;
299         }
300
301 #ifdef DEBUG
302       olsr_printf(3, "\tNetmask:%s\n", sockaddr_to_string(&ifr.ifr_netmask));
303 #endif
304
305       if(memcmp(&((struct sockaddr_in *)&ifp->int_netmask)->sin_addr.s_addr,
306                 &((struct sockaddr_in *)&ifr.ifr_netmask)->sin_addr.s_addr, 
307                 ipsize) != 0)
308         {
309           /* New address */
310           olsr_printf(1, "IPv4 netmask changed for %s\n", ifr.ifr_name);
311           olsr_printf(1, "\tOld:%s\n", sockaddr_to_string(&ifp->int_netmask));
312           olsr_printf(1, "\tNew:%s\n", sockaddr_to_string(&ifr.ifr_netmask));
313
314           ifp->int_netmask = ifr.ifr_netmask;
315
316           if_changes = 1;
317         }
318             
319       /* Check broadcast address */      
320       if (ioctl(ioctl_s, SIOCGIFBRDADDR, &ifr) < 0) 
321         {
322           olsr_syslog(OLSR_LOG_ERR, "%s: ioctl (get broadaddr)", ifr.ifr_name);
323           goto remove_interface;
324         }
325
326 #ifdef DEBUG
327       olsr_printf(3, "\tBroadcast address:%s\n", sockaddr_to_string(&ifr.ifr_broadaddr));
328 #endif
329       
330       if(memcmp(&((struct sockaddr_in *)&ifp->int_broadaddr)->sin_addr.s_addr,
331                 &((struct sockaddr_in *)&ifr.ifr_broadaddr)->sin_addr.s_addr, 
332                 ipsize) != 0)
333         {
334
335           /* New address */
336           olsr_printf(1, "IPv4 broadcast changed for %s\n", ifr.ifr_name);
337           olsr_printf(1, "\tOld:%s\n", sockaddr_to_string(&ifp->int_broadaddr));
338           olsr_printf(1, "\tNew:%s\n", sockaddr_to_string(&ifr.ifr_broadaddr));
339
340           ifp->int_broadaddr = ifr.ifr_broadaddr;
341           if_changes = 1;
342         }            
343       
344     }
345
346   if(if_changes)
347     {
348       /*
349        *Call possible ifchange functions registered by plugins  
350        */
351       tmp_ifchgf_list = ifchgf_list;
352       while(tmp_ifchgf_list != NULL)
353         {
354           tmp_ifchgf_list->function(ifp, IFCHG_IF_UPDATE);
355           tmp_ifchgf_list = tmp_ifchgf_list->next;
356         }
357     }
358   return if_changes;
359
360
361  remove_interface:
362   olsr_printf(1, "Removing interface %s\n", iface->name);
363   olsr_syslog(OLSR_LOG_INFO, "Removing interface %s\n", iface->name);
364
365   /*
366    *Call possible ifchange functions registered by plugins  
367    */
368   tmp_ifchgf_list = ifchgf_list;
369   while(tmp_ifchgf_list != NULL)
370     {
371       tmp_ifchgf_list->function(ifp, IFCHG_IF_REMOVE);
372       tmp_ifchgf_list = tmp_ifchgf_list->next;
373     }
374   
375   /* Dequeue */
376   if(ifp == ifnet)
377     {
378       ifnet = ifp->int_next;
379     }
380   else
381     {
382       tmp_ifp = ifnet;
383       while(tmp_ifp->int_next != ifp)
384         {
385           tmp_ifp = tmp_ifp->int_next;
386         }
387       tmp_ifp->int_next = ifp->int_next;
388     }
389   /* Check main addr */
390   if(COMP_IP(&main_addr, &ifp->ip_addr))
391     {
392       if(ifnet == NULL)
393         {
394           /* No more interface */
395           memset(&main_addr, 0, ipsize);
396           olsr_printf(1, "No more interfaces...\n");
397         }
398       else
399         {
400           COPY_IP(&main_addr, &ifnet->ip_addr);
401           olsr_printf(1, "New main address: %s\n", olsr_ip_to_string(&main_addr));
402           olsr_syslog(OLSR_LOG_INFO, "New main address: %s\n", olsr_ip_to_string(&main_addr));
403         }
404     }
405
406   nbinterf--;
407
408   iface->configured = 0;
409   iface->interf = NULL;
410   /* Close olsr socket */
411   close(ifp->olsr_socket);
412   remove_olsr_socket(ifp->olsr_socket, &olsr_input);
413   /* Free memory */
414   free(ifp->int_name);
415   free(ifp);
416
417   if((nbinterf == 0) && (!allow_no_int))
418     {
419       olsr_printf(1, "No more active interfaces - exiting.\n");
420       olsr_syslog(OLSR_LOG_INFO, "No more active interfaces - exiting.\n");
421       exit_value = EXIT_FAILURE;
422       kill(getpid(), SIGINT);
423     }
424
425   return 0;
426
427 }
428
429
430
431 /**
432  * Initializes a interface described by iface,
433  * if it is set up and is of the correct type.
434  *
435  *@param iface the if_name struct describing the interface
436  *@param so the socket to use for ioctls
437  *
438  */
439 int
440 chk_if_up(struct if_name *iface, int debuglvl)
441 {
442   struct interface ifs, *ifp;
443   struct ifreq ifr;
444   union olsr_ip_addr null_addr;
445   struct ifchgf *tmp_ifchgf_list;
446
447   memset(&ifr, 0, sizeof(struct ifreq));
448   strncpy(ifr.ifr_name, iface->name, IFNAMSIZ);
449
450   olsr_printf(debuglvl, "Checking %s:\n", ifr.ifr_name);
451
452   /* Get flags (and check if interface exists) */
453   if (ioctl(ioctl_s, SIOCGIFFLAGS, &ifr) < 0) 
454     {
455       olsr_printf(debuglvl, "\tNo such interface!\n");
456       return 0;
457     }
458
459   ifs.int_flags = ifr.ifr_flags | IFF_INTERFACE;      
460
461
462   if ((ifs.int_flags & IFF_UP) == 0)
463     {
464       olsr_printf(debuglvl, "\tInterface not up - skipping it...\n");
465       return 0;
466     }
467
468   /* Check broadcast */
469   if ((ipversion == AF_INET) && (!(ifs.int_flags & IFF_BROADCAST))) 
470     {
471       olsr_printf(debuglvl, "\tNo broadcast - skipping\n");
472       return 0;
473     }
474
475
476   if (ifs.int_flags & IFF_LOOPBACK)
477     {
478       olsr_printf(debuglvl, "\tThis is a loopback interface - skipping it...\n");
479       return 0;
480     }
481
482   /* trying to detect if interface is wireless. */
483   if(check_wireless_interface(&ifr))
484     {
485       olsr_printf(debuglvl, "\tWireless interface detected\n");
486       ifs.is_wireless = 1;
487     }
488   else
489     {
490       olsr_printf(debuglvl, "\tNot a wireless interface\n");
491       ifs.is_wireless = 0;
492     }
493
494   
495   /* IP version 6 */
496   if(ipversion == AF_INET6)
497     {
498       /* Get interface address */
499       
500       if(get_ipv6_address(ifr.ifr_name, &ifs.int6_addr, ipv6_addrtype) <= 0)
501         {
502           if(ipv6_addrtype == IPV6_ADDR_SITELOCAL)
503             olsr_printf(debuglvl, "\tCould not find site-local IPv6 address for %s\n", ifr.ifr_name);
504           else
505             olsr_printf(debuglvl, "\tCould not find global IPv6 address for %s\n", ifr.ifr_name);
506           
507           return 0;
508         }
509       
510       olsr_printf(debuglvl, "\tAddress: %s\n", ip6_to_string(&ifs.int6_addr.sin6_addr));
511       
512       
513       /* Set default multicast address */
514       if(inet_pton(AF_INET6, ipv6_mult, &ifs.int6_multaddr.sin6_addr) < 0)
515         {
516           perror("Convert multicastaddr");
517           return 0;
518         }
519           
520       /* Set address family */
521       ifs.int6_multaddr.sin6_family = AF_INET6;
522       /* Set port */
523       ifs.int6_multaddr.sin6_port = olsr_udp_port;
524       
525       olsr_printf(debuglvl, "\tMulticast: %s\n", ip6_to_string(&ifs.int6_multaddr.sin6_addr));
526       
527     }
528   /* IP version 4 */
529   else
530     {
531       /* Get interface address (IPv4)*/
532       if(ioctl(ioctl_s, SIOCGIFADDR, &ifr) < 0) 
533         {
534           olsr_printf(debuglvl, "\tCould not get address of interface - skipping it\n");
535           return 0;
536         }
537       
538       ifs.int_addr = ifr.ifr_addr;
539       
540       /* Find netmask */
541       
542       if (ioctl(ioctl_s, SIOCGIFNETMASK, &ifr) < 0) 
543         {
544           olsr_syslog(OLSR_LOG_ERR, "%s: ioctl (get broadaddr)", ifr.ifr_name);
545           return 0;
546         }
547       
548       ifs.int_netmask = ifr.ifr_netmask;
549       
550       /* Find broadcast address */
551       
552       if (ioctl(ioctl_s, SIOCGIFBRDADDR, &ifr) < 0) 
553         {
554           olsr_syslog(OLSR_LOG_ERR, "%s: ioctl (get broadaddr)", ifr.ifr_name);
555           return 0;
556         }
557       
558       ifs.int_broadaddr = ifr.ifr_broadaddr;
559       
560       
561       /* Deactivate IP spoof filter */
562       deactivate_spoof(ifr.ifr_name, nbinterf, ipversion);
563       
564       /* Disable ICMP redirects */
565       disable_redirects(ifr.ifr_name, nbinterf, ipversion);
566       
567     }
568   
569   
570   /* Get interface index */
571   
572   ifs.if_index = if_nametoindex(ifr.ifr_name);
573   
574   /* Set interface metric */
575   ifs.int_metric = ifs.is_wireless;
576   
577   /* setting the interfaces number*/
578   ifs.if_nr = iface->index;
579
580   olsr_syslog(OLSR_LOG_INFO, "Adding interface %s\n", iface->name);
581   olsr_printf(1, "Interface %s set up for use with index %d\n", iface->name, ifs.if_nr);
582
583   if(ipversion == AF_INET)
584     {
585       olsr_printf(1, "\tAddress:%s\n", sockaddr_to_string(&ifs.int_addr));
586       olsr_printf(1, "\tNetmask:%s\n", sockaddr_to_string(&ifs.int_netmask));
587       olsr_printf(1, "\tBroadcast address:%s\n", sockaddr_to_string(&ifs.int_broadaddr));
588     }
589   else
590     {
591       olsr_printf(1, "\tAddress: %s\n", ip6_to_string(&ifs.int6_addr.sin6_addr));
592       olsr_printf(1, "\tMulticast: %s\n", ip6_to_string(&ifs.int6_multaddr.sin6_addr));
593     }
594
595   nbinterf++; 
596   
597   ifp = olsr_malloc(sizeof (struct interface), "Interface update 2");
598   
599   iface->configured = 1;
600   iface->interf = ifp;
601   
602   memcpy(ifp, &ifs, sizeof(struct interface));
603   
604   ifp->int_name = olsr_malloc(strlen(ifr.ifr_name) + 1, "Interface update 3");
605       
606   strcpy(ifp->int_name, ifr.ifr_name);
607   /* Segfaults if using strncpy(IFNAMSIZ) why oh why?? */
608   ifp->int_next = ifnet;
609   ifnet = ifp;
610
611   if(ipversion == AF_INET)
612     {
613       /* IP version 4 */
614       ifp->ip_addr.v4 = ((struct sockaddr_in *)&ifp->int_addr)->sin_addr.s_addr;
615       
616       /*
617        *We create one socket for each interface and bind
618        *the socket to it. This to ensure that we can control
619        *on what interface the message is transmitted
620        */
621       
622       ifp->olsr_socket = getsocket((struct sockaddr *)&addrsock, bufspace, ifp->int_name);
623       
624       if (ifp->olsr_socket < 0)
625         {
626           fprintf(stderr, "Could not initialize socket... exiting!\n\n");
627           olsr_syslog(OLSR_LOG_ERR, "Could not initialize socket... exiting!\n\n");
628           exit_value = EXIT_FAILURE;
629           kill(getpid(), SIGINT);
630         }
631     }
632   else
633     {
634       /* IP version 6 */
635       memcpy(&ifp->ip_addr, &ifp->int6_addr.sin6_addr, ipsize);
636
637       
638       /*
639        *We create one socket for each interface and bind
640        *the socket to it. This to ensure that we can control
641        *on what interface the message is transmitted
642        */
643       
644       ifp->olsr_socket = getsocket6(&addrsock6, bufspace, ifp->int_name);
645       
646       join_mcast(ifp, ifp->olsr_socket);
647       
648       if (ifp->olsr_socket < 0)
649         {
650           fprintf(stderr, "Could not initialize socket... exiting!\n\n");
651           olsr_syslog(OLSR_LOG_ERR, "Could not initialize socket... exiting!\n\n");
652           exit_value = EXIT_FAILURE;
653           kill(getpid(), SIGINT);
654         }
655       
656     }
657   
658   /* Register socket */
659   add_olsr_socket(ifp->olsr_socket, &olsr_input);
660   
661   
662   /* Set TOS */
663   
664   if (setsockopt(ifp->olsr_socket, SOL_SOCKET, SO_PRIORITY, (char*)&precedence, sizeof(precedence)) < 0)
665     {
666       perror("setsockopt(SO_PRIORITY)");
667       olsr_syslog(OLSR_LOG_ERR, "OLSRD: setsockopt(SO_PRIORITY) error %m");
668     }
669   if (setsockopt(ifp->olsr_socket, SOL_IP, IP_TOS, (char*)&tos_bits, sizeof(tos_bits)) < 0)    
670     {
671       perror("setsockopt(IP_TOS)");
672       olsr_syslog(OLSR_LOG_ERR, "setsockopt(IP_TOS) error %m");
673     }
674   
675   /*
676    *Initialize sequencenumber as a random 16bit value
677    */
678   ifp->olsr_seqnum = random() & 0xFFFF;
679
680   /*
681    * Set main address if this is the only interface
682    */
683   memset(&null_addr, 0, ipsize);
684   if(COMP_IP(&null_addr, &main_addr))
685     {
686       COPY_IP(&main_addr, &ifp->ip_addr);
687       olsr_printf(1, "New main address: %s\n", olsr_ip_to_string(&main_addr));
688       olsr_syslog(OLSR_LOG_INFO, "New main address: %s\n", olsr_ip_to_string(&main_addr));
689     }
690   
691   /*
692    *Call possible ifchange functions registered by plugins  
693    */
694   tmp_ifchgf_list = ifchgf_list;
695   while(tmp_ifchgf_list != NULL)
696     {
697       tmp_ifchgf_list->function(ifp, IFCHG_IF_ADD);
698       tmp_ifchgf_list = tmp_ifchgf_list->next;
699     }
700
701   return 1;
702 }
703
704
705
706
707 /**
708  *Check if a interface is wireless
709  *Returns 1 if no info can be gathered
710  *
711  *@param sock socket to use for kernel communication
712  *@param ifr a ifreq struct describing the interface
713  *
714  *@return 1 if interface is wireless(or no info was
715  *found) 0 if not.
716  */
717 int
718 check_wireless_interface(struct ifreq *ifr)
719 {
720   if(ioctl(ioctl_s, SIOCGIWNAME, ifr) >= 0)
721     {
722       return 1;
723     }
724   else
725     {
726       return 0;
727     }
728
729 }
730