diff --git a/sys/netinet/ip_icmp.c b/sys/netinet/ip_icmp.c index fd1a3cd24..61f71b6ca 100644 --- a/sys/netinet/ip_icmp.c +++ b/sys/netinet/ip_icmp.c @@ -124,6 +124,20 @@ SYSCTL_UINT(_net_inet_icmp, OID_AUTO, maskfake, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(icmpmaskfake), 0, "Fake reply to ICMP Address Mask Request packets"); +/* + * XXX TEST/DEBUG ONLY -- not for upstream submission. + * + * Truncates outgoing ICMP_TSTAMPREPLY/ICMP_MASKREPLY packets by this many + * bytes before transmit, to reproduce ping(8) pr_pack() short-reply + * handling for local testing. 0 (default) disables and is a no-op. + */ +VNET_DEFINE_STATIC(int, icmp_debug_trunclen) = 0; +#define V_icmp_debug_trunclen VNET(icmp_debug_trunclen) +SYSCTL_INT(_net_inet_icmp, OID_AUTO, debug_trunclen, CTLFLAG_VNET | CTLFLAG_RW, + &VNET_NAME(icmp_debug_trunclen), 0, + "XXX TEST ONLY: truncate outgoing ICMP timestamp/mask replies by " + "this many bytes; 0 disables (default)"); + VNET_DEFINE(int, drop_redirect) = 0; #define V_drop_redirect VNET(drop_redirect) SYSCTL_INT(_net_inet_icmp, OID_AUTO, drop_redirect, CTLFLAG_VNET | CTLFLAG_RW, @@ -655,6 +669,18 @@ icmp_input(struct mbuf **mp, int *offp, int proto) ip->ip_src = satosin(&ia->ia_dstaddr)->sin_addr; } reflect: + /* XXX TEST/DEBUG ONLY -- see V_icmp_debug_trunclen above. */ + if (V_icmp_debug_trunclen > 0 && + (icp->icmp_type == ICMP_TSTAMPREPLY || + icp->icmp_type == ICMP_MASKREPLY)) { + int trunclen = min(V_icmp_debug_trunclen, + icmplen - ICMP_MINLEN); + + if (trunclen > 0) { + m_adj(m, -trunclen); + ip->ip_len = htons(ntohs(ip->ip_len) - trunclen); + } + } ICMPSTAT_INC(icps_reflect); ICMPSTAT_INC2(icps_outhist, icp->icmp_type); icmp_reflect(m); @@ -753,6 +779,10 @@ icmp_input(struct mbuf **mp, int *offp, int proto) } raw: + if (icmplen <= 32) + printf("XXXDBG icmp_input: raw: type=%d icmplen=%d " + "hlen=%d m_len=%d m_pkthdr.len=%d\n", icp->icmp_type, + icmplen, hlen, m->m_len, m->m_pkthdr.len); *mp = m; rip_input(mp, offp, proto); return (IPPROTO_DONE);