/*
 * 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.
 *
 * Portions of this code may have been derived from code distributed
 * with the cmu-snmp1.2u.tar.Z distribution containing the following
 * copyright.
 *	Copyright 1988, 1989 by Carnegie Mellon University
 */

/**********************************************************************
 *
 * Name:        $RCSfile: collect-cmu.c,v $
 *
 * Dated:       $Date: 93/05/14 11:36:37 $
 *
 * Author:      $Author: pusateri $
 *
 * Revision:    $Revision: 1.4 $
 *
 * Description:
 *
 *
 ***********************************************************************/

#ifndef lint
static char RCSid[]=
"$Id: collect-cmu.c,v 1.4 93/05/14 11:36:37 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;

oid objid_ospfIfIpAddress[] = {1, 3, 6, 1, 2, 1, 14, 7, 1, 1};
int length_ospfIfIpAddress = sizeof(objid_ospfIfIpAddress)/sizeof(oid);
oid objid_ospfIfAreaId[] = {1, 3, 6, 1, 2, 1, 14, 7, 1, 3};
int length_ospfIfAreaId = sizeof(objid_ospfIfAreaId)/sizeof(oid);
oid objid_ospfIfType[] = {1, 3, 6, 1, 2, 1, 14, 7, 1, 4};
int length_ospfIfType = sizeof(objid_ospfIfType)/sizeof(oid);
oid objid_ospfIfRtrPriority[] = {1, 3, 6, 1, 2, 1, 14, 7, 1, 6};
int length_ospfIfRtrPriority = sizeof(objid_ospfIfRtrPriority)/sizeof(oid);
oid objid_ospfIfState[] = {1, 3, 6, 1, 2, 1, 14, 7, 1, 12};
int length_ospfIfState = sizeof(objid_ospfIfState)/sizeof(oid);
oid objid_ospfIfDesignatedRouter[] = {1, 3, 6, 1, 2, 1, 14, 7, 1, 13};
int length_ospfIfDesignatedRouter = sizeof(objid_ospfIfDesignatedRouter)/sizeof(oid);
oid objid_ospfIfBackupDesignatedRouter[] = {1, 3, 6, 1, 2, 1, 14, 7, 1, 14};
int length_ospfIfBackupDesignatedRouter = sizeof(objid_ospfIfBackupDesignatedRouter)/sizeof(oid);


void collect_ospf_interfaces(ss)
struct snmp_session *ss;
{
    struct ospfIf *cur;
    struct snmp_pdu *pdu, *response;
    struct variable_list *vars;
    int	    good_var, index;
    int	    status, count;

    pdu = snmp_pdu_create(GETNEXT_REQ_MSG);

    snmp_add_null_var(pdu, objid_ospfIfIpAddress, length_ospfIfIpAddress);
    snmp_add_null_var(pdu, objid_ospfIfAreaId, length_ospfIfAreaId);
    snmp_add_null_var(pdu, objid_ospfIfType, length_ospfIfType);
    snmp_add_null_var(pdu, objid_ospfIfRtrPriority, length_ospfIfRtrPriority);
    snmp_add_null_var(pdu, objid_ospfIfState, length_ospfIfState);
    snmp_add_null_var(pdu, objid_ospfIfDesignatedRouter, length_ospfIfDesignatedRouter);
    snmp_add_null_var(pdu, objid_ospfIfBackupDesignatedRouter, length_ospfIfBackupDesignatedRouter);

