Luciano
Luciano

Reputation: 1601

Powershell SNMP converting IP Address: Getting wrong value

How do I properly convert an IP Address gotten via OleSNMP to a useable value?

I'm trying to write a Powershell script to query devices with SNMP and then display the data. Stuff works fine for simple types, but I'm having problems with the IP Addresses (and MAC addresses, but let's stick to IP for now)

Here's what I have (simplified to the problem space):

param ($ipaddr='10.1.128.114', $community='Public')

$snmp = New-Object -ComObject oleprn.OleSNMP
$snmp.open($ipaddr, $community)

$result = $snmp.get(".1.3.6.1.2.1.4.20.1.1.10.1.128.114")
$enc = [system.Text.Encoding]::ASCII
$bytes = $enc.GetBytes($result)
write-host( "bytes:" + $bytes)

Which outputs:

bytes:10 1 63 114

When I expected

bytes:10 1 128 114

For contrast, the snmp-get outputs:

$ snmpget 10.1.128.114 -c Public -v2c -On .1.3.6.1.2.1.4.20.1.1.10.1.128.114
.1.3.6.1.2.1.4.20.1.1.10.1.128.114 = IpAddress: 10.1.128.114

And yes, I realize that in my final script I'll have to walk the table instead of using a direct "get" but I need to fix my parsing first.

Upvotes: 1

Views: 629

Answers (1)

mclayton
mclayton

Reputation: 9975

As mentioned in the comments, the ASCII encoding substitutes characters outside its valid range with a question mark ?, which is ASCII character 63.

More info is available in the documentation for ASCIIEncoding.GetBytes - search for "?" and you'll find this:

ASCIIEncoding does not provide error detection. Any Unicode character greater than U+007F is encoded as the ASCII question mark ("?").

Note, 0x7F is 127, so since [char] 128 is outside this range, it's being converted to the byte equivalent of ? (which is 63) when you call GetBytes.

Your code is basically doing this this:

$result = ([char] 10) + ([char] 1) + ([char] 128) + ([char] 114)

$encoding = [System.Text.Encoding]::ASCII
$bytes = $encoding.GetBytes($result)
$bytes
# 10
# 1
# 63 (i.e. "?")
# 114

You need to use an encoder which will convert characters higher than 0x7F into the equivalent bytes - something like iso-8859-1 seems to work:

$result = ([char] 10) + ([char] 1) + ([char] 128) + ([char] 114)

$encoding = [System.Text.Encoding]::GetEncoding("iso-8859-1")
$bytes = $encoding.GetBytes($result)
$bytes
# 10
# 1
# 128
# 114

Upvotes: 2

Related Questions