mksysctl_openbsd.pl 5.0 KB

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