| #!/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; | |
| 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 | |
| package syscall; | |
| 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 |