Exemple #1
0
/**@brief UDP Port Set-Up.
 *
 * @details Sets up UDP Port to listen on.
 */
static void udp_port_setup(void)
{
    ip6_addr_t any_addr;
    ip6_addr_set_any(&any_addr);

    mp_udp_port = udp_new_ip6();

    if (mp_udp_port != NULL)
    {
        err_t err = udp_bind_ip6(mp_udp_port, &any_addr, UDP_CLIENT_PORT);
        APP_ERROR_CHECK(err);

        udp_recv_ip6(mp_udp_port,udp_recv_data_handler, NULL);
    }
    else
    {
        ASSERT(0);
    }
}
/**
 * Initialize DHCP6 server.
 *
 * Join DHCP6 multicast groups.
 * Create and bind server pcb.
 * Prebuild fixed parts of reply.
 */
err_t
dhcp6ds_init(struct netif *proxy_netif)
{
    ip6_addr_t *pxaddr, *pxaddr_nonlocal;
    int i;
    err_t error;

    LWIP_ASSERT1(proxy_netif != NULL);
    LWIP_ASSERT1(proxy_netif->hwaddr_len == 6); /* ethernet */

    pxaddr = netif_ip6_addr(proxy_netif, 0); /* link local */

    /*
     * XXX: TODO: This is a leftover from testing with IPv6 mapped
     * loopback with a special IPv6->IPv4 mapping hack in pxudp.c
     */
    /* advertise ourself as DNS resolver - will be proxied to host */
    pxaddr_nonlocal = NULL;
    for (i = 1; i < LWIP_IPV6_NUM_ADDRESSES; ++i) {
        if (ip6_addr_ispreferred(netif_ip6_addr_state(proxy_netif, i))
            && !ip6_addr_islinklocal(netif_ip6_addr(proxy_netif, i)))
        {
            pxaddr_nonlocal = netif_ip6_addr(proxy_netif, i);
            break;
        }
    }
    LWIP_ASSERT1(pxaddr_nonlocal != NULL); /* must be configured on the netif */


    error = mld6_joingroup(pxaddr, &all_dhcp_relays_and_servers);
    if (error != ERR_OK) {
        DPRINTF0(("%s: failed to join All_DHCP_Relay_Agents_and_Servers: %s\n",
                  __func__, proxy_lwip_strerr(error)));
        goto err;
    }

    error = mld6_joingroup(pxaddr, &all_dhcp_servers);
    if (error != ERR_OK) {
        DPRINTF0(("%s: failed to join All_DHCP_Servers: %s\n",
                  __func__, proxy_lwip_strerr(error)));
        goto err1;
    }


    dhcp6ds_pcb = udp_new_ip6();
    if (dhcp6ds_pcb == NULL) {
        DPRINTF0(("%s: failed to allocate PCB\n", __func__));
        error = ERR_MEM;
        goto err2;
    }

    udp_recv_ip6(dhcp6ds_pcb, dhcp6ds_recv, NULL);

    error = udp_bind_ip6(dhcp6ds_pcb, pxaddr, DHCP6_SERVER_PORT);
    if (error != ERR_OK) {
        DPRINTF0(("%s: failed to bind PCB\n", __func__));
        goto err3;
    }


#define OPT_SET(buf, off, c) do {                       \
        u16_t _s = PP_HTONS(c);                         \
        memcpy(&(buf)[off], &_s, sizeof(u16_t));        \
    } while (0)

