Package org.jnetpcap.packet

Source Code of org.jnetpcap.packet.JRegistry$Entry

/*
* Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Sly Technologies, Inc.
*
* This file is part of jNetPcap.
*
* jNetPcap is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
package org.jnetpcap.packet;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Formatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.jnetpcap.PcapDLT;
import org.jnetpcap.packet.structure.AnnotatedBinding;
import org.jnetpcap.packet.structure.AnnotatedHeader;
import org.jnetpcap.packet.structure.AnnotatedScannerMethod;
import org.jnetpcap.packet.structure.HeaderDefinitionError;
import org.jnetpcap.protocol.JProtocol;
import org.jnetpcap.util.resolver.Resolver;
import org.jnetpcap.util.resolver.Resolver.ResolverType;

// TODO: Auto-generated Javadoc
/**
* A registry of protocols, their classes, runtime IDs and bindings. This is a
* global registry that all of jnetpcap's packet framework accesses. The
* registry matains tables of bindings, header scanners and numerical IDs for
* each header. The registry also performs various lookup and cross reference
* infomatation such as mapping a header class to a numerical ID.
*
* @author Mark Bednarczyk
* @author Sly Technologies, Inc.
*/
@SuppressWarnings("unchecked")
public final class JRegistry {

  /**
   * A header information entry created for every header registered. Entry class
   * contains various bits and pieces of information about the registred header.
   *
   * @author Mark Bednarczyk
   * @author Sly Technologies, Inc.
   */
  private static class Entry {

    /** The annotated header. */
    private AnnotatedHeader annotatedHeader;

    /** The class name. */
    private final String className;

    /** The clazz. */
    private Class<? extends JHeader> clazz;

    /** The id. */
    private final int id;

    /**
     * Instantiates a new entry.
     *
     * @param id
     *          the id
     * @param c
     *          the c
     */
    public Entry(int id, Class<? extends JHeader> c) {
      this.id = id;
      this.clazz = c;
      this.className = c.getName();
    }

    /**
     * Instantiates a new entry.
     *
     * @param id
     *          the id
     * @param className
     *          the class name
     */
    public Entry(int id, String className) {
      this.id = id;
      this.className = className;
    }

    /**
     * Gets the header class.
     *
     * @return the header class
     */
    public Class<? extends JHeader> getHeaderClass() {
      if (clazz == null) {
        try {
          return (Class<? extends JHeader>) Class.forName(className);
        } catch (ClassNotFoundException e) {
          throw new IllegalStateException(e);
        }
      } else {
        return this.clazz;
      }
    }
  }

  /**
   * A private duplicate constant for MAX_ID_COUNT who's name is prefixed with
   * A_ so that due to source code sorting, we don't get compiler errors. Made
   * private so no one outside this class knows about it. Got tired of having to
   * move MAX_ID_COUNT definition around after each source sort.
   */
  private final static int A_MAX_ID_COUNT = 64;

  /** Number of core protocols defined by jNetPcap. */
  public static final int CORE_ID_COUNT = JProtocol.values().length;

  /** The Constant DLTS_TO_IDS. */
  private final static int[] DLTS_TO_IDS;

  /** The errors. */
  private static List<HeaderDefinitionError> errors =
      new ArrayList<HeaderDefinitionError>();

  /**
   * A flag that allows tells that a java scanner's process bindings method has
   * been overriden.
   */
  public final static int FLAG_HEURISTIC_BINDING = 0x00000010;

  /**
   * A flag that allows tells that a java scanner's process bindings method has
   * been overriden.
   */
  public final static int FLAG_HEURISTIC_PRE_BINDING = 0x00000020;

  /**
   * A flag that allows tells that a java scanner's process bindings method has
   * been overriden.
   */
  public final static int FLAG_OVERRIDE_BINDING = 0x00000002;

  /**
   * A flag that allows tells that a java scanner's get length method has been
   * overriden.
   */
  public final static int FLAG_OVERRIDE_LENGTH = 0x00000001;

  /** The Constant headerFlags. */
  private final static int headerFlags[] = new int[A_MAX_ID_COUNT];