    good_var = 7;
    while(good_var == 7){
	good_var = 0;
	status = snmp_synch_response(ss, pdu, &response);
	if (status == STAT_SUCCESS){
	    if (response->errstat == SNMP_ERR_NOERROR){
		pdu = snmp_pdu_create(GETNEXT_REQ_MSG);

		index = 0;
		if (ifp == (struct ospfIf *) 0) {
		    ifp = (struct ospfIf *) malloc(sizeof(struct ospfIf));
		    cur = ifp;
		    cur->prev = (struct ospfIf *) 0;
		}
		else {
		    cur->next = (struct ospfIf *) malloc(sizeof(struct ospfIf));
		    cur->next->prev = cur;
		    cur = cur->next;
		}
		cur->next = (struct ospfIf *) 0;
		for(vars = response->variables; vars; vars = vars->next_variable) {
		    if (index == 0 && vars->name_length >= length_ospfIfIpAddress &&
			!bcmp((char *)objid_ospfIfIpAddress, (char *)vars->name,
			sizeof(objid_ospfIfIpAddress))){
			    cur->ospfIfIpAddress = *vars->val.integer;
			    snmp_add_null_var(pdu, vars->name, vars->name_length);
			    good_var++;
		    } else if (index == 1 && vars->name_length >= length_ospfIfAreaId &&
			!bcmp((char *)objid_ospfIfAreaId, (char *)vars->name,
			sizeof(objid_ospfIfAreaId))){
			    cur->ospfIfAreaId = *vars->val.integer;
			    snmp_add_null_var(pdu, vars->name, vars->name_length);
			    good_var++;
		    } else if (index == 2 && vars->name_length >= length_ospfIfType &&
			!bcmp((char *)objid_ospfIfType, (char *)vars->name,
			sizeof(objid_ospfIfType))){
			    cur->ospfIfType = *vars->val.integer;
			    snmp_add_null_var(pdu, vars->name, vars->name_length);
			    good_var++;
		    } else if (index == 3 && vars->name_length >= length_ospfIfRtrPriority &&
			!bcmp((char *)objid_ospfIfRtrPriority, (char *)vars->name,
			sizeof(objid_ospfIfRtrPriority))){
			    cur->ospfIfRtrPriority = *vars->val.integer;
			    snmp_add_null_var(pdu, vars->name, vars->name_length);
			    good_var++;
		    } else if (index == 4 && vars->name_length >= length_ospfIfState &&
			!bcmp((char *)objid_ospfIfState, (char *)vars->name,
			sizeof(objid_ospfIfState))){
			    cur->ospfIfState = *vars->val.integer;
			    snmp_add_null_var(pdu, vars->name, vars->name_length);
			    good_var++;
		    } else if (index == 5 && vars->name_length >= length_ospfIfDesignatedRouter &&
			!bcmp((char *)objid_ospfIfDesignatedRouter, (char *)vars->name,
			sizeof(objid_ospfIfDesignatedRouter))){
			    cur->ospfIfDesignatedRouter = *vars->val.integer;
			    snmp_add_null_var(pdu, vars->name, vars->name_length);
			    good_var++;
		    } else if (index == 6 && vars->name_length >= length_ospfIfBackupDesignatedRouter &&
			!bcmp((char *)objid_ospfIfBackupDesignatedRouter, (char *)vars->name,
			sizeof(objid_ospfIfBackupDesignatedRouter))){
			    cur->ospfIfBackupDesignatedRouter = *vars->val.integer;
			    snmp_add_null_var(pdu, vars->name, vars->name_length);
			    good_var++;
		    }
		    index++;
		}
	    } else {
		printf("Error in packet.\nReason: %s\n", snmp_errstring(response->errstat));
		if (response->errstat == SNMP_ERR_NOSUCHNAME){
		    printf("This name doesn't exist: ");
		    for(count = 1, vars = response->variables; vars && count != response->errindex;
			vars = vars->next_variable, count++)
			    ;
		    if (vars)
			print_objid(vars->name, vars->name_length);
		    printf("\n");
		}
	    }

	} else if (status == STAT_TIMEOUT){
	    printf("No Response from router\n");
	    exit(1);
	} else {    /* status == STAT_ERROR */
	    printf("An error occurred, Quitting\n");
	    exit(2);
	}

	if (response)
	    snmp_free_pdu(response);
    }
	/* get rid of last element that contains garbage. */
	/* this loop is ugly and copied from CMU. It needs rewritten */
    if (cur->prev) {
	cur->prev->next = (struct ospfIf *) 0;
	free(cur);
    }
}

oid objid_ospfNbrIpAddr[] = {1, 3, 6, 1, 2, 1, 14, 10, 1, 1};
int length_ospfNbrIpAddr = sizeof(objid_ospfNbrIpAddr)/sizeof(oid);
oid objid_ospfNbrRtrId[] = {1, 3, 6, 1, 2, 1, 14, 10, 1, 3};
int length_ospfNbrRtrId = sizeof(objid_ospfNbrRtrId)/sizeof(oid);
oid objid_ospfNbrPriority[] = {1, 3, 6, 1, 2, 1, 14, 10, 1, 5};
int length_ospfNbrPriority = sizeof(objid_ospfNbrPriority)/sizeof(oid);
oid objid_ospfNbrState[] = {1, 3, 6, 1, 2, 1, 14, 10, 1, 6};
int length_ospfNbrState = sizeof(objid_ospfNbrState)/sizeof(oid);


void collect_ospf_neighbors(ss)
struct snmp_session *ss;
{
    struct ospfNbr *cur;
    struct snmp_pdu *pdu, *response;
    struct variable_list *vars;
    int	    good_var, index;
    int	    status, count;

    pdu = snmp_pdu_create(GETNEXT_REQ_MSG);

