Index: sys/netinet/ip_icmp.c =================================================================== --- sys/netinet/ip_icmp.c +++ sys/netinet/ip_icmp.c @@ -89,6 +89,12 @@ &VNET_NAME(icmplim), 0, "Maximum number of ICMP responses per second"); +VNET_DEFINE_STATIC(int, icmplim_jitter) = 16; +#define V_icmplim_jitter VNET(icmplim_jitter) +SYSCTL_INT(_net_inet_icmp, ICMPCTL_ICMPLIM, icmplim_jitter, CTLFLAG_VNET | CTLFLAG_RW, + &VNET_NAME(icmplim_jitter), 0, + "Jitter value for randomizing the bandwidth limit"); + VNET_DEFINE_STATIC(int, icmplim_output) = 1; #define V_icmplim_output VNET(icmplim_output) SYSCTL_INT(_net_inet_icmp, OID_AUTO, icmplim_output, CTLFLAG_VNET | CTLFLAG_RW, @@ -1094,6 +1100,11 @@ }; #define V_icmp_rates VNET(icmp_rates) +/* + * Adjust limit +/- to jitter the measurement for security Paper + * forthcoming. + */ + static void icmp_bandlimit_init(void) { @@ -1120,18 +1131,32 @@ badport_bandlim(int which) { int64_t pps; - + uint32_t jitter, limit; + if (V_icmplim == 0 || which == BANDLIM_UNLIMITED) return (0); KASSERT(which >= 0 && which < BANDLIM_MAX, ("%s: which %d", __func__, which)); - pps = counter_ratecheck(&V_icmp_rates[which].cr, V_icmplim); + /* + * Add random jitter to the administratively set limit. + * If the returned random number is even then add the jitter + * and if odd then subtract. + */ + jitter = arc4random_uniform(V_icmplim_jitter); + + if (jitter % 2 == 0) + limit = V_icmplim + jitter; + else + limit = V_icmplim - jitter; + + pps = counter_ratecheck(&V_icmp_rates[which].cr, limit); + if (pps == -1) return (-1); if (pps > 0 && V_icmplim_output) log(LOG_NOTICE, "Limiting %s from %jd to %d packets/sec\n", - V_icmp_rates[which].descr, (intmax_t )pps, V_icmplim); + V_icmp_rates[which].descr, (intmax_t )pps, limit); return (0); }