  /** The Constant IDS_TO_DLTS. */
  private final static int[] IDS_TO_DLTS;

  /** The LAS t_ id. */
  private static int LAST_ID = JProtocol.values().length;

  /** The Constant MAP_BY_ID. */
  private final static Entry[] MAP_BY_ID = new Entry[A_MAX_ID_COUNT];

  /** Holds class to ID mapping - this is global accross all registries. */
  private static Map<String, Entry> mapByClassName =
      new HashMap<String, Entry>();

  /** The map subs by class name. */
  private static Map<String, AnnotatedHeader> mapSubsByClassName =
      new HashMap<String, AnnotatedHeader>(50);

  /** The Constant MAX_DLT_COUNT. */
  private static final int MAX_DLT_COUNT = 512;

  /**
   * Maximum number of protocol header entries allowed by this implementation of
   * JRegistry.
   */
  public final static int MAX_ID_COUNT = 64;

  /**
   * A constant if returned from {@link #mapDLTToId} or {@link #mapIdToDLT} that
   * no mapping exists.
   */
  public static final int NO_DLT_MAPPING = -1;

  /**
   * Allow any type of key to be used so that users can register their own
   * unknown type resolvers.
   */
  private final static Map<Object, Resolver> resolvers =
      new HashMap<Object, Resolver>();

  /**
   * Header scanners for each header type and protocol. The user can override
   * native direct scanners by supplying a java based scanner that will override
   * a particular protocols entry.
   */
  private final static JHeaderScanner[] scanners =
      new JHeaderScanner[A_MAX_ID_COUNT];

  /**
   * Initialize JRegistry with defaults
   * <ul>
   * <li>libpcap DLT mappings</li>
   * <li>Register CORE protocols</li>
   * <li>Register address resolvers</li>
   * </ul>
   */
  static {
    /**
     * Initialized DLT to ID mappings
     */
    DLTS_TO_IDS = new int[MAX_DLT_COUNT];
    IDS_TO_DLTS = new int[MAX_ID_COUNT];

    Arrays.fill(JRegistry.DLTS_TO_IDS, -1);
    Arrays.fill(JRegistry.IDS_TO_DLTS, -1);

    /**
     * Register CORE protocols
     */
    for (JProtocol p : JProtocol.values()) {

      try {
        register(p);
      } catch (Exception e) {
        System.err.println("JRegistry Error: " + e.getMessage());
        e.printStackTrace();

        System.exit(0);
      }
    }

    /**
     * Bind CORE protocols. Most bindings are provided by the native scanner but
     * some protocols may have java bindings as well that need to be registered.
     * They are by default registered in addition to the native bindings.
     */
    for (JProtocol p : JProtocol.values()) {

      try {
        JBinding[] bindings =
            AnnotatedBinding.inspectJHeaderClass(p.getHeaderClass(), errors);
        if (bindings != null && bindings.length != 0) {
          addBindings(bindings);
        }
      } catch (Exception e) {
        System.err.println("JRegistry Error: " + e.getMessage());
        e.printStackTrace();

        System.exit(0);
      }
    }

    /**
     * Register default resolvers for address to name mappings
     */
    for (ResolverType t : ResolverType.values()) {
      if (t.getResolver() != null) {
        try {
          registerResolver(t, t.getResolver());
        } catch (Exception e) {
          System.err.println("JRegistry Error: " + e.getMessage());
          e.printStackTrace();

          System.exit(0);
        }
      }
    }

    /**
     * Enable heuristics by default for TCP and UDP protocols
     */
    setFlags(JProtocol.TCP_ID, FLAG_HEURISTIC_BINDING);
    setFlags(JProtocol.UDP_ID, FLAG_HEURISTIC_BINDING);

  }

