1 #include "routers.h"
2 
is_router_lla_in(router_list_t * list,struct in6_addr lla)3 int is_router_lla_in(router_list_t *list, struct in6_addr lla)
4 {
5 	router_list_t *tmp = list;
6 
7 	while(tmp != NULL)
8 	{
9 		if(IN6_ARE_ADDR_EQUAL(&lla,&(tmp->lla)))
10 			return 1;
11 
12 		tmp = tmp->next;
13 	}
14 
15 	return 0;
16 }
17 
is_router_mac_in(router_list_t * list,struct ether_addr eth)18 int is_router_mac_in(router_list_t *list, struct ether_addr eth)
19 {
20 	router_list_t *tmp = list;
21 
22 	while(tmp != NULL)
23 	{
24 		if(!MEMCMP(&eth,&(tmp->mac), sizeof(struct ether_addr)))
25 			return 1;
26 
27 		tmp = tmp->next;
28 	}
29 
30 	return 0;
31 }
32 
33 
router_get(router_list_t * list,struct in6_addr lla,struct ether_addr eth)34 router_list_t * router_get(router_list_t *list, struct in6_addr lla, struct ether_addr eth)
35 {
36 	router_list_t *tmp = list;
37 
38 	while(tmp != NULL)
39 	{
40 		if(!MEMCMP(&eth,&(tmp->mac), sizeof(struct ether_addr)))
41 			if(IN6_ARE_ADDR_EQUAL(&lla,&(tmp->lla)))
42 				return tmp;
43 
44 		tmp = tmp->next;
45 	}
46 
47 	return NULL;
48 }
49 
router_has_router(router_list_t * list,struct in6_addr lla,struct ether_addr eth)50 int router_has_router(router_list_t *list, struct in6_addr lla, struct ether_addr eth) {
51 	if (router_get(list, lla, eth)==NULL) {
52 		return 0;
53 	}
54 	return 1;
55 }
56 
router_add(router_list_t ** list,struct ether_addr * eth,struct in6_addr * lla,uint8_t curhoplimit,uint8_t flags_reserved,uint16_t router_lifetime,uint32_t reachable_timer,uint32_t retrans_timer,uint32_t mtu,int p_volatile)57 int router_add(router_list_t **list, struct ether_addr* eth, struct in6_addr* lla,
58 	uint8_t curhoplimit, uint8_t flags_reserved, uint16_t router_lifetime, uint32_t reachable_timer, uint32_t retrans_timer,
59 	uint32_t mtu, int p_volatile)
60 {
61 	router_list_t *tmp = *list,*new=NULL;
62 
63 	if(router_has_router(*list,*lla,*eth))
64 	{
65 		fprintf(stderr,"Router already in list\n");
66 		return 0;
67 	}
68 
69 	if( (new=(router_list_t *)malloc(sizeof(router_list_t))) == NULL)
70 	{
71 		perror("malloc");
72 		return 0;
73 	}
74 
75 	memcpy(&new->mac, eth, sizeof(struct ether_addr));
76 	memcpy(&new->lla, lla, sizeof(struct in6_addr));
77 	new->param_curhoplimit     = curhoplimit;
78 	new->param_flags_reserved  = flags_reserved;
79 	new->param_router_lifetime = router_lifetime;
80 	new->param_reachable_timer = reachable_timer;
81 	new->param_retrans_timer   = retrans_timer;
82 	new->param_mtu   = mtu;
83 	new->params_volatile = p_volatile;
84 	new->addresses = NULL;
85 	new->prefixes = NULL;
86 	new->next = NULL;
87 
88 	if(*list != NULL)
89 	{
90 		while(tmp->next != NULL)
91 			tmp=tmp->next;
92 		tmp->next=new;
93 	}
94 	else
95 		 *list = new;
96 
97 	return 1;
98 }
99 
router_add_prefix(router_list_t * list,struct in6_addr lla,struct ether_addr eth,struct in6_addr prefix,int mask,uint8_t flags_reserved,uint32_t valid_lifetime,uint32_t preferred_lifetime)100 int router_add_prefix(router_list_t *list, struct in6_addr lla, struct ether_addr eth, struct in6_addr prefix, int mask,
101 	uint8_t flags_reserved, uint32_t valid_lifetime, uint32_t preferred_lifetime)
102 {
103 	router_list_t *tmp = list;
104 	prefix_t *new, *ptmp = NULL;
105 
106 	if( (new=(prefix_t *)malloc(sizeof(prefix_t))) == NULL)
107 	{
108 		perror("malloc");
109 		return 0;
110 	}
111 
112 	new->prefix               = prefix;
113 	new->mask                 = mask;
114 	new->param_flags_reserved = flags_reserved;
115 	new->param_valid_time     = valid_lifetime;
116 	new->param_preferred_time = preferred_lifetime;
117 	new->next=NULL;
118 
119 	tmp = router_get(list,  lla, eth);
120 	if (tmp==NULL) return 0;
121 
122 	ptmp = tmp->prefixes;
123 	if(ptmp == NULL) {
124 		tmp->prefixes = new;
125 	} else {
126 		while(ptmp->next != NULL) {
127 			ptmp=ptmp->next;
128 		}
129 		ptmp->next=new;
130 	}
131 	return 1;
132 }
133 
134 
router_get_prefix(router_list_t * list,struct in6_addr lla,struct ether_addr eth,struct in6_addr prefix,int mask)135 prefix_t* router_get_prefix(router_list_t *list, struct in6_addr lla, struct ether_addr eth, struct in6_addr prefix, int mask)
136 {
137 	router_list_t* router = router_get(list, lla, eth);
138 	prefix_t *ptmp;
139 
140 	if (router==NULL) {
141 		return NULL;
142 	}
143 	ptmp = router->prefixes;
144 	while(ptmp != NULL) {
145 		if( (ptmp->mask == mask) && (IN6_ARE_ADDR_EQUAL(&prefix,&(ptmp->prefix))) ) {
146 			return ptmp;
147 		}
148 		ptmp = ptmp->next;
149 	}
150 	return NULL;
151 }
152 
router_has_prefix(router_list_t * list,struct in6_addr lla,struct ether_addr eth,struct in6_addr prefix,int mask)153 int router_has_prefix(router_list_t *list, struct in6_addr lla, struct ether_addr eth, struct in6_addr prefix, int mask) {
154         if (router_get_prefix(list, lla, eth, prefix, mask)==NULL) {
155 		return 0;
156 	}
157 	return 1;
158 }
159 
160 
router_add_address(router_list_t * list,struct ether_addr eth,struct in6_addr addr)161 int router_add_address(router_list_t *list, struct ether_addr eth, struct in6_addr addr)
162 {
163 	router_list_t *tmp = list;
164 	address_t *new = NULL;
165 
166 
167 	if(router_has_address(list,eth,addr))
168 	{
169 		fprintf(stderr,"Address already in list\n");
170 		return 0;
171 	}
172 
173 
174 	if( (new=(address_t *)malloc(sizeof(address_t))) == NULL)
175 	{
176 		perror("malloc");
177 		return 0;
178 	}
179 
180 	new->address = addr;
181 	new->next=NULL;
182 
183 	while(tmp != NULL)
184 	{
185 		if(!MEMCMP(&eth,&(tmp->mac), sizeof(struct ether_addr)))
186 		{
187 				address_t *atmp = tmp->addresses;
188 				if(atmp == NULL)
189 					tmp->addresses = new;
190 				else
191 				{
192 					while(atmp->next != NULL)
193 						atmp=atmp->next;
194 					atmp->next=new;
195 				}
196 				return 1;
197 		}
198 		else
199 			tmp = tmp->next;
200 	}
201 
202 	return 0;
203 }
204 
205 
router_has_address(router_list_t * list,struct ether_addr eth,struct in6_addr addr)206 int router_has_address(router_list_t *list, struct ether_addr eth, struct in6_addr addr)
207 {
208 	router_list_t *tmp = list;
209 	while(tmp != NULL)
210 	{
211 		if(!MEMCMP(&eth,&(tmp->mac), sizeof(struct ether_addr)))
212 		{
213 				address_t *atmp = tmp->addresses;
214 				while(atmp != NULL)
215 				{
216 					if( IN6_ARE_ADDR_EQUAL(&addr,&(atmp->address)) )
217 						return 1;
218 
219 					atmp = atmp->next;
220 				}
221 				return 0;
222 		}
223 		tmp = tmp->next;
224 	}
225 	return 0;
226 }
227 
nb_router(router_list_t * routers)228 int nb_router(router_list_t *routers)
229 {
230 	int n = 0;
231 	router_list_t *tmp = routers;
232 
233 	while(tmp != NULL)
234 	{
235 		n++;
236 		tmp=tmp->next;
237 	}
238 
239 	return n;
240 }
241 
242 
print_routers(router_list_t * list)243 void print_routers(router_list_t *list)
244 {
245 	router_list_t *tmp = list;
246 	while(tmp != NULL)
247 	{
248 		char eth[ETH_ADDRSTRLEN+1], lla[INET6_ADDRSTRLEN+1];
249 		prefix_t *ptmp = tmp->prefixes;
250 		address_t *atmp = tmp->addresses;
251 
252 		ipv6_ntoa(lla,tmp->lla);
253 		strncpy(eth,ether_ntoa(&(tmp->mac)), ETH_ADDRSTRLEN);
254 		fprintf(stderr,"Router (%s,%s) :\n", eth, lla);
255 		fprintf(stderr,"    RA params:\n");
256 		fprintf(stderr,"        curhoplimit:     %u\n", tmp->param_curhoplimit);
257 		fprintf(stderr,"        flags:           [");
258 		if (tmp->param_flags_reserved&ND_RA_FLAG_MANAGED) {
259 			fprintf(stderr,"MANAGED ");
260 		}
261 		if (tmp->param_flags_reserved&ND_RA_FLAG_OTHER) {
262 			fprintf(stderr,"OTHER ");
263 		}
264 /* no support for home agent in FreeBSD
265 		if (tmp->param_flags_reserved&ND_RA_FLAG_HOME_AGENT) {
266 			fprintf(stderr,"HOME_AGENT ");
267 		}
268 */
269 		fprintf(stderr,"]\n");
270 		fprintf(stderr,"        router lifetime: %u\n", tmp->param_router_lifetime);
271 		fprintf(stderr,"        reachable timer: %u\n", tmp->param_reachable_timer);
272 		fprintf(stderr,"        retrans timer:   %u\n", tmp->param_retrans_timer);
273 		if (tmp->param_mtu>0) {
274 			fprintf(stderr,"        mtu:             %u\n", tmp->param_mtu);
275 		}
276 		if (tmp->params_volatile==0) {
277 			fprintf(stderr,"        Parameters of future Router Advertisements will be\n");
278 			fprintf(stderr,"        checked against those stored in the router list.\n");
279 		}
280 		fprintf(stderr,"    Address(es):\n");
281 		while(atmp != NULL)
282 		{
283 			char addr[48];
284 			ipv6_ntoa(addr,atmp->address);
285 			fprintf(stderr,"        %s\n", addr);
286 			atmp=atmp->next;
287 		}
288 		fprintf(stderr,"    Prefix(es):\n");
289 		while(ptmp != NULL)
290 		{
291 			char prefix[64];
292 			ipv6_ntoa(prefix,ptmp->prefix);
293 			sprintf(prefix,"%s/%d", prefix,ptmp->mask);
294 			fprintf(stderr,"        %s\n", prefix);
295 			fprintf(stderr,"            flags:          [");
296 			if (ptmp->param_flags_reserved&ND_OPT_PI_FLAG_ONLINK) {
297 				fprintf(stderr,"ONLINK ");
298 			}
299 			if (ptmp->param_flags_reserved&ND_OPT_PI_FLAG_AUTO) {
300 				fprintf(stderr,"AUTO ");
301 			}
302 /* No suuportin FreeBSD yet
303 			if (ptmp->param_flags_reserved&ND_OPT_PI_FLAG_RADDR) {
304 				fprintf(stderr,"RADDR ");
305 			}
306 */
307 			fprintf(stderr,"]\n");
308 			fprintf(stderr,"            valid time:     %u\n", ptmp->param_valid_time);
309 			fprintf(stderr,"            preferred time: %u\n", ptmp->param_preferred_time);
310 			ptmp=ptmp->next;
311 		}
312 		fprintf(stderr,"\n");
313 		tmp=tmp->next;
314 	}
315 }
316 
clean_router_prefixes(router_list_t ** list,struct ether_addr eth)317 int clean_router_prefixes(router_list_t **list, struct ether_addr eth)
318 {
319 	router_list_t *tmp = *list;
320 
321 	while(tmp != NULL)
322 	{
323 		if(!MEMCMP(&eth,&(tmp->mac), sizeof(struct ether_addr)))
324 		{
325 			prefix_t *ptmp = tmp->prefixes, *ptodel = NULL;
326 
327 			while( ptmp != NULL)
328 			{
329 				ptodel = ptmp;
330 				ptmp = ptmp->next;
331 				free(ptodel);
332 			}
333 
334 			return 1;
335 		}
336 
337 		tmp = tmp->next;
338 	}
339 
340 	return 0;
341 }
342 
343 
clean_router_addresses(router_list_t ** list,struct ether_addr eth)344 int clean_router_addresses(router_list_t **list, struct ether_addr eth)
345 {
346 	router_list_t *tmp = *list;
347 
348 	while(tmp != NULL)
349 	{
350 		if(!MEMCMP(&eth,&(tmp->mac), sizeof(struct ether_addr)))
351 		{
352 			address_t *atmp = tmp->addresses, *atodel = NULL;
353 
354 			while( atmp != NULL)
355 			{
356 				atodel = atmp;
357 				atmp = atmp->next;
358 				free(atodel);
359 			}
360 
361 			return 1;
362 		}
363 
364 		tmp = tmp->next;
365 	}
366 
367 	return 0;
368 }
369 
clean_routers(router_list_t ** list)370 int clean_routers(router_list_t **list)
371 {
372 	router_list_t *tmp = *list, *rtodel = NULL;
373 
374 	while(tmp != NULL)
375 	{
376 		rtodel = tmp;
377 		clean_router_addresses(list,tmp->mac);
378 		clean_router_prefixes(list,tmp->mac);
379 		tmp = tmp->next;
380 		free(rtodel);
381 	}
382 
383 	return 1;
384 }
385 
386 #if 0
387 
388 REMOVED COMPLICATED FUNCTIONS
389 
390 int is_router_in(router_list_t *list, struct in6_addr lla, struct ether_addr eth)
391 {
392 	router_list_t *tmp = list;
393 
394 	while(tmp != NULL)
395 	{
396 		if(!MEMCMP(&eth,&(tmp->mac), sizeof(struct ether_addr)))
397 			if(IN6_ARE_ADDR_EQUAL(&lla,&(tmp->lla)))
398 				return 1;
399 
400 		tmp = tmp->next;
401 	}
402 
403 	return 0;
404 }
405 
406 
407 
408 router_list_t * get_router_lla_in(router_list_t *list, struct in6_addr lla)
409 {
410 	router_list_t *tmp = list;
411 
412 	while(tmp != NULL)
413 	{
414 		if(IN6_ARE_ADDR_EQUAL(&lla,&(tmp->lla)))
415 			return tmp;
416 
417 		tmp = tmp->next;
418 	}
419 
420 	return NULL;
421 }
422 
423 router_list_t * get_router_mac_in(router_list_t *list, struct ether_addr eth)
424 {
425 	router_list_t *tmp = list;
426 
427 	while(tmp != NULL)
428 	{
429 		if(!MEMCMP(&eth,&(tmp->mac), sizeof(struct ether_addr)))
430 			return tmp;
431 
432 		tmp = tmp->next;
433 	}
434 
435 	return NULL;
436 }
437 
438 
439 int add_router(router_list_t **list, struct in6_addr lla, struct ether_addr eth)
440 {
441 	router_list_t *tmp = *list,*new=NULL;
442 
443 	if(is_router_in(*list,lla,eth))
444 	{
445 		fprintf(stderr,"Router already in list\n");
446 		return 0;
447 	}
448 
449 	if( (new=(router_list_t *)malloc(sizeof(router_list_t))) == NULL)
450 	{
451 		perror("malloc");
452 		return 0;
453 	}
454 
455 	new->mac = eth;
456 	new->lla = lla;
457 	new->addresses = NULL;
458 	new->prefixes = NULL;
459 	new->next = NULL;
460 
461 	if(*list != NULL)
462 	{
463 		while(tmp->next != NULL)
464 			tmp=tmp->next;
465 		tmp->next=new;
466 	}
467 	else
468 		 *list = new;
469 
470 	return 1;
471 }
472 
473 int router_add_prefix(router_list_t **list, struct in6_addr lla, struct ether_addr eth, struct in6_addr prefix, int mask,
474 	uint8_t flags_reserved, uint32_t valid_lifetime, uint32_t preferred_lifetime)
475 {
476 	router_list_t *tmp = *list;
477 	prefix_t *new = NULL;
478 
479 	/*
480 	if(is_prefix_in(lla,eth,prefix))
481 	{
482 		fprintf(stderr,"Prefix already in list\n");
483 		return 0;
484 	}
485 	*/
486 
487 	if( (new=(prefix_t *)malloc(sizeof(prefix_t))) == NULL)
488 	{
489 		perror("malloc");
490 		return 0;
491 	}
492 
493 	new->prefix               = prefix;
494 	new->mask                 = mask;
495 	new->param_flags_reserved = flags_reserved;
496 	new->param_valid_time     = valid_lifetime;
497 	new->param_preferred_time = preferred_lifetime;
498 	new->next=NULL;
499 
500 	while(tmp != NULL)
501 	{
502 		if(!MEMCMP(&eth,&(tmp->mac), sizeof(struct ether_addr)))
503 		{
504 			if(IN6_ARE_ADDR_EQUAL(&lla,&(tmp->lla)))
505 			{
506 				prefix_t *ptmp = tmp->prefixes;
507 				if(ptmp == NULL)
508 					tmp->prefixes = new;
509 				else
510 				{
511 					while(ptmp->next != NULL)
512 						ptmp=ptmp->next;
513 					ptmp->next=new;
514 				}
515 				return 1;
516 			}
517 		}
518 		else
519 			tmp = tmp->next;
520 	}
521 
522 	return 0;
523 }
524 
525 
526 int router_has_prefix(router_list_t *list, struct in6_addr lla, struct ether_addr eth, struct in6_addr prefix, int mask)
527 {
528 	router_list_t *tmp = list;
529 	while(tmp != NULL)
530 	{
531 		if(!MEMCMP(&eth,&(tmp->mac), sizeof(struct ether_addr)))
532 		{
533 			if(IN6_ARE_ADDR_EQUAL(&lla,&(tmp->lla)))
534 			{
535 				prefix_t *ptmp = tmp->prefixes;
536 				while(ptmp != NULL)
537 				{
538 					if( (ptmp->mask == mask) && (IN6_ARE_ADDR_EQUAL(&prefix,&(ptmp->prefix))) )
539 						return 1;
540 
541 					ptmp = ptmp->next;
542 				}
543 				return 0;
544 			}
545 		}
546 		tmp = tmp->next;
547 	}
548 	return 0;
549 }
550 #endif
551