static void vboxNetAdpDarwinComposeUUID(PVBOXNETADP pThis, PRTUUID pUuid) { /* Generate UUID from name and MAC address. */ RTUuidClear(pUuid); memcpy(pUuid->au8, "vboxnet", 7); pUuid->Gen.u8ClockSeqHiAndReserved = (pUuid->Gen.u8ClockSeqHiAndReserved & 0x3f) | 0x80; pUuid->Gen.u16TimeHiAndVersion = (pUuid->Gen.u16TimeHiAndVersion & 0x0fff) | 0x4000; pUuid->Gen.u8ClockSeqLow = pThis->iUnit; vboxNetAdpComposeMACAddress(pThis, (PRTMAC)pUuid->Gen.au8Node); }
int main(int argc, char **argv) { RTTEST hTest; int rc = RTTestInitAndCreate("tstRTUuid", &hTest); if (rc) return rc; RTTestBanner(hTest); #define CHECK_RC() \ do { if (RT_FAILURE(rc)) { RTTestFailed(hTest, "line %d: rc=%Rrc", __LINE__, rc); } } while (0) RTTestSub(hTest, "RTUuidClear & RTUuisIsNull"); RTUUID UuidNull; rc = RTUuidClear(&UuidNull); CHECK_RC(); RTTEST_CHECK(hTest, RTUuidIsNull(&UuidNull)); RTTEST_CHECK(hTest, RTUuidCompare(&UuidNull, &UuidNull) == 0); RTTestSub(hTest, "RTUuidCreate"); RTUUID Uuid; rc = RTUuidCreate(&Uuid); CHECK_RC(); RTTEST_CHECK(hTest, !RTUuidIsNull(&Uuid)); RTTEST_CHECK(hTest, RTUuidCompare(&Uuid, &Uuid) == 0); RTTEST_CHECK(hTest, RTUuidCompare(&Uuid, &UuidNull) > 0); RTTEST_CHECK(hTest, RTUuidCompare(&UuidNull, &Uuid) < 0); RTTestSub(hTest, "RTUuidToStr"); char sz[RTUUID_STR_LENGTH]; rc = RTUuidToStr(&Uuid, sz, sizeof(sz)); CHECK_RC(); RTTEST_CHECK(hTest, strlen(sz) == RTUUID_STR_LENGTH - 1); RTTestPrintf(hTest, RTTESTLVL_INFO, "UUID=%s\n", sz); RTTestSub(hTest, "RTUuidFromStr"); RTUUID Uuid2; rc = RTUuidFromStr(&Uuid2, sz); CHECK_RC(); RTTEST_CHECK(hTest, RTUuidCompare(&Uuid, &Uuid2) == 0); char *psz = (char *)RTTestGuardedAllocTail(hTest, RTUUID_STR_LENGTH); if (psz) { RTStrPrintf(psz, RTUUID_STR_LENGTH, "%s", sz); RTTESTI_CHECK_RC(RTUuidFromStr(&Uuid2, psz), VINF_SUCCESS); RTTEST_CHECK(hTest, RTUuidCompare(&Uuid, &Uuid2) == 0); for (unsigned off = 1; off < RTUUID_STR_LENGTH; off++) { char *psz2 = psz + off; RTStrPrintf(psz2, RTUUID_STR_LENGTH - off, "%s", sz); RTTESTI_CHECK_RC(RTUuidFromStr(&Uuid2, psz2), VERR_INVALID_UUID_FORMAT); } RTTestGuardedFree(hTest, psz); } RTUuidClear(&Uuid2); char sz2[RTUUID_STR_LENGTH + 2]; RTStrPrintf(sz2, sizeof(sz2), "{%s}", sz); rc = RTUuidFromStr(&Uuid2, sz2); CHECK_RC(); RTTEST_CHECK(hTest, RTUuidCompare(&Uuid, &Uuid2) == 0); psz = (char *)RTTestGuardedAllocTail(hTest, RTUUID_STR_LENGTH + 2); if (psz) { RTStrPrintf(psz, RTUUID_STR_LENGTH + 2, "{%s}", sz); RTTESTI_CHECK_RC(RTUuidFromStr(&Uuid2, psz), VINF_SUCCESS); RTTEST_CHECK(hTest, RTUuidCompare(&Uuid, &Uuid2) == 0); for (unsigned off = 1; off < RTUUID_STR_LENGTH + 2; off++) { char *psz2 = psz + off; RTStrPrintf(psz2, RTUUID_STR_LENGTH + 2 - off, "{%s}", sz); RTTESTI_CHECK_RC(RTUuidFromStr(&Uuid2, psz2), VERR_INVALID_UUID_FORMAT); } RTTestGuardedFree(hTest, psz); } RTTestSub(hTest, "RTUuidToUtf16"); RTUTF16 wsz[RTUUID_STR_LENGTH]; rc = RTUuidToUtf16(&Uuid, wsz, sizeof(wsz)); CHECK_RC(); RTTEST_CHECK(hTest, RTUtf16Len(wsz) == RTUUID_STR_LENGTH - 1); RTTestSub(hTest, "RTUuidFromUtf16"); rc = RTUuidFromUtf16(&Uuid2, wsz); CHECK_RC(); RTTEST_CHECK(hTest, RTUuidCompare(&Uuid, &Uuid2) == 0); RTUTF16 *pwsz; rc = RTStrToUtf16(sz2, &pwsz); RTTEST_CHECK(hTest, rc == VINF_SUCCESS); if (RT_SUCCESS(rc)) { RTTESTI_CHECK_RC(RTUuidFromUtf16(&Uuid2, pwsz), VINF_SUCCESS); RTTEST_CHECK(hTest, RTUuidCompare(&Uuid, &Uuid2) == 0); RTUTF16 *pwsz2 = (RTUTF16*)RTTestGuardedAllocTail(hTest, 2 * (RTUUID_STR_LENGTH + 2)); if (pwsz2) { memcpy(pwsz2, pwsz, 2 * (RTUUID_STR_LENGTH + 2)); RTTESTI_CHECK_RC(RTUuidFromUtf16(&Uuid2, pwsz2), VINF_SUCCESS); RTTEST_CHECK(hTest, RTUuidCompare(&Uuid, &Uuid2) == 0); for (unsigned off = 1; off < RTUUID_STR_LENGTH + 2; off++) { RTUTF16 *pwsz3 = pwsz2 + off; memcpy(pwsz3, pwsz, 2 * (RTUUID_STR_LENGTH + 1 - off)); pwsz3[RTUUID_STR_LENGTH + 1 - off] = 0; RTTESTI_CHECK_RC(RTUuidFromUtf16(&Uuid2, pwsz3), VERR_INVALID_UUID_FORMAT); } RTTestGuardedFree(hTest, pwsz2); } RTUtf16Free(pwsz); } RTTestSub(hTest, "RTUuidCompareStr"); RTTEST_CHECK(hTest, RTUuidCompareStr(&Uuid, sz) == 0); RTTEST_CHECK(hTest, RTUuidCompareStr(&Uuid, "00000000-0000-0000-0000-000000000000") > 0); RTTEST_CHECK(hTest, RTUuidCompareStr(&UuidNull, "00000000-0000-0000-0000-000000000000") == 0); RTTestSub(hTest, "RTUuidCompare2Strs"); RTTEST_CHECK(hTest, RTUuidCompare2Strs(sz, sz) == 0); RTTEST_CHECK(hTest, RTUuidCompare2Strs(sz, "00000000-0000-0000-0000-000000000000") > 0); RTTEST_CHECK(hTest, RTUuidCompare2Strs("00000000-0000-0000-0000-000000000000", sz) < 0); RTTEST_CHECK(hTest, RTUuidCompare2Strs("00000000-0000-0000-0000-000000000000", "00000000-0000-0000-0000-000000000000") == 0); RTTEST_CHECK(hTest, RTUuidCompare2Strs("d95d883b-f91d-4ce5-a5c5-d08bb6a85dec", "a56193c7-3e0b-4c03-9d66-56efb45082f7") > 0); RTTEST_CHECK(hTest, RTUuidCompare2Strs("a56193c7-3e0b-4c03-9d66-56efb45082f7", "d95d883b-f91d-4ce5-a5c5-d08bb6a85dec") < 0); /* * Check the binary representation. */ RTTestSub(hTest, "Binary representation"); RTUUID Uuid3; Uuid3.au8[0] = 0x01; Uuid3.au8[1] = 0x23; Uuid3.au8[2] = 0x45; Uuid3.au8[3] = 0x67; Uuid3.au8[4] = 0x89; Uuid3.au8[5] = 0xab; Uuid3.au8[6] = 0xcd; Uuid3.au8[7] = 0x4f; Uuid3.au8[8] = 0x10; Uuid3.au8[9] = 0xb2; Uuid3.au8[10] = 0x54; Uuid3.au8[11] = 0x76; Uuid3.au8[12] = 0x98; Uuid3.au8[13] = 0xba; Uuid3.au8[14] = 0xdc; Uuid3.au8[15] = 0xfe; Uuid3.Gen.u8ClockSeqHiAndReserved = (Uuid3.Gen.u8ClockSeqHiAndReserved & 0x3f) | 0x80; Uuid3.Gen.u16TimeHiAndVersion = (Uuid3.Gen.u16TimeHiAndVersion & 0x0fff) | 0x4000; const char *pszUuid3 = "67452301-ab89-4fcd-90b2-547698badcfe"; rc = RTUuidToStr(&Uuid3, sz, sizeof(sz)); CHECK_RC(); RTTEST_CHECK(hTest, strcmp(sz, pszUuid3) == 0); rc = RTUuidFromStr(&Uuid, pszUuid3); CHECK_RC(); RTTEST_CHECK(hTest, RTUuidCompare(&Uuid, &Uuid3) == 0); RTTEST_CHECK(hTest, memcmp(&Uuid3, &Uuid, sizeof(Uuid)) == 0); /* * checking the clock seq and time hi and version bits... */ RTTestSub(hTest, "Clock seq, time hi, version bits"); RTUUID Uuid4Changes; Uuid4Changes.au64[0] = 0; Uuid4Changes.au64[1] = 0; RTUUID Uuid4Prev; RTUuidCreate(&Uuid4Prev); for (unsigned i = 0; i < 1024; i++) { RTUUID Uuid4; RTUuidCreate(&Uuid4); Uuid4Changes.au64[0] |= Uuid4.au64[0] ^ Uuid4Prev.au64[0]; Uuid4Changes.au64[1] |= Uuid4.au64[1] ^ Uuid4Prev.au64[1]; #if 0 /** @todo make a bit string/dumper similar to %Rhxs/d. */ RTPrintf("tstUuid: %d %d %d %d-%d %d %d %d %d %d %d %d-%d %d %d %d ; %d %d %d %d-%d %d %d %d %d %d %d %d-%d %d %d %d\n", !!(Uuid4.Gen.u16ClockSeq & RT_BIT(0)), !!(Uuid4.Gen.u16ClockSeq & RT_BIT(1)), !!(Uuid4.Gen.u16ClockSeq & RT_BIT(2)), !!(Uuid4.Gen.u16ClockSeq & RT_BIT(3)), !!(Uuid4.Gen.u16ClockSeq & RT_BIT(4)), !!(Uuid4.Gen.u16ClockSeq & RT_BIT(5)), !!(Uuid4.Gen.u16ClockSeq & RT_BIT(6)), !!(Uuid4.Gen.u16ClockSeq & RT_BIT(7)), !!(Uuid4.Gen.u16ClockSeq & RT_BIT(8)), !!(Uuid4.Gen.u16ClockSeq & RT_BIT(9)), !!(Uuid4.Gen.u16ClockSeq & RT_BIT(10)), !!(Uuid4.Gen.u16ClockSeq & RT_BIT(11)), !!(Uuid4.Gen.u16ClockSeq & RT_BIT(12)), !!(Uuid4.Gen.u16ClockSeq & RT_BIT(13)), !!(Uuid4.Gen.u16ClockSeq & RT_BIT(14)), !!(Uuid4.Gen.u16ClockSeq & RT_BIT(15)), !!(Uuid4.Gen.u16TimeHiAndVersion & RT_BIT(0)), !!(Uuid4.Gen.u16TimeHiAndVersion & RT_BIT(1)), !!(Uuid4.Gen.u16TimeHiAndVersion & RT_BIT(2)), !!(Uuid4.Gen.u16TimeHiAndVersion & RT_BIT(3)), !!(Uuid4.Gen.u16TimeHiAndVersion & RT_BIT(4)), !!(Uuid4.Gen.u16TimeHiAndVersion & RT_BIT(5)), !!(Uuid4.Gen.u16TimeHiAndVersion & RT_BIT(6)), !!(Uuid4.Gen.u16TimeHiAndVersion & RT_BIT(7)), !!(Uuid4.Gen.u16TimeHiAndVersion & RT_BIT(8)), !!(Uuid4.Gen.u16TimeHiAndVersion & RT_BIT(9)), !!(Uuid4.Gen.u16TimeHiAndVersion & RT_BIT(10)), !!(Uuid4.Gen.u16TimeHiAndVersion & RT_BIT(11)), !!(Uuid4.Gen.u16TimeHiAndVersion & RT_BIT(12)), !!(Uuid4.Gen.u16TimeHiAndVersion & RT_BIT(13)), !!(Uuid4.Gen.u16TimeHiAndVersion & RT_BIT(14)), !!(Uuid4.Gen.u16TimeHiAndVersion & RT_BIT(15)) ); #endif Uuid4Prev = Uuid4; } RTUUID Uuid4Fixed; Uuid4Fixed.au64[0] = ~Uuid4Changes.au64[0]; Uuid4Fixed.au64[1] = ~Uuid4Changes.au64[1]; RTTestPrintf(hTest, RTTESTLVL_INFO, "fixed bits: %RTuuid (mask)\n", &Uuid4Fixed); RTTestPrintf(hTest, RTTESTLVL_INFO, "tstUuid: raw: %.*Rhxs\n", sizeof(Uuid4Fixed), &Uuid4Fixed); Uuid4Prev.au64[0] &= Uuid4Fixed.au64[0]; Uuid4Prev.au64[1] &= Uuid4Fixed.au64[1]; RTTestPrintf(hTest, RTTESTLVL_INFO, "tstUuid: fixed bits: %RTuuid (value)\n", &Uuid4Prev); RTTestPrintf(hTest, RTTESTLVL_INFO, "tstUuid: raw: %.*Rhxs\n", sizeof(Uuid4Prev), &Uuid4Prev); /* * Summary. */ return RTTestSummaryAndDestroy(hTest); }
static int getInterfaceInfo(int iSocket, const char *pszName, PNETIFINFO pInfo) { // Zeroing out pInfo is a bad idea as it should contain both short and long names at // this point. So make sure the structure is cleared by the caller if necessary! // memset(pInfo, 0, sizeof(*pInfo)); struct ifreq Req; RT_ZERO(Req); RTStrCopy(Req.ifr_name, sizeof(Req.ifr_name), pszName); if (ioctl(iSocket, SIOCGIFHWADDR, &Req) >= 0) { switch (Req.ifr_hwaddr.sa_family) { case ARPHRD_ETHER: pInfo->enmMediumType = NETIF_T_ETHERNET; break; default: pInfo->enmMediumType = NETIF_T_UNKNOWN; break; } /* Generate UUID from name and MAC address. */ RTUUID uuid; RTUuidClear(&uuid); memcpy(&uuid, Req.ifr_name, RT_MIN(sizeof(Req.ifr_name), sizeof(uuid))); uuid.Gen.u8ClockSeqHiAndReserved = (uuid.Gen.u8ClockSeqHiAndReserved & 0x3f) | 0x80; uuid.Gen.u16TimeHiAndVersion = (uuid.Gen.u16TimeHiAndVersion & 0x0fff) | 0x4000; memcpy(uuid.Gen.au8Node, &Req.ifr_hwaddr.sa_data, sizeof(uuid.Gen.au8Node)); pInfo->Uuid = uuid; memcpy(&pInfo->MACAddress, Req.ifr_hwaddr.sa_data, sizeof(pInfo->MACAddress)); if (ioctl(iSocket, SIOCGIFADDR, &Req) >= 0) memcpy(pInfo->IPAddress.au8, &((struct sockaddr_in *)&Req.ifr_addr)->sin_addr.s_addr, sizeof(pInfo->IPAddress.au8)); if (ioctl(iSocket, SIOCGIFNETMASK, &Req) >= 0) memcpy(pInfo->IPNetMask.au8, &((struct sockaddr_in *)&Req.ifr_addr)->sin_addr.s_addr, sizeof(pInfo->IPNetMask.au8)); if (ioctl(iSocket, SIOCGIFFLAGS, &Req) >= 0) pInfo->enmStatus = Req.ifr_flags & IFF_UP ? NETIF_S_UP : NETIF_S_DOWN; FILE *fp = fopen("/proc/net/if_inet6", "r"); if (fp) { RTNETADDRIPV6 IPv6Address; unsigned uIndex, uLength, uScope, uTmp; char szName[30]; for (;;) { RT_ZERO(szName); int n = fscanf(fp, "%08x%08x%08x%08x" " %02x %02x %02x %02x %20s\n", &IPv6Address.au32[0], &IPv6Address.au32[1], &IPv6Address.au32[2], &IPv6Address.au32[3], &uIndex, &uLength, &uScope, &uTmp, szName); if (n == EOF) break; if (n != 9 || uLength > 128) { Log(("getInterfaceInfo: Error while reading /proc/net/if_inet6, n=%d uLength=%u\n", n, uLength)); break; } if (!strcmp(Req.ifr_name, szName)) { pInfo->IPv6Address.au32[0] = htonl(IPv6Address.au32[0]); pInfo->IPv6Address.au32[1] = htonl(IPv6Address.au32[1]); pInfo->IPv6Address.au32[2] = htonl(IPv6Address.au32[2]); pInfo->IPv6Address.au32[3] = htonl(IPv6Address.au32[3]); ASMBitSetRange(&pInfo->IPv6NetMask, 0, uLength); } } fclose(fp); } /* * Don't even try to get speed for non-Ethernet interfaces, it only * produces errors. */ if (pInfo->enmMediumType == NETIF_T_ETHERNET) pInfo->uSpeedMbits = getInterfaceSpeed(pszName); else pInfo->uSpeedMbits = 0; } return VINF_SUCCESS; }
int NetIfGetConfigByName(PNETIFINFO pInfo) { int rc = VINF_SUCCESS; size_t cbNeeded; char *pBuf, *pNext; int aiMib[6]; aiMib[0] = CTL_NET; aiMib[1] = PF_ROUTE; aiMib[2] = 0; aiMib[3] = 0; /* address family */ aiMib[4] = NET_RT_IFLIST; aiMib[5] = 0; if (sysctl(aiMib, 6, NULL, &cbNeeded, NULL, 0) < 0) { Log(("NetIfList: Failed to get estimate for list size (errno=%d).\n", errno)); return RTErrConvertFromErrno(errno); } if ((pBuf = (char*)RTMemAlloc(cbNeeded)) == NULL) return VERR_NO_MEMORY; if (sysctl(aiMib, 6, pBuf, &cbNeeded, NULL, 0) < 0) { RTMemFree(pBuf); Log(("NetIfList: Failed to retrieve interface table (errno=%d).\n", errno)); return RTErrConvertFromErrno(errno); } int sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP); if (sock < 0) { RTMemFree(pBuf); Log(("NetIfList: socket() -> %d\n", errno)); return RTErrConvertFromErrno(errno); } char *pEnd = pBuf + cbNeeded; for (pNext = pBuf; pNext < pEnd;) { struct if_msghdr *pIfMsg = (struct if_msghdr *)pNext; if (pIfMsg->ifm_type != RTM_IFINFO) { Log(("NetIfList: Got message %u while expecting %u.\n", pIfMsg->ifm_type, RTM_IFINFO)); rc = VERR_INTERNAL_ERROR; break; } struct sockaddr_dl *pSdl = (struct sockaddr_dl *)(pIfMsg + 1); bool fSkip = !!strncmp(pInfo->szShortName, pSdl->sdl_data, pSdl->sdl_nlen) || pInfo->szShortName[pSdl->sdl_nlen] != '\0'; pNext += pIfMsg->ifm_msglen; while (pNext < pEnd) { struct ifa_msghdr *pIfAddrMsg = (struct ifa_msghdr *)pNext; if (pIfAddrMsg->ifam_type != RTM_NEWADDR) break; if (!fSkip) extractAddressesToNetInfo(pIfAddrMsg->ifam_addrs, (char *)(pIfAddrMsg + 1), pIfAddrMsg->ifam_msglen + (char *)pIfAddrMsg, pInfo); pNext += pIfAddrMsg->ifam_msglen; } if (!fSkip && pSdl->sdl_type == IFT_ETHER) { size_t cbNameLen = pSdl->sdl_nlen + 1; memcpy(pInfo->MACAddress.au8, LLADDR(pSdl), sizeof(pInfo->MACAddress.au8)); pInfo->enmMediumType = NETIF_T_ETHERNET; /* Generate UUID from name and MAC address. */ RTUUID uuid; RTUuidClear(&uuid); memcpy(&uuid, pInfo->szShortName, RT_MIN(cbNameLen, sizeof(uuid))); uuid.Gen.u8ClockSeqHiAndReserved = (uuid.Gen.u8ClockSeqHiAndReserved & 0x3f) | 0x80; uuid.Gen.u16TimeHiAndVersion = (uuid.Gen.u16TimeHiAndVersion & 0x0fff) | 0x4000; memcpy(uuid.Gen.au8Node, pInfo->MACAddress.au8, sizeof(uuid.Gen.au8Node)); pInfo->Uuid = uuid; struct ifreq IfReq; RTStrCopy(IfReq.ifr_name, sizeof(IfReq.ifr_name), pInfo->szShortName); if (ioctl(sock, SIOCGIFFLAGS, &IfReq) < 0) { Log(("NetIfList: ioctl(SIOCGIFFLAGS) -> %d\n", errno)); pInfo->enmStatus = NETIF_S_UNKNOWN; } else pInfo->enmStatus = (IfReq.ifr_flags & IFF_UP) ? NETIF_S_UP : NETIF_S_DOWN; return VINF_SUCCESS; } } close(sock); RTMemFree(pBuf); return rc; }
int NetIfList(std::list <ComObjPtr<HostNetworkInterface> > &list) { int rc = VINF_SUCCESS; size_t cbNeeded; char *pBuf, *pNext; int aiMib[6]; unsigned short u16DefaultIface = 0; /* initialized to shut up gcc */ /* Get the index of the interface associated with default route. */ rc = getDefaultIfaceIndex(&u16DefaultIface); if (RT_FAILURE(rc)) return rc; aiMib[0] = CTL_NET; aiMib[1] = PF_ROUTE; aiMib[2] = 0; aiMib[3] = 0; /* address family */ aiMib[4] = NET_RT_IFLIST; aiMib[5] = 0; if (sysctl(aiMib, 6, NULL, &cbNeeded, NULL, 0) < 0) { Log(("NetIfList: Failed to get estimate for list size (errno=%d).\n", errno)); return RTErrConvertFromErrno(errno); } if ((pBuf = (char*)RTMemAlloc(cbNeeded)) == NULL) return VERR_NO_MEMORY; if (sysctl(aiMib, 6, pBuf, &cbNeeded, NULL, 0) < 0) { RTMemFree(pBuf); Log(("NetIfList: Failed to retrieve interface table (errno=%d).\n", errno)); return RTErrConvertFromErrno(errno); } int sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP); if (sock < 0) { RTMemFree(pBuf); Log(("NetIfList: socket() -> %d\n", errno)); return RTErrConvertFromErrno(errno); } PDARWINETHERNIC pNIC; PDARWINETHERNIC pEtherNICs = DarwinGetEthernetControllers(); char *pEnd = pBuf + cbNeeded; for (pNext = pBuf; pNext < pEnd;) { struct if_msghdr *pIfMsg = (struct if_msghdr *)pNext; if (pIfMsg->ifm_type != RTM_IFINFO) { Log(("NetIfList: Got message %u while expecting %u.\n", pIfMsg->ifm_type, RTM_IFINFO)); rc = VERR_INTERNAL_ERROR; break; } struct sockaddr_dl *pSdl = (struct sockaddr_dl *)(pIfMsg + 1); size_t cbNameLen = pSdl->sdl_nlen + 1; Assert(pSdl->sdl_nlen < sizeof(pNIC->szBSDName)); for (pNIC = pEtherNICs; pNIC; pNIC = pNIC->pNext) if ( !strncmp(pSdl->sdl_data, pNIC->szBSDName, pSdl->sdl_nlen) && pNIC->szBSDName[pSdl->sdl_nlen] == '\0') { cbNameLen = strlen(pNIC->szName) + 1; break; } PNETIFINFO pNew = (PNETIFINFO)RTMemAllocZ(RT_OFFSETOF(NETIFINFO, szName[cbNameLen])); if (!pNew) { rc = VERR_NO_MEMORY; break; } memcpy(pNew->MACAddress.au8, LLADDR(pSdl), sizeof(pNew->MACAddress.au8)); pNew->enmMediumType = NETIF_T_ETHERNET; Assert(sizeof(pNew->szShortName) > pSdl->sdl_nlen); memcpy(pNew->szShortName, pSdl->sdl_data, RT_MIN(pSdl->sdl_nlen, sizeof(pNew->szShortName) - 1)); /* * If we found the adapter in the list returned by * DarwinGetEthernetControllers() copy the name and UUID from there. */ if (pNIC) { memcpy(pNew->szName, pNIC->szName, cbNameLen); pNew->Uuid = pNIC->Uuid; } else { memcpy(pNew->szName, pSdl->sdl_data, pSdl->sdl_nlen); /* Generate UUID from name and MAC address. */ RTUUID uuid; RTUuidClear(&uuid); memcpy(&uuid, pNew->szShortName, RT_MIN(cbNameLen, sizeof(uuid))); uuid.Gen.u8ClockSeqHiAndReserved = (uuid.Gen.u8ClockSeqHiAndReserved & 0x3f) | 0x80; uuid.Gen.u16TimeHiAndVersion = (uuid.Gen.u16TimeHiAndVersion & 0x0fff) | 0x4000; memcpy(uuid.Gen.au8Node, pNew->MACAddress.au8, sizeof(uuid.Gen.au8Node)); pNew->Uuid = uuid; } pNext += pIfMsg->ifm_msglen; while (pNext < pEnd) { struct ifa_msghdr *pIfAddrMsg = (struct ifa_msghdr *)pNext; if (pIfAddrMsg->ifam_type != RTM_NEWADDR) break; extractAddressesToNetInfo(pIfAddrMsg->ifam_addrs, (char *)(pIfAddrMsg + 1), pIfAddrMsg->ifam_msglen + (char *)pIfAddrMsg, pNew); pNext += pIfAddrMsg->ifam_msglen; } if (pSdl->sdl_type == IFT_ETHER) { struct ifreq IfReq; RTStrCopy(IfReq.ifr_name, sizeof(IfReq.ifr_name), pNew->szShortName); if (ioctl(sock, SIOCGIFFLAGS, &IfReq) < 0) { Log(("NetIfList: ioctl(SIOCGIFFLAGS) -> %d\n", errno)); pNew->enmStatus = NETIF_S_UNKNOWN; } else pNew->enmStatus = (IfReq.ifr_flags & IFF_UP) ? NETIF_S_UP : NETIF_S_DOWN; HostNetworkInterfaceType_T enmType; if (strncmp(pNew->szName, RT_STR_TUPLE("vboxnet"))) enmType = HostNetworkInterfaceType_Bridged; else enmType = HostNetworkInterfaceType_HostOnly; ComObjPtr<HostNetworkInterface> IfObj; IfObj.createObject(); if (SUCCEEDED(IfObj->init(Bstr(pNew->szName), enmType, pNew))) { /* Make sure the default interface gets to the beginning. */ if (pIfMsg->ifm_index == u16DefaultIface) list.push_front(IfObj); else list.push_back(IfObj); } } RTMemFree(pNew); } for (pNIC = pEtherNICs; pNIC;) { void *pvFree = pNIC; pNIC = pNIC->pNext; RTMemFree(pvFree); } close(sock); RTMemFree(pBuf); return rc; }
static int getInterfaceInfo(int iSocket, const char *pszName, PNETIFINFO pInfo) { // Zeroing out pInfo is a bad idea as it should contain both short and long names at // this point. So make sure the structure is cleared by the caller if necessary! // memset(pInfo, 0, sizeof(*pInfo)); struct ifreq Req; memset(&Req, 0, sizeof(Req)); strncpy(Req.ifr_name, pszName, sizeof(Req.ifr_name) - 1); if (ioctl(iSocket, SIOCGIFHWADDR, &Req) >= 0) { switch (Req.ifr_hwaddr.sa_family) { case ARPHRD_ETHER: pInfo->enmMediumType = NETIF_T_ETHERNET; break; default: pInfo->enmMediumType = NETIF_T_UNKNOWN; break; } /* Generate UUID from name and MAC address. */ RTUUID uuid; RTUuidClear(&uuid); memcpy(&uuid, Req.ifr_name, RT_MIN(sizeof(Req.ifr_name), sizeof(uuid))); uuid.Gen.u8ClockSeqHiAndReserved = (uuid.Gen.u8ClockSeqHiAndReserved & 0x3f) | 0x80; uuid.Gen.u16TimeHiAndVersion = (uuid.Gen.u16TimeHiAndVersion & 0x0fff) | 0x4000; memcpy(uuid.Gen.au8Node, &Req.ifr_hwaddr.sa_data, sizeof(uuid.Gen.au8Node)); pInfo->Uuid = uuid; memcpy(&pInfo->MACAddress, Req.ifr_hwaddr.sa_data, sizeof(pInfo->MACAddress)); if (ioctl(iSocket, SIOCGIFADDR, &Req) >= 0) memcpy(pInfo->IPAddress.au8, &((struct sockaddr_in *)&Req.ifr_addr)->sin_addr.s_addr, sizeof(pInfo->IPAddress.au8)); if (ioctl(iSocket, SIOCGIFNETMASK, &Req) >= 0) memcpy(pInfo->IPNetMask.au8, &((struct sockaddr_in *)&Req.ifr_addr)->sin_addr.s_addr, sizeof(pInfo->IPNetMask.au8)); if (ioctl(iSocket, SIOCGIFFLAGS, &Req) >= 0) pInfo->enmStatus = Req.ifr_flags & IFF_UP ? NETIF_S_UP : NETIF_S_DOWN; FILE *fp = fopen("/proc/net/if_inet6", "r"); if (fp) { RTNETADDRIPV6 IPv6Address; unsigned uIndex, uLength, uScope, uTmp; char szName[30]; for (;;) { memset(szName, 0, sizeof(szName)); int n = fscanf(fp, "%08x%08x%08x%08x" " %02x %02x %02x %02x %20s\n", &IPv6Address.au32[0], &IPv6Address.au32[1], &IPv6Address.au32[2], &IPv6Address.au32[3], &uIndex, &uLength, &uScope, &uTmp, szName); if (n == EOF) break; if (n != 9 || uLength > 128) { Log(("getInterfaceInfo: Error while reading /proc/net/if_inet6, n=%d uLength=%u\n", n, uLength)); break; } if (!strcmp(Req.ifr_name, szName)) { pInfo->IPv6Address.au32[0] = htonl(IPv6Address.au32[0]); pInfo->IPv6Address.au32[1] = htonl(IPv6Address.au32[1]); pInfo->IPv6Address.au32[2] = htonl(IPv6Address.au32[2]); pInfo->IPv6Address.au32[3] = htonl(IPv6Address.au32[3]); ASMBitSetRange(&pInfo->IPv6NetMask, 0, uLength); } } fclose(fp); } /* * Don't even try to get speed for non-Ethernet interfaces, it only * produces errors. */ pInfo->uSpeedMbits = 0; if (pInfo->enmMediumType == NETIF_T_ETHERNET) { /* * I wish I could do simple ioctl here, but older kernels require root * privileges for any ethtool commands. */ char szBuf[256]; /* First, we try to retrieve the speed via sysfs. */ RTStrPrintf(szBuf, sizeof(szBuf), "/sys/class/net/%s/speed", pszName); fp = fopen(szBuf, "r"); if (fp) { if (fscanf(fp, "%u", &pInfo->uSpeedMbits) != 1) pInfo->uSpeedMbits = 0; fclose(fp); } if (pInfo->uSpeedMbits == 10) { /* Check the cable is plugged in at all */ unsigned uCarrier = 0; RTStrPrintf(szBuf, sizeof(szBuf), "/sys/class/net/%s/carrier", pszName); fp = fopen(szBuf, "r"); if (fp) { if (fscanf(fp, "%u", &uCarrier) != 1 || uCarrier == 0) pInfo->uSpeedMbits = 0; fclose(fp); } } if (pInfo->uSpeedMbits == 0) { /* Failed to get speed via sysfs, go to plan B. */ int rc = NetIfAdpCtlOut(pszName, "speed", szBuf, sizeof(szBuf)); if (RT_SUCCESS(rc)) pInfo->uSpeedMbits = RTStrToUInt32(szBuf); } } } return VINF_SUCCESS; }
/** * Creates the default configuration. * This assumes an empty tree. * * @returns VBox status code. * @param pVM VM handle. */ static DECLCALLBACK(int) cfgmR3CreateDefault(PVM pVM, void *pvUser) { uint64_t cbMem = *(uint64_t *)pvUser; int rc; int rcAll = VINF_SUCCESS; bool fIOAPIC = false; #define UPDATERC() do { if (RT_FAILURE(rc) && RT_SUCCESS(rcAll)) rcAll = rc; } while (0) /* * Create VM default values. */ PCFGMNODE pRoot = CFGMR3GetRoot(pVM); rc = CFGMR3InsertString(pRoot, "Name", "Default VM"); UPDATERC(); rc = CFGMR3InsertInteger(pRoot, "RamSize", cbMem); UPDATERC(); rc = CFGMR3InsertInteger(pRoot, "TimerMillies", 10); UPDATERC(); rc = CFGMR3InsertInteger(pRoot, "RawR3Enabled", 0); UPDATERC(); /** @todo CFGM Defaults: RawR0, PATMEnabled and CASMEnabled needs attention later. */ rc = CFGMR3InsertInteger(pRoot, "RawR0Enabled", 0); UPDATERC(); rc = CFGMR3InsertInteger(pRoot, "PATMEnabled", 0); UPDATERC(); rc = CFGMR3InsertInteger(pRoot, "CSAMEnabled", 0); UPDATERC(); /* * PDM. */ PCFGMNODE pPdm; rc = CFGMR3InsertNode(pRoot, "PDM", &pPdm); UPDATERC(); PCFGMNODE pDevices = NULL; rc = CFGMR3InsertNode(pPdm, "Devices", &pDevices); UPDATERC(); rc = CFGMR3InsertInteger(pDevices, "LoadBuiltin", 1); /* boolean */ UPDATERC(); PCFGMNODE pDrivers = NULL; rc = CFGMR3InsertNode(pPdm, "Drivers", &pDrivers); UPDATERC(); rc = CFGMR3InsertInteger(pDrivers, "LoadBuiltin", 1); /* boolean */ UPDATERC(); /* * Devices */ pDevices = NULL; rc = CFGMR3InsertNode(pRoot, "Devices", &pDevices); UPDATERC(); /* device */ PCFGMNODE pDev = NULL; PCFGMNODE pInst = NULL; PCFGMNODE pCfg = NULL; #if 0 PCFGMNODE pLunL0 = NULL; PCFGMNODE pLunL1 = NULL; #endif /* * PC Arch. */ rc = CFGMR3InsertNode(pDevices, "pcarch", &pDev); UPDATERC(); rc = CFGMR3InsertNode(pDev, "0", &pInst); UPDATERC(); rc = CFGMR3InsertInteger(pInst, "Trusted", 1); /* boolean */ UPDATERC(); rc = CFGMR3InsertNode(pInst, "Config", &pCfg); UPDATERC(); /* * PC Bios. */ rc = CFGMR3InsertNode(pDevices, "pcbios", &pDev); UPDATERC(); rc = CFGMR3InsertNode(pDev, "0", &pInst); UPDATERC(); rc = CFGMR3InsertInteger(pInst, "Trusted", 1); /* boolean */ UPDATERC(); rc = CFGMR3InsertNode(pInst, "Config", &pCfg); UPDATERC(); rc = CFGMR3InsertInteger(pCfg, "RamSize", cbMem); UPDATERC(); rc = CFGMR3InsertString(pCfg, "BootDevice0", "IDE"); UPDATERC(); rc = CFGMR3InsertString(pCfg, "BootDevice1", "NONE"); UPDATERC(); rc = CFGMR3InsertString(pCfg, "BootDevice2", "NONE"); UPDATERC(); rc = CFGMR3InsertString(pCfg, "BootDevice3", "NONE"); UPDATERC(); rc = CFGMR3InsertString(pCfg, "HardDiskDevice", "piix3ide"); UPDATERC(); rc = CFGMR3InsertString(pCfg, "FloppyDevice", "i82078"); rc = CFGMR3InsertInteger(pCfg, "IOAPIC", fIOAPIC); UPDATERC(); RTUUID Uuid; RTUuidClear(&Uuid); rc = CFGMR3InsertBytes(pCfg, "UUID", &Uuid, sizeof(Uuid)); UPDATERC(); /* Bios logo. */ rc = CFGMR3InsertInteger(pCfg, "FadeIn", 0); UPDATERC(); rc = CFGMR3InsertInteger(pCfg, "FadeOut", 0); UPDATERC(); rc = CFGMR3InsertInteger(pCfg, "LogoTime", 0); UPDATERC(); rc = CFGMR3InsertString(pCfg, "LogoFile", ""); UPDATERC(); /* * ACPI */ rc = CFGMR3InsertNode(pDevices, "acpi", &pDev); UPDATERC(); rc = CFGMR3InsertNode(pDev, "0", &pInst); UPDATERC(); rc = CFGMR3InsertInteger(pInst, "Trusted", 1); /* boolean */ UPDATERC(); rc = CFGMR3InsertNode(pInst, "Config", &pCfg); UPDATERC(); rc = CFGMR3InsertInteger(pCfg, "RamSize", cbMem); UPDATERC(); rc = CFGMR3InsertInteger(pCfg, "IOAPIC", fIOAPIC); UPDATERC(); rc = CFGMR3InsertInteger(pInst, "PCIDeviceNo", 7); UPDATERC(); rc = CFGMR3InsertInteger(pInst, "PCIFunctionNo", 0); UPDATERC(); /* * DMA */ rc = CFGMR3InsertNode(pDevices, "8237A", &pDev); UPDATERC(); rc = CFGMR3InsertNode(pDev, "0", &pInst); UPDATERC(); rc = CFGMR3InsertInteger(pInst, "Trusted", 1); /* boolean */ UPDATERC(); /* * PCI bus. */ rc = CFGMR3InsertNode(pDevices, "pci", &pDev); /* piix3 */ UPDATERC(); rc = CFGMR3InsertNode(pDev, "0", &pInst); UPDATERC(); rc = CFGMR3InsertInteger(pInst, "Trusted", 1); /* boolean */ UPDATERC(); rc = CFGMR3InsertNode(pInst, "Config", &pCfg); UPDATERC(); rc = CFGMR3InsertInteger(pCfg, "IOAPIC", fIOAPIC); UPDATERC(); /* * PS/2 keyboard & mouse */ rc = CFGMR3InsertNode(pDevices, "pckbd", &pDev); UPDATERC(); rc = CFGMR3InsertNode(pDev, "0", &pInst); UPDATERC(); rc = CFGMR3InsertInteger(pInst, "Trusted", 1); /* boolean */ UPDATERC(); rc = CFGMR3InsertNode(pInst, "Config", &pCfg); UPDATERC(); /* * Floppy */ rc = CFGMR3InsertNode(pDevices, "i82078", &pDev); UPDATERC(); rc = CFGMR3InsertNode(pDev, "0", &pInst); UPDATERC(); rc = CFGMR3InsertInteger(pInst, "Trusted", 1); UPDATERC(); rc = CFGMR3InsertNode(pInst, "Config", &pCfg); UPDATERC(); rc = CFGMR3InsertInteger(pCfg, "IRQ", 6); UPDATERC(); rc = CFGMR3InsertInteger(pCfg, "DMA", 2); UPDATERC(); rc = CFGMR3InsertInteger(pCfg, "MemMapped", 0 ); UPDATERC(); rc = CFGMR3InsertInteger(pCfg, "IOBase", 0x3f0); UPDATERC(); /* * i8254 Programmable Interval Timer And Dummy Speaker */ rc = CFGMR3InsertNode(pDevices, "i8254", &pDev); UPDATERC(); rc = CFGMR3InsertNode(pDev, "0", &pInst); UPDATERC(); rc = CFGMR3InsertNode(pInst, "Config", &pCfg); UPDATERC(); /* * i8259 Programmable Interrupt Controller. */ rc = CFGMR3InsertNode(pDevices, "i8259", &pDev); UPDATERC(); rc = CFGMR3InsertNode(pDev, "0", &pInst); UPDATERC(); rc = CFGMR3InsertInteger(pInst, "Trusted", 1); /* boolean */ UPDATERC(); rc = CFGMR3InsertNode(pInst, "Config", &pCfg); UPDATERC(); /* * APIC. */ rc = CFGMR3InsertNode(pDevices, "apic", &pDev); UPDATERC(); rc = CFGMR3InsertNode(pDev, "0", &pInst); UPDATERC(); rc = CFGMR3InsertInteger(pInst, "Trusted", 1); /* boolean */ UPDATERC(); rc = CFGMR3InsertNode(pInst, "Config", &pCfg); UPDATERC(); rc = CFGMR3InsertInteger(pCfg, "IOAPIC", fIOAPIC); UPDATERC(); if (fIOAPIC) { /* * I/O Advanced Programmable Interrupt Controller. */ rc = CFGMR3InsertNode(pDevices, "ioapic", &pDev); UPDATERC(); rc = CFGMR3InsertNode(pDev, "0", &pInst); UPDATERC(); rc = CFGMR3InsertInteger(pInst, "Trusted", 1); /* boolean */ UPDATERC(); rc = CFGMR3InsertNode(pInst, "Config", &pCfg); UPDATERC(); } /* * RTC MC146818. */ rc = CFGMR3InsertNode(pDevices, "mc146818", &pDev); UPDATERC(); rc = CFGMR3InsertNode(pDev, "0", &pInst); UPDATERC(); rc = CFGMR3InsertNode(pInst, "Config", &pCfg); UPDATERC(); /* * VGA. */ rc = CFGMR3InsertNode(pDevices, "vga", &pDev); UPDATERC(); rc = CFGMR3InsertNode(pDev, "0", &pInst); UPDATERC(); rc = CFGMR3InsertInteger(pInst, "Trusted", 1); /* boolean */ UPDATERC(); rc = CFGMR3InsertInteger(pInst, "PCIDeviceNo", 2); UPDATERC(); rc = CFGMR3InsertInteger(pInst, "PCIFunctionNo", 0); UPDATERC(); rc = CFGMR3InsertNode(pInst, "Config", &pCfg); UPDATERC(); rc = CFGMR3InsertInteger(pCfg, "VRamSize", 8 * _1M); UPDATERC(); rc = CFGMR3InsertInteger(pCfg, "CustomVideoModes", 0); rc = CFGMR3InsertInteger(pCfg, "HeightReduction", 0); UPDATERC(); //rc = CFGMR3InsertInteger(pCfg, "MonitorCount", 1); UPDATERC(); /* * IDE controller. */ rc = CFGMR3InsertNode(pDevices, "piix3ide", &pDev); /* piix3 */ UPDATERC(); rc = CFGMR3InsertNode(pDev, "0", &pInst); UPDATERC(); rc = CFGMR3InsertInteger(pInst, "Trusted", 1); /* boolean */ UPDATERC(); rc = CFGMR3InsertNode(pInst, "Config", &pCfg); UPDATERC(); rc = CFGMR3InsertInteger(pInst, "PCIDeviceNo", 1); UPDATERC(); rc = CFGMR3InsertInteger(pInst, "PCIFunctionNo", 1); UPDATERC(); /* * Network card. */ rc = CFGMR3InsertNode(pDevices, "pcnet", &pDev); UPDATERC(); rc = CFGMR3InsertNode(pDev, "0", &pInst); UPDATERC(); rc = CFGMR3InsertInteger(pInst, "Trusted", 1); /* boolean */ UPDATERC(); rc = CFGMR3InsertInteger(pInst, "PCIDeviceNo", 3); UPDATERC(); rc = CFGMR3InsertInteger(pInst, "PCIFunctionNo", 0); UPDATERC(); rc = CFGMR3InsertNode(pInst, "Config", &pCfg); UPDATERC(); rc = CFGMR3InsertInteger(pCfg, "Am79C973", 1); UPDATERC(); RTMAC Mac; Mac.au16[0] = 0x0080; Mac.au16[2] = Mac.au16[1] = 0x8086; rc = CFGMR3InsertBytes(pCfg, "MAC", &Mac, sizeof(Mac)); UPDATERC(); /* * VMM Device */ rc = CFGMR3InsertNode(pDevices, "VMMDev", &pDev); UPDATERC(); rc = CFGMR3InsertNode(pDev, "0", &pInst); UPDATERC(); rc = CFGMR3InsertNode(pInst, "Config", &pCfg); UPDATERC(); rc = CFGMR3InsertInteger(pInst, "Trusted", 1); /* boolean */ UPDATERC(); rc = CFGMR3InsertInteger(pInst, "PCIDeviceNo", 4); UPDATERC(); rc = CFGMR3InsertInteger(pInst, "PCIFunctionNo", 0); UPDATERC(); /* * ... */ #undef UPDATERC return rcAll; }
static void vboxSolarisAddHostIface(char *pszIface, int Instance, void *pvHostNetworkInterfaceList) { std::list<ComObjPtr<HostNetworkInterface> > *pList = (std::list<ComObjPtr<HostNetworkInterface> > *)pvHostNetworkInterfaceList; Assert(pList); typedef std::map <std::string, std::string> NICMap; typedef std::pair <std::string, std::string> NICPair; static NICMap SolarisNICMap; if (SolarisNICMap.empty()) { SolarisNICMap.insert(NICPair("afe", "ADMtek Centaur/Comet Fast Ethernet")); SolarisNICMap.insert(NICPair("atge", "Atheros/Attansic Gigabit Ethernet")); SolarisNICMap.insert(NICPair("aggr", "Link Aggregation Interface")); SolarisNICMap.insert(NICPair("bfe", "Broadcom BCM4401 Fast Ethernet")); SolarisNICMap.insert(NICPair("bge", "Broadcom BCM57xx Gigabit Ethernet")); SolarisNICMap.insert(NICPair("bnx", "Broadcom NetXtreme Gigabit Ethernet")); SolarisNICMap.insert(NICPair("bnxe", "Broadcom NetXtreme II 10 Gigabit Ethernet")); SolarisNICMap.insert(NICPair("ce", "Cassini Gigabit Ethernet")); SolarisNICMap.insert(NICPair("chxge", "Chelsio Ethernet")); SolarisNICMap.insert(NICPair("dmfe", "Davicom 9102 Fast Ethernet")); SolarisNICMap.insert(NICPair("dnet", "DEC 21040/41 21140 Ethernet")); SolarisNICMap.insert(NICPair("e1000", "Intel PRO/1000 Gigabit Ethernet")); SolarisNICMap.insert(NICPair("e1000g", "Intel PRO/1000 Gigabit Ethernet")); SolarisNICMap.insert(NICPair("elx", "3COM Etherlink III Ethernet")); SolarisNICMap.insert(NICPair("elxl", "3COM Etherlink XL Ethernet")); SolarisNICMap.insert(NICPair("eri", "eri Fast Ethernet")); SolarisNICMap.insert(NICPair("ge", "GEM Gigabit Ethernet")); SolarisNICMap.insert(NICPair("hme", "SUNW,hme Fast-Ethernet")); SolarisNICMap.insert(NICPair("hxge", "Sun Blade 10 Gigabit Ethernet")); SolarisNICMap.insert(NICPair("igb", "Intel 82575 PCI-E Gigabit Ethernet")); SolarisNICMap.insert(NICPair("ipge", "PCI-E Gigabit Ethernet")); SolarisNICMap.insert(NICPair("iprb", "Intel 82557/58/59 Ethernet")); SolarisNICMap.insert(NICPair("ixgb", "Intel 82597ex 10 Gigabit Ethernet")); SolarisNICMap.insert(NICPair("ixgbe", "Intel 10 Gigabit PCI-E Ethernet")); SolarisNICMap.insert(NICPair("mcxe", "Mellanox ConnectX-2 10 Gigabit Ethernet")); SolarisNICMap.insert(NICPair("mxfe", "Macronix 98715 Fast Ethernet")); SolarisNICMap.insert(NICPair("nfo", "Nvidia Gigabit Ethernet")); SolarisNICMap.insert(NICPair("nge", "Nvidia Gigabit Ethernet")); SolarisNICMap.insert(NICPair("ntxn", "NetXen 10/1 Gigabit Ethernet")); SolarisNICMap.insert(NICPair("nxge", "Sun 10/1 Gigabit Ethernet")); SolarisNICMap.insert(NICPair("pcelx", "3COM EtherLink III PCMCIA Ethernet")); SolarisNICMap.insert(NICPair("pcn", "AMD PCnet Ethernet")); SolarisNICMap.insert(NICPair("qfe", "SUNW,qfe Quad Fast-Ethernet")); SolarisNICMap.insert(NICPair("rge", "Realtek Gigabit Ethernet")); SolarisNICMap.insert(NICPair("rtls", "Realtek 8139 Fast Ethernet")); SolarisNICMap.insert(NICPair("sfe", "SiS900 Fast Ethernet")); SolarisNICMap.insert(NICPair("skge", "SksKonnect Gigabit Ethernet")); SolarisNICMap.insert(NICPair("spwr", "SMC EtherPower II 10/100 (9432) Ethernet")); SolarisNICMap.insert(NICPair("vboxnet", "VirtualBox Host Ethernet")); SolarisNICMap.insert(NICPair("vboxvnic_template", "VirtualBox Virtual Network Interface Template")); SolarisNICMap.insert(NICPair("vlan", "Virtual LAN Ethernet")); SolarisNICMap.insert(NICPair("vr", "VIA Rhine Fast Ethernet")); SolarisNICMap.insert(NICPair("vnic", "Virtual Network Interface Ethernet")); SolarisNICMap.insert(NICPair("xge", "Neterior Xframe 10Gigabit Ethernet")); SolarisNICMap.insert(NICPair("yge", "Marvell Yukon 2 Fast Ethernet")); } /* * Try picking up description from our NIC map. */ char szNICInstance[128]; RTStrPrintf(szNICInstance, sizeof(szNICInstance), "%s%d", pszIface, Instance); char szNICDesc[256]; std::string Description = SolarisNICMap[pszIface]; if (Description != "VirtualBox Host Ethernet") { if (Description != "") RTStrPrintf(szNICDesc, sizeof(szNICDesc), "%s - %s", szNICInstance, Description.c_str()); else RTStrPrintf(szNICDesc, sizeof(szNICDesc), "%s - Ethernet", szNICInstance); } else RTStrPrintf(szNICDesc, sizeof(szNICDesc), "%s", szNICInstance); /* * Try to get IP V4 address and netmask as well as Ethernet address. */ NETIFINFO Info; memset(&Info, 0, sizeof(Info)); int Sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP); if (Sock > 0) { struct lifreq IfReq; strcpy(IfReq.lifr_name, szNICInstance); if (ioctl(Sock, SIOCGLIFADDR, &IfReq) >= 0) { memcpy(Info.IPAddress.au8, &((struct sockaddr_in *)&IfReq.lifr_addr)->sin_addr.s_addr, sizeof(Info.IPAddress.au8)); struct arpreq ArpReq; memcpy(&ArpReq.arp_pa, &IfReq.lifr_addr, sizeof(struct sockaddr_in)); /* * We might fail if the interface has not been assigned an IP address. * That doesn't matter; as long as it's plumbed we can pick it up. * But, if it has not acquired an IP address we cannot obtain it's MAC * address this way, so we just use all zeros there. */ if (ioctl(Sock, SIOCGARP, &ArpReq) >= 0) { memcpy(&Info.MACAddress, ArpReq.arp_ha.sa_data, sizeof(Info.MACAddress)); } } if (ioctl(Sock, SIOCGLIFNETMASK, &IfReq) >= 0) { memcpy(Info.IPNetMask.au8, &((struct sockaddr_in *)&IfReq.lifr_addr)->sin_addr.s_addr, sizeof(Info.IPNetMask.au8)); } if (ioctl(Sock, SIOCGLIFFLAGS, &IfReq) >= 0) { Info.enmStatus = IfReq.lifr_flags & IFF_UP ? NETIF_S_UP : NETIF_S_DOWN; } close(Sock); } /* * Try to get IP V6 address and netmask. */ Sock = socket(PF_INET6, SOCK_DGRAM, IPPROTO_IP); if (Sock > 0) { struct lifreq IfReq; strcpy(IfReq.lifr_name, szNICInstance); if (ioctl(Sock, SIOCGLIFADDR, &IfReq) >= 0) { memcpy(Info.IPv6Address.au8, ((struct sockaddr_in6 *)&IfReq.lifr_addr)->sin6_addr.s6_addr, sizeof(Info.IPv6Address.au8)); } if (ioctl(Sock, SIOCGLIFNETMASK, &IfReq) >= 0) { memcpy(Info.IPv6NetMask.au8, ((struct sockaddr_in6 *)&IfReq.lifr_addr)->sin6_addr.s6_addr, sizeof(Info.IPv6NetMask.au8)); } close(Sock); } /* * Construct UUID with interface name and the MAC address if available. */ RTUUID Uuid; RTUuidClear(&Uuid); memcpy(&Uuid, szNICInstance, RT_MIN(strlen(szNICInstance), sizeof(Uuid))); Uuid.Gen.u8ClockSeqHiAndReserved = (Uuid.Gen.u8ClockSeqHiAndReserved & 0x3f) | 0x80; Uuid.Gen.u16TimeHiAndVersion = (Uuid.Gen.u16TimeHiAndVersion & 0x0fff) | 0x4000; Uuid.Gen.au8Node[0] = Info.MACAddress.au8[0]; Uuid.Gen.au8Node[1] = Info.MACAddress.au8[1]; Uuid.Gen.au8Node[2] = Info.MACAddress.au8[2]; Uuid.Gen.au8Node[3] = Info.MACAddress.au8[3]; Uuid.Gen.au8Node[4] = Info.MACAddress.au8[4]; Uuid.Gen.au8Node[5] = Info.MACAddress.au8[5]; Info.Uuid = Uuid; Info.enmMediumType = NETIF_T_ETHERNET; strncpy(Info.szShortName, szNICInstance, sizeof(Info.szShortName) - 1); HostNetworkInterfaceType_T enmType; if (strncmp("vboxnet", szNICInstance, 7)) enmType = HostNetworkInterfaceType_Bridged; else enmType = HostNetworkInterfaceType_HostOnly; queryIfaceSpeed(&Info); ComObjPtr<HostNetworkInterface> IfObj; IfObj.createObject(); if (SUCCEEDED(IfObj->init(Bstr(szNICDesc), enmType, &Info))) pList->push_back(IfObj); }