|
|
- #!/usr/bin/env perl
-
- # Copyright 2011 The Go Authors. All rights reserved.
- # Use of this source code is governed by a BSD-style
- # license that can be found in the LICENSE file.
-
- #
- # Parse the header files for OpenBSD and generate a Go usable sysctl MIB.
- #
- # Build a MIB with each entry being an array containing the level, type and
- # a hash that will contain additional entries if the current entry is a node.
- # We then walk this MIB and create a flattened sysctl name to OID hash.
- #
-
- use strict;
-
- if($ENV{'GOARCH'} eq "" || $ENV{'GOOS'} eq "") {
- print STDERR "GOARCH or GOOS not defined in environment\n";
- exit 1;
- }
-
- my $debug = 0;
- my %ctls = ();
-
- my @headers = qw (
- sys/sysctl.h
- sys/socket.h
- sys/tty.h
- sys/malloc.h
- sys/mount.h
- sys/namei.h
- sys/sem.h
- sys/shm.h
- sys/vmmeter.h
- uvm/uvm_param.h
- uvm/uvm_swap_encrypt.h
- ddb/db_var.h
- net/if.h
- net/if_pfsync.h
- net/pipex.h
- netinet/in.h
- netinet/icmp_var.h
- netinet/igmp_var.h
- netinet/ip_ah.h
- netinet/ip_carp.h
- netinet/ip_divert.h
- netinet/ip_esp.h
- netinet/ip_ether.h
- netinet/ip_gre.h
- netinet/ip_ipcomp.h
- netinet/ip_ipip.h
- netinet/pim_var.h
- netinet/tcp_var.h
- netinet/udp_var.h
- netinet6/in6.h
- netinet6/ip6_divert.h
- netinet6/pim6_var.h
- netinet/icmp6.h
- netmpls/mpls.h
- );
-
- my @ctls = qw (
- kern
- vm
- fs
- net
- #debug # Special handling required
- hw
- #machdep # Arch specific
- user
- ddb
- #vfs # Special handling required
- fs.posix
- kern.forkstat
- kern.intrcnt
- kern.malloc
- kern.nchstats
- kern.seminfo
- kern.shminfo
- kern.timecounter
- kern.tty
- kern.watchdog
- net.bpf
- net.ifq
- net.inet
- net.inet.ah
- net.inet.carp
- net.inet.divert
- net.inet.esp
- net.inet.etherip
- net.inet.gre
- net.inet.icmp
- net.inet.igmp
- net.inet.ip
- net.inet.ip.ifq
- net.inet.ipcomp
- net.inet.ipip
- net.inet.mobileip
- net.inet.pfsync
- net.inet.pim
- net.inet.tcp
- net.inet.udp
- net.inet6
- net.inet6.divert
- net.inet6.ip6
- net.inet6.icmp6
- net.inet6.pim6
- net.inet6.tcp6
- net.inet6.udp6
- net.mpls
- net.mpls.ifq
- net.key
- net.pflow
- net.pfsync
- net.pipex
- net.rt
- vm.swapencrypt
- #vfsgenctl # Special handling required
- );
-
- # Node name "fixups"
- my %ctl_map = (
- "ipproto" => "net.inet",
- "net.inet.ipproto" => "net.inet",
- "net.inet6.ipv6proto" => "net.inet6",
- "net.inet6.ipv6" => "net.inet6.ip6",
- "net.inet.icmpv6" => "net.inet6.icmp6",
- "net.inet6.divert6" => "net.inet6.divert",
- "net.inet6.tcp6" => "net.inet.tcp",
- "net.inet6.udp6" => "net.inet.udp",
- "mpls" => "net.mpls",
- "swpenc" => "vm.swapencrypt"
- );
-
- # Node mappings
- my %node_map = (
- "net.inet.ip.ifq" => "net.ifq",
- "net.inet.pfsync" => "net.pfsync",
- "net.mpls.ifq" => "net.ifq"
- );
-
- my $ctlname;
- my %mib = ();
- my %sysctl = ();
- my $node;
-
- sub debug() {
- print STDERR "$_[0]\n" if $debug;
- }
-
- # Walk the MIB and build a sysctl name to OID mapping.
- sub build_sysctl() {
- my ($node, $name, $oid) = @_;
- my %node = %{$node};
- my @oid = @{$oid};
-
- foreach my $key (sort keys %node) {
- my @node = @{$node{$key}};
- my $nodename = $name.($name ne '' ? '.' : '').$key;
- my @nodeoid = (@oid, $node[0]);
- if ($node[1] eq 'CTLTYPE_NODE') {
- if (exists $node_map{$nodename}) {
- $node = \%mib;
- $ctlname = $node_map{$nodename};
- foreach my $part (split /\./, $ctlname) {
- $node = \%{@{$$node{$part}}[2]};
- }
- } else {
- $node = $node[2];
- }
- &build_sysctl($node, $nodename, \@nodeoid);
- } elsif ($node[1] ne '') {
- $sysctl{$nodename} = \@nodeoid;
- }
- }
- }
-
- foreach my $ctl (@ctls) {
- $ctls{$ctl} = $ctl;
- }
-
- # Build MIB
- foreach my $header (@headers) {
- &debug("Processing $header...");
- open HEADER, "/usr/include/$header" ||
- print STDERR "Failed to open $header\n";
- while (<HEADER>) {
- if ($_ =~ /^#define\s+(CTL_NAMES)\s+{/ ||
- $_ =~ /^#define\s+(CTL_(.*)_NAMES)\s+{/ ||
- $_ =~ /^#define\s+((.*)CTL_NAMES)\s+{/) {
- if ($1 eq 'CTL_NAMES') {
- # Top level.
- $node = \%mib;
- } else {
- # Node.
- my $nodename = lc($2);
- if ($header =~ /^netinet\//) {
- $ctlname = "net.inet.$nodename";
- } elsif ($header =~ /^netinet6\//) {
- $ctlname = "net.inet6.$nodename";
- } elsif ($header =~ /^net\//) {
- $ctlname = "net.$nodename";
- } else {
- $ctlname = "$nodename";
- $ctlname =~ s/^(fs|net|kern)_/$1\./;
- }
- if (exists $ctl_map{$ctlname}) {
- $ctlname = $ctl_map{$ctlname};
- }
- if (not exists $ctls{$ctlname}) {
- &debug("Ignoring $ctlname...");
- next;
- }
-
- # Walk down from the top of the MIB.
- $node = \%mib;
- foreach my $part (split /\./, $ctlname) {
- if (not exists $$node{$part}) {
- &debug("Missing node $part");
- $$node{$part} = [ 0, '', {} ];
- }
- $node = \%{@{$$node{$part}}[2]};
- }
- }
-
- # Populate current node with entries.
- my $i = -1;
- while (defined($_) && $_ !~ /^}/) {
- $_ = <HEADER>;
- $i++ if $_ =~ /{.*}/;
- next if $_ !~ /{\s+"(\w+)",\s+(CTLTYPE_[A-Z]+)\s+}/;
- $$node{$1} = [ $i, $2, {} ];
- }
- }
- }
- close HEADER;
- }
-
- &build_sysctl(\%mib, "", []);
-
- print <<EOF;
- // mksysctl_openbsd.pl
- // MACHINE GENERATED BY THE ABOVE COMMAND; DO NOT EDIT
-
- // +build $ENV{'GOARCH'},$ENV{'GOOS'}
-
- package unix;
-
- type mibentry struct {
- ctlname string
- ctloid []_C_int
- }
-
- var sysctlMib = []mibentry {
- EOF
-
- foreach my $name (sort keys %sysctl) {
- my @oid = @{$sysctl{$name}};
- print "\t{ \"$name\", []_C_int{ ", join(', ', @oid), " } }, \n";
- }
-
- print <<EOF;
- }
- EOF
|