Skip to content

Commit a834758

Browse files
committed
Topology, SNMP
1 parent 4a27852 commit a834758

File tree

4 files changed

+100
-46
lines changed

4 files changed

+100
-46
lines changed

Protest/Front/topology.css

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@
2424
display: grid;
2525

2626
grid-template-columns: 88px auto;
27-
grid-template-rows: 16px 16px 16px 16px;
27+
grid-template-rows: 12px 20px 20px 12px;
28+
-webkit-user-select: text; user-select: text;
2829
}
2930

3031
.topology-device {

Protest/Front/topology.js

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -334,11 +334,8 @@ class Topology extends Window {
334334

335335
const ipLabel = document.createElement("div");
336336
ipLabel.style.gridArea = "3 / 2";
337-
ipLabel.style.fontWeight = "bold";
338337
ipLabel.textContent = initial.ip;
339338
grid.appendChild(ipLabel);
340-
341-
342339
}
343340

344341
}

Protest/Protocols/Snmp.Oid.cs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,6 @@ internal static class Oid {
6464
INTERFACE_ERROR_OUT,
6565
};
6666

67-
public static string[] TOPOLOGY_SWITCH_OID = new string[] {
68-
LLDP_LOCAL_SYS_DATA,
69-
LLDP_REMOTE_SYS_DATA,
70-
};
7167

7268
public const string LLDP_LOCAL_SYS_DATA = "1.0.8802.1.1.2.1.3";
7369
public const string LLDP_REMOTE_SYS_DATA = "1.0.8802.1.1.2.1.4";

Protest/Tools/Topology.cs

Lines changed: 98 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
1-
using Lextm.SharpSnmpLib;
2-
using Org.BouncyCastle.Asn1.X509;
3-
using Protest.Http;
4-
using Protest.Protocols.Snmp;
5-
using System.Collections.Generic;
1+
using System.Collections.Generic;
62
using System.Net;
73
using System.Net.WebSockets;
84
using System.Text;
95
using System.Text.Json;
106
using System.Threading;
117
using System.Threading.Tasks;
8+
using Protest.Protocols.Snmp;
9+
using Lextm.SharpSnmpLib;
10+
using Protest.Http;
1211

1312
namespace Protest.Tools;
1413

@@ -68,45 +67,106 @@ internal static async void WebSocketHandler(HttpListenerContext ctx) {
6867
candidates.Add(device);
6968
}
7069

