/*
 * Copyright (c) 1993 Thomas Pusateri
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that: (1) source code distributions
 * retain the above copyright notice and this paragraph in its entirety, (2)
 * redistribution for commercial purposes be limited to those that obtain
 * prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 *
 */

/**********************************************************************
 *
 * Name:        $RCSfile: print.c,v $
 *
 * Dated:       $Date: 93/05/14 14:25:15 $
 *
 * Author:      $Author: pusateri $
 *
 * Revision:    $Revision: 1.6 $
 *
 * Description:
 *
 *
 ***********************************************************************/

#ifndef lint
static char RCSid[]=
"$Id: print.c,v 1.6 93/05/14 14:25:15 pusateri Exp $";
#endif

#include <sys/types.h>
#include <netinet/in.h>
#include <stdio.h>

#include "snmp.h"
#include "snmp_impl.h"
#include "asn1.h"
#include "snmp_client.h"
#include "snmp_api.h"
#include "mib.h"
#include "ospf.h"

extern struct ospfIf *ifp;
extern struct ospfNbr *nbrp;
extern struct ospfLsdb *lsdbp;
extern struct ospf_advlist *ap;
extern struct ospfRT *rtp;
extern struct ospfFT *ftp;

void print_ospf_interfaces()
{
    struct ospfIf *cur;

    printf("  Area          IP Address      Type  State  Pri  DR            BDR\n");
    printf("-------------------------------------------------------------------------------\n");

    cur = ifp;
    while(cur) {
	printf("%-16s", inet_ntoa(cur->ospfIfAreaId));
	printf("%-16s", inet_ntoa(cur->ospfIfIpAddress));
	switch (cur->ospfIfType) {
	case 1:
			printf("Bcast ");
			break;
	case 2:
			printf("NBMA  ");
			break;
	case 3:
			printf("PtoP  ");
			break;
	default:
			printf("?     ");
	}
	switch (cur->ospfIfState) {
	case 1:
			printf("Down   ");
			break;
	case 2:
			printf("Loopbck");
			break;
	case 3:
			printf("Waiting");
			break;
	case 4:
			printf("P To P ");
			break;
	case 5:
			printf("DR     ");
			break;
	case 6:
			printf("BckupDR");
			break;
	case 7:
			printf("DR Othr");
			break;
	default:
			printf("?      ");

	}
	printf("%-3d", cur->ospfIfRtrPriority);
	printf("%-16s", inet_ntoa(cur->ospfIfDesignatedRouter));
	printf("%-16s\n", inet_ntoa(cur->ospfIfBackupDesignatedRouter));

	cur = cur->next;
    }
}

void print_ospf_neighbors()
{
    struct ospfNbr *cur;

    printf("  Router Id     Nbr IP Addr     State     Pri\n");
    printf("-------------------------------------------------------------------------------\n");

    cur = nbrp;
    while(cur) {
	printf("%-16s", inet_ntoa(cur->ospfNbrRtrId));
	printf("%-16s", inet_ntoa(cur->ospfNbrIpAddr));
	switch (cur->ospfNbrState) {
	case 1:
			printf("Down      ");
			break;
	case 2:
			printf("Attempt   ");
			break;
	case 3:
			printf("Init      ");
			break;
	case 4:
			printf("2 Way     ");
			break;
	case 5:
			printf("Exch Start");
			break;
	case 6:
			printf("Exchange  ");
			break;
	case 7:
			printf("Loading   ");
			break;
	case 8:
	case -1:
		/* -1 is to get around a bug in older gated-alpha */
			printf("Full      ");
			break;
	default:
			printf("?      ");

	}
	printf("%-3d\n", cur->ospfNbrPriority);

	cur = cur->next;
    }
}

void print_ospf_lsdb()
{
    struct ospfLsdb *cur;

    printf("  Area          LSType Link ID         Adv Rtr         Age   Sequence\n"); 
    printf("-------------------------------------------------------------------------------\n");

    cur = lsdbp;
    while(cur) {
	printf("%-16s", inet_ntoa(cur->ospfLsdbAreaId));
	switch (cur->ospfLsdbType) {
	case 1:
			printf("Router ");
			break;
	case 2:
			printf("Net    ");
			break;
	case 3:
			printf("SumNet ");
			break;
	case 4:
			printf("SumASB ");
			break;
	case 5:
			printf("ASE    ");
			break;
	default:
			printf("?      ");

	}
	printf("%-16s", inet_ntoa(cur->ospfLsdbLSID));
	printf("%-16s", inet_ntoa(cur->ospfLsdbRouterId));
	printf("%-6d", cur->ospfLsdbAge);
	printf("%-9x\n", cur->ospfLsdbSequence);

	cur = cur->next;
    }
}

