VirtualBox

Changeset 41996 in vbox


Ignore:
Timestamp:
Jul 3, 2012 10:55:24 AM (13 years ago)
Author:
vboxsync
Message:

NAT: enhances TFTP option handling.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Network/slirp/tftp.c

    r41995 r41996  
    5555} ENMTFTPSESSIONFMT;
    5656
     57typedef struct TFPTPSESSIONOPTDESC
     58{
     59    int fRequested;
     60    int u16Value;
     61} TFPTPSESSIONOPTDESC, *PTFPTPSESSIONOPTDESC;
     62
    5763typedef struct TFTPSESSION
    5864{
     
    6369    int         iTimestamp;
    6470    ENMTFTPSESSIONFMT enmTftpFmt;
    65     uint16_t    u16BlkSize;
    66     uint16_t    u16TSize;
    67     uint16_t    u16Size;
    68     uint16_t    u16Timeout;
     71    TFPTPSESSIONOPTDESC OptionBlkSize;
     72    TFPTPSESSIONOPTDESC OptionTSize;
     73    TFPTPSESSIONOPTDESC OptionSize;
     74    TFPTPSESSIONOPTDESC OptionTimeout;
    6975} TFTPSESSION, *PTFTPSESSION, **PPTFTPSESSION;
    7076
     
    115121};
    116122
    117 static uint16_t g_au16RFC2348TftpSessionBlkSize[] =
    118 {
    119     512,
    120     1024,
    121     1428,
    122     2048,
    123     4096,
    124     8192
    125 };
    126 
    127123/**
    128124 * This function evaluate file name.
     
    262258{
    263259    pTftpSession->fInUse = 0;
     260}
     261
     262DECLINLINE(int)tftpSessionParseAndMarkOption(const char *pcszRawOption, PTFPTPSESSIONOPTDESC pTftpSessionOption)
     263{
     264    int rc  = VINF_SUCCESS;
     265    rc = RTStrToInt16Full(pcszRawOption, 0, (int16_t *)&pTftpSessionOption->u16Value);
     266    AssertRCReturn(rc, rc);
     267    pTftpSessionOption->fRequested = 1;
     268    return rc;
    264269}
    265270
     
    306311        {
    307312            if (!RTStrICmp("blksize", g_TftpDesc[idxOptionArg].pszName))
    308                 rc = RTStrToInt16Full(pszTftpRRQRaw, 0, (int16_t *)&pTftpSession->u16BlkSize);
     313                rc = tftpSessionParseAndMarkOption(pszTftpRRQRaw, &pTftpSession->OptionBlkSize);
    309314            else if (!RTStrICmp("size", g_TftpDesc[idxOptionArg].pszName))
    310                 rc = RTStrToInt16Full(pszTftpRRQRaw, 0, (int16_t *)&pTftpSession->u16Size);
     315                rc = tftpSessionParseAndMarkOption(pszTftpRRQRaw, &pTftpSession->OptionSize);
    311316            else if (!RTStrICmp("tsize", g_TftpDesc[idxOptionArg].pszName))
    312                 rc = RTStrToInt16Full(pszTftpRRQRaw, 0, (int16_t *)&pTftpSession->u16TSize);
     317                rc = tftpSessionParseAndMarkOption(pszTftpRRQRaw, &pTftpSession->OptionTSize);
    313318            else if (!RTStrICmp("timeoute", g_TftpDesc[idxOptionArg].pszName))
    314                 rc = RTStrToInt16Full(pszTftpRRQRaw, 0, (int16_t *)&pTftpSession->u16Timeout);
     319                rc = tftpSessionParseAndMarkOption(pszTftpRRQRaw, &pTftpSession->OptionSize);
    315320            else
    316321                rc = VERR_INVALID_PARAMETER;
     
    431436
    432437/* @todo: rewrite this */
    433 DECLINLINE(int) tftpSessionEvaluateBlkSize(PNATState pData, PTFTPSESSION pTftpSession)
     438DECLINLINE(int) tftpSessionEvaluateOptions(PNATState pData, PTFTPSESSION pTftpSession)
    434439{
    435440    int rc = VINF_SUCCESS;
    436441    RTFILE hSessionFile;
    437442    uint64_t cbSessionFile = 0;
    438     int      idxRFC2348TftpSessionBlkSize = 0;
    439     uint32_t cBlockSessionFile = 0;
    440443    LogFlowFunc(("pTftpSession:%p\n", pTftpSession));
    441444
     
    455458    }
    456459
    457     if (!pTftpSession->u16BlkSize)
    458     {
    459         pTftpSession->u16BlkSize = 1428;
    460     }
    461     cBlockSessionFile = ASMDivU64ByU32RetU32(cbSessionFile, pTftpSession->u16BlkSize);
    462     while (   cBlockSessionFile >= UINT16_MAX
    463            && idxRFC2348TftpSessionBlkSize < RT_ELEMENTS(g_au16RFC2348TftpSessionBlkSize))
    464     {
    465         if (pTftpSession->u16BlkSize > g_au16RFC2348TftpSessionBlkSize[idxRFC2348TftpSessionBlkSize])
    466         {
    467             idxRFC2348TftpSessionBlkSize++;
    468             continue;
    469         }
    470 
    471 
    472         idxRFC2348TftpSessionBlkSize++;
    473         /* No bigger values in RFC2348 */
    474         AssertReturn(idxRFC2348TftpSessionBlkSize < RT_ELEMENTS(g_au16RFC2348TftpSessionBlkSize), VERR_INTERNAL_ERROR);
    475         if (g_au16RFC2348TftpSessionBlkSize[idxRFC2348TftpSessionBlkSize] >= if_maxlinkhdr)
    476         {
    477             /* Buffer size is too large for current settings */
    478             rc = VERR_BUFFER_OVERFLOW;
    479             LogFlowFuncLeaveRC(rc);
    480         }
     460    if (pTftpSession->OptionTSize.fRequested)
     461        pTftpSession->OptionTSize.u16Value = (uint16_t)cbSessionFile;
     462    if (   !pTftpSession->OptionBlkSize.u16Value
     463        && !pTftpSession->OptionBlkSize.fRequested)
     464    {
     465        pTftpSession->OptionBlkSize.u16Value = 1428;
    481466    }
    482467    LogFlowFuncLeaveRC(rc);
     
    508493
    509494DECLINLINE(int) tftpReadDataBlock(PNATState pData,
    510                                   PTFTPSESSION pTftpSession,
     495                                  PTFTPSESSION pcTftpSession,
    511496                                  uint16_t u16BlockNr,
    512497                                  uint8_t *pu8Data,
     
    515500    RTFILE  hSessionFile;
    516501    int rc = VINF_SUCCESS;
    517     LogFlowFunc(("pTftpSession:%p, u16BlockNr:%RX16, pu8Data:%p, pcbReadData:%p\n",
    518                     pTftpSession,
     502    uint16_t u16BlkSize = 0;
     503    AssertPtrReturn(pData, VERR_INVALID_PARAMETER);
     504    AssertPtrReturn(pcTftpSession, VERR_INVALID_PARAMETER);
     505    AssertPtrReturn(pu8Data, VERR_INVALID_PARAMETER);
     506    AssertPtrReturn(pcbReadData, VERR_INVALID_PARAMETER);
     507    LogFlowFunc(("pcTftpSession:%p, u16BlockNr:%RX16, pu8Data:%p, pcbReadData:%p\n",
     508                    pcTftpSession,
    519509                    u16BlockNr,
    520510                    pu8Data,
    521511                    pcbReadData));
    522512
    523     rc = pftpSessionOpenFile(pData, pTftpSession, &hSessionFile);
     513    u16BlkSize = pcTftpSession->OptionBlkSize.u16Value;
     514    rc = pftpSessionOpenFile(pData, pcTftpSession, &hSessionFile);
    524515    if (RT_FAILURE(rc))
    525516    {
     
    531522    {
    532523        rc = RTFileSeek(hSessionFile,
    533                         u16BlockNr * pTftpSession->u16BlkSize,
     524                        u16BlockNr * u16BlkSize,
    534525                        RTFILE_SEEK_BEGIN,
    535526                        NULL);
     
    540531            return rc;
    541532        }
    542         rc = RTFileRead(hSessionFile, pu8Data, pTftpSession->u16BlkSize, (size_t *)pcbReadData);
     533        rc = RTFileRead(hSessionFile, pu8Data, u16BlkSize, (size_t *)pcbReadData);
    543534        if (RT_FAILURE(rc))
    544535        {
     
    587578    int rc = VINF_SUCCESS;
    588579
    589     rc = tftpSessionEvaluateBlkSize(pData, pTftpSession);
     580    rc = tftpSessionEvaluateOptions(pData, pTftpSession);
    590581    if (RT_FAILURE(rc))
    591582    {
     
    608599    pTftpIpHeader->u16TftpOpType = RT_H2N_U16_C(TFTP_OACK);
    609600
    610     if (pTftpSession->u16BlkSize)
    611         rc = tftpAddOptionToOACK(pData, m, "blksize", pTftpSession->u16BlkSize);
    612     if (   RT_SUCCESS(rc)
    613         && pTftpSession->u16Size)
    614         rc = tftpAddOptionToOACK(pData, m, "size", pTftpSession->u16Size);
    615     if (   RT_SUCCESS(rc)
    616         && pTftpSession->u16TSize)
    617         rc = tftpAddOptionToOACK(pData, m, "tsize", pTftpSession->u16TSize);
     601    if (pTftpSession->OptionBlkSize.fRequested)
     602        rc = tftpAddOptionToOACK(pData, m, "blksize", pTftpSession->OptionBlkSize.u16Value);
     603    else if (pTftpSession->OptionSize.fRequested)
     604        rc = tftpAddOptionToOACK(pData, m, "size", pTftpSession->OptionSize.u16Value);
     605    else if (pTftpSession->OptionTSize.fRequested)
     606        rc = tftpAddOptionToOACK(pData, m, "tsize", pTftpSession->OptionTSize.u16Value);
    618607
    619608    rc = tftpSend(pData, pTftpSession, m, pcTftpIpHeaderRecv);
Note: See TracChangeset for help on using the changeset viewer.

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