package asaModels import ( //"github.com/sirupsen/logrus" "errors" "regexp" "strconv" "strings" //"fmt" //"bytes" //"text/template" ) type ( // Capture represents data about a packet capture running on an ASA. Capture struct { Trace bool `json:"trace,omitempty"` // trace on or off CircularBuffer bool `json:"circular-buffer,omitempty"` // circular buffer used or not Bytes int `json:"bytes"` // bytes captured so far PacketLength int `json:"packet-length,omitempty"` // packet length upper limit in bytes Buffer int `json:"buffer,omitempty"` // buffer size in bytes AccessList string `json:"access-list,omitempty"` // name of access-list filtering the capture EthernetType string `json:"ethernet-type,omitempty"` // e.g. "ip" or "arp" Interface string `json:"interface,omitempty"` // name of interface on which capture listens Name string `json:"name"` // name of capture Status string `json:"status"` // e.g. "Capturing" or "Buffer Full" Type string `json:"type"` // e.g. "raw-data", "isakmp ikev1", or "asp-drop acl-drop" Match []Match `json:"match,omitempty"` // slice of match criteria } // Match represents one line of packet capture match criteria on an ASA. Currently just a string. Match string //// CaptureData represents the contents of a packet capture running on an ASA. //CaptureData struct { // CaptureName string `json:"capture_name"` // Packets []Packet `json:"packets"` //} // //// Packet represents a packet captured on an ASA. Currently just a string. //Packet string ) // CaptureDataPattern is regex to parse the output of "show capture " on an ASA. //CaptureDataPattern = regexp.MustCompile(`\d+: (.*)`) // ParseCaptures parses the output of "show capture" on an ASA and returns a slice of `Capture`s. func ParseCaptures(s string) ([]Capture, error) { var cs []Capture var c Capture var capPattern = regexp.MustCompile( `capture (\S+) ` + `type (asp-drop \S+|isakmp(?: ikev[12])?|raw-data|tls-proxy)` + `(?: ethernet-type (\S+))?` + `(?: access-list (\S+))?` + `(?: buffer (\d+))?` + `(?: packet-length (\d+))?` + `(?: (trace))?` + `(?: interface (\S+))?` + `(?: (circular-buffer))?` + ` \[(.*?) - (\d+) bytes\]`) lines := strings.Split(s, "\n") if len(lines) < 1 { return cs, errors.New("can't parse capture from empty string") } for i := range lines { line := lines[i] if strings.HasPrefix(line, ` match`) { // Lines that start with ` match` are part of the preceding capture definition. if c.Name == "" { return cs, errors.New("match criteria appear before capture declaration") } txt := line[2:] m := Match(txt) c.Match = append(c.Match, m) } else if strings.HasPrefix(line, `capture`) { // Lines that start with `capture` are capture definitions. if c.Name != "" { // If the current Capture struct has already been populated, push it off to the slice before parsing a new Capture. cs = append(cs, c) c = Capture{} } // Populate the Capture struct using regex match groups. ms := capPattern.FindStringSubmatch(line) c.Name = ms[1] c.Type = ms[2] c.EthernetType = ms[3] c.AccessList = ms[4] c.Buffer, _ = strconv.Atoi(ms[5]) c.PacketLength, _ = strconv.Atoi(ms[6]) c.Trace = bool(ms[7] != "") c.Interface = ms[8] c.CircularBuffer = bool(ms[9] != "") c.Status = ms[10] c.Bytes, _ = strconv.Atoi(ms[11]) } else { // Lines that start with neither ` match` nor `capture` are not acceptable. return cs, errors.New("line does not appear to be from `show capture` output") } } cs = append(cs, c) return cs, nil } // StrpCapture produces a string in ASA config syntax format from a Capture struct. //// WARNING: Function is experimental //func StrpCapture(c Capture) (string, error){ // var buf bytes.Buffer // tmpl, _ := template.New("test").Parse( // "capture {{.Name}}" + // "type {{.Type}} ethernet-type {{.EthernetType}} access-list {{.AccessList}}" + // "buffer {{.Buffer}} packet-length {{.PacketLength}} {{.Trace}} interface {{.Interface}} {{.CircularBuffer}}"+ // "{{.Match}}") // _ := tmpl.Execute(&buf, c) // return buf.String(), nil //} // ValidateCapture returns nil if the given Capture struct can be converted to valid ASA config. func ValidateCapture(c Capture) error { return nil } func (c Capture) Validate() error { return ValidateCapture(c) } //func (c Capture) Strp() (string, error) { // return StrpCapture(c) //}