/* 
 * $ID: idrp_dump.c,v 1.8 1995/10/10 16:22:42 skh Exp $
 * Merit IDRP release 1.1 (gated 3.5.4).  Copyright (c) 1994 by Merit Network, Inc. 
 */

#include "include.h"
#include "iso.h"
#include "idrp.h"
#include <stdio.h>


/* idrp_dump.c
 * 
 * IDRP DUMP routines
 *	idrp_master_dump
 * 	idrp_dump_attr_list(peer)
 * 	idrp_peer_dump
 * 	idrp_dump_peer_mib(fd,peer)
 * 	idrp_dump_peer_extra(fd,peer)
 * 
 *	idrp_peer_rtbit_dump
 *	idrp_dump_local_rib(fd)
	idrp_qos_active_dump(fd,fdk);
 *
 */ 

char *off_on[] = {"OFF", "ON"};  
char *state_string[] = {"IDRP_CLOSED", "IDRP_OPEN_RCVD", "IDRP_OPEN_SENT", 
			  "IDRP_CLOSE_WAIT", "IDRP_ESTABLISHED"};
char *false_true[] = {"FALSE", "TRUE"};




void 
idrp_master_dump(tp, fd)
task *tp;
FILE *fd;
{

        idrpPeer *peer;

        peer = &idrp_this_node;
  	if (fd == NULL) {
	  fd = fopen ("/var/tmp/gatedlog.idrp", "w");
	}

	(void) fprintf(fd, "\n\n\n-------------------------------\n IDRP Master Task MIB structures : ");
	idrp_dump_peer_local_mib(fd);

	(void) fprintf(fd, "\n\nIDRP Peer MIB structures : ");
	IDRP_LIST(peer, idrp_peers)  {
	  if (peer == &idrp_this_node)
	    continue;
	  idrp_dump_peer_mib(fd,peer);
	  idrp_dump_peer_extra(fd,peer);
	} IDRP_LIST_END

	peer = (idrpPeer *) 0;
	(void) fprintf(fd, "\n\n***********************************************");
	(void) fprintf(fd, "\nIDRP Attributes (dump of all attribute records):");
	(void) fprintf(fd, "\n***********************************************");
	idrp_dump_attr_list(fd,peer,0,rib_cnt);
	(void) fprintf(fd, "\n\nRIB contents are in the routing table:");
	(void) fprintf(fd, "\nRoutes for idrp are  :");
	idrp_dump_local_rib(fd);
        
        /* dump adj-ribs per peer */
        IDRP_LIST(peer, idrp_peers)
	  idrp_dump_adj_rib(fd,peer);
	IDRP_LIST_END

	idrp_dump_pref_list(fd,peer);
	idrp_dump_aggr_list(fd,peer);
	idrp_dump_dist_list(fd,peer);
	(void) fprintf (fd, "\n\n\n");
}

			
void 
idrp_peer_dump(tp, fd)
task *tp;
FILE *fd;
{
/* variables and initialization */
	idrpPeer *peer;

	peer = (idrpPeer *) tp->task_data;
	idrp_dump_peer_mib(fd,peer);
	idrp_dump_peer_extra(fd,peer);
	idrp_dump_pref_list(fd,peer);
		
	/* peer information */

}

