]> git.proxmox.com Git - qemu.git/blobdiff - slirp/tcp_subr.c
slirp: Replace m_freem with m_free
[qemu.git] / slirp / tcp_subr.c
index 219f1dd00557c3c0acf595ca446c0818d9cdef9a..61079b1b2d9121567256d4162b5448e906005d36 100644 (file)
  * Tcp initialization
  */
 void
-tcp_init(void)
+tcp_init(Slirp *slirp)
 {
-       tcp_iss = 1;            /* wrong */
-       tcb.so_next = tcb.so_prev = &tcb;
+    slirp->tcp_iss = 1;                /* wrong */
+    slirp->tcb.so_next = slirp->tcb.so_prev = &slirp->tcb;
+    slirp->tcp_last_so = &slirp->tcb;
 }
 
 /*
@@ -60,7 +61,6 @@ tcp_init(void)
  * in a skeletal tcp/ip header, minimizing the amount of work
  * necessary when the connection is used.
  */
-/* struct tcpiphdr * */
 void
 tcp_template(struct tcpcb *tp)
 {
@@ -117,13 +117,9 @@ tcp_respond(struct tcpcb *tp, struct tcpiphdr *ti, struct mbuf *m,
        if (tp)
                win = sbspace(&tp->t_socket->so_rcv);
         if (m == NULL) {
-               if ((m = m_get()) == NULL)
+               if ((m = m_get(tp->t_socket->slirp)) == NULL)
                        return;
-#ifdef TCP_COMPAT_42
-               tlen = 1;
-#else
                tlen = 0;
-#endif
                m->m_data += IF_MAXLINKHDR;
                *mtod(m, struct tcpiphdr *) = *ti;
                ti = mtod(m, struct tcpiphdr *);
@@ -138,8 +134,8 @@ tcp_respond(struct tcpcb *tp, struct tcpiphdr *ti, struct mbuf *m,
                m->m_len = sizeof (struct tcpiphdr);
                tlen = 0;
 #define xchg(a,b,type) { type t; t=a; a=b; b=t; }
-               xchg(ti->ti_dst.s_addr, ti->ti_src.s_addr, u_int32_t);
-               xchg(ti->ti_dport, ti->ti_sport, u_int16_t);
+               xchg(ti->ti_dst.s_addr, ti->ti_src.s_addr, uint32_t);
+               xchg(ti->ti_dport, ti->ti_sport, uint16_t);
 #undef xchg
        }
        ti->ti_len = htons((u_short)(sizeof (struct tcphdr) + tlen));
@@ -154,9 +150,9 @@ tcp_respond(struct tcpcb *tp, struct tcpiphdr *ti, struct mbuf *m,
        ti->ti_off = sizeof (struct tcphdr) >> 2;
        ti->ti_flags = flags;
        if (tp)
-               ti->ti_win = htons((u_int16_t) (win >> tp->rcv_scale));
+               ti->ti_win = htons((uint16_t) (win >> tp->rcv_scale));
        else
-               ti->ti_win = htons((u_int16_t)win);
+               ti->ti_win = htons((uint16_t)win);
        ti->ti_urp = 0;
        ti->ti_sum = 0;
        ti->ti_sum = cksum(m, tlen);
@@ -220,12 +216,6 @@ tcp_newtcpcb(struct socket *so)
  */
 struct tcpcb *tcp_drop(struct tcpcb *tp, int err)
 {
-/* tcp_drop(tp, errno)
-       register struct tcpcb *tp;
-       int errno;
-{
-*/
-
        DEBUG_CALL("tcp_drop");
        DEBUG_ARG("tp = %lx", (long)tp);
        DEBUG_ARG("errno = %d", errno);
@@ -233,13 +223,7 @@ struct tcpcb *tcp_drop(struct tcpcb *tp, int err)
        if (TCPS_HAVERCVDSYN(tp->t_state)) {
                tp->t_state = TCPS_CLOSED;
                (void) tcp_output(tp);
-               STAT(tcpstat.tcps_drops++);
-       } else
-               STAT(tcpstat.tcps_conndrops++);
-/*     if (errno == ETIMEDOUT && tp->t_softerror)
- *             errno = tp->t_softerror;
- */
-/*     so->so_error = errno; */
+       }
        return (tcp_close(tp));
 }
 
@@ -254,6 +238,7 @@ tcp_close(struct tcpcb *tp)
 {
        register struct tcpiphdr *t;
        struct socket *so = tp->t_socket;
+       Slirp *slirp = so->slirp;
        register struct mbuf *m;
 
        DEBUG_CALL("tcp_close");
@@ -265,51 +250,20 @@ tcp_close(struct tcpcb *tp)
                t = tcpiphdr_next(t);
                m = tcpiphdr_prev(t)->ti_mbuf;
                remque(tcpiphdr2qlink(tcpiphdr_prev(t)));
-               m_freem(m);
+               m_free(m);
        }
-       /* It's static */
-/*     if (tp->t_template)
- *             (void) m_free(dtom(tp->t_template));
- */
-/*     free(tp, M_PCB);  */
        free(tp);
         so->so_tcpcb = NULL;
-       soisfdisconnected(so);
        /* clobber input socket cache if we're closing the cached connection */
-       if (so == tcp_last_so)
-               tcp_last_so = &tcb;
+       if (so == slirp->tcp_last_so)
+               slirp->tcp_last_so = &slirp->tcb;
        closesocket(so->s);
        sbfree(&so->so_rcv);
        sbfree(&so->so_snd);
        sofree(so);
-       STAT(tcpstat.tcps_closed++);
        return ((struct tcpcb *)0);
 }
 
-#ifdef notdef
-void
-tcp_drain()
-{
-       /* XXX */
-}
-
-/*
- * When a source quench is received, close congestion window
- * to one segment.  We will gradually open it again as we proceed.
- */
-void
-tcp_quench(i, errno)
-
-       int errno;
-{
-       struct tcpcb *tp = intotcpcb(inp);
-
-       if (tp)
-               tp->snd_cwnd = tp->t_maxseg;
-}
-
-#endif /* notdef */
-
 /*
  * TCP protocol interface to socket abstraction.
  */
@@ -349,9 +303,6 @@ tcp_sockclosed(struct tcpcb *tp)
                tp->t_state = TCPS_LAST_ACK;
                break;
        }
-/*     soisfdisconnecting(tp->t_socket); */
-       if (tp && tp->t_state >= TCPS_FIN_WAIT_2)
-               soisfdisconnected(tp->t_socket);
        if (tp)
                tcp_output(tp);
 }
