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