• 【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 }
  • 相关阅读:
    pytest学习Pytest基础
    Docker基础认识
    DNS 域名解析协议
    Python从数据库取数据到Excel
    PO设计模式
    unittest多种加载执行用例方法
    Dev XtraGridView 添加行时滚动条(界面)随焦点滚动
    阅读器关闭时READ的尝试无效 真正原因 测试通过解决办法
    转帖 用SQL语句 查看 某一存储过程 所带参数
    转 C#多线程及控制线程数量,对for循环输出效率
  • 原文地址:https://www.cnblogs.com/utank/p/8671085.html
Copyright © 2020-2023  润新知