#ifndef   PIM_DM_h
#define   PIM_DM_h
#include "ospf_defs.h"

typedef struct PimDM_Interface {
     OspfT_Interface_Type	 interface_type;
     IpT_Address	       	 interface_address;
     IpT_Address	       	 interface_mask;
     int	                 mtu;
     List                       *pim_neighbor_list;
     Packet  *                   hello_message_ptr;
     Evhandle                    interface_hello_timer;
} PimDM_Interface;

typedef struct PimDM_Neighbor {
     IpT_Address      neighbor_address;
     PimDM_Interface *parent_intf_ptr;
     Evhandle         neighbor_time_out_handle;
     Packet          *last_message_ptr;
     Evhandle         rxmt_timer;
     Evhandle         delay_send_timer;
} PimDM_Neighbor; 

typedef struct {
     IpT_Address source;
     IpT_Address group;
} SrcGrpPair;

/*
typedef struct PimDM_Mroute_Entry {
     double       entry_time;
     SrcGrpPair  *SrcGrp;
     IpT_Address  RPF_neighbor;
     IpT_Address  forwarder;
     IpT_Address  iif;  
     List        *oif;
     int          num_forward_intf;
     Evhandle     negative_timer;
     Evhandle     graft_resend_timer;
     Packet      *graft_message_ptr;
     Evhandle     delay_join_timer;
     
} PimDM_Mroute_Entry;*/


typedef struct PimDM_Mroute_Entry {
     SrcGrpPair  *SrcGrp;
     IpT_Address  RPF_neighbor;
     IpT_Address  forwarder;
     IpT_Address  iif;  
     List        *oif;
     int          num_forward_intf;
     Evhandle     entry_timer;
     Evhandle     graft_resend_timer;
     Packet      *graft_message_ptr;
     Evhandle     delay_join_timer;
     
} PimDM_Mroute_Entry;

typedef struct Mlocal_Entry {
     IpT_Address  intf_addr;
     List *       group_list;  
} Mlocal_Entry;

typedef struct PimDM_Mroute_Table {
     List *   Mroute_entry_list_ptr;
     Boolean  dirty_flag;
     double   last_cal_time;
} PimDM_Mroute_Table;


typedef enum OIF_Status {
     Prune,
     Forward
} OIF_Status;  


typedef struct {
     OIF_Status  forward_status;
     Evhandle    rebroadcast_timer;
     IpT_Address interface_addr;
     Evhandle    delay_prune_timer;
     PimDM_Mroute_Entry   *parent_Mroute_entry_ptr;
} OIF_Interface;

typedef struct {
     IpT_Address  intf_addr;
     List *group_join;
} Mlocal_entry;

typedef struct {
     IpT_Address group;
} Mlocal_Join;

  

typedef enum pim_message_type {
     HelloMsg,
     PruneMsg,
     GraftMsg,
     Graft_AckMsg
} PimDM_Message_Type;


typedef struct pim_message {
     PimDM_Interface * interface_ptr;
     Packet * message_ptr;
} PimDM_Message_Send;      

typedef struct pim_delay_prune_message {
     PimDM_Mroute_Entry *Mroute_entry;
     OIF_Interface      *oif_intf_ptr;
     SrcGrpPair         *SrcGrp;
     IpT_Address        prune_intf_addr;  
} PimDM_Delay_Prune_Message;

/* Changed by Anindya Neogi */
/* Date : 7-17-97 */
/* included for pim-ip interaction */

#define MAXINF 10
#define ENTRY_END '@'
#define TERMINATE_LIST -1
#define TRUE 1
#define FALSE 0
#define FILE_END '#'
#define NOT_FILE_END '%'

enum Mode_Type {FORWARD, PRUNE};

typedef    int intList[MAXINF] ;
typedef    int IP_Addr[4] ;
typedef    int MCAST_Addr[4] ;

typedef    struct { IP_Addr     Source;
                    MCAST_Addr  Group;
} SGPair;

typedef    struct      { int Hour;
                         int Min;
                         int Sec;
} Time;

typedef    struct { IP_Addr        InfNum;
                    enum Mode_Type  Mode;
                    Time       Uptime;
                    Time       ExpireTime;
} Inf_List_Entry;


/* MLOCAL Table entry */
typedef struct { MCAST_Addr   GroupId;
                 IP_Addr      IntList[MAXINF];
				 struct MLOCAL_Entry *NextEntry;
}  MLOCAL_Entry ;

/* MROUTE Entry */
typedef struct MROUTE_Entry {  SGPair          SrcGrp;
                  Time            Uptime;
                  Time            ExpireTime;  
                  IP_Addr         IncInf;
                  IP_Addr         RPFNeighbor;
                  Inf_List_Entry  IntList[MAXINF];  
	          struct MROUTE_Entry    *NextEntry;
} MROUTE_Entry ;


/* End of Change */
 
/* PimDMT_Router_Id: PIM_DM Router ID, implemented as IpT_Address. */
typedef IpT_Address PimDMT_Router_Id;


 /* Pim_DMT_Rte_Table: PIM_DM Routing Table. */
typedef struct PimDMT_Rte_Table 
    {
    MROUTE_Entry *Mcast_Rte_Table;       /* ROUTING TABLE */
    Boolean	dirty_flag;     /* Flag indicating table needs to be recalculated. */
    double	last_calc_time; /* Last time routing table was calculated. */
    } PimDMT_Rte_Table;


/* PimDMT_Router: Representation of an PIM_DM router. */
typedef struct PimDMT_Router	
    {	
    PimDMT_Router_Id  router_id;	/* Unique ID for router. */
    OmsT_Pr_Handle    proc_reg_handle;  /* Process registry handle used to accMroute_entry;
ess router variables. */
    Prohandle         proc_handle;	/* Process handle (used to invoke root process). */
    int	              ip_outstrm;	/* Stream index to IP. */
    int	              options;		/* Flag board indicating optional capabilities. */                  PimDMT_Rte_Table  *mcast_rte_table_ptr; /* Pointer to PIM routing table. */
    Stathandle	      load_stat;	/* Stat handle to load statistic. */
    double	      bits_accum;       /* Total accumulated bits router has sent. */
    } PimDMT_Router;

#endif
