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 /* virtual network configuration */
37 struct in_addr vnetwork_addr
;
38 struct in_addr vnetwork_mask
;
39 struct in_addr vhost_addr
;
40 struct in_addr vdhcp_startaddr
;
41 struct in_addr vnameserver_addr
;
43 /* emulated hosts use the MAC addr 52:55:IP:IP:IP:IP */
44 static const uint8_t special_ethaddr
[6] = {
45 0x52, 0x55, 0x00, 0x00, 0x00, 0x00
48 /* ARP cache for the guest IP addresses (XXX: allow many entries) */
49 uint8_t client_ethaddr
[6];
50 static struct in_addr client_ipaddr
;
52 static const uint8_t zero_ethaddr
[6] = { 0, 0, 0, 0, 0, 0 };
55 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 GlobalFree(FixedInfo
);
104 static void winsock_cleanup(void)
111 static int get_dns_addr(struct in_addr
*pdns_addr
)
117 struct in_addr tmp_addr
;
119 f
= fopen("/etc/resolv.conf", "r");
124 lprint("IP address of your DNS(s): ");
126 while (fgets(buff
, 512, f
) != NULL
) {
127 if (sscanf(buff
, "nameserver%*[ \t]%256s", buff2
) == 1) {
128 if (!inet_aton(buff2
, &tmp_addr
))
130 if (tmp_addr
.s_addr
== loopback_addr
.s_addr
)
132 /* If it's the first one, set it to dns_addr */
134 *pdns_addr
= tmp_addr
;
147 lprint("%s", inet_ntoa(tmp_addr
));
159 static void slirp_init_once(void)
161 static int initialized
;
174 WSAStartup(MAKEWORD(2,0), &Data
);
175 atexit(winsock_cleanup
);
178 loopback_addr
.s_addr
= htonl(INADDR_LOOPBACK
);
180 /* FIXME: This address may change during runtime */
181 if (gethostname(our_name
, sizeof(our_name
)) == 0) {
182 he
= gethostbyname(our_name
);
184 our_addr
= *(struct in_addr
*)he
->h_addr
;
187 if (our_addr
.s_addr
== 0) {
188 our_addr
= loopback_addr
;
191 /* FIXME: This address may change during runtime */
192 if (get_dns_addr(&dns_addr
) < 0) {
193 dns_addr
= loopback_addr
;
197 static void slirp_state_save(QEMUFile
*f
, void *opaque
);
198 static int slirp_state_load(QEMUFile
*f
, void *opaque
, int version_id
);
200 void slirp_init(int restricted
, struct in_addr vnetwork
,
201 struct in_addr vnetmask
, struct in_addr vhost
,
202 const char *vhostname
, const char *tftp_path
,
203 const char *bootfile
, struct in_addr vdhcp_start
,
204 struct in_addr vnameserver
)
209 slirp_restrict
= restricted
;
214 /* Initialise mbufs *after* setting the MTU */
217 vnetwork_addr
= vnetwork
;
218 vnetwork_mask
= vnetmask
;
221 pstrcpy(slirp_hostname
, sizeof(slirp_hostname
), vhostname
);
223 qemu_free(tftp_prefix
);
226 tftp_prefix
= qemu_strdup(tftp_path
);
228 qemu_free(bootp_filename
);
229 bootp_filename
= NULL
;
231 bootp_filename
= qemu_strdup(bootfile
);
233 vdhcp_startaddr
= vdhcp_start
;
234 vnameserver_addr
= vnameserver
;
236 register_savevm("slirp", 0, 2, slirp_state_save
, slirp_state_load
, NULL
);
239 #define CONN_CANFSEND(so) (((so)->so_state & (SS_FCANTSENDMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED)
240 #define CONN_CANFRCV(so) (((so)->so_state & (SS_FCANTRCVMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED)
241 #define UPD_NFDS(x) if (nfds < (x)) nfds = (x)
244 * curtime kept to an accuracy of 1ms
247 static void updtime(void)
253 curtime
= tb
.time
* 1000 + tb
.millitm
;
256 static void updtime(void)
260 gettimeofday(&tv
, NULL
);
262 curtime
= tv
.tv_sec
* 1000 + tv
.tv_usec
/ 1000;
266 void slirp_select_fill(int *pnfds
,
267 fd_set
*readfds
, fd_set
*writefds
, fd_set
*xfds
)
269 struct socket
*so
, *so_next
;
270 struct timeval timeout
;
279 global_readfds
= NULL
;
280 global_writefds
= NULL
;
290 * *_slowtimo needs calling if there are IP fragments
291 * in the fragment queue, or there are TCP connections active
293 do_slowtimo
= ((tcb
.so_next
!= &tcb
) ||
294 (&ipq
.ip_link
!= ipq
.ip_link
.next
));
296 for (so
= tcb
.so_next
; so
!= &tcb
; so
= so_next
) {
297 so_next
= so
->so_next
;
300 * See if we need a tcp_fasttimo
302 if (time_fasttimo
== 0 && so
->so_tcpcb
->t_flags
& TF_DELACK
)
303 time_fasttimo
= curtime
; /* Flag when we want a fasttimo */
306 * NOFDREF can include still connecting to local-host,
307 * newly socreated() sockets etc. Don't want to select these.
309 if (so
->so_state
& SS_NOFDREF
|| so
->s
== -1)
313 * Set for reading sockets which are accepting
315 if (so
->so_state
& SS_FACCEPTCONN
) {
316 FD_SET(so
->s
, readfds
);
322 * Set for writing sockets which are connecting
324 if (so
->so_state
& SS_ISFCONNECTING
) {
325 FD_SET(so
->s
, writefds
);
331 * Set for writing if we are connected, can send more, and
332 * we have something to send
334 if (CONN_CANFSEND(so
) && so
->so_rcv
.sb_cc
) {
335 FD_SET(so
->s
, writefds
);
340 * Set for reading (and urgent data) if we are connected, can
341 * receive more, and we have room for it XXX /2 ?
343 if (CONN_CANFRCV(so
) && (so
->so_snd
.sb_cc
< (so
->so_snd
.sb_datalen
/2))) {
344 FD_SET(so
->s
, readfds
);
353 for (so
= udb
.so_next
; so
!= &udb
; so
= so_next
) {
354 so_next
= so
->so_next
;
357 * See if it's timed out
360 if (so
->so_expire
<= curtime
) {
364 do_slowtimo
= 1; /* Let socket expire */
368 * When UDP packets are received from over the
369 * link, they're sendto()'d straight away, so
370 * no need for setting for writing
371 * Limit the number of packets queued by this session
372 * to 4. Note that even though we try and limit this
373 * to 4 packets, the session could have more queued
374 * if the packets needed to be fragmented
377 if ((so
->so_state
& SS_ISFCONNECTED
) && so
->so_queued
<= 4) {
378 FD_SET(so
->s
, readfds
);
384 * Setup timeout to use minimum CPU usage, especially when idle
388 * First, see the timeout needed by *timo
391 timeout
.tv_usec
= -1;
393 * If a slowtimo is needed, set timeout to 500ms from the last
394 * slow timeout. If a fast timeout is needed, set timeout within
395 * 200ms of when it was requested.
398 /* XXX + 10000 because some select()'s aren't that accurate */
399 timeout
.tv_usec
= ((500 - (curtime
- last_slowtimo
)) * 1000) + 10000;
400 if (timeout
.tv_usec
< 0)
402 else if (timeout
.tv_usec
> 510000)
403 timeout
.tv_usec
= 510000;
405 /* Can only fasttimo if we also slowtimo */
407 tmp_time
= (200 - (curtime
- time_fasttimo
)) * 1000;
411 /* Choose the smallest of the 2 */
412 if (tmp_time
< timeout
.tv_usec
)
413 timeout
.tv_usec
= (u_int
)tmp_time
;
419 void slirp_select_poll(fd_set
*readfds
, fd_set
*writefds
, fd_set
*xfds
,
422 struct socket
*so
, *so_next
;
429 global_readfds
= readfds
;
430 global_writefds
= writefds
;
437 * See if anything has timed out
439 if (time_fasttimo
&& ((curtime
- time_fasttimo
) >= 2)) {
443 if (do_slowtimo
&& ((curtime
- last_slowtimo
) >= 499)) {
446 last_slowtimo
= curtime
;
456 for (so
= tcb
.so_next
; so
!= &tcb
; so
= so_next
) {
457 so_next
= so
->so_next
;
460 * FD_ISSET is meaningless on these sockets
461 * (and they can crash the program)
463 if (so
->so_state
& SS_NOFDREF
|| so
->s
== -1)
468 * This will soread as well, so no need to
469 * test for readfds below if this succeeds
471 if (FD_ISSET(so
->s
, xfds
))
474 * Check sockets for reading
476 else if (FD_ISSET(so
->s
, readfds
)) {
478 * Check for incoming connections
480 if (so
->so_state
& SS_FACCEPTCONN
) {
486 /* Output it if we read something */
488 tcp_output(sototcpcb(so
));
492 * Check sockets for writing
494 if (FD_ISSET(so
->s
, writefds
)) {
496 * Check for non-blocking, still-connecting sockets
498 if (so
->so_state
& SS_ISFCONNECTING
) {
500 so
->so_state
&= ~SS_ISFCONNECTING
;
502 ret
= send(so
->s
, (const void *) &ret
, 0, 0);
504 /* XXXXX Must fix, zero bytes is a NOP */
505 if (errno
== EAGAIN
|| errno
== EWOULDBLOCK
||
506 errno
== EINPROGRESS
|| errno
== ENOTCONN
)
510 so
->so_state
&= SS_PERSISTENT_MASK
;
511 so
->so_state
|= SS_NOFDREF
;
513 /* else so->so_state &= ~SS_ISFCONNECTING; */
518 tcp_input((struct mbuf
*)NULL
, sizeof(struct ip
), so
);
523 * XXXXX If we wrote something (a lot), there
524 * could be a need for a window update.
525 * In the worst case, the remote will send
526 * a window probe to get things going again
531 * Probe a still-connecting, non-blocking socket
532 * to check if it's still alive
535 if (so
->so_state
& SS_ISFCONNECTING
) {
536 ret
= recv(so
->s
, (char *)&ret
, 0,0);
540 if (errno
== EAGAIN
|| errno
== EWOULDBLOCK
||
541 errno
== EINPROGRESS
|| errno
== ENOTCONN
)
542 continue; /* Still connecting, continue */
545 so
->so_state
&= SS_PERSISTENT_MASK
;
546 so
->so_state
|= SS_NOFDREF
;
548 /* tcp_input will take care of it */
550 ret
= send(so
->s
, &ret
, 0,0);
553 if (errno
== EAGAIN
|| errno
== EWOULDBLOCK
||
554 errno
== EINPROGRESS
|| errno
== ENOTCONN
)
557 so
->so_state
&= SS_PERSISTENT_MASK
;
558 so
->so_state
|= SS_NOFDREF
;
560 so
->so_state
&= ~SS_ISFCONNECTING
;
563 tcp_input((struct mbuf
*)NULL
, sizeof(struct ip
),so
);
564 } /* SS_ISFCONNECTING */
570 * Incoming packets are sent straight away, they're not buffered.
571 * Incoming UDP data isn't buffered either.
573 for (so
= udb
.so_next
; so
!= &udb
; so
= so_next
) {
574 so_next
= so
->so_next
;
576 if (so
->s
!= -1 && FD_ISSET(so
->s
, readfds
)) {
583 * See if we can start outputting
588 /* clear global file descriptor sets.
589 * these reside on the stack in vl.c
590 * so they're unusable if we're not in
591 * slirp_select_fill or slirp_select_poll.
593 global_readfds
= NULL
;
594 global_writefds
= NULL
;
601 #define ETH_P_IP 0x0800 /* Internet Protocol packet */
602 #define ETH_P_ARP 0x0806 /* Address Resolution packet */
604 #define ARPOP_REQUEST 1 /* ARP request */
605 #define ARPOP_REPLY 2 /* ARP reply */
609 unsigned char h_dest
[ETH_ALEN
]; /* destination eth addr */
610 unsigned char h_source
[ETH_ALEN
]; /* source ether addr */
611 unsigned short h_proto
; /* packet type ID field */
616 unsigned short ar_hrd
; /* format of hardware address */
617 unsigned short ar_pro
; /* format of protocol address */
618 unsigned char ar_hln
; /* length of hardware address */
619 unsigned char ar_pln
; /* length of protocol address */
620 unsigned short ar_op
; /* ARP opcode (command) */
623 * Ethernet looks like this : This bit is variable sized however...
625 unsigned char ar_sha
[ETH_ALEN
]; /* sender hardware address */
626 uint32_t ar_sip
; /* sender IP address */
627 unsigned char ar_tha
[ETH_ALEN
]; /* target hardware address */
628 uint32_t ar_tip
; /* target IP address */
629 } __attribute__((packed
));
631 static void arp_input(const uint8_t *pkt
, int pkt_len
)
633 struct ethhdr
*eh
= (struct ethhdr
*)pkt
;
634 struct arphdr
*ah
= (struct arphdr
*)(pkt
+ ETH_HLEN
);
635 uint8_t arp_reply
[ETH_HLEN
+ sizeof(struct arphdr
)];
636 struct ethhdr
*reh
= (struct ethhdr
*)arp_reply
;
637 struct arphdr
*rah
= (struct arphdr
*)(arp_reply
+ ETH_HLEN
);
639 struct ex_list
*ex_ptr
;
641 ar_op
= ntohs(ah
->ar_op
);
644 if ((ah
->ar_tip
& vnetwork_mask
.s_addr
) == vnetwork_addr
.s_addr
) {
645 if (ah
->ar_tip
== vnameserver_addr
.s_addr
||
646 ah
->ar_tip
== vhost_addr
.s_addr
)
648 for (ex_ptr
= exec_list
; ex_ptr
; ex_ptr
= ex_ptr
->ex_next
) {
649 if (ex_ptr
->ex_addr
.s_addr
== ah
->ar_tip
)
654 /* XXX: make an ARP request to have the client address */
655 memcpy(client_ethaddr
, eh
->h_source
, ETH_ALEN
);
657 /* ARP request for alias/dns mac address */
658 memcpy(reh
->h_dest
, pkt
+ ETH_ALEN
, ETH_ALEN
);
659 memcpy(reh
->h_source
, special_ethaddr
, ETH_ALEN
- 4);
660 memcpy(&reh
->h_source
[2], &ah
->ar_tip
, 4);
661 reh
->h_proto
= htons(ETH_P_ARP
);
663 rah
->ar_hrd
= htons(1);
664 rah
->ar_pro
= htons(ETH_P_IP
);
665 rah
->ar_hln
= ETH_ALEN
;
667 rah
->ar_op
= htons(ARPOP_REPLY
);
668 memcpy(rah
->ar_sha
, reh
->h_source
, ETH_ALEN
);
669 rah
->ar_sip
= ah
->ar_tip
;
670 memcpy(rah
->ar_tha
, ah
->ar_sha
, ETH_ALEN
);
671 rah
->ar_tip
= ah
->ar_sip
;
672 slirp_output(arp_reply
, sizeof(arp_reply
));
676 /* reply to request of client mac address ? */
677 if (!memcmp(client_ethaddr
, zero_ethaddr
, ETH_ALEN
) &&
678 ah
->ar_sip
== client_ipaddr
.s_addr
) {
679 memcpy(client_ethaddr
, ah
->ar_sha
, ETH_ALEN
);
687 void slirp_input(const uint8_t *pkt
, int pkt_len
)
692 if (pkt_len
< ETH_HLEN
)
695 proto
= ntohs(*(uint16_t *)(pkt
+ 12));
698 arp_input(pkt
, pkt_len
);
704 /* Note: we add to align the IP header */
705 if (M_FREEROOM(m
) < pkt_len
+ 2) {
706 m_inc(m
, pkt_len
+ 2);
708 m
->m_len
= pkt_len
+ 2;
709 memcpy(m
->m_data
+ 2, pkt
, pkt_len
);
711 m
->m_data
+= 2 + ETH_HLEN
;
712 m
->m_len
-= 2 + ETH_HLEN
;
721 /* output the IP packet to the ethernet device */
722 void if_encap(const uint8_t *ip_data
, int ip_data_len
)
725 struct ethhdr
*eh
= (struct ethhdr
*)buf
;
727 if (ip_data_len
+ ETH_HLEN
> sizeof(buf
))
730 if (!memcmp(client_ethaddr
, zero_ethaddr
, ETH_ALEN
)) {
731 uint8_t arp_req
[ETH_HLEN
+ sizeof(struct arphdr
)];
732 struct ethhdr
*reh
= (struct ethhdr
*)arp_req
;
733 struct arphdr
*rah
= (struct arphdr
*)(arp_req
+ ETH_HLEN
);
734 const struct ip
*iph
= (const struct ip
*)ip_data
;
736 /* If the client addr is not known, there is no point in
737 sending the packet to it. Normally the sender should have
738 done an ARP request to get its MAC address. Here we do it
739 in place of sending the packet and we hope that the sender
740 will retry sending its packet. */
741 memset(reh
->h_dest
, 0xff, ETH_ALEN
);
742 memcpy(reh
->h_source
, special_ethaddr
, ETH_ALEN
- 4);
743 memcpy(&reh
->h_source
[2], &vhost_addr
, 4);
744 reh
->h_proto
= htons(ETH_P_ARP
);
745 rah
->ar_hrd
= htons(1);
746 rah
->ar_pro
= htons(ETH_P_IP
);
747 rah
->ar_hln
= ETH_ALEN
;
749 rah
->ar_op
= htons(ARPOP_REQUEST
);
751 memcpy(rah
->ar_sha
, special_ethaddr
, ETH_ALEN
- 4);
752 memcpy(&rah
->ar_sha
[2], &vhost_addr
, 4);
754 rah
->ar_sip
= vhost_addr
.s_addr
;
755 /* target hw addr (none) */
756 memset(rah
->ar_tha
, 0, ETH_ALEN
);
758 rah
->ar_tip
= iph
->ip_dst
.s_addr
;
759 client_ipaddr
= iph
->ip_dst
;
760 slirp_output(arp_req
, sizeof(arp_req
));
762 memcpy(eh
->h_dest
, client_ethaddr
, ETH_ALEN
);
763 memcpy(eh
->h_source
, special_ethaddr
, ETH_ALEN
- 4);
764 /* XXX: not correct */
765 memcpy(&eh
->h_source
[2], &vhost_addr
, 4);
766 eh
->h_proto
= htons(ETH_P_IP
);
767 memcpy(buf
+ sizeof(struct ethhdr
), ip_data
, ip_data_len
);
768 slirp_output(buf
, ip_data_len
+ ETH_HLEN
);
772 /* Drop host forwarding rule, return 0 if found. */
773 int slirp_remove_hostfwd(int is_udp
, struct in_addr host_addr
, int host_port
)
776 struct socket
*head
= (is_udp
? &udb
: &tcb
);
777 struct sockaddr_in addr
;
778 int port
= htons(host_port
);
781 for (so
= head
->so_next
; so
!= head
; so
= so
->so_next
) {
782 addr_len
= sizeof(addr
);
783 if ((so
->so_state
& SS_HOSTFWD
) &&
784 getsockname(so
->s
, (struct sockaddr
*)&addr
, &addr_len
) == 0 &&
785 addr
.sin_addr
.s_addr
== host_addr
.s_addr
&&
786 addr
.sin_port
== port
) {
796 int slirp_add_hostfwd(int is_udp
, struct in_addr host_addr
, int host_port
,
797 struct in_addr guest_addr
, int guest_port
)
799 if (!guest_addr
.s_addr
) {
800 guest_addr
= vdhcp_startaddr
;
803 if (!udp_listen(host_addr
.s_addr
, htons(host_port
), guest_addr
.s_addr
,
804 htons(guest_port
), SS_HOSTFWD
))
807 if (!tcp_listen(host_addr
.s_addr
, htons(host_port
), guest_addr
.s_addr
,
808 htons(guest_port
), SS_HOSTFWD
))
814 int slirp_add_exec(int do_pty
, const void *args
, struct in_addr guest_addr
,
817 if (!guest_addr
.s_addr
) {
819 vnetwork_addr
.s_addr
| (htonl(0x0204) & ~vnetwork_mask
.s_addr
);
821 if ((guest_addr
.s_addr
& vnetwork_mask
.s_addr
) != vnetwork_addr
.s_addr
||
822 guest_addr
.s_addr
== vhost_addr
.s_addr
||
823 guest_addr
.s_addr
== vnameserver_addr
.s_addr
) {
826 return add_exec(&exec_list
, do_pty
, (char *)args
, guest_addr
,
830 ssize_t
slirp_send(struct socket
*so
, const void *buf
, size_t len
, int flags
)
832 if (so
->s
== -1 && so
->extra
) {
833 qemu_chr_write(so
->extra
, buf
, len
);
837 return send(so
->s
, buf
, len
, flags
);
840 static struct socket
*
841 slirp_find_ctl_socket(struct in_addr guest_addr
, int guest_port
)
845 for (so
= tcb
.so_next
; so
!= &tcb
; so
= so
->so_next
) {
846 if (so
->so_faddr
.s_addr
== guest_addr
.s_addr
&&
847 htons(so
->so_fport
) == guest_port
) {
854 size_t slirp_socket_can_recv(struct in_addr guest_addr
, int guest_port
)
862 so
= slirp_find_ctl_socket(guest_addr
, guest_port
);
864 if (!so
|| so
->so_state
& SS_NOFDREF
)
867 if (!CONN_CANFRCV(so
) || so
->so_snd
.sb_cc
>= (so
->so_snd
.sb_datalen
/2))
870 return sopreprbuf(so
, iov
, NULL
);
873 void slirp_socket_recv(struct in_addr guest_addr
, int guest_port
,
874 const uint8_t *buf
, int size
)
877 struct socket
*so
= slirp_find_ctl_socket(guest_addr
, guest_port
);
882 ret
= soreadbuf(so
, (const char *)buf
, size
);
885 tcp_output(sototcpcb(so
));
888 static void slirp_tcp_save(QEMUFile
*f
, struct tcpcb
*tp
)
892 qemu_put_sbe16(f
, tp
->t_state
);
893 for (i
= 0; i
< TCPT_NTIMERS
; i
++)
894 qemu_put_sbe16(f
, tp
->t_timer
[i
]);
895 qemu_put_sbe16(f
, tp
->t_rxtshift
);
896 qemu_put_sbe16(f
, tp
->t_rxtcur
);
897 qemu_put_sbe16(f
, tp
->t_dupacks
);
898 qemu_put_be16(f
, tp
->t_maxseg
);
899 qemu_put_sbyte(f
, tp
->t_force
);
900 qemu_put_be16(f
, tp
->t_flags
);
901 qemu_put_be32(f
, tp
->snd_una
);
902 qemu_put_be32(f
, tp
->snd_nxt
);
903 qemu_put_be32(f
, tp
->snd_up
);
904 qemu_put_be32(f
, tp
->snd_wl1
);
905 qemu_put_be32(f
, tp
->snd_wl2
);
906 qemu_put_be32(f
, tp
->iss
);
907 qemu_put_be32(f
, tp
->snd_wnd
);
908 qemu_put_be32(f
, tp
->rcv_wnd
);
909 qemu_put_be32(f
, tp
->rcv_nxt
);
910 qemu_put_be32(f
, tp
->rcv_up
);
911 qemu_put_be32(f
, tp
->irs
);
912 qemu_put_be32(f
, tp
->rcv_adv
);
913 qemu_put_be32(f
, tp
->snd_max
);
914 qemu_put_be32(f
, tp
->snd_cwnd
);
915 qemu_put_be32(f
, tp
->snd_ssthresh
);
916 qemu_put_sbe16(f
, tp
->t_idle
);
917 qemu_put_sbe16(f
, tp
->t_rtt
);
918 qemu_put_be32(f
, tp
->t_rtseq
);
919 qemu_put_sbe16(f
, tp
->t_srtt
);
920 qemu_put_sbe16(f
, tp
->t_rttvar
);
921 qemu_put_be16(f
, tp
->t_rttmin
);
922 qemu_put_be32(f
, tp
->max_sndwnd
);
923 qemu_put_byte(f
, tp
->t_oobflags
);
924 qemu_put_byte(f
, tp
->t_iobc
);
925 qemu_put_sbe16(f
, tp
->t_softerror
);
926 qemu_put_byte(f
, tp
->snd_scale
);
927 qemu_put_byte(f
, tp
->rcv_scale
);
928 qemu_put_byte(f
, tp
->request_r_scale
);
929 qemu_put_byte(f
, tp
->requested_s_scale
);
930 qemu_put_be32(f
, tp
->ts_recent
);
931 qemu_put_be32(f
, tp
->ts_recent_age
);
932 qemu_put_be32(f
, tp
->last_ack_sent
);
935 static void slirp_sbuf_save(QEMUFile
*f
, struct sbuf
*sbuf
)
939 qemu_put_be32(f
, sbuf
->sb_cc
);
940 qemu_put_be32(f
, sbuf
->sb_datalen
);
941 off
= (uint32_t)(sbuf
->sb_wptr
- sbuf
->sb_data
);
942 qemu_put_sbe32(f
, off
);
943 off
= (uint32_t)(sbuf
->sb_rptr
- sbuf
->sb_data
);
944 qemu_put_sbe32(f
, off
);
945 qemu_put_buffer(f
, (unsigned char*)sbuf
->sb_data
, sbuf
->sb_datalen
);
948 static void slirp_socket_save(QEMUFile
*f
, struct socket
*so
)
950 qemu_put_be32(f
, so
->so_urgc
);
951 qemu_put_be32(f
, so
->so_faddr
.s_addr
);
952 qemu_put_be32(f
, so
->so_laddr
.s_addr
);
953 qemu_put_be16(f
, so
->so_fport
);
954 qemu_put_be16(f
, so
->so_lport
);
955 qemu_put_byte(f
, so
->so_iptos
);
956 qemu_put_byte(f
, so
->so_emu
);
957 qemu_put_byte(f
, so
->so_type
);
958 qemu_put_be32(f
, so
->so_state
);
959 slirp_sbuf_save(f
, &so
->so_rcv
);
960 slirp_sbuf_save(f
, &so
->so_snd
);
961 slirp_tcp_save(f
, so
->so_tcpcb
);
964 static void slirp_state_save(QEMUFile
*f
, void *opaque
)
966 struct ex_list
*ex_ptr
;
968 for (ex_ptr
= exec_list
; ex_ptr
; ex_ptr
= ex_ptr
->ex_next
)
969 if (ex_ptr
->ex_pty
== 3) {
971 so
= slirp_find_ctl_socket(ex_ptr
->ex_addr
, ntohs(ex_ptr
->ex_fport
));
975 qemu_put_byte(f
, 42);
976 slirp_socket_save(f
, so
);
980 qemu_put_be16(f
, ip_id
);
983 static void slirp_tcp_load(QEMUFile
*f
, struct tcpcb
*tp
)
987 tp
->t_state
= qemu_get_sbe16(f
);
988 for (i
= 0; i
< TCPT_NTIMERS
; i
++)
989 tp
->t_timer
[i
] = qemu_get_sbe16(f
);
990 tp
->t_rxtshift
= qemu_get_sbe16(f
);
991 tp
->t_rxtcur
= qemu_get_sbe16(f
);
992 tp
->t_dupacks
= qemu_get_sbe16(f
);
993 tp
->t_maxseg
= qemu_get_be16(f
);
994 tp
->t_force
= qemu_get_sbyte(f
);
995 tp
->t_flags
= qemu_get_be16(f
);
996 tp
->snd_una
= qemu_get_be32(f
);
997 tp
->snd_nxt
= qemu_get_be32(f
);
998 tp
->snd_up
= qemu_get_be32(f
);
999 tp
->snd_wl1
= qemu_get_be32(f
);
1000 tp
->snd_wl2
= qemu_get_be32(f
);
1001 tp
->iss
= qemu_get_be32(f
);
1002 tp
->snd_wnd
= qemu_get_be32(f
);
1003 tp
->rcv_wnd
= qemu_get_be32(f
);
1004 tp
->rcv_nxt
= qemu_get_be32(f
);
1005 tp
->rcv_up
= qemu_get_be32(f
);
1006 tp
->irs
= qemu_get_be32(f
);
1007 tp
->rcv_adv
= qemu_get_be32(f
);
1008 tp
->snd_max
= qemu_get_be32(f
);
1009 tp
->snd_cwnd
= qemu_get_be32(f
);
1010 tp
->snd_ssthresh
= qemu_get_be32(f
);
1011 tp
->t_idle
= qemu_get_sbe16(f
);
1012 tp
->t_rtt
= qemu_get_sbe16(f
);
1013 tp
->t_rtseq
= qemu_get_be32(f
);
1014 tp
->t_srtt
= qemu_get_sbe16(f
);
1015 tp
->t_rttvar
= qemu_get_sbe16(f
);
1016 tp
->t_rttmin
= qemu_get_be16(f
);
1017 tp
->max_sndwnd
= qemu_get_be32(f
);
1018 tp
->t_oobflags
= qemu_get_byte(f
);
1019 tp
->t_iobc
= qemu_get_byte(f
);
1020 tp
->t_softerror
= qemu_get_sbe16(f
);
1021 tp
->snd_scale
= qemu_get_byte(f
);
1022 tp
->rcv_scale
= qemu_get_byte(f
);
1023 tp
->request_r_scale
= qemu_get_byte(f
);
1024 tp
->requested_s_scale
= qemu_get_byte(f
);
1025 tp
->ts_recent
= qemu_get_be32(f
);
1026 tp
->ts_recent_age
= qemu_get_be32(f
);
1027 tp
->last_ack_sent
= qemu_get_be32(f
);
1031 static int slirp_sbuf_load(QEMUFile
*f
, struct sbuf
*sbuf
)
1033 uint32_t off
, sb_cc
, sb_datalen
;
1035 sb_cc
= qemu_get_be32(f
);
1036 sb_datalen
= qemu_get_be32(f
);
1038 sbreserve(sbuf
, sb_datalen
);
1040 if (sbuf
->sb_datalen
!= sb_datalen
)
1043 sbuf
->sb_cc
= sb_cc
;
1045 off
= qemu_get_sbe32(f
);
1046 sbuf
->sb_wptr
= sbuf
->sb_data
+ off
;
1047 off
= qemu_get_sbe32(f
);
1048 sbuf
->sb_rptr
= sbuf
->sb_data
+ off
;
1049 qemu_get_buffer(f
, (unsigned char*)sbuf
->sb_data
, sbuf
->sb_datalen
);
1054 static int slirp_socket_load(QEMUFile
*f
, struct socket
*so
)
1056 if (tcp_attach(so
) < 0)
1059 so
->so_urgc
= qemu_get_be32(f
);
1060 so
->so_faddr
.s_addr
= qemu_get_be32(f
);
1061 so
->so_laddr
.s_addr
= qemu_get_be32(f
);
1062 so
->so_fport
= qemu_get_be16(f
);
1063 so
->so_lport
= qemu_get_be16(f
);
1064 so
->so_iptos
= qemu_get_byte(f
);
1065 so
->so_emu
= qemu_get_byte(f
);
1066 so
->so_type
= qemu_get_byte(f
);
1067 so
->so_state
= qemu_get_be32(f
);
1068 if (slirp_sbuf_load(f
, &so
->so_rcv
) < 0)
1070 if (slirp_sbuf_load(f
, &so
->so_snd
) < 0)
1072 slirp_tcp_load(f
, so
->so_tcpcb
);
1077 static int slirp_state_load(QEMUFile
*f
, void *opaque
, int version_id
)
1079 struct ex_list
*ex_ptr
;
1082 while ((r
= qemu_get_byte(f
))) {
1084 struct socket
*so
= socreate();
1089 ret
= slirp_socket_load(f
, so
);
1094 if ((so
->so_faddr
.s_addr
& vnetwork_mask
.s_addr
) !=
1095 vnetwork_addr
.s_addr
) {
1098 for (ex_ptr
= exec_list
; ex_ptr
; ex_ptr
= ex_ptr
->ex_next
) {
1099 if (ex_ptr
->ex_pty
== 3 &&
1100 so
->so_faddr
.s_addr
== ex_ptr
->ex_addr
.s_addr
&&
1101 so
->so_fport
== ex_ptr
->ex_fport
) {
1108 so
->extra
= (void *)ex_ptr
->ex_exec
;
1111 if (version_id
>= 2) {
1112 ip_id
= qemu_get_be16(f
);