网络管理相关知识:RTA 与 SNMP 详解
1. RTA 相关内容
1.1 RTA 错误定义
在 RTA 中,定义了一系列错误信息,这些错误信息以宏定义的形式呈现,用于在数据库操作过程中提示不同类型的错误。以下是具体的错误定义:
#define Er_Max_Tbls "%s %d: Too many tables in DB"
#define Er_Max_Cols "%s %d: Too many columns in DB"
#define Er_Tname_Big "%s %d: Too many characters in table name: %s"
#define Er_Cname_Big "%s %d: Too many characters in column name: %s"
#define Er_Hname_Big "%s %d: Too many characters in help text: %s"
#define Er_Tbl_Dup "%s %d: DB already has table named: %s"
#define Er_Col_Dup "%s %d: Table '%s' already has column named: %s"
#define Er_Col_Type "%s %d: Column contains an unknown data type: %s"
#define Er_Col_Flag "%s %d: Column contains unknown flag data: %s"
#define Er_Col_Name "%s %d: Incorrect table in column definition: %s"
#define Er_Cmd_Cols "%s %d: Too many columns in table: %s"
#define Er_No_Space "%s %d: Not enough buffer space"
#define Er_Reserved "%s %d: Table or column is a reserved word: %s"
这些错误信息涵盖了数据库中表和列的数量限制、名称长度限制、重复定义、数据类型错误等多种常见问题。
1.2 SQL 错误定义
除了 RTA 错误,还定义了一些 SQL 相关的错误:
#define Er_Bad_SQL "%s %d: SQL parse error: %s"
#define Er_Readonly "%s %d: Attempt to UPDATE readonly column: %s"
Er_Bad_SQL
用于提示 SQL 语句解析错误,而
Er_Readonly
则用于阻止对只读列进行更新操作。
1.3 跟踪消息定义
跟踪消息用于记录 SQL 命令的执行情况:
#define Er_Trace_SQL "%s %d: SQL command: %s (%s)"
这个宏定义可以帮助开发者在调试过程中了解具体执行的 SQL 命令。
1.4 回调例程
在 RTA 中,有读回调和写回调两种回调例程。读回调在使用列值之前执行,写回调在所有列更新完成后调用。它们在成功时返回 0,失败时返回非零值。
1.4.1 读回调
读回调对于计算总和、平均值等数值非常有用,因为只有在需要这些值时才进行计算,避免了不必要的连续计算开销。读回调的调用参数如下:
| 参数 | 描述 |
| ---- | ---- |
|
char *tblname
| 引用的表名 |
|
char *colname
| 引用的列名 |
|
char *sqlcmd
| SQL 命令的文本 |
|
void *pr
| 指向表中受影响行的指针 |
|
int rowid
| 正在读取或写入的行的从零开始的行号 |
以下是一个简单的流程图,展示读回调的执行流程:
graph TD;
A[开始] --> B[执行读操作];
B --> C{是否需要读回调};
C -- 是 --> D[执行读回调];
C -- 否 --> E[继续读操作];
D --> E;
E --> F[结束];
1.4.2 写回调
写回调在与配置更改相关的场景中最为适用,同时也是记录配置更改的理想位置。写回调的参数与读回调基本相同,但增加了一个指向修改前行副本的指针,这有助于检测行数据的变化。写回调的调用参数如下:
| 参数 | 描述 |
| ---- | ---- |
|
char *tblname
| 引用的表名 |
|
char *colname
| 引用的列名 |
|
char *sqlcmd
| SQL 命令的文本 |
|
void *pr
| 指向表中受影响行的指针 |
|
int rowid
| 正在读取或写入的行的从零开始的行号 |
|
void *poldrow
| 指向修改前行副本的指针 |
写回调在失败时,会将表的行恢复到初始值,并向客户端返回 SQL 错误
TRIGGERED ACTION EXCEPTION
。以下是写回调的执行流程:
graph TD;
A[开始] --> B[执行更新操作];
B --> C{是否执行完所有列更新};
C -- 是 --> D[执行写回调];
C -- 否 --> B;
D --> E{写回调是否成功};
E -- 是 --> F[更新完成];
E -- 否 --> G[恢复行到初始值];
G --> H[返回 SQL 错误];
F --> I[结束];
H --> I;
2. SNMP 相关内容
2.1 为什么需要 SNMP
在 20 世纪 70 年代初,计算机及其 I/O 设备体积庞大,需要专门的空调房间。大多数大公司使用独立系统进行计算任务,出现问题时,系统控制台会打印错误信息,前面板指示灯也会停止闪烁,很容易发现问题。
然而,如今即使是小型科技公司也拥有服务器机房,里面摆满了来自多个供应商的计算机和网络设备,如交换机、路由器、打印服务器、Web 服务器、RAID 服务器等。网络打印机分布在各个方便的位置,每个办公桌都配备了台式机或笔记本电脑。高科技公司的计算机数量通常比员工数量还多。
在这样复杂的网络环境中,单个组件的故障很难被检测到。因此,IT 管理人员需要某种自动化手段来管理这些设备。简单的自动化可以是自定义的脚本,用于定期进行 ping 扫描,但大型网络更可能依赖于使用 SNMP 的网络管理系统(NMS),如惠普的 OpenView。这种系统不仅可以检测设备故障,还可以记录性能统计信息、保存重启历史记录,并维护设备发送的关于潜在问题的通知日志。设备可能会报告数据包丢失或重传过多、连接失败、风扇转速过慢或 CPU 过热、CPU、内存或磁盘利用率过高以及系统重启等问题。
2.2 代理和管理器
被管理的设备(如路由器、交换机、Web 主机、台式计算机、网络打印机等)都运行一个名为 SNMP 代理的服务器进程(守护进程)。该代理监听特定的 UDP 端口(通常是 161 端口,但不总是),以接收读(GET)和写(SET)命令,并负责获取请求的数据并返回。此外,该代理和设备上的其他监控软件还可以向一个或多个配置好的目标系统发送自发通知,称为陷阱(traps)或通知(informs)。
管理应用程序(管理器)会轮询代理以获取信息。它们可以保存历史信息、生成报告或创建网络设备的图形化地图。一些管理应用程序只是简单的命令行工具,如 Net - SNMP 提供的
snmpwalk
、
snmpget
和
snmpset
命令。
以下是代理和管理器之间交互的简单流程图:
graph LR;
A[管理器] --> B[发送请求];
B --> C[SNMP 代理];
C --> D[处理请求];
D --> E[返回响应];
E --> A;
C --> F[发送陷阱/通知];
F --> G[管理器];
2.3 命名空间、语法和协议
SNMP 代表简单网络管理协议,但它实际上不仅仅是一个协议,还包括数据命名方式、数据描述语法和网络数据交换协议。这些组件分别称为 MIB(命名方案)、SMI(语法)和 SNMP 协议。描述 SNMP 的 RFC 包含了一组对管理网络设备有用的通用信息,称为 MIB - 2。
2.4 MIB(管理信息库)
MIB 代表管理信息库,可以将其视为虚拟数据库的分层命名方案。这是一个“虚拟”数据库,因为数据可能在代理收到读取请求之前并不存在于存储中。当请求一个对象(可以看作数据库记录中的一个字段)时,代理会检索信息并返回,这个过程可能涉及从被管理系统获取多个信息片段并计算要返回的值。请求信息的行为本身可能会触发值的创建。
虽然有一个通用的寻址方案,但我们将其划分为多个子分区,也称为 MIB。通常,人们提到 MIB 时,指的是其中一个子分区。MIB - 2 就是其中之一,还有许多其他 MIB 由不同的组织为不同的目的定义。有些由标准组织制定,有些由私有公司定义,用于描述其网络产品提供的专有数据。
2.5 OID(对象标识符)
每个 MIB 中的每个对象都有一个对象标识符(OID)。OID 是一个由句点分隔的十进制数字序列组成的唯一名称,例如
.1.3.6.1.2.1.1.2.0
。这个名称表示对象在命名空间中的位置,第一个点代表树的根,每个数字代表树中的一个节点(分支的基础)。SNMP 中所有可命名的对象都位于这个 OID 树的某个位置,每个名称(OID)都包含从树的根到该对象的完整路径。
OID 的工作方式类似于 Unix 文件系统。例如,Unix 文件系统中的文件路径
/usr/local/bin/myprog
,如果用点代替斜杠分隔目录,路径将变为
.usr.local.bin.myprog
。假设存在以下目录名称和数字的映射表:
| 目录 | 编号 |
| ---- | ---- |
|
usr
| 1 |
|
local
| 3 |
|
bin
| 6 |
|
myprog
| 1 |
那么使用数字代替名称后,路径将变为
.1.3.6.1
。
在 OID 树中,一些节点以组织命名,如 ISO(国际标准化组织)和 DOD(美国国防部)。互联网号码分配机构(IANA)负责为企业节点下的公司和组织分配编号,这些公司和组织有权管理其自身子树中的 OIDs。我们最感兴趣的部分是
.1.3.6.1
(
.iso.org.dod.internet
)下的节点,包括
mgmt.mib - 2
(
.1.3.6.1.2.1
)子树和
private.enterprises
(
.1.3.6.1.4.1
)子树。MIB - 2 是前面提到的通用对象集,所有可通过 SNMP 管理的网络设备都支持它。企业 OID 是组织注册其私有 MIB 的地方。
网络管理相关知识:RTA 与 SNMP 详解
2.6 MIB - 2
MIB - 2 在 RFC 1213 中定义,描述了一组对管理网络设备有帮助的核心信息。它被组织成以下十个组,并非所有网络设备都支持所有组,但通常可以找到大部分组。
| 组名 | 描述 |
| ---- | ---- |
| System | 包含如
sysDescr
(操作系统、硬件、网络软件等的可打印描述)、
sysContact
(通常是系统管理员的电子邮件地址)、
sysLocation
(系统位置的可打印描述)和
sysObjectID
(可用于确定设备类型的 OID)等对象。 |
| Interfaces | 是一个描述系统可用网络接口的表,包含每个接口的速度和接口活动(进出字节数)信息。通过定期轮询进出字节数,可以了解接口带宽的使用百分比,有助于监控网络中路由器的容量。 |
| AT | 地址转换组,MIB - 2 弃用了该组,仅为与实现 MIB - 1 的设备兼容而包含。除非对 SNMP 历史有特殊兴趣,否则可忽略该组。 |
| IP | 包含与 IP(网络)层相关的信息,如
ipAddrTable
(IP 地址表),描述系统可用接口的 IP 地址。 |
| ICMP | 包含各种 Internet 控制消息协议(ICMP)统计信息。 |
| TCP | 包含各种 TCP 层统计信息,如
tcpConnTable
(TCP 连接表),描述该系统与网络中其他系统之间的当前 TCP 连接。该表常用于网络发现。 |
| UDP | 包含各种用户数据报协议(UDP)数据报统计信息。 |
| EGP | 包含支持外部网关协议(EGP)的系统的 EGP 统计信息。 |
| Transmission | 包含与管理传输介质相关的信息。 |
| SNMP | 包含与 SNMP 协议本身相关的各种统计信息。 |
2.7 SMI(管理信息结构)
MIB 使用由管理信息结构(SMI)定义的语法进行描述,SMI 是抽象语法表示法一(ASN.1)的子集。ASN.1 的创建是为了以独立于机器架构的方式描述数据(例如,不假设字节序或字长)。SNMP SMI 采用了 ASN.1 可定义的对象类型的子集,然后简化了表示法。
以下是一个使用 SMI 语法描述的对象定义示例:
system OBJECT IDENTIFIER ::= { mib-2 1 }
sysDescr OBJECT-TYPE
SYNTAX DisplayString (SIZE (0..255))
ACCESS read-only
STATUS mandatory
DESCRIPTION
"A textual description of the entity. This value
should include the full name and version
identification of the system's hardware type,
software operating-system, and networking
software. It is mandatory that this only contain
printable ASCII characters."
::= { system 1 }
::=
表示“被定义为”,
{mib - 2 1}
表示如果
mib - 2
是
.1.3.6.1.2.1
,那么
system
是
.1.3.6.1.2.1.1
,因此
sysDescr
是
.1.3.6.1.2.1.1.1
。每个定义描述了 OID 树中的一个步骤。
需要注意的是,有些对象标识符只是描述树结构中的节点,而有些则描述实际可读取的对象(叶节点),这类似于文件系统中的目录和文件。在读取
sysDescr
时,必须请求
.1.3.6.1.4.1.1.1.0
,这里的结尾零表示正在检索对象的实例。标量对象实例(即不在表中的独立对象)总是以
.0
结尾。
SMI 对 MIB 的描述通常分布在 MIB 文件中,这是一个文本文件,包含对通用 MIB 一部分的明确描述。有时,单个表的描述会放在单独的文件中,其他文件可能只包含一组其他 MIB 文件使用的通用对象或定义,如文本约定。通常,特定产品的私有 MIB 会在单个文件或一小部分文件中描述,并根据需要从其他文件导入类型和约定,类似于 C 语言中使用
#include
语句。MIB 文件不仅是供人类使用的 MIB 正式定义,还可通过编程方式用于解释 SNMP 响应以显示给人类。因此,MIB 文件必须像任何计算机程序一样在语法上正确,有 MIB 编译器和检查器来帮助验证 MIB 文件的正确性。
以下是一个简单的流程图,展示 MIB 文件的使用流程:
graph TD;
A[编写 MIB 文件] --> B[验证 MIB 文件];
B --> C{验证是否通过};
C -- 是 --> D[使用 MIB 文件读取 SNMP 响应];
C -- 否 --> E[修改 MIB 文件];
E --> B;
D --> F[显示解释后的结果];
2.8 SNMP 协议
虽然 SNMP 协议值得单独用一章来介绍,但我们可以从它定义的协议数据单元(PDUs)及其用途来了解其大部分内容。
2.8.1 基本命令:GET、SET、GETNEXT
SNMP 协议用于在被管理系统和管理它们的应用程序之间交换信息。被管理系统运行一个名为代理(通常是
snmpd
)的守护进程,它提供从一个或多个 MIB 中读取信息或写入信息的能力。
GET
、
SET
和
GETNEXT
PDUs 分别用于读取、写入和遍历 MIB。
-
GET命令 :用于从 MIB 中读取特定对象的值。 -
SET命令 :用于向 MIB 中的可写对象写入值。 -
GETNEXT命令 :允许指定一个对象,然后请求代理返回 MIB 树中下一个对象的 OID 和值。通过重复使用GETNEXT命令,可以从 OID 树的某个点开始遍历其整个子树,这个过程称为遍历 MIB。当返回的 OID 不在第一个 OID 定义的子树内时,遍历结束。应用程序可以通过这种方式找出被管理系统支持哪些 MIB。
以下是
GETNEXT
遍历 MIB 的流程图:
graph TD;
A[开始遍历] --> B[发送 GETNEXT 请求];
B --> C[代理处理请求];
C --> D{返回的 OID 是否在子树内};
D -- 是 --> E[输出 OID 和值];
E --> B;
D -- 否 --> F[结束遍历];
2.8.2 陷阱和通知
被管理系统还可以向配置好的目标管理节点自发发送信息,这个过程称为发送 SNMP 陷阱(trap)或通知(inform)。陷阱是向目标系统发送的,但发送者永远不知道是否到达。通知是对陷阱的改进,因为它期望从接收者那里得到回复,如果在合理时间内没有收到回复,可以重试。
以下是陷阱和通知的发送流程对比图:
graph LR;
A[被管理系统] --> B[发送陷阱];
B --> C[目标管理节点];
A --> D[发送通知];
D --> E[目标管理节点];
E --> F[返回回复];
F --> D;
2.9 命令行工具示例
以下是使用 Net - SNMP 包提供的命令行工具的示例,这些工具使用了前面讨论的 SNMP PDUs 来实现其功能。
-
snmpget命令 :用于检索单个对象的值。例如,要检索前面提到的sysDescr字段,可以使用以下命令:
snmpget -c public 10.1.1.21 .1.3.6.1.2.1.1.1.0
这个命令请求 IP 地址为
10.1.1.21
的系统上
sysDescr
对象的实例,使用的社区名称为
public
(可以将其视为密码)。
snmpget
命令会生成一个 SNMP
GET
PDU。
-
snmpwalk命令 :使用一系列GETNEXTPDUs 来遍历 MIB 子树。例如,要从系统中检索接口表,可以使用以下命令:
snmpwalk -c public 10.1.1.21 .1.3.6.1.2.1.2
执行该命令可能会得到如下结果:
interfaces.ifNumber.0 = 2
interfaces.ifTable.ifEntry.ifIndex.1 = 1
interfaces.ifTable.ifEntry.ifIndex.2 = 2
interfaces.ifTable.ifEntry.ifDescr.1 = lo
interfaces.ifTable.ifEntry.ifDescr.2 = eth0
interfaces.ifTable.ifEntry.ifType.1 = softwareLoopback(24)
interfaces.ifTable.ifEntry.ifType.2 = ethernetCsmacd(6)
interfaces.ifTable.ifEntry.ifMtu.1 = 16436
interfaces.ifTable.ifEntry.ifMtu.2 = 1500
interfaces.ifTable.ifEntry.ifSpeed.1 = Gauge32: 10000000
interfaces.ifTable.ifEntry.ifSpeed.2 = Gauge32: 100000000
interfaces.ifTable.ifEntry.ifPhysAddress.1 =
interfaces.ifTable.ifEntry.ifPhysAddress.2 = 0:8:74:93:4d:29
interfaces.ifTable.ifEntry.ifAdminStatus.1 = up(1)
interfaces.ifTable.ifEntry.ifAdminStatus.2 = up(1)
interfaces.ifTable.ifEntry.ifOperStatus.1 = up(1)
interfaces.ifTable.ifEntry.ifOperStatus.2 = up(1)
interfaces.ifTable.ifEntry.ifInOctets.1 = Counter32: 199082
interfaces.ifTable.ifEntry.ifInOctets.2 = Counter32: 291688668
interfaces.ifTable.ifEntry.ifInUcastPkts.1 = Counter32: 3380
interfaces.ifTable.ifEntry.ifInUcastPkts.2 = Counter32: 1579204
interfaces.ifTable.ifEntry.ifInDiscards.1 = Counter32: 0
interfaces.ifTable.ifEntry.ifInDiscards.2 = Counter32: 0
interfaces.ifTable.ifEntry.ifInErrors.1 = Counter32: 0
interfaces.ifTable.ifEntry.ifInErrors.2 = Counter32: 0
interfaces.ifTable.ifEntry.ifOutOctets.1 = Counter32: 199082
interfaces.ifTable.ifEntry.ifOutOctets.2 = Counter32: 61187262
interfaces.ifTable.ifEntry.ifOutUcastPkts.1 = Counter32: 3380
interfaces.ifTable.ifEntry.ifOutUcastPkts.2 = Counter32: 682356
interfaces.ifTable.ifEntry.ifOutDiscards.1 = Counter32: 0
interfaces.ifTable.ifEntry.ifOutDiscards.2 = Counter32: 0
interfaces.ifTable.ifEntry.ifOutErrors.1 = Counter32: 0
interfaces.ifTable.ifEntry.ifOutErrors.2 = Counter32: 0
interfaces.ifTable.ifEntry.ifOutQLen.1 = Gauge32: 0
interfaces.ifTable.ifEntry.ifOutQLen.2 = Gauge32: 0
interfaces.ifTable.ifEntry.ifSpecific.1 = OID: .ccitt.zeroDotZero
interfaces.ifTable.ifEntry.ifSpecific.2 = OID: .ccitt.zeroDotZero
通过这些命令行工具,可以方便地与 SNMP 代理进行交互,获取和修改网络设备的管理信息。
超级会员免费看
11

被折叠的 条评论
为什么被折叠?



