First Commit of Voltha-Go-Controller from Radisys

Change-Id: I8e2e908e7ab09a4fe3d86849da18b6d69dcf4ab0
diff --git a/vendor/github.com/google/gopacket/layers/dhcpv4.go b/vendor/github.com/google/gopacket/layers/dhcpv4.go
new file mode 100644
index 0000000..67c80b7
--- /dev/null
+++ b/vendor/github.com/google/gopacket/layers/dhcpv4.go
@@ -0,0 +1,595 @@
+// Copyright 2016 Google, Inc. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree.
+
+package layers
+
+import (
+	"bytes"
+	"encoding/binary"
+	"fmt"
+	"net"
+
+	"github.com/google/gopacket"
+)
+
+// DHCPOp rerprents a bootp operation
+type DHCPOp byte
+
+// bootp operations
+const (
+	DHCPOpRequest DHCPOp = 1
+	DHCPOpReply   DHCPOp = 2
+)
+
+// String returns a string version of a DHCPOp.
+func (o DHCPOp) String() string {
+	switch o {
+	case DHCPOpRequest:
+		return "Request"
+	case DHCPOpReply:
+		return "Reply"
+	default:
+		return "Unknown"
+	}
+}
+
+// DHCPMsgType represents a DHCP operation
+type DHCPMsgType byte
+
+// Constants that represent DHCP operations
+const (
+	DHCPMsgTypeUnspecified DHCPMsgType = iota
+	DHCPMsgTypeDiscover
+	DHCPMsgTypeOffer
+	DHCPMsgTypeRequest
+	DHCPMsgTypeDecline
+	DHCPMsgTypeAck
+	DHCPMsgTypeNak
+	DHCPMsgTypeRelease
+	DHCPMsgTypeInform
+)
+
+// String returns a string version of a DHCPMsgType.
+func (o DHCPMsgType) String() string {
+	switch o {
+	case DHCPMsgTypeUnspecified:
+		return "Unspecified"
+	case DHCPMsgTypeDiscover:
+		return "Discover"
+	case DHCPMsgTypeOffer:
+		return "Offer"
+	case DHCPMsgTypeRequest:
+		return "Request"
+	case DHCPMsgTypeDecline:
+		return "Decline"
+	case DHCPMsgTypeAck:
+		return "Ack"
+	case DHCPMsgTypeNak:
+		return "Nak"
+	case DHCPMsgTypeRelease:
+		return "Release"
+	case DHCPMsgTypeInform:
+		return "Inform"
+	default:
+		return "Unknown"
+	}
+}
+
+//DHCPMagic is the RFC 2131 "magic cooke" for DHCP.
+var DHCPMagic uint32 = 0x63825363
+
+// DHCPv4 contains data for a single DHCP packet.
+type DHCPv4 struct {
+	BaseLayer
+	Operation    DHCPOp
+	HardwareType LinkType
+	HardwareLen  uint8
+	HardwareOpts uint8
+	Xid          uint32
+	Secs         uint16
+	Flags        uint16
+	ClientIP     net.IP
+	YourClientIP net.IP
+	NextServerIP net.IP
+	RelayAgentIP net.IP
+	ClientHWAddr net.HardwareAddr
+	ServerName   []byte
+	File         []byte
+	Options      DHCPOptions
+}
+
+// DHCPOptions is used to get nicely printed option lists which would normally
+// be cut off after 5 options.
+type DHCPOptions []DHCPOption
+
+// String returns a string version of the options list.
+func (o DHCPOptions) String() string {
+	buf := &bytes.Buffer{}
+	buf.WriteByte('[')
+	for i, opt := range o {
+		buf.WriteString(opt.String())
+		if i+1 != len(o) {
+			buf.WriteString(", ")
+		}
+	}
+	buf.WriteByte(']')
+	return buf.String()
+}
+
+// LayerType returns gopacket.LayerTypeDHCPv4
+func (d *DHCPv4) LayerType() gopacket.LayerType { return LayerTypeDHCPv4 }
+
+// DecodeFromBytes decodes the given bytes into this layer.
+func (d *DHCPv4) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
+	if len(data) < 240 {
+		df.SetTruncated()
+		return fmt.Errorf("DHCPv4 length %d too short", len(data))
+	}
+	d.Options = d.Options[:0]
+	d.Operation = DHCPOp(data[0])
+	d.HardwareType = LinkType(data[1])
+	d.HardwareLen = data[2]
+	d.HardwareOpts = data[3]
+	d.Xid = binary.BigEndian.Uint32(data[4:8])
+	d.Secs = binary.BigEndian.Uint16(data[8:10])
+	d.Flags = binary.BigEndian.Uint16(data[10:12])
+	d.ClientIP = net.IP(data[12:16])
+	d.YourClientIP = net.IP(data[16:20])
+	d.NextServerIP = net.IP(data[20:24])
+	d.RelayAgentIP = net.IP(data[24:28])
+	d.ClientHWAddr = net.HardwareAddr(data[28 : 28+d.HardwareLen])
+	d.ServerName = data[44:108]
+	d.File = data[108:236]
+	if binary.BigEndian.Uint32(data[236:240]) != DHCPMagic {
+		return InvalidMagicCookie
+	}
+
+	if len(data) <= 240 {
+		// DHCP Packet could have no option (??)
+		return nil
+	}
+
+	options := data[240:]
+
+	stop := len(options)
+	start := 0
+	for start < stop {
+		o := DHCPOption{}
+		if err := o.decode(options[start:]); err != nil {
+			return err
+		}
+		if o.Type == DHCPOptEnd {
+			break
+		}
+		d.Options = append(d.Options, o)
+		// Check if the option is a single byte pad
+		if o.Type == DHCPOptPad {
+			start++
+		} else {
+			start += int(o.Length) + 2
+		}
+	}
+
+	d.Contents = data
+
+	return nil
+}
+
+// Len returns the length of a DHCPv4 packet.
+func (d *DHCPv4) Len() uint16 {
+	n := uint16(240)
+	for _, o := range d.Options {
+		if o.Type == DHCPOptPad {
+			n++
+		} else {
+			n += uint16(o.Length) + 2
+		}
+	}
+	n++ // for opt end
+	return n
+}
+
+// SerializeTo writes the serialized form of this layer into the
+// SerializationBuffer, implementing gopacket.SerializableLayer.
+// See the docs for gopacket.SerializableLayer for more info.
+func (d *DHCPv4) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
+	plen := int(d.Len())
+
+	data, err := b.PrependBytes(plen)
+	if err != nil {
+		return err
+	}
+
+	data[0] = byte(d.Operation)
+	data[1] = byte(d.HardwareType)
+	if opts.FixLengths {
+		d.HardwareLen = uint8(len(d.ClientHWAddr))
+	}
+	data[2] = d.HardwareLen
+	data[3] = d.HardwareOpts
+	binary.BigEndian.PutUint32(data[4:8], d.Xid)
+	binary.BigEndian.PutUint16(data[8:10], d.Secs)
+	binary.BigEndian.PutUint16(data[10:12], d.Flags)
+	copy(data[12:16], d.ClientIP.To4())
+	copy(data[16:20], d.YourClientIP.To4())
+	copy(data[20:24], d.NextServerIP.To4())
+	copy(data[24:28], d.RelayAgentIP.To4())
+	copy(data[28:44], d.ClientHWAddr)
+	copy(data[44:108], d.ServerName)
+	copy(data[108:236], d.File)
+	binary.BigEndian.PutUint32(data[236:240], DHCPMagic)
+
+	if len(d.Options) > 0 {
+		offset := 240
+		for _, o := range d.Options {
+			if err := o.encode(data[offset:]); err != nil {
+				return err
+			}
+			// A pad option is only a single byte
+			if o.Type == DHCPOptPad {
+				offset++
+			} else {
+				offset += 2 + len(o.Data)
+			}
+		}
+		optend := NewDHCPOption(DHCPOptEnd, nil)
+		if err := optend.encode(data[offset:]); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+// CanDecode returns the set of layer types that this DecodingLayer can decode.
+func (d *DHCPv4) CanDecode() gopacket.LayerClass {
+	return LayerTypeDHCPv4
+}
+
+// NextLayerType returns the layer type contained by this DecodingLayer.
+func (d *DHCPv4) NextLayerType() gopacket.LayerType {
+	return gopacket.LayerTypePayload
+}
+
+func decodeDHCPv4(data []byte, p gopacket.PacketBuilder) error {
+	dhcp := &DHCPv4{}
+	err := dhcp.DecodeFromBytes(data, p)
+	if err != nil {
+		return err
+	}
+	p.AddLayer(dhcp)
+	return p.NextDecoder(gopacket.LayerTypePayload)
+}
+
+// DHCPOpt represents a DHCP option or parameter from RFC-2132
+type DHCPOpt byte
+
+// Constants for the DHCPOpt options.
+const (
+	DHCPOptPad                   DHCPOpt = 0
+	DHCPOptSubnetMask            DHCPOpt = 1   // 4, net.IP
+	DHCPOptTimeOffset            DHCPOpt = 2   // 4, int32 (signed seconds from UTC)
+	DHCPOptRouter                DHCPOpt = 3   // n*4, [n]net.IP
+	DHCPOptTimeServer            DHCPOpt = 4   // n*4, [n]net.IP
+	DHCPOptNameServer            DHCPOpt = 5   // n*4, [n]net.IP
+	DHCPOptDNS                   DHCPOpt = 6   // n*4, [n]net.IP
+	DHCPOptLogServer             DHCPOpt = 7   // n*4, [n]net.IP
+	DHCPOptCookieServer          DHCPOpt = 8   // n*4, [n]net.IP
+	DHCPOptLPRServer             DHCPOpt = 9   // n*4, [n]net.IP
+	DHCPOptImpressServer         DHCPOpt = 10  // n*4, [n]net.IP
+	DHCPOptResLocServer          DHCPOpt = 11  // n*4, [n]net.IP
+	DHCPOptHostname              DHCPOpt = 12  // n, string
+	DHCPOptBootfileSize          DHCPOpt = 13  // 2, uint16
+	DHCPOptMeritDumpFile         DHCPOpt = 14  // >1, string
+	DHCPOptDomainName            DHCPOpt = 15  // n, string
+	DHCPOptSwapServer            DHCPOpt = 16  // n*4, [n]net.IP
+	DHCPOptRootPath              DHCPOpt = 17  // n, string
+	DHCPOptExtensionsPath        DHCPOpt = 18  // n, string
+	DHCPOptIPForwarding          DHCPOpt = 19  // 1, bool
+	DHCPOptSourceRouting         DHCPOpt = 20  // 1, bool
+	DHCPOptPolicyFilter          DHCPOpt = 21  // 8*n, [n]{net.IP/net.IP}
+	DHCPOptDatagramMTU           DHCPOpt = 22  // 2, uint16
+	DHCPOptDefaultTTL            DHCPOpt = 23  // 1, byte
+	DHCPOptPathMTUAgingTimeout   DHCPOpt = 24  // 4, uint32
+	DHCPOptPathPlateuTableOption DHCPOpt = 25  // 2*n, []uint16
+	DHCPOptInterfaceMTU          DHCPOpt = 26  // 2, uint16
+	DHCPOptAllSubsLocal          DHCPOpt = 27  // 1, bool
+	DHCPOptBroadcastAddr         DHCPOpt = 28  // 4, net.IP
+	DHCPOptMaskDiscovery         DHCPOpt = 29  // 1, bool
+	DHCPOptMaskSupplier          DHCPOpt = 30  // 1, bool
+	DHCPOptRouterDiscovery       DHCPOpt = 31  // 1, bool
+	DHCPOptSolicitAddr           DHCPOpt = 32  // 4, net.IP
+	DHCPOptStaticRoute           DHCPOpt = 33  // n*8, [n]{net.IP/net.IP} -- note the 2nd is router not mask
+	DHCPOptARPTrailers           DHCPOpt = 34  // 1, bool
+	DHCPOptARPTimeout            DHCPOpt = 35  // 4, uint32
+	DHCPOptEthernetEncap         DHCPOpt = 36  // 1, bool
+	DHCPOptTCPTTL                DHCPOpt = 37  // 1, byte
+	DHCPOptTCPKeepAliveInt       DHCPOpt = 38  // 4, uint32
+	DHCPOptTCPKeepAliveGarbage   DHCPOpt = 39  // 1, bool
+	DHCPOptNISDomain             DHCPOpt = 40  // n, string
+	DHCPOptNISServers            DHCPOpt = 41  // 4*n,  [n]net.IP
+	DHCPOptNTPServers            DHCPOpt = 42  // 4*n, [n]net.IP
+	DHCPOptVendorOption          DHCPOpt = 43  // n, [n]byte // may be encapsulated.
+	DHCPOptNetBIOSTCPNS          DHCPOpt = 44  // 4*n, [n]net.IP
+	DHCPOptNetBIOSTCPDDS         DHCPOpt = 45  // 4*n, [n]net.IP
+	DHCPOptNETBIOSTCPNodeType    DHCPOpt = 46  // 1, magic byte
+	DHCPOptNetBIOSTCPScope       DHCPOpt = 47  // n, string
+	DHCPOptXFontServer           DHCPOpt = 48  // n, string
+	DHCPOptXDisplayManager       DHCPOpt = 49  // n, string
+	DHCPOptRequestIP             DHCPOpt = 50  // 4, net.IP
+	DHCPOptLeaseTime             DHCPOpt = 51  // 4, uint32
+	DHCPOptExtOptions            DHCPOpt = 52  // 1, 1/2/3
+	DHCPOptMessageType           DHCPOpt = 53  // 1, 1-7
+	DHCPOptServerID              DHCPOpt = 54  // 4, net.IP
+	DHCPOptParamsRequest         DHCPOpt = 55  // n, []byte
+	DHCPOptMessage               DHCPOpt = 56  // n, 3
+	DHCPOptMaxMessageSize        DHCPOpt = 57  // 2, uint16
+	DHCPOptT1                    DHCPOpt = 58  // 4, uint32
+	DHCPOptT2                    DHCPOpt = 59  // 4, uint32
+	DHCPOptClassID               DHCPOpt = 60  // n, []byte
+	DHCPOptClientID              DHCPOpt = 61  // n >=  2, []byte
+	DHCPOptDomainSearch          DHCPOpt = 119 // n, string
+	DHCPOptSIPServers            DHCPOpt = 120 // n, url
+	DHCPOptClasslessStaticRoute  DHCPOpt = 121 //
+	DHCPOptMUDURLV4              DHCPOpt = 161 // n, string
+	DHCPOptEnd                   DHCPOpt = 255
+)
+
+// String returns a string version of a DHCPOpt.
+func (o DHCPOpt) String() string {
+	switch o {
+	case DHCPOptPad:
+		return "(padding)"
+	case DHCPOptSubnetMask:
+		return "SubnetMask"
+	case DHCPOptTimeOffset:
+		return "TimeOffset"
+	case DHCPOptRouter:
+		return "Router"
+	case DHCPOptTimeServer:
+		return "rfc868" // old time server protocol stringified to dissuade confusion w. NTP
+	case DHCPOptNameServer:
+		return "ien116" // obscure nameserver protocol stringified to dissuade confusion w. DNS
+	case DHCPOptDNS:
+		return "DNS"
+	case DHCPOptLogServer:
+		return "mitLCS" // MIT LCS server protocol yada yada w. Syslog
+	case DHCPOptCookieServer:
+		return "CookieServer"
+	case DHCPOptLPRServer:
+		return "LPRServer"
+	case DHCPOptImpressServer:
+		return "ImpressServer"
+	case DHCPOptResLocServer:
+		return "ResourceLocationServer"
+	case DHCPOptHostname:
+		return "Hostname"
+	case DHCPOptBootfileSize:
+		return "BootfileSize"
+	case DHCPOptMeritDumpFile:
+		return "MeritDumpFile"
+	case DHCPOptDomainName:
+		return "DomainName"
+	case DHCPOptSwapServer:
+		return "SwapServer"
+	case DHCPOptRootPath:
+		return "RootPath"
+	case DHCPOptExtensionsPath:
+		return "ExtensionsPath"
+	case DHCPOptIPForwarding:
+		return "IPForwarding"
+	case DHCPOptSourceRouting:
+		return "SourceRouting"
+	case DHCPOptPolicyFilter:
+		return "PolicyFilter"
+	case DHCPOptDatagramMTU:
+		return "DatagramMTU"
+	case DHCPOptDefaultTTL:
+		return "DefaultTTL"
+	case DHCPOptPathMTUAgingTimeout:
+		return "PathMTUAgingTimeout"
+	case DHCPOptPathPlateuTableOption:
+		return "PathPlateuTableOption"
+	case DHCPOptInterfaceMTU:
+		return "InterfaceMTU"
+	case DHCPOptAllSubsLocal:
+		return "AllSubsLocal"
+	case DHCPOptBroadcastAddr:
+		return "BroadcastAddress"
+	case DHCPOptMaskDiscovery:
+		return "MaskDiscovery"
+	case DHCPOptMaskSupplier:
+		return "MaskSupplier"
+	case DHCPOptRouterDiscovery:
+		return "RouterDiscovery"
+	case DHCPOptSolicitAddr:
+		return "SolicitAddr"
+	case DHCPOptStaticRoute:
+		return "StaticRoute"
+	case DHCPOptARPTrailers:
+		return "ARPTrailers"
+	case DHCPOptARPTimeout:
+		return "ARPTimeout"
+	case DHCPOptEthernetEncap:
+		return "EthernetEncap"
+	case DHCPOptTCPTTL:
+		return "TCPTTL"
+	case DHCPOptTCPKeepAliveInt:
+		return "TCPKeepAliveInt"
+	case DHCPOptTCPKeepAliveGarbage:
+		return "TCPKeepAliveGarbage"
+	case DHCPOptNISDomain:
+		return "NISDomain"
+	case DHCPOptNISServers:
+		return "NISServers"
+	case DHCPOptNTPServers:
+		return "NTPServers"
+	case DHCPOptVendorOption:
+		return "VendorOption"
+	case DHCPOptNetBIOSTCPNS:
+		return "NetBIOSOverTCPNS"
+	case DHCPOptNetBIOSTCPDDS:
+		return "NetBiosOverTCPDDS"
+	case DHCPOptNETBIOSTCPNodeType:
+		return "NetBIOSOverTCPNodeType"
+	case DHCPOptNetBIOSTCPScope:
+		return "NetBIOSOverTCPScope"
+	case DHCPOptXFontServer:
+		return "XFontServer"
+	case DHCPOptXDisplayManager:
+		return "XDisplayManager"
+	case DHCPOptEnd:
+		return "(end)"
+	case DHCPOptSIPServers:
+		return "SipServers"
+	case DHCPOptRequestIP:
+		return "RequestIP"
+	case DHCPOptLeaseTime:
+		return "LeaseTime"
+	case DHCPOptExtOptions:
+		return "ExtOpts"
+	case DHCPOptMessageType:
+		return "MessageType"
+	case DHCPOptServerID:
+		return "ServerID"
+	case DHCPOptParamsRequest:
+		return "ParamsRequest"
+	case DHCPOptMessage:
+		return "Message"
+	case DHCPOptMaxMessageSize:
+		return "MaxDHCPSize"
+	case DHCPOptT1:
+		return "Timer1"
+	case DHCPOptT2:
+		return "Timer2"
+	case DHCPOptClassID:
+		return "ClassID"
+	case DHCPOptClientID:
+		return "ClientID"
+	case DHCPOptDomainSearch:
+		return "DomainSearch"
+	case DHCPOptClasslessStaticRoute:
+		return "ClasslessStaticRoute"
+	case DHCPOptMUDURLV4:
+		return "ManufacturerUsageDescriptionURL"
+	default:
+		return "Unknown"
+	}
+}
+
+// DHCPOption rerpresents a DHCP option.
+type DHCPOption struct {
+	Type   DHCPOpt
+	Length uint8
+	Data   []byte
+}
+
+// String returns a string version of a DHCP Option.
+func (o DHCPOption) String() string {
+	switch o.Type {
+
+	case DHCPOptHostname, DHCPOptMeritDumpFile, DHCPOptDomainName, DHCPOptRootPath,
+		DHCPOptExtensionsPath, DHCPOptNISDomain, DHCPOptNetBIOSTCPScope, DHCPOptXFontServer,
+		DHCPOptXDisplayManager, DHCPOptMessage, DHCPOptDomainSearch: // string
+		return fmt.Sprintf("Option(%s:%s)", o.Type, string(o.Data))
+
+	case DHCPOptMessageType:
+		if len(o.Data) != 1 {
+			return fmt.Sprintf("Option(%s:INVALID)", o.Type)
+		}
+		return fmt.Sprintf("Option(%s:%s)", o.Type, DHCPMsgType(o.Data[0]))
+
+	case DHCPOptSubnetMask, DHCPOptServerID, DHCPOptBroadcastAddr,
+		DHCPOptSolicitAddr, DHCPOptRequestIP: // net.IP
+		if len(o.Data) < 4 {
+			return fmt.Sprintf("Option(%s:INVALID)", o.Type)
+		}
+		return fmt.Sprintf("Option(%s:%s)", o.Type, net.IP(o.Data))
+
+	case DHCPOptT1, DHCPOptT2, DHCPOptLeaseTime, DHCPOptPathMTUAgingTimeout,
+		DHCPOptARPTimeout, DHCPOptTCPKeepAliveInt: // uint32
+		if len(o.Data) != 4 {
+			return fmt.Sprintf("Option(%s:INVALID)", o.Type)
+		}
+		return fmt.Sprintf("Option(%s:%d)", o.Type,
+			uint32(o.Data[0])<<24|uint32(o.Data[1])<<16|uint32(o.Data[2])<<8|uint32(o.Data[3]))
+
+	case DHCPOptParamsRequest:
+		buf := &bytes.Buffer{}
+		buf.WriteString(fmt.Sprintf("Option(%s:", o.Type))
+		for i, v := range o.Data {
+			buf.WriteString(DHCPOpt(v).String())
+			if i+1 != len(o.Data) {
+				buf.WriteByte(',')
+			}
+		}
+		buf.WriteString(")")
+		return buf.String()
+
+	default:
+		return fmt.Sprintf("Option(%s:%v)", o.Type, o.Data)
+	}
+}
+
+// NewDHCPOption constructs a new DHCPOption with a given type and data.
+func NewDHCPOption(t DHCPOpt, data []byte) DHCPOption {
+	o := DHCPOption{Type: t}
+	if data != nil {
+		o.Data = data
+		o.Length = uint8(len(data))
+	}
+	return o
+}
+
+func (o *DHCPOption) encode(b []byte) error {
+	switch o.Type {
+	case DHCPOptPad, DHCPOptEnd:
+		b[0] = byte(o.Type)
+	default:
+		b[0] = byte(o.Type)
+		b[1] = o.Length
+		copy(b[2:], o.Data)
+	}
+	return nil
+}
+
+func (o *DHCPOption) decode(data []byte) error {
+	if len(data) < 1 {
+		// Pad/End have a length of 1
+		return DecOptionNotEnoughData
+	}
+	o.Type = DHCPOpt(data[0])
+	switch o.Type {
+	case DHCPOptPad, DHCPOptEnd:
+		o.Data = nil
+	default:
+		if len(data) < 2 {
+			return DecOptionNotEnoughData
+		}
+		o.Length = data[1]
+		if int(o.Length) > len(data[2:]) {
+			return DecOptionMalformed
+		}
+		o.Data = data[2 : 2+int(o.Length)]
+	}
+	return nil
+}
+
+// DHCPv4Error is used for constant errors for DHCPv4. It is needed for test asserts.
+type DHCPv4Error string
+
+// DHCPv4Error implements error interface.
+func (d DHCPv4Error) Error() string {
+	return string(d)
+}
+
+const (
+	// DecOptionNotEnoughData is returned when there is not enough data during option's decode process
+	DecOptionNotEnoughData = DHCPv4Error("Not enough data to decode")
+	// DecOptionMalformed is returned when the option is malformed
+	DecOptionMalformed = DHCPv4Error("Option is malformed")
+	// InvalidMagicCookie is returned when Magic cookie is missing into BOOTP header
+	InvalidMagicCookie = DHCPv4Error("Bad DHCP header")
+)