| 4621 | } |
| 4622 | |
| 4623 | static int |
| 4624 | pf_test_state_udp(struct pf_state **state, int direction, struct pfi_kkif *kif, |
| 4625 | struct mbuf *m, int off, void *h, struct pf_pdesc *pd) |
| 4626 | { |
| 4627 | struct pf_state_peer *src, *dst; |
| 4628 | struct pf_state_key_cmp key; |
| 4629 | struct udphdr *uh = pd->hdr.udp; |
| 4630 | |
| 4631 | bzero(&key, sizeof(key)); |
| 4632 | key.af = pd->af; |
| 4633 | key.proto = IPPROTO_UDP; |
| 4634 | if (direction == PF_IN) { /* wire side, straight */ |
| 4635 | PF_ACPY(&key.addr[0], pd->src, key.af); |
| 4636 | PF_ACPY(&key.addr[1], pd->dst, key.af); |
| 4637 | key.port[0] = uh->uh_sport; |
| 4638 | key.port[1] = uh->uh_dport; |
| 4639 | } else { /* stack side, reverse */ |
| 4640 | PF_ACPY(&key.addr[1], pd->src, key.af); |
| 4641 | PF_ACPY(&key.addr[0], pd->dst, key.af); |
| 4642 | key.port[1] = uh->uh_sport; |
| 4643 | key.port[0] = uh->uh_dport; |
| 4644 | } |
| 4645 | |
| 4646 | STATE_LOOKUP(kif, &key, direction, *state, pd); |
| 4647 | |
| 4648 | if (direction == (*state)->direction) { |
| 4649 | src = &(*state)->src; |
| 4650 | dst = &(*state)->dst; |
| 4651 | } else { |
| 4652 | src = &(*state)->dst; |
| 4653 | dst = &(*state)->src; |
| 4654 | } |
| 4655 | |
| 4656 | /* update states */ |
| 4657 | if (src->state < PFUDPS_SINGLE) |
| 4658 | src->state = PFUDPS_SINGLE; |
| 4659 | if (dst->state == PFUDPS_SINGLE) |
| 4660 | dst->state = PFUDPS_MULTIPLE; |
| 4661 | |
| 4662 | /* update expire time */ |
| 4663 | (*state)->expire = time_uptime; |
| 4664 | if (src->state == PFUDPS_MULTIPLE && dst->state == PFUDPS_MULTIPLE) |
| 4665 | (*state)->timeout = PFTM_UDP_MULTIPLE; |
| 4666 | else |
| 4667 | (*state)->timeout = PFTM_UDP_SINGLE; |
| 4668 | |
| 4669 | /* translate source/destination address, if necessary */ |
| 4670 | if ((*state)->key[PF_SK_WIRE] != (*state)->key[PF_SK_STACK]) { |
| 4671 | struct pf_state_key *nk = (*state)->key[pd->didx]; |
| 4672 | |
| 4673 | if (PF_ANEQ(pd->src, &nk->addr[pd->sidx], pd->af) || |
| 4674 | nk->port[pd->sidx] != uh->uh_sport) |
| 4675 | pf_change_ap(m, pd->src, &uh->uh_sport, pd->ip_sum, |
| 4676 | &uh->uh_sum, &nk->addr[pd->sidx], |
| 4677 | nk->port[pd->sidx], 1, pd->af); |
| 4678 | |
| 4679 | if (PF_ANEQ(pd->dst, &nk->addr[pd->didx], pd->af) || |
| 4680 | nk->port[pd->didx] != uh->uh_dport) |
no test coverage detected