  /**
   * Adds bindings found in the container class. Any static methods that have
   * the <code>Bind</code> annotation defined will be extracted and wrapped as
   * <code>JBinding</code> interface objects, suitable to be registered with for
   * a target header. Bindings contained in any class that does not extend
   * <code>JHeader</code> is required to provide both "to" and "from" parameters
   * to <code>Bind</code> annotation.
   *
   * @param container
   *          container that has static bind methods
   */
  public static void addBindings(Class<?> container) {
    clearErrors();

    if (JHeader.class.isAssignableFrom(container)) {
      addBindings(AnnotatedBinding
          .inspectJHeaderClass((Class<? extends JHeader>) container, errors));

    } else {
      addBindings(AnnotatedBinding.inspectClass(container, errors));
    }
  }

  /**
   * Adds additional bindings to a particular protocol.
   *
   * @param bindings
   *          the bindings
   */
  public static void addBindings(JBinding... bindings) {

    for (JBinding b : bindings) {
      scanners[b.getTargetId()].addBindings(b);
    }

  }

  /**
   * Adds all of the bindings found in the bindinsContainer object supplied. The
   * methods that have the <code>Bind</code> annotation, will be extracted and
   * converted to JBinding objects that will call on those methods as a binding.
   * The "this" pointer in the instance methods will be set to null, therefore
   * do not rely on any super methods and "this" operator. The bind annotation
   * inspector check and ensure that only "Object" class is extended for the
   * container class.
   *
   * @param bindingContainer
   *          container object that contains binding instance methods
   */
  public static void addBindings(Object bindingContainer) {
    if (bindingContainer instanceof JBinding) {
      addBindings(new JBinding[] { (JBinding) bindingContainer
      });
      return;
    }

    clearErrors();
    addBindings(AnnotatedBinding.inspectObject(bindingContainer, errors));
  }

  /**
   * Clears any existing registery errors.
   */
  public static void clearErrors() {
    errors.clear();
  }

  /**
   * Clears the supplied bits within the flag's bitmap.
   *
   * @param id
   *          protocol ID
   * @param flags
   *          flags to clear
   */
  public static void clearFlags(int id, int flags) {
    headerFlags[id] &= ~flags;
  }

  /**
   * Clears java scanners for supplied list of headers.
   *
   * @param classes
   *          classes of all the headers that java scanner will be cleared if
   *          previously registered
   */
  public static void clearScanners(Class<? extends JHeader>... classes) {
    for (Class<? extends JHeader> c : classes) {
      int id = lookupId(c);

      scanners[id].setScannerMethod(null);
    }
  }

  /**
   * Clears java scanners for supplied list of headers.
   *
   * @param ids
   *          ids of all the headers that java scanner will be cleared if
   *          previously registered
   */
  public static void clearScanners(int... ids) {
    for (int id : ids) {
      scanners[id].setScannerMethod(null);
    }
  }

  /**
   * Removes previously registered scanners that are defined in the supplied
   * object container. Any scanners within the supplied container are retrieved
   * and all the currently registered java scanner for the headers that the
   * retrieved scanners target, are cleared.
   *
   * @param container
   *          container object containing scanner methods which target headers
   *          that will be cleared of java scanners
   */
  public static void clearScanners(Object container) {
    AnnotatedScannerMethod[] methods =
        AnnotatedScannerMethod.inspectObject(container);

    int[] ids = new int[methods.length];

    for (int i = 0; i < ids.length; i++) {
      ids[i] = methods[i].getId();
    }

    clearScanners(ids);
  }

  /**
   * Creates a new header entry for storing information about a header.
   *
   * @param c
   *          header class
   * @return newly created entry
   */
  private static Entry createNewEntry(Class<? extends JHeader> c) {
    int id = LAST_ID;
    Entry e;
    mapByClassName.put(c.getCanonicalName(), e = new Entry(id, c));
    MAP_BY_ID[id] = e;

    LAST_ID++;

    return e;
  }

  /**
   * Retrieves all current bindings bound to a protocol.
   *
   * @param id
   *          protocol id
   * @return array of bindings for this protocol
   */
  public static JBinding[] getBindings(int id) {
    return scanners[id].getBindings();
  }

  /**
   * Retrieves the recent errors that were generated by registry operations.
   *
   * @return array of errors
   */
  public static HeaderDefinitionError[] getErrors() {
    return errors.toArray(new HeaderDefinitionError[errors.size()]);
  }

