Skip to content

Commit

Permalink
Updated statistics parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
PacketCrunch committed Dec 8, 2022
1 parent af0f456 commit eece0c7
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 8 deletions.
9 changes: 9 additions & 0 deletions lib_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -274,3 +274,12 @@ func TestCounter(t *testing.T) {
t.Errorf("Counter get got %d of expected %d", idx, 2)
}
}

func TestIfStat(t *testing.T) {
var ifs IfiStat

err := NetGetIfiStats("eth0", &ifs)
if err != 0 {
t.Errorf("Get stats failed for eth0")
}
}
87 changes: 79 additions & 8 deletions netutils.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,48 @@
package loxilib

import (
"bufio"
"bytes"
"encoding/binary"
"errors"
"net"
"unsafe"
"os"
"strconv"
"strings"
"syscall"
"errors"
"bytes"
"unsafe"
)

// constants related to ifstats
const (
RxBytes = iota
RxPkts
RxErrors
RxDrops
RxFifo
RxFrame
RxComp
RxMcast
TxBytes
TxPkts
TxErrors
TxDrops
TxFifo
TxColls
TxCarr
TxComp
MaxSidx
)

const (
OsIfStatFile = "/proc/net/dev"
)

// IfiStat - Container of interface statistics
type IfiStat struct {
Ifs [MaxSidx]uint64
}

// Ntohl - Network to host byte-order long
func Ntohl(i uint32) uint32 {
return binary.BigEndian.Uint32((*(*[4]byte)(unsafe.Pointer(&i)))[:])
Expand All @@ -36,7 +70,7 @@ func Ntohs(i uint16) uint16 {
return binary.BigEndian.Uint16((*(*[2]byte)(unsafe.Pointer(&i)))[:])
}

// IPtonl - Convert net.IP to network byte-order long
// IPtonl - Convert net.IP to network byte-order long
func IPtonl(ip net.IP) uint32 {
var val uint32

Expand Down Expand Up @@ -69,7 +103,7 @@ func NltoIP(addr uint32) net.IP {

// ArpPing - sends a arp request given the DIP, SIP and interface name
func ArpPing(DIP net.IP, SIP net.IP, ifName string) (int, error) {
bZeroAddr := []byte{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }
bZeroAddr := []byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0}
fd, err := syscall.Socket(syscall.AF_PACKET, syscall.SOCK_DGRAM, int(Htons(syscall.ETH_P_ARP)))
if err != nil {
return -1, errors.New("af-packet-err")
Expand Down Expand Up @@ -100,10 +134,10 @@ func ArpPing(DIP net.IP, SIP net.IP, ifName string) (int, error) {
buf := new(bytes.Buffer)

var sb = make([]byte, 2)
binary.BigEndian.PutUint16(sb, 1) // HwType = 1
binary.BigEndian.PutUint16(sb, 1) // HwType = 1
buf.Write(sb)

binary.BigEndian.PutUint16(sb, 0x0800) // protoType
binary.BigEndian.PutUint16(sb, 0x0800) // protoType
buf.Write(sb)

buf.Write([]byte{6}) // hwAddrLen
Expand All @@ -113,7 +147,7 @@ func ArpPing(DIP net.IP, SIP net.IP, ifName string) (int, error) {
buf.Write(sb)

buf.Write(ifi.HardwareAddr) // senderHwAddr
buf.Write(SIP.To4()) // senderProtoAddr
buf.Write(SIP.To4()) // senderProtoAddr

buf.Write(bZeroAddr) // targetHwAddr
buf.Write(DIP.To4()) // targetProtoAddr
Expand All @@ -127,3 +161,40 @@ func ArpPing(DIP net.IP, SIP net.IP, ifName string) (int, error) {

return 0, nil
}

// NetGetIfiStats - Get OS statistics for a given interface
func NetGetIfiStats(ifName string, ifs *IfiStat) int {
file, err := os.Open(OsIfStatFile)
if err != nil {
return -1
}
defer file.Close()

scanner := bufio.NewScanner(file)
for scanner.Scan() {
content := scanner.Text()
ifi := strings.Split(content, ":")
if len(ifi) > 1 {
if ifi[0] != ifName {
continue
}

ifSfs := strings.Fields(ifi[1])
if len(ifSfs) >= MaxSidx {
for i := 0; i < MaxSidx; i++ {
val, err := strconv.ParseUint(ifSfs[i], 10, 64)
if err == nil {
ifs.Ifs[i] = val
}
}
break
}
}
}

if err := scanner.Err(); err != nil {
return -1
}

return 0
}

0 comments on commit eece0c7

Please sign in to comment.