source: libpacketdump/asn1.cc @ 950d54a

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivegetfragoffhelplibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since 950d54a was 950d54a, checked in by Perry Lorier <perry@…>, 16 years ago

Add libpacketdump to cvs

  • Property mode set to 100644
File size: 7.9 KB
Line 
1#include <list>
2#include <vector>
3#include <inttypes.h>
4#include <assert.h>
5#include <ctype.h>
6#include <string>
7#ifdef TEST
8#include <stdio.h>
9#endif
10#include "asn1.h"
11#include <boost/format.hpp>
12
13
14const char *const ASN_type_class_t_names[] = {
15                "Universal",
16                "Application",
17                "Context Specific",
18                "Private",
19};
20
21ASN_type::ASN_type(uint8_t _type) : type(_type){
22        /* Not implemented multibyte tags yet */
23        assert(getTag() != 0x1F);
24}
25
26ASN_type_class_t ASN_type::getClass(void) const {
27        return (ASN_type_class_t) (type >> 6);
28}
29
30bool ASN_type::isPrimative(void) const {
31        return !((type >> 5) & 0x01);
32}
33
34int ASN_type::getTag(void) const {
35        return (type & 0x1F);
36}
37
38ASN_data::ASN_data(ASN_type _type,uint64_t _len) : type(_type),
39                                                len(_len) 
40{
41};
42
43void ASN_data::parse(void) 
44{
45};
46
47void ASN_data::display(void) {
48                        printf(" ASN: %s %s 0x%x\n",
49                                        ASN_type_class_t_names[(int)type.getClass()],
50                                        type.isPrimative() 
51                                                ? "Primative" 
52                                                : "Constructed",
53                                        type.getTag()
54                              );
55                        buffer_t::const_iterator it=buffer.begin();
56                        while(it!=buffer.end()) {
57                                printf(" ASN:");
58
59                                buffer_t::const_iterator hexit=it;
60                                for(uint64_t i=0;i<8;i++) {
61                                        if (hexit!=buffer.end()) {
62                                                printf(" %02x",*hexit);
63                                                hexit++;
64                                        }
65                                        else
66                                                printf("   ");
67                                }
68                                printf("\t");
69                                for(uint64_t i=0;i<8;i++) {
70                                        if (it!=buffer.end()) {
71                                                printf("%c",
72                                                        isprint(*it)
73                                                        ? *it
74                                                        : '.');
75                                                it++;
76                                        }
77                                }
78                                printf("\n");
79                        }
80                }; // display
81
82ASN_data::~ASN_data() {};
83
84std::string ASN_data::toString(void) {
85        return std::string("Unknown");
86};
87
88bool ASN::eof(void) const { 
89        return buffer.size()<=0; 
90}
91
92// Type 0 - End of contents
93// Type 1 - Bool
94class ASN_bool : public ASN_data {
95        public:
96                ASN_bool(ASN_type t,uint64_t l) : ASN_data(t,l) {};
97                bool getValue(void) const {
98                        return *buffer.begin()!=0;
99                }
100                void display(void) const {
101                        printf(" ASN: Bool:\t%s\n",getValue()
102                                                ?"True":
103                                                "False");
104                }
105};
106
107// Type 2 - Integer
108class ASN_int : public ASN_data {
109        public:
110                ASN_int(ASN_type t,uint64_t l) : ASN_data(t,l) {};
111                uint64_t getValue(void) {
112                        uint64_t val=0;
113                        for(buffer_t::const_iterator i=buffer.begin();
114                                        i!=buffer.end();
115                                        i++) {
116                                val=(val<<8)+*i;
117                        }
118                        return val;
119                }
120                void display(void) {
121                        printf(" ASN: Int:\t0x");
122                        // Yeah, this is a dirty trick
123                        for(buffer_t::const_iterator i=buffer.begin();
124                                        i!=buffer.end();
125                                        i++) {
126                                printf("%02x",*i);
127                        }
128                        printf("\n");
129                }
130};
131
132// Type 3 -- Bitstring
133class ASN_bitstring : public ASN_data {
134        public:
135                ASN_bitstring(ASN_type t,uint64_t l) : ASN_data(t,l) {};
136                void display(void) {
137                        printf(" DEBUG: %i bytes\n",buffer.size());
138                        printf(" ASN: Bitstring:\t0b");
139                        buffer_t::const_iterator i=buffer.begin();
140                        //int bits=*i;
141                        i++;
142                        for( ;
143                                        i!=buffer.end();
144                                        i++) {
145                                for (int j=0;j<7;j++) {
146                                        if (*i & (1<<(7-j))) {
147                                                printf("1");
148                                        }
149                                        else {
150                                                printf("0");
151                                        }
152                                }
153                                printf(" ");
154                        }
155                        printf("\n");
156                }
157};
158// Types - Simple Strings
159class ASN_string : public ASN_data {
160        public:
161                ASN_string(ASN_type t,uint64_t l) : ASN_data(t,l) {};
162                std::string getValue(void) {
163                        std::string s;
164                        for(buffer_t::const_iterator i=buffer.begin();
165                                        i!=buffer.end();
166                                        i++) {
167                                s=s+(char)*i;
168                        }
169                        return s;
170                }
171                void display(void) {
172                        printf(" ASN: String:\t%s\n",getValue().c_str());
173                }
174};
175// Type 5 - Null
176class ASN_null : public ASN_data {
177        public:
178                ASN_null(ASN_type t,uint64_t l) : ASN_data(t,l) {};
179                void display(void) { printf(" ASN: NULL\n"); }
180};
181
182// Type 6 - Object Identifier
183class ASN_oid : public ASN_data {
184        private:
185                std::vector<uint64_t> oid;
186                uint64_t decodeInt(void) {
187                        uint64_t x=0;
188                        while(*buffer.begin()&0x80) {
189                                x=(x<<7)|(*buffer.begin()&~0x80);
190                                buffer.pop_front();
191                        }
192                        x=(x<<7)|(*buffer.begin());
193                        buffer.pop_front();
194                        return x;
195                }
196        public:
197                ASN_oid(ASN_type t,uint64_t l) : ASN_data(t,l) {};
198                void parse(void) {
199                        uint64_t first = decodeInt();
200                        oid.push_back(first/40);
201                        oid.push_back(first%40);
202                        while(buffer.size()!=0)
203                                oid.push_back(decodeInt());
204                };
205                void display(void) {
206                        printf(" ASN: OID");
207                        for(std::vector<uint64_t>::const_iterator i=oid.begin();
208                                        i!=oid.end();
209                                        i++) {
210                                printf(" %lli",*i);
211                        }
212                        printf("\n");
213                };
214                std::string toString(void) {
215                        std::string ret;
216                        for(std::vector<uint64_t>::const_iterator i=oid.begin();
217                                        i!=oid.end();
218                                        i++) {
219                                ret+=(boost::format(" %i") % *i).str();
220                        }
221                        return ret;
222                }
223};
224
225
226// Abstract Container for sets and sequences
227class ASN_container : public ASN_data {
228        protected:
229                std::vector<ASN_data *> subencodings;
230        public:
231                typedef std::vector<ASN_data *>::const_iterator const_iterator;
232                ASN_container(ASN_type t,uint64_t l) : ASN_data(t,l) {};
233                void parse() {
234                        ASN n;
235                        n.feed(buffer,len);
236                        while (!n.eof()) {
237                                subencodings.push_back(n.getEncoding());
238                        }
239                };
240                const_iterator begin(void) { return (const_iterator)subencodings.begin(); }
241                const_iterator end(void) { return (const_iterator)subencodings.end(); }
242};
243
244// Type 16 - Sequence
245class ASN_sequence : public ASN_container {
246        public:
247                ASN_sequence(ASN_type t,uint64_t l) : ASN_container(t,l) {};
248                void display(void) {
249                        if (subencodings.size()==2 
250                          &&subencodings[0]->type.getTag() == 6) {
251                                printf(" ASN: Sequence OID (%s)\n",subencodings[0]->toString().c_str());
252                                subencodings[1]->display();
253                                return;
254                        }
255
256                        printf(" ASN: Sequence begin (%i items)\n",subencodings.size());
257                        for(const_iterator i=begin();
258                                        i!=end();
259                                        i++)
260                                (*i)->display();
261                        printf(" ASN: Sequence end\n");
262                }
263};
264// Type 17 - Set
265class ASN_set : public ASN_container {
266        public:
267                ASN_set(ASN_type t,uint64_t l) : ASN_container(t,l) {};
268                void display(void) {
269                        if (subencodings.size()==1) {
270                                printf(" ASN: Single item set\n");
271                                subencodings[0]->display();
272                                return;
273                        }
274                        printf(" ASN: Set begin\n");
275                        for(const_iterator i=begin();
276                                        i!=end();
277                                        i++)
278                                (*i)->display();
279                        printf(" ASN: Set end\n");
280                }
281};
282
283
284void ASN::feed(char *buff,int size)
285{
286        while(size-->0) 
287                buffer.push_back(*(buff++));
288}
289
290
291ASN_type ASN::getType(void)
292{
293        ASN_type t(*buffer.begin());
294        buffer.pop_front();
295        return t;
296}
297
298uint64_t ASN::getLength(void)
299{
300        // TODO Only supports definite encodings
301        uint64_t len=0;
302        uint8_t x = *buffer.begin();
303        buffer.pop_front();
304        assert(x != 0x80); // Indefinate encoding
305        // Short form
306        if ((x&0x80)==0) {
307                return x;
308        }
309        x&=~0x80;
310        // Long form
311        while(x-->0) {
312                len=(len<<8)|*buffer.begin();
313                buffer.pop_front();
314        }
315        return len;
316}
317
318ASN_data *ASN::getEncoding(void) 
319{
320        ASN_type t=getType();
321        uint64_t l=getLength();
322        ASN_data *ret;
323        switch(t.getClass()) {
324                case Universal:
325                        switch(t.getTag()) {
326                                case 1:
327                                        ret=new ASN_bool(t,l);
328                                        break;
329                                case 2:
330                                        ret=new ASN_int(t,l);
331                                        break;
332                                case 3:
333                                        ret=new ASN_bitstring(t,l);
334                                        break;
335                                case 5:
336                                        ret=new ASN_null(t,l);
337                                        break;
338                                case 6:
339                                        ret=new ASN_oid(t,l);
340                                        break;
341                                case 16:
342                                        ret=new ASN_sequence(t,l);
343                                        break;
344                                case 17:
345                                        ret=new ASN_set(t,l);
346                                        break;
347                                case 18:
348                                case 19:
349                                case 20:
350                                case 21:
351                                case 22:
352                                case 25:
353                                case 26:
354                                case 27:
355                                        ret=new ASN_string(t,l);
356                                        break;
357                                default:
358                                        ret=new ASN_data(t,l);
359                                        break;
360                        }
361                        break;
362                default:
363                        ret=new ASN_data(t,l);
364                        break;
365        }
366        ret->feed(buffer,l);
367        ret->parse();
368        return ret;
369}
370
371void ASN_data::feed(std::list<uint8_t> &buff,uint64_t len)
372{
373        while(len-->0) {
374                buffer.push_back(*buff.begin());
375                buff.pop_front();
376        }
377}
378
379void ASN::feed(std::list<uint8_t> &buff,uint64_t len)
380{
381        while(len-->0) {
382                buffer.push_back(*buff.begin());
383                buff.pop_front();
384        }
385}
386#ifdef TEST
387int main(int argc, char **argv)
388{
389        FILE *f=fopen(argv[1],"r");
390        ASN *asn = new ASN();;
391        char buffer[1024];
392        int size;
393
394        size=fread(buffer,1,sizeof(buffer),f);
395        printf("Read %i bytes\n",size);
396       
397        asn->feed(buffer,size);
398
399        while(!asn->eof()) {
400                ASN_data *data= asn->getEncoding();
401
402                data->display();
403        }
404
405        return 0;
406}
407#endif
Note: See TracBrowser for help on using the repository browser.