]> git.proxmox.com Git - mirror_qemu.git/blob - slirp/slirp.c
slirp: add clock_get_ns() callback
[mirror_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 "qemu/osdep.h"
25 #include "qemu-common.h"
26 #include "qemu/timer.h"
27 #include "qemu/error-report.h"
28 #include "chardev/char-fe.h"
29 #include "migration/register.h"
30 #include "slirp.h"
31 #include "hw/hw.h"
32 #include "qemu/cutils.h"
33
34 #ifndef _WIN32
35 #include <net/if.h>
36 #endif
37
38 int slirp_debug;
39
40 /* Define to 1 if you want KEEPALIVE timers */
41 bool slirp_do_keepalive;
42
43 /* host loopback address */
44 struct in_addr loopback_addr;
45 /* host loopback network mask */
46 unsigned long loopback_mask;
47
48 /* emulated hosts use the MAC addr 52:55:IP:IP:IP:IP */
49 static const uint8_t special_ethaddr[ETH_ALEN] = {
50 0x52, 0x55, 0x00, 0x00, 0x00, 0x00
51 };
52
53 u_int curtime;
54
55 static QTAILQ_HEAD(, Slirp) slirp_instances =
56 QTAILQ_HEAD_INITIALIZER(slirp_instances);
57
58 static struct in_addr dns_addr;
59 #ifndef _WIN32
60 static struct in6_addr dns6_addr;
61 #endif
62 static u_int dns_addr_time;
63 #ifndef _WIN32
64 static u_int dns6_addr_time;
65 #endif
66
67 #define TIMEOUT_FAST 2 /* milliseconds */
68 #define TIMEOUT_SLOW 499 /* milliseconds */
69 /* for the aging of certain requests like DNS */
70 #define TIMEOUT_DEFAULT 1000 /* milliseconds */
71
72 #ifdef _WIN32
73
74 int get_dns_addr(struct in_addr *pdns_addr)
75 {
76 FIXED_INFO *FixedInfo=NULL;
77 ULONG BufLen;
78 DWORD ret;
79 IP_ADDR_STRING *pIPAddr;
80 struct in_addr tmp_addr;
81
82 if (dns_addr.s_addr != 0 && (curtime - dns_addr_time) < TIMEOUT_DEFAULT) {
83 *pdns_addr = dns_addr;
84 return 0;
85 }
86
87 FixedInfo = (FIXED_INFO *)GlobalAlloc(GPTR, sizeof(FIXED_INFO));
88 BufLen = sizeof(FIXED_INFO);
89
90 if (ERROR_BUFFER_OVERFLOW == GetNetworkParams(FixedInfo, &BufLen)) {
91 if (FixedInfo) {
92 GlobalFree(FixedInfo);
93 FixedInfo = NULL;
94 }
95 FixedInfo = GlobalAlloc(GPTR, BufLen);
96 }
97
98 if ((ret = GetNetworkParams(FixedInfo, &BufLen)) != ERROR_SUCCESS) {
99 printf("GetNetworkParams failed. ret = %08x\n", (u_int)ret );
100 if (FixedInfo) {
101 GlobalFree(FixedInfo);
102 FixedInfo = NULL;
103 }
104 return -1;
105 }
106
107 pIPAddr = &(FixedInfo->DnsServerList);
108 inet_aton(pIPAddr->IpAddress.String, &tmp_addr);
109 *pdns_addr = tmp_addr;
110 dns_addr = tmp_addr;
111 dns_addr_time = curtime;
112 if (FixedInfo) {
113 GlobalFree(FixedInfo);
114 FixedInfo = NULL;
115 }
116 return 0;
117 }
118
119 int get_dns6_addr(struct in6_addr *pdns6_addr, uint32_t *scope_id)
120 {
121 return -1;
122 }
123
124 static void winsock_cleanup(void)
125 {
126 WSACleanup();
127 }
128
129 #else
130
131 static int get_dns_addr_cached(void *pdns_addr, void *cached_addr,
132 socklen_t addrlen,
133 struct stat *cached_stat, u_int *cached_time)
134 {
135 struct stat old_stat;
136 if (curtime - *cached_time < TIMEOUT_DEFAULT) {
137 memcpy(pdns_addr, cached_addr, addrlen);
138 return 0;
139 }
140 old_stat = *cached_stat;
141 if (stat("/etc/resolv.conf", cached_stat) != 0) {
142 return -1;
143 }
144 if (cached_stat->st_dev == old_stat.st_dev
145 && cached_stat->st_ino == old_stat.st_ino
146 && cached_stat->st_size == old_stat.st_size
147 && cached_stat->st_mtime == old_stat.st_mtime) {
148 memcpy(pdns_addr, cached_addr, addrlen);
149 return 0;
150 }
151 return 1;
152 }
153
154 static int get_dns_addr_resolv_conf(int af, void *pdns_addr, void *cached_addr,
155 socklen_t addrlen, uint32_t *scope_id,
156 u_int *cached_time)
157 {
158 char buff[512];
159 char buff2[257];
160 FILE *f;
161 int found = 0;
162 void *tmp_addr = alloca(addrlen);
163 unsigned if_index;
164
165 f = fopen("/etc/resolv.conf", "r");
166 if (!f)
167 return -1;
168
169 DEBUG_MISC("IP address of your DNS(s): ");
170 while (fgets(buff, 512, f) != NULL) {
171 if (sscanf(buff, "nameserver%*[ \t]%256s", buff2) == 1) {
172 char *c = strchr(buff2, '%');
173 if (c) {
174 if_index = if_nametoindex(c + 1);
175 *c = '\0';
176 } else {
177 if_index = 0;
178 }
179
180 if (!inet_pton(af, buff2, tmp_addr)) {
181 continue;
182 }
183 /* If it's the first one, set it to dns_addr */
184 if (!found) {
185 memcpy(pdns_addr, tmp_addr, addrlen);
186 memcpy(cached_addr, tmp_addr, addrlen);
187 if (scope_id) {
188 *scope_id = if_index;
189 }
190 *cached_time = curtime;
191 } else {
192 DEBUG_MISC(", ");
193 }
194
195 if (++found > 3) {
196 DEBUG_MISC("(more)");
197 break;
198 } else if (slirp_debug & DBG_MISC) {
199 char s[INET6_ADDRSTRLEN];
200 const char *res = inet_ntop(af, tmp_addr, s, sizeof(s));
201 if (!res) {
202 res = "(string conversion error)";
203 }
204 DEBUG_MISC("%s", res);
205 }
206 }
207 }
208 fclose(f);
209 if (!found)
210 return -1;
211 return 0;
212 }
213
214 int get_dns_addr(struct in_addr *pdns_addr)
215 {
216 static struct stat dns_addr_stat;
217
218 if (dns_addr.s_addr != 0) {
219 int ret;
220 ret = get_dns_addr_cached(pdns_addr, &dns_addr, sizeof(dns_addr),
221 &dns_addr_stat, &dns_addr_time);
222 if (ret <= 0) {
223 return ret;
224 }
225 }
226 return get_dns_addr_resolv_conf(AF_INET, pdns_addr, &dns_addr,
227 sizeof(dns_addr), NULL, &dns_addr_time);
228 }
229
230 int get_dns6_addr(struct in6_addr *pdns6_addr, uint32_t *scope_id)
231 {
232 static struct stat dns6_addr_stat;
233
234 if (!in6_zero(&dns6_addr)) {
235 int ret;
236 ret = get_dns_addr_cached(pdns6_addr, &dns6_addr, sizeof(dns6_addr),
237 &dns6_addr_stat, &dns6_addr_time);
238 if (ret <= 0) {
239 return ret;
240 }
241 }
242 return get_dns_addr_resolv_conf(AF_INET6, pdns6_addr, &dns6_addr,
243 sizeof(dns6_addr),
244 scope_id, &dns6_addr_time);
245 }
246
247 #endif
248
249 static void slirp_init_once(void)
250 {
251 static int initialized;
252 const char *debug;
253 #ifdef _WIN32
254 WSADATA Data;
255 #endif
256
257 if (initialized) {
258 return;
259 }
260 initialized = 1;
261
262 #ifdef _WIN32
263 WSAStartup(MAKEWORD(2,0), &Data);
264 atexit(winsock_cleanup);
265 #endif
266
267 loopback_addr.s_addr = htonl(INADDR_LOOPBACK);
268 loopback_mask = htonl(IN_CLASSA_NET);
269
270 debug = g_getenv("SLIRP_DEBUG");
271 if (debug) {
272 const GDebugKey keys[] = {
273 { "call", DBG_CALL },
274 { "misc", DBG_MISC },
275 { "error", DBG_ERROR },
276 };
277 slirp_debug = g_parse_debug_string(debug, keys, G_N_ELEMENTS(keys));
278 }
279
280
281 }
282
283 static void slirp_state_save(QEMUFile *f, void *opaque);
284 static int slirp_state_load(QEMUFile *f, void *opaque, int version_id);
285
286 static SaveVMHandlers savevm_slirp_state = {
287 .save_state = slirp_state_save,
288 .load_state = slirp_state_load,
289 };
290
291 Slirp *slirp_init(int restricted, bool in_enabled, struct in_addr vnetwork,
292 struct in_addr vnetmask, struct in_addr vhost,
293 bool in6_enabled,
294 struct in6_addr vprefix_addr6, uint8_t vprefix_len,
295 struct in6_addr vhost6, const char *vhostname,
296 const char *tftp_server_name,
297 const char *tftp_path, const char *bootfile,
298 struct in_addr vdhcp_start, struct in_addr vnameserver,
299 struct in6_addr vnameserver6, const char **vdnssearch,
300 const char *vdomainname,
301 const SlirpCb *callbacks,
302 void *opaque)
303 {
304 Slirp *slirp = g_malloc0(sizeof(Slirp));
305
306 slirp_init_once();
307
308 slirp->cb = callbacks;
309 slirp->grand = g_rand_new();
310 slirp->restricted = restricted;
311
312 slirp->in_enabled = in_enabled;
313 slirp->in6_enabled = in6_enabled;
314
315 if_init(slirp);
316 ip_init(slirp);
317 ip6_init(slirp);
318
319 /* Initialise mbufs *after* setting the MTU */
320 m_init(slirp);
321
322 slirp->vnetwork_addr = vnetwork;
323 slirp->vnetwork_mask = vnetmask;
324 slirp->vhost_addr = vhost;
325 slirp->vprefix_addr6 = vprefix_addr6;
326 slirp->vprefix_len = vprefix_len;
327 slirp->vhost_addr6 = vhost6;
328 if (vhostname) {
329 pstrcpy(slirp->client_hostname, sizeof(slirp->client_hostname),
330 vhostname);
331 }
332 slirp->tftp_prefix = g_strdup(tftp_path);
333 slirp->bootp_filename = g_strdup(bootfile);
334 slirp->vdomainname = g_strdup(vdomainname);
335 slirp->vdhcp_startaddr = vdhcp_start;
336 slirp->vnameserver_addr = vnameserver;
337 slirp->vnameserver_addr6 = vnameserver6;
338 slirp->tftp_server_name = g_strdup(tftp_server_name);
339
340 if (vdnssearch) {
341 translate_dnssearch(slirp, vdnssearch);
342 }
343
344 slirp->opaque = opaque;
345
346 register_savevm_live(NULL, "slirp", 0, 4, &savevm_slirp_state, slirp);
347
348 QTAILQ_INSERT_TAIL(&slirp_instances, slirp, entry);
349
350 return slirp;
351 }
352
353 void slirp_cleanup(Slirp *slirp)
354 {
355 struct gfwd_list *e, *next;
356
357 for (e = slirp->guestfwd_list; e; e = next) {
358 next = e->ex_next;
359 g_free(e->ex_exec);
360 g_free(e);
361 }
362
363 QTAILQ_REMOVE(&slirp_instances, slirp, entry);
364
365 unregister_savevm(NULL, "slirp", slirp);
366
367 ip_cleanup(slirp);
368 ip6_cleanup(slirp);
369 m_cleanup(slirp);
370
371 g_rand_free(slirp->grand);
372
373 g_free(slirp->vdnssearch);
374 g_free(slirp->tftp_prefix);
375 g_free(slirp->bootp_filename);
376 g_free(slirp->vdomainname);
377 g_free(slirp);
378 }
379
380 #define CONN_CANFSEND(so) (((so)->so_state & (SS_FCANTSENDMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED)
381 #define CONN_CANFRCV(so) (((so)->so_state & (SS_FCANTRCVMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED)
382
383 static void slirp_update_timeout(uint32_t *timeout)
384 {
385 Slirp *slirp;
386 uint32_t t;
387
388 if (*timeout <= TIMEOUT_FAST) {
389 return;
390 }
391
392 t = MIN(1000, *timeout);
393
394 /* If we have tcp timeout with slirp, then we will fill @timeout with
395 * more precise value.
396 */
397 QTAILQ_FOREACH(slirp, &slirp_instances, entry) {
398 if (slirp->time_fasttimo) {
399 *timeout = TIMEOUT_FAST;
400 return;
401 }
402 if (slirp->do_slowtimo) {
403 t = MIN(TIMEOUT_SLOW, t);
404 }
405 }
406 *timeout = t;
407 }
408
409 void slirp_pollfds_fill(GArray *pollfds, uint32_t *timeout)
410 {
411 Slirp *slirp;
412 struct socket *so, *so_next;
413
414 if (QTAILQ_EMPTY(&slirp_instances)) {
415 return;
416 }
417
418 /*
419 * First, TCP sockets
420 */
421
422 QTAILQ_FOREACH(slirp, &slirp_instances, entry) {
423 /*
424 * *_slowtimo needs calling if there are IP fragments
425 * in the fragment queue, or there are TCP connections active
426 */
427 slirp->do_slowtimo = ((slirp->tcb.so_next != &slirp->tcb) ||
428 (&slirp->ipq.ip_link != slirp->ipq.ip_link.next));
429
430 for (so = slirp->tcb.so_next; so != &slirp->tcb;
431 so = so_next) {
432 int events = 0;
433
434 so_next = so->so_next;
435
436 so->pollfds_idx = -1;
437
438 /*
439 * See if we need a tcp_fasttimo
440 */
441 if (slirp->time_fasttimo == 0 &&
442 so->so_tcpcb->t_flags & TF_DELACK) {
443 slirp->time_fasttimo = curtime; /* Flag when want a fasttimo */
444 }
445
446 /*
447 * NOFDREF can include still connecting to local-host,
448 * newly socreated() sockets etc. Don't want to select these.
449 */
450 if (so->so_state & SS_NOFDREF || so->s == -1) {
451 continue;
452 }
453
454 /*
455 * Set for reading sockets which are accepting
456 */
457 if (so->so_state & SS_FACCEPTCONN) {
458 GPollFD pfd = {
459 .fd = so->s,
460 .events = G_IO_IN | G_IO_HUP | G_IO_ERR,
461 };
462 so->pollfds_idx = pollfds->len;
463 g_array_append_val(pollfds, pfd);
464 continue;
465 }
466
467 /*
468 * Set for writing sockets which are connecting
469 */
470 if (so->so_state & SS_ISFCONNECTING) {
471 GPollFD pfd = {
472 .fd = so->s,
473 .events = G_IO_OUT | G_IO_ERR,
474 };
475 so->pollfds_idx = pollfds->len;
476 g_array_append_val(pollfds, pfd);
477 continue;
478 }
479
480 /*
481 * Set for writing if we are connected, can send more, and
482 * we have something to send
483 */
484 if (CONN_CANFSEND(so) && so->so_rcv.sb_cc) {
485 events |= G_IO_OUT | G_IO_ERR;
486 }
487
488 /*
489 * Set for reading (and urgent data) if we are connected, can
490 * receive more, and we have room for it XXX /2 ?
491 */
492 if (CONN_CANFRCV(so) &&
493 (so->so_snd.sb_cc < (so->so_snd.sb_datalen/2))) {
494 events |= G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_PRI;
495 }
496
497 if (events) {
498 GPollFD pfd = {
499 .fd = so->s,
500 .events = events,
501 };
502 so->pollfds_idx = pollfds->len;
503 g_array_append_val(pollfds, pfd);
504 }
505 }
506
507 /*
508 * UDP sockets
509 */
510 for (so = slirp->udb.so_next; so != &slirp->udb;
511 so = so_next) {
512 so_next = so->so_next;
513
514 so->pollfds_idx = -1;
515
516 /*
517 * See if it's timed out
518 */
519 if (so->so_expire) {
520 if (so->so_expire <= curtime) {
521 udp_detach(so);
522 continue;
523 } else {
524 slirp->do_slowtimo = true; /* Let socket expire */
525 }
526 }
527
528 /*
529 * When UDP packets are received from over the
530 * link, they're sendto()'d straight away, so
531 * no need for setting for writing
532 * Limit the number of packets queued by this session
533 * to 4. Note that even though we try and limit this
534 * to 4 packets, the session could have more queued
535 * if the packets needed to be fragmented
536 * (XXX <= 4 ?)
537 */
538 if ((so->so_state & SS_ISFCONNECTED) && so->so_queued <= 4) {
539 GPollFD pfd = {
540 .fd = so->s,
541 .events = G_IO_IN | G_IO_HUP | G_IO_ERR,
542 };
543 so->pollfds_idx = pollfds->len;
544 g_array_append_val(pollfds, pfd);
545 }
546 }
547
548 /*
549 * ICMP sockets
550 */
551 for (so = slirp->icmp.so_next; so != &slirp->icmp;
552 so = so_next) {
553 so_next = so->so_next;
554
555 so->pollfds_idx = -1;
556
557 /*
558 * See if it's timed out
559 */
560 if (so->so_expire) {
561 if (so->so_expire <= curtime) {
562 icmp_detach(so);
563 continue;
564 } else {
565 slirp->do_slowtimo = true; /* Let socket expire */
566 }
567 }
568
569 if (so->so_state & SS_ISFCONNECTED) {
570 GPollFD pfd = {
571 .fd = so->s,
572 .events = G_IO_IN | G_IO_HUP | G_IO_ERR,
573 };
574 so->pollfds_idx = pollfds->len;
575 g_array_append_val(pollfds, pfd);
576 }
577 }
578 }
579 slirp_update_timeout(timeout);
580 }
581
582 void slirp_pollfds_poll(GArray *pollfds, int select_error)
583 {
584 Slirp *slirp = QTAILQ_FIRST(&slirp_instances);
585 struct socket *so, *so_next;
586 int ret;
587
588 if (!slirp) {
589 return;
590 }
591
592 curtime = slirp->cb->clock_get_ns() / SCALE_MS;
593
594 QTAILQ_FOREACH(slirp, &slirp_instances, entry) {
595 /*
596 * See if anything has timed out
597 */
598 if (slirp->time_fasttimo &&
599 ((curtime - slirp->time_fasttimo) >= TIMEOUT_FAST)) {
600 tcp_fasttimo(slirp);
601 slirp->time_fasttimo = 0;
602 }
603 if (slirp->do_slowtimo &&
604 ((curtime - slirp->last_slowtimo) >= TIMEOUT_SLOW)) {
605 ip_slowtimo(slirp);
606 tcp_slowtimo(slirp);
607 slirp->last_slowtimo = curtime;
608 }
609
610 /*
611 * Check sockets
612 */
613 if (!select_error) {
614 /*
615 * Check TCP sockets
616 */
617 for (so = slirp->tcb.so_next; so != &slirp->tcb;
618 so = so_next) {
619 int revents;
620
621 so_next = so->so_next;
622
623 revents = 0;
624 if (so->pollfds_idx != -1) {
625 revents = g_array_index(pollfds, GPollFD,
626 so->pollfds_idx).revents;
627 }
628
629 if (so->so_state & SS_NOFDREF || so->s == -1) {
630 continue;
631 }
632
633 /*
634 * Check for URG data
635 * This will soread as well, so no need to
636 * test for G_IO_IN below if this succeeds
637 */
638 if (revents & G_IO_PRI) {
639 ret = sorecvoob(so);
640 if (ret < 0) {
641 /* Socket error might have resulted in the socket being
642 * removed, do not try to do anything more with it. */
643 continue;
644 }
645 }
646 /*
647 * Check sockets for reading
648 */
649 else if (revents & (G_IO_IN | G_IO_HUP | G_IO_ERR)) {
650 /*
651 * Check for incoming connections
652 */
653 if (so->so_state & SS_FACCEPTCONN) {
654 tcp_connect(so);
655 continue;
656 } /* else */
657 ret = soread(so);
658
659 /* Output it if we read something */
660 if (ret > 0) {
661 tcp_output(sototcpcb(so));
662 }
663 if (ret < 0) {
664 /* Socket error might have resulted in the socket being
665 * removed, do not try to do anything more with it. */
666 continue;
667 }
668 }
669
670 /*
671 * Check sockets for writing
672 */
673 if (!(so->so_state & SS_NOFDREF) &&
674 (revents & (G_IO_OUT | G_IO_ERR))) {
675 /*
676 * Check for non-blocking, still-connecting sockets
677 */
678 if (so->so_state & SS_ISFCONNECTING) {
679 /* Connected */
680 so->so_state &= ~SS_ISFCONNECTING;
681
682 ret = send(so->s, (const void *) &ret, 0, 0);
683 if (ret < 0) {
684 /* XXXXX Must fix, zero bytes is a NOP */
685 if (errno == EAGAIN || errno == EWOULDBLOCK ||
686 errno == EINPROGRESS || errno == ENOTCONN) {
687 continue;
688 }
689
690 /* else failed */
691 so->so_state &= SS_PERSISTENT_MASK;
692 so->so_state |= SS_NOFDREF;
693 }
694 /* else so->so_state &= ~SS_ISFCONNECTING; */
695
696 /*
697 * Continue tcp_input
698 */
699 tcp_input((struct mbuf *)NULL, sizeof(struct ip), so,
700 so->so_ffamily);
701 /* continue; */
702 } else {
703 ret = sowrite(so);
704 if (ret > 0) {
705 /* Call tcp_output in case we need to send a window
706 * update to the guest, otherwise it will be stuck
707 * until it sends a window probe. */
708 tcp_output(sototcpcb(so));
709 }
710 }
711 }
712 }
713
714 /*
715 * Now UDP sockets.
716 * Incoming packets are sent straight away, they're not buffered.
717 * Incoming UDP data isn't buffered either.
718 */
719 for (so = slirp->udb.so_next; so != &slirp->udb;
720 so = so_next) {
721 int revents;
722
723 so_next = so->so_next;
724
725 revents = 0;
726 if (so->pollfds_idx != -1) {
727 revents = g_array_index(pollfds, GPollFD,
728 so->pollfds_idx).revents;
729 }
730
731 if (so->s != -1 &&
732 (revents & (G_IO_IN | G_IO_HUP | G_IO_ERR))) {
733 sorecvfrom(so);
734 }
735 }
736
737 /*
738 * Check incoming ICMP relies.
739 */
740 for (so = slirp->icmp.so_next; so != &slirp->icmp;
741 so = so_next) {
742 int revents;
743
744 so_next = so->so_next;
745
746 revents = 0;
747 if (so->pollfds_idx != -1) {
748 revents = g_array_index(pollfds, GPollFD,
749 so->pollfds_idx).revents;
750 }
751
752 if (so->s != -1 &&
753 (revents & (G_IO_IN | G_IO_HUP | G_IO_ERR))) {
754 icmp_receive(so);
755 }
756 }
757 }
758
759 if_start(slirp);
760 }
761 }
762
763 static void arp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len)
764 {
765 struct slirp_arphdr *ah = (struct slirp_arphdr *)(pkt + ETH_HLEN);
766 uint8_t arp_reply[MAX(ETH_HLEN + sizeof(struct slirp_arphdr), 64)];
767 struct ethhdr *reh = (struct ethhdr *)arp_reply;
768 struct slirp_arphdr *rah = (struct slirp_arphdr *)(arp_reply + ETH_HLEN);
769 int ar_op;
770 struct gfwd_list *ex_ptr;
771
772 if (!slirp->in_enabled) {
773 return;
774 }
775
776 ar_op = ntohs(ah->ar_op);
777 switch(ar_op) {
778 case ARPOP_REQUEST:
779 if (ah->ar_tip == ah->ar_sip) {
780 /* Gratuitous ARP */
781 arp_table_add(slirp, ah->ar_sip, ah->ar_sha);
782 return;
783 }
784
785 if ((ah->ar_tip & slirp->vnetwork_mask.s_addr) ==
786 slirp->vnetwork_addr.s_addr) {
787 if (ah->ar_tip == slirp->vnameserver_addr.s_addr ||
788 ah->ar_tip == slirp->vhost_addr.s_addr)
789 goto arp_ok;
790 for (ex_ptr = slirp->guestfwd_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
791 if (ex_ptr->ex_addr.s_addr == ah->ar_tip)
792 goto arp_ok;
793 }
794 return;
795 arp_ok:
796 memset(arp_reply, 0, sizeof(arp_reply));
797
798 arp_table_add(slirp, ah->ar_sip, ah->ar_sha);
799
800 /* ARP request for alias/dns mac address */
801 memcpy(reh->h_dest, pkt + ETH_ALEN, ETH_ALEN);
802 memcpy(reh->h_source, special_ethaddr, ETH_ALEN - 4);
803 memcpy(&reh->h_source[2], &ah->ar_tip, 4);
804 reh->h_proto = htons(ETH_P_ARP);
805
806 rah->ar_hrd = htons(1);
807 rah->ar_pro = htons(ETH_P_IP);
808 rah->ar_hln = ETH_ALEN;
809 rah->ar_pln = 4;
810 rah->ar_op = htons(ARPOP_REPLY);
811 memcpy(rah->ar_sha, reh->h_source, ETH_ALEN);
812 rah->ar_sip = ah->ar_tip;
813 memcpy(rah->ar_tha, ah->ar_sha, ETH_ALEN);
814 rah->ar_tip = ah->ar_sip;
815 slirp->cb->output(slirp->opaque, arp_reply, sizeof(arp_reply));
816 }
817 break;
818 case ARPOP_REPLY:
819 arp_table_add(slirp, ah->ar_sip, ah->ar_sha);
820 break;
821 default:
822 break;
823 }
824 }
825
826 void slirp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len)
827 {
828 struct mbuf *m;
829 int proto;
830
831 if (pkt_len < ETH_HLEN)
832 return;
833
834 proto = ntohs(*(uint16_t *)(pkt + 12));
835 switch(proto) {
836 case ETH_P_ARP:
837 arp_input(slirp, pkt, pkt_len);
838 break;
839 case ETH_P_IP:
840 case ETH_P_IPV6:
841 m = m_get(slirp);
842 if (!m)
843 return;
844 /* Note: we add 2 to align the IP header on 4 bytes,
845 * and add the margin for the tcpiphdr overhead */
846 if (M_FREEROOM(m) < pkt_len + TCPIPHDR_DELTA + 2) {
847 m_inc(m, pkt_len + TCPIPHDR_DELTA + 2);
848 }
849 m->m_len = pkt_len + TCPIPHDR_DELTA + 2;
850 memcpy(m->m_data + TCPIPHDR_DELTA + 2, pkt, pkt_len);
851
852 m->m_data += TCPIPHDR_DELTA + 2 + ETH_HLEN;
853 m->m_len -= TCPIPHDR_DELTA + 2 + ETH_HLEN;
854
855 if (proto == ETH_P_IP) {
856 ip_input(m);
857 } else if (proto == ETH_P_IPV6) {
858 ip6_input(m);
859 }
860 break;
861
862 case ETH_P_NCSI:
863 ncsi_input(slirp, pkt, pkt_len);
864 break;
865
866 default:
867 break;
868 }
869 }
870
871 /* Prepare the IPv4 packet to be sent to the ethernet device. Returns 1 if no
872 * packet should be sent, 0 if the packet must be re-queued, 2 if the packet
873 * is ready to go.
874 */
875 static int if_encap4(Slirp *slirp, struct mbuf *ifm, struct ethhdr *eh,
876 uint8_t ethaddr[ETH_ALEN])
877 {
878 const struct ip *iph = (const struct ip *)ifm->m_data;
879
880 if (iph->ip_dst.s_addr == 0) {
881 /* 0.0.0.0 can not be a destination address, something went wrong,
882 * avoid making it worse */
883 return 1;
884 }
885 if (!arp_table_search(slirp, iph->ip_dst.s_addr, ethaddr)) {
886 uint8_t arp_req[ETH_HLEN + sizeof(struct slirp_arphdr)];
887 struct ethhdr *reh = (struct ethhdr *)arp_req;
888 struct slirp_arphdr *rah = (struct slirp_arphdr *)(arp_req + ETH_HLEN);
889
890 if (!ifm->resolution_requested) {
891 /* If the client addr is not known, send an ARP request */
892 memset(reh->h_dest, 0xff, ETH_ALEN);
893 memcpy(reh->h_source, special_ethaddr, ETH_ALEN - 4);
894 memcpy(&reh->h_source[2], &slirp->vhost_addr, 4);
895 reh->h_proto = htons(ETH_P_ARP);
896 rah->ar_hrd = htons(1);
897 rah->ar_pro = htons(ETH_P_IP);
898 rah->ar_hln = ETH_ALEN;
899 rah->ar_pln = 4;
900 rah->ar_op = htons(ARPOP_REQUEST);
901
902 /* source hw addr */
903 memcpy(rah->ar_sha, special_ethaddr, ETH_ALEN - 4);
904 memcpy(&rah->ar_sha[2], &slirp->vhost_addr, 4);
905
906 /* source IP */
907 rah->ar_sip = slirp->vhost_addr.s_addr;
908
909 /* target hw addr (none) */
910 memset(rah->ar_tha, 0, ETH_ALEN);
911
912 /* target IP */
913 rah->ar_tip = iph->ip_dst.s_addr;
914 slirp->client_ipaddr = iph->ip_dst;
915 slirp->cb->output(slirp->opaque, arp_req, sizeof(arp_req));
916 ifm->resolution_requested = true;
917
918 /* Expire request and drop outgoing packet after 1 second */
919 ifm->expiration_date = slirp->cb->clock_get_ns() + 1000000000ULL;
920 }
921 return 0;
922 } else {
923 memcpy(eh->h_source, special_ethaddr, ETH_ALEN - 4);
924 /* XXX: not correct */
925 memcpy(&eh->h_source[2], &slirp->vhost_addr, 4);
926 eh->h_proto = htons(ETH_P_IP);
927
928 /* Send this */
929 return 2;
930 }
931 }
932
933 /* Prepare the IPv6 packet to be sent to the ethernet device. Returns 1 if no
934 * packet should be sent, 0 if the packet must be re-queued, 2 if the packet
935 * is ready to go.
936 */
937 static int if_encap6(Slirp *slirp, struct mbuf *ifm, struct ethhdr *eh,
938 uint8_t ethaddr[ETH_ALEN])
939 {
940 const struct ip6 *ip6h = mtod(ifm, const struct ip6 *);
941 if (!ndp_table_search(slirp, ip6h->ip_dst, ethaddr)) {
942 if (!ifm->resolution_requested) {
943 ndp_send_ns(slirp, ip6h->ip_dst);
944 ifm->resolution_requested = true;
945 ifm->expiration_date = slirp->cb->clock_get_ns() + 1000000000ULL;
946 }
947 return 0;
948 } else {
949 eh->h_proto = htons(ETH_P_IPV6);
950 in6_compute_ethaddr(ip6h->ip_src, eh->h_source);
951
952 /* Send this */
953 return 2;
954 }
955 }
956
957 /* Output the IP packet to the ethernet device. Returns 0 if the packet must be
958 * re-queued.
959 */
960 int if_encap(Slirp *slirp, struct mbuf *ifm)
961 {
962 uint8_t buf[1600];
963 struct ethhdr *eh = (struct ethhdr *)buf;
964 uint8_t ethaddr[ETH_ALEN];
965 const struct ip *iph = (const struct ip *)ifm->m_data;
966 int ret;
967
968 if (ifm->m_len + ETH_HLEN > sizeof(buf)) {
969 return 1;
970 }
971
972 switch (iph->ip_v) {
973 case IPVERSION:
974 ret = if_encap4(slirp, ifm, eh, ethaddr);
975 if (ret < 2) {
976 return ret;
977 }
978 break;
979
980 case IP6VERSION:
981 ret = if_encap6(slirp, ifm, eh, ethaddr);
982 if (ret < 2) {
983 return ret;
984 }
985 break;
986
987 default:
988 g_assert_not_reached();
989 break;
990 }
991
992 memcpy(eh->h_dest, ethaddr, ETH_ALEN);
993 DEBUG_ARG("src = %02x:%02x:%02x:%02x:%02x:%02x",
994 eh->h_source[0], eh->h_source[1], eh->h_source[2],
995 eh->h_source[3], eh->h_source[4], eh->h_source[5]);
996 DEBUG_ARG("dst = %02x:%02x:%02x:%02x:%02x:%02x",
997 eh->h_dest[0], eh->h_dest[1], eh->h_dest[2],
998 eh->h_dest[3], eh->h_dest[4], eh->h_dest[5]);
999 memcpy(buf + sizeof(struct ethhdr), ifm->m_data, ifm->m_len);
1000 slirp->cb->output(slirp->opaque, buf, ifm->m_len + ETH_HLEN);
1001 return 1;
1002 }
1003
1004 /* Drop host forwarding rule, return 0 if found. */
1005 int slirp_remove_hostfwd(Slirp *slirp, int is_udp, struct in_addr host_addr,
1006 int host_port)
1007 {
1008 struct socket *so;
1009 struct socket *head = (is_udp ? &slirp->udb : &slirp->tcb);
1010 struct sockaddr_in addr;
1011 int port = htons(host_port);
1012 socklen_t addr_len;
1013
1014 for (so = head->so_next; so != head; so = so->so_next) {
1015 addr_len = sizeof(addr);
1016 if ((so->so_state & SS_HOSTFWD) &&
1017 getsockname(so->s, (struct sockaddr *)&addr, &addr_len) == 0 &&
1018 addr.sin_addr.s_addr == host_addr.s_addr &&
1019 addr.sin_port == port) {
1020 close(so->s);
1021 sofree(so);
1022 return 0;
1023 }
1024 }
1025
1026 return -1;
1027 }
1028
1029 int slirp_add_hostfwd(Slirp *slirp, int is_udp, struct in_addr host_addr,
1030 int host_port, struct in_addr guest_addr, int guest_port)
1031 {
1032 if (!guest_addr.s_addr) {
1033 guest_addr = slirp->vdhcp_startaddr;
1034 }
1035 if (is_udp) {
1036 if (!udp_listen(slirp, host_addr.s_addr, htons(host_port),
1037 guest_addr.s_addr, htons(guest_port), SS_HOSTFWD))
1038 return -1;
1039 } else {
1040 if (!tcp_listen(slirp, host_addr.s_addr, htons(host_port),
1041 guest_addr.s_addr, htons(guest_port), SS_HOSTFWD))
1042 return -1;
1043 }
1044 return 0;
1045 }
1046
1047 static bool
1048 check_guestfwd(Slirp *slirp, struct in_addr *guest_addr, int guest_port)
1049 {
1050 struct gfwd_list *tmp_ptr;
1051
1052 if (!guest_addr->s_addr) {
1053 guest_addr->s_addr = slirp->vnetwork_addr.s_addr |
1054 (htonl(0x0204) & ~slirp->vnetwork_mask.s_addr);
1055 }
1056 if ((guest_addr->s_addr & slirp->vnetwork_mask.s_addr) !=
1057 slirp->vnetwork_addr.s_addr ||
1058 guest_addr->s_addr == slirp->vhost_addr.s_addr ||
1059 guest_addr->s_addr == slirp->vnameserver_addr.s_addr) {
1060 return false;
1061 }
1062
1063 /* check if the port is "bound" */
1064 for (tmp_ptr = slirp->guestfwd_list; tmp_ptr; tmp_ptr = tmp_ptr->ex_next) {
1065 if (guest_port == tmp_ptr->ex_fport &&
1066 guest_addr->s_addr == tmp_ptr->ex_addr.s_addr)
1067 return false;
1068 }
1069
1070 return true;
1071 }
1072
1073 int slirp_add_exec(Slirp *slirp, void *chardev, const char *cmdline,
1074 struct in_addr *guest_addr, int guest_port)
1075 {
1076 if (!check_guestfwd(slirp, guest_addr, guest_port)) {
1077 return -1;
1078 }
1079
1080 return add_exec(&slirp->guestfwd_list, chardev, cmdline, *guest_addr,
1081 htons(guest_port));
1082 }
1083
1084 ssize_t slirp_send(struct socket *so, const void *buf, size_t len, int flags)
1085 {
1086 if (so->s == -1 && so->chardev) {
1087 /* XXX this blocks entire thread. Rewrite to use
1088 * qemu_chr_fe_write and background I/O callbacks */
1089 qemu_chr_fe_write_all(so->chardev, buf, len);
1090 return len;
1091 }
1092
1093 if (so->s == -1) {
1094 /*
1095 * This should in theory not happen but it is hard to be
1096 * sure because some code paths will end up with so->s == -1
1097 * on a failure but don't dispose of the struct socket.
1098 * Check specifically, so we don't pass -1 to send().
1099 */
1100 errno = EBADF;
1101 return -1;
1102 }
1103
1104 return send(so->s, buf, len, flags);
1105 }
1106
1107 static struct socket *
1108 slirp_find_ctl_socket(Slirp *slirp, struct in_addr guest_addr, int guest_port)
1109 {
1110 struct socket *so;
1111
1112 for (so = slirp->tcb.so_next; so != &slirp->tcb; so = so->so_next) {
1113 if (so->so_faddr.s_addr == guest_addr.s_addr &&
1114 htons(so->so_fport) == guest_port) {
1115 return so;
1116 }
1117 }
1118 return NULL;
1119 }
1120
1121 size_t slirp_socket_can_recv(Slirp *slirp, struct in_addr guest_addr,
1122 int guest_port)
1123 {
1124 struct iovec iov[2];
1125 struct socket *so;
1126
1127 so = slirp_find_ctl_socket(slirp, guest_addr, guest_port);
1128
1129 if (!so || so->so_state & SS_NOFDREF) {
1130 return 0;
1131 }
1132
1133 if (!CONN_CANFRCV(so) || so->so_snd.sb_cc >= (so->so_snd.sb_datalen/2)) {
1134 return 0;
1135 }
1136
1137 return sopreprbuf(so, iov, NULL);
1138 }
1139
1140 void slirp_socket_recv(Slirp *slirp, struct in_addr guest_addr, int guest_port,
1141 const uint8_t *buf, int size)
1142 {
1143 int ret;
1144 struct socket *so = slirp_find_ctl_socket(slirp, guest_addr, guest_port);
1145
1146 if (!so)
1147 return;
1148
1149 ret = soreadbuf(so, (const char *)buf, size);
1150
1151 if (ret > 0)
1152 tcp_output(sototcpcb(so));
1153 }
1154
1155 static int slirp_tcp_post_load(void *opaque, int version)
1156 {
1157 tcp_template((struct tcpcb *)opaque);
1158
1159 return 0;
1160 }
1161
1162 static const VMStateDescription vmstate_slirp_tcp = {
1163 .name = "slirp-tcp",
1164 .version_id = 0,
1165 .post_load = slirp_tcp_post_load,
1166 .fields = (VMStateField[]) {
1167 VMSTATE_INT16(t_state, struct tcpcb),
1168 VMSTATE_INT16_ARRAY(t_timer, struct tcpcb, TCPT_NTIMERS),
1169 VMSTATE_INT16(t_rxtshift, struct tcpcb),
1170 VMSTATE_INT16(t_rxtcur, struct tcpcb),
1171 VMSTATE_INT16(t_dupacks, struct tcpcb),
1172 VMSTATE_UINT16(t_maxseg, struct tcpcb),
1173 VMSTATE_UINT8(t_force, struct tcpcb),
1174 VMSTATE_UINT16(t_flags, struct tcpcb),
1175 VMSTATE_UINT32(snd_una, struct tcpcb),
1176 VMSTATE_UINT32(snd_nxt, struct tcpcb),
1177 VMSTATE_UINT32(snd_up, struct tcpcb),
1178 VMSTATE_UINT32(snd_wl1, struct tcpcb),
1179 VMSTATE_UINT32(snd_wl2, struct tcpcb),
1180 VMSTATE_UINT32(iss, struct tcpcb),
1181 VMSTATE_UINT32(snd_wnd, struct tcpcb),
1182 VMSTATE_UINT32(rcv_wnd, struct tcpcb),
1183 VMSTATE_UINT32(rcv_nxt, struct tcpcb),
1184 VMSTATE_UINT32(rcv_up, struct tcpcb),
1185 VMSTATE_UINT32(irs, struct tcpcb),
1186 VMSTATE_UINT32(rcv_adv, struct tcpcb),
1187 VMSTATE_UINT32(snd_max, struct tcpcb),
1188 VMSTATE_UINT32(snd_cwnd, struct tcpcb),
1189 VMSTATE_UINT32(snd_ssthresh, struct tcpcb),
1190 VMSTATE_INT16(t_idle, struct tcpcb),
1191 VMSTATE_INT16(t_rtt, struct tcpcb),
1192 VMSTATE_UINT32(t_rtseq, struct tcpcb),
1193 VMSTATE_INT16(t_srtt, struct tcpcb),
1194 VMSTATE_INT16(t_rttvar, struct tcpcb),
1195 VMSTATE_UINT16(t_rttmin, struct tcpcb),
1196 VMSTATE_UINT32(max_sndwnd, struct tcpcb),
1197 VMSTATE_UINT8(t_oobflags, struct tcpcb),
1198 VMSTATE_UINT8(t_iobc, struct tcpcb),
1199 VMSTATE_INT16(t_softerror, struct tcpcb),
1200 VMSTATE_UINT8(snd_scale, struct tcpcb),
1201 VMSTATE_UINT8(rcv_scale, struct tcpcb),
1202 VMSTATE_UINT8(request_r_scale, struct tcpcb),
1203 VMSTATE_UINT8(requested_s_scale, struct tcpcb),
1204 VMSTATE_UINT32(ts_recent, struct tcpcb),
1205 VMSTATE_UINT32(ts_recent_age, struct tcpcb),
1206 VMSTATE_UINT32(last_ack_sent, struct tcpcb),
1207 VMSTATE_END_OF_LIST()
1208 }
1209 };
1210
1211 /* The sbuf has a pair of pointers that are migrated as offsets;
1212 * we calculate the offsets and restore the pointers using
1213 * pre_save/post_load on a tmp structure.
1214 */
1215 struct sbuf_tmp {
1216 struct sbuf *parent;
1217 uint32_t roff, woff;
1218 };
1219
1220 static int sbuf_tmp_pre_save(void *opaque)
1221 {
1222 struct sbuf_tmp *tmp = opaque;
1223 tmp->woff = tmp->parent->sb_wptr - tmp->parent->sb_data;
1224 tmp->roff = tmp->parent->sb_rptr - tmp->parent->sb_data;
1225
1226 return 0;
1227 }
1228
1229 static int sbuf_tmp_post_load(void *opaque, int version)
1230 {
1231 struct sbuf_tmp *tmp = opaque;
1232 uint32_t requested_len = tmp->parent->sb_datalen;
1233
1234 /* Allocate the buffer space used by the field after the tmp */
1235 sbreserve(tmp->parent, tmp->parent->sb_datalen);
1236
1237 if (tmp->parent->sb_datalen != requested_len) {
1238 return -ENOMEM;
1239 }
1240 if (tmp->woff >= requested_len ||
1241 tmp->roff >= requested_len) {
1242 g_critical("invalid sbuf offsets r/w=%u/%u len=%u",
1243 tmp->roff, tmp->woff, requested_len);
1244 return -EINVAL;
1245 }
1246
1247 tmp->parent->sb_wptr = tmp->parent->sb_data + tmp->woff;
1248 tmp->parent->sb_rptr = tmp->parent->sb_data + tmp->roff;
1249
1250 return 0;
1251 }
1252
1253
1254 static const VMStateDescription vmstate_slirp_sbuf_tmp = {
1255 .name = "slirp-sbuf-tmp",
1256 .post_load = sbuf_tmp_post_load,
1257 .pre_save = sbuf_tmp_pre_save,
1258 .version_id = 0,
1259 .fields = (VMStateField[]) {
1260 VMSTATE_UINT32(woff, struct sbuf_tmp),
1261 VMSTATE_UINT32(roff, struct sbuf_tmp),
1262 VMSTATE_END_OF_LIST()
1263 }
1264 };
1265
1266 static const VMStateDescription vmstate_slirp_sbuf = {
1267 .name = "slirp-sbuf",
1268 .version_id = 0,
1269 .fields = (VMStateField[]) {
1270 VMSTATE_UINT32(sb_cc, struct sbuf),
1271 VMSTATE_UINT32(sb_datalen, struct sbuf),
1272 VMSTATE_WITH_TMP(struct sbuf, struct sbuf_tmp, vmstate_slirp_sbuf_tmp),
1273 VMSTATE_VBUFFER_UINT32(sb_data, struct sbuf, 0, NULL, sb_datalen),
1274 VMSTATE_END_OF_LIST()
1275 }
1276 };
1277
1278 static bool slirp_older_than_v4(void *opaque, int version_id)
1279 {
1280 return version_id < 4;
1281 }
1282
1283 static bool slirp_family_inet(void *opaque, int version_id)
1284 {
1285 union slirp_sockaddr *ssa = (union slirp_sockaddr *)opaque;
1286 return ssa->ss.ss_family == AF_INET;
1287 }
1288
1289 static int slirp_socket_pre_load(void *opaque)
1290 {
1291 struct socket *so = opaque;
1292 if (tcp_attach(so) < 0) {
1293 return -ENOMEM;
1294 }
1295 /* Older versions don't load these fields */
1296 so->so_ffamily = AF_INET;
1297 so->so_lfamily = AF_INET;
1298 return 0;
1299 }
1300
1301 #ifndef _WIN32
1302 #define VMSTATE_SIN4_ADDR(f, s, t) VMSTATE_UINT32_TEST(f, s, t)
1303 #else
1304 /* Win uses u_long rather than uint32_t - but it's still 32bits long */
1305 #define VMSTATE_SIN4_ADDR(f, s, t) VMSTATE_SINGLE_TEST(f, s, t, 0, \
1306 vmstate_info_uint32, u_long)
1307 #endif
1308
1309 /* The OS provided ss_family field isn't that portable; it's size
1310 * and type varies (16/8 bit, signed, unsigned)
1311 * and the values it contains aren't fully portable.
1312 */
1313 typedef struct SS_FamilyTmpStruct {
1314 union slirp_sockaddr *parent;
1315 uint16_t portable_family;
1316 } SS_FamilyTmpStruct;
1317
1318 #define SS_FAMILY_MIG_IPV4 2 /* Linux, BSD, Win... */
1319 #define SS_FAMILY_MIG_IPV6 10 /* Linux */
1320 #define SS_FAMILY_MIG_OTHER 0xffff
1321
1322 static int ss_family_pre_save(void *opaque)
1323 {
1324 SS_FamilyTmpStruct *tss = opaque;
1325
1326 tss->portable_family = SS_FAMILY_MIG_OTHER;
1327
1328 if (tss->parent->ss.ss_family == AF_INET) {
1329 tss->portable_family = SS_FAMILY_MIG_IPV4;
1330 } else if (tss->parent->ss.ss_family == AF_INET6) {
1331 tss->portable_family = SS_FAMILY_MIG_IPV6;
1332 }
1333
1334 return 0;
1335 }
1336
1337 static int ss_family_post_load(void *opaque, int version_id)
1338 {
1339 SS_FamilyTmpStruct *tss = opaque;
1340
1341 switch (tss->portable_family) {
1342 case SS_FAMILY_MIG_IPV4:
1343 tss->parent->ss.ss_family = AF_INET;
1344 break;
1345 case SS_FAMILY_MIG_IPV6:
1346 case 23: /* compatibility: AF_INET6 from mingw */
1347 case 28: /* compatibility: AF_INET6 from FreeBSD sys/socket.h */
1348 tss->parent->ss.ss_family = AF_INET6;
1349 break;
1350 default:
1351 g_critical("invalid ss_family type %x", tss->portable_family);
1352 return -EINVAL;
1353 }
1354
1355 return 0;
1356 }
1357
1358 static const VMStateDescription vmstate_slirp_ss_family = {
1359 .name = "slirp-socket-addr/ss_family",
1360 .pre_save = ss_family_pre_save,
1361 .post_load = ss_family_post_load,
1362 .fields = (VMStateField[]) {
1363 VMSTATE_UINT16(portable_family, SS_FamilyTmpStruct),
1364 VMSTATE_END_OF_LIST()
1365 }
1366 };
1367
1368 static const VMStateDescription vmstate_slirp_socket_addr = {
1369 .name = "slirp-socket-addr",
1370 .version_id = 4,
1371 .fields = (VMStateField[]) {
1372 VMSTATE_WITH_TMP(union slirp_sockaddr, SS_FamilyTmpStruct,
1373 vmstate_slirp_ss_family),
1374 VMSTATE_SIN4_ADDR(sin.sin_addr.s_addr, union slirp_sockaddr,
1375 slirp_family_inet),
1376 VMSTATE_UINT16_TEST(sin.sin_port, union slirp_sockaddr,
1377 slirp_family_inet),
1378
1379 #if 0
1380 /* Untested: Needs checking by someone with IPv6 test */
1381 VMSTATE_BUFFER_TEST(sin6.sin6_addr, union slirp_sockaddr,
1382 slirp_family_inet6),
1383 VMSTATE_UINT16_TEST(sin6.sin6_port, union slirp_sockaddr,
1384 slirp_family_inet6),
1385 VMSTATE_UINT32_TEST(sin6.sin6_flowinfo, union slirp_sockaddr,
1386 slirp_family_inet6),
1387 VMSTATE_UINT32_TEST(sin6.sin6_scope_id, union slirp_sockaddr,
1388 slirp_family_inet6),
1389 #endif
1390
1391 VMSTATE_END_OF_LIST()
1392 }
1393 };
1394
1395 static const VMStateDescription vmstate_slirp_socket = {
1396 .name = "slirp-socket",
1397 .version_id = 4,
1398 .pre_load = slirp_socket_pre_load,
1399 .fields = (VMStateField[]) {
1400 VMSTATE_UINT32(so_urgc, struct socket),
1401 /* Pre-v4 versions */
1402 VMSTATE_SIN4_ADDR(so_faddr.s_addr, struct socket,
1403 slirp_older_than_v4),
1404 VMSTATE_SIN4_ADDR(so_laddr.s_addr, struct socket,
1405 slirp_older_than_v4),
1406 VMSTATE_UINT16_TEST(so_fport, struct socket, slirp_older_than_v4),
1407 VMSTATE_UINT16_TEST(so_lport, struct socket, slirp_older_than_v4),
1408 /* v4 and newer */
1409 VMSTATE_STRUCT(fhost, struct socket, 4, vmstate_slirp_socket_addr,
1410 union slirp_sockaddr),
1411 VMSTATE_STRUCT(lhost, struct socket, 4, vmstate_slirp_socket_addr,
1412 union slirp_sockaddr),
1413
1414 VMSTATE_UINT8(so_iptos, struct socket),
1415 VMSTATE_UINT8(so_emu, struct socket),
1416 VMSTATE_UINT8(so_type, struct socket),
1417 VMSTATE_INT32(so_state, struct socket),
1418 VMSTATE_STRUCT(so_rcv, struct socket, 0, vmstate_slirp_sbuf,
1419 struct sbuf),
1420 VMSTATE_STRUCT(so_snd, struct socket, 0, vmstate_slirp_sbuf,
1421 struct sbuf),
1422 VMSTATE_STRUCT_POINTER(so_tcpcb, struct socket, vmstate_slirp_tcp,
1423 struct tcpcb),
1424 VMSTATE_END_OF_LIST()
1425 }
1426 };
1427
1428 static const VMStateDescription vmstate_slirp_bootp_client = {
1429 .name = "slirp_bootpclient",
1430 .fields = (VMStateField[]) {
1431 VMSTATE_UINT16(allocated, BOOTPClient),
1432 VMSTATE_BUFFER(macaddr, BOOTPClient),
1433 VMSTATE_END_OF_LIST()
1434 }
1435 };
1436
1437 static const VMStateDescription vmstate_slirp = {
1438 .name = "slirp",
1439 .version_id = 4,
1440 .fields = (VMStateField[]) {
1441 VMSTATE_UINT16_V(ip_id, Slirp, 2),
1442 VMSTATE_STRUCT_ARRAY(bootp_clients, Slirp, NB_BOOTP_CLIENTS, 3,
1443 vmstate_slirp_bootp_client, BOOTPClient),
1444 VMSTATE_END_OF_LIST()
1445 }
1446 };
1447
1448 static void slirp_state_save(QEMUFile *f, void *opaque)
1449 {
1450 Slirp *slirp = opaque;
1451 struct gfwd_list *ex_ptr;
1452
1453 for (ex_ptr = slirp->guestfwd_list; ex_ptr; ex_ptr = ex_ptr->ex_next)
1454 if (ex_ptr->ex_chardev) {
1455 struct socket *so;
1456 so = slirp_find_ctl_socket(slirp, ex_ptr->ex_addr,
1457 ntohs(ex_ptr->ex_fport));
1458 if (!so)
1459 continue;
1460
1461 qemu_put_byte(f, 42);
1462 vmstate_save_state(f, &vmstate_slirp_socket, so, NULL);
1463 }
1464 qemu_put_byte(f, 0);
1465
1466 vmstate_save_state(f, &vmstate_slirp, slirp, NULL);
1467 }
1468
1469
1470 static int slirp_state_load(QEMUFile *f, void *opaque, int version_id)
1471 {
1472 Slirp *slirp = opaque;
1473 struct gfwd_list *ex_ptr;
1474
1475 while (qemu_get_byte(f)) {
1476 int ret;
1477 struct socket *so = socreate(slirp);
1478
1479 ret = vmstate_load_state(f, &vmstate_slirp_socket, so, version_id);
1480
1481 if (ret < 0)
1482 return ret;
1483
1484 if ((so->so_faddr.s_addr & slirp->vnetwork_mask.s_addr) !=
1485 slirp->vnetwork_addr.s_addr) {
1486 return -EINVAL;
1487 }
1488 for (ex_ptr = slirp->guestfwd_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
1489 if (ex_ptr->ex_chardev &&
1490 so->so_faddr.s_addr == ex_ptr->ex_addr.s_addr &&
1491 so->so_fport == ex_ptr->ex_fport) {
1492 break;
1493 }
1494 }
1495 if (!ex_ptr)
1496 return -EINVAL;
1497 }
1498
1499 return vmstate_load_state(f, &vmstate_slirp, slirp, version_id);
1500 }