Changeset 5698 in vbox
- Timestamp:
- Nov 12, 2007 6:31:09 AM (17 years ago)
- svn:sync-xref-src-repo-rev:
- 26045
- Location:
- trunk/src/VBox
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Makefile.kmk
r5651 r5698 525 525 Drivers_DEFS += VBOX_WITH_CROSSBOW 526 526 Drivers_INCS += \ 527 Network/solaris \ 528 Network/solaris/sys #why sys? 527 Network/solaris 529 528 endif 530 529 endif -
trunk/src/VBox/Devices/Network/DrvTAP.cpp
r5586 r5698 33 33 # include <iprt/asm.h> 34 34 # include <iprt/semaphore.h> 35 #endif 36 #ifdef RT_OS_SOLARIS 37 # include <iprt/process.h> 38 # include <iprt/env.h> 39 # ifdef VBOX_WITH_CROSSBOW 40 # include <iprt/mem.h> 41 # endif 35 42 #endif 36 43 … … 102 109 # ifdef VBOX_WITH_CROSSBOW 103 110 /** Crossbow: MAC address of the device. */ 104 char *pszMACAddress;111 PDMMAC MacAddress; 105 112 /** Crossbow: Handle of the NIC. */ 106 113 dlpi_handle_t pDeviceHandle; 114 /** Crossbow: ID of the virtual NIC. */ 115 uint_t uDeviceID; 107 116 # else 108 117 /** IP device file handle (/dev/udp). */ … … 161 170 162 171 /******************************************************************************* 163 * Internal Functions 172 * Internal Functions & Globals * 164 173 *******************************************************************************/ 165 174 #ifdef RT_OS_SOLARIS … … 167 176 static int SolarisCreateVNIC(PDRVTAP pData); 168 177 static int SolarisGetNIC(char *pszNICName, size_t cbSize); 169 static int SolarisOpenNIC(PDRVTAP pData, const char *pszNICName , struct ether_addr *pEtherAddr);170 static dladm_status_t SolarisCompareVNIC(void* pArg, dladm_vnic_attr_sys_t *pVNICAttr);178 static int SolarisOpenNIC(PDRVTAP pData, const char *pszNICName); 179 static int SolarisDLPIErr2VBoxErr(int rc); 171 180 # else 172 181 static int SolarisTAPAttach(PPDMDRVINS pDrvIns); … … 318 327 rc = VINF_SUCCESS; 319 328 cbRead = sizeof(achBuf); 320 if (dlpi_recv(pData->pDeviceHandle, NULL, NULL, achBuf, &cbRead, -1, NULL) != DLPI_SUCCESS) 321 rc = VERR_GENERAL_FAILURE; /** @todo find a better return code. */ /** r=bird: just make a conversion function. */ 329 int rc2 = dlpi_recv(pData->pDeviceHandle, NULL, NULL, achBuf, &cbRead, -1, NULL); 330 if (rc2 != DLPI_SUCCESS) 331 rc = SolarisDLPIErr2VBoxErr(rc2); 322 332 #else 323 333 rc = RTFileRead(pData->FileDevice, achBuf, sizeof(achBuf), &cbRead); … … 457 467 int rc = VINF_SUCCESS; 458 468 cbRead = sizeof(achBuf); 459 if (dlpi_recv(pData->pDeviceHandle, NULL, NULL, achBuf, &cbRead, -1, NULL) != DLPI_SUCCESS) 460 rc = VERR_GENERAL_FAILURE; /** @todo find a better return code. */ 469 int rc2 = dlpi_recv(pData->pDeviceHandle, NULL, NULL, achBuf, &cbRead, -1, NULL); 470 if (rc2 != DLPI_SUCCESS) 471 rc = SolarisDLPIErr2VBoxErr(rc2); 461 472 #else 462 473 int rc = RTFileRead(pData->FileDevice, achBuf, RT_MIN(sizeof(achBuf), cbMax), &cbRead); … … 507 518 pszArgs[2] = NULL; 508 519 509 /** @todo use RTProcCreate */510 511 520 Log2(("Starting TAP setup application: %s %s\n", pData->pszSetupApplication, pData->pszDeviceNameActual)); 512 pid_t pid = fork(); 513 if (pid < 0) 514 { 515 /* Bad. fork() failed! */ 521 RTPROCESS pid = NIL_RTPROCESS; 522 int rc = RTProcCreate(pszArgs[0], pszArgs, RTENV_DEFAULT, 0, &pid); 523 if (RT_SUCCESS(rc)) 524 { 525 RTPROCSTATUS Status; 526 rc = RTProcWait(pid, 0, &Status); 527 if (RT_SUCCESS(rc)) 528 { 529 if (Status.iStatus == 0 && Status.enmReason == RTPROCEXITREASON_NORMAL) 530 return VINF_SUCCESS; 531 532 LogRel(("TAP#%d: Error running TAP setup application: %s\n", pData->pDrvIns->iInstance, pData->pszSetupApplication)); 533 return VERR_HOSTIF_INIT_FAILED; 534 } 535 else 536 { 537 LogRel(("TAP#%d: RTProcWait failed for: %s\n", pData->pDrvIns->iInstance, pData->pszSetupApplication)); 538 return VERR_HOSTIF_INIT_FAILED; 539 } 540 } 541 else 542 { 543 /* Bad. RTProcCreate() failed! */ 516 544 LogRel(("TAP#%d: Failed to fork() process for running TAP setup application: %s\n", pData->pDrvIns->iInstance, 517 545 pData->pszSetupApplication, strerror(errno))); 518 return VERR_HOSTIF_INIT_FAILED; 519 } 520 if (pid == 0) 521 { 522 /* Child process. */ 523 execv(pszArgs[0], pszArgs); 524 _exit(1); 525 } 526 527 /* Parent process. */ 528 int result; 529 while (waitpid(pid, &result, 0) < 0) 530 ; 531 if (!WIFEXITED(result) || WEXITSTATUS(result) != 0) 532 { 533 LogRel(("TAP#%d: Failed to run TAP setup application: %s\n", pData->pDrvIns->iInstance, pData->pszSetupApplication)); 534 return VERR_HOSTIF_INIT_FAILED; 535 } 536 537 return VINF_SUCCESS; 546 } 547 548 return VERR_HOSTIF_INIT_FAILED; 538 549 } 539 550 … … 552 563 pszArgs[2] = NULL; 553 564 554 /** @todo use RTProcCreate */555 556 565 Log2(("Starting TAP terminate application: %s %s\n", pData->pszTerminateApplication, pData->pszDeviceNameActual)); 557 pid_t pid = fork(); 558 if (pid < 0) 559 { 560 /* Bad. fork() failed! */ 566 RTPROCESS pid = NIL_RTPROCESS; 567 int rc = RTProcCreate(pszArgs[0], pszArgs, RTENV_DEFAULT, 0, &pid); 568 if (RT_SUCCESS(rc)) 569 { 570 RTPROCSTATUS Status; 571 rc = RTProcWait(pid, 0, &Status); 572 if (RT_SUCCESS(rc)) 573 { 574 if (Status.iStatus == 0 && Status.enmReason == RTPROCEXITREASON_NORMAL) 575 return VINF_SUCCESS; 576 577 LogRel(("TAP#%d: Error running TAP terminate application: %s\n", pData->pDrvIns->iInstance, pData->pszTerminateApplication)); 578 return VERR_HOSTIF_TERM_FAILED; 579 } 580 else 581 { 582 LogRel(("TAP#%d: RTProcWait failed for: %s\n", pData->pDrvIns->iInstance, pData->pszTerminateApplication)); 583 return VERR_HOSTIF_INIT_FAILED; 584 } 585 } 586 else 587 { 588 /* Bad. RTProcCreate() failed! */ 561 589 LogRel(("TAP#%d: Failed to fork() process for running TAP terminate application: %s\n", pData->pDrvIns->iInstance, 562 590 pData->pszTerminateApplication, strerror(errno))); 563 return VERR_HOSTIF_TERM_FAILED; 564 } 565 if (pid == 0) 566 { 567 /* Child process. */ 568 execv(pszArgs[0], pszArgs); 569 _exit(1); 570 } 571 572 /* Parent process. */ 573 int result; 574 while (waitpid(pid, &result, 0) < 0) 575 ; 576 if (!WIFEXITED(result) || WEXITSTATUS(result) != 0) 577 { 578 LogRel(("TAP#%d: Failed to run TAP terminate application: %s\n", pData->pDrvIns->iInstance, pData->pszSetupApplication)); 579 return VERR_HOSTIF_TERM_FAILED; 580 } 581 582 return VINF_SUCCESS; 591 } 592 return VERR_HOSTIF_TERM_FAILED; 583 593 } 584 594 … … 609 619 610 620 /* 611 * Get the MAC address with ':' seperators as ether_aton() needs those612 */613 /** @todo r=bird: ether_addr is just a byte array, just pass the PDMMAC614 * structure around and memcpy it, this is too much work. */615 struct ether_addr *pEtherAddr = NULL;616 if (pData->pszMACAddress && strlen(pData->pszMACAddress) == 12)617 {618 char szMACAddress[12 + 6 + 1];619 RTStrPrintf(szMACAddress, sizeof(szMACAddress), "%c%c:%c%c:%c%c:%c%c:%c%c:%c%c",620 pData->pszMACAddress[0], pData->pszMACAddress[1], pData->pszMACAddress[2], pData->pszMACAddress[3],621 pData->pszMACAddress[4], pData->pszMACAddress[5], pData->pszMACAddress[6], pData->pszMACAddress[7],622 pData->pszMACAddress[8], pData->pszMACAddress[9], pData->pszMACAddress[10], pData->pszMACAddress[11]);623 624 pEtherAddr = ether_aton(szMACAddress);625 }626 if (!pEtherAddr)627 return PDMDrvHlpVMSetError(pData->pDrvIns, VERR_HOSTIF_INIT_FAILED, RT_SRC_POS,628 N_("Invalid MAC address %s"), pData->pszMACAddress);629 630 /*631 621 * Setup VNIC parameters. 632 622 */ 633 623 dladm_vnic_attr_sys_t VNICAttr; 634 strncpy(VNICAttr.va_dev_name, szNICName, sizeof(VNICAttr.va_dev_name) - 1); /** @todo r=bird: don't ever use strncpy! Esp. not with an uninitialized structure. */ 635 memcpy(VNICAttr.va_mac_addr, (uchar_t *)pEtherAddr->ether_addr_octet, ETHERADDRL); 624 memset(&VNICAttr, 0, sizeof(VNICAttr)); 625 size_t cbDestSize = sizeof(VNICAttr.va_dev_name); 626 if (strlcpy(VNICAttr.va_dev_name, szNICName, cbDestSize) >= cbDestSize) 627 return VERR_BUFFER_OVERFLOW; 628 Assert(sizeof(struct ether_addr) == sizeof(pData->MacAddress)); 629 memcpy(VNICAttr.va_mac_addr, &pData->MacAddress, ETHERADDRL); 636 630 VNICAttr.va_mac_len = ETHERADDRL; 637 631 … … 652 646 653 647 /* 654 * Create a VNIC if it doesn't already exist. 655 * XXX: Perhaps VMs should not use existing VNICs??? 648 * Create the VNIC. 656 649 */ 657 650 /** r=bird: The users should be able to create the vnic himself and pass it down. This would be the 658 651 * same as the tapN interface name. */ 659 dladm_status_t rc = dladm_vnic_walk_sys(SolarisCompareVNIC, &VNICAttr); 660 if (rc == DLADM_STATUS_OK) 661 { 662 uint32_t flags = DLADM_VNIC_OPT_TEMP; 663 if (fAutoID) 664 flags |= DLADM_VNIC_OPT_AUTOID; 665 666 rc = dladm_vnic_create(fAutoID ? 0 : VnicID, szNICName, VNIC_MAC_ADDR_TYPE_FIXED, 667 (uchar_t *)pEtherAddr->ether_addr_octet, ETHERADDRL, &VnicID, flags); 668 if (rc != DLADM_STATUS_OK) 669 return PDMDrvHlpVMSetError(pData->pDrvIns, VERR_HOSTIF_INIT_FAILED, RT_SRC_POS, 670 N_("dladm_vnic_create() failed. NIC %s probably incorrect."), szNICName); 671 } 672 else 673 /** r=bird: This can't possibly fail in any way, or what? */ 674 VnicID = VNICAttr.va_vnic_id; 675 676 652 uint32_t flags = DLADM_VNIC_OPT_TEMP; 653 if (fAutoID) 654 flags |= DLADM_VNIC_OPT_AUTOID; 655 656 dladm_status_t rc = dladm_vnic_create(fAutoID ? 0 : VnicID, szNICName, VNIC_MAC_ADDR_TYPE_FIXED, 657 (uchar_t *)&pData->MacAddress, ETHERADDRL, &VnicID, flags); 658 if (rc != DLADM_STATUS_OK) 659 return PDMDrvHlpVMSetError(pData->pDrvIns, VERR_HOSTIF_INIT_FAILED, RT_SRC_POS, 660 N_("dladm_vnic_create() failed. NIC %s probably incorrect."), szNICName); 661 677 662 pData->pszDeviceNameActual = NULL; 678 663 RTStrAPrintf(&pData->pszDeviceNameActual, "vnic%u", VnicID); 679 680 ret = SolarisOpenNIC(pData, szNICName, pEtherAddr); 664 pData->uDeviceID = VnicID; 665 666 ret = SolarisOpenNIC(pData, szNICName); 681 667 if (VBOX_FAILURE(ret)) 682 668 return ret; … … 698 684 */ 699 685 int InetSocket = socket(AF_INET, SOCK_DGRAM, 0); 700 if (RT_UNLIKELY( inetSocket == -1))686 if (RT_UNLIKELY(InetSocket == -1)) 701 687 { 702 688 LogRel(("SolarisGetNIC: Socket creation for AF_INET family failed.\n")); … … 707 693 struct lifnum IfNum; 708 694 IfNum.lifn_family = AF_UNSPEC; 709 if (ioctl(InetSocket, SIOCGLIFNUM, (char *)&IfNum) >= 0)695 if (ioctl(InetSocket, SIOCGLIFNUM, &IfNum) >= 0) 710 696 { 711 697 caddr_t pBuf = (caddr_t)RTMemAlloc(IfNum.lifn_count * sizeof(struct lifreq)); 712 if (p szBuffer)698 if (pBuf) 713 699 { 714 700 struct lifconf IfCfg; 715 701 memset(&IfCfg, 0, sizeof(IfCfg)); 716 702 IfCfg.lifc_family = AF_UNSPEC; 717 IfCfg.lifc_buf = pBuf 718 if (ioctl(InetSocket, SIOCGLIFCONF, (char *)&IfCfg) >= 0) 703 IfCfg.lifc_buf = pBuf; 704 IfCfg.lifc_len = IfNum.lifn_count * sizeof(struct lifreq); 705 if (ioctl(InetSocket, SIOCGLIFCONF, &IfCfg) >= 0) 719 706 { 720 707 /* … … 729 716 { 730 717 dlpi_handle_t hNIC = NULL; 731 if (dlpi_open(paIf[iIf].lifr_name, &hNIC, 0) == DLPI_SUCCESS)718 if (dlpi_open(paIf[iIf].lifr_name, &hNIC, DLPI_RAW) == DLPI_SUCCESS) 732 719 { 733 720 dlpi_info_t NICInfo; … … 755 742 rc = VERR_HOSTIF_INIT_FAILED; 756 743 } 757 free(p szBuffer);744 free(pBuf); 758 745 } 759 746 else … … 778 765 * @param pEtherAddr Ethernet address to use for the VNIC. 779 766 */ 780 static int SolarisOpenNIC(PDRVTAP pData, const char *pszNICName , struct ether_addr *pEtherAddr)767 static int SolarisOpenNIC(PDRVTAP pData, const char *pszNICName) 781 768 { 782 769 /* … … 795 782 if (rc == DLPI_SUCCESS) 796 783 { 797 rc = dlpi_set_physaddr(pData->pDeviceHandle, DL_CURR_PHYS_ADDR, pEtherAddr->ether_addr_octet, ETHERADDRL);784 rc = dlpi_set_physaddr(pData->pDeviceHandle, DL_CURR_PHYS_ADDR, &pData->MacAddress, ETHERADDRL); 798 785 if (rc == DLPI_SUCCESS) 799 786 { … … 836 823 837 824 /** 838 * Crossbow: delete avirtual NIC.825 * Crossbow: Delete the virtual NIC. 839 826 * 840 827 * @returns VBox error code. … … 843 830 static int SolarisDeleteVNIC(PDRVTAP pData) 844 831 { 845 /* 846 * Extract the VNIC ID from the name. e.g.: "vnic900" we need "900". 847 */ 848 const char *pszVNICName = pData->pszDeviceNameActual; 849 while (*pszVNICName && !isdigit(*pszVNICName)) 850 pszVNICName++; 851 852 if (pszVNICName) 853 { 854 /** @todo r=bird: what about just remembering the VNIC ID? (assuming it's the same as during creation.) */ 855 uint_t VnicID = atoi(pszVNICName); 856 dladm_status_t rc = dladm_vnic_delete(VnicID, DLADM_VNIC_OPT_TEMP); 832 if (pData->pszDeviceNameActual) 833 { 834 dladm_status_t rc = dladm_vnic_delete(pData->uDeviceID, DLADM_VNIC_OPT_TEMP); 857 835 if (rc == DLADM_STATUS_OK) 858 836 return VINF_SUCCESS; … … 863 841 864 842 /** 865 * Crossbow: VNIC comparison hook function. 866 * 867 * @returns VBox error code. 868 * @param pvArg Opaque pointer to a VNIC. 869 * @param pVNICAttr Pointer to another VNIC to compare with the first. 870 */ 871 static dladm_status_t SolarisCompareVNIC(void *pvArg, dladm_vnic_attr_sys_t *pVNICAttr) 872 { 873 dladm_vnic_attr_sys_t *pVNICAttr2 = (dladm_vnic_attr_sys_t *)pvArg; 874 if ( strcmp(pVNICAttr2->va_dev_name, pVNICAttr->va_dev_name) != 0 875 || memcmp(pVNICAttr2->va_mac_addr, pVNICAttr->va_mac_addr, pVNICAttr2->va_mac_len) != 0 876 || pVNICAttr2->va_mac_len != pVNICAttr->va_mac_len) 877 return DLADM_STATUS_OK; 878 879 pVNICAttr->va_vnic_id = pVNICAttr2->va_vnic_id; 880 return DLADM_STATUS_EXIST; 843 * Crossbow: Converts a Solaris DLPI error code to a VBox error code. 844 * 845 * @returns corresponding VBox error code. 846 * @param rc DLPI error code (DLPI_* defines). 847 */ 848 static int SolarisDLPIErr2VBoxErr(int rc) 849 { 850 switch (rc) 851 { 852 case DLPI_SUCCESS: return VINF_SUCCESS; 853 case DLPI_EINVAL: return VERR_INVALID_PARAMETER; 854 case DLPI_ELINKNAMEINVAL: return VERR_INVALID_NAME; 855 case DLPI_EINHANDLE: return VERR_INVALID_HANDLE; 856 case DLPI_ETIMEDOUT: return VERR_TIMEOUT; 857 case DLPI_FAILURE: return VERR_GENERAL_FAILURE; 858 859 case DLPI_EVERNOTSUP: 860 case DLPI_EMODENOTSUP: 861 case DLPI_ERAWNOTSUP: 862 case DLPI_ENOTENOTSUP: 863 case DLPI_EUNAVAILSAP: return VERR_NOT_SUPPORTED; 864 865 /* Define VBox error codes for these, if really needed. */ 866 case DLPI_ENOLINK: 867 case DLPI_EBADLINK: 868 case DLPI_ENOTEIDINVAL: 869 case DLPI_EBADMSG: 870 case DLPI_ENOTSTYLE2: return VERR_GENERAL_FAILURE; 871 } 872 873 AssertMsgFailed(("SolarisDLPIErr2VBoxErr: Unhandled error %d\n", rc)); 874 return VERR_UNRESOLVED_ERROR; 881 875 } 882 876 … … 1125 1119 1126 1120 #ifdef RT_OS_SOLARIS 1127 /** @todo r=bird: exactly where and when this is closed depends on how it was created, see ConsoleImpl.cpp. It's a bit complicated, I know :-/ */1128 1121 if (pData->FileDevice != NIL_RTFILE) 1129 1122 { … … 1153 1146 dlpi_close(pData->pDeviceHandle); 1154 1147 SolarisDeleteVNIC(pData); 1155 MMR3HeapFree(pData->pszMACAddress);1156 1148 # endif 1157 1149 … … 1188 1180 pData->pszDeviceNameActual = NULL; 1189 1181 # ifdef VBOX_WITH_CROSSBOW 1190 pData->pszMACAddress = NULL;1191 1182 pData->pDeviceHandle = NULL; 1183 pData->uDeviceID = 0; 1192 1184 # else 1193 1185 pData->IPFileDevice = NIL_RTFILE; … … 1211 1203 * Validate the config. 1212 1204 */ 1213 if (!CFGMR3AreValuesValid(pCfgHandle, "Device\0InitProg\0TermProg\0FileHandle\0TAPSetupApplication\0TAPTerminateApplication\0MAC Address"))1205 if (!CFGMR3AreValuesValid(pCfgHandle, "Device\0InitProg\0TermProg\0FileHandle\0TAPSetupApplication\0TAPTerminateApplication\0MAC")) 1214 1206 return PDMDRV_SET_ERROR(pDrvIns, VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES, ""); 1215 1207 … … 1255 1247 1256 1248 # ifdef VBOX_WITH_CROSSBOW 1257 rc = CFGMR3Query StringAlloc(pCfgHandle, "MACAddress", &pData->pszMACAddress); /** @todo r=bird: MACAddress -> MAC; pass bytes like for pcnet. See VBoxBFE and ConsoleImpl.cpp comments. */1249 rc = CFGMR3QueryBytes(pCfgHandle, "MAC", &pData->MacAddress, sizeof(pData->MacAddress)); 1258 1250 if (VBOX_FAILURE(rc)) 1259 return PDMDrvHlpVMSetError(pDrvIns, VERR_HOSTIF_INIT_FAILED, RT_SRC_POS, 1260 N_("Failed to query \"MACAddress\"")); 1251 return PDMDRV_SET_ERROR(pDrvIns, rc, N_("Configuration error: Failed to query \"MAC\"")); 1261 1252 # endif 1262 1253 -
trunk/src/VBox/Frontends/VBoxBFE/VBoxBFE.cpp
r5586 r5698 1678 1678 rc = CFGMR3InsertString(pCfg, "Device", g_aNetDevs[ulInstance].pszName); UPDATE_RC(); 1679 1679 # ifdef VBOX_WITH_CROSSBOW 1680 /** @todo r=bird: Just pass the g_aNetDevs[ulInstance].Mac structure as a byte blob 1681 * using CFGMR3InsertBytes() with any mess. */ 1682 // rc = CFGMR3InsertBytes(pCfg, "MAC", &g_aNetDevs[ulInstance].Mac, sizeof(g_aNetDevs[ulInstance].Mac)); 1683 // UPDATE_RC(); 1680 rc = CFGMR3InsertBytes(pCfg, "MAC", &g_aNetDevs[ulInstance].Mac, sizeof(g_aNetDevs[ulInstance].Mac)); 1681 UPDATE_RC(); 1684 1682 # endif 1685 1683 -
trunk/src/VBox/Main/ConsoleImpl2.cpp
r5637 r5698 1026 1026 # ifdef VBOX_WITH_CROSSBOW 1027 1027 /* Crossbow: needs the MAC address for setting up TAP. */ 1028 /** @todo r=bird: pass it as bytes like we do above for the NIC and drop the messy double conversion. */ 1029 //rc = CFGMR3InsertBytes(pCfg, "MAC", &Mac, sizeof(Mac)); RC_CHECK(); 1028 rc = CFGMR3InsertBytes(pCfg, "MAC", &Mac, sizeof(Mac)); RC_CHECK(); 1030 1029 # endif 1031 1030 # else
Note:
See TracChangeset
for help on using the changeset viewer.