The Go Programming Language

Source file src/pkg/net/ip.go

     1	// Copyright 2009 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	// IP address manipulations
     6	//
     7	// IPv4 addresses are 4 bytes; IPv6 addresses are 16 bytes.
     8	// An IPv4 address can be converted to an IPv6 address by
     9	// adding a canonical prefix (10 zeros, 2 0xFFs).
    10	// This library accepts either size of byte array but always
    11	// returns 16-byte addresses.
    12	
    13	package net
    14	
    15	import "os"
    16	
    17	// IP address lengths (bytes).
    18	const (
    19		IPv4len = 4
    20		IPv6len = 16
    21	)
    22	
    23	// An IP is a single IP address, an array of bytes.
    24	// Functions in this package accept either 4-byte (IP v4)
    25	// or 16-byte (IP v6) arrays as input.  Unless otherwise
    26	// specified, functions in this package always return
    27	// IP addresses in 16-byte form using the canonical
    28	// embedding.
    29	//
    30	// Note that in this documentation, referring to an
    31	// IP address as an IPv4 address or an IPv6 address
    32	// is a semantic property of the address, not just the
    33	// length of the byte array: a 16-byte array can still
    34	// be an IPv4 address.
    35	type IP []byte
    36	
    37	// An IP mask is an IP address.
    38	type IPMask []byte
    39	
    40	// IPv4 returns the IP address (in 16-byte form) of the
    41	// IPv4 address a.b.c.d.
    42	func IPv4(a, b, c, d byte) IP {
    43		p := make(IP, IPv6len)
    44		copy(p, v4InV6Prefix)
    45		p[12] = a
    46		p[13] = b
    47		p[14] = c
    48		p[15] = d
    49		return p
    50	}
    51	
    52	var v4InV6Prefix = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff}
    53	
    54	// IPv4Mask returns the IP mask (in 16-byte form) of the
    55	// IPv4 mask a.b.c.d.
    56	func IPv4Mask(a, b, c, d byte) IPMask {
    57		p := make(IPMask, IPv6len)
    58		for i := 0; i < 12; i++ {
    59			p[i] = 0xff
    60		}
    61		p[12] = a
    62		p[13] = b
    63		p[14] = c
    64		p[15] = d
    65		return p
    66	}
    67	
    68	// Well-known IPv4 addresses
    69	var (
    70		IPv4bcast     = IPv4(255, 255, 255, 255) // broadcast
    71		IPv4allsys    = IPv4(224, 0, 0, 1)       // all systems
    72		IPv4allrouter = IPv4(224, 0, 0, 2)       // all routers
    73		IPv4zero      = IPv4(0, 0, 0, 0)         // all zeros
    74	)
    75	
    76	// Well-known IPv6 addresses
    77	var (
    78		IPv6zero                   = IP{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
    79		IPv6unspecified            = IP{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
    80		IPv6loopback               = IP{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}
    81		IPv6interfacelocalallnodes = IP{0xff, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01}
    82		IPv6linklocalallnodes      = IP{0xff, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01}
    83		IPv6linklocalallrouters    = IP{0xff, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x02}
    84	)
    85	
    86	// IsUnspecified returns true if ip is an unspecified address.
    87	func (ip IP) IsUnspecified() bool {
    88		if ip.Equal(IPv4zero) || ip.Equal(IPv6unspecified) {
    89			return true
    90		}
    91		return false
    92	}
    93	
    94	// IsLoopback returns true if ip is a loopback address.
    95	func (ip IP) IsLoopback() bool {
    96		if ip4 := ip.To4(); ip4 != nil && ip4[0] == 127 {
    97			return true
    98		}
    99		return ip.Equal(IPv6loopback)
   100	}
   101	
   102	// IsMulticast returns true if ip is a multicast address.
   103	func (ip IP) IsMulticast() bool {
   104		if ip4 := ip.To4(); ip4 != nil && ip4[0]&0xf0 == 0xe0 {
   105			return true
   106		}
   107		return ip[0] == 0xff
   108	}
   109	
   110	// IsInterfaceLinkLocalMulticast returns true if ip is
   111	// an interface-local multicast address.
   112	func (ip IP) IsInterfaceLocalMulticast() bool {
   113		return len(ip) == IPv6len && ip[0] == 0xff && ip[1]&0x0f == 0x01
   114	}
   115	
   116	// IsLinkLocalMulticast returns true if ip is a link-local
   117	// multicast address.
   118	func (ip IP) IsLinkLocalMulticast() bool {
   119		if ip4 := ip.To4(); ip4 != nil && ip4[0] == 224 && ip4[1] == 0 && ip4[2] == 0 {
   120			return true
   121		}
   122		return ip[0] == 0xff && ip[1]&0x0f == 0x02
   123	}
   124	
   125	// IsLinkLocalUnicast returns true if ip is a link-local
   126	// unicast address.
   127	func (ip IP) IsLinkLocalUnicast() bool {
   128		if ip4 := ip.To4(); ip4 != nil && ip4[0] == 169 && ip4[1] == 254 {
   129			return true
   130		}
   131		return ip[0] == 0xfe && ip[1]&0xc0 == 0x80
   132	}
   133	
   134	// IsGlobalUnicast returns true if ip is a global unicast
   135	// address.
   136	func (ip IP) IsGlobalUnicast() bool {
   137		return !ip.IsUnspecified() &&
   138			!ip.IsLoopback() &&
   139			!ip.IsMulticast() &&
   140			!ip.IsLinkLocalUnicast()
   141	}
   142	
   143	// Is p all zeros?
   144	func isZeros(p IP) bool {
   145		for i := 0; i < len(p); i++ {
   146			if p[i] != 0 {
   147				return false
   148			}
   149		}
   150		return true
   151	}
   152	
   153	// To4 converts the IPv4 address ip to a 4-byte representation.
   154	// If ip is not an IPv4 address, To4 returns nil.
   155	func (ip IP) To4() IP {
   156		if len(ip) == IPv4len {
   157			return ip
   158		}
   159		if len(ip) == IPv6len &&
   160			isZeros(ip[0:10]) &&
   161			ip[10] == 0xff &&
   162			ip[11] == 0xff {
   163			return ip[12:16]
   164		}
   165		return nil
   166	}
   167	
   168	// To16 converts the IP address ip to a 16-byte representation.
   169	// If ip is not an IP address (it is the wrong length), To16 returns nil.
   170	func (ip IP) To16() IP {
   171		if len(ip) == IPv4len {
   172			return IPv4(ip[0], ip[1], ip[2], ip[3])
   173		}
   174		if len(ip) == IPv6len {
   175			return ip
   176		}
   177		return nil
   178	}
   179	
   180	// Default route masks for IPv4.
   181	var (
   182		classAMask = IPv4Mask(0xff, 0, 0, 0)
   183		classBMask = IPv4Mask(0xff, 0xff, 0, 0)
   184		classCMask = IPv4Mask(0xff, 0xff, 0xff, 0)
   185	)
   186	
   187	// DefaultMask returns the default IP mask for the IP address ip.
   188	// Only IPv4 addresses have default masks; DefaultMask returns
   189	// nil if ip is not a valid IPv4 address.
   190	func (ip IP) DefaultMask() IPMask {
   191		if ip = ip.To4(); ip == nil {
   192			return nil
   193		}
   194		switch true {
   195		case ip[0] < 0x80:
   196			return classAMask
   197		case ip[0] < 0xC0:
   198			return classBMask
   199		default:
   200			return classCMask
   201		}
   202		return nil // not reached
   203	}
   204	
   205	func allFF(b []byte) bool {
   206		for _, c := range b {
   207			if c != 0xff {
   208				return false
   209			}
   210		}
   211		return true
   212	}
   213	
   214	// Mask returns the result of masking the IP address ip with mask.
   215	func (ip IP) Mask(mask IPMask) IP {
   216		n := len(ip)
   217		if len(mask) == 16 && len(ip) == 4 && allFF(mask[:12]) {
   218			mask = mask[12:]
   219		}
   220		if len(mask) == 4 && len(ip) == 16 && bytesEqual(ip[:12], v4InV6Prefix) {
   221			ip = ip[12:]
   222		}
   223		if n != len(mask) {
   224			return nil
   225		}
   226		out := make(IP, n)
   227		for i := 0; i < n; i++ {
   228			out[i] = ip[i] & mask[i]
   229		}
   230		return out
   231	}
   232	
   233	// Convert i to decimal string.
   234	func itod(i uint) string {
   235		if i == 0 {
   236			return "0"
   237		}
   238	
   239		// Assemble decimal in reverse order.
   240		var b [32]byte
   241		bp := len(b)
   242		for ; i > 0; i /= 10 {
   243			bp--
   244			b[bp] = byte(i%10) + '0'
   245		}
   246	
   247		return string(b[bp:])
   248	}
   249	
   250	// Convert i to hexadecimal string.
   251	func itox(i uint) string {
   252		if i == 0 {
   253			return "0"
   254		}
   255	
   256		// Assemble hexadecimal in reverse order.
   257		var b [32]byte
   258		bp := len(b)
   259		for ; i > 0; i /= 16 {
   260			bp--
   261			b[bp] = "0123456789abcdef"[byte(i%16)]
   262		}
   263	
   264		return string(b[bp:])
   265	}
   266	
   267	// String returns the string form of the IP address ip.
   268	// If the address is an IPv4 address, the string representation
   269	// is dotted decimal ("74.125.19.99").  Otherwise the representation
   270	// is IPv6 ("2001:4860:0:2001::68").
   271	func (ip IP) String() string {
   272		p := ip
   273	
   274		if len(ip) == 0 {
   275			return ""
   276		}
   277	
   278		// If IPv4, use dotted notation.
   279		if p4 := p.To4(); len(p4) == 4 {
   280			return itod(uint(p4[0])) + "." +
   281				itod(uint(p4[1])) + "." +
   282				itod(uint(p4[2])) + "." +
   283				itod(uint(p4[3]))
   284		}
   285		if len(p) != IPv6len {
   286			return "?"
   287		}
   288	
   289		// Find longest run of zeros.
   290		e0 := -1
   291		e1 := -1
   292		for i := 0; i < 16; i += 2 {
   293			j := i
   294			for j < 16 && p[j] == 0 && p[j+1] == 0 {
   295				j += 2
   296			}
   297			if j > i && j-i > e1-e0 {
   298				e0 = i
   299				e1 = j
   300			}
   301		}
   302		// The symbol "::" MUST NOT be used to shorten just one 16 bit 0 field.
   303		if e1-e0 <= 2 {
   304			e0 = -1
   305			e1 = -1
   306		}
   307	
   308		// Print with possible :: in place of run of zeros
   309		var s string
   310		for i := 0; i < 16; i += 2 {
   311			if i == e0 {
   312				s += "::"
   313				i = e1
   314				if i >= 16 {
   315					break
   316				}
   317			} else if i > 0 {
   318				s += ":"
   319			}
   320			s += itox((uint(p[i]) << 8) | uint(p[i+1]))
   321		}
   322		return s
   323	}
   324	
   325	// Equal returns true if ip and x are the same IP address.
   326	// An IPv4 address and that same address in IPv6 form are
   327	// considered to be equal.
   328	func (ip IP) Equal(x IP) bool {
   329		if len(ip) == len(x) {
   330			return bytesEqual(ip, x)
   331		}
   332		if len(ip) == 4 && len(x) == 16 {
   333			return bytesEqual(x[0:12], v4InV6Prefix) && bytesEqual(ip, x[12:])
   334		}
   335		if len(ip) == 16 && len(x) == 4 {
   336			return bytesEqual(ip[0:12], v4InV6Prefix) && bytesEqual(ip[12:], x)
   337		}
   338		return false
   339	}
   340	
   341	func bytesEqual(x, y []byte) bool {
   342		if len(x) != len(y) {
   343			return false
   344		}
   345		for i, b := range x {
   346			if y[i] != b {
   347				return false
   348			}
   349		}
   350		return true
   351	}
   352	
   353	// If mask is a sequence of 1 bits followed by 0 bits,
   354	// return the number of 1 bits.
   355	func simpleMaskLength(mask IPMask) int {
   356		var n int
   357		for i, v := range mask {
   358			if v == 0xff {
   359				n += 8
   360				continue
   361			}
   362			// found non-ff byte
   363			// count 1 bits
   364			for v&0x80 != 0 {
   365				n++
   366				v <<= 1
   367			}
   368			// rest must be 0 bits
   369			if v != 0 {
   370				return -1
   371			}
   372			for i++; i < len(mask); i++ {
   373				if mask[i] != 0 {
   374					return -1
   375				}
   376			}
   377			break
   378		}
   379		return n
   380	}
   381	
   382	// String returns the string representation of mask.
   383	// If the mask is in the canonical form--ones followed by zeros--the
   384	// string representation is just the decimal number of ones.
   385	// If the mask is in a non-canonical form, it is formatted
   386	// as an IP address.
   387	func (mask IPMask) String() string {
   388		switch len(mask) {
   389		case 4:
   390			n := simpleMaskLength(mask)
   391			if n >= 0 {
   392				return itod(uint(n + (IPv6len-IPv4len)*8))
   393			}
   394		case 16:
   395			n := simpleMaskLength(mask)
   396			if n >= 12*8 {
   397				return itod(uint(n - 12*8))
   398			}
   399		}
   400		return IP(mask).String()
   401	}
   402	
   403	// Parse IPv4 address (d.d.d.d).
   404	func parseIPv4(s string) IP {
   405		var p [IPv4len]byte
   406		i := 0
   407		for j := 0; j < IPv4len; j++ {
   408			if i >= len(s) {
   409				// Missing octets.
   410				return nil
   411			}
   412			if j > 0 {
   413				if s[i] != '.' {
   414					return nil
   415				}
   416				i++
   417			}
   418			var (
   419				n  int
   420				ok bool
   421			)
   422			n, i, ok = dtoi(s, i)
   423			if !ok || n > 0xFF {
   424				return nil
   425			}
   426			p[j] = byte(n)
   427		}
   428		if i != len(s) {
   429			return nil
   430		}
   431		return IPv4(p[0], p[1], p[2], p[3])
   432	}
   433	
   434	// Parse IPv6 address.  Many forms.
   435	// The basic form is a sequence of eight colon-separated
   436	// 16-bit hex numbers separated by colons,
   437	// as in 0123:4567:89ab:cdef:0123:4567:89ab:cdef.
   438	// Two exceptions:
   439	//	* A run of zeros can be replaced with "::".
   440	//	* The last 32 bits can be in IPv4 form.
   441	// Thus, ::ffff:1.2.3.4 is the IPv4 address 1.2.3.4.
   442	func parseIPv6(s string) IP {
   443		p := make(IP, 16)
   444		ellipsis := -1 // position of ellipsis in p
   445		i := 0         // index in string s
   446	
   447		// Might have leading ellipsis
   448		if len(s) >= 2 && s[0] == ':' && s[1] == ':' {
   449			ellipsis = 0
   450			i = 2
   451			// Might be only ellipsis
   452			if i == len(s) {
   453				return p
   454			}
   455		}
   456	
   457		// Loop, parsing hex numbers followed by colon.
   458		j := 0
   459		for j < IPv6len {
   460			// Hex number.
   461			n, i1, ok := xtoi(s, i)
   462			if !ok || n > 0xFFFF {
   463				return nil
   464			}
   465	
   466			// If followed by dot, might be in trailing IPv4.
   467			if i1 < len(s) && s[i1] == '.' {
   468				if ellipsis < 0 && j != IPv6len-IPv4len {
   469					// Not the right place.
   470					return nil
   471				}
   472				if j+IPv4len > IPv6len {
   473					// Not enough room.
   474					return nil
   475				}
   476				p4 := parseIPv4(s[i:])
   477				if p4 == nil {
   478					return nil
   479				}
   480				p[j] = p4[12]
   481				p[j+1] = p4[13]
   482				p[j+2] = p4[14]
   483				p[j+3] = p4[15]
   484				i = len(s)
   485				j += 4
   486				break
   487			}
   488	
   489			// Save this 16-bit chunk.
   490			p[j] = byte(n >> 8)
   491			p[j+1] = byte(n)
   492			j += 2
   493	
   494			// Stop at end of string.
   495			i = i1
   496			if i == len(s) {
   497				break
   498			}
   499	
   500			// Otherwise must be followed by colon and more.
   501			if s[i] != ':' || i+1 == len(s) {
   502				return nil
   503			}
   504			i++
   505	
   506			// Look for ellipsis.
   507			if s[i] == ':' {
   508				if ellipsis >= 0 { // already have one
   509					return nil
   510				}
   511				ellipsis = j
   512				if i++; i == len(s) { // can be at end
   513					break
   514				}
   515			}
   516		}
   517	
   518		// Must have used entire string.
   519		if i != len(s) {
   520			return nil
   521		}
   522	
   523		// If didn't parse enough, expand ellipsis.
   524		if j < IPv6len {
   525			if ellipsis < 0 {
   526				return nil
   527			}
   528			n := IPv6len - j
   529			for k := j - 1; k >= ellipsis; k-- {
   530				p[k+n] = p[k]
   531			}
   532			for k := ellipsis + n - 1; k >= ellipsis; k-- {
   533				p[k] = 0
   534			}
   535		}
   536		return p
   537	}
   538	
   539	// A ParseError represents a malformed text string and the type of string that was expected.
   540	type ParseError struct {
   541		Type string
   542		Text string
   543	}
   544	
   545	func (e *ParseError) String() string {
   546		return "invalid " + e.Type + ": " + e.Text
   547	}
   548	
   549	func parseIP(s string) IP {
   550		if p := parseIPv4(s); p != nil {
   551			return p
   552		}
   553		if p := parseIPv6(s); p != nil {
   554			return p
   555		}
   556		return nil
   557	}
   558	
   559	// ParseIP parses s as an IP address, returning the result.
   560	// The string s can be in dotted decimal ("74.125.19.99")
   561	// or IPv6 ("2001:4860:0:2001::68") form.
   562	// If s is not a valid textual representation of an IP address,
   563	// ParseIP returns nil.
   564	func ParseIP(s string) IP {
   565		if p := parseIPv4(s); p != nil {
   566			return p
   567		}
   568		return parseIPv6(s)
   569	}
   570	
   571	// ParseCIDR parses s as a CIDR notation IP address and mask,
   572	// like "192.168.100.1/24", "2001:DB8::/48", as defined in
   573	// RFC 4632 and RFC 4291.
   574	func ParseCIDR(s string) (ip IP, mask IPMask, err os.Error) {
   575		i := byteIndex(s, '/')
   576		if i < 0 {
   577			return nil, nil, &ParseError{"CIDR address", s}
   578		}
   579		ipstr, maskstr := s[:i], s[i+1:]
   580		iplen := 4
   581		ip = parseIPv4(ipstr)
   582		if ip == nil {
   583			iplen = 16
   584			ip = parseIPv6(ipstr)
   585		}
   586		nn, i, ok := dtoi(maskstr, 0)
   587		if ip == nil || !ok || i != len(maskstr) || nn < 0 || nn > 8*iplen {
   588			return nil, nil, &ParseError{"CIDR address", s}
   589		}
   590		n := uint(nn)
   591		if iplen == 4 {
   592			v4mask := ^uint32(0xffffffff >> n)
   593			mask = IPv4Mask(byte(v4mask>>24), byte(v4mask>>16), byte(v4mask>>8), byte(v4mask))
   594		} else {
   595			mask = make(IPMask, 16)
   596			for i := 0; i < 16; i++ {
   597				if n >= 8 {
   598					mask[i] = 0xff
   599					n -= 8
   600					continue
   601				}
   602				mask[i] = ^byte(0xff >> n)
   603				n = 0
   604	
   605			}
   606		}
   607		// address must not have any bits not in mask
   608		for i := range ip {
   609			if ip[i]&^mask[i] != 0 {
   610				return nil, nil, &ParseError{"CIDR address", s}
   611			}
   612		}
   613		return ip, mask, nil
   614	}

release.r60.3. Except as noted, this content is licensed under a Creative Commons Attribution 3.0 License.