Skip to content

Commit

Permalink
rebase Initial support for parsing /proc/net/arp #105 from @skottler
Browse files Browse the repository at this point in the history
Signed-off-by: Christoph Maser <christoph.maser+github@gmail.com>
  • Loading branch information
TheMeier committed Aug 3, 2019
1 parent 5da962f commit efaf9fb
Show file tree
Hide file tree
Showing 3 changed files with 133 additions and 0 deletions.
84 changes: 84 additions & 0 deletions arp.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// Copyright 2019 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package procfs

import (
"fmt"
"io/ioutil"
"net"
"strings"
)

// ARPEntry contains a single row of the columnar data represented in
// /proc/net/arp.
type ARPEntry struct {
// IP address
IPAddr net.IP
// MAC address
HWAddr net.HardwareAddr
// Name of the device
Device string
}

// GatherARPEntries retrieves all the ARP entries, parse the relevant columns,
// and then return a slice of ARPEntry's.
func (fs FS) GatherARPEntries() ([]ARPEntry, error) {
data, err := ioutil.ReadFile(fs.proc.Path("net/arp"))
if err != nil {
return nil, fmt.Errorf("error reading arp %s: %s", fs.proc.Path("net/arp"), err)
}

return parseARPEntries(data)
}

func parseARPEntries(data []byte) ([]ARPEntry, error) {
lines := strings.Split(string(data), "\n")
entries := make([]ARPEntry, 0)
var err error

for _, line := range lines {
columns := strings.Fields(line)
width := len(columns)
expectedDataWidth := 6
expectedHeaderWidth := 9

if width == expectedHeaderWidth || width == 0 {
continue
} else if width == expectedDataWidth {
entry, err := parseARPEntry(columns)
if err != nil {
return []ARPEntry{}, fmt.Errorf("failed to parse ARP entry: %s", err)
}
entries = append(entries, entry)
} else {
return []ARPEntry{}, fmt.Errorf("%d columns were detected, but %d were expected", width, expectedDataWidth)
}

}

return entries, err
}

func parseARPEntry(columns []string) (ARPEntry, error) {
ip := net.ParseIP(columns[0])
mac := net.HardwareAddr(columns[3])

entry := ARPEntry{
IPAddr: ip,
HWAddr: mac,
Device: columns[5],
}

return entry, nil
}
43 changes: 43 additions & 0 deletions arp_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright 2019 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package procfs

import (
"net"
"testing"
)

func TestARP(t *testing.T) {
fs, err := NewFS(procTestFixtures)
if err != nil {
t.Fatal(err)
}

arpFile, err := fs.GatherARPEntries()
if err != nil {
t.Fatal(err)
}

if want, got := "192.168.224.1", arpFile[0].IPAddr.String(); want != got {
t.Errorf("want 192.168.224.1, got %s", got)
}

if want, got := net.HardwareAddr("00:50:56:c0:00:08").String(), arpFile[0].HWAddr.String(); want != got {
t.Errorf("want 00:50:56:c0:00:08, got %s", got)
}

if want, got := "ens33", arpFile[0].Device; want != got {
t.Errorf("want ens33, got %s", got)
}
}
6 changes: 6 additions & 0 deletions fixtures.ttar
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,12 @@ Mode: 644
Directory: fixtures/proc/net
Mode: 755
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Path: fixtures/proc/net/arp
Lines: 2
IP address HW type Flags HW address Mask Device
192.168.224.1 0x1 0x2 00:50:56:c0:00:08 * ens33
Mode: 664
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Path: fixtures/proc/net/dev
Lines: 6
Inter-| Receive | Transmit
Expand Down

0 comments on commit efaf9fb

Please sign in to comment.