Author: cy
Date: Thu Apr  7 01:42:09 2016
New Revision: 297632
URL: https://svnweb.freebsd.org/changeset/base/297632

Log:
  Add DTrace probes for packets flagged as bad by ipfilter. All probes
  for bad packets are named ipf_fi_bad_*.  An example of its use might be:
  
  dtrace -n 'sdt:::ipf_fi_bad_* { stack(); }'
  
  Reviewed by:   Darren Reed <darr...@reed.wattle.id.au>

Modified:
  head/sys/contrib/ipfilter/netinet/fil.c
  head/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c
  head/sys/contrib/ipfilter/netinet/ip_frag.c
  head/sys/contrib/ipfilter/netinet/ip_state.c

Modified: head/sys/contrib/ipfilter/netinet/fil.c
==============================================================================
--- head/sys/contrib/ipfilter/netinet/fil.c     Thu Apr  7 01:18:41 2016        
(r297631)
+++ head/sys/contrib/ipfilter/netinet/fil.c     Thu Apr  7 01:42:09 2016        
(r297632)
@@ -629,6 +629,7 @@ ipf_pr_ipv6hdr(fin)
                ipf_main_softc_t *softc = fin->fin_main_soft;
 
                fin->fin_flx |= FI_BAD;
+               DT2(ipf_fi_bad_ipv6_frag_1, fr_info_t *, fin, int, go);
                LBUMPD(ipf_stats[fin->fin_out], fr_v6_badfrag);
                LBUMP(ipf_stats[fin->fin_out].fr_v6_bad);
        }
@@ -687,6 +688,7 @@ ipf_pr_ipv6exthdr(fin, multiple, proto)
 
        if (shift > fin->fin_dlen) {    /* Nasty extension header length? */
                fin->fin_flx |= FI_BAD;
+               DT3(ipf_fi_bad_pr_ipv6exthdr_len, fr_info_t *, fin, u_short, 
shift, u_short, fin->fin_dlen);
                LBUMPD(ipf_stats[fin->fin_out], fr_v6_ext_hlen);
                return NULL;
        }
@@ -708,9 +710,10 @@ ipf_pr_ipv6exthdr(fin, multiple, proto)
                         * Most IPv6 extension headers are only allowed once.
                         */
                        if ((multiple == 0) &&
-                           ((fin->fin_optmsk & ip6exthdr[i].ol_bit) != 0))
+                           ((fin->fin_optmsk & ip6exthdr[i].ol_bit) != 0)) {
                                fin->fin_flx |= FI_BAD;
-                       else
+                               DT2(ipf_fi_bad_ipv6exthdr_once, fr_info_t *, 
fin, u_int, (fin->fin_optmsk & ip6exthdr[i].ol_bit));
+                       } else
                                fin->fin_optmsk |= ip6exthdr[i].ol_bit;
                        break;
                }
@@ -790,6 +793,7 @@ ipf_pr_routing6(fin)
                        ipf_main_softc_t *softc = fin->fin_main_soft;
 
                        fin->fin_flx |= FI_BAD;
+                       DT1(ipf_fi_bad_routing6, fr_info_t *, fin);
                        LBUMPD(ipf_stats[fin->fin_out], fr_v6_rh_bad);
                        return IPPROTO_NONE;
                }
@@ -852,8 +856,10 @@ ipf_pr_fragment6(fin)
                 * Any fragment that isn't the last fragment must have its
                 * length as a multiple of 8.
                 */
-               if ((fin->fin_plen & 7) != 0)
+               if ((fin->fin_plen & 7) != 0) {
                        fin->fin_flx |= FI_BAD;
+                       DT2(ipf_fi_bad_frag_not_8, fr_info_t *, fin, u_int, 
(fin->fin_plen & 7));
+               }
        }
 
        fin->fin_fraghdr = frag;
@@ -865,8 +871,10 @@ ipf_pr_fragment6(fin)
        /*
         * Jumbograms aren't handled, so the max. length is 64k
         */
