|
xorp
|
00001 00002 // -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*- 00003 00004 // Copyright (c) 2001-2009 XORP, Inc. 00005 // 00006 // This program is free software; you can redistribute it and/or modify 00007 // it under the terms of the GNU General Public License, Version 2, June 00008 // 1991 as published by the Free Software Foundation. Redistribution 00009 // and/or modification of this program under the terms of any other 00010 // version of the GNU General Public License is not permitted. 00011 // 00012 // This program is distributed in the hope that it will be useful, but 00013 // WITHOUT ANY WARRANTY; without even the implied warranty of 00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For more details, 00015 // see the GNU General Public License, Version 2, a copy of which can be 00016 // found in the XORP LICENSE.gpl file. 00017 // 00018 // XORP Inc, 2953 Bunker Hill Lane, Suite 204, Santa Clara, CA 95054, USA; 00019 // http://xorp.net 00020 00021 // $XORP: xorp/bgp/packet.hh,v 1.50 2008/12/05 02:02:07 atanu Exp $ 00022 00023 #ifndef __BGP_PACKET_HH__ 00024 #define __BGP_PACKET_HH__ 00025 00026 #include "libxorp/xorp.h" 00027 #include "libxorp/debug.h" 00028 #include "libxorp/ipv4net.hh" 00029 #include "libxorp/ipv4.hh" 00030 00031 #include "path_attribute.hh" 00032 00033 #ifdef HAVE_SYS_UIO_H 00034 #include <sys/uio.h> 00035 #endif 00036 00037 #ifdef HAVE_NETINET_IN_H 00038 #include <netinet/in.h> 00039 #endif 00040 00041 #include "libproto/packet.hh" 00042 00043 #include "exceptions.hh" 00044 #include "parameter.hh" 00045 #include "local_data.hh" 00046 #include "peer_data.hh" 00047 #include "path_attribute.hh" 00048 #include "update_attrib.hh" 00049 00050 class BGPPeer; 00051 00052 enum BgpPacketType { 00053 MESSAGETYPEOPEN = 1, 00054 MESSAGETYPEUPDATE = 2, 00055 MESSAGETYPENOTIFICATION = 3, 00056 MESSAGETYPEKEEPALIVE = 4 00057 }; 00058 00062 enum Notify { 00063 #define UNSPECIFIED 0 // Unspecified subcode error 00064 MSGHEADERERR = 1, // Message Header Error 00065 #define CONNNOTSYNC 1 // Connection Not Synchronized 00066 #define BADMESSLEN 2 // Bad Message Length 00067 #define BADMESSTYPE 3 // Bad Message Type 00068 OPENMSGERROR = 2, // OPEN Message Error 00069 #define UNSUPVERNUM 1 // Unsupported Version Number 00070 #define BADASPEER 2 // Bad BGPPeer AS 00071 #define BADBGPIDENT 3 // Bad BGP Identifier 00072 #define UNSUPOPTPAR 4 // Unsupported Optional Parameter 00073 #define AUTHFAIL 5 // Authentication Failure 00074 #define UNACCEPTHOLDTIME 6 // Unacceptable Hold Time 00075 #define UNSUPCAPABILITY 7 // Unsupported Capability (RFC 3392) 00076 UPDATEMSGERR = 3, // UPDATE Message Error 00077 #define MALATTRLIST 1 // Malformed Attribute List 00078 #define UNRECOGWATTR 2 // Unrecognized Well-known Attribute 00079 #define MISSWATTR 3 // Missing Well-known Attribute 00080 #define ATTRFLAGS 4 // Attribute Flags Error 00081 #define ATTRLEN 5 // Attribute Length Error 00082 #define INVALORGATTR 6 // Invalid ORIGIN Attribute 00083 //#define 00084 #define INVALNHATTR 8 // Invalid NEXT_HOP Attribute 00085 #define OPTATTR 9 // Optional Attribute Error 00086 #define INVALNETFIELD 10 // Invalid Network Field 00087 #define MALASPATH 11 // Malformed AS_PATH 00088 HOLDTIMEEXP = 4, // Hold Timer Expired 00089 FSMERROR = 5, // Finite State Machine Error 00090 CEASE = 6 // Cease 00091 }; 00092 00100 class BGPPacket { 00101 public: 00105 enum Status { 00106 GOOD_MESSAGE, 00107 ILLEGAL_MESSAGE_LENGTH, 00108 CONNECTION_CLOSED, 00109 }; 00110 00111 // 00112 // The BGP common header (on the wire) 00113 // 00114 // struct fixed_header { 00115 // uint8_t marker[MARKER_SIZE]; // normally all bits are ones. 00116 // uint16_t length; // this is in network format 00117 // uint8_t type; // enum BgpPacketType 00118 // }; 00119 // 00120 00121 // Various header-related constants 00122 static const size_t MARKER_SIZE = 16; 00123 static const size_t COMMON_HEADER_LEN = MARKER_SIZE 00124 + sizeof(uint16_t) + sizeof(uint8_t); 00125 static const size_t MARKER_OFFSET = 0; 00126 static const size_t LENGTH_OFFSET = MARKER_SIZE; 00127 static const size_t TYPE_OFFSET = LENGTH_OFFSET + sizeof(uint16_t); 00128 00129 // 00130 // Various min and max packet size, accounting for the basic 00131 // information in the packet itself. 00132 // 00133 static const size_t MINPACKETSIZE = COMMON_HEADER_LEN; 00134 static const size_t MAXPACKETSIZE = 4096; 00135 static const size_t MINOPENPACKET = COMMON_HEADER_LEN + 10; 00136 static const size_t MINUPDATEPACKET = COMMON_HEADER_LEN + 2 + 2; 00137 static const size_t MINKEEPALIVEPACKET = COMMON_HEADER_LEN; 00138 static const size_t MINNOTIFICATIONPACKET = COMMON_HEADER_LEN + 2; 00139 00140 // The default marker. 00141 static const uint8_t Marker[MARKER_SIZE]; 00142 00143 BGPPacket() {} 00144 virtual ~BGPPacket() {} 00145 uint8_t type() const { return _Type; } 00146 virtual string str() const = 0; 00147 00148 virtual bool encode(uint8_t *buf, size_t &len, const BGPPeerData *peerdata) const = 0; 00149 protected: 00150 /* 00151 * Return the external representation of the packet into a buffer. 00152 * If the caller supplies the buffer it is its responsibility to make 00153 * sure that it has the correct size, otherwise the routine will 00154 * allocate it with new uint8_t[len]. 00155 * It is responsibility of the caller to dispose of the buffer. 00156 * Note that this routine will only copy the BGP common header part. 00157 * The derived-class methods are in charge of filling up any 00158 * additional data past it. 00159 */ 00160 uint8_t *basic_encode(size_t len, uint8_t *buf) const; 00161 00162 // don't allow the use of the default copy constructor 00163 BGPPacket(const BGPPacket& BGPPacket); 00164 uint8_t _Type; 00165 private: 00166 }; 00167 00168 /* **************** OpenPacket *********************** */ 00169 00170 class OpenPacket : public BGPPacket { 00171 public: 00172 OpenPacket(const uint8_t *d, uint16_t l) 00173 throw(CorruptMessage); 00174 OpenPacket(const AsNum& as, const IPv4& bgpid, const uint16_t holdtime); 00175 ~OpenPacket() {} 00176 bool encode(uint8_t *buf, size_t& len, const BGPPeerData *peerdata) const; 00177 string str() const; 00178 00179 uint8_t Version() const { return _Version; } 00180 const AsNum as() const { return _as; } 00181 uint16_t HoldTime() const { return _HoldTime; } 00182 const IPv4 id() const { return _id; } 00183 uint8_t OptParmLen() const { return _OptParmLen; } 00184 bool operator==(const OpenPacket& him) const; 00185 void add_parameter(const ParameterNode& p); 00186 00187 const ParameterList& parameter_list() const { return _parameter_list; } 00188 00189 protected: 00190 00191 private: 00192 OpenPacket(); 00193 // don't allow the use of the default copy constructor 00194 OpenPacket(const OpenPacket& OpenPacket); 00195 00196 IPv4 _id; 00197 AsNum _as; 00198 uint16_t _HoldTime; 00199 uint8_t _OptParmLen; 00200 uint8_t _Version; 00201 00202 ParameterList _parameter_list; 00203 }; 00204 00205 /* **************** UpdatePacket *********************** */ 00206 00207 class UpdatePacket : public BGPPacket { 00208 public: 00209 UpdatePacket(); 00210 UpdatePacket(const uint8_t *d, uint16_t l, const BGPPeerData *peerdata, 00211 BGPMain* mainprocess, bool do_checks) 00212 throw(CorruptMessage,UnusableMessage); 00213 00214 ~UpdatePacket(); 00215 00216 void add_withdrawn(const BGPUpdateAttrib& wdr); 00217 void replace_pathattribute_list(FPAList4Ref& pa_list); 00218 00219 void add_pathatt(const PathAttribute& pa); 00220 void add_pathatt(PathAttribute *pa); 00221 00222 void add_nlri(const BGPUpdateAttrib& nlri); 00223 const BGPUpdateAttribList& wr_list() const { return _wr_list; } 00224 FPAList4Ref& pa_list() { return _pa_list; } 00225 const BGPUpdateAttribList& nlri_list() const { return _nlri_list; } 00226 00227 template <typename A> const MPReachNLRIAttribute<A> *mpreach(Safi) const; 00228 template <typename A> const MPUNReachNLRIAttribute<A> *mpunreach(Safi) const; 00229 00230 bool encode(uint8_t *buf, size_t& len, const BGPPeerData *peerdata) const; 00231 00232 bool big_enough() const; 00233 00234 string str() const; 00235 bool operator==(const UpdatePacket& him) const; 00236 protected: 00237 00238 private: 00239 // don't allow the use of the default copy constructor 00240 UpdatePacket(const UpdatePacket& UpdatePacket); 00241 00242 BGPUpdateAttribList _wr_list; 00243 FPAList4Ref _pa_list; 00244 BGPUpdateAttribList _nlri_list; 00245 }; 00246 00247 template <typename A> 00248 const MPReachNLRIAttribute<A> * 00249 UpdatePacket::mpreach(Safi safi) const 00250 { 00251 XLOG_ASSERT(!(A::ip_version() == 4 && SAFI_UNICAST == safi)); 00252 FastPathAttributeList<IPv4>& fpalist = *_pa_list; 00253 MPReachNLRIAttribute<A>* mpreach = fpalist.template mpreach<A>(safi); 00254 return mpreach; 00255 } 00256 00257 template <typename A> 00258 const MPUNReachNLRIAttribute<A> * 00259 UpdatePacket::mpunreach(Safi safi) const 00260 { 00261 XLOG_ASSERT(!(A::ip_version() == 4 && SAFI_UNICAST == safi)); 00262 FastPathAttributeList<IPv4>& fpalist = *_pa_list; 00263 MPUNReachNLRIAttribute<A>* mpunreach = fpalist.template mpunreach<A>(safi); 00264 return mpunreach; 00265 } 00266 00267 00268 /* **************** BGPNotificationPacket *********************** */ 00269 00270 class NotificationPacket : public BGPPacket { 00271 public: 00272 NotificationPacket(const uint8_t *d, uint16_t l) throw(CorruptMessage); 00273 NotificationPacket(uint8_t ec, uint8_t esc = 0, 00274 const uint8_t *d = 0, size_t l=0); 00275 NotificationPacket(); 00276 ~NotificationPacket() { delete[] _error_data; } 00277 uint8_t error_code() const { return _error_code; } 00278 uint8_t error_subcode() const { return _error_subcode; } 00282 static bool validate_error_code(const int error, const int subcode); 00286 static string pretty_print_error_code(const int error, const int subcode, 00287 const uint8_t* error_data = 0, 00288 const size_t len = 0); 00289 const uint8_t* error_data() const { return _error_data; } 00290 bool encode(uint8_t *buf, size_t &len, const BGPPeerData *peerdata) const; 00291 string str() const; 00292 bool operator==(const NotificationPacket& him) const; 00293 protected: 00294 00295 private: 00296 // don't allow the use of the default copy constructor 00297 NotificationPacket(const NotificationPacket& Notificationpacket); 00298 size_t _Length; // total size incl. header 00299 const uint8_t* _error_data; 00300 uint8_t _error_code; 00301 uint8_t _error_subcode; 00302 }; 00303 00308 class KeepAlivePacket : public BGPPacket { 00309 public: 00313 KeepAlivePacket(const uint8_t *buf, uint16_t l) 00314 throw(CorruptMessage) { 00315 if (l != BGPPacket::MINKEEPALIVEPACKET) 00316 xorp_throw(CorruptMessage, 00317 c_format("KeepAlivePacket length %d instead of %u", 00318 l, 00319 XORP_UINT_CAST(BGPPacket::MINKEEPALIVEPACKET)), 00320 MSGHEADERERR, BADMESSLEN, buf + BGPPacket::MARKER_SIZE, 00321 2); 00322 00323 _Type = MESSAGETYPEKEEPALIVE; 00324 } 00325 00326 KeepAlivePacket() { 00327 _Type = MESSAGETYPEKEEPALIVE; 00328 } 00329 ~KeepAlivePacket() {} 00330 bool encode(uint8_t *buf, size_t &len, const BGPPeerData *peerdata) const { 00331 UNUSED(peerdata); 00332 len = BGPPacket::MINKEEPALIVEPACKET; 00333 return basic_encode(len, buf); 00334 } 00335 virtual string str() const { return "Keepalive Packet\n"; } 00336 bool operator==(const KeepAlivePacket&) const { return true; } 00337 protected: 00338 00339 private: 00340 // don't allow the use of the default copy constructor 00341 KeepAlivePacket(const KeepAlivePacket& KeepAlivePacket); 00342 }; 00343 00344 #endif // __BGP_PACKET_HH__