2 * The olsr.org Optimized Link-State Routing daemon(olsrd)
3 * Copyright (c) 2004-2009, the olsr.org team - see HISTORY file
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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
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.
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.
33 * Visit http://www.olsr.org for more information.
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.
42 #include "NetworkInterfaces.h"
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() */
56 #include <linux/if_ether.h> /* ETH_P_IP */
57 #include <linux/if_packet.h> /* packet_mreq, PACKET_MR_PROMISC, PACKET_ADD_MEMBERSHIP */
58 #include <linux/if_tun.h> /* IFF_TAP */
59 #endif /* __linux__ */
60 #include <netinet/ip.h> /* struct ip */
61 #include <netinet/udp.h> /* SOL_UDP */
62 #include <stdlib.h> /* atoi, malloc */
63 #include <strings.h> /* strcasecmp */
66 #include "olsr.h" /* OLSR_PRINTF() */
68 #include "defs.h" /* olsr_cnf */
69 #include "link_set.h" /* get_link_set() */
70 #include "tc_set.h" /* olsr_lookup_tc_entry(), olsr_lookup_tc_edge() */
71 #include "net_olsr.h" /* ipequal */
72 #include "lq_plugin.h"
73 //#include "olsr_ip_prefix_list.h"
76 #include "Packet.h" /* IFHWADDRLEN */
77 #include "mdns.h" /* PLUGIN_NAME, MainAddressOf() */
78 #include "Address.h" /* IsMulticast() */
79 #include "plugin_util.h"
84 /* List of network interface objects used by BMF plugin */
85 struct TBmfInterface *BmfInterfaces = NULL;
86 struct TBmfInterface *LastBmfInterface = NULL;
88 /* Highest-numbered open socket file descriptor. To be used as first
89 * parameter in calls to select(...). */
92 /* Set of socket file descriptors */
96 /* -------------------------------------------------------------------------
97 * Function : CreateCaptureSocket
98 * Description: Create socket for promiscuously capturing multicast IP traffic
99 * Input : ifname - network interface (e.g. "eth0")
101 * Return : the socket descriptor ( >= 0), or -1 if an error occurred
103 * Notes : The socket is a cooked IP packet socket, bound to the specified
105 * ------------------------------------------------------------------------- */
107 CreateCaptureSocket(const char *ifName)
109 int ifIndex = if_nametoindex(ifName);
110 struct packet_mreq mreq;
112 struct sockaddr_ll bindTo;
114 /* Open cooked IP packet socket */
115 if (olsr_cnf->ip_version == AF_INET) {
116 skfd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP));
118 skfd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IPV6));
121 BmfPError("socket(PF_PACKET) error");
125 /* Set interface to promiscuous mode */
126 memset(&mreq, 0, sizeof(struct packet_mreq));
127 mreq.mr_ifindex = ifIndex;
128 mreq.mr_type = PACKET_MR_PROMISC;
129 if (setsockopt(skfd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) {
130 BmfPError("setsockopt(PACKET_MR_PROMISC) error");
135 /* Get hardware (MAC) address */
136 memset(&req, 0, sizeof(struct ifreq));
137 strncpy(req.ifr_name, ifName, IFNAMSIZ - 1);
138 req.ifr_name[IFNAMSIZ - 1] = '\0'; /* Ensures null termination */
139 if (ioctl(skfd, SIOCGIFHWADDR, &req) < 0) {
140 BmfPError("error retrieving MAC address");
145 /* Bind the socket to the specified interface */
146 memset(&bindTo, 0, sizeof(bindTo));
147 bindTo.sll_family = AF_PACKET;
148 if (olsr_cnf->ip_version == AF_INET) {
149 bindTo.sll_protocol = htons(ETH_P_IP);
151 bindTo.sll_protocol = htons(ETH_P_IPV6);
153 bindTo.sll_ifindex = ifIndex;
154 memcpy(bindTo.sll_addr, req.ifr_hwaddr.sa_data, IFHWADDRLEN);
155 bindTo.sll_halen = IFHWADDRLEN;
157 if (bind(skfd, (struct sockaddr *)&bindTo, sizeof(bindTo)) < 0) {
158 BmfPError("bind() error");
163 /* Set socket to blocking operation */
164 if (fcntl(skfd, F_SETFL, fcntl(skfd, F_GETFL, 0) & ~O_NONBLOCK) < 0) {
165 BmfPError("fcntl() error");
169 //AddDescriptorToInputSet(skfd);
170 add_olsr_socket(skfd, &DoMDNS,NULL, NULL, SP_PR_READ);
173 } /* CreateCaptureSocket */
176 /* -------------------------------------------------------------------------
177 * Function : CreateRouterElectionSocket
178 * Description: Create socket for capturing router election hello packets
179 * Input : ifname - network interface (e.g. "eth0")
181 * Return : the socket descriptor ( >= 0), or -1 if an error occurred
183 * Notes : The socket is a cooked IP packet socket, bound to the specified
185 * ------------------------------------------------------------------------- */
187 CreateRouterElectionSocket(const char *ifName)
192 int ipAddMembershipSetting;
193 short int ipPort = htons(5354);
194 struct in_addr ipv4_addr;
196 int ifIndex = if_nametoindex(ifName);
200 union olsr_sockaddr address;
204 int socketReuseFlagValue = 1;
208 memset(&address, 0, sizeof(address));
209 if (olsr_cnf->ip_version == AF_INET) {
210 ipFamilySetting = AF_INET;
211 ipProtoSetting = IPPROTO_IP;
212 ipMcLoopSetting = IP_MULTICAST_LOOP;
213 ipAddMembershipSetting = IP_ADD_MEMBERSHIP;
215 address.in4.sin_family = ipFamilySetting;
216 address.in4.sin_addr.s_addr = INADDR_ANY;
217 address.in4.sin_port = ipPort;
219 addrSize = sizeof(struct sockaddr_in);
221 ipFamilySetting = AF_INET6;
222 ipProtoSetting = IPPROTO_IPV6;
223 ipMcLoopSetting = IPV6_MULTICAST_LOOP;
224 ipAddMembershipSetting = IPV6_ADD_MEMBERSHIP;
226 address.in6.sin6_family = ipFamilySetting;
227 address.in6.sin6_addr = in6addr_any;
228 address.in6.sin6_port = ipPort;
230 addrSize = sizeof(struct sockaddr_in6);
233 /* Create a datagram socket on which to receive. */
235 rxSocket = socket(ipFamilySetting, SOCK_DGRAM, 0);
237 BmfPError("Could not create a receive socket for interface %s",
242 /* Enable SO_REUSEADDR to allow multiple applications to receive the same
243 * multicast messages */
245 if (setsockopt(rxSocket, SOL_SOCKET, SO_REUSEADDR, &socketReuseFlagValue,
246 sizeof(socketReuseFlagValue)) < 0) {
247 BmfPError("Could not set the reuse flag on the receive socket for"
248 " interface %s", ifName);
252 /* Bind to the proper port number with the IP address INADDR_ANY
253 * (INADDR_ANY is really required here, do not change it) */
255 if (bind(rxSocket, addr, addrSize) < 0) {
256 BmfPError("Could not bind the receive socket for interface"
257 " %s to port %u", ifName, ntohs(ipPort));
261 /* Enable multicast local loopback */
263 if (setsockopt(rxSocket, ipProtoSetting, ipMcLoopSetting, &mcLoopValue,
264 sizeof(mcLoopValue)) < 0) {
265 BmfPError("Could not enable multicast loopback on the"
266 " receive socket for interface %s", ifName);
270 /* Join the multicast group on the local interface. Note that this
271 * ADD_MEMBERSHIP option must be called for each local interface over
272 * which the multicast datagrams are to be received. */
273 if (ipFamilySetting == AF_INET) {
274 static const char * mc4Addr = "224.0.0.2";
275 struct ip_mreq mc_settings;
276 (void) memset(&mc_settings, 0, sizeof(mc_settings));
277 if (inet_pton(AF_INET, mc4Addr, &mc_settings.imr_multiaddr.s_addr) != 1) {
278 BmfPError("Could not convert ipv4 multicast address %s", mc4Addr);
281 (void) memset(&req, 0, sizeof(struct ifreq));
282 strncpy(req.ifr_name, ifName, IFNAMSIZ - 1);
283 req.ifr_name[IFNAMSIZ -1] = '\0'; /* Ensure null termination */
284 if(ioctl(rxSocket, SIOCGIFADDR, &req)){
285 BmfPError("Could not get ipv4 address of %s interface", ifName);
289 struct sockaddr* ifra = &req.ifr_addr;
290 ipv4_addr = ((struct sockaddr_in *)(void *) ifra)->sin_addr;
292 mc_settings.imr_interface = ipv4_addr;
294 if (setsockopt(rxSocket, ipProtoSetting, ipAddMembershipSetting,
295 &mc_settings, sizeof(mc_settings)) < 0) {
296 BmfPError("Could not subscribe interface %s to the configured"
297 " multicast group", ifName);
301 static const char * mc6Addr = "ff02::2";
302 struct ipv6_mreq mc6_settings;
303 (void) memset(&mc6_settings, 0, sizeof(mc6_settings));
304 if (inet_pton(AF_INET6, mc6Addr, &mc6_settings.ipv6mr_multiaddr.s6_addr) != 1) {
305 BmfPError("Could not convert ipv6 multicast address %s", mc6Addr);
308 mc6_settings.ipv6mr_interface = ifIndex;
310 if (setsockopt(rxSocket, ipProtoSetting, ipAddMembershipSetting,
311 &mc6_settings, sizeof(mc6_settings)) < 0) {
312 BmfPError("Could not subscribe interface %s to the configured"
313 " multicast group", ifName);
318 add_olsr_socket(rxSocket, DoElection, NULL, NULL,
323 bail: if (rxSocket >= 0) {
327 } /* CreateRouterElectionSocket */
329 static int CreateHelloSocket(const char *ifName) {
335 short int ipPort = htons(5354);
336 struct in_addr ipv4_addr;
338 int ifIndex = if_nametoindex(ifName);
342 union olsr_sockaddr address;
349 memset(&address, 0, sizeof(address));
350 if (olsr_cnf->ip_version == AF_INET) {
351 ipFamilySetting = AF_INET;
352 ipProtoSetting = IPPROTO_IP;
353 ipMcLoopSetting = IP_MULTICAST_LOOP;
354 ipMcIfSetting = IP_MULTICAST_IF;
355 ipTtlSetting = IP_MULTICAST_TTL;
356 ifIndex = if_nametoindex(ifName);
358 ipFamilySetting = AF_INET6;
359 ipProtoSetting = IPPROTO_IPV6;
360 ipMcLoopSetting = IPV6_MULTICAST_LOOP;
361 ipMcIfSetting = IPV6_MULTICAST_IF;
362 ipTtlSetting = IPV6_MULTICAST_HOPS;
363 ifIndex = if_nametoindex(ifName);
366 addrSize = sizeof(ifIndex);
369 /* Create a datagram socket on which to transmit */
371 txSocket = socket(ipFamilySetting, SOCK_DGRAM, 0);
373 BmfPError("Could not create a transmit socket for interface %s",
378 if (olsr_cnf->ip_version == AF_INET) {
379 (void) memset(&req, 0, sizeof(struct ifreq));
380 strncpy(req.ifr_name, ifName, IFNAMSIZ - 1);
381 req.ifr_name[IFNAMSIZ -1] = '\0'; /* Ensure null termination */
382 if(ioctl(txSocket, SIOCGIFADDR, &req)){
383 BmfPError("Could not get ipv4 address of %s interface", ifName);
387 struct sockaddr * ifra = &req.ifr_addr;
388 ipv4_addr = ((struct sockaddr_in *)(void *) ifra)->sin_addr;
390 address.in4.sin_addr = ipv4_addr;
391 address.in4.sin_family = ipFamilySetting;
392 address.in4.sin_port = ipPort;
394 addrSize = sizeof(struct sockaddr_in);
397 /* Bind the socket to the desired interface */
399 if (setsockopt(txSocket, ipProtoSetting, ipMcIfSetting, addr, addrSize) < 0) {
400 BmfPError("Could not set the multicast interface on the"
401 " transmit socket to interface %s", ifName);
405 /* Disable multicast local loopback */
407 if (setsockopt(txSocket, ipProtoSetting, ipMcLoopSetting, &mcLoopValue,
408 sizeof(mcLoopValue)) < 0) {
409 BmfPError("Could not disable multicast loopback on the"
410 " transmit socket for interface %s", ifName);
414 /* Set the TTL on the socket */
416 if (setsockopt(txSocket, ipProtoSetting, ipTtlSetting, &txTtl,
417 sizeof(txTtl)) < 0) {
418 BmfPError("Could not set TTL on the transmit socket"
419 " for interface %s", ifName);
423 /* Set the no delay option on the socket */
425 if (fcntl(txSocket, F_SETFL, O_NDELAY) < 0) {
426 BmfPError("Could not set the no delay option on the"
427 " transmit socket for interface %s", ifName);
433 bail: if (txSocket >= 0) {
439 /* -------------------------------------------------------------------------
440 * Function : CreateInterface
441 * Description: Create a new TBmfInterface object and adds it to the global
443 * Input : ifName - name of the network interface (e.g. "eth0")
444 * : olsrIntf - OLSR interface object of the network interface, or
445 * NULL if the network interface is not OLSR-enabled
447 * Return : the number of opened sockets
448 * Data Used : BmfInterfaces, LastBmfInterface
449 * ------------------------------------------------------------------------- */
451 //FOR MDNS IS ALWAYS CALLED WITH NULL AS SECOND ARG
454 CreateInterface(const char *ifName, struct interface_olsr *olsrIntf)
456 int capturingSkfd = -1;
457 int encapsulatingSkfd = -1;
458 int listeningSkfd = -1;
459 int electionSkfd = -1;
464 struct TBmfInterface *newIf = olsr_malloc(sizeof(struct TBmfInterface), "TBMFInterface (mdns)");
466 assert(ifName != NULL);
471 //TODO: assert interface is not talking OLSR
474 /* Create socket for capturing and sending of multicast packets on
475 * non-OLSR interfaces, and on OLSR-interfaces if configured. */
477 capturingSkfd = CreateCaptureSocket(ifName);
478 electionSkfd = CreateRouterElectionSocket(ifName);
479 helloSkfd = CreateHelloSocket(ifName);
480 if (capturingSkfd < 0 || electionSkfd < 0 || helloSkfd < 0) {
481 if (capturingSkfd >= 0) {
482 close(capturingSkfd);
484 if (electionSkfd >= 0) {
487 if (helloSkfd >= 0) {
497 /* For ioctl operations on the network interface, use either capturingSkfd
498 * or encapsulatingSkfd, whichever is available */
499 ioctlSkfd = (capturingSkfd >= 0) ? capturingSkfd : encapsulatingSkfd;
501 /* Retrieve the MAC address of the interface. */
502 memset(&ifr, 0, sizeof(struct ifreq));
503 strncpy(ifr.ifr_name, ifName, IFNAMSIZ - 1);
504 ifr.ifr_name[IFNAMSIZ - 1] = '\0'; /* Ensures null termination */
505 if (ioctl(ioctlSkfd, SIOCGIFHWADDR, &ifr) < 0) {
506 BmfPError("ioctl(SIOCGIFHWADDR) error for interface \"%s\"", ifName);
507 if (capturingSkfd >= 0) {
508 close(capturingSkfd);
510 if (electionSkfd >= 0) {
513 if (helloSkfd >= 0) {
520 /* Copy data into TBmfInterface object */
521 newIf->capturingSkfd = capturingSkfd;
522 newIf->encapsulatingSkfd = encapsulatingSkfd;
523 newIf->listeningSkfd = listeningSkfd;
524 newIf->electionSkfd = electionSkfd;
525 newIf->helloSkfd = helloSkfd;
526 memcpy(newIf->macAddr, ifr.ifr_hwaddr.sa_data, IFHWADDRLEN);
527 memcpy(newIf->ifName, ifName, IFNAMSIZ);
528 newIf->olsrIntf = olsrIntf;
529 newIf->isActive = 1; //as default the interface is active
530 if (olsrIntf != NULL) {
531 /* For an OLSR-interface, copy the interface address and broadcast
532 * address from the OLSR interface object. Downcast to correct sockaddr
534 newIf->intAddr.v4 = olsrIntf->int_addr.sin_addr;
535 newIf->broadAddr.v4 = olsrIntf->int_broadaddr.sin_addr;
537 /* For a non-OLSR interface, retrieve the IP address ourselves */
538 memset(&ifr, 0, sizeof(struct ifreq));
539 strncpy(ifr.ifr_name, ifName, IFNAMSIZ - 1);
540 ifr.ifr_name[IFNAMSIZ - 1] = '\0'; /* Ensures null termination */
541 if (ioctl(ioctlSkfd, SIOCGIFADDR, &ifr) < 0) {
542 BmfPError("ioctl(SIOCGIFADDR) error for interface \"%s\"", ifName);
544 newIf->intAddr.v4.s_addr = inet_addr("0.0.0.0");
546 /* Downcast to correct sockaddr subtype */
547 struct sockaddr* ifra = &ifr.ifr_addr;
548 newIf->intAddr.v4 = ((struct sockaddr_in *)ARM_NOWARN_ALIGN(ifra))->sin_addr;
551 /* For a non-OLSR interface, retrieve the IP broadcast address ourselves */
552 memset(&ifr, 0, sizeof(struct ifreq));
553 strncpy(ifr.ifr_name, ifName, IFNAMSIZ - 1);
554 ifr.ifr_name[IFNAMSIZ - 1] = '\0'; /* Ensures null termination */
555 if (ioctl(ioctlSkfd, SIOCGIFBRDADDR, &ifr) < 0) {
556 BmfPError("ioctl(SIOCGIFBRDADDR) error for interface \"%s\"", ifName);
558 newIf->broadAddr.v4.s_addr = inet_addr("0.0.0.0");
560 /* Downcast to correct sockaddr subtype */
561 struct sockaddr* ifrb = &ifr.ifr_broadaddr;
562 newIf->broadAddr.v4 = ((struct sockaddr_in *)ARM_NOWARN_ALIGN(ifrb))->sin_addr;
566 /* Initialize fragment history table */
567 //memset(&newIf->fragmentHistory, 0, sizeof(newIf->fragmentHistory));
568 //newIf->nextFragmentHistoryEntry = 0;
571 //newIf->nBmfPacketsRx = 0;
572 //newIf->nBmfPacketsRxDup = 0;
573 //newIf->nBmfPacketsTx = 0;
575 /* Add new TBmfInterface object to global list. OLSR interfaces are
576 * added at the front of the list, non-OLSR interfaces at the back. */
577 if (BmfInterfaces == NULL) {
578 /* First TBmfInterface object in list */
580 BmfInterfaces = newIf;
581 LastBmfInterface = newIf;
582 } else if (olsrIntf != NULL) {
583 /* Add new TBmfInterface object at front of list */
584 newIf->next = BmfInterfaces;
585 BmfInterfaces = newIf;
587 /* Add new TBmfInterface object at back of list */
589 LastBmfInterface->next = newIf;
590 LastBmfInterface = newIf;
595 // "%s: opened %d socket%s on %s interface \"%s\"\n",
596 // PLUGIN_NAME_SHORT,
598 // nOpened == 1 ? "" : "s",
599 // olsrIntf != NULL ? "OLSR" : "non-OLSR",
603 } /* CreateInterface */
605 /* -------------------------------------------------------------------------
606 * Function : CreateBmfNetworkInterfaces
607 * Description: Create a list of TBmfInterface objects, one for each network
608 * interface on which BMF runs
609 * Input : skipThisIntf - network interface to skip, if seen
611 * Return : fail (-1) or success (0)
613 * ------------------------------------------------------------------------- */
615 CreateBmfNetworkInterfaces(struct interface_olsr *skipThisIntf)
622 int nOpenedSockets = 0;
624 /* Clear input descriptor set */
627 skfd = socket(PF_INET, SOCK_DGRAM, 0);
629 BmfPError("no inet socket available to retrieve interface list");
633 /* Retrieve the network interface configuration list */
636 ifc.ifc_len = sizeof(struct ifreq) * numreqs;
637 ifc.ifc_buf = realloc(ifc.ifc_buf, ifc.ifc_len);
639 if (ioctl(skfd, SIOCGIFCONF, &ifc) < 0) {
640 BmfPError("ioctl(SIOCGIFCONF) error");
646 if ((unsigned)ifc.ifc_len == sizeof(struct ifreq) * numreqs) {
647 /* Assume it overflowed; double the space and try again */
649 assert(numreqs < 1024);
650 continue; /* for (;;) */
652 break; /* for (;;) */
657 /* For each item in the interface configuration list... */
659 for (n = ifc.ifc_len / sizeof(struct ifreq); --n >= 0; ifr++) {
660 struct interface_olsr *olsrIntf;
661 union olsr_ip_addr ipAddr;
663 /* Skip the BMF network interface itself */
664 //if (strncmp(ifr->ifr_name, EtherTunTapIfName, IFNAMSIZ) == 0)
666 // continue; /* for (n = ...) */
669 /* ...find the OLSR interface structure, if any */
671 struct sockaddr* ifra = &ifr->ifr_addr;
672 ipAddr.v4 = ((struct sockaddr_in *)ARM_NOWARN_ALIGN(ifra))->sin_addr;
674 olsrIntf = if_ifwithaddr(&ipAddr);
676 if (skipThisIntf != NULL && olsrIntf == skipThisIntf) {
677 continue; /* for (n = ...) */
680 if (olsrIntf == NULL && !IsNonOlsrBmfIf(ifr->ifr_name)) {
681 /* Interface is neither OLSR interface, nor specified as non-OLSR BMF
682 * interface in the BMF plugin parameter list */
683 continue; /* for (n = ...) */
686 if (!IsNonOlsrBmfIf(ifr->ifr_name)) {
687 //If the interface is not specified in the configuration file then go ahead
688 continue; /* for (n = ...) */
690 //TODO: asser if->ifr_name is not talking OLSR
691 //nOpenedSockets += CreateInterface(ifr->ifr_name, olsrIntf);
692 nOpenedSockets += CreateInterface(ifr->ifr_name, NULL);
694 } /* for (n = ...) */
698 if (BmfInterfaces == NULL) {
699 //OLSR_PRINTF(1, "%s: could not initialize any network interface\n", PLUGIN_NAME);
701 //OLSR_PRINTF(1, "%s: opened %d sockets\n", PLUGIN_NAME, nOpenedSockets);
704 } /* CreateBmfNetworkInterfaces */
706 /* -------------------------------------------------------------------------
707 * Function : AddInterface
708 * Description: Add an OLSR-enabled network interface to the list of BMF-enabled
710 * Input : newIntf - network interface to add
714 * ------------------------------------------------------------------------- */
716 AddInterface(struct interface_olsr *newIntf)
720 assert(newIntf != NULL);
722 /* nOpened = */ (void)CreateInterface(newIntf->int_name, newIntf);
724 //OLSR_PRINTF(1, "%s: opened %d sockets\n", PLUGIN_NAME, nOpened);
727 /* -------------------------------------------------------------------------
728 * Function : CloseBmfNetworkInterfaces
729 * Description: Closes every socket on each network interface used by BMF
735 * - the local EtherTunTap interface (e.g. "tun0" or "tap0")
736 * - for each BMF-enabled interface, the socket used for
737 * capturing multicast packets
738 * - for each OLSR-enabled interface, the socket used for
739 * encapsulating packets
740 * Also restores the network state to the situation before BMF
742 * ------------------------------------------------------------------------- */
744 CloseBmfNetworkInterfaces(void)
747 u_int32_t totalOlsrBmfPacketsRx = 0;
748 u_int32_t totalOlsrBmfPacketsRxDup = 0;
749 u_int32_t totalOlsrBmfPacketsTx = 0;
750 u_int32_t totalNonOlsrBmfPacketsRx = 0;
751 u_int32_t totalNonOlsrBmfPacketsRxDup = 0;
752 u_int32_t totalNonOlsrBmfPacketsTx = 0;
754 /* Close all opened sockets */
755 struct TBmfInterface *nextBmfIf = BmfInterfaces;
756 while (nextBmfIf != NULL) {
757 struct TBmfInterface *bmfIf = nextBmfIf;
758 nextBmfIf = bmfIf->next;
760 if (bmfIf->capturingSkfd >= 0) {
761 close(bmfIf->capturingSkfd);
764 if (bmfIf->encapsulatingSkfd >= 0) {
765 close(bmfIf->encapsulatingSkfd);
768 if (bmfIf->electionSkfd >= 0) {
769 close(bmfIf->electionSkfd);
772 if (bmfIf->helloSkfd >= 0) {
773 close(bmfIf->helloSkfd);
778 // "%s: %s interface \"%s\": RX pkts %u (%u dups); TX pkts %u\n",
779 // PLUGIN_NAME_SHORT,
780 // bmfIf->olsrIntf != NULL ? "OLSR" : "non-OLSR",
782 // bmfIf->nBmfPacketsRx,
783 // bmfIf->nBmfPacketsRxDup,
784 // bmfIf->nBmfPacketsTx);
788 // "%s: closed %s interface \"%s\"\n",
789 // PLUGIN_NAME_SHORT,
790 // bmfIf->olsrIntf != NULL ? "OLSR" : "non-OLSR",
794 if (bmfIf->olsrIntf != NULL) {
795 totalOlsrBmfPacketsRx += bmfIf->nBmfPacketsRx;
796 totalOlsrBmfPacketsRxDup += bmfIf->nBmfPacketsRxDup;
797 totalOlsrBmfPacketsTx += bmfIf->nBmfPacketsTx;
799 totalNonOlsrBmfPacketsRx += bmfIf->nBmfPacketsRx;
800 totalNonOlsrBmfPacketsRxDup += bmfIf->nBmfPacketsRxDup;
801 totalNonOlsrBmfPacketsTx += bmfIf->nBmfPacketsTx;
807 BmfInterfaces = NULL;
809 //OLSR_PRINTF(1, "%s: closed %d sockets\n", PLUGIN_NAME_SHORT, nClosed);
811 } /* CloseBmfNetworkInterfaces */
813 #define MAX_NON_OLSR_IFS 32
814 static char NonOlsrIfNames[MAX_NON_OLSR_IFS][IFNAMSIZ];
815 static int nNonOlsrIfs = 0;
816 /* -------------------------------------------------------------------------
817 * Function : AddNonOlsrBmfIf
818 * Description: Add an non-OLSR enabled network interface to the list of BMF-enabled
820 * Input : ifName - network interface (e.g. "eth0")
824 * Return : success (0) or fail (1)
825 * Data Used : NonOlsrIfNames
826 * ------------------------------------------------------------------------- */
828 AddNonOlsrBmfIf(const char *ifName, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused)))
830 assert(ifName != NULL);
832 if (nNonOlsrIfs >= MAX_NON_OLSR_IFS) {
835 // "%s: too many non-OLSR interfaces specified, maximum is %d\n",
837 // MAX_NON_OLSR_IFS);
841 strncpy(NonOlsrIfNames[nNonOlsrIfs], ifName, IFNAMSIZ - 1);
842 NonOlsrIfNames[nNonOlsrIfs][IFNAMSIZ - 1] = '\0'; /* Ensures null termination */
845 } /* AddNonOlsrBmfIf */
849 set_TTL_Check(const char *TTL_Check, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused)))
851 assert(TTL_Check!= NULL);
852 set_plugin_boolean(TTL_Check, &my_TTL_Check, addon);
854 } /* Set TTL Check */
857 set_MDNS_TTL(const char *MDNS_TTL, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused)))
859 assert(MDNS_TTL!= NULL);
860 my_MDNS_TTL = atoi(MDNS_TTL);
863 /* -------------------------------------------------------------------------
864 * Function : IsNonOlsrBmfIf
865 * Description: Checks if a network interface is OLSR-enabled
866 * Input : ifName - network interface (e.g. "eth0")
868 * Return : true (1) or false (0)
869 * Data Used : NonOlsrIfNames
870 * ------------------------------------------------------------------------- */
872 IsNonOlsrBmfIf(const char *ifName)
876 assert(ifName != NULL);
878 for (i = 0; i < nNonOlsrIfs; i++) {
879 if (strncmp(NonOlsrIfNames[i], ifName, IFNAMSIZ) == 0)
883 } /* IsNonOlsrBmfIf */