1 // Copyright 2011 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package net 6 7 const hexDigit = "0123456789abcdef" 8 9 // A HardwareAddr represents a physical hardware address. 10 type HardwareAddr []byte 11 12 func (a HardwareAddr) String() string { 13 if len(a) == 0 { 14 return "" 15 } 16 buf := make([]byte, 0, len(a)*3-1) 17 for i, b := range a { 18 if i > 0 { 19 buf = append(buf, ':') 20 } 21 buf = append(buf, hexDigit[b>>4]) 22 buf = append(buf, hexDigit[b&0xF]) 23 } 24 return string(buf) 25 } 26 27 // ParseMAC parses s as an IEEE 802 MAC-48, EUI-48, or EUI-64 using one of the 28 // following formats: 29 // 01:23:45:67:89:ab 30 // 01:23:45:67:89:ab:cd:ef 31 // 01-23-45-67-89-ab 32 // 01-23-45-67-89-ab-cd-ef 33 // 0123.4567.89ab 34 // 0123.4567.89ab.cdef 35 func ParseMAC(s string) (hw HardwareAddr, err error) { 36 if len(s) < 14 { 37 goto error 38 } 39 40 if s[2] == ':' || s[2] == '-' { 41 if (len(s)+1)%3 != 0 { 42 goto error 43 } 44 n := (len(s) + 1) / 3 45 if n != 6 && n != 8 { 46 goto error 47 } 48 hw = make(HardwareAddr, n) 49 for x, i := 0, 0; i < n; i++ { 50 var ok bool 51 if hw[i], ok = xtoi2(s[x:], s[2]); !ok { 52 goto error 53 } 54 x += 3 55 } 56 } else if s[4] == '.' { 57 if (len(s)+1)%5 != 0 { 58 goto error 59 } 60 n := 2 * (len(s) + 1) / 5 61 if n != 6 && n != 8 { 62 goto error 63 } 64 hw = make(HardwareAddr, n) 65 for x, i := 0, 0; i < n; i += 2 { 66 var ok bool 67 if hw[i], ok = xtoi2(s[x:x+2], 0); !ok { 68 goto error 69 } 70 if hw[i+1], ok = xtoi2(s[x+2:], s[4]); !ok { 71 goto error 72 } 73 x += 5 74 } 75 } else { 76 goto error 77 } 78 return hw, nil 79 80 error: 81 return nil, &AddrError{Err: "invalid MAC address", Addr: s} 82 } 83