/*************************************************/
/*Title:    snmp.h                               */
/*Descr:    SNMP Agent(Head File)                */
/*Author:   Liang Hanxi                          */
/*Create:   2002-4-1                             */
/*Modify:   2002-6-25                            */
/*************************************************/

#ifndef _SNMP_HEAD_FILE
#define _SNMP_HEAD_FILE
#include "../../../debug/src/include/debug.h"
#include "../../../iptrans/src/include/iptrans.h"
#include	<stdarg.h>
#include	<stdlib.h>
#include	<time.h>
#include	<ctype.h>
#include	<math.h>
#include 	<sys/types.h>
#include 	<sys/stat.h>
#include 	<unistd.h>
#include 	<string.h>


#define SNMP_DEBUG_MASK 0		
#define	SNMP_DEBUG_LOG	0

#define SNMP_VERSION	{9, 0, 1}
#define SNMP_V1			0
#define SNMP_V2			1
#define COMMUNITY		"public"
#define SNMP_ANY_COMMUNITY	0	//Should be set to 1 if snmp module is invoked in OMC 
#define BIND_MAX		50
#define OID_MAXLEN		32
//#define FIX_OID		{0x2b,0x06,0x01,0x04,0x01,0x8a,0x5d,0x01,0x01}
#define FIX_OID			{1,3,6,1,4,1,1373,1,3}
//{iso(1).org(3).dod(6).internet(1).private(4).enterprises(1).interWAVE(1373).1.1}
#define FIX_OIDLEN		8
#define SNMP_OID			{1,3,6,1,4,1,1373,1,3,2,3,3}
#define SNMP_OIDLEN			12

#define HEAP_SIZE		500*1024
#define SNMP_PORT		4957
#define SNMP_VAR_MAX	1600
//PDU
#define PDU_GET			0
#define PDU_GETNEXT		1
#define PDU_RSP			2
#define PDU_SET			3
#define PDU_GETBULK		5
#define PDU_INFORM		6
#define PDU_TRAP		7
#define PDU_REPORT		8
//variable type
#define NoSuchObject	0x80
#define NosuchInstance	0x81
#define EndOfMibView	0x82

//Debug
#define SNMPDB_IN		0x00
#define SNMPDB_OUT		0x01
#define SNMPDB_ERR		0x02
#define SNMPDB_NOREG	0x04
#define SNMPDB_VALUE	0x10
#define SNMPDB_ALARM	0x20
#define SNMPDB_MIB		0x40
#define SNMPDB_SYS      0x80

#ifndef _T_BYTE
#define _T_BYTE
	typedef	unsigned char BYTE;
#endif

#ifndef _T_BOOL
#define _T_BOOL
	typedef	unsigned char BOOL;
#endif

#ifndef _T_DWORD
#define _T_DWORD
	typedef	unsigned int DWORD;
#endif

#ifndef _T_WORD
#define _T_WORD
	typedef	unsigned short WORD;
#endif

// by simon at 23/9/25
//char				SnmpVer[16];

typedef struct var_list{
	DWORD			oid[OID_MAXLEN];
	BYTE			oidlen;
	BYTE			vartype;
	short			msglen;
	BYTE			msg[SNMP_VAR_MAX];
}var_list;

typedef struct snmp_pdu					//protocol data unit
{
	BYTE			pdu_type;		//0-get request 2-get(set) respond 3-set request 7-trap
	DWORD			request_id;
	char			community[16];
	BYTE			var_num;
	var_list		var[BIND_MAX];
	BYTE			error_status;		//0:no error 1:too big 2:nosuchname 3:badvalue 4:readonly 5:generr
	BYTE			error_index;	
	//add by yizane start
	DWORD			non_repeaters;		//in getbulk replace error_status
	DWORD			max_repetitions;	//in getbulk replace error_index
	//add by yizane end
} snmp_pdu;

