| version 1.147, 2002/04/18 22:33:21 |
version 1.148, 2002/05/07 02:59:38 |
| Line 858 ip_reass(ipqe, fp) |
|
| Line 858 ip_reass(ipqe, fp) |
|
| fp->ipq_ttl = IPFRAGTTL; |
fp->ipq_ttl = IPFRAGTTL; |
| fp->ipq_p = ipqe->ipqe_ip->ip_p; |
fp->ipq_p = ipqe->ipqe_ip->ip_p; |
| fp->ipq_id = ipqe->ipqe_ip->ip_id; |
fp->ipq_id = ipqe->ipqe_ip->ip_id; |
| LIST_INIT(&fp->ipq_fragq); |
TAILQ_INIT(&fp->ipq_fragq); |
| fp->ipq_src = ipqe->ipqe_ip->ip_src; |
fp->ipq_src = ipqe->ipqe_ip->ip_src; |
| fp->ipq_dst = ipqe->ipqe_ip->ip_dst; |
fp->ipq_dst = ipqe->ipqe_ip->ip_dst; |
| p = NULL; |
p = NULL; |
| Line 868 ip_reass(ipqe, fp) |
|
| Line 868 ip_reass(ipqe, fp) |
|
| /* |
/* |
| * Find a segment which begins after this one does. |
* Find a segment which begins after this one does. |
| */ |
*/ |
| for (p = NULL, q = LIST_FIRST(&fp->ipq_fragq); q != NULL; |
for (p = NULL, q = TAILQ_FIRST(&fp->ipq_fragq); q != NULL; |
| p = q, q = LIST_NEXT(q, ipqe_q)) |
p = q, q = TAILQ_NEXT(q, ipqe_q)) |
| if (q->ipqe_ip->ip_off > ipqe->ipqe_ip->ip_off) |
if (q->ipqe_ip->ip_off > ipqe->ipqe_ip->ip_off) |
| break; |
break; |
| |
|
| Line 904 ip_reass(ipqe, fp) |
|
| Line 904 ip_reass(ipqe, fp) |
|
| m_adj(q->ipqe_m, i); |
m_adj(q->ipqe_m, i); |
| break; |
break; |
| } |
} |
| nq = LIST_NEXT(q, ipqe_q); |
nq = TAILQ_NEXT(q, ipqe_q); |
| m_freem(q->ipqe_m); |
m_freem(q->ipqe_m); |
| LIST_REMOVE(q, ipqe_q); |
TAILQ_REMOVE(&fp->ipq_fragq, q, ipqe_q); |
| pool_put(&ipqent_pool, q); |
pool_put(&ipqent_pool, q); |
| } |
} |
| |
|
|
|
| * check for complete reassembly. |
* check for complete reassembly. |
| */ |
*/ |
| if (p == NULL) { |
if (p == NULL) { |
| LIST_INSERT_HEAD(&fp->ipq_fragq, ipqe, ipqe_q); |
TAILQ_INSERT_HEAD(&fp->ipq_fragq, ipqe, ipqe_q); |
| } else { |
} else { |
| LIST_INSERT_AFTER(p, ipqe, ipqe_q); |
TAILQ_INSERT_AFTER(&fp->ipq_fragq, p, ipqe, ipqe_q); |
| } |
} |
| next = 0; |
next = 0; |
| for (p = NULL, q = LIST_FIRST(&fp->ipq_fragq); q != NULL; |
for (p = NULL, q = TAILQ_FIRST(&fp->ipq_fragq); q != NULL; |
| p = q, q = LIST_NEXT(q, ipqe_q)) { |
p = q, q = TAILQ_NEXT(q, ipqe_q)) { |
| if (q->ipqe_ip->ip_off != next) |
if (q->ipqe_ip->ip_off != next) |
| return (0); |
return (0); |
| next += q->ipqe_ip->ip_len; |
next += q->ipqe_ip->ip_len; |
|
|
| * Reassembly is complete. Check for a bogus message size and |
* Reassembly is complete. Check for a bogus message size and |
| * concatenate fragments. |
* concatenate fragments. |
| */ |
*/ |
| q = LIST_FIRST(&fp->ipq_fragq); |
q = TAILQ_FIRST(&fp->ipq_fragq); |
| ip = q->ipqe_ip; |
ip = q->ipqe_ip; |
| if ((next + (ip->ip_hl << 2)) > IP_MAXPACKET) { |
if ((next + (ip->ip_hl << 2)) > IP_MAXPACKET) { |
| ipstat.ips_toolong++; |
ipstat.ips_toolong++; |
|
|
| t = m->m_next; |
t = m->m_next; |
| m->m_next = 0; |
m->m_next = 0; |
| m_cat(m, t); |
m_cat(m, t); |
| nq = LIST_NEXT(q, ipqe_q); |
nq = TAILQ_NEXT(q, ipqe_q); |
| pool_put(&ipqent_pool, q); |
pool_put(&ipqent_pool, q); |
| for (q = nq; q != NULL; q = nq) { |
for (q = nq; q != NULL; q = nq) { |
| t = q->ipqe_m; |
t = q->ipqe_m; |
| nq = LIST_NEXT(q, ipqe_q); |
nq = TAILQ_NEXT(q, ipqe_q); |
| pool_put(&ipqent_pool, q); |
pool_put(&ipqent_pool, q); |
| m_cat(m, t); |
m_cat(m, t); |
| } |
} |
|
|
| |
|
| IPQ_LOCK_CHECK(); |
IPQ_LOCK_CHECK(); |
| |
|
| for (q = LIST_FIRST(&fp->ipq_fragq); q != NULL; q = p) { |
for (q = TAILQ_FIRST(&fp->ipq_fragq); q != NULL; q = p) { |
| p = LIST_NEXT(q, ipqe_q); |
p = TAILQ_NEXT(q, ipqe_q); |
| m_freem(q->ipqe_m); |
m_freem(q->ipqe_m); |
| LIST_REMOVE(q, ipqe_q); |
TAILQ_REMOVE(&fp->ipq_fragq, q, ipqe_q); |
| pool_put(&ipqent_pool, q); |
pool_put(&ipqent_pool, q); |
| } |
} |
| LIST_REMOVE(fp, ipq_q); |
LIST_REMOVE(fp, ipq_q); |