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

  1. Newsgroups: comp.sources.misc
  2. From: nevil@ccu1.aukuni.ac.nz (J Nevil Brownlee)
  3. Subject: v40i108:  netramet - Network Traffic Accounting Meter, Part20/25
  4. Message-ID: <1993Nov9.020415.18757@sparky.sterling.com>
  5. X-Md4-Signature: 1331df52aa07a6e4b7a68481eb704dd8
  6. Sender: kent@sparky.sterling.com (Kent Landfield)
  7. Organization: Sterling Software
  8. Date: Tue, 9 Nov 1993 02:04:15 GMT
  9. Approved: kent@sparky.sterling.com
  10.  
  11. Submitted-by: nevil@ccu1.aukuni.ac.nz (J Nevil Brownlee)
  12. Posting-number: Volume 40, Issue 108
  13. Archive-name: netramet/part20
  14. Environment: INET, UNIX, DOS
  15.  
  16. #! /bin/sh
  17. # This is a shell archive.  Remove anything before this line, then feed it
  18. # into a shell via "sh file" or similar.  To overwrite existing files,
  19. # type "sh file -c".
  20. # Contents:  netramet/src/apps/snmp_vars.h netramet/src/apps/snmpagnt.c
  21. #   netramet/src/snmplib/mib.c netramet/src/snmplib/snmpagnt.c
  22. # Wrapped by kent@sparky on Tue Nov  2 18:17:12 1993
  23. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
  24. echo If this archive is complete, you will see the following message:
  25. echo '          "shar: End of archive 20 (of 25)."'
  26. if test -f 'netramet/src/apps/snmp_vars.h' -a "${1}" != "-c" ; then 
  27.   echo shar: Will not clobber existing file \"'netramet/src/apps/snmp_vars.h'\"
  28. else
  29.   echo shar: Extracting \"'netramet/src/apps/snmp_vars.h'\" \(5636 characters\)
  30.   sed "s/^X//" >'netramet/src/apps/snmp_vars.h' <<'END_OF_FILE'
  31. X/*
  32. X * Definitions for SNMP (RFC 1067) agent variable finder.
  33. X *
  34. X *
  35. X/***********************************************************
  36. X    Copyright 1988, 1989 by Carnegie Mellon University
  37. X    Copyright 1989    TGV, Incorporated
  38. X
  39. X              All Rights Reserved
  40. X
  41. XPermission to use, copy, modify, and distribute this software and its
  42. Xdocumentation for any purpose and without fee is hereby granted,
  43. Xprovided that the above copyright notice appear in all copies and that
  44. Xboth that copyright notice and this permission notice appear in
  45. Xsupporting documentation, and that the name of CMU and TGV not be used
  46. Xin advertising or publicity pertaining to distribution of the software
  47. Xwithout specific, written prior permission.
  48. X
  49. XCMU AND TGV DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  50. XINCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
  51. XEVENT SHALL CMU OR TGV BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  52. XCONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
  53. XUSE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
  54. XOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  55. XPERFORMANCE OF THIS SOFTWARE.
  56. X******************************************************************/
  57. X
  58. Xu_char    *var_system();
  59. Xu_char    *var_ifEntry();
  60. Xu_char    *var_atEntry();
  61. Xu_char    *var_ip();
  62. Xu_char    *var_ipAddrEntry();
  63. Xu_char    *var_ipRouteEntry();
  64. Xu_char    *var_icmp();
  65. Xu_char    *var_tcp();
  66. Xu_char    *var_udp();
  67. Xu_char    *var_process();
  68. Xu_char    *var_event();
  69. Xu_char    *getStatPtr();
  70. X
  71. Xextern long long_return;
  72. Xextern u_char return_buf[];
  73. X
  74. X#define INST    0xFFFFFFFF    /* used to fill out the instance field of the variables table */
  75. X
  76. X/*
  77. X * These are unit magic numbers for each variable.
  78. X */
  79. X
  80. X#define VERSION_DESCR    0
  81. X#define VERSION_ID    1
  82. X#define IFNUMBER    2
  83. X#define UPTIME        3
  84. X#define EVENTNEXTINDEX    4
  85. X
  86. X
  87. X#define IFINDEX        1
  88. X#define IFDESCR        2
  89. X#define IFTYPE        3
  90. X#define IFMTU        4
  91. X#define IFSPEED        5
  92. X#define IFPHYSADDRESS    6
  93. X#define IFADMINSTATUS    7
  94. X#define IFOPERSTATUS    8
  95. X#define IFLASTCHANGE    9
  96. X#define IFINOCTETS    10
  97. X#define IFINUCASTPKTS    11
  98. X#define IFINNUCASTPKTS    12
  99. X#define IFINDISCARDS    13
  100. X#define IFINERRORS    14
  101. X#define IFINUNKNOWNPROTOS 15
  102. X#define IFOUTOCTETS    16
  103. X#define IFOUTUCASTPKTS    17
  104. X#define IFOUTNUCASTPKTS 18
  105. X#define IFOUTDISCARDS    19
  106. X#define IFOUTERRORS    20
  107. X#define IFOUTQLEN    21
  108. X
  109. X#define ATIFINDEX    0
  110. X#define ATPHYSADDRESS    1
  111. X#define ATNETADDRESS    2
  112. X
  113. X#define IPFORWARDING    0
  114. X#define IPDEFAULTTTL    1
  115. X#define IPINRECEIVES    2
  116. X#define IPINHDRERRORS    3
  117. X#define IPINADDRERRORS    4
  118. X#define IPFORWDATAGRAMS 5
  119. X#define IPINUNKNOWNPROTOS 6
  120. X#define IPINDISCARDS    7
  121. X#define IPINDELIVERS    8
  122. X#define IPOUTREQUESTS    9
  123. X#define IPOUTDISCARDS    10
  124. X#define IPOUTNOROUTES    11
  125. X#define IPREASMTIMEOUT    12
  126. X#define IPREASMREQDS    13
  127. X#define IPREASMOKS    14
  128. X#define IPREASMFAILS    15
  129. X#define IPFRAGOKS    16
  130. X#define IPFRAGFAILS    17
  131. X#define IPFRAGCREATES    18
  132. X
  133. X#define IPADADDR    1
  134. X#define IPADIFINDEX    2
  135. X#define IPADNETMASK    3
  136. X#define IPADBCASTADDR    4
  137. X
  138. X#define IPROUTEDEST    0
  139. X#define IPROUTEIFINDEX    1
  140. X#define IPROUTEMETRIC1    2
  141. X#define IPROUTEMETRIC2    3
  142. X#define IPROUTEMETRIC3    4
  143. X#define IPROUTEMETRIC4    5
  144. X#define IPROUTENEXTHOP    6
  145. X#define IPROUTETYPE    7
  146. X#define IPROUTEPROTO    8
  147. X#define IPROUTEAGE    9
  148. X
  149. X#define ICMPINMSGS         0
  150. X#define ICMPINERRORS         1
  151. X#define ICMPINDESTUNREACHS   2
  152. X#define ICMPINTIMEEXCDS      3
  153. X#define ICMPINPARMPROBS      4
  154. X#define ICMPINSRCQUENCHS     5
  155. X#define ICMPINREDIRECTS      6
  156. X#define ICMPINECHOS         7
  157. X#define ICMPINECHOREPS         8
  158. X#define ICMPINTIMESTAMPS     9
  159. X#define ICMPINTIMESTAMPREPS 10
  160. X#define ICMPINADDRMASKS     11
  161. X#define ICMPINADDRMASKREPS  12
  162. X#define ICMPOUTMSGS        13
  163. X#define ICMPOUTERRORS        14
  164. X#define ICMPOUTDESTUNREACHS 15
  165. X#define ICMPOUTTIMEEXCDS    16
  166. X#define ICMPOUTPARMPROBS    17
  167. X#define ICMPOUTSRCQUENCHS   18
  168. X#define ICMPOUTREDIRECTS    19
  169. X#define ICMPOUTECHOS        20
  170. X#define ICMPOUTECHOREPS     21
  171. X#define ICMPOUTTIMESTAMPS   22
  172. X#define ICMPOUTTIMESTAMPREPS 23
  173. X#define ICMPOUTADDRMASKS    24
  174. X#define ICMPOUTADDRMASKREPS 25
  175. X
  176. X#define TCPRTOALGORITHM      1
  177. X#define TCPRTOMIN         2
  178. X#define TCPRTOMAX         3
  179. X#define TCPMAXCONN         4
  180. X#define TCPACTIVEOPENS         5
  181. X#define TCPPASSIVEOPENS      6
  182. X#define TCPATTEMPTFAILS      7
  183. X#define TCPESTABRESETS         8
  184. X#define TCPCURRESTAB         9
  185. X#define TCPINSEGS        10
  186. X#define TCPOUTSEGS        11
  187. X#define TCPRETRANSSEGS        12
  188. X#define TCPCONNSTATE        13
  189. X#define TCPCONNLOCALADDRESS 14
  190. X#define TCPCONNLOCALPORT    15
  191. X#define TCPCONNREMADDRESS   16
  192. X#define TCPCONNREMPORT        17
  193. X
  194. X#define UDPINDATAGRAMS        0
  195. X#define UDPNOPORTS        1
  196. X#define UDPINERRORS        2
  197. X#define UDPOUTDATAGRAMS     3
  198. X
  199. X#define EVENTCLASS            0
  200. X#define EVENTINSTANCE            1
  201. X#define EVENTALARMTYPE            2
  202. X#define EVENTTIME            3
  203. X#define EVENTPROBCAUSE            4
  204. X#define EVENTSPECIFICPROBLEM        5
  205. X#define EVENTSEVERITY            6
  206. X#define EVENTBACKUPSTATUS        7
  207. X#define EVENTBACKUPINSTANCE        8
  208. X#define EVENTTREND            9
  209. X#define EVENTTHRESHOLD            10
  210. X#define EVENTTHRESHOLDLEVEL        11
  211. X#define EVENTTHRESHOLDOBSVALUE        12
  212. X#define EVENTID                13
  213. X#define EVENTCORRELATIONS        14
  214. X#define EVENTOPERSTATE            16
  215. X#define EVENTADMINSTATE            17
  216. X#define EVENTMONATTRIBUTES        18
  217. X#define EVENTREPAIRACTION        19
  218. X#define EVENTDATA            20
  219. X#define EVENTTEXT            21
  220. X#define EVENTCREDIBILITY        22
  221. X#define EVENTINDEX            23
  222. X#define EVENTVALID            24
  223. X
  224. X
  225. Xstruct variable {
  226. X    oid            name[26];        /* object identifier of variable */
  227. X    u_char        namelen;        /* length of above */
  228. X    char        type;        /* type of variable, INTEGER or (octet) STRING */
  229. X    u_char        magic;        /* passed to function as a hint */
  230. X    u_short        acl;        /* access control list for variable */
  231. X    u_char        *(*findVar)();  /* function that finds variable */
  232. X};
  233. END_OF_FILE
  234.   if test 5636 -ne `wc -c <'netramet/src/apps/snmp_vars.h'`; then
  235.     echo shar: \"'netramet/src/apps/snmp_vars.h'\" unpacked with wrong size!
  236.   fi
  237.   # end of 'netramet/src/apps/snmp_vars.h'
  238. fi
  239. if test -f 'netramet/src/apps/snmpagnt.c' -a "${1}" != "-c" ; then 
  240.   echo shar: Will not clobber existing file \"'netramet/src/apps/snmpagnt.c'\"
  241. else
  242.   echo shar: Extracting \"'netramet/src/apps/snmpagnt.c'\" \(18099 characters\)
  243.   sed "s/^X//" >'netramet/src/apps/snmpagnt.c' <<'END_OF_FILE'
  244. X/*
  245. X * Simple Network Management Protocol (RFC 1067).
  246. X *
  247. X */
  248. X/***********************************************************
  249. X    Copyright 1988, 1989 by Carnegie Mellon University
  250. X
  251. X                      All Rights Reserved
  252. X
  253. XPermission to use, copy, modify, and distribute this software and its 
  254. Xdocumentation for any purpose and without fee is hereby granted, 
  255. Xprovided that the above copyright notice appear in all copies and that
  256. Xboth that copyright notice and this permission notice appear in 
  257. Xsupporting documentation, and that the name of CMU not be
  258. Xused in advertising or publicity pertaining to distribution of the
  259. Xsoftware without specific, written prior permission.  
  260. X
  261. XCMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  262. XALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  263. XCMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  264. XANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  265. XWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  266. XARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  267. XSOFTWARE.
  268. X******************************************************************/
  269. X
  270. X#include "ausnmp.h"
  271. X
  272. X#ifdef KINETICS
  273. X#include "gw.h"
  274. X#include "ab.h"
  275. X#include "inet.h"
  276. X#include "fp4/cmdmacro.h"
  277. X#include "fp4/pbuf.h"
  278. X#include "glob.h"
  279. X#endif
  280. X
  281. X#if (defined(unix) && !defined(KINETICS))
  282. X#include <sys/types.h>
  283. X#include <netinet/in.h>
  284. X#ifndef NULL
  285. X#define NULL 0
  286. X#endif
  287. X#endif
  288. X
  289. X#include "snmp.h"
  290. X#include "snmpimpl.h"  /* AU */
  291. X#include "asn1.h"
  292. X
  293. X#include "mib.h"
  294. X
  295. Xvoid    snmp_input();
  296. Xvoid    snmp_trap();
  297. Xint    create_identical();
  298. Xint    parse_var_op_list();
  299. Xint    snmp_access();
  300. X
  301. X#if kinetics
  302. Xchar    version_descr[];
  303. Xoid    version_id[];
  304. Xint    version_id_len;
  305. X#endif
  306. X
  307. Xstruct pbuf *definitelyGetBuf();
  308. X
  309. X#define NUM_COMMUNITIES    5
  310. Xchar    *communities[NUM_COMMUNITIES] = {
  311. X    "public", 
  312. X    "proxy",
  313. X    "private",
  314. X    "regional",
  315. X    "core"
  316. X};
  317. X
  318. X/* these can't be global in a multi-process router */
  319. X    u_char    sid[SID_MAX_LEN + 1];
  320. X    int        sidlen;
  321. X    u_char    *packet_end;
  322. X    int        community;
  323. X
  324. X
  325. X#ifdef KINETICS
  326. Xvoid
  327. Xsnmp_input(p)
  328. X    struct pbuf *p;
  329. X{
  330. X    struct ip        *ip = (struct ip *)p->p_off;
  331. X    int            hlen = (int)ip->ip_hl << 2;
  332. X    register struct udp        *udp;
  333. X    register u_char *data;  /* pointer to the rest of the unread data */
  334. X    int            length; /* bytes of data left in msg after the "data" pointer */
  335. X    struct pbuf        *out_packet;
  336. X    register u_char *out_data;
  337. X    int            out_length;
  338. X    u_short        udp_src;
  339. X    extern struct mib_udp   mib_udp;
  340. X
  341. X    
  342. X    udp = (struct udp *)(p->p_off + hlen);
  343. X    if (ntohs(ip->ip_len) - hlen < sizeof(struct udp) ||    /* IP length < minimum UDP packet */
  344. X        ntohs(udp->length) > ntohs(ip->ip_len) - hlen){ /* UDP length > IP data */
  345. X    ERROR("dropped packet with bad length");    /* delete me */
  346. X    return; /* drop packet */
  347. X    }
  348. X    data = (u_char *)udp + sizeof(struct udp);
  349. X    length = ntohs(udp->length) - sizeof(struct udp);
  350. X
  351. X    out_packet = definitelyGetBuf(); /* drop packets off input queue if necessary */
  352. X    out_data = (u_char *)(out_packet->p_off + sizeof (struct ip) + sizeof (struct udp));
  353. X    out_length = MAXDATA - sizeof(struct ip) - sizeof (struct udp);
  354. X
  355. XK_LEDON();
  356. X    if (!snmp_agent_parse(data, length, out_data, &out_length, (u_long)ip->ip_src)){
  357. X    K_PFREE(out_packet);
  358. XK_LEDOFF();
  359. X    return;
  360. X    }
  361. XK_LEDOFF();
  362. X    out_packet->p_len = packet_end - (u_char *)out_packet->p_off;
  363. X    setiphdr(out_packet, ip->ip_src);    /* address to source of request packet (ntohl ??? ) */
  364. X    udp_src = ntohs(udp->src);
  365. X    udp = (struct udp *)(out_packet->p_off + sizeof (struct ip));
  366. X    udp->src = htons(SNMP_PORT);
  367. X    udp->dst = htons(udp_src);
  368. X    udp->length = out_packet->p_len - sizeof(struct ip);
  369. X    udp->checksum = 0;    /* this should be computed */
  370. X
  371. X    mib_udp.udpOutDatagrams++;
  372. X    routeip(out_packet, 0, 0);
  373. X}
  374. X
  375. X
  376. Xvoid
  377. Xsnmp_trap(destAddr, trapType, specificType)
  378. X    u_long  destAddr;
  379. X    int        trapType;
  380. X    int        specificType;
  381. X{
  382. X    struct pbuf        *out_packet;
  383. X    register u_char *out_data;
  384. X    register struct udp        *udp;
  385. X    int            out_length;
  386. X    static oid        sysDescrOid[] = {1, 3, 6, 1, 2, 1, 1, 1, 0};
  387. X    
  388. X    out_packet = definitelyGetBuf(); /* drop packets off input queue if necessary */
  389. X    out_data = (u_char *)(out_packet->p_off + sizeof (struct ip) + sizeof (struct udp));
  390. X    out_length = MAXDATA - sizeof(struct ip) - sizeof (struct udp);
  391. X
  392. XK_LEDON();
  393. X    out_packet->p_len = snmp_build_trap(out_data, out_length, version_id, version_id_len,
  394. X    conf.ipaddr, trapType, specificType, TICKS2MS(tickclock)/10, sysDescrOid, sizeof(sysDescrOid)/sizeof(oid),
  395. X    ASN_OCTET_STR, strlen(version_descr), (u_char *)version_descr);
  396. X    if (out_packet->p_len == 0){
  397. X    K_PFREE(out_packet);
  398. XK_LEDOFF();
  399. X    return;
  400. X    }
  401. XK_LEDOFF();
  402. X    out_packet->p_len += sizeof(struct ip) + sizeof(struct udp);
  403. X    setiphdr(out_packet, destAddr);    /* address to source of request packet (ntohl ??? ) */
  404. X    udp = (struct udp *)(out_packet->p_off + sizeof (struct ip));
  405. X    udp->src = htons(SNMP_PORT);
  406. X    udp->dst = htons(SNMP_TRAP_PORT);
  407. X    udp->length = out_packet->p_len - sizeof(struct ip);
  408. X    udp->checksum = 0;    /* this should be computed */
  409. X
  410. X    mib_udp.udpOutDatagrams++;
  411. X    routeip(out_packet, 0, 0);
  412. X}
  413. X#endif
  414. X
  415. Xint
  416. Xsnmp_agent_parse(data, length, out_data, out_length, sourceip)
  417. X    register u_char    *data;
  418. X    int            length;
  419. X    register u_char    *out_data;
  420. X    int            *out_length;
  421. X    u_long        sourceip;    /* possibly for authentication */
  422. X{
  423. X    u_char        msg_type, type;
  424. X    long        zero = 0;
  425. X    long        reqid, errstat, errindex;
  426. X    register u_char *out_auth, *out_header, *out_reqid;
  427. X    u_char        *startData = data;
  428. X    int            startLength = length;
  429. X    long        version;
  430. X    int            header_shift, auth_shift;
  431. X
  432. X    sidlen = SID_MAX_LEN;
  433. X    data = snmp_auth_parse(data, &length, sid, &sidlen, &version); /* authenticates message and returns length if valid */
  434. X    if (data == NULL){
  435. X    ERROR("bad authentication");
  436. X    /* send auth fail trap */
  437. X    return 0;
  438. X    }
  439. X    if (version != SNMP_VERSION_1){
  440. X    ERROR("wrong version");
  441. X    return NULL;
  442. X    }
  443. X    community = get_community(sid);
  444. X    if (community == -1)
  445. X    return NULL;
  446. X    data = asn_parse_header(data, &length, &msg_type);
  447. X    if (data == NULL){
  448. X    ERROR("bad header");
  449. X    return 0;
  450. X    }
  451. X    if (msg_type != GET_REQ_MSG && msg_type != GETNEXT_REQ_MSG && msg_type != SET_REQ_MSG){
  452. X    return 0;
  453. X    }
  454. X    data = asn_parse_int(data, &length, &type, &reqid, sizeof(reqid));
  455. X    if (data == NULL){
  456. X    ERROR("bad parse of reqid");
  457. X    return 0;
  458. X    }
  459. X
  460. X    data = asn_parse_int(data, &length, &type, &errstat, sizeof(errstat));
  461. X    if (data == NULL){
  462. X    ERROR("bad parse of errstat");
  463. X    return 0;
  464. X    }
  465. X        data = asn_parse_int(data, &length, &type, &errindex, sizeof(errindex));
  466. X    if (data == NULL){
  467. X    ERROR("bad parse of errindex");
  468. X    return 0;
  469. X    }
  470. X    /*
  471. X     * Now start cobbling together what is known about the output packet.
  472. X     * The final lengths are not known now, so they will have to be recomputed
  473. X     * later.
  474. X     */
  475. X    out_auth = out_data;
  476. X    out_header = snmp_auth_build(out_auth, out_length, sid, &sidlen, &zero, 0);
  477. X    if (out_header == NULL){
  478. X    ERROR("snmp_auth_build failed");
  479. X    return 0;
  480. X    }
  481. X    out_reqid = asn_build_header(out_header, out_length, (u_char)GET_RSP_MSG, 0);
  482. X    if (out_reqid == NULL){
  483. X    ERROR("");
  484. X    return 0;
  485. X    }
  486. X
  487. X    type = (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER);
  488. X    /* return identical request id */
  489. X    out_data = asn_build_int(out_reqid, out_length, type, &reqid, sizeof(reqid));
  490. X    if (out_data == NULL){
  491. X    ERROR("build reqid failed");
  492. X    return 0;
  493. X    }
  494. X
  495. X    /* assume that error status will be zero */
  496. X    out_data = asn_build_int(out_data, out_length, type, &zero, sizeof(zero));
  497. X    if (out_data == NULL){
  498. X    ERROR("build errstat failed");
  499. X    return 0;
  500. X    }
  501. X
  502. X    /* assume that error index will be zero */
  503. X    out_data = asn_build_int(out_data, out_length, type, &zero, sizeof(zero));
  504. X    if (out_data == NULL){
  505. X    ERROR("build errindex failed");
  506. X    return 0;
  507. X    }
  508. X    errstat = parse_var_op_list(data, length, out_data, *out_length, msg_type, &errindex, 0);
  509. X    if (msg_type == SET_REQ_MSG && errstat == SNMP_ERR_NOERROR){
  510. X    /*
  511. X     * SETS require 2 passes through the var_op_list.  The first pass verifies that
  512. X     * all types, lengths, and values are valid, and the second does the set.  Then
  513. X     * the identical GET RESPONSE packet is returned.
  514. X     */
  515. X    errstat = parse_var_op_list(data, length, out_data, *out_length, msg_type, &errindex, 1);
  516. X    if (create_identical(startData, out_auth, startLength, 0L, 0L)) {
  517. X        *out_length = packet_end - out_auth;  /* AU: Have to set this! */
  518. X        return 1;
  519. X    }
  520. X    return 0;
  521. X    }
  522. X    switch((short)errstat){
  523. X    case SNMP_ERR_NOERROR:
  524. X        /*
  525. X         * Because of the assumption above that header lengths would be encoded
  526. X         * in one byte, things need to be fixed, now that the actual lengths are known.
  527. X         */
  528. X        header_shift = 0;
  529. X        *out_length = packet_end - out_reqid;
  530. X        if (*out_length >= 0x80){
  531. X        header_shift++;
  532. X        if (*out_length > 0xFF)
  533. X            header_shift++;
  534. X        }
  535. X        auth_shift = 0;
  536. X        *out_length = (packet_end - out_auth) - 2 + header_shift;
  537. X        if (*out_length >= 0x80){
  538. X        auth_shift++;
  539. X        if (*out_length > 0xFF)
  540. X            auth_shift++;
  541. X        }
  542. X        if (auth_shift + header_shift){
  543. X        /*
  544. X         * Shift packet (from request id to end of packet) by the sum of the
  545. X         * necessary shift counts.
  546. X         */
  547. X        shift_array(out_reqid, packet_end - out_reqid, auth_shift + header_shift);
  548. X        /* Now adjust pointers into the packet */
  549. X        packet_end += auth_shift + header_shift;
  550. X        out_reqid += auth_shift + header_shift;
  551. X        out_header += auth_shift;
  552. X        }
  553. X        
  554. X        /* re-encode the headers with the real lengths */
  555. X        out_data = out_header;
  556. X        *out_length = packet_end - out_reqid;
  557. X        out_data = asn_build_header(out_data, out_length, GET_RSP_MSG, *out_length);
  558. X        if (out_data != out_reqid){
  559. X        ERROR("internal error: header");
  560. X        return 0;
  561. X        }
  562. X
  563. X        out_data = out_auth;
  564. X        *out_length = packet_end - out_auth;
  565. X        out_data = snmp_auth_build(out_data, out_length, sid, &sidlen, &zero, packet_end - out_header);
  566. X        if (out_data != out_header){
  567. X        ERROR("internal error");
  568. X        return 0;
  569. X        }
  570. X        break;
  571. X    case SNMP_ERR_NOSUCHNAME:
  572. X    case SNMP_ERR_TOOBIG:
  573. X    case SNMP_ERR_BADVALUE:
  574. X    case SNMP_ERR_READONLY:
  575. X    case SNMP_ERR_GENERR:
  576. X        if (create_identical(startData, out_auth, startLength, errstat, errindex))
  577. X        break;
  578. X        return 0;
  579. X    default:
  580. X        return 0;
  581. X    }
  582. X    *out_length = packet_end - out_auth;
  583. X    return 1;
  584. X}
  585. X
  586. X/*
  587. X * Parse_var_op_list goes through the list of variables and retrieves each one,
  588. X * placing it's value in the output packet.  If doSet is non-zero, the variable is set
  589. X * with the value in the packet.  If any error occurs, an error code is returned.
  590. X */
  591. Xint
  592. Xparse_var_op_list(data, length, out_data, out_length, msgtype, index, doSet)
  593. X    register u_char    *data;
  594. X    int            length;
  595. X    register u_char    *out_data;
  596. X    int            out_length;
  597. X    u_char        msgtype;
  598. X    register long    *index;
  599. X    int            doSet;
  600. X{
  601. X    u_char  type;
  602. X    oid        var_name[MAX_NAME_LEN];
  603. X    int        var_name_len, var_val_len;
  604. X    u_char  var_val_type, *var_val, statType;
  605. X    u_char far *statP;
  606. X    int        statLen;
  607. X    u_short acl;
  608. X    int        rw, exact;
  609. X    int        (*write_method)();
  610. X    u_char  *headerP, *var_list_start;
  611. X    int        dummyLen;
  612. X    int        header_shift;
  613. X    u_char far *getStatPtr();
  614. X
  615. X    if (msgtype == SET_REQ_MSG)
  616. X    rw = WRITE;
  617. X    else
  618. X    rw = READ;
  619. X    if (msgtype == GETNEXT_REQ_MSG)
  620. X    exact = FALSE;
  621. X    else
  622. X    exact = TRUE;
  623. X    data = asn_parse_header(data, &length, &type);
  624. X    if (data == NULL){
  625. X    ERROR("not enough space for varlist");
  626. X    return PARSE_ERROR;
  627. X    }
  628. X    if (type != (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR)){
  629. X    ERROR("wrong type");
  630. X    return PARSE_ERROR;
  631. X    }
  632. X    headerP = out_data;
  633. X    out_data = asn_build_header(out_data, &out_length, (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR), 0);
  634. X    if (out_data == NULL){
  635. X        ERROR("not enough space in output packet");
  636. X    return BUILD_ERROR;
  637. X    }
  638. X    var_list_start = out_data;
  639. X
  640. X    *index = 1;
  641. X    while((int)length > 0){
  642. X    /* parse the name, value pair */
  643. X    var_name_len = MAX_NAME_LEN;
  644. X    data = snmp_parse_var_op(data, var_name, &var_name_len, &var_val_type, &var_val_len, &var_val, (int *)&length);
  645. X    if (data == NULL)
  646. X        return PARSE_ERROR;
  647. X    /* now attempt to retrieve the variable on the local entity */
  648. X    statP = getStatPtr(var_name, &var_name_len, &statType, &statLen, &acl, exact, &write_method);
  649. X    if (statP == NULL)
  650. X        return SNMP_ERR_NOSUCHNAME;
  651. X    /* Check if this user has access rights to this variable */
  652. X    if (!snmp_access(acl, community, rw))
  653. X        return SNMP_ERR_NOSUCHNAME;    /* bogus */
  654. X    if (msgtype == SET_REQ_MSG){
  655. X        if (write_method == 0){
  656. X        /* see if the type and value is consistent with this entities variable */
  657. X        if (!goodValue(var_val_type, var_val_len, statType, statLen)){
  658. X            return SNMP_ERR_BADVALUE;
  659. X        }
  660. X        /* actually do the set if necessary */
  661. X        if (doSet)
  662. X            setVariable(var_val, var_val_type, var_val_len, statP, statLen);
  663. X        } else {
  664. X        if (!(*write_method)(doSet, var_val, var_val_type, var_val_len, statP))
  665. X            return SNMP_ERR_BADVALUE;
  666. X        }
  667. X    }
  668. X    /* retrieve the value of the variable and place it into the outgoing packet */
  669. X    out_data = snmp_build_var_op(out_data, var_name, &var_name_len, statType, statLen, statP, &out_length);
  670. X    if (out_data == NULL){
  671. X        return SNMP_ERR_TOOBIG;
  672. X    }
  673. X
  674. X    (*index)++;
  675. X    }
  676. X    packet_end = out_data;  /* save a pointer to the end of the packet */
  677. X
  678. X    /*
  679. X     * Because of the assumption above that header lengths would be encoded
  680. X     * in one byte, things need to be fixed, now that the actual lengths are known.
  681. X     */
  682. X    header_shift = 0;
  683. X    out_length = packet_end - var_list_start;
  684. X    if (out_length >= 0x80){
  685. X    header_shift++;
  686. X    if (out_length > 0xFF)
  687. X        header_shift++;
  688. X    }
  689. X    if (header_shift){
  690. X    shift_array(var_list_start, packet_end - var_list_start, header_shift);
  691. X    packet_end += header_shift;
  692. X    var_list_start += header_shift;
  693. X    }
  694. X
  695. X    /* Now rebuild header with the actual lengths */
  696. X    dummyLen = packet_end - var_list_start;
  697. X    if (asn_build_header(headerP, &dummyLen, (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR), dummyLen) == NULL){
  698. X    return SNMP_ERR_TOOBIG;    /* bogus error ???? */
  699. X    }
  700. X    *index = 0;
  701. X    return SNMP_ERR_NOERROR;
  702. X}
  703. X
  704. X/*
  705. X * create a packet identical to the input packet, except for the error status
  706. X * and the error index which are set according to the input variables.
  707. X * Returns 1 upon success and 0 upon failure.
  708. X */
  709. Xint
  710. Xcreate_identical(snmp_in, snmp_out, snmp_length, errstat, errindex)
  711. X    u_char        *snmp_in;
  712. X    u_char        *snmp_out;
  713. X    int            snmp_length;
  714. X    long        errstat, errindex;
  715. X{
  716. X    register u_char *data;
  717. X    u_char        type;
  718. X    u_long        dummy;
  719. X    int            length, headerLength;
  720. X    register u_char *headerPtr, *reqidPtr, *errstatPtr, *errindexPtr, *varListPtr;
  721. X
  722. X    bcopy((char far *)snmp_in, (char far *)snmp_out, snmp_length);
  723. X    length = snmp_length;
  724. X    headerPtr = snmp_auth_parse(snmp_out, &length, sid, &sidlen, (long *)&dummy);
  725. X    if (headerPtr == NULL)
  726. X    return 0;
  727. X    reqidPtr = asn_parse_header(headerPtr, &length, (u_char *)&dummy);
  728. X    if (reqidPtr == NULL)
  729. X    return 0;
  730. X    headerLength = length;
  731. X    errstatPtr = asn_parse_int(reqidPtr, &length, &type, (long *)&dummy, sizeof dummy);    /* request id */
  732. X    if (errstatPtr == NULL)
  733. X    return 0;
  734. X    errindexPtr = asn_parse_int(errstatPtr, &length, &type, (long *)&dummy, sizeof dummy);    /* error status */
  735. X    if (errindexPtr == NULL)
  736. X    return 0;
  737. X    varListPtr = asn_parse_int(errindexPtr, &length, &type, (long *)&dummy, sizeof dummy);    /* error index */
  738. X    if (varListPtr == NULL)
  739. X    return 0;
  740. X
  741. X    data = asn_build_header(headerPtr, &headerLength, GET_RSP_MSG, headerLength);
  742. X    if (data != reqidPtr)
  743. X    return 0;
  744. X    length = snmp_length;
  745. X    type = (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER);
  746. X    data = asn_build_int(errstatPtr, &length, type, &errstat, sizeof errstat);
  747. X    if (data != errindexPtr)
  748. X    return 0;
  749. X    data = asn_build_int(errindexPtr, &length, type, &errindex, sizeof errindex);
  750. X    if (data != varListPtr)
  751. X    return 0;
  752. X    packet_end = snmp_out + snmp_length;
  753. X    return 1;
  754. X}
  755. X
  756. X#ifdef KINETICS
  757. Xstruct pbuf *
  758. XdefinitelyGetBuf(){
  759. X    register struct pbuf *p;
  760. X
  761. X    K_PGET(PT_DATA, p);
  762. X    while(p == 0){
  763. X#ifdef notdef
  764. X    if (pq->pq_head != NULL){
  765. X        K_PDEQ(SPLIMP, pq, p);
  766. X        if (p) K_PFREE(p);
  767. X    } else if (sendq->pq_head != NULL){
  768. X        K_PDEQ(SPLIMP, sendq, p);
  769. X        if (p) K_PFREE(p);
  770. X    }
  771. X#endif
  772. X    K_PGET(PT_DATA, p);
  773. X    }
  774. X    return p;
  775. X}
  776. X#endif
  777. X
  778. Xint
  779. Xsnmp_access(acl, community, rw)
  780. X    u_short     acl;
  781. X    int        community;
  782. X    int        rw;
  783. X{
  784. X    /*
  785. X     * Each group has 2 bits, the more significant one is for read access,
  786. X     * the less significant one is for write access.
  787. X     */
  788. X
  789. X    community <<= 1;    /* multiply by two two shift two bits at a time */
  790. X    if (rw == READ){
  791. X    return (acl & (2 << community));    /* return the correct bit */
  792. X    } else {
  793. X    return (acl & (1 << community));
  794. X    }
  795. X}
  796. X
  797. Xint
  798. Xget_community(sessionid)
  799. X    u_char    *sessionid;
  800. X{
  801. X    int    count;
  802. X
  803. X    for(count = 0; count < NUM_COMMUNITIES; count++){
  804. X    if (!strcmp(communities[count], (char *)sessionid))
  805. X        break;
  806. X    }
  807. X    if (count == NUM_COMMUNITIES)
  808. X    return -1;
  809. X    return count;
  810. X}
  811. X
  812. Xint
  813. XgoodValue(inType, inLen, actualType, actualLen)
  814. X    u_char    inType, actualType;
  815. X    int        inLen, actualLen;
  816. X{
  817. X    if (inLen > actualLen)
  818. X    return FALSE;
  819. X    return (inType == actualType);
  820. X}
  821. X
  822. XsetVariable(var_val, var_val_type, var_val_len, statP, statLen)
  823. X    u_char  *var_val;
  824. X    u_char  var_val_type;
  825. X    int        var_val_len;
  826. X    u_char far *statP;
  827. X    int        statLen;
  828. X{
  829. X    int        buffersize = 1000;
  830. X
  831. X    switch(var_val_type){
  832. X    case ASN_INTEGER:
  833. X    case COUNTER:
  834. X    case GAUGE:
  835. X    case TIMETICKS:
  836. X        asn_parse_int(var_val, &buffersize, &var_val_type, (long *)statP, statLen);
  837. X        break;
  838. X    case ASN_OCTET_STR:
  839. X    case IPADDRESS:
  840. X    case OPAQUE:
  841. X        asn_parse_string(var_val, &buffersize, &var_val_type, statP, &statLen);
  842. X        break;
  843. X    case ASN_OBJECT_ID:
  844. X        asn_parse_objid(var_val, &buffersize, &var_val_type, (oid *)statP, &statLen);
  845. X        break;
  846. X    }
  847. X}
  848. X
  849. X
  850. END_OF_FILE
  851.   if test 18099 -ne `wc -c <'netramet/src/apps/snmpagnt.c'`; then
  852.     echo shar: \"'netramet/src/apps/snmpagnt.c'\" unpacked with wrong size!
  853.   fi
  854.   # end of 'netramet/src/apps/snmpagnt.c'
  855. fi
  856. if test -f 'netramet/src/snmplib/mib.c' -a "${1}" != "-c" ; then 
  857.   echo shar: Will not clobber existing file \"'netramet/src/snmplib/mib.c'\"
  858. else
  859.   echo shar: Extracting \"'netramet/src/snmplib/mib.c'\" \(17927 characters\)
  860.   sed "s/^X//" >'netramet/src/snmplib/mib.c' <<'END_OF_FILE'
  861. X/***********************************************************
  862. X    Copyright 1988, 1989 by Carnegie Mellon University
  863. X
  864. X                      All Rights Reserved
  865. X
  866. XPermission to use, copy, modify, and distribute this software and its 
  867. Xdocumentation for any purpose and without fee is hereby granted, 
  868. Xprovided that the above copyright notice appear in all copies and that
  869. Xboth that copyright notice and this permission notice appear in 
  870. Xsupporting documentation, and that the name of CMU not be
  871. Xused in advertising or publicity pertaining to distribution of the
  872. Xsoftware without specific, written prior permission.  
  873. X
  874. XCMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  875. XALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  876. XCMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  877. XANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  878. XWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  879. XARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  880. XSOFTWARE.
  881. X******************************************************************/
  882. X#include <stdio.h>
  883. X#include <ctype.h>
  884. X#include <sys/types.h>
  885. X#include <netinet/in.h>
  886. X#include <sys/time.h>
  887. X#include "ausnmp.h"
  888. X#include "asn1.h"
  889. X#include "snmpimpl.h"
  890. X#include "snmpapi.h"
  891. X#include "parse.h"
  892. X
  893. Xstatic void sprint_by_type();
  894. X
  895. Xstatic char *
  896. XuptimeString(timeticks, buf)
  897. X    register long timeticks;
  898. X    char *buf;
  899. X{
  900. X    int    seconds, minutes, hours, days;
  901. X
  902. X    timeticks /= 100;
  903. X    days = timeticks / (60 * 60 * 24);
  904. X    timeticks %= (60 * 60 * 24);
  905. X
  906. X    hours = timeticks / (60 * 60);
  907. X    timeticks %= (60 * 60);
  908. X
  909. X    minutes = timeticks / 60;
  910. X    seconds = timeticks % 60;
  911. X
  912. X    if (days == 0){
  913. X    sprintf(buf, "%d:%02d:%02d", hours, minutes, seconds);
  914. X    } else if (days == 1) {
  915. X    sprintf(buf, "%d day, %d:%02d:%02d", days, hours, minutes, seconds);
  916. X    } else {
  917. X    sprintf(buf, "%d days, %d:%02d:%02d", days, hours, minutes, seconds);
  918. X    }
  919. X    return buf;
  920. X}
  921. X
  922. Xstatic sprint_hexstring(buf, cp, len)
  923. X    char *buf;
  924. X    u_char  *cp;
  925. X    int        len;
  926. X{
  927. X
  928. X    for(; len >= 16; len -= 16){
  929. 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]);
  930. X    buf += strlen(buf);
  931. X    cp += 8;
  932. 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]);
  933. X    buf += strlen(buf);
  934. X    cp += 8;
  935. X    }
  936. X    for(; len > 0; len--){
  937. X    sprintf(buf, "%02X ", *cp++);
  938. X    buf += strlen(buf);
  939. X    }
  940. X    *buf = '\0';
  941. X}
  942. X
  943. Xstatic sprint_asciistring(buf, cp, len)
  944. X    char *buf;
  945. X    u_char  *cp;
  946. X    int        len;
  947. X{
  948. X    int    x;
  949. X
  950. X    for(x = 0; x < len; x++){
  951. X    if (isprint(*cp)){
  952. X        *buf++ = *cp++;
  953. X    } else {
  954. X        *buf++ = '.';
  955. X        cp++;
  956. X    }
  957. X    if ((x % 48) == 47)
  958. X        *buf++ = '\n';
  959. X    }
  960. X    *buf = '\0';
  961. X}
  962. X
  963. X#ifdef UNUSED
  964. Xint
  965. Xread_rawobjid(input, output, out_len)
  966. X    char *input;
  967. X    oid *output;
  968. X    int    *out_len;
  969. X{
  970. X    char    buf[12], *cp;
  971. X    oid        *op = output;
  972. X    u_long  subid;
  973. X
  974. X    while(*input != '\0'){
  975. X    if (!isdigit(*input))
  976. X        break;
  977. X    cp = buf;
  978. X    while(isdigit(*input))
  979. X        *cp++ = *input++;
  980. X    *cp = '\0';
  981. X    subid = atoi(buf);
  982. X    if(subid > MAX_SUBID){
  983. X        fprintf(stderr, "sub-identifier too large: %s\n", buf);
  984. X        return 0;
  985. X    }
  986. X    if((*out_len)-- <= 0){
  987. X        fprintf(stderr, "object identifier too long\n");
  988. X        return 0;
  989. X    }
  990. X    *op++ = subid;
  991. X    if(*input++ != '.')
  992. X        break;
  993. X    }
  994. X    *out_len = op - output;
  995. X    if (*out_len == 0)
  996. X    return 0;
  997. X    return 1;
  998. X}
  999. X
  1000. X#endif /* UNUSED */
  1001. X
  1002. Xstatic void
  1003. Xsprint_octet_string(buf, var)
  1004. X    char *buf;
  1005. X    struct variable_list *var;
  1006. X{
  1007. X    int hex, x;
  1008. X    u_char *cp;
  1009. X
  1010. X    if (var->type != ASN_OCTET_STR){
  1011. X    sprintf(buf, "Wrong Type (should be OCTET STRING): ");
  1012. X    buf += strlen(buf);
  1013. X    sprint_by_type(buf, var, (struct enum_list *)NULL);
  1014. X    return;
  1015. X    }
  1016. X    hex = 0;
  1017. X    for(cp = var->val.string, x = 0; x < var->val_len; x++, cp++){
  1018. X    if (!(isprint(*cp) || isspace(*cp)))
  1019. X        hex = 1;
  1020. X    }
  1021. X    if (var->val_len <= 4)
  1022. X    hex = 1;    /* not likely to be ascii */
  1023. X    if (hex){
  1024. X    sprintf(buf, "OCTET STRING-   (hex):\t");
  1025. X    buf += strlen(buf);
  1026. X    sprint_hexstring(buf, var->val.string, var->val_len);
  1027. X    } else {
  1028. X    sprintf(buf, "OCTET STRING- (ascii):\t");
  1029. X    buf += strlen(buf);
  1030. X    sprint_asciistring(buf, var->val.string, var->val_len);
  1031. X    }
  1032. X}
  1033. X
  1034. Xstatic void
  1035. Xsprint_opaque(buf, var)
  1036. X    char *buf;
  1037. X    struct variable_list *var;
  1038. X{
  1039. X
  1040. X    if (var->type != OPAQUE){
  1041. X    sprintf(buf, "Wrong Type (should be Opaque): ");
  1042. X    buf += strlen(buf);
  1043. X    sprint_by_type(buf, var, (struct enum_list *)NULL);
  1044. X    return;
  1045. X    }
  1046. X    sprintf(buf, "OPAQUE -   (hex):\t");
  1047. X    buf += strlen(buf);
  1048. X    sprint_hexstring(buf, var->val.string, var->val_len);
  1049. X}
  1050. X
  1051. Xstatic void
  1052. Xsprint_object_identifier(buf, var)
  1053. X    char *buf;
  1054. X    struct variable_list *var;
  1055. X{
  1056. X    if (var->type != ASN_OBJECT_ID){
  1057. X    sprintf(buf, "Wrong Type (should be OBJECT IDENTIFIER): ");
  1058. X    buf += strlen(buf);
  1059. X    sprint_by_type(buf, var, (struct enum_list *)NULL);
  1060. X    return;
  1061. X    }
  1062. X    sprintf(buf, "OBJECT IDENTIFIER:\t");
  1063. X    buf += strlen(buf);
  1064. X    sprint_objid(buf, (oid *)(var->val.objid), var->val_len / sizeof(oid));
  1065. X}
  1066. X
  1067. Xstatic void
  1068. Xsprint_timeticks(buf, var)
  1069. X    char *buf;
  1070. X    struct variable_list *var;
  1071. X{
  1072. X    char timebuf[32];
  1073. X
  1074. X    if (var->type != TIMETICKS){
  1075. X    sprintf(buf, "Wrong Type (should be Timeticks): ");
  1076. X    buf += strlen(buf);
  1077. X    sprint_by_type(buf, var, (struct enum_list *)NULL);
  1078. X    return;
  1079. X    }
  1080. X    sprintf(buf, "Timeticks: (%d) %s", *(var->val.integer), uptimeString(*(var->val.integer), timebuf));
  1081. X}
  1082. X
  1083. Xstatic void
  1084. Xsprint_integer(buf, var, enums)
  1085. X    char *buf;
  1086. X    struct variable_list *var;
  1087. X    struct enum_list        *enums;
  1088. X{
  1089. X    char    *enum_string = NULL;
  1090. X
  1091. X    if (var->type != ASN_INTEGER){
  1092. X    sprintf(buf, "Wrong Type (should be INTEGER): ");
  1093. X    buf += strlen(buf);
  1094. X    sprint_by_type(buf, var, (struct enum_list *)NULL);
  1095. X    return;
  1096. X    }
  1097. X    for (; enums; enums = enums->next)
  1098. X    if (enums->value == *var->val.integer){
  1099. X        enum_string = enums->label;
  1100. X        break;
  1101. X    }
  1102. X    if (enum_string == NULL)
  1103. X    sprintf(buf, "INTEGER: %d", *var->val.integer);
  1104. X    else
  1105. X    sprintf(buf, "INTEGER: %s(%d)", enum_string, *var->val.integer);
  1106. X}
  1107. X
  1108. Xstatic void
  1109. Xsprint_gauge(buf, var)
  1110. X    char *buf;
  1111. X    struct variable_list *var;
  1112. X{
  1113. X    if (var->type != GAUGE){
  1114. X    sprintf(buf, "Wrong Type (should be Gauge): ");
  1115. X    buf += strlen(buf);
  1116. X    sprint_by_type(buf, var, (struct enum_list *)NULL);
  1117. X    return;
  1118. X    }
  1119. X    sprintf(buf, "Gauge: %lu", *var->val.integer);
  1120. X}
  1121. X
  1122. Xstatic void
  1123. Xsprint_counter(buf, var)
  1124. X    char *buf;
  1125. X    struct variable_list *var;
  1126. X{
  1127. X    if (var->type != COUNTER){
  1128. X    sprintf(buf, "Wrong Type (should be Counter): ");
  1129. X    buf += strlen(buf);
  1130. X    sprint_by_type(buf, var, (struct enum_list *)NULL);
  1131. X    return;
  1132. X    }
  1133. X    sprintf(buf, "Counter: %lu", *var->val.integer);
  1134. X}
  1135. X
  1136. Xstatic void
  1137. Xsprint_networkaddress(buf, var)
  1138. X    char *buf;
  1139. X    struct variable_list *var;
  1140. X{
  1141. X    int x, len;
  1142. X    u_char *cp;
  1143. X
  1144. X    sprintf(buf, "Network Address:\t");
  1145. X    buf += strlen(buf);
  1146. X    cp = var->val.string;    
  1147. X    len = var->val_len;
  1148. X    for(x = 0; x < len; x++){
  1149. X    sprintf(buf, "%02X", *cp++);
  1150. X    buf += strlen(buf);
  1151. X    if (x < (len - 1))
  1152. X        *buf++ = ':';
  1153. X    }
  1154. X}
  1155. X
  1156. Xstatic void
  1157. Xsprint_ipaddress(buf, var)
  1158. X    char *buf;
  1159. X    struct variable_list *var;
  1160. X{
  1161. X    u_char *ip;
  1162. X
  1163. X    if (var->type != IPADDRESS){
  1164. X    sprintf(buf, "Wrong Type (should be Ipaddress): ");
  1165. X    buf += strlen(buf);
  1166. X    sprint_by_type(buf, var, (struct enum_list *)NULL);
  1167. X    return;
  1168. X    }
  1169. X    ip = var->val.string;
  1170. X    sprintf(buf, "IpAddress:\t%d.%d.%d.%d",ip[0], ip[1], ip[2], ip[3]);
  1171. X}
  1172. X
  1173. Xstatic void
  1174. Xsprint_unsigned_short(buf, var)
  1175. X    char *buf;
  1176. X    struct variable_list *var;
  1177. X{
  1178. X    if (var->type != ASN_INTEGER){
  1179. X    sprintf(buf, "Wrong Type (should be INTEGER): ");
  1180. X    buf += strlen(buf);
  1181. X    sprint_by_type(buf, var, (struct enum_list *)NULL);
  1182. X    return;
  1183. X    }
  1184. X    sprintf(buf, "INTEGER (0..65535): %lu", *var->val.integer);
  1185. X}
  1186. X
  1187. Xstatic void
  1188. Xsprint_null(buf, var)
  1189. X    char *buf;
  1190. X    struct variable_list *var;
  1191. X{
  1192. X    if (var->type != ASN_NULL){
  1193. X    sprintf(buf, "Wrong Type (should be NULL): ");
  1194. X    buf += strlen(buf);
  1195. X    sprint_by_type(buf, var, (struct enum_list *)NULL);
  1196. X    return;
  1197. X    }
  1198. X    sprintf(buf, "NULL");
  1199. X}
  1200. X
  1201. Xstatic void
  1202. Xsprint_unknowntype(buf, var)
  1203. X    char *buf;
  1204. X    struct variable_list *var;
  1205. X{
  1206. X/*    sprintf(buf, "Variable has bad type"); */
  1207. X    sprint_by_type(buf, var, NULL);
  1208. X}
  1209. X
  1210. Xstatic void
  1211. Xsprint_badtype(buf)
  1212. X    char *buf;
  1213. X{
  1214. X    sprintf(buf, "Variable has bad type");
  1215. X}
  1216. X
  1217. Xstatic void
  1218. Xsprint_by_type(buf, var, enums)
  1219. X    char *buf;
  1220. X    struct variable_list *var;
  1221. X    struct enum_list        *enums;
  1222. X{
  1223. X    switch (var->type){
  1224. X    case ASN_INTEGER:
  1225. X        sprint_integer(buf, var, enums);
  1226. X        break;
  1227. X    case ASN_OCTET_STR:
  1228. X        sprint_octet_string(buf, var);
  1229. X        break;
  1230. X    case OPAQUE:
  1231. X        sprint_opaque(buf, var);
  1232. X        break;
  1233. X    case ASN_OBJECT_ID:
  1234. X        sprint_object_identifier(buf, var);
  1235. X        break;
  1236. X    case TIMETICKS:
  1237. X        sprint_timeticks(buf, var);
  1238. X        break;
  1239. X    case GAUGE:
  1240. X        sprint_gauge(buf, var);
  1241. X        break;
  1242. X    case COUNTER:
  1243. X        sprint_counter(buf, var);
  1244. X        break;
  1245. X    case IPADDRESS:
  1246. X        sprint_ipaddress(buf, var);
  1247. X        break;
  1248. X    case ASN_NULL:
  1249. X        sprint_null(buf, var);
  1250. X        break;
  1251. X    default:
  1252. X        sprint_badtype(buf);
  1253. X        break;
  1254. X    }
  1255. X}
  1256. X
  1257. Xstruct tree *get_symbol();
  1258. X
  1259. Xoid RFC1066_MIB[] = { 1, 3, 6, 1, 2, 1 };
  1260. Xunsigned char RFC1066_MIB_text[] = ".iso.org.dod.internet.mgmt.mib";
  1261. Xstruct tree *Mib;
  1262. X
  1263. Xinit_mib()
  1264. X{
  1265. X    char *file, *getenv();
  1266. X
  1267. X    Mib = 0;
  1268. X    file = getenv("MIBFILE");
  1269. X    if (file)
  1270. X    Mib = read_mib(file);
  1271. X    if (!Mib)
  1272. X    Mib = read_mib("mib.txt");
  1273. X    if (!Mib)
  1274. X    Mib = read_mib("/etc/mib.txt");
  1275. X    if (!Mib){
  1276. X    fprintf(stderr, "Couldn't find mib file\n");
  1277. X    exit(2);
  1278. X    }
  1279. X    set_functions(Mib);
  1280. X}
  1281. X
  1282. Xstatic
  1283. Xset_functions(subtree)
  1284. X    struct tree *subtree;
  1285. X{
  1286. X    for(; subtree; subtree = subtree->next_peer){
  1287. X    switch(subtree->type){
  1288. X        case TYPE_OBJID:
  1289. X        subtree->printer = sprint_object_identifier;
  1290. X        break;
  1291. X        case TYPE_OCTETSTR:
  1292. X        subtree->printer = sprint_octet_string;
  1293. X        break;
  1294. X        case TYPE_INTEGER:
  1295. X        subtree->printer = sprint_integer;
  1296. X        break;
  1297. X        case TYPE_NETADDR:
  1298. X        subtree->printer = sprint_networkaddress;
  1299. X        break;
  1300. X        case TYPE_IPADDR:
  1301. X        subtree->printer = sprint_ipaddress;
  1302. X        break;
  1303. X        case TYPE_COUNTER:
  1304. X        subtree->printer = sprint_counter;
  1305. X        break;
  1306. X        case TYPE_GAUGE:
  1307. X        subtree->printer = sprint_gauge;
  1308. X        break;
  1309. X        case TYPE_TIMETICKS:
  1310. X        subtree->printer = sprint_timeticks;
  1311. X        break;
  1312. X        case TYPE_OPAQUE:
  1313. X        subtree->printer = sprint_opaque;
  1314. X        break;
  1315. X        case TYPE_NULL:
  1316. X        subtree->printer = sprint_null;
  1317. X        break;
  1318. X        case TYPE_OTHER:
  1319. X        default:
  1320. X        subtree->printer = sprint_unknowntype;
  1321. X        break;
  1322. X    }
  1323. X    set_functions(subtree->child_list);
  1324. X    }
  1325. X}
  1326. X
  1327. X#ifdef testing
  1328. Xint snmp_dump_packet = 0;
  1329. X
  1330. Xmain(argc, argv)
  1331. X     int argc;
  1332. X     char *argv[];
  1333. X{
  1334. X    oid objid[64];
  1335. X    int objidlen = sizeof (objid);
  1336. X    int count;
  1337. X    struct variable variable;
  1338. X
  1339. X    init_mib(&Mib);
  1340. X    if (argc < 2)
  1341. X    print_subtree(Mib, 0);
  1342. X    variable.type = ASN_INTEGER;
  1343. X    variable.val.integer = 3;
  1344. X    variable.val_len = 4;
  1345. X    for (argc--; argc; argc--, argv++) {
  1346. X    objidlen = sizeof (objid);
  1347. X    printf("read_objid(%s) = %d\n",
  1348. X           argv[1], read_objid(argv[1], objid, &objidlen));
  1349. X    for(count = 0; count < objidlen; count++)
  1350. X        printf("%d.", objid[count]);
  1351. X    printf("\n");
  1352. X    print_variable(objid, objidlen, &variable);
  1353. X    }
  1354. X}
  1355. X
  1356. X#endif testing
  1357. X
  1358. X
  1359. Xstatic struct tree *
  1360. Xfind_rfc1066_mib(root)
  1361. X    struct tree *root;
  1362. X{
  1363. X    oid *op = RFC1066_MIB;
  1364. X    struct tree *tp;
  1365. X    int len;
  1366. X
  1367. X    for(len = sizeof(RFC1066_MIB)/sizeof(oid); len; len--, op++){
  1368. X    for(tp = root; tp; tp = tp->next_peer){
  1369. X        if (tp->subid == *op){
  1370. X        root = tp->child_list;
  1371. X        break;
  1372. X        }
  1373. X    }
  1374. X    if (tp == NULL)
  1375. X        return NULL;
  1376. X    }
  1377. X    return root;
  1378. X}
  1379. X
  1380. Xint read_objid(input, output, out_len)
  1381. X    char *input;
  1382. X    oid *output;
  1383. X    int    *out_len;   /* number of subid's in "output" */
  1384. X{
  1385. X    struct tree *root = Mib;
  1386. X    oid *op = output;
  1387. X    int i;
  1388. X
  1389. X    if (*input == '.')
  1390. X    input++;
  1391. X    else {
  1392. X    root = find_rfc1066_mib(root);
  1393. X    for (i = 0; i < sizeof (RFC1066_MIB)/sizeof(oid); i++) {
  1394. X        if ((*out_len)-- > 0)
  1395. X        *output++ = RFC1066_MIB[i];
  1396. X        else {
  1397. X        fprintf(stderr, "object identifier too long\n");
  1398. X        return (0);
  1399. X        }
  1400. X    }
  1401. X    }
  1402. X
  1403. X    if (root == NULL){
  1404. X    fprintf(stderr, "Mib not initialized.  Exiting.\n");
  1405. X    exit(1);
  1406. X    }
  1407. X    if ((*out_len =
  1408. X     parse_subtree(root, input, output, out_len)) == 0)
  1409. X    return (0);
  1410. X    *out_len += output - op;
  1411. X
  1412. X    return (1);
  1413. X}
  1414. X
  1415. Xstatic
  1416. Xparse_subtree(subtree, input, output, out_len)
  1417. X    struct tree *subtree;
  1418. X    char *input;
  1419. X    oid    *output;
  1420. X    int    *out_len;   /* number of subid's */
  1421. X{
  1422. X    char buf[128], *to = buf;
  1423. X    u_long subid = 0;
  1424. X    struct tree *tp;
  1425. X
  1426. X    /*
  1427. X     * No empty strings.  Can happen if there is a trailing '.' or two '.'s
  1428. X     * in a row, i.e. "..".
  1429. X     */
  1430. X    if ((*input == '\0') ||
  1431. X    (*input == '.'))
  1432. X    return (0);
  1433. X
  1434. X    if (isdigit(*input)) {
  1435. X    /*
  1436. X     * Read the number, then try to find it in the subtree.
  1437. X     */
  1438. X    while (isdigit(*input)) {
  1439. X        subid *= 10;
  1440. X        subid += *input++ - '0';
  1441. X    }
  1442. X    for (tp = subtree; tp; tp = tp->next_peer) {
  1443. X        if (tp->subid == subid)
  1444. X        goto found;
  1445. X    }
  1446. X    tp = NULL;
  1447. X    }
  1448. X    else {
  1449. X    /*
  1450. X     * Read the name into a buffer.
  1451. X     */
  1452. X    while ((*input != '\0') &&
  1453. X           (*input != '.')) {
  1454. X        *to++ = *input++;
  1455. X    }
  1456. X    *to = '\0';
  1457. X
  1458. X    /*
  1459. X     * Find the name in the subtree;
  1460. X     */
  1461. X    for (tp = subtree; tp; tp = tp->next_peer) {
  1462. X        if (lc_cmp(tp->label, buf) == 0) {
  1463. X        subid = tp->subid;
  1464. X        goto found;
  1465. X        }
  1466. X    }
  1467. X
  1468. X    /*
  1469. X     * If we didn't find the entry, punt...
  1470. X     */
  1471. X    if (tp == NULL) {
  1472. X        fprintf(stderr, "sub-identifier not found: %s\n", buf);
  1473. X        return (0);
  1474. X    }
  1475. X    }
  1476. X
  1477. Xfound:
  1478. X    if(subid > (u_long)MAX_SUBID){
  1479. X    fprintf(stderr, "sub-identifier too large: %s\n", buf);
  1480. X    return (0);
  1481. X    }
  1482. X
  1483. X    if ((*out_len)-- <= 0){
  1484. X    fprintf(stderr, "object identifier too long\n");
  1485. X    return (0);
  1486. X    }
  1487. X    *output++ = subid;
  1488. X
  1489. X    if (*input != '.')
  1490. X    return (1);
  1491. X    if ((*out_len =
  1492. X     parse_subtree(tp ? tp->child_list : NULL, ++input, output, out_len)) == 0)
  1493. X    return (0);
  1494. X    return (++*out_len);
  1495. X}
  1496. X
  1497. Xprint_objid(objid, objidlen)
  1498. X    oid        *objid;
  1499. X    int        objidlen;    /* number of subidentifiers */
  1500. X{
  1501. X    char    buf[256];
  1502. X    struct tree    *subtree = Mib;
  1503. X
  1504. X    *buf = '.';    /* this is a fully qualified name */
  1505. X    get_symbol(objid, objidlen, subtree, buf + 1);
  1506. X    printf("%s\n", buf);
  1507. X        
  1508. X}
  1509. X
  1510. Xsprint_objid(buf, objid, objidlen)
  1511. X    char *buf;
  1512. X    oid        *objid;
  1513. X    int        objidlen;    /* number of subidentifiers */
  1514. X{
  1515. X    struct tree    *subtree = Mib;
  1516. X
  1517. X    *buf = '.';    /* this is a fully qualified name */
  1518. X    get_symbol(objid, objidlen, subtree, buf + 1);
  1519. X}
  1520. X
  1521. X
  1522. Xprint_variable(objid, objidlen, variable)
  1523. X    oid     *objid;
  1524. X    int        objidlen;
  1525. X    struct  variable_list *variable;
  1526. X{
  1527. X    char    buf[512], *cp;
  1528. X    struct tree    *subtree = Mib;
  1529. X
  1530. X    *buf = '.';    /* this is a fully qualified name */
  1531. X    subtree = get_symbol(objid, objidlen, subtree, buf + 1);
  1532. X    cp = buf;
  1533. X    if ((strlen(buf) >= strlen((char *)RFC1066_MIB_text)) && !bcmp(buf, (char *)RFC1066_MIB_text,
  1534. X    strlen((char *)RFC1066_MIB_text))){
  1535. X        cp += sizeof(RFC1066_MIB_text);
  1536. X    }
  1537. X    printf("Name: %s\n", cp);
  1538. X    *buf = '\0';
  1539. X    if (subtree->printer)
  1540. X    (*subtree->printer)(buf, variable, subtree->enums);
  1541. X    else {
  1542. X    sprint_by_type(buf, variable, subtree->enums);
  1543. X    }
  1544. X    printf("%s\n", buf);
  1545. X}
  1546. X
  1547. Xsprint_variable(buf, objid, objidlen, variable)
  1548. X    char *buf;
  1549. X    oid     *objid;
  1550. X    int        objidlen;
  1551. X    struct  variable_list *variable;
  1552. X{
  1553. X    char    tempbuf[512], *cp;
  1554. X    struct tree    *subtree = Mib;
  1555. X
  1556. X    *tempbuf = '.';    /* this is a fully qualified name */
  1557. X    subtree = get_symbol(objid, objidlen, subtree, tempbuf + 1);
  1558. X    cp = tempbuf;
  1559. X    if ((strlen(buf) >= strlen((char *)RFC1066_MIB_text)) && !bcmp(buf, (char *)RFC1066_MIB_text,
  1560. X    strlen((char *)RFC1066_MIB_text))){
  1561. X        cp += sizeof(RFC1066_MIB_text);
  1562. X    }
  1563. X    sprintf(buf, "Name: %s\n", cp);
  1564. X    buf += strlen(buf);
  1565. X    if (subtree->printer)
  1566. X    (*subtree->printer)(buf, variable, subtree->enums);
  1567. X    else {
  1568. X    sprint_by_type(buf, variable, subtree->enums);
  1569. X    }
  1570. X    strcat(buf, "\n");
  1571. X}
  1572. X
  1573. Xsprint_value(buf, objid, objidlen, variable)
  1574. X    char *buf;
  1575. X    oid     *objid;
  1576. X    int        objidlen;
  1577. X    struct  variable_list *variable;
  1578. X{
  1579. X    char    tempbuf[512];
  1580. X    struct tree    *subtree = Mib;
  1581. X
  1582. X    subtree = get_symbol(objid, objidlen, subtree, tempbuf);
  1583. X    if (subtree->printer)
  1584. X    (*subtree->printer)(buf, variable, subtree->enums);
  1585. X    else {
  1586. X    sprint_by_type(buf, variable, subtree->enums);
  1587. X    }
  1588. X}
  1589. X
  1590. Xprint_value(objid, objidlen, variable)
  1591. X    oid     *objid;
  1592. X    int        objidlen;
  1593. X    struct  variable_list *variable;
  1594. X{
  1595. X    char    tempbuf[512];
  1596. X    struct tree    *subtree = Mib;
  1597. X
  1598. X    subtree = get_symbol(objid, objidlen, subtree, tempbuf);
  1599. X    if (subtree->printer)
  1600. X    (*subtree->printer)(tempbuf, variable, subtree->enums);
  1601. X    else {
  1602. X    sprint_by_type(tempbuf, variable, subtree->enums);
  1603. X    }
  1604. X    printf("%s\n", tempbuf);
  1605. X}
  1606. X
  1607. Xstruct tree *
  1608. Xget_symbol(objid, objidlen, subtree, buf)
  1609. X    oid        *objid;
  1610. X    int        objidlen;
  1611. X    struct tree    *subtree;
  1612. X    char    *buf;
  1613. X{
  1614. X    struct tree    *return_tree = NULL;
  1615. X
  1616. X    for(; subtree; subtree = subtree->next_peer){
  1617. X    if (*objid == subtree->subid){
  1618. X        strcpy(buf, subtree->label);
  1619. X        goto found;
  1620. X    }
  1621. X    }
  1622. X
  1623. X    /* subtree not found */
  1624. X    while(objidlen--){    /* output rest of name, uninterpreted */
  1625. X    sprintf(buf, "%u.", *objid++);
  1626. X    while(*buf)
  1627. X        buf++;
  1628. X    }
  1629. X    *(buf - 1) = '\0'; /* remove trailing dot */
  1630. X    return NULL;
  1631. X
  1632. Xfound:
  1633. X    if (objidlen > 1){
  1634. X    while(*buf)
  1635. X        buf++;
  1636. X    *buf++ = '.';
  1637. X    *buf = '\0';
  1638. X    return_tree = get_symbol(objid + 1, objidlen - 1, subtree->child_list, buf);
  1639. X    } 
  1640. X    if (return_tree != NULL)
  1641. X    return return_tree;
  1642. X    else
  1643. X    return subtree;
  1644. X}
  1645. X
  1646. X
  1647. Xstatic int
  1648. Xlc_cmp(s1, s2)
  1649. X    char *s1, *s2;
  1650. X{
  1651. X    char c1, c2;
  1652. X
  1653. X    while(*s1 && *s2){
  1654. X    if (isupper(*s1))
  1655. X        c1 = tolower(*s1);
  1656. X    else
  1657. X        c1 = *s1;
  1658. X    if (isupper(*s2))
  1659. X        c2 = tolower(*s2);
  1660. X    else
  1661. X        c2 = *s2;
  1662. X    if (c1 != c2)
  1663. X        return ((c1 - c2) > 0 ? 1 : -1);
  1664. X    s1++;
  1665. X    s2++;
  1666. X    }
  1667. X
  1668. X    if (*s1)
  1669. X    return -1;
  1670. X    if (*s2)
  1671. X    return 1;
  1672. X    return 0;
  1673. X}
  1674. X
  1675. END_OF_FILE
  1676.   if test 17927 -ne `wc -c <'netramet/src/snmplib/mib.c'`; then
  1677.     echo shar: \"'netramet/src/snmplib/mib.c'\" unpacked with wrong size!
  1678.   fi
  1679.   # end of 'netramet/src/snmplib/mib.c'
  1680. fi
  1681. if test -f 'netramet/src/snmplib/snmpagnt.c' -a "${1}" != "-c" ; then 
  1682.   echo shar: Will not clobber existing file \"'netramet/src/snmplib/snmpagnt.c'\"
  1683. else
  1684.   echo shar: Extracting \"'netramet/src/snmplib/snmpagnt.c'\" \(18099 characters\)
  1685.   sed "s/^X//" >'netramet/src/snmplib/snmpagnt.c' <<'END_OF_FILE'
  1686. X/*
  1687. X * Simple Network Management Protocol (RFC 1067).
  1688. X *
  1689. X */
  1690. X/***********************************************************
  1691. X    Copyright 1988, 1989 by Carnegie Mellon University
  1692. X
  1693. X                      All Rights Reserved
  1694. X
  1695. XPermission to use, copy, modify, and distribute this software and its 
  1696. Xdocumentation for any purpose and without fee is hereby granted, 
  1697. Xprovided that the above copyright notice appear in all copies and that
  1698. Xboth that copyright notice and this permission notice appear in 
  1699. Xsupporting documentation, and that the name of CMU not be
  1700. Xused in advertising or publicity pertaining to distribution of the
  1701. Xsoftware without specific, written prior permission.  
  1702. X
  1703. XCMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  1704. XALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  1705. XCMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  1706. XANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  1707. XWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  1708. XARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  1709. XSOFTWARE.
  1710. X******************************************************************/
  1711. X
  1712. X#include "ausnmp.h"
  1713. X
  1714. X#ifdef KINETICS
  1715. X#include "gw.h"
  1716. X#include "ab.h"
  1717. X#include "inet.h"
  1718. X#include "fp4/cmdmacro.h"
  1719. X#include "fp4/pbuf.h"
  1720. X#include "glob.h"
  1721. X#endif
  1722. X
  1723. X#if (defined(unix) && !defined(KINETICS))
  1724. X#include <sys/types.h>
  1725. X#include <netinet/in.h>
  1726. X#ifndef NULL
  1727. X#define NULL 0
  1728. X#endif
  1729. X#endif
  1730. X
  1731. X#include "snmp.h"
  1732. X#include "snmpimpl.h"  /* AU */
  1733. X#include "asn1.h"
  1734. X
  1735. X#include "mib.h"
  1736. X
  1737. Xvoid    snmp_input();
  1738. Xvoid    snmp_trap();
  1739. Xint    create_identical();
  1740. Xint    parse_var_op_list();
  1741. Xint    snmp_access();
  1742. X
  1743. X#if kinetics
  1744. Xchar    version_descr[];
  1745. Xoid    version_id[];
  1746. Xint    version_id_len;
  1747. X#endif
  1748. X
  1749. Xstruct pbuf *definitelyGetBuf();
  1750. X
  1751. X#define NUM_COMMUNITIES    5
  1752. Xchar    *communities[NUM_COMMUNITIES] = {
  1753. X    "public", 
  1754. X    "proxy",
  1755. X    "private",
  1756. X    "regional",
  1757. X    "core"
  1758. X};
  1759. X
  1760. X/* these can't be global in a multi-process router */
  1761. X    u_char    sid[SID_MAX_LEN + 1];
  1762. X    int        sidlen;
  1763. X    u_char    *packet_end;
  1764. X    int        community;
  1765. X
  1766. X
  1767. X#ifdef KINETICS
  1768. Xvoid
  1769. Xsnmp_input(p)
  1770. X    struct pbuf *p;
  1771. X{
  1772. X    struct ip        *ip = (struct ip *)p->p_off;
  1773. X    int            hlen = (int)ip->ip_hl << 2;
  1774. X    register struct udp        *udp;
  1775. X    register u_char *data;  /* pointer to the rest of the unread data */
  1776. X    int            length; /* bytes of data left in msg after the "data" pointer */
  1777. X    struct pbuf        *out_packet;
  1778. X    register u_char *out_data;
  1779. X    int            out_length;
  1780. X    u_short        udp_src;
  1781. X    extern struct mib_udp   mib_udp;
  1782. X
  1783. X    
  1784. X    udp = (struct udp *)(p->p_off + hlen);
  1785. X    if (ntohs(ip->ip_len) - hlen < sizeof(struct udp) ||    /* IP length < minimum UDP packet */
  1786. X        ntohs(udp->length) > ntohs(ip->ip_len) - hlen){ /* UDP length > IP data */
  1787. X    ERROR("dropped packet with bad length");    /* delete me */
  1788. X    return; /* drop packet */
  1789. X    }
  1790. X    data = (u_char *)udp + sizeof(struct udp);
  1791. X    length = ntohs(udp->length) - sizeof(struct udp);
  1792. X
  1793. X    out_packet = definitelyGetBuf(); /* drop packets off input queue if necessary */
  1794. X    out_data = (u_char *)(out_packet->p_off + sizeof (struct ip) + sizeof (struct udp));
  1795. X    out_length = MAXDATA - sizeof(struct ip) - sizeof (struct udp);
  1796. X
  1797. XK_LEDON();
  1798. X    if (!snmp_agent_parse(data, length, out_data, &out_length, (u_long)ip->ip_src)){
  1799. X    K_PFREE(out_packet);
  1800. XK_LEDOFF();
  1801. X    return;
  1802. X    }
  1803. XK_LEDOFF();
  1804. X    out_packet->p_len = packet_end - (u_char *)out_packet->p_off;
  1805. X    setiphdr(out_packet, ip->ip_src);    /* address to source of request packet (ntohl ??? ) */
  1806. X    udp_src = ntohs(udp->src);
  1807. X    udp = (struct udp *)(out_packet->p_off + sizeof (struct ip));
  1808. X    udp->src = htons(SNMP_PORT);
  1809. X    udp->dst = htons(udp_src);
  1810. X    udp->length = out_packet->p_len - sizeof(struct ip);
  1811. X    udp->checksum = 0;    /* this should be computed */
  1812. X
  1813. X    mib_udp.udpOutDatagrams++;
  1814. X    routeip(out_packet, 0, 0);
  1815. X}
  1816. X
  1817. X
  1818. Xvoid
  1819. Xsnmp_trap(destAddr, trapType, specificType)
  1820. X    u_long  destAddr;
  1821. X    int        trapType;
  1822. X    int        specificType;
  1823. X{
  1824. X    struct pbuf        *out_packet;
  1825. X    register u_char *out_data;
  1826. X    register struct udp        *udp;
  1827. X    int            out_length;
  1828. X    static oid        sysDescrOid[] = {1, 3, 6, 1, 2, 1, 1, 1, 0};
  1829. X    
  1830. X    out_packet = definitelyGetBuf(); /* drop packets off input queue if necessary */
  1831. X    out_data = (u_char *)(out_packet->p_off + sizeof (struct ip) + sizeof (struct udp));
  1832. X    out_length = MAXDATA - sizeof(struct ip) - sizeof (struct udp);
  1833. X
  1834. XK_LEDON();
  1835. X    out_packet->p_len = snmp_build_trap(out_data, out_length, version_id, version_id_len,
  1836. X    conf.ipaddr, trapType, specificType, TICKS2MS(tickclock)/10, sysDescrOid, sizeof(sysDescrOid)/sizeof(oid),
  1837. X    ASN_OCTET_STR, strlen(version_descr), (u_char *)version_descr);
  1838. X    if (out_packet->p_len == 0){
  1839. X    K_PFREE(out_packet);
  1840. XK_LEDOFF();
  1841. X    return;
  1842. X    }
  1843. XK_LEDOFF();
  1844. X    out_packet->p_len += sizeof(struct ip) + sizeof(struct udp);
  1845. X    setiphdr(out_packet, destAddr);    /* address to source of request packet (ntohl ??? ) */
  1846. X    udp = (struct udp *)(out_packet->p_off + sizeof (struct ip));
  1847. X    udp->src = htons(SNMP_PORT);
  1848. X    udp->dst = htons(SNMP_TRAP_PORT);
  1849. X    udp->length = out_packet->p_len - sizeof(struct ip);
  1850. X    udp->checksum = 0;    /* this should be computed */
  1851. X
  1852. X    mib_udp.udpOutDatagrams++;
  1853. X    routeip(out_packet, 0, 0);
  1854. X}
  1855. X#endif
  1856. X
  1857. Xint
  1858. Xsnmp_agent_parse(data, length, out_data, out_length, sourceip)
  1859. X    register u_char    *data;
  1860. X    int            length;
  1861. X    register u_char    *out_data;
  1862. X    int            *out_length;
  1863. X    u_long        sourceip;    /* possibly for authentication */
  1864. X{
  1865. X    u_char        msg_type, type;
  1866. X    long        zero = 0;
  1867. X    long        reqid, errstat, errindex;
  1868. X    register u_char *out_auth, *out_header, *out_reqid;
  1869. X    u_char        *startData = data;
  1870. X    int            startLength = length;
  1871. X    long        version;
  1872. X    int            header_shift, auth_shift;
  1873. X
  1874. X    sidlen = SID_MAX_LEN;
  1875. X    data = snmp_auth_parse(data, &length, sid, &sidlen, &version); /* authenticates message and returns length if valid */
  1876. X    if (data == NULL){
  1877. X    ERROR("bad authentication");
  1878. X    /* send auth fail trap */
  1879. X    return 0;
  1880. X    }
  1881. X    if (version != SNMP_VERSION_1){
  1882. X    ERROR("wrong version");
  1883. X    return NULL;
  1884. X    }
  1885. X    community = get_community(sid);
  1886. X    if (community == -1)
  1887. X    return NULL;
  1888. X    data = asn_parse_header(data, &length, &msg_type);
  1889. X    if (data == NULL){
  1890. X    ERROR("bad header");
  1891. X    return 0;
  1892. X    }
  1893. X    if (msg_type != GET_REQ_MSG && msg_type != GETNEXT_REQ_MSG && msg_type != SET_REQ_MSG){
  1894. X    return 0;
  1895. X    }
  1896. X    data = asn_parse_int(data, &length, &type, &reqid, sizeof(reqid));
  1897. X    if (data == NULL){
  1898. X    ERROR("bad parse of reqid");
  1899. X    return 0;
  1900. X    }
  1901. X
  1902. X    data = asn_parse_int(data, &length, &type, &errstat, sizeof(errstat));
  1903. X    if (data == NULL){
  1904. X    ERROR("bad parse of errstat");
  1905. X    return 0;
  1906. X    }
  1907. X        data = asn_parse_int(data, &length, &type, &errindex, sizeof(errindex));
  1908. X    if (data == NULL){
  1909. X    ERROR("bad parse of errindex");
  1910. X    return 0;
  1911. X    }
  1912. X    /*
  1913. X     * Now start cobbling together what is known about the output packet.
  1914. X     * The final lengths are not known now, so they will have to be recomputed
  1915. X     * later.
  1916. X     */
  1917. X    out_auth = out_data;
  1918. X    out_header = snmp_auth_build(out_auth, out_length, sid, &sidlen, &zero, 0);
  1919. X    if (out_header == NULL){
  1920. X    ERROR("snmp_auth_build failed");
  1921. X    return 0;
  1922. X    }
  1923. X    out_reqid = asn_build_header(out_header, out_length, (u_char)GET_RSP_MSG, 0);
  1924. X    if (out_reqid == NULL){
  1925. X    ERROR("");
  1926. X    return 0;
  1927. X    }
  1928. X
  1929. X    type = (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER);
  1930. X    /* return identical request id */
  1931. X    out_data = asn_build_int(out_reqid, out_length, type, &reqid, sizeof(reqid));
  1932. X    if (out_data == NULL){
  1933. X    ERROR("build reqid failed");
  1934. X    return 0;
  1935. X    }
  1936. X
  1937. X    /* assume that error status will be zero */
  1938. X    out_data = asn_build_int(out_data, out_length, type, &zero, sizeof(zero));
  1939. X    if (out_data == NULL){
  1940. X    ERROR("build errstat failed");
  1941. X    return 0;
  1942. X    }
  1943. X
  1944. X    /* assume that error index will be zero */
  1945. X    out_data = asn_build_int(out_data, out_length, type, &zero, sizeof(zero));
  1946. X    if (out_data == NULL){
  1947. X    ERROR("build errindex failed");
  1948. X    return 0;
  1949. X    }
  1950. X    errstat = parse_var_op_list(data, length, out_data, *out_length, msg_type, &errindex, 0);
  1951. X    if (msg_type == SET_REQ_MSG && errstat == SNMP_ERR_NOERROR){
  1952. X    /*
  1953. X     * SETS require 2 passes through the var_op_list.  The first pass verifies that
  1954. X     * all types, lengths, and values are valid, and the second does the set.  Then
  1955. X     * the identical GET RESPONSE packet is returned.
  1956. X     */
  1957. X    errstat = parse_var_op_list(data, length, out_data, *out_length, msg_type, &errindex, 1);
  1958. X    if (create_identical(startData, out_auth, startLength, 0L, 0L)) {
  1959. X        *out_length = packet_end - out_auth;  /* AU: Have to set this! */
  1960. X        return 1;
  1961. X    }
  1962. X    return 0;
  1963. X    }
  1964. X    switch((short)errstat){
  1965. X    case SNMP_ERR_NOERROR:
  1966. X        /*
  1967. X         * Because of the assumption above that header lengths would be encoded
  1968. X         * in one byte, things need to be fixed, now that the actual lengths are known.
  1969. X         */
  1970. X        header_shift = 0;
  1971. X        *out_length = packet_end - out_reqid;
  1972. X        if (*out_length >= 0x80){
  1973. X        header_shift++;
  1974. X        if (*out_length > 0xFF)
  1975. X            header_shift++;
  1976. X        }
  1977. X        auth_shift = 0;
  1978. X        *out_length = (packet_end - out_auth) - 2 + header_shift;
  1979. X        if (*out_length >= 0x80){
  1980. X        auth_shift++;
  1981. X        if (*out_length > 0xFF)
  1982. X            auth_shift++;
  1983. X        }
  1984. X        if (auth_shift + header_shift){
  1985. X        /*
  1986. X         * Shift packet (from request id to end of packet) by the sum of the
  1987. X         * necessary shift counts.
  1988. X         */
  1989. X        shift_array(out_reqid, packet_end - out_reqid, auth_shift + header_shift);
  1990. X        /* Now adjust pointers into the packet */
  1991. X        packet_end += auth_shift + header_shift;
  1992. X        out_reqid += auth_shift + header_shift;
  1993. X        out_header += auth_shift;
  1994. X        }
  1995. X        
  1996. X        /* re-encode the headers with the real lengths */
  1997. X        out_data = out_header;
  1998. X        *out_length = packet_end - out_reqid;
  1999. X        out_data = asn_build_header(out_data, out_length, GET_RSP_MSG, *out_length);
  2000. X        if (out_data != out_reqid){
  2001. X        ERROR("internal error: header");
  2002. X        return 0;
  2003. X        }
  2004. X
  2005. X        out_data = out_auth;
  2006. X        *out_length = packet_end - out_auth;
  2007. X        out_data = snmp_auth_build(out_data, out_length, sid, &sidlen, &zero, packet_end - out_header);
  2008. X        if (out_data != out_header){
  2009. X        ERROR("internal error");
  2010. X        return 0;
  2011. X        }
  2012. X        break;
  2013. X    case SNMP_ERR_NOSUCHNAME:
  2014. X    case SNMP_ERR_TOOBIG:
  2015. X    case SNMP_ERR_BADVALUE:
  2016. X    case SNMP_ERR_READONLY:
  2017. X    case SNMP_ERR_GENERR:
  2018. X        if (create_identical(startData, out_auth, startLength, errstat, errindex))
  2019. X        break;
  2020. X        return 0;
  2021. X    default:
  2022. X        return 0;
  2023. X    }
  2024. X    *out_length = packet_end - out_auth;
  2025. X    return 1;
  2026. X}
  2027. X
  2028. X/*
  2029. X * Parse_var_op_list goes through the list of variables and retrieves each one,
  2030. X * placing it's value in the output packet.  If doSet is non-zero, the variable is set
  2031. X * with the value in the packet.  If any error occurs, an error code is returned.
  2032. X */
  2033. Xint
  2034. Xparse_var_op_list(data, length, out_data, out_length, msgtype, index, doSet)
  2035. X    register u_char    *data;
  2036. X    int            length;
  2037. X    register u_char    *out_data;
  2038. X    int            out_length;
  2039. X    u_char        msgtype;
  2040. X    register long    *index;
  2041. X    int            doSet;
  2042. X{
  2043. X    u_char  type;
  2044. X    oid        var_name[MAX_NAME_LEN];
  2045. X    int        var_name_len, var_val_len;
  2046. X    u_char  var_val_type, *var_val, statType;
  2047. X    u_char far *statP;
  2048. X    int        statLen;
  2049. X    u_short acl;
  2050. X    int        rw, exact;
  2051. X    int        (*write_method)();
  2052. X    u_char  *headerP, *var_list_start;
  2053. X    int        dummyLen;
  2054. X    int        header_shift;
  2055. X    u_char far *getStatPtr();
  2056. X
  2057. X    if (msgtype == SET_REQ_MSG)
  2058. X    rw = WRITE;
  2059. X    else
  2060. X    rw = READ;
  2061. X    if (msgtype == GETNEXT_REQ_MSG)
  2062. X    exact = FALSE;
  2063. X    else
  2064. X    exact = TRUE;
  2065. X    data = asn_parse_header(data, &length, &type);
  2066. X    if (data == NULL){
  2067. X    ERROR("not enough space for varlist");
  2068. X    return PARSE_ERROR;
  2069. X    }
  2070. X    if (type != (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR)){
  2071. X    ERROR("wrong type");
  2072. X    return PARSE_ERROR;
  2073. X    }
  2074. X    headerP = out_data;
  2075. X    out_data = asn_build_header(out_data, &out_length, (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR), 0);
  2076. X    if (out_data == NULL){
  2077. X        ERROR("not enough space in output packet");
  2078. X    return BUILD_ERROR;
  2079. X    }
  2080. X    var_list_start = out_data;
  2081. X
  2082. X    *index = 1;
  2083. X    while((int)length > 0){
  2084. X    /* parse the name, value pair */
  2085. X    var_name_len = MAX_NAME_LEN;
  2086. X    data = snmp_parse_var_op(data, var_name, &var_name_len, &var_val_type, &var_val_len, &var_val, (int *)&length);
  2087. X    if (data == NULL)
  2088. X        return PARSE_ERROR;
  2089. X    /* now attempt to retrieve the variable on the local entity */
  2090. X    statP = getStatPtr(var_name, &var_name_len, &statType, &statLen, &acl, exact, &write_method);
  2091. X    if (statP == NULL)
  2092. X        return SNMP_ERR_NOSUCHNAME;
  2093. X    /* Check if this user has access rights to this variable */
  2094. X    if (!snmp_access(acl, community, rw))
  2095. X        return SNMP_ERR_NOSUCHNAME;    /* bogus */
  2096. X    if (msgtype == SET_REQ_MSG){
  2097. X        if (write_method == 0){
  2098. X        /* see if the type and value is consistent with this entities variable */
  2099. X        if (!goodValue(var_val_type, var_val_len, statType, statLen)){
  2100. X            return SNMP_ERR_BADVALUE;
  2101. X        }
  2102. X        /* actually do the set if necessary */
  2103. X        if (doSet)
  2104. X            setVariable(var_val, var_val_type, var_val_len, statP, statLen);
  2105. X        } else {
  2106. X        if (!(*write_method)(doSet, var_val, var_val_type, var_val_len, statP))
  2107. X            return SNMP_ERR_BADVALUE;
  2108. X        }
  2109. X    }
  2110. X    /* retrieve the value of the variable and place it into the outgoing packet */
  2111. X    out_data = snmp_build_var_op(out_data, var_name, &var_name_len, statType, statLen, statP, &out_length);
  2112. X    if (out_data == NULL){
  2113. X        return SNMP_ERR_TOOBIG;
  2114. X    }
  2115. X
  2116. X    (*index)++;
  2117. X    }
  2118. X    packet_end = out_data;  /* save a pointer to the end of the packet */
  2119. X
  2120. X    /*
  2121. X     * Because of the assumption above that header lengths would be encoded
  2122. X     * in one byte, things need to be fixed, now that the actual lengths are known.
  2123. X     */
  2124. X    header_shift = 0;
  2125. X    out_length = packet_end - var_list_start;
  2126. X    if (out_length >= 0x80){
  2127. X    header_shift++;
  2128. X    if (out_length > 0xFF)
  2129. X        header_shift++;
  2130. X    }
  2131. X    if (header_shift){
  2132. X    shift_array(var_list_start, packet_end - var_list_start, header_shift);
  2133. X    packet_end += header_shift;
  2134. X    var_list_start += header_shift;
  2135. X    }
  2136. X
  2137. X    /* Now rebuild header with the actual lengths */
  2138. X    dummyLen = packet_end - var_list_start;
  2139. X    if (asn_build_header(headerP, &dummyLen, (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR), dummyLen) == NULL){
  2140. X    return SNMP_ERR_TOOBIG;    /* bogus error ???? */
  2141. X    }
  2142. X    *index = 0;
  2143. X    return SNMP_ERR_NOERROR;
  2144. X}
  2145. X
  2146. X/*
  2147. X * create a packet identical to the input packet, except for the error status
  2148. X * and the error index which are set according to the input variables.
  2149. X * Returns 1 upon success and 0 upon failure.
  2150. X */
  2151. Xint
  2152. Xcreate_identical(snmp_in, snmp_out, snmp_length, errstat, errindex)
  2153. X    u_char        *snmp_in;
  2154. X    u_char        *snmp_out;
  2155. X    int            snmp_length;
  2156. X    long        errstat, errindex;
  2157. X{
  2158. X    register u_char *data;
  2159. X    u_char        type;
  2160. X    u_long        dummy;
  2161. X    int            length, headerLength;
  2162. X    register u_char *headerPtr, *reqidPtr, *errstatPtr, *errindexPtr, *varListPtr;
  2163. X
  2164. X    bcopy((char far *)snmp_in, (char far *)snmp_out, snmp_length);
  2165. X    length = snmp_length;
  2166. X    headerPtr = snmp_auth_parse(snmp_out, &length, sid, &sidlen, (long *)&dummy);
  2167. X    if (headerPtr == NULL)
  2168. X    return 0;
  2169. X    reqidPtr = asn_parse_header(headerPtr, &length, (u_char *)&dummy);
  2170. X    if (reqidPtr == NULL)
  2171. X    return 0;
  2172. X    headerLength = length;
  2173. X    errstatPtr = asn_parse_int(reqidPtr, &length, &type, (long *)&dummy, sizeof dummy);    /* request id */
  2174. X    if (errstatPtr == NULL)
  2175. X    return 0;
  2176. X    errindexPtr = asn_parse_int(errstatPtr, &length, &type, (long *)&dummy, sizeof dummy);    /* error status */
  2177. X    if (errindexPtr == NULL)
  2178. X    return 0;
  2179. X    varListPtr = asn_parse_int(errindexPtr, &length, &type, (long *)&dummy, sizeof dummy);    /* error index */
  2180. X    if (varListPtr == NULL)
  2181. X    return 0;
  2182. X
  2183. X    data = asn_build_header(headerPtr, &headerLength, GET_RSP_MSG, headerLength);
  2184. X    if (data != reqidPtr)
  2185. X    return 0;
  2186. X    length = snmp_length;
  2187. X    type = (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER);
  2188. X    data = asn_build_int(errstatPtr, &length, type, &errstat, sizeof errstat);
  2189. X    if (data != errindexPtr)
  2190. X    return 0;
  2191. X    data = asn_build_int(errindexPtr, &length, type, &errindex, sizeof errindex);
  2192. X    if (data != varListPtr)
  2193. X    return 0;
  2194. X    packet_end = snmp_out + snmp_length;
  2195. X    return 1;
  2196. X}
  2197. X
  2198. X#ifdef KINETICS
  2199. Xstruct pbuf *
  2200. XdefinitelyGetBuf(){
  2201. X    register struct pbuf *p;
  2202. X
  2203. X    K_PGET(PT_DATA, p);
  2204. X    while(p == 0){
  2205. X#ifdef notdef
  2206. X    if (pq->pq_head != NULL){
  2207. X        K_PDEQ(SPLIMP, pq, p);
  2208. X        if (p) K_PFREE(p);
  2209. X    } else if (sendq->pq_head != NULL){
  2210. X        K_PDEQ(SPLIMP, sendq, p);
  2211. X        if (p) K_PFREE(p);
  2212. X    }
  2213. X#endif
  2214. X    K_PGET(PT_DATA, p);
  2215. X    }
  2216. X    return p;
  2217. X}
  2218. X#endif
  2219. X
  2220. Xint
  2221. Xsnmp_access(acl, community, rw)
  2222. X    u_short     acl;
  2223. X    int        community;
  2224. X    int        rw;
  2225. X{
  2226. X    /*
  2227. X     * Each group has 2 bits, the more significant one is for read access,
  2228. X     * the less significant one is for write access.
  2229. X     */
  2230. X
  2231. X    community <<= 1;    /* multiply by two two shift two bits at a time */
  2232. X    if (rw == READ){
  2233. X    return (acl & (2 << community));    /* return the correct bit */
  2234. X    } else {
  2235. X    return (acl & (1 << community));
  2236. X    }
  2237. X}
  2238. X
  2239. Xint
  2240. Xget_community(sessionid)
  2241. X    u_char    *sessionid;
  2242. X{
  2243. X    int    count;
  2244. X
  2245. X    for(count = 0; count < NUM_COMMUNITIES; count++){
  2246. X    if (!strcmp(communities[count], (char *)sessionid))
  2247. X        break;
  2248. X    }
  2249. X    if (count == NUM_COMMUNITIES)
  2250. X    return -1;
  2251. X    return count;
  2252. X}
  2253. X
  2254. Xint
  2255. XgoodValue(inType, inLen, actualType, actualLen)
  2256. X    u_char    inType, actualType;
  2257. X    int        inLen, actualLen;
  2258. X{
  2259. X    if (inLen > actualLen)
  2260. X    return FALSE;
  2261. X    return (inType == actualType);
  2262. X}
  2263. X
  2264. XsetVariable(var_val, var_val_type, var_val_len, statP, statLen)
  2265. X    u_char  *var_val;
  2266. X    u_char  var_val_type;
  2267. X    int        var_val_len;
  2268. X    u_char far *statP;
  2269. X    int        statLen;
  2270. X{
  2271. X    int        buffersize = 1000;
  2272. X
  2273. X    switch(var_val_type){
  2274. X    case ASN_INTEGER:
  2275. X    case COUNTER:
  2276. X    case GAUGE:
  2277. X    case TIMETICKS:
  2278. X        asn_parse_int(var_val, &buffersize, &var_val_type, (long *)statP, statLen);
  2279. X        break;
  2280. X    case ASN_OCTET_STR:
  2281. X    case IPADDRESS:
  2282. X    case OPAQUE:
  2283. X        asn_parse_string(var_val, &buffersize, &var_val_type, statP, &statLen);
  2284. X        break;
  2285. X    case ASN_OBJECT_ID:
  2286. X        asn_parse_objid(var_val, &buffersize, &var_val_type, (oid *)statP, &statLen);
  2287. X        break;
  2288. X    }
  2289. X}
  2290. X
  2291. X
  2292. END_OF_FILE
  2293.   if test 18099 -ne `wc -c <'netramet/src/snmplib/snmpagnt.c'`; then
  2294.     echo shar: \"'netramet/src/snmplib/snmpagnt.c'\" unpacked with wrong size!
  2295.   fi
  2296.   # end of 'netramet/src/snmplib/snmpagnt.c'
  2297. fi
  2298. echo shar: End of archive 20 \(of 25\).
  2299. cp /dev/null ark20isdone
  2300. MISSING=""
  2301. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 ; do
  2302.     if test ! -f ark${I}isdone ; then
  2303.     MISSING="${MISSING} ${I}"
  2304.     fi
  2305. done
  2306. if test "${MISSING}" = "" ; then
  2307.     echo You have unpacked all 25 archives.
  2308.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2309. else
  2310.     echo You still must unpack the following archives:
  2311.     echo "        " ${MISSING}
  2312. fi
  2313. exit 0
  2314. exit 0 # Just in case...
  2315.