Expand Up
@@ -295,8 +295,6 @@ static void pf_change_ap(struct mbuf *, struct pf_addr *, u_int16_t *,
u_int16_t , u_int8_t , sa_family_t );
static int pf_modulate_sack (struct mbuf * , int , struct pf_pdesc * ,
struct tcphdr * , struct pf_state_peer * );
int pf_icmp_mapping (struct pf_pdesc * , u_int8_t , int * ,
int * , u_int16_t * , u_int16_t * );
static void pf_change_icmp (struct pf_addr * , u_int16_t * ,
struct pf_addr * , struct pf_addr * , u_int16_t ,
u_int16_t * , u_int16_t * , u_int16_t * ,
Expand Down
Expand Up
@@ -343,10 +341,6 @@ static int pf_test_state_tcp(struct pf_kstate **,
static int pf_test_state_udp (struct pf_kstate * * ,
struct pfi_kkif * , struct mbuf * , int ,
void * , struct pf_pdesc * );
int pf_icmp_state_lookup (struct pf_state_key_cmp * ,
struct pf_pdesc * , struct pf_kstate * * , struct mbuf * ,
int , struct pfi_kkif * , u_int16_t , u_int16_t ,
int , int * , int , int );
static int pf_test_state_icmp (struct pf_kstate * * ,
struct pfi_kkif * , struct mbuf * , int ,
void * , struct pf_pdesc * , u_short * );
Expand Down
Expand Up
@@ -399,8 +393,6 @@ extern struct proc *pf_purge_proc;
VNET_DEFINE (struct pf_limit , pf_limits [PF_LIMIT_MAX ]);
enum { PF_ICMP_MULTI_NONE , PF_ICMP_MULTI_SOLICITED , PF_ICMP_MULTI_LINK };
#define PACKET_UNDO_NAT (_m , _pd , _off , _s ) \
do { \
struct pf_state_key *nk; \
Expand Down
Expand Up
@@ -1767,174 +1759,6 @@ pf_isforlocal(struct mbuf *m, int af)
return (false);
}
int
pf_icmp_mapping (struct pf_pdesc * pd , u_int8_t type ,
int * icmp_dir , int * multi , u_int16_t * virtual_id , u_int16_t * virtual_type )
{
/*
* ICMP types marked with PF_OUT are typically responses to
* PF_IN, and will match states in the opposite direction.
* PF_IN ICMP types need to match a state with that type.
*/
* icmp_dir = PF_OUT ;
* multi = PF_ICMP_MULTI_LINK ;
/* Queries (and responses) */
switch (pd -> af ) {
#ifdef INET
case AF_INET :
switch (type ) {
case ICMP_ECHO :
* icmp_dir = PF_IN ;
case ICMP_ECHOREPLY :
* virtual_type = ICMP_ECHO ;
* virtual_id = pd -> hdr .icmp .icmp_id ;
break ;
case ICMP_TSTAMP :
* icmp_dir = PF_IN ;
case ICMP_TSTAMPREPLY :
* virtual_type = ICMP_TSTAMP ;
* virtual_id = pd -> hdr .icmp .icmp_id ;
break ;
case ICMP_IREQ :
* icmp_dir = PF_IN ;
case ICMP_IREQREPLY :
* virtual_type = ICMP_IREQ ;
* virtual_id = pd -> hdr .icmp .icmp_id ;
break ;
case ICMP_MASKREQ :
* icmp_dir = PF_IN ;
case ICMP_MASKREPLY :
* virtual_type = ICMP_MASKREQ ;
* virtual_id = pd -> hdr .icmp .icmp_id ;
break ;
case ICMP_IPV6_WHEREAREYOU :
* icmp_dir = PF_IN ;
case ICMP_IPV6_IAMHERE :
* virtual_type = ICMP_IPV6_WHEREAREYOU ;
* virtual_id = 0 ; /* Nothing sane to match on! */
break ;
case ICMP_MOBILE_REGREQUEST :
* icmp_dir = PF_IN ;
case ICMP_MOBILE_REGREPLY :
* virtual_type = ICMP_MOBILE_REGREQUEST ;
* virtual_id = 0 ; /* Nothing sane to match on! */
break ;
case ICMP_ROUTERSOLICIT :
* icmp_dir = PF_IN ;
case ICMP_ROUTERADVERT :
* virtual_type = ICMP_ROUTERSOLICIT ;
* virtual_id = 0 ; /* Nothing sane to match on! */
break ;
/* These ICMP types map to other connections */
case ICMP_UNREACH :
case ICMP_SOURCEQUENCH :
case ICMP_REDIRECT :
case ICMP_TIMXCEED :
case ICMP_PARAMPROB :
/* These will not be used, but set them anyway */
* icmp_dir = PF_IN ;
* virtual_type = type ;
* virtual_id = 0 ;
HTONS (* virtual_type );
return (1 ); /* These types match to another state */
/*
* All remaining ICMP types get their own states,
* and will only match in one direction.
*/
default :
* icmp_dir = PF_IN ;
* virtual_type = type ;
* virtual_id = 0 ;
break ;
}
break ;
#endif /* INET */
#ifdef INET6
case AF_INET6 :
switch (type ) {
case ICMP6_ECHO_REQUEST :
* icmp_dir = PF_IN ;
case ICMP6_ECHO_REPLY :
* virtual_type = ICMP6_ECHO_REQUEST ;
* virtual_id = pd -> hdr .icmp6 .icmp6_id ;
break ;
case MLD_LISTENER_QUERY :
case MLD_LISTENER_REPORT : {
/*
* Listener Report can be sent by clients
* without an associated Listener Query.
* In addition to that, when Report is sent as a
* reply to a Query its source and destination
* address are different.
*/
* icmp_dir = PF_IN ;
* virtual_type = MLD_LISTENER_QUERY ;
* virtual_id = 0 ; /* XXX missing fake id */
break ;
}
case MLD_MTRACE :
* icmp_dir = PF_IN ;
case MLD_MTRACE_RESP :
* virtual_type = MLD_MTRACE ;
* virtual_id = 0 ; /* Nothing sane to match on! */
break ;
case ND_NEIGHBOR_SOLICIT :
* icmp_dir = PF_IN ;
case ND_NEIGHBOR_ADVERT : {
* virtual_type = ND_NEIGHBOR_SOLICIT ;
* multi = PF_ICMP_MULTI_SOLICITED ;
* virtual_id = 0 ; /* XXX missing fake id */
HTONS (* virtual_type ); return (1 ); /* XXX disable state tracking for now */
break ;
}
/*
* These ICMP types map to other connections.
* ND_REDIRECT can't be in this list because the triggering
* packet header is optional.
*/
case ICMP6_DST_UNREACH :
case ICMP6_PACKET_TOO_BIG :
case ICMP6_TIME_EXCEEDED :
case ICMP6_PARAM_PROB :
/* These will not be used, but set them anyway */
* icmp_dir = PF_IN ;
* virtual_type = type ;
* virtual_id = 0 ;
HTONS (* virtual_type );
return (1 ); /* These types match to another state */
/*
* All remaining ICMP6 types get their own states,
* and will only match in one direction.
*/
default :
* icmp_dir = PF_IN ;
* virtual_type = type ;
* virtual_id = 0 ;
break ;
}
break ;
#endif /* INET6 */
default :
* icmp_dir = PF_IN ;
* virtual_type = type ;
* virtual_id = 0 ;
break ;
}
HTONS (* virtual_type );
return (0 ); /* These types match to their own state */
}
void
pf_intr (void * v )
{
Expand Down
Expand Up
@@ -4598,8 +4422,8 @@ pf_test_rule(struct pf_krule **rm, struct pf_kstate **sm, struct pfi_kkif *kif,
int tag = -1 ;
int asd = 0 ;
int match = 0 ;
int state_icmp = 0 , icmp_dir , multi ;
u_int16_t sport = 0 , dport = 0 , virtual_type , virtual_id ;
int state_icmp = 0 ;
u_int16_t sport = 0 , dport = 0 ;
u_int16_t bproto_sum = 0 , bip_sum = 0 ;
u_int8_t icmptype = 0 , icmpcode = 0 ;
struct pf_kanchor_stackframe anchor_stack [PF_ANCHOR_STACKSIZE ];
Expand Down
Expand Up
@@ -4633,37 +4457,33 @@ pf_test_rule(struct pf_krule **rm, struct pf_kstate **sm, struct pfi_kkif *kif,
case IPPROTO_ICMP :
if (pd -> af != AF_INET )
break ;
sport = dport = pd -> hdr .icmp .icmp_id ;
hdrlen = sizeof (pd -> hdr .icmp );
icmptype = pd -> hdr .icmp .icmp_type ;
icmpcode = pd -> hdr .icmp .icmp_code ;
state_icmp = pf_icmp_mapping (pd , icmptype ,
& icmp_dir , & multi , & virtual_id , & virtual_type );
if (icmp_dir == PF_IN ) {
sport = virtual_id ;
dport = virtual_type ;
} else {
sport = virtual_type ;
dport = virtual_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 :
if (af != AF_INET6 )
break ;
sport = dport = pd -> hdr .icmp6 .icmp6_id ;
hdrlen = sizeof (pd -> hdr .icmp6 );
icmptype = pd -> hdr .icmp6 .icmp6_type ;
icmpcode = pd -> hdr .icmp6 .icmp6_code ;
state_icmp = pf_icmp_mapping (pd , icmptype ,
& icmp_dir , & multi , & virtual_id , & virtual_type );
if (icmp_dir == PF_IN ) {
sport = virtual_id ;
dport = virtual_type ;
} else {
sport = virtual_type ;
dport = virtual_id ;
}
if (icmptype == ICMP6_DST_UNREACH ||
icmptype == ICMP6_PACKET_TOO_BIG ||
icmptype == ICMP6_TIME_EXCEEDED ||
icmptype == ICMP6_PARAM_PROB )
state_icmp ++ ;
break ;
#endif /* INET6 */
default :
Expand Down
Expand Up
@@ -4757,6 +4577,7 @@ pf_test_rule(struct pf_krule **rm, struct pf_kstate **sm, struct pfi_kkif *kif,
}
#ifdef INET
case IPPROTO_ICMP :
nk -> port [0 ] = nk -> port [1 ];
if (PF_ANEQ (saddr , & nk -> addr [pd -> sidx ], AF_INET ))
pf_change_a (& saddr -> v4 .s_addr , pd -> ip_sum ,
nk -> addr [pd -> sidx ].v4 .s_addr , 0 );
Expand All
@@ -4765,19 +4586,19 @@ pf_test_rule(struct pf_krule **rm, struct pf_kstate **sm, struct pfi_kkif *kif,
pf_change_a (& daddr -> v4 .s_addr , pd -> ip_sum ,
nk -> addr [pd -> didx ].v4 .s_addr , 0 );
if (virtual_type == htons (ICMP_ECHO ) &&
nk -> port [pd -> sidx ] != pd -> hdr .icmp .icmp_id ) {
if (nk -> port [1 ] != pd -> hdr .icmp .icmp_id ) {
pd -> hdr .icmp .icmp_cksum = pf_cksum_fixup (
pd -> hdr .icmp .icmp_cksum , sport ,
nk -> port [pd -> sidx ], 0 );
pd -> hdr .icmp .icmp_id = nk -> port [pd -> sidx ];
nk -> port [1 ], 0 );
pd -> hdr .icmp .icmp_id = nk -> port [1 ];
pd -> sport = & pd -> hdr .icmp .icmp_id ;
}
m_copyback (m , off , ICMP_MINLEN , (caddr_t )& pd -> hdr .icmp );
break ;
#endif /* INET */
#ifdef INET6
case IPPROTO_ICMPV6 :
nk -> port [0 ] = nk -> port [1 ];
if (PF_ANEQ (saddr , & nk -> addr [pd -> sidx ], AF_INET6 ))
pf_change_a6 (saddr , & pd -> hdr .icmp6 .icmp6_cksum ,
& nk -> addr [pd -> sidx ], 0 );
Expand Down
Expand Up
@@ -6619,75 +6440,15 @@ pf_multihome_scan_asconf(struct mbuf *m, int start, int len,
return (pf_multihome_scan (m , start , len , pd , kif , SCTP_ADD_IP_ADDRESS ));
}
int
pf_icmp_state_lookup (struct pf_state_key_cmp * key , struct pf_pdesc * pd ,
struct pf_kstate * * state , struct mbuf * m , int direction , struct pfi_kkif * kif ,
u_int16_t icmpid , u_int16_t type , int icmp_dir , int * iidx , int multi ,
int inner )
{
key -> af = pd -> af ;
key -> proto = pd -> proto ;
if (icmp_dir == PF_IN ) {
* iidx = pd -> sidx ;
key -> port [pd -> sidx ] = icmpid ;
key -> port [pd -> didx ] = type ;
} else {
* iidx = pd -> didx ;
key -> port [pd -> sidx ] = type ;
key -> port [pd -> didx ] = icmpid ;
}
if (pd -> af == AF_INET6 && multi != PF_ICMP_MULTI_NONE ) {
switch (multi ) {
case PF_ICMP_MULTI_SOLICITED :
key -> addr [pd -> sidx ].addr32 [0 ] = IPV6_ADDR_INT32_MLL ;
key -> addr [pd -> sidx ].addr32 [1 ] = 0 ;
key -> addr [pd -> sidx ].addr32 [2 ] = IPV6_ADDR_INT32_ONE ;
key -> addr [pd -> sidx ].addr32 [3 ] = pd -> src -> addr32 [3 ];
key -> addr [pd -> sidx ].addr8 [12 ] = 0xff ;
break ;
case PF_ICMP_MULTI_LINK :
key -> addr [pd -> sidx ].addr32 [0 ] = IPV6_ADDR_INT32_MLL ;
key -> addr [pd -> sidx ].addr32 [1 ] = 0 ;
key -> addr [pd -> sidx ].addr32 [2 ] = 0 ;
key -> addr [pd -> sidx ].addr32 [3 ] = IPV6_ADDR_INT32_ONE ;
break ;
}
} else
PF_ACPY (& key -> addr [pd -> sidx ], pd -> src , key -> af );
PF_ACPY (& key -> addr [pd -> didx ], pd -> dst , key -> af );
STATE_LOOKUP (kif , key , * state , pd );
/* Is this ICMP message flowing in right direction? */
if ((* state )-> rule .ptr -> type &&
(((!inner && (* state )-> direction == direction ) ||
(inner && (* state )-> direction != direction )) ?
PF_IN : PF_OUT ) != icmp_dir ) {
if (V_pf_status .debug >= PF_DEBUG_MISC ) {
printf ("pf: icmp type %d in wrong direction (%d): " ,
icmp_dir , pd -> dir );
pf_print_state (* state );
printf ("\n" );
}
return (PF_DROP );
}
return (-1 );
}
static int
pf_test_state_icmp (struct pf_kstate * * state , struct pfi_kkif * kif ,
struct mbuf * m , int off , void * h , struct pf_pdesc * pd , u_short * reason )
{
struct pf_addr * saddr = pd -> src , * daddr = pd -> dst ;
u_int16_t * icmpsum , virtual_id , virtual_type ;
u_int16_t icmpid = 0 , * icmpsum ;
u_int8_t icmptype , icmpcode ;
int icmp_dir , iidx , ret , multi ;
int state_icmp = 0 ;
struct pf_state_key_cmp key ;
#ifdef INET
u_int16_t icmpid ;
#endif
MPASS (* state == NULL );
bzero (& key , sizeof (key ));
switch (pd -> proto ) {
Expand All
@@ -6697,43 +6458,49 @@ pf_test_state_icmp(struct pf_kstate **state, struct pfi_kkif *kif,
icmpcode = pd -> hdr .icmp .icmp_code ;
icmpid = pd -> hdr .icmp .icmp_id ;
icmpsum = & pd -> hdr .icmp .icmp_cksum ;
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 ;
#ifdef INET
icmpid = pd -> hdr .icmp6 .icmp6_id ;
#endif
icmpsum = & pd -> hdr .icmp6 .icmp6_cksum ;
if (icmptype == ICMP6_DST_UNREACH ||
icmptype == ICMP6_PACKET_TOO_BIG ||
icmptype == ICMP6_TIME_EXCEEDED ||
icmptype == ICMP6_PARAM_PROB )
state_icmp ++ ;
break ;
#endif /* INET6 */
}
if (pf_icmp_mapping (pd , icmptype , & icmp_dir , & multi ,
& virtual_id , & virtual_type ) == 0 ) {
if (!state_icmp ) {
/*
* ICMP query/reply message not related to a TCP/UDP packet.
* Search for an ICMP state.
*/
ret = pf_icmp_state_lookup (& key , pd , state , m , pd -> dir ,
kif , virtual_id , virtual_type , icmp_dir , & iidx ,
PF_ICMP_MULTI_NONE , 0 );
if (ret >= 0 ) {
if (ret == PF_DROP && pd -> af == AF_INET6 &&
icmp_dir == PF_OUT ) {
if (* state != NULL )
PF_STATE_UNLOCK ((* state ));
ret = pf_icmp_state_lookup (& key , pd , state , m ,
pd -> dir , kif , virtual_id , virtual_type ,
icmp_dir , & iidx , multi , 0 );
if (ret >= 0 )
return (ret );
} else
return (ret );
key .af = pd -> af ;
key .proto = pd -> proto ;
key .port [0 ] = key .port [1 ] = icmpid ;
if (pd -> dir == PF_IN ) { /* wire side, straight */
PF_ACPY (& key .addr [0 ], pd -> src , key .af );
PF_ACPY (& key .addr [1 ], pd -> dst , key .af );
} else { /* stack side, reverse */
PF_ACPY (& key .addr [1 ], pd -> src , key .af );
PF_ACPY (& key .addr [0 ], pd -> dst , key .af );
}
STATE_LOOKUP (kif , & key , * state , pd );
(* state )-> expire = time_uptime ;
(* state )-> timeout = PFTM_ICMP_ERROR_REPLY ;
Expand All
@@ -6756,14 +6523,14 @@ pf_test_state_icmp(struct pf_kstate **state, struct pfi_kkif *kif,
pd -> ip_sum ,
nk -> addr [pd -> didx ].v4 .s_addr , 0 );
if (nk -> port [iidx ] !=
if (nk -> port [0 ] !=
pd -> hdr .icmp .icmp_id ) {
pd -> hdr .icmp .icmp_cksum =
pf_cksum_fixup (
pd -> hdr .icmp .icmp_cksum , icmpid ,
nk -> port [iidx ], 0 );
nk -> port [pd -> sidx ], 0 );
pd -> hdr .icmp .icmp_id =
nk -> port [iidx ];
nk -> port [pd -> sidx ];
}
m_copyback (m , off , ICMP_MINLEN ,
Expand Down
Expand Up
@@ -6811,7 +6578,6 @@ pf_test_state_icmp(struct pf_kstate **state, struct pfi_kkif *kif,
int off2 = 0 ;
pd2 .af = pd -> af ;
pd2 .dir = pd -> dir ;
/* Payload packet is from the opposite direction. */
pd2 .sidx = (pd -> dir == PF_IN ) ? 1 : 0 ;
pd2 .didx = (pd -> dir == PF_IN ) ? 0 : 1 ;
Expand Down
Expand Up
@@ -7119,25 +6885,23 @@ pf_test_state_icmp(struct pf_kstate **state, struct pfi_kkif *kif,
}
#ifdef INET
case IPPROTO_ICMP : {
struct icmp * iih = & pd2 . hdr . icmp ;
struct icmp iih ;
if (!pf_pull_hdr (m , off2 , iih , ICMP_MINLEN ,
if (!pf_pull_hdr (m , off2 , & iih , ICMP_MINLEN ,
NULL , reason , pd2 .af )) {
DPFPRINTF (PF_DEBUG_MISC ,
("pf: ICMP error message too short i"
"(icmp)\n" ));
return (PF_DROP );
}
icmpid = iih -> icmp_id ;
pf_icmp_mapping (& pd2 , iih -> icmp_type ,
& icmp_dir , & multi , & virtual_id , & virtual_type );
key .af = pd2 .af ;
key .proto = IPPROTO_ICMP ;
PF_ACPY (& key .addr [pd2 .sidx ], pd2 .src , key .af );
PF_ACPY (& key .addr [pd2 .didx ], pd2 .dst , key .af );
key .port [0 ] = key .port [1 ] = iih .icmp_id ;
ret = pf_icmp_state_lookup (& key , & pd2 , state , m ,
pd2 .dir , kif , virtual_id , virtual_type ,
icmp_dir , & iidx , PF_ICMP_MULTI_NONE , 1 );
if (ret >= 0 )
return (ret );
STATE_LOOKUP (kif , & key , * state , pd );
/* translate source/destination address, if necessary */
if ((* state )-> key [PF_SK_WIRE ] !=
Expand All
@@ -7147,64 +6911,49 @@ pf_test_state_icmp(struct pf_kstate **state, struct pfi_kkif *kif,
if (PF_ANEQ (pd2 .src ,
& nk -> addr [pd2 .sidx ], pd2 .af ) ||
(virtual_type == htons (ICMP_ECHO ) &&
nk -> port [iidx ] != iih -> icmp_id ))
pf_change_icmp (pd2 .src ,
(virtual_type == htons (ICMP_ECHO )) ?
& iih -> icmp_id : NULL ,
nk -> port [pd2 .sidx ] != iih .icmp_id )
pf_change_icmp (pd2 .src , & iih .icmp_id ,
daddr , & nk -> addr [pd2 .sidx ],
(virtual_type == htons (ICMP_ECHO )) ?
nk -> port [iidx ] : 0 , NULL ,
nk -> port [pd2 .sidx ], NULL ,
pd2 .ip_sum , icmpsum ,
pd -> ip_sum , 0 , AF_INET );
if (PF_ANEQ (pd2 .dst ,
& nk -> addr [pd2 .didx ], pd2 .af ))
pf_change_icmp (pd2 .dst , NULL , NULL ,
& nk -> addr [pd2 .didx ], 0 , NULL ,
pd2 .ip_sum , icmpsum , pd -> ip_sum , 0 ,
AF_INET );
& nk -> addr [pd2 .didx ], pd2 .af ) ||
nk -> port [pd2 .didx ] != iih .icmp_id )
pf_change_icmp (pd2 .dst , & iih .icmp_id ,
saddr , & nk -> addr [pd2 .didx ],
nk -> port [pd2 .didx ], NULL ,
pd2 .ip_sum , icmpsum ,
pd -> ip_sum , 0 , AF_INET );
m_copyback (m , off , ICMP_MINLEN , (caddr_t )& pd -> hdr .icmp );
m_copyback (m , ipoff2 , sizeof (h2 ), (caddr_t )& h2 );
m_copyback (m , off2 , ICMP_MINLEN , (caddr_t )iih );
m_copyback (m , off2 , ICMP_MINLEN , (caddr_t )& iih );
}
return (PF_PASS );
break ;
}
#endif /* INET */
#ifdef INET6
case IPPROTO_ICMPV6 : {
struct icmp6_hdr * iih = & pd2 . hdr . icmp6 ;
struct icmp6_hdr iih ;
if (!pf_pull_hdr (m , off2 , iih ,
if (!pf_pull_hdr (m , off2 , & iih ,
sizeof (struct icmp6_hdr ), NULL , reason , pd2 .af )) {
DPFPRINTF (PF_DEBUG_MISC ,
("pf: ICMP error message too short "
"(icmp6)\n" ));
return (PF_DROP );
}
pf_icmp_mapping (& pd2 , iih -> icmp6_type ,
& icmp_dir , & multi , & virtual_id , & virtual_type );
ret = pf_icmp_state_lookup (& key , & pd2 , state , m ,
pd -> dir , kif , virtual_id , virtual_type ,
icmp_dir , & iidx , PF_ICMP_MULTI_NONE , 1 );
if (ret >= 0 ) {
if (ret == PF_DROP && pd -> af == AF_INET6 &&
icmp_dir == PF_OUT ) {
if (* state != NULL )
PF_STATE_UNLOCK ((* state ));
ret = pf_icmp_state_lookup (& key , pd ,
state , m , pd -> dir , kif ,
virtual_id , virtual_type ,
icmp_dir , & iidx , multi , 1 );
if (ret >= 0 )
return (ret );
} else
return (ret );
}
key .af = pd2 .af ;
key .proto = IPPROTO_ICMPV6 ;
PF_ACPY (& key .addr [pd2 .sidx ], pd2 .src , key .af );
PF_ACPY (& key .addr [pd2 .didx ], pd2 .dst , key .af );
key .port [0 ] = key .port [1 ] = iih .icmp6_id ;
STATE_LOOKUP (kif , & key , * state , pd );
/* translate source/destination address, if necessary */
if ((* state )-> key [PF_SK_WIRE ] !=
Expand All
@@ -7214,29 +6963,27 @@ pf_test_state_icmp(struct pf_kstate **state, struct pfi_kkif *kif,
if (PF_ANEQ (pd2 .src ,
& nk -> addr [pd2 .sidx ], pd2 .af ) ||
((virtual_type == htons (ICMP6_ECHO_REQUEST )) &&
nk -> port [pd2 .sidx ] != iih -> icmp6_id ))
pf_change_icmp (pd2 .src ,
(virtual_type == htons (ICMP6_ECHO_REQUEST ))
? & iih -> icmp6_id : NULL ,
nk -> port [pd2 .sidx ] != iih .icmp6_id )
pf_change_icmp (pd2 .src , & iih .icmp6_id ,
daddr , & nk -> addr [pd2 .sidx ],
(virtual_type == htons (ICMP6_ECHO_REQUEST ))
? nk -> port [iidx ] : 0 , NULL ,
nk -> port [pd2 .sidx ], NULL ,
pd2 .ip_sum , icmpsum ,
pd -> ip_sum , 0 , AF_INET6 );
if (PF_ANEQ (pd2 .dst ,
& nk -> addr [pd2 .didx ], pd2 .af ))
pf_change_icmp (pd2 .dst , NULL , NULL ,
& nk -> addr [pd2 .didx ], 0 , NULL ,
& nk -> addr [pd2 .didx ], pd2 .af ) ||
nk -> port [pd2 .didx ] != iih .icmp6_id )
pf_change_icmp (pd2 .dst , & iih .icmp6_id ,
saddr , & nk -> addr [pd2 .didx ],
nk -> port [pd2 .didx ], NULL ,
pd2 .ip_sum , icmpsum ,
pd -> ip_sum , 0 , AF_INET6 );
m_copyback (m , off , sizeof (struct icmp6_hdr ),
(caddr_t )& pd -> hdr .icmp6 );
m_copyback (m , ipoff2 , sizeof (h2_6 ), (caddr_t )& h2_6 );
m_copyback (m , off2 , sizeof (struct icmp6_hdr ),
(caddr_t )iih );
(caddr_t )& iih );
}
return (PF_PASS );
break ;
Expand Down