// Copyright 2021 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

//go:build !build_with_native_toolchain
// +build !build_with_native_toolchain

package filter

import (
	"sync"

	"gvisor.dev/gvisor/pkg/tcpip"
	"gvisor.dev/gvisor/pkg/tcpip/header"
	"gvisor.dev/gvisor/pkg/tcpip/stack"
)

var _ stack.Matcher = (*filterDisabledNICMatcher)(nil)

// filterDisabledNICMatcher is a stack.Matcher that keeps track of which
// NICs have filtering disabled.
//
// All NICs are considered to have filtering disabled until explicitly
// enabled.
type filterDisabledNICMatcher struct {
	mu struct {
		sync.RWMutex
		// nicNames are the NICs where the filter is enabled on.
		nicNames map[string]tcpip.NICID
	}
}

// Name implements stack.Matcher.
func (*filterDisabledNICMatcher) Name() string {
	return "filterDisabledNICMatcher"
}

// Match implements stack.Matcher.
func (d *filterDisabledNICMatcher) Match(hook stack.Hook, _ *stack.PacketBuffer, inNicName, outNicName string) (matches bool, hotdrop bool) {
	if inNicName != "" && d.nicDisabled(inNicName) {
		return true, false
	}
	if outNicName != "" && d.nicDisabled(outNicName) {
		return true, false
	}
	return false, false
}

func (d *filterDisabledNICMatcher) init() {
	d.mu.Lock()
	defer d.mu.Unlock()
	d.mu.nicNames = make(map[string]tcpip.NICID)
}

func (d *filterDisabledNICMatcher) nicDisabled(name string) bool {
	d.mu.RLock()
	defer d.mu.RUnlock()
	_, ok := d.mu.nicNames[name]
	return !ok
}

// portMatcher matches port to some range.
type portMatcher struct {
	start uint16
	end   uint16
}

func (m *portMatcher) match(port uint16) bool {
	return port >= m.start && port <= m.end
}

func NewTCPSourcePortMatcher(start, end uint16) *TCPSourcePortMatcher {
	return &TCPSourcePortMatcher{portMatcher: portMatcher{start, end}}
}

var _ stack.Matcher = (*TCPSourcePortMatcher)(nil)

// TCPSourcePortMatcher matches TCP packets and ports.
type TCPSourcePortMatcher struct {
	portMatcher
}

// Name implements stack.Matcher.
func (*TCPSourcePortMatcher) Name() string {
	return "TCPSourcePortMatcher"
}

// Match implements stack.Matcher.
func (m *TCPSourcePortMatcher) Match(_ stack.Hook, pkt *stack.PacketBuffer, _, _ string) (matches bool, hotdrop bool) {
	tcp := header.TCP(pkt.TransportHeader().View())
	if len(tcp) < header.TCPMinimumSize {
		// Drop immediately as the packet is invalid.
		return false, true
	}

	return m.portMatcher.match(tcp.SourcePort()), false
}

func NewTCPDestinationPortMatcher(start, end uint16) *TCPDestinationPortMatcher {
	return &TCPDestinationPortMatcher{portMatcher: portMatcher{start, end}}
}

var _ stack.Matcher = (*TCPDestinationPortMatcher)(nil)

// TCPDestinationPortMatcher matches TCP packets and ports.
type TCPDestinationPortMatcher struct {
	portMatcher
}

// Name implements stack.Matcher.
func (*TCPDestinationPortMatcher) Name() string {
	return "TCPDestinationPortMatcher"
}

// Match implements stack.Matcher.
func (m *TCPDestinationPortMatcher) Match(_ stack.Hook, pkt *stack.PacketBuffer, _, _ string) (matches bool, hotdrop bool) {
	tcp := header.TCP(pkt.TransportHeader().View())
	if len(tcp) < header.TCPMinimumSize {
		// Drop immediately as the packet is invalid.
		return false, true
	}

	return m.portMatcher.match(tcp.DestinationPort()), false
}

func NewUDPSourcePortMatcher(start, end uint16) *UDPSourcePortMatcher {
	return &UDPSourcePortMatcher{portMatcher: portMatcher{start, end}}
}

var _ stack.Matcher = (*UDPSourcePortMatcher)(nil)

// UDPSourcePortMatcher matches UDP packets and ports.
type UDPSourcePortMatcher struct {
	portMatcher
}

// Name implements stack.Matcher.
func (*UDPSourcePortMatcher) Name() string {
	return "UDPSourcePortMatcher"
}

// Match implements stack.Matcher.
func (m *UDPSourcePortMatcher) Match(_ stack.Hook, pkt *stack.PacketBuffer, _, _ string) (matches bool, hotdrop bool) {
	udp := header.UDP(pkt.TransportHeader().View())
	if len(udp) < header.UDPMinimumSize {
		// Drop immediately as the packet is invalid.
		return false, true
	}

	return m.portMatcher.match(udp.SourcePort()), false
}

func NewUDPDestinationPortMatcher(start, end uint16) *UDPDestinationPortMatcher {
	return &UDPDestinationPortMatcher{portMatcher: portMatcher{start, end}}
}

var _ stack.Matcher = (*UDPDestinationPortMatcher)(nil)

// UDPDestinationPortMatcher matches UDP packets and ports.
type UDPDestinationPortMatcher struct {
	portMatcher
}

// Name implements stack.Matcher.
func (*UDPDestinationPortMatcher) Name() string {
	return "UDPDestinationPortMatcher"
}

// Match implements stack.Matcher.
func (m *UDPDestinationPortMatcher) Match(_ stack.Hook, pkt *stack.PacketBuffer, _, _ string) (matches bool, hotdrop bool) {
	udp := header.UDP(pkt.TransportHeader().View())
	if len(udp) < header.UDPMinimumSize {
		// Drop immediately as the packet is invalid.
		return false, true
	}

	return m.portMatcher.match(udp.DestinationPort()), false
}
