Wrap recv to avoid warnings
[qemu.git] / slirp / slirp.c
blobdf787ea1d923525d225e8678ae462d3b5b0a0d88
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-timer.h"
26 #include "qemu-char.h"
27 #include "slirp.h"
28 #include "hw/hw.h"
30 /* host loopback address */
31 struct in_addr loopback_addr;
33 /* emulated hosts use the MAC addr 52:55:IP:IP:IP:IP */
34 static const uint8_t special_ethaddr[6] = {
35 0x52, 0x55, 0x00, 0x00, 0x00, 0x00
38 static const uint8_t zero_ethaddr[6] = { 0, 0, 0, 0, 0, 0 };
40 /* XXX: suppress those select globals */
41 fd_set *global_readfds, *global_writefds, *global_xfds;
43 u_int curtime;
44 static u_int time_fasttimo, last_slowtimo;
45 static int do_slowtimo;
47 static QTAILQ_HEAD(slirp_instances, Slirp) slirp_instances =
48 QTAILQ_HEAD_INITIALIZER(slirp_instances);
50 static struct in_addr dns_addr;
51 static u_int dns_addr_time;
53 #ifdef _WIN32
55 int get_dns_addr(struct in_addr *pdns_addr)
57 FIXED_INFO *FixedInfo=NULL;
58 ULONG BufLen;
59 DWORD ret;
60 IP_ADDR_STRING *pIPAddr;
61 struct in_addr tmp_addr;
63 if (dns_addr.s_addr != 0 && (curtime - dns_addr_time) < 1000) {
64 *pdns_addr = dns_addr;
65 return 0;
68 FixedInfo = (FIXED_INFO *)GlobalAlloc(GPTR, sizeof(FIXED_INFO));
69 BufLen = sizeof(FIXED_INFO);
71 if (ERROR_BUFFER_OVERFLOW == GetNetworkParams(FixedInfo, &BufLen)) {
72 if (FixedInfo) {
73 GlobalFree(FixedInfo);
74 FixedInfo = NULL;
76 FixedInfo = GlobalAlloc(GPTR, BufLen);
79 if ((ret = GetNetworkParams(FixedInfo, &BufLen)) != ERROR_SUCCESS) {
80 printf("GetNetworkParams failed. ret = %08x\n", (u_int)ret );
81 if (FixedInfo) {
82 GlobalFree(FixedInfo);
83 FixedInfo = NULL;
85 return -1;
88 pIPAddr = &(FixedInfo->DnsServerList);
89 inet_aton(pIPAddr->IpAddress.String, &tmp_addr);
90 *pdns_addr = tmp_addr;
91 dns_addr = tmp_addr;
92 dns_addr_time = curtime;
93 if (FixedInfo) {
94 GlobalFree(FixedInfo);
95 FixedInfo = NULL;
97 return 0;
100 static void winsock_cleanup(void)
102 WSACleanup();
105 #else
107 static struct stat dns_addr_stat;
109 int get_dns_addr(struct in_addr *pdns_addr)
111 char buff[512];
112 char buff2[257];
113 FILE *f;
114 int found = 0;
115 struct in_addr tmp_addr;
117 if (dns_addr.s_addr != 0) {
118 struct stat old_stat;
119 if ((curtime - dns_addr_time) < 1000) {
120 *pdns_addr = dns_addr;
121 return 0;
123 old_stat = dns_addr_stat;
124 if (stat("/etc/resolv.conf", &dns_addr_stat) != 0)
125 return -1;
126 if ((dns_addr_stat.st_dev == old_stat.st_dev)
127 && (dns_addr_stat.st_ino == old_stat.st_ino)
128 && (dns_addr_stat.st_size == old_stat.st_size)
129 && (dns_addr_stat.st_mtime == old_stat.st_mtime)) {
130 *pdns_addr = dns_addr;
131 return 0;
135 f = fopen("/etc/resolv.conf", "r");
136 if (!f)
137 return -1;
139 #ifdef DEBUG
140 lprint("IP address of your DNS(s): ");
141 #endif
142 while (fgets(buff, 512, f) != NULL) {
143 if (sscanf(buff, "nameserver%*[ \t]%256s", buff2) == 1) {
144 if (!inet_aton(buff2, &tmp_addr))
145 continue;
146 /* If it's the first one, set it to dns_addr */
147 if (!found) {
148 *pdns_addr = tmp_addr;
149 dns_addr = tmp_addr;
150 dns_addr_time = curtime;
152 #ifdef DEBUG
153 else
154 lprint(", ");
155 #endif
156 if (++found > 3) {
157 #ifdef DEBUG
158 lprint("(more)");
159 #endif
160 break;
162 #ifdef DEBUG
163 else
164 lprint("%s", inet_ntoa(tmp_addr));
165 #endif
168 fclose(f);
169 if (!found)
170 return -1;
171 return 0;
174 #endif
176 static void slirp_init_once(void)
178 static int initialized;
179 #ifdef _WIN32
180 WSADATA Data;
181 #endif
183 if (initialized) {
184 return;
186 initialized = 1;
188 #ifdef _WIN32
189 WSAStartup(MAKEWORD(2,0), &Data);
190 atexit(winsock_cleanup);
191 #endif
193 loopback_addr.s_addr = htonl(INADDR_LOOPBACK);
196 static void slirp_state_save(QEMUFile *f, void *opaque);
197 static int slirp_state_load(QEMUFile *f, void *opaque, int version_id);
199 Slirp *slirp_init(int restricted, struct in_addr vnetwork,
200 struct in_addr vnetmask, struct in_addr vhost,
201 const char *vhostname, const char *tftp_path,
202 const char *bootfile, struct in_addr vdhcp_start,
203 struct in_addr vnameserver, void *opaque)
205 Slirp *slirp = qemu_mallocz(sizeof(Slirp));
207 slirp_init_once();
209 slirp->restricted = restricted;
211 if_init(slirp);
212 ip_init(slirp);
214 /* Initialise mbufs *after* setting the MTU */
215 m_init(slirp);
217 slirp->vnetwork_addr = vnetwork;
218 slirp->vnetwork_mask = vnetmask;
219 slirp->vhost_addr = vhost;
220 if (vhostname) {
221 pstrcpy(slirp->client_hostname, sizeof(slirp->client_hostname),
222 vhostname);
224 if (tftp_path) {
225 slirp->tftp_prefix = qemu_strdup(tftp_path);
227 if (bootfile) {
228 slirp->bootp_filename = qemu_strdup(bootfile);
230 slirp->vdhcp_startaddr = vdhcp_start;
231 slirp->vnameserver_addr = vnameserver;
233 slirp->opaque = opaque;
235 register_savevm(NULL, "slirp", 0, 3,
236 slirp_state_save, slirp_state_load, slirp);
238 QTAILQ_INSERT_TAIL(&slirp_instances, slirp, entry);
240 return slirp;
243 void slirp_cleanup(Slirp *slirp)
245 QTAILQ_REMOVE(&slirp_instances, slirp, entry);
247 unregister_savevm(NULL, "slirp", slirp);
249 qemu_free(slirp->tftp_prefix);
250 qemu_free(slirp->bootp_filename);
251 qemu_free(slirp);
254 #define CONN_CANFSEND(so) (((so)->so_state & (SS_FCANTSENDMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED)
255 #define CONN_CANFRCV(so) (((so)->so_state & (SS_FCANTRCVMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED)
256 #define UPD_NFDS(x) if (nfds < (x)) nfds = (x)
258 void slirp_select_fill(int *pnfds,
259 fd_set *readfds, fd_set *writefds, fd_set *xfds)
261 Slirp *slirp;
262 struct socket *so, *so_next;
263 int nfds;
265 if (QTAILQ_EMPTY(&slirp_instances)) {
266 return;
269 /* fail safe */
270 global_readfds = NULL;
271 global_writefds = NULL;
272 global_xfds = NULL;
274 nfds = *pnfds;
276 * First, TCP sockets
278 do_slowtimo = 0;
280 QTAILQ_FOREACH(slirp, &slirp_instances, entry) {
282 * *_slowtimo needs calling if there are IP fragments
283 * in the fragment queue, or there are TCP connections active
285 do_slowtimo |= ((slirp->tcb.so_next != &slirp->tcb) ||
286 (&slirp->ipq.ip_link != slirp->ipq.ip_link.next));
288 for (so = slirp->tcb.so_next; so != &slirp->tcb;
289 so = so_next) {
290 so_next = so->so_next;
293 * See if we need a tcp_fasttimo
295 if (time_fasttimo == 0 && so->so_tcpcb->t_flags & TF_DELACK)
296 time_fasttimo = curtime; /* Flag when we want a fasttimo */
299 * NOFDREF can include still connecting to local-host,
300 * newly socreated() sockets etc. Don't want to select these.
302 if (so->so_state & SS_NOFDREF || so->s == -1)
303 continue;
306 * Set for reading sockets which are accepting
308 if (so->so_state & SS_FACCEPTCONN) {
309 FD_SET(so->s, readfds);
310 UPD_NFDS(so->s);
311 continue;
315 * Set for writing sockets which are connecting
317 if (so->so_state & SS_ISFCONNECTING) {
318 FD_SET(so->s, writefds);
319 UPD_NFDS(so->s);
320 continue;
324 * Set for writing if we are connected, can send more, and
325 * we have something to send
327 if (CONN_CANFSEND(so) && so->so_rcv.sb_cc) {
328 FD_SET(so->s, writefds);
329 UPD_NFDS(so->s);
333 * Set for reading (and urgent data) if we are connected, can
334 * receive more, and we have room for it XXX /2 ?
336 if (CONN_CANFRCV(so) && (so->so_snd.sb_cc < (so->so_snd.sb_datalen/2))) {
337 FD_SET(so->s, readfds);
338 FD_SET(so->s, xfds);
339 UPD_NFDS(so->s);
344 * UDP sockets
346 for (so = slirp->udb.so_next; so != &slirp->udb;
347 so = so_next) {
348 so_next = so->so_next;
351 * See if it's timed out
353 if (so->so_expire) {
354 if (so->so_expire <= curtime) {
355 udp_detach(so);
356 continue;
357 } else
358 do_slowtimo = 1; /* Let socket expire */
362 * When UDP packets are received from over the
363 * link, they're sendto()'d straight away, so
364 * no need for setting for writing
365 * Limit the number of packets queued by this session
366 * to 4. Note that even though we try and limit this
367 * to 4 packets, the session could have more queued
368 * if the packets needed to be fragmented
369 * (XXX <= 4 ?)
371 if ((so->so_state & SS_ISFCONNECTED) && so->so_queued <= 4) {
372 FD_SET(so->s, readfds);
373 UPD_NFDS(so->s);
378 * ICMP sockets
380 for (so = slirp->icmp.so_next; so != &slirp->icmp;
381 so = so_next) {
382 so_next = so->so_next;
385 * See if it's timed out
387 if (so->so_expire) {
388 if (so->so_expire <= curtime) {
389 icmp_detach(so);
390 continue;
391 } else {
392 do_slowtimo = 1; /* Let socket expire */
396 if (so->so_state & SS_ISFCONNECTED) {
397 FD_SET(so->s, readfds);
398 UPD_NFDS(so->s);
403 *pnfds = nfds;
406 void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds,
407 int select_error)
409 Slirp *slirp;
410 struct socket *so, *so_next;
411 int ret;
413 if (QTAILQ_EMPTY(&slirp_instances)) {
414 return;
417 global_readfds = readfds;
418 global_writefds = writefds;
419 global_xfds = xfds;
421 curtime = qemu_get_clock_ms(rt_clock);
423 QTAILQ_FOREACH(slirp, &slirp_instances, entry) {
425 * See if anything has timed out
427 if (time_fasttimo && ((curtime - time_fasttimo) >= 2)) {
428 tcp_fasttimo(slirp);
429 time_fasttimo = 0;
431 if (do_slowtimo && ((curtime - last_slowtimo) >= 499)) {
432 ip_slowtimo(slirp);
433 tcp_slowtimo(slirp);
434 last_slowtimo = curtime;
438 * Check sockets
440 if (!select_error) {
442 * Check TCP sockets
444 for (so = slirp->tcb.so_next; so != &slirp->tcb;
445 so = so_next) {
446 so_next = so->so_next;
449 * FD_ISSET is meaningless on these sockets
450 * (and they can crash the program)
452 if (so->so_state & SS_NOFDREF || so->s == -1)
453 continue;
456 * Check for URG data
457 * This will soread as well, so no need to
458 * test for readfds below if this succeeds
460 if (FD_ISSET(so->s, xfds))
461 sorecvoob(so);
463 * Check sockets for reading
465 else if (FD_ISSET(so->s, readfds)) {
467 * Check for incoming connections
469 if (so->so_state & SS_FACCEPTCONN) {
470 tcp_connect(so);
471 continue;
472 } /* else */
473 ret = soread(so);
475 /* Output it if we read something */
476 if (ret > 0)
477 tcp_output(sototcpcb(so));
481 * Check sockets for writing
483 if (FD_ISSET(so->s, writefds)) {
485 * Check for non-blocking, still-connecting sockets
487 if (so->so_state & SS_ISFCONNECTING) {
488 /* Connected */
489 so->so_state &= ~SS_ISFCONNECTING;
491 ret = send(so->s, (const void *) &ret, 0, 0);
492 if (ret < 0) {
493 /* XXXXX Must fix, zero bytes is a NOP */
494 if (errno == EAGAIN || errno == EWOULDBLOCK ||
495 errno == EINPROGRESS || errno == ENOTCONN)
496 continue;
498 /* else failed */
499 so->so_state &= SS_PERSISTENT_MASK;
500 so->so_state |= SS_NOFDREF;
502 /* else so->so_state &= ~SS_ISFCONNECTING; */
505 * Continue tcp_input
507 tcp_input((struct mbuf *)NULL, sizeof(struct ip), so);
508 /* continue; */
509 } else
510 ret = sowrite(so);
512 * XXXXX If we wrote something (a lot), there
513 * could be a need for a window update.
514 * In the worst case, the remote will send
515 * a window probe to get things going again
520 * Probe a still-connecting, non-blocking socket
521 * to check if it's still alive
523 #ifdef PROBE_CONN
524 if (so->so_state & SS_ISFCONNECTING) {
525 ret = qemu_recv(so->s, &ret, 0,0);
527 if (ret < 0) {
528 /* XXX */
529 if (errno == EAGAIN || errno == EWOULDBLOCK ||
530 errno == EINPROGRESS || errno == ENOTCONN)
531 continue; /* Still connecting, continue */
533 /* else failed */
534 so->so_state &= SS_PERSISTENT_MASK;
535 so->so_state |= SS_NOFDREF;
537 /* tcp_input will take care of it */
538 } else {
539 ret = send(so->s, &ret, 0,0);
540 if (ret < 0) {
541 /* XXX */
542 if (errno == EAGAIN || errno == EWOULDBLOCK ||
543 errno == EINPROGRESS || errno == ENOTCONN)
544 continue;
545 /* else failed */
546 so->so_state &= SS_PERSISTENT_MASK;
547 so->so_state |= SS_NOFDREF;
548 } else
549 so->so_state &= ~SS_ISFCONNECTING;
552 tcp_input((struct mbuf *)NULL, sizeof(struct ip),so);
553 } /* SS_ISFCONNECTING */
554 #endif
558 * Now UDP sockets.
559 * Incoming packets are sent straight away, they're not buffered.
560 * Incoming UDP data isn't buffered either.
562 for (so = slirp->udb.so_next; so != &slirp->udb;
563 so = so_next) {
564 so_next = so->so_next;
566 if (so->s != -1 && FD_ISSET(so->s, readfds)) {
567 sorecvfrom(so);
572 * Check incoming ICMP relies.
574 for (so = slirp->icmp.so_next; so != &slirp->icmp;
575 so = so_next) {
576 so_next = so->so_next;
578 if (so->s != -1 && FD_ISSET(so->s, readfds)) {
579 icmp_receive(so);
585 * See if we can start outputting
587 if (slirp->if_queued) {
588 if_start(slirp);
592 /* clear global file descriptor sets.
593 * these reside on the stack in vl.c
594 * so they're unusable if we're not in
595 * slirp_select_fill or slirp_select_poll.
597 global_readfds = NULL;
598 global_writefds = NULL;
599 global_xfds = NULL;
602 #define ETH_ALEN 6
603 #define ETH_HLEN 14
605 #define ETH_P_IP 0x0800 /* Internet Protocol packet */
606 #define ETH_P_ARP 0x0806 /* Address Resolution packet */
608 #define ARPOP_REQUEST 1 /* ARP request */
609 #define ARPOP_REPLY 2 /* ARP reply */
611 struct ethhdr
613 unsigned char h_dest[ETH_ALEN]; /* destination eth addr */
614 unsigned char h_source[ETH_ALEN]; /* source ether addr */
615 unsigned short h_proto; /* packet type ID field */
618 struct arphdr
620 unsigned short ar_hrd; /* format of hardware address */
621 unsigned short ar_pro; /* format of protocol address */
622 unsigned char ar_hln; /* length of hardware address */
623 unsigned char ar_pln; /* length of protocol address */
624 unsigned short ar_op; /* ARP opcode (command) */
627 * Ethernet looks like this : This bit is variable sized however...
629 unsigned char ar_sha[ETH_ALEN]; /* sender hardware address */
630 uint32_t ar_sip; /* sender IP address */
631 unsigned char ar_tha[ETH_ALEN]; /* target hardware address */
632 uint32_t ar_tip ; /* target IP address */
633 } __attribute__((packed));
635 static void arp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len)
637 struct ethhdr *eh = (struct ethhdr *)pkt;
638 struct arphdr *ah = (struct arphdr *)(pkt + ETH_HLEN);
639 uint8_t arp_reply[max(ETH_HLEN + sizeof(struct arphdr), 64)];
640 struct ethhdr *reh = (struct ethhdr *)arp_reply;
641 struct arphdr *rah = (struct arphdr *)(arp_reply + ETH_HLEN);
642 int ar_op;
643 struct ex_list *ex_ptr;
645 ar_op = ntohs(ah->ar_op);
646 switch(ar_op) {
647 case ARPOP_REQUEST:
648 if ((ah->ar_tip & slirp->vnetwork_mask.s_addr) ==
649 slirp->vnetwork_addr.s_addr) {
650 if (ah->ar_tip == slirp->vnameserver_addr.s_addr ||
651 ah->ar_tip == slirp->vhost_addr.s_addr)
652 goto arp_ok;
653 for (ex_ptr = slirp->exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
654 if (ex_ptr->ex_addr.s_addr == ah->ar_tip)
655 goto arp_ok;
657 return;
658 arp_ok:
659 memset(arp_reply, 0, sizeof(arp_reply));
660 /* XXX: make an ARP request to have the client address */
661 memcpy(slirp->client_ethaddr, eh->h_source, ETH_ALEN);
663 /* ARP request for alias/dns mac address */
664 memcpy(reh->h_dest, pkt + ETH_ALEN, ETH_ALEN);
665 memcpy(reh->h_source, special_ethaddr, ETH_ALEN - 4);
666 memcpy(&reh->h_source[2], &ah->ar_tip, 4);
667 reh->h_proto = htons(ETH_P_ARP);
669 rah->ar_hrd = htons(1);
670 rah->ar_pro = htons(ETH_P_IP);
671 rah->ar_hln = ETH_ALEN;
672 rah->ar_pln = 4;
673 rah->ar_op = htons(ARPOP_REPLY);
674 memcpy(rah->ar_sha, reh->h_source, ETH_ALEN);
675 rah->ar_sip = ah->ar_tip;
676 memcpy(rah->ar_tha, ah->ar_sha, ETH_ALEN);
677 rah->ar_tip = ah->ar_sip;
678 slirp_output(slirp->opaque, arp_reply, sizeof(arp_reply));
680 break;
681 case ARPOP_REPLY:
682 /* reply to request of client mac address ? */
683 if (!memcmp(slirp->client_ethaddr, zero_ethaddr, ETH_ALEN) &&
684 ah->ar_sip == slirp->client_ipaddr.s_addr) {
685 memcpy(slirp->client_ethaddr, ah->ar_sha, ETH_ALEN);
687 break;
688 default:
689 break;
693 void slirp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len)
695 struct mbuf *m;
696 int proto;
698 if (pkt_len < ETH_HLEN)
699 return;
701 proto = ntohs(*(uint16_t *)(pkt + 12));
702 switch(proto) {
703 case ETH_P_ARP:
704 arp_input(slirp, pkt, pkt_len);
705 break;
706 case ETH_P_IP:
707 m = m_get(slirp);
708 if (!m)
709 return;
710 /* Note: we add to align the IP header */
711 if (M_FREEROOM(m) < pkt_len + 2) {
712 m_inc(m, pkt_len + 2);
714 m->m_len = pkt_len + 2;
715 memcpy(m->m_data + 2, pkt, pkt_len);
717 m->m_data += 2 + ETH_HLEN;
718 m->m_len -= 2 + ETH_HLEN;
720 ip_input(m);
721 break;
722 default:
723 break;
727 /* output the IP packet to the ethernet device */
728 void if_encap(Slirp *slirp, const uint8_t *ip_data, int ip_data_len)
730 uint8_t buf[1600];
731 struct ethhdr *eh = (struct ethhdr *)buf;
733 if (ip_data_len + ETH_HLEN > sizeof(buf))
734 return;
736 if (!memcmp(slirp->client_ethaddr, zero_ethaddr, ETH_ALEN)) {
737 uint8_t arp_req[ETH_HLEN + sizeof(struct arphdr)];
738 struct ethhdr *reh = (struct ethhdr *)arp_req;
739 struct arphdr *rah = (struct arphdr *)(arp_req + ETH_HLEN);
740 const struct ip *iph = (const struct ip *)ip_data;
742 /* If the client addr is not known, there is no point in
743 sending the packet to it. Normally the sender should have
744 done an ARP request to get its MAC address. Here we do it
745 in place of sending the packet and we hope that the sender
746 will retry sending its packet. */
747 memset(reh->h_dest, 0xff, ETH_ALEN);
748 memcpy(reh->h_source, special_ethaddr, ETH_ALEN - 4);
749 memcpy(&reh->h_source[2], &slirp->vhost_addr, 4);
750 reh->h_proto = htons(ETH_P_ARP);
751 rah->ar_hrd = htons(1);
752 rah->ar_pro = htons(ETH_P_IP);
753 rah->ar_hln = ETH_ALEN;
754 rah->ar_pln = 4;
755 rah->ar_op = htons(ARPOP_REQUEST);
756 /* source hw addr */
757 memcpy(rah->ar_sha, special_ethaddr, ETH_ALEN - 4);
758 memcpy(&rah->ar_sha[2], &slirp->vhost_addr, 4);
759 /* source IP */
760 rah->ar_sip = slirp->vhost_addr.s_addr;
761 /* target hw addr (none) */
762 memset(rah->ar_tha, 0, ETH_ALEN);
763 /* target IP */
764 rah->ar_tip = iph->ip_dst.s_addr;
765 slirp->client_ipaddr = iph->ip_dst;
766 slirp_output(slirp->opaque, arp_req, sizeof(arp_req));
767 } else {
768 memcpy(eh->h_dest, slirp->client_ethaddr, ETH_ALEN);
769 memcpy(eh->h_source, special_ethaddr, ETH_ALEN - 4);
770 /* XXX: not correct */
771 memcpy(&eh->h_source[2], &slirp->vhost_addr, 4);
772 eh->h_proto = htons(ETH_P_IP);
773 memcpy(buf + sizeof(struct ethhdr), ip_data, ip_data_len);
774 slirp_output(slirp->opaque, buf, ip_data_len + ETH_HLEN);
778 /* Drop host forwarding rule, return 0 if found. */
779 int slirp_remove_hostfwd(Slirp *slirp, int is_udp, struct in_addr host_addr,
780 int host_port)
782 struct socket *so;
783 struct socket *head = (is_udp ? &slirp->udb : &slirp->tcb);
784 struct sockaddr_in addr;
785 int port = htons(host_port);
786 socklen_t addr_len;
788 for (so = head->so_next; so != head; so = so->so_next) {
789 addr_len = sizeof(addr);
790 if ((so->so_state & SS_HOSTFWD) &&
791 getsockname(so->s, (struct sockaddr *)&addr, &addr_len) == 0 &&
792 addr.sin_addr.s_addr == host_addr.s_addr &&
793 addr.sin_port == port) {
794 close(so->s);
795 sofree(so);
796 return 0;
800 return -1;
803 int slirp_add_hostfwd(Slirp *slirp, int is_udp, struct in_addr host_addr,
804 int host_port, struct in_addr guest_addr, int guest_port)
806 if (!guest_addr.s_addr) {
807 guest_addr = slirp->vdhcp_startaddr;
809 if (is_udp) {
810 if (!udp_listen(slirp, host_addr.s_addr, htons(host_port),
811 guest_addr.s_addr, htons(guest_port), SS_HOSTFWD))
812 return -1;
813 } else {
814 if (!tcp_listen(slirp, host_addr.s_addr, htons(host_port),
815 guest_addr.s_addr, htons(guest_port), SS_HOSTFWD))
816 return -1;
818 return 0;
821 int slirp_add_exec(Slirp *slirp, int do_pty, const void *args,
822 struct in_addr *guest_addr, int guest_port)
824 if (!guest_addr->s_addr) {
825 guest_addr->s_addr = slirp->vnetwork_addr.s_addr |
826 (htonl(0x0204) & ~slirp->vnetwork_mask.s_addr);
828 if ((guest_addr->s_addr & slirp->vnetwork_mask.s_addr) !=
829 slirp->vnetwork_addr.s_addr ||
830 guest_addr->s_addr == slirp->vhost_addr.s_addr ||
831 guest_addr->s_addr == slirp->vnameserver_addr.s_addr) {
832 return -1;
834 return add_exec(&slirp->exec_list, do_pty, (char *)args, *guest_addr,
835 htons(guest_port));
838 ssize_t slirp_send(struct socket *so, const void *buf, size_t len, int flags)
840 if (so->s == -1 && so->extra) {
841 qemu_chr_write(so->extra, buf, len);
842 return len;
845 return send(so->s, buf, len, flags);
848 static struct socket *
849 slirp_find_ctl_socket(Slirp *slirp, struct in_addr guest_addr, int guest_port)
851 struct socket *so;
853 for (so = slirp->tcb.so_next; so != &slirp->tcb; so = so->so_next) {
854 if (so->so_faddr.s_addr == guest_addr.s_addr &&
855 htons(so->so_fport) == guest_port) {
856 return so;
859 return NULL;
862 size_t slirp_socket_can_recv(Slirp *slirp, struct in_addr guest_addr,
863 int guest_port)
865 struct iovec iov[2];
866 struct socket *so;
868 so = slirp_find_ctl_socket(slirp, guest_addr, guest_port);
870 if (!so || so->so_state & SS_NOFDREF)
871 return 0;
873 if (!CONN_CANFRCV(so) || so->so_snd.sb_cc >= (so->so_snd.sb_datalen/2))
874 return 0;
876 return sopreprbuf(so, iov, NULL);
879 void slirp_socket_recv(Slirp *slirp, struct in_addr guest_addr, int guest_port,
880 const uint8_t *buf, int size)
882 int ret;
883 struct socket *so = slirp_find_ctl_socket(slirp, guest_addr, guest_port);
885 if (!so)
886 return;
888 ret = soreadbuf(so, (const char *)buf, size);
890 if (ret > 0)
891 tcp_output(sototcpcb(so));
894 static void slirp_tcp_save(QEMUFile *f, struct tcpcb *tp)
896 int i;
898 qemu_put_sbe16(f, tp->t_state);
899 for (i = 0; i < TCPT_NTIMERS; i++)
900 qemu_put_sbe16(f, tp->t_timer[i]);
901 qemu_put_sbe16(f, tp->t_rxtshift);
902 qemu_put_sbe16(f, tp->t_rxtcur);
903 qemu_put_sbe16(f, tp->t_dupacks);
904 qemu_put_be16(f, tp->t_maxseg);
905 qemu_put_sbyte(f, tp->t_force);
906 qemu_put_be16(f, tp->t_flags);
907 qemu_put_be32(f, tp->snd_una);
908 qemu_put_be32(f, tp->snd_nxt);
909 qemu_put_be32(f, tp->snd_up);
910 qemu_put_be32(f, tp->snd_wl1);
911 qemu_put_be32(f, tp->snd_wl2);
912 qemu_put_be32(f, tp->iss);
913 qemu_put_be32(f, tp->snd_wnd);
914 qemu_put_be32(f, tp->rcv_wnd);
915 qemu_put_be32(f, tp->rcv_nxt);
916 qemu_put_be32(f, tp->rcv_up);
917 qemu_put_be32(f, tp->irs);
918 qemu_put_be32(f, tp->rcv_adv);
919 qemu_put_be32(f, tp->snd_max);
920 qemu_put_be32(f, tp->snd_cwnd);
921 qemu_put_be32(f, tp->snd_ssthresh);
922 qemu_put_sbe16(f, tp->t_idle);
923 qemu_put_sbe16(f, tp->t_rtt);
924 qemu_put_be32(f, tp->t_rtseq);
925 qemu_put_sbe16(f, tp->t_srtt);
926 qemu_put_sbe16(f, tp->t_rttvar);
927 qemu_put_be16(f, tp->t_rttmin);
928 qemu_put_be32(f, tp->max_sndwnd);
929 qemu_put_byte(f, tp->t_oobflags);
930 qemu_put_byte(f, tp->t_iobc);
931 qemu_put_sbe16(f, tp->t_softerror);
932 qemu_put_byte(f, tp->snd_scale);
933 qemu_put_byte(f, tp->rcv_scale);
934 qemu_put_byte(f, tp->request_r_scale);
935 qemu_put_byte(f, tp->requested_s_scale);
936 qemu_put_be32(f, tp->ts_recent);
937 qemu_put_be32(f, tp->ts_recent_age);
938 qemu_put_be32(f, tp->last_ack_sent);
941 static void slirp_sbuf_save(QEMUFile *f, struct sbuf *sbuf)
943 uint32_t off;
945 qemu_put_be32(f, sbuf->sb_cc);
946 qemu_put_be32(f, sbuf->sb_datalen);
947 off = (uint32_t)(sbuf->sb_wptr - sbuf->sb_data);
948 qemu_put_sbe32(f, off);
949 off = (uint32_t)(sbuf->sb_rptr - sbuf->sb_data);
950 qemu_put_sbe32(f, off);
951 qemu_put_buffer(f, (unsigned char*)sbuf->sb_data, sbuf->sb_datalen);
954 static void slirp_socket_save(QEMUFile *f, struct socket *so)
956 qemu_put_be32(f, so->so_urgc);
957 qemu_put_be32(f, so->so_faddr.s_addr);
958 qemu_put_be32(f, so->so_laddr.s_addr);
959 qemu_put_be16(f, so->so_fport);
960 qemu_put_be16(f, so->so_lport);
961 qemu_put_byte(f, so->so_iptos);
962 qemu_put_byte(f, so->so_emu);
963 qemu_put_byte(f, so->so_type);
964 qemu_put_be32(f, so->so_state);
965 slirp_sbuf_save(f, &so->so_rcv);
966 slirp_sbuf_save(f, &so->so_snd);
967 slirp_tcp_save(f, so->so_tcpcb);
970 static void slirp_bootp_save(QEMUFile *f, Slirp *slirp)
972 int i;
974 for (i = 0; i < NB_BOOTP_CLIENTS; i++) {
975 qemu_put_be16(f, slirp->bootp_clients[i].allocated);
976 qemu_put_buffer(f, slirp->bootp_clients[i].macaddr, 6);
980 static void slirp_state_save(QEMUFile *f, void *opaque)
982 Slirp *slirp = opaque;
983 struct ex_list *ex_ptr;
985 for (ex_ptr = slirp->exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next)
986 if (ex_ptr->ex_pty == 3) {
987 struct socket *so;
988 so = slirp_find_ctl_socket(slirp, ex_ptr->ex_addr,
989 ntohs(ex_ptr->ex_fport));
990 if (!so)
991 continue;
993 qemu_put_byte(f, 42);
994 slirp_socket_save(f, so);
996 qemu_put_byte(f, 0);
998 qemu_put_be16(f, slirp->ip_id);
1000 slirp_bootp_save(f, slirp);
1003 static void slirp_tcp_load(QEMUFile *f, struct tcpcb *tp)
1005 int i;
1007 tp->t_state = qemu_get_sbe16(f);
1008 for (i = 0; i < TCPT_NTIMERS; i++)
1009 tp->t_timer[i] = qemu_get_sbe16(f);
1010 tp->t_rxtshift = qemu_get_sbe16(f);
1011 tp->t_rxtcur = qemu_get_sbe16(f);
1012 tp->t_dupacks = qemu_get_sbe16(f);
1013 tp->t_maxseg = qemu_get_be16(f);
1014 tp->t_force = qemu_get_sbyte(f);
1015 tp->t_flags = qemu_get_be16(f);
1016 tp->snd_una = qemu_get_be32(f);
1017 tp->snd_nxt = qemu_get_be32(f);
1018 tp->snd_up = qemu_get_be32(f);
1019 tp->snd_wl1 = qemu_get_be32(f);
1020 tp->snd_wl2 = qemu_get_be32(f);
1021 tp->iss = qemu_get_be32(f);
1022 tp->snd_wnd = qemu_get_be32(f);
1023 tp->rcv_wnd = qemu_get_be32(f);
1024 tp->rcv_nxt = qemu_get_be32(f);
1025 tp->rcv_up = qemu_get_be32(f);
1026 tp->irs = qemu_get_be32(f);
1027 tp->rcv_adv = qemu_get_be32(f);
1028 tp->snd_max = qemu_get_be32(f);
1029 tp->snd_cwnd = qemu_get_be32(f);
1030 tp->snd_ssthresh = qemu_get_be32(f);
1031 tp->t_idle = qemu_get_sbe16(f);
1032 tp->t_rtt = qemu_get_sbe16(f);
1033 tp->t_rtseq = qemu_get_be32(f);
1034 tp->t_srtt = qemu_get_sbe16(f);
1035 tp->t_rttvar = qemu_get_sbe16(f);
1036 tp->t_rttmin = qemu_get_be16(f);
1037 tp->max_sndwnd = qemu_get_be32(f);
1038 tp->t_oobflags = qemu_get_byte(f);
1039 tp->t_iobc = qemu_get_byte(f);
1040 tp->t_softerror = qemu_get_sbe16(f);
1041 tp->snd_scale = qemu_get_byte(f);
1042 tp->rcv_scale = qemu_get_byte(f);
1043 tp->request_r_scale = qemu_get_byte(f);
1044 tp->requested_s_scale = qemu_get_byte(f);
1045 tp->ts_recent = qemu_get_be32(f);
1046 tp->ts_recent_age = qemu_get_be32(f);
1047 tp->last_ack_sent = qemu_get_be32(f);
1048 tcp_template(tp);
1051 static int slirp_sbuf_load(QEMUFile *f, struct sbuf *sbuf)
1053 uint32_t off, sb_cc, sb_datalen;
1055 sb_cc = qemu_get_be32(f);
1056 sb_datalen = qemu_get_be32(f);
1058 sbreserve(sbuf, sb_datalen);
1060 if (sbuf->sb_datalen != sb_datalen)
1061 return -ENOMEM;
1063 sbuf->sb_cc = sb_cc;
1065 off = qemu_get_sbe32(f);
1066 sbuf->sb_wptr = sbuf->sb_data + off;
1067 off = qemu_get_sbe32(f);
1068 sbuf->sb_rptr = sbuf->sb_data + off;
1069 qemu_get_buffer(f, (unsigned char*)sbuf->sb_data, sbuf->sb_datalen);
1071 return 0;
1074 static int slirp_socket_load(QEMUFile *f, struct socket *so)
1076 if (tcp_attach(so) < 0)
1077 return -ENOMEM;
1079 so->so_urgc = qemu_get_be32(f);
1080 so->so_faddr.s_addr = qemu_get_be32(f);
1081 so->so_laddr.s_addr = qemu_get_be32(f);
1082 so->so_fport = qemu_get_be16(f);
1083 so->so_lport = qemu_get_be16(f);
1084 so->so_iptos = qemu_get_byte(f);
1085 so->so_emu = qemu_get_byte(f);
1086 so->so_type = qemu_get_byte(f);
1087 so->so_state = qemu_get_be32(f);
1088 if (slirp_sbuf_load(f, &so->so_rcv) < 0)
1089 return -ENOMEM;
1090 if (slirp_sbuf_load(f, &so->so_snd) < 0)
1091 return -ENOMEM;
1092 slirp_tcp_load(f, so->so_tcpcb);
1094 return 0;
1097 static void slirp_bootp_load(QEMUFile *f, Slirp *slirp)
1099 int i;
1101 for (i = 0; i < NB_BOOTP_CLIENTS; i++) {
1102 slirp->bootp_clients[i].allocated = qemu_get_be16(f);
1103 qemu_get_buffer(f, slirp->bootp_clients[i].macaddr, 6);
1107 static int slirp_state_load(QEMUFile *f, void *opaque, int version_id)
1109 Slirp *slirp = opaque;
1110 struct ex_list *ex_ptr;
1112 while (qemu_get_byte(f)) {
1113 int ret;
1114 struct socket *so = socreate(slirp);
1116 if (!so)
1117 return -ENOMEM;
1119 ret = slirp_socket_load(f, so);
1121 if (ret < 0)
1122 return ret;
1124 if ((so->so_faddr.s_addr & slirp->vnetwork_mask.s_addr) !=
1125 slirp->vnetwork_addr.s_addr) {
1126 return -EINVAL;
1128 for (ex_ptr = slirp->exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
1129 if (ex_ptr->ex_pty == 3 &&
1130 so->so_faddr.s_addr == ex_ptr->ex_addr.s_addr &&
1131 so->so_fport == ex_ptr->ex_fport) {
1132 break;
1135 if (!ex_ptr)
1136 return -EINVAL;
1138 so->extra = (void *)ex_ptr->ex_exec;
1141 if (version_id >= 2) {
1142 slirp->ip_id = qemu_get_be16(f);
1145 if (version_id >= 3) {
1146 slirp_bootp_load(f, slirp);
1149 return 0;