static void add_interface(CFMutableArrayRef *interfaces, CFStringRef if_name) { SCNetworkInterfaceRef interface; if (*interfaces == NULL) { *interfaces = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); } interface = _SCNetworkInterfaceCreateWithBSDName(NULL, if_name, kIncludeNoVirtualInterfaces); CFArrayAppendValue(*interfaces, interface); CFRelease(interface); }
static CFStringRef copy_default_name(void) { CFStringRef model; size_t n; CFMutableStringRef str; // get HW model name model = _SC_hw_model(TRUE); if (model == NULL) { return NULL; } // start off with the [trunated] HW model str = CFStringCreateMutable(NULL, 0); CFStringAppend(str, model); // truncate as needed n = CFStringGetLength(str); if (n > (NETBIOS_NAME_LEN - 1)) { CFStringReplace(str, CFRangeMake(NETBIOS_NAME_LEN, n - (NETBIOS_NAME_LEN - 1)), CFSTR("")); n = NETBIOS_NAME_LEN - 1; } // // if there is room for at least one byte (two hex characters) // of the MAC address than append that to the NetBIOS name. // // NETBIOS_NAME_LEN max length // -1 the last byte is reserved // -3 "-XX" // if (n < (NETBIOS_NAME_LEN - 1 - 3)) { SCNetworkInterfaceRef interface; interface = _SCNetworkInterfaceCreateWithBSDName(NULL, CFSTR("en0"), kIncludeNoVirtualInterfaces); if (interface != NULL) { CFMutableStringRef en0_MAC; en0_MAC = (CFMutableStringRef)SCNetworkInterfaceGetHardwareAddressString(interface); if (en0_MAC != NULL) { CFIndex en0_MAC_len; // remove ":" characters from MAC address string en0_MAC = CFStringCreateMutableCopy(NULL, 0, en0_MAC); CFStringFindAndReplace(en0_MAC, CFSTR(":"), CFSTR(""), CFRangeMake(0, CFStringGetLength(en0_MAC)), 0); // // compute how may bytes (characters) to append // ... and limit that number to 6 // // NETBIOS_NAME_LEN max length // -1 the last byte is reserved // -n "iMac" // -1 "-" // n = ((NETBIOS_NAME_LEN - 1 - n - 1) / 2) * 2; if (n > 6) { n = 6; } // remove what we don't want en0_MAC_len = CFStringGetLength(en0_MAC); if (en0_MAC_len > n) { CFStringDelete(en0_MAC, CFRangeMake(0, en0_MAC_len - n)); } // append CFStringAppendFormat(str, NULL, CFSTR("-%@"), en0_MAC); CFRelease(en0_MAC); } CFRelease(interface); } } CFStringUppercase(str, NULL); return str; }
static void add_configured_interface(const void *key, const void *value, void *context) { SCNetworkInterfacePrivateRef interfacePrivate; addContextRef myContext = (addContextRef)context; SCVLANInterfaceRef vlan; CFStringRef vlan_if = (CFStringRef)key; CFDictionaryRef vlan_info = (CFDictionaryRef)value; CFStringRef vlan_name; CFDictionaryRef vlan_options; SCNetworkInterfaceRef vlan_physical; CFStringRef vlan_physical_if; CFNumberRef vlan_tag; vlan_physical_if = CFDictionaryGetValue(vlan_info, kSCPropVirtualNetworkInterfacesVLANInterface); if (!isA_CFString(vlan_physical_if)) { // if prefs are confused return; } vlan_tag = CFDictionaryGetValue(vlan_info, kSCPropVirtualNetworkInterfacesVLANTag); if (!isA_CFNumber(vlan_tag)) { // if prefs are confused return; } // create the VLAN interface vlan = (SCVLANInterfaceRef)_SCVLANInterfaceCreatePrivate(NULL, vlan_if); assert(vlan != NULL); // set physical interface and tag vlan_physical = _SCNetworkInterfaceCreateWithBSDName(NULL, vlan_physical_if, kIncludeBondInterfaces); assert(vlan_physical != NULL); // since we KNOW that the physical interface supported VLANs when // it was first established it's OK to force that state here ... // and this is needed for the case when the interface (e.g. a // dongle) is not currently attached to the system interfacePrivate = (SCNetworkInterfacePrivateRef)vlan_physical; interfacePrivate->supportsVLAN = TRUE; // and now we associate the physical interface and tag SCVLANInterfaceSetPhysicalInterfaceAndTag(vlan, vlan_physical, vlan_tag); CFRelease(vlan_physical); // set display name vlan_name = CFDictionaryGetValue(vlan_info, kSCPropUserDefinedName); if (isA_CFString(vlan_name)) { SCVLANInterfaceSetLocalizedDisplayName(vlan, vlan_name); } // set options vlan_options = CFDictionaryGetValue(vlan_info, kSCPropVirtualNetworkInterfacesVLANOptions); if (isA_CFDictionary(vlan_options)) { SCVLANInterfaceSetOptions(vlan, vlan_options); } // estabish link to the stored configuration interfacePrivate = (SCNetworkInterfacePrivateRef)vlan; interfacePrivate->prefs = CFRetain(myContext->prefs); CFArrayAppendValue(myContext->vlans, vlan); CFRelease(vlan); return; }
CFArrayRef _SCVLANInterfaceCopyActive(void) { struct ifaddrs *ifap; struct ifaddrs *ifp; int s; CFMutableArrayRef vlans = NULL; if (getifaddrs(&ifap) == -1) { SCLog(TRUE, LOG_ERR, CFSTR("getifaddrs() failed: %s"), strerror(errno)); _SCErrorSet(kSCStatusFailed); return NULL; } s = inet_dgram_socket(); if (s == -1) { _SCErrorSet(errno); goto done; } vlans = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); for (ifp = ifap; ifp != NULL; ifp = ifp->ifa_next) { struct if_data *if_data; struct ifreq ifr; SCVLANInterfaceRef vlan; CFStringRef vlan_if; SCNetworkInterfaceRef vlan_physical; CFStringRef vlan_physical_if; CFNumberRef vlan_tag; char vlr_parent[IFNAMSIZ]; int vlr_tag; struct vlanreq vreq; if_data = (struct if_data *)ifp->ifa_data; if (if_data == NULL || ifp->ifa_addr->sa_family != AF_LINK || if_data->ifi_type != IFT_L2VLAN) { continue; } bzero(&ifr, sizeof(ifr)); bzero(&vreq, sizeof(vreq)); strlcpy(ifr.ifr_name, ifp->ifa_name, sizeof(ifr.ifr_name)); ifr.ifr_data = (caddr_t)&vreq; if (ioctl(s, SIOCGIFVLAN, (caddr_t)&ifr) == -1) { SCLog(TRUE, LOG_ERR, CFSTR("ioctl() failed: %s"), strerror(errno)); CFRelease(vlans); vlans = NULL; _SCErrorSet(kSCStatusFailed); goto done; } // create the VLAN interface vlan_if = CFStringCreateWithCString(NULL, ifp->ifa_name, kCFStringEncodingASCII); vlan = (SCVLANInterfaceRef)_SCVLANInterfaceCreatePrivate(NULL, vlan_if); assert(vlan != NULL); CFRelease(vlan_if); // set the physical interface and tag strlcpy(vlr_parent, vreq.vlr_parent, sizeof(vlr_parent)); vlan_physical_if = CFStringCreateWithCString(NULL, vlr_parent, kCFStringEncodingASCII); vlan_physical = _SCNetworkInterfaceCreateWithBSDName(NULL, vlan_physical_if, kIncludeBondInterfaces); assert(vlan_physical != NULL); CFRelease(vlan_physical_if); vlr_tag = vreq.vlr_tag; vlan_tag = CFNumberCreate(NULL, kCFNumberIntType, &vlr_tag); assert(vlan_tag != NULL); SCVLANInterfaceSetPhysicalInterfaceAndTag(vlan, vlan_physical, vlan_tag); CFRelease(vlan_physical); CFRelease(vlan_tag); // add VLAN CFArrayAppendValue(vlans, vlan); CFRelease(vlan); } done : if (s != -1) { (void) close(s); } freeifaddrs(ifap); return vlans; }
SCBondStatusRef SCBondInterfaceCopyStatus(SCBondInterfaceRef bond) { int bond_if_active; int bond_if_status; CFIndex i; struct if_bond_status_req *ibsr_p = NULL; char if_name[IFNAMSIZ]; CFIndex n; CFNumberRef num; int s; struct if_bond_status *scan_p; SCBondStatusRef status = NULL; CFMutableDictionaryRef status_bond; CFMutableDictionaryRef status_interfaces; if (!isA_SCBondInterface(bond)) { _SCErrorSet(kSCStatusInvalidArgument); return NULL; } s = inet_dgram_socket(); if (s == -1) { _SCErrorSet(errno); goto done; } _SC_cfstring_to_cstring(SCNetworkInterfaceGetBSDName(bond), if_name, sizeof(if_name), kCFStringEncodingASCII); if (siocgifmedia(s, if_name, &bond_if_status, &bond_if_active) == -1) { _SCErrorSet(errno); switch (errno) { case EBUSY : case ENXIO : break; default : SCLog(TRUE, LOG_ERR, CFSTR("siocgifmedia(%s) failed: %s"), if_name, strerror(errno)); } goto done; } ibsr_p = if_bond_status_req_copy(s, if_name); if (ibsr_p == NULL) { _SCErrorSet(errno); goto done; } status_bond = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); status_interfaces = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); n = ibsr_p->ibsr_total; for (i = 0, scan_p = (struct if_bond_status *)ibsr_p->ibsr_buffer; i < n; i++, scan_p++) { int collecting = 0; int distributing = 0; SCNetworkInterfaceRef interface; CFStringRef interface_name; struct if_bond_partner_state * ps; CFMutableDictionaryRef status_interface; int status_val; ps = &scan_p->ibs_partner_state; if (lacp_actor_partner_state_in_sync(scan_p->ibs_state)) { /* we're in-sync */ status_val = kSCBondStatusOK; if (lacp_actor_partner_state_in_sync(ps->ibps_state)) { /* partner is also in-sync */ if (lacp_actor_partner_state_collecting(scan_p->ibs_state) && lacp_actor_partner_state_distributing(ps->ibps_state)) { /* we're able to collect (receive) frames */ collecting = 1; } if (lacp_actor_partner_state_distributing(scan_p->ibs_state) && lacp_actor_partner_state_collecting(ps->ibps_state)) { /* we're able to distribute (transmit) frames */ distributing = 1; } } } else { int active = 0; int status = 0; static lacp_system zeroes = { {0, 0, 0, 0, 0, 0}}; if (siocgifmedia(s, scan_p->ibs_if_name, &status, &active) == -1) { switch (errno) { case EBUSY : case ENXIO : break; default : SCLog(TRUE, LOG_ERR, CFSTR("siocgifmedia(%s) failed: %s"), if_name, strerror(errno)); break; } } if (((status & IFM_AVALID) == 0) || ((status & IFM_ACTIVE) == 0) || ((active & IFM_FDX ) == 0)) { /* link down or not full-duplex */ status_val = kSCBondStatusLinkInvalid; } else if ((ps->ibps_system_priority == 0) && (bcmp(&zeroes, &ps->ibps_system, sizeof(zeroes)) == 0)) { /* no one on the other end of the link */ status_val = kSCBondStatusNoPartner; } else if (active != bond_if_active) { /* the link speed was different */ status_val = kSCBondStatusLinkInvalid; } else { /* partner is not in the active group */ status_val = kSCBondStatusNotInActiveGroup; } } // interface strlcpy(if_name, scan_p->ibs_if_name, sizeof(if_name)); interface_name = CFStringCreateWithCString(NULL, if_name, kCFStringEncodingASCII); interface = _SCNetworkInterfaceCreateWithBSDName(NULL, interface_name, kIncludeNoVirtualInterfaces); CFRelease(interface_name); // interface status status_interface = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); num = CFNumberCreate(NULL, kCFNumberIntType, &status_val); CFDictionarySetValue(status_interface, kSCBondStatusDeviceAggregationStatus, num); CFRelease(num); num = CFNumberCreate(NULL, kCFNumberIntType, &collecting); CFDictionarySetValue(status_interface, kSCBondStatusDeviceCollecting, num); CFRelease(num); num = CFNumberCreate(NULL, kCFNumberIntType, &distributing); CFDictionarySetValue(status_interface, kSCBondStatusDeviceDistributing, num); CFRelease(num); CFDictionarySetValue(status_interfaces, interface, status_interface); CFRelease(interface); CFRelease(status_interface); } status = __SCBondStatusCreatePrivate(NULL, bond, status_bond, status_interfaces); CFRelease(status_bond); CFRelease(status_interfaces); done: if (s != -1) { close(s); } if (ibsr_p != NULL) { free(ibsr_p); } return (SCBondStatusRef)status; }