Home | History | Annotate | Download | only in net
      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