-       if ((fin->fin_off << 3) + fin->fin_dlen > 65535)
+       if ((fin->fin_off << 3) + fin->fin_dlen > 65535) {
                  fin->fin_flx |= FI_BAD;
+                 DT2(ipf_fi_bad_jumbogram, fr_info_t *, fin, u_int, 
((fin->fin_off << 3) + fin->fin_dlen));
+       }
 
        /*
         * We don't know where the transport layer header (or whatever is next
@@ -970,8 +978,10 @@ ipf_pr_icmp6(fin)
                        icmp6 = fin->fin_dp;
                        ip6 = (ip6_t *)((char *)icmp6 + ICMPERR_ICMPHLEN);
                        if (IP6_NEQ(&fin->fin_fi.fi_dst,
-                                   (i6addr_t *)&ip6->ip6_src))
+                                   (i6addr_t *)&ip6->ip6_src)) {
                                fin->fin_flx |= FI_BAD;
+                               DT1(ipf_fi_bad_icmp6, fr_info_t *, fin);
+                       }
                        break;
                default :
                        break;
@@ -1283,8 +1293,10 @@ ipf_pr_icmp(fin)
        case ICMP_UNREACH :
 #ifdef icmp_nextmtu
                if (icmp->icmp_code == ICMP_UNREACH_NEEDFRAG) {
-                       if (icmp->icmp_nextmtu < softc->ipf_icmpminfragmtu)
+                       if (icmp->icmp_nextmtu < softc->ipf_icmpminfragmtu) {
                                fin->fin_flx |= FI_BAD;
+                               DT3(ipf_fi_bad_icmp_nextmtu, fr_info_t *, fin, 
u_int, icmp->icmp_nextmtu, u_int, softc->ipf_icmpminfragmtu);
+                       }
                }
 #endif
        case ICMP_SOURCEQUENCH :
@@ -1303,16 +1315,20 @@ ipf_pr_icmp(fin)
                 * fragment.
                 */
                oip = (ip_t *)((char *)fin->fin_dp + ICMPERR_ICMPHLEN);
-               if ((ntohs(oip->ip_off) & IP_OFFMASK) != 0)
+               if ((ntohs(oip->ip_off) & IP_OFFMASK) != 0) {
                        fin->fin_flx |= FI_BAD;
+                       DT2(ipf_fi_bad_icmp_err, fr_info_t, fin, u_int, 
(ntohs(oip->ip_off) & IP_OFFMASK));
+               }
 
                /*
                 * If the destination of this packet doesn't match the
                 * source of the original packet then this packet is
                 * not correct.
                 */
-               if (oip->ip_src.s_addr != fin->fin_daddr)
+               if (oip->ip_src.s_addr != fin->fin_daddr) {
                        fin->fin_flx |= FI_BAD;
+                       DT1(ipf_fi_bad_src_ne_dst, fr_info_t *, fin);
+               }
                break;
        default :
                break;
@@ -1372,6 +1388,7 @@ ipf_pr_tcpcommon(fin)
        if (tlen < sizeof(tcphdr_t)) {
                LBUMPD(ipf_stats[fin->fin_out], fr_tcp_small);
                fin->fin_flx |= FI_BAD;
+               DT3(ipf_fi_bad_tlen, fr_info_t, fin, u_int, tlen, u_int, 
sizeof(tcphdr_t));
                return 1;
        }
 
