/* Copyright 1986 by the Massachusetts Institute of Technology */
/* See permission and disclaimer notice in file notice.h */
#include	"notice.h"

/* Routing info */
#define iprte struct _iprte_st
iprte {
    iprte *ipr_link;		/* Hash bucket link */
    inaddr ipr_addr;		/* Net (or subnet) this route is for */
    inaddr ipr_subnet_mask;	/* Set to the subnet mask for this net
				   (or 0 if net is not subnetted) */
    inaddr ipr_gw;		/* Next hop gateway */
    inaddr ipr_src_gw;          /* GW which was the source of this route */
    net *ipr_netp;		/* Net of next hop gateway */
    unsl ipr_metric;		/* Metric of route */
    unsl ipr_time;		/* Time last updated */
    unsw ipr_autonomous_system; /* Autonomous system which generated this */
    unsb ipr_type;		/* Type of route (T_<foo> in src/const.h) */
    unsb ipr_owner;		/* Who manages this route */
    unsb ipr_flags;
    unsl ipr_usage;             /* How many times have we sent things out this
                                   way ... */
};

/* Owners */
#define O_NONE 0
#define O_EGP 1
#define O_RIP 2

/* Flags */
#define F_SUBNET 1		/* Route is a subnet */
#define F_MODIFIED 2		/* Route has been modified since last brdcst */
#define F_SILENT 4		/* Don't advertise this route */
#define F_EGP_PRIMARY 8         /* This came from a "primary" egp server */

/* These are for restrictions */
#define F_RES_SUBNET     1 /* Subnet restrictions */
#define F_ANNOUNCE       2 /* Announce this net */
#define F_DONT_ANNOUNCE    4 /* Don't announce this net */
#define F_LISTEN         8 /* Listen to announcements of this net */
#define F_DONT_LISTEN   16 /* Don't listen to announcements of this net */
#define F_RES_RIP       32 /* Restriction applies to RIP */
#define F_RES_EGP       64 /* Restriction applies to EGP */
#define F_SET_DEFAULT_METRIC 128
                           /* only used to set def metric for don't listen */

#define HASH_SIZE 256		/* Size of hash table (must be power of 2,
				 * HASH_SIZE - 1 is used as a mask).
				 * (Note: Due to the current hash
				 * algorithm, HASH_SIZE should *not*
				 * be changed.) */

/* Static init */
struct ipsrte {
    byte *sr_addr;
    byte *sr_gw;
    unsl sr_metric;
    bitl sr_flags;		/* For F_SILENT flag */
};

#define ipr_res_entry struct _ipr_res_entry_st

struct _ipr_res_entry_st {
  ipr_res_entry *link;	/* Hash bucket link */
  inaddr addr;		/* Net (or subnet) this route is for */
  inaddr subnet_mask;	/* Set to the subnet mask for this net
				   (or 0 if net is not subnetted) */
  unsl metric;
  bitl flags;
};

/* This has pointers for address and subnet and no link */
#define ipr_res_entry_init struct _ipr_res_entry_init_st

struct _ipr_res_entry_init_st {
  byte *addr;		/* Net (or subnet) this route is for */
  byte *subnet_mask;	/* Set to the subnet mask for this net
				   (or 0 if net is not subnetted) */
  unsl metric;      /* longs for alignment, ugh! */
  bitl flags;
};

/* Routing restrictions ... only per interface ... if we actually have
   a given type of restriction we'll allocate a HASH_SIZE array of
   ipr_res_bucket's ... */

#define ipr_res_table struct ipr_res

struct ipr_res {
  ipr_res_entry **table;
  ipr_res_entry **saved_table;
  int announce;
  int dont_announce;
  int listen; 
  int dont_listen;
  unsl default_metric;
};

/* Array of per interface routing restriction tables */
ext ipr_res_table *ipr_restrictions;

/* Used to initialize above. Contains a pointer (per-interface) to
   a chain of ipr_res_entry's */
ext ipr_res_entry_init *ipr_init_restrictions[];

ext iprte *ip_routes[];		/* Hash table of internet routes */
ext struct ipsrte iprte_sinit[]; /* Static route initialization table */
ext net *indefgi;		/* Default gw interface */
ext inaddr indefga;		/* Default gw address */
ext byte mask_table[8][4];	/* Network masks (indexed by top three
				 * bits of internet address) */

/* Macros.  After the code is debugged, what's in procedures and
 * what's in macros needs to be redone to reduce the number procedure
 * calls. */
#define IPR_NO_CREATE 0
#define IPR_CREATE 1
#define IPR_HOST_ROUTES 1
#define IPR_NO_HOST_ROUTES 0
#define ipr_lookup(addr) ipr_hash(addr, IPR_NO_CREATE, IPR_HOST_ROUTES)
#define ipr_make(addr) ipr_hash(addr, IPR_CREATE, IPR_HOST_ROUTES)
#define ipr_make_net(addr) ipr_hash(addr, IPR_CREATE, IPR_NO_HOST_ROUTES)
#define ipr_make1(addr) ipr_hash1(addr, IPR_CREATE)
#define is_subnet(ipr) ((ipr)->ipr_flags & F_SUBNET)
#define net_mask(addr) \
	(*(long *)mask_table[((addr)->i_byte.i_byteh & CLMSK) >> CLSHFT])

/* External functions */
ext iprte *ipr_hash(), *ipr_hash1();
ext ipr_res_entry *ipr_res_hash(), *ipr_res_hash1();

