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-char.h"
30 struct in_addr our_addr
;
31 /* host dns address */
32 struct in_addr dns_addr
;
33 /* host loopback address */
34 struct in_addr loopback_addr
;
36 /* address for slirp virtual addresses */
37 struct in_addr special_addr
;
38 /* virtual address alias for host */
39 struct in_addr alias_addr
;
41 static const uint8_t special_ethaddr
[6] = {
42 0x52, 0x54, 0x00, 0x12, 0x35, 0x00
45 /* ARP cache for the guest IP addresses (XXX: allow many entries) */
46 uint8_t client_ethaddr
[6];
47 static struct in_addr client_ipaddr
;
49 static const uint8_t zero_ethaddr
[6] = { 0, 0, 0, 0, 0, 0 };
51 const char *slirp_special_ip
= CTL_SPECIAL
;
53 static int do_slowtimo
;
57 struct ex_list
*exec_list
;
59 /* XXX: suppress those select globals */
60 fd_set
*global_readfds
, *global_writefds
, *global_xfds
;
62 char slirp_hostname
[33];
66 static int get_dns_addr(struct in_addr
*pdns_addr
)
68 FIXED_INFO
*FixedInfo
=NULL
;
71 IP_ADDR_STRING
*pIPAddr
;
72 struct in_addr tmp_addr
;
74 FixedInfo
= (FIXED_INFO
*)GlobalAlloc(GPTR
, sizeof(FIXED_INFO
));
75 BufLen
= sizeof(FIXED_INFO
);
77 if (ERROR_BUFFER_OVERFLOW
== GetNetworkParams(FixedInfo
, &BufLen
)) {
79 GlobalFree(FixedInfo
);
82 FixedInfo
= GlobalAlloc(GPTR
, BufLen
);
85 if ((ret
= GetNetworkParams(FixedInfo
, &BufLen
)) != ERROR_SUCCESS
) {
86 printf("GetNetworkParams failed. ret = %08x\n", (u_int
)ret
);
88 GlobalFree(FixedInfo
);
94 pIPAddr
= &(FixedInfo
->DnsServerList
);
95 inet_aton(pIPAddr
->IpAddress
.String
, &tmp_addr
);
96 *pdns_addr
= tmp_addr
;
98 printf( "DNS Servers:\n" );
99 printf( "DNS Addr:%s\n", pIPAddr
->IpAddress
.String
);
101 pIPAddr
= FixedInfo
-> DnsServerList
.Next
;
103 printf( "DNS Addr:%s\n", pIPAddr
->IpAddress
.String
);
104 pIPAddr
= pIPAddr
->Next
;
108 GlobalFree(FixedInfo
);
116 static int get_dns_addr(struct in_addr
*pdns_addr
)
122 struct in_addr tmp_addr
;
124 f
= fopen("/etc/resolv.conf", "r");
129 lprint("IP address of your DNS(s): ");
131 while (fgets(buff
, 512, f
) != NULL
) {
132 if (sscanf(buff
, "nameserver%*[ \t]%256s", buff2
) == 1) {
133 if (!inet_aton(buff2
, &tmp_addr
))
135 if (tmp_addr
.s_addr
== loopback_addr
.s_addr
)
137 /* If it's the first one, set it to dns_addr */
139 *pdns_addr
= tmp_addr
;
152 lprint("%s", inet_ntoa(tmp_addr
));
165 static void slirp_cleanup(void)
171 static void slirp_state_save(QEMUFile
*f
, void *opaque
);
172 static int slirp_state_load(QEMUFile
*f
, void *opaque
, int version_id
);
174 void slirp_init(int restricted
, char *special_ip
)
176 // debug_init("/tmp/slirp.log", DEBUG_DEFAULT);
181 WSAStartup(MAKEWORD(2,0), &Data
);
182 atexit(slirp_cleanup
);
187 slirp_restrict
= restricted
;
192 /* Initialise mbufs *after* setting the MTU */
195 /* set default addresses */
196 inet_aton("127.0.0.1", &loopback_addr
);
198 if (get_dns_addr(&dns_addr
) < 0) {
199 dns_addr
= loopback_addr
;
200 fprintf (stderr
, "Warning: No DNS servers found\n");
204 slirp_special_ip
= special_ip
;
206 inet_aton(slirp_special_ip
, &special_addr
);
207 alias_addr
.s_addr
= special_addr
.s_addr
| htonl(CTL_ALIAS
);
209 register_savevm("slirp", 0, 1, slirp_state_save
, slirp_state_load
, NULL
);
212 #define CONN_CANFSEND(so) (((so)->so_state & (SS_FCANTSENDMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED)
213 #define CONN_CANFRCV(so) (((so)->so_state & (SS_FCANTRCVMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED)
214 #define UPD_NFDS(x) if (nfds < (x)) nfds = (x)
217 * curtime kept to an accuracy of 1ms
220 static void updtime(void)
225 curtime
= (u_int
)tb
.time
* (u_int
)1000;
226 curtime
+= (u_int
)tb
.millitm
;
229 static void updtime(void)
231 gettimeofday(&tt
, NULL
);
233 curtime
= (u_int
)tt
.tv_sec
* (u_int
)1000;
234 curtime
+= (u_int
)tt
.tv_usec
/ (u_int
)1000;
236 if ((tt
.tv_usec
% 1000) >= 500)
241 void slirp_select_fill(int *pnfds
,
242 fd_set
*readfds
, fd_set
*writefds
, fd_set
*xfds
)
244 struct socket
*so
, *so_next
;
245 struct timeval timeout
;
250 global_readfds
= NULL
;
251 global_writefds
= NULL
;
261 * *_slowtimo needs calling if there are IP fragments
262 * in the fragment queue, or there are TCP connections active
264 do_slowtimo
= ((tcb
.so_next
!= &tcb
) ||
265 (&ipq
.ip_link
!= ipq
.ip_link
.next
));
267 for (so
= tcb
.so_next
; so
!= &tcb
; so
= so_next
) {
268 so_next
= so
->so_next
;
271 * See if we need a tcp_fasttimo
273 if (time_fasttimo
== 0 && so
->so_tcpcb
->t_flags
& TF_DELACK
)
274 time_fasttimo
= curtime
; /* Flag when we want a fasttimo */
277 * NOFDREF can include still connecting to local-host,
278 * newly socreated() sockets etc. Don't want to select these.
280 if (so
->so_state
& SS_NOFDREF
|| so
->s
== -1)
284 * Set for reading sockets which are accepting
286 if (so
->so_state
& SS_FACCEPTCONN
) {
287 FD_SET(so
->s
, readfds
);
293 * Set for writing sockets which are connecting
295 if (so
->so_state
& SS_ISFCONNECTING
) {
296 FD_SET(so
->s
, writefds
);
302 * Set for writing if we are connected, can send more, and
303 * we have something to send
305 if (CONN_CANFSEND(so
) && so
->so_rcv
.sb_cc
) {
306 FD_SET(so
->s
, writefds
);
311 * Set for reading (and urgent data) if we are connected, can
312 * receive more, and we have room for it XXX /2 ?
314 if (CONN_CANFRCV(so
) && (so
->so_snd
.sb_cc
< (so
->so_snd
.sb_datalen
/2))) {
315 FD_SET(so
->s
, readfds
);
324 for (so
= udb
.so_next
; so
!= &udb
; so
= so_next
) {
325 so_next
= so
->so_next
;
328 * See if it's timed out
331 if (so
->so_expire
<= curtime
) {
335 do_slowtimo
= 1; /* Let socket expire */
339 * When UDP packets are received from over the
340 * link, they're sendto()'d straight away, so
341 * no need for setting for writing
342 * Limit the number of packets queued by this session
343 * to 4. Note that even though we try and limit this
344 * to 4 packets, the session could have more queued
345 * if the packets needed to be fragmented
348 if ((so
->so_state
& SS_ISFCONNECTED
) && so
->so_queued
<= 4) {
349 FD_SET(so
->s
, readfds
);
356 * Setup timeout to use minimum CPU usage, especially when idle
360 * First, see the timeout needed by *timo
363 timeout
.tv_usec
= -1;
365 * If a slowtimo is needed, set timeout to 500ms from the last
366 * slow timeout. If a fast timeout is needed, set timeout within
367 * 200ms of when it was requested.
370 /* XXX + 10000 because some select()'s aren't that accurate */
371 timeout
.tv_usec
= ((500 - (curtime
- last_slowtimo
)) * 1000) + 10000;
372 if (timeout
.tv_usec
< 0)
374 else if (timeout
.tv_usec
> 510000)
375 timeout
.tv_usec
= 510000;
377 /* Can only fasttimo if we also slowtimo */
379 tmp_time
= (200 - (curtime
- time_fasttimo
)) * 1000;
383 /* Choose the smallest of the 2 */
384 if (tmp_time
< timeout
.tv_usec
)
385 timeout
.tv_usec
= (u_int
)tmp_time
;
391 void slirp_select_poll(fd_set
*readfds
, fd_set
*writefds
, fd_set
*xfds
)
393 struct socket
*so
, *so_next
;
396 global_readfds
= readfds
;
397 global_writefds
= writefds
;
404 * See if anything has timed out
407 if (time_fasttimo
&& ((curtime
- time_fasttimo
) >= 2)) {
411 if (do_slowtimo
&& ((curtime
- last_slowtimo
) >= 499)) {
414 last_slowtimo
= curtime
;
425 for (so
= tcb
.so_next
; so
!= &tcb
; so
= so_next
) {
426 so_next
= so
->so_next
;
429 * FD_ISSET is meaningless on these sockets
430 * (and they can crash the program)
432 if (so
->so_state
& SS_NOFDREF
|| so
->s
== -1)
437 * This will soread as well, so no need to
438 * test for readfds below if this succeeds
440 if (FD_ISSET(so
->s
, xfds
))
443 * Check sockets for reading
445 else if (FD_ISSET(so
->s
, readfds
)) {
447 * Check for incoming connections
449 if (so
->so_state
& SS_FACCEPTCONN
) {
455 /* Output it if we read something */
457 tcp_output(sototcpcb(so
));
461 * Check sockets for writing
463 if (FD_ISSET(so
->s
, writefds
)) {
465 * Check for non-blocking, still-connecting sockets
467 if (so
->so_state
& SS_ISFCONNECTING
) {
469 so
->so_state
&= ~SS_ISFCONNECTING
;
471 ret
= send(so
->s
, (const void *) &ret
, 0, 0);
473 /* XXXXX Must fix, zero bytes is a NOP */
474 if (errno
== EAGAIN
|| errno
== EWOULDBLOCK
||
475 errno
== EINPROGRESS
|| errno
== ENOTCONN
)
479 so
->so_state
= SS_NOFDREF
;
481 /* else so->so_state &= ~SS_ISFCONNECTING; */
486 tcp_input((struct mbuf
*)NULL
, sizeof(struct ip
), so
);
491 * XXXXX If we wrote something (a lot), there
492 * could be a need for a window update.
493 * In the worst case, the remote will send
494 * a window probe to get things going again
499 * Probe a still-connecting, non-blocking socket
500 * to check if it's still alive
503 if (so
->so_state
& SS_ISFCONNECTING
) {
504 ret
= recv(so
->s
, (char *)&ret
, 0,0);
508 if (errno
== EAGAIN
|| errno
== EWOULDBLOCK
||
509 errno
== EINPROGRESS
|| errno
== ENOTCONN
)
510 continue; /* Still connecting, continue */
513 so
->so_state
= SS_NOFDREF
;
515 /* tcp_input will take care of it */
517 ret
= send(so
->s
, &ret
, 0,0);
520 if (errno
== EAGAIN
|| errno
== EWOULDBLOCK
||
521 errno
== EINPROGRESS
|| errno
== ENOTCONN
)
524 so
->so_state
= SS_NOFDREF
;
526 so
->so_state
&= ~SS_ISFCONNECTING
;
529 tcp_input((struct mbuf
*)NULL
, sizeof(struct ip
),so
);
530 } /* SS_ISFCONNECTING */
536 * Incoming packets are sent straight away, they're not buffered.
537 * Incoming UDP data isn't buffered either.
539 for (so
= udb
.so_next
; so
!= &udb
; so
= so_next
) {
540 so_next
= so
->so_next
;
542 if (so
->s
!= -1 && FD_ISSET(so
->s
, readfds
)) {
549 * See if we can start outputting
551 if (if_queued
&& link_up
)
554 /* clear global file descriptor sets.
555 * these reside on the stack in vl.c
556 * so they're unusable if we're not in
557 * slirp_select_fill or slirp_select_poll.
559 global_readfds
= NULL
;
560 global_writefds
= NULL
;
567 #define ETH_P_IP 0x0800 /* Internet Protocol packet */
568 #define ETH_P_ARP 0x0806 /* Address Resolution packet */
570 #define ARPOP_REQUEST 1 /* ARP request */
571 #define ARPOP_REPLY 2 /* ARP reply */
575 unsigned char h_dest
[ETH_ALEN
]; /* destination eth addr */
576 unsigned char h_source
[ETH_ALEN
]; /* source ether addr */
577 unsigned short h_proto
; /* packet type ID field */
582 unsigned short ar_hrd
; /* format of hardware address */
583 unsigned short ar_pro
; /* format of protocol address */
584 unsigned char ar_hln
; /* length of hardware address */
585 unsigned char ar_pln
; /* length of protocol address */
586 unsigned short ar_op
; /* ARP opcode (command) */
589 * Ethernet looks like this : This bit is variable sized however...
591 unsigned char ar_sha
[ETH_ALEN
]; /* sender hardware address */
592 unsigned char ar_sip
[4]; /* sender IP address */
593 unsigned char ar_tha
[ETH_ALEN
]; /* target hardware address */
594 unsigned char ar_tip
[4]; /* target IP address */
597 static void arp_input(const uint8_t *pkt
, int pkt_len
)
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
);
605 struct ex_list
*ex_ptr
;
607 ar_op
= ntohs(ah
->ar_op
);
610 if (!memcmp(ah
->ar_tip
, &special_addr
, 3)) {
611 if (ah
->ar_tip
[3] == CTL_DNS
|| ah
->ar_tip
[3] == CTL_ALIAS
)
613 for (ex_ptr
= exec_list
; ex_ptr
; ex_ptr
= ex_ptr
->ex_next
) {
614 if (ex_ptr
->ex_addr
== ah
->ar_tip
[3])
619 /* XXX: make an ARP request to have the client address */
620 memcpy(client_ethaddr
, eh
->h_source
, ETH_ALEN
);
622 /* ARP request for alias/dns mac address */
623 memcpy(reh
->h_dest
, pkt
+ ETH_ALEN
, ETH_ALEN
);
624 memcpy(reh
->h_source
, special_ethaddr
, ETH_ALEN
- 1);
625 reh
->h_source
[5] = ah
->ar_tip
[3];
626 reh
->h_proto
= htons(ETH_P_ARP
);
628 rah
->ar_hrd
= htons(1);
629 rah
->ar_pro
= htons(ETH_P_IP
);
630 rah
->ar_hln
= ETH_ALEN
;
632 rah
->ar_op
= htons(ARPOP_REPLY
);
633 memcpy(rah
->ar_sha
, reh
->h_source
, ETH_ALEN
);
634 memcpy(rah
->ar_sip
, ah
->ar_tip
, 4);
635 memcpy(rah
->ar_tha
, ah
->ar_sha
, ETH_ALEN
);
636 memcpy(rah
->ar_tip
, ah
->ar_sip
, 4);
637 slirp_output(arp_reply
, sizeof(arp_reply
));
641 /* reply to request of client mac address ? */
642 if (!memcmp(client_ethaddr
, zero_ethaddr
, ETH_ALEN
) &&
643 !memcmp(ah
->ar_sip
, &client_ipaddr
.s_addr
, 4)) {
644 memcpy(client_ethaddr
, ah
->ar_sha
, ETH_ALEN
);
652 void slirp_input(const uint8_t *pkt
, int pkt_len
)
657 if (pkt_len
< ETH_HLEN
)
660 proto
= ntohs(*(uint16_t *)(pkt
+ 12));
663 arp_input(pkt
, pkt_len
);
669 /* Note: we add to align the IP header */
670 if (M_FREEROOM(m
) < pkt_len
+ 2) {
671 m_inc(m
, pkt_len
+ 2);
673 m
->m_len
= pkt_len
+ 2;
674 memcpy(m
->m_data
+ 2, pkt
, pkt_len
);
676 m
->m_data
+= 2 + ETH_HLEN
;
677 m
->m_len
-= 2 + ETH_HLEN
;
686 /* output the IP packet to the ethernet device */
687 void if_encap(const uint8_t *ip_data
, int ip_data_len
)
690 struct ethhdr
*eh
= (struct ethhdr
*)buf
;
692 if (ip_data_len
+ ETH_HLEN
> sizeof(buf
))
695 if (!memcmp(client_ethaddr
, zero_ethaddr
, ETH_ALEN
)) {
696 uint8_t arp_req
[ETH_HLEN
+ sizeof(struct arphdr
)];
697 struct ethhdr
*reh
= (struct ethhdr
*)arp_req
;
698 struct arphdr
*rah
= (struct arphdr
*)(arp_req
+ ETH_HLEN
);
699 const struct ip
*iph
= (const struct ip
*)ip_data
;
701 /* If the client addr is not known, there is no point in
702 sending the packet to it. Normally the sender should have
703 done an ARP request to get its MAC address. Here we do it
704 in place of sending the packet and we hope that the sender
705 will retry sending its packet. */
706 memset(reh
->h_dest
, 0xff, ETH_ALEN
);
707 memcpy(reh
->h_source
, special_ethaddr
, ETH_ALEN
- 1);
708 reh
->h_source
[5] = CTL_ALIAS
;
709 reh
->h_proto
= htons(ETH_P_ARP
);
710 rah
->ar_hrd
= htons(1);
711 rah
->ar_pro
= htons(ETH_P_IP
);
712 rah
->ar_hln
= ETH_ALEN
;
714 rah
->ar_op
= htons(ARPOP_REQUEST
);
716 memcpy(rah
->ar_sha
, special_ethaddr
, ETH_ALEN
- 1);
717 rah
->ar_sha
[5] = CTL_ALIAS
;
719 memcpy(rah
->ar_sip
, &alias_addr
, 4);
720 /* target hw addr (none) */
721 memset(rah
->ar_tha
, 0, ETH_ALEN
);
723 memcpy(rah
->ar_tip
, &iph
->ip_dst
, 4);
724 client_ipaddr
= iph
->ip_dst
;
725 slirp_output(arp_req
, sizeof(arp_req
));
727 memcpy(eh
->h_dest
, client_ethaddr
, ETH_ALEN
);
728 memcpy(eh
->h_source
, special_ethaddr
, ETH_ALEN
- 1);
729 /* XXX: not correct */
730 eh
->h_source
[5] = CTL_ALIAS
;
731 eh
->h_proto
= htons(ETH_P_IP
);
732 memcpy(buf
+ sizeof(struct ethhdr
), ip_data
, ip_data_len
);
733 slirp_output(buf
, ip_data_len
+ ETH_HLEN
);
737 /* Unlistens a redirection
739 * Return value: number of redirs removed */
740 int slirp_redir_rm(int is_udp
, int host_port
)
743 struct socket
*head
= (is_udp
? &udb
: &tcb
);
744 int fport
= htons(host_port
);
748 for (so
= head
->so_next
; so
!= head
; so
= so
->so_next
) {
749 if (so
->so_fport
== fport
) {
760 int slirp_redir(int is_udp
, int host_port
,
761 struct in_addr guest_addr
, int guest_port
)
764 if (!udp_listen(htons(host_port
), guest_addr
.s_addr
,
765 htons(guest_port
), 0))
768 if (!solisten(htons(host_port
), guest_addr
.s_addr
,
769 htons(guest_port
), 0))
775 int slirp_add_exec(int do_pty
, const void *args
, int addr_low_byte
,
778 return add_exec(&exec_list
, do_pty
, (char *)args
,
779 addr_low_byte
, htons(guest_port
));
782 ssize_t
slirp_send(struct socket
*so
, const void *buf
, size_t len
, int flags
)
784 if (so
->s
== -1 && so
->extra
) {
785 qemu_chr_write(so
->extra
, buf
, len
);
789 return send(so
->s
, buf
, len
, flags
);
792 static struct socket
*slirp_find_ctl_socket(int addr_low_byte
, int guest_port
)
796 for (so
= tcb
.so_next
; so
!= &tcb
; so
= so
->so_next
) {
797 if ((so
->so_faddr
.s_addr
& htonl(0xffffff00)) ==
799 && (ntohl(so
->so_faddr
.s_addr
) & 0xff) ==
801 && htons(so
->so_fport
) == guest_port
)
808 size_t slirp_socket_can_recv(int addr_low_byte
, int guest_port
)
816 so
= slirp_find_ctl_socket(addr_low_byte
, guest_port
);
818 if (!so
|| so
->so_state
& SS_NOFDREF
)
821 if (!CONN_CANFRCV(so
) || so
->so_snd
.sb_cc
>= (so
->so_snd
.sb_datalen
/2))
824 return sopreprbuf(so
, iov
, NULL
);
827 void slirp_socket_recv(int addr_low_byte
, int guest_port
, const uint8_t *buf
,
831 struct socket
*so
= slirp_find_ctl_socket(addr_low_byte
, guest_port
);
836 ret
= soreadbuf(so
, (const char *)buf
, size
);
839 tcp_output(sototcpcb(so
));
842 static void slirp_tcp_save(QEMUFile
*f
, struct tcpcb
*tp
)
846 qemu_put_sbe16(f
, tp
->t_state
);
847 for (i
= 0; i
< TCPT_NTIMERS
; i
++)
848 qemu_put_sbe16(f
, tp
->t_timer
[i
]);
849 qemu_put_sbe16(f
, tp
->t_rxtshift
);
850 qemu_put_sbe16(f
, tp
->t_rxtcur
);
851 qemu_put_sbe16(f
, tp
->t_dupacks
);
852 qemu_put_be16(f
, tp
->t_maxseg
);
853 qemu_put_sbyte(f
, tp
->t_force
);
854 qemu_put_be16(f
, tp
->t_flags
);
855 qemu_put_be32(f
, tp
->snd_una
);
856 qemu_put_be32(f
, tp
->snd_nxt
);
857 qemu_put_be32(f
, tp
->snd_up
);
858 qemu_put_be32(f
, tp
->snd_wl1
);
859 qemu_put_be32(f
, tp
->snd_wl2
);
860 qemu_put_be32(f
, tp
->iss
);
861 qemu_put_be32(f
, tp
->snd_wnd
);
862 qemu_put_be32(f
, tp
->rcv_wnd
);
863 qemu_put_be32(f
, tp
->rcv_nxt
);
864 qemu_put_be32(f
, tp
->rcv_up
);
865 qemu_put_be32(f
, tp
->irs
);
866 qemu_put_be32(f
, tp
->rcv_adv
);
867 qemu_put_be32(f
, tp
->snd_max
);
868 qemu_put_be32(f
, tp
->snd_cwnd
);
869 qemu_put_be32(f
, tp
->snd_ssthresh
);
870 qemu_put_sbe16(f
, tp
->t_idle
);
871 qemu_put_sbe16(f
, tp
->t_rtt
);
872 qemu_put_be32(f
, tp
->t_rtseq
);
873 qemu_put_sbe16(f
, tp
->t_srtt
);
874 qemu_put_sbe16(f
, tp
->t_rttvar
);
875 qemu_put_be16(f
, tp
->t_rttmin
);
876 qemu_put_be32(f
, tp
->max_sndwnd
);
877 qemu_put_byte(f
, tp
->t_oobflags
);
878 qemu_put_byte(f
, tp
->t_iobc
);
879 qemu_put_sbe16(f
, tp
->t_softerror
);
880 qemu_put_byte(f
, tp
->snd_scale
);
881 qemu_put_byte(f
, tp
->rcv_scale
);
882 qemu_put_byte(f
, tp
->request_r_scale
);
883 qemu_put_byte(f
, tp
->requested_s_scale
);
884 qemu_put_be32(f
, tp
->ts_recent
);
885 qemu_put_be32(f
, tp
->ts_recent_age
);
886 qemu_put_be32(f
, tp
->last_ack_sent
);
889 static void slirp_sbuf_save(QEMUFile
*f
, struct sbuf
*sbuf
)
893 qemu_put_be32(f
, sbuf
->sb_cc
);
894 qemu_put_be32(f
, sbuf
->sb_datalen
);
895 off
= (uint32_t)(sbuf
->sb_wptr
- sbuf
->sb_data
);
896 qemu_put_sbe32(f
, off
);
897 off
= (uint32_t)(sbuf
->sb_rptr
- sbuf
->sb_data
);
898 qemu_put_sbe32(f
, off
);
899 qemu_put_buffer(f
, (unsigned char*)sbuf
->sb_data
, sbuf
->sb_datalen
);
902 static void slirp_socket_save(QEMUFile
*f
, struct socket
*so
)
904 qemu_put_be32(f
, so
->so_urgc
);
905 qemu_put_be32(f
, so
->so_faddr
.s_addr
);
906 qemu_put_be32(f
, so
->so_laddr
.s_addr
);
907 qemu_put_be16(f
, so
->so_fport
);
908 qemu_put_be16(f
, so
->so_lport
);
909 qemu_put_byte(f
, so
->so_iptos
);
910 qemu_put_byte(f
, so
->so_emu
);
911 qemu_put_byte(f
, so
->so_type
);
912 qemu_put_be32(f
, so
->so_state
);
913 slirp_sbuf_save(f
, &so
->so_rcv
);
914 slirp_sbuf_save(f
, &so
->so_snd
);
915 slirp_tcp_save(f
, so
->so_tcpcb
);
918 static void slirp_state_save(QEMUFile
*f
, void *opaque
)
920 struct ex_list
*ex_ptr
;
922 for (ex_ptr
= exec_list
; ex_ptr
; ex_ptr
= ex_ptr
->ex_next
)
923 if (ex_ptr
->ex_pty
== 3) {
925 so
= slirp_find_ctl_socket(ex_ptr
->ex_addr
, ntohs(ex_ptr
->ex_fport
));
929 qemu_put_byte(f
, 42);
930 slirp_socket_save(f
, so
);
935 static void slirp_tcp_load(QEMUFile
*f
, struct tcpcb
*tp
)
939 tp
->t_state
= qemu_get_sbe16(f
);
940 for (i
= 0; i
< TCPT_NTIMERS
; i
++)
941 tp
->t_timer
[i
] = qemu_get_sbe16(f
);
942 tp
->t_rxtshift
= qemu_get_sbe16(f
);
943 tp
->t_rxtcur
= qemu_get_sbe16(f
);
944 tp
->t_dupacks
= qemu_get_sbe16(f
);
945 tp
->t_maxseg
= qemu_get_be16(f
);
946 tp
->t_force
= qemu_get_sbyte(f
);
947 tp
->t_flags
= qemu_get_be16(f
);
948 tp
->snd_una
= qemu_get_be32(f
);
949 tp
->snd_nxt
= qemu_get_be32(f
);
950 tp
->snd_up
= qemu_get_be32(f
);
951 tp
->snd_wl1
= qemu_get_be32(f
);
952 tp
->snd_wl2
= qemu_get_be32(f
);
953 tp
->iss
= qemu_get_be32(f
);
954 tp
->snd_wnd
= qemu_get_be32(f
);
955 tp
->rcv_wnd
= qemu_get_be32(f
);
956 tp
->rcv_nxt
= qemu_get_be32(f
);
957 tp
->rcv_up
= qemu_get_be32(f
);
958 tp
->irs
= qemu_get_be32(f
);
959 tp
->rcv_adv
= qemu_get_be32(f
);
960 tp
->snd_max
= qemu_get_be32(f
);
961 tp
->snd_cwnd
= qemu_get_be32(f
);
962 tp
->snd_ssthresh
= qemu_get_be32(f
);
963 tp
->t_idle
= qemu_get_sbe16(f
);
964 tp
->t_rtt
= qemu_get_sbe16(f
);
965 tp
->t_rtseq
= qemu_get_be32(f
);
966 tp
->t_srtt
= qemu_get_sbe16(f
);
967 tp
->t_rttvar
= qemu_get_sbe16(f
);
968 tp
->t_rttmin
= qemu_get_be16(f
);
969 tp
->max_sndwnd
= qemu_get_be32(f
);
970 tp
->t_oobflags
= qemu_get_byte(f
);
971 tp
->t_iobc
= qemu_get_byte(f
);
972 tp
->t_softerror
= qemu_get_sbe16(f
);
973 tp
->snd_scale
= qemu_get_byte(f
);
974 tp
->rcv_scale
= qemu_get_byte(f
);
975 tp
->request_r_scale
= qemu_get_byte(f
);
976 tp
->requested_s_scale
= qemu_get_byte(f
);
977 tp
->ts_recent
= qemu_get_be32(f
);
978 tp
->ts_recent_age
= qemu_get_be32(f
);
979 tp
->last_ack_sent
= qemu_get_be32(f
);
983 static int slirp_sbuf_load(QEMUFile
*f
, struct sbuf
*sbuf
)
985 uint32_t off
, sb_cc
, sb_datalen
;
987 sb_cc
= qemu_get_be32(f
);
988 sb_datalen
= qemu_get_be32(f
);
990 sbreserve(sbuf
, sb_datalen
);
992 if (sbuf
->sb_datalen
!= sb_datalen
)
997 off
= qemu_get_sbe32(f
);
998 sbuf
->sb_wptr
= sbuf
->sb_data
+ off
;
999 off
= qemu_get_sbe32(f
);
1000 sbuf
->sb_rptr
= sbuf
->sb_data
+ off
;
1001 qemu_get_buffer(f
, (unsigned char*)sbuf
->sb_data
, sbuf
->sb_datalen
);
1006 static int slirp_socket_load(QEMUFile
*f
, struct socket
*so
)
1008 if (tcp_attach(so
) < 0)
1011 so
->so_urgc
= qemu_get_be32(f
);
1012 so
->so_faddr
.s_addr
= qemu_get_be32(f
);
1013 so
->so_laddr
.s_addr
= qemu_get_be32(f
);
1014 so
->so_fport
= qemu_get_be16(f
);
1015 so
->so_lport
= qemu_get_be16(f
);
1016 so
->so_iptos
= qemu_get_byte(f
);
1017 so
->so_emu
= qemu_get_byte(f
);
1018 so
->so_type
= qemu_get_byte(f
);
1019 so
->so_state
= qemu_get_be32(f
);
1020 if (slirp_sbuf_load(f
, &so
->so_rcv
) < 0)
1022 if (slirp_sbuf_load(f
, &so
->so_snd
) < 0)
1024 slirp_tcp_load(f
, so
->so_tcpcb
);
1029 static int slirp_state_load(QEMUFile
*f
, void *opaque
, int version_id
)
1031 struct ex_list
*ex_ptr
;
1034 while ((r
= qemu_get_byte(f
))) {
1036 struct socket
*so
= socreate();
1041 ret
= slirp_socket_load(f
, so
);
1046 if ((so
->so_faddr
.s_addr
& htonl(0xffffff00)) != special_addr
.s_addr
)
1049 for (ex_ptr
= exec_list
; ex_ptr
; ex_ptr
= ex_ptr
->ex_next
)
1050 if (ex_ptr
->ex_pty
== 3 &&
1051 (ntohl(so
->so_faddr
.s_addr
) & 0xff) == ex_ptr
->ex_addr
&&
1052 so
->so_fport
== ex_ptr
->ex_fport
)
1058 so
->extra
= (void *)ex_ptr
->ex_exec
;