xorp

packet.hh

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__
 All Classes Namespaces Functions Variables Typedefs Enumerations