func (f *ScmpFilter) GetSSB() (bool, error) {
	ssb, err := f.getFilterAttr(filterAttrSSB)
	if err != nil {
		if e := checkAPI("GetSSB", 4, 2, 5, 0); e != nil {
			err = e
		}
		return false, err
	}
	if ssb == 0 {
		return false, nil
	}
	return true, nil
}
GetSSB returns the current state the SSB bit will be set to on the filter
being loaded, or an error if an issue was encountered retrieving the value.
The SSB bit tells the kernel that a seccomp user is not interested in enabling
Speculative Store Bypass mitigation.
The SSB bit is only usable when libseccomp API level 4 or higher is
supported.
package seccomp
import (
	"fmt"
	"os"
	"runtime"
	"strings"
	"sync"
	"syscall"
	"unsafe"
)
import "C"
type VersionError struct {
	op                  string  
	major, minor, micro uint    
	curAPI, minAPI      uint    
}
func init() {
	_, _ = getAPI()
}
func (e VersionError) Error() string {
	if e.minAPI != 0 {
		return fmt.Sprintf("%s requires libseccomp >= %d.%d.%d and API level >= %d "+
			"(current version: %d.%d.%d, API level: %d)",
			e.op, e.major, e.minor, e.micro, e.minAPI,
			verMajor, verMinor, verMicro, e.curAPI)
	}
	return fmt.Sprintf("%s requires libseccomp >= %d.%d.%d (current version: %d.%d.%d)",
		e.op, e.major, e.minor, e.micro, verMajor, verMinor, verMicro)
}
type ScmpArch uint
type ScmpAction uint
type ScmpCompareOp uint
type ScmpCondition struct {
	Argument uint          `json:"argument,omitempty"`
	Op       ScmpCompareOp `json:"operator,omitempty"`
	Operand1 uint64        `json:"operand_one,omitempty"`
	Operand2 uint64        `json:"operand_two,omitempty"`
}
type ScmpSyscall int32
type ScmpFd int32
type ScmpNotifData struct {
	Syscall      ScmpSyscall `json:"syscall,omitempty"`
	Arch         ScmpArch    `json:"arch,omitempty"`
	InstrPointer uint64      `json:"instr_pointer,omitempty"`
	Args         []uint64    `json:"args,omitempty"`
}
type ScmpNotifReq struct {
	ID    uint64        `json:"id,omitempty"`
	Pid   uint32        `json:"pid,omitempty"`
	Flags uint32        `json:"flags,omitempty"`
	Data  ScmpNotifData `json:"data,omitempty"`
}
type ScmpNotifResp struct {
	ID    uint64 `json:"id,omitempty"`
	Error int32  `json:"error,omitempty"`
	Val   uint64 `json:"val,omitempty"`
	Flags uint32 `json:"flags,omitempty"`
}
const (
	ArchInvalid ScmpArch = iota
	ArchNative
	ArchX86
	ArchAMD64
	ArchX32
	ArchARM
	ArchARM64
	ArchMIPS
	ArchMIPS64
	ArchMIPS64N32
	ArchMIPSEL
	ArchMIPSEL64
	ArchMIPSEL64N32
	ArchPPC
	ArchPPC64
	ArchPPC64LE
	ArchS390
	ArchS390X
	ArchPARISC
	ArchPARISC64
	ArchRISCV64
)
const (
	ActInvalid ScmpAction = iota
	ActKill
	ActTrap
	ActNotify
	ActErrno
	ActTrace
	ActAllow
	ActLog
	ActKillThread
	ActKillProcess
)
const (
	CompareInvalid ScmpCompareOp = iota
	CompareNotEqual
	CompareLess
	CompareLessOrEqual
	CompareEqual
	CompareGreaterEqual
	CompareGreater
	CompareMaskedEqual
)
var ErrSyscallDoesNotExist = fmt.Errorf("could not resolve syscall name")
const (
	NotifRespFlagContinue uint32 = 1
)
func GetArchFromString(arch string) (ScmpArch, error) {
	if err := ensureSupportedVersion(); err != nil {
		return ArchInvalid, err
	}
	switch strings.ToLower(arch) {
	case "x86":
		return ArchX86, nil
	case "amd64", "x86-64", "x86_64", "x64":
		return ArchAMD64, nil
	case "x32":
		return ArchX32, nil
	case "arm":
		return ArchARM, nil
	case "arm64", "aarch64":
		return ArchARM64, nil
	case "mips":
		return ArchMIPS, nil
	case "mips64":
		return ArchMIPS64, nil
	case "mips64n32":
		return ArchMIPS64N32, nil
	case "mipsel":
		return ArchMIPSEL, nil
	case "mipsel64":
		return ArchMIPSEL64, nil
	case "mipsel64n32":
		return ArchMIPSEL64N32, nil
	case "ppc":
		return ArchPPC, nil
	case "ppc64":
		return ArchPPC64, nil
	case "ppc64le":
		return ArchPPC64LE, nil
	case "s390":
		return ArchS390, nil
	case "s390x":
		return ArchS390X, nil
	case "parisc":
		return ArchPARISC, nil
	case "parisc64":
		return ArchPARISC64, nil
	case "riscv64":
		return ArchRISCV64, nil
	default:
		return ArchInvalid, fmt.Errorf("cannot convert unrecognized string %q", arch)
	}
}
func (a ScmpArch) String() string {
	switch a {
	case ArchX86:
		return "x86"
	case ArchAMD64:
		return "amd64"
	case ArchX32:
		return "x32"
	case ArchARM:
		return "arm"
	case ArchARM64:
		return "arm64"
	case ArchMIPS:
		return "mips"
	case ArchMIPS64:
		return "mips64"
	case ArchMIPS64N32:
		return "mips64n32"
	case ArchMIPSEL:
		return "mipsel"
	case ArchMIPSEL64:
		return "mipsel64"
	case ArchMIPSEL64N32:
		return "mipsel64n32"
	case ArchPPC:
		return "ppc"
	case ArchPPC64:
		return "ppc64"
	case ArchPPC64LE:
		return "ppc64le"
	case ArchS390:
		return "s390"
	case ArchS390X:
		return "s390x"
	case ArchPARISC:
		return "parisc"
	case ArchPARISC64:
		return "parisc64"
	case ArchRISCV64:
		return "riscv64"
	case ArchNative:
		return "native"
	case ArchInvalid:
		return "Invalid architecture"
	default:
		return fmt.Sprintf("Unknown architecture %#x", uint(a))
	}
}
func (a ScmpCompareOp) String() string {
	switch a {
	case CompareNotEqual:
		return "Not equal"
	case CompareLess:
		return "Less than"
	case CompareLessOrEqual:
		return "Less than or equal to"
	case CompareEqual:
		return "Equal"
	case CompareGreaterEqual:
		return "Greater than or equal to"
	case CompareGreater:
		return "Greater than"
	case CompareMaskedEqual:
		return "Masked equality"
	case CompareInvalid:
		return "Invalid comparison operator"
	default:
		return fmt.Sprintf("Unrecognized comparison operator %#x", uint(a))
	}
}
func (a ScmpAction) String() string {
	switch a & 0xFFFF {
	case ActKill, ActKillThread:
		return "Action: Kill thread"
	case ActKillProcess:
		return "Action: Kill process"
	case ActTrap:
		return "Action: Send SIGSYS"
	case ActErrno:
		return fmt.Sprintf("Action: Return error code %d", (a >> 16))
	case ActTrace:
		return fmt.Sprintf("Action: Notify tracing processes with code %d",
			(a >> 16))
	case ActNotify:
		return "Action: Notify userspace"
	case ActLog:
		return "Action: Log system call"
	case ActAllow:
		return "Action: Allow system call"
	default:
		return fmt.Sprintf("Unrecognized Action %#x", uint(a))
	}
}
func (a ScmpAction) SetReturnCode(code int16) ScmpAction {
	aTmp := a & 0x0000FFFF
	if aTmp == ActErrno || aTmp == ActTrace {
		return (aTmp | (ScmpAction(code)&0xFFFF)<<16)
	}
	return a
}
func (a ScmpAction) GetReturnCode() int16 {
	return int16(a >> 16)
}
func GetLibraryVersion() (major, minor, micro uint) {
	return verMajor, verMinor, verMicro
}
func GetAPI() (uint, error) {
	return getAPI()
}
func SetAPI(api uint) error {
	return setAPI(api)
}
func (s ScmpSyscall) GetName() (string, error) {
	return s.GetNameByArch(ArchNative)
}
func (s ScmpSyscall) GetNameByArch(arch ScmpArch) (string, error) {
	if err := sanitizeArch(arch); err != nil {
		return "", err
	}
	cString := C.seccomp_syscall_resolve_num_arch(arch.toNative(), C.int(s))
	if cString == nil {
		return "", ErrSyscallDoesNotExist
	}
	defer C.free(unsafe.Pointer(cString))
	finalStr := C.GoString(cString)
	return finalStr, nil
}
func GetSyscallFromName(name string) (ScmpSyscall, error) {
	if err := ensureSupportedVersion(); err != nil {
		return 0, err
	}
	cString := C.CString(name)
	defer C.free(unsafe.Pointer(cString))
	result := C.seccomp_syscall_resolve_name(cString)
	if result == scmpError {
		return 0, ErrSyscallDoesNotExist
	}
	return ScmpSyscall(result), nil
}
func GetSyscallFromNameByArch(name string, arch ScmpArch) (ScmpSyscall, error) {
	if err := ensureSupportedVersion(); err != nil {
		return 0, err
	}
	if err := sanitizeArch(arch); err != nil {
		return 0, err
	}
	cString := C.CString(name)
	defer C.free(unsafe.Pointer(cString))
	result := C.seccomp_syscall_resolve_name_arch(arch.toNative(), cString)
	if result == scmpError {
		return 0, ErrSyscallDoesNotExist
	}
	return ScmpSyscall(result), nil
}
func MakeCondition(arg uint, comparison ScmpCompareOp, values ...uint64) (ScmpCondition, error) {
	var condStruct ScmpCondition
	if err := ensureSupportedVersion(); err != nil {
		return condStruct, err
	}
	if err := sanitizeCompareOp(comparison); err != nil {
		return condStruct, err
	} else if arg > 5 {
		return condStruct, fmt.Errorf("syscalls only have up to 6 arguments (%d given)", arg)
	} else if len(values) > 2 {
		return condStruct, fmt.Errorf("conditions can have at most 2 arguments (%d given)", len(values))
	} else if len(values) == 0 {
		return condStruct, fmt.Errorf("must provide at least one value to compare against")
	}
	condStruct.Argument = arg
	condStruct.Op = comparison
	condStruct.Operand1 = values[0]
	if len(values) == 2 {
		condStruct.Operand2 = values[1]
	} else {
		condStruct.Operand2 = 0  
	}
	return condStruct, nil
}
func GetNativeArch() (ScmpArch, error) {
	if err := ensureSupportedVersion(); err != nil {
		return ArchInvalid, err
	}
	arch := C.seccomp_arch_native()
	return archFromNative(arch)
}
type ScmpFilter struct {
	filterCtx C.scmp_filter_ctx
	valid     bool
	lock      sync.Mutex
}
func NewFilter(defaultAction ScmpAction) (*ScmpFilter, error) {
	if err := ensureSupportedVersion(); err != nil {
		return nil, err
	}
	if err := sanitizeAction(defaultAction); err != nil {
		return nil, err
	}
	fPtr := C.seccomp_init(defaultAction.toNative())
	if fPtr == nil {
		return nil, fmt.Errorf("could not create filter")
	}
	filter := new(ScmpFilter)
	filter.filterCtx = fPtr
	filter.valid = true
	runtime.SetFinalizer(filter, filterFinalizer)
	if err := filter.setFilterAttr(filterAttrTsync, 0x1); err != nil && err != syscall.ENOTSUP {
		filter.Release()
		return nil, fmt.Errorf("could not create filter - error setting tsync bit: %v", err)
	}
	return filter, nil
}
func (f *ScmpFilter) IsValid() bool {
	f.lock.Lock()
	defer f.lock.Unlock()
	return f.valid
}
func (f *ScmpFilter) Reset(defaultAction ScmpAction) error {
	f.lock.Lock()
	defer f.lock.Unlock()
	if err := sanitizeAction(defaultAction); err != nil {
		return err
	} else if !f.valid {
		return errBadFilter
	}
	if retCode := C.seccomp_reset(f.filterCtx, defaultAction.toNative()); retCode != 0 {
		return errRc(retCode)
	}
	return nil
}
func (f *ScmpFilter) Release() {
	f.lock.Lock()
	defer f.lock.Unlock()
	if !f.valid {
		return
	}
	f.valid = false
	C.seccomp_release(f.filterCtx)
}
func (f *ScmpFilter) Merge(src *ScmpFilter) error {
	f.lock.Lock()
	defer f.lock.Unlock()
	src.lock.Lock()
	defer src.lock.Unlock()
	if !src.valid || !f.valid {
		return fmt.Errorf("one or more of the filter contexts is invalid or uninitialized")
	}
	if retCode := C.seccomp_merge(f.filterCtx, src.filterCtx); retCode != 0 {
		e := errRc(retCode)
		if e == syscall.EINVAL {
			return fmt.Errorf("filters could not be merged due to a mismatch in attributes or invalid filter")
		}
		return e
	}
	src.valid = false
	return nil
}
func (f *ScmpFilter) IsArchPresent(arch ScmpArch) (bool, error) {
	f.lock.Lock()
	defer f.lock.Unlock()
	if err := sanitizeArch(arch); err != nil {
		return false, err
	} else if !f.valid {
		return false, errBadFilter
	}
	if retCode := C.seccomp_arch_exist(f.filterCtx, arch.toNative()); retCode != 0 {
		e := errRc(retCode)
		if e == syscall.EEXIST {
			return false, nil
		}
		return false, e
	}
	return true, nil
}
func (f *ScmpFilter) AddArch(arch ScmpArch) error {
	f.lock.Lock()
	defer f.lock.Unlock()
	if err := sanitizeArch(arch); err != nil {
		return err
	} else if !f.valid {
		return errBadFilter
	}
	if retCode := C.seccomp_arch_add(f.filterCtx, arch.toNative()); retCode != 0 {
		if e := errRc(retCode); e != syscall.EEXIST {
			return e
		}
	}
	return nil
}
func (f *ScmpFilter) RemoveArch(arch ScmpArch) error {
	f.lock.Lock()
	defer f.lock.Unlock()
	if err := sanitizeArch(arch); err != nil {
		return err
	} else if !f.valid {
		return errBadFilter
	}
	if retCode := C.seccomp_arch_remove(f.filterCtx, arch.toNative()); retCode != 0 {
		if e := errRc(retCode); e != syscall.EEXIST {
			return e
		}
	}
	return nil
}
func (f *ScmpFilter) Load() error {
	f.lock.Lock()
	defer f.lock.Unlock()
	if !f.valid {
		return errBadFilter
	}
	if retCode := C.seccomp_load(f.filterCtx); retCode != 0 {
		return errRc(retCode)
	}
	return nil
}
func (f *ScmpFilter) GetDefaultAction() (ScmpAction, error) {
	action, err := f.getFilterAttr(filterAttrActDefault)
	if err != nil {
		return 0x0, err
	}
	return actionFromNative(action)
}
func (f *ScmpFilter) GetBadArchAction() (ScmpAction, error) {
	action, err := f.getFilterAttr(filterAttrActBadArch)
	if err != nil {
		return 0x0, err
	}
	return actionFromNative(action)
}
func (f *ScmpFilter) GetNoNewPrivsBit() (bool, error) {
	noNewPrivs, err := f.getFilterAttr(filterAttrNNP)
	if err != nil {
		return false, err
	}
	if noNewPrivs == 0 {
		return false, nil
	}
	return true, nil
}
func (f *ScmpFilter) GetLogBit() (bool, error) {
	log, err := f.getFilterAttr(filterAttrLog)
	if err != nil {
		if e := checkAPI("GetLogBit", 3, 2, 4, 0); e != nil {
			err = e
		}
		return false, err
	}
	if log == 0 {
		return false, nil
	}
	return true, nil
}