Blame vendor/golang.org/x/sys/unix/mksysctl_openbsd.go

Packit 63bb0d
// Copyright 2019 The Go Authors. All rights reserved.
Packit 63bb0d
// Use of this source code is governed by a BSD-style
Packit 63bb0d
// license that can be found in the LICENSE file.
Packit 63bb0d
Packit 63bb0d
// +build ignore
Packit 63bb0d
Packit 63bb0d
// Parse the header files for OpenBSD and generate a Go usable sysctl MIB.
Packit 63bb0d
//
Packit 63bb0d
// Build a MIB with each entry being an array containing the level, type and
Packit 63bb0d
// a hash that will contain additional entries if the current entry is a node.
Packit 63bb0d
// We then walk this MIB and create a flattened sysctl name to OID hash.
Packit 63bb0d
Packit 63bb0d
package main
Packit 63bb0d
Packit 63bb0d
import (
Packit 63bb0d
	"bufio"
Packit 63bb0d
	"fmt"
Packit 63bb0d
	"os"
Packit 63bb0d
	"path/filepath"
Packit 63bb0d
	"regexp"
Packit 63bb0d
	"sort"
Packit 63bb0d
	"strings"
Packit 63bb0d
)
Packit 63bb0d
Packit 63bb0d
var (
Packit 63bb0d
	goos, goarch string
Packit 63bb0d
)
Packit 63bb0d
Packit 63bb0d
// cmdLine returns this programs's commandline arguments.
Packit 63bb0d
func cmdLine() string {
Packit 63bb0d
	return "go run mksysctl_openbsd.go " + strings.Join(os.Args[1:], " ")
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
// buildTags returns build tags.
Packit 63bb0d
func buildTags() string {
Packit 63bb0d
	return fmt.Sprintf("%s,%s", goarch, goos)
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
// reMatch performs regular expression match and stores the substring slice to value pointed by m.
Packit 63bb0d
func reMatch(re *regexp.Regexp, str string, m *[]string) bool {
Packit 63bb0d
	*m = re.FindStringSubmatch(str)
Packit 63bb0d
	if *m != nil {
Packit 63bb0d
		return true
Packit 63bb0d
	}
Packit 63bb0d
	return false
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
type nodeElement struct {
Packit 63bb0d
	n  int
Packit 63bb0d
	t  string
Packit 63bb0d
	pE *map[string]nodeElement
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
var (
Packit 63bb0d
	debugEnabled bool
Packit 63bb0d
	mib          map[string]nodeElement
Packit 63bb0d
	node         *map[string]nodeElement
Packit 63bb0d
	nodeMap      map[string]string
Packit 63bb0d
	sysCtl       []string
Packit 63bb0d
)
Packit 63bb0d
Packit 63bb0d
var (
Packit 63bb0d
	ctlNames1RE = regexp.MustCompile(`^#define\s+(CTL_NAMES)\s+{`)
Packit 63bb0d
	ctlNames2RE = regexp.MustCompile(`^#define\s+(CTL_(.*)_NAMES)\s+{`)
Packit 63bb0d
	ctlNames3RE = regexp.MustCompile(`^#define\s+((.*)CTL_NAMES)\s+{`)
Packit 63bb0d
	netInetRE   = regexp.MustCompile(`^netinet/`)
Packit 63bb0d
	netInet6RE  = regexp.MustCompile(`^netinet6/`)
Packit 63bb0d
	netRE       = regexp.MustCompile(`^net/`)
Packit 63bb0d
	bracesRE    = regexp.MustCompile(`{.*}`)
Packit 63bb0d
	ctlTypeRE   = regexp.MustCompile(`{\s+"(\w+)",\s+(CTLTYPE_[A-Z]+)\s+}`)
Packit 63bb0d
	fsNetKernRE = regexp.MustCompile(`^(fs|net|kern)_`)
Packit 63bb0d
)
Packit 63bb0d
Packit 63bb0d
func debug(s string) {
Packit 63bb0d
	if debugEnabled {
Packit 63bb0d
		fmt.Fprintln(os.Stderr, s)
Packit 63bb0d
	}
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
// Walk the MIB and build a sysctl name to OID mapping.
Packit 63bb0d
func buildSysctl(pNode *map[string]nodeElement, name string, oid []int) {
Packit 63bb0d
	lNode := pNode // local copy of pointer to node
Packit 63bb0d
	var keys []string
Packit 63bb0d
	for k := range *lNode {
Packit 63bb0d
		keys = append(keys, k)
Packit 63bb0d
	}
Packit 63bb0d
	sort.Strings(keys)
Packit 63bb0d
Packit 63bb0d
	for _, key := range keys {
Packit 63bb0d
		nodename := name
Packit 63bb0d
		if name != "" {
Packit 63bb0d
			nodename += "."
Packit 63bb0d
		}
Packit 63bb0d
		nodename += key
Packit 63bb0d
Packit 63bb0d
		nodeoid := append(oid, (*pNode)[key].n)
Packit 63bb0d
Packit 63bb0d
		if (*pNode)[key].t == `CTLTYPE_NODE` {
Packit 63bb0d
			if _, ok := nodeMap[nodename]; ok {
Packit 63bb0d
				lNode = &mib
Packit 63bb0d
				ctlName := nodeMap[nodename]
Packit 63bb0d
				for _, part := range strings.Split(ctlName, ".") {
Packit 63bb0d
					lNode = ((*lNode)[part]).pE
Packit 63bb0d
				}
Packit 63bb0d
			} else {
Packit 63bb0d
				lNode = (*pNode)[key].pE
Packit 63bb0d
			}
Packit 63bb0d
			buildSysctl(lNode, nodename, nodeoid)
Packit 63bb0d
		} else if (*pNode)[key].t != "" {
Packit 63bb0d
			oidStr := []string{}
Packit 63bb0d
			for j := range nodeoid {
Packit 63bb0d
				oidStr = append(oidStr, fmt.Sprintf("%d", nodeoid[j]))
Packit 63bb0d
			}
Packit 63bb0d
			text := "\t{ \"" + nodename + "\", []_C_int{ " + strings.Join(oidStr, ", ") + " } }, \n"
Packit 63bb0d
			sysCtl = append(sysCtl, text)
Packit 63bb0d
		}
Packit 63bb0d
	}
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
func main() {
Packit 63bb0d
	// Get the OS (using GOOS_TARGET if it exist)
Packit 63bb0d
	goos = os.Getenv("GOOS_TARGET")
Packit 63bb0d
	if goos == "" {
Packit 63bb0d
		goos = os.Getenv("GOOS")
Packit 63bb0d
	}
Packit 63bb0d
	// Get the architecture (using GOARCH_TARGET if it exists)
Packit 63bb0d
	goarch = os.Getenv("GOARCH_TARGET")
Packit 63bb0d
	if goarch == "" {
Packit 63bb0d
		goarch = os.Getenv("GOARCH")
Packit 63bb0d
	}
Packit 63bb0d
	// Check if GOOS and GOARCH environment variables are defined
Packit 63bb0d
	if goarch == "" || goos == "" {
Packit 63bb0d
		fmt.Fprintf(os.Stderr, "GOARCH or GOOS not defined in environment\n")
Packit 63bb0d
		os.Exit(1)
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	mib = make(map[string]nodeElement)
Packit 63bb0d
	headers := [...]string{
Packit 63bb0d
		`sys/sysctl.h`,
Packit 63bb0d
		`sys/socket.h`,
Packit 63bb0d
		`sys/tty.h`,
Packit 63bb0d
		`sys/malloc.h`,
Packit 63bb0d
		`sys/mount.h`,
Packit 63bb0d
		`sys/namei.h`,
Packit 63bb0d
		`sys/sem.h`,
Packit 63bb0d
		`sys/shm.h`,
Packit 63bb0d
		`sys/vmmeter.h`,
Packit 63bb0d
		`uvm/uvmexp.h`,
Packit 63bb0d
		`uvm/uvm_param.h`,
Packit 63bb0d
		`uvm/uvm_swap_encrypt.h`,
Packit 63bb0d
		`ddb/db_var.h`,
Packit 63bb0d
		`net/if.h`,
Packit 63bb0d
		`net/if_pfsync.h`,
Packit 63bb0d
		`net/pipex.h`,
Packit 63bb0d
		`netinet/in.h`,
Packit 63bb0d
		`netinet/icmp_var.h`,
Packit 63bb0d
		`netinet/igmp_var.h`,
Packit 63bb0d
		`netinet/ip_ah.h`,
Packit 63bb0d
		`netinet/ip_carp.h`,
Packit 63bb0d
		`netinet/ip_divert.h`,
Packit 63bb0d
		`netinet/ip_esp.h`,
Packit 63bb0d
		`netinet/ip_ether.h`,
Packit 63bb0d
		`netinet/ip_gre.h`,
Packit 63bb0d
		`netinet/ip_ipcomp.h`,
Packit 63bb0d
		`netinet/ip_ipip.h`,
Packit 63bb0d
		`netinet/pim_var.h`,
Packit 63bb0d
		`netinet/tcp_var.h`,
Packit 63bb0d
		`netinet/udp_var.h`,
Packit 63bb0d
		`netinet6/in6.h`,
Packit 63bb0d
		`netinet6/ip6_divert.h`,
Packit 63bb0d
		`netinet6/pim6_var.h`,
Packit 63bb0d
		`netinet/icmp6.h`,
Packit 63bb0d
		`netmpls/mpls.h`,
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	ctls := [...]string{
Packit 63bb0d
		`kern`,
Packit 63bb0d
		`vm`,
Packit 63bb0d
		`fs`,
Packit 63bb0d
		`net`,
Packit 63bb0d
		//debug			/* Special handling required */
Packit 63bb0d
		`hw`,
Packit 63bb0d
		//machdep		/* Arch specific */
Packit 63bb0d
		`user`,
Packit 63bb0d
		`ddb`,
Packit 63bb0d
		//vfs			/* Special handling required */
Packit 63bb0d
		`fs.posix`,
Packit 63bb0d
		`kern.forkstat`,
Packit 63bb0d
		`kern.intrcnt`,
Packit 63bb0d
		`kern.malloc`,
Packit 63bb0d
		`kern.nchstats`,
Packit 63bb0d
		`kern.seminfo`,
Packit 63bb0d
		`kern.shminfo`,
Packit 63bb0d
		`kern.timecounter`,
Packit 63bb0d
		`kern.tty`,
Packit 63bb0d
		`kern.watchdog`,
Packit 63bb0d
		`net.bpf`,
Packit 63bb0d
		`net.ifq`,
Packit 63bb0d
		`net.inet`,
Packit 63bb0d
		`net.inet.ah`,
Packit 63bb0d
		`net.inet.carp`,
Packit 63bb0d
		`net.inet.divert`,
Packit 63bb0d
		`net.inet.esp`,
Packit 63bb0d
		`net.inet.etherip`,
Packit 63bb0d
		`net.inet.gre`,
Packit 63bb0d
		`net.inet.icmp`,
Packit 63bb0d
		`net.inet.igmp`,
Packit 63bb0d
		`net.inet.ip`,
Packit 63bb0d
		`net.inet.ip.ifq`,
Packit 63bb0d
		`net.inet.ipcomp`,
Packit 63bb0d
		`net.inet.ipip`,
Packit 63bb0d
		`net.inet.mobileip`,
Packit 63bb0d
		`net.inet.pfsync`,
Packit 63bb0d
		`net.inet.pim`,
Packit 63bb0d
		`net.inet.tcp`,
Packit 63bb0d
		`net.inet.udp`,
Packit 63bb0d
		`net.inet6`,
Packit 63bb0d
		`net.inet6.divert`,
Packit 63bb0d
		`net.inet6.ip6`,
Packit 63bb0d
		`net.inet6.icmp6`,
Packit 63bb0d
		`net.inet6.pim6`,
Packit 63bb0d
		`net.inet6.tcp6`,
Packit 63bb0d
		`net.inet6.udp6`,
Packit 63bb0d
		`net.mpls`,
Packit 63bb0d
		`net.mpls.ifq`,
Packit 63bb0d
		`net.key`,
Packit 63bb0d
		`net.pflow`,
Packit 63bb0d
		`net.pfsync`,
Packit 63bb0d
		`net.pipex`,
Packit 63bb0d
		`net.rt`,
Packit 63bb0d
		`vm.swapencrypt`,
Packit 63bb0d
		//vfsgenctl		/* Special handling required */
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	// Node name "fixups"
Packit 63bb0d
	ctlMap := map[string]string{
Packit 63bb0d
		"ipproto":             "net.inet",
Packit 63bb0d
		"net.inet.ipproto":    "net.inet",
Packit 63bb0d
		"net.inet6.ipv6proto": "net.inet6",
Packit 63bb0d
		"net.inet6.ipv6":      "net.inet6.ip6",
Packit 63bb0d
		"net.inet.icmpv6":     "net.inet6.icmp6",
Packit 63bb0d
		"net.inet6.divert6":   "net.inet6.divert",
Packit 63bb0d
		"net.inet6.tcp6":      "net.inet.tcp",
Packit 63bb0d
		"net.inet6.udp6":      "net.inet.udp",
Packit 63bb0d
		"mpls":                "net.mpls",
Packit 63bb0d
		"swpenc":              "vm.swapencrypt",
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	// Node mappings
Packit 63bb0d
	nodeMap = map[string]string{
Packit 63bb0d
		"net.inet.ip.ifq": "net.ifq",
Packit 63bb0d
		"net.inet.pfsync": "net.pfsync",
Packit 63bb0d
		"net.mpls.ifq":    "net.ifq",
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	mCtls := make(map[string]bool)
Packit 63bb0d
	for _, ctl := range ctls {
Packit 63bb0d
		mCtls[ctl] = true
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	for _, header := range headers {
Packit 63bb0d
		debug("Processing " + header)
Packit 63bb0d
		file, err := os.Open(filepath.Join("/usr/include", header))
Packit 63bb0d
		if err != nil {
Packit 63bb0d
			fmt.Fprintf(os.Stderr, "%v\n", err)
Packit 63bb0d
			os.Exit(1)
Packit 63bb0d
		}
Packit 63bb0d
		s := bufio.NewScanner(file)
Packit 63bb0d
		for s.Scan() {
Packit 63bb0d
			var sub []string
Packit 63bb0d
			if reMatch(ctlNames1RE, s.Text(), &sub) ||
Packit 63bb0d
				reMatch(ctlNames2RE, s.Text(), &sub) ||
Packit 63bb0d
				reMatch(ctlNames3RE, s.Text(), &sub) {
Packit 63bb0d
				if sub[1] == `CTL_NAMES` {
Packit 63bb0d
					// Top level.
Packit 63bb0d
					node = &mib
Packit 63bb0d
				} else {
Packit 63bb0d
					// Node.
Packit 63bb0d
					nodename := strings.ToLower(sub[2])
Packit 63bb0d
					ctlName := ""
Packit 63bb0d
					if reMatch(netInetRE, header, &sub) {
Packit 63bb0d
						ctlName = "net.inet." + nodename
Packit 63bb0d
					} else if reMatch(netInet6RE, header, &sub) {
Packit 63bb0d
						ctlName = "net.inet6." + nodename
Packit 63bb0d
					} else if reMatch(netRE, header, &sub) {
Packit 63bb0d
						ctlName = "net." + nodename
Packit 63bb0d
					} else {
Packit 63bb0d
						ctlName = nodename
Packit 63bb0d
						ctlName = fsNetKernRE.ReplaceAllString(ctlName, `$1.`)
Packit 63bb0d
					}
Packit 63bb0d
Packit 63bb0d
					if val, ok := ctlMap[ctlName]; ok {
Packit 63bb0d
						ctlName = val
Packit 63bb0d
					}
Packit 63bb0d
					if _, ok := mCtls[ctlName]; !ok {
Packit 63bb0d
						debug("Ignoring " + ctlName + "...")
Packit 63bb0d
						continue
Packit 63bb0d
					}
Packit 63bb0d
Packit 63bb0d
					// Walk down from the top of the MIB.
Packit 63bb0d
					node = &mib
Packit 63bb0d
					for _, part := range strings.Split(ctlName, ".") {
Packit 63bb0d
						if _, ok := (*node)[part]; !ok {
Packit 63bb0d
							debug("Missing node " + part)
Packit 63bb0d
							(*node)[part] = nodeElement{n: 0, t: "", pE: &map[string]nodeElement{}}
Packit 63bb0d
						}
Packit 63bb0d
						node = (*node)[part].pE
Packit 63bb0d
					}
Packit 63bb0d
				}
Packit 63bb0d
Packit 63bb0d
				// Populate current node with entries.
Packit 63bb0d
				i := -1
Packit 63bb0d
				for !strings.HasPrefix(s.Text(), "}") {
Packit 63bb0d
					s.Scan()
Packit 63bb0d
					if reMatch(bracesRE, s.Text(), &sub) {
Packit 63bb0d
						i++
Packit 63bb0d
					}
Packit 63bb0d
					if !reMatch(ctlTypeRE, s.Text(), &sub) {
Packit 63bb0d
						continue
Packit 63bb0d
					}
Packit 63bb0d
					(*node)[sub[1]] = nodeElement{n: i, t: sub[2], pE: &map[string]nodeElement{}}
Packit 63bb0d
				}
Packit 63bb0d
			}
Packit 63bb0d
		}
Packit 63bb0d
		err = s.Err()
Packit 63bb0d
		if err != nil {
Packit 63bb0d
			fmt.Fprintf(os.Stderr, "%v\n", err)
Packit 63bb0d
			os.Exit(1)
Packit 63bb0d
		}
Packit 63bb0d
		file.Close()
Packit 63bb0d
	}
Packit 63bb0d
	buildSysctl(&mib, "", []int{})
Packit 63bb0d
Packit 63bb0d
	sort.Strings(sysCtl)
Packit 63bb0d
	text := strings.Join(sysCtl, "")
Packit 63bb0d
Packit 63bb0d
	fmt.Printf(srcTemplate, cmdLine(), buildTags(), text)
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
const srcTemplate = `// %s
Packit 63bb0d
// Code generated by the command above; DO NOT EDIT.
Packit 63bb0d
Packit 63bb0d
// +build %s
Packit 63bb0d
Packit 63bb0d
package unix
Packit 63bb0d
Packit 63bb0d
type mibentry struct {
Packit 63bb0d
	ctlname string
Packit 63bb0d
	ctloid []_C_int
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
var sysctlMib = []mibentry {
Packit 63bb0d
%s
Packit 63bb0d
}
Packit 63bb0d
`