实验:对OCI测试程序产生回包数据的读取

前言

尝试分析OCI测试程序产生回包流的读取。
用调试器带上OCI测试程序跑,跟到OCI dll中,数据分隔已经搞清了。按照数据分隔往出读,含义也能猜个大概。
但是OCI的回包流格式和sqldeveloper.exe的回包流格式不一样。
sqldeveloper.exe是java写的,不知道他调用的本地函数是哪个。只能靠猜,不靠谱。
看sqldeveloper和oracle数据库的包交互,好像磋商了通讯协议的版本。产生的回包,格式比OCI的紧凑(size小)。
OCI应该也能干这事,初学,没有深入实验了。
做这个实验,为以后抓包和分析包的实验留一个测试工程。稍加改动就可以做别的实验。

测试工程

src_oci_tns_package_reader.7z
编译环境 : vs2017 vc++ console on win10x64

功能:
进行抓包,根据OCI dll读取回包的反汇编实现为依据,尝试在测试程序中模拟读取并显示。
经过读取后,OCI回包的2进制流,已经变成了可以猜测理解的数据。

运行效果

packet_reader 1.0.0.1 2018-01-13 13:21
if need quit, press 'q'
pcap loop ...
header->caplen = 66, header->len = 66
header->caplen = 66, header->len = 66
header->caplen = 54, header->len = 54
header->caplen = 112, header->len = 112
header->caplen = 298, header->len = 298
header->caplen = 54, header->len = 54
header->caplen = 62, header->len = 62
header->caplen = 112, header->len = 112
header->caplen = 298, header->len = 298
header->caplen = 54, header->len = 54
header->caplen = 86, header->len = 86
header->caplen = 222, header->len = 222
header->caplen = 217, header->len = 217
header->caplen = 214, header->len = 214
header->caplen = 305, header->len = 305
header->caplen = 539, header->len = 539
header->caplen = 93, header->len = 93
header->caplen = 54, header->len = 54
header->caplen = 293, header->len = 293
header->caplen = 135, header->len = 135
header->caplen = 80, header->len = 80
header->caplen = 326, header->len = 326
header->caplen = 444, header->len = 444
header->caplen = 1472, header->len = 1472
header->caplen = 1240, header->len = 1240
header->caplen = 380, header->len = 380
header->caplen = 1001, header->len = 1001
>> proc_tns_data_describe_information
--------------------------------------------------------------------------------
proc_tns_data_describe_information 0x00000237229C0751, length = 936
--------------------------------------------------------------------------------
00000000    17 00 00 00 27 E6 48 2C 16 04 06 B1 E1 1B A6 43     ....'.H,.......C
00000010    F9 DF 70 B5 78 76 01 0E 0B 29 0B 30 04 00 00 03     ..p.xv...).0....
00000020    00 00 00 51 01 01 80 00 00 32 00 00 00 00 00 00     ...Q.....2......
00000030    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00     ................
00000040    00 69 03 01 00 32 00 00 00 00 00 00 00 00 05 05     .i...2..........
00000050    00 00 00 05 54 4F 50 49 43 00 00 00 00 00 00 00     ....TOPIC.......
00000060    00 00 00 00 00 00 00 01 02 00 00 81 16 00 00 00     ................
00000070    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00     ................
00000080    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00     ................
00000090    00 03 03 00 00 00 03 53 45 51 00 00 00 00 00 00     .......SEQ......
000000A0    00 00 01 00 00 00 00 00 01 01 80 00 00 E8 03 00     ................
000000B0    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00     ................
000000C0    00 00 00 00 00 69 03 01 00 E8 03 00 00 00 00 00     .....i..........
000000D0    00 01 04 04 00 00 00 04 49 4E 46 4F 00 00 00 00     ........INFO....
000000E0    00 00 00 00 02 00 00 00 00 00 07 00 00 00 07 78     ...............x
000000F0    76 01 0E 16 03 0C 01 00 00 00 E8 1F 00 00 0A 00     v...............
00000100    00 00 0A 00 00 00 00 00 00 00 06 01 1A 00 03 00     ................
00000110    00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00     ................
00000120    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00     ................
00000130    00 00 00 00 00 00 00 00 00 00 00 00 07 2A 2C 01     .............*,.
00000140    03 06 41 43 43 45 50 54 02 C1 02 1C 69 6E 66 6F     ..ACCEPT....info
00000150    20 3D 20 68 65 6C 6C 6F 2C 20 77 6F 72 6C 64 2C      = hello, world,
00000160    20 53 45 51 20 3D 20 31 08 06 00 65 84 16 00 00      SEQ = 1...e....
00000170    00 00 00 03 00 00 00 00 00 00 00 00 00 00 00 00     ................
00000180    00 00 00 00 00 13 00 00 00 00 00 12 00 00 00 12     ................
00000190    53 49 4D 50 4C 49 46 49 45 44 20 43 48 49 4E 45     SIMPLIFIED CHINE
000001A0    53 45 10 00 00 00 00 00 05 00 00 00 05 43 48 49     SE...........CHI
000001B0    4E 41 09 00 00 00 00 00 03 00 00 00 03 EF BF A5     NA..............
000001C0    00 00 00 00 00 00 05 00 00 00 05 43 48 49 4E 41     ...........CHINA
000001D0    01 00 00 00 00 00 02 00 00 00 02 2E 2C 02 00 00     ............,...
000001E0    00 00 00 08 00 00 00 08 41 4C 33 32 55 54 46 38     ........AL32UTF8
000001F0    0A 00 00 00 00 00 09 00 00 00 09 47 52 45 47 4F     ...........GREGO
00000200    52 49 41 4E 0C 00 00 00 00 00 09 00 00 00 09 44     RIAN...........D
00000210    44 2D 4D 4F 4E 2D 52 52 07 00 00 00 00 00 12 00     D-MON-RR........
00000220    00 00 12 53 49 4D 50 4C 49 46 49 45 44 20 43 48     ...SIMPLIFIED CH
00000230    49 4E 45 53 45 08 00 00 00 00 00 06 00 00 00 06     INESE...........
00000240    42 49 4E 41 52 59 0B 00 00 00 00 00 0E 00 00 00     BINARY..........
00000250    0E 48 48 2E 4D 49 2E 53 53 58 46 46 20 41 4D 39     .HH.MI.SSXFF AM9
00000260    00 00 00 00 00 18 00 00 00 18 44 44 2D 4D 4F 4E     ..........DD-MON
00000270    2D 52 52 20 48 48 2E 4D 49 2E 53 53 58 46 46 20     -RR HH.MI.SSXFF
00000280    41 4D 3A 00 00 00 00 00 12 00 00 00 12 48 48 2E     AM:..........HH.
00000290    4D 49 2E 53 53 58 46 46 20 41 4D 20 54 5A 52 3B     MI.SSXFF AM TZR;
000002A0    00 00 00 00 00 1C 00 00 00 1C 44 44 2D 4D 4F 4E     ..........DD-MON
000002B0    2D 52 52 20 48 48 2E 4D 49 2E 53 53 58 46 46 20     -RR HH.MI.SSXFF
000002C0    41 4D 20 54 5A 52 3C 00 00 00 00 00 03 00 00 00     AM TZR<.........
000002D0    03 EF BF A5 34 00 00 00 00 00 06 00 00 00 06 42     ....4..........B
000002E0    49 4E 41 52 59 32 00 00 00 00 00 04 00 00 00 04     INARY2..........
000002F0    42 59 54 45 3D 00 00 00 00 00 05 00 00 00 05 46     BYTE=..........F
00000300    41 4C 53 45 3E 00 00 00 00 00 0B 00 00 00 0B 80     ALSE>...........
00000310    00 00 00 44 3C 3C 80 00 00 00 A3 00 00 00 00 00     ...D<<..........
00000320    04 01 00 00 00 04 00 01 01 00 00 00 00 00 00 00     ................
00000330    00 00 03 00 00 00 03 00 20 00 00 00 00 00 00 00     ........ .......
00000340    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00     ................
00000350    00 05 00 00 01 00 00 00 36 01 00 00 00 00 00 00     ........6.......
00000360    00 00 00 00 00 00 00 00 60 02 5A 19 00 00 00 00     ........`.Z.....
00000370    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00     ................
00000380    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00     ................
00000390    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00     ................
000003A0    00 00 00 00 00 00 00 00                             ........

type is 10
00000000    17 00 00 00                                         ....

i_len_next_data = 23
00000000    27 E6 48 2C 16 04 06 B1 E1 1B A6 43 F9 DF 70 B5     '.H,.......C..p.
00000010    78 76 01 0E 0B 29 0B                                xv...).

00000000    30 04 00 00                                         0...

00000000    03 00 00 00                                         ....

i_column_count = 3
00000000    51                                                  Q

column 1 desc info
00000000    01                                                  .

00000000    01 80 00 00 32 00 00 00 00 00 00 00 00 00 00 00     ....2...........
00000010    00 00 00 00 00 00 00 00 00 00 00 00 69 03 01 00     ............i...
00000020    32 00 00 00 00 00 00 00                             2.......

00000000    00                                                  .

00000000    05                                                  .

00000000    05 00 00 00                                         ....

i_len_next_data = 5
00000000    54 4F 50 49 43                                      TOPIC

00000000    00 00 00 00                                         ....

00000000    00 00 00 00                                         ....

00000000    00 00                                               ..

00000000    00 00 00 00                                         ....

column 2 desc info
00000000    01                                                  .

00000000    02 00 00 81 16 00 00 00 00 00 00 00 00 00 00 00     ................
00000010    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00     ................
00000020    00 00 00 00 00 00 00 00                             ........

00000000    00                                                  .

00000000    03                                                  .

00000000    03 00 00 00                                         ....

i_len_next_data = 3
00000000    53 45 51                                            SEQ

00000000    00 00 00 00                                         ....

00000000    00 00 00 00                                         ....

00000000    01 00                                               ..

00000000    00 00 00 00                                         ....

column 3 desc info
00000000    01                                                  .

00000000    01 80 00 00 E8 03 00 00 00 00 00 00 00 00 00 00     ................
00000010    00 00 00 00 00 00 00 00 00 00 00 00 69 03 01 00     ............i...
00000020    E8 03 00 00 00 00 00 00                             ........

00000000    01                                                  .

00000000    04                                                  .

00000000    04 00 00 00                                         ....

i_len_next_data = 4
00000000    49 4E 46 4F                                         INFO

00000000    00 00 00 00                                         ....

00000000    00 00 00 00                                         ....

00000000    02 00                                               ..

00000000    00 00 00 00                                         ....

00000000    07 00 00 00                                         ....

i_len_next_data = 7
00000000    78 76 01 0E 16 03 0C                                xv.....

00000000    01 00 00 00                                         ....

00000000    E8 1F 00 00                                         ....

00000000    0A 00 00 00                                         ....

00000000    0A 00 00 00                                         ....

00000000    00 00 00 00                                         ....

00000000    06                                                  .

00000000    01                                                  .

00000000    1A 00 03 00 00 00 00 00 01 00 00 00 00 00 00 00     ................
00000010    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00     ................
00000020    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00     ................

00000000    07                                                  .

i_len_next_data = 42
00000000    2C 01 03 06 41 43 43 45 50 54 02 C1 02 1C 69 6E     ,...ACCEPT....in
00000010    66 6F 20 3D 20 68 65 6C 6C 6F 2C 20 77 6F 72 6C     fo = hello, worl
00000020    64 2C 20 53 45 51 20 3D 20 31                       d, SEQ = 1

00000000    08                                                  .

00000000    06 00                                               ..

00000000    65 84 16 00 00 00 00 00 03 00 00 00 00 00 00 00     e...............
00000010    00 00 00 00 00 00 00 00                             ........

00000000    00 00                                               ..

00000000    13 00                                               ..

00000000    00 00 00 00                                         ....

00000000    12 00 00 00                                         ....

i_len_next_data = 18
00000000    53 49 4D 50 4C 49 46 49 45 44 20 43 48 49 4E 45     SIMPLIFIED CHINE
00000010    53 45                                               SE

00000000    10 00                                               ..

00000000    00 00 00 00                                         ....

00000000    05 00 00 00                                         ....

i_len_next_data = 5
00000000    43 48 49 4E 41                                      CHINA

00000000    09 00                                               ..

00000000    00 00 00 00                                         ....

00000000    03 00 00 00                                         ....

i_len_next_data = 3
00000000    EF BF A5                                            ...

00000000    00 00                                               ..

00000000    00 00 00 00                                         ....

00000000    05 00 00 00                                         ....

i_len_next_data = 5
00000000    43 48 49 4E 41                                      CHINA

00000000    01 00                                               ..

00000000    00 00 00 00                                         ....

00000000    02 00 00 00                                         ....

i_len_next_data = 2
00000000    2E 2C                                               .,

00000000    02 00                                               ..

00000000    00 00 00 00                                         ....

00000000    08 00 00 00                                         ....

i_len_next_data = 8
00000000    41 4C 33 32 55 54 46 38                             AL32UTF8

00000000    0A 00                                               ..

00000000    00 00 00 00                                         ....

00000000    09 00 00 00                                         ....

i_len_next_data = 9
00000000    47 52 45 47 4F 52 49 41 4E                          GREGORIAN

00000000    0C 00                                               ..

00000000    00 00 00 00                                         ....

00000000    09 00 00 00                                         ....

i_len_next_data = 9
00000000    44 44 2D 4D 4F 4E 2D 52 52                          DD-MON-RR

00000000    07 00                                               ..

00000000    00 00 00 00                                         ....

00000000    12 00 00 00                                         ....

i_len_next_data = 18
00000000    53 49 4D 50 4C 49 46 49 45 44 20 43 48 49 4E 45     SIMPLIFIED CHINE
00000010    53 45                                               SE

00000000    08 00                                               ..

00000000    00 00 00 00                                         ....

00000000    06 00 00 00                                         ....

i_len_next_data = 6
00000000    42 49 4E 41 52 59                                   BINARY

00000000    0B 00                                               ..

00000000    00 00 00 00                                         ....

00000000    0E 00 00 00                                         ....

i_len_next_data = 14
00000000    48 48 2E 4D 49 2E 53 53 58 46 46 20 41 4D           HH.MI.SSXFF AM

00000000    39 00                                               9.

00000000    00 00 00 00                                         ....

00000000    18 00 00 00                                         ....

i_len_next_data = 24
00000000    44 44 2D 4D 4F 4E 2D 52 52 20 48 48 2E 4D 49 2E     DD-MON-RR HH.MI.
00000010    53 53 58 46 46 20 41 4D                             SSXFF AM

00000000    3A 00                                               :.

00000000    00 00 00 00                                         ....

00000000    12 00 00 00                                         ....

i_len_next_data = 18
00000000    48 48 2E 4D 49 2E 53 53 58 46 46 20 41 4D 20 54     HH.MI.SSXFF AM T
00000010    5A 52                                               ZR

00000000    3B 00                                               ;.

00000000    00 00 00 00                                         ....

00000000    1C 00 00 00                                         ....

i_len_next_data = 28
00000000    44 44 2D 4D 4F 4E 2D 52 52 20 48 48 2E 4D 49 2E     DD-MON-RR HH.MI.
00000010    53 53 58 46 46 20 41 4D 20 54 5A 52                 SSXFF AM TZR

00000000    3C 00                                               <.

00000000    00 00 00 00                                         ....

00000000    03 00 00 00                                         ....

i_len_next_data = 3
00000000    EF BF A5                                            ...

00000000    34 00                                               4.

00000000    00 00 00 00                                         ....

00000000    06 00 00 00                                         ....

i_len_next_data = 6
00000000    42 49 4E 41 52 59                                   BINARY

00000000    32 00                                               2.

00000000    00 00 00 00                                         ....

00000000    04 00 00 00                                         ....

i_len_next_data = 4
00000000    42 59 54 45                                         BYTE

00000000    3D 00                                               =.

00000000    00 00 00 00                                         ....

00000000    05 00 00 00                                         ....

i_len_next_data = 5
00000000    46 41 4C 53 45                                      FALSE

00000000    3E 00                                               >.

00000000    00 00 00 00                                         ....

00000000    0B 00 00 00                                         ....

i_len_next_data = 11
00000000    80 00 00 00 44 3C 3C 80 00 00 00                    ....D<<....

00000000    A3 00                                               ..

00000000    00 00 00 00                                         ....

00000000    04                                                  .

00000000    01 00 00 00                                         ....

00000000    04 00                                               ..

00000000    01                                                  .

00000000    01 00 00 00 00 00 00 00 00 00 03 00 00 00 03 00     ................
00000010    20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00      ...............
00000020    00 00 00 00 00 00 00 00 00 05 00 00 01 00 00 00     ................
00000030    36 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00     6...............
00000040    60 02 5A 19 00 00 00 00 00 00 00 00 00 00 00 00     `.Z.............
00000050    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00     ................
00000060    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00     ................
00000070    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00     ................

