Exemple #1
0
/*----------------------------------------------------------------------
|       NPT_NetworkInterface::GetNetworkInterfaces
+---------------------------------------------------------------------*/
NPT_Result
NPT_NetworkInterface::GetNetworkInterfaces(NPT_List<NPT_NetworkInterface*>& interfaces)
{
    union SceNetApctlInfo info;
    int ret = sceNetApctlGetInfo(SCE_NET_APCTL_INFO_IP_ADDRESS, &info);
    if (ret < 0) {
        return NPT_FAILURE;
    }
    NPT_IpAddress primary_address;
    if (NPT_FAILED(primary_address.Parse(info.ip_address))) {
        return NPT_FAILURE;
    }

    NPT_IpAddress netmask;
    if (NPT_FAILED(netmask.Parse(info.netmask))) {
        return NPT_FAILURE;
    }

    NPT_IpAddress broadcast_address;
    NPT_Flags    flags = 0;
    flags |= NPT_NETWORK_INTERFACE_FLAG_BROADCAST;
    flags |= NPT_NETWORK_INTERFACE_FLAG_MULTICAST;

    // get mac address
    SceNetEtherAddr mac_info;
    ret = sceNetGetLocalEtherAddr(&mac_info);
    if (ret < 0) {
        return NPT_FAILURE;
    }
    NPT_MacAddress mac(TYPE_IEEE_802_11, mac_info.data, SCE_NET_ETHER_ADDR_LEN);

    // create an interface object
    char iface_name[5];
    iface_name[0] = 'i';
    iface_name[1] = 'f';
    iface_name[2] = '0';
    iface_name[3] = '0';
    iface_name[4] = '\0';
    NPT_NetworkInterface* iface = new NPT_NetworkInterface(iface_name, mac, flags);

    // set the interface address
    NPT_NetworkInterfaceAddress iface_address(
        primary_address,
        broadcast_address,
        NPT_IpAddress::Any,
        netmask);
    iface->AddAddress(iface_address);  

    // add the interface to the list
    interfaces.Add(iface);  

    return NPT_SUCCESS;
}
Exemple #2
0
NPT_UdpMulticastSocket* Server::getNewMulticastSocket()
{
    NPT_NetworkInterface* serverInterface = gMS->serverInterface();

    auto addresses = serverInterface->GetAddresses();
    if (!addresses.GetFirstItem())
    {
        throw new std::runtime_error("No usable addresses found for UPnP multicast");
    }

    NPT_SocketAddress localAddress((*addresses.GetFirstItem()).GetPrimaryAddress(), 0);

    NPT_UdpMulticastSocket* ssdpSocket = new NPT_UdpMulticastSocket();
    ssdpSocket->Bind(localAddress, true);
    ssdpSocket->SetTimeToLive(32);
    return ssdpSocket;
}
/*----------------------------------------------------------------------
|       NPT_NetworkInterface::GetNetworkInterfaces
+---------------------------------------------------------------------*/
NPT_Result
NPT_NetworkInterface::GetNetworkInterfaces(NPT_List<NPT_NetworkInterface*>& interfaces)
{
    int net = socket(AF_INET, SOCK_DGRAM, 0);

    // Try to get the config until we have enough memory for it
    // According to "Unix Network Programming", some implementations
    // do not return an error when the supplied buffer is too small
    // so we need to try, increasing the buffer size every time,
    // until we get the same size twice. We cannot assume success when
    // the returned size is smaller than the supplied buffer, because
    // some implementations can return less that the buffer size if
    // another structure does not fit.
    unsigned int buffer_size = 4096; // initial guess
    unsigned int last_size = 0;
    struct ifconf config;
    unsigned char* buffer;
    for (; buffer_size < 65536;) {
        buffer = new unsigned char[buffer_size];
        config.ifc_len = buffer_size;
        config.ifc_buf = (char*)buffer;
        if (ioctl(net, SIOCGIFCONF, &config) < 0) {
            if (errno != EINVAL || last_size != 0) {
                return NPT_ERROR_BASE_UNIX-errno;
            }
        } else {
            if ((unsigned int)config.ifc_len == last_size) {
                // same size, we can use the buffer
                break;
            }
            // different size, we need to reallocate
            last_size = config.ifc_len;
        }

        // supply 4096 more bytes more next time around
        buffer_size += 4096;
        delete[] buffer;
    }

    // iterate over all objects
    unsigned char *entries;
    for (entries = buffer; entries < buffer+config.ifc_len;) {
        struct ifreq* entry = (struct ifreq*)entries;
        // get the size of the addresses
        unsigned int address_length;
#if defined(NPT_CONFIG_HAVE_SOCKADDR_SA_LEN)
        address_length = sizeof(struct sockaddr) > entry->ifr_addr.sa_len ?
                         sizeof(sockaddr) : entry->ifr_addr.sa_len;
#else
        switch (entry->ifr_addr.sa_family) {
#if defined(AF_INET6)
        case AF_INET6:
            address_length = sizeof(struct sockaddr_in6);
            break;
#endif // defined(AF_INET6)

        default:
            address_length = sizeof(struct sockaddr);
            break;
        }
#endif

        // point to the next entry
        entries += address_length + sizeof(entry->ifr_name);

        // ignore anything except AF_INET and AF_LINK addresses
        if (entry->ifr_addr.sa_family != AF_INET
#if defined(AF_LINK)
                && entry->ifr_addr.sa_family != AF_LINK
#endif
           ) {
            continue;
        }

        // get detailed info about the interface
        NPT_Flags flags = 0;
#if defined(SIOCGIFFLAGS)
        struct ifreq query = *entry;
        if (ioctl(net, SIOCGIFFLAGS, &query) < 0) continue;

        // process the flags
        if ((query.ifr_flags & IFF_UP) == 0) {
            // the interface is not up, ignore it
            continue;
        }
        if (query.ifr_flags & IFF_BROADCAST) {
            flags |= NPT_NETWORK_INTERFACE_FLAG_BROADCAST;
        }
        if (query.ifr_flags & IFF_LOOPBACK) {
            flags |= NPT_NETWORK_INTERFACE_FLAG_LOOPBACK;
        }
#if defined(IFF_POINTOPOINT)
        if (query.ifr_flags & IFF_POINTOPOINT) {
            flags |= NPT_NETWORK_INTERFACE_FLAG_POINT_TO_POINT;
        }
#endif // defined(IFF_POINTOPOINT)
        if (query.ifr_flags & IFF_PROMISC) {
            flags |= NPT_NETWORK_INTERFACE_FLAG_PROMISCUOUS;
        }
        if (query.ifr_flags & IFF_MULTICAST) {
            flags |= NPT_NETWORK_INTERFACE_FLAG_MULTICAST;
        }
#endif // defined(SIOCGIFFLAGS)

        // get a pointer to an interface we've looped over before
        // or create a new one
        NPT_NetworkInterface* interface = NULL;
        for (NPT_List<NPT_NetworkInterface*>::Iterator iface_iter = interfaces.GetFirstItem();
                iface_iter;
                ++iface_iter) {
            if ((*iface_iter)->GetName() == (const char*)entry->ifr_name) {
                interface = *iface_iter;
                break;
            }
        }
        if (interface == NULL) {
            // create a new interface object
            interface = new NPT_NetworkInterface(entry->ifr_name, flags);

            // add the interface to the list
            interfaces.Add(interface);

            // get the mac address
#if defined(SIOCGIFHWADDR)
            if (ioctl(net, SIOCGIFHWADDR, &query) == 0) {
                NPT_MacAddress::Type mac_addr_type;
                unsigned int         mac_addr_length = IFHWADDRLEN;
                switch (query.ifr_addr.sa_family) {
#if defined(ARPHRD_ETHER)
                case ARPHRD_ETHER:
                    mac_addr_type = NPT_MacAddress::TYPE_ETHERNET;
                    break;
#endif

#if defined(ARPHRD_LOOPBACK)
                case ARPHRD_LOOPBACK:
                    mac_addr_type = NPT_MacAddress::TYPE_LOOPBACK;
                    length = 0;
                    break;
#endif

#if defined(ARPHRD_PPP)
                case ARPHRD_PPP:
                    mac_addr_type = NPT_MacAddress::TYPE_PPP;
                    mac_addr_length = 0;
                    break;
#endif

#if defined(ARPHRD_IEEE80211)
                case ARPHRD_IEEE80211:
                    mac_addr_type = NPT_MacAddress::TYPE_IEEE_802_11;
                    break;
#endif

                default:
                    mac_addr_type = NPT_MacAddress::TYPE_UNKNOWN;
                    mac_addr_length = sizeof(query.ifr_addr.sa_data);
                    break;
                }

                interface->SetMacAddress(mac_addr_type, (const unsigned char*)query.ifr_addr.sa_data, mac_addr_length);
            }
#endif
        }

        switch (entry->ifr_addr.sa_family) {
        case AF_INET: {
            // primary address
            NPT_IpAddress primary_address(ntohl(((struct sockaddr_in*)&entry->ifr_addr)->sin_addr.s_addr));

            // broadcast address
            NPT_IpAddress broadcast_address;
#if defined(SIOCGIFBRDADDR)
            if (flags & NPT_NETWORK_INTERFACE_FLAG_BROADCAST) {
                if (ioctl(net, SIOCGIFBRDADDR, &query) == 0) {
                    broadcast_address.Set(ntohl(((struct sockaddr_in*)&query.ifr_addr)->sin_addr.s_addr));
                }
            }
#endif

            // point to point address
            NPT_IpAddress destination_address;
#if defined(SIOCGIFDSTADDR)
            if (flags & NPT_NETWORK_INTERFACE_FLAG_POINT_TO_POINT) {
                if (ioctl(net, SIOCGIFDSTADDR, &query) == 0) {
                    destination_address.Set(ntohl(((struct sockaddr_in*)&query.ifr_addr)->sin_addr.s_addr));
                }
            }
#endif

            // netmask
            NPT_IpAddress netmask(0xFFFFFFFF);
#if defined(SIOCGIFNETMASK)
            if (ioctl(net, SIOCGIFNETMASK, &query) == 0) {
                netmask.Set(ntohl(((struct sockaddr_in*)&query.ifr_addr)->sin_addr.s_addr));
            }
#endif

            // add the address to the interface
            NPT_NetworkInterfaceAddress iface_address(
                primary_address,
                broadcast_address,
                destination_address,
                netmask);
            interface->AddAddress(iface_address);

            break;
        }

#if defined(AF_LINK) && defined(NPT_CONFIG_HAVE_SOCKADDR_DL)
        case AF_LINK: {
            struct sockaddr_dl* mac_addr = (struct sockaddr_dl*)&entry->ifr_addr;
            NPT_MacAddress::Type mac_addr_type = NPT_MacAddress::TYPE_UNKNOWN;
            switch (mac_addr->sdl_type) {
#if defined(IFT_LOOP)
            case IFT_LOOP:
                mac_addr_type = NPT_MacAddress::TYPE_LOOPBACK;
                break;
#endif
#if defined(IFT_ETHER)
            case IFT_ETHER:
                mac_addr_type = NPT_MacAddress::TYPE_ETHERNET;
                break;
#endif
#if defined(IFT_PPP)
            case IFT_PPP:
                mac_addr_type = NPT_MacAddress::TYPE_PPP;
                break;
#endif
            }
            interface->SetMacAddress(mac_addr_type,
                                     (const unsigned char*)(&mac_addr->sdl_data[mac_addr->sdl_nlen]),
                                     mac_addr->sdl_alen);
            break;
        }
#endif
        }
    }

    // free resources
    delete[] buffer;
    close(net);

    return NPT_SUCCESS;
}
/*----------------------------------------------------------------------
 |       NPT_NetworkInterface::GetNetworkInterfaces
 +---------------------------------------------------------------------*/
