/** * Writes a frame packet to the buffer. * * @returns VBox status code. * @param pBuf The buffer. * @param pRingBuf The ring buffer to read from. * @param cSegs The number of segments. * @param paSegs The segments. */ int VBoxNetIntIfRingWriteFrame(PINTNETBUF pBuf, PINTNETRINGBUF pRingBuf, size_t cSegs, PCINTNETSEG paSegs) { RT_NOREF(pBuf); /* * Validate input. */ AssertPtr(pBuf); AssertPtr(pRingBuf); AssertPtr(paSegs); Assert(cSegs > 0); /* * Calc frame size. */ uint32_t cbFrame = 0; for (size_t iSeg = 0; iSeg < cSegs; iSeg++) cbFrame += paSegs[iSeg].cb; Assert(cbFrame >= sizeof(RTMAC) * 2); /* * Allocate a frame, copy the data and commit it. */ PINTNETHDR pHdr = NULL; void *pvFrame = NULL; int rc = IntNetRingAllocateFrame(pRingBuf, cbFrame, &pHdr, &pvFrame); if (RT_SUCCESS(rc)) { vboxnetIntIfCopySG(pvFrame, cSegs, paSegs); IntNetRingCommitFrame(pRingBuf, pHdr); return VINF_SUCCESS; } return rc; }
/* S/G API */ int VBoxNetBaseService::sendBufferOnWire(PCINTNETSEG paSegs, size_t cSegs, size_t cbFrame) { /* Allocate frame */ PINTNETHDR pHdr = NULL; uint8_t *pbFrame = NULL; int rc = IntNetRingAllocateFrame(&m->m_pIfBuf->Send, (uint32_t)cbFrame, &pHdr, (void **)&pbFrame); AssertRCReturn(rc, rc); /* Now we fill pvFrame with S/G above */ size_t offFrame = 0; for (size_t idxSeg = 0; idxSeg < cSegs; ++idxSeg) { memcpy(&pbFrame[offFrame], paSegs[idxSeg].pv, paSegs[idxSeg].cb); offFrame += paSegs[idxSeg].cb; } /* Commit */ IntNetRingCommitFrameEx(&m->m_pIfBuf->Send, pHdr, cbFrame); LogFlowFuncLeaveRC(rc); return rc; }
/* S/G API */ int VBoxNetBaseService::sendBufferOnWire(PCINTNETSEG pcSg, int cSg, size_t cbFrame) { int rc = VINF_SUCCESS; PINTNETHDR pHdr = NULL; uint8_t *pu8Frame = NULL; int offFrame = 0; int idxSg = 0; /* Allocate frame */ rc = IntNetRingAllocateFrame(&m_pIfBuf->Send, cbFrame, &pHdr, (void **)&pu8Frame); AssertRCReturn(rc, rc); /* Now we fill pvFrame with S/G above */ for (idxSg = 0; idxSg < cSg; ++idxSg) { memcpy(&pu8Frame[offFrame], pcSg[idxSg].pv, pcSg[idxSg].cb); offFrame+=pcSg[idxSg].cb; } /* Commit */ IntNetRingCommitFrame(&m_pIfBuf->Send, pHdr); LogFlowFuncLeaveRC(rc); return rc; }