void
idrp_dump_peer_mib(fd,peer)
FILE		 *fd;
idrpPeer	*peer;
{
	/* MIB variables 
	 */ 

	(void) fprintf(fd, "\n\n  bisNegotiatedVersion %d ", peer->version);
	(void) fprintf(fd, "\n  bisNet %s", peer->name);
	(void) fprintf(fd, "\n  bisPeerSNPAs: ");
	/* (void) idrp_dump_snpa_list (fd, peer->snpa);*/
	(void) fprintf(fd, "\n  bisRDC: No RDC support");
	(void) fprintf(fd, "\n  bisRDI %A",sockbuild_iso((byte *) peer->rdi.isoa_genaddr,
								peer->rdi.isoa_len));
	(void) fprintf (fd, "\n  KeepAliveSinceLastUpdate %d ", 
			peer->keepAlives_Since_last_Update);

	(void) fprintf (fd, "\n  lastAckRecv (send_unack) %d", peer->send_unack);
	(void) fprintf (fd, "\n  lastAckSent (rcv_seq_expected - 1) %d", 
			peer->rcv_seq_expected - 1);
	(void) fprintf (fd, "\n  lastSeqNoRecv (rcv_seq_expected - 1) %d",
			peer->rcv_seq_expected - 1);
	(void) fprintf (fd, "\n  lastSeqNoSent (send_next -1) %d",
			peer->send_next - 1);
	(void) fprintf (fd, "\n  listForOpen %s", false_true[peer->listen_for_open]);
	(void) fprintf (fd, "\n  MaxPDUPeer %d, OutstandingPDUs (recv_cerdit) %d",
			peer->pdu_maxsendsize, peer->rcv_credit);
	(void) fprintf (fd, "\n  State %s ", state_string[peer->state - 1]);
	(void) fprintf (fd, "\n  totalBISPDUsin %d, totalBISPDUsout %d, updatesIn %d, UpdatesOut %d",
			peer->totalBISPDUIn, peer->totalBISPDUOut,
			peer->updatesIn, peer->updatesOut);

	(void) fprintf(fd, "\n    /*   SND.NXT = %d, SEND.UWE = %d, SND.UNA = %d", peer->send_next,
		       peer->upper_window_edge, peer->send_unack);
	(void) fprintf(fd, "\n     *   RCV.EXP = %d, RCV.CRED = %d, RCV.CREDAV = %d", 
		       peer->rcv_seq_expected, peer->rcv_credit, peer->rcved_credit_avail);
	(void) fprintf(fd, "\n     *   HOLDTIME = %d, KEEPALIVETIME = %d",
		       peer->hold_time, peer->keepalive_time);
	(void) fprintf(fd, "\n     */  MAXSENDSIZE = %d, MAXRCVSIZE = %d", 
		       peer->pdu_maxsendsize, peer->pdu_maxrcvsize);

	/* dump the policy - which is null right now */

}


void
idrp_dump_peer_local_mib(fd)
FILE		 *fd;
{
        idrpPeer *peer;
	idrpPeer *local;

	local = &idrp_this_node;
	/* MIB variables 
	 */ 
        (void) fprintf(fd, "\n  AuthenticationTypeCode %d, Capacity %d, CloseWaitDelayTime %d", 
		       local->AuthType, local->Capacity, local->close_wait);
        (void) fprintf(fd, "\n  ExternalBisNeighbor: ");
	IDRP_EXT_PEER (peer) 
	  {
	    (void) fprintf(fd, "\n    NET %s (%A)", peer->name, peer->ip_neighbor);
	  }
	IDRP_EXT_PEER_END
        (void) fprintf(fd, "\n  HoldTime %d ", local->hold_time);
	(void) fprintf(fd, "\n  InternalBis: ");
	if (idrp_peers)
		{
		IDRP_INT_PEER(peer)
		  {
		    (void) fprintf(fd, "\n    NET %s (%A)", peer->name, peer->ip_neighbor);
		   } IDRP_INT_PEER_END
		}
	
	(void) fprintf(fd, "\n  InternalSystems: ");
	(void) idrp_dump_internal_systems (fd);
	(void) fprintf(fd, "\n  IntaIS: ");
	(void) idrp_dump_intra_is_systems (fd);
	(void) fprintf(fd, "\n  KeepAliveTime %d, localRDI %A",
		       local->keepalive_time, 
		       sockbuild_iso((byte *) local->rdi.isoa_genaddr,local->rdi.isoa_len));


	(void) fprintf(fd, "\n  Local SNPA: ");
	/*        (void) idrp_dump_snpa_list (fd, local->snpa);*/

	(void) fprintf (fd, "\n  LocExpense %d, MaxCPUOverloadTime %d", 
			local->Expense, local->cpu_overload_time);
	(void) fprintf (fd, "\n  MaxPDULocal (pdu_maxrecvsize) %d", local->pdu_maxsendsize);
	(void) fprintf (fd, "\n  MaxRibIntegrityCheck %d, MaxRibIntegrityCheckTimer %d",
			local->max_rib_integ_check, local->ribcheck_timer);

	(void) fprintf (fd, "\n  MinRouteAdvTimer %T, MultiExit %s, Priority %d", 
			local->min_advRD_time,false_true[local->multi_exit], local->Priority);
	(void) fprintf (fd, "\n  rdcConfig: No rdc support");
	(void) fprintf (fd, "\n  rdLRE: Not supported");
	(void) fprintf (fd, "\n  RetransmissionTime %d", local->keepalive_time);
	
	(void) fprintf (fd, "\n  ribAttsSet: Only default routes supported");
	(void) fprintf (fd, "\n  RouteServer %s, Version %d ", 	
			off_on[local->route_server], local->version);
}


