Added CVS Id to all C and haeder files
[olsrd.git] / src / interfaces.c
1 /*
2  * OLSR ad-hoc routing table management protocol
3  * Copyright (C) 2003 Andreas T√łnnesen (andreto@ifi.uio.no)
4  *
5  * This file is part of the olsr.org OLSR daemon.
6  *
7  * olsr.org is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * olsr.org is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with olsr.org; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  * 
21  * 
22  * $Id: interfaces.c,v 1.6 2004/09/21 19:08:57 kattemat Exp $
23  *
24  */
25
26 #include "defs.h"
27 #include "interfaces.h"
28 #include "ifnet.h"
29 #include "scheduler.h"
30
31 /**
32  *Do initialization of various data needed for
33  *network interface management.
34  *This function also tries to set up the given interfaces.
35  *
36  *@return the number of interfaces configured
37  */
38 int
39 ifinit()
40 {
41   struct if_name *tmp_if;
42
43
44   /* Initial values */
45   ifnet = NULL;
46   nbinterf = 0;
47
48   /*
49    *Initializing addrsock struct to be
50    *used on all the sockets
51    */
52   if(ipversion == AF_INET)
53     {
54       /* IP version 4 */
55       memset(&addrsock, 0, sizeof (addrsock));
56       addrsock.sin_family = AF_INET;
57       addrsock.sin_port = olsr_udp_port;
58       (addrsock.sin_addr).s_addr = INADDR_ANY;
59     }
60   else
61     {
62       /* IP version 6 */
63       memset(&addrsock6, 0, sizeof (addrsock6));
64       addrsock6.sin6_family = AF_INET6;
65       addrsock6.sin6_port = olsr_udp_port;
66       //(addrsock6.sin6_addr).s_addr = IN6ADDR_ANY_INIT;
67     }
68
69   olsr_printf(1, "\n ---- Interface configuration ---- \n\n");
70   /* Run trough all interfaces immedeatly */
71   for(tmp_if = if_names; tmp_if != NULL; tmp_if = tmp_if->next)
72     {
73       chk_if_up(tmp_if, 1);     
74     }
75   
76   /* register network interface update function with scheduler */
77   olsr_register_scheduler_event(&check_interface_updates, 5.0, 0, NULL);
78
79   return nbinterf;
80 }
81
82
83
84 /**
85  *Find the local interface with a given address.
86  *
87  *@param addr the address to check.
88  *
89  *@return the interface struct representing the interface
90  *that matched the address.
91  */
92
93 struct interface *
94 if_ifwithaddr(union olsr_ip_addr *addr)
95 {
96   struct interface *ifp;
97
98   for (ifp = ifnet; ifp; ifp = ifp->int_next)
99     {
100       if(ipversion == AF_INET)
101         {
102           /* IPv4 */
103           //printf("Checking: %s == ", inet_ntoa(((struct sockaddr_in *)&ifp->int_addr)->sin_addr));
104           //printf("%s\n", olsr_ip_to_string(addr));
105
106           if (COMP_IP(&((struct sockaddr_in *)&ifp->int_addr)->sin_addr, addr))
107               return ifp;
108         }
109       else
110         {
111           /* IPv6 */
112           //printf("Checking %s ", olsr_ip_to_string((union olsr_ip_addr *)&ifp->int6_addr.sin6_addr));
113           //printf("== %s\n", olsr_ip_to_string((union olsr_ip_addr *)&((struct sockaddr_in6 *)addr)->sin6_addr));
114           if (COMP_IP(&ifp->int6_addr.sin6_addr, addr))
115             return ifp;
116         }
117     }
118   return NULL;
119 }
120
121
122
123 /**
124  *Find the interface with a given number.
125  *
126  *@param nr the number of the interface to find.
127  *
128  *@return return the interface struct representing the interface
129  *that matched the number.
130  */
131 struct interface *
132 if_ifwithsock(int fd)
133 {
134   struct interface *ifp;
135   ifp = ifnet;
136
137   while (ifp) 
138     {
139       if (ifp->olsr_socket == fd)
140         return ifp;
141       ifp = ifp->int_next;
142     }
143   
144   return (ifp);
145 }
146
147 #ifndef WIN32
148 /*
149  *From net-tools lib/interface.c
150  *
151  */
152
153 int
154 get_ipv6_address(char *ifname, struct sockaddr_in6 *saddr6, int scope_in)
155 {
156   char addr6[40], devname[IFNAMSIZ];
157   char addr6p[8][5];
158   int plen, scope, dad_status, if_idx;
159   FILE *f;
160   struct sockaddr_in6 tmp_sockaddr6;
161
162   if ((f = fopen(_PATH_PROCNET_IFINET6, "r")) != NULL) 
163     {
164       while (fscanf(f, "%4s%4s%4s%4s%4s%4s%4s%4s %02x %02x %02x %02x %20s\n",
165                     addr6p[0], addr6p[1], addr6p[2], addr6p[3],
166                     addr6p[4], addr6p[5], addr6p[6], addr6p[7],
167                     &if_idx, &plen, &scope, &dad_status, devname) != EOF) 
168         {
169           if (!strcmp(devname, ifname)) 
170             {
171               sprintf(addr6, "%s:%s:%s:%s:%s:%s:%s:%s",
172                       addr6p[0], addr6p[1], addr6p[2], addr6p[3],
173                       addr6p[4], addr6p[5], addr6p[6], addr6p[7]);
174               if(debug_level > 1)
175                 {
176                   olsr_printf(1, "\tinet6 addr: %s\n", addr6);
177                   olsr_printf(3, "\tScope:");
178                 }
179               if(scope == scope_in)
180                 {
181                   olsr_printf(3, "IPv6 addr:\n");
182                   inet_pton(AF_INET6,addr6,&tmp_sockaddr6);
183                   memcpy(&saddr6->sin6_addr, &tmp_sockaddr6, sizeof(struct in6_addr));    
184                   fclose(f);
185                   return 1;
186                 }
187             }
188         }
189       fclose(f);
190     }
191   
192   return 0;
193 }
194 #endif
195
196
197
198
199
200 /**
201  *Create a new interf_name struct using a given
202  *name and insert it into the interface list.
203  *
204  *@param name the name of the interface.
205  *
206  *@return nada
207  */
208 void
209 queue_if(char *name)
210 {
211
212   struct if_name *interf_n;
213
214   //printf("Adding interface %s\n", name);
215
216   /* check if the inerfaces already exists */
217   interf_n = if_names;
218   while(interf_n != NULL)
219     {
220       if(memcmp(interf_n->name, name, strlen(name)) == 0)
221         {
222           fprintf(stderr, "Duplicate interfaces defined... not adding %s\n", name);
223           return;
224         }
225       interf_n = interf_n->next;
226     }
227
228   interf_n = olsr_malloc(sizeof(struct if_name), "queue interface");
229
230   /* strlen () does not return length including terminating /0 */
231   interf_n->name = olsr_malloc(strlen(name) + 1, "queue interface name");
232   interf_n->configured = 0;
233   interf_n->interf = NULL;
234   interf_n->index = queued_ifs++;
235
236   strcpy(interf_n->name, name);
237   interf_n->next = if_names;
238   if_names = interf_n;
239
240 }
241
242
243
244
245 /**
246  *Add an ifchange function. These functions are called on all (non-initial)
247  *changes in the interface set.
248  *
249  *@param
250  *
251  *@return
252  */
253 int
254 add_ifchgf(int (*f)(struct interface *, int))
255 {
256
257   struct ifchgf *new_ifchgf;
258
259   new_ifchgf = olsr_malloc(sizeof(struct ifchgf), "Add ifchgfunction");
260
261   new_ifchgf->next = ifchgf_list;
262   new_ifchgf->function = f;
263
264   ifchgf_list = new_ifchgf;
265
266   return 1;
267 }
268
269
270
271 /*
272  * Remove an ifchange function
273  */
274 int
275 del_ifchgf(int (*f)(struct interface *, int))
276 {
277   struct ifchgf *tmp_ifchgf, *prev;
278
279   tmp_ifchgf = ifchgf_list;
280   prev = NULL;
281
282   while(tmp_ifchgf)
283     {
284       if(tmp_ifchgf->function == f)
285         {
286           /* Remove entry */
287           if(prev == NULL)
288             {
289               ifchgf_list = tmp_ifchgf->next;
290               free(tmp_ifchgf);
291             }
292           else
293             {
294               prev->next = tmp_ifchgf->next;
295               free(tmp_ifchgf);
296             }
297           return 1;
298         }
299       prev = tmp_ifchgf;
300       tmp_ifchgf = tmp_ifchgf->next;
301     }
302
303   return 0;
304 }