    snmp_add_null_var(pdu, objid_ospfNbrIpAddr, length_ospfNbrIpAddr);
    snmp_add_null_var(pdu, objid_ospfNbrRtrId, length_ospfNbrRtrId);
    snmp_add_null_var(pdu, objid_ospfNbrPriority, length_ospfNbrPriority);
    snmp_add_null_var(pdu, objid_ospfNbrState, length_ospfNbrState);

    good_var = 4;
    while(good_var == 4){
	good_var = 0;
	status = snmp_synch_response(ss, pdu, &response);
	if (status == STAT_SUCCESS){
	    if (response->errstat == SNMP_ERR_NOERROR){
		pdu = snmp_pdu_create(GETNEXT_REQ_MSG);

		index = 0;
		if (nbrp == (struct ospfNbr *) 0) {
		    nbrp = (struct ospfNbr *) malloc(sizeof(struct ospfNbr));
		    cur = nbrp;
		    cur->prev = (struct ospfNbr *) 0;
		}
		else {
		    cur->next = (struct ospfNbr *) malloc(sizeof(struct ospfNbr));
		    cur->next->prev = cur;
		    cur = cur->next;
		}
		cur->next = (struct ospfNbr *) 0;
		for(vars = response->variables; vars; vars = vars->next_variable) {
		    if (index == 0 && vars->name_length >= length_ospfNbrIpAddr &&
			!bcmp((char *)objid_ospfNbrIpAddr, (char *)vars->name,
			sizeof(objid_ospfNbrIpAddr))){
			    cur->ospfNbrIpAddr = *vars->val.integer;
			    snmp_add_null_var(pdu, vars->name, vars->name_length);
			    good_var++;
		    } else if (index == 1 && vars->name_length >= length_ospfNbrRtrId &&
			!bcmp((char *)objid_ospfNbrRtrId, (char *)vars->name,
			sizeof(objid_ospfNbrRtrId))){
			    cur->ospfNbrRtrId = *vars->val.integer;
			    snmp_add_null_var(pdu, vars->name, vars->name_length);
			    good_var++;
		    } else if (index == 2 && vars->name_length >= length_ospfNbrPriority &&
			!bcmp((char *)objid_ospfNbrPriority, (char *)vars->name,
			sizeof(objid_ospfNbrPriority))){
			    cur->ospfNbrPriority = *vars->val.integer;
			    snmp_add_null_var(pdu, vars->name, vars->name_length);
			    good_var++;
		    } else if (index == 3 && vars->name_length >= length_ospfNbrState &&
			!bcmp((char *)objid_ospfNbrState, (char *)vars->name,
			sizeof(objid_ospfNbrState))){
			    cur->ospfNbrState = *vars->val.integer;
			    snmp_add_null_var(pdu, vars->name, vars->name_length);
			    good_var++;
		    }
		    index++;
		}
	    } else {
		printf("Error in packet.\nReason: %s\n", snmp_errstring(response->errstat));
		if (response->errstat == SNMP_ERR_NOSUCHNAME){
		    printf("This name doesn't exist: ");
		    for(count = 1, vars = response->variables; vars && count != response->errindex;
			vars = vars->next_variable, count++)
			    ;
		    if (vars)
			print_objid(vars->name, vars->name_length);
		    printf("\n");
		}
	    }

	} else if (status == STAT_TIMEOUT){
	    printf("No Response from router\n");
	    exit(1);
	} else {    /* status == STAT_ERROR */
	    printf("An error occurred, Quitting\n");
	    exit(2);
	}

	if (response)
	    snmp_free_pdu(response);
    }
	/* get rid of last element that contains garbage. */
	/* this loop is ugly and copied from CMU. It needs rewritten */
    if (cur->prev) {
	cur->prev->next = (struct ospfNbr *) 0;
	free(cur);
    }
}

oid objid_ospfLsdbAreaId[] = {1, 3, 6, 1, 2, 1, 14, 4, 1, 1};
int length_ospfLsdbAreaId = sizeof(objid_ospfLsdbAreaId)/sizeof(oid);
oid objid_ospfLsdbType[] = {1, 3, 6, 1, 2, 1, 14, 4, 1, 2};
int length_ospfLsdbType = sizeof(objid_ospfLsdbType)/sizeof(oid);
oid objid_ospfLsdbLSID[] = {1, 3, 6, 1, 2, 1, 14, 4, 1, 3};
int length_ospfLsdbLSID = sizeof(objid_ospfLsdbLSID)/sizeof(oid);
oid objid_ospfLsdbRouterId[] = {1, 3, 6, 1, 2, 1, 14, 4, 1, 4};
int length_ospfLsdbRouterId = sizeof(objid_ospfLsdbRouterId)/sizeof(oid);
oid objid_ospfLsdbSequence[] = {1, 3, 6, 1, 2, 1, 14, 4, 1, 5};
int length_ospfLsdbSequence = sizeof(objid_ospfLsdbSequence)/sizeof(oid);
oid objid_ospfLsdbAge[] = {1, 3, 6, 1, 2, 1, 14, 4, 1, 6};
int length_ospfLsdbAge = sizeof(objid_ospfLsdbAge)/sizeof(oid);
oid objid_ospfLsdbChecksum[] = {1, 3, 6, 1, 2, 1, 14, 4, 1, 7};
int length_ospfLsdbChecksum = sizeof(objid_ospfLsdbChecksum)/sizeof(oid);


