xorp

packet.hh

00001 // -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*-
00002 // vim:set sts=4 ts=8:
00003 
00004 // Copyright (c) 2001-2011 XORP, Inc and Others-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/ospf/packet.hh,v 1.44 2008/10/02 21:57:48 bms Exp $
00022 
00023 #ifndef __OSPF_PACKET_HH__
00024 #define __OSPF_PACKET_HH__
00025 
00030 class Packet {
00031  public:
00032     static const size_t STANDARD_HEADER_V2 = 24;
00033     static const size_t STANDARD_HEADER_V3 = 16;
00034 
00035     static const size_t VERSION_OFFSET = 0;
00036     static const size_t TYPE_OFFSET = 1;
00037     static const size_t LEN_OFFSET = 2;
00038     static const size_t ROUTER_ID_OFFSET = 4;
00039     static const size_t AREA_ID_OFFSET = 8;
00040     static const size_t CHECKSUM_OFFSET = 12;
00041 
00042     // OSPFv2 only.
00043     static const size_t AUTH_TYPE_OFFSET = 14;
00044     static const size_t AUTH_PAYLOAD_OFFSET = 16;
00045     static const size_t AUTH_PAYLOAD_SIZE = 8;
00046 
00047     // OSPFv3 only.
00048     static const size_t INSTANCE_ID_OFFSET = 14;
00049 
00050     Packet(OspfTypes::Version version)
00051         : _version(version), _valid(false), _router_id(0), _area_id(0),
00052           _auth_type(0), _instance_id(0)
00053     {
00054     memset(&_auth[0], 0, sizeof(_auth));
00055     }
00056 
00057     virtual ~Packet()
00058     {}
00059 
00071     size_t decode_standard_header(uint8_t *ptr, size_t& len) throw(InvalidPacket);
00072 
00077     virtual Packet *decode(uint8_t *ptr, size_t len)
00078     const throw(InvalidPacket) = 0;
00079 
00092     size_t encode_standard_header(uint8_t *ptr, size_t len);
00093 
00100     virtual bool encode(vector<uint8_t>& pkt) = 0;
00101 
00105     void store(uint8_t *ptr, size_t len) {
00106     _pkt.resize(len);
00107     memcpy(&_pkt[0], ptr, len);
00108     }
00109 
00114     vector<uint8_t>& get() {
00115     return _pkt;
00116     }
00117 
00121     OspfTypes::Version get_version() const { return _version; }
00122 
00128     virtual OspfTypes::Type get_type() const = 0;
00129 
00133     OspfTypes::RouterID get_router_id() const { return _router_id; }
00134 
00138     void set_router_id(OspfTypes::RouterID id) { _router_id = id; }
00139 
00143     OspfTypes::AreaID get_area_id() const { return _area_id; }
00144 
00148     void set_area_id(OspfTypes::AreaID id) { _area_id = id; }    
00149 
00153     uint16_t get_auth_type() const { return _auth_type; }
00154 
00158     void set_auth_type(uint16_t auth_type) { _auth_type = auth_type; }
00159 
00163     uint8_t get_instance_id() const { 
00164     XLOG_ASSERT(OspfTypes::V3 == get_version());
00165     return _instance_id;
00166     }
00167 
00171     void set_instance_id(uint8_t instance_id) { 
00172     XLOG_ASSERT(OspfTypes::V3 == get_version());
00173     _instance_id = instance_id;
00174     }
00175 
00179     size_t get_standard_header_length() {
00180     switch(_version) {
00181     case OspfTypes::V2:
00182         return STANDARD_HEADER_V2;
00183         break;
00184     case OspfTypes::V3:
00185         return STANDARD_HEADER_V3;
00186         break;
00187     }
00188     XLOG_UNREACHABLE();
00189     return 0;
00190     }
00191 
00201     size_t decode_point() const;
00202 
00207     string standard() const;
00208 
00212     virtual string str() const = 0;
00213 
00214  private:
00215     const OspfTypes::Version    _version;
00216     vector<uint8_t> _pkt;   // Raw packet
00217 
00221     bool _valid;
00222 
00227     OspfTypes::RouterID _router_id;
00228     OspfTypes::AreaID   _area_id;
00229     OspfTypes::AuType   _auth_type;         // OSPFv2 Only
00230     uint8_t         _auth[AUTH_PAYLOAD_SIZE];   // OSPFv2 Only
00231     uint8_t     _instance_id;           // OSPFv3 Only
00232 };
00233 
00237 class PacketDecoder {
00238  public:    
00239      ~PacketDecoder();
00240 
00246     void register_decoder(Packet *packet);
00247 
00248 #if 0
00249 
00256     void register_decoder(Packet *packet,
00257               OspfTypes::Version version,
00258               OspfTypes::Type type);
00259 #endif
00260 
00269     Packet *decode(uint8_t *ptr, size_t len) throw(InvalidPacket);
00270  private:
00271     map<OspfTypes::Type , Packet *> _ospfv2;    // OSPFv2 Packet decoders
00272     map<OspfTypes::Type , Packet *> _ospfv3;    // OSPFv3 Packet decoders
00273 };
00274 
00278 class HelloPacket : public Packet {
00279  public:
00280     static const size_t MINIMUM_LENGTH = 20;    // The minumum length
00281                         // of a hello packet.
00282                         // The same for OSPFv2
00283                         // and OSPFv3. How did
00284                         // that happen?
00285 
00286 
00287     static const size_t DESIGNATED_ROUTER_OFFSET = 12;
00288     static const size_t BACKUP_DESIGNATED_ROUTER_OFFSET = 16;
00289 
00290     // OSPFv2
00291     static const size_t NETWORK_MASK_OFFSET = 0;
00292     static const size_t HELLO_INTERVAL_V2_OFFSET = 4;
00293     static const size_t OPTIONS_V2_OFFSET = 6;
00294     static const size_t ROUTER_PRIORITY_V2_OFFSET = 7;
00295     static const size_t ROUTER_DEAD_INTERVAL_V2_OFFSET = 8;
00296 
00297     // OSPFv3
00298     static const size_t INTERFACE_ID_OFFSET = 0;
00299     static const size_t ROUTER_PRIORITY_V3_OFFSET = 4;
00300     static const size_t OPTIONS_V3_OFFSET = 4;
00301     static const size_t HELLO_INTERVAL_V3_OFFSET = 8;
00302     static const size_t ROUTER_DEAD_INTERVAL_V3_OFFSET = 10;
00303 
00304     HelloPacket(OspfTypes::Version version)
00305     : Packet(version), _network_mask(0), _interface_id(0),
00306       _hello_interval(0), _options(0), _router_priority(0),
00307       _router_dead_interval(0)
00308     {}
00309 
00310     OspfTypes::Type get_type() const { return 1; }
00311 
00312     Packet *decode(uint8_t *ptr, size_t len) const throw(InvalidPacket);
00313 
00320     bool encode(vector<uint8_t>& pkt);
00321 
00322     // Network Mask.
00323     void set_network_mask(uint32_t network_mask) {
00324     XLOG_ASSERT(OspfTypes::V2 == get_version());
00325     _network_mask = network_mask;
00326     }
00327 
00328     uint32_t get_network_mask() const {
00329     XLOG_ASSERT(OspfTypes::V2 == get_version());
00330     return _network_mask;
00331     }
00332 
00333     // Interface ID.
00334     void set_interface_id(uint32_t interface_id) {
00335     XLOG_ASSERT(OspfTypes::V3 == get_version());
00336     _interface_id = interface_id;
00337     }
00338 
00339     uint32_t get_interface_id() const {
00340     XLOG_ASSERT(OspfTypes::V3 == get_version());
00341     return _interface_id;
00342     }
00343 
00344     // Hello Interval.
00345     void set_hello_interval(uint16_t hello_interval) {
00346     _hello_interval = hello_interval;
00347     }
00348 
00349     uint16_t get_hello_interval() const {
00350     return _hello_interval;
00351     }
00352 
00353     // Options.
00354     void set_options(uint32_t options) {
00355     switch(get_version()) {
00356     case OspfTypes::V2:
00357         if (options > 0xff)
00358         XLOG_WARNING("Attempt to set %#x in an 8 bit field",
00359                  options);
00360         _options = options & 0xff;
00361         break;
00362     case OspfTypes::V3:
00363         if (options  > 0xffffff)
00364         XLOG_WARNING("Attempt to set %#x in a 24 bit field",
00365                  options);
00366         _options = options & 0xffffff;
00367         break;
00368     }
00369     }
00370 
00371     uint32_t get_options() const {
00372     return _options;
00373     }
00374 
00375     // Router Priority.
00376     void set_router_priority(uint8_t router_priority) {
00377     _router_priority = router_priority;
00378     }
00379 
00380     uint8_t get_router_priority() const {
00381     return _router_priority;
00382     }
00383 
00384     // Router Dead Interval.
00385     void set_router_dead_interval(uint32_t router_dead_interval) {
00386     switch(get_version()) {
00387     case OspfTypes::V2:
00388         _router_dead_interval = router_dead_interval;
00389         break;
00390     case OspfTypes::V3:
00391         if ( router_dead_interval > 0xffff)
00392         XLOG_WARNING("Attempt to set %#x in a 16 bit field",
00393                  router_dead_interval);
00394         _router_dead_interval = router_dead_interval & 0xffff;
00395         break;
00396     }
00397     }
00398 
00399     uint32_t get_router_dead_interval() const {
00400     return _router_dead_interval;
00401     }
00402 
00403     // Designated Router
00404     void set_designated_router(OspfTypes::RouterID dr) {
00405     _dr = dr;
00406     }
00407 
00408     OspfTypes::RouterID get_designated_router() const {
00409     return _dr;
00410     }
00411     
00412     // Backup Designated Router
00413     void set_backup_designated_router(OspfTypes::RouterID bdr) {
00414     _bdr = bdr;
00415     }
00416 
00417     OspfTypes::RouterID get_backup_designated_router() const {
00418     return _bdr;
00419     }
00420     
00421     list<OspfTypes::RouterID>& get_neighbours() {
00422     return _neighbours;
00423     }
00424 
00428     string str() const;
00429 
00430  private:
00431     uint32_t _network_mask; // OSPF V2 Only
00432     uint32_t _interface_id; // OSPF V3 Only
00433     uint16_t _hello_interval;
00434     uint32_t _options;      // Large enough to accomodate V2 and V3 options
00435     uint8_t  _router_priority;  // Router Priority.
00436     uint32_t _router_dead_interval; // In seconds.
00437     OspfTypes::RouterID _dr;    // Designated router.
00438     OspfTypes::RouterID _bdr;   // Backup Designated router.
00439 
00440     list<OspfTypes::RouterID> _neighbours; // Router IDs of neighbours.
00441 };
00442 
00446 class DataDescriptionPacket : public Packet {
00447  public:
00448     DataDescriptionPacket(OspfTypes::Version version)
00449     : Packet(version), _interface_mtu(0), _options(0),
00450       _i_bit(false), _m_bit(false), _ms_bit(false), _DD_seqno(0)
00451     {}
00452 
00453     OspfTypes::Type get_type() const { return 2; }
00454 
00455     size_t minimum_length() const {
00456     switch(get_version()) {
00457     case OspfTypes::V2:
00458         return 8;
00459         break;
00460     case OspfTypes::V3:
00461         return 12;
00462         break;
00463     }
00464     XLOG_UNREACHABLE();
00465     return 0;
00466     }
00467 
00468     Packet *decode(uint8_t *ptr, size_t len) const throw(InvalidPacket);
00469 
00476     bool encode(vector<uint8_t>& pkt);
00477 
00478     // Interface MTU
00479     void set_interface_mtu(uint16_t mtu) {
00480     _interface_mtu = mtu;
00481     }
00482 
00483     uint16_t get_interface_mtu() const {
00484     return _interface_mtu;
00485     }
00486 
00487     // Options.
00488     void set_options(uint32_t options) {
00489     switch(get_version()) {
00490     case OspfTypes::V2:
00491         if (options > 0xff)
00492         XLOG_WARNING("Attempt to set %#x in an 8 bit field",
00493                  options);
00494         _options = options & 0xff;
00495         break;
00496     case OspfTypes::V3:
00497         if (options  > 0xffffff)
00498         XLOG_WARNING("Attempt to set %#x in a 24 bit field",
00499                  options);
00500         _options = options & 0xffffff;
00501         break;
00502     }
00503     }
00504 
00505     uint32_t get_options() const {
00506     return _options;
00507     }
00508 
00509     // Init bit.
00510     void set_i_bit(bool bit) {
00511     _i_bit = bit;
00512     }
00513 
00514     bool get_i_bit() const {
00515     return _i_bit;
00516     }
00517 
00518     // More bit.
00519     void set_m_bit(bool bit) {
00520     _m_bit = bit;
00521     }
00522 
00523     bool get_m_bit() const {
00524     return _m_bit;
00525     }
00526 
00527     // Master/Slave bit
00528     void set_ms_bit(bool bit) {
00529     _ms_bit = bit;
00530     }
00531 
00532     bool get_ms_bit() const {
00533     return _ms_bit;
00534     }
00535     
00536     // Database description sequence number.
00537     void set_dd_seqno(uint32_t seqno) {
00538     _DD_seqno = seqno;
00539     }
00540     
00541     uint32_t get_dd_seqno() const {
00542     return _DD_seqno;
00543     }
00544 
00545     list<Lsa_header>& get_lsa_headers() {
00546     return _lsa_headers;
00547     }
00548     
00552     string str() const;
00553 
00554  private:
00555     uint16_t    _interface_mtu;
00556     uint32_t    _options;   // Large enough to accomodate V2 and V3 options
00557     bool    _i_bit;     // The init bit.
00558     bool    _m_bit;     // The more bit.
00559     bool    _ms_bit;    // The Master/Slave bit.
00560     uint32_t    _DD_seqno;  // Database description sequence number.
00561     
00562     list<Lsa_header> _lsa_headers;
00563 };
00564 
00568 class LinkStateRequestPacket : public Packet {
00569  public:
00570     LinkStateRequestPacket(OspfTypes::Version version)
00571     : Packet(version)
00572     {}
00573 
00574     OspfTypes::Type get_type() const { return 3; }
00575 
00576     Packet *decode(uint8_t *ptr, size_t len) const throw(InvalidPacket);
00577 
00584     bool encode(vector<uint8_t>& pkt);
00585     
00586     list<Ls_request>& get_ls_request() {
00587     return _ls_request;
00588     }
00589     
00593     string str() const;
00594  private:
00595     list<Ls_request> _ls_request;
00596 };
00597 
00601 class LinkStateUpdatePacket : public Packet {
00602  public:
00603     LinkStateUpdatePacket(OspfTypes::Version version, LsaDecoder& lsa_decoder)
00604     : Packet(version), _lsa_decoder(lsa_decoder)
00605     {}
00606 
00607     OspfTypes::Type get_type() const { return 4; }
00608 
00609     Packet *decode(uint8_t *ptr, size_t len) const throw(InvalidPacket);
00610 
00617     bool encode(vector<uint8_t>& pkt);
00618 
00626     bool encode(vector<uint8_t>& pkt, uint16_t inftransdelay);
00627 
00628     list<Lsa::LsaRef>& get_lsas() {
00629     return _lsas;
00630     }
00631     
00635     string str() const;
00636     
00637  private:
00638     LsaDecoder& _lsa_decoder;   // LSA decoders.
00639 
00640     // The packet contains a field with the number of LSAs that it
00641     // contains there is no point in storing it.
00642 
00643     list<Lsa::LsaRef> _lsas;    // The list of LSAs in the packet.
00644 };
00645 
00649 class LinkStateAcknowledgementPacket : public Packet {
00650  public:
00651     LinkStateAcknowledgementPacket(OspfTypes::Version version)
00652     : Packet(version)
00653     {}
00654 
00655     OspfTypes::Type get_type() const { return 5; }
00656 
00657     Packet *decode(uint8_t *ptr, size_t len) const throw(InvalidPacket);
00658 
00665     bool encode(vector<uint8_t>& pkt);
00666 
00667     list<Lsa_header>& get_lsa_headers() {
00668     return _lsa_headers;
00669     }
00670     
00674     string str() const;
00675     
00676  private:
00677     list<Lsa_header> _lsa_headers;
00678 };
00679 
00684 inline
00685 void
00686 initialise_packet_decoder(OspfTypes::Version version,
00687               PacketDecoder& packet_decoder, 
00688               LsaDecoder& lsa_decoder)
00689 {
00690     packet_decoder.register_decoder(new HelloPacket(version));
00691     packet_decoder.register_decoder(new DataDescriptionPacket(version));
00692     packet_decoder.register_decoder(new LinkStateUpdatePacket(version,
00693                                    lsa_decoder));
00694     packet_decoder.register_decoder(new LinkStateRequestPacket(version));
00695     packet_decoder.
00696     register_decoder(new LinkStateAcknowledgementPacket(version));
00697 }
00698 
00702 class Options {
00703  public:
00704      static const uint32_t V6_bit = 0x1;
00705      static const uint32_t E_bit = 0x2;
00706      static const uint32_t MC_bit = 0x4;
00707      static const uint32_t N_bit = 0x8;
00708      static const uint32_t P_bit = N_bit;
00709      static const uint32_t R_bit = 0x10;
00710      static const uint32_t EA_bit = 0x10;
00711      static const uint32_t DC_bit = 0x20;
00712 
00713      Options(OspfTypes::Version version, uint32_t options)
00714      : _version(version), _options(options)
00715      {
00716      }
00717 
00718      void set_bit(bool set, uint32_t bit) {
00719      if (set)
00720          _options |= bit;
00721      else
00722          _options &= ~bit;
00723     
00724      }
00725      bool get_bit(uint32_t bit) const { return _options & bit ? true : false; }
00726 
00727      void set_v6_bit(bool set) {
00728      XLOG_ASSERT(OspfTypes::V3 == _version);
00729      set_bit(set, V6_bit);
00730      }
00731      bool get_v6_bit() const {
00732      XLOG_ASSERT(OspfTypes::V3 == _version);
00733      return get_bit(V6_bit);
00734      }
00735 
00736      void set_e_bit(bool set) { set_bit(set, E_bit); }
00737      bool get_e_bit() const { return get_bit(E_bit); }
00738 
00739      void set_mc_bit(bool set) { set_bit(set, MC_bit); }
00740      bool get_mc_bit() const { return get_bit(MC_bit); }
00741 
00742      void set_n_bit(bool set) { set_bit(set, N_bit); }
00743      bool get_n_bit() const { return get_bit(N_bit); }
00744 
00745      void set_p_bit(bool set) { set_n_bit(set); }
00746      bool get_p_bit() const { return get_n_bit(); }
00747 
00748      void set_r_bit(bool set) {
00749      XLOG_ASSERT(OspfTypes::V3 == _version);
00750      set_bit(set, R_bit);
00751      }
00752      bool get_r_bit() const {
00753      XLOG_ASSERT(OspfTypes::V3 == _version);
00754      return get_bit(R_bit);
00755      }
00756 
00757      void set_ea_bit(bool set) {
00758      XLOG_ASSERT(OspfTypes::V2 == _version);
00759      set_bit(set, EA_bit);
00760      }
00761      bool get_ea_bit() const {
00762      XLOG_ASSERT(OspfTypes::V2 == _version);
00763      return get_bit(EA_bit);
00764      }
00765 
00766      void set_dc_bit(bool set) { set_bit(set, DC_bit); }
00767      bool get_dc_bit() const { return get_bit(DC_bit); }
00768      
00769      uint32_t get_options() { return _options; }
00770 
00771      string pp_bool(bool val) const { return val ? "1" : "0"; }
00772 
00773      string str() const {
00774      string out;
00775 
00776      switch(_version) {
00777      case OspfTypes::V2:
00778          out = "DC: " + pp_bool(get_dc_bit());
00779          out += " EA: " + pp_bool(get_ea_bit());
00780          out += " N/P: " + pp_bool(get_n_bit());
00781          out += " MC: " + pp_bool(get_mc_bit());
00782          out += " E: " + pp_bool(get_e_bit());
00783          break;
00784      case OspfTypes::V3:
00785          out = "DC: " + pp_bool(get_dc_bit());
00786          out += " R: " + pp_bool(get_r_bit());
00787          out += " N: " + pp_bool(get_n_bit());
00788          out += " MC: " + pp_bool(get_mc_bit());
00789          out += " E: " + pp_bool(get_e_bit());
00790          out += " V6: " + pp_bool(get_v6_bit());
00791          break;
00792      }
00793 
00794      return out;
00795      }
00796     
00797  private:
00798      OspfTypes::Version _version;
00799      uint32_t _options;
00800 };
00801 
00817 template <typename A> 
00818 void
00819 ipv6_checksum_verify(const A& src, const A& dst,
00820              const uint8_t *data, size_t len,
00821              size_t checksum_offset, uint8_t protocol)
00822     throw(InvalidPacket);
00823 
00839 template <typename A> 
00840 void
00841 ipv6_checksum_apply(const A& src, const A& dst,
00842             uint8_t *data, size_t len,
00843             size_t checksum_offset, uint8_t protocol)
00844     throw(InvalidPacket);
00845 
00846 #endif // __OSPF_PACKET_HH__
 All Classes Namespaces Functions Variables Typedefs Enumerations