pf.c (2da98eef1f352c496ffd458b4c68ddee972bb903) | pf.c (89f6723288b0d27d3f14f93e6e83f672fa2b8aca) |
---|---|
1/*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2001 Daniel Hartmeier 5 * Copyright (c) 2002 - 2008 Henning Brauer 6 * Copyright (c) 2012 Gleb Smirnoff <glebius@FreeBSD.org> 7 * All rights reserved. 8 * --- 334 unchanged lines hidden (view full) --- 343 struct pfi_kkif *, struct mbuf *, int, 344 void *, struct pf_pdesc *, u_short *); 345static int pf_test_state_udp(struct pf_kstate **, 346 struct pfi_kkif *, struct mbuf *, int, 347 void *, struct pf_pdesc *); 348int pf_icmp_state_lookup(struct pf_state_key_cmp *, 349 struct pf_pdesc *, struct pf_kstate **, struct mbuf *, 350 int, struct pfi_kkif *, u_int16_t, u_int16_t, | 1/*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2001 Daniel Hartmeier 5 * Copyright (c) 2002 - 2008 Henning Brauer 6 * Copyright (c) 2012 Gleb Smirnoff <glebius@FreeBSD.org> 7 * All rights reserved. 8 * --- 334 unchanged lines hidden (view full) --- 343 struct pfi_kkif *, struct mbuf *, int, 344 void *, struct pf_pdesc *, u_short *); 345static int pf_test_state_udp(struct pf_kstate **, 346 struct pfi_kkif *, struct mbuf *, int, 347 void *, struct pf_pdesc *); 348int pf_icmp_state_lookup(struct pf_state_key_cmp *, 349 struct pf_pdesc *, struct pf_kstate **, struct mbuf *, 350 int, struct pfi_kkif *, u_int16_t, u_int16_t, |
351 int, int *, int); | 351 int, int *, int, int); |
352static int pf_test_state_icmp(struct pf_kstate **, 353 struct pfi_kkif *, struct mbuf *, int, 354 void *, struct pf_pdesc *, u_short *); 355static void pf_sctp_multihome_detach_addr(const struct pf_kstate *); 356static void pf_sctp_multihome_delayed(struct pf_pdesc *, int, 357 struct pfi_kkif *, struct pf_kstate *, int); 358static int pf_test_state_sctp(struct pf_kstate **, 359 struct pfi_kkif *, struct mbuf *, int, --- 6274 unchanged lines hidden (view full) --- 6634 len -= sizeof(struct sctp_asconf_chunk); 6635 6636 return (pf_multihome_scan(m, start, len, pd, kif, SCTP_ADD_IP_ADDRESS)); 6637} 6638 6639int 6640pf_icmp_state_lookup(struct pf_state_key_cmp *key, struct pf_pdesc *pd, 6641 struct pf_kstate **state, struct mbuf *m, int direction, struct pfi_kkif *kif, | 352static int pf_test_state_icmp(struct pf_kstate **, 353 struct pfi_kkif *, struct mbuf *, int, 354 void *, struct pf_pdesc *, u_short *); 355static void pf_sctp_multihome_detach_addr(const struct pf_kstate *); 356static void pf_sctp_multihome_delayed(struct pf_pdesc *, int, 357 struct pfi_kkif *, struct pf_kstate *, int); 358static int pf_test_state_sctp(struct pf_kstate **, 359 struct pfi_kkif *, struct mbuf *, int, --- 6274 unchanged lines hidden (view full) --- 6634 len -= sizeof(struct sctp_asconf_chunk); 6635 6636 return (pf_multihome_scan(m, start, len, pd, kif, SCTP_ADD_IP_ADDRESS)); 6637} 6638 6639int 6640pf_icmp_state_lookup(struct pf_state_key_cmp *key, struct pf_pdesc *pd, 6641 struct pf_kstate **state, struct mbuf *m, int direction, struct pfi_kkif *kif, |
6642 u_int16_t icmpid, u_int16_t type, int icmp_dir, int *iidx, int multi) | 6642 u_int16_t icmpid, u_int16_t type, int icmp_dir, int *iidx, int multi, 6643 int inner) |
6643{ 6644 key->af = pd->af; 6645 key->proto = pd->proto; 6646 if (icmp_dir == PF_IN) { 6647 *iidx = pd->sidx; 6648 key->port[pd->sidx] = icmpid; 6649 key->port[pd->didx] = type; 6650 } else { --- 20 unchanged lines hidden (view full) --- 6671 } else 6672 PF_ACPY(&key->addr[pd->sidx], pd->src, key->af); 6673 PF_ACPY(&key->addr[pd->didx], pd->dst, key->af); 6674 6675 STATE_LOOKUP(kif, key, *state, pd); 6676 6677 /* Is this ICMP message flowing in right direction? */ 6678 if ((*state)->rule.ptr->type && | 6644{ 6645 key->af = pd->af; 6646 key->proto = pd->proto; 6647 if (icmp_dir == PF_IN) { 6648 *iidx = pd->sidx; 6649 key->port[pd->sidx] = icmpid; 6650 key->port[pd->didx] = type; 6651 } else { --- 20 unchanged lines hidden (view full) --- 6672 } else 6673 PF_ACPY(&key->addr[pd->sidx], pd->src, key->af); 6674 PF_ACPY(&key->addr[pd->didx], pd->dst, key->af); 6675 6676 STATE_LOOKUP(kif, key, *state, pd); 6677 6678 /* Is this ICMP message flowing in right direction? */ 6679 if ((*state)->rule.ptr->type && |
6679 (((*state)->direction == direction) ? | 6680 (((!inner && (*state)->direction == direction) || 6681 (inner && (*state)->direction != direction)) ? |
6680 PF_IN : PF_OUT) != icmp_dir) { 6681 if (V_pf_status.debug >= PF_DEBUG_MISC) { 6682 printf("pf: icmp type %d in wrong direction (%d): ", 6683 icmp_dir, pd->dir); 6684 pf_print_state(*state); 6685 printf("\n"); 6686 } 6687 return (PF_DROP); --- 41 unchanged lines hidden (view full) --- 6729 if (pf_icmp_mapping(pd, icmptype, &icmp_dir, &multi, 6730 &virtual_id, &virtual_type) == 0) { 6731 /* 6732 * ICMP query/reply message not related to a TCP/UDP packet. 6733 * Search for an ICMP state. 6734 */ 6735 ret = pf_icmp_state_lookup(&key, pd, state, m, pd->dir, 6736 kif, virtual_id, virtual_type, icmp_dir, &iidx, | 6682 PF_IN : PF_OUT) != icmp_dir) { 6683 if (V_pf_status.debug >= PF_DEBUG_MISC) { 6684 printf("pf: icmp type %d in wrong direction (%d): ", 6685 icmp_dir, pd->dir); 6686 pf_print_state(*state); 6687 printf("\n"); 6688 } 6689 return (PF_DROP); --- 41 unchanged lines hidden (view full) --- 6731 if (pf_icmp_mapping(pd, icmptype, &icmp_dir, &multi, 6732 &virtual_id, &virtual_type) == 0) { 6733 /* 6734 * ICMP query/reply message not related to a TCP/UDP packet. 6735 * Search for an ICMP state. 6736 */ 6737 ret = pf_icmp_state_lookup(&key, pd, state, m, pd->dir, 6738 kif, virtual_id, virtual_type, icmp_dir, &iidx, |
6737 PF_ICMP_MULTI_NONE); | 6739 PF_ICMP_MULTI_NONE, 0); |
6738 if (ret >= 0) { 6739 if (ret == PF_DROP && pd->af == AF_INET6 && 6740 icmp_dir == PF_OUT) { 6741 if (*state != NULL) 6742 PF_STATE_UNLOCK((*state)); 6743 ret = pf_icmp_state_lookup(&key, pd, state, m, 6744 pd->dir, kif, virtual_id, virtual_type, | 6740 if (ret >= 0) { 6741 if (ret == PF_DROP && pd->af == AF_INET6 && 6742 icmp_dir == PF_OUT) { 6743 if (*state != NULL) 6744 PF_STATE_UNLOCK((*state)); 6745 ret = pf_icmp_state_lookup(&key, pd, state, m, 6746 pd->dir, kif, virtual_id, virtual_type, |
6745 icmp_dir, &iidx, multi); | 6747 icmp_dir, &iidx, multi, 0); |
6746 if (ret >= 0) 6747 return (ret); 6748 } else 6749 return (ret); 6750 } 6751 6752 (*state)->expire = pf_get_uptime(); 6753 (*state)->timeout = PFTM_ICMP_ERROR_REPLY; --- 67 unchanged lines hidden (view full) --- 6821#ifdef INET6 6822 struct ip6_hdr h2_6; 6823 int terminal = 0; 6824#endif /* INET6 */ 6825 int ipoff2 = 0; 6826 int off2 = 0; 6827 6828 pd2.af = pd->af; | 6748 if (ret >= 0) 6749 return (ret); 6750 } else 6751 return (ret); 6752 } 6753 6754 (*state)->expire = pf_get_uptime(); 6755 (*state)->timeout = PFTM_ICMP_ERROR_REPLY; --- 67 unchanged lines hidden (view full) --- 6823#ifdef INET6 6824 struct ip6_hdr h2_6; 6825 int terminal = 0; 6826#endif /* INET6 */ 6827 int ipoff2 = 0; 6828 int off2 = 0; 6829 6830 pd2.af = pd->af; |
6831 pd2.dir = pd->dir; |
|
6829 /* Payload packet is from the opposite direction. */ 6830 pd2.sidx = (pd->dir == PF_IN) ? 1 : 0; 6831 pd2.didx = (pd->dir == PF_IN) ? 0 : 1; 6832 switch (pd->af) { 6833#ifdef INET 6834 case AF_INET: 6835 /* offset of h2 in mbuf chain */ 6836 ipoff2 = off + ICMP_MINLEN; --- 305 unchanged lines hidden (view full) --- 7142 "(icmp)\n")); 7143 return (PF_DROP); 7144 } 7145 7146 icmpid = iih->icmp_id; 7147 pf_icmp_mapping(&pd2, iih->icmp_type, 7148 &icmp_dir, &multi, &virtual_id, &virtual_type); 7149 | 6832 /* Payload packet is from the opposite direction. */ 6833 pd2.sidx = (pd->dir == PF_IN) ? 1 : 0; 6834 pd2.didx = (pd->dir == PF_IN) ? 0 : 1; 6835 switch (pd->af) { 6836#ifdef INET 6837 case AF_INET: 6838 /* offset of h2 in mbuf chain */ 6839 ipoff2 = off + ICMP_MINLEN; --- 305 unchanged lines hidden (view full) --- 7145 "(icmp)\n")); 7146 return (PF_DROP); 7147 } 7148 7149 icmpid = iih->icmp_id; 7150 pf_icmp_mapping(&pd2, iih->icmp_type, 7151 &icmp_dir, &multi, &virtual_id, &virtual_type); 7152 |
7150 pd2.dir = icmp_dir; | |
7151 ret = pf_icmp_state_lookup(&key, &pd2, state, m, 7152 pd2.dir, kif, virtual_id, virtual_type, | 7153 ret = pf_icmp_state_lookup(&key, &pd2, state, m, 7154 pd2.dir, kif, virtual_id, virtual_type, |
7153 icmp_dir, &iidx, PF_ICMP_MULTI_NONE); | 7155 icmp_dir, &iidx, PF_ICMP_MULTI_NONE, 1); |
7154 if (ret >= 0) 7155 return (ret); 7156 7157 /* translate source/destination address, if necessary */ 7158 if ((*state)->key[PF_SK_WIRE] != 7159 (*state)->key[PF_SK_STACK]) { 7160 struct pf_state_key *nk = 7161 (*state)->key[pd->didx]; --- 36 unchanged lines hidden (view full) --- 7198 ("pf: ICMP error message too short " 7199 "(icmp6)\n")); 7200 return (PF_DROP); 7201 } 7202 7203 pf_icmp_mapping(&pd2, iih->icmp6_type, 7204 &icmp_dir, &multi, &virtual_id, &virtual_type); 7205 | 7156 if (ret >= 0) 7157 return (ret); 7158 7159 /* translate source/destination address, if necessary */ 7160 if ((*state)->key[PF_SK_WIRE] != 7161 (*state)->key[PF_SK_STACK]) { 7162 struct pf_state_key *nk = 7163 (*state)->key[pd->didx]; --- 36 unchanged lines hidden (view full) --- 7200 ("pf: ICMP error message too short " 7201 "(icmp6)\n")); 7202 return (PF_DROP); 7203 } 7204 7205 pf_icmp_mapping(&pd2, iih->icmp6_type, 7206 &icmp_dir, &multi, &virtual_id, &virtual_type); 7207 |
7206 pd2.dir = icmp_dir; | |
7207 ret = pf_icmp_state_lookup(&key, &pd2, state, m, 7208 pd->dir, kif, virtual_id, virtual_type, | 7208 ret = pf_icmp_state_lookup(&key, &pd2, state, m, 7209 pd->dir, kif, virtual_id, virtual_type, |
7209 icmp_dir, &iidx, PF_ICMP_MULTI_NONE); | 7210 icmp_dir, &iidx, PF_ICMP_MULTI_NONE, 1); |
7210 if (ret >= 0) { 7211 if (ret == PF_DROP && pd->af == AF_INET6 && 7212 icmp_dir == PF_OUT) { 7213 if (*state != NULL) 7214 PF_STATE_UNLOCK((*state)); 7215 ret = pf_icmp_state_lookup(&key, pd, 7216 state, m, pd->dir, kif, 7217 virtual_id, virtual_type, | 7211 if (ret >= 0) { 7212 if (ret == PF_DROP && pd->af == AF_INET6 && 7213 icmp_dir == PF_OUT) { 7214 if (*state != NULL) 7215 PF_STATE_UNLOCK((*state)); 7216 ret = pf_icmp_state_lookup(&key, pd, 7217 state, m, pd->dir, kif, 7218 virtual_id, virtual_type, |
7218 icmp_dir, &iidx, multi); | 7219 icmp_dir, &iidx, multi, 1); |
7219 if (ret >= 0) 7220 return (ret); 7221 } else 7222 return (ret); 7223 } 7224 7225 /* translate source/destination address, if necessary */ 7226 if ((*state)->key[PF_SK_WIRE] != --- 2184 unchanged lines hidden --- | 7220 if (ret >= 0) 7221 return (ret); 7222 } else 7223 return (ret); 7224 } 7225 7226 /* translate source/destination address, if necessary */ 7227 if ((*state)->key[PF_SK_WIRE] != --- 2184 unchanged lines hidden --- |