samples: net: DNS resolving sample application
Change-Id: I4a0283efde4d0dd8ccd0933071acb277431d4a32 Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
This commit is contained in:
parent
cbfce3a299
commit
c6cad93d8c
5 changed files with 367 additions and 0 deletions
13
samples/net/dns_resolve/Makefile
Normal file
13
samples/net/dns_resolve/Makefile
Normal file
|
@ -0,0 +1,13 @@
|
|||
#
|
||||
# Copyright (c) 2016 Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
BOARD ?= qemu_x86
|
||||
CONF_FILE ?= prj_$(BOARD).conf
|
||||
|
||||
include $(ZEPHYR_BASE)/Makefile.inc
|
||||
ifeq ($(BOARD), qemu_x86)
|
||||
include $(ZEPHYR_BASE)/samples/net/common/Makefile.ipstack
|
||||
endif
|
59
samples/net/dns_resolve/prj_qemu_x86.conf
Normal file
59
samples/net/dns_resolve/prj_qemu_x86.conf
Normal file
|
@ -0,0 +1,59 @@
|
|||
CONFIG_NETWORKING=y
|
||||
CONFIG_NET_UDP=y
|
||||
CONFIG_RANDOM_GENERATOR=y
|
||||
CONFIG_TEST_RANDOM_GENERATOR=y
|
||||
CONFIG_NET_SLIP_TAP=y
|
||||
CONFIG_INIT_STACKS=y
|
||||
CONFIG_NET_NBUF_RX_COUNT=4
|
||||
CONFIG_NET_NBUF_TX_COUNT=4
|
||||
CONFIG_NET_NBUF_RX_DATA_COUNT=14
|
||||
CONFIG_NET_NBUF_TX_DATA_COUNT=14
|
||||
|
||||
CONFIG_NET_IF_UNICAST_IPV6_ADDR_COUNT=3
|
||||
CONFIG_NET_IF_MCAST_IPV6_ADDR_COUNT=5
|
||||
|
||||
CONFIG_NET_LOG=y
|
||||
CONFIG_SYS_LOG=y
|
||||
CONFIG_SYS_LOG_NET_LEVEL=4
|
||||
CONFIG_SYS_LOG_SHOW_COLOR=y
|
||||
#CONFIG_NET_DEBUG_NET_BUF=y
|
||||
CONFIG_NET_DEBUG_DNS_RESOLVE=y
|
||||
#CONFIG_NET_DEBUG_CONTEXT=y
|
||||
#CONFIG_NET_DEBUG_CORE=y
|
||||
#CONFIG_NET_DEBUG_IF=y
|
||||
#CONFIG_NET_DEBUG_IPV4=y
|
||||
#CONFIG_NET_DEBUG_IPV6=y
|
||||
#CONFIG_NET_DEBUG_UDP=y
|
||||
#CONFIG_NET_DEBUG_DHCPV4=y
|
||||
#CONFIG_SLIP_DEBUG=y
|
||||
|
||||
CONFIG_NET_IPV4=y
|
||||
CONFIG_NET_IPV6=y
|
||||
|
||||
# Enable the DNS resolver
|
||||
CONFIG_DNS_RESOLVER=y
|
||||
# Enable additional buffers
|
||||
CONFIG_DNS_RESOLVER_ADDITIONAL_BUF_CTR=2
|
||||
# Enable additional queries
|
||||
CONFIG_DNS_RESOLVER_ADDITIONAL_QUERIES=2
|
||||
|
||||
CONFIG_DNS_RESOLVER_MAX_SERVERS=2
|
||||
CONFIG_DNS_SERVER_IP_ADDRESSES=y
|
||||
CONFIG_DNS_NUM_CONCUR_QUERIES=2
|
||||
|
||||
# Google DNS IPv4 and IPv6 servers
|
||||
CONFIG_DNS_SERVER1="8.8.8.8"
|
||||
CONFIG_DNS_SERVER2="2001:4860:4860::8888"
|
||||
|
||||
CONFIG_NET_DHCPV4=y
|
||||
|
||||
CONFIG_NET_MGMT=y
|
||||
CONFIG_NET_MGMT_EVENT=y
|
||||
|
||||
CONFIG_NET_SHELL=y
|
||||
|
||||
CONFIG_NET_SAMPLES_IP_ADDRESSES=y
|
||||
CONFIG_NET_SAMPLES_MY_IPV6_ADDR="2001:db8::1"
|
||||
CONFIG_NET_SAMPLES_PEER_IPV6_ADDR="2001:db8::2"
|
||||
CONFIG_NET_SAMPLES_MY_IPV4_ADDR="192.0.2.1"
|
||||
CONFIG_NET_SAMPLES_PEER_IPV4_ADDR="192.0.2.2"
|
7
samples/net/dns_resolve/src/Makefile
Normal file
7
samples/net/dns_resolve/src/Makefile
Normal file
|
@ -0,0 +1,7 @@
|
|||
#
|
||||
# Copyright (c) 2016 Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
obj-y += main.o
|
284
samples/net/dns_resolve/src/main.c
Normal file
284
samples/net/dns_resolve/src/main.c
Normal file
|
@ -0,0 +1,284 @@
|
|||
/*
|
||||
* Copyright (c) 2017 Intel Corporation.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#if 1
|
||||
#define SYS_LOG_DOMAIN "dns-res"
|
||||
#define NET_SYS_LOG_LEVEL SYS_LOG_LEVEL_DEBUG
|
||||
#define NET_LOG_ENABLED 1
|
||||
#endif
|
||||
|
||||
#include <zephyr.h>
|
||||
#include <sections.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <net/net_core.h>
|
||||
#include <net/net_if.h>
|
||||
#include <net/net_mgmt.h>
|
||||
#include <net/dns_resolve.h>
|
||||
|
||||
#define STACKSIZE 2000
|
||||
char __noinit __stack thread_stack[STACKSIZE];
|
||||
|
||||
#define DNS_TIMEOUT 2000 /* ms */
|
||||
|
||||
void dns_result_cb(enum dns_resolve_status status,
|
||||
struct dns_addrinfo *info,
|
||||
void *user_data)
|
||||
{
|
||||
char hr_addr[NET_IPV6_ADDR_LEN];
|
||||
char *hr_family;
|
||||
void *addr;
|
||||
|
||||
switch (status) {
|
||||
case DNS_EAI_CANCELED:
|
||||
NET_INFO("DNS query was canceled");
|
||||
return;
|
||||
case DNS_EAI_FAIL:
|
||||
NET_INFO("DNS resolve failed");
|
||||
return;
|
||||
case DNS_EAI_NODATA:
|
||||
NET_INFO("Cannot resolve address");
|
||||
return;
|
||||
case DNS_EAI_ALLDONE:
|
||||
NET_INFO("DNS resolving finished");
|
||||
return;
|
||||
case DNS_EAI_INPROGRESS:
|
||||
break;
|
||||
default:
|
||||
NET_INFO("DNS resolving error (%d)", status);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!info) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (info->ai_family == AF_INET) {
|
||||
hr_family = "IPv4";
|
||||
addr = &net_sin(&info->ai_addr)->sin_addr;
|
||||
} else if (info->ai_family == AF_INET6) {
|
||||
hr_family = "IPv6";
|
||||
addr = &net_sin6(&info->ai_addr)->sin6_addr;
|
||||
} else {
|
||||
NET_ERR("Invalid IP address family %d", info->ai_family);
|
||||
return;
|
||||
}
|
||||
|
||||
NET_INFO("%s address: %s", hr_family,
|
||||
net_addr_ntop(info->ai_family, addr,
|
||||
hr_addr, sizeof(hr_addr)));
|
||||
}
|
||||
|
||||
#if defined(CONFIG_NET_DHCPV4)
|
||||
static struct net_mgmt_event_callback mgmt4_cb;
|
||||
static struct k_delayed_work ipv4_timer;
|
||||
|
||||
static void do_ipv4_lookup(struct k_work *work)
|
||||
{
|
||||
uint16_t dns_id;
|
||||
int ret;
|
||||
|
||||
ret = dns_get_addr_info("www.zephyrproject.org",
|
||||
DNS_QUERY_TYPE_A,
|
||||
&dns_id,
|
||||
dns_result_cb,
|
||||
NULL,
|
||||
DNS_TIMEOUT);
|
||||
if (ret < 0) {
|
||||
NET_ERR("Cannot resolve IPv4 address (%d)", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
NET_DBG("DNS id %u", dns_id);
|
||||
}
|
||||
|
||||
static void ipv4_addr_add_handler(struct net_mgmt_event_callback *cb,
|
||||
uint32_t mgmt_event,
|
||||
struct net_if *iface)
|
||||
{
|
||||
char hr_addr[NET_IPV4_ADDR_LEN];
|
||||
int i;
|
||||
|
||||
if (mgmt_event != NET_EVENT_IPV4_ADDR_ADD) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < NET_IF_MAX_IPV4_ADDR; i++) {
|
||||
struct net_if_addr *if_addr = &iface->ipv4.unicast[i];
|
||||
|
||||
if (if_addr->addr_type != NET_ADDR_DHCP || !if_addr->is_used) {
|
||||
continue;
|
||||
}
|
||||
|
||||
NET_INFO("IPv4 address: %s",
|
||||
net_addr_ntop(AF_INET, &if_addr->address.in_addr,
|
||||
hr_addr, NET_IPV4_ADDR_LEN));
|
||||
NET_INFO("Lease time: %u seconds", iface->dhcpv4.lease_time);
|
||||
NET_INFO("Subnet: %s",
|
||||
net_addr_ntop(AF_INET, &iface->ipv4.netmask,
|
||||
hr_addr, NET_IPV4_ADDR_LEN));
|
||||
NET_INFO("Router: %s",
|
||||
net_addr_ntop(AF_INET, &iface->ipv4.gw,
|
||||
hr_addr, NET_IPV4_ADDR_LEN));
|
||||
break;
|
||||
}
|
||||
|
||||
/* We cannot run DNS lookup directly from this thread as the
|
||||
* management event thread stack is very small by default.
|
||||
* So run it from work queue instead.
|
||||
*/
|
||||
k_delayed_work_init(&ipv4_timer, do_ipv4_lookup);
|
||||
k_delayed_work_submit(&ipv4_timer, 0);
|
||||
}
|
||||
|
||||
static void setup_dhcpv4(struct net_if *iface)
|
||||
{
|
||||
NET_INFO("Running dhcpv4 client...");
|
||||
|
||||
net_mgmt_init_event_callback(&mgmt4_cb, ipv4_addr_add_handler,
|
||||
NET_EVENT_IPV4_ADDR_ADD);
|
||||
net_mgmt_add_event_callback(&mgmt4_cb);
|
||||
|
||||
net_dhcpv4_start(iface);
|
||||
}
|
||||
|
||||
#else
|
||||
#define setup_dhcpv4(...)
|
||||
#endif /* CONFIG_NET_DHCPV4 */
|
||||
|
||||
#if defined(CONFIG_NET_IPV4) && !defined(CONFIG_NET_DHCPV4)
|
||||
|
||||
#if !defined(CONFIG_NET_SAMPLES_MY_IPV4_ADDR)
|
||||
#error "You need to define an IPv4 address or enable DHCPv4!"
|
||||
#endif
|
||||
|
||||
static void setup_ipv4(struct net_if *iface)
|
||||
{
|
||||
char hr_addr[NET_IPV4_ADDR_LEN];
|
||||
struct in_addr addr;
|
||||
uint16_t dns_id;
|
||||
int ret;
|
||||
|
||||
if (net_addr_pton(AF_INET, CONFIG_NET_SAMPLES_MY_IPV4_ADDR, &addr)) {
|
||||
NET_ERR("Invalid address: %s", CONFIG_NET_SAMPLES_MY_IPV4_ADDR);
|
||||
return;
|
||||
}
|
||||
|
||||
net_if_ipv4_addr_add(iface, &addr, NET_ADDR_MANUAL, 0);
|
||||
|
||||
NET_INFO("IPv4 address: %s",
|
||||
net_addr_ntop(AF_INET, &addr, hr_addr, NET_IPV4_ADDR_LEN));
|
||||
|
||||
ret = dns_get_addr_info("www.zephyrproject.org",
|
||||
DNS_QUERY_TYPE_A,
|
||||
&dns_id,
|
||||
dns_result_cb,
|
||||
NULL,
|
||||
DNS_TIMEOUT);
|
||||
if (ret < 0) {
|
||||
NET_ERR("Cannot resolve IPv4 address (%d)", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
NET_DBG("DNS id %u", dns_id);
|
||||
}
|
||||
|
||||
#else
|
||||
#define setup_ipv4(...)
|
||||
#endif /* CONFIG_NET_IPV4 && !CONFIG_NET_DHCPV4 */
|
||||
|
||||
#if defined(CONFIG_NET_IPV6)
|
||||
|
||||
#if !defined(CONFIG_NET_SAMPLES_MY_IPV6_ADDR)
|
||||
#error "You need to define an IPv6 address!"
|
||||
#endif
|
||||
|
||||
static struct net_mgmt_event_callback mgmt6_cb;
|
||||
static struct k_delayed_work ipv6_timer;
|
||||
|
||||
static void do_ipv6_lookup(struct k_work *work)
|
||||
{
|
||||
uint16_t dns_id;
|
||||
int ret;
|
||||
|
||||
ret = dns_get_addr_info("www.zephyrproject.org",
|
||||
DNS_QUERY_TYPE_AAAA,
|
||||
&dns_id,
|
||||
dns_result_cb,
|
||||
NULL,
|
||||
DNS_TIMEOUT);
|
||||
if (ret < 0) {
|
||||
NET_ERR("Cannot resolve IPv6 address (%d)", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
NET_DBG("DNS id %u", dns_id);
|
||||
}
|
||||
|
||||
/* DNS query will most probably fail if we do not have a default
|
||||
* router configured because typically the DNS server is outside of local
|
||||
* network. So wait for that before continuing.
|
||||
*/
|
||||
static void ipv6_router_add_handler(struct net_mgmt_event_callback *cb,
|
||||
uint32_t mgmt_event,
|
||||
struct net_if *iface)
|
||||
{
|
||||
if (mgmt_event != NET_EVENT_IPV6_ROUTER_ADD) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* We cannot run DNS lookup directly from this thread as the
|
||||
* management event thread stack is very small by default.
|
||||
* So run it from work queue instead.
|
||||
*/
|
||||
k_delayed_work_init(&ipv6_timer, do_ipv6_lookup);
|
||||
k_delayed_work_submit(&ipv6_timer, 0);
|
||||
}
|
||||
|
||||
static void setup_ipv6(struct net_if *iface)
|
||||
{
|
||||
char hr_addr[NET_IPV6_ADDR_LEN];
|
||||
struct in6_addr addr;
|
||||
|
||||
if (net_addr_pton(AF_INET6, CONFIG_NET_SAMPLES_MY_IPV6_ADDR, &addr)) {
|
||||
NET_ERR("Invalid address: %s", CONFIG_NET_SAMPLES_MY_IPV6_ADDR);
|
||||
return;
|
||||
}
|
||||
|
||||
net_mgmt_init_event_callback(&mgmt6_cb, ipv6_router_add_handler,
|
||||
NET_EVENT_IPV6_ROUTER_ADD);
|
||||
net_mgmt_add_event_callback(&mgmt6_cb);
|
||||
|
||||
net_if_ipv6_addr_add(iface, &addr, NET_ADDR_MANUAL, 0);
|
||||
|
||||
NET_INFO("IPv6 address: %s",
|
||||
net_addr_ntop(AF_INET6, &addr, hr_addr, NET_IPV6_ADDR_LEN));
|
||||
}
|
||||
|
||||
#else
|
||||
#define setup_ipv6(...)
|
||||
#endif /* CONFIG_NET_IPV6 */
|
||||
|
||||
static void network_setup(void)
|
||||
{
|
||||
struct net_if *iface = net_if_get_default();
|
||||
|
||||
setup_ipv4(iface);
|
||||
|
||||
setup_dhcpv4(iface);
|
||||
|
||||
setup_ipv6(iface);
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
NET_INFO("Starting DNS resolve sample");
|
||||
|
||||
k_thread_spawn(&thread_stack[0], STACKSIZE,
|
||||
(k_thread_entry_t)network_setup,
|
||||
NULL, NULL, NULL, K_PRIO_COOP(7), 0, 0);
|
||||
}
|
4
samples/net/dns_resolve/testcase.ini
Normal file
4
samples/net/dns_resolve/testcase.ini
Normal file
|
@ -0,0 +1,4 @@
|
|||
[test]
|
||||
tags = net dns
|
||||
build_only = true
|
||||
platform_whitelist = qemu_x86
|
Loading…
Add table
Add a link
Reference in a new issue