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