void
idrp_dump_peer_extra(fd,peer)
FILE	*fd;
idrpPeer	*peer;
{

  	

}

void
idrp_dump_attr_list(fd,peer_search,rib1,rib2)
FILE	*fd;
idrpPeer	*peer_search;
int	rib1;
int	rib2; 	
{
	/* dump the attribute list
	 * - if peer_search specified -
	 * - then look only for that peer
	 * - in route_ids
	 */
 
	idrp_attribute_record *att;
	idrpRoute_entry *rte;
	int n = 0;
	int rib_id;

	for (rib_id = rib1; rib_id < rib2 ; rib_id++)
         {
         ATTR_LIST(att,rib_id)
	  {
	    if ((peer_search == NULL) || in_rt_list (att, peer_search)) {
	      att->ref_no = n; /* for reference later when dumping routes */
	      (void) fprintf(fd, "\n  #%d  ATTR   RefCnt %d, RIB_id %d, Mask %x ", 
			     n++, att->ref_cnt, att->rib_id, att->idrp_mask );
	      for (rte = att->route_id_list; rte; rte = rte->p_next)
		{
	         (void) fprintf(fd, "\n\t (route list  peer %s)", rte->peer->name);
	        }
	      idrp_dump_attr_entry (fd, att);
	    }
	  } ATTR_LIST_END
	} 
}

int
in_rt_list (att, peer)
idrp_attribute_record   *att;
idrpPeer                *peer;
{

        /* Returns true if a given peer appears in the 
	 * - route list of an atribute record
	 */

  	idrpRoute_entry		*rt;
	rt = att->route_id_list;		

	while (rt != NULL)
	  {
	    if (peer == rt->peer)
	      return (1);
	    rt = rt->p_next;
	  }
	    
	return (0);
}   



