3 * The olsr.org Optimized Link-State Routing daemon(olsrd)
4 * Copyright (c) 2004, Andreas Tonnesen(andreto@olsr.org)
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * * Neither the name of olsr.org, olsrd nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
34 * Visit http://www.olsr.org for more information.
36 * If you find this software useful feel free to make a donation
37 * to the project. For more information see the website or contact
38 * the copyright holders.
42 #if defined __FreeBSD_kernel__
44 #endif /* defined __FreeBSD_kernel__ */
46 /* comment: we need this otherwise it does not include the proper files to find IPv6_PKTINFO */
47 #define __APPLE_USE_RFC_2292
50 #include "../net_os.h"
51 #include "../ipcalc.h"
52 #include "../parser.h" /* dnc: needed for call to packet_parser() */
53 #include "../olsr_protocol.h"
54 #include "../olsr_cfg.h"
57 #include <sys/types.h>
58 #include <sys/socket.h>
63 #include <sys/ioctl.h>
66 #include <netinet/in.h>
71 #include "wrn/coreip/netinet6/in6_var.h"
73 #include <sys/socket.h>
74 #include "wrn/coreip/net/ifaddrs.h"
75 #include <selectLib.h>
77 #define syslog(a, b) fdprintf(a, b);
78 #else /* _WRS_KERNEL */
79 #include <sys/param.h>
80 #endif /* _WRS_KERNEL */
83 #include <net/if_ether.h>
84 #include <netinet6/in6_var.h> /* For struct in6_ifreq */
85 #include <net80211/ieee80211_ioctl.h>
87 #endif /* __NetBSD__ */
90 #include <netinet/if_ether.h>
91 #include <netinet/in_systm.h>
92 #include <netinet/ip.h>
93 #include <netinet/ip_icmp.h>
94 #include <netinet/icmp_var.h>
95 #include <netinet/icmp6.h>
96 #include <netinet6/in6_var.h> /* For struct in6_ifreq */
99 #include <net80211/ieee80211.h>
100 #include <net80211/ieee80211_ioctl.h>
101 #endif /* __OpenBSD__ */
103 #if defined __FreeBSD__ || defined __FreeBSD_kernel__
104 #include <net/if_var.h>
105 #include <net/ethernet.h>
106 #include <netinet/in_var.h>
108 #ifndef FBSD_NO_80211
109 #include <net80211/ieee80211.h>
110 #include <net80211/ieee80211_ioctl.h>
111 #endif /* FBSD_NO_80211 */
112 #endif /* defined __FreeBSD__ || defined __FreeBSD_kernel__ */
116 #include <net/if_var.h>
117 #include <net/ethernet.h>
118 #include <netinet/in_var.h>
119 #endif /* __APPLE__ */
121 #include <net/if_dl.h>
126 #include <sys/sysctl.h>
128 static int ignore_redir;
129 static int send_redir;
133 set_sysctl_int(const char *name, int new)
136 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__APPLE__) || defined(__OpenBSD__) || defined(__NetBSD__)
137 size_t len = sizeof(old);
138 #else /* defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__APPLE__) || defined(__OpenBSD__) || defined(__NetBSD__) */
139 unsigned int len = sizeof(old);
140 #endif /* defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__APPLE__) || defined(__OpenBSD__) || defined(__NetBSD__) */
145 /* Set net.inet.ip.forwarding by default. */
149 mib[3] = IPCTL_FORWARDING;
151 if (!strcmp(name, "net.inet6.ip6.forwarding")) {
153 mib[2] = IPPROTO_IPV6;
154 } else if (!strcmp(name, "net.inet.icmp.rediraccept")) {
155 mib[2] = IPPROTO_ICMP;
156 mib[3] = ICMPCTL_REDIRACCEPT;
157 } else if (!strcmp(name, "net.inet6.icmp6.rediraccept")) {
158 mib[2] = IPPROTO_ICMPV6;
159 mib[3] = ICMPV6CTL_REDIRACCEPT;
160 } else if (!strcmp(name, "net.inet.ip.redirect")) {
161 mib[3] = IPCTL_SENDREDIRECTS;
162 } else if (!strcmp(name, "net.inet6.ip6.redirect")) {
164 mib[2] = IPPROTO_IPV6;
165 mib[3] = IPCTL_SENDREDIRECTS;
168 if (sysctl(mib, 4, &old, &len, &new, sizeof(new)) < 0)
170 #else /* __OpenBSD__ */
172 if (sysctlbyname((const char *)name, &old, &len, &new, sizeof(new)) < 0)
174 #endif /* __OpenBSD__ */
180 net_os_set_global_ifoptions(void) {
181 const char *name = olsr_cnf->ip_version == AF_INET ? "net.inet.ip.forwarding" : "net.inet6.ip6.forwarding";
183 gateway = set_sysctl_int(name, 1);
185 fprintf(stderr, "Cannot enable IP forwarding. Please enable IP forwarding manually." " Continuing in 3 seconds...\n");
186 olsr_startup_sleep(3);
189 /* do not accept ICMP redirects */
191 #if defined(__OpenBSD__) || defined(__NetBSD__)
192 if (olsr_cnf->ip_version == AF_INET)
193 name = "net.inet.icmp.rediraccept";
195 name = "net.inet6.icmp6.rediraccept";
197 ignore_redir = set_sysctl_int(name, 0);
198 #elif defined __FreeBSD__ || defined __FreeBSD_kernel__ || defined __APPLE__
199 if (olsr_cnf->ip_version == AF_INET) {
200 name = "net.inet.icmp.drop_redirect";
201 ignore_redir = set_sysctl_int(name, 1);
203 name = "net.inet6.icmp6.rediraccept";
204 ignore_redir = set_sysctl_int(name, 0);
206 #else /* defined __FreeBSD__ || defined __FreeBSD_kernel__ || defined __APPLE__ */
207 if (olsr_cnf->ip_version == AF_INET)
208 name = "net.inet.icmp.drop_redirect";
210 name = "net.inet6.icmp6.drop_redirect";
212 ignore_redir = set_sysctl_int(name, 1);
213 #endif /* defined __FreeBSD__ || defined __FreeBSD_kernel__ || defined __APPLE__ */
215 if (ignore_redir < 0) {
217 "Cannot disable incoming ICMP redirect messages. " "Please disable them manually. Continuing in 3 seconds...\n");
218 olsr_startup_sleep(3);
221 /* do not send ICMP redirects */
223 if (olsr_cnf->ip_version == AF_INET)
224 name = "net.inet.ip.redirect";
226 name = "net.inet6.ip6.redirect";
228 send_redir = set_sysctl_int(name, 0);
229 if (send_redir < 0) {
231 "Cannot disable outgoing ICMP redirect messages. " "Please disable them manually. Continuing in 3 seconds...\n");
232 olsr_startup_sleep(3);
236 int net_os_set_ifoptions(const char *if_name __attribute__ ((unused)), struct interface *iface __attribute__ ((unused))) {
241 net_os_restore_ifoptions(void) {
242 /* reset IP forwarding */
243 const char *name = olsr_cnf->ip_version == AF_INET ? "net.inet.ip.forwarding" : "net.inet6.ip6.forwarding";
245 set_sysctl_int(name, gateway);
247 /* reset incoming ICMP redirects */
250 name = olsr_cnf->ip_version == AF_INET ? "net.inet.icmp.rediraccept" : "net.inet6.icmp6.rediraccept";
251 #elif defined __FreeBSD__ || defined __FreeBSD_kernel__ || defined __APPLE__
252 name = olsr_cnf->ip_version == AF_INET ? "net.inet.icmp.drop_redirect" : "net.inet6.icmp6.rediraccept";
253 #else /* defined __FreeBSD__ || defined __FreeBSD_kernel__ || defined __APPLE__ */
254 name = olsr_cnf->ip_version == AF_INET ? "net.inet.icmp.drop_redirect" : "net.inet6.icmp6.drop_redirect";
255 #endif /* defined __FreeBSD__ || defined __FreeBSD_kernel__ || defined __APPLE__ */
256 set_sysctl_int(name, ignore_redir);
258 /* reset outgoing ICMP redirects */
259 name = olsr_cnf->ip_version == AF_INET ? "net.inet.ip.redirect" : "net.inet6.ip6.redirect";
260 set_sysctl_int(name, send_redir);
265 *Creates a nonblocking broadcast socket.
266 *@param sa sockaddr struct. Used for bind(2).
267 *@return the FD of the socket or -1 on error.
270 gethemusocket(struct sockaddr_in *pin)
274 OLSR_PRINTF(1, " Connecting to switch daemon port 10150...");
276 if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
278 syslog(LOG_ERR, "hcsocket: %m");
282 if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0) {
283 perror("SO_REUSEADDR failed");
287 /* connect to PORT on HOST */
288 if (connect(sock, (struct sockaddr *)pin, sizeof(*pin)) < 0) {
290 fprintf(stderr, "Error connecting %d - %s\n", errno, strerror(errno));
291 printf("connection refused\n");
298 /* Keep TCP socket blocking */
303 getsocket(int bufspace, struct interface *ifp __attribute__ ((unused)))
305 struct sockaddr_in sin;
307 int sock = socket(AF_INET, SOCK_DGRAM, 0);
310 syslog(LOG_ERR, "socket: %m");
315 if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char *)&on, sizeof(on)) < 0) {
316 perror("setsockopt");
317 syslog(LOG_ERR, "setsockopt SO_BROADCAST: %m");
322 if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0) {
323 perror("SO_REUSEADDR failed");
328 if (setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, (char *)&on, sizeof(on)) < 0) {
329 perror("SO_REUSEPORT failed");
334 if (setsockopt(sock, IPPROTO_IP, IP_RECVIF, (char *)&on, sizeof(on)) < 0) {
335 perror("IP_RECVIF failed");
341 for (on = bufspace;; on -= 1024) {
342 if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char *)&on, sizeof(on)) == 0)
344 if (on <= 8 * 1024) {
345 perror("setsockopt");
346 syslog(LOG_ERR, "setsockopt SO_RCVBUF: %m");
352 memset(&sin, 0, sizeof(sin));
353 sin.sin_family = AF_INET;
354 sin.sin_port = htons(olsr_cnf->olsrport);
357 sin.sin_addr.s_addr = ifp->int_addr.sin_addr.s_addr;
360 if (bind(sock, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
362 syslog(LOG_ERR, "bind: %m");
367 on = fcntl(sock, F_GETFL);
369 syslog(LOG_ERR, "fcntl (F_GETFL): %m\n");
371 if (fcntl(sock, F_SETFL, on | O_NONBLOCK) == -1) {
372 syslog(LOG_ERR, "fcntl O_NONBLOCK: %m\n");
379 getsocket6(int bufspace, struct interface *ifp __attribute__ ((unused)))
381 struct sockaddr_in6 sin;
383 int sock = socket(AF_INET6, SOCK_DGRAM, 0);
387 syslog(LOG_ERR, "socket: %m");
392 for (on = bufspace;; on -= 1024) {
393 if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char *)&on, sizeof(on)) == 0)
395 if (on <= 8 * 1024) {
396 perror("setsockopt");
397 syslog(LOG_ERR, "setsockopt SO_RCVBUF: %m");
403 if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0) {
404 perror("SO_REUSEADDR failed");
409 if (setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, (char *)&on, sizeof(on)) < 0) {
410 perror("SO_REUSEPORT failed");
414 #ifdef IPV6_RECVPKTINFO
415 if (setsockopt(sock, IPPROTO_IPV6, IPV6_RECVPKTINFO, (char *)&on, sizeof(on)) < 0) {
416 perror("IPV6_RECVPKTINFO failed");
420 #elif defined IPV6_PKTINFO
421 if (setsockopt(sock, IPPROTO_IPV6, IPV6_PKTINFO, (char *)&on, sizeof(on)) < 0) {
422 perror("IPV6_PKTINFO failed");
426 #endif /* defined IPV6_PKTINFO */
428 memset(&sin, 0, sizeof(sin));
429 sin.sin6_family = AF_INET6;
430 sin.sin6_port = htons(olsr_cnf->olsrport);
433 memcpy(&sin.sin6_addr, &ifp->int6_addr.sin6_addr, sizeof(struct in6_addr));
436 if (bind(sock, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
438 syslog(LOG_ERR, "bind: %m");
443 on = fcntl(sock, F_GETFL);
445 syslog(LOG_ERR, "fcntl (F_GETFL): %m\n");
447 if (fcntl(sock, F_SETFL, on | O_NONBLOCK) == -1) {
448 syslog(LOG_ERR, "fcntl O_NONBLOCK: %m\n");
455 join_mcast(struct interface *ifs, int sock)
457 /* See netinet6/in6.h */
458 struct ipaddr_str addrstr;
459 struct ipv6_mreq mcastreq;
460 #ifdef IPV6_USE_MIN_MTU
462 #endif /* IPV6_USE_MIN_MTU */
464 mcastreq.ipv6mr_multiaddr = ifs->int6_multaddr.sin6_addr;
465 mcastreq.ipv6mr_interface = ifs->if_index;
467 if (ifs->olsr_socket == sock) {
469 OLSR_PRINTF(3, "Interface %s joining multicast %s...", ifs->int_name,
470 olsr_ip_to_string(&addrstr, (union olsr_ip_addr *)&ifs->int6_multaddr.sin6_addr));
473 #ifdef IPV6_JOIN_GROUP
474 /* Join receiver group */
475 if (setsockopt(sock, IPPROTO_IPV6, IPV6_JOIN_GROUP, (char *)&mcastreq, sizeof(struct ipv6_mreq)) < 0)
476 #else /* IPV6_JOIN_GROUP */ /* rfc 2133, obsoleted */
477 /* Join receiver group */
478 if (setsockopt(sock, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, (char *)&mcastreq, sizeof(struct ipv6_mreq)) < 0)
479 #endif /* IPV6_JOIN_GROUP */
481 perror("Join multicast send");
486 if (setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_IF, (char *)&mcastreq.ipv6mr_interface, sizeof(mcastreq.ipv6mr_interface)) < 0) {
487 perror("Set multicast if");
491 #ifdef IPV6_USE_MIN_MTU
493 * This allow multicast packets to use the full interface MTU and not
494 * be limited to 1280 bytes.
497 if (setsockopt(sock, IPPROTO_IPV6, IPV6_USE_MIN_MTU, (char *)&on, sizeof(on)) < 0) {
498 perror("IPV6_USE_MIN_MTU failed");
502 #endif /* IPV6_USE_MIN_MTU */
504 OLSR_PRINTF(3, "OK\n");
509 get_ipv6_address(char *ifname, struct sockaddr_in6 *saddr6, struct olsr_ip_prefix *prefix)
511 struct ifaddrs *ifap, *ifa;
512 const struct sockaddr_in6 *sin6 = NULL;
513 const union olsr_ip_addr *tmp_ip;
514 struct in6_ifreq ifr6;
519 if (getifaddrs(&ifap) != 0) {
520 OLSR_PRINTF(3, "get_ipv6_address: getifaddrs() failed.\n");
524 for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
525 if ((ifa->ifa_addr->sa_family == AF_INET6) && (strcmp(ifa->ifa_name, ifname) == 0)) {
526 sin6 = (const struct sockaddr_in6 *)(ifa->ifa_addr);
527 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))
529 strscpy(ifr6.ifr_name, ifname, sizeof(ifr6.ifr_name));
530 if ((s6 = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
531 OLSR_PRINTF(3, "socket(AF_INET6,SOCK_DGRAM)");
534 ifr6.ifr_addr = *sin6;
535 if (ioctl(s6, SIOCGIFAFLAG_IN6, &ifr6) < 0) {
536 OLSR_PRINTF(3, "ioctl(SIOCGIFAFLAG_IN6)");
541 flags6 = ifr6.ifr_ifru.ifru_flags6;
542 if ((flags6 & IN6_IFF_ANYCAST) != 0)
545 tmp_ip = (const union olsr_ip_addr *) &sin6->sin6_addr;
546 if ((prefix == NULL && !IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))
547 || (prefix != NULL && ip_in_net(tmp_ip, prefix))) {
548 memcpy(&saddr6->sin6_addr, &sin6->sin6_addr, sizeof(struct in6_addr));
562 * Wrapper for sendto(2)
566 static u_int16_t ip_id = 0;
570 olsr_sendto(int s, const void *buf, size_t len, int flags __attribute__ ((unused)), const struct sockaddr *to, socklen_t tolen)
576 char errbuf[LIBNET_ERRBUF_SIZE];
577 libnet_ptag_t udp_tag, ip_tag, ether_tag;
578 unsigned char enet_broadcast[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
580 struct sockaddr_in *to_in = (struct sockaddr_in *)to;
582 struct interface *iface;
584 udp_tag = ip_tag = ether_tag = 0;
585 destip = to_in->sin_addr.s_addr;
586 iface = if_ifwithsock(s);
588 /* initialize libnet */
589 context = libnet_init(LIBNET_LINK, iface->int_name, errbuf);
590 if (context == NULL) {
591 OLSR_PRINTF(1, "libnet init: %s\n", libnet_geterror(context));
595 /* initialize IP ID field if necessary */
597 ip_id = (u_int16_t) (arc4random() & 0xffff);
600 udp_tag = libnet_build_udp(olsr_cnf->olsrport, /* src port */
601 olsr_cnf->olsrport, /* dest port */
602 LIBNET_UDP_H + len, /* length */
605 len, /* payload size */
606 context, /* context */
607 udp_tag); /* pblock */
609 OLSR_PRINTF(1, "libnet UDP header: %s\n", libnet_geterror(context));
613 ip_tag = libnet_build_ipv4(LIBNET_IPV4_H + LIBNET_UDP_H + len, /* len */
618 IPPROTO_UDP, /* protocol */
620 libnet_get_ipaddr4(context), /* src IP */
621 destip, /* dest IP */
624 context, /* context */
625 ip_tag); /* pblock */
627 OLSR_PRINTF(1, "libnet IP header: %s\n", libnet_geterror(context));
631 ether_tag = libnet_build_ethernet(enet_broadcast, /* ethernet dest */
632 libnet_get_hwaddr(context), /* ethernet source */
633 ETHERTYPE_IP, /* protocol type */
635 0, /* payload size */
636 context, /* libnet handle */
637 ether_tag); /* pblock tag */
638 if (ether_tag == -1) {
639 OLSR_PRINTF(1, "libnet ethernet header: %s\n", libnet_geterror(context));
643 status = libnet_write(context);
645 OLSR_PRINTF(1, "libnet packet write: %s\n", libnet_geterror(context));
649 libnet_destroy(context);
654 return sendto(s, buf, len, flags, (const struct sockaddr *)to, tolen);
659 * Wrapper for recvfrom(2)
663 olsr_recvfrom(int s, void *buf, size_t len, int flags __attribute__ ((unused)), struct sockaddr *from, socklen_t * fromlen)
669 unsigned char chdr[4096];
672 struct sockaddr_dl *sdl;
673 struct sockaddr_in *sin = (struct sockaddr_in *)from;
674 struct sockaddr_in6 *sin6;
675 struct in6_addr *iaddr6;
676 struct in6_pktinfo *pkti;
677 struct interface *ifc;
678 char addrstr[INET6_ADDRSTRLEN];
679 char iname[IFNAMSIZ];
682 memset(&mhdr, 0, sizeof(mhdr));
683 memset(&iov, 0, sizeof(iov));
685 mhdr.msg_name = (caddr_t) from;
686 mhdr.msg_namelen = *fromlen;
689 mhdr.msg_control = (caddr_t) & cmu;
690 mhdr.msg_controllen = sizeof(cmu);
695 count = recvmsg(s, &mhdr, MSG_DONTWAIT);
700 /* this needs to get communicated back to caller */
701 *fromlen = mhdr.msg_namelen;
702 if (olsr_cnf->ip_version == AF_INET6) {
703 for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(&mhdr); cm; cm = (struct cmsghdr *)CMSG_NXTHDR(&mhdr, cm)) {
704 if (cm->cmsg_level == IPPROTO_IPV6 && cm->cmsg_type == IPV6_PKTINFO) {
705 pkti = (struct in6_pktinfo *)CMSG_DATA(cm);
706 iaddr6 = &pkti->ipi6_addr;
707 if_indextoname(pkti->ipi6_ifindex, iname);
712 sdl = (struct sockaddr_dl *)CMSG_DATA(cm);
713 memset(iname, 0, sizeof(iname));
714 memcpy(iname, sdl->sdl_data, sdl->sdl_nlen);
717 ifc = if_ifwithsock(s);
719 sin6 = (struct sockaddr_in6 *)from;
720 OLSR_PRINTF(4, "%d bytes from %s, socket associated %s really received on %s\n", count,
721 inet_ntop(olsr_cnf->ip_version, olsr_cnf->ip_version == AF_INET6 ? (char *)&sin6->sin6_addr : (char *)&sin->sin_addr,
722 addrstr, sizeof(addrstr)), ifc->int_name, iname);
725 if (strcmp(ifc->int_name, iname) != 0) {
728 #endif /* __NetBSD__ */
734 * Wrapper for select(2)
738 olsr_select(int nfds, fd_set * readfds, fd_set * writefds, fd_set * exceptfds, struct timeval *timeout)
740 return select(nfds, readfds, writefds, exceptfds, timeout);
744 check_wireless_interface(char *ifname)
746 #if (defined __FreeBSD__ || defined __FreeBSD_kernel__ ) && !defined FBSD_NO_80211
748 /* From FreeBSD ifconfig/ifieee80211.c ieee80211_status() */
749 struct ieee80211req ireq;
752 memset(&ireq, 0, sizeof(ireq));
753 strscpy(ireq.i_name, ifname, sizeof(ireq.i_name));
755 ireq.i_type = IEEE80211_IOC_SSID;
757 return (ioctl(olsr_cnf->ioctl_s, SIOCG80211, &ireq) >= 0) ? 1 : 0;
758 #elif defined __OpenBSD__
759 struct ieee80211_nodereq nr;
760 bzero(&nr, sizeof(nr));
761 strscpy(nr.nr_ifname, ifname, sizeof(nr.nr_ifname));
762 return (ioctl(olsr_cnf->ioctl_s, SIOCG80211FLAGS, &nr) >= 0) ? 1 : 0;
763 #elif defined __NetBSD__
765 struct ieee80211_nwid data;
768 memset(&ireq, 0, sizeof(ireq));
769 strscpy(ireq.ifr_name, ifname, sizeof(ireq.ifr_name));
770 ireq.ifr_data = &data;
771 ret = ioctl(olsr_cnf->ioctl_s, SIOCG80211NWID, &ireq);
775 #else /* defined __NetBSD__ */
776 ifname = NULL; /* squelsh compiler warning */
778 #endif /* defined __NetBSD__ */
781 #include <sys/sockio.h>
784 calculate_if_metric(char *ifname)
786 if (check_wireless_interface(ifname)) {
791 return WEIGHT_ETHERNET_DEFAULT;
798 * indent-tabs-mode: nil