func (cfg *Config) Load() error {
	cfg.loadCLIConfigEnv()
	if err := cfg.parseConfig(); err != nil {
		return fmt.Errorf("failed to read config file : %s", err.Error())
	}
	if err := cfg.parseBPF(); err != nil {
		return fmt.Errorf("failed to read BPF file : %s", err.Error())
	}
	cfg.loadCLIOverrides()
	return nil
}
Load set the default values and parse the user's config
package config
import (
	"fmt"
	"github.com/bonjourmalware/melody/internal/fileutils"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"path/filepath"
	"github.com/bonjourmalware/melody/internal/clihelper"
	"github.com/c2h5oh/datasize"
	"gopkg.in/yaml.v3"
)
const (
	UDPKind = "udp"
	TCPKind = "tcp"
	ICMPv4Kind = "icmpv4"
	ICMPv6Kind = "icmpv6"
	HTTPKind = "http"
	HTTPSKind = "https"
	defaultConfig = `---
logs.dir: "logs/"
logs.sensor.file: melody.ndjson
logs.sensor.rotation.max_size: 1G
logs.sensor.rotation.max_age: 30 # days
logs.sensor.rotation.enable: true
logs.sensor.rotation.compress: true
logs.errors.file: melody_err.log
logs.errors.rotation.max_size: 1G
logs.errors.rotation.max_age: 30 # days
logs.errors.rotation.enable: true
logs.errors.rotation.compress: true
logs.http.post.max_size: "10KB"
logs.tcp.payload.max_size: "10KB"
logs.udp.payload.max_size: "10KB"
logs.icmpv4.payload.max_size: "10KB"
logs.icmpv6.payload.max_size: "10KB"
rules.dir: "rules/rules-enabled"
rules.match.protocols: ["all"]
listen.interface: "lo"
filters.bpf.file: "filter.bpf"
filters.ipv4.proto: []
filters.ipv6.proto: []
server.http.enable: true
server.http.port: 10080
server.http.dir: "var/http/serve"
server.http.response.missing_status_code: 200
server.http.response.headers:
      Server: "Apache"
server.https.enable: true
server.https.port: 10443
server.https.dir: "var/https/serve"
server.https.crt: "var/https/certs/cert.pem"
server.https.key: "var/https/certs/key.pem"
server.https.response.missing_status_code: 200
server.https.response.headers:
      Server: "Apache"
`
)
var (
	Cfg *Config
	Cli = new(CLI)
	SupportedProtocols = []string{
		TCPKind,
		UDPKind,
		ICMPv4Kind,
		ICMPv6Kind,
		HTTPKind,
		HTTPSKind,
	}
)
type CLI struct {
	PcapFilePath   *string
	BPF            *string
	Stdout         *bool
	Interface      *string
	Dump           *bool
	ConfigFilePath *string
	ConfigDirPath  *string
	BPFFilePath    *string
	HomeDirPath    *string
	FreeConfig     clihelper.MultiString
}
type Config struct {
	ConfigFilePath string
	ConfigDirPath  string
	BPFFilePath    string
	HomeDirPath    string
	LogsDir        string `yaml:"logs.dir"`
	LogsSensorFile                string `yaml:"logs.sensor.file"`
	LogsSensorMaxSizeRaw          string `yaml:"logs.sensor.rotation.max_size"`
	LogsSensorMaxSize             int
	LogsSensorMaxAge              int  `yaml:"logs.sensor.rotation.max_age"`
	LogsSensorCompressRotatedLogs bool `yaml:"logs.sensor.rotation.compress"`
	LogSensorEnableRotation       bool `yaml:"logs.sensor.rotation.enable"`
	LogsErrorsFile                string `yaml:"logs.errors.file"`
	LogsErrorsMaxSizeRaw          string `yaml:"logs.errors.rotation.max_size"`
	LogsErrorsMaxSize             int
	LogsErrorsMaxAge              int  `yaml:"logs.errors.rotation.max_age"`
	LogsErrorsCompressRotatedLogs bool `yaml:"logs.errors.rotation.compress"`
	LogErrorsEnableRotation       bool `yaml:"logs.errors.rotation.enable"`
	RulesDir string `yaml:"rules.dir"`
	BPFFile  string `yaml:"filters.bpf.file"`
	BPF      string
	Interface            string   `yaml:"listen.interface"`
	MaxPOSTDataSizeRaw   string   `yaml:"logs.http.post.max_size"`
	MaxTCPDataSizeRaw    string   `yaml:"logs.tcp.payload.max_size"`
	MaxUDPDataSizeRaw    string   `yaml:"logs.udp.payload.max_size"`
	MaxICMPv4DataSizeRaw string   `yaml:"logs.icmpv4.payload.max_size"`
	MaxICMPv6DataSizeRaw string   `yaml:"logs.icmpv6.payload.max_size"`
	MatchProtocols       []string `yaml:"rules.match.protocols"`
	ServerHTTPEnable                bool              `yaml:"server.http.enable"`
	ServerHTTPPort                  int               `yaml:"server.http.port"`
	ServerHTTPDir                   string            `yaml:"server.http.dir"`
	ServerHTTPMissingResponseStatus int               `yaml:"server.http.response.missing_status_code"`
	ServerHTTPHeaders               map[string]string `yaml:"server.http.response.headers"`
	ServerHTTPSEnable                bool              `yaml:"server.https.enable"`
	ServerHTTPSPort                  int               `yaml:"server.https.port"`
	ServerHTTPSDir                   string            `yaml:"server.https.dir"`
	ServerHTTPSMissingResponseStatus int               `yaml:"server.https.response.missing_status_code"`
	ServerHTTPSCert                  string            `yaml:"server.https.crt"`
	ServerHTTPSKey                   string            `yaml:"server.https.key"`
	ServerHTTPSHeaders               map[string]string `yaml:"server.https.response.headers"`
	RawDiscardProto4 []string `yaml:"filters.ipv4.proto"`
	RawDiscardProto6 []string `yaml:"filters.ipv6.proto"`
	DiscardProto4 map[string]interface{}
	DiscardProto6 map[string]interface{}
	MaxPOSTDataSize   uint64
	MaxTCPDataSize    uint64
	MaxUDPDataSize    uint64
	MaxICMPv4DataSize uint64
	MaxICMPv6DataSize uint64
	PcapFile          *os.File
}
func NewConfig() *Config {
	cfg := &Config{}
	if err := yaml.Unmarshal([]byte(defaultConfig), cfg); err != nil {
		log.Println("Failed to load default config")
		log.Println(err)
		os.Exit(1)
	}
	if err := cfg.ParseConfigAt(nil); err != nil {
		log.Println("Failed to parse default config")
		log.Println(err)
		os.Exit(1)
	}
	cfg.ConfigDirPath = "."
	cfg.HomeDirPath = "."
	cfg.ConfigFilePath = "config.yml"
	cfg.BPFFilePath = "filter.bpf"
	cfg.BPF = "inbound and not net 127.0.0.0/24"
	return cfg
}