<< proc_tns_data_describe_information = true
header->caplen = 75, header->len = 75
header->caplen = 296, header->len = 296
>> proc_tns_data_row_transfer
--------------------------------------------------------------------------------
proc_tns_data_row_transfer 0x00000237229C0135, length = 231
--------------------------------------------------------------------------------
00000000    01 1A 93 03 00 00 00 00 00 02 00 00 00 00 00 00     ................
00000010    00 00 00 00 00 00 00 00 00 00 00 B0 00 00 00 00     ................
00000020    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00     ................
00000030    00 07 15 2C 00 03 06 41 43 43 45 50 54 02 C1 03     ...,...ACCEPT...
00000040    07 20 41 43 43 45 50 54 07 15 2C 00 03 06 41 43     . ACCEPT..,...AC
00000050    43 45 50 54 02 C1 04 07 20 2D 2D 2D 2D 2D 2D 04     CEPT.... ------.
00000060    01 00 00 00 05 00 01 03 00 00 00 00 00 00 00 00     ................
00000070    00 03 00 00 00 03 00 20 00 00 00 00 00 00 00 00     ....... ........
00000080    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00     ................
00000090    06 00 00 01 00 00 00 36 01 00 00 00 00 00 00 00     .......6........
000000A0    00 00 00 00 00 00 00 60 02 5A 19 00 00 00 00 00     .......`.Z......
000000B0    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00     ................
000000C0    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00     ................
000000D0    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00     ................
000000E0    00 00 00 00 00 00 00                                .......

00000000    01                                                  .

00000000    1A 93 03 00 00 00 00 00 02 00 00 00 00 00 00 00     ................
00000010    00 00 00 00 00 00 00 00 00 00 B0 00 00 00 00 00     ................
00000020    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00     ................

00000000    07                                                  .

i_len_next_data = 21
00000000    2C 00 03 06 41 43 43 45 50 54 02 C1 03 07 20 41     ,...ACCEPT.... A
00000010    43 43 45 50 54                                      CCEPT

00000000    07                                                  .

i_len_next_data = 21
00000000    2C 00 03 06 41 43 43 45 50 54 02 C1 04 07 20 2D     ,...ACCEPT.... -
00000010    2D 2D 2D 2D 2D 04 01 00 00 00 05 00 01 03 00 00     -----...........
00000020    00 00 00 00 00 00 00 03 00 00 00 03 00 20 00 00     ............. ..
00000030    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00     ................
00000040    00 00 00 00 00 00 06 00 00 01 00 00 00 36 01 00     .............6..
00000050    00 00 00 00 00 00 00 00 00 00 00 00 00 60 02 5A     .............`.Z
00000060    19 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00     ................
00000070    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00     ................
00000080    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00     ................
00000090    00 00 00 00 00 00 00 00 00 00 00 00 00              .............

00000000    2C 00 03 06 41 43 43 45 50 54 02 C1 04 07 20 2D     ,...ACCEPT.... -
00000010    2D 2D 2D 2D 2D                                      -----

00000000    04                                                  .

00000000    01 00 00 00                                         ....

00000000    05 00                                               ..

00000000    01                                                  .

00000000    03 00 00 00 00 00 00 00 00 00 03 00 00 00 03 00     ................
00000010    20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00      ...............
00000020    00 00 00 00 00 00 00 00 00 06 00 00 01 00 00 00     ................
00000030    36 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00     6...............
00000040    60 02 5A 19 00 00 00 00 00 00 00 00 00 00 00 00     `.Z.............
00000050    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00     ................
00000060    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00     ................
00000070    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00     ................

<< proc_tns_data_row_transfer = true
header->caplen = 75, header->len = 75
header->caplen = 652, header->len = 652
>> proc_tns_data_row_transfer
--------------------------------------------------------------------------------
proc_tns_data_row_transfer 0x00000237229C02D1, length = 587
--------------------------------------------------------------------------------
00000000    01 1A 93 03 00 00 00 00 00 02 00 00 00 00 00 00     ................
00000010    00 00 00 00 00 00 00 00 00 00 00 B0 00 00 00 00     ................
00000020    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00     ................
00000030    00 07 0D 2C 00 02 06 41 43 43 45 50 54 02 C1 05     ...,...ACCEPT...
00000040    07 FE FF 0C 02 03 00 40 7C 91 00 22 06 41 43 43     .......@|..".ACC
00000050    45 50 54 02 C1 06 FE 68 01 30 30 30 30 30 30 30     EPT....h.0000000
00000060    30 30 30 31 31 31 31 31 31 31 31 31 31 32 32 32     0001111111111222
00000070    32 32 32 32 32 32 32 33 33 33 33 33 33 33 33 33     2222222333333333
00000080    33 34 34 34 34 34 34 34 34 34 34 35 35 35 35 35     3444444444455555
00000090    35 35 35 35 35 36 36 36 36 36 36 36 36 36 36 37     5555566666666667
000000A0    37 37 37 37 37 37 37 37 37 38 38 38 38 38 38 38     7777777778888888
000000B0    38 38 38 39 39 39 39 39 39 39 39 39 39 61 61 61     8889999999999aaa
000000C0    61 61 61 61 61 61 61 62 62 62 62 62 62 62 62 62     aaaaaaabbbbbbbbb
000000D0    62 63 63 63 63 63 63 63 63 63 63 64 64 64 64 64     bccccccccccddddd
000000E0    64 64 64 64 64 65 65 65 65 65 65 65 65 65 65 66     dddddeeeeeeeeeef
000000F0    66 66 66 66 66 66 66 66 66 67 67 67 67 67 67 67     fffffffffggggggg
00000100    67 67 67 68 68 68 68 68 68 68 68 68 68 69 69 69     ggghhhhhhhhhhiii
00000110    69 69 69 69 69 69 69 6A 6A 6A 6A 6A 6A 6A 6A 6A     iiiiiiijjjjjjjjj
00000120    6A 6B 6B 6B 6B 6B 6B 6B 6B 6B 6B 6C 6C 6C 6C 6C     jkkkkkkkkkklllll
00000130    6C 6C 6C 6C 6C 6D 6D 6D 6D 6D 6D 6D 6D 6D 6D 6E     lllllmmmmmmmmmmn
00000140    6E 6E 7F 6E 6E 6E 6E 6E 6E 6E 6F 6F 6F 6F 6F 6F     nn.nnnnnnnoooooo
00000150    6F 6F 6F 6F 70 70 70 70 70 70 70 70 70 70 71 71     ooooppppppppppqq
00000160    71 71 71 71 71 71 71 71 72 72 72 72 72 72 72 72     qqqqqqqqrrrrrrrr
00000170    72 72 73 73 73 73 73 73 73 73 73 73 74 74 74 74     rrsssssssssstttt
00000180    74 74 74 74 74 74 75 75 75 75 75 75 75 75 75 75     ttttttuuuuuuuuuu
00000190    76 76 76 76 76 76 76 76 76 76 77 77 77 77 77 77     vvvvvvvvvvwwwwww
000001A0    77 77 77 77 78 78 78 78 78 78 78 78 78 78 79 79     wwwwxxxxxxxxxxyy
000001B0    79 79 79 79 79 79 79 79 7A 7A 7A 7A 7A 7A 7A 7A     yyyyyyyyzzzzzzzz
000001C0    7A 7A 00 04 01 00 00 00 06 00 01 05 00 00 00 00     zz..............
000001D0    00 00 00 00 00 03 00 00 00 03 00 20 00 00 00 00     ........... ....
000001E0    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00     ................
000001F0    00 00 00 00 07 00 00 01 00 00 00 36 01 00 00 00     ...........6....
00000200    00 00 00 00 00 00 00 00 00 00 00 60 02 5A 19 00     ...........`.Z..
00000210    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00     ................
00000220    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00     ................
00000230    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00     ................
00000240    00 00 00 00 00 00 00 00 00 00 00                    ...........

