diff --git a/vendor/github.com/google/gopacket/layers/pppoe.go b/vendor/github.com/google/gopacket/layers/pppoe.go
new file mode 100644
index 0000000..9a40e2d
--- /dev/null
+++ b/vendor/github.com/google/gopacket/layers/pppoe.go
@@ -0,0 +1,206 @@
+// Copyright 2012 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"
+
+	"github.com/google/gopacket"
+)
+
+type PPPoEOpt uint16
+
+// Constants for PPPoE Options
+const (
+	PPPoEOptEndOfList        PPPoEOpt = 0x0000
+	PPPoEOptServiceName      PPPoEOpt = 0x0101
+	PPPoEOptAcName           PPPoEOpt = 0x0102
+	PPPoEOptHostUniq         PPPoEOpt = 0x0103
+	PPPoEOptAcCookie         PPPoEOpt = 0x0104
+	PPPoEOptVendorSpecific   PPPoEOpt = 0x0105
+	PPPoEOptRelaySessionId   PPPoEOpt = 0x0110
+	PPPoEOptServiceErrorName PPPoEOpt = 0x0201
+	PPPoEOptAcSystemError    PPPoEOpt = 0x0202
+	PPPoEOptGenericError     PPPoEOpt = 0x0203
+)
+
+type PPPoEOption struct {
+	Type   PPPoEOpt
+	Length uint16
+	Data   []byte
+}
+
+func (o PPPoEOption) encode(b []byte) (uint16, error) {
+	binary.BigEndian.PutUint16(b[0:2], uint16(o.Type))
+	binary.BigEndian.PutUint16(b[2:4], uint16(o.Length))
+	copy(b[4:], o.Data)
+	return (4 + o.Length), nil
+}
+
+func (o PPPoEOption) decode(b []byte) error {
+	if len(b) < 4 {
+		return DecOptionNotEnoughData
+	}
+	o.Type = PPPoEOpt(binary.BigEndian.Uint16(b[0:2]))
+	o.Length = binary.BigEndian.Uint16(b[2:4])
+	if int(o.Length) > len(b[4:]) {
+		return DecOptionNotEnoughData
+	}
+	o.Data = b[4 : 4+int(o.Length)]
+	return nil
+}
+
+func NewPPPoEOption(opt PPPoEOpt, data []byte) PPPoEOption {
+	length := (uint16)(len(data))
+	option := PPPoEOption{Type: opt, Length: length, Data: data}
+	return option
+}
+
+func (o PPPoEOption) String() string {
+	return fmt.Sprintf("Option(%s:%v)", o.Type, o.Data)
+}
+
+func (o PPPoEOption) length() int {
+	return 4 + int(o.Length)
+}
+
+type PPPoEOptions []PPPoEOption
+
+// String returns a string version of the options list.
+func (o PPPoEOptions) 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()
+}
+
+func (o PPPoEOptions) length() int {
+	length := 0
+	for _, op := range o {
+		length = length + op.length()
+	}
+	return length
+}
+
+// String returns a string version of a PPPoEOpt.
+func (o PPPoEOpt) String() string {
+	switch o {
+	case PPPoEOptEndOfList:
+		return "EndOfList"
+	case PPPoEOptServiceName:
+		return "ServiceName"
+	case PPPoEOptAcName:
+		return "AcName"
+	case PPPoEOptHostUniq:
+		return "HostUniq"
+	case PPPoEOptAcCookie:
+		return "AcCookie"
+	case PPPoEOptVendorSpecific:
+		return "VendorSpecific"
+	case PPPoEOptRelaySessionId:
+		return "RelaySessionId"
+	case PPPoEOptServiceErrorName:
+		return "ServiceErrorName"
+	case PPPoEOptAcSystemError:
+		return "AcSystemError"
+	case PPPoEOptGenericError:
+		return "GenericError"
+	default:
+		return "Unknown"
+	}
+}
+
+// PPPoE is the layer for PPPoE encapsulation headers.
+type PPPoE struct {
+	BaseLayer
+	Version   uint8
+	Type      uint8
+	Code      PPPoECode
+	SessionId uint16
+	Length    uint16
+	Options   PPPoEOptions
+}
+
+// LayerType returns gopacket.LayerTypePPPoE.
+func (p *PPPoE) LayerType() gopacket.LayerType {
+	return LayerTypePPPoE
+}
+
+func (p *PPPoE) DecodeOptions(data []byte, len uint16) {
+
+	start := uint16(0)
+	stop := len
+	for start < stop {
+		pppoeOpt := &PPPoEOption{}
+		pppoeOpt.Type = PPPoEOpt(binary.BigEndian.Uint16(data[start : start+2]))
+		pppoeOpt.Length = binary.BigEndian.Uint16(data[start+2 : start+4])
+		if pppoeOpt.Length != 0 {
+			pppoeOpt.Data = data[start+4 : start+4+pppoeOpt.Length]
+		}
+		start = start + 4 + pppoeOpt.Length
+		p.Options = append(p.Options, *pppoeOpt)
+	}
+
+}
+
+// decodePPPoE decodes the PPPoE header (see http://tools.ietf.org/html/rfc2516).
+func decodePPPoE(data []byte, p gopacket.PacketBuilder) error {
+
+	pppoe := &PPPoE{
+		Version:   data[0] >> 4,
+		Type:      data[0] & 0x0F,
+		Code:      PPPoECode(data[1]),
+		SessionId: binary.BigEndian.Uint16(data[2:4]),
+		Length:    binary.BigEndian.Uint16(data[4:6]),
+	}
+	pppoe.DecodeOptions(data[6:], pppoe.Length)
+	pppoe.BaseLayer = BaseLayer{data[:6], data[6 : 6+pppoe.Length]}
+	p.AddLayer(pppoe)
+	return p.NextDecoder(pppoe.Code)
+}
+
+// SerializeTo writes the serialized form of this layer into the
+// SerializationBuffer, implementing gopacket.SerializableLayer.
+// See the docs for gopacket.SerializableLayer for more info.
+func (p *PPPoE) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
+	payload := b.Bytes()
+
+	//Pkt length with Options
+	length := 6
+	optLength := 0
+	for _, o := range p.Options {
+		optLength = optLength + o.length()
+	}
+
+	bytes, err := b.PrependBytes(length + optLength)
+	if err != nil {
+		return err
+	}
+	bytes[0] = (p.Version << 4) | p.Type
+	bytes[1] = byte(p.Code)
+	binary.BigEndian.PutUint16(bytes[2:], p.SessionId)
+	if opts.FixLengths {
+		p.Length = uint16(len(payload) + optLength)
+	}
+	binary.BigEndian.PutUint16(bytes[4:], p.Length)
+
+	//Encoding the options
+	start := uint16(6)
+	for _, option := range p.Options {
+		optLen, _ := option.encode(bytes[start:])
+		start = start + optLen
+	}
+	return nil
+}
