14edb46e9SPaul Traina#!/bin/sh 24edb46e9SPaul Traina# 3a90e161bSBill Fenner# Copyright (c) 1990, 1996 4a90e161bSBill Fenner# John Robert LoVerso. All rights reserved. 5a90e161bSBill Fenner# SMIv2 parsing copyright (c) 1999 6a90e161bSBill Fenner# William C. Fenner. 74edb46e9SPaul Traina# 8a90e161bSBill Fenner# Redistribution and use in source and binary forms, with or without 9a90e161bSBill Fenner# modification, are permitted provided that the following conditions 10a90e161bSBill Fenner# are met: 114edb46e9SPaul Traina# 12a90e161bSBill Fenner# 1. Redistributions of source code must retain the above copyright 13a90e161bSBill Fenner# notices, this list of conditions and the following disclaimer. 14a90e161bSBill Fenner# 15a90e161bSBill Fenner# 2. Redistributions in binary form must reproduce the above copyright 16a90e161bSBill Fenner# notices, this list of conditions and the following disclaimer in the 17a90e161bSBill Fenner# documentation and/or other materials provided with the distribution. 18a90e161bSBill Fenner# 19a90e161bSBill Fenner# THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 20a90e161bSBill Fenner# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21a90e161bSBill Fenner# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22a90e161bSBill Fenner# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, 23a90e161bSBill Fenner# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24a90e161bSBill Fenner# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25a90e161bSBill Fenner# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26a90e161bSBill Fenner# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27a90e161bSBill Fenner# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28a90e161bSBill Fenner# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 294edb46e9SPaul Traina 304edb46e9SPaul Traina# 314edb46e9SPaul Traina# This script will read either ASN.1-style MIB files or the ".defs" files 324edb46e9SPaul Traina# created by the ISODE "mosy" program on such files. 334edb46e9SPaul Traina# 344edb46e9SPaul Traina# The output of this script is the "mib.h" file used by tcpdumps' ASN.1/SNMP 354edb46e9SPaul Traina# decoding code. 364edb46e9SPaul Traina# 374edb46e9SPaul Traina# This script needs to be run by "gawk" (GNU awk). "nawk" will work, but 384edb46e9SPaul Traina# dump will get a recursion error if you process LARGE mibs. While it would 39*0a7e5f1fSJoseph Mingrone# by fairly easy to rewrite this not to use recursion (and also easy to 404edb46e9SPaul Traina# eliminate use of gsub and functions to use classic "awk"), you have to 414edb46e9SPaul Traina# order the structure declarations in defined-first order for the compiler 424edb46e9SPaul Traina# not to barf; too bad tsort doesn't take arguments. 434edb46e9SPaul Traina# 444edb46e9SPaul Traina 454edb46e9SPaul Trainacat << EOF 464edb46e9SPaul Traina/* 474edb46e9SPaul Traina * This file was generated by tcpdump/makemib on `date` 484edb46e9SPaul Traina * You probably don't want to edit this by hand! 494edb46e9SPaul Traina * 504edb46e9SPaul Traina * struct mib somename = { desc, oid-octet, type, child-pointer, next-pointer 514edb46e9SPaul Traina}; 524edb46e9SPaul Traina */ 534edb46e9SPaul Traina 544edb46e9SPaul TrainaEOF 554edb46e9SPaul Traina 56b0453382SBill Fennerawk ' 574edb46e9SPaul TrainaBEGIN { 58b0453382SBill Fenner debug=0; 594edb46e9SPaul Traina # for sanity, we prep the namespace with objects from RFC-1155 604edb46e9SPaul Traina # (we manually establish the root) 614edb46e9SPaul Traina oid["iso"]=1 624edb46e9SPaul Traina oidadd("org", "iso", 3) 634edb46e9SPaul Traina oidadd("dod", "org", 6) 644edb46e9SPaul Traina oidadd("internet", "dod", 1) 654edb46e9SPaul Traina oidadd("directory", "internet", 1) 664edb46e9SPaul Traina oidadd("mgmt", "internet", 2) 67b0453382SBill Fenner#XXX oidadd("mib", "mgmt", 1) 68b0453382SBill Fenner oidadd("mib-2", "mgmt", 1) 694edb46e9SPaul Traina oidadd("experimental", "internet", 3) 704edb46e9SPaul Traina oidadd("private", "internet", 4) 714edb46e9SPaul Traina oidadd("enterprises", "private", 1) 72b0453382SBill Fenner oidadd("ip", "mib-2", 4) 73b0453382SBill Fenner oidadd("transmission", "mib-2", 10) 744edb46e9SPaul Traina 754edb46e9SPaul Traina holddesc="none" 764edb46e9SPaul Traina} 774edb46e9SPaul Traina 784edb46e9SPaul Traina# 794edb46e9SPaul Traina# Read mosy "*.defs" file. mosy does all the parsing work; we just read 804edb46e9SPaul Traina# its simple and straightforward output. It would not be too hard to make 814edb46e9SPaul Traina# tcpdump directly read mosy output, but... 824edb46e9SPaul Traina# 83b0453382SBill Fenner# Ignore these unless the current file is called something.defs; false 84b0453382SBill Fenner# positives are too common in DESCRIPTIONs. 854edb46e9SPaul Traina 86b0453382SBill FennerNF > 1 && index($2,".")>0 && FILENAME ~ /\.defs/ { 874edb46e9SPaul Traina # currently ignore items of the form "{ iso.3.6.1 }" 88b0453382SBill Fenner if (split($2, p, ".") == 2) { 894edb46e9SPaul Traina oidadd($1, p[1], p[2]) 90b0453382SBill Fenner } 914edb46e9SPaul Traina next 924edb46e9SPaul Traina} 934edb46e9SPaul Traina 944edb46e9SPaul Traina# 95b0453382SBill Fenner# Must be a MIB file 96b0453382SBill Fenner# Make it easier to parse - used to be done by sed 97b0453382SBill Fenner{ sub(/--\*.*\*--/, ""); sub(/--.*/, ""); gsub(/[{}]/, " & "); } 98b0453382SBill Fenner 99b0453382SBill Fenner# 100b0453382SBill Fenner# this next section is simple and naive, but does the job ok 1014edb46e9SPaul Traina# 1024edb46e9SPaul Traina 103b0453382SBill Fenner# foo OBJECT IDENTIFIER ::= { baz 17 } 104b0453382SBill Fenner# or 105b0453382SBill Fenner# foo OBJECT IDENTIFIER ::= 106b0453382SBill Fenner# { baz 17 } 1074edb46e9SPaul Traina$2$3$4 == "OBJECTIDENTIFIER::=" { 1084edb46e9SPaul Traina holddesc="none" 1094edb46e9SPaul Traina if (NF == 8) 1104edb46e9SPaul Traina oidadd($1, $6, $7) 111b0453382SBill Fenner if (NF == 4) 112b0453382SBill Fenner holddesc=$1 113b0453382SBill Fenner next 1144edb46e9SPaul Traina} 115b0453382SBill Fenner$1 == "{" && holddesc != "none" && NF == 4 { 116b0453382SBill Fenner oidadd(holddesc, $2, $3) 117b0453382SBill Fenner holddesc="none" 118b0453382SBill Fenner} 119b0453382SBill Fenner# 120b0453382SBill Fenner# foo OBJECT IDENTIFIER 121b0453382SBill Fenner# ::= { bar 1 } 122b0453382SBill Fenner$2$3 == "OBJECTIDENTIFIER" && $1 != "SYNTAX" && NF == 3 { 123b0453382SBill Fenner holddesc=$1 124b0453382SBill Fenner} 125b0453382SBill Fenner# 126b0453382SBill Fenner# foo 127b0453382SBill Fenner# OBJECT IDENTIFIER ::= { bar 1 } 128b0453382SBill Fenner# a couple of heuristics to exclude single words in e.g. long 129b0453382SBill Fenner# DESCRIPTION clauses 130b0453382SBill FennerNF == 1 && $1 ~ "[a-z][a-z]*[A-Z]" && $1 !~ /[(){}.,]/ && holddesc == "none" { 131b0453382SBill Fenner holddesc=$1 132b0453382SBill Fenner} 133b0453382SBill Fenner$1$2$3 == "OBJECTIDENTIFIER::=" && holddesc != "none" { 134b0453382SBill Fenner oidadd(holddesc, $5, $6) 135b0453382SBill Fenner holddesc="none" 136b0453382SBill Fenner} 137b0453382SBill Fenner# 138b0453382SBill Fenner# "normal" style 139b0453382SBill Fenner# foo OBJECT-TYPE ... 140b0453382SBill Fenner# ... 141b0453382SBill Fenner# ::= { baz 5 } 142b0453382SBill Fenner$2 == "MODULE-IDENTITY" || $2 == "MODULE-COMPLIANCE" || 143b0453382SBill Fenner $2 == "OBJECT-IDENTITY" || $2 == "OBJECT-TYPE" || 144b0453382SBill Fenner $2 == "OBJECT-GROUP" || 145b0453382SBill Fenner $2 == "NOTIFICATION-TYPE" || $2 == "NOTIFICATION-GROUP" { 1464edb46e9SPaul Traina holddesc=$1 1474edb46e9SPaul Traina} 1484edb46e9SPaul Traina$1 == "::=" && holddesc != "none" && NF == 5 { 1494edb46e9SPaul Traina oidadd(holddesc, $3, $4) 1504edb46e9SPaul Traina holddesc="none" 1514edb46e9SPaul Traina} 152b0453382SBill Fenner# 153b0453382SBill Fenner# foo ::= { baz 17 } 154b0453382SBill Fenner$2$3 == "::={" { 155b0453382SBill Fenner oidadd($1,$4,$5) 156b0453382SBill Fenner holddesc="none" 157b0453382SBill Fenner} 158b0453382SBill Fenner 1594edb46e9SPaul Traina 1604edb46e9SPaul Traina# 1614edb46e9SPaul Traina# End of the road - output the data. 1624edb46e9SPaul Traina# 1634edb46e9SPaul Traina 1644edb46e9SPaul TrainaEND { 1654edb46e9SPaul Traina print "struct obj" 1664edb46e9SPaul Traina dump("iso") 1674edb46e9SPaul Traina print "*mibroot = &_iso_obj;" 1684edb46e9SPaul Traina} 1694edb46e9SPaul Traina 170b0453382SBill Fennerfunction inn(file) { 171b0453382SBill Fenner if (file == "" || file == "-") 172b0453382SBill Fenner return "" 173b0453382SBill Fenner return " in " file 174b0453382SBill Fenner} 175b0453382SBill Fenner 1764edb46e9SPaul Traina# 1774edb46e9SPaul Traina# add a new object to the tree 1784edb46e9SPaul Traina# 1794edb46e9SPaul Traina# new OBJECT IDENTIFIER ::= { parent value } 1804edb46e9SPaul Traina# 1814edb46e9SPaul Traina 1824edb46e9SPaul Trainafunction oidadd(new, parent, value) { 183b0453382SBill Fenner # Ignore 0.0 184b0453382SBill Fenner if (parent == "0" && value == 0) 185b0453382SBill Fenner return 186b0453382SBill Fenner if (debug) 187b0453382SBill Fenner print "/* oidadd" inn(FILENAME) ":", new, "in", parent, "as", value, "line", $0, "*/" 1884edb46e9SPaul Traina # use safe C identifiers 1894edb46e9SPaul Traina gsub(/[-&\/]/,"",new) 1904edb46e9SPaul Traina gsub(/[-&\/]/,"",parent) 1914edb46e9SPaul Traina # check if parent missing 192b0453382SBill Fenner if (oid[parent] == "") { 193b0453382SBill Fenner printf "/* parse problem%s: no parent for %s.%s(%d) */\n", \ 194b0453382SBill Fenner inn(FILENAME), parent, new, value 1954edb46e9SPaul Traina return 1964edb46e9SPaul Traina } 1974edb46e9SPaul Traina # check if parent.value already exists 1984edb46e9SPaul Traina if (oid[new] > 0 && oid[new] != value) { 199b0453382SBill Fenner printf "/* parse problem%s: dup %s.%s(%d) != old (%d) */\n", \ 200b0453382SBill Fenner inn(FILENAME), parent, new, value, oid[new] 2014edb46e9SPaul Traina return 2024edb46e9SPaul Traina } 2034edb46e9SPaul Traina # check for new name for parent.value 2044edb46e9SPaul Traina if (child[parent] != "") { 2054edb46e9SPaul Traina for (sib = child[parent]; sib != ""; sib = sibling[sib]) 2064edb46e9SPaul Traina if (oid[sib] == value) { 207b0453382SBill Fenner if (new != sib) 208b0453382SBill Fenner printf "/* parse problem%s: new name" \ 209b0453382SBill Fenner " \"%s\"" \ 2104edb46e9SPaul Traina " for %s.%s(%d) ignored */\n", \ 211b0453382SBill Fenner inn(FILENAME), new, parent, \ 212b0453382SBill Fenner sib, value 2134edb46e9SPaul Traina return 2144edb46e9SPaul Traina } 2154edb46e9SPaul Traina } 2164edb46e9SPaul Traina 2174edb46e9SPaul Traina oid[new]=value 2184edb46e9SPaul Traina if (child[parent] == "") { 2194edb46e9SPaul Traina child[parent] = new 2204edb46e9SPaul Traina } else { 2214edb46e9SPaul Traina sibling[new] = child[parent] 2224edb46e9SPaul Traina child[parent] = new 2234edb46e9SPaul Traina } 2244edb46e9SPaul Traina} 2254edb46e9SPaul Traina 2264edb46e9SPaul Traina# 2274edb46e9SPaul Traina# old(?) routine to recurse down the tree (in postfix order for convenience) 2284edb46e9SPaul Traina# 2294edb46e9SPaul Traina 2304edb46e9SPaul Trainafunction dump(item, c, s) { 2314edb46e9SPaul Traina# newitem=sofar"."item"("oid[item]")" 2324edb46e9SPaul Traina# printf "/* %s c=%s s=%s */\n", newitem, child[item], sibling[item] 2334edb46e9SPaul Traina c="NULL" 2344edb46e9SPaul Traina if (child[item] != "") { 2354edb46e9SPaul Traina dump(child[item]) 2364edb46e9SPaul Traina c = "&_"child[item]"_obj" 2374edb46e9SPaul Traina } 2384edb46e9SPaul Traina s="NULL" 2394edb46e9SPaul Traina if (sibling[item] != "") { 2404edb46e9SPaul Traina dump(sibling[item]) 2414edb46e9SPaul Traina s = "&_"sibling[item]"_obj" 2424edb46e9SPaul Traina } 2434edb46e9SPaul Traina printf "_%s_obj = {\n\t\"%s\", %d, 0,\n\t%s, %s\n},\n", \ 2444edb46e9SPaul Traina item, item, oid[item], c, s 2454edb46e9SPaul Traina} 246b0453382SBill Fenner' $@ 2474edb46e9SPaul Trainaexit 0 248