|
|
1.1.1.5 root 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"
1.1.1.6 root 25: #include "qemu-timer.h"
1.1.1.5 root 26: #include "qemu-char.h"
1.1 root 27: #include "slirp.h"
1.1.1.5 root 28: #include "hw/hw.h"
1.1 root 29:
30: /* host loopback address */
31: struct in_addr loopback_addr;
32:
1.1.1.6 root 33: /* emulated hosts use the MAC addr 52:55:IP:IP:IP:IP */
1.1.1.11 root 34: static const uint8_t special_ethaddr[ETH_ALEN] = {
1.1.1.6 root 35: 0x52, 0x55, 0x00, 0x00, 0x00, 0x00
1.1 root 36: };
37:
1.1.1.11 root 38: static const uint8_t zero_ethaddr[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };
1.1 root 39:
40: /* XXX: suppress those select globals */
41: fd_set *global_readfds, *global_writefds, *global_xfds;
42:
1.1.1.6 root 43: u_int curtime;
44: static u_int time_fasttimo, last_slowtimo;
45: static int do_slowtimo;
46:
1.1.1.7 root 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;
1.1.1.2 root 52:
1.1 root 53: #ifdef _WIN32
54:
1.1.1.7 root 55: int get_dns_addr(struct in_addr *pdns_addr)
1.1 root 56: {
57: FIXED_INFO *FixedInfo=NULL;
58: ULONG BufLen;
59: DWORD ret;
60: IP_ADDR_STRING *pIPAddr;
61: struct in_addr tmp_addr;
1.1.1.4 root 62:
1.1.1.7 root 63: if (dns_addr.s_addr != 0 && (curtime - dns_addr_time) < 1000) {
64: *pdns_addr = dns_addr;
65: return 0;
66: }
67:
1.1 root 68: FixedInfo = (FIXED_INFO *)GlobalAlloc(GPTR, sizeof(FIXED_INFO));
69: BufLen = sizeof(FIXED_INFO);
1.1.1.4 root 70:
1.1 root 71: if (ERROR_BUFFER_OVERFLOW == GetNetworkParams(FixedInfo, &BufLen)) {
72: if (FixedInfo) {
73: GlobalFree(FixedInfo);
74: FixedInfo = NULL;
75: }
76: FixedInfo = GlobalAlloc(GPTR, BufLen);
77: }
1.1.1.4 root 78:
1.1 root 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: }
1.1.1.4 root 87:
1.1 root 88: pIPAddr = &(FixedInfo->DnsServerList);
89: inet_aton(pIPAddr->IpAddress.String, &tmp_addr);
90: *pdns_addr = tmp_addr;
1.1.1.7 root 91: dns_addr = tmp_addr;
92: dns_addr_time = curtime;
1.1 root 93: if (FixedInfo) {
94: GlobalFree(FixedInfo);
95: FixedInfo = NULL;
96: }
97: return 0;
98: }
99:
1.1.1.6 root 100: static void winsock_cleanup(void)
101: {
102: WSACleanup();
103: }
104:
1.1 root 105: #else
106:
1.1.1.7 root 107: static struct stat dns_addr_stat;
108:
109: int get_dns_addr(struct in_addr *pdns_addr)
1.1 root 110: {
111: char buff[512];
1.1.1.5 root 112: char buff2[257];
1.1 root 113: FILE *f;
114: int found = 0;
115: struct in_addr tmp_addr;
1.1.1.4 root 116:
1.1.1.7 root 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:
1.1 root 135: f = fopen("/etc/resolv.conf", "r");
136: if (!f)
137: return -1;
138:
1.1.1.4 root 139: #ifdef DEBUG
1.1 root 140: lprint("IP address of your DNS(s): ");
1.1.1.4 root 141: #endif
1.1 root 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 */
1.1.1.7 root 147: if (!found) {
1.1 root 148: *pdns_addr = tmp_addr;
1.1.1.7 root 149: dns_addr = tmp_addr;
150: dns_addr_time = curtime;
151: }
1.1.1.4 root 152: #ifdef DEBUG
1.1 root 153: else
154: lprint(", ");
1.1.1.4 root 155: #endif
1.1 root 156: if (++found > 3) {
1.1.1.4 root 157: #ifdef DEBUG
1.1 root 158: lprint("(more)");
1.1.1.4 root 159: #endif
1.1 root 160: break;
1.1.1.4 root 161: }
162: #ifdef DEBUG
163: else
1.1 root 164: lprint("%s", inet_ntoa(tmp_addr));
1.1.1.4 root 165: #endif
1.1 root 166: }
167: }
168: fclose(f);
169: if (!found)
170: return -1;
171: return 0;
172: }
173:
174: #endif
175:
1.1.1.6 root 176: static void slirp_init_once(void)
1.1 root 177: {
1.1.1.6 root 178: static int initialized;
179: #ifdef _WIN32
180: WSADATA Data;
1.1 root 181: #endif
182:
1.1.1.6 root 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:
1.1.1.5 root 196: static void slirp_state_save(QEMUFile *f, void *opaque);
197: static int slirp_state_load(QEMUFile *f, void *opaque, int version_id);
198:
1.1.1.6 root 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)
1.1 root 204: {
1.1.1.11 root 205: Slirp *slirp = g_malloc0(sizeof(Slirp));
1.1.1.4 root 206:
1.1.1.6 root 207: slirp_init_once();
1.1 root 208:
1.1.1.6 root 209: slirp->restricted = restricted;
1.1 root 210:
1.1.1.6 root 211: if_init(slirp);
212: ip_init(slirp);
1.1 root 213:
214: /* Initialise mbufs *after* setting the MTU */
1.1.1.6 root 215: m_init(slirp);
1.1 root 216:
1.1.1.6 root 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) {
1.1.1.11 root 225: slirp->tftp_prefix = g_strdup(tftp_path);
1.1 root 226: }
1.1.1.6 root 227: if (bootfile) {
1.1.1.11 root 228: slirp->bootp_filename = g_strdup(bootfile);
1.1.1.6 root 229: }
230: slirp->vdhcp_startaddr = vdhcp_start;
231: slirp->vnameserver_addr = vnameserver;
1.1 root 232:
1.1.1.6 root 233: slirp->opaque = opaque;
1.1.1.5 root 234:
1.1.1.8 root 235: register_savevm(NULL, "slirp", 0, 3,
236: slirp_state_save, slirp_state_load, slirp);
1.1 root 237:
1.1.1.7 root 238: QTAILQ_INSERT_TAIL(&slirp_instances, slirp, entry);
1.1 root 239:
1.1.1.6 root 240: return slirp;
1.1 root 241: }
1.1.1.6 root 242:
243: void slirp_cleanup(Slirp *slirp)
1.1 root 244: {
1.1.1.7 root 245: QTAILQ_REMOVE(&slirp_instances, slirp, entry);
1.1.1.4 root 246:
1.1.1.8 root 247: unregister_savevm(NULL, "slirp", slirp);
1.1.1.4 root 248:
1.1.1.12! root 249: ip_cleanup(slirp);
! 250: m_cleanup(slirp);
! 251:
1.1.1.11 root 252: g_free(slirp->tftp_prefix);
253: g_free(slirp->bootp_filename);
254: g_free(slirp);
1.1 root 255: }
1.1.1.6 root 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)
1.1 root 260:
1.1.1.12! root 261: void slirp_update_timeout(uint32_t *timeout)
! 262: {
! 263: if (!QTAILQ_EMPTY(&slirp_instances)) {
! 264: *timeout = MIN(1000, *timeout);
! 265: }
! 266: }
! 267:
1.1.1.4 root 268: void slirp_select_fill(int *pnfds,
1.1 root 269: fd_set *readfds, fd_set *writefds, fd_set *xfds)
270: {
1.1.1.6 root 271: Slirp *slirp;
1.1 root 272: struct socket *so, *so_next;
273: int nfds;
1.1.1.6 root 274:
1.1.1.7 root 275: if (QTAILQ_EMPTY(&slirp_instances)) {
1.1.1.6 root 276: return;
277: }
1.1 root 278:
279: /* fail safe */
280: global_readfds = NULL;
281: global_writefds = NULL;
282: global_xfds = NULL;
1.1.1.4 root 283:
1.1 root 284: nfds = *pnfds;
285: /*
286: * First, TCP sockets
287: */
288: do_slowtimo = 0;
1.1.1.6 root 289:
1.1.1.7 root 290: QTAILQ_FOREACH(slirp, &slirp_instances, entry) {
1.1.1.4 root 291: /*
1.1 root 292: * *_slowtimo needs calling if there are IP fragments
293: * in the fragment queue, or there are TCP connections active
294: */
1.1.1.6 root 295: do_slowtimo |= ((slirp->tcb.so_next != &slirp->tcb) ||
296: (&slirp->ipq.ip_link != slirp->ipq.ip_link.next));
1.1.1.4 root 297:
1.1.1.6 root 298: for (so = slirp->tcb.so_next; so != &slirp->tcb;
299: so = so_next) {
1.1 root 300: so_next = so->so_next;
1.1.1.4 root 301:
1.1 root 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 */
1.1.1.4 root 307:
1.1 root 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;
1.1.1.4 root 314:
1.1 root 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: }
1.1.1.4 root 323:
1.1 root 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: }
1.1.1.4 root 332:
1.1 root 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: }
1.1.1.4 root 341:
1.1 root 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: }
1.1.1.4 root 352:
1.1 root 353: /*
354: * UDP sockets
355: */
1.1.1.6 root 356: for (so = slirp->udb.so_next; so != &slirp->udb;
357: so = so_next) {
1.1 root 358: so_next = so->so_next;
1.1.1.4 root 359:
1.1 root 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: }
1.1.1.4 root 370:
1.1 root 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: }
1.1.1.10 root 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: }
1.1 root 411: }
1.1.1.4 root 412:
1.1 root 413: *pnfds = nfds;
1.1.1.4 root 414: }
1.1 root 415:
1.1.1.6 root 416: void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds,
417: int select_error)
1.1 root 418: {
1.1.1.6 root 419: Slirp *slirp;
1.1 root 420: struct socket *so, *so_next;
421: int ret;
422:
1.1.1.7 root 423: if (QTAILQ_EMPTY(&slirp_instances)) {
1.1.1.6 root 424: return;
425: }
426:
1.1 root 427: global_readfds = readfds;
428: global_writefds = writefds;
429: global_xfds = xfds;
430:
1.1.1.10 root 431: curtime = qemu_get_clock_ms(rt_clock);
1.1.1.4 root 432:
1.1.1.7 root 433: QTAILQ_FOREACH(slirp, &slirp_instances, entry) {
1.1 root 434: /*
1.1.1.4 root 435: * See if anything has timed out
1.1 root 436: */
437: if (time_fasttimo && ((curtime - time_fasttimo) >= 2)) {
1.1.1.6 root 438: tcp_fasttimo(slirp);
1.1 root 439: time_fasttimo = 0;
440: }
441: if (do_slowtimo && ((curtime - last_slowtimo) >= 499)) {
1.1.1.6 root 442: ip_slowtimo(slirp);
443: tcp_slowtimo(slirp);
1.1 root 444: last_slowtimo = curtime;
445: }
1.1.1.4 root 446:
1.1 root 447: /*
448: * Check sockets
449: */
1.1.1.6 root 450: if (!select_error) {
1.1 root 451: /*
452: * Check TCP sockets
453: */
1.1.1.6 root 454: for (so = slirp->tcb.so_next; so != &slirp->tcb;
455: so = so_next) {
1.1 root 456: so_next = so->so_next;
1.1.1.4 root 457:
1.1 root 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;
1.1.1.4 root 464:
1.1 root 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);
1.1.1.4 root 484:
1.1 root 485: /* Output it if we read something */
486: if (ret > 0)
487: tcp_output(sototcpcb(so));
488: }
1.1.1.4 root 489:
1.1 root 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;
1.1.1.4 root 500:
1.1.1.6 root 501: ret = send(so->s, (const void *) &ret, 0, 0);
1.1 root 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;
1.1.1.4 root 507:
1.1 root 508: /* else failed */
1.1.1.6 root 509: so->so_state &= SS_PERSISTENT_MASK;
510: so->so_state |= SS_NOFDREF;
1.1 root 511: }
512: /* else so->so_state &= ~SS_ISFCONNECTING; */
1.1.1.4 root 513:
1.1 root 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: /*
1.1.1.4 root 522: * XXXXX If we wrote something (a lot), there
1.1 root 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: }
1.1.1.4 root 528:
1.1 root 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) {
1.1.1.10 root 535: ret = qemu_recv(so->s, &ret, 0,0);
1.1.1.4 root 536:
1.1 root 537: if (ret < 0) {
538: /* XXX */
539: if (errno == EAGAIN || errno == EWOULDBLOCK ||
540: errno == EINPROGRESS || errno == ENOTCONN)
541: continue; /* Still connecting, continue */
1.1.1.4 root 542:
1.1 root 543: /* else failed */
1.1.1.6 root 544: so->so_state &= SS_PERSISTENT_MASK;
545: so->so_state |= SS_NOFDREF;
1.1.1.4 root 546:
1.1 root 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 */
1.1.1.6 root 556: so->so_state &= SS_PERSISTENT_MASK;
557: so->so_state |= SS_NOFDREF;
1.1 root 558: } else
559: so->so_state &= ~SS_ISFCONNECTING;
1.1.1.4 root 560:
1.1 root 561: }
562: tcp_input((struct mbuf *)NULL, sizeof(struct ip),so);
563: } /* SS_ISFCONNECTING */
564: #endif
565: }
1.1.1.4 root 566:
1.1 root 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: */
1.1.1.6 root 572: for (so = slirp->udb.so_next; so != &slirp->udb;
573: so = so_next) {
1.1 root 574: so_next = so->so_next;
1.1.1.4 root 575:
1.1 root 576: if (so->s != -1 && FD_ISSET(so->s, readfds)) {
577: sorecvfrom(so);
578: }
579: }
1.1.1.10 root 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: }
1.1 root 592: }
1.1.1.4 root 593:
1.1.1.12! root 594: if_start(slirp);
1.1.1.6 root 595: }
1.1 root 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:
1.1.1.6 root 607: static void arp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len)
1.1 root 608: {
609: struct arphdr *ah = (struct arphdr *)(pkt + ETH_HLEN);
1.1.1.9 root 610: uint8_t arp_reply[max(ETH_HLEN + sizeof(struct arphdr), 64)];
1.1 root 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:
1.1.1.11 root 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:
1.1.1.6 root 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)
1.1 root 629: goto arp_ok;
1.1.1.6 root 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)
1.1 root 632: goto arp_ok;
633: }
634: return;
635: arp_ok:
1.1.1.9 root 636: memset(arp_reply, 0, sizeof(arp_reply));
1.1.1.11 root 637:
638: arp_table_add(slirp, ah->ar_sip, ah->ar_sha);
1.1 root 639:
640: /* ARP request for alias/dns mac address */
641: memcpy(reh->h_dest, pkt + ETH_ALEN, ETH_ALEN);
1.1.1.6 root 642: memcpy(reh->h_source, special_ethaddr, ETH_ALEN - 4);
643: memcpy(&reh->h_source[2], &ah->ar_tip, 4);
1.1 root 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);
1.1.1.6 root 652: rah->ar_sip = ah->ar_tip;
1.1 root 653: memcpy(rah->ar_tha, ah->ar_sha, ETH_ALEN);
1.1.1.6 root 654: rah->ar_tip = ah->ar_sip;
655: slirp_output(slirp->opaque, arp_reply, sizeof(arp_reply));
1.1 root 656: }
657: break;
1.1.1.5 root 658: case ARPOP_REPLY:
1.1.1.11 root 659: arp_table_add(slirp, ah->ar_sip, ah->ar_sha);
1.1.1.5 root 660: break;
1.1 root 661: default:
662: break;
663: }
664: }
665:
1.1.1.6 root 666: void slirp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len)
1.1 root 667: {
668: struct mbuf *m;
669: int proto;
670:
671: if (pkt_len < ETH_HLEN)
672: return;
1.1.1.4 root 673:
1.1 root 674: proto = ntohs(*(uint16_t *)(pkt + 12));
675: switch(proto) {
676: case ETH_P_ARP:
1.1.1.6 root 677: arp_input(slirp, pkt, pkt_len);
1.1 root 678: break;
679: case ETH_P_IP:
1.1.1.6 root 680: m = m_get(slirp);
1.1 root 681: if (!m)
682: return;
1.1.1.3 root 683: /* Note: we add to align the IP header */
1.1.1.5 root 684: if (M_FREEROOM(m) < pkt_len + 2) {
685: m_inc(m, pkt_len + 2);
686: }
1.1.1.3 root 687: m->m_len = pkt_len + 2;
688: memcpy(m->m_data + 2, pkt, pkt_len);
1.1 root 689:
1.1.1.3 root 690: m->m_data += 2 + ETH_HLEN;
691: m->m_len -= 2 + ETH_HLEN;
1.1 root 692:
693: ip_input(m);
694: break;
695: default:
696: break;
697: }
698: }
699:
1.1.1.11 root 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)
1.1 root 704: {
705: uint8_t buf[1600];
706: struct ethhdr *eh = (struct ethhdr *)buf;
1.1.1.11 root 707: uint8_t ethaddr[ETH_ALEN];
708: const struct ip *iph = (const struct ip *)ifm->m_data;
1.1 root 709:
1.1.1.11 root 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)) {
1.1.1.5 root 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:
1.1.1.11 root 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;
1.1.1.5 root 751: } else {
1.1.1.11 root 752: memcpy(eh->h_dest, ethaddr, ETH_ALEN);
1.1.1.6 root 753: memcpy(eh->h_source, special_ethaddr, ETH_ALEN - 4);
1.1.1.5 root 754: /* XXX: not correct */
1.1.1.6 root 755: memcpy(&eh->h_source[2], &slirp->vhost_addr, 4);
1.1.1.5 root 756: eh->h_proto = htons(ETH_P_IP);
1.1.1.11 root 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;
1.1.1.5 root 760: }
1.1 root 761: }
762:
1.1.1.6 root 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)
1.1 root 790: {
1.1.1.6 root 791: if (!guest_addr.s_addr) {
792: guest_addr = slirp->vdhcp_startaddr;
793: }
1.1 root 794: if (is_udp) {
1.1.1.6 root 795: if (!udp_listen(slirp, host_addr.s_addr, htons(host_port),
796: guest_addr.s_addr, htons(guest_port), SS_HOSTFWD))
1.1 root 797: return -1;
798: } else {
1.1.1.6 root 799: if (!tcp_listen(slirp, host_addr.s_addr, htons(host_port),
800: guest_addr.s_addr, htons(guest_port), SS_HOSTFWD))
1.1 root 801: return -1;
802: }
803: return 0;
804: }
805:
1.1.1.6 root 806: int slirp_add_exec(Slirp *slirp, int do_pty, const void *args,
807: struct in_addr *guest_addr, int guest_port)
1.1 root 808: {
1.1.1.6 root 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));
1.1 root 821: }
1.1.1.5 root 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) {
1.1.1.11 root 826: qemu_chr_fe_write(so->extra, buf, len);
1.1.1.5 root 827: return len;
828: }
829:
830: return send(so->s, buf, len, flags);
831: }
832:
1.1.1.6 root 833: static struct socket *
834: slirp_find_ctl_socket(Slirp *slirp, struct in_addr guest_addr, int guest_port)
1.1.1.5 root 835: {
1.1.1.6 root 836: struct socket *so;
1.1.1.5 root 837:
1.1.1.6 root 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;
1.1.1.5 root 845: }
846:
1.1.1.6 root 847: size_t slirp_socket_can_recv(Slirp *slirp, struct in_addr guest_addr,
848: int guest_port)
1.1.1.5 root 849: {
850: struct iovec iov[2];
851: struct socket *so;
852:
1.1.1.6 root 853: so = slirp_find_ctl_socket(slirp, guest_addr, guest_port);
1.1.1.5 root 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:
1.1.1.6 root 864: void slirp_socket_recv(Slirp *slirp, struct in_addr guest_addr, int guest_port,
865: const uint8_t *buf, int size)
1.1.1.5 root 866: {
867: int ret;
1.1.1.6 root 868: struct socket *so = slirp_find_ctl_socket(slirp, guest_addr, guest_port);
869:
1.1.1.5 root 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:
1.1.1.6 root 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:
1.1.1.5 root 965: static void slirp_state_save(QEMUFile *f, void *opaque)
966: {
1.1.1.6 root 967: Slirp *slirp = opaque;
1.1.1.5 root 968: struct ex_list *ex_ptr;
969:
1.1.1.6 root 970: for (ex_ptr = slirp->exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next)
1.1.1.5 root 971: if (ex_ptr->ex_pty == 3) {
972: struct socket *so;
1.1.1.6 root 973: so = slirp_find_ctl_socket(slirp, ex_ptr->ex_addr,
974: ntohs(ex_ptr->ex_fport));
1.1.1.5 root 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);
1.1.1.6 root 982:
983: qemu_put_be16(f, slirp->ip_id);
984:
985: slirp_bootp_save(f, slirp);
1.1.1.5 root 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:
1.1.1.6 root 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:
1.1.1.5 root 1092: static int slirp_state_load(QEMUFile *f, void *opaque, int version_id)
1093: {
1.1.1.6 root 1094: Slirp *slirp = opaque;
1.1.1.5 root 1095: struct ex_list *ex_ptr;
1096:
1.1.1.8 root 1097: while (qemu_get_byte(f)) {
1.1.1.5 root 1098: int ret;
1.1.1.6 root 1099: struct socket *so = socreate(slirp);
1.1.1.5 root 1100:
1101: if (!so)
1102: return -ENOMEM;
1103:
1104: ret = slirp_socket_load(f, so);
1105:
1106: if (ret < 0)
1107: return ret;
1108:
1.1.1.6 root 1109: if ((so->so_faddr.s_addr & slirp->vnetwork_mask.s_addr) !=
1110: slirp->vnetwork_addr.s_addr) {
1.1.1.5 root 1111: return -EINVAL;
1.1.1.6 root 1112: }
1113: for (ex_ptr = slirp->exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
1.1.1.5 root 1114: if (ex_ptr->ex_pty == 3 &&
1.1.1.6 root 1115: so->so_faddr.s_addr == ex_ptr->ex_addr.s_addr &&
1116: so->so_fport == ex_ptr->ex_fport) {
1.1.1.5 root 1117: break;
1.1.1.6 root 1118: }
1119: }
1.1.1.5 root 1120: if (!ex_ptr)
1121: return -EINVAL;
1122:
1123: so->extra = (void *)ex_ptr->ex_exec;
1124: }
1125:
1.1.1.6 root 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:
1.1.1.5 root 1134: return 0;
1135: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.