void
idrp_dump_attr_entry(fd,att_rec)
FILE	*fd;
idrp_attribute_record *att_rec;
{
         int attr_type;
	 idrp_canon_rdpath *p_can;


         for (attr_type = 1; attr_type < IDRP_ATTR_MAX + 1; attr_type++) {
	   
	   /* if  attribute not present skip */
	   if (!att_rec->attrib[attr_type].present)
	     continue;
	   
	   (void) fprintf (fd, "\n          %s  ",  idrpAttrTypeStrings[attr_type]);
	   
	   switch (attr_type) {
	   case IDRP_ATTR_ROUTE_SEPARATOR: /* 4 byte rt id, 1 byte pref */
	     (void) fprintf (fd, "RouteID %ld   Local Pref %d", 
			     idrp_get_byte_value ((char *) att_rec->attrib[attr_type].data, 4),
			     idrp_get_byte_value ((char *) att_rec->attrib[attr_type].data + 4, 1));
	     break;
	   case IDRP_ATTR_RD_PATH:
	     RDPATH_LIST(att_rec->rd_path,p_can)	
	       (void) fprintf (fd, "\n\t     %A", sockbuild_iso((byte *) p_can->p_rdi->rdi.isoa_genaddr,
								p_can->p_rdi->rdi.isoa_len));
	     RDPATH_LIST_END
	     break;
	   case IDRP_ATTR_NEXT_HOP: 
	     (void) fprintf (fd, "  %A", att_rec->next_hop);
	     break;
	   case IDRP_ATTR_DIST_LIST_INCL: 
	     if (att_rec->p_opts == NULL)
	       (void) fprintf (fd, "  NULL");
	     else {
	       RDPATH_LIST(att_rec->p_opts->p_DIST_LIST_INCL,p_can)	
		 (void) fprintf (fd, "\n\t     %A", sockbuild_iso((byte *) p_can->p_rdi->rdi.isoa_genaddr,
								p_can->p_rdi->rdi.isoa_len));
	       RDPATH_LIST_END
	       }
	       break;
	   case IDRP_ATTR_DIST_LIST_EXCL: 
	     	     if (att_rec->p_opts == NULL)
	       (void) fprintf (fd, "  NULL");
	     else {
	       RDPATH_LIST(att_rec->p_opts->p_DIST_LIST_EXCL,p_can)	
		 (void) fprintf (fd, "\n\t     %A", sockbuild_iso((byte *) p_can->p_rdi->rdi.isoa_genaddr,
								p_can->p_rdi->rdi.isoa_len));
	       RDPATH_LIST_END
	       }
	       break;
	   case IDRP_ATTR_MULTI_EXIT_DISC: /* 1 byte */
	     (void) fprintf (fd, "  %d", (char) att_rec->attrib[attr_type].data[0]);
	     break;
	   case IDRP_ATTR_TRANSIT_DELAY: /* 2 bytes */
		if (att_rec->p_opts->p_qos)
			{
	     		(void) fprintf (fd, "  %d", att_rec->p_opts->p_qos->delay.value);
			}
		else
			{
			(void) fprintf (fd, "  %d", idrp_get_byte_value ((char *) att_rec->attrib[attr_type].data, 2));
			}
	     break;
	   case IDRP_ATTR_RESIDUAL_ERROR: /* 4 bytes */
		if (att_rec->p_opts->p_qos)
			{
	     		(void) fprintf (fd, "  %d", att_rec->p_opts->p_qos->error.value);
			}
		else
			{
			(void) fprintf (fd, "  %d", idrp_get_byte_value ((char *) att_rec->attrib[attr_type].data, 4));
			}
	     break;
	   case IDRP_ATTR_EXPENSE: /* 2 bytes */
		if (att_rec->p_opts->p_qos)
			{
	     		(void) fprintf (fd, "  %d", att_rec->p_opts->p_qos->expense.value);
			}
		else
			{
			(void) fprintf (fd, "  %d", idrp_get_byte_value ((char *) att_rec->attrib[attr_type].data, 2));
			}
	     break;
	   case IDRP_ATTR_HIERARCH_REC: /* 1 byte */
	     (void) fprintf (fd, "  %d", (char) att_rec->attrib[attr_type].data[0]);
	     break;
	   case IDRP_ATTR_HOP_COUNT: /* 1 byte */
	     (void) fprintf (fd, "  %d ", att_rec->p_opts->hopcount);
	     break;
	   case IDRP_ATTR_CAPACITY: /* 1 byte */
		(void) fprintf (fd, "  %d", att_rec->p_opts->capacity.value);
	     break;
	   case IDRP_ATTR_PRIORITY: /* 1 byte */
		if (att_rec->p_opts->p_qos)
			{
	     		(void) fprintf (fd, "  %d", att_rec->p_opts->p_qos->priority.value);
			}
		else
			{
			(void) fprintf (fd, "  %d", idrp_get_byte_value ((char *) att_rec->attrib[attr_type].data, 1));
			}
	     break;

	   case IDRP_ATTR_SECURITY: 
		if (att_rec->p_opts->p_qos)
			{
	     		(void) fprintf (fd, "  %d %d", att_rec->p_opts->p_qos->sec_type.value,att_rec->p_opts->p_qos->sec_value.value);
			}
		else
			{
			(void) fprintf (fd, "  %d", idrp_get_byte_value ((char *) att_rec->attrib[attr_type].data, 2));
			}
	      break;
	   }
	 }


}



extern void
idrp_peer_rtbit_dump(rth, data, buf)
rt_head *rth;
void_t data;
char *buf;
{
	idrpPeer *peer;
	metric_t metric;
	char mybuf[50];

	peer = (idrpPeer *)data;
	bcopy("rtbit =",buf,6);
}


/* master dump of routing tables */
/* Dump the LocRib. */

