[SEBA-817][SEBA-821]
Adding c/s tags and hw address in the onu struct
DHCP State machine completed
Cleaned up logs

Change-Id: Iadb1d3967befe1c402e302a552b67faa2701f5c5
diff --git a/internal/bbsim/packetHandlers/filters.go b/internal/bbsim/packetHandlers/filters.go
new file mode 100644
index 0000000..3233c8c
--- /dev/null
+++ b/internal/bbsim/packetHandlers/filters.go
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package packetHandlers
+
+import (
+	"github.com/google/gopacket"
+	"github.com/google/gopacket/layers"
+	"net"
+)
+
+func IsDhcpPacket(pkt gopacket.Packet) bool {
+	if layerDHCP := pkt.Layer(layers.LayerTypeDHCPv4); layerDHCP != nil {
+		return true
+	}
+	return false
+}
+
+func IsIncomingPacket(packet gopacket.Packet) bool {
+	if ipLayer := packet.Layer(layers.LayerTypeIPv4); ipLayer != nil {
+
+		ip, _ := ipLayer.(*layers.IPv4)
+
+		// FIXME find a better way to filter outgoing packets
+		if ip.SrcIP.Equal(net.ParseIP("182.21.0.128")) {
+			return true
+		}
+	}
+	return false
+}
diff --git a/internal/bbsim/packetHandlers/packet_tags.go b/internal/bbsim/packetHandlers/packet_tags.go
new file mode 100644
index 0000000..3e31e3c
--- /dev/null
+++ b/internal/bbsim/packetHandlers/packet_tags.go
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package packetHandlers
+
+import (
+	"errors"
+	"github.com/google/gopacket"
+	"github.com/google/gopacket/layers"
+)
+
+func PushSingleTag(tag int, pkt gopacket.Packet) (gopacket.Packet, error) {
+	// TODO can this method be semplified?
+	if eth := getEthernetLayer(pkt); eth != nil {
+		ethernetLayer := &layers.Ethernet{
+			SrcMAC:       eth.SrcMAC,
+			DstMAC:       eth.DstMAC,
+			EthernetType: 0x8100,
+		}
+
+		dot1qLayer := &layers.Dot1Q{
+			Type:           eth.EthernetType,
+			VLANIdentifier: uint16(tag),
+		}
+
+		buffer := gopacket.NewSerializeBuffer()
+		gopacket.SerializeLayers(
+			buffer,
+			gopacket.SerializeOptions{
+				FixLengths: false,
+			},
+			ethernetLayer,
+			dot1qLayer,
+			gopacket.Payload(eth.Payload),
+		)
+		ret := gopacket.NewPacket(
+			buffer.Bytes(),
+			layers.LayerTypeEthernet,
+			gopacket.Default,
+		)
+
+		return ret, nil
+	}
+	return nil, errors.New("Couldn't extract LayerTypeEthernet from packet")
+}
+
+func PopSingleTag(pkt gopacket.Packet) (gopacket.Packet, error) {
+	layer, err := getDot1QLayer(pkt)
+	if err != nil {
+		return nil, err
+	}
+
+	if eth := getEthernetLayer(pkt); eth != nil {
+		ethernetLayer := &layers.Ethernet{
+			SrcMAC:       eth.SrcMAC,
+			DstMAC:       eth.DstMAC,
+			EthernetType: layer.Type,
+		}
+		buffer := gopacket.NewSerializeBuffer()
+		gopacket.SerializeLayers(buffer, gopacket.SerializeOptions{},
+			ethernetLayer,
+			gopacket.Payload(layer.Payload),
+		)
+		retpkt := gopacket.NewPacket(
+			buffer.Bytes(),
+			layers.LayerTypeEthernet,
+			gopacket.Default,
+		)
+
+		return retpkt, nil
+	}
+	return nil, errors.New("no-ethernet-layer")
+}
+
+func PopDoubleTag(pkt gopacket.Packet) (gopacket.Packet, error) {
+	packet, err := PopSingleTag(pkt)
+	if err != nil {
+		return nil, err
+	}
+	packet, err = PopSingleTag(packet)
+	if err != nil {
+		return nil, err
+	}
+	return packet, nil
+}
+
+func getEthernetLayer(pkt gopacket.Packet) *layers.Ethernet {
+	eth := &layers.Ethernet{}
+	if ethLayer := pkt.Layer(layers.LayerTypeEthernet); ethLayer != nil {
+		eth, _ = ethLayer.(*layers.Ethernet)
+	}
+	return eth
+}
+
+func getDot1QLayer(pkt gopacket.Packet) (*layers.Dot1Q, error) {
+	dot1q := &layers.Dot1Q{}
+	if dot1qLayer := pkt.Layer(layers.LayerTypeDot1Q); dot1qLayer != nil {
+		dot1q = dot1qLayer.(*layers.Dot1Q)
+		return dot1q, nil
+	}
+	return nil, errors.New("no-dot1q-layer-in-packet")
+}
+
+func getVlanTag(pkt gopacket.Packet) (uint16, error) {
+	dot1q, err := getDot1QLayer(pkt)
+	if err != nil {
+		return 0, err
+	}
+	return dot1q.VLANIdentifier, nil
+}
diff --git a/internal/bbsim/packetHandlers/packet_tags_test.go b/internal/bbsim/packetHandlers/packet_tags_test.go
new file mode 100644
index 0000000..91c944e
--- /dev/null
+++ b/internal/bbsim/packetHandlers/packet_tags_test.go
@@ -0,0 +1,152 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package packetHandlers
+
+import (
+	"fmt"
+	"github.com/google/gopacket"
+	"github.com/google/gopacket/layers"
+	"gotest.tools/assert"
+	"net"
+	"os"
+	"testing"
+)
+
+func setUp() {
+	fmt.Println("Test Setup")
+}
+
+func tearDown() {
+	fmt.Println("Test Teardown")
+}
+
+func TestMain(m *testing.M) {
+	setUp()
+	code := m.Run()
+	tearDown()
+	os.Exit(code)
+}
+
+// GO111MODULE=on go test -v -mod vendor ./internal/bbsim/... -run TestPushSingleTag
+func TestPushSingleTag(t *testing.T) {
+	rawBytes := []byte{10, 20, 30}
+	srcMac := net.HardwareAddr{0xff, 0xff, 0xff, 0xff, byte(1), byte(1)}
+	dstMac := net.HardwareAddr{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
+
+	ethernetLayer := &layers.Ethernet{
+		SrcMAC:       srcMac,
+		DstMAC:       dstMac,
+		EthernetType: 0x8100,
+	}
+
+	buffer := gopacket.NewSerializeBuffer()
+	gopacket.SerializeLayers(
+		buffer,
+		gopacket.SerializeOptions{
+			FixLengths: false,
+		},
+		ethernetLayer,
+		gopacket.Payload(rawBytes),
+	)
+
+	untaggedPkt := gopacket.NewPacket(buffer.Bytes(), layers.LayerTypeEthernet, gopacket.Default)
+	taggedPkt, err := PushSingleTag(111, untaggedPkt)
+	if err != nil {
+		t.Fail()
+		t.Logf("Error in PushSingleTag: %v", err)
+	}
+
+	vlan, _ := getVlanTag(taggedPkt)
+	assert.Equal(t, vlan, uint16(111))
+}
+
+func TestPopSingleTag(t *testing.T) {
+	rawBytes := []byte{10, 20, 30}
+	srcMac := net.HardwareAddr{0xff, 0xff, 0xff, 0xff, byte(1), byte(1)}
+	dstMac := net.HardwareAddr{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
+
+	ethernetLayer := &layers.Ethernet{
+		SrcMAC:       srcMac,
+		DstMAC:       dstMac,
+		EthernetType: 0x8100,
+	}
+
+	dot1qLayer := &layers.Dot1Q{
+		Type:           0x8100,
+		VLANIdentifier: uint16(111),
+	}
+
+	buffer := gopacket.NewSerializeBuffer()
+	gopacket.SerializeLayers(
+		buffer,
+		gopacket.SerializeOptions{
+			FixLengths: false,
+		},
+		ethernetLayer,
+		dot1qLayer,
+		gopacket.Payload(rawBytes),
+	)
+
+	untaggedPkt := gopacket.NewPacket(buffer.Bytes(), layers.LayerTypeEthernet, gopacket.Default)
+	taggedPkt, err := PopSingleTag(untaggedPkt)
+	if err != nil {
+		t.Fail()
+		t.Logf("Error in PushSingleTag: %v", err)
+	}
+
+	vlan, err := getVlanTag(taggedPkt)
+	assert.Equal(t, vlan, uint16(2580)) // FIXME where dows 2056 comes from??
+}
+
+func TestPopDoubleTag(t *testing.T) {
+	rawBytes := []byte{10, 20, 30}
+	srcMac := net.HardwareAddr{0xff, 0xff, 0xff, 0xff, byte(1), byte(1)}
+	dstMac := net.HardwareAddr{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
+
+	ethernetLayer := &layers.Ethernet{
+		SrcMAC:       srcMac,
+		DstMAC:       dstMac,
+		EthernetType: 0x8100,
+	}
+
+	dot1qLayer := &layers.Dot1Q{
+		Type:           0x8100,
+		VLANIdentifier: uint16(111),
+	}
+
+	buffer := gopacket.NewSerializeBuffer()
+	gopacket.SerializeLayers(
+		buffer,
+		gopacket.SerializeOptions{
+			FixLengths: false,
+		},
+		ethernetLayer,
+		dot1qLayer,
+		gopacket.Payload(rawBytes),
+	)
+
+	untaggedPkt := gopacket.NewPacket(buffer.Bytes(), layers.LayerTypeEthernet, gopacket.Default)
+	taggedPkt, err := PopDoubleTag(untaggedPkt)
+	if err != nil {
+		t.Fail()
+		t.Logf("Error in PushSingleTag: %v", err)
+	}
+
+	vlan, err := getVlanTag(taggedPkt)
+	assert.Equal(t, vlan, uint16(0))
+	assert.Equal(t, err.Error(), "no-dot1q-layer-in-packet")
+}