Ejemplo n.º 1
0
/*----------------------------------------------------------------------
|   NPT_NetworkNameResolver::Resolve
+---------------------------------------------------------------------*/
NPT_Result
NPT_NetworkNameResolver::Resolve(const char*              name, 
                                 NPT_List<NPT_IpAddress>& addresses,
                                 NPT_Timeout              /*timeout*/)
{
    // empty the list first
    addresses.Clear();
    
    
    // get the addr list

    //struct addrinfo hints;
    //NPT_SetMemory(&hints, 0, sizeof(hints));
    //hints.ai_family   = PF_UNSPEC;
    //hints.ai_socktype = SOCK_STREAM;
    //hints.ai_flags    = AI_DEFAULT;
    struct addrinfo *infos = NULL;
    int result = getaddrinfo(name,  /* hostname */
                             NULL,  /* servname */
                             NULL,  /* hints    */
                             &infos /* res      */);
    if (result != 0) {
        return MapGetAddrInfoErrorCode(result);
    }
    
    for (struct addrinfo* info = infos; 
                          info && addresses.GetItemCount() < NPT_BSD_NETWORK_MAX_ADDR_LIST_LENGTH;
                          info = info->ai_next) {
        unsigned int expected_length;
        if (info->ai_family == AF_INET) {
            expected_length = sizeof(struct sockaddr_in);
#if defined(NPT_CONFIG_ENABLE_IPV6)
        } else if (info->ai_family == AF_INET6) {
            expected_length = sizeof(struct sockaddr_in6);
#endif
        } else {
            continue;
        }
        if ((unsigned int)info->ai_addrlen < expected_length) continue;
        if (info->ai_protocol != 0 && info->ai_protocol != IPPROTO_TCP) continue;
    
        if (info->ai_family == AF_INET) {
            struct sockaddr_in* inet_addr = (struct sockaddr_in*)info->ai_addr;
            NPT_IpAddress address(ntohl(inet_addr->sin_addr.s_addr));
            addresses.Add(address);
        }
#if defined(NPT_CONFIG_ENABLE_IPV6)
        else if (info->ai_family == AF_INET6) {
            struct sockaddr_in6* inet_addr = (struct sockaddr_in6*)info->ai_addr;
            NPT_IpAddress address(NPT_IpAddress::IPV6, inet_addr->sin6_addr.s6_addr, 16, inet_addr->sin6_scope_id);
            addresses.Add(address);
        }
#endif
    }
    freeaddrinfo(infos);
    
    return NPT_SUCCESS;
}
Ejemplo n.º 2
0
/*----------------------------------------------------------------------
|       NPT_PSPQueue::Push
+---------------------------------------------------------------------*/
NPT_Result
NPT_PSPQueue::Push(NPT_QueueItem* item)
{
    // lock the mutex that protects the list
    m_Items.Lock();

    // check that we have not exceeded the max
    //if (m_MaxItems) {
    //    while (m_Items.GetItemCount() >= m_MaxItems) {
    //        // wait until some items have been removed
    //        //NPT_Debug(":: NPT_PSPQueue::Push - waiting for queue to empty\n");
    //        pthread_cond_wait(&m_CanPushOrPopCondition, &m_Mutex);
    //    }
    //}

    // add the item to the list
    m_Items.Add(item);

    // if the list was previously empty, signal the condition
    // to wake up the waiting thread
    //if (m_Items.GetItemCount() == 1) {    
    //    pthread_cond_signal(&m_CanPushOrPopCondition);
    //}

    // unlock the mutex
    m_Items.Unlock();

    return NPT_SUCCESS;
}
/*----------------------------------------------------------------------
|   NPT_File::GetRoots
+---------------------------------------------------------------------*/
NPT_Result
NPT_File::GetRoots(NPT_List<NPT_String>& roots)
{
    roots.Clear();
    roots.Add("/");
    return NPT_SUCCESS;
}
Ejemplo n.º 4
0
/*----------------------------------------------------------------------
|       NPT_PosixQueue::Push
+---------------------------------------------------------------------*/
NPT_Result
NPT_PosixQueue::Push(NPT_QueueItem* item, NPT_Timeout timeout)
{    
    struct     timespec timed;
    struct     timeval  now;

    // get current time from system
    if (gettimeofday(&now, NULL)) {
        return NPT_FAILURE;
    }

    now.tv_usec += timeout * 1000;
    if (now.tv_usec >= 1000000) {
        now.tv_sec += now.tv_usec / 1000000;
        now.tv_usec = now.tv_usec % 1000000;
    }

    // setup timeout
    timed.tv_sec  = now.tv_sec;
    timed.tv_nsec = now.tv_usec * 1000;

    // lock the mutex that protects the list
    if (pthread_mutex_lock(&m_Mutex)) {
        return NPT_FAILURE;
    }

    NPT_Result result = NPT_SUCCESS;
    // check that we have not exceeded the max
    if (m_MaxItems) {
        while (m_Items.GetItemCount() >= m_MaxItems) {
            // wait until some items have been removed
            //NPT_Debug(":: NPT_PosixQueue::Push - waiting for queue to empty\n");
            if (timeout == NPT_TIMEOUT_INFINITE) {
                pthread_cond_wait(&m_CanPushOrPopCondition, &m_Mutex);
            } else {
                int wait_res = pthread_cond_timedwait(&m_CanPushOrPopCondition, &m_Mutex, &timed);
                if (wait_res == ETIMEDOUT) {
                    result = NPT_ERROR_TIMEOUT;
                    break;
                }
            }
        }
    }

    // add the item to the list
    if (result == NPT_SUCCESS) {
        m_Items.Add(item);

        // if the list was previously empty, signal the condition
        // to wake up the waiting thread
        if (m_Items.GetItemCount() == 1) {    
            pthread_cond_signal(&m_CanPushOrPopCondition);
        }
    }

    // unlock the mutex
    pthread_mutex_unlock(&m_Mutex);

    return result;
}
Ejemplo n.º 5
0
NPT_List<const Object*> Container::getChildren() const
{
	NPT_List<const Object*> ls;
	for (NPT_Ordinal i = 0; i < childCount(); i++) {
		ls.Add(childAt(i));
	}
	return ls;
}
/*----------------------------------------------------------------------
|   NPT_File::ListDir
+---------------------------------------------------------------------*/
NPT_Result 
NPT_File::ListDir(const char*           path, 
                  NPT_List<NPT_String>& entries, 
                  NPT_Ordinal           start /* = 0 */, 
                  NPT_Cardinal          max   /* = 0 */)
{
    // default return value
    entries.Clear();
    
    // check the arguments
    if (path == NULL) return NPT_ERROR_INVALID_PARAMETERS;
    
    // list the entries
    DIR *directory = opendir(path);
    if (directory == NULL) return NPT_ERROR_NO_SUCH_ITEM;
    
    NPT_Cardinal count = 0;
    for (;;) {
        struct dirent* entry_pointer = NULL;
#if defined(NPT_CONFIG_HAVE_READDIR_R)
        struct dirent entry;
        int result = readdir_r(directory, &entry, &entry_pointer);
        if (result != 0 || entry_pointer == NULL) break;
#else
        entry_pointer = readdir(directory);
        if (entry_pointer == NULL) break;
#endif
        // ignore odd names
        if (entry_pointer->d_name[0] == '\0') continue;

        // ignore . and ..
        if (entry_pointer->d_name[0] == '.' && 
            entry_pointer->d_name[1] == '\0') {
            continue;
        }
        if (entry_pointer->d_name[0] == '.' && 
            entry_pointer->d_name[1] == '.' &&
            entry_pointer->d_name[2] == '\0') {
            continue;
        }        
        
        // continue if we still have some items to skip
        if (start > 0) {
            --start;
            continue;
        }
        entries.Add(NPT_String(entry_pointer->d_name));

        // stop when we have reached the maximum requested
        if (max && ++count == max) break;
    }
    
    closedir(directory);
    
    return NPT_SUCCESS;
}
Ejemplo n.º 7
0
/*----------------------------------------------------------------------
|       NPT_PosixQueue::Push
+---------------------------------------------------------------------*/
NPT_Result
NPT_PosixQueue::Push(NPT_QueueItem* item, NPT_Timeout timeout)
{
    struct timespec timed;
    if (timeout != NPT_TIMEOUT_INFINITE) {
        NPT_CHECK(GetTimeOut(timeout, timed));
    }

    // lock the mutex that protects the list
    if (pthread_mutex_lock(&m_Mutex)) {
        return NPT_FAILURE;
    }

    NPT_Result result = NPT_SUCCESS;
    // check that we have not exceeded the max
    if (m_MaxItems) {
        while (m_Items.GetItemCount() >= m_MaxItems) {
            // wait until we can push
            ++m_PushersWaitingCount;
            if (timeout == NPT_TIMEOUT_INFINITE) {
                pthread_cond_wait(&m_CanPushCondition, &m_Mutex);
                --m_PushersWaitingCount;
            } else {
                int wait_res = pthread_cond_timedwait(&m_CanPushCondition, 
                                                      &m_Mutex, 
                                                      &timed);
                --m_PushersWaitingCount;
                if (wait_res == ETIMEDOUT) {
                    result = NPT_ERROR_TIMEOUT;
                    break;
                }
            }

            if (m_Aborting) {
                result = NPT_ERROR_INTERRUPTED;
                break;
            }
        }
    }

    // add the item to the list
    if (result == NPT_SUCCESS) {
        m_Items.Add(item);

        // wake up any thread that may be waiting to pop
        if (m_PoppersWaitingCount) { 
            pthread_cond_broadcast(&m_CanPopCondition);
        }
    }

    // unlock the mutex
    pthread_mutex_unlock(&m_Mutex);

    return result;
}
Ejemplo n.º 8
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;
}
Ejemplo n.º 9
0
/*----------------------------------------------------------------------
|   NPT_String::Split
+---------------------------------------------------------------------*/
NPT_List<NPT_String> 
NPT_String::Split(const char* separator) const
{
    NPT_List<NPT_String> result;
    NPT_Size             separator_length = NPT_StringLength(separator);
    
    // sepcial case for empty separators
    if (separator_length == 0) {
        result.Add(*this);
        return result;
    }
    
    int current = 0;  
    int next;  
    do {
        next = Find(separator, current);
        unsigned int end = (next>=0?(unsigned int)next:GetLength());
        result.Add(SubString(current, end-current));
        current = next+separator_length;
    } while (next >= 0);
    
    return result;
}
/*----------------------------------------------------------------------
|   NPT_File::ListDir
+---------------------------------------------------------------------*/
NPT_Result 
NPT_File::ListDir(const char*           path, 
                  NPT_List<NPT_String>& entries, 
                  NPT_Ordinal           start /* = 0 */, 
                  NPT_Cardinal          max   /* = 0 */)
{
    NPT_WIN32_USE_CHAR_CONVERSION;

    // default return value
    entries.Clear();

    // check the arguments
    if (path == NULL || path[0] == '\0') return NPT_ERROR_INVALID_PARAMETERS;

    // construct a path name with a \* wildcard at the end
    NPT_String path_pattern = path;
    if (path_pattern.EndsWith("\\") || path_pattern.EndsWith("/")) {
        path_pattern += "*";
    } else {
        path_pattern += "\\*";
    }

    // list the entries
    WIN32_FIND_DATAW find_data;
    HANDLE find_handle = FindFirstFileW(NPT_WIN32_A2W(path_pattern.GetChars()), &find_data);
    if (find_handle == INVALID_HANDLE_VALUE) return MapError(GetLastError());
    NPT_Cardinal count = 0;
    do {
        if (NPT_File_ProcessFindData(&find_data)) {
            // continue if we still have entries to skip
            if (start > 0) {
                --start;
                continue;
            }
            entries.Add(NPT_WIN32_W2A(find_data.cFileName));

            // stop when we have reached the maximum requested
            if (max && ++count == max) return NPT_SUCCESS;
        }
    } while (FindNextFileW(find_handle, &find_data));
    DWORD last_error = GetLastError();
    FindClose(find_handle);
    if (last_error != ERROR_NO_MORE_FILES) return MapError(last_error);

    return NPT_SUCCESS;
}
/*----------------------------------------------------------------------
|   NPT_File::GetRoots
+---------------------------------------------------------------------*/
NPT_Result
NPT_File::GetRoots(NPT_List<NPT_String>& roots)
{
    roots.Clear();
#if defined(_WIN32_WCE) || defined(_XBOX)
    return NPT_ERROR_NOT_IMPLEMENTED;
#else
    DWORD drives = GetLogicalDrives();
    for (unsigned int i=0; i<26; i++) {
        if (drives & (1<<i)) {
            char drive_name[4] = {'A'+i, ':', '\\', 0};
            roots.Add(drive_name);
        }
    }
    return NPT_SUCCESS;
#endif
}
Ejemplo n.º 12
0
/*----------------------------------------------------------------------
|   NPT_Win32Queue::Push
+---------------------------------------------------------------------*/
NPT_Result
NPT_Win32Queue::Push(NPT_QueueItem* item, NPT_Timeout timeout)
{
    // lock the mutex that protects the list
    NPT_CHECK(m_Mutex.Lock());

    // check that we have not exceeded the max
    if (m_MaxItems) {
        while (m_Items.GetItemCount() >= m_MaxItems) {
            // we must wait until some items have been removed

            // reset the condition to indicate that the queue is full
            m_CanPushCondition->Reset();

            // unlock the mutex so that another thread can pop
            m_Mutex.Unlock();

            // wait for the condition to signal that we can push
            NPT_Result result = m_CanPushCondition->Wait(timeout);
            if (NPT_FAILED(result)) return result;

            // relock the mutex so that we can check the list again
            NPT_CHECK(m_Mutex.Lock());
        }
    }

    // add the item to the list
    m_Items.Add(item);

    // wake up the threads waiting to pop
    m_CanPopCondition->Signal();

    // unlock the mutex
    m_Mutex.Unlock();

    return NPT_SUCCESS;
}
Ejemplo n.º 13
0
void FrontEnd::processSsdpSearch(SsdpServerTask *task, Interface *intf, const NPT_DataBuffer& data, const NPT_SocketAddress& fromAddr)
{
	do {
		NPT_HttpRequest *req;
		NPT_InputStreamReference inputStream0(new NPT_MemoryStream(data.GetData(), data.GetDataSize()));
		NPT_BufferedInputStream inputStream(inputStream0);
		if (NPT_FAILED(NPT_HttpRequest::Parse(inputStream, NULL, req))) {
			break;
		}

		PtrHolder<NPT_HttpRequest> req1(req);
		if (req->GetMethod().Compare("M-SEARCH") != 0 || req->GetProtocol().Compare(NPT_HTTP_PROTOCOL_1_1) != 0 || req->GetUrl().GetPath().Compare("*") != 0) {
			break;
		}

		NPT_HttpHeader *hdrMan = req->GetHeaders().GetHeader("MAN");
		if (!hdrMan || hdrMan->GetValue().Compare("\"ssdp:discover\"") != 0) {
			break;
		}

		NPT_HttpHeader *hdrHost = req->GetHeaders().GetHeader("HOST");
		if (!hdrHost || (hdrHost->GetValue().Compare("239.255.255.250:1900") != 0 && hdrHost->GetValue().Compare("239.255.255.250") != 0)) {
			break;
		}

		int mx;
		NPT_HttpHeader *hdrMX = req->GetHeaders().GetHeader("MX");
		if (!hdrMX || NPT_FAILED(NPT_ParseInteger(hdrMX->GetValue(), mx)) || mx < 1) {
			break;
		}

		if (mx > 120) {
			mx = 120;
		}

		NPT_HttpHeader *hdrST = req->GetHeaders().GetHeader("ST");
		if (!hdrST) {
			break;
		}

		NPT_List<MatchContext*> matchList;

		NPT_UdpSocket sock(NPT_SOCKET_FLAG_CANCELLABLE);
		sock.Bind(NPT_SocketAddress(intf->m_context.m_ifAddr, 0));
		NPT_SharedVariable waitVar;
		waitVar.SetValue(0);

		{
			ReadLocker locker(m_dsLock);
			for (NPT_Ordinal i = 0; i < m_deviceImplList.GetItemCount(); i++) {
				NPT_List<DeviceImplInfo*>::Iterator it = m_deviceImplList.GetItem(i);
				DeviceImplInfo *info = *it;
				MatchContext *matchContext = new MatchContext();
				if (info->m_deviceImpl->match(hdrST->GetValue(), matchContext->matches)) {
					matchList.Add(matchContext);
					matchContext->deviceUuid = info->m_deviceImpl->uuid();
					matchContext->expireSeconds = info->m_deviceImpl->m_expireSeconds;
					matchContext->descPath = info->m_deviceImpl->m_descPath;
					matchContext->httpRoot = info->m_context.m_httpRoot;
				} else {
					delete matchContext;
				}
			}
		}

		SsdpSearchAbortCallback abortCallback(&sock, &waitVar);
		if (task->registerAbortCallback(&abortCallback)) {

			for (NPT_Ordinal i = 0; i < matchList.GetItemCount(); i++) {
				MatchContext *matchContext = *matchList.GetItem(i);

				NPT_String location = NPT_String::Format("http://%s:%d%s%s", intf->m_context.m_ifAddr.ToString().GetChars(), intf->m_context.m_httpPort, matchContext->httpRoot.GetChars(), matchContext->descPath.GetChars());

				bool broken = false;

				for (NPT_Ordinal j = 0; j < matchContext->matches.GetItemCount(); j++) {
					NPT_List<DeviceImplMatch>::Iterator it2 = matchContext->matches.GetItem(j);

					NPT_Timeout timeout = NPT_System::GetRandomInteger() % (mx * 1000);
					// TODO: wait or not ???
					timeout = 0;
					if (NPT_SUCCEEDED(waitVar.WaitWhileEquals(0, timeout))) {
						break;
					}

					{
						ReadLocker locker(m_dsLock);
						if (m_deviceImplIndex.HasKey(matchContext->deviceUuid)) {
							NPT_TimeStamp ts;
							NPT_System::GetCurrentTimeStamp(ts);
							NPT_String dateStr = NPT_DateTime(ts).ToString(NPT_DateTime::FORMAT_RFC_1123);
							NPT_String resp = NPT_String::Format("HTTP/1.1 200 OK\r\nCACHE-CONTROL: max-age=%d\r\nDATE: %s\r\nEXT: \r\nLOCATION: %s\r\nSERVER: %s\r\nST: %s\r\nUSN: %s\r\nCUSTOM:%s\r\n\r\n",
														matchContext->expireSeconds, dateStr.GetChars(), location.GetChars(), m_serverHeader.GetChars(), it2->m_st.GetChars(), it2->m_usn.GetChars(), m_DevName.GetChars());
							NPT_DataBuffer packet(resp.GetChars(), resp.GetLength(), false);
							sock.Send(packet, &fromAddr);
						}
					}
				}

				if (broken) {
					break;
				}
			}

			task->unregisterAbortCallback(&abortCallback);
		}

		matchList.Apply(NPT_ObjectDeleter<MatchContext>());
	} while (false);
}
Ejemplo n.º 14
0
/*----------------------------------------------------------------------
|       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;
}
Ejemplo n.º 16
0
Archivo: UPnP.cpp Proyecto: MrMC/mrmc
void CUPnP::RegisterUserdata(void* ptr)
{
  NPT_AutoLock lock(g_UserDataLock);
  g_UserData.Add(ptr);
}
Ejemplo n.º 17
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;
}
Ejemplo n.º 18
0
void FrontEnd::broadcastLocked(DeviceImplInfo *deviceInfo, bool avail)
{
	NPT_TimeStamp ts;
	NPT_System::GetCurrentTimeStamp(ts);

	NPT_List<MatchContext*> matchList;

	if (deviceInfo) {
		deviceInfo->m_updateTS = ts;
		MatchContext *matchContext = new MatchContext();
		if (deviceInfo->m_deviceImpl->match("ssdp:all", matchContext->matches)) {
			matchList.Add(matchContext);
			matchContext->deviceUuid = deviceInfo->m_deviceImpl->uuid();
			matchContext->expireSeconds = deviceInfo->m_deviceImpl->m_expireSeconds;
			matchContext->descPath = deviceInfo->m_deviceImpl->m_descPath;
			matchContext->httpRoot = deviceInfo->m_context.m_httpRoot;
		} else {
			delete matchContext;
		}
	} else {
		for (NPT_Ordinal i = 0; i < m_deviceImplList.GetItemCount(); i++) {
			NPT_List<DeviceImplInfo*>::Iterator it = m_deviceImplList.GetItem(i);
			DeviceImplInfo *info = *it;
			info->m_updateTS = ts;
			MatchContext *matchContext = new MatchContext();
			if (info->m_deviceImpl->match("ssdp:all", matchContext->matches)) {
				matchList.Add(matchContext);
				matchContext->deviceUuid = info->m_deviceImpl->uuid();
				matchContext->expireSeconds = info->m_deviceImpl->m_expireSeconds;
				matchContext->descPath = info->m_deviceImpl->m_descPath;
				matchContext->httpRoot = info->m_context.m_httpRoot;
			} else {
				delete matchContext;
			}
		}
	}

	NPT_SocketAddress targetAddr(NPT_IpAddress(239, 255, 255, 250), 1900);

	for (NPT_Ordinal i = 0; i < m_ifList.GetItemCount(); i++) {
		Interface *nif = *m_ifList.GetItem(i);
		NPT_UdpSocket sock(NPT_SOCKET_FLAG_CANCELLABLE);
		sock.Bind(NPT_SocketAddress(nif->m_context.m_ifAddr, 0));
		for (NPT_Ordinal j = 0; j < matchList.GetItemCount(); j++) {
			MatchContext *matchContext = *matchList.GetItem(j);
			NPT_String location = NPT_String::Format("http://%s:%d%s%s", nif->m_context.m_ifAddr.ToString().GetChars(), nif->m_context.m_httpPort, matchContext->httpRoot.GetChars(), matchContext->descPath.GetChars());
			for (NPT_Ordinal k = 0; k < matchContext->matches.GetItemCount(); k++) {
				NPT_List<DeviceImplMatch>::Iterator it2 = matchContext->matches.GetItem(k);
				NPT_String msg;
				if (avail) {
					//msg = NPT_String::Format("NOTIFY * HTTP/1.1\r\nHOST: 239.255.255.250:1900\r\nCACHE-CONTROL: max-age=%d\r\nLOCATION: %s\r\nNT: %s\r\nNTS: ssdp:alive\r\nSERVER: %s\r\nUSN: %s\r\n\r\n",
					//		matchContext->expireSeconds, location.GetChars(), it2->m_st.GetChars(), m_serverHeader.GetChars(), it2->m_usn.GetChars());
					msg = NPT_String::Format("NOTIFY * HTTP/1.1\r\nHOST: 239.255.255.250:1900\r\nCACHE-CONTROL: max-age=%d\r\nLOCATION: %s\r\nNT: %s\r\nNTS: ssdp:alive\r\nSERVER: %s\r\nUSN: %s\r\nCUSTOM:%s\r\n\r\n",
											matchContext->expireSeconds, location.GetChars(), it2->m_st.GetChars(), m_serverHeader.GetChars(), it2->m_usn.GetChars(), m_DevName.GetChars());
				} else {
					msg = NPT_String::Format("NOTIFY * HTTP/1.1\r\nHOST: 239.255.255.250:1900\r\nNT: %s\r\nNTS: ssdp:byebye\r\nUSN: %s\r\nCUSTOM:%s\r\n\r\n",
											it2->m_st.GetChars(), it2->m_usn.GetChars(), m_DevName.GetChars());
				}
				NPT_DataBuffer packet(msg.GetChars(), msg.GetLength(), false);
				sock.Send(packet, &targetAddr);
			}
		}
	}

	matchList.Apply(NPT_ObjectDeleter<MatchContext>());
}
Ejemplo n.º 19
0
/*----------------------------------------------------------------------
|   NPT_NetworkInterface::GetNetworkInterfaces
+---------------------------------------------------------------------*/
NPT_Result
NPT_NetworkInterface::GetNetworkInterfaces(NPT_List<NPT_NetworkInterface*>& interfaces)
{
    IP_ADAPTER_ADDRESSES* iface_list = NULL;
    ULONG                 size = sizeof(IP_ADAPTER_INFO);

    // get the interface table
    for(;;) {
        iface_list = (IP_ADAPTER_ADDRESSES*)malloc(size);
        DWORD result = GetAdaptersAddresses(AF_INET,
                                            0,
                                            NULL,
                                            iface_list, &size);
        if (result == NO_ERROR) {
            break;
        } else {
            // free and try again
            free(iface_list);
            if (result != ERROR_BUFFER_OVERFLOW) {
                return NPT_FAILURE;
            }
        }
    }

    // iterate over the interfaces
    for (IP_ADAPTER_ADDRESSES* iface = iface_list; iface; iface = iface->Next) {
        // skip this interface if it is not up
        if (iface->OperStatus != IfOperStatusUp) continue;

        // get the interface type and mac address
        NPT_MacAddress::Type mac_type;
        switch (iface->IfType) {
            case IF_TYPE_ETHERNET_CSMACD:   mac_type = NPT_MacAddress::TYPE_ETHERNET; break;
            case IF_TYPE_SOFTWARE_LOOPBACK: mac_type = NPT_MacAddress::TYPE_LOOPBACK; break;
            case IF_TYPE_PPP:               mac_type = NPT_MacAddress::TYPE_PPP;      break;
            default:                        mac_type = NPT_MacAddress::TYPE_UNKNOWN;  break;
        }
        NPT_MacAddress mac(mac_type, iface->PhysicalAddress, iface->PhysicalAddressLength);

        // compute interface flags
        NPT_Flags flags = 0;
        if (!(iface->Flags & IP_ADAPTER_NO_MULTICAST)) flags |= NPT_NETWORK_INTERFACE_FLAG_MULTICAST;
        if (iface->IfType == IF_TYPE_SOFTWARE_LOOPBACK) flags |= NPT_NETWORK_INTERFACE_FLAG_LOOPBACK;
        if (iface->IfType == IF_TYPE_PPP) flags |= NPT_NETWORK_INTERFACE_FLAG_POINT_TO_POINT;

        // compute the unicast address (only the first one is supported for now)
        NPT_IpAddress primary_address;
        if (iface->FirstUnicastAddress) {
            if (iface->FirstUnicastAddress->Address.lpSockaddr == NULL) continue;
            if (iface->FirstUnicastAddress->Address.iSockaddrLength != sizeof(SOCKADDR_IN)) continue;
            SOCKADDR_IN* address = (SOCKADDR_IN*)iface->FirstUnicastAddress->Address.lpSockaddr;
            if (address->sin_family != AF_INET) continue;
            primary_address.Set(ntohl(address->sin_addr.s_addr));
        }
        NPT_IpAddress broadcast_address; // not supported yet
        NPT_IpAddress netmask;           // not supported yet

        // convert the interface name to UTF-8
        // BUG in Wine: FriendlyName is NULL
        unsigned int iface_name_length = (unsigned int)iface->FriendlyName?wcslen(iface->FriendlyName):0;
        char* iface_name = new char[4*iface_name_length+1];
        int result = WideCharToMultiByte(
            CP_UTF8, 0, iface->FriendlyName, iface_name_length,
            iface_name, 4*iface_name_length+1,
            NULL, NULL);
        if (result > 0) {
            iface_name[result] = '\0';
        } else {
            iface_name[0] = '\0';
        }

        // create an interface descriptor
        NPT_NetworkInterface* iface_object = new NPT_NetworkInterface(iface_name, mac, flags);
        NPT_NetworkInterfaceAddress iface_address(
            primary_address,
            broadcast_address,
            NPT_IpAddress::Any,
            netmask);
        iface_object->AddAddress(iface_address);  
    
        // cleanup 
        delete[] iface_name;
         
        // add the interface to the list
        interfaces.Add(iface_object);   
    }

    free(iface_list);
    return NPT_SUCCESS;
}