static void 
idrp_dump_local_rib(fd)
FILE *fd;
{

        rt_list		*rtl;
	rt_entry *rt = (rt_entry *) 0;	
	rt_head	 *rth = (rt_head *) 0;	
	idrpRoute *idrp_find_idrp_route();


	fprintf(fd, "\n\n\tIDRP Local Rib:");
	fprintf(fd, "\n  RibID   Attr id   Destination                Next Hop NET");

        /* IP */
	(void) fprintf(fd, "\nIP Routes \n");
        rtl = (rt_list *) rthlist_active (AF_INET);

	RT_LIST(rth,rtl,rt_head)
	  {
	  if (socktype(rth->rth_dest) != AF_INET)
		continue;	    
	  rt = rth->rth_active; 
	  if (IS_AN_IDRP(rt) || IS_LOCAL_IDRP(rt))
	        idrp_dump_route_mib (fd, (idrpRoute *) rt->rt_idrp); 
	  }	
	RT_LIST_END(rth,rtl,rt_head)

	/* ISO */
	(void) fprintf(fd, "\nISO Routes \n");

        rtl = (rt_list *) rthlist_active (AF_ISO);

	RT_LIST(rth,rtl,rt_head)
	  {
	  if (socktype(rth->rth_dest) != AF_ISO)
		continue;	    
	  rt = rth->rth_active; 
	    if (IS_AN_IDRP(rt) || IS_LOCAL_IDRP(rt))
	        idrp_dump_route_mib (fd, (idrpRoute *) rt->rt_idrp); 
	  }	
	RT_LIST_END(rth,rtl,rt_head)

#ifdef	IDRP_QOS	
	  {
	  FILE *fdk = NULL;
	  idrp_qos_active_dump(fd,fdk);
	  }
#endif
}

static void idrp_dump_adj_rib(fd,peer)
FILE *fd;
idrpPeer	*peer;
{
  	register rtq_entry *rtq = NULL;
	rt_entry *rt = (rt_entry *) 0;	
	int i;


	(void) fprintf(fd, "\n\n\tIDRP ADJ Rib:");
	(void) fprintf(fd, "\n  Net: %s    Rib Id: 0 (default)", peer->name);
	(void) fprintf(fd, "\n  RibID    Attr id   Destination                Next Hop NET");

	NLRI_FAMILY_LOOP(i) 
		{
		  /* collect gateway routes for all families */
		  switch (i) {
		  case IDRP_NLRI_ISO:
		    rtq = (rtq_entry *) &(peer->iso_gw.gw_rtq);
		    break;
		  case IDRP_NLRI_IP:
		    rtq = (rtq_entry *) &(peer->gw.gw_rtq);
		    break;
		  default:
		    rtq = NULL;
		    break;
		  }

		  RTQ_LIST (rtq, rt)
		    {
			/* IDRP routes or routes imported to
			 * idrp from other protocols
			 */
 
			if (IS_AN_IDRP(rt) || IS_LOCAL_IDRP(rt))
				{
				idrp_dump_route_mib (fd, (idrpRoute *) rt->rt_data);
				}

		    }	
		  RTQ_LIST_END(rtq, rt);
		}
	NLRI_FAMILY_LOOP_END;	
}

void
idrp_dump_route_mib (fd, idrp_rt)
FILE *fd;     
idrpRoute *idrp_rt;
{
  /* dump route mib attributes according to Sues spec */

  if (fd == NULL) 
    fd = fopen ("/var/tmp/gated_dump", "w");



  /* rib, route/attr id, destination nlri, next hop */
  if (iso_ptoa(&idrp_rt->nlri) == NULL)
    (void) fprintf (fd, "\n   %d        %d      %-26s\t%A", idrp_rt->p_attr->rib_id, idrp_rt->p_attr->ref_no,
		       "Default", idrp_rt->p_attr->next_hop);
  else
    (void) fprintf (fd, "\n   %d        %d      %-26s\t%A", idrp_rt->p_attr->rib_id, idrp_rt->p_attr->ref_no,
		    iso_ptoa(&idrp_rt->nlri), idrp_rt->p_attr->next_hop);
}


