slirp: Kill slirp_is_inited
[qemu/qemu-dev-zwu.git] / slirp / slirp.c
blobcf52d36ece42d7d9190a3b492af8c9fac5e80e69
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 if (!link_up) {
275 return;
278 /* fail safe */
279 global_readfds = NULL;
280 global_writefds = NULL;
281 global_xfds = NULL;
283 nfds = *pnfds;
285 * First, TCP sockets
287 do_slowtimo = 0;
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)
310 continue;
313 * Set for reading sockets which are accepting
315 if (so->so_state & SS_FACCEPTCONN) {
316 FD_SET(so->s, readfds);
317 UPD_NFDS(so->s);
318 continue;
322 * Set for writing sockets which are connecting
324 if (so->so_state & SS_ISFCONNECTING) {
325 FD_SET(so->s, writefds);
326 UPD_NFDS(so->s);
327 continue;
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);
336 UPD_NFDS(so->s);
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);
345 FD_SET(so->s, xfds);
346 UPD_NFDS(so->s);
351 * UDP sockets
353 for (so = udb.so_next; so != &udb; so = so_next) {
354 so_next = so->so_next;
357 * See if it's timed out
359 if (so->so_expire) {
360 if (so->so_expire <= curtime) {
361 udp_detach(so);
362 continue;
363 } else
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
375 * (XXX <= 4 ?)
377 if ((so->so_state & SS_ISFCONNECTED) && so->so_queued <= 4) {
378 FD_SET(so->s, readfds);
379 UPD_NFDS(so->s);
384 * Setup timeout to use minimum CPU usage, especially when idle
388 * First, see the timeout needed by *timo
390 timeout.tv_sec = 0;
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.
397 if (do_slowtimo) {
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)
401 timeout.tv_usec = 0;
402 else if (timeout.tv_usec > 510000)
403 timeout.tv_usec = 510000;
405 /* Can only fasttimo if we also slowtimo */
406 if (time_fasttimo) {
407 tmp_time = (200 - (curtime - time_fasttimo)) * 1000;
408 if (tmp_time < 0)
409 tmp_time = 0;
411 /* Choose the smallest of the 2 */
412 if (tmp_time < timeout.tv_usec)
413 timeout.tv_usec = (u_int)tmp_time;
416 *pnfds = nfds;
419 void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds,
420 int select_error)
422 struct socket *so, *so_next;
423 int ret;
425 if (!link_up) {
426 return;
429 global_readfds = readfds;
430 global_writefds = writefds;
431 global_xfds = xfds;
433 /* Update time */
434 updtime();
437 * See if anything has timed out
439 if (time_fasttimo && ((curtime - time_fasttimo) >= 2)) {
440 tcp_fasttimo();
441 time_fasttimo = 0;
443 if (do_slowtimo && ((curtime - last_slowtimo) >= 499)) {
444 ip_slowtimo();
445 tcp_slowtimo();
446 last_slowtimo = curtime;
450 * Check sockets
452 if (!select_error) {
454 * Check TCP sockets
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)
464 continue;
467 * Check for URG data
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))
472 sorecvoob(so);
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) {
481 tcp_connect(so);
482 continue;
483 } /* else */
484 ret = soread(so);
486 /* Output it if we read something */
487 if (ret > 0)
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) {
499 /* Connected */
500 so->so_state &= ~SS_ISFCONNECTING;
502 ret = send(so->s, (const void *) &ret, 0, 0);
503 if (ret < 0) {
504 /* XXXXX Must fix, zero bytes is a NOP */
505 if (errno == EAGAIN || errno == EWOULDBLOCK ||
506 errno == EINPROGRESS || errno == ENOTCONN)
507 continue;
509 /* else failed */
510 so->so_state &= SS_PERSISTENT_MASK;
511 so->so_state |= SS_NOFDREF;
513 /* else so->so_state &= ~SS_ISFCONNECTING; */
516 * Continue tcp_input
518 tcp_input((struct mbuf *)NULL, sizeof(struct ip), so);
519 /* continue; */
520 } else
521 ret = sowrite(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
534 #ifdef PROBE_CONN
535 if (so->so_state & SS_ISFCONNECTING) {
536 ret = recv(so->s, (char *)&ret, 0,0);
538 if (ret < 0) {
539 /* XXX */
540 if (errno == EAGAIN || errno == EWOULDBLOCK ||
541 errno == EINPROGRESS || errno == ENOTCONN)
542 continue; /* Still connecting, continue */
544 /* else failed */
545 so->so_state &= SS_PERSISTENT_MASK;
546 so->so_state |= SS_NOFDREF;
548 /* tcp_input will take care of it */
549 } else {
550 ret = send(so->s, &ret, 0,0);
551 if (ret < 0) {
552 /* XXX */
553 if (errno == EAGAIN || errno == EWOULDBLOCK ||
554 errno == EINPROGRESS || errno == ENOTCONN)
555 continue;
556 /* else failed */
557 so->so_state &= SS_PERSISTENT_MASK;
558 so->so_state |= SS_NOFDREF;
559 } else
560 so->so_state &= ~SS_ISFCONNECTING;
563 tcp_input((struct mbuf *)NULL, sizeof(struct ip),so);
564 } /* SS_ISFCONNECTING */
565 #endif
569 * Now UDP sockets.
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)) {
577 sorecvfrom(so);
583 * See if we can start outputting
585 if (if_queued)
586 if_start();
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;
595 global_xfds = NULL;
598 #define ETH_ALEN 6
599 #define ETH_HLEN 14
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 */
607 struct ethhdr
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 */
614 struct arphdr
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);
638 int ar_op;
639 struct ex_list *ex_ptr;
641 ar_op = ntohs(ah->ar_op);
642 switch(ar_op) {
643 case ARPOP_REQUEST:
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)
647 goto arp_ok;
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)
650 goto arp_ok;
652 return;
653 arp_ok:
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;
666 rah->ar_pln = 4;
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));
674 break;
675 case ARPOP_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);
681 break;
682 default:
683 break;
687 void slirp_input(const uint8_t *pkt, int pkt_len)
689 struct mbuf *m;
690 int proto;
692 if (pkt_len < ETH_HLEN)
693 return;
695 proto = ntohs(*(uint16_t *)(pkt + 12));
696 switch(proto) {
697 case ETH_P_ARP:
698 arp_input(pkt, pkt_len);
699 break;
700 case ETH_P_IP:
701 m = m_get();
702 if (!m)
703 return;
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;
714 ip_input(m);
715 break;
716 default:
717 break;
721 /* output the IP packet to the ethernet device */
722 void if_encap(const uint8_t *ip_data, int ip_data_len)
724 uint8_t buf[1600];
725 struct ethhdr *eh = (struct ethhdr *)buf;
727 if (ip_data_len + ETH_HLEN > sizeof(buf))
728 return;
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;
748 rah->ar_pln = 4;
749 rah->ar_op = htons(ARPOP_REQUEST);
750 /* source hw addr */
751 memcpy(rah->ar_sha, special_ethaddr, ETH_ALEN - 4);
752 memcpy(&rah->ar_sha[2], &vhost_addr, 4);
753 /* source IP */
754 rah->ar_sip = vhost_addr.s_addr;
755 /* target hw addr (none) */
756 memset(rah->ar_tha, 0, ETH_ALEN);
757 /* target IP */
758 rah->ar_tip = iph->ip_dst.s_addr;
759 client_ipaddr = iph->ip_dst;
760 slirp_output(arp_req, sizeof(arp_req));
761 } else {
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)
775 struct socket *so;
776 struct socket *head = (is_udp ? &udb : &tcb);
777 struct sockaddr_in addr;
778 int port = htons(host_port);
779 socklen_t addr_len;
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) {
787 close(so->s);
788 sofree(so);
789 return 0;
793 return -1;
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;
802 if (is_udp) {
803 if (!udp_listen(host_addr.s_addr, htons(host_port), guest_addr.s_addr,
804 htons(guest_port), SS_HOSTFWD))
805 return -1;
806 } else {
807 if (!tcp_listen(host_addr.s_addr, htons(host_port), guest_addr.s_addr,
808 htons(guest_port), SS_HOSTFWD))
809 return -1;
811 return 0;
814 int slirp_add_exec(int do_pty, const void *args, struct in_addr guest_addr,
815 int guest_port)
817 if (!guest_addr.s_addr) {
818 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) {
824 return -1;
826 return add_exec(&exec_list, do_pty, (char *)args, guest_addr,
827 htons(guest_port));
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);
834 return 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)
843 struct socket *so;
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) {
848 return so;
851 return NULL;
854 size_t slirp_socket_can_recv(struct in_addr guest_addr, int guest_port)
856 struct iovec iov[2];
857 struct socket *so;
859 if (!link_up)
860 return 0;
862 so = slirp_find_ctl_socket(guest_addr, guest_port);
864 if (!so || so->so_state & SS_NOFDREF)
865 return 0;
867 if (!CONN_CANFRCV(so) || so->so_snd.sb_cc >= (so->so_snd.sb_datalen/2))
868 return 0;
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)
876 int ret;
877 struct socket *so = slirp_find_ctl_socket(guest_addr, guest_port);
879 if (!so)
880 return;
882 ret = soreadbuf(so, (const char *)buf, size);
884 if (ret > 0)
885 tcp_output(sototcpcb(so));
888 static void slirp_tcp_save(QEMUFile *f, struct tcpcb *tp)
890 int i;
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)
937 uint32_t off;
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) {
970 struct socket *so;
971 so = slirp_find_ctl_socket(ex_ptr->ex_addr, ntohs(ex_ptr->ex_fport));
972 if (!so)
973 continue;
975 qemu_put_byte(f, 42);
976 slirp_socket_save(f, so);
978 qemu_put_byte(f, 0);
980 qemu_put_be16(f, ip_id);
983 static void slirp_tcp_load(QEMUFile *f, struct tcpcb *tp)
985 int i;
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);
1028 tcp_template(tp);
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)
1041 return -ENOMEM;
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);
1051 return 0;
1054 static int slirp_socket_load(QEMUFile *f, struct socket *so)
1056 if (tcp_attach(so) < 0)
1057 return -ENOMEM;
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)
1069 return -ENOMEM;
1070 if (slirp_sbuf_load(f, &so->so_snd) < 0)
1071 return -ENOMEM;
1072 slirp_tcp_load(f, so->so_tcpcb);
1074 return 0;
1077 static int slirp_state_load(QEMUFile *f, void *opaque, int version_id)
1079 struct ex_list *ex_ptr;
1080 int r;
1082 while ((r = qemu_get_byte(f))) {
1083 int ret;
1084 struct socket *so = socreate();
1086 if (!so)
1087 return -ENOMEM;
1089 ret = slirp_socket_load(f, so);
1091 if (ret < 0)
1092 return ret;
1094 if ((so->so_faddr.s_addr & vnetwork_mask.s_addr) !=
1095 vnetwork_addr.s_addr) {
1096 return -EINVAL;
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) {
1102 break;
1105 if (!ex_ptr)
1106 return -EINVAL;
1108 so->extra = (void *)ex_ptr->ex_exec;
1111 if (version_id >= 2) {
1112 ip_id = qemu_get_be16(f);
1115 return 0;