github.com/Andyfoo/golang/x/sys@v0.0.0-20190901054642-57c1bf301704/unix/mksysctl_openbsd.pl (about) 1 #!/usr/bin/env perl 2 3 # Copyright 2011 The Go Authors. All rights reserved. 4 # Use of this source code is governed by a BSD-style 5 # license that can be found in the LICENSE file. 6 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 15 use strict; 16 17 if($ENV{'GOARCH'} eq "" || $ENV{'GOOS'} eq "") { 18 print STDERR "GOARCH or GOOS not defined in environment\n"; 19 exit 1; 20 } 21 22 my $debug = 0; 23 my %ctls = (); 24 25 my @headers = qw ( 26 sys/sysctl.h 27 sys/socket.h 28 sys/tty.h 29 sys/malloc.h 30 sys/mount.h 31 sys/namei.h 32 sys/sem.h 33 sys/shm.h 34 sys/vmmeter.h 35 uvm/uvmexp.h 36 uvm/uvm_param.h 37 uvm/uvm_swap_encrypt.h 38 ddb/db_var.h 39 net/if.h 40 net/if_pfsync.h 41 net/pipex.h 42 netinet/in.h 43 netinet/icmp_var.h 44 netinet/igmp_var.h 45 netinet/ip_ah.h 46 netinet/ip_carp.h 47 netinet/ip_divert.h 48 netinet/ip_esp.h 49 netinet/ip_ether.h 50 netinet/ip_gre.h 51 netinet/ip_ipcomp.h 52 netinet/ip_ipip.h 53 netinet/pim_var.h 54 netinet/tcp_var.h 55 netinet/udp_var.h 56 netinet6/in6.h 57 netinet6/ip6_divert.h 58 netinet6/pim6_var.h 59 netinet/icmp6.h 60 netmpls/mpls.h 61 ); 62 63 my @ctls = qw ( 64 kern 65 vm 66 fs 67 net 68 #debug # Special handling required 69 hw 70 #machdep # Arch specific 71 user 72 ddb 73 #vfs # Special handling required 74 fs.posix 75 kern.forkstat 76 kern.intrcnt 77 kern.malloc 78 kern.nchstats 79 kern.seminfo 80 kern.shminfo 81 kern.timecounter 82 kern.tty 83 kern.watchdog 84 net.bpf 85 net.ifq 86 net.inet 87 net.inet.ah 88 net.inet.carp 89 net.inet.divert 90 net.inet.esp 91 net.inet.etherip 92 net.inet.gre 93 net.inet.icmp 94 net.inet.igmp 95 net.inet.ip 96 net.inet.ip.ifq 97 net.inet.ipcomp 98 net.inet.ipip 99 net.inet.mobileip 100 net.inet.pfsync 101 net.inet.pim 102 net.inet.tcp 103 net.inet.udp 104 net.inet6 105 net.inet6.divert 106 net.inet6.ip6 107 net.inet6.icmp6 108 net.inet6.pim6 109 net.inet6.tcp6 110 net.inet6.udp6 111 net.mpls 112 net.mpls.ifq 113 net.key 114 net.pflow 115 net.pfsync 116 net.pipex 117 net.rt 118 vm.swapencrypt 119 #vfsgenctl # Special handling required 120 ); 121 122 # Node name "fixups" 123 my %ctl_map = ( 124 "ipproto" => "net.inet", 125 "net.inet.ipproto" => "net.inet", 126 "net.inet6.ipv6proto" => "net.inet6", 127 "net.inet6.ipv6" => "net.inet6.ip6", 128 "net.inet.icmpv6" => "net.inet6.icmp6", 129 "net.inet6.divert6" => "net.inet6.divert", 130 "net.inet6.tcp6" => "net.inet.tcp", 131 "net.inet6.udp6" => "net.inet.udp", 132 "mpls" => "net.mpls", 133 "swpenc" => "vm.swapencrypt" 134 ); 135 136 # Node mappings 137 my %node_map = ( 138 "net.inet.ip.ifq" => "net.ifq", 139 "net.inet.pfsync" => "net.pfsync", 140 "net.mpls.ifq" => "net.ifq" 141 ); 142 143 my $ctlname; 144 my %mib = (); 145 my %sysctl = (); 146 my $node; 147 148 sub debug() { 149 print STDERR "$_[0]\n" if $debug; 150 } 151 152 # Walk the MIB and build a sysctl name to OID mapping. 153 sub build_sysctl() { 154 my ($node, $name, $oid) = @_; 155 my %node = %{$node}; 156 my @oid = @{$oid}; 157 158 foreach my $key (sort keys %node) { 159 my @node = @{$node{$key}}; 160 my $nodename = $name.($name ne '' ? '.' : '').$key; 161 my @nodeoid = (@oid, $node[0]); 162 if ($node[1] eq 'CTLTYPE_NODE') { 163 if (exists $node_map{$nodename}) { 164 $node = \%mib; 165 $ctlname = $node_map{$nodename}; 166 foreach my $part (split /\./, $ctlname) { 167 $node = \%{@{$$node{$part}}[2]}; 168 } 169 } else { 170 $node = $node[2]; 171 } 172 &build_sysctl($node, $nodename, \@nodeoid); 173 } elsif ($node[1] ne '') { 174 $sysctl{$nodename} = \@nodeoid; 175 } 176 } 177 } 178 179 foreach my $ctl (@ctls) { 180 $ctls{$ctl} = $ctl; 181 } 182 183 # Build MIB 184 foreach my $header (@headers) { 185 &debug("Processing $header..."); 186 open HEADER, "/usr/include/$header" || 187 print STDERR "Failed to open $header\n"; 188 while (<HEADER>) { 189 if ($_ =~ /^#define\s+(CTL_NAMES)\s+{/ || 190 $_ =~ /^#define\s+(CTL_(.*)_NAMES)\s+{/ || 191 $_ =~ /^#define\s+((.*)CTL_NAMES)\s+{/) { 192 if ($1 eq 'CTL_NAMES') { 193 # Top level. 194 $node = \%mib; 195 } else { 196 # Node. 197 my $nodename = lc($2); 198 if ($header =~ /^netinet\//) { 199 $ctlname = "net.inet.$nodename"; 200 } elsif ($header =~ /^netinet6\//) { 201 $ctlname = "net.inet6.$nodename"; 202 } elsif ($header =~ /^net\//) { 203 $ctlname = "net.$nodename"; 204 } else { 205 $ctlname = "$nodename"; 206 $ctlname =~ s/^(fs|net|kern)_/$1\./; 207 } 208 if (exists $ctl_map{$ctlname}) { 209 $ctlname = $ctl_map{$ctlname}; 210 } 211 if (not exists $ctls{$ctlname}) { 212 &debug("Ignoring $ctlname..."); 213 next; 214 } 215 216 # Walk down from the top of the MIB. 217 $node = \%mib; 218 foreach my $part (split /\./, $ctlname) { 219 if (not exists $$node{$part}) { 220 &debug("Missing node $part"); 221 $$node{$part} = [ 0, '', {} ]; 222 } 223 $node = \%{@{$$node{$part}}[2]}; 224 } 225 } 226 227 # Populate current node with entries. 228 my $i = -1; 229 while (defined($_) && $_ !~ /^}/) { 230 $_ = <HEADER>; 231 $i++ if $_ =~ /{.*}/; 232 next if $_ !~ /{\s+"(\w+)",\s+(CTLTYPE_[A-Z]+)\s+}/; 233 $$node{$1} = [ $i, $2, {} ]; 234 } 235 } 236 } 237 close HEADER; 238 } 239 240 &build_sysctl(\%mib, "", []); 241 242 print <<EOF; 243 // mksysctl_openbsd.pl 244 // Code generated by the command above; DO NOT EDIT. 245 246 // +build $ENV{'GOARCH'},$ENV{'GOOS'} 247 248 package unix; 249 250 type mibentry struct { 251 ctlname string 252 ctloid []_C_int 253 } 254 255 var sysctlMib = []mibentry { 256 EOF 257 258 foreach my $name (sort keys %sysctl) { 259 my @oid = @{$sysctl{$name}}; 260 print "\t{ \"$name\", []_C_int{ ", join(', ', @oid), " } }, \n"; 261 } 262 263 print <<EOF; 264 } 265 EOF