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, EUI-64, or a 20-octet
     28 // IP over InfiniBand link-layer address using one of the 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:cd:ef:00:00:01:23:45:67:89:ab:cd:ef:00:00
     32 //   01-23-45-67-89-ab
     33 //   01-23-45-67-89-ab-cd-ef
     34 //   01-23-45-67-89-ab-cd-ef-00-00-01-23-45-67-89-ab-cd-ef-00-00
     35 //   0123.4567.89ab
     36 //   0123.4567.89ab.cdef
     37 //   0123.4567.89ab.cdef.0000.0123.4567.89ab.cdef.0000
     38 func ParseMAC(s string) (hw HardwareAddr, err error) {
     39 	if len(s) < 14 {
     40 		goto error
     41 	}
     42 
     43 	if s[2] == ':' || s[2] == '-' {
     44 		if (len(s)+1)%3 != 0 {
     45 			goto error
     46 		}
     47 		n := (len(s) + 1) / 3
     48 		if n != 6 && n != 8 && n != 20 {
     49 			goto error
     50 		}
     51 		hw = make(HardwareAddr, n)
     52 		for x, i := 0, 0; i < n; i++ {
     53 			var ok bool
     54 			if hw[i], ok = xtoi2(s[x:], s[2]); !ok {
     55 				goto error
     56 			}
     57 			x += 3
     58 		}
     59 	} else if s[4] == '.' {
     60 		if (len(s)+1)%5 != 0 {
     61 			goto error
     62 		}
     63 		n := 2 * (len(s) + 1) / 5
     64 		if n != 6 && n != 8 && n != 20 {
     65 			goto error
     66 		}
     67 		hw = make(HardwareAddr, n)
     68 		for x, i := 0, 0; i < n; i += 2 {
     69 			var ok bool
     70 			if hw[i], ok = xtoi2(s[x:x+2], 0); !ok {
     71 				goto error
     72 			}
     73 			if hw[i+1], ok = xtoi2(s[x+2:], s[4]); !ok {
     74 				goto error
     75 			}
     76 			x += 5
     77 		}
     78 	} else {
     79 		goto error
     80 	}
     81 	return hw, nil
     82 
     83 error:
     84 	return nil, &AddrError{Err: "invalid MAC address", Addr: s}
     85 }
     86