compute checksum for roms bigger than a segment
[qemu-kvm/fedora.git] / slirp / slirp.c
blob827dce71bb9f142430968fdb14d5d3b899f62b72
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 address */
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;
47 u_int curtime;
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);
54 #ifdef _WIN32
56 static int get_dns_addr(struct in_addr *pdns_addr)
58 FIXED_INFO *FixedInfo=NULL;
59 ULONG BufLen;
60 DWORD ret;
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)) {
68 if (FixedInfo) {
69 GlobalFree(FixedInfo);
70 FixedInfo = NULL;
72 FixedInfo = GlobalAlloc(GPTR, BufLen);
75 if ((ret = GetNetworkParams(FixedInfo, &BufLen)) != ERROR_SUCCESS) {
76 printf("GetNetworkParams failed. ret = %08x\n", (u_int)ret );
77 if (FixedInfo) {
78 GlobalFree(FixedInfo);
79 FixedInfo = NULL;
81 return -1;
84 pIPAddr = &(FixedInfo->DnsServerList);
85 inet_aton(pIPAddr->IpAddress.String, &tmp_addr);
86 *pdns_addr = tmp_addr;
87 if (FixedInfo) {
88 GlobalFree(FixedInfo);
89 FixedInfo = NULL;
91 return 0;
94 static void winsock_cleanup(void)
96 WSACleanup();
99 #else
101 static int get_dns_addr(struct in_addr *pdns_addr)
103 char buff[512];
104 char buff2[257];
105 FILE *f;
106 int found = 0;
107 struct in_addr tmp_addr;
109 f = fopen("/etc/resolv.conf", "r");
110 if (!f)
111 return -1;
113 #ifdef DEBUG
114 lprint("IP address of your DNS(s): ");
115 #endif
116 while (fgets(buff, 512, f) != NULL) {
117 if (sscanf(buff, "nameserver%*[ \t]%256s", buff2) == 1) {
118 if (!inet_aton(buff2, &tmp_addr))
119 continue;
120 if (tmp_addr.s_addr == loopback_addr.s_addr)
121 tmp_addr = our_addr;
122 /* If it's the first one, set it to dns_addr */
123 if (!found)
124 *pdns_addr = tmp_addr;
125 #ifdef DEBUG
126 else
127 lprint(", ");
128 #endif
129 if (++found > 3) {
130 #ifdef DEBUG
131 lprint("(more)");
132 #endif
133 break;
135 #ifdef DEBUG
136 else
137 lprint("%s", inet_ntoa(tmp_addr));
138 #endif
141 fclose(f);
142 if (!found)
143 return -1;
144 return 0;
147 #endif
149 static void slirp_init_once(void)
151 static int initialized;
152 struct hostent *he;
153 char our_name[256];
154 #ifdef _WIN32
155 WSADATA Data;
156 #endif
158 if (initialized) {
159 return;
161 initialized = 1;
163 #ifdef _WIN32
164 WSAStartup(MAKEWORD(2,0), &Data);
165 atexit(winsock_cleanup);
166 #endif
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);
173 if (he) {
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));
198 slirp_init_once();
200 slirp->restricted = restricted;
202 if_init(slirp);
203 ip_init(slirp);
205 /* Initialise mbufs *after* setting the MTU */
206 m_init(slirp);
208 slirp->vnetwork_addr = vnetwork;
209 slirp->vnetwork_mask = vnetmask;
210 slirp->vhost_addr = vhost;
211 if (vhostname) {
212 pstrcpy(slirp->client_hostname, sizeof(slirp->client_hostname),
213 vhostname);
215 if (tftp_path) {
216 slirp->tftp_prefix = qemu_strdup(tftp_path);
218 if (bootfile) {
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);
230 return slirp;
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);
241 qemu_free(slirp);
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)
251 Slirp *slirp;
252 struct socket *so, *so_next;
253 int nfds;
255 if (TAILQ_EMPTY(&slirp_instances)) {
256 return;
259 /* fail safe */
260 global_readfds = NULL;
261 global_writefds = NULL;
262 global_xfds = NULL;
264 nfds = *pnfds;
266 * First, TCP sockets
268 do_slowtimo = 0;
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;
279 so = so_next) {
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)
293 continue;
296 * Set for reading sockets which are accepting
298 if (so->so_state & SS_FACCEPTCONN) {
299 FD_SET(so->s, readfds);
300 UPD_NFDS(so->s);
301 continue;
305 * Set for writing sockets which are connecting
307 if (so->so_state & SS_ISFCONNECTING) {
308 FD_SET(so->s, writefds);
309 UPD_NFDS(so->s);
310 continue;
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);
319 UPD_NFDS(so->s);
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);
328 FD_SET(so->s, xfds);
329 UPD_NFDS(so->s);
334 * UDP sockets
336 for (so = slirp->udb.so_next; so != &slirp->udb;
337 so = so_next) {
338 so_next = so->so_next;
341 * See if it's timed out
343 if (so->so_expire) {
344 if (so->so_expire <= curtime) {
345 udp_detach(so);
346 continue;
347 } else
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
359 * (XXX <= 4 ?)
361 if ((so->so_state & SS_ISFCONNECTED) && so->so_queued <= 4) {
362 FD_SET(so->s, readfds);
363 UPD_NFDS(so->s);
368 *pnfds = nfds;
371 void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds,
372 int select_error)
374 Slirp *slirp;
375 struct socket *so, *so_next;
376 int ret;
378 if (TAILQ_EMPTY(&slirp_instances)) {
379 return;
382 global_readfds = readfds;
383 global_writefds = writefds;
384 global_xfds = xfds;
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)) {
393 tcp_fasttimo(slirp);
394 time_fasttimo = 0;
396 if (do_slowtimo && ((curtime - last_slowtimo) >= 499)) {
397 ip_slowtimo(slirp);
398 tcp_slowtimo(slirp);
399 last_slowtimo = curtime;
403 * Check sockets
405 if (!select_error) {
407 * Check TCP sockets
409 for (so = slirp->tcb.so_next; so != &slirp->tcb;
410 so = so_next) {
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)
418 continue;
421 * Check for URG data
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))
426 sorecvoob(so);
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) {
435 tcp_connect(so);
436 continue;
437 } /* else */
438 ret = soread(so);
440 /* Output it if we read something */
441 if (ret > 0)
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) {
453 /* Connected */
454 so->so_state &= ~SS_ISFCONNECTING;
456 ret = send(so->s, (const void *) &ret, 0, 0);
457 if (ret < 0) {
458 /* XXXXX Must fix, zero bytes is a NOP */
459 if (errno == EAGAIN || errno == EWOULDBLOCK ||
460 errno == EINPROGRESS || errno == ENOTCONN)
461 continue;
463 /* else failed */
464 so->so_state &= SS_PERSISTENT_MASK;
465 so->so_state |= SS_NOFDREF;
467 /* else so->so_state &= ~SS_ISFCONNECTING; */
470 * Continue tcp_input
472 tcp_input((struct mbuf *)NULL, sizeof(struct ip), so);
473 /* continue; */
474 } else
475 ret = sowrite(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
488 #ifdef PROBE_CONN
489 if (so->so_state & SS_ISFCONNECTING) {
490 ret = recv(so->s, (char *)&ret, 0,0);
492 if (ret < 0) {
493 /* XXX */
494 if (errno == EAGAIN || errno == EWOULDBLOCK ||
495 errno == EINPROGRESS || errno == ENOTCONN)
496 continue; /* Still connecting, continue */
498 /* else failed */
499 so->so_state &= SS_PERSISTENT_MASK;
500 so->so_state |= SS_NOFDREF;
502 /* tcp_input will take care of it */
503 } else {
504 ret = send(so->s, &ret, 0,0);
505 if (ret < 0) {
506 /* XXX */
507 if (errno == EAGAIN || errno == EWOULDBLOCK ||
508 errno == EINPROGRESS || errno == ENOTCONN)
509 continue;
510 /* else failed */
511 so->so_state &= SS_PERSISTENT_MASK;
512 so->so_state |= SS_NOFDREF;
513 } else
514 so->so_state &= ~SS_ISFCONNECTING;
517 tcp_input((struct mbuf *)NULL, sizeof(struct ip),so);
518 } /* SS_ISFCONNECTING */
519 #endif
523 * Now UDP sockets.
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;
528 so = so_next) {
529 so_next = so->so_next;
531 if (so->s != -1 && FD_ISSET(so->s, readfds)) {
532 sorecvfrom(so);
538 * See if we can start outputting
540 if (slirp->if_queued) {
541 if_start(slirp);
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;
552 global_xfds = NULL;
555 #define ETH_ALEN 6
556 #define ETH_HLEN 14
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 */
564 struct ethhdr
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 */
571 struct arphdr
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);
595 int ar_op;
596 struct ex_list *ex_ptr;
598 ar_op = ntohs(ah->ar_op);
599 switch(ar_op) {
600 case ARPOP_REQUEST:
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)
605 goto arp_ok;
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)
608 goto arp_ok;
610 return;
611 arp_ok:
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;
624 rah->ar_pln = 4;
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));
632 break;
633 case ARPOP_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);
639 break;
640 default:
641 break;
645 void slirp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len)
647 struct mbuf *m;
648 int proto;
650 if (pkt_len < ETH_HLEN)
651 return;
653 proto = ntohs(*(uint16_t *)(pkt + 12));
654 switch(proto) {
655 case ETH_P_ARP:
656 arp_input(slirp, pkt, pkt_len);
657 break;
658 case ETH_P_IP:
659 m = m_get(slirp);
660 if (!m)
661 return;
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;
672 ip_input(m);
673 break;
674 default:
675 break;
679 /* output the IP packet to the ethernet device */
680 void if_encap(Slirp *slirp, const uint8_t *ip_data, int ip_data_len)
682 uint8_t buf[1600];
683 struct ethhdr *eh = (struct ethhdr *)buf;
685 if (ip_data_len + ETH_HLEN > sizeof(buf))
686 return;
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;
706 rah->ar_pln = 4;
707 rah->ar_op = htons(ARPOP_REQUEST);
708 /* source hw addr */
709 memcpy(rah->ar_sha, special_ethaddr, ETH_ALEN - 4);
710 memcpy(&rah->ar_sha[2], &slirp->vhost_addr, 4);
711 /* source IP */
712 rah->ar_sip = slirp->vhost_addr.s_addr;
713 /* target hw addr (none) */
714 memset(rah->ar_tha, 0, ETH_ALEN);
715 /* target IP */
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));
719 } else {
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,
732 int host_port)
734 struct socket *so;
735 struct socket *head = (is_udp ? &slirp->udb : &slirp->tcb);
736 struct sockaddr_in addr;
737 int port = htons(host_port);
738 socklen_t addr_len;
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) {
746 close(so->s);
747 sofree(so);
748 return 0;
752 return -1;
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;
761 if (is_udp) {
762 if (!udp_listen(slirp, host_addr.s_addr, htons(host_port),
763 guest_addr.s_addr, htons(guest_port), SS_HOSTFWD))
764 return -1;
765 } else {
766 if (!tcp_listen(slirp, host_addr.s_addr, htons(host_port),
767 guest_addr.s_addr, htons(guest_port), SS_HOSTFWD))
768 return -1;
770 return 0;
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) {
784 return -1;
786 return add_exec(&slirp->exec_list, do_pty, (char *)args, *guest_addr,
787 htons(guest_port));
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);
794 return 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)
803 struct socket *so;
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) {
808 return so;
811 return NULL;
814 size_t slirp_socket_can_recv(Slirp *slirp, struct in_addr guest_addr,
815 int guest_port)
817 struct iovec iov[2];
818 struct socket *so;
820 so = slirp_find_ctl_socket(slirp, guest_addr, guest_port);
822 if (!so || so->so_state & SS_NOFDREF)
823 return 0;
825 if (!CONN_CANFRCV(so) || so->so_snd.sb_cc >= (so->so_snd.sb_datalen/2))
826 return 0;
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)
834 int ret;
835 struct socket *so = slirp_find_ctl_socket(slirp, guest_addr, guest_port);
837 if (!so)
838 return;
840 ret = soreadbuf(so, (const char *)buf, size);
842 if (ret > 0)
843 tcp_output(sototcpcb(so));
846 static void slirp_tcp_save(QEMUFile *f, struct tcpcb *tp)
848 int i;
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)
895 uint32_t off;
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)
924 int i;
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) {
939 struct socket *so;
940 so = slirp_find_ctl_socket(slirp, ex_ptr->ex_addr,
941 ntohs(ex_ptr->ex_fport));
942 if (!so)
943 continue;
945 qemu_put_byte(f, 42);
946 slirp_socket_save(f, so);
948 qemu_put_byte(f, 0);
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)
957 int i;
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);
1000 tcp_template(tp);
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)
1013 return -ENOMEM;
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);
1023 return 0;
1026 static int slirp_socket_load(QEMUFile *f, struct socket *so)
1028 if (tcp_attach(so) < 0)
1029 return -ENOMEM;
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)
1041 return -ENOMEM;
1042 if (slirp_sbuf_load(f, &so->so_snd) < 0)
1043 return -ENOMEM;
1044 slirp_tcp_load(f, so->so_tcpcb);
1046 return 0;
1049 static void slirp_bootp_load(QEMUFile *f, Slirp *slirp)
1051 int i;
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;
1063 int r;
1065 while ((r = qemu_get_byte(f))) {
1066 int ret;
1067 struct socket *so = socreate(slirp);
1069 if (!so)
1070 return -ENOMEM;
1072 ret = slirp_socket_load(f, so);
1074 if (ret < 0)
1075 return ret;
1077 if ((so->so_faddr.s_addr & slirp->vnetwork_mask.s_addr) !=
1078 slirp->vnetwork_addr.s_addr) {
1079 return -EINVAL;
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) {
1085 break;
1088 if (!ex_ptr)
1089 return -EINVAL;
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);
1102 return 0;