| version 1.49, 1997/04/15 00:41:52 |
version 1.50, 1997/06/24 02:26:04 |
|
|
| * but it's not worth the time; just let them time out.) |
* but it's not worth the time; just let them time out.) |
| */ |
*/ |
| if (ip->ip_off & ~(IP_DF|IP_RF)) { |
if (ip->ip_off & ~(IP_DF|IP_RF)) { |
| if (m->m_flags & M_EXT) { /* XXX */ |
|
| if ((m = m_pullup(m, sizeof (struct ip))) == 0) { |
|
| ipstat.ips_toosmall++; |
|
| goto next; |
|
| } |
|
| ip = mtod(m, struct ip *); |
|
| } |
|
| /* |
/* |
| * Look for queue of fragments |
* Look for queue of fragments |
| * of this datagram. |
* of this datagram. |
|
|
| goto bad; |
goto bad; |
| } |
} |
| ipqe->ipqe_mff = mff; |
ipqe->ipqe_mff = mff; |
| |
ipqe->ipqe_m = m; |
| ipqe->ipqe_ip = ip; |
ipqe->ipqe_ip = ip; |
| ip = ip_reass(ipqe, fp); |
m = ip_reass(ipqe, fp); |
| if (ip == 0) |
if (m == 0) |
| goto next; |
goto next; |
| ipstat.ips_reassembled++; |
ipstat.ips_reassembled++; |
| m = dtom(ip); |
ip = mtod(m, struct ip *); |
| } else |
} else |
| if (fp) |
if (fp) |
| ip_freef(fp); |
ip_freef(fp); |
|
|
| * reassembly of this datagram already exists, then it |
* reassembly of this datagram already exists, then it |
| * is given as fp; otherwise have to make a chain. |
* is given as fp; otherwise have to make a chain. |
| */ |
*/ |
| struct ip * |
struct mbuf * |
| ip_reass(ipqe, fp) |
ip_reass(ipqe, fp) |
| register struct ipqent *ipqe; |
register struct ipqent *ipqe; |
| register struct ipq *fp; |
register struct ipq *fp; |
| { |
{ |
| register struct mbuf *m = dtom(ipqe->ipqe_ip); |
register struct mbuf *m = ipqe->ipqe_m; |
| register struct ipqent *nq, *p, *q; |
register struct ipqent *nq, *p, *q; |
| struct ip *ip; |
struct ip *ip; |
| struct mbuf *t; |
struct mbuf *t; |
| Line 478 ip_reass(ipqe, fp) |
|
| Line 472 ip_reass(ipqe, fp) |
|
| * If first fragment to arrive, create a reassembly queue. |
* If first fragment to arrive, create a reassembly queue. |
| */ |
*/ |
| if (fp == 0) { |
if (fp == 0) { |
| if ((t = m_get(M_DONTWAIT, MT_FTABLE)) == NULL) |
MALLOC(fp, struct ipq *, sizeof (struct ipq), |
| |
M_FTABLE, M_NOWAIT); |
| |
if (fp == NULL) |
| goto dropfrag; |
goto dropfrag; |
| fp = mtod(t, struct ipq *); |
|
| LIST_INSERT_HEAD(&ipq, fp, ipq_q); |
LIST_INSERT_HEAD(&ipq, fp, ipq_q); |
| fp->ipq_ttl = IPFRAGTTL; |
fp->ipq_ttl = IPFRAGTTL; |
| fp->ipq_p = ipqe->ipqe_ip->ip_p; |
fp->ipq_p = ipqe->ipqe_ip->ip_p; |
| Line 511 ip_reass(ipqe, fp) |
|
| Line 506 ip_reass(ipqe, fp) |
|
| if (i > 0) { |
if (i > 0) { |
| if (i >= ipqe->ipqe_ip->ip_len) |
if (i >= ipqe->ipqe_ip->ip_len) |
| goto dropfrag; |
goto dropfrag; |
| m_adj(dtom(ipqe->ipqe_ip), i); |
m_adj(ipqe->ipqe_m, i); |
| ipqe->ipqe_ip->ip_off += i; |
ipqe->ipqe_ip->ip_off += i; |
| ipqe->ipqe_ip->ip_len -= i; |
ipqe->ipqe_ip->ip_len -= i; |
| } |
} |
| Line 528 ip_reass(ipqe, fp) |
|
| Line 523 ip_reass(ipqe, fp) |
|
| if (i < q->ipqe_ip->ip_len) { |
if (i < q->ipqe_ip->ip_len) { |
| q->ipqe_ip->ip_len -= i; |
q->ipqe_ip->ip_len -= i; |
| q->ipqe_ip->ip_off += i; |
q->ipqe_ip->ip_off += i; |
| m_adj(dtom(q->ipqe_ip), i); |
m_adj(q->ipqe_m, i); |
| break; |
break; |
| } |
} |
| nq = q->ipqe_q.le_next; |
nq = q->ipqe_q.le_next; |
| m_freem(dtom(q->ipqe_ip)); |
m_freem(q->ipqe_m); |
| LIST_REMOVE(q, ipqe_q); |
LIST_REMOVE(q, ipqe_q); |
| FREE(q, M_IPQ); |
FREE(q, M_IPQ); |
| } |
} |
|
|
| ip_freef(fp); |
ip_freef(fp); |
| return (0); |
return (0); |
| } |
} |
| m = dtom(q->ipqe_ip); |
m = q->ipqe_m; |
| 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 = q->ipqe_q.le_next; |
nq = q->ipqe_q.le_next; |
| FREE(q, M_IPQ); |
FREE(q, M_IPQ); |
| for (q = nq; q != NULL; q = nq) { |
for (q = nq; q != NULL; q = nq) { |
| t = dtom(q->ipqe_ip); |
t = q->ipqe_m; |
| nq = q->ipqe_q.le_next; |
nq = q->ipqe_q.le_next; |
| FREE(q, M_IPQ); |
FREE(q, M_IPQ); |
| m_cat(m, t); |
m_cat(m, t); |
|
|
| ip->ip_src = fp->ipq_src; |
ip->ip_src = fp->ipq_src; |
| ip->ip_dst = fp->ipq_dst; |
ip->ip_dst = fp->ipq_dst; |
| LIST_REMOVE(fp, ipq_q); |
LIST_REMOVE(fp, ipq_q); |
| (void) m_free(dtom(fp)); |
FREE(fp, M_FTABLE); |
| m->m_len += (ip->ip_hl << 2); |
m->m_len += (ip->ip_hl << 2); |
| m->m_data -= (ip->ip_hl << 2); |
m->m_data -= (ip->ip_hl << 2); |
| /* some debugging cruft by sklower, below, will go away soon */ |
/* some debugging cruft by sklower, below, will go away soon */ |
| if (m->m_flags & M_PKTHDR) { /* XXX this should be done elsewhere */ |
if (m->m_flags & M_PKTHDR) { /* XXX this should be done elsewhere */ |
| register int plen = 0; |
register int plen = 0; |
| for (t = m; m; m = m->m_next) |
for (t = m; t; t = t->m_next) |
| plen += m->m_len; |
plen += t->m_len; |
| t->m_pkthdr.len = plen; |
m->m_pkthdr.len = plen; |
| } |
} |
| return (ip); |
return (m); |
| |
|
| dropfrag: |
dropfrag: |
| ipstat.ips_fragdropped++; |
ipstat.ips_fragdropped++; |
|
|
| |
|
| for (q = fp->ipq_fragq.lh_first; q != NULL; q = p) { |
for (q = fp->ipq_fragq.lh_first; q != NULL; q = p) { |
| p = q->ipqe_q.le_next; |
p = q->ipqe_q.le_next; |
| m_freem(dtom(q->ipqe_ip)); |
m_freem(q->ipqe_m); |
| LIST_REMOVE(q, ipqe_q); |
LIST_REMOVE(q, ipqe_q); |
| FREE(q, M_IPQ); |
FREE(q, M_IPQ); |
| } |
} |
| LIST_REMOVE(fp, ipq_q); |
LIST_REMOVE(fp, ipq_q); |
| (void) m_free(dtom(fp)); |
FREE(fp, M_FTABLE); |
| } |
} |
| |
|
| /* |
/* |