Rename 'struct interface' to 'struct interface_olsr'
[olsrd.git] / lib / p2pd / src / NetworkInterfaces.c
1 /*
2  * The olsr.org Optimized Link-State Routing daemon(olsrd)
3  * Copyright (c) 2004-2009, the olsr.org team - see HISTORY file
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  */
40
41
42 #include "NetworkInterfaces.h"
43
44 /* System includes */
45 #include <stddef.h>             /* NULL */
46 #include <syslog.h>             /* syslog() */
47 #include <string.h>             /* strerror(), strchr(), strcmp() */
48 #include <errno.h>              /* errno */
49 #include <unistd.h>             /* close() */
50 #include <sys/ioctl.h>          /* ioctl() */
51 #include <fcntl.h>              /* fcntl() */
52 #include <assert.h>             /* assert() */
53 #include <net/if.h>             /* socket(), ifreq, if_indextoname(), if_nametoindex() */
54 #include <netinet/in.h>         /* htons() */
55 #include <linux/if_ether.h>     /* ETH_P_IP */
56 #include <linux/if_packet.h>    /* packet_mreq, PACKET_MR_PROMISC, PACKET_ADD_MEMBERSHIP */
57 #include <linux/if_tun.h>       /* IFF_TAP */
58 #include <netinet/ip.h>         /* struct ip */
59 #include <netinet/udp.h>        /* SOL_UDP */
60 #include <stdlib.h>             /* atoi, malloc */
61
62 /* OLSRD includes */
63 #include "olsr.h"               /* OLSR_PRINTF() */
64 #include "ipcalc.h"
65 #include "defs.h"               /* olsr_cnf */
66 #include "link_set.h"           /* get_link_set() */
67 #include "tc_set.h"             /* olsr_lookup_tc_entry(), olsr_lookup_tc_edge() */
68 #include "net_olsr.h"           /* ipequal */
69 #include "lq_plugin.h"
70 //#include "olsr_ip_prefix_list.h"
71
72 /* Plugin includes */
73 #include "Packet.h"             /* IFHWADDRLEN */
74 #include "p2pd.h"               /* PLUGIN_NAME, MainAddressOf() */
75 //#include "Address.h"            /* IsMulticast() */
76
77
78 /* List of network interface objects used by BMF plugin */
79 struct NonOlsrInterface *nonOlsrInterfaces = NULL;
80 struct NonOlsrInterface *lastNonOlsrInterface = NULL;
81
82 /* -------------------------------------------------------------------------
83  * Function   : CreateCaptureSocket
84  * Description: Create socket for promiscuously capturing multicast IP traffic
85  * Input      : ifname - network interface (e.g. "eth0")
86  * Output     : none
87  * Return     : the socket descriptor ( >= 0), or -1 if an error occurred
88  * Data Used  : none
89  * Notes      : The socket is a cooked IP packet socket, bound to the specified
90  *              network interface
91  * ------------------------------------------------------------------------- */
92 int
93 CreateCaptureSocket(const char *ifName)
94 {
95   int ifIndex = if_nametoindex(ifName);
96   struct packet_mreq mreq;
97   struct ifreq req;
98   struct sockaddr_ll bindTo;
99   int skfd = 0;
100   /* Open cooked IP packet socket */
101   if (olsr_cnf->ip_version == AF_INET) {
102     skfd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP));
103   } else {
104     skfd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IPV6));
105   }
106   if (skfd < 0) {
107     P2pdPError("socket(PF_PACKET) error");
108     return -1;
109   }
110
111   /* Set interface to promiscuous mode */
112   memset(&mreq, 0, sizeof(struct packet_mreq));
113   mreq.mr_ifindex = ifIndex;
114   mreq.mr_type = PACKET_MR_PROMISC;
115   if (setsockopt(skfd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) {
116     P2pdPError("setsockopt(PACKET_MR_PROMISC) error");
117     close(skfd);
118     return -1;
119   }
120
121   /* Get hardware (MAC) address */
122   memset(&req, 0, sizeof(struct ifreq));
123   strncpy(req.ifr_name, ifName, IFNAMSIZ - 1);
124   req.ifr_name[IFNAMSIZ - 1] = '\0';    /* Ensures null termination */
125   if (ioctl(skfd, SIOCGIFHWADDR, &req) < 0) {
126     P2pdPError("error retrieving MAC address");
127     close(skfd);
128     return -1;
129   }
130
131   /* Bind the socket to the specified interface */
132   memset(&bindTo, 0, sizeof(bindTo));
133   bindTo.sll_family = AF_PACKET;
134   if (olsr_cnf->ip_version == AF_INET) {
135     bindTo.sll_protocol = htons(ETH_P_IP);
136   } else {
137     bindTo.sll_protocol = htons(ETH_P_IPV6);
138   }
139   bindTo.sll_ifindex = ifIndex;
140   memcpy(bindTo.sll_addr, req.ifr_hwaddr.sa_data, IFHWADDRLEN);
141   bindTo.sll_halen = IFHWADDRLEN;
142
143   if (bind(skfd, (struct sockaddr *)&bindTo, sizeof(bindTo)) < 0) {
144     P2pdPError("bind() error");
145     close(skfd);
146     return -1;
147   }
148
149   /* Set socket to blocking operation */
150   if (fcntl(skfd, F_SETFL, fcntl(skfd, F_GETFL, 0) & ~O_NONBLOCK) < 0) {
151     P2pdPError("fcntl() error");
152     close(skfd);
153     return -1;
154   }
155   //AddDescriptorToInputSet(skfd);
156   add_olsr_socket(skfd, (socket_handler_func)&DoP2pd, NULL, NULL, SP_PR_READ);
157
158   return skfd;
159 }                               /* CreateCaptureSocket */
160
161 /* -------------------------------------------------------------------------
162  * Function   : CreateInterface
163  * Description: Create a new NonOlsrInterface object and adds it to the global
164  *              nonOlsrInterfaces list
165  * Input      : ifName - name of the network interface (e.g. "eth0")
166  *            : olsrIntf - OLSR interface object of the network interface, or
167  *                NULL if the network interface is not OLSR-enabled
168  * Output     : none
169  * Return     : the number of opened sockets
170  * Data Used  : nonOlsrInterfaces, lastNonOlsrInterface
171  * ------------------------------------------------------------------------- */
172
173 //FOR MDNS IS ALWAYS CALLED WITH NULL AS SECOND ARG
174
175 static int
176 CreateInterface(const char *ifName, struct interface_olsr *olsrIntf)
177 {
178   int capturingSkfd = -1;
179   int encapsulatingSkfd = -1;
180   int listeningSkfd = -1;
181   int ioctlSkfd;
182   struct ifreq ifr;
183   int nOpened = 0;
184   struct NonOlsrInterface *newIf = malloc(sizeof(struct NonOlsrInterface));
185
186   assert(ifName != NULL);
187
188   if (newIf == NULL) {
189     return 0;
190   }
191 //TODO: assert interface is not talking OLSR
192
193
194   /* Create socket for capturing and sending of multicast packets on
195    * non-OLSR interfaces, and on OLSR-interfaces if configured. */
196   if ((olsrIntf == NULL)) {
197     capturingSkfd = CreateCaptureSocket(ifName);
198     if (capturingSkfd < 0) {
199       free(newIf);
200       return 0;
201     }
202
203     nOpened++;
204   }
205
206   /* For ioctl operations on the network interface, use either capturingSkfd
207    * or encapsulatingSkfd, whichever is available */
208   ioctlSkfd = (capturingSkfd >= 0) ? capturingSkfd : encapsulatingSkfd;
209
210   /* Retrieve the MAC address of the interface. */
211   memset(&ifr, 0, sizeof(struct ifreq));
212   strncpy(ifr.ifr_name, ifName, IFNAMSIZ - 1);
213   ifr.ifr_name[IFNAMSIZ - 1] = '\0';    /* Ensures null termination */
214   if (ioctl(ioctlSkfd, SIOCGIFHWADDR, &ifr) < 0) {
215     P2pdPError("ioctl(SIOCGIFHWADDR) error for interface \"%s\"", ifName);
216     if (capturingSkfd >= 0) {
217       close(capturingSkfd);
218     }
219     free(newIf);
220     return 0;
221   }
222
223   /* Copy data into NonOlsrInterface object */
224   newIf->capturingSkfd = capturingSkfd;
225   newIf->encapsulatingSkfd = encapsulatingSkfd;
226   newIf->listeningSkfd = listeningSkfd;
227   memcpy(newIf->macAddr, ifr.ifr_hwaddr.sa_data, IFHWADDRLEN);
228   memcpy(newIf->ifName, ifName, IFNAMSIZ);
229   newIf->olsrIntf = olsrIntf;
230   if (olsrIntf != NULL) {
231     /* For an OLSR-interface, copy the interface address and broadcast
232      * address from the OLSR interface object. Downcast to correct sockaddr
233      * subtype. */
234     newIf->intAddr.v4 = olsrIntf->int_addr.sin_addr;
235     newIf->broadAddr.v4 = olsrIntf->int_broadaddr.sin_addr;
236   } else {
237     /* For a non-OLSR interface, retrieve the IP address ourselves */
238     memset(&ifr, 0, sizeof(struct ifreq));
239     strncpy(ifr.ifr_name, ifName, IFNAMSIZ - 1);
240     ifr.ifr_name[IFNAMSIZ - 1] = '\0';  /* Ensures null termination */
241     if (ioctl(ioctlSkfd, SIOCGIFADDR, &ifr) < 0) {
242       P2pdPError("ioctl(SIOCGIFADDR) error for interface \"%s\"", ifName);
243
244       newIf->intAddr.v4.s_addr = inet_addr("0.0.0.0");
245     } else {
246       /* Downcast to correct sockaddr subtype */
247       newIf->intAddr.v4 = ((struct sockaddr_in *) ARM_NOWARN_ALIGN(&ifr.ifr_addr))->sin_addr;
248     }
249
250     /* For a non-OLSR interface, retrieve the IP broadcast address ourselves */
251     memset(&ifr, 0, sizeof(struct ifreq));
252     strncpy(ifr.ifr_name, ifName, IFNAMSIZ - 1);
253     ifr.ifr_name[IFNAMSIZ - 1] = '\0';  /* Ensures null termination */
254     if (ioctl(ioctlSkfd, SIOCGIFBRDADDR, &ifr) < 0) {
255       P2pdPError("ioctl(SIOCGIFBRDADDR) error for interface \"%s\"", ifName);
256
257       newIf->broadAddr.v4.s_addr = inet_addr("0.0.0.0");
258     } else {
259       /* Downcast to correct sockaddr subtype */
260       newIf->broadAddr.v4 = ((struct sockaddr_in *) ARM_NOWARN_ALIGN(&ifr.ifr_broadaddr))->sin_addr;
261     }
262   }
263
264   /* Initialize fragment history table */
265   //memset(&newIf->fragmentHistory, 0, sizeof(newIf->fragmentHistory));
266   //newIf->nextFragmentHistoryEntry = 0;
267
268   /* Reset counters */
269   //newIf->nNonOlsrPacketsRx = 0;
270   //newIf->nNonOlsrPacketsRxDup = 0;
271   //newIf->nNonOlsrPacketsTx = 0;
272
273   /* Add new NonOlsrInterface object to global list. OLSR interfaces are
274    * added at the front of the list, non-OLSR interfaces at the back. */
275   if (nonOlsrInterfaces == NULL) {
276     /* First NonOlsrInterface object in list */
277     newIf->next = NULL;
278     nonOlsrInterfaces = newIf;
279     lastNonOlsrInterface = newIf;
280   } else if (olsrIntf != NULL) {
281     /* Add new NonOlsrInterface object at front of list */
282     newIf->next = nonOlsrInterfaces;
283     nonOlsrInterfaces = newIf;
284   } else {
285     /* Add new NonOlsrInterface object at back of list */
286     newIf->next = NULL;
287     lastNonOlsrInterface->next = newIf;
288     lastNonOlsrInterface = newIf;
289   }
290
291   //OLSR_PRINTF(
292   //  8,
293   //  "%s: opened %d socket%s on %s interface \"%s\"\n",
294   //  PLUGIN_NAME_SHORT,
295   //  nOpened,
296   //  nOpened == 1 ? "" : "s",
297   //  olsrIntf != NULL ? "OLSR" : "non-OLSR",
298   //  ifName);
299
300   return nOpened;
301 }                               /* CreateInterface */
302
303 /* -------------------------------------------------------------------------
304  * Function   : CreateNonOlsrNetworkInterfaces
305  * Description: Create a list of NonOlsrInterface objects, one for each network
306  *              interface on which BMF runs
307  * Input      : skipThisIntf - network interface to skip, if seen
308  * Output     : none
309  * Return     : fail (-1) or success (0)
310  * Data Used  : none
311  * ------------------------------------------------------------------------- */
312 int
313 CreateNonOlsrNetworkInterfaces(struct interface_olsr *skipThisIntf)
314 {
315   int skfd;
316   struct ifconf ifc;
317   int numreqs = 30;
318   struct ifreq *ifr;
319   int n;
320   int nOpenedSockets = 0;
321
322   /* Clear input descriptor set */
323   FD_ZERO(&InputSet);
324
325   skfd = socket(PF_INET, SOCK_DGRAM, 0);
326   if (skfd < 0) {
327     P2pdPError("no inet socket available to retrieve interface list");
328     return -1;
329   }
330
331   /* Retrieve the network interface configuration list */
332   ifc.ifc_buf = NULL;
333   for (;;) {
334     ifc.ifc_len = sizeof(struct ifreq) * numreqs;
335     ifc.ifc_buf = realloc(ifc.ifc_buf, ifc.ifc_len);
336
337     if (ioctl(skfd, SIOCGIFCONF, &ifc) < 0) {
338       P2pdPError("ioctl(SIOCGIFCONF) error");
339
340       close(skfd);
341       free(ifc.ifc_buf);
342       return -1;
343     }
344     if ((unsigned)ifc.ifc_len == sizeof(struct ifreq) * numreqs) {
345       /* Assume it overflowed; double the space and try again */
346       numreqs *= 2;
347       assert(numreqs < 1024);
348       continue;                 /* for (;;) */
349     }
350     break;                      /* for (;;) */
351   }                             /* for (;;) */
352
353   close(skfd);
354
355   /* For each item in the interface configuration list... */
356   ifr = ifc.ifc_req;
357   for (n = ifc.ifc_len / sizeof(struct ifreq); --n >= 0; ifr++) {
358     struct interface_olsr *olsrIntf;
359     union olsr_ip_addr ipAddr;
360
361     /* Skip the BMF network interface itself */
362     //if (strncmp(ifr->ifr_name, EtherTunTapIfName, IFNAMSIZ) == 0)
363     //{
364     //  continue; /* for (n = ...) */
365     //}
366
367     /* ...find the OLSR interface structure, if any */
368     ipAddr.v4 = ((struct sockaddr_in *) ARM_NOWARN_ALIGN(&ifr->ifr_addr))->sin_addr;
369     olsrIntf = if_ifwithaddr(&ipAddr);
370
371     if (skipThisIntf != NULL && olsrIntf == skipThisIntf) {
372       continue;                 /* for (n = ...) */
373     }
374
375     if (olsrIntf == NULL && !IsNonOlsrIf(ifr->ifr_name)) {
376       /* Interface is neither OLSR interface, nor specified as non-OLSR
377        * interface in the plugin parameter list */
378       continue;                 /* for (n = ...) */
379     }
380
381     if (!IsNonOlsrIf(ifr->ifr_name)) {
382       //If the interface is not specified in the configuration file then go ahead
383       continue;                 /* for (n = ...) */
384     }
385     //TODO: asser if->ifr_name is not talking OLSR
386     //nOpenedSockets += CreateInterface(ifr->ifr_name, olsrIntf);
387     nOpenedSockets += CreateInterface(ifr->ifr_name, NULL);
388
389   }                             /* for (n = ...) */
390
391   free(ifc.ifc_buf);
392
393   if (nonOlsrInterfaces == NULL) {
394     //OLSR_PRINTF(1, "%s: could not initialize any network interface\n", PLUGIN_NAME);
395   } else {
396     //OLSR_PRINTF(1, "%s: opened %d sockets\n", PLUGIN_NAME, nOpenedSockets);
397   }
398   return 0;
399 }                               /* CreateNonOlsrNetworkInterfaces */
400
401 /* -------------------------------------------------------------------------
402  * Function   : AddInterface
403  * Description: Add an OLSR-enabled network interface to the list of BMF-enabled
404  *              network interfaces
405  * Input      : newIntf - network interface to add
406  * Output     : none
407  * Return     : none
408  * Data Used  : none
409  * ------------------------------------------------------------------------- */
410 void
411 AddInterface(struct interface_olsr *newIntf)
412 {
413   /* int nOpened; */
414
415   assert(newIntf != NULL);
416
417   /* nOpened = */ (void)CreateInterface(newIntf->int_name, newIntf);
418
419   //OLSR_PRINTF(1, "%s: opened %d sockets\n", PLUGIN_NAME, nOpened);
420 }                               /* AddInterface */
421
422 /* -------------------------------------------------------------------------
423  * Function   : CloseNonOlsrNetworkInterfaces
424  * Description: Closes every socket on each network interface used by BMF
425  * Input      : none
426  * Output     : none
427  * Return     : none
428  * Data Used  : none
429  * Notes      : Closes
430  *              - the local EtherTunTap interface (e.g. "tun0" or "tap0")
431  *              - for each BMF-enabled interface, the socket used for
432  *                capturing multicast packets
433  *              - for each OLSR-enabled interface, the socket used for
434  *                encapsulating packets
435  *              Also restores the network state to the situation before BMF
436  *              was started.
437  * ------------------------------------------------------------------------- */
438 void
439 CloseNonOlsrNetworkInterfaces(void)
440 {
441   int nClosed = 0;
442   u_int32_t totalOlsrPacketsRx = 0;
443   u_int32_t totalOlsrPacketsRxDup = 0;
444   u_int32_t totalOlsrPacketsTx = 0;
445   u_int32_t totalNonOlsrPacketsRx = 0;
446   u_int32_t totalNonOlsrPacketsRxDup = 0;
447   u_int32_t totalNonOlsrPacketsTx = 0;
448
449   /* Close all opened sockets */
450   struct NonOlsrInterface *nextIf = nonOlsrInterfaces;
451   while (nextIf != NULL) {
452     struct NonOlsrInterface *ifc = nextIf;
453     nextIf = ifc->next;
454
455     if (ifc->capturingSkfd >= 0) {
456       close(ifc->capturingSkfd);
457       nClosed++;
458     }
459     if (ifc->encapsulatingSkfd >= 0) {
460       close(ifc->encapsulatingSkfd);
461       nClosed++;
462     }
463     //OLSR_PRINTF(
464     //  7,
465     //  "%s: %s interface \"%s\": RX pkts %u (%u dups); TX pkts %u\n",
466     //  PLUGIN_NAME_SHORT,
467     //  ifc->olsrIntf != NULL ? "OLSR" : "non-OLSR",
468     //  ifc->ifName,
469     //  ifc->nPacketsRx,
470     //  ifc->nPacketsRxDup,
471     //  ifc->nPacketsTx);
472
473     //OLSR_PRINTF(
474     //  1,
475     //  "%s: closed %s interface \"%s\"\n",
476     //  PLUGIN_NAME_SHORT,
477     //  ifc->olsrIntf != NULL ? "OLSR" : "non-OLSR",
478     //  ifc->ifName);
479
480     /* Add totals */
481     if (ifc->olsrIntf != NULL) {
482       totalOlsrPacketsRx                                += ifc->nPacketsRx;
483       totalOlsrPacketsRxDup                     += ifc->nPacketsRxDup;
484       totalOlsrPacketsTx                                += ifc->nPacketsTx;
485     } else {
486       totalNonOlsrPacketsRx             += ifc->nPacketsRx;
487       totalNonOlsrPacketsRxDup  += ifc->nPacketsRxDup;
488       totalNonOlsrPacketsTx                     += ifc->nPacketsTx;
489     }
490
491     free(ifc);
492   }                             /* while */
493
494   nonOlsrInterfaces = NULL;
495
496   //OLSR_PRINTF(1, "%s: closed %d sockets\n", PLUGIN_NAME_SHORT, nClosed);
497
498 }                               /* CloseNonOlsrNetworkInterfaces */
499
500 #define MAX_NON_OLSR_IFS 32
501 static char NonOlsrIfNames[MAX_NON_OLSR_IFS][IFNAMSIZ];
502 static int nNonOlsrIfs = 0;
503 /* -------------------------------------------------------------------------
504  * Function   : AddNonOlsrIf
505  * Description: Add an non-OLSR enabled network interface to the list of BMF-enabled
506  *              network interfaces
507  * Input      : ifName - network interface (e.g. "eth0")
508  *              data - not used
509  *              addon - not used
510  * Output     : none
511  * Return     : success (0) or fail (1)
512  * Data Used  : NonOlsrIfNames
513  * ------------------------------------------------------------------------- */
514 int
515 AddNonOlsrIf(const char *ifName, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused)))
516 {
517   assert(ifName != NULL);
518
519   if (nNonOlsrIfs >= MAX_NON_OLSR_IFS) {
520     //OLSR_PRINTF(
521     //  1,
522     //  "%s: too many non-OLSR interfaces specified, maximum is %d\n",
523     //  PLUGIN_NAME,
524     //  MAX_NON_OLSR_IFS);
525     return 1;
526   }
527
528   olsr_printf(1, "\nAdding interface '%s' to list of interface\n", ifName);
529   
530   strncpy(NonOlsrIfNames[nNonOlsrIfs], ifName, IFNAMSIZ - 1);
531   NonOlsrIfNames[nNonOlsrIfs][IFNAMSIZ - 1] = '\0';     /* Ensures null termination */
532   nNonOlsrIfs++;
533   return 0;
534 }                               /* AddNonOlsrIf */
535
536 /* -------------------------------------------------------------------------
537  * Function   : IsNonOlsrIf
538  * Description: Checks if a network interface is OLSR-enabled
539  * Input      : ifName - network interface (e.g. "eth0")
540  * Output     : none
541  * Return     : true (1) or false (0)
542  * Data Used  : NonOlsrIfNames
543  * ------------------------------------------------------------------------- */
544 int
545 IsNonOlsrIf(const char *ifName)
546 {
547   int i;
548
549   assert(ifName != NULL);
550
551   for (i = 0; i < nNonOlsrIfs; i++) {
552     if (strncmp(NonOlsrIfNames[i], ifName, IFNAMSIZ) == 0)
553       return 1;
554   }
555   return 0;
556 }                               /* IsNonOlsrIf */