#include <stdbool.h>
#define ELM_MALLOC(p,error_action) \
do { \
p = malloc(sizeof(*p)); \
if (p == NULL) { \
syslog(LOG_ERR, "<%s> malloc failed: %s", \
__func__, strerror(errno)); \
error_action; \
} \
memset(p, 0, sizeof(*p)); \
} while(0)
#define IN6ADDR_LINKLOCAL_ALLNODES_INIT \
{{{ 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }}}
#define IN6ADDR_LINKLOCAL_ALLROUTERS_INIT \
{{{ 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 }}}
#define IN6ADDR_SITELOCAL_ALLROUTERS_INIT \
{{{ 0xff, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 }}}
extern struct sockaddr_in6 sin6_linklocal_allnodes;
extern struct sockaddr_in6 sin6_linklocal_allrouters;
extern struct sockaddr_in6 sin6_sitelocal_allrouters;
#ifndef IPV6_RECVPKTINFO
#ifdef IPV6_PKTINFO
#define IPV6_RECVPKTINFO IPV6_PKTINFO
#endif
#endif
#ifndef IPV6_RECVHOPLIMIT
#ifdef IPV6_HOPLIMIT
#define IPV6_RECVHOPLIMIT IPV6_HOPLIMIT
#endif
#endif
#define DEF_MAXRTRADVINTERVAL 600
#define DEF_ADVLINKMTU 0
#define DEF_ADVREACHABLETIME 0
#define DEF_ADVRETRANSTIMER 0
#define DEF_ADVCURHOPLIMIT 64
#define DEF_ADVVALIDLIFETIME 2592000
#define DEF_ADVPREFERREDLIFETIME 604800
#define MAXROUTERLIFETIME 9000
#define MIN_MAXINTERVAL 4
#define MAX_MAXINTERVAL 1800
#define MIN_MININTERVAL 3
#define MAXREACHABLETIME 3600000
#define MAX_INITIAL_RTR_ADVERT_INTERVAL 16
#define MAX_INITIAL_RTR_ADVERTISEMENTS 3
#define MAX_FINAL_RTR_ADVERTISEMENTS 3
#define MIN_DELAY_BETWEEN_RAS 3
#define MAX_RA_DELAY_TIME 500000
#define PREFIX_FROM_KERNEL 1
#define PREFIX_FROM_CONFIG 2
#define PREFIX_FROM_DYNAMIC 3
struct prefix {
TAILQ_ENTRY(prefix) pfx_next;
struct rainfo *pfx_rainfo;
struct rtadvd_timer *pfx_timer;
uint32_t pfx_validlifetime;
uint32_t pfx_vltimeexpire;
uint32_t pfx_preflifetime;
uint32_t pfx_pltimeexpire;
int pfx_onlinkflg;
int pfx_autoconfflg;
int pfx_prefixlen;
int pfx_origin;
struct in6_addr pfx_prefix;
};
struct rtinfo {
TAILQ_ENTRY(rtinfo) rti_next;
uint32_t rti_ltime;
int rti_rtpref;
int rti_prefixlen;
struct in6_addr rti_prefix;
};
struct rdnss_addr {
TAILQ_ENTRY(rdnss_addr) ra_next;
struct in6_addr ra_dns;
};
struct rdnss {
TAILQ_ENTRY(rdnss) rd_next;
TAILQ_HEAD(, rdnss_addr) rd_list;
uint32_t rd_ltime;
};
struct pref64 {
TAILQ_ENTRY(pref64) p64_next;
uint16_t p64_plc;
uint16_t p64_sl;
struct in6_addr p64_prefix;
};
#define _DNAME_LABELENC_MAXLEN \
(NI_MAXHOST + (NI_MAXHOST / 64 + 1) + 1)
#define DNAME_LABELENC_MAXLEN \
(_DNAME_LABELENC_MAXLEN + 8 - _DNAME_LABELENC_MAXLEN % 8)
struct dnssl_addr {
TAILQ_ENTRY(dnssl_addr) da_next;
int da_len;
char da_dom[DNAME_LABELENC_MAXLEN];
};
struct dnssl {
TAILQ_ENTRY(dnssl) dn_next;
TAILQ_HEAD(, dnssl_addr) dn_list;
uint32_t dn_ltime;
};
struct soliciter {
TAILQ_ENTRY(soliciter) sol_next;
struct sockaddr_in6 sol_addr;
};
struct rainfo {
TAILQ_ENTRY(rainfo) rai_next;
struct ifinfo *rai_ifinfo;
int rai_advlinkopt;
int rai_advifprefix;
uint16_t rai_lifetime;
uint16_t rai_maxinterval;
uint16_t rai_mininterval;
int rai_managedflg;
int rai_otherflg;
#ifdef DRAFT_IETF_6MAN_IPV6ONLY_FLAG
int rai_ipv6onlyflg;
#endif
int rai_rtpref;
uint32_t rai_linkmtu;
uint32_t rai_reachabletime;
uint32_t rai_retranstimer;
uint8_t rai_hoplimit;
TAILQ_HEAD(, prefix) rai_prefix;
int rai_pfxs;
uint16_t rai_clockskew;
TAILQ_HEAD(, rdnss) rai_rdnss;
TAILQ_HEAD(, dnssl) rai_dnssl;
TAILQ_HEAD(, rtinfo) rai_route;
int rai_routes;
size_t rai_ra_datalen;
char *rai_ra_data;
TAILQ_HEAD(, pref64) rai_pref64;
TAILQ_HEAD(, soliciter) rai_soliciter;
};
extern TAILQ_HEAD(railist_head_t, rainfo) railist;
#define IFI_STATE_UNCONFIGURED 0
#define IFI_STATE_CONFIGURED 1
#define IFI_STATE_TRANSITIVE 2
struct ifinfo {
TAILQ_ENTRY(ifinfo) ifi_next;
uint16_t ifi_state;
uint16_t ifi_persist;
uint16_t ifi_ifindex;
char ifi_ifname[IFNAMSIZ];
uint8_t ifi_type;
uint16_t ifi_flags;
uint32_t ifi_nd_flags;
uint32_t ifi_phymtu;
struct sockaddr_dl ifi_sdl;
struct rainfo *ifi_rainfo;
struct rainfo *ifi_rainfo_trans;
uint16_t ifi_burstcount;
uint32_t ifi_burstinterval;
struct rtadvd_timer *ifi_ra_timer;
struct timespec ifi_ra_lastsent;
uint16_t ifi_rs_waitcount;
uint64_t ifi_raoutput;
uint64_t ifi_rainput;
uint64_t ifi_rainconsistent;
uint64_t ifi_rsinput;
};
extern TAILQ_HEAD(ifilist_head_t, ifinfo) ifilist;
extern char *mcastif;
struct rtadvd_timer *ra_timeout(void *);
void ra_timer_update(void *, struct timespec *);
void ra_output(struct ifinfo *);
int prefix_match(struct in6_addr *, int,
struct in6_addr *, int);
struct ifinfo *if_indextoifinfo(int);
struct prefix *find_prefix(struct rainfo *,
struct in6_addr *, int);
void rtadvd_set_reload(int);
void rtadvd_set_shutdown(int);