From 2cc9aea1d36fcc1ad66b5e77d56431a51ea8d8ea Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Thu, 11 Apr 2013 17:11:02 +0200 Subject: add support for Recursive DNS Server (rfc6106) Signed-off-by: Jiri Pirko --- libndp/libndp.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ libndp/ndp_private.h | 9 +++++++++ 2 files changed, 61 insertions(+) (limited to 'libndp') diff --git a/libndp/libndp.c b/libndp/libndp.c index d2b0bb6..95ae9f6 100644 --- a/libndp/libndp.c +++ b/libndp/libndp.c @@ -1009,6 +1009,10 @@ static struct ndp_msg_opt_type_info ndp_msg_opt_type_info_list[] = .raw_struct_size = sizeof(struct __nd_opt_route_info), .check_valid = ndp_msg_opt_route_check_valid, }, + [NDP_MSG_OPT_RDNSS] = { + .raw_type = __ND_OPT_RDNSS, + .raw_struct_size = sizeof(struct __nd_opt_rdnss), + }, }; #define NDP_MSG_OPT_TYPE_LIST_SIZE ARRAY_SIZE(ndp_msg_opt_type_info_list) @@ -1349,6 +1353,54 @@ ndp_msg_opt_route_preference(struct ndp_msg *msg, int offset) return (ri->nd_opt_ri_prf_reserved >> 3) & 3; } +/** + * ndp_msg_opt_rdnss_lifetime: + * @msg: message structure + * + * Get Recursive DNS Server lifetime. + * User should use this function only inside ndp_msg_opt_for_each_offset() + * macro loop. + * + * Returns: route lifetime in seconds, (uint32_t) -1 means infinity. + **/ +NDP_EXPORT +uint32_t ndp_msg_opt_rdnss_lifetime(struct ndp_msg *msg, int offset) +{ + struct __nd_opt_rdnss *rdnss = + ndp_msg_payload_opts_offset(msg, offset); + + return ntohl(rdnss->nd_opt_rdnss_lifetime); +} + +/** + * ndp_msg_opt_rdnss_addr: + * @msg: message structure + * @offset: in-message offset + * @addr_index: address index + * + * Get Recursive DNS Server address. + * User should use this function only inside ndp_msg_opt_for_each_offset() + * macro loop. + * + * Returns: address. + **/ +NDP_EXPORT +struct in6_addr *ndp_msg_opt_rdnss_addr(struct ndp_msg *msg, int offset, + int addr_index) +{ + static struct in6_addr addr; + struct __nd_opt_rdnss *rdnss = + ndp_msg_payload_opts_offset(msg, offset); + size_t len = rdnss->nd_opt_rdnss_len << 3; /* convert to bytes */ + + len -= in_struct_offset(struct __nd_opt_rdnss, nd_opt_rdnss_addresses); + if ((addr_index + 1) * sizeof(addr) > len) + return NULL; + memcpy(&addr, &rdnss->nd_opt_rdnss_addresses[addr_index * sizeof(addr)], + sizeof(addr)); + return &addr; +} + static int ndp_call_handlers(struct ndp *ndp, struct ndp_msg *msg); static int ndp_sock_recv(struct ndp *ndp) diff --git a/libndp/ndp_private.h b/libndp/ndp_private.h index 7ab0ade..7424e8c 100644 --- a/libndp/ndp_private.h +++ b/libndp/ndp_private.h @@ -83,6 +83,7 @@ ndp_log_null(struct ndp *ndp, const char *format, ...) {} */ #define __ND_OPT_ROUTE_INFO 24 /* rfc4191 */ +#define __ND_OPT_RDNSS 25 /* rfc6106 */ struct __nd_opt_route_info { /* route information */ uint8_t nd_opt_ri_type; @@ -93,4 +94,12 @@ struct __nd_opt_route_info { /* route information */ char nd_opt_ri_prefix[0]; }; +struct __nd_opt_rdnss { /* Recursive DNS Server */ + uint8_t nd_opt_rdnss_type; + uint8_t nd_opt_rdnss_len; + uint16_t nd_opt_rdnss_reserved; + uint32_t nd_opt_rdnss_lifetime; + char nd_opt_rdnss_addresses[0]; +}; + #endif /* _NDP_PRIVATE_H_ */ -- cgit v1.2.1