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 }