| 4688 | } |
| 4689 | |
| 4690 | static int |
| 4691 | pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kkif *kif, |
| 4692 | struct mbuf *m, int off, void *h, struct pf_pdesc *pd, u_short *reason) |
| 4693 | { |
| 4694 | struct pf_addr *saddr = pd->src, *daddr = pd->dst; |
| 4695 | u_int16_t icmpid = 0, *icmpsum; |
| 4696 | u_int8_t icmptype, icmpcode; |
| 4697 | int state_icmp = 0; |
| 4698 | struct pf_state_key_cmp key; |
| 4699 | |
| 4700 | bzero(&key, sizeof(key)); |
| 4701 | switch (pd->proto) { |
| 4702 | #ifdef INET |
| 4703 | case IPPROTO_ICMP: |
| 4704 | icmptype = pd->hdr.icmp->icmp_type; |
| 4705 | icmpcode = pd->hdr.icmp->icmp_code; |
| 4706 | icmpid = pd->hdr.icmp->icmp_id; |
| 4707 | icmpsum = &pd->hdr.icmp->icmp_cksum; |
| 4708 | |
| 4709 | if (icmptype == ICMP_UNREACH || |
| 4710 | icmptype == ICMP_SOURCEQUENCH || |
| 4711 | icmptype == ICMP_REDIRECT || |
| 4712 | icmptype == ICMP_TIMXCEED || |
| 4713 | icmptype == ICMP_PARAMPROB) |
| 4714 | state_icmp++; |
| 4715 | break; |
| 4716 | #endif /* INET */ |
| 4717 | #ifdef INET6 |
| 4718 | case IPPROTO_ICMPV6: |
| 4719 | icmptype = pd->hdr.icmp6->icmp6_type; |
| 4720 | icmpcode = pd->hdr.icmp6->icmp6_code; |
| 4721 | icmpid = pd->hdr.icmp6->icmp6_id; |
| 4722 | icmpsum = &pd->hdr.icmp6->icmp6_cksum; |
| 4723 | |
| 4724 | if (icmptype == ICMP6_DST_UNREACH || |
| 4725 | icmptype == ICMP6_PACKET_TOO_BIG || |
| 4726 | icmptype == ICMP6_TIME_EXCEEDED || |
| 4727 | icmptype == ICMP6_PARAM_PROB) |
| 4728 | state_icmp++; |
| 4729 | break; |
| 4730 | #endif /* INET6 */ |
| 4731 | } |
| 4732 | |
| 4733 | if (!state_icmp) { |
| 4734 | /* |
| 4735 | * ICMP query/reply message not related to a TCP/UDP packet. |
| 4736 | * Search for an ICMP state. |
| 4737 | */ |
| 4738 | key.af = pd->af; |
| 4739 | key.proto = pd->proto; |
| 4740 | key.port[0] = key.port[1] = icmpid; |
| 4741 | if (direction == PF_IN) { /* wire side, straight */ |
| 4742 | PF_ACPY(&key.addr[0], pd->src, key.af); |
| 4743 | PF_ACPY(&key.addr[1], pd->dst, key.af); |
| 4744 | } else { /* stack side, reverse */ |
| 4745 | PF_ACPY(&key.addr[1], pd->src, key.af); |
| 4746 | PF_ACPY(&key.addr[0], pd->dst, key.af); |
| 4747 | } |
no test coverage detected