00000000    01                                                  .

00000000    1A 93 03 00 00 00 00 00 02 00 00 00 00 00 00 00     ................
00000010    00 00 00 00 00 00 00 00 00 00 B0 00 00 00 00 00     ................
00000020    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00     ................

00000000    07                                                  .

i_len_next_data = 13
00000000    2C 00 02 06 41 43 43 45 50 54 02 C1 05              ,...ACCEPT...

00000000    07                                                  .

00000000    0C 02 03 00 40 7C 91 00 22 06 41 43 43 45 50 54     ....@|..".ACCEPT
00000010    02 C1 06 FE 68 01 30 30 30 30 30 30 30 30 30 30     ....h.0000000000
00000020    31 31 31 31 31 31 31 31 31 31 32 32 32 32 32 32     1111111111222222
00000030    32 32 32 32 33 33 33 33 33 33 33 33 33 33 34 34     2222333333333344
00000040    34 34 34 34 34 34 34 34 35 35 35 35 35 35 35 35     4444444455555555
00000050    35 35 36 36 36 36 36 36 36 36 36 36 37 37 37 37     5566666666667777
00000060    37 37 37 37 37 37 38 38 38 38 38 38 38 38 38 38     7777778888888888
00000070    39 39 39 39 39 39 39 39 39 39 61 61 61 61 61 61     9999999999aaaaaa
00000080    61 61 61 61 62 62 62 62 62 62 62 62 62 62 63 63     aaaabbbbbbbbbbcc
00000090    63 63 63 63 63 63 63 63 64 64 64 64 64 64 64 64     ccccccccdddddddd
000000A0    64 64 65 65 65 65 65 65 65 65 65 65 66 66 66 66     ddeeeeeeeeeeffff
000000B0    66 66 66 66 66 66 67 67 67 67 67 67 67 67 67 67     ffffffgggggggggg
000000C0    68 68 68 68 68 68 68 68 68 68 69 69 69 69 69 69     hhhhhhhhhhiiiiii
000000D0    69 69 69 69 6A 6A 6A 6A 6A 6A 6A 6A 6A 6A 6B 6B     iiiijjjjjjjjjjkk
000000E0    6B 6B 6B 6B 6B 6B 6B 6B 6C 6C 6C 6C 6C 6C 6C 6C     kkkkkkkkllllllll
000000F0    6C 6C 6D 6D 6D 6D 6D 6D 6D 6D 6D 6D 6E 6E 6E 6E     llmmmmmmmmmmnnnn
00000100    6E 6E 6E 6E 6E 6E 6F 6F 6F 6F 6F 6F 6F 6F 6F 6F     nnnnnnoooooooooo
00000110    70 70 70 70 70 70 70 70 70 70 71 71 71 71 71 71     ppppppppppqqqqqq
00000120    71 71 71 71 72 72 72 72 72 72 72 72 72 72 73 73     qqqqrrrrrrrrrrss
00000130    73 73 73 73 73 73 73 73 74 74 74 74 74 74 74 74     sssssssstttttttt
00000140    74 74 75 75 75 75 75 75 75 75 75 75 76 76 76 76     ttuuuuuuuuuuvvvv
00000150    76 76 76 76 76 76 77 77 77 77 77 77 77 77 77 77     vvvvvvwwwwwwwwww
00000160    78 78 78 78 78 78 78 78 78 78 79 79 79 79 79 79     xxxxxxxxxxyyyyyy
00000170    79 79 79 79 7A 7A 7A 7A 7A 7A 7A 7A 7A 7A           yyyyzzzzzzzzzz

00000000    00 04 01 00 00 00 06 00 01                          .........

00000000    05 00 00 00 00 00 00 00 00 00 03 00 00 00 03 00     ................
00000010    20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00      ...............
00000020    00 00 00 00 00 00 00 00 00 07 00 00 01 00 00 00     ................
00000030    36 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00     6...............
00000040    60 02 5A 19 00 00 00 00 00 00 00 00 00 00 00 00     `.Z.............
00000050    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00     ................
00000060    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00     ................
00000070    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00     ................

<< proc_tns_data_row_transfer = true
header->caplen = 75, header->len = 75
header->caplen = 299, header->len = 299
>> proc_tns_data_row_transfer
--------------------------------------------------------------------------------
proc_tns_data_row_transfer 0x00000237229C05D1, length = 234
--------------------------------------------------------------------------------
00000000    01 1A 93 03 00 00 00 00 00 02 00 00 00 00 00 00     ................
00000010    00 00 00 00 00 00 00 00 00 00 00 B0 00 00 00 00     ................
00000020    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00     ................
00000030    00 07 0D 2C 00 02 06 41 43 43 45 50 54 02 C1 07     ...,...ACCEPT...
00000040    04 01 00 00 00 07 00 01 06 00 00 00 7B 05 00 00     ............{...
00000050    00 00 03 00 00 00 03 00 20 00 00 00 00 00 00 00     ........ .......
00000060    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00     ................
00000070    00 08 00 00 01 00 00 00 36 01 00 00 00 00 00 00     ........6.......
00000080    00 00 00 00 00 00 00 00 60 02 5A 19 00 00 00 00     ........`.Z.....
00000090    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00     ................
000000A0    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00     ................
000000B0    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00     ................
000000C0    00 00 00 00 00 00 00 00 21 4F 52 41 2D 30 31 34     ........!ORA-014
000000D0    30 33 3A 20 E6 9C AA E6 89 BE E5 88 B0 E4 BB BB     03: ............
000000E0    E4 BD 95 E6 95 B0 E6 8D AE 0A                       ..........

00000000    01                                                  .

00000000    1A 93 03 00 00 00 00 00 02 00 00 00 00 00 00 00     ................
00000010    00 00 00 00 00 00 00 00 00 00 B0 00 00 00 00 00     ................
00000020    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00     ................

00000000    07                                                  .

i_len_next_data = 13
00000000    2C 00 02 06 41 43 43 45 50 54 02 C1 07              ,...ACCEPT...

00000000    04                                                  .

00000000    01 00 00 00                                         ....

00000000    07 00                                               ..

00000000    01                                                  .

