All Downloads are FREE. Search and download functionalities are using the official Maven repository.

es.tid.bgp.bgp4.messages.BGP4Update Maven / Gradle / Ivy

The newest version!
package es.tid.bgp.bgp4.messages;

import es.tid.bgp.bgp4.update.fields.*;
import es.tid.bgp.bgp4.update.fields.pathAttributes.*;

import java.util.ArrayList;

/**
 * 

BGP4 Update Message (RFC 4271).

*

From RFC 4271 Section 4.3.

* RFC 4271. * 4.3. UPDATE Message Format *

* UPDATE messages are used to transfer routing information between BGP * peers. The information in the UPDATE message can be used to * construct a graph that describes the relationships of the various * Autonomous Systems. By applying rules to be discussed, routing * information loops and some other anomalies may be detected and * removed from inter-AS routing. *

* An UPDATE message is used to advertise feasible routes that share * common path attributes to a peer, or to withdraw multiple unfeasible * routes from service (see 3.1). An UPDATE message MAY simultaneously * advertise a feasible route and withdraw multiple unfeasible routes * from service. The UPDATE message always includes the fixed-size BGP * header, and also includes the other fields, as shown below (note, * some of the shown fields may not be present in every UPDATE message): *

 * +-----------------------------------------------------+
 * |   Withdrawn Routes Length (2 octets)                |
 * +-----------------------------------------------------+
 * |   Withdrawn Routes (variable)                       |
 * +-----------------------------------------------------+
 * |   Total Path Attribute Length (2 octets)            |
 * +-----------------------------------------------------+
 * |   Path Attributes (variable)                        |
 * +-----------------------------------------------------+
 * |   Network Layer Reachability Information (variable) |
 * +-----------------------------------------------------+
 * 
* * @author mcs, pac */ public class BGP4Update extends BGP4Message { /** * Used to check the origin of update message */ private String learntFrom; /** * Total length of the Withdrawn Routes field in octets. */ //private int withdrawnRoutesLength; /** * List of IP address prefixes for the routes that are being withdrawn from service. */ private WithdrawnRoutes withdrawnRoutes; /** * Total length of the Path Attributes field in octets */ //private int totalPathAttibuteLength; /** * List of path attributes */ private ArrayList pathAttributes; /** * Network Layer Reachability Information */ private NLRI nlri; /** * Construct for encoding */ public BGP4Update() { super(); this.setMessageType(BGP4MessageTypes.MESSAGE_UPDATE); pathAttributes = new ArrayList(); } /** * Construct for decoding * * @param bytes bytes of the message */ public BGP4Update(byte[] bytes) { super(bytes); this.messageBytes = new byte[bytes.length]; System.arraycopy(bytes, 0, this.messageBytes, 0, bytes.length); decode(); } /** * Encode BGP4 Update message */ public void encode() { //Encode BGP4 Update if((withdrawnRoutes == null) && (pathAttributes.size() == 0)) log.warn("There should be withdrawnRoutes or path Attributes"); int withdrawnRoutesLength=0; if(withdrawnRoutes == null) withdrawnRoutesLength = 0; int len = BGPHeaderLength; //Add 4 octects for the lengths len = len + 4; //withdrawnRoutesLength + totalPathAttibuteLength if(withdrawnRoutes != null) { withdrawnRoutes.encode(); len = len + withdrawnRoutes.getLength(); withdrawnRoutesLength = withdrawnRoutes.getLength(); } int totalPathAttibuteLength = 0; for(int i = 0; i < pathAttributes.size(); ++ i) { pathAttributes.get(i).encode(); len = len + pathAttributes.get(i).getLength(); totalPathAttibuteLength = totalPathAttibuteLength + pathAttributes.get(i).getLength(); } if(nlri != null) { //NLRI encoding nlri.encode(); len = len + nlri.getLength(); } this.setMessageLength(len); messageBytes = new byte[len]; encodeHeader(); int offset = BGPHeaderLength; //Add withdrawnRoutesLength this.messageBytes[offset] = (byte) (withdrawnRoutesLength >>> 8 & 0xFF); this.messageBytes[offset + 1] = (byte) (withdrawnRoutesLength & 0xFF); offset = offset + 2; //Add withdrawnRoutes if(withdrawnRoutes != null) { System.arraycopy(withdrawnRoutes.getBytes(), 0, messageBytes, offset, withdrawnRoutes.getLength()); offset = offset + withdrawnRoutes.getLength(); } //Add totalPathAttibuteLength this.messageBytes[offset] = (byte) (totalPathAttibuteLength >>> 8 & 0xFF); this.messageBytes[offset + 1] = (byte) (totalPathAttibuteLength & 0xFF); offset = offset + 2; //Add Path Attributes for(int i = 0; i < pathAttributes.size(); ++ i) { System.arraycopy(pathAttributes.get(i).getBytes(), 0, messageBytes, offset, pathAttributes.get(i).getLength()); offset = offset + pathAttributes.get(i).getLength(); } //Add NLRI if(nlri != null) { System.arraycopy(nlri.getBytes(), 0, messageBytes, offset, nlri.getBytes().length); offset = offset + nlri.getLength(); } } public void decode() { int offset = BGPHeaderLength; //Withdrawn Routes length int withdrawnRoutesLength = ((((int) messageBytes[offset]) << 8) & 0xFF00) | ((int) messageBytes[offset + 1] & 0xFF); offset = offset + 2; //Withdrawn Routes if(withdrawnRoutesLength != 0) { //Decodificar withdrawnRoutes log.warn("withdrawnRoutesLength not implemented"); offset = offset + withdrawnRoutesLength; } else { withdrawnRoutes =null; } //Path Attributes Length int totalPathAttibuteLength = ((((int) messageBytes[offset]) << 8) & 0xFF00) | ((int) messageBytes[offset + 1] & 0xFF); offset = offset + 2; if(totalPathAttibuteLength != 0) { pathAttributes = new ArrayList(); int len = 0; int attribute_typeCode; int attribute_length; int mandatory_length; while(len < totalPathAttibuteLength) { //Path Attributes attribute_typeCode = PathAttribute.getAttibuteTypeCode(messageBytes, offset); attribute_length = PathAttribute.getAttributeLength(messageBytes, offset); mandatory_length = PathAttribute.getMandatoryLength(messageBytes, offset); if(attribute_typeCode == PathAttributesTypeCode.PATH_ATTRIBUTE_TYPECODE_ORIGIN) { OriginAttribute origin = new OriginAttribute(messageBytes, offset); pathAttributes.add(origin); } else if(attribute_typeCode == PathAttributesTypeCode.PATH_ATTRIBUTE_TYPECODE_ASPATH) { AS_Path_Attribute as_Path_Attribute = new AS_Path_Attribute(messageBytes, offset); pathAttributes.add(as_Path_Attribute); } else if((attribute_typeCode == PathAttributesTypeCode.PATH_ATTRIBUTE_TYPECODE_BGP_LS_ATTRIBUTE) || (attribute_typeCode == PathAttributesTypeCode.PATH_ATTRIBUTE_TYPECODE_BGP_LS_ATTRIBUTE_LEGACY)) { LinkStateAttribute linkState_Attribute = new LinkStateAttribute(messageBytes, offset); pathAttributes.add(linkState_Attribute); } else if(attribute_typeCode == PathAttributesTypeCode.PATH_ATTRIBUTE_TYPECODE_MP_REACH_NLRI) { //PATH_ATTRIBUTE_TYPECODE_MP_REACH_NLRI int afi = MP_Reach_Attribute.getAFI(messageBytes, offset); if(afi == AFICodes.AFI_BGP_LS) { BGP_LS_MP_Reach_Attribute blsra = new BGP_LS_MP_Reach_Attribute(messageBytes, offset); pathAttributes.add(blsra); } else { Generic_MP_Reach_Attribute gblsra = new Generic_MP_Reach_Attribute(messageBytes, offset); pathAttributes.add(gblsra); } } else if(attribute_typeCode == PathAttributesTypeCode.PATH_ATTRIBUTE_TYPECODE_MP_UN_REACH_NLRI) { Generic_MP_Unreach_Attribute mpUnreachAttribute = new Generic_MP_Unreach_Attribute(messageBytes, offset); pathAttributes.add(mpUnreachAttribute); } else { log.warn("attribute_typeCode NOT supported by this implementation " + attribute_typeCode); } offset = offset + attribute_length + mandatory_length; len = len + attribute_length + mandatory_length; } if (offset>=this.getLength()){ return; } //NLRI //if (nlri != null){ int nlri_type = LinkStateNLRI.getNLRIType(messageBytes, offset); if(nlri_type == NLRITypes.Link_NLRI) { //Link_NLRI nlri = new LinkNLRI(messageBytes, offset); offset = offset + nlri.getLength(); } if(nlri_type == NLRITypes.Node_NLRI) { //Node_NLRI nlri = new NodeNLRI(messageBytes, offset); //UPDATE message Length - 23 - Total Path Attributes Length // - Withdrawn Routes Length offset = offset + nlri.getLength(); } if(nlri_type == NLRITypes.IT_Node_NLRI) { //ITNode_NLRI nlri = new ITNodeNLRI(messageBytes, offset); offset = offset + nlri.getLength(); } if((nlri == null) && (withdrawnRoutesLength == 0)) { log.warn("BGP4 Update without NRLI and without Withdrawn Routes"); } } } public WithdrawnRoutes getWithdrawnRoutes() { return withdrawnRoutes; } public void setWithdrawnRoutes(WithdrawnRoutes withdrawnRoutes) { //this.withdrawnRoutes = withdrawnRoutes; FIXME: First, implement WithdrawnRoutes } public ArrayList getPathAttributes() { return pathAttributes; } public void setPathAttributes(ArrayList pathAttribute) { this.pathAttributes = pathAttribute; } public NLRI getNlri() { return nlri; } public void setNlri(NLRI nlri) { this.nlri = nlri; } public String getLearntFrom() { return learntFrom; } public void setLearntFrom(String learntFrom) { this.learntFrom = learntFrom; } @Override public String toString() { // TODO Auto-generated method stub StringBuffer sb = new StringBuffer(80000); sb.append("BGP4Update Msg: "); // if(withdrawnRoutesLength != 0) // { // sb.append("> Withdrawn Routes: \n"); // sb.append(withdrawnRoutes.toString()); // } if(pathAttributes.size() != 0) { sb.append("> Path Attibutes: \n "); for(int i = 0; i < pathAttributes.size(); ++ i) { sb.append("> " + pathAttributes.get(i).toString() + "\n"); } } if(nlri != null) sb.append(nlri.toString()); return sb.toString(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy