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("slirp", 0, 3, slirp_state_save, slirp_state_load, slirp);
236
237 QTAILQ_INSERT_TAIL(&slirp_instances, slirp, entry);
238
239 return slirp;
240}
241
242void slirp_cleanup(Slirp *slirp)
243{
244 QTAILQ_REMOVE(&slirp_instances, slirp, entry);
245
246 unregister_savevm("slirp", slirp);
247
248 qemu_free(slirp->tftp_prefix);
249 qemu_free(slirp->bootp_filename);
250 qemu_free(slirp);
251}
252
253#define CONN_CANFSEND(so) (((so)->so_state & (SS_FCANTSENDMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED)
254#define CONN_CANFRCV(so) (((so)->so_state & (SS_FCANTRCVMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED)
255#define UPD_NFDS(x) if (nfds < (x)) nfds = (x)
256
257void slirp_select_fill(int *pnfds,
258 fd_set *readfds, fd_set *writefds, fd_set *xfds)
259{
260 Slirp *slirp;
261 struct socket *so, *so_next;
262 int nfds;
263
264 if (QTAILQ_EMPTY(&slirp_instances)) {
265 return;
266 }
267
268
269 global_readfds = NULL;
270 global_writefds = NULL;
271 global_xfds = NULL;
272
273 nfds = *pnfds;
274
275
276
277 do_slowtimo = 0;
278
279 QTAILQ_FOREACH(slirp, &slirp_instances, entry) {
280
281
282
283
284 do_slowtimo |= ((slirp->tcb.so_next != &slirp->tcb) ||
285 (&slirp->ipq.ip_link != slirp->ipq.ip_link.next));
286
287 for (so = slirp->tcb.so_next; so != &slirp->tcb;
288 so = so_next) {
289 so_next = so->so_next;
290
291
292
293
294 if (time_fasttimo == 0 && so->so_tcpcb->t_flags & TF_DELACK)
295 time_fasttimo = curtime;
296
297
298
299
300
301 if (so->so_state & SS_NOFDREF || so->s == -1)
302 continue;
303
304
305
306
307 if (so->so_state & SS_FACCEPTCONN) {
308 FD_SET(so->s, readfds);
309 UPD_NFDS(so->s);
310 continue;
311 }
312
313
314
315
316 if (so->so_state & SS_ISFCONNECTING) {
317 FD_SET(so->s, writefds);
318 UPD_NFDS(so->s);
319 continue;
320 }
321
322
323
324
325
326 if (CONN_CANFSEND(so) && so->so_rcv.sb_cc) {
327 FD_SET(so->s, writefds);
328 UPD_NFDS(so->s);
329 }
330
331
332
333
334
335 if (CONN_CANFRCV(so) && (so->so_snd.sb_cc < (so->so_snd.sb_datalen/2))) {
336 FD_SET(so->s, readfds);
337 FD_SET(so->s, xfds);
338 UPD_NFDS(so->s);
339 }
340 }
341
342
343
344
345 for (so = slirp->udb.so_next; so != &slirp->udb;
346 so = so_next) {
347 so_next = so->so_next;
348
349
350
351
352 if (so->so_expire) {
353 if (so->so_expire <= curtime) {
354 udp_detach(so);
355 continue;
356 } else
357 do_slowtimo = 1;
358 }
359
360
361
362
363
364
365
366
367
368
369
370 if ((so->so_state & SS_ISFCONNECTED) && so->so_queued <= 4) {
371 FD_SET(so->s, readfds);
372 UPD_NFDS(so->s);
373 }
374 }
375 }
376
377 *pnfds = nfds;
378}
379
380void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds,
381 int select_error)
382{
383 Slirp *slirp;
384 struct socket *so, *so_next;
385 int ret;
386
387 if (QTAILQ_EMPTY(&slirp_instances)) {
388 return;
389 }
390
391 global_readfds = readfds;
392 global_writefds = writefds;
393 global_xfds = xfds;
394
395 curtime = qemu_get_clock(rt_clock);
396
397 QTAILQ_FOREACH(slirp, &slirp_instances, entry) {
398
399
400
401 if (time_fasttimo && ((curtime - time_fasttimo) >= 2)) {
402 tcp_fasttimo(slirp);
403 time_fasttimo = 0;
404 }
405 if (do_slowtimo && ((curtime - last_slowtimo) >= 499)) {
406 ip_slowtimo(slirp);
407 tcp_slowtimo(slirp);
408 last_slowtimo = curtime;
409 }
410
411
412
413
414 if (!select_error) {
415
416
417
418 for (so = slirp->tcb.so_next; so != &slirp->tcb;
419 so = so_next) {
420 so_next = so->so_next;
421
422
423
424
425
426 if (so->so_state & SS_NOFDREF || so->s == -1)
427 continue;
428
429
430
431
432
433
434 if (FD_ISSET(so->s, xfds))
435 sorecvoob(so);
436
437
438
439 else if (FD_ISSET(so->s, readfds)) {
440
441
442
443 if (so->so_state & SS_FACCEPTCONN) {
444 tcp_connect(so);
445 continue;
446 }
447 ret = soread(so);
448
449
450 if (ret > 0)
451 tcp_output(sototcpcb(so));
452 }
453
454
455
456
457 if (FD_ISSET(so->s, writefds)) {
458
459
460
461 if (so->so_state & SS_ISFCONNECTING) {
462
463 so->so_state &= ~SS_ISFCONNECTING;
464
465 ret = send(so->s, (const void *) &ret, 0, 0);
466 if (ret < 0) {
467
468 if (errno == EAGAIN || errno == EWOULDBLOCK ||
469 errno == EINPROGRESS || errno == ENOTCONN)
470 continue;
471
472
473 so->so_state &= SS_PERSISTENT_MASK;
474 so->so_state |= SS_NOFDREF;
475 }
476
477
478
479
480
481 tcp_input((struct mbuf *)NULL, sizeof(struct ip), so);
482
483 } else
484 ret = sowrite(so);
485
486
487
488
489
490
491 }
492
493
494
495
496
497#ifdef PROBE_CONN
498 if (so->so_state & SS_ISFCONNECTING) {
499 ret = recv(so->s, (char *)&ret, 0,0);
500
501 if (ret < 0) {
502
503 if (errno == EAGAIN || errno == EWOULDBLOCK ||
504 errno == EINPROGRESS || errno == ENOTCONN)
505 continue;
506
507
508 so->so_state &= SS_PERSISTENT_MASK;
509 so->so_state |= SS_NOFDREF;
510
511
512 } else {
513 ret = send(so->s, &ret, 0,0);
514 if (ret < 0) {
515
516 if (errno == EAGAIN || errno == EWOULDBLOCK ||
517 errno == EINPROGRESS || errno == ENOTCONN)
518 continue;
519
520 so->so_state &= SS_PERSISTENT_MASK;
521 so->so_state |= SS_NOFDREF;
522 } else
523 so->so_state &= ~SS_ISFCONNECTING;
524
525 }
526 tcp_input((struct mbuf *)NULL, sizeof(struct ip),so);
527 }
528#endif
529 }
530
531
532
533
534
535
536 for (so = slirp->udb.so_next; so != &slirp->udb;
537 so = so_next) {
538 so_next = so->so_next;
539
540 if (so->s != -1 && FD_ISSET(so->s, readfds)) {
541 sorecvfrom(so);
542 }
543 }
544 }
545
546
547
548
549 if (slirp->if_queued) {
550 if_start(slirp);
551 }
552 }
553
554
555
556
557
558
559 global_readfds = NULL;
560 global_writefds = NULL;
561 global_xfds = NULL;
562}
563
564#define ETH_ALEN 6
565#define ETH_HLEN 14
566
567#define ETH_P_IP 0x0800
568#define ETH_P_ARP 0x0806
569
570#define ARPOP_REQUEST 1
571#define ARPOP_REPLY 2
572
573struct ethhdr
574{
575 unsigned char h_dest[ETH_ALEN];
576 unsigned char h_source[ETH_ALEN];
577 unsigned short h_proto;
578};
579
580struct arphdr
581{
582 unsigned short ar_hrd;
583 unsigned short ar_pro;
584 unsigned char ar_hln;
585 unsigned char ar_pln;
586 unsigned short ar_op;
587
588
589
590
591 unsigned char ar_sha[ETH_ALEN];
592 uint32_t ar_sip;
593 unsigned char ar_tha[ETH_ALEN];
594 uint32_t ar_tip ;
595} __attribute__((packed));
596
597static void arp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len)
598{
599 struct ethhdr *eh = (struct ethhdr *)pkt;
600 struct arphdr *ah = (struct arphdr *)(pkt + ETH_HLEN);
601 uint8_t arp_reply[ETH_HLEN + sizeof(struct arphdr)];
602 struct ethhdr *reh = (struct ethhdr *)arp_reply;
603 struct arphdr *rah = (struct arphdr *)(arp_reply + ETH_HLEN);
604 int ar_op;
605 struct ex_list *ex_ptr;
606
607 ar_op = ntohs(ah->ar_op);
608 switch(ar_op) {
609 case ARPOP_REQUEST:
610 if ((ah->ar_tip & slirp->vnetwork_mask.s_addr) ==
611 slirp->vnetwork_addr.s_addr) {
612 if (ah->ar_tip == slirp->vnameserver_addr.s_addr ||
613 ah->ar_tip == slirp->vhost_addr.s_addr)
614 goto arp_ok;
615 for (ex_ptr = slirp->exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
616 if (ex_ptr->ex_addr.s_addr == ah->ar_tip)
617 goto arp_ok;
618 }
619 return;
620 arp_ok:
621
622 memcpy(slirp->client_ethaddr, eh->h_source, ETH_ALEN);
623
624
625 memcpy(reh->h_dest, pkt + ETH_ALEN, ETH_ALEN);
626 memcpy(reh->h_source, special_ethaddr, ETH_ALEN - 4);
627 memcpy(&reh->h_source[2], &ah->ar_tip, 4);
628 reh->h_proto = htons(ETH_P_ARP);
629
630 rah->ar_hrd = htons(1);
631 rah->ar_pro = htons(ETH_P_IP);
632 rah->ar_hln = ETH_ALEN;
633 rah->ar_pln = 4;
634 rah->ar_op = htons(ARPOP_REPLY);
635 memcpy(rah->ar_sha, reh->h_source, ETH_ALEN);
636 rah->ar_sip = ah->ar_tip;
637 memcpy(rah->ar_tha, ah->ar_sha, ETH_ALEN);
638 rah->ar_tip = ah->ar_sip;
639 slirp_output(slirp->opaque, arp_reply, sizeof(arp_reply));
640 }
641 break;
642 case ARPOP_REPLY:
643
644 if (!memcmp(slirp->client_ethaddr, zero_ethaddr, ETH_ALEN) &&
645 ah->ar_sip == slirp->client_ipaddr.s_addr) {
646 memcpy(slirp->client_ethaddr, ah->ar_sha, ETH_ALEN);
647 }
648 break;
649 default:
650 break;
651 }
652}
653
654void slirp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len)
655{
656 struct mbuf *m;
657 int proto;
658
659 if (pkt_len < ETH_HLEN)
660 return;
661
662 proto = ntohs(*(uint16_t *)(pkt + 12));
663 switch(proto) {
664 case ETH_P_ARP:
665 arp_input(slirp, pkt, pkt_len);
666 break;
667 case ETH_P_IP:
668 m = m_get(slirp);
669 if (!m)
670 return;
671
672 if (M_FREEROOM(m) < pkt_len + 2) {
673 m_inc(m, pkt_len + 2);
674 }
675 m->m_len = pkt_len + 2;
676 memcpy(m->m_data + 2, pkt, pkt_len);
677
678 m->m_data += 2 + ETH_HLEN;
679 m->m_len -= 2 + ETH_HLEN;
680
681 ip_input(m);
682 break;
683 default:
684 break;
685 }
686}
687
688
689void if_encap(Slirp *slirp, const uint8_t *ip_data, int ip_data_len)
690{
691 uint8_t buf[1600];
692 struct ethhdr *eh = (struct ethhdr *)buf;
693
694 if (ip_data_len + ETH_HLEN > sizeof(buf))
695 return;
696
697 if (!memcmp(slirp->client_ethaddr, zero_ethaddr, ETH_ALEN)) {
698 uint8_t arp_req[ETH_HLEN + sizeof(struct arphdr)];
699 struct ethhdr *reh = (struct ethhdr *)arp_req;
700 struct arphdr *rah = (struct arphdr *)(arp_req + ETH_HLEN);
701 const struct ip *iph = (const struct ip *)ip_data;
702
703
704
705
706
707
708 memset(reh->h_dest, 0xff, ETH_ALEN);
709 memcpy(reh->h_source, special_ethaddr, ETH_ALEN - 4);
710 memcpy(&reh->h_source[2], &slirp->vhost_addr, 4);
711 reh->h_proto = htons(ETH_P_ARP);
712 rah->ar_hrd = htons(1);
713 rah->ar_pro = htons(ETH_P_IP);
714 rah->ar_hln = ETH_ALEN;
715 rah->ar_pln = 4;
716 rah->ar_op = htons(ARPOP_REQUEST);
717
718 memcpy(rah->ar_sha, special_ethaddr, ETH_ALEN - 4);
719 memcpy(&rah->ar_sha[2], &slirp->vhost_addr, 4);
720
721 rah->ar_sip = slirp->vhost_addr.s_addr;
722
723 memset(rah->ar_tha, 0, ETH_ALEN);
724
725 rah->ar_tip = iph->ip_dst.s_addr;
726 slirp->client_ipaddr = iph->ip_dst;
727 slirp_output(slirp->opaque, arp_req, sizeof(arp_req));
728 } else {
729 memcpy(eh->h_dest, slirp->client_ethaddr, ETH_ALEN);
730 memcpy(eh->h_source, special_ethaddr, ETH_ALEN - 4);
731
732 memcpy(&eh->h_source[2], &slirp->vhost_addr, 4);
733 eh->h_proto = htons(ETH_P_IP);
734 memcpy(buf + sizeof(struct ethhdr), ip_data, ip_data_len);
735 slirp_output(slirp->opaque, buf, ip_data_len + ETH_HLEN);
736 }
737}
738
739
740int slirp_remove_hostfwd(Slirp *slirp, int is_udp, struct in_addr host_addr,
741 int host_port)
742{
743 struct socket *so;
744 struct socket *head = (is_udp ? &slirp->udb : &slirp->tcb);
745 struct sockaddr_in addr;
746 int port = htons(host_port);
747 socklen_t addr_len;
748
749 for (so = head->so_next; so != head; so = so->so_next) {
750 addr_len = sizeof(addr);
751 if ((so->so_state & SS_HOSTFWD) &&
752 getsockname(so->s, (struct sockaddr *)&addr, &addr_len) == 0 &&
753 addr.sin_addr.s_addr == host_addr.s_addr &&
754 addr.sin_port == port) {
755 close(so->s);
756 sofree(so);
757 return 0;
758 }
759 }
760
761 return -1;
762}
763
764int slirp_add_hostfwd(Slirp *slirp, int is_udp, struct in_addr host_addr,
765 int host_port, struct in_addr guest_addr, int guest_port)
766{
767 if (!guest_addr.s_addr) {
768 guest_addr = slirp->vdhcp_startaddr;
769 }
770 if (is_udp) {
771 if (!udp_listen(slirp, host_addr.s_addr, htons(host_port),
772 guest_addr.s_addr, htons(guest_port), SS_HOSTFWD))
773 return -1;
774 } else {
775 if (!tcp_listen(slirp, host_addr.s_addr, htons(host_port),
776 guest_addr.s_addr, htons(guest_port), SS_HOSTFWD))
777 return -1;
778 }
779 return 0;
780}
781
782int slirp_add_exec(Slirp *slirp, int do_pty, const void *args,
783 struct in_addr *guest_addr, int guest_port)
784{
785 if (!guest_addr->s_addr) {
786 guest_addr->s_addr = slirp->vnetwork_addr.s_addr |
787 (htonl(0x0204) & ~slirp->vnetwork_mask.s_addr);
788 }
789 if ((guest_addr->s_addr & slirp->vnetwork_mask.s_addr) !=
790 slirp->vnetwork_addr.s_addr ||
791 guest_addr->s_addr == slirp->vhost_addr.s_addr ||
792 guest_addr->s_addr == slirp->vnameserver_addr.s_addr) {
793 return -1;
794 }
795 return add_exec(&slirp->exec_list, do_pty, (char *)args, *guest_addr,
796 htons(guest_port));
797}
798
799ssize_t slirp_send(struct socket *so, const void *buf, size_t len, int flags)
800{
801 if (so->s == -1 && so->extra) {
802 qemu_chr_write(so->extra, buf, len);
803 return len;
804 }
805
806 return send(so->s, buf, len, flags);
807}
808
809static struct socket *
810slirp_find_ctl_socket(Slirp *slirp, struct in_addr guest_addr, int guest_port)
811{
812 struct socket *so;
813
814 for (so = slirp->tcb.so_next; so != &slirp->tcb; so = so->so_next) {
815 if (so->so_faddr.s_addr == guest_addr.s_addr &&
816 htons(so->so_fport) == guest_port) {
817 return so;
818 }
819 }
820 return NULL;
821}
822
823size_t slirp_socket_can_recv(Slirp *slirp, struct in_addr guest_addr,
824 int guest_port)
825{
826 struct iovec iov[2];
827 struct socket *so;
828
829 so = slirp_find_ctl_socket(slirp, guest_addr, guest_port);
830
831 if (!so || so->so_state & SS_NOFDREF)
832 return 0;
833
834 if (!CONN_CANFRCV(so) || so->so_snd.sb_cc >= (so->so_snd.sb_datalen/2))
835 return 0;
836
837 return sopreprbuf(so, iov, NULL);
838}
839
840void slirp_socket_recv(Slirp *slirp, struct in_addr guest_addr, int guest_port,
841 const uint8_t *buf, int size)
842{
843 int ret;
844 struct socket *so = slirp_find_ctl_socket(slirp, guest_addr, guest_port);
845
846 if (!so)
847 return;
848
849 ret = soreadbuf(so, (const char *)buf, size);
850
851 if (ret > 0)
852 tcp_output(sototcpcb(so));
853}
854
855static void slirp_tcp_save(QEMUFile *f, struct tcpcb *tp)
856{
857 int i;
858
859 qemu_put_sbe16(f, tp->t_state);
860 for (i = 0; i < TCPT_NTIMERS; i++)
861 qemu_put_sbe16(f, tp->t_timer[i]);
862 qemu_put_sbe16(f, tp->t_rxtshift);
863 qemu_put_sbe16(f, tp->t_rxtcur);
864 qemu_put_sbe16(f, tp->t_dupacks);
865 qemu_put_be16(f, tp->t_maxseg);
866 qemu_put_sbyte(f, tp->t_force);
867 qemu_put_be16(f, tp->t_flags);
868 qemu_put_be32(f, tp->snd_una);
869 qemu_put_be32(f, tp->snd_nxt);
870 qemu_put_be32(f, tp->snd_up);
871 qemu_put_be32(f, tp->snd_wl1);
872 qemu_put_be32(f, tp->snd_wl2);
873 qemu_put_be32(f, tp->iss);
874 qemu_put_be32(f, tp->snd_wnd);
875 qemu_put_be32(f, tp->rcv_wnd);
876 qemu_put_be32(f, tp->rcv_nxt);
877 qemu_put_be32(f, tp->rcv_up);
878 qemu_put_be32(f, tp->irs);
879 qemu_put_be32(f, tp->rcv_adv);
880 qemu_put_be32(f, tp->snd_max);
881 qemu_put_be32(f, tp->snd_cwnd);
882 qemu_put_be32(f, tp->snd_ssthresh);
883 qemu_put_sbe16(f, tp->t_idle);
884 qemu_put_sbe16(f, tp->t_rtt);
885 qemu_put_be32(f, tp->t_rtseq);
886 qemu_put_sbe16(f, tp->t_srtt);
887 qemu_put_sbe16(f, tp->t_rttvar);
888 qemu_put_be16(f, tp->t_rttmin);
889 qemu_put_be32(f, tp->max_sndwnd);
890 qemu_put_byte(f, tp->t_oobflags);
891 qemu_put_byte(f, tp->t_iobc);
892 qemu_put_sbe16(f, tp->t_softerror);
893 qemu_put_byte(f, tp->snd_scale);
894 qemu_put_byte(f, tp->rcv_scale);
895 qemu_put_byte(f, tp->request_r_scale);
896 qemu_put_byte(f, tp->requested_s_scale);
897 qemu_put_be32(f, tp->ts_recent);
898 qemu_put_be32(f, tp->ts_recent_age);
899 qemu_put_be32(f, tp->last_ack_sent);
900}
901
902static void slirp_sbuf_save(QEMUFile *f, struct sbuf *sbuf)
903{
904 uint32_t off;
905
906 qemu_put_be32(f, sbuf->sb_cc);
907 qemu_put_be32(f, sbuf->sb_datalen);
908 off = (uint32_t)(sbuf->sb_wptr - sbuf->sb_data);
909 qemu_put_sbe32(f, off);
910 off = (uint32_t)(sbuf->sb_rptr - sbuf->sb_data);
911 qemu_put_sbe32(f, off);
912 qemu_put_buffer(f, (unsigned char*)sbuf->sb_data, sbuf->sb_datalen);
913}
914
915static void slirp_socket_save(QEMUFile *f, struct socket *so)
916{
917 qemu_put_be32(f, so->so_urgc);
918 qemu_put_be32(f, so->so_faddr.s_addr);
919 qemu_put_be32(f, so->so_laddr.s_addr);
920 qemu_put_be16(f, so->so_fport);
921 qemu_put_be16(f, so->so_lport);
922 qemu_put_byte(f, so->so_iptos);
923 qemu_put_byte(f, so->so_emu);
924 qemu_put_byte(f, so->so_type);
925 qemu_put_be32(f, so->so_state);
926 slirp_sbuf_save(f, &so->so_rcv);
927 slirp_sbuf_save(f, &so->so_snd);
928 slirp_tcp_save(f, so->so_tcpcb);
929}
930
931static void slirp_bootp_save(QEMUFile *f, Slirp *slirp)
932{
933 int i;
934
935 for (i = 0; i < NB_BOOTP_CLIENTS; i++) {
936 qemu_put_be16(f, slirp->bootp_clients[i].allocated);
937 qemu_put_buffer(f, slirp->bootp_clients[i].macaddr, 6);
938 }
939}
940
941static void slirp_state_save(QEMUFile *f, void *opaque)
942{
943 Slirp *slirp = opaque;
944 struct ex_list *ex_ptr;
945
946 for (ex_ptr = slirp->exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next)
947 if (ex_ptr->ex_pty == 3) {
948 struct socket *so;
949 so = slirp_find_ctl_socket(slirp, ex_ptr->ex_addr,
950 ntohs(ex_ptr->ex_fport));
951 if (!so)
952 continue;
953
954 qemu_put_byte(f, 42);
955 slirp_socket_save(f, so);
956 }
957 qemu_put_byte(f, 0);
958
959 qemu_put_be16(f, slirp->ip_id);
960
961 slirp_bootp_save(f, slirp);
962}
963
964static void slirp_tcp_load(QEMUFile *f, struct tcpcb *tp)
965{
966 int i;
967
968 tp->t_state = qemu_get_sbe16(f);
969 for (i = 0; i < TCPT_NTIMERS; i++)
970 tp->t_timer[i] = qemu_get_sbe16(f);
971 tp->t_rxtshift = qemu_get_sbe16(f);
972 tp->t_rxtcur = qemu_get_sbe16(f);
973 tp->t_dupacks = qemu_get_sbe16(f);
974 tp->t_maxseg = qemu_get_be16(f);
975 tp->t_force = qemu_get_sbyte(f);
976 tp->t_flags = qemu_get_be16(f);
977 tp->snd_una = qemu_get_be32(f);
978 tp->snd_nxt = qemu_get_be32(f);
979 tp->snd_up = qemu_get_be32(f);
980 tp->snd_wl1 = qemu_get_be32(f);
981 tp->snd_wl2 = qemu_get_be32(f);
982 tp->iss = qemu_get_be32(f);
983 tp->snd_wnd = qemu_get_be32(f);
984 tp->rcv_wnd = qemu_get_be32(f);
985 tp->rcv_nxt = qemu_get_be32(f);
986 tp->rcv_up = qemu_get_be32(f);
987 tp->irs = qemu_get_be32(f);
988 tp->rcv_adv = qemu_get_be32(f);
989 tp->snd_max = qemu_get_be32(f);
990 tp->snd_cwnd = qemu_get_be32(f);
991 tp->snd_ssthresh = qemu_get_be32(f);
992 tp->t_idle = qemu_get_sbe16(f);
993 tp->t_rtt = qemu_get_sbe16(f);
994 tp->t_rtseq = qemu_get_be32(f);
995 tp->t_srtt = qemu_get_sbe16(f);
996 tp->t_rttvar = qemu_get_sbe16(f);
997 tp->t_rttmin = qemu_get_be16(f);
998 tp->max_sndwnd = qemu_get_be32(f);
999 tp->t_oobflags = qemu_get_byte(f);
1000 tp->t_iobc = qemu_get_byte(f);
1001 tp->t_softerror = qemu_get_sbe16(f);
1002 tp->snd_scale = qemu_get_byte(f);
1003 tp->rcv_scale = qemu_get_byte(f);
1004 tp->request_r_scale = qemu_get_byte(f);
1005 tp->requested_s_scale = qemu_get_byte(f);
1006 tp->ts_recent = qemu_get_be32(f);
1007 tp->ts_recent_age = qemu_get_be32(f);
1008 tp->last_ack_sent = qemu_get_be32(f);
1009 tcp_template(tp);
1010}
1011
1012static int slirp_sbuf_load(QEMUFile *f, struct sbuf *sbuf)
1013{
1014 uint32_t off, sb_cc, sb_datalen;
1015
1016 sb_cc = qemu_get_be32(f);
1017 sb_datalen = qemu_get_be32(f);
1018
1019 sbreserve(sbuf, sb_datalen);
1020
1021 if (sbuf->sb_datalen != sb_datalen)
1022 return -ENOMEM;
1023
1024 sbuf->sb_cc = sb_cc;
1025
1026 off = qemu_get_sbe32(f);
1027 sbuf->sb_wptr = sbuf->sb_data + off;
1028 off = qemu_get_sbe32(f);
1029 sbuf->sb_rptr = sbuf->sb_data + off;
1030 qemu_get_buffer(f, (unsigned char*)sbuf->sb_data, sbuf->sb_datalen);
1031
1032 return 0;
1033}
1034
1035static int slirp_socket_load(QEMUFile *f, struct socket *so)
1036{
1037 if (tcp_attach(so) < 0)
1038 return -ENOMEM;
1039
1040 so->so_urgc = qemu_get_be32(f);
1041 so->so_faddr.s_addr = qemu_get_be32(f);
1042 so->so_laddr.s_addr = qemu_get_be32(f);
1043 so->so_fport = qemu_get_be16(f);
1044 so->so_lport = qemu_get_be16(f);
1045 so->so_iptos = qemu_get_byte(f);
1046 so->so_emu = qemu_get_byte(f);
1047 so->so_type = qemu_get_byte(f);
1048 so->so_state = qemu_get_be32(f);
1049 if (slirp_sbuf_load(f, &so->so_rcv) < 0)
1050 return -ENOMEM;
1051 if (slirp_sbuf_load(f, &so->so_snd) < 0)
1052 return -ENOMEM;
1053 slirp_tcp_load(f, so->so_tcpcb);
1054
1055 return 0;
1056}
1057
1058static void slirp_bootp_load(QEMUFile *f, Slirp *slirp)
1059{
1060 int i;
1061
1062 for (i = 0; i < NB_BOOTP_CLIENTS; i++) {
1063 slirp->bootp_clients[i].allocated = qemu_get_be16(f);
1064 qemu_get_buffer(f, slirp->bootp_clients[i].macaddr, 6);
1065 }
1066}
1067
1068static int slirp_state_load(QEMUFile *f, void *opaque, int version_id)
1069{
1070 Slirp *slirp = opaque;
1071 struct ex_list *ex_ptr;
1072 int r;
1073
1074 while ((r = 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