package cisco import ( "fmt" "math/rand" "strings" "time" ) func showVersion(s *iosState) string { days := 14 + rand.Intn(350) hours := rand.Intn(24) mins := rand.Intn(60) return fmt.Sprintf(`Cisco IOS Software, %s Software (%s-UNIVERSALK9-M), Version %s, RELEASE SOFTWARE (fc3) Technical Support: http://www.cisco.com/techsupport Copyright (c) 1986-2019 by Cisco Systems, Inc. Compiled Thu 30-Jan-19 10:08 by prod_rel_team ROM: Bootstrap program is %s boot loader BOOTLDR: %s Boot Loader (C2960-HBOOT-M) Version 15.0(2r)SE, RELEASE SOFTWARE (fc1) %s uptime is %d days, %d hours, %d minutes System returned to ROM by power-on System image file is "flash:/%s-universalk9-mz.SPA.%s.bin" This product contains cryptographic features and is subject to United States and local country laws governing import, export, transfer and use. cisco %s (%s) processor (revision K0) with 524288K bytes of memory. Processor board ID %s Last reset from power-on 2 Gigabit Ethernet interfaces 1 Virtual Ethernet interface 64K bytes of flash-simulated non-volatile configuration memory. Total of 65536K bytes of APC System Flash (Read/Write) Configuration register is 0x2102`, s.model, s.model, s.iosVersion, s.model, s.model, s.hostname, days, hours, mins, s.model, s.iosVersion, s.model, processorForModel(s.model), s.serial, ) } func processorForModel(model string) string { if strings.HasPrefix(model, "C29") { return "PowerPC405" } return "MIPS" } func showClock() string { now := time.Now().UTC() return fmt.Sprintf("*%s UTC", now.Format("15:04:05.000 Mon Jan 2 2006")) } func showIPRoute(s *iosState) string { var b strings.Builder b.WriteString("Codes: C - connected, S - static, R - RIP, M - mobile, B - BGP\n") b.WriteString(" D - EIGRP, EX - EIGRP external, O - OSPF, IA - OSPF inter area\n") b.WriteString(" N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2\n") b.WriteString(" E1 - OSPF external type 1, E2 - OSPF external type 2\n") b.WriteString(" i - IS-IS, su - IS-IS summary, L1 - IS-IS level-1, L2 - IS-IS level-2\n") b.WriteString(" ia - IS-IS inter area, * - candidate default, U - per-user static route\n") b.WriteString(" o - ODR, P - periodic downloaded static route\n\n") b.WriteString("Gateway of last resort is 10.0.0.2 to network 0.0.0.0\n\n") for _, iface := range s.interfaces { if iface.ip == "unassigned" || iface.status != "up" { continue } network := networkFromIP(iface.ip, iface.mask) maskBits := maskBits(iface.mask) fmt.Fprintf(&b, "C %s/%d is directly connected, %s\n", network, maskBits, iface.name) } b.WriteString("S* 0.0.0.0/0 [1/0] via 10.0.0.2") return b.String() } func showIPInterfaceBrief(s *iosState) string { var b strings.Builder fmt.Fprintf(&b, "%-25s %-15s %-4s %-7s %-22s %s\n", "Interface", "IP-Address", "OK?", "Method", "Status", "Protocol") for _, iface := range s.interfaces { ip := iface.ip if ip == "" { ip = "unassigned" } fmt.Fprintf(&b, "%-25s %-15s YES manual %-22s %s\n", iface.name, ip, iface.status, iface.protocol) } return b.String() } func showInterfaces(s *iosState) string { var b strings.Builder for i, iface := range s.interfaces { if i > 0 { b.WriteString("\n") } upDown := "up" if iface.shutdown { upDown = "administratively down" } fmt.Fprintf(&b, "%s is %s, line protocol is %s\n", iface.name, upDown, iface.protocol) fmt.Fprintf(&b, " Hardware is Gigabit Ethernet, address is %s (bia %s)\n", iface.mac, iface.mac) if iface.ip != "unassigned" && iface.ip != "" { fmt.Fprintf(&b, " Internet address is %s/%d\n", iface.ip, maskBits(iface.mask)) } fmt.Fprintf(&b, " MTU %d bytes, BW %s sec, DLY 10 usec,\n", iface.mtu, iface.bandwidth) b.WriteString(" reliability 255/255, txload 1/255, rxload 1/255\n") b.WriteString(" Encapsulation ARPA, loopback not set\n") fmt.Fprintf(&b, " %d packets input, %d bytes, 0 no buffer\n", iface.rxPackets, iface.rxBytes) fmt.Fprintf(&b, " %d packets output, %d bytes, 0 underruns", iface.txPackets, iface.txBytes) } return b.String() } func showRunningConfig(s *iosState) string { var b strings.Builder b.WriteString("Building configuration...\n\n") b.WriteString("Current configuration : 1482 bytes\n") b.WriteString("!\n") b.WriteString("! Last configuration change at 14:32:22 UTC Mon Feb 10 2025\n") b.WriteString("!\n") b.WriteString("version 15.0\n") b.WriteString("service timestamps debug datetime msec\n") b.WriteString("service timestamps log datetime msec\n") b.WriteString("no service password-encryption\n") b.WriteString("!\n") fmt.Fprintf(&b, "hostname %s\n", s.hostname) b.WriteString("!\n") b.WriteString("boot-start-marker\n") b.WriteString("boot-end-marker\n") b.WriteString("!\n") if s.enablePass != "" { b.WriteString("enable secret 5 $1$mERr$hx5rVt7rPNoS4wqbXKX7m0\n") } b.WriteString("!\n") b.WriteString("no aaa new-model\n") b.WriteString("!\n") for _, iface := range s.interfaces { b.WriteString("!\n") fmt.Fprintf(&b, "interface %s\n", iface.name) if iface.desc != "" { fmt.Fprintf(&b, " description %s\n", iface.desc) } if iface.ip != "unassigned" && iface.ip != "" { fmt.Fprintf(&b, " ip address %s %s\n", iface.ip, iface.mask) } else { b.WriteString(" no ip address\n") } if iface.shutdown { b.WriteString(" shutdown\n") } } b.WriteString("!\n") b.WriteString("ip forward-protocol nd\n") b.WriteString("!\n") b.WriteString("ip route 0.0.0.0 0.0.0.0 10.0.0.2\n") b.WriteString("!\n") b.WriteString("access-list 10 permit 192.168.1.0 0.0.0.255\n") b.WriteString("access-list 10 deny any\n") b.WriteString("!\n") b.WriteString("line con 0\n") b.WriteString(" logging synchronous\n") b.WriteString("line vty 0 4\n") b.WriteString(" login local\n") b.WriteString(" transport input ssh\n") b.WriteString("!\n") b.WriteString("end") return b.String() } func showVLANBrief() string { var b strings.Builder fmt.Fprintf(&b, "%-6s %-32s %-10s %s\n", "VLAN", "Name", "Status", "Ports") b.WriteString("---- -------------------------------- --------- -------------------------------\n") fmt.Fprintf(&b, "%-6s %-32s %-10s %s\n", "1", "default", "active", "Gi0/0, Gi0/1, Gi0/2") fmt.Fprintf(&b, "%-6s %-32s %-10s %s\n", "10", "MGMT", "active", "") fmt.Fprintf(&b, "%-6s %-32s %-10s %s\n", "20", "USERS", "active", "") fmt.Fprintf(&b, "%-6s %-32s %-10s %s\n", "99", "NATIVE", "active", "") fmt.Fprintf(&b, "%-6s %-32s %-10s %s\n", "1002", "fddi-default", "act/unsup", "") fmt.Fprintf(&b, "%-6s %-32s %-10s %s\n", "1003", "token-ring-default", "act/unsup", "") fmt.Fprintf(&b, "%-6s %-32s %-10s %s", "1004", "fddinet-default", "act/unsup", "") return b.String() } // networkFromIP derives the network address from an IP and mask. func networkFromIP(ip, mask string) string { ipParts := parseIPv4(ip) maskParts := parseIPv4(mask) if ipParts == nil || maskParts == nil { return ip } return fmt.Sprintf("%d.%d.%d.%d", ipParts[0]&maskParts[0], ipParts[1]&maskParts[1], ipParts[2]&maskParts[2], ipParts[3]&maskParts[3], ) } func maskBits(mask string) int { parts := parseIPv4(mask) if parts == nil { return 24 } bits := 0 for _, p := range parts { for i := 7; i >= 0; i-- { if p&(1<