Skip to content

Commit a44febc

Browse files
authored
Honor RemotePort for SNMP sessions (#16)
1 parent dc8ded6 commit a44febc

2 files changed

Lines changed: 50 additions & 2 deletions

File tree

netsnmp/client.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,9 @@ def __init__(self, **args):
140140
# check for transports that may be tunneled
141141
transportCheck = re.compile('^(tls|dtls|ssh)');
142142
match = transportCheck.match(sess_args['DestHost'])
143+
peer = sess_args['DestHost']
144+
if not match and sess_args['RemotePort'] != 161:
145+
peer = '{}:{}'.format(peer, sess_args['RemotePort'])
143146

144147
err = None
145148

@@ -163,7 +166,7 @@ def __init__(self, **args):
163166
elif sess_args['Version'] == 3:
164167
self.sess_ptr = client_intf.session_v3(
165168
sess_args['Version'],
166-
sess_args['DestHost'],
169+
peer,
167170
sess_args['LocalPort'],
168171
sess_args['Retries'],
169172
sess_args['Timeout'],
@@ -182,7 +185,7 @@ def __init__(self, **args):
182185
self.sess_ptr = client_intf.session(
183186
sess_args['Version'],
184187
sess_args['Community'],
185-
sess_args['DestHost'],
188+
peer,
186189
sess_args['LocalPort'],
187190
sess_args['Retries'],
188191
sess_args['Timeout'])
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import socket
2+
import unittest
3+
4+
import netsnmp
5+
6+
7+
class RemotePortTests(unittest.TestCase):
8+
def assert_request_received(
9+
self, version, dest_host, use_remote_port=False):
10+
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as listener:
11+
listener.bind(('127.0.0.1', 0))
12+
listener.settimeout(1)
13+
port = listener.getsockname()[1]
14+
session_args = {
15+
'Version': version,
16+
'DestHost': dest_host.format(port=port),
17+
'Community': 'public',
18+
'Timeout': 1000,
19+
'Retries': 0,
20+
}
21+
if use_remote_port:
22+
session_args['RemotePort'] = port
23+
session = netsnmp.Session(**session_args)
24+
varlist = netsnmp.VarList(
25+
netsnmp.Varbind('.1.3.6.1.2.1.1.1', '0'))
26+
27+
session.get(varlist)
28+
request, _ = listener.recvfrom(65535)
29+
self.assertTrue(request)
30+
31+
def test_remote_port_selects_destination_port(self):
32+
for version in (1, 2, 3):
33+
with self.subTest(version=version):
34+
self.assert_request_received(
35+
version, '127.0.0.1', use_remote_port=True)
36+
37+
def test_dest_host_port_remains_supported(self):
38+
for version in (1, 2, 3):
39+
with self.subTest(version=version):
40+
self.assert_request_received(
41+
version, '127.0.0.1:{port}')
42+
43+
44+
if __name__ == '__main__':
45+
unittest.main()

0 commit comments

Comments
 (0)