static void link_update_quality_metric(const char *if_name) { struct ifreq ifr; int quality = IFNET_LQM_THRESH_UNKNOWN; int sock; sock = dgram_socket(AF_INET); if (sock == -1) { SCLog(TRUE, LOG_NOTICE, CFSTR("socket_get_link_quality: socket open failed, %s"), strerror(errno)); goto done; } bzero((char *)&ifr, sizeof(ifr)); snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s", if_name); if (ioctl(sock, SIOCGIFLINKQUALITYMETRIC, (caddr_t)&ifr) != -1) { quality = ifr.ifr_link_quality_metric; } done: interface_update_quality_metric(if_name, quality); if (sock != -1) close(sock); return; }
/* * Setup to accept new incoming connections */ static void bsd_accept( const struct security_driver * driver, char *(*conf_fn)(char *, void *), int in, int out, void (*fn)(security_handle_t *, pkt_t *), void *datap) { struct stat sbuf; assert(in >= 0 && out >= 0); assert(fn != NULL); (void)out; /* Quiet unused parameter warning */ (void)driver; /* Quiet unused parameter warning */ (void)conf_fn; (void)datap; /* * We assume in and out point to the same socket, and just use * in. */ dgram_socket(&netfd4.dgram, in); dgram_socket(&netfd6.dgram, in); /* * Assign the function and return. When they call recvpkt later, * the recvpkt callback will call this function when it discovers * new incoming connections */ netfd4.accept_fn = fn; netfd4.recv_security_ok = &bsd_recv_security_ok; netfd4.prefix_packet = &bsd_prefix_packet; netfd4.driver = &bsd_security_driver; /* check if in is a socket */ if (fstat(in, &sbuf) == -1) { g_warning("Can't fstat file descriptor; cannot use BSD auth"); } else if (S_ISSOCK(sbuf.st_mode)) { udp_addref(&netfd4, &udp_netfd_read_callback); } else { g_warning("input file descriptor is not a socket; cannot use BSD auth"); } }
static void mark_if_down(char * name) { int s = dgram_socket(AF_INET); if (s < 0) return; ifflags_clear(s, name, IFF_UP); close(s); }
static void mark_if_up(char * name) { int s = dgram_socket(AF_INET); if (s == -1) return; ifflags_set(s, name, IFF_UP); close(s); }
/* * Setup to accept new incoming connections */ static void bsdudp_accept( const struct security_driver *driver, char * (*conf_fn)(char *, void *), int in, int out, void (*fn)(security_handle_t *, pkt_t *), void *datap) { (void)driver; /* Quiet unused parameter warning */ (void)out; /* Quiet unused parameter warning */ (void)conf_fn; (void)datap; assert(in >= 0 && out >= 0); assert(fn != NULL); /* * We assume in and out point to the same socket, and just use * in. */ dgram_socket(&netfd4.dgram, in); dgram_socket(&netfd6.dgram, in); /* * Assign the function and return. When they call recvpkt later, * the recvpkt callback will call this function when it discovers * new incoming connections */ netfd4.accept_fn = fn; netfd4.recv_security_ok = &bsd_recv_security_ok; netfd4.prefix_packet = &bsd_prefix_packet; netfd4.need_priv_port = 1; netfd4.driver = &bsdudp_security_driver; udp_addref(&netfd4, &udp_netfd_read_callback); }
__private_extern__ void link_update_status(const char *if_name, boolean_t attach) { CFBooleanRef active = NULL; struct ifmediareq ifm; int sock; sock = dgram_socket(AF_INET); if (sock == -1) { SCLog(TRUE, LOG_NOTICE, CFSTR("link_update_status: socket open failed, %s"), strerror(errno)); goto done; } bzero((char *)&ifm, sizeof(ifm)); (void) strncpy(ifm.ifm_name, if_name, sizeof(ifm.ifm_name)); if (ioctl(sock, SIOCGIFMEDIA, (caddr_t)&ifm) == -1) { /* if media status not available for this interface */ goto done; } if (ifm.ifm_count == 0) { /* no media types */ goto done; } if (!(ifm.ifm_status & IFM_AVALID)) { /* if active bit not valid */ goto done; } if (ifm.ifm_status & IFM_ACTIVE) { active = kCFBooleanTrue; } else { active = kCFBooleanFalse; } done: interface_update_status(if_name, active, attach); if (sock != -1) close(sock); return; }
static int socket_reference_count(const char* if_name) { struct ifreq ifr; int ref = INVALID_SOCKET_REF; int s; s = dgram_socket(AF_INET); if (s == -1) { return (ref); } bzero((char *)&ifr, sizeof(ifr)); snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s", if_name); if (ioctl(s, SIOCGIFGETRTREFCNT, (caddr_t)&ifr) != -1) { ref = ifr.ifr_route_refcnt; } else { ref = INVALID_SOCKET_REF; } close(s); return (ref); }
void prime() { struct ifaddrs *ifap = NULL; struct ifaddrs *scan; int sock = -1; SCLog(_verbose, LOG_DEBUG, CFSTR("prime() called")); cache_open(); sock = dgram_socket(AF_INET); if (sock == -1) { SCLog(TRUE, LOG_ERR, CFSTR("could not get interface list, socket() failed: %s"), strerror(errno)); goto done; } if (getifaddrs(&ifap) < 0) { SCLog(TRUE, LOG_ERR, CFSTR("could not get interface info, getifaddrs() failed: %s"), strerror(errno)); goto done; } /* update list of interfaces & link status */ for (scan = ifap; scan != NULL; scan = scan->ifa_next) { if (scan->ifa_addr == NULL || scan->ifa_addr->sa_family != AF_LINK) { continue; } /* get the per-interface link/media information */ link_add(scan->ifa_name); } /* * update IPv4 network addresses already assigned to * the interfaces. */ interface_update_ipv4(ifap, NULL); /* * update IPv6 network addresses already assigned to * the interfaces. */ interface_update_ipv6(ifap, NULL); /* * update AppleTalk network addresses already assigned * to the interfaces. */ interface_update_appletalk(ifap, NULL); freeifaddrs(ifap); done: if (sock >= 0) close(sock); cache_write(store); cache_close(); return; }
__private_extern__ void interface_update_ipv6(struct ifaddrs *ifap, const char *if_name) { struct ifaddrs *ifa; struct ifaddrs *ifap_temp = NULL; CFStringRef interface; boolean_t interfaceFound = FALSE; CFStringRef key = NULL; CFMutableDictionaryRef oldIFs; CFMutableDictionaryRef newDict = NULL; CFMutableDictionaryRef newIFs; int sock = -1; oldIFs = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); newIFs = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); if (!ifap) { if (getifaddrs(&ifap_temp) == -1) { SCLog(TRUE, LOG_ERR, CFSTR("getifaddrs() failed: %s"), strerror(errno)); goto error; } ifap = ifap_temp; } for (ifa = ifap; ifa; ifa = ifa->ifa_next) { struct in6_ifreq ifr6; #define flags6 ifr6.ifr_ifru.ifru_flags6 struct sockaddr_in6 *sin6; if (ifa->ifa_addr->sa_family != AF_INET6) { continue; /* sorry, not interested */ } /* check if this is the requested interface */ if (if_name) { if (strncmp(if_name, ifa->ifa_name, IFNAMSIZ) == 0) { interfaceFound = TRUE; /* yes, this is the one I want */ } else { continue; /* sorry, not interested */ } } if (sock == -1) { sock = dgram_socket(AF_INET6); if (sock == -1) { SCLog(TRUE, LOG_NOTICE, CFSTR("interface_update_ipv6: socket open failed, %s"), strerror(errno)); goto error; } } /* get the current cache information */ interface = CFStringCreateWithCString(NULL, ifa->ifa_name, kCFStringEncodingMacRoman); key = SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL, kSCDynamicStoreDomainState, interface, kSCEntNetIPv6); CFRelease(interface); newDict = copyIF(key, oldIFs, newIFs); /* ALIGN: ifa->ifa_addr aligned (getifaddrs), cast ok. */ sin6 = (struct sockaddr_in6 *)(void *)ifa->ifa_addr; /* XXX: embedded link local addr check */ if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) || IN6_IS_ADDR_MC_LINKLOCAL(&sin6->sin6_addr)) { u_int16_t index; index = sin6->sin6_addr.s6_addr16[1]; if (index != 0) { sin6->sin6_addr.s6_addr16[1] = 0; if (sin6->sin6_scope_id == 0) { sin6->sin6_scope_id = ntohs(index); } } } bzero((char *)&ifr6, sizeof(ifr6)); strncpy(ifr6.ifr_name, ifa->ifa_name, sizeof(ifr6.ifr_name)); ifr6.ifr_addr = *sin6; if (ioctl(sock, SIOCGIFAFLAG_IN6, &ifr6) == -1) { /* if flags not available for this address */ SCLog(TRUE, (errno != EADDRNOTAVAIL) ? LOG_NOTICE : LOG_DEBUG, CFSTR("interface_update_ipv6: ioctl failed, %s"), strerror(errno)); } appendAddress (newDict, kSCPropNetIPv6Addresses, sin6); #ifdef NOTYET appendScopeID (newDict, sin6); #endif /* NOTYET */ /* ALIGN: ifa should be aligned (from getifaddrs), cast ok. * appendPrefixLen expect byte alignment */ appendPrefixLen(newDict, (struct sockaddr_in6 *)(void *)ifa->ifa_netmask); appendFlags (newDict, flags6); if (ifa->ifa_flags & IFF_POINTOPOINT && ifa->ifa_dstaddr != NULL) { struct sockaddr_in6 *dst6; /* ALIGN: ifa should be aligned (from getifaddrs), cast ok. */ dst6 = (struct sockaddr_in6 *)(void *)ifa->ifa_dstaddr; /* XXX: embedded link local addr check */ if (IN6_IS_ADDR_LINKLOCAL(&dst6->sin6_addr) || IN6_IS_ADDR_MC_LINKLOCAL(&dst6->sin6_addr)) { u_int16_t index; index = dst6->sin6_addr.s6_addr16[1]; if (index != 0) { dst6->sin6_addr.s6_addr16[1] = 0; if (dst6->sin6_scope_id == 0) { dst6->sin6_scope_id = ntohs(index); } } } appendAddress(newDict, kSCPropNetIPv6DestAddresses, dst6); } CFDictionarySetValue(newIFs, key, newDict); CFRelease(newDict); CFRelease(key); } /* if the last address[es] were removed from the target interface */ if (if_name && !interfaceFound) { interface = CFStringCreateWithCString(NULL, if_name, kCFStringEncodingMacRoman); key = SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL, kSCDynamicStoreDomainState, interface, kSCEntNetIPv6); CFRelease(interface); newDict = copyIF(key, oldIFs, newIFs); CFDictionarySetValue(newIFs, key, newDict); CFRelease(newDict); CFRelease(key); } CFDictionaryApplyFunction(newIFs, updateStore, oldIFs); error : if (ifap_temp) freeifaddrs(ifap_temp); if (sock != -1) close(sock); CFRelease(oldIFs); CFRelease(newIFs); return; }
static void prime(void) { struct ifaddrs *ifap = NULL; struct ifaddrs *scan; int sock = -1; SCLog(_verbose, LOG_DEBUG, CFSTR("prime() called")); cache_open(); sock = dgram_socket(AF_INET); if (sock == -1) { SCLog(TRUE, LOG_ERR, CFSTR("could not get interface list, socket() failed: %s"), strerror(errno)); goto done; } if (getifaddrs(&ifap) == -1) { SCLog(TRUE, LOG_ERR, CFSTR("could not get interface info, getifaddrs() failed: %s"), strerror(errno)); goto done; } /* update list of interfaces & link status */ for (scan = ifap; scan != NULL; scan = scan->ifa_next) { if (scan->ifa_addr == NULL || scan->ifa_addr->sa_family != AF_LINK) { continue; } /* get the per-interface link/media information */ link_add(scan->ifa_name); } /* * update IPv4 network addresses already assigned to * the interfaces. */ ipv4_interface_update(ifap, NULL); /* * update IPv6 network addresses already assigned to * the interfaces. */ interface_update_ipv6(ifap, NULL); freeifaddrs(ifap); done: if (sock != -1) close(sock); cache_write(store); cache_close(); network_changed = TRUE; post_network_changed(); /* start handling kernel events */ dispatch_resume(S_kev_source); return; }