  /**
   * Gets the current flags for a specified protocol.
   *
   * @param id
   *          numerical id of the protocol header
   * @return current flags as a bit mask
   */
  public static int getFlags(int id) {
    return headerFlags[id];
  }

  /**
   * Retrives all the flags for all of the protocols.
   *
   * @return array of flags, one element for each protocol
   */
  public static int[] getAllFlags() {
    final int[] copy = new int[headerFlags.length];
    System.arraycopy(headerFlags, 0, copy, 0, copy.length);
    return copy;
  }

  /**
   * Sets all flags to the values in the array supplied. Flags are copied, into
   * the JRegistry flags database.
   *
   * @param flags
   *          flags to be copied.
   */
  public static void setAllFlags(int[] flags) {
    System.arraycopy(flags, 0, headerFlags, 0, flags.length);
  }

  /**
   * Retrieves the entire list of scanners for all registered protocols.
   *
   * @return array of header scanners
   */
  public static JHeaderScanner[] getHeaderScanners() {
    JHeaderScanner[] s = new JHeaderScanner[MAX_ID_COUNT];
    System.arraycopy(scanners, 0, s, 0, MAX_ID_COUNT);

    return s;
  }

  /**
   * Retrieves a registered instance of any resolver.
   *
   * @param customType
   *          resolver type
   * @return currently registered resolver
   */
  public static Resolver getResolver(Object customType) {
    Resolver resolver = resolvers.get(customType);

    resolver.initializeIfNeeded();

    return resolver;
  }

  /**
   * Retrieves a registered instance of a resolver.
   *
   * @param type
   *          resolver type
   * @return currently registered resolver
   */
  public static Resolver getResolver(ResolverType type) {
    return getResolver((Object) type);
  }

  /**
   * Checks if a mapping for libpcap dlt value is defined.
   *
   * @param dlt
   *          value to check for
   * @return true if dlt mapping exists, otherwise false
   */
  public static boolean hasDltMapping(int dlt) {
    return dlt >= 0 && dlt < DLTS_TO_IDS.length
        && DLTS_TO_IDS[dlt] != NO_DLT_MAPPING;
  }

  /**
   * Checks if there are any registry errors that were recently generated.
   *
   * @return true if error queue is not empty
   */
  public static boolean hasErrors() {
    return errors.isEmpty();
  }

  /**
   * Checks if resolver of specific type is currently registered.
   *
   * @param type
   *          type of resolver to check for
   * @return true if resolver is registered, otherwise false
   */
  public static boolean hasResolver(Object type) {
    return resolvers.containsKey(type);
  }

  /**
   * Checks if resolver of specific type is currently registered.
   *
   * @param type
   *          type of resolver to check for
   * @return true if resolver is registered, otherwise false
   */
  public static boolean hasResolver(ResolverType type) {
    return resolvers.containsKey(type);
  }

  /**
   * Inspect.
   *
   * @param c
   *          the c
   * @param errors
   *          the errors
   * @return the annotated header
   */
  public static AnnotatedHeader inspect(Class<? extends JHeader> c,
      List<HeaderDefinitionError> errors) {

    return AnnotatedHeader.inspectJHeaderClass(c, errors);
  }

  /**
   * Returns a complete list of currently active resolvers types.
   *
   * @return the object[]
   */
  public static Object[] listResolvers() {
    return resolvers.keySet().toArray(new Object[resolvers.size()]);
  }

  /**
   * Lookup annotated header.
   *
   * @param c
   *          the c
   * @return the annotated header
   * @throws UnregisteredHeaderException
   *           the unregistered header exception
   */
  public static AnnotatedHeader lookupAnnotatedHeader(Class<? extends JHeader> c)
      throws UnregisteredHeaderException {

    if (JSubHeader.class.isAssignableFrom(c)) {
      return lookupAnnotatedSubHeader((Class<? extends JSubHeader<? extends JSubHeader<?>>>) c);
    }

    return lookupAnnotatedHeader(lookupIdNoCreate(c));
  }

