Subject: IP packet length patch for 1.2
To: None <netbsd-users@NetBSD.ORG>
From: Jason Thorpe <thorpej@OG.ORG>
List: netbsd-users
Date: 04/23/1997 21:27:52
Attached below is the IP packet length changes I recently committed to
NetBSD-current, merged into NetBSD 1.2. They should work fine... They
merged into 1.2 trivially.
I want to make sure these get in the first official patch, so please
let me know if there are any problems with them.
--------------------------------------------------------------------------
Jason R. Thorpe thorpej@OG.ORG
Just me and my collection of obsolete computer gear(s).
----- snip -----
Index: ip.h
===================================================================
RCS file: /cvsroot/src/sys/netinet/ip.h,v
retrieving revision 1.9
diff -c -r1.9 ip.h
*** ip.h 1995/05/15 01:22:44 1.9
--- ip.h 1996/10/26 18:37:07
***************
*** 43,52 ****
/*
* Structure of an internet header, naked of options.
- *
- * We declare ip_len and ip_off to be short, rather than u_short
- * pragmatically since otherwise unsigned comparisons can result
- * against negative integers quite easily, and fail in subtle ways.
*/
struct ip {
#if BYTE_ORDER == LITTLE_ENDIAN
--- 43,48 ----
***************
*** 58,66 ****
ip_hl:4; /* header length */
#endif
u_int8_t ip_tos; /* type of service */
! int16_t ip_len; /* total length */
u_int16_t ip_id; /* identification */
! int16_t ip_off; /* fragment offset field */
#define IP_DF 0x4000 /* dont fragment flag */
#define IP_MF 0x2000 /* more fragments flag */
#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */
--- 54,62 ----
ip_hl:4; /* header length */
#endif
u_int8_t ip_tos; /* type of service */
! u_int16_t ip_len; /* total length */
u_int16_t ip_id; /* identification */
! u_int16_t ip_off; /* fragment offset field */
#define IP_DF 0x4000 /* dont fragment flag */
#define IP_MF 0x2000 /* more fragments flag */
#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */
Index: ip_input.c
===================================================================
RCS file: /cvsroot/src/sys/netinet/ip_input.c,v
retrieving revision 1.30
diff -c -r1.30 ip_input.c
*** ip_input.c 1996/03/16 23:53:58 1.30
--- ip_input.c 1996/10/26 18:37:21
***************
*** 531,540 ****
return (0);
/*
! * Reassembly is complete; concatenate fragments.
*/
q = fp->ipq_fragq.lh_first;
ip = q->ipqe_ip;
m = dtom(q->ipqe_ip);
t = m->m_next;
m->m_next = 0;
--- 531,546 ----
return (0);
/*
! * Reassembly is complete. Check for a bogus message size and
! * concatenate fragments.
*/
q = fp->ipq_fragq.lh_first;
ip = q->ipqe_ip;
+ if ((next + (ip->ip_hl << 2)) > IP_MAXPACKET) {
+ ipstat.ips_toolong++;
+ ip_freef(fp);
+ return (0);
+ }
m = dtom(q->ipqe_ip);
t = m->m_next;
m->m_next = 0;
Index: ip_var.h
===================================================================
RCS file: /cvsroot/src/sys/netinet/ip_var.h,v
retrieving revision 1.16
diff -c -r1.16 ip_var.h
*** ip_var.h 1996/02/13 23:43:20 1.16
--- ip_var.h 1996/10/26 18:37:26
***************
*** 41,51 ****
* Overlay for ip header used by other protocols (tcp, udp).
*/
struct ipovly {
! u_int8_t ih_x1[9]; /* (unused) */
! u_int8_t ih_pr; /* protocol */
! int16_t ih_len; /* protocol length */
! struct in_addr ih_src; /* source internet address */
! struct in_addr ih_dst; /* destination internet address */
};
/*
--- 41,51 ----
* Overlay for ip header used by other protocols (tcp, udp).
*/
struct ipovly {
! u_int8_t ih_x1[9]; /* (unused) */
! u_int8_t ih_pr; /* protocol */
! u_int16_t ih_len; /* protocol length */
! struct in_addr ih_src; /* source internet address */
! struct in_addr ih_dst; /* destination internet address */
};
/*
***************
*** 143,148 ****
--- 143,149 ----
u_long ips_rawout; /* total raw ip packets generated */
u_long ips_badfrags; /* malformed fragments (bad length) */
u_long ips_rcvmemdrop; /* frags dropped for lack of memory */
+ u_long ips_toolong; /* ip length > max ip packet size */
};
#ifdef _KERNEL
Index: raw_ip.c
===================================================================
RCS file: /cvsroot/src/sys/netinet/raw_ip.c,v
retrieving revision 1.25
diff -c -r1.25 raw_ip.c
*** raw_ip.c 1996/02/18 18:58:33 1.25
--- raw_ip.c 1996/10/26 18:37:28
***************
*** 171,176 ****
--- 171,180 ----
* Otherwise, allocate an mbuf for a header and fill it in.
*/
if ((inp->inp_flags & INP_HDRINCL) == 0) {
+ if ((m->m_pkthdr.len + sizeof(struct ip)) > IP_MAXPACKET) {
+ m_freem(m);
+ return (EMSGSIZE);
+ }
M_PREPEND(m, sizeof(struct ip), M_WAIT);
ip = mtod(m, struct ip *);
ip->ip_tos = 0;
***************
*** 182,187 ****
--- 186,195 ----
ip->ip_ttl = MAXTTL;
opts = inp->inp_options;
} else {
+ if (m->m_pkthdr.len > IP_MAXPACKET) {
+ m_freem(m);
+ return (EMSGSIZE);
+ }
ip = mtod(m, struct ip *);
if (ip->ip_id == 0)
ip->ip_id = htons(ip_id++);
Index: udp.h
===================================================================
RCS file: /cvsroot/src/sys/netinet/udp.h,v
retrieving revision 1.6
diff -c -r1.6 udp.h
*** udp.h 1995/04/13 06:37:10 1.6
--- udp.h 1996/10/26 18:37:29
***************
*** 1,4 ****
! /* $NetBSD: udp.h,v 1.6 1995/04/13 06:37:10 cgd Exp $ */
/*
* Copyright (c) 1982, 1986, 1993
--- 1,4 ----
! /* $NetBSD: udp.h,v 1.7 1996/10/25 06:22:25 thorpej Exp $ */
/*
* Copyright (c) 1982, 1986, 1993
***************
*** 42,47 ****
struct udphdr {
u_int16_t uh_sport; /* source port */
u_int16_t uh_dport; /* destination port */
! int16_t uh_ulen; /* udp length */
u_int16_t uh_sum; /* udp checksum */
};
--- 42,47 ----
struct udphdr {
u_int16_t uh_sport; /* source port */
u_int16_t uh_dport; /* destination port */
! u_int16_t uh_ulen; /* udp length */
u_int16_t uh_sum; /* udp checksum */
};
Index: udp_usrreq.c
===================================================================
RCS file: /cvsroot/src/sys/netinet/udp_usrreq.c,v
retrieving revision 1.29
diff -c -r1.29 udp_usrreq.c
*** udp_usrreq.c 1996/05/20 16:56:20 1.29
--- udp_usrreq.c 1996/10/26 18:37:35
***************
*** 462,467 ****
--- 462,476 ----
}
/*
+ * Compute the packet length of the IP header, and
+ * punt if the length looks bogus.
+ */
+ if ((len + sizeof(struct udpiphdr)) > IP_MAXPACKET) {
+ error = EMSGSIZE;
+ goto release;
+ }
+
+ /*
* Fill in mbuf with extended UDP header
* and addresses and length put into network format.
*/