Skip to content

Commit

Permalink
Merge pull request #3 from IvanKuchin/development
Browse files Browse the repository at this point in the history
Feature: added routing table parsing
  • Loading branch information
IvanKuchin authored May 1, 2023
2 parents d52f810 + d1fd76d commit d0a13aa
Show file tree
Hide file tree
Showing 17 changed files with 839 additions and 345 deletions.
2 changes: 1 addition & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"request": "launch",
"mode": "auto",
"program": "${workspaceFolder}/main.go",
"args": ["-r", "examples/sh_run.prod", "-s", "examples/syslog"],
"args": ["-r", "examples/sh_run", "-s", "examples/syslog", "-i", "examples/sh_ip_route"],
}
]
}
27 changes: 27 additions & 0 deletions examples/sh_ip_route
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
ciscoasa(config)# sh route

Codes: L - local, C - connected, S - static, R - RIP, M - mobile, B - BGP
D - EIGRP, EX - EIGRP external, O - OSPF, IA - OSPF inter area
N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2
E1 - OSPF external type 1, E2 - OSPF external type 2, V - VPN
i - IS-IS, su - IS-IS summary, L1 - IS-IS level-1, L2 - IS-IS level-2
ia - IS-IS inter area, * - candidate default, U - per-user static route
o - ODR, P - periodic downloaded static route, + - replicated route
SI - Static InterVRF
Gateway of last resort is 123.123.123.2 to network 0.0.0.0

S* 0.0.0.0 0.0.0.0 [1/0] via 123.123.123.2, outside
B 10.10.9.0 255.255.255.0 [200/0] via 192.168.0.2, 00:07:01
C 123.123.123.0 255.255.255.0 is directly connected, outside
L 123.123.123.1 255.255.255.255 is directly connected, outside
C 192.168.0.0 255.255.255.0 is directly connected, inside
L 192.168.0.1 255.255.255.255 is directly connected, inside
S 200.200.200.0 255.255.255.0 [1/0] via 123.123.123.3, outside

C 10.0.0.0 255.0.0.0 is directly connected, inside
C 10.11.0.0 255.255.0.0 is directly connected, inside
C 10.21.0.0 255.255.0.0 is directly connected, inside
C 10.31.0.0 255.255.0.0 is directly connected, inside
C 10.11.12.0 255.255.255.0 is directly connected, inside
C 10.11.13.0 255.255.255.0 is directly connected, inside
C 10.11.14.0 255.255.255.0 is directly connected, inside
178 changes: 24 additions & 154 deletions internal/cisco-asa-access-list/cisco-asa-access-entry/address_object.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,134 +6,15 @@ import (
"fmt"
"log"
"net"
"net/netip"
"strconv"
"strings"

sh_run_pipe "github.com/ivankuchin/excessive-acl/internal/cisco-asa-access-list/sh-run-pipe"
"github.com/ivankuchin/excessive-acl/internal/utils"
)

func parseIP(ip_str string) (uint32, error) {

ipAddr, err := netip.ParseAddr(ip_str)
if err != nil {
error_string := "ERROR: failed to parse ip address"
log.Print(error_string, "(", ip_str, ")")
return 0, errors.New(error_string)
}

if ipAddr.Is6() {
error_string := "ERROR: ipv6 not implemented"
log.Print(error_string)
return 0, errors.New(error_string)
}

octets := ipAddr.As4()
return uint32(octets[0])<<24 + uint32(octets[1])<<16 + uint32(octets[2])<<8 + uint32(octets[3]), nil
}

