/* * Mibble MIB Parser (www.mibble.org) * * See LICENSE.txt for licensing information. * * Copyright (c) 2004-2017 Per Cederberg. All rights reserved. */ package net.percederberg.mibble; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.net.URL; import java.net.MalformedURLException; import java.util.Iterator; import net.percederberg.mibble.value.ObjectIdentifierValue; /** * A program that parses and prints a MIB file. If the MIB file(s) * specified on the command-line uses constructs or syntax that are * not supported, an error message will be printed to the standard * output. * * @author Per Cederberg * @version 2.10 * @since 2.0 */ public class MibblePrinter { /** * The command-line help output. */ private static final String COMMAND_HELP = "Prints the contents of an SNMP MIB file. This program comes with\n" + "ABSOLUTELY NO WARRANTY; for details see the LICENSE.txt file.\n" + "\n" + "Syntax: MibblePrinter [--mib|--oid|--debug] <file(s) or URL(s)>\n" + "\n" + " --mib Prints a formatted and indented version of the MIB.\n" + " This is the default printing mode.\n" + " --mibtree Prints a tree of all loaded MIBs, showing every MIB\n" + " import statement\n" + " --oid Prints the complete OID tree, including all nodes\n" + " in imported MIB files\n" + " --debug Prints the MIB contents in debug format, which will\n" + " display all values completely resolved."; /** * The internal error message. */ private static final String INTERNAL_ERROR = "INTERNAL ERROR: An internal error has been found. Please report\n" + " this error to the maintainers (see the web site for\n" + " instructions). Be sure to include the version number, as\n" + " well as the text below:\n"; /** * The MIB pretty printing mode. */ private static final int MIB_PRINT_MODE = 0; /** * The MIB tree printing mode. */ private static final int MIBTREE_PRINT_MODE = 1; /** * The MIB oid tree printing mode. */ private static final int OID_PRINT_MODE = 2; /** * The MIB debug printing mode. */ private static final int DEBUG_PRINT_MODE = 3; /** * The application main entry point. * * @param args the command-line parameters */ public static void main(String[] args) { // Check command-line arguments if (args.length < 1) { printHelp("No MIB file or URL specified"); System.exit(1); } else if (args[0].startsWith("--") && args.length < 2) { printHelp("No MIB file or URL specified"); System.exit(1); } int printMode = MIB_PRINT_MODE; int pos = 0; if (args[0].equals("--mib")) { printMode = MIB_PRINT_MODE; pos++; } else if (args[0].equals("--mibtree")) { printMode = MIBTREE_PRINT_MODE; pos++; } else if (args[0].equals("--oid")) { printMode = OID_PRINT_MODE; pos++; } else if (args[0].equals("--debug")) { printMode = DEBUG_PRINT_MODE; pos++; } else if (args[0].startsWith("--")) { printHelp("No option '" + args[0] + "' exist"); System.exit(1); } // Parse the MIB files MibLoader loader = new MibLoader(); try { for (; pos < args.length; pos++) { URL url = null; try { url = new URL(args[pos]); } catch (MalformedURLException e) { // Ignore error } Mib mib = null; if (url == null) { File file = new File(args[pos]); loader.addDir(file.getParentFile()); mib = loader.load(file); } else { mib = loader.load(url); } if (mib.getLog().warningCount() > 0) { mib.getLog().printTo(System.err); } } } catch (FileNotFoundException e) { printError(args[pos], e); System.exit(1); } catch (IOException e) { printError(args[pos], e); System.exit(1); } catch (MibLoaderException e) { e.getLog().printTo(System.err); System.exit(1); } catch (RuntimeException e) { printInternalError(e); System.exit(1); } // Print loaded MIBs if (printMode == OID_PRINT_MODE) { printOidTree(loader); } else { printMibs(loader, printMode); } } /** * Prints the contents of all MIBs in a MIB loader. * * @param loader the MIB loader * @param printMode the print mode to use */ private static void printMibs(MibLoader loader, int printMode) { for (Mib mib : loader.getAllMibs()) { if (mib.isLoaded()) { if (printMode == MIB_PRINT_MODE) { printMib(mib); } if (printMode == MIBTREE_PRINT_MODE) { printImports(mib, ""); } else { printDebug(mib); } } } } /** * Prints the contents of a single MIB in pretty printing mode. * * @param mib the MIB to print */ private static void printMib(Mib mib) { MibWriter os = new MibWriter(System.out); os.print(mib); System.out.println(); System.out.println(); } /** * Prints the MIB import tree. * * @param mib the MIB to print * @param prefix the indent prefix */ private static void printImports(Mib mib, String prefix) { System.out.print(prefix); System.out.println(mib.getName()); if (prefix.length() >= 4) { boolean isLast = prefix.endsWith(" \u2517\u2501 "); prefix = prefix.substring(0, prefix.length() - 4); prefix += isLast ? " " : " \u2503 "; } Iterator<MibImport> iter = mib.getAllImports().iterator(); while (iter.hasNext()) { MibImport imp = iter.next(); String branch = iter.hasNext() ? " \u2523\u2501 " : " \u2517\u2501 "; printImports(imp.getMib(), prefix + branch); } } /** * Prints the contents of a single MIB in debug mode. * * @param mib the MIB to print */ private static void printDebug(Mib mib) { Iterator<MibSymbol> iter = mib.getAllSymbols().iterator(); while (iter.hasNext()) { System.out.println(iter.next()); System.out.println(); } System.out.println(); System.out.println(); } /** * Prints the complete OID tree. All MIB modules loaded with the * specified MIB loader will be printed. * * @param loader the MIB loader */ private static void printOidTree(MibLoader loader) { if (loader.getAllMibs().length <= 0) { printError("no MIB modules have been loaded"); return; } Mib mib = loader.getAllMibs()[0]; ObjectIdentifierValue root = null; Iterator<MibSymbol> iter = mib.getAllSymbols().iterator(); while (root == null && iter.hasNext()) { MibSymbol symbol = iter.next(); if (symbol instanceof MibValueSymbol) { MibValue value = ((MibValueSymbol) symbol).getValue(); if (value instanceof ObjectIdentifierValue) { root = (ObjectIdentifierValue) value; } } } if (root == null) { printError("no OID value could be found in " + mib.getName()); } else { while (root.getParent() != null) { root = root.getParent(); } printOid(root); } } /** * Prints the detailed OID tree starting in the specified OID. * * @param oid the OID node to print */ private static void printOid(ObjectIdentifierValue oid) { System.out.println(oid.toDetailString()); for (int i = 0; i < oid.getChildCount(); i++) { printOid(oid.getChild(i)); } } /** * Prints command-line help information. * * @param error an optional error message, or null */ private static void printHelp(String error) { System.err.println(COMMAND_HELP); System.err.println(); if (error != null) { printError(error); } } /** * Prints an internal error message. This type of error should * only be reported when run-time exceptions occur, such as null * pointer and the likes. All these error should be reported as * bugs to the program maintainers. * * @param e the exception to be reported */ private static void printInternalError(Exception e) { System.err.println(INTERNAL_ERROR); e.printStackTrace(); } /** * Prints an error message. * * @param message the error message */ private static void printError(String message) { System.err.print("Error: "); System.err.println(message); } /** * Prints a file not found error message. * * @param file the file name not found * @param e the detailed exception */ private static void printError(String file, FileNotFoundException e) { StringBuilder buffer = new StringBuilder(); buffer.append("couldn't open file:\n "); buffer.append(file); printError(buffer.toString()); } /** * Prints a URL not found error message. * * @param url the URL not found * @param e the detailed exception */ private static void printError(String url, IOException e) { StringBuilder buffer = new StringBuilder(); buffer.append("couldn't open URL:\n "); buffer.append(url); printError(buffer.toString()); } }