]> Git Repo - qemu.git/blob - slirp/slirp.c
vhost-net: revamp configure logic
[qemu.git] / 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 #ifdef WITH_QEMU
27 #include "state.h"
28 #endif
29
30 #ifndef _WIN32
31 #include <net/if.h>
32 #endif
33
34 int slirp_debug;
35
36 /* Define to 1 if you want KEEPALIVE timers */
37 bool slirp_do_keepalive;
38
39 /* host loopback address */
40 struct in_addr loopback_addr;
41 /* host loopback network mask */
42 unsigned long loopback_mask;
43
44 /* emulated hosts use the MAC addr 52:55:IP:IP:IP:IP */
45 static const uint8_t special_ethaddr[ETH_ALEN] = {
46     0x52, 0x55, 0x00, 0x00, 0x00, 0x00
47 };
48
49 unsigned curtime;
50
51 static struct in_addr dns_addr;
52 #ifndef _WIN32
53 static struct in6_addr dns6_addr;
54 #endif
55 static unsigned dns_addr_time;
56 #ifndef _WIN32
57 static unsigned dns6_addr_time;
58 #endif
59
60 #define TIMEOUT_FAST 2  /* milliseconds */
61 #define TIMEOUT_SLOW 499  /* milliseconds */
62 /* for the aging of certain requests like DNS */
63 #define TIMEOUT_DEFAULT 1000  /* milliseconds */
64
65 #ifdef _WIN32
66
67 int get_dns_addr(struct in_addr *pdns_addr)
68 {
69     FIXED_INFO *FixedInfo=NULL;
70     ULONG    BufLen;
71     DWORD    ret;
72     IP_ADDR_STRING *pIPAddr;
73     struct in_addr tmp_addr;
74
75     if (dns_addr.s_addr != 0 && (curtime - dns_addr_time) < TIMEOUT_DEFAULT) {
76         *pdns_addr = dns_addr;
77         return 0;
78     }
79
80     FixedInfo = (FIXED_INFO *)GlobalAlloc(GPTR, sizeof(FIXED_INFO));
81     BufLen = sizeof(FIXED_INFO);
82
83     if (ERROR_BUFFER_OVERFLOW == GetNetworkParams(FixedInfo, &BufLen)) {
84         if (FixedInfo) {
85             GlobalFree(FixedInfo);
86             FixedInfo = NULL;
87         }
88         FixedInfo = GlobalAlloc(GPTR, BufLen);
89     }
90
91     if ((ret = GetNetworkParams(FixedInfo, &BufLen)) != ERROR_SUCCESS) {
92         printf("GetNetworkParams failed. ret = %08x\n", (unsigned)ret );
93         if (FixedInfo) {
94             GlobalFree(FixedInfo);
95             FixedInfo = NULL;
96         }
97         return -1;
98     }
99
100     pIPAddr = &(FixedInfo->DnsServerList);
101     inet_aton(pIPAddr->IpAddress.String, &tmp_addr);
102     *pdns_addr = tmp_addr;
103     dns_addr = tmp_addr;
104     dns_addr_time = curtime;
105     if (FixedInfo) {
106         GlobalFree(FixedInfo);
107         FixedInfo = NULL;
108     }
109     return 0;
110 }
111
112 int get_dns6_addr(struct in6_addr *pdns6_addr, uint32_t *scope_id)
113 {
114     return -1;
115 }
116
117 static void winsock_cleanup(void)
118 {
119     WSACleanup();
120 }
121
122 #else
123
124 static int get_dns_addr_cached(void *pdns_addr, void *cached_addr,
125                                socklen_t addrlen,
126                                struct stat *cached_stat, unsigned *cached_time)
127 {
128     struct stat old_stat;
129     if (curtime - *cached_time < TIMEOUT_DEFAULT) {
130         memcpy(pdns_addr, cached_addr, addrlen);
131         return 0;
132     }
133     old_stat = *cached_stat;
134     if (stat("/etc/resolv.conf", cached_stat) != 0) {
135         return -1;
136     }
137     if (cached_stat->st_dev == old_stat.st_dev
138         && cached_stat->st_ino == old_stat.st_ino
139         && cached_stat->st_size == old_stat.st_size
140         && cached_stat->st_mtime == old_stat.st_mtime) {
141         memcpy(pdns_addr, cached_addr, addrlen);
142         return 0;
143     }
144     return 1;
145 }
146
147 static int get_dns_addr_resolv_conf(int af, void *pdns_addr, void *cached_addr,
148                                     socklen_t addrlen, uint32_t *scope_id,
149                                     unsigned *cached_time)
150 {
151     char buff[512];
152     char buff2[257];
153     FILE *f;
154     int found = 0;
155     void *tmp_addr = alloca(addrlen);
156     unsigned if_index;
157
158     f = fopen("/etc/resolv.conf", "r");
159     if (!f)
160         return -1;
161
162     DEBUG_MISC("IP address of your DNS(s):");
163     while (fgets(buff, 512, f) != NULL) {
164         if (sscanf(buff, "nameserver%*[ \t]%256s", buff2) == 1) {
165             char *c = strchr(buff2, '%');
166             if (c) {
167                 if_index = if_nametoindex(c + 1);
168                 *c = '\0';
169             } else {
170                 if_index = 0;
171             }
172
173             if (!inet_pton(af, buff2, tmp_addr)) {
174                 continue;
175             }
176             /* If it's the first one, set it to dns_addr */
177             if (!found) {
178                 memcpy(pdns_addr, tmp_addr, addrlen);
179                 memcpy(cached_addr, tmp_addr, addrlen);
180                 if (scope_id) {
181                     *scope_id = if_index;
182                 }
183                 *cached_time = curtime;
184             }
185
186             if (++found > 3) {
187                 DEBUG_MISC("  (more)");
188                 break;
189             } else if (slirp_debug & DBG_MISC) {
190                 char s[INET6_ADDRSTRLEN];
191                 const char *res = inet_ntop(af, tmp_addr, s, sizeof(s));
192                 if (!res) {
193                     res = "  (string conversion error)";
194                 }
195                 DEBUG_MISC("  %s", res);
196             }
197         }
198     }
199     fclose(f);
200     if (!found)
201         return -1;
202     return 0;
203 }
204
205 int get_dns_addr(struct in_addr *pdns_addr)
206 {
207     static struct stat dns_addr_stat;
208
209     if (dns_addr.s_addr != 0) {
210         int ret;
211         ret = get_dns_addr_cached(pdns_addr, &dns_addr, sizeof(dns_addr),
212                                   &dns_addr_stat, &dns_addr_time);
213         if (ret <= 0) {
214             return ret;
215         }
216     }
217     return get_dns_addr_resolv_conf(AF_INET, pdns_addr, &dns_addr,
218                                     sizeof(dns_addr), NULL, &dns_addr_time);
219 }
220
221 int get_dns6_addr(struct in6_addr *pdns6_addr, uint32_t *scope_id)
222 {
223     static struct stat dns6_addr_stat;
224
225     if (!in6_zero(&dns6_addr)) {
226         int ret;
227         ret = get_dns_addr_cached(pdns6_addr, &dns6_addr, sizeof(dns6_addr),
228                                   &dns6_addr_stat, &dns6_addr_time);
229         if (ret <= 0) {
230             return ret;
231         }
232     }
233     return get_dns_addr_resolv_conf(AF_INET6, pdns6_addr, &dns6_addr,
234                                     sizeof(dns6_addr),
235                                     scope_id, &dns6_addr_time);
236 }
237
238 #endif
239
240 static void slirp_init_once(void)
241 {
242     static int initialized;
243     const char *debug;
244 #ifdef _WIN32
245     WSADATA Data;
246 #endif
247
248     if (initialized) {
249         return;
250     }
251     initialized = 1;
252
253 #ifdef _WIN32
254     WSAStartup(MAKEWORD(2,0), &Data);
255     atexit(winsock_cleanup);
256 #endif
257
258     loopback_addr.s_addr = htonl(INADDR_LOOPBACK);
259     loopback_mask = htonl(IN_CLASSA_NET);
260
261     debug = g_getenv("SLIRP_DEBUG");
262     if (debug) {
263         const GDebugKey keys[] = {
264             { "call", DBG_CALL },
265             { "misc", DBG_MISC },
266             { "error", DBG_ERROR },
267             { "tftp", DBG_TFTP },
268         };
269         slirp_debug = g_parse_debug_string(debug, keys, G_N_ELEMENTS(keys));
270     }
271
272
273 }
274
275 Slirp *slirp_init(int restricted, bool in_enabled, struct in_addr vnetwork,
276                   struct in_addr vnetmask, struct in_addr vhost,
277                   bool in6_enabled,
278                   struct in6_addr vprefix_addr6, uint8_t vprefix_len,
279                   struct in6_addr vhost6, const char *vhostname,
280                   const char *tftp_server_name,
281                   const char *tftp_path, const char *bootfile,
282                   struct in_addr vdhcp_start, struct in_addr vnameserver,
283                   struct in6_addr vnameserver6, const char **vdnssearch,
284                   const char *vdomainname,
285                   const SlirpCb *callbacks,
286                   void *opaque)
287 {
288     Slirp *slirp = g_malloc0(sizeof(Slirp));
289
290     slirp_init_once();
291
292     slirp->opaque = opaque;
293     slirp->cb = callbacks;
294     slirp->grand = g_rand_new();
295     slirp->restricted = restricted;
296
297     slirp->in_enabled = in_enabled;
298     slirp->in6_enabled = in6_enabled;
299
300     if_init(slirp);
301     ip_init(slirp);
302     ip6_init(slirp);
303
304     /* Initialise mbufs *after* setting the MTU */
305     m_init(slirp);
306
307     slirp->vnetwork_addr = vnetwork;
308     slirp->vnetwork_mask = vnetmask;
309     slirp->vhost_addr = vhost;
310     slirp->vprefix_addr6 = vprefix_addr6;
311     slirp->vprefix_len = vprefix_len;
312     slirp->vhost_addr6 = vhost6;
313     if (vhostname) {
314         slirp_pstrcpy(slirp->client_hostname, sizeof(slirp->client_hostname),
315                       vhostname);
316     }
317     slirp->tftp_prefix = g_strdup(tftp_path);
318     slirp->bootp_filename = g_strdup(bootfile);
319     slirp->vdomainname = g_strdup(vdomainname);
320     slirp->vdhcp_startaddr = vdhcp_start;
321     slirp->vnameserver_addr = vnameserver;
322     slirp->vnameserver_addr6 = vnameserver6;
323     slirp->tftp_server_name = g_strdup(tftp_server_name);
324
325     if (vdnssearch) {
326         translate_dnssearch(slirp, vdnssearch);
327     }
328
329 #ifdef WITH_QEMU
330     slirp_state_register(slirp);
331 #endif
332     return slirp;
333 }
334
335 void slirp_cleanup(Slirp *slirp)
336 {
337     struct gfwd_list *e, *next;
338
339     for (e = slirp->guestfwd_list; e; e = next) {
340         next = e->ex_next;
341         g_free(e->ex_exec);
342         g_free(e);
343     }
344
345 #ifdef WITH_QEMU
346     slirp_state_unregister(slirp);
347 #endif
348     ip_cleanup(slirp);
349     ip6_cleanup(slirp);
350     m_cleanup(slirp);
351
352     g_rand_free(slirp->grand);
353
354     g_free(slirp->vdnssearch);
355     g_free(slirp->tftp_prefix);
356     g_free(slirp->bootp_filename);
357     g_free(slirp->vdomainname);
358     g_free(slirp);
359 }
360
361 #define CONN_CANFSEND(so) (((so)->so_state & (SS_FCANTSENDMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED)
362 #define CONN_CANFRCV(so) (((so)->so_state & (SS_FCANTRCVMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED)
363
364 static void slirp_update_timeout(Slirp *slirp, uint32_t *timeout)
365 {
366     uint32_t t;
367
368     if (*timeout <= TIMEOUT_FAST) {
369         return;
370     }
371
372     t = MIN(1000, *timeout);
373
374     /* If we have tcp timeout with slirp, then we will fill @timeout with
375      * more precise value.
376      */
377     if (slirp->time_fasttimo) {
378         *timeout = TIMEOUT_FAST;
379         return;
380     }
381     if (slirp->do_slowtimo) {
382         t = MIN(TIMEOUT_SLOW, t);
383     }
384     *timeout = t;
385 }
386
387 void slirp_pollfds_fill(Slirp *slirp, uint32_t *timeout,
388                         SlirpAddPollCb add_poll, void *opaque)
389 {
390     struct socket *so, *so_next;
391
392     /*
393      * First, TCP sockets
394      */
395
396     /*
397      * *_slowtimo needs calling if there are IP fragments
398      * in the fragment queue, or there are TCP connections active
399      */
400     slirp->do_slowtimo = ((slirp->tcb.so_next != &slirp->tcb) ||
401                           (&slirp->ipq.ip_link != slirp->ipq.ip_link.next));
402
403     for (so = slirp->tcb.so_next; so != &slirp->tcb; so = so_next) {
404         int events = 0;
405
406         so_next = so->so_next;
407
408         so->pollfds_idx = -1;
409
410         /*
411          * See if we need a tcp_fasttimo
412          */
413         if (slirp->time_fasttimo == 0 &&
414             so->so_tcpcb->t_flags & TF_DELACK) {
415             slirp->time_fasttimo = curtime; /* Flag when want a fasttimo */
416         }
417
418         /*
419          * NOFDREF can include still connecting to local-host,
420          * newly socreated() sockets etc. Don't want to select these.
421          */
422         if (so->so_state & SS_NOFDREF || so->s == -1) {
423             continue;
424         }
425
426         /*
427          * Set for reading sockets which are accepting
428          */
429         if (so->so_state & SS_FACCEPTCONN) {
430             so->pollfds_idx = add_poll(so->s,
431                 SLIRP_POLL_IN | SLIRP_POLL_HUP | SLIRP_POLL_ERR, opaque);
432             continue;
433         }
434
435         /*
436          * Set for writing sockets which are connecting
437          */
438         if (so->so_state & SS_ISFCONNECTING) {
439             so->pollfds_idx = add_poll(so->s,
440                 SLIRP_POLL_OUT | SLIRP_POLL_ERR, opaque);
441             continue;
442         }
443
444         /*
445          * Set for writing if we are connected, can send more, and
446          * we have something to send
447          */
448         if (CONN_CANFSEND(so) && so->so_rcv.sb_cc) {
449             events |= SLIRP_POLL_OUT | SLIRP_POLL_ERR;
450         }
451
452         /*
453          * Set for reading (and urgent data) if we are connected, can
454          * receive more, and we have room for it XXX /2 ?
455          */
456         if (CONN_CANFRCV(so) &&
457             (so->so_snd.sb_cc < (so->so_snd.sb_datalen/2))) {
458             events |= SLIRP_POLL_IN | SLIRP_POLL_HUP |
459                       SLIRP_POLL_ERR | SLIRP_POLL_PRI;
460         }
461
462         if (events) {
463             so->pollfds_idx = add_poll(so->s, events, opaque);
464         }
465     }
466
467     /*
468      * UDP sockets
469      */
470     for (so = slirp->udb.so_next; so != &slirp->udb; so = so_next) {
471         so_next = so->so_next;
472
473         so->pollfds_idx = -1;
474
475         /*
476          * See if it's timed out
477          */
478         if (so->so_expire) {
479             if (so->so_expire <= curtime) {
480                 udp_detach(so);
481                 continue;
482             } else {
483                 slirp->do_slowtimo = true; /* Let socket expire */
484             }
485         }
486
487         /*
488          * When UDP packets are received from over the
489          * link, they're sendto()'d straight away, so
490          * no need for setting for writing
491          * Limit the number of packets queued by this session
492          * to 4.  Note that even though we try and limit this
493          * to 4 packets, the session could have more queued
494          * if the packets needed to be fragmented
495          * (XXX <= 4 ?)
496          */
497         if ((so->so_state & SS_ISFCONNECTED) && so->so_queued <= 4) {
498             so->pollfds_idx = add_poll(so->s,
499                 SLIRP_POLL_IN | SLIRP_POLL_HUP | SLIRP_POLL_ERR, opaque);
500         }
501     }
502
503     /*
504      * ICMP sockets
505      */
506     for (so = slirp->icmp.so_next; so != &slirp->icmp; so = so_next) {
507         so_next = so->so_next;
508
509         so->pollfds_idx = -1;
510
511         /*
512          * See if it's timed out
513          */
514         if (so->so_expire) {
515             if (so->so_expire <= curtime) {
516                 icmp_detach(so);
517                 continue;
518             } else {
519                 slirp->do_slowtimo = true; /* Let socket expire */
520             }
521         }
522
523         if (so->so_state & SS_ISFCONNECTED) {
524             so->pollfds_idx = add_poll(so->s,
525                 SLIRP_POLL_IN | SLIRP_POLL_HUP | SLIRP_POLL_ERR, opaque);
526         }
527     }
528
529     slirp_update_timeout(slirp, timeout);
530 }
531
532 void slirp_pollfds_poll(Slirp *slirp, int select_error,
533                         SlirpGetREventsCb get_revents, void *opaque)
534 {
535     struct socket *so, *so_next;
536     int ret;
537
538     curtime = slirp->cb->clock_get_ns(slirp->opaque) / SCALE_MS;
539
540     /*
541      * See if anything has timed out
542      */
543     if (slirp->time_fasttimo &&
544         ((curtime - slirp->time_fasttimo) >= TIMEOUT_FAST)) {
545         tcp_fasttimo(slirp);
546         slirp->time_fasttimo = 0;
547     }
548     if (slirp->do_slowtimo &&
549         ((curtime - slirp->last_slowtimo) >= TIMEOUT_SLOW)) {
550         ip_slowtimo(slirp);
551         tcp_slowtimo(slirp);
552         slirp->last_slowtimo = curtime;
553     }
554
555     /*
556      * Check sockets
557      */
558     if (!select_error) {
559         /*
560          * Check TCP sockets
561          */
562         for (so = slirp->tcb.so_next; so != &slirp->tcb;
563              so = so_next) {
564             int revents;
565
566             so_next = so->so_next;
567
568             revents = 0;
569             if (so->pollfds_idx != -1) {
570                 revents = get_revents(so->pollfds_idx, opaque);
571             }
572
573             if (so->so_state & SS_NOFDREF || so->s == -1) {
574                 continue;
575             }
576
577             /*
578              * Check for URG data
579              * This will soread as well, so no need to
580              * test for SLIRP_POLL_IN below if this succeeds
581              */
582             if (revents & SLIRP_POLL_PRI) {
583                 ret = sorecvoob(so);
584                 if (ret < 0) {
585                     /* Socket error might have resulted in the socket being
586                      * removed, do not try to do anything more with it. */
587                     continue;
588                 }
589             }
590             /*
591              * Check sockets for reading
592              */
593             else if (revents &
594                      (SLIRP_POLL_IN | SLIRP_POLL_HUP | SLIRP_POLL_ERR)) {
595                 /*
596                  * Check for incoming connections
597                  */
598                 if (so->so_state & SS_FACCEPTCONN) {
599                     tcp_connect(so);
600                     continue;
601                 } /* else */
602                 ret = soread(so);
603
604                 /* Output it if we read something */
605                 if (ret > 0) {
606                     tcp_output(sototcpcb(so));
607                 }
608                 if (ret < 0) {
609                     /* Socket error might have resulted in the socket being
610                      * removed, do not try to do anything more with it. */
611                     continue;
612                 }
613             }
614
615             /*
616              * Check sockets for writing
617              */
618             if (!(so->so_state & SS_NOFDREF) &&
619                 (revents & (SLIRP_POLL_OUT | SLIRP_POLL_ERR))) {
620                 /*
621                  * Check for non-blocking, still-connecting sockets
622                  */
623                 if (so->so_state & SS_ISFCONNECTING) {
624                     /* Connected */
625                     so->so_state &= ~SS_ISFCONNECTING;
626
627                     ret = send(so->s, (const void *) &ret, 0, 0);
628                     if (ret < 0) {
629                         /* XXXXX Must fix, zero bytes is a NOP */
630                         if (errno == EAGAIN || errno == EWOULDBLOCK ||
631                             errno == EINPROGRESS || errno == ENOTCONN) {
632                             continue;
633                         }
634
635                         /* else failed */
636                         so->so_state &= SS_PERSISTENT_MASK;
637                         so->so_state |= SS_NOFDREF;
638                     }
639                     /* else so->so_state &= ~SS_ISFCONNECTING; */
640
641                     /*
642                      * Continue tcp_input
643                      */
644                     tcp_input((struct mbuf *)NULL, sizeof(struct ip), so,
645                               so->so_ffamily);
646                     /* continue; */
647                 } else {
648                     ret = sowrite(so);
649                     if (ret > 0) {
650                         /* Call tcp_output in case we need to send a window
651                          * update to the guest, otherwise it will be stuck
652                          * until it sends a window probe. */
653                         tcp_output(sototcpcb(so));
654                     }
655                 }
656             }
657         }
658
659         /*
660          * Now UDP sockets.
661          * Incoming packets are sent straight away, they're not buffered.
662          * Incoming UDP data isn't buffered either.
663          */
664         for (so = slirp->udb.so_next; so != &slirp->udb;
665              so = so_next) {
666             int revents;
667
668             so_next = so->so_next;
669
670             revents = 0;
671             if (so->pollfds_idx != -1) {
672                 revents = get_revents(so->pollfds_idx, opaque);
673             }
674
675             if (so->s != -1 &&
676                 (revents & (SLIRP_POLL_IN | SLIRP_POLL_HUP | SLIRP_POLL_ERR))) {
677                 sorecvfrom(so);
678             }
679         }
680
681         /*
682          * Check incoming ICMP relies.
683          */
684         for (so = slirp->icmp.so_next; so != &slirp->icmp;
685              so = so_next) {
686             int revents;
687
688             so_next = so->so_next;
689
690             revents = 0;
691             if (so->pollfds_idx != -1) {
692                 revents = get_revents(so->pollfds_idx, opaque);
693             }
694
695             if (so->s != -1 &&
696                 (revents & (SLIRP_POLL_IN | SLIRP_POLL_HUP | SLIRP_POLL_ERR))) {
697                 icmp_receive(so);
698             }
699         }
700     }
701
702     if_start(slirp);
703 }
704
705 static void arp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len)
706 {
707     struct slirp_arphdr *ah = (struct slirp_arphdr *)(pkt + ETH_HLEN);
708     uint8_t arp_reply[MAX(ETH_HLEN + sizeof(struct slirp_arphdr), 64)];
709     struct ethhdr *reh = (struct ethhdr *)arp_reply;
710     struct slirp_arphdr *rah = (struct slirp_arphdr *)(arp_reply + ETH_HLEN);
711     int ar_op;
712     struct gfwd_list *ex_ptr;
713
714     if (!slirp->in_enabled) {
715         return;
716     }
717
718     ar_op = ntohs(ah->ar_op);
719     switch(ar_op) {
720     case ARPOP_REQUEST:
721         if (ah->ar_tip == ah->ar_sip) {
722             /* Gratuitous ARP */
723             arp_table_add(slirp, ah->ar_sip, ah->ar_sha);
724             return;
725         }
726
727         if ((ah->ar_tip & slirp->vnetwork_mask.s_addr) ==
728             slirp->vnetwork_addr.s_addr) {
729             if (ah->ar_tip == slirp->vnameserver_addr.s_addr ||
730                 ah->ar_tip == slirp->vhost_addr.s_addr)
731                 goto arp_ok;
732             for (ex_ptr = slirp->guestfwd_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
733                 if (ex_ptr->ex_addr.s_addr == ah->ar_tip)
734                     goto arp_ok;
735             }
736             return;
737         arp_ok:
738             memset(arp_reply, 0, sizeof(arp_reply));
739
740             arp_table_add(slirp, ah->ar_sip, ah->ar_sha);
741
742             /* ARP request for alias/dns mac address */
743             memcpy(reh->h_dest, pkt + ETH_ALEN, ETH_ALEN);
744             memcpy(reh->h_source, special_ethaddr, ETH_ALEN - 4);
745             memcpy(&reh->h_source[2], &ah->ar_tip, 4);
746             reh->h_proto = htons(ETH_P_ARP);
747
748             rah->ar_hrd = htons(1);
749             rah->ar_pro = htons(ETH_P_IP);
750             rah->ar_hln = ETH_ALEN;
751             rah->ar_pln = 4;
752             rah->ar_op = htons(ARPOP_REPLY);
753             memcpy(rah->ar_sha, reh->h_source, ETH_ALEN);
754             rah->ar_sip = ah->ar_tip;
755             memcpy(rah->ar_tha, ah->ar_sha, ETH_ALEN);
756             rah->ar_tip = ah->ar_sip;
757             slirp_send_packet_all(slirp, arp_reply, sizeof(arp_reply));
758         }
759         break;
760     case ARPOP_REPLY:
761         arp_table_add(slirp, ah->ar_sip, ah->ar_sha);
762         break;
763     default:
764         break;
765     }
766 }
767
768 void slirp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len)
769 {
770     struct mbuf *m;
771     int proto;
772
773     if (pkt_len < ETH_HLEN)
774         return;
775
776     proto = (((uint16_t) pkt[12]) << 8) + pkt[13];
777     switch(proto) {
778     case ETH_P_ARP:
779         arp_input(slirp, pkt, pkt_len);
780         break;
781     case ETH_P_IP:
782     case ETH_P_IPV6:
783         m = m_get(slirp);
784         if (!m)
785             return;
786         /* Note: we add 2 to align the IP header on 4 bytes,
787          * and add the margin for the tcpiphdr overhead  */
788         if (M_FREEROOM(m) < pkt_len + TCPIPHDR_DELTA + 2) {
789             m_inc(m, pkt_len + TCPIPHDR_DELTA + 2);
790         }
791         m->m_len = pkt_len + TCPIPHDR_DELTA + 2;
792         memcpy(m->m_data + TCPIPHDR_DELTA + 2, pkt, pkt_len);
793
794         m->m_data += TCPIPHDR_DELTA + 2 + ETH_HLEN;
795         m->m_len -= TCPIPHDR_DELTA + 2 + ETH_HLEN;
796
797         if (proto == ETH_P_IP) {
798             ip_input(m);
799         } else if (proto == ETH_P_IPV6) {
800             ip6_input(m);
801         }
802         break;
803
804     case ETH_P_NCSI:
805         ncsi_input(slirp, pkt, pkt_len);
806         break;
807
808     default:
809         break;
810     }
811 }
812
813 /* Prepare the IPv4 packet to be sent to the ethernet device. Returns 1 if no
814  * packet should be sent, 0 if the packet must be re-queued, 2 if the packet
815  * is ready to go.
816  */
817 static int if_encap4(Slirp *slirp, struct mbuf *ifm, struct ethhdr *eh,
818         uint8_t ethaddr[ETH_ALEN])
819 {
820     const struct ip *iph = (const struct ip *)ifm->m_data;
821
822     if (iph->ip_dst.s_addr == 0) {
823         /* 0.0.0.0 can not be a destination address, something went wrong,
824          * avoid making it worse */
825         return 1;
826     }
827     if (!arp_table_search(slirp, iph->ip_dst.s_addr, ethaddr)) {
828         uint8_t arp_req[ETH_HLEN + sizeof(struct slirp_arphdr)];
829         struct ethhdr *reh = (struct ethhdr *)arp_req;
830         struct slirp_arphdr *rah = (struct slirp_arphdr *)(arp_req + ETH_HLEN);
831
832         if (!ifm->resolution_requested) {
833             /* If the client addr is not known, send an ARP request */
834             memset(reh->h_dest, 0xff, ETH_ALEN);
835             memcpy(reh->h_source, special_ethaddr, ETH_ALEN - 4);
836             memcpy(&reh->h_source[2], &slirp->vhost_addr, 4);
837             reh->h_proto = htons(ETH_P_ARP);
838             rah->ar_hrd = htons(1);
839             rah->ar_pro = htons(ETH_P_IP);
840             rah->ar_hln = ETH_ALEN;
841             rah->ar_pln = 4;
842             rah->ar_op = htons(ARPOP_REQUEST);
843
844             /* source hw addr */
845             memcpy(rah->ar_sha, special_ethaddr, ETH_ALEN - 4);
846             memcpy(&rah->ar_sha[2], &slirp->vhost_addr, 4);
847
848             /* source IP */
849             rah->ar_sip = slirp->vhost_addr.s_addr;
850
851             /* target hw addr (none) */
852             memset(rah->ar_tha, 0, ETH_ALEN);
853
854             /* target IP */
855             rah->ar_tip = iph->ip_dst.s_addr;
856             slirp->client_ipaddr = iph->ip_dst;
857             slirp_send_packet_all(slirp, arp_req, sizeof(arp_req));
858             ifm->resolution_requested = true;
859
860             /* Expire request and drop outgoing packet after 1 second */
861             ifm->expiration_date =
862                 slirp->cb->clock_get_ns(slirp->opaque) + 1000000000ULL;
863         }
864         return 0;
865     } else {
866         memcpy(eh->h_source, special_ethaddr, ETH_ALEN - 4);
867         /* XXX: not correct */
868         memcpy(&eh->h_source[2], &slirp->vhost_addr, 4);
869         eh->h_proto = htons(ETH_P_IP);
870
871         /* Send this */
872         return 2;
873     }
874 }
875
876 /* Prepare the IPv6 packet to be sent to the ethernet device. Returns 1 if no
877  * packet should be sent, 0 if the packet must be re-queued, 2 if the packet
878  * is ready to go.
879  */
880 static int if_encap6(Slirp *slirp, struct mbuf *ifm, struct ethhdr *eh,
881         uint8_t ethaddr[ETH_ALEN])
882 {
883     const struct ip6 *ip6h = mtod(ifm, const struct ip6 *);
884     if (!ndp_table_search(slirp, ip6h->ip_dst, ethaddr)) {
885         if (!ifm->resolution_requested) {
886             ndp_send_ns(slirp, ip6h->ip_dst);
887             ifm->resolution_requested = true;
888             ifm->expiration_date = slirp->cb->clock_get_ns(slirp->opaque) + 1000000000ULL;
889         }
890         return 0;
891     } else {
892         eh->h_proto = htons(ETH_P_IPV6);
893         in6_compute_ethaddr(ip6h->ip_src, eh->h_source);
894
895         /* Send this */
896         return 2;
897     }
898 }
899
900 /* Output the IP packet to the ethernet device. Returns 0 if the packet must be
901  * re-queued.
902  */
903 int if_encap(Slirp *slirp, struct mbuf *ifm)
904 {
905     uint8_t buf[1600];
906     struct ethhdr *eh = (struct ethhdr *)buf;
907     uint8_t ethaddr[ETH_ALEN];
908     const struct ip *iph = (const struct ip *)ifm->m_data;
909     int ret;
910
911     if (ifm->m_len + ETH_HLEN > sizeof(buf)) {
912         return 1;
913     }
914
915     switch (iph->ip_v) {
916     case IPVERSION:
917         ret = if_encap4(slirp, ifm, eh, ethaddr);
918         if (ret < 2) {
919             return ret;
920         }
921         break;
922
923     case IP6VERSION:
924         ret = if_encap6(slirp, ifm, eh, ethaddr);
925         if (ret < 2) {
926             return ret;
927         }
928         break;
929
930     default:
931         g_assert_not_reached();
932         break;
933     }
934
935     memcpy(eh->h_dest, ethaddr, ETH_ALEN);
936     DEBUG_ARG("src = %02x:%02x:%02x:%02x:%02x:%02x",
937               eh->h_source[0], eh->h_source[1], eh->h_source[2],
938               eh->h_source[3], eh->h_source[4], eh->h_source[5]);
939     DEBUG_ARG("dst = %02x:%02x:%02x:%02x:%02x:%02x",
940               eh->h_dest[0], eh->h_dest[1], eh->h_dest[2],
941               eh->h_dest[3], eh->h_dest[4], eh->h_dest[5]);
942     memcpy(buf + sizeof(struct ethhdr), ifm->m_data, ifm->m_len);
943     slirp_send_packet_all(slirp, buf, ifm->m_len + ETH_HLEN);
944     return 1;
945 }
946
947 /* Drop host forwarding rule, return 0 if found. */
948 int slirp_remove_hostfwd(Slirp *slirp, int is_udp, struct in_addr host_addr,
949                          int host_port)
950 {
951     struct socket *so;
952     struct socket *head = (is_udp ? &slirp->udb : &slirp->tcb);
953     struct sockaddr_in addr;
954     int port = htons(host_port);
955     socklen_t addr_len;
956
957     for (so = head->so_next; so != head; so = so->so_next) {
958         addr_len = sizeof(addr);
959         if ((so->so_state & SS_HOSTFWD) &&
960             getsockname(so->s, (struct sockaddr *)&addr, &addr_len) == 0 &&
961             addr.sin_addr.s_addr == host_addr.s_addr &&
962             addr.sin_port == port) {
963             so->slirp->cb->unregister_poll_fd(so->s, so->slirp->opaque);
964             closesocket(so->s);
965             sofree(so);
966             return 0;
967         }
968     }
969
970     return -1;
971 }
972
973 int slirp_add_hostfwd(Slirp *slirp, int is_udp, struct in_addr host_addr,
974                       int host_port, struct in_addr guest_addr, int guest_port)
975 {
976     if (!guest_addr.s_addr) {
977         guest_addr = slirp->vdhcp_startaddr;
978     }
979     if (is_udp) {
980         if (!udp_listen(slirp, host_addr.s_addr, htons(host_port),
981                         guest_addr.s_addr, htons(guest_port), SS_HOSTFWD))
982             return -1;
983     } else {
984         if (!tcp_listen(slirp, host_addr.s_addr, htons(host_port),
985                         guest_addr.s_addr, htons(guest_port), SS_HOSTFWD))
986             return -1;
987     }
988     return 0;
989 }
990
991 static bool
992 check_guestfwd(Slirp *slirp, struct in_addr *guest_addr, int guest_port)
993 {
994     struct gfwd_list *tmp_ptr;
995
996     if (!guest_addr->s_addr) {
997         guest_addr->s_addr = slirp->vnetwork_addr.s_addr |
998             (htonl(0x0204) & ~slirp->vnetwork_mask.s_addr);
999     }
1000     if ((guest_addr->s_addr & slirp->vnetwork_mask.s_addr) !=
1001         slirp->vnetwork_addr.s_addr ||
1002         guest_addr->s_addr == slirp->vhost_addr.s_addr ||
1003         guest_addr->s_addr == slirp->vnameserver_addr.s_addr) {
1004         return false;
1005     }
1006
1007     /* check if the port is "bound" */
1008     for (tmp_ptr = slirp->guestfwd_list; tmp_ptr; tmp_ptr = tmp_ptr->ex_next) {
1009         if (guest_port == tmp_ptr->ex_fport &&
1010             guest_addr->s_addr == tmp_ptr->ex_addr.s_addr)
1011             return false;
1012     }
1013
1014     return true;
1015 }
1016
1017 int slirp_add_exec(Slirp *slirp, const char *cmdline,
1018                    struct in_addr *guest_addr, int guest_port)
1019 {
1020     if (!check_guestfwd(slirp, guest_addr, guest_port)) {
1021         return -1;
1022     }
1023
1024     add_exec(&slirp->guestfwd_list, cmdline, *guest_addr, htons(guest_port));
1025     return 0;
1026 }
1027
1028 int slirp_add_guestfwd(Slirp *slirp, SlirpWriteCb write_cb, void *opaque,
1029                        struct in_addr *guest_addr, int guest_port)
1030 {
1031     if (!check_guestfwd(slirp, guest_addr, guest_port)) {
1032         return -1;
1033     }
1034
1035     add_guestfwd(&slirp->guestfwd_list, write_cb, opaque,
1036                  *guest_addr, htons(guest_port));
1037     return 0;
1038 }
1039
1040 ssize_t slirp_send(struct socket *so, const void *buf, size_t len, int flags)
1041 {
1042     if (so->s == -1 && so->guestfwd) {
1043         /* XXX this blocks entire thread. Rewrite to use
1044          * qemu_chr_fe_write and background I/O callbacks */
1045         so->guestfwd->write_cb(buf, len, so->guestfwd->opaque);
1046         return len;
1047     }
1048
1049     if (so->s == -1) {
1050         /*
1051          * This should in theory not happen but it is hard to be
1052          * sure because some code paths will end up with so->s == -1
1053          * on a failure but don't dispose of the struct socket.
1054          * Check specifically, so we don't pass -1 to send().
1055          */
1056         errno = EBADF;
1057         return -1;
1058     }
1059
1060     return send(so->s, buf, len, flags);
1061 }
1062
1063 struct socket *
1064 slirp_find_ctl_socket(Slirp *slirp, struct in_addr guest_addr, int guest_port)
1065 {
1066     struct socket *so;
1067
1068     for (so = slirp->tcb.so_next; so != &slirp->tcb; so = so->so_next) {
1069         if (so->so_faddr.s_addr == guest_addr.s_addr &&
1070             htons(so->so_fport) == guest_port) {
1071             return so;
1072         }
1073     }
1074     return NULL;
1075 }
1076
1077 size_t slirp_socket_can_recv(Slirp *slirp, struct in_addr guest_addr,
1078                              int guest_port)
1079 {
1080     struct iovec iov[2];
1081     struct socket *so;
1082
1083     so = slirp_find_ctl_socket(slirp, guest_addr, guest_port);
1084
1085     if (!so || so->so_state & SS_NOFDREF) {
1086         return 0;
1087     }
1088
1089     if (!CONN_CANFRCV(so) || so->so_snd.sb_cc >= (so->so_snd.sb_datalen/2)) {
1090         return 0;
1091     }
1092
1093     return sopreprbuf(so, iov, NULL);
1094 }
1095
1096 void slirp_socket_recv(Slirp *slirp, struct in_addr guest_addr, int guest_port,
1097                        const uint8_t *buf, int size)
1098 {
1099     int ret;
1100     struct socket *so = slirp_find_ctl_socket(slirp, guest_addr, guest_port);
1101
1102     if (!so)
1103         return;
1104
1105     ret = soreadbuf(so, (const char *)buf, size);
1106
1107     if (ret > 0)
1108         tcp_output(sototcpcb(so));
1109 }
1110
1111 void slirp_send_packet_all(Slirp *slirp, const void *buf, size_t len)
1112 {
1113     ssize_t ret = slirp->cb->send_packet(buf, len, slirp->opaque);
1114
1115     if (ret < 0) {
1116         g_critical("Failed to send packet, ret: %ld", (long) ret);
1117     } else if (ret < len) {
1118         DEBUG_ERROR("send_packet() didn't send all data: %ld < %lu",
1119                 (long) ret, (unsigned long) len);
1120     }
1121 }
This page took 0.08301 seconds and 4 git commands to generate.