Changeset View
Changeset View
Standalone View
Standalone View
sys/netpfil/pf/pf.c
Show First 20 Lines • Show All 303 Lines • ▼ Show 20 Lines | |||||
static int pf_tcp_track_sloppy(struct pf_kstate **, | static int pf_tcp_track_sloppy(struct pf_kstate **, | ||||
struct pf_pdesc *, u_short *); | struct pf_pdesc *, u_short *); | ||||
static int pf_test_state_tcp(struct pf_kstate **, int, | static int pf_test_state_tcp(struct pf_kstate **, int, | ||||
struct pfi_kkif *, struct mbuf *, int, | struct pfi_kkif *, struct mbuf *, int, | ||||
void *, struct pf_pdesc *, u_short *); | void *, struct pf_pdesc *, u_short *); | ||||
static int pf_test_state_udp(struct pf_kstate **, int, | static int pf_test_state_udp(struct pf_kstate **, int, | ||||
struct pfi_kkif *, struct mbuf *, int, | struct pfi_kkif *, struct mbuf *, int, | ||||
void *, struct pf_pdesc *); | void *, struct pf_pdesc *); | ||||
static int pf_test_state_sctp(struct pf_kstate **, int, | |||||
struct pfi_kkif *, struct mbuf *, int, | |||||
void *, struct pf_pdesc *, u_short *); | |||||
static int pf_test_state_icmp(struct pf_kstate **, int, | static int pf_test_state_icmp(struct pf_kstate **, int, | ||||
struct pfi_kkif *, struct mbuf *, int, | struct pfi_kkif *, struct mbuf *, int, | ||||
void *, struct pf_pdesc *, u_short *); | void *, struct pf_pdesc *, u_short *); | ||||
static int pf_test_state_other(struct pf_kstate **, int, | static int pf_test_state_other(struct pf_kstate **, int, | ||||
struct pfi_kkif *, struct mbuf *, struct pf_pdesc *); | struct pfi_kkif *, struct mbuf *, struct pf_pdesc *); | ||||
static u_int16_t pf_calc_mss(struct pf_addr *, sa_family_t, | static u_int16_t pf_calc_mss(struct pf_addr *, sa_family_t, | ||||
int, u_int16_t); | int, u_int16_t); | ||||
static int pf_check_proto_cksum(struct mbuf *, int, int, | static int pf_check_proto_cksum(struct mbuf *, int, int, | ||||
▲ Show 20 Lines • Show All 3,910 Lines • ▼ Show 20 Lines | case IPPROTO_TCP: | ||||
dport = th->th_dport; | dport = th->th_dport; | ||||
hdrlen = sizeof(*th); | hdrlen = sizeof(*th); | ||||
break; | break; | ||||
case IPPROTO_UDP: | case IPPROTO_UDP: | ||||
sport = pd->hdr.udp.uh_sport; | sport = pd->hdr.udp.uh_sport; | ||||
dport = pd->hdr.udp.uh_dport; | dport = pd->hdr.udp.uh_dport; | ||||
hdrlen = sizeof(pd->hdr.udp); | hdrlen = sizeof(pd->hdr.udp); | ||||
break; | break; | ||||
case IPPROTO_SCTP: | |||||
sport = pd->hdr.sctp.src_port; | |||||
dport = pd->hdr.sctp.dest_port; | |||||
hdrlen = sizeof(pd->hdr.sctp); | |||||
break; | |||||
#ifdef INET | #ifdef INET | ||||
case IPPROTO_ICMP: | case IPPROTO_ICMP: | ||||
if (pd->af != AF_INET) | if (pd->af != AF_INET) | ||||
break; | break; | ||||
sport = dport = pd->hdr.icmp.icmp_id; | sport = dport = pd->hdr.icmp.icmp_id; | ||||
hdrlen = sizeof(pd->hdr.icmp); | hdrlen = sizeof(pd->hdr.icmp); | ||||
icmptype = pd->hdr.icmp.icmp_type; | icmptype = pd->hdr.icmp.icmp_type; | ||||
icmpcode = pd->hdr.icmp.icmp_code; | icmpcode = pd->hdr.icmp.icmp_code; | ||||
▲ Show 20 Lines • Show All 451 Lines • ▼ Show 20 Lines | case IPPROTO_TCP: | ||||
s->timeout = PFTM_TCP_FIRST_PACKET; | s->timeout = PFTM_TCP_FIRST_PACKET; | ||||
atomic_add_32(&V_pf_status.states_halfopen, 1); | atomic_add_32(&V_pf_status.states_halfopen, 1); | ||||
break; | break; | ||||
case IPPROTO_UDP: | case IPPROTO_UDP: | ||||
pf_set_protostate(s, PF_PEER_SRC, PFUDPS_SINGLE); | pf_set_protostate(s, PF_PEER_SRC, PFUDPS_SINGLE); | ||||
pf_set_protostate(s, PF_PEER_DST, PFUDPS_NO_TRAFFIC); | pf_set_protostate(s, PF_PEER_DST, PFUDPS_NO_TRAFFIC); | ||||
s->timeout = PFTM_UDP_FIRST_PACKET; | s->timeout = PFTM_UDP_FIRST_PACKET; | ||||
break; | break; | ||||
case IPPROTO_SCTP: | |||||
pf_set_protostate(s, PF_PEER_SRC, SCTP_COOKIE_WAIT); | |||||
pf_set_protostate(s, PF_PEER_DST, SCTP_CLOSED); | |||||
s->timeout = PFTM_TCP_FIRST_PACKET; | |||||
break; | |||||
case IPPROTO_ICMP: | case IPPROTO_ICMP: | ||||
#ifdef INET6 | #ifdef INET6 | ||||
case IPPROTO_ICMPV6: | case IPPROTO_ICMPV6: | ||||
#endif | #endif | ||||
s->timeout = PFTM_ICMP_FIRST_PACKET; | s->timeout = PFTM_ICMP_FIRST_PACKET; | ||||
break; | break; | ||||
default: | default: | ||||
pf_set_protostate(s, PF_PEER_SRC, PFOTHERS_SINGLE); | pf_set_protostate(s, PF_PEER_SRC, PFOTHERS_SINGLE); | ||||
▲ Show 20 Lines • Show All 953 Lines • ▼ Show 20 Lines | if (PF_ANEQ(pd->dst, &nk->addr[pd->didx], pd->af) || | ||||
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); | ||||
} | } | ||||
static int | static int | ||||
pf_test_state_sctp(struct pf_kstate **state, int direction, | |||||
struct pfi_kkif *kif, struct mbuf *m, int off, void *h, | |||||
struct pf_pdesc *pd, u_short *reason) | |||||
{ | |||||
struct pf_state_key_cmp key; | |||||
struct pf_state_peer *src; //, *dst; | |||||
struct sctphdr *sh = &pd->hdr.sctp; | |||||
u_int8_t psrc; //, pdst; | |||||
bzero(&key, sizeof(key)); | |||||
key.af = pd->af; | |||||
key.proto = IPPROTO_SCTP; | |||||
if (direction == PF_IN) { /* wire side, straight */ | |||||
PF_ACPY(&key.addr[0], pd->src, key.af); | |||||
PF_ACPY(&key.addr[1], pd->dst, key.af); | |||||
key.port[0] = sh->src_port; | |||||
key.port[1] = sh->dest_port; | |||||
} else { /* stack side, reverse */ | |||||
PF_ACPY(&key.addr[1], pd->src, key.af); | |||||
PF_ACPY(&key.addr[0], pd->dst, key.af); | |||||
key.port[1] = sh->src_port; | |||||
key.port[0] = sh->dest_port; | |||||
} | |||||
STATE_LOOKUP(kif, &key, direction, *state, pd); | |||||
if (pd->dir == (*state)->direction) { | |||||
src = &(*state)->src; | |||||
psrc = PF_PEER_SRC; | |||||
} else { | |||||
src = &(*state)->dst; | |||||
psrc = PF_PEER_DST; | |||||
} | |||||
/* Track state. */ | |||||
if (pd->sctp_flags & PFDESC_SCTP_INIT) { | |||||
if (src->state < SCTP_COOKIE_WAIT) { | |||||
pf_set_protostate(*state, psrc, SCTP_COOKIE_WAIT); | |||||
(*state)->timeout = PFTM_TCP_OPENING; | |||||
} | |||||
} | |||||
if (pd->sctp_flags & PFDESC_SCTP_COOKIE) { | |||||
if (src->state < SCTP_ESTABLISHED) { | |||||
pf_set_protostate(*state, psrc, SCTP_ESTABLISHED); | |||||
(*state)->timeout = PFTM_TCP_ESTABLISHED; | |||||
} | |||||
} | |||||
if (pd->sctp_flags & (PFDESC_SCTP_SHUTDOWN | PFDESC_SCTP_ABORT)) { | |||||
if (src->state < SCTP_SHUTDOWN_PENDING) { | |||||
pf_set_protostate(*state, psrc, SCTP_SHUTDOWN_PENDING); | |||||
(*state)->timeout = PFTM_TCP_CLOSING; | |||||
} | |||||
} | |||||
(*state)->expire = time_uptime; | |||||
return (PF_PASS); | |||||
} | |||||
static int | |||||
pf_test_state_icmp(struct pf_kstate **state, int direction, struct pfi_kkif *kif, | pf_test_state_icmp(struct pf_kstate **state, int direction, struct pfi_kkif *kif, | ||||
struct mbuf *m, int off, void *h, struct pf_pdesc *pd, u_short *reason) | struct mbuf *m, int off, void *h, struct pf_pdesc *pd, u_short *reason) | ||||
{ | { | ||||
struct pf_addr *saddr = pd->src, *daddr = pd->dst; | struct pf_addr *saddr = pd->src, *daddr = pd->dst; | ||||
u_int16_t icmpid = 0, *icmpsum; | u_int16_t icmpid = 0, *icmpsum; | ||||
u_int8_t icmptype, icmpcode; | u_int8_t icmptype, icmpcode; | ||||
int state_icmp = 0; | int state_icmp = 0; | ||||
struct pf_state_key_cmp key; | struct pf_state_key_cmp key; | ||||
▲ Show 20 Lines • Show All 1,706 Lines • ▼ Show 20 Lines | if (action == PF_PASS) { | ||||
a = s->anchor.ptr; | a = s->anchor.ptr; | ||||
log = s->log; | log = s->log; | ||||
} else if (s == NULL) | } else if (s == NULL) | ||||
action = pf_test_rule(&r, &s, dir, kif, m, off, &pd, | action = pf_test_rule(&r, &s, dir, kif, m, off, &pd, | ||||
&a, &ruleset, inp); | &a, &ruleset, inp); | ||||
break; | break; | ||||
} | } | ||||
case IPPROTO_SCTP: { | |||||
if (!pf_pull_hdr(m, off, &pd.hdr.sctp, sizeof(pd.hdr.sctp), | |||||
&action, &reason, AF_INET)) { | |||||
if (action != PF_PASS) | |||||
log = PF_LOG_FORCE; | |||||
goto done; | |||||
} | |||||
pd.sport = &pd.hdr.sctp.src_port; | |||||
pd.dport = &pd.hdr.sctp.dest_port; | |||||
if (pd.hdr.sctp.src_port == 0 || pd.hdr.sctp.dest_port == 0) { | |||||
action = PF_DROP; | |||||
REASON_SET(&reason, PFRES_SHORT); | |||||
goto done; | |||||
} | |||||
action = pf_normalize_sctp(dir, kif, m, 0, off, h, &pd); | |||||
if (action == PF_DROP) | |||||
goto done; | |||||
action = pf_test_state_sctp(&s, dir, kif, m, off, h, &pd, | |||||
&reason); | |||||
if (action == PF_PASS) { | |||||
if (V_pfsync_update_state_ptr != NULL) | |||||
V_pfsync_update_state_ptr(s); | |||||
r = s->rule.ptr; | |||||
a = s->anchor.ptr; | |||||
log = s->log; | |||||
} else { | |||||
action = pf_test_rule(&r, &s, dir, kif, m, off, | |||||
&pd, &a, &ruleset, inp); | |||||
} | |||||
break; | |||||
} | |||||
case IPPROTO_ICMP: { | case IPPROTO_ICMP: { | ||||
if (!pf_pull_hdr(m, off, &pd.hdr.icmp, ICMP_MINLEN, | if (!pf_pull_hdr(m, off, &pd.hdr.icmp, ICMP_MINLEN, | ||||
&action, &reason, AF_INET)) { | &action, &reason, AF_INET)) { | ||||
if (action != PF_PASS) | if (action != PF_PASS) | ||||
log = PF_LOG_FORCE; | log = PF_LOG_FORCE; | ||||
goto done; | goto done; | ||||
} | } | ||||
action = pf_test_state_icmp(&s, dir, kif, m, off, h, &pd, | action = pf_test_state_icmp(&s, dir, kif, m, off, h, &pd, | ||||
▲ Show 20 Lines • Show All 539 Lines • ▼ Show 20 Lines | if (action == PF_PASS) { | ||||
if (V_pfsync_update_state_ptr != NULL) | if (V_pfsync_update_state_ptr != NULL) | ||||
V_pfsync_update_state_ptr(s); | V_pfsync_update_state_ptr(s); | ||||
r = s->rule.ptr; | r = s->rule.ptr; | ||||
a = s->anchor.ptr; | a = s->anchor.ptr; | ||||
log = s->log; | log = s->log; | ||||
} else if (s == NULL) | } else if (s == NULL) | ||||
action = pf_test_rule(&r, &s, dir, kif, m, off, &pd, | action = pf_test_rule(&r, &s, dir, kif, m, off, &pd, | ||||
&a, &ruleset, inp); | &a, &ruleset, inp); | ||||
break; | |||||
} | |||||
case IPPROTO_SCTP: { | |||||
if (!pf_pull_hdr(m, off, &pd.hdr.sctp, sizeof(pd.hdr.sctp), | |||||
&action, &reason, AF_INET6)) { | |||||
if (action != PF_PASS) | |||||
log = PF_LOG_FORCE; | |||||
goto done; | |||||
} | |||||
pd.sport = &pd.hdr.sctp.src_port; | |||||
pd.dport = &pd.hdr.sctp.dest_port; | |||||
if (pd.hdr.sctp.src_port == 0 || pd.hdr.sctp.dest_port == 0) { | |||||
action = PF_DROP; | |||||
REASON_SET(&reason, PFRES_SHORT); | |||||
goto done; | |||||
} | |||||
action = pf_normalize_sctp(dir, kif, m, 0, off, h, &pd); | |||||
if (action == PF_DROP) | |||||
goto done; | |||||
action = pf_test_state_sctp(&s, dir, kif, m, off, h, &pd, | |||||
&reason); | |||||
if (action == PF_PASS) { | |||||
if (V_pfsync_update_state_ptr != NULL) | |||||
V_pfsync_update_state_ptr(s); | |||||
r = s->rule.ptr; | |||||
a = s->anchor.ptr; | |||||
log = s->log; | |||||
} else { | |||||
action = pf_test_rule(&r, &s, dir, kif, m, off, | |||||
&pd, &a, &ruleset, inp); | |||||
} | |||||
break; | break; | ||||
} | } | ||||
case IPPROTO_ICMP: { | case IPPROTO_ICMP: { | ||||
action = PF_DROP; | action = PF_DROP; | ||||
DPFPRINTF(PF_DEBUG_MISC, | DPFPRINTF(PF_DEBUG_MISC, | ||||
("pf: dropping IPv6 packet with ICMPv4 payload\n")); | ("pf: dropping IPv6 packet with ICMPv4 payload\n")); | ||||
goto done; | goto done; | ||||
▲ Show 20 Lines • Show All 253 Lines • Show Last 20 Lines |