version 1.1.1.3, 2018/04/24 16:54:30
|
version 1.1.1.4, 2018/04/24 17:25:38
|
Line 40
|
Line 40
|
|
|
#include <slirp.h> |
#include <slirp.h> |
|
|
u_int16_t ip_id; |
|
|
|
/* Number of packets queued before we start sending |
/* Number of packets queued before we start sending |
* (to prevent allocing too many mbufs) */ |
* (to prevent allocing too many mbufs) */ |
#define IF_THRESH 10 |
#define IF_THRESH 10 |
Line 53 u_int16_t ip_id;
|
Line 51 u_int16_t ip_id;
|
* The mbuf opt, if present, will not be freed. |
* The mbuf opt, if present, will not be freed. |
*/ |
*/ |
int |
int |
ip_output(so, m0) |
ip_output(struct socket *so, struct mbuf *m0) |
struct socket *so; |
|
struct mbuf *m0; |
|
{ |
{ |
|
Slirp *slirp = m0->slirp; |
register struct ip *ip; |
register struct ip *ip; |
register struct mbuf *m = m0; |
register struct mbuf *m = m0; |
register int hlen = sizeof(struct ip ); |
register int hlen = sizeof(struct ip ); |
Line 66 ip_output(so, m0)
|
Line 63 ip_output(so, m0)
|
DEBUG_ARG("so = %lx", (long)so); |
DEBUG_ARG("so = %lx", (long)so); |
DEBUG_ARG("m0 = %lx", (long)m0); |
DEBUG_ARG("m0 = %lx", (long)m0); |
|
|
/* We do no options */ |
|
/* if (opt) { |
|
* m = ip_insertoptions(m, opt, &len); |
|
* hlen = len; |
|
* } |
|
*/ |
|
ip = mtod(m, struct ip *); |
ip = mtod(m, struct ip *); |
/* |
/* |
* Fill in IP header. |
* Fill in IP header. |
*/ |
*/ |
ip->ip_v = IPVERSION; |
ip->ip_v = IPVERSION; |
ip->ip_off &= IP_DF; |
ip->ip_off &= IP_DF; |
ip->ip_id = htons(ip_id++); |
ip->ip_id = htons(slirp->ip_id++); |
ip->ip_hl = hlen >> 2; |
ip->ip_hl = hlen >> 2; |
STAT(ipstat.ips_localout++); |
|
|
|
/* |
|
* Verify that we have any chance at all of being able to queue |
|
* the packet or packet fragments |
|
*/ |
|
/* XXX Hmmm... */ |
|
/* if (if_queued > IF_THRESH && towrite <= 0) { |
|
* error = ENOBUFS; |
|
* goto bad; |
|
* } |
|
*/ |
|
|
|
/* |
/* |
* If small enough for interface, can just send directly. |
* If small enough for interface, can just send directly. |
Line 112 ip_output(so, m0)
|
Line 91 ip_output(so, m0)
|
*/ |
*/ |
if (ip->ip_off & IP_DF) { |
if (ip->ip_off & IP_DF) { |
error = -1; |
error = -1; |
STAT(ipstat.ips_cantfrag++); |
|
goto bad; |
goto bad; |
} |
} |
|
|
Line 134 ip_output(so, m0)
|
Line 112 ip_output(so, m0)
|
mhlen = sizeof (struct ip); |
mhlen = sizeof (struct ip); |
for (off = hlen + len; off < (u_int16_t)ip->ip_len; off += len) { |
for (off = hlen + len; off < (u_int16_t)ip->ip_len; off += len) { |
register struct ip *mhip; |
register struct ip *mhip; |
m = m_get(); |
m = m_get(slirp); |
if (m == 0) { |
if (m == NULL) { |
error = -1; |
error = -1; |
STAT(ipstat.ips_odropped++); |
|
goto sendorfree; |
goto sendorfree; |
} |
} |
m->m_data += IF_MAXLINKHDR; |
m->m_data += IF_MAXLINKHDR; |
mhip = mtod(m, struct ip *); |
mhip = mtod(m, struct ip *); |
*mhip = *ip; |
*mhip = *ip; |
|
|
/* No options */ |
|
/* if (hlen > sizeof (struct ip)) { |
|
* mhlen = ip_optcopy(ip, mhip) + sizeof (struct ip); |
|
* mhip->ip_hl = mhlen >> 2; |
|
* } |
|
*/ |
|
m->m_len = mhlen; |
m->m_len = mhlen; |
mhip->ip_off = ((off - hlen) >> 3) + (ip->ip_off & ~IP_MF); |
mhip->ip_off = ((off - hlen) >> 3) + (ip->ip_off & ~IP_MF); |
if (ip->ip_off & IP_MF) |
if (ip->ip_off & IP_MF) |
Line 170 ip_output(so, m0)
|
Line 141 ip_output(so, m0)
|
mhip->ip_sum = cksum(m, mhlen); |
mhip->ip_sum = cksum(m, mhlen); |
*mnext = m; |
*mnext = m; |
mnext = &m->m_nextpkt; |
mnext = &m->m_nextpkt; |
STAT(ipstat.ips_ofragments++); |
|
} |
} |
/* |
/* |
* Update first fragment by trimming what's been copied out |
* Update first fragment by trimming what's been copied out |
Line 185 ip_output(so, m0)
|
Line 155 ip_output(so, m0)
|
sendorfree: |
sendorfree: |
for (m = m0; m; m = m0) { |
for (m = m0; m; m = m0) { |
m0 = m->m_nextpkt; |
m0 = m->m_nextpkt; |
m->m_nextpkt = 0; |
m->m_nextpkt = NULL; |
if (error == 0) |
if (error == 0) |
if_output(so, m); |
if_output(so, m); |
else |
else |
m_freem(m); |
m_freem(m); |
} |
} |
|
|
if (error == 0) |
|
STAT(ipstat.ips_fragmented++); |
|
} |
} |
|
|
done: |
done: |