#ifdef IDRP_QOS
void
idrp_dump_route_qos (fd, idrp_rt)
FILE *fd;     
idrpRoute *idrp_rt;
{
  /* dump route mib attributes according to Sues spec */

  if (fd == NULL) 
    fd = fopen ("/var/tmp/gated_dump", "w");



  /* rib, route/attr id, destination nlri, next hop */
  if (iso_ptoa(&idrp_rt->nlri) == NULL)
    (void) fprintf (fd, "\n   %d        %d       %x      %-26s\t%A", idrp_rt->p_attr->rib_id, idrp_rt->p_attr->ref_no,idrp_rt->qos_status,
		       "Default", idrp_rt->p_attr->next_hop);
  else
    (void) fprintf (fd, "\n   %d        %d       %x      %-26s\t%A", idrp_rt->p_attr->rib_id, idrp_rt->p_attr->ref_no,idrp_rt->qos_status,
		    iso_ptoa(&idrp_rt->nlri), idrp_rt->p_attr->next_hop);
}


idrp_kernel_route_qos (fd, idrp_rt)
FILE *fd;     
idrpRoute *idrp_rt;
{
  /* dump route mib attributes according to Sues spec */

  if (fd == NULL) 
    fd = fopen ("/var/tmp/gated_dump", "w");

  /* rib, route/attr id, destination nlri, next hop */
  if (iso_ptoa(&idrp_rt->nlri) == NULL)
    (void) fprintf (fd, "\n%d       %x      %-26s\t%A", idrp_rt->p_attr->rib_id,
		       "Default", idrp_rt->p_attr->next_hop);
  else
    (void) fprintf (fd, "\n%d         %A\t%A", qos_rib[idrp_rt->p_attr->rib_id]->parse_id,
		    idrp_rt->p_rt->rt_head->rth_dest, idrp_rt->p_attr->next_hop);
}
#endif /* IDRP_QOS */

void
idrp_dump_pref_list(fd,peer)
FILE	*fd;
idrpPeer	*peer;
{
/* if (idrp_import_list) {
 *          control_exterior_dump(fd, 1, control_import_dump, idrp_import_list);
 *   }
 */
}
void
idrp_dump_aggr_list(fd,peer)
FILE	*fd;
idrpPeer	*peer;
{
}

void
idrp_dump_dist_list(fd,peer)
FILE	*fd;
idrpPeer	*peer;
{
 /*      if (idrp_export_list) {
 *         control_exterior_dump(fd, 1, control_export_dump,idrp _export_list);
 * 	   }
 */
}


void
idrp_dump_intra_is_systems (fd)
FILE *fd;
{
  (void) fprintf (fd, "\n     Not Implemented");
}


void
idrp_dump_internal_systems (fd)
FILE *fd;
{
  	idrp_attribute_record *p_att;	
	idrpRoute_entry *p_idrp_rt_entry;
	idrpRoute *p_idrp_rt;
	int n;
	int i = 0;
	int rib_id;		
	
	/* walk attributes for records with no pdu for local routes.
	 * Display all routes attached to the attribute record.
	 */

 	QOS_RIB_LIST(rib_id)
	 {
  	 ATTR_LIST(p_att,rib_id)
	  {
	  if (p_att->local_mask & IDRP_LOCAL_NO_PDU) {
	    p_idrp_rt_entry = (idrpRoute_entry *) p_att->route_id_list;
	    
	    while (p_idrp_rt_entry != NULL) {
	      NLRI_FAMILY_LOOP(n)
		{
		  p_idrp_rt = (idrpRoute *) p_idrp_rt_entry->p_route[n];
		  while (p_idrp_rt != NULL) {
		    (void) fprintf (fd, "\n     %s", iso_ptoa(&p_idrp_rt->nlri));
		    p_idrp_rt = (idrpRoute *) p_idrp_rt->p_next_nlri;
		  }
		}
	      NLRI_FAMILY_LOOP_END
	      p_idrp_rt_entry = (idrpRoute_entry *) p_idrp_rt_entry->p_next;
	    }
	   }
	 } ATTR_LIST_END
	} QOS_RIB_LIST_END
}


