Remove the olsr-specific duplicated types
[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 #include "common/string.h"
50
51 /* The interface linked-list */
52 struct interface *ifnet = NULL;
53
54 /* Ifchange functions */
55 struct ifchgf {
56   ifchg_cb_func function;
57   struct ifchgf *next;
58 };
59
60 static struct ifchgf *ifchgf_list = NULL;
61
62
63 /* Some cookies for stats keeping */
64 struct olsr_cookie_info *interface_poll_timer_cookie = NULL;
65 struct olsr_cookie_info *hello_gen_timer_cookie = NULL;
66 struct olsr_cookie_info *tc_gen_timer_cookie = NULL;
67 struct olsr_cookie_info *mid_gen_timer_cookie = NULL;
68 struct olsr_cookie_info *hna_gen_timer_cookie = NULL;
69 struct olsr_cookie_info *buffer_hold_timer_cookie = NULL;
70
71 /**
72  * Do initialization of various data needed for network interface management.
73  * This function also tries to set up the given interfaces.
74  *
75  * @return the number of interfaces configured
76  */
77 int
78 ifinit(void)
79 {
80   struct olsr_if *tmp_if;
81
82   /* Initial values */
83
84   /*
85    * Get some cookies for getting stats to ease troubleshooting.
86    */
87   interface_poll_timer_cookie =
88     olsr_alloc_cookie("Interface Polling", OLSR_COOKIE_TYPE_TIMER);
89   buffer_hold_timer_cookie =
90     olsr_alloc_cookie("Buffer Hold", OLSR_COOKIE_TYPE_TIMER);
91
92   hello_gen_timer_cookie =
93     olsr_alloc_cookie("Hello Generation", OLSR_COOKIE_TYPE_TIMER);
94   tc_gen_timer_cookie =
95     olsr_alloc_cookie("TC Generation", OLSR_COOKIE_TYPE_TIMER);
96   mid_gen_timer_cookie =
97     olsr_alloc_cookie("MID Generation", OLSR_COOKIE_TYPE_TIMER);
98   hna_gen_timer_cookie =
99     olsr_alloc_cookie("HNA Generation", OLSR_COOKIE_TYPE_TIMER);
100
101   OLSR_PRINTF(1, "\n ---- Interface configuration ---- \n\n");
102
103   /* Run trough all interfaces immediately */
104   for (tmp_if = olsr_cnf->interfaces; tmp_if != NULL; tmp_if = tmp_if->next) {
105     if (tmp_if->host_emul) {
106       add_hemu_if(tmp_if);
107     } else {
108       if (!olsr_cnf->host_emul) {       /* XXX: TEMPORARY! */
109         chk_if_up(tmp_if, 1);
110       }
111     }
112   }
113
114   /* Kick a periodic timer for the network interface update function */
115   olsr_start_timer(olsr_cnf->nic_chgs_pollrate * MSEC_PER_SEC, 5,
116                    OLSR_TIMER_PERIODIC, &check_interface_updates, NULL,
117                    interface_poll_timer_cookie->ci_id);
118
119   return (ifnet == NULL) ? 0 : 1;
120 }
121
122 void
123 run_ifchg_cbs(struct interface *ifp, int flag)
124 {
125   struct ifchgf *tmp;
126   for (tmp = ifchgf_list; tmp != NULL; tmp = tmp->next) {
127     tmp->function(ifp, flag);
128   }
129 }
130
131 /**
132  * Find the local interface with a given address.
133  *
134  * @param addr the address to check.
135  * @return the interface struct representing the interface
136  * that matched the address.
137  */
138 struct interface *
139 if_ifwithaddr(const union olsr_ip_addr *addr)
140 {
141   struct interface *ifp;
142   if (!addr) {
143     return NULL;
144   }
145   if (olsr_cnf->ip_version == AF_INET) {
146     /* IPv4 */
147     for (ifp = ifnet; ifp != NULL; ifp = ifp->int_next) {
148 /*
149       struct ipaddr_str ifbuf, addrbuf;
150       printf("Checking: %s == %s\n", ip4_to_string(&ifbuf, ifp->int_addr.sin_addr), olsr_ip_to_string(&addrbuf, addr));
151 */
152       if (ip4equal(&ifp->int_addr.sin_addr, &addr->v4)) {
153         return ifp;
154       }
155     }
156   } else {
157     /* IPv6 */
158     for (ifp = ifnet; ifp != NULL; ifp = ifp->int_next) {
159 /*
160       struct ipaddr_str ifbuf, addrbuf;
161       printf("Checking %s == %s\n", ip6_to_string(&ifbuf, &ifp->int6_addr.sin6_addr), olsr_ip_to_string(&addrbuf, addr));
162 */
163       if (ip6equal(&ifp->int6_addr.sin6_addr, &addr->v6)) {
164         return ifp;
165       }
166     }
167   }
168   return NULL;
169 }
170
171 /**
172  * Find the interface with a given number.
173  *
174  * @param nr the number of the interface to find.
175  * @return return the interface struct representing the interface
176  * that matched the number.
177  */
178 struct interface *
179 if_ifwithsock(int fd)
180 {
181   struct interface *ifp;
182   for (ifp = ifnet; ifp != NULL; ifp = ifp->int_next) {
183     if (ifp->olsr_socket == fd) {
184       return ifp;
185     }
186   }
187   return NULL;
188 }
189
190
191 /**
192  * Find the interface with a given label.
193  *
194  * @param if_name the label of the interface to find.
195  * @return return the interface struct representing the interface
196  * that matched the label.
197  */
198 struct interface *
199 if_ifwithname(const char *if_name)
200 {
201   struct interface *ifp;
202   for (ifp = ifnet; ifp != NULL; ifp = ifp->int_next) {
203     /* good ol' strcmp should be sufficient here */
204     if (strcmp(ifp->int_name, if_name) == 0) {
205       return ifp;
206     }
207   }
208   return NULL;
209 }
210
211 /**
212  * Find the interface with a given interface index.
213  *
214  * @param iif_index of the interface to find.
215  * @return return the interface struct representing the interface
216  * that matched the iif_index.
217  */
218 struct interface *
219 if_ifwithindex(const int if_index)
220 {
221   struct interface *ifp;
222   for (ifp = ifnet; ifp != NULL; ifp = ifp->int_next) {
223     if (ifp->if_index == if_index) {
224       return ifp;
225     }
226   }
227   return NULL;
228 }
229
230 /**
231  * Get an interface name for a given interface index
232  *
233  * @param iif_index of the interface to find.
234  * @return "" or interface name.
235  */
236 const char *
237 if_ifwithindex_name(const int if_index)
238 {
239   const struct interface *const ifp = if_ifwithindex(if_index);
240   return ifp == NULL ? "void" : ifp->int_name;
241 }
242
243
244 /**
245  * Create a new interf_name struct using a given
246  * name and insert it into the interface list.
247  *
248  * @param name the name of the interface.
249  * @return nada
250  */
251 struct olsr_if *
252 queue_if(const char *name, int hemu)
253 {
254   struct olsr_if *tmp;
255
256   //printf("Adding interface %s\n", name);
257
258   /* check if the inerfaces already exists */
259   for (tmp = olsr_cnf->interfaces; tmp != NULL; tmp = tmp->next) {
260     if (strcmp(tmp->name, name) == 0) {
261       fprintf(stderr, "Duplicate interfaces defined... not adding %s\n", name);
262       return NULL;
263     }
264   }
265
266   tmp = olsr_malloc(sizeof(*tmp), "queue interface");
267
268   tmp->name = olsr_malloc(strlen(name) + 1, "queue interface name");
269   strcpy(tmp->name, name);
270   tmp->cnf = NULL;
271   tmp->interf = NULL;
272   tmp->configured = 0;
273
274   tmp->host_emul = hemu ? true : false;
275
276   tmp->next = olsr_cnf->interfaces;
277   olsr_cnf->interfaces = tmp;
278
279   return tmp;
280 }
281
282 /**
283  * Add an ifchange function. These functions are called on all (non-initial)
284  * changes in the interface set.
285  */
286 void
287 add_ifchgf(ifchg_cb_func f)
288 {
289   struct ifchgf *tmp = olsr_malloc(sizeof(struct ifchgf), "Add ifchgfunction");
290
291   tmp->function = f;
292   tmp->next = ifchgf_list;
293   ifchgf_list = tmp;
294 }
295
296 /*
297  * Remove an ifchange function
298  */
299 int
300 del_ifchgf(ifchg_cb_func f)
301 {
302   struct ifchgf *tmp, *prev;
303
304   for (tmp = ifchgf_list, prev = NULL;
305        tmp != NULL;
306        prev = tmp, tmp = tmp->next) {
307     if (tmp->function == f) {
308       /* Remove entry */
309       if (prev == NULL) {
310         ifchgf_list = tmp->next;
311       } else {
312         prev->next = tmp->next;
313       }
314       free(tmp);
315       return 1;
316     }
317   }
318   return 0;
319 }
320
321 /*
322  * Local Variables:
323  * c-basic-offset: 2
324  * indent-tabs-mode: nil
325  * End:
326  */