88namespace Protest . Protocols . Snmp ;
99
1010internal static partial class Polling {
11- public static byte [ ] SwitchInterface ( Dictionary < string , string > parameters ) {
11+
12+ public static byte [ ] GetInterfaces ( Dictionary < string , string > parameters ) {
1213 if ( parameters is null ) { return Data . CODE_INVALID_ARGUMENT . Array ; }
1314
1415 parameters . TryGetValue ( "file" , out string file ) ;
@@ -36,135 +37,143 @@ public static byte[] SwitchInterface(Dictionary<string, string> parameters) {
3637 return Data . CODE_INVALID_ARGUMENT . Array ;
3738 }
3839
39- return SwitchInterface ( _ipAddress , _snmpProfile ) ;
40+ try {
41+ IList < Variable > list = Polling . SnmpQuery ( _ipAddress , _snmpProfile , Oid . SWITCH_OID , Polling . SnmpOperation . Walk ) ;
42+ Dictionary < string , string > parsed = Polling . ParseResponse ( list ) ;
43+ if ( parsed is null ) return "{\" error\" :\" Failed to fetch interfaces\" }"u8 . ToArray ( ) ;
44+
45+ Dictionary < int , string > [ ] dictionaries = ComputeInterface ( list , parsed ) ;
46+
47+ return SwitchInterfaces_LiveStatFormat (
48+ dictionaries [ 0 ] ,
49+ dictionaries [ 1 ] ,
50+ dictionaries [ 2 ] ,
51+ dictionaries [ 3 ] ,
52+ dictionaries [ 4 ] ,
53+ dictionaries [ 5 ] ,
54+ dictionaries [ 6 ]
55+ ) ;
56+ }
57+ catch ( Exception ex ) {
58+ return JsonSerializer . SerializeToUtf8Bytes ( new { error = ex . Message } ) ;
59+ }
4060 }
4161
42- public static byte [ ] SwitchInterface ( IPAddress target , SnmpProfiles . Profile snmpProfile ) {
62+ public static string FetchInterfaces ( System . Net . IPAddress target , SnmpProfiles . Profile snmpProfile ) {
4363 try {
44- IList < Variable > snmpResult = Polling . SnmpQuery ( target , snmpProfile , Oid . SWITCH_OID , Polling . SnmpOperation . Walk ) ;
45- Dictionary < string , string > interfaces = Polling . ParseResponse ( snmpResult ) ;
46-
47- if ( interfaces is null ) return "{\" error\" :\" Failed to fetch interfaces\" }"u8 . ToArray ( ) ;
48-
49- Dictionary < int , string > descriptor = new Dictionary < int , string > ( ) ;
50- Dictionary < int , string > alias = new Dictionary < int , string > ( ) ;
51- Dictionary < int , string > type = new Dictionary < int , string > ( ) ;
52- Dictionary < int , string > speed = new Dictionary < int , string > ( ) ;
53- Dictionary < int , string > untagged = new Dictionary < int , string > ( ) ;
54- Dictionary < int , string > tagged = new Dictionary < int , string > ( ) ;
55-
56- Dictionary < short , List < int > > taggedMap = new Dictionary < short , List < int > > ( ) ;
57- for ( int i = 0 ; i < snmpResult . Count ; i ++ ) {
58- string oid = snmpResult [ i ] . Id . ToString ( ) ;
59- if ( ! oid . StartsWith ( Oid . INTERFACE_1Q_VLAN_ENGRESS ) ) continue ;
60-
61- int dotIndex = oid . LastIndexOf ( '.' ) ;
62- if ( dotIndex == - 1 ) continue ;
63- if ( ! short . TryParse ( oid [ ( dotIndex + 1 ) ..] , out short vlanId ) ) continue ;
64-
65- byte [ ] raw = snmpResult [ i ] . Data . ToBytes ( ) ;
66-
67- int startIndex = GetPortBitmapStart ( raw ) ;
68- if ( startIndex == - 1 ) continue ;
69-
70- int maxIndex = Math . Min ( raw . Length , startIndex + GetPortBitmapLength ( raw , startIndex ) ) ;
71-
72- for ( int j = startIndex ; j < maxIndex ; j ++ ) {
73- byte b = raw [ j ] ;
74- for ( int k = 0 ; k < 8 ; k ++ ) {
75- if ( ( b & ( 1 << ( 7 - k ) ) ) == 0 ) continue ;
76-
77- int portIndex = 8 * ( j - startIndex ) + ( k + 1 ) ;
78- if ( ! taggedMap . TryGetValue ( vlanId , out var ports ) ) {
79- ports = new List < int > ( ) ;
80- taggedMap [ vlanId ] = ports ;
81- }
82- if ( ! ports . Contains ( portIndex ) ) {
83- ports . Add ( portIndex ) ;
64+ IList < Variable > list = Polling . SnmpQuery ( target , snmpProfile , Oid . SWITCH_OID , Polling . SnmpOperation . Walk ) ;
65+ Dictionary < string , string > parsed = Polling . ParseResponse ( list ) ;
66+ if ( parsed is null ) return null ;
67+
68+ Dictionary < int , string > [ ] dictionaries = ComputeInterface ( list , parsed ) ;
69+
70+ return SwitchInterfaces_FetchFormat (
71+ dictionaries [ 0 ] ,
72+ dictionaries [ 1 ] ,
73+ dictionaries [ 2 ] ,
74+ dictionaries [ 3 ] ,
75+ dictionaries [ 4 ] ,
76+ dictionaries [ 5 ] ,
77+ dictionaries [ 6 ]
78+ ) ;
79+ }
80+ catch {
81+ return null ;
82+ }
83+ }
84+
85+
86+
87+ private static Dictionary < int , string > [ ] ComputeInterface ( IList < Variable > list , Dictionary < string , string > parsed ) {
88+ Dictionary < int , string > descriptor = new Dictionary < int , string > ( ) ;
89+ Dictionary < int , string > alias = new Dictionary < int , string > ( ) ;
90+ Dictionary < int , string > type = new Dictionary < int , string > ( ) ;
91+ Dictionary < int , string > speed = new Dictionary < int , string > ( ) ;
92+ Dictionary < int , string > untagged = new Dictionary < int , string > ( ) ;
93+ Dictionary < int , string > tagged = new Dictionary < int , string > ( ) ;
94+
95+ Dictionary < short , List < int > > taggedMap = new Dictionary < short , List < int > > ( ) ;
96+ for ( int i = 0 ; i < list . Count ; i ++ ) {
97+ string oid = list [ i ] . Id . ToString ( ) ;
98+ if ( ! oid . StartsWith ( Oid . INTERFACE_1Q_VLAN_ENGRESS ) ) continue ;
99+
100+ int dotIndex = oid . LastIndexOf ( '.' ) ;
101+ if ( dotIndex == - 1 ) continue ;
102+ if ( ! short . TryParse ( oid [ ( dotIndex + 1 ) ..] , out short vlanId ) ) continue ;
103+
104+ byte [ ] raw = list [ i ] . Data . ToBytes ( ) ;
105+
106+ int startIndex = GetPortBitmapStart ( raw ) ;
107+ if ( startIndex == - 1 ) continue ;
108+
109+ int maxIndex = Math . Min ( raw . Length , startIndex + GetPortBitmapLength ( raw , startIndex ) ) ;
110+
111+ for ( int j = startIndex ; j < maxIndex ; j ++ ) {
112+ byte b = raw [ j ] ;
113+ for ( int k = 0 ; k < 8 ; k ++ ) {
114+ if ( ( b & ( 1 << ( 7 - k ) ) ) == 0 ) continue ;
115+
116+ int portIndex = 8 * ( j - startIndex ) + ( k + 1 ) ;
117+ if ( ! taggedMap . TryGetValue ( vlanId , out var ports ) ) {
118+ ports = new List < int > ( ) ;
119+ taggedMap [ vlanId ] = ports ;
84120 }
121+ if ( ! ports . Contains ( portIndex ) ) {
122+ ports . Add ( portIndex ) ;
85123 }
86124 }
87125 }
88- foreach ( KeyValuePair < short , List < int > > pair in taggedMap ) {
89- foreach ( int port in pair . Value ) {
90- tagged . TryGetValue ( port , out var existing ) ;
91- tagged [ port ] = string . IsNullOrEmpty ( existing ) ? pair . Key . ToString ( ) : $ " { existing } , { pair . Key . ToString ( ) } " ;
92- }
126+ }
127+ foreach ( KeyValuePair < short , List < int > > pair in taggedMap ) {
128+ foreach ( int port in pair . Value ) {
129+ tagged . TryGetValue ( port , out var existing ) ;
130+ tagged [ port ] = string . IsNullOrEmpty ( existing ) ? pair . Key . ToString ( ) : $ " { existing } , { pair . Key . ToString ( ) } " ;
93131 }
132+ }
94133
95- Dictionary < int , string > macTable = new Dictionary < int , string > ( ) ;
96- foreach ( KeyValuePair < string , string > pair in interfaces ) {
97- if ( ! pair . Key . StartsWith ( Oid . INTERFACE_1D_TP_FDB ) ) continue ;
98- if ( ! int . TryParse ( pair . Value , out int port ) ) continue ;
99- string mac = String . Join ( String . Empty , pair . Key . Split ( '.' ) . TakeLast ( 6 ) . Select ( o=> int . Parse ( o ) . ToString ( "x2" ) ) ) ;
134+ Dictionary < int , string > macTable = new Dictionary < int , string > ( ) ;
135+ foreach ( KeyValuePair < string , string > pair in parsed ) {
136+ if ( ! pair . Key . StartsWith ( Oid . INTERFACE_1D_TP_FDB ) ) continue ;
137+ if ( ! int . TryParse ( pair . Value , out int port ) ) continue ;
138+ string mac = String . Join ( String . Empty , pair . Key . Split ( '.' ) . TakeLast ( 6 ) . Select ( o=> int . Parse ( o ) . ToString ( "x2" ) ) ) ;
100139
101- if ( macTable . ContainsKey ( port ) ) {
102- macTable [ port ] = null ;
103- }
104- else {
105- macTable . Add ( port , mac ) ;
106- }
140+ if ( macTable . ContainsKey ( port ) ) {
141+ macTable [ port ] = null ;
107142 }
143+ else {
144+ macTable . Add ( port , mac ) ;
145+ }
146+ }
108147
109- foreach ( KeyValuePair < string , string > pair in interfaces ) {
110- int index = int . Parse ( pair . Key . Split ( '.' ) [ ^ 1 ] ) ;
148+ foreach ( KeyValuePair < string , string > pair in parsed ) {
149+ int index = int . Parse ( pair . Key . Split ( '.' ) [ ^ 1 ] ) ;
111150
112- if ( pair . Key . StartsWith ( Oid . INTERFACE_DESCRIPTOR ) ) {
113- descriptor . Add ( index , pair . Value ) ;
114- }
115- else if ( pair . Key . StartsWith ( Oid . INTERFACE_ALIAS ) ) {
116- alias . Add ( index , pair . Value ) ;
117- }
118- else if ( pair . Key . StartsWith ( Oid . INTERFACE_TYPE ) ) {
119- type . Add ( index , pair . Value ) ;
120- }
121- else if ( pair . Key . StartsWith ( Oid . INTERFACE_SPEED ) ) {
122- speed . Add ( index , pair . Value ) ;
123- }
124- else if ( pair . Key . StartsWith ( Oid . INTERFACE_1Q_VLAN ) ) {
125- untagged . Add ( index , pair . Value ) ;
126- }
151+ if ( pair . Key . StartsWith ( Oid . INTERFACE_DESCRIPTOR ) ) {
152+ descriptor . Add ( index , pair . Value ) ;
153+ }
154+ else if ( pair . Key . StartsWith ( Oid . INTERFACE_ALIAS ) ) {
155+ alias . Add ( index , pair . Value ) ;
156+ }
157+ else if ( pair . Key . StartsWith ( Oid . INTERFACE_TYPE ) ) {
158+ type . Add ( index , pair . Value ) ;
159+ }
160+ else if ( pair . Key . StartsWith ( Oid . INTERFACE_SPEED ) ) {
161+ speed . Add ( index , pair . Value ) ;
162+ }
163+ else if ( pair . Key . StartsWith ( Oid . INTERFACE_1Q_VLAN ) ) {
164+ untagged . Add ( index , pair . Value ) ;
127165 }
128-
129- return JsonSerializer . SerializeToUtf8Bytes (
130- type . Where ( o => o . Value == "6" )
131- . Select ( pair => new {
132- number = descriptor . GetValueOrDefault ( pair . Key , null ) ,
133- port = speed . GetValueOrDefault ( pair . Key , "N/A" ) switch {
134- "10000" => "SFP+" ,
135- "25000" => "SFP+" ,
136- "40000" => "QSFP" ,
137- "100000" => "QSFP" ,
138- "200000" => "QSFP" ,
139- "400000" => "QSFP" ,
140- "800000" => "QSFP" ,
141- _ => "Ethernet"
142- } ,
143- speed = speed . GetValueOrDefault ( pair . Key , "N/A" ) switch {
144- "10" => "10 Mbps" ,
145- "100" => "100 Mbps" ,
146- "1000" => "1 Gbps" ,
147- "2500" => "2.5 Gbps" ,
148- "5000" => "5 Gbps" ,
149- "10000" => "10 Gbps" ,
150- "25000" => "25 Gbps" ,
151- "40000" => "40 Gbps" ,
152- "100000" => "100 Gbps" ,
153- "200000" => "200 Gbps" ,
154- "400000" => "400 Gbps" ,
155- "800000" => "800 Gbps" ,
156- _ => "N/A"
157- } ,
158- untagged = untagged . GetValueOrDefault ( pair . Key , "" ) ,
159- tagged = tagged . GetValueOrDefault ( pair . Key , "" ) ,
160- comment = alias . GetValueOrDefault ( pair . Key , String . Empty ) ,
161- link = DatabaseInstances . FindDeviceByMac ( macTable . GetValueOrDefault ( pair . Key , null ) ) ,
162- } )
163- ) ;
164- }
165- catch ( Exception ex ) {
166- return JsonSerializer . SerializeToUtf8Bytes ( new { error = ex . Message } ) ;
167166 }
167+
168+ return new Dictionary < int , string > [ ] {
169+ type ,
170+ descriptor ,
171+ speed ,
172+ untagged ,
173+ tagged ,
174+ alias ,
175+ macTable
176+ } ;
168177 }
169178
170179 internal static int GetPortBitmapStart ( byte [ ] raw ) {
@@ -182,4 +191,97 @@ internal static int GetPortBitmapLength(byte[] raw, int startIndex) {
182191 return raw . Length - startIndex ;
183192 }
184193
194+ private static byte [ ] SwitchInterfaces_LiveStatFormat (
195+ Dictionary < int , string > type ,
196+ Dictionary < int , string > descriptor ,
197+ Dictionary < int , string > speed ,
198+ Dictionary < int , string > untagged ,
199+ Dictionary < int , string > tagged ,
200+ Dictionary < int , string > alias ,
201+ Dictionary < int , string > macTable ) {
202+
203+ return JsonSerializer . SerializeToUtf8Bytes (
204+ type . Where ( o => o . Value == "6" )
205+ . Select ( pair => new {
206+ number = descriptor . GetValueOrDefault ( pair . Key , null ) ,
207+ port = speed . GetValueOrDefault ( pair . Key , "N/A" ) switch {
208+ "10000" => "SFP+" ,
209+ "25000" => "SFP+" ,
210+ "40000" => "QSFP" ,
211+ "100000" => "QSFP" ,
212+ "200000" => "QSFP" ,
213+ "400000" => "QSFP" ,
214+ "800000" => "QSFP" ,
215+ _ => "Ethernet"
216+ } ,
217+ speed = speed . GetValueOrDefault ( pair . Key , "N/A" ) switch {
218+ "10" => "10 Mbps" ,
219+ "100" => "100 Mbps" ,
220+ "1000" => "1 Gbps" ,
221+ "2500" => "2.5 Gbps" ,
222+ "5000" => "5 Gbps" ,
223+ "10000" => "10 Gbps" ,
224+ "25000" => "25 Gbps" ,
225+ "40000" => "40 Gbps" ,
226+ "100000" => "100 Gbps" ,
227+ "200000" => "200 Gbps" ,
228+ "400000" => "400 Gbps" ,
229+ "800000" => "800 Gbps" ,
230+ _ => "N/A"
231+ } ,
232+ untagged = untagged . GetValueOrDefault ( pair . Key , "" ) ,
233+ tagged = tagged . GetValueOrDefault ( pair . Key , "" ) ,
234+ comment = alias . GetValueOrDefault ( pair . Key , String . Empty ) ,
235+ link = DatabaseInstances . FindDeviceByMac ( macTable . GetValueOrDefault ( pair . Key , null ) ) ,
236+ } )
237+ ) ;
238+ }
239+
240+ private static string SwitchInterfaces_FetchFormat (
241+ Dictionary < int , string > type ,
242+ Dictionary < int , string > descriptor ,
243+ Dictionary < int , string > speed ,
244+ Dictionary < int , string > untagged ,
245+ Dictionary < int , string > tagged ,
246+ Dictionary < int , string > alias ,
247+ Dictionary < int , string > macTable ) {
248+
249+ return JsonSerializer . Serialize ( new {
250+ i = type . Where ( o => o . Value == "6" )
251+ . Select ( pair => new {
252+ n = descriptor . GetValueOrDefault ( pair . Key , null ) ,
253+ i = speed . GetValueOrDefault ( pair . Key , "N/A" ) switch {
254+ "10000" => "SFP+" ,
255+ "25000" => "SFP+" ,
256+ "40000" => "QSFP" ,
257+ "100000" => "QSFP" ,
258+ "200000" => "QSFP" ,
259+ "400000" => "QSFP" ,
260+ "800000" => "QSFP" ,
261+ _ => "Ethernet"
262+ } ,
263+ s = speed . GetValueOrDefault ( pair . Key , "N/A" ) switch {
264+ "10" => "10 Mbps" ,
265+ "100" => "100 Mbps" ,
266+ "1000" => "1 Gbps" ,
267+ "2500" => "2.5 Gbps" ,
268+ "5000" => "5 Gbps" ,
269+ "10000" => "10 Gbps" ,
270+ "25000" => "25 Gbps" ,
271+ "40000" => "40 Gbps" ,
272+ "100000" => "100 Gbps" ,
273+ "200000" => "200 Gbps" ,
274+ "400000" => "400 Gbps" ,
275+ "800000" => "800 Gbps" ,
276+ _ => "N/A"
277+ } ,
278+ v = untagged . GetValueOrDefault ( pair . Key , "" ) ,
279+ t = tagged . GetValueOrDefault ( pair . Key , "" ) ,
280+ c = alias . GetValueOrDefault ( pair . Key , String . Empty ) ,
281+ l = DatabaseInstances . FindDeviceByMac ( macTable . GetValueOrDefault ( pair . Key , null ) ) ,
282+ } ) ,
283+ n = "horizontal"
284+ } ) ;
285+ }
286+
185287}
0 commit comments