* pfil hook that is called for each IPv4 packet making its way through the * stack in either direction. * The pfil subsystem holds a non-sleepable mutex somewhere when * calling our hook function, so we can't sleep at all. * It's very important to use the M_NOWAIT flag with all function calls * that support it so that they won't sleep, otherwise you get a panic. */
| 827 | * that support it so that they won't sleep, otherwise you get a panic. |
| 828 | */ |
| 829 | static pfil_return_t |
| 830 | siftr_chkpkt(struct mbuf **m, struct ifnet *ifp, int flags, |
| 831 | void *ruleset __unused, struct inpcb *inp) |
| 832 | { |
| 833 | struct pkt_node *pn; |
| 834 | struct ip *ip; |
| 835 | struct tcphdr *th; |
| 836 | struct tcpcb *tp; |
| 837 | struct siftr_stats *ss; |
| 838 | unsigned int ip_hl; |
| 839 | int inp_locally_locked, dir; |
| 840 | |
| 841 | inp_locally_locked = 0; |
| 842 | dir = PFIL_DIR(flags); |
| 843 | ss = DPCPU_PTR(ss); |
| 844 | |
| 845 | /* |
| 846 | * m_pullup is not required here because ip_{input|output} |
| 847 | * already do the heavy lifting for us. |
| 848 | */ |
| 849 | |
| 850 | ip = mtod(*m, struct ip *); |
| 851 | |
| 852 | /* Only continue processing if the packet is TCP. */ |
| 853 | if (ip->ip_p != IPPROTO_TCP) |
| 854 | goto ret; |
| 855 | |
| 856 | /* |
| 857 | * If a kernel subsystem reinjects packets into the stack, our pfil |
| 858 | * hook will be called multiple times for the same packet. |
| 859 | * Make sure we only process unique packets. |
| 860 | */ |
| 861 | if (siftr_chkreinject(*m, dir, ss)) |
| 862 | goto ret; |
| 863 | |
| 864 | if (dir == PFIL_IN) |
| 865 | ss->n_in++; |
| 866 | else |
| 867 | ss->n_out++; |
| 868 | |
| 869 | /* |
| 870 | * Create a tcphdr struct starting at the correct offset |
| 871 | * in the IP packet. ip->ip_hl gives the ip header length |
| 872 | * in 4-byte words, so multiply it to get the size in bytes. |
| 873 | */ |
| 874 | ip_hl = (ip->ip_hl << 2); |
| 875 | th = (struct tcphdr *)((caddr_t)ip + ip_hl); |
| 876 | |
| 877 | /* |
| 878 | * If the pfil hooks don't provide a pointer to the |
| 879 | * inpcb, we need to find it ourselves and lock it. |
| 880 | */ |
| 881 | if (!inp) { |
| 882 | /* Find the corresponding inpcb for this pkt. */ |
| 883 | inp = siftr_findinpcb(INP_IPV4, ip, *m, th->th_sport, |
| 884 | th->th_dport, dir, ss); |
| 885 | |
| 886 | if (inp == NULL) |
nothing calls this directly
no test coverage detected