home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume40 / netramet / part19 < prev    next >
Encoding:
Text File  |  1993-11-07  |  64.0 KB  |  2,130 lines

  1. Newsgroups: comp.sources.misc
  2. From: nevil@ccu1.aukuni.ac.nz (J Nevil Brownlee)
  3. Subject: v40i107:  netramet - Network Traffic Accounting Meter, Part19/25
  4. Message-ID: <1993Nov7.221409.12568@sparky.sterling.com>
  5. X-Md4-Signature: 056c3eed425e1490b79a96528a729666
  6. Sender: kent@sparky.sterling.com (Kent Landfield)
  7. Organization: Sterling Software
  8. Date: Sun, 7 Nov 1993 22:14:09 GMT
  9. Approved: kent@sparky.sterling.com
  10.  
  11. Submitted-by: nevil@ccu1.aukuni.ac.nz (J Nevil Brownlee)
  12. Posting-number: Volume 40, Issue 107
  13. Archive-name: netramet/part19
  14. Environment: INET, UNIX, DOS
  15.  
  16. #! /bin/sh
  17. # This is a shell archive.  Remove anything before this line, then feed it
  18. # into a shell via "sh file" or similar.  To overwrite existing files,
  19. # type "sh file -c".
  20. # Contents:  netramet/src/manager/oldnm.c
  21. #   netramet/src/snmplib/snmpapi.c
  22. #   netramet/src/snmplib/~snmp_vars.h.kip
  23. # Wrapped by kent@sparky on Tue Nov  2 18:17:11 1993
  24. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
  25. echo If this archive is complete, you will see the following message:
  26. echo '          "shar: End of archive 19 (of 25)."'
  27. if test -f 'netramet/src/manager/oldnm.c' -a "${1}" != "-c" ; then 
  28.   echo shar: Will not clobber existing file \"'netramet/src/manager/oldnm.c'\"
  29. else
  30.   echo shar: Extracting \"'netramet/src/manager/oldnm.c'\" \(29675 characters\)
  31.   sed "s/^X//" >'netramet/src/manager/oldnm.c' <<'END_OF_FILE'
  32. X/* 1200, Fri 23 Oct 92
  33. X
  34. X   NM.C:  First attempt at a manager for the AU Accounting Meter
  35. X
  36. X   Copyright (C) 1992 by Nevil Brownlee,
  37. X   Computer Centre,  University of Auckland */
  38. X
  39. X/***********************************************************
  40. X    Copyright 1988 by Carnegie Mellon University
  41. X
  42. X                      All Rights Reserved
  43. X
  44. XPermission to use, copy, modify, and distribute this software and its 
  45. Xdocumentation for any purpose and without fee is hereby granted, 
  46. Xprovided that the above copyright notice appear in all copies and that
  47. Xboth that copyright notice and this permission notice appear in 
  48. Xsupporting documentation, and that the name of CMU not be
  49. Xused in advertising or publicity pertaining to distribution of the
  50. Xsoftware without specific, written prior permission.  
  51. X
  52. XCMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  53. XALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  54. XCMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  55. XANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  56. XWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  57. XARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  58. XSOFTWARE.
  59. X******************************************************************/
  60. X#include <sys/param.h>
  61. X#include <sys/types.h>
  62. X#include <netinet/in.h>
  63. X#include <netdb.h>
  64. X
  65. X#include <stdio.h>
  66. X#include <ctype.h>
  67. X#include <sys/time.h>
  68. X#include <errno.h>
  69. X
  70. X#include <string.h>
  71. X#include <malloc.h>
  72. X
  73. X#include "snmp.h"
  74. X#include "snmpimpl.h"
  75. X#include "asn1.h"
  76. X#include "snmpclnt.h"
  77. X#include "snmpapi.h"
  78. X#include "mib.h"
  79. X
  80. X#ifndef BSD4_3
  81. X#define BSD4_2
  82. X#endif
  83. X
  84. X#define FLOWLIMIT  6000
  85. X#define RULEFILE "rules.txt"
  86. X
  87. Xextern int  errno;
  88. Xint    snmp_dump_packet = 0;
  89. X
  90. X#define  INT_ACCT  1, 3, 6, 1, 3, 99
  91. X#define  AUKUNI    1, 3, 6, 1, 4, 1, 411
  92. X
  93. Xoid o_sysDescr[]          = {MIB, 1, 1, 0};
  94. Xoid o_sysUpTime[]      = {MIB, 1, 3, 0};
  95. Xoid o_ifNumber[]      = {MIB, 2, 1, 0};
  96. X
  97. X#define    FT_INDEX  (sizeof(o_ftFlowNbr)/sizeof(oid) - 1)
  98. X
  99. Xoid o_ftFlowNbr[]         = {INT_ACCT, 3, 1, 1, 0xFFFF};
  100. Xoid o_ftFlowStatus[]      = {INT_ACCT, 3, 1, 2, 0xFFFF};
  101. Xoid o_ftNextActiveFlow[]  = {INT_ACCT, 3, 1, 3, 0xFFFF};
  102. Xoid o_ftAddrType[]        = {INT_ACCT, 3, 1, 4, 0xFFFF};
  103. Xoid o_ftFromAddr[]        = {INT_ACCT, 3, 1, 5, 0xFFFF};
  104. Xoid o_ftFromMask[]        = {INT_ACCT, 3, 1, 6, 0xFFFF};
  105. Xoid o_ftFromTally[]       = {INT_ACCT, 3, 1, 7, 0xFFFF};
  106. Xoid o_ftToAddr[]          = {INT_ACCT, 3, 1, 8, 0xFFFF};
  107. Xoid o_ftToMask[]          = {INT_ACCT, 3, 1, 9, 0xFFFF};
  108. Xoid o_ftToTally[]         = {INT_ACCT, 3, 1,10, 0xFFFF};
  109. Xoid o_ftFwdPackets[]      = {INT_ACCT, 3, 1,11, 0xFFFF};
  110. Xoid o_ftFwdBytes[]        = {INT_ACCT, 3, 1,12, 0xFFFF};
  111. Xoid o_ftBackPackets[]     = {INT_ACCT, 3, 1,13, 0xFFFF};
  112. Xoid o_ftBackBytes[]       = {INT_ACCT, 3, 1,14, 0xFFFF};
  113. Xoid o_ftChkFwdPackets[]   = {INT_ACCT, 3, 1,15, 0xFFFF};
  114. Xoid o_ftChkFwdBytes[]     = {INT_ACCT, 3, 1,16, 0xFFFF};
  115. Xoid o_ftChkBackPackets[]  = {INT_ACCT, 3, 1,17, 0xFFFF};
  116. Xoid o_ftChkBackBytes[]    = {INT_ACCT, 3, 1,18, 0xFFFF};
  117. Xoid o_ftFlowBlob[]        = {INT_ACCT, 3, 1,19, 0xFFFF};
  118. Xoid o_ftFlowCount[]       = {INT_ACCT, 3, 2, 0};
  119. Xoid o_ftChkTime[]         = {INT_ACCT, 3, 3, 0};
  120. Xoid o_ftChkFlowCount[]    = {INT_ACCT, 3, 4, 0};
  121. Xoid o_ftPrevChkTime[]     = {INT_ACCT, 3, 5, 0};
  122. Xoid o_ftChkActFlows[]     = {INT_ACCT, 3, 6, 0};
  123. Xoid o_ftFirstActFlow[]    = {INT_ACCT, 3, 7, 0};
  124. Xoid o_ftCheckPoint[]      = {INT_ACCT, 3, 8, 0};
  125. X
  126. X#define    RT_INDEX  (sizeof(o_rtIndex)/sizeof(oid) - 1)
  127. X
  128. Xoid o_rtIndex[]           = {INT_ACCT, 4, 1, 1, 0xFFFF};
  129. Xoid o_rtTreeNbr[]         = {INT_ACCT, 4, 1, 2, 0xFFFF};
  130. Xoid o_rtAddrType[]        = {INT_ACCT, 4, 1, 3, 0xFFFF};
  131. Xoid o_rtFromAddr[]        = {INT_ACCT, 4, 1, 4, 0xFFFF};
  132. Xoid o_rtFromMask[]        = {INT_ACCT, 4, 1, 5, 0xFFFF};
  133. Xoid o_rtFromTally[]       = {INT_ACCT, 4, 1, 6, 0xFFFF};
  134. Xoid o_rtToAddr[]          = {INT_ACCT, 4, 1, 7, 0xFFFF};
  135. Xoid o_rtToMask[]          = {INT_ACCT, 4, 1, 8, 0xFFFF};
  136. Xoid o_rtToTally[]         = {INT_ACCT, 4, 1, 9, 0xFFFF};
  137. X
  138. Xoid o_crRuleCount[]       = {INT_ACCT, 4, 2, 0};
  139. Xoid o_crTreeNbr[]         = {INT_ACCT, 4, 3, 0};
  140. Xoid o_crAddrType[]        = {INT_ACCT, 4, 4, 0};
  141. Xoid o_crFromAddr[]        = {INT_ACCT, 4, 5, 0};
  142. Xoid o_crFromMask[]        = {INT_ACCT, 4, 6, 0};
  143. Xoid o_crFromTally[]       = {INT_ACCT, 4, 7, 0};
  144. Xoid o_crToAddr[]          = {INT_ACCT, 4, 8, 0};
  145. Xoid o_crToMask[]          = {INT_ACCT, 4, 9, 0};
  146. Xoid o_crToTally[]         = {INT_ACCT, 4,10, 0};
  147. X
  148. X#define    PT_INDEX  (sizeof(o_ptPacketType) - 1)
  149. X
  150. Xoid o_ptpacket_types[]    = {AUKUNI, 1, 1, 0};
  151. Xoid o_ptPacketType[]      = {AUKUNI, 1, 2, 1, 1, 0xFF};
  152. Xoid o_ptPacketCount[]     = {AUKUNI, 1, 2, 1, 2, 0xFF};
  153. Xoid o_ptByteCount[]       = {AUKUNI, 1, 2, 1, 3, 0xFF};
  154. X
  155. Xoid o_pcNearMem[]         = {AUKUNI, 2, 1, 0};
  156. Xoid o_pcFarMem[]          = {AUKUNI, 2, 2, 0};
  157. Xoid o_pcBadPackets[]      = {AUKUNI, 2, 3, 0};
  158. Xoid o_pcNoBufPackets[]    = {AUKUNI, 2, 4, 0};
  159. Xoid o_pcLostPackets[]     = {AUKUNI, 2, 5, 0};
  160. Xoid o_pcPacketBacklog[]   = {AUKUNI, 2, 6, 0};
  161. Xoid o_pcChkSearches[]     = {AUKUNI, 2, 7, 0};
  162. Xoid o_pcChkCompares[]     = {AUKUNI, 2, 8, 0};
  163. X
  164. X
  165. X#define ADDR_LEN  4
  166. X
  167. Xstruct flow_info {
  168. X   unsigned char AddrType,
  169. X      FromAddr[ADDR_LEN], FromMask[ADDR_LEN], FromTally[ADDR_LEN],
  170. X      ToAddr[ADDR_LEN], ToMask[ADDR_LEN], ToTally[ADDR_LEN];
  171. X   unsigned long
  172. X      FwdPackets,FwdBytes,  BackPackets,BackBytes;
  173. X   unsigned short NextActiveFlow;
  174. X   };
  175. X
  176. Xstruct rule_info {
  177. X   int RuleNbr;
  178. X   unsigned char TreeNbr, AddrType,
  179. X      FromAddr[ADDR_LEN], FromMask[ADDR_LEN], FromTally[ADDR_LEN],
  180. X      ToAddr[ADDR_LEN], ToMask[ADDR_LEN], ToTally[ADDR_LEN];
  181. X   };
  182. X
  183. X#define AT_IGNORE     0  /* Addr_type values */
  184. X#define AT_IP         1
  185. X#define AT_NOVELL     2
  186. X#define AT_DECNET     3
  187. X#define AT_ETHERTALK  4
  188. X
  189. X#define NAME_LN  64
  190. X
  191. Xstruct meter_status {
  192. X   struct meter_status *next;
  193. X
  194. X   char name[NAME_LN];
  195. X   char community[NAME_LN];
  196. X   char rulefile[NAME_LN];
  197. X
  198. X   struct snmp_session *ss;
  199. X
  200. X   short status;
  201. X
  202. X   char descr[NAME_LN];  /* From meter_info() */
  203. X   long uptime;
  204. X   short ifcount;
  205. X
  206. X   unsigned short flowcount;  /* Current nbr of flows */
  207. X   unsigned short rulecount;  /*    and rules */
  208. X
  209. X   unsigned short flowsknown;  /* Nbr of flows we have key data for */
  210. X
  211. X   unsigned short CheckPoint;
  212. X   unsigned short ChkFlowCount;
  213. X   unsigned short ChkActFlows;
  214. X   unsigned short FirstActFlow;
  215. X   long ChkTime;
  216. X   long PrevChkTime;
  217. X
  218. X   FILE *keys;
  219. X   FILE *flows;
  220. X   FILE *log;
  221. X   };
  222. X
  223. Xstruct meter_status *first_meter;
  224. X
  225. X/* Values for status */
  226. X
  227. X#define    MT_MANAGE    0x0001  /* Manage this meter */
  228. X#define    MT_INFO         0x0002  /* Have basic info */
  229. X#define    MT_UP         0x0004  /* Meter is running */
  230. X#define    MT_REPORTED  0x0008  /* Current status reported */
  231. X
  232. X#ifdef MTR_LIST
  233. X/* #define  CTLFILE  "/usr/local/src/snmp/manager.cfg" */
  234. X#define  CTLFILE  "manager.cfg"
  235. X#endif
  236. X
  237. Xunsigned short getshort(unsigned char *ucp);
  238. Xunsigned long getlong(unsigned char *ucp);
  239. X
  240. Xvoid init_meter();
  241. Xvoid monitor_meter();
  242. Xvoid monitor(struct meter_status *ms);
  243. Xvoid print_meters();
  244. Xvoid meter_print(struct meter_status *ms);
  245. X
  246. Xvoid printaddress(FILE *f,unsigned char *a);
  247. Xvoid getaddress(unsigned char *a);
  248. X
  249. Xvoid parse_rulefile(struct meter_status *ms, int list);
  250. Xint add_rule(struct meter_status *ms, struct rule_info *ri);
  251. X
  252. Xint chk_info(struct meter_status *ms, int control);
  253. X
  254. Xint blob_info(struct meter_status *ms, unsigned char *fb, int fn);
  255. Xint flow_info(struct meter_status *ms, struct flow_info *fi,
  256. X   int fn, int getkey, int getflow);
  257. X
  258. Xchar *uptime_string(unsigned long timeticks, char *buf);
  259. X
  260. Xint verbose;
  261. X
  262. Xvoid main(argc,argv)
  263. Xint argc;
  264. Xchar *argv[];
  265. X{
  266. X   struct meter_status *ms;
  267. X   struct snmp_session session, *ssp;
  268. X
  269. X   int arg;
  270. X   char meter[NAME_LN], community[NAME_LN], rfname[NAME_LN],
  271. X      filename[NAME_LN*2];
  272. X   int interval = 0;
  273. X
  274. X   meter[0] = community[0] = rfname[0] = NULL;
  275. X
  276. X#ifdef MTR_LIST
  277. X   parse_ctlfile();
  278. X#endif
  279. X
  280. X   init_mib();
  281. X
  282. X   /*  usage: nm meter-name community */
  283. X
  284. X   for (arg = 1; arg < argc; arg++) {
  285. X      if (argv[arg][0] == '-') {
  286. X     switch (argv[arg][1]) {
  287. X     case 'd':
  288. X        snmp_dump_packet++;
  289. X        break;
  290. X     case 'c':
  291. X        if ((interval = atoi(argv[arg]+2)) == 0) interval = 120;
  292. X        break;
  293. X     case 'r':
  294. X        strcpy(rfname, argv[++arg]);
  295. X        break;
  296. X     case 'v':
  297. X        verbose++;
  298. X        break;
  299. X     default:
  300. X        printf("Invalid option: -%c\n", argv[arg][1]);
  301. X        break;
  302. X        }
  303. X     continue;
  304. X     }
  305. X      if (meter[0] == NULL) strcpy(meter,argv[arg]);
  306. X      else if (community[0] == NULL) strcpy(community,argv[arg]);
  307. X      }
  308. X
  309. X   if (meter[0] == NULL) {
  310. X      printf("nm meter-name community\n\n");
  311. X      exit(0);
  312. X      }
  313. X
  314. X   ms = (struct meter_status *)calloc(sizeof(struct meter_status), 1);
  315. X   strcpy(ms->name,meter);
  316. X   strcpy(ms->community,community);
  317. X   if (*rfname) strcpy(ms->rulefile, rfname);
  318. X   else strcpy(ms->rulefile, RULEFILE);
  319. X
  320. X   strcpy(filename,meter);
  321. X   strcat(filename,".log");
  322. X   if ((ms->log = fopen(filename,"wa")) == NULL) {
  323. X      printf("Failed to open %s\n",filename);
  324. X      exit(0);
  325. X      }
  326. X   strcpy(filename,meter);
  327. X   strcat(filename,".keys");
  328. X   if ((ms->keys = fopen(filename,"wa")) == NULL) {
  329. X      printf("Failed to open %s\n",filename);
  330. X      exit(0);
  331. X      }
  332. X   strcpy(filename,meter);
  333. X   strcat(filename,".flows");
  334. X   if ((ms->flows = fopen(filename,"wa")) == NULL) {
  335. X      printf("Failed to open %s\n",filename);
  336. X      exit(0);
  337. X      }
  338. X
  339. X   bzero((char *)&session, sizeof(struct snmp_session));
  340. X   session.peername = ms->name;
  341. X   session.community = ms->community;
  342. X   session.community_len = strlen(ms->community);
  343. X   session.retries = SNMP_DEFAULT_RETRIES;
  344. X   session.timeout = SNMP_DEFAULT_TIMEOUT;
  345. X   session.authenticator = NULL;
  346. X   snmp_synch_setup(&session);
  347. X   ssp = snmp_open(&session);
  348. X   if (ssp == NULL) {
  349. X      printf("Couldn't open snmp to %s\n", session.peername);
  350. X      exit(-1);
  351. X      }
  352. X   ms->ss = ssp;
  353. X
  354. X   ms->status = MT_MANAGE;
  355. X   first_meter = ms;  /* $$$$$$$ */
  356. X
  357. X#ifdef MTR_LIST
  358. X   if (!explicit) add_all_meters();
  359. X#endif
  360. X
  361. X   init_meter();
  362. X
  363. X   if (!interval) {
  364. X      print_meters();
  365. X      exit (0);
  366. X      }
  367. X
  368. X   parse_rulefile(ms,TRUE);  /* Download the rules we want to use */
  369. X
  370. X   for (;;) {
  371. X      sleep(interval);
  372. X
  373. X      monitor_meter();
  374. X      if (verbose) print_meters();
  375. X      }
  376. X   }
  377. X
  378. X#ifdef MTR_LIST
  379. Xvoid parse_ctlfile()
  380. X{
  381. X   struct meter_status *ms, *mp;
  382. X   FILE *fp;
  383. X   char linebuffer[256];
  384. X   char label[128];
  385. X   char community[128];
  386. X   int n;
  387. X
  388. X   if ((fp = fopen(CTLFILE, "r")) == NULL) {
  389. X      perror(CTLFILE);
  390. X      exit(1);
  391. X      }
  392. X
  393. X   while (fgets(linebuffer, sizeof(linebuffer), fp) != NULL) {
  394. X      if (linebuffer[0] < '0' || linebuffer[0] > 'z') continue;
  395. X      n = sscanf(linebuffer, "%s %s", label, community);
  396. X      if (n < 1) continue;
  397. X      ms = (struct meter_status *)calloc(sizeof(struct meter_status), 1);
  398. X      ms->name = savestr(label);
  399. X      ms->community = n > 1 ? savestr(community) : savestr("public");
  400. X      ms->next = NULL;
  401. X
  402. X      if ((mp = first_meter) == NULL) first_meter = ms;
  403. X      else {
  404. X     while (mp->next) mp = mp->next;
  405. X     mp->next = ms;
  406. X     }
  407. X      }
  408. X   }
  409. X
  410. Xvoid add_all_meters()
  411. X{
  412. X   struct meter_status *ms;
  413. X   for (ms = first_meter; ms != NULL; ms = ms->next)
  414. X      ms->status = MT_MANAGE;
  415. X   }
  416. X
  417. Xvoid add_meter(name)
  418. Xchar *name;
  419. X{
  420. X   struct meter_status *ms;
  421. X
  422. X   for (ms = first_meter; ms != NULL; ms = ms->next) {
  423. X      if (strcasecmp(name,ms->name) == 0) break;
  424. X      }
  425. X
  426. X   if (ms == NULL) {
  427. X      struct hostent *hp;
  428. X      u_long addr;
  429. X
  430. X      if ((addr = (u_long)inet_addr(name)) == (u_long)-1) {
  431. X     hp = gethostbyname(name);
  432. X     if (hp != NULL) {
  433. X        for (ms = first_meter; ms != NULL; ms = ms->next) {
  434. X#ifdef h_addr
  435. X           char **ap;
  436. X#endif
  437. X           if (strcasecmp(hp->h_name, ms->name) == 0) break;
  438. X#ifdef h_addr
  439. X           if (hp->h_addr_list == NULL) continue;
  440. X
  441. X           for (ap = hp->h_addr_list; *ap; ap++) {
  442. X          if (addr == *(u_long *)(*ap)) break;
  443. X          }
  444. X           if (*ap) break;
  445. X#else
  446. X           if (addr == *(u_long *)(hp->h_addr)) break;
  447. X#endif
  448. X                    
  449. X           }
  450. X        if (ms == NULL) {
  451. X           printf("No config info for %s\n", name);
  452. X           return;
  453. X           }
  454. X        }
  455. X         else {
  456. X        printf("No config info for %s\n", name);
  457. X        return;
  458. X        }
  459. X     }
  460. X      }
  461. X
  462. X   ms->status = MT_MANAGE;
  463. X   }
  464. X#endif
  465. X
  466. Xvoid init_meter()
  467. X{
  468. X   struct meter_status *ms;
  469. X   int haveone = 0;
  470. X
  471. X   for (ms = first_meter; ms; ms = ms->next) {
  472. X      if (!(ms->status & MT_MANAGE)) continue;
  473. X      haveone++;
  474. X      if (meter_info(ms)) {
  475. X         ms->status |= (MT_UP | MT_INFO);
  476. X         meter_print(ms);
  477. X         }
  478. X      }
  479. X
  480. X   if (!haveone) {
  481. X      printf("No meters to monitor\n");
  482. X      exit(5);
  483. X      }
  484. X   }
  485. X
  486. X
  487. Xvoid monitor_meter()
  488. X{
  489. X   struct meter_status *ms;
  490. X   for (ms = first_meter; ms; ms = ms->next)
  491. X      if (ms->status & MT_MANAGE) monitor(ms);
  492. X   }
  493. X
  494. X/* CAUTION:  Following struct doesn't work because of alignment on 32-bit words
  495. X *
  496. X * struct active_flow_data {  
  497. X *    unsigned short flow_nbr;
  498. X *    unsigned long fwd_bytes, back_bytes;
  499. X *    }; 
  500. X */
  501. X
  502. X#define flow_nbr_x    0
  503. X#define fwd_bytes_x   (flow_nbr_x + sizeof(unsigned short))
  504. X#define back_bytes_x  (fwd_bytes_x + sizeof(unsigned long))
  505. X#define flow_data_sz  (back_bytes_x + sizeof(unsigned long))
  506. X
  507. X#define FLOWBLOBSZ  25
  508. X
  509. Xunsigned short getshort(ucp)
  510. Xunsigned char *ucp;
  511. X{
  512. X   return ucp[0]<<8 | ucp[1];
  513. X   }
  514. X
  515. Xunsigned long getlong(ucp)
  516. Xunsigned char *ucp;
  517. X{
  518. X   return ucp[0]<<24 | ucp[1]<<16 | ucp[2]<<8 | ucp[3];
  519. X   }
  520. X
  521. Xvoid monitor(ms)  /* Called every interval for each meter */
  522. Xstruct meter_status *ms;
  523. X{
  524. X   time_t t;
  525. X   char *ts;
  526. X   unsigned short fn, nactive, n;
  527. X   struct flow_info fi;
  528. X   unsigned char flowblob[FLOWBLOBSZ*flow_data_sz], *afdp;
  529. X   unsigned long fwd_bytes, back_bytes;
  530. X
  531. X   time(&t);  ts = ctime(&t);
  532. X   if (!(ms->status & MT_INFO)) {  /* No info */
  533. X      if (meter_info(ms))  /* Got some */
  534. X     ms->status |= (MT_UP | MT_INFO);
  535. X      return;
  536. X      }
  537. X   if (meter_info(ms) == 0) {  /* Lost contact */
  538. X      if (ms->status & MT_UP) {  /* Was up */
  539. X     fprintf(ms->log,"%19.19s -- %s: No response\n", ts,ms->name);
  540. X     if (verbose) printf("%19.19s -- %s: No response\n", ts,ms->name);
  541. X     }
  542. X      ms->status &= ~MT_UP;  /* Mark as 'down' */
  543. X      return;
  544. X      }
  545. X   if (!(ms->status & MT_UP)) {  /* Have contact now, was down */
  546. X      fprintf(ms->log,"%19.19s -- %s: Regained contact\n", ts,ms->name);
  547. X      if (verbose) printf("%19.19s -- %s: Regained contact\n", ts,ms->name);
  548. X      }
  549. X   ms->status |= MT_UP;
  550. X
  551. X   /* Meter processing .. */
  552. X
  553. X   if (!chk_info(ms,1)) {
  554. X      printf("%19.19s -- %s: Failed to get chk info\n", ts,ms->name);
  555. X      return;
  556. X       }
  557. X   else {
  558. X      if (verbose) printf(
  559. X     "%19.19s -- %s: %u flows, %u active, %u first.  From %ld to %ld\n",
  560. X        ts,ms->name,
  561. X        ms->ChkFlowCount,ms->ChkActFlows,ms->FirstActFlow,
  562. X        ms->PrevChkTime,ms->ChkTime);
  563. X
  564. X      /* Get the keys and flows here .. */
  565. X
  566. X      fprintf(ms->keys, 
  567. X         "## %19.19s %s: %u flows, %u active. Checkpoint %u, from %ld to %ld##\n",
  568. X         ts,ms->name, ms->ChkFlowCount,ms->ChkActFlows, 
  569. X         ms->CheckPoint, ms->PrevChkTime,ms->ChkTime);
  570. X      for (fn = ms->flowsknown+1; fn <= ms->ChkFlowCount; ++fn) {
  571. X         if (!flow_info(ms, &fi, fn, 1, 0)) {
  572. X            printf(ms->log,"   Failed to get key for flow %d\n", fn);
  573. X            printf("Failed to get key for flow %d\n", fn);
  574. X            }
  575. X         else {
  576. X            fprintf(ms->keys, "%u %u", fn, fi.AddrType);
  577. X            printaddress(ms->keys, fi.FromAddr);
  578. X            printaddress(ms->keys, fi.ToAddr);
  579. X            fprintf(ms->keys,"\n");
  580. X        }
  581. X         }
  582. X      ms->flowsknown = ms->ChkFlowCount;
  583. X      fflush(ms->keys);
  584. X
  585. X      fprintf(ms->flows, 
  586. X         "## %19.19s %s: %u flows, %u active. Checkpoint %u, from %ld to %ld##\n",
  587. X         ts,ms->name, ms->ChkFlowCount,ms->ChkActFlows, 
  588. X         ms->CheckPoint, ms->PrevChkTime,ms->ChkTime);
  589. X      fn = ms->FirstActFlow;  nactive = ms->ChkActFlows;  
  590. X      while (nactive != 0) {
  591. X         if (!blob_info(ms,flowblob, fn)) {
  592. X            printf(ms->log,"   Failed to get flow for flow %d\n", fn);
  593. X            printf("Failed to get flow for flow %d\n", fn);
  594. X            }
  595. X         else {
  596. X            for (n = 0, afdp = flowblob;  nactive != 0 && n != FLOWBLOBSZ; 
  597. X                  --nactive, ++n, afdp += flow_data_sz) {
  598. X               fprintf(ms->flows,"%u %lu %lu\n",
  599. X                  fn = ntohs(getshort(afdp + flow_nbr_x)),
  600. X                  ntohl(getlong(afdp + fwd_bytes_x)),
  601. X                  ntohl(getlong(afdp + back_bytes_x)) );
  602. X           }
  603. X            }
  604. X         ++fn;
  605. X     }
  606. X      fflush(ms->flows);
  607. X
  608. X      if (ms->flowsknown > FLOWLIMIT) chk_info(ms,-1);  /* Restart meter */
  609. X      }
  610. X
  611. X   fflush(ms->log);  
  612. X   }
  613. X
  614. X#define ADD_VAR(v)        snmp_add_null_var(pdu, v, sizeof(v)/sizeof(oid))
  615. X#define ADD_X_VAR(v,x,n)  { v[x] = n;  ADD_VAR(v); }
  616. X
  617. X#define STRING_VAL(v)     bcopy(vars->val.string, v, vars->val_len)
  618. X#define INT_VAL(v)        v = *(vars->val.integer)
  619. X
  620. X#define SET_INT(v)        { vars->type = INTEGER;\
  621. X     vars->val.integer = (long *)malloc(vars->val_len = sizeof(long));\
  622. X     *(vars->val.integer) = (long)v; }
  623. X#define SET_STRING(v)     { vars->type = STRING;\
  624. X     vars->val.string = (u_char *)malloc(ADDR_LEN);\
  625. X     bcopy(v, (char *)vars->val.string, vars->val_len = ADDR_LEN); }
  626. X
  627. Xint add_rule(ms,ri)
  628. Xstruct meter_status *ms;
  629. Xstruct rule_info *ri;
  630. X{
  631. X   int i, count, status;
  632. X   struct snmp_pdu *pdu, *response;
  633. X   struct variable_list *vars;
  634. X
  635. X   pdu = snmp_pdu_create(SET_REQ_MSG);
  636. X   if (ri->RuleNbr == 0) {
  637. X      ADD_VAR(o_crRuleCount);  /* Clear rule table */
  638. X         vars = pdu->variables;
  639. X         SET_INT(ri->RuleNbr);
  640. X      }
  641. X   else {
  642. X      ADD_VAR(o_crTreeNbr);
  643. X         vars = pdu->variables;
  644. X         SET_INT(ri->TreeNbr);
  645. X      ADD_VAR(o_crAddrType);
  646. X         vars = vars->next_variable;
  647. X         SET_INT(ri->AddrType);
  648. X      ADD_VAR(o_crFromAddr);
  649. X         vars = vars->next_variable;
  650. X         SET_STRING(ri->FromAddr);
  651. X      ADD_VAR(o_crFromMask);
  652. X         vars = vars->next_variable;
  653. X         SET_STRING(ri->FromMask);
  654. X      ADD_VAR(o_crFromTally);
  655. X         vars = vars->next_variable;
  656. X         SET_STRING(ri->FromTally);
  657. X      ADD_VAR(o_crToAddr);
  658. X         vars = vars->next_variable;
  659. X         SET_STRING(ri->ToAddr);
  660. X      ADD_VAR(o_crToMask);
  661. X         vars = vars->next_variable;
  662. X         SET_STRING(ri->ToMask);
  663. X      ADD_VAR(o_crToTally);
  664. X         vars = vars->next_variable;
  665. X         SET_STRING(ri->ToTally);
  666. X      ADD_VAR(o_crRuleCount);  /* Add current rule to rule table */
  667. X         vars = vars->next_variable;
  668. X         SET_INT(ri->RuleNbr);
  669. X      }
  670. X
  671. X   status = snmp_synch_response(ms->ss, pdu, &response);
  672. X   if (status == STAT_SUCCESS) {
  673. X      if (response->errstat == SNMP_ERR_NOERROR) {
  674. X         if (ri->RuleNbr == 0) printf("Rule table cleared\n");
  675. X         else printf("Rule %d added to table\n", ri->RuleNbr);
  676. X         ms->rulecount = ri->RuleNbr;
  677. X     }
  678. X      else {
  679. X     printf("Error in packet\nReason: %sn",
  680. X        snmp_errstring(response->errstat));
  681. X     if (response->errstat == SNMP_ERR_NOSUCHNAME) {
  682. X        printf("This name does not exist: ");
  683. X        for (count=1, vars = response->variables;
  684. X           vars && count != response->errindex;
  685. X          vars = vars->next_variable, count++) ;
  686. X        if (vars) print_objid(vars->name, vars->name_length);
  687. X        printf("\n");
  688. X        }
  689. X     }
  690. X      }
  691. X   else return 0;
  692. X   snmp_free_pdu(response);
  693. X   return 1;
  694. X   }
  695. X
  696. Xint chk_info(ms,control)
  697. Xstruct meter_status *ms;
  698. Xint control;  /* 0 = read, -1 = restart, 1 = checkpoint */
  699. X{
  700. X   int i, count, status;
  701. X   struct snmp_pdu *pdu, *response;
  702. X   struct variable_list *vars;
  703. X
  704. X   if (control == -1) {
  705. X      ms->CheckPoint = ms->flowsknown = 0;
  706. X      }
  707. X   else if (control == 1) ++ms->CheckPoint;
  708. X
  709. X   if (control != 0) {  /* Make new checkpoint */
  710. X      pdu = snmp_pdu_create(SET_REQ_MSG);
  711. X      ADD_VAR(o_ftCheckPoint);
  712. X      vars = pdu->variables;
  713. X      SET_INT(ms->CheckPoint);  /* New checkpoint number */
  714. X      status = snmp_synch_response(ms->ss, pdu, &response);
  715. X      if (status == STAT_SUCCESS) {
  716. X     if (response->errstat == SNMP_ERR_NOERROR) {
  717. X        vars = response->variables;
  718. X        INT_VAL(ms->CheckPoint);
  719. X        }
  720. X     else {
  721. X        printf("Error in packet\nReason: %sn",
  722. X           snmp_errstring(response->errstat));
  723. X        if (response->errstat == SNMP_ERR_NOSUCHNAME) {
  724. X           printf("This name does not exist: ");
  725. X           for (count=1, vars = response->variables;
  726. X          vars && count != response->errindex;
  727. X             vars = vars->next_variable, count++) ;
  728. X           if (vars) print_objid(vars->name, vars->name_length);
  729. X           printf("\n");
  730. X           }
  731. X        }
  732. X     }
  733. X      else return 0;
  734. X      snmp_free_pdu(response);
  735. X      }
  736. X
  737. X   pdu = snmp_pdu_create(GET_REQ_MSG);
  738. X   ADD_VAR(o_ftChkFlowCount);
  739. X   ADD_VAR(o_ftChkActFlows);
  740. X   ADD_VAR(o_ftFirstActFlow);
  741. X   ADD_VAR(o_ftChkTime);
  742. X   ADD_VAR(o_ftPrevChkTime);
  743. X   status = snmp_synch_response(ms->ss, pdu, &response);
  744. X   if (status == STAT_SUCCESS) {
  745. X      if (response->errstat == SNMP_ERR_NOERROR) {
  746. X     vars = response->variables;
  747. X     INT_VAL(ms->ChkFlowCount);
  748. X     vars = vars->next_variable;
  749. X     INT_VAL(ms->ChkActFlows);
  750. X     vars = vars->next_variable;
  751. X     INT_VAL(ms->FirstActFlow);
  752. X     vars = vars->next_variable;
  753. X     INT_VAL(ms->ChkTime);
  754. X     vars = vars->next_variable;
  755. X     INT_VAL(ms->PrevChkTime);
  756. X     }
  757. X      else {
  758. X     printf("Error in packet\nReason: %sn",
  759. X        snmp_errstring(response->errstat));
  760. X     if (response->errstat == SNMP_ERR_NOSUCHNAME) {
  761. X        printf("This name does not exist: ");
  762. X        for (count=1, vars = response->variables;
  763. X           vars && count != response->errindex;
  764. X          vars = vars->next_variable, count++) ;
  765. X        if (vars) print_objid(vars->name, vars->name_length);
  766. X        printf("\n");
  767. X        }
  768. X     }
  769. X      }
  770. X   else return 0;
  771. X   snmp_free_pdu(response);
  772. X   return 1;
  773. X   }
  774. X
  775. Xint blob_info(ms,fb, fn)
  776. Xstruct meter_status *ms;
  777. Xunsigned char *fb;
  778. Xint fn;
  779. X{
  780. X   int i, count, status;
  781. X   struct snmp_pdu *pdu, *response;
  782. X   struct variable_list *vars;
  783. X
  784. X   pdu = snmp_pdu_create(GET_REQ_MSG);
  785. X   ADD_X_VAR(o_ftFlowBlob,FT_INDEX,fn);
  786. X   status = snmp_synch_response(ms->ss, pdu, &response);
  787. X   if (status == STAT_SUCCESS) {
  788. X      if (response->errstat == SNMP_ERR_NOERROR) {
  789. X     vars = response->variables;
  790. X     STRING_VAL(fb);
  791. X     }
  792. X      else {
  793. X     printf("Error in packet\nReason: %sn",
  794. X        snmp_errstring(response->errstat));
  795. X     if (response->errstat == SNMP_ERR_NOSUCHNAME) {
  796. X        printf("This name does not exist: ");
  797. X        for (count=1, vars = response->variables;
  798. X           vars && count != response->errindex;
  799. X          vars = vars->next_variable, count++) ;
  800. X        if (vars) print_objid(vars->name, vars->name_length);
  801. X        printf("\n");
  802. X        }
  803. X     }
  804. X      }
  805. X   else return 0;
  806. X   snmp_free_pdu(response);
  807. X   return 1;
  808. X   }
  809. X
  810. Xint flow_info(ms,fi, fn, getkey,getflow)
  811. Xstruct meter_status *ms;
  812. Xstruct flow_info *fi;
  813. Xint fn, getkey,getflow;
  814. X{
  815. X   int i, count, status;
  816. X   struct snmp_pdu *pdu, *response;
  817. X   struct variable_list *vars;
  818. X
  819. X   pdu = snmp_pdu_create(GET_REQ_MSG);
  820. X   if (getkey) {
  821. X      ADD_X_VAR(o_ftAddrType,FT_INDEX,fn);
  822. X      ADD_X_VAR(o_ftFromAddr,FT_INDEX,fn);
  823. X      ADD_X_VAR(o_ftToAddr,FT_INDEX,fn);
  824. X      }
  825. X   if (getflow) {
  826. X      ADD_X_VAR(o_ftChkFwdBytes,FT_INDEX,fn);
  827. X      ADD_X_VAR(o_ftChkBackBytes,FT_INDEX,fn);
  828. X      ADD_X_VAR(o_ftNextActiveFlow,FT_INDEX,fn);
  829. X      }
  830. X   status = snmp_synch_response(ms->ss, pdu, &response);
  831. X   if (status == STAT_SUCCESS) {
  832. X      if (response->errstat == SNMP_ERR_NOERROR) {
  833. X     vars = response->variables;
  834. X     if (getkey) {
  835. X        INT_VAL(fi->AddrType);
  836. X        vars = vars->next_variable;
  837. X        STRING_VAL(fi->FromAddr);
  838. X        vars = vars->next_variable;
  839. X        STRING_VAL(fi->ToAddr);
  840. X        vars = vars->next_variable;
  841. X        }
  842. X     if (getflow) {
  843. X        INT_VAL(fi->FwdBytes);
  844. X        vars = vars->next_variable;
  845. X        INT_VAL(fi->BackBytes);
  846. X        vars = vars->next_variable;
  847. X        INT_VAL(fi->NextActiveFlow);
  848. X        }
  849. X     }
  850. X      else {
  851. X     printf("Error in packet\nReason: %sn",
  852. X        snmp_errstring(response->errstat));
  853. X     if (response->errstat == SNMP_ERR_NOSUCHNAME) {
  854. X        printf("This name does not exist: ");
  855. X        for (count=1, vars = response->variables;
  856. X           vars && count != response->errindex;
  857. X          vars = vars->next_variable, count++) ;
  858. X        if (vars) print_objid(vars->name, vars->name_length);
  859. X        printf("\n");
  860. X        }
  861. X     }
  862. X      }
  863. X   else return 0;
  864. X   snmp_free_pdu(response);
  865. X   return 1;
  866. X   }
  867. X
  868. Xint meter_info(ms)
  869. Xstruct meter_status *ms;
  870. X{
  871. X   int i, count, status;
  872. X   struct snmp_pdu *pdu, *response;
  873. X   struct variable_list *vars;
  874. X
  875. X   pdu = snmp_pdu_create(GET_REQ_MSG);
  876. X   ADD_VAR(o_sysDescr);
  877. X   ADD_VAR(o_sysUpTime);
  878. X   ADD_VAR(o_ifNumber);
  879. X   ADD_VAR(o_ftFlowCount);
  880. X   status = snmp_synch_response(ms->ss, pdu, &response);
  881. X   if (status == STAT_SUCCESS) {
  882. X      if (response->errstat == SNMP_ERR_NOERROR) {
  883. X     vars = response->variables;
  884. X     STRING_VAL(ms->descr);
  885. X         vars = vars->next_variable;
  886. X     INT_VAL(ms->uptime);
  887. X         vars = vars->next_variable;
  888. X     INT_VAL(ms->ifcount);
  889. X         vars = vars->next_variable;
  890. X     INT_VAL(ms->flowcount);
  891. X     }
  892. X      else {
  893. X     printf("Error in packet\nReason: %sn",
  894. X        snmp_errstring(response->errstat));
  895. X     if (response->errstat == SNMP_ERR_NOSUCHNAME) {
  896. X        printf("This name does not exist: ");
  897. X        for (count=1, vars = response->variables;
  898. X           vars && count != response->errindex;
  899. X          vars = vars->next_variable, count++) ;
  900. X        if (vars) print_objid(vars->name, vars->name_length);
  901. X        printf("\n");
  902. X        }
  903. X     }
  904. X      }
  905. X   else return 0;
  906. X   snmp_free_pdu(response);
  907. X   return 1;
  908. X   }
  909. X
  910. Xvoid print_meters()
  911. X{
  912. X   struct meter_status *ms;
  913. X   for (ms = first_meter; ms; ms = ms->next)
  914. X      if (ms->status & MT_MANAGE) meter_print(ms);
  915. X   }
  916. X
  917. Xvoid meter_print(ms)
  918. Xstruct meter_status *ms;
  919. X{
  920. X   struct timeval tv;
  921. X   char buf[32];
  922. X   time_t t;   char *ts;
  923. X
  924. X   time(&t);  ts = ctime(&t);
  925. X
  926. X   gettimeofday(&tv, (struct timezone *)0);
  927. X   tv.tv_sec -= ms->uptime / 100;
  928. X   if ((ms->uptime % 100)*10000 > tv.tv_usec) {
  929. X      tv.tv_sec--;
  930. X      tv.tv_usec += 1000000;
  931. X      }
  932. X   tv.tv_usec -= (ms->uptime % 100)*10000;
  933. X
  934. X   fprintf(ms->log,
  935. X      "%19.19s -- %s: %s\n\tUp %s (since %.24s)\n\t\t%d interfaces, %u flows\n\n",
  936. X     ts,ms->name, ms->descr, uptime_string(ms->uptime, buf),
  937. X     ctime(&tv.tv_sec), ms->ifcount, ms->flowcount);
  938. X   if (verbose) printf(
  939. X      "%19.19s -- %s: %s\n\tUp %s (since %.24s)\n\t\t%d interfaces, %u flows\n\n",
  940. X     ts,ms->name, ms->descr, uptime_string(ms->uptime, buf),
  941. X     ctime(&tv.tv_sec), ms->ifcount, ms->flowcount);
  942. X   }
  943. X
  944. X
  945. Xchar *uptime_string(timeticks, buf)
  946. Xunsigned long timeticks;
  947. Xchar *buf;
  948. X{
  949. X   int    seconds, minutes, hours, days;
  950. X
  951. X   timeticks /= 100;
  952. X   days = timeticks / (60 * 60 * 24);
  953. X   timeticks %= (60 * 60 * 24);
  954. X
  955. X   hours = timeticks / (60 * 60);
  956. X   timeticks %= (60 * 60);
  957. X
  958. X   minutes = timeticks / 60;
  959. X   seconds = timeticks % 60;
  960. X
  961. X   if (days == 0){
  962. X      sprintf(buf, "%d:%02d:%02d", hours, minutes, seconds);
  963. X      }
  964. X   else if (days == 1) {
  965. X      sprintf(buf, "%d day, %d:%02d:%02d",
  966. X     days, hours, minutes, seconds);
  967. X      }
  968. X   else {
  969. X      sprintf(buf, "%d days, %d:%02d:%02d",
  970. X     days, hours, minutes, seconds);
  971. X      }
  972. X   return buf;
  973. X   }
  974. X
  975. Xvoid printaddress(f,a)
  976. XFILE *f;
  977. Xunsigned char *a;
  978. X{
  979. X   int j;
  980. X   fprintf(f," %u", a[0]);
  981. X   for (j = 1; j != ADDR_LEN; ++j) fprintf(f,".%u", a[j]);
  982. X   }
  983. X
  984. X
  985. XFILE *rfp;  /* For rules file */
  986. Xchar inbuf[256], *ibp;
  987. Xint lic, ic, iblisted, rule_line;
  988. X
  989. Xint nextchar()
  990. X{
  991. X   lic = ic;
  992. X   for (;;) {
  993. X      if (lic == '\n') {
  994. X     if (fgets(inbuf, sizeof(inbuf), rfp) == NULL) return ic = EOF;
  995. X     iblisted = 0;  ++rule_line;
  996. X     ibp = inbuf;
  997. X     }
  998. X      ic = *ibp++;
  999. X      if (ic == '#') lic = '\n';  /* Ignore comments */
  1000. X      else return ic;
  1001. X      }
  1002. X   }
  1003. X
  1004. Xint getnbr()
  1005. X{
  1006. X   int v = 0;
  1007. X   for (;;) {
  1008. X      if (ic == EOF) return EOF;
  1009. X      if (isdigit(ic)) break;
  1010. X      else nextchar(rfp);
  1011. X      }
  1012. X   for (;;) {
  1013. X      v = v*10 + ic-'0';
  1014. X      if (nextchar(ic) == EOF) return EOF;
  1015. X      if (!isdigit(ic)) break;
  1016. X      }
  1017. X   if (v > 255) {
  1018. X      if (!iblisted) {
  1019. X     printf("RULEFILE line %d: %s\n", rule_line,inbuf);
  1020. X     iblisted = 1;
  1021. X     }
  1022. X      printf("Number > 255 !!!\n");
  1023. X      }
  1024. X   return v;
  1025. X   }
  1026. X
  1027. Xvoid getaddress(a)
  1028. Xunsigned char *a;
  1029. X{
  1030. X   int j;
  1031. X   for (j = 0; j != ADDR_LEN; ++j) a[j] = getnbr();
  1032. X   }
  1033. X
  1034. Xvoid parse_rulefile(ms,list)
  1035. Xstruct meter_status *ms;
  1036. Xint list;
  1037. X{
  1038. X   struct rule_info ri;
  1039. X   int c, rule_nbr = 0;
  1040. X
  1041. X   if ((rfp = fopen(ms->rulefile, "r")) == NULL) {
  1042. X      perror(ms->rulefile);
  1043. X      exit(1);
  1044. X      }
  1045. X
  1046. X   ri.RuleNbr = 0;  add_rule(ms, &ri);  /* Clear rule table */
  1047. X   
  1048. X   ic = '\n';  rule_line = 0;
  1049. X   for (;;) {
  1050. X      do {  /* First char of a line */
  1051. X     nextchar(rfp);
  1052. X     if (ic == EOF) break;
  1053. X     } while (lic != '\n');
  1054. X      if (ic == EOF) break;
  1055. X      ri.TreeNbr = getnbr();
  1056. X      if (ic == EOF) break;
  1057. X      for (;;) {
  1058. X     if (ic == EOF) break;
  1059. X     if (isalpha(ic)) break;
  1060. X     else nextchar(rfp);
  1061. X     }
  1062. X      c = toupper(ic);
  1063. X      if (c == 'I') ri.AddrType = AT_IP;
  1064. X      else if (c == 'N') ri.AddrType = AT_NOVELL;
  1065. X      else if (c == 'D') ri.AddrType = AT_DECNET;
  1066. X      else if (c == 'A') ri.AddrType = AT_ETHERTALK;
  1067. X      else ri.AddrType = AT_IGNORE;
  1068. X
  1069. X      getaddress(ri.FromAddr);
  1070. X      if (ic == EOF) break;
  1071. X      getaddress(ri.FromMask);
  1072. X      if (ic == EOF) break;
  1073. X      getaddress(ri.FromTally);
  1074. X      if (ic == EOF) break;
  1075. X      getaddress(ri.ToAddr);
  1076. X      if (ic == EOF) break;
  1077. X      getaddress(ri.ToMask);
  1078. X      if (ic == EOF) break;
  1079. X      getaddress(ri.ToTally);
  1080. X      if (ic == EOF) break;
  1081. X
  1082. X      ri.RuleNbr = ++rule_nbr;
  1083. X
  1084. X      if (list) {
  1085. X     printf("Rule %d:  %d,  %d,", ri.RuleNbr, ri.TreeNbr, ri.AddrType);
  1086. X     printaddress(stdout, ri.FromAddr);
  1087. X     printaddress(stdout, ri.FromMask);
  1088. X     printaddress(stdout, ri.FromTally);
  1089. X     printf("\n               ");
  1090. X     printaddress(stdout, ri.ToAddr);
  1091. X     printaddress(stdout, ri.ToMask);
  1092. X     printaddress(stdout, ri.ToTally);
  1093. X     printf("\n");
  1094. X     }
  1095. X
  1096. X      add_rule(ms,&ri);  /* Add rule to meter's rule table */
  1097. X      }
  1098. X   chk_info(ms,-1);  /* Restart with new rule table */
  1099. X   fclose(rfp);
  1100. X   }
  1101. END_OF_FILE
  1102.   if test 29675 -ne `wc -c <'netramet/src/manager/oldnm.c'`; then
  1103.     echo shar: \"'netramet/src/manager/oldnm.c'\" unpacked with wrong size!
  1104.   fi
  1105.   # end of 'netramet/src/manager/oldnm.c'
  1106. fi
  1107. if test -f 'netramet/src/snmplib/snmpapi.c' -a "${1}" != "-c" ; then 
  1108.   echo shar: Will not clobber existing file \"'netramet/src/snmplib/snmpapi.c'\"
  1109. else
  1110.   echo shar: Extracting \"'netramet/src/snmplib/snmpapi.c'\" \(28823 characters\)
  1111.   sed "s/^X//" >'netramet/src/snmplib/snmpapi.c' <<'END_OF_FILE'
  1112. X/***********************************************************
  1113. X    Copyright 1989 by Carnegie Mellon University
  1114. X
  1115. X                      All Rights Reserved
  1116. X
  1117. XPermission to use, copy, modify, and distribute this software and its 
  1118. Xdocumentation for any purpose and without fee is hereby granted, 
  1119. Xprovided that the above copyright notice appear in all copies and that
  1120. Xboth that copyright notice and this permission notice appear in 
  1121. Xsupporting documentation, and that the name of CMU not be
  1122. Xused in advertising or publicity pertaining to distribution of the
  1123. Xsoftware without specific, written prior permission.  
  1124. X
  1125. XCMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  1126. XALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  1127. XCMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  1128. XANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  1129. XWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  1130. XARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  1131. XSOFTWARE.
  1132. X******************************************************************/
  1133. X/*
  1134. X * snmp_api.c - API for access to snmp.
  1135. X */
  1136. X
  1137. X#include <stdio.h>
  1138. X#include <sys/types.h>
  1139. X#include <sys/param.h>
  1140. X#include <sys/time.h>
  1141. X#include <netinet/in.h>
  1142. X#include <sys/socket.h>
  1143. X#include <netdb.h>
  1144. X#include "ausnmp.h"
  1145. X#include "asn1.h"
  1146. X#include "snmp.h"
  1147. X#include "snmpimpl.h"
  1148. X#include "snmpapi.h"
  1149. X
  1150. X#define PACKET_LENGTH    4500
  1151. X
  1152. X#ifndef BSD4_3
  1153. X#define BSD4_2
  1154. X#endif
  1155. X
  1156. X#ifndef BSD4_3
  1157. X
  1158. Xtypedef long    fd_mask;
  1159. X#define NFDBITS    (sizeof(fd_mask) * NBBY)    /* bits per mask */
  1160. X
  1161. X#define    FD_SET(n, p)    ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
  1162. X#define    FD_CLR(n, p)    ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
  1163. X#define    FD_ISSET(n, p)    ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
  1164. X#define FD_ZERO(p)    bzero((char *)(p), sizeof(*(p)))
  1165. X#endif
  1166. X
  1167. Xoid default_enterprise[] = {1, 3, 6, 1, 4, 1, 3, 1, 1}; /* enterprises.cmu.systems.cmuSNMP */
  1168. X
  1169. X#define DEFAULT_COMMUNITY   "public"
  1170. X#define DEFAULT_RETRIES        4
  1171. X#define DEFAULT_TIMEOUT        1000000L
  1172. X#define DEFAULT_REMPORT        SNMP_PORT
  1173. X#define DEFAULT_ENTERPRISE  default_enterprise
  1174. X#define DEFAULT_TIME        0
  1175. X
  1176. X/*
  1177. X * Internal information about the state of the snmp session.
  1178. X */
  1179. Xstruct snmp_internal_session {
  1180. X    int        sd;        /* socket descriptor for this connection */
  1181. X    ipaddr  addr;    /* address of connected peer */
  1182. X    struct request_list *requests;/* Info about outstanding requests */
  1183. X};
  1184. X
  1185. X/*
  1186. X * A list of all the outstanding requests for a particular session.
  1187. X */
  1188. Xstruct request_list {
  1189. X    struct request_list *next_request;
  1190. X    u_long  request_id;    /* request id */
  1191. X    int        retries;    /* Number of retries */
  1192. X    u_long timeout;    /* length to wait for timeout */
  1193. X    struct timeval time; /* Time this request was made */
  1194. X    struct timeval expire;  /* time this request is due to expire */
  1195. X    struct snmp_pdu *pdu;   /* The pdu for this request (saved so it can be retransmitted */
  1196. X};
  1197. X
  1198. X/*
  1199. X * The list of active/open sessions.
  1200. X */
  1201. Xstruct session_list {
  1202. X    struct session_list *next;
  1203. X    struct snmp_session *session;
  1204. X    struct snmp_internal_session *internal;
  1205. X};
  1206. X
  1207. Xstruct session_list *Sessions = NULL;
  1208. X
  1209. Xu_long Reqid = 0;
  1210. Xint snmp_errno = 0;
  1211. X
  1212. Xchar *api_errors[4] = {
  1213. X    "Unknown session",
  1214. X    "Unknown host",
  1215. X    "Invalid local port",
  1216. X    "Unknown Error"
  1217. X};
  1218. X
  1219. Xstatic char *
  1220. Xapi_errstring(snmp_errnumber)
  1221. X    int    snmp_errnumber;
  1222. X{
  1223. X    if (snmp_errnumber <= SNMPERR_BAD_SESSION && snmp_errnumber >= SNMPERR_GENERR){
  1224. X    return api_errors[snmp_errnumber + 4];
  1225. X    } else {
  1226. X    return "Unknown Error";
  1227. X    }
  1228. X}
  1229. X
  1230. X
  1231. X/*
  1232. X * Gets initial request ID for all transactions.
  1233. X */
  1234. Xstatic
  1235. Xinit_snmp(){
  1236. X    struct timeval tv;
  1237. X
  1238. X    gettimeofday(&tv, (struct timezone *)0);
  1239. X    srandom(tv.tv_sec ^ tv.tv_usec);
  1240. X    Reqid = random();
  1241. X}
  1242. X
  1243. X/*
  1244. X * Sets up the session with the snmp_session information provided
  1245. X * by the user.  Then opens and binds the necessary UDP port.
  1246. X * A handle to the created session is returned (this is different than
  1247. X * the pointer passed to snmp_open()).  On any error, NULL is returned
  1248. X * and snmp_errno is set to the appropriate error code.
  1249. X */
  1250. Xstruct snmp_session *
  1251. Xsnmp_open(session)
  1252. X    struct snmp_session *session;
  1253. X{
  1254. X    struct session_list *slp;
  1255. X    struct snmp_internal_session *isp;
  1256. X    u_char *cp;
  1257. X    int sd;
  1258. X    u_long addr;
  1259. X    struct sockaddr_in    me;
  1260. X    struct hostent *hp;
  1261. X    struct servent *servp;
  1262. X
  1263. X
  1264. X    if (Reqid == 0)
  1265. X    init_snmp();
  1266. X
  1267. X    /* Copy session structure and link into list */
  1268. X    slp = (struct session_list *)malloc(sizeof(struct session_list));
  1269. X    slp->internal = isp = (struct snmp_internal_session *)malloc(sizeof(struct snmp_internal_session));
  1270. X    bzero((char *)isp, sizeof(struct snmp_internal_session));
  1271. X    slp->internal->sd = -1; /* mark it not set */
  1272. X    slp->session = (struct snmp_session *)malloc(sizeof(struct snmp_session));
  1273. X    bcopy((char *)session, (char *)slp->session, sizeof(struct snmp_session));
  1274. X    session = slp->session;
  1275. X    /* now link it in. */
  1276. X    slp->next = Sessions;
  1277. X    Sessions = slp;
  1278. X    /*
  1279. X     * session now points to the new structure that still contains pointers to
  1280. X     * data allocated elsewhere.  Some of this data is copied to space malloc'd
  1281. X     * here, and the pointer replaced with the new one.
  1282. X     */
  1283. X
  1284. X    if (session->peername != NULL){
  1285. X    cp = (u_char *)malloc((unsigned)strlen(session->peername) + 1);
  1286. X    strcpy((char *)cp, session->peername);
  1287. X    session->peername = (char *)cp;
  1288. X    }
  1289. X
  1290. X    /* Fill in defaults if necessary */
  1291. X    if (session->community_len != SNMP_DEFAULT_COMMUNITY_LEN){
  1292. X    cp = (u_char *)malloc((unsigned)session->community_len);
  1293. X    bcopy((char *)session->community, (char *)cp, session->community_len);
  1294. X    } else {
  1295. X    session->community_len = strlen(DEFAULT_COMMUNITY);
  1296. X    cp = (u_char *)malloc((unsigned)session->community_len);
  1297. X    bcopy((char *)DEFAULT_COMMUNITY, (char *)cp, session->community_len);
  1298. X    }
  1299. X    session->community = cp;    /* replace pointer with pointer to new data */
  1300. X
  1301. X    if (session->retries == SNMP_DEFAULT_RETRIES)
  1302. X    session->retries = DEFAULT_RETRIES;
  1303. X    if (session->timeout == SNMP_DEFAULT_TIMEOUT)
  1304. X    session->timeout = DEFAULT_TIMEOUT;
  1305. X    isp->requests = NULL;
  1306. X
  1307. X    /* Set up connections */
  1308. X    sd = socket(AF_INET, SOCK_DGRAM, 0);
  1309. X    if (sd < 0){
  1310. X    perror("socket");
  1311. X    snmp_errno = SNMPERR_GENERR;
  1312. X    if (!snmp_close(session)){
  1313. X        fprintf(stderr, "Couldn't abort session: %s. Exiting\n", api_errstring(snmp_errno));
  1314. X        exit(1);
  1315. X    }
  1316. X    return 0;
  1317. X    }
  1318. X    isp->sd = sd;
  1319. X    if (session->peername != SNMP_DEFAULT_PEERNAME){
  1320. X    if ((addr = inet_addr(session->peername)) != -1){
  1321. X        bcopy((char *)&addr, (char *)&isp->addr.sin_addr, sizeof(isp->addr.sin_addr));
  1322. X    } else {
  1323. X        hp = gethostbyname(session->peername);
  1324. X        if (hp == NULL){
  1325. X        fprintf(stderr, "unknown host: %s\n", session->peername);
  1326. X        snmp_errno = SNMPERR_BAD_ADDRESS;
  1327. X        if (!snmp_close(session)){
  1328. X            fprintf(stderr, "Couldn't abort session: %s. Exiting\n", api_errstring(snmp_errno));
  1329. X            exit(2);
  1330. X        }
  1331. X        return 0;
  1332. X        } else {
  1333. X        bcopy((char *)hp->h_addr, (char *)&isp->addr.sin_addr, hp->h_length);
  1334. X        }
  1335. X    }
  1336. X    isp->addr.sin_family = AF_INET;
  1337. X    if (session->remote_port == SNMP_DEFAULT_REMPORT){
  1338. X        servp = getservbyname("snmp", "udp");
  1339. X        if (servp != NULL){
  1340. X        isp->addr.sin_port = servp->s_port;
  1341. X        } else {
  1342. X        isp->addr.sin_port = htons(SNMP_PORT);
  1343. X        }
  1344. X    } else {
  1345. X        isp->addr.sin_port = htons(session->remote_port);
  1346. X    }
  1347. X    } else {
  1348. X    isp->addr.sin_addr.s_addr = SNMP_DEFAULT_ADDRESS;
  1349. X    }
  1350. X
  1351. X    me.sin_family = AF_INET;
  1352. X    me.sin_addr.s_addr = INADDR_ANY;
  1353. X    me.sin_port = htons(session->local_port);
  1354. X    if (bind(sd, (struct sockaddr *)&me, sizeof(me)) != 0){
  1355. X    perror("bind");
  1356. X    snmp_errno = SNMPERR_BAD_LOCPORT;
  1357. X    if (!snmp_close(session)){
  1358. X        fprintf(stderr, "Couldn't abort session: %s. Exiting\n", api_errstring(snmp_errno));
  1359. X        exit(3);
  1360. X    }
  1361. X    return 0;
  1362. X    }
  1363. X    return session;
  1364. X}
  1365. X
  1366. X
  1367. X/*
  1368. X * Free each element in the input request list.
  1369. X */
  1370. Xstatic
  1371. Xfree_request_list(rp)
  1372. X    struct request_list *rp;
  1373. X{
  1374. X    struct request_list *orp;
  1375. X
  1376. X    while(rp){
  1377. X    orp = rp;
  1378. X    rp = rp->next_request;
  1379. X    if (orp->pdu != NULL)
  1380. X        snmp_free_pdu(orp->pdu);
  1381. X    free((char *)orp);
  1382. X    }
  1383. X}
  1384. X
  1385. X/*
  1386. X * Close the input session.  Frees all data allocated for the session,
  1387. X * dequeues any pending requests, and closes any sockets allocated for
  1388. X * the session.  Returns 0 on error, 1 otherwise.
  1389. X */
  1390. Xint 
  1391. Xsnmp_close(session)
  1392. X    struct snmp_session *session;
  1393. X{
  1394. X    struct session_list *slp = NULL, *oslp = NULL;
  1395. X
  1396. X    if (Sessions->session == session){    /* If first entry */
  1397. X    slp = Sessions;
  1398. X    Sessions = slp->next;
  1399. X    } else {
  1400. X    for(slp = Sessions; slp; slp = slp->next){
  1401. X        if (slp->session == session){
  1402. X        if (oslp)   /* if we found entry that points here */
  1403. X            oslp->next = slp->next;    /* link around this entry */
  1404. X        break;
  1405. X        }
  1406. X        oslp = slp;
  1407. X    }
  1408. X    }
  1409. X    /* If we found the session, free all data associated with it */
  1410. X    if (slp){
  1411. X    if (slp->session->community != NULL)
  1412. X        free((char *)slp->session->community);
  1413. X    if(slp->session->peername != NULL)
  1414. X        free((char *)slp->session->peername);
  1415. X    free((char *)slp->session);
  1416. X    if (slp->internal->sd != -1)
  1417. X        close(slp->internal->sd);
  1418. X    free_request_list(slp->internal->requests);
  1419. X    free((char *)slp->internal);
  1420. X    free((char *)slp);
  1421. X    } else {
  1422. X    snmp_errno = SNMPERR_BAD_SESSION;
  1423. X    return 0;
  1424. X    }
  1425. X    return 1;
  1426. X}
  1427. X
  1428. X/*
  1429. X * Takes a session and a pdu and serializes the ASN PDU into the area
  1430. X * pointed to by packet.  out_length is the size of the data area available.
  1431. X * Returns the length of the completed packet in out_length.  If any errors
  1432. X * occur, -1 is returned.  If all goes well, 0 is returned.
  1433. X */
  1434. Xstatic int
  1435. Xsnmp_build(session, pdu, packet, out_length)
  1436. X    struct snmp_session    *session;
  1437. X    struct snmp_pdu    *pdu;
  1438. X    register u_char    *packet;
  1439. X    int            *out_length;
  1440. X{
  1441. X    u_char  buf[PACKET_LENGTH];
  1442. X    register u_char  *cp;
  1443. X    struct variable_list *vp;
  1444. X    int        length;
  1445. X    long    zero = 0;
  1446. X    int        totallength;
  1447. X
  1448. X    length = *out_length;
  1449. X    cp = packet;
  1450. X    for(vp = pdu->variables; vp; vp = vp->next_variable){
  1451. X    cp = snmp_build_var_op(cp, vp->name, &vp->name_length, vp->type, vp->val_len, (u_char *)vp->val.string, &length);
  1452. X    if (cp == NULL)
  1453. X        return -1;
  1454. X    }
  1455. X    totallength = cp - packet;
  1456. X
  1457. X    length = PACKET_LENGTH;
  1458. X    cp = asn_build_header(buf, &length, (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR), totallength);
  1459. X    if (cp == NULL)
  1460. X    return -1;
  1461. X    bcopy((char *)packet, (char *)cp, totallength);
  1462. X    totallength += cp - buf;
  1463. X
  1464. X    length = *out_length;
  1465. X    if (pdu->command != TRP_REQ_MSG){
  1466. X    /* request id */
  1467. X    cp = asn_build_int(packet, &length,
  1468. X        (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
  1469. X        (long *)&pdu->reqid, sizeof(pdu->reqid));
  1470. X    if (cp == NULL)
  1471. X        return -1;
  1472. X    /* error status */
  1473. X    cp = asn_build_int(cp, &length,
  1474. X        (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
  1475. X        (long *)&pdu->errstat, sizeof(pdu->errstat));
  1476. X    if (cp == NULL)
  1477. X        return -1;
  1478. X    /* error index */
  1479. X    cp = asn_build_int(cp, &length,
  1480. X        (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
  1481. X        (long *)&pdu->errindex, sizeof(pdu->errindex));
  1482. X    if (cp == NULL)
  1483. X        return -1;
  1484. X    } else {    /* this is a trap message */
  1485. X    /* enterprise */
  1486. X    cp = asn_build_objid(packet, &length,
  1487. X        (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OBJECT_ID),
  1488. X        (oid *)pdu->enterprise, pdu->enterprise_length);
  1489. X    if (cp == NULL)
  1490. X        return -1;
  1491. X    /* agent-addr */
  1492. X    cp = asn_build_string(cp, &length,
  1493. X        (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OCTET_STR),
  1494. X        (u_char *)&pdu->agent_addr.sin_addr.s_addr, sizeof(pdu->agent_addr.sin_addr.s_addr));
  1495. X    if (cp == NULL)
  1496. X        return -1;
  1497. X    /* generic trap */
  1498. X    cp = asn_build_int(cp, &length,
  1499. X        (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
  1500. X        (long *)&pdu->trap_type, sizeof(pdu->trap_type));
  1501. X    if (cp == NULL)
  1502. X        return -1;
  1503. X    /* specific trap */
  1504. X    cp = asn_build_int(cp, &length,
  1505. X        (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
  1506. X        (long *)&pdu->specific_type, sizeof(pdu->specific_type));
  1507. X    if (cp == NULL)
  1508. X        return -1;
  1509. X    /* timestamp  */
  1510. X    cp = asn_build_int(cp, &length,
  1511. X        (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
  1512. X        (long *)&pdu->time, sizeof(pdu->time));
  1513. X    if (cp == NULL)
  1514. X        return -1;
  1515. X    }
  1516. X    if (length < totallength)
  1517. X    return -1;
  1518. X    bcopy((char *)buf, (char *)cp, totallength);
  1519. X    totallength += cp - packet;
  1520. X
  1521. X    length = PACKET_LENGTH;
  1522. X    cp = asn_build_header(buf, &length, (u_char)pdu->command, totallength);
  1523. X    if (cp == NULL)
  1524. X    return -1;
  1525. X    if (length < totallength)
  1526. X    return -1;
  1527. X    bcopy((char *)packet, (char *)cp, totallength);
  1528. X    totallength += cp - buf;
  1529. X
  1530. X    length = *out_length;
  1531. X    cp = snmp_auth_build(packet, &length, session->community, &session->community_len, &zero, totallength);
  1532. X    if (cp == NULL)
  1533. X    return -1;
  1534. X    if ((*out_length - (cp - packet)) < totallength)
  1535. X    return -1;
  1536. X    bcopy((char *)buf, (char *)cp, totallength);
  1537. X    totallength += cp - packet;
  1538. X    *out_length = totallength;
  1539. X    return 0;
  1540. X}
  1541. X
  1542. X/*
  1543. X * Parses the packet recieved on the input session, and places the data into
  1544. X * the input pdu.  length is the length of the input packet.  If any errors
  1545. X * are encountered, -1 is returned.  Otherwise, a 0 is returned.
  1546. X */
  1547. Xstatic int
  1548. Xsnmp_parse(session, pdu, data, length)
  1549. X    struct snmp_session *session;
  1550. X    struct snmp_pdu *pdu;
  1551. X    u_char  *data;
  1552. X    int        length;
  1553. X{
  1554. X    u_char  msg_type;
  1555. X    u_char  type;
  1556. X    u_char  *var_val;
  1557. X    long    version;
  1558. X    int        len, four;
  1559. X    u_char community[128];
  1560. X    int community_length = 128;
  1561. X    struct variable_list *vp;
  1562. X    oid        objid[MAX_NAME_LEN], *op;
  1563. X
  1564. X    /* authenticates message and returns length if valid */
  1565. X    data = snmp_auth_parse(data, &length, community, &community_length, &version);
  1566. X    if (data == NULL)
  1567. X    return -1;
  1568. X    if (version != SNMP_VERSION_1){
  1569. X    fprintf(stderr, "Wrong version: %d\n", version);
  1570. X    fprintf(stderr, "Continuing anyway\n");
  1571. X    }
  1572. X    if (session->authenticator){
  1573. X    data = session->authenticator(data, &length, community, community_length);
  1574. X    if (data == NULL)
  1575. X        return 0;
  1576. X    }
  1577. X    data = asn_parse_header(data, &length, &msg_type);
  1578. X    if (data == NULL)
  1579. X    return -1;
  1580. X    pdu->command = msg_type;
  1581. X    if (pdu->command != TRP_REQ_MSG){
  1582. X    data = asn_parse_int(data, &length, &type, (long *)&pdu->reqid, sizeof(pdu->reqid));
  1583. X    if (data == NULL)
  1584. X        return -1;
  1585. X    data = asn_parse_int(data, &length, &type, (long *)&pdu->errstat, sizeof(pdu->errstat));
  1586. X    if (data == NULL)
  1587. X        return -1;
  1588. X    data = asn_parse_int(data, &length, &type, (long *)&pdu->errindex, sizeof(pdu->errindex));
  1589. X    if (data == NULL)
  1590. X        return -1;
  1591. X    } else {
  1592. X    pdu->enterprise_length = MAX_NAME_LEN;
  1593. X    data = asn_parse_objid(data, &length, &type, objid, &pdu->enterprise_length);
  1594. X    if (data == NULL)
  1595. X        return -1;
  1596. X    pdu->enterprise = (oid *)malloc(pdu->enterprise_length * sizeof(oid));
  1597. X    bcopy((char *)objid, (char *)pdu->enterprise, pdu->enterprise_length * sizeof(oid));
  1598. X
  1599. X    four = 4;
  1600. X    data = asn_parse_string(data, &length, &type, (u_char *)&pdu->agent_addr.sin_addr.s_addr, &four);
  1601. X    if (data == NULL)
  1602. X        return -1;
  1603. X    data = asn_parse_int(data, &length, &type, (long *)&pdu->trap_type, sizeof(pdu->trap_type));
  1604. X    if (data == NULL)
  1605. X        return -1;
  1606. X    data = asn_parse_int(data, &length, &type, (long *)&pdu->specific_type, sizeof(pdu->specific_type));
  1607. X    if (data == NULL)
  1608. X        return -1;
  1609. X    data = asn_parse_int(data, &length, &type, (long *)&pdu->time, sizeof(pdu->time));
  1610. X    if (data == NULL)
  1611. X        return -1;
  1612. X    }
  1613. X    data = asn_parse_header(data, &length, &type);
  1614. X    if (data == NULL)
  1615. X    return -1;
  1616. X    if (type != (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR))
  1617. X    return -1;
  1618. X    while((int)length > 0){
  1619. X    if (pdu->variables == NULL){
  1620. X        pdu->variables = vp = (struct variable_list *)malloc(sizeof(struct variable_list));
  1621. X    } else {
  1622. X        vp->next_variable = (struct variable_list *)malloc(sizeof(struct variable_list));
  1623. X        vp = vp->next_variable;
  1624. X    }
  1625. X    vp->next_variable = NULL;
  1626. X    vp->val.string = NULL;
  1627. X    vp->name = NULL;
  1628. X    vp->name_length = MAX_NAME_LEN;
  1629. X    data = snmp_parse_var_op(data, objid, &vp->name_length, &vp->type, &vp->val_len, &var_val, (int *)&length);
  1630. X    if (data == NULL)
  1631. X        return -1;
  1632. X    op = (oid *)malloc((unsigned)vp->name_length * sizeof(oid));
  1633. X    bcopy((char *)objid, (char *)op, vp->name_length * sizeof(oid));
  1634. X    vp->name = op;
  1635. X
  1636. X    len = PACKET_LENGTH;
  1637. X    switch((short)vp->type){
  1638. X        case ASN_INTEGER:
  1639. X        case COUNTER:
  1640. X        case GAUGE:
  1641. X        case TIMETICKS:
  1642. X        vp->val.integer = (long *)malloc(sizeof(long));
  1643. X        vp->val_len = sizeof(long);
  1644. X        asn_parse_int(var_val, &len, &vp->type, (long *)vp->val.integer, sizeof(vp->val.integer));
  1645. X        break;
  1646. X        case ASN_OCTET_STR:
  1647. X        case IPADDRESS:
  1648. X        case OPAQUE:
  1649. X        vp->val.string = (u_char *)malloc((unsigned)vp->val_len);
  1650. X        asn_parse_string(var_val, &len, &vp->type, vp->val.string, &vp->val_len);
  1651. X        break;
  1652. X        case ASN_OBJECT_ID:
  1653. X        vp->val_len = MAX_NAME_LEN;
  1654. X        asn_parse_objid(var_val, &len, &vp->type, objid, &vp->val_len);
  1655. X        vp->val_len *= sizeof(oid);
  1656. X        vp->val.objid = (oid *)malloc((unsigned)vp->val_len);
  1657. X        bcopy((char *)objid, (char *)vp->val.objid, vp->val_len);
  1658. X        break;
  1659. X        case ASN_NULL:
  1660. X        break;
  1661. X        default:
  1662. X        fprintf(stderr, "bad type returned (%x)\n", vp->type);
  1663. X        break;
  1664. X    }
  1665. X    }
  1666. X    return 0;
  1667. X}
  1668. X
  1669. X/*
  1670. X * Sends the input pdu on the session after calling snmp_build to create
  1671. X * a serialized packet.  If necessary, set some of the pdu data from the
  1672. X * session defaults.  Add a request corresponding to this pdu to the list
  1673. X * of outstanding requests on this session, then send the pdu.
  1674. X * Returns the request id of the generated packet if applicable, otherwise 1.
  1675. X * On any error, 0 is returned.
  1676. X * The pdu is freed by snmp_send() unless a failure occured.
  1677. X */
  1678. Xint
  1679. Xsnmp_send(session, pdu)
  1680. X    struct snmp_session *session;
  1681. X    struct snmp_pdu    *pdu;
  1682. X{
  1683. X    struct session_list *slp;
  1684. X    struct snmp_internal_session *isp = NULL;
  1685. X    u_char  packet[PACKET_LENGTH];
  1686. X    int length = PACKET_LENGTH;
  1687. X    struct request_list *rp;
  1688. X    struct timeval tv;
  1689. X
  1690. X    for(slp = Sessions; slp; slp = slp->next){
  1691. X    if (slp->session == session){
  1692. X        isp = slp->internal;
  1693. X        break;
  1694. X    }
  1695. X    }
  1696. X    if (isp == NULL){
  1697. X    snmp_errno = SNMPERR_BAD_SESSION;
  1698. X    return 0;
  1699. X    }
  1700. X    if (pdu->command == GET_REQ_MSG || pdu->command == GETNEXT_REQ_MSG
  1701. X    || pdu->command == GET_RSP_MSG || pdu->command == SET_REQ_MSG){
  1702. X    if (pdu->reqid == SNMP_DEFAULT_REQID)
  1703. X        pdu->reqid = ++Reqid;
  1704. X    if (pdu->errstat == SNMP_DEFAULT_ERRSTAT)
  1705. X        pdu->errstat = 0;
  1706. X    if (pdu->errindex == SNMP_DEFAULT_ERRINDEX)
  1707. X        pdu->errindex = 0;
  1708. X    } else {
  1709. X    /* fill in trap defaults */
  1710. X    pdu->reqid = 1;    /* give a bogus non-error reqid for traps */
  1711. X    if (pdu->enterprise_length == SNMP_DEFAULT_ENTERPRISE_LENGTH){
  1712. X        pdu->enterprise = (oid *)malloc(sizeof(DEFAULT_ENTERPRISE));
  1713. X        bcopy((char *)DEFAULT_ENTERPRISE, (char *)pdu->enterprise, sizeof(DEFAULT_ENTERPRISE));
  1714. X        pdu->enterprise_length = sizeof(DEFAULT_ENTERPRISE)/sizeof(oid);
  1715. X    }
  1716. X    if (pdu->time == SNMP_DEFAULT_TIME)
  1717. X        pdu->time = DEFAULT_TIME;
  1718. X    }
  1719. X    if (pdu->address.sin_addr.s_addr == SNMP_DEFAULT_ADDRESS){
  1720. X    if (isp->addr.sin_addr.s_addr != SNMP_DEFAULT_ADDRESS){
  1721. X        bcopy((char *)&isp->addr, (char *)&pdu->address, sizeof(pdu->address));
  1722. X    } else {
  1723. X        fprintf(stderr, "No remote IP address specified\n");
  1724. X        snmp_errno = SNMPERR_BAD_ADDRESS;
  1725. X        return 0;
  1726. X    }
  1727. X    }
  1728. X    
  1729. X
  1730. X    if (snmp_build(session, pdu, packet, &length) < 0){
  1731. X    fprintf(stderr, "Error building packet\n");
  1732. X    snmp_errno = SNMPERR_GENERR;
  1733. X    return 0;
  1734. X    }
  1735. X    if (snmp_dump_packet){
  1736. X    int count;
  1737. X
  1738. X    for(count = 0; count < length; count++){
  1739. X        printf("%02X ", packet[count]);
  1740. X        if ((count % 16) == 15)
  1741. X        printf("\n");
  1742. X    }
  1743. X    printf("\n\n");
  1744. X    }
  1745. X
  1746. X    gettimeofday(&tv, (struct timezone *)0);
  1747. X    if (sendto(isp->sd, (char *)packet, length, 0, (struct sockaddr *)&pdu->address, sizeof(pdu->address)) < 0){
  1748. X    perror("sendto");
  1749. X    snmp_errno = SNMPERR_GENERR;
  1750. X    return 0;
  1751. X    }
  1752. X    if (pdu->command == GET_REQ_MSG || pdu->command == GETNEXT_REQ_MSG || pdu->command == SET_REQ_MSG){
  1753. X    /* set up to expect a response */
  1754. X    rp = (struct request_list *)malloc(sizeof(struct request_list));
  1755. X    rp->next_request = isp->requests;
  1756. X    isp->requests = rp;
  1757. X    rp->pdu = pdu;
  1758. X    rp->request_id = pdu->reqid;
  1759. X
  1760. X    rp->retries = 1;
  1761. X    rp->timeout = session->timeout;
  1762. X    rp->time = tv;
  1763. X    tv.tv_usec += rp->timeout;
  1764. X    tv.tv_sec += tv.tv_usec / 1000000L;
  1765. X    tv.tv_usec %= 1000000L;
  1766. X    rp->expire = tv;
  1767. X    }
  1768. X    return pdu->reqid;
  1769. X}
  1770. X
  1771. X/*
  1772. X * Frees the pdu and any malloc'd data associated with it.
  1773. X */
  1774. Xvoid
  1775. Xsnmp_free_pdu(pdu)
  1776. X    struct snmp_pdu *pdu;
  1777. X{
  1778. X    struct variable_list *vp, *ovp;
  1779. X
  1780. X    vp = pdu->variables;
  1781. X    while(vp){
  1782. X    if (vp->name)
  1783. X        free((char *)vp->name);
  1784. X    if (vp->val.string)
  1785. X        free((char *)vp->val.string);
  1786. X    ovp = vp;
  1787. X    vp = vp->next_variable;
  1788. X    free((char *)ovp);
  1789. X    }
  1790. X    if (pdu->enterprise)
  1791. X    free((char *)pdu->enterprise);
  1792. X    free((char *)pdu);
  1793. X}
  1794. X
  1795. X
  1796. X/*
  1797. X * Checks to see if any of the fd's set in the fdset belong to
  1798. X * snmp.  Each socket with it's fd set has a packet read from it
  1799. X * and snmp_parse is called on the packet received.  The resulting pdu
  1800. X * is passed to the callback routine for that session.  If the callback
  1801. X * routine returns successfully, the pdu and it's request are deleted.
  1802. X */
  1803. Xvoid
  1804. Xsnmp_read(fdset)
  1805. X    fd_set  *fdset;
  1806. X{
  1807. X    struct session_list *slp;
  1808. X    struct snmp_session *sp;
  1809. X    struct snmp_internal_session *isp;
  1810. X    u_char packet[PACKET_LENGTH];
  1811. X    struct sockaddr_in    from;
  1812. X    int length, fromlength;
  1813. X    struct snmp_pdu *pdu;
  1814. X    struct request_list *rp, *orp;
  1815. X
  1816. X    for(slp = Sessions; slp; slp = slp->next){
  1817. X    if (FD_ISSET(slp->internal->sd, fdset)){
  1818. X        sp = slp->session;
  1819. X        isp = slp->internal;
  1820. X        fromlength = sizeof from;
  1821. X        length = recvfrom(isp->sd, (char *)packet, PACKET_LENGTH, 0, (struct sockaddr *)&from, &fromlength);
  1822. X        if (length == -1)
  1823. X        perror("recvfrom");
  1824. X        if (snmp_dump_packet){
  1825. X        int count;
  1826. X
  1827. X        printf("recieved %d bytes from %s:\n", length, inet_ntoa(from.sin_addr));
  1828. X        for(count = 0; count < length; count++){
  1829. X            printf("%02X ", packet[count]);
  1830. X            if ((count % 16) == 15)
  1831. X            printf("\n");
  1832. X        }
  1833. X        printf("\n\n");
  1834. X        }
  1835. X
  1836. X        pdu = (struct snmp_pdu *)malloc(sizeof(struct snmp_pdu));
  1837. X        pdu->address = from;
  1838. X        pdu->reqid = 0;
  1839. X        pdu->variables = NULL;
  1840. X        pdu->enterprise = NULL;
  1841. X        pdu->enterprise_length = 0;
  1842. X        if (snmp_parse(sp, pdu, packet, length) != SNMP_ERR_NOERROR){
  1843. X        fprintf(stderr, "Mangled packet\n");
  1844. X        snmp_free_pdu(pdu);
  1845. X        return;
  1846. X        }
  1847. X
  1848. X        if (pdu->command == GET_RSP_MSG){
  1849. X        for(rp = isp->requests; rp; rp = rp->next_request){
  1850. X            if (rp->request_id == pdu->reqid){
  1851. X            if (sp->callback(RECEIVED_MESSAGE, sp, pdu->reqid, pdu, sp->callback_magic) == 1){
  1852. X                /* successful, so delete request */
  1853. X                orp = rp;
  1854. X                if (isp->requests == orp){
  1855. X                /* first in list */
  1856. X                isp->requests = orp->next_request;
  1857. X                } else {
  1858. X                for(rp = isp->requests; rp; rp = rp->next_request){
  1859. X                    if (rp->next_request == orp){
  1860. X                    rp->next_request = orp->next_request;    /* link around it */
  1861. X                    break;
  1862. X                    }
  1863. X                }
  1864. X                }
  1865. X                snmp_free_pdu(orp->pdu);
  1866. X                free((char *)orp);
  1867. X                break;  /* there shouldn't be any more request with the same reqid */
  1868. X            }
  1869. X            }
  1870. X        }
  1871. X        } else if (pdu->command == GET_REQ_MSG || pdu->command == GETNEXT_REQ_MSG
  1872. X            || pdu->command == TRP_REQ_MSG || pdu->command == SET_REQ_MSG){
  1873. X        sp->callback(RECEIVED_MESSAGE, sp, pdu->reqid, pdu, sp->callback_magic);
  1874. X        }
  1875. X        snmp_free_pdu(pdu);
  1876. X    }
  1877. X    }
  1878. X}
  1879. X
  1880. X/*
  1881. X * Returns info about what snmp requires from a select statement.
  1882. X * numfds is the number of fds in the list that are significant.
  1883. X * All file descriptors opened for SNMP are OR'd into the fdset.
  1884. X * If activity occurs on any of these file descriptors, snmp_read
  1885. X * should be called with that file descriptor set
  1886. X *
  1887. X * The timeout is the latest time that SNMP can wait for a timeout.  The
  1888. X * select should be done with the minimum time between timeout and any other
  1889. X * timeouts necessary.  This should be checked upon each invocation of select.
  1890. X * If a timeout is received, snmp_timeout should be called to check if the
  1891. X * timeout was for SNMP.  (snmp_timeout is idempotent)
  1892. X *
  1893. X * Block is 1 if the select is requested to block indefinitely, rather than time out.
  1894. X * If block is input as 1, the timeout value will be treated as undefined, but it must
  1895. X * be available for setting in snmp_select_info.  On return, if block is true, the value
  1896. X * of timeout will be undefined.
  1897. X *
  1898. X * snmp_select_info returns the number of open sockets.  (i.e. The number of sessions open)
  1899. X */
  1900. Xint
  1901. Xsnmp_select_info(numfds, fdset, timeout, block)
  1902. X    int        *numfds;
  1903. X    fd_set  *fdset;
  1904. X    struct timeval *timeout;
  1905. X    int        *block; /* should the select block until input arrives (i.e. no input) */
  1906. X{
  1907. X    struct session_list *slp;
  1908. X    struct snmp_internal_session *isp;
  1909. X    struct request_list *rp;
  1910. X    struct timeval now, earliest;
  1911. X    int active = 0, requests = 0;
  1912. X
  1913. X    timerclear(&earliest);
  1914. X    /*
  1915. X     * For each request outstanding, add it's socket to the fdset,
  1916. X     * and if it is the earliest timeout to expire, mark it as lowest.
  1917. X     */
  1918. X    for(slp = Sessions; slp; slp = slp->next){
  1919. X    active++;
  1920. X    isp = slp->internal;
  1921. X    if ((isp->sd + 1) > *numfds)
  1922. X        *numfds = (isp->sd + 1);
  1923. X    FD_SET(isp->sd, fdset);
  1924. X    if (isp->requests){
  1925. X        /* found another session with outstanding requests */
  1926. X        requests++;
  1927. X        for(rp = isp->requests; rp; rp = rp->next_request){
  1928. X        if (!timerisset(&earliest) || timercmp(&rp->expire, &earliest, <))
  1929. X            earliest = rp->expire;
  1930. X        }
  1931. X    }
  1932. X    }
  1933. X    if (requests == 0)    /* if none are active, skip arithmetic */
  1934. X    return active;
  1935. X
  1936. X    /*
  1937. X     * Now find out how much time until the earliest timeout.  This
  1938. X     * transforms earliest from an absolute time into a delta time, the
  1939. X     * time left until the select should timeout.
  1940. X     */
  1941. X    gettimeofday(&now, (struct timezone *)0);
  1942. X    earliest.tv_sec--;    /* adjust time to make arithmetic easier */
  1943. X    earliest.tv_usec += 1000000L;
  1944. X    earliest.tv_sec -= now.tv_sec;
  1945. X    earliest.tv_usec -= now.tv_usec;
  1946. X    while (earliest.tv_usec >= 1000000L){
  1947. X    earliest.tv_usec -= 1000000L;
  1948. X    earliest.tv_sec += 1;
  1949. X    }
  1950. X    if (earliest.tv_sec < 0){
  1951. X    earliest.tv_sec = 0;
  1952. X    earliest.tv_usec = 0;
  1953. X    }
  1954. X
  1955. X    /* if it was blocking before or our delta time is less, reset timeout */
  1956. X    if (*block == 1 || timercmp(&earliest, timeout, <)){
  1957. X    *timeout = earliest;
  1958. X    *block = 0;
  1959. X    }
  1960. X    return active;
  1961. X}
  1962. X
  1963. X/*
  1964. X * snmp_timeout should be called whenever the timeout from snmp_select_info expires,
  1965. X * but it is idempotent, so snmp_timeout can be polled (probably a cpu expensive
  1966. X * proposition).  snmp_timeout checks to see if any of the sessions have an
  1967. X * outstanding request that has timed out.  If it finds one (or more), and that
  1968. X * pdu has more retries available, a new packet is formed from the pdu and is
  1969. X * resent.  If there are no more retries available, the callback for the session
  1970. X * is used to alert the user of the timeout.
  1971. X */
  1972. Xvoid
  1973. Xsnmp_timeout(){
  1974. X    struct session_list *slp;
  1975. X    struct snmp_session *sp;
  1976. X    struct snmp_internal_session *isp;
  1977. X    struct request_list *rp, *orp, *freeme = NULL;
  1978. X    struct timeval now;
  1979. X
  1980. X    gettimeofday(&now, (struct timezone *)0);
  1981. X    /*
  1982. X     * For each request outstanding, check to see if it has expired.
  1983. X     */
  1984. X    for(slp = Sessions; slp; slp = slp->next){
  1985. X    sp = slp->session;
  1986. X    isp = slp->internal;
  1987. X    orp = NULL;
  1988. X    for(rp = isp->requests; rp; rp = rp->next_request){
  1989. X        if (freeme != NULL){    /* frees rp's after the for loop goes on to the next_request */
  1990. X        free((char *)freeme);
  1991. X        freeme = NULL;
  1992. X        }
  1993. X        if (timercmp(&rp->expire, &now, <)){
  1994. X        /* this timer has expired */
  1995. X        if (rp->retries >= sp->retries){
  1996. X            /* No more chances, delete this entry */
  1997. X            sp->callback(TIMED_OUT, sp, rp->pdu->reqid, rp->pdu, sp->callback_magic);
  1998. X            if (orp == NULL){
  1999. X            isp->requests = rp->next_request;
  2000. X            } else {
  2001. X            orp->next_request = rp->next_request;
  2002. X            }
  2003. X            snmp_free_pdu(rp->pdu);
  2004. X            freeme = rp;
  2005. X            continue;    /* don't update orp below */
  2006. X        } else {
  2007. X            u_char  packet[PACKET_LENGTH];
  2008. X            int length = PACKET_LENGTH;
  2009. X            struct timeval tv;
  2010. X
  2011. X            /* retransmit this pdu */
  2012. X            rp->retries++;
  2013. X            rp->timeout <<= 1;
  2014. X            if (snmp_build(sp, rp->pdu, packet, &length) < 0){
  2015. X            fprintf(stderr, "Error building packet\n");
  2016. X            }
  2017. X            if (snmp_dump_packet){
  2018. X            int count;
  2019. X
  2020. X            for(count = 0; count < length; count++){
  2021. X                printf("%02X ", packet[count]);
  2022. X                if ((count % 16) == 15)
  2023. X                printf("\n");
  2024. X            }
  2025. X            printf("\n\n");
  2026. X            }
  2027. X            gettimeofday(&tv, (struct timezone *)0);
  2028. X            if (sendto(isp->sd, (char *)packet, length, 0, (struct sockaddr *)&rp->pdu->address, sizeof(rp->pdu->address)) < 0){
  2029. X            perror("sendto");
  2030. X            }
  2031. X            rp->time = tv;
  2032. X            tv.tv_usec += rp->timeout;
  2033. X            tv.tv_sec += tv.tv_usec / 1000000L;
  2034. X            tv.tv_usec %= 1000000L;
  2035. X            rp->expire = tv;
  2036. X        }
  2037. X        }
  2038. X        orp = rp;
  2039. X    }
  2040. X    if (freeme != NULL){
  2041. X        free((char *)freeme);
  2042. X        freeme = NULL;
  2043. X    }
  2044. X    }
  2045. X}
  2046. END_OF_FILE
  2047.   if test 28823 -ne `wc -c <'netramet/src/snmplib/snmpapi.c'`; then
  2048.     echo shar: \"'netramet/src/snmplib/snmpapi.c'\" unpacked with wrong size!
  2049.   fi
  2050.   # end of 'netramet/src/snmplib/snmpapi.c'
  2051. fi
  2052. if test -f 'netramet/src/snmplib/~snmp_vars.h.kip' -a "${1}" != "-c" ; then 
  2053.   echo shar: Will not clobber existing file \"'netramet/src/snmplib/~snmp_vars.h.kip'\"
  2054. else
  2055.   echo shar: Extracting \"'netramet/src/snmplib/~snmp_vars.h.kip'\" \(1789 characters\)
  2056.   sed "s/^X//" >'netramet/src/snmplib/~snmp_vars.h.kip' <<'END_OF_FILE'
  2057. X/*
  2058. X * Definitions for SNMP (RFC 1067) agent variable finder.
  2059. X *
  2060. X *
  2061. X */
  2062. X/***********************************************************
  2063. X    Copyright 1988, 1989 by Carnegie Mellon University
  2064. X
  2065. X                      All Rights Reserved
  2066. X
  2067. XPermission to use, copy, modify, and distribute this software and its 
  2068. Xdocumentation for any purpose and without fee is hereby granted, 
  2069. Xprovided that the above copyright notice appear in all copies and that
  2070. Xboth that copyright notice and this permission notice appear in 
  2071. Xsupporting documentation, and that the name of CMU not be
  2072. Xused in advertising or publicity pertaining to distribution of the
  2073. Xsoftware without specific, written prior permission.  
  2074. X
  2075. XCMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  2076. XALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  2077. XCMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  2078. XANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  2079. XWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  2080. XARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  2081. XSOFTWARE.
  2082. X******************************************************************/
  2083. X
  2084. X#define        MAX_INTERFACES    2
  2085. Xextern    struct mib_ifEntry  mib_ifEntry[MAX_INTERFACES];
  2086. Xextern    struct mib_ip        mib_ip;
  2087. X#define        ROUTE_ENTRIES    2
  2088. Xextern    struct mib_udp        mib_udp;
  2089. Xextern    long    mib_icmpInMsgs;
  2090. Xextern    long    mib_icmpOutMsgs;
  2091. Xextern    long    mib_icmpInErrors;    /* not checked in KIP */
  2092. Xextern    long    mib_icmpOutErrors;    /* not checked in KIP */
  2093. Xextern    long    mib_icmpInCount[];
  2094. Xextern    long    mib_icmpOutCount[];
  2095. X
  2096. Xu_char    *var_system();
  2097. Xu_char    *var_ifEntry();
  2098. Xu_char    *var_atEntry();
  2099. Xu_char    *var_ip();
  2100. Xu_char    *var_ipAddrEntry();
  2101. Xu_char    *var_ipRouteEntry();
  2102. Xu_char    *var_icmp();
  2103. Xu_char    *var_udp();
  2104. Xu_char    *getStatPtr();
  2105. X
  2106. X
  2107. END_OF_FILE
  2108.   if test 1789 -ne `wc -c <'netramet/src/snmplib/~snmp_vars.h.kip'`; then
  2109.     echo shar: \"'netramet/src/snmplib/~snmp_vars.h.kip'\" unpacked with wrong size!
  2110.   fi
  2111.   # end of 'netramet/src/snmplib/~snmp_vars.h.kip'
  2112. fi
  2113. echo shar: End of archive 19 \(of 25\).
  2114. cp /dev/null ark19isdone
  2115. MISSING=""
  2116. 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
  2117.     if test ! -f ark${I}isdone ; then
  2118.     MISSING="${MISSING} ${I}"
  2119.     fi
  2120. done
  2121. if test "${MISSING}" = "" ; then
  2122.     echo You have unpacked all 25 archives.
  2123.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2124. else
  2125.     echo You still must unpack the following archives:
  2126.     echo "        " ${MISSING}
  2127. fi
  2128. exit 0
  2129. exit 0 # Just in case...
  2130.