Move tcpdump-3.9/ to tcpdump/. No need for a versioned dir.
[dragonfly.git] / contrib / tcpdump / makemib
CommitLineData
c8cf0f94
PA
1#!/bin/sh
2#
3# Copyright (c) 1990, 1996
4# John Robert LoVerso. All rights reserved.
5# SMIv2 parsing copyright (c) 1999
6# William C. Fenner.
7#
8# Redistribution and use in source and binary forms, with or without
9# modification, are permitted provided that the following conditions
10# are met:
11#
12# 1. Redistributions of source code must retain the above copyright
13# notices, this list of conditions and the following disclaimer.
14#
15# 2. Redistributions in binary form must reproduce the above copyright
16# notices, this list of conditions and the following disclaimer in the
17# documentation and/or other materials provided with the distribution.
18#
19# THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
20# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29#
30# @(#) $Id: makemib,v 1.3 2001/09/17 22:16:52 fenner Exp $ (jlv)
31
32#
33# This script will read either ASN.1-style MIB files or the ".defs" files
34# created by the ISODE "mosy" program on such files.
35#
36# The output of this script is the "mib.h" file used by tcpdumps' ASN.1/SNMP
37# decoding code.
38#
39# This script needs to be run by "gawk" (GNU awk). "nawk" will work, but
40# dump will get a recursion error if you process LARGE mibs. While it would
41# by farily easy to rewrite this not to use recursion (and also easy to
42# eliminate use of gsub and functions to use classic "awk"), you have to
43# order the structure declarations in defined-first order for the compiler
44# not to barf; too bad tsort doesn't take arguments.
45#
46
47cat << EOF
48/*
49 * This file was generated by tcpdump/makemib on `date`
50 * You probably don't want to edit this by hand!
51 *
52 * struct mib somename = { desc, oid-octet, type, child-pointer, next-pointer
53};
54 */
55
56EOF
57
58awk '
59BEGIN {
60 debug=0;
61 # for sanity, we prep the namespace with objects from RFC-1155
62 # (we manually establish the root)
63 oid["iso"]=1
64 oidadd("org", "iso", 3)
65 oidadd("dod", "org", 6)
66 oidadd("internet", "dod", 1)
67 oidadd("directory", "internet", 1)
68 oidadd("mgmt", "internet", 2)
69#XXX oidadd("mib", "mgmt", 1)
70 oidadd("mib-2", "mgmt", 1)
71 oidadd("experimental", "internet", 3)
72 oidadd("private", "internet", 4)
73 oidadd("enterprises", "private", 1)
74 oidadd("ip", "mib-2", 4)
75 oidadd("transmission", "mib-2", 10)
76
77 holddesc="none"
78}
79
80#
81# Read mosy "*.defs" file. mosy does all the parsing work; we just read
82# its simple and straightforward output. It would not be too hard to make
83# tcpdump directly read mosy output, but...
84#
85# Ignore these unless the current file is called something.defs; false
86# positives are too common in DESCRIPTIONs.
87
88NF > 1 && index($2,".")>0 && FILENAME ~ /\.defs/ {
89 # currently ignore items of the form "{ iso.3.6.1 }"
90 if (split($2, p, ".") == 2) {
91 oidadd($1, p[1], p[2])
92 }
93 next
94}
95
96#
97# Must be a MIB file
98# Make it easier to parse - used to be done by sed
99{ sub(/--\*.*\*--/, ""); sub(/--.*/, ""); gsub(/[{}]/, " & "); }
100
101#
102# this next section is simple and naive, but does the job ok
103#
104
105# foo OBJECT IDENTIFIER ::= { baz 17 }
106# or
107# foo OBJECT IDENTIFIER ::=
108# { baz 17 }
109$2$3$4 == "OBJECTIDENTIFIER::=" {
110 holddesc="none"
111 if (NF == 8)
112 oidadd($1, $6, $7)
113 if (NF == 4)
114 holddesc=$1
115 next
116}
117$1 == "{" && holddesc != "none" && NF == 4 {
118 oidadd(holddesc, $2, $3)
119 holddesc="none"
120}
121#
122# foo OBJECT IDENTIFIER
123# ::= { bar 1 }
124$2$3 == "OBJECTIDENTIFIER" && $1 != "SYNTAX" && NF == 3 {
125 holddesc=$1
126}
127#
128# foo
129# OBJECT IDENTIFIER ::= { bar 1 }
130# a couple of heuristics to exclude single words in e.g. long
131# DESCRIPTION clauses
132NF == 1 && $1 ~ "[a-z][a-z]*[A-Z]" && $1 !~ /[(){}.,]/ && holddesc == "none" {
133 holddesc=$1
134}
135$1$2$3 == "OBJECTIDENTIFIER::=" && holddesc != "none" {
136 oidadd(holddesc, $5, $6)
137 holddesc="none"
138}
139#
140# "normal" style
141# foo OBJECT-TYPE ...
142# ...
143# ::= { baz 5 }
144$2 == "MODULE-IDENTITY" || $2 == "MODULE-COMPLIANCE" ||
145 $2 == "OBJECT-IDENTITY" || $2 == "OBJECT-TYPE" ||
146 $2 == "OBJECT-GROUP" ||
147 $2 == "NOTIFICATION-TYPE" || $2 == "NOTIFICATION-GROUP" {
148 holddesc=$1
149}
150$1 == "::=" && holddesc != "none" && NF == 5 {
151 oidadd(holddesc, $3, $4)
152 holddesc="none"
153}
154#
155# foo ::= { baz 17 }
156$2$3 == "::={" {
157 oidadd($1,$4,$5)
158 holddesc="none"
159}
160
161
162#
163# End of the road - output the data.
164#
165
166END {
167 print "struct obj"
168 dump("iso")
169 print "*mibroot = &_iso_obj;"
170}
171
172function inn(file) {
173 if (file == "" || file == "-")
174 return ""
175 return " in " file
176}
177
178#
179# add a new object to the tree
180#
181# new OBJECT IDENTIFIER ::= { parent value }
182#
183
184function oidadd(new, parent, value) {
185 # Ignore 0.0
186 if (parent == "0" && value == 0)
187 return
188 if (debug)
189 print "/* oidadd" inn(FILENAME) ":", new, "in", parent, "as", value, "line", $0, "*/"
190 # use safe C identifiers
191 gsub(/[-&\/]/,"",new)
192 gsub(/[-&\/]/,"",parent)
193 # check if parent missing
194 if (oid[parent] == "") {
195 printf "/* parse problem%s: no parent for %s.%s(%d) */\n", \
196 inn(FILENAME), parent, new, value
197 return
198 }
199 # check if parent.value already exists
200 if (oid[new] > 0 && oid[new] != value) {
201 printf "/* parse problem%s: dup %s.%s(%d) != old (%d) */\n", \
202 inn(FILENAME), parent, new, value, oid[new]
203 return
204 }
205 # check for new name for parent.value
206 if (child[parent] != "") {
207 for (sib = child[parent]; sib != ""; sib = sibling[sib])
208 if (oid[sib] == value) {
209 if (new != sib)
210 printf "/* parse problem%s: new name" \
211 " \"%s\"" \
212 " for %s.%s(%d) ignored */\n", \
213 inn(FILENAME), new, parent, \
214 sib, value
215 return
216 }
217 }
218
219 oid[new]=value
220 if (child[parent] == "") {
221 child[parent] = new
222 } else {
223 sibling[new] = child[parent]
224 child[parent] = new
225 }
226}
227
228#
229# old(?) routine to recurse down the tree (in postfix order for convenience)
230#
231
232function dump(item, c, s) {
233# newitem=sofar"."item"("oid[item]")"
234# printf "/* %s c=%s s=%s */\n", newitem, child[item], sibling[item]
235 c="NULL"
236 if (child[item] != "") {
237 dump(child[item])
238 c = "&_"child[item]"_obj"
239 }
240 s="NULL"
241 if (sibling[item] != "") {
242 dump(sibling[item])
243 s = "&_"sibling[item]"_obj"
244 }
245 printf "_%s_obj = {\n\t\"%s\", %d, 0,\n\t%s, %s\n},\n", \
246 item, item, oid[item], c, s
247}
248' $@
249exit 0