@@ -1385,6 +1402,7 @@ ipf_pr_tcpcommon(fin)
         */
        if ((flags & TH_URG) != 0 && (tcp->th_urp == 0)) {
                fin->fin_flx |= FI_BAD;
+               DT3(ipf_fi_bad_th_urg, fr_info_t*, fin, u_int, (flags & 
TH_URG), u_int, tcp->th_urp);
 #if 0
        } else if ((flags & TH_URG) == 0 && (tcp->th_urp != 0)) {
                /*
@@ -1392,11 +1410,13 @@ ipf_pr_tcpcommon(fin)
                 * traffic with bogus values in the urgent pointer field.
                 */
                fin->fin_flx |= FI_BAD;
+               DT3(ipf_fi_bad_th_urg0, fr_info_t *, fin, u_int, (flags & 
TH_URG), u_int, tcp->th_urp);
 #endif
        } else if (((flags & (TH_SYN|TH_FIN)) != 0) &&
                   ((flags & (TH_RST|TH_ACK)) == TH_RST)) {
                /* TH_FIN|TH_RST|TH_ACK seems to appear "naturally" */
                fin->fin_flx |= FI_BAD;
+               DT1(ipf_fi_bad_th_fin_rst_ack, fr_info_t, fin);
 #if 1
        } else if (((flags & TH_SYN) != 0) &&
                   ((flags & (TH_URG|TH_PUSH)) != 0)) {
@@ -1405,6 +1425,7 @@ ipf_pr_tcpcommon(fin)
                 * possible(?) with T/TCP...but who uses T/TCP?
                 */
                fin->fin_flx |= FI_BAD;
+               DT1(ipf_fi_bad_th_syn_urg_psh, fr_info_t *, fin);
 #endif
        } else if (!(flags & TH_ACK)) {
                /*
@@ -1423,10 +1444,13 @@ ipf_pr_tcpcommon(fin)
                         * achieved.
                         */
                        /*fin->fin_flx |= FI_BAD*/;
+                       /*DT1(ipf_fi_bad_th_syn_ack, fr_info_t *, fin);*/
                } else if (!(flags & (TH_RST|TH_SYN))) {
                        fin->fin_flx |= FI_BAD;
+                       DT1(ipf_fi_bad_th_rst_syn, fr_info_t *, fin);
                } else if ((flags & (TH_URG|TH_PUSH|TH_FIN)) != 0) {
                        fin->fin_flx |= FI_BAD;
+                       DT1(ipf_fi_bad_th_urg_push_fin, fr_info_t *, fin);
                }
        }
        if (fin->fin_flx & FI_BAD) {
@@ -1757,6 +1781,7 @@ ipf_pr_ipv4hdr(fin)
                                 * must be an even multiple of 8.
                                 */
                                fi->fi_flx |= FI_BAD;
+                               DT1(ipf_fi_bad_fragbody_gt_65535, fr_info_t *, 
fin);
                        }
                }
        }
