|
|
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);
602: uint8_t arp_reply[ETH_HLEN + sizeof(struct arphdr)];
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:
622: /* XXX: make an ARP request to have the client address */
1.1.1.6 root 623: memcpy(slirp->client_ethaddr, eh->h_source, ETH_ALEN);
1.1 root 624:
625: /* ARP request for alias/dns mac address */
626: memcpy(reh->h_dest, pkt + ETH_ALEN, ETH_ALEN);
1.1.1.6 root 627: memcpy(reh->h_source, special_ethaddr, ETH_ALEN - 4);
628: memcpy(&reh->h_source[2], &ah->ar_tip, 4);
1.1 root 629: reh->h_proto = htons(ETH_P_ARP);
630:
631: rah->ar_hrd = htons(1);
632: rah->ar_pro = htons(ETH_P_IP);
633: rah->ar_hln = ETH_ALEN;
634: rah->ar_pln = 4;
635: rah->ar_op = htons(ARPOP_REPLY);
636: memcpy(rah->ar_sha, reh->h_source, ETH_ALEN);
1.1.1.6 root 637: rah->ar_sip = ah->ar_tip;
1.1 root 638: memcpy(rah->ar_tha, ah->ar_sha, ETH_ALEN);
1.1.1.6 root 639: rah->ar_tip = ah->ar_sip;
640: slirp_output(slirp->opaque, arp_reply, sizeof(arp_reply));
1.1 root 641: }
642: break;
1.1.1.5 root 643: case ARPOP_REPLY:
644: /* reply to request of client mac address ? */
1.1.1.6 root 645: if (!memcmp(slirp->client_ethaddr, zero_ethaddr, ETH_ALEN) &&
646: ah->ar_sip == slirp->client_ipaddr.s_addr) {
647: memcpy(slirp->client_ethaddr, ah->ar_sha, ETH_ALEN);
1.1.1.5 root 648: }
649: break;
1.1 root 650: default:
651: break;
652: }
653: }
654:
1.1.1.6 root 655: void slirp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len)
1.1 root 656: {
657: struct mbuf *m;
658: int proto;
659:
660: if (pkt_len < ETH_HLEN)
661: return;
1.1.1.4 root 662:
1.1 root 663: proto = ntohs(*(uint16_t *)(pkt + 12));
664: switch(proto) {
665: case ETH_P_ARP:
1.1.1.6 root 666: arp_input(slirp, pkt, pkt_len);
1.1 root 667: break;
668: case ETH_P_IP:
1.1.1.6 root 669: m = m_get(slirp);
1.1 root 670: if (!m)
671: return;
1.1.1.3 root 672: /* Note: we add to align the IP header */
1.1.1.5 root 673: if (M_FREEROOM(m) < pkt_len + 2) {
674: m_inc(m, pkt_len + 2);
675: }
1.1.1.3 root 676: m->m_len = pkt_len + 2;
677: memcpy(m->m_data + 2, pkt, pkt_len);
1.1 root 678:
1.1.1.3 root 679: m->m_data += 2 + ETH_HLEN;
680: m->m_len -= 2 + ETH_HLEN;
1.1 root 681:
682: ip_input(m);
683: break;
684: default:
685: break;
686: }
687: }
688:
689: /* output the IP packet to the ethernet device */
1.1.1.6 root 690: void if_encap(Slirp *slirp, const uint8_t *ip_data, int ip_data_len)
1.1 root 691: {
692: uint8_t buf[1600];
693: struct ethhdr *eh = (struct ethhdr *)buf;
694:
695: if (ip_data_len + ETH_HLEN > sizeof(buf))
696: return;
1.1.1.5 root 697:
1.1.1.6 root 698: if (!memcmp(slirp->client_ethaddr, zero_ethaddr, ETH_ALEN)) {
1.1.1.5 root 699: uint8_t arp_req[ETH_HLEN + sizeof(struct arphdr)];
700: struct ethhdr *reh = (struct ethhdr *)arp_req;
701: struct arphdr *rah = (struct arphdr *)(arp_req + ETH_HLEN);
702: const struct ip *iph = (const struct ip *)ip_data;
703:
704: /* If the client addr is not known, there is no point in
705: sending the packet to it. Normally the sender should have
706: done an ARP request to get its MAC address. Here we do it
707: in place of sending the packet and we hope that the sender
708: will retry sending its packet. */
709: memset(reh->h_dest, 0xff, ETH_ALEN);
1.1.1.6 root 710: memcpy(reh->h_source, special_ethaddr, ETH_ALEN - 4);
711: memcpy(&reh->h_source[2], &slirp->vhost_addr, 4);
1.1.1.5 root 712: reh->h_proto = htons(ETH_P_ARP);
713: rah->ar_hrd = htons(1);
714: rah->ar_pro = htons(ETH_P_IP);
715: rah->ar_hln = ETH_ALEN;
716: rah->ar_pln = 4;
717: rah->ar_op = htons(ARPOP_REQUEST);
718: /* source hw addr */
1.1.1.6 root 719: memcpy(rah->ar_sha, special_ethaddr, ETH_ALEN - 4);
720: memcpy(&rah->ar_sha[2], &slirp->vhost_addr, 4);
1.1.1.5 root 721: /* source IP */
1.1.1.6 root 722: rah->ar_sip = slirp->vhost_addr.s_addr;
1.1.1.5 root 723: /* target hw addr (none) */
724: memset(rah->ar_tha, 0, ETH_ALEN);
725: /* target IP */
1.1.1.6 root 726: rah->ar_tip = iph->ip_dst.s_addr;
727: slirp->client_ipaddr = iph->ip_dst;
728: slirp_output(slirp->opaque, arp_req, sizeof(arp_req));
1.1.1.5 root 729: } else {
1.1.1.6 root 730: memcpy(eh->h_dest, slirp->client_ethaddr, ETH_ALEN);
731: memcpy(eh->h_source, special_ethaddr, ETH_ALEN - 4);
1.1.1.5 root 732: /* XXX: not correct */
1.1.1.6 root 733: memcpy(&eh->h_source[2], &slirp->vhost_addr, 4);
1.1.1.5 root 734: eh->h_proto = htons(ETH_P_IP);
735: memcpy(buf + sizeof(struct ethhdr), ip_data, ip_data_len);
1.1.1.6 root 736: slirp_output(slirp->opaque, buf, ip_data_len + ETH_HLEN);
1.1.1.5 root 737: }
1.1 root 738: }
739:
1.1.1.6 root 740: /* Drop host forwarding rule, return 0 if found. */
741: int slirp_remove_hostfwd(Slirp *slirp, int is_udp, struct in_addr host_addr,
742: int host_port)
743: {
744: struct socket *so;
745: struct socket *head = (is_udp ? &slirp->udb : &slirp->tcb);
746: struct sockaddr_in addr;
747: int port = htons(host_port);
748: socklen_t addr_len;
749:
750: for (so = head->so_next; so != head; so = so->so_next) {
751: addr_len = sizeof(addr);
752: if ((so->so_state & SS_HOSTFWD) &&
753: getsockname(so->s, (struct sockaddr *)&addr, &addr_len) == 0 &&
754: addr.sin_addr.s_addr == host_addr.s_addr &&
755: addr.sin_port == port) {
756: close(so->s);
757: sofree(so);
758: return 0;
759: }
760: }
761:
762: return -1;
763: }
764:
765: int slirp_add_hostfwd(Slirp *slirp, int is_udp, struct in_addr host_addr,
766: int host_port, struct in_addr guest_addr, int guest_port)
1.1 root 767: {
1.1.1.6 root 768: if (!guest_addr.s_addr) {
769: guest_addr = slirp->vdhcp_startaddr;
770: }
1.1 root 771: if (is_udp) {
1.1.1.6 root 772: if (!udp_listen(slirp, host_addr.s_addr, htons(host_port),
773: guest_addr.s_addr, htons(guest_port), SS_HOSTFWD))
1.1 root 774: return -1;
775: } else {
1.1.1.6 root 776: if (!tcp_listen(slirp, host_addr.s_addr, htons(host_port),
777: guest_addr.s_addr, htons(guest_port), SS_HOSTFWD))
1.1 root 778: return -1;
779: }
780: return 0;
781: }
782:
1.1.1.6 root 783: int slirp_add_exec(Slirp *slirp, int do_pty, const void *args,
784: 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->s_addr = slirp->vnetwork_addr.s_addr |
788: (htonl(0x0204) & ~slirp->vnetwork_mask.s_addr);
789: }
790: if ((guest_addr->s_addr & slirp->vnetwork_mask.s_addr) !=
791: slirp->vnetwork_addr.s_addr ||
792: guest_addr->s_addr == slirp->vhost_addr.s_addr ||
793: guest_addr->s_addr == slirp->vnameserver_addr.s_addr) {
794: return -1;
795: }
796: return add_exec(&slirp->exec_list, do_pty, (char *)args, *guest_addr,
797: htons(guest_port));
1.1 root 798: }
1.1.1.5 root 799:
800: ssize_t slirp_send(struct socket *so, const void *buf, size_t len, int flags)
801: {
802: if (so->s == -1 && so->extra) {
803: qemu_chr_write(so->extra, buf, len);
804: return len;
805: }
806:
807: return send(so->s, buf, len, flags);
808: }
809:
1.1.1.6 root 810: static struct socket *
811: slirp_find_ctl_socket(Slirp *slirp, struct in_addr guest_addr, int guest_port)
1.1.1.5 root 812: {
1.1.1.6 root 813: struct socket *so;
1.1.1.5 root 814:
1.1.1.6 root 815: for (so = slirp->tcb.so_next; so != &slirp->tcb; so = so->so_next) {
816: if (so->so_faddr.s_addr == guest_addr.s_addr &&
817: htons(so->so_fport) == guest_port) {
818: return so;
819: }
820: }
821: return NULL;
1.1.1.5 root 822: }
823:
1.1.1.6 root 824: size_t slirp_socket_can_recv(Slirp *slirp, struct in_addr guest_addr,
825: int guest_port)
1.1.1.5 root 826: {
827: struct iovec iov[2];
828: struct socket *so;
829:
1.1.1.6 root 830: so = slirp_find_ctl_socket(slirp, guest_addr, guest_port);
1.1.1.5 root 831:
832: if (!so || so->so_state & SS_NOFDREF)
833: return 0;
834:
835: if (!CONN_CANFRCV(so) || so->so_snd.sb_cc >= (so->so_snd.sb_datalen/2))
836: return 0;
837:
838: return sopreprbuf(so, iov, NULL);
839: }
840:
1.1.1.6 root 841: void slirp_socket_recv(Slirp *slirp, struct in_addr guest_addr, int guest_port,
842: const uint8_t *buf, int size)
1.1.1.5 root 843: {
844: int ret;
1.1.1.6 root 845: struct socket *so = slirp_find_ctl_socket(slirp, guest_addr, guest_port);
846:
1.1.1.5 root 847: if (!so)
848: return;
849:
850: ret = soreadbuf(so, (const char *)buf, size);
851:
852: if (ret > 0)
853: tcp_output(sototcpcb(so));
854: }
855:
856: static void slirp_tcp_save(QEMUFile *f, struct tcpcb *tp)
857: {
858: int i;
859:
860: qemu_put_sbe16(f, tp->t_state);
861: for (i = 0; i < TCPT_NTIMERS; i++)
862: qemu_put_sbe16(f, tp->t_timer[i]);
863: qemu_put_sbe16(f, tp->t_rxtshift);
864: qemu_put_sbe16(f, tp->t_rxtcur);
865: qemu_put_sbe16(f, tp->t_dupacks);
866: qemu_put_be16(f, tp->t_maxseg);
867: qemu_put_sbyte(f, tp->t_force);
868: qemu_put_be16(f, tp->t_flags);
869: qemu_put_be32(f, tp->snd_una);
870: qemu_put_be32(f, tp->snd_nxt);
871: qemu_put_be32(f, tp->snd_up);
872: qemu_put_be32(f, tp->snd_wl1);
873: qemu_put_be32(f, tp->snd_wl2);
874: qemu_put_be32(f, tp->iss);
875: qemu_put_be32(f, tp->snd_wnd);
876: qemu_put_be32(f, tp->rcv_wnd);
877: qemu_put_be32(f, tp->rcv_nxt);
878: qemu_put_be32(f, tp->rcv_up);
879: qemu_put_be32(f, tp->irs);
880: qemu_put_be32(f, tp->rcv_adv);
881: qemu_put_be32(f, tp->snd_max);
882: qemu_put_be32(f, tp->snd_cwnd);
883: qemu_put_be32(f, tp->snd_ssthresh);
884: qemu_put_sbe16(f, tp->t_idle);
885: qemu_put_sbe16(f, tp->t_rtt);
886: qemu_put_be32(f, tp->t_rtseq);
887: qemu_put_sbe16(f, tp->t_srtt);
888: qemu_put_sbe16(f, tp->t_rttvar);
889: qemu_put_be16(f, tp->t_rttmin);
890: qemu_put_be32(f, tp->max_sndwnd);
891: qemu_put_byte(f, tp->t_oobflags);
892: qemu_put_byte(f, tp->t_iobc);
893: qemu_put_sbe16(f, tp->t_softerror);
894: qemu_put_byte(f, tp->snd_scale);
895: qemu_put_byte(f, tp->rcv_scale);
896: qemu_put_byte(f, tp->request_r_scale);
897: qemu_put_byte(f, tp->requested_s_scale);
898: qemu_put_be32(f, tp->ts_recent);
899: qemu_put_be32(f, tp->ts_recent_age);
900: qemu_put_be32(f, tp->last_ack_sent);
901: }
902:
903: static void slirp_sbuf_save(QEMUFile *f, struct sbuf *sbuf)
904: {
905: uint32_t off;
906:
907: qemu_put_be32(f, sbuf->sb_cc);
908: qemu_put_be32(f, sbuf->sb_datalen);
909: off = (uint32_t)(sbuf->sb_wptr - sbuf->sb_data);
910: qemu_put_sbe32(f, off);
911: off = (uint32_t)(sbuf->sb_rptr - sbuf->sb_data);
912: qemu_put_sbe32(f, off);
913: qemu_put_buffer(f, (unsigned char*)sbuf->sb_data, sbuf->sb_datalen);
914: }
915:
916: static void slirp_socket_save(QEMUFile *f, struct socket *so)
917: {
918: qemu_put_be32(f, so->so_urgc);
919: qemu_put_be32(f, so->so_faddr.s_addr);
920: qemu_put_be32(f, so->so_laddr.s_addr);
921: qemu_put_be16(f, so->so_fport);
922: qemu_put_be16(f, so->so_lport);
923: qemu_put_byte(f, so->so_iptos);
924: qemu_put_byte(f, so->so_emu);
925: qemu_put_byte(f, so->so_type);
926: qemu_put_be32(f, so->so_state);
927: slirp_sbuf_save(f, &so->so_rcv);
928: slirp_sbuf_save(f, &so->so_snd);
929: slirp_tcp_save(f, so->so_tcpcb);
930: }
931:
1.1.1.6 root 932: static void slirp_bootp_save(QEMUFile *f, Slirp *slirp)
933: {
934: int i;
935:
936: for (i = 0; i < NB_BOOTP_CLIENTS; i++) {
937: qemu_put_be16(f, slirp->bootp_clients[i].allocated);
938: qemu_put_buffer(f, slirp->bootp_clients[i].macaddr, 6);
939: }
940: }
941:
1.1.1.5 root 942: static void slirp_state_save(QEMUFile *f, void *opaque)
943: {
1.1.1.6 root 944: Slirp *slirp = opaque;
1.1.1.5 root 945: struct ex_list *ex_ptr;
946:
1.1.1.6 root 947: for (ex_ptr = slirp->exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next)
1.1.1.5 root 948: if (ex_ptr->ex_pty == 3) {
949: struct socket *so;
1.1.1.6 root 950: so = slirp_find_ctl_socket(slirp, ex_ptr->ex_addr,
951: ntohs(ex_ptr->ex_fport));
1.1.1.5 root 952: if (!so)
953: continue;
954:
955: qemu_put_byte(f, 42);
956: slirp_socket_save(f, so);
957: }
958: qemu_put_byte(f, 0);
1.1.1.6 root 959:
960: qemu_put_be16(f, slirp->ip_id);
961:
962: slirp_bootp_save(f, slirp);
1.1.1.5 root 963: }
964:
965: static void slirp_tcp_load(QEMUFile *f, struct tcpcb *tp)
966: {
967: int i;
968:
969: tp->t_state = qemu_get_sbe16(f);
970: for (i = 0; i < TCPT_NTIMERS; i++)
971: tp->t_timer[i] = qemu_get_sbe16(f);
972: tp->t_rxtshift = qemu_get_sbe16(f);
973: tp->t_rxtcur = qemu_get_sbe16(f);
974: tp->t_dupacks = qemu_get_sbe16(f);
975: tp->t_maxseg = qemu_get_be16(f);
976: tp->t_force = qemu_get_sbyte(f);
977: tp->t_flags = qemu_get_be16(f);
978: tp->snd_una = qemu_get_be32(f);
979: tp->snd_nxt = qemu_get_be32(f);
980: tp->snd_up = qemu_get_be32(f);
981: tp->snd_wl1 = qemu_get_be32(f);
982: tp->snd_wl2 = qemu_get_be32(f);
983: tp->iss = qemu_get_be32(f);
984: tp->snd_wnd = qemu_get_be32(f);
985: tp->rcv_wnd = qemu_get_be32(f);
986: tp->rcv_nxt = qemu_get_be32(f);
987: tp->rcv_up = qemu_get_be32(f);
988: tp->irs = qemu_get_be32(f);
989: tp->rcv_adv = qemu_get_be32(f);
990: tp->snd_max = qemu_get_be32(f);
991: tp->snd_cwnd = qemu_get_be32(f);
992: tp->snd_ssthresh = qemu_get_be32(f);
993: tp->t_idle = qemu_get_sbe16(f);
994: tp->t_rtt = qemu_get_sbe16(f);
995: tp->t_rtseq = qemu_get_be32(f);
996: tp->t_srtt = qemu_get_sbe16(f);
997: tp->t_rttvar = qemu_get_sbe16(f);
998: tp->t_rttmin = qemu_get_be16(f);
999: tp->max_sndwnd = qemu_get_be32(f);
1000: tp->t_oobflags = qemu_get_byte(f);
1001: tp->t_iobc = qemu_get_byte(f);
1002: tp->t_softerror = qemu_get_sbe16(f);
1003: tp->snd_scale = qemu_get_byte(f);
1004: tp->rcv_scale = qemu_get_byte(f);
1005: tp->request_r_scale = qemu_get_byte(f);
1006: tp->requested_s_scale = qemu_get_byte(f);
1007: tp->ts_recent = qemu_get_be32(f);
1008: tp->ts_recent_age = qemu_get_be32(f);
1009: tp->last_ack_sent = qemu_get_be32(f);
1010: tcp_template(tp);
1011: }
1012:
1013: static int slirp_sbuf_load(QEMUFile *f, struct sbuf *sbuf)
1014: {
1015: uint32_t off, sb_cc, sb_datalen;
1016:
1017: sb_cc = qemu_get_be32(f);
1018: sb_datalen = qemu_get_be32(f);
1019:
1020: sbreserve(sbuf, sb_datalen);
1021:
1022: if (sbuf->sb_datalen != sb_datalen)
1023: return -ENOMEM;
1024:
1025: sbuf->sb_cc = sb_cc;
1026:
1027: off = qemu_get_sbe32(f);
1028: sbuf->sb_wptr = sbuf->sb_data + off;
1029: off = qemu_get_sbe32(f);
1030: sbuf->sb_rptr = sbuf->sb_data + off;
1031: qemu_get_buffer(f, (unsigned char*)sbuf->sb_data, sbuf->sb_datalen);
1032:
1033: return 0;
1034: }
1035:
1036: static int slirp_socket_load(QEMUFile *f, struct socket *so)
1037: {
1038: if (tcp_attach(so) < 0)
1039: return -ENOMEM;
1040:
1041: so->so_urgc = qemu_get_be32(f);
1042: so->so_faddr.s_addr = qemu_get_be32(f);
1043: so->so_laddr.s_addr = qemu_get_be32(f);
1044: so->so_fport = qemu_get_be16(f);
1045: so->so_lport = qemu_get_be16(f);
1046: so->so_iptos = qemu_get_byte(f);
1047: so->so_emu = qemu_get_byte(f);
1048: so->so_type = qemu_get_byte(f);
1049: so->so_state = qemu_get_be32(f);
1050: if (slirp_sbuf_load(f, &so->so_rcv) < 0)
1051: return -ENOMEM;
1052: if (slirp_sbuf_load(f, &so->so_snd) < 0)
1053: return -ENOMEM;
1054: slirp_tcp_load(f, so->so_tcpcb);
1055:
1056: return 0;
1057: }
1058:
1.1.1.6 root 1059: static void slirp_bootp_load(QEMUFile *f, Slirp *slirp)
1060: {
1061: int i;
1062:
1063: for (i = 0; i < NB_BOOTP_CLIENTS; i++) {
1064: slirp->bootp_clients[i].allocated = qemu_get_be16(f);
1065: qemu_get_buffer(f, slirp->bootp_clients[i].macaddr, 6);
1066: }
1067: }
1068:
1.1.1.5 root 1069: static int slirp_state_load(QEMUFile *f, void *opaque, int version_id)
1070: {
1.1.1.6 root 1071: Slirp *slirp = opaque;
1.1.1.5 root 1072: struct ex_list *ex_ptr;
1073:
1.1.1.8 ! root 1074: while (qemu_get_byte(f)) {
1.1.1.5 root 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.