void print_ospf_lsa()
{
    int i;
    u_long *maskptr;
    struct ospf_advlist *cur;				/* current LSA */
    struct lsa_router_header *rhp;			/* router LSA Header ptr */
    struct router_link *lp;				/* link ptr */

    printf("-------------------------------------------------------------------------------\n");

    cur = ap;
    while(cur) {
	switch(cur->entry->header.LStype) {
	case ROUTER_LSA:
		printf("Router  %-16s", inet_ntoa(cur->entry->header.lsID));
		rhp = (struct lsa_router_header *) &cur->entry->lsa_data;

		/* I don't print Router LSA flags yet (VEB) */

		lp = (struct router_link *) ((size_t) &cur->entry->lsa_data +
		    sizeof(struct lsa_router_header));
		for (i=0; i < rhp->nlinks; i++) {
		    switch (lp->linktype) {
		    case 1:
				printf("Pt2Pt RtrID: %-16s ", inet_ntoa(lp->linkID));
				printf("intf %-16s\n", inet_ntoa(lp->linkdata));
				break;
		    case 2:
				printf("TransNet DR: %-16s ", inet_ntoa(lp->linkID));
				printf("intf %-16s\n", inet_ntoa(lp->linkdata));
				break;
		    case 3:
				printf("Stub Net   : %-16s ", inet_ntoa(lp->linkID));
				printf("mask %-16s\n", inet_ntoa(lp->linkdata));
				break;
		    case 4:
				printf("VirtualLink: %-16s ", inet_ntoa(lp->linkID));
				printf("intf %-16s\n", inet_ntoa(lp->linkdata));
				break;
		    }
		    lp = (struct router_link *) ((size_t) lp + sizeof(struct router_link) +
			lp->ntos * sizeof(struct TOSmetric));
		    printf("                        ");
		}
		printf("\n");
		break;
	case NETWORK_LSA:
		maskptr = (u_long *) &cur->entry->lsa_data;
		printf("network %-16s", inet_ntoa(cur->entry->header.lsID));
		printf("mask %-16s", inet_ntoa(*maskptr));
		printf("dr %-16s", inet_ntoa(cur->entry->header.router));
		printf("\n");
		break;
	case SUMNET_LSA:
		break;
	case ASBR_LSA:
		break;
	case ASE_LSA:
		break;
	default:
		printf("\tUnknown Link State Type\n");
	}
	cur = cur->next;
    }
}

void print_route_table()
{
    struct ospfRT *cur;

    printf("  Dest           Mask           NextHop         Proto   Metric Age\n");
    printf("-------------------------------------------------------------------------------\n");

    cur = rtp;
    while(cur) {
      if (IN_CLASSD(cur->ipRouteDest) == 0) {
	printf("%-16s", inet_ntoa(cur->ipRouteDest));
	printf("%-16s", inet_ntoa(cur->ipRouteMask));
	printf("%-16s", inet_ntoa(cur->ipRouteNextHop));
	switch(cur->ipRouteProto) {
	case r_OTHER:
		printf("other   ");
		break;
	case r_LOCAL:
		printf("local   ");
		break;
	case r_NETMGMT:
		printf("netmgmt ");
		break;
	case r_ICMP:
		printf("redirct ");
		break;
	case r_EGP:
		printf("egp     ");
		break;
	case r_GGP:
		printf("ggp     ");
		break;
	case r_HELLO:
		printf("hello   ");
		break;
	case r_RIP:
		printf("rip     ");
		break;
	case r_IS_IS:
		printf("is-is   ");
		break;
	case r_ES_IS:
		printf("es-is   ");
		break;
	case r_IGRP:
		printf("igrp    ");
		break;
	case r_BBNSPF:
		printf("bbnspf  ");
		break;
	case r_OSPF:
		printf("ospf    ");
		break;
	case r_BGP:
		printf("bgp     ");
		break;
	default:
		printf("???     ");
		break;
	}
	printf("%-6d", cur->ipRouteMetric1);
	printf("%-6d\n", cur->ipRouteAge);
      }
      cur = cur->next;
    }
    printf("\n");
}

void print_forward_table()
{
    struct ospfFT *cur;

    printf("  Dest           Mask           NextHop         Proto   Metric Age\n");
    printf("-------------------------------------------------------------------------------\n");

    cur = ftp;
    while(cur) {
      if (IN_CLASSD(cur->ipForwardDest) == 0) {
	printf("%-16s", inet_ntoa(cur->ipForwardDest));
	printf("%-16s", inet_ntoa(cur->ipForwardMask));
	printf("%-16s", inet_ntoa(cur->ipForwardNextHop));
	switch(cur->ipForwardProto) {
	case f_OTHER:
		printf("other   ");
		break;
	case f_LOCAL:
		printf("intf    ");
		break;
	case f_NETMGMT:
		printf("static  ");
		break;
	case f_ICMP:
		printf("redrct  ");
		break;
	case f_EGP:
		printf("egp     ");
		break;
	case f_GGP:
		printf("ggp     ");
		break;
	case f_HELLO:
		printf("hello   ");
		break;
	case f_RIP:
		printf("rip     ");
		break;
	case f_IS_IS:
		printf("is-is   ");
		break;
	case f_ES_IS:
		printf("es-is   ");
		break;
	case f_IGRP:
		printf("igrp    ");
		break;
	case f_BBNSPF:
		printf("bbnspf  ");
		break;
	case f_OSPF:
		printf("ospf    ");
		break;
	case f_BGP:
		printf("bgp     ");
		break;
	case f_IDPR:
		printf("idpr    ");
		break;
	default:
		printf("???     ");
		break;
	}
	printf("%-6d", cur->ipForwardMetric1);
	printf("%-6d\n", cur->ipForwardAge);
      }
      cur = cur->next;
    }
}
