/* ospf_lsa.h: Data type defintions and constants for OSPF */
/* Link State Advertisement package.                       */

/* Prevent multiple includes */
#ifndef			HEADER_FILE_ospf_lsa_h

#define			HEADER_FILE_ospf_lsa_h

/* OspfT_Lsa_Type: OSPF Link State Advertisement Type. */
typedef enum OspfT_Lsa_Type
	{
	OspfC_Lsa_Router_Links = 1,
	OspfC_Lsa_Network_Links,
	OspfC_Lsa_Summary_Links
	} OspfT_Lsa_Type;

/* OspfT_Lsa_Header: OSPF Link State Advertisement Header. */
typedef struct OspfT_Lsa_Header
	{
	double						age;			/* Time in seconds since the LSA was originated. */
	OspfT_Lsa_Type				type;			/* Type of LSA. */
	IpT_Address					link_state_id;	/* Identifies network environment being described by LSA. */
	OspfT_Router_Id				router_id;		/* Router that originated the LSA. */
	int							sequence_num;	/* Sequence number; used for identfying duplicate LSAs. */
	int							num_retrans;	/* Number of times LSA has been retransmitted. */
	} OspfT_Lsa_Header;

/* OspfT_Lsa_Router_Link_Type: Type of router link being described. */
typedef enum OspfT_Lsa_Router_Link_Type
	{
	OspfC_Lsa_Router_Link_Point_To_Point,
	OspfC_Lsa_Router_Link_Transit_Net,
	OspfC_Lsa_Router_Link_Stub_Net
	} OspfT_Lsa_Router_Link_Type;

/* OspfT_Lsa_Router_Links_Info: Specific information about links in a router links advertisement. */
typedef struct OspfT_Lsa_Router_Links_Info
	{	
	IpT_Address					link_id;		/* Identifies object router link connects to. */
	IpT_Address					link_data;		/* Further information identifying object router link connects to. */
	OspfT_Lsa_Router_Link_Type	link_type;		/* Type of router link. */
	int							link_cost;		/* Cost of using this outbound link. */
	} OspfT_Lsa_Router_Links_Info;

/* OspfT_Lsa_Router_Links: Data specific to router links advertisements. */
typedef struct OspfT_Lsa_Router_Links
	{
	Boolean				is_asbr;		/* Flag denoting whether router is an AS boundary router. */
	Boolean				is_abr;			/* Flag denoting whether router is an area border router. */
	List *				link_list_ptr;  /* List of (OspfT_Lsa_Router_Links_Info *); info about attached links. */
	} OspfT_Lsa_Router_Links;

/* OspfT_Lsa_Network_Links: Data specific to network links advertisements. */
typedef struct OspfT_Lsa_Network_Links
	{
	IpT_Address		network_mask;		/* IP address mask for this network. */
	List *			router_list_ptr; 	/* List of attached routers (type int); identfied by router ID. */
	} OspfT_Lsa_Network_Links;

/* OspfT_Lsa_Summary_Links: Data specific to summary links advertisements (type 3). */
typedef struct OspfT_Lsa_Summary_Links
	{
	IpT_Address					network_mask;		/* IP address mask for this network. */
	int							network_cost;		/* Cost to get to network from advertising router. */
	} OspfT_Lsa_Summary_Links;

/* OspfT_Lsa: OSPF Link State Advertisement. */
typedef struct OspfT_Lsa
	{
	OspfT_Lsa_Header *	lsa_header_ptr;				/* LSA header. */
	double				timestamp;					/* Time LSA was created. */
	Boolean				replace;					/* Indicates whether LSA is slated for replacement. */
	int					rxmt_count;					/* Number of times this LSA appears on a retransmission list. */
	union											/* Type-specific information for LSA. */
		{	
		OspfT_Lsa_Router_Links *	lsa_router_links_ptr;
		OspfT_Lsa_Network_Links *	lsa_network_links_ptr;
		OspfT_Lsa_Summary_Links *	lsa_summary_links_ptr;
		}				lsa_data;
	} OspfT_Lsa;

