尝试分析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 // 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 = ®ister_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 = ®ister_thread_user_control;
register_thread_user_control.pUserData = &thread_param;
register_thread_user_control.pfnThreadProc = ThreadProc;
thread_user_control.RegisterThreadProc(®ister_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(ð_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
#pragma comment(lib, "Ws2_32.lib")
#include
#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
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
#include
#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(<ime, &local_tv_sec);
strftime(timestr, sizeof timestr, "%H:%M:%S", <ime);
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
#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);
}