Index: icmp_var.h =================================================================== RCS file: /home/ncvs/src/sys/netinet/icmp_var.h,v retrieving revision 1.25 diff -u -p -r1.25 icmp_var.h --- icmp_var.h 7 Jan 2005 01:45:44 -0000 1.25 +++ icmp_var.h 24 Feb 2007 23:58:08 -0000 @@ -82,7 +82,11 @@ extern int badport_bandlim(int); #define BANDLIM_ICMP_TSTAMP 2 #define BANDLIM_RST_CLOSEDPORT 3 /* No connection, and no listeners */ #define BANDLIM_RST_OPENPORT 4 /* No connection, listener */ -#define BANDLIM_MAX 4 +#define BANDLIM_ICMP_FWD_UNREACH 5 /* forwarding: limit unreachable */ +#define BANDLIM_ICMP_FWD_TIMXCEED 6 /* forwarding: limit time-exceeded */ +#define BANDLIM_ICMP_FWD_NEEDFRAG 7 /* forwarding: limit need-frag */ +#define BANDLIM_ICMP_FWD_FILTER 8 /* forwarding: limit admin-prohib */ +#define BANDLIM_MAX 8 #endif #endif Index: ip_fastfwd.c =================================================================== RCS file: /home/ncvs/src/sys/netinet/ip_fastfwd.c,v retrieving revision 1.39 diff -u -p -r1.39 ip_fastfwd.c --- ip_fastfwd.c 5 Feb 2007 00:15:40 -0000 1.39 +++ ip_fastfwd.c 24 Feb 2007 23:58:08 -0000 @@ -100,6 +100,7 @@ #include #include #include +#include #include #include @@ -138,7 +139,11 @@ ip_findroute(struct route *ro, struct in ipstat.ips_cantforward++; if (rt) RTFREE(rt); - icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, 0, 0); + if (badport_bandlim(BANDLIM_ICMP_FWD_UNREACH) < 0) { + m_freem(m); + } else { + icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, 0, 0); + } return NULL; } return dst; @@ -295,8 +300,12 @@ ip_fastforward(struct mbuf *m) if (ip_doopts == 1) return m; else if (ip_doopts == 2) { - icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_FILTER_PROHIB, - 0, 0); + if (badport_bandlim(BANDLIM_ICMP_FWD_FILTER) < 0) { + m_freem(m); + } else { + icmp_error(m, ICMP_UNREACH, + ICMP_UNREACH_FILTER_PROHIB, 0, 0); + } return NULL; /* mbuf already free'd */ } /* else ignore IP options and continue */ @@ -394,7 +403,12 @@ passin: if (!ipstealth) { #endif if (ip->ip_ttl <= IPTTLDEC) { - icmp_error(m, ICMP_TIMXCEED, ICMP_TIMXCEED_INTRANS, 0, 0); + if (badport_bandlim(BANDLIM_ICMP_FWD_TIMXCEED) < 0) { + m_freem(m); + } else { + icmp_error(m, ICMP_TIMXCEED, ICMP_TIMXCEED_INTRANS, + 0, 0); + } return NULL; /* mbuf already free'd */ } @@ -501,8 +515,12 @@ passout: */ if ((ro.ro_rt->rt_flags & RTF_REJECT) && ro.ro_rt->rt_rmx.rmx_expire >= time_uptime) { - icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, 0, 0); - goto consumed; + if (badport_bandlim(BANDLIM_ICMP_FWD_UNREACH) < 0) { + goto drop; + } else { + icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, 0, 0); + goto consumed; + } } #ifndef ALTQ @@ -521,8 +539,12 @@ passout: * Check if media link state of interface is not down */ if (ifp->if_link_state == LINK_STATE_DOWN) { - icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, 0, 0); - goto consumed; + if (badport_bandlim(BANDLIM_ICMP_FWD_UNREACH) < 0) { + goto drop; + } else { + icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, 0, 0); + goto consumed; + } } /* @@ -551,8 +573,10 @@ passout: */ if (ip->ip_off & IP_DF) { ipstat.ips_cantfrag++; - icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG, - 0, mtu); + if (badport_bandlim(BANDLIM_ICMP_FWD_NEEDFRAG) < 0) + goto drop; + icmp_error(m, ICMP_UNREACH, + ICMP_UNREACH_NEEDFRAG, 0, mtu); goto consumed; } else { /* Index: ip_icmp.c =================================================================== RCS file: /home/ncvs/src/sys/netinet/ip_icmp.c,v retrieving revision 1.113 diff -u -p -r1.113 ip_icmp.c --- ip_icmp.c 22 Oct 2006 11:52:16 -0000 1.113 +++ ip_icmp.c 24 Feb 2007 23:58:09 -0000 @@ -905,7 +905,12 @@ badport_bandlim(int which) { "icmp ping response" }, { "icmp tstamp response" }, { "closed port RST response" }, - { "open port RST response" } + { "open port RST response" }, + /* Messages generated by forwarding path */ + { "icmp forward unreach response" }, + { "icmp forward ttl exceeded response" }, + { "icmp forward need fragment response" }, + { "icmp forward admin prohibited response" } }; /* Index: ip_input.c =================================================================== RCS file: /home/ncvs/src/sys/netinet/ip_input.c,v retrieving revision 1.324 diff -u -p -r1.324 ip_input.c --- ip_input.c 3 Feb 2007 06:45:51 -0000 1.324 +++ ip_input.c 24 Feb 2007 23:58:10 -0000 @@ -65,6 +65,7 @@ #include #include #include +#include #include #include #ifdef DEV_CARP @@ -1260,8 +1261,10 @@ ip_forward(struct mbuf *m, int srcrt) if (!ipstealth) { #endif if (ip->ip_ttl <= IPTTLDEC) { - icmp_error(m, ICMP_TIMXCEED, ICMP_TIMXCEED_INTRANS, - 0, 0); + if (badport_bandlim(BANDLIM_ICMP_FWD_TIMXCEED) >= 0) { + icmp_error(m, ICMP_TIMXCEED, + ICMP_TIMXCEED_INTRANS, 0, 0); + } return; } #ifdef IPSTEALTH @@ -1269,7 +1272,8 @@ ip_forward(struct mbuf *m, int srcrt) #endif if (!srcrt && (ia = ip_rtaddr(ip->ip_dst)) == NULL) { - icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, 0, 0); + if (badport_bandlim(BANDLIM_ICMP_FWD_UNREACH) >= 0) + icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, 0, 0); return; } @@ -1386,6 +1390,10 @@ ip_forward(struct mbuf *m, int srcrt) default: type = ICMP_UNREACH; code = ICMP_UNREACH_HOST; + if (badport_bandlim(BANDLIM_ICMP_FWD_UNREACH) < 0) { + m_freem(mcopy); + return; + } break; case EMSGSIZE: @@ -1407,6 +1415,10 @@ ip_forward(struct mbuf *m, int srcrt) mtu = ip_next_mtu(ip->ip_len, 0); } ipstat.ips_cantfrag++; + if (badport_bandlim(BANDLIM_ICMP_FWD_NEEDFRAG) < 0) { + m_freem(mcopy); + return; + } break; case ENOBUFS: @@ -1431,6 +1443,7 @@ ip_forward(struct mbuf *m, int srcrt) m_freem(mcopy); return; } + icmp_error(mcopy, type, code, dest.s_addr, mtu); }