// GetHexPorts gets all open ports as hex strings from /proc/net/{tcp,udp} // Its protocol argument can only be one of: "tcp" | "udp" func GetHexPorts(protocol string) (ports []string) { var path string switch strings.ToLower(protocol) { case "tcp": path = "/proc/net/tcp" case "udp": path = "/proc/net/udp" default: log.WithFields(log.Fields{ "protocol": protocol, "valid protocols": "tcp|udp", }).Fatal("Invalid protocol passed to GetHexPorts!") } data := chkutil.FileToString(path) rowSep := regexp.MustCompile(`\n+`) colSep := regexp.MustCompile(`\s+`) table := tabular.SeparateString(rowSep, colSep, data) localAddresses := tabular.GetColumnByHeader("local_address", table) portRe := regexp.MustCompile(`([0-9A-F]{8}):([0-9A-F]{4})`) for _, address := range localAddresses { port := portRe.FindString(address) if port != "" { if len(port) < 10 { log.WithFields(log.Fields{ "port": port, "length": len(port), }).Fatal("Couldn't parse port number in " + path) } portString := string(port[9:]) ports = append(ports, portString) } } return ports }
// swapOrMemory returns output from `free`, it is an abstraction of swap and // memory. inputs: status: free | used | total; swapOrMem: memory | swap; // units: b | kb | mb | gb | tb func swapOrMemory(status string, swapOrMem string, units string) (int, error) { unitsToFlag := map[string]string{ "b": "--bytes", "kb": "--kilo", "mb": "--mega", "gb": "--giga", "tb": "--tera", } typeToRow := map[string]int{ "memory": 0, "swap": 1, } // check to see that our keys are really in our dict if _, ok := unitsToFlag[units]; !ok { return 0, errors.New("Invalid units in swapOrMemory: " + units) } else if _, ok := typeToRow[swapOrMem]; !ok { return 0, errors.New("Invalid option in swapOrMemory: " + swapOrMem) } // execute free and return the appropriate output cmd := exec.Command("free", unitsToFlag[units]) out, err := cmd.CombinedOutput() if err != nil { return 0, err } // TODO probabalisticsplit isn't handling this appropriately //table := tabular.ProbabalisticSplit(outStr) colSep := regexp.MustCompile(`\s+`) rowSep := regexp.MustCompile(`\n+`) table := tabular.SeparateString(rowSep, colSep, string(out)) column := tabular.GetColumnByHeader(status, table) // filter out useless row from some versions of `free` for i, row := range table { if len(row) > 0 && strings.Contains(row[0], "-/+") { table = append(table[:i], table[i+1:]...) } } row := typeToRow[swapOrMem] // check for errors in output of `free` if column == nil || len(column) < 1 { errors.New("Free column was empty") } if row >= len(column) { errors.New("`free` didn't output enough rows") } toReturn, err := strconv.ParseInt(column[row], 10, 64) if err != nil { errors.New("Couldn't parse output of `free` as an int") } return int(toReturn), nil }
// Groups returns a slice of Group structs, parsed from /etc/group. func Groups() (groups []Group, err error) { path := "/etc/group" data, err := ioutil.ReadFile(path) if err != nil { return groups, err } rowSep := regexp.MustCompile(`\n`) colSep := regexp.MustCompile(`:`) lines := tabular.SeparateString(rowSep, colSep, string(data)) commaRegexp := regexp.MustCompile(`,`) for _, line := range lines { if len(line) > 3 { // only lines that have all fields (non-empty) gid, err := strconv.ParseInt(line[2], 10, 64) if err != nil { return groups, err } userSlice := commaRegexp.Split(line[3], -1) group := Group{Name: line[0], ID: int(gid), Users: userSlice} groups = append(groups, group) } } return groups, nil }
// getGroups returns a list of Group structs, as parsed from /etc/group func getGroups() (groups []Group) { path := "/etc/group" data := wrkutils.FileToString(path) rowSep := regexp.MustCompile(`\n`) colSep := regexp.MustCompile(`:`) lines := tabular.SeparateString(rowSep, colSep, data) commaRegexp := regexp.MustCompile(`,`) for _, line := range lines { if len(line) > 3 { // only lines that have all fields (non-empty) gid, err := strconv.ParseInt(line[2], 10, 64) if err != nil { log.WithFields(log.Fields{ "group": line[0], "path": path, }).Fatal("Could not parse ID for group") } userSlice := commaRegexp.Split(line[3], -1) group := Group{Name: line[0], ID: int(gid), Users: userSlice} groups = append(groups, group) } } return groups }