/** * Route.java */ package SSF.OS.BGP4; import java.io.*; import java.util.*; import SSF.OS.BGP4.Comm.*; import SSF.OS.BGP4.Path.*; import SSF.OS.BGP4.Util.*; // ===== class SSF.OS.BGP4.Route =========================================== // /** * Information describing a single route. A route is described as a unit of * information that pairs a destination with the attributes of a path to that * destination. In other words, route = destination + path attributes. */ public class Route implements Externalizable { // ......................... constants ........................... // /** For undefined string values. */ public static final String undefined = "undefined"; /** The DML string names of route attributes other than path attributes. */ public static final String[] attrib_dmlnames = { undefined, "nlri_ip" }; /** The NHI versions of the DML string names of route attributes other than * path attributes. */ public static final String[] attrib_nhidmlnames = { undefined, "nlri_nhi" }; /** The maximum route attribute type code for non- path attributes. */ public static final int MAX_TYPECODE = -1; /** The minimum route attribute type code for non- path attributes. */ public static final int MIN_TYPECODE = -1; /** A route attribute "type code" value for NLRI. It is negative since the * type codes for path attributes are all positive. */ public static final int NLRI_TYPECODE = -1; /** An array of short integers of size zero. Used to initialize AS paths * when the Global.flat_aspaths option is in use. */ private static final short[] emptyShortArray = new short[0]; // ........................ member data .......................... // /** The destination of the route. This is actually just an IP address * prefix, so it may represent a specific host, subnet, AS, or perhaps an * even larger (possibly geographical) portion of the network. */ public IPaddress nlri; /** An array of path attributes which describe the path to the destination. * This information is received via update messages. */ public Attribute[] pas; /** If using the Global.flat_aspaths AS path optimization, this array of * short integers will be used instead of an ASpath object in the 'pas' * Attribute array. */ public short[] aspath = null; /** If using the Global.linked_aspaths AS path optimization, this is the * first AS in the AS path. */ public short as1 = 0; /** If using the Global.linked_aspaths AS path optimization, this is a link * to the route which holds the next AS in the AS path. */ public Route next_rte = null; /** The NextHop attribute when using the Global.basic_attribs * optimization. */ private IPaddress nexthop = null; /** The LocalPref attribute when using the Global.basic_attribs * optimization. */ private short localpref = -1; ////selma //If using the Global.flat_aspaths AS path optimization public Vector history=null; ///// ////selma public boolean epsilon=false; ///// // ----- Route() --------------------------------------------------------- // /** * Default initializer. */ public Route() { if (!Global.basic_attribs) { // We initialize the array so that we can index it by attribute type // code. It's easier than having an unordered array and having to search // through it each and every time when looking for a particular // attribute. This way is less space-efficient, but more time-efficient. pas = new Attribute[Attribute.MAX_TYPECODE+1]; } // All mandatory attributes should be set immediately after a route is // constructed. Here we initialize the AS path only, because an empty AS // path can be valid for routes originated by the local BGP speaker. if (Global.flat_aspaths) { aspath = emptyShortArray; ////selma history=new Vector(); //// } else if (Global.linked_aspaths) { // do nothing } else { pas[ASpath.TYPECODE] = new ASpath(new ArrayList()); ////selma pas[History.TYPECODE]=new History(); ///// } } // ----- constructor Route(Route) ---------------------------------------- // /** * Constructs a new route based on an existing one. * * @param rte The existing route on which to base the new one. */ public Route(Route rte) { nlri = new IPaddress(rte.nlri); epsilon=rte.epsilon; //selma if (Global.basic_attribs) { nexthop = rte.nexthop; localpref = rte.localpref; } else { pas = copy_attribs(rte.pas); } if (Global.flat_aspaths) { aspath = new short[rte.aspath.length]; for (int i=0; i 0); } else if (Global.linked_aspaths) { return (as1 != 0); } else { return (pas[ASpath.TYPECODE] != null); } } // ----- aspath_length --------------------------------------------------- // /** * Returns the number of ASes in the AS path attribute. * * @return the number of ASes in the AS path attribute */ public final int aspath_length() { if (Global.flat_aspaths) { return aspath.length; } else if (Global.linked_aspaths) { if (!has_aspath()) { return 0; } int len = 0; Route nextrte = this; while (nextrte != null) { if (nextrte.has_aspath()) { len++; nextrte = nextrte.next_rte; } else { nextrte = null; } } return len; } else { ASpath asp = (ASpath)pas[ASpath.TYPECODE]; if (asp == null) { return 0; } int sz = 0; for (int i=0; i 255) { // 1 or 2 octets for the attribute length field octets += 2; } else { octets++; } return octets; } // ----- nexthop_bytecount ----------------------------------------------- // /** * Returns the number of octets (bytes) needed to represent this next hop * path attribute in an update message. The number is the sum of the two * octets needed for the attribute type (which contains attribute flags and * the attribute type code), the one octets needed for the attribute length, * and the four octets needed for the attribute value. * * @return the number of octets (bytes) needed to represent this next hop * path attribute in an update message */ public int nexthop_bytecount() { if (nexthop != null) { return 7; } else { return 0; } } // ----- localpref_bytecount --------------------------------------------- // /** * Returns the number of octets (bytes) needed to represent this local * preference path attribute in an update message. The number is the sum of * the two octets needed for the attribute type (which contains attribute * flags and the attribute type code), the one octet needed for the attribute * length, and the four octets needed for the attribute value. * * @return the number of octets (bytes) needed to represent this local * preference discriminator path attribute in an update message */ public int localpref_bytecount() { if (localpref != -1) { return 7; } else { return 0; } } // ----- aspath_toMinString() -------------------------------------------- // /** * Returns the AS path as a string, leaving out set/sequence information. * * @return the AS path as a string, without set/sequence info */ public final String aspath_toMinString() { return aspath_toMinString(' ',false); } // ----- aspath_toMinString(char,boolean) -------------------------------- // /** * Returns the AS path as a string, leaving out set/sequence information. * * @param sepchar The character used to separate AS numbers in the list. * @param usenhi Whether or not to show AS numbers as NHI address prefixes. * @return the AS path as a string, without set/sequence info */ public final String aspath_toMinString(char sepchar, boolean usenhi) { if (epsilon) return "epsilon"; if (!Global.flat_aspaths && !Global.linked_aspaths) { return ((ASpath)pas[ASpath.TYPECODE]).toMinString(sepchar,usenhi); } if (Global.flat_aspaths) { String str = ""; for (int i=0; i