diff options
Diffstat (limited to 'utils/net.go')
| -rw-r--r-- | utils/net.go | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/utils/net.go b/utils/net.go new file mode 100644 index 0000000..76454bd --- /dev/null +++ b/utils/net.go @@ -0,0 +1,59 @@ +package utils + +import ( + "fmt" + "strings" +) + +// Mac is a 48-bit hardware address. +type Mac struct { + Addr [6]byte +} + +// Format renders the canonical lowercase, zero-padded form aa:bb:cc:dd:ee:ff. +func (m *Mac) Format() string { + return fmt.Sprintf("%02x:%02x:%02x:%02x:%02x:%02x", + m.Addr[0], m.Addr[1], m.Addr[2], m.Addr[3], m.Addr[4], m.Addr[5]) +} + +// ParseMac reads a colon-separated hex MAC. It tolerates uppercase and the +// zero-stripped octets macOS prints (e.g. "8:0:27:ab:cd:ef"). +func ParseMac(s string) (*Mac, error) { + mac := &Mac{} + t := strings.TrimSpace(s) + n, err := fmt.Sscanf(t, "%x:%x:%x:%x:%x:%x", + &mac.Addr[0], &mac.Addr[1], &mac.Addr[2], &mac.Addr[3], &mac.Addr[4], &mac.Addr[5]) + if err != nil { + return nil, err + } + if n != 6 { + return nil, fmt.Errorf("invalid mac %q: parsed %d of 6 octets", s, n) + } + return mac, nil +} + +// INet4 is an IPv4 address. +type INet4 struct { + Addr [4]byte +} + +// Format renders the dotted-decimal form a.b.c.d. +func (n *INet4) Format() string { + return fmt.Sprintf("%d.%d.%d.%d", n.Addr[0], n.Addr[1], n.Addr[2], n.Addr[3]) +} + +// ParseINet4 reads a dotted-decimal IPv4 address. Out-of-range octets (>255) +// overflow the byte and are rejected. +func ParseINet4(s string) (*INet4, error) { + addr := &INet4{} + t := strings.TrimSpace(s) + n, err := fmt.Sscanf(t, "%d.%d.%d.%d", + &addr.Addr[0], &addr.Addr[1], &addr.Addr[2], &addr.Addr[3]) + if err != nil { + return nil, err + } + if n != 4 { + return nil, fmt.Errorf("invalid ipv4 %q: parsed %d of 4 octets", s, n) + } + return addr, nil +} |
