home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume40 / nocol / part16 < prev    next >
Encoding:
Text File  |  1993-11-23  |  75.5 KB  |  2,727 lines

  1. Newsgroups: comp.sources.misc
  2. From: vikas@jvnc.net (Vikas Aggarwal)
  3. Subject: v40i146:  nocol - Network Monitoring System, Part16/26
  4. Message-ID: <1993Nov23.212715.21794@sparky.sterling.com>
  5. X-Md4-Signature: 6ef5a56089ff8473e6a93cd3fa2036fb
  6. Sender: kent@sparky.sterling.com (Kent Landfield)
  7. Organization: Sterling Software
  8. Date: Tue, 23 Nov 1993 21:27:15 GMT
  9. Approved: kent@sparky.sterling.com
  10.  
  11. Submitted-by: vikas@jvnc.net (Vikas Aggarwal)
  12. Posting-number: Volume 40, Issue 146
  13. Archive-name: nocol/part16
  14. Environment: INET, UNIX
  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:  nocol-3.0/src/cmu-snmp/apps/snmpnetstat/inet.c
  21. #   nocol-3.0/src/cmu-snmp/man/snmpget.1
  22. #   nocol-3.0/src/cmu-snmp/snmplib/mib.c
  23. #   nocol-3.0/src/perlnocol/nocollib.pl
  24. #   nocol-3.0/src/pingmon/pingmon.c nocol-3.0/src/tpmon/main.c
  25. # Wrapped by kent@sparky on Tue Nov  9 22:22:21 1993
  26. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
  27. echo If this archive is complete, you will see the following message:
  28. echo '          "shar: End of archive 16 (of 26)."'
  29. if test -f 'nocol-3.0/src/cmu-snmp/apps/snmpnetstat/inet.c' -a "${1}" != "-c" ; then 
  30.   echo shar: Will not clobber existing file \"'nocol-3.0/src/cmu-snmp/apps/snmpnetstat/inet.c'\"
  31. else
  32.   echo shar: Extracting \"'nocol-3.0/src/cmu-snmp/apps/snmpnetstat/inet.c'\" \(14030 characters\)
  33.   sed "s/^X//" >'nocol-3.0/src/cmu-snmp/apps/snmpnetstat/inet.c' <<'END_OF_FILE'
  34. X/***********************************************************
  35. X    Copyright 1989 by Carnegie Mellon University
  36. X
  37. X                      All Rights Reserved
  38. X
  39. XPermission to use, copy, modify, and distribute this software and its 
  40. Xdocumentation for any purpose and without fee is hereby granted, 
  41. Xprovided that the above copyright notice appear in all copies and that
  42. Xboth that copyright notice and this permission notice appear in 
  43. Xsupporting documentation, and that the name of CMU not be
  44. Xused in advertising or publicity pertaining to distribution of the
  45. Xsoftware without specific, written prior permission.  
  46. X
  47. XCMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  48. XALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  49. XCMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  50. XANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  51. XWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  52. XARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  53. XSOFTWARE.
  54. X******************************************************************/
  55. X/*
  56. X * Copyright (c) 1983,1988 Regents of the University of California.
  57. X * All rights reserved.
  58. X *
  59. X * Redistribution and use in source and binary forms are permitted
  60. X * provided that this notice is preserved and that due credit is given
  61. X * to the University of California at Berkeley. The name of the University
  62. X * may not be used to endorse or promote products derived from this
  63. X * software without specific prior written permission. This software
  64. X * is provided ``as is'' without express or implied warranty.
  65. X */
  66. X
  67. X#include <strings.h>
  68. X#include <stdio.h>
  69. X
  70. X#include <sys/param.h>
  71. X#include <sys/socket.h>
  72. X
  73. X#include <netinet/in.h>
  74. X
  75. X#include <netdb.h>
  76. X
  77. X#include "main.h"
  78. X#include "asn1.h"
  79. X#include "snmp.h"
  80. X#include "snmp_impl.h"
  81. X#include "snmp_api.h"
  82. X#include "snmp_client.h"
  83. X#include "mib.h"
  84. X
  85. Xextern    int aflag;
  86. Xextern    int nflag;
  87. Xextern    char *plural();
  88. Xextern    char *malloc();
  89. Xextern    struct snmp_session *Session;
  90. Xextern    struct variable_list *getvarbyname();
  91. X
  92. X
  93. Xchar    *inetname();
  94. X
  95. Xstruct stat_table {
  96. X    int        entry;  /* entry number in table */
  97. X    /* format string to printf(description, value, plural(value)); */
  98. X    /* warning: the %d must be before the %s */
  99. X    char    description[80];
  100. X};
  101. X
  102. Xstatic oid oid_ipstats[] = {1, 3, 6, 1, 2, 1, 4, 0, 0};
  103. Xstruct stat_table ip_stattab[] = {
  104. X    {3, "%d total datagram%s received"},
  105. X    {4, "%d datagram%s with header errors"},
  106. X    {5, "%d datagram%s with an invalid destination address"},
  107. X    {6, "%d datagram%s forwarded"},
  108. X    {7, "%d datagram%s with unknown protocol"},
  109. X    {8, "%d datagram%s discarded"},
  110. X    {9, "%d datagram%s delivered"},
  111. X    {10, "%d output datagram request%s"},
  112. X    {11, "%d output datagram%s discarded"},
  113. X    {12, "%d datagram%s with no route"},
  114. X    {14, "%d fragment%s received"},
  115. X    {15, "%d datagram%s reassembled"},
  116. X    {16, "%d reassembly failure%s"},
  117. X    {17, "%d datagram%s fragmented"},
  118. X    {18, "%d fragmentation failure%s"},
  119. X    {19, "%d fragment%s created"}
  120. X};
  121. X
  122. Xstatic oid oid_udpstats[] = {1, 3, 6, 1, 2, 1, 7, 0, 0};
  123. Xstruct stat_table udp_stattab[] = {
  124. X    {1, "%d total datagram%s received"},
  125. X    {2, "%d datagram%s to invalid port"},
  126. X    {3, "%d datagram%s dropped due to errors"},
  127. X    {4, "%d output datagram request%s"}
  128. X};
  129. X
  130. Xstatic oid oid_tcpstats[] = {1, 3, 6, 1, 2, 1, 6, 0, 0};
  131. Xstruct stat_table tcp_stattab[] = {
  132. X    {5, "%d active open%s"},
  133. X    {6, "%d passive open%s"},
  134. X    {7, "%d failed attempt%s"},
  135. X    {8, "%d reset%s of established connections"},
  136. X    {9, "%d current established connection%s"},
  137. X    {10, "%d segment%s received"},
  138. X    {11, "%d segment%s sent"},
  139. X    {12, "%d segment%s retransmitted"}
  140. X};
  141. X
  142. Xstatic oid oid_icmpstats[] = {1, 3, 6, 1, 2, 1, 5, 0, 0};
  143. Xstruct stat_table icmp_stattab[] = {
  144. X    {1, "%d total message%s received"},
  145. X    {2, "%d message%s dropped due to errors"},
  146. X    {14, "%d ouput message request%s"},
  147. X    {15, "%d output message%s discarded"}
  148. X};
  149. X
  150. Xstruct stat_table icmp_inhistogram[] = {
  151. X    {3, "Destination unreachable: %d"},
  152. X    {4, "Time Exceeded: %d"},
  153. X    {5, "Parameter Problem: %d"},
  154. X    {6, "Source Quench: %d"},
  155. X    {7, "Redirect: %d"},
  156. X    {8, "Echo Request: %d"},
  157. X    {9, "Echo Reply: %d"},
  158. X    {10, "Timestamp Request: %d"},
  159. X    {11, "Timestamp Reply: %d"},
  160. X    {12, "Address Mask Request: %d"},
  161. X    {13, "Addrss Mask Reply:%d"},
  162. X};
  163. X
  164. Xstruct stat_table icmp_outhistogram[] = {
  165. X    {16, "Destination unreachable: %d"},
  166. X    {17, "Time Exceeded: %d"},
  167. X    {18, "Parameter Problem: %d"},
  168. X    {19, "Source Quench: %d"},
  169. X    {20, "Redirect: %d"},
  170. X    {21, "Echo Request: %d"},
  171. X    {22, "Echo Reply: %d"},
  172. X    {23, "Timestamp Request: %d"},
  173. X    {24, "Timestamp Reply: %d"},
  174. X    {25, "Address Mask Request: %d"},
  175. X    {26, "Addrss Mask Reply:%d"},
  176. X};
  177. X
  178. Xstruct tcpconn_entry {
  179. X    oid        instance[10];
  180. X    struct in_addr  localAddress;
  181. X    int        locAddrSet;
  182. X    u_short localPort;
  183. X    int        locPortSet;
  184. X    struct in_addr  remoteAddress;
  185. X    int        remAddrSet;
  186. X    u_short remotePort;
  187. X    int        remPortSet;
  188. X    int        state;
  189. X    int        stateSet;
  190. X    struct tcpconn_entry *next;
  191. X};
  192. X
  193. X#define TCPCONN_STATE    1
  194. X#define TCPCONN_LOCADDR    2
  195. X#define TCPCONN_LOCPORT    3
  196. X#define TCPCONN_REMADDR    4
  197. X#define TCPCONN_REMPORT    5
  198. X
  199. X
  200. X
  201. Xstatic oid oid_tcpconntable[] = {1, 3, 6, 1, 2, 1, 6, 13, 1};
  202. X#define ENTRY 9
  203. X
  204. Xchar *tcpstates[] = {
  205. X    "",            "CLOSED",        "LISTEN",   "SYNSENT",
  206. X    "SYNRECEIVED",  "ESTABLISHED",  "FINWAIT1", "FINWAIT2",
  207. X    "CLOSEWAIT",    "LASTACK",        "CLOSING",    "TIMEWAIT"
  208. X};
  209. X#define TCP_NSTATES 11
  210. X
  211. X/*
  212. X * Print a summary of connections related to an Internet
  213. X * protocol (currently only TCP).  For TCP, also give state of connection.
  214. X */
  215. Xprotopr(){
  216. X    struct tcpconn_entry *tcpconn = NULL, *tp, *newp;
  217. X    struct snmp_pdu *request, *response;
  218. X    struct variable_list *vp;
  219. X    oid *instance;
  220. X    int first, status;
  221. X
  222. X    request = snmp_pdu_create(GETNEXT_REQ_MSG);
  223. X
  224. X    snmp_add_null_var(request, oid_tcpconntable, sizeof(oid_tcpconntable)/sizeof(oid));
  225. X
  226. X    while(1){
  227. X    status = snmp_synch_response(Session, request, &response);
  228. X    if (status != STAT_SUCCESS || response->errstat != SNMP_ERR_NOERROR){
  229. X        fprintf(stderr, "SNMP request failed\n");
  230. X        break;
  231. X    }
  232. X    vp = response->variables;
  233. X    if (vp->name_length != 20 ||
  234. X        bcmp((char *)vp->name, (char *)oid_tcpconntable, sizeof(oid_tcpconntable))){
  235. X        break;
  236. X    }
  237. X    
  238. X    request = snmp_pdu_create(GETNEXT_REQ_MSG);
  239. X    snmp_add_null_var(request, vp->name, vp->name_length);
  240. X
  241. X    instance = vp->name + 10;
  242. X    for(tp = tcpconn; tp != NULL; tp = tp->next){
  243. X        if (!bcmp((char *)instance, (char *)tp->instance,
  244. X        sizeof(tp->instance)))
  245. X            break;
  246. X    }
  247. X    if (tp == NULL){
  248. X        newp = (struct tcpconn_entry *)malloc(sizeof(struct tcpconn_entry));
  249. X        if (tcpconn == NULL){
  250. X        tcpconn = newp;
  251. X        } else {
  252. X        for(tp = tcpconn; tp->next != NULL; tp = tp->next)
  253. X            ;
  254. X        tp->next = newp;
  255. X        }
  256. X        tp = newp;
  257. X        bzero((char *)tp, sizeof(*tp));
  258. X        tp->next = NULL;
  259. X        bcopy((char *)instance, (char *)tp->instance, sizeof(tp->instance));
  260. X    }
  261. X
  262. X    if (vp->name[ENTRY] == TCPCONN_STATE){
  263. X        tp->state = *vp->val.integer;
  264. X        tp->stateSet = 1;
  265. X
  266. X    }
  267. X
  268. X    if (vp->name[ENTRY] == TCPCONN_LOCADDR){
  269. X        bcopy((char *)vp->val.string, (char *)&tp->localAddress, sizeof(u_long));
  270. X        tp->locAddrSet = 1;
  271. X
  272. X    }
  273. X
  274. X    if (vp->name[ENTRY] == TCPCONN_LOCPORT){
  275. X        tp->localPort = *vp->val.integer;
  276. X        tp->locPortSet = 1;
  277. X
  278. X    }
  279. X
  280. X    if (vp->name[ENTRY] == TCPCONN_REMADDR){
  281. X        bcopy((char *)vp->val.string, (char *)&tp->remoteAddress, sizeof(u_long));
  282. X        tp->remAddrSet = 1;
  283. X
  284. X    }
  285. X
  286. X    if (vp->name[ENTRY] == TCPCONN_REMPORT){
  287. X        tp->remotePort = *vp->val.integer;
  288. X        tp->remPortSet = 1;
  289. X
  290. X    }
  291. X
  292. X    }
  293. X
  294. X    for(first = 1, tp = tcpconn; tp != NULL; tp = tp->next){
  295. X    if (!(tp->stateSet && tp->locAddrSet
  296. X        && tp->locPortSet && tp->remAddrSet && tp->remPortSet)){
  297. X        printf("incomplete entry\n");
  298. X        continue;
  299. X    }
  300. X    if (!aflag && tp->state == MIB_TCPCONNSTATE_LISTEN)
  301. X            continue;
  302. X    if (first){
  303. X        printf("Active Internet Connections");
  304. X        if (aflag)
  305. X        printf(" (including servers)");
  306. X        putchar('\n');
  307. X        printf("%-5.5s %-6.6s %-6.6s  %-22.22s %-22.22s %s\n",
  308. X            "Proto", "Recv-Q", "Send-Q",
  309. X            "Local Address", "Foreign Address", "(state)");
  310. X        first = 0;
  311. X    }
  312. X    printf("%-5.5s %6d %6d ", "tcp", 0, 0);
  313. X    inetprint(&tp->localAddress, tp->localPort, "tcp");
  314. X    inetprint(&tp->remoteAddress, tp->remotePort, "tcp");
  315. X    if (tp->state < 1 || tp->state > TCP_NSTATES)
  316. X        printf(" %d", tp->state);
  317. X    else
  318. X        printf(" %s", tcpstates[tp->state]);
  319. X    putchar('\n');
  320. X    }
  321. X
  322. X}
  323. X
  324. X
  325. X/*
  326. X * Dump UDP statistics structure.
  327. X */
  328. Xudp_stats()
  329. X{
  330. X    oid varname[MAX_NAME_LEN], *udpentry;
  331. X    int varname_len;
  332. X    struct variable_list *var;
  333. X    int count;
  334. X    struct stat_table *sp = udp_stattab;
  335. X
  336. X    bcopy((char *)oid_udpstats, (char *)varname, sizeof(oid_udpstats));
  337. X    varname_len = sizeof(oid_udpstats) / sizeof(oid);
  338. X    udpentry = varname + 7;
  339. X    printf("udp:\n");
  340. X    count = sizeof(udp_stattab) / sizeof (struct stat_table);
  341. X    while (count--){
  342. X    *udpentry = sp->entry;
  343. X    var = getvarbyname(Session, varname, varname_len);
  344. X    if (var){
  345. X        putchar('\t');
  346. X        printf(sp->description, *var->val.integer, plural((int)*var->val.integer));
  347. X        putchar('\n');
  348. X    }
  349. X    sp++;
  350. X    }
  351. X
  352. X}
  353. X
  354. X/*
  355. X * Dump TCP statistics structure.
  356. X */
  357. Xtcp_stats()
  358. X{
  359. X    oid varname[MAX_NAME_LEN], *tcpentry;
  360. X    int varname_len;
  361. X    struct variable_list *var;
  362. X    int count;
  363. X    struct stat_table *sp = tcp_stattab;
  364. X
  365. X    bcopy((char *)oid_tcpstats, (char *)varname, sizeof(oid_tcpstats));
  366. X    varname_len = sizeof(oid_tcpstats) / sizeof(oid);
  367. X    tcpentry = varname + 7;
  368. X    printf("tcp:\n");
  369. X    count = sizeof(tcp_stattab) / sizeof (struct stat_table);
  370. X    while (count--){
  371. X    *tcpentry = sp->entry;
  372. X    var = getvarbyname(Session, varname, varname_len);
  373. X    if (var){
  374. X        putchar('\t');
  375. X        printf(sp->description, *var->val.integer, plural((int)*var->val.integer));
  376. X        putchar('\n');
  377. X    }
  378. X    sp++;
  379. X    }
  380. X
  381. X}
  382. X
  383. X/*
  384. X * Dump IP statistics structure.
  385. X */
  386. Xip_stats()
  387. X{
  388. X    oid varname[MAX_NAME_LEN], *ipentry;
  389. X    int varname_len;
  390. X    struct variable_list *var;
  391. X    int count;
  392. X    struct stat_table *sp = ip_stattab;
  393. X
  394. X    bcopy((char *)oid_ipstats, (char *)varname, sizeof(oid_ipstats));
  395. X    varname_len = sizeof(oid_ipstats) / sizeof(oid);
  396. X    ipentry = varname + 7;
  397. X    printf("ip:\n");
  398. X    count = sizeof(ip_stattab) / sizeof (struct stat_table);
  399. X    while (count--){
  400. X    *ipentry = sp->entry;
  401. X    var = getvarbyname(Session, varname, varname_len);
  402. X    if (var){
  403. X        putchar('\t');
  404. X        printf(sp->description, *var->val.integer, plural((int)*var->val.integer));
  405. X        putchar('\n');
  406. X    }
  407. X    sp++;
  408. X    }
  409. X
  410. X}
  411. X
  412. X/*
  413. X * Dump ICMP statistics.
  414. X */
  415. Xicmp_stats()
  416. X{
  417. X    oid varname[MAX_NAME_LEN], *icmpentry;
  418. X    int varname_len;
  419. X    struct variable_list *var;
  420. X    int count, first;
  421. X    struct stat_table *sp;
  422. X
  423. X    bcopy((char *)oid_icmpstats, (char *)varname, sizeof(oid_icmpstats));
  424. X    varname_len = sizeof(oid_icmpstats) / sizeof(oid);
  425. X    icmpentry = varname + 7;
  426. X    printf("icmp:\n");
  427. X    sp = icmp_stattab;
  428. X    count = sizeof(icmp_stattab) / sizeof (struct stat_table);
  429. X    while (count--){
  430. X    *icmpentry = sp->entry;
  431. X    var = getvarbyname(Session, varname, varname_len);
  432. X    if (var){
  433. X        putchar('\t');
  434. X        printf(sp->description, *var->val.integer, plural((int)*var->val.integer));
  435. X        putchar('\n');
  436. X    }
  437. X    sp++;
  438. X    }
  439. X
  440. X    sp = icmp_outhistogram;
  441. X    first = 1;
  442. X    count = sizeof(icmp_outhistogram) / sizeof (struct stat_table);
  443. X    while (count--){
  444. X    *icmpentry = sp->entry;
  445. X    var = getvarbyname(Session, varname, varname_len);
  446. X    if (var && *var->val.integer != 0){
  447. X        if (first){
  448. X        printf("\tOutput Histogram:\n");
  449. X        first = 0;
  450. X        }
  451. X        printf("\t\t");
  452. X        printf(sp->description, *var->val.integer, plural((int)*var->val.integer));
  453. X        putchar('\n');
  454. X    }
  455. X    sp++;
  456. X    }
  457. X
  458. X    sp = icmp_inhistogram;
  459. X    first = 1;
  460. X    count = sizeof(icmp_inhistogram) / sizeof (struct stat_table);
  461. X    while (count--){
  462. X    *icmpentry = sp->entry;
  463. X    var = getvarbyname(Session, varname, varname_len);
  464. X    if (var && *var->val.integer != 0){
  465. X        if (first){
  466. X        printf("\tInput Histogram:\n");
  467. X        first = 0;
  468. X        }
  469. X        printf("\t\t");
  470. X        printf(sp->description, *var->val.integer, plural((int)*var->val.integer));
  471. X        putchar('\n');
  472. X    }
  473. X    sp++;
  474. X    }
  475. X}
  476. X
  477. X/*
  478. X * Pretty print an Internet address (net address + port).
  479. X * If the nflag was specified, use numbers instead of names.
  480. X */
  481. Xinetprint(in, port, proto)
  482. X    register struct in_addr *in;
  483. X    u_short port; 
  484. X    char *proto;
  485. X{
  486. X    struct servent *sp = 0;
  487. X    char line[80], *cp, *index();
  488. X    int width;
  489. X
  490. X    sprintf(line, "%.*s.", 16, inetname(*in));
  491. X    cp = index(line, '\0');
  492. X    if (!nflag && port)
  493. X        sp = getservbyport((int)port, proto);
  494. X    if (sp || port == 0)
  495. X        sprintf(cp, "%.8s", sp ? sp->s_name : "*");
  496. X    else
  497. X        sprintf(cp, "%d", ntohs((u_short)port));
  498. X    width = 22;
  499. X    printf(" %-*.*s", width, width, line);
  500. X}
  501. X
  502. X/*
  503. X * Construct an Internet address representation.
  504. X * If the nflag has been supplied, give 
  505. X * numeric value, otherwise try for symbolic name.
  506. X */
  507. Xchar *
  508. Xinetname(in)
  509. X    struct in_addr in;
  510. X{
  511. X    register char *cp;
  512. X    static char line[50];
  513. X    struct hostent *hp;
  514. X    struct netent *np;
  515. X    static char domain[MAXHOSTNAMELEN + 1];
  516. X    static int first = 1;
  517. X
  518. X    if (first && !nflag) {
  519. X        first = 0;
  520. X        if (gethostname(domain, MAXHOSTNAMELEN) == 0 &&
  521. X            (cp = index(domain, '.')))
  522. X            (void) strcpy(domain, cp + 1);
  523. X        else
  524. X            domain[0] = 0;
  525. X    }
  526. X    cp = 0;
  527. X    if (!nflag && in.s_addr != INADDR_ANY) {
  528. X        u_long net = inet_netof(in);
  529. X        u_long lna = inet_lnaof(in);
  530. X
  531. X        if (lna == INADDR_ANY) {
  532. X            np = getnetbyaddr(net, AF_INET);
  533. X            if (np)
  534. X                cp = np->n_name;
  535. X        }
  536. X        if (cp == 0) {
  537. X            hp = gethostbyaddr((char *)&in, sizeof (in), AF_INET);
  538. X            if (hp) {
  539. X                if ((cp = index(hp->h_name, '.')) &&
  540. X                    !strcmp(cp + 1, domain))
  541. X                    *cp = 0;
  542. X                cp = hp->h_name;
  543. X            }
  544. X        }
  545. X    }
  546. X    if (in.s_addr == INADDR_ANY)
  547. X        strcpy(line, "*");
  548. X    else if (cp)
  549. X        strcpy(line, cp);
  550. X    else {
  551. X        in.s_addr = ntohl(in.s_addr);
  552. X#define C(x)    ((x) & 0xff)
  553. X        sprintf(line, "%u.%u.%u.%u", C(in.s_addr >> 24),
  554. X            C(in.s_addr >> 16), C(in.s_addr >> 8), C(in.s_addr));
  555. X    }
  556. X    return (line);
  557. X}
  558. END_OF_FILE
  559.   if test 14030 -ne `wc -c <'nocol-3.0/src/cmu-snmp/apps/snmpnetstat/inet.c'`; then
  560.     echo shar: \"'nocol-3.0/src/cmu-snmp/apps/snmpnetstat/inet.c'\" unpacked with wrong size!
  561.   fi
  562.   # end of 'nocol-3.0/src/cmu-snmp/apps/snmpnetstat/inet.c'
  563. fi
  564. if test -f 'nocol-3.0/src/cmu-snmp/man/snmpget.1' -a "${1}" != "-c" ; then 
  565.   echo shar: Will not clobber existing file \"'nocol-3.0/src/cmu-snmp/man/snmpget.1'\"
  566. else
  567.   echo shar: Extracting \"'nocol-3.0/src/cmu-snmp/man/snmpget.1'\" \(2626 characters\)
  568.   sed "s/^X//" >'nocol-3.0/src/cmu-snmp/man/snmpget.1' <<'END_OF_FILE'
  569. X.\* /***********************************************************
  570. X.\"     Copyright 1988, 1989 by Carnegie Mellon University
  571. X.\" 
  572. X.\"                       All Rights Reserved
  573. X.\" 
  574. X.\" Permission to use, copy, modify, and distribute this software and its 
  575. X.\" documentation for any purpose and without fee is hereby granted, 
  576. X.\" provided that the above copyright notice appear in all copies and that
  577. X.\" both that copyright notice and this permission notice appear in 
  578. X.\" supporting documentation, and that the name of CMU not be
  579. X.\" used in advertising or publicity pertaining to distribution of the
  580. X.\" software without specific, written prior permission.  
  581. X.\" 
  582. X.\" CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  583. X.\" ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  584. X.\" CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  585. X.\" ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  586. X.\" WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  587. X.\" ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  588. X.\" SOFTWARE.
  589. X.\" ******************************************************************/
  590. X.TH SNMPGET 1 "17 September 1989"
  591. X.UC 4
  592. X.SH NAME
  593. Xsnmpget - communicates with a network entity using SNMP GET Requests.
  594. X.SH SYNOPSIS
  595. Xsnmpget host community variable-name [variable-name]...
  596. X.SH DESCRIPTION
  597. XSnmpget is an SNMP application that uses the GET Request to query for
  598. Xinformation on a network entity.  One or more fully qualified object
  599. Xidentifiers may be given as arguments on the command line.
  600. XEach variable name is given in the format specified in
  601. X.IR variables (5).
  602. X.PP
  603. XThe
  604. X.I host
  605. Xspecification may be either a host name or an internet address
  606. Xspecified in "dot notation"
  607. X.PP
  608. XThe
  609. X.I community
  610. Xspecifies the community name for the transaction with the remote system.
  611. X.PP
  612. XFor example
  613. X.PP
  614. X.I snmpget netdev-kbox.cc.cmu.edu public system.sysdescr.0 system.sysUpTime.0
  615. X.PP
  616. Xwill retrieve the variables sysDescr.0 and sysUpTime.0:
  617. X.PP
  618. X.I Name: system.sysDescr.0
  619. X.br
  620. X.I OCTET STRING- (ascii):    Kinetics FastPath2
  621. X.PP
  622. X.I Name: system.sysUpTime.0
  623. X.br
  624. X.I Timeticks: (2270351) 6:18:23
  625. X.PP
  626. XIf the network entity has an error processing the request packet, an error
  627. Xpacket will be returned and a message will be shown, helping to pinpoint in what
  628. Xway the request was malformed.  If there were other variables in the request,
  629. Xthe request will be resent without the bad variable.
  630. X.PP
  631. XAdding a "-d" to the argument list will cause the application to dump input and output packets.
  632. X.PP
  633. X.SH "SEE ALSO"
  634. Xvariables(5), RFC 1065, RFC 1066, RFC 1067
  635. END_OF_FILE
  636.   if test 2626 -ne `wc -c <'nocol-3.0/src/cmu-snmp/man/snmpget.1'`; then
  637.     echo shar: \"'nocol-3.0/src/cmu-snmp/man/snmpget.1'\" unpacked with wrong size!
  638.   fi
  639.   # end of 'nocol-3.0/src/cmu-snmp/man/snmpget.1'
  640. fi
  641. if test -f 'nocol-3.0/src/cmu-snmp/snmplib/mib.c' -a "${1}" != "-c" ; then 
  642.   echo shar: Will not clobber existing file \"'nocol-3.0/src/cmu-snmp/snmplib/mib.c'\"
  643. else
  644.   echo shar: Extracting \"'nocol-3.0/src/cmu-snmp/snmplib/mib.c'\" \(17909 characters\)
  645.   sed "s/^X//" >'nocol-3.0/src/cmu-snmp/snmplib/mib.c' <<'END_OF_FILE'
  646. X/***********************************************************
  647. X    Copyright 1988, 1989 by Carnegie Mellon University
  648. X
  649. X                      All Rights Reserved
  650. X
  651. XPermission to use, copy, modify, and distribute this software and its 
  652. Xdocumentation for any purpose and without fee is hereby granted, 
  653. Xprovided that the above copyright notice appear in all copies and that
  654. Xboth that copyright notice and this permission notice appear in 
  655. Xsupporting documentation, and that the name of CMU not be
  656. Xused in advertising or publicity pertaining to distribution of the
  657. Xsoftware without specific, written prior permission.  
  658. X
  659. XCMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  660. XALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  661. XCMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  662. XANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  663. XWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  664. XARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  665. XSOFTWARE.
  666. X******************************************************************/
  667. X#include <stdio.h>
  668. X#include <ctype.h>
  669. X#include <sys/types.h>
  670. X#include <netinet/in.h>
  671. X#include <sys/time.h>
  672. X#include "asn1.h"
  673. X#include "snmp_impl.h"
  674. X#include "snmp_api.h"
  675. X#include "parse.h"
  676. X
  677. Xstatic void sprint_by_type();
  678. X
  679. Xstatic char *
  680. XuptimeString(timeticks, buf)
  681. X    register long timeticks;
  682. X    char *buf;
  683. X{
  684. X    int    seconds, minutes, hours, days;
  685. X
  686. X    timeticks /= 100;
  687. X    days = timeticks / (60 * 60 * 24);
  688. X    timeticks %= (60 * 60 * 24);
  689. X
  690. X    hours = timeticks / (60 * 60);
  691. X    timeticks %= (60 * 60);
  692. X
  693. X    minutes = timeticks / 60;
  694. X    seconds = timeticks % 60;
  695. X
  696. X    if (days == 0){
  697. X    sprintf(buf, "%d:%02d:%02d", hours, minutes, seconds);
  698. X    } else if (days == 1) {
  699. X    sprintf(buf, "%d day, %d:%02d:%02d", days, hours, minutes, seconds);
  700. X    } else {
  701. X    sprintf(buf, "%d days, %d:%02d:%02d", days, hours, minutes, seconds);
  702. X    }
  703. X    return buf;
  704. X}
  705. X
  706. Xstatic sprint_hexstring(buf, cp, len)
  707. X    char *buf;
  708. X    u_char  *cp;
  709. X    int        len;
  710. X{
  711. X
  712. X    for(; len >= 16; len -= 16){
  713. X    sprintf(buf, "%02X %02X %02X %02X %02X %02X %02X %02X ", cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]);
  714. X    buf += strlen(buf);
  715. X    cp += 8;
  716. X    sprintf(buf, "%02X %02X %02X %02X %02X %02X %02X %02X\n", cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]);
  717. X    buf += strlen(buf);
  718. X    cp += 8;
  719. X    }
  720. X    for(; len > 0; len--){
  721. X    sprintf(buf, "%02X ", *cp++);
  722. X    buf += strlen(buf);
  723. X    }
  724. X    *buf = '\0';
  725. X}
  726. X
  727. Xstatic sprint_asciistring(buf, cp, len)
  728. X    char *buf;
  729. X    u_char  *cp;
  730. X    int        len;
  731. X{
  732. X    int    x;
  733. X
  734. X    for(x = 0; x < len; x++){
  735. X    if (isprint(*cp)){
  736. X        *buf++ = *cp++;
  737. X    } else {
  738. X        *buf++ = '.';
  739. X        cp++;
  740. X    }
  741. X    if ((x % 48) == 47)
  742. X        *buf++ = '\n';
  743. X    }
  744. X    *buf = '\0';
  745. X}
  746. X
  747. X#ifdef UNUSED
  748. Xint
  749. Xread_rawobjid(input, output, out_len)
  750. X    char *input;
  751. X    oid *output;
  752. X    int    *out_len;
  753. X{
  754. X    char    buf[12], *cp;
  755. X    oid        *op = output;
  756. X    u_long  subid;
  757. X
  758. X    while(*input != '\0'){
  759. X    if (!isdigit(*input))
  760. X        break;
  761. X    cp = buf;
  762. X    while(isdigit(*input))
  763. X        *cp++ = *input++;
  764. X    *cp = '\0';
  765. X    subid = atoi(buf);
  766. X    if(subid > MAX_SUBID){
  767. X        fprintf(stderr, "sub-identifier too large: %s\n", buf);
  768. X        return 0;
  769. X    }
  770. X    if((*out_len)-- <= 0){
  771. X        fprintf(stderr, "object identifier too long\n");
  772. X        return 0;
  773. X    }
  774. X    *op++ = subid;
  775. X    if(*input++ != '.')
  776. X        break;
  777. X    }
  778. X    *out_len = op - output;
  779. X    if (*out_len == 0)
  780. X    return 0;
  781. X    return 1;
  782. X}
  783. X
  784. X#endif /* UNUSED */
  785. X
  786. Xstatic void
  787. Xsprint_octet_string(buf, var)
  788. X    char *buf;
  789. X    struct variable_list *var;
  790. X{
  791. X    int hex, x;
  792. X    u_char *cp;
  793. X
  794. X    if (var->type != ASN_OCTET_STR){
  795. X    sprintf(buf, "Wrong Type (should be OCTET STRING): ");
  796. X    buf += strlen(buf);
  797. X    sprint_by_type(buf, var, (struct enum_list *)NULL);
  798. X    return;
  799. X    }
  800. X    hex = 0;
  801. X    for(cp = var->val.string, x = 0; x < var->val_len; x++, cp++){
  802. X    if (!(isprint(*cp) || isspace(*cp)))
  803. X        hex = 1;
  804. X    }
  805. X    if (var->val_len <= 4)
  806. X    hex = 1;    /* not likely to be ascii */
  807. X    if (hex){
  808. X    sprintf(buf, "OCTET STRING-   (hex):\t");
  809. X    buf += strlen(buf);
  810. X    sprint_hexstring(buf, var->val.string, var->val_len);
  811. X    } else {
  812. X    sprintf(buf, "OCTET STRING- (ascii):\t");
  813. X    buf += strlen(buf);
  814. X    sprint_asciistring(buf, var->val.string, var->val_len);
  815. X    }
  816. X}
  817. X
  818. Xstatic void
  819. Xsprint_opaque(buf, var)
  820. X    char *buf;
  821. X    struct variable_list *var;
  822. X{
  823. X
  824. X    if (var->type != OPAQUE){
  825. X    sprintf(buf, "Wrong Type (should be Opaque): ");
  826. X    buf += strlen(buf);
  827. X    sprint_by_type(buf, var, (struct enum_list *)NULL);
  828. X    return;
  829. X    }
  830. X    sprintf(buf, "OPAQUE -   (hex):\t");
  831. X    buf += strlen(buf);
  832. X    sprint_hexstring(buf, var->val.string, var->val_len);
  833. X}
  834. X
  835. Xstatic void
  836. Xsprint_object_identifier(buf, var)
  837. X    char *buf;
  838. X    struct variable_list *var;
  839. X{
  840. X    if (var->type != ASN_OBJECT_ID){
  841. X    sprintf(buf, "Wrong Type (should be OBJECT IDENTIFIER): ");
  842. X    buf += strlen(buf);
  843. X    sprint_by_type(buf, var, (struct enum_list *)NULL);
  844. X    return;
  845. X    }
  846. X    sprintf(buf, "OBJECT IDENTIFIER:\t");
  847. X    buf += strlen(buf);
  848. X    sprint_objid(buf, (oid *)(var->val.objid), var->val_len / sizeof(oid));
  849. X}
  850. X
  851. Xstatic void
  852. Xsprint_timeticks(buf, var)
  853. X    char *buf;
  854. X    struct variable_list *var;
  855. X{
  856. X    char timebuf[32];
  857. X
  858. X    if (var->type != TIMETICKS){
  859. X    sprintf(buf, "Wrong Type (should be Timeticks): ");
  860. X    buf += strlen(buf);
  861. X    sprint_by_type(buf, var, (struct enum_list *)NULL);
  862. X    return;
  863. X    }
  864. X    sprintf(buf, "Timeticks: (%d) %s", *(var->val.integer), uptimeString(*(var->val.integer), timebuf));
  865. X}
  866. X
  867. Xstatic void
  868. Xsprint_integer(buf, var, enums)
  869. X    char *buf;
  870. X    struct variable_list *var;
  871. X    struct enum_list        *enums;
  872. X{
  873. X    char    *enum_string = NULL;
  874. X
  875. X    if (var->type != ASN_INTEGER){
  876. X    sprintf(buf, "Wrong Type (should be INTEGER): ");
  877. X    buf += strlen(buf);
  878. X    sprint_by_type(buf, var, (struct enum_list *)NULL);
  879. X    return;
  880. X    }
  881. X    for (; enums; enums = enums->next)
  882. X    if (enums->value == *var->val.integer){
  883. X        enum_string = enums->label;
  884. X        break;
  885. X    }
  886. X    if (enum_string == NULL)
  887. X    sprintf(buf, "INTEGER: %d", *var->val.integer);
  888. X    else
  889. X    sprintf(buf, "INTEGER: %s(%d)", enum_string, *var->val.integer);
  890. X}
  891. X
  892. Xstatic void
  893. Xsprint_gauge(buf, var)
  894. X    char *buf;
  895. X    struct variable_list *var;
  896. X{
  897. X    if (var->type != GAUGE){
  898. X    sprintf(buf, "Wrong Type (should be Gauge): ");
  899. X    buf += strlen(buf);
  900. X    sprint_by_type(buf, var, (struct enum_list *)NULL);
  901. X    return;
  902. X    }
  903. X    sprintf(buf, "Gauge: %lu", *var->val.integer);
  904. X}
  905. X
  906. Xstatic void
  907. Xsprint_counter(buf, var)
  908. X    char *buf;
  909. X    struct variable_list *var;
  910. X{
  911. X    if (var->type != COUNTER){
  912. X    sprintf(buf, "Wrong Type (should be Counter): ");
  913. X    buf += strlen(buf);
  914. X    sprint_by_type(buf, var, (struct enum_list *)NULL);
  915. X    return;
  916. X    }
  917. X    sprintf(buf, "Counter: %lu", *var->val.integer);
  918. X}
  919. X
  920. Xstatic void
  921. Xsprint_networkaddress(buf, var)
  922. X    char *buf;
  923. X    struct variable_list *var;
  924. X{
  925. X    int x, len;
  926. X    u_char *cp;
  927. X
  928. X    sprintf(buf, "Network Address:\t");
  929. X    buf += strlen(buf);
  930. X    cp = var->val.string;    
  931. X    len = var->val_len;
  932. X    for(x = 0; x < len; x++){
  933. X    sprintf(buf, "%02X", *cp++);
  934. X    buf += strlen(buf);
  935. X    if (x < (len - 1))
  936. X        *buf++ = ':';
  937. X    }
  938. X}
  939. X
  940. Xstatic void
  941. Xsprint_ipaddress(buf, var)
  942. X    char *buf;
  943. X    struct variable_list *var;
  944. X{
  945. X    u_char *ip;
  946. X
  947. X    if (var->type != IPADDRESS){
  948. X    sprintf(buf, "Wrong Type (should be Ipaddress): ");
  949. X    buf += strlen(buf);
  950. X    sprint_by_type(buf, var, (struct enum_list *)NULL);
  951. X    return;
  952. X    }
  953. X    ip = var->val.string;
  954. X    sprintf(buf, "IpAddress:\t%d.%d.%d.%d",ip[0], ip[1], ip[2], ip[3]);
  955. X}
  956. X
  957. Xstatic void
  958. Xsprint_unsigned_short(buf, var)
  959. X    char *buf;
  960. X    struct variable_list *var;
  961. X{
  962. X    if (var->type != ASN_INTEGER){
  963. X    sprintf(buf, "Wrong Type (should be INTEGER): ");
  964. X    buf += strlen(buf);
  965. X    sprint_by_type(buf, var, (struct enum_list *)NULL);
  966. X    return;
  967. X    }
  968. X    sprintf(buf, "INTEGER (0..65535): %lu", *var->val.integer);
  969. X}
  970. X
  971. Xstatic void
  972. Xsprint_null(buf, var)
  973. X    char *buf;
  974. X    struct variable_list *var;
  975. X{
  976. X    if (var->type != ASN_NULL){
  977. X    sprintf(buf, "Wrong Type (should be NULL): ");
  978. X    buf += strlen(buf);
  979. X    sprint_by_type(buf, var, (struct enum_list *)NULL);
  980. X    return;
  981. X    }
  982. X    sprintf(buf, "NULL");
  983. X}
  984. X
  985. Xstatic void
  986. Xsprint_unknowntype(buf, var)
  987. X    char *buf;
  988. X    struct variable_list *var;
  989. X{
  990. X/*    sprintf(buf, "Variable has bad type"); */
  991. X    sprint_by_type(buf, var, NULL);
  992. X}
  993. X
  994. Xstatic void
  995. Xsprint_badtype(buf)
  996. X    char *buf;
  997. X{
  998. X    sprintf(buf, "Variable has bad type");
  999. X}
  1000. X
  1001. Xstatic void
  1002. Xsprint_by_type(buf, var, enums)
  1003. X    char *buf;
  1004. X    struct variable_list *var;
  1005. X    struct enum_list        *enums;
  1006. X{
  1007. X    switch (var->type){
  1008. X    case ASN_INTEGER:
  1009. X        sprint_integer(buf, var, enums);
  1010. X        break;
  1011. X    case ASN_OCTET_STR:
  1012. X        sprint_octet_string(buf, var);
  1013. X        break;
  1014. X    case OPAQUE:
  1015. X        sprint_opaque(buf, var);
  1016. X        break;
  1017. X    case ASN_OBJECT_ID:
  1018. X        sprint_object_identifier(buf, var);
  1019. X        break;
  1020. X    case TIMETICKS:
  1021. X        sprint_timeticks(buf, var);
  1022. X        break;
  1023. X    case GAUGE:
  1024. X        sprint_gauge(buf, var);
  1025. X        break;
  1026. X    case COUNTER:
  1027. X        sprint_counter(buf, var);
  1028. X        break;
  1029. X    case IPADDRESS:
  1030. X        sprint_ipaddress(buf, var);
  1031. X        break;
  1032. X    case ASN_NULL:
  1033. X        sprint_null(buf, var);
  1034. X        break;
  1035. X    default:
  1036. X        sprint_badtype(buf);
  1037. X        break;
  1038. X    }
  1039. X}
  1040. X
  1041. Xstruct tree *get_symbol();
  1042. X
  1043. Xoid RFC1066_MIB[] = { 1, 3, 6, 1, 2, 1 };
  1044. Xunsigned char RFC1066_MIB_text[] = ".iso.org.dod.internet.mgmt.mib";
  1045. Xstruct tree *Mib;
  1046. X
  1047. Xinit_mib()
  1048. X{
  1049. X    char *file, *getenv();
  1050. X
  1051. X    Mib = 0;
  1052. X    file = getenv("MIBFILE");
  1053. X    if (file)
  1054. X    Mib = read_mib(file);
  1055. X    if (!Mib)
  1056. X    Mib = read_mib("mib.txt");
  1057. X    if (!Mib)
  1058. X    Mib = read_mib("/etc/mib.txt");
  1059. X    if (!Mib){
  1060. X    fprintf(stderr, "Couldn't find mib file\n");
  1061. X    exit(2);
  1062. X    }
  1063. X    set_functions(Mib);
  1064. X}
  1065. X
  1066. Xstatic
  1067. Xset_functions(subtree)
  1068. X    struct tree *subtree;
  1069. X{
  1070. X    for(; subtree; subtree = subtree->next_peer){
  1071. X    switch(subtree->type){
  1072. X        case TYPE_OBJID:
  1073. X        subtree->printer = sprint_object_identifier;
  1074. X        break;
  1075. X        case TYPE_OCTETSTR:
  1076. X        subtree->printer = sprint_octet_string;
  1077. X        break;
  1078. X        case TYPE_INTEGER:
  1079. X        subtree->printer = sprint_integer;
  1080. X        break;
  1081. X        case TYPE_NETADDR:
  1082. X        subtree->printer = sprint_networkaddress;
  1083. X        break;
  1084. X        case TYPE_IPADDR:
  1085. X        subtree->printer = sprint_ipaddress;
  1086. X        break;
  1087. X        case TYPE_COUNTER:
  1088. X        subtree->printer = sprint_counter;
  1089. X        break;
  1090. X        case TYPE_GAUGE:
  1091. X        subtree->printer = sprint_gauge;
  1092. X        break;
  1093. X        case TYPE_TIMETICKS:
  1094. X        subtree->printer = sprint_timeticks;
  1095. X        break;
  1096. X        case TYPE_OPAQUE:
  1097. X        subtree->printer = sprint_opaque;
  1098. X        break;
  1099. X        case TYPE_NULL:
  1100. X        subtree->printer = sprint_null;
  1101. X        break;
  1102. X        case TYPE_OTHER:
  1103. X        default:
  1104. X        subtree->printer = sprint_unknowntype;
  1105. X        break;
  1106. X    }
  1107. X    set_functions(subtree->child_list);
  1108. X    }
  1109. X}
  1110. X
  1111. X#ifdef testing
  1112. Xint snmp_dump_packet = 0;
  1113. X
  1114. Xmain(argc, argv)
  1115. X     int argc;
  1116. X     char *argv[];
  1117. X{
  1118. X    oid objid[64];
  1119. X    int objidlen = sizeof (objid);
  1120. X    int count;
  1121. X    struct variable variable;
  1122. X
  1123. X    init_mib(&Mib);
  1124. X    if (argc < 2)
  1125. X    print_subtree(Mib, 0);
  1126. X    variable.type = ASN_INTEGER;
  1127. X    variable.val.integer = 3;
  1128. X    variable.val_len = 4;
  1129. X    for (argc--; argc; argc--, argv++) {
  1130. X    objidlen = sizeof (objid);
  1131. X    printf("read_objid(%s) = %d\n",
  1132. X           argv[1], read_objid(argv[1], objid, &objidlen));
  1133. X    for(count = 0; count < objidlen; count++)
  1134. X        printf("%d.", objid[count]);
  1135. X    printf("\n");
  1136. X    print_variable(objid, objidlen, &variable);
  1137. X    }
  1138. X}
  1139. X
  1140. X#endif testing
  1141. X
  1142. X
  1143. Xstatic struct tree *
  1144. Xfind_rfc1066_mib(root)
  1145. X    struct tree *root;
  1146. X{
  1147. X    oid *op = RFC1066_MIB;
  1148. X    struct tree *tp;
  1149. X    int len;
  1150. X
  1151. X    for(len = sizeof(RFC1066_MIB)/sizeof(oid); len; len--, op++){
  1152. X    for(tp = root; tp; tp = tp->next_peer){
  1153. X        if (tp->subid == *op){
  1154. X        root = tp->child_list;
  1155. X        break;
  1156. X        }
  1157. X    }
  1158. X    if (tp == NULL)
  1159. X        return NULL;
  1160. X    }
  1161. X    return root;
  1162. X}
  1163. X
  1164. Xint read_objid(input, output, out_len)
  1165. X    char *input;
  1166. X    oid *output;
  1167. X    int    *out_len;   /* number of subid's in "output" */
  1168. X{
  1169. X    struct tree *root = Mib;
  1170. X    oid *op = output;
  1171. X    int i;
  1172. X
  1173. X    if (*input == '.')
  1174. X    input++;
  1175. X    else {
  1176. X    root = find_rfc1066_mib(root);
  1177. X    for (i = 0; i < sizeof (RFC1066_MIB)/sizeof(oid); i++) {
  1178. X        if ((*out_len)-- > 0)
  1179. X        *output++ = RFC1066_MIB[i];
  1180. X        else {
  1181. X        fprintf(stderr, "object identifier too long\n");
  1182. X        return (0);
  1183. X        }
  1184. X    }
  1185. X    }
  1186. X
  1187. X    if (root == NULL){
  1188. X    fprintf(stderr, "Mib not initialized.  Exiting.\n");
  1189. X    exit(1);
  1190. X    }
  1191. X    if ((*out_len =
  1192. X     parse_subtree(root, input, output, out_len)) == 0)
  1193. X    return (0);
  1194. X    *out_len += output - op;
  1195. X
  1196. X    return (1);
  1197. X}
  1198. X
  1199. Xstatic
  1200. Xparse_subtree(subtree, input, output, out_len)
  1201. X    struct tree *subtree;
  1202. X    char *input;
  1203. X    oid    *output;
  1204. X    int    *out_len;   /* number of subid's */
  1205. X{
  1206. X    char buf[128], *to = buf;
  1207. X    u_long subid = 0;
  1208. X    struct tree *tp;
  1209. X
  1210. X    /*
  1211. X     * No empty strings.  Can happen if there is a trailing '.' or two '.'s
  1212. X     * in a row, i.e. "..".
  1213. X     */
  1214. X    if ((*input == '\0') ||
  1215. X    (*input == '.'))
  1216. X    return (0);
  1217. X
  1218. X    if (isdigit(*input)) {
  1219. X    /*
  1220. X     * Read the number, then try to find it in the subtree.
  1221. X     */
  1222. X    while (isdigit(*input)) {
  1223. X        subid *= 10;
  1224. X        subid += *input++ - '0';
  1225. X    }
  1226. X    for (tp = subtree; tp; tp = tp->next_peer) {
  1227. X        if (tp->subid == subid)
  1228. X        goto found;
  1229. X    }
  1230. X    tp = NULL;
  1231. X    }
  1232. X    else {
  1233. X    /*
  1234. X     * Read the name into a buffer.
  1235. X     */
  1236. X    while ((*input != '\0') &&
  1237. X           (*input != '.')) {
  1238. X        *to++ = *input++;
  1239. X    }
  1240. X    *to = '\0';
  1241. X
  1242. X    /*
  1243. X     * Find the name in the subtree;
  1244. X     */
  1245. X    for (tp = subtree; tp; tp = tp->next_peer) {
  1246. X        if (lc_cmp(tp->label, buf) == 0) {
  1247. X        subid = tp->subid;
  1248. X        goto found;
  1249. X        }
  1250. X    }
  1251. X
  1252. X    /*
  1253. X     * If we didn't find the entry, punt...
  1254. X     */
  1255. X    if (tp == NULL) {
  1256. X        fprintf(stderr, "sub-identifier not found: %s\n", buf);
  1257. X        return (0);
  1258. X    }
  1259. X    }
  1260. X
  1261. Xfound:
  1262. X    if(subid > (u_long)MAX_SUBID){
  1263. X    fprintf(stderr, "sub-identifier too large: %s\n", buf);
  1264. X    return (0);
  1265. X    }
  1266. X
  1267. X    if ((*out_len)-- <= 0){
  1268. X    fprintf(stderr, "object identifier too long\n");
  1269. X    return (0);
  1270. X    }
  1271. X    *output++ = subid;
  1272. X
  1273. X    if (*input != '.')
  1274. X    return (1);
  1275. X    if ((*out_len =
  1276. X     parse_subtree(tp ? tp->child_list : NULL, ++input, output, out_len)) == 0)
  1277. X    return (0);
  1278. X    return (++*out_len);
  1279. X}
  1280. X
  1281. Xprint_objid(objid, objidlen)
  1282. X    oid        *objid;
  1283. X    int        objidlen;    /* number of subidentifiers */
  1284. X{
  1285. X    char    buf[256];
  1286. X    struct tree    *subtree = Mib;
  1287. X
  1288. X    *buf = '.';    /* this is a fully qualified name */
  1289. X    get_symbol(objid, objidlen, subtree, buf + 1);
  1290. X    printf("%s\n", buf);
  1291. X        
  1292. X}
  1293. X
  1294. Xsprint_objid(buf, objid, objidlen)
  1295. X    char *buf;
  1296. X    oid        *objid;
  1297. X    int        objidlen;    /* number of subidentifiers */
  1298. X{
  1299. X    struct tree    *subtree = Mib;
  1300. X
  1301. X    *buf = '.';    /* this is a fully qualified name */
  1302. X    get_symbol(objid, objidlen, subtree, buf + 1);
  1303. X}
  1304. X
  1305. X
  1306. Xprint_variable(objid, objidlen, variable)
  1307. X    oid     *objid;
  1308. X    int        objidlen;
  1309. X    struct  variable_list *variable;
  1310. X{
  1311. X    char    buf[512], *cp;
  1312. X    struct tree    *subtree = Mib;
  1313. X
  1314. X    *buf = '.';    /* this is a fully qualified name */
  1315. X    subtree = get_symbol(objid, objidlen, subtree, buf + 1);
  1316. X    cp = buf;
  1317. X    if ((strlen(buf) >= strlen((char *)RFC1066_MIB_text)) && !bcmp(buf, (char *)RFC1066_MIB_text,
  1318. X    strlen((char *)RFC1066_MIB_text))){
  1319. X        cp += sizeof(RFC1066_MIB_text);
  1320. X    }
  1321. X    printf("Name: %s\n", cp);
  1322. X    *buf = '\0';
  1323. X    if (subtree->printer)
  1324. X    (*subtree->printer)(buf, variable, subtree->enums);
  1325. X    else {
  1326. X    sprint_by_type(buf, variable, subtree->enums);
  1327. X    }
  1328. X    printf("%s\n", buf);
  1329. X}
  1330. X
  1331. Xsprint_variable(buf, objid, objidlen, variable)
  1332. X    char *buf;
  1333. X    oid     *objid;
  1334. X    int        objidlen;
  1335. X    struct  variable_list *variable;
  1336. X{
  1337. X    char    tempbuf[512], *cp;
  1338. X    struct tree    *subtree = Mib;
  1339. X
  1340. X    *tempbuf = '.';    /* this is a fully qualified name */
  1341. X    subtree = get_symbol(objid, objidlen, subtree, tempbuf + 1);
  1342. X    cp = tempbuf;
  1343. X    if ((strlen(buf) >= strlen((char *)RFC1066_MIB_text)) && !bcmp(buf, (char *)RFC1066_MIB_text,
  1344. X    strlen((char *)RFC1066_MIB_text))){
  1345. X        cp += sizeof(RFC1066_MIB_text);
  1346. X    }
  1347. X    sprintf(buf, "Name: %s\n", cp);
  1348. X    buf += strlen(buf);
  1349. X    if (subtree->printer)
  1350. X    (*subtree->printer)(buf, variable, subtree->enums);
  1351. X    else {
  1352. X    sprint_by_type(buf, variable, subtree->enums);
  1353. X    }
  1354. X    strcat(buf, "\n");
  1355. X}
  1356. X
  1357. Xsprint_value(buf, objid, objidlen, variable)
  1358. X    char *buf;
  1359. X    oid     *objid;
  1360. X    int        objidlen;
  1361. X    struct  variable_list *variable;
  1362. X{
  1363. X    char    tempbuf[512];
  1364. X    struct tree    *subtree = Mib;
  1365. X
  1366. X    subtree = get_symbol(objid, objidlen, subtree, tempbuf);
  1367. X    if (subtree->printer)
  1368. X    (*subtree->printer)(buf, variable, subtree->enums);
  1369. X    else {
  1370. X    sprint_by_type(buf, variable, subtree->enums);
  1371. X    }
  1372. X}
  1373. X
  1374. Xprint_value(objid, objidlen, variable)
  1375. X    oid     *objid;
  1376. X    int        objidlen;
  1377. X    struct  variable_list *variable;
  1378. X{
  1379. X    char    tempbuf[512];
  1380. X    struct tree    *subtree = Mib;
  1381. X
  1382. X    subtree = get_symbol(objid, objidlen, subtree, tempbuf);
  1383. X    if (subtree->printer)
  1384. X    (*subtree->printer)(tempbuf, variable, subtree->enums);
  1385. X    else {
  1386. X    sprint_by_type(tempbuf, variable, subtree->enums);
  1387. X    }
  1388. X    printf("%s\n", tempbuf);
  1389. X}
  1390. X
  1391. Xstruct tree *
  1392. Xget_symbol(objid, objidlen, subtree, buf)
  1393. X    oid        *objid;
  1394. X    int        objidlen;
  1395. X    struct tree    *subtree;
  1396. X    char    *buf;
  1397. X{
  1398. X    struct tree    *return_tree = NULL;
  1399. X
  1400. X    for(; subtree; subtree = subtree->next_peer){
  1401. X    if (*objid == subtree->subid){
  1402. X        strcpy(buf, subtree->label);
  1403. X        goto found;
  1404. X    }
  1405. X    }
  1406. X
  1407. X    /* subtree not found */
  1408. X    while(objidlen--){    /* output rest of name, uninterpreted */
  1409. X    sprintf(buf, "%u.", *objid++);
  1410. X    while(*buf)
  1411. X        buf++;
  1412. X    }
  1413. X    *(buf - 1) = '\0'; /* remove trailing dot */
  1414. X    return NULL;
  1415. X
  1416. Xfound:
  1417. X    if (objidlen > 1){
  1418. X    while(*buf)
  1419. X        buf++;
  1420. X    *buf++ = '.';
  1421. X    *buf = '\0';
  1422. X    return_tree = get_symbol(objid + 1, objidlen - 1, subtree->child_list, buf);
  1423. X    } 
  1424. X    if (return_tree != NULL)
  1425. X    return return_tree;
  1426. X    else
  1427. X    return subtree;
  1428. X}
  1429. X
  1430. X
  1431. Xstatic int
  1432. Xlc_cmp(s1, s2)
  1433. X    char *s1, *s2;
  1434. X{
  1435. X    char c1, c2;
  1436. X
  1437. X    while(*s1 && *s2){
  1438. X    if (isupper(*s1))
  1439. X        c1 = tolower(*s1);
  1440. X    else
  1441. X        c1 = *s1;
  1442. X    if (isupper(*s2))
  1443. X        c2 = tolower(*s2);
  1444. X    else
  1445. X        c2 = *s2;
  1446. X    if (c1 != c2)
  1447. X        return ((c1 - c2) > 0 ? 1 : -1);
  1448. X    s1++;
  1449. X    s2++;
  1450. X    }
  1451. X
  1452. X    if (*s1)
  1453. X    return -1;
  1454. X    if (*s2)
  1455. X    return 1;
  1456. X    return 0;
  1457. X}
  1458. X
  1459. END_OF_FILE
  1460.   if test 17909 -ne `wc -c <'nocol-3.0/src/cmu-snmp/snmplib/mib.c'`; then
  1461.     echo shar: \"'nocol-3.0/src/cmu-snmp/snmplib/mib.c'\" unpacked with wrong size!
  1462.   fi
  1463.   # end of 'nocol-3.0/src/cmu-snmp/snmplib/mib.c'
  1464. fi
  1465. if test -f 'nocol-3.0/src/perlnocol/nocollib.pl' -a "${1}" != "-c" ; then 
  1466.   echo shar: Will not clobber existing file \"'nocol-3.0/src/perlnocol/nocollib.pl'\"
  1467. else
  1468.   echo shar: Extracting \"'nocol-3.0/src/perlnocol/nocollib.pl'\" \(11972 characters\)
  1469.   sed "s/^X//" >'nocol-3.0/src/perlnocol/nocollib.pl' <<'END_OF_FILE'
  1470. X#!/usr/local/bin/perl
  1471. X#
  1472. X# $Header: /home/aggarwal/lsrc/nocol/src/perlnocol/RCS/nocollib.pl,v 1.5 1993/11/01 23:51:53 aggarwal Exp $
  1473. X#
  1474. X#     nocollib.pl - perl library of NOCOL routines
  1475. X#
  1476. X# Date: September 21, 1993
  1477. X# Programmer: John Wobus, jmwobus@mailbox.syr.edu
  1478. X#  Modifications:  vikas@jvnc.net
  1479. X#
  1480. X#    (c) Syracuse University Computing & Network Services 1993
  1481. X#
  1482. X# No warranty is expressed or implied.  Permission to copy and use is
  1483. X# extended to all.  Permission to redistribute is granted under the
  1484. X# following conditions: it is not sold for profit; this copyright
  1485. X# notice remains intact; the same permissions extend to the recipient;
  1486. X# and if any changes are made, a notice is added so stating.
  1487. X#
  1488. X
  1489. X## The following is a list of associative arrays used globally to
  1490. X#  refer to the fields in the EVENT structure.
  1491. X#    sender, sitename, siteaddr,
  1492. X#    varname, varval, varthres, varunits,
  1493. X#    mon, day, hour, min, severity, loglevel, nocop
  1494. X#
  1495. X#  Define $libdebug=1 to turn on verbose debugging messages.
  1496. X#  Might need to fix the '$event_t' description for null padding
  1497. X#  (since some systems might align structure fields on different
  1498. X#  boundaries).
  1499. X#
  1500. X# Usage:
  1501. X#
  1502. X#  require "nocollib.pl";
  1503. X#
  1504. X#
  1505. X# Subroutines:
  1506. X#
  1507. X#   unpackevent -    Extracts packed EVENT fields into various arrays
  1508. X#   packevent -        Converts array fields into a packed EVENT structure
  1509. X#   readevent -        Read EVENT from open IEVENT file desc and unpack it.
  1510. X#   writeevent -    Pack various arrays into EVENT struct and write out.
  1511. X#   gettime -        Get local month/day/hour/min
  1512. X#   standalone -    Kill earlier running processes and setup signals
  1513. X#   init_events -    Fill in various arrays with initial (global) values
  1514. X#   update_event -    Given status, updates array fields and logs if needed
  1515. X#   eventlog -        Logs event to 'noclogd' daemon
  1516. X#   
  1517. X#
  1518. X####################################################################
  1519. X# 
  1520. X
  1521. X#######################
  1522. X##  Customize these  ##
  1523. X#######################
  1524. X$nocolroot = "/nocol"  unless $nocolroot;
  1525. X$etcdir  = "$nocolroot/etc"  unless $etcdir;    # location of config file
  1526. X$bindir  = "$nocolroot/bin"  unless $bindir;
  1527. X$datadir = "$nocolroot/data" unless $datadir;    # output data file
  1528. X
  1529. Xpush(@INC, $bindir); push(@INC, $etcdir); # add to search paths for 'require'
  1530. X
  1531. X$NLOG_HOST = "minnie.jvnc.net" ;    # Used for logging to noclogd
  1532. X$NLOG_SERVICE = "noclog" ;        # if port is in /etc/services
  1533. X$NLOG_PORT = 5354 ;            # default port if NOT in /etc/services
  1534. X
  1535. X## Need to pad (actual length is 195, have to align on word? boundary)
  1536. X$event_t = "a12 a16 a128  a16 L L a8  CCCC CC C x" ;  # event structure format
  1537. X$levent = length( pack($event_t, 0, '') );        # sizeof structure
  1538. X
  1539. Xif ($libdebug) {print "(libdebug) Sizeof event= $levent\n" ;}
  1540. X
  1541. X######################
  1542. X##  GLOBAL DEFINES  ##
  1543. X######################
  1544. X
  1545. X$E_CRITICAL = 1;
  1546. X$E_ERROR    = 2;
  1547. X$E_WARNING  = 3;
  1548. X$E_INFO     = 4;
  1549. X
  1550. X$n_UP          = 0x01;
  1551. X$n_DOWN        = 0x02;
  1552. X$n_UNKNOWN     = 0x04;
  1553. X$n_TEST        = 0x08;
  1554. X$n_NODISPLAY   = 0x10;
  1555. X
  1556. X#######################
  1557. X##
  1558. X
  1559. X##
  1560. X# Given an index (to the list of associative arrays that are globally
  1561. X# declared), and an event structure, it unpacks and fills in the arrays
  1562. X# with the values from the event structure.
  1563. X
  1564. Xsub unpackevent {
  1565. X    local($i, $event) = @_ ;        # index and event
  1566. X    local($vpad);
  1567. X    ($sender{$i},$sitename{$i},$siteaddr{$i},
  1568. X     $varname{$i},$varvalue{$i},$varthres{$i},$varunits{$i},
  1569. X     $mon{$i},$day{$i},$hour{$i},$min{$i},
  1570. X     $severity{$i},$loglevel{$i},$nocop{$i}, $vpad)
  1571. X    =unpack($event_t, $event);
  1572. X    
  1573. X    if ($libdebug) { print "(debug) unpackevent: $i\n"; }
  1574. X    
  1575. X}
  1576. X
  1577. X##
  1578. X# Given an index (to the list of associative arrays that are globally
  1579. X# declared), it creates an EVENT structure and returns it.
  1580. X# Note the 'vpad' to align the structure on an even byte boundary.
  1581. Xsub packevent {
  1582. X    local($i) = @_ ;        #index to associative arrays
  1583. X    local($event) ;
  1584. X    local($vpad) = "" ;
  1585. X    $event = pack($event_t, 
  1586. X          $sender{$i},$sitename{$i},$siteaddr{$i},
  1587. X          $varname{$i},$varvalue{$i},$varthres{$i},$varunits{$i},
  1588. X          $mon{$i},$day{$i},$hour{$i},$min{$i},
  1589. X          $severity{$i},$loglevel{$i},$nocop{$i}, $vpad) ;
  1590. X    
  1591. X    if ($libdebug) { print "(debug) packevent: $i\n"; }
  1592. X    return($event) ;
  1593. X}
  1594. X
  1595. X##
  1596. X## Subroutines to read and write from the datafile.
  1597. X#
  1598. Xsub readevent {
  1599. X    local($index) = @_ ;
  1600. X    local($bl,$event);
  1601. X    
  1602. X    $index = 'TEMP' unless $index ;        # use TEMP storage by default
  1603. X    if ($bl = read(IEVENTS, $event, $levent))
  1604. X    {
  1605. X    &unpackevent($index, $event);        # fills in the various arrays
  1606. X    }
  1607. X    return($bl);
  1608. X}
  1609. X
  1610. Xsub writeevent {
  1611. X    local($index) = @_ ;
  1612. X    local($event) ;
  1613. X    
  1614. X    $event = &packevent($index);
  1615. X    
  1616. X    print OEVENTS $event ;
  1617. X}
  1618. X
  1619. X##
  1620. X#  printevent()  to display the event arrays given an index 
  1621. Xsub printevent {
  1622. X    local($i) = @_ ;
  1623. X    
  1624. X    print "
  1625. X      SENDER= $sender{$i},$sitename{$i},$siteaddr{$i},
  1626. X      VAR= $varname{$i},$varvalue{$i},$varthres{$i},$varunits{$i},
  1627. X      DATE= $mon{$i},$day{$i},$hour{$i},$min{$i},
  1628. X      SEV= $severity{$i},$loglevel{$i},$nocop{$i}\n" ;
  1629. X    
  1630. X}
  1631. X
  1632. X
  1633. X##    gettime()
  1634. X#
  1635. Xsub gettime {
  1636. X    local($mon,$day,$hour,$min,@time);
  1637. X    
  1638. X    @time=localtime(time);
  1639. X    $mon=substr("00".(1+$time[4]),-2);
  1640. X    $day=substr("00".$time[3],-2);
  1641. X    $hour=substr("00".$time[2],-2);
  1642. X    $min=substr("00".$time[1],-2);
  1643. X    return($mon,$day,$hour,$min);
  1644. X}
  1645. X
  1646. X## Another cheesy way to do a 'gettime'
  1647. X#
  1648. X#sub gettime {
  1649. X#  local($date);
  1650. X#  chop($date=`$bindate +"%m %d %H %M"`);
  1651. X#  return(split(/\s+/,$date));
  1652. X#}
  1653. X
  1654. X##    standalone()
  1655. X# Checks to see if PIDFILE exists and kills any earlier running process.
  1656. X# Created new PIDFILE and sets up signal handlers. Incidentally, pidfile
  1657. X# cannot be local since it is unlinked by the signal handler routines.
  1658. X#
  1659. Xsub standalone {
  1660. X    local($me,$dir)=@_;
  1661. X    local($localhost)=`hostname`; chop ($localhost);
  1662. X    local($pid,$host);
  1663. X    
  1664. X    ($pidfile)="$dir/$me.pid";
  1665. X
  1666. X    if(open(PID,"<$pidfile"))
  1667. X    {
  1668. X    chop($pid=<PID>); chop($host=<PID>); close(PID);
  1669. X    if ("$host" ne "$localhost") {
  1670. X        die("Program probably running on $host, else delete $pidfile\n");
  1671. X    }
  1672. X    
  1673. X    if($pid =~/^\d+$/)
  1674. X    {
  1675. X        foreach (`ps $pid`)
  1676. X        {
  1677. X        chop;
  1678. X        if(/$pid.*$me/){ kill(9,$pid); print "killing process $pid\n" };
  1679. X        }
  1680. X    }
  1681. X    }
  1682. X    if(open(PID,">$pidfile")){print PID "$$\n$localhost\n"; close(PID);}
  1683. X
  1684. X    $SIG{"QUIT"} = clean_out ;
  1685. X    $SIG{"TERM"} = clean_out ;
  1686. X    $SIG{"INT"}  = clean_out ;
  1687. X    $SIG{"USR1"} = toggle_libdebug ;
  1688. X}
  1689. X
  1690. Xsub clean_out {
  1691. X   unlink $pidfile ;
  1692. X   unlink $datafile ; 
  1693. X   die "Terminating on signal\n" ;
  1694. X}
  1695. X
  1696. Xsub toggle_libdebug {
  1697. X    if ($libdebug) { --$libdebug ;}
  1698. X    else {++$libdebug ;}
  1699. X
  1700. X    if ($libdebug) { print "(nocollib): libdebug ON\n"; }
  1701. X
  1702. X}
  1703. X
  1704. X
  1705. X## Fill in default values for the item arrays. Inserts the following 'global'
  1706. X#  variables:   $sender  $varname  $varunits
  1707. X#  Gets the sitename/siteaddr from the args passed to it.
  1708. Xsub init_event {
  1709. X    local($sitename, $siteaddr, $i) = @_ ;    # index into assoc arrays
  1710. X    
  1711. X    if ($libdebug){print "(debug) init_event: Inserting- $i, Sitename= $sitename, Siteaddr= $siteaddr\n"; }
  1712. X    
  1713. X    
  1714. X    $sender{$i} = $sender ;
  1715. X    $sitename{$i} = $sitename ;
  1716. X    $siteaddr{$i} = "$siteaddr";
  1717. X    
  1718. X    $varname{$i}  = $varname ;
  1719. X    $varvalue{$i} = 0 ;
  1720. X    $varthres{$i} = 0 ;
  1721. X    $varunits{$i} = $varunits ;
  1722. X    
  1723. X    ($mon{$i},$day{$i},$hour{$i},$min{$i}) = &gettime ;
  1724. X    
  1725. X    $severity{$i} = $E_INFO;
  1726. X    $loglevel{$i} = $E_INFO;
  1727. X    $nocop{$i}    = $nocop{$i} | $n_UNKNOWN ;
  1728. X    
  1729. X} # end init_event()
  1730. X
  1731. X
  1732. X##    update_event()
  1733. X# Given index to events, status (0 or 1), new value, max severity to escalate
  1734. X# to,   this subroutine will update the various associative arrays and log
  1735. X# the event also (if the state has changed).
  1736. Xsub update_event {
  1737. X    local($i, $status, $value, $maxsev) = @_ ;    # $i is index to arrays
  1738. X    
  1739. X    if ($libdebug) {
  1740. X    print "(debug) update_event: ITEM $i, stat=$status, maxsev=$maxsev \n";
  1741. X    }
  1742. X    if ($maxsev < $E_CRITICAL) { $maxsev = $E_CRITICAL; }
  1743. X    if ($status)    # status is UP
  1744. X    {
  1745. X    ($mon{$i},$day{$i},$hour{$i},$min{$i}) = &gettime ;
  1746. X    $varvalue{$i} = $value ;
  1747. X    if (!($nocop{$i} & $n_UP))            # recent state change
  1748. X    {
  1749. X        $nocop{$i} = $nocop{$i} & ~($n_UP | $n_DOWN | $n_UNKNOWN) | $n_UP;
  1750. X        $loglevel{$i} = $severity{$i} ;    # loglevel set to old level
  1751. X        $severity{$i} = $E_INFO;
  1752. X        &eventlog(&packevent($i)) ;        # log to noclogd daemon
  1753. X    }
  1754. X    }
  1755. X    else        # status is DOWN, escalate severity
  1756. X    {
  1757. X    if (!($nocop{$i} & $n_DOWN))            # recent state change
  1758. X    {
  1759. X        ($mon{$i},$day{$i},$hour{$i},$min{$i}) = &gettime ;
  1760. X    }
  1761. X    $varvalue{$i} = $value ;
  1762. X    $nocop{$i} = $nocop{$i} & ~($n_UP | $n_DOWN | $n_UNKNOWN) | $n_DOWN;
  1763. X    if ($severity{$i} > $maxsev)
  1764. X    {
  1765. X        --$severity{$i} ;        # escalate severity
  1766. X    }
  1767. X    
  1768. X    if ($loglevel{$i} != $severity{$i})        # new change
  1769. X    {
  1770. X        $loglevel{$i} = $severity{$i};
  1771. X        &eventlog(&packevent($i));
  1772. X    }
  1773. X    }
  1774. X    
  1775. X    if ($libdebug) {print "(debug) update_event:\n"; &printevent($i); }
  1776. X    
  1777. X}  # end update_event()
  1778. X
  1779. X##
  1780. X##    eventlog()
  1781. X#
  1782. X#
  1783. X
  1784. X$NLOG_HOST = "noclog.jvnc.net" unless $NLOG_HOST ;
  1785. X$NLOG_SERVICE = "noclog" unless $NLOG_SERVICE ;
  1786. X$NLOG_PORT = 2325 unless $NLOG_PORT ;
  1787. X$RETRY_REOPEN = 1*60 ;
  1788. X$isopenlogfd = 0 ;                # init this to negative value
  1789. X$logclosetime = -1 ;            # when logging last failed
  1790. X
  1791. Xsub eventlog {
  1792. X    local($event) = @_ ;
  1793. X    local($bytesleft) ;
  1794. X    
  1795. X    local($AF_INET) = 2;
  1796. X    local($SOCK_DGRAM) = 2;
  1797. X    
  1798. X    if ($isopenlogfd == 0)
  1799. X    {
  1800. X    local($curtime) = time ;
  1801. X    if (($curtime  - $logclosetime) < RETRY_REOPEN)
  1802. X    {
  1803. X        return (-1) ;    # don't try again until RETRY_REOPEN secs
  1804. X    }
  1805. X    ($junk, $junk, $proto) = getprotobyname('udp');
  1806. X    if (! socket(logfd, $AF_INET, $SOCK_DGRAM, $proto))
  1807. X    {
  1808. X        print "socket() call failed: $!\n";
  1809. X        $logclosetime = time ;    # record time of last attempt
  1810. X        return (-1);
  1811. X    }
  1812. X    
  1813. X    ## Get port number, host address to use
  1814. X    ($name, $aliases, $port) = getservbyname($NLOG_SERVICE, 'udp');
  1815. X    if (! $port) { $port = $NLOG_PORT ; }
  1816. X    
  1817. X    if ($NLOG_HOST =~ /^\d+/)
  1818. X    {        # IP address, not name
  1819. X        ($junk,$junk,$junk,$junk, $remoteaddr) = gethostbyaddr($NLOG_HOST, $AF_INET);
  1820. X    }
  1821. X    else
  1822. X    {
  1823. X        ($junk,$junk,$junk,$junk, $remoteaddr) = gethostbyname($NLOG_HOST);
  1824. X    }
  1825. X    
  1826. X        if ($libdebug) { print "(debug) eventlog: Port= $port, proto= $proto\n";}
  1827. X    $sockaddr = 'S n a4 x8' ;
  1828. X    $remote = pack($sockaddr, $AF_INET, $port, $remoteaddr);
  1829. X    if (! connect(logfd, $remote))
  1830. X    {
  1831. X        print ("Cannot connect to $NLOG_HOST: $!\n");
  1832. X        close(logfd);
  1833. X        $logclosetime = time ;    # record time of last attempt
  1834. X        $isopenlogfd = 0 ;         # reset
  1835. X        return(-1) ;
  1836. X    }
  1837. X    
  1838. X        if ($libdebug) {print "(debug) eventlog: socket opened\n"; }
  1839. X    $isopenlogfd = 1;        # open
  1840. X    }      # end: if(socket not open)
  1841. X    
  1842. X    ## Here only if socket has been opened and have to write out EVENT.
  1843. X    $bytesleft = length ($event) ;
  1844. X    while ($bytesleft)
  1845. X    {
  1846. X    local($written);
  1847. X    local($offset) = 0;
  1848. X        $written = syswrite(logfd, $event, $bytesleft, $offset );
  1849. X    if ($written <= 0)
  1850. X    {
  1851. X        if ($libdebug) {print ("eventlog syswrite error: $!\n");}
  1852. X        close(logfd);
  1853. X        return(-1);
  1854. X        }
  1855. X    
  1856. X    $bytesleft -= $written;
  1857. X    $offset += $written
  1858. X    }            # end:  while($bytesleft)
  1859. X    
  1860. X}
  1861. X
  1862. X
  1863. X##
  1864. X##
  1865. X# Standard main.. just create subroutines in your new
  1866. X# nocol monitor and call nocol_main from your monitor's main()
  1867. X# This is a sample.
  1868. X#
  1869. Xsub nocol_main {
  1870. X    
  1871. X    @me=split(/\//,$0); $me=pop(@me);
  1872. X    $piddir=join("/",@me); if ($piddir eq "") {$piddir=$etcdir;}
  1873. X    $cfile="$etcdir/$me-confg";
  1874. X    $datafile="$datadir/$me-output";
  1875. X
  1876. X    $sender= $me ;                          # filled in the EVENT sender
  1877. X
  1878. X    if ($p=fork){print "$p\n"; exit;}
  1879. X    &standalone($me, $piddir);
  1880. X    
  1881. X    &readconf;
  1882. X    
  1883. X    foreach $item (@items) {
  1884. X    &init_events($item);        # fill in initial values
  1885. X    }
  1886. X    while (1)
  1887. X    {
  1888. X    foreach $item (@items) {
  1889. X        &dotest;
  1890. X        &update_event($v, $status, $value, $maxseverity);
  1891. X    }
  1892. X    open(OEVENTS,">$datafile");
  1893. X    foreach $item (@items)
  1894. X    {
  1895. X        if(!$forget{$item})
  1896. X        {
  1897. X        &writeevent($item);
  1898. X        }
  1899. X    }
  1900. X    close(OEVENTS);
  1901. X    sleep($sleepint);
  1902. X    }                # end: while(1)
  1903. X    
  1904. X}    # end nocol_main()
  1905. X
  1906. X##
  1907. X#
  1908. X##
  1909. END_OF_FILE
  1910.   if test 11972 -ne `wc -c <'nocol-3.0/src/perlnocol/nocollib.pl'`; then
  1911.     echo shar: \"'nocol-3.0/src/perlnocol/nocollib.pl'\" unpacked with wrong size!
  1912.   fi
  1913.   chmod +x 'nocol-3.0/src/perlnocol/nocollib.pl'
  1914.   # end of 'nocol-3.0/src/perlnocol/nocollib.pl'
  1915. fi
  1916. if test -f 'nocol-3.0/src/pingmon/pingmon.c' -a "${1}" != "-c" ; then 
  1917.   echo shar: Will not clobber existing file \"'nocol-3.0/src/pingmon/pingmon.c'\"
  1918. else
  1919.   echo shar: Extracting \"'nocol-3.0/src/pingmon/pingmon.c'\" \(11711 characters\)
  1920.   sed "s/^X//" >'nocol-3.0/src/pingmon/pingmon.c' <<'END_OF_FILE'
  1921. X/*
  1922. X**    $Header: /home/aggarwal/lsrc/nocol/src/pingmon/RCS/pingmon.c,v 2.1 1993/10/30 03:15:21 aggarwal Exp $
  1923. X*/
  1924. X
  1925. X/*+
  1926. X**
  1927. X** DESCRIPTION
  1928. X**
  1929. X**    Runs the "ping" program to monitor a site. Marks a site as UP
  1930. X**    DOWN or UNKNOWN. It writes directly to the 'pingoutput' file
  1931. X**    instead of to a temporary file. Uses raw i/o calls.
  1932. X**
  1933. X**    This program opens the 'data file' supplied by the user and then
  1934. X**    creates the 'pingoutput' file. It then directly reads and writes
  1935. X**    from this file. On recieving a HUP signal, it rescans the 'data
  1936. X**    file' supplied by the user and continues.
  1937. X**
  1938. X**
  1939. X** AUTHOR
  1940. X**    Vikas Aggarwal, October 16, 1989
  1941. X**
  1942. X*/
  1943. X
  1944. X/*  Copyright 1992 JvNCnet
  1945. X
  1946. X Permission to use, copy, modify and distribute this software and its
  1947. X documentation for any purpose is hereby granted without fee, provided that
  1948. X the above copyright notice appear in all copies and that both that copyright
  1949. X notice and this permission notice appear in supporting documentation, and
  1950. X that the name of JvNCnet not be used in advertising or publicity pertaining
  1951. X to distribution of the software without specific, written prior permission.
  1952. X JvNCnet makes no representations about the suitability of this software for
  1953. X any purpose.  It is provided "as is" without express or implied warranty.
  1954. X
  1955. X JvNCnet DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
  1956. X IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL JvNCnet
  1957. X BE LIABLE FOR ANY DAMAGES WHATSOEVER, INCLUDING DAMAGES RESULTING FROM LOSS
  1958. X OF USE, DATA OR PROFITS, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  1959. X OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  1960. X*/
  1961. X
  1962. X
  1963. X/*
  1964. X * MODIFICATIONS
  1965. X *
  1966. X * $Log: pingmon.c,v $
  1967. X * Revision 2.1  1993/10/30  03:15:21  aggarwal
  1968. X * Fixed definitions of signal handler programs. Also appends directory
  1969. X * name to the pidfile while trying to unlink it.
  1970. X *
  1971. X * Revision 2.0  1992/06/18  21:18:16  aggarwal
  1972. X * Checked sleep logic. Cleaned up for release.
  1973. X *
  1974. X * Revision 1.11  1992/05/13  16:13:59  aggarwal
  1975. X * Altered for automatic output datafile, etc depending on its own
  1976. X * runtime name.
  1977. X *
  1978. X * Revision 1.5  90/04/16  18:12:21  aggarwal
  1979. X * Added stuff so that the config file can have comments.
  1980. X * Also can now send a SIGUSR1 to the program whose pid
  1981. X * is stored in 'program.pid' file.
  1982. X * 
  1983. X * Revision 1.4  90/03/15  15:27:22  aggarwal
  1984. X * Closed the fdout if it was not zero (if getting a SIGHUP signal, then
  1985. X * it should close the open output file before reopening it).
  1986. X * 
  1987. X * Revision 1.3  90/03/09  12:52:02  aggarwal
  1988. X * Major changes so that it can read in SIGNAL progname to send a
  1989. X * signal to another process when a site goes to CRITICAL the first
  1990. X * time.
  1991. X * 
  1992. X * Revision 1.1  89/12/13  14:16:09  aggarwal
  1993. X * Initial revision
  1994. X * 
  1995. X */ 
  1996. X#ifndef lint
  1997. X static char rcsid[] = "$RCSfile: pingmon.c,v $ $Revision: 2.1 $ $Date: 1993/10/30 03:15:21 $" ;
  1998. X#endif
  1999. X
  2000. X#include "pingmon.h"            /* program specific defines    */
  2001. X
  2002. X#include <string.h>            /* For strcat() definitions    */
  2003. X#include <sys/file.h>
  2004. X#include <signal.h>            /* For signal numbers        */
  2005. X#include <setjmp.h>
  2006. X
  2007. X
  2008. X/*+ 
  2009. X** Global variables
  2010. X**/
  2011. X
  2012. Xstatic char  nodesfile[MAXLINE];    /* Filename with list of nodes */
  2013. Xstatic char  datafile[MAXLINE];        /* Name of output data file */
  2014. Xstatic time_t pollinterval ;        /* Time between polls */
  2015. Xjmp_buf    env;                /* For longjmp and setjmp     */
  2016. X
  2017. Xmain (ac, av)
  2018. X     int ac;
  2019. X     char **av;
  2020. X{
  2021. X    extern char    *prognm ;            /* in pingmon.h     */
  2022. X    extern int debug ;
  2023. X    extern char *optarg;
  2024. X    extern int optind;
  2025. X    int    fdout = 0;            /* File desc for output data file */
  2026. X    register int c ;
  2027. X    char *p ;
  2028. X    time_t starttm, polltime ;
  2029. X    void done(), restart();            /* For the signals    */
  2030. X
  2031. X    prognm = av[0] ;                /* Save the program name */
  2032. X
  2033. X#ifdef SENDER
  2034. X    sender = SENDER ;
  2035. X#else                        /* delete the directory name */
  2036. X    if ((sender = (char *)strrchr (prognm , '/')) == NULL)
  2037. X      sender = prognm ;                /* no path in program name */
  2038. X    else
  2039. X      sender++ ;                /* skip leading '/' */
  2040. X#endif
  2041. X
  2042. X    /* the output data filename */    
  2043. X    sprintf(datafile,  "%s/%s%s\0",
  2044. X        DATADIR,  sender, PINGOUTPUTEXT); 
  2045. X    sprintf(nodesfile, "%s\0", NODESFILE) ;    /* the name of IP hosts file */
  2046. X
  2047. X    ping = PING ;
  2048. X
  2049. X    while ((c = getopt(ac, av, "do:p:")) != EOF)
  2050. X      switch (c)
  2051. X      {
  2052. X       case 'd':
  2053. X      debug++ ;
  2054. X      break ;
  2055. X       case 'o':                /* output datafile */
  2056. X      sprintf(datafile, "%s\0", optarg) ;
  2057. X      break ;
  2058. X       case 'p':                /* ping command to use */
  2059. X      ping = (char *)malloc (strlen(optarg) + 1) ;
  2060. X      strcpy(ping, optarg);
  2061. X      break ;
  2062. X       case '?':
  2063. X       default:
  2064. X      fprintf (stderr, "%s: Unknown flag: %c\n", prognm, optarg);
  2065. X      help() ;
  2066. X      goto Cleanup ;
  2067. X      }
  2068. X
  2069. X    switch ( ac - optind )
  2070. X    {
  2071. X     case 0:                    /* default input file */
  2072. X    break ;
  2073. X     case 1:
  2074. X    sprintf(nodesfile, "%s\0", av[optind]) ;
  2075. X    break ;
  2076. X     default:
  2077. X    fprintf (stderr, "%s Error: Too many 'hosts' files\n\n", prognm);
  2078. X    help() ;
  2079. X    goto Cleanup;
  2080. X    }
  2081. X
  2082. X    if (access(ping, F_OK | X_OK) != 0)    /* check if PING is executable    */
  2083. X    {
  2084. X    perror (ping);
  2085. X    done();
  2086. X    }
  2087. X
  2088. X    p = malloc (strlen(sender) + strlen(ETCDIR) + 2) ;
  2089. X    sprintf(p, "%s/%s\0", ETCDIR, sender) ;
  2090. X    if (standalone(p) == -1)     /* Kill prev running process    */
  2091. X    {
  2092. X    fprintf(stderr, "%s: Error in standalone...exiting\n", prognm);
  2093. X    exit (1);
  2094. X    }
  2095. X    else
  2096. X      free(p) ;        /* not needed anymore */
  2097. X
  2098. X    if (debug)
  2099. X      fprintf(stderr,
  2100. X          "(debug) %s: PING= '%s', NODESFILE= '%s', DATAFILE= '%s'\n",
  2101. X          prognm, ping, nodesfile, datafile) ;
  2102. X    
  2103. X    setjmp (env);            /* Save the environment in case    */
  2104. X
  2105. X    signal (SIGQUIT, done);        /* Delete pid file while dying    */
  2106. X    signal (SIGTERM, done);
  2107. X    signal (SIGINT, done);
  2108. X    signal (SIGHUP, restart);        /* Re-read the nodesfile file    */
  2109. X
  2110. X    if (getenv(DEBUG_FLG) != NULL)      /* see ifdebug mode desired     */
  2111. X      debug = debug ^ 1 ;
  2112. X
  2113. X    umask (002);            /* write access to the group    */
  2114. X    if (fdout != 0)            /* Say, recovering from longjmp    */
  2115. X      close(fdout);
  2116. X
  2117. X    openeventlog() ;            /* for logging */
  2118. X    if ( (fdout = open(datafile, O_RDWR | O_CREAT | O_TRUNC, 0664)) < 0)
  2119. X    {
  2120. X    fprintf(stderr, "(%s) ERROR in open datafile ", prognm);
  2121. X    perror (datafile);
  2122. X    goto Cleanup ;
  2123. X    }
  2124. X
  2125. X    if (init_sites(fdout, nodesfile) == -1 )
  2126. X      goto Cleanup ;
  2127. X
  2128. X    /* poll_sites makes one complete pass over the list of nodes */
  2129. X    while (1)                          /* forever */
  2130. X    {
  2131. X    starttm = time((time_t *)NULL) ;    /* time started this cycle */
  2132. X    if (poll_sites(fdout) == -1)        /* Polling error */
  2133. X      break ;
  2134. X
  2135. X    if ( (polltime = time((time_t *)NULL) - starttm) < pollinterval)
  2136. X      sleep ((unsigned)(pollinterval - polltime));
  2137. X    }
  2138. X    /* HERE ONLY IF ERROR */
  2139. X Cleanup:
  2140. X    done();
  2141. X
  2142. X}    /***************** End of main *******************/
  2143. X    
  2144. X/*+ 
  2145. X** FUNCTION:
  2146. X**     Brief usage
  2147. X**/
  2148. Xhelp ()
  2149. X{
  2150. X    static char usage[] = " [-d (debug)]  [-o <output file>] [-p <ping command>] [nodesfile file]\n";
  2151. X
  2152. X    fprintf(stderr, "\nUSAGE: %s %s\n\n", prognm, usage);
  2153. X    fprintf(stderr,"\tThis program finds out the status of sites by ");
  2154. X    fprintf(stderr,"sending out an ICMP ping request and writing\n");
  2155. X    fprintf(stderr,"\tthe output into the file %s.\n", datafile);
  2156. X
  2157. X    fprintf(stderr,"\tBy default, the list of nodes to monitor is %s\n", 
  2158. X        nodesfile);
  2159. X    fprintf(stderr,"\tbut can be changed on the command line.\n");
  2160. X
  2161. X    fprintf(stderr,"\tThe 'node-file' format is:\n");
  2162. X    fprintf(stderr,"\t\t POLLINTERVAL  <#secs>\n");
  2163. X    fprintf(stderr,"\t\t <node> <ip-address>  [TEST]\n\n");
  2164. X    fprintf(stderr,"\tThe program writes its pid in %s.pid and \n",prognm);
  2165. X    fprintf(stderr,"\tif a new process starts, it kills the earlier one.\n");
  2166. X    fprintf(stderr,"\tIf a HUP signal is sent to the process, it rescans ");
  2167. X    fprintf(stderr,"the nodes file. \n");
  2168. X    fprintf(stderr,"\nTo run in debug mode, do a 'setenv %s 1'\n",DEBUG_FLG);
  2169. X    return (1);
  2170. X}
  2171. X
  2172. X
  2173. X/*
  2174. X** FUNCTION
  2175. X**
  2176. X**    init_sites
  2177. X**
  2178. X**    This function writes to the LSTFILE. All sites in the NODESFILE
  2179. X**    file are set to UNKNOWN status.
  2180. X**
  2181. X**    Careful while using 'localtime': the calue of the month varies from
  2182. X**    0 - 11 and hence has to be incremented for the correct month.
  2183. X*/
  2184. X
  2185. Xinit_sites(fdout, nodesfile)
  2186. X     int fdout ;            /* Output file descriptor    */
  2187. X     char *nodesfile;            /* Filename of the nodes file    */
  2188. X{
  2189. X    extern char *sender ;
  2190. X    FILE *p_nodes ;
  2191. X    EVENT v;                /* Defined in NOCOL.H        */
  2192. X    char record[MAXLINE];
  2193. X    struct tm *loctime ;
  2194. X    time_t locclock ;            /* Careful, don't use 'long'    */
  2195. X
  2196. X    if ((p_nodes = fopen(nodesfile, "r")) == NULL)
  2197. X    {
  2198. X    fprintf(stderr, "%s error (init_sites) ", prognm) ;
  2199. X    perror (nodesfile);
  2200. X    return (-1);
  2201. X    }
  2202. X
  2203. X    /*
  2204. X     * Fill in the static data stuff
  2205. X     */
  2206. X    bzero (&v, sizeof(v)) ;
  2207. X
  2208. X    locclock = time((time_t *)0);
  2209. X    loctime = localtime((long *)&locclock);
  2210. X
  2211. X    v.mon = loctime->tm_mon + 1;    v.day = loctime->tm_mday;
  2212. X    v.hour = loctime->tm_hour;        v.min = loctime->tm_min;
  2213. X
  2214. X    strncpy (v.sender, sender, sizeof(v.sender) - 1);
  2215. X
  2216. X    strncpy (v.var.name, VARNM, sizeof (v.var.name) - 1);
  2217. X    strncpy (v.var.units, VARUNITS, sizeof (v.var.units) - 1);
  2218. X    v.var.threshold = PING_THRES ;        /* num of packets lost    */
  2219. X
  2220. X    v.nocop = SETF_UPDOUN (v.nocop, n_UNKNOWN);    /* Set all to UNKNOWN    */
  2221. X    v.severity = E_INFO ;
  2222. X
  2223. X    while(fgetline(p_nodes,record,MAXLINE) > 0 ) 
  2224. X    {
  2225. X#ifdef IP
  2226. X    u_long inet_addr() ;
  2227. X#endif
  2228. X    char w1[MAXLINE], w2[MAXLINE], w3[MAXLINE];    /* Confg words    */
  2229. X    int rc;                        /* return code    */
  2230. X
  2231. X    v.nocop = 0 ;                /* Init options to zero    */
  2232. X    *w1 = *w2 = *w3 = NULL ;
  2233. X    rc = sscanf(record,"%s %s %s", w1, w2, w3);
  2234. X    if (rc == 0 || *w1 == NULL || *w1 == '#')  /* Comment or blank     */
  2235. X      continue;
  2236. X
  2237. X        if (strncmp(w1, "POLLINTERVAL", 12) == 0 || strncmp(w1, "pollinterval", 12) == 0)
  2238. X        {
  2239. X            char *p;                                    /* for strtol */
  2240. X            pollinterval = (u_long)strtol(w2, &p, 0) ;
  2241. X            if (p == w2)
  2242. X            {
  2243. X                fprintf(stderr,"(%s): Error in format for POLLINTERVAL '%s'\n",
  2244. X                        prognm, w2) ;
  2245. X                pollinterval = 0 ;              /* reset to default above */
  2246. X            }
  2247. X            continue ;
  2248. X        }
  2249. X
  2250. X    strncpy(v.site.name, w1, sizeof(v.site.name) - 1);
  2251. X    strncpy(v.site.addr, w2, sizeof(v.site.addr) - 1);  /* no checks */
  2252. X
  2253. X#ifdef    IP        /* For IP, check the IP address */
  2254. X
  2255. X    if (inet_addr(w2) == -1)    /* bad address */
  2256. X    {
  2257. X        fprintf(stderr,
  2258. X            "(%s): Error in address '%s' for site '%s', ignoring\n",
  2259. X            prognm, w2, w1);
  2260. X        continue ;
  2261. X    }
  2262. X#endif
  2263. X    if (*w3 != NULL)            /* Some other keyword    */
  2264. X    {
  2265. X        if (strcmp(w3, "test") == 0 || strcmp(w3, "TEST") == 0)
  2266. X          v.nocop = v.nocop | n_TEST ;
  2267. X        else
  2268. X          fprintf(stderr, "%s: Ignoring unknown keyword- %s\n", prognm,w3);
  2269. X    }
  2270. X
  2271. X    if (write (fdout, (char *)&v, sizeof(v)) != sizeof(v))
  2272. X    {
  2273. X        fprintf(stderr, "%s (write): %s\n", prognm, sys_errlist[errno]);
  2274. X        exit (1) ;
  2275. X    }
  2276. X
  2277. X    }                    /* end: while            */
  2278. X    fclose (p_nodes);            /* Not needed any more        */    
  2279. X    return(1);                /* All OK            */
  2280. X}        /* end:  init_sites()        */
  2281. X
  2282. X
  2283. X/*+         restart
  2284. X** FUNCTION:
  2285. X**
  2286. X**     If a SIGHUP is sent, it rescans the nodesfile file and starts all
  2287. X** over without exiting from the program.
  2288. X**/
  2289. X
  2290. Xvoid restart ()
  2291. X{
  2292. X    closeeventlog();
  2293. X    longjmp (env, 1);
  2294. X}
  2295. X
  2296. X/*+         done
  2297. X** FUNCTION:
  2298. X**
  2299. X** Delete the PID and the data file.
  2300. X** Called just before exiting. Only if error. Exits since it can be called
  2301. X** on recieving a signal.
  2302. X**/
  2303. Xvoid done ()
  2304. X{
  2305. X    char pidfile[MAXLINE] ;
  2306. X
  2307. X    closeeventlog() ;
  2308. X
  2309. X    fprintf (stderr, "%s: removing data, pid file.... ", prognm);
  2310. X    sprintf (pidfile, "%s/%s.pid\0", ETCDIR, prognm);
  2311. X    unlink (pidfile);                /* remove the PID file    */
  2312. X    unlink (datafile);                /* delete the data file */
  2313. X    fprintf (stderr, "Done\n");
  2314. X    exit (1);
  2315. X}
  2316. END_OF_FILE
  2317.   if test 11711 -ne `wc -c <'nocol-3.0/src/pingmon/pingmon.c'`; then
  2318.     echo shar: \"'nocol-3.0/src/pingmon/pingmon.c'\" unpacked with wrong size!
  2319.   fi
  2320.   # end of 'nocol-3.0/src/pingmon/pingmon.c'
  2321. fi
  2322. if test -f 'nocol-3.0/src/tpmon/main.c' -a "${1}" != "-c" ; then 
  2323.   echo shar: Will not clobber existing file \"'nocol-3.0/src/tpmon/main.c'\"
  2324. else
  2325.   echo shar: Extracting \"'nocol-3.0/src/tpmon/main.c'\" \(11468 characters\)
  2326.   sed "s/^X//" >'nocol-3.0/src/tpmon/main.c' <<'END_OF_FILE'
  2327. X/*
  2328. X * $Header: /home/aggarwal/lsrc/nocol/src/tpmon/RCS/main.c,v 2.1 1993/10/30 03:27:42 aggarwal Exp $
  2329. X *
  2330. X * DESCRIPTION: throughput monitor
  2331. X *
  2332. X *   This program connects to the 'discard' port on a remote host and
  2333. X *   sends random data to the remote host and calculates the throughput
  2334. X *   (in bits per second).
  2335. X *
  2336. X *   For interfacing with 'nocol', it opens the data file supplied by 
  2337. X *   the user and then creates a 'tpmon-output' file for use with netmon.
  2338. X *   It then directly reads and writes from this file.  If it gets SIGHUP,
  2339. X *   it rescans the data file before continuing.
  2340. X *
  2341. X *   Derived in part from the pingmon code, RCS v1.11
  2342. X *
  2343. X *   S. Spencer Sun, Princeton Univ. / JvNCnet, June 1992
  2344. X *
  2345. X * MODIFICATIONS
  2346. X *
  2347. X * $Log: main.c,v $
  2348. X * Revision 2.1  1993/10/30  03:27:42  aggarwal
  2349. X * Deleted watchdog info. Fixed defines of the signal handlers
  2350. X *
  2351. X * Revision 2.0  1992/06/18  21:20:43  aggarwal
  2352. X * Just increased the revision number for rcsid[] and releasing.
  2353. X *
  2354. X * Revision 1.3  1992/06/14  23:38:56  aggarwal
  2355. X * Had to increment 'sender' after 'strrchr'
  2356. X *
  2357. X * Revision 1.2  1992/06/12  04:15:47  aggarwal
  2358. X * Fixed scanning of keyword 'pollinterval'
  2359. X *
  2360. X * Revision 1.1  1992/06/12  04:06:46  aggarwal
  2361. X * Initial revision
  2362. X *
  2363. X *
  2364. X */
  2365. X/*  Copyright 1992 JvNCnet
  2366. X
  2367. X Permission to use, copy, modify and distribute this software and its
  2368. X documentation for any purpose is hereby granted without fee, provided that
  2369. X the above copyright notice appear in all copies and that both that copyright
  2370. X notice and this permission notice appear in supporting documentation, and
  2371. X that the name of JvNCnet not be used in advertising or publicity pertaining
  2372. X to distribution of the software without specific, written prior permission.
  2373. X JvNCnet makes no representations about the suitability of this software for
  2374. X any purpose.  It is provided "as is" without express or implied warranty.
  2375. X
  2376. X JvNCnet DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
  2377. X IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL JvNCnet
  2378. X BE LIABLE FOR ANY DAMAGES WHATSOEVER, INCLUDING DAMAGES RESULTING FROM LOSS
  2379. X OF USE, DATA OR PROFITS, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  2380. X OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  2381. X*/
  2382. X
  2383. X/* ^L */
  2384. X
  2385. X#ifndef lint
  2386. X static char rcsid[] = "$RCSfile: main.c,v $ $Revision: 2.1 $ $Date: 1993/10/30 03:27:42 $" ;
  2387. X#endif
  2388. X
  2389. X
  2390. X
  2391. X#include "nocol.h"            /*    common structures    */
  2392. X
  2393. X#include <string.h>            /* For strcat() definitions    */
  2394. X#include <sys/file.h>
  2395. X#include <signal.h>            /* For signal numbers        */
  2396. X#include <setjmp.h>
  2397. X
  2398. X#define GLOBALS                /* for global variables */
  2399. X#include "tpmon.h"            /* program specific defines    */
  2400. X#undef GLOBALS
  2401. X
  2402. X
  2403. X/*+ 
  2404. X * Variables definitions
  2405. X */
  2406. X
  2407. Xjmp_buf    env;                /* For longjmp and setjmp     */
  2408. X
  2409. Xmain (ac, av)
  2410. X     int ac;
  2411. X     char **av;
  2412. X{
  2413. X    extern char *prognm ;                       /* in pingmon.h  */
  2414. X    extern int debug ;
  2415. X    extern char *optarg;
  2416. X    extern int optind;
  2417. X    int    fdout = 0;            /* File desc for output data file */
  2418. X    register int c ;
  2419. X    char *p;
  2420. X    time_t starttm, polltime ;
  2421. X    void done(), restart();            /* For the signals    */
  2422. X
  2423. X    prognm = av[0] ;                /* Save the program name */
  2424. X
  2425. X#ifdef SENDER
  2426. X    sender = SENDER ;
  2427. X#else                        /* delete the directory name */
  2428. X    if ((sender = (char *)strrchr (prognm , '/')) == NULL)
  2429. X      sender = prognm ;                /* no path in program name */
  2430. X    else
  2431. X      sender++ ;                /* skip leading '/' */
  2432. X#endif
  2433. X
  2434. X    /* the output data filename */    
  2435. X    sprintf(datafile,  "%s/%s%s\0", DATADIR,  sender, TPMONOUTPUTEXT); 
  2436. X    sprintf(ipnodes, "%s\0", NODESFILE);    /* the name of the config file */
  2437. X
  2438. X    while ((c = getopt(ac, av, "do:")) != EOF)
  2439. X      switch (c) {
  2440. X        case 'd':
  2441. X      debug++ ;
  2442. X      break ;
  2443. X        case 'o':                /* output datafile */
  2444. X      sprintf(datafile, "%s\0", optarg) ;
  2445. X      break ;
  2446. X        case '?':
  2447. X        default:
  2448. X      fprintf (stderr, "%s: Unknown flag: %c\n", prognm, optarg);
  2449. X      help() ;
  2450. X      goto Cleanup ;
  2451. X      }
  2452. X
  2453. X    switch (ac - optind) {
  2454. X      case 0:                    /* default input file */
  2455. X    break ;
  2456. X      case 1:
  2457. X    sprintf(ipnodes, "%s\0", av[optind]) ;
  2458. X    break ;
  2459. X      default:
  2460. X    fprintf (stderr, "%s Error: Too many 'hosts' files\n\n", prognm);
  2461. X    help() ;
  2462. X    goto Cleanup;
  2463. X    }
  2464. X
  2465. X
  2466. X    p = malloc (sizeof(sender) + sizeof(ETCDIR) + 1) ;
  2467. X    sprintf(p, "%s/%s\0", ETCDIR, sender) ;
  2468. X    if (standalone(p) == -1) {        /* Kill prev running process    */
  2469. X      fprintf(stderr, "%s: Error in standalone...exiting\n", prognm);
  2470. X      exit (1);
  2471. X    }
  2472. X    else
  2473. X      free(p);        /* not needed anymore */
  2474. X
  2475. X    if (debug)
  2476. X      fprintf(stderr,
  2477. X    "(debug) %s: NODESFILE= '%s', DATAFILE= '%s'\n",
  2478. X      prognm, ipnodes, datafile) ;
  2479. X    
  2480. X    setjmp (env);            /* Save the environment in case    */
  2481. X
  2482. X    signal (SIGQUIT, done);        /* Delete pid file while dying    */
  2483. X    signal (SIGTERM, done);
  2484. X    signal (SIGINT, done);
  2485. X    signal (SIGHUP, restart);        /* Re-read the ipnodes file    */
  2486. X
  2487. X    if (getenv(DEBUG_FLG) != NULL)      /* see ifdebug mode desired     */
  2488. X      debug = debug ^ 1 ;
  2489. X
  2490. X    umask (002);            /* write access to the group    */
  2491. X    if (fdout != 0)            /* Say, recovering from longjmp    */
  2492. X      close(fdout);
  2493. X
  2494. X    openeventlog() ;            /* noclogd for logging */
  2495. X
  2496. X    if ( (fdout = open(datafile, O_RDWR | O_CREAT | O_TRUNC, 0664)) < 0) {
  2497. X      fprintf(stderr, "(%s) ERROR in open datafile ", prognm);
  2498. X      perror (datafile);
  2499. X      goto Cleanup ;
  2500. X    }
  2501. X
  2502. X    if (init_sites(fdout, ipnodes) == -1 )
  2503. X      goto Cleanup ;
  2504. X
  2505. X    if (!pollinterval)
  2506. X      pollinterval = POLLINTERVAL ;        /* default value */
  2507. X
  2508. X
  2509. X    /* poll_sites makes one complete pass over the list of nodes */
  2510. X    while (1)                                   /* forever */
  2511. X    {
  2512. X        starttm = time((time_t *)NULL) ;        /* time started this cycle */
  2513. X        if (poll_sites(fdout) == -1)            /* Polling error */
  2514. X          break ;
  2515. X
  2516. X        if ( (polltime = time((time_t *)NULL) - starttm) < pollinterval)
  2517. X          sleep ((unsigned)(pollinterval - polltime));
  2518. X    }
  2519. X
  2520. X    /* HERE ONLY IF ERROR */
  2521. X  Cleanup:
  2522. X    done();
  2523. X
  2524. X}    /***************** End of main *******************/
  2525. X    
  2526. X/*+ 
  2527. X** FUNCTION:
  2528. X**     Brief usage
  2529. X**/
  2530. Xhelp ()
  2531. X{
  2532. X    static char usage[] = " [-d (debug)] [-o <output file>] [<config file>]\n";
  2533. X
  2534. X    fprintf(stderr, "\nUSAGE: %s %s\n\n", prognm, usage);
  2535. X    fprintf(stderr, "\tThis program tests the throughput to sites by connecting\n");
  2536. X    fprintf(stderr, "\tto the discard port (TCP port 9) and writing data into\n");
  2537. X    fprintf(stderr, "\tit as fast as it can and measuring the transfer rate.\n");
  2538. X
  2539. X    fprintf(stderr,"\tBy default, the list of sites to monitor is in %s\n",
  2540. X        ipnodes);
  2541. X    fprintf(stderr,"\tbut can be changed on the command line.\n");
  2542. X
  2543. X    fprintf(stderr,"\tThe 'config file' format is:\n");
  2544. X    fprintf(stderr,"\t\t <hostname> <ip-address>  <threshold> [TEST]\n");
  2545. X    fprintf(stderr,"\t\t POLLINTERVAL <number of secs>\n");
  2546. X    fprintf(stderr,"\tThe program writes its pid in %s.pid and \n",prognm);
  2547. X    fprintf(stderr,"\tif a new process starts, it kills the earlier one.\n");
  2548. X    fprintf(stderr,"\tIf a HUP signal is sent to the process, it rescans ");
  2549. X    fprintf(stderr,"the config file. \n");
  2550. X    return (1);
  2551. X}
  2552. X
  2553. X
  2554. X/*
  2555. X** FUNCTION
  2556. X**
  2557. X**    init_sites
  2558. X**
  2559. X**    This function writes to the LSTFILE. All sites in the NODESFILE
  2560. X**    file are set to UNINIT status.
  2561. X**
  2562. X**    Careful while using 'localtime': the calue of the month varies from
  2563. X**    0 - 11 and hence has to be incremented for the correct month.
  2564. X*/
  2565. X
  2566. Xinit_sites(fdout, ipnodes)
  2567. X     int fdout ;            /* Output file descriptor    */
  2568. X     char *ipnodes;            /* Filename of the ipnodes file    */
  2569. X{
  2570. X    extern char sigtoprog[];        /* In pingmon.h            */
  2571. X    extern char *sender ;
  2572. X    FILE *p_nodes ;
  2573. X    EVENT v;                /* Defined in NOCOL.H        */
  2574. X    char record[MAXLINE];
  2575. X    struct tm *loctime ;
  2576. X    time_t locclock ;            /* Careful, don't use 'long'    */
  2577. X
  2578. X    if ((p_nodes = fopen(ipnodes, "r")) == NULL)
  2579. X    {
  2580. X    fprintf(stderr, "%s error (init_sites) ", prognm) ;
  2581. X    perror (ipnodes);
  2582. X    return (-1);
  2583. X    }
  2584. X
  2585. X    /*
  2586. X     * Fill in the static data stuff
  2587. X     */
  2588. X    bzero (&v, sizeof(v)) ;
  2589. X    locclock = time((time_t *)0);
  2590. X    loctime = localtime((long *)&locclock);
  2591. X
  2592. X    v.mon = loctime->tm_mon + 1;        v.day = loctime->tm_mday;
  2593. X    v.hour = loctime->tm_hour;          v.min = loctime->tm_min;
  2594. X
  2595. X    /*
  2596. X     * in the following strncpy's, the NULL is already appended because
  2597. X     * of the bzero, and copying one less than size of the arrays.
  2598. X     */
  2599. X    strncpy (v.sender, sender, sizeof(v.sender) - 1);
  2600. X
  2601. X    strncpy (v.var.name, VARNM, sizeof (v.var.name) - 1);
  2602. X    strncpy (v.var.units, VARUNITS, sizeof (v.var.units) - 1);
  2603. X    v.var.value = 0 ; v.var.threshold = 0 ;    /* threshold reset below */
  2604. X    v.nocop = SETF_UPDOUN (v.nocop, n_UNKNOWN); /* Set all to UNKNOWN   */
  2605. X    v.severity = E_INFO ;
  2606. X
  2607. X    while(fgetline(p_nodes,record,MAXLINE) > 0 ) 
  2608. X    {
  2609. X    u_long inet_addr() ;
  2610. X    char *p;        /* for strtol */
  2611. X    u_long thresh;
  2612. X    char w1[MAXLINE], w2[MAXLINE], w3[MAXLINE], w4[MAXLINE];
  2613. X        /* Confg words    */
  2614. X    int rc;                        /* return code    */
  2615. X
  2616. X    v.nocop = 0 ;                /* Init options to zero    */
  2617. X    *w1 = *w2 = *w3 = *w4 = NULL ;
  2618. X        /* line should look like "<name>  <IP#>  <threshold>  [TEST]" */
  2619. X    rc = sscanf(record,"%s %s %s %s", w1, w2, w3, w4);
  2620. X    if (rc == 0 || *w1 == NULL || *w1 == '#')  /* Comment or blank     */
  2621. X      continue;
  2622. X
  2623. X    if (strncmp(w1, "POLLINT", 7) == 0 || strncmp(w1, "pollint", 7) == 0)
  2624. X    {
  2625. X        pollinterval = (u_long)strtol(w2, &p, 0) ;
  2626. X        if (p == w2)
  2627. X        {
  2628. X        fprintf(stderr,"(%s): Error in format for POLLINTERVAL '%s'\n",
  2629. X            prognm, w2) ;
  2630. X        pollinterval = 0 ;        /* reset to default above */
  2631. X        }
  2632. X        continue ;
  2633. X    }
  2634. X
  2635. X    strncpy(v.site.name, w1, sizeof(v.site.name) - 1);
  2636. X    strncpy(v.site.addr, w2, sizeof(v.site.addr) - 1);    /* no checks */
  2637. X
  2638. X    if (inet_addr(w2) == -1)    /* bad address */
  2639. X    {
  2640. X        fprintf(stderr,
  2641. X            "(%s): Error in address '%s' for site '%s', ignoring\n",
  2642. X            prognm, w2, w1);
  2643. X        continue ;
  2644. X    }
  2645. X
  2646. X        thresh = (u_long)strtol(w3, &p, 0);
  2647. X        if (p == w3) {             /* strtod() couldn't convert */
  2648. X          fprintf(stderr,
  2649. X            "(%s): Error in format of threshold '%s' for site '%s'\n", 
  2650. X          prognm, w3, w1);
  2651. X      fprintf(stderr,
  2652. X            "\t(should be a long integer representing bits per second)\n");
  2653. X        } else
  2654. X          v.var.threshold = thresh;
  2655. X              
  2656. X    if (*w4 != NULL)            /* Some other keyword    */
  2657. X    {
  2658. X        if (strcmp(w4, "test") == 0 || strcmp(w3, "TEST") == 0)
  2659. X          v.nocop = v.nocop | n_TEST ;
  2660. X        else
  2661. X          fprintf(stderr, "%s: Ignoring unknown keyword- %s\n", prognm,w3);
  2662. X    }
  2663. X
  2664. X    write (fdout, (char *)&v, sizeof(v)) ;
  2665. X
  2666. X    }                    /* end: while            */
  2667. X    fclose (p_nodes);            /* Not needed any more        */    
  2668. X    return(1);                /* All OK            */
  2669. X}        /* end:  init_sites()        */
  2670. X
  2671. X
  2672. X/*+         restart
  2673. X** FUNCTION:
  2674. X**
  2675. X**     If a SIGHUP is sent, it rescans the ipnodes file and starts all
  2676. X** over without exiting from the program.
  2677. X**/
  2678. X
  2679. Xvoid restart ()
  2680. X{
  2681. X    closeeventlog() ;
  2682. X    longjmp (env, 1);
  2683. X}
  2684. X
  2685. X/*+             done
  2686. X** FUNCTION:
  2687. X**
  2688. X** Delete the PID and data file.
  2689. X** Called just before exiting. Only if error. Exits since it can be called
  2690. X** on recieving a signal.
  2691. X**/
  2692. Xvoid done ()
  2693. X{
  2694. X    char pidfile[MAXLINE] ;
  2695. X
  2696. X    closeeventlog() ;                /* Logging */
  2697. X    fprintf (stderr, "%s: removing pid, data file.... ", prognm);
  2698. X    sprintf (pidfile, "%s/%s.pid\0", ETCDIR, prognm);
  2699. X    unlink (pidfile);                           /* remove the PID file  */
  2700. X    unlink (datafile);                          /* delete the data file */
  2701. X    fprintf (stderr, "Done\n");
  2702. X    exit (1);
  2703. X}        /* end  done() */
  2704. END_OF_FILE
  2705.   if test 11468 -ne `wc -c <'nocol-3.0/src/tpmon/main.c'`; then
  2706.     echo shar: \"'nocol-3.0/src/tpmon/main.c'\" unpacked with wrong size!
  2707.   fi
  2708.   # end of 'nocol-3.0/src/tpmon/main.c'
  2709. fi
  2710. echo shar: End of archive 16 \(of 26\).
  2711. cp /dev/null ark16isdone
  2712. MISSING=""
  2713. 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 26 ; do
  2714.     if test ! -f ark${I}isdone ; then
  2715.     MISSING="${MISSING} ${I}"
  2716.     fi
  2717. done
  2718. if test "${MISSING}" = "" ; then
  2719.     echo You have unpacked all 26 archives.
  2720.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2721. else
  2722.     echo You still must unpack the following archives:
  2723.     echo "        " ${MISSING}
  2724. fi
  2725. exit 0
  2726. exit 0 # Just in case...
  2727.