71-
byte[] message = JsonSerializer.SerializeToUtf8Bytes( new {
72-
initial = candidates.Select(device => new {
73-
file = device.filename,
74-
type = device.attributes.TryGetValue("type", out Database.Attribute typeAttr) ? typeAttr.value : "N/A",
75-
ip = device.attributes.TryGetValue("ip", out Database.Attribute ipAttr) ? ipAttr.value : "N/A",
76-
hostname = device.attributes.TryGetValue("hostname", out Database.Attribute hostnameAttr) ? hostnameAttr.value : "N/A",
77-
})
78-
});
79-
80-
await WsWriteText(ws, message);
81-
82-
for (int i = 0; i < candidates.Count; i++) {
83-
if (!candidates[i].attributes.TryGetValue("ip", out Database.Attribute ipAttr)) continue;
84-
if (!candidates[i].attributes.TryGetValue("snmp profile", out Database.Attribute profileAttr)) continue;
85-
if (!SnmpProfiles.FromGuid(profileAttr.value, out SnmpProfiles.Profile snmpProfile) || snmpProfile is null) continue;
86-
87-
string ipString = ipAttr.value.Split(";")[0].Trim();
88-
if (IPAddress.TryParse(ipString, out IPAddress ipAddress)) {
89-
await WsWriteText(ws, System.Text.Encoding.UTF8.GetBytes($"{{\"retrieve\":\"{candidates[i].filename}\"}}"));
90-
91-
Dictionary<string, string> response = SnmpRequest(ipAddress, snmpProfile);
92-
93-
if (response is null || response.Count == 0) {
94-
await WsWriteText(ws, System.Text.Encoding.UTF8.GetBytes($"{{\"nosnmp\":\"{candidates[i].filename}\"}}"));
95-
}
96-
else {
97-
await WsWriteText(ws, System.Text.Encoding.UTF8.GetBytes($"{{\"snmp\":\"{candidates[i].filename}\"}}"));
70+
try {
71+
byte[] message = JsonSerializer.SerializeToUtf8Bytes(new {
72+
initial = candidates.Select(device => new {
73+
file = device.filename,
74+
type = device.attributes.TryGetValue("type", out Database.Attribute typeAttr) ? typeAttr.value : "N/A",
75+
ip = device.attributes.TryGetValue("ip", out Database.Attribute ipAttr) ? ipAttr.value : "N/A",
76+
hostname = device.attributes.TryGetValue("hostname", out Database.Attribute hostnameAttr) ? hostnameAttr.value : "N/A",
77+
//location = device.attributes.TryGetValue("location", out Database.Attribute locationAttr) ? locationAttr.value : "N/A",
78+
})
79+
});
80+
81+
await WsWriteText(ws, message);
82+
83+
for (int i = 0; i < candidates.Count; i++) {
84+
if (!candidates[i].attributes.TryGetValue("ip", out Database.Attribute ipAttr)) continue;
85+
if (!candidates[i].attributes.TryGetValue("snmp profile", out Database.Attribute profileAttr)) continue;
86+
if (!SnmpProfiles.FromGuid(profileAttr.value, out SnmpProfiles.Profile snmpProfile) || snmpProfile is null) continue;
87+
88+
string ipString = ipAttr.value.Split(";")[0].Trim();
89+
if (IPAddress.TryParse(ipString, out IPAddress ipAddress)) {
90+
await WsWriteText(ws, System.Text.Encoding.UTF8.GetBytes($"{{\"retrieve\":\"{candidates[i].filename}\"}}"));
91+
92+
Dictionary<string, string> local = Polling.ParseResponse(
93+
Polling.SnmpQuery(ipAddress, snmpProfile, [Oid.LLDP_LOCAL_SYS_DATA], Polling.SnmpOperation.Walk)
94+
);
95+
96+
Dictionary<string, string> remote = Polling.ParseResponse(
97+
Polling.SnmpQuery(ipAddress, snmpProfile, [Oid.LLDP_REMOTE_SYS_DATA], Polling.SnmpOperation.Walk)
98+
);
99+
100+
if (local is null || local.Count == 0 || remote is null || remote.Count == 0) {
101+
await WsWriteText(ws, System.Text.Encoding.UTF8.GetBytes($"{{\"nosnmp\":\"{candidates[i].filename}\"}}"));
102+
}
103+
else {
104+
byte[] response = ComputeSnmpResponse(candidates[i].filename, local, remote);
105+
await WsWriteText(ws, response);
106+
}
98107
}
99108
}
100-
}
101109

102-
await ws.CloseAsync(WebSocketCloseStatus.NormalClosure, String.Empty, CancellationToken.None);
110+
await ws.CloseAsync(WebSocketCloseStatus.NormalClosure, String.Empty, CancellationToken.None);
111+
}
112+
catch (WebSocketException ex) when (ex.WebSocketErrorCode == WebSocketError.ConnectionClosedPrematurely) {
113+
return;
114+
}
115+
catch (WebSocketException ex) when (ex.WebSocketErrorCode != WebSocketError.ConnectionClosedPrematurely) {
116+
//do nothing
117+
}
118+
catch (Exception ex) {
119+
Logger.Error(ex);
120+
}
103121
}
104122

105-
private static Dictionary<string, string> SnmpRequest(System.Net.IPAddress target, SnmpProfiles.Profile snmpProfile) {
106-
IList<Variable> list = Polling.SnmpQuery(target, snmpProfile, Oid.TOPOLOGY_SWITCH_OID, Polling.SnmpOperation.Walk);
107-
Dictionary<string, string> parsed = Polling.ParseResponse(list);
123+
private static byte[] ComputeSnmpResponse(string file, Dictionary<string, string> local, Dictionary<string, string> remote) {
124+
local.TryGetValue("1.0.8802.1.1.2.1.3.1.0", out string idSuptype);
125+
local.TryGetValue("1.0.8802.1.1.2.1.3.2.0", out string id);
126+
local.TryGetValue("1.0.8802.1.1.2.1.3.3.0", out string hostname);
127+
local.TryGetValue("1.0.8802.1.1.2.1.3.4.0", out string description);
128+
129+
Dictionary<int, string> localPortIdSuptype = new Dictionary<int, string>();
130+
Dictionary<int, string> localPortId = new Dictionary<int, string>();
131+
132+
Dictionary<int, string> remoteChassisIdSuptype = new Dictionary<int, string>();
133+
Dictionary<int, string> remoteChassisId = new Dictionary<int, string>();
134+
Dictionary<int, string> remotePortIdSuptype = new Dictionary<int, string>();
135+
Dictionary<int, string> remotePortId = new Dictionary<int, string>();
136+
Dictionary<int, string> remoteSystemName = new Dictionary<int, string>();
137+
138+
foreach (KeyValuePair<string, string> pair in local) {
139+
if (!int.TryParse(pair.Key.Split('.')[^1], out int index)) continue;
140+
141+
if (pair.Key.StartsWith("1.0.8802.1.1.2.1.3.7.1.2")) {
142+
localPortIdSuptype.Add(index, pair.Value);
143+
}
144+
else if (pair.Key.StartsWith("1.0.8802.1.1.2.1.3.7.1.3")) {
145+
localPortId.Add(index, pair.Value);
146+
}
147+
}
148+
149+
foreach (KeyValuePair<string, string> pair in remote) {
150+
if (!int.TryParse(pair.Key.Split('.')[^1], out int index)) continue;
151+
152+
if (pair.Key.StartsWith("1.0.8802.1.1.2.1.4.1.1.4")) {
153+
remoteChassisIdSuptype.Add(index, pair.Value);
154+
}
155+
else if (pair.Key.StartsWith("1.0.8802.1.1.2.1.4.1.1.5")) {
156+
remoteChassisId.Add(index, pair.Value);
157+
}
158+
if (pair.Key.StartsWith("1.0.8802.1.1.2.1.4.1.1.6")) {
159+
remotePortIdSuptype.Add(index, pair.Value);
160+
}
161+
else if (pair.Key.StartsWith("1.0.8802.1.1.2.1.4.1.1.7")) {
162+
remotePortId.Add(index, pair.Value);
163+
}
164+
else if (pair.Key.StartsWith("1.0.8802.1.1.2.1.4.1.1.9")) {
165+
remoteSystemName.Add(index, pair.Value);
166+
}
167+
}
108168

109-
return parsed;
169+
return null;
110170
}
111171

112172
}

0 commit comments

Comments
 (0)