/* * Check if we are interested in this interface * @param ifa a pointer to a ifaddr struct */ static void add_iface_if_needed(iface_t **head, iface_t **tail, struct ifaddrs *ifa) { // XXX RJ - added some print statements here to debug networking // I don't think there is any functional difference from the // original artnet code, but if something isn't working, it's // worth double checking. printf("add_iface_if_needed\n"); // skip down, loopback and non inet interfaces if (!ifa || !ifa->ifa_addr) { printf("null or null addr\n"); return; } // XXX work here to figure out how to print IP struct sockaddr_in *sckin = (struct sockaddr_in *) ifa->ifa_addr; printf("IP: %s\n", inet_ntoa(sckin->sin_addr)); if (!(ifa->ifa_flags & IFF_UP)) { printf("UP\n"); return; } if (ifa->ifa_flags & IFF_LOOPBACK) { printf("LOOPBACK\n"); return; } if (ifa->ifa_addr->sa_family != AF_INET) { printf("!= AF_INET\n"); return; } iface_t *iface = new_iface(head, tail); struct sockaddr_in *sin = (struct sockaddr_in*) ifa->ifa_addr; iface->ip_addr.sin_addr = sin->sin_addr; strncpy(iface->if_name, ifa->ifa_name, IFNAME_SIZE - 1); printf("got here\n"); if (ifa->ifa_flags & IFF_BROADCAST) { printf(" broadcast\n"); sin = (struct sockaddr_in *) ifa->ifa_broadaddr; iface->bcast_addr.sin_addr = sin->sin_addr; } }
/* * Set if_head to point to a list of iface_t structures which represent the * interfaces on this machine * @param ift_head the address of the pointer to the head of the list */ static int get_ifaces(iface_t **if_head) { iface_t *if_tail, *iface; PIP_ADAPTER_INFO pAdapter = NULL; PIP_ADAPTER_INFO pAdapterInfo; IP_ADDR_STRING *ipAddress; DWORD status; ULONG ulOutBufLen = sizeof(IP_ADAPTER_INFO); unsigned long net, mask; if_tail = NULL; while (1) { pAdapterInfo = (IP_ADAPTER_INFO*) malloc(ulOutBufLen); if (!pAdapterInfo) { artnet_error("Error allocating memory needed for GetAdaptersinfo"); return ARTNET_EMEM; } status= GetAdaptersInfo(pAdapterInfo, &ulOutBufLen); if (status == NO_ERROR) break; free(pAdapterInfo); if (status != ERROR_BUFFER_OVERFLOW) { printf("GetAdaptersInfo failed with error: %d\n", (int) status); return ARTNET_ENET; } } for (pAdapter = pAdapterInfo; pAdapter && pAdapter < pAdapterInfo + ulOutBufLen; pAdapter = pAdapter->Next) { if(pAdapter->Type != MIB_IF_TYPE_ETHERNET) continue; for (ipAddress = &pAdapter->IpAddressList; ipAddress; ipAddress = ipAddress->Next) { net = inet_addr(ipAddress->IpAddress.String); if (net) { // Windows doesn't seem to have the notion of an interface being 'up' // so we check if this interface has an address assigned. iface = new_iface(if_head, &if_tail); if (!iface) continue; mask = inet_addr(ipAddress->IpMask.String); strncpy(iface->if_name, pAdapter->AdapterName, IFNAME_SIZE); memcpy(iface->hw_addr, pAdapter->Address, ARTNET_MAC_SIZE); iface->ip_addr.sin_addr.s_addr = net; iface->bcast_addr.sin_addr.s_addr = ( (net & mask) | (0xFFFFFFFF ^ mask)); } } } free(pAdapterInfo); return (ARTNET_EOK); }
/* * Check if we are interested in this interface * @param ifa a pointer to a ifaddr struct */ static void add_iface_if_needed(iface_t **head, iface_t **tail, struct ifaddrs *ifa) { // skip down, loopback and non inet interfaces if (!ifa || !ifa->ifa_addr) return; if (!(ifa->ifa_flags & IFF_UP)) return; if (ifa->ifa_flags & IFF_LOOPBACK) return; if (ifa->ifa_addr->sa_family != AF_INET) return; iface_t *iface = new_iface(head, tail); struct sockaddr_in *sin = (struct sockaddr_in*) ifa->ifa_addr; iface->ip_addr.sin_addr = sin->sin_addr; strncpy(iface->if_name, ifa->ifa_name, IFNAME_SIZE - 1); if (ifa->ifa_flags & IFF_BROADCAST) { sin = (struct sockaddr_in *) ifa->ifa_broadaddr; iface->bcast_addr.sin_addr = sin->sin_addr; } }
void IPACM_LanToLan::handle_iface_up(ipacm_event_eth_bridge *data) { list<IPACM_LanToLan_Iface>::iterator it; IPACMDBG_H("Interface name: %s IP type: %d\n", data->p_iface->dev_name, data->iptype); for(it = m_iface.begin(); it != m_iface.end(); it++) { if(it->get_iface_pointer() == data->p_iface) { IPACMDBG_H("Found the interface.\n"); if(it->get_m_is_ip_addr_assigned(data->iptype) == false) { IPACMDBG_H("IP type %d was not active before, activating it now.\n", data->iptype); it->set_m_is_ip_addr_assigned(data->iptype, true); /* install inter-interface rules */ if(it->get_m_support_inter_iface_offload()) it->add_all_inter_interface_client_flt_rule(data->iptype); /* install intra-BSS rules */ if(it->get_m_support_intra_iface_offload()) it->add_all_intra_interface_client_flt_rule(data->iptype); } break; } } if(it == m_iface.end()) //If the interface has not been created before { if(m_iface.size() == MAX_NUM_IFACE) { IPACMERR("The number of interfaces has reached maximum %d.\n", MAX_NUM_IFACE); return; } if(!data->p_iface->tx_prop || !data->p_iface->rx_prop) { IPACMERR("The interface %s does not have tx_prop or rx_prop.\n", data->p_iface->dev_name); return; } if(data->p_iface->tx_prop->tx[0].hdr_l2_type == IPA_HDR_L2_NONE || data->p_iface->tx_prop->tx[0].hdr_l2_type == IPA_HDR_L2_MAX) { IPACMERR("Invalid l2 header type %s!\n", ipa_l2_hdr_type[data->p_iface->tx_prop->tx[0].hdr_l2_type]); return; } IPACMDBG_H("Does not find the interface, insert a new one.\n"); IPACM_LanToLan_Iface new_iface(data->p_iface); new_iface.set_m_is_ip_addr_assigned(data->iptype, true); m_iface.push_front(new_iface); IPACMDBG_H("Now the total number of interfaces is %d.\n", m_iface.size()); IPACM_LanToLan_Iface &front_iface = m_iface.front(); /* install inter-interface rules */ if(front_iface.get_m_support_inter_iface_offload()) { for(it = ++m_iface.begin(); it != m_iface.end(); it++) { /* add peer info only when both interfaces support inter-interface communication */ if(it->get_m_support_inter_iface_offload()) { /* populate hdr_proc_ctx and routing table handle */ handle_new_iface_up(&front_iface, &(*it)); /* add client specific routing rule on existing interface */ it->add_client_rt_rule_for_new_iface(); } } /* add client specific filtering rule on new interface */ front_iface.add_all_inter_interface_client_flt_rule(data->iptype); } /* populate the intra-interface information */ if(front_iface.get_m_support_intra_iface_offload()) { front_iface.handle_intra_interface_info(); } /* handle cached client add event */ handle_cached_client_add_event(front_iface.get_iface_pointer()); } return; }
/* * Set if_head to point to a list of iface_t structures which represent the * interfaces on this machine * @param ift_head the address of the pointer to the head of the list */ static int get_ifaces(iface_t **if_head) { struct ifconf ifc; struct ifreq *ifr, ifrcopy; struct sockaddr_in *sin; int len, lastlen, flags; char *buf, *ptr; iface_t *if_tail, *iface; int ret = ARTNET_EOK; int sd; *if_head = if_tail = NULL; // create socket to get iface config sd = socket(PF_INET, SOCK_DGRAM, 0); if (sd < 0) { artnet_error("%s : Could not create socket %s", __FUNCTION__, strerror(errno)); ret = ARTNET_ENET; goto e_return; } // first use ioctl to get a listing of interfaces lastlen = 0; len = INITIAL_IFACE_COUNT * sizeof(struct ifreq); for (;;) { buf = malloc(len); if (buf == NULL) { artnet_error_malloc(); ret = ARTNET_EMEM; goto e_free; } ifc.ifc_len = len; ifc.ifc_buf = buf; if (ioctl(sd, SIOCGIFCONF, &ifc) < 0) { if (errno != EINVAL || lastlen != 0) { artnet_error("%s : ioctl error %s", __FUNCTION__, strerror(errno)); ret = ARTNET_ENET; goto e_free; } } else { if (ifc.ifc_len == lastlen) break; lastlen = ifc.ifc_len; } len += IFACE_COUNT_INC * sizeof(struct ifreq); free(buf); } // loop through each iface for (ptr = buf; ptr < buf + ifc.ifc_len;) { ifr = (struct ifreq*) ptr; // work out length here #ifdef HAVE_SOCKADDR_SA_LEN len = max(sizeof(struct sockaddr), ifr->ifr_addr.sa_len); #else switch (ifr->ifr_addr.sa_family) { #ifdef IPV6 case AF_INET6: len = sizeof(struct sockaddr_in6); break; #endif case AF_INET: default: len = sizeof(SA); break; } #endif ptr += sizeof(ifr->ifr_name) + len; // look for AF_INET interfaces if (ifr->ifr_addr.sa_family == AF_INET) { ifrcopy = *ifr; if (ioctl(sd, SIOCGIFFLAGS, &ifrcopy) < 0) { artnet_error("%s : ioctl error %s" , __FUNCTION__, strerror(errno)); ret = ARTNET_ENET; goto e_free_list; } flags = ifrcopy.ifr_flags; if ((flags & IFF_UP) == 0) continue; //skip down interfaces if ((flags & IFF_LOOPBACK)) continue; //skip lookback iface = new_iface(if_head, &if_tail); if (!iface) goto e_free_list; sin = (struct sockaddr_in *) &ifr->ifr_addr; iface->ip_addr.sin_addr = sin->sin_addr; // fetch bcast address #ifdef SIOCGIFBRDADDR if (flags & IFF_BROADCAST) { if (ioctl(sd, SIOCGIFBRDADDR, &ifrcopy) < 0) { artnet_error("%s : ioctl error %s" , __FUNCTION__, strerror(errno)); ret = ARTNET_ENET; goto e_free_list; } sin = (struct sockaddr_in *) &ifrcopy.ifr_broadaddr; iface->bcast_addr.sin_addr = sin->sin_addr; } #endif // fetch hardware address #ifdef SIOCGIFHWADDR if (flags & SIOCGIFHWADDR) { if (ioctl(sd, SIOCGIFHWADDR, &ifrcopy) < 0) { artnet_error("%s : ioctl error %s", __FUNCTION__, strerror(errno)); ret = ARTNET_ENET; goto e_free_list; } memcpy(&iface->hw_addr, ifrcopy.ifr_hwaddr.sa_data, ARTNET_MAC_SIZE); } #endif /* ok, if that all failed we should prob try and use sysctl to work out the bcast * and hware addresses * i'll leave that for another day */ } } free(buf); return ARTNET_EOK; e_free_list: free_ifaces(*if_head); e_free: free(buf); close(sd); e_return: return ret; }