saddr, 0, daddr, 0, &pd->naddr, NULL)) != NULL) {
saddr, icmpid, daddr, icmpid, &pd->naddr, NULL)) != NULL) {
pf_test_icmp(struct pf_rule **rm, struct pf_state **sm, int direction,    struct pfi_kif *kif, struct mbuf *m, int off, void *h,    struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm,    struct ifqueue *ifq){	struct pf_rule		*nr = NULL;	struct pf_addr		*saddr = pd->src, *daddr = pd->dst;	struct pf_rule		*r, *a = NULL;	struct pf_ruleset	*ruleset = NULL;	struct pf_src_node	*nsn = NULL;	u_short			 reason;	u_int16_t		 icmpid;	sa_family_t		 af = pd->af;	u_int8_t		 icmptype, icmpcode;	int			 state_icmp = 0;	struct pf_tag		*pftag = NULL;	int			 tag = -1;#ifdef INET6	int			 rewrite = 0;#endif /* INET6 */	int			 asd = 0;	if (pf_check_congestion(ifq))		return (PF_DROP);	switch (pd->proto) {#ifdef INET	case IPPROTO_ICMP:		icmptype = pd->hdr.icmp->icmp_type;		icmpcode = pd->hdr.icmp->icmp_code;		icmpid = pd->hdr.icmp->icmp_id;		if (icmptype == ICMP_UNREACH ||		    icmptype == ICMP_SOURCEQUENCH ||		    icmptype == ICMP_REDIRECT ||		    icmptype == ICMP_TIMXCEED ||		    icmptype == ICMP_PARAMPROB)			state_icmp++;		break;#endif /* INET */#ifdef INET6	case IPPROTO_ICMPV6:		icmptype = pd->hdr.icmp6->icmp6_type;		icmpcode = pd->hdr.icmp6->icmp6_code;		icmpid = pd->hdr.icmp6->icmp6_id;		if (icmptype == ICMP6_DST_UNREACH ||		    icmptype == ICMP6_PACKET_TOO_BIG ||		    icmptype == ICMP6_TIME_EXCEEDED ||		    icmptype == ICMP6_PARAM_PROB)			state_icmp++;		break;#endif /* INET6 */	}	r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr);	if (direction == PF_OUT) {		/* check outgoing packet for BINAT/NAT */		if ((nr = pf_get_translation(pd, m, off, PF_OUT, kif, &nsn,		    saddr, 0, daddr, 0, &pd->naddr, NULL)) != NULL) {			PF_ACPY(&pd->baddr, saddr, af);			switch (af) {#ifdef INET			case AF_INET:				pf_change_a(&saddr->v4.s_addr, pd->ip_sum,				    pd->naddr.v4.s_addr, 0);				break;#endif /* INET */#ifdef INET6			case AF_INET6:				pf_change_a6(saddr, &pd->hdr.icmp6->icmp6_cksum,				    &pd->naddr, 0);				rewrite++;				break;#endif /* INET6 */			}			if (nr->natpass)				r = NULL;			pd->nat_rule = nr;		}	} else {		/* check incoming packet for BINAT/RDR */		if ((nr = pf_get_translation(pd, m, off, PF_IN, kif, &nsn,		    saddr, 0, daddr, 0, &pd->naddr, NULL)) != NULL) {			PF_ACPY(&pd->baddr, daddr, af);			switch (af) {#ifdef INET			case AF_INET:				pf_change_a(&daddr->v4.s_addr,				    pd->ip_sum, pd->naddr.v4.s_addr, 0);				break;#endif /* INET */#ifdef INET6			case AF_INET6:				pf_change_a6(daddr, &pd->hdr.icmp6->icmp6_cksum,				    &pd->naddr, 0);				rewrite++;				break;#endif /* INET6 */			}			if (nr->natpass)				r = NULL;			pd->nat_rule = nr;		}	}	while (r != NULL) {		r->evaluations++;		if (r->kif != NULL &&		    (r->kif != kif && r->kif != kif->pfik_parent) == !r->ifnot)			r = r->skip[PF_SKIP_IFP].ptr;		else if (r->direction && r->direction != direction)			r = r->skip[PF_SKIP_DIR].ptr;		else if (r->af && r->af != af)			r = r->skip[PF_SKIP_AF].ptr;		else if (r->proto && r->proto != pd->proto)			r = r->skip[PF_SKIP_PROTO].ptr;		else if (PF_MISMATCHAW(&r->src.addr, saddr, af, r->src.neg))			r = r->skip[PF_SKIP_SRC_ADDR].ptr;		else if (PF_MISMATCHAW(&r->dst.addr, daddr, af, r->dst.neg))			r = r->skip[PF_SKIP_DST_ADDR].ptr;		else if (r->type && r->type != icmptype + 1)			r = TAILQ_NEXT(r, entries);		else if (r->code && r->code != icmpcode + 1)			r = TAILQ_NEXT(r, entries);		else if (r->tos && !(r->tos & pd->tos))			r = TAILQ_NEXT(r, entries);		else if (r->rule_flag & PFRULE_FRAGMENT)			r = TAILQ_NEXT(r, entries);		else if (r->prob && r->prob <= arc4random())			r = TAILQ_NEXT(r, entries);		else if (r->match_tag && !pf_match_tag(m, r, nr, &pftag, &tag))			r = TAILQ_NEXT(r, entries);		else if (r->os_fingerprint != PF_OSFP_ANY)			r = TAILQ_NEXT(r, entries);		else {			if (r->tag)				tag = r->tag;			if (r->anchor == NULL) {				*rm = r;				*am = a;				*rsm = ruleset;				if ((*rm)->quick)					break;				r = TAILQ_NEXT(r, entries);			} else				pf_step_into_anchor(&asd, &ruleset,				    PF_RULESET_FILTER, &r, &a);		}		if (r == NULL)			pf_step_out_of_anchor(&asd, &ruleset,			    PF_RULESET_FILTER, &r, &a);	}	r = *rm;	a = *am;	ruleset = *rsm;	REASON_SET(&reason, PFRES_MATCH);	if (r->log) {#ifdef INET6		if (rewrite)			m_copyback(m, off, sizeof(struct icmp6_hdr),			    pd->hdr.icmp6);#endif /* INET6 */		PFLOG_PACKET(kif, h, m, af, direction, reason, r, a, ruleset);	}	if (r->action != PF_PASS)		return (PF_DROP);	if (pf_tag_packet(m, pftag, tag)) {		REASON_SET(&reason, PFRES_MEMORY);		return (PF_DROP);	}	if (!state_icmp && (r->keep_state || nr != NULL)) {		/* create new state */		struct pf_state	*s = NULL;		struct pf_src_node *sn = NULL;		/* check maximums */		if (r->max_states && (r->states >= r->max_states)) {			pf_status.lcounters[LCNT_STATES]++;			goto cleanup;		}		/* src node for flter rule */		if ((r->rule_flag & PFRULE_SRCTRACK ||		    r->rpool.opts & PF_POOL_STICKYADDR) &&		    pf_insert_src_node(&sn, r, saddr, af) != 0)			goto cleanup;		/* src node for translation rule */		if (nr != NULL && (nr->rpool.opts & PF_POOL_STICKYADDR) &&		    ((direction == PF_OUT &&		    pf_insert_src_node(&nsn, nr, &pd->baddr, af) != 0) ||		    (pf_insert_src_node(&nsn, nr, saddr, af) != 0)))			goto cleanup;		s = pool_get(&pf_state_pl, PR_NOWAIT);		if (s == NULL) {cleanup:			if (sn != NULL && sn->states == 0 && sn->expire == 0) {				RB_REMOVE(pf_src_tree, &tree_src_tracking, sn);				pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++;				pf_status.src_nodes--;				pool_put(&pf_src_tree_pl, sn);			}			if (nsn != sn && nsn != NULL && nsn->states == 0 &&			    nsn->expire == 0) {				RB_REMOVE(pf_src_tree, &tree_src_tracking, nsn);				pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++;				pf_status.src_nodes--;				pool_put(&pf_src_tree_pl, nsn);			}			REASON_SET(&reason, PFRES_MEMORY);			return (PF_DROP);		}		bzero(s, sizeof(*s));		s->rule.ptr = r;		s->nat_rule.ptr = nr;		s->anchor.ptr = a;		STATE_INC_COUNTERS(s);		s->allow_opts = r->allow_opts;		s->log = r->log & 2;		s->proto = pd->proto;		s->direction = direction;		s->af = af;		if (direction == PF_OUT) {			PF_ACPY(&s->gwy.addr, saddr, af);			s->gwy.port = icmpid;			PF_ACPY(&s->ext.addr, daddr, af);			s->ext.port = icmpid;			if (nr != NULL)				PF_ACPY(&s->lan.addr, &pd->baddr, af);			else				PF_ACPY(&s->lan.addr, &s->gwy.addr, af);			s->lan.port = icmpid;		} else {			PF_ACPY(&s->lan.addr, daddr, af);			s->lan.port = icmpid;			PF_ACPY(&s->ext.addr, saddr, af);			s->ext.port = icmpid;			if (nr != NULL)				PF_ACPY(&s->gwy.addr, &pd->baddr, af);			else				PF_ACPY(&s->gwy.addr, &s->lan.addr, af);			s->gwy.port = icmpid;		}		s->creation = time_second;		s->expire = time_second;		s->timeout = PFTM_ICMP_FIRST_PACKET;		pf_set_rt_ifp(s, saddr);		if (sn != NULL) {			s->src_node = sn;			s->src_node->states++;		}		if (nsn != NULL) {			PF_ACPY(&nsn->raddr, &pd->naddr, af);			s->nat_src_node = nsn;			s->nat_src_node->states++;		}		if (pf_insert_state(BOUND_IFACE(r, kif), s)) {			REASON_SET(&reason, PFRES_MEMORY);			pf_src_tree_remove_state(s);			STATE_DEC_COUNTERS(s);			pool_put(&pf_state_pl, s);			return (PF_DROP);		} else			*sm = s;	}#ifdef INET6	/* copy back packet headers if we performed IPv6 NAT operations */	if (rewrite)		m_copyback(m, off, sizeof(struct icmp6_hdr),		    pd->hdr.icmp6);#endif /* INET6 */	return (PF_PASS);}