void collect_ospf_lsdb(ss)
struct snmp_session *ss;
{
    struct ospfLsdb *cur;
    struct snmp_pdu *pdu, *response;
    struct variable_list *vars;
    int	    good_var, index;
    int	    status, count;

    pdu = snmp_pdu_create(GETNEXT_REQ_MSG);

    snmp_add_null_var(pdu, objid_ospfLsdbAreaId, length_ospfLsdbAreaId);
    snmp_add_null_var(pdu, objid_ospfLsdbType, length_ospfLsdbType);
    snmp_add_null_var(pdu, objid_ospfLsdbLSID, length_ospfLsdbLSID);
    snmp_add_null_var(pdu, objid_ospfLsdbRouterId, length_ospfLsdbRouterId);
    snmp_add_null_var(pdu, objid_ospfLsdbSequence, length_ospfLsdbSequence);
    snmp_add_null_var(pdu, objid_ospfLsdbAge, length_ospfLsdbAge);
    snmp_add_null_var(pdu, objid_ospfLsdbChecksum, length_ospfLsdbChecksum);

    good_var = 7;
    while(good_var == 7){
	good_var = 0;
	status = snmp_synch_response(ss, pdu, &response);
	if (status == STAT_SUCCESS){
	    if (response->errstat == SNMP_ERR_NOERROR){
		pdu = snmp_pdu_create(GETNEXT_REQ_MSG);

		index = 0;
		if (lsdbp == (struct ospfLsdb *) 0) {
		    lsdbp = (struct ospfLsdb *) malloc(sizeof(struct ospfLsdb));
		    cur = lsdbp;
		    cur->prev = (struct ospfLsdb *) 0;
		}
		else {
		    cur->next = (struct ospfLsdb *) malloc(sizeof(struct ospfLsdb));
		    cur->next->prev = cur;
		    cur = cur->next;
		}
		cur->next = (struct ospfLsdb *) 0;
		for(vars = response->variables; vars; vars = vars->next_variable) {
		    if (index == 0 && vars->name_length >= length_ospfLsdbAreaId &&
			!bcmp((char *)objid_ospfLsdbAreaId, (char *)vars->name,
			sizeof(objid_ospfLsdbAreaId))){
			    cur->ospfLsdbAreaId = *vars->val.integer;
			    snmp_add_null_var(pdu, vars->name, vars->name_length);
			    good_var++;
		    } else if (index == 1 && vars->name_length >= length_ospfLsdbType &&
			!bcmp((char *)objid_ospfLsdbType, (char *)vars->name,
			sizeof(objid_ospfLsdbType))){
			    cur->ospfLsdbType = *vars->val.integer;
			    snmp_add_null_var(pdu, vars->name, vars->name_length);
			    good_var++;
		    } else if (index == 2 && vars->name_length >= length_ospfLsdbLSID &&
			!bcmp((char *)objid_ospfLsdbLSID, (char *)vars->name,
			sizeof(objid_ospfLsdbLSID))){
			    cur->ospfLsdbLSID = *vars->val.integer;
			    snmp_add_null_var(pdu, vars->name, vars->name_length);
			    good_var++;
		    } else if (index == 3 && vars->name_length >= length_ospfLsdbRouterId &&
			!bcmp((char *)objid_ospfLsdbRouterId, (char *)vars->name,
			sizeof(objid_ospfLsdbRouterId))){
			    cur->ospfLsdbRouterId = *vars->val.integer;
			    snmp_add_null_var(pdu, vars->name, vars->name_length);
			    good_var++;
		    } else if (index == 4 && vars->name_length >= length_ospfLsdbSequence &&
			!bcmp((char *)objid_ospfLsdbSequence, (char *)vars->name,
			sizeof(objid_ospfLsdbSequence))){
			    cur->ospfLsdbSequence = *vars->val.integer;
			    snmp_add_null_var(pdu, vars->name, vars->name_length);
			    good_var++;
		    } else if (index == 5 && vars->name_length >= length_ospfLsdbAge &&
			!bcmp((char *)objid_ospfLsdbAge, (char *)vars->name,
			sizeof(objid_ospfLsdbAge))){
			    cur->ospfLsdbAge = *vars->val.integer;
			    snmp_add_null_var(pdu, vars->name, vars->name_length);
			    good_var++;
		    } else if (index == 6 && vars->name_length >= length_ospfLsdbChecksum &&
			!bcmp((char *)objid_ospfLsdbChecksum, (char *)vars->name,
			sizeof(objid_ospfLsdbChecksum))){
			    cur->ospfLsdbChecksum = *vars->val.integer;
			    snmp_add_null_var(pdu, vars->name, vars->name_length);
			    good_var++;
		    }
		    index++;
		}
	    } else {
		printf("Error in packet.\nReason: %s\n", snmp_errstring(response->errstat));
		if (response->errstat == SNMP_ERR_NOSUCHNAME){
		    printf("This name doesn't exist: ");
		    for(count = 1, vars = response->variables; vars && count != response->errindex;
			vars = vars->next_variable, count++)
			    ;
		    if (vars)
			print_objid(vars->name, vars->name_length);
		    printf("\n");
		}
	    }

	} else if (status == STAT_TIMEOUT){
	    printf("No Response from router\n");
	    exit(1);
	} else {    /* status == STAT_ERROR */
	    printf("An error occurred, Quitting\n");
	    exit(2);
	}

	if (response)
	    snmp_free_pdu(response);
    }
	/* get rid of last element that contains garbage. */
	/* this loop is ugly and copied from CMU. It needs rewritten */
    if (cur->prev) {
	cur->prev->next = (struct ospfLsdb *) 0;
	free(cur);
    }
}

