* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* terms and conditions of the copyright.
*/
-#define WANT_SYS_IOCTL_H
#include <slirp.h>
/* patchable/settable parameters for tcp */
-int tcp_mssdflt = TCP_MSS;
-int tcp_rttdflt = TCPTV_SRTTDFLT / PR_SLOWHZ;
-int tcp_do_rfc1323 = 0; /* Don't do rfc1323 performance enhancements */
-int tcp_rcvspace; /* You may want to change this */
-int tcp_sndspace; /* Keep small if you have an error prone link */
+/* Don't do rfc1323 performance enhancements */
+#define TCP_DO_RFC1323 0
/*
* Tcp initialization
*/
void
-tcp_init()
+tcp_init(void)
{
tcp_iss = 1; /* wrong */
tcb.so_next = tcb.so_prev = &tcb;
-
- /* tcp_rcvspace = our Window we advertise to the remote */
- tcp_rcvspace = TCP_RCVSPACE;
- tcp_sndspace = TCP_SNDSPACE;
-
- /* Make sure tcp_sndspace is at least 2*MSS */
- if (tcp_sndspace < 2*(min(if_mtu, if_mru) - sizeof(struct tcpiphdr)))
- tcp_sndspace = 2*(min(if_mtu, if_mru) - sizeof(struct tcpiphdr));
}
/*
*/
/* struct tcpiphdr * */
void
-tcp_template(tp)
- struct tcpcb *tp;
+tcp_template(struct tcpcb *tp)
{
struct socket *so = tp->t_socket;
register struct tcpiphdr *n = &tp->t_template;
- n->ti_next = n->ti_prev = 0;
+ n->ti_mbuf = NULL;
n->ti_x1 = 0;
n->ti_pr = IPPROTO_TCP;
n->ti_len = htons(sizeof (struct tcpiphdr) - sizeof (struct ip));
* segment are as specified by the parameters.
*/
void
-tcp_respond(tp, ti, m, ack, seq, flags)
- struct tcpcb *tp;
- register struct tcpiphdr *ti;
- register struct mbuf *m;
- tcp_seq ack, seq;
- int flags;
+tcp_respond(struct tcpcb *tp, struct tcpiphdr *ti, struct mbuf *m,
+ tcp_seq ack, tcp_seq seq, int flags)
{
register int tlen;
int win = 0;
if (tp)
win = sbspace(&tp->t_socket->so_rcv);
- if (m == 0) {
+ if (m == NULL) {
if ((m = m_get()) == NULL)
return;
#ifdef TCP_COMPAT_42
#else
tlen = 0;
#endif
- m->m_data += if_maxlinkhdr;
+ m->m_data += IF_MAXLINKHDR;
*mtod(m, struct tcpiphdr *) = *ti;
ti = mtod(m, struct tcpiphdr *);
flags = TH_ACK;
tlen += sizeof (struct tcpiphdr);
m->m_len = tlen;
- ti->ti_next = ti->ti_prev = 0;
+ ti->ti_mbuf = NULL;
ti->ti_x1 = 0;
ti->ti_seq = htonl(seq);
ti->ti_ack = htonl(ack);
if(flags & TH_RST)
((struct ip *)ti)->ip_ttl = MAXTTL;
else
- ((struct ip *)ti)->ip_ttl = ip_defttl;
+ ((struct ip *)ti)->ip_ttl = IPDEFTTL;
(void) ip_output((struct socket *)0, m);
}
* protocol control block.
*/
struct tcpcb *
-tcp_newtcpcb(so)
- struct socket *so;
+tcp_newtcpcb(struct socket *so)
{
register struct tcpcb *tp;
return ((struct tcpcb *)0);
memset((char *) tp, 0, sizeof(struct tcpcb));
- tp->seg_next = tp->seg_prev = (tcpiphdrp_32)tp;
- tp->t_maxseg = tcp_mssdflt;
+ tp->seg_next = tp->seg_prev = (struct tcpiphdr*)tp;
+ tp->t_maxseg = TCP_MSS;
- tp->t_flags = tcp_do_rfc1323 ? (TF_REQ_SCALE|TF_REQ_TSTMP) : 0;
+ tp->t_flags = TCP_DO_RFC1323 ? (TF_REQ_SCALE|TF_REQ_TSTMP) : 0;
tp->t_socket = so;
/*
* reasonable initial retransmit time.
*/
tp->t_srtt = TCPTV_SRTTBASE;
- tp->t_rttvar = tcp_rttdflt * PR_SLOWHZ << 2;
+ tp->t_rttvar = TCPTV_SRTTDFLT << 2;
tp->t_rttmin = TCPTV_MIN;
TCPT_RANGESET(tp->t_rxtcur,
if (TCPS_HAVERCVDSYN(tp->t_state)) {
tp->t_state = TCPS_CLOSED;
(void) tcp_output(tp);
- tcpstat.tcps_drops++;
+ STAT(tcpstat.tcps_drops++);
} else
- tcpstat.tcps_conndrops++;
+ STAT(tcpstat.tcps_conndrops++);
/* if (errno == ETIMEDOUT && tp->t_softerror)
* errno = tp->t_softerror;
*/
* wake up any sleepers
*/
struct tcpcb *
-tcp_close(tp)
- register struct tcpcb *tp;
+tcp_close(struct tcpcb *tp)
{
register struct tcpiphdr *t;
struct socket *so = tp->t_socket;
DEBUG_ARG("tp = %lx", (long )tp);
/* free the reassembly queue, if any */
- t = (struct tcpiphdr *) tp->seg_next;
- while (t != (struct tcpiphdr *)tp) {
- t = (struct tcpiphdr *)t->ti_next;
- m = (struct mbuf *) REASS_MBUF((struct tcpiphdr *)t->ti_prev);
- remque_32((struct tcpiphdr *) t->ti_prev);
+ t = tcpfrag_list_first(tp);
+ while (!tcpfrag_list_end(t, tp)) {
+ t = tcpiphdr_next(t);
+ m = tcpiphdr_prev(t)->ti_mbuf;
+ remque(tcpiphdr2qlink(tcpiphdr_prev(t)));
m_freem(m);
}
/* It's static */
*/
/* free(tp, M_PCB); */
free(tp);
- so->so_tcpcb = 0;
+ so->so_tcpcb = NULL;
soisfdisconnected(so);
/* clobber input socket cache if we're closing the cached connection */
if (so == tcp_last_so)
sbfree(&so->so_rcv);
sbfree(&so->so_snd);
sofree(so);
- tcpstat.tcps_closed++;
+ STAT(tcpstat.tcps_closed++);
return ((struct tcpcb *)0);
}
+#ifdef notdef
void
tcp_drain()
{
* When a source quench is received, close congestion window
* to one segment. We will gradually open it again as we proceed.
*/
-
-#ifdef notdef
-
void
tcp_quench(i, errno)
* We can let the user exit from the close as soon as the FIN is acked.
*/
void
-tcp_sockclosed(tp)
- struct tcpcb *tp;
+tcp_sockclosed(struct tcpcb *tp)
{
DEBUG_CALL("tcp_sockclosed");
* nonblocking. Connect returns after the SYN is sent, and does
* not wait for ACK+SYN.
*/
-int tcp_fconnect(so)
- struct socket *so;
+int tcp_fconnect(struct socket *so)
{
int ret=0;
* here and SYN the local-host.
*/
void
-tcp_connect(inso)
- struct socket *inso;
+tcp_connect(struct socket *inso)
{
struct socket *so;
struct sockaddr_in addr;
- int addrlen = sizeof(struct sockaddr_in);
+ socklen_t addrlen = sizeof(struct sockaddr_in);
struct tcpcb *tp;
int s, opt;
*/
/* soisconnecting(so); */ /* NOFDREF used instead */
- tcpstat.tcps_connattempt++;
+ STAT(tcpstat.tcps_connattempt++);
tp->t_state = TCPS_SYN_SENT;
tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT;
* Attach a TCPCB to a socket.
*/
int
-tcp_attach(so)
- struct socket *so;
+tcp_attach(struct socket *so)
{
if ((so->so_tcpcb = tcp_newtcpcb(so)) == NULL)
return -1;
/*
* Set the socket's type of service field
*/
-struct tos_t tcptos[] = {
+static const struct tos_t tcptos[] = {
{0, 20, IPTOS_THROUGHPUT, 0}, /* ftp data */
{21, 21, IPTOS_LOWDELAY, EMU_FTP}, /* ftp control */
{0, 23, IPTOS_LOWDELAY, 0}, /* telnet */
{0, 0, 0, 0}
};
-struct emu_t *tcpemu = 0;
+#ifdef CONFIG_QEMU
+static
+#endif
+struct emu_t *tcpemu = NULL;
/*
* Return TOS according to the above table
*/
u_int8_t
-tcp_tos(so)
- struct socket *so;
+tcp_tos(struct socket *so)
{
int i = 0;
struct emu_t *emup;
return 0;
}
+#if 0
int do_echo = -1;
+#endif
/*
* Emulate programs that try and connect to us
* NOTE: if you return 0 you MUST m_free() the mbuf!
*/
int
-tcp_emu(so, m)
- struct socket *so;
- struct mbuf *m;
+tcp_emu(struct socket *so, struct mbuf *m)
{
u_int n1, n2, n3, n4, n5, n6;
- char buff[256];
+ char buff[257];
u_int32_t laddr;
u_int lport;
char *bptr;
{
struct socket *tmpso;
struct sockaddr_in addr;
- int addrlen = sizeof(struct sockaddr_in);
+ socklen_t addrlen = sizeof(struct sockaddr_in);
struct sbuf *so_rcv = &so->so_rcv;
memcpy(so_rcv->sb_wptr, m->m_data, m->m_len);
so_rcv->sb_rptr += m->m_len;
m->m_data[m->m_len] = 0; /* NULL terminate */
if (strchr(m->m_data, '\r') || strchr(m->m_data, '\n')) {
- if (sscanf(so_rcv->sb_data, "%d%*[ ,]%d", &n1, &n2) == 2) {
+ if (sscanf(so_rcv->sb_data, "%u%*[ ,]%u", &n1, &n2) == 2) {
HTONS(n1);
HTONS(n2);
/* n2 is the one on our host */
}
}
}
- so_rcv->sb_cc = sprintf(so_rcv->sb_data, "%d,%d\r\n", n1, n2);
+ so_rcv->sb_cc = snprintf(so_rcv->sb_data,
+ so_rcv->sb_datalen,
+ "%d,%d\r\n", n1, n2);
so_rcv->sb_rptr = so_rcv->sb_data;
so_rcv->sb_wptr = so_rcv->sb_data + so_rcv->sb_cc;
}
/*soisfconnecting(ns);*/
- tcpstat.tcps_connattempt++;
+ STAT(tcpstat.tcps_connattempt++);
tp->t_state = TCPS_SYN_SENT;
tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT;
}
#endif
case EMU_FTP: /* ftp */
- *(m->m_data+m->m_len) = 0; /* NULL terminate for strstr */
+ *(m->m_data+m->m_len) = 0; /* NUL terminate for strstr */
if ((bptr = (char *)strstr(m->m_data, "ORT")) != NULL) {
/*
* Need to emulate the PORT command
*/
- x = sscanf(bptr, "ORT %d,%d,%d,%d,%d,%d\r\n%256[^\177]",
+ x = sscanf(bptr, "ORT %u,%u,%u,%u,%u,%u\r\n%256[^\177]",
&n1, &n2, &n3, &n4, &n5, &n6, buff);
if (x < 6)
return 1;
n4 = (laddr & 0xff);
m->m_len = bptr - m->m_data; /* Adjust length */
- m->m_len += sprintf(bptr,"ORT %d,%d,%d,%d,%d,%d\r\n%s",
- n1, n2, n3, n4, n5, n6, x==7?buff:"");
+ m->m_len += snprintf(bptr, m->m_hdr.mh_size - m->m_len,
+ "ORT %d,%d,%d,%d,%d,%d\r\n%s",
+ n1, n2, n3, n4, n5, n6, x==7?buff:"");
return 1;
} else if ((bptr = (char *)strstr(m->m_data, "27 Entering")) != NULL) {
/*
* Need to emulate the PASV response
*/
- x = sscanf(bptr, "27 Entering Passive Mode (%d,%d,%d,%d,%d,%d)\r\n%256[^\177]",
+ x = sscanf(bptr, "27 Entering Passive Mode (%u,%u,%u,%u,%u,%u)\r\n%256[^\177]",
&n1, &n2, &n3, &n4, &n5, &n6, buff);
if (x < 6)
return 1;
n4 = (laddr & 0xff);
m->m_len = bptr - m->m_data; /* Adjust length */
- m->m_len += sprintf(bptr,"27 Entering Passive Mode (%d,%d,%d,%d,%d,%d)\r\n%s",
- n1, n2, n3, n4, n5, n6, x==7?buff:"");
+ m->m_len += snprintf(bptr, m->m_hdr.mh_size - m->m_len,
+ "27 Entering Passive Mode (%d,%d,%d,%d,%d,%d)\r\n%s",
+ n1, n2, n3, n4, n5, n6, x==7?buff:"");
return 1;
}
}
if (m->m_data[m->m_len-1] == '\0' && lport != 0 &&
(so = solisten(0, so->so_laddr.s_addr, htons(lport), SS_FACCEPTONCE)) != NULL)
- m->m_len = sprintf(m->m_data, "%d", ntohs(so->so_fport))+1;
+ m->m_len = snprintf(m->m_data, m->m_hdr.mh_size, "%d",
+ ntohs(so->so_fport)) + 1;
return 1;
case EMU_IRC:
return 1;
m->m_len = bptr - m->m_data; /* Adjust length */
- m->m_len += sprintf(bptr, "DCC CHAT chat %lu %u%c\n",
- (unsigned long)ntohl(so->so_faddr.s_addr),
- ntohs(so->so_fport), 1);
+ m->m_len += snprintf(bptr, m->m_hdr.mh_size,
+ "DCC CHAT chat %lu %u%c\n",
+ (unsigned long)ntohl(so->so_faddr.s_addr),
+ ntohs(so->so_fport), 1);
} else if (sscanf(bptr, "DCC SEND %256s %u %u %u", buff, &laddr, &lport, &n1) == 4) {
if ((so = solisten(0, htonl(laddr), htons(lport), SS_FACCEPTONCE)) == NULL)
return 1;
m->m_len = bptr - m->m_data; /* Adjust length */
- m->m_len += sprintf(bptr, "DCC SEND %s %lu %u %u%c\n",
- buff, (unsigned long)ntohl(so->so_faddr.s_addr),
- ntohs(so->so_fport), n1, 1);
+ m->m_len += snprintf(bptr, m->m_hdr.mh_size,
+ "DCC SEND %s %lu %u %u%c\n", buff,
+ (unsigned long)ntohl(so->so_faddr.s_addr),
+ ntohs(so->so_fport), n1, 1);
} else if (sscanf(bptr, "DCC MOVE %256s %u %u %u", buff, &laddr, &lport, &n1) == 4) {
if ((so = solisten(0, htonl(laddr), htons(lport), SS_FACCEPTONCE)) == NULL)
return 1;
m->m_len = bptr - m->m_data; /* Adjust length */
- m->m_len += sprintf(bptr, "DCC MOVE %s %lu %u %u%c\n",
- buff, (unsigned long)ntohl(so->so_faddr.s_addr),
- ntohs(so->so_fport), n1, 1);
+ m->m_len += snprintf(bptr, m->m_hdr.mh_size,
+ "DCC MOVE %s %lu %u %u%c\n", buff,
+ (unsigned long)ntohl(so->so_faddr.s_addr),
+ ntohs(so->so_fport), n1, 1);
}
return 1;
* return 2 if this is a command-line connection
*/
int
-tcp_ctl(so)
- struct socket *so;
+tcp_ctl(struct socket *so)
{
struct sbuf *sb = &so->so_snd;
int command;
for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
if (ex_ptr->ex_fport == so->so_fport &&
command == ex_ptr->ex_addr) {
+ if (ex_ptr->ex_pty == 3) {
+ so->s = -1;
+ so->extra = (void *)ex_ptr->ex_exec;
+ return 1;
+ }
do_pty = ex_ptr->ex_pty;
goto do_exec;
}
/* FALLTHROUGH */
case CTL_ALIAS:
- sb->sb_cc = sprintf(sb->sb_wptr,
- "Error: No application configured.\r\n");
+ sb->sb_cc = snprintf(sb->sb_wptr, sb->sb_datalen - (sb->sb_wptr - sb->sb_data),
+ "Error: No application configured.\r\n");
sb->sb_wptr += sb->sb_cc;
return(0);