#define SERVERID_SET(off, c)    OPT_SET(dhcp6ds_serverid, (off), (c))
#define DNSSRV_SET(off, c)      OPT_SET(dhcp6ds_dns, (off), (c))

    SERVERID_SET(0, DHCP6_OPTION_SERVERID);
    SERVERID_SET(2, DUID_LL_LEN);
    SERVERID_SET(4, DHCP6_DUID_LL);
    SERVERID_SET(6, ARES_HRD_ETHERNET);
    memcpy(&dhcp6ds_serverid[8], proxy_netif->hwaddr, 6);

    DNSSRV_SET(0, DHCP6_OPTION_DNS_SERVERS);
    DNSSRV_SET(2, 16);          /* one IPv6 address */
    /*
     * XXX: TODO: This is a leftover from testing with IPv6 mapped
     * loopback with a special IPv6->IPv4 mapping hack in pxudp.c
     */
    memcpy(&dhcp6ds_dns[4], pxaddr_nonlocal, sizeof(ip6_addr_t));

#undef SERVERID_SET
#undef DNSSRV_SET

    return ERR_OK;


  err3:
    udp_remove(dhcp6ds_pcb);
    dhcp6ds_pcb = NULL;
  err2:
    mld6_leavegroup(pxaddr, &all_dhcp_servers);
  err1:
    mld6_leavegroup(pxaddr, &all_dhcp_relays_and_servers);
  err:
    return error;
}
Exemple #3
0
err_t
pxdns_init(struct netif *proxy_netif)
{
    struct pxdns *pxdns = &g_pxdns;
    err_t error;

    LWIP_UNUSED_ARG(proxy_netif);

    pxdns->pmhdl4.callback = pxdns_pmgr_pump;
    pxdns->pmhdl4.data = (void *)pxdns;
    pxdns->pmhdl4.slot = -1;

    pxdns->pmhdl6.callback = pxdns_pmgr_pump;
    pxdns->pmhdl6.data = (void *)pxdns;
    pxdns->pmhdl6.slot = -1;

    pxdns->pcb4 = udp_new();
    if (pxdns->pcb4 == NULL) {
        error = ERR_MEM;
        goto err_cleanup_pcb;
    }

    pxdns->pcb6 = udp_new_ip6();
    if (pxdns->pcb6 == NULL) {
        error = ERR_MEM;
        goto err_cleanup_pcb;
    }

    error = udp_bind(pxdns->pcb4, IP_ADDR_ANY, 53);
    if (error != ERR_OK) {
        goto err_cleanup_pcb;
    }

    error = udp_bind_ip6(pxdns->pcb6, IP6_ADDR_ANY, 53);
    if (error != ERR_OK) {
        goto err_cleanup_pcb;
    }

    udp_recv(pxdns->pcb4, pxdns_recv4, pxdns);
    udp_recv_ip6(pxdns->pcb6, pxdns_recv6, pxdns);

    pxdns->sock4 = socket(AF_INET, SOCK_DGRAM, 0);
    if (pxdns->sock4 == INVALID_SOCKET) {
        goto err_cleanup_pcb;
    }

    pxdns->sock6 = socket(AF_INET6, SOCK_DGRAM, 0);
    if (pxdns->sock6 == INVALID_SOCKET) {
        /* it's ok if the host doesn't support IPv6 */
        /* XXX: TODO: log */
    }

    pxdns->generation = 0;
    pxdns->nresolvers = 0;
    pxdns->resolvers = NULL;
    pxdns_create_resolver_sockaddrs(pxdns, g_proxy_options->nameservers);

    sys_mutex_new(&pxdns->lock);

    pxdns->timeout_slot = 0;
    pxdns->timeout_mask = 0;

    /* NB: assumes pollmgr thread is not running yet */
    pollmgr_add(&pxdns->pmhdl4, pxdns->sock4, POLLIN);
    if (pxdns->sock6 != INVALID_SOCKET) {
        pollmgr_add(&pxdns->pmhdl6, pxdns->sock6, POLLIN);
    }

    return ERR_OK;

  err_cleanup_pcb:
    if (pxdns->pcb4 != NULL) {
        udp_remove(pxdns->pcb4);
        pxdns->pcb4 = NULL;
    }
    if (pxdns->pcb6 != NULL) {
        udp_remove(pxdns->pcb6);
        pxdns->pcb4 = NULL;
    }

    return error;
}