mdns: suppress a Coverity warning
[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 struct RtElHelloPkt *hello;
38 uint8_t NETWORK_ID;
39 union olsr_ip_addr ROUTER_ID;
40
41 //List for routers
42 struct list_entity ListOfRouter;
43 #define ROUTER_ELECTION_ENTRIES(nr, iterator) listbackport_for_each_element_safe(&ListOfRouter, nr, list, iterator)
44
45 int ParseElectionPacket (struct RtElHelloPkt *rcvPkt, struct RouterListEntry *listEntry, int skfd){
46   OLSR_PRINTF(1, "parsing ipv4 packet \n");
47   listEntry->ttl = ENTRYTTL;
48   listEntry->network_id = rcvPkt->network_id;
49   listbackport_init_node(&listEntry->list);
50   listEntry->skfd = skfd;
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, int skfd){
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   listEntry6->skfd = skfd;
61   (void) memcpy(&listEntry6->router_id, &rcvPkt->router_id.v6, sizeof(struct in6_addr));//Need to insert an address validity check?
62   return 1;
63 }
64
65 int UpdateRouterList (struct RouterListEntry *listEntry){
66
67   struct RouterListEntry *tmp, *iterator;
68   int exist = 0, status = 0;
69
70   if (olsr_cnf->ip_version == AF_INET6)         //mdns plugin is running in ipv4, discard ipv6
71     return 0;
72
73   ROUTER_ELECTION_ENTRIES(tmp, iterator) {
74     OLSR_PRINTF(1,"inspecting entry");
75     if((tmp->network_id == listEntry->network_id) && (tmp->skfd == listEntry->skfd) &&
76                 (memcmp(&listEntry->router_id, &tmp->router_id, sizeof(struct in_addr)) == 0)){
77       exist = 1;
78       tmp->ttl = listEntry->ttl;
79       status = 1;
80     }
81   }
82     if (exist == 0)
83       listbackport_add_tail(&ListOfRouter, &(listEntry->list));
84   return status;
85 }
86
87 int UpdateRouterList6 (struct RouterListEntry6 *listEntry6){
88
89   struct RouterListEntry6 *tmp, *iterator;
90   int exist = 0, status = 0;
91
92   if (olsr_cnf->ip_version == AF_INET)          //mdns plugin is running in ipv6, discard ipv4
93     return 0;
94  
95   ROUTER_ELECTION_ENTRIES(tmp, iterator) { 
96     if((tmp->network_id == listEntry6->network_id) && (tmp->skfd == listEntry6->skfd)  &&
97               (memcmp(&listEntry6->router_id, &tmp->router_id, sizeof(struct in6_addr))) == 0){
98       exist = 1;
99       tmp->ttl = listEntry6->ttl;
100       status = 1;
101     }
102   }
103     if (exist == 0)
104       listbackport_add_tail(&ListOfRouter, &(listEntry6->list));
105   return status;
106 }
107
108 void helloTimer (void *foo __attribute__ ((unused))){
109
110   struct TBmfInterface *walker;
111   struct sockaddr_in dest;
112   struct sockaddr_in6 dest6;
113   OLSR_PRINTF(1,"hello start \n");
114
115   for (walker = BmfInterfaces; walker != NULL; walker = walker->next) {
116     if (olsr_cnf->ip_version == AF_INET) {
117       memset((char *) &dest, 0, sizeof(dest));
118       dest.sin_family = AF_INET;
119       dest.sin_addr.s_addr = inet_addr("224.0.0.2");
120       dest.sin_port = htons(5354);
121
122       OLSR_PRINTF(1,"hello running \n");
123
124       sendto(walker->helloSkfd, (const char * ) hello, 
125                         sizeof(struct RtElHelloPkt), 0, (struct sockaddr *)&dest, sizeof(dest));
126     }
127     else{
128       memset((char *) &dest6, 0, sizeof(dest6));
129       dest6.sin6_family = AF_INET6;
130       (void) inet_pton(AF_INET6, "ff02::2", &dest6.sin6_addr);
131       dest6.sin6_port = htons(5354);
132
133       OLSR_PRINTF(1,"hello running \n");
134
135       sendto(walker->helloSkfd, (const char * ) hello,  
136                         sizeof(struct RtElHelloPkt), 0, (struct sockaddr *)&dest6, sizeof(dest6));
137     }
138   }
139   return;
140 }
141
142 void electTimer (void *foo __attribute__ ((unused))){
143
144   struct TBmfInterface *walker;
145   struct RouterListEntry *tmp, *iterator;
146   struct RouterListEntry6 *tmp6, *iterator6;
147
148   OLSR_PRINTF(1,"elect start \n");
149
150   for(walker = BmfInterfaces; walker != NULL; walker = walker->next){
151     if (listbackport_is_empty(&ListOfRouter)){
152       walker->isActive = 1;
153       OLSR_PRINTF(1,"elect empty \n");
154       continue;
155     }
156
157     walker->isActive = 1;
158     if (olsr_cnf->ip_version == AF_INET) {
159       ROUTER_ELECTION_ENTRIES(tmp, iterator){
160         OLSR_PRINTF(1,"inspecting element \n");
161         if(tmp->network_id == NETWORK_ID)
162           if(tmp->skfd == walker->electionSkfd)
163             if(memcmp(&tmp->router_id, &ROUTER_ID.v4, sizeof(struct in_addr)) < 0)
164               walker->isActive = 0;
165         OLSR_PRINTF(1,"confrontation done \n");
166         tmp->ttl = ((tmp->ttl)- 1);
167         if(tmp->ttl <= 0){
168           listbackport_remove(&tmp->list);
169           free(tmp);
170         }
171         OLSR_PRINTF(1,"inspect finish \n");
172       }
173     }
174     else{
175       ROUTER_ELECTION_ENTRIES(tmp6, iterator6){
176         if(tmp6->network_id == NETWORK_ID)
177           if(tmp6->skfd == walker->electionSkfd)
178             if(memcmp(&tmp6->router_id, &ROUTER_ID.v6, sizeof(struct in6_addr)) < 0)
179               walker->isActive = 0;
180         tmp6->ttl = ((tmp6->ttl)- 1);
181         if(tmp6->ttl <=  0){
182           listbackport_remove(&tmp6->list);
183           free(tmp6);
184         }
185       }
186     }
187
188     OLSR_PRINTF(1,"elect finish \n");
189   }
190
191   return;
192 }
193
194 void initTimer (void *foo __attribute__ ((unused))){
195   listbackport_init_head(&ListOfRouter);
196
197   NETWORK_ID = (uint8_t) 1;             //Default Network id
198
199   OLSR_PRINTF(1,"Initialization \n");
200   memcpy(&ROUTER_ID, &olsr_cnf->main_addr, sizeof(union olsr_ip_addr));
201   hello = (struct RtElHelloPkt *) malloc(sizeof(struct RtElHelloPkt));
202   OLSR_PRINTF(1,"initialization running step 1\n");
203   memcpy(hello->head, "$REP", 4);
204   if(olsr_cnf->ip_version == AF_INET)
205     hello->ipFamily = AF_INET;
206   else
207     hello->ipFamily = AF_INET6;
208   hello->network_id = NETWORK_ID;
209   memcpy(&hello->router_id, &ROUTER_ID, sizeof(union olsr_ip_addr));
210   OLSR_PRINTF(1,"initialization end\n");
211   return;
212 }
213
214 int
215 set_Network_ID(const char *Network_ID, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused)))
216 {
217   int temp;
218   assert(Network_ID!= NULL);
219   set_plugin_int(Network_ID, &temp, addon);
220   NETWORK_ID = (uint8_t) temp;
221   return 0;
222 } /* Set Network ID */
223
224
225 int InitRouterList(void *foo __attribute__ ((unused))){
226
227   struct olsr_cookie_info *RouterElectionTimerCookie = NULL;
228   struct olsr_cookie_info *HelloTimerCookie = NULL;
229   struct olsr_cookie_info *InitCookie = NULL;
230
231   RouterElectionTimerCookie = olsr_alloc_cookie("Router Election", OLSR_COOKIE_TYPE_TIMER);
232   HelloTimerCookie = olsr_alloc_cookie("Hello Packet", OLSR_COOKIE_TYPE_TIMER);
233   InitCookie = olsr_alloc_cookie("Init", OLSR_COOKIE_TYPE_TIMER);
234
235   olsr_start_timer((unsigned int) INIT_TIMER * MSEC_PER_SEC, 0, OLSR_TIMER_ONESHOT, initTimer, NULL,
236                    InitCookie);
237   olsr_start_timer((unsigned int) HELLO_TIMER * MSEC_PER_SEC, 0, OLSR_TIMER_PERIODIC, helloTimer, NULL,
238                    HelloTimerCookie);
239   olsr_start_timer((unsigned int) ELECTION_TIMER * MSEC_PER_SEC, 0, OLSR_TIMER_PERIODIC, electTimer, NULL,
240                    RouterElectionTimerCookie);
241
242   return 0;
243 }