From bae005d1db73b3bc6a4b6fa49a7e8d079998a47c Mon Sep 17 00:00:00 2001 From: darrenr Date: Sat, 10 Jun 2000 12:39:19 +0000 Subject: [PATCH] add icmpreturndatabytes kernel variable (default 8) which specifies the number of extra data bytes to return in ICMP error messages. This is also available via sysctl as net.icmp.returndatabytes and is limited to [8,512]. --- sys/netinet/icmp_var.h | 6 ++-- sys/netinet/ip_icmp.c | 66 ++++++++++++++++++++++++++---------------- 2 files changed, 45 insertions(+), 27 deletions(-) diff --git a/sys/netinet/icmp_var.h b/sys/netinet/icmp_var.h index 7791d249332a..7f3d0d6e9df5 100644 --- a/sys/netinet/icmp_var.h +++ b/sys/netinet/icmp_var.h @@ -1,4 +1,4 @@ -/* $NetBSD: icmp_var.h,v 1.14 2000/02/15 04:03:49 thorpej Exp $ */ +/* $NetBSD: icmp_var.h,v 1.15 2000/06/10 12:39:20 darrenr Exp $ */ /* * Copyright (c) 1982, 1986, 1993 @@ -62,12 +62,14 @@ struct icmpstat { */ #define ICMPCTL_MASKREPL 1 /* allow replies to netmask requests */ #define ICMPCTL_ERRRATELIMIT 2 /* error rate limit */ -#define ICMPCTL_MAXID 3 +#define ICMPCTL_RETURNDATABYTES 3 /* # of bytes to include in errors */ +#define ICMPCTL_MAXID 4 #define ICMPCTL_NAMES { \ { 0, 0 }, \ { "maskrepl", CTLTYPE_INT }, \ { "errratelimit", CTLTYPE_INT }, \ + { "returndatabytes", CTLTYPE_INT }, \ } #ifdef _KERNEL diff --git a/sys/netinet/ip_icmp.c b/sys/netinet/ip_icmp.c index 911c3a5160ab..f94758b1049e 100644 --- a/sys/netinet/ip_icmp.c +++ b/sys/netinet/ip_icmp.c @@ -1,4 +1,4 @@ -/* $NetBSD: ip_icmp.c,v 1.46 2000/05/22 12:08:43 itojun Exp $ */ +/* $NetBSD: ip_icmp.c,v 1.47 2000/06/10 12:39:19 darrenr Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -146,6 +146,7 @@ int icmpmaskrepl = 0; #ifdef ICMPPRINTFS int icmpprintfs = 0; #endif +int icmpreturndatabytes = 8; #if 0 static int ip_next_mtu __P((int, int)); @@ -217,7 +218,7 @@ icmp_error(n, type, code, dest, destifp) m = m_gethdr(M_DONTWAIT, MT_HEADER); if (m == NULL) goto freeit; - icmplen = oiplen + min(8, oip->ip_len - oiplen); + icmplen = oiplen + min(icmpreturndatabytes, oip->ip_len - oiplen); m->m_len = icmplen + ICMP_MINLEN; MH_ALIGN(m, m->m_len); icp = mtod(m, struct icmp *); @@ -244,7 +245,7 @@ icmp_error(n, type, code, dest, destifp) HTONS(oip->ip_off); HTONS(oip->ip_len); icp->icmp_code = code; - bcopy((caddr_t)oip, (caddr_t)&icp->icmp_ip, icmplen); + m_copydata(n, 0, icmplen, (caddr_t)&icp->icmp_ip); nip = &icp->icmp_ip; /* @@ -258,11 +259,16 @@ icmp_error(n, type, code, dest, destifp) m->m_pkthdr.len = m->m_len; m->m_pkthdr.rcvif = n->m_pkthdr.rcvif; nip = mtod(m, struct ip *); - bcopy((caddr_t)oip, (caddr_t)nip, sizeof(struct ip)); - nip->ip_len = m->m_len; + /* ip_v set in ip_output */ nip->ip_hl = sizeof(struct ip) >> 2; - nip->ip_p = IPPROTO_ICMP; nip->ip_tos = 0; + nip->ip_len = m->m_len; + /* ip_id set in ip_output */ + nip->ip_off = 0; + /* ip_ttl set in icmp_reflect */ + nip->ip_p = IPPROTO_ICMP; + nip->ip_src = oip->ip_src; + nip->ip_dst = oip->ip_dst; icmp_reflect(m); freeit: @@ -795,40 +801,50 @@ icmp_sysctl(name, namelen, oldp, oldlenp, newp, newlen) void *newp; size_t newlen; { + int arg, error, s; /* All sysctl names at this level are terminal. */ if (namelen != 1) return (ENOTDIR); - switch (name[0]) { + switch (name[0]) + { case ICMPCTL_MASKREPL: - return (sysctl_int(oldp, oldlenp, newp, newlen, &icmpmaskrepl)); + error = sysctl_int(oldp, oldlenp, newp, newlen, &icmpmaskrepl); + break; case ICMPCTL_ERRRATELIMIT: - { - int rate_usec, error, s; - /* * The sysctl specifies the rate in usec-between-icmp, * so we must convert from/to a timeval. */ - rate_usec = (icmperrratelim.tv_sec * 1000000) + + arg = (icmperrratelim.tv_sec * 1000000) + icmperrratelim.tv_usec; - error = sysctl_int(oldp, oldlenp, newp, newlen, &rate_usec); + error = sysctl_int(oldp, oldlenp, newp, newlen, &arg); if (error) - return (error); - if (rate_usec < 0) - return (EINVAL); - s = splsoftnet(); - icmperrratelim.tv_sec = rate_usec / 1000000; - icmperrratelim.tv_usec = rate_usec % 1000000; - splx(s); - - return (0); - } + break; + if (arg >= 0) { + s = splsoftnet(); + icmperrratelim.tv_sec = arg / 1000000; + icmperrratelim.tv_usec = arg % 1000000; + splx(s); + } else + error = EINVAL; + break; + case ICMPCTL_RETURNDATABYTES: + arg = icmpreturndatabytes; + error = sysctl_int(oldp, oldlenp, newp, newlen, &arg); + if (error) + break; + if ((arg >= 8) || (arg <= 512)) + icmpreturndatabytes = arg; + else + error = EINVAL; + break; default: - return (ENOPROTOOPT); + error = ENOPROTOOPT; + break; } - /* NOTREACHED */ + return error; } static void