VirtualBox

Changeset 25276 in vbox


Ignore:
Timestamp:
Dec 9, 2009 4:23:51 PM (15 years ago)
Author:
vboxsync
Message:

NAT: force re-activation of port forwarding on link down; coding style; added some log statements

Location:
trunk/src/VBox/Devices/Network/slirp
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Network/slirp/bootp.c

    r25265 r25276  
    4040/* XXX: only DHCP is supported */
    4141static const uint8_t rfc1533_cookie[] = { RFC1533_COOKIE };
    42 static void bootp_reply(PNATState pData, struct mbuf *m0, int off, uint16_t flags);
     42
     43static void bootp_reply(PNATState pData, struct mbuf *m0, int offReply, uint16_t flags);
    4344
    4445static uint8_t *dhcp_find_option(uint8_t *vend, uint8_t tag)
     
    6061    return NULL;
    6162}
     63
    6264static BOOTPClient *bc_alloc_client(PNATState pData)
    6365{
     
    7880    return NULL;
    7981}
     82
    8083static BOOTPClient *get_new_addr(PNATState pData, struct in_addr *paddr)
    8184{
    8285    BOOTPClient *bc;
    8386    bc = bc_alloc_client(pData);
    84     if (bc == NULL)
     87    if (!bc)
    8588        return NULL;
     89
    8690    paddr->s_addr = htonl(ntohl(pData->special_addr.s_addr) | (bc->number + START_ADDR));
    8791    bc->addr.s_addr = paddr->s_addr;
     
    97101        {
    98102            memset(&bootp_clients[i], 0, sizeof(BOOTPClient));
    99             return 1;
    100         }
    101     }
    102     return 0;
     103            return VINF_SUCCESS;
     104        }
     105    }
     106    return VERR_NOT_FOUND;
    103107}
    104108
     
    205209}
    206210
    207 static int dhcp_do_ack_offer(PNATState pData, struct mbuf *m, BOOTPClient *bc, int is_from_request)
    208 {
    209     int off = 0;
     211static int dhcp_do_ack_offer(PNATState pData, struct mbuf *m, BOOTPClient *bc, int fDhcpRequest)
     212{
    210213    struct bootp_t *rbp = NULL;
    211214    uint8_t *q;
     
    236239    rbp->bp_siaddr = pData->tftp_server; /* Next Server IP address, i.e. TFTP */
    237240    Log(("NAT: DHCP: bp_siaddr:%R[IP4]\n", &rbp->bp_siaddr));
    238     if (is_from_request)
     241    if (fDhcpRequest)
    239242    {
    240243        rbp->bp_ciaddr.s_addr = bc->addr.s_addr; /* Client IP address */
     
    331334
    332335    dhcp_create_msg(pData, bp, m, DHCPNAK);
    333 
    334336    return 7;
    335337}
    336 static int dhcp_send_ack(PNATState pData, struct bootp_t *bp, BOOTPClient *bc, struct mbuf *m, int is_from_request)
     338
     339static int dhcp_send_ack(PNATState pData, struct bootp_t *bp, BOOTPClient *bc, struct mbuf *m, int fDhcpRequest)
    337340{
    338341    struct bootp_t *rbp;
    339     int off = 0; /* boot_reply will fill general options and add END before sending response*/
     342    int offReply = 0; /* boot_reply will fill general options and add END before sending response */
    340343
    341344    dhcp_create_msg(pData, bp, m, DHCPACK);
    342     off = dhcp_do_ack_offer(pData, m, bc, is_from_request);
    343     return off;
    344 }
     345    offReply = dhcp_do_ack_offer(pData, m, bc, fDhcpRequest);
     346    return offReply;
     347}
     348
    345349static int dhcp_send_offer(PNATState pData, struct bootp_t *bp, BOOTPClient *bc, struct mbuf *m)
    346350{
    347     int off = 0; /* boot_reply will fill general options and add END before sending response*/
     351    int offReply = 0; /* boot_reply will fill general options and add END before sending response */
    348352
    349353    dhcp_create_msg(pData, bp, m, DHCPOFFER);
    350     off = dhcp_do_ack_offer(pData, m, bc, 0);
    351     return off;
     354    offReply = dhcp_do_ack_offer(pData, m, bc, /* fDhcpRequest=*/ 0);
     355    return offReply;
    352356}
    353357
     
    364368 *
    365369 */
    366 enum DHCP_REQUEST_STATES{INIT_REBOOT, SELECTING, RENEWING, REBINDING, NONE};
     370
     371enum DHCP_REQUEST_STATES
     372{
     373    INIT_REBOOT,
     374    SELECTING,
     375    RENEWING,
     376    REBINDING,
     377    NONE
     378};
     379
    367380static int dhcp_decode_request(PNATState pData, struct bootp_t *bp, const uint8_t *buf, int size, struct mbuf *m)
    368381{
    369382    BOOTPClient *bc = NULL;
    370383    struct in_addr daddr;
    371     int off;
     384    int offReply;
    372385    uint8_t *opt;
    373386    uint8_t *req_ip = NULL;
     
    375388    uint32_t ui32;
    376389    enum DHCP_REQUEST_STATES dhcp_stat = NONE;
    377     /*need to understand which type of request we get */
     390
     391    /* need to understand which type of request we get */
    378392    req_ip = dhcp_find_option(&bp->bp_vend[0], RFC2132_REQ_ADDR);
    379393    server_ip = dhcp_find_option(&bp->bp_vend[0], RFC2132_SRV_ID);
     
    382396    if (server_ip != NULL)
    383397    {
    384         /*selecting*/
     398        /* selecting */
    385399        if (!bc)
    386400        {
    387              LogRel(("NAT: DHCP no IP wasn't allocated\n"));
     401             LogRel(("NAT: DHCP no IP was allocated\n"));
    388402             return -1;
    389403        }
     404
    390405        dhcp_stat = SELECTING;
    391406        Assert((bp->bp_ciaddr.s_addr == INADDR_ANY));
     
    412427        }
    413428    }
    414         /*?? renewing ??*/
     429
     430    /*?? renewing ??*/
    415431    switch (dhcp_stat)
    416432    {
    417433        case RENEWING:
    418         {
    419             Assert((   server_ip == NULL
    420                 && req_ip == NULL
    421                 && bp->bp_ciaddr.s_addr != INADDR_ANY));
     434            Assert((server_ip == NULL && req_ip == NULL && bp->bp_ciaddr.s_addr != INADDR_ANY));
    422435            if (bc != NULL)
    423436            {
     
    429442               if ((bp->bp_ciaddr.s_addr & htonl(pData->netmask)) != pData->special_addr.s_addr)
    430443               {
    431                     off = dhcp_send_nack(pData, bp, bc, m);
    432                     return off;
     444                   LogRel(("NAT: Client %R[IP4] requested IP -- sending NAK\n", &bp->bp_ciaddr));
     445                   offReply = dhcp_send_nack(pData, bp, bc, m);
     446                   return offReply;
    433447               }
     448
    434449               bc = bc_alloc_client(pData);
    435                if (bc == NULL)
     450               if (!bc)
    436451               {
    437                    LogRel(("NAT: can't alloc address. RENEW has been silently ignored\n"));
     452                   LogRel(("NAT: can't alloc address. RENEW has been silently ignored.\n"));
    438453                   return -1;
    439454               }
     455
    440456               Assert((bp->bp_hlen == ETH_ALEN));
    441457               memcpy(bc->macaddr, bp->bp_hwaddr, bp->bp_hlen);
     
    443459               slirp_arp_cache_update(pData, bp->bp_ciaddr.s_addr, bp->bp_hwaddr);
    444460            }
    445         }
    446         break;
     461            break;
     462
    447463        case INIT_REBOOT:
    448464            Assert(server_ip == NULL);
     
    451467            if ((ui32 & htonl(pData->netmask)) != pData->special_addr.s_addr)
    452468            {
    453                 LogRel(("NAT: address %R[IP4] has been req.\n", &ui32));
    454                  off = dhcp_send_nack(pData, bp, bc, m);
    455                  return off;
     469                LogRel(("NAT: address %R[IP4] has been requested -- sending NAK\n", &ui32));
     470                offReply = dhcp_send_nack(pData, bp, bc, m);
     471                return offReply;
    456472            }
     473
    457474            bc = bc_alloc_client(pData);
    458             if (bc == NULL)
     475            if (!bc)
    459476            {
    460477                LogRel(("NAT: can't alloc address. RENEW has been silently ignored\n"));
     
    465482            bc->addr.s_addr = ui32;
    466483            slirp_arp_cache_update(pData, bp->bp_ciaddr.s_addr, bp->bp_hwaddr);
    467         break;
     484            break;
     485
    468486        case NONE:
    469487            Assert((dhcp_stat != NONE));
    470488            return -1;
     489
    471490        default:
    472         break;
    473     }
    474     off = dhcp_send_ack(pData, bp, bc, m, 1);
    475     return off;
    476 }
    477 
    478 static int dhcp_decode_discover(PNATState pData, struct bootp_t *bp, const uint8_t *buf, int size, int flag, struct mbuf *m)
     491            break;
     492    }
     493
     494    LogRel(("NAT: DHCP offered IP address %R[IP4]\n", &bc->addr));
     495    offReply = dhcp_send_ack(pData, bp, bc, m, /* fDhcpRequest=*/ 1);
     496    return offReply;
     497}
     498
     499static int dhcp_decode_discover(PNATState pData, struct bootp_t *bp, const uint8_t *buf, int size, int fDhcpDiscover, struct mbuf *m)
    479500{
    480501    BOOTPClient *bc;
    481502    struct in_addr daddr;
    482     int off;
    483     /* flag == 1 discover */
    484     if (flag == 1)
     503    int offReply;
     504
     505    if (fDhcpDiscover)
    485506    {
    486507        bc = find_addr(pData, &daddr, bp->bp_hwaddr);
     
    496517            memcpy(bc->macaddr, bp->bp_hwaddr, 6);
    497518        }
     519
    498520        bc->xid = bp->bp_xid;
    499         /*bc isn't NULL */
    500         off = dhcp_send_offer(pData, bp, bc, m);
    501         return off;
     521        LogRel(("NAT: DHCP offered IP address %R[IP4]\n", &bc->addr));
     522        offReply = dhcp_send_offer(pData, bp, bc, m);
     523        return offReply;
    502524    }
    503525    else
    504526    {
    505         /* flag == 0 inform */
    506527        bc = find_addr(pData, &daddr, bp->bp_hwaddr);
    507         if (bc == NULL)
     528        if (!bc)
    508529        {
    509530            LogRel(("NAT: DHCP Inform was ignored no boot client was found\n"));
    510531            return -1;
    511532        }
    512         off = dhcp_send_ack(pData, bp, bc, m, 0);
    513         return off;
    514     }
     533
     534        LogRel(("NAT: DHCP offered IP address %R[IP4]\n", &bc->addr));
     535        offReply = dhcp_send_ack(pData, bp, bc, m, /* fDhcpRequest=*/ 0);
     536        return offReply;
     537    }
     538
    515539    return -1;
    516540}
     
    518542static int dhcp_decode_release(PNATState pData, struct bootp_t *bp, const uint8_t *buf, int size)
    519543{
    520     release_addr(pData, &bp->bp_ciaddr);
     544    int rc = release_addr(pData, &bp->bp_ciaddr);
     545    LogRel(("NAT: %s %R[IP4]\n",
     546            RT_SUCCESS(rc) ? "DHCP released IP address" : "Ignored DHCP release for IP address",
     547            &bp->bp_ciaddr));
    521548    return 0;
    522549}
     
    592619    int pmsg_type;
    593620    struct in_addr req_ip;
    594     int flag = 0;
     621    int fDhcpDiscover = 0;
    595622    int len, tag;
    596623    struct mbuf *m = NULL;
     
    619646        return;
    620647    }
     648
    621649    switch (*(p+2))
    622650    {
    623651        case DHCPDISCOVER:
    624             flag = 1;
     652            fDhcpDiscover = 1;
    625653            /**/
    626654        case DHCPINFORM:
    627             rc = dhcp_decode_discover(pData, bp, buf, size, flag, m);
     655            rc = dhcp_decode_discover(pData, bp, buf, size, fDhcpDiscover, m);
    628656            if (rc > 0)
    629657                goto reply;
     
    671699}
    672700
    673 static void bootp_reply(PNATState pData, struct mbuf *m, int off, uint16_t flags)
     701static void bootp_reply(PNATState pData, struct mbuf *m, int offReply, uint16_t flags)
    674702{
    675703    struct sockaddr_in saddr, daddr;
     
    682710    q = rbp->bp_vend;
    683711    nack = (q[6] == DHCPNAK);
    684     q += off;
     712    q += offReply;
    685713
    686714#ifndef VBOX_WITH_NAT_SERVICE
     
    692720    FILL_BOOTP_EXT(q, RFC2132_SRV_ID, 4, &saddr.sin_addr);
    693721
    694 
    695     *q++ = RFC1533_END; /*end of message */
    696 
     722    *q++ = RFC1533_END; /* end of message */
    697723
    698724#ifdef VBOX_WITH_SLIRP_BSD_MBUF
     
    725751    int i;
    726752
    727     if (ether == NULL || pip == NULL)
     753    if (!ether || !pip)
    728754        return VERR_INVALID_PARAMETER;
    729755
  • trunk/src/VBox/Devices/Network/slirp/ip_input.c

    r23369 r25276  
    233233    STAM_PROFILE_STOP(&pData->StatIP_input, a);
    234234    return;
     235
    235236bad:
    236237    Log2(("NAT: IP datagram to %R[IP4] with size(%d) claimed as bad\n",
  • trunk/src/VBox/Devices/Network/slirp/slirp.c

    r25266 r25276  
    194194#define LOG_NAT_SOCK(so, proto, winevent, r_fdset, w_fdset, x_fdset) DO_LOG_NAT_SOCK((so), proto, (winevent), r_fdset, w_fdset, x_fdset)
    195195
    196 static void activate_port_forwarding(PNATState, struct ethhdr *);
     196static void activate_port_forwarding(PNATState, uint8_t *pEther);
    197197
    198198static const uint8_t special_ethaddr[6] =
     
    662662{
    663663    struct socket *so;
     664    struct port_forward_rule *rule = NULL;
    664665
    665666    while ((so = tcb.so_next) != &tcb)
     
    673674    while ((so = udb.so_next) != &udb)
    674675        udp_detach(pData, so);
     676
     677    /*
     678     *  Clear the active state of port-forwarding rules to force
     679     *  re-setup on restoration of communications.
     680     */
     681    LIST_FOREACH(rule, &pData->port_forward_rule_head, list)
     682    {
     683        rule->activated = 0;
     684    }
     685    pData->cRedirectionsActive = 0;
    675686
    676687    link_up = 0;
     
    15161527                slirp_arp_cache_add(pData, *(uint32_t *)ah->ar_tip, &eh->h_dest[0]);
    15171528                /* good opportunity to activate port-forwarding on address (self)asignment*/
    1518                 if (pData->port_forwarding_activated != pData->port_forwarding_count)
    1519                     activate_port_forwarding(pData, eh);
     1529                if (pData->cRedirectionsActive != pData->cRedirectionsStored)
     1530                    activate_port_forwarding(pData, eh->h_source);
    15201531            }
    15211532            break;
     
    15291540            slirp_arp_cache_add(pData, *(uint32_t *)ah->ar_sip, ah->ar_sha);
    15301541            /* after/save restore we need up port forwarding again */
    1531             if (pData->port_forwarding_activated != pData->port_forwarding_count)
    1532                 activate_port_forwarding(pData, eh);
     1542            if (pData->cRedirectionsActive != pData->cRedirectionsStored)
     1543                activate_port_forwarding(pData, eh->h_source);
    15331544            m_free(pData, m);
    15341545            break;
     
    15541565    struct ethhdr *eh;
    15551566#endif
     1567    uint8_t au8Ether[ETH_ALEN];
    15561568
    15571569#ifndef VBOX_WITH_SLIRP_BSD_MBUF
     
    16071619    /* Note: we add to align the IP header */
    16081620
    1609     if (pData->port_forwarding_activated != pData->port_forwarding_count)
    1610         activate_port_forwarding(pData, mtod(m, struct ethhdr *));
     1621    memcpy(au8Ether, eh->h_source, ETH_ALEN);
    16111622
    16121623    switch(proto)
     
    16531664    }
    16541665
     1666    if (pData->cRedirectionsActive != pData->cRedirectionsStored)
     1667        activate_port_forwarding(pData, au8Ether);
     1668
    16551669#ifdef VBOX_WITH_SLIRP_BSD_MBUF
    16561670    RTMemFree((void *)pkt);
     
    17291743    uint32_t ip = INADDR_ANY;
    17301744    int rc;
    1731    
     1745
    17321746    if (eth_addr == NULL)
    17331747        return INADDR_ANY;
     
    17521766 * @todo finish this for service case
    17531767 */
    1754 static void activate_port_forwarding(PNATState pData, struct ethhdr *ethdr)
     1768static void activate_port_forwarding(PNATState pData, uint8_t *h_source)
    17551769{
    17561770    struct port_forward_rule *rule = NULL;
     
    17711785
    17721786        if (rule->activated)
    1773             continue; /*already activated */
     1787            continue;
     1788
    17741789#ifdef VBOX_WITH_NAT_SERVICE
    1775         if (memcmp(rule->mac_address, ethdr->h_source, ETH_ALEN) != 0)
     1790        if (memcmp(rule->mac_address, h_source, ETH_ALEN) != 0)
    17761791            continue; /*not right mac, @todo: it'd be better do the list port forwarding per mac */
    1777         guest_addr = find_guest_ip(pData, ethdr->h_source);
     1792        guest_addr = find_guest_ip(pData, h_source);
    17781793#else
    17791794#if 0
    1780         if (memcmp(client_ethaddr, ethdr->h_source, ETH_ALEN) != 0)
     1795        if (memcmp(client_ethaddr, h_source, ETH_ALEN) != 0)
    17811796            continue;
    17821797#endif
    1783         guest_addr = find_guest_ip(pData, ethdr->h_source);
     1798        guest_addr = find_guest_ip(pData, h_source);
    17841799#endif
    17851800        if (guest_addr == INADDR_ANY)
     
    17881803            return;
    17891804        }
     1805
    17901806#if !defined(VBOX_WITH_NAT_SERVICE)
    17911807        if (rule->guest_addr.s_addr != guest_addr)
     
    17931809#endif
    17941810
    1795         LogRel(("NAT: set redirect %s hp:%d gp:%d\n", (rule->proto == IPPROTO_UDP?"UDP":"TCP"),
    1796             rule->host_port, rule->guest_port));
     1811        LogRel(("NAT: set redirect %s host port %d => guest port %d @ %R[IP4]\n",
     1812               (rule->proto == IPPROTO_UDP?"UDP":"TCP"),
     1813               rule->host_port, rule->guest_port, &guest_addr));
    17971814
    17981815        if (rule->proto == IPPROTO_UDP)
    1799         {
    18001816            so = udp_listen(pData, rule->bind_ip.s_addr, htons(rule->host_port), guest_addr,
    18011817                            htons(rule->guest_port), 0);
    1802             pData->port_forwarding_activated++;
    1803         }
    18041818        else
    1805         {
    18061819            so = solisten(pData, rule->bind_ip.s_addr, htons(rule->host_port), guest_addr,
    18071820                          htons(rule->guest_port), 0);
    1808             pData->port_forwarding_activated++;
    1809         }
    18101821
    18111822        if (so == NULL)
    1812         {
    1813             LogRel(("NAT: failed redirect %s hp:%d gp:%d\n", (rule->proto == IPPROTO_UDP?"UDP":"TCP"),
    1814                 rule->host_port, rule->guest_port));
    18151823            goto remove_port_forwarding;
    1816         }
    18171824
    18181825        psin = (struct sockaddr_in *)&sa;
     
    18241831        rc = getsockname(so->s, &sa, &socketlen);
    18251832        if (rc < 0 || sa.sa_family != AF_INET)
    1826         {
    1827             LogRel(("NAT: failed redirect %s hp:%d gp:%d\n", (rule->proto == IPPROTO_UDP?"UDP":"TCP"),
    1828                 rule->host_port, rule->guest_port));
    18291833            goto remove_port_forwarding;
    1830         }
    18311834
    18321835        psin = (struct sockaddr_in *)&sa;
     
    18441847                                    rule->proto);
    18451848        if (!link)
    1846         {
    1847             LogRel(("NAT: failed redirect %s hp:%d gp:%d\n", (rule->proto == IPPROTO_UDP?"UDP":"TCP"),
    1848                    rule->host_port, rule->guest_port));
    18491849            goto remove_port_forwarding;
    1850         }
    18511850
    18521851        so->so_la = lib;
    18531852        rule->activated = 1;
     1853        pData->cRedirectionsActive++;
    18541854        continue;
    18551855
    18561856    remove_port_forwarding:
     1857        LogRel(("NAT: failed to redirect %s %d => %d\n",
     1858                (rule->proto == IPPROTO_UDP?"UDP":"TCP"), rule->host_port, rule->guest_port));
    18571859        LIST_REMOVE(rule, list);
    1858         pData->port_forwarding_count--;
     1860        pData->cRedirectionsStored--;
    18591861        RTMemFree(rule);
    18601862    }
     
    18781880    struct port_forward_rule *rule = NULL;
    18791881    Assert(memcmp(ethaddr, zerro_ethaddr, ETH_ALEN) == 0);
     1882
    18801883    rule = RTMemAllocZ(sizeof(struct port_forward_rule));
    18811884    if (rule == NULL)
    18821885        return 1;
     1886
    18831887    rule->proto = (is_udp ? IPPROTO_UDP : IPPROTO_TCP);
    18841888    rule->host_port = host_port;
     
    18911895    /* @todo add mac address */
    18921896    LIST_INSERT_HEAD(&pData->port_forward_rule_head, rule, list);
    1893     pData->port_forwarding_count++;
     1897    pData->cRedirectionsStored++;
    18941898    return 0;
    18951899}
    18961900
    18971901int slirp_add_exec(PNATState pData, int do_pty, const char *args, int addr_low_byte,
    1898                   int guest_port)
     1902                   int guest_port)
    18991903{
    19001904    return add_exec(&exec_list, do_pty, (char *)args,
     
    19992003    }
    20002004    else
    2001     {
    20022005        LogRel(("NAT: Host Resolver conflicts with DNS proxy, the last one was forcely ignored\n"));
    2003     }
    20042006}
    20052007
     
    20132015        }                                                                           \
    20142016        else                                                                        \
    2015         {                                                                           \
    20162017            LogRel(("NAT: (" #name ":%d)\n", (val)));                               \
    2017         }                                                                           \
    20182018    } while (0)
    20192019
  • trunk/src/VBox/Devices/Network/slirp/slirp_state.h

    r25265 r25276  
    318318    LIST_HEAD(handler_chain, proto_handler) handler_chain;
    319319    struct port_forward_rule_list port_forward_rule_head;
    320     int port_forwarding_activated;
    321     int port_forwarding_count;
     320    int cRedirectionsActive;
     321    int cRedirectionsStored;
    322322    struct arp_cache_head arp_cache;
    323323    /*libalis modules' handlers*/
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette