qemu/slirp/slirp.c
<<
>>
Prefs
   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/osdep.h"
  25#include "qemu-common.h"
  26#include "qemu/timer.h"
  27#include "qemu/error-report.h"
  28#include "sysemu/char.h"
  29#include "slirp.h"
  30#include "hw/hw.h"
  31#include "qemu/cutils.h"
  32
  33/* host loopback address */
  34struct in_addr loopback_addr;
  35/* host loopback network mask */
  36unsigned long loopback_mask;
  37
  38/* emulated hosts use the MAC addr 52:55:IP:IP:IP:IP */
  39static const uint8_t special_ethaddr[ETH_ALEN] = {
  40    0x52, 0x55, 0x00, 0x00, 0x00, 0x00
  41};
  42
  43u_int curtime;
  44
  45static QTAILQ_HEAD(slirp_instances, Slirp) slirp_instances =
  46    QTAILQ_HEAD_INITIALIZER(slirp_instances);
  47
  48static struct in_addr dns_addr;
  49static u_int dns_addr_time;
  50
  51#define TIMEOUT_FAST 2  /* milliseconds */
  52#define TIMEOUT_SLOW 499  /* milliseconds */
  53/* for the aging of certain requests like DNS */
  54#define TIMEOUT_DEFAULT 1000  /* milliseconds */
  55
  56#ifdef _WIN32
  57
  58int get_dns_addr(struct in_addr *pdns_addr)
  59{
  60    FIXED_INFO *FixedInfo=NULL;
  61    ULONG    BufLen;
  62    DWORD    ret;
  63    IP_ADDR_STRING *pIPAddr;
  64    struct in_addr tmp_addr;
  65
  66    if (dns_addr.s_addr != 0 && (curtime - dns_addr_time) < TIMEOUT_DEFAULT) {
  67        *pdns_addr = dns_addr;
  68        return 0;
  69    }
  70
  71    FixedInfo = (FIXED_INFO *)GlobalAlloc(GPTR, sizeof(FIXED_INFO));
  72    BufLen = sizeof(FIXED_INFO);
  73
  74    if (ERROR_BUFFER_OVERFLOW == GetNetworkParams(FixedInfo, &BufLen)) {
  75        if (FixedInfo) {
  76            GlobalFree(FixedInfo);
  77            FixedInfo = NULL;
  78        }
  79        FixedInfo = GlobalAlloc(GPTR, BufLen);
  80    }
  81
  82    if ((ret = GetNetworkParams(FixedInfo, &BufLen)) != ERROR_SUCCESS) {
  83        printf("GetNetworkParams failed. ret = %08x\n", (u_int)ret );
  84        if (FixedInfo) {
  85            GlobalFree(FixedInfo);
  86            FixedInfo = NULL;
  87        }
  88        return -1;
  89    }
  90
  91    pIPAddr = &(FixedInfo->DnsServerList);
  92    inet_aton(pIPAddr->IpAddress.String, &tmp_addr);
  93    *pdns_addr = tmp_addr;
  94    dns_addr = tmp_addr;
  95    dns_addr_time = curtime;
  96    if (FixedInfo) {
  97        GlobalFree(FixedInfo);
  98        FixedInfo = NULL;
  99    }
 100    return 0;
 101}
 102
 103static void winsock_cleanup(void)
 104{
 105    WSACleanup();
 106}
 107
 108#else
 109
 110static struct stat dns_addr_stat;
 111
 112int get_dns_addr(struct in_addr *pdns_addr)
 113{
 114    char buff[512];
 115    char buff2[257];
 116    FILE *f;
 117    int found = 0;
 118    struct in_addr tmp_addr;
 119
 120    if (dns_addr.s_addr != 0) {
 121        struct stat old_stat;
 122        if ((curtime - dns_addr_time) < TIMEOUT_DEFAULT) {
 123            *pdns_addr = dns_addr;
 124            return 0;
 125        }
 126        old_stat = dns_addr_stat;
 127        if (stat("/etc/resolv.conf", &dns_addr_stat) != 0)
 128            return -1;
 129        if ((dns_addr_stat.st_dev == old_stat.st_dev)
 130            && (dns_addr_stat.st_ino == old_stat.st_ino)
 131            && (dns_addr_stat.st_size == old_stat.st_size)
 132            && (dns_addr_stat.st_mtime == old_stat.st_mtime)) {
 133            *pdns_addr = dns_addr;
 134            return 0;
 135        }
 136    }
 137
 138    f = fopen("/etc/resolv.conf", "r");
 139    if (!f)
 140        return -1;
 141
 142#ifdef DEBUG
 143    fprintf(stderr, "IP address of your DNS(s): ");
 144#endif
 145    while (fgets(buff, 512, f) != NULL) {
 146        if (sscanf(buff, "nameserver%*[ \t]%256s", buff2) == 1) {
 147            if (!inet_aton(buff2, &tmp_addr))
 148                continue;
 149            /* If it's the first one, set it to dns_addr */
 150            if (!found) {
 151                *pdns_addr = tmp_addr;
 152                dns_addr = tmp_addr;
 153                dns_addr_time = curtime;
 154            }
 155#ifdef DEBUG
 156            else
 157                fprintf(stderr, ", ");
 158#endif
 159            if (++found > 3) {
 160#ifdef DEBUG
 161                fprintf(stderr, "(more)");
 162#endif
 163                break;
 164            }
 165#ifdef DEBUG
 166            else
 167                fprintf(stderr, "%s", inet_ntoa(tmp_addr));
 168#endif
 169        }
 170    }
 171    fclose(f);
 172    if (!found)
 173        return -1;
 174    return 0;
 175}
 176
 177#endif
 178
 179static void slirp_init_once(void)
 180{
 181    static int initialized;
 182#ifdef _WIN32
 183    WSADATA Data;
 184#endif
 185
 186    if (initialized) {
 187        return;
 188    }
 189    initialized = 1;
 190
 191#ifdef _WIN32
 192    WSAStartup(MAKEWORD(2,0), &Data);
 193    atexit(winsock_cleanup);
 194#endif
 195
 196    loopback_addr.s_addr = htonl(INADDR_LOOPBACK);
 197    loopback_mask = htonl(IN_CLASSA_NET);
 198}
 199
 200static void slirp_state_save(QEMUFile *f, void *opaque);
 201static int slirp_state_load(QEMUFile *f, void *opaque, int version_id);
 202
 203Slirp *slirp_init(int restricted, bool in_enabled, struct in_addr vnetwork,
 204                  struct in_addr vnetmask, struct in_addr vhost,
 205                  bool in6_enabled,
 206                  struct in6_addr vprefix_addr6, uint8_t vprefix_len,
 207                  struct in6_addr vhost6, const char *vhostname,
 208                  const char *tftp_path, const char *bootfile,
 209                  struct in_addr vdhcp_start, struct in_addr vnameserver,
 210                  struct in6_addr vnameserver6, const char **vdnssearch,
 211                  void *opaque)
 212{
 213    Slirp *slirp = g_malloc0(sizeof(Slirp));
 214
 215    slirp_init_once();
 216
 217    slirp->grand = g_rand_new();
 218    slirp->restricted = restricted;
 219
 220    slirp->in_enabled = in_enabled;
 221    slirp->in6_enabled = in6_enabled;
 222
 223    if_init(slirp);
 224    ip_init(slirp);
 225    ip6_init(slirp);
 226
 227    /* Initialise mbufs *after* setting the MTU */
 228    m_init(slirp);
 229
 230    slirp->vnetwork_addr = vnetwork;
 231    slirp->vnetwork_mask = vnetmask;
 232    slirp->vhost_addr = vhost;
 233    slirp->vprefix_addr6 = vprefix_addr6;
 234    slirp->vprefix_len = vprefix_len;
 235    slirp->vhost_addr6 = vhost6;
 236    if (vhostname) {
 237        pstrcpy(slirp->client_hostname, sizeof(slirp->client_hostname),
 238                vhostname);
 239    }
 240    slirp->tftp_prefix = g_strdup(tftp_path);
 241    slirp->bootp_filename = g_strdup(bootfile);
 242    slirp->vdhcp_startaddr = vdhcp_start;
 243    slirp->vnameserver_addr = vnameserver;
 244    slirp->vnameserver_addr6 = vnameserver6;
 245
 246    if (vdnssearch) {
 247        translate_dnssearch(slirp, vdnssearch);
 248    }
 249
 250    slirp->opaque = opaque;
 251
 252    register_savevm(NULL, "slirp", 0, 4,
 253                    slirp_state_save, slirp_state_load, slirp);
 254
 255    QTAILQ_INSERT_TAIL(&slirp_instances, slirp, entry);
 256
 257    return slirp;
 258}
 259
 260void slirp_cleanup(Slirp *slirp)
 261{
 262    QTAILQ_REMOVE(&slirp_instances, slirp, entry);
 263
 264    unregister_savevm(NULL, "slirp", slirp);
 265
 266    ip_cleanup(slirp);
 267    ip6_cleanup(slirp);
 268    m_cleanup(slirp);
 269
 270    g_rand_free(slirp->grand);
 271
 272    g_free(slirp->vdnssearch);
 273    g_free(slirp->tftp_prefix);
 274    g_free(slirp->bootp_filename);
 275    g_free(slirp);
 276}
 277
 278#define CONN_CANFSEND(so) (((so)->so_state & (SS_FCANTSENDMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED)
 279#define CONN_CANFRCV(so) (((so)->so_state & (SS_FCANTRCVMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED)
 280
 281static void slirp_update_timeout(uint32_t *timeout)
 282{
 283    Slirp *slirp;
 284    uint32_t t;
 285
 286    if (*timeout <= TIMEOUT_FAST) {
 287        return;
 288    }
 289
 290    t = MIN(1000, *timeout);
 291
 292    /* If we have tcp timeout with slirp, then we will fill @timeout with
 293     * more precise value.
 294     */
 295    QTAILQ_FOREACH(slirp, &slirp_instances, entry) {
 296        if (slirp->time_fasttimo) {
 297            *timeout = TIMEOUT_FAST;
 298            return;
 299        }
 300        if (slirp->do_slowtimo) {
 301            t = MIN(TIMEOUT_SLOW, t);
 302        }
 303    }
 304    *timeout = t;
 305}
 306
 307void slirp_pollfds_fill(GArray *pollfds, uint32_t *timeout)
 308{
 309    Slirp *slirp;
 310    struct socket *so, *so_next;
 311
 312    if (QTAILQ_EMPTY(&slirp_instances)) {
 313        return;
 314    }
 315
 316    /*
 317     * First, TCP sockets
 318     */
 319
 320    QTAILQ_FOREACH(slirp, &slirp_instances, entry) {
 321        /*
 322         * *_slowtimo needs calling if there are IP fragments
 323         * in the fragment queue, or there are TCP connections active
 324         */
 325        slirp->do_slowtimo = ((slirp->tcb.so_next != &slirp->tcb) ||
 326                (&slirp->ipq.ip_link != slirp->ipq.ip_link.next));
 327
 328        for (so = slirp->tcb.so_next; so != &slirp->tcb;
 329                so = so_next) {
 330            int events = 0;
 331
 332            so_next = so->so_next;
 333
 334            so->pollfds_idx = -1;
 335
 336            /*
 337             * See if we need a tcp_fasttimo
 338             */
 339            if (slirp->time_fasttimo == 0 &&
 340                so->so_tcpcb->t_flags & TF_DELACK) {
 341                slirp->time_fasttimo = curtime; /* Flag when want a fasttimo */
 342            }
 343
 344            /*
 345             * NOFDREF can include still connecting to local-host,
 346             * newly socreated() sockets etc. Don't want to select these.
 347             */
 348            if (so->so_state & SS_NOFDREF || so->s == -1) {
 349                continue;
 350            }
 351
 352            /*
 353             * Set for reading sockets which are accepting
 354             */
 355            if (so->so_state & SS_FACCEPTCONN) {
 356                GPollFD pfd = {
 357                    .fd = so->s,
 358                    .events = G_IO_IN | G_IO_HUP | G_IO_ERR,
 359                };
 360                so->pollfds_idx = pollfds->len;
 361                g_array_append_val(pollfds, pfd);
 362                continue;
 363            }
 364
 365            /*
 366             * Set for writing sockets which are connecting
 367             */
 368            if (so->so_state & SS_ISFCONNECTING) {
 369                GPollFD pfd = {
 370                    .fd = so->s,
 371                    .events = G_IO_OUT | G_IO_ERR,
 372                };
 373                so->pollfds_idx = pollfds->len;
 374                g_array_append_val(pollfds, pfd);
 375                continue;
 376            }
 377
 378            /*
 379             * Set for writing if we are connected, can send more, and
 380             * we have something to send
 381             */
 382            if (CONN_CANFSEND(so) && so->so_rcv.sb_cc) {
 383                events |= G_IO_OUT | G_IO_ERR;
 384            }
 385
 386            /*
 387             * Set for reading (and urgent data) if we are connected, can
 388             * receive more, and we have room for it XXX /2 ?
 389             */
 390            if (CONN_CANFRCV(so) &&
 391                (so->so_snd.sb_cc < (so->so_snd.sb_datalen/2))) {
 392                events |= G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_PRI;
 393            }
 394
 395            if (events) {
 396                GPollFD pfd = {
 397                    .fd = so->s,
 398                    .events = events,
 399                };
 400                so->pollfds_idx = pollfds->len;
 401                g_array_append_val(pollfds, pfd);
 402            }
 403        }
 404
 405        /*
 406         * UDP sockets
 407         */
 408        for (so = slirp->udb.so_next; so != &slirp->udb;
 409                so = so_next) {
 410            so_next = so->so_next;
 411
 412            so->pollfds_idx = -1;
 413
 414            /*
 415             * See if it's timed out
 416             */
 417            if (so->so_expire) {
 418                if (so->so_expire <= curtime) {
 419                    udp_detach(so);
 420                    continue;
 421                } else {
 422                    slirp->do_slowtimo = true; /* Let socket expire */
 423                }
 424            }
 425
 426            /*
 427             * When UDP packets are received from over the
 428             * link, they're sendto()'d straight away, so
 429             * no need for setting for writing
 430             * Limit the number of packets queued by this session
 431             * to 4.  Note that even though we try and limit this
 432             * to 4 packets, the session could have more queued
 433             * if the packets needed to be fragmented
 434             * (XXX <= 4 ?)
 435             */
 436            if ((so->so_state & SS_ISFCONNECTED) && so->so_queued <= 4) {
 437                GPollFD pfd = {
 438                    .fd = so->s,
 439                    .events = G_IO_IN | G_IO_HUP | G_IO_ERR,
 440                };
 441                so->pollfds_idx = pollfds->len;
 442                g_array_append_val(pollfds, pfd);
 443            }
 444        }
 445
 446        /*
 447         * ICMP sockets
 448         */
 449        for (so = slirp->icmp.so_next; so != &slirp->icmp;
 450                so = so_next) {
 451            so_next = so->so_next;
 452
 453            so->pollfds_idx = -1;
 454
 455            /*
 456             * See if it's timed out
 457             */
 458            if (so->so_expire) {
 459                if (so->so_expire <= curtime) {
 460                    icmp_detach(so);
 461                    continue;
 462                } else {
 463                    slirp->do_slowtimo = true; /* Let socket expire */
 464                }
 465            }
 466
 467            if (so->so_state & SS_ISFCONNECTED) {
 468                GPollFD pfd = {
 469                    .fd = so->s,
 470                    .events = G_IO_IN | G_IO_HUP | G_IO_ERR,
 471                };
 472                so->pollfds_idx = pollfds->len;
 473                g_array_append_val(pollfds, pfd);
 474            }
 475        }
 476    }
 477    slirp_update_timeout(timeout);
 478}
 479
 480void slirp_pollfds_poll(GArray *pollfds, int select_error)
 481{
 482    Slirp *slirp;
 483    struct socket *so, *so_next;
 484    int ret;
 485
 486    if (QTAILQ_EMPTY(&slirp_instances)) {
 487        return;
 488    }
 489
 490    curtime = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
 491
 492    QTAILQ_FOREACH(slirp, &slirp_instances, entry) {
 493        /*
 494         * See if anything has timed out
 495         */
 496        if (slirp->time_fasttimo &&
 497            ((curtime - slirp->time_fasttimo) >= TIMEOUT_FAST)) {
 498            tcp_fasttimo(slirp);
 499            slirp->time_fasttimo = 0;
 500        }
 501        if (slirp->do_slowtimo &&
 502            ((curtime - slirp->last_slowtimo) >= TIMEOUT_SLOW)) {
 503            ip_slowtimo(slirp);
 504            tcp_slowtimo(slirp);
 505            slirp->last_slowtimo = curtime;
 506        }
 507
 508        /*
 509         * Check sockets
 510         */
 511        if (!select_error) {
 512            /*
 513             * Check TCP sockets
 514             */
 515            for (so = slirp->tcb.so_next; so != &slirp->tcb;
 516                    so = so_next) {
 517                int revents;
 518
 519                so_next = so->so_next;
 520
 521                revents = 0;
 522                if (so->pollfds_idx != -1) {
 523                    revents = g_array_index(pollfds, GPollFD,
 524                                            so->pollfds_idx).revents;
 525                }
 526
 527                if (so->so_state & SS_NOFDREF || so->s == -1) {
 528                    continue;
 529                }
 530
 531                /*
 532                 * Check for URG data
 533                 * This will soread as well, so no need to
 534                 * test for G_IO_IN below if this succeeds
 535                 */
 536                if (revents & G_IO_PRI) {
 537                    ret = sorecvoob(so);
 538                    if (ret < 0) {
 539                        /* Socket error might have resulted in the socket being
 540                         * removed, do not try to do anything more with it. */
 541                        continue;
 542                    }
 543                }
 544                /*
 545                 * Check sockets for reading
 546                 */
 547                else if (revents & (G_IO_IN | G_IO_HUP | G_IO_ERR)) {
 548                    /*
 549                     * Check for incoming connections
 550                     */
 551                    if (so->so_state & SS_FACCEPTCONN) {
 552                        tcp_connect(so);
 553                        continue;
 554                    } /* else */
 555                    ret = soread(so);
 556
 557                    /* Output it if we read something */
 558                    if (ret > 0) {
 559                        tcp_output(sototcpcb(so));
 560                    }
 561                    if (ret < 0) {
 562                        /* Socket error might have resulted in the socket being
 563                         * removed, do not try to do anything more with it. */
 564                        continue;
 565                    }
 566                }
 567
 568                /*
 569                 * Check sockets for writing
 570                 */
 571                if (!(so->so_state & SS_NOFDREF) &&
 572                        (revents & (G_IO_OUT | G_IO_ERR))) {
 573                    /*
 574                     * Check for non-blocking, still-connecting sockets
 575                     */
 576                    if (so->so_state & SS_ISFCONNECTING) {
 577                        /* Connected */
 578                        so->so_state &= ~SS_ISFCONNECTING;
 579
 580                        ret = send(so->s, (const void *) &ret, 0, 0);
 581                        if (ret < 0) {
 582                            /* XXXXX Must fix, zero bytes is a NOP */
 583                            if (errno == EAGAIN || errno == EWOULDBLOCK ||
 584                                errno == EINPROGRESS || errno == ENOTCONN) {
 585                                continue;
 586                            }
 587
 588                            /* else failed */
 589                            so->so_state &= SS_PERSISTENT_MASK;
 590                            so->so_state |= SS_NOFDREF;
 591                        }
 592                        /* else so->so_state &= ~SS_ISFCONNECTING; */
 593
 594                        /*
 595                         * Continue tcp_input
 596                         */
 597                        tcp_input((struct mbuf *)NULL, sizeof(struct ip), so,
 598                                  so->so_ffamily);
 599                        /* continue; */
 600                    } else {
 601                        ret = sowrite(so);
 602                    }
 603                    /*
 604                     * XXXXX If we wrote something (a lot), there
 605                     * could be a need for a window update.
 606                     * In the worst case, the remote will send
 607                     * a window probe to get things going again
 608                     */
 609                }
 610
 611                /*
 612                 * Probe a still-connecting, non-blocking socket
 613                 * to check if it's still alive
 614                 */
 615#ifdef PROBE_CONN
 616                if (so->so_state & SS_ISFCONNECTING) {
 617                    ret = qemu_recv(so->s, &ret, 0, 0);
 618
 619                    if (ret < 0) {
 620                        /* XXX */
 621                        if (errno == EAGAIN || errno == EWOULDBLOCK ||
 622                            errno == EINPROGRESS || errno == ENOTCONN) {
 623                            continue; /* Still connecting, continue */
 624                        }
 625
 626                        /* else failed */
 627                        so->so_state &= SS_PERSISTENT_MASK;
 628                        so->so_state |= SS_NOFDREF;
 629
 630                        /* tcp_input will take care of it */
 631                    } else {
 632                        ret = send(so->s, &ret, 0, 0);
 633                        if (ret < 0) {
 634                            /* XXX */
 635                            if (errno == EAGAIN || errno == EWOULDBLOCK ||
 636                                errno == EINPROGRESS || errno == ENOTCONN) {
 637                                continue;
 638                            }
 639                            /* else failed */
 640                            so->so_state &= SS_PERSISTENT_MASK;
 641                            so->so_state |= SS_NOFDREF;
 642                        } else {
 643                            so->so_state &= ~SS_ISFCONNECTING;
 644                        }
 645
 646                    }
 647                    tcp_input((struct mbuf *)NULL, sizeof(struct ip), so,
 648                              so->so_ffamily);
 649                } /* SS_ISFCONNECTING */
 650#endif
 651            }
 652
 653            /*
 654             * Now UDP sockets.
 655             * Incoming packets are sent straight away, they're not buffered.
 656             * Incoming UDP data isn't buffered either.
 657             */
 658            for (so = slirp->udb.so_next; so != &slirp->udb;
 659                    so = so_next) {
 660                int revents;
 661
 662                so_next = so->so_next;
 663
 664                revents = 0;
 665                if (so->pollfds_idx != -1) {
 666                    revents = g_array_index(pollfds, GPollFD,
 667                            so->pollfds_idx).revents;
 668                }
 669
 670                if (so->s != -1 &&
 671                    (revents & (G_IO_IN | G_IO_HUP | G_IO_ERR))) {
 672                    sorecvfrom(so);
 673                }
 674            }
 675
 676            /*
 677             * Check incoming ICMP relies.
 678             */
 679            for (so = slirp->icmp.so_next; so != &slirp->icmp;
 680                    so = so_next) {
 681                    int revents;
 682
 683                    so_next = so->so_next;
 684
 685                    revents = 0;
 686                    if (so->pollfds_idx != -1) {
 687                        revents = g_array_index(pollfds, GPollFD,
 688                                                so->pollfds_idx).revents;
 689                    }
 690
 691                    if (so->s != -1 &&
 692                        (revents & (G_IO_IN | G_IO_HUP | G_IO_ERR))) {
 693                    icmp_receive(so);
 694                }
 695            }
 696        }
 697
 698        if_start(slirp);
 699    }
 700}
 701
 702static void arp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len)
 703{
 704    struct arphdr *ah = (struct arphdr *)(pkt + ETH_HLEN);
 705    uint8_t arp_reply[max(ETH_HLEN + sizeof(struct arphdr), 64)];
 706    struct ethhdr *reh = (struct ethhdr *)arp_reply;
 707    struct arphdr *rah = (struct arphdr *)(arp_reply + ETH_HLEN);
 708    int ar_op;
 709    struct ex_list *ex_ptr;
 710
 711    if (!slirp->in_enabled) {
 712        return;
 713    }
 714
 715    ar_op = ntohs(ah->ar_op);
 716    switch(ar_op) {
 717    case ARPOP_REQUEST:
 718        if (ah->ar_tip == ah->ar_sip) {
 719            /* Gratuitous ARP */
 720            arp_table_add(slirp, ah->ar_sip, ah->ar_sha);
 721            return;
 722        }
 723
 724        if ((ah->ar_tip & slirp->vnetwork_mask.s_addr) ==
 725            slirp->vnetwork_addr.s_addr) {
 726            if (ah->ar_tip == slirp->vnameserver_addr.s_addr ||
 727                ah->ar_tip == slirp->vhost_addr.s_addr)
 728                goto arp_ok;
 729            for (ex_ptr = slirp->exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
 730                if (ex_ptr->ex_addr.s_addr == ah->ar_tip)
 731                    goto arp_ok;
 732            }
 733            return;
 734        arp_ok:
 735            memset(arp_reply, 0, sizeof(arp_reply));
 736
 737            arp_table_add(slirp, ah->ar_sip, ah->ar_sha);
 738
 739            /* ARP request for alias/dns mac address */
 740            memcpy(reh->h_dest, pkt + ETH_ALEN, ETH_ALEN);
 741            memcpy(reh->h_source, special_ethaddr, ETH_ALEN - 4);
 742            memcpy(&reh->h_source[2], &ah->ar_tip, 4);
 743            reh->h_proto = htons(ETH_P_ARP);
 744
 745            rah->ar_hrd = htons(1);
 746            rah->ar_pro = htons(ETH_P_IP);
 747            rah->ar_hln = ETH_ALEN;
 748            rah->ar_pln = 4;
 749            rah->ar_op = htons(ARPOP_REPLY);
 750            memcpy(rah->ar_sha, reh->h_source, ETH_ALEN);
 751            rah->ar_sip = ah->ar_tip;
 752            memcpy(rah->ar_tha, ah->ar_sha, ETH_ALEN);
 753            rah->ar_tip = ah->ar_sip;
 754            slirp_output(slirp->opaque, arp_reply, sizeof(arp_reply));
 755        }
 756        break;
 757    case ARPOP_REPLY:
 758        arp_table_add(slirp, ah->ar_sip, ah->ar_sha);
 759        break;
 760    default:
 761        break;
 762    }
 763}
 764
 765void slirp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len)
 766{
 767    struct mbuf *m;
 768    int proto;
 769
 770    if (pkt_len < ETH_HLEN)
 771        return;
 772
 773    proto = ntohs(*(uint16_t *)(pkt + 12));
 774    switch(proto) {
 775    case ETH_P_ARP:
 776        arp_input(slirp, pkt, pkt_len);
 777        break;
 778    case ETH_P_IP:
 779    case ETH_P_IPV6:
 780        m = m_get(slirp);
 781        if (!m)
 782            return;
 783        /* Note: we add 2 to align the IP header on 4 bytes,
 784         * and add the margin for the tcpiphdr overhead  */
 785        if (M_FREEROOM(m) < pkt_len + TCPIPHDR_DELTA + 2) {
 786            m_inc(m, pkt_len + TCPIPHDR_DELTA + 2);
 787        }
 788        m->m_len = pkt_len + TCPIPHDR_DELTA + 2;
 789        memcpy(m->m_data + TCPIPHDR_DELTA + 2, pkt, pkt_len);
 790
 791        m->m_data += TCPIPHDR_DELTA + 2 + ETH_HLEN;
 792        m->m_len -= TCPIPHDR_DELTA + 2 + ETH_HLEN;
 793
 794        if (proto == ETH_P_IP) {
 795            ip_input(m);
 796        } else if (proto == ETH_P_IPV6) {
 797            ip6_input(m);
 798        }
 799        break;
 800
 801    default:
 802        break;
 803    }
 804}
 805
 806/* Prepare the IPv4 packet to be sent to the ethernet device. Returns 1 if no
 807 * packet should be sent, 0 if the packet must be re-queued, 2 if the packet
 808 * is ready to go.
 809 */
 810static int if_encap4(Slirp *slirp, struct mbuf *ifm, struct ethhdr *eh,
 811        uint8_t ethaddr[ETH_ALEN])
 812{
 813    const struct ip *iph = (const struct ip *)ifm->m_data;
 814
 815    if (iph->ip_dst.s_addr == 0) {
 816        /* 0.0.0.0 can not be a destination address, something went wrong,
 817         * avoid making it worse */
 818        return 1;
 819    }
 820    if (!arp_table_search(slirp, iph->ip_dst.s_addr, ethaddr)) {
 821        uint8_t arp_req[ETH_HLEN + sizeof(struct arphdr)];
 822        struct ethhdr *reh = (struct ethhdr *)arp_req;
 823        struct arphdr *rah = (struct arphdr *)(arp_req + ETH_HLEN);
 824
 825        if (!ifm->resolution_requested) {
 826            /* If the client addr is not known, send an ARP request */
 827            memset(reh->h_dest, 0xff, ETH_ALEN);
 828            memcpy(reh->h_source, special_ethaddr, ETH_ALEN - 4);
 829            memcpy(&reh->h_source[2], &slirp->vhost_addr, 4);
 830            reh->h_proto = htons(ETH_P_ARP);
 831            rah->ar_hrd = htons(1);
 832            rah->ar_pro = htons(ETH_P_IP);
 833            rah->ar_hln = ETH_ALEN;
 834            rah->ar_pln = 4;
 835            rah->ar_op = htons(ARPOP_REQUEST);
 836
 837            /* source hw addr */
 838            memcpy(rah->ar_sha, special_ethaddr, ETH_ALEN - 4);
 839            memcpy(&rah->ar_sha[2], &slirp->vhost_addr, 4);
 840
 841            /* source IP */
 842            rah->ar_sip = slirp->vhost_addr.s_addr;
 843
 844            /* target hw addr (none) */
 845            memset(rah->ar_tha, 0, ETH_ALEN);
 846
 847            /* target IP */
 848            rah->ar_tip = iph->ip_dst.s_addr;
 849            slirp->client_ipaddr = iph->ip_dst;
 850            slirp_output(slirp->opaque, arp_req, sizeof(arp_req));
 851            ifm->resolution_requested = true;
 852
 853            /* Expire request and drop outgoing packet after 1 second */
 854            ifm->expiration_date = qemu_clock_get_ns(QEMU_CLOCK_REALTIME) + 1000000000ULL;
 855        }
 856        return 0;
 857    } else {
 858        memcpy(eh->h_source, special_ethaddr, ETH_ALEN - 4);
 859        /* XXX: not correct */
 860        memcpy(&eh->h_source[2], &slirp->vhost_addr, 4);
 861        eh->h_proto = htons(ETH_P_IP);
 862
 863        /* Send this */
 864        return 2;
 865    }
 866}
 867
 868/* Prepare the IPv6 packet to be sent to the ethernet device. Returns 1 if no
 869 * packet should be sent, 0 if the packet must be re-queued, 2 if the packet
 870 * is ready to go.
 871 */
 872static int if_encap6(Slirp *slirp, struct mbuf *ifm, struct ethhdr *eh,
 873        uint8_t ethaddr[ETH_ALEN])
 874{
 875    const struct ip6 *ip6h = mtod(ifm, const struct ip6 *);
 876    if (!ndp_table_search(slirp, ip6h->ip_dst, ethaddr)) {
 877        if (!ifm->resolution_requested) {
 878            ndp_send_ns(slirp, ip6h->ip_dst);
 879            ifm->resolution_requested = true;
 880            ifm->expiration_date =
 881                qemu_clock_get_ns(QEMU_CLOCK_REALTIME) + 1000000000ULL;
 882        }
 883        return 0;
 884    } else {
 885        eh->h_proto = htons(ETH_P_IPV6);
 886        in6_compute_ethaddr(ip6h->ip_src, eh->h_source);
 887
 888        /* Send this */
 889        return 2;
 890    }
 891}
 892
 893/* Output the IP packet to the ethernet device. Returns 0 if the packet must be
 894 * re-queued.
 895 */
 896int if_encap(Slirp *slirp, struct mbuf *ifm)
 897{
 898    uint8_t buf[1600];
 899    struct ethhdr *eh = (struct ethhdr *)buf;
 900    uint8_t ethaddr[ETH_ALEN];
 901    const struct ip *iph = (const struct ip *)ifm->m_data;
 902    int ret;
 903
 904    if (ifm->m_len + ETH_HLEN > sizeof(buf)) {
 905        return 1;
 906    }
 907
 908    switch (iph->ip_v) {
 909    case IPVERSION:
 910        ret = if_encap4(slirp, ifm, eh, ethaddr);
 911        if (ret < 2) {
 912            return ret;
 913        }
 914        break;
 915
 916    case IP6VERSION:
 917        ret = if_encap6(slirp, ifm, eh, ethaddr);
 918        if (ret < 2) {
 919            return ret;
 920        }
 921        break;
 922
 923    default:
 924        g_assert_not_reached();
 925        break;
 926    }
 927
 928    memcpy(eh->h_dest, ethaddr, ETH_ALEN);
 929    DEBUG_ARGS((dfd, " src = %02x:%02x:%02x:%02x:%02x:%02x\n",
 930                eh->h_source[0], eh->h_source[1], eh->h_source[2],
 931                eh->h_source[3], eh->h_source[4], eh->h_source[5]));
 932    DEBUG_ARGS((dfd, " dst = %02x:%02x:%02x:%02x:%02x:%02x\n",
 933                eh->h_dest[0], eh->h_dest[1], eh->h_dest[2],
 934                eh->h_dest[3], eh->h_dest[4], eh->h_dest[5]));
 935    memcpy(buf + sizeof(struct ethhdr), ifm->m_data, ifm->m_len);
 936    slirp_output(slirp->opaque, buf, ifm->m_len + ETH_HLEN);
 937    return 1;
 938}
 939
 940/* Drop host forwarding rule, return 0 if found. */
 941int slirp_remove_hostfwd(Slirp *slirp, int is_udp, struct in_addr host_addr,
 942                         int host_port)
 943{
 944    struct socket *so;
 945    struct socket *head = (is_udp ? &slirp->udb : &slirp->tcb);
 946    struct sockaddr_in addr;
 947    int port = htons(host_port);
 948    socklen_t addr_len;
 949
 950    for (so = head->so_next; so != head; so = so->so_next) {
 951        addr_len = sizeof(addr);
 952        if ((so->so_state & SS_HOSTFWD) &&
 953            getsockname(so->s, (struct sockaddr *)&addr, &addr_len) == 0 &&
 954            addr.sin_addr.s_addr == host_addr.s_addr &&
 955            addr.sin_port == port) {
 956            close(so->s);
 957            sofree(so);
 958            return 0;
 959        }
 960    }
 961
 962    return -1;
 963}
 964
 965int slirp_add_hostfwd(Slirp *slirp, int is_udp, struct in_addr host_addr,
 966                      int host_port, struct in_addr guest_addr, int guest_port)
 967{
 968    if (!guest_addr.s_addr) {
 969        guest_addr = slirp->vdhcp_startaddr;
 970    }
 971    if (is_udp) {
 972        if (!udp_listen(slirp, host_addr.s_addr, htons(host_port),
 973                        guest_addr.s_addr, htons(guest_port), SS_HOSTFWD))
 974            return -1;
 975    } else {
 976        if (!tcp_listen(slirp, host_addr.s_addr, htons(host_port),
 977                        guest_addr.s_addr, htons(guest_port), SS_HOSTFWD))
 978            return -1;
 979    }
 980    return 0;
 981}
 982
 983int slirp_add_exec(Slirp *slirp, int do_pty, const void *args,
 984                   struct in_addr *guest_addr, int guest_port)
 985{
 986    if (!guest_addr->s_addr) {
 987        guest_addr->s_addr = slirp->vnetwork_addr.s_addr |
 988            (htonl(0x0204) & ~slirp->vnetwork_mask.s_addr);
 989    }
 990    if ((guest_addr->s_addr & slirp->vnetwork_mask.s_addr) !=
 991        slirp->vnetwork_addr.s_addr ||
 992        guest_addr->s_addr == slirp->vhost_addr.s_addr ||
 993        guest_addr->s_addr == slirp->vnameserver_addr.s_addr) {
 994        return -1;
 995    }
 996    return add_exec(&slirp->exec_list, do_pty, (char *)args, *guest_addr,
 997                    htons(guest_port));
 998}
 999
