Oracle客户端和服务器使用TNS作为其数据交换协议。 它提供了一种对用户透明的层, 为不同的工业标准协议提供统一, 通用的接口。

基本上是TNS以这样的方式指定了端口1521上的会话是“控制”的各种会话。 Oracle侦听器进程在此端口上侦听。连接到此端口后,客户端请求Oracle“服务”。如果侦听器知道此类服务,则将“重定向”消息发送回客户端。

在分析期间,通过Wireshark的抓取Oracle TNS协议解析分析。

TNS 协议版本

协议版本Oracle 版本
SQL*Net v1Oracle Database Server 6
SQL*Net v2Oracle Database Sever 7 (7.0.15.4)
Net8Oracle Database Server 8.x 开始
Oracle NetOracle Database Server 9 以后

实际上TNS 属于 Oracle Net 的一部分, 我们通常所说的 TNS 协议其实是 SQL*Net 协议,现在 Oracle 将它称之为 Oracle Net

Oracle Net Stack通信

数据库服务器是管理数据库的Oracle软件,客户端是从服务器请求信息的应用程序。 客户端和服务器通信的方式称为客户端/服务器堆栈。

在这里插入图片描述
通过数据库服务器端上的类似通信堆栈接收来自客户端通信堆栈发送的客户端应用程序的信息。 数据库服务器侧的过程流程与客户端的进程流相反,通过通信层的信息升高。

该通信架构基于开放系统互连(OSI)模型。 在OSI模型中,单独的计算机之间的通信以堆叠的方式发生,其中通过几层代码从一个节点传递给另一个节点,包括:

在这里插入图片描述

除了支持 TCP/IP 协议之外,TNS 协议还支持以下基础网络协议:

  • TCP/IP (IPv4 and IPv6)
  • TCP/IP with SSL
  • Named Pipes
  • Sockets Direct Protocol (SDP)

客户端/服务器连接进程中的所有Oracle软件都需要现有的网络协议栈来在传输层的两台计算机之间建立计算机级连接。

网络协议负责将数据从客户端计算机传输到数据库服务器计算机,此时数据将数据传递给服务器端Oracle协议支持层。

TNS 协议基本结构分析

在这里插入图片描述
Packet length:是整个TNS报文的长度。
Packet Checksum: 默认不生成,用0填充。
Packet Type:标志TNS数据包的类型,可能的数据包类型是:

#define TNS_TYPE_CONNECT        1
#define TNS_TYPE_ACCEPT         2
#define TNS_TYPE_ACK            3
#define TNS_TYPE_REFUSE         4
#define TNS_TYPE_REDIRECT       5
#define TNS_TYPE_DATA           6
#define TNS_TYPE_NULL           7
#define TNS_TYPE_ABORT          9
#define TNS_TYPE_RESEND         11
#define TNS_TYPE_MARKER         12
#define TNS_TYPE_ATTENTION      13
#define TNS_TYPE_CONTROL        14
#define TNS_TYPE_MAX            19

type的最大值为19, 超过19都不是TNS的报文。

Reserved :为 00。
header Checksum: 默认不生成,用0填充。

Oracle TNS 协议解析

下面对Oracle TNS 协 议做较为详细的解析。
在这里插入图片描述

  • Connect

在这里插入图片描述

客户端连接数据库,首先发送 Connect 报文,连接数据包是类型1。

连接数据是表单的字符串(source_route = yes)(hop_count = 0)(connect_data =((sid =)cid =(program =)(host =)(user =)))或类似的。

示例连接数据:

(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(Host=ahost)(Port=1521))
(CONNECT_DATA=(SID=test)(CID=(PROGRAM=)(HOST=abcdef)(USER=root))))

报文中重点包含 客户端可以使用的 NS 版本范围,及连接数据。

  • Accept

数据库服务器收到正确的连接请求,最终会回应 Accept 报文,在Accept之前会回应 Resend 或者 Redirect报文。

在这里插入图片描述
Accept报文中重点包含服务器接受的NS 版 本。

  • Refuse

当客户端发 起错 误的连接时, 会收 到 服 务 器 返 回 的 Refuse 报 文。

  • Redirect

当客户端收到 Redirect 报文,将终止当前的网络连接(FIN, ACK),使用 Redirect 报文中的参数(协议、主机及端口)重新发起 连接。

  • Data

在这里插入图片描述
要了解Data报文,关键是需要知道TTCCode的含义:

#define SQLNET_SET_PROTOCOL     1
#define SQLNET_SET_DATATYPES    2
#define SQLNET_USER_OCI_FUNC    3
#define SQLNET_RETURN_STATUS    4
#define SQLNET_ACCESS_USR_ADDR  5
#define SQLNET_ROW_TRANSF_HDR   6
#define SQLNET_ROW_TRANSF_DATA  7
#define SQLNET_RETURN_OPI_PARAM 8
#define SQLNET_FUNCCOMPLETE     9
#define SQLNET_NERROR_RET_DEF   10
#define SQLNET_IOVEC_4FAST_UPI  11
#define SQLNET_LONG_4FAST_UPI   12
#define SQLNET_INVOKE_USER_CB   13
#define SQLNET_LOB_FILE_DF      14
#define SQLNET_WARNING          15
#define SQLNET_DESCRIBE_INFO    16
#define SQLNET_PIGGYBACK_FUNC   17
#define SQLNET_SIG_4UCS         18
#define SQLNET_FLUSH_BIND_DATA  19
#define SQLNET_SNS              0xdeadbeef
#define SQLNET_XTRN_PROCSERV_R1 32
#define SQLNET_XTRN_PROCSERV_R2 68
  • Marker

在这里插入图片描述
Marker 报文的作用是通知客户端或服务器停止发送数据, Marker 报文仅有 3 个字节。

Oracle(TNS)协议解析及C/C++代码解析

	switch (type)
	{
		case TNS_TYPE_CONNECT:
			dissect_tns_connect(oracle_data,offset);
			break;
		case TNS_TYPE_ACCEPT:
			dissect_tns_accept(oracle_data,offset);
			break;
		case TNS_TYPE_REFUSE:
			dissect_tns_refuse(oracle_data,offset);
			break;
		case TNS_TYPE_REDIRECT:
			dissect_tns_redirect(oracle_data,offset);
			break;
		case TNS_TYPE_ABORT:
			dissect_tns_abort(oracle_data,offset);
			break;
		case TNS_TYPE_MARKER:
			dissect_tns_marker(oracle_data,offset);
			break;
		case TNS_TYPE_ATTENTION:
			dissect_tns_marker(oracle_data,offset);
			break;
		case TNS_TYPE_CONTROL:
			dissect_tns_control(oracle_data,offset);
			break;
		case TNS_TYPE_DATA:
			dissect_tns_data(oracle_data,offset);
			break;
		default:

			break;
	}

解析运行:
在这里插入图片描述

总结

本文分析了Oracle的网络结构和报文基本结构,最后对TNS的关键报文进行了较为详细的解析及代码实现。

欢迎关注微信公众号【程序猿编码】,需要Oracle TNS完整源码和报文请添加本人微信号(c17865354792)

参考:1. https://docs.oracle.com/cd/B28359_01/network.111/b28316/architecture.htm#NETAG004
2.http://www.oracle-internals.com/?p=22

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