allow SLIRP to make an ARP request to get the client MAC address. It is useful if...
[qemu] / slirp / slirp.c
1 #include "slirp.h"
2
3 /* host address */
4 struct in_addr our_addr;
5 /* host dns address */
6 struct in_addr dns_addr;
7 /* host loopback address */
8 struct in_addr loopback_addr;
9
10 /* address for slirp virtual addresses */
11 struct in_addr special_addr;
12 /* virtual address alias for host */
13 struct in_addr alias_addr;
14
15 static const uint8_t special_ethaddr[6] = {
16     0x52, 0x54, 0x00, 0x12, 0x35, 0x00
17 };
18
19 /* ARP cache for the guest IP addresses (XXX: allow many entries) */
20 uint8_t client_ethaddr[6];
21 static struct in_addr client_ipaddr;
22
23 static const uint8_t zero_ethaddr[6] = { 0, 0, 0, 0, 0, 0 };
24
25 int do_slowtimo;
26 int link_up;
27 struct timeval tt;
28 FILE *lfd;
29 struct ex_list *exec_list;
30
31 /* XXX: suppress those select globals */
32 fd_set *global_readfds, *global_writefds, *global_xfds;
33
34 char slirp_hostname[33];
35
36 #ifdef _WIN32
37
38 static int get_dns_addr(struct in_addr *pdns_addr)
39 {
40     FIXED_INFO *FixedInfo=NULL;
41     ULONG    BufLen;
42     DWORD    ret;
43     IP_ADDR_STRING *pIPAddr;
44     struct in_addr tmp_addr;
45
46     FixedInfo = (FIXED_INFO *)GlobalAlloc(GPTR, sizeof(FIXED_INFO));
47     BufLen = sizeof(FIXED_INFO);
48
49     if (ERROR_BUFFER_OVERFLOW == GetNetworkParams(FixedInfo, &BufLen)) {
50         if (FixedInfo) {
51             GlobalFree(FixedInfo);
52             FixedInfo = NULL;
53         }
54         FixedInfo = GlobalAlloc(GPTR, BufLen);
55     }
56
57     if ((ret = GetNetworkParams(FixedInfo, &BufLen)) != ERROR_SUCCESS) {
58         printf("GetNetworkParams failed. ret = %08x\n", (u_int)ret );
59         if (FixedInfo) {
60             GlobalFree(FixedInfo);
61             FixedInfo = NULL;
62         }
63         return -1;
64     }
65
66     pIPAddr = &(FixedInfo->DnsServerList);
67     inet_aton(pIPAddr->IpAddress.String, &tmp_addr);
68     *pdns_addr = tmp_addr;
69 #if 0
70     printf( "DNS Servers:\n" );
71     printf( "DNS Addr:%s\n", pIPAddr->IpAddress.String );
72
73     pIPAddr = FixedInfo -> DnsServerList.Next;
74     while ( pIPAddr ) {
75             printf( "DNS Addr:%s\n", pIPAddr ->IpAddress.String );
76             pIPAddr = pIPAddr ->Next;
77     }
78 #endif
79     if (FixedInfo) {
80         GlobalFree(FixedInfo);
81         FixedInfo = NULL;
82     }
83     return 0;
84 }
85
86 #else
87
88 static int get_dns_addr(struct in_addr *pdns_addr)
89 {
90     char buff[512];
91     char buff2[257];
92     FILE *f;
93     int found = 0;
94     struct in_addr tmp_addr;
95
96     f = fopen("/etc/resolv.conf", "r");
97     if (!f)
98         return -1;
99
100 #ifdef DEBUG
101     lprint("IP address of your DNS(s): ");
102 #endif
103     while (fgets(buff, 512, f) != NULL) {
104         if (sscanf(buff, "nameserver%*[ \t]%256s", buff2) == 1) {
105             if (!inet_aton(buff2, &tmp_addr))
106                 continue;
107             if (tmp_addr.s_addr == loopback_addr.s_addr)
108                 tmp_addr = our_addr;
109             /* If it's the first one, set it to dns_addr */
110             if (!found)
111                 *pdns_addr = tmp_addr;
112 #ifdef DEBUG
113             else
114                 lprint(", ");
115 #endif
116             if (++found > 3) {
117 #ifdef DEBUG
118                 lprint("(more)");
119 #endif
120                 break;
121             }
122 #ifdef DEBUG
123             else
124                 lprint("%s", inet_ntoa(tmp_addr));
125 #endif
126         }
127     }
128     fclose(f);
129     if (!found)
130         return -1;
131     return 0;
132 }
133
134 #endif
135
136 #ifdef _WIN32
137 static void slirp_cleanup(void)
138 {
139     WSACleanup();
140 }
141 #endif
142
143 void slirp_init(void)
144 {
145     //    debug_init("/tmp/slirp.log", DEBUG_DEFAULT);
146
147 #ifdef _WIN32
148     {
149         WSADATA Data;
150         WSAStartup(MAKEWORD(2,0), &Data);
151         atexit(slirp_cleanup);
152     }
153 #endif
154
155     link_up = 1;
156
157     if_init();
158     ip_init();
159
160     /* Initialise mbufs *after* setting the MTU */
161     m_init();
162
163     /* set default addresses */
164     inet_aton("127.0.0.1", &loopback_addr);
165
166     if (get_dns_addr(&dns_addr) < 0) {
167         dns_addr = loopback_addr;
168         fprintf (stderr, "Warning: No DNS servers found\n");
169     }
170
171     inet_aton(CTL_SPECIAL, &special_addr);
172     alias_addr.s_addr = special_addr.s_addr | htonl(CTL_ALIAS);
173     getouraddr();
174 }
175
176 #define CONN_CANFSEND(so) (((so)->so_state & (SS_FCANTSENDMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED)
177 #define CONN_CANFRCV(so) (((so)->so_state & (SS_FCANTRCVMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED)
178 #define UPD_NFDS(x) if (nfds < (x)) nfds = (x)
179
180 /*
181  * curtime kept to an accuracy of 1ms
182  */
183 #ifdef _WIN32
184 static void updtime(void)
185 {
186     struct _timeb tb;
187
188     _ftime(&tb);
189     curtime = (u_int)tb.time * (u_int)1000;
190     curtime += (u_int)tb.millitm;
191 }
192 #else
193 static void updtime(void)
194 {
195         gettimeofday(&tt, 0);
196
197         curtime = (u_int)tt.tv_sec * (u_int)1000;
198         curtime += (u_int)tt.tv_usec / (u_int)1000;
199
200         if ((tt.tv_usec % 1000) >= 500)
201            curtime++;
202 }
203 #endif
204
205 void slirp_select_fill(int *pnfds,
206                        fd_set *readfds, fd_set *writefds, fd_set *xfds)
207 {
208     struct socket *so, *so_next;
209     struct timeval timeout;
210     int nfds;
211     int tmp_time;
212
213     /* fail safe */
214     global_readfds = NULL;
215     global_writefds = NULL;
216     global_xfds = NULL;
217
218     nfds = *pnfds;
219         /*
220          * First, TCP sockets
221          */
222         do_slowtimo = 0;
223         if (link_up) {
224                 /*
225                  * *_slowtimo needs calling if there are IP fragments
226                  * in the fragment queue, or there are TCP connections active
227                  */
228                 do_slowtimo = ((tcb.so_next != &tcb) ||
229                                ((struct ipasfrag *)&ipq != (struct ipasfrag *)ipq.next));
230
231                 for (so = tcb.so_next; so != &tcb; so = so_next) {
232                         so_next = so->so_next;
233
234                         /*
235                          * See if we need a tcp_fasttimo
236                          */
237                         if (time_fasttimo == 0 && so->so_tcpcb->t_flags & TF_DELACK)
238                            time_fasttimo = curtime; /* Flag when we want a fasttimo */
239
240                         /*
241                          * NOFDREF can include still connecting to local-host,
242                          * newly socreated() sockets etc. Don't want to select these.
243                          */
244                         if (so->so_state & SS_NOFDREF || so->s == -1)
245                            continue;
246
247                         /*
248                          * Set for reading sockets which are accepting
249                          */
250                         if (so->so_state & SS_FACCEPTCONN) {
251                                 FD_SET(so->s, readfds);
252                                 UPD_NFDS(so->s);
253                                 continue;
254                         }
255
256                         /*
257                          * Set for writing sockets which are connecting
258                          */
259                         if (so->so_state & SS_ISFCONNECTING) {
260                                 FD_SET(so->s, writefds);
261                                 UPD_NFDS(so->s);
262                                 continue;
263                         }
264
265                         /*
266                          * Set for writing if we are connected, can send more, and
267                          * we have something to send
268                          */
269                         if (CONN_CANFSEND(so) && so->so_rcv.sb_cc) {
270                                 FD_SET(so->s, writefds);
271                                 UPD_NFDS(so->s);
272                         }
273
274                         /*
275                          * Set for reading (and urgent data) if we are connected, can
276                          * receive more, and we have room for it XXX /2 ?
277                          */
278                         if (CONN_CANFRCV(so) && (so->so_snd.sb_cc < (so->so_snd.sb_datalen/2))) {
279                                 FD_SET(so->s, readfds);
280                                 FD_SET(so->s, xfds);
281                                 UPD_NFDS(so->s);
282                         }
283                 }
284
285                 /*
286                  * UDP sockets
287                  */
288                 for (so = udb.so_next; so != &udb; so = so_next) {
289                         so_next = so->so_next;
290
291                         /*
292                          * See if it's timed out
293                          */
294                         if (so->so_expire) {
295                                 if (so->so_expire <= curtime) {
296                                         udp_detach(so);
297                                         continue;
298                                 } else
299                                         do_slowtimo = 1; /* Let socket expire */
300                         }
301
302                         /*
303                          * When UDP packets are received from over the
304                          * link, they're sendto()'d straight away, so
305                          * no need for setting for writing
306                          * Limit the number of packets queued by this session
307                          * to 4.  Note that even though we try and limit this
308                          * to 4 packets, the session could have more queued
309                          * if the packets needed to be fragmented
310                          * (XXX <= 4 ?)
311                          */
312                         if ((so->so_state & SS_ISFCONNECTED) && so->so_queued <= 4) {
313                                 FD_SET(so->s, readfds);
314                                 UPD_NFDS(so->s);
315                         }
316                 }
317         }
318
319         /*
320          * Setup timeout to use minimum CPU usage, especially when idle
321          */
322
323         /*
324          * First, see the timeout needed by *timo
325          */
326         timeout.tv_sec = 0;
327         timeout.tv_usec = -1;
328         /*
329          * If a slowtimo is needed, set timeout to 500ms from the last
330          * slow timeout. If a fast timeout is needed, set timeout within
331          * 200ms of when it was requested.
332          */
333         if (do_slowtimo) {
334                 /* XXX + 10000 because some select()'s aren't that accurate */
335                 timeout.tv_usec = ((500 - (curtime - last_slowtimo)) * 1000) + 10000;
336                 if (timeout.tv_usec < 0)
337                    timeout.tv_usec = 0;
338                 else if (timeout.tv_usec > 510000)
339                    timeout.tv_usec = 510000;
340
341                 /* Can only fasttimo if we also slowtimo */
342                 if (time_fasttimo) {
343                         tmp_time = (200 - (curtime - time_fasttimo)) * 1000;
344                         if (tmp_time < 0)
345                            tmp_time = 0;
346
347                         /* Choose the smallest of the 2 */
348                         if (tmp_time < timeout.tv_usec)
349                            timeout.tv_usec = (u_int)tmp_time;
350                 }
351         }
352         *pnfds = nfds;
353 }
354
355 void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds)
356 {
357     struct socket *so, *so_next;
358     int ret;
359
360     global_readfds = readfds;
361     global_writefds = writefds;
362     global_xfds = xfds;
363
364         /* Update time */
365         updtime();
366
367         /*
368          * See if anything has timed out
369          */
370         if (link_up) {
371                 if (time_fasttimo && ((curtime - time_fasttimo) >= 2)) {
372                         tcp_fasttimo();
373                         time_fasttimo = 0;
374                 }
375                 if (do_slowtimo && ((curtime - last_slowtimo) >= 499)) {
376                         ip_slowtimo();
377                         tcp_slowtimo();
378                         last_slowtimo = curtime;
379                 }
380         }
381
382         /*
383          * Check sockets
384          */
385         if (link_up) {
386                 /*
387                  * Check TCP sockets
388                  */
389                 for (so = tcb.so_next; so != &tcb; so = so_next) {
390                         so_next = so->so_next;
391
392                         /*
393                          * FD_ISSET is meaningless on these sockets
394                          * (and they can crash the program)
395                          */
396                         if (so->so_state & SS_NOFDREF || so->s == -1)
397                            continue;
398
399                         /*
400                          * Check for URG data
401                          * This will soread as well, so no need to
402                          * test for readfds below if this succeeds
403                          */
404                         if (FD_ISSET(so->s, xfds))
405                            sorecvoob(so);
406                         /*
407                          * Check sockets for reading
408                          */
409                         else if (FD_ISSET(so->s, readfds)) {
410                                 /*
411                                  * Check for incoming connections
412                                  */
413                                 if (so->so_state & SS_FACCEPTCONN) {
414                                         tcp_connect(so);
415                                         continue;
416                                 } /* else */
417                                 ret = soread(so);
418
419                                 /* Output it if we read something */
420                                 if (ret > 0)
421                                    tcp_output(sototcpcb(so));
422                         }
423
424                         /*
425                          * Check sockets for writing
426                          */
427                         if (FD_ISSET(so->s, writefds)) {
428                           /*
429                            * Check for non-blocking, still-connecting sockets
430                            */
431                           if (so->so_state & SS_ISFCONNECTING) {
432                             /* Connected */
433                             so->so_state &= ~SS_ISFCONNECTING;
434
435                             ret = send(so->s, &ret, 0, 0);
436                             if (ret < 0) {
437                               /* XXXXX Must fix, zero bytes is a NOP */
438                               if (errno == EAGAIN || errno == EWOULDBLOCK ||
439                                   errno == EINPROGRESS || errno == ENOTCONN)
440                                 continue;
441
442                               /* else failed */
443                               so->so_state = SS_NOFDREF;
444                             }
445                             /* else so->so_state &= ~SS_ISFCONNECTING; */
446
447                             /*
448                              * Continue tcp_input
449                              */
450                             tcp_input((struct mbuf *)NULL, sizeof(struct ip), so);
451                             /* continue; */
452                           } else
453                             ret = sowrite(so);
454                           /*
455                            * XXXXX If we wrote something (a lot), there
456                            * could be a need for a window update.
457                            * In the worst case, the remote will send
458                            * a window probe to get things going again
459                            */
460                         }
461
462                         /*
463                          * Probe a still-connecting, non-blocking socket
464                          * to check if it's still alive
465                          */
466 #ifdef PROBE_CONN
467                         if (so->so_state & SS_ISFCONNECTING) {
468                           ret = recv(so->s, (char *)&ret, 0,0);
469
470                           if (ret < 0) {
471                             /* XXX */
472                             if (errno == EAGAIN || errno == EWOULDBLOCK ||
473                                 errno == EINPROGRESS || errno == ENOTCONN)
474                               continue; /* Still connecting, continue */
475
476                             /* else failed */
477                             so->so_state = SS_NOFDREF;
478
479                             /* tcp_input will take care of it */
480                           } else {
481                             ret = send(so->s, &ret, 0,0);
482                             if (ret < 0) {
483                               /* XXX */
484                               if (errno == EAGAIN || errno == EWOULDBLOCK ||
485                                   errno == EINPROGRESS || errno == ENOTCONN)
486                                 continue;
487                               /* else failed */
488                               so->so_state = SS_NOFDREF;
489                             } else
490                               so->so_state &= ~SS_ISFCONNECTING;
491
492                           }
493                           tcp_input((struct mbuf *)NULL, sizeof(struct ip),so);
494                         } /* SS_ISFCONNECTING */
495 #endif
496                 }
497
498                 /*
499                  * Now UDP sockets.
500                  * Incoming packets are sent straight away, they're not buffered.
501                  * Incoming UDP data isn't buffered either.
502                  */
503                 for (so = udb.so_next; so != &udb; so = so_next) {
504                         so_next = so->so_next;
505
506                         if (so->s != -1 && FD_ISSET(so->s, readfds)) {
507                             sorecvfrom(so);
508                         }
509                 }
510         }
511
512         /*
513          * See if we can start outputting
514          */
515         if (if_queued && link_up)
516            if_start();
517
518         /* clear global file descriptor sets.
519          * these reside on the stack in vl.c
520          * so they're unusable if we're not in
521          * slirp_select_fill or slirp_select_poll.
522          */
523          global_readfds = NULL;
524          global_writefds = NULL;
525          global_xfds = NULL;
526 }
527
528 #define ETH_ALEN 6
529 #define ETH_HLEN 14
530
531 #define ETH_P_IP        0x0800          /* Internet Protocol packet     */
532 #define ETH_P_ARP       0x0806          /* Address Resolution packet    */
533
534 #define ARPOP_REQUEST   1               /* ARP request                  */
535 #define ARPOP_REPLY     2               /* ARP reply                    */
536
537 struct ethhdr
538 {
539         unsigned char   h_dest[ETH_ALEN];       /* destination eth addr */
540         unsigned char   h_source[ETH_ALEN];     /* source ether addr    */
541         unsigned short  h_proto;                /* packet type ID field */
542 };
543
544 struct arphdr
545 {
546         unsigned short  ar_hrd;         /* format of hardware address   */
547         unsigned short  ar_pro;         /* format of protocol address   */
548         unsigned char   ar_hln;         /* length of hardware address   */
549         unsigned char   ar_pln;         /* length of protocol address   */
550         unsigned short  ar_op;          /* ARP opcode (command)         */
551
552          /*
553           *      Ethernet looks like this : This bit is variable sized however...
554           */
555         unsigned char           ar_sha[ETH_ALEN];       /* sender hardware address      */
556         unsigned char           ar_sip[4];              /* sender IP address            */
557         unsigned char           ar_tha[ETH_ALEN];       /* target hardware address      */
558         unsigned char           ar_tip[4];              /* target IP address            */
559 };
560
561 static void arp_input(const uint8_t *pkt, int pkt_len)
562 {
563     struct ethhdr *eh = (struct ethhdr *)pkt;
564     struct arphdr *ah = (struct arphdr *)(pkt + ETH_HLEN);
565     uint8_t arp_reply[ETH_HLEN + sizeof(struct arphdr)];
566     struct ethhdr *reh = (struct ethhdr *)arp_reply;
567     struct arphdr *rah = (struct arphdr *)(arp_reply + ETH_HLEN);
568     int ar_op;
569     struct ex_list *ex_ptr;
570
571     ar_op = ntohs(ah->ar_op);
572     switch(ar_op) {
573     case ARPOP_REQUEST:
574         if (!memcmp(ah->ar_tip, &special_addr, 3)) {
575             if (ah->ar_tip[3] == CTL_DNS || ah->ar_tip[3] == CTL_ALIAS)
576                 goto arp_ok;
577             for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
578                 if (ex_ptr->ex_addr == ah->ar_tip[3])
579                     goto arp_ok;
580             }
581             return;
582         arp_ok:
583             /* XXX: make an ARP request to have the client address */
584             memcpy(client_ethaddr, eh->h_source, ETH_ALEN);
585
586             /* ARP request for alias/dns mac address */
587             memcpy(reh->h_dest, pkt + ETH_ALEN, ETH_ALEN);
588             memcpy(reh->h_source, special_ethaddr, ETH_ALEN - 1);
589             reh->h_source[5] = ah->ar_tip[3];
590             reh->h_proto = htons(ETH_P_ARP);
591
592             rah->ar_hrd = htons(1);
593             rah->ar_pro = htons(ETH_P_IP);
594             rah->ar_hln = ETH_ALEN;
595             rah->ar_pln = 4;
596             rah->ar_op = htons(ARPOP_REPLY);
597             memcpy(rah->ar_sha, reh->h_source, ETH_ALEN);
598             memcpy(rah->ar_sip, ah->ar_tip, 4);
599             memcpy(rah->ar_tha, ah->ar_sha, ETH_ALEN);
600             memcpy(rah->ar_tip, ah->ar_sip, 4);
601             slirp_output(arp_reply, sizeof(arp_reply));
602         }
603         break;
604     case ARPOP_REPLY:
605         /* reply to request of client mac address ? */
606         if (!memcmp(client_ethaddr, zero_ethaddr, ETH_ALEN) &&
607             !memcmp(ah->ar_sip, &client_ipaddr.s_addr, 4)) {
608             memcpy(client_ethaddr, ah->ar_sha, ETH_ALEN);
609         }
610         break;
611     default:
612         break;
613     }
614 }
615
616 void slirp_input(const uint8_t *pkt, int pkt_len)
617 {
618     struct mbuf *m;
619     int proto;
620
621     if (pkt_len < ETH_HLEN)
622         return;
623
624     proto = ntohs(*(uint16_t *)(pkt + 12));
625     switch(proto) {
626     case ETH_P_ARP:
627         arp_input(pkt, pkt_len);
628         break;
629     case ETH_P_IP:
630         m = m_get();
631         if (!m)
632             return;
633         /* Note: we add to align the IP header */
634         m->m_len = pkt_len + 2;
635         memcpy(m->m_data + 2, pkt, pkt_len);
636
637         m->m_data += 2 + ETH_HLEN;
638         m->m_len -= 2 + ETH_HLEN;
639
640         ip_input(m);
641         break;
642     default:
643         break;
644     }
645 }
646
647 /* output the IP packet to the ethernet device */
648 void if_encap(const uint8_t *ip_data, int ip_data_len)
649 {
650     uint8_t buf[1600];
651     struct ethhdr *eh = (struct ethhdr *)buf;
652
653     if (ip_data_len + ETH_HLEN > sizeof(buf))
654         return;
655     
656     if (!memcmp(client_ethaddr, zero_ethaddr, ETH_ALEN)) {
657         uint8_t arp_req[ETH_HLEN + sizeof(struct arphdr)];
658         struct ethhdr *reh = (struct ethhdr *)arp_req;
659         struct arphdr *rah = (struct arphdr *)(arp_req + ETH_HLEN);
660         const struct ip *iph = (const struct ip *)ip_data;
661
662         /* If the client addr is not known, there is no point in
663            sending the packet to it. Normally the sender should have
664            done an ARP request to get its MAC address. Here we do it
665            in place of sending the packet and we hope that the sender
666            will retry sending its packet. */
667         memset(reh->h_dest, 0xff, ETH_ALEN);
668         memcpy(reh->h_source, special_ethaddr, ETH_ALEN - 1);
669         reh->h_source[5] = CTL_ALIAS;
670         reh->h_proto = htons(ETH_P_ARP);
671         rah->ar_hrd = htons(1);
672         rah->ar_pro = htons(ETH_P_IP);
673         rah->ar_hln = ETH_ALEN;
674         rah->ar_pln = 4;
675         rah->ar_op = htons(ARPOP_REQUEST);
676         /* source hw addr */
677         memcpy(rah->ar_sha, special_ethaddr, ETH_ALEN - 1);
678         rah->ar_sha[5] = CTL_ALIAS;
679         /* source IP */
680         memcpy(rah->ar_sip, &alias_addr, 4);
681         /* target hw addr (none) */
682         memset(rah->ar_tha, 0, ETH_ALEN);
683         /* target IP */
684         memcpy(rah->ar_tip, &iph->ip_dst, 4);
685         client_ipaddr = iph->ip_dst;
686         slirp_output(arp_req, sizeof(arp_req));
687     } else {
688         memcpy(eh->h_dest, client_ethaddr, ETH_ALEN);
689         memcpy(eh->h_source, special_ethaddr, ETH_ALEN - 1);
690         /* XXX: not correct */
691         eh->h_source[5] = CTL_ALIAS;
692         eh->h_proto = htons(ETH_P_IP);
693         memcpy(buf + sizeof(struct ethhdr), ip_data, ip_data_len);
694         slirp_output(buf, ip_data_len + ETH_HLEN);
695     }
696 }
697
698 int slirp_redir(int is_udp, int host_port,
699                 struct in_addr guest_addr, int guest_port)
700 {
701     if (is_udp) {
702         if (!udp_listen(htons(host_port), guest_addr.s_addr,
703                         htons(guest_port), 0))
704             return -1;
705     } else {
706         if (!solisten(htons(host_port), guest_addr.s_addr,
707                       htons(guest_port), 0))
708             return -1;
709     }
710     return 0;
711 }
712
713 int slirp_add_exec(int do_pty, const char *args, int addr_low_byte,
714                   int guest_port)
715 {
716     return add_exec(&exec_list, do_pty, (char *)args,
717                     addr_low_byte, htons(guest_port));
718 }