Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/netinet Improve robustness of icmp_error():
details: https://anonhg.NetBSD.org/src/rev/809accf267de
branches: trunk
changeset: 495193:809accf267de
user: sommerfeld <sommerfeld%NetBSD.org@localhost>
date: Mon Jul 24 03:32:31 2000 +0000
description:
Improve robustness of icmp_error():
- allow it to work when icmpreturndatabytes is sufficiently large that the
icmp error message doesn't fit in a header mbuf.
- defend against mbuf chains shorter than their contained ip->ip_len.
diffstat:
sys/netinet/ip_icmp.c | 38 ++++++++++++++++++++++++++++++++++----
1 files changed, 34 insertions(+), 4 deletions(-)
diffs (63 lines):
diff -r 228e103b1119 -r 809accf267de sys/netinet/ip_icmp.c
--- a/sys/netinet/ip_icmp.c Mon Jul 24 02:54:22 2000 +0000
+++ b/sys/netinet/ip_icmp.c Mon Jul 24 03:32:31 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ip_icmp.c,v 1.51 2000/07/10 09:31:30 itojun Exp $ */
+/* $NetBSD: ip_icmp.c,v 1.52 2000/07/24 03:32:31 sommerfeld Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -179,7 +179,7 @@
unsigned oiplen = oip->ip_hl << 2;
struct icmp *icp;
struct mbuf *m;
- unsigned icmplen;
+ unsigned icmplen, mblen;
#ifdef ICMPPRINTFS
if (icmpprintfs)
@@ -218,12 +218,42 @@
/*
* Now, formulate icmp message
*/
+ icmplen = oiplen + min(icmpreturndatabytes, oip->ip_len - oiplen);
+ /*
+ * Defend against mbuf chains shorter than oip->ip_len:
+ */
+ mblen = 0;
+ for (m = n; m && (mblen < icmplen); m = m->m_next)
+ mblen += m->m_len;
+ icmplen = min(mblen, icmplen);
+
+ /*
+ * As we are not required to return everything we have,
+ * we return whatever we can return at ease.
+ *
+ * Note that ICMP datagrams longer than 576 octets are out of spec
+ * according to RFC1812; the limit on icmpreturndatabytes below in
+ * icmp_sysctl will keep things below that limit.
+ */
+
+ KASSERT(ICMP_MINLEN <= MCLBYTES);
+
+ if (icmplen + ICMP_MINLEN > MCLBYTES)
+ icmplen = MCLBYTES - ICMP_MINLEN;
+
m = m_gethdr(M_DONTWAIT, MT_HEADER);
+ if (m && (icmplen + ICMP_MINLEN > MHLEN)) {
+ MCLGET(m, M_DONTWAIT);
+ if ((m->m_flags & M_EXT) == 0) {
+ m_freem(m);
+ m = NULL;
+ }
+ }
if (m == NULL)
goto freeit;
- icmplen = oiplen + min(icmpreturndatabytes, oip->ip_len - oiplen);
m->m_len = icmplen + ICMP_MINLEN;
- MH_ALIGN(m, m->m_len);
+ if ((m->m_flags & M_EXT) == 0)
+ MH_ALIGN(m, m->m_len);
icp = mtod(m, struct icmp *);
if ((u_int)type > ICMP_MAXTYPE)
panic("icmp_error");
Home |
Main Index |
Thread Index |
Old Index