package sysdig import ( "encoding/csv" "fmt" "io" "log" "net" "strconv" "strings" ) const ( RX = iota TX ) type Record struct { Host, Container, Process string Pid, Tid uint64 Proto string ServerIp net.IP ServerPort uint16 ClientIp net.IP ClientPort uint16 Direction int Bytes uint64 } func ParseOutput(result string) ([]Record, error) { r := csv.NewReader(strings.NewReader(result)) r.Comma = '\t' var records []Record for { record, err := r.Read() if err == io.EOF { break } if err != nil { log.Fatal(err) } if record[0] == "host" { continue } pid, err := strconv.ParseUint(record[3], 10, 64) if err != nil { return nil, fmt.Errorf("invalid pid %s: %v", record[2], err) } tid, err := strconv.ParseUint(record[4], 10, 64) if err != nil { return nil, fmt.Errorf("invalid tid %s: %v", record[3], err) } sip := net.ParseIP(record[6]) if sip == nil { return nil, fmt.Errorf("invalid ip '%s'", record[6]) } sport, err := strconv.ParseUint(record[7], 10, 16) if err != nil { return nil, fmt.Errorf("invalid port %s: %v", record[7], err) } cip := net.ParseIP(record[8]) if cip == nil { return nil, fmt.Errorf("invalid ip '%s'", record[8]) } cport, err := strconv.ParseUint(record[9], 10, 16) if err != nil { return nil, fmt.Errorf("invalid port %s: %v", record[9], err) } var direction int if record[10] == "rx" { direction = RX } else { direction = TX } bytes, err := strconv.ParseUint(record[11], 10, 64) if err != nil { return nil, fmt.Errorf("invalid transmission size %s: %v", record[11], err) } records = append(records, Record{ record[0], record[1], record[2], pid, tid, record[5], sip, uint16(sport), cip, uint16(cport), direction, bytes, }) } return records, nil }