參考的網址如下:
http://www.chu.edu.tw/~hsiang/91_Class/NM2.ppt
符合 BER 格式的封包內容像這樣 ... (這算是補充 PTT 沒有的部份)
底下就是一份實作的範例
snmptrap.tcl
# Snmptrap 封包內容共三段
# Version + Community + Data(SNMP Protocol Data Unit (SNMP PDU))
#
# ------------------------------------
# |Type
# ------------------------------------
# Version |INTEGER {version-1(0)}
# Community |OCTET STRING
# Data |ANY (Sequence)
# ------------------------------------
#
#
# 其中 Data 又分為兩段
# PDU Header + PDU Data
#
#
# PDU Header 又分五段
# Enterprise + Agent address + Generic trap type + Specific trap code + Time stamp
#
# Enterprise—Identifies the type of managed object that generates the trap.
# Agent address—Provides the address of the managed object that generates the trap.
# Generic trap type—Indicates one of a number of generic trap types.
# Specific trap code—Indicates one of a number of specific trap codes.
# Time stamp—Provides the amount of time that has elapsed between the last network reinitialization and generation of the trap.
#
# ------------------------------------
# |Type
# ------------------------------------
# Enterprise |ObjectIdentifier
# Agent address |Hex
# Generic trap type |INTEGER
# Specific trap code |INTEGER
# Time stamp |IntegerOrEnum
# ------------------------------------
#
#
#
# PDU Data 為一份序列(Sequence),序列內容可以包含一個以上的序列,結構如下
# [[OID + Value][OID + Value][OID + Value] ... [OID + Value]]
#
# ------------------------
# For demo send trap ...
# ----------------------
# import package
# ----------------------
package require asn
package require udp
package require ip
# -------------------------
# utility procedures
# -------------------------
# Figure out what this machine's IP address is.
# Refernce http://wiki.tcl.tk/3015 to rewrite this proc
proc myip {} {
set myip "127.0.0.1"
switch $::tcl_platform(platform) {
unix {
set buffer [exec /sbin/ifconfig]
set scan "inet addr:"
foreach line [split $buffer \n] {
if ![regexp $scan $line] continue
set s [expr [string first $scan $line 0] + [string length $scan]]
set f [expr [string first " " $line $s] - 1]
set addr [string range $line $s $f]
if { $addr != "127.0.0.1" } {
set myip $addr
break
}
}
}
windows {
catch { exec ipconfig } data
set buffer [split $data \n]
foreach line $buffer {
if [regexp -nocase {IP Address} $line] {
set myip [string trim [lindex [split $line :] end]]
break
}
}
}
}
return $myip
}
proc myHexIP {} {
return [string range [ip::toHex [myip]] 2 end]
}
proc send_trap {args} {
# ---------------------
# Configuration
# ---------------------
# send trap to ... ?
set server 127.0.0.1
set port 162
# 0 | 1
set version 0
# public | password
set community public
# 1.3.6.1.4.1.23041
set enterprise "1 3 6 1 4 1 23041"
set agent_address [myHexIP]
set generic_trap_type 6
set specific_trap_code 0
# --------------------------------
# start for encoding
set timestamp [clock second]
# Version
set packet [asn::asnInteger $version]
# Version + Community
append packet [asn::asnOctetString $community]
# PDU Header = Enterprise + Agent address + Generic trap type + Specific trap code + Time stamp
set PDU_Header [asn::asnObjectIdentifier $enterprise]
append PDU_Header [binary format H* "4004$agent_address"]
append PDU_Header [asn::asnInteger $generic_trap_type]
append PDU_Header [asn::asnInteger $specific_trap_code]
append PDU_Header [asn::asnIntegerOrEnum 43 [expr ([clock seconds] - $timestamp) * 100]]
# PDU Data = [[OID + Value][OID + Value][OID + Value] ... [OID + Value]]
set PDU_Data ""
foreach {OID value} $args {
set sequence [asn::asnObjectIdentifier $OID]
append sequence [asn::asnOctetString [encoding convertto $value]]
# 將 OID + Value 編成一個序列
set sequence [asn::asnSequence $sequence]
# 放入 PDU_Data 主序列中
append PDU_Data $sequence
}
# 把 PDU_Data 正式編成一個序列
set PDU_Data [asn::asnSequence $PDU_Data]
# SNMP PDU = PDU Header + PDU Data
set SNMP_PDU [format {%s%s} $PDU_Header $PDU_Data]
# OCTET STRING (0x04)
set SNMP_PDU [asn::asnChoiceConstr 4 $SNMP_PDU]
# Version + Community + Data(SNMP Protocol Data Unit (SNMP PDU))
append packet $SNMP_PDU
# 把 packet 正式編成一個序列
set packet [asn::asnSequence $packet]
# 發送 trap / udp
set s [udp_open]
fconfigure $s -blocking 0 -remote [list $server $port] -translation binary -encoding binary
puts -nonewline $s $packet
flush $s
close $s
}
# Version + Community + Data(SNMP Protocol Data Unit (SNMP PDU))
#
# ------------------------------------
# |Type
# ------------------------------------
# Version |INTEGER {version-1(0)}
# Community |OCTET STRING
# Data |ANY (Sequence)
# ------------------------------------
#
#
# 其中 Data 又分為兩段
# PDU Header + PDU Data
#
#
# PDU Header 又分五段
# Enterprise + Agent address + Generic trap type + Specific trap code + Time stamp
#
# Enterprise—Identifies the type of managed object that generates the trap.
# Agent address—Provides the address of the managed object that generates the trap.
# Generic trap type—Indicates one of a number of generic trap types.
# Specific trap code—Indicates one of a number of specific trap codes.
# Time stamp—Provides the amount of time that has elapsed between the last network reinitialization and generation of the trap.
#
# ------------------------------------
# |Type
# ------------------------------------
# Enterprise |ObjectIdentifier
# Agent address |Hex
# Generic trap type |INTEGER
# Specific trap code |INTEGER
# Time stamp |IntegerOrEnum
# ------------------------------------
#
#
#
# PDU Data 為一份序列(Sequence),序列內容可以包含一個以上的序列,結構如下
# [[OID + Value][OID + Value][OID + Value] ... [OID + Value]]
#
# ------------------------
# For demo send trap ...
# ----------------------
# import package
# ----------------------
package require asn
package require udp
package require ip
# -------------------------
# utility procedures
# -------------------------
# Figure out what this machine's IP address is.
# Refernce http://wiki.tcl.tk/3015 to rewrite this proc
proc myip {} {
set myip "127.0.0.1"
switch $::tcl_platform(platform) {
unix {
set buffer [exec /sbin/ifconfig]
set scan "inet addr:"
foreach line [split $buffer \n] {
if ![regexp $scan $line] continue
set s [expr [string first $scan $line 0] + [string length $scan]]
set f [expr [string first " " $line $s] - 1]
set addr [string range $line $s $f]
if { $addr != "127.0.0.1" } {
set myip $addr
break
}
}
}
windows {
catch { exec ipconfig } data
set buffer [split $data \n]
foreach line $buffer {
if [regexp -nocase {IP Address} $line] {
set myip [string trim [lindex [split $line :] end]]
break
}
}
}
}
return $myip
}
proc myHexIP {} {
return [string range [ip::toHex [myip]] 2 end]
}
proc send_trap {args} {
# ---------------------
# Configuration
# ---------------------
# send trap to ... ?
set server 127.0.0.1
set port 162
# 0 | 1
set version 0
# public | password
set community public
# 1.3.6.1.4.1.23041
set enterprise "1 3 6 1 4 1 23041"
set agent_address [myHexIP]
set generic_trap_type 6
set specific_trap_code 0
# --------------------------------
# start for encoding
set timestamp [clock second]
# Version
set packet [asn::asnInteger $version]
# Version + Community
append packet [asn::asnOctetString $community]
# PDU Header = Enterprise + Agent address + Generic trap type + Specific trap code + Time stamp
set PDU_Header [asn::asnObjectIdentifier $enterprise]
append PDU_Header [binary format H* "4004$agent_address"]
append PDU_Header [asn::asnInteger $generic_trap_type]
append PDU_Header [asn::asnInteger $specific_trap_code]
append PDU_Header [asn::asnIntegerOrEnum 43 [expr ([clock seconds] - $timestamp) * 100]]
# PDU Data = [[OID + Value][OID + Value][OID + Value] ... [OID + Value]]
set PDU_Data ""
foreach {OID value} $args {
set sequence [asn::asnObjectIdentifier $OID]
append sequence [asn::asnOctetString [encoding convertto $value]]
# 將 OID + Value 編成一個序列
set sequence [asn::asnSequence $sequence]
# 放入 PDU_Data 主序列中
append PDU_Data $sequence
}
# 把 PDU_Data 正式編成一個序列
set PDU_Data [asn::asnSequence $PDU_Data]
# SNMP PDU = PDU Header + PDU Data
set SNMP_PDU [format {%s%s} $PDU_Header $PDU_Data]
# OCTET STRING (0x04)
set SNMP_PDU [asn::asnChoiceConstr 4 $SNMP_PDU]
# Version + Community + Data(SNMP Protocol Data Unit (SNMP PDU))
append packet $SNMP_PDU
# 把 packet 正式編成一個序列
set packet [asn::asnSequence $packet]
# 發送 trap / udp
set s [udp_open]
fconfigure $s -blocking 0 -remote [list $server $port] -translation binary -encoding binary
puts -nonewline $s $packet
flush $s
close $s
}
接下來只要利用 send_trap 這個 proc 並傳兩個參數(OID、value),就可以打開接收器看成果了!
沒有留言:
張貼留言