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