SNMP.C
上传用户:sunrenlu
上传日期:2022-06-13
资源大小:1419k
文件大小:25k
源码类别:

操作系统开发

开发平台:

DOS

  1. /* Beholder RMON ethernet network monitor,Copyright (C) 1993 DNPAP group */
  2. /* See file COPYING 'GNU General Public Licence' for copyright details   */
  3. /************************************************************************
  4. ** MODULE INFORMATION*
  5. **********************
  6. **     FILE     NAME:       snmp.c
  7. **     SYSTEM   NAME:       SNMP Packet Module
  8. **     ORIGINAL AUTHOR(S):  Dirk Wisse
  9. **     VERSION  NUMBER:     1
  10. **     CREATION DATE:       1990/11/28
  11. **
  12. ** DESCRIPTION: SNMP Packet Module
  13. **
  14. *************************************************************************
  15. ** CHANGES INFORMATION **
  16. *************************
  17. ** REVISION:    $Revision$
  18. ** WORKFILE:    $Workfile$
  19. ** LOGINFO:     $Log$
  20. *************************************************************************/
  21. #include "dnpap.h"
  22. #include <asn1.h>
  23. #include <snmp.h>
  24.  
  25. /*prototypes*/
  26. STATIC BOOLEAN SnmpSyn2TagCls(unsigned *Tag, unsigned *Cls, int Syn);
  27. STATIC BOOLEAN SnmpTagCls2Syn(unsigned Tag, unsigned Cls, WORD *Syn);
  28. STATIC BOOLEAN SnmpObjEnc(ASN1_SCK *Asn1, SNMP_OBJECT *Obj);
  29. STATIC BOOLEAN SnmpObjDec(ASN1_SCK *Asn1, SNMP_OBJECT *Obj);
  30. STATIC BOOLEAN SnmpLstEnc(ASN1_SCK *Asn1, SNMP_OBJECT *Lst, unsigned LstLen);
  31. STATIC BOOLEAN SnmpLstDec(ASN1_SCK *Asn1, SNMP_OBJECT *Lst, unsigned LstSze, unsigned *LstLen);
  32. STATIC BOOLEAN SnmpRqsEnc(ASN1_SCK *Asn1, SNMP_REQUEST *Rqs);
  33. STATIC BOOLEAN SnmpRqsDec(ASN1_SCK *Asn1, SNMP_REQUEST *Rqs);
  34. STATIC BOOLEAN SnmpTrpEnc(ASN1_SCK *Asn1, SNMP_TRAP *Trp);
  35. STATIC BOOLEAN SnmpTrpDec(ASN1_SCK *Asn1, SNMP_TRAP *Trp);
  36. STATIC BOOLEAN SnmpPduEnc(ASN1_SCK *Asn1, SNMP_PDU *Pdu, SNMP_OBJECT *Lst, unsigned LstLen);
  37. STATIC BOOLEAN SnmpPduDec(ASN1_SCK *Asn1, SNMP_PDU *Pdu, SNMP_OBJECT *Lst, unsigned LstSze, unsigned *LstLen);
  38. #define SNMP_IPA    0
  39. #define SNMP_CNT    1
  40. #define SNMP_GGE    2
  41. #define SNMP_TIT    3
  42. #define SNMP_OPQ    4
  43. INT snmpErrStatus = SNMP_NOERROR;
  44. typedef struct _SNMP_CNV SNMP_CNV;
  45. struct _SNMP_CNV
  46. {
  47.     unsigned Class;
  48.     unsigned Tag;
  49.     int      Syntax;
  50. };
  51. SNMP_STAT SnmpStat;
  52. CONST CHAR *SnmpTrap[] =
  53. {
  54. "cold start",
  55. "warm start",
  56. "link down",
  57. "link up",
  58. "authentication failure",
  59.     "neighbor loss",
  60. "enterprise specific"
  61. };
  62. static SNMP_CNV SnmpCnv [] =
  63. {
  64.     {ASN1_UNI, ASN1_NUL, SNMP_NULL},
  65.     {ASN1_UNI, ASN1_INT, SNMP_INTEGER},
  66.     {ASN1_UNI, ASN1_OTS, SNMP_OCTETSTR},
  67.     {ASN1_UNI, ASN1_OTS, SNMP_DISPLAYSTR},
  68.     {ASN1_UNI, ASN1_OJI, SNMP_OBJECTID},
  69.     {ASN1_APL, SNMP_IPA, SNMP_IPADDR},
  70.     {ASN1_APL, SNMP_CNT, SNMP_COUNTER},
  71.     {ASN1_APL, SNMP_GGE, SNMP_GAUGE},
  72.     {ASN1_APL, SNMP_TIT, SNMP_TIMETICKS},
  73.     {ASN1_APL, SNMP_OPQ, SNMP_OPAQUE},
  74.     {0,       0,       -1}
  75. };
  76. /**************************************************************
  77. ** NAME:        SnmpSyn2TagCls
  78. ** SYNOPSIS:    BOOLEAN SnmpSyn2TagCls
  79. **                  (
  80. **                      unsigned    *Tag,
  81. **                      unsigned    *Cls,
  82. **                      int         Syn
  83. **                  )
  84. ** DESCRIPTION: Converts Syntax tag to ASN1 tag and class.
  85. **              See SnmpCnv for conversion.
  86. ** RETURNS:     BOOLEAN success.
  87. **************************************************************/
  88. BOOLEAN SnmpSyn2TagCls
  89.     (
  90.         unsigned    *Tag,
  91.         unsigned    *Cls,
  92.         int         Syn
  93.     )
  94. {
  95.     SNMP_CNV
  96.         *Cnv;
  97.     Cnv = SnmpCnv;
  98.     while (Cnv->Syntax != -1)
  99.     {
  100.         if (Cnv->Syntax == Syn)
  101.         {
  102.             *Tag = Cnv->Tag;
  103.             *Cls = Cnv->Class;
  104.             return TRUE;
  105.         }
  106.         Cnv++;
  107.     }
  108.     return FALSE;
  109. }
  110. /**************************************************************
  111. ** NAME:        SnmpTagCls2Syn
  112. ** SYNOPSIS:    BOOLEAN SnmpTagCls2Syn
  113. **                  (
  114. **                      unsigned    Tag,
  115. **                      unsigned    Cls,
  116. **                      WORD        *Syn
  117. **                  )
  118. ** DESCRIPTION: Converts ASN1 tag and class to Syntax tag.
  119. **              See SnmpCnv for conversion.
  120. ** RETURNS:     BOOLEAN success.
  121. **************************************************************/
  122. BOOLEAN SnmpTagCls2Syn
  123.     (
  124.         unsigned    Tag,
  125.         unsigned    Cls,
  126.         WORD        *Syn
  127.     )
  128. {
  129.     SNMP_CNV
  130.         *Cnv;
  131.     Cnv = SnmpCnv;
  132.     while (Cnv->Syntax != -1)
  133.     {
  134.         if (Cnv->Tag == Tag && Cnv->Class == Cls)
  135.         {
  136.             *Syn = Cnv->Syntax;
  137.             return TRUE;
  138.         }
  139.         Cnv++;
  140.     }
  141.     return FALSE;
  142. }
  143. /**************************************************************
  144. ** NAME:        SnmpObjEnc
  145. ** SYNOPSIS:    BOOLEAN SnmpObjEnc
  146. **                  (
  147. **                      ASN1_SCK     *Asn1,
  148. **                      SNMP_OBJECT   *Obj,
  149. **                  )
  150. ** DESCRIPTION: Encodes an object in ASN1.
  151. ** RETURNS:     BOOLEAN success.
  152. **************************************************************/
  153. BOOLEAN SnmpObjEnc
  154.     (
  155.         ASN1_SCK     *Asn1,
  156.         SNMP_OBJECT   *Obj
  157.     )
  158. {
  159.     unsigned
  160.         Cls,
  161.         Tag;
  162.     BYTE
  163.         *Eoc,
  164.         *End;
  165.     if (!Asn1EocEnc (Asn1, &Eoc))
  166.         return FALSE;
  167.     switch (Obj->Type)
  168.     {
  169.         case SNMP_INTEGER:
  170.             if (!Asn1IntEncLng (Asn1, &End, Obj->Syntax.LngInt))
  171.                 return FALSE;
  172.             break;
  173.         case SNMP_OCTETSTR:
  174.         case SNMP_OPAQUE:
  175.             if (!Asn1OtsEnc (Asn1, &End, Obj->Syntax.BufChr, Obj->SyntaxLen))
  176.                 return FALSE;
  177.             break;
  178.         case SNMP_NULL:
  179.             if (!Asn1NulEnc (Asn1, &End))
  180.                 return FALSE;
  181.             break;
  182.         case SNMP_OBJECTID:
  183.             if (!Asn1OjiEnc (Asn1, &End, Obj->Syntax.BufInt, Obj->SyntaxLen))
  184.                 return FALSE;
  185.             break;
  186.         case SNMP_IPADDR:
  187.             if (!Asn1OtsEnc (Asn1, &End, (BYTE *)&Obj->Syntax.LngUns, 4))
  188.                 return FALSE;
  189.             break;
  190.         case SNMP_COUNTER:
  191.         case SNMP_GAUGE:
  192.         case SNMP_TIMETICKS:
  193.             if (!Asn1IntEncLngUns (Asn1, &End, Obj->Syntax.LngUns))
  194.                 return FALSE;
  195.             break;
  196.         default:
  197.             return FALSE;
  198.     }
  199.     if (!SnmpSyn2TagCls (&Tag, &Cls, Obj->Type))
  200.         return FALSE;
  201.     if (!Asn1HdrEnc (Asn1, End, Cls, ASN1_PRI, Tag))
  202.         return FALSE;
  203.     if (!Asn1OjiEnc (Asn1, &End, Obj->Id, Obj->IdLen))
  204.         return FALSE;
  205.     if (!Asn1HdrEnc (Asn1, End, ASN1_UNI, ASN1_PRI, ASN1_OJI))
  206.         return FALSE;
  207.     if (!Asn1HdrEnc (Asn1, Eoc, ASN1_UNI, ASN1_CON, ASN1_SEQ))
  208.         return FALSE;
  209.     return TRUE;
  210. }
  211. /**************************************************************
  212. ** NAME:        SnmpObjDec
  213. ** SYNOPSIS:    BOOLEAN SnmpObjDec
  214. **                  (
  215. **                      ASN1_SCK     *Asn1,
  216. **                      SNMP_OBJECT   *Obj,
  217. **                  )
  218. ** DESCRIPTION: Decodes an object from ASN1.
  219. ** RETURNS:     BOOLEAN success.
  220. **************************************************************/
  221. BOOLEAN SnmpObjDec
  222.     (
  223.         ASN1_SCK     *Asn1,
  224.         SNMP_OBJECT   *Obj
  225.     )
  226. {
  227.     unsigned
  228.         Cls,
  229.         Con,
  230.         Tag;
  231.     BYTE
  232.         *Eoc,
  233.         *End;
  234.     if (!Asn1HdrDec (Asn1, &Eoc, &Cls, &Con, &Tag))
  235.         return FALSE;
  236.     if (Cls != ASN1_UNI || Con != ASN1_CON || Tag != ASN1_SEQ)
  237.         return FALSE;
  238.     if (!Asn1HdrDec (Asn1, &End, &Cls, &Con, &Tag))
  239.         return FALSE;
  240.     if (Cls != ASN1_UNI || Con != ASN1_PRI || Tag != ASN1_OJI)
  241.         return FALSE;
  242.     if (!Asn1OjiDec (Asn1, End, Obj->Id, SNMP_SIZE_OBJECTID, &Obj->IdLen))
  243.         return FALSE;
  244.     if (!Asn1HdrDec (Asn1, &End, &Cls, &Con, &Tag))
  245.         return FALSE;
  246.     if (Con != ASN1_PRI)
  247.         return FALSE;
  248.     if (!SnmpTagCls2Syn (Tag, Cls, &Obj->Type))
  249.         return FALSE;
  250.     switch (Obj->Type)
  251.     {
  252.         case SNMP_INTEGER:
  253.             if (!Asn1IntDecLng (Asn1, End, &Obj->Syntax.LngInt))
  254.                 return FALSE;
  255.             break;
  256.         case SNMP_OCTETSTR:
  257.         case SNMP_OPAQUE:
  258.             if (!Asn1OtsDec (Asn1, End, Obj->Syntax.BufChr, SNMP_SIZE_BUFCHR,
  259.                 &Obj->SyntaxLen))
  260.                 return FALSE;
  261.             break;
  262.         case SNMP_NULL:
  263.             if (!Asn1NulDec (Asn1, End))
  264.                 return FALSE;
  265.             break;
  266.         case SNMP_OBJECTID:
  267.             if (!Asn1OjiDec (Asn1, End, Obj->Syntax.BufInt, SNMP_SIZE_BUFINT,
  268.                 &Obj->SyntaxLen))
  269.                 return FALSE;
  270.             break;
  271.         case SNMP_IPADDR:
  272.             if (!Asn1OtsDec (Asn1, End, (BYTE *)&Obj->Syntax.LngUns, 4,
  273.                 &Obj->SyntaxLen))
  274.                 return FALSE;
  275.             if (Obj->SyntaxLen != 4)
  276.                 return FALSE;
  277.             break;
  278.         case SNMP_COUNTER:
  279.         case SNMP_GAUGE:
  280.         case SNMP_TIMETICKS:
  281.             if (!Asn1IntDecLngUns (Asn1, End, &Obj->Syntax.LngUns))
  282.                 return FALSE;
  283.             break;
  284.         default:
  285.             return FALSE;
  286.     }
  287.     if (!Asn1EocDec (Asn1, Eoc))
  288.         return FALSE;
  289.     return TRUE;
  290. }
  291. /**************************************************************
  292. ** NAME:        SnmpLstEnc
  293. ** SYNOPSIS:    BOOLEAN
  294. **                  SnmpLstEnc
  295. **                  (
  296. **                      ASN1_SCK     *Asn1,
  297. **                      SNMP_OBJECT   *Lst,
  298. **                      unsigned     LstLen
  299. **                  )
  300. ** DESCRIPTION: Encodes a list of objects in ASN1.
  301. ** RETURNS:     BOOLEAN success.
  302. **************************************************************/
  303. BOOLEAN
  304.     SnmpLstEnc
  305.     (
  306.         ASN1_SCK     *Asn1,
  307.         SNMP_OBJECT  *Lst,
  308.         unsigned     LstLen
  309.     )
  310. {
  311.     BYTE
  312.         *Eoc;
  313.     if (!Asn1EocEnc (Asn1, &Eoc))
  314.         return FALSE;
  315.     Lst += LstLen;
  316.     while (LstLen-- > 0)
  317.     {
  318.         if (!SnmpObjEnc (Asn1, --Lst))
  319.             return FALSE;
  320.     }
  321.     if (!Asn1HdrEnc (Asn1, Eoc, ASN1_UNI, ASN1_CON, ASN1_SEQ))
  322.         return FALSE;
  323.     return TRUE;
  324. }
  325. /**************************************************************
  326. ** NAME:        SnmpLstDec
  327. ** SYNOPSIS:    BOOLEAN
  328. **                  SnmpLstDec
  329. **                  (
  330. **                      ASN1_SCK     *Asn1,
  331. **                      SNMP_OBJECT   *Lst,
  332. **                      unsigned     LstSze,
  333. **                      unsigned     *LstLen
  334. **                  )
  335. ** DESCRIPTION: Decodes a list of objects from ASN1.
  336. ** RETURNS:     BOOLEAN success.
  337. **************************************************************/
  338. BOOLEAN
  339.     SnmpLstDec
  340.     (
  341.         ASN1_SCK     *Asn1,
  342.         SNMP_OBJECT   *Lst,
  343.         unsigned     LstSze,
  344.         unsigned     *LstLen
  345.     )
  346. {
  347.     unsigned
  348.         Cls,
  349.         Con,
  350.         Tag;
  351.     BYTE
  352.         *Eoc;
  353.     if (!Asn1HdrDec (Asn1, &Eoc, &Cls, &Con, &Tag))
  354.         return FALSE;
  355.     if (Cls != ASN1_UNI || Con != ASN1_CON || Tag != ASN1_SEQ)
  356.         return FALSE;
  357.     *LstLen = 0;
  358.     while (!Asn1Eoc (Asn1, Eoc))
  359.     {
  360.         if (++(*LstLen) > LstSze)
  361.         {
  362.             snmpErrStatus = SNMP_TOOBIG;
  363.             return FALSE;
  364.         }
  365.         if (!SnmpObjDec (Asn1, Lst++))
  366.             return FALSE;
  367.     }
  368.     if (!Asn1EocDec (Asn1, Eoc))
  369.         return FALSE;
  370.     return TRUE;
  371. }
  372. /**************************************************************
  373. ** NAME:        SnmpRqsEnc
  374. ** SYNOPSIS:    BOOLEAN
  375. **                  SnmpRqsEnc
  376. **                  (
  377. **                      ASN1_SCK     *Asn1,
  378. **                      SNMP_REQUEST *Rqs
  379. **                  )
  380. ** DESCRIPTION: Encodes a request or response PDU in ASN1.
  381. ** RETURNS:     BOOLEAN success.
  382. **************************************************************/
  383. BOOLEAN
  384.     SnmpRqsEnc
  385.     (
  386.         ASN1_SCK     *Asn1,
  387.         SNMP_REQUEST *Rqs
  388.     )
  389. {
  390.     BYTE
  391.         *End;
  392.     if (!Asn1IntEncUns (Asn1, &End, Rqs->ErrorIndex))
  393.         return FALSE;
  394.     if (!Asn1HdrEnc (Asn1, End, ASN1_UNI, ASN1_PRI, ASN1_INT))
  395.         return FALSE;
  396.     if (!Asn1IntEncUns (Asn1, &End, Rqs->ErrorStatus))
  397.         return FALSE;
  398.     if (!Asn1HdrEnc (Asn1, End, ASN1_UNI, ASN1_PRI, ASN1_INT))
  399.         return FALSE;
  400.     if (!Asn1IntEncLngUns (Asn1, &End, Rqs->Id))
  401.         return FALSE;
  402.     if (!Asn1HdrEnc (Asn1, End, ASN1_UNI, ASN1_PRI, ASN1_INT))
  403.         return FALSE;
  404.     return TRUE;
  405. }
  406. /**************************************************************
  407. ** NAME:        SnmpRqsDec
  408. ** SYNOPSIS:    BOOLEAN
  409. **                  SnmpRqsDec
  410. **                  (
  411. **                      ASN1_SCK     *Asn1,
  412. **                      SNMP_REQUEST *Rqs
  413. **                  )
  414. ** DESCRIPTION: Decodes a request or response PDU from ASN1.
  415. ** RETURNS:     BOOLEAN success.
  416. **************************************************************/
  417. BOOLEAN
  418.     SnmpRqsDec
  419.     (
  420.         ASN1_SCK     *Asn1,
  421.         SNMP_REQUEST *Rqs
  422.     )
  423. {
  424.     unsigned
  425.         Cls,
  426.         Con,
  427.         Tag;
  428.     BYTE
  429.         *End;
  430.     if (!Asn1HdrDec (Asn1, &End, &Cls, &Con, &Tag))
  431.         return FALSE;
  432.     if (Cls != ASN1_UNI || Con != ASN1_PRI || Tag != ASN1_INT)
  433.         return FALSE;
  434.     if (!Asn1IntDecLngUns (Asn1, End, &Rqs->Id))
  435.         return FALSE;
  436.     if (!Asn1HdrDec (Asn1, &End, &Cls, &Con, &Tag))
  437.         return FALSE;
  438.     if (Cls != ASN1_UNI || Con != ASN1_PRI || Tag != ASN1_INT)
  439.         return FALSE;
  440.     if (!Asn1IntDecUns (Asn1, End, &Rqs->ErrorStatus))
  441.         return FALSE;
  442.     if (!Asn1HdrDec (Asn1, &End, &Cls, &Con, &Tag))
  443.         return FALSE;
  444.     if (Cls != ASN1_UNI || Con != ASN1_PRI || Tag != ASN1_INT)
  445.         return FALSE;
  446.     if (!Asn1IntDecUns (Asn1, End, &Rqs->ErrorIndex))
  447.         return FALSE;
  448.     return TRUE;
  449. }
  450. /**************************************************************
  451. ** NAME:        SnmpTrpEnc
  452. ** SYNOPSIS:    BOOLEAN
  453. **                  SnmpTrpEnc
  454. **                  (
  455. **                      ASN1_SCK     *Asn1,
  456. **                      SNMP_TRAP    *Trp
  457. **                  )
  458. ** DESCRIPTION: Encodes a trap PDU in ASN1.
  459. ** RETURNS:     BOOLEAN success.
  460. **************************************************************/
  461. BOOLEAN
  462.     SnmpTrpEnc
  463.     (
  464.         ASN1_SCK     *Asn1,
  465.         SNMP_TRAP    *Trp
  466.     )
  467. {
  468.     BYTE
  469.         *End;
  470.     if (!Asn1IntEncLngUns (Asn1, &End, Trp->Time))
  471.         return FALSE;
  472.     if (!Asn1HdrEnc (Asn1, End, ASN1_APL, ASN1_PRI, SNMP_TIT))
  473.         return FALSE;
  474.     if (!Asn1IntEncUns (Asn1, &End, Trp->Specific))
  475.         return FALSE;
  476.     if (!Asn1HdrEnc (Asn1, End, ASN1_UNI, ASN1_PRI, ASN1_INT))
  477.         return FALSE;
  478.     if (!Asn1IntEncUns (Asn1, &End, Trp->General))
  479.         return FALSE;
  480.     if (!Asn1HdrEnc (Asn1, End, ASN1_UNI, ASN1_PRI, ASN1_INT))
  481.         return FALSE;
  482.     if (!Asn1OtsEnc (Asn1, &End, (BYTE *)&(Trp->IpAddress), 4))
  483.         return FALSE;
  484.     if (!Asn1HdrEnc (Asn1, End, ASN1_APL, ASN1_PRI, SNMP_IPA))
  485.         return FALSE;
  486.     if (!Asn1OjiEnc (Asn1, &End, Trp->Id, Trp->IdLen))
  487.         return FALSE;
  488.     if (!Asn1HdrEnc (Asn1, End, ASN1_UNI, ASN1_PRI, ASN1_OJI))
  489.         return FALSE;
  490.     return TRUE;
  491. }
  492. /**************************************************************
  493. ** NAME:        SnmpTrpDec
  494. ** SYNOPSIS:    BOOLEAN
  495. **                  SnmpTrpDec
  496. **                  (
  497. **                      ASN1_SCK     *Asn1,
  498. **                      SNMP_TRAP    *Trp
  499. **                  )
  500. ** DESCRIPTION: Decodes a trap PDU from ASN1.
  501. ** RETURNS:     BOOLEAN success.
  502. **************************************************************/
  503. BOOLEAN
  504.     SnmpTrpDec
  505.     (
  506.         ASN1_SCK     *Asn1,
  507.         SNMP_TRAP    *Trp
  508.     )
  509. {
  510.     unsigned
  511.         Cls,
  512.         Con,
  513.         Tag;
  514.     BYTE
  515.         *End;
  516.     if (!Asn1HdrDec (Asn1, &End, &Cls, &Con, &Tag))
  517.         return FALSE;
  518.     if (Cls != ASN1_UNI || Con != ASN1_PRI || Tag != ASN1_OJI)
  519.         return FALSE;
  520.     if (!Asn1OjiDec (Asn1, End, Trp->Id, sizeof(Trp->Id)/sizeof(Trp->Id[0]), &Trp->IdLen))
  521.         return FALSE;
  522.     if (!Asn1HdrDec (Asn1, &End, &Cls, &Con, &Tag))
  523.         return FALSE;
  524.     if (Cls != ASN1_APL || Con != ASN1_PRI || Tag != SNMP_IPA)
  525.         return FALSE;
  526.     if (!Asn1OtsDec (Asn1, End, (BYTE *)&(Trp->IpAddress), 4, &Tag))
  527.         return FALSE;
  528.     if (!Asn1HdrDec (Asn1, &End, &Cls, &Con, &Tag))
  529.         return FALSE;
  530.     if (Cls != ASN1_UNI || Con != ASN1_PRI || Tag != ASN1_INT)
  531.         return FALSE;
  532.     if (!Asn1IntDecUns (Asn1, End, &Trp->General))
  533.         return FALSE;
  534.     if (!Asn1HdrDec (Asn1, &End, &Cls, &Con, &Tag))
  535.         return FALSE;
  536.     if (Cls != ASN1_UNI || Con != ASN1_PRI || Tag != ASN1_INT)
  537.         return FALSE;
  538.     if (!Asn1IntDecUns (Asn1, End, &Trp->Specific))
  539.         return FALSE;
  540.     if (!Asn1HdrDec (Asn1, &End, &Cls, &Con, &Tag))
  541.         return FALSE;
  542.     if (Cls != ASN1_APL || Con != ASN1_PRI || Tag != SNMP_TIT)
  543.         return FALSE;
  544.     if (!Asn1IntDecLngUns (Asn1, End, &Trp->Time))
  545.         return FALSE;
  546.     return TRUE;
  547. }
  548. /**************************************************************
  549. ** NAME:        SnmpPduEnc
  550. ** SYNOPSIS:    BOOLEAN
  551. **                  SnmpPduEnc
  552. **                  (
  553. **                      ASN1_SCK     *Asn1,
  554. **                      SNMP_PDU     *Pdu,
  555. **                      SNMP_OBJECT   *Lst,
  556. **                      unsigned     LstLen
  557. **                  )
  558. ** DESCRIPTION: Encodes a PDU in ASN1.
  559. **              Pdu is a union of snmp_ror and snmp_trp.
  560. ** RETURNS:     BOOLEAN success.
  561. **************************************************************/
  562. BOOLEAN
  563.     SnmpPduEnc
  564.     (
  565.         ASN1_SCK     *Asn1,
  566.         SNMP_PDU     *Pdu,
  567.         SNMP_OBJECT   *Lst,
  568.         unsigned     LstLen
  569.     )
  570. {
  571.     BYTE
  572.         *Eoc;
  573.     if (!Asn1EocEnc (Asn1, &Eoc))
  574.         return FALSE;
  575.     if (!SnmpLstEnc (Asn1, Lst, LstLen))
  576.         return FALSE;
  577.     switch (Pdu->Type)
  578.     {
  579.         case SNMP_PDU_GET:
  580.         case SNMP_PDU_NEXT:
  581.         case SNMP_PDU_RESPONSE:
  582.         case SNMP_PDU_SET:
  583.             if (!SnmpRqsEnc (Asn1, &Pdu->Request))
  584.                 return FALSE;
  585.             break;
  586.         case SNMP_PDU_TRAP:
  587.            if (!SnmpTrpEnc (Asn1, &Pdu->Trap))
  588.                 return FALSE;
  589.             break;
  590.         default:
  591.             return FALSE;
  592.     }
  593.     if (!Asn1HdrEnc (Asn1, Eoc, ASN1_CTX, ASN1_CON, Pdu->Type))
  594.         return FALSE;
  595.     return TRUE;
  596. }
  597. /**************************************************************
  598. ** NAME:        SnmpPduDec
  599. ** SYNOPSIS:    BOOLEAN
  600. **                  SnmpPduDec
  601. **                  (
  602. **                      ASN1_SCK     *Asn1,
  603. **                      SNMP_PDU     *Pdu
  604. **                      SNMP_OBJECT   *Lst,
  605. **                      unsigned     LstSze,
  606. **                      unsigned     *LstLen
  607. **                  )
  608. ** DESCRIPTION: Decodes a PDU from ASN1.
  609. **              Pdu is a union of snmp_ror and snmp_trp.
  610. ** RETURNS:     BOOLEAN success.
  611. **************************************************************/
  612. BOOLEAN
  613.     SnmpPduDec
  614.     (
  615.         ASN1_SCK     *Asn1,
  616.         SNMP_PDU     *Pdu,
  617.         SNMP_OBJECT   *Lst,
  618.         unsigned     LstSze,
  619.         unsigned     *LstLen
  620.     )
  621. {
  622.     unsigned
  623.         Cls,
  624.         Con;
  625.     BYTE
  626.         *Eoc;
  627.     if (!Asn1HdrDec (Asn1, &Eoc, &Cls, &Con, &Pdu->Type))
  628.         return FALSE;
  629.     if (Cls != ASN1_CTX || Con != ASN1_CON)
  630.         return FALSE;
  631.     switch (Pdu->Type)
  632.     {
  633.         case SNMP_PDU_GET:
  634.         case SNMP_PDU_NEXT:
  635.         case SNMP_PDU_RESPONSE:
  636.         case SNMP_PDU_SET:
  637.             if (!SnmpRqsDec (Asn1, &Pdu->Request))
  638.                 return FALSE;
  639.             break;
  640.         case SNMP_PDU_TRAP:
  641.             if (!SnmpTrpDec (Asn1, &Pdu->Trap))
  642.                 return FALSE;
  643.             break;
  644.         default:
  645.             SnmpStat.InBadTypes++;
  646.             return FALSE;
  647.     }
  648.     if (!SnmpLstDec (Asn1, Lst, LstSze, LstLen))
  649.         return FALSE;
  650.     if (!Asn1EocDec (Asn1, Eoc))
  651.         return FALSE;
  652.     return TRUE;
  653. }
  654. /**************************************************************
  655. ** NAME:        SnmpEnc                                   [API]
  656. ** SYNOPSIS:    BOOLEAN SnmpEnc
  657. **                  (
  658. **                      BYTE        **Snmp, 
  659. **                      unsigned    *SnmpLen,
  660. **                      SNMP_PDU    *Pdu, 
  661. **                      BYTE        *Com, 
  662. **                      unsigned    ComLen, 
  663. **                      SNMP_OBJECT  *Lst, 
  664. **                      unsigned    LstLen
  665. **                  )
  666. ** DESCRIPTION: Encodes a request, response or trap in ASN1.
  667. ** RETURNS:     BOOLEAN success.
  668. **************************************************************/
  669. BOOLEAN SnmpEnc(BYTE        **Snmp, 
  670.                 unsigned    *SnmpLen,
  671.                 SNMP_PDU    *Pdu, 
  672.                 BYTE        *Com, 
  673.                 unsigned    ComLen, 
  674.                 SNMP_OBJECT  *Lst, 
  675.                 unsigned    LstLen)
  676. {
  677.     BYTE
  678.         *Eoc,
  679.         *End;
  680.     ASN1_SCK
  681.         Asn1;
  682.     snmpErrStatus = SNMP_GENERROR;
  683.     Asn1Opn (&Asn1, *Snmp, *SnmpLen, ASN1_ENC);
  684.     if (!Asn1EocEnc (&Asn1, &Eoc))
  685.         return FALSE;
  686.     if (!SnmpPduEnc (&Asn1, Pdu, Lst, LstLen))
  687.         return FALSE;
  688.     if (!Asn1OtsEnc (&Asn1, &End, Com, ComLen))
  689.         return FALSE;
  690.     if (!Asn1HdrEnc (&Asn1, End, ASN1_UNI, ASN1_PRI, ASN1_OTS))
  691.         return FALSE;
  692.     if (!Asn1IntEncUns (&Asn1, &End, SNMP_VERSION))
  693.         return FALSE;
  694.     if (!Asn1HdrEnc (&Asn1, End, ASN1_UNI, ASN1_PRI, ASN1_INT))
  695.         return FALSE;
  696.     if (!Asn1HdrEnc (&Asn1, Eoc, ASN1_UNI, ASN1_CON, ASN1_SEQ))
  697.         return FALSE;
  698.     Asn1Cls (&Asn1, Snmp, SnmpLen);
  699.     
  700.     SnmpStat.OutPkts++;
  701.     switch (Pdu->Type)
  702.     {
  703.         case SNMP_PDU_GET:
  704.             SnmpStat.OutGetRequests++;
  705.             break;
  706.         case SNMP_PDU_NEXT:
  707.             SnmpStat.OutGetNexts++;
  708.             break;
  709.         case SNMP_PDU_RESPONSE:
  710.             SnmpStat.OutGetResponses++;
  711.             break;
  712.         case SNMP_PDU_SET:
  713.             SnmpStat.OutSetRequests++;
  714.             break;
  715.         case SNMP_PDU_TRAP:
  716.             SnmpStat.OutTraps++;
  717.             break;
  718.     }
  719.     
  720.     return TRUE;
  721. }
  722. /**************************************************************
  723. ** NAME:        SnmpDec                                   [API]
  724. ** SYNOPSIS:    BOOLEAN SnmpDec
  725. **                  (
  726. **                      BYTE        *Snmp, 
  727. **                      unsigned    SnmpLen,
  728. **                      SNMP_PDU    *Pdu,
  729. **                      BYTE        *Com, 
  730. **                      unsigned    ComSze,
  731. **                      unsigned    *ComLen, 
  732. **                      SNMP_OBJECT  *Lst, 
  733. **                      unsigned    LstSze,
  734. **                      unsigned    *LstLen
  735. **                  )
  736. ** DESCRIPTION: Decodes a request, response or trap from ASN1.
  737. ** RETURNS:     BOOLEAN success.
  738. **************************************************************/
  739. BOOLEAN SnmpDec(BYTE        *Snmp, 
  740.                 unsigned    SnmpLen,
  741.                 SNMP_PDU    *Pdu,
  742.                 BYTE        *Com, 
  743.                 unsigned    ComSze,
  744.                 unsigned    *ComLen, 
  745.                 SNMP_OBJECT  *Lst, 
  746.                 unsigned    LstSze,
  747.                 unsigned    *LstLen)
  748. {
  749.     unsigned
  750.         Cls,
  751.         Con,
  752.         Tag;
  753.     BYTE
  754.         *Eoc,
  755.         *End;
  756.     ASN1_SCK
  757.         Asn1;
  758.     unsigned
  759.         Ver;
  760.     snmpErrStatus = SNMP_GENERROR;
  761.     Asn1Opn (&Asn1, Snmp, SnmpLen, ASN1_DEC);
  762.     if (!Asn1HdrDec (&Asn1, &Eoc, &Cls, &Con, &Tag))
  763.     {
  764.         SnmpStat.InASNParseErrs++;
  765.         return FALSE;
  766.     }
  767.     if (Cls != ASN1_UNI || Con != ASN1_CON || Tag != ASN1_SEQ)
  768.     {
  769.         SnmpStat.InASNParseErrs++;
  770.         return FALSE;
  771.     }
  772.     if (!Asn1HdrDec (&Asn1, &End, &Cls, &Con, &Tag))
  773.     {
  774.         SnmpStat.InASNParseErrs++;
  775.         return FALSE;
  776.     }
  777.     if (Cls != ASN1_UNI || Con != ASN1_PRI || Tag != ASN1_INT)
  778.     {
  779.         SnmpStat.InASNParseErrs++;
  780.         return FALSE;
  781.     }
  782.     if (!Asn1IntDecUns (&Asn1, End, &Ver))
  783.     {
  784.         SnmpStat.InASNParseErrs++;
  785.         return FALSE;
  786.     }
  787.     if (!Asn1HdrDec (&Asn1, &End, &Cls, &Con, &Tag))
  788.     {
  789.         SnmpStat.InASNParseErrs++;
  790.         return FALSE;
  791.     }
  792.     if (Cls != ASN1_UNI || Con != ASN1_PRI || Tag != ASN1_OTS)
  793.     {
  794.         SnmpStat.InASNParseErrs++;
  795.         return FALSE;
  796.     }
  797.     if (!Asn1OtsDec (&Asn1, End, Com, ComSze, ComLen))
  798.     {
  799.         SnmpStat.InASNParseErrs++;
  800.         return FALSE;
  801.     }
  802.     if (Ver != SNMP_VERSION)
  803.     {
  804.         SnmpStat.InBadVersions++;
  805.         return FALSE;
  806.     }
  807.     if (!SnmpPduDec (&Asn1, Pdu, Lst, LstSze, LstLen))
  808.     {
  809.         SnmpStat.InASNParseErrs++;
  810.         return FALSE;
  811.     }
  812.     if (!Asn1EocDec (&Asn1, Eoc))
  813.     {
  814.         SnmpStat.InASNParseErrs++;
  815.         return FALSE;
  816.     }
  817.     Asn1Cls (&Asn1, &Snmp, &SnmpLen);
  818.     
  819.     SnmpStat.InPkts++;
  820.     switch (Pdu->Type)
  821.     {
  822.         case SNMP_PDU_GET:
  823.             SnmpStat.InGetRequests++;
  824.             break;
  825.         case SNMP_PDU_NEXT:
  826.             SnmpStat.InGetNexts++;
  827.             break;
  828.         case SNMP_PDU_RESPONSE:
  829.             SnmpStat.InGetResponses++;
  830.             break;
  831.         case SNMP_PDU_SET:
  832.             SnmpStat.InSetRequests++;
  833.             break;
  834.         case SNMP_PDU_TRAP:
  835.             SnmpStat.InTraps++;
  836.             break;
  837.     }
  838.     
  839.     return TRUE;
  840. }