- (mib2c): created a mib2c template creator.
git-svn-id: file:///home/hardaker/lib/sf-bkups/net-snmp-convert-svnrepo/trunk@1357 06827809-a52a-0410-b366-d66718629ded
diff --git a/local/mib2c b/local/mib2c
new file mode 100755
index 0000000..f10e698
--- /dev/null
+++ b/local/mib2c
@@ -0,0 +1,279 @@
+#!/usr/local/bin/perl -w
+
+#
+# Description:
+#
+# This program, given an OID reference as an argument, creates some
+# template mib module files to be used with the ucd-snmp agent. It is
+# far from perfect and will not generate working modules, but it
+# significantly shortens development time by outlining the basic
+# structure.
+#
+# Its up to you to verify what it does and change the default values
+# it returns.
+#
+# You *must* correct the beginning of the var_XXX() function to
+# correctly determine mib ownership of the incoming request.
+#
+
+use SNMP;
+#use strict 'vars';
+$SNMP::save_descriptions=1;
+$SNMP::use_long_names=1;
+$SNMP::use_enums=1;
+SNMP::initMib();
+
+#
+# internal conversion tables
+#
+%typeToVar = qw(OctetStr string Objid objid Integer long_ret NetAddr objid
+ Ipaddr objid Counter long_ret Gauge long_ret Timeticks long_ret
+ UInteger long_ret);
+
+%typeToPtr = qw(OctetStr string Objid objid Integer &long_ret NetAddr objid
+ Ipaddr objid Counter &long_ret Gauge &long_ret
+ Timeticks &long_ret UInteger &long_ret);
+
+%typeToParser = qw(OctetStr string Objid objid Integer int NetAddr objid
+ Ipaddr objid Counter int Gauge int Timeticks int
+ UInteger unsigned_int);
+
+%varDefaults = ('long_ret' =>
+" long_ret = 0;
+ return (unsigned char *) &long_ret;\n",
+ 'objid' =>
+" objid[0] = 0;
+ objid[1] = 0;
+ *var_len = 2*sizeof(oid);
+ return (unsigned char *) objid;\n",
+
+ 'string' =>
+" *string = 0;
+ *var_len = strlen(string);
+ return (unsigned char *) string;\n");
+
+%typeToASN = qw(OctetStr ASN_OCTET_STR Objid ASN_OBJECT_ID Integer ASN_INTEGER
+ NetAddr ASN_OBJECT_ID Ipaddr ASN_IPADDRESS Counter ASN_COUNTER
+ Gauge ASN_GAUGE Timeticks ASN_TIMETICKS
+ UInteger ASN_UINTEGER);
+
+%accessToUCD = qw(ReadOnly RONLY ReadWrite RWRITE
+ WriteOnly RWRITE Create RWRITE);
+
+@varLengths = (2,4,7,8,13);
+
+$oid = shift;
+
+if (!defined($oid)) {
+ print STDERR "You didn\'t specify a mib oid to convert!\n";
+ exit(1);
+}
+
+$mib = $SNMP::MIB{$oid};
+$_ = $fulloid = $mib->{'objectID'};
+if (!defined ($fulloid)) {
+ print STDERR "Couldn\'t find mib reference: $oid\n";
+ exit(1);
+}
+
+s/[^.]//g;
+$fulllen = length($_);
+$outputName = shift;
+$outputName = $mib->{'label'} if (!defined($outputName));
+$OUTPUTNAME = uc($outputName);
+print "outputing to $outputName.c and $outputName.h ...\n";
+
+open(DOTH,">$outputName.h");
+open(DOTC,">$outputName.c");
+print DOTH "
+/* This file was generated by mib2c and is intended for use as a mib module
+ for the ucd-snmp snmpd agent. */
+
+#ifndef _MIBGROUP_${OUTPUTNAME}_H
+#define _MIBGROUP_${OUTPUTNAME}_H
+
+/* we use header_generic and checkmib from the util_funcs module */
+
+config_require(util_funcs)
+
+/* Magic number definitions: */\n\n";
+
+print DOTC "
+/* This file was generated by mib2c and is intended for use as a mib module
+ for the ucd-snmp snmpd agent. */
+
+#include <config.h>
+
+#include \"mibincl.h\"
+#include \"$outputName.h\"
+
+void init_$outputName __P((void)) {
+/* place any initialization routines needed here */
+}
+
+unsigned char *
+var_$outputName(vp, name, length, exact, var_len, write_method)
+ struct variable *vp;
+ oid *name;
+ int *length;
+ int exact;
+ int *var_len;
+ int (**write_method) __P((int, unsigned char *,unsigned char, int, unsigned char *,oid*, int));
+{
+
+ /* variables we may use later */
+ static long long_ret;
+ static unsigned char string[1500];
+ static oid objid[30];
+
+ *write_method = 0; /* assume it isnt writable for the time being */
+ *var_len = sizeof(long_ret); /* assume an integer and change later if not */
+
+ /* XXX: this following line is almost gaurunteed to be wrong for
+ your mib, please fix this */
+ if (!checkmib(vp,name,length,exact,var_len,write_method,newname,1)))
+ return 0;
+
+ /* this is where we do the value assignments for the mib results. */
+ switch(vp->magic) {\n\n";
+
+#
+# Collect mib information
+#
+$count = 0;
+$depth = loadMib($mib,0,0)-1;
+for($varlen = 0; $varlen <= $#varLengths; $varlen++) {
+ last if ($depth <= $varLengths[$varlen]);
+}
+$varlen = $varLengths[$varlen];
+
+print DOTC " default:
+ ERROR_MSG(\"\");
+ }
+ return 0;
+}
+
+$writeInfo";
+
+print DOTH "
+/* function definitions */
+
+extern void init_$outputName __P((void));
+extern unsigned char *var_$outputName __P((struct variable *, oid *, int *, int, int *, int (**write) __P((int, unsigned char *, unsigned char, int, unsigned char *, oid *, int)) ));
+$functionInfo
+
+/* Only load this structure when this .h file is called in the snmp_vars.c
+ file in tha agent subdirectory of the source tree */
+
+#ifdef IN_SNMP_VARS_C
+
+/* this variable defines function callbacks and type return information
+ for the $outputName mib */
+
+struct variable$varlen ${outputName}_variables[] = {
+$structinfo
+};
+
+/* now load this mib into the agents mib table */
+config_load_mib(" . substr($fulloid,1) . ", $fulllen, ${outputName}_variables)
+
+#endif /* IN_SNMP_VARS_C */
+#endif /* _MIBGROUP_${OUTPUTNAME}_H */\n";
+
+#
+# Writable variable code
+#
+close(DOTH);
+close(DOTC);
+print " depth: $depth\n";
+print " Number of Lines Created:\n";
+system("wc -l $outputName.c $outputName.h");
+print "Done.\n";
+
+sub loadMib {
+ my $mib = shift;
+# my $oid = shift;
+ my $depth = shift;
+ $depth = $depth + 1;
+# my $mib = $SNMP::MIB{$oid};
+# print "doing $mib->{label} : $mib->{objectID}\n";
+ if (defined($mib->{'access'}) &&
+ $mib->{'access'} =~ /ReadOnly|ReadWrite|WriteOnly|Create/) {
+ my $cname = uc($mib->{'label'});
+ print DOTC " case $cname:\n";
+ if (!defined($typeToVar{$mib->{'type'}})) {
+ print DOTC "/* unknown type: $mib->{type}. mib2c can not set up a default value for this mib value */.";
+ print STDERR "unknown type: $mib->{type} for $mib->{label}\n";
+ } else {
+ if ($mib->{'access'} =~ /ReadWrite|WriteOnly|Create/) {
+ createWriteFunction($mib->{'label'}, $mib->{'type'});
+ print DOTC " *write_method = write_$mib->{label};\n";
+ }
+ print DOTC $varDefaults{$typeToVar{$mib->{'type'}}}, "\n";
+ $count = $count + 1;
+ printf DOTH ("#define %-20s $count\n", $cname);
+ $subid = $mib->{'objectID'};
+ $subid =~ s/$fulloid\.//;
+ $subid =~ s/\./,/g;
+ $structinfo .=
+ sprintf(" { %-20s, %-14s, %-6.6s, %s, %d, { %s } },\n",
+ $cname, $typeToASN{$mib->{'type'}},
+ $accessToUCD{$mib->{'access'}},
+ "var_$outputName",
+ $depth-1, $subid);
+ }
+ }
+ my $children = $$mib{'children'};
+ my $i;
+ my $newdepth = $depth;
+ foreach $i (@{$children}) {
+ $newdepth = max(loadMib($i, $depth), $newdepth);
+ }
+ return $newdepth;
+}
+
+sub max {
+ my $x = shift;
+ my $y = shift;
+ return ($x > $y) ? $x : $y;
+}
+
+sub createWriteFunction {
+ my $name = shift;
+ my $type = shift;
+
+ $writeInfo .= "int
+write_$name(action, var_val, var_val_type, var_val_len, statP, name, name_len)
+ int action;
+ u_char *var_val;
+ u_char var_val_type;
+ int var_val_len;
+ u_char *statP;
+ oid *name;
+ int name_len;
+{
+ /* variables we may use later */
+ static long long_ret;
+ static unsigned char string[1500];
+ static oid objid[30];
+ int size, bigsize=1000;
+
+ if (var_val_type != $typeToASN{$type}){
+ fprintf(stderr, \"write to $name not $typeToASN{$type}\\n\");
+ return SNMP_ERR_WRONGTYPE;
+ }
+ if (var_val_len > sizeof($typeToVar{$type})){
+ printf(\"bad length\\n\");
+ return SNMP_ERR_WRONGLENGTH;
+ }
+ size = sizeof($typeToVar{$type});
+ asn_parse_$typeToParser{$type}(var_val, &bigsize, &var_val_type, $typeToPtr{$type}, size);
+ if (action == COMMIT){
+ /* Here, the variable has been stored in $typeToVar{$type} for
+ you to use, and you have just been asked to do something with
+ it... Your code goes here. */
+ }
+ return SNMP_ERR_NOERROR;
+}\n\n";
+ $functionInfo .= "int write_$name __P((int, u_char *,u_char, int, u_char *,oid*, int));\n";
+}