github.com/giovannyortegon/go@v0.0.0-20220115155912-8890063f5bdd/src/pkg/mod/golang.org/x/sys@v0.0.0-20210927094055-39ccf1dd6fa6/unix/mksysctl_openbsd.go (about) 1 // Copyright 2019 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 //go:build ignore 6 // +build ignore 7 8 // Parse the header files for OpenBSD and generate a Go usable sysctl MIB. 9 // 10 // Build a MIB with each entry being an array containing the level, type and 11 // a hash that will contain additional entries if the current entry is a node. 12 // We then walk this MIB and create a flattened sysctl name to OID hash. 13 14 package main 15 16 import ( 17 "bufio" 18 "fmt" 19 "os" 20 "path/filepath" 21 "regexp" 22 "sort" 23 "strings" 24 ) 25 26 var ( 27 goos, goarch string 28 ) 29 30 // cmdLine returns this programs's commandline arguments. 31 func cmdLine() string { 32 return "go run mksysctl_openbsd.go " + strings.Join(os.Args[1:], " ") 33 } 34 35 // goBuildTags returns build tags in the go:build format. 36 func goBuildTags() string { 37 return fmt.Sprintf("%s && %s", goarch, goos) 38 } 39 40 // plusBuildTags returns build tags in the +build format. 41 func plusBuildTags() string { 42 return fmt.Sprintf("%s,%s", goarch, goos) 43 } 44 45 // reMatch performs regular expression match and stores the substring slice to value pointed by m. 46 func reMatch(re *regexp.Regexp, str string, m *[]string) bool { 47 *m = re.FindStringSubmatch(str) 48 if *m != nil { 49 return true 50 } 51 return false 52 } 53 54 type nodeElement struct { 55 n int 56 t string 57 pE *map[string]nodeElement 58 } 59 60 var ( 61 debugEnabled bool 62 mib map[string]nodeElement 63 node *map[string]nodeElement 64 nodeMap map[string]string 65 sysCtl []string 66 ) 67 68 var ( 69 ctlNames1RE = regexp.MustCompile(`^#define\s+(CTL_NAMES)\s+{`) 70 ctlNames2RE = regexp.MustCompile(`^#define\s+(CTL_(.*)_NAMES)\s+{`) 71 ctlNames3RE = regexp.MustCompile(`^#define\s+((.*)CTL_NAMES)\s+{`) 72 netInetRE = regexp.MustCompile(`^netinet/`) 73 netInet6RE = regexp.MustCompile(`^netinet6/`) 74 netRE = regexp.MustCompile(`^net/`) 75 bracesRE = regexp.MustCompile(`{.*}`) 76 ctlTypeRE = regexp.MustCompile(`{\s+"(\w+)",\s+(CTLTYPE_[A-Z]+)\s+}`) 77 fsNetKernRE = regexp.MustCompile(`^(fs|net|kern)_`) 78 ) 79 80 func debug(s string) { 81 if debugEnabled { 82 fmt.Fprintln(os.Stderr, s) 83 } 84 } 85 86 // Walk the MIB and build a sysctl name to OID mapping. 87 func buildSysctl(pNode *map[string]nodeElement, name string, oid []int) { 88 lNode := pNode // local copy of pointer to node 89 var keys []string 90 for k := range *lNode { 91 keys = append(keys, k) 92 } 93 sort.Strings(keys) 94 95 for _, key := range keys { 96 nodename := name 97 if name != "" { 98 nodename += "." 99 } 100 nodename += key 101 102 nodeoid := append(oid, (*pNode)[key].n) 103 104 if (*pNode)[key].t == `CTLTYPE_NODE` { 105 if _, ok := nodeMap[nodename]; ok { 106 lNode = &mib 107 ctlName := nodeMap[nodename] 108 for _, part := range strings.Split(ctlName, ".") { 109 lNode = ((*lNode)[part]).pE 110 } 111 } else { 112 lNode = (*pNode)[key].pE 113 } 114 buildSysctl(lNode, nodename, nodeoid) 115 } else if (*pNode)[key].t != "" { 116 oidStr := []string{} 117 for j := range nodeoid { 118 oidStr = append(oidStr, fmt.Sprintf("%d", nodeoid[j])) 119 } 120 text := "\t{ \"" + nodename + "\", []_C_int{ " + strings.Join(oidStr, ", ") + " } }, \n" 121 sysCtl = append(sysCtl, text) 122 } 123 } 124 } 125 126 func main() { 127 // Get the OS (using GOOS_TARGET if it exist) 128 goos = os.Getenv("GOOS_TARGET") 129 if goos == "" { 130 goos = os.Getenv("GOOS") 131 } 132 // Get the architecture (using GOARCH_TARGET if it exists) 133 goarch = os.Getenv("GOARCH_TARGET") 134 if goarch == "" { 135 goarch = os.Getenv("GOARCH") 136 } 137 // Check if GOOS and GOARCH environment variables are defined 138 if goarch == "" || goos == "" { 139 fmt.Fprintf(os.Stderr, "GOARCH or GOOS not defined in environment\n") 140 os.Exit(1) 141 } 142 143 mib = make(map[string]nodeElement) 144 headers := [...]string{ 145 `sys/sysctl.h`, 146 `sys/socket.h`, 147 `sys/tty.h`, 148 `sys/malloc.h`, 149 `sys/mount.h`, 150 `sys/namei.h`, 151 `sys/sem.h`, 152 `sys/shm.h`, 153 `sys/vmmeter.h`, 154 `uvm/uvmexp.h`, 155 `uvm/uvm_param.h`, 156 `uvm/uvm_swap_encrypt.h`, 157 `ddb/db_var.h`, 158 `net/if.h`, 159 `net/if_pfsync.h`, 160 `net/pipex.h`, 161 `netinet/in.h`, 162 `netinet/icmp_var.h`, 163 `netinet/igmp_var.h`, 164 `netinet/ip_ah.h`, 165 `netinet/ip_carp.h`, 166 `netinet/ip_divert.h`, 167 `netinet/ip_esp.h`, 168 `netinet/ip_ether.h`, 169 `netinet/ip_gre.h`, 170 `netinet/ip_ipcomp.h`, 171 `netinet/ip_ipip.h`, 172 `netinet/tcp_var.h`, 173 `netinet/udp_var.h`, 174 `netinet6/in6.h`, 175 `netinet6/ip6_divert.h`, 176 `netinet/icmp6.h`, 177 `netmpls/mpls.h`, 178 } 179 180 ctls := [...]string{ 181 `kern`, 182 `vm`, 183 `fs`, 184 `net`, 185 //debug /* Special handling required */ 186 `hw`, 187 //machdep /* Arch specific */ 188 `user`, 189 `ddb`, 190 //vfs /* Special handling required */ 191 `fs.posix`, 192 `kern.forkstat`, 193 `kern.intrcnt`, 194 `kern.malloc`, 195 `kern.nchstats`, 196 `kern.seminfo`, 197 `kern.shminfo`, 198 `kern.timecounter`, 199 `kern.tty`, 200 `kern.watchdog`, 201 `net.bpf`, 202 `net.ifq`, 203 `net.inet`, 204 `net.inet.ah`, 205 `net.inet.carp`, 206 `net.inet.divert`, 207 `net.inet.esp`, 208 `net.inet.etherip`, 209 `net.inet.gre`, 210 `net.inet.icmp`, 211 `net.inet.igmp`, 212 `net.inet.ip`, 213 `net.inet.ip.ifq`, 214 `net.inet.ipcomp`, 215 `net.inet.ipip`, 216 `net.inet.mobileip`, 217 `net.inet.pfsync`, 218 `net.inet.tcp`, 219 `net.inet.udp`, 220 `net.inet6`, 221 `net.inet6.divert`, 222 `net.inet6.ip6`, 223 `net.inet6.icmp6`, 224 `net.inet6.tcp6`, 225 `net.inet6.udp6`, 226 `net.mpls`, 227 `net.mpls.ifq`, 228 `net.key`, 229 `net.pflow`, 230 `net.pfsync`, 231 `net.pipex`, 232 `net.rt`, 233 `vm.swapencrypt`, 234 //vfsgenctl /* Special handling required */ 235 } 236 237 // Node name "fixups" 238 ctlMap := map[string]string{ 239 "ipproto": "net.inet", 240 "net.inet.ipproto": "net.inet", 241 "net.inet6.ipv6proto": "net.inet6", 242 "net.inet6.ipv6": "net.inet6.ip6", 243 "net.inet.icmpv6": "net.inet6.icmp6", 244 "net.inet6.divert6": "net.inet6.divert", 245 "net.inet6.tcp6": "net.inet.tcp", 246 "net.inet6.udp6": "net.inet.udp", 247 "mpls": "net.mpls", 248 "swpenc": "vm.swapencrypt", 249 } 250 251 // Node mappings 252 nodeMap = map[string]string{ 253 "net.inet.ip.ifq": "net.ifq", 254 "net.inet.pfsync": "net.pfsync", 255 "net.mpls.ifq": "net.ifq", 256 } 257 258 mCtls := make(map[string]bool) 259 for _, ctl := range ctls { 260 mCtls[ctl] = true 261 } 262 263 for _, header := range headers { 264 debug("Processing " + header) 265 file, err := os.Open(filepath.Join("/usr/include", header)) 266 if err != nil { 267 fmt.Fprintf(os.Stderr, "%v\n", err) 268 os.Exit(1) 269 } 270 s := bufio.NewScanner(file) 271 for s.Scan() { 272 var sub []string 273 if reMatch(ctlNames1RE, s.Text(), &sub) || 274 reMatch(ctlNames2RE, s.Text(), &sub) || 275 reMatch(ctlNames3RE, s.Text(), &sub) { 276 if sub[1] == `CTL_NAMES` { 277 // Top level. 278 node = &mib 279 } else { 280 // Node. 281 nodename := strings.ToLower(sub[2]) 282 ctlName := "" 283 if reMatch(netInetRE, header, &sub) { 284 ctlName = "net.inet." + nodename 285 } else if reMatch(netInet6RE, header, &sub) { 286 ctlName = "net.inet6." + nodename 287 } else if reMatch(netRE, header, &sub) { 288 ctlName = "net." + nodename 289 } else { 290 ctlName = nodename 291 ctlName = fsNetKernRE.ReplaceAllString(ctlName, `$1.`) 292 } 293 294 if val, ok := ctlMap[ctlName]; ok { 295 ctlName = val 296 } 297 if _, ok := mCtls[ctlName]; !ok { 298 debug("Ignoring " + ctlName + "...") 299 continue 300 } 301 302 // Walk down from the top of the MIB. 303 node = &mib 304 for _, part := range strings.Split(ctlName, ".") { 305 if _, ok := (*node)[part]; !ok { 306 debug("Missing node " + part) 307 (*node)[part] = nodeElement{n: 0, t: "", pE: &map[string]nodeElement{}} 308 } 309 node = (*node)[part].pE 310 } 311 } 312 313 // Populate current node with entries. 314 i := -1 315 for !strings.HasPrefix(s.Text(), "}") { 316 s.Scan() 317 if reMatch(bracesRE, s.Text(), &sub) { 318 i++ 319 } 320 if !reMatch(ctlTypeRE, s.Text(), &sub) { 321 continue 322 } 323 (*node)[sub[1]] = nodeElement{n: i, t: sub[2], pE: &map[string]nodeElement{}} 324 } 325 } 326 } 327 err = s.Err() 328 if err != nil { 329 fmt.Fprintf(os.Stderr, "%v\n", err) 330 os.Exit(1) 331 } 332 file.Close() 333 } 334 buildSysctl(&mib, "", []int{}) 335 336 sort.Strings(sysCtl) 337 text := strings.Join(sysCtl, "") 338 339 fmt.Printf(srcTemplate, cmdLine(), goBuildTags(), plusBuildTags(), text) 340 } 341 342 const srcTemplate = `// %s 343 // Code generated by the command above; DO NOT EDIT. 344 345 //go:build %s 346 // +build %s 347 348 package unix 349 350 type mibentry struct { 351 ctlname string 352 ctloid []_C_int 353 } 354 355 var sysctlMib = []mibentry { 356 %s 357 } 358 `