  /**
   * Lookup annotated header.
   *
   * @param id
   *          the id
   * @return the annotated header
   * @throws UnregisteredHeaderException
   *           the unregistered header exception
   */
  public static AnnotatedHeader lookupAnnotatedHeader(int id)
      throws UnregisteredHeaderException {
    if (MAP_BY_ID[id] == null || MAP_BY_ID[id].annotatedHeader == null) {
      throw new UnregisteredHeaderException("header [" + id
          + "] not registered");
    }

    return MAP_BY_ID[id].annotatedHeader;
  }

  /**
   * Lookup annotated header.
   *
   * @param protocol
   *          the protocol
   * @return the annotated header
   */
  public static AnnotatedHeader lookupAnnotatedHeader(JProtocol protocol) {
    Class<? extends JHeader> c = protocol.getHeaderClass();
    Entry e = MAP_BY_ID[protocol.getId()];

    if (e.annotatedHeader == null) {
      errors.clear();
      e.annotatedHeader = inspect(c, errors);

      registerAnnotatedSubHeaders(e.annotatedHeader.getHeaders());
    }

    return e.annotatedHeader;
  }

  /**
   * Lookup annotated sub header.
   *
   * @param c
   *          the c
   * @return the annotated header
   */
  static AnnotatedHeader lookupAnnotatedSubHeader(Class<? extends JSubHeader<? extends JSubHeader<?>>> c) {
    if (mapSubsByClassName.containsKey(c.getCanonicalName()) == false) {
      throw new UnregisteredHeaderException("sub header [" + c.getName()
          + "] not registered, most likely parent not registered as well");
    }

    return mapSubsByClassName.get(c.getCanonicalName());
  }

  /**
   * Looks up the class of a header based on its ID.
   *
   * @param id
   *          protocol id
   * @return class for this protocol
   * @throws UnregisteredHeaderException
   *           thrown if protocol not found, invalid ID
   */
  public static Class<? extends JHeader> lookupClass(int id)
      throws UnregisteredHeaderException {

    if (id > LAST_ID) {
      throw new UnregisteredHeaderException("invalid id " + id);
    }

    final Entry entry = MAP_BY_ID[id];

    if (entry == null) {
      throw new UnregisteredHeaderException("invalid id " + id);
    }

    return entry.getHeaderClass();
  }

  /**
   * Look's up the protocol header ID using a class name.
   *
   * @param c
   *          class of the header
   * @return numerical ID of the protocol header
   */
  public static int lookupId(Class<? extends JHeader> c) {

    if (JSubHeader.class.isAssignableFrom(c)) {
      AnnotatedHeader header =
          lookupAnnotatedSubHeader((Class<? extends JSubHeader<? extends JSubHeader<?>>>) c);

      return header.getId();
    }

    Entry e = mapByClassName.get(c.getCanonicalName());
    if (e == null) {
      e = createNewEntry(c);
    }

    return e.id;
  }

  /**
   * Look's up the protocol header ID using a protocol constant. This method
   * does not throw any exception since all core protocols defined on Jprotocol
   * table are guarrantted to be registered.
   *
   * @param p
   *          protocol constant
   * @return numerical ID of the protocol header
   */
  public static int lookupId(JProtocol p) {
    return p.getId();
  }

  /**
   * Lookup id no create.
   *
   * @param c
   *          the c
   * @return the int
   * @throws UnregisteredHeaderException
   *           the unregistered header exception
   */
  private static int lookupIdNoCreate(Class<? extends JHeader> c)
      throws UnregisteredHeaderException {
    if (mapByClassName.containsKey(c.getCanonicalName()) == false) {
      throw new UnregisteredHeaderException("header [" + c.getName()
          + "] not registered");
    }

    return mapByClassName.get(c.getCanonicalName()).id;
  }

  /**
   * Looks up a header scanner.
   *
   * @param id
   *          id of the scanner to lookup
   * @return header scanner for this ID
   */
  public static JHeaderScanner lookupScanner(int id) {
    return scanners[id];
  }

  /**
   * Map dlt to id.
   *
   * @param dlt
   *          the dlt
   * @return the int
   */
  public static int mapDLTToId(int dlt) {
    return DLTS_TO_IDS[dlt];
  }