func parseMask(mask_str string) (uint32, error) {
switch mask_str {
case "0.0.0.0":
return uint32(0)<<24 + uint32(0)<<16 + uint32(0)<<8 + uint32(0), nil
case "128.0.0.0":
return uint32(128)<<24 + uint32(0)<<16 + uint32(0)<<8 + uint32(0), nil
case "192.0.0.0":
return uint32(192)<<24 + uint32(0)<<16 + uint32(0)<<8 + uint32(0), nil
case "224.0.0.0":
return uint32(224)<<24 + uint32(0)<<16 + uint32(0)<<8 + uint32(0), nil
case "240.0.0.0":
return uint32(240)<<24 + uint32(0)<<16 + uint32(0)<<8 + uint32(0), nil
case "248.0.0.0":
return uint32(248)<<24 + uint32(0)<<16 + uint32(0)<<8 + uint32(0), nil
case "252.0.0.0":
return uint32(252)<<24 + uint32(0)<<16 + uint32(0)<<8 + uint32(0), nil
case "254.0.0.0":
return uint32(254)<<24 + uint32(0)<<16 + uint32(0)<<8 + uint32(0), nil
case "255.0.0.0":
return uint32(255)<<24 + uint32(0)<<16 + uint32(0)<<8 + uint32(0), nil
case "255.128.0.0":
return uint32(255)<<24 + uint32(128)<<16 + uint32(0)<<8 + uint32(0), nil
case "255.192.0.0":
return uint32(255)<<24 + uint32(192)<<16 + uint32(0)<<8 + uint32(0), nil
case "255.224.0.0":
return uint32(255)<<24 + uint32(224)<<16 + uint32(0)<<8 + uint32(0), nil
case "255.240.0.0":
return uint32(255)<<24 + uint32(240)<<16 + uint32(0)<<8 + uint32(0), nil
case "255.248.0.0":
return uint32(255)<<24 + uint32(248)<<16 + uint32(0)<<8 + uint32(0), nil
case "255.252.0.0":
return uint32(255)<<24 + uint32(252)<<16 + uint32(0)<<8 + uint32(0), nil
case "255.254.0.0":
return uint32(255)<<24 + uint32(254)<<16 + uint32(0)<<8 + uint32(0), nil
case "255.255.0.0":
return uint32(255)<<24 + uint32(255)<<16 + uint32(0)<<8 + uint32(0), nil
case "255.255.128.0":
return uint32(255)<<24 + uint32(255)<<16 + uint32(128)<<8 + uint32(0), nil
case "255.255.192.0":
return uint32(255)<<24 + uint32(255)<<16 + uint32(192)<<8 + uint32(0), nil
case "255.255.224.0":
return uint32(255)<<24 + uint32(255)<<16 + uint32(224)<<8 + uint32(0), nil
case "255.255.240.0":
return uint32(255)<<24 + uint32(255)<<16 + uint32(240)<<8 + uint32(0), nil
case "255.255.248.0":
return uint32(255)<<24 + uint32(255)<<16 + uint32(248)<<8 + uint32(0), nil
case "255.255.252.0":
return uint32(255)<<24 + uint32(255)<<16 + uint32(252)<<8 + uint32(0), nil
case "255.255.254.0":
return uint32(255)<<24 + uint32(255)<<16 + uint32(254)<<8 + uint32(0), nil
case "255.255.255.0":
return uint32(255)<<24 + uint32(255)<<16 + uint32(255)<<8 + uint32(0), nil
case "255.255.255.128":
return uint32(255)<<24 + uint32(255)<<16 + uint32(255)<<8 + uint32(128), nil
case "255.255.255.192":
return uint32(255)<<24 + uint32(255)<<16 + uint32(255)<<8 + uint32(192), nil
case "255.255.255.224":
return uint32(255)<<24 + uint32(255)<<16 + uint32(255)<<8 + uint32(224), nil
case "255.255.255.240":
return uint32(255)<<24 + uint32(255)<<16 + uint32(255)<<8 + uint32(240), nil
case "255.255.255.248":
return uint32(255)<<24 + uint32(255)<<16 + uint32(255)<<8 + uint32(248), nil
case "255.255.255.252":
return uint32(255)<<24 + uint32(255)<<16 + uint32(255)<<8 + uint32(252), nil
case "255.255.255.254":
return uint32(255)<<24 + uint32(255)<<16 + uint32(255)<<8 + uint32(254), nil
case "255.255.255.255":
return uint32(255)<<24 + uint32(255)<<16 + uint32(255)<<8 + uint32(255), nil
default:
error_string := "ERROR: failed to parse mask"
log.Print(error_string, "(", mask_str, ")")
return 0, errors.New(error_string)
}
}