void
idrp_dump_snpa_list (fd, snpal)
FILE *fd;
snpa_list snpal;
{


  idrp_dump_snpa_entry (fd, &(snpal.snpa1));
  

}


void 
idrp_dump_snpa_entry (fd, snpa)
FILE *fd;
snpa_entry *snpa;
{
  	/* print octetcs of snpa in pretty format */

	int i = 0;
 	while (i++ < (snpa->len -1))
	  (void) fprintf (fd, "%x.", snpa->snpa[i]);
	(void) fprintf (fd, "%x  ", snpa->snpa[i]);
}


long
idrp_get_byte_value (data, n)
char *data;
int n;
{
	/* comment goes here */

	long l;
	bzero(&l, 4);
	bcopy(data, &l, n);

	if (n == 4)
	  return (ntohl (l));
	else
	  return (ntohs (l));
}


void idrp_dump_ann_list (p_ann_list, fd)
     idrp_ann_list *p_ann_list;
     FILE *fd;
{
          int i;
	  idrp_ann_list *p_atl;
	  idrpRoute	*p_irt;

	  if (fd == NULL) {
	    fd = fopen ("/var/tmp/gated_dump", "w");
	  }

	  fprintf(fd, "\n\nIdrp Announce List Dump:\n\n");


	  ANN_LIST(p_atl,p_ann_list) {
	    idrp_dump_peer_mib(fd,p_atl->peer);

	    fprintf(fd, "\nWithdrawals:");
	    NLRI_FAMILY_LOOP(i) {
	      ANN_WITH_LIST_WALK(p_irt,i,p_atl)	
		idrp_dump_route_mib (fd, p_irt);
	      ANN_WITH_LIST_WALK_END
	      }
	    NLRI_FAMILY_LOOP_END

	    fprintf(fd, "\nAnnounce:");
	    NLRI_FAMILY_LOOP(i) {
	      ANN_ANN_LIST_WALK(p_irt,i,p_atl)	
		idrp_dump_route_mib (fd, p_irt);
	      ANN_ANN_LIST_WALK_END
	      }
	    NLRI_FAMILY_LOOP_END

	    }
	  ANN_LIST_END
	    fclose (fd);
}


void 
idrp_dump_ann_list2 (p_ann_list, fd)
idrp_ann_list *p_ann_list;
FILE *fd;
{
          int i;
	  idrp_ann_list *p_atl;
	  idrpRoute	*p_irt;

	  if (fd == NULL) {
	    fd = fopen ("/var/tmp/gated_dump", "w");
	  }

	  fprintf(fd, "\n\nIdrp Announce List Dump:\n\n");


	  ANN_LIST(p_atl,p_ann_list) {
	    idrp_dump_peer_mib(fd,p_atl->peer);

	    fprintf(fd, "\nWithdrawals:");
	    NLRI_FAMILY_LOOP(i) {
	      ANN_WITH_LIST_WALK(p_irt,i,p_atl)	
		idrp_dump_route_mib (fd, p_irt);
	      ANN_WITH_LIST_WALK_END
	      }
	    NLRI_FAMILY_LOOP_END

	    fprintf(fd, "\nAnnounce:");
	    NLRI_FAMILY_LOOP(i) {
	      ANN_ANN_LIST_WALK(p_irt,i,p_atl)	
		idrp_dump_route_mib (fd, p_irt);
	      ANN_ANN_LIST_WALK_END
	      }
	    NLRI_FAMILY_LOOP_END

	    }
	  ANN_LIST_END
	    fclose (fd);
}


idrpRoute *
idrp_find_idrp_route(p_gated_rt)
rt_entry *p_gated_rt;
{
 /* walk the idrp_attr_list until the end of the local attribute
  * to find the idrp_route structure
  */
int			i;
idrp_attribute_record	*p_att;
struct iso_prefix	dest;
idrpRoute		*p_irt;
idrpRoute_entry		*p_rte;
int			rib_id = p_att->rib_id; 
		
	ATTR_LIST(p_att,rib_id)
		{
		for (p_rte = p_att->route_id_list;p_rte; p_rte = p_rte->p_next)
			{
			NLRI_FAMILY_LOOP(i)
				{
				for (p_irt = p_rte->p_route[i]; p_irt; p_irt = p_irt->p_next_nlri)
					{
					  if (p_irt->p_rt == p_gated_rt)
					    return (p_irt);
					}
				}
			} NLRI_FAMILY_LOOP_END;
		} ATTR_LIST_END;

	return(0);
}