  /**
   * Map id to dlt.
   *
   * @param id
   *          the id
   * @return the int
   */
  public static int mapIdToDLT(int id) {
    return IDS_TO_DLTS[id];
  }

  /**
   * Map id to pcap dlt.
   *
   * @param id
   *          the id
   * @return the pcap dlt
   */
  public static PcapDLT mapIdToPcapDLT(int id) {
    return PcapDLT.valueOf(IDS_TO_DLTS[id]);
  }

  /**
   * Register.
   *
   * @param c
   *          the c
   * @return the int
   * @throws RegistryHeaderErrors
   *           the registry header errors
   */
  public static int register(Class<? extends JHeader> c)
      throws RegistryHeaderErrors {

    List<HeaderDefinitionError> errors = new ArrayList<HeaderDefinitionError>();

    int id = register(c, errors);

    if (errors.isEmpty() == false) {
      throw new RegistryHeaderErrors(c, errors, "while trying to register "
          + c.getSimpleName() + " class");
    }

    return id;
  }

  /**
   * Registeres a new protocol header. A new numerical ID is assigned to the
   * protocol and various mappings are recorded for this protocol.
   *
   * @param c
   *          class of the header
   * @param errors
   *          the errors
   * @return numerical id assigned to this new protocol
   */
  public static int register(Class<? extends JHeader> c,
      List<HeaderDefinitionError> errors) {

    AnnotatedHeader annotatedHeader = inspect(c, errors);
    if (errors.isEmpty() == false) {
      return -1;
    }

    Entry e = mapByClassName.get(c.getCanonicalName());
    if (e == null) {
      e = createNewEntry(c);
    }

    int id = e.id;
    e.annotatedHeader = annotatedHeader;

    scanners[id] = new JHeaderScanner(c);

    registerAnnotatedSubHeaders(annotatedHeader.getHeaders());

    JBinding[] bindings = AnnotatedBinding.inspectJHeaderClass(c, errors);
    if (errors.isEmpty() == false) {
      return -1;
    }
    addBindings(bindings);

    for (PcapDLT d : annotatedHeader.getDlt()) {
      registerDLT(d, id);
    }

    return id;
  }

  /**
   * Registeres the core protocols. Not user accessible as this is done by
   * default for all core protocols.
   *
   * @param protocol
   *          core protocol
   * @return id of the core protocol, should be the same as ID pre-assigned in
   *         JProtocol table
   */
  static int register(JProtocol protocol) {

    Entry e = new Entry(protocol.getId(), protocol.getHeaderClassName());
    mapByClassName.put(protocol.getHeaderClassName(), e);
    MAP_BY_ID[protocol.getId()] = e;

    try {
      scanners[protocol.getId()] = new JHeaderScanner(protocol);
    } catch (UnregisteredHeaderException ex) {
      register(protocol.getClazz(), errors);
    }

    for (PcapDLT d : protocol.getDlt()) {
      registerDLT(d, protocol.getId());
    }

    return protocol.getId();
  }

  /**
   * Register annotated sub headers.
   *
   * @param subs
   *          the subs
   */
  private static void registerAnnotatedSubHeaders(AnnotatedHeader[] subs) {
    for (AnnotatedHeader c : subs) {
      mapSubsByClassName.put(c.getHeaderClass().getCanonicalName(), c);

      registerAnnotatedSubHeaders(c.getHeaders());
    }
  }

  /**
   * Register dlt.
   *
   * @param dlt
   *          the dlt
   * @param id
   *          the id
   */
  public static void registerDLT(int dlt, int id) {
    DLTS_TO_IDS[dlt] = id;
    IDS_TO_DLTS[id] = dlt;
  }

  /**
   * Register dlt.
   *
   * @param dlt
   *          the dlt
   * @param id
   *          the id
   */
  public static void registerDLT(PcapDLT dlt, int id) {
    registerDLT(dlt.getValue(), id);
  }