/***** Procedure Declarations *****/
OspfT_Lsa_Type				ospf_lsa_type_get (OspfT_Lsa *lsa_ptr);
OspfT_Lsa *					ospf_lsa_area_lookup (OspfT_Area *area_ptr, IpT_Address link_state_id, IpT_Address adv_router_id, OspfT_Lsa_Type lsa_type);
OspfT_Lsa *					ospf_lsa_lookup (List *lsa_list_ptr, IpT_Address link_state_id, IpT_Address adv_router_id, OspfT_Lsa_Type lsa_type);
OspfT_Lsa_Header *			ospf_lsa_header_lookup (List *lsa_header_list_ptr, IpT_Address link_state_id, IpT_Address adv_router_id, OspfT_Lsa_Type lsa_type);
void						ospf_lsa_remove (List *lsa_list_ptr, OspfT_Lsa *lsa_ptr);
void						ospf_lsa_header_remove (List *lsa_header_list_ptr, OspfT_Lsa_Header *lsa_header_ptr);
int							ospf_lsa_compare (OspfT_Lsa_Header *lsa1_header_ptr, OspfT_Lsa_Header *lsa2_header_ptr);
void						ospf_lsa_rxmt_list_purge (List *lsa_list_ptr, OspfT_Lsa *lsa_ptr);
void						ospf_lsa_header_list_purge (List *lsa_header_list_ptr, OspfT_Lsa_Header *lsa_header_ptr);
void						ospf_lsa_max_age_purge (OspfT_Router *router_ptr);
void						ospf_lsa_flush (OspfT_Lsa *lsa_ptr, OspfT_Area *area_ptr);
void						ospf_lsa_list_process (List *lsa_list_ptr, OspfT_Area *area_ptr, OspfT_Neighbor *rcvd_nbr_ptr);
void						ospf_lsa_self_orig_rcvd (OspfT_Lsa *lsa_ptr, OspfT_Interface *interface_ptr);
void						ospf_lsa_ack_direct_send (OspfT_Lsa *lsa_ptr, OspfT_Neighbor *nbr_ptr);
void						ospf_lsa_ack_delayed_send (OspfT_Lsa *lsa_ptr, OspfT_Interface *intf_ptr);
void						ospf_lsa_ack_delay_timer_handler (OspfT_Interface *intf_ptr, int intrpt_code);
OspfT_Lsa *					ospf_lsa_create (OspfT_Lsa_Header *lsa_header_ptr);
OspfT_Lsa_Header *			ospf_lsa_header_create (OspfT_Lsa_Type lsa_type, IpT_Address orig_router_id, IpT_Address link_state_id);
OspfT_Lsa_Router_Links *		ospf_lsa_router_links_create (void);
OspfT_Lsa_Router_Links_Info *	ospf_lsa_router_links_info_create (void);
OspfT_Lsa_Network_Links *		ospf_lsa_network_links_create (void);
OspfT_Lsa_Summary_Links *		ospf_lsa_summary_links_create (void);
void							ospf_lsa_header_destroy (OspfT_Lsa_Header *lsa_header_ptr);
void							ospf_lsa_destroy (OspfT_Lsa *lsa_ptr);
void							ospf_lsa_router_links_destroy (OspfT_Lsa_Router_Links *router_links_ptr);
void							ospf_lsa_router_links_info_destroy (OspfT_Lsa_Router_Links_Info *router_links_info_ptr);
void							ospf_lsa_network_links_destroy (OspfT_Lsa_Network_Links *network_links_ptr);
void							ospf_lsa_summary_links_destroy (OspfT_Lsa_Summary_Links *summary_links_ptr);
void							ospf_lsa_list_print (List *lsa_list_ptr);
void							ospf_lsa_print (OspfT_Lsa *lsa_ptr);
void							ospf_lsa_header_print (OspfT_Lsa_Header *lsa_header_ptr);
void							ospf_lsa_summary_links_print (OspfT_Lsa_Summary_Links *summary_links_ptr);
void							ospf_lsa_network_links_print (OspfT_Lsa_Network_Links *network_links_ptr);
void							ospf_lsa_router_links_print (OspfT_Lsa_Router_Links *router_links_ptr);
OspfT_Lsa *						ospf_lsa_copy (OspfT_Lsa *lsa_ptr);
OspfT_Lsa_Header *				ospf_lsa_header_copy (OspfT_Lsa_Header *lsa_header_ptr);
OspfT_Lsa_Router_Links *		ospf_lsa_router_links_copy (OspfT_Lsa_Router_Links *router_links_ptr);
OspfT_Lsa_Router_Links_Info *	ospf_lsa_router_links_info_copy (OspfT_Lsa_Router_Links_Info *info_ptr);
OspfT_Lsa_Network_Links *		ospf_lsa_network_links_copy (OspfT_Lsa_Network_Links *network_links_ptr);
OspfT_Lsa_Summary_Links *		ospf_lsa_summary_links_copy (OspfT_Lsa_Summary_Links *summary_links_ptr);
void							ospf_lsa_djk_nodes_add (OspfT_Lsa *lsa_ptr, List *node_list_ptr);
void							ospf_lsa_djk_router_connect_create (DjkT_Node *node_ptr, OspfT_Lsa *lsa_ptr, List *node_list_ptr);
void							ospf_lsa_djk_network_connect_create (DjkT_Node *node_ptr, OspfT_Lsa *lsa_ptr, List *node_list_ptr);
List *							ospf_lsa_djk_node_list_create (OspfT_Area *area_ptr);
DjkT_Node *						ospf_lsa_djk_node_lookup (List *node_list_ptr, IpT_Address link_state_id, OspfT_Lsa_Type lsa_type);

#endif
