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"
31 struct in_addr our_addr
;
32 /* host dns address */
33 struct in_addr dns_addr
;
34 /* host loopback address */
35 struct in_addr loopback_addr
;
37 /* emulated hosts use the MAC addr 52:55:IP:IP:IP:IP */
38 static const uint8_t special_ethaddr
[6] = {
39 0x52, 0x55, 0x00, 0x00, 0x00, 0x00
42 static const uint8_t zero_ethaddr
[6] = { 0, 0, 0, 0, 0, 0 };
44 /* XXX: suppress those select globals */
45 fd_set
*global_readfds
, *global_writefds
, *global_xfds
;
48 static u_int time_fasttimo
, last_slowtimo
;
49 static int do_slowtimo
;
51 static TAILQ_HEAD(slirp_instances
, Slirp
) slirp_instances
=
52 TAILQ_HEAD_INITIALIZER(slirp_instances
);
56 static int get_dns_addr(struct in_addr
*pdns_addr
)
58 FIXED_INFO
*FixedInfo
=NULL
;
61 IP_ADDR_STRING
*pIPAddr
;
62 struct in_addr tmp_addr
;
64 FixedInfo
= (FIXED_INFO
*)GlobalAlloc(GPTR
, sizeof(FIXED_INFO
));
65 BufLen
= sizeof(FIXED_INFO
);
67 if (ERROR_BUFFER_OVERFLOW
== GetNetworkParams(FixedInfo
, &BufLen
)) {
69 GlobalFree(FixedInfo
);
72 FixedInfo
= GlobalAlloc(GPTR
, BufLen
);
75 if ((ret
= GetNetworkParams(FixedInfo
, &BufLen
)) != ERROR_SUCCESS
) {
76 printf("GetNetworkParams failed. ret = %08x\n", (u_int
)ret
);
78 GlobalFree(FixedInfo
);
84 pIPAddr
= &(FixedInfo
->DnsServerList
);
85 inet_aton(pIPAddr
->IpAddress
.String
, &tmp_addr
);
86 *pdns_addr
= tmp_addr
;
88 GlobalFree(FixedInfo
);
94 static void winsock_cleanup(void)
101 static int get_dns_addr(struct in_addr
*pdns_addr
)
107 struct in_addr tmp_addr
;
109 f
= fopen("/etc/resolv.conf", "r");
114 lprint("IP address of your DNS(s): ");
116 while (fgets(buff
, 512, f
) != NULL
) {
117 if (sscanf(buff
, "nameserver%*[ \t]%256s", buff2
) == 1) {
118 if (!inet_aton(buff2
, &tmp_addr
))
120 if (tmp_addr
.s_addr
== loopback_addr
.s_addr
)
122 /* If it's the first one, set it to dns_addr */
124 *pdns_addr
= tmp_addr
;
137 lprint("%s", inet_ntoa(tmp_addr
));
149 static void slirp_init_once(void)
151 static int initialized
;
164 WSAStartup(MAKEWORD(2,0), &Data
);
165 atexit(winsock_cleanup
);
168 loopback_addr
.s_addr
= htonl(INADDR_LOOPBACK
);
170 /* FIXME: This address may change during runtime */
171 if (gethostname(our_name
, sizeof(our_name
)) == 0) {
172 he
= gethostbyname(our_name
);
174 our_addr
= *(struct in_addr
*)he
->h_addr
;
177 if (our_addr
.s_addr
== 0) {
178 our_addr
= loopback_addr
;
181 /* FIXME: This address may change during runtime */
182 if (get_dns_addr(&dns_addr
) < 0) {
183 dns_addr
= loopback_addr
;
187 static void slirp_state_save(QEMUFile
*f
, void *opaque
);
188 static int slirp_state_load(QEMUFile
*f
, void *opaque
, int version_id
);
190 Slirp
*slirp_init(int restricted
, struct in_addr vnetwork
,
191 struct in_addr vnetmask
, struct in_addr vhost
,
192 const char *vhostname
, const char *tftp_path
,
193 const char *bootfile
, struct in_addr vdhcp_start
,
194 struct in_addr vnameserver
, void *opaque
)
196 Slirp
*slirp
= qemu_mallocz(sizeof(Slirp
));
200 slirp
->restricted
= restricted
;
205 /* Initialise mbufs *after* setting the MTU */
208 slirp
->vnetwork_addr
= vnetwork
;
209 slirp
->vnetwork_mask
= vnetmask
;
210 slirp
->vhost_addr
= vhost
;
212 pstrcpy(slirp
->client_hostname
, sizeof(slirp
->client_hostname
),
216 slirp
->tftp_prefix
= qemu_strdup(tftp_path
);
219 slirp
->bootp_filename
= qemu_strdup(bootfile
);
221 slirp
->vdhcp_startaddr
= vdhcp_start
;
222 slirp
->vnameserver_addr
= vnameserver
;
224 slirp
->opaque
= opaque
;
226 register_savevm("slirp", 0, 3, slirp_state_save
, slirp_state_load
, slirp
);
228 TAILQ_INSERT_TAIL(&slirp_instances
, slirp
, entry
);
233 void slirp_cleanup(Slirp
*slirp
)
235 TAILQ_REMOVE(&slirp_instances
, slirp
, entry
);
237 unregister_savevm("slirp", slirp
);
239 qemu_free(slirp
->tftp_prefix
);
240 qemu_free(slirp
->bootp_filename
);
244 #define CONN_CANFSEND(so) (((so)->so_state & (SS_FCANTSENDMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED)
245 #define CONN_CANFRCV(so) (((so)->so_state & (SS_FCANTRCVMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED)
246 #define UPD_NFDS(x) if (nfds < (x)) nfds = (x)
248 void slirp_select_fill(int *pnfds
,
249 fd_set
*readfds
, fd_set
*writefds
, fd_set
*xfds
)
252 struct socket
*so
, *so_next
;
255 if (TAILQ_EMPTY(&slirp_instances
)) {
260 global_readfds
= NULL
;
261 global_writefds
= NULL
;
270 TAILQ_FOREACH(slirp
, &slirp_instances
, entry
) {
272 * *_slowtimo needs calling if there are IP fragments
273 * in the fragment queue, or there are TCP connections active
275 do_slowtimo
|= ((slirp
->tcb
.so_next
!= &slirp
->tcb
) ||
276 (&slirp
->ipq
.ip_link
!= slirp
->ipq
.ip_link
.next
));
278 for (so
= slirp
->tcb
.so_next
; so
!= &slirp
->tcb
;
280 so_next
= so
->so_next
;
283 * See if we need a tcp_fasttimo
285 if (time_fasttimo
== 0 && so
->so_tcpcb
->t_flags
& TF_DELACK
)
286 time_fasttimo
= curtime
; /* Flag when we want a fasttimo */
289 * NOFDREF can include still connecting to local-host,
290 * newly socreated() sockets etc. Don't want to select these.
292 if (so
->so_state
& SS_NOFDREF
|| so
->s
== -1)
296 * Set for reading sockets which are accepting
298 if (so
->so_state
& SS_FACCEPTCONN
) {
299 FD_SET(so
->s
, readfds
);
305 * Set for writing sockets which are connecting
307 if (so
->so_state
& SS_ISFCONNECTING
) {
308 FD_SET(so
->s
, writefds
);
314 * Set for writing if we are connected, can send more, and
315 * we have something to send
317 if (CONN_CANFSEND(so
) && so
->so_rcv
.sb_cc
) {
318 FD_SET(so
->s
, writefds
);
323 * Set for reading (and urgent data) if we are connected, can
324 * receive more, and we have room for it XXX /2 ?
326 if (CONN_CANFRCV(so
) && (so
->so_snd
.sb_cc
< (so
->so_snd
.sb_datalen
/2))) {
327 FD_SET(so
->s
, readfds
);
336 for (so
= slirp
->udb
.so_next
; so
!= &slirp
->udb
;
338 so_next
= so
->so_next
;
341 * See if it's timed out
344 if (so
->so_expire
<= curtime
) {
348 do_slowtimo
= 1; /* Let socket expire */
352 * When UDP packets are received from over the
353 * link, they're sendto()'d straight away, so
354 * no need for setting for writing
355 * Limit the number of packets queued by this session
356 * to 4. Note that even though we try and limit this
357 * to 4 packets, the session could have more queued
358 * if the packets needed to be fragmented
361 if ((so
->so_state
& SS_ISFCONNECTED
) && so
->so_queued
<= 4) {
362 FD_SET(so
->s
, readfds
);
371 void slirp_select_poll(fd_set
*readfds
, fd_set
*writefds
, fd_set
*xfds
,
375 struct socket
*so
, *so_next
;
378 if (TAILQ_EMPTY(&slirp_instances
)) {
382 global_readfds
= readfds
;
383 global_writefds
= writefds
;
386 curtime
= qemu_get_clock(rt_clock
);
388 TAILQ_FOREACH(slirp
, &slirp_instances
, entry
) {
390 * See if anything has timed out
392 if (time_fasttimo
&& ((curtime
- time_fasttimo
) >= 2)) {
396 if (do_slowtimo
&& ((curtime
- last_slowtimo
) >= 499)) {
399 last_slowtimo
= curtime
;
409 for (so
= slirp
->tcb
.so_next
; so
!= &slirp
->tcb
;
411 so_next
= so
->so_next
;
414 * FD_ISSET is meaningless on these sockets
415 * (and they can crash the program)
417 if (so
->so_state
& SS_NOFDREF
|| so
->s
== -1)
422 * This will soread as well, so no need to
423 * test for readfds below if this succeeds
425 if (FD_ISSET(so
->s
, xfds
))
428 * Check sockets for reading
430 else if (FD_ISSET(so
->s
, readfds
)) {
432 * Check for incoming connections
434 if (so
->so_state
& SS_FACCEPTCONN
) {
440 /* Output it if we read something */
442 tcp_output(sototcpcb(so
));
446 * Check sockets for writing
448 if (FD_ISSET(so
->s
, writefds
)) {
450 * Check for non-blocking, still-connecting sockets
452 if (so
->so_state
& SS_ISFCONNECTING
) {
454 so
->so_state
&= ~SS_ISFCONNECTING
;
456 ret
= send(so
->s
, (const void *) &ret
, 0, 0);
458 /* XXXXX Must fix, zero bytes is a NOP */
459 if (errno
== EAGAIN
|| errno
== EWOULDBLOCK
||
460 errno
== EINPROGRESS
|| errno
== ENOTCONN
)
464 so
->so_state
&= SS_PERSISTENT_MASK
;
465 so
->so_state
|= SS_NOFDREF
;
467 /* else so->so_state &= ~SS_ISFCONNECTING; */
472 tcp_input((struct mbuf
*)NULL
, sizeof(struct ip
), so
);
477 * XXXXX If we wrote something (a lot), there
478 * could be a need for a window update.
479 * In the worst case, the remote will send
480 * a window probe to get things going again
485 * Probe a still-connecting, non-blocking socket
486 * to check if it's still alive
489 if (so
->so_state
& SS_ISFCONNECTING
) {
490 ret
= recv(so
->s
, (char *)&ret
, 0,0);
494 if (errno
== EAGAIN
|| errno
== EWOULDBLOCK
||
495 errno
== EINPROGRESS
|| errno
== ENOTCONN
)
496 continue; /* Still connecting, continue */
499 so
->so_state
&= SS_PERSISTENT_MASK
;
500 so
->so_state
|= SS_NOFDREF
;
502 /* tcp_input will take care of it */
504 ret
= send(so
->s
, &ret
, 0,0);
507 if (errno
== EAGAIN
|| errno
== EWOULDBLOCK
||
508 errno
== EINPROGRESS
|| errno
== ENOTCONN
)
511 so
->so_state
&= SS_PERSISTENT_MASK
;
512 so
->so_state
|= SS_NOFDREF
;
514 so
->so_state
&= ~SS_ISFCONNECTING
;
517 tcp_input((struct mbuf
*)NULL
, sizeof(struct ip
),so
);
518 } /* SS_ISFCONNECTING */
524 * Incoming packets are sent straight away, they're not buffered.
525 * Incoming UDP data isn't buffered either.
527 for (so
= slirp
->udb
.so_next
; so
!= &slirp
->udb
;
529 so_next
= so
->so_next
;
531 if (so
->s
!= -1 && FD_ISSET(so
->s
, readfds
)) {
538 * See if we can start outputting
540 if (slirp
->if_queued
) {
545 /* clear global file descriptor sets.
546 * these reside on the stack in vl.c
547 * so they're unusable if we're not in
548 * slirp_select_fill or slirp_select_poll.
550 global_readfds
= NULL
;
551 global_writefds
= NULL
;
558 #define ETH_P_IP 0x0800 /* Internet Protocol packet */
559 #define ETH_P_ARP 0x0806 /* Address Resolution packet */
561 #define ARPOP_REQUEST 1 /* ARP request */
562 #define ARPOP_REPLY 2 /* ARP reply */
566 unsigned char h_dest
[ETH_ALEN
]; /* destination eth addr */
567 unsigned char h_source
[ETH_ALEN
]; /* source ether addr */
568 unsigned short h_proto
; /* packet type ID field */
573 unsigned short ar_hrd
; /* format of hardware address */
574 unsigned short ar_pro
; /* format of protocol address */
575 unsigned char ar_hln
; /* length of hardware address */
576 unsigned char ar_pln
; /* length of protocol address */
577 unsigned short ar_op
; /* ARP opcode (command) */
580 * Ethernet looks like this : This bit is variable sized however...
582 unsigned char ar_sha
[ETH_ALEN
]; /* sender hardware address */
583 uint32_t ar_sip
; /* sender IP address */
584 unsigned char ar_tha
[ETH_ALEN
]; /* target hardware address */
585 uint32_t ar_tip
; /* target IP address */
586 } __attribute__((packed
));
588 static void arp_input(Slirp
*slirp
, const uint8_t *pkt
, int pkt_len
)
590 struct ethhdr
*eh
= (struct ethhdr
*)pkt
;
591 struct arphdr
*ah
= (struct arphdr
*)(pkt
+ ETH_HLEN
);
592 uint8_t arp_reply
[ETH_HLEN
+ sizeof(struct arphdr
)];
593 struct ethhdr
*reh
= (struct ethhdr
*)arp_reply
;
594 struct arphdr
*rah
= (struct arphdr
*)(arp_reply
+ ETH_HLEN
);
596 struct ex_list
*ex_ptr
;
598 ar_op
= ntohs(ah
->ar_op
);
601 if ((ah
->ar_tip
& slirp
->vnetwork_mask
.s_addr
) ==
602 slirp
->vnetwork_addr
.s_addr
) {
603 if (ah
->ar_tip
== slirp
->vnameserver_addr
.s_addr
||
604 ah
->ar_tip
== slirp
->vhost_addr
.s_addr
)
606 for (ex_ptr
= slirp
->exec_list
; ex_ptr
; ex_ptr
= ex_ptr
->ex_next
) {
607 if (ex_ptr
->ex_addr
.s_addr
== ah
->ar_tip
)
612 /* XXX: make an ARP request to have the client address */
613 memcpy(slirp
->client_ethaddr
, eh
->h_source
, ETH_ALEN
);
615 /* ARP request for alias/dns mac address */
616 memcpy(reh
->h_dest
, pkt
+ ETH_ALEN
, ETH_ALEN
);
617 memcpy(reh
->h_source
, special_ethaddr
, ETH_ALEN
- 4);
618 memcpy(&reh
->h_source
[2], &ah
->ar_tip
, 4);
619 reh
->h_proto
= htons(ETH_P_ARP
);
621 rah
->ar_hrd
= htons(1);
622 rah
->ar_pro
= htons(ETH_P_IP
);
623 rah
->ar_hln
= ETH_ALEN
;
625 rah
->ar_op
= htons(ARPOP_REPLY
);
626 memcpy(rah
->ar_sha
, reh
->h_source
, ETH_ALEN
);
627 rah
->ar_sip
= ah
->ar_tip
;
628 memcpy(rah
->ar_tha
, ah
->ar_sha
, ETH_ALEN
);
629 rah
->ar_tip
= ah
->ar_sip
;
630 slirp_output(slirp
->opaque
, arp_reply
, sizeof(arp_reply
));
634 /* reply to request of client mac address ? */
635 if (!memcmp(slirp
->client_ethaddr
, zero_ethaddr
, ETH_ALEN
) &&
636 ah
->ar_sip
== slirp
->client_ipaddr
.s_addr
) {
637 memcpy(slirp
->client_ethaddr
, ah
->ar_sha
, ETH_ALEN
);
645 void slirp_input(Slirp
*slirp
, const uint8_t *pkt
, int pkt_len
)
650 if (pkt_len
< ETH_HLEN
)
653 proto
= ntohs(*(uint16_t *)(pkt
+ 12));
656 arp_input(slirp
, pkt
, pkt_len
);
662 /* Note: we add to align the IP header */
663 if (M_FREEROOM(m
) < pkt_len
+ 2) {
664 m_inc(m
, pkt_len
+ 2);
666 m
->m_len
= pkt_len
+ 2;
667 memcpy(m
->m_data
+ 2, pkt
, pkt_len
);
669 m
->m_data
+= 2 + ETH_HLEN
;
670 m
->m_len
-= 2 + ETH_HLEN
;
679 /* output the IP packet to the ethernet device */
680 void if_encap(Slirp
*slirp
, const uint8_t *ip_data
, int ip_data_len
)
683 struct ethhdr
*eh
= (struct ethhdr
*)buf
;
685 if (ip_data_len
+ ETH_HLEN
> sizeof(buf
))
688 if (!memcmp(slirp
->client_ethaddr
, zero_ethaddr
, ETH_ALEN
)) {
689 uint8_t arp_req
[ETH_HLEN
+ sizeof(struct arphdr
)];
690 struct ethhdr
*reh
= (struct ethhdr
*)arp_req
;
691 struct arphdr
*rah
= (struct arphdr
*)(arp_req
+ ETH_HLEN
);
692 const struct ip
*iph
= (const struct ip
*)ip_data
;
694 /* If the client addr is not known, there is no point in
695 sending the packet to it. Normally the sender should have
696 done an ARP request to get its MAC address. Here we do it
697 in place of sending the packet and we hope that the sender
698 will retry sending its packet. */
699 memset(reh
->h_dest
, 0xff, ETH_ALEN
);
700 memcpy(reh
->h_source
, special_ethaddr
, ETH_ALEN
- 4);
701 memcpy(&reh
->h_source
[2], &slirp
->vhost_addr
, 4);
702 reh
->h_proto
= htons(ETH_P_ARP
);
703 rah
->ar_hrd
= htons(1);
704 rah
->ar_pro
= htons(ETH_P_IP
);
705 rah
->ar_hln
= ETH_ALEN
;
707 rah
->ar_op
= htons(ARPOP_REQUEST
);
709 memcpy(rah
->ar_sha
, special_ethaddr
, ETH_ALEN
- 4);
710 memcpy(&rah
->ar_sha
[2], &slirp
->vhost_addr
, 4);
712 rah
->ar_sip
= slirp
->vhost_addr
.s_addr
;
713 /* target hw addr (none) */
714 memset(rah
->ar_tha
, 0, ETH_ALEN
);
716 rah
->ar_tip
= iph
->ip_dst
.s_addr
;
717 slirp
->client_ipaddr
= iph
->ip_dst
;
718 slirp_output(slirp
->opaque
, arp_req
, sizeof(arp_req
));
720 memcpy(eh
->h_dest
, slirp
->client_ethaddr
, ETH_ALEN
);
721 memcpy(eh
->h_source
, special_ethaddr
, ETH_ALEN
- 4);
722 /* XXX: not correct */
723 memcpy(&eh
->h_source
[2], &slirp
->vhost_addr
, 4);
724 eh
->h_proto
= htons(ETH_P_IP
);
725 memcpy(buf
+ sizeof(struct ethhdr
), ip_data
, ip_data_len
);
726 slirp_output(slirp
->opaque
, buf
, ip_data_len
+ ETH_HLEN
);
730 /* Drop host forwarding rule, return 0 if found. */
731 int slirp_remove_hostfwd(Slirp
*slirp
, int is_udp
, struct in_addr host_addr
,
735 struct socket
*head
= (is_udp
? &slirp
->udb
: &slirp
->tcb
);
736 struct sockaddr_in addr
;
737 int port
= htons(host_port
);
740 for (so
= head
->so_next
; so
!= head
; so
= so
->so_next
) {
741 addr_len
= sizeof(addr
);
742 if ((so
->so_state
& SS_HOSTFWD
) &&
743 getsockname(so
->s
, (struct sockaddr
*)&addr
, &addr_len
) == 0 &&
744 addr
.sin_addr
.s_addr
== host_addr
.s_addr
&&
745 addr
.sin_port
== port
) {
755 int slirp_add_hostfwd(Slirp
*slirp
, int is_udp
, struct in_addr host_addr
,
756 int host_port
, struct in_addr guest_addr
, int guest_port
)
758 if (!guest_addr
.s_addr
) {
759 guest_addr
= slirp
->vdhcp_startaddr
;
762 if (!udp_listen(slirp
, host_addr
.s_addr
, htons(host_port
),
763 guest_addr
.s_addr
, htons(guest_port
), SS_HOSTFWD
))
766 if (!tcp_listen(slirp
, host_addr
.s_addr
, htons(host_port
),
767 guest_addr
.s_addr
, htons(guest_port
), SS_HOSTFWD
))
773 int slirp_add_exec(Slirp
*slirp
, int do_pty
, const void *args
,
774 struct in_addr
*guest_addr
, int guest_port
)
776 if (!guest_addr
->s_addr
) {
777 guest_addr
->s_addr
= slirp
->vnetwork_addr
.s_addr
|
778 (htonl(0x0204) & ~slirp
->vnetwork_mask
.s_addr
);
780 if ((guest_addr
->s_addr
& slirp
->vnetwork_mask
.s_addr
) !=
781 slirp
->vnetwork_addr
.s_addr
||
782 guest_addr
->s_addr
== slirp
->vhost_addr
.s_addr
||
783 guest_addr
->s_addr
== slirp
->vnameserver_addr
.s_addr
) {
786 return add_exec(&slirp
->exec_list
, do_pty
, (char *)args
, *guest_addr
,
790 ssize_t
slirp_send(struct socket
*so
, const void *buf
, size_t len
, int flags
)
792 if (so
->s
== -1 && so
->extra
) {
793 qemu_chr_write(so
->extra
, buf
, len
);
797 return send(so
->s
, buf
, len
, flags
);
800 static struct socket
*
801 slirp_find_ctl_socket(Slirp
*slirp
, struct in_addr guest_addr
, int guest_port
)
805 for (so
= slirp
->tcb
.so_next
; so
!= &slirp
->tcb
; so
= so
->so_next
) {
806 if (so
->so_faddr
.s_addr
== guest_addr
.s_addr
&&
807 htons(so
->so_fport
) == guest_port
) {
814 size_t slirp_socket_can_recv(Slirp
*slirp
, struct in_addr guest_addr
,
820 so
= slirp_find_ctl_socket(slirp
, guest_addr
, guest_port
);
822 if (!so
|| so
->so_state
& SS_NOFDREF
)
825 if (!CONN_CANFRCV(so
) || so
->so_snd
.sb_cc
>= (so
->so_snd
.sb_datalen
/2))
828 return sopreprbuf(so
, iov
, NULL
);
831 void slirp_socket_recv(Slirp
*slirp
, struct in_addr guest_addr
, int guest_port
,
832 const uint8_t *buf
, int size
)
835 struct socket
*so
= slirp_find_ctl_socket(slirp
, guest_addr
, guest_port
);
840 ret
= soreadbuf(so
, (const char *)buf
, size
);
843 tcp_output(sototcpcb(so
));
846 static void slirp_tcp_save(QEMUFile
*f
, struct tcpcb
*tp
)
850 qemu_put_sbe16(f
, tp
->t_state
);
851 for (i
= 0; i
< TCPT_NTIMERS
; i
++)
852 qemu_put_sbe16(f
, tp
->t_timer
[i
]);
853 qemu_put_sbe16(f
, tp
->t_rxtshift
);
854 qemu_put_sbe16(f
, tp
->t_rxtcur
);
855 qemu_put_sbe16(f
, tp
->t_dupacks
);
856 qemu_put_be16(f
, tp
->t_maxseg
);
857 qemu_put_sbyte(f
, tp
->t_force
);
858 qemu_put_be16(f
, tp
->t_flags
);
859 qemu_put_be32(f
, tp
->snd_una
);
860 qemu_put_be32(f
, tp
->snd_nxt
);
861 qemu_put_be32(f
, tp
->snd_up
);
862 qemu_put_be32(f
, tp
->snd_wl1
);
863 qemu_put_be32(f
, tp
->snd_wl2
);
864 qemu_put_be32(f
, tp
->iss
);
865 qemu_put_be32(f
, tp
->snd_wnd
);
866 qemu_put_be32(f
, tp
->rcv_wnd
);
867 qemu_put_be32(f
, tp
->rcv_nxt
);
868 qemu_put_be32(f
, tp
->rcv_up
);
869 qemu_put_be32(f
, tp
->irs
);
870 qemu_put_be32(f
, tp
->rcv_adv
);
871 qemu_put_be32(f
, tp
->snd_max
);
872 qemu_put_be32(f
, tp
->snd_cwnd
);
873 qemu_put_be32(f
, tp
->snd_ssthresh
);
874 qemu_put_sbe16(f
, tp
->t_idle
);
875 qemu_put_sbe16(f
, tp
->t_rtt
);
876 qemu_put_be32(f
, tp
->t_rtseq
);
877 qemu_put_sbe16(f
, tp
->t_srtt
);
878 qemu_put_sbe16(f
, tp
->t_rttvar
);
879 qemu_put_be16(f
, tp
->t_rttmin
);
880 qemu_put_be32(f
, tp
->max_sndwnd
);
881 qemu_put_byte(f
, tp
->t_oobflags
);
882 qemu_put_byte(f
, tp
->t_iobc
);
883 qemu_put_sbe16(f
, tp
->t_softerror
);
884 qemu_put_byte(f
, tp
->snd_scale
);
885 qemu_put_byte(f
, tp
->rcv_scale
);
886 qemu_put_byte(f
, tp
->request_r_scale
);
887 qemu_put_byte(f
, tp
->requested_s_scale
);
888 qemu_put_be32(f
, tp
->ts_recent
);
889 qemu_put_be32(f
, tp
->ts_recent_age
);
890 qemu_put_be32(f
, tp
->last_ack_sent
);
893 static void slirp_sbuf_save(QEMUFile
*f
, struct sbuf
*sbuf
)
897 qemu_put_be32(f
, sbuf
->sb_cc
);
898 qemu_put_be32(f
, sbuf
->sb_datalen
);
899 off
= (uint32_t)(sbuf
->sb_wptr
- sbuf
->sb_data
);
900 qemu_put_sbe32(f
, off
);
901 off
= (uint32_t)(sbuf
->sb_rptr
- sbuf
->sb_data
);
902 qemu_put_sbe32(f
, off
);
903 qemu_put_buffer(f
, (unsigned char*)sbuf
->sb_data
, sbuf
->sb_datalen
);
906 static void slirp_socket_save(QEMUFile
*f
, struct socket
*so
)
908 qemu_put_be32(f
, so
->so_urgc
);
909 qemu_put_be32(f
, so
->so_faddr
.s_addr
);
910 qemu_put_be32(f
, so
->so_laddr
.s_addr
);
911 qemu_put_be16(f
, so
->so_fport
);
912 qemu_put_be16(f
, so
->so_lport
);
913 qemu_put_byte(f
, so
->so_iptos
);
914 qemu_put_byte(f
, so
->so_emu
);
915 qemu_put_byte(f
, so
->so_type
);
916 qemu_put_be32(f
, so
->so_state
);
917 slirp_sbuf_save(f
, &so
->so_rcv
);
918 slirp_sbuf_save(f
, &so
->so_snd
);
919 slirp_tcp_save(f
, so
->so_tcpcb
);
922 static void slirp_bootp_save(QEMUFile
*f
, Slirp
*slirp
)
926 for (i
= 0; i
< NB_BOOTP_CLIENTS
; i
++) {
927 qemu_put_be16(f
, slirp
->bootp_clients
[i
].allocated
);
928 qemu_put_buffer(f
, slirp
->bootp_clients
[i
].macaddr
, 6);
932 static void slirp_state_save(QEMUFile
*f
, void *opaque
)
934 Slirp
*slirp
= opaque
;
935 struct ex_list
*ex_ptr
;
937 for (ex_ptr
= slirp
->exec_list
; ex_ptr
; ex_ptr
= ex_ptr
->ex_next
)
938 if (ex_ptr
->ex_pty
== 3) {
940 so
= slirp_find_ctl_socket(slirp
, ex_ptr
->ex_addr
,
941 ntohs(ex_ptr
->ex_fport
));
945 qemu_put_byte(f
, 42);
946 slirp_socket_save(f
, so
);
950 qemu_put_be16(f
, slirp
->ip_id
);
952 slirp_bootp_save(f
, slirp
);
955 static void slirp_tcp_load(QEMUFile
*f
, struct tcpcb
*tp
)
959 tp
->t_state
= qemu_get_sbe16(f
);
960 for (i
= 0; i
< TCPT_NTIMERS
; i
++)
961 tp
->t_timer
[i
] = qemu_get_sbe16(f
);
962 tp
->t_rxtshift
= qemu_get_sbe16(f
);
963 tp
->t_rxtcur
= qemu_get_sbe16(f
);
964 tp
->t_dupacks
= qemu_get_sbe16(f
);
965 tp
->t_maxseg
= qemu_get_be16(f
);
966 tp
->t_force
= qemu_get_sbyte(f
);
967 tp
->t_flags
= qemu_get_be16(f
);
968 tp
->snd_una
= qemu_get_be32(f
);
969 tp
->snd_nxt
= qemu_get_be32(f
);
970 tp
->snd_up
= qemu_get_be32(f
);
971 tp
->snd_wl1
= qemu_get_be32(f
);
972 tp
->snd_wl2
= qemu_get_be32(f
);
973 tp
->iss
= qemu_get_be32(f
);
974 tp
->snd_wnd
= qemu_get_be32(f
);
975 tp
->rcv_wnd
= qemu_get_be32(f
);
976 tp
->rcv_nxt
= qemu_get_be32(f
);
977 tp
->rcv_up
= qemu_get_be32(f
);
978 tp
->irs
= qemu_get_be32(f
);
979 tp
->rcv_adv
= qemu_get_be32(f
);
980 tp
->snd_max
= qemu_get_be32(f
);
981 tp
->snd_cwnd
= qemu_get_be32(f
);
982 tp
->snd_ssthresh
= qemu_get_be32(f
);
983 tp
->t_idle
= qemu_get_sbe16(f
);
984 tp
->t_rtt
= qemu_get_sbe16(f
);
985 tp
->t_rtseq
= qemu_get_be32(f
);
986 tp
->t_srtt
= qemu_get_sbe16(f
);
987 tp
->t_rttvar
= qemu_get_sbe16(f
);
988 tp
->t_rttmin
= qemu_get_be16(f
);
989 tp
->max_sndwnd
= qemu_get_be32(f
);
990 tp
->t_oobflags
= qemu_get_byte(f
);
991 tp
->t_iobc
= qemu_get_byte(f
);
992 tp
->t_softerror
= qemu_get_sbe16(f
);
993 tp
->snd_scale
= qemu_get_byte(f
);
994 tp
->rcv_scale
= qemu_get_byte(f
);
995 tp
->request_r_scale
= qemu_get_byte(f
);
996 tp
->requested_s_scale
= qemu_get_byte(f
);
997 tp
->ts_recent
= qemu_get_be32(f
);
998 tp
->ts_recent_age
= qemu_get_be32(f
);
999 tp
->last_ack_sent
= qemu_get_be32(f
);
1003 static int slirp_sbuf_load(QEMUFile
*f
, struct sbuf
*sbuf
)
1005 uint32_t off
, sb_cc
, sb_datalen
;
1007 sb_cc
= qemu_get_be32(f
);
1008 sb_datalen
= qemu_get_be32(f
);
1010 sbreserve(sbuf
, sb_datalen
);
1012 if (sbuf
->sb_datalen
!= sb_datalen
)
1015 sbuf
->sb_cc
= sb_cc
;
1017 off
= qemu_get_sbe32(f
);
1018 sbuf
->sb_wptr
= sbuf
->sb_data
+ off
;
1019 off
= qemu_get_sbe32(f
);
1020 sbuf
->sb_rptr
= sbuf
->sb_data
+ off
;
1021 qemu_get_buffer(f
, (unsigned char*)sbuf
->sb_data
, sbuf
->sb_datalen
);
1026 static int slirp_socket_load(QEMUFile
*f
, struct socket
*so
)
1028 if (tcp_attach(so
) < 0)
1031 so
->so_urgc
= qemu_get_be32(f
);
1032 so
->so_faddr
.s_addr
= qemu_get_be32(f
);
1033 so
->so_laddr
.s_addr
= qemu_get_be32(f
);
1034 so
->so_fport
= qemu_get_be16(f
);
1035 so
->so_lport
= qemu_get_be16(f
);
1036 so
->so_iptos
= qemu_get_byte(f
);
1037 so
->so_emu
= qemu_get_byte(f
);
1038 so
->so_type
= qemu_get_byte(f
);
1039 so
->so_state
= qemu_get_be32(f
);
1040 if (slirp_sbuf_load(f
, &so
->so_rcv
) < 0)
1042 if (slirp_sbuf_load(f
, &so
->so_snd
) < 0)
1044 slirp_tcp_load(f
, so
->so_tcpcb
);
1049 static void slirp_bootp_load(QEMUFile
*f
, Slirp
*slirp
)
1053 for (i
= 0; i
< NB_BOOTP_CLIENTS
; i
++) {
1054 slirp
->bootp_clients
[i
].allocated
= qemu_get_be16(f
);
1055 qemu_get_buffer(f
, slirp
->bootp_clients
[i
].macaddr
, 6);
1059 static int slirp_state_load(QEMUFile
*f
, void *opaque
, int version_id
)
1061 Slirp
*slirp
= opaque
;
1062 struct ex_list
*ex_ptr
;
1065 while ((r
= qemu_get_byte(f
))) {
1067 struct socket
*so
= socreate(slirp
);
1072 ret
= slirp_socket_load(f
, so
);
1077 if ((so
->so_faddr
.s_addr
& slirp
->vnetwork_mask
.s_addr
) !=
1078 slirp
->vnetwork_addr
.s_addr
) {
1081 for (ex_ptr
= slirp
->exec_list
; ex_ptr
; ex_ptr
= ex_ptr
->ex_next
) {
1082 if (ex_ptr
->ex_pty
== 3 &&
1083 so
->so_faddr
.s_addr
== ex_ptr
->ex_addr
.s_addr
&&
1084 so
->so_fport
== ex_ptr
->ex_fport
) {
1091 so
->extra
= (void *)ex_ptr
->ex_exec
;
1094 if (version_id
>= 2) {
1095 slirp
->ip_id
= qemu_get_be16(f
);
1098 if (version_id
>= 3) {
1099 slirp_bootp_load(f
, slirp
);