Fixed script and line-break quirks
[olsrd.git] / src / interfaces.c
1
2 /*
3  * The olsr.org Optimized Link-State Routing daemon(olsrd)
4  * Copyright (c) 2004, Andreas Tonnesen(andreto@olsr.org)
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  *   notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above copyright
14  *   notice, this list of conditions and the following disclaimer in
15  *   the documentation and/or other materials provided with the
16  *   distribution.
17  * * Neither the name of olsr.org, olsrd nor the names of its
18  *   contributors may be used to endorse or promote products derived
19  *   from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  *
34  * Visit http://www.olsr.org for more information.
35  *
36  * If you find this software useful feel free to make a donation
37  * to the project. For more information see the website or contact
38  * the copyright holders.
39  *
40  */
41
42 #include "defs.h"
43 #include "interfaces.h"
44 #include "ifnet.h"
45 #include "scheduler.h"
46 #include "olsr.h"
47 #include "net_olsr.h"
48 #include "ipcalc.h"
49
50 /* The interface linked-list */
51 struct interface *ifnet;
52
53 /* Ifchange functions */
54 struct ifchgf {
55   int (*function) (struct interface *, int);
56   struct ifchgf *next;
57 };
58
59 static struct ifchgf *ifchgf_list;
60
61 /* Some cookies for stats keeping */
62 struct olsr_cookie_info *interface_poll_timer_cookie = NULL;
63 struct olsr_cookie_info *hello_gen_timer_cookie = NULL;
64 struct olsr_cookie_info *tc_gen_timer_cookie = NULL;
65 struct olsr_cookie_info *mid_gen_timer_cookie = NULL;
66 struct olsr_cookie_info *hna_gen_timer_cookie = NULL;
67
68 /**
69  *Do initialization of various data needed for
70  *network interface management.
71  *This function also tries to set up the given interfaces.
72  *
73  *@return the number of interfaces configured
74  */
75 int
76 ifinit(void)
77 {
78   struct olsr_if *tmp_if;
79
80   /* Initial values */
81   ifnet = NULL;
82
83   /*
84    * Get some cookies for getting stats to ease troubleshooting.
85    */
86   interface_poll_timer_cookie = olsr_alloc_cookie("Interface Polling", OLSR_COOKIE_TYPE_TIMER);
87
88   hello_gen_timer_cookie = olsr_alloc_cookie("Hello Generation", OLSR_COOKIE_TYPE_TIMER);
89   tc_gen_timer_cookie = olsr_alloc_cookie("TC Generation", OLSR_COOKIE_TYPE_TIMER);
90   mid_gen_timer_cookie = olsr_alloc_cookie("MID Generation", OLSR_COOKIE_TYPE_TIMER);
91   hna_gen_timer_cookie = olsr_alloc_cookie("HNA Generation", OLSR_COOKIE_TYPE_TIMER);
92
93   OLSR_PRINTF(1, "\n ---- Interface configuration ---- \n\n");
94   /* Run trough all interfaces immedeatly */
95   for (tmp_if = olsr_cnf->interfaces; tmp_if != NULL; tmp_if = tmp_if->next) {
96     if (!tmp_if->host_emul) {
97       if (!olsr_cnf->host_emul) /* XXX: TEMPORARY! */
98         chk_if_up(tmp_if, 1);
99     } else {
100       add_hemu_if(tmp_if);
101     }
102   }
103
104   /* Kick a periodic timer for the network interface update function */
105   olsr_start_timer((unsigned int)olsr_cnf->nic_chgs_pollrate * MSEC_PER_SEC, 5, OLSR_TIMER_PERIODIC, &check_interface_updates, NULL,
106                    interface_poll_timer_cookie->ci_id);
107
108   return (ifnet == NULL) ? 0 : 1;
109 }
110
111 void
112 run_ifchg_cbs(struct interface *ifp, int flag)
113 {
114   struct ifchgf *tmp_ifchgf_list = ifchgf_list;
115
116   while (tmp_ifchgf_list != NULL) {
117     tmp_ifchgf_list->function(ifp, flag);
118     tmp_ifchgf_list = tmp_ifchgf_list->next;
119   }
120 }
121
122 /**
123  *Find the local interface with a given address.
124  *
125  *@param addr the address to check.
126  *
127  *@return the interface struct representing the interface
128  *that matched the address.
129  */
130
131 struct interface *
132 if_ifwithaddr(const union olsr_ip_addr *addr)
133 {
134   struct interface *ifp;
135
136   if (!addr)
137     return NULL;
138
139   for (ifp = ifnet; ifp; ifp = ifp->int_next) {
140     if (olsr_cnf->ip_version == AF_INET) {
141       /* IPv4 */
142       //printf("Checking: %s == ", inet_ntoa(((struct sockaddr_in *)&ifp->int_addr)->sin_addr));
143       //printf("%s\n", olsr_ip_to_string(addr));
144
145       if (((struct sockaddr_in *)&ifp->int_addr)->sin_addr.s_addr == addr->v4.s_addr)
146         return ifp;
147     } else {
148       /* IPv6 */
149       //printf("Checking %s ", olsr_ip_to_string((union olsr_ip_addr *)&ifp->int6_addr.sin6_addr));
150       //printf("== %s\n", olsr_ip_to_string((union olsr_ip_addr *)&((struct sockaddr_in6 *)addr)->sin6_addr));
151       if (ip6equal(&ifp->int6_addr.sin6_addr, &addr->v6))
152         return ifp;
153     }
154   }
155   return NULL;
156 }
157
158 /**
159  *Find the interface with a given number.
160  *
161  *@param nr the number of the interface to find.
162  *
163  *@return return the interface struct representing the interface
164  *that matched the number.
165  */
166 struct interface *
167 if_ifwithsock(int fd)
168 {
169   struct interface *ifp;
170   ifp = ifnet;
171
172   while (ifp) {
173     if (ifp->olsr_socket == fd)
174       return ifp;
175     ifp = ifp->int_next;
176   }
177
178   return NULL;
179 }
180
181 /**
182  *Find the interface with a given label.
183  *
184  *@param if_name the label of the interface to find.
185  *
186  *@return return the interface struct representing the interface
187  *that matched the label.
188  */
189 struct interface *
190 if_ifwithname(const char *if_name)
191 {
192   struct interface *ifp = ifnet;
193   while (ifp) {
194     /* good ol' strcmp should be sufficcient here */
195     if (strcmp(ifp->int_name, if_name) == 0) {
196       return ifp;
197     }
198     ifp = ifp->int_next;
199   }
200   return NULL;
201 }
202
203 /**
204  *Find the interface with a given interface index.
205  *
206  *@param iif_index of the interface to find.
207  *
208  *@return return the interface struct representing the interface
209  *that matched the iif_index.
210  */
211 struct interface *
212 if_ifwithindex(const int if_index)
213 {
214   struct interface *ifp = ifnet;
215   while (ifp != NULL) {
216     if (ifp->if_index == if_index) {
217       return ifp;
218     }
219     ifp = ifp->int_next;
220   }
221   return NULL;
222 }
223
224 /**
225  *Get an interface name for a given interface index
226  *
227  *@param iif_index of the interface to find.
228  *
229  *@return "" or interface name.
230  */
231 const char *
232 if_ifwithindex_name(const int if_index)
233 {
234   const struct interface *const ifp = if_ifwithindex(if_index);
235   return ifp == NULL ? "void" : ifp->int_name;
236 }
237
238 /**
239  *Create a new interf_name struct using a given
240  *name and insert it into the interface list.
241  *
242  *@param name the name of the interface.
243  *
244  *@return nada
245  */
246 struct olsr_if *
247 queue_if(const char *name, int hemu)
248 {
249   struct olsr_if *interf_n = olsr_cnf->interfaces;
250   size_t name_size;
251
252   //printf("Adding interface %s\n", name);
253
254   /* check if the inerfaces already exists */
255   while (interf_n != NULL) {
256     if (memcmp(interf_n->name, name, strlen(name)) == 0) {
257       fprintf(stderr, "Duplicate interfaces defined... not adding %s\n", name);
258       return NULL;
259     }
260     interf_n = interf_n->next;
261   }
262
263   interf_n = olsr_malloc(sizeof(struct olsr_if), "queue interface");
264
265   name_size = strlen(name) + 1;
266   interf_n->name = olsr_malloc(name_size, "queue interface name");
267   interf_n->cnf = NULL;
268   interf_n->interf = NULL;
269   interf_n->configured = 0;
270
271   interf_n->host_emul = hemu ? OLSR_TRUE : OLSR_FALSE;
272
273   strscpy(interf_n->name, name, name_size);
274   interf_n->next = olsr_cnf->interfaces;
275   olsr_cnf->interfaces = interf_n;
276
277   return interf_n;
278 }
279
280 /**
281  *Add an ifchange function. These functions are called on all (non-initial)
282  *changes in the interface set.
283  *
284  *@param
285  *
286  *@return
287  */
288 int
289 add_ifchgf(int (*f) (struct interface *, int))
290 {
291
292   struct ifchgf *new_ifchgf;
293
294   new_ifchgf = olsr_malloc(sizeof(struct ifchgf), "Add ifchgfunction");
295
296   new_ifchgf->next = ifchgf_list;
297   new_ifchgf->function = f;
298
299   ifchgf_list = new_ifchgf;
300
301   return 1;
302 }
303
304 /*
305  * Remove an ifchange function
306  */
307 int
308 del_ifchgf(int (*f) (struct interface *, int))
309 {
310   struct ifchgf *tmp_ifchgf, *prev;
311
312   tmp_ifchgf = ifchgf_list;
313   prev = NULL;
314
315   while (tmp_ifchgf) {
316     if (tmp_ifchgf->function == f) {
317       /* Remove entry */
318       if (prev == NULL) {
319         ifchgf_list = tmp_ifchgf->next;
320         free(tmp_ifchgf);
321       } else {
322         prev->next = tmp_ifchgf->next;
323         free(tmp_ifchgf);
324       }
325       return 1;
326     }
327     prev = tmp_ifchgf;
328     tmp_ifchgf = tmp_ifchgf->next;
329   }
330
331   return 0;
332 }
333
334 /*
335  * Local Variables:
336  * c-basic-offset: 2
337  * indent-tabs-mode: nil
338  * End:
339  */