/*
 * 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"
	"net"
)

func IsDhcpPacket(pkt gopacket.Packet) bool {
	if layerDHCP := pkt.Layer(layers.LayerTypeDHCPv4); layerDHCP != nil {
		return true
	}
	return false
}

func IsIgmpPacket(pkt gopacket.Packet) bool {
	if igmpLayer := pkt.Layer(layers.LayerTypeIGMP); igmpLayer != nil {
		return true
	}
	return false
}

func IsLldpPacket(pkt gopacket.Packet) bool {
	if layer := pkt.Layer(layers.LayerTypeLinkLayerDiscovery); layer != nil {
		return true
	}
	return false
}

// return true if the packet is coming in the OLT from the DHCP Server
// given that we only check DHCP packets we can use the Operation
// Request are outgoing (toward the server)
// Replies are incoming (toward the OLT)
func IsIncomingPacket(packet gopacket.Packet) bool {
	layerDHCP := packet.Layer(layers.LayerTypeDHCPv4)
	if dhcp, ok := layerDHCP.(*layers.DHCPv4); ok {
		if dhcp.Operation == layers.DHCPOpReply {
			return true
		}
	}
	return false
}

// returns the Destination Mac Address contained in the packet
func GetDstMacAddressFromPacket(packet gopacket.Packet) (net.HardwareAddr, error) {
	if ethLayer := packet.Layer(layers.LayerTypeEthernet); ethLayer != nil {
		eth, _ := ethLayer.(*layers.Ethernet)

		if eth.DstMAC != nil {
			return eth.DstMAC, nil
		}
	}
	return nil, errors.New("cant-find-mac-address")
}

// returns the Source Mac Address contained in the packet
func GetSrcMacAddressFromPacket(packet gopacket.Packet) (net.HardwareAddr, error) {
	if ethLayer := packet.Layer(layers.LayerTypeEthernet); ethLayer != nil {
		eth, _ := ethLayer.(*layers.Ethernet)

		if eth.DstMAC != nil {
			return eth.SrcMAC, nil
		}
	}
	return nil, errors.New("cant-find-mac-address")
}

// returns wether it's an EAPOL or DHCP packet, error if it's none
func GetPktType(pkt gopacket.Packet) (PacketType, error) {
	if pkt.Layer(layers.LayerTypeEAP) != nil || pkt.Layer(layers.LayerTypeEAPOL) != nil {
		return EAPOL, nil
	} else if IsDhcpPacket(pkt) {
		return DHCP, nil
	} else if IsIgmpPacket(pkt) {
		return IGMP, nil
	}
	return UNKNOWN, errors.New("unknown-packet-type")
}
