12d965fe3f7c9af16c3586ad2d095edc6ba17231
[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.11 2004/11/02 21:14:12 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 olsr_if *tmp_if;
42
43
44   /* Initial values */
45   ifnet = NULL;
46
47   /*
48    *Initializing addrsock struct to be
49    *used on all the sockets
50    */
51   if(olsr_cnf->ip_version == AF_INET)
52     {
53       /* IP version 4 */
54       memset(&addrsock, 0, sizeof (addrsock));
55       addrsock.sin_family = AF_INET;
56       addrsock.sin_port = olsr_udp_port;
57       (addrsock.sin_addr).s_addr = INADDR_ANY;
58     }
59   else
60     {
61       /* IP version 6 */
62       memset(&addrsock6, 0, sizeof (addrsock6));
63       addrsock6.sin6_family = AF_INET6;
64       addrsock6.sin6_port = olsr_udp_port;
65       //(addrsock6.sin6_addr).s_addr = IN6ADDR_ANY_INIT;
66     }
67
68   olsr_printf(1, "\n ---- Interface configuration ---- \n\n");
69   /* Run trough all interfaces immedeatly */
70   for(tmp_if = olsr_cnf->interfaces; tmp_if != NULL; tmp_if = tmp_if->next)
71     {
72       chk_if_up(tmp_if, 1);     
73     }
74   
75   /* register network interface update function with scheduler */
76   olsr_register_scheduler_event(&check_interface_updates, NULL, 5.0, 0, NULL);
77
78   return (ifnet == NULL) ? 0 : 1;
79 }
80
81
82
83 /**
84  *Find the local interface with a given address.
85  *
86  *@param addr the address to check.
87  *
88  *@return the interface struct representing the interface
89  *that matched the address.
90  */
91
92 struct interface *
93 if_ifwithaddr(union olsr_ip_addr *addr)
94 {
95   struct interface *ifp;
96
97   for (ifp = ifnet; ifp; ifp = ifp->int_next)
98     {
99       if(olsr_cnf->ip_version == AF_INET)
100         {
101           /* IPv4 */
102           //printf("Checking: %s == ", inet_ntoa(((struct sockaddr_in *)&ifp->int_addr)->sin_addr));
103           //printf("%s\n", olsr_ip_to_string(addr));
104
105           if (COMP_IP(&((struct sockaddr_in *)&ifp->int_addr)->sin_addr, addr))
106               return ifp;
107         }
108       else
109         {
110           /* IPv6 */
111           //printf("Checking %s ", olsr_ip_to_string((union olsr_ip_addr *)&ifp->int6_addr.sin6_addr));
112           //printf("== %s\n", olsr_ip_to_string((union olsr_ip_addr *)&((struct sockaddr_in6 *)addr)->sin6_addr));
113           if (COMP_IP(&ifp->int6_addr.sin6_addr, addr))
114             return ifp;
115         }
116     }
117   return NULL;
118 }
119
120
121
122 /**
123  *Find the interface with a given number.
124  *
125  *@param nr the number of the interface to find.
126  *
127  *@return return the interface struct representing the interface
128  *that matched the number.
129  */
130 struct interface *
131 if_ifwithsock(int fd)
132 {
133   struct interface *ifp;
134   ifp = ifnet;
135
136   while (ifp) 
137     {
138       if (ifp->olsr_socket == fd)
139         return ifp;
140       ifp = ifp->int_next;
141     }
142   
143   return (ifp);
144 }
145
146
147 /**
148  *Create a new interf_name struct using a given
149  *name and insert it into the interface list.
150  *
151  *@param name the name of the interface.
152  *
153  *@return nada
154  */
155 void
156 queue_if(char *name)
157 {
158
159   struct olsr_if *interf_n = olsr_cnf->interfaces;
160
161   //printf("Adding interface %s\n", name);
162
163   /* check if the inerfaces already exists */
164   while(interf_n != NULL)
165     {
166       if(memcmp(interf_n->name, name, strlen(name)) == 0)
167         {
168           fprintf(stderr, "Duplicate interfaces defined... not adding %s\n", name);
169           return;
170         }
171       interf_n = interf_n->next;
172     }
173
174   interf_n = olsr_malloc(sizeof(struct olsr_if), "queue interface");
175
176   /* strlen () does not return length including terminating /0 */
177   interf_n->name = olsr_malloc(strlen(name) + 1, "queue interface name");
178   interf_n->cnf = NULL;
179   interf_n->interf = NULL;
180   interf_n->configured = 0;
181   interf_n->index = olsr_cnf->ifcnt++;
182
183   strcpy(interf_n->name, name);
184   interf_n->next = olsr_cnf->interfaces;
185   olsr_cnf->interfaces = interf_n;
186
187 }
188
189
190
191 /**
192  *Add an ifchange function. These functions are called on all (non-initial)
193  *changes in the interface set.
194  *
195  *@param
196  *
197  *@return
198  */
199 int
200 add_ifchgf(int (*f)(struct interface *, int))
201 {
202
203   struct ifchgf *new_ifchgf;
204
205   new_ifchgf = olsr_malloc(sizeof(struct ifchgf), "Add ifchgfunction");
206
207   new_ifchgf->next = ifchgf_list;
208   new_ifchgf->function = f;
209
210   ifchgf_list = new_ifchgf;
211
212   return 1;
213 }
214
215
216
217 /*
218  * Remove an ifchange function
219  */
220 int
221 del_ifchgf(int (*f)(struct interface *, int))
222 {
223   struct ifchgf *tmp_ifchgf, *prev;
224
225   tmp_ifchgf = ifchgf_list;
226   prev = NULL;
227
228   while(tmp_ifchgf)
229     {
230       if(tmp_ifchgf->function == f)
231         {
232           /* Remove entry */
233           if(prev == NULL)
234             {
235               ifchgf_list = tmp_ifchgf->next;
236               free(tmp_ifchgf);
237             }
238           else
239             {
240               prev->next = tmp_ifchgf->next;
241               free(tmp_ifchgf);
242             }
243           return 1;
244         }
245       prev = tmp_ifchgf;
246       tmp_ifchgf = tmp_ifchgf->next;
247     }
248
249   return 0;
250 }