00000000    06 00 00 00 7B 05 00 00 00 00 03 00 00 00 03 00     ....{...........
00000010    20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00      ...............
00000020    00 00 00 00 00 00 00 00 00 08 00 00 01 00 00 00     ................
00000030    36 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00     6...............
00000040    60 02 5A 19 00 00 00 00 00 00 00 00 00 00 00 00     `.Z.............
00000050    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00     ................
00000060    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00     ................
00000070    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00     ................

00000000    21                                                  !

00000000    4F 52 41 2D 30 31 34 30 33 3A 20 E6 9C AA E6 89     ORA-01403: .....
00000010    BE E5 88 B0 E4 BB BB E4 BD 95 E6 95 B0 E6 8D AE     ................
00000020    0A                                                  .

<< proc_tns_data_row_transfer = true
header->caplen = 67, header->len = 67
header->caplen = 71, header->len = 71
header->caplen = 64, header->len = 64
header->caplen = 54, header->len = 54
header->caplen = 54, header->len = 54
header->caplen = 54, header->len = 54
header->caplen = 54, header->len = 54
user command quit
pcap loop break...
请按任意键继续. . .

工程预览

// packet_reader.cpp: 定义控制台应用程序的入口点。
// build as x64 debug

#include "stdafx.h"
#include <conio.h> // for getchar
#include "pcap_helper.h"
#include "MyThread.h"

#define PROG_NAME "packet_reader"
#define PROG_VER "1.0.0.1"
#define PROG_MODIFY_TIME "2018-01-13 13:21"

#define CMD_QUIT 'q'

/*
1. rpcap://\Device\NPF_{2C72F185-1C6F-40EC-A416-D40199629008}
(Network adapter 'VMware Virtual Ethernet Adapter' on local host)
2. rpcap://\Device\NPF_{82E7E4AC-9700-49D1-9951-195B1DB3AD1B}
(Network adapter 'VMware Virtual Ethernet Adapter' on local host)
3. rpcap://\Device\NPF_{438F5CEE-37EB-42CB-95EC-09E043C7C82B}
(Network adapter 'TAP-Windows Adapter V9' on local host)
4. rpcap://\Device\NPF_{F866A2FB-CB94-4DB2-953B-7B84E556A44D}
(Network adapter 'Realtek PCIe GBE Family Controller' on local host)
5. rpcap://\Device\NPF_{5806072D-CAA1-498B-8084-6C3A66E33D8E}
(Network adapter 'MS NDIS 6.0 LoopBack Driver' on local host)
*/

#define NIC_NAME "rpcap://\\Device\\NPF_{82E7E4AC-9700-49D1-9951-195B1DB3AD1B}"
#define SRC_IP "192.168.180.129"
#define SRC_PORT "1521"
#define PCAP_FILTER_STRING "host " SRC_IP "&& port " SRC_PORT

typedef struct tag_my_thread_param {
	CMyThread::TAG_REGISTERTHREADPROC* m_p_thread_param;
	pcap_t * p_h_pcap;
}MY_THREAD_PARAM;

bool g_b_packet_process = true;
int g_i_cb_packet_process_counter = 0;

void cb_packet_process(u_char* param, const struct pcap_pkthdr* header, const u_char* pkt_data);
unsigned __stdcall ThreadProc(void* pParam);
void help();

int main()
{
	pcap_t * p_h_pcap = NULL;
	struct bpf_program _bpf;
	char sz_buf[PCAP_ERRBUF_SIZE] = { '\0' };

	CMyThread thread_user_control;
	CMyThread::TAG_REGISTERTHREADPROC register_thread_user_control;
	MY_THREAD_PARAM thread_param;
	thread_param.m_p_thread_param = &register_thread_user_control;

	help();

	// show_all_nic();
	do {
		p_h_pcap = pcap_open(NIC_NAME,			// name of the device
			65536,			// portion of the packet to capture
							// 65536 guarantees that the whole packet will be captured on all the link layers
			PCAP_OPENFLAG_PROMISCUOUS, 	// promiscuous mode
			1000,				// read timeout
			NULL,				// authentication on the remote machine
			sz_buf			// error buffer
		);

		if (NULL == p_h_pcap) {
			break;
		}

		if (pcap_datalink(p_h_pcap) != DLT_EN10MB)
		{
			printf("\nThis program works only on Ethernet networks.\n");
			break;
		}

		if (pcap_compile(p_h_pcap, &_bpf, PCAP_FILTER_STRING, 1, -1) < 0)
		{
			printf("Unable to compile the packet filter. Check the syntax.\n");
			break;
		}

		if (pcap_setfilter(p_h_pcap, &_bpf) < 0)
		{
			printf("Error setting the filter.\n");
			break;
		}

		printf("pcap loop ...\n");

		thread_param.p_h_pcap = p_h_pcap;
		thread_param.m_p_thread_param = &register_thread_user_control;

		register_thread_user_control.pUserData = &thread_param;
		register_thread_user_control.pfnThreadProc = ThreadProc;
		thread_user_control.RegisterThreadProc(&register_thread_user_control);
		thread_user_control.Start();

		pcap_loop(p_h_pcap, 0, cb_packet_process, NULL);
		printf("pcap loop break...\n");
	} while (0);

	if (NULL != p_h_pcap) {
		pcap_close(p_h_pcap);
		p_h_pcap = NULL;
	}

	thread_user_control.Stop();
	system("pause");
	return 0;
}

void cb_packet_process(u_char* param, const struct pcap_pkthdr* header, const u_char* pkt_data)
{
	ETHERNET_HEADER eth_hdr;
	IP_HEADER ip_hdr;
	TCP_HEADER tcp_hdr;
	ORA_TNS_HEADER tns_hdr;
	ORA_TNS_DATA_HEADER tns_data_hdr;
	g_i_cb_packet_process_counter++;

	const u_char* p_data = NULL;
	int i_data_len = 0;

	int i_len_ip_hdr = 0;
	int i_len_tcp_hdr = 0;

	do {
		if (!g_b_packet_process) {
			break;
		}

		if ((NULL == header) || (NULL == pkt_data)) {
			break;
		}

		// show_packet(header, pkt_data);

		p_data = pkt_data;
		i_data_len = header->len;
		printf("header->caplen = %d, header->len = %d\n", header->caplen, header->len);
		if (header->len < MIN_PACKET_LENGTH) {
			break;
		}

		memcpy(&eth_hdr, p_data, sizeof(eth_hdr));
		p_data += sizeof(eth_hdr);
		i_data_len -= (int)sizeof(eth_hdr);

		memcpy(&ip_hdr, p_data, sizeof(ip_hdr));
		i_len_ip_hdr = get_size_ip_header(&ip_hdr);
		if ((int)header->len < (SIZE_ETHERNET_HEADER + i_len_ip_hdr + MIN_SIZE_TCP_HEADER)) {
			break;
		}

		p_data += i_len_ip_hdr;
		i_data_len -= i_len_ip_hdr;

		memcpy(&tcp_hdr, p_data, sizeof(tcp_hdr));
		i_len_tcp_hdr = get_size_tcp_header(&tcp_hdr);
		if ((int)header->len < (SIZE_ETHERNET_HEADER + i_len_ip_hdr + i_len_tcp_hdr)) {
			break;
		}

		p_data += i_len_tcp_hdr;
		i_data_len -= i_len_tcp_hdr;

		// only process payload from database to client
		if (atoi(SRC_PORT) != ntohs(tcp_hdr.sourcePort)) {
			break;
		}

		// only process oracle tns payload
		if (i_data_len <= sizeof(ORA_TNS_HEADER)) {
			break;
		}

		memcpy(&tns_hdr, p_data, sizeof(tns_hdr));
		p_data += sizeof(ORA_TNS_HEADER);
		i_data_len -= sizeof(ORA_TNS_HEADER);

		// only process TNS_TYPE_DATA
		if (TNS_TYPE_DATA != tns_hdr.type) {
			break;
		}

		if (i_data_len <= sizeof(ORA_TNS_DATA_HEADER)) {
			break;
		}

		memcpy(&tns_data_hdr, p_data, sizeof(tns_data_hdr));
		p_data += sizeof(ORA_TNS_DATA_HEADER);
		i_data_len -= sizeof(ORA_TNS_DATA_HEADER);

		if (i_data_len <= 0) {
			break;
		}

		switch (tns_data_hdr.data_id) {
		case TNS_DATA_ID_DESCRIBE_INFORMATION:
			g_b_packet_process = proc_tns_data_describe_information(p_data, i_data_len);
			break;
		case TNS_DATA_ROW_TRANSFER_HEADER:
			g_b_packet_process = proc_tns_data_row_transfer(p_data, i_data_len);
			break;
		default:
			break;
		}
	} while (0);
}

unsigned __stdcall ThreadProc(void* pParam) {
	MY_THREAD_PARAM* p_thread_param = NULL;
	CMyThread::TAG_REGISTERTHREADPROC* pThreadInfo = NULL;
	CMyThread::PFN_IS pfnIsNeedQuit = NULL;
	CMyThread::PFN_IS pfnIsCanContinue = NULL;
	char c_input = '\0';

	do {
		if (NULL == pParam) {
			break;
		}

		p_thread_param = (MY_THREAD_PARAM*)pParam;
		if (NULL == p_thread_param) {
			break;
		}

		if (NULL == p_thread_param->p_h_pcap) {
			break;
		}

		pThreadInfo = p_thread_param->m_p_thread_param;

		if ((NULL != pThreadInfo->pThreadControlClass)
			&& (NULL != pThreadInfo->pfnIsNeedQuit)) {
			pfnIsNeedQuit = pThreadInfo->pfnIsNeedQuit;
		}

		if ((NULL != pThreadInfo->pThreadControlClass)
			&& (NULL != pThreadInfo->pfnIsCanContinue)) {
			pfnIsCanContinue = pThreadInfo->pfnIsCanContinue;
		}

		do {
			Sleep(1);
			if (NULL != pfnIsNeedQuit) {
				if ((pThreadInfo->pThreadControlClass->*pfnIsNeedQuit)()) {
					break; // 如果线程函数退出判断点有多个, 此代码块按需调用
				}
			}

			if (NULL != pfnIsCanContinue) {
				if ((pThreadInfo->pThreadControlClass->*pfnIsCanContinue)()) {
					// 如果线程函数继续判断点有多个, 此代码块按需调用
					if (!g_b_packet_process) {
						pcap_breakloop(p_thread_param->p_h_pcap);
						printf("packet process error!\n");
						break;
					}

					c_input = getch();
					if ('q' == c_input) {
						if (NULL != p_thread_param->p_h_pcap) {
							// pcap_loop是阻塞执行的, 必须在其他线程中执行pcap_breakloop,才能打断
							pcap_breakloop(p_thread_param->p_h_pcap);
						}
						printf("user command quit\n");
						break;
					}
				}
			}
		} while (1);
	} while (0);

	return EXIT_SUCCESS;
}

void help()
{
	printf("%s %s %s\n", PROG_NAME, PROG_VER, PROG_MODIFY_TIME);
	printf("if need quit, press '%c'\n", CMD_QUIT);
}
// @file pcap_helper.h

#ifndef __PCAP_HELPER_H__
#define __PCAP_HELPER_H__

#include <winsock2.h>
#pragma comment(lib, "Ws2_32.lib")

#include <windows.h>

#define HAVE_REMOTE
#include "pcap.h"
#pragma comment(lib, "wpcap.lib")
#pragma comment(lib, "Packet.lib")

#pragma pack(push)
#pragma pack(1)

#define SAFE_DELETE(p) \
if (NULL != (p)) { \
	delete[] (p); \
	(p) = NULL; \
}

typedef struct tag_mac_addr {
	u_char uc_ary[6];
}MAC_ADDR;

// ETHERNET_HEADER size = 14
typedef struct tag_ethernet_header {
	MAC_ADDR dest_mac;
	MAC_ADDR src_mac;
	u_short type;
}ETHERNET_HEADER;
#define SIZE_ETHERNET_HEADER 14 // sizeof(ETHERNET_HEADER)

/* 4 bytes IP address */
typedef struct tag_ip_address {
	u_char byte1;
	u_char byte2;
	u_char byte3;
	u_char byte4;
}IP_ADDRESS;

typedef struct tag_ip_header {
	u_char	ver_ihl;		// Version (4 bits) + Internet header length (4 bits)
	u_char	tos;			// Type of service 
	u_short tlen;			// Total length 
	u_short identification; // Identification
	u_short flags_fo;		// Flags (3 bits) + Fragment offset (13 bits)
	u_char	ttl;			// Time to live
	u_char	proto;			// Protocol
	u_short crc;			// Header checksum
	IP_ADDRESS	saddr;		// Source address
	IP_ADDRESS	daddr;		// Destination address
	// u_int	op_pad;			// Option + Padding
}IP_HEADER;
#define MIN_SIZE_IP_HEADER 20 // sizeof(IP_HEADER)

typedef struct tcp_header
{
	u_short sourcePort;			// 16位源端口号    | Source port
	u_short destinationPort;    // 16位目的端口号 | Destination port
	u_long sequenceNumber;      // 32位序列号      | Sequence Number
	u_long acknowledgeNumber;   // 32位确认号      | Acknowledgement number
	u_char   dataoffset;        // 高4位表示数据偏移,低6位保留字 | Header length
	u_char   flags;             // 6位标志位       | packet flags
	u_short windows;            // 16位窗口大小    | Window size
	u_short checksum;           // 16位校验和      | Header Checksum
	u_short urgentPointer;      // 16位紧急数据偏移量   | Urgent pointer...still don't know what this is...
	// u_int	op_pad;			// Option + Padding
}TCP_HEADER;
#define MIN_SIZE_TCP_HEADER 20 // sizeof(TCP_HEADER)

#define MIN_PACKET_LENGTH (SIZE_ETHERNET_HEADER + MIN_SIZE_IP_HEADER + MIN_SIZE_TCP_HEADER)

/*
0      8       16            31
+ -------------- + -------------- +
| Packet Length | Packet Chksm |
+------ + ------ - +-------------- + 8 byte header
| Type | Rsrvd | Header Chksm |
+------ + ------ - +-------------- +
| P A Y L O A D |
+---------------------------- - +
*/
typedef struct tag_ora_tns_header{
	u_short packet_len;
	u_short packet_check_sum;
	u_char type;
	u_char reserve;
	u_short header_check_sum;
	// payload
}ORA_TNS_HEADER;

#define TNS_TYPE_DATA 6

typedef struct tag_ora_tns_data_header {
	u_short data_flags;
	u_char data_id;
	// payload
}ORA_TNS_DATA_HEADER;

#define TNS_DATA_ID_DESCRIBE_INFORMATION 0x10
#define TNS_DATA_ROW_TRANSFER_HEADER 0x06

#define TNS_RECODE_TYPE_NORMAL 7
#define TNS_RECODE_TYPE_LAST 4

#pragma pack(pop)

// nic is "Network Interface Card"
void show_all_nic();
void show_packet(const struct pcap_pkthdr *header, const u_char *pkt_data);
void show_data(const char* psz_tip, const u_char *pdata, int i_len);
void show_data_no_tip(const u_char *pdata, int i_len);

// 取出长度后,返回剩下的数据和长度
bool get_next_data_len_and_move_to_data(const u_char* pdata_in, int i_len_in, int& i_next_data_len_out, const u_char*& ppdata_out, int& i_len_out);
bool get_next_data_len_only(const u_char* pdata_in, int i_len_in, int& i_next_data_len_out);
bool merge_large_data_then_move_to_next_data(
	const u_char* pdata_in, int i_len_in, 
	const u_char*& ppdata_next_out, int& i_len_next_out,
	const u_char* pdata_merge_out, int i_len_merge);

bool parse_data(const u_char* pdata_in, int i_len_in);

u_long get_data_value(const u_char* pdata_in, int i_len_in);

int get_size_ip_header(IP_HEADER* p_ip_header);
int get_size_tcp_header(TCP_HEADER* p_tcp_header);

bool proc_tns_data_describe_information(const u_char* p_data, int i_data_len);
bool proc_tns_data_row_transfer(const u_char* p_data, int i_data_len);

#endif // #ifndef __PCAP_HELPER_H__
// MyThread.h: interface for the CMyThread class.
//
//

#if !defined(AFX_MYTHREAD_H__8B713CD4_E5C4_467D_87C0_B5197689E5C8__INCLUDED_)
#define AFX_MYTHREAD_H__8B713CD4_E5C4_467D_87C0_B5197689E5C8__INCLUDED_

#include <windows.h>

class CMyThread
{
public:
	typedef unsigned(__stdcall *PFN_THREADPROC)(void *);
	typedef BOOL(CMyThread::*PFN_IS)();
	typedef struct _tag_RegisterThreadproc {
		IN void* pUserData; ///< 用户数据指针, 我们不动, 线程自己用
		IN PFN_THREADPROC pfnThreadProc; ///< 传入的线程处理函数地址

										 /// 线程控制类指针, 配合下面2个回调函数使用
		OUT CMyThread* pThreadControlClass;

		/// 传出的回调函数指针, 提供给线程函数用来判断是继续还是挂起
		OUT PFN_IS pfnIsCanContinue;

		/// 传出的回调函数指针, 提供给线程函数判断是否要退出线程
		OUT PFN_IS pfnIsNeedQuit;

		_tag_RegisterThreadproc() {
			pUserData = NULL;
			pfnThreadProc = NULL;
			pThreadControlClass = NULL;
			pfnIsCanContinue = NULL;
			pfnIsNeedQuit = NULL;
		}
	} TAG_REGISTERTHREADPROC;

public:
	CMyThread();
	virtual ~CMyThread();

	void RegisterThreadProc(CMyThread::TAG_REGISTERTHREADPROC* pParam); ///< 注册回调函数
	void Start(); ///< 线程开始
	void Pause(); ///< 线程挂起
	void Continue(); ///< 线程恢复运行
	void Stop(); ///< 线程停止

	BOOL cbIsCanContinue(); ///< 给线程函数的回调-是否可以继续运行线程
	BOOL cbIsNeedQuit(); ///< 给线程函数的回调-是否退出线程

private:
	HANDLE m_hThread; ///< 线程句柄
	PFN_THREADPROC m_pThreadProc; ///< 线程处理函数
	UINT m_uThreadId; ///< 线程ID
	HANDLE m_hEventContinue; ///< 事件句柄 - 继续
	HANDLE m_hEventQuit; ///< 事件句柄 - 退出线程
	void* m_pUserData; ///< 用户数据指针, 我们不动, 创建线程时, 当线程参数
};

#endif // !defined(AFX_MYTHREAD_H__8B713CD4_E5C4_467D_87C0_B5197689E5C8__INCLUDED_)

// @file pcap_helper.cpp

#include "stdafx.h"
#include <ctype.h>
#include <assert.h>
#include "pcap_helper.h"

extern int g_i_cb_packet_process_counter;

void show_all_nic()
{
	int i = 0;
	pcap_if_t* alldevs = NULL;
	pcap_if_t* d = NULL;
	char sz_buf[PCAP_ERRBUF_SIZE] = {'\0'};

	do {
		/* Retrieve the device list on the local machine */
		if (pcap_findalldevs_ex((char*)PCAP_SRC_IF_STRING, NULL, &alldevs, sz_buf) == -1)
		{
			printf("Error in pcap_findalldevs: %s\n", sz_buf);
			break;
		}

		/* Print the list */
		for (d = alldevs; (NULL != d); d = d->next)
		{
			printf("%d. %s\n\t", ++i, d->name);
			if (d->description)
				printf("(%s)\n", d->description);
			else
				printf("(No description available)\n");
		}

		if (0 == i)
		{
			printf("No interfaces found! Make sure WinPcap is installed.\n");
		}
	} while (0);

	if (NULL != alldevs) {
		pcap_freealldevs(alldevs);
	}
}

void show_packet(const struct pcap_pkthdr *header, const u_char *pkt_data)
{
	struct tm ltime;
	time_t local_tv_sec;
	char timestr[16] = { '\0' };

	/* convert the timestamp to readable format */
	local_tv_sec = header->ts.tv_sec;
	localtime_s(&ltime, &local_tv_sec);
	strftime(timestr, sizeof timestr, "%H:%M:%S", &ltime);

	printf("--------------------------------------------------------------------------------\n");
	printf("%s.%ld pccket_len = %d\n", timestr, header->ts.tv_usec, header->len);
	printf("--------------------------------------------------------------------------------\n");
	show_data_no_tip(pkt_data, (int)header->len);
}

void show_data(const char* psz_tip, const u_char *pdata, int i_len)
{
	printf("--------------------------------------------------------------------------------\n");
	printf("%s 0x%p, length = %d\n", (NULL != psz_tip) ? psz_tip : "data", pdata, i_len);
	printf("--------------------------------------------------------------------------------\n");
	show_data_no_tip(pdata, i_len);
}

void show_data_no_tip(const u_char *pdata, int i_len)
{
	int i = 0;

	int i_pos = 0;
	char sz_line_content[17] = { '\0' };
	char sz_char[2] = { '\0' };
	unsigned char uc = '\0';

	for (i = 0; i < i_len; i++) {
		if (0 == i_pos) {
			memset(sz_line_content, 0, sizeof(sz_line_content));
			printf("%8.8X    ", i);
		}

		uc = *(pdata + i);
		printf("%2.2X ", uc);

		if (isprint(uc) > 0) {
			sz_char[0] = (char)uc;
		}
		else {
			sz_char[0] = '.';
		}
		strcat(sz_line_content, sz_char);

		if (++i_pos == 16) {
			i_pos = 0;
			printf("    %s\n", sz_line_content);
		}
	}

	if (0 != i_pos) {
		uc = ' ';
		for (i = i_pos; i < 16; i++) {
			printf("%2.2c ", uc);
		}

		sz_char[0] = ' ';
		for (i = i_pos; i < 16; i++) {
			strcat(sz_line_content, sz_char);
		}
		printf("    %s\n", sz_line_content);
	}

	printf("\n");
}

int get_size_ip_header(IP_HEADER* p_ip_header)
{
	assert(NULL != p_ip_header);
	return (p_ip_header->ver_ihl & 0x0f) * 4;
}

int get_size_tcp_header(TCP_HEADER* p_tcp_header)
{
	assert(NULL != p_tcp_header);
	return ((p_tcp_header->dataoffset >> 4) & 0x0f) * 4;
}

bool proc_tns_data_describe_information(const u_char* p_data, int i_data_len)
{
	bool b_packet_process = false;
	const u_char* p_data_now = p_data;
	int i_data_len_now = i_data_len;
	int i_opt_len = 0;
	int i_len_next_data = 0;
	int i_column_count = 0;
	int i = 0;
	u_short us_data_type = 0;
	u_long ul_vale = 0;

	printf(">> proc_tns_data_describe_information\n");
	do {
		show_data("proc_tns_data_describe_information", p_data_now, i_data_len_now);

		if (25 == g_i_cb_packet_process_counter) {
			printf(""); // for debug
		}

	//	// --------------------------------------------------------------------------------
	//	// tns data id
	//	// --------------------------------------------------------------------------------
	//	10
		printf("type is 10\n");

		// 扒过皮的数据是从这开始的

		//	// --------------------------------------------------------------------------------
	//	// tns纯数据开始
	//	// --------------------------------------------------------------------------------
	//	17 00 00 00 // 长度(执行SQL的所有者信息, e.g. java, oci, plsql)
	    // 字节写的OCI测试程序 这里读4个字节
		// sqldeveloper.exe 这里读1个字节
		// 这里判断如果后3个字符是0,说明是4个字节的长度
		// 否则说明是一个字节的长度
		i_opt_len = 4;
		if (i_data_len_now < i_opt_len) {
			break;
		}
		show_data_no_tip(p_data_now, i_opt_len);
		i_len_next_data = (int)*p_data_now; // 长度都是取第一个字节
		printf("i_len_next_data = %d\n", i_len_next_data);

		ul_vale = get_data_value(p_data_now, i_opt_len);
		i_opt_len = (ul_vale >= 0xff) ? 1 : 4; // 后面3个字节有一个不为0
		if (4 != i_opt_len) {
			// 现在只能读出OCI测试程序产生的回包
			// sqldeveloper.exe 产生的回包,格式不一样. 因为不能用调试器带着跑,不知道流的读取格式
			printf("only support OCI program\r\n");
			break;
		}

		p_data_now += i_opt_len;
		i_data_len_now -= i_opt_len;

	//				// rd 23 (0x17 = 8 + 8 + 4 + 2 + 1)
	//	27 e6 48 2c 16 04 06 b1
	//	e1 1b a6 43 f9 df 70 b5
	//	78 76 01 08 0f 29 10
		i_opt_len = i_len_next_data;
		if (i_data_len_now < i_opt_len) {
			break;
		}
		show_data_no_tip(p_data_now, i_opt_len);
		p_data_now += i_opt_len;
		i_data_len_now -= i_opt_len;

	//	98 00 00 00 // rd 4
		i_opt_len = 4;
		if (i_data_len_now < i_opt_len) {
			break;
		}
		show_data_no_tip(p_data_now, i_opt_len);
		p_data_now += i_opt_len;
		i_data_len_now -= i_opt_len;

	//	03 00 00 00 // rd 4
		i_opt_len = 4;
		if (i_data_len_now < i_opt_len) {
			break;
		}
		show_data_no_tip(p_data_now, i_opt_len);
		i_column_count = *(int*)p_data_now;
		printf("i_column_count = %d\n", i_column_count);
		p_data_now += i_opt_len;
		i_data_len_now -= i_opt_len;
		
		//	51 // rd 1
		i_opt_len = 1;
		if (i_data_len_now < i_opt_len) {
			break;
		}
		show_data_no_tip(p_data_now, i_opt_len);
		p_data_now += i_opt_len;
		i_data_len_now -= i_opt_len;

		for (i = 0; i < i_column_count; i++) {
			printf("column %d desc info\n", i + 1);
			//	   // --------------------------------------------------------------------------------
			//	   // 列1的概要信息
			//	   // --------------------------------------------------------------------------------
			//	01 // rd 1
			i_opt_len = 1;
			if (i_data_len_now < i_opt_len) {
				break;
			}
			show_data_no_tip(p_data_now, i_opt_len);
			p_data_now += i_opt_len;
			i_data_len_now -= i_opt_len;

			//	   // rd 40
			//	01 80 00 00 32 00 00 00
			//	00 00 00 00 00 00 00 00
			//	00 00 00 00 00 00 00 00
			//	00 00 00 00 54 03 01 00
			//	32 00 00 00 00 00 00 00
			i_opt_len = 40;
			if (i_data_len_now < i_opt_len) {
				break;
			}
			show_data_no_tip(p_data_now, i_opt_len);
			p_data_now += i_opt_len;
			i_data_len_now -= i_opt_len;

			//	// --------------------------------------------------------------------------------
			//	// 列1的信息
			//	// --------------------------------------------------------------------------------
			//	00 // rd 1
			i_opt_len = 1;
			if (i_data_len_now < i_opt_len) {
				break;
			}
			show_data_no_tip(p_data_now, i_opt_len);
			p_data_now += i_opt_len;
			i_data_len_now -= i_opt_len;

			//	05 // rd 1
			i_opt_len = 1;
			if (i_data_len_now < i_opt_len) {
				break;
			}
			show_data_no_tip(p_data_now, i_opt_len);
			p_data_now += i_opt_len;
			i_data_len_now -= i_opt_len;

			//	05 00 00 00 // rd 4
			i_opt_len = 4;
			if (i_data_len_now < i_opt_len) {
				break;
			}
			show_data_no_tip(p_data_now, i_opt_len);
			p_data_now += i_opt_len;
			i_data_len_now -= i_opt_len;

			//	05 // 字符串长度
			if (!get_next_data_len_only(p_data_now, i_data_len_now, i_len_next_data)) {
				break;
			}

			if (i_len_next_data > 0xff) {
				printf("not imp\n");
			}
			else {
				if (!get_next_data_len_and_move_to_data(p_data_now, i_data_len_now, i_len_next_data, p_data_now, i_data_len_now)) {
					break;
				}
			}

			printf("i_len_next_data = %d\n", i_len_next_data);

			//	54 4f 50 49 43 // rd 5 => TOPIC
			i_opt_len = i_len_next_data;
			if (i_data_len_now < i_opt_len) {
				break;
			}
			show_data_no_tip(p_data_now, i_opt_len);
			p_data_now += i_opt_len;
			i_data_len_now -= i_opt_len;

			//	00 00 00 00 // rd 4
			i_opt_len = 4;
			if (i_data_len_now < i_opt_len) {
				break;
			}
			show_data_no_tip(p_data_now, i_opt_len);
			p_data_now += i_opt_len;
			i_data_len_now -= i_opt_len;

			//	00 00 00 00 // rd 4
			i_opt_len = 4;
			if (i_data_len_now < i_opt_len) {
				break;
			}
			show_data_no_tip(p_data_now, i_opt_len);
			p_data_now += i_opt_len;
			i_data_len_now -= i_opt_len;

			//	00 00 // rd 2
			i_opt_len = 2;
			if (i_data_len_now < i_opt_len) {
				break;
			}
			show_data_no_tip(p_data_now, i_opt_len);
			p_data_now += i_opt_len;
			i_data_len_now -= i_opt_len;

			//	00 00 00 00 // rd 4
			i_opt_len = 4;
			if (i_data_len_now < i_opt_len) {
				break;
			}
			show_data_no_tip(p_data_now, i_opt_len);
			p_data_now += i_opt_len;
			i_data_len_now -= i_opt_len;
		}

	// 列基本信息读完

	// 记录描述信息?
	//	07 00 00 00 // rd 4
		i_opt_len = 4;
		if (i_data_len_now < i_opt_len) {
			break;
		}
		show_data_no_tip(p_data_now, i_opt_len);
		p_data_now += i_opt_len;
		i_data_len_now -= i_opt_len;

	//	07 // rd 1
		if (!get_next_data_len_only(p_data_now, i_data_len_now, i_len_next_data)) {
			break;
		}

		if (i_len_next_data > 0xff) {
			printf("not imp\n");
		}
		else {
			if (!get_next_data_len_and_move_to_data(p_data_now, i_data_len_now, i_len_next_data, p_data_now, i_data_len_now)) {
				break;
			}
		}

		printf("i_len_next_data = %d\n", i_len_next_data);

		//	78 76 01 08 0f 2b 16 // rd 7
		i_opt_len = i_len_next_data;
		if (i_data_len_now < i_opt_len) {
			break;
		}
		show_data_no_tip(p_data_now, i_opt_len);
		p_data_now += i_opt_len;
		i_data_len_now -= i_opt_len;

	//	01 00 00 00 // rd 4
		i_opt_len = 4;
		if (i_data_len_now < i_opt_len) {
			break;
		}
		show_data_no_tip(p_data_now, i_opt_len);
		p_data_now += i_opt_len;
		i_data_len_now -= i_opt_len;
		
		//	e8 1f 00 00 // rd 4
		i_opt_len = 4;
		if (i_data_len_now < i_opt_len) {
			break;
		}
		show_data_no_tip(p_data_now, i_opt_len);
		p_data_now += i_opt_len;
		i_data_len_now -= i_opt_len;

	//	1a 00 00 00 // rd 4
		i_opt_len = 4;
		if (i_data_len_now < i_opt_len) {
			break;
		}
		show_data_no_tip(p_data_now, i_opt_len);
		p_data_now += i_opt_len;
		i_data_len_now -= i_opt_len;

		//	1a 00 00 00 // rd 4
		i_opt_len = 4;
		if (i_data_len_now < i_opt_len) {
			break;
		}
		show_data_no_tip(p_data_now, i_opt_len);
		p_data_now += i_opt_len;
		i_data_len_now -= i_opt_len;

	//	00 00 00 00 // rd 4
		i_opt_len = 4;
		if (i_data_len_now < i_opt_len) {
			break;
		}
		show_data_no_tip(p_data_now, i_opt_len);
		p_data_now += i_opt_len;
		i_data_len_now -= i_opt_len;

	//	06 // rd 1
		i_opt_len = 1;
		if (i_data_len_now < i_opt_len) {
			break;
		}
		show_data_no_tip(p_data_now, i_opt_len);
		i_len_next_data = (int)*(u_char*)p_data_now * 8;
		p_data_now += i_opt_len;
		i_data_len_now -= i_opt_len;

	//	01 // rd 1
		i_opt_len = 1;
		if (i_data_len_now < i_opt_len) {
			break;
		}
		show_data_no_tip(p_data_now, i_opt_len);
		p_data_now += i_opt_len;
		i_data_len_now -= i_opt_len;

	//	   // rd 48 (8 * 6)
	//	1a 00 03 00 00 00 00 00
	//	01 00 00 00 00 00 00 00
	//	00 00 00 00 00 00 00 00
	//	00 00 00 00 00 00 00 00
	//	00 00 00 00 00 00 00 00
	//	00 00 00 00 00 00 00 00
		i_opt_len = i_len_next_data;
		if (i_data_len_now < i_opt_len) {
			break;
		}
		show_data_no_tip(p_data_now, i_opt_len);
		p_data_now += i_opt_len;
		i_data_len_now -= i_opt_len;

	//	// --------------------------------------------------------------------------------
	//	// 第一条记录
	//	// --------------------------------------------------------------------------------
	//	07 // rd 1 // 记录的数据类型(0x07) ?
		i_opt_len = 1;
		if (i_data_len_now < i_opt_len) {
			break;
		}
		show_data_no_tip(p_data_now, i_opt_len);
		p_data_now += i_opt_len;
		i_data_len_now -= i_opt_len;
		
		//	2b // rd 1(length)
		if (!get_next_data_len_only(p_data_now, i_data_len_now, i_len_next_data)) {
			break;
		}

		if (i_len_next_data > 0xff) {
			printf("not imp\n");
		}
		else {
			if (!get_next_data_len_and_move_to_data(p_data_now, i_data_len_now, i_len_next_data, p_data_now, i_data_len_now)) {
				break;
			}
		}

		printf("i_len_next_data = %d\n", i_len_next_data);

	//	   // rd 43(0x2b = 8 * 5 + 2 + 1),第一条记录
	//	0c 01 03 00 40 7c 91 00
	//	22 06 41 43 43 45 50 54
	//	02 c1 02 17 69 6e 66 6f
	//	3a 73 65 71 3d 31 2c 74
	//	6f 70 69 63 3d 41 43 43
	//	45 50 54
		i_opt_len = i_len_next_data;
		if (i_data_len_now < i_opt_len) {
			break;
		}
		show_data_no_tip(p_data_now, i_opt_len);
		p_data_now += i_opt_len;
		i_data_len_now -= i_opt_len;

	//	08 // rd 1 // 类型?
		i_opt_len = 1;
		if (i_data_len_now < i_opt_len) {
			break;
		}
		show_data_no_tip(p_data_now, i_opt_len);
		p_data_now += i_opt_len;
		i_data_len_now -= i_opt_len;

		//	06 00 // rd 2
		i_opt_len = 2;
		if (i_data_len_now < i_opt_len) {
			break;
		}
		show_data_no_tip(p_data_now, i_opt_len);
		p_data_now += i_opt_len;
		i_data_len_now -= i_opt_len;

	//		  // rd 24(0x18)
	//	38 f5 11 00 00 00 00 00
	//	03 00 00 00 00 00 00 00
	//	00 00 00 00 00 00 00 00
		i_opt_len = 24;
		if (i_data_len_now < i_opt_len) {
			break;
		}
		show_data_no_tip(p_data_now, i_opt_len);
		p_data_now += i_opt_len;
		i_data_len_now -= i_opt_len;

	//	00 00 // rd 2
		i_opt_len = 2;
		if (i_data_len_now < i_opt_len) {
			break;
		}
		show_data_no_tip(p_data_now, i_opt_len);
		p_data_now += i_opt_len;
		i_data_len_now -= i_opt_len;

	// 附加的数据
		do {
			//		  // --------------------------------------------------------------------------------
			//		  // 读数据
			//		  // --------------------------------------------------------------------------------

			//	13 00 // rd 2
			i_opt_len = 2;
			if (i_data_len_now < i_opt_len) {
				break;
			}
			show_data_no_tip(p_data_now, i_opt_len);
			us_data_type = *(u_short*)p_data_now;
			p_data_now += i_opt_len;
			i_data_len_now -= i_opt_len;

			// a3 00 代表是包结尾的最后一块数据,读取逻辑和其他的附加数据不一样
			if (0xa3 != us_data_type) {
				//	00 00 00 00 // rd 4
				i_opt_len = 4;
				if (i_data_len_now < i_opt_len) {
					break;
				}
				show_data_no_tip(p_data_now, i_opt_len);
				p_data_now += i_opt_len;
				i_data_len_now -= i_opt_len;

				//	12 00 00 00 // rd 4
				i_opt_len = 4;
				if (i_data_len_now < i_opt_len) {
					break;
				}
				show_data_no_tip(p_data_now, i_opt_len);
				p_data_now += i_opt_len;
				i_data_len_now -= i_opt_len;

				//	12 // rd 1
				if (!get_next_data_len_only(p_data_now, i_data_len_now, i_len_next_data)) {
					break;
				}

				if (i_len_next_data > 0xff) {
					printf("not imp\n");
				}
				else {
					if (!get_next_data_len_and_move_to_data(p_data_now, i_data_len_now, i_len_next_data, p_data_now, i_data_len_now)) {
						break;
					}
				}

				printf("i_len_next_data = %d\n", i_len_next_data);

				//	   // rd 18(0x12)
				//	53 49 4d 50 4c 49 46 49
				//	45 44 20 43 48 49 4e 45
				//	53 45
				i_opt_len = i_len_next_data;
				if (i_data_len_now < i_opt_len) {
					break;
				}
				show_data_no_tip(p_data_now, i_opt_len);
				i_len_next_data = (int)*(u_char*)p_data_now;
				p_data_now += i_opt_len;
				i_data_len_now -= i_opt_len;
			} else {
				break;
			}
		} while (1);

	//	// --------------------------------------------------------------------------------
	//	// 读数据
	//	// --------------------------------------------------------------------------------
	//	10 00 // rd 2
	//	00 00 00 00 // rd 4
	//	05 00 00 00 // rd 4

	//	05 // rd 1
	//	43 48 49 4e 41 // rd 5

	if (0xa3 == us_data_type) {
		//	// --------------------------------------------------------------------------------
		//	// 读数据 - 最后一块
		//	// --------------------------------------------------------------------------------
		//	a3 00 // rd 2 // is us_data_type, 前面已经读取过了

		//	00 00 00 00  ...D << .......... // rd 4
		i_opt_len = 4;
		if (i_data_len_now < i_opt_len) {
			break;
		}
		show_data_no_tip(p_data_now, i_opt_len);
		p_data_now += i_opt_len;
		i_data_len_now -= i_opt_len;

		//	04 // rd 1, 0x00a3就读一个么?
		i_opt_len = 1;
		if (i_data_len_now < i_opt_len) {
			break;
		}
		show_data_no_tip(p_data_now, i_opt_len);
		p_data_now += i_opt_len;
		i_data_len_now -= i_opt_len;

		//	01 00 00 00 // rd 4
		i_opt_len = 4;
		if (i_data_len_now < i_opt_len) {
			break;
		}
		show_data_no_tip(p_data_now, i_opt_len);
		p_data_now += i_opt_len;
		i_data_len_now -= i_opt_len;

		//	04 00 // rd 2
		i_opt_len = 2;
		if (i_data_len_now < i_opt_len) {
			break;
		}
		show_data_no_tip(p_data_now, i_opt_len);
		p_data_now += i_opt_len;
		i_data_len_now -= i_opt_len;

		//	01 // rd 1
		i_opt_len = 1;
		if (i_data_len_now < i_opt_len) {
			break;
		}
		show_data_no_tip(p_data_now, i_opt_len);
		p_data_now += i_opt_len;
		i_data_len_now -= i_opt_len;
	}

	//	   // rd 16 * 8
	//	01 00 00 00 00 00 00 00
	//	00 00 03 00 00 00 03 00
	//	20 00 00 00 00 00 00 00
	//	00 00 00 00 00 00 00 00
	//	00 00 00 00 00 00 00 00
	//	00 05 00 00 01 00 00 00
	//	36 01 00 00 00 00 00 00
	//	00 00 00 00 00 00 00 00
	//	00 4d 6f 19 00 00 00 00
	//	00 00 00 00 00 00 00 00
	//	00 00 00 00 00 00 00 00
	//	00 00 00 00 00 00 00 00
	//	00 00 00 00 00 00 00 00
	//	00 00 00 00 00 00 00 00
	//	00 00 00 00 00 00 00 00
	//	00 00 00 00 00 00 00 00

	i_opt_len = 16 * 8;
	if (i_data_len_now < i_opt_len) {
		break;
	}
	show_data_no_tip(p_data_now, i_opt_len);
	p_data_now += i_opt_len;
	i_data_len_now -= i_opt_len;

		b_packet_process = ((0 == i_data_len_now) ? true : false);
	} while (0);

	printf("<< proc_tns_data_describe_information = %s\n", b_packet_process ? "true" : "false");

	if (!b_packet_process) {
		printf("g_i_cb_packet_process_counter = %d\n", g_i_cb_packet_process_counter); // for debug
	}

	return b_packet_process;
}

/* 最后一行记录包的读法
06

01

// rd 48(8*6)
1a 93 03 00 00 00 00 00
02 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 b0 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00

07

0d

// rd 13 (0x0d)
2c 00 02 06 41 43 43 45 50 54 02 c1 07


04

01 00 00 00

07 00

01

// rd 16 * 8
06 00 00 00 7b 05 00 00
00 00 03 00 00 00 03 00
20 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 08 00 00 01 00 00 00
36 01 00 00 00 00 00 00
00 00 00 00 00 00 00 00
70 8e 50 19 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00

21

4f 52 41 2d

// rd 29 (8*3 + 4 + 1)
30 31 34 30 33 3a 20 e6
9c aa e6 89 be e5 88 b0
e4 bb bb e4 bd 95 e6 95

b0 e6 8d ae

0a
*/
bool proc_tns_data_row_transfer(const u_char* p_data, int i_data_len)
{
	bool b_packet_process = false;
	const u_char* p_data_now = p_data;
	int i_data_len_now = i_data_len;
	int i_opt_len = 0;
	int i_len_next_data = 0;
	int i_column_count = 0;
	int i = 0;
	u_short us_data_type = 0;
	u_char uc_data_type = 0;
	u_char* p_data_merge = NULL;

	printf(">> proc_tns_data_row_transfer\n");
	do {
		show_data("proc_tns_data_row_transfer", p_data_now, i_data_len_now);
		if (33 == g_i_cb_packet_process_counter) {
			printf(""); // for debug
		}

		//0x00000000000000FC = 252

		//	0000   00 50 56 c0 00 08 00 0c 29 91 36 b6 08 00 45 00.PV.....).6...E.
		//	0010   01 2e 03 e0 40 00 80 06 40 15 c0 a8 9a 82 c0 a8  ....@...@.......
		//	0020   9a 01 05 f1 0e 1c a4 3f 0f 12 fc 3f f8 3f 50 18  ....... ? ... ? . ? P.
		//	0030   01 00 27 27 00 00 01 06 00 00 06 00 00 00 00 00  ..''............

		//	06 // rd 1

		// 扒掉皮的数据从这开始
		//	01 // rd 1, type ?
		i_opt_len = 1;
		if (i_data_len_now < i_opt_len) {
			break;
		}
		show_data_no_tip(p_data_now, i_opt_len);
		p_data_now += i_opt_len;
		i_data_len_now -= i_opt_len;

		//	   // rd 48 (8 * 6)
		//	1a 4f 03 00 00 00 00 00
		//	02 00 00 00 00 00 00 00
		//	00 00 00 00 00 00 00 00
		//	00 00 b0 00 00 00 00 00
		//	00 00 00 00 00 00 00 00
		//	00 00 00 00 00 00 00 00

		i_opt_len = 8 * 6;
		if (i_data_len_now < i_opt_len) {
			break;
		}
		show_data_no_tip(p_data_now, i_opt_len);
		p_data_now += i_opt_len;
		i_data_len_now -= i_opt_len;

		//	07 // rd 1
		i_opt_len = 1;
		if (i_data_len_now < i_opt_len) {
			break;
		}
		show_data_no_tip(p_data_now, i_opt_len);
		p_data_now += i_opt_len;
		i_data_len_now -= i_opt_len;

		//	2b // rd 1, length
		if (!get_next_data_len_only(p_data_now, i_data_len_now, i_len_next_data)) {
			break;
		}

		if (i_len_next_data > 0xff) {
			printf("not imp\n");
			break;
		}
		else {
			if (!get_next_data_len_and_move_to_data(p_data_now, i_data_len_now, i_len_next_data, p_data_now, i_data_len_now)) {
				break;
			}
		}

		printf("i_len_next_data = %d\n", i_len_next_data);

		//	   // rd 43 (0x2b = 8 * 5 + 2 + 1)
		//	0c 01 03 00 40 7c 91 00
		//	23 06 41 43 43 45 50 54
		//	02 c1 03 17 69 6e 66 6f
		//	3a 73 65 71 3d 32 2c 74
		//	6f 70 69 63 3d 41 43 43
		//	45 50 54
		i_opt_len = i_len_next_data;
		if (i_data_len_now < i_opt_len) {
			break;
		}
		show_data_no_tip(p_data_now, i_opt_len);
		p_data_now += i_opt_len;
		i_data_len_now -= i_opt_len;

		//	// rd 1
		//	07
		i_opt_len = 1;
		if (i_data_len_now < i_opt_len) {
			break;
		}
		show_data_no_tip(p_data_now, i_opt_len);
		uc_data_type = *p_data_now;
		p_data_now += i_opt_len;
		i_data_len_now -= i_opt_len;

		if (TNS_RECODE_TYPE_NORMAL == uc_data_type) {
			/*
			fe 如果是0xfe, 说明数据长度> 0x255
			// 长度(1) + 数据(0xff) // 这个可能有多块
			// 长度(1) + 数据(0x7f) // 如果长度小于0xff, 数据就拼完了

			将数据长度>0x255的数据拼好后,再分析

			00 04 01 00 00 00 06 00 01
			// 128
			*/

			//	13 // rd 1
			if (!get_next_data_len_only(p_data_now, i_data_len_now, i_len_next_data)) {
				break;
			}

			if (i_len_next_data > 0xff) {
				SAFE_DELETE(p_data_merge);
				p_data_merge = new u_char[i_len_next_data];
				if (!merge_large_data_then_move_to_next_data(p_data_now, i_data_len_now, p_data_now, i_data_len_now, p_data_merge, i_len_next_data)) {
					break;
				}

				// OCI遇到长数据时,也是拷贝出来后,再处理
				if (!parse_data(p_data_merge, i_len_next_data)) {
					break;
				}

				// rd 9
				i_opt_len = 9;
				if (i_data_len_now < i_opt_len) {
					break;
				}
				show_data_no_tip(p_data_now, i_opt_len);
				p_data_now += i_opt_len;
				i_data_len_now -= i_opt_len;

				// rd 128 (8 * 16)
				i_opt_len = 128;
				if (i_data_len_now < i_opt_len) {
					break;
				}
				show_data_no_tip(p_data_now, i_opt_len);
				p_data_now += i_opt_len;
				i_data_len_now -= i_opt_len;
			}
			else {
				if (!get_next_data_len_and_move_to_data(p_data_now, i_data_len_now, i_len_next_data, p_data_now, i_data_len_now)) {
					break;
				}

				printf("i_len_next_data = %d\n", i_len_next_data);
				show_data_no_tip(p_data_now, i_data_len_now);

				if (i_len_next_data < i_data_len_now) {
					// i_len_next_data 指示的是当前数据块中的一部分数据长度
					//	   // rd 19(0x13 = 8 * 2 + 2 + 1)
					//	2c 00 03 06 41 43 43 45
					//	50 54 02 c1 04 05 69 6e
					//	66 6f 33
					i_opt_len = i_len_next_data;
					if (i_data_len_now < i_opt_len) {
						break;
					}
					show_data_no_tip(p_data_now, i_opt_len);
					i_len_next_data = (int)*(u_char*)p_data_now;
					p_data_now += i_opt_len;
					i_data_len_now -= i_opt_len;

					//	04 // rd 1
					i_opt_len = 1;
					if (i_data_len_now < i_opt_len) {
						break;
					}
					show_data_no_tip(p_data_now, i_opt_len);
					i_len_next_data = (int)*(u_char*)p_data_now;
					p_data_now += i_opt_len;
					i_data_len_now -= i_opt_len;

					//	01 00 00 00 // rd 4
					i_opt_len = i_len_next_data;
					if (i_data_len_now < i_opt_len) {
						break;
					}
					show_data_no_tip(p_data_now, i_opt_len);
					i_len_next_data = (int)*(u_char*)p_data_now;
					p_data_now += i_opt_len;
					i_data_len_now -= i_opt_len;

					//	05 00 // rd 2
					i_opt_len = 2;
					if (i_data_len_now < i_opt_len) {
						break;
					}
					show_data_no_tip(p_data_now, i_opt_len);
					p_data_now += i_opt_len;
					i_data_len_now -= i_opt_len;

					//	01 // rd 1
					i_opt_len = 1;
					if (i_data_len_now < i_opt_len) {
						break;
					}
					show_data_no_tip(p_data_now, i_opt_len);
					p_data_now += i_opt_len;
					i_data_len_now -= i_opt_len;

					//	   // rd 128 (8 * 16)
					i_opt_len = 8 * 16;
					if (i_data_len_now < i_opt_len) {
						break;
					}
					show_data_no_tip(p_data_now, i_opt_len);
					p_data_now += i_opt_len;
					i_data_len_now -= i_opt_len;
				}
			}
		}
		else if (TNS_RECODE_TYPE_LAST == uc_data_type) {
			// 01 00 00 00 // rd 4
			i_opt_len = 4;
			if (i_data_len_now < i_opt_len) {
				break;
			}
			show_data_no_tip(p_data_now, i_opt_len);
			p_data_now += i_opt_len;
			i_data_len_now -= i_opt_len;

			// 07 00 // rd 2
			i_opt_len = 2;
			if (i_data_len_now < i_opt_len) {
				break;
			}
			show_data_no_tip(p_data_now, i_opt_len);
			p_data_now += i_opt_len;
			i_data_len_now -= i_opt_len;

			// 01 // rd 1
			i_opt_len = 1;
			if (i_data_len_now < i_opt_len) {
				break;
			}
			show_data_no_tip(p_data_now, i_opt_len);
			p_data_now += i_opt_len;
			i_data_len_now -= i_opt_len;

			// rd 16 * 8
			//06 00 00 00 7b 05 00 00
			//00 00 03 00 00 00 03 00
			//20 00 00 00 00 00 00 00
			//00 00 00 00 00 00 00 00
			//00 00 00 00 00 00 00 00
			//00 08 00 00 01 00 00 00
			//36 01 00 00 00 00 00 00
			//00 00 00 00 00 00 00 00
			//70 8e 50 19 00 00 00 00
			//00 00 00 00 00 00 00 00
			//00 00 00 00 00 00 00 00
			//00 00 00 00 00 00 00 00
			//00 00 00 00 00 00 00 00
			//00 00 00 00 00 00 00 00
			//00 00 00 00 00 00 00 00
			//00 00 00 00 00 00 00 00
			i_opt_len = 8 * 16;
			if (i_data_len_now < i_opt_len) {
				break;
			}
			show_data_no_tip(p_data_now, i_opt_len);
			p_data_now += i_opt_len;
			i_data_len_now -= i_opt_len;

			// 21 rd 1, 读数据长度, 暂不考虑超长数据
			i_opt_len = 1;
			if (i_data_len_now < i_opt_len) {
				break;
			}
			show_data_no_tip(p_data_now, i_opt_len);
			i_len_next_data = (int)*(u_char*)p_data_now;
			p_data_now += i_opt_len;
			i_data_len_now -= i_opt_len;

			// 一起读的,可能为了字节对齐,先读了4个字节
			// 4f 52 41 2d // rd 4
			// rd 29 (8*3 + 4 + 1)
			//30 31 34 30 33 3a 20 e6
			//9c aa e6 89 be e5 88 b0
			//e4 bb bb e4 bd 95 e6 95
			//b0 e6 8d ae
			//0a
			i_opt_len = i_len_next_data;
			if (i_data_len_now < i_opt_len) {
				break;
			}
			show_data_no_tip(p_data_now, i_opt_len);
			p_data_now += i_opt_len;
			i_data_len_now -= i_opt_len;
		}
		else {
			// 未实现的记录类型分析
			printf("not imp, uc_data_type = %d\n", uc_data_type);
			break;
		}

		b_packet_process = ((0 == i_data_len_now) ? true : false);
	} while (0);
	printf("<< proc_tns_data_row_transfer = %s\n", b_packet_process ? "true" : "false");

	if (!b_packet_process) {
		printf("g_i_cb_packet_process_counter = %d\n", g_i_cb_packet_process_counter); // for debug
	}

	SAFE_DELETE(p_data_merge);
	return b_packet_process;
}

bool get_next_data_len_and_move_to_data(const u_char* pdata_in, int i_len_in, int& i_next_data_len_out, const u_char*& ppdata_out, int& i_len_out)
{
	bool b_rc = false;
	u_char uc_len = '\0';
	int i_len = 0;
	const u_char* pdata_now = pdata_in;
	int i_len_now = i_len_in;
	int i_len_opt = 0;
	int i_pos = 0;

	do {
		if ((NULL == pdata_in) || (NULL == ppdata_out)) {
			break;
		}

		if (i_len_now < 1) {
			break;
		}

		// 可以直接挪动到数据的情况,只存在于长度小于0xfc的情况
		// when length >= 0xfc, data have multi part
		uc_len = *(u_char*)pdata_now;
		if (uc_len >= 0xfc) {
			break;
		}

		i_len = (int)uc_len;
		i_len_opt = 1;
		pdata_now += i_len_opt;
		i_len_now -= i_len_opt;

		ppdata_out = pdata_now;
		i_len_out = i_len_now;
		i_next_data_len_out = i_len;

		b_rc = true;
	} while (0);

	return b_rc;
}

bool get_next_data_len_only(const u_char* pdata_in, int i_len_in, int& i_next_data_len_out)
{
	bool b_rc = false;
	u_char uc_len = '\0';
	int i_len = 0;
	const u_char* pdata_now = pdata_in;
	int i_len_now = i_len_in;
	int i_len_opt = 0;
	int i_pos = 0;

	i_next_data_len_out = 0;
	do {
		if (NULL == pdata_in) {
			break;
		}

		if (i_len_now < 1) {
			break;
		}

		uc_len = *(u_char*)pdata_now;
		if (uc_len < 0xfc) {
			i_next_data_len_out = (int)uc_len;
			b_rc = true;
			break;
		}
		else if (uc_len == 0xfc) {
			printf("not imp...\n");
			break;
		}
		else if (uc_len == 0xfd) {
			printf("not imp...\n");
			break;
		}
		else if (uc_len == 0xfe) {
			i_len_now--;
			pdata_now++;
			if (i_len_now < 1) {
				break;
			}

			do {
				uc_len = *pdata_now;
				i_len_now--;
				pdata_now++;
				if (i_len_now < (int)uc_len) {
					break;
				}

				if (0xff == uc_len) {
					// FE FF data[...] length[1bytes] data[...] length[1bytes] data[...]

					// move after 0xff

					i_next_data_len_out += (int)uc_len;
					i_len_now -= (int)uc_len;
					pdata_now += (int)uc_len;
					continue;
				} else {
					i_next_data_len_out += (int)uc_len;
					b_rc = true;
					break;
				}
			} while (1);
		}
		else {
			printf("not imp...\n");
			break;
		}
	} while (0);

	if (i_next_data_len_out > 0xff) {
		printf(""); // for debug
	}

	return b_rc;
}

bool merge_large_data_then_move_to_next_data(
	const u_char* pdata_in, int i_len_in,
	const u_char*& ppdata_next_out, int& i_len_next_out,
	const u_char* pdata_merge_out, int i_len_merge)
{
	bool b_rc = false;
	const u_char* pdata_now = pdata_in;
	int i_len_now = i_len_in;
	u_char uc_len = '\0';
	int i_len_merge_index = 0;

	do {
		i_len_next_out = i_len_in;

		if ((NULL == pdata_in)
			|| (NULL == ppdata_next_out)
			|| (NULL == *ppdata_next_out)
			|| (NULL == pdata_merge_out)
			|| (i_len_in < i_len_merge)) {
			break;
		}

		if (i_len_now < 1) {
			break;
		}

		uc_len = *(u_char*)pdata_now;
		i_len_now--;
		pdata_now++;
		if (uc_len < 0xfc) {
			if (i_len_merge < uc_len) {
				break;
			}
			i_len_merge -= uc_len;

			memcpy((void*)(pdata_merge_out + i_len_merge_index), pdata_now, uc_len);
			i_len_merge_index += uc_len;

			i_len_now -= (int)uc_len;
			pdata_now += (int)uc_len;

			b_rc = true;
			break;
		}
		else if (uc_len == 0xfc) {
			printf("not imp...\n");
			break;
		}
		else if (uc_len == 0xfd) {
			printf("not imp...\n");
			break;
		}
		else if (uc_len == 0xfe) {
			if (i_len_now < 1) {
				break;
			}

			do {
				uc_len = *pdata_now;
				i_len_now--;
				pdata_now++;
				if (i_len_now < (int)uc_len) {
					break;
				}

				if (0xff == uc_len) {
					// FE FF data[...] length[1bytes] data[...] length[1bytes] data[...]
					if (i_len_merge < uc_len) {
						break;
					}
					i_len_merge -= uc_len;

					memcpy((void*)(pdata_merge_out + i_len_merge_index), pdata_now, uc_len);
					i_len_merge_index += uc_len;

					i_len_now -= (int)uc_len;
					pdata_now += (int)uc_len;
					continue;
				}
				else {
					if (i_len_merge < uc_len) {
						break;
					}
					i_len_merge -= uc_len;

					memcpy((void*)(pdata_merge_out + i_len_merge_index), pdata_now, uc_len);
					i_len_merge_index += uc_len;

					i_len_now -= (int)uc_len;
					pdata_now += (int)uc_len;

					b_rc = true;
					break;
				}
			} while (1);
		}
		else {
			printf("not imp...\n");
			break;
		}
	} while (0);

	i_len_next_out = i_len_now;
	ppdata_next_out = pdata_now;

	return b_rc;
}

bool parse_data(const u_char* pdata_in, int i_len_in)
{
	bool b_rc = false;

	do {
		if ((NULL == pdata_in)
			|| (i_len_in <= 0)) {
			break;
		}

		show_data_no_tip(pdata_in, i_len_in);
		b_rc = true;
	} while (0);

	return b_rc;
}

u_long get_data_value(const u_char* pdata_in, int i_len_in)
{
	int i = 0;
	u_long l_rc = 0;
	u_char uc = '\0';

	do {
		if ((NULL == pdata_in) || (i_len_in <= 0)) {
			break;
		}

		// OCI里面取数据,也是从后往前取,计算方便
		for (i = 0; i < i_len_in; i++) {
			uc = *(pdata_in + i_len_in - 1 - i);
			l_rc <<= 8;
			l_rc += (u_long)uc;
		}
	} while (0);

	return l_rc;
}
// MyThread.cpp: implementation of the CMyThread class.
//
//

#include "stdafx.h"
#include <process.h>
#include "MyThread.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#define new DEBUG_NEW
#endif

//
// Construction/Destruction
//

CMyThread::CMyThread()
{
	m_hThread = NULL;
	m_pThreadProc = NULL;
	m_uThreadId = (UINT)-1;
	m_pUserData = NULL;

	/// 事件对象用于通知机制时的创建要求, 手工复位, 有信号
	m_hEventContinue = CreateEvent(NULL, TRUE, TRUE, NULL);
	m_hEventQuit = CreateEvent(NULL, TRUE, TRUE, NULL);
}

CMyThread::~CMyThread()
{
	Stop();
}

void CMyThread::RegisterThreadProc(CMyThread::TAG_REGISTERTHREADPROC* pParam) {
	if ((NULL != pParam) && (NULL != pParam->pfnThreadProc)) {
		if (m_pThreadProc != pParam->pfnThreadProc) {
			Stop();

			/// 线程入参
			m_pThreadProc = pParam->pfnThreadProc;
			m_pUserData = pParam->pUserData;

			/// 填充出参
			pParam->pThreadControlClass = this;
			pParam->pfnIsCanContinue = &CMyThread::cbIsCanContinue;
			pParam->pfnIsNeedQuit = &CMyThread::cbIsNeedQuit;
		}
	}
}

void CMyThread::Start() {
	if (NULL != m_pThreadProc) {
		Stop();
		Continue();
		m_hThread = (HANDLE)_beginthreadex(
			NULL, 0, m_pThreadProc, m_pUserData, 0, &m_uThreadId);
	}
}

void CMyThread::Pause() {
	ResetEvent(m_hEventContinue);
}

void CMyThread::Continue() {
	SetEvent(m_hEventContinue);
}

BOOL CMyThread::cbIsCanContinue() {
	WaitForSingleObject(m_hEventContinue, INFINITE);
	return TRUE;
}

BOOL CMyThread::cbIsNeedQuit() {
	return (WAIT_OBJECT_0 == WaitForSingleObject(m_hEventQuit, 0));
}

void CMyThread::Stop() {
	SetEvent(m_hEventQuit);
	Continue();

	if (NULL != m_hThread) {
		WaitForSingleObject(m_hThread, INFINITE);
		m_hThread = NULL;
	}

	ResetEvent(m_hEventQuit);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值