int main(int argc, char **argv)
{
    /*
     * Init IPRT.
     */
    int rc = RTR3InitExe(argc, &argv, 0);
    if (RT_FAILURE(rc))
        return RTMsgInitFailure(rc);

    /*
     * Locate a native DTrace command binary.
     */
    bool fIsNativeDTrace = false;
    char szDTraceCmd[RTPATH_MAX];
    szDTraceCmd[0] = '\0';

#if defined(RT_OS_DARWIN) || defined(RT_OS_FREEBSD) || defined(RT_OS_LINUX) || defined(RT_OS_SOLARIS)
    /*
     * 1. Try native first on platforms where it's applicable.
     */
    static const char * const s_apszNativeDTrace[] =
    {
        "/usr/sbin/dtrace",
        "/sbin/dtrace",
        "/usr/bin/dtrace",
        "/bin/dtrace",
        "/usr/local/sbin/dtrace",
        "/usr/local/bin/dtrace"
    };
    if (!RTEnvExist("VBOX_DTRACE_NO_NATIVE"))
        for (uint32_t i = 0; i < RT_ELEMENTS(s_apszNativeDTrace); i++)
            if (RTFileExists(s_apszNativeDTrace[i]))
            {
                fIsNativeDTrace = true;
                strcpy(szDTraceCmd, s_apszNativeDTrace[i]);
# ifdef RT_OS_LINUX
                /** @todo Warn if the dtrace modules haven't been loaded or vboxdrv isn't
                 *        compiled against them. */
# endif
                break;
            }
    if (szDTraceCmd[0] == '\0')
#endif
    {
        /*
         * 2. VBoxDTrace extension pack installed?
         *
         * Note! We cannot use the COM API here because this program is usually
         *       run thru sudo or directly as root, even if the target
         *       VirtualBox process is running as regular user.  This is due to
         *       the privileges required to run dtrace scripts on a host.
         */
        rc = RTPathAppPrivateArch(szDTraceCmd, sizeof(szDTraceCmd));
        if (RT_SUCCESS(rc))
            rc = RTPathAppend(szDTraceCmd, sizeof(szDTraceCmd),
                              VBOX_EXTPACK_INSTALL_DIR RTPATH_SLASH_STR VBOX_EXTPACK_VBOXDTRACE_MANGLED_NAME);
        if (RT_SUCCESS(rc))
            rc = RTPathAppend(szDTraceCmd, sizeof(szDTraceCmd), RTBldCfgTargetDotArch());
        if (RT_SUCCESS(rc))
            rc = RTPathAppend(szDTraceCmd, sizeof(szDTraceCmd), "VBoxDTraceCmd");
        if (RT_SUCCESS(rc))
            rc = RTStrCat(szDTraceCmd, sizeof(szDTraceCmd), RTLdrGetSuff());
        if (RT_FAILURE(rc))
            return RTMsgErrorExit(RTEXITCODE_FAILURE, "Error constructing extension pack path: %Rrc", rc);
        if (!RTFileExists(szDTraceCmd))
            return RTMsgErrorExit(RTEXITCODE_FAILURE,
                                  "Unable to find a DTrace implementation. VBoxDTrace Extension Pack installed?");
        fIsNativeDTrace = false;
    }


    /*
     * Construct a new command line that includes our libary.
     */
    char szDTraceLibDir[RTPATH_MAX];
    rc = RTPathAppPrivateNoArch(szDTraceLibDir, sizeof(szDTraceLibDir));
    if (RT_SUCCESS(rc))
        rc = RTPathAppend(szDTraceLibDir, sizeof(szDTraceLibDir), "dtrace" RTPATH_SLASH_STR "lib");
    if (RT_SUCCESS(rc))
        rc = RTPathAppend(szDTraceLibDir, sizeof(szDTraceLibDir), RTBldCfgTargetArch());
    if (RT_FAILURE(rc))
        return RTMsgErrorExit(RTEXITCODE_FAILURE, "Error constructing dtrace library path for VBox: %Rrc", rc);

    char **papszArgs = (char **)RTMemAlloc((argc + 3) * sizeof(char *));
    if (!papszArgs)
        return RTMsgErrorExit(RTEXITCODE_FAILURE, "No memory for argument list.");

    int cArgs    = 1;
    papszArgs[0] = fIsNativeDTrace ? szDTraceCmd : argv[0];
    if (argc > 1)
    {
        papszArgs[cArgs++] = (char *)"-L";
        papszArgs[cArgs++] = szDTraceLibDir;
    }
    for (int i = 1; i < argc; i++)
        papszArgs[cArgs++] = argv[i];
    papszArgs[cArgs] = NULL;
    Assert(cArgs <= argc + 3);


    /*
     * The native DTrace we execute as a sub-process and wait for.
     */
    RTEXITCODE rcExit;
    if (fIsNativeDTrace)
    {
        RTPROCESS hProc;
        rc = RTProcCreate(szDTraceCmd, papszArgs, RTENV_DEFAULT, 0, &hProc);
        if (RT_SUCCESS(rc))
        {
            RTPROCSTATUS Status;
            rc = RTProcWait(hProc, RTPROCWAIT_FLAGS_BLOCK, &Status);
            if (RT_SUCCESS(rc))
            {
                if (Status.enmReason == RTPROCEXITREASON_NORMAL)
                    rcExit = (RTEXITCODE)Status.iStatus;
                else
                    rcExit = RTEXITCODE_FAILURE;
            }
            else
                rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Error waiting for child process: %Rrc", rc);
        }
        else
            rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Error executing '%s': %Rrc", szDTraceCmd, rc);
    }
    /*
     * While the VBoxDTrace we load and call the main function of.
     */
    else
    {
        RTERRINFOSTATIC ErrInfo;
        RTLDRMOD hMod;
        rc = SUPR3HardenedLdrLoadPlugIn(szDTraceCmd, &hMod, RTErrInfoInitStatic(&ErrInfo));
        if (RT_SUCCESS(rc))
        {
            PFNVBOXDTRACEMAIN pfnVBoxDTraceMain;
            rc = RTLdrGetSymbol(hMod, "VBoxDTraceMain", (void **)&pfnVBoxDTraceMain);
            if (RT_SUCCESS(rc))
                rcExit = (RTEXITCODE)pfnVBoxDTraceMain(cArgs, papszArgs);
            else
                rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Error locating 'VBoxDTraceMain' in '%s': %Rrc", szDTraceCmd, rc);
        }
        else
            rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Error loading '%s': %Rrc (%s)", szDTraceCmd, rc, ErrInfo.szMsg);
    }
    return rcExit;
}
Beispiel #2
0
DECLHIDDEN(int) VUSBSnifferCreate(PVUSBSNIFFER phSniffer, uint32_t fFlags,
                                  const char *pszCaptureFilename, const char *pszDesc)
{
    int rc = VINF_SUCCESS;
    PVUSBSNIFFERINT pThis = NULL;

    pThis = (PVUSBSNIFFERINT)RTMemAllocZ(sizeof(VUSBSNIFFERINT));
    if (pThis)
    {
        pThis->hFile       = NIL_RTFILE;
        pThis->cbBlockCur  = 0;
        pThis->cbBlockMax  = 0;
        pThis->pbBlockData = NULL;
        pThis->hMtx        = NIL_RTSEMFASTMUTEX;

        rc = RTSemFastMutexCreate(&pThis->hMtx);
        if (RT_SUCCESS(rc))
        {
            rc = RTFileOpen(&pThis->hFile, pszCaptureFilename, RTFILE_O_DENY_NONE | RTFILE_O_CREATE_REPLACE | RTFILE_O_WRITE | RTFILE_O_READ);
            if (RT_SUCCESS(rc))
            {
                /* Write header and link type blocks. */
                DumpFileShb Shb;

                Shb.Hdr.u32BlockType        = DUMPFILE_SHB_BLOCK_TYPE;
                Shb.Hdr.u32BlockTotalLength = 0; /* Filled out by lower layer. */
                Shb.u32ByteOrderMagic       = DUMPFILE_SHB_BYTE_ORDER_MAGIC;
                Shb.u16VersionMajor         = DUMPFILE_SHB_VERSION_MAJOR;
                Shb.u16VersionMinor         = DUMPFILE_SHB_VERSION_MINOR;
                Shb.u64SectionLength        = UINT64_C(0xffffffffffffffff); /* -1 */

                /* Write the blocks. */
                rc = vusbSnifferBlockNew(pThis, &Shb.Hdr, sizeof(Shb));
                if (RT_SUCCESS(rc))
                {
                    const char *pszOpt = RTBldCfgTargetDotArch();
                    rc = vusbSnifferAddOption(pThis, DUMPFILE_OPTION_CODE_HARDWARE, pszOpt, strlen(pszOpt) + 1);
                }

                if (RT_SUCCESS(rc))
                {
                    char szTmp[512];
                    size_t cbTmp = sizeof(szTmp);

                    RT_ZERO(szTmp);

                    /* Build the OS code. */
                    rc = RTSystemQueryOSInfo(RTSYSOSINFO_PRODUCT, szTmp, cbTmp);
                    if (RT_SUCCESS(rc))
                    {
                        size_t cb = strlen(szTmp);

                        szTmp[cb] = ' ';
                        rc = RTSystemQueryOSInfo(RTSYSOSINFO_RELEASE, &szTmp[cb + 1], cbTmp - (cb + 1));
                        if (RT_SUCCESS(rc))
                        {
                            cb = strlen(szTmp);
                            szTmp[cb] = ' ';
                            rc = RTSystemQueryOSInfo(RTSYSOSINFO_VERSION, &szTmp[cb + 1], cbTmp - (cb + 1));
                        }
                    }

                    if (RT_SUCCESS(rc) || rc == VERR_BUFFER_OVERFLOW)
                        rc = vusbSnifferAddOption(pThis, DUMPFILE_OPTION_CODE_OS, szTmp, strlen(szTmp) + 1);
                    else
                        rc = VINF_SUCCESS; /* Skip OS code if building the string failed. */
                }

                if (RT_SUCCESS(rc))
                {
                    /** @todo: Add product info. */
                }

                if (RT_SUCCESS(rc))
                    rc = vusbSnifferAddOption(pThis, DUMPFILE_OPTION_CODE_END, NULL, 0);
                if (RT_SUCCESS(rc))
                    rc = vusbSnifferBlockCommit(pThis);

                /* Write Interface descriptor block. */
                if (RT_SUCCESS(rc))
                {
                    DumpFileIdb Idb;

                    Idb.Hdr.u32BlockType        = DUMPFILE_IDB_BLOCK_TYPE;
                    Idb.Hdr.u32BlockTotalLength = 0; /* Filled out by lower layer. */
                    Idb.u16LinkType             = DUMPFILE_IDB_LINK_TYPE_USB_LINUX_MMAPED;
                    Idb.u16Reserved             = 0;
                    Idb.u32SnapLen              = UINT32_C(0xffffffff);

                    rc = vusbSnifferBlockNew(pThis, &Idb.Hdr, sizeof(Idb));
                    if (RT_SUCCESS(rc))
                    {
                        uint8_t u8TsResolution = 9; /* Nano second resolution. */
                        /* Add timestamp resolution option. */
                        rc = vusbSnifferAddOption(pThis, DUMPFILE_IDB_OPTION_TS_RESOLUTION,
                                                  &u8TsResolution, sizeof(u8TsResolution));
                    }
                    if (RT_SUCCESS(rc))
                        rc = vusbSnifferAddOption(pThis, DUMPFILE_OPTION_CODE_END, NULL, 0);
                    if (RT_SUCCESS(rc))
                        rc = vusbSnifferBlockCommit(pThis);
                }

                if (RT_SUCCESS(rc))
                {
                    *phSniffer = pThis;
                    return VINF_SUCCESS;
                }

                RTFileClose(pThis->hFile);
                pThis->hFile = NIL_RTFILE;
                RTFileDelete(pszCaptureFilename);
            }
            RTSemFastMutexDestroy(pThis->hMtx);
            pThis->hMtx = NIL_RTSEMFASTMUTEX;
        }
        RTMemFree(pThis);
    }
    else
        rc = VERR_NO_MEMORY;

    return rc;
}
Beispiel #3
0
static void vboxHeaderFooter(PRTLOGGER pReleaseLogger, RTLOGPHASE enmPhase, PFNRTLOGPHASEMSG pfnLog)
{
    /* some introductory information */
    static RTTIMESPEC s_TimeSpec;
    char szTmp[256];
    if (enmPhase == RTLOGPHASE_BEGIN)
        RTTimeNow(&s_TimeSpec);
    RTTimeSpecToString(&s_TimeSpec, szTmp, sizeof(szTmp));

    switch (enmPhase)
    {
        case RTLOGPHASE_BEGIN:
        {
            bool fOldBuffered = RTLogSetBuffering(pReleaseLogger, true /*fBuffered*/);
            pfnLog(pReleaseLogger,
                   "VirtualBox %s %s r%u %s (%s %s) release log\n"
#ifdef VBOX_BLEEDING_EDGE
                   "EXPERIMENTAL build " VBOX_BLEEDING_EDGE "\n"
#endif
                   "Log opened %s\n",
                   g_pszLogEntity, VBOX_VERSION_STRING, RTBldCfgRevision(),
                   RTBldCfgTargetDotArch(), __DATE__, __TIME__, szTmp);

            int vrc = RTSystemQueryOSInfo(RTSYSOSINFO_PRODUCT, szTmp, sizeof(szTmp));
            if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW)
                pfnLog(pReleaseLogger, "OS Product: %s\n", szTmp);
            vrc = RTSystemQueryOSInfo(RTSYSOSINFO_RELEASE, szTmp, sizeof(szTmp));
            if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW)
                pfnLog(pReleaseLogger, "OS Release: %s\n", szTmp);
            vrc = RTSystemQueryOSInfo(RTSYSOSINFO_VERSION, szTmp, sizeof(szTmp));
            if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW)
                pfnLog(pReleaseLogger, "OS Version: %s\n", szTmp);
            vrc = RTSystemQueryOSInfo(RTSYSOSINFO_SERVICE_PACK, szTmp, sizeof(szTmp));
            if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW)
                pfnLog(pReleaseLogger, "OS Service Pack: %s\n", szTmp);

            vrc = RTSystemQueryDmiString(RTSYSDMISTR_PRODUCT_NAME, szTmp, sizeof(szTmp));
            if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW)
                pfnLog(pReleaseLogger, "DMI Product Name: %s\n", szTmp);
            vrc = RTSystemQueryDmiString(RTSYSDMISTR_PRODUCT_VERSION, szTmp, sizeof(szTmp));
            if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW)
                pfnLog(pReleaseLogger, "DMI Product Version: %s\n", szTmp);

            uint64_t cbHostRam = 0, cbHostRamAvail = 0;
            vrc = RTSystemQueryTotalRam(&cbHostRam);
            if (RT_SUCCESS(vrc))
                vrc = RTSystemQueryAvailableRam(&cbHostRamAvail);
            if (RT_SUCCESS(vrc))
                pfnLog(pReleaseLogger, "Host RAM: %lluMB RAM, available: %lluMB\n",
                       cbHostRam / _1M, cbHostRamAvail / _1M);

            /* the package type is interesting for Linux distributions */
            char szExecName[RTPATH_MAX];
            char *pszExecName = RTProcGetExecutablePath(szExecName, sizeof(szExecName));
            pfnLog(pReleaseLogger,
                   "Executable: %s\n"
                   "Process ID: %u\n"
                   "Package type: %s"
#ifdef VBOX_OSE
                   " (OSE)"
#endif
                   "\n",
                   pszExecName ? pszExecName : "unknown",
                   RTProcSelf(),
                   VBOX_PACKAGE_STRING);
            RTLogSetBuffering(pReleaseLogger, fOldBuffered);
            break;
        }
        case RTLOGPHASE_PREROTATE:
            pfnLog(pReleaseLogger, "Log rotated - Log started %s\n", szTmp);
            break;

        case RTLOGPHASE_POSTROTATE:
            pfnLog(pReleaseLogger, "Log continuation - Log started %s\n", szTmp);
            break;

        case RTLOGPHASE_END:
            pfnLog(pReleaseLogger, "End of log file - Log started %s\n", szTmp);
            break;

        default:
            /* nothing */;
    }
}
Beispiel #4
0
/** @copydoc VUSBSNIFFERFMT::pfnInit */
static DECLCALLBACK(int) vusbSnifferFmtPcanNgInit(PVUSBSNIFFERFMTINT pThis, PVUSBSNIFFERSTRM pStrm)
{
    int rc = VINF_SUCCESS;

    pThis->pStrm       = pStrm;
    pThis->cbBlockCur  = 0;
    pThis->cbBlockMax  = 0;
    pThis->pbBlockData = NULL;

    /* Write header and link type blocks. */
    DumpFileShb Shb;

    Shb.Hdr.u32BlockType        = DUMPFILE_SHB_BLOCK_TYPE;
    Shb.Hdr.u32BlockTotalLength = 0; /* Filled out by lower layer. */
    Shb.u32ByteOrderMagic       = DUMPFILE_SHB_BYTE_ORDER_MAGIC;
    Shb.u16VersionMajor         = DUMPFILE_SHB_VERSION_MAJOR;
    Shb.u16VersionMinor         = DUMPFILE_SHB_VERSION_MINOR;
    Shb.u64SectionLength        = UINT64_C(0xffffffffffffffff); /* -1 */

    /* Write the blocks. */
    rc = vusbSnifferBlockNew(pThis, &Shb.Hdr, sizeof(Shb));
    if (RT_SUCCESS(rc))
    {
        const char *pszOpt = RTBldCfgTargetDotArch();
        rc = vusbSnifferAddOption(pThis, DUMPFILE_OPTION_CODE_HARDWARE, pszOpt, strlen(pszOpt) + 1);
    }

    if (RT_SUCCESS(rc))
    {
        char szTmp[512];
        size_t cbTmp = sizeof(szTmp);

        RT_ZERO(szTmp);

        /* Build the OS code. */
        rc = RTSystemQueryOSInfo(RTSYSOSINFO_PRODUCT, szTmp, cbTmp);
        if (RT_SUCCESS(rc))
        {
            size_t cb = strlen(szTmp);

            szTmp[cb] = ' ';
            rc = RTSystemQueryOSInfo(RTSYSOSINFO_RELEASE, &szTmp[cb + 1], cbTmp - (cb + 1));
            if (RT_SUCCESS(rc))
            {
                cb = strlen(szTmp);
                szTmp[cb] = ' ';
                rc = RTSystemQueryOSInfo(RTSYSOSINFO_VERSION, &szTmp[cb + 1], cbTmp - (cb + 1));
            }
        }

        if (RT_SUCCESS(rc) || rc == VERR_BUFFER_OVERFLOW)
            rc = vusbSnifferAddOption(pThis, DUMPFILE_OPTION_CODE_OS, szTmp, strlen(szTmp) + 1);
        else
            rc = VINF_SUCCESS; /* Skip OS code if building the string failed. */
    }

    if (RT_SUCCESS(rc))
    {
        /** @todo: Add product info. */
    }

    if (RT_SUCCESS(rc))
        rc = vusbSnifferAddOption(pThis, DUMPFILE_OPTION_CODE_END, NULL, 0);
    if (RT_SUCCESS(rc))
        rc = vusbSnifferBlockCommit(pThis);

    /* Write Interface descriptor block. */
    if (RT_SUCCESS(rc))
    {
        DumpFileIdb Idb;

        Idb.Hdr.u32BlockType        = DUMPFILE_IDB_BLOCK_TYPE;
        Idb.Hdr.u32BlockTotalLength = 0; /* Filled out by lower layer. */
        Idb.u16LinkType             = DUMPFILE_IDB_LINK_TYPE_USB_LINUX_MMAPED;
        Idb.u16Reserved             = 0;
        Idb.u32SnapLen              = UINT32_C(0xffffffff);

        rc = vusbSnifferBlockNew(pThis, &Idb.Hdr, sizeof(Idb));
        if (RT_SUCCESS(rc))
        {
            uint8_t u8TsResolution = 9; /* Nano second resolution. */
            /* Add timestamp resolution option. */
            rc = vusbSnifferAddOption(pThis, DUMPFILE_IDB_OPTION_TS_RESOLUTION,
                                      &u8TsResolution, sizeof(u8TsResolution));
        }
        if (RT_SUCCESS(rc))
            rc = vusbSnifferAddOption(pThis, DUMPFILE_OPTION_CODE_END, NULL, 0);
        if (RT_SUCCESS(rc))
            rc = vusbSnifferBlockCommit(pThis);
    }

    if (   RT_FAILURE(rc)
        && pThis->pbBlockData)
        RTMemFree(pThis->pbBlockData);

    return rc;
}