func MakeCondition(arg uint, comparison ScmpCompareOp, values ...uint64) (ScmpCondition, error) {
	var condStruct ScmpCondition
	if err := ensureSupportedVersion(); err != nil {
		return condStruct, err
	}
	if comparison == CompareInvalid {
		return condStruct, fmt.Errorf("invalid comparison operator")
	} else if arg > 5 {
		return condStruct, fmt.Errorf("syscalls only have up to 6 arguments")
	} else if len(values) > 2 {
		return condStruct, fmt.Errorf("conditions can have at most 2 arguments")
	} 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
}
MakeCondition creates and returns a new condition to attach to a filter rule.
Associated rules will only match if this condition is true.
Accepts the number the argument we are checking, and a comparison operator
and value to compare to.
The rule will match if argument $arg (zero-indexed) of the syscall is
$COMPARE_OP the provided comparison value.
Some comparison operators accept two values. Masked equals, for example,
will mask $arg of the syscall with the second value provided (via bitwise
AND) and then compare against the first value provided.
For example, in the less than or equal case, if the syscall argument was
0 and the value provided was 1, the condition would match, as 0 is less
than or equal to 1.
Return either an error on bad argument or a valid ScmpCondition struct.
package seccomp
import (
	"fmt"
	"os"
	"runtime"
	"strings"
	"sync"
	"syscall"
	"unsafe"
)
import "C"
type VersionError struct {
	message string
	minimum string
}
func (e VersionError) Error() string {
	format := "Libseccomp version too low: "
	if e.message != "" {
		format += e.message + ": "
	}
	format += "minimum supported is "
	if e.minimum != "" {
		format += e.minimum + ": "
	} else {
		format += "2.1.0: "
	}
	format += "detected %d.%d.%d"
	return fmt.Sprintf(format, 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
const (
	ArchInvalid ScmpArch = iota
	ArchNative ScmpArch = iota
	ArchX86 ScmpArch = iota
	ArchAMD64 ScmpArch = iota
	ArchX32 ScmpArch = iota
	ArchARM ScmpArch = iota
	ArchARM64 ScmpArch = iota
	ArchMIPS ScmpArch = iota
	ArchMIPS64 ScmpArch = iota
	ArchMIPS64N32 ScmpArch = iota
	ArchMIPSEL ScmpArch = iota
	ArchMIPSEL64 ScmpArch = iota
	ArchMIPSEL64N32 ScmpArch = iota
	ArchPPC ScmpArch = iota
	ArchPPC64 ScmpArch = iota
	ArchPPC64LE ScmpArch = iota
	ArchS390 ScmpArch = iota
	ArchS390X ScmpArch = iota
)
const (
	ActInvalid ScmpAction = iota
	ActKill ScmpAction = iota
	ActTrap ScmpAction = iota
	ActErrno ScmpAction = iota
	ActTrace ScmpAction = iota
	ActAllow ScmpAction = iota
)
const (
	CompareInvalid ScmpCompareOp = iota
	CompareNotEqual ScmpCompareOp = iota
	CompareLess ScmpCompareOp = iota
	CompareLessOrEqual ScmpCompareOp = iota
	CompareEqual ScmpCompareOp = iota
	CompareGreaterEqual ScmpCompareOp = iota
	CompareGreater ScmpCompareOp = iota
	CompareMaskedEqual ScmpCompareOp = iota
)
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
	default:
		return ArchInvalid, fmt.Errorf("cannot convert unrecognized string %s", 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 ArchNative:
		return "native"
	case ArchInvalid:
		return "Invalid architecture"
	default:
		return "Unknown architecture"
	}
}
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 "Unrecognized comparison operator"
	}
}
func (a ScmpAction) String() string {
	switch a & 0xFFFF {
	case ActKill:
		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 ActAllow:
		return "Action: Allow system call"
	default:
		return "Unrecognized Action"
	}
}
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 int) {
	return verMajor, verMinor, verMicro
}
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 "", fmt.Errorf("could not resolve syscall name")
	}
	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, fmt.Errorf("could not resolve name to syscall")
	}
	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, fmt.Errorf("could not resolve name to syscall")
	}
	return ScmpSyscall(result), nil
}