oid objid_ospfLsdbAdvertisement[] = {1, 3, 6, 1, 2, 1, 14, 4, 1, 8};
int length_ospfLsdbAdvertisement = sizeof(objid_ospfLsdbAdvertisement)/sizeof(oid);


void collect_ospf_lsa(ss)
struct snmp_session *ss;
{
    struct ospf_advlist *cur;
    struct snmp_pdu *pdu, *response;
    struct variable_list *vars;
    int	    good_var, index;
    int	    status, count;

    pdu = snmp_pdu_create(GETNEXT_REQ_MSG);

    snmp_add_null_var(pdu, objid_ospfLsdbAdvertisement, length_ospfLsdbAdvertisement);

    good_var = 1;
    while(good_var == 1){
	good_var = 0;
	status = snmp_synch_response(ss, pdu, &response);
	if (status == STAT_SUCCESS){
	    if (response->errstat == SNMP_ERR_NOERROR){
		pdu = snmp_pdu_create(GETNEXT_REQ_MSG);

		index = 0;
		if (ap == (struct ospf_advlist *) 0) {
		    ap = (struct ospf_advlist *) malloc(sizeof(struct ospf_advlist));
		    cur = ap;
		    cur->prev = (struct ospf_advlist *) 0;
		}
		else {
		    cur->next = (struct ospf_advlist *) malloc(sizeof(struct ospf_advlist));
		    cur->next->prev = cur;
		    cur = cur->next;
		}
		cur->next = (struct ospf_advlist *) 0;
		for(vars = response->variables; vars; vars = vars->next_variable) {
		    if (index == 0 && vars->name_length >= length_ospfLsdbAdvertisement &&
			!bcmp((char *)objid_ospfLsdbAdvertisement, (char *)vars->name,
			sizeof(objid_ospfLsdbAdvertisement))){
			    cur->entry = (struct ospfLsdbAdvertisement *) malloc(vars->val_len + 1);
			    bcopy(vars->val.string, (char *) cur->entry, vars->val_len);
			    snmp_add_null_var(pdu, vars->name, vars->name_length);
			    good_var++;
		    }
		    index++;
		}
	    } else {
		printf("Error in packet.\nReason: %s\n", snmp_errstring(response->errstat));
		if (response->errstat == SNMP_ERR_NOSUCHNAME){
		    printf("This name doesn't exist: ");
		    for(count = 1, vars = response->variables; vars && count != response->errindex;
			vars = vars->next_variable, count++)
			    ;
		    if (vars)
			print_objid(vars->name, vars->name_length);
		    printf("\n");
		}
	    }

	} else if (status == STAT_TIMEOUT){
	    printf("No Response from router\n");
	    exit(1);
	} else {    /* status == STAT_ERROR */
	    printf("An error occurred, Quitting\n");
	    exit(2);
	}

	if (response)
	    snmp_free_pdu(response);
    }
	/* get rid of last element that contains garbage. */
	/* this loop is ugly and copied from CMU. It needs rewritten */
    if (cur->prev) {
	cur->prev->next = (struct ospf_advlist *) 0;
	free(cur);
    }
}

