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