【TLV】非递归TLV数据解析

  1 #include <stdio.h>
  2 
  3 
  4 #define X_LEN_OF_TAG_MAX        ( 2 )
  5 #define X_LEN_OF_LEN_MAX        ( 2 )
  6 
  7 struct st_tlv_t {
  8     unsigned int TAG;
  9     unsigned char isCustructed;
 10     unsigned int valLen;
 11     unsigned char *pVal;
 12 
 13 };
 14 
 15 static int skipZeroBytes( unsigned char **pcur, unsigned char *end )
 16 {
 17     while( **pcur == 0 && (*pcur < end) )
 18         (*pcur)++;
 19         
 20     if( *pcur < end )
 21         return 1;
 22         
 23     return 0;    
 24 }
 25 
 26 static int parseTag( unsigned char **pcur, unsigned char *end, struct st_tlv_t *tlv )
 27 {
 28     unsigned char *pp;
 29     int lenOfTag;
 30     int i;
 31     
 32     if( *pcur >= end )
 33         return 0;
 34         
 35     pp = *pcur;
 36 
 37     lenOfTag = 1;
 38     if( (*pp++ & 0x1f) == 0x1f )
 39     {
 40         do {
 41             if( pp >= end )
 42                 return 0;
 43             
 44             lenOfTag++;    
 45         } while( (*pp++) & 0x80 );    
 46     }
 47     if( lenOfTag > X_LEN_OF_TAG_MAX )
 48     {
 49         return 0;    
 50     }
 51         
 52     tlv->isCustructed = ( **pcur & ( 1 << 5 ) ) ? 1 : 0;
 53     
 54     tlv->TAG = 0;
 55     for( i = 0; i < lenOfTag; i++ )
 56     {
 57         tlv->TAG <<= 8;
 58         tlv->TAG |= *(*pcur + i );
 59     }
 60     
 61     (*pcur) += lenOfTag;
 62     //printf("tlv->TAG:%x
", tlv->TAG);
 63     return 1;
 64 }
 65 
 66 static int parseLength( unsigned char **pcur, unsigned char *end, struct st_tlv_t *tlv )
 67 {
 68     unsigned char *pp;
 69     int lenOfLen;
 70     int i;
 71     
 72     if( *pcur >= end || **pcur == 0 )
 73         return 0;
 74         
 75     pp = *pcur;
 76     
 77     if( *pp & 0x80 )
 78     {
 79         lenOfLen = *pp & 0x7F;
 80         if( pp + lenOfLen >= end )
 81             return 0;
 82         if( lenOfLen > X_LEN_OF_LEN_MAX )
 83             return 0;
 84         pp++;
 85         tlv->valLen = 0;
 86         for( i = 0; i < lenOfLen; i++ )
 87         {
 88             tlv->valLen <<= 8;
 89             tlv->valLen |= *(pp + i );
 90         }
 91         (*pcur) += (lenOfLen+1);
 92     }
 93     else
 94     {
 95         tlv->valLen = **pcur;
 96         (*pcur)++;
 97     }
 98     //printf("tlv->valLen:%d
", tlv->valLen);
 99     return 1;
100 }
101 
102 static int parseValue( unsigned char **pcur, unsigned char *end, struct st_tlv_t *tlv )
103 {
104     if( (*pcur + tlv->valLen) > end )
105         return 0;
106         
107     tlv->pVal = ( unsigned char *)(*pcur);
108     
109     return 1;    
110 }
111 
112 
113 int parseTlv( unsigned char *buffer, int length, struct st_tlv_t *tlv )
114 {
115     unsigned char *cur;
116     unsigned char *end;
117     
118     cur = buffer;
119     end = buffer + length;
120     
121     if( !skipZeroBytes( &cur, end ) )
122         return 0;
123         
124     if( !parseTag( &cur, end, tlv ) )
125         return 0;
126 
127     if( !parseLength( &cur, end, tlv ) )
128         return 0;
129 
130     if( !parseValue( &cur, end, tlv ) )
131         return 0;
132     
133     return 1;
134 }
135 
136 int printTlv( struct st_tlv_t *tlv )
137 {
138     int i;
139     printf("
[%x] len:%d
", tlv->TAG, tlv->valLen);
140     for( i = 0; i < tlv->valLen; i++ )
141         printf("%02x", tlv->pVal[i]);
142     printf("
");
143     
144     return 0;
145 }
146 
147 int parseTlvXXX(  unsigned char *buffer, int length, int reverse )
148 {
149     unsigned char *cur;
150     unsigned char *end;    
151     struct st_tlv_t tlv;
152     
153     cur = buffer;
154     end = buffer + length;
155 
156     while( cur < end )
157     {
158         if( !parseTlv( cur, end-cur, &tlv ) )
159             return 0;
160         
161         printTlv( &tlv );
162         
163         // 如果是复合型的TAG,则进入复合TAG内部继续分析
164         if( tlv.isCustructed && reverse )
165         {
166             cur = tlv.pVal;
167         }
168         else // 如果是简单型的TAG,则分析下一个TAG
169         {
170             cur = tlv.pVal + tlv.valLen;
171         }
172     }
173 
174     
175     if( cur > end )
176         return 0;
177 
178     return 1;
179 }
180 
181 int main( void )
182 {
183     int ret;
184     
185     unsigned char tlv_buf0[] = {
186         0x70,0x28,0x61,0x26,0x4f,0x07,0xa0,0x00,
187         0x00,0x03,0x33,0x01,0x01,0x50,0x0b,0x50,
188         0x42,0x4f,0x43,0x20,0x43,0x72,0x65,0x64,
189         0x69,0x74,0x87,0x01,0x01,0x9f,0x12,0x0a,
190         0x50,0x42,0x4f,0x43,0x20,0x44,0x45,0x42,
191         0x49,0x54,0x90,0x00
192     };
193     unsigned char tlv_buf1[] = {
194         0x00,0x00,0x00,
195         0x70,0x81,0x83,0x90,0x81,0x80,0x25,0x3c,
196         0x3c,0x1f,0xd9,0x92,0x8d,0x88,0x21,0x11,
197         0xa6,0xac,0x4c,0xa2,0x07,0xdf,0x93,0x10,
198         0x64,0x23,0x95,0xea,0x09,0x7b,0x3c,0xb1,
199         0x6d,0x51,0x76,0x53,0x35,0x38,0x03,0xc2,
200         0xc1,0x03,0x3e,0x4a,0xac,0xb9,0x73,0x5d,
201         0x2e,0x69,0xca,0x49,0x8f,0xeb,0x4c,0xc0,
202         0xae,0xe1,0xff,0xc7,0xf5,0x44,0x83,0x09,
203         0x3a,0x30,0xcc,0xbf,0x6b,0x20,0x11,0xd6,
204         0x09,0xe5,0x2f,0xd7,0x87,0x76,0xb6,0x6b,
205         0x6d,0x86,0x95,0xcb,0xc0,0x46,0x21,0x6b,
206         0xf8,0x1c,0x52,0xd5,0xc2,0xf9,0x47,0xde,
207         0xe3,0xad,0xd7,0x20,0x9a,0xb3,0x27,0xf2,
208         0x9c,0x10,0x6b,0xfa,0x0e,0x29,0x1d,0x9d,
209         0xab,0x00,0x91,0x06,0xf4,0x89,0xba,0x59,
210         0x43,0x6d,0xa9,0x46,0x75,0xdf,0x9d,0x31,
211         0xdc,0xaf,0xbd,0x6a,0xbe,0x20,
212     };
213     unsigned char tlv_buf2[] = {
214         0x6f,0x24,0x84,0x0e,0x31,0x50,0x41,0x59,
215         0x2e,0x53,0x59,0x53,0x2e,0x44,0x44,0x46,
216         0x30,0x31,0xa5,0x12,0x88,0x01,0x01,0x5f,
217         0x2d,0x08,0x7a,0x68,0x65,0x6e,0x66,0x72,
218         0x64,0x65,0x9f,0x11,0x01,0x01    
219     };
220 
221     ret = parseTlvXXX( tlv_buf0, sizeof(tlv_buf0), 0 );
222     printf("0-parseTlvXX: %d
", ret);
223 
224     ret = parseTlvXXX( tlv_buf1, sizeof(tlv_buf1), 1 );
225     printf("1-parseTlvXX: %d
", ret);
226     
227 
228     ret = parseTlvXXX( tlv_buf2, sizeof(tlv_buf2), 1 );
229     printf("2-parseTlvXX: %d
", ret);
230     
231     return 0;    
232 }
原文地址:https://www.cnblogs.com/utank/p/8671085.html