  /**
   * Registers a new resolver of any type, replacing the previous resolver.
   *
   * @param customType
   *          type of resolver to replace
   * @param custom
   *          new resolver to register
   */
  public static void registerResolver(Object customType, Resolver custom) {
    resolvers.put(customType, custom);
  }

  /**
   * Registers a new resolver of specific type, replacing the previous resolver.
   *
   * @param type
   *          type of resolver to replace
   * @param custom
   *          new resolver to register
   */
  public static void registerResolver(ResolverType type, Resolver custom) {
    resolvers.put(type, custom);
  }

  /**
   * Clears any existing java bindings for the specified protocol.
   *
   * @param id
   *          numerical id of the protocol header
   */
  public static void resetBindings(int id) {
    scanners[id].clearBindings();
  }

  /**
   * Sets the current flag for a specified protocol.
   *
   * @param id
   *          numerical id of the protocol header
   * @param flags
   *          flags to set (bitwise OR) with the existing flags
   */
  public static void setFlags(int id, int flags) {
    headerFlags[id] |= flags;
  }

  /**
   * Sets the header scanners for each header type and protocol.
   *
   * @param scanners
   *          the new header scanners for each header type and protocol
   */
  public static void setScanners(AnnotatedScannerMethod... scanners) {
    for (AnnotatedScannerMethod m : scanners) {
      JHeaderScanner scanner = JRegistry.scanners[m.getId()];

      scanner.setScannerMethod(m);
    }
  }

  /**
   * Sets the header scanners for each header type and protocol.
   *
   * @param c
   *          the new header scanners for each header type and protocol
   */
  public static void setScanners(Class<?> c) {
    if (JHeader.class.isAssignableFrom(c)) {
      setScanners(AnnotatedScannerMethod
          .inspectJHeaderClass((Class<? extends JHeader>) c));
    } else {
      setScanners(AnnotatedScannerMethod
          .inspectClass((Class<? extends JHeader>) c));
    }
  }

  /**
   * Sets the header scanners for each header type and protocol.
   *
   * @param container
   *          the new header scanners for each header type and protocol
   */
  public static void setScanners(Object container) {
    AnnotatedScannerMethod[] methods =
        AnnotatedScannerMethod.inspectObject(container);

    setScanners(methods);
  }

  /**
   * Prepares the registry for shutdown. The registry will save caches and
   * release resources other that may be held.
   *
   * @throws IOException
   *           Signals that an I/O exception has occurred.
   */
  public static void shutdown() throws IOException {
    for (Resolver resolver : resolvers.values()) {
      if (resolver != null) {
        resolver.saveCache();
      }
    }

    resolvers.clear();
  }

  /**
   * Dumps various tables JRegistry maintains as debug information.
   *
   * @return multi-line string containing various debug information about
   *         JRegistry
   */
  public static String toDebugString() {
    Formatter out = new Formatter();

    try {
      /*
       * Dump scanners and their configs
       */
      for (int i = 0; i < A_MAX_ID_COUNT; i++) {
        if (scanners[i] != null) {
          out.format("scanner[%-2d] class=%-15s %s\n", i, lookupClass(i)
              .getSimpleName(), scanners[i].toString());
        }
      }

      /*
       * Dump existing DLT to ID mappings
       */
      for (int i = 0; i < MAX_DLT_COUNT; i++) {
        if (hasDltMapping(i)) {
          int id = mapDLTToId(i);
          Class<?> c = lookupClass(id);

          out.format("libpcap::%-24s => header::%s.class(%d)\n", PcapDLT
              .valueOf(i).toString() + "(" + i + ")", c.getSimpleName(), id);
        }
      }
    } catch (UnregisteredHeaderException e) {
      throw new IllegalStateException(e);
    }

    for (Object k : resolvers.keySet()) {
      Resolver r = resolvers.get(k);
      r.initializeIfNeeded();
      out.format("Resolver %s: %s\n", String.valueOf(k), r.toString());
    }

    return out.toString();
  }

  /**
   * Instantiates a new j registry.
   */
  private JRegistry() {
    // Can't instantiate
  }
}
TOP

Related Classes of org.jnetpcap.packet.JRegistry$Entry

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.