package asaModels import ( "fmt" "regexp" "strconv" "strings" ) var ( HASHRE = regexp.MustCompile(`(?i)access-list\s+(.*?);\s+([0-9]+)\s+elements;\s+name\s+hash:\s+(0x\S+)`) ACLRULERE = regexp.MustCompile(`(?i)line\s+([0-9]+)\s+(extended.*?)\s+\(hitcnt=([0-9]+)\)\s+(\S+).*?(\n|$)`) SHOWACLRE = regexp.MustCompile(`(?i)(\s+|)access-list\s+(\S+)\s+line\s+([0-9]+)\s+(.*?)\s+\(hitcnt=([0-9]+)\)\s+(0x\S+)`) SHOWACLOBJRE = regexp.MustCompile(`(?i)(\s+|)access-list\s+(\S+)\s+line\s+([0-9]+)\s+(.*?object-group.*?)\s+(0x\S+)`) ) type ( ShowAccessLists struct { AccessLists []*ShowAccessList `json:"show_access_list"` } ShowAccessList struct { Name string `json:"name"` Elements int `json:"elements"` Hash string `json:"hash"` Rules []*AccessListRule `json:"rules"` } AccessListRule struct { Line int `json:"line"` Rule string `json:"rule"` Hits int `json:"hit_count"` Hash string `json:"hash"` RuleItems []*AccessListItem `json:"rule_items"` } AccessListItem struct { Line int `json:"line"` Rule string `json:"rule"` Hits int `json:"hit_count"` Hash string `json:"hash"` } ) func ParseShowAccessLists(s string) ShowAccessLists { var a ShowAccessLists a.Parse(s) return a } func (a *ShowAccessLists) Parse(s string) { elements := make(map[string]*ShowAccessList) rules := make(map[string][]*AccessListRule) for _, l := range strings.Split(s, "\n") { l = strings.TrimRight(l, " ") if !ParseShowRule(l, rules) { ParseShowBase(l, elements) } } for name, rule := range elements { if rs, ok := rules[name]; ok { rule.Rules = rs a.AccessLists = append(a.AccessLists, rule) } } } func ParseShowBase(l string, rules map[string]*ShowAccessList) (f bool) { m := HASHRE.FindStringSubmatch(l) if len(m) == 0 { return } n, _ := strconv.Atoi(m[2]) if _, ok := rules[m[1]]; !ok { rules[m[1]] = &ShowAccessList{ Name: m[1], Elements: n, Hash: m[3], } } return true } func ParseShowRule(l string, rules map[string][]*AccessListRule) (f bool) { m := SHOWACLRE.FindStringSubmatch(l) if len(m) == 0 { return ParseObjectDestRule(l, rules) } f = true n, _ := strconv.Atoi(m[3]) c, _ := strconv.Atoi(m[6]) switch m[1] { case "": rules[m[2]] = append(rules[m[2]], &AccessListRule{ Line: n, Hits: c, Rule: m[4], Hash: m[6], }) return default: for _, r := range rules[m[2]] { n, _ := strconv.Atoi(m[3]) if r.Line == n { r.RuleItems = append(r.RuleItems, &AccessListItem{ Line: n, Hits: c, Rule: m[4], Hash: m[6], }) } } return } } func ParseObjectDestRule(l string, rules map[string][]*AccessListRule) (f bool) { m := SHOWACLOBJRE.FindStringSubmatch(l) if len(m) == 0 { return false } f = true n, _ := strconv.Atoi(m[3]) rules[m[2]] = append(rules[m[2]], &AccessListRule{ Line: n, Rule: m[4], Hash: m[5], }) return } // returns a string of the base rule func (s *ShowAccessList) BaseRuleString(rule *AccessListRule) string { if rule != nil { return fmt.Sprintf("access-list %s line %d %s", s.Name, rule.Line, rule.Rule) } return "" } // returns a string of the rule item func (s *ShowAccessList) RuleItemString(ri *AccessListItem) string { if ri != nil { return fmt.Sprintf("access-list %s line %d %s", s.Name, ri.Line, ri.Rule) } return "" } func (a *ShowAccessLists) FindACL(name string) *ShowAccessList { for _, acl := range a.AccessLists { if acl.Name == name { return acl } } return nil }