4 * Copyright (c) 2004-2008 Fabrice Bellard
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 #include "qemu-common.h"
28 struct in_addr our_addr;
29 /* host dns address */
30 struct in_addr dns_addr;
31 /* host loopback address */
32 struct in_addr loopback_addr;
34 /* address for slirp virtual addresses */
35 struct in_addr special_addr;
36 /* virtual address alias for host */
37 struct in_addr alias_addr;
39 static const uint8_t special_ethaddr[6] = {
40 0x52, 0x54, 0x00, 0x12, 0x35, 0x00
43 /* ARP cache for the guest IP addresses (XXX: allow many entries) */
44 uint8_t client_ethaddr[6];
45 static struct in_addr client_ipaddr;
47 static const uint8_t zero_ethaddr[6] = { 0, 0, 0, 0, 0, 0 };
49 char *slirp_special_ip = CTL_SPECIAL;
55 struct ex_list *exec_list;
57 /* XXX: suppress those select globals */
58 fd_set *global_readfds, *global_writefds, *global_xfds;
60 char slirp_hostname[33];
64 static int get_dns_addr(struct in_addr *pdns_addr)
66 FIXED_INFO *FixedInfo=NULL;
69 IP_ADDR_STRING *pIPAddr;
70 struct in_addr tmp_addr;
72 FixedInfo = (FIXED_INFO *)GlobalAlloc(GPTR, sizeof(FIXED_INFO));
73 BufLen = sizeof(FIXED_INFO);
75 if (ERROR_BUFFER_OVERFLOW == GetNetworkParams(FixedInfo, &BufLen)) {
77 GlobalFree(FixedInfo);
80 FixedInfo = GlobalAlloc(GPTR, BufLen);
83 if ((ret = GetNetworkParams(FixedInfo, &BufLen)) != ERROR_SUCCESS) {
84 printf("GetNetworkParams failed. ret = %08x\n", (u_int)ret );
86 GlobalFree(FixedInfo);
92 pIPAddr = &(FixedInfo->DnsServerList);
93 inet_aton(pIPAddr->IpAddress.String, &tmp_addr);
94 *pdns_addr = tmp_addr;
96 printf( "DNS Servers:\n" );
97 printf( "DNS Addr:%s\n", pIPAddr->IpAddress.String );
99 pIPAddr = FixedInfo -> DnsServerList.Next;
101 printf( "DNS Addr:%s\n", pIPAddr ->IpAddress.String );
102 pIPAddr = pIPAddr ->Next;
106 GlobalFree(FixedInfo);
114 static int get_dns_addr(struct in_addr *pdns_addr)
120 struct in_addr tmp_addr;
122 f = fopen("/etc/resolv.conf", "r");
127 lprint("IP address of your DNS(s): ");
129 while (fgets(buff, 512, f) != NULL) {
130 if (sscanf(buff, "nameserver%*[ \t]%256s", buff2) == 1) {
131 if (!inet_aton(buff2, &tmp_addr))
133 if (tmp_addr.s_addr == loopback_addr.s_addr)
135 /* If it's the first one, set it to dns_addr */
137 *pdns_addr = tmp_addr;
150 lprint("%s", inet_ntoa(tmp_addr));
163 static void slirp_cleanup(void)
169 void slirp_init(int restrict, char *special_ip)
171 // debug_init("/tmp/slirp.log", DEBUG_DEFAULT);
176 WSAStartup(MAKEWORD(2,0), &Data);
177 atexit(slirp_cleanup);
182 slirp_restrict = restrict;
187 /* Initialise mbufs *after* setting the MTU */
190 /* set default addresses */
191 inet_aton("127.0.0.1", &loopback_addr);
193 if (get_dns_addr(&dns_addr) < 0) {
194 dns_addr = loopback_addr;
195 fprintf (stderr, "Warning: No DNS servers found\n");
199 slirp_special_ip = special_ip;
201 inet_aton(slirp_special_ip, &special_addr);
202 alias_addr.s_addr = special_addr.s_addr | htonl(CTL_ALIAS);
206 #define CONN_CANFSEND(so) (((so)->so_state & (SS_FCANTSENDMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED)
207 #define CONN_CANFRCV(so) (((so)->so_state & (SS_FCANTRCVMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED)
208 #define UPD_NFDS(x) if (nfds < (x)) nfds = (x)
211 * curtime kept to an accuracy of 1ms
214 static void updtime(void)
219 curtime = (u_int)tb.time * (u_int)1000;
220 curtime += (u_int)tb.millitm;
223 static void updtime(void)
225 gettimeofday(&tt, 0);
227 curtime = (u_int)tt.tv_sec * (u_int)1000;
228 curtime += (u_int)tt.tv_usec / (u_int)1000;
230 if ((tt.tv_usec % 1000) >= 500)
235 void slirp_select_fill(int *pnfds,
236 fd_set *readfds, fd_set *writefds, fd_set *xfds)
238 struct socket *so, *so_next;
239 struct timeval timeout;
244 global_readfds = NULL;
245 global_writefds = NULL;
255 * *_slowtimo needs calling if there are IP fragments
256 * in the fragment queue, or there are TCP connections active
258 do_slowtimo = ((tcb.so_next != &tcb) ||
259 ((struct ipasfrag *)&ipq != (struct ipasfrag *)ipq.next));
261 for (so = tcb.so_next; so != &tcb; so = so_next) {
262 so_next = so->so_next;
265 * See if we need a tcp_fasttimo
267 if (time_fasttimo == 0 && so->so_tcpcb->t_flags & TF_DELACK)
268 time_fasttimo = curtime; /* Flag when we want a fasttimo */
271 * NOFDREF can include still connecting to local-host,
272 * newly socreated() sockets etc. Don't want to select these.
274 if (so->so_state & SS_NOFDREF || so->s == -1)
278 * Set for reading sockets which are accepting
280 if (so->so_state & SS_FACCEPTCONN) {
281 FD_SET(so->s, readfds);
287 * Set for writing sockets which are connecting
289 if (so->so_state & SS_ISFCONNECTING) {
290 FD_SET(so->s, writefds);
296 * Set for writing if we are connected, can send more, and
297 * we have something to send
299 if (CONN_CANFSEND(so) && so->so_rcv.sb_cc) {
300 FD_SET(so->s, writefds);
305 * Set for reading (and urgent data) if we are connected, can
306 * receive more, and we have room for it XXX /2 ?
308 if (CONN_CANFRCV(so) && (so->so_snd.sb_cc < (so->so_snd.sb_datalen/2))) {
309 FD_SET(so->s, readfds);
318 for (so = udb.so_next; so != &udb; so = so_next) {
319 so_next = so->so_next;
322 * See if it's timed out
325 if (so->so_expire <= curtime) {
329 do_slowtimo = 1; /* Let socket expire */
333 * When UDP packets are received from over the
334 * link, they're sendto()'d straight away, so
335 * no need for setting for writing
336 * Limit the number of packets queued by this session
337 * to 4. Note that even though we try and limit this
338 * to 4 packets, the session could have more queued
339 * if the packets needed to be fragmented
342 if ((so->so_state & SS_ISFCONNECTED) && so->so_queued <= 4) {
343 FD_SET(so->s, readfds);
350 * Setup timeout to use minimum CPU usage, especially when idle
354 * First, see the timeout needed by *timo
357 timeout.tv_usec = -1;
359 * If a slowtimo is needed, set timeout to 500ms from the last
360 * slow timeout. If a fast timeout is needed, set timeout within
361 * 200ms of when it was requested.
364 /* XXX + 10000 because some select()'s aren't that accurate */
365 timeout.tv_usec = ((500 - (curtime - last_slowtimo)) * 1000) + 10000;
366 if (timeout.tv_usec < 0)
368 else if (timeout.tv_usec > 510000)
369 timeout.tv_usec = 510000;
371 /* Can only fasttimo if we also slowtimo */
373 tmp_time = (200 - (curtime - time_fasttimo)) * 1000;
377 /* Choose the smallest of the 2 */
378 if (tmp_time < timeout.tv_usec)
379 timeout.tv_usec = (u_int)tmp_time;
385 void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds)
387 struct socket *so, *so_next;
390 global_readfds = readfds;
391 global_writefds = writefds;
398 * See if anything has timed out
401 if (time_fasttimo && ((curtime - time_fasttimo) >= 2)) {
405 if (do_slowtimo && ((curtime - last_slowtimo) >= 499)) {
408 last_slowtimo = curtime;
419 for (so = tcb.so_next; so != &tcb; so = so_next) {
420 so_next = so->so_next;
423 * FD_ISSET is meaningless on these sockets
424 * (and they can crash the program)
426 if (so->so_state & SS_NOFDREF || so->s == -1)
431 * This will soread as well, so no need to
432 * test for readfds below if this succeeds
434 if (FD_ISSET(so->s, xfds))
437 * Check sockets for reading
439 else if (FD_ISSET(so->s, readfds)) {
441 * Check for incoming connections
443 if (so->so_state & SS_FACCEPTCONN) {
449 /* Output it if we read something */
451 tcp_output(sototcpcb(so));
455 * Check sockets for writing
457 if (FD_ISSET(so->s, writefds)) {
459 * Check for non-blocking, still-connecting sockets
461 if (so->so_state & SS_ISFCONNECTING) {
463 so->so_state &= ~SS_ISFCONNECTING;
465 ret = send(so->s, &ret, 0, 0);
467 /* XXXXX Must fix, zero bytes is a NOP */
468 if (errno == EAGAIN || errno == EWOULDBLOCK ||
469 errno == EINPROGRESS || errno == ENOTCONN)
473 so->so_state = SS_NOFDREF;
475 /* else so->so_state &= ~SS_ISFCONNECTING; */
480 tcp_input((struct mbuf *)NULL, sizeof(struct ip), so);
485 * XXXXX If we wrote something (a lot), there
486 * could be a need for a window update.
487 * In the worst case, the remote will send
488 * a window probe to get things going again
493 * Probe a still-connecting, non-blocking socket
494 * to check if it's still alive
497 if (so->so_state & SS_ISFCONNECTING) {
498 ret = recv(so->s, (char *)&ret, 0,0);
502 if (errno == EAGAIN || errno == EWOULDBLOCK ||
503 errno == EINPROGRESS || errno == ENOTCONN)
504 continue; /* Still connecting, continue */
507 so->so_state = SS_NOFDREF;
509 /* tcp_input will take care of it */
511 ret = send(so->s, &ret, 0,0);
514 if (errno == EAGAIN || errno == EWOULDBLOCK ||
515 errno == EINPROGRESS || errno == ENOTCONN)
518 so->so_state = SS_NOFDREF;
520 so->so_state &= ~SS_ISFCONNECTING;
523 tcp_input((struct mbuf *)NULL, sizeof(struct ip),so);
524 } /* SS_ISFCONNECTING */
530 * Incoming packets are sent straight away, they're not buffered.
531 * Incoming UDP data isn't buffered either.
533 for (so = udb.so_next; so != &udb; so = so_next) {
534 so_next = so->so_next;
536 if (so->s != -1 && FD_ISSET(so->s, readfds)) {
543 * See if we can start outputting
545 if (if_queued && link_up)
548 /* clear global file descriptor sets.
549 * these reside on the stack in vl.c
550 * so they're unusable if we're not in
551 * slirp_select_fill or slirp_select_poll.
553 global_readfds = NULL;
554 global_writefds = NULL;
561 #define ETH_P_IP 0x0800 /* Internet Protocol packet */
562 #define ETH_P_ARP 0x0806 /* Address Resolution packet */
564 #define ARPOP_REQUEST 1 /* ARP request */
565 #define ARPOP_REPLY 2 /* ARP reply */
569 unsigned char h_dest[ETH_ALEN]; /* destination eth addr */
570 unsigned char h_source[ETH_ALEN]; /* source ether addr */
571 unsigned short h_proto; /* packet type ID field */
576 unsigned short ar_hrd; /* format of hardware address */
577 unsigned short ar_pro; /* format of protocol address */
578 unsigned char ar_hln; /* length of hardware address */
579 unsigned char ar_pln; /* length of protocol address */
580 unsigned short ar_op; /* ARP opcode (command) */
583 * Ethernet looks like this : This bit is variable sized however...
585 unsigned char ar_sha[ETH_ALEN]; /* sender hardware address */
586 unsigned char ar_sip[4]; /* sender IP address */
587 unsigned char ar_tha[ETH_ALEN]; /* target hardware address */
588 unsigned char ar_tip[4]; /* target IP address */
591 static void arp_input(const uint8_t *pkt, int pkt_len)
593 struct ethhdr *eh = (struct ethhdr *)pkt;
594 struct arphdr *ah = (struct arphdr *)(pkt + ETH_HLEN);
595 uint8_t arp_reply[ETH_HLEN + sizeof(struct arphdr)];
596 struct ethhdr *reh = (struct ethhdr *)arp_reply;
597 struct arphdr *rah = (struct arphdr *)(arp_reply + ETH_HLEN);
599 struct ex_list *ex_ptr;
601 ar_op = ntohs(ah->ar_op);
604 if (!memcmp(ah->ar_tip, &special_addr, 3)) {
605 if (ah->ar_tip[3] == CTL_DNS || ah->ar_tip[3] == CTL_ALIAS)
607 for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
608 if (ex_ptr->ex_addr == ah->ar_tip[3])
613 /* XXX: make an ARP request to have the client address */
614 memcpy(client_ethaddr, eh->h_source, ETH_ALEN);
616 /* ARP request for alias/dns mac address */
617 memcpy(reh->h_dest, pkt + ETH_ALEN, ETH_ALEN);
618 memcpy(reh->h_source, special_ethaddr, ETH_ALEN - 1);
619 reh->h_source[5] = ah->ar_tip[3];
620 reh->h_proto = htons(ETH_P_ARP);
622 rah->ar_hrd = htons(1);
623 rah->ar_pro = htons(ETH_P_IP);
624 rah->ar_hln = ETH_ALEN;
626 rah->ar_op = htons(ARPOP_REPLY);
627 memcpy(rah->ar_sha, reh->h_source, ETH_ALEN);
628 memcpy(rah->ar_sip, ah->ar_tip, 4);
629 memcpy(rah->ar_tha, ah->ar_sha, ETH_ALEN);
630 memcpy(rah->ar_tip, ah->ar_sip, 4);
631 slirp_output(arp_reply, sizeof(arp_reply));
635 /* reply to request of client mac address ? */
636 if (!memcmp(client_ethaddr, zero_ethaddr, ETH_ALEN) &&
637 !memcmp(ah->ar_sip, &client_ipaddr.s_addr, 4)) {
638 memcpy(client_ethaddr, ah->ar_sha, ETH_ALEN);
646 void slirp_input(const uint8_t *pkt, int pkt_len)
651 if (pkt_len < ETH_HLEN)
654 proto = ntohs(*(uint16_t *)(pkt + 12));
657 arp_input(pkt, pkt_len);
663 /* Note: we add to align the IP header */
664 if (M_FREEROOM(m) < pkt_len + 2) {
665 m_inc(m, pkt_len + 2);
667 m->m_len = pkt_len + 2;
668 memcpy(m->m_data + 2, pkt, pkt_len);
670 m->m_data += 2 + ETH_HLEN;
671 m->m_len -= 2 + ETH_HLEN;
680 /* output the IP packet to the ethernet device */
681 void if_encap(const uint8_t *ip_data, int ip_data_len)
684 struct ethhdr *eh = (struct ethhdr *)buf;
686 if (ip_data_len + ETH_HLEN > sizeof(buf))
689 if (!memcmp(client_ethaddr, zero_ethaddr, ETH_ALEN)) {
690 uint8_t arp_req[ETH_HLEN + sizeof(struct arphdr)];
691 struct ethhdr *reh = (struct ethhdr *)arp_req;
692 struct arphdr *rah = (struct arphdr *)(arp_req + ETH_HLEN);
693 const struct ip *iph = (const struct ip *)ip_data;
695 /* If the client addr is not known, there is no point in
696 sending the packet to it. Normally the sender should have
697 done an ARP request to get its MAC address. Here we do it
698 in place of sending the packet and we hope that the sender
699 will retry sending its packet. */
700 memset(reh->h_dest, 0xff, ETH_ALEN);
701 memcpy(reh->h_source, special_ethaddr, ETH_ALEN - 1);
702 reh->h_source[5] = CTL_ALIAS;
703 reh->h_proto = htons(ETH_P_ARP);
704 rah->ar_hrd = htons(1);
705 rah->ar_pro = htons(ETH_P_IP);
706 rah->ar_hln = ETH_ALEN;
708 rah->ar_op = htons(ARPOP_REQUEST);
710 memcpy(rah->ar_sha, special_ethaddr, ETH_ALEN - 1);
711 rah->ar_sha[5] = CTL_ALIAS;
713 memcpy(rah->ar_sip, &alias_addr, 4);
714 /* target hw addr (none) */
715 memset(rah->ar_tha, 0, ETH_ALEN);
717 memcpy(rah->ar_tip, &iph->ip_dst, 4);
718 client_ipaddr = iph->ip_dst;
719 slirp_output(arp_req, sizeof(arp_req));
721 memcpy(eh->h_dest, client_ethaddr, ETH_ALEN);
722 memcpy(eh->h_source, special_ethaddr, ETH_ALEN - 1);
723 /* XXX: not correct */
724 eh->h_source[5] = CTL_ALIAS;
725 eh->h_proto = htons(ETH_P_IP);
726 memcpy(buf + sizeof(struct ethhdr), ip_data, ip_data_len);
727 slirp_output(buf, ip_data_len + ETH_HLEN);
731 int slirp_redir(int is_udp, int host_port,
732 struct in_addr guest_addr, int guest_port)
735 if (!udp_listen(htons(host_port), guest_addr.s_addr,
736 htons(guest_port), 0))
739 if (!solisten(htons(host_port), guest_addr.s_addr,
740 htons(guest_port), 0))
746 int slirp_add_exec(int do_pty, const void *args, int addr_low_byte,
749 return add_exec(&exec_list, do_pty, (char *)args,
750 addr_low_byte, htons(guest_port));
753 ssize_t slirp_send(struct socket *so, const void *buf, size_t len, int flags)
755 if (so->s == -1 && so->extra) {
756 qemu_chr_write(so->extra, buf, len);
760 return send(so->s, buf, len, flags);
763 static struct socket *slirp_find_ctl_socket(int addr_low_byte, int guest_port)
767 for (so = tcb.so_next; so != &tcb; so = so->so_next) {
768 if ((so->so_faddr.s_addr & htonl(0xffffff00)) ==
770 && (ntohl(so->so_faddr.s_addr) & 0xff) ==
772 && htons(so->so_fport) == guest_port)
779 size_t slirp_socket_can_recv(int addr_low_byte, int guest_port)
787 so = slirp_find_ctl_socket(addr_low_byte, guest_port);
789 if (!so || so->so_state & SS_NOFDREF)
792 if (!CONN_CANFRCV(so) || so->so_snd.sb_cc >= (so->so_snd.sb_datalen/2))
795 return sopreprbuf(so, iov, NULL);
798 void slirp_socket_recv(int addr_low_byte, int guest_port, const uint8_t *buf,
802 struct socket *so = slirp_find_ctl_socket(addr_low_byte, guest_port);
807 ret = soreadbuf(so, buf, size);
810 tcp_output(sototcpcb(so));