|
|
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" ! 25: #include "qemu-char.h" 1.1 root 26: #include "slirp.h" 1.1.1.5 ! root 27: #include "hw/hw.h" 1.1 root 28: 29: /* host address */ 30: struct in_addr our_addr; 31: /* host dns address */ 32: struct in_addr dns_addr; 33: /* host loopback address */ 34: struct in_addr loopback_addr; 35: 36: /* address for slirp virtual addresses */ 37: struct in_addr special_addr; 1.1.1.2 root 38: /* virtual address alias for host */ 39: struct in_addr alias_addr; 1.1 root 40: 1.1.1.4 root 41: static const uint8_t special_ethaddr[6] = { 1.1 root 42: 0x52, 0x54, 0x00, 0x12, 0x35, 0x00 43: }; 44: 1.1.1.5 ! root 45: /* ARP cache for the guest IP addresses (XXX: allow many entries) */ 1.1 root 46: uint8_t client_ethaddr[6]; 1.1.1.5 ! root 47: static struct in_addr client_ipaddr; ! 48: ! 49: static const uint8_t zero_ethaddr[6] = { 0, 0, 0, 0, 0, 0 }; 1.1 root 50: 1.1.1.5 ! root 51: const char *slirp_special_ip = CTL_SPECIAL; ! 52: int slirp_restrict; 1.1 root 53: int do_slowtimo; 54: int link_up; 55: struct timeval tt; 56: FILE *lfd; 57: struct ex_list *exec_list; 58: 59: /* XXX: suppress those select globals */ 60: fd_set *global_readfds, *global_writefds, *global_xfds; 61: 1.1.1.2 root 62: char slirp_hostname[33]; 63: 1.1 root 64: #ifdef _WIN32 65: 66: static int get_dns_addr(struct in_addr *pdns_addr) 67: { 68: FIXED_INFO *FixedInfo=NULL; 69: ULONG BufLen; 70: DWORD ret; 71: IP_ADDR_STRING *pIPAddr; 72: struct in_addr tmp_addr; 1.1.1.4 root 73: 1.1 root 74: FixedInfo = (FIXED_INFO *)GlobalAlloc(GPTR, sizeof(FIXED_INFO)); 75: BufLen = sizeof(FIXED_INFO); 1.1.1.4 root 76: 1.1 root 77: if (ERROR_BUFFER_OVERFLOW == GetNetworkParams(FixedInfo, &BufLen)) { 78: if (FixedInfo) { 79: GlobalFree(FixedInfo); 80: FixedInfo = NULL; 81: } 82: FixedInfo = GlobalAlloc(GPTR, BufLen); 83: } 1.1.1.4 root 84: 1.1 root 85: if ((ret = GetNetworkParams(FixedInfo, &BufLen)) != ERROR_SUCCESS) { 86: printf("GetNetworkParams failed. ret = %08x\n", (u_int)ret ); 87: if (FixedInfo) { 88: GlobalFree(FixedInfo); 89: FixedInfo = NULL; 90: } 91: return -1; 92: } 1.1.1.4 root 93: 1.1 root 94: pIPAddr = &(FixedInfo->DnsServerList); 95: inet_aton(pIPAddr->IpAddress.String, &tmp_addr); 96: *pdns_addr = tmp_addr; 97: #if 0 98: printf( "DNS Servers:\n" ); 99: printf( "DNS Addr:%s\n", pIPAddr->IpAddress.String ); 1.1.1.4 root 100: 1.1 root 101: pIPAddr = FixedInfo -> DnsServerList.Next; 102: while ( pIPAddr ) { 103: printf( "DNS Addr:%s\n", pIPAddr ->IpAddress.String ); 104: pIPAddr = pIPAddr ->Next; 105: } 106: #endif 107: if (FixedInfo) { 108: GlobalFree(FixedInfo); 109: FixedInfo = NULL; 110: } 111: return 0; 112: } 113: 114: #else 115: 116: static int get_dns_addr(struct in_addr *pdns_addr) 117: { 118: char buff[512]; 1.1.1.5 ! root 119: char buff2[257]; 1.1 root 120: FILE *f; 121: int found = 0; 122: struct in_addr tmp_addr; 1.1.1.4 root 123: 1.1 root 124: f = fopen("/etc/resolv.conf", "r"); 125: if (!f) 126: return -1; 127: 1.1.1.4 root 128: #ifdef DEBUG 1.1 root 129: lprint("IP address of your DNS(s): "); 1.1.1.4 root 130: #endif 1.1 root 131: while (fgets(buff, 512, f) != NULL) { 132: if (sscanf(buff, "nameserver%*[ \t]%256s", buff2) == 1) { 133: if (!inet_aton(buff2, &tmp_addr)) 134: continue; 135: if (tmp_addr.s_addr == loopback_addr.s_addr) 136: tmp_addr = our_addr; 137: /* If it's the first one, set it to dns_addr */ 138: if (!found) 139: *pdns_addr = tmp_addr; 1.1.1.4 root 140: #ifdef DEBUG 1.1 root 141: else 142: lprint(", "); 1.1.1.4 root 143: #endif 1.1 root 144: if (++found > 3) { 1.1.1.4 root 145: #ifdef DEBUG 1.1 root 146: lprint("(more)"); 1.1.1.4 root 147: #endif 1.1 root 148: break; 1.1.1.4 root 149: } 150: #ifdef DEBUG 151: else 1.1 root 152: lprint("%s", inet_ntoa(tmp_addr)); 1.1.1.4 root 153: #endif 1.1 root 154: } 155: } 156: fclose(f); 157: if (!found) 158: return -1; 159: return 0; 160: } 161: 162: #endif 163: 164: #ifdef _WIN32 1.1.1.4 root 165: static void slirp_cleanup(void) 1.1 root 166: { 167: WSACleanup(); 168: } 169: #endif 170: 1.1.1.5 ! root 171: static void slirp_state_save(QEMUFile *f, void *opaque); ! 172: static int slirp_state_load(QEMUFile *f, void *opaque, int version_id); ! 173: ! 174: void slirp_init(int restrict, char *special_ip) 1.1 root 175: { 176: // debug_init("/tmp/slirp.log", DEBUG_DEFAULT); 1.1.1.4 root 177: 1.1 root 178: #ifdef _WIN32 179: { 180: WSADATA Data; 181: WSAStartup(MAKEWORD(2,0), &Data); 182: atexit(slirp_cleanup); 183: } 184: #endif 185: 186: link_up = 1; 1.1.1.5 ! root 187: slirp_restrict = restrict; 1.1 root 188: 189: if_init(); 190: ip_init(); 191: 192: /* Initialise mbufs *after* setting the MTU */ 193: m_init(); 194: 195: /* set default addresses */ 196: inet_aton("127.0.0.1", &loopback_addr); 197: 198: if (get_dns_addr(&dns_addr) < 0) { 1.1.1.2 root 199: dns_addr = loopback_addr; 200: fprintf (stderr, "Warning: No DNS servers found\n"); 1.1 root 201: } 202: 1.1.1.5 ! root 203: if (special_ip) ! 204: slirp_special_ip = special_ip; ! 205: ! 206: inet_aton(slirp_special_ip, &special_addr); 1.1.1.2 root 207: alias_addr.s_addr = special_addr.s_addr | htonl(CTL_ALIAS); 208: getouraddr(); 1.1.1.5 ! root 209: register_savevm("slirp", 0, 1, slirp_state_save, slirp_state_load, NULL); 1.1 root 210: } 211: 212: #define CONN_CANFSEND(so) (((so)->so_state & (SS_FCANTSENDMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED) 213: #define CONN_CANFRCV(so) (((so)->so_state & (SS_FCANTRCVMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED) 214: #define UPD_NFDS(x) if (nfds < (x)) nfds = (x) 215: 216: /* 217: * curtime kept to an accuracy of 1ms 218: */ 219: #ifdef _WIN32 220: static void updtime(void) 221: { 222: struct _timeb tb; 223: 224: _ftime(&tb); 225: curtime = (u_int)tb.time * (u_int)1000; 226: curtime += (u_int)tb.millitm; 227: } 228: #else 229: static void updtime(void) 230: { 231: gettimeofday(&tt, 0); 1.1.1.4 root 232: 1.1 root 233: curtime = (u_int)tt.tv_sec * (u_int)1000; 234: curtime += (u_int)tt.tv_usec / (u_int)1000; 1.1.1.4 root 235: 1.1 root 236: if ((tt.tv_usec % 1000) >= 500) 237: curtime++; 238: } 239: #endif 240: 1.1.1.4 root 241: void slirp_select_fill(int *pnfds, 1.1 root 242: fd_set *readfds, fd_set *writefds, fd_set *xfds) 243: { 244: struct socket *so, *so_next; 245: struct timeval timeout; 246: int nfds; 247: int tmp_time; 248: 249: /* fail safe */ 250: global_readfds = NULL; 251: global_writefds = NULL; 252: global_xfds = NULL; 1.1.1.4 root 253: 1.1 root 254: nfds = *pnfds; 255: /* 256: * First, TCP sockets 257: */ 258: do_slowtimo = 0; 259: if (link_up) { 1.1.1.4 root 260: /* 1.1 root 261: * *_slowtimo needs calling if there are IP fragments 262: * in the fragment queue, or there are TCP connections active 263: */ 264: do_slowtimo = ((tcb.so_next != &tcb) || 1.1.1.5 ! root 265: (&ipq.ip_link != ipq.ip_link.next)); 1.1.1.4 root 266: 1.1 root 267: for (so = tcb.so_next; so != &tcb; so = so_next) { 268: so_next = so->so_next; 1.1.1.4 root 269: 1.1 root 270: /* 271: * See if we need a tcp_fasttimo 272: */ 273: if (time_fasttimo == 0 && so->so_tcpcb->t_flags & TF_DELACK) 274: time_fasttimo = curtime; /* Flag when we want a fasttimo */ 1.1.1.4 root 275: 1.1 root 276: /* 277: * NOFDREF can include still connecting to local-host, 278: * newly socreated() sockets etc. Don't want to select these. 279: */ 280: if (so->so_state & SS_NOFDREF || so->s == -1) 281: continue; 1.1.1.4 root 282: 1.1 root 283: /* 284: * Set for reading sockets which are accepting 285: */ 286: if (so->so_state & SS_FACCEPTCONN) { 287: FD_SET(so->s, readfds); 288: UPD_NFDS(so->s); 289: continue; 290: } 1.1.1.4 root 291: 1.1 root 292: /* 293: * Set for writing sockets which are connecting 294: */ 295: if (so->so_state & SS_ISFCONNECTING) { 296: FD_SET(so->s, writefds); 297: UPD_NFDS(so->s); 298: continue; 299: } 1.1.1.4 root 300: 1.1 root 301: /* 302: * Set for writing if we are connected, can send more, and 303: * we have something to send 304: */ 305: if (CONN_CANFSEND(so) && so->so_rcv.sb_cc) { 306: FD_SET(so->s, writefds); 307: UPD_NFDS(so->s); 308: } 1.1.1.4 root 309: 1.1 root 310: /* 311: * Set for reading (and urgent data) if we are connected, can 312: * receive more, and we have room for it XXX /2 ? 313: */ 314: if (CONN_CANFRCV(so) && (so->so_snd.sb_cc < (so->so_snd.sb_datalen/2))) { 315: FD_SET(so->s, readfds); 316: FD_SET(so->s, xfds); 317: UPD_NFDS(so->s); 318: } 319: } 1.1.1.4 root 320: 1.1 root 321: /* 322: * UDP sockets 323: */ 324: for (so = udb.so_next; so != &udb; so = so_next) { 325: so_next = so->so_next; 1.1.1.4 root 326: 1.1 root 327: /* 328: * See if it's timed out 329: */ 330: if (so->so_expire) { 331: if (so->so_expire <= curtime) { 332: udp_detach(so); 333: continue; 334: } else 335: do_slowtimo = 1; /* Let socket expire */ 336: } 1.1.1.4 root 337: 1.1 root 338: /* 339: * When UDP packets are received from over the 340: * link, they're sendto()'d straight away, so 341: * no need for setting for writing 342: * Limit the number of packets queued by this session 343: * to 4. Note that even though we try and limit this 344: * to 4 packets, the session could have more queued 345: * if the packets needed to be fragmented 346: * (XXX <= 4 ?) 347: */ 348: if ((so->so_state & SS_ISFCONNECTED) && so->so_queued <= 4) { 349: FD_SET(so->s, readfds); 350: UPD_NFDS(so->s); 351: } 352: } 353: } 1.1.1.4 root 354: 1.1 root 355: /* 356: * Setup timeout to use minimum CPU usage, especially when idle 357: */ 1.1.1.4 root 358: 359: /* 1.1 root 360: * First, see the timeout needed by *timo 361: */ 362: timeout.tv_sec = 0; 363: timeout.tv_usec = -1; 364: /* 365: * If a slowtimo is needed, set timeout to 500ms from the last 366: * slow timeout. If a fast timeout is needed, set timeout within 367: * 200ms of when it was requested. 368: */ 369: if (do_slowtimo) { 370: /* XXX + 10000 because some select()'s aren't that accurate */ 371: timeout.tv_usec = ((500 - (curtime - last_slowtimo)) * 1000) + 10000; 372: if (timeout.tv_usec < 0) 373: timeout.tv_usec = 0; 374: else if (timeout.tv_usec > 510000) 375: timeout.tv_usec = 510000; 1.1.1.4 root 376: 1.1 root 377: /* Can only fasttimo if we also slowtimo */ 378: if (time_fasttimo) { 379: tmp_time = (200 - (curtime - time_fasttimo)) * 1000; 380: if (tmp_time < 0) 381: tmp_time = 0; 1.1.1.4 root 382: 1.1 root 383: /* Choose the smallest of the 2 */ 384: if (tmp_time < timeout.tv_usec) 385: timeout.tv_usec = (u_int)tmp_time; 386: } 387: } 388: *pnfds = nfds; 1.1.1.4 root 389: } 1.1 root 390: 391: void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds) 392: { 393: struct socket *so, *so_next; 394: int ret; 395: 396: global_readfds = readfds; 397: global_writefds = writefds; 398: global_xfds = xfds; 399: 400: /* Update time */ 401: updtime(); 1.1.1.4 root 402: 1.1 root 403: /* 1.1.1.4 root 404: * See if anything has timed out 1.1 root 405: */ 406: if (link_up) { 407: if (time_fasttimo && ((curtime - time_fasttimo) >= 2)) { 408: tcp_fasttimo(); 409: time_fasttimo = 0; 410: } 411: if (do_slowtimo && ((curtime - last_slowtimo) >= 499)) { 412: ip_slowtimo(); 413: tcp_slowtimo(); 414: last_slowtimo = curtime; 415: } 416: } 1.1.1.4 root 417: 1.1 root 418: /* 419: * Check sockets 420: */ 421: if (link_up) { 422: /* 423: * Check TCP sockets 424: */ 425: for (so = tcb.so_next; so != &tcb; so = so_next) { 426: so_next = so->so_next; 1.1.1.4 root 427: 1.1 root 428: /* 429: * FD_ISSET is meaningless on these sockets 430: * (and they can crash the program) 431: */ 432: if (so->so_state & SS_NOFDREF || so->s == -1) 433: continue; 1.1.1.4 root 434: 1.1 root 435: /* 436: * Check for URG data 437: * This will soread as well, so no need to 438: * test for readfds below if this succeeds 439: */ 440: if (FD_ISSET(so->s, xfds)) 441: sorecvoob(so); 442: /* 443: * Check sockets for reading 444: */ 445: else if (FD_ISSET(so->s, readfds)) { 446: /* 447: * Check for incoming connections 448: */ 449: if (so->so_state & SS_FACCEPTCONN) { 450: tcp_connect(so); 451: continue; 452: } /* else */ 453: ret = soread(so); 1.1.1.4 root 454: 1.1 root 455: /* Output it if we read something */ 456: if (ret > 0) 457: tcp_output(sototcpcb(so)); 458: } 1.1.1.4 root 459: 1.1 root 460: /* 461: * Check sockets for writing 462: */ 463: if (FD_ISSET(so->s, writefds)) { 464: /* 465: * Check for non-blocking, still-connecting sockets 466: */ 467: if (so->so_state & SS_ISFCONNECTING) { 468: /* Connected */ 469: so->so_state &= ~SS_ISFCONNECTING; 1.1.1.4 root 470: 1.1 root 471: ret = send(so->s, &ret, 0, 0); 472: if (ret < 0) { 473: /* XXXXX Must fix, zero bytes is a NOP */ 474: if (errno == EAGAIN || errno == EWOULDBLOCK || 475: errno == EINPROGRESS || errno == ENOTCONN) 476: continue; 1.1.1.4 root 477: 1.1 root 478: /* else failed */ 479: so->so_state = SS_NOFDREF; 480: } 481: /* else so->so_state &= ~SS_ISFCONNECTING; */ 1.1.1.4 root 482: 1.1 root 483: /* 484: * Continue tcp_input 485: */ 486: tcp_input((struct mbuf *)NULL, sizeof(struct ip), so); 487: /* continue; */ 488: } else 489: ret = sowrite(so); 490: /* 1.1.1.4 root 491: * XXXXX If we wrote something (a lot), there 1.1 root 492: * could be a need for a window update. 493: * In the worst case, the remote will send 494: * a window probe to get things going again 495: */ 496: } 1.1.1.4 root 497: 1.1 root 498: /* 499: * Probe a still-connecting, non-blocking socket 500: * to check if it's still alive 501: */ 502: #ifdef PROBE_CONN 503: if (so->so_state & SS_ISFCONNECTING) { 504: ret = recv(so->s, (char *)&ret, 0,0); 1.1.1.4 root 505: 1.1 root 506: if (ret < 0) { 507: /* XXX */ 508: if (errno == EAGAIN || errno == EWOULDBLOCK || 509: errno == EINPROGRESS || errno == ENOTCONN) 510: continue; /* Still connecting, continue */ 1.1.1.4 root 511: 1.1 root 512: /* else failed */ 513: so->so_state = SS_NOFDREF; 1.1.1.4 root 514: 1.1 root 515: /* tcp_input will take care of it */ 516: } else { 517: ret = send(so->s, &ret, 0,0); 518: if (ret < 0) { 519: /* XXX */ 520: if (errno == EAGAIN || errno == EWOULDBLOCK || 521: errno == EINPROGRESS || errno == ENOTCONN) 522: continue; 523: /* else failed */ 524: so->so_state = SS_NOFDREF; 525: } else 526: so->so_state &= ~SS_ISFCONNECTING; 1.1.1.4 root 527: 1.1 root 528: } 529: tcp_input((struct mbuf *)NULL, sizeof(struct ip),so); 530: } /* SS_ISFCONNECTING */ 531: #endif 532: } 1.1.1.4 root 533: 1.1 root 534: /* 535: * Now UDP sockets. 536: * Incoming packets are sent straight away, they're not buffered. 537: * Incoming UDP data isn't buffered either. 538: */ 539: for (so = udb.so_next; so != &udb; so = so_next) { 540: so_next = so->so_next; 1.1.1.4 root 541: 1.1 root 542: if (so->s != -1 && FD_ISSET(so->s, readfds)) { 543: sorecvfrom(so); 544: } 545: } 546: } 1.1.1.4 root 547: 1.1 root 548: /* 549: * See if we can start outputting 550: */ 551: if (if_queued && link_up) 552: if_start(); 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 */ 592: unsigned char ar_sip[4]; /* sender IP address */ 593: unsigned char ar_tha[ETH_ALEN]; /* target hardware address */ 594: unsigned char ar_tip[4]; /* target IP address */ 595: }; 596: 1.1.1.5 ! root 597: static void arp_input(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: 610: if (!memcmp(ah->ar_tip, &special_addr, 3)) { 1.1.1.4 root 611: if (ah->ar_tip[3] == CTL_DNS || ah->ar_tip[3] == CTL_ALIAS) 1.1 root 612: goto arp_ok; 613: for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) { 614: if (ex_ptr->ex_addr == ah->ar_tip[3]) 615: goto arp_ok; 616: } 617: return; 618: arp_ok: 619: /* XXX: make an ARP request to have the client address */ 620: memcpy(client_ethaddr, eh->h_source, ETH_ALEN); 621: 622: /* ARP request for alias/dns mac address */ 623: memcpy(reh->h_dest, pkt + ETH_ALEN, ETH_ALEN); 624: memcpy(reh->h_source, special_ethaddr, ETH_ALEN - 1); 625: reh->h_source[5] = ah->ar_tip[3]; 626: reh->h_proto = htons(ETH_P_ARP); 627: 628: rah->ar_hrd = htons(1); 629: rah->ar_pro = htons(ETH_P_IP); 630: rah->ar_hln = ETH_ALEN; 631: rah->ar_pln = 4; 632: rah->ar_op = htons(ARPOP_REPLY); 633: memcpy(rah->ar_sha, reh->h_source, ETH_ALEN); 634: memcpy(rah->ar_sip, ah->ar_tip, 4); 635: memcpy(rah->ar_tha, ah->ar_sha, ETH_ALEN); 636: memcpy(rah->ar_tip, ah->ar_sip, 4); 637: slirp_output(arp_reply, sizeof(arp_reply)); 638: } 639: break; 1.1.1.5 ! root 640: case ARPOP_REPLY: ! 641: /* reply to request of client mac address ? */ ! 642: if (!memcmp(client_ethaddr, zero_ethaddr, ETH_ALEN) && ! 643: !memcmp(ah->ar_sip, &client_ipaddr.s_addr, 4)) { ! 644: memcpy(client_ethaddr, ah->ar_sha, ETH_ALEN); ! 645: } ! 646: break; 1.1 root 647: default: 648: break; 649: } 650: } 651: 652: void slirp_input(const uint8_t *pkt, int pkt_len) 653: { 654: struct mbuf *m; 655: int proto; 656: 657: if (pkt_len < ETH_HLEN) 658: return; 1.1.1.4 root 659: 1.1 root 660: proto = ntohs(*(uint16_t *)(pkt + 12)); 661: switch(proto) { 662: case ETH_P_ARP: 663: arp_input(pkt, pkt_len); 664: break; 665: case ETH_P_IP: 666: m = m_get(); 667: if (!m) 668: return; 1.1.1.3 root 669: /* Note: we add to align the IP header */ 1.1.1.5 ! root 670: if (M_FREEROOM(m) < pkt_len + 2) { ! 671: m_inc(m, pkt_len + 2); ! 672: } 1.1.1.3 root 673: m->m_len = pkt_len + 2; 674: memcpy(m->m_data + 2, pkt, pkt_len); 1.1 root 675: 1.1.1.3 root 676: m->m_data += 2 + ETH_HLEN; 677: m->m_len -= 2 + ETH_HLEN; 1.1 root 678: 679: ip_input(m); 680: break; 681: default: 682: break; 683: } 684: } 685: 686: /* output the IP packet to the ethernet device */ 687: void if_encap(const uint8_t *ip_data, int ip_data_len) 688: { 689: uint8_t buf[1600]; 690: struct ethhdr *eh = (struct ethhdr *)buf; 691: 692: if (ip_data_len + ETH_HLEN > sizeof(buf)) 693: return; 1.1.1.5 ! root 694: ! 695: if (!memcmp(client_ethaddr, zero_ethaddr, ETH_ALEN)) { ! 696: uint8_t arp_req[ETH_HLEN + sizeof(struct arphdr)]; ! 697: struct ethhdr *reh = (struct ethhdr *)arp_req; ! 698: struct arphdr *rah = (struct arphdr *)(arp_req + ETH_HLEN); ! 699: const struct ip *iph = (const struct ip *)ip_data; ! 700: ! 701: /* If the client addr is not known, there is no point in ! 702: sending the packet to it. Normally the sender should have ! 703: done an ARP request to get its MAC address. Here we do it ! 704: in place of sending the packet and we hope that the sender ! 705: will retry sending its packet. */ ! 706: memset(reh->h_dest, 0xff, ETH_ALEN); ! 707: memcpy(reh->h_source, special_ethaddr, ETH_ALEN - 1); ! 708: reh->h_source[5] = CTL_ALIAS; ! 709: reh->h_proto = htons(ETH_P_ARP); ! 710: rah->ar_hrd = htons(1); ! 711: rah->ar_pro = htons(ETH_P_IP); ! 712: rah->ar_hln = ETH_ALEN; ! 713: rah->ar_pln = 4; ! 714: rah->ar_op = htons(ARPOP_REQUEST); ! 715: /* source hw addr */ ! 716: memcpy(rah->ar_sha, special_ethaddr, ETH_ALEN - 1); ! 717: rah->ar_sha[5] = CTL_ALIAS; ! 718: /* source IP */ ! 719: memcpy(rah->ar_sip, &alias_addr, 4); ! 720: /* target hw addr (none) */ ! 721: memset(rah->ar_tha, 0, ETH_ALEN); ! 722: /* target IP */ ! 723: memcpy(rah->ar_tip, &iph->ip_dst, 4); ! 724: client_ipaddr = iph->ip_dst; ! 725: slirp_output(arp_req, sizeof(arp_req)); ! 726: } else { ! 727: memcpy(eh->h_dest, client_ethaddr, ETH_ALEN); ! 728: memcpy(eh->h_source, special_ethaddr, ETH_ALEN - 1); ! 729: /* XXX: not correct */ ! 730: eh->h_source[5] = CTL_ALIAS; ! 731: eh->h_proto = htons(ETH_P_IP); ! 732: memcpy(buf + sizeof(struct ethhdr), ip_data, ip_data_len); ! 733: slirp_output(buf, ip_data_len + ETH_HLEN); ! 734: } 1.1 root 735: } 736: 1.1.1.4 root 737: int slirp_redir(int is_udp, int host_port, 1.1 root 738: struct in_addr guest_addr, int guest_port) 739: { 740: if (is_udp) { 1.1.1.4 root 741: if (!udp_listen(htons(host_port), guest_addr.s_addr, 1.1 root 742: htons(guest_port), 0)) 743: return -1; 744: } else { 1.1.1.4 root 745: if (!solisten(htons(host_port), guest_addr.s_addr, 1.1 root 746: htons(guest_port), 0)) 747: return -1; 748: } 749: return 0; 750: } 751: 1.1.1.5 ! root 752: int slirp_add_exec(int do_pty, const void *args, int addr_low_byte, 1.1 root 753: int guest_port) 754: { 1.1.1.4 root 755: return add_exec(&exec_list, do_pty, (char *)args, 1.1 root 756: addr_low_byte, htons(guest_port)); 757: } 1.1.1.5 ! root 758: ! 759: ssize_t slirp_send(struct socket *so, const void *buf, size_t len, int flags) ! 760: { ! 761: if (so->s == -1 && so->extra) { ! 762: qemu_chr_write(so->extra, buf, len); ! 763: return len; ! 764: } ! 765: ! 766: return send(so->s, buf, len, flags); ! 767: } ! 768: ! 769: static struct socket *slirp_find_ctl_socket(int addr_low_byte, int guest_port) ! 770: { ! 771: struct socket *so; ! 772: ! 773: for (so = tcb.so_next; so != &tcb; so = so->so_next) { ! 774: if ((so->so_faddr.s_addr & htonl(0xffffff00)) == ! 775: special_addr.s_addr ! 776: && (ntohl(so->so_faddr.s_addr) & 0xff) == ! 777: addr_low_byte ! 778: && htons(so->so_fport) == guest_port) ! 779: return so; ! 780: } ! 781: ! 782: return NULL; ! 783: } ! 784: ! 785: size_t slirp_socket_can_recv(int addr_low_byte, int guest_port) ! 786: { ! 787: struct iovec iov[2]; ! 788: struct socket *so; ! 789: ! 790: if (!link_up) ! 791: return 0; ! 792: ! 793: so = slirp_find_ctl_socket(addr_low_byte, guest_port); ! 794: ! 795: if (!so || so->so_state & SS_NOFDREF) ! 796: return 0; ! 797: ! 798: if (!CONN_CANFRCV(so) || so->so_snd.sb_cc >= (so->so_snd.sb_datalen/2)) ! 799: return 0; ! 800: ! 801: return sopreprbuf(so, iov, NULL); ! 802: } ! 803: ! 804: void slirp_socket_recv(int addr_low_byte, int guest_port, const uint8_t *buf, ! 805: int size) ! 806: { ! 807: int ret; ! 808: struct socket *so = slirp_find_ctl_socket(addr_low_byte, guest_port); ! 809: ! 810: if (!so) ! 811: return; ! 812: ! 813: ret = soreadbuf(so, (const char *)buf, size); ! 814: ! 815: if (ret > 0) ! 816: tcp_output(sototcpcb(so)); ! 817: } ! 818: ! 819: static void slirp_tcp_save(QEMUFile *f, struct tcpcb *tp) ! 820: { ! 821: int i; ! 822: ! 823: qemu_put_sbe16(f, tp->t_state); ! 824: for (i = 0; i < TCPT_NTIMERS; i++) ! 825: qemu_put_sbe16(f, tp->t_timer[i]); ! 826: qemu_put_sbe16(f, tp->t_rxtshift); ! 827: qemu_put_sbe16(f, tp->t_rxtcur); ! 828: qemu_put_sbe16(f, tp->t_dupacks); ! 829: qemu_put_be16(f, tp->t_maxseg); ! 830: qemu_put_sbyte(f, tp->t_force); ! 831: qemu_put_be16(f, tp->t_flags); ! 832: qemu_put_be32(f, tp->snd_una); ! 833: qemu_put_be32(f, tp->snd_nxt); ! 834: qemu_put_be32(f, tp->snd_up); ! 835: qemu_put_be32(f, tp->snd_wl1); ! 836: qemu_put_be32(f, tp->snd_wl2); ! 837: qemu_put_be32(f, tp->iss); ! 838: qemu_put_be32(f, tp->snd_wnd); ! 839: qemu_put_be32(f, tp->rcv_wnd); ! 840: qemu_put_be32(f, tp->rcv_nxt); ! 841: qemu_put_be32(f, tp->rcv_up); ! 842: qemu_put_be32(f, tp->irs); ! 843: qemu_put_be32(f, tp->rcv_adv); ! 844: qemu_put_be32(f, tp->snd_max); ! 845: qemu_put_be32(f, tp->snd_cwnd); ! 846: qemu_put_be32(f, tp->snd_ssthresh); ! 847: qemu_put_sbe16(f, tp->t_idle); ! 848: qemu_put_sbe16(f, tp->t_rtt); ! 849: qemu_put_be32(f, tp->t_rtseq); ! 850: qemu_put_sbe16(f, tp->t_srtt); ! 851: qemu_put_sbe16(f, tp->t_rttvar); ! 852: qemu_put_be16(f, tp->t_rttmin); ! 853: qemu_put_be32(f, tp->max_sndwnd); ! 854: qemu_put_byte(f, tp->t_oobflags); ! 855: qemu_put_byte(f, tp->t_iobc); ! 856: qemu_put_sbe16(f, tp->t_softerror); ! 857: qemu_put_byte(f, tp->snd_scale); ! 858: qemu_put_byte(f, tp->rcv_scale); ! 859: qemu_put_byte(f, tp->request_r_scale); ! 860: qemu_put_byte(f, tp->requested_s_scale); ! 861: qemu_put_be32(f, tp->ts_recent); ! 862: qemu_put_be32(f, tp->ts_recent_age); ! 863: qemu_put_be32(f, tp->last_ack_sent); ! 864: } ! 865: ! 866: static void slirp_sbuf_save(QEMUFile *f, struct sbuf *sbuf) ! 867: { ! 868: uint32_t off; ! 869: ! 870: qemu_put_be32(f, sbuf->sb_cc); ! 871: qemu_put_be32(f, sbuf->sb_datalen); ! 872: off = (uint32_t)(sbuf->sb_wptr - sbuf->sb_data); ! 873: qemu_put_sbe32(f, off); ! 874: off = (uint32_t)(sbuf->sb_rptr - sbuf->sb_data); ! 875: qemu_put_sbe32(f, off); ! 876: qemu_put_buffer(f, (unsigned char*)sbuf->sb_data, sbuf->sb_datalen); ! 877: } ! 878: ! 879: static void slirp_socket_save(QEMUFile *f, struct socket *so) ! 880: { ! 881: qemu_put_be32(f, so->so_urgc); ! 882: qemu_put_be32(f, so->so_faddr.s_addr); ! 883: qemu_put_be32(f, so->so_laddr.s_addr); ! 884: qemu_put_be16(f, so->so_fport); ! 885: qemu_put_be16(f, so->so_lport); ! 886: qemu_put_byte(f, so->so_iptos); ! 887: qemu_put_byte(f, so->so_emu); ! 888: qemu_put_byte(f, so->so_type); ! 889: qemu_put_be32(f, so->so_state); ! 890: slirp_sbuf_save(f, &so->so_rcv); ! 891: slirp_sbuf_save(f, &so->so_snd); ! 892: slirp_tcp_save(f, so->so_tcpcb); ! 893: } ! 894: ! 895: static void slirp_state_save(QEMUFile *f, void *opaque) ! 896: { ! 897: struct ex_list *ex_ptr; ! 898: ! 899: for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) ! 900: if (ex_ptr->ex_pty == 3) { ! 901: struct socket *so; ! 902: so = slirp_find_ctl_socket(ex_ptr->ex_addr, ntohs(ex_ptr->ex_fport)); ! 903: if (!so) ! 904: continue; ! 905: ! 906: qemu_put_byte(f, 42); ! 907: slirp_socket_save(f, so); ! 908: } ! 909: qemu_put_byte(f, 0); ! 910: } ! 911: ! 912: static void slirp_tcp_load(QEMUFile *f, struct tcpcb *tp) ! 913: { ! 914: int i; ! 915: ! 916: tp->t_state = qemu_get_sbe16(f); ! 917: for (i = 0; i < TCPT_NTIMERS; i++) ! 918: tp->t_timer[i] = qemu_get_sbe16(f); ! 919: tp->t_rxtshift = qemu_get_sbe16(f); ! 920: tp->t_rxtcur = qemu_get_sbe16(f); ! 921: tp->t_dupacks = qemu_get_sbe16(f); ! 922: tp->t_maxseg = qemu_get_be16(f); ! 923: tp->t_force = qemu_get_sbyte(f); ! 924: tp->t_flags = qemu_get_be16(f); ! 925: tp->snd_una = qemu_get_be32(f); ! 926: tp->snd_nxt = qemu_get_be32(f); ! 927: tp->snd_up = qemu_get_be32(f); ! 928: tp->snd_wl1 = qemu_get_be32(f); ! 929: tp->snd_wl2 = qemu_get_be32(f); ! 930: tp->iss = qemu_get_be32(f); ! 931: tp->snd_wnd = qemu_get_be32(f); ! 932: tp->rcv_wnd = qemu_get_be32(f); ! 933: tp->rcv_nxt = qemu_get_be32(f); ! 934: tp->rcv_up = qemu_get_be32(f); ! 935: tp->irs = qemu_get_be32(f); ! 936: tp->rcv_adv = qemu_get_be32(f); ! 937: tp->snd_max = qemu_get_be32(f); ! 938: tp->snd_cwnd = qemu_get_be32(f); ! 939: tp->snd_ssthresh = qemu_get_be32(f); ! 940: tp->t_idle = qemu_get_sbe16(f); ! 941: tp->t_rtt = qemu_get_sbe16(f); ! 942: tp->t_rtseq = qemu_get_be32(f); ! 943: tp->t_srtt = qemu_get_sbe16(f); ! 944: tp->t_rttvar = qemu_get_sbe16(f); ! 945: tp->t_rttmin = qemu_get_be16(f); ! 946: tp->max_sndwnd = qemu_get_be32(f); ! 947: tp->t_oobflags = qemu_get_byte(f); ! 948: tp->t_iobc = qemu_get_byte(f); ! 949: tp->t_softerror = qemu_get_sbe16(f); ! 950: tp->snd_scale = qemu_get_byte(f); ! 951: tp->rcv_scale = qemu_get_byte(f); ! 952: tp->request_r_scale = qemu_get_byte(f); ! 953: tp->requested_s_scale = qemu_get_byte(f); ! 954: tp->ts_recent = qemu_get_be32(f); ! 955: tp->ts_recent_age = qemu_get_be32(f); ! 956: tp->last_ack_sent = qemu_get_be32(f); ! 957: tcp_template(tp); ! 958: } ! 959: ! 960: static int slirp_sbuf_load(QEMUFile *f, struct sbuf *sbuf) ! 961: { ! 962: uint32_t off, sb_cc, sb_datalen; ! 963: ! 964: sb_cc = qemu_get_be32(f); ! 965: sb_datalen = qemu_get_be32(f); ! 966: ! 967: sbreserve(sbuf, sb_datalen); ! 968: ! 969: if (sbuf->sb_datalen != sb_datalen) ! 970: return -ENOMEM; ! 971: ! 972: sbuf->sb_cc = sb_cc; ! 973: ! 974: off = qemu_get_sbe32(f); ! 975: sbuf->sb_wptr = sbuf->sb_data + off; ! 976: off = qemu_get_sbe32(f); ! 977: sbuf->sb_rptr = sbuf->sb_data + off; ! 978: qemu_get_buffer(f, (unsigned char*)sbuf->sb_data, sbuf->sb_datalen); ! 979: ! 980: return 0; ! 981: } ! 982: ! 983: static int slirp_socket_load(QEMUFile *f, struct socket *so) ! 984: { ! 985: if (tcp_attach(so) < 0) ! 986: return -ENOMEM; ! 987: ! 988: so->so_urgc = qemu_get_be32(f); ! 989: so->so_faddr.s_addr = qemu_get_be32(f); ! 990: so->so_laddr.s_addr = qemu_get_be32(f); ! 991: so->so_fport = qemu_get_be16(f); ! 992: so->so_lport = qemu_get_be16(f); ! 993: so->so_iptos = qemu_get_byte(f); ! 994: so->so_emu = qemu_get_byte(f); ! 995: so->so_type = qemu_get_byte(f); ! 996: so->so_state = qemu_get_be32(f); ! 997: if (slirp_sbuf_load(f, &so->so_rcv) < 0) ! 998: return -ENOMEM; ! 999: if (slirp_sbuf_load(f, &so->so_snd) < 0) ! 1000: return -ENOMEM; ! 1001: slirp_tcp_load(f, so->so_tcpcb); ! 1002: ! 1003: return 0; ! 1004: } ! 1005: ! 1006: static int slirp_state_load(QEMUFile *f, void *opaque, int version_id) ! 1007: { ! 1008: struct ex_list *ex_ptr; ! 1009: int r; ! 1010: ! 1011: while ((r = qemu_get_byte(f))) { ! 1012: int ret; ! 1013: struct socket *so = socreate(); ! 1014: ! 1015: if (!so) ! 1016: return -ENOMEM; ! 1017: ! 1018: ret = slirp_socket_load(f, so); ! 1019: ! 1020: if (ret < 0) ! 1021: return ret; ! 1022: ! 1023: if ((so->so_faddr.s_addr & htonl(0xffffff00)) != special_addr.s_addr) ! 1024: return -EINVAL; ! 1025: ! 1026: for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) ! 1027: if (ex_ptr->ex_pty == 3 && ! 1028: (ntohl(so->so_faddr.s_addr) & 0xff) == ex_ptr->ex_addr && ! 1029: so->so_fport == ex_ptr->ex_fport) ! 1030: break; ! 1031: ! 1032: if (!ex_ptr) ! 1033: return -EINVAL; ! 1034: ! 1035: so->extra = (void *)ex_ptr->ex_exec; ! 1036: } ! 1037: ! 1038: return 0; ! 1039: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.