#ifndef _DEFS_H
#define _DEFS_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdio.h>
#include <netdb.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <stdarg.h>
#include <syslog.h>
#include <time.h>
#include <md5.h>
#include <libintl.h>
#include <locale.h>
#include "radix.h"
#include <sys/time.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/sysmacros.h>
#include <net/if.h>
#include <net/route.h>
#include <net/if_dl.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define RIPVERSION RIPv2
#include <protocols/routed.h>
#define DAY (24*60*60)
#define NEVER DAY
#define EPOCH NEVER
#define CHECK_BAD_INTERVAL 5
#define CHECK_ACT_INTERVAL 30
#define CHECK_QUIET_INTERVAL 300
#define LIM_SEC(s, l) ((s).tv_sec = MIN((s).tv_sec, (l)))
#define FAKE_METRIC (HOPCNT_INFINITY-2)
#define MAX_MAXADVERTISEINTERVAL 1800
#define MIN_MAXADVERTISEINTERVAL 4
#define DEF_MAXADVERTISEINTERVAL 600
#define DEF_PREFERENCELEVEL 0
#define MIN_PREFERENCELEVEL 0x80000000
#define MAX_INITIAL_ADVERT_INTERVAL 16
#define MAX_INITIAL_ADVERTS 3
#define MAX_RESPONSE_DELAY 2
#define MAX_SOLICITATION_DELAY 1
#define SOLICITATION_INTERVAL 3
#define MAX_SOLICITATIONS 3
#define SIGN_PREF(p) ((p) ^ MIN_PREFERENCELEVEL)
#define UNSIGN_PREF(p) SIGN_PREF(p)
#define OVER_MAXPACKETSIZE (MAXPACKETSIZE+sizeof (struct netinfo)*2)
union pkt_buf {
uint8_t packet[OVER_MAXPACKETSIZE*2];
struct rip rip;
};
extern struct dr *drs;
#define IF_NAME_LEN (MAXHOSTNAMELEN + sizeof ("remote()") + 1)
#define MAX_ROUTES (128*1024)
enum origin {
RO_NONE,
RO_RIP,
RO_RDISC,
RO_STATIC,
RO_LOOPBCK,
RO_PTOPT,
RO_NET_SYN,
RO_IF,
RO_FILE
};
struct rt_spare {
struct interface *rts_ifp;
uint32_t rts_gate;
uint32_t rts_router;
uint8_t rts_metric;
enum origin rts_origin;
uint16_t rts_tag;
time_t rts_time;
uint32_t rts_de_ag;
uint16_t rts_flags;
};
#define RTS_EXTERNAL 0x0001
#define SPARE_INC 2
#define EMPTY_RT_SPARE { NULL, 0, 0, HOPCNT_INFINITY, RO_NONE, 0, 0, 0, 0 }
struct rt_entry {
struct radix_node rt_nodes[2];
struct sockaddr_in rt_dst_sock;
time_t rt_poison_time;
in_addr_t rt_mask;
uint32_t rt_seqno;
uint16_t rt_state;
#define RS_IF 0x0001
#define RS_NET_INT 0x0002
#define RS_NET_SYN 0x0004
#define RS_NO_NET_SYN (RS_LOCAL | RS_IF)
#define RS_SUBNET 0x0008
#define RS_LOCAL 0x0010
#define RS_MHOME 0x0020
#define RS_STATIC 0x0040
#define RS_NOPROPAGATE 0x0080
#define RS_BADIF 0x0100
uint8_t rt_poison_metric;
uint_t rt_num_spares;
struct rt_spare *rt_spares;
};
#define rt_dst rt_dst_sock.sin_addr.s_addr
#define rt_ifp rt_spares[0].rts_ifp
#define rt_gate rt_spares[0].rts_gate
#define rt_router rt_spares[0].rts_router
#define rt_metric rt_spares[0].rts_metric
#define rt_tag rt_spares[0].rts_tag
#define rt_time rt_spares[0].rts_time
#define rt_de_ag rt_spares[0].rts_de_ag
#define HOST_MASK 0xffffffffU
#define RT_ISHOST(rt) ((rt)->rt_mask == HOST_MASK)
#define AGE_RT(rt_state, rts_origin, ifp) \
((!((rt_state) & (RS_MHOME | RS_STATIC | RS_NET_SYN)) && \
(rts_origin != RO_RDISC) && \
(rts_origin != RO_FILE)) && \
(!((rt_state) & RS_IF) || \
(ifp) == NULL || \
(((ifp)->int_state & IS_REMOTE) && \
!((ifp)->int_state & IS_PASSIVE))))
#define BETTER_LINK(rt, A, B) ((A)->rts_metric < HOPCNT_INFINITY && \
now_stale <= (A)->rts_time && \
((A)->rts_metric < (B)->rts_metric || \
((A)->rts_gate == (A)->rts_router && \
(B)->rts_gate != (B)->rts_router) || \
((A)->rts_metric == (B)->rts_metric && \
now_stale > (B)->rts_time) || \
(RT_ISHOST(rt) && \
(rt)->rt_dst == (A)->rts_router && \
(A)->rts_metric == (B)->rts_metric)))
struct hlinkage {
void *hl_next;
void **hl_prev;
};
struct physical_interface {
struct hlinkage phyi_link;
uint32_t phyi_index;
struct interface *phyi_interface;
struct phyi_data {
uint32_t ipackets;
uint32_t ierrors;
uint32_t opackets;
uint32_t oerrors;
time_t ts;
} phyi_data;
char phyi_name[IF_NAME_LEN+1];
};
struct interface {
struct hlinkage int_link;
#define int_next int_link.hl_next
struct hlinkage int_ahash;
struct hlinkage int_bhash;
struct hlinkage int_nhash;
struct hlinkage int_ilist;
struct physical_interface *int_phys;
char int_name[IF_NAME_LEN+1];
in_addr_t int_addr;
in_addr_t int_brdaddr;
in_addr_t int_dstaddr;
in_addr_t int_net;
in_addr_t int_mask;
in_addr_t int_ripv1_mask;
in_addr_t int_std_addr;
in_addr_t int_std_net;
in_addr_t int_std_mask;
in_addr_t int_ripout_addr;
uint64_t int_if_flags;
uint32_t int_state;
time_t int_act_time;
time_t int_query_time;
uint32_t int_transitions;
uint8_t int_metric;
uint8_t int_d_metric;
#define MAX_AUTH_KEYS 5
struct auth {
time_t start, end;
uint16_t type;
uint8_t key[RIP_AUTH_PW_LEN +1];
uint8_t keyid;
uint8_t warnedflag;
} int_auth[MAX_AUTH_KEYS];
int int_rdisc_pref;
uint32_t int_rdisc_int;
uint32_t int_rdisc_cnt;
struct timeval int_rdisc_timer;
};
#define IS_ALIAS 0x00000001
#define IS_SUBNET 0x00000002
#define IS_REMOTE 0x00000004
#define IS_PASSIVE 0x00000008
#define IS_EXTERNAL 0x00000010
#define IS_CHECKED 0x00000020
#define IS_ALL_HOSTS 0x00000040
#define IS_ALL_ROUTERS 0x00000080
#define IS_DISTRUST 0x00000100
#define IS_REDIRECT_OK 0x00000200
#define IS_BROKE 0x00000400
#define IS_SICK 0x00000800
#define IS_DUP 0x00001000
#define IS_NEED_NET_SYN 0x00002000
#define IS_NO_AG 0x00004000
#define IS_NO_SUPER_AG 0x00008000
#define IS_NO_RIPV1_IN 0x00010000
#define IS_NO_RIPV2_IN 0x00020000
#define IS_NO_RIP_IN (IS_NO_RIPV1_IN | IS_NO_RIPV2_IN)
#define IS_RIP_IN_OFF(s) (((s) & IS_NO_RIP_IN) == IS_NO_RIP_IN)
#define IS_NO_RIPV1_OUT 0x00040000
#define IS_NO_RIPV2_OUT 0x00080000
#define IS_NO_RIP_OUT (IS_NO_RIPV1_OUT | IS_NO_RIPV2_OUT)
#define IS_NO_RIP (IS_NO_RIP_OUT | IS_NO_RIP_IN)
#define IS_RIP_OUT_OFF(s) (((s) & IS_NO_RIP_OUT) == IS_NO_RIP_OUT)
#define IS_RIP_OFF(s) (((s) & IS_NO_RIP) == IS_NO_RIP)
#define IS_NO_RIP_MCAST 0x00100000
#define IS_NO_ADV_IN 0x00200000
#define IS_NO_SOL_OUT 0x00400000
#define IS_SOL_OUT 0x00800000
#define GROUP_IS_SOL_OUT (IS_SOL_OUT | IS_NO_SOL_OUT)
#define IS_NO_ADV_OUT 0x01000000
#define IS_ADV_OUT 0x02000000
#define GROUP_IS_ADV_OUT (IS_NO_ADV_OUT | IS_ADV_OUT)
#define IS_BCAST_RDISC 0x04000000
#define IS_NO_RDISC (IS_NO_ADV_IN | IS_NO_SOL_OUT | IS_NO_ADV_OUT)
#define IS_PM_RDISC 0x08000000
#define IS_NO_HOST 0x10000000
#define IS_SUPPRESS_RDISC 0x20000000
#define IS_FLUSH_RDISC 0x40000000
#define IS_PASSIVE_IFP(ifp) \
(((ifp)->int_state & (IS_REMOTE|IS_PASSIVE|IS_EXTERNAL|IS_ALIAS)) == \
(IS_REMOTE|IS_PASSIVE))
#define IS_IFF_UP(f) (((f) & (IFF_UP|IFF_RUNNING)) == (IFF_UP|IFF_RUNNING))
#define IS_IFF_QUIET(f) ((f) & (IFF_LOOPBACK|IFF_NORTEXCH|IFF_NOXMIT))
#define IS_IFF_ROUTING(f) \
(((f) & IFF_ROUTER) && !((f) & (IFF_NORTEXCH|IFF_NOXMIT)))
#define NUM_AG_SLOTS 32
struct ag_info {
struct ag_info *ag_fine;
struct ag_info *ag_cors;
in_addr_t ag_dst_h;
in_addr_t ag_mask;
in_addr_t ag_gate;
struct interface *ag_ifp;
in_addr_t ag_nhop;
uint8_t ag_metric;
uint8_t ag_pref;
uint32_t ag_seqno;
uint16_t ag_tag;
uint16_t ag_state;
#define AGS_SUPPRESS 0x001
#define AGS_AGGREGATE 0x002
#define AGS_REDUN0 0x004
#define AGS_REDUN1 0x008
#define AG_IS_REDUN(state) (((state) & (AGS_REDUN0 | AGS_REDUN1)) \
== (AGS_REDUN0 | AGS_REDUN1))
#define AGS_GATEWAY 0x010
#define AGS_IF 0x020
#define AGS_RIPV2 0x040
#define AGS_FINE_GATE 0x080
#define AGS_CORS_GATE 0x100
#define AGS_SPLIT_HZ 0x200
#define AGS_PASSIVE 0x400
#define AGS_FILE 0x800
#define AGS_AGGREGATE_EITHER (AGS_RIPV2 | AGS_GATEWAY | \
AGS_SUPPRESS | AGS_CORS_GATE)
};
struct khash {
struct khash *k_next;
in_addr_t k_dst;
in_addr_t k_mask;
in_addr_t k_gate;
struct interface *k_ifp;
short k_metric;
ushort_t k_state;
time_t k_keep;
time_t k_redirect_time;
};
#define KS_NEW 0x0001
#define KS_DELETE 0x0002
#define KS_ADD 0x0004
#define KS_CHANGE 0x0008
#define KS_DEL_ADD 0x0010
#define KS_STATIC 0x0020
#define KS_GATEWAY 0x0040
#define KS_DYNAMIC 0x0080
#define KS_DELETED 0x0100
#define KS_PRIVATE 0x0200
#define KS_CHECK 0x0400
#define KS_IF 0x0800
#define KS_PASSIVE 0x1000
#define KS_DEPRE_IF 0x2000
#define KS_FILE 0x4000
struct dr {
struct interface *dr_ifp;
in_addr_t dr_gate;
time_t dr_ts;
time_t dr_life;
uint32_t dr_recv_pref;
uint32_t dr_pref;
uint32_t dr_flags;
#define DR_CHANGED 1
};
struct parm {
struct parm *parm_next;
in_addr_t parm_net;
in_addr_t parm_mask;
in_addr_t parm_ripout_addr;
uint32_t parm_int_state;
int32_t parm_rdisc_pref;
uint32_t parm_rdisc_int;
struct auth parm_auth[MAX_AUTH_KEYS];
char parm_name[IF_NAME_LEN+1];
uint8_t parm_d_metric;
};
extern struct intnet {
struct intnet *intnet_next;
in_addr_t intnet_addr;
in_addr_t intnet_mask;
int8_t intnet_metric;
} *intnets;
extern struct r1net {
struct r1net *r1net_next;
in_addr_t r1net_net;
in_addr_t r1net_match;
in_addr_t r1net_mask;
} *r1nets;
extern struct tgate {
struct tgate *tgate_next;
in_addr_t tgate_addr;
#define MAX_TGATE_NETS 32
struct tgate_net {
in_addr_t net;
in_addr_t mask;
} tgate_nets[MAX_TGATE_NETS];
} *tgates;
enum output_type {OUT_QUERY, OUT_UNICAST, OUT_BROADCAST, OUT_MULTICAST,
NO_OUT_MULTICAST, NO_OUT_RIPV2};
extern struct ws_buf {
struct rip *buf;
struct netinfo *n;
struct netinfo *base;
struct netinfo *lim;
enum output_type type;
} v12buf;
extern int stopint;
extern int rip_sock;
extern struct interface *rip_sock_interface;
extern int rt_sock;
extern int rdisc_sock;
extern int rdisc_mib_sock;
extern boolean_t rip_enabled;
extern boolean_t supplier;
extern boolean_t supplier_set;
extern boolean_t save_space;
extern boolean_t ridhosts;
extern boolean_t mhome;
extern boolean_t advertise_mhome;
extern boolean_t auth_ok;
extern boolean_t no_install;
extern struct timeval clk;
extern struct timeval epoch;
extern struct timeval now;
extern time_t now_stale;
extern time_t now_expire;
extern time_t now_garbage;
extern struct timeval age_timer;
extern struct timeval no_flash;
extern struct timeval rdisc_timer;
extern boolean_t rdisc_ok;
extern struct timeval ifscan_timer;
extern in_addr_t loopaddr;
extern uint_t tot_interfaces;
extern uint_t rip_interfaces;
extern uint_t ripout_interfaces;
extern uint_t fwd_interfaces;
extern struct interface *ifnet;
extern size_t hash_table_sizes[];
extern boolean_t have_ripv1_out;
extern boolean_t need_flash;
extern struct timeval need_kern;
extern uint32_t update_seqno;
extern struct interface dummy_ifp;
extern int tracelevel, new_tracelevel;
#define MAX_TRACELEVEL 5
#define TRACERTS (tracelevel >= 5)
#define TRACEKERNEL (tracelevel >= 4)
#define TRACECONTENTS (tracelevel >= 3)
#define TRACEPACKETS (tracelevel >= 2)
#define TRACEACTIONS (tracelevel != 0)
extern FILE *ftrace;
extern char inittracename[MAXPATHLEN+1];
extern struct radix_node_head *rhead;
extern void fix_sock(int, const char *);
extern void fix_select(void);
extern void rip_off(void);
extern void rip_on(struct interface *);
extern void bufinit(void);
extern int output(enum output_type, struct sockaddr_in *,
struct interface *, struct rip *, int);
extern void clr_ws_buf(struct ws_buf *, struct auth *);
extern void rip_query(void);
extern void rip_bcast(int);
extern void supply(struct sockaddr_in *, struct interface *,
enum output_type, int, int, boolean_t);
extern void msglog(const char *, ...);
extern void writelog(int, const char *, ...);
struct msg_limit {
time_t reuse;
struct msg_sub {
in_addr_t addr;
time_t until;
#define MSG_SUBJECT_N 8
} subs[MSG_SUBJECT_N];
};
extern void msglim(struct msg_limit *, in_addr_t, const char *, ...);
#define LOGERR(msg) msglog(msg ": %s", rip_strerror(errno))
extern void logbad(boolean_t, const char *, ...);
#define BADERR(dump, msg) logbad(dump, msg ": %s", rip_strerror(errno))
#ifdef DEBUG
#define DBGERR(dump, msg) BADERR(dump, msg)
#else
#define DBGERR(dump, msg) LOGERR(msg)
#endif
extern char *naddr_ntoa(in_addr_t);
extern const char *saddr_ntoa(struct sockaddr_storage *);
extern const char *rip_strerror(int errnum);
extern char *if_bit_string(uint_t, boolean_t);
extern void *rtmalloc(size_t, const char *);
extern void timevaladd(struct timeval *, struct timeval *);
extern void intvl_random(struct timeval *, ulong_t, ulong_t);
extern boolean_t getnet(const char *, in_addr_t *, in_addr_t *);
extern int gethost(char *, in_addr_t *);
extern void gwkludge(void);
extern const char *parse_parms(char *, boolean_t);
extern const char *insert_parm(struct parm *);
extern void get_parms(struct interface *);
extern void lastlog(void);
extern void trace_close(int);
extern void set_tracefile(const char *, const char *, int);
extern void tracelevel_msg(const char *, int);
extern void trace_off(const char *, ...);
extern void set_tracelevel(void);
extern void trace_flush(void);
extern void trace_misc(const char *, ...);
extern void trace_act(const char *, ...);
extern void trace_pkt(const char *, ...);
extern void trace_add_del(const char *, struct rt_entry *);
extern void trace_change(struct rt_entry *, uint16_t, struct rt_spare *,
const char *);
extern void trace_if(const char *, struct interface *);
extern void trace_khash(const struct khash *);
extern void trace_dr(const struct dr *);
extern void trace_upslot(struct rt_entry *, struct rt_spare *,
struct rt_spare *);
extern void trace_rip(const char *, const char *, struct sockaddr_in *,
struct interface *, struct rip *, int);
extern char *addrname(in_addr_t, in_addr_t, int);
extern char *rtname(in_addr_t, in_addr_t, in_addr_t);
extern void rdisc_age(in_addr_t);
extern void set_rdisc_mg(struct interface *, int);
extern void set_supplier(void);
extern void if_bad_rdisc(struct interface *);
extern void if_rewire_rdisc(struct interface *, struct interface *);
extern void if_ok_rdisc(struct interface *);
extern int read_rip(void);
extern void input_route(in_addr_t, in_addr_t, struct rt_spare *,
struct netinfo *, uint16_t);
extern void read_rt(void);
extern void read_d(void);
extern void process_d_mib_sock(void);
extern void rdisc_adv(boolean_t);
extern void rdisc_sol(void);
extern struct interface *receiving_interface(struct msghdr *, boolean_t);
extern void *find_ancillary(struct msghdr *, int);
extern boolean_t should_supply(struct interface *);
extern void rdisc_dump(void);
extern void rdisc_suppress(struct interface *);
extern void rdisc_restore(struct interface *);
extern void age_peer_info(void);
extern void sigtrace_more(int);
extern void sigtrace_less(int);
extern void sigtrace_dump(int);
extern void sync_kern(void);
extern void age(in_addr_t);
extern void kern_dump(void);
extern void kern_flush_ifp(struct interface *);
extern void kern_rewire_ifp(struct interface *, struct interface *);
extern void ag_flush(in_addr_t, in_addr_t, void (*)(struct ag_info *));
extern void ag_check(in_addr_t, in_addr_t, in_addr_t, struct interface *,
in_addr_t, uint8_t, uint8_t, uint32_t, uint16_t, uint16_t,
void (*)(struct ag_info *));
extern void del_static(in_addr_t, in_addr_t, in_addr_t,
struct interface *, int);
extern void del_redirects(in_addr_t, time_t);
extern struct rt_entry *rtget(in_addr_t, in_addr_t);
extern struct rt_entry *rtfind(in_addr_t);
extern void rtinit(void);
extern void rtadd(in_addr_t, in_addr_t, uint16_t, struct rt_spare *);
extern void rtchange(struct rt_entry *, uint16_t, struct rt_spare *,
char *);
extern void rtdelete(struct rt_entry *);
extern void rts_delete(struct rt_entry *, struct rt_spare *);
extern void rtbad_sub(struct rt_entry *, struct interface *);
extern void rtswitch(struct rt_entry *, struct rt_spare *);
#define S_ADDR(x) (((struct sockaddr_in *)(x))->sin_addr.s_addr)
#define INFO_DST(I) ((I)->rti_info[RTAX_DST])
#define INFO_GATE(I) ((I)->rti_info[RTAX_GATEWAY])
#define INFO_MASK(I) ((I)->rti_info[RTAX_NETMASK])
#define INFO_AUTHOR(I) ((I)->rti_info[RTAX_AUTHOR])
struct rewire_data {
struct interface *if_old;
struct interface *if_new;
int metric_delta;
};
extern char *qstring(const uchar_t *, int);
extern in_addr_t std_mask(in_addr_t);
extern int parse_quote(char **, const char *, char *, char *, int);
extern in_addr_t ripv1_mask_net(in_addr_t, const struct interface *);
extern in_addr_t ripv1_mask_host(in_addr_t, const struct interface *);
#define on_net(a, net, mask) (((ntohl(a) ^ (net)) & (mask)) == 0)
extern boolean_t check_dst(in_addr_t);
extern boolean_t remote_address_ok(struct interface *, in_addr_t);
extern struct interface *check_dup(const char *, in_addr_t, in_addr_t,
in_addr_t, uint64_t, boolean_t);
extern boolean_t check_remote(struct interface *);
extern void iftbl_alloc(void);
extern void ifscan(void);
extern int walk_bad(struct radix_node *, void *);
extern int walk_rewire(struct radix_node *, void *);
extern void if_ok(struct interface *, const char *, boolean_t);
extern void if_sick(struct interface *, boolean_t);
extern void if_link(struct interface *, uint32_t);
extern struct interface *ifwithaddr(in_addr_t, boolean_t, boolean_t);
extern struct interface *ifwithindex(ulong_t, boolean_t);
extern struct interface *ifwithname(const char *);
extern struct physical_interface *phys_byname(const char *);
extern boolean_t addr_on_ifp(in_addr_t, struct interface *,
struct interface **);
extern struct interface *findremoteif(in_addr_t);
extern struct interface *findifaddr(in_addr_t);
extern struct interface *iflookup(in_addr_t);
extern struct auth *find_auth(struct interface *);
extern void end_md5_auth(struct ws_buf *, struct auth *);
extern void rip_mcast_on(struct interface *);
extern void rip_mcast_off(struct interface *);
extern void trace_dump();
extern int sendtoif(int, const void *, uint_t, uint_t, struct sockaddr_in *,
uint_t);
#ifdef __cplusplus
}
#endif
#endif