/* Portions of the SNMP code are from the Beholder project and are       */
/* Copyright (C) 1993 DNPAP group                                        */
/* Portions Copyright (c) 2000 Erick Engelke                             */

#ifndef _SNMP_H_
#define _SNMP_H_

#include <rtos.h>
#include "dnpap.h"

#define SNMP_VERSION    0

/* Default Sizes */

#define SNMP_SIZE_COMM              255
#define SNMP_SIZE_OBJECTID          63
#define SNMP_SIZE_BUFCHR            255
#define SNMP_SIZE_BUFINT            63

#define SNMP_SIZE_SMALLOBJECTID     15

/* Requests */

#define SNMP_PDU_GET                0
#define SNMP_PDU_NEXT               1
#define SNMP_PDU_RESPONSE           2
#define SNMP_PDU_SET                3
#define SNMP_PDU_TRAP               4

/* Errors */
#define SNMP_NOOVERRIDE            -1

#define SNMP_NOERROR                0
#define SNMP_TOOBIG                 1
#define SNMP_NOSUCHNAME             2
#define SNMP_BADVALUE               3
#define SNMP_READONLY               4
#define SNMP_GENERROR               5

/* General Traps */

#define SNMP_TRAP_COLDSTART          0
#define SNMP_TRAP_WARMSTART          1
#define SNMP_TRAP_LINKDOWN           2
#define SNMP_TRAP_LINKUP             3
#define SNMP_TRAP_AUTFAILURE         4
#define SNMP_TRAP_EQPNEIGHBORLOSS    5
#define SNMP_TRAP_ENTSPECIFIC        6

/* Rmon Status */

#define SNMP_VALID               1
#define SNMP_CREATEREQUEST       2
#define SNMP_UNDERCREATION       3
#define SNMP_INVALID             4

/* Types */

#define SNMP_NULL                0
#define SNMP_INTEGER             1    /* LngInt */
#define SNMP_OCTETSTR            2    /* BufChr */
#define SNMP_OBJECTID            3    /* BufInt */
#define SNMP_IPADDR              4    /* LngUns */
#define SNMP_COUNTER             5    /* LngUns */
#define SNMP_GAUGE               6    /* LngUns */
#define SNMP_TIMETICKS           7    /* LngUns */
#define SNMP_OPAQUE              8    /* BufChr */
#define SNMP_DISPLAYSTR          2    /* BufChr */

/* Typedefs */

typedef struct  _SNMP_STAT       SNMP_STAT;
typedef struct  _SNMP_REQUEST    SNMP_REQUEST;
typedef struct  _SNMP_TRAP       SNMP_TRAP;
typedef union   _SNMP_PDU        SNMP_PDU;
typedef union   _SNMP_SYNTAX     SNMP_SYNTAX;
typedef struct  _SNMP_OBJECT     SNMP_OBJECT;

union _SNMP_SYNTAX
{
         LONG            LngInt;
    LWORD           LngUns;
    BYTE            BufChr [SNMP_SIZE_BUFCHR];
    LONG            BufInt [SNMP_SIZE_BUFINT];
    VOID            *Ptr;
};

struct _SNMP_OBJECT
{
    WORD            Request;
    LONG            Id [SNMP_SIZE_OBJECTID];
    UINT                IdLen;
    WORD            Type;
    SNMP_SYNTAX     Syntax;
    UINT                SyntaxLen;
};


struct _SNMP_STAT
{
         long unsigned   OutPkts;
         long unsigned   OutTooBigs;
         long unsigned   OutNoSuchNames;
         long unsigned   OutBadValues;
         long unsigned   OutReadOnlys;
    long unsigned   OutGenErrs;
    long unsigned   OutGetRequests;
    long unsigned   OutGetNexts;
    long unsigned   OutSetRequests;
    long unsigned   OutGetResponses;
    long unsigned   OutTraps;
    long unsigned   InPkts;
    long unsigned   InTooBigs;
    long unsigned   InNoSuchNames;
    long unsigned   InBadValues;
    long unsigned   InReadOnlys;
    long unsigned   InGenErrs;
    long unsigned   InGetRequests;
    long unsigned   InGetNexts;
    long unsigned   InSetRequests;
    long unsigned   InGetResponses;
         long unsigned   InTraps;
         long unsigned   InBadVersions;
         long unsigned   InASNParseErrs;
         long unsigned   InBadTypes;
};


struct _SNMP_REQUEST
{
         unsigned        Type;
         long unsigned   Id;
         unsigned        ErrorStatus;
         unsigned        ErrorIndex;
};


struct _SNMP_TRAP
{
    unsigned        Type;
    unsigned long   Id [SNMP_SIZE_BUFINT];
    unsigned        IdLen;
    long unsigned   IpAddress;
    unsigned        General;
    unsigned        Specific;
    long unsigned   Time;
};


union _SNMP_PDU
{
    unsigned        Type;
    SNMP_TRAP       Trap;
    SNMP_REQUEST    Request;
};


extern INT snmpErrStatus;
extern CONST CHAR *SnmpTrap[];

BOOLEAN SnmpEnc(BYTE        **Snmp,
                                         unsigned    *SnmpLen,
                                         SNMP_PDU    *Pdu,
                                         BYTE        *Com,
                                         unsigned    ComLen,
                                         SNMP_OBJECT *Lst,
                                         unsigned    LstLen);

BOOLEAN SnmpDec(BYTE        *Snmp,
                unsigned    SnmpLen,
                SNMP_PDU    *Pdu,
                BYTE        *Com,
                unsigned    ComSze,
                unsigned    *ComLen,
                SNMP_OBJECT *Lst,
                unsigned    LstSze,
                unsigned    *LstLen);

#define SNMP_OID_SIZE 25
typedef long (*SNMP_FUNC)(void *, char *, int, SNMP_OBJECT *, DWORD, DWORD);

typedef struct _esnmp_oid {
         int     oidlen;
         int     oid[ SNMP_OID_SIZE ];       /* last in list is -1 */
         SNMP_FUNC fn;
    DWORD   data1, data2;
} esnmp_oid;

void snmp_compile_oids( esnmp_oid far *p );
void snmpthread( DWORD dummy );
extern crit_x *_snmp_cs;

int snmp_trap( DWORD remote_ip, char *community, char *entOID, char *OID, DWORD agent,
        int genTrapType, int specTrapType, int valueType, void *value, int valueLen );

/* Multiple traps in one */
int snmp_traps( DWORD remote_ip, char *community, char *entOid,
        int count, char **OID, DWORD agent,
        int genTrapType, int specTrapType, int *valueType, void **value, int *valueLen );

extern void (*_snmp_prewalk)( int op,  SNMP_OBJECT *list );
extern int (*_snmp_override)(  BYTE *com, int op, SNMP_OBJECT *list );

/*
 * compare_oid - tell us if src is > (+1), = (0) or < (-1) cmp
 */
int _snmp_compare_oid( SNMP_OBJECT *src, esnmp_oid *cmp );

// snmp_copyobjectid - copies "1.3.6..." to a reply packet and sets length
void snmp_copyobjectid( DWORD * dest, char *source, UINT *len );


/* If you need to process multi-MIB PDUs, set global variable snmpd_maxvars
 * to some higher number inside your application, before you start the
 * snmpd thread.  It is used to allocate buffers at thread start time
 */
extern int snmpd_maxvars;

#endif

