Text file src/syscall/mksysctl_openbsd.pl

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

View as plain text