/**@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; }
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; }