File:  [Qemu by Fabrice Bellard] / qemu / slirp / slirp.c
Revision 1.1.1.12 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 19:51:37 2018 UTC (3 years, 3 months ago) by root
Branches: qemu, MAIN
CVS tags: qemu1101, HEAD
qemu 1.1.1

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

unix.superglobalmegacorp.com