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