#ifdef	IDRP_QOS

/* dump the active routes for
 * all qos ribs
 */

void
idrp_qos_active_dump(fd,fdk)
FILE *fd;
FILE *fdk;
{
int	rib_id;
idrp_ann_list		*p_ann;
idrp_attribute_record	*p_att;
idrpRoute_entry		*p_rte;
idrpRoute		*p_irt;
int			i;

  	if (fd == NULL) {
	  fd = fopen ("/var/tmp/qos_dump.log", "w");
	}

	if (fdk == NULL) {
	  fdk = fopen("/var/tmp/qos_kernel.log","a");
	}

	fprintf(fd, "\n\n\tIDRP QOS Local Rib:");
	fprintf(fd, "\n  RibID   Attr id status   Destination                Next Hop NET");

	QOS_RIB_ONLY_LIST(rib_id)
		{
		fprintf(fdk,"\n#Ribid = %d, kernel string (len %d) =  %A\n",rib_id,qos_rib[rib_id]->kern_len,qos_rib[rib_id]->p_qos_str);
		ATTR_LIST(p_att,rib_id)
			{
			for (p_rte = p_att->route_id_list; p_rte; p_rte = p_rte->p_next)
				{
				/* look for a route with an active route list
				 */
			
				NLRI_FAMILY_LOOP(i)
					{	
					for (p_irt = p_rte->p_route[i]; p_irt; p_irt = p_irt->p_next_nlri)
						{
						IDRP_QOS_STATUS_BIT_TEST(p_irt,IDRP_STATUS_QOS_ACTIVE)
						  {
						  idrp_dump_route_qos (fd, (idrpRoute *) p_irt);

						  /* here we test to see if the route cannot be dropped
						   * into kernel due to gated preference being set to invalid
						   */
						 
						  if (p_irt->gated_pref != IDRP_GATED_INVALID_ROUTE_PREF)
							idrp_kernel_route_qos (fdk, (idrpRoute *) p_irt); 
						  }
						}
					} NLRI_FAMILY_LOOP_END;
				}
			} ATTR_LIST_END; 	
	
		}QOS_RIB_ONLY_LIST_END;
	(void) fprintf (fd, "\n\n\n");

}

/* dump the attributes for just the 
 * qos ribs 
 */

void
idrp_qos_attr_dump(fd,fdk)
FILE *fd;
FILE *fdk;
{
idrpPeer *peer = (idrpPeer *) 0;

  	if (fd == NULL) {
	  fd = fopen ("/var/tmp/qos_dump.log", "w");
	}

	if (fdk == NULL) {
	  fdk = fopen ("/var/tmp/qos_kernel.log","w");
	}
	(void) fprintf(fd, "\n\n***********************************************");
	(void) fprintf(fd, "\nIDRP Attributes (dump of all attribute records):");
	(void) fprintf(fd, "\n***********************************************");
	idrp_dump_attr_list(fd,peer,1,rib_cnt);
	idrp_qos_active_dump(fd,fdk);
	fclose(fd);
	fclose(fdk);	
}

#endif

void
idrp_local_rib_dump_only(fd)
FILE 	*fd;
{
idrpPeer *peer;

  	if (fd == NULL) {
	  fd = fopen ("/var/tmp/local_rib_dump.log", "w");
	}

	peer = (idrpPeer *) 0;
	(void) fprintf(fd, "\n\n***********************************************");
	(void) fprintf(fd, "\nIDRP Attributes (dump of all attribute records):");
	(void) fprintf(fd, "\n***********************************************");
	idrp_dump_attr_list(fd,peer,0,rib_cnt);
	(void) fprintf(fd, "\n\nRIB contents are in the routing table:");
	(void) fprintf(fd, "\nRoutes for idrp are  :");
	idrp_dump_local_rib(fd);

	fclose(fd);
}
