diff --git a/sys/netinet/icmp_var.h b/sys/netinet/icmp_var.h index 2eeef541fb21..fd04f2760847 100644 --- a/sys/netinet/icmp_var.h +++ b/sys/netinet/icmp_var.h @@ -77,6 +77,12 @@ struct icmpstat { #ifdef _KERNEL SYSCTL_DECL(_net_inet_icmp); extern int badport_bandlim __P((int)); +#define BANDLIM_UNREACH 0 +#define BANDLIM_RST_NOTOPEN 1 +#define BANDLIM_RST_OPEN 2 +#define BANDLIM_ECHO 3 +#define BANDLIM_TSTAMP 4 +#define BANDLIM_MAX 4 #endif #endif diff --git a/sys/netinet/ip_icmp.c b/sys/netinet/ip_icmp.c index eb68d1d0493b..5a44807ad3b0 100644 --- a/sys/netinet/ip_icmp.c +++ b/sys/netinet/ip_icmp.c @@ -449,7 +449,10 @@ icmp_input(m, off, proto) break; } icp->icmp_type = ICMP_ECHOREPLY; - goto reflect; + if (badport_bandlim(BANDLIM_ECHO) < 0) + goto freeit; + else + goto reflect; case ICMP_TSTAMP: if (!icmpbmcastecho @@ -464,7 +467,10 @@ icmp_input(m, off, proto) icp->icmp_type = ICMP_TSTAMPREPLY; icp->icmp_rtime = iptime(); icp->icmp_ttime = icp->icmp_rtime; /* bogus, do later! */ - goto reflect; + if (badport_bandlim(BANDLIM_TSTAMP) < 0) + goto freeit; + else + goto reflect; case ICMP_MASKREQ: #define satosin(sa) ((struct sockaddr_in *)(sa)) @@ -821,16 +827,23 @@ ip_next_mtu(mtu, dir) int badport_bandlim(int which) { - static int lticks[2]; - static int lpackets[2]; + static int lticks[BANDLIM_MAX + 1]; + static int lpackets[BANDLIM_MAX + 1]; int dticks; + const char *bandlimittype[] = { + "Limiting icmp unreach response", + "Limiting closed port RST response", + "Limiting open port RST response", + "Limiting icmp ping response", + "Limiting icmp tstamp response" + }; /* * Return ok status if feature disabled or argument out of * ranage. */ - if (icmplim <= 0 || which >= 2 || which < 0) + if (icmplim <= 0 || which > BANDLIM_MAX || which < 0) return(0); dticks = ticks - lticks[which]; @@ -840,7 +853,8 @@ badport_bandlim(int which) if ((unsigned int)dticks > hz) { if (lpackets[which] > icmplim && icmplim_output) { - printf("icmp-response bandwidth limit %d/%d pps\n", + printf("%s from %d to %d packets per second\n", + bandlimittype[which], lpackets[which], icmplim ); diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index cb7e05e93696..367fc95a8d96 100644 --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -392,6 +392,7 @@ tcp_input(m, off0, proto) struct ip6_hdr *ip6 = NULL; int isipv6; #endif /* INET6 */ + int rstreason = 0; /* For badport_bandlim accounting purposes */ #ifdef INET6 isipv6 = (mtod(m, struct ip *)->ip_v == 6) ? 1 : 0; @@ -641,11 +642,14 @@ tcp_input(m, off0, proto) goto drop; } } + rstreason = BANDLIM_RST_NOTOPEN; goto maybedropwithreset; } tp = intotcpcb(inp); - if (tp == 0) + if (tp == 0) { + rstreason = BANDLIM_RST_NOTOPEN; goto maybedropwithreset; + } if (tp->t_state == TCPS_CLOSED) goto drop; @@ -2259,7 +2263,9 @@ tcp_input(m, off0, proto) * we think we are under attack or not. */ maybedropwithreset: - if (badport_bandlim(1) < 0) + if (rstreason != BANDLIM_RST_NOTOPEN) + rstreason = BANDLIM_RST_OPEN; + if (badport_bandlim(rstreason) < 0) goto drop; /* fall through */ dropwithreset: diff --git a/sys/netinet/tcp_reass.c b/sys/netinet/tcp_reass.c index cb7e05e93696..367fc95a8d96 100644 --- a/sys/netinet/tcp_reass.c +++ b/sys/netinet/tcp_reass.c @@ -392,6 +392,7 @@ tcp_input(m, off0, proto) struct ip6_hdr *ip6 = NULL; int isipv6; #endif /* INET6 */ + int rstreason = 0; /* For badport_bandlim accounting purposes */ #ifdef INET6 isipv6 = (mtod(m, struct ip *)->ip_v == 6) ? 1 : 0; @@ -641,11 +642,14 @@ tcp_input(m, off0, proto) goto drop; } } + rstreason = BANDLIM_RST_NOTOPEN; goto maybedropwithreset; } tp = intotcpcb(inp); - if (tp == 0) + if (tp == 0) { + rstreason = BANDLIM_RST_NOTOPEN; goto maybedropwithreset; + } if (tp->t_state == TCPS_CLOSED) goto drop; @@ -2259,7 +2263,9 @@ tcp_input(m, off0, proto) * we think we are under attack or not. */ maybedropwithreset: - if (badport_bandlim(1) < 0) + if (rstreason != BANDLIM_RST_NOTOPEN) + rstreason = BANDLIM_RST_OPEN; + if (badport_bandlim(rstreason) < 0) goto drop; /* fall through */ dropwithreset: diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c index 221dd8d4570c..651e16624d6f 100644 --- a/sys/netinet/udp_usrreq.c +++ b/sys/netinet/udp_usrreq.c @@ -353,7 +353,7 @@ udp_input(m, off, proto) udpstat.udps_noportbcast++; goto bad; } - if (badport_bandlim(0) < 0) + if (badport_bandlim(BANDLIM_UNREACH) < 0) goto bad; if (blackhole) goto bad;