4 * Copyright (c) 2004-2008 Fabrice Bellard
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:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
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
24 #include "qemu-common.h"
25 #include "qemu-timer.h"
26 #include "qemu-char.h"
30 /* host dns address */
31 struct in_addr dns_addr;
32 /* host loopback address */
33 struct in_addr loopback_addr;
35 /* emulated hosts use the MAC addr 52:55:IP:IP:IP:IP */
36 static const uint8_t special_ethaddr[6] = {
37 0x52, 0x55, 0x00, 0x00, 0x00, 0x00
40 static const uint8_t zero_ethaddr[6] = { 0, 0, 0, 0, 0, 0 };
42 /* XXX: suppress those select globals */
43 fd_set *global_readfds, *global_writefds, *global_xfds;
46 static u_int time_fasttimo, last_slowtimo;
47 static int do_slowtimo;
49 static TAILQ_HEAD(slirp_instances, Slirp) slirp_instances =
50 TAILQ_HEAD_INITIALIZER(slirp_instances);
54 static int get_dns_addr(struct in_addr *pdns_addr)
56 FIXED_INFO *FixedInfo=NULL;
59 IP_ADDR_STRING *pIPAddr;
60 struct in_addr tmp_addr;
62 FixedInfo = (FIXED_INFO *)GlobalAlloc(GPTR, sizeof(FIXED_INFO));
63 BufLen = sizeof(FIXED_INFO);
65 if (ERROR_BUFFER_OVERFLOW == GetNetworkParams(FixedInfo, &BufLen)) {
67 GlobalFree(FixedInfo);
70 FixedInfo = GlobalAlloc(GPTR, BufLen);
73 if ((ret = GetNetworkParams(FixedInfo, &BufLen)) != ERROR_SUCCESS) {
74 printf("GetNetworkParams failed. ret = %08x\n", (u_int)ret );
76 GlobalFree(FixedInfo);
82 pIPAddr = &(FixedInfo->DnsServerList);
83 inet_aton(pIPAddr->IpAddress.String, &tmp_addr);
84 *pdns_addr = tmp_addr;
86 GlobalFree(FixedInfo);
92 static void winsock_cleanup(void)
99 static int get_dns_addr(struct in_addr *pdns_addr)
105 struct in_addr tmp_addr;
107 f = fopen("/etc/resolv.conf", "r");
112 lprint("IP address of your DNS(s): ");
114 while (fgets(buff, 512, f) != NULL) {
115 if (sscanf(buff, "nameserver%*[ \t]%256s", buff2) == 1) {
116 if (!inet_aton(buff2, &tmp_addr))
118 /* If it's the first one, set it to dns_addr */
120 *pdns_addr = tmp_addr;
133 lprint("%s", inet_ntoa(tmp_addr));
145 static void slirp_init_once(void)
147 static int initialized;
158 WSAStartup(MAKEWORD(2,0), &Data);
159 atexit(winsock_cleanup);
162 loopback_addr.s_addr = htonl(INADDR_LOOPBACK);
164 /* FIXME: This address may change during runtime */
165 if (get_dns_addr(&dns_addr) < 0) {
166 dns_addr = loopback_addr;
170 static void slirp_state_save(QEMUFile *f, void *opaque);
171 static int slirp_state_load(QEMUFile *f, void *opaque, int version_id);
173 Slirp *slirp_init(int restricted, struct in_addr vnetwork,
174 struct in_addr vnetmask, struct in_addr vhost,
175 const char *vhostname, const char *tftp_path,
176 const char *bootfile, struct in_addr vdhcp_start,
177 struct in_addr vnameserver, void *opaque)
179 Slirp *slirp = qemu_mallocz(sizeof(Slirp));
183 slirp->restricted = restricted;
188 /* Initialise mbufs *after* setting the MTU */
191 slirp->vnetwork_addr = vnetwork;
192 slirp->vnetwork_mask = vnetmask;
193 slirp->vhost_addr = vhost;
195 pstrcpy(slirp->client_hostname, sizeof(slirp->client_hostname),
199 slirp->tftp_prefix = qemu_strdup(tftp_path);
202 slirp->bootp_filename = qemu_strdup(bootfile);
204 slirp->vdhcp_startaddr = vdhcp_start;
205 slirp->vnameserver_addr = vnameserver;
207 slirp->opaque = opaque;
209 register_savevm("slirp", 0, 3, slirp_state_save, slirp_state_load, slirp);
211 TAILQ_INSERT_TAIL(&slirp_instances, slirp, entry);
216 void slirp_cleanup(Slirp *slirp)
218 TAILQ_REMOVE(&slirp_instances, slirp, entry);
220 unregister_savevm("slirp", slirp);
222 qemu_free(slirp->tftp_prefix);
223 qemu_free(slirp->bootp_filename);
227 #define CONN_CANFSEND(so) (((so)->so_state & (SS_FCANTSENDMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED)
228 #define CONN_CANFRCV(so) (((so)->so_state & (SS_FCANTRCVMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED)
229 #define UPD_NFDS(x) if (nfds < (x)) nfds = (x)
231 void slirp_select_fill(int *pnfds,
232 fd_set *readfds, fd_set *writefds, fd_set *xfds)
235 struct socket *so, *so_next;
238 if (TAILQ_EMPTY(&slirp_instances)) {
243 global_readfds = NULL;
244 global_writefds = NULL;
253 TAILQ_FOREACH(slirp, &slirp_instances, entry) {
255 * *_slowtimo needs calling if there are IP fragments
256 * in the fragment queue, or there are TCP connections active
258 do_slowtimo |= ((slirp->tcb.so_next != &slirp->tcb) ||
259 (&slirp->ipq.ip_link != slirp->ipq.ip_link.next));
261 for (so = slirp->tcb.so_next; so != &slirp->tcb;
263 so_next = so->so_next;
266 * See if we need a tcp_fasttimo
268 if (time_fasttimo == 0 && so->so_tcpcb->t_flags & TF_DELACK)
269 time_fasttimo = curtime; /* Flag when we want a fasttimo */
272 * NOFDREF can include still connecting to local-host,
273 * newly socreated() sockets etc. Don't want to select these.
275 if (so->so_state & SS_NOFDREF || so->s == -1)
279 * Set for reading sockets which are accepting
281 if (so->so_state & SS_FACCEPTCONN) {
282 FD_SET(so->s, readfds);
288 * Set for writing sockets which are connecting
290 if (so->so_state & SS_ISFCONNECTING) {
291 FD_SET(so->s, writefds);
297 * Set for writing if we are connected, can send more, and
298 * we have something to send
300 if (CONN_CANFSEND(so) && so->so_rcv.sb_cc) {
301 FD_SET(so->s, writefds);
306 * Set for reading (and urgent data) if we are connected, can
307 * receive more, and we have room for it XXX /2 ?
309 if (CONN_CANFRCV(so) && (so->so_snd.sb_cc < (so->so_snd.sb_datalen/2))) {
310 FD_SET(so->s, readfds);
319 for (so = slirp->udb.so_next; so != &slirp->udb;
321 so_next = so->so_next;
324 * See if it's timed out
327 if (so->so_expire <= curtime) {
331 do_slowtimo = 1; /* Let socket expire */
335 * When UDP packets are received from over the
336 * link, they're sendto()'d straight away, so
337 * no need for setting for writing
338 * Limit the number of packets queued by this session
339 * to 4. Note that even though we try and limit this
340 * to 4 packets, the session could have more queued
341 * if the packets needed to be fragmented
344 if ((so->so_state & SS_ISFCONNECTED) && so->so_queued <= 4) {
345 FD_SET(so->s, readfds);
354 void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds,
358 struct socket *so, *so_next;
361 if (TAILQ_EMPTY(&slirp_instances)) {
365 global_readfds = readfds;
366 global_writefds = writefds;
369 curtime = qemu_get_clock(rt_clock);
371 TAILQ_FOREACH(slirp, &slirp_instances, entry) {
373 * See if anything has timed out
375 if (time_fasttimo && ((curtime - time_fasttimo) >= 2)) {
379 if (do_slowtimo && ((curtime - last_slowtimo) >= 499)) {
382 last_slowtimo = curtime;
392 for (so = slirp->tcb.so_next; so != &slirp->tcb;
394 so_next = so->so_next;
397 * FD_ISSET is meaningless on these sockets
398 * (and they can crash the program)
400 if (so->so_state & SS_NOFDREF || so->s == -1)
405 * This will soread as well, so no need to
406 * test for readfds below if this succeeds
408 if (FD_ISSET(so->s, xfds))
411 * Check sockets for reading
413 else if (FD_ISSET(so->s, readfds)) {
415 * Check for incoming connections
417 if (so->so_state & SS_FACCEPTCONN) {
423 /* Output it if we read something */
425 tcp_output(sototcpcb(so));
429 * Check sockets for writing
431 if (FD_ISSET(so->s, writefds)) {
433 * Check for non-blocking, still-connecting sockets
435 if (so->so_state & SS_ISFCONNECTING) {
437 so->so_state &= ~SS_ISFCONNECTING;
439 ret = send(so->s, (const void *) &ret, 0, 0);
441 /* XXXXX Must fix, zero bytes is a NOP */
442 if (errno == EAGAIN || errno == EWOULDBLOCK ||
443 errno == EINPROGRESS || errno == ENOTCONN)
447 so->so_state &= SS_PERSISTENT_MASK;
448 so->so_state |= SS_NOFDREF;
450 /* else so->so_state &= ~SS_ISFCONNECTING; */
455 tcp_input((struct mbuf *)NULL, sizeof(struct ip), so);
460 * XXXXX If we wrote something (a lot), there
461 * could be a need for a window update.
462 * In the worst case, the remote will send
463 * a window probe to get things going again
468 * Probe a still-connecting, non-blocking socket
469 * to check if it's still alive
472 if (so->so_state & SS_ISFCONNECTING) {
473 ret = recv(so->s, (char *)&ret, 0,0);
477 if (errno == EAGAIN || errno == EWOULDBLOCK ||
478 errno == EINPROGRESS || errno == ENOTCONN)
479 continue; /* Still connecting, continue */
482 so->so_state &= SS_PERSISTENT_MASK;
483 so->so_state |= SS_NOFDREF;
485 /* tcp_input will take care of it */
487 ret = send(so->s, &ret, 0,0);
490 if (errno == EAGAIN || errno == EWOULDBLOCK ||
491 errno == EINPROGRESS || errno == ENOTCONN)
494 so->so_state &= SS_PERSISTENT_MASK;
495 so->so_state |= SS_NOFDREF;
497 so->so_state &= ~SS_ISFCONNECTING;
500 tcp_input((struct mbuf *)NULL, sizeof(struct ip),so);
501 } /* SS_ISFCONNECTING */
507 * Incoming packets are sent straight away, they're not buffered.
508 * Incoming UDP data isn't buffered either.
510 for (so = slirp->udb.so_next; so != &slirp->udb;
512 so_next = so->so_next;
514 if (so->s != -1 && FD_ISSET(so->s, readfds)) {
521 * See if we can start outputting
523 if (slirp->if_queued) {
528 /* clear global file descriptor sets.
529 * these reside on the stack in vl.c
530 * so they're unusable if we're not in
531 * slirp_select_fill or slirp_select_poll.
533 global_readfds = NULL;
534 global_writefds = NULL;
541 #define ETH_P_IP 0x0800 /* Internet Protocol packet */
542 #define ETH_P_ARP 0x0806 /* Address Resolution packet */
544 #define ARPOP_REQUEST 1 /* ARP request */
545 #define ARPOP_REPLY 2 /* ARP reply */
549 unsigned char h_dest[ETH_ALEN]; /* destination eth addr */
550 unsigned char h_source[ETH_ALEN]; /* source ether addr */
551 unsigned short h_proto; /* packet type ID field */
556 unsigned short ar_hrd; /* format of hardware address */
557 unsigned short ar_pro; /* format of protocol address */
558 unsigned char ar_hln; /* length of hardware address */
559 unsigned char ar_pln; /* length of protocol address */
560 unsigned short ar_op; /* ARP opcode (command) */
563 * Ethernet looks like this : This bit is variable sized however...
565 unsigned char ar_sha[ETH_ALEN]; /* sender hardware address */
566 uint32_t ar_sip; /* sender IP address */
567 unsigned char ar_tha[ETH_ALEN]; /* target hardware address */
568 uint32_t ar_tip ; /* target IP address */
569 } __attribute__((packed));
571 static void arp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len)
573 struct ethhdr *eh = (struct ethhdr *)pkt;
574 struct arphdr *ah = (struct arphdr *)(pkt + ETH_HLEN);
575 uint8_t arp_reply[ETH_HLEN + sizeof(struct arphdr)];
576 struct ethhdr *reh = (struct ethhdr *)arp_reply;
577 struct arphdr *rah = (struct arphdr *)(arp_reply + ETH_HLEN);
579 struct ex_list *ex_ptr;
581 ar_op = ntohs(ah->ar_op);
584 if ((ah->ar_tip & slirp->vnetwork_mask.s_addr) ==
585 slirp->vnetwork_addr.s_addr) {
586 if (ah->ar_tip == slirp->vnameserver_addr.s_addr ||
587 ah->ar_tip == slirp->vhost_addr.s_addr)
589 for (ex_ptr = slirp->exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
590 if (ex_ptr->ex_addr.s_addr == ah->ar_tip)
595 /* XXX: make an ARP request to have the client address */
596 memcpy(slirp->client_ethaddr, eh->h_source, ETH_ALEN);
598 /* ARP request for alias/dns mac address */
599 memcpy(reh->h_dest, pkt + ETH_ALEN, ETH_ALEN);
600 memcpy(reh->h_source, special_ethaddr, ETH_ALEN - 4);
601 memcpy(&reh->h_source[2], &ah->ar_tip, 4);
602 reh->h_proto = htons(ETH_P_ARP);
604 rah->ar_hrd = htons(1);
605 rah->ar_pro = htons(ETH_P_IP);
606 rah->ar_hln = ETH_ALEN;
608 rah->ar_op = htons(ARPOP_REPLY);
609 memcpy(rah->ar_sha, reh->h_source, ETH_ALEN);
610 rah->ar_sip = ah->ar_tip;
611 memcpy(rah->ar_tha, ah->ar_sha, ETH_ALEN);
612 rah->ar_tip = ah->ar_sip;
613 slirp_output(slirp->opaque, arp_reply, sizeof(arp_reply));
617 /* reply to request of client mac address ? */
618 if (!memcmp(slirp->client_ethaddr, zero_ethaddr, ETH_ALEN) &&
619 ah->ar_sip == slirp->client_ipaddr.s_addr) {
620 memcpy(slirp->client_ethaddr, ah->ar_sha, ETH_ALEN);
628 void slirp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len)
633 if (pkt_len < ETH_HLEN)
636 proto = ntohs(*(uint16_t *)(pkt + 12));
639 arp_input(slirp, pkt, pkt_len);
645 /* Note: we add to align the IP header */
646 if (M_FREEROOM(m) < pkt_len + 2) {
647 m_inc(m, pkt_len + 2);
649 m->m_len = pkt_len + 2;
650 memcpy(m->m_data + 2, pkt, pkt_len);
652 m->m_data += 2 + ETH_HLEN;
653 m->m_len -= 2 + ETH_HLEN;
662 /* output the IP packet to the ethernet device */
663 void if_encap(Slirp *slirp, const uint8_t *ip_data, int ip_data_len)
666 struct ethhdr *eh = (struct ethhdr *)buf;
668 if (ip_data_len + ETH_HLEN > sizeof(buf))
671 if (!memcmp(slirp->client_ethaddr, zero_ethaddr, ETH_ALEN)) {
672 uint8_t arp_req[ETH_HLEN + sizeof(struct arphdr)];
673 struct ethhdr *reh = (struct ethhdr *)arp_req;
674 struct arphdr *rah = (struct arphdr *)(arp_req + ETH_HLEN);
675 const struct ip *iph = (const struct ip *)ip_data;
677 /* If the client addr is not known, there is no point in
678 sending the packet to it. Normally the sender should have
679 done an ARP request to get its MAC address. Here we do it
680 in place of sending the packet and we hope that the sender
681 will retry sending its packet. */
682 memset(reh->h_dest, 0xff, ETH_ALEN);
683 memcpy(reh->h_source, special_ethaddr, ETH_ALEN - 4);
684 memcpy(&reh->h_source[2], &slirp->vhost_addr, 4);
685 reh->h_proto = htons(ETH_P_ARP);
686 rah->ar_hrd = htons(1);
687 rah->ar_pro = htons(ETH_P_IP);
688 rah->ar_hln = ETH_ALEN;
690 rah->ar_op = htons(ARPOP_REQUEST);
692 memcpy(rah->ar_sha, special_ethaddr, ETH_ALEN - 4);
693 memcpy(&rah->ar_sha[2], &slirp->vhost_addr, 4);
695 rah->ar_sip = slirp->vhost_addr.s_addr;
696 /* target hw addr (none) */
697 memset(rah->ar_tha, 0, ETH_ALEN);
699 rah->ar_tip = iph->ip_dst.s_addr;
700 slirp->client_ipaddr = iph->ip_dst;
701 slirp_output(slirp->opaque, arp_req, sizeof(arp_req));
703 memcpy(eh->h_dest, slirp->client_ethaddr, ETH_ALEN);
704 memcpy(eh->h_source, special_ethaddr, ETH_ALEN - 4);
705 /* XXX: not correct */
706 memcpy(&eh->h_source[2], &slirp->vhost_addr, 4);
707 eh->h_proto = htons(ETH_P_IP);
708 memcpy(buf + sizeof(struct ethhdr), ip_data, ip_data_len);
709 slirp_output(slirp->opaque, buf, ip_data_len + ETH_HLEN);
713 /* Drop host forwarding rule, return 0 if found. */
714 int slirp_remove_hostfwd(Slirp *slirp, int is_udp, struct in_addr host_addr,
718 struct socket *head = (is_udp ? &slirp->udb : &slirp->tcb);
719 struct sockaddr_in addr;
720 int port = htons(host_port);
723 for (so = head->so_next; so != head; so = so->so_next) {
724 addr_len = sizeof(addr);
725 if ((so->so_state & SS_HOSTFWD) &&
726 getsockname(so->s, (struct sockaddr *)&addr, &addr_len) == 0 &&
727 addr.sin_addr.s_addr == host_addr.s_addr &&
728 addr.sin_port == port) {
738 int slirp_add_hostfwd(Slirp *slirp, int is_udp, struct in_addr host_addr,
739 int host_port, struct in_addr guest_addr, int guest_port)
741 if (!guest_addr.s_addr) {
742 guest_addr = slirp->vdhcp_startaddr;
745 if (!udp_listen(slirp, host_addr.s_addr, htons(host_port),
746 guest_addr.s_addr, htons(guest_port), SS_HOSTFWD))
749 if (!tcp_listen(slirp, host_addr.s_addr, htons(host_port),
750 guest_addr.s_addr, htons(guest_port), SS_HOSTFWD))
756 int slirp_add_exec(Slirp *slirp, int do_pty, const void *args,
757 struct in_addr *guest_addr, int guest_port)
759 if (!guest_addr->s_addr) {
760 guest_addr->s_addr = slirp->vnetwork_addr.s_addr |
761 (htonl(0x0204) & ~slirp->vnetwork_mask.s_addr);
763 if ((guest_addr->s_addr & slirp->vnetwork_mask.s_addr) !=
764 slirp->vnetwork_addr.s_addr ||
765 guest_addr->s_addr == slirp->vhost_addr.s_addr ||
766 guest_addr->s_addr == slirp->vnameserver_addr.s_addr) {
769 return add_exec(&slirp->exec_list, do_pty, (char *)args, *guest_addr,
773 ssize_t slirp_send(struct socket *so, const void *buf, size_t len, int flags)
775 if (so->s == -1 && so->extra) {
776 qemu_chr_write(so->extra, buf, len);
780 return send(so->s, buf, len, flags);
783 static struct socket *
784 slirp_find_ctl_socket(Slirp *slirp, struct in_addr guest_addr, int guest_port)
788 for (so = slirp->tcb.so_next; so != &slirp->tcb; so = so->so_next) {
789 if (so->so_faddr.s_addr == guest_addr.s_addr &&
790 htons(so->so_fport) == guest_port) {
797 size_t slirp_socket_can_recv(Slirp *slirp, struct in_addr guest_addr,
803 so = slirp_find_ctl_socket(slirp, guest_addr, guest_port);
805 if (!so || so->so_state & SS_NOFDREF)
808 if (!CONN_CANFRCV(so) || so->so_snd.sb_cc >= (so->so_snd.sb_datalen/2))
811 return sopreprbuf(so, iov, NULL);
814 void slirp_socket_recv(Slirp *slirp, struct in_addr guest_addr, int guest_port,
815 const uint8_t *buf, int size)
818 struct socket *so = slirp_find_ctl_socket(slirp, guest_addr, guest_port);
823 ret = soreadbuf(so, (const char *)buf, size);
826 tcp_output(sototcpcb(so));
829 static void slirp_tcp_save(QEMUFile *f, struct tcpcb *tp)
833 qemu_put_sbe16(f, tp->t_state);
834 for (i = 0; i < TCPT_NTIMERS; i++)
835 qemu_put_sbe16(f, tp->t_timer[i]);
836 qemu_put_sbe16(f, tp->t_rxtshift);
837 qemu_put_sbe16(f, tp->t_rxtcur);
838 qemu_put_sbe16(f, tp->t_dupacks);
839 qemu_put_be16(f, tp->t_maxseg);
840 qemu_put_sbyte(f, tp->t_force);
841 qemu_put_be16(f, tp->t_flags);
842 qemu_put_be32(f, tp->snd_una);
843 qemu_put_be32(f, tp->snd_nxt);
844 qemu_put_be32(f, tp->snd_up);
845 qemu_put_be32(f, tp->snd_wl1);
846 qemu_put_be32(f, tp->snd_wl2);
847 qemu_put_be32(f, tp->iss);
848 qemu_put_be32(f, tp->snd_wnd);
849 qemu_put_be32(f, tp->rcv_wnd);
850 qemu_put_be32(f, tp->rcv_nxt);
851 qemu_put_be32(f, tp->rcv_up);
852 qemu_put_be32(f, tp->irs);
853 qemu_put_be32(f, tp->rcv_adv);
854 qemu_put_be32(f, tp->snd_max);
855 qemu_put_be32(f, tp->snd_cwnd);
856 qemu_put_be32(f, tp->snd_ssthresh);
857 qemu_put_sbe16(f, tp->t_idle);
858 qemu_put_sbe16(f, tp->t_rtt);
859 qemu_put_be32(f, tp->t_rtseq);
860 qemu_put_sbe16(f, tp->t_srtt);
861 qemu_put_sbe16(f, tp->t_rttvar);
862 qemu_put_be16(f, tp->t_rttmin);
863 qemu_put_be32(f, tp->max_sndwnd);
864 qemu_put_byte(f, tp->t_oobflags);
865 qemu_put_byte(f, tp->t_iobc);
866 qemu_put_sbe16(f, tp->t_softerror);
867 qemu_put_byte(f, tp->snd_scale);
868 qemu_put_byte(f, tp->rcv_scale);
869 qemu_put_byte(f, tp->request_r_scale);
870 qemu_put_byte(f, tp->requested_s_scale);
871 qemu_put_be32(f, tp->ts_recent);
872 qemu_put_be32(f, tp->ts_recent_age);
873 qemu_put_be32(f, tp->last_ack_sent);
876 static void slirp_sbuf_save(QEMUFile *f, struct sbuf *sbuf)
880 qemu_put_be32(f, sbuf->sb_cc);
881 qemu_put_be32(f, sbuf->sb_datalen);
882 off = (uint32_t)(sbuf->sb_wptr - sbuf->sb_data);
883 qemu_put_sbe32(f, off);
884 off = (uint32_t)(sbuf->sb_rptr - sbuf->sb_data);
885 qemu_put_sbe32(f, off);
886 qemu_put_buffer(f, (unsigned char*)sbuf->sb_data, sbuf->sb_datalen);
889 static void slirp_socket_save(QEMUFile *f, struct socket *so)
891 qemu_put_be32(f, so->so_urgc);
892 qemu_put_be32(f, so->so_faddr.s_addr);
893 qemu_put_be32(f, so->so_laddr.s_addr);
894 qemu_put_be16(f, so->so_fport);
895 qemu_put_be16(f, so->so_lport);
896 qemu_put_byte(f, so->so_iptos);
897 qemu_put_byte(f, so->so_emu);
898 qemu_put_byte(f, so->so_type);
899 qemu_put_be32(f, so->so_state);
900 slirp_sbuf_save(f, &so->so_rcv);
901 slirp_sbuf_save(f, &so->so_snd);
902 slirp_tcp_save(f, so->so_tcpcb);
905 static void slirp_bootp_save(QEMUFile *f, Slirp *slirp)
909 for (i = 0; i < NB_BOOTP_CLIENTS; i++) {
910 qemu_put_be16(f, slirp->bootp_clients[i].allocated);
911 qemu_put_buffer(f, slirp->bootp_clients[i].macaddr, 6);
915 static void slirp_state_save(QEMUFile *f, void *opaque)
917 Slirp *slirp = opaque;
918 struct ex_list *ex_ptr;
920 for (ex_ptr = slirp->exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next)
921 if (ex_ptr->ex_pty == 3) {
923 so = slirp_find_ctl_socket(slirp, ex_ptr->ex_addr,
924 ntohs(ex_ptr->ex_fport));
928 qemu_put_byte(f, 42);
929 slirp_socket_save(f, so);
933 qemu_put_be16(f, slirp->ip_id);
935 slirp_bootp_save(f, slirp);
938 static void slirp_tcp_load(QEMUFile *f, struct tcpcb *tp)
942 tp->t_state = qemu_get_sbe16(f);
943 for (i = 0; i < TCPT_NTIMERS; i++)
944 tp->t_timer[i] = qemu_get_sbe16(f);
945 tp->t_rxtshift = qemu_get_sbe16(f);
946 tp->t_rxtcur = qemu_get_sbe16(f);
947 tp->t_dupacks = qemu_get_sbe16(f);
948 tp->t_maxseg = qemu_get_be16(f);
949 tp->t_force = qemu_get_sbyte(f);
950 tp->t_flags = qemu_get_be16(f);
951 tp->snd_una = qemu_get_be32(f);
952 tp->snd_nxt = qemu_get_be32(f);
953 tp->snd_up = qemu_get_be32(f);
954 tp->snd_wl1 = qemu_get_be32(f);
955 tp->snd_wl2 = qemu_get_be32(f);
956 tp->iss = qemu_get_be32(f);
957 tp->snd_wnd = qemu_get_be32(f);
958 tp->rcv_wnd = qemu_get_be32(f);
959 tp->rcv_nxt = qemu_get_be32(f);
960 tp->rcv_up = qemu_get_be32(f);
961 tp->irs = qemu_get_be32(f);
962 tp->rcv_adv = qemu_get_be32(f);
963 tp->snd_max = qemu_get_be32(f);
964 tp->snd_cwnd = qemu_get_be32(f);
965 tp->snd_ssthresh = qemu_get_be32(f);
966 tp->t_idle = qemu_get_sbe16(f);
967 tp->t_rtt = qemu_get_sbe16(f);
968 tp->t_rtseq = qemu_get_be32(f);
969 tp->t_srtt = qemu_get_sbe16(f);
970 tp->t_rttvar = qemu_get_sbe16(f);
971 tp->t_rttmin = qemu_get_be16(f);
972 tp->max_sndwnd = qemu_get_be32(f);
973 tp->t_oobflags = qemu_get_byte(f);
974 tp->t_iobc = qemu_get_byte(f);
975 tp->t_softerror = qemu_get_sbe16(f);
976 tp->snd_scale = qemu_get_byte(f);
977 tp->rcv_scale = qemu_get_byte(f);
978 tp->request_r_scale = qemu_get_byte(f);
979 tp->requested_s_scale = qemu_get_byte(f);
980 tp->ts_recent = qemu_get_be32(f);
981 tp->ts_recent_age = qemu_get_be32(f);
982 tp->last_ack_sent = qemu_get_be32(f);
986 static int slirp_sbuf_load(QEMUFile *f, struct sbuf *sbuf)
988 uint32_t off, sb_cc, sb_datalen;
990 sb_cc = qemu_get_be32(f);
991 sb_datalen = qemu_get_be32(f);
993 sbreserve(sbuf, sb_datalen);
995 if (sbuf->sb_datalen != sb_datalen)
1000 off = qemu_get_sbe32(f);
1001 sbuf->sb_wptr = sbuf->sb_data + off;
1002 off = qemu_get_sbe32(f);
1003 sbuf->sb_rptr = sbuf->sb_data + off;
1004 qemu_get_buffer(f, (unsigned char*)sbuf->sb_data, sbuf->sb_datalen);
1009 static int slirp_socket_load(QEMUFile *f, struct socket *so)
1011 if (tcp_attach(so) < 0)
1014 so->so_urgc = qemu_get_be32(f);
1015 so->so_faddr.s_addr = qemu_get_be32(f);
1016 so->so_laddr.s_addr = qemu_get_be32(f);
1017 so->so_fport = qemu_get_be16(f);
1018 so->so_lport = qemu_get_be16(f);
1019 so->so_iptos = qemu_get_byte(f);
1020 so->so_emu = qemu_get_byte(f);
1021 so->so_type = qemu_get_byte(f);
1022 so->so_state = qemu_get_be32(f);
1023 if (slirp_sbuf_load(f, &so->so_rcv) < 0)
1025 if (slirp_sbuf_load(f, &so->so_snd) < 0)
1027 slirp_tcp_load(f, so->so_tcpcb);
1032 static void slirp_bootp_load(QEMUFile *f, Slirp *slirp)
1036 for (i = 0; i < NB_BOOTP_CLIENTS; i++) {
1037 slirp->bootp_clients[i].allocated = qemu_get_be16(f);
1038 qemu_get_buffer(f, slirp->bootp_clients[i].macaddr, 6);
1042 static int slirp_state_load(QEMUFile *f, void *opaque, int version_id)
1044 Slirp *slirp = opaque;
1045 struct ex_list *ex_ptr;
1048 while ((r = qemu_get_byte(f))) {
1050 struct socket *so = socreate(slirp);
1055 ret = slirp_socket_load(f, so);
1060 if ((so->so_faddr.s_addr & slirp->vnetwork_mask.s_addr) !=
1061 slirp->vnetwork_addr.s_addr) {
1064 for (ex_ptr = slirp->exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
1065 if (ex_ptr->ex_pty == 3 &&
1066 so->so_faddr.s_addr == ex_ptr->ex_addr.s_addr &&
1067 so->so_fport == ex_ptr->ex_fport) {
1074 so->extra = (void *)ex_ptr->ex_exec;
1077 if (version_id >= 2) {
1078 slirp->ip_id = qemu_get_be16(f);
1081 if (version_id >= 3) {
1082 slirp_bootp_load(f, slirp);