oid objid_ipRouteDest[] = {1, 3, 6, 1, 2, 1, 4, 21, 1, 1};
int length_ipRouteDest = sizeof(objid_ipRouteDest)/sizeof(oid);
oid objid_ipRouteMetric1[] = {1, 3, 6, 1, 2, 1, 4, 21, 1, 3};
int length_ipRouteMetric1 = sizeof(objid_ipRouteMetric1)/sizeof(oid);
oid objid_ipRouteNextHop[] = {1, 3, 6, 1, 2, 1, 4, 21, 1, 7};
int length_ipRouteNextHop = sizeof(objid_ipRouteNextHop)/sizeof(oid);
oid objid_ipRouteType[] = {1, 3, 6, 1, 2, 1, 4, 21, 1, 8};
int length_ipRouteType = sizeof(objid_ipRouteType)/sizeof(oid);
oid objid_ipRouteProto[] = {1, 3, 6, 1, 2, 1, 4, 21, 1, 9};
int length_ipRouteProto = sizeof(objid_ipRouteProto)/sizeof(oid);
oid objid_ipRouteAge[] = {1, 3, 6, 1, 2, 1, 4, 21, 1, 10};
int length_ipRouteAge = sizeof(objid_ipRouteAge)/sizeof(oid);
oid objid_ipRouteMask[] = {1, 3, 6, 1, 2, 1, 4, 21, 1, 11};
int length_ipRouteMask = sizeof(objid_ipRouteMask)/sizeof(oid);


void collect_route_table(ss)
struct snmp_session *ss;
{
    struct ospfRT *cur;
    struct snmp_pdu *pdu, *response;
    struct variable_list *vars;
    int	    good_var, index;
    int	    status, count;

    pdu = snmp_pdu_create(GETNEXT_REQ_MSG);

    snmp_add_null_var(pdu, objid_ipRouteDest, length_ipRouteDest);
    snmp_add_null_var(pdu, objid_ipRouteMetric1, length_ipRouteMetric1);
    snmp_add_null_var(pdu, objid_ipRouteNextHop, length_ipRouteNextHop);
    snmp_add_null_var(pdu, objid_ipRouteType, length_ipRouteType);
    snmp_add_null_var(pdu, objid_ipRouteProto, length_ipRouteProto);
    snmp_add_null_var(pdu, objid_ipRouteAge, length_ipRouteAge);
    snmp_add_null_var(pdu, objid_ipRouteMask, length_ipRouteMask);

