Changeset View
Changeset View
Standalone View
Standalone View
head/sys/netpfil/pf/pf.c
Show First 20 Lines • Show All 196 Lines • ▼ Show 20 Lines | |||||
CTASSERT((1 << PFID_CPUBITS) >= MAXCPU); | CTASSERT((1 << PFID_CPUBITS) >= MAXCPU); | ||||
static void pf_src_tree_remove_state(struct pf_state *); | static void pf_src_tree_remove_state(struct pf_state *); | ||||
static void pf_init_threshold(struct pf_threshold *, u_int32_t, | static void pf_init_threshold(struct pf_threshold *, u_int32_t, | ||||
u_int32_t); | u_int32_t); | ||||
static void pf_add_threshold(struct pf_threshold *); | static void pf_add_threshold(struct pf_threshold *); | ||||
static int pf_check_threshold(struct pf_threshold *); | static int pf_check_threshold(struct pf_threshold *); | ||||
static void pf_change_ap(struct pf_addr *, u_int16_t *, | static void pf_change_ap(struct mbuf *, struct pf_addr *, u_int16_t *, | ||||
u_int16_t *, u_int16_t *, struct pf_addr *, | u_int16_t *, u_int16_t *, struct pf_addr *, | ||||
u_int16_t, u_int8_t, sa_family_t); | u_int16_t, u_int8_t, sa_family_t); | ||||
static int pf_modulate_sack(struct mbuf *, int, struct pf_pdesc *, | static int pf_modulate_sack(struct mbuf *, int, struct pf_pdesc *, | ||||
struct tcphdr *, struct pf_state_peer *); | struct tcphdr *, struct pf_state_peer *); | ||||
static void pf_change_icmp(struct pf_addr *, u_int16_t *, | static void pf_change_icmp(struct pf_addr *, u_int16_t *, | ||||
struct pf_addr *, struct pf_addr *, u_int16_t, | struct pf_addr *, struct pf_addr *, u_int16_t, | ||||
u_int16_t *, u_int16_t *, u_int16_t *, | u_int16_t *, u_int16_t *, u_int16_t *, | ||||
u_int16_t *, u_int8_t, sa_family_t); | u_int16_t *, u_int8_t, sa_family_t); | ||||
▲ Show 20 Lines • Show All 1,772 Lines • ▼ Show 20 Lines | pf_addr_wrap_neq(struct pf_addr_wrap *aw1, struct pf_addr_wrap *aw2) | ||||
case PF_ADDR_TABLE: | case PF_ADDR_TABLE: | ||||
return (aw1->p.tbl != aw2->p.tbl); | return (aw1->p.tbl != aw2->p.tbl); | ||||
default: | default: | ||||
printf("invalid address type: %d\n", aw1->type); | printf("invalid address type: %d\n", aw1->type); | ||||
return (1); | return (1); | ||||
} | } | ||||
} | } | ||||
/** | |||||
* Checksum updates are a little complicated because the checksum in the TCP/UDP | |||||
* header isn't always a full checksum. In some cases (i.e. output) it's a | |||||
* pseudo-header checksum, which is a partial checksum over src/dst IP | |||||
* addresses, protocol number and length. | |||||
* | |||||
* That means we have the following cases: | |||||
* * Input or forwarding: we don't have TSO, the checksum fields are full | |||||
* checksums, we need to update the checksum whenever we change anything. | |||||
* * Output (i.e. the checksum is a pseudo-header checksum): | |||||
* x The field being updated is src/dst address or affects the length of | |||||
* the packet. We need to update the pseudo-header checksum (note that this | |||||
* checksum is not ones' complement). | |||||
* x Some other field is being modified (e.g. src/dst port numbers): We | |||||
* don't have to update anything. | |||||
**/ | |||||
u_int16_t | u_int16_t | ||||
pf_cksum_fixup(u_int16_t cksum, u_int16_t old, u_int16_t new, u_int8_t udp) | pf_cksum_fixup(u_int16_t cksum, u_int16_t old, u_int16_t new, u_int8_t udp) | ||||
{ | { | ||||
u_int32_t l; | u_int32_t l; | ||||
if (udp && !cksum) | if (udp && !cksum) | ||||
return (0x0000); | return (0x0000); | ||||
l = cksum + old - new; | l = cksum + old - new; | ||||
l = (l >> 16) + (l & 65535); | l = (l >> 16) + (l & 65535); | ||||
l = l & 65535; | l = l & 65535; | ||||
if (udp && !l) | if (udp && !l) | ||||
return (0xFFFF); | return (0xFFFF); | ||||
return (l); | return (l); | ||||
} | } | ||||
u_int16_t | |||||
pf_proto_cksum_fixup(struct mbuf *m, u_int16_t cksum, u_int16_t old, | |||||
u_int16_t new, u_int8_t udp) | |||||
{ | |||||
if (m->m_pkthdr.csum_flags & (CSUM_DELAY_DATA | CSUM_DELAY_DATA_IPV6)) | |||||
return (cksum); | |||||
return (pf_cksum_fixup(cksum, old, new, udp)); | |||||
} | |||||
static void | static void | ||||
pf_change_ap(struct pf_addr *a, u_int16_t *p, u_int16_t *ic, u_int16_t *pc, | pf_change_ap(struct mbuf *m, struct pf_addr *a, u_int16_t *p, u_int16_t *ic, | ||||
struct pf_addr *an, u_int16_t pn, u_int8_t u, sa_family_t af) | u_int16_t *pc, struct pf_addr *an, u_int16_t pn, u_int8_t u, | ||||
sa_family_t af) | |||||
{ | { | ||||
struct pf_addr ao; | struct pf_addr ao; | ||||
u_int16_t po = *p; | u_int16_t po = *p; | ||||
PF_ACPY(&ao, a, af); | PF_ACPY(&ao, a, af); | ||||
PF_ACPY(a, an, af); | PF_ACPY(a, an, af); | ||||
if (m->m_pkthdr.csum_flags & (CSUM_DELAY_DATA | CSUM_DELAY_DATA_IPV6)) | |||||
*pc = ~*pc; | |||||
*p = pn; | *p = pn; | ||||
switch (af) { | switch (af) { | ||||
#ifdef INET | #ifdef INET | ||||
case AF_INET: | case AF_INET: | ||||
*ic = pf_cksum_fixup(pf_cksum_fixup(*ic, | *ic = pf_cksum_fixup(pf_cksum_fixup(*ic, | ||||
ao.addr16[0], an->addr16[0], 0), | ao.addr16[0], an->addr16[0], 0), | ||||
ao.addr16[1], an->addr16[1], 0); | ao.addr16[1], an->addr16[1], 0); | ||||
*p = pn; | *p = pn; | ||||
*pc = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(*pc, | |||||
*pc = pf_cksum_fixup(pf_cksum_fixup(*pc, | |||||
ao.addr16[0], an->addr16[0], u), | ao.addr16[0], an->addr16[0], u), | ||||
ao.addr16[1], an->addr16[1], u), | ao.addr16[1], an->addr16[1], u); | ||||
po, pn, u); | |||||
*pc = pf_proto_cksum_fixup(m, *pc, po, pn, u); | |||||
break; | break; | ||||
#endif /* INET */ | #endif /* INET */ | ||||
#ifdef INET6 | #ifdef INET6 | ||||
case AF_INET6: | case AF_INET6: | ||||
*pc = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup( | *pc = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup( | ||||
pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup( | pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup( | ||||
pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(*pc, | pf_cksum_fixup(pf_cksum_fixup(*pc, | ||||
ao.addr16[0], an->addr16[0], u), | ao.addr16[0], an->addr16[0], u), | ||||
ao.addr16[1], an->addr16[1], u), | ao.addr16[1], an->addr16[1], u), | ||||
ao.addr16[2], an->addr16[2], u), | ao.addr16[2], an->addr16[2], u), | ||||
ao.addr16[3], an->addr16[3], u), | ao.addr16[3], an->addr16[3], u), | ||||
ao.addr16[4], an->addr16[4], u), | ao.addr16[4], an->addr16[4], u), | ||||
ao.addr16[5], an->addr16[5], u), | ao.addr16[5], an->addr16[5], u), | ||||
ao.addr16[6], an->addr16[6], u), | ao.addr16[6], an->addr16[6], u), | ||||
ao.addr16[7], an->addr16[7], u), | ao.addr16[7], an->addr16[7], u); | ||||
po, pn, u); | |||||
*pc = pf_proto_cksum_fixup(m, *pc, po, pn, u); | |||||
break; | break; | ||||
#endif /* INET6 */ | #endif /* INET6 */ | ||||
} | } | ||||
if (m->m_pkthdr.csum_flags & (CSUM_DELAY_DATA | | |||||
CSUM_DELAY_DATA_IPV6)) { | |||||
*pc = ~*pc; | |||||
if (! *pc) | |||||
*pc = 0xffff; | |||||
} | } | ||||
} | |||||
/* Changes a u_int32_t. Uses a void * so there are no align restrictions */ | /* Changes a u_int32_t. Uses a void * so there are no align restrictions */ | ||||
void | void | ||||
pf_change_a(void *a, u_int16_t *c, u_int32_t an, u_int8_t u) | pf_change_a(void *a, u_int16_t *c, u_int32_t an, u_int8_t u) | ||||
{ | { | ||||
u_int32_t ao; | u_int32_t ao; | ||||
memcpy(&ao, a, sizeof(ao)); | memcpy(&ao, a, sizeof(ao)); | ||||
memcpy(a, &an, sizeof(u_int32_t)); | memcpy(a, &an, sizeof(u_int32_t)); | ||||
*c = pf_cksum_fixup(pf_cksum_fixup(*c, ao / 65536, an / 65536, u), | *c = pf_cksum_fixup(pf_cksum_fixup(*c, ao / 65536, an / 65536, u), | ||||
ao % 65536, an % 65536, u); | ao % 65536, an % 65536, u); | ||||
} | } | ||||
void | |||||
pf_change_proto_a(struct mbuf *m, void *a, u_int16_t *c, u_int32_t an, u_int8_t udp) | |||||
{ | |||||
u_int32_t ao; | |||||
memcpy(&ao, a, sizeof(ao)); | |||||
memcpy(a, &an, sizeof(u_int32_t)); | |||||
*c = pf_proto_cksum_fixup(m, | |||||
pf_proto_cksum_fixup(m, *c, ao / 65536, an / 65536, udp), | |||||
ao % 65536, an % 65536, udp); | |||||
} | |||||
#ifdef INET6 | #ifdef INET6 | ||||
static void | static void | ||||
pf_change_a6(struct pf_addr *a, u_int16_t *c, struct pf_addr *an, u_int8_t u) | pf_change_a6(struct pf_addr *a, u_int16_t *c, struct pf_addr *an, u_int8_t u) | ||||
{ | { | ||||
struct pf_addr ao; | struct pf_addr ao; | ||||
PF_ACPY(&ao, a, AF_INET6); | PF_ACPY(&ao, a, AF_INET6); | ||||
PF_ACPY(a, an, AF_INET6); | PF_ACPY(a, an, AF_INET6); | ||||
▲ Show 20 Lines • Show All 129 Lines • ▼ Show 20 Lines | case TCPOPT_NOP: | ||||
break; | break; | ||||
case TCPOPT_SACK: | case TCPOPT_SACK: | ||||
if (olen > hlen) | if (olen > hlen) | ||||
olen = hlen; | olen = hlen; | ||||
if (olen >= TCPOLEN_SACKLEN) { | if (olen >= TCPOLEN_SACKLEN) { | ||||
for (i = 2; i + TCPOLEN_SACK <= olen; | for (i = 2; i + TCPOLEN_SACK <= olen; | ||||
i += TCPOLEN_SACK) { | i += TCPOLEN_SACK) { | ||||
memcpy(&sack, &opt[i], sizeof(sack)); | memcpy(&sack, &opt[i], sizeof(sack)); | ||||
pf_change_a(&sack.start, &th->th_sum, | pf_change_proto_a(m, &sack.start, &th->th_sum, | ||||
htonl(ntohl(sack.start) - | htonl(ntohl(sack.start) - dst->seqdiff), 0); | ||||
dst->seqdiff), 0); | pf_change_proto_a(m, &sack.end, &th->th_sum, | ||||
pf_change_a(&sack.end, &th->th_sum, | htonl(ntohl(sack.end) - dst->seqdiff), 0); | ||||
htonl(ntohl(sack.end) - | |||||
dst->seqdiff), 0); | |||||
memcpy(&opt[i], &sack, sizeof(sack)); | memcpy(&opt[i], &sack, sizeof(sack)); | ||||
} | } | ||||
copyback = 1; | copyback = 1; | ||||
} | } | ||||
/* FALLTHROUGH */ | /* FALLTHROUGH */ | ||||
default: | default: | ||||
if (olen < 2) | if (olen < 2) | ||||
olen = 2; | olen = 2; | ||||
▲ Show 20 Lines • Show All 887 Lines • ▼ Show 20 Lines | if ((nr = pf_get_translation(pd, m, off, direction, kif, &nsn, &sk, | ||||
switch (pd->proto) { | switch (pd->proto) { | ||||
case IPPROTO_TCP: | case IPPROTO_TCP: | ||||
bproto_sum = th->th_sum; | bproto_sum = th->th_sum; | ||||
pd->proto_sum = &th->th_sum; | pd->proto_sum = &th->th_sum; | ||||
if (PF_ANEQ(saddr, &nk->addr[pd->sidx], af) || | if (PF_ANEQ(saddr, &nk->addr[pd->sidx], af) || | ||||
nk->port[pd->sidx] != sport) { | nk->port[pd->sidx] != sport) { | ||||
pf_change_ap(saddr, &th->th_sport, pd->ip_sum, | pf_change_ap(m, saddr, &th->th_sport, pd->ip_sum, | ||||
&th->th_sum, &nk->addr[pd->sidx], | &th->th_sum, &nk->addr[pd->sidx], | ||||
nk->port[pd->sidx], 0, af); | nk->port[pd->sidx], 0, af); | ||||
pd->sport = &th->th_sport; | pd->sport = &th->th_sport; | ||||
sport = th->th_sport; | sport = th->th_sport; | ||||
} | } | ||||
if (PF_ANEQ(daddr, &nk->addr[pd->didx], af) || | if (PF_ANEQ(daddr, &nk->addr[pd->didx], af) || | ||||
nk->port[pd->didx] != dport) { | nk->port[pd->didx] != dport) { | ||||
pf_change_ap(daddr, &th->th_dport, pd->ip_sum, | pf_change_ap(m, daddr, &th->th_dport, pd->ip_sum, | ||||
&th->th_sum, &nk->addr[pd->didx], | &th->th_sum, &nk->addr[pd->didx], | ||||
nk->port[pd->didx], 0, af); | nk->port[pd->didx], 0, af); | ||||
dport = th->th_dport; | dport = th->th_dport; | ||||
pd->dport = &th->th_dport; | pd->dport = &th->th_dport; | ||||
} | } | ||||
rewrite++; | rewrite++; | ||||
break; | break; | ||||
case IPPROTO_UDP: | case IPPROTO_UDP: | ||||
bproto_sum = pd->hdr.udp->uh_sum; | bproto_sum = pd->hdr.udp->uh_sum; | ||||
pd->proto_sum = &pd->hdr.udp->uh_sum; | pd->proto_sum = &pd->hdr.udp->uh_sum; | ||||
if (PF_ANEQ(saddr, &nk->addr[pd->sidx], af) || | if (PF_ANEQ(saddr, &nk->addr[pd->sidx], af) || | ||||
nk->port[pd->sidx] != sport) { | nk->port[pd->sidx] != sport) { | ||||
pf_change_ap(saddr, &pd->hdr.udp->uh_sport, | pf_change_ap(m, saddr, &pd->hdr.udp->uh_sport, | ||||
pd->ip_sum, &pd->hdr.udp->uh_sum, | pd->ip_sum, &pd->hdr.udp->uh_sum, | ||||
&nk->addr[pd->sidx], | &nk->addr[pd->sidx], | ||||
nk->port[pd->sidx], 1, af); | nk->port[pd->sidx], 1, af); | ||||
sport = pd->hdr.udp->uh_sport; | sport = pd->hdr.udp->uh_sport; | ||||
pd->sport = &pd->hdr.udp->uh_sport; | pd->sport = &pd->hdr.udp->uh_sport; | ||||
} | } | ||||
if (PF_ANEQ(daddr, &nk->addr[pd->didx], af) || | if (PF_ANEQ(daddr, &nk->addr[pd->didx], af) || | ||||
nk->port[pd->didx] != dport) { | nk->port[pd->didx] != dport) { | ||||
pf_change_ap(daddr, &pd->hdr.udp->uh_dport, | pf_change_ap(m, daddr, &pd->hdr.udp->uh_dport, | ||||
pd->ip_sum, &pd->hdr.udp->uh_sum, | pd->ip_sum, &pd->hdr.udp->uh_sum, | ||||
&nk->addr[pd->didx], | &nk->addr[pd->didx], | ||||
nk->port[pd->didx], 1, af); | nk->port[pd->didx], 1, af); | ||||
dport = pd->hdr.udp->uh_dport; | dport = pd->hdr.udp->uh_dport; | ||||
pd->dport = &pd->hdr.udp->uh_dport; | pd->dport = &pd->hdr.udp->uh_dport; | ||||
} | } | ||||
rewrite++; | rewrite++; | ||||
break; | break; | ||||
▲ Show 20 Lines • Show All 335 Lines • ▼ Show 20 Lines | case IPPROTO_TCP: | ||||
s->src.seqlo = ntohl(th->th_seq); | s->src.seqlo = ntohl(th->th_seq); | ||||
s->src.seqhi = s->src.seqlo + pd->p_len + 1; | s->src.seqhi = s->src.seqlo + pd->p_len + 1; | ||||
if ((th->th_flags & (TH_SYN|TH_ACK)) == TH_SYN && | if ((th->th_flags & (TH_SYN|TH_ACK)) == TH_SYN && | ||||
r->keep_state == PF_STATE_MODULATE) { | r->keep_state == PF_STATE_MODULATE) { | ||||
/* Generate sequence number modulator */ | /* Generate sequence number modulator */ | ||||
if ((s->src.seqdiff = pf_tcp_iss(pd) - s->src.seqlo) == | if ((s->src.seqdiff = pf_tcp_iss(pd) - s->src.seqlo) == | ||||
0) | 0) | ||||
s->src.seqdiff = 1; | s->src.seqdiff = 1; | ||||
pf_change_a(&th->th_seq, &th->th_sum, | pf_change_proto_a(m, &th->th_seq, &th->th_sum, | ||||
htonl(s->src.seqlo + s->src.seqdiff), 0); | htonl(s->src.seqlo + s->src.seqdiff), 0); | ||||
*rewrite = 1; | *rewrite = 1; | ||||
} else | } else | ||||
s->src.seqdiff = 0; | s->src.seqdiff = 0; | ||||
if (th->th_flags & TH_SYN) { | if (th->th_flags & TH_SYN) { | ||||
s->src.seqhi++; | s->src.seqhi++; | ||||
s->src.wscale = pf_get_wscale(m, off, | s->src.wscale = pf_get_wscale(m, off, | ||||
th->th_off, pd->af); | th->th_off, pd->af); | ||||
▲ Show 20 Lines • Show All 307 Lines • ▼ Show 20 Lines | if (src->seqlo == 0) { | ||||
} | } | ||||
/* Deferred generation of sequence number modulator */ | /* Deferred generation of sequence number modulator */ | ||||
if (dst->seqdiff && !src->seqdiff) { | if (dst->seqdiff && !src->seqdiff) { | ||||
/* use random iss for the TCP server */ | /* use random iss for the TCP server */ | ||||
while ((src->seqdiff = arc4random() - seq) == 0) | while ((src->seqdiff = arc4random() - seq) == 0) | ||||
; | ; | ||||
ack = ntohl(th->th_ack) - dst->seqdiff; | ack = ntohl(th->th_ack) - dst->seqdiff; | ||||
pf_change_a(&th->th_seq, &th->th_sum, htonl(seq + | pf_change_proto_a(m, &th->th_seq, &th->th_sum, htonl(seq + | ||||
src->seqdiff), 0); | src->seqdiff), 0); | ||||
pf_change_a(&th->th_ack, &th->th_sum, htonl(ack), 0); | pf_change_proto_a(m, &th->th_ack, &th->th_sum, htonl(ack), 0); | ||||
*copyback = 1; | *copyback = 1; | ||||
} else { | } else { | ||||
ack = ntohl(th->th_ack); | ack = ntohl(th->th_ack); | ||||
} | } | ||||
end = seq + pd->p_len; | end = seq + pd->p_len; | ||||
if (th->th_flags & TH_SYN) { | if (th->th_flags & TH_SYN) { | ||||
end++; | end++; | ||||
Show All 33 Lines | if (src->seqhi == 1 || | ||||
src->seqhi = end + MAX(1, dst->max_win << dws); | src->seqhi = end + MAX(1, dst->max_win << dws); | ||||
if (win > src->max_win) | if (win > src->max_win) | ||||
src->max_win = win; | src->max_win = win; | ||||
} else { | } else { | ||||
ack = ntohl(th->th_ack) - dst->seqdiff; | ack = ntohl(th->th_ack) - dst->seqdiff; | ||||
if (src->seqdiff) { | if (src->seqdiff) { | ||||
/* Modulate sequence numbers */ | /* Modulate sequence numbers */ | ||||
pf_change_a(&th->th_seq, &th->th_sum, htonl(seq + | pf_change_proto_a(m, &th->th_seq, &th->th_sum, htonl(seq + | ||||
src->seqdiff), 0); | src->seqdiff), 0); | ||||
pf_change_a(&th->th_ack, &th->th_sum, htonl(ack), 0); | pf_change_proto_a(m, &th->th_ack, &th->th_sum, htonl(ack), 0); | ||||
*copyback = 1; | *copyback = 1; | ||||
} | } | ||||
end = seq + pd->p_len; | end = seq + pd->p_len; | ||||
if (th->th_flags & TH_SYN) | if (th->th_flags & TH_SYN) | ||||
end++; | end++; | ||||
if (th->th_flags & TH_FIN) | if (th->th_flags & TH_FIN) | ||||
end++; | end++; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 437 Lines • ▼ Show 20 Lines | pf_test_state_tcp(struct pf_state **state, int direction, struct pfi_kif *kif, | ||||
} | } | ||||
/* translate source/destination address, if necessary */ | /* translate source/destination address, if necessary */ | ||||
if ((*state)->key[PF_SK_WIRE] != (*state)->key[PF_SK_STACK]) { | if ((*state)->key[PF_SK_WIRE] != (*state)->key[PF_SK_STACK]) { | ||||
struct pf_state_key *nk = (*state)->key[pd->didx]; | struct pf_state_key *nk = (*state)->key[pd->didx]; | ||||
if (PF_ANEQ(pd->src, &nk->addr[pd->sidx], pd->af) || | if (PF_ANEQ(pd->src, &nk->addr[pd->sidx], pd->af) || | ||||
nk->port[pd->sidx] != th->th_sport) | nk->port[pd->sidx] != th->th_sport) | ||||
pf_change_ap(pd->src, &th->th_sport, pd->ip_sum, | pf_change_ap(m, pd->src, &th->th_sport, | ||||
&th->th_sum, &nk->addr[pd->sidx], | pd->ip_sum, &th->th_sum, &nk->addr[pd->sidx], | ||||
nk->port[pd->sidx], 0, pd->af); | nk->port[pd->sidx], 0, pd->af); | ||||
if (PF_ANEQ(pd->dst, &nk->addr[pd->didx], pd->af) || | if (PF_ANEQ(pd->dst, &nk->addr[pd->didx], pd->af) || | ||||
nk->port[pd->didx] != th->th_dport) | nk->port[pd->didx] != th->th_dport) | ||||
pf_change_ap(pd->dst, &th->th_dport, pd->ip_sum, | pf_change_ap(m, pd->dst, &th->th_dport, | ||||
&th->th_sum, &nk->addr[pd->didx], | pd->ip_sum, &th->th_sum, &nk->addr[pd->didx], | ||||
nk->port[pd->didx], 0, pd->af); | nk->port[pd->didx], 0, pd->af); | ||||
copyback = 1; | copyback = 1; | ||||
} | } | ||||
/* Copyback sequence modulation or stateful scrub changes if needed */ | /* Copyback sequence modulation or stateful scrub changes if needed */ | ||||
if (copyback) | if (copyback) | ||||
m_copyback(m, off, sizeof(*th), (caddr_t)th); | m_copyback(m, off, sizeof(*th), (caddr_t)th); | ||||
▲ Show 20 Lines • Show All 47 Lines • ▼ Show 20 Lines | else | ||||
(*state)->timeout = PFTM_UDP_SINGLE; | (*state)->timeout = PFTM_UDP_SINGLE; | ||||
/* translate source/destination address, if necessary */ | /* translate source/destination address, if necessary */ | ||||
if ((*state)->key[PF_SK_WIRE] != (*state)->key[PF_SK_STACK]) { | if ((*state)->key[PF_SK_WIRE] != (*state)->key[PF_SK_STACK]) { | ||||
struct pf_state_key *nk = (*state)->key[pd->didx]; | struct pf_state_key *nk = (*state)->key[pd->didx]; | ||||
if (PF_ANEQ(pd->src, &nk->addr[pd->sidx], pd->af) || | if (PF_ANEQ(pd->src, &nk->addr[pd->sidx], pd->af) || | ||||
nk->port[pd->sidx] != uh->uh_sport) | nk->port[pd->sidx] != uh->uh_sport) | ||||
pf_change_ap(pd->src, &uh->uh_sport, pd->ip_sum, | pf_change_ap(m, pd->src, &uh->uh_sport, pd->ip_sum, | ||||
&uh->uh_sum, &nk->addr[pd->sidx], | &uh->uh_sum, &nk->addr[pd->sidx], | ||||
nk->port[pd->sidx], 1, pd->af); | nk->port[pd->sidx], 1, pd->af); | ||||
if (PF_ANEQ(pd->dst, &nk->addr[pd->didx], pd->af) || | if (PF_ANEQ(pd->dst, &nk->addr[pd->didx], pd->af) || | ||||
nk->port[pd->didx] != uh->uh_dport) | nk->port[pd->didx] != uh->uh_dport) | ||||
pf_change_ap(pd->dst, &uh->uh_dport, pd->ip_sum, | pf_change_ap(m, pd->dst, &uh->uh_dport, pd->ip_sum, | ||||
&uh->uh_sum, &nk->addr[pd->didx], | &uh->uh_sum, &nk->addr[pd->didx], | ||||
nk->port[pd->didx], 1, pd->af); | nk->port[pd->didx], 1, pd->af); | ||||
m_copyback(m, off, sizeof(*uh), (caddr_t)uh); | m_copyback(m, off, sizeof(*uh), (caddr_t)uh); | ||||
} | } | ||||
return (PF_PASS); | return (PF_PASS); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 2,050 Lines • Show Last 20 Lines |