/*
* ndp.h - Neighbour discovery library
* Copyright (C) 2013-2015 Jiri Pirko <jiri@resnulli.us>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _NDP_H_
#define _NDP_H_
#include <stdarg.h>
#include <stdbool.h>
#include <netinet/in.h>
#ifdef __cplusplus
extern "C" {
#endif
struct ndp;
void ndp_set_log_fn(struct ndp *ndp,
void (*log_fn)(struct ndp *ndp, int priority,
const char *file, int line, const char *fn,
const char *format, va_list args));
int ndp_get_log_priority(struct ndp *ndp);
void ndp_set_log_priority(struct ndp *ndp, int priority);
struct ndp_msg;
struct ndp_msgrs;
struct ndp_msgra;
struct ndp_msgns;
struct ndp_msgna;
struct ndp_msgr;
enum ndp_msg_type {
NDP_MSG_RS, /* Router Solicitation */
NDP_MSG_RA, /* Router Advertisement */
NDP_MSG_NS, /* Neighbor Solicitation */
NDP_MSG_NA, /* Neighbor Advertisement */
NDP_MSG_R, /* Redirect */
NDP_MSG_ALL, /* Matches all */
};
#define ND_OPT_NORMAL 0x0000 /* default, no change to ND message */
#define ND_OPT_NA_UNSOL 0x0001 /* Unsolicited Neighbour Advertisement */
enum ndp_route_preference {
NDP_ROUTE_PREF_LOW = 3,
NDP_ROUTE_PREF_MEDIUM = 0,
NDP_ROUTE_PREF_HIGH = 1,
};
int ndp_msg_new(struct ndp_msg **p_msg, enum ndp_msg_type msg_type);
void ndp_msg_destroy(struct ndp_msg *msg);
void *ndp_msg_payload(struct ndp_msg *msg);
size_t ndp_msg_payload_maxlen(struct ndp_msg *msg);
size_t ndp_msg_payload_len(struct ndp_msg *msg);
void ndp_msg_payload_len_set(struct ndp_msg *msg, size_t len);
void *ndp_msg_payload_opts(struct ndp_msg *msg);
size_t ndp_msg_payload_opts_len(struct ndp_msg *msg);
struct ndp_msgrs *ndp_msgrs(struct ndp_msg *msg);
struct ndp_msgra *ndp_msgra(struct ndp_msg *msg);
struct ndp_msgns *ndp_msgns(struct ndp_msg *msg);
struct ndp_msgna *ndp_msgna(struct ndp_msg *msg);
struct ndp_msgr *ndp_msgr(struct ndp_msg *msg);
enum ndp_msg_type ndp_msg_type(struct ndp_msg *msg);
struct in6_addr *ndp_msg_addrto(struct ndp_msg *msg);
uint32_t ndp_msg_ifindex(struct ndp_msg *msg);
void ndp_msg_ifindex_set(struct ndp_msg *msg, uint32_t ifindex);
int ndp_msg_send(struct ndp *ndp, struct ndp_msg *msg);
int ndp_msg_send_with_flags(struct ndp *ndp, struct ndp_msg *msg, uint8_t flags);
uint8_t ndp_msgra_curhoplimit(struct ndp_msgra *msgra);
void ndp_msgra_curhoplimit_set(struct ndp_msgra *msgra, uint8_t curhoplimit);
bool ndp_msgra_flag_managed(struct ndp_msgra *msgra);
void ndp_msgra_flag_managed_set(struct ndp_msgra *msgra, bool flag_managed);
bool ndp_msgra_flag_other(struct ndp_msgra *msgra);
void ndp_msgra_flag_other_set(struct ndp_msgra *msgra, bool flag_other);
bool ndp_msgra_flag_home_agent(struct ndp_msgra *msgra);
void ndp_msgra_flag_home_agent_set(struct ndp_msgra *msgra,
bool flag_home_agent);
enum ndp_route_preference ndp_msgra_route_preference(struct ndp_msgra *msgra);
void ndp_msgra_route_preference_set(struct ndp_msgra *msgra,
enum ndp_route_preference pref);
uint16_t ndp_msgra_router_lifetime(struct ndp_msgra *msgra);
void ndp_msgra_router_lifetime_set(struct ndp_msgra *msgra,
uint16_t router_lifetime);
uint32_t ndp_msgra_reachable_time(struct ndp_msgra *msgra);
void ndp_msgra_reachable_time_set(struct ndp_msgra *msgra,
uint32_t reachable_time);
uint32_t ndp_msgra_retransmit_time(struct ndp_msgra *msgra);
void ndp_msgra_retransmit_time_set(struct ndp_msgra *msgra,
uint32_t retransmit_time);
bool ndp_msgna_flag_router(struct ndp_msgna *msgna);
void ndp_msgna_flag_router_set(struct ndp_msgna *msgna, bool flag_router);
bool ndp_msgna_flag_solicited(struct ndp_msgna *msgna);
void ndp_msgna_flag_solicited_set(struct ndp_msgna *msgna,
bool flag_solicited);
bool ndp_msgna_flag_override(struct ndp_msgna *msgna);
void ndp_msgna_flag_override_set(struct ndp_msgna *msgna, bool flag_override);
enum ndp_msg_opt_type {
NDP_MSG_OPT_SLLADDR, /* Source Link-layer Address */
NDP_MSG_OPT_TLLADDR, /* Target Link-layer Address */
NDP_MSG_OPT_PREFIX, /* Prefix Information */
NDP_MSG_OPT_REDIR, /* Redirected Header */
NDP_MSG_OPT_MTU, /* MTU */
NDP_MSG_OPT_ROUTE, /* Route Information */
NDP_MSG_OPT_RDNSS, /* Recursive DNS Server */
NDP_MSG_OPT_DNSSL, /* DNS Search List */
};
int ndp_msg_next_opt_offset(struct ndp_msg *msg, int offset,
enum ndp_msg_opt_type opt_type);
#define ndp_msg_opt_for_each_offset(offset, msg, type) \
for (offset = ndp_msg_next_opt_offset(msg, -1, type); \
offset != -1; \
offset = ndp_msg_next_opt_offset(msg, offset, type))
unsigned char *ndp_msg_opt_slladdr(struct ndp_msg *msg, int offset);
size_t ndp_msg_opt_slladdr_len(struct ndp_msg *msg, int offset);
unsigned char *ndp_msg_opt_tlladdr(struct ndp_msg *msg, int offset);
size_t ndp_msg_opt_tlladdr_len(struct ndp_msg *msg, int offset);
struct in6_addr *ndp_msg_opt_prefix(struct ndp_msg *msg, int offset);
uint8_t ndp_msg_opt_prefix_len(struct ndp_msg *msg, int offset);
uint32_t ndp_msg_opt_prefix_valid_time(struct ndp_msg *msg, int offset);
uint32_t ndp_msg_opt_prefix_preferred_time(struct ndp_msg *msg, int offset);
bool ndp_msg_opt_prefix_flag_on_link(struct ndp_msg *msg, int offset);
bool ndp_msg_opt_prefix_flag_auto_addr_conf(struct ndp_msg *msg, int offset);
bool ndp_msg_opt_prefix_flag_router_addr(struct ndp_msg *msg, int offset);
uint32_t ndp_msg_opt_mtu(struct ndp_msg *msg, int offset);
struct in6_addr *ndp_msg_opt_route_prefix(struct ndp_msg *msg, int offset);
uint8_t ndp_msg_opt_route_prefix_len(struct ndp_msg *msg, int offset);
uint32_t ndp_msg_opt_route_lifetime(struct ndp_msg *msg, int offset);
enum ndp_route_preference
ndp_msg_opt_route_preference(struct ndp_msg *msg, int offset);
uint32_t ndp_msg_opt_rdnss_lifetime(struct ndp_msg *msg, int offset);
struct in6_addr *ndp_msg_opt_rdnss_addr(struct ndp_msg *msg, int offset,
int addr_index);
#define ndp_msg_opt_rdnss_for_each_addr(addr, addr_index, msg, offset) \
for (addr_index = 0, \
addr = ndp_msg_opt_rdnss_addr(msg, offset, addr_index); \
addr; \
addr = ndp_msg_opt_rdnss_addr(msg, offset, ++addr_index))
uint32_t ndp_msg_opt_dnssl_lifetime(struct ndp_msg *msg, int offset);
char *ndp_msg_opt_dnssl_domain(struct ndp_msg *msg, int offset,
int domain_index);
#define ndp_msg_opt_dnssl_for_each_domain(domain, domain_index, msg, offset) \
for (domain_index = 0, \
domain = ndp_msg_opt_dnssl_domain(msg, offset, domain_index); \
domain; \
domain = ndp_msg_opt_dnssl_domain(msg, offset, ++domain_index))
typedef int (*ndp_msgrcv_handler_func_t)(struct ndp *ndp, struct ndp_msg *msg,
void *priv);
int ndp_msgrcv_handler_register(struct ndp *ndp, ndp_msgrcv_handler_func_t func,
enum ndp_msg_type msg_type, uint32_t ifindex,
void *priv);
void ndp_msgrcv_handler_unregister(struct ndp *ndp, ndp_msgrcv_handler_func_t func,
enum ndp_msg_type msg_type, uint32_t ifindex,
void *priv);
int ndp_get_eventfd(struct ndp *ndp);
int ndp_call_eventfd_handler(struct ndp *ndp);
int ndp_callall_eventfd_handler(struct ndp *ndp);
int ndp_open(struct ndp **p_ndp);
void ndp_close(struct ndp *ndp);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* _NDP_H_ */