Commit b0d80757 authored by John Andersen's avatar John Andersen Committed by Jukka Rissanen
Browse files

net: ip: dhcpv4: Handle DHCPV4_OPTIONS_DNS_SERVER



Actually set Zephyr's default DNS server based on the corresponding
DHCP option received. This makes DHCP-based setup Zephyr complete:
now it's possible to connect Zephyr DHCP-enabled system to a typical
router, and it will fully auto-configure to access Internet.

This initial implementation uses just first DNS server address as
returned in DHCP message, it may need to be extended in the future
based on the need.

Signed-off-by: default avatarJohn Andersen <john.s.andersen@intel.com>
Signed-off-by: default avatarPaul Sokolovsky <paul.sokolovsky@linaro.org>
parent d965598e
Loading
Loading
Loading
Loading
+41 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@
#include <net/udp.h>
#include "udp_internal.h"
#include <net/dhcpv4.h>
#include <net/dns_resolve.h>

struct dhcp_msg {
	u8_t op;		/* Message type, 1:BOOTREQUEST, 2:BOOTREPLY */
@@ -745,6 +746,46 @@ static enum net_verdict parse_options(struct net_if *iface,
			net_if_ipv4_set_gw(iface, &router);
			break;
		}
#if defined(CONFIG_DNS_RESOLVER)
		case DHCPV4_OPTIONS_DNS_SERVER: {
			int status;
			struct sockaddr_in dns;
			const struct sockaddr *dns_servers[] = {
				(struct sockaddr *)&dns, NULL
			};

			/* DNS server option may present 1 or more
			 * addresses. Each 4 bytes in length. DNS
			 * servers should be listed in order
			 * of preference.  Hence we choose the first
			 * and skip the rest.
			 */
			if (length % 4 != 0) {
				NET_ERR("options_dns, bad length");
				return NET_DROP;
			}

			memset(&dns, 0, sizeof(dns));
			frag = net_frag_read(frag, pos, &pos, 4,
					     dns.sin_addr.s4_addr);
			frag = net_frag_skip(frag, pos, &pos, length - 4);
			if (!frag && pos) {
				NET_ERR("options_dns, short packet");
				return NET_DROP;
			}
			dns.sin_family = AF_INET;

			dns_resolve_close(dns_resolve_get_default());
			status = dns_resolve_init(dns_resolve_get_default(),
						  NULL, dns_servers);
			if (status < 0) {
				NET_DBG("options_dns, failed to set "
					"resolve address: %d", status);
				return NET_DROP;
			}
			break;
		}
#endif
		case DHCPV4_OPTIONS_LEASE_TIME:
			if (length != 4) {
				NET_ERR("options_lease_time, bad length");