1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
|
#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(){ str[stringlen]='\0'; return str; }
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__
|