package asaModels import ( "fmt" "net" "regexp" "github.rackspace.com/gorax/tools/util" ) var ( connectedRouteRE = regexp.MustCompile(`(?i)C[ ]+(\S+)\s+(\S+)\s+is\s+directly\s+connected,\s+(\S+)`) staticRouteRe = regexp.MustCompile(`(?i)S(\*|)[ ]+(\S+)\s+(\S+)\s+\[(.*?)\]\s+via\s+(\S+),\s+(\S+)`) bgpRouteRe = regexp.MustCompile(`(?i)B[ ]+(\S+)\s+(\S+)\s+\[(.*?)\]\s+via\s+(\S+),\s+(\S+)`) eigrpextRouteRe = regexp.MustCompile(`(?i)D\sEX[ ]+(\S+)\s+(\S+)\s+\[(.*?)\]\s+via\s+(\S+),\s+(\S+)\s(\S+)`) eigrpRouteRe = regexp.MustCompile(`(?i)D\s[ ]+(\S+)\s+(\S+)\s+\[(.*?)\]\s+via\s+(\S+),\s+(\S+)\s(\S+)`) ) type RouteTable struct { Routes []*RouteEntry `json:"routes"` } type RouteEntry struct { Type string `json:"type"` Network string `json:"network"` Netmask string `json:"netmask"` NextHop string `json:"next_hop"` IfName string `json:"interface"` LastResort bool `json:"last_resort"` ipn *net.IPNet } func (r RouteEntry) String() string { return fmt.Sprintf("%s %s %s %s %s", r.Type, r.Network, r.Netmask, r.NextHop, r.IfName) } func ParseRouteTable(s string) RouteTable { var rt RouteTable rt.Parse(s) return rt } func (r *RouteTable) Parse(s string) { for _, v := range connectedRouteRE.FindAllStringSubmatch(s, -1) { r.Routes = append(r.Routes, &RouteEntry{ Type: "connected", Network: v[1], Netmask: v[2], IfName: v[3], NextHop: "self", LastResort: v[1] == "*", }) } for _, v := range staticRouteRe.FindAllStringSubmatch(s, -1) { r.Routes = append(r.Routes, &RouteEntry{ Type: "static", Network: v[2], Netmask: v[3], NextHop: v[5], IfName: v[6], LastResort: v[1] == "*", }) } for _, v := range bgpRouteRe.FindAllStringSubmatch(s, -1) { r.Routes = append(r.Routes, &RouteEntry{ Type: "bgp", Network: v[1], Netmask: v[2], NextHop: v[4], }) } for _, v := range eigrpextRouteRe.FindAllStringSubmatch(s, -1) { r.Routes = append(r.Routes, &RouteEntry{ Type: "eigrp_external", Network: v[1], Netmask: v[2], NextHop: v[4], IfName: v[6], }) } for _, v := range eigrpRouteRe.FindAllStringSubmatch(s, -1) { r.Routes = append(r.Routes, &RouteEntry{ Type: "eigrp", Network: v[1], Netmask: v[2], NextHop: v[4], IfName: v[6], }) } } func (r *RouteEntry) Contains(ip net.IP) bool { if r.LastResort { return false } if r.ipn == nil { ipn, err := util.IPNetwork(r.Network, r.Netmask) if err != nil { return false } r.ipn = ipn } return r.ipn.Contains(ip) }