mDNS: Implemented Host Filtering for ipv4 and ipv6, writing in the config file which...
[olsrd.git] / lib / mdns / src / RouterElection.c
1 /* System includes */
2 #include <stddef.h>             /* NULL */
3 #include <sys/types.h>          /* ssize_t */
4 #include <string.h>             /* strerror() */
5 #include <stdarg.h>             /* va_list, va_start, va_end */
6 #include <errno.h>              /* errno */
7 #include <assert.h>             /* assert() */
8 #include <linux/if_ether.h>     /* ETH_P_IP */
9 #include <linux/if_packet.h>    /* struct sockaddr_ll, PACKET_MULTICAST */
10 //#include <pthread.h> /* pthread_t, pthread_create() */
11 #include <signal.h>             /* sigset_t, sigfillset(), sigdelset(), SIGINT */
12 #include <netinet/ip.h>         /* struct ip */
13 #include <netinet/udp.h>        /* struct udphdr */
14 #include <unistd.h>             /* close() */
15
16 #include <netinet/in.h>
17 #include <netinet/ip6.h>
18
19 /* OLSRD includes */
20 #include "plugin_util.h"        /* set_plugin_int */
21 #include "defs.h"               /* olsr_cnf, //OLSR_PRINTF */
22 #include "ipcalc.h"
23 #include "olsr.h"               /* //OLSR_PRINTF */
24 #include "mid_set.h"            /* mid_lookup_main_addr() */
25 #include "link_set.h"           /* get_best_link_to_neighbor() */
26 #include "net_olsr.h"           /* ipequal */
27 #include "hna_set.h"
28
29 /* plugin includes */
30 #include "NetworkInterfaces.h"  /* TBmfInterface, CreateBmfNetworkInterfaces(), CloseBmfNetworkInterfaces() */
31 #include "Address.h"            /* IsMulticast() */
32 #include "Packet.h"             /* ENCAP_HDR_LEN, BMF_ENCAP_TYPE, BMF_ENCAP_LEN etc. */
33 #include "list_backport.h"
34 #include "RouterElection.h"
35 #include "mdns.h"
36
37 int ISMASTER = 1;
38 struct RtElHelloPkt *hello;
39 uint8_t NETWORK_ID;
40 union olsr_ip_addr ROUTER_ID;
41
42 //List for routers
43 struct list_entity ListOfRouter;
44 #define ROUTER_ELECTION_ENTRIES(nr, iterator) listbackport_for_each_element_safe(&ListOfRouter, nr, list, iterator)
45
46 int ParseElectionPacket (struct RtElHelloPkt *rcvPkt, struct RouterListEntry *listEntry){
47   OLSR_PRINTF(1, "parsing ipv4 packet \n");
48   listEntry->ttl = ENTRYTTL;
49   listEntry->network_id = rcvPkt->network_id;
50   listbackport_init_node(&listEntry->list);
51   (void) memcpy(&listEntry->router_id, &rcvPkt->router_id.v4, sizeof(struct in_addr));  //Need to insert an address validity check?
52   return 1;
53 }
54
55 int ParseElectionPacket6 (struct RtElHelloPkt *rcvPkt, struct RouterListEntry6 *listEntry6){
56   OLSR_PRINTF(1, "parsing ipv6 packet \n");
57   listEntry6->ttl = ENTRYTTL;
58   listEntry6->network_id = rcvPkt->network_id;
59   listbackport_init_node(&listEntry6->list);
60   (void) memcpy(&listEntry6->router_id, &rcvPkt->router_id.v6, sizeof(struct in6_addr));//Need to insert an address validity check?
61   return 1;
62 }
63
64 int UpdateRouterList (struct RouterListEntry *listEntry){
65
66   struct RouterListEntry *tmp, *iterator;
67   int exist = 0, status = 0;
68
69   if (olsr_cnf->ip_version == AF_INET6)         //mdns plugin is running in ipv4, discard ipv6
70     return 0;
71
72   ROUTER_ELECTION_ENTRIES(tmp, iterator) {
73     OLSR_PRINTF(1,"inspecting entry");
74     if((tmp->network_id == listEntry->network_id) &&
75                 (memcmp(&listEntry->router_id, &tmp->router_id, sizeof(struct in_addr)) == 0)){
76       exist = 1;
77       tmp->ttl = listEntry->ttl;
78       status = 1;
79     }
80   }
81     if (exist == 0)
82       listbackport_add_tail(&ListOfRouter, &(listEntry->list));
83   return status;
84 }
85
86 int UpdateRouterList6 (struct RouterListEntry6 *listEntry6){
87
88   struct RouterListEntry6 *tmp, *iterator;
89   int exist = 0, status = 0;
90
91   if (olsr_cnf->ip_version == AF_INET)          //mdns plugin is running in ipv6, discard ipv4
92     return 0;
93  
94   ROUTER_ELECTION_ENTRIES(tmp, iterator) { 
95     if((tmp->network_id == listEntry6->network_id) &&
96               (memcmp(&listEntry6->router_id, &tmp->router_id, sizeof(struct in6_addr))) == 0){
97       exist = 1;
98       tmp->ttl = listEntry6->ttl;
99       status = 1;
100     }
101   }
102     if (exist == 0)
103       listbackport_add_tail(&ListOfRouter, &(listEntry6->list));
104   return status;
105 }
106
107 void helloTimer (void *foo __attribute__ ((unused))){
108
109   struct TBmfInterface *walker;
110   struct sockaddr_in dest;
111   struct sockaddr_in6 dest6;
112   OLSR_PRINTF(1,"hello start \n");
113
114   for (walker = BmfInterfaces; walker != NULL; walker = walker->next) {
115     if (olsr_cnf->ip_version == AF_INET) {
116       memset((char *) &dest, 0, sizeof(dest));
117       dest.sin_family = AF_INET;
118       dest.sin_addr.s_addr = inet_addr("224.0.0.2");
119       dest.sin_port = htons(5354);
120
121       OLSR_PRINTF(1,"hello running \n");
122
123       OLSR_PRINTF(1,"%zd \n", sendto(walker->helloSkfd, (const char * ) hello, 
124                         sizeof(struct RtElHelloPkt), 0, (struct sockaddr *)&dest, sizeof(dest)));
125     }
126     else{
127       memset((char *) &dest6, 0, sizeof(dest6));
128       dest6.sin6_family = AF_INET6;
129       (void) inet_pton(AF_INET6, "ff02::2", &dest6.sin6_addr);
130       dest6.sin6_port = htons(5354);
131
132       OLSR_PRINTF(1,"hello running \n");
133
134       OLSR_PRINTF(1,"%i \n", (int) sendto(walker->helloSkfd, (const char * ) hello,  
135                         sizeof(struct RtElHelloPkt), 0, (struct sockaddr *)&dest6, sizeof(dest6)));
136     }
137   }
138   return;
139 }
140
141 void electTimer (void *foo __attribute__ ((unused))){
142
143   struct RouterListEntry *tmp, *iterator;
144   struct RouterListEntry6 *tmp6, *iterator6;
145
146   OLSR_PRINTF(1,"elect start \n");
147
148   if (listbackport_is_empty(&ListOfRouter)){
149     ISMASTER = 1;
150     OLSR_PRINTF(1,"elect empty \n");
151     return;
152   }
153
154   ISMASTER = 1;
155   if (olsr_cnf->ip_version == AF_INET) {
156     ROUTER_ELECTION_ENTRIES(tmp, iterator){
157       OLSR_PRINTF(1,"inspecting element \n");
158       if(tmp->network_id == NETWORK_ID)
159         if(memcmp(&tmp->router_id, &ROUTER_ID.v4, sizeof(struct in_addr)) < 0)
160           ISMASTER = 0;
161       OLSR_PRINTF(1,"confrontation done \n");
162       tmp->ttl = ((tmp->ttl)- 1);
163       if(tmp->ttl <= 0){
164         listbackport_remove(&tmp->list);
165         free(tmp);
166       }
167       OLSR_PRINTF(1,"inspect finish \n");
168     }
169   }
170   else{
171     ROUTER_ELECTION_ENTRIES(tmp6, iterator6){
172       if(tmp6->network_id == NETWORK_ID)
173         if(memcmp(&tmp6->router_id, &ROUTER_ID.v6, sizeof(struct in6_addr)) < 0)
174           ISMASTER = 0;
175       tmp6->ttl = ((tmp6->ttl)- 1);
176       if(tmp6->ttl <=  0){
177         listbackport_remove(&tmp6->list);
178         free(tmp6);
179       }
180     }
181   }
182
183   OLSR_PRINTF(1,"elect finish \n");
184
185   return;
186 }
187
188 void initTimer (void *foo __attribute__ ((unused))){
189   listbackport_init_head(&ListOfRouter);
190
191   NETWORK_ID = (uint8_t) 1;             //Default Network id
192
193   OLSR_PRINTF(1,"Initialization \n");
194   memcpy(&ROUTER_ID, &olsr_cnf->main_addr, sizeof(union olsr_ip_addr));
195   hello = (struct RtElHelloPkt *) malloc(sizeof(struct RtElHelloPkt));
196   OLSR_PRINTF(1,"initialization running step 1\n");
197   strcpy(hello->head, "$REP");
198   if(olsr_cnf->ip_version == AF_INET)
199     hello->ipFamily = AF_INET;
200   else
201     hello->ipFamily = AF_INET6;
202   hello->network_id = NETWORK_ID;
203   memcpy(&hello->router_id, &ROUTER_ID, sizeof(union olsr_ip_addr));
204   OLSR_PRINTF(1,"initialization end\n");
205   return;
206 }
207
208 int
209 set_Network_ID(const char *Network_ID, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused)))
210 {
211   int temp;
212   assert(Network_ID!= NULL);
213   set_plugin_int(Network_ID, &temp, addon);
214   NETWORK_ID = (uint8_t) temp;
215   return 0;
216 } /* Set Network ID */
217
218
219 int InitRouterList(void *foo __attribute__ ((unused))){
220
221   struct olsr_cookie_info *RouterElectionTimerCookie = NULL;
222   struct olsr_cookie_info *HelloTimerCookie = NULL;
223   struct olsr_cookie_info *InitCookie = NULL;
224
225   RouterElectionTimerCookie = olsr_alloc_cookie("Router Election", OLSR_COOKIE_TYPE_TIMER);
226   HelloTimerCookie = olsr_alloc_cookie("Hello Packet", OLSR_COOKIE_TYPE_TIMER);
227   InitCookie = olsr_alloc_cookie("Init", OLSR_COOKIE_TYPE_TIMER);
228
229   olsr_start_timer((unsigned int) INIT_TIMER * MSEC_PER_SEC, 0, OLSR_TIMER_ONESHOT, initTimer, NULL,
230                    InitCookie);
231   olsr_start_timer((unsigned int) HELLO_TIMER * MSEC_PER_SEC, 0, OLSR_TIMER_PERIODIC, helloTimer, NULL,
232                    HelloTimerCookie);
233   olsr_start_timer((unsigned int) ELECTION_TIMER * MSEC_PER_SEC, 0, OLSR_TIMER_PERIODIC, electTimer, NULL,
234                    RouterElectionTimerCookie);
235
236   return 0;
237 }