VirtualBox

Changeset 5698 in vbox


Ignore:
Timestamp:
Nov 12, 2007 6:31:09 AM (17 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
26045
Message:

Solaris crossbow changes.

Location:
trunk/src/VBox
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Makefile.kmk

    r5651 r5698  
    525525  Drivers_DEFS += VBOX_WITH_CROSSBOW
    526526  Drivers_INCS += \
    527         Network/solaris \
    528         Network/solaris/sys #why sys?
     527        Network/solaris
    529528 endif
    530529endif
  • trunk/src/VBox/Devices/Network/DrvTAP.cpp

    r5586 r5698  
    3333# include <iprt/asm.h>
    3434# 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
    3542#endif
    3643
     
    102109# ifdef VBOX_WITH_CROSSBOW
    103110    /** Crossbow: MAC address of the device. */
    104     char                   *pszMACAddress;
     111    PDMMAC                  MacAddress;
    105112    /** Crossbow: Handle of the NIC. */
    106113    dlpi_handle_t           pDeviceHandle;
     114    /** Crossbow: ID of the virtual NIC. */
     115    uint_t                  uDeviceID;
    107116# else
    108117    /** IP device file handle (/dev/udp). */
     
    161170
    162171/*******************************************************************************
    163 *   Internal Functions                                                         *
     172*   Internal Functions & Globals                                               *
    164173*******************************************************************************/
    165174#ifdef RT_OS_SOLARIS
     
    167176static int              SolarisCreateVNIC(PDRVTAP pData);
    168177static 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);
     178static int              SolarisOpenNIC(PDRVTAP pData, const char *pszNICName);
     179static int              SolarisDLPIErr2VBoxErr(int rc);
    171180# else
    172181static int              SolarisTAPAttach(PPDMDRVINS pDrvIns);
     
    318327            rc = VINF_SUCCESS;
    319328            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);
    322332#else
    323333            rc = RTFileRead(pData->FileDevice, achBuf, sizeof(achBuf), &cbRead);
     
    457467                int rc = VINF_SUCCESS;
    458468                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);
    461472#else
    462473                int rc = RTFileRead(pData->FileDevice, achBuf, RT_MIN(sizeof(achBuf), cbMax), &cbRead);
     
    507518    pszArgs[2] = NULL;
    508519
    509 /** @todo use RTProcCreate */
    510 
    511520    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! */
    516544        LogRel(("TAP#%d: Failed to fork() process for running TAP setup application: %s\n", pData->pDrvIns->iInstance,
    517545              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;   
    538549}
    539550
     
    552563    pszArgs[2] = NULL;
    553564
    554 /** @todo use RTProcCreate */
    555 
    556565    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! */
    561589        LogRel(("TAP#%d: Failed to fork() process for running TAP terminate application: %s\n", pData->pDrvIns->iInstance,
    562590              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;   
    583593}
    584594
     
    609619
    610620    /*
    611      * Get the MAC address with ':' seperators as ether_aton() needs those
    612      */
    613     /** @todo r=bird: ether_addr is just a byte array, just pass the PDMMAC
    614      * 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     /*
    631621     * Setup VNIC parameters.
    632622     */
    633623    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);
    636630    VNICAttr.va_mac_len = ETHERADDRL;
    637631
     
    652646
    653647    /*
    654      * Create a VNIC if it doesn't already exist.
    655      * XXX: Perhaps VMs should not use existing VNICs???
     648     * Create the VNIC.
    656649     */
    657650/** r=bird: The users should be able to create the vnic himself and pass it down. This would be the
    658651 * 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   
    677662    pData->pszDeviceNameActual = NULL;
    678663    RTStrAPrintf(&pData->pszDeviceNameActual, "vnic%u", VnicID);
    679 
    680     ret = SolarisOpenNIC(pData, szNICName, pEtherAddr);
     664    pData->uDeviceID = VnicID;
     665
     666    ret = SolarisOpenNIC(pData, szNICName);
    681667    if (VBOX_FAILURE(ret))
    682668        return ret;
     
    698684     */
    699685    int InetSocket = socket(AF_INET, SOCK_DGRAM, 0);
    700     if (RT_UNLIKELY(inetSocket == -1))
     686    if (RT_UNLIKELY(InetSocket == -1))
    701687    {
    702688        LogRel(("SolarisGetNIC: Socket creation for AF_INET family failed.\n"));
     
    707693    struct lifnum IfNum;
    708694    IfNum.lifn_family = AF_UNSPEC;
    709     if (ioctl(InetSocket, SIOCGLIFNUM, (char *)&IfNum) >= 0)
     695    if (ioctl(InetSocket, SIOCGLIFNUM, &IfNum) >= 0)
    710696    {
    711697        caddr_t pBuf = (caddr_t)RTMemAlloc(IfNum.lifn_count * sizeof(struct lifreq));
    712         if (pszBuffer)
     698        if (pBuf)
    713699        {
    714700            struct lifconf IfCfg;
    715701            memset(&IfCfg, 0, sizeof(IfCfg));
    716702            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)
    719706            {
    720707                /*
     
    729716                    {
    730717                        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)
    732719                        {
    733720                            dlpi_info_t NICInfo;
     
    755742                rc = VERR_HOSTIF_INIT_FAILED;
    756743            }
    757             free(pszBuffer);
     744            free(pBuf);
    758745        }
    759746        else
     
    778765 * @param   pEtherAddr      Ethernet address to use for the VNIC.
    779766 */
    780 static int SolarisOpenNIC(PDRVTAP pData, const char *pszNICName, struct ether_addr *pEtherAddr)
     767static int SolarisOpenNIC(PDRVTAP pData, const char *pszNICName)
    781768{
    782769    /*
     
    795782    if (rc == DLPI_SUCCESS)
    796783    {
    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);
    798785        if (rc == DLPI_SUCCESS)
    799786        {
     
    836823
    837824/**
    838  * Crossbow: delete a virtual NIC.
     825 * Crossbow: Delete the virtual NIC.
    839826 *
    840827 * @returns VBox error code.
     
    843830static int SolarisDeleteVNIC(PDRVTAP pData)
    844831{
    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);
    857835        if (rc == DLADM_STATUS_OK)
    858836            return VINF_SUCCESS;
     
    863841
    864842/**
    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 */
     848static 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;
    881875}
    882876
     
    11251119
    11261120#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 :-/ */
    11281121    if (pData->FileDevice != NIL_RTFILE)
    11291122    {
     
    11531146    dlpi_close(pData->pDeviceHandle);
    11541147    SolarisDeleteVNIC(pData);
    1155     MMR3HeapFree(pData->pszMACAddress);
    11561148# endif
    11571149
     
    11881180    pData->pszDeviceNameActual          = NULL;
    11891181# ifdef VBOX_WITH_CROSSBOW
    1190     pData->pszMACAddress                = NULL;
    11911182    pData->pDeviceHandle                = NULL;
     1183    pData->uDeviceID                    = 0;
    11921184# else
    11931185    pData->IPFileDevice                 = NIL_RTFILE;
     
    12111203     * Validate the config.
    12121204     */
    1213     if (!CFGMR3AreValuesValid(pCfgHandle, "Device\0InitProg\0TermProg\0FileHandle\0TAPSetupApplication\0TAPTerminateApplication\0MACAddress"))
     1205    if (!CFGMR3AreValuesValid(pCfgHandle, "Device\0InitProg\0TermProg\0FileHandle\0TAPSetupApplication\0TAPTerminateApplication\0MAC"))
    12141206        return PDMDRV_SET_ERROR(pDrvIns, VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES, "");
    12151207
     
    12551247
    12561248# ifdef VBOX_WITH_CROSSBOW
    1257     rc = CFGMR3QueryStringAlloc(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));
    12581250    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\""));
    12611252# endif
    12621253
  • trunk/src/VBox/Frontends/VBoxBFE/VBoxBFE.cpp

    r5586 r5698  
    16781678                    rc = CFGMR3InsertString(pCfg, "Device", g_aNetDevs[ulInstance].pszName); UPDATE_RC();
    16791679# 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();
    16841682# endif
    16851683
  • trunk/src/VBox/Main/ConsoleImpl2.cpp

    r5637 r5698  
    10261026#  ifdef VBOX_WITH_CROSSBOW
    10271027                        /* 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();
    10301029#  endif
    10311030# else
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette