Beispiel #1
0
/**
 * Convert the given exported device structure from host to network byte order.
 *
 * @returns nothing.
 * @param   pDevice           The device structure to convert.
 */
DECLINLINE(void) usbProxyBackendUsbIpExportedDeviceN2H(PUsbIpExportedDevice pDevice)
{
    pDevice->u32BusNum    = RT_N2H_U32(pDevice->u32BusNum);
    pDevice->u32DevNum    = RT_N2H_U32(pDevice->u32DevNum);
    pDevice->u32Speed     = RT_N2H_U16(pDevice->u32Speed);
    pDevice->u16VendorId  = RT_N2H_U16(pDevice->u16VendorId);
    pDevice->u16ProductId = RT_N2H_U16(pDevice->u16ProductId);
    pDevice->u16BcdDevice = RT_N2H_U16(pDevice->u16BcdDevice);
}
Beispiel #2
0
int VBoxNetDhcp::hostDnsServers(const ComHostPtr& host,
                                const RTNETADDRIPV4& networkid,
                                const AddressToOffsetMapping& mapping,
                                AddressList& servers)
{
    ComBstrArray strs;

    HRESULT hrc = host->COMGETTER(NameServers)(ComSafeArrayAsOutParam(strs));
    if (FAILED(hrc))
        return VERR_NOT_FOUND;

    /*
     * Recent fashion is to run dnsmasq on 127.0.1.1 which we
     * currently can't map.  If that's the only nameserver we've got,
     * we need to use DNS proxy for VMs to reach it.
     */
    bool fUnmappedLoopback = false;

    for (size_t i = 0; i < strs.size(); ++i)
    {
        RTNETADDRIPV4 addr;
        int rc;

        rc = RTNetStrToIPv4Addr(com::Utf8Str(strs[i]).c_str(), &addr);
        if (RT_FAILURE(rc))
            continue;

        if (addr.au8[0] == 127)
        {
            AddressToOffsetMapping::const_iterator remap(mapping.find(addr));

            if (remap != mapping.end())
            {
                int offset = remap->second;
                addr.u = RT_H2N_U32(RT_N2H_U32(networkid.u) + offset);
            }
            else
            {
                fUnmappedLoopback = true;
                continue;
            }
        }

        servers.push_back(addr);
    }

    if (servers.empty() && fUnmappedLoopback)
    {
        RTNETADDRIPV4 proxy;

        proxy.u = networkid.u | RT_H2N_U32_C(1U);
        servers.push_back(proxy);
    }

    return VINF_SUCCESS;
}
Beispiel #3
0
int VBoxNetDhcp::initNoMain()
{
    CmdParameterIterator it;

    RTNETADDRIPV4 address = getIpv4Address();
    RTNETADDRIPV4 netmask = getIpv4Netmask();
    RTNETADDRIPV4 networkId;
    networkId.u = address.u & netmask.u;

    RTNETADDRIPV4 UpperAddress;
    RTNETADDRIPV4 LowerAddress = networkId;
    UpperAddress.u = RT_H2N_U32(RT_N2H_U32(LowerAddress.u) | RT_N2H_U32(netmask.u));

    for (it = CmdParameterll.begin(); it != CmdParameterll.end(); ++it)
    {
        switch(it->Key)
        {
            case 'l':
                RTNetStrToIPv4Addr(it->strValue.c_str(), &LowerAddress);
                break;

            case 'u':
                RTNetStrToIPv4Addr(it->strValue.c_str(), &UpperAddress);
                break;
            case 'b':
                break;

        }
    }

    ConfigurationManager *confManager = ConfigurationManager::getConfigurationManager();
    AssertPtrReturn(confManager, VERR_INTERNAL_ERROR);
    confManager->addNetwork(unconst(g_RootConfig),
                            networkId,
                            netmask,
                            LowerAddress,
                            UpperAddress);

    return VINF_SUCCESS;
}
Beispiel #4
0
/**
 * @note: const dropped here, because of map<K,V>::operator[] which isn't const, map<K,V>::at() has const
 * variant but it's C++11.
 */
int hostDnsServers(const ComHostPtr& host, const RTNETADDRIPV4& networkid,
                   /*const*/ AddressToOffsetMapping& mapping, AddressList& servers)
{
    servers.clear();

    ComBstrArray strs;
    if (SUCCEEDED(host->COMGETTER(NameServers)(ComSafeArrayAsOutParam(strs))))
    {
        RTNETADDRIPV4 addr;
        int rc;

        for (unsigned int i = 0; i < strs.size(); ++i)
        {
            rc = RTNetStrToIPv4Addr(com::Utf8Str(strs[i]).c_str(), &addr);
            if (RT_SUCCESS(rc))
            {
                if (addr.au8[0] == 127)
                {
                    /* XXX: here we want map<K,V>::at(const K& k) const */
                    if (mapping[addr] != 0)
                    {
                        addr.u = RT_H2N_U32(RT_N2H_U32(networkid.u)
                                            + mapping[addr]);
                    }
                    else
                        continue; /* XXX: Warning here (local mapping wasn't registered) */
                }

                servers.push_back(addr);
            }
        }
    }
    else
        return VERR_NOT_FOUND;

    return VINF_SUCCESS;
}
Beispiel #5
0
/**
 * Processes the data in the scratch buffer based on the current state.
 *
 * @returns VBox status code.
 */
int USBProxyBackendUsbIp::processData()
{
    int rc = VINF_SUCCESS;

    switch (m->enmRecvState)
    {
        case kUsbIpRecvState_Hdr:
        {
            /* Check that the reply matches our expectations. */
            if (   RT_N2H_U16(m->Scratch.RetDevList.u16Version) == USBIP_VERSION
                && RT_N2H_U16(m->Scratch.RetDevList.u16Cmd) == USBIP_REQ_RET_DEVLIST
                && RT_N2H_U32(m->Scratch.RetDevList.u32Status) == USBIP_STATUS_SUCCESS)
            {
                /* Populate the number of exported devices in the list and go to the next state. */
                m->cDevicesLeft = RT_N2H_U32(m->Scratch.RetDevList.u32DevicesExported);
                if (m->cDevicesLeft)
                    advanceState(kUsbIpRecvState_ExportedDevice);
                else
                    advanceState(kUsbIpRecvState_None);
            }
            else
            {
                LogRelMax(10, ("USB/IP: Host sent an invalid reply to the list exported device request (Version: %#x Cmd: %#x Status: %#x)\n",
                               RT_N2H_U16(m->Scratch.RetDevList.u16Version), RT_N2H_U16(m->Scratch.RetDevList.u16Cmd),
                               RT_N2H_U32(m->Scratch.RetDevList.u32Status)));
                rc = VERR_INVALID_STATE;
            }
            break;
        }
        case kUsbIpRecvState_ExportedDevice:
        {
            /* Create a new device and add it to the list. */
            usbProxyBackendUsbIpExportedDeviceN2H(&m->Scratch.ExportedDevice);
            rc = addDeviceToList(&m->Scratch.ExportedDevice);
            if (RT_SUCCESS(rc))
            {
                m->cInterfacesLeft = m->Scratch.ExportedDevice.bNumInterfaces;
                if (m->cInterfacesLeft)
                    advanceState(kUsbIpRecvState_DeviceInterface);
                else
                {
                    m->cDevicesLeft--;
                    if (m->cDevicesLeft)
                        advanceState(kUsbIpRecvState_ExportedDevice);
                    else
                        advanceState(kUsbIpRecvState_None);
                }
            }
            break;
        }
        case kUsbIpRecvState_DeviceInterface:
        {
            /*
             * If all interfaces for the current device were received receive the next device
             * if there is another one left, if not we are done with the current request.
             */
            m->cInterfacesLeft--;
            if (m->cInterfacesLeft)
                advanceState(kUsbIpRecvState_DeviceInterface);
            else
            {
                m->cDevicesLeft--;
                if (m->cDevicesLeft)
                    advanceState(kUsbIpRecvState_ExportedDevice);
                else
                    advanceState(kUsbIpRecvState_None);
            }
            break;
        }
        case kUsbIpRecvState_None:
        default:
            AssertMsgFailed(("Invalid USB/IP receive state %d\n", m->enmRecvState));
            return VERR_INVALID_STATE;
    }

    return rc;
}
Beispiel #6
0
    /* here we should check if we reached the end of the DNS server list */
    hash_remove_request(pData, (struct request *)arg);
    free((struct request *)arg);
    ++removed_queries;
}
#else /* VBOX */
static void
timeout(PNATState pData, struct socket *so, void *arg)
{
    struct request *req = (struct request *)arg;
    struct dns_entry *de;
    /* be paranoid */
    AssertPtrReturnVoid(arg);

    if (   req->dnsgen != pData->dnsgen
        || req->dns_server == NULL
        || (de = TAILQ_PREV(req->dns_server, dns_list_head, de_list)) == NULL)
    {
        if (req->dnsgen != pData->dnsgen)
        {
            /* XXX: Log2 */
            LogRel(("NAT: dnsproxy: timeout: req %p dnsgen %u != %u on %R[natsock]\n",
                    req, req->dnsgen, pData->dnsgen, so));
        }
        hash_remove_request(pData, req);
        RTMemFree(req);
        ++removed_queries;
        /* the rest of clean up at the end of the method. */
    }
    else
    {
        struct ip *ip;
        struct udphdr *udp;
        int iphlen;
        struct mbuf *m = NULL;
        char *data;

        m = slirpDnsMbufAlloc(pData);
        if (m == NULL)
        {
            LogRel(("NAT: Can't allocate mbuf\n"));
            goto socket_clean_up;
        }

        /* mbuf initialization */
        m->m_data += if_maxlinkhdr;

        ip = mtod(m, struct ip *);
        udp = (struct udphdr *)&ip[1]; /* ip attributes */
        data = (char *)&udp[1];
        iphlen = sizeof(struct ip);

        m->m_len += sizeof(struct ip);
        m->m_len += sizeof(struct udphdr);
        m->m_len += req->nbyte;

        ip->ip_src.s_addr = so->so_laddr.s_addr;
        ip->ip_dst.s_addr = RT_H2N_U32(RT_N2H_U32(pData->special_addr.s_addr) | CTL_DNS);
        udp->uh_dport = ntohs(53);
        udp->uh_sport = so->so_lport;

        memcpy(data, req->byte, req->nbyte); /* coping initial req */

        /* req points to so->so_timeout_arg */
        req->dns_server = de;

        /* expiration will be bumped in dnsproxy_query */

        dnsproxy_query(pData, so, m, iphlen);
        /* should we free so->so_m ? */
        return;
    }

 socket_clean_up:
    /* This socket (so) will be detached, so we need to remove timeout(&_arg) references
     * before leave
     */
    so->so_timeout = NULL;
    so->so_timeout_arg = NULL;
    return;

}