Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F168171425
D17922.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
2 KB
Referenced Files
None
Subscribers
None
D17922.diff
View Options
Index: head/sys/netinet/ip_reass.c
===================================================================
--- head/sys/netinet/ip_reass.c
+++ head/sys/netinet/ip_reass.c
@@ -211,19 +211,21 @@
* convert offset of this to bytes.
*/
ip->ip_len = htons(ntohs(ip->ip_len) - hlen);
- if (ip->ip_off & htons(IP_MF)) {
- /*
- * Make sure that fragments have a data length
- * that's a non-zero multiple of 8 bytes.
- */
- if (ip->ip_len == htons(0) || (ntohs(ip->ip_len) & 0x7) != 0) {
- IPSTAT_INC(ips_toosmall); /* XXX */
- IPSTAT_INC(ips_fragdropped);
- m_freem(m);
- return (NULL);
- }
+ /*
+ * Make sure that fragments have a data length
+ * that's a non-zero multiple of 8 bytes, unless
+ * this is the last fragment.
+ */
+ if (ip->ip_len == htons(0) ||
+ ((ip->ip_off & htons(IP_MF)) && (ntohs(ip->ip_len) & 0x7) != 0)) {
+ IPSTAT_INC(ips_toosmall); /* XXX */
+ IPSTAT_INC(ips_fragdropped);
+ m_freem(m);
+ return (NULL);
+ }
+ if (ip->ip_off & htons(IP_MF))
m->m_flags |= M_IP_FRAG;
- } else
+ else
m->m_flags &= ~M_IP_FRAG;
ip->ip_off = htons(ntohs(ip->ip_off) << 3);
@@ -301,9 +303,28 @@
fp->ipq_src = ip->ip_src;
fp->ipq_dst = ip->ip_dst;
fp->ipq_frags = m;
+ if (m->m_flags & M_IP_FRAG)
+ fp->ipq_maxoff = -1;
+ else
+ fp->ipq_maxoff = ntohs(ip->ip_off) + ntohs(ip->ip_len);
m->m_nextpkt = NULL;
goto done;
} else {
+ /*
+ * If we already saw the last fragment, make sure
+ * this fragment's offset looks sane. Otherwise, if
+ * this is the last fragment, record its endpoint.
+ */
+ if (fp->ipq_maxoff > 0) {
+ i = ntohs(ip->ip_off) + ntohs(ip->ip_len);
+ if (((m->m_flags & M_IP_FRAG) && i >= fp->ipq_maxoff) ||
+ ((m->m_flags & M_IP_FRAG) == 0 &&
+ i != fp->ipq_maxoff)) {
+ fp = NULL;
+ goto dropfrag;
+ }
+ } else if ((m->m_flags & M_IP_FRAG) == 0)
+ fp->ipq_maxoff = ntohs(ip->ip_off) + ntohs(ip->ip_len);
fp->ipq_nfrags++;
atomic_add_int(&nfrags, 1);
#ifdef MAC
Index: head/sys/netinet/ip_var.h
===================================================================
--- head/sys/netinet/ip_var.h
+++ head/sys/netinet/ip_var.h
@@ -61,6 +61,7 @@
u_char ipq_ttl; /* time for reass q to live */
u_char ipq_p; /* protocol of this fragment */
u_short ipq_id; /* sequence id for reassembly */
+ int ipq_maxoff; /* total length of packet */
struct mbuf *ipq_frags; /* to ip headers of fragments */
struct in_addr ipq_src,ipq_dst;
u_char ipq_nfrags; /* # frags in this packet */
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Aug 27, 5:11 PM (16 h, 5 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
37367140
Default Alt Text
D17922.diff (2 KB)
Attached To
Mode
D17922: More IPv4 fragment checks
Attached
Detach File
Event Timeline
Log In to Comment