Платформа ЦРНП "Мирокод" для разработки проектов
https://git.mirocod.ru
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
85 lines
2.2 KiB
85 lines
2.2 KiB
// 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 |
|
const ( |
|
expectedDataWidth = 6 |
|
expectedHeaderWidth = 9 |
|
) |
|
for _, line := range lines { |
|
columns := strings.Fields(line) |
|
width := len(columns) |
|
|
|
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 |
|
}
|
|
|