VirtualBox

Changeset 50013 in vbox


Ignore:
Timestamp:
Dec 31, 2013 2:49:40 AM (11 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
91460
Message:

NAT/ip_icmp.c:

  1. ICMP error send in mbuf allocated from mbuf_zone (256b) that reduces maximum size to 214 bytes of payload, but doesn't require allocate additional buffer from cluster zones.
  2. composing ICMP error datagram is grouped and commented, the calculation of size of the error ICMP payload delayed to the end of function.
File:
1 edited

Legend:

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

    r50012 r50013  
    602602 * ICMP fragmentation is illegal.  All machines must accept 576 bytes in one
    603603 * packet.  The maximum payload is 576-20(ip hdr)-8(icmp hdr)=548
     604 * @note: implementation note: MSIZE is 256 bytes (minimal buffer), m_getjcl we allocate two mbufs on: clust_zone
     605 * and mbuf_zone. the maximum payload 256 - 14 (Ethernet header) - 20 (IPv4 hdr) - 8 (ICMPv4 header) = 214
    604606 *
    605607 * @note This function will free msrc!
    606608 */
    607609
    608 #define ICMP_MAXDATALEN (IP_MSS-28)
     610#define ICMP_MAXDATALEN (MSIZE - 28 - ETH_HLEN)
    609611void icmp_error(PNATState pData, struct mbuf *msrc, u_char type, u_char code, int minsize, const char *message)
    610612{
     
    654656    }
    655657
    656     new_ip_size = sizeof(struct ip) + ICMP_MINLEN + ICMP_MAXDATALEN;
    657     new_m_size = if_maxlinkhdr + new_ip_size;
    658     if (new_m_size < MSIZE)
    659         size = MCLBYTES;
    660     else if (new_m_size < MCLBYTES)
    661         size = MCLBYTES;
    662     else if(new_m_size < MJUM9BYTES)
    663         size = MJUM9BYTES;
    664     else if (new_m_size < MJUM16BYTES)
    665         size = MJUM16BYTES;
    666     else
    667         AssertMsgFailed(("Unsupported size"));
    668     m = m_getjcl(pData, M_NOWAIT, MT_HEADER, M_PKTHDR, size);
     658    m = m_gethdr(pData, M_NOWAIT, MT_HEADER);
    669659    if (!m)
    670660        goto end_error;
     
    673663    m->m_pkthdr.header = mtod(m, void *);
    674664
    675     m->m_len = msrc->m_len < new_ip_size ? msrc->m_len : new_ip_size;
    676     memcpy(m->m_data, msrc->m_data, m->m_len);   /* copy msrc to m */
    677 
    678     /* make the header of the reply packet */
    679     ip   = mtod(m, struct ip *);
    680     hlen = sizeof(struct ip);             /* no options in reply */
     665    memcpy(m->m_pkthdr.header, ip, shlen); /* initialize respond IP header with data from original one. */
     666
     667    ip   = mtod(m, struct ip *); /* ip points to new IP header */
     668    hlen = sizeof(struct ip);  /* trim the IP header no options in reply */
    681669
    682670    /* fill in icmp */
    683     m->m_data += hlen;
    684     m->m_len  -= hlen;
    685 
    686     icp = mtod(m, struct icmp *);
    687 
    688     if (minsize)
    689         s_ip_len = shlen+ICMP_MINLEN;      /* return header+8b only */
    690     else if (s_ip_len > ICMP_MAXDATALEN)   /* maximum size */
    691         s_ip_len = ICMP_MAXDATALEN;
    692 
    693     m->m_len = ICMP_MINLEN + s_ip_len;     /* 8 bytes ICMP header */
    694 
    695     /* min. size = 8+sizeof(struct ip)+8 */
     671    m->m_data += hlen; /* shifts m_data to ICMP header */
     672    icp = mtod(m, struct icmp *); /* _icp_: points to the ICMP header */
     673    m->m_data += RT_OFFSETOF(struct icmp, icmp_ip); /* shifts m_data to IP header payload */
    696674
    697675    icp->icmp_type = type;
     
    700678    icp->icmp_seq = 0;
    701679
    702     memcpy(&icp->icmp_ip, msrc->m_data, s_ip_len);   /* report the ip packet */
    703 
    704680    HTONS(icp->icmp_ip.ip_len);
    705681    HTONS(icp->icmp_ip.ip_id);
    706682    HTONS(icp->icmp_ip.ip_off);
    707683
     684    memcpy(mtod(m, void *), mtod(msrc, void *), shlen);  /* copy original IP header (with options) */
     685    msrc->m_data += shlen; /* _msrc_: shifts m_data of original mbuf to the end of original IP header */
     686    msrc->m_len -= shlen; /* _msrc_: alter m_len to size of original IP datagram payload */
     687    m->m_data += shlen; /* _m_: shifts m_data to the end of reported IP datagram */
     688    /* initialize reported payload of original datagram  with MUST size RFC792 or with rest of allocated mbuf */
     689    s_ip_len = minsize ? 8 : M_TRAILINGSPACE(m);
     690    /* trims original IP datagram's payload to the lenght of its mbuf size or already reserved space if it's smaller */
     691    s_ip_len = RT_MIN(s_ip_len, msrc->m_len);
     692    memcpy(mtod(m, void *), mtod(msrc, void *), s_ip_len);
     693
    708694#if DEBUG
    709695    if (message)
    710696    {
    711         /* DEBUG : append message to ICMP packet */
     697
    712698        size_t message_len;
     699        /**
     700         * Trim reported payload to first eight bytes (RFC792) to let sniffering tools do
     701         * their audit duties, and add hint message to the tail of mandatory piece.
     702         */
     703        s_ip_len = 8;
     704        /**
     705         * _m_: shifts m_data to the end of mandatory 8b piece to let M_TRAILINGSPACE
     706         * to returns available space with counting mandatory region.
     707         */
     708        m->m_data += s_ip_len;
    713709        message_len = strlen(message);
    714         if (message_len > ICMP_MAXDATALEN)
    715             message_len = ICMP_MAXDATALEN;
     710        if (message_len > M_TRAILINGSPACE(m))
     711            message_len = M_TRAILINGSPACE(m);
     712   
     713        /**
     714         * m->m_data points to the end of 8 bytes payload, and m->m_len is length of appended
     715         * message.
     716         */
    716717        m_append(pData, m, (int)message_len, message);
     718        m->m_data -= s_ip_len; /* now we're ready for further processing, with pointing to mandatory payload */
    717719    }
    718720#else
    719721    NOREF(message);
    720722#endif
    721 
     723   
     724    m->m_data -= shlen + RT_OFFSETOF(struct icmp, icmp_ip); /* _m_: shifts m_data to the start of ICMP header */
     725    m->m_len += s_ip_len + shlen + RT_OFFSETOF(struct icmp, icmp_ip); /* _m_: m_len counts bytes in IP payload */
     726   
    722727    icp->icmp_cksum = 0;
    723728    icp->icmp_cksum = cksum(m, m->m_len);
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