version 1.1.1.4, 2018/04/24 16:54:35
|
version 1.1.1.5, 2018/04/24 17:25:42
|
Line 7
|
Line 7
|
|
|
#include <slirp.h> |
#include <slirp.h> |
|
|
int if_queued = 0; /* Number of packets queued so far */ |
|
|
|
struct mbuf if_fastq; /* fast queue (for interactive data) */ |
|
struct mbuf if_batchq; /* queue for non-interactive data */ |
|
struct mbuf *next_m; /* Pointer to next mbuf to output */ |
|
|
|
#define ifs_init(ifm) ((ifm)->ifs_next = (ifm)->ifs_prev = (ifm)) |
#define ifs_init(ifm) ((ifm)->ifs_next = (ifm)->ifs_prev = (ifm)) |
|
|
static void |
static void |
Line 32 ifs_remque(struct mbuf *ifm)
|
Line 26 ifs_remque(struct mbuf *ifm)
|
} |
} |
|
|
void |
void |
if_init() |
if_init(Slirp *slirp) |
{ |
|
if_fastq.ifq_next = if_fastq.ifq_prev = &if_fastq; |
|
if_batchq.ifq_next = if_batchq.ifq_prev = &if_batchq; |
|
// sl_compress_init(&comp_s); |
|
next_m = &if_batchq; |
|
} |
|
|
|
#if 0 |
|
/* |
|
* This shouldn't be needed since the modem is blocking and |
|
* we don't expect any signals, but what the hell.. |
|
*/ |
|
inline int |
|
writen(fd, bptr, n) |
|
int fd; |
|
char *bptr; |
|
int n; |
|
{ |
{ |
int ret; |
slirp->if_fastq.ifq_next = slirp->if_fastq.ifq_prev = &slirp->if_fastq; |
int total; |
slirp->if_batchq.ifq_next = slirp->if_batchq.ifq_prev = &slirp->if_batchq; |
|
slirp->next_m = &slirp->if_batchq; |
/* This should succeed most of the time */ |
|
ret = send(fd, bptr, n,0); |
|
if (ret == n || ret <= 0) |
|
return ret; |
|
|
|
/* Didn't write everything, go into the loop */ |
|
total = ret; |
|
while (n > total) { |
|
ret = send(fd, bptr+total, n-total,0); |
|
if (ret <= 0) |
|
return ret; |
|
total += ret; |
|
} |
|
return total; |
|
} |
} |
|
|
/* |
/* |
* if_input - read() the tty, do "top level" processing (ie: check for any escapes), |
|
* and pass onto (*ttyp->if_input) |
|
* |
|
* XXXXX Any zeros arriving by themselves are NOT placed into the arriving packet. |
|
*/ |
|
#define INBUFF_SIZE 2048 /* XXX */ |
|
void |
|
if_input(ttyp) |
|
struct ttys *ttyp; |
|
{ |
|
u_char if_inbuff[INBUFF_SIZE]; |
|
int if_n; |
|
|
|
DEBUG_CALL("if_input"); |
|
DEBUG_ARG("ttyp = %lx", (long)ttyp); |
|
|
|
if_n = recv(ttyp->fd, (char *)if_inbuff, INBUFF_SIZE,0); |
|
|
|
DEBUG_MISC((dfd, " read %d bytes\n", if_n)); |
|
|
|
if (if_n <= 0) { |
|
if (if_n == 0 || (errno != EINTR && errno != EAGAIN)) { |
|
if (ttyp->up) |
|
link_up--; |
|
tty_detached(ttyp, 0); |
|
} |
|
return; |
|
} |
|
if (if_n == 1) { |
|
if (*if_inbuff == '0') { |
|
ttyp->ones = 0; |
|
if (++ttyp->zeros >= 5) |
|
slirp_exit(0); |
|
return; |
|
} |
|
if (*if_inbuff == '1') { |
|
ttyp->zeros = 0; |
|
if (++ttyp->ones >= 5) |
|
tty_detached(ttyp, 0); |
|
return; |
|
} |
|
} |
|
ttyp->ones = ttyp->zeros = 0; |
|
|
|
(*ttyp->if_input)(ttyp, if_inbuff, if_n); |
|
} |
|
#endif |
|
|
|
/* |
|
* if_output: Queue packet into an output queue. |
* if_output: Queue packet into an output queue. |
* There are 2 output queue's, if_fastq and if_batchq. |
* There are 2 output queue's, if_fastq and if_batchq. |
* Each output queue is a doubly linked list of double linked lists |
* Each output queue is a doubly linked list of double linked lists |
Line 133 if_input(ttyp)
|
Line 47 if_input(ttyp)
|
* it'll temporarily get downgraded to the batchq) |
* it'll temporarily get downgraded to the batchq) |
*/ |
*/ |
void |
void |
if_output(so, ifm) |
if_output(struct socket *so, struct mbuf *ifm) |
struct socket *so; |
|
struct mbuf *ifm; |
|
{ |
{ |
|
Slirp *slirp = ifm->slirp; |
struct mbuf *ifq; |
struct mbuf *ifq; |
int on_fastq = 1; |
int on_fastq = 1; |
|
|
Line 161 if_output(so, ifm)
|
Line 74 if_output(so, ifm)
|
* We mustn't put this packet back on the fastq (or we'll send it out of order) |
* We mustn't put this packet back on the fastq (or we'll send it out of order) |
* XXX add cache here? |
* XXX add cache here? |
*/ |
*/ |
for (ifq = if_batchq.ifq_prev; ifq != &if_batchq; ifq = ifq->ifq_prev) { |
for (ifq = slirp->if_batchq.ifq_prev; ifq != &slirp->if_batchq; |
|
ifq = ifq->ifq_prev) { |
if (so == ifq->ifq_so) { |
if (so == ifq->ifq_so) { |
/* A match! */ |
/* A match! */ |
ifm->ifq_so = so; |
ifm->ifq_so = so; |
Line 172 if_output(so, ifm)
|
Line 86 if_output(so, ifm)
|
|
|
/* No match, check which queue to put it on */ |
/* No match, check which queue to put it on */ |
if (so && (so->so_iptos & IPTOS_LOWDELAY)) { |
if (so && (so->so_iptos & IPTOS_LOWDELAY)) { |
ifq = if_fastq.ifq_prev; |
ifq = slirp->if_fastq.ifq_prev; |
on_fastq = 1; |
on_fastq = 1; |
/* |
/* |
* Check if this packet is a part of the last |
* Check if this packet is a part of the last |
Line 184 if_output(so, ifm)
|
Line 98 if_output(so, ifm)
|
goto diddit; |
goto diddit; |
} |
} |
} else |
} else |
ifq = if_batchq.ifq_prev; |
ifq = slirp->if_batchq.ifq_prev; |
|
|
/* Create a new doubly linked list for this session */ |
/* Create a new doubly linked list for this session */ |
ifm->ifq_so = so; |
ifm->ifq_so = so; |
Line 192 if_output(so, ifm)
|
Line 106 if_output(so, ifm)
|
insque(ifm, ifq); |
insque(ifm, ifq); |
|
|
diddit: |
diddit: |
++if_queued; |
slirp->if_queued++; |
|
|
if (so) { |
if (so) { |
/* Update *_queued */ |
/* Update *_queued */ |
Line 212 diddit:
|
Line 126 diddit:
|
remque(ifm->ifs_next); |
remque(ifm->ifs_next); |
|
|
/* ...And insert in the new. That'll teach ya! */ |
/* ...And insert in the new. That'll teach ya! */ |
insque(ifm->ifs_next, &if_batchq); |
insque(ifm->ifs_next, &slirp->if_batchq); |
} |
} |
} |
} |
|
|
Line 220 diddit:
|
Line 134 diddit:
|
/* |
/* |
* This prevents us from malloc()ing too many mbufs |
* This prevents us from malloc()ing too many mbufs |
*/ |
*/ |
if (link_up) { |
if_start(ifm->slirp); |
/* if_start will check towrite */ |
|
if_start(); |
|
} |
|
#endif |
#endif |
} |
} |
|
|
Line 240 diddit:
|
Line 151 diddit:
|
* to the first, etc. etc. |
* to the first, etc. etc. |
*/ |
*/ |
void |
void |
if_start(void) |
if_start(Slirp *slirp) |
{ |
{ |
struct mbuf *ifm, *ifqt; |
struct mbuf *ifm, *ifqt; |
|
|
DEBUG_CALL("if_start"); |
DEBUG_CALL("if_start"); |
|
|
if (if_queued == 0) |
if (slirp->if_queued == 0) |
return; /* Nothing to do */ |
return; /* Nothing to do */ |
|
|
again: |
again: |
/* check if we can really output */ |
/* check if we can really output */ |
if (!slirp_can_output()) |
if (!slirp_can_output(slirp->opaque)) |
return; |
return; |
|
|
/* |
/* |
* See which queue to get next packet from |
* See which queue to get next packet from |
* If there's something in the fastq, select it immediately |
* If there's something in the fastq, select it immediately |
*/ |
*/ |
if (if_fastq.ifq_next != &if_fastq) { |
if (slirp->if_fastq.ifq_next != &slirp->if_fastq) { |
ifm = if_fastq.ifq_next; |
ifm = slirp->if_fastq.ifq_next; |
} else { |
} else { |
/* Nothing on fastq, see if next_m is valid */ |
/* Nothing on fastq, see if next_m is valid */ |
if (next_m != &if_batchq) |
if (slirp->next_m != &slirp->if_batchq) |
ifm = next_m; |
ifm = slirp->next_m; |
else |
else |
ifm = if_batchq.ifq_next; |
ifm = slirp->if_batchq.ifq_next; |
|
|
/* Set which packet to send on next iteration */ |
/* Set which packet to send on next iteration */ |
next_m = ifm->ifq_next; |
slirp->next_m = ifm->ifq_next; |
} |
} |
/* Remove it from the queue */ |
/* Remove it from the queue */ |
ifqt = ifm->ifq_prev; |
ifqt = ifm->ifq_prev; |
remque(ifm); |
remque(ifm); |
--if_queued; |
slirp->if_queued--; |
|
|
/* If there are more packets for this session, re-queue them */ |
/* If there are more packets for this session, re-queue them */ |
if (ifm->ifs_next != /* ifm->ifs_prev != */ ifm) { |
if (ifm->ifs_next != /* ifm->ifs_prev != */ ifm) { |
Line 289 if_start(void)
|
Line 200 if_start(void)
|
} |
} |
|
|
/* Encapsulate the packet for sending */ |
/* Encapsulate the packet for sending */ |
if_encap((uint8_t *)ifm->m_data, ifm->m_len); |
if_encap(slirp, (uint8_t *)ifm->m_data, ifm->m_len); |
|
|
m_free(ifm); |
m_free(ifm); |
|
|
if (if_queued) |
if (slirp->if_queued) |
goto again; |
goto again; |
} |
} |