@@ -1840,6 +1865,7 @@ ipf_pr_ipv4hdr(fin)
                                case IPOPT_SECURITY :
                                        if (optmsk & op->ol_bit) {
                                                fin->fin_flx |= FI_BAD;
+                                               DT2(ipf_fi_bad_ipopt_security, 
fr_info_t *, fin, u_short, (optmsk & op->ol_bit));
                                        } else {
                                                doi = ipf_checkripso(s);
                                                secmsk = doi >> 16;
@@ -1851,6 +1877,7 @@ ipf_pr_ipv4hdr(fin)
 
                                        if (optmsk & op->ol_bit) {
                                                fin->fin_flx |= FI_BAD;
+                                               DT2(ipf_fi_bad_ipopt_cipso, 
fr_info_t *, fin, u_short, (optmsk & op->ol_bit));
                                        } else {
                                                doi = ipf_checkcipso(fin,
                                                                     s, ol);
@@ -1949,6 +1976,7 @@ ipf_checkcipso(fin, s, ol)
        if (ol < 6 || ol > 40) {
                LBUMPD(ipf_stats[fin->fin_out], fr_v4_cipso_bad);
                fin->fin_flx |= FI_BAD;
+               DT2(ipf_fi_bad_checkcipso_ol, fr_info_t *, fin, u_int, ol);
                return 0;
        }
 
@@ -1966,6 +1994,7 @@ ipf_checkcipso(fin, s, ol)
                if (tlen > len || tlen < 4 || tlen > 34) {
                        LBUMPD(ipf_stats[fin->fin_out], fr_v4_cipso_tlen);
                        fin->fin_flx |= FI_BAD;
+                       DT2(ipf_fi_bad_checkcipso_tlen, fr_info_t *, fin, 
u_int, tlen);
                        return 0;
                }
 
@@ -1976,10 +2005,12 @@ ipf_checkcipso(fin, s, ol)
                 */
                if (tag == 0) {
                        fin->fin_flx |= FI_BAD;
+                       DT2(ipf_fi_bad_checkcipso_tag, fr_info_t *, fin, u_int, 
tag);
                        continue;
                } else if (tag == 1) {
                        if (*(t + 2) != 0) {
                                fin->fin_flx |= FI_BAD;
+                               DT2(ipf_fi_bad_checkcipso_tag1_t2, fr_info_t *, 
fin, u_int, (*t + 2));
                                continue;
                        }
                        sensitivity = *(t + 3);
@@ -1988,6 +2019,7 @@ ipf_checkcipso(fin, s, ol)
                } else if (tag == 4) {
                        if (*(t + 2) != 0) {
                                fin->fin_flx |= FI_BAD;
+                               DT2(ipf_fi_bad_checkcipso_tag4_t2, fr_info_t *, 
fin, u_int, (*t + 2));
                                continue;
                        }
                        sensitivity = *(t + 3);
@@ -1996,6 +2028,7 @@ ipf_checkcipso(fin, s, ol)
                } else if (tag == 5) {
                        if (*(t + 2) != 0) {
                                fin->fin_flx |= FI_BAD;
+                               DT2(ipf_fi_bad_checkcipso_tag5_t2, fr_info_t *, 
fin, u_int, (*t + 2));
                                continue;
                        }
                        sensitivity = *(t + 3);
@@ -2006,6 +2039,7 @@ ipf_checkcipso(fin, s, ol)
                        ;
                } else {
                        fin->fin_flx |= FI_BAD;
+                       DT2(ipf_fi_bad_checkcipso_tag127, fr_info_t *, fin, 
u_int, tag);
                        continue;
                }
 

Modified: head/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c
==============================================================================
--- head/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c  Thu Apr  7 01:18:41 
2016        (r297631)
+++ head/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c  Thu Apr  7 01:42:09 
2016        (r297632)
@@ -1091,6 +1091,7 @@ ipf_checkv4sum(fin)
            CSUM_IP_CHECKED) {
                fin->fin_cksum = FI_CK_BAD;
                fin->fin_flx |= FI_BAD;
+               DT2(ipf_fi_bad_checkv4sum_csum_ip_checked, fr_info_t *, fin, 
u_int, m->m_pkthdr.csum_flags & (CSUM_IP_CHECKED|CSUM_IP_VALID));
                return -1;
        }
        if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID) {
@@ -1120,6 +1121,7 @@ ipf_checkv4sum(fin)
                if (sum != 0) {
                        fin->fin_cksum = FI_CK_BAD;
                        fin->fin_flx |= FI_BAD;
+                       DT2(ipf_fi_bad_checkv4sum_sum, fr_info_t *, fin, u_int, 
sum);
                } else {
                        fin->fin_cksum = FI_CK_SUMOK;
                        return 0;
@@ -1143,12 +1145,14 @@ skipauto:
        if (manual != 0) {
                if (ipf_checkl4sum(fin) == -1) {
                        fin->fin_flx |= FI_BAD;
+                       DT2(ipf_fi_bad_checkv4sum_manual, fr_info_t *, fin, 
u_int, manual);
                        return -1;
                }
        }
 #else
        if (ipf_checkl4sum(fin) == -1) {
                fin->fin_flx |= FI_BAD;
+               DT2(ipf_fi_bad_checkv4sum_checkl4sum, fr_info_t *, fin, u_int, 
-1);
                return -1;
        }
 #endif
@@ -1162,16 +1166,20 @@ ipf_checkv6sum(fin)
        fr_info_t *fin;
 {
        if ((fin->fin_flx & FI_NOCKSUM) != 0)
+               DT(ipf_checkv6sum_fi_nocksum);
                return 0;
 
        if ((fin->fin_flx & FI_SHORT) != 0)
+               DT(ipf_checkv6sum_fi_short);
                return 1;
 
        if (fin->fin_cksum != FI_CK_NEEDED)
+               DT(ipf_checkv6sum_fi_ck_needed);
                return (fin->fin_cksum > FI_CK_NEEDED) ? 0 : -1;
 
        if (ipf_checkl4sum(fin) == -1) {
                fin->fin_flx |= FI_BAD;
+               DT2(ipf_fi_bad_checkv6sum_checkl4sum, fr_info_t *, fin, u_int, 
-1);
                return -1;
        }
        return 0;

Modified: head/sys/contrib/ipfilter/netinet/ip_frag.c
==============================================================================
--- head/sys/contrib/ipfilter/netinet/ip_frag.c Thu Apr  7 01:18:41 2016        
(r297631)
+++ head/sys/contrib/ipfilter/netinet/ip_frag.c Thu Apr  7 01:42:09 2016        
(r297632)
@@ -719,6 +719,8 @@ ipf_frag_lookup(softc, softf, fin, table
                                        FBUMP(ifs_overlap);
                                        DT2(ifs_overlap, u_short, off,
                                            ipfr_t *, f);
+                                       DT3(ipf_fi_bad_ifs_overlap, fr_info_t 
*, fin, u_short, off,
+                                           ipfr_t *, f);
                                        fin->fin_flx |= FI_BAD;
                                        break;
                                }
@@ -901,6 +903,7 @@ ipf_frag_known(fin, passp)
                if (fin->fin_flx & FI_BAD) {
                        fr = &ipfr_block;
                        fin->fin_reason = FRB_BADFRAG;
+                       DT2(ipf_frb_badfrag, fr_info_t *, fin, uint, fra);
                } else {
                        fr = fra->ipfr_rule;
                }

Modified: head/sys/contrib/ipfilter/netinet/ip_state.c
==============================================================================
--- head/sys/contrib/ipfilter/netinet/ip_state.c        Thu Apr  7 01:18:41 
2016        (r297631)
+++ head/sys/contrib/ipfilter/netinet/ip_state.c        Thu Apr  7 01:42:09 
2016        (r297632)
@@ -1611,8 +1611,10 @@ ipf_state_add(softc, fin, stsave, flags)
                            TH_SYN &&
                            (TCP_OFF(tcp) > (sizeof(tcphdr_t) >> 2))) {
                                if (ipf_tcpoptions(softs, fin, tcp,
-                                             &is->is_tcp.ts_data[0]) == -1)
+                                             &is->is_tcp.ts_data[0]) == -1) {
                                        fin->fin_flx |= FI_BAD;
+                                       
DT1(ipf_fi_bad_tcpoptions_th_fin_ack_ecnall, fr_info_t *, fin);
+                               }
                        }
 
                        if ((fin->fin_out != 0) && (pass & FR_NEWISN) != 0) {
@@ -2068,8 +2070,10 @@ ipf_state_tcp(softc, softs, fin, tcp, is
                        is->is_s0[!source] = ntohl(tcp->th_seq) + 1;
                        if ((TCP_OFF(tcp) > (sizeof(tcphdr_t) >> 2))) {
                                if (ipf_tcpoptions(softs, fin, tcp,
-                                                  fdata) == -1)
+                                                  fdata) == -1) {
                                        fin->fin_flx |= FI_BAD;
+                                       DT1(ipf_fi_bad_winscale_syn_ack, 
fr_info_t *, fin);
+                               }
                        }
                        if ((fin->fin_out != 0) && (is->is_pass & FR_NEWISN))
                                ipf_checknewisn(fin, is);
@@ -2077,8 +2081,10 @@ ipf_state_tcp(softc, softs, fin, tcp, is
                        is->is_s0[source] = ntohl(tcp->th_seq) + 1;
                        if ((TCP_OFF(tcp) > (sizeof(tcphdr_t) >> 2))) {
                                if (ipf_tcpoptions(softs, fin, tcp,
-                                                  fdata) == -1)
+                                                  fdata) == -1) {
                                        fin->fin_flx |= FI_BAD;
+                                       DT1(ipf_fi_bad_winscale_syn, fr_info_t 
*, fin);
+                               }
                        }
 
                        if ((fin->fin_out != 0) && (is->is_pass & FR_NEWISN))
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to