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