typedef struct snmp_addr
{
	unsigned int remote_ip; //DWORD	remote_ip;
	unsigned int local_ip; //DWORD	local_ip;
	WORD	remote_port;
	WORD	local_port;
	BYTE	broadcast;
} snmp_addr;

typedef struct snmp_msg
{
	snmp_addr		addr;
	message_list	msglist;
}snmp_msg;

typedef struct snmp_buf
{
	snmp_msg		msgout[256];
	BYTE			readsub, writesub;
}snmp_buf;

//snmp_buf		snmp_outbuf;

typedef struct snmp_filter
{
	BYTE	flag;
	BYTE	type;
	BYTE	oidlen;
	DWORD	ip;
	DWORD	oid[OID_MAXLEN];
	short	local_port;
	short	remote_port;

	
}snmp_filter;

#define		MAX_SNMP_RECORD		32
#define		SNMP_SHM_KEY		0x60000001
#define		SNMP_SHM_PERM		0666

typedef	struct	snmp_log_info
{
	BYTE	currentNo;	/*from 0-MAX_SNMP_RECORD-1 */
	char	log_info[MAX_SNMP_RECORD][512];	
}snmp_log_info;


/*---------------------------------------*/
typedef void	(*trapcall)(BYTE oidlen, DWORD *oid, BYTE *pdata,WORD len,snmp_addr *addr);
typedef int		(*setcall)(BYTE oidlen, DWORD *oid, BYTE *pdata,WORD len);
typedef int		(*getcall)(BYTE oidlen, DWORD *oid, BYTE *pdata,BYTE *vartype);
//add by yizane start
typedef int		(*getnextcall)(BYTE in_oidlen, DWORD *in_oid, BYTE *oidlen, DWORD *oid, BYTE *pdata,BYTE *vartype);
//add by yizane end
typedef void	(*rspcall)(snmp_pdu *pdu,snmp_addr *addr);
typedef int		(*snmpcall)(snmp_pdu *pdu,snmp_addr *addr);

typedef struct mib_nod{
	DWORD		id;
	trapcall	trap_proc;
	setcall		set_proc;
	getcall		get_proc;
	//add by yizane start
	getnextcall		getnext_proc;
	//add by yizane end
	rspcall		rsp_proc;
	snmpcall	snmp_proc;
	struct mib_nod		*pnext;
	struct mib_nod		*psub;
}mib_nod;

typedef struct snmp_csta{
	DWORD		timestamp;
	DWORD		trap_in;
	DWORD		trap_out;
	DWORD		set_in;
	DWORD		set_out;
	DWORD		get_in;
	DWORD		get_out;
	//add by yizane start
	DWORD		getnext_in;
	DWORD		getnext_out;
	DWORD		getbulk_in;
	DWORD		getbulk_out;		
	//add by yizane end
	DWORD		rsp_in;
	DWORD		rsp_out;
	DWORD		fail_parse;
	DWORD		not_register;
	DWORD		fail_build;
}snmp_csta;

typedef struct snmp_mib{
	BYTE		sysid[2];
	BYTE		setpasswd[10];
	BYTE		getpasswd[10];
	DWORD		set_oid[64][20];
	DWORD		get_oid[64][20];
	DWORD		trap_oid[64][20];
	DWORD		rsp_oid[64][20];
}snmp_mib;

/********************************************************************/
/*						Macros For ASN.1 Encoding					*/
/********************************************************************/
#define insert_length(buf,pos,len) {\
	if(len<0)\
	{\
		snmp_debug(SNMPDB_ERR,"length should be larger than zero.");\
		return 0;\
	}\
	else if(len<0x80)\
		*(buf+pos--)=len;\
	else if(len<0x100)\
	{\
		*(buf+pos--)=len;\
		*(buf+pos--)=0x81;\
	}\
	else if(len<1600)\
	{\
		*(buf+pos--)=len & 0xFF;\
		*(buf+pos--)=len >>8;\
		*(buf+pos--)=0x82;\
	}\
	else\
	{\
		snmp_debug(SNMPDB_ERR,"Length(%d) exceed limit.varindex=%d",len,var_num);\
		return 0;\
	}\
}

