* more fixups for the generated .c file
[olsrd.git] / src / hna_set.c
1 /*
2  * The olsr.org Optimized Link-State Routing daemon(olsrd)
3  * Copyright (c) 2004, Andreas T√łnnesen(andreto@olsr.org)
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without 
7  * modification, are permitted provided that the following conditions 
8  * are met:
9  *
10  * * Redistributions of source code must retain the above copyright 
11  *   notice, this list of conditions and the following disclaimer.
12  * * Redistributions in binary form must reproduce the above copyright 
13  *   notice, this list of conditions and the following disclaimer in 
14  *   the documentation and/or other materials provided with the 
15  *   distribution.
16  * * Neither the name of olsr.org, olsrd nor the names of its 
17  *   contributors may be used to endorse or promote products derived 
18  *   from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
23  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
24  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
26  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
27  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
28  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 
30  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
31  * POSSIBILITY OF SUCH DAMAGE.
32  *
33  * Visit http://www.olsr.org for more information.
34  *
35  * If you find this software useful feel free to make a donation
36  * to the project. For more information see the website or contact
37  * the copyright holders.
38  *
39  * $Id: hna_set.c,v 1.19 2007/04/25 22:08:08 bernd67 Exp $
40  */
41
42 #include "defs.h"
43 #include "olsr.h"
44 #include "scheduler.h"
45
46
47 struct hna_entry hna_set[HASHSIZE];
48 size_t netmask_size;
49
50
51 /**
52  *Initialize the HNA set
53  */
54 int
55 olsr_init_hna_set(void)
56 {
57
58   int index;
59
60   if(olsr_cnf->ip_version == AF_INET)
61     {
62       netmask_size = sizeof(olsr_u32_t);
63     }
64   else
65     {
66       netmask_size = sizeof(olsr_u16_t);
67     }
68
69   /* Since the holdingtime is assumed to be rather large for 
70    * HNA entries, the timeoutfunction is only ran once every second
71    */
72   olsr_register_scheduler_event(&olsr_time_out_hna_set, NULL, 1, 0, NULL);
73
74   for(index=0;index<HASHSIZE;index++)
75     {
76       hna_set[index].next = &hna_set[index];
77       hna_set[index].prev = &hna_set[index];
78     }
79
80   return 1;
81 }
82
83
84
85
86 /**
87  *Lookup a network entry in a networkentry list
88  *
89  *@param nets the network list to look in
90  *@param net the network to look for
91  *@param mask the netmask to look for
92  *
93  *@return the localted entry or NULL of not found
94  */
95 struct hna_net *
96 olsr_lookup_hna_net(struct hna_net *nets, union olsr_ip_addr *net, union hna_netmask *mask)
97 {
98   struct hna_net *tmp_net;
99
100
101   /* Loop trough entrys */
102   for(tmp_net = nets->next;
103       tmp_net != nets;
104       tmp_net = tmp_net->next)
105     { 
106       if(COMP_IP(&tmp_net->A_network_addr, net) &&
107          (memcmp(&tmp_net->A_netmask, mask, netmask_size) == 0))
108         return tmp_net;
109     }
110   
111   /* Not found */
112   return NULL;
113 }
114
115
116
117
118 /**
119  *Lookup a gateway entry
120  *
121  *@param gw the address of the gateway
122  *
123  *@return the located entry or NULL if not found
124  */
125 struct hna_entry *
126 olsr_lookup_hna_gw(union olsr_ip_addr *gw)
127 {
128   struct hna_entry *tmp_hna;
129   olsr_u32_t hash;
130
131   //OLSR_PRINTF(5, "TC: lookup entry\n");
132
133   hash = olsr_hashing(gw);
134   
135   /* Check for registered entry */
136   for(tmp_hna = hna_set[hash].next;
137       tmp_hna != &hna_set[hash];
138       tmp_hna = tmp_hna->next)
139     {
140       if(COMP_IP(&tmp_hna->A_gateway_addr, gw))
141         return tmp_hna;
142     }
143   
144   /* Not found */
145   return NULL;
146 }
147
148
149
150 /**
151  *Add a gatewayentry to the HNA set
152  *
153  *@param addr the address of the gateway
154  *
155  *@return the created entry
156  */
157 struct hna_entry *
158 olsr_add_hna_entry(union olsr_ip_addr *addr)
159 {
160   struct hna_entry *new_entry;
161   olsr_u32_t hash;
162
163   new_entry = olsr_malloc(sizeof(struct hna_entry), "New HNA entry");
164
165   /* Fill struct */
166   COPY_IP(&new_entry->A_gateway_addr, addr);
167
168   /* Link nets */
169   new_entry->networks.next = &new_entry->networks;
170   new_entry->networks.prev = &new_entry->networks;
171
172   /* queue */
173   hash = olsr_hashing(addr);
174   
175   hna_set[hash].next->prev = new_entry;
176   new_entry->next = hna_set[hash].next;
177   hna_set[hash].next = new_entry;
178   new_entry->prev = &hna_set[hash];
179
180   return new_entry;
181
182 }
183
184
185
186 /**
187  *Adds a ntework entry to a HNA gateway
188  *
189  *@param hna_gw the gateway entry to add the
190  *network to
191  *@param net the networkaddress to add
192  *@param mask the netmask
193  *
194  *@return the newly created entry
195  */
196 struct hna_net *
197 olsr_add_hna_net(struct hna_entry *hna_gw, union olsr_ip_addr *net, union hna_netmask *mask)
198 {
199   struct hna_net *new_net;
200
201
202   /* Add the net */
203   new_net = olsr_malloc(sizeof(struct hna_net), "Add HNA net");
204   
205   /* Fill struct */
206   COPY_IP(&new_net->A_network_addr, net);
207   memcpy(&new_net->A_netmask, mask, netmask_size);
208
209   /* Queue */
210   hna_gw->networks.next->prev = new_net;
211   new_net->next = hna_gw->networks.next;
212   hna_gw->networks.next = new_net;
213   new_net->prev = &hna_gw->networks;
214
215   return new_net;
216 }
217
218
219
220
221 /**
222  * Update a HNA entry. If it does not exist it
223  * is created.
224  * This is the only function that should be called 
225  * from outside concerning creation of HNA entries.
226  *
227  *@param gw address of the gateway
228  *@param net address of the network
229  *@param mask the netmask
230  *@param vtime the validitytime of the entry
231  *
232  *@return nada
233  */
234 void
235 olsr_update_hna_entry(union olsr_ip_addr *gw, union olsr_ip_addr *net, union hna_netmask *mask, float vtime)
236 {
237   struct hna_entry *gw_entry;
238   struct hna_net *net_entry;
239
240   if((gw_entry = olsr_lookup_hna_gw(gw)) == NULL)
241     /* Need to add the entry */
242     gw_entry = olsr_add_hna_entry(gw);
243   
244   if((net_entry = olsr_lookup_hna_net(&gw_entry->networks, net, mask)) == NULL)
245     {
246       /* Need to add the net */
247       net_entry = olsr_add_hna_net(gw_entry, net, mask);
248       changes_hna = OLSR_TRUE;
249     }
250
251   /* Update holdingtime */
252   net_entry->A_time = GET_TIMESTAMP(vtime*1000);
253
254 }
255
256
257
258
259
260
261 /**
262  *Function that times out all entrys in the hna set and
263  *deletes the timed out ones.
264  *
265  *@return nada
266  */
267 void
268 olsr_time_out_hna_set(void *foo __attribute__((unused)))
269 {
270   int index;
271
272   for(index=0;index<HASHSIZE;index++)
273     {
274       struct hna_entry *tmp_hna = hna_set[index].next;
275       /* Check all entrys */
276       while(tmp_hna != &hna_set[index])
277         {
278           /* Check all networks */
279           struct hna_net *tmp_net = tmp_hna->networks.next;
280
281           while(tmp_net != &tmp_hna->networks)
282             {
283               if(TIMED_OUT(tmp_net->A_time))
284                 {
285                   struct hna_net *net_to_delete = tmp_net;
286                   tmp_net = tmp_net->next;
287                   DEQUEUE_ELEM(net_to_delete);
288                   free(net_to_delete);
289                   changes_hna = OLSR_TRUE;
290                 }
291               else
292                 tmp_net = tmp_net->next;
293             }
294
295           /* Delete gw entry if empty */
296           if(tmp_hna->networks.next == &tmp_hna->networks)
297             {
298               struct hna_entry *hna_to_delete = tmp_hna;
299               tmp_hna = tmp_hna->next;
300
301               /* Dequeue */
302               DEQUEUE_ELEM(hna_to_delete);
303               /* Delete */
304               free(hna_to_delete);
305             }
306           else
307             tmp_hna = tmp_hna->next;
308         }
309     }
310
311 }
312
313
314
315 /**
316  *Function that times out all entrys in the hna set and
317  *deletes the timed out ones.
318  *
319  *@return nada
320  */
321 void
322 olsr_print_hna_set(void)
323 {
324   int index;
325
326   OLSR_PRINTF(1, "\n--- %02d:%02d:%02d.%02d ------------------------------------------------- HNA SET\n\n",
327               nowtm->tm_hour,
328               nowtm->tm_min,
329               nowtm->tm_sec,
330               (int)now.tv_usec/10000);
331   
332   if(olsr_cnf->ip_version == AF_INET)
333     OLSR_PRINTF(1, "IP net          netmask         GW IP\n");
334   else
335     OLSR_PRINTF(1, "IP net/prefixlen               GW IP\n");
336
337   for(index=0;index<HASHSIZE;index++)
338     {
339       struct hna_entry *tmp_hna = hna_set[index].next;
340       /* Check all entrys */
341       while(tmp_hna != &hna_set[index])
342         {
343           /* Check all networks */
344           struct hna_net *tmp_net = tmp_hna->networks.next;
345
346           while(tmp_net != &tmp_hna->networks)
347             {
348               if(olsr_cnf->ip_version == AF_INET)
349                 {
350                   OLSR_PRINTF(1, "%-15s ", olsr_ip_to_string(&tmp_net->A_network_addr));
351                   OLSR_PRINTF(1, "%-15s ", olsr_ip_to_string((union olsr_ip_addr *)&tmp_net->A_netmask.v4));
352                   OLSR_PRINTF(1, "%-15s\n", olsr_ip_to_string(&tmp_hna->A_gateway_addr));
353                 }
354               else
355                 {
356                   OLSR_PRINTF(1, "%-27s/%d", olsr_ip_to_string(&tmp_net->A_network_addr), tmp_net->A_netmask.v6);
357                   OLSR_PRINTF(1, "%s\n", olsr_ip_to_string(&tmp_hna->A_gateway_addr));
358                 }
359
360               tmp_net = tmp_net->next;
361             }
362           tmp_hna = tmp_hna->next;
363         }
364     }
365
366 }
367
368