@@ -368,12 +319,13 @@ tcp_sockclosed(struct tcpcb *tp)
  */
 int tcp_fconnect(struct socket *so)
 {
+  Slirp *slirp = so->slirp;
   int ret=0;
 
   DEBUG_CALL("tcp_fconnect");
   DEBUG_ARG("so = %lx", (long )so);
 
-  if( (ret=so->s=socket(AF_INET,SOCK_STREAM,0)) >= 0) {
+  if( (ret = so->s = qemu_socket(AF_INET,SOCK_STREAM,0)) >= 0) {
     int opt, s=so->s;
     struct sockaddr_in addr;
 
@@ -384,10 +336,12 @@ int tcp_fconnect(struct socket *so)
     setsockopt(s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(opt ));
 
     addr.sin_family = AF_INET;
-    if ((so->so_faddr.s_addr & vnetwork_mask.s_addr) == vnetwork_addr.s_addr) {
+    if ((so->so_faddr.s_addr & slirp->vnetwork_mask.s_addr) ==
+        slirp->vnetwork_addr.s_addr) {
       /* It's an alias */
-      if (so->so_faddr.s_addr == vnameserver_addr.s_addr) {
-       addr.sin_addr = dns_addr;
+      if (so->so_faddr.s_addr == slirp->vnameserver_addr.s_addr) {
+       if (get_dns_addr(&addr.sin_addr) < 0)
+         addr.sin_addr = loopback_addr;
       } else {
        addr.sin_addr = loopback_addr;
       }
@@ -426,6 +380,7 @@ int tcp_fconnect(struct socket *so)
 void
 tcp_connect(struct socket *inso)
 {
+       Slirp *slirp = inso->slirp;
        struct socket *so;
        struct sockaddr_in addr;
        socklen_t addrlen = sizeof(struct sockaddr_in);
@@ -443,7 +398,7 @@ tcp_connect(struct socket *inso)
                /* FACCEPTONCE already have a tcpcb */
                so = inso;
        } else {
-               if ((so = socreate()) == NULL) {
+               if ((so = socreate(slirp)) == NULL) {
                        /* If it failed, get rid of the pending connection */
                        closesocket(accept(inso->s,(struct sockaddr *)&addr,&addrlen));
                        return;
@@ -474,7 +429,7 @@ tcp_connect(struct socket *inso)
        so->so_faddr = addr.sin_addr;
        /* Translate connections from localhost to the real hostname */
        if (so->so_faddr.s_addr == 0 || so->so_faddr.s_addr == loopback_addr.s_addr)
-          so->so_faddr = vhost_addr;
+          so->so_faddr = slirp->vhost_addr;
 
        /* Close the accept() socket, set right state */
        if (inso->so_state & SS_FACCEPTONCE) {
@@ -490,19 +445,10 @@ tcp_connect(struct socket *inso)
 
        tcp_template(tp);
 
-       /* Compute window scaling to request.  */
-/*     while (tp->request_r_scale < TCP_MAX_WINSHIFT &&
- *             (TCP_MAXWIN << tp->request_r_scale) < so->so_rcv.sb_hiwat)
- *             tp->request_r_scale++;
- */
-
-/*     soisconnecting(so); */ /* NOFDREF used instead */
-       STAT(tcpstat.tcps_connattempt++);
-
        tp->t_state = TCPS_SYN_SENT;
        tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT;
-       tp->iss = tcp_iss;
-       tcp_iss += TCP_ISSINCR/2;
+       tp->iss = slirp->tcp_iss;
+       slirp->tcp_iss += TCP_ISSINCR/2;
        tcp_sendseqinit(tp);
        tcp_output(tp);
 }
@@ -516,7 +462,7 @@ tcp_attach(struct socket *so)
        if ((so->so_tcpcb = tcp_newtcpcb(so)) == NULL)
           return -1;
 
-       insque(so, &tcb);
+       insque(so, &so->slirp->tcb);
 
        return 0;
 }
@@ -540,15 +486,12 @@ static const struct tos_t tcptos[] = {
          {0, 0, 0, 0}
 };
 
-#ifdef CONFIG_QEMU
-static
-#endif
-struct emu_t *tcpemu = NULL;
+static struct emu_t *tcpemu = NULL;
 
 /*
  * Return TOS according to the above table
  */
-u_int8_t
+uint8_t
 tcp_tos(struct socket *so)
 {
        int i = 0;
@@ -575,10 +518,6 @@ tcp_tos(struct socket *so)
        return 0;
 }
 
-#if 0
-int do_echo = -1;
-#endif
-
 /*
  * Emulate programs that try and connect to us
  * This includes ftp (the data connection is
@@ -606,9 +545,10 @@ int do_echo = -1;
 int
 tcp_emu(struct socket *so, struct mbuf *m)
 {
+       Slirp *slirp = so->slirp;
        u_int n1, n2, n3, n4, n5, n6;
         char buff[257];
-       u_int32_t laddr;
+       uint32_t laddr;
        u_int lport;
        char *bptr;
 
@@ -639,7 +579,9 @@ tcp_emu(struct socket *so, struct mbuf *m)
                                        HTONS(n1);
                                        HTONS(n2);
                                        /* n2 is the one on our host */
-                                       for (tmpso = tcb.so_next; tmpso != &tcb; tmpso = tmpso->so_next) {
+                                       for (tmpso = slirp->tcb.so_next;
+                                            tmpso != &slirp->tcb;
+                                            tmpso = tmpso->so_next) {
                                                if (tmpso->so_laddr.s_addr == so->so_laddr.s_addr &&
                                                    tmpso->so_lport == n2 &&
                                                    tmpso->so_faddr.s_addr == so->so_faddr.s_addr &&
@@ -661,302 +603,6 @@ tcp_emu(struct socket *so, struct mbuf *m)
                        return 0;
                }
 
-#if 0
-        case EMU_RLOGIN:
-               /*
-                * Rlogin emulation
-                * First we accumulate all the initial option negotiation,
-                * then fork_exec() rlogin according to the  options
-                */
-               {
-                       int i, i2, n;
-                       char *ptr;
-                       char args[100];
-                       char term[100];
-                       struct sbuf *so_snd = &so->so_snd;
-                       struct sbuf *so_rcv = &so->so_rcv;
-
-                       /* First check if they have a priveladged port, or too much data has arrived */
-                       if (ntohs(so->so_lport) > 1023 || ntohs(so->so_lport) < 512 ||
-                           (m->m_len + so_rcv->sb_wptr) > (so_rcv->sb_data + so_rcv->sb_datalen)) {
-                               memcpy(so_snd->sb_wptr, "Permission denied\n", 18);
-                               so_snd->sb_wptr += 18;
-                               so_snd->sb_cc += 18;
-                               tcp_sockclosed(sototcpcb(so));
-                               m_free(m);
-                               return 0;
-                       }
-
-                       /* Append the current data */
-                       memcpy(so_rcv->sb_wptr, m->m_data, m->m_len);
-                       so_rcv->sb_wptr += m->m_len;
-                       so_rcv->sb_rptr += m->m_len;
-                       m_free(m);
-
-                       /*
-                        * Check if we have all the initial options,
-                        * and build argument list to rlogin while we're here
-                        */
-                       n = 0;
-                       ptr = so_rcv->sb_data;
-                       args[0] = 0;
-                       term[0] = 0;
-                       while (ptr < so_rcv->sb_wptr) {
-                               if (*ptr++ == 0) {
-                                       n++;
-                                       if (n == 2) {
-                                               sprintf(args, "rlogin -l %s %s",
-                                                       ptr, inet_ntoa(so->so_faddr));
-                                       } else if (n == 3) {
-                                               i2 = so_rcv->sb_wptr - ptr;
-                                               for (i = 0; i < i2; i++) {
-                                                       if (ptr[i] == '/') {
-                                                               ptr[i] = 0;
-#ifdef HAVE_SETENV
-                                                               sprintf(term, "%s", ptr);
-#else
-                                                               sprintf(term, "TERM=%s", ptr);
-#endif
-                                                               ptr[i] = '/';
-                                                               break;
-                                                       }
-                                               }
-                                       }
-                               }
-                       }
-
-                       if (n != 4)
-                          return 0;
-
-                       /* We have it, set our term variable and fork_exec() */
-#ifdef HAVE_SETENV
-                       setenv("TERM", term, 1);
-#else
-                       putenv(term);
-#endif
-                       fork_exec(so, args, 2);
-                       term[0] = 0;
-                       so->so_emu = 0;
-
-                       /* And finally, send the client a 0 character */
-                       so_snd->sb_wptr[0] = 0;
-                       so_snd->sb_wptr++;
-                       so_snd->sb_cc++;
-
-                       return 0;
-               }
-
-        case EMU_RSH:
-               /*
-                * rsh emulation
-                * First we accumulate all the initial option negotiation,
-                * then rsh_exec() rsh according to the  options
-                */
-               {
-                       int  n;
-                       char *ptr;
-                       char *user;
-                       char *args;
-                       struct sbuf *so_snd = &so->so_snd;
-                       struct sbuf *so_rcv = &so->so_rcv;
-
-                       /* First check if they have a priveladged port, or too much data has arrived */
-                       if (ntohs(so->so_lport) > 1023 || ntohs(so->so_lport) < 512 ||
-                           (m->m_len + so_rcv->sb_wptr) > (so_rcv->sb_data + so_rcv->sb_datalen)) {
-                               memcpy(so_snd->sb_wptr, "Permission denied\n", 18);
-                               so_snd->sb_wptr += 18;
-                               so_snd->sb_cc += 18;
-                               tcp_sockclosed(sototcpcb(so));
-                               m_free(m);
-                               return 0;
-                       }
-
-                       /* Append the current data */
-                       memcpy(so_rcv->sb_wptr, m->m_data, m->m_len);
-                       so_rcv->sb_wptr += m->m_len;
-                       so_rcv->sb_rptr += m->m_len;
-                       m_free(m);
-
-                       /*
-                        * Check if we have all the initial options,
-                        * and build argument list to rlogin while we're here
-                        */
-                       n = 0;
-                       ptr = so_rcv->sb_data;
-                       user="";
-                       args="";
-                       if (so->extra==NULL) {
-                               struct socket *ns;
-                               struct tcpcb* tp;
-                               int port=atoi(ptr);
-                               if (port <= 0) return 0;
-                if (port > 1023 || port < 512) {
-                  memcpy(so_snd->sb_wptr, "Permission denied\n", 18);
-                  so_snd->sb_wptr += 18;
-                  so_snd->sb_cc += 18;
-                  tcp_sockclosed(sototcpcb(so));
-                  return 0;
-                }
-                               if ((ns=socreate()) == NULL)
-                  return 0;
-                               if (tcp_attach(ns)<0) {
-                  free(ns);
-                  return 0;
-                               }
-
-                               ns->so_laddr=so->so_laddr;
-                               ns->so_lport=htons(port);
-
-                               (void) tcp_mss(sototcpcb(ns), 0);
-
-                               ns->so_faddr=so->so_faddr;
-                               ns->so_fport=htons(IPPORT_RESERVED-1); /* Use a fake port. */
-
-                               if (ns->so_faddr.s_addr == 0 ||
-                                       ns->so_faddr.s_addr == loopback_addr.s_addr)
-                  ns->so_faddr = alias_addr;
-
-                               ns->so_iptos = tcp_tos(ns);
-                               tp = sototcpcb(ns);
-
-                               tcp_template(tp);
-
-                               /* Compute window scaling to request.  */
-                               /*      while (tp->request_r_scale < TCP_MAX_WINSHIFT &&
-                                *              (TCP_MAXWIN << tp->request_r_scale) < so->so_rcv.sb_hiwat)
-                                *              tp->request_r_scale++;
-                                */
-
-                /*soisfconnecting(ns);*/
-
-                               STAT(tcpstat.tcps_connattempt++);
-
-                               tp->t_state = TCPS_SYN_SENT;
-                               tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT;
-                               tp->iss = tcp_iss;
-                               tcp_iss += TCP_ISSINCR/2;
-                               tcp_sendseqinit(tp);
-                               tcp_output(tp);
-                               so->extra=ns;
-                       }
-                       while (ptr < so_rcv->sb_wptr) {
-              if (*ptr++ == 0) {
-                n++;
-                if (n == 2) {
-                  user=ptr;
-                } else if (n == 3) {
-                  args=ptr;
-                }
-              }
-                       }
-
-                       if (n != 4)
-              return 0;
-
-                       rsh_exec(so,so->extra, user, inet_ntoa(so->so_faddr), args);
-                       so->so_emu = 0;
-                       so->extra=NULL;
-
-                       /* And finally, send the client a 0 character */
-                       so_snd->sb_wptr[0] = 0;
-                       so_snd->sb_wptr++;
-                       so_snd->sb_cc++;
-
-                       return 0;
-               }
-
-        case EMU_CTL:
-               {
-                       int num;
-                       struct sbuf *so_snd = &so->so_snd;
-                       struct sbuf *so_rcv = &so->so_rcv;
-
-                       /*
-                        * If there is binary data here, we save it in so->so_m
-                        */
-                       if (!so->so_m) {
-                         int rxlen;
-                         char *rxdata;
-                         rxdata=mtod(m, char *);
-                         for (rxlen=m->m_len; rxlen; rxlen--) {
-                           if (*rxdata++ & 0x80) {
-                             so->so_m = m;
-                             return 0;
-                           }
-                         }
-                       } /* if(so->so_m==NULL) */
-
-                       /*
-                        * Append the line
-                        */
-                       sbappendsb(so_rcv, m);
-
-                       /* To avoid going over the edge of the buffer, we reset it */
-                       if (so_snd->sb_cc == 0)
-                          so_snd->sb_wptr = so_snd->sb_rptr = so_snd->sb_data;
-
-                       /*
-                        * A bit of a hack:
-                        * If the first packet we get here is 1 byte long, then it
-                        * was done in telnet character mode, therefore we must echo
-                        * the characters as they come.  Otherwise, we echo nothing,
-                        * because in linemode, the line is already echoed
-                        * XXX two or more control connections won't work
-                        */
-                       if (do_echo == -1) {
-                               if (m->m_len == 1) do_echo = 1;
-                               else do_echo = 0;
-                       }
-                       if (do_echo) {
-                         sbappendsb(so_snd, m);
-                         m_free(m);
-                         tcp_output(sototcpcb(so)); /* XXX */
-                       } else
-                         m_free(m);
-
-                       num = 0;
-                       while (num < so->so_rcv.sb_cc) {
-                               if (*(so->so_rcv.sb_rptr + num) == '\n' ||
-                                   *(so->so_rcv.sb_rptr + num) == '\r') {
-                                       int n;
-
-                                       *(so_rcv->sb_rptr + num) = 0;
-                                       if (ctl_password && !ctl_password_ok) {
-                                               /* Need a password */
-                                               if (sscanf(so_rcv->sb_rptr, "pass %256s", buff) == 1) {
-                                                       if (strcmp(buff, ctl_password) == 0) {
-                                                               ctl_password_ok = 1;
-                                                               n = sprintf(so_snd->sb_wptr,
-                                                                           "Password OK.\r\n");
-                                                               goto do_prompt;
-                                                       }
-                                               }
-                                               n = sprintf(so_snd->sb_wptr,
-                                        "Error: Password required, log on with \"pass PASSWORD\"\r\n");
-                                               goto do_prompt;
-                                       }
-                                       cfg_quitting = 0;
-                                       n = do_config(so_rcv->sb_rptr, so, PRN_SPRINTF);
-                                       if (!cfg_quitting) {
-                                               /* Register the printed data */
-do_prompt:
-                                               so_snd->sb_cc += n;
-                                               so_snd->sb_wptr += n;
-                                               /* Add prompt */
-                                               n = sprintf(so_snd->sb_wptr, "Slirp> ");
-                                               so_snd->sb_cc += n;
-                                               so_snd->sb_wptr += n;
-                                       }
-                                       /* Drop so_rcv data */
-                                       so_rcv->sb_cc = 0;
-                                       so_rcv->sb_wptr = so_rcv->sb_rptr = so_rcv->sb_data;
-                                       tcp_output(sototcpcb(so)); /* Send the reply */
-                               }
-                               num++;
-                       }
-                       return 0;
-               }
-#endif
         case EMU_FTP: /* ftp */
                 *(m->m_data+m->m_len) = 0; /* NUL terminate for strstr */
                if ((bptr = (char *)strstr(m->m_data, "ORT")) != NULL) {
@@ -971,9 +617,10 @@ do_prompt:
                        laddr = htonl((n1 << 24) | (n2 << 16) | (n3 << 8) | (n4));
                        lport = htons((n5 << 8) | (n6));
 
-                       if ((so = tcp_listen(INADDR_ANY, 0, laddr, lport, SS_FACCEPTONCE)) == NULL)
+                       if ((so = tcp_listen(slirp, INADDR_ANY, 0, laddr,
+                                            lport, SS_FACCEPTONCE)) == NULL) {
                           return 1;
-
+                       }
                        n6 = ntohs(so->so_fport);
 
                        n5 = (n6 >> 8) & 0xff;
@@ -1003,9 +650,10 @@ do_prompt:
                        laddr = htonl((n1 << 24) | (n2 << 16) | (n3 << 8) | (n4));
                        lport = htons((n5 << 8) | (n6));
 
-                       if ((so = tcp_listen(INADDR_ANY, 0, laddr, lport, SS_FACCEPTONCE)) == NULL)
+                       if ((so = tcp_listen(slirp, INADDR_ANY, 0, laddr,
+                                            lport, SS_FACCEPTONCE)) == NULL) {
                           return 1;
-
+                       }
                        n6 = ntohs(so->so_fport);
 
                        n5 = (n6 >> 8) & 0xff;
@@ -1043,7 +691,8 @@ do_prompt:
                        lport += m->m_data[i] - '0';
                }
                if (m->m_data[m->m_len-1] == '\0' && lport != 0 &&
-                   (so = tcp_listen(INADDR_ANY, 0, so->so_laddr.s_addr, htons(lport), SS_FACCEPTONCE)) != NULL)
+                   (so = tcp_listen(slirp, INADDR_ANY, 0, so->so_laddr.s_addr,
+                                    htons(lport), SS_FACCEPTONCE)) != NULL)
                     m->m_len = snprintf(m->m_data, m->m_hdr.mh_size, "%d",
                                         ntohs(so->so_fport)) + 1;
                return 1;
@@ -1058,27 +707,33 @@ do_prompt:
 
                /* The %256s is for the broken mIRC */
                if (sscanf(bptr, "DCC CHAT %256s %u %u", buff, &laddr, &lport) == 3) {
-                       if ((so = tcp_listen(INADDR_ANY, 0, htonl(laddr), htons(lport), SS_FACCEPTONCE)) == NULL)
+                       if ((so = tcp_listen(slirp, INADDR_ANY, 0,
+                                            htonl(laddr), htons(lport),
+                                            SS_FACCEPTONCE)) == NULL) {
                                return 1;
-
+                       }
                        m->m_len = bptr - m->m_data; /* Adjust length */
                         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 = tcp_listen(INADDR_ANY, 0, htonl(laddr), htons(lport), SS_FACCEPTONCE)) == NULL)
+                       if ((so = tcp_listen(slirp, INADDR_ANY, 0,
+                                            htonl(laddr), htons(lport),
+                                            SS_FACCEPTONCE)) == NULL) {
                                return 1;
-
+                       }
                        m->m_len = bptr - m->m_data; /* Adjust length */
                         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 = tcp_listen(INADDR_ANY, 0, htonl(laddr), htons(lport), SS_FACCEPTONCE)) == NULL)
+                       if ((so = tcp_listen(slirp, INADDR_ANY, 0,
+                                            htonl(laddr), htons(lport),
+                                            SS_FACCEPTONCE)) == NULL) {
                                return 1;
-
+                       }
                        m->m_len = bptr - m->m_data; /* Adjust length */
                         m->m_len += snprintf(bptr, m->m_hdr.mh_size,
                                              "DCC MOVE %s %lu %u %u%c\n", buff,
@@ -1100,7 +755,7 @@ do_prompt:
                 * A typical packet for player version 1.0 (release version):
                 *
                 * 0000:50 4E 41 00 05
-                * 0000:00 01 00 02 1B D7 00 00 67 E6 6C DC 63 00 12 50 .....×..gælÜc..P
+                * 0000:00 01 00 02 1B D7 00 00 67 E6 6C DC 63 00 12 50 ........g.l.c..P
                 * 0010:4E 43 4C 49 45 4E 54 20 31 30 31 20 41 4C 50 48 NCLIENT 101 ALPH
                 * 0020:41 6C 00 00 52 00 17 72 61 66 69 6C 65 73 2F 76 Al..R..rafiles/v
                 * 0030:6F 61 2F 65 6E 67 6C 69 73 68 5F 2E 72 61 79 42 oa/english_.rayB
@@ -1112,8 +767,8 @@ do_prompt:
                 *
                 * A typical packet for player version 2.0 (beta):
                 *
-                * 0000:50 4E 41 00 06 00 02 00 00 00 01 00 02 1B C1 00 PNA...........Á.
-                * 0010:00 67 75 78 F5 63 00 0A 57 69 6E 32 2E 30 2E 30 .guxõc..Win2.0.0
+                * 0000:50 4E 41 00 06 00 02 00 00 00 01 00 02 1B C1 00 PNA.............
+                * 0010:00 67 75 78 F5 63 00 0A 57 69 6E 32 2E 30 2E 30 .gux.c..Win2.0.0
                 * 0020:2E 35 6C 00 00 52 00 1C 72 61 66 69 6C 65 73 2F .5l..R..rafiles/
                 * 0030:77 65 62 73 69 74 65 2F 32 30 72 65 6C 65 61 73 website/20releas
                 * 0040:65 2E 72 61 79 53 00 00 06 36 42                e.rayS...6B
@@ -1191,7 +846,7 @@ do_prompt:
 
                                /* try to get udp port between 6970 - 7170 */
                                for (p = 6970; p < 7071; p++) {
-                                       if (udp_listen(INADDR_ANY,
+                                       if (udp_listen(slirp, INADDR_ANY,
                                                       htons(p),
                                                       so->so_laddr.s_addr,
                                                       htons(lport),
@@ -1202,7 +857,7 @@ do_prompt:
                                if (p == 7071)
                                   p = 0;
                                *(u_char *)bptr++ = (p >> 8) & 0xff;
-                               *(u_char *)bptr++ = p & 0xff;
+                                *(u_char *)bptr = p & 0xff;
                                ra = 0;
                                return 1;   /* port redirected, we're done */
                                break;
@@ -1228,6 +883,7 @@ do_prompt:
  */
 int tcp_ctl(struct socket *so)
 {
+    Slirp *slirp = so->slirp;
     struct sbuf *sb = &so->so_snd;
     struct ex_list *ex_ptr;
     int do_pty;
@@ -1235,9 +891,9 @@ int tcp_ctl(struct socket *so)
     DEBUG_CALL("tcp_ctl");
     DEBUG_ARG("so = %lx", (long )so);
 
-    if (so->so_faddr.s_addr != vhost_addr.s_addr) {
+    if (so->so_faddr.s_addr != slirp->vhost_addr.s_addr) {
         /* Check if it's pty_exec */
-        for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
+        for (ex_ptr = slirp->exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
             if (ex_ptr->ex_fport == so->so_fport &&
                 so->so_faddr.s_addr == ex_ptr->ex_addr.s_addr) {
                 if (ex_ptr->ex_pty == 3) {