mirror of
https://github.com/golang/go
synced 2024-11-22 03:04:41 -07:00
net: add ParseMAC function
ParseMAC parses a string representing MAC-48, EUI-48, or EUI-64 into a HardwareAddr. R=rsc, fshahriar CC=golang-dev https://golang.org/cl/4922048
This commit is contained in:
parent
39194de8ca
commit
af18e4b9b0
@ -26,6 +26,75 @@ func (a HardwareAddr) String() string {
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
// ParseMAC parses s as an IEEE 802 MAC-48, EUI-48, or EUI-64 using one of the
|
||||
// following formats:
|
||||
// 01:23:45:67:89:ab
|
||||
// 01:23:45:67:89:ab:cd:ef
|
||||
// 01-23-45-67-89-ab
|
||||
// 01-23-45-67-89-ab-cd-ef
|
||||
// 0123.4567.89ab
|
||||
// 0123.4567.89ab.cdef
|
||||
func ParseMAC(s string) (hw HardwareAddr, err os.Error) {
|
||||
if len(s) < 14 {
|
||||
goto error
|
||||
}
|
||||
|
||||
if s[2] == ':' || s[2] == '-' {
|
||||
if (len(s)+1)%3 != 0 {
|
||||
goto error
|
||||
}
|
||||
n := (len(s) + 1) / 3
|
||||
if n != 6 && n != 8 {
|
||||
goto error
|
||||
}
|
||||
hw = make(HardwareAddr, n)
|
||||
for x, i := 0, 0; i < n; i++ {
|
||||
var ok bool
|
||||
if hw[i], ok = xtoi2(s[x:], s[2]); !ok {
|
||||
goto error
|
||||
}
|
||||
x += 3
|
||||
}
|
||||
} else if s[4] == '.' {
|
||||
if (len(s)+1)%5 != 0 {
|
||||
goto error
|
||||
}
|
||||
n := 2 * (len(s) + 1) / 5
|
||||
if n != 6 && n != 8 {
|
||||
goto error
|
||||
}
|
||||
hw = make(HardwareAddr, n)
|
||||
for x, i := 0, 0; i < n; i += 2 {
|
||||
var ok bool
|
||||
if hw[i], ok = xtoi2(s[x:x+2], 0); !ok {
|
||||
goto error
|
||||
}
|
||||
if hw[i+1], ok = xtoi2(s[x+2:], s[4]); !ok {
|
||||
goto error
|
||||
}
|
||||
x += 5
|
||||
}
|
||||
} else {
|
||||
goto error
|
||||
}
|
||||
return hw, nil
|
||||
|
||||
error:
|
||||
return nil, os.NewError("invalid MAC address: " + s)
|
||||
}
|
||||
|
||||
// xtoi2 converts the next two hex digits of s into a byte.
|
||||
// If s is longer than 2 bytes then the third byte must be e.
|
||||
// If the first two bytes of s are not hex digits or the third byte
|
||||
// does not match e, false is returned.
|
||||
func xtoi2(s string, e byte) (byte, bool) {
|
||||
if len(s) > 2 && s[2] != e {
|
||||
return 0, false
|
||||
}
|
||||
n, ei, ok := xtoi(s[:2], 0)
|
||||
return byte(n), ok && ei == 2
|
||||
}
|
||||
|
||||
// Interface represents a mapping between network interface name
|
||||
// and index. It also represents network interface facility
|
||||
// information.
|
||||
|
@ -6,6 +6,9 @@ package net
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"os"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
@ -71,3 +74,46 @@ func TestInterfaceAddrs(t *testing.T) {
|
||||
t.Logf("interface address %q\n", ifa.String())
|
||||
}
|
||||
}
|
||||
|
||||
var mactests = []struct {
|
||||
in string
|
||||
out HardwareAddr
|
||||
err string
|
||||
}{
|
||||
{"01:23:45:67:89:AB", HardwareAddr{1, 0x23, 0x45, 0x67, 0x89, 0xab}, ""},
|
||||
{"01-23-45-67-89-AB", HardwareAddr{1, 0x23, 0x45, 0x67, 0x89, 0xab}, ""},
|
||||
{"0123.4567.89AB", HardwareAddr{1, 0x23, 0x45, 0x67, 0x89, 0xab}, ""},
|
||||
{"ab:cd:ef:AB:CD:EF", HardwareAddr{0xab, 0xcd, 0xef, 0xab, 0xcd, 0xef}, ""},
|
||||
{"01.02.03.04.05.06", nil, "invalid MAC address"},
|
||||
{"01:02:03:04:05:06:", nil, "invalid MAC address"},
|
||||
{"x1:02:03:04:05:06", nil, "invalid MAC address"},
|
||||
{"01002:03:04:05:06", nil, "invalid MAC address"},
|
||||
{"01:02003:04:05:06", nil, "invalid MAC address"},
|
||||
{"01:02:03004:05:06", nil, "invalid MAC address"},
|
||||
{"01:02:03:04005:06", nil, "invalid MAC address"},
|
||||
{"01:02:03:04:05006", nil, "invalid MAC address"},
|
||||
{"01-02:03:04:05:06", nil, "invalid MAC address"},
|
||||
{"01:02-03-04-05-06", nil, "invalid MAC address"},
|
||||
{"0123:4567:89AF", nil, "invalid MAC address"},
|
||||
{"0123-4567-89AF", nil, "invalid MAC address"},
|
||||
{"01:23:45:67:89:AB:CD:EF", HardwareAddr{1, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}, ""},
|
||||
{"01-23-45-67-89-AB-CD-EF", HardwareAddr{1, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}, ""},
|
||||
{"0123.4567.89AB.CDEF", HardwareAddr{1, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}, ""},
|
||||
}
|
||||
|
||||
func match(err os.Error, s string) bool {
|
||||
if s == "" {
|
||||
return err == nil
|
||||
}
|
||||
return err != nil && strings.Contains(err.String(), s)
|
||||
}
|
||||
|
||||
func TestParseMAC(t *testing.T) {
|
||||
for _, tt := range mactests {
|
||||
out, err := ParseMAC(tt.in)
|
||||
if !reflect.DeepEqual(out, tt.out) || !match(err, tt.err) {
|
||||
t.Errorf("ParseMAC(%q) = %v, %v, want %v, %v", tt.in, out, err, tt.out,
|
||||
tt.err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user