1000ssize_t slirp_send(struct socket *so, const void *buf, size_t len, int flags)
1001{
1002    if (so->s == -1 && so->extra) {
1003        qemu_chr_fe_write(so->extra, buf, len);
1004        return len;
1005    }
1006
1007    return send(so->s, buf, len, flags);
1008}
1009
1010static struct socket *
1011slirp_find_ctl_socket(Slirp *slirp, struct in_addr guest_addr, int guest_port)
1012{
1013    struct socket *so;
1014
1015    for (so = slirp->tcb.so_next; so != &slirp->tcb; so = so->so_next) {
1016        if (so->so_faddr.s_addr == guest_addr.s_addr &&
1017            htons(so->so_fport) == guest_port) {
1018            return so;
1019        }
1020    }
1021    return NULL;
1022}
1023
1024size_t slirp_socket_can_recv(Slirp *slirp, struct in_addr guest_addr,
1025                             int guest_port)
1026{
1027    struct iovec iov[2];
1028    struct socket *so;
1029
1030    so = slirp_find_ctl_socket(slirp, guest_addr, guest_port);
1031
1032    if (!so || so->so_state & SS_NOFDREF) {
1033        return 0;
1034    }
1035
1036    if (!CONN_CANFRCV(so) || so->so_snd.sb_cc >= (so->so_snd.sb_datalen/2)) {
1037        return 0;
1038    }
1039
1040    return sopreprbuf(so, iov, NULL);
1041}
1042
1043void slirp_socket_recv(Slirp *slirp, struct in_addr guest_addr, int guest_port,
1044                       const uint8_t *buf, int size)
1045{
1046    int ret;
1047    struct socket *so = slirp_find_ctl_socket(slirp, guest_addr, guest_port);
1048
1049    if (!so)
1050        return;
1051
1052    ret = soreadbuf(so, (const char *)buf, size);
1053
1054    if (ret > 0)
1055        tcp_output(sototcpcb(so));
1056}
1057
1058static void slirp_tcp_save(QEMUFile *f, struct tcpcb *tp)
1059{
1060    int i;
1061
1062    qemu_put_sbe16(f, tp->t_state);
1063    for (i = 0; i < TCPT_NTIMERS; i++)
1064        qemu_put_sbe16(f, tp->t_timer[i]);
1065    qemu_put_sbe16(f, tp->t_rxtshift);
1066    qemu_put_sbe16(f, tp->t_rxtcur);
1067    qemu_put_sbe16(f, tp->t_dupacks);
1068    qemu_put_be16(f, tp->t_maxseg);
1069    qemu_put_sbyte(f, tp->t_force);
1070    qemu_put_be16(f, tp->t_flags);
1071    qemu_put_be32(f, tp->snd_una);
1072    qemu_put_be32(f, tp->snd_nxt);
1073    qemu_put_be32(f, tp->snd_up);
1074    qemu_put_be32(f, tp->snd_wl1);
1075    qemu_put_be32(f, tp->snd_wl2);
1076    qemu_put_be32(f, tp->iss);
1077    qemu_put_be32(f, tp->snd_wnd);
1078    qemu_put_be32(f, tp->rcv_wnd);
1079    qemu_put_be32(f, tp->rcv_nxt);
1080    qemu_put_be32(f, tp->rcv_up);
1081    qemu_put_be32(f, tp->irs);
1082    qemu_put_be32(f, tp->rcv_adv);
1083    qemu_put_be32(f, tp->snd_max);
1084    qemu_put_be32(f, tp->snd_cwnd);
1085    qemu_put_be32(f, tp->snd_ssthresh);
1086    qemu_put_sbe16(f, tp->t_idle);
1087    qemu_put_sbe16(f, tp->t_rtt);
1088    qemu_put_be32(f, tp->t_rtseq);
1089    qemu_put_sbe16(f, tp->t_srtt);
1090    qemu_put_sbe16(f, tp->t_rttvar);
1091    qemu_put_be16(f, tp->t_rttmin);
1092    qemu_put_be32(f, tp->max_sndwnd);
1093    qemu_put_byte(f, tp->t_oobflags);
1094    qemu_put_byte(f, tp->t_iobc);
1095    qemu_put_sbe16(f, tp->t_softerror);
1096    qemu_put_byte(f, tp->snd_scale);
1097    qemu_put_byte(f, tp->rcv_scale);
1098    qemu_put_byte(f, tp->request_r_scale);
1099    qemu_put_byte(f, tp->requested_s_scale);
1100    qemu_put_be32(f, tp->ts_recent);
1101    qemu_put_be32(f, tp->ts_recent_age);
1102    qemu_put_be32(f, tp->last_ack_sent);
1103}
1104
1105static void slirp_sbuf_save(QEMUFile *f, struct sbuf *sbuf)
1106{
1107    uint32_t off;
1108
1109    qemu_put_be32(f, sbuf->sb_cc);
1110    qemu_put_be32(f, sbuf->sb_datalen);
1111    off = (uint32_t)(sbuf->sb_wptr - sbuf->sb_data);
1112    qemu_put_sbe32(f, off);
1113    off = (uint32_t)(sbuf->sb_rptr - sbuf->sb_data);
1114    qemu_put_sbe32(f, off);
1115    qemu_put_buffer(f, (unsigned char*)sbuf->sb_data, sbuf->sb_datalen);
1116}
1117
1118static void slirp_socket_save(QEMUFile *f, struct socket *so)
1119{
1120    qemu_put_be32(f, so->so_urgc);
1121    qemu_put_be16(f, so->so_ffamily);
1122    switch (so->so_ffamily) {
1123    case AF_INET:
1124        qemu_put_be32(f, so->so_faddr.s_addr);
1125        qemu_put_be16(f, so->so_fport);
1126        break;
1127    default:
1128        error_report(
1129                "so_ffamily unknown, unable to save so_faddr and so_fport\n");
1130    }
1131    qemu_put_be16(f, so->so_lfamily);
1132    switch (so->so_lfamily) {
1133    case AF_INET:
1134        qemu_put_be32(f, so->so_laddr.s_addr);
1135        qemu_put_be16(f, so->so_lport);
1136        break;
1137    default:
1138        error_report(
1139                "so_ffamily unknown, unable to save so_laddr and so_lport\n");
1140    }
1141    qemu_put_byte(f, so->so_iptos);
1142    qemu_put_byte(f, so->so_emu);
1143    qemu_put_byte(f, so->so_type);
1144    qemu_put_be32(f, so->so_state);
1145    slirp_sbuf_save(f, &so->so_rcv);
1146    slirp_sbuf_save(f, &so->so_snd);
1147    slirp_tcp_save(f, so->so_tcpcb);
1148}
1149
1150static void slirp_bootp_save(QEMUFile *f, Slirp *slirp)
1151{
1152    int i;
1153
1154    for (i = 0; i < NB_BOOTP_CLIENTS; i++) {
1155        qemu_put_be16(f, slirp->bootp_clients[i].allocated);
1156        qemu_put_buffer(f, slirp->bootp_clients[i].macaddr, 6);
1157    }
1158}
1159
1160static void slirp_state_save(QEMUFile *f, void *opaque)
1161{
1162    Slirp *slirp = opaque;
1163    struct ex_list *ex_ptr;
1164
1165    for (ex_ptr = slirp->exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next)
1166        if (ex_ptr->ex_pty == 3) {
1167            struct socket *so;
1168            so = slirp_find_ctl_socket(slirp, ex_ptr->ex_addr,
1169                                       ntohs(ex_ptr->ex_fport));
1170            if (!so)
1171                continue;
1172
1173            qemu_put_byte(f, 42);
1174            slirp_socket_save(f, so);
1175        }
1176    qemu_put_byte(f, 0);
1177
1178    qemu_put_be16(f, slirp->ip_id);
1179
1180    slirp_bootp_save(f, slirp);
1181}
1182
1183static void slirp_tcp_load(QEMUFile *f, struct tcpcb *tp)
1184{
1185    int i;
1186
1187    tp->t_state = qemu_get_sbe16(f);
1188    for (i = 0; i < TCPT_NTIMERS; i++)
1189        tp->t_timer[i] = qemu_get_sbe16(f);
1190    tp->t_rxtshift = qemu_get_sbe16(f);
1191    tp->t_rxtcur = qemu_get_sbe16(f);
1192    tp->t_dupacks = qemu_get_sbe16(f);
1193    tp->t_maxseg = qemu_get_be16(f);
1194    tp->t_force = qemu_get_sbyte(f);
1195    tp->t_flags = qemu_get_be16(f);
1196    tp->snd_una = qemu_get_be32(f);
1197    tp->snd_nxt = qemu_get_be32(f);
1198    tp->snd_up = qemu_get_be32(f);
1199    tp->snd_wl1 = qemu_get_be32(f);
1200    tp->snd_wl2 = qemu_get_be32(f);
1201    tp->iss = qemu_get_be32(f);
1202    tp->snd_wnd = qemu_get_be32(f);
1203    tp->rcv_wnd = qemu_get_be32(f);
1204    tp->rcv_nxt = qemu_get_be32(f);
1205    tp->rcv_up = qemu_get_be32(f);
1206    tp->irs = qemu_get_be32(f);
1207    tp->rcv_adv = qemu_get_be32(f);
1208    tp->snd_max = qemu_get_be32(f);
1209    tp->snd_cwnd = qemu_get_be32(f);
1210    tp->snd_ssthresh = qemu_get_be32(f);
1211    tp->t_idle = qemu_get_sbe16(f);
1212    tp->t_rtt = qemu_get_sbe16(f);
1213    tp->t_rtseq = qemu_get_be32(f);
1214    tp->t_srtt = qemu_get_sbe16(f);
1215    tp->t_rttvar = qemu_get_sbe16(f);
1216    tp->t_rttmin = qemu_get_be16(f);
1217    tp->max_sndwnd = qemu_get_be32(f);
1218    tp->t_oobflags = qemu_get_byte(f);
1219    tp->t_iobc = qemu_get_byte(f);
1220    tp->t_softerror = qemu_get_sbe16(f);
1221    tp->snd_scale = qemu_get_byte(f);
1222    tp->rcv_scale = qemu_get_byte(f);
1223    tp->request_r_scale = qemu_get_byte(f);
1224    tp->requested_s_scale = qemu_get_byte(f);
1225    tp->ts_recent = qemu_get_be32(f);
1226    tp->ts_recent_age = qemu_get_be32(f);
1227    tp->last_ack_sent = qemu_get_be32(f);
1228    tcp_template(tp);
1229}
1230
1231static int slirp_sbuf_load(QEMUFile *f, struct sbuf *sbuf)
1232{
1233    uint32_t off, sb_cc, sb_datalen;
1234
1235    sb_cc = qemu_get_be32(f);
1236    sb_datalen = qemu_get_be32(f);
1237
1238    sbreserve(sbuf, sb_datalen);
1239
1240    if (sbuf->sb_datalen != sb_datalen)
1241        return -ENOMEM;
1242
1243    sbuf->sb_cc = sb_cc;
1244
1245    off = qemu_get_sbe32(f);
1246    sbuf->sb_wptr = sbuf->sb_data + off;
1247    off = qemu_get_sbe32(f);
1248    sbuf->sb_rptr = sbuf->sb_data + off;
1249    qemu_get_buffer(f, (unsigned char*)sbuf->sb_data, sbuf->sb_datalen);
1250
1251    return 0;
1252}
1253
1254static int slirp_socket_load(QEMUFile *f, struct socket *so, int version_id)
1255{
1256    if (tcp_attach(so) < 0)
1257        return -ENOMEM;
1258
1259    so->so_urgc = qemu_get_be32(f);
1260    if (version_id <= 3) {
1261        so->so_ffamily = AF_INET;
1262        so->so_faddr.s_addr = qemu_get_be32(f);
1263        so->so_laddr.s_addr = qemu_get_be32(f);
1264        so->so_fport = qemu_get_be16(f);
1265        so->so_lport = qemu_get_be16(f);
1266    } else {
1267        so->so_ffamily = qemu_get_be16(f);
1268        switch (so->so_ffamily) {
1269        case AF_INET:
1270            so->so_faddr.s_addr = qemu_get_be32(f);
1271            so->so_fport = qemu_get_be16(f);
1272            break;
1273        default:
1274            error_report(
1275                "so_ffamily unknown, unable to restore so_faddr and so_lport");
1276        }
1277        so->so_lfamily = qemu_get_be16(f);
1278        switch (so->so_lfamily) {
1279        case AF_INET:
1280            so->so_laddr.s_addr = qemu_get_be32(f);
1281            so->so_lport = qemu_get_be16(f);
1282            break;
1283        default:
1284            error_report(
1285                "so_ffamily unknown, unable to restore so_laddr and so_lport");
1286        }
1287    }
1288    so->so_iptos = qemu_get_byte(f);
1289    so->so_emu = qemu_get_byte(f);
1290    so->so_type = qemu_get_byte(f);
1291    so->so_state = qemu_get_be32(f);
1292    if (slirp_sbuf_load(f, &so->so_rcv) < 0)
1293        return -ENOMEM;
1294    if (slirp_sbuf_load(f, &so->so_snd) < 0)
1295        return -ENOMEM;
1296    slirp_tcp_load(f, so->so_tcpcb);
1297
1298    return 0;
1299}
1300
1301static void slirp_bootp_load(QEMUFile *f, Slirp *slirp)
1302{
1303    int i;
1304
1305    for (i = 0; i < NB_BOOTP_CLIENTS; i++) {
1306        slirp->bootp_clients[i].allocated = qemu_get_be16(f);
1307        qemu_get_buffer(f, slirp->bootp_clients[i].macaddr, 6);
1308    }
1309}
1310
1311static int slirp_state_load(QEMUFile *f, void *opaque, int version_id)
1312{
1313    Slirp *slirp = opaque;
1314    struct ex_list *ex_ptr;
1315
1316    while (qemu_get_byte(f)) {
1317        int ret;
1318        struct socket *so = socreate(slirp);
1319
1320        if (!so)
1321            return -ENOMEM;
1322
1323        ret = slirp_socket_load(f, so, version_id);
1324
1325        if (ret < 0)
1326            return ret;
1327
1328        if ((so->so_faddr.s_addr & slirp->vnetwork_mask.s_addr) !=
1329            slirp->vnetwork_addr.s_addr) {
1330            return -EINVAL;
1331        }
1332        for (ex_ptr = slirp->exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
1333            if (ex_ptr->ex_pty == 3 &&
1334                so->so_faddr.s_addr == ex_ptr->ex_addr.s_addr &&
1335                so->so_fport == ex_ptr->ex_fport) {
1336                break;
1337            }
1338        }
1339        if (!ex_ptr)
1340            return -EINVAL;
1341
1342        so->extra = (void *)ex_ptr->ex_exec;
1343    }
1344
1345    if (version_id >= 2) {
1346        slirp->ip_id = qemu_get_be16(f);
1347    }
1348
1349    if (version_id >= 3) {
1350        slirp_bootp_load(f, slirp);
1351    }
1352
1353    return 0;
1354}
1355