#define enc_integer(buf,pos,val) {\
	if(val<0)\
	{\
		snmp_debug(SNMPDB_ERR,"integer should larger than zero.val=%d",val);\
		return -1;\
	}\
	else if(val<0x80)\
	{\
		*(buf+pos--)=(BYTE)val;\
		*(buf+pos--)=1;\
	}\
	else if(val<0x8000)\
	{\
		*(buf+pos--)=val & 0xFF;\
		*(buf+pos--)=val>>8;\
		*(buf+pos--)=2;\
	}\
	else if(val<0x800000)\
	{\
		*(buf+pos--)= val & 0xFF;\
		*(buf+pos--)=(val & 0xFFFF)>>8;\
		*(buf+pos--)=val>>16;\
		*(buf+pos--)=3;\
	}\
	else if(val<0x80000000)\
	{\
		*(buf+pos--)= val & 0xFF;\
		*(buf+pos--)=(val & 0xFFFF)>>8;\
		*(buf+pos--)=(val & 0xFFFFFF)>>16;\
		*(buf+pos--)=val>>24;\
		*(buf+pos--)=4;\
	}\
	else if(val<0xFFFFFFFF)\
	{\
		*(buf+pos--)= val & 0xFF;\
		*(buf+pos--)=(val & 0xFFFF)>>8;\
		*(buf+pos--)=(val & 0xFFFFFF)>>16;\
		*(buf+pos--)=val>>24;\
		*(buf+pos--)=0;\
		*(buf+pos--)=5;\
	}\
	else\
	{\
		snmp_debug(SNMPDB_ERR,"Integer's value exceed limit.val=%d",val);\
		return -1;\
	}\
}

void snmp_init(WORD nport);
void snmpmib_init();
void snmp_timer();
int snmp_send(snmp_pdu *msgbuf,snmp_addr *addr);
int snmp_plat_send(snmp_pdu *msgbuf,snmp_addr *addr);
int snmp_receive(snmp_pdu *msgbuf,snmp_addr *addr);
int get_response(BYTE oidlen, DWORD *oid, BYTE *pdata,BYTE *vartype);
int set_response(BYTE oidlen, DWORD *oid, BYTE *pdata,WORD datalen);
//add by yizane start
int	getnext_response(BYTE pr_oidlen, DWORD *pre_oid, BYTE *oidlen, DWORD *oid, BYTE *pdata,BYTE *vartype);
//add by yizane end
void inquire_trapmsg(trapcall trap_proc);
void inquire_setmsg(BYTE oidlen,DWORD *oid,setcall set_proc);
void inquire_getmsg(BYTE oidlen,DWORD *oid,getcall get_proc);
void inquire_rspmsg(BYTE oidlen,DWORD *oid,rspcall rsp_proc);
void inquire_snmpmsg(BYTE oidlen,DWORD *oid,snmpcall snmp_proc);
//add by yizane start
void inquire_getnextmsg(BYTE oidlen,DWORD *oid,getnextcall getnext_proc);
//add by yizane end
void rob_trapmsg(BYTE oidlen,DWORD *oid,trapcall trap_proc);
BYTE encode_integer(BYTE *buf,DWORD val);
DWORD decode_integer(BYTE *buf,BYTE len);
void snmp_log(char *info);
void snmp_debug(DWORD mask, const char *fmt,...);
void snmp_showbuf(DWORD mask, BYTE *buf, int len);
void snmp_logmsg(DWORD mask, snmp_pdu *pdu, snmp_addr *addr);
void snmp_debug_setup();
void snmp_debug_timer();
void snmp_debug_csta(BYTE npage,int instance);
void snmp_debug_hb(BYTE npage);
void snmp_init_serial_number(BYTE *Serial);
void snmp_set_timenosync();//call of this function will tell snmp module do not sync the omc time

#include "table.h"

/********************************************************************/
#endif

