+
+ TCP_LOG_TH_FLAGS(TCP_LOG_HDR, th, tp, false, ifp);
+
+ if (tp->t_state == TCPS_CLOSED) {
+ TCP_LOG_DROP_PCB(TCP_LOG_HDR, th, tp, false, "tp state TCPS_CLOSED");
+ goto drop;
+ }
+
+#if NECP
+ if (so->so_state & SS_ISCONNECTED) {
+ // Connected TCP sockets have a fully-bound local and remote,
+ // so the policy check doesn't need to override addresses
+ if (!necp_socket_is_allowed_to_send_recv(inp, ifp, NULL, NULL, NULL)) {
+ TCP_LOG_DROP_NECP(TCP_LOG_HDR, th, intotcpcb(inp), false);
+ IF_TCP_STATINC(ifp, badformat);
+ goto drop;
+ }
+ } else {
+ /*
+ * If the proc_uuid_policy table has been updated since the last use
+ * of the listening socket (i.e., the proc_uuid_policy_table_gencount
+ * has been updated), the flags in the socket may be out of date.
+ * If INP2_WANT_APP_POLICY is stale, inbound packets may
+ * be dropped by NECP if the socket should now match a per-app
+ * exception policy.
+ * In order to avoid this refresh the proc_uuid_policy state to
+ * potentially recalculate the socket's flags before checking
+ * with NECP.
+ */
+ (void) inp_update_policy(inp);
+#if INET6
+ if (isipv6) {
+ if (!necp_socket_is_allowed_to_send_recv_v6(inp,
+ th->th_dport, th->th_sport, &ip6->ip6_dst,
+ &ip6->ip6_src, ifp, NULL, NULL, NULL)) {
+ TCP_LOG_DROP_NECP(TCP_LOG_HDR, th, intotcpcb(inp), false);
+ IF_TCP_STATINC(ifp, badformat);
+ goto drop;
+ }
+ } else
+#endif
+ {
+ if (!necp_socket_is_allowed_to_send_recv_v4(inp,
+ th->th_dport, th->th_sport, &ip->ip_dst, &ip->ip_src,
+ ifp, NULL, NULL, NULL)) {
+ TCP_LOG_DROP_NECP(TCP_LOG_HDR, th, intotcpcb(inp), false);
+ IF_TCP_STATINC(ifp, badformat);
+ goto drop;
+ }
+ }
+ }
+#endif /* NECP */
+
+ prev_t_state = tp->t_state;
+
+ /* If none of the FIN|SYN|RST|ACK flag is set, drop */
+ if (tcp_do_rfc5961 && (thflags & TH_ACCEPT) == 0) {
+ TCP_LOG_DROP_PCB(TCP_LOG_HDR, th, tp, false, "rfc5961 TH_ACCEPT == 0");