Changeset 50013 in vbox
- Timestamp:
- Dec 31, 2013 2:49:40 AM (11 years ago)
- svn:sync-xref-src-repo-rev:
- 91460
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Network/slirp/ip_icmp.c
r50012 r50013 602 602 * ICMP fragmentation is illegal. All machines must accept 576 bytes in one 603 603 * 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 604 606 * 605 607 * @note This function will free msrc! 606 608 */ 607 609 608 #define ICMP_MAXDATALEN ( IP_MSS-28)610 #define ICMP_MAXDATALEN (MSIZE - 28 - ETH_HLEN) 609 611 void icmp_error(PNATState pData, struct mbuf *msrc, u_char type, u_char code, int minsize, const char *message) 610 612 { … … 654 656 } 655 657 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); 669 659 if (!m) 670 660 goto end_error; … … 673 663 m->m_pkthdr.header = mtod(m, void *); 674 664 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 */ 681 669 682 670 /* 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 */ 696 674 697 675 icp->icmp_type = type; … … 700 678 icp->icmp_seq = 0; 701 679 702 memcpy(&icp->icmp_ip, msrc->m_data, s_ip_len); /* report the ip packet */703 704 680 HTONS(icp->icmp_ip.ip_len); 705 681 HTONS(icp->icmp_ip.ip_id); 706 682 HTONS(icp->icmp_ip.ip_off); 707 683 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 708 694 #if DEBUG 709 695 if (message) 710 696 { 711 /* DEBUG : append message to ICMP packet */ 697 712 698 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; 713 709 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 */ 716 717 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 */ 717 719 } 718 720 #else 719 721 NOREF(message); 720 722 #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 722 727 icp->icmp_cksum = 0; 723 728 icp->icmp_cksum = cksum(m, m->m_len);
Note:
See TracChangeset
for help on using the changeset viewer.