#ifndef __BER_H__
#define __BER_H__
#include <stdlib.h>
#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__
syntax highlighted by Code2HTML, v. 0.9.1