Documentation ¶
Overview ¶
Package iid provides functions for generating and validating IPv6 Interface Identifiers (IID's). For the purposes of this module an IID is an IPv6 address constructed, somehow, from information which uniquely identifies a given interface on a network, and is unique within that network.
As part of validation this package imports the Internet Assigned Numbers Authority (IANA) Reserved IPv6 Interface Identifiers as a data structure and implements functions to compare the reserved networks against IID's to avoid conflicts. The data set for the IANA registry is available from:
- https://www.iana.org/assignments/ipv6-interface-ids/ipv6-interface-ids.xhtml
Index ¶
- Variables
- func GenerateRFC7217Addr(ip net.IP, hw net.HardwareAddr, counter int64, netid, secret []byte, ...) (net.IP, error)
- func MakeEUI64Addr(ip net.IP, hw net.HardwareAddr, scope Scope) net.IP
- func MakeOpaqueAddr(ip net.IP, hw net.HardwareAddr, counter int64, netid, secret []byte) (net.IP, error)
- type Reservation
- type Scope
Constants ¶
This section is empty.
Variables ¶
var (
ErrIIDAddressCollision = errors.New("proposed IID collides with IANA reserved IID list")
)
Errors that may be returned by functions in this package
var Registry []*Reservation
Registry holds the aggregated network list from IANA's "Reserved IPv6 Interface Identifiers" as specified in RFC5453. In order to be compliant with RFC7217's algorithm for "Semantically Opaque Interface Identifiers" addresses should be checked against this registry to make sure there are no conflicts
Functions ¶
func GenerateRFC7217Addr ¶
func GenerateRFC7217Addr(ip net.IP, hw net.HardwareAddr, counter int64, netid, secret []byte, htype crypto.Hash, scope Scope) (net.IP, error)
GenerateRFC7217Addr generates a pseudo-random IID from supplied input parameters in compliance with RFC7217. The signature of this function deviates from the one specified in that RFC only insomuch as is necessary to conform to the implementing language. In most cases this function is overkill and the function MakeOpaqueAddr, in this package, should be used instead.
The input fields are:
ip: v6 net.IP, only the first 64bits will be used
hw: 48- or 64-bit net.HardwareAddr, typically of the interface that this address will be assigned to
counter: a monotonically incrementing number read from some non-volatile local storage. This variable provides the velocity to the entire algorithm and should be incremented after each use. There is no guarantee that a generated address wont accidentally fall within the range of reserved IPv6 IIDs and, should this happen, an ErrIIDAddressCollision will be returned. This is harmless and if it happens counter should be incremented and the function called again
netid: some piece of information identifying the local subnet, such as an 802.11 SSID. RFC6059 lists other interesting options. This field may be left blank ([]byte{})
secret: a local, closely held, secret key. This is the sauce that makes the address opaque
htype: a crypto.Hash function to use when generating the IID.
scope: the scope of the IID
NOTE that MD5 is specifically prohibited for being too easily guessable.
NOTE that unless you use sha256 you will need to import the hash function you intend to use, (e.g. import _ "crypto/sha512")
func MakeEUI64Addr ¶
MakeEUI64Addr takes an IPv6 address, a hardware MAC address and a scope as input and uses them to generate an Interface Identifier suitable for use in link local, global unicast and Stateless Address Autoconfiguration (SLAAC) addresses (but see RFC4941 for problems with this last case).
The IP is assumed to be a /64, and the hardware address must be either 48 or 64 bits. The hardware address will be appended to the IP address as per RFC4291 section 2.5.1 and be modified as follows:
* the 7th bit of the first octet (the 'X' bit in the EUI-64 format) may be modified per the definition for each constant.
* if the address is 48 bits, the octets 0xFFFE are inserted in the middle of the address to pad it to 64 bits
func MakeOpaqueAddr ¶
func MakeOpaqueAddr(ip net.IP, hw net.HardwareAddr, counter int64, netid, secret []byte) (net.IP, error)
MakeOpaqueAddr offers one implementation of RFC7217's algorithm for generating a "semantically opaque interface identifier". The caller must supply a counter and secret and MAY supply an additional "netid". Ultimately this function calls GenerateRFC7217Addr() with scope set to "global" and an htype of SHA256, but please see the documentation in that function for an explanation of all the input fields
Types ¶
type Reservation ¶
type Reservation struct { // FirstRes is the first address in the reservation FirstRes []byte // LastRes is the last address in the reservation LastRes []byte // Title is a name given to the reservation Title string // RFC is the list of relevant RFCs RFC string }
Reservation describes an entry in the IANA IP Special Registry
func GetReservationsForIP ¶
func GetReservationsForIP(ip net.IP) *Reservation
GetReservationsForIP returns a list of any IANA reserved networks that the supplied IP is part of
type Scope ¶
type Scope int
Scope describes the availability of an IPv6 IID and determines how IID- generating functions treat the 7th bit in the 9th octet of the address (the 'X' bit in the EUI-64 format, or the 'u' bit in RFC4291)
NOTE: there is some ambiguity to the RFC here. Most discussions I've seen on the topic say that the bit should _always_ be inverted, but the RFC reads like the IPv6 EUI64 format uses the _inverse signal_ from the IEEE EUI64 format; so where the IEEE uses 0 for global scoping, the IPv6 IID should use 1. This module punts on the question and provides for all interpretations via the scope parameter but recommends passing an explicit ScopeGlobal or ScopeLocal
const ( // ScopeNone is an undefined IID scope, the X bit will not be modified ScopeNone Scope = iota // ScopeInvert will cause the X bit to be inverted, setting 0 to 1 and 1 // to 0. This behavior is widely interpreted as the correct behavior ScopeInvert // ScopeGlobal will cause the X bit to be set to 1, indicating that the // IID should be globally scoped ScopeGlobal // ScopeLocal will cause the X bit to be set to 0, indicating that the IID // should only be locally scoped ScopeLocal )