NPT_Result
NPT_NetworkInterface::GetNetworkInterfaces(NPT_List<NPT_NetworkInterface*>& interfaces)
{
    int result = 0;
    struct ifaddrs * ifaddrsList = NULL;
    struct ifaddrs * ifaddr = NULL;
    NPT_Flags flags = 0;
    
    result = getifaddrs(&ifaddrsList);
    
    if( result != 0 || ifaddrsList == NULL)
        return NPT_FAILURE;
    
    for(ifaddr = ifaddrsList; NULL!= ifaddr; ifaddr = ifaddr->ifa_next) {
        
        if(ifaddr->ifa_addr == NULL /*|| ifaddr->ifa_addr->sa_family == AF_INET6*/)
            continue;
        
        // process the flags
        if ((ifaddr->ifa_flags & IFF_UP) == 0) {
            // the interface is not up, ignore it
            continue;
        }
        if (ifaddr->ifa_flags & IFF_BROADCAST) {
            flags |= NPT_NETWORK_INTERFACE_FLAG_BROADCAST;
        }
        if (ifaddr->ifa_flags & IFF_LOOPBACK) {
            flags |= NPT_NETWORK_INTERFACE_FLAG_LOOPBACK;
        }
#if defined(IFF_POINTOPOINT)
        if (ifaddr->ifa_flags & IFF_POINTOPOINT) {
            flags |= NPT_NETWORK_INTERFACE_FLAG_POINT_TO_POINT;
        }
#endif // defined(IFF_POINTOPOINT)
        if (ifaddr->ifa_flags & IFF_PROMISC) {
            flags |= NPT_NETWORK_INTERFACE_FLAG_PROMISCUOUS;
        }
        if (ifaddr->ifa_flags & IFF_MULTICAST) {
            flags |= NPT_NETWORK_INTERFACE_FLAG_MULTICAST;
        }
        
        NPT_NetworkInterface* interface = NULL;
        for (NPT_List<NPT_NetworkInterface*>::Iterator iface_iter = interfaces.GetFirstItem();
             iface_iter;
             ++iface_iter) {
            if ((*iface_iter)->GetName() == (const char*)ifaddr->ifa_name) {
                interface = *iface_iter;
                break;
            }
        }
        
        // create a new interface object
        if(interface == NULL)
            interface = new NPT_NetworkInterface(ifaddr->ifa_name, flags);
        
        if (interface == NULL)
            continue;
            
            // get the mac address
            NPT_MacAddress::Type mac_addr_type;
            unsigned int         mac_addr_length = IFHWADDRLEN;
            switch (ifaddr->ifa_addr->sa_family) {
                case AF_LOCAL:
                case AF_INET:
#if defined(AF_LINK)
                case AF_LINK:
#endif
                    mac_addr_type = NPT_MacAddress::TYPE_ETHERNET;
#if defined(ARPHRD_LOOPBACK)      
                    mac_addr_type = NPT_MacAddress::TYPE_LOOPBACK;
                    length = 0;
#endif               
                    break;
#if defined(AF_PPP)
                case AF_PPP:
                    mac_addr_type = NPT_MacAddress::TYPE_PPP;
                    mac_addr_length = 0;
                    break;
#endif
#if defined(AF_IEEE80211)
                case AF_IEEE80211:
                    mac_addr_type = NPT_MacAddress::TYPE_IEEE_802_11;
                    break;
#endif                    
                default:
                    mac_addr_type = NPT_MacAddress::TYPE_UNKNOWN;
                    mac_addr_length = sizeof(ifaddr->ifa_addr->sa_data);
                    break;
            }


            if(interface->GetMacAddress().GetLength() == 0)
                interface->SetMacAddress(mac_addr_type, (const unsigned char*)ifaddr->ifa_addr->sa_data, mac_addr_length);
        
#if defined(NPT_CONFIG_HAVE_NET_IF_DL_H)        
        if (ifaddr->ifa_addr->sa_family == AF_LINK) {
            //Refer to LLADDR
            struct sockaddr_dl * socket_dl = (struct sockaddr_dl *)ifaddr->ifa_addr;
            
            interface->SetMacAddress(mac_addr_type, (const unsigned char*)socket_dl->sdl_data+socket_dl->sdl_nlen, socket_dl->sdl_alen);
        }
#endif
            switch (ifaddr->ifa_addr->sa_family) {
                case AF_INET: {
                    // primary address
                    NPT_IpAddress primary_address( ntohl(((struct sockaddr_in *)ifaddr->ifa_addr)->sin_addr.s_addr));
                    
                    // broadcast address
                    NPT_IpAddress broadcast_address;
                    if ((flags & NPT_NETWORK_INTERFACE_FLAG_BROADCAST) && ifaddr->ifa_dstaddr) {
                        broadcast_address.Set(ntohl(((struct sockaddr_in*)ifaddr->ifa_dstaddr)->sin_addr.s_addr));
                    }
                    
                    // point to point address
                    NPT_IpAddress destination_address;
                    if ((flags & NPT_NETWORK_INTERFACE_FLAG_POINT_TO_POINT) && ifaddr->ifa_dstaddr) {
                        destination_address.Set(ntohl(((struct sockaddr_in*)ifaddr->ifa_dstaddr)->sin_addr.s_addr));
                    }
                    
                    // netmask
                    NPT_IpAddress netmask(0xFFFFFFFF);
                    if(ifaddr->ifa_netmask)
                        netmask.Set(ntohl(((struct sockaddr_in*)ifaddr->ifa_netmask)->sin_addr.s_addr));
                    
                    // add the address to the interface
                    NPT_NetworkInterfaceAddress iface_address(primary_address,
                                                              broadcast_address,
                                                              destination_address,
                                                              netmask);

                    interface->AddAddress(iface_address);
                    
                    break;
                }
                    
            }
            // add the interface to the list
            interfaces.Add(interface);
        
    }
    freeifaddrs(ifaddrsList);
    
    return NPT_SUCCESS;
}
Exemple #5
0
NPT_Result FrontEnd::start()
{
	WriteLocker locker(m_stateLock);
	if (m_state != State_Stopped) {
		return NPT_ERROR_INVALID_STATE;
	}

	NPT_Result nr;

	NPT_List<NPT_NetworkInterface*> ifList;
	nr = NPT_NetworkInterface::GetNetworkInterfaces(ifList);
	if (NPT_FAILED(nr)) {
		return nr;
	}

	for (NPT_Ordinal i = 0; i < ifList.GetItemCount(); i++) {
		NPT_NetworkInterface *nif = *ifList.GetItem(i);
		if (nif->GetAddresses().GetFirstItem() && (m_includeLoopback || ((nif->GetFlags() & NPT_NETWORK_INTERFACE_FLAG_LOOPBACK) == 0))) {
			Interface *intf = new Interface();
			intf->m_owner = this;
			intf->m_nif = nif;
			intf->m_context.m_ifAddr = nif->GetAddresses().GetFirstItem()->GetPrimaryAddress();
			intf->m_httpConnector = new HttpConnector(intf, intf->m_context.m_ifAddr);
			intf->m_ssdpConnector = new SsdpConnector(intf, intf->m_context.m_ifAddr);
			intf->m_context.m_httpPort = 0;
			intf->m_context.m_ssdpPort = 0;
			m_ifList.Add(intf);
			m_interfaceContextList.Add(&intf->m_context);
		} else {
			delete nif;
		}
	}

	if (m_ifList.GetItemCount() == 0) {
		return NPT_FAILURE;
	}

	for (NPT_Ordinal i = 0; i < m_ifList.GetItemCount(); i++) {
		Interface *intf = *m_ifList.GetItem(i);
		if (NPT_SUCCEEDED(intf->m_httpConnector->start())) {
			intf->m_context.m_httpPort = intf->m_httpConnector->port();
		}
		if (NPT_SUCCEEDED(intf->m_ssdpConnector->start())) {
			intf->m_context.m_ssdpPort = intf->m_ssdpConnector->port();
		}
	}

	m_taskGroup->reset();

	{
		ReadLocker locker1(m_cpLock);
		for (NPT_Ordinal i = 0; i < m_controlPointList.GetItemCount(); i++) {
			ControlPointInfo *info = *m_controlPointList.GetItem(i);
			info->m_controlPoint->implAttach(this, info->m_context);
		}

		for (NPT_Ordinal i = 0; i < m_deviceImplList.GetItemCount(); i++) {
			DeviceImplInfo *info = *m_deviceImplList.GetItem(i);
			info->m_deviceImpl->implAttach(this, info->m_context);
		}

		broadcastLocked(NULL, true);
	}

	m_taskGroup->startTask(new SsdpBroadcastTask(this));

	m_state = State_Running;
	return NPT_SUCCESS;
}
Exemple #6
0
/*----------------------------------------------------------------------
|   NPT_NetworkInterface::GetNetworkInterfaces
+---------------------------------------------------------------------*/
NPT_Result
NPT_NetworkInterface::GetNetworkInterfaces(NPT_List<NPT_NetworkInterface*>& interfaces)
{
    // create a socket to talk to the TCP/IP stack
    SOCKET net;
    if((net = WSASocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP, NULL, 0, 0)) == INVALID_SOCKET) {
        return NPT_FAILURE;
    }

    // get a list of interfaces
    INTERFACE_INFO query[32];  // get up to 32 interfaces 
    DWORD bytes_returned;
    int io_result = WSAIoctl(net, 
                             SIO_GET_INTERFACE_LIST, 
                             NULL, 0, 
                             &query, sizeof(query), 
                             &bytes_returned, 
                             NULL, NULL);
    if (io_result == SOCKET_ERROR) {
        closesocket(net);
        return NPT_FAILURE;
    }

    // we don't need the socket anymore
    closesocket(net);

    // Display interface information
    int interface_count = (bytes_returned/sizeof(INTERFACE_INFO));
    unsigned int iface_index = 0;
    for (int i=0; i<interface_count; i++) {
        SOCKADDR_IN* address;
        NPT_Flags    flags = 0;

        // primary address
        address = (SOCKADDR_IN*)&query[i].iiAddress;
        NPT_IpAddress primary_address(ntohl(address->sin_addr.s_addr));

        // netmask
        address = (SOCKADDR_IN*)&query[i].iiNetmask;
        NPT_IpAddress netmask(ntohl(address->sin_addr.s_addr));

        // broadcast address
        address = (SOCKADDR_IN*)&query[i].iiBroadcastAddress;
        NPT_IpAddress broadcast_address(ntohl(address->sin_addr.s_addr));

        {
            // broadcast address is incorrect
            unsigned char addr[4];
            for(int i=0; i<4; i++) {
                addr[i] = (primary_address.AsBytes()[i] & netmask.AsBytes()[i]) | 
                    ~netmask.AsBytes()[i];
            }
            broadcast_address.Set(addr);
        }

        // ignore interfaces that are not up
        if (!(query[i].iiFlags & IFF_UP)) {
            continue;
        }
        if (query[i].iiFlags & IFF_BROADCAST) {
            flags |= NPT_NETWORK_INTERFACE_FLAG_BROADCAST;
        }
        if (query[i].iiFlags & IFF_MULTICAST) {
            flags |= NPT_NETWORK_INTERFACE_FLAG_MULTICAST;
        }
        if (query[i].iiFlags & IFF_LOOPBACK) {
            flags |= NPT_NETWORK_INTERFACE_FLAG_LOOPBACK;
        }
        if (query[i].iiFlags & IFF_POINTTOPOINT) {
            flags |= NPT_NETWORK_INTERFACE_FLAG_POINT_TO_POINT;
        }

        // mac address (no support for this for now)
        NPT_MacAddress mac;

        // create an interface object
        char iface_name[5];
        iface_name[0] = 'i';
        iface_name[1] = 'f';
        iface_name[2] = '0'+(iface_index/10);
        iface_name[3] = '0'+(iface_index%10);
        iface_name[4] = '\0';
        NPT_NetworkInterface* iface = new NPT_NetworkInterface(iface_name, mac, flags);

        // set the interface address
        NPT_NetworkInterfaceAddress iface_address(
            primary_address,
            broadcast_address,
            NPT_IpAddress::Any,
            netmask);
        iface->AddAddress(iface_address);  
         
        // add the interface to the list
        interfaces.Add(iface);   

        // increment the index (used for generating the name
        iface_index++;
    }

    return NPT_SUCCESS;
}