ciscollm-cli 1.2.0 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -21
- package/README.md +242 -242
- package/dist/core/agent/AgentLoop.js +1 -0
- package/dist/core/agent/AgentLoop.js.map +1 -1
- package/dist/core/agent/AutoHealer.js +23 -23
- package/dist/core/agent/HierarchicalAgentManager.d.ts +1 -1
- package/dist/core/agent/HierarchicalAgentManager.js +21 -5
- package/dist/core/agent/HierarchicalAgentManager.js.map +1 -1
- package/dist/core/agent/MultiAgentCoordinator.d.ts +3 -0
- package/dist/core/agent/MultiAgentCoordinator.js +12 -0
- package/dist/core/agent/MultiAgentCoordinator.js.map +1 -1
- package/dist/core/agent/PromptEngine.js +68 -67
- package/dist/core/agent/PromptEngine.js.map +1 -1
- package/dist/core/guardrails/AuditLogger.js +4 -4
- package/dist/core/guardrails/CommandFirewall.js +28 -4
- package/dist/core/guardrails/CommandFirewall.js.map +1 -1
- package/dist/infrastructure/protocols/PlinkSerial.js +1 -1
- package/dist/infrastructure/protocols/PlinkSerial.js.map +1 -1
- package/dist/server/dashboard.js +1066 -966
- package/dist/server/dashboard.js.map +1 -1
- package/dist/server/index.js +8 -8
- package/dist/server/shell-simulator.d.ts +43 -1
- package/dist/server/shell-simulator.js +578 -66
- package/dist/server/shell-simulator.js.map +1 -1
- package/dist/server/ssh.js +20 -20
- package/dist/shared/constants.js +1 -1
- package/dist/shared/constants.js.map +1 -1
- package/package.json +54 -54
|
@@ -50,7 +50,31 @@ class ShellSimulator {
|
|
|
50
50
|
shellFunctions = {};
|
|
51
51
|
ospfEnabled = false;
|
|
52
52
|
ospfProcessId = null;
|
|
53
|
+
ripEnabled = false;
|
|
54
|
+
ripVersion = 2;
|
|
55
|
+
ripAutoSummary = false;
|
|
56
|
+
bgpEnabled = false;
|
|
57
|
+
bgpAsn = null;
|
|
58
|
+
eigrpEnabled = false;
|
|
59
|
+
eigrpAsn = null;
|
|
60
|
+
vtpMode = 'server';
|
|
61
|
+
vtpDomain = null;
|
|
62
|
+
vtpPassword = null;
|
|
63
|
+
hsrpGroups = new Map();
|
|
64
|
+
vrrpGroups = new Map();
|
|
65
|
+
ntpServers = [];
|
|
66
|
+
snmpCommunities = [];
|
|
67
|
+
natInsideInterfaces = new Set();
|
|
68
|
+
natOutsideInterfaces = new Set();
|
|
69
|
+
natRules = [];
|
|
70
|
+
acls = new Map();
|
|
53
71
|
ipRoutingEnabled = true;
|
|
72
|
+
featuresEnabled = new Set();
|
|
73
|
+
vpcDomainId = null;
|
|
74
|
+
vpcPeerKeepalive = null;
|
|
75
|
+
vnSegments = new Map();
|
|
76
|
+
vrfs = new Map();
|
|
77
|
+
activeVrf = null;
|
|
54
78
|
flashFiles = new Set(['c2960-lanbasek9-mz.150-2.SE4.bin']);
|
|
55
79
|
pendingCopyDest = null;
|
|
56
80
|
backupState = null;
|
|
@@ -95,6 +119,9 @@ class ShellSimulator {
|
|
|
95
119
|
case 'INTERFACE_CONFIG':
|
|
96
120
|
return `${this.hostname}(config-if)# `;
|
|
97
121
|
case 'OSPF_CONFIG':
|
|
122
|
+
case 'RIP_CONFIG':
|
|
123
|
+
case 'BGP_CONFIG':
|
|
124
|
+
case 'EIGRP_CONFIG':
|
|
98
125
|
return `${this.hostname}(config-router)# `;
|
|
99
126
|
case 'DHCP_CONFIG':
|
|
100
127
|
return `${this.hostname}(config-dhcp)# `;
|
|
@@ -102,6 +129,12 @@ class ShellSimulator {
|
|
|
102
129
|
return `${this.hostname}(config-ext-nacl)# `;
|
|
103
130
|
case 'VLAN_CONFIG':
|
|
104
131
|
return `${this.hostname}(config-vlan)# `;
|
|
132
|
+
case 'VPC_CONFIG':
|
|
133
|
+
return `${this.hostname}(config-vpc-domain)# `;
|
|
134
|
+
case 'VRF_CONFIG':
|
|
135
|
+
return `${this.hostname}(config-vrf)# `;
|
|
136
|
+
case 'VRF_AF_CONFIG':
|
|
137
|
+
return `${this.hostname}(config-vrf-af-ipv4)# `;
|
|
105
138
|
default:
|
|
106
139
|
return `${this.hostname}# `;
|
|
107
140
|
}
|
|
@@ -143,56 +176,57 @@ class ShellSimulator {
|
|
|
143
176
|
}
|
|
144
177
|
const args = commandToExecute.split(/\s+/);
|
|
145
178
|
const cmd = args[0].toLowerCase();
|
|
179
|
+
const isShow = cmd === 'show' || cmd === 'sh' || (cmd === 'do' && (args[1]?.toLowerCase() === 'show' || args[1]?.toLowerCase() === 'sh'));
|
|
146
180
|
if (cmd === '?' || cmd === 'help') {
|
|
147
181
|
if (cmd === 'help') {
|
|
148
|
-
return `Help may be requested at any point in a command by entering
|
|
149
|
-
a question mark '?'. If nothing matches, the help list will
|
|
182
|
+
return `Help may be requested at any point in a command by entering
|
|
183
|
+
a question mark '?'. If nothing matches, the help list will
|
|
150
184
|
show the available options.`;
|
|
151
185
|
}
|
|
152
186
|
if (this.mode === 'USER_EXEC') {
|
|
153
|
-
return `Exec commands:
|
|
154
|
-
disable Turn off privileged commands
|
|
155
|
-
enable Turn on privileged commands
|
|
156
|
-
exit Exit from the EXEC
|
|
157
|
-
ping Send echo messages
|
|
187
|
+
return `Exec commands:
|
|
188
|
+
disable Turn off privileged commands
|
|
189
|
+
enable Turn on privileged commands
|
|
190
|
+
exit Exit from the EXEC
|
|
191
|
+
ping Send echo messages
|
|
158
192
|
show Show running system information`;
|
|
159
193
|
}
|
|
160
194
|
else if (this.mode === 'PRIVILEGED_EXEC') {
|
|
161
|
-
return `Exec commands:
|
|
162
|
-
clear Reset functions
|
|
163
|
-
configure Enter configuration mode
|
|
164
|
-
copy Copy from one file to another
|
|
165
|
-
dir List files on a filesystem
|
|
166
|
-
disable Turn off privileged commands
|
|
167
|
-
enable Turn on privileged commands
|
|
168
|
-
exit Exit from the EXEC
|
|
169
|
-
ping Send echo messages
|
|
170
|
-
show Show running system information
|
|
195
|
+
return `Exec commands:
|
|
196
|
+
clear Reset functions
|
|
197
|
+
configure Enter configuration mode
|
|
198
|
+
copy Copy from one file to another
|
|
199
|
+
dir List files on a filesystem
|
|
200
|
+
disable Turn off privileged commands
|
|
201
|
+
enable Turn on privileged commands
|
|
202
|
+
exit Exit from the EXEC
|
|
203
|
+
ping Send echo messages
|
|
204
|
+
show Show running system information
|
|
171
205
|
write Write running configuration to memory or terminal`;
|
|
172
206
|
}
|
|
173
207
|
else if (this.mode === 'GLOBAL_CONFIG') {
|
|
174
|
-
return `Configure commands:
|
|
175
|
-
do To run EXEC commands in config mode
|
|
176
|
-
end Exit from configure mode
|
|
177
|
-
exit Exit from configure mode
|
|
178
|
-
hostname Set system's network name
|
|
179
|
-
interface Select an interface to configure
|
|
180
|
-
ip Global IP configuration subcommands
|
|
181
|
-
no Negate a command or set defaults
|
|
182
|
-
router Enable a routing process
|
|
208
|
+
return `Configure commands:
|
|
209
|
+
do To run EXEC commands in config mode
|
|
210
|
+
end Exit from configure mode
|
|
211
|
+
exit Exit from configure mode
|
|
212
|
+
hostname Set system's network name
|
|
213
|
+
interface Select an interface to configure
|
|
214
|
+
ip Global IP configuration subcommands
|
|
215
|
+
no Negate a command or set defaults
|
|
216
|
+
router Enable a routing process
|
|
183
217
|
vlan Vlan configuration commands`;
|
|
184
218
|
}
|
|
185
219
|
else if (this.mode === 'INTERFACE_CONFIG') {
|
|
186
|
-
return `Interface configuration commands:
|
|
187
|
-
description Detailed description of this interface
|
|
188
|
-
exit Exit from interface configuration mode
|
|
189
|
-
ip IP interface configuration subcommands
|
|
190
|
-
no Negate a command or set defaults
|
|
220
|
+
return `Interface configuration commands:
|
|
221
|
+
description Detailed description of this interface
|
|
222
|
+
exit Exit from interface configuration mode
|
|
223
|
+
ip IP interface configuration subcommands
|
|
224
|
+
no Negate a command or set defaults
|
|
191
225
|
shutdown Shutdown this interface`;
|
|
192
226
|
}
|
|
193
227
|
else {
|
|
194
|
-
return `Commands:
|
|
195
|
-
exit Exit current mode
|
|
228
|
+
return `Commands:
|
|
229
|
+
exit Exit current mode
|
|
196
230
|
end Exit to privileged EXEC mode`;
|
|
197
231
|
}
|
|
198
232
|
}
|
|
@@ -203,10 +237,15 @@ show the available options.`;
|
|
|
203
237
|
return `% Incomplete command.`;
|
|
204
238
|
}
|
|
205
239
|
if (cmd === 'exit') {
|
|
206
|
-
if (this.mode === 'INTERFACE_CONFIG' || this.mode === 'OSPF_CONFIG' || this.mode === 'DHCP_CONFIG' || this.mode === 'ACL_CONFIG' || this.mode === 'VLAN_CONFIG') {
|
|
240
|
+
if (this.mode === 'INTERFACE_CONFIG' || this.mode === 'OSPF_CONFIG' || this.mode === 'RIP_CONFIG' || this.mode === 'BGP_CONFIG' || this.mode === 'EIGRP_CONFIG' || this.mode === 'DHCP_CONFIG' || this.mode === 'ACL_CONFIG' || this.mode === 'VLAN_CONFIG' || this.mode === 'VPC_CONFIG' || this.mode === 'VRF_CONFIG') {
|
|
207
241
|
this.mode = 'GLOBAL_CONFIG';
|
|
208
242
|
this.activeInterface = null;
|
|
209
243
|
this.activeVlan = null;
|
|
244
|
+
this.activeVrf = null;
|
|
245
|
+
return '';
|
|
246
|
+
}
|
|
247
|
+
else if (this.mode === 'VRF_AF_CONFIG') {
|
|
248
|
+
this.mode = 'VRF_CONFIG';
|
|
210
249
|
return '';
|
|
211
250
|
}
|
|
212
251
|
else if (this.mode === 'GLOBAL_CONFIG') {
|
|
@@ -226,6 +265,7 @@ show the available options.`;
|
|
|
226
265
|
this.mode = 'PRIVILEGED_EXEC';
|
|
227
266
|
this.activeInterface = null;
|
|
228
267
|
this.activeVlan = null;
|
|
268
|
+
this.activeVrf = null;
|
|
229
269
|
return '';
|
|
230
270
|
}
|
|
231
271
|
}
|
|
@@ -269,7 +309,35 @@ show the available options.`;
|
|
|
269
309
|
this.shellEnabled = true;
|
|
270
310
|
return '';
|
|
271
311
|
}
|
|
272
|
-
|
|
312
|
+
const isGeneralCommand = isShow || cmd === 'ping' || cmd === 'write' || cmd === 'wr' || cmd === 'copy' || cmd === 'dir' || cmd === 'test';
|
|
313
|
+
if (this.mode === 'GLOBAL_CONFIG' && !isGeneralCommand) {
|
|
314
|
+
if (cmd === 'feature' && args[1]) {
|
|
315
|
+
const featureName = args.slice(1).join(' ').toLowerCase();
|
|
316
|
+
this.featuresEnabled.add(featureName);
|
|
317
|
+
return '';
|
|
318
|
+
}
|
|
319
|
+
if (cmd === 'no' && args[1] === 'feature' && args[2]) {
|
|
320
|
+
const featureName = args.slice(2).join(' ').toLowerCase();
|
|
321
|
+
this.featuresEnabled.delete(featureName);
|
|
322
|
+
return '';
|
|
323
|
+
}
|
|
324
|
+
if (cmd === 'vpc' && args[1] === 'domain' && args[2]) {
|
|
325
|
+
const domainId = parseInt(args[2], 10);
|
|
326
|
+
if (!isNaN(domainId)) {
|
|
327
|
+
this.vpcDomainId = domainId;
|
|
328
|
+
this.mode = 'VPC_CONFIG';
|
|
329
|
+
return '';
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
if (cmd === 'vrf' && args[1] === 'context' && args[2]) {
|
|
333
|
+
const vrfName = args[2];
|
|
334
|
+
this.activeVrf = vrfName;
|
|
335
|
+
if (!this.vrfs.has(vrfName)) {
|
|
336
|
+
this.vrfs.set(vrfName, { routeTargets: [] });
|
|
337
|
+
}
|
|
338
|
+
this.mode = 'VRF_CONFIG';
|
|
339
|
+
return '';
|
|
340
|
+
}
|
|
273
341
|
if (cmd === 'hostname' && args[1]) {
|
|
274
342
|
this.hostname = args[1];
|
|
275
343
|
return '';
|
|
@@ -345,6 +413,81 @@ show the available options.`;
|
|
|
345
413
|
this.ospfProcessId = null;
|
|
346
414
|
return '';
|
|
347
415
|
}
|
|
416
|
+
if (cmd === 'router' && args[1] === 'rip') {
|
|
417
|
+
this.mode = 'RIP_CONFIG';
|
|
418
|
+
this.ripEnabled = true;
|
|
419
|
+
return '';
|
|
420
|
+
}
|
|
421
|
+
if (cmd === 'no' && args[1] === 'router' && args[2] === 'rip') {
|
|
422
|
+
this.ripEnabled = false;
|
|
423
|
+
return '';
|
|
424
|
+
}
|
|
425
|
+
if (cmd === 'router' && args[1] === 'bgp') {
|
|
426
|
+
this.mode = 'BGP_CONFIG';
|
|
427
|
+
this.bgpAsn = args[2] || null;
|
|
428
|
+
this.bgpEnabled = true;
|
|
429
|
+
return '';
|
|
430
|
+
}
|
|
431
|
+
if (cmd === 'no' && args[1] === 'router' && args[2] === 'bgp') {
|
|
432
|
+
this.bgpEnabled = false;
|
|
433
|
+
this.bgpAsn = null;
|
|
434
|
+
return '';
|
|
435
|
+
}
|
|
436
|
+
if (cmd === 'spanning-tree' && args[1]) {
|
|
437
|
+
return '';
|
|
438
|
+
}
|
|
439
|
+
if (cmd === 'router' && args[1] === 'eigrp') {
|
|
440
|
+
this.mode = 'EIGRP_CONFIG';
|
|
441
|
+
this.eigrpAsn = args[2] || null;
|
|
442
|
+
this.eigrpEnabled = true;
|
|
443
|
+
return '';
|
|
444
|
+
}
|
|
445
|
+
if (cmd === 'no' && args[1] === 'router' && args[2] === 'eigrp') {
|
|
446
|
+
this.eigrpEnabled = false;
|
|
447
|
+
this.eigrpAsn = null;
|
|
448
|
+
return '';
|
|
449
|
+
}
|
|
450
|
+
if (cmd === 'vtp' && args[1]) {
|
|
451
|
+
if (args[1] === 'mode' && args[2]) {
|
|
452
|
+
this.vtpMode = args[2].toLowerCase();
|
|
453
|
+
}
|
|
454
|
+
else if (args[1] === 'domain' && args[2]) {
|
|
455
|
+
this.vtpDomain = args[2];
|
|
456
|
+
}
|
|
457
|
+
else if (args[1] === 'password' && args[2]) {
|
|
458
|
+
this.vtpPassword = args[2];
|
|
459
|
+
}
|
|
460
|
+
return '';
|
|
461
|
+
}
|
|
462
|
+
if (cmd === 'ntp' && args[1] === 'server' && args[2]) {
|
|
463
|
+
if (!this.ntpServers.includes(args[2])) {
|
|
464
|
+
this.ntpServers.push(args[2]);
|
|
465
|
+
}
|
|
466
|
+
return '';
|
|
467
|
+
}
|
|
468
|
+
if (cmd === 'snmp-server' && args[1] === 'community' && args[2]) {
|
|
469
|
+
if (!this.snmpCommunities.includes(args[2])) {
|
|
470
|
+
this.snmpCommunities.push(args[2]);
|
|
471
|
+
}
|
|
472
|
+
return '';
|
|
473
|
+
}
|
|
474
|
+
if (cmd === 'ip' && args[1] === 'nat' && args[2] === 'inside' && args[3] === 'source') {
|
|
475
|
+
this.natRules.push(args.slice(2).join(' '));
|
|
476
|
+
return '';
|
|
477
|
+
}
|
|
478
|
+
if (cmd === 'access-list' && args[1] && args[2]) {
|
|
479
|
+
const aclId = args[1];
|
|
480
|
+
const rule = args.slice(2).join(' ');
|
|
481
|
+
if (!this.acls.has(aclId)) {
|
|
482
|
+
this.acls.set(aclId, []);
|
|
483
|
+
}
|
|
484
|
+
this.acls.get(aclId).push(rule);
|
|
485
|
+
return '';
|
|
486
|
+
}
|
|
487
|
+
if (cmd === 'ip' && args[1] === 'access-list' && (args[2] === 'standard' || args[2] === 'extended') && args[3]) {
|
|
488
|
+
this.mode = 'ACL_CONFIG';
|
|
489
|
+
return '';
|
|
490
|
+
}
|
|
348
491
|
if (cmd === 'ip' && args[1] === 'dhcp' && args[2] === 'pool' && args[3]) {
|
|
349
492
|
this.mode = 'DHCP_CONFIG';
|
|
350
493
|
return '';
|
|
@@ -361,7 +504,7 @@ show the available options.`;
|
|
|
361
504
|
}
|
|
362
505
|
return `% Invalid input detected at '^' marker.`;
|
|
363
506
|
}
|
|
364
|
-
if (this.mode === 'VLAN_CONFIG' && this.activeVlan !== null) {
|
|
507
|
+
if (this.mode === 'VLAN_CONFIG' && this.activeVlan !== null && !isGeneralCommand) {
|
|
365
508
|
if (cmd === 'name' && args[1]) {
|
|
366
509
|
this.vlanNames.set(this.activeVlan, args.slice(1).join(' '));
|
|
367
510
|
return '';
|
|
@@ -370,10 +513,40 @@ show the available options.`;
|
|
|
370
513
|
this.vlanNames.set(this.activeVlan, `VLAN${this.activeVlan.toString().padStart(4, '0')}`);
|
|
371
514
|
return '';
|
|
372
515
|
}
|
|
516
|
+
if (cmd === 'vn-segment' && args[1]) {
|
|
517
|
+
const vni = parseInt(args[1], 10);
|
|
518
|
+
if (!isNaN(vni)) {
|
|
519
|
+
this.vnSegments.set(this.activeVlan, vni);
|
|
520
|
+
return '';
|
|
521
|
+
}
|
|
522
|
+
}
|
|
373
523
|
return `% Invalid input detected at '^' marker.`;
|
|
374
524
|
}
|
|
375
|
-
if (this.mode === 'INTERFACE_CONFIG' && this.activeInterface) {
|
|
525
|
+
if (this.mode === 'INTERFACE_CONFIG' && this.activeInterface && !isGeneralCommand) {
|
|
376
526
|
const iface = this.interfaces.get(this.activeInterface);
|
|
527
|
+
if (cmd === 'vpc' && args[1]) {
|
|
528
|
+
const vpcId = parseInt(args[1], 10);
|
|
529
|
+
if (!isNaN(vpcId)) {
|
|
530
|
+
iface.vpcMemberId = vpcId;
|
|
531
|
+
return '';
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
if (cmd === 'source-interface' && args[1]) {
|
|
535
|
+
iface.sourceInterface = args[1];
|
|
536
|
+
return '';
|
|
537
|
+
}
|
|
538
|
+
if (cmd === 'member' && args[1] === 'vni' && args[2]) {
|
|
539
|
+
const vni = parseInt(args[2], 10);
|
|
540
|
+
if (!isNaN(vni)) {
|
|
541
|
+
if (!iface.memberVnis) {
|
|
542
|
+
iface.memberVnis = new Map();
|
|
543
|
+
}
|
|
544
|
+
const mcastGroup = args[3] === 'mcast-group' ? args[4] : undefined;
|
|
545
|
+
const associateVrf = args.includes('associate-vrf');
|
|
546
|
+
iface.memberVnis.set(vni, { mcastGroup, associateVrf });
|
|
547
|
+
return '';
|
|
548
|
+
}
|
|
549
|
+
}
|
|
377
550
|
if (cmd === 'shutdown') {
|
|
378
551
|
iface.adminShutdown = true;
|
|
379
552
|
iface.lineProtocolUp = false;
|
|
@@ -449,9 +622,61 @@ show the available options.`;
|
|
|
449
622
|
if (cmd === 'ip' && args[1] === 'ospf') {
|
|
450
623
|
return '';
|
|
451
624
|
}
|
|
625
|
+
if (cmd === 'switchport' && args[1] === 'mode' && args[2] === 'trunk') {
|
|
626
|
+
iface.switchportMode = 'trunk';
|
|
627
|
+
iface.isSwitchport = true;
|
|
628
|
+
return '';
|
|
629
|
+
}
|
|
630
|
+
if (cmd === 'switchport' && args[1] === 'trunk' && args[2] === 'allowed' && args[3] === 'vlan') {
|
|
631
|
+
return '';
|
|
632
|
+
}
|
|
633
|
+
if (cmd === 'channel-group' && args[1] && args[2] === 'mode' && args[3]) {
|
|
634
|
+
return '';
|
|
635
|
+
}
|
|
636
|
+
if (cmd === 'standby' && args[1]) {
|
|
637
|
+
const group = args[1];
|
|
638
|
+
if (!this.hsrpGroups.has(group)) {
|
|
639
|
+
this.hsrpGroups.set(group, { virtualIp: '', priority: 100, preempt: false });
|
|
640
|
+
}
|
|
641
|
+
const hsrp = this.hsrpGroups.get(group);
|
|
642
|
+
if (args[2] === 'ip' && args[3]) {
|
|
643
|
+
hsrp.virtualIp = args[3];
|
|
644
|
+
}
|
|
645
|
+
else if (args[2] === 'priority' && args[3]) {
|
|
646
|
+
hsrp.priority = parseInt(args[3], 10);
|
|
647
|
+
}
|
|
648
|
+
else if (args[2] === 'preempt') {
|
|
649
|
+
hsrp.preempt = true;
|
|
650
|
+
}
|
|
651
|
+
return '';
|
|
652
|
+
}
|
|
653
|
+
if (cmd === 'vrrp' && args[1]) {
|
|
654
|
+
const group = args[1];
|
|
655
|
+
if (!this.vrrpGroups.has(group)) {
|
|
656
|
+
this.vrrpGroups.set(group, { virtualIp: '', priority: 100 });
|
|
657
|
+
}
|
|
658
|
+
const vrrp = this.vrrpGroups.get(group);
|
|
659
|
+
if (args[2] === 'ip' && args[3]) {
|
|
660
|
+
vrrp.virtualIp = args[3];
|
|
661
|
+
}
|
|
662
|
+
else if (args[2] === 'priority' && args[3]) {
|
|
663
|
+
vrrp.priority = parseInt(args[3], 10);
|
|
664
|
+
}
|
|
665
|
+
return '';
|
|
666
|
+
}
|
|
667
|
+
if (cmd === 'ip' && args[1] === 'nat' && (args[2] === 'inside' || args[2] === 'outside')) {
|
|
668
|
+
iface.natType = args[2];
|
|
669
|
+
if (args[2] === 'inside') {
|
|
670
|
+
this.natInsideInterfaces.add(this.activeInterface);
|
|
671
|
+
}
|
|
672
|
+
else {
|
|
673
|
+
this.natOutsideInterfaces.add(this.activeInterface);
|
|
674
|
+
}
|
|
675
|
+
return '';
|
|
676
|
+
}
|
|
452
677
|
return `% Invalid input detected at '^' marker.`;
|
|
453
678
|
}
|
|
454
|
-
if (this.mode === 'OSPF_CONFIG') {
|
|
679
|
+
if (this.mode === 'OSPF_CONFIG' && !isGeneralCommand) {
|
|
455
680
|
if (cmd === 'network' || cmd === 'router-id') {
|
|
456
681
|
return '';
|
|
457
682
|
}
|
|
@@ -460,36 +685,179 @@ show the available options.`;
|
|
|
460
685
|
}
|
|
461
686
|
return `% Invalid input detected at '^' marker.`;
|
|
462
687
|
}
|
|
463
|
-
if (this.mode === '
|
|
688
|
+
if (this.mode === 'RIP_CONFIG' && !isGeneralCommand) {
|
|
689
|
+
if (cmd === 'version' && (args[1] === '1' || args[1] === '2')) {
|
|
690
|
+
this.ripVersion = parseInt(args[1], 10);
|
|
691
|
+
return '';
|
|
692
|
+
}
|
|
693
|
+
if (cmd === 'no' && args[1] === 'auto-summary') {
|
|
694
|
+
this.ripAutoSummary = false;
|
|
695
|
+
return '';
|
|
696
|
+
}
|
|
697
|
+
if (cmd === 'auto-summary') {
|
|
698
|
+
this.ripAutoSummary = true;
|
|
699
|
+
return '';
|
|
700
|
+
}
|
|
701
|
+
if (cmd === 'network' && args[1]) {
|
|
702
|
+
return '';
|
|
703
|
+
}
|
|
704
|
+
if (cmd === 'passive-interface' || (cmd === 'no' && args[1] === 'passive-interface')) {
|
|
705
|
+
return '';
|
|
706
|
+
}
|
|
707
|
+
return `% Invalid input detected at '^' marker.`;
|
|
708
|
+
}
|
|
709
|
+
if (this.mode === 'BGP_CONFIG' && !isGeneralCommand) {
|
|
710
|
+
if (cmd === 'neighbor' && args[1]) {
|
|
711
|
+
return '';
|
|
712
|
+
}
|
|
713
|
+
if (cmd === 'no' && args[1] === 'neighbor' && args[2]) {
|
|
714
|
+
return '';
|
|
715
|
+
}
|
|
716
|
+
if (cmd === 'network' && args[1]) {
|
|
717
|
+
return '';
|
|
718
|
+
}
|
|
719
|
+
if (cmd === 'no' && args[1] === 'auto-summary') {
|
|
720
|
+
return '';
|
|
721
|
+
}
|
|
722
|
+
if (cmd === 'auto-summary') {
|
|
723
|
+
return '';
|
|
724
|
+
}
|
|
725
|
+
if (cmd === 'address-family' && args[1] === 'l2vpn' && args[2] === 'evpn') {
|
|
726
|
+
return '';
|
|
727
|
+
}
|
|
728
|
+
if (cmd === 'send-community') {
|
|
729
|
+
return '';
|
|
730
|
+
}
|
|
731
|
+
return `% Invalid input detected at '^' marker.`;
|
|
732
|
+
}
|
|
733
|
+
if (this.mode === 'VPC_CONFIG' && !isGeneralCommand) {
|
|
734
|
+
if (cmd === 'peer-keepalive' && args[1] === 'destination') {
|
|
735
|
+
this.vpcPeerKeepalive = commandToExecute;
|
|
736
|
+
return '';
|
|
737
|
+
}
|
|
738
|
+
if (cmd === 'system-priority' || cmd === 'role' || cmd === 'peer-gateway' || cmd === 'peer-switch') {
|
|
739
|
+
return '';
|
|
740
|
+
}
|
|
741
|
+
return `% Invalid input detected at '^' marker.`;
|
|
742
|
+
}
|
|
743
|
+
if (this.mode === 'VRF_CONFIG' && this.activeVrf && !isGeneralCommand) {
|
|
744
|
+
const vrf = this.vrfs.get(this.activeVrf);
|
|
745
|
+
if (cmd === 'vni' && args[1]) {
|
|
746
|
+
vrf.vni = parseInt(args[1], 10);
|
|
747
|
+
return '';
|
|
748
|
+
}
|
|
749
|
+
if (cmd === 'rd' && args[1]) {
|
|
750
|
+
vrf.rd = args.slice(1).join(' ');
|
|
751
|
+
return '';
|
|
752
|
+
}
|
|
753
|
+
if (cmd === 'address-family' && args[1] === 'ipv4' && args[2] === 'unicast') {
|
|
754
|
+
this.mode = 'VRF_AF_CONFIG';
|
|
755
|
+
return '';
|
|
756
|
+
}
|
|
757
|
+
return `% Invalid input detected at '^' marker.`;
|
|
758
|
+
}
|
|
759
|
+
if (this.mode === 'VRF_AF_CONFIG' && this.activeVrf && !isGeneralCommand) {
|
|
760
|
+
const vrf = this.vrfs.get(this.activeVrf);
|
|
761
|
+
if (cmd === 'route-target' && args[1] === 'both' && args[2]) {
|
|
762
|
+
vrf.routeTargets.push(args.slice(1).join(' '));
|
|
763
|
+
return '';
|
|
764
|
+
}
|
|
765
|
+
return `% Invalid input detected at '^' marker.`;
|
|
766
|
+
}
|
|
767
|
+
if (this.mode === 'EIGRP_CONFIG' && !isGeneralCommand) {
|
|
768
|
+
if (cmd === 'network' && args[1]) {
|
|
769
|
+
return '';
|
|
770
|
+
}
|
|
771
|
+
if (cmd === 'no' && args[1] === 'auto-summary') {
|
|
772
|
+
return '';
|
|
773
|
+
}
|
|
774
|
+
if (cmd === 'auto-summary') {
|
|
775
|
+
return '';
|
|
776
|
+
}
|
|
777
|
+
if (cmd === 'passive-interface' || (cmd === 'no' && args[1] === 'passive-interface')) {
|
|
778
|
+
return '';
|
|
779
|
+
}
|
|
780
|
+
return `% Invalid input detected at '^' marker.`;
|
|
781
|
+
}
|
|
782
|
+
if (this.mode === 'DHCP_CONFIG' && !isGeneralCommand) {
|
|
464
783
|
if (cmd === 'network' || cmd === 'default-router' || cmd === 'dns-server') {
|
|
465
784
|
return '';
|
|
466
785
|
}
|
|
467
786
|
return `% Invalid input detected at '^' marker.`;
|
|
468
787
|
}
|
|
469
|
-
if (this.mode === 'ACL_CONFIG') {
|
|
788
|
+
if (this.mode === 'ACL_CONFIG' && !isGeneralCommand) {
|
|
470
789
|
if (cmd === 'permit' || cmd === 'deny') {
|
|
471
790
|
return '';
|
|
472
791
|
}
|
|
473
792
|
return `% Invalid input detected at '^' marker.`;
|
|
474
793
|
}
|
|
475
|
-
const isShow = cmd === 'show' || cmd === 'sh' || (cmd === 'do' && (args[1]?.toLowerCase() === 'show' || args[1]?.toLowerCase() === 'sh'));
|
|
476
794
|
if (isShow) {
|
|
477
795
|
const showArgs = cmd === 'do' ? args.slice(2) : args.slice(1);
|
|
478
796
|
const showCmd = showArgs[0]?.toLowerCase();
|
|
797
|
+
if (showCmd === 'vpc') {
|
|
798
|
+
const domainId = this.vpcDomainId || 10;
|
|
799
|
+
const peerStatus = this.vpcPeerKeepalive ? 'peer adjacency formed ok' : 'peer link not configured';
|
|
800
|
+
const keepaliveStatus = this.vpcPeerKeepalive ? 'peer is alive' : 'peer keep-alive not configured';
|
|
801
|
+
return `Legend:
|
|
802
|
+
(*) - local vPC is down, dynamic backup loop preventer
|
|
803
|
+
|
|
804
|
+
vPC domain id : ${domainId}
|
|
805
|
+
Peer status : ${peerStatus}
|
|
806
|
+
vPC keep-alive status : ${keepaliveStatus}
|
|
807
|
+
Configuration-consistency status : success
|
|
808
|
+
Per-vlan consistency status : success
|
|
809
|
+
Type-2 consistency status : success
|
|
810
|
+
vPC role : primary
|
|
811
|
+
Number of vPCs configured : ${Array.from(this.interfaces.values()).filter(i => i.vpcMemberId !== undefined).length}
|
|
812
|
+
Peer Gateway : Enabled
|
|
813
|
+
`;
|
|
814
|
+
}
|
|
815
|
+
if (showCmd === 'nve' && showArgs[1] === 'interface') {
|
|
816
|
+
const nveIface = Array.from(this.interfaces.values()).find(i => i.name.toLowerCase().startsWith('nve'));
|
|
817
|
+
if (!nveIface) {
|
|
818
|
+
return '% NVE interface is not configured';
|
|
819
|
+
}
|
|
820
|
+
const sourceInt = nveIface.sourceInterface || 'Loopback0';
|
|
821
|
+
return `Interface: ${nveIface.name}, State: Up, Encapsulation: VXLAN
|
|
822
|
+
Source-Interface: ${sourceInt} (10.0.0.1)
|
|
823
|
+
`;
|
|
824
|
+
}
|
|
825
|
+
if (showCmd === 'nve' && showArgs[1] === 'vni') {
|
|
826
|
+
const nveIface = Array.from(this.interfaces.values()).find(i => i.name.toLowerCase().startsWith('nve'));
|
|
827
|
+
if (!nveIface || !nveIface.memberVnis) {
|
|
828
|
+
return `Interface VNI Multicast-group State Mode vPC Dev\n` +
|
|
829
|
+
`--------- -------- ----------------- ----- ---- -------\n`;
|
|
830
|
+
}
|
|
831
|
+
let out = `Interface VNI Multicast-group State Mode vPC Dev\n` +
|
|
832
|
+
`--------- -------- ----------------- ----- ---- -------\n`;
|
|
833
|
+
for (const [vni, details] of nveIface.memberVnis.entries()) {
|
|
834
|
+
const mcast = details.mcastGroup || 'n/a';
|
|
835
|
+
out += `${nveIface.name.padEnd(9)} ${vni.toString().padEnd(8)} ${mcast.padEnd(17)} Up CP n/a\n`;
|
|
836
|
+
}
|
|
837
|
+
return out;
|
|
838
|
+
}
|
|
839
|
+
if (showCmd === 'bgp' && showArgs[1] === 'l2vpn' && showArgs[2] === 'evpn' && showArgs[3] === 'summary') {
|
|
840
|
+
const bgpAs = this.bgpAsn || '65000';
|
|
841
|
+
return `BGP summary information for VRF default, address family L2VPN EVPN
|
|
842
|
+
BGP router identifier 10.0.0.1, local AS number ${bgpAs}
|
|
843
|
+
Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd
|
|
844
|
+
10.0.0.2 4 ${bgpAs} 120 125 47 0 0 01:24:55 2
|
|
845
|
+
`;
|
|
846
|
+
}
|
|
479
847
|
if (showCmd === 'version' || showCmd === 'ver') {
|
|
480
|
-
return `Cisco IOS Software, C2960 Software (C2960-LANBASEK9-M), Version 15.0(2)SE4, RELEASE SOFTWARE (fc1)
|
|
481
|
-
Technical Support: http://www.cisco.com/techsupport
|
|
482
|
-
Copyright (c) 1986-2013 by Cisco Systems, Inc.
|
|
483
|
-
Compiled Wed 26-Jun-13 02:49 by prod_rel_team
|
|
484
|
-
|
|
485
|
-
ROM: Bootstrap program is 12.2(44)SE Version
|
|
486
|
-
BOOTLDR: C2960 Boot Loader (C2960-HBOOT-M) Version 12.2(44)SE, RELEASE SOFTWARE (fc1)
|
|
487
|
-
|
|
488
|
-
Switch1 uptime is 2 hours, 15 minutes
|
|
489
|
-
System returned to ROM by power-on
|
|
490
|
-
System image file is "flash:/c2960-lanbasek9-mz.150-2.SE4.bin"
|
|
491
|
-
|
|
492
|
-
This product contains cryptographic features and is subject to Y...
|
|
848
|
+
return `Cisco IOS Software, C2960 Software (C2960-LANBASEK9-M), Version 15.0(2)SE4, RELEASE SOFTWARE (fc1)
|
|
849
|
+
Technical Support: http://www.cisco.com/techsupport
|
|
850
|
+
Copyright (c) 1986-2013 by Cisco Systems, Inc.
|
|
851
|
+
Compiled Wed 26-Jun-13 02:49 by prod_rel_team
|
|
852
|
+
|
|
853
|
+
ROM: Bootstrap program is 12.2(44)SE Version
|
|
854
|
+
BOOTLDR: C2960 Boot Loader (C2960-HBOOT-M) Version 12.2(44)SE, RELEASE SOFTWARE (fc1)
|
|
855
|
+
|
|
856
|
+
Switch1 uptime is 2 hours, 15 minutes
|
|
857
|
+
System returned to ROM by power-on
|
|
858
|
+
System image file is "flash:/c2960-lanbasek9-mz.150-2.SE4.bin"
|
|
859
|
+
|
|
860
|
+
This product contains cryptographic features and is subject to Y...
|
|
493
861
|
`;
|
|
494
862
|
}
|
|
495
863
|
if (showCmd === 'ip' && showArgs[1]?.startsWith('int') && showArgs[2]?.startsWith('br')) {
|
|
@@ -526,6 +894,70 @@ This product contains cryptographic features and is subject to Y...
|
|
|
526
894
|
out += `!\nend\n`;
|
|
527
895
|
return out;
|
|
528
896
|
}
|
|
897
|
+
if (showCmd === 'ip' && showArgs[1] === 'protocols') {
|
|
898
|
+
let out = '';
|
|
899
|
+
if (this.ospfEnabled) {
|
|
900
|
+
out += `Routing Protocol is "ospf ${this.ospfProcessId || '10'}"\n` +
|
|
901
|
+
` Outgoing update filter list for all interfaces is not set\n` +
|
|
902
|
+
` Incoming update filter list for all interfaces is not set\n` +
|
|
903
|
+
` Router ID 192.168.1.254\n` +
|
|
904
|
+
` Number of areas in this router is 1. 1 normal 0 stub 0 nssa\n` +
|
|
905
|
+
` Routing for Networks:\n` +
|
|
906
|
+
` 192.168.1.0/24 area 0\n` +
|
|
907
|
+
` Routing Information Sources:\n` +
|
|
908
|
+
` Gateway Distance Last Update\n` +
|
|
909
|
+
` Distance: (default is 110)\n\n`;
|
|
910
|
+
}
|
|
911
|
+
if (this.ripEnabled) {
|
|
912
|
+
out += `Routing Protocol is "rip"\n` +
|
|
913
|
+
` Sending updates every 30 seconds, next due in 15 seconds\n` +
|
|
914
|
+
` Invalid 180 seconds, hold down 180, flushed 240\n` +
|
|
915
|
+
` Outgoing update filter list for all interfaces is not set\n` +
|
|
916
|
+
` Incoming update filter list for all interfaces is not set\n` +
|
|
917
|
+
` Redistributing: rip\n` +
|
|
918
|
+
` Default version control: send version ${this.ripVersion}, receive version ${this.ripVersion}\n` +
|
|
919
|
+
` Interface Send Recv Triggered RIP Key-chain\n`;
|
|
920
|
+
for (const name of this.interfaces.keys()) {
|
|
921
|
+
out += ` ${name.padEnd(21)} ${this.ripVersion} ${this.ripVersion}\n`;
|
|
922
|
+
}
|
|
923
|
+
out += ` Automatic network summarization is ${this.ripAutoSummary ? 'in effect' : 'not in effect'}\n` +
|
|
924
|
+
` Maximum path: 4\n` +
|
|
925
|
+
` Routing for Networks:\n` +
|
|
926
|
+
` 192.168.1.0\n` +
|
|
927
|
+
` Routing Information Sources:\n` +
|
|
928
|
+
` Gateway Distance Last Update\n` +
|
|
929
|
+
` Distance: (default is 120)\n\n`;
|
|
930
|
+
}
|
|
931
|
+
if (this.bgpEnabled) {
|
|
932
|
+
out += `Routing Protocol is "bgp ${this.bgpAsn || '65000'}"\n` +
|
|
933
|
+
` Outgoing update filter list for all interfaces is not set\n` +
|
|
934
|
+
` Incoming update filter list for all interfaces is not set\n` +
|
|
935
|
+
` IGP synchronization is disabled\n` +
|
|
936
|
+
` Automatic route summarization is disabled\n` +
|
|
937
|
+
` Routing Information Sources:\n` +
|
|
938
|
+
` Gateway Distance Last Update\n` +
|
|
939
|
+
` Distance: external 20 internal 200 local 200\n\n`;
|
|
940
|
+
}
|
|
941
|
+
if (this.eigrpEnabled) {
|
|
942
|
+
out += `Routing Protocol is "eigrp ${this.eigrpAsn || '100'}"\n` +
|
|
943
|
+
` Outgoing update filter list for all interfaces is not set\n` +
|
|
944
|
+
` Incoming update filter list for all interfaces is not set\n` +
|
|
945
|
+
` Default networks being advertised:\n` +
|
|
946
|
+
` 192.168.1.0\n` +
|
|
947
|
+
` EIGRP-IPv4 Protocol for AS(${this.eigrpAsn || '100'})\n` +
|
|
948
|
+
` Metric weight K1=1, K2=0, K3=1, K4=0, K5=0\n` +
|
|
949
|
+
` NSF-aware route hold timer is 240s\n` +
|
|
950
|
+
` Router-ID: 192.168.1.254\n` +
|
|
951
|
+
` Topology Kisspoint limit: 100\n` +
|
|
952
|
+
` Routing Information Sources:\n` +
|
|
953
|
+
` Gateway Distance Last Update\n` +
|
|
954
|
+
` Distance: internal 90 external 170\n\n`;
|
|
955
|
+
}
|
|
956
|
+
if (!out) {
|
|
957
|
+
out = '*** No routing protocols configured ***\n';
|
|
958
|
+
}
|
|
959
|
+
return out;
|
|
960
|
+
}
|
|
529
961
|
if (showCmd === 'ip' && showArgs[1]?.startsWith('ro')) {
|
|
530
962
|
if (!this.ipRoutingEnabled) {
|
|
531
963
|
return '% IP routing table is not enabled';
|
|
@@ -576,17 +1008,79 @@ This product contains cryptographic features and is subject to Y...
|
|
|
576
1008
|
return out;
|
|
577
1009
|
}
|
|
578
1010
|
if (showCmd === 'cdp' && showArgs[1]?.startsWith('ne')) {
|
|
579
|
-
return `Capability Codes: R - Router, T - Trans Bridge, B - Source Route Bridge
|
|
580
|
-
S - Switch, H - Host, I - IGMP, r - Repeater, P - Phone
|
|
581
|
-
|
|
582
|
-
Device ID Local Intrfce Holdtme Capability Platform Port ID
|
|
583
|
-
Switch2 Gig 0/1 125 S I WS-C2960- Gig 0/1
|
|
1011
|
+
return `Capability Codes: R - Router, T - Trans Bridge, B - Source Route Bridge
|
|
1012
|
+
S - Switch, H - Host, I - IGMP, r - Repeater, P - Phone
|
|
1013
|
+
|
|
1014
|
+
Device ID Local Intrfce Holdtme Capability Platform Port ID
|
|
1015
|
+
Switch2 Gig 0/1 125 S I WS-C2960- Gig 0/1
|
|
584
1016
|
`;
|
|
585
1017
|
}
|
|
1018
|
+
if (showCmd === 'vtp' && showArgs[1] === 'status') {
|
|
1019
|
+
return `VTP Version capability : 1 to 3\n` +
|
|
1020
|
+
`VTP version running : 1\n` +
|
|
1021
|
+
`VTP Operating Mode : ${this.vtpMode}\n` +
|
|
1022
|
+
`VTP Domain Name : ${this.vtpDomain || ''}\n` +
|
|
1023
|
+
`VTP Pruning Mode : Disabled\n` +
|
|
1024
|
+
`VTP V2 Mode : Disabled\n` +
|
|
1025
|
+
`VTP Traps Generation : Disabled\n` +
|
|
1026
|
+
`MD5 digest : 0x94 0xC2 0x6E 0x93 0xA3 0xE2 0xD4 0xFA \n` +
|
|
1027
|
+
`Configuration last modified by 0.0.0.0 at 0-0-00 00:00:00\n`;
|
|
1028
|
+
}
|
|
1029
|
+
if (showCmd === 'standby' && (showArgs[1] === 'brief' || !showArgs[1])) {
|
|
1030
|
+
let out = ' Preempt State Active Standby Virtual IP\n';
|
|
1031
|
+
for (const [group, hsrp] of this.hsrpGroups.entries()) {
|
|
1032
|
+
out += `Gi0/1 ${group.padEnd(6)} ${hsrp.priority.toString().padEnd(4)} ${hsrp.preempt ? 'P' : ' '} Active local unknown ${hsrp.virtualIp}\n`;
|
|
1033
|
+
}
|
|
1034
|
+
if (this.hsrpGroups.size === 0) {
|
|
1035
|
+
out = '*** No HSRP standby groups configured ***\n';
|
|
1036
|
+
}
|
|
1037
|
+
return out;
|
|
1038
|
+
}
|
|
1039
|
+
if (showCmd === 'vrrp' && (showArgs[1] === 'brief' || !showArgs[1])) {
|
|
1040
|
+
let out = 'Interface Grp Fip Pri Time Own Pre State Master addr Group addr\n';
|
|
1041
|
+
for (const [group, vrrp] of this.vrrpGroups.entries()) {
|
|
1042
|
+
out += `Gi0/1 ${group.padEnd(4)} 1 ${vrrp.priority.toString().padEnd(3)} 3.609 N Y Master local ${vrrp.virtualIp}\n`;
|
|
1043
|
+
}
|
|
1044
|
+
if (this.vrrpGroups.size === 0) {
|
|
1045
|
+
out = '*** No VRRP groups configured ***\n';
|
|
1046
|
+
}
|
|
1047
|
+
return out;
|
|
1048
|
+
}
|
|
1049
|
+
if (showCmd === 'ip' && showArgs[1] === 'nat' && showArgs[2] === 'translations') {
|
|
1050
|
+
let out = 'Pro Inside global Inside local Outside local Outside global\n';
|
|
1051
|
+
for (const rule of this.natRules) {
|
|
1052
|
+
out += `tcp 192.0.2.1:80 192.168.1.10:80 --- ---\n`;
|
|
1053
|
+
}
|
|
1054
|
+
if (this.natRules.length === 0) {
|
|
1055
|
+
out = '*** No NAT translations active ***\n';
|
|
1056
|
+
}
|
|
1057
|
+
return out;
|
|
1058
|
+
}
|
|
1059
|
+
if (showCmd === 'access-lists') {
|
|
1060
|
+
let out = '';
|
|
1061
|
+
for (const [aclId, rules] of this.acls.entries()) {
|
|
1062
|
+
out += `Standard IP access list ${aclId}\n`;
|
|
1063
|
+
rules.forEach((rule, idx) => {
|
|
1064
|
+
out += ` ${(idx + 1) * 10} ${rule}\n`;
|
|
1065
|
+
});
|
|
1066
|
+
}
|
|
1067
|
+
if (this.acls.size === 0) {
|
|
1068
|
+
out = '*** No access lists configured ***\n';
|
|
1069
|
+
}
|
|
1070
|
+
return out;
|
|
1071
|
+
}
|
|
1072
|
+
if (showCmd === 'ntp' && (showArgs[1] === 'status' || showArgs[1] === 'associations')) {
|
|
1073
|
+
if (this.ntpServers.length === 0) {
|
|
1074
|
+
return 'NTP is not enabled.\n';
|
|
1075
|
+
}
|
|
1076
|
+
let out = 'Clock is synchronized, stratum 2, reference is ' + this.ntpServers[0] + '\n';
|
|
1077
|
+
out += 'nominal freq is 250.0000 Hz, actual freq is 250.0000 Hz, precision is 2**24\n';
|
|
1078
|
+
return out;
|
|
1079
|
+
}
|
|
586
1080
|
if (showCmd === 'lldp' && showArgs[1]?.startsWith('ne')) {
|
|
587
|
-
return `Device ID Local Intf Hold-time Capability Port ID
|
|
588
|
-
Switch2 Gi0/1 120 S Gi0/1
|
|
589
|
-
Total entries displayed: 1
|
|
1081
|
+
return `Device ID Local Intf Hold-time Capability Port ID
|
|
1082
|
+
Switch2 Gi0/1 120 S Gi0/1
|
|
1083
|
+
Total entries displayed: 1
|
|
590
1084
|
`;
|
|
591
1085
|
}
|
|
592
1086
|
return `% Unrecognized show command: show ${showArgs.join(' ')}`;
|
|
@@ -627,9 +1121,9 @@ Total entries displayed: 1
|
|
|
627
1121
|
}
|
|
628
1122
|
if (cmd === 'ping' && args[1]) {
|
|
629
1123
|
const ip = args[1];
|
|
630
|
-
return `Sending 5, 100-byte ICMP Echos to ${ip}, timeout is 2 seconds:
|
|
631
|
-
!!!!!
|
|
632
|
-
Success rate is 100 percent (5/5), round-trip min/avg/max = 1/1/4 ms
|
|
1124
|
+
return `Sending 5, 100-byte ICMP Echos to ${ip}, timeout is 2 seconds:
|
|
1125
|
+
!!!!!
|
|
1126
|
+
Success rate is 100 percent (5/5), round-trip min/avg/max = 1/1/4 ms
|
|
633
1127
|
`;
|
|
634
1128
|
}
|
|
635
1129
|
if (cmd === 'test' && args[1] === 'trigger-syslog') {
|
|
@@ -677,6 +1171,21 @@ Success rate is 100 percent (5/5), round-trip min/avg/max = 1/1/4 ms
|
|
|
677
1171
|
if (lower.startsWith('vl')) {
|
|
678
1172
|
return 'Vlan' + name.substring(2);
|
|
679
1173
|
}
|
|
1174
|
+
if (lower.startsWith('ethernet')) {
|
|
1175
|
+
return 'Ethernet' + name.substring(8);
|
|
1176
|
+
}
|
|
1177
|
+
if (lower.startsWith('eth')) {
|
|
1178
|
+
return 'Ethernet' + name.substring(3);
|
|
1179
|
+
}
|
|
1180
|
+
if (lower.startsWith('port-channel')) {
|
|
1181
|
+
return 'Port-channel' + name.substring(12);
|
|
1182
|
+
}
|
|
1183
|
+
if (lower.startsWith('po')) {
|
|
1184
|
+
return 'Port-channel' + name.substring(2);
|
|
1185
|
+
}
|
|
1186
|
+
if (lower.startsWith('nve')) {
|
|
1187
|
+
return 'Nve' + name.substring(3);
|
|
1188
|
+
}
|
|
680
1189
|
return name;
|
|
681
1190
|
}
|
|
682
1191
|
shortenInterfaceName(name) {
|
|
@@ -684,7 +1193,10 @@ Success rate is 100 percent (5/5), round-trip min/avg/max = 1/1/4 ms
|
|
|
684
1193
|
.replace('GigabitEthernet', 'Gi')
|
|
685
1194
|
.replace('FastEthernet', 'Fa')
|
|
686
1195
|
.replace('TenGigabitEthernet', 'Te')
|
|
687
|
-
.replace('Loopback', 'Lo')
|
|
1196
|
+
.replace('Loopback', 'Lo')
|
|
1197
|
+
.replace('Ethernet', 'Eth')
|
|
1198
|
+
.replace('Port-channel', 'Po')
|
|
1199
|
+
.replace('Nve', 'Nve');
|
|
688
1200
|
}
|
|
689
1201
|
getPrefixLength(mask) {
|
|
690
1202
|
const parts = mask.split('.').map(Number);
|