func ProtoCounters(protocols []string) ([]ProtoCountersStat, error) {
	return nil, errors.New("NetProtoCounters not implemented for darwin")
}
NetProtoCounters returns network statistics for the entire system
If protocols is empty then all protocols are returned, otherwise
just the protocols in the list are returned.
Not Implemented for Darwin
package net
import (
	"errors"
	"fmt"
	"os/exec"
	"regexp"
	"strconv"
	"strings"
)
var (
	errNetstatHeader  = errors.New("Can't parse header of netstat output")
	netstatLinkRegexp = regexp.MustCompile(`^<Link#(\d+)>$`)
)
const endOfLine = "\n"
func parseNetstatLine(line string) (stat *IOCountersStat, linkId *uint, err error) {
	var (
		numericValue uint64
		columns      = strings.Fields(line)
	)
	if columns[0] == "Name" {
		err = errNetstatHeader
		return
	}
	if subMatch := netstatLinkRegexp.FindStringSubmatch(columns[2]); len(subMatch) == 2 {
		numericValue, err = strconv.ParseUint(subMatch[1], 10, 64)
		if err != nil {
			return
		}
		linkIdUint := uint(numericValue)
		linkId = &linkIdUint
	}
	base := 1
	numberColumns := len(columns)
	if numberColumns < 12 {
		base = 0
	}
	if numberColumns < 11 || numberColumns > 13 {
		err = fmt.Errorf("Line %q do have an invalid number of columns %d", line, numberColumns)
		return
	}
	parsed := make([]uint64, 0, 7)
	vv := []string{
		columns[base+3],  
		columns[base+4],  
		columns[base+5],  
		columns[base+6],  
		columns[base+7],  
		columns[base+8],  
	}
	if len(columns) == 12 {
		vv = append(vv, columns[base+10])
	}
	for _, target := range vv {
		if target == "-" {
			parsed = append(parsed, 0)
			continue
		}
		if numericValue, err = strconv.ParseUint(target, 10, 64); err != nil {
			return
		}
		parsed = append(parsed, numericValue)
	}
	stat = &IOCountersStat{
		Name:        strings.Trim(columns[0], "*"),  
		PacketsRecv: parsed[0],
		Errin:       parsed[1],
		BytesRecv:   parsed[2],
		PacketsSent: parsed[3],
		Errout:      parsed[4],
		BytesSent:   parsed[5],
	}
	if len(parsed) == 7 {
		stat.Dropout = parsed[6]
	}
	return
}
type netstatInterface struct {
	linkId *uint
	stat   *IOCountersStat
}
func parseNetstatOutput(output string) ([]netstatInterface, error) {
	var (
		err   error
		lines = strings.Split(strings.Trim(output, endOfLine), endOfLine)
	)
	numberInterfaces := len(lines) - 1
	interfaces := make([]netstatInterface, numberInterfaces)
	if numberInterfaces == 0 {
		return interfaces, nil
	}
	for index := 0; index < numberInterfaces; index++ {
		nsIface := netstatInterface{}
		if nsIface.stat, nsIface.linkId, err = parseNetstatLine(lines[index+1]); err != nil {
			return nil, err
		}
		interfaces[index] = nsIface
	}
	return interfaces, nil
}
type mapInterfaceNameUsage map[string]uint
func newMapInterfaceNameUsage(ifaces []netstatInterface) mapInterfaceNameUsage {
	output := make(mapInterfaceNameUsage)
	for index := range ifaces {
		if ifaces[index].linkId != nil {
			ifaceName := ifaces[index].stat.Name
			usage, ok := output[ifaceName]
			if ok {
				output[ifaceName] = usage + 1
			} else {
				output[ifaceName] = 1
			}
		}
	}
	return output
}
func (min mapInterfaceNameUsage) isTruncated() bool {
	for _, usage := range min {
		if usage > 1 {
			return true
		}
	}
	return false
}
func (min mapInterfaceNameUsage) notTruncated() []string {
	output := make([]string, 0)
	for ifaceName, usage := range min {
		if usage == 1 {
			output = append(output, ifaceName)
		}
	}
	return output
}
func IOCounters(pernic bool) ([]IOCountersStat, error) {
	var (
		ret      []IOCountersStat
		retIndex int
	)
	netstat, err := exec.LookPath("/usr/sbin/netstat")
	if err != nil {
		return nil, err
	}
	out, err := invoke.Command(netstat, "-ibdnW")
	if err != nil {
		return nil, err
	}
	nsInterfaces, err := parseNetstatOutput(string(out))
	if err != nil {
		return nil, err
	}
	ifaceUsage := newMapInterfaceNameUsage(nsInterfaces)
	notTruncated := ifaceUsage.notTruncated()
	ret = make([]IOCountersStat, len(notTruncated))
	if !ifaceUsage.isTruncated() {
		for index := range nsInterfaces {
			if nsInterfaces[index].linkId != nil {
				ret[retIndex] = *nsInterfaces[index].stat
				retIndex++
			}
		}
	} else {
		ifconfig, err := exec.LookPath("/sbin/ifconfig")
		if err != nil {
			return nil, err
		}
		if out, err = invoke.Command(ifconfig, "-l"); err != nil {
			return nil, err
		}
		interfaceNames := strings.Fields(strings.TrimRight(string(out), endOfLine))
		for _, interfaceName := range interfaceNames {
			truncated := true
			for index := range nsInterfaces {
				if nsInterfaces[index].linkId != nil && nsInterfaces[index].stat.Name == interfaceName {
					ret[retIndex] = *nsInterfaces[index].stat
					retIndex++
					truncated = false
					break
				}
			}
			if truncated {
				if out, err = invoke.Command(netstat, "-ibdnWI"+interfaceName); err != nil {
					return nil, err
				}
				parsedIfaces, err := parseNetstatOutput(string(out))
				if err != nil {
					return nil, err
				}
				if len(parsedIfaces) == 0 {
					continue
				}
				for index := range parsedIfaces {
					if parsedIfaces[index].linkId != nil {
						ret = append(ret, *parsedIfaces[index].stat)
						break
					}
				}
			}
		}
	}
	if pernic == false {
		return getIOCountersAll(ret)
	}
	return ret, nil
}
func IOCountersByFile(pernic bool, filename string) ([]IOCountersStat, error) {
	return IOCounters(pernic)
}
func FilterCounters() ([]FilterStat, error) {
	return nil, errors.New("NetFilterCounters not implemented for darwin")
}