...

Text file src/pkg/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

View as plain text