func parseSubnet(parsing_pos uint, fields []string) (uint, addressObject, error) {
var _address_object addressObject

if len(fields) < int(parsing_pos+2) {
error_string := "ERROR: not enough fields to parse subnet"
log.Print(error_string, "(", fields, ")")
return 0, _address_object, errors.New(error_string)
}

ip, err := parseIP(fields[parsing_pos])
if err != nil {
return 0, _address_object, err
}

mask, err := parseMask(fields[parsing_pos+1])
if err != nil {
return 0, _address_object, err
}

_address_object.start = ip & mask
_address_object.finish = ip | ^mask

return parsing_pos + 2, _address_object, nil
}

func parseFQDN(fqdn string) ([]addressObject, error) {
var _address_objects []addressObject
func parseFQDN(fqdn string) ([]utils.AddressObject, error) {
var _address_objects []utils.AddressObject

ips, err := net.LookupIP(fqdn)
if err != nil {
Expand All @@ -147,15 +28,15 @@ func parseFQDN(fqdn string) ([]addressObject, error) {
fmt.Printf("Skipping IPv6 address: %s in %s name resolution\n", ip.String(), fqdn)
continue
}
_address_object := addressObject{start: binary.BigEndian.Uint32(ip.To4()), finish: binary.BigEndian.Uint32(ip.To4())}
_address_object := utils.AddressObject{Start: binary.BigEndian.Uint32(ip.To4()), Finish: binary.BigEndian.Uint32(ip.To4())}
_address_objects = append(_address_objects, _address_object)
}

return _address_objects, nil
}

func parseAddressObjectContent(fields []string) ([]addressObject, error) {
var _address_objects []addressObject
func parseAddressObjectContent(fields []string) ([]utils.AddressObject, error) {
var _address_objects []utils.AddressObject

switch fields[0] {
case "fqdn":
Expand All @@ -178,11 +59,11 @@ func parseAddressObjectContent(fields []string) ([]addressObject, error) {
return nil, errors.New(error_string)
}

ip, err := parseIP(fields[1])
ip, err := utils.ParseIP(fields[1])
if err != nil {
return nil, err
}
_address_objects = append(_address_objects, addressObject{start: ip, finish: ip})
_address_objects = append(_address_objects, utils.AddressObject{Start: ip, Finish: ip})

return _address_objects, nil
case "subnet":
Expand All @@ -192,7 +73,7 @@ func parseAddressObjectContent(fields []string) ([]addressObject, error) {
return nil, errors.New(error_string)
}

_, _address_object, err := parseSubnet(1, fields)
_, _address_object, err := utils.ParseSubnet(1, fields)
if err != nil {
return nil, err
}
Expand All @@ -206,17 +87,17 @@ func parseAddressObjectContent(fields []string) ([]addressObject, error) {
return nil, errors.New(error_string)
}

start, err := parseIP(fields[1])
start, err := utils.ParseIP(fields[1])
if err != nil {
return nil, err
}

finish, err := parseIP(fields[2])
finish, err := utils.ParseIP(fields[2])
if err != nil {
return nil, err
}

_address_objects = append(_address_objects, addressObject{start: start, finish: finish})
_address_objects = append(_address_objects, utils.AddressObject{Start: start, Finish: finish})

return _address_objects, nil
default:
Expand All @@ -226,7 +107,7 @@ func parseAddressObjectContent(fields []string) ([]addressObject, error) {
}
}

func parseAddressObject(name string) ([]addressObject, error) {
func parseAddressObject(name string) ([]utils.AddressObject, error) {
address_object_text := sh_run_pipe.SectionExact("object network " + name).Exclude("object network " + name).Exclude("description ").Exclude(" nat ")
if address_object_text.Len() != 1 {
error_message := "object network must have only 1 line in it. object network " + name + " is " + strconv.Itoa(int(address_object_text.Len())) + " lines."
Expand All @@ -243,8 +124,8 @@ func parseAddressObject(name string) ([]addressObject, error) {
return parseAddressObjectContent(fields)
}

func parseAddressObjectGroup(name string) ([]addressObject, error) {
var address_object_group []addressObject
func parseAddressObjectGroup(name string) ([]utils.AddressObject, error) {
var address_object_group []utils.AddressObject

address_object_group_text := sh_run_pipe.SectionExact("object-group network " + name).Exclude("object-group network " + name).Exclude("description ")
if address_object_group_text.Len() == 0 {
Expand Down Expand Up @@ -296,7 +177,7 @@ func parseAddressObjectGroup(name string) ([]addressObject, error) {
return nil, errors.New(error_string)
}

_, _ao, err := parseSubnet(1, fields)
_, _ao, err := utils.ParseSubnet(1, fields)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -326,8 +207,8 @@ func parseAddressObjectGroup(name string) ([]addressObject, error) {
return address_object_group, nil
}

func getAddressObjects(parsing_pos uint, fields []string) (uint, []addressObject, error) {
var address_objects []addressObject
func getAddressObjects(parsing_pos uint, fields []string) (uint, []utils.AddressObject, error) {
var address_objects []utils.AddressObject

switch fields[parsing_pos] {
case "object":
Expand Down Expand Up @@ -362,23 +243,23 @@ func getAddressObjects(parsing_pos uint, fields []string) (uint, []addressObject
parsing_pos += 2

case "any4":
address_objects = append(address_objects, addressObject{0, 0xffffffff})
address_objects = append(address_objects, utils.AddressObject{Start: 0, Finish: 0xffffffff})

// --- set parsing position to a next block
parsing_pos += 1

case "any":
address_objects = append(address_objects, addressObject{0, 0xffffffff})
address_objects = append(address_objects, utils.AddressObject{Start: 0, Finish: 0xffffffff})

// --- set parsing position to a next block
parsing_pos += 1

case "host":
ip, err := parseIP(fields[parsing_pos+1])
ip, err := utils.ParseIP(fields[parsing_pos+1])
if err != nil {
return 0, nil, err
}
address_objects = append(address_objects, addressObject{ip, ip})
address_objects = append(address_objects, utils.AddressObject{Start: ip, Finish: ip})

// --- set parsing position to a next block
parsing_pos += 2
Expand All @@ -399,9 +280,9 @@ func getAddressObjects(parsing_pos uint, fields []string) (uint, []addressObject
return 0, nil, errors.New(error_string)

default:
var _address_object addressObject
var _address_object utils.AddressObject
var err error
parsing_pos, _address_object, err = parseSubnet(parsing_pos, fields)
parsing_pos, _address_object, err = utils.ParseSubnet(parsing_pos, fields)
if err != nil {
return 0, nil, err
}
Expand All @@ -410,14 +291,3 @@ func getAddressObjects(parsing_pos uint, fields []string) (uint, []addressObject

return parsing_pos, address_objects, nil
}

func ipToString(ip uint32) string {
return fmt.Sprintf("%d.%d.%d.%d", byte(ip>>24), byte(ip>>16), byte(ip>>8), byte(ip))
}

func (a *addressObject) print() {
ip1 := ipToString(a.start)
ip2 := ipToString(a.finish)
s := fmt.Sprintf("prefix: %v -> %v ", ip1, ip2)
log.Print(s)
}
Loading

0 comments on commit d0a13aa

Please sign in to comment.