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 ;
62using System . Net ;
73using System . Net . WebSockets ;
84using System . Text ;
95using System . Text . Json ;
106using System . Threading ;
117using System . Threading . Tasks ;
8+ using Protest . Protocols . Snmp ;
9+ using Lextm . SharpSnmpLib ;
10+ using Protest . Http ;
1211
1312namespace 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