    good_var = 7;
    while(good_var == 7){
	good_var = 0;
	status = snmp_synch_response(ss, pdu, &response);
	if (status == STAT_SUCCESS){
	    if (response->errstat == SNMP_ERR_NOERROR){
		pdu = snmp_pdu_create(GETNEXT_REQ_MSG);

		index = 0;
		if (rtp == (struct ospfRT *) 0) {
		    rtp = (struct ospfRT *) malloc(sizeof(struct ospfRT));
		    cur = rtp;
		    cur->prev = (struct ospfRT *) 0;
		}
		else {
		    cur->next = (struct ospfRT *) malloc(sizeof(struct ospfRT));
		    cur->next->prev = cur;
		    cur = cur->next;
		}
		cur->next = (struct ospfRT *) 0;
		for(vars = response->variables; vars; vars = vars->next_variable) {
		    if (index == 0 && vars->name_length >= length_ipRouteDest &&
			!bcmp((char *)objid_ipRouteDest, (char *)vars->name,
			sizeof(objid_ipRouteDest))){
			    cur->ipRouteDest = *vars->val.integer;
			    snmp_add_null_var(pdu, vars->name, vars->name_length);
			    good_var++;
		    } else if (index == 1 && vars->name_length >= length_ipRouteMetric1 &&
			!bcmp((char *)objid_ipRouteMetric1, (char *)vars->name,
			sizeof(objid_ipRouteMetric1))){
			    cur->ipRouteMetric1 = *vars->val.integer;
			    snmp_add_null_var(pdu, vars->name, vars->name_length);
			    good_var++;
		    } else if (index == 2 && vars->name_length >= length_ipRouteNextHop &&
			!bcmp((char *)objid_ipRouteNextHop, (char *)vars->name,
			sizeof(objid_ipRouteNextHop))){
			    cur->ipRouteNextHop = *vars->val.integer;
			    snmp_add_null_var(pdu, vars->name, vars->name_length);
			    good_var++;
		    } else if (index == 3 && vars->name_length >= length_ipRouteType &&
			!bcmp((char *)objid_ipRouteType, (char *)vars->name,
			sizeof(objid_ipRouteType))){
			    cur->ipRouteType = *vars->val.integer;
			    snmp_add_null_var(pdu, vars->name, vars->name_length);
			    good_var++;
		    } else if (index == 4 && vars->name_length >= length_ipRouteProto &&
			!bcmp((char *)objid_ipRouteProto, (char *)vars->name,
			sizeof(objid_ipRouteProto))){
			    cur->ipRouteProto = *vars->val.integer;
			    snmp_add_null_var(pdu, vars->name, vars->name_length);
			    good_var++;
		    } else if (index == 5 && vars->name_length >= length_ipRouteAge &&
			!bcmp((char *)objid_ipRouteAge, (char *)vars->name,
			sizeof(objid_ipRouteAge))){
			    cur->ipRouteAge = *vars->val.integer;
			    snmp_add_null_var(pdu, vars->name, vars->name_length);
			    good_var++;
		    } else if (index == 6 && vars->name_length >= length_ipRouteMask &&
			!bcmp((char *)objid_ipRouteMask, (char *)vars->name,
			sizeof(objid_ipRouteMask))){
			    cur->ipRouteMask = *vars->val.integer;
			    snmp_add_null_var(pdu, vars->name, vars->name_length);
			    good_var++;
		    }
		    index++;
		}
	    } else {
		printf("Error in packet.\nReason: %s\n", snmp_errstring(response->errstat));
		if (response->errstat == SNMP_ERR_NOSUCHNAME){
		    printf("This name doesn't exist: ");
		    for(count = 1, vars = response->variables; vars && count != response->errindex;
			vars = vars->next_variable, count++)
			    ;
		    if (vars)
			print_objid(vars->name, vars->name_length);
		    printf("\n");
		}
	    }

	} else if (status == STAT_TIMEOUT){
	    printf("No Response from router\n");
	    exit(1);
	} else {    /* status == STAT_ERROR */
	    printf("An error occurred, Quitting\n");
	    exit(2);
	}

	if (response)
	    snmp_free_pdu(response);
    }
	/* get rid of last element that contains garbage. */
	/* this loop is ugly and copied from CMU. It needs rewritten */
    if (cur->prev) {
	cur->prev->next = (struct ospfRT *) 0;
	free(cur);
    }
}

oid objid_ipForwardDest[] = {1, 3, 6, 1, 2, 1, 4, 24, 2, 1, 1};
int length_ipForwardDest = sizeof(objid_ipForwardDest)/sizeof(oid);
oid objid_ipForwardMask[] = {1, 3, 6, 1, 2, 1, 4, 24, 2, 1, 2};
int length_ipForwardMask = sizeof(objid_ipForwardMask)/sizeof(oid);
oid objid_ipForwardNextHop[] = {1, 3, 6, 1, 2, 1, 4, 24, 2, 1, 4};
int length_ipForwardNextHop = sizeof(objid_ipForwardNextHop)/sizeof(oid);
oid objid_ipForwardType[] = {1, 3, 6, 1, 2, 1, 4, 24, 2, 1, 6};
int length_ipForwardType = sizeof(objid_ipForwardType)/sizeof(oid);
oid objid_ipForwardProto[] = {1, 3, 6, 1, 2, 1, 4, 24, 2, 1, 7};
int length_ipForwardProto = sizeof(objid_ipForwardProto)/sizeof(oid);
oid objid_ipForwardAge[] = {1, 3, 6, 1, 2, 1, 4, 24, 2, 1, 8};
int length_ipForwardAge = sizeof(objid_ipForwardAge)/sizeof(oid);
oid objid_ipForwardMetric1[] = {1, 3, 6, 1, 2, 1, 4, 24, 2, 1, 11};
int length_ipForwardMetric1 = sizeof(objid_ipForwardMetric1)/sizeof(oid);


void collect_forward_table(ss)
struct snmp_session *ss;
{
    struct ospfFT *cur;
    struct snmp_pdu *pdu, *response;
    struct variable_list *vars;
    int	    good_var, index;
    int	    status, count;

    pdu = snmp_pdu_create(GETNEXT_REQ_MSG);

    snmp_add_null_var(pdu, objid_ipForwardDest, length_ipForwardDest);
    snmp_add_null_var(pdu, objid_ipForwardMask, length_ipForwardMask);
    snmp_add_null_var(pdu, objid_ipForwardNextHop, length_ipForwardNextHop);
    snmp_add_null_var(pdu, objid_ipForwardType, length_ipForwardType);
    snmp_add_null_var(pdu, objid_ipForwardProto, length_ipForwardProto);
    snmp_add_null_var(pdu, objid_ipForwardAge, length_ipForwardAge);
    snmp_add_null_var(pdu, objid_ipForwardMetric1, length_ipForwardMetric1);

