VirtualBox

Changeset 22664 in vbox


Ignore:
Timestamp:
Sep 1, 2009 2:03:09 PM (15 years ago)
Author:
vboxsync
Message:

NAT: hide away dhcp internals, adds helper lookups functions

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

Legend:

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

    r22541 r22664  
    2424#include <slirp.h>
    2525
     26/** Entry in the table of known DHCP clients. */
     27typedef struct
     28{
     29    uint32_t xid;
     30    bool allocated;
     31    uint8_t macaddr[6];
     32    struct in_addr addr;
     33    int number;
     34} BOOTPClient;
     35/** Number of DHCP clients supported by NAT. */
     36#define NB_ADDR     16
     37
     38#define bootp_clients ((BOOTPClient *)pData->pbootp_clients)
     39
    2640/* XXX: only DHCP is supported */
    27 
    2841static const uint8_t rfc1533_cookie[] = { RFC1533_COOKIE };
    2942static void bootp_reply(PNATState pData, struct mbuf *m0, int off, uint16_t flags);
     
    683696    }
    684697}
     698
     699int bootp_cache_lookup_ip_by_ether(PNATState pData,const uint8_t* ether, uint32_t *pip)
     700{
     701    int rc = 1;
     702    uint32_t ip = INADDR_ANY;
     703    int i;
     704    if (ether == NULL || pip == NULL)
     705        goto done;
     706    for (i = 0; i < NB_ADDR; i++)
     707    {
     708        if (   bootp_clients[i].allocated
     709            && memcmp(bootp_clients[i].macaddr, ether, ETH_ALEN) == 0)
     710        {
     711            ip = bootp_clients[i].addr.s_addr;
     712            rc = 0;
     713            break;
     714        }
     715    }
     716done:
     717    *pip = ip;
     718    return rc;
     719}
     720
     721int bootp_cache_lookup_ether_by_ip(PNATState pData, uint32_t ip, uint8_t *ether)
     722{
     723    int rc = 1;
     724    int i;
     725    if (ether == NULL)
     726        goto done;
     727    for (i = 0; i < NB_ADDR; i++)
     728    {
     729        if (   bootp_clients[i].allocated
     730            && ip == bootp_clients[i].addr.s_addr)
     731        {
     732            memcpy(ether, bootp_clients[i].macaddr, ETH_ALEN);
     733            rc = 0;
     734            break;
     735        }
     736    }
     737done:
     738    return rc;
     739}
     740
     741/*
     742 * Initialize dhcp server
     743 * @returns 0 - if initialization is ok, non-zero otherwise
     744 */
     745int bootp_dhcp_init(PNATState pData)
     746{
     747    int rc = 1;
     748    pData->pbootp_clients = RTMemAllocZ(sizeof(BOOTPClient) * NB_ADDR);
     749    if (pData->pbootp_clients != NULL)
     750        rc = 0;
     751    return rc;
     752}
     753
     754int bootp_dhcp_fini(PNATState pData)
     755{
     756    if (pData->pbootp_clients != NULL)
     757        RTMemFree(pData->pbootp_clients);
     758}
  • trunk/src/VBox/Devices/Network/slirp/bootp.h

    r22500 r22664  
    115115};
    116116
    117 /** Entry in the table of known DHCP clients. */
    118 typedef struct
    119 {
    120     uint32_t xid;
    121     bool allocated;
    122     uint8_t macaddr[6];
    123     struct in_addr addr;
    124     int number;
    125 } BOOTPClient;
    126117
    127118#define DHCP_FLAGS_B (1<<15)
     
    133124
    134125void bootp_input(PNATState, struct mbuf *m);
     126int bootp_cache_lookup_ip_by_ether(PNATState, const uint8_t *, uint32_t *);
     127int bootp_cache_lookup_ether_by_ip(PNATState, uint32_t, uint8_t *);
     128int bootp_dhcp_init(PNATState);
     129int bootp_dhcp_fini(PNATState);
  • trunk/src/VBox/Devices/Network/slirp/ip_output.c

    r22500 r22664  
    4646#include "alias.h"
    4747
    48 static const uint8_t* rt_lookup_in_cache(PNATState pData, uint32_t dst)
     48static int rt_lookup_in_cache(PNATState pData, uint32_t dst, uint8_t *ether)
    4949{
    50     int i;
    51     struct arp_cache_entry *ac = NULL;
    52    /* @todo (vasily) to quick ramp up on routing rails
    53     * we use information from DHCP server leasings, this
    54     * code couldn't detect any changes in network topology
    55     * and should be borrowed from other places
    56     */
    57     LIST_FOREACH(ac, &pData->arp_cache, list)
    58     {
    59         if (ac->ip == dst)
    60             return &ac->ether[0];
    61     }
    62     for (i = 0; i < NB_ADDR; i++)
    63     {
    64         if (   bootp_clients[i].allocated
    65             && bootp_clients[i].addr.s_addr == dst)
    66             return &bootp_clients[i].macaddr[0];
    67     }
     50    int rc = 1;
     51    rc = slirp_arp_lookup_ether_by_ip(pData, dst, ether);
     52    if (rc == 0)
     53        return rc;
     54    rc = bootp_cache_lookup_ether_by_ip(pData, dst, ether);
     55    if (rc == 0)
     56        return rc;
    6857    /*
    6958     * no chance to send this packet, sorry, we will request ether address via ARP
    7059     */
    7160    slirp_arp_who_has(pData, dst);
    72     return NULL;
     61    return rc;
    7362}
    7463
     
    8877    extern uint8_t zerro_ethaddr[ETH_ALEN];
    8978    struct ethhdr *eh = NULL;
    90     const uint8_t *eth_dst = NULL;
     79    uint8_t eth_dst[ETH_ALEN];
     80    int rc = 1;
    9181
    9282    STAM_PROFILE_START(&pData->StatIP_output, a);
     
    134124     eh = (struct ethhdr *)MBUF_HEAD(m);
    135125     if (memcmp(eh->h_source, zerro_ethaddr, ETH_ALEN) == 0)
    136          eth_dst = rt_lookup_in_cache(pData, ip->ip_dst.s_addr);
     126     {
     127        rc = rt_lookup_in_cache(pData, ip->ip_dst.s_addr, eth_dst);
     128        if (rc != 0)
     129            goto bad;
     130     }
     131     else
     132    {
     133        memcpy(eth_dst, eh->h_source, ETH_ALEN);
     134        rc = 0; /*some times we've already know where to send packet*/
     135    }
    137136
    138137    /*
     
    145144        ip->ip_sum = 0;
    146145        ip->ip_sum = cksum(m, hlen);
    147         if (eth_dst != NULL)
    148             memcpy(eh->h_source, eth_dst, ETH_ALEN);
    149         {
    150             int rc;
    151             STAM_PROFILE_START(&pData->StatALIAS_output, a);
    152             rc = LibAliasOut((m->m_la ? m->m_la : pData->proxy_alias),
    153                 mtod(m, char *), m->m_len);
    154             Log2(("NAT: LibAlias return %d\n", rc));
    155             STAM_PROFILE_STOP(&pData->StatALIAS_output, a);
    156         }
     146   
     147        Assert((rc == 0));
     148        memcpy(eh->h_source, eth_dst, ETH_ALEN);
     149   
     150        STAM_PROFILE_START(&pData->StatALIAS_output, a);
     151        rc = LibAliasOut((m->m_la ? m->m_la : pData->proxy_alias),
     152            mtod(m, char *), m->m_len);
     153        Log2(("NAT: LibAlias return %d\n", rc));
     154        STAM_PROFILE_STOP(&pData->StatALIAS_output, a);
    157155
    158156        if_output(pData, so, m);
     
    203201            /* we've calculated eth_dst for first packet */
    204202            eh = (struct ethhdr *)MBUF_HEAD(m);
    205             if (eth_dst != NULL) {
    206                 memcpy(eh->h_source, eth_dst, ETH_ALEN);
    207             }
     203            Assert((rc == 0));
     204
     205            memcpy(eh->h_source, eth_dst, ETH_ALEN);
    208206
    209207#if 0 /* No options */
     
    247245        ip->ip_sum = 0;
    248246        ip->ip_sum = cksum(m, hlen);
    249         {
    250             int rc;
    251             STAM_PROFILE_START(&pData->StatALIAS_output, a);
    252             rc = LibAliasOut((m->m_la ? m->m_la : pData->proxy_alias),
    253                 mtod(m, char *), m->m_len);
    254             Log2(("NAT: LibAlias return %d\n", rc));
    255             STAM_PROFILE_STOP(&pData->StatALIAS_output, a);
    256         }
     247
     248        STAM_PROFILE_START(&pData->StatALIAS_output, a);
     249        rc = LibAliasOut((m->m_la ? m->m_la : pData->proxy_alias),
     250            mtod(m, char *), m->m_len);
     251        Log2(("NAT: LibAlias return %d\n", rc));
     252        STAM_PROFILE_STOP(&pData->StatALIAS_output, a);
    257253
    258254sendorfree:
  • trunk/src/VBox/Devices/Network/slirp/slirp.c

    r22597 r22664  
    190190
    191191static void activate_port_forwarding(PNATState, struct ethhdr *);
    192 static uint32_t find_guest_ip(PNATState, uint8_t *);
     192static uint32_t find_guest_ip(PNATState, const uint8_t *);
    193193
    194194static const uint8_t special_ethaddr[6] =
     
    515515    link_up = 1;
    516516
     517    bootp_dhcp_init(pData);
    517518    debug_init();
    518519    if_init(pData);
     
    649650        RTMemFree(ac);
    650651    }
     652    bootp_dhcp_fini(pData);
    651653#ifdef RT_OS_WINDOWS
    652654    WSACleanup();
     
    15321534 * @todo  see rt_lookup_in_cache
    15331535 */
    1534 static uint32_t find_guest_ip(PNATState pData, uint8_t *eth_addr)
     1536static uint32_t find_guest_ip(PNATState pData, const uint8_t *eth_addr)
    15351537{
    15361538    int i;
     1539    uint32_t ip = INADDR_ANY;
     1540    if (eth_addr == NULL)
     1541        goto done;
    15371542    if (memcmp(eth_addr, zerro_ethaddr, ETH_ALEN) == 0
    15381543        || memcmp(eth_addr, broadcast_ethaddr, ETH_ALEN) == 0)
    15391544        goto done;
    1540     for (i = 0; i < NB_ADDR; i++)
    1541     {
    1542         if (   bootp_clients[i].allocated
    1543             && memcmp(bootp_clients[i].macaddr, eth_addr, ETH_ALEN) == 0)
    1544             return bootp_clients[i].addr.s_addr;
    1545     }
     1545    if(slirp_arp_lookup_ip_by_ether(pData, eth_addr, &ip) == 0)
     1546        goto done;
     1547    bootp_cache_lookup_ip_by_ether(pData, eth_addr, &ip);
    15461548done:
    1547     return INADDR_ANY;
     1549    return ip;
    15481550}
    15491551
     
    18271829    _8K_1M_CHECK_ARG("TCP_SNDSPACE", kilobytes);
    18281830    tcp_sndspace = kilobytes * _1K;
     1831}
     1832
     1833/*
     1834 * Looking for Ether by ip in ARP-cache
     1835 * Note: it´s responsible of caller to allocate buffer for result
     1836 * @returns 0 - if found, 1 - otherwise
     1837 */
     1838int slirp_arp_lookup_ether_by_ip(PNATState pData, uint32_t ip, uint8_t *ether)
     1839{
     1840    struct arp_cache_entry *ac = NULL;
     1841    int rc = 1;
     1842    if (ether == NULL)
     1843        return rc;
     1844
     1845    if (LIST_EMPTY(&pData->arp_cache))
     1846        return rc;
     1847
     1848    LIST_FOREACH(ac, &pData->arp_cache, list)
     1849    {
     1850        if (ac->ip == ip)
     1851        {
     1852            memcpy(ether, ac->ether, ETH_ALEN);
     1853            rc = 0;
     1854            return rc;
     1855        }
     1856    }
     1857    return rc;
     1858}
     1859
     1860/*
     1861 * Looking for IP by Ether in ARP-cache
     1862 * Note: it´s responsible of caller to allocate buffer for result
     1863 * @returns 0 - if found, 1 - otherwise
     1864 */
     1865int slirp_arp_lookup_ip_by_ether(PNATState pData, const uint8_t *ether, uint32_t *ip)
     1866{
     1867    struct arp_cache_entry *ac = NULL;
     1868    int rc = 1;
     1869    *ip = INADDR_ANY;
     1870    if (LIST_EMPTY(&pData->arp_cache))
     1871        return rc;
     1872    LIST_FOREACH(ac, &pData->arp_cache, list)
     1873    {
     1874        if (memcmp(ether, ac->ether, ETH_ALEN))
     1875        {
     1876            *ip = ac->ip;
     1877            rc = 0;
     1878            return rc;
     1879        }
     1880    }
     1881    return rc;
    18291882}
    18301883
  • trunk/src/VBox/Devices/Network/slirp/slirp.h

    r22584 r22664  
    415415int nbt_alias_load(PNATState);
    416416int nbt_alias_unload(PNATState);
    417 #endif
    418 
     417
     418int slirp_arp_lookup_ip_by_ether(PNATState, const uint8_t *, uint32_t *);
     419int slirp_arp_lookup_ether_by_ip(PNATState, uint32_t, uint8_t *);
     420#endif
     421
  • trunk/src/VBox/Devices/Network/slirp/slirp_state.h

    r22500 r22664  
    3030#include "dnsproxy/dnsproxy.h"
    3131
    32 /** Number of DHCP clients supported by NAT. */
    33 #define NB_ADDR     16
    3432
    3533/** Where to start DHCP IP number allocation. */
     
    10098{
    10199    /* Stuff from boot.c */
    102     BOOTPClient bootp_clients[NB_ADDR];
     100    void *pbootp_clients;
    103101    const char *bootp_filename;
    104102    /* Stuff from if.c */
     
    306304
    307305#define bootp_filename pData->bootp_filename
    308 #define bootp_clients pData->bootp_clients
    309306
    310307#define if_mtu pData->if_mtu
  • trunk/src/VBox/Devices/Network/slirp/tcp_output.c

    r22013 r22664  
    589589                         so->so_options & SO_DONTROUTE, 0);
    590590#endif
    591 #ifdef VBOX_WITH_NAT_SERVICE
    592         {
    593             struct ethhdr *eh0, *eh;
    594             eh = (struct ethhdr *)m->m_dat;
    595 
    596             if (so->so_m != NULL)
    597             {
    598                 eh0 = (struct ethhdr *)so->so_m->m_dat;
    599                 memcpy(eh->h_source, eh0->h_source, ETH_ALEN);
    600             }
    601         }
    602 #endif
    603591        if(so->so_la != NULL)
    604592            m->m_la = so->so_la;
  • trunk/src/VBox/Devices/Network/slirp/tcp_subr.c

    r22013 r22664  
    124124        if ((m = m_get(pData)) == NULL)
    125125            return;
    126 #ifdef VBOX_WITH_NAT_SERVICE
    127         {
    128             struct ethhdr *eh0, *eh;
    129             Assert(tp->t_socket->so_m);
    130             eh0 = (struct ethhdr *)tp->t_socket->so_m->m_dat;
    131             eh = (struct ethhdr *)m->m_dat;
    132             memcpy(eh->h_source, eh0->h_source, ETH_ALEN);
    133         }
    134 #endif
    135126#ifdef TCP_COMPAT_42
    136127        tlen = 1;
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