Date: Mon, 20 Nov 2000 22:41:41 +0100 From: Jesper Skriver <jesper@skriver.dk> To: "Louis A. Mamakos" <louie@TransSys.COM> Cc: hackers@FreeBSD.ORG Subject: Re: React to ICMP administratively prohibited ? Message-ID: <20001120224141.A80979@skriver.dk> In-Reply-To: <200011192301.eAJN15714300@whizzo.transsys.com>; from louie@TransSys.COM on Sun, Nov 19, 2000 at 06:01:05PM -0500 References: <20001118155446.A81075@skriver.dk> <Pine.BSF.4.21.0011181102540.52996-100000@achilles.silby.com> <20001118183632.A99512@skriver.dk> <20001119215357.A41281@skriver.dk> <200011192103.eAJL34713541@whizzo.transsys.com> <20001119220451.B41281@skriver.dk> <20001119223818.A79237@skriver.dk> <200011192301.eAJN15714300@whizzo.transsys.com>
next in thread | previous in thread | raw e-mail | index | archive | help
--IJpNTDwzlM2Ie8A6 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Sun, Nov 19, 2000 at 06:01:05PM -0500, Louis A. Mamakos wrote: > > It would seem more appropriate, somehow, to push the response to the > ICMP message up into the protocols where they can take the appropriate > action. Of course, the problem is that the PRC_* abstracted codes may > not be rich enough to express all the semantics you'd wish to convey. > > So one goal might be to see if this sort of process could get pushed into > netinet/tcp_sub.c:tcp_ctlinput(). Personally, I don't really like the > idea of the icmp_input() function reaching into TCP's private state and > doing stuff. So what you propose is to let netinet/ip_icmp.c all alone, and do something like the below in netinet/tcp_sub.c:tcp_ctlinput() else if ((icmp_admin_prohib_like_rst == 1) && ((cmd == ICMP_UNREACH_NET_PROHIB) || (cmd == ICMP_UNREACH_HOST_PROHIB) || (cmd == ICMP_UNREACH_FILTER_PROHIB)) && (ip)) notify = tcp_drop_syn_sent; instead of else if ((icmp_admin_prohib_like_rst == 1) && (cmd == PRC_UNREACH_PORT) && (ip)) notify = tcp_drop_syn_sent; correct ? Is this ok - from my vague understanding of this part of the code, I thought I had to use the PRC_* abstracted codes ... > There's too many potential interactions (e.g., what about > IPSEC security associations?) Dunno, know very little of IPsec ... Latest diff attached, this implement a sysctl, 'net.inet.tcp.icmp_admin_prohib_like_rst' which default to being disabled. /Jesper -- Jesper Skriver, jesper(at)skriver(dot)dk - CCIE #5456 Work: Network manager @ AS3292 (Tele Danmark DataNetworks) Private: Geek @ AS2109 (A much smaller network ;-) One Unix to rule them all, One Resolver to find them, One IP to bring them all and in the zone to bind them. --IJpNTDwzlM2Ie8A6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="icmp_admin_prohib_like_rst.diff" diff -ru sys/netinet.old/ip_icmp.c sys/netinet/ip_icmp.c --- sys/netinet.old/ip_icmp.c Thu Nov 2 10:46:23 2000 +++ sys/netinet/ip_icmp.c Mon Nov 20 22:33:43 2000 @@ -328,6 +328,11 @@ case ICMP_UNREACH_NET_UNKNOWN: case ICMP_UNREACH_NET_PROHIB: + if (icp->icmp_ip.ip_p == IPPROTO_TCP) { + code = PRC_UNREACH_PORT; + break; + } + case ICMP_UNREACH_TOSNET: code = PRC_UNREACH_NET; break; @@ -335,11 +340,21 @@ case ICMP_UNREACH_HOST_UNKNOWN: case ICMP_UNREACH_ISOLATED: case ICMP_UNREACH_HOST_PROHIB: + if (icp->icmp_ip.ip_p == IPPROTO_TCP) { + code = PRC_UNREACH_PORT; + break; + } + case ICMP_UNREACH_TOSHOST: code = PRC_UNREACH_HOST; break; case ICMP_UNREACH_FILTER_PROHIB: + if (icp->icmp_ip.ip_p == IPPROTO_TCP) { + code = PRC_UNREACH_PORT; + break; + } + case ICMP_UNREACH_HOST_PRECEDENCE: case ICMP_UNREACH_PRECEDENCE_CUTOFF: code = PRC_UNREACH_PORT; diff -ru sys/netinet.old/tcp_subr.c sys/netinet/tcp_subr.c --- sys/netinet.old/tcp_subr.c Fri Oct 27 13:45:41 2000 +++ sys/netinet/tcp_subr.c Mon Nov 20 22:33:48 2000 @@ -134,6 +134,14 @@ SYSCTL_INT(_net_inet_tcp, OID_AUTO, pcbcount, CTLFLAG_RD, &tcbinfo.ipi_count, 0, "Number of active PCBs"); +/* + * React to ICMP administratively prohibited + */ + +static int icmp_admin_prohib_like_rst = 0; +SYSCTL_INT(_net_inet_tcp, OID_AUTO, icmp_admin_prohib_like_rst, CTLFLAG_RW, + &icmp_admin_prohib_like_rst, 0, "Treat ICMP administratively prohibited messages like TCP RST."); + static void tcp_cleartaocache __P((void)); static void tcp_notify __P((struct inpcb *, int)); @@ -961,6 +969,8 @@ if (cmd == PRC_QUENCH) notify = tcp_quench; + else if ((icmp_admin_prohib_like_rst == 1) && (cmd == PRC_UNREACH_PORT) && (ip)) + notify = tcp_drop_syn_sent; else if (cmd == PRC_MSGSIZE) notify = tcp_mtudisc; else if (!PRC_IS_REDIRECT(cmd) && @@ -1071,6 +1081,20 @@ if (tp) tp->snd_cwnd = tp->t_maxseg; +} + +/* + * When a ICMP unreachable is recieved, drop the + * TCP connection, but only if in SYN SENT + */ +void +tcp_drop_syn_sent(inp, errno) + struct inpcb *inp; + int errno; +{ + struct tcpcb *tp = intotcpcb(inp); + if((tp) && (tp->t_state == TCPS_SYN_SENT)) + tcp_drop(tp, errno); } /* diff -ru sys/netinet.old/tcp_var.h sys/netinet/tcp_var.h --- sys/netinet.old/tcp_var.h Sat Jul 22 01:26:37 2000 +++ sys/netinet/tcp_var.h Sun Nov 19 21:17:55 2000 @@ -387,6 +387,7 @@ void tcp_input __P((struct mbuf *, int, int)); void tcp_mss __P((struct tcpcb *, int)); int tcp_mssopt __P((struct tcpcb *)); +void tcp_drop_syn_sent __P((struct inpcb *, int)); void tcp_mtudisc __P((struct inpcb *, int)); struct tcpcb * tcp_newtcpcb __P((struct inpcb *)); --IJpNTDwzlM2Ie8A6-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20001120224141.A80979>