#ifndef	RSPFPKTLEN
struct rspfpacketh {
    char version;
    char type;
    unsigned char fragn;
    unsigned char fragtot;
    int16 csum;
    unsigned char sync;
    unsigned char nodes;
    int16 envid;
};
#define RSPFPKTLEN	10
struct rspfnodeh {
    int32 addr;
    short seq;			/* 16 bit signed int */
    unsigned char subseq;
    unsigned char links;
};
#define RSPFNODELEN	8
struct rspflinkh {
    unsigned char horizon;
    unsigned char erp;
    unsigned char cost;
    unsigned char adjn;
};
#define RSPFLINKLEN	4
struct rspfrouter {
    struct rspfrouter *next;
    char sent;			/* True if the data has already been sent */
    char subseq;		/* Sub-sequence number of latest update */
    int32 time;			/* Time when data was last received */
    struct mbuf *data;		/* Latest data, starting with node header */
};
#define NULLRROUTER	(struct rspfrouter *)0
struct rspfreasm {
    struct rspfreasm *next;
    int32 addr;			/* Address of originating station */
    int32 time;			/* Time when a fragment was last received */
    struct mbuf *data;		/* A queue of fragments */
};
#define NULLRREASM	(struct rspfreasm *)0

#define RSPF_RTIME	30		/* Reassembly timeout in seconds */

/* RRH header, host format */
struct rrh {
    char version;
    char type;
    int16 csum;
    int32 addr;
    int16 seq;
    char flags;
#define RSPFMODE	1	/* Tells whether we want a VC link or not */
};
#define RRHLEN		11
union rspf {
    struct {
	char version;
#define RSPF_VERSION	21		/* Current version */
	char type;
#define RSPF_FULLPKT	1		/* Routing update */
#define RSPF_RRH	3		/* Router-Router Hello */
    } hdr;
    struct rspfpacketh pkthdr;
    struct rrh rrh;
};

#define RSPF_PROCMAX	5		/* Maximum number of processes handling
					   suspect adjacencies */

struct rspfadj {
    struct rspfadj *next;
    int32 addr;
    unsigned char cost;		/* Cost to reach this adjacency */
    int16 seq;			/* Number of AX.25 frames it has sent */
    int32 heard;		/* Number of heard AX.25 frames */
    struct timer timer;		/* Adjacency turns suspect if timer expires */
    char tos;			/* Preferred type of service */
    char added;			/* Used by the SPF algorithm */
    void *scratch;		/* also used by SPF (contains the interface) */
    struct proc *pinger;	/* Pointer to rspfping process */
    char state;
#define RSPF_TENTATIVE	0
#define RSPF_OK		1
#define RSPF_SUSPECT	2
#define RSPF_BAD	3
    int okcnt;			/* Times adjacency has entered OK state */
};
#define NULLADJ (struct rspfadj *)0

struct rspfiface {
    struct rspfiface *next;
    struct iface *iface;
    unsigned char quality;	/* Default quality for this interface */
    unsigned char horizon;	/* Default horizon value */
    unsigned char erp;		/* Default ERP factor */
};
#define NULLRIFACE (struct rspfiface *)0

struct rspf_stat {
     unsigned rrhin;		/* RRH's received */
     unsigned rrhout;		/* RRH's sent */
     unsigned updatein;		/* Updates received */
     unsigned updateout;	/* Updates sent */
     unsigned badcsum;		/* Bad checksums */
     unsigned badvers;		/* Bad versions */
     unsigned norspfiface;	/* RSPF packets from non RSPF interfaces */
     unsigned oldreport;	/* Node headers with old sequence numbers */
     unsigned outpolls;		/* Poll packets sent */
     unsigned noadjupdate;	/* Updates received from non-adjacencies */
};

/* Event types in main loop */
#define RSPFE_RRH	1	/* It is time to send a new RRH */
#define RSPFE_CHECK	2	/* An adjacency has becomed suspect */
#define RSPFE_UPDATE	3	/* Time to send a new routing updates */
#define RSPFE_ARP	4	/* An ARP reply was received */
#define RSPFE_PACKET	5	/* A packet was received (RRH or Update) */
     
extern struct rspf_stat Rspf_stat;
extern struct rspfreasm *Rspfreasmq;
extern struct rspfiface *Rspfifaces;
extern struct rspfadj *Adjs;
extern struct rspfrouter *Rspfrouters;
extern struct mbuf *Rspfinq;
extern struct timer Rspfreasmt, Susptimer;
extern char *Rrh_message;
extern int Rspfownmode;
extern unsigned short Rspfpingmax;

#ifdef __GNUC__
struct ip;			/* forward declarations */
struct pseudo_header;
#endif

void rspfmain __ARGS((int v,void *v1,void *v2));
void rspf_input __ARGS((struct iface *iface,struct ip *ip,struct mbuf *bp,int rxbroadcast));
void rspfarpupcall __ARGS((int32 addr,int16 hardware,struct iface *iface));
void rspfrouteupcall __ARGS((int32 addr,unsigned bits,int32 gateway));
void rspfevent __ARGS((void *t));
void rspfsuspect __ARGS((void *t));
struct mbuf *makeownupdate __ARGS((int32 dest,int new));
int ntohrspf __ARGS((union rspf *rspf,struct mbuf **bpp));
int ntohrspfnode __ARGS((struct rspfnodeh *nodeh,struct mbuf **bpp));
int ntohrspflink __ARGS((struct rspflinkh *linkh,struct mbuf **bpp));
struct mbuf *htonrrh __ARGS((struct rrh *rrh,struct mbuf *data,struct pseudo_header *ph));
struct mbuf *htonrspf __ARGS((struct rspfpacketh *pkth,struct mbuf *data));
struct mbuf *htonrspfnode __ARGS((struct rspfnodeh *nodeh,struct mbuf *data));
struct mbuf *htonrspflink __ARGS((struct rspflinkh *linkh,struct mbuf *data));
/* #ifdef MONITOR
void rspfnodedump __ARGS((FILE *fp,struct mbuf **bpp,int adjcnt,int mon));
#else */
void rspfnodedump __ARGS((FILE *fp,struct mbuf **bpp,int adjcnt));
/* #endif */
#endif
