1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#include "qemu-common.h"
25#include "qemu-timer.h"
26#include "qemu-char.h"
27#include "slirp.h"
28#include "hw/hw.h"
29
30
31struct in_addr loopback_addr;
32
33
34static const uint8_t special_ethaddr[6] = {
35 0x52, 0x55, 0x00, 0x00, 0x00, 0x00
36};
37
38static const uint8_t zero_ethaddr[6] = { 0, 0, 0, 0, 0, 0 };
39
40
41fd_set *global_readfds, *global_writefds, *global_xfds;
42
43u_int curtime;
44static u_int time_fasttimo, last_slowtimo;
45static int do_slowtimo;
46
47static QTAILQ_HEAD(slirp_instances, Slirp) slirp_instances =
48 QTAILQ_HEAD_INITIALIZER(slirp_instances);
49
50static struct in_addr dns_addr;
51static u_int dns_addr_time;
52
53#ifdef _WIN32
54
55int get_dns_addr(struct in_addr *pdns_addr)
56{
57 FIXED_INFO *FixedInfo=NULL;
58 ULONG BufLen;
59 DWORD ret;
60 IP_ADDR_STRING *pIPAddr;
61 struct in_addr tmp_addr;
62
63 if (dns_addr.s_addr != 0 && (curtime - dns_addr_time) < 1000) {
64 *pdns_addr = dns_addr;
65 return 0;
66 }
67
68 FixedInfo = (FIXED_INFO *)GlobalAlloc(GPTR, sizeof(FIXED_INFO));
69 BufLen = sizeof(FIXED_INFO);
70
71 if (ERROR_BUFFER_OVERFLOW == GetNetworkParams(FixedInfo, &BufLen)) {
72 if (FixedInfo) {
73 GlobalFree(FixedInfo);
74 FixedInfo = NULL;
75 }
76 FixedInfo = GlobalAlloc(GPTR, BufLen);
77 }
78
79 if ((ret = GetNetworkParams(FixedInfo, &BufLen)) != ERROR_SUCCESS) {
80 printf("GetNetworkParams failed. ret = %08x\n", (u_int)ret );
81 if (FixedInfo) {
82 GlobalFree(FixedInfo);
83 FixedInfo = NULL;
84 }
85 return -1;
86 }
87
88 pIPAddr = &(FixedInfo->DnsServerList);
89 inet_aton(pIPAddr->IpAddress.String, &tmp_addr);
90 *pdns_addr = tmp_addr;
91 dns_addr = tmp_addr;
92 dns_addr_time = curtime;
93 if (FixedInfo) {
94 GlobalFree(FixedInfo);
95 FixedInfo = NULL;
96 }
97 return 0;
98}
99
100static void winsock_cleanup(void)
101{
102 WSACleanup();
103}
104
105#else
106
107static struct stat dns_addr_stat;
108
109int get_dns_addr(struct in_addr *pdns_addr)
110{
111 char buff[512];
112 char buff2[257];
113 FILE *f;
114 int found = 0;
115 struct in_addr tmp_addr;
116
117 if (dns_addr.s_addr != 0) {
118 struct stat old_stat;
119 if ((curtime - dns_addr_time) < 1000) {
120 *pdns_addr = dns_addr;
121 return 0;
122 }
123 old_stat = dns_addr_stat;
124 if (stat("/etc/resolv.conf", &dns_addr_stat) != 0)
125 return -1;
126 if ((dns_addr_stat.st_dev == old_stat.st_dev)
127 && (dns_addr_stat.st_ino == old_stat.st_ino)
128 && (dns_addr_stat.st_size == old_stat.st_size)
129 && (dns_addr_stat.st_mtime == old_stat.st_mtime)) {
130 *pdns_addr = dns_addr;
131 return 0;
132 }
133 }
134
135 f = fopen("/etc/resolv.conf", "r");
136 if (!f)
137 return -1;
138
139#ifdef DEBUG
140 lprint("IP address of your DNS(s): ");
141#endif
142 while (fgets(buff, 512, f) != NULL) {
143 if (sscanf(buff, "nameserver%*[ \t]%256s", buff2) == 1) {
144 if (!inet_aton(buff2, &tmp_addr))
145 continue;
146
147 if (!found) {
148 *pdns_addr = tmp_addr;
149 dns_addr = tmp_addr;
150 dns_addr_time = curtime;
151 }
152#ifdef DEBUG
153 else
154 lprint(", ");
155#endif
156 if (++found > 3) {
157#ifdef DEBUG
158 lprint("(more)");
159#endif
160 break;
161 }
162#ifdef DEBUG
163 else
164 lprint("%s", inet_ntoa(tmp_addr));
165#endif
166 }
167 }
168 fclose(f);
169 if (!found)
170 return -1;
171 return 0;
172}
173
174#endif
175
176static void slirp_init_once(void)
177{
178 static int initialized;
179#ifdef _WIN32
180 WSADATA Data;
181#endif
182
183 if (initialized) {
184 return;
185 }
186 initialized = 1;
187
188#ifdef _WIN32
189 WSAStartup(MAKEWORD(2,0), &Data);
190 atexit(winsock_cleanup);
191#endif
192
193 loopback_addr.s_addr = htonl(INADDR_LOOPBACK);
194}
195
196static void slirp_state_save(QEMUFile *f, void *opaque);
197static int slirp_state_load(QEMUFile *f, void *opaque, int version_id);
198
199Slirp *slirp_init(int restricted, struct in_addr vnetwork,
200 struct in_addr vnetmask, struct in_addr vhost,
201 const char *vhostname, const char *tftp_path,
202 const char *bootfile, struct in_addr vdhcp_start,
203 struct in_addr vnameserver, void *opaque)
204{
205 Slirp *slirp = qemu_mallocz(sizeof(Slirp));
206
207 slirp_init_once();
208
209 slirp->restricted = restricted;
210
211 if_init(slirp);
212 ip_init(slirp);
213
214
215 m_init(slirp);
216
217 slirp->vnetwork_addr = vnetwork;
218 slirp->vnetwork_mask = vnetmask;
219 slirp->vhost_addr = vhost;
220 if (vhostname) {
221 pstrcpy(slirp->client_hostname, sizeof(slirp->client_hostname),
222 vhostname);
223 }
224 if (tftp_path) {
225 slirp->tftp_prefix = qemu_strdup(tftp_path);
226 }
227 if (bootfile) {
228 slirp->bootp_filename = qemu_strdup(bootfile);
229 }
230 slirp->vdhcp_startaddr = vdhcp_start;
231 slirp->vnameserver_addr = vnameserver;
232
233 slirp->opaque = opaque;
234
235 register_savevm(NULL, "slirp", 0, 3,
236 slirp_state_save, slirp_state_load, slirp);
237
238 QTAILQ_INSERT_TAIL(&slirp_instances, slirp, entry);
239
240 return slirp;
241}
242
243void slirp_cleanup(Slirp *slirp)
244{
245 QTAILQ_REMOVE(&slirp_instances, slirp, entry);
246
247 unregister_savevm(NULL, "slirp", slirp);
248
249 qemu_free(slirp->tftp_prefix);
250 qemu_free(slirp->bootp_filename);
251 qemu_free(slirp);
252}
253
254#define CONN_CANFSEND(so) (((so)->so_state & (SS_FCANTSENDMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED)
255#define CONN_CANFRCV(so) (((so)->so_state & (SS_FCANTRCVMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED)
256#define UPD_NFDS(x) if (nfds < (x)) nfds = (x)
257
258void slirp_select_fill(int *pnfds,
259 fd_set *readfds, fd_set *writefds, fd_set *xfds)
260{
261 Slirp *slirp;
262 struct socket *so, *so_next;
263 int nfds;
264
265 if (QTAILQ_EMPTY(&slirp_instances)) {
266 return;
267 }
268
269
270 global_readfds = NULL;
271 global_writefds = NULL;
272 global_xfds = NULL;
273
274 nfds = *pnfds;
275
276
277
278 do_slowtimo = 0;
279
280 QTAILQ_FOREACH(slirp, &slirp_instances, entry) {
281
282
283
284
285 do_slowtimo |= ((slirp->tcb.so_next != &slirp->tcb) ||
286 (&slirp->ipq.ip_link != slirp->ipq.ip_link.next));
287
288 for (so = slirp->tcb.so_next; so != &slirp->tcb;
289 so = so_next) {
290 so_next = so->so_next;
291
292
293
294
295 if (time_fasttimo == 0 && so->so_tcpcb->t_flags & TF_DELACK)
296 time_fasttimo = curtime;
297
298
299
300
301
302 if (so->so_state & SS_NOFDREF || so->s == -1)
303 continue;
304
305
306
307
308 if (so->so_state & SS_FACCEPTCONN) {
309 FD_SET(so->s, readfds);
310 UPD_NFDS(so->s);
311 continue;
312 }
313
314
315
316
317 if (so->so_state & SS_ISFCONNECTING) {
318 FD_SET(so->s, writefds);
319 UPD_NFDS(so->s);
320 continue;
321 }
322
323
324
325
326
327 if (CONN_CANFSEND(so) && so->so_rcv.sb_cc) {
328 FD_SET(so->s, writefds);
329 UPD_NFDS(so->s);
330 }
331
332
333
334
335
336 if (CONN_CANFRCV(so) && (so->so_snd.sb_cc < (so->so_snd.sb_datalen/2))) {
337 FD_SET(so->s, readfds);
338 FD_SET(so->s, xfds);
339 UPD_NFDS(so->s);
340 }
341 }
342
343
344
345
346 for (so = slirp->udb.so_next; so != &slirp->udb;
347 so = so_next) {
348 so_next = so->so_next;
349
350
351
352
353 if (so->so_expire) {
354 if (so->so_expire <= curtime) {
355 udp_detach(so);
356 continue;
357 } else
358 do_slowtimo = 1;
359 }
360
361
362
363
364
365
366
367
368
369
370
371 if ((so->so_state & SS_ISFCONNECTED) && so->so_queued <= 4) {
372 FD_SET(so->s, readfds);
373 UPD_NFDS(so->s);
374 }
375 }
376 }
377
378 *pnfds = nfds;
379}
380
381void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds,
382 int select_error)
383{
384 Slirp *slirp;
385 struct socket *so, *so_next;
386 int ret;
387
388 if (QTAILQ_EMPTY(&slirp_instances)) {
389 return;
390 }
391
392 global_readfds = readfds;
393 global_writefds = writefds;
394 global_xfds = xfds;
395
396 curtime = qemu_get_clock(rt_clock);
397
398 QTAILQ_FOREACH(slirp, &slirp_instances, entry) {
399
400
401
402 if (time_fasttimo && ((curtime - time_fasttimo) >= 2)) {
403 tcp_fasttimo(slirp);
404 time_fasttimo = 0;
405 }
406 if (do_slowtimo && ((curtime - last_slowtimo) >= 499)) {
407 ip_slowtimo(slirp);
408 tcp_slowtimo(slirp);
409 last_slowtimo = curtime;
410 }
411
412
413
414
415 if (!select_error) {
416
417
418
419 for (so = slirp->tcb.so_next; so != &slirp->tcb;
420 so = so_next) {
421 so_next = so->so_next;
422
423
424
425
426
427 if (so->so_state & SS_NOFDREF || so->s == -1)
428 continue;
429
430
431
432
433
434
435 if (FD_ISSET(so->s, xfds))
436 sorecvoob(so);
437
438
439
440 else if (FD_ISSET(so->s, readfds)) {
441
442
443
444 if (so->so_state & SS_FACCEPTCONN) {
445 tcp_connect(so);
446 continue;
447 }
448 ret = soread(so);
449
450
451 if (ret > 0)
452 tcp_output(sototcpcb(so));
453 }
454
455
456
457
458 if (FD_ISSET(so->s, writefds)) {
459
460
461
462 if (so->so_state & SS_ISFCONNECTING) {
463
464 so->so_state &= ~SS_ISFCONNECTING;
465
466 ret = send(so->s, (const void *) &ret, 0, 0);
467 if (ret < 0) {
468
469 if (errno == EAGAIN || errno == EWOULDBLOCK ||
470 errno == EINPROGRESS || errno == ENOTCONN)
471 continue;
472
473
474 so->so_state &= SS_PERSISTENT_MASK;
475 so->so_state |= SS_NOFDREF;
476 }
477
478
479
480
481
482 tcp_input((struct mbuf *)NULL, sizeof(struct ip), so);
483
484 } else
485 ret = sowrite(so);
486
487
488
489
490
491
492 }
493
494
495
496
497
498#ifdef PROBE_CONN
499 if (so->so_state & SS_ISFCONNECTING) {
500 ret = recv(so->s, (char *)&ret, 0,0);
501
502 if (ret < 0) {
503
504 if (errno == EAGAIN || errno == EWOULDBLOCK ||
505 errno == EINPROGRESS || errno == ENOTCONN)
506 continue;
507
508
509 so->so_state &= SS_PERSISTENT_MASK;
510 so->so_state |= SS_NOFDREF;
511
512
513 } else {
514 ret = send(so->s, &ret, 0,0);
515 if (ret < 0) {
516
517 if (errno == EAGAIN || errno == EWOULDBLOCK ||
518 errno == EINPROGRESS || errno == ENOTCONN)
519 continue;
520
521 so->so_state &= SS_PERSISTENT_MASK;
522 so->so_state |= SS_NOFDREF;
523 } else
524 so->so_state &= ~SS_ISFCONNECTING;
525
526 }
527 tcp_input((struct mbuf *)NULL, sizeof(struct ip),so);
528 }
529#endif
530 }
531
532
533
534
535
536
537 for (so = slirp->udb.so_next; so != &slirp->udb;
538 so = so_next) {
539 so_next = so->so_next;
540
541 if (so->s != -1 && FD_ISSET(so->s, readfds)) {
542 sorecvfrom(so);
543 }
544 }
545 }
546
547
548
549
550 if (slirp->if_queued) {
551 if_start(slirp);
552 }
553 }
554
555
556
557
558
559
560 global_readfds = NULL;
561 global_writefds = NULL;
562 global_xfds = NULL;
563}
564
565#define ETH_ALEN 6
566#define ETH_HLEN 14
567
568#define ETH_P_IP 0x0800
569#define ETH_P_ARP 0x0806
570
571#define ARPOP_REQUEST 1
572#define ARPOP_REPLY 2
573
574struct ethhdr
575{
576 unsigned char h_dest[ETH_ALEN];
577 unsigned char h_source[ETH_ALEN];
578 unsigned short h_proto;
579};
580
581struct arphdr
582{
583 unsigned short ar_hrd;
584 unsigned short ar_pro;
585 unsigned char ar_hln;
586 unsigned char ar_pln;
587 unsigned short ar_op;
588
589
590
591
592 unsigned char ar_sha[ETH_ALEN];
593 uint32_t ar_sip;
594 unsigned char ar_tha[ETH_ALEN];
595 uint32_t ar_tip ;
596} __attribute__((packed));
597
598static void arp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len)
599{
600 struct ethhdr *eh = (struct ethhdr *)pkt;
601 struct arphdr *ah = (struct arphdr *)(pkt + ETH_HLEN);
602 uint8_t arp_reply[ETH_HLEN + sizeof(struct arphdr)];
603 struct ethhdr *reh = (struct ethhdr *)arp_reply;
604 struct arphdr *rah = (struct arphdr *)(arp_reply + ETH_HLEN);
605 int ar_op;
606 struct ex_list *ex_ptr;
607
608 ar_op = ntohs(ah->ar_op);
609 switch(ar_op) {
610 case ARPOP_REQUEST:
611 if ((ah->ar_tip & slirp->vnetwork_mask.s_addr) ==
612 slirp->vnetwork_addr.s_addr) {
613 if (ah->ar_tip == slirp->vnameserver_addr.s_addr ||
614 ah->ar_tip == slirp->vhost_addr.s_addr)
615 goto arp_ok;
616 for (ex_ptr = slirp->exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
617 if (ex_ptr->ex_addr.s_addr == ah->ar_tip)
618 goto arp_ok;
619 }
620 return;
621 arp_ok:
622
623 memcpy(slirp->client_ethaddr, eh->h_source, ETH_ALEN);
624
625
626 memcpy(reh->h_dest, pkt + ETH_ALEN, ETH_ALEN);
627 memcpy(reh->h_source, special_ethaddr, ETH_ALEN - 4);
628 memcpy(&reh->h_source[2], &ah->ar_tip, 4);
629 reh->h_proto = htons(ETH_P_ARP);
630
631 rah->ar_hrd = htons(1);
632 rah->ar_pro = htons(ETH_P_IP);
633 rah->ar_hln = ETH_ALEN;
634 rah->ar_pln = 4;
635 rah->ar_op = htons(ARPOP_REPLY);
636 memcpy(rah->ar_sha, reh->h_source, ETH_ALEN);
637 rah->ar_sip = ah->ar_tip;
638 memcpy(rah->ar_tha, ah->ar_sha, ETH_ALEN);
639 rah->ar_tip = ah->ar_sip;
640 slirp_output(slirp->opaque, arp_reply, sizeof(arp_reply));
641 }
642 break;
643 case ARPOP_REPLY:
644
645 if (!memcmp(slirp->client_ethaddr, zero_ethaddr, ETH_ALEN) &&
646 ah->ar_sip == slirp->client_ipaddr.s_addr) {
647 memcpy(slirp->client_ethaddr, ah->ar_sha, ETH_ALEN);
648 }
649 break;
650 default:
651 break;
652 }
653}
654
655void slirp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len)
656{
657 struct mbuf *m;
658 int proto;
659
660 if (pkt_len < ETH_HLEN)
661 return;
662
663 proto = ntohs(*(uint16_t *)(pkt + 12));
664 switch(proto) {
665 case ETH_P_ARP:
666 arp_input(slirp, pkt, pkt_len);
667 break;
668 case ETH_P_IP:
669 m = m_get(slirp);
670 if (!m)
671 return;
672
673 if (M_FREEROOM(m) < pkt_len + 2) {
674 m_inc(m, pkt_len + 2);
675 }
676 m->m_len = pkt_len + 2;
677 memcpy(m->m_data + 2, pkt, pkt_len);
678
679 m->m_data += 2 + ETH_HLEN;
680 m->m_len -= 2 + ETH_HLEN;
681
682 ip_input(m);
683 break;
684 default:
685 break;
686 }
687}
688
689
690void if_encap(Slirp *slirp, const uint8_t *ip_data, int ip_data_len)
691{
692 uint8_t buf[1600];
693 struct ethhdr *eh = (struct ethhdr *)buf;
694
695 if (ip_data_len + ETH_HLEN > sizeof(buf))
696 return;
697
698 if (!memcmp(slirp->client_ethaddr, zero_ethaddr, ETH_ALEN)) {
699 uint8_t arp_req[ETH_HLEN + sizeof(struct arphdr)];
700 struct ethhdr *reh = (struct ethhdr *)arp_req;
701 struct arphdr *rah = (struct arphdr *)(arp_req + ETH_HLEN);
702 const struct ip *iph = (const struct ip *)ip_data;
703
704
705
706
707
708
709 memset(reh->h_dest, 0xff, ETH_ALEN);
710 memcpy(reh->h_source, special_ethaddr, ETH_ALEN - 4);
711 memcpy(&reh->h_source[2], &slirp->vhost_addr, 4);
712 reh->h_proto = htons(ETH_P_ARP);
713 rah->ar_hrd = htons(1);
714 rah->ar_pro = htons(ETH_P_IP);
715 rah->ar_hln = ETH_ALEN;
716 rah->ar_pln = 4;
717 rah->ar_op = htons(ARPOP_REQUEST);
718
719 memcpy(rah->ar_sha, special_ethaddr, ETH_ALEN - 4);
720 memcpy(&rah->ar_sha[2], &slirp->vhost_addr, 4);
721
722 rah->ar_sip = slirp->vhost_addr.s_addr;
723
724 memset(rah->ar_tha, 0, ETH_ALEN);
725
726 rah->ar_tip = iph->ip_dst.s_addr;
727 slirp->client_ipaddr = iph->ip_dst;
728 slirp_output(slirp->opaque, arp_req, sizeof(arp_req));
729 } else {
730 memcpy(eh->h_dest, slirp->client_ethaddr, ETH_ALEN);
731 memcpy(eh->h_source, special_ethaddr, ETH_ALEN - 4);
732
733 memcpy(&eh->h_source[2], &slirp->vhost_addr, 4);
734 eh->h_proto = htons(ETH_P_IP);
735 memcpy(buf + sizeof(struct ethhdr), ip_data, ip_data_len);
736 slirp_output(slirp->opaque, buf, ip_data_len + ETH_HLEN);
737 }
738}
739
740
741int slirp_remove_hostfwd(Slirp *slirp, int is_udp, struct in_addr host_addr,
742 int host_port)
743{
744 struct socket *so;
745 struct socket *head = (is_udp ? &slirp->udb : &slirp->tcb);
746 struct sockaddr_in addr;
747 int port = htons(host_port);
748 socklen_t addr_len;
749
750 for (so = head->so_next; so != head; so = so->so_next) {
751 addr_len = sizeof(addr);
752 if ((so->so_state & SS_HOSTFWD) &&
753 getsockname(so->s, (struct sockaddr *)&addr, &addr_len) == 0 &&
754 addr.sin_addr.s_addr == host_addr.s_addr &&
755 addr.sin_port == port) {
756 close(so->s);
757 sofree(so);
758 return 0;
759 }
760 }
761
762 return -1;
763}
764
765int slirp_add_hostfwd(Slirp *slirp, int is_udp, struct in_addr host_addr,
766 int host_port, struct in_addr guest_addr, int guest_port)
767{
768 if (!guest_addr.s_addr) {
769 guest_addr = slirp->vdhcp_startaddr;
770 }
771 if (is_udp) {
772 if (!udp_listen(slirp, host_addr.s_addr, htons(host_port),
773 guest_addr.s_addr, htons(guest_port), SS_HOSTFWD))
774 return -1;
775 } else {
776 if (!tcp_listen(slirp, host_addr.s_addr, htons(host_port),
777 guest_addr.s_addr, htons(guest_port), SS_HOSTFWD))
778 return -1;
779 }
780 return 0;
781}
782
783int slirp_add_exec(Slirp *slirp, int do_pty, const void *args,
784 struct in_addr *guest_addr, int guest_port)
785{
786 if (!guest_addr->s_addr) {
787 guest_addr->s_addr = slirp->vnetwork_addr.s_addr |
788 (htonl(0x0204) & ~slirp->vnetwork_mask.s_addr);
789 }
790 if ((guest_addr->s_addr & slirp->vnetwork_mask.s_addr) !=
791 slirp->vnetwork_addr.s_addr ||
792 guest_addr->s_addr == slirp->vhost_addr.s_addr ||
793 guest_addr->s_addr == slirp->vnameserver_addr.s_addr) {
794 return -1;
795 }
796 return add_exec(&slirp->exec_list, do_pty, (char *)args, *guest_addr,
797 htons(guest_port));
798}
799
800ssize_t slirp_send(struct socket *so, const void *buf, size_t len, int flags)
801{
802 if (so->s == -1 && so->extra) {
803 qemu_chr_write(so->extra, buf, len);
804 return len;
805 }
806
807 return send(so->s, buf, len, flags);
808}
809
810static struct socket *
811slirp_find_ctl_socket(Slirp *slirp, struct in_addr guest_addr, int guest_port)
812{
813 struct socket *so;
814
815 for (so = slirp->tcb.so_next; so != &slirp->tcb; so = so->so_next) {
816 if (so->so_faddr.s_addr == guest_addr.s_addr &&
817 htons(so->so_fport) == guest_port) {
818 return so;
819 }
820 }
821 return NULL;
822}
823
824size_t slirp_socket_can_recv(Slirp *slirp, struct in_addr guest_addr,
825 int guest_port)
826{
827 struct iovec iov[2];
828 struct socket *so;
829
830 so = slirp_find_ctl_socket(slirp, guest_addr, guest_port);
831
832 if (!so || so->so_state & SS_NOFDREF)
833 return 0;
834
835 if (!CONN_CANFRCV(so) || so->so_snd.sb_cc >= (so->so_snd.sb_datalen/2))
836 return 0;
837
838 return sopreprbuf(so, iov, NULL);
839}
840
841void slirp_socket_recv(Slirp *slirp, struct in_addr guest_addr, int guest_port,
842 const uint8_t *buf, int size)
843{
844 int ret;
845 struct socket *so = slirp_find_ctl_socket(slirp, guest_addr, guest_port);
846
847 if (!so)
848 return;
849
850 ret = soreadbuf(so, (const char *)buf, size);
851
852 if (ret > 0)
853 tcp_output(sototcpcb(so));
854}
855
856static void slirp_tcp_save(QEMUFile *f, struct tcpcb *tp)
857{
858 int i;
859
860 qemu_put_sbe16(f, tp->t_state);
861 for (i = 0; i < TCPT_NTIMERS; i++)
862 qemu_put_sbe16(f, tp->t_timer[i]);
863 qemu_put_sbe16(f, tp->t_rxtshift);
864 qemu_put_sbe16(f, tp->t_rxtcur);
865 qemu_put_sbe16(f, tp->t_dupacks);
866 qemu_put_be16(f, tp->t_maxseg);
867 qemu_put_sbyte(f, tp->t_force);
868 qemu_put_be16(f, tp->t_flags);
869 qemu_put_be32(f, tp->snd_una);
870 qemu_put_be32(f, tp->snd_nxt);
871 qemu_put_be32(f, tp->snd_up);
872 qemu_put_be32(f, tp->snd_wl1);
873 qemu_put_be32(f, tp->snd_wl2);
874 qemu_put_be32(f, tp->iss);
875 qemu_put_be32(f, tp->snd_wnd);
876 qemu_put_be32(f, tp->rcv_wnd);
877 qemu_put_be32(f, tp->rcv_nxt);
878 qemu_put_be32(f, tp->rcv_up);
879 qemu_put_be32(f, tp->irs);
880 qemu_put_be32(f, tp->rcv_adv);
881 qemu_put_be32(f, tp->snd_max);
882 qemu_put_be32(f, tp->snd_cwnd);
883 qemu_put_be32(f, tp->snd_ssthresh);
884 qemu_put_sbe16(f, tp->t_idle);
885 qemu_put_sbe16(f, tp->t_rtt);
886 qemu_put_be32(f, tp->t_rtseq);
887 qemu_put_sbe16(f, tp->t_srtt);
888 qemu_put_sbe16(f, tp->t_rttvar);
889 qemu_put_be16(f, tp->t_rttmin);
890 qemu_put_be32(f, tp->max_sndwnd);
891 qemu_put_byte(f, tp->t_oobflags);
892 qemu_put_byte(f, tp->t_iobc);
893 qemu_put_sbe16(f, tp->t_softerror);
894 qemu_put_byte(f, tp->snd_scale);
895 qemu_put_byte(f, tp->rcv_scale);
896 qemu_put_byte(f, tp->request_r_scale);
897 qemu_put_byte(f, tp->requested_s_scale);
898 qemu_put_be32(f, tp->ts_recent);
899 qemu_put_be32(f, tp->ts_recent_age);
900 qemu_put_be32(f, tp->last_ack_sent);
901}
902
903static void slirp_sbuf_save(QEMUFile *f, struct sbuf *sbuf)
904{
905 uint32_t off;
906
907 qemu_put_be32(f, sbuf->sb_cc);
908 qemu_put_be32(f, sbuf->sb_datalen);
909 off = (uint32_t)(sbuf->sb_wptr - sbuf->sb_data);
910 qemu_put_sbe32(f, off);
911 off = (uint32_t)(sbuf->sb_rptr - sbuf->sb_data);
912 qemu_put_sbe32(f, off);
913 qemu_put_buffer(f, (unsigned char*)sbuf->sb_data, sbuf->sb_datalen);
914}
915
916static void slirp_socket_save(QEMUFile *f, struct socket *so)
917{
918 qemu_put_be32(f, so->so_urgc);
919 qemu_put_be32(f, so->so_faddr.s_addr);
920 qemu_put_be32(f, so->so_laddr.s_addr);
921 qemu_put_be16(f, so->so_fport);
922 qemu_put_be16(f, so->so_lport);
923 qemu_put_byte(f, so->so_iptos);
924 qemu_put_byte(f, so->so_emu);
925 qemu_put_byte(f, so->so_type);
926 qemu_put_be32(f, so->so_state);
927 slirp_sbuf_save(f, &so->so_rcv);
928 slirp_sbuf_save(f, &so->so_snd);
929 slirp_tcp_save(f, so->so_tcpcb);
930}
931
932static void slirp_bootp_save(QEMUFile *f, Slirp *slirp)
933{
934 int i;
935
936 for (i = 0; i < NB_BOOTP_CLIENTS; i++) {
937 qemu_put_be16(f, slirp->bootp_clients[i].allocated);
938 qemu_put_buffer(f, slirp->bootp_clients[i].macaddr, 6);
939 }
940}
941
942static void slirp_state_save(QEMUFile *f, void *opaque)
943{
944 Slirp *slirp = opaque;
945 struct ex_list *ex_ptr;
946
947 for (ex_ptr = slirp->exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next)
948 if (ex_ptr->ex_pty == 3) {
949 struct socket *so;
950 so = slirp_find_ctl_socket(slirp, ex_ptr->ex_addr,
951 ntohs(ex_ptr->ex_fport));
952 if (!so)
953 continue;
954
955 qemu_put_byte(f, 42);
956 slirp_socket_save(f, so);
957 }
958 qemu_put_byte(f, 0);
959
960 qemu_put_be16(f, slirp->ip_id);
961
962 slirp_bootp_save(f, slirp);
963}
964
965static void slirp_tcp_load(QEMUFile *f, struct tcpcb *tp)
966{
967 int i;
968
969 tp->t_state = qemu_get_sbe16(f);
970 for (i = 0; i < TCPT_NTIMERS; i++)
971 tp->t_timer[i] = qemu_get_sbe16(f);
972 tp->t_rxtshift = qemu_get_sbe16(f);
973 tp->t_rxtcur = qemu_get_sbe16(f);
974 tp->t_dupacks = qemu_get_sbe16(f);
975 tp->t_maxseg = qemu_get_be16(f);
976 tp->t_force = qemu_get_sbyte(f);
977 tp->t_flags = qemu_get_be16(f);
978 tp->snd_una = qemu_get_be32(f);
979 tp->snd_nxt = qemu_get_be32(f);
980 tp->snd_up = qemu_get_be32(f);
981 tp->snd_wl1 = qemu_get_be32(f);
982 tp->snd_wl2 = qemu_get_be32(f);
983 tp->iss = qemu_get_be32(f);
984 tp->snd_wnd = qemu_get_be32(f);
985 tp->rcv_wnd = qemu_get_be32(f);
986 tp->rcv_nxt = qemu_get_be32(f);
987 tp->rcv_up = qemu_get_be32(f);
988 tp->irs = qemu_get_be32(f);
989 tp->rcv_adv = qemu_get_be32(f);
990 tp->snd_max = qemu_get_be32(f);
991 tp->snd_cwnd = qemu_get_be32(f);
992 tp->snd_ssthresh = qemu_get_be32(f);
993 tp->t_idle = qemu_get_sbe16(f);
994 tp->t_rtt = qemu_get_sbe16(f);
995 tp->t_rtseq = qemu_get_be32(f);
996 tp->t_srtt = qemu_get_sbe16(f);
997 tp->t_rttvar = qemu_get_sbe16(f);
998 tp->t_rttmin = qemu_get_be16(f);
999 tp->max_sndwnd = qemu_get_be32(f);
1000 tp->t_oobflags = qemu_get_byte(f);
1001 tp->t_iobc = qemu_get_byte(f);
1002 tp->t_softerror = qemu_get_sbe16(f);
1003 tp->snd_scale = qemu_get_byte(f);
1004 tp->rcv_scale = qemu_get_byte(f);
1005 tp->request_r_scale = qemu_get_byte(f);
1006 tp->requested_s_scale = qemu_get_byte(f);
1007 tp->ts_recent = qemu_get_be32(f);
1008 tp->ts_recent_age = qemu_get_be32(f);
1009 tp->last_ack_sent = qemu_get_be32(f);
1010 tcp_template(tp);
1011}
1012
1013static int slirp_sbuf_load(QEMUFile *f, struct sbuf *sbuf)
1014{
1015 uint32_t off, sb_cc, sb_datalen;
1016
1017 sb_cc = qemu_get_be32(f);
1018 sb_datalen = qemu_get_be32(f);
1019
1020 sbreserve(sbuf, sb_datalen);
1021
1022 if (sbuf->sb_datalen != sb_datalen)
1023 return -ENOMEM;
1024
1025 sbuf->sb_cc = sb_cc;
1026
1027 off = qemu_get_sbe32(f);
1028 sbuf->sb_wptr = sbuf->sb_data + off;
1029 off = qemu_get_sbe32(f);
1030 sbuf->sb_rptr = sbuf->sb_data + off;
1031 qemu_get_buffer(f, (unsigned char*)sbuf->sb_data, sbuf->sb_datalen);
1032
1033 return 0;
1034}
1035
1036static int slirp_socket_load(QEMUFile *f, struct socket *so)
1037{
1038 if (tcp_attach(so) < 0)
1039 return -ENOMEM;
1040
1041 so->so_urgc = qemu_get_be32(f);
1042 so->so_faddr.s_addr = qemu_get_be32(f);
1043 so->so_laddr.s_addr = qemu_get_be32(f);
1044 so->so_fport = qemu_get_be16(f);
1045 so->so_lport = qemu_get_be16(f);
1046 so->so_iptos = qemu_get_byte(f);
1047 so->so_emu = qemu_get_byte(f);
1048 so->so_type = qemu_get_byte(f);
1049 so->so_state = qemu_get_be32(f);
1050 if (slirp_sbuf_load(f, &so->so_rcv) < 0)
1051 return -ENOMEM;
1052 if (slirp_sbuf_load(f, &so->so_snd) < 0)
1053 return -ENOMEM;
1054 slirp_tcp_load(f, so->so_tcpcb);
1055
1056 return 0;
1057}
1058
1059static void slirp_bootp_load(QEMUFile *f, Slirp *slirp)
1060{
1061 int i;
1062
1063 for (i = 0; i < NB_BOOTP_CLIENTS; i++) {
1064 slirp->bootp_clients[i].allocated = qemu_get_be16(f);
1065 qemu_get_buffer(f, slirp->bootp_clients[i].macaddr, 6);
1066 }
1067}
1068
1069static int slirp_state_load(QEMUFile *f, void *opaque, int version_id)
1070{
1071 Slirp *slirp = opaque;
1072 struct ex_list *ex_ptr;
1073
1074 while (qemu_get_byte(f)) {
1075 int ret;
1076 struct socket *so = socreate(slirp);
1077
1078 if (!so)
1079 return -ENOMEM;
1080
1081 ret = slirp_socket_load(f, so);
1082
1083 if (ret < 0)
1084 return ret;
1085
1086 if ((so->so_faddr.s_addr & slirp->vnetwork_mask.s_addr) !=
1087 slirp->vnetwork_addr.s_addr) {
1088 return -EINVAL;
1089 }
1090 for (ex_ptr = slirp->exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
1091 if (ex_ptr->ex_pty == 3 &&
1092 so->so_faddr.s_addr == ex_ptr->ex_addr.s_addr &&
1093 so->so_fport == ex_ptr->ex_fport) {
1094 break;
1095 }
1096 }
1097 if (!ex_ptr)
1098 return -EINVAL;
1099
1100 so->extra = (void *)ex_ptr->ex_exec;
1101 }
1102
1103 if (version_id >= 2) {
1104 slirp->ip_id = qemu_get_be16(f);
1105 }
1106
1107 if (version_id >= 3) {
1108 slirp_bootp_load(f, slirp);
1109 }
1110
1111 return 0;
1112}
1113