Beispiel #1
0
s32 cellNetCtlGetInfo(s32 code, vm::ptr<CellNetCtlInfo> info)
{
    cellNetCtl.todo("cellNetCtlGetInfo(code=0x%x (%s), info=*0x%x)", code, InfoCodeToName(code), info);

    if (code == CELL_NET_CTL_INFO_MTU)
    {
#ifdef _WIN32
        ULONG bufLen = sizeof(PIP_ADAPTER_ADDRESSES) + 1;
        PIP_ADAPTER_ADDRESSES pAddresses = (PIP_ADAPTER_ADDRESSES)malloc(bufLen);
        DWORD ret;

        ret = GetAdaptersAddresses(AF_INET, GAA_FLAG_INCLUDE_PREFIX, nullptr, pAddresses, &bufLen);

        if (ret == ERROR_BUFFER_OVERFLOW)
        {
            cellNetCtl.error("cellNetCtlGetInfo(INFO_MTU): GetAdaptersAddresses buffer overflow.");
            free(pAddresses);
            pAddresses = (PIP_ADAPTER_ADDRESSES)malloc(bufLen);

            if (pAddresses == nullptr)
            {
                cellNetCtl.error("cellNetCtlGetInfo(INFO_MTU): Unable to allocate memory for pAddresses.");
                return CELL_NET_CTL_ERROR_NET_CABLE_NOT_CONNECTED;
            }
        }

        ret = GetAdaptersAddresses(AF_INET, GAA_FLAG_INCLUDE_PREFIX, nullptr, pAddresses, &bufLen);

        if (ret == NO_ERROR)
        {
            PIP_ADAPTER_ADDRESSES pCurrAddresses = pAddresses;

            for (int c = 0; c < rpcs3::config.misc.net._interface.value(); c++)
            {
                pCurrAddresses = pCurrAddresses->Next;
            }

            info->mtu = pCurrAddresses->Mtu;
        }
        else
        {
            cellNetCtl.error("cellNetCtlGetInfo(INFO_MTU): Call to GetAdaptersAddresses failed. (%d)", ret);
            info->mtu = 1500; // Seems to be the default value on Windows 10.
        }

        free(pAddresses);
#else
        struct ifaddrs *ifaddr, *ifa;
        s32 family, n;

        if (getifaddrs(&ifaddr) == -1)
        {
            cellNetCtl.error("cellNetCtlGetInfo(INFO_MTU): Call to getifaddrs returned negative.");
        }

        for (ifa = ifaddr, n = 0; ifa != nullptr; ifa = ifa->ifa_next, n++)
        {
            if (ifa->ifa_addr == nullptr)
            {
                continue;
            }

            if (n < rpcs3::config.misc.net._interface.value())
            {
                continue;
            }

            family = ifa->ifa_addr->sa_family;

            if (family == AF_INET)
            {
                u32 fd = open("/proc/net/dev", O_RDONLY);
                struct ifreq freq;

                if (ioctl(fd, SIOCGIFMTU, &freq) == -1)
                {
                    cellNetCtl.error("cellNetCtlGetInfo(INFO_MTU): Call to ioctl failed.");
                }
                else
                {
                    info->mtu = (u32)freq.ifr_mtu;
                }

                close(fd);
            }
        }

        freeifaddrs(ifaddr);
#endif
    }
    else if (code == CELL_NET_CTL_INFO_LINK)
    {
        if (rpcs3::config.misc.net.status.value() == misc_net_status::ip_obtained)
        {
            info->link = CELL_NET_CTL_LINK_CONNECTED;
        }
        else
        {
            info->link = CELL_NET_CTL_LINK_DISCONNECTED;
        }
    }
    else if (code == CELL_NET_CTL_INFO_IP_ADDRESS)
    {
        // 0.0.0.0 seems to be the default address when no ethernet cables are connected to the PS3
        strcpy_trunc(info->ip_address, "0.0.0.0");

#ifdef _WIN32
        ULONG bufLen = sizeof(IP_ADAPTER_INFO);
        PIP_ADAPTER_INFO pAdapterInfo = (IP_ADAPTER_INFO*)malloc(bufLen);
        DWORD ret;

        ret = GetAdaptersInfo(pAdapterInfo, &bufLen);

        if (ret == ERROR_BUFFER_OVERFLOW)
        {
            cellNetCtl.error("cellNetCtlGetInfo(IP_ADDRESS): GetAdaptersInfo buffer overflow.");
            free(pAdapterInfo);
            pAdapterInfo = (IP_ADAPTER_INFO*)malloc(bufLen);

            if (pAdapterInfo == nullptr)
            {
                cellNetCtl.error("cellNetCtlGetInfo(IP_ADDRESS): Unable to allocate memory for pAddresses.");
                return CELL_NET_CTL_ERROR_NET_CABLE_NOT_CONNECTED;
            }
        }

        ret = GetAdaptersInfo(pAdapterInfo, &bufLen);

        if (ret == NO_ERROR)
        {
            PIP_ADAPTER_INFO pAdapter = pAdapterInfo;

            for (int c = 0; c < rpcs3::config.misc.net._interface.value(); c++)
            {
                pAdapter = pAdapter->Next;
            }

            strcpy_trunc(info->ip_address, pAdapter->IpAddressList.IpAddress.String);
        }
        else
        {
            cellNetCtl.error("cellNetCtlGetInfo(IP_ADDRESS): Call to GetAdaptersInfo failed. (%d)", ret);
        }

        free(pAdapterInfo);
#else
        struct ifaddrs *ifaddr, *ifa;
        s32 family, n;

        if (getifaddrs(&ifaddr) == -1)
        {
            cellNetCtl.error("cellNetCtlGetInfo(IP_ADDRESS): Call to getifaddrs returned negative.");
        }

        for (ifa = ifaddr, n = 0; ifa != nullptr; ifa = ifa->ifa_next, n++)
        {
            if (ifa->ifa_addr == nullptr)
            {
                continue;
            }

            if (n < rpcs3::config.misc.net._interface.value())
            {
                continue;
            }

            family = ifa->ifa_addr->sa_family;

            if (family == AF_INET)
            {
                strcpy_trunc(info->ip_address, ifa->ifa_addr->sa_data);
            }
        }

        freeifaddrs(ifaddr);
#endif
    }
    else if (code == CELL_NET_CTL_INFO_NETMASK)
    {
#ifdef _WIN32
        ULONG bufLen = sizeof(IP_ADAPTER_INFO) + 1;
        PIP_ADAPTER_INFO pAdapterInfo = (PIP_ADAPTER_INFO)malloc(bufLen);
        DWORD ret;

        ret = GetAdaptersInfo(pAdapterInfo, &bufLen);

        if (ret == ERROR_BUFFER_OVERFLOW)
        {
            cellNetCtl.error("cellNetCtlGetInfo(INFO_NETMASK): GetAdaptersInfo buffer overflow.");
            free(pAdapterInfo);
            pAdapterInfo = (IP_ADAPTER_INFO*)malloc(bufLen);

            if (pAdapterInfo == nullptr)
            {
                cellNetCtl.error("cellNetCtlGetInfo(INFO_NETMASK): Unable to allocate memory for pAddresses.");
                return CELL_NET_CTL_ERROR_NET_CABLE_NOT_CONNECTED;
            }
        }

        ret = GetAdaptersInfo(pAdapterInfo, &bufLen);

        if (ret == NO_ERROR)
        {
            PIP_ADAPTER_INFO pAdapter = pAdapterInfo;

            for (int c = 0; c < rpcs3::config.misc.net._interface.value(); c++)
            {
                pAdapter = pAdapter->Next;
            }

            for (int c = 0; c < 4; c++)
            {
                info->netmask[c] = (s8)pAdapter->IpAddressList.IpMask.String;
            }
        }
        else
        {
            cellNetCtl.error("cellNetCtlGetInfo(INFO_NETMASK): Call to GetAdaptersInfo failed. (%d)", ret);
            // TODO: Is this the default netmask?
            info->netmask[0] = 255;
            info->netmask[1] = 255;
            info->netmask[2] = 255;
            info->netmask[3] = 0;
        }

        free(pAdapterInfo);
#else
        struct ifaddrs *ifaddr, *ifa;
        s32 family, n;

        if (getifaddrs(&ifaddr) == -1)
        {
            cellNetCtl.error("cellNetCtlGetInfo(INFO_NETMASK): Call to getifaddrs returned negative.");
        }

        for (ifa = ifaddr, n = 0; ifa != nullptr; ifa = ifa->ifa_next, n++)
        {
            if (ifa->ifa_addr == nullptr)
            {
                continue;
            }

            if (n < rpcs3::config.misc.net._interface.value())
            {
                continue;
            }

            family = ifa->ifa_addr->sa_family;

            if (family == AF_INET)
            {
                strcpy_trunc(info->ip_address, ifa->ifa_netmask->sa_data);
            }
        }

        freeifaddrs(ifaddr);
#endif
    }

    return CELL_OK;
}
Beispiel #2
0
s32 cellNetCtlGetInfo(s32 code, vm::ptr<CellNetCtlInfo> info)
{
	cellNetCtl.Todo("cellNetCtlGetInfo(code=0x%x (%s), info=*0x%x)", code, InfoCodeToName(code), info);

	if (code == CELL_NET_CTL_INFO_IP_ADDRESS)
	{
#ifdef _WIN32
		PIP_ADAPTER_INFO pAdapterInfo;
		pAdapterInfo = (IP_ADAPTER_INFO*) malloc(sizeof(IP_ADAPTER_INFO));
		ULONG buflen = sizeof(IP_ADAPTER_INFO);

		if (GetAdaptersInfo(pAdapterInfo, &buflen) == ERROR_BUFFER_OVERFLOW)
		{
			free(pAdapterInfo);
			pAdapterInfo = (IP_ADAPTER_INFO*) malloc(buflen);
		}

		if (GetAdaptersInfo(pAdapterInfo, &buflen) == NO_ERROR)
		{
			PIP_ADAPTER_INFO pAdapter = pAdapterInfo;

			for (int c = 0; c < Ini.NETInterface.GetValue(); c++)
			{
				pAdapter = pAdapter->Next;
			}

			strcpy_trunc(info->ip_address, pAdapter->IpAddressList.IpAddress.String);
		}
		else
		{
			cellNetCtl.Error("cellNetCtlGetInfo(IP_ADDRESS): Call to GetAdaptersInfo failed.");
			// 0.0.0.0 seems to be the default address when no ethernet cables are connected to the PS3
			strcpy_trunc(info->ip_address, "0.0.0.0");
		}
#else
		struct ifaddrs *ifaddr, *ifa;
		int family, s, n;
		char host[NI_MAXHOST];

		if (getifaddrs(&ifaddr) == -1)
		{
			LOG_ERROR(HLE, "Call to getifaddrs returned negative.");
		}

		for (ifa = ifaddr, n = 0; ifa != NULL; ifa = ifa->ifa_next, n++)
		{
			if (ifa->ifa_addr == NULL)
			{
				continue;
			}

			if (n < Ini.NETInterface.GetValue())
			{
				continue;
			}

			family = ifa->ifa_addr->sa_family;

			if (family == AF_INET)
			{
				strcpy_trunc(info->ip_address, ifa->ifa_addr->sa_data);
			}
		}

		freeifaddrs(ifaddr);
#endif
	}
	else if (code == CELL_NET_CTL_INFO_NETMASK)
	{
#ifdef _WIN32
		PIP_ADAPTER_INFO pAdapterInfo;
		pAdapterInfo = (IP_ADAPTER_INFO*)malloc(sizeof(IP_ADAPTER_INFO));
		ULONG buflen = sizeof(IP_ADAPTER_INFO);

		if (GetAdaptersInfo(pAdapterInfo, &buflen) == ERROR_BUFFER_OVERFLOW)
		{
			free(pAdapterInfo);
			pAdapterInfo = (IP_ADAPTER_INFO*)malloc(buflen);
		}

		if (GetAdaptersInfo(pAdapterInfo, &buflen) == NO_ERROR)
		{
			PIP_ADAPTER_INFO pAdapter = pAdapterInfo;

			for (int c = 0; c < Ini.NETInterface.GetValue(); c++)
			{
				pAdapter = pAdapter->Next;
			}

			strcpy_trunc(info->ip_address, pAdapter->IpAddressList.IpMask.String);
		}
		else
		{
			cellNetCtl.Error("cellNetCtlGetInfo(INFO_NETMASK): Call to GetAdaptersInfo failed.");
			// TODO: What would be the default netmask? 255.255.255.0?
		}
#else
		struct ifaddrs *ifaddr, *ifa;
		int family, s, n;
		char host[NI_MAXHOST];

		if (getifaddrs(&ifaddr) == -1)
		{
			LOG_ERROR(HLE, "Call to getifaddrs returned negative.");
		}

		for (ifa = ifaddr, n = 0; ifa != NULL; ifa = ifa->ifa_next, n++)
		{
			if (ifa->ifa_addr == NULL)
			{
				continue;
			}

			if (n < Ini.NETInterface.GetValue())
			{
				continue;
			}

			family = ifa->ifa_addr->sa_family;

			if (family == AF_INET)
			{
				strcpy_trunc(info->ip_address, ifa->ifa_netmask->sa_data);
			}
	}

		freeifaddrs(ifaddr);
#endif
	}

	return CELL_OK;
}