mksysctl_openbsd.pl 5.2 KB

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