#ifndef __BER_H__ #define __BER_H__ #include #include "compat.h" enum Tags {INT_TAG=0x02,STRING_TAG=0x04,NULL_TAG=0x05,OID_TAG=0x06, CONSTRUCTOR_TAG=0x20,SEQUENCE_TAG=0x30,IPADDR_TAG=0x40, COUNTER_TAG=0x41,TIME_TICK_TAG=0x43,GET_REQ_TAG=0xa0, GET_NEXT_TAG=0xa1,GET_RESP_TAG=0xa2,SET_REQ_TAG=0xa3}; class BerEncodedData { unsigned char *data; unsigned long length; // this is the length of the data as it appears in the // packet not just the length of the data part of the // packet. In other words this includes the header // length. public: BerEncodedData *next; BerEncodedData(unsigned char *dat, unsigned long len); ~BerEncodedData(){delete data;} inline unsigned char *Data(){return data;} inline void Data(unsigned char* dat){data=dat;} inline unsigned int Length(){return length;} }; class BerBase { protected: // used for decoding the wire format BerBase(unsigned char* data); public: // head of the linked list that holds private copy of the data BerEncodedData *edatacache; // simple linkage field BerBase *next; inline BerBase():edatacache(NULL),next(NULL){} inline ~BerBase(){if(edatacache!=NULL) delete edatacache;} // returns a char* of malloced data that the application can use virtual BerEncodedData *encode(); // returns the head to the list of the data still owned by datastructure. virtual BerEncodedData *getdata(); /* return the full length basically to overcome the problems with seqences * where their edatacache->Length() is just the length of the header not * the length of the whole sequence. */ unsigned long fulllen(); // makes an ascii representation of the string and then puts it in buf // then returns the lenth it used up. -1 if it won't fit. virtual int print(char *buf, unsigned int len)=0; Tags type(){ return (Tags) *(edatacache->Data()); } }; class BerNull: public BerBase{ public: BerNull(unsigned char *); inline BerNull(){} virtual BerEncodedData *encode(); virtual int print(char *buf, unsigned int len); }; class BerInt: public BerBase { long val; public: BerInt(unsigned char *str); inline BerInt(long value): val(value){} virtual BerEncodedData *encode(); virtual int print(char *buf, unsigned int len); inline long value(){ return val;} }; class BerTimeTick: public BerBase { unsigned long val; public: BerTimeTick(unsigned char *str); virtual int print(char *buf, unsigned int len); virtual BerEncodedData *encode(); inline unsigned long value(){ return val;} }; class BerString: public BerBase { char *str; unsigned int stringlen; public: // this one is for decoding the wire format of the string only. It is not // for a typical initialization of the class. BerString(unsigned char *strng); // this one is for normal use BerString(CONST char *strng,unsigned int length); virtual BerEncodedData *encode(); virtual int print(char *buf, unsigned int len); int copy(char *buf, unsigned int len); inline const char *Str(){ return str; } // Warning: no terminator! inline unsigned int strlen(){ return stringlen; } }; class BerIPAddr: public BerBase { unsigned char *ipaddr; unsigned int len; public: BerIPAddr(unsigned char *strng); BerIPAddr(CONST char *addr,int len); virtual BerEncodedData *encode(); virtual int print(char *buf, unsigned int len); inline unsigned char *IPaddr(){return ipaddr;} inline unsigned int Len(){return len;} }; class BerOid: public BerBase { unsigned char *eoid; unsigned int oidbytes; public: BerOid(unsigned char *str); //decoding wire protocol only BerOid(CONST char *oidstr,unsigned int len); int operator==(BerOid & other); virtual BerEncodedData *encode(); virtual int print(char *buf, unsigned int len); }; class BerSequence: public BerBase{ BerBase *head,*tail; Tags tag; unsigned long seqlen; public: BerSequence(unsigned char *str); BerSequence(Tags tag,unsigned int entries ...); ~BerSequence(); BerEncodedData *encode(); BerEncodedData *getdata(); // void prepend(unsigned int num ...); void append(unsigned int num ...); BerBase *peek(unsigned int num); // look at the num'd entry in the list BerBase *extract(unsigned int num); // remove the num'd entry in the list virtual int print(char *buf, unsigned int len); }; unsigned char *start_data(Tags type,unsigned int len, unsigned char &headlen); unsigned long unpack_len(unsigned char *start,unsigned char &headerlen); #endif //__BER_H__