1#!/bin/sh 2# 3# Copyright (c) 1990, 1996, by John Robert LoVerso. 4# All rights reserved. 5# 6# Redistribution and use in source and binary forms are permitted 7# provided that the above copyright notice and this paragraph are 8# duplicated in all such forms and that any documentation, 9# advertising materials, and other materials related to such 10# distribution and use acknowledge that the software was developed 11# by John Robert LoVerso. 12# THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 13# IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 14# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 15# 16# @(#) $Id: makemib,v 2.1 90/07/10 23:51:54 loverso Exp Locker: loverso $ (jlv 17) 18 19# 20# This script will read either ASN.1-style MIB files or the ".defs" files 21# created by the ISODE "mosy" program on such files. 22# 23# The output of this script is the "mib.h" file used by tcpdumps' ASN.1/SNMP 24# decoding code. 25# 26# This script needs to be run by "gawk" (GNU awk). "nawk" will work, but 27# dump will get a recursion error if you process LARGE mibs. While it would 28# by farily easy to rewrite this not to use recursion (and also easy to 29# eliminate use of gsub and functions to use classic "awk"), you have to 30# order the structure declarations in defined-first order for the compiler 31# not to barf; too bad tsort doesn't take arguments. 32# 33 34cat << EOF 35/* 36 * This file was generated by tcpdump/makemib on `date` 37 * You probably don't want to edit this by hand! 38 * 39 * struct mib somename = { desc, oid-octet, type, child-pointer, next-pointer 40}; 41 */ 42 43EOF 44 45# use sed to make the ASN.1 easier to parse 46# I should really just use a recursive descent parser in awk, but... 47sed \ 48 -e 's/--\*.*\*--//' \ 49 -e 's/--.*//' \ 50 -e 's/\([{}]\)/ \1 /g' \ 51 $@ \ 52| gawk ' 53BEGIN { 54 # for sanity, we prep the namespace with objects from RFC-1155 55 # (we manually establish the root) 56 oid["iso"]=1 57 oidadd("org", "iso", 3) 58 oidadd("dod", "org", 6) 59 oidadd("internet", "dod", 1) 60 oidadd("directory", "internet", 1) 61 oidadd("mgmt", "internet", 2) 62 oidadd("mib", "mgmt", 1) 63 oidadd("experimental", "internet", 3) 64 oidadd("private", "internet", 4) 65 oidadd("enterprises", "private", 1) 66 67 holddesc="none" 68} 69 70# 71# Read mosy "*.defs" file. mosy does all the parsing work; we just read 72# its simple and straightforward output. It would not be too hard to make 73# tcpdump directly read mosy output, but... 74# 75 76NF > 1 && index($2,".")>0 { 77 # currently ignore items of the form "{ iso.3.6.1 }" 78 if (split($2, p, ".") == 2) 79 oidadd($1, p[1], p[2]) 80 next 81} 82 83# 84# this next section is simple and naive, but does the job 100% 85# 86 87$2$3$4 == "OBJECTIDENTIFIER::=" { 88 holddesc="none" 89 if (NF == 8) 90 oidadd($1, $6, $7) 91} 92$2 == "OBJECT-TYPE" { 93 holddesc=$1 94} 95$1 == "::=" && holddesc != "none" && NF == 5 { 96 oidadd(holddesc, $3, $4) 97 holddesc="none" 98} 99 100# 101# End of the road - output the data. 102# 103 104END { 105 print "struct obj" 106 dump("iso") 107 print "*mibroot = &_iso_obj;" 108} 109 110# 111# add a new object to the tree 112# 113# new OBJECT IDENTIFIER ::= { parent value } 114# 115 116function oidadd(new, parent, value) { 117 # use safe C identifiers 118 gsub(/[-&\/]/,"",new) 119 gsub(/[-&\/]/,"",parent) 120 # check if parent missing 121 if (oid[parent] == 0) { 122 printf "/* parse problem: no parent for %s.%s(%d) */\n", \ 123 parent, new, value 124 return 125 } 126 # check if parent.value already exists 127 if (oid[new] > 0 && oid[new] != value) { 128 printf "/* parse problem: dup %s.%s(%d) != old (%d) */\n", \ 129 parent, new, value, oid[new] 130 return 131 } 132 # check for new name for parent.value 133 if (child[parent] != "") { 134 for (sib = child[parent]; sib != ""; sib = sibling[sib]) 135 if (oid[sib] == value) { 136 printf "/* parse problem: new name \"%s\"" \ 137 " for %s.%s(%d) ignored */\n", \ 138 new, parent, sib, value 139 return 140 } 141 } 142 143 oid[new]=value 144 if (child[parent] == "") { 145 child[parent] = new 146 } else { 147 sibling[new] = child[parent] 148 child[parent] = new 149 } 150} 151 152# 153# old(?) routine to recurse down the tree (in postfix order for convenience) 154# 155 156function dump(item, c, s) { 157# newitem=sofar"."item"("oid[item]")" 158# printf "/* %s c=%s s=%s */\n", newitem, child[item], sibling[item] 159 c="NULL" 160 if (child[item] != "") { 161 dump(child[item]) 162 c = "&_"child[item]"_obj" 163 } 164 s="NULL" 165 if (sibling[item] != "") { 166 dump(sibling[item]) 167 s = "&_"sibling[item]"_obj" 168 } 169 printf "_%s_obj = {\n\t\"%s\", %d, 0,\n\t%s, %s\n},\n", \ 170 item, item, oid[item], c, s 171} 172' 173exit 0 174