VirtualBox

Changeset 17780 in vbox


Ignore:
Timestamp:
Mar 12, 2009 10:23:53 PM (16 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
44313
Message:

sending reply

Location:
trunk/src/VBox/NetworkServices
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/NetworkServices/DHCP/VBoxNetDHCP.cpp

    r17779 r17780  
    15481548     * Send it.
    15491549     */
    1550 
     1550    int rc;
     1551#if 0
     1552    if (pDhcpMsg->bp_flags & RTNET_DHCP_FLAGS_NO_BROADCAST)
     1553    {
     1554        RTNETADDRIPV4 IPv4AddrBrdCast;
     1555        IPv4AddrBrdCast.u = UINT32_C(0xffffffff); /* broadcast IP */
     1556        rc = VBoxNetUDPUnicast(m_pSession, m_hIf, m_pIfBuf,
     1557                               m_Ipv4Address, &m_MacAddress, RTNETIPV4_PORT_BOOTPS,                 /* sender */
     1558                               IPv4AddrBrdCast, &pDhcpMsg->bp_chaddr.Mac, RTNETIPV4_PORT_BOOTPC,    /* receiver */
     1559                               pReply, cbReply);
     1560    }
     1561    else
     1562#endif
     1563        rc = VBoxNetUDPBroadcast(m_pSession, m_hIf, m_pIfBuf,
     1564                                 m_Ipv4Address, &m_MacAddress, RTNETIPV4_PORT_BOOTPS,               /* sender */
     1565                                 RTNETIPV4_PORT_BOOTPC,                                             /* receiver port */
     1566                                 pReply, cbReply);
     1567    if (RT_FAILURE(rc))
     1568        debugPrint(0, true, "error %Rrc when sending the reply", rc);
    15511569}
    15521570
  • trunk/src/VBox/NetworkServices/UDPLib/VBoxNetUDP.cpp

    r17403 r17780  
    2323*   Header Files                                                               *
    2424*******************************************************************************/
     25#define LOG_GROUP LOG_GROUP_DEFAULT
    2526#include "VBoxNetUDP.h"
    2627#include <iprt/stream.h>
    2728#include <iprt/string.h>
     29#include <iprt/rand.h>
     30#include <VBox/vmm.h>
     31#include <VBox/log.h>
    2832
    2933
     
    151155}
    152156
     157
     158/**
     159 * Flushes the send buffer.
     160 *
     161 * @returns VBox status code.
     162 * @param   pSession        The support driver session.
     163 * @param   hIf             The interface handle to flush.
     164 */
     165static int vboxnetudpFlush(PSUPDRVSESSION pSession, INTNETIFHANDLE hIf)
     166{
     167    INTNETIFSENDREQ SendReq;
     168    SendReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
     169    SendReq.Hdr.cbReq    = sizeof(SendReq);
     170    SendReq.pSession     = pSession;
     171    SendReq.hIf          = hIf;
     172    return SUPCallVMMR0Ex(NIL_RTR0PTR, VMMR0_DO_INTNET_IF_SEND, 0, &SendReq.Hdr);
     173}
     174
     175
     176/**
     177 * Copys the SG segments into the specified fram.
     178 *
     179 * @param   pvFrame     The frame buffer.
     180 * @param   cSegs       The number of segments.
     181 * @param   paSegs      The segments.
     182 */
     183static void vboxnetudpCopySG(void *pvFrame, size_t cSegs, PCINTNETSEG paSegs)
     184{
     185    uint8_t *pbDst = (uint8_t *)pvFrame;
     186    for (size_t iSeg = 0; iSeg < cSegs; iSeg++)
     187    {
     188        memcpy(pbDst, paSegs[iSeg].pv, paSegs[iSeg].cb);
     189        pbDst += paSegs[iSeg].cb;
     190    }
     191}
     192
     193
     194/**
     195 * Writes a frame packet to the buffer.
     196 *
     197 * @returns VBox status code.
     198 * @param   pBuf        The buffer.
     199 * @param   pRingBuf    The ring buffer to read from.
     200 * @param   cSegs       The number of segments.
     201 * @param   paSegs      The segments.
     202 * @remark  This is the same as INTNETRingWriteFrame and
     203 *          drvIntNetRingWriteFrame.
     204 */
     205static int vboxnetudpRingWriteFrame(PINTNETBUF pBuf, PINTNETRINGBUF pRingBuf,
     206                                    size_t cSegs, PCINTNETSEG paSegs)
     207{
     208    /*
     209     * Validate input.
     210     */
     211    Assert(pBuf);
     212    Assert(pRingBuf);
     213    uint32_t offWrite = pRingBuf->offWrite;
     214    Assert(offWrite == RT_ALIGN_32(offWrite, sizeof(INTNETHDR)));
     215    uint32_t offRead = pRingBuf->offRead;
     216    Assert(offRead == RT_ALIGN_32(offRead, sizeof(INTNETHDR)));
     217    AssertPtr(paSegs);
     218    Assert(cSegs > 0);
     219
     220    /* Calc frame size. */
     221    uint32_t cbFrame = 0;
     222    for (size_t iSeg = 0; iSeg < cSegs; iSeg++)
     223        cbFrame += paSegs[iSeg].cb;
     224
     225    Assert(cbFrame >= sizeof(RTMAC) * 2);
     226
     227
     228    const uint32_t cb = RT_ALIGN_32(cbFrame, sizeof(INTNETHDR));
     229    if (offRead <= offWrite)
     230    {
     231        /*
     232         * Try fit it all before the end of the buffer.
     233         */
     234        if (pRingBuf->offEnd - offWrite >= cb + sizeof(INTNETHDR))
     235        {
     236            PINTNETHDR pHdr = (PINTNETHDR)((uint8_t *)pBuf + offWrite);
     237            pHdr->u16Type  = INTNETHDR_TYPE_FRAME;
     238            pHdr->cbFrame  = cbFrame;
     239            pHdr->offFrame = sizeof(INTNETHDR);
     240
     241            vboxnetudpCopySG(pHdr + 1, cSegs, paSegs);
     242
     243            offWrite += cb + sizeof(INTNETHDR);
     244            Assert(offWrite <= pRingBuf->offEnd && offWrite >= pRingBuf->offStart);
     245            if (offWrite >= pRingBuf->offEnd)
     246                offWrite = pRingBuf->offStart;
     247            Log2(("WriteFrame: offWrite: %#x -> %#x (1)\n", pRingBuf->offWrite, offWrite));
     248            ASMAtomicXchgU32(&pRingBuf->offWrite, offWrite);
     249            return VINF_SUCCESS;
     250        }
     251
     252        /*
     253         * Try fit the frame at the start of the buffer.
     254         * (The header fits before the end of the buffer because of alignment.)
     255         */
     256        AssertMsg(pRingBuf->offEnd - offWrite >= sizeof(INTNETHDR), ("offEnd=%x offWrite=%x\n", pRingBuf->offEnd, offWrite));
     257        if (offRead - pRingBuf->offStart > cb) /* not >= ! */
     258        {
     259            PINTNETHDR  pHdr = (PINTNETHDR)((uint8_t *)pBuf + offWrite);
     260            void       *pvFrameOut = (PINTNETHDR)((uint8_t *)pBuf + pRingBuf->offStart);
     261            pHdr->u16Type  = INTNETHDR_TYPE_FRAME;
     262            pHdr->cbFrame  = cbFrame;
     263            pHdr->offFrame = (intptr_t)pvFrameOut - (intptr_t)pHdr;
     264
     265            vboxnetudpCopySG(pvFrameOut, cSegs, paSegs);
     266
     267            offWrite = pRingBuf->offStart + cb;
     268            ASMAtomicXchgU32(&pRingBuf->offWrite, offWrite);
     269            Log2(("WriteFrame: offWrite: %#x -> %#x (2)\n", pRingBuf->offWrite, offWrite));
     270            return VINF_SUCCESS;
     271        }
     272    }
     273    /*
     274     * The reader is ahead of the writer, try fit it into that space.
     275     */
     276    else if (offRead - offWrite > cb + sizeof(INTNETHDR)) /* not >= ! */
     277    {
     278        PINTNETHDR pHdr = (PINTNETHDR)((uint8_t *)pBuf + offWrite);
     279        pHdr->u16Type  = INTNETHDR_TYPE_FRAME;
     280        pHdr->cbFrame  = cbFrame;
     281        pHdr->offFrame = sizeof(INTNETHDR);
     282
     283        vboxnetudpCopySG(pHdr + 1, cSegs, paSegs);
     284
     285        offWrite += cb + sizeof(INTNETHDR);
     286        ASMAtomicXchgU32(&pRingBuf->offWrite, offWrite);
     287        Log2(("WriteFrame: offWrite: %#x -> %#x (3)\n", pRingBuf->offWrite, offWrite));
     288        return VINF_SUCCESS;
     289    }
     290
     291    /* (it didn't fit) */
     292    /** @todo stats */
     293    return VERR_BUFFER_OVERFLOW;
     294}
     295
     296
     297/** Internal worker for VBoxNetUDPUnicast and VBoxNetUDPBroadcast. */
     298static int vboxnetudpSend(PSUPDRVSESSION pSession, INTNETIFHANDLE hIf, PINTNETBUF pBuf,
     299                          RTNETADDRIPV4 SrcIPv4Addr, PCRTMAC pSrcMacAddr, unsigned uSrcPort,
     300                          RTNETADDRIPV4 DstIPv4Addr, PCRTMAC pDstMacAddr, unsigned uDstPort,
     301                          void const *pvData, size_t cbData)
     302{
     303    INTNETSEG aSegs[4];
     304
     305    /* the Ethernet header */
     306    RTNETETHERHDR EtherHdr;
     307    EtherHdr.DstMac     = *pDstMacAddr;
     308    EtherHdr.SrcMac     = *pSrcMacAddr;
     309    EtherHdr.EtherType  = RT_H2BE_U16_C(RTNET_ETHERTYPE_IPV4);
     310
     311    aSegs[0].pv   = &EtherHdr;
     312    aSegs[0].cb   = sizeof(EtherHdr);
     313    aSegs[0].Phys = NIL_RTHCPHYS;
     314
     315    /* the IP header */
     316    RTNETIPV4 IpHdr;
     317    IpHdr.ip_v          = 4;
     318    IpHdr.ip_hl         = sizeof(RTNETIPV4) / sizeof(uint32_t);
     319    IpHdr.ip_tos        = 0;
     320    IpHdr.ip_len        = RT_H2BE_U16(cbData + sizeof(RTNETUDP) + sizeof(RTNETIPV4));
     321    IpHdr.ip_id         = (uint16_t)RTRandU32();
     322    IpHdr.ip_off        = 0;
     323    IpHdr.ip_ttl        = 255;
     324    IpHdr.ip_p          = RTNETIPV4_PROT_UDP;
     325    IpHdr.ip_sum        = 0;
     326    IpHdr.ip_src.u      = 0;
     327    IpHdr.ip_dst.u      = UINT32_C(0xffffffff); /* broadcast */
     328    IpHdr.ip_sum        = RTNetIPv4HdrChecksum(&IpHdr);
     329
     330    aSegs[1].pv   = &IpHdr;
     331    aSegs[1].cb   = sizeof(IpHdr);
     332    aSegs[1].Phys = NIL_RTHCPHYS;
     333
     334
     335    /* the UDP bit */
     336    RTNETUDP UdpHdr;
     337    UdpHdr.uh_sport     = RT_H2BE_U16(uSrcPort);
     338    UdpHdr.uh_dport     = RT_H2BE_U16(uDstPort);
     339    UdpHdr.uh_ulen      = RT_H2BE_U16(cbData + sizeof(RTNETUDP));
     340#if 0
     341    UdpHdr.uh_sum       = 0; /* pretend checksumming is disabled */
     342#else
     343    UdpHdr.uh_sum       = RTNetIPv4UDPChecksum(&IpHdr, &UdpHdr, pvData);
     344#endif
     345
     346    aSegs[2].pv   = &UdpHdr;
     347    aSegs[2].cb   = sizeof(UdpHdr);
     348    aSegs[2].Phys = NIL_RTHCPHYS;
     349
     350    /* the payload */
     351    aSegs[3].pv   = (void *)pvData;
     352    aSegs[3].cb   = cbData;
     353    aSegs[3].Phys = NIL_RTHCPHYS;
     354
     355
     356    /* write it */
     357    int rc = vboxnetudpRingWriteFrame(pBuf, &pBuf->Send, RT_ELEMENTS(aSegs), &aSegs[0]);
     358    int rc2 = vboxnetudpFlush(pSession, hIf);
     359    if (RT_FAILURE(rc))
     360    {
     361        rc = vboxnetudpRingWriteFrame(pBuf, &pBuf->Send, RT_ELEMENTS(aSegs), &aSegs[0]);
     362        rc2 = vboxnetudpFlush(pSession, hIf);
     363    }
     364
     365    if (RT_SUCCESS(rc))
     366        rc = rc2;
     367    return rc;
     368}
     369
     370
     371/**
     372 * Sends an unicast UDP packet.
     373 *
     374 * @returns VBox status code.
     375 * @param   pSession        The support driver session handle.
     376 * @param   hIf             The interface handle.
     377 * @param   pBuf            The interface buffer.
     378 * @param   SrcIPv4Addr     The source IPv4 address.
     379 * @param   pSrcMacAddr     The source MAC address.
     380 * @param   uSrcPort        The source port number.
     381 * @param   DstIPv4Addr     The destination IPv4 address. Can be broadcast.
     382 * @param   pDstMacAddr     The destination MAC address.
     383 * @param   uDstPort        The destination port number.
     384 * @param   pvData          The data payload.
     385 * @param   cbData          The size of the data payload.
     386 */
     387int     VBoxNetUDPUnicast(PSUPDRVSESSION pSession, INTNETIFHANDLE hIf, PINTNETBUF pBuf,
     388                          RTNETADDRIPV4 SrcIPv4Addr, PCRTMAC pSrcMacAddr, unsigned uSrcPort,
     389                          RTNETADDRIPV4 DstIPv4Addr, PCRTMAC pDstMacAddr, unsigned uDstPort,
     390                          void const *pvData, size_t cbData)
     391{
     392    return vboxnetudpSend(pSession, hIf, pBuf,
     393                          SrcIPv4Addr, pSrcMacAddr, uSrcPort,
     394                          DstIPv4Addr, pDstMacAddr, uDstPort,
     395                          pvData, cbData);
     396}
     397
     398
     399/**
     400 * Sends a broadcast UDP packet.
     401 *
     402 * @returns VBox status code.
     403 * @param   pSession        The support driver session handle.
     404 * @param   hIf             The interface handle.
     405 * @param   pBuf            The interface buffer.
     406 * @param   SrcIPv4Addr     The source IPv4 address.
     407 * @param   pSrcMacAddr     The source MAC address.
     408 * @param   uSrcPort        The source port number.
     409 * @param   uDstPort        The destination port number.
     410 * @param   pvData          The data payload.
     411 * @param   cbData          The size of the data payload.
     412 */
     413int     VBoxNetUDPBroadcast(PSUPDRVSESSION pSession, INTNETIFHANDLE hIf, PINTNETBUF pBuf,
     414                            RTNETADDRIPV4 SrcIPv4Addr, PCRTMAC pSrcMacAddr, unsigned uSrcPort,
     415                            unsigned uDstPort,
     416                            void const *pvData, size_t cbData)
     417{
     418    RTNETADDRIPV4   IPv4AddrBrdCast;
     419    IPv4AddrBrdCast.u = UINT32_C(0xffffffff);
     420    RTMAC           MacBrdCast;
     421    MacBrdCast.au16[0] = MacBrdCast.au16[1] = MacBrdCast.au16[2] = UINT16_C(0xffff);
     422
     423    return vboxnetudpSend(pSession, hIf, pBuf,
     424                          SrcIPv4Addr, pSrcMacAddr, uSrcPort,
     425                          IPv4AddrBrdCast, &MacBrdCast, uDstPort,
     426                          pvData, cbData);
     427}
     428
  • trunk/src/VBox/NetworkServices/UDPLib/VBoxNetUDP.h

    r17374 r17780  
    5151/** @}  */
    5252
    53 void *VBoxNetUDPMatch(PCINTNETBUF pBuf, unsigned uDstPort, PCRTMAC pDstMac, uint32_t fFlags, PVBOXNETUDPHDRS pHdrs, size_t *pcb);
    54 
     53void *  VBoxNetUDPMatch(PCINTNETBUF pBuf, unsigned uDstPort, PCRTMAC pDstMac, uint32_t fFlags, PVBOXNETUDPHDRS pHdrs, size_t *pcb);
     54int     VBoxNetUDPUnicast(PSUPDRVSESSION pSession, INTNETIFHANDLE hIf, PINTNETBUF pBuf,
     55                          RTNETADDRIPV4 SrcIPv4Addr, PCRTMAC SrcMacAddr, unsigned uSrcPort,
     56                          RTNETADDRIPV4 DstIPv4Addr, PCRTMAC DstMacAddr, unsigned uDstPort,
     57                          void const *pvData, size_t cbData);
     58int     VBoxNetUDPBroadcast(PSUPDRVSESSION pSession, INTNETIFHANDLE hIf, PINTNETBUF pBuf,
     59                            RTNETADDRIPV4 SrcIPv4Addr, PCRTMAC SrcMacAddr, unsigned uSrcPort,
     60                            unsigned uDstPort,
     61                            void const *pvData, size_t cbData);
    5562
    5663__END_DECLS
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