version 1.10, 2000/02/06 12:49:42 |
version 1.10.4.2, 2003/02/11 15:56:40 |
Line 66 static void frag6_insque __P((struct ip6 |
|
Line 66 static void frag6_insque __P((struct ip6 |
|
static void frag6_remque __P((struct ip6q *)); |
static void frag6_remque __P((struct ip6q *)); |
static void frag6_freef __P((struct ip6q *)); |
static void frag6_freef __P((struct ip6q *)); |
|
|
|
/* XXX we eventually need splreass6, or some real semaphore */ |
int frag6_doing_reass; |
int frag6_doing_reass; |
u_int frag6_nfragpackets; |
u_int frag6_nfragpackets; |
struct ip6q ip6q; /* ip6 reassemble queue */ |
struct ip6q ip6q; /* ip6 reassemble queue */ |
Line 205 frag6_input(mp, offp, proto) |
|
Line 206 frag6_input(mp, offp, proto) |
|
/* offset now points to data portion */ |
/* offset now points to data portion */ |
offset += sizeof(struct ip6_frag); |
offset += sizeof(struct ip6_frag); |
|
|
|
frag6_doing_reass = 1; |
|
|
for (q6 = ip6q.ip6q_next; q6 != &ip6q; q6 = q6->ip6q_next) |
for (q6 = ip6q.ip6q_next; q6 != &ip6q; q6 = q6->ip6q_next) |
if (ip6f->ip6f_ident == q6->ip6q_ident && |
if (ip6f->ip6f_ident == q6->ip6q_ident && |
IN6_ARE_ADDR_EQUAL(&ip6->ip6_src, &q6->ip6q_src) && |
IN6_ARE_ADDR_EQUAL(&ip6->ip6_src, &q6->ip6q_src) && |
Line 216 frag6_input(mp, offp, proto) |
|
Line 219 frag6_input(mp, offp, proto) |
|
* the first fragment to arrive, create a reassembly queue. |
* the first fragment to arrive, create a reassembly queue. |
*/ |
*/ |
first_frag = 1; |
first_frag = 1; |
frag6_nfragpackets++; |
|
|
|
/* |
/* |
* Enforce upper bound on number of fragmented packets |
* Enforce upper bound on number of fragmented packets |
Line 224 frag6_input(mp, offp, proto) |
|
Line 226 frag6_input(mp, offp, proto) |
|
* If maxfrag is 0, never accept fragments. |
* If maxfrag is 0, never accept fragments. |
* If maxfrag is -1, accept all fragments without limitation. |
* If maxfrag is -1, accept all fragments without limitation. |
*/ |
*/ |
if (frag6_nfragpackets >= (u_int)ip6_maxfragpackets) { |
if (ip6_maxfragpackets < 0) |
ip6stat.ip6s_fragoverflow++; |
; |
in6_ifstat_inc(dstifp, ifs6_reass_fail); |
else if (frag6_nfragpackets >= (u_int)ip6_maxfragpackets) |
frag6_freef(ip6q.ip6q_prev); |
goto dropfrag; |
} |
frag6_nfragpackets++; |
q6 = (struct ip6q *)malloc(sizeof(struct ip6q), M_FTABLE, |
q6 = (struct ip6q *)malloc(sizeof(struct ip6q), M_FTABLE, |
M_DONTWAIT); |
M_DONTWAIT); |
if (q6 == NULL) |
if (q6 == NULL) |
Line 273 frag6_input(mp, offp, proto) |
|
Line 275 frag6_input(mp, offp, proto) |
|
icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER, |
icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER, |
offset - sizeof(struct ip6_frag) + |
offset - sizeof(struct ip6_frag) + |
offsetof(struct ip6_frag, ip6f_offlg)); |
offsetof(struct ip6_frag, ip6f_offlg)); |
|
frag6_doing_reass = 0; |
return(IPPROTO_DONE); |
return(IPPROTO_DONE); |
} |
} |
} |
} |
Line 280 frag6_input(mp, offp, proto) |
|
Line 283 frag6_input(mp, offp, proto) |
|
icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER, |
icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER, |
offset - sizeof(struct ip6_frag) + |
offset - sizeof(struct ip6_frag) + |
offsetof(struct ip6_frag, ip6f_offlg)); |
offsetof(struct ip6_frag, ip6f_offlg)); |
|
frag6_doing_reass = 0; |
return(IPPROTO_DONE); |
return(IPPROTO_DONE); |
} |
} |
/* |
/* |
Line 392 frag6_input(mp, offp, proto) |
|
Line 396 frag6_input(mp, offp, proto) |
|
i = af6->ip6af_up->ip6af_off + af6->ip6af_up->ip6af_frglen |
i = af6->ip6af_up->ip6af_off + af6->ip6af_up->ip6af_frglen |
- ip6af->ip6af_off; |
- ip6af->ip6af_off; |
if (i > 0) { |
if (i > 0) { |
|
#if 0 /* suppress the noisy log */ |
log(LOG_ERR, "%d bytes of a fragment from %s " |
log(LOG_ERR, "%d bytes of a fragment from %s " |
"overlaps the previous fragment\n", |
"overlaps the previous fragment\n", |
i, ip6_sprintf(&q6->ip6q_src)); |
i, ip6_sprintf(&q6->ip6q_src)); |
|
#endif |
|
free(ip6af, M_FTABLE); |
goto dropfrag; |
goto dropfrag; |
} |
} |
} |
} |
if (af6 != (struct ip6asfrag *)q6) { |
if (af6 != (struct ip6asfrag *)q6) { |
i = (ip6af->ip6af_off + ip6af->ip6af_frglen) - af6->ip6af_off; |
i = (ip6af->ip6af_off + ip6af->ip6af_frglen) - af6->ip6af_off; |
if (i > 0) { |
if (i > 0) { |
|
#if 0 /* suppress the noisy log */ |
log(LOG_ERR, "%d bytes of a fragment from %s " |
log(LOG_ERR, "%d bytes of a fragment from %s " |
"overlaps the succeeding fragment", |
"overlaps the succeeding fragment", |
i, ip6_sprintf(&q6->ip6q_src)); |
i, ip6_sprintf(&q6->ip6q_src)); |
|
#endif |
|
free(ip6af, M_FTABLE); |
goto dropfrag; |
goto dropfrag; |
} |
} |
} |
} |
|
|
in6_ifstat_inc(dstifp, ifs6_reass_fail); |
in6_ifstat_inc(dstifp, ifs6_reass_fail); |
ip6stat.ip6s_fragdropped++; |
ip6stat.ip6s_fragdropped++; |
m_freem(m); |
m_freem(m); |
|
frag6_doing_reass = 0; |
return IPPROTO_DONE; |
return IPPROTO_DONE; |
} |
} |
|
|
Line 643 frag6_slowtimo() |
|
Line 654 frag6_slowtimo() |
|
* (due to the limit being lowered), drain off |
* (due to the limit being lowered), drain off |
* enough to get down to the new limit. |
* enough to get down to the new limit. |
*/ |
*/ |
while (frag6_nfragpackets > (u_int)ip6_maxfragpackets) { |
while (frag6_nfragpackets > (u_int)ip6_maxfragpackets && |
|
ip6q.ip6q_prev) { |
ip6stat.ip6s_fragoverflow++; |
ip6stat.ip6s_fragoverflow++; |
/* XXX in6_ifstat_inc(ifp, ifs6_reass_fail) */ |
/* XXX in6_ifstat_inc(ifp, ifs6_reass_fail) */ |
frag6_freef(ip6q.ip6q_prev); |
frag6_freef(ip6q.ip6q_prev); |