slirp: Clean up updtime
[qemu-kvm/fedora.git] / slirp / slirp.c
blob20c691f3e38f4ab6f42beedf8dc1309ba8b47883
1 /*
2 * libslirp glue
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
22 * THE SOFTWARE.
24 #include "qemu-common.h"
25 #include "qemu-char.h"
26 #include "slirp.h"
27 #include "hw/hw.h"
29 /* host address */
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 };
54 int slirp_restrict;
55 static int do_slowtimo;
56 int link_up;
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];
64 #ifdef _WIN32
66 static int get_dns_addr(struct in_addr *pdns_addr)
68 FIXED_INFO *FixedInfo=NULL;
69 ULONG BufLen;
70 DWORD ret;
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)) {
78 if (FixedInfo) {
79 GlobalFree(FixedInfo);
80 FixedInfo = NULL;
82 FixedInfo = GlobalAlloc(GPTR, BufLen);
85 if ((ret = GetNetworkParams(FixedInfo, &BufLen)) != ERROR_SUCCESS) {
86 printf("GetNetworkParams failed. ret = %08x\n", (u_int)ret );
87 if (FixedInfo) {
88 GlobalFree(FixedInfo);
89 FixedInfo = NULL;
91 return -1;
94 pIPAddr = &(FixedInfo->DnsServerList);
95 inet_aton(pIPAddr->IpAddress.String, &tmp_addr);
96 *pdns_addr = tmp_addr;
97 if (FixedInfo) {
98 GlobalFree(FixedInfo);
99 FixedInfo = NULL;
101 return 0;
104 static void winsock_cleanup(void)
106 WSACleanup();
109 #else
111 static int get_dns_addr(struct in_addr *pdns_addr)
113 char buff[512];
114 char buff2[257];
115 FILE *f;
116 int found = 0;
117 struct in_addr tmp_addr;
119 f = fopen("/etc/resolv.conf", "r");
120 if (!f)
121 return -1;
123 #ifdef DEBUG
124 lprint("IP address of your DNS(s): ");
125 #endif
126 while (fgets(buff, 512, f) != NULL) {
127 if (sscanf(buff, "nameserver%*[ \t]%256s", buff2) == 1) {
128 if (!inet_aton(buff2, &tmp_addr))
129 continue;
130 if (tmp_addr.s_addr == loopback_addr.s_addr)
131 tmp_addr = our_addr;
132 /* If it's the first one, set it to dns_addr */
133 if (!found)
134 *pdns_addr = tmp_addr;
135 #ifdef DEBUG
136 else
137 lprint(", ");
138 #endif
139 if (++found > 3) {
140 #ifdef DEBUG
141 lprint("(more)");
142 #endif
143 break;
145 #ifdef DEBUG
146 else
147 lprint("%s", inet_ntoa(tmp_addr));
148 #endif
151 fclose(f);
152 if (!found)
153 return -1;
154 return 0;
157 #endif
159 static void slirp_init_once(void)
161 static int initialized;
162 struct hostent *he;
163 char our_name[256];
164 #ifdef _WIN32
165 WSADATA Data;
166 #endif
168 if (initialized) {
169 return;
171 initialized = 1;
173 #ifdef _WIN32
174 WSAStartup(MAKEWORD(2,0), &Data);
175 atexit(winsock_cleanup);
176 #endif
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);
183 if (he) {
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)
206 slirp_init_once();
208 link_up = 1;
209 slirp_restrict = restricted;
211 if_init();
212 ip_init();
214 /* Initialise mbufs *after* setting the MTU */
215 m_init();
217 vnetwork_addr = vnetwork;
218 vnetwork_mask = vnetmask;
219 vhost_addr = vhost;
220 if (vhostname) {
221 pstrcpy(slirp_hostname, sizeof(slirp_hostname), vhostname);
223 qemu_free(tftp_prefix);
224 tftp_prefix = NULL;
225 if (tftp_path) {
226 tftp_prefix = qemu_strdup(tftp_path);
228 qemu_free(bootp_filename);
229 bootp_filename = NULL;
230 if (bootfile) {
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
246 #ifdef _WIN32
247 static void updtime(void)
249 struct _timeb tb;
251 _ftime(&tb);
253 curtime = tb.time * 1000 + tb.millitm;
255 #else
256 static void updtime(void)
258 struct timeval tv;
260 gettimeofday(&tv, NULL);
262 curtime = tv.tv_sec * 1000 + tv.tv_usec / 1000;
264 #endif
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;
271 int nfds;
272 int tmp_time;
274 /* fail safe */
275 global_readfds = NULL;
276 global_writefds = NULL;
277 global_xfds = NULL;
279 nfds = *pnfds;
281 * First, TCP sockets
283 do_slowtimo = 0;
284 if (link_up) {
286 * *_slowtimo needs calling if there are IP fragments
287 * in the fragment queue, or there are TCP connections active
289 do_slowtimo = ((tcb.so_next != &tcb) ||
290 (&ipq.ip_link != ipq.ip_link.next));
292 for (so = tcb.so_next; so != &tcb; so = so_next) {
293 so_next = so->so_next;
296 * See if we need a tcp_fasttimo
298 if (time_fasttimo == 0 && so->so_tcpcb->t_flags & TF_DELACK)
299 time_fasttimo = curtime; /* Flag when we want a fasttimo */
302 * NOFDREF can include still connecting to local-host,
303 * newly socreated() sockets etc. Don't want to select these.
305 if (so->so_state & SS_NOFDREF || so->s == -1)
306 continue;
309 * Set for reading sockets which are accepting
311 if (so->so_state & SS_FACCEPTCONN) {
312 FD_SET(so->s, readfds);
313 UPD_NFDS(so->s);
314 continue;
318 * Set for writing sockets which are connecting
320 if (so->so_state & SS_ISFCONNECTING) {
321 FD_SET(so->s, writefds);
322 UPD_NFDS(so->s);
323 continue;
327 * Set for writing if we are connected, can send more, and
328 * we have something to send
330 if (CONN_CANFSEND(so) && so->so_rcv.sb_cc) {
331 FD_SET(so->s, writefds);
332 UPD_NFDS(so->s);
336 * Set for reading (and urgent data) if we are connected, can
337 * receive more, and we have room for it XXX /2 ?
339 if (CONN_CANFRCV(so) && (so->so_snd.sb_cc < (so->so_snd.sb_datalen/2))) {
340 FD_SET(so->s, readfds);
341 FD_SET(so->s, xfds);
342 UPD_NFDS(so->s);
347 * UDP sockets
349 for (so = udb.so_next; so != &udb; so = so_next) {
350 so_next = so->so_next;
353 * See if it's timed out
355 if (so->so_expire) {
356 if (so->so_expire <= curtime) {
357 udp_detach(so);
358 continue;
359 } else
360 do_slowtimo = 1; /* Let socket expire */
364 * When UDP packets are received from over the
365 * link, they're sendto()'d straight away, so
366 * no need for setting for writing
367 * Limit the number of packets queued by this session
368 * to 4. Note that even though we try and limit this
369 * to 4 packets, the session could have more queued
370 * if the packets needed to be fragmented
371 * (XXX <= 4 ?)
373 if ((so->so_state & SS_ISFCONNECTED) && so->so_queued <= 4) {
374 FD_SET(so->s, readfds);
375 UPD_NFDS(so->s);
381 * Setup timeout to use minimum CPU usage, especially when idle
385 * First, see the timeout needed by *timo
387 timeout.tv_sec = 0;
388 timeout.tv_usec = -1;
390 * If a slowtimo is needed, set timeout to 500ms from the last
391 * slow timeout. If a fast timeout is needed, set timeout within
392 * 200ms of when it was requested.
394 if (do_slowtimo) {
395 /* XXX + 10000 because some select()'s aren't that accurate */
396 timeout.tv_usec = ((500 - (curtime - last_slowtimo)) * 1000) + 10000;
397 if (timeout.tv_usec < 0)
398 timeout.tv_usec = 0;
399 else if (timeout.tv_usec > 510000)
400 timeout.tv_usec = 510000;
402 /* Can only fasttimo if we also slowtimo */
403 if (time_fasttimo) {
404 tmp_time = (200 - (curtime - time_fasttimo)) * 1000;
405 if (tmp_time < 0)
406 tmp_time = 0;
408 /* Choose the smallest of the 2 */
409 if (tmp_time < timeout.tv_usec)
410 timeout.tv_usec = (u_int)tmp_time;
413 *pnfds = nfds;
416 void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds)
418 struct socket *so, *so_next;
419 int ret;
421 global_readfds = readfds;
422 global_writefds = writefds;
423 global_xfds = xfds;
425 /* Update time */
426 updtime();
429 * See if anything has timed out
431 if (link_up) {
432 if (time_fasttimo && ((curtime - time_fasttimo) >= 2)) {
433 tcp_fasttimo();
434 time_fasttimo = 0;
436 if (do_slowtimo && ((curtime - last_slowtimo) >= 499)) {
437 ip_slowtimo();
438 tcp_slowtimo();
439 last_slowtimo = curtime;
444 * Check sockets
446 if (link_up) {
448 * Check TCP sockets
450 for (so = tcb.so_next; so != &tcb; so = so_next) {
451 so_next = so->so_next;
454 * FD_ISSET is meaningless on these sockets
455 * (and they can crash the program)
457 if (so->so_state & SS_NOFDREF || so->s == -1)
458 continue;
461 * Check for URG data
462 * This will soread as well, so no need to
463 * test for readfds below if this succeeds
465 if (FD_ISSET(so->s, xfds))
466 sorecvoob(so);
468 * Check sockets for reading
470 else if (FD_ISSET(so->s, readfds)) {
472 * Check for incoming connections
474 if (so->so_state & SS_FACCEPTCONN) {
475 tcp_connect(so);
476 continue;
477 } /* else */
478 ret = soread(so);
480 /* Output it if we read something */
481 if (ret > 0)
482 tcp_output(sototcpcb(so));
486 * Check sockets for writing
488 if (FD_ISSET(so->s, writefds)) {
490 * Check for non-blocking, still-connecting sockets
492 if (so->so_state & SS_ISFCONNECTING) {
493 /* Connected */
494 so->so_state &= ~SS_ISFCONNECTING;
496 ret = send(so->s, (const void *) &ret, 0, 0);
497 if (ret < 0) {
498 /* XXXXX Must fix, zero bytes is a NOP */
499 if (errno == EAGAIN || errno == EWOULDBLOCK ||
500 errno == EINPROGRESS || errno == ENOTCONN)
501 continue;
503 /* else failed */
504 so->so_state &= SS_PERSISTENT_MASK;
505 so->so_state |= SS_NOFDREF;
507 /* else so->so_state &= ~SS_ISFCONNECTING; */
510 * Continue tcp_input
512 tcp_input((struct mbuf *)NULL, sizeof(struct ip), so);
513 /* continue; */
514 } else
515 ret = sowrite(so);
517 * XXXXX If we wrote something (a lot), there
518 * could be a need for a window update.
519 * In the worst case, the remote will send
520 * a window probe to get things going again
525 * Probe a still-connecting, non-blocking socket
526 * to check if it's still alive
528 #ifdef PROBE_CONN
529 if (so->so_state & SS_ISFCONNECTING) {
530 ret = recv(so->s, (char *)&ret, 0,0);
532 if (ret < 0) {
533 /* XXX */
534 if (errno == EAGAIN || errno == EWOULDBLOCK ||
535 errno == EINPROGRESS || errno == ENOTCONN)
536 continue; /* Still connecting, continue */
538 /* else failed */
539 so->so_state &= SS_PERSISTENT_MASK;
540 so->so_state |= SS_NOFDREF;
542 /* tcp_input will take care of it */
543 } else {
544 ret = send(so->s, &ret, 0,0);
545 if (ret < 0) {
546 /* XXX */
547 if (errno == EAGAIN || errno == EWOULDBLOCK ||
548 errno == EINPROGRESS || errno == ENOTCONN)
549 continue;
550 /* else failed */
551 so->so_state &= SS_PERSISTENT_MASK;
552 so->so_state |= SS_NOFDREF;
553 } else
554 so->so_state &= ~SS_ISFCONNECTING;
557 tcp_input((struct mbuf *)NULL, sizeof(struct ip),so);
558 } /* SS_ISFCONNECTING */
559 #endif
563 * Now UDP sockets.
564 * Incoming packets are sent straight away, they're not buffered.
565 * Incoming UDP data isn't buffered either.
567 for (so = udb.so_next; so != &udb; so = so_next) {
568 so_next = so->so_next;
570 if (so->s != -1 && FD_ISSET(so->s, readfds)) {
571 sorecvfrom(so);
577 * See if we can start outputting
579 if (if_queued && link_up)
580 if_start();
582 /* clear global file descriptor sets.
583 * these reside on the stack in vl.c
584 * so they're unusable if we're not in
585 * slirp_select_fill or slirp_select_poll.
587 global_readfds = NULL;
588 global_writefds = NULL;
589 global_xfds = NULL;
592 #define ETH_ALEN 6
593 #define ETH_HLEN 14
595 #define ETH_P_IP 0x0800 /* Internet Protocol packet */
596 #define ETH_P_ARP 0x0806 /* Address Resolution packet */
598 #define ARPOP_REQUEST 1 /* ARP request */
599 #define ARPOP_REPLY 2 /* ARP reply */
601 struct ethhdr
603 unsigned char h_dest[ETH_ALEN]; /* destination eth addr */
604 unsigned char h_source[ETH_ALEN]; /* source ether addr */
605 unsigned short h_proto; /* packet type ID field */
608 struct arphdr
610 unsigned short ar_hrd; /* format of hardware address */
611 unsigned short ar_pro; /* format of protocol address */
612 unsigned char ar_hln; /* length of hardware address */
613 unsigned char ar_pln; /* length of protocol address */
614 unsigned short ar_op; /* ARP opcode (command) */
617 * Ethernet looks like this : This bit is variable sized however...
619 unsigned char ar_sha[ETH_ALEN]; /* sender hardware address */
620 uint32_t ar_sip; /* sender IP address */
621 unsigned char ar_tha[ETH_ALEN]; /* target hardware address */
622 uint32_t ar_tip ; /* target IP address */
623 } __attribute__((packed));
625 static void arp_input(const uint8_t *pkt, int pkt_len)
627 struct ethhdr *eh = (struct ethhdr *)pkt;
628 struct arphdr *ah = (struct arphdr *)(pkt + ETH_HLEN);
629 uint8_t arp_reply[ETH_HLEN + sizeof(struct arphdr)];
630 struct ethhdr *reh = (struct ethhdr *)arp_reply;
631 struct arphdr *rah = (struct arphdr *)(arp_reply + ETH_HLEN);
632 int ar_op;
633 struct ex_list *ex_ptr;
635 ar_op = ntohs(ah->ar_op);
636 switch(ar_op) {
637 case ARPOP_REQUEST:
638 if ((ah->ar_tip & vnetwork_mask.s_addr) == vnetwork_addr.s_addr) {
639 if (ah->ar_tip == vnameserver_addr.s_addr ||
640 ah->ar_tip == vhost_addr.s_addr)
641 goto arp_ok;
642 for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
643 if (ex_ptr->ex_addr.s_addr == ah->ar_tip)
644 goto arp_ok;
646 return;
647 arp_ok:
648 /* XXX: make an ARP request to have the client address */
649 memcpy(client_ethaddr, eh->h_source, ETH_ALEN);
651 /* ARP request for alias/dns mac address */
652 memcpy(reh->h_dest, pkt + ETH_ALEN, ETH_ALEN);
653 memcpy(reh->h_source, special_ethaddr, ETH_ALEN - 4);
654 memcpy(&reh->h_source[2], &ah->ar_tip, 4);
655 reh->h_proto = htons(ETH_P_ARP);
657 rah->ar_hrd = htons(1);
658 rah->ar_pro = htons(ETH_P_IP);
659 rah->ar_hln = ETH_ALEN;
660 rah->ar_pln = 4;
661 rah->ar_op = htons(ARPOP_REPLY);
662 memcpy(rah->ar_sha, reh->h_source, ETH_ALEN);
663 rah->ar_sip = ah->ar_tip;
664 memcpy(rah->ar_tha, ah->ar_sha, ETH_ALEN);
665 rah->ar_tip = ah->ar_sip;
666 slirp_output(arp_reply, sizeof(arp_reply));
668 break;
669 case ARPOP_REPLY:
670 /* reply to request of client mac address ? */
671 if (!memcmp(client_ethaddr, zero_ethaddr, ETH_ALEN) &&
672 ah->ar_sip == client_ipaddr.s_addr) {
673 memcpy(client_ethaddr, ah->ar_sha, ETH_ALEN);
675 break;
676 default:
677 break;
681 void slirp_input(const uint8_t *pkt, int pkt_len)
683 struct mbuf *m;
684 int proto;
686 if (pkt_len < ETH_HLEN)
687 return;
689 proto = ntohs(*(uint16_t *)(pkt + 12));
690 switch(proto) {
691 case ETH_P_ARP:
692 arp_input(pkt, pkt_len);
693 break;
694 case ETH_P_IP:
695 m = m_get();
696 if (!m)
697 return;
698 /* Note: we add to align the IP header */
699 if (M_FREEROOM(m) < pkt_len + 2) {
700 m_inc(m, pkt_len + 2);
702 m->m_len = pkt_len + 2;
703 memcpy(m->m_data + 2, pkt, pkt_len);
705 m->m_data += 2 + ETH_HLEN;
706 m->m_len -= 2 + ETH_HLEN;
708 ip_input(m);
709 break;
710 default:
711 break;
715 /* output the IP packet to the ethernet device */
716 void if_encap(const uint8_t *ip_data, int ip_data_len)
718 uint8_t buf[1600];
719 struct ethhdr *eh = (struct ethhdr *)buf;
721 if (ip_data_len + ETH_HLEN > sizeof(buf))
722 return;
724 if (!memcmp(client_ethaddr, zero_ethaddr, ETH_ALEN)) {
725 uint8_t arp_req[ETH_HLEN + sizeof(struct arphdr)];
726 struct ethhdr *reh = (struct ethhdr *)arp_req;
727 struct arphdr *rah = (struct arphdr *)(arp_req + ETH_HLEN);
728 const struct ip *iph = (const struct ip *)ip_data;
730 /* If the client addr is not known, there is no point in
731 sending the packet to it. Normally the sender should have
732 done an ARP request to get its MAC address. Here we do it
733 in place of sending the packet and we hope that the sender
734 will retry sending its packet. */
735 memset(reh->h_dest, 0xff, ETH_ALEN);
736 memcpy(reh->h_source, special_ethaddr, ETH_ALEN - 4);
737 memcpy(&reh->h_source[2], &vhost_addr, 4);
738 reh->h_proto = htons(ETH_P_ARP);
739 rah->ar_hrd = htons(1);
740 rah->ar_pro = htons(ETH_P_IP);
741 rah->ar_hln = ETH_ALEN;
742 rah->ar_pln = 4;
743 rah->ar_op = htons(ARPOP_REQUEST);
744 /* source hw addr */
745 memcpy(rah->ar_sha, special_ethaddr, ETH_ALEN - 4);
746 memcpy(&rah->ar_sha[2], &vhost_addr, 4);
747 /* source IP */
748 rah->ar_sip = vhost_addr.s_addr;
749 /* target hw addr (none) */
750 memset(rah->ar_tha, 0, ETH_ALEN);
751 /* target IP */
752 rah->ar_tip = iph->ip_dst.s_addr;
753 client_ipaddr = iph->ip_dst;
754 slirp_output(arp_req, sizeof(arp_req));
755 } else {
756 memcpy(eh->h_dest, client_ethaddr, ETH_ALEN);
757 memcpy(eh->h_source, special_ethaddr, ETH_ALEN - 4);
758 /* XXX: not correct */
759 memcpy(&eh->h_source[2], &vhost_addr, 4);
760 eh->h_proto = htons(ETH_P_IP);
761 memcpy(buf + sizeof(struct ethhdr), ip_data, ip_data_len);
762 slirp_output(buf, ip_data_len + ETH_HLEN);
766 /* Drop host forwarding rule, return 0 if found. */
767 int slirp_remove_hostfwd(int is_udp, struct in_addr host_addr, int host_port)
769 struct socket *so;
770 struct socket *head = (is_udp ? &udb : &tcb);
771 struct sockaddr_in addr;
772 int port = htons(host_port);
773 socklen_t addr_len;
775 for (so = head->so_next; so != head; so = so->so_next) {
776 addr_len = sizeof(addr);
777 if ((so->so_state & SS_HOSTFWD) &&
778 getsockname(so->s, (struct sockaddr *)&addr, &addr_len) == 0 &&
779 addr.sin_addr.s_addr == host_addr.s_addr &&
780 addr.sin_port == port) {
781 close(so->s);
782 sofree(so);
783 return 0;
787 return -1;
790 int slirp_add_hostfwd(int is_udp, struct in_addr host_addr, int host_port,
791 struct in_addr guest_addr, int guest_port)
793 if (!guest_addr.s_addr) {
794 guest_addr = vdhcp_startaddr;
796 if (is_udp) {
797 if (!udp_listen(host_addr.s_addr, htons(host_port), guest_addr.s_addr,
798 htons(guest_port), SS_HOSTFWD))
799 return -1;
800 } else {
801 if (!tcp_listen(host_addr.s_addr, htons(host_port), guest_addr.s_addr,
802 htons(guest_port), SS_HOSTFWD))
803 return -1;
805 return 0;
808 int slirp_add_exec(int do_pty, const void *args, struct in_addr guest_addr,
809 int guest_port)
811 if (!guest_addr.s_addr) {
812 guest_addr.s_addr =
813 vnetwork_addr.s_addr | (htonl(0x0204) & ~vnetwork_mask.s_addr);
815 if ((guest_addr.s_addr & vnetwork_mask.s_addr) != vnetwork_addr.s_addr ||
816 guest_addr.s_addr == vhost_addr.s_addr ||
817 guest_addr.s_addr == vnameserver_addr.s_addr) {
818 return -1;
820 return add_exec(&exec_list, do_pty, (char *)args, guest_addr,
821 htons(guest_port));
824 ssize_t slirp_send(struct socket *so, const void *buf, size_t len, int flags)
826 if (so->s == -1 && so->extra) {
827 qemu_chr_write(so->extra, buf, len);
828 return len;
831 return send(so->s, buf, len, flags);
834 static struct socket *
835 slirp_find_ctl_socket(struct in_addr guest_addr, int guest_port)
837 struct socket *so;
839 for (so = tcb.so_next; so != &tcb; so = so->so_next) {
840 if (so->so_faddr.s_addr == guest_addr.s_addr &&
841 htons(so->so_fport) == guest_port) {
842 return so;
845 return NULL;
848 size_t slirp_socket_can_recv(struct in_addr guest_addr, int guest_port)
850 struct iovec iov[2];
851 struct socket *so;
853 if (!link_up)
854 return 0;
856 so = slirp_find_ctl_socket(guest_addr, guest_port);
858 if (!so || so->so_state & SS_NOFDREF)
859 return 0;
861 if (!CONN_CANFRCV(so) || so->so_snd.sb_cc >= (so->so_snd.sb_datalen/2))
862 return 0;
864 return sopreprbuf(so, iov, NULL);
867 void slirp_socket_recv(struct in_addr guest_addr, int guest_port,
868 const uint8_t *buf, int size)
870 int ret;
871 struct socket *so = slirp_find_ctl_socket(guest_addr, guest_port);
873 if (!so)
874 return;
876 ret = soreadbuf(so, (const char *)buf, size);
878 if (ret > 0)
879 tcp_output(sototcpcb(so));
882 static void slirp_tcp_save(QEMUFile *f, struct tcpcb *tp)
884 int i;
886 qemu_put_sbe16(f, tp->t_state);
887 for (i = 0; i < TCPT_NTIMERS; i++)
888 qemu_put_sbe16(f, tp->t_timer[i]);
889 qemu_put_sbe16(f, tp->t_rxtshift);
890 qemu_put_sbe16(f, tp->t_rxtcur);
891 qemu_put_sbe16(f, tp->t_dupacks);
892 qemu_put_be16(f, tp->t_maxseg);
893 qemu_put_sbyte(f, tp->t_force);
894 qemu_put_be16(f, tp->t_flags);
895 qemu_put_be32(f, tp->snd_una);
896 qemu_put_be32(f, tp->snd_nxt);
897 qemu_put_be32(f, tp->snd_up);
898 qemu_put_be32(f, tp->snd_wl1);
899 qemu_put_be32(f, tp->snd_wl2);
900 qemu_put_be32(f, tp->iss);
901 qemu_put_be32(f, tp->snd_wnd);
902 qemu_put_be32(f, tp->rcv_wnd);
903 qemu_put_be32(f, tp->rcv_nxt);
904 qemu_put_be32(f, tp->rcv_up);
905 qemu_put_be32(f, tp->irs);
906 qemu_put_be32(f, tp->rcv_adv);
907 qemu_put_be32(f, tp->snd_max);
908 qemu_put_be32(f, tp->snd_cwnd);
909 qemu_put_be32(f, tp->snd_ssthresh);
910 qemu_put_sbe16(f, tp->t_idle);
911 qemu_put_sbe16(f, tp->t_rtt);
912 qemu_put_be32(f, tp->t_rtseq);
913 qemu_put_sbe16(f, tp->t_srtt);
914 qemu_put_sbe16(f, tp->t_rttvar);
915 qemu_put_be16(f, tp->t_rttmin);
916 qemu_put_be32(f, tp->max_sndwnd);
917 qemu_put_byte(f, tp->t_oobflags);
918 qemu_put_byte(f, tp->t_iobc);
919 qemu_put_sbe16(f, tp->t_softerror);
920 qemu_put_byte(f, tp->snd_scale);
921 qemu_put_byte(f, tp->rcv_scale);
922 qemu_put_byte(f, tp->request_r_scale);
923 qemu_put_byte(f, tp->requested_s_scale);
924 qemu_put_be32(f, tp->ts_recent);
925 qemu_put_be32(f, tp->ts_recent_age);
926 qemu_put_be32(f, tp->last_ack_sent);
929 static void slirp_sbuf_save(QEMUFile *f, struct sbuf *sbuf)
931 uint32_t off;
933 qemu_put_be32(f, sbuf->sb_cc);
934 qemu_put_be32(f, sbuf->sb_datalen);
935 off = (uint32_t)(sbuf->sb_wptr - sbuf->sb_data);
936 qemu_put_sbe32(f, off);
937 off = (uint32_t)(sbuf->sb_rptr - sbuf->sb_data);
938 qemu_put_sbe32(f, off);
939 qemu_put_buffer(f, (unsigned char*)sbuf->sb_data, sbuf->sb_datalen);
942 static void slirp_socket_save(QEMUFile *f, struct socket *so)
944 qemu_put_be32(f, so->so_urgc);
945 qemu_put_be32(f, so->so_faddr.s_addr);
946 qemu_put_be32(f, so->so_laddr.s_addr);
947 qemu_put_be16(f, so->so_fport);
948 qemu_put_be16(f, so->so_lport);
949 qemu_put_byte(f, so->so_iptos);
950 qemu_put_byte(f, so->so_emu);
951 qemu_put_byte(f, so->so_type);
952 qemu_put_be32(f, so->so_state);
953 slirp_sbuf_save(f, &so->so_rcv);
954 slirp_sbuf_save(f, &so->so_snd);
955 slirp_tcp_save(f, so->so_tcpcb);
958 static void slirp_state_save(QEMUFile *f, void *opaque)
960 struct ex_list *ex_ptr;
962 for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next)
963 if (ex_ptr->ex_pty == 3) {
964 struct socket *so;
965 so = slirp_find_ctl_socket(ex_ptr->ex_addr, ntohs(ex_ptr->ex_fport));
966 if (!so)
967 continue;
969 qemu_put_byte(f, 42);
970 slirp_socket_save(f, so);
972 qemu_put_byte(f, 0);
974 qemu_put_be16(f, ip_id);
977 static void slirp_tcp_load(QEMUFile *f, struct tcpcb *tp)
979 int i;
981 tp->t_state = qemu_get_sbe16(f);
982 for (i = 0; i < TCPT_NTIMERS; i++)
983 tp->t_timer[i] = qemu_get_sbe16(f);
984 tp->t_rxtshift = qemu_get_sbe16(f);
985 tp->t_rxtcur = qemu_get_sbe16(f);
986 tp->t_dupacks = qemu_get_sbe16(f);
987 tp->t_maxseg = qemu_get_be16(f);
988 tp->t_force = qemu_get_sbyte(f);
989 tp->t_flags = qemu_get_be16(f);
990 tp->snd_una = qemu_get_be32(f);
991 tp->snd_nxt = qemu_get_be32(f);
992 tp->snd_up = qemu_get_be32(f);
993 tp->snd_wl1 = qemu_get_be32(f);
994 tp->snd_wl2 = qemu_get_be32(f);
995 tp->iss = qemu_get_be32(f);
996 tp->snd_wnd = qemu_get_be32(f);
997 tp->rcv_wnd = qemu_get_be32(f);
998 tp->rcv_nxt = qemu_get_be32(f);
999 tp->rcv_up = qemu_get_be32(f);
1000 tp->irs = qemu_get_be32(f);
1001 tp->rcv_adv = qemu_get_be32(f);
1002 tp->snd_max = qemu_get_be32(f);
1003 tp->snd_cwnd = qemu_get_be32(f);
1004 tp->snd_ssthresh = qemu_get_be32(f);
1005 tp->t_idle = qemu_get_sbe16(f);
1006 tp->t_rtt = qemu_get_sbe16(f);
1007 tp->t_rtseq = qemu_get_be32(f);
1008 tp->t_srtt = qemu_get_sbe16(f);
1009 tp->t_rttvar = qemu_get_sbe16(f);
1010 tp->t_rttmin = qemu_get_be16(f);
1011 tp->max_sndwnd = qemu_get_be32(f);
1012 tp->t_oobflags = qemu_get_byte(f);
1013 tp->t_iobc = qemu_get_byte(f);
1014 tp->t_softerror = qemu_get_sbe16(f);
1015 tp->snd_scale = qemu_get_byte(f);
1016 tp->rcv_scale = qemu_get_byte(f);
1017 tp->request_r_scale = qemu_get_byte(f);
1018 tp->requested_s_scale = qemu_get_byte(f);
1019 tp->ts_recent = qemu_get_be32(f);
1020 tp->ts_recent_age = qemu_get_be32(f);
1021 tp->last_ack_sent = qemu_get_be32(f);
1022 tcp_template(tp);
1025 static int slirp_sbuf_load(QEMUFile *f, struct sbuf *sbuf)
1027 uint32_t off, sb_cc, sb_datalen;
1029 sb_cc = qemu_get_be32(f);
1030 sb_datalen = qemu_get_be32(f);
1032 sbreserve(sbuf, sb_datalen);
1034 if (sbuf->sb_datalen != sb_datalen)
1035 return -ENOMEM;
1037 sbuf->sb_cc = sb_cc;
1039 off = qemu_get_sbe32(f);
1040 sbuf->sb_wptr = sbuf->sb_data + off;
1041 off = qemu_get_sbe32(f);
1042 sbuf->sb_rptr = sbuf->sb_data + off;
1043 qemu_get_buffer(f, (unsigned char*)sbuf->sb_data, sbuf->sb_datalen);
1045 return 0;
1048 static int slirp_socket_load(QEMUFile *f, struct socket *so)
1050 if (tcp_attach(so) < 0)
1051 return -ENOMEM;
1053 so->so_urgc = qemu_get_be32(f);
1054 so->so_faddr.s_addr = qemu_get_be32(f);
1055 so->so_laddr.s_addr = qemu_get_be32(f);
1056 so->so_fport = qemu_get_be16(f);
1057 so->so_lport = qemu_get_be16(f);
1058 so->so_iptos = qemu_get_byte(f);
1059 so->so_emu = qemu_get_byte(f);
1060 so->so_type = qemu_get_byte(f);
1061 so->so_state = qemu_get_be32(f);
1062 if (slirp_sbuf_load(f, &so->so_rcv) < 0)
1063 return -ENOMEM;
1064 if (slirp_sbuf_load(f, &so->so_snd) < 0)
1065 return -ENOMEM;
1066 slirp_tcp_load(f, so->so_tcpcb);
1068 return 0;
1071 static int slirp_state_load(QEMUFile *f, void *opaque, int version_id)
1073 struct ex_list *ex_ptr;
1074 int r;
1076 while ((r = qemu_get_byte(f))) {
1077 int ret;
1078 struct socket *so = socreate();
1080 if (!so)
1081 return -ENOMEM;
1083 ret = slirp_socket_load(f, so);
1085 if (ret < 0)
1086 return ret;
1088 if ((so->so_faddr.s_addr & vnetwork_mask.s_addr) !=
1089 vnetwork_addr.s_addr) {
1090 return -EINVAL;
1092 for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
1093 if (ex_ptr->ex_pty == 3 &&
1094 so->so_faddr.s_addr == ex_ptr->ex_addr.s_addr &&
1095 so->so_fport == ex_ptr->ex_fport) {
1096 break;
1099 if (!ex_ptr)
1100 return -EINVAL;
1102 so->extra = (void *)ex_ptr->ex_exec;
1105 if (version_id >= 2) {
1106 ip_id = qemu_get_be16(f);
1109 return 0;