File:  [Qemu by Fabrice Bellard] / qemu / slirp / slirp.c
Revision 1.1.1.7 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 17:41:03 2018 UTC (2 years, 11 months ago) by root
Branches: qemu, MAIN
CVS tags: qemu0125, qemu0124, qemu0123, qemu0122, qemu0121, qemu0120, HEAD
qemu 0.12.0

    1: /*
    2:  * libslirp glue
    3:  *
    4:  * Copyright (c) 2004-2008 Fabrice Bellard
    5:  *
    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:
   12:  *
   13:  * The above copyright notice and this permission notice shall be included in
   14:  * all copies or substantial portions of the Software.
   15:  *
   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.
   23:  */
   24: #include "qemu-common.h"
   25: #include "qemu-timer.h"
   26: #include "qemu-char.h"
   27: #include "slirp.h"
   28: #include "hw/hw.h"
   29: 
   30: /* host loopback address */
   31: struct in_addr loopback_addr;
   32: 
   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
   36: };
   37: 
   38: static const uint8_t zero_ethaddr[6] = { 0, 0, 0, 0, 0, 0 };
   39: 
   40: /* XXX: suppress those select globals */
   41: fd_set *global_readfds, *global_writefds, *global_xfds;
   42: 
   43: u_int curtime;
   44: static u_int time_fasttimo, last_slowtimo;
   45: static int do_slowtimo;
   46: 
   47: static QTAILQ_HEAD(slirp_instances, Slirp) slirp_instances =
   48:     QTAILQ_HEAD_INITIALIZER(slirp_instances);
   49: 
   50: static struct in_addr dns_addr;
   51: static u_int dns_addr_time;
   52: 
   53: #ifdef _WIN32
   54: 
   55: int get_dns_addr(struct in_addr *pdns_addr)
   56: {
   57:     FIXED_INFO *FixedInfo=NULL;
   58:     ULONG    BufLen;
   59:     DWORD    ret;
   60:     IP_ADDR_STRING *pIPAddr;
   61:     struct in_addr tmp_addr;
   62: 
   63:     if (dns_addr.s_addr != 0 && (curtime - dns_addr_time) < 1000) {
   64:         *pdns_addr = dns_addr;
   65:         return 0;
   66:     }
   67: 
   68:     FixedInfo = (FIXED_INFO *)GlobalAlloc(GPTR, sizeof(FIXED_INFO));
   69:     BufLen = sizeof(FIXED_INFO);
   70: 
   71:     if (ERROR_BUFFER_OVERFLOW == GetNetworkParams(FixedInfo, &BufLen)) {
   72:         if (FixedInfo) {
   73:             GlobalFree(FixedInfo);
   74:             FixedInfo = NULL;
   75:         }
   76:         FixedInfo = GlobalAlloc(GPTR, BufLen);
   77:     }
   78: 
   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;
   84:         }
   85:         return -1;
   86:     }
   87: 
   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;
   96:     }
   97:     return 0;
   98: }
   99: 
  100: static void winsock_cleanup(void)
  101: {
  102:     WSACleanup();
  103: }
  104: 
  105: #else
  106: 
  107: static struct stat dns_addr_stat;
  108: 
  109: int get_dns_addr(struct in_addr *pdns_addr)
  110: {
  111:     char buff[512];
  112:     char buff2[257];
  113:     FILE *f;
  114:     int found = 0;
  115:     struct in_addr tmp_addr;
  116: 
  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;
  122:         }
  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;
  132:         }
  133:     }
  134: 
  135:     f = fopen("/etc/resolv.conf", "r");
  136:     if (!f)
  137:         return -1;
  138: 
  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;
  151:             }
  152: #ifdef DEBUG
  153:             else
  154:                 lprint(", ");
  155: #endif
  156:             if (++found > 3) {
  157: #ifdef DEBUG
  158:                 lprint("(more)");
  159: #endif
  160:                 break;
  161:             }
  162: #ifdef DEBUG
  163:             else
  164:                 lprint("%s", inet_ntoa(tmp_addr));
  165: #endif
  166:         }
  167:     }
  168:     fclose(f);
  169:     if (!found)
  170:         return -1;
  171:     return 0;
  172: }
  173: 
  174: #endif
  175: 
  176: static void slirp_init_once(void)
  177: {
  178:     static int initialized;
  179: #ifdef _WIN32
  180:     WSADATA Data;
  181: #endif
  182: 
  183:     if (initialized) {
  184:         return;
  185:     }
  186:     initialized = 1;
  187: 
  188: #ifdef _WIN32
  189:     WSAStartup(MAKEWORD(2,0), &Data);
  190:     atexit(winsock_cleanup);
  191: #endif
  192: 
  193:     loopback_addr.s_addr = htonl(INADDR_LOOPBACK);
  194: }
  195: 
  196: static void slirp_state_save(QEMUFile *f, void *opaque);
  197: static int slirp_state_load(QEMUFile *f, void *opaque, int version_id);
  198: 
  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)
  204: {
  205:     Slirp *slirp = qemu_mallocz(sizeof(Slirp));
  206: 
  207:     slirp_init_once();
  208: 
  209:     slirp->restricted = restricted;
  210: 
  211:     if_init(slirp);
  212:     ip_init(slirp);
  213: 
  214:     /* Initialise mbufs *after* setting the MTU */
  215:     m_init(slirp);
  216: 
  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);
  223:     }
  224:     if (tftp_path) {
  225:         slirp->tftp_prefix = qemu_strdup(tftp_path);
  226:     }
  227:     if (bootfile) {
  228:         slirp->bootp_filename = qemu_strdup(bootfile);
  229:     }
  230:     slirp->vdhcp_startaddr = vdhcp_start;
  231:     slirp->vnameserver_addr = vnameserver;
  232: 
  233:     slirp->opaque = opaque;
  234: 
  235:     register_savevm("slirp", 0, 3, slirp_state_save, slirp_state_load, slirp);
  236: 
  237:     QTAILQ_INSERT_TAIL(&slirp_instances, slirp, entry);
  238: 
  239:     return slirp;
  240: }
  241: 
  242: void slirp_cleanup(Slirp *slirp)
  243: {
  244:     QTAILQ_REMOVE(&slirp_instances, slirp, entry);
  245: 
  246:     unregister_savevm("slirp", slirp);
  247: 
  248:     qemu_free(slirp->tftp_prefix);
  249:     qemu_free(slirp->bootp_filename);
  250:     qemu_free(slirp);
  251: }
  252: 
  253: #define CONN_CANFSEND(so) (((so)->so_state & (SS_FCANTSENDMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED)
  254: #define CONN_CANFRCV(so) (((so)->so_state & (SS_FCANTRCVMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED)
  255: #define UPD_NFDS(x) if (nfds < (x)) nfds = (x)
  256: 
  257: void slirp_select_fill(int *pnfds,
  258:                        fd_set *readfds, fd_set *writefds, fd_set *xfds)
  259: {
  260:     Slirp *slirp;
  261:     struct socket *so, *so_next;
  262:     int nfds;
  263: 
  264:     if (QTAILQ_EMPTY(&slirp_instances)) {
  265:         return;
  266:     }
  267: 
  268:     /* fail safe */
  269:     global_readfds = NULL;
  270:     global_writefds = NULL;
  271:     global_xfds = NULL;
  272: 
  273:     nfds = *pnfds;
  274: 	/*
  275: 	 * First, TCP sockets
  276: 	 */
  277: 	do_slowtimo = 0;
  278: 
  279: 	QTAILQ_FOREACH(slirp, &slirp_instances, entry) {
  280: 		/*
  281: 		 * *_slowtimo needs calling if there are IP fragments
  282: 		 * in the fragment queue, or there are TCP connections active
  283: 		 */
  284: 		do_slowtimo |= ((slirp->tcb.so_next != &slirp->tcb) ||
  285: 		    (&slirp->ipq.ip_link != slirp->ipq.ip_link.next));
  286: 
  287: 		for (so = slirp->tcb.so_next; so != &slirp->tcb;
  288: 		     so = so_next) {
  289: 			so_next = so->so_next;
  290: 
  291: 			/*
  292: 			 * See if we need a tcp_fasttimo
  293: 			 */
  294: 			if (time_fasttimo == 0 && so->so_tcpcb->t_flags & TF_DELACK)
  295: 			   time_fasttimo = curtime; /* Flag when we want a fasttimo */
  296: 
  297: 			/*
  298: 			 * NOFDREF can include still connecting to local-host,
  299: 			 * newly socreated() sockets etc. Don't want to select these.
  300: 	 		 */
  301: 			if (so->so_state & SS_NOFDREF || so->s == -1)
  302: 			   continue;
  303: 
  304: 			/*
  305: 			 * Set for reading sockets which are accepting
  306: 			 */
  307: 			if (so->so_state & SS_FACCEPTCONN) {
  308:                                 FD_SET(so->s, readfds);
  309: 				UPD_NFDS(so->s);
  310: 				continue;
  311: 			}
  312: 
  313: 			/*
  314: 			 * Set for writing sockets which are connecting
  315: 			 */
  316: 			if (so->so_state & SS_ISFCONNECTING) {
  317: 				FD_SET(so->s, writefds);
  318: 				UPD_NFDS(so->s);
  319: 				continue;
  320: 			}
  321: 
  322: 			/*
  323: 			 * Set for writing if we are connected, can send more, and
  324: 			 * we have something to send
  325: 			 */
  326: 			if (CONN_CANFSEND(so) && so->so_rcv.sb_cc) {
  327: 				FD_SET(so->s, writefds);
  328: 				UPD_NFDS(so->s);
  329: 			}
  330: 
  331: 			/*
  332: 			 * Set for reading (and urgent data) if we are connected, can
  333: 			 * receive more, and we have room for it XXX /2 ?
  334: 			 */
  335: 			if (CONN_CANFRCV(so) && (so->so_snd.sb_cc < (so->so_snd.sb_datalen/2))) {
  336: 				FD_SET(so->s, readfds);
  337: 				FD_SET(so->s, xfds);
  338: 				UPD_NFDS(so->s);
  339: 			}
  340: 		}
  341: 
  342: 		/*
  343: 		 * UDP sockets
  344: 		 */
  345: 		for (so = slirp->udb.so_next; so != &slirp->udb;
  346: 		     so = so_next) {
  347: 			so_next = so->so_next;
  348: 
  349: 			/*
  350: 			 * See if it's timed out
  351: 			 */
  352: 			if (so->so_expire) {
  353: 				if (so->so_expire <= curtime) {
  354: 					udp_detach(so);
  355: 					continue;
  356: 				} else
  357: 					do_slowtimo = 1; /* Let socket expire */
  358: 			}
  359: 
  360: 			/*
  361: 			 * When UDP packets are received from over the
  362: 			 * link, they're sendto()'d straight away, so
  363: 			 * no need for setting for writing
  364: 			 * Limit the number of packets queued by this session
  365: 			 * to 4.  Note that even though we try and limit this
  366: 			 * to 4 packets, the session could have more queued
  367: 			 * if the packets needed to be fragmented
  368: 			 * (XXX <= 4 ?)
  369: 			 */
  370: 			if ((so->so_state & SS_ISFCONNECTED) && so->so_queued <= 4) {
  371: 				FD_SET(so->s, readfds);
  372: 				UPD_NFDS(so->s);
  373: 			}
  374: 		}
  375: 	}
  376: 
  377:         *pnfds = nfds;
  378: }
  379: 
  380: void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds,
  381:                        int select_error)
  382: {
  383:     Slirp *slirp;
  384:     struct socket *so, *so_next;
  385:     int ret;
  386: 
  387:     if (QTAILQ_EMPTY(&slirp_instances)) {
  388:         return;
  389:     }
  390: 
  391:     global_readfds = readfds;
  392:     global_writefds = writefds;
  393:     global_xfds = xfds;
  394: 
  395:     curtime = qemu_get_clock(rt_clock);
  396: 
  397:     QTAILQ_FOREACH(slirp, &slirp_instances, entry) {
  398: 	/*
  399: 	 * See if anything has timed out
  400: 	 */
  401: 		if (time_fasttimo && ((curtime - time_fasttimo) >= 2)) {
  402: 			tcp_fasttimo(slirp);
  403: 			time_fasttimo = 0;
  404: 		}
  405: 		if (do_slowtimo && ((curtime - last_slowtimo) >= 499)) {
  406: 			ip_slowtimo(slirp);
  407: 			tcp_slowtimo(slirp);
  408: 			last_slowtimo = curtime;
  409: 		}
  410: 
  411: 	/*
  412: 	 * Check sockets
  413: 	 */
  414: 	if (!select_error) {
  415: 		/*
  416: 		 * Check TCP sockets
  417: 		 */
  418: 		for (so = slirp->tcb.so_next; so != &slirp->tcb;
  419: 		     so = so_next) {
  420: 			so_next = so->so_next;
  421: 
  422: 			/*
  423: 			 * FD_ISSET is meaningless on these sockets
  424: 			 * (and they can crash the program)
  425: 			 */
  426: 			if (so->so_state & SS_NOFDREF || so->s == -1)
  427: 			   continue;
  428: 
  429: 			/*
  430: 			 * Check for URG data
  431: 			 * This will soread as well, so no need to
  432: 			 * test for readfds below if this succeeds
  433: 			 */
  434: 			if (FD_ISSET(so->s, xfds))
  435: 			   sorecvoob(so);
  436: 			/*
  437: 			 * Check sockets for reading
  438: 			 */
  439: 			else if (FD_ISSET(so->s, readfds)) {
  440: 				/*
  441: 				 * Check for incoming connections
  442: 				 */
  443: 				if (so->so_state & SS_FACCEPTCONN) {
  444: 					tcp_connect(so);
  445: 					continue;
  446: 				} /* else */
  447: 				ret = soread(so);
  448: 
  449: 				/* Output it if we read something */
  450: 				if (ret > 0)
  451: 				   tcp_output(sototcpcb(so));
  452: 			}
  453: 
  454: 			/*
  455: 			 * Check sockets for writing
  456: 			 */
  457: 			if (FD_ISSET(so->s, writefds)) {
  458: 			  /*
  459: 			   * Check for non-blocking, still-connecting sockets
  460: 			   */
  461: 			  if (so->so_state & SS_ISFCONNECTING) {
  462: 			    /* Connected */
  463: 			    so->so_state &= ~SS_ISFCONNECTING;
  464: 
  465: 			    ret = send(so->s, (const void *) &ret, 0, 0);
  466: 			    if (ret < 0) {
  467: 			      /* XXXXX Must fix, zero bytes is a NOP */
  468: 			      if (errno == EAGAIN || errno == EWOULDBLOCK ||
  469: 				  errno == EINPROGRESS || errno == ENOTCONN)
  470: 				continue;
  471: 
  472: 			      /* else failed */
  473: 			      so->so_state &= SS_PERSISTENT_MASK;
  474: 			      so->so_state |= SS_NOFDREF;
  475: 			    }
  476: 			    /* else so->so_state &= ~SS_ISFCONNECTING; */
  477: 
  478: 			    /*
  479: 			     * Continue tcp_input
  480: 			     */
  481: 			    tcp_input((struct mbuf *)NULL, sizeof(struct ip), so);
  482: 			    /* continue; */
  483: 			  } else
  484: 			    ret = sowrite(so);
  485: 			  /*
  486: 			   * XXXXX If we wrote something (a lot), there
  487: 			   * could be a need for a window update.
  488: 			   * In the worst case, the remote will send
  489: 			   * a window probe to get things going again
  490: 			   */
  491: 			}
  492: 
  493: 			/*
  494: 			 * Probe a still-connecting, non-blocking socket
  495: 			 * to check if it's still alive
  496: 	 	 	 */
  497: #ifdef PROBE_CONN
  498: 			if (so->so_state & SS_ISFCONNECTING) {
  499: 			  ret = recv(so->s, (char *)&ret, 0,0);
  500: 
  501: 			  if (ret < 0) {
  502: 			    /* XXX */
  503: 			    if (errno == EAGAIN || errno == EWOULDBLOCK ||
  504: 				errno == EINPROGRESS || errno == ENOTCONN)
  505: 			      continue; /* Still connecting, continue */
  506: 
  507: 			    /* else failed */
  508: 			    so->so_state &= SS_PERSISTENT_MASK;
  509: 			    so->so_state |= SS_NOFDREF;
  510: 
  511: 			    /* tcp_input will take care of it */
  512: 			  } else {
  513: 			    ret = send(so->s, &ret, 0,0);
  514: 			    if (ret < 0) {
  515: 			      /* XXX */
  516: 			      if (errno == EAGAIN || errno == EWOULDBLOCK ||
  517: 				  errno == EINPROGRESS || errno == ENOTCONN)
  518: 				continue;
  519: 			      /* else failed */
  520: 			      so->so_state &= SS_PERSISTENT_MASK;
  521: 			      so->so_state |= SS_NOFDREF;
  522: 			    } else
  523: 			      so->so_state &= ~SS_ISFCONNECTING;
  524: 
  525: 			  }
  526: 			  tcp_input((struct mbuf *)NULL, sizeof(struct ip),so);
  527: 			} /* SS_ISFCONNECTING */
  528: #endif
  529: 		}
  530: 
  531: 		/*
  532: 		 * Now UDP sockets.
  533: 		 * Incoming packets are sent straight away, they're not buffered.
  534: 		 * Incoming UDP data isn't buffered either.
  535: 		 */
  536: 		for (so = slirp->udb.so_next; so != &slirp->udb;
  537: 		     so = so_next) {
  538: 			so_next = so->so_next;
  539: 
  540: 			if (so->s != -1 && FD_ISSET(so->s, readfds)) {
  541:                             sorecvfrom(so);
  542:                         }
  543: 		}
  544: 	}
  545: 
  546: 	/*
  547: 	 * See if we can start outputting
  548: 	 */
  549: 	if (slirp->if_queued) {
  550: 	    if_start(slirp);
  551: 	}
  552:     }
  553: 
  554: 	/* clear global file descriptor sets.
  555: 	 * these reside on the stack in vl.c
  556: 	 * so they're unusable if we're not in
  557: 	 * slirp_select_fill or slirp_select_poll.
  558: 	 */
  559: 	 global_readfds = NULL;
  560: 	 global_writefds = NULL;
  561: 	 global_xfds = NULL;
  562: }
  563: 
  564: #define ETH_ALEN 6
  565: #define ETH_HLEN 14
  566: 
  567: #define ETH_P_IP	0x0800		/* Internet Protocol packet	*/
  568: #define ETH_P_ARP	0x0806		/* Address Resolution packet	*/
  569: 
  570: #define	ARPOP_REQUEST	1		/* ARP request			*/
  571: #define	ARPOP_REPLY	2		/* ARP reply			*/
  572: 
  573: struct ethhdr
  574: {
  575: 	unsigned char	h_dest[ETH_ALEN];	/* destination eth addr	*/
  576: 	unsigned char	h_source[ETH_ALEN];	/* source ether addr	*/
  577: 	unsigned short	h_proto;		/* packet type ID field	*/
  578: };
  579: 
  580: struct arphdr
  581: {
  582: 	unsigned short	ar_hrd;		/* format of hardware address	*/
  583: 	unsigned short	ar_pro;		/* format of protocol address	*/
  584: 	unsigned char	ar_hln;		/* length of hardware address	*/
  585: 	unsigned char	ar_pln;		/* length of protocol address	*/
  586: 	unsigned short	ar_op;		/* ARP opcode (command)		*/
  587: 
  588: 	 /*
  589: 	  *	 Ethernet looks like this : This bit is variable sized however...
  590: 	  */
  591: 	unsigned char		ar_sha[ETH_ALEN];	/* sender hardware address	*/
  592: 	uint32_t		ar_sip;			/* sender IP address		*/
  593: 	unsigned char		ar_tha[ETH_ALEN];	/* target hardware address	*/
  594: 	uint32_t		ar_tip	;		/* target IP address		*/
  595: } __attribute__((packed));
  596: 
  597: static void arp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len)
  598: {
  599:     struct ethhdr *eh = (struct ethhdr *)pkt;
  600:     struct arphdr *ah = (struct arphdr *)(pkt + ETH_HLEN);
  601:     uint8_t arp_reply[ETH_HLEN + sizeof(struct arphdr)];
  602:     struct ethhdr *reh = (struct ethhdr *)arp_reply;
  603:     struct arphdr *rah = (struct arphdr *)(arp_reply + ETH_HLEN);
  604:     int ar_op;
  605:     struct ex_list *ex_ptr;
  606: 
  607:     ar_op = ntohs(ah->ar_op);
  608:     switch(ar_op) {
  609:     case ARPOP_REQUEST:
  610:         if ((ah->ar_tip & slirp->vnetwork_mask.s_addr) ==
  611:             slirp->vnetwork_addr.s_addr) {
  612:             if (ah->ar_tip == slirp->vnameserver_addr.s_addr ||
  613:                 ah->ar_tip == slirp->vhost_addr.s_addr)
  614:                 goto arp_ok;
  615:             for (ex_ptr = slirp->exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
  616:                 if (ex_ptr->ex_addr.s_addr == ah->ar_tip)
  617:                     goto arp_ok;
  618:             }
  619:             return;
  620:         arp_ok:
  621:             /* XXX: make an ARP request to have the client address */
  622:             memcpy(slirp->client_ethaddr, eh->h_source, ETH_ALEN);
  623: 
  624:             /* ARP request for alias/dns mac address */
  625:             memcpy(reh->h_dest, pkt + ETH_ALEN, ETH_ALEN);
  626:             memcpy(reh->h_source, special_ethaddr, ETH_ALEN - 4);
  627:             memcpy(&reh->h_source[2], &ah->ar_tip, 4);
  628:             reh->h_proto = htons(ETH_P_ARP);
  629: 
  630:             rah->ar_hrd = htons(1);
  631:             rah->ar_pro = htons(ETH_P_IP);
  632:             rah->ar_hln = ETH_ALEN;
  633:             rah->ar_pln = 4;
  634:             rah->ar_op = htons(ARPOP_REPLY);
  635:             memcpy(rah->ar_sha, reh->h_source, ETH_ALEN);
  636:             rah->ar_sip = ah->ar_tip;
  637:             memcpy(rah->ar_tha, ah->ar_sha, ETH_ALEN);
  638:             rah->ar_tip = ah->ar_sip;
  639:             slirp_output(slirp->opaque, arp_reply, sizeof(arp_reply));
  640:         }
  641:         break;
  642:     case ARPOP_REPLY:
  643:         /* reply to request of client mac address ? */
  644:         if (!memcmp(slirp->client_ethaddr, zero_ethaddr, ETH_ALEN) &&
  645:             ah->ar_sip == slirp->client_ipaddr.s_addr) {
  646:             memcpy(slirp->client_ethaddr, ah->ar_sha, ETH_ALEN);
  647:         }
  648:         break;
  649:     default:
  650:         break;
  651:     }
  652: }
  653: 
  654: void slirp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len)
  655: {
  656:     struct mbuf *m;
  657:     int proto;
  658: 
  659:     if (pkt_len < ETH_HLEN)
  660:         return;
  661: 
  662:     proto = ntohs(*(uint16_t *)(pkt + 12));
  663:     switch(proto) {
  664:     case ETH_P_ARP:
  665:         arp_input(slirp, pkt, pkt_len);
  666:         break;
  667:     case ETH_P_IP:
  668:         m = m_get(slirp);
  669:         if (!m)
  670:             return;
  671:         /* Note: we add to align the IP header */
  672:         if (M_FREEROOM(m) < pkt_len + 2) {
  673:             m_inc(m, pkt_len + 2);
  674:         }
  675:         m->m_len = pkt_len + 2;
  676:         memcpy(m->m_data + 2, pkt, pkt_len);
  677: 
  678:         m->m_data += 2 + ETH_HLEN;
  679:         m->m_len -= 2 + ETH_HLEN;
  680: 
  681:         ip_input(m);
  682:         break;
  683:     default:
  684:         break;
  685:     }
  686: }
  687: 
  688: /* output the IP packet to the ethernet device */
  689: void if_encap(Slirp *slirp, const uint8_t *ip_data, int ip_data_len)
  690: {
  691:     uint8_t buf[1600];
  692:     struct ethhdr *eh = (struct ethhdr *)buf;
  693: 
  694:     if (ip_data_len + ETH_HLEN > sizeof(buf))
  695:         return;
  696:     
  697:     if (!memcmp(slirp->client_ethaddr, zero_ethaddr, ETH_ALEN)) {
  698:         uint8_t arp_req[ETH_HLEN + sizeof(struct arphdr)];
  699:         struct ethhdr *reh = (struct ethhdr *)arp_req;
  700:         struct arphdr *rah = (struct arphdr *)(arp_req + ETH_HLEN);
  701:         const struct ip *iph = (const struct ip *)ip_data;
  702: 
  703:         /* If the client addr is not known, there is no point in
  704:            sending the packet to it. Normally the sender should have
  705:            done an ARP request to get its MAC address. Here we do it
  706:            in place of sending the packet and we hope that the sender
  707:            will retry sending its packet. */
  708:         memset(reh->h_dest, 0xff, ETH_ALEN);
  709:         memcpy(reh->h_source, special_ethaddr, ETH_ALEN - 4);
  710:         memcpy(&reh->h_source[2], &slirp->vhost_addr, 4);
  711:         reh->h_proto = htons(ETH_P_ARP);
  712:         rah->ar_hrd = htons(1);
  713:         rah->ar_pro = htons(ETH_P_IP);
  714:         rah->ar_hln = ETH_ALEN;
  715:         rah->ar_pln = 4;
  716:         rah->ar_op = htons(ARPOP_REQUEST);
  717:         /* source hw addr */
  718:         memcpy(rah->ar_sha, special_ethaddr, ETH_ALEN - 4);
  719:         memcpy(&rah->ar_sha[2], &slirp->vhost_addr, 4);
  720:         /* source IP */
  721:         rah->ar_sip = slirp->vhost_addr.s_addr;
  722:         /* target hw addr (none) */
  723:         memset(rah->ar_tha, 0, ETH_ALEN);
  724:         /* target IP */
  725:         rah->ar_tip = iph->ip_dst.s_addr;
  726:         slirp->client_ipaddr = iph->ip_dst;
  727:         slirp_output(slirp->opaque, arp_req, sizeof(arp_req));
  728:     } else {
  729:         memcpy(eh->h_dest, slirp->client_ethaddr, ETH_ALEN);
  730:         memcpy(eh->h_source, special_ethaddr, ETH_ALEN - 4);
  731:         /* XXX: not correct */
  732:         memcpy(&eh->h_source[2], &slirp->vhost_addr, 4);
  733:         eh->h_proto = htons(ETH_P_IP);
  734:         memcpy(buf + sizeof(struct ethhdr), ip_data, ip_data_len);
  735:         slirp_output(slirp->opaque, buf, ip_data_len + ETH_HLEN);
  736:     }
  737: }
  738: 
  739: /* Drop host forwarding rule, return 0 if found. */
  740: int slirp_remove_hostfwd(Slirp *slirp, int is_udp, struct in_addr host_addr,
  741:                          int host_port)
  742: {
  743:     struct socket *so;
  744:     struct socket *head = (is_udp ? &slirp->udb : &slirp->tcb);
  745:     struct sockaddr_in addr;
  746:     int port = htons(host_port);
  747:     socklen_t addr_len;
  748: 
  749:     for (so = head->so_next; so != head; so = so->so_next) {
  750:         addr_len = sizeof(addr);
  751:         if ((so->so_state & SS_HOSTFWD) &&
  752:             getsockname(so->s, (struct sockaddr *)&addr, &addr_len) == 0 &&
  753:             addr.sin_addr.s_addr == host_addr.s_addr &&
  754:             addr.sin_port == port) {
  755:             close(so->s);
  756:             sofree(so);
  757:             return 0;
  758:         }
  759:     }
  760: 
  761:     return -1;
  762: }
  763: 
  764: int slirp_add_hostfwd(Slirp *slirp, int is_udp, struct in_addr host_addr,
  765:                       int host_port, struct in_addr guest_addr, int guest_port)
  766: {
  767:     if (!guest_addr.s_addr) {
  768:         guest_addr = slirp->vdhcp_startaddr;
  769:     }
  770:     if (is_udp) {
  771:         if (!udp_listen(slirp, host_addr.s_addr, htons(host_port),
  772:                         guest_addr.s_addr, htons(guest_port), SS_HOSTFWD))
  773:             return -1;
  774:     } else {
  775:         if (!tcp_listen(slirp, host_addr.s_addr, htons(host_port),
  776:                         guest_addr.s_addr, htons(guest_port), SS_HOSTFWD))
  777:             return -1;
  778:     }
  779:     return 0;
  780: }
  781: 
  782: int slirp_add_exec(Slirp *slirp, int do_pty, const void *args,
  783:                    struct in_addr *guest_addr, int guest_port)
  784: {
  785:     if (!guest_addr->s_addr) {
  786:         guest_addr->s_addr = slirp->vnetwork_addr.s_addr |
  787:             (htonl(0x0204) & ~slirp->vnetwork_mask.s_addr);
  788:     }
  789:     if ((guest_addr->s_addr & slirp->vnetwork_mask.s_addr) !=
  790:         slirp->vnetwork_addr.s_addr ||
  791:         guest_addr->s_addr == slirp->vhost_addr.s_addr ||
  792:         guest_addr->s_addr == slirp->vnameserver_addr.s_addr) {
  793:         return -1;
  794:     }
  795:     return add_exec(&slirp->exec_list, do_pty, (char *)args, *guest_addr,
  796:                     htons(guest_port));
  797: }
  798: 
  799: ssize_t slirp_send(struct socket *so, const void *buf, size_t len, int flags)
  800: {
  801: 	if (so->s == -1 && so->extra) {
  802: 		qemu_chr_write(so->extra, buf, len);
  803: 		return len;
  804: 	}
  805: 
  806: 	return send(so->s, buf, len, flags);
  807: }
  808: 
  809: static struct socket *
  810: slirp_find_ctl_socket(Slirp *slirp, struct in_addr guest_addr, int guest_port)
  811: {
  812:     struct socket *so;
  813: 
  814:     for (so = slirp->tcb.so_next; so != &slirp->tcb; so = so->so_next) {
  815:         if (so->so_faddr.s_addr == guest_addr.s_addr &&
  816:             htons(so->so_fport) == guest_port) {
  817:             return so;
  818:         }
  819:     }
  820:     return NULL;
  821: }
  822: 
  823: size_t slirp_socket_can_recv(Slirp *slirp, struct in_addr guest_addr,
  824:                              int guest_port)
  825: {
  826: 	struct iovec iov[2];
  827: 	struct socket *so;
  828: 
  829: 	so = slirp_find_ctl_socket(slirp, guest_addr, guest_port);
  830: 
  831: 	if (!so || so->so_state & SS_NOFDREF)
  832: 		return 0;
  833: 
  834: 	if (!CONN_CANFRCV(so) || so->so_snd.sb_cc >= (so->so_snd.sb_datalen/2))
  835: 		return 0;
  836: 
  837: 	return sopreprbuf(so, iov, NULL);
  838: }
  839: 
  840: void slirp_socket_recv(Slirp *slirp, struct in_addr guest_addr, int guest_port,
  841:                        const uint8_t *buf, int size)
  842: {
  843:     int ret;
  844:     struct socket *so = slirp_find_ctl_socket(slirp, guest_addr, guest_port);
  845: 
  846:     if (!so)
  847:         return;
  848: 
  849:     ret = soreadbuf(so, (const char *)buf, size);
  850: 
  851:     if (ret > 0)
  852:         tcp_output(sototcpcb(so));
  853: }
  854: 
  855: static void slirp_tcp_save(QEMUFile *f, struct tcpcb *tp)
  856: {
  857:     int i;
  858: 
  859:     qemu_put_sbe16(f, tp->t_state);
  860:     for (i = 0; i < TCPT_NTIMERS; i++)
  861:         qemu_put_sbe16(f, tp->t_timer[i]);
  862:     qemu_put_sbe16(f, tp->t_rxtshift);
  863:     qemu_put_sbe16(f, tp->t_rxtcur);
  864:     qemu_put_sbe16(f, tp->t_dupacks);
  865:     qemu_put_be16(f, tp->t_maxseg);
  866:     qemu_put_sbyte(f, tp->t_force);
  867:     qemu_put_be16(f, tp->t_flags);
  868:     qemu_put_be32(f, tp->snd_una);
  869:     qemu_put_be32(f, tp->snd_nxt);
  870:     qemu_put_be32(f, tp->snd_up);
  871:     qemu_put_be32(f, tp->snd_wl1);
  872:     qemu_put_be32(f, tp->snd_wl2);
  873:     qemu_put_be32(f, tp->iss);
  874:     qemu_put_be32(f, tp->snd_wnd);
  875:     qemu_put_be32(f, tp->rcv_wnd);
  876:     qemu_put_be32(f, tp->rcv_nxt);
  877:     qemu_put_be32(f, tp->rcv_up);
  878:     qemu_put_be32(f, tp->irs);
  879:     qemu_put_be32(f, tp->rcv_adv);
  880:     qemu_put_be32(f, tp->snd_max);
  881:     qemu_put_be32(f, tp->snd_cwnd);
  882:     qemu_put_be32(f, tp->snd_ssthresh);
  883:     qemu_put_sbe16(f, tp->t_idle);
  884:     qemu_put_sbe16(f, tp->t_rtt);
  885:     qemu_put_be32(f, tp->t_rtseq);
  886:     qemu_put_sbe16(f, tp->t_srtt);
  887:     qemu_put_sbe16(f, tp->t_rttvar);
  888:     qemu_put_be16(f, tp->t_rttmin);
  889:     qemu_put_be32(f, tp->max_sndwnd);
  890:     qemu_put_byte(f, tp->t_oobflags);
  891:     qemu_put_byte(f, tp->t_iobc);
  892:     qemu_put_sbe16(f, tp->t_softerror);
  893:     qemu_put_byte(f, tp->snd_scale);
  894:     qemu_put_byte(f, tp->rcv_scale);
  895:     qemu_put_byte(f, tp->request_r_scale);
  896:     qemu_put_byte(f, tp->requested_s_scale);
  897:     qemu_put_be32(f, tp->ts_recent);
  898:     qemu_put_be32(f, tp->ts_recent_age);
  899:     qemu_put_be32(f, tp->last_ack_sent);
  900: }
  901: 
  902: static void slirp_sbuf_save(QEMUFile *f, struct sbuf *sbuf)
  903: {
  904:     uint32_t off;
  905: 
  906:     qemu_put_be32(f, sbuf->sb_cc);
  907:     qemu_put_be32(f, sbuf->sb_datalen);
  908:     off = (uint32_t)(sbuf->sb_wptr - sbuf->sb_data);
  909:     qemu_put_sbe32(f, off);
  910:     off = (uint32_t)(sbuf->sb_rptr - sbuf->sb_data);
  911:     qemu_put_sbe32(f, off);
  912:     qemu_put_buffer(f, (unsigned char*)sbuf->sb_data, sbuf->sb_datalen);
  913: }
  914: 
  915: static void slirp_socket_save(QEMUFile *f, struct socket *so)
  916: {
  917:     qemu_put_be32(f, so->so_urgc);
  918:     qemu_put_be32(f, so->so_faddr.s_addr);
  919:     qemu_put_be32(f, so->so_laddr.s_addr);
  920:     qemu_put_be16(f, so->so_fport);
  921:     qemu_put_be16(f, so->so_lport);
  922:     qemu_put_byte(f, so->so_iptos);
  923:     qemu_put_byte(f, so->so_emu);
  924:     qemu_put_byte(f, so->so_type);
  925:     qemu_put_be32(f, so->so_state);
  926:     slirp_sbuf_save(f, &so->so_rcv);
  927:     slirp_sbuf_save(f, &so->so_snd);
  928:     slirp_tcp_save(f, so->so_tcpcb);
  929: }
  930: 
  931: static void slirp_bootp_save(QEMUFile *f, Slirp *slirp)
  932: {
  933:     int i;
  934: 
  935:     for (i = 0; i < NB_BOOTP_CLIENTS; i++) {
  936:         qemu_put_be16(f, slirp->bootp_clients[i].allocated);
  937:         qemu_put_buffer(f, slirp->bootp_clients[i].macaddr, 6);
  938:     }
  939: }
  940: 
  941: static void slirp_state_save(QEMUFile *f, void *opaque)
  942: {
  943:     Slirp *slirp = opaque;
  944:     struct ex_list *ex_ptr;
  945: 
  946:     for (ex_ptr = slirp->exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next)
  947:         if (ex_ptr->ex_pty == 3) {
  948:             struct socket *so;
  949:             so = slirp_find_ctl_socket(slirp, ex_ptr->ex_addr,
  950:                                        ntohs(ex_ptr->ex_fport));
  951:             if (!so)
  952:                 continue;
  953: 
  954:             qemu_put_byte(f, 42);
  955:             slirp_socket_save(f, so);
  956:         }
  957:     qemu_put_byte(f, 0);
  958: 
  959:     qemu_put_be16(f, slirp->ip_id);
  960: 
  961:     slirp_bootp_save(f, slirp);
  962: }
  963: 
  964: static void slirp_tcp_load(QEMUFile *f, struct tcpcb *tp)
  965: {
  966:     int i;
  967: 
  968:     tp->t_state = qemu_get_sbe16(f);
  969:     for (i = 0; i < TCPT_NTIMERS; i++)
  970:         tp->t_timer[i] = qemu_get_sbe16(f);
  971:     tp->t_rxtshift = qemu_get_sbe16(f);
  972:     tp->t_rxtcur = qemu_get_sbe16(f);
  973:     tp->t_dupacks = qemu_get_sbe16(f);
  974:     tp->t_maxseg = qemu_get_be16(f);
  975:     tp->t_force = qemu_get_sbyte(f);
  976:     tp->t_flags = qemu_get_be16(f);
  977:     tp->snd_una = qemu_get_be32(f);
  978:     tp->snd_nxt = qemu_get_be32(f);
  979:     tp->snd_up = qemu_get_be32(f);
  980:     tp->snd_wl1 = qemu_get_be32(f);
  981:     tp->snd_wl2 = qemu_get_be32(f);
  982:     tp->iss = qemu_get_be32(f);
  983:     tp->snd_wnd = qemu_get_be32(f);
  984:     tp->rcv_wnd = qemu_get_be32(f);
  985:     tp->rcv_nxt = qemu_get_be32(f);
  986:     tp->rcv_up = qemu_get_be32(f);
  987:     tp->irs = qemu_get_be32(f);
  988:     tp->rcv_adv = qemu_get_be32(f);
  989:     tp->snd_max = qemu_get_be32(f);
  990:     tp->snd_cwnd = qemu_get_be32(f);
  991:     tp->snd_ssthresh = qemu_get_be32(f);
  992:     tp->t_idle = qemu_get_sbe16(f);
  993:     tp->t_rtt = qemu_get_sbe16(f);
  994:     tp->t_rtseq = qemu_get_be32(f);
  995:     tp->t_srtt = qemu_get_sbe16(f);
  996:     tp->t_rttvar = qemu_get_sbe16(f);
  997:     tp->t_rttmin = qemu_get_be16(f);
  998:     tp->max_sndwnd = qemu_get_be32(f);
  999:     tp->t_oobflags = qemu_get_byte(f);
 1000:     tp->t_iobc = qemu_get_byte(f);
 1001:     tp->t_softerror = qemu_get_sbe16(f);
 1002:     tp->snd_scale = qemu_get_byte(f);
 1003:     tp->rcv_scale = qemu_get_byte(f);
 1004:     tp->request_r_scale = qemu_get_byte(f);
 1005:     tp->requested_s_scale = qemu_get_byte(f);
 1006:     tp->ts_recent = qemu_get_be32(f);
 1007:     tp->ts_recent_age = qemu_get_be32(f);
 1008:     tp->last_ack_sent = qemu_get_be32(f);
 1009:     tcp_template(tp);
 1010: }
 1011: 
 1012: static int slirp_sbuf_load(QEMUFile *f, struct sbuf *sbuf)
 1013: {
 1014:     uint32_t off, sb_cc, sb_datalen;
 1015: 
 1016:     sb_cc = qemu_get_be32(f);
 1017:     sb_datalen = qemu_get_be32(f);
 1018: 
 1019:     sbreserve(sbuf, sb_datalen);
 1020: 
 1021:     if (sbuf->sb_datalen != sb_datalen)
 1022:         return -ENOMEM;
 1023: 
 1024:     sbuf->sb_cc = sb_cc;
 1025: 
 1026:     off = qemu_get_sbe32(f);
 1027:     sbuf->sb_wptr = sbuf->sb_data + off;
 1028:     off = qemu_get_sbe32(f);
 1029:     sbuf->sb_rptr = sbuf->sb_data + off;
 1030:     qemu_get_buffer(f, (unsigned char*)sbuf->sb_data, sbuf->sb_datalen);
 1031: 
 1032:     return 0;
 1033: }
 1034: 
 1035: static int slirp_socket_load(QEMUFile *f, struct socket *so)
 1036: {
 1037:     if (tcp_attach(so) < 0)
 1038:         return -ENOMEM;
 1039: 
 1040:     so->so_urgc = qemu_get_be32(f);
 1041:     so->so_faddr.s_addr = qemu_get_be32(f);
 1042:     so->so_laddr.s_addr = qemu_get_be32(f);
 1043:     so->so_fport = qemu_get_be16(f);
 1044:     so->so_lport = qemu_get_be16(f);
 1045:     so->so_iptos = qemu_get_byte(f);
 1046:     so->so_emu = qemu_get_byte(f);
 1047:     so->so_type = qemu_get_byte(f);
 1048:     so->so_state = qemu_get_be32(f);
 1049:     if (slirp_sbuf_load(f, &so->so_rcv) < 0)
 1050:         return -ENOMEM;
 1051:     if (slirp_sbuf_load(f, &so->so_snd) < 0)
 1052:         return -ENOMEM;
 1053:     slirp_tcp_load(f, so->so_tcpcb);
 1054: 
 1055:     return 0;
 1056: }
 1057: 
 1058: static void slirp_bootp_load(QEMUFile *f, Slirp *slirp)
 1059: {
 1060:     int i;
 1061: 
 1062:     for (i = 0; i < NB_BOOTP_CLIENTS; i++) {
 1063:         slirp->bootp_clients[i].allocated = qemu_get_be16(f);
 1064:         qemu_get_buffer(f, slirp->bootp_clients[i].macaddr, 6);
 1065:     }
 1066: }
 1067: 
 1068: static int slirp_state_load(QEMUFile *f, void *opaque, int version_id)
 1069: {
 1070:     Slirp *slirp = opaque;
 1071:     struct ex_list *ex_ptr;
 1072:     int r;
 1073: 
 1074:     while ((r = qemu_get_byte(f))) {
 1075:         int ret;
 1076:         struct socket *so = socreate(slirp);
 1077: 
 1078:         if (!so)
 1079:             return -ENOMEM;
 1080: 
 1081:         ret = slirp_socket_load(f, so);
 1082: 
 1083:         if (ret < 0)
 1084:             return ret;
 1085: 
 1086:         if ((so->so_faddr.s_addr & slirp->vnetwork_mask.s_addr) !=
 1087:             slirp->vnetwork_addr.s_addr) {
 1088:             return -EINVAL;
 1089:         }
 1090:         for (ex_ptr = slirp->exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
 1091:             if (ex_ptr->ex_pty == 3 &&
 1092:                 so->so_faddr.s_addr == ex_ptr->ex_addr.s_addr &&
 1093:                 so->so_fport == ex_ptr->ex_fport) {
 1094:                 break;
 1095:             }
 1096:         }
 1097:         if (!ex_ptr)
 1098:             return -EINVAL;
 1099: 
 1100:         so->extra = (void *)ex_ptr->ex_exec;
 1101:     }
 1102: 
 1103:     if (version_id >= 2) {
 1104:         slirp->ip_id = qemu_get_be16(f);
 1105:     }
 1106: 
 1107:     if (version_id >= 3) {
 1108:         slirp_bootp_load(f, slirp);
 1109:     }
 1110: 
 1111:     return 0;
 1112: }

unix.superglobalmegacorp.com