home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-11-07 | 64.0 KB | 2,130 lines |
- Newsgroups: comp.sources.misc
- From: nevil@ccu1.aukuni.ac.nz (J Nevil Brownlee)
- Subject: v40i107: netramet - Network Traffic Accounting Meter, Part19/25
- Message-ID: <1993Nov7.221409.12568@sparky.sterling.com>
- X-Md4-Signature: 056c3eed425e1490b79a96528a729666
- Sender: kent@sparky.sterling.com (Kent Landfield)
- Organization: Sterling Software
- Date: Sun, 7 Nov 1993 22:14:09 GMT
- Approved: kent@sparky.sterling.com
-
- Submitted-by: nevil@ccu1.aukuni.ac.nz (J Nevil Brownlee)
- Posting-number: Volume 40, Issue 107
- Archive-name: netramet/part19
- Environment: INET, UNIX, DOS
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then feed it
- # into a shell via "sh file" or similar. To overwrite existing files,
- # type "sh file -c".
- # Contents: netramet/src/manager/oldnm.c
- # netramet/src/snmplib/snmpapi.c
- # netramet/src/snmplib/~snmp_vars.h.kip
- # Wrapped by kent@sparky on Tue Nov 2 18:17:11 1993
- PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
- echo If this archive is complete, you will see the following message:
- echo ' "shar: End of archive 19 (of 25)."'
- if test -f 'netramet/src/manager/oldnm.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'netramet/src/manager/oldnm.c'\"
- else
- echo shar: Extracting \"'netramet/src/manager/oldnm.c'\" \(29675 characters\)
- sed "s/^X//" >'netramet/src/manager/oldnm.c' <<'END_OF_FILE'
- X/* 1200, Fri 23 Oct 92
- X
- X NM.C: First attempt at a manager for the AU Accounting Meter
- X
- X Copyright (C) 1992 by Nevil Brownlee,
- X Computer Centre, University of Auckland */
- X
- X/***********************************************************
- X Copyright 1988 by Carnegie Mellon University
- X
- X All Rights Reserved
- X
- XPermission to use, copy, modify, and distribute this software and its
- Xdocumentation for any purpose and without fee is hereby granted,
- Xprovided that the above copyright notice appear in all copies and that
- Xboth that copyright notice and this permission notice appear in
- Xsupporting documentation, and that the name of CMU not be
- Xused in advertising or publicity pertaining to distribution of the
- Xsoftware without specific, written prior permission.
- X
- XCMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
- XALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
- XCMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
- XANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- XWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
- XARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- XSOFTWARE.
- X******************************************************************/
- X#include <sys/param.h>
- X#include <sys/types.h>
- X#include <netinet/in.h>
- X#include <netdb.h>
- X
- X#include <stdio.h>
- X#include <ctype.h>
- X#include <sys/time.h>
- X#include <errno.h>
- X
- X#include <string.h>
- X#include <malloc.h>
- X
- X#include "snmp.h"
- X#include "snmpimpl.h"
- X#include "asn1.h"
- X#include "snmpclnt.h"
- X#include "snmpapi.h"
- X#include "mib.h"
- X
- X#ifndef BSD4_3
- X#define BSD4_2
- X#endif
- X
- X#define FLOWLIMIT 6000
- X#define RULEFILE "rules.txt"
- X
- Xextern int errno;
- Xint snmp_dump_packet = 0;
- X
- X#define INT_ACCT 1, 3, 6, 1, 3, 99
- X#define AUKUNI 1, 3, 6, 1, 4, 1, 411
- X
- Xoid o_sysDescr[] = {MIB, 1, 1, 0};
- Xoid o_sysUpTime[] = {MIB, 1, 3, 0};
- Xoid o_ifNumber[] = {MIB, 2, 1, 0};
- X
- X#define FT_INDEX (sizeof(o_ftFlowNbr)/sizeof(oid) - 1)
- X
- Xoid o_ftFlowNbr[] = {INT_ACCT, 3, 1, 1, 0xFFFF};
- Xoid o_ftFlowStatus[] = {INT_ACCT, 3, 1, 2, 0xFFFF};
- Xoid o_ftNextActiveFlow[] = {INT_ACCT, 3, 1, 3, 0xFFFF};
- Xoid o_ftAddrType[] = {INT_ACCT, 3, 1, 4, 0xFFFF};
- Xoid o_ftFromAddr[] = {INT_ACCT, 3, 1, 5, 0xFFFF};
- Xoid o_ftFromMask[] = {INT_ACCT, 3, 1, 6, 0xFFFF};
- Xoid o_ftFromTally[] = {INT_ACCT, 3, 1, 7, 0xFFFF};
- Xoid o_ftToAddr[] = {INT_ACCT, 3, 1, 8, 0xFFFF};
- Xoid o_ftToMask[] = {INT_ACCT, 3, 1, 9, 0xFFFF};
- Xoid o_ftToTally[] = {INT_ACCT, 3, 1,10, 0xFFFF};
- Xoid o_ftFwdPackets[] = {INT_ACCT, 3, 1,11, 0xFFFF};
- Xoid o_ftFwdBytes[] = {INT_ACCT, 3, 1,12, 0xFFFF};
- Xoid o_ftBackPackets[] = {INT_ACCT, 3, 1,13, 0xFFFF};
- Xoid o_ftBackBytes[] = {INT_ACCT, 3, 1,14, 0xFFFF};
- Xoid o_ftChkFwdPackets[] = {INT_ACCT, 3, 1,15, 0xFFFF};
- Xoid o_ftChkFwdBytes[] = {INT_ACCT, 3, 1,16, 0xFFFF};
- Xoid o_ftChkBackPackets[] = {INT_ACCT, 3, 1,17, 0xFFFF};
- Xoid o_ftChkBackBytes[] = {INT_ACCT, 3, 1,18, 0xFFFF};
- Xoid o_ftFlowBlob[] = {INT_ACCT, 3, 1,19, 0xFFFF};
- Xoid o_ftFlowCount[] = {INT_ACCT, 3, 2, 0};
- Xoid o_ftChkTime[] = {INT_ACCT, 3, 3, 0};
- Xoid o_ftChkFlowCount[] = {INT_ACCT, 3, 4, 0};
- Xoid o_ftPrevChkTime[] = {INT_ACCT, 3, 5, 0};
- Xoid o_ftChkActFlows[] = {INT_ACCT, 3, 6, 0};
- Xoid o_ftFirstActFlow[] = {INT_ACCT, 3, 7, 0};
- Xoid o_ftCheckPoint[] = {INT_ACCT, 3, 8, 0};
- X
- X#define RT_INDEX (sizeof(o_rtIndex)/sizeof(oid) - 1)
- X
- Xoid o_rtIndex[] = {INT_ACCT, 4, 1, 1, 0xFFFF};
- Xoid o_rtTreeNbr[] = {INT_ACCT, 4, 1, 2, 0xFFFF};
- Xoid o_rtAddrType[] = {INT_ACCT, 4, 1, 3, 0xFFFF};
- Xoid o_rtFromAddr[] = {INT_ACCT, 4, 1, 4, 0xFFFF};
- Xoid o_rtFromMask[] = {INT_ACCT, 4, 1, 5, 0xFFFF};
- Xoid o_rtFromTally[] = {INT_ACCT, 4, 1, 6, 0xFFFF};
- Xoid o_rtToAddr[] = {INT_ACCT, 4, 1, 7, 0xFFFF};
- Xoid o_rtToMask[] = {INT_ACCT, 4, 1, 8, 0xFFFF};
- Xoid o_rtToTally[] = {INT_ACCT, 4, 1, 9, 0xFFFF};
- X
- Xoid o_crRuleCount[] = {INT_ACCT, 4, 2, 0};
- Xoid o_crTreeNbr[] = {INT_ACCT, 4, 3, 0};
- Xoid o_crAddrType[] = {INT_ACCT, 4, 4, 0};
- Xoid o_crFromAddr[] = {INT_ACCT, 4, 5, 0};
- Xoid o_crFromMask[] = {INT_ACCT, 4, 6, 0};
- Xoid o_crFromTally[] = {INT_ACCT, 4, 7, 0};
- Xoid o_crToAddr[] = {INT_ACCT, 4, 8, 0};
- Xoid o_crToMask[] = {INT_ACCT, 4, 9, 0};
- Xoid o_crToTally[] = {INT_ACCT, 4,10, 0};
- X
- X#define PT_INDEX (sizeof(o_ptPacketType) - 1)
- X
- Xoid o_ptpacket_types[] = {AUKUNI, 1, 1, 0};
- Xoid o_ptPacketType[] = {AUKUNI, 1, 2, 1, 1, 0xFF};
- Xoid o_ptPacketCount[] = {AUKUNI, 1, 2, 1, 2, 0xFF};
- Xoid o_ptByteCount[] = {AUKUNI, 1, 2, 1, 3, 0xFF};
- X
- Xoid o_pcNearMem[] = {AUKUNI, 2, 1, 0};
- Xoid o_pcFarMem[] = {AUKUNI, 2, 2, 0};
- Xoid o_pcBadPackets[] = {AUKUNI, 2, 3, 0};
- Xoid o_pcNoBufPackets[] = {AUKUNI, 2, 4, 0};
- Xoid o_pcLostPackets[] = {AUKUNI, 2, 5, 0};
- Xoid o_pcPacketBacklog[] = {AUKUNI, 2, 6, 0};
- Xoid o_pcChkSearches[] = {AUKUNI, 2, 7, 0};
- Xoid o_pcChkCompares[] = {AUKUNI, 2, 8, 0};
- X
- X
- X#define ADDR_LEN 4
- X
- Xstruct flow_info {
- X unsigned char AddrType,
- X FromAddr[ADDR_LEN], FromMask[ADDR_LEN], FromTally[ADDR_LEN],
- X ToAddr[ADDR_LEN], ToMask[ADDR_LEN], ToTally[ADDR_LEN];
- X unsigned long
- X FwdPackets,FwdBytes, BackPackets,BackBytes;
- X unsigned short NextActiveFlow;
- X };
- X
- Xstruct rule_info {
- X int RuleNbr;
- X unsigned char TreeNbr, AddrType,
- X FromAddr[ADDR_LEN], FromMask[ADDR_LEN], FromTally[ADDR_LEN],
- X ToAddr[ADDR_LEN], ToMask[ADDR_LEN], ToTally[ADDR_LEN];
- X };
- X
- X#define AT_IGNORE 0 /* Addr_type values */
- X#define AT_IP 1
- X#define AT_NOVELL 2
- X#define AT_DECNET 3
- X#define AT_ETHERTALK 4
- X
- X#define NAME_LN 64
- X
- Xstruct meter_status {
- X struct meter_status *next;
- X
- X char name[NAME_LN];
- X char community[NAME_LN];
- X char rulefile[NAME_LN];
- X
- X struct snmp_session *ss;
- X
- X short status;
- X
- X char descr[NAME_LN]; /* From meter_info() */
- X long uptime;
- X short ifcount;
- X
- X unsigned short flowcount; /* Current nbr of flows */
- X unsigned short rulecount; /* and rules */
- X
- X unsigned short flowsknown; /* Nbr of flows we have key data for */
- X
- X unsigned short CheckPoint;
- X unsigned short ChkFlowCount;
- X unsigned short ChkActFlows;
- X unsigned short FirstActFlow;
- X long ChkTime;
- X long PrevChkTime;
- X
- X FILE *keys;
- X FILE *flows;
- X FILE *log;
- X };
- X
- Xstruct meter_status *first_meter;
- X
- X/* Values for status */
- X
- X#define MT_MANAGE 0x0001 /* Manage this meter */
- X#define MT_INFO 0x0002 /* Have basic info */
- X#define MT_UP 0x0004 /* Meter is running */
- X#define MT_REPORTED 0x0008 /* Current status reported */
- X
- X#ifdef MTR_LIST
- X/* #define CTLFILE "/usr/local/src/snmp/manager.cfg" */
- X#define CTLFILE "manager.cfg"
- X#endif
- X
- Xunsigned short getshort(unsigned char *ucp);
- Xunsigned long getlong(unsigned char *ucp);
- X
- Xvoid init_meter();
- Xvoid monitor_meter();
- Xvoid monitor(struct meter_status *ms);
- Xvoid print_meters();
- Xvoid meter_print(struct meter_status *ms);
- X
- Xvoid printaddress(FILE *f,unsigned char *a);
- Xvoid getaddress(unsigned char *a);
- X
- Xvoid parse_rulefile(struct meter_status *ms, int list);
- Xint add_rule(struct meter_status *ms, struct rule_info *ri);
- X
- Xint chk_info(struct meter_status *ms, int control);
- X
- Xint blob_info(struct meter_status *ms, unsigned char *fb, int fn);
- Xint flow_info(struct meter_status *ms, struct flow_info *fi,
- X int fn, int getkey, int getflow);
- X
- Xchar *uptime_string(unsigned long timeticks, char *buf);
- X
- Xint verbose;
- X
- Xvoid main(argc,argv)
- Xint argc;
- Xchar *argv[];
- X{
- X struct meter_status *ms;
- X struct snmp_session session, *ssp;
- X
- X int arg;
- X char meter[NAME_LN], community[NAME_LN], rfname[NAME_LN],
- X filename[NAME_LN*2];
- X int interval = 0;
- X
- X meter[0] = community[0] = rfname[0] = NULL;
- X
- X#ifdef MTR_LIST
- X parse_ctlfile();
- X#endif
- X
- X init_mib();
- X
- X /* usage: nm meter-name community */
- X
- X for (arg = 1; arg < argc; arg++) {
- X if (argv[arg][0] == '-') {
- X switch (argv[arg][1]) {
- X case 'd':
- X snmp_dump_packet++;
- X break;
- X case 'c':
- X if ((interval = atoi(argv[arg]+2)) == 0) interval = 120;
- X break;
- X case 'r':
- X strcpy(rfname, argv[++arg]);
- X break;
- X case 'v':
- X verbose++;
- X break;
- X default:
- X printf("Invalid option: -%c\n", argv[arg][1]);
- X break;
- X }
- X continue;
- X }
- X if (meter[0] == NULL) strcpy(meter,argv[arg]);
- X else if (community[0] == NULL) strcpy(community,argv[arg]);
- X }
- X
- X if (meter[0] == NULL) {
- X printf("nm meter-name community\n\n");
- X exit(0);
- X }
- X
- X ms = (struct meter_status *)calloc(sizeof(struct meter_status), 1);
- X strcpy(ms->name,meter);
- X strcpy(ms->community,community);
- X if (*rfname) strcpy(ms->rulefile, rfname);
- X else strcpy(ms->rulefile, RULEFILE);
- X
- X strcpy(filename,meter);
- X strcat(filename,".log");
- X if ((ms->log = fopen(filename,"wa")) == NULL) {
- X printf("Failed to open %s\n",filename);
- X exit(0);
- X }
- X strcpy(filename,meter);
- X strcat(filename,".keys");
- X if ((ms->keys = fopen(filename,"wa")) == NULL) {
- X printf("Failed to open %s\n",filename);
- X exit(0);
- X }
- X strcpy(filename,meter);
- X strcat(filename,".flows");
- X if ((ms->flows = fopen(filename,"wa")) == NULL) {
- X printf("Failed to open %s\n",filename);
- X exit(0);
- X }
- X
- X bzero((char *)&session, sizeof(struct snmp_session));
- X session.peername = ms->name;
- X session.community = ms->community;
- X session.community_len = strlen(ms->community);
- X session.retries = SNMP_DEFAULT_RETRIES;
- X session.timeout = SNMP_DEFAULT_TIMEOUT;
- X session.authenticator = NULL;
- X snmp_synch_setup(&session);
- X ssp = snmp_open(&session);
- X if (ssp == NULL) {
- X printf("Couldn't open snmp to %s\n", session.peername);
- X exit(-1);
- X }
- X ms->ss = ssp;
- X
- X ms->status = MT_MANAGE;
- X first_meter = ms; /* $$$$$$$ */
- X
- X#ifdef MTR_LIST
- X if (!explicit) add_all_meters();
- X#endif
- X
- X init_meter();
- X
- X if (!interval) {
- X print_meters();
- X exit (0);
- X }
- X
- X parse_rulefile(ms,TRUE); /* Download the rules we want to use */
- X
- X for (;;) {
- X sleep(interval);
- X
- X monitor_meter();
- X if (verbose) print_meters();
- X }
- X }
- X
- X#ifdef MTR_LIST
- Xvoid parse_ctlfile()
- X{
- X struct meter_status *ms, *mp;
- X FILE *fp;
- X char linebuffer[256];
- X char label[128];
- X char community[128];
- X int n;
- X
- X if ((fp = fopen(CTLFILE, "r")) == NULL) {
- X perror(CTLFILE);
- X exit(1);
- X }
- X
- X while (fgets(linebuffer, sizeof(linebuffer), fp) != NULL) {
- X if (linebuffer[0] < '0' || linebuffer[0] > 'z') continue;
- X n = sscanf(linebuffer, "%s %s", label, community);
- X if (n < 1) continue;
- X ms = (struct meter_status *)calloc(sizeof(struct meter_status), 1);
- X ms->name = savestr(label);
- X ms->community = n > 1 ? savestr(community) : savestr("public");
- X ms->next = NULL;
- X
- X if ((mp = first_meter) == NULL) first_meter = ms;
- X else {
- X while (mp->next) mp = mp->next;
- X mp->next = ms;
- X }
- X }
- X }
- X
- Xvoid add_all_meters()
- X{
- X struct meter_status *ms;
- X for (ms = first_meter; ms != NULL; ms = ms->next)
- X ms->status = MT_MANAGE;
- X }
- X
- Xvoid add_meter(name)
- Xchar *name;
- X{
- X struct meter_status *ms;
- X
- X for (ms = first_meter; ms != NULL; ms = ms->next) {
- X if (strcasecmp(name,ms->name) == 0) break;
- X }
- X
- X if (ms == NULL) {
- X struct hostent *hp;
- X u_long addr;
- X
- X if ((addr = (u_long)inet_addr(name)) == (u_long)-1) {
- X hp = gethostbyname(name);
- X if (hp != NULL) {
- X for (ms = first_meter; ms != NULL; ms = ms->next) {
- X#ifdef h_addr
- X char **ap;
- X#endif
- X if (strcasecmp(hp->h_name, ms->name) == 0) break;
- X#ifdef h_addr
- X if (hp->h_addr_list == NULL) continue;
- X
- X for (ap = hp->h_addr_list; *ap; ap++) {
- X if (addr == *(u_long *)(*ap)) break;
- X }
- X if (*ap) break;
- X#else
- X if (addr == *(u_long *)(hp->h_addr)) break;
- X#endif
- X
- X }
- X if (ms == NULL) {
- X printf("No config info for %s\n", name);
- X return;
- X }
- X }
- X else {
- X printf("No config info for %s\n", name);
- X return;
- X }
- X }
- X }
- X
- X ms->status = MT_MANAGE;
- X }
- X#endif
- X
- Xvoid init_meter()
- X{
- X struct meter_status *ms;
- X int haveone = 0;
- X
- X for (ms = first_meter; ms; ms = ms->next) {
- X if (!(ms->status & MT_MANAGE)) continue;
- X haveone++;
- X if (meter_info(ms)) {
- X ms->status |= (MT_UP | MT_INFO);
- X meter_print(ms);
- X }
- X }
- X
- X if (!haveone) {
- X printf("No meters to monitor\n");
- X exit(5);
- X }
- X }
- X
- X
- Xvoid monitor_meter()
- X{
- X struct meter_status *ms;
- X for (ms = first_meter; ms; ms = ms->next)
- X if (ms->status & MT_MANAGE) monitor(ms);
- X }
- X
- X/* CAUTION: Following struct doesn't work because of alignment on 32-bit words
- X *
- X * struct active_flow_data {
- X * unsigned short flow_nbr;
- X * unsigned long fwd_bytes, back_bytes;
- X * };
- X */
- X
- X#define flow_nbr_x 0
- X#define fwd_bytes_x (flow_nbr_x + sizeof(unsigned short))
- X#define back_bytes_x (fwd_bytes_x + sizeof(unsigned long))
- X#define flow_data_sz (back_bytes_x + sizeof(unsigned long))
- X
- X#define FLOWBLOBSZ 25
- X
- Xunsigned short getshort(ucp)
- Xunsigned char *ucp;
- X{
- X return ucp[0]<<8 | ucp[1];
- X }
- X
- Xunsigned long getlong(ucp)
- Xunsigned char *ucp;
- X{
- X return ucp[0]<<24 | ucp[1]<<16 | ucp[2]<<8 | ucp[3];
- X }
- X
- Xvoid monitor(ms) /* Called every interval for each meter */
- Xstruct meter_status *ms;
- X{
- X time_t t;
- X char *ts;
- X unsigned short fn, nactive, n;
- X struct flow_info fi;
- X unsigned char flowblob[FLOWBLOBSZ*flow_data_sz], *afdp;
- X unsigned long fwd_bytes, back_bytes;
- X
- X time(&t); ts = ctime(&t);
- X if (!(ms->status & MT_INFO)) { /* No info */
- X if (meter_info(ms)) /* Got some */
- X ms->status |= (MT_UP | MT_INFO);
- X return;
- X }
- X if (meter_info(ms) == 0) { /* Lost contact */
- X if (ms->status & MT_UP) { /* Was up */
- X fprintf(ms->log,"%19.19s -- %s: No response\n", ts,ms->name);
- X if (verbose) printf("%19.19s -- %s: No response\n", ts,ms->name);
- X }
- X ms->status &= ~MT_UP; /* Mark as 'down' */
- X return;
- X }
- X if (!(ms->status & MT_UP)) { /* Have contact now, was down */
- X fprintf(ms->log,"%19.19s -- %s: Regained contact\n", ts,ms->name);
- X if (verbose) printf("%19.19s -- %s: Regained contact\n", ts,ms->name);
- X }
- X ms->status |= MT_UP;
- X
- X /* Meter processing .. */
- X
- X if (!chk_info(ms,1)) {
- X printf("%19.19s -- %s: Failed to get chk info\n", ts,ms->name);
- X return;
- X }
- X else {
- X if (verbose) printf(
- X "%19.19s -- %s: %u flows, %u active, %u first. From %ld to %ld\n",
- X ts,ms->name,
- X ms->ChkFlowCount,ms->ChkActFlows,ms->FirstActFlow,
- X ms->PrevChkTime,ms->ChkTime);
- X
- X /* Get the keys and flows here .. */
- X
- X fprintf(ms->keys,
- X "## %19.19s %s: %u flows, %u active. Checkpoint %u, from %ld to %ld##\n",
- X ts,ms->name, ms->ChkFlowCount,ms->ChkActFlows,
- X ms->CheckPoint, ms->PrevChkTime,ms->ChkTime);
- X for (fn = ms->flowsknown+1; fn <= ms->ChkFlowCount; ++fn) {
- X if (!flow_info(ms, &fi, fn, 1, 0)) {
- X printf(ms->log," Failed to get key for flow %d\n", fn);
- X printf("Failed to get key for flow %d\n", fn);
- X }
- X else {
- X fprintf(ms->keys, "%u %u", fn, fi.AddrType);
- X printaddress(ms->keys, fi.FromAddr);
- X printaddress(ms->keys, fi.ToAddr);
- X fprintf(ms->keys,"\n");
- X }
- X }
- X ms->flowsknown = ms->ChkFlowCount;
- X fflush(ms->keys);
- X
- X fprintf(ms->flows,
- X "## %19.19s %s: %u flows, %u active. Checkpoint %u, from %ld to %ld##\n",
- X ts,ms->name, ms->ChkFlowCount,ms->ChkActFlows,
- X ms->CheckPoint, ms->PrevChkTime,ms->ChkTime);
- X fn = ms->FirstActFlow; nactive = ms->ChkActFlows;
- X while (nactive != 0) {
- X if (!blob_info(ms,flowblob, fn)) {
- X printf(ms->log," Failed to get flow for flow %d\n", fn);
- X printf("Failed to get flow for flow %d\n", fn);
- X }
- X else {
- X for (n = 0, afdp = flowblob; nactive != 0 && n != FLOWBLOBSZ;
- X --nactive, ++n, afdp += flow_data_sz) {
- X fprintf(ms->flows,"%u %lu %lu\n",
- X fn = ntohs(getshort(afdp + flow_nbr_x)),
- X ntohl(getlong(afdp + fwd_bytes_x)),
- X ntohl(getlong(afdp + back_bytes_x)) );
- X }
- X }
- X ++fn;
- X }
- X fflush(ms->flows);
- X
- X if (ms->flowsknown > FLOWLIMIT) chk_info(ms,-1); /* Restart meter */
- X }
- X
- X fflush(ms->log);
- X }
- X
- X#define ADD_VAR(v) snmp_add_null_var(pdu, v, sizeof(v)/sizeof(oid))
- X#define ADD_X_VAR(v,x,n) { v[x] = n; ADD_VAR(v); }
- X
- X#define STRING_VAL(v) bcopy(vars->val.string, v, vars->val_len)
- X#define INT_VAL(v) v = *(vars->val.integer)
- X
- X#define SET_INT(v) { vars->type = INTEGER;\
- X vars->val.integer = (long *)malloc(vars->val_len = sizeof(long));\
- X *(vars->val.integer) = (long)v; }
- X#define SET_STRING(v) { vars->type = STRING;\
- X vars->val.string = (u_char *)malloc(ADDR_LEN);\
- X bcopy(v, (char *)vars->val.string, vars->val_len = ADDR_LEN); }
- X
- Xint add_rule(ms,ri)
- Xstruct meter_status *ms;
- Xstruct rule_info *ri;
- X{
- X int i, count, status;
- X struct snmp_pdu *pdu, *response;
- X struct variable_list *vars;
- X
- X pdu = snmp_pdu_create(SET_REQ_MSG);
- X if (ri->RuleNbr == 0) {
- X ADD_VAR(o_crRuleCount); /* Clear rule table */
- X vars = pdu->variables;
- X SET_INT(ri->RuleNbr);
- X }
- X else {
- X ADD_VAR(o_crTreeNbr);
- X vars = pdu->variables;
- X SET_INT(ri->TreeNbr);
- X ADD_VAR(o_crAddrType);
- X vars = vars->next_variable;
- X SET_INT(ri->AddrType);
- X ADD_VAR(o_crFromAddr);
- X vars = vars->next_variable;
- X SET_STRING(ri->FromAddr);
- X ADD_VAR(o_crFromMask);
- X vars = vars->next_variable;
- X SET_STRING(ri->FromMask);
- X ADD_VAR(o_crFromTally);
- X vars = vars->next_variable;
- X SET_STRING(ri->FromTally);
- X ADD_VAR(o_crToAddr);
- X vars = vars->next_variable;
- X SET_STRING(ri->ToAddr);
- X ADD_VAR(o_crToMask);
- X vars = vars->next_variable;
- X SET_STRING(ri->ToMask);
- X ADD_VAR(o_crToTally);
- X vars = vars->next_variable;
- X SET_STRING(ri->ToTally);
- X ADD_VAR(o_crRuleCount); /* Add current rule to rule table */
- X vars = vars->next_variable;
- X SET_INT(ri->RuleNbr);
- X }
- X
- X status = snmp_synch_response(ms->ss, pdu, &response);
- X if (status == STAT_SUCCESS) {
- X if (response->errstat == SNMP_ERR_NOERROR) {
- X if (ri->RuleNbr == 0) printf("Rule table cleared\n");
- X else printf("Rule %d added to table\n", ri->RuleNbr);
- X ms->rulecount = ri->RuleNbr;
- X }
- X else {
- X printf("Error in packet\nReason: %sn",
- X snmp_errstring(response->errstat));
- X if (response->errstat == SNMP_ERR_NOSUCHNAME) {
- X printf("This name does not exist: ");
- X for (count=1, vars = response->variables;
- X vars && count != response->errindex;
- X vars = vars->next_variable, count++) ;
- X if (vars) print_objid(vars->name, vars->name_length);
- X printf("\n");
- X }
- X }
- X }
- X else return 0;
- X snmp_free_pdu(response);
- X return 1;
- X }
- X
- Xint chk_info(ms,control)
- Xstruct meter_status *ms;
- Xint control; /* 0 = read, -1 = restart, 1 = checkpoint */
- X{
- X int i, count, status;
- X struct snmp_pdu *pdu, *response;
- X struct variable_list *vars;
- X
- X if (control == -1) {
- X ms->CheckPoint = ms->flowsknown = 0;
- X }
- X else if (control == 1) ++ms->CheckPoint;
- X
- X if (control != 0) { /* Make new checkpoint */
- X pdu = snmp_pdu_create(SET_REQ_MSG);
- X ADD_VAR(o_ftCheckPoint);
- X vars = pdu->variables;
- X SET_INT(ms->CheckPoint); /* New checkpoint number */
- X status = snmp_synch_response(ms->ss, pdu, &response);
- X if (status == STAT_SUCCESS) {
- X if (response->errstat == SNMP_ERR_NOERROR) {
- X vars = response->variables;
- X INT_VAL(ms->CheckPoint);
- X }
- X else {
- X printf("Error in packet\nReason: %sn",
- X snmp_errstring(response->errstat));
- X if (response->errstat == SNMP_ERR_NOSUCHNAME) {
- X printf("This name does not exist: ");
- X for (count=1, vars = response->variables;
- X vars && count != response->errindex;
- X vars = vars->next_variable, count++) ;
- X if (vars) print_objid(vars->name, vars->name_length);
- X printf("\n");
- X }
- X }
- X }
- X else return 0;
- X snmp_free_pdu(response);
- X }
- X
- X pdu = snmp_pdu_create(GET_REQ_MSG);
- X ADD_VAR(o_ftChkFlowCount);
- X ADD_VAR(o_ftChkActFlows);
- X ADD_VAR(o_ftFirstActFlow);
- X ADD_VAR(o_ftChkTime);
- X ADD_VAR(o_ftPrevChkTime);
- X status = snmp_synch_response(ms->ss, pdu, &response);
- X if (status == STAT_SUCCESS) {
- X if (response->errstat == SNMP_ERR_NOERROR) {
- X vars = response->variables;
- X INT_VAL(ms->ChkFlowCount);
- X vars = vars->next_variable;
- X INT_VAL(ms->ChkActFlows);
- X vars = vars->next_variable;
- X INT_VAL(ms->FirstActFlow);
- X vars = vars->next_variable;
- X INT_VAL(ms->ChkTime);
- X vars = vars->next_variable;
- X INT_VAL(ms->PrevChkTime);
- X }
- X else {
- X printf("Error in packet\nReason: %sn",
- X snmp_errstring(response->errstat));
- X if (response->errstat == SNMP_ERR_NOSUCHNAME) {
- X printf("This name does not exist: ");
- X for (count=1, vars = response->variables;
- X vars && count != response->errindex;
- X vars = vars->next_variable, count++) ;
- X if (vars) print_objid(vars->name, vars->name_length);
- X printf("\n");
- X }
- X }
- X }
- X else return 0;
- X snmp_free_pdu(response);
- X return 1;
- X }
- X
- Xint blob_info(ms,fb, fn)
- Xstruct meter_status *ms;
- Xunsigned char *fb;
- Xint fn;
- X{
- X int i, count, status;
- X struct snmp_pdu *pdu, *response;
- X struct variable_list *vars;
- X
- X pdu = snmp_pdu_create(GET_REQ_MSG);
- X ADD_X_VAR(o_ftFlowBlob,FT_INDEX,fn);
- X status = snmp_synch_response(ms->ss, pdu, &response);
- X if (status == STAT_SUCCESS) {
- X if (response->errstat == SNMP_ERR_NOERROR) {
- X vars = response->variables;
- X STRING_VAL(fb);
- X }
- X else {
- X printf("Error in packet\nReason: %sn",
- X snmp_errstring(response->errstat));
- X if (response->errstat == SNMP_ERR_NOSUCHNAME) {
- X printf("This name does not exist: ");
- X for (count=1, vars = response->variables;
- X vars && count != response->errindex;
- X vars = vars->next_variable, count++) ;
- X if (vars) print_objid(vars->name, vars->name_length);
- X printf("\n");
- X }
- X }
- X }
- X else return 0;
- X snmp_free_pdu(response);
- X return 1;
- X }
- X
- Xint flow_info(ms,fi, fn, getkey,getflow)
- Xstruct meter_status *ms;
- Xstruct flow_info *fi;
- Xint fn, getkey,getflow;
- X{
- X int i, count, status;
- X struct snmp_pdu *pdu, *response;
- X struct variable_list *vars;
- X
- X pdu = snmp_pdu_create(GET_REQ_MSG);
- X if (getkey) {
- X ADD_X_VAR(o_ftAddrType,FT_INDEX,fn);
- X ADD_X_VAR(o_ftFromAddr,FT_INDEX,fn);
- X ADD_X_VAR(o_ftToAddr,FT_INDEX,fn);
- X }
- X if (getflow) {
- X ADD_X_VAR(o_ftChkFwdBytes,FT_INDEX,fn);
- X ADD_X_VAR(o_ftChkBackBytes,FT_INDEX,fn);
- X ADD_X_VAR(o_ftNextActiveFlow,FT_INDEX,fn);
- X }
- X status = snmp_synch_response(ms->ss, pdu, &response);
- X if (status == STAT_SUCCESS) {
- X if (response->errstat == SNMP_ERR_NOERROR) {
- X vars = response->variables;
- X if (getkey) {
- X INT_VAL(fi->AddrType);
- X vars = vars->next_variable;
- X STRING_VAL(fi->FromAddr);
- X vars = vars->next_variable;
- X STRING_VAL(fi->ToAddr);
- X vars = vars->next_variable;
- X }
- X if (getflow) {
- X INT_VAL(fi->FwdBytes);
- X vars = vars->next_variable;
- X INT_VAL(fi->BackBytes);
- X vars = vars->next_variable;
- X INT_VAL(fi->NextActiveFlow);
- X }
- X }
- X else {
- X printf("Error in packet\nReason: %sn",
- X snmp_errstring(response->errstat));
- X if (response->errstat == SNMP_ERR_NOSUCHNAME) {
- X printf("This name does not exist: ");
- X for (count=1, vars = response->variables;
- X vars && count != response->errindex;
- X vars = vars->next_variable, count++) ;
- X if (vars) print_objid(vars->name, vars->name_length);
- X printf("\n");
- X }
- X }
- X }
- X else return 0;
- X snmp_free_pdu(response);
- X return 1;
- X }
- X
- Xint meter_info(ms)
- Xstruct meter_status *ms;
- X{
- X int i, count, status;
- X struct snmp_pdu *pdu, *response;
- X struct variable_list *vars;
- X
- X pdu = snmp_pdu_create(GET_REQ_MSG);
- X ADD_VAR(o_sysDescr);
- X ADD_VAR(o_sysUpTime);
- X ADD_VAR(o_ifNumber);
- X ADD_VAR(o_ftFlowCount);
- X status = snmp_synch_response(ms->ss, pdu, &response);
- X if (status == STAT_SUCCESS) {
- X if (response->errstat == SNMP_ERR_NOERROR) {
- X vars = response->variables;
- X STRING_VAL(ms->descr);
- X vars = vars->next_variable;
- X INT_VAL(ms->uptime);
- X vars = vars->next_variable;
- X INT_VAL(ms->ifcount);
- X vars = vars->next_variable;
- X INT_VAL(ms->flowcount);
- X }
- X else {
- X printf("Error in packet\nReason: %sn",
- X snmp_errstring(response->errstat));
- X if (response->errstat == SNMP_ERR_NOSUCHNAME) {
- X printf("This name does not exist: ");
- X for (count=1, vars = response->variables;
- X vars && count != response->errindex;
- X vars = vars->next_variable, count++) ;
- X if (vars) print_objid(vars->name, vars->name_length);
- X printf("\n");
- X }
- X }
- X }
- X else return 0;
- X snmp_free_pdu(response);
- X return 1;
- X }
- X
- Xvoid print_meters()
- X{
- X struct meter_status *ms;
- X for (ms = first_meter; ms; ms = ms->next)
- X if (ms->status & MT_MANAGE) meter_print(ms);
- X }
- X
- Xvoid meter_print(ms)
- Xstruct meter_status *ms;
- X{
- X struct timeval tv;
- X char buf[32];
- X time_t t; char *ts;
- X
- X time(&t); ts = ctime(&t);
- X
- X gettimeofday(&tv, (struct timezone *)0);
- X tv.tv_sec -= ms->uptime / 100;
- X if ((ms->uptime % 100)*10000 > tv.tv_usec) {
- X tv.tv_sec--;
- X tv.tv_usec += 1000000;
- X }
- X tv.tv_usec -= (ms->uptime % 100)*10000;
- X
- X fprintf(ms->log,
- X "%19.19s -- %s: %s\n\tUp %s (since %.24s)\n\t\t%d interfaces, %u flows\n\n",
- X ts,ms->name, ms->descr, uptime_string(ms->uptime, buf),
- X ctime(&tv.tv_sec), ms->ifcount, ms->flowcount);
- X if (verbose) printf(
- X "%19.19s -- %s: %s\n\tUp %s (since %.24s)\n\t\t%d interfaces, %u flows\n\n",
- X ts,ms->name, ms->descr, uptime_string(ms->uptime, buf),
- X ctime(&tv.tv_sec), ms->ifcount, ms->flowcount);
- X }
- X
- X
- Xchar *uptime_string(timeticks, buf)
- Xunsigned long timeticks;
- Xchar *buf;
- X{
- X int seconds, minutes, hours, days;
- X
- X timeticks /= 100;
- X days = timeticks / (60 * 60 * 24);
- X timeticks %= (60 * 60 * 24);
- X
- X hours = timeticks / (60 * 60);
- X timeticks %= (60 * 60);
- X
- X minutes = timeticks / 60;
- X seconds = timeticks % 60;
- X
- X if (days == 0){
- X sprintf(buf, "%d:%02d:%02d", hours, minutes, seconds);
- X }
- X else if (days == 1) {
- X sprintf(buf, "%d day, %d:%02d:%02d",
- X days, hours, minutes, seconds);
- X }
- X else {
- X sprintf(buf, "%d days, %d:%02d:%02d",
- X days, hours, minutes, seconds);
- X }
- X return buf;
- X }
- X
- Xvoid printaddress(f,a)
- XFILE *f;
- Xunsigned char *a;
- X{
- X int j;
- X fprintf(f," %u", a[0]);
- X for (j = 1; j != ADDR_LEN; ++j) fprintf(f,".%u", a[j]);
- X }
- X
- X
- XFILE *rfp; /* For rules file */
- Xchar inbuf[256], *ibp;
- Xint lic, ic, iblisted, rule_line;
- X
- Xint nextchar()
- X{
- X lic = ic;
- X for (;;) {
- X if (lic == '\n') {
- X if (fgets(inbuf, sizeof(inbuf), rfp) == NULL) return ic = EOF;
- X iblisted = 0; ++rule_line;
- X ibp = inbuf;
- X }
- X ic = *ibp++;
- X if (ic == '#') lic = '\n'; /* Ignore comments */
- X else return ic;
- X }
- X }
- X
- Xint getnbr()
- X{
- X int v = 0;
- X for (;;) {
- X if (ic == EOF) return EOF;
- X if (isdigit(ic)) break;
- X else nextchar(rfp);
- X }
- X for (;;) {
- X v = v*10 + ic-'0';
- X if (nextchar(ic) == EOF) return EOF;
- X if (!isdigit(ic)) break;
- X }
- X if (v > 255) {
- X if (!iblisted) {
- X printf("RULEFILE line %d: %s\n", rule_line,inbuf);
- X iblisted = 1;
- X }
- X printf("Number > 255 !!!\n");
- X }
- X return v;
- X }
- X
- Xvoid getaddress(a)
- Xunsigned char *a;
- X{
- X int j;
- X for (j = 0; j != ADDR_LEN; ++j) a[j] = getnbr();
- X }
- X
- Xvoid parse_rulefile(ms,list)
- Xstruct meter_status *ms;
- Xint list;
- X{
- X struct rule_info ri;
- X int c, rule_nbr = 0;
- X
- X if ((rfp = fopen(ms->rulefile, "r")) == NULL) {
- X perror(ms->rulefile);
- X exit(1);
- X }
- X
- X ri.RuleNbr = 0; add_rule(ms, &ri); /* Clear rule table */
- X
- X ic = '\n'; rule_line = 0;
- X for (;;) {
- X do { /* First char of a line */
- X nextchar(rfp);
- X if (ic == EOF) break;
- X } while (lic != '\n');
- X if (ic == EOF) break;
- X ri.TreeNbr = getnbr();
- X if (ic == EOF) break;
- X for (;;) {
- X if (ic == EOF) break;
- X if (isalpha(ic)) break;
- X else nextchar(rfp);
- X }
- X c = toupper(ic);
- X if (c == 'I') ri.AddrType = AT_IP;
- X else if (c == 'N') ri.AddrType = AT_NOVELL;
- X else if (c == 'D') ri.AddrType = AT_DECNET;
- X else if (c == 'A') ri.AddrType = AT_ETHERTALK;
- X else ri.AddrType = AT_IGNORE;
- X
- X getaddress(ri.FromAddr);
- X if (ic == EOF) break;
- X getaddress(ri.FromMask);
- X if (ic == EOF) break;
- X getaddress(ri.FromTally);
- X if (ic == EOF) break;
- X getaddress(ri.ToAddr);
- X if (ic == EOF) break;
- X getaddress(ri.ToMask);
- X if (ic == EOF) break;
- X getaddress(ri.ToTally);
- X if (ic == EOF) break;
- X
- X ri.RuleNbr = ++rule_nbr;
- X
- X if (list) {
- X printf("Rule %d: %d, %d,", ri.RuleNbr, ri.TreeNbr, ri.AddrType);
- X printaddress(stdout, ri.FromAddr);
- X printaddress(stdout, ri.FromMask);
- X printaddress(stdout, ri.FromTally);
- X printf("\n ");
- X printaddress(stdout, ri.ToAddr);
- X printaddress(stdout, ri.ToMask);
- X printaddress(stdout, ri.ToTally);
- X printf("\n");
- X }
- X
- X add_rule(ms,&ri); /* Add rule to meter's rule table */
- X }
- X chk_info(ms,-1); /* Restart with new rule table */
- X fclose(rfp);
- X }
- END_OF_FILE
- if test 29675 -ne `wc -c <'netramet/src/manager/oldnm.c'`; then
- echo shar: \"'netramet/src/manager/oldnm.c'\" unpacked with wrong size!
- fi
- # end of 'netramet/src/manager/oldnm.c'
- fi
- if test -f 'netramet/src/snmplib/snmpapi.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'netramet/src/snmplib/snmpapi.c'\"
- else
- echo shar: Extracting \"'netramet/src/snmplib/snmpapi.c'\" \(28823 characters\)
- sed "s/^X//" >'netramet/src/snmplib/snmpapi.c' <<'END_OF_FILE'
- X/***********************************************************
- X Copyright 1989 by Carnegie Mellon University
- X
- X All Rights Reserved
- X
- XPermission to use, copy, modify, and distribute this software and its
- Xdocumentation for any purpose and without fee is hereby granted,
- Xprovided that the above copyright notice appear in all copies and that
- Xboth that copyright notice and this permission notice appear in
- Xsupporting documentation, and that the name of CMU not be
- Xused in advertising or publicity pertaining to distribution of the
- Xsoftware without specific, written prior permission.
- X
- XCMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
- XALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
- XCMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
- XANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- XWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
- XARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- XSOFTWARE.
- X******************************************************************/
- X/*
- X * snmp_api.c - API for access to snmp.
- X */
- X
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <sys/param.h>
- X#include <sys/time.h>
- X#include <netinet/in.h>
- X#include <sys/socket.h>
- X#include <netdb.h>
- X#include "ausnmp.h"
- X#include "asn1.h"
- X#include "snmp.h"
- X#include "snmpimpl.h"
- X#include "snmpapi.h"
- X
- X#define PACKET_LENGTH 4500
- X
- X#ifndef BSD4_3
- X#define BSD4_2
- X#endif
- X
- X#ifndef BSD4_3
- X
- Xtypedef long fd_mask;
- X#define NFDBITS (sizeof(fd_mask) * NBBY) /* bits per mask */
- X
- X#define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
- X#define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
- X#define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
- X#define FD_ZERO(p) bzero((char *)(p), sizeof(*(p)))
- X#endif
- X
- Xoid default_enterprise[] = {1, 3, 6, 1, 4, 1, 3, 1, 1}; /* enterprises.cmu.systems.cmuSNMP */
- X
- X#define DEFAULT_COMMUNITY "public"
- X#define DEFAULT_RETRIES 4
- X#define DEFAULT_TIMEOUT 1000000L
- X#define DEFAULT_REMPORT SNMP_PORT
- X#define DEFAULT_ENTERPRISE default_enterprise
- X#define DEFAULT_TIME 0
- X
- X/*
- X * Internal information about the state of the snmp session.
- X */
- Xstruct snmp_internal_session {
- X int sd; /* socket descriptor for this connection */
- X ipaddr addr; /* address of connected peer */
- X struct request_list *requests;/* Info about outstanding requests */
- X};
- X
- X/*
- X * A list of all the outstanding requests for a particular session.
- X */
- Xstruct request_list {
- X struct request_list *next_request;
- X u_long request_id; /* request id */
- X int retries; /* Number of retries */
- X u_long timeout; /* length to wait for timeout */
- X struct timeval time; /* Time this request was made */
- X struct timeval expire; /* time this request is due to expire */
- X struct snmp_pdu *pdu; /* The pdu for this request (saved so it can be retransmitted */
- X};
- X
- X/*
- X * The list of active/open sessions.
- X */
- Xstruct session_list {
- X struct session_list *next;
- X struct snmp_session *session;
- X struct snmp_internal_session *internal;
- X};
- X
- Xstruct session_list *Sessions = NULL;
- X
- Xu_long Reqid = 0;
- Xint snmp_errno = 0;
- X
- Xchar *api_errors[4] = {
- X "Unknown session",
- X "Unknown host",
- X "Invalid local port",
- X "Unknown Error"
- X};
- X
- Xstatic char *
- Xapi_errstring(snmp_errnumber)
- X int snmp_errnumber;
- X{
- X if (snmp_errnumber <= SNMPERR_BAD_SESSION && snmp_errnumber >= SNMPERR_GENERR){
- X return api_errors[snmp_errnumber + 4];
- X } else {
- X return "Unknown Error";
- X }
- X}
- X
- X
- X/*
- X * Gets initial request ID for all transactions.
- X */
- Xstatic
- Xinit_snmp(){
- X struct timeval tv;
- X
- X gettimeofday(&tv, (struct timezone *)0);
- X srandom(tv.tv_sec ^ tv.tv_usec);
- X Reqid = random();
- X}
- X
- X/*
- X * Sets up the session with the snmp_session information provided
- X * by the user. Then opens and binds the necessary UDP port.
- X * A handle to the created session is returned (this is different than
- X * the pointer passed to snmp_open()). On any error, NULL is returned
- X * and snmp_errno is set to the appropriate error code.
- X */
- Xstruct snmp_session *
- Xsnmp_open(session)
- X struct snmp_session *session;
- X{
- X struct session_list *slp;
- X struct snmp_internal_session *isp;
- X u_char *cp;
- X int sd;
- X u_long addr;
- X struct sockaddr_in me;
- X struct hostent *hp;
- X struct servent *servp;
- X
- X
- X if (Reqid == 0)
- X init_snmp();
- X
- X /* Copy session structure and link into list */
- X slp = (struct session_list *)malloc(sizeof(struct session_list));
- X slp->internal = isp = (struct snmp_internal_session *)malloc(sizeof(struct snmp_internal_session));
- X bzero((char *)isp, sizeof(struct snmp_internal_session));
- X slp->internal->sd = -1; /* mark it not set */
- X slp->session = (struct snmp_session *)malloc(sizeof(struct snmp_session));
- X bcopy((char *)session, (char *)slp->session, sizeof(struct snmp_session));
- X session = slp->session;
- X /* now link it in. */
- X slp->next = Sessions;
- X Sessions = slp;
- X /*
- X * session now points to the new structure that still contains pointers to
- X * data allocated elsewhere. Some of this data is copied to space malloc'd
- X * here, and the pointer replaced with the new one.
- X */
- X
- X if (session->peername != NULL){
- X cp = (u_char *)malloc((unsigned)strlen(session->peername) + 1);
- X strcpy((char *)cp, session->peername);
- X session->peername = (char *)cp;
- X }
- X
- X /* Fill in defaults if necessary */
- X if (session->community_len != SNMP_DEFAULT_COMMUNITY_LEN){
- X cp = (u_char *)malloc((unsigned)session->community_len);
- X bcopy((char *)session->community, (char *)cp, session->community_len);
- X } else {
- X session->community_len = strlen(DEFAULT_COMMUNITY);
- X cp = (u_char *)malloc((unsigned)session->community_len);
- X bcopy((char *)DEFAULT_COMMUNITY, (char *)cp, session->community_len);
- X }
- X session->community = cp; /* replace pointer with pointer to new data */
- X
- X if (session->retries == SNMP_DEFAULT_RETRIES)
- X session->retries = DEFAULT_RETRIES;
- X if (session->timeout == SNMP_DEFAULT_TIMEOUT)
- X session->timeout = DEFAULT_TIMEOUT;
- X isp->requests = NULL;
- X
- X /* Set up connections */
- X sd = socket(AF_INET, SOCK_DGRAM, 0);
- X if (sd < 0){
- X perror("socket");
- X snmp_errno = SNMPERR_GENERR;
- X if (!snmp_close(session)){
- X fprintf(stderr, "Couldn't abort session: %s. Exiting\n", api_errstring(snmp_errno));
- X exit(1);
- X }
- X return 0;
- X }
- X isp->sd = sd;
- X if (session->peername != SNMP_DEFAULT_PEERNAME){
- X if ((addr = inet_addr(session->peername)) != -1){
- X bcopy((char *)&addr, (char *)&isp->addr.sin_addr, sizeof(isp->addr.sin_addr));
- X } else {
- X hp = gethostbyname(session->peername);
- X if (hp == NULL){
- X fprintf(stderr, "unknown host: %s\n", session->peername);
- X snmp_errno = SNMPERR_BAD_ADDRESS;
- X if (!snmp_close(session)){
- X fprintf(stderr, "Couldn't abort session: %s. Exiting\n", api_errstring(snmp_errno));
- X exit(2);
- X }
- X return 0;
- X } else {
- X bcopy((char *)hp->h_addr, (char *)&isp->addr.sin_addr, hp->h_length);
- X }
- X }
- X isp->addr.sin_family = AF_INET;
- X if (session->remote_port == SNMP_DEFAULT_REMPORT){
- X servp = getservbyname("snmp", "udp");
- X if (servp != NULL){
- X isp->addr.sin_port = servp->s_port;
- X } else {
- X isp->addr.sin_port = htons(SNMP_PORT);
- X }
- X } else {
- X isp->addr.sin_port = htons(session->remote_port);
- X }
- X } else {
- X isp->addr.sin_addr.s_addr = SNMP_DEFAULT_ADDRESS;
- X }
- X
- X me.sin_family = AF_INET;
- X me.sin_addr.s_addr = INADDR_ANY;
- X me.sin_port = htons(session->local_port);
- X if (bind(sd, (struct sockaddr *)&me, sizeof(me)) != 0){
- X perror("bind");
- X snmp_errno = SNMPERR_BAD_LOCPORT;
- X if (!snmp_close(session)){
- X fprintf(stderr, "Couldn't abort session: %s. Exiting\n", api_errstring(snmp_errno));
- X exit(3);
- X }
- X return 0;
- X }
- X return session;
- X}
- X
- X
- X/*
- X * Free each element in the input request list.
- X */
- Xstatic
- Xfree_request_list(rp)
- X struct request_list *rp;
- X{
- X struct request_list *orp;
- X
- X while(rp){
- X orp = rp;
- X rp = rp->next_request;
- X if (orp->pdu != NULL)
- X snmp_free_pdu(orp->pdu);
- X free((char *)orp);
- X }
- X}
- X
- X/*
- X * Close the input session. Frees all data allocated for the session,
- X * dequeues any pending requests, and closes any sockets allocated for
- X * the session. Returns 0 on error, 1 otherwise.
- X */
- Xint
- Xsnmp_close(session)
- X struct snmp_session *session;
- X{
- X struct session_list *slp = NULL, *oslp = NULL;
- X
- X if (Sessions->session == session){ /* If first entry */
- X slp = Sessions;
- X Sessions = slp->next;
- X } else {
- X for(slp = Sessions; slp; slp = slp->next){
- X if (slp->session == session){
- X if (oslp) /* if we found entry that points here */
- X oslp->next = slp->next; /* link around this entry */
- X break;
- X }
- X oslp = slp;
- X }
- X }
- X /* If we found the session, free all data associated with it */
- X if (slp){
- X if (slp->session->community != NULL)
- X free((char *)slp->session->community);
- X if(slp->session->peername != NULL)
- X free((char *)slp->session->peername);
- X free((char *)slp->session);
- X if (slp->internal->sd != -1)
- X close(slp->internal->sd);
- X free_request_list(slp->internal->requests);
- X free((char *)slp->internal);
- X free((char *)slp);
- X } else {
- X snmp_errno = SNMPERR_BAD_SESSION;
- X return 0;
- X }
- X return 1;
- X}
- X
- X/*
- X * Takes a session and a pdu and serializes the ASN PDU into the area
- X * pointed to by packet. out_length is the size of the data area available.
- X * Returns the length of the completed packet in out_length. If any errors
- X * occur, -1 is returned. If all goes well, 0 is returned.
- X */
- Xstatic int
- Xsnmp_build(session, pdu, packet, out_length)
- X struct snmp_session *session;
- X struct snmp_pdu *pdu;
- X register u_char *packet;
- X int *out_length;
- X{
- X u_char buf[PACKET_LENGTH];
- X register u_char *cp;
- X struct variable_list *vp;
- X int length;
- X long zero = 0;
- X int totallength;
- X
- X length = *out_length;
- X cp = packet;
- X for(vp = pdu->variables; vp; vp = vp->next_variable){
- X cp = snmp_build_var_op(cp, vp->name, &vp->name_length, vp->type, vp->val_len, (u_char *)vp->val.string, &length);
- X if (cp == NULL)
- X return -1;
- X }
- X totallength = cp - packet;
- X
- X length = PACKET_LENGTH;
- X cp = asn_build_header(buf, &length, (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR), totallength);
- X if (cp == NULL)
- X return -1;
- X bcopy((char *)packet, (char *)cp, totallength);
- X totallength += cp - buf;
- X
- X length = *out_length;
- X if (pdu->command != TRP_REQ_MSG){
- X /* request id */
- X cp = asn_build_int(packet, &length,
- X (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
- X (long *)&pdu->reqid, sizeof(pdu->reqid));
- X if (cp == NULL)
- X return -1;
- X /* error status */
- X cp = asn_build_int(cp, &length,
- X (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
- X (long *)&pdu->errstat, sizeof(pdu->errstat));
- X if (cp == NULL)
- X return -1;
- X /* error index */
- X cp = asn_build_int(cp, &length,
- X (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
- X (long *)&pdu->errindex, sizeof(pdu->errindex));
- X if (cp == NULL)
- X return -1;
- X } else { /* this is a trap message */
- X /* enterprise */
- X cp = asn_build_objid(packet, &length,
- X (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OBJECT_ID),
- X (oid *)pdu->enterprise, pdu->enterprise_length);
- X if (cp == NULL)
- X return -1;
- X /* agent-addr */
- X cp = asn_build_string(cp, &length,
- X (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OCTET_STR),
- X (u_char *)&pdu->agent_addr.sin_addr.s_addr, sizeof(pdu->agent_addr.sin_addr.s_addr));
- X if (cp == NULL)
- X return -1;
- X /* generic trap */
- X cp = asn_build_int(cp, &length,
- X (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
- X (long *)&pdu->trap_type, sizeof(pdu->trap_type));
- X if (cp == NULL)
- X return -1;
- X /* specific trap */
- X cp = asn_build_int(cp, &length,
- X (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
- X (long *)&pdu->specific_type, sizeof(pdu->specific_type));
- X if (cp == NULL)
- X return -1;
- X /* timestamp */
- X cp = asn_build_int(cp, &length,
- X (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
- X (long *)&pdu->time, sizeof(pdu->time));
- X if (cp == NULL)
- X return -1;
- X }
- X if (length < totallength)
- X return -1;
- X bcopy((char *)buf, (char *)cp, totallength);
- X totallength += cp - packet;
- X
- X length = PACKET_LENGTH;
- X cp = asn_build_header(buf, &length, (u_char)pdu->command, totallength);
- X if (cp == NULL)
- X return -1;
- X if (length < totallength)
- X return -1;
- X bcopy((char *)packet, (char *)cp, totallength);
- X totallength += cp - buf;
- X
- X length = *out_length;
- X cp = snmp_auth_build(packet, &length, session->community, &session->community_len, &zero, totallength);
- X if (cp == NULL)
- X return -1;
- X if ((*out_length - (cp - packet)) < totallength)
- X return -1;
- X bcopy((char *)buf, (char *)cp, totallength);
- X totallength += cp - packet;
- X *out_length = totallength;
- X return 0;
- X}
- X
- X/*
- X * Parses the packet recieved on the input session, and places the data into
- X * the input pdu. length is the length of the input packet. If any errors
- X * are encountered, -1 is returned. Otherwise, a 0 is returned.
- X */
- Xstatic int
- Xsnmp_parse(session, pdu, data, length)
- X struct snmp_session *session;
- X struct snmp_pdu *pdu;
- X u_char *data;
- X int length;
- X{
- X u_char msg_type;
- X u_char type;
- X u_char *var_val;
- X long version;
- X int len, four;
- X u_char community[128];
- X int community_length = 128;
- X struct variable_list *vp;
- X oid objid[MAX_NAME_LEN], *op;
- X
- X /* authenticates message and returns length if valid */
- X data = snmp_auth_parse(data, &length, community, &community_length, &version);
- X if (data == NULL)
- X return -1;
- X if (version != SNMP_VERSION_1){
- X fprintf(stderr, "Wrong version: %d\n", version);
- X fprintf(stderr, "Continuing anyway\n");
- X }
- X if (session->authenticator){
- X data = session->authenticator(data, &length, community, community_length);
- X if (data == NULL)
- X return 0;
- X }
- X data = asn_parse_header(data, &length, &msg_type);
- X if (data == NULL)
- X return -1;
- X pdu->command = msg_type;
- X if (pdu->command != TRP_REQ_MSG){
- X data = asn_parse_int(data, &length, &type, (long *)&pdu->reqid, sizeof(pdu->reqid));
- X if (data == NULL)
- X return -1;
- X data = asn_parse_int(data, &length, &type, (long *)&pdu->errstat, sizeof(pdu->errstat));
- X if (data == NULL)
- X return -1;
- X data = asn_parse_int(data, &length, &type, (long *)&pdu->errindex, sizeof(pdu->errindex));
- X if (data == NULL)
- X return -1;
- X } else {
- X pdu->enterprise_length = MAX_NAME_LEN;
- X data = asn_parse_objid(data, &length, &type, objid, &pdu->enterprise_length);
- X if (data == NULL)
- X return -1;
- X pdu->enterprise = (oid *)malloc(pdu->enterprise_length * sizeof(oid));
- X bcopy((char *)objid, (char *)pdu->enterprise, pdu->enterprise_length * sizeof(oid));
- X
- X four = 4;
- X data = asn_parse_string(data, &length, &type, (u_char *)&pdu->agent_addr.sin_addr.s_addr, &four);
- X if (data == NULL)
- X return -1;
- X data = asn_parse_int(data, &length, &type, (long *)&pdu->trap_type, sizeof(pdu->trap_type));
- X if (data == NULL)
- X return -1;
- X data = asn_parse_int(data, &length, &type, (long *)&pdu->specific_type, sizeof(pdu->specific_type));
- X if (data == NULL)
- X return -1;
- X data = asn_parse_int(data, &length, &type, (long *)&pdu->time, sizeof(pdu->time));
- X if (data == NULL)
- X return -1;
- X }
- X data = asn_parse_header(data, &length, &type);
- X if (data == NULL)
- X return -1;
- X if (type != (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR))
- X return -1;
- X while((int)length > 0){
- X if (pdu->variables == NULL){
- X pdu->variables = vp = (struct variable_list *)malloc(sizeof(struct variable_list));
- X } else {
- X vp->next_variable = (struct variable_list *)malloc(sizeof(struct variable_list));
- X vp = vp->next_variable;
- X }
- X vp->next_variable = NULL;
- X vp->val.string = NULL;
- X vp->name = NULL;
- X vp->name_length = MAX_NAME_LEN;
- X data = snmp_parse_var_op(data, objid, &vp->name_length, &vp->type, &vp->val_len, &var_val, (int *)&length);
- X if (data == NULL)
- X return -1;
- X op = (oid *)malloc((unsigned)vp->name_length * sizeof(oid));
- X bcopy((char *)objid, (char *)op, vp->name_length * sizeof(oid));
- X vp->name = op;
- X
- X len = PACKET_LENGTH;
- X switch((short)vp->type){
- X case ASN_INTEGER:
- X case COUNTER:
- X case GAUGE:
- X case TIMETICKS:
- X vp->val.integer = (long *)malloc(sizeof(long));
- X vp->val_len = sizeof(long);
- X asn_parse_int(var_val, &len, &vp->type, (long *)vp->val.integer, sizeof(vp->val.integer));
- X break;
- X case ASN_OCTET_STR:
- X case IPADDRESS:
- X case OPAQUE:
- X vp->val.string = (u_char *)malloc((unsigned)vp->val_len);
- X asn_parse_string(var_val, &len, &vp->type, vp->val.string, &vp->val_len);
- X break;
- X case ASN_OBJECT_ID:
- X vp->val_len = MAX_NAME_LEN;
- X asn_parse_objid(var_val, &len, &vp->type, objid, &vp->val_len);
- X vp->val_len *= sizeof(oid);
- X vp->val.objid = (oid *)malloc((unsigned)vp->val_len);
- X bcopy((char *)objid, (char *)vp->val.objid, vp->val_len);
- X break;
- X case ASN_NULL:
- X break;
- X default:
- X fprintf(stderr, "bad type returned (%x)\n", vp->type);
- X break;
- X }
- X }
- X return 0;
- X}
- X
- X/*
- X * Sends the input pdu on the session after calling snmp_build to create
- X * a serialized packet. If necessary, set some of the pdu data from the
- X * session defaults. Add a request corresponding to this pdu to the list
- X * of outstanding requests on this session, then send the pdu.
- X * Returns the request id of the generated packet if applicable, otherwise 1.
- X * On any error, 0 is returned.
- X * The pdu is freed by snmp_send() unless a failure occured.
- X */
- Xint
- Xsnmp_send(session, pdu)
- X struct snmp_session *session;
- X struct snmp_pdu *pdu;
- X{
- X struct session_list *slp;
- X struct snmp_internal_session *isp = NULL;
- X u_char packet[PACKET_LENGTH];
- X int length = PACKET_LENGTH;
- X struct request_list *rp;
- X struct timeval tv;
- X
- X for(slp = Sessions; slp; slp = slp->next){
- X if (slp->session == session){
- X isp = slp->internal;
- X break;
- X }
- X }
- X if (isp == NULL){
- X snmp_errno = SNMPERR_BAD_SESSION;
- X return 0;
- X }
- X if (pdu->command == GET_REQ_MSG || pdu->command == GETNEXT_REQ_MSG
- X || pdu->command == GET_RSP_MSG || pdu->command == SET_REQ_MSG){
- X if (pdu->reqid == SNMP_DEFAULT_REQID)
- X pdu->reqid = ++Reqid;
- X if (pdu->errstat == SNMP_DEFAULT_ERRSTAT)
- X pdu->errstat = 0;
- X if (pdu->errindex == SNMP_DEFAULT_ERRINDEX)
- X pdu->errindex = 0;
- X } else {
- X /* fill in trap defaults */
- X pdu->reqid = 1; /* give a bogus non-error reqid for traps */
- X if (pdu->enterprise_length == SNMP_DEFAULT_ENTERPRISE_LENGTH){
- X pdu->enterprise = (oid *)malloc(sizeof(DEFAULT_ENTERPRISE));
- X bcopy((char *)DEFAULT_ENTERPRISE, (char *)pdu->enterprise, sizeof(DEFAULT_ENTERPRISE));
- X pdu->enterprise_length = sizeof(DEFAULT_ENTERPRISE)/sizeof(oid);
- X }
- X if (pdu->time == SNMP_DEFAULT_TIME)
- X pdu->time = DEFAULT_TIME;
- X }
- X if (pdu->address.sin_addr.s_addr == SNMP_DEFAULT_ADDRESS){
- X if (isp->addr.sin_addr.s_addr != SNMP_DEFAULT_ADDRESS){
- X bcopy((char *)&isp->addr, (char *)&pdu->address, sizeof(pdu->address));
- X } else {
- X fprintf(stderr, "No remote IP address specified\n");
- X snmp_errno = SNMPERR_BAD_ADDRESS;
- X return 0;
- X }
- X }
- X
- X
- X if (snmp_build(session, pdu, packet, &length) < 0){
- X fprintf(stderr, "Error building packet\n");
- X snmp_errno = SNMPERR_GENERR;
- X return 0;
- X }
- X if (snmp_dump_packet){
- X int count;
- X
- X for(count = 0; count < length; count++){
- X printf("%02X ", packet[count]);
- X if ((count % 16) == 15)
- X printf("\n");
- X }
- X printf("\n\n");
- X }
- X
- X gettimeofday(&tv, (struct timezone *)0);
- X if (sendto(isp->sd, (char *)packet, length, 0, (struct sockaddr *)&pdu->address, sizeof(pdu->address)) < 0){
- X perror("sendto");
- X snmp_errno = SNMPERR_GENERR;
- X return 0;
- X }
- X if (pdu->command == GET_REQ_MSG || pdu->command == GETNEXT_REQ_MSG || pdu->command == SET_REQ_MSG){
- X /* set up to expect a response */
- X rp = (struct request_list *)malloc(sizeof(struct request_list));
- X rp->next_request = isp->requests;
- X isp->requests = rp;
- X rp->pdu = pdu;
- X rp->request_id = pdu->reqid;
- X
- X rp->retries = 1;
- X rp->timeout = session->timeout;
- X rp->time = tv;
- X tv.tv_usec += rp->timeout;
- X tv.tv_sec += tv.tv_usec / 1000000L;
- X tv.tv_usec %= 1000000L;
- X rp->expire = tv;
- X }
- X return pdu->reqid;
- X}
- X
- X/*
- X * Frees the pdu and any malloc'd data associated with it.
- X */
- Xvoid
- Xsnmp_free_pdu(pdu)
- X struct snmp_pdu *pdu;
- X{
- X struct variable_list *vp, *ovp;
- X
- X vp = pdu->variables;
- X while(vp){
- X if (vp->name)
- X free((char *)vp->name);
- X if (vp->val.string)
- X free((char *)vp->val.string);
- X ovp = vp;
- X vp = vp->next_variable;
- X free((char *)ovp);
- X }
- X if (pdu->enterprise)
- X free((char *)pdu->enterprise);
- X free((char *)pdu);
- X}
- X
- X
- X/*
- X * Checks to see if any of the fd's set in the fdset belong to
- X * snmp. Each socket with it's fd set has a packet read from it
- X * and snmp_parse is called on the packet received. The resulting pdu
- X * is passed to the callback routine for that session. If the callback
- X * routine returns successfully, the pdu and it's request are deleted.
- X */
- Xvoid
- Xsnmp_read(fdset)
- X fd_set *fdset;
- X{
- X struct session_list *slp;
- X struct snmp_session *sp;
- X struct snmp_internal_session *isp;
- X u_char packet[PACKET_LENGTH];
- X struct sockaddr_in from;
- X int length, fromlength;
- X struct snmp_pdu *pdu;
- X struct request_list *rp, *orp;
- X
- X for(slp = Sessions; slp; slp = slp->next){
- X if (FD_ISSET(slp->internal->sd, fdset)){
- X sp = slp->session;
- X isp = slp->internal;
- X fromlength = sizeof from;
- X length = recvfrom(isp->sd, (char *)packet, PACKET_LENGTH, 0, (struct sockaddr *)&from, &fromlength);
- X if (length == -1)
- X perror("recvfrom");
- X if (snmp_dump_packet){
- X int count;
- X
- X printf("recieved %d bytes from %s:\n", length, inet_ntoa(from.sin_addr));
- X for(count = 0; count < length; count++){
- X printf("%02X ", packet[count]);
- X if ((count % 16) == 15)
- X printf("\n");
- X }
- X printf("\n\n");
- X }
- X
- X pdu = (struct snmp_pdu *)malloc(sizeof(struct snmp_pdu));
- X pdu->address = from;
- X pdu->reqid = 0;
- X pdu->variables = NULL;
- X pdu->enterprise = NULL;
- X pdu->enterprise_length = 0;
- X if (snmp_parse(sp, pdu, packet, length) != SNMP_ERR_NOERROR){
- X fprintf(stderr, "Mangled packet\n");
- X snmp_free_pdu(pdu);
- X return;
- X }
- X
- X if (pdu->command == GET_RSP_MSG){
- X for(rp = isp->requests; rp; rp = rp->next_request){
- X if (rp->request_id == pdu->reqid){
- X if (sp->callback(RECEIVED_MESSAGE, sp, pdu->reqid, pdu, sp->callback_magic) == 1){
- X /* successful, so delete request */
- X orp = rp;
- X if (isp->requests == orp){
- X /* first in list */
- X isp->requests = orp->next_request;
- X } else {
- X for(rp = isp->requests; rp; rp = rp->next_request){
- X if (rp->next_request == orp){
- X rp->next_request = orp->next_request; /* link around it */
- X break;
- X }
- X }
- X }
- X snmp_free_pdu(orp->pdu);
- X free((char *)orp);
- X break; /* there shouldn't be any more request with the same reqid */
- X }
- X }
- X }
- X } else if (pdu->command == GET_REQ_MSG || pdu->command == GETNEXT_REQ_MSG
- X || pdu->command == TRP_REQ_MSG || pdu->command == SET_REQ_MSG){
- X sp->callback(RECEIVED_MESSAGE, sp, pdu->reqid, pdu, sp->callback_magic);
- X }
- X snmp_free_pdu(pdu);
- X }
- X }
- X}
- X
- X/*
- X * Returns info about what snmp requires from a select statement.
- X * numfds is the number of fds in the list that are significant.
- X * All file descriptors opened for SNMP are OR'd into the fdset.
- X * If activity occurs on any of these file descriptors, snmp_read
- X * should be called with that file descriptor set
- X *
- X * The timeout is the latest time that SNMP can wait for a timeout. The
- X * select should be done with the minimum time between timeout and any other
- X * timeouts necessary. This should be checked upon each invocation of select.
- X * If a timeout is received, snmp_timeout should be called to check if the
- X * timeout was for SNMP. (snmp_timeout is idempotent)
- X *
- X * Block is 1 if the select is requested to block indefinitely, rather than time out.
- X * If block is input as 1, the timeout value will be treated as undefined, but it must
- X * be available for setting in snmp_select_info. On return, if block is true, the value
- X * of timeout will be undefined.
- X *
- X * snmp_select_info returns the number of open sockets. (i.e. The number of sessions open)
- X */
- Xint
- Xsnmp_select_info(numfds, fdset, timeout, block)
- X int *numfds;
- X fd_set *fdset;
- X struct timeval *timeout;
- X int *block; /* should the select block until input arrives (i.e. no input) */
- X{
- X struct session_list *slp;
- X struct snmp_internal_session *isp;
- X struct request_list *rp;
- X struct timeval now, earliest;
- X int active = 0, requests = 0;
- X
- X timerclear(&earliest);
- X /*
- X * For each request outstanding, add it's socket to the fdset,
- X * and if it is the earliest timeout to expire, mark it as lowest.
- X */
- X for(slp = Sessions; slp; slp = slp->next){
- X active++;
- X isp = slp->internal;
- X if ((isp->sd + 1) > *numfds)
- X *numfds = (isp->sd + 1);
- X FD_SET(isp->sd, fdset);
- X if (isp->requests){
- X /* found another session with outstanding requests */
- X requests++;
- X for(rp = isp->requests; rp; rp = rp->next_request){
- X if (!timerisset(&earliest) || timercmp(&rp->expire, &earliest, <))
- X earliest = rp->expire;
- X }
- X }
- X }
- X if (requests == 0) /* if none are active, skip arithmetic */
- X return active;
- X
- X /*
- X * Now find out how much time until the earliest timeout. This
- X * transforms earliest from an absolute time into a delta time, the
- X * time left until the select should timeout.
- X */
- X gettimeofday(&now, (struct timezone *)0);
- X earliest.tv_sec--; /* adjust time to make arithmetic easier */
- X earliest.tv_usec += 1000000L;
- X earliest.tv_sec -= now.tv_sec;
- X earliest.tv_usec -= now.tv_usec;
- X while (earliest.tv_usec >= 1000000L){
- X earliest.tv_usec -= 1000000L;
- X earliest.tv_sec += 1;
- X }
- X if (earliest.tv_sec < 0){
- X earliest.tv_sec = 0;
- X earliest.tv_usec = 0;
- X }
- X
- X /* if it was blocking before or our delta time is less, reset timeout */
- X if (*block == 1 || timercmp(&earliest, timeout, <)){
- X *timeout = earliest;
- X *block = 0;
- X }
- X return active;
- X}
- X
- X/*
- X * snmp_timeout should be called whenever the timeout from snmp_select_info expires,
- X * but it is idempotent, so snmp_timeout can be polled (probably a cpu expensive
- X * proposition). snmp_timeout checks to see if any of the sessions have an
- X * outstanding request that has timed out. If it finds one (or more), and that
- X * pdu has more retries available, a new packet is formed from the pdu and is
- X * resent. If there are no more retries available, the callback for the session
- X * is used to alert the user of the timeout.
- X */
- Xvoid
- Xsnmp_timeout(){
- X struct session_list *slp;
- X struct snmp_session *sp;
- X struct snmp_internal_session *isp;
- X struct request_list *rp, *orp, *freeme = NULL;
- X struct timeval now;
- X
- X gettimeofday(&now, (struct timezone *)0);
- X /*
- X * For each request outstanding, check to see if it has expired.
- X */
- X for(slp = Sessions; slp; slp = slp->next){
- X sp = slp->session;
- X isp = slp->internal;
- X orp = NULL;
- X for(rp = isp->requests; rp; rp = rp->next_request){
- X if (freeme != NULL){ /* frees rp's after the for loop goes on to the next_request */
- X free((char *)freeme);
- X freeme = NULL;
- X }
- X if (timercmp(&rp->expire, &now, <)){
- X /* this timer has expired */
- X if (rp->retries >= sp->retries){
- X /* No more chances, delete this entry */
- X sp->callback(TIMED_OUT, sp, rp->pdu->reqid, rp->pdu, sp->callback_magic);
- X if (orp == NULL){
- X isp->requests = rp->next_request;
- X } else {
- X orp->next_request = rp->next_request;
- X }
- X snmp_free_pdu(rp->pdu);
- X freeme = rp;
- X continue; /* don't update orp below */
- X } else {
- X u_char packet[PACKET_LENGTH];
- X int length = PACKET_LENGTH;
- X struct timeval tv;
- X
- X /* retransmit this pdu */
- X rp->retries++;
- X rp->timeout <<= 1;
- X if (snmp_build(sp, rp->pdu, packet, &length) < 0){
- X fprintf(stderr, "Error building packet\n");
- X }
- X if (snmp_dump_packet){
- X int count;
- X
- X for(count = 0; count < length; count++){
- X printf("%02X ", packet[count]);
- X if ((count % 16) == 15)
- X printf("\n");
- X }
- X printf("\n\n");
- X }
- X gettimeofday(&tv, (struct timezone *)0);
- X if (sendto(isp->sd, (char *)packet, length, 0, (struct sockaddr *)&rp->pdu->address, sizeof(rp->pdu->address)) < 0){
- X perror("sendto");
- X }
- X rp->time = tv;
- X tv.tv_usec += rp->timeout;
- X tv.tv_sec += tv.tv_usec / 1000000L;
- X tv.tv_usec %= 1000000L;
- X rp->expire = tv;
- X }
- X }
- X orp = rp;
- X }
- X if (freeme != NULL){
- X free((char *)freeme);
- X freeme = NULL;
- X }
- X }
- X}
- END_OF_FILE
- if test 28823 -ne `wc -c <'netramet/src/snmplib/snmpapi.c'`; then
- echo shar: \"'netramet/src/snmplib/snmpapi.c'\" unpacked with wrong size!
- fi
- # end of 'netramet/src/snmplib/snmpapi.c'
- fi
- if test -f 'netramet/src/snmplib/~snmp_vars.h.kip' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'netramet/src/snmplib/~snmp_vars.h.kip'\"
- else
- echo shar: Extracting \"'netramet/src/snmplib/~snmp_vars.h.kip'\" \(1789 characters\)
- sed "s/^X//" >'netramet/src/snmplib/~snmp_vars.h.kip' <<'END_OF_FILE'
- X/*
- X * Definitions for SNMP (RFC 1067) agent variable finder.
- X *
- X *
- X */
- X/***********************************************************
- X Copyright 1988, 1989 by Carnegie Mellon University
- X
- X All Rights Reserved
- X
- XPermission to use, copy, modify, and distribute this software and its
- Xdocumentation for any purpose and without fee is hereby granted,
- Xprovided that the above copyright notice appear in all copies and that
- Xboth that copyright notice and this permission notice appear in
- Xsupporting documentation, and that the name of CMU not be
- Xused in advertising or publicity pertaining to distribution of the
- Xsoftware without specific, written prior permission.
- X
- XCMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
- XALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
- XCMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
- XANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- XWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
- XARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- XSOFTWARE.
- X******************************************************************/
- X
- X#define MAX_INTERFACES 2
- Xextern struct mib_ifEntry mib_ifEntry[MAX_INTERFACES];
- Xextern struct mib_ip mib_ip;
- X#define ROUTE_ENTRIES 2
- Xextern struct mib_udp mib_udp;
- Xextern long mib_icmpInMsgs;
- Xextern long mib_icmpOutMsgs;
- Xextern long mib_icmpInErrors; /* not checked in KIP */
- Xextern long mib_icmpOutErrors; /* not checked in KIP */
- Xextern long mib_icmpInCount[];
- Xextern long mib_icmpOutCount[];
- X
- Xu_char *var_system();
- Xu_char *var_ifEntry();
- Xu_char *var_atEntry();
- Xu_char *var_ip();
- Xu_char *var_ipAddrEntry();
- Xu_char *var_ipRouteEntry();
- Xu_char *var_icmp();
- Xu_char *var_udp();
- Xu_char *getStatPtr();
- X
- X
- END_OF_FILE
- if test 1789 -ne `wc -c <'netramet/src/snmplib/~snmp_vars.h.kip'`; then
- echo shar: \"'netramet/src/snmplib/~snmp_vars.h.kip'\" unpacked with wrong size!
- fi
- # end of 'netramet/src/snmplib/~snmp_vars.h.kip'
- fi
- echo shar: End of archive 19 \(of 25\).
- cp /dev/null ark19isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 25 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still must unpack the following archives:
- echo " " ${MISSING}
- fi
- exit 0
- exit 0 # Just in case...
-