Changeset View
Changeset View
Standalone View
Standalone View
head/sys/netpfil/pf/pf_norm.c
Show First 20 Lines • Show All 1,133 Lines • ▼ Show 20 Lines | |||||
{ | { | ||||
struct mbuf *m = *m0; | struct mbuf *m = *m0; | ||||
struct pf_rule *r; | struct pf_rule *r; | ||||
struct ip6_hdr *h = mtod(m, struct ip6_hdr *); | struct ip6_hdr *h = mtod(m, struct ip6_hdr *); | ||||
int extoff; | int extoff; | ||||
int off; | int off; | ||||
struct ip6_ext ext; | struct ip6_ext ext; | ||||
struct ip6_opt opt; | struct ip6_opt opt; | ||||
struct ip6_opt_jumbo jumbo; | |||||
struct ip6_frag frag; | struct ip6_frag frag; | ||||
u_int32_t jumbolen = 0, plen; | u_int32_t plen; | ||||
int optend; | int optend; | ||||
int ooff; | int ooff; | ||||
u_int8_t proto; | u_int8_t proto; | ||||
int terminal; | int terminal; | ||||
PF_RULES_RASSERT(); | PF_RULES_RASSERT(); | ||||
r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_SCRUB].active.ptr); | r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_SCRUB].active.ptr); | ||||
Show All 27 Lines | else { | ||||
r->packets[dir == PF_OUT]++; | r->packets[dir == PF_OUT]++; | ||||
r->bytes[dir == PF_OUT] += pd->tot_len; | r->bytes[dir == PF_OUT] += pd->tot_len; | ||||
} | } | ||||
/* Check for illegal packets */ | /* Check for illegal packets */ | ||||
if (sizeof(struct ip6_hdr) + IPV6_MAXPACKET < m->m_pkthdr.len) | if (sizeof(struct ip6_hdr) + IPV6_MAXPACKET < m->m_pkthdr.len) | ||||
goto drop; | goto drop; | ||||
plen = ntohs(h->ip6_plen); | |||||
/* jumbo payload option not supported */ | |||||
if (plen == 0) | |||||
goto drop; | |||||
extoff = 0; | extoff = 0; | ||||
off = sizeof(struct ip6_hdr); | off = sizeof(struct ip6_hdr); | ||||
proto = h->ip6_nxt; | proto = h->ip6_nxt; | ||||
terminal = 0; | terminal = 0; | ||||
do { | do { | ||||
switch (proto) { | switch (proto) { | ||||
case IPPROTO_FRAGMENT: | case IPPROTO_FRAGMENT: | ||||
goto fragment; | goto fragment; | ||||
Show All 27 Lines | case IPPROTO_HOPOPTS: | ||||
ooff++; | ooff++; | ||||
continue; | continue; | ||||
} | } | ||||
if (!pf_pull_hdr(m, ooff, &opt, sizeof(opt), | if (!pf_pull_hdr(m, ooff, &opt, sizeof(opt), | ||||
NULL, NULL, AF_INET6)) | NULL, NULL, AF_INET6)) | ||||
goto shortpkt; | goto shortpkt; | ||||
if (ooff + sizeof(opt) + opt.ip6o_len > optend) | if (ooff + sizeof(opt) + opt.ip6o_len > optend) | ||||
goto drop; | goto drop; | ||||
switch (opt.ip6o_type) { | if (opt.ip6o_type == IP6OPT_JUMBO) | ||||
case IP6OPT_JUMBO: | |||||
if (h->ip6_plen != 0) | |||||
goto drop; | goto drop; | ||||
if (!pf_pull_hdr(m, ooff, &jumbo, | |||||
sizeof(jumbo), NULL, NULL, | |||||
AF_INET6)) | |||||
goto shortpkt; | |||||
memcpy(&jumbolen, jumbo.ip6oj_jumbo_len, | |||||
sizeof(jumbolen)); | |||||
jumbolen = ntohl(jumbolen); | |||||
if (jumbolen <= IPV6_MAXPACKET) | |||||
goto drop; | |||||
if (sizeof(struct ip6_hdr) + jumbolen != | |||||
m->m_pkthdr.len) | |||||
goto drop; | |||||
break; | |||||
default: | |||||
break; | |||||
} | |||||
ooff += sizeof(opt) + opt.ip6o_len; | ooff += sizeof(opt) + opt.ip6o_len; | ||||
} while (ooff < optend); | } while (ooff < optend); | ||||
off = optend; | off = optend; | ||||
proto = ext.ip6e_nxt; | proto = ext.ip6e_nxt; | ||||
break; | break; | ||||
default: | default: | ||||
terminal = 1; | terminal = 1; | ||||
break; | break; | ||||
} | } | ||||
} while (!terminal); | } while (!terminal); | ||||
/* jumbo payload option must be present, or plen > 0 */ | |||||
if (ntohs(h->ip6_plen) == 0) | |||||
plen = jumbolen; | |||||
else | |||||
plen = ntohs(h->ip6_plen); | |||||
if (plen == 0) | |||||
goto drop; | |||||
if (sizeof(struct ip6_hdr) + plen > m->m_pkthdr.len) | if (sizeof(struct ip6_hdr) + plen > m->m_pkthdr.len) | ||||
goto shortpkt; | goto shortpkt; | ||||
pf_scrub_ip6(&m, r->min_ttl); | pf_scrub_ip6(&m, r->min_ttl); | ||||
return (PF_PASS); | return (PF_PASS); | ||||
fragment: | fragment: | ||||
/* Jumbo payload packets cannot be fragmented. */ | |||||
plen = ntohs(h->ip6_plen); | |||||
if (plen == 0 || jumbolen) | |||||
goto drop; | |||||
if (sizeof(struct ip6_hdr) + plen > m->m_pkthdr.len) | if (sizeof(struct ip6_hdr) + plen > m->m_pkthdr.len) | ||||
goto shortpkt; | goto shortpkt; | ||||
if (!pf_pull_hdr(m, off, &frag, sizeof(frag), NULL, NULL, AF_INET6)) | if (!pf_pull_hdr(m, off, &frag, sizeof(frag), NULL, NULL, AF_INET6)) | ||||
goto shortpkt; | goto shortpkt; | ||||
/* Offset now points to data portion. */ | /* Offset now points to data portion. */ | ||||
off += sizeof(frag); | off += sizeof(frag); | ||||
▲ Show 20 Lines • Show All 740 Lines • Show Last 20 Lines |