    good_var = 7;
    while(good_var == 7){
	good_var = 0;
	status = snmp_synch_response(ss, pdu, &response);
	if (status == STAT_SUCCESS){
	    if (response->errstat == SNMP_ERR_NOERROR){
		pdu = snmp_pdu_create(GETNEXT_REQ_MSG);

		index = 0;
		if (ftp == (struct ospfFT *) 0) {
		    ftp = (struct ospfFT *) malloc(sizeof(struct ospfFT));
		    cur = ftp;
		    cur->prev = (struct ospfFT *) 0;
		}
		else {
		    cur->next = (struct ospfFT *) malloc(sizeof(struct ospfFT));
		    cur->next->prev = cur;
		    cur = cur->next;
		}
		cur->next = (struct ospfFT *) 0;
		for(vars = response->variables; vars; vars = vars->next_variable) {
		    if (index == 0 && vars->name_length >= length_ipForwardDest &&
			!bcmp((char *)objid_ipForwardDest, (char *)vars->name,
			sizeof(objid_ipForwardDest))){
			    cur->ipForwardDest = *vars->val.integer;
			    snmp_add_null_var(pdu, vars->name, vars->name_length);
			    good_var++;
		    } else if (index == 1 && vars->name_length >= length_ipForwardMask &&
			!bcmp((char *)objid_ipForwardMask, (char *)vars->name,
			sizeof(objid_ipForwardMask))){
			    cur->ipForwardMask = *vars->val.integer;
			    snmp_add_null_var(pdu, vars->name, vars->name_length);
			    good_var++;
		    } else if (index == 2 && vars->name_length >= length_ipForwardNextHop &&
			!bcmp((char *)objid_ipForwardNextHop, (char *)vars->name,
			sizeof(objid_ipForwardNextHop))){
			    cur->ipForwardNextHop = *vars->val.integer;
			    snmp_add_null_var(pdu, vars->name, vars->name_length);
			    good_var++;
		    } else if (index == 3 && vars->name_length >= length_ipForwardType &&
			!bcmp((char *)objid_ipForwardType, (char *)vars->name,
			sizeof(objid_ipForwardType))){
			    cur->ipForwardType = *vars->val.integer;
			    snmp_add_null_var(pdu, vars->name, vars->name_length);
			    good_var++;
		    } else if (index == 4 && vars->name_length >= length_ipForwardProto &&
			!bcmp((char *)objid_ipForwardProto, (char *)vars->name,
			sizeof(objid_ipForwardProto))){
			    cur->ipForwardProto = *vars->val.integer;
			    snmp_add_null_var(pdu, vars->name, vars->name_length);
			    good_var++;
		    } else if (index == 5 && vars->name_length >= length_ipForwardAge &&
			!bcmp((char *)objid_ipForwardAge, (char *)vars->name,
			sizeof(objid_ipForwardAge))){
			    cur->ipForwardAge = *vars->val.integer;
			    snmp_add_null_var(pdu, vars->name, vars->name_length);
			    good_var++;
		    } else if (index == 6 && vars->name_length >= length_ipForwardMetric1 &&
			!bcmp((char *)objid_ipForwardMetric1, (char *)vars->name,
			sizeof(objid_ipForwardMetric1))){
			    cur->ipForwardMetric1 = *vars->val.integer;
			    snmp_add_null_var(pdu, vars->name, vars->name_length);
			    good_var++;
		    }
		    index++;
		}
	    } else {
		printf("Error in packet.\nReason: %s\n", snmp_errstring(response->errstat));
		if (response->errstat == SNMP_ERR_NOSUCHNAME){
		    printf("This name doesn't exist: ");
		    for(count = 1, vars = response->variables; vars && count != response->errindex;
			vars = vars->next_variable, count++)
			    ;
		    if (vars)
			print_objid(vars->name, vars->name_length);
		    printf("\n");
		}
	    }

	} else if (status == STAT_TIMEOUT){
	    printf("No Response from router\n");
	    exit(1);
	} else {    /* status == STAT_ERROR */
	    printf("An error occurred, Quitting\n");
	    exit(2);
	}

	if (response)
	    snmp_free_pdu(response);
    }
	/* get rid of last element that contains garbage. */
	/* this loop is ugly and copied from CMU. It needs rewritten */
    if (cur->prev) {
	cur->prev->next = (struct ospfFT *) 0;
	free(cur);
    }
}
