xorp

lsa.hh

00001 // -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*-
00002 
00003 // Copyright (c) 2001-2009 XORP, Inc.
00004 //
00005 // This program is free software; you can redistribute it and/or modify
00006 // it under the terms of the GNU General Public License, Version 2, June
00007 // 1991 as published by the Free Software Foundation. Redistribution
00008 // and/or modification of this program under the terms of any other
00009 // version of the GNU General Public License is not permitted.
00010 // 
00011 // This program is distributed in the hope that it will be useful, but
00012 // WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For more details,
00014 // see the GNU General Public License, Version 2, a copy of which can be
00015 // found in the XORP LICENSE.gpl file.
00016 // 
00017 // XORP Inc, 2953 Bunker Hill Lane, Suite 204, Santa Clara, CA 95054, USA;
00018 // http://xorp.net
00019 
00020 // $XORP: xorp/ospf/lsa.hh,v 1.113 2008/10/02 21:57:47 bms Exp $
00021 
00022 #ifndef __OSPF_LSA_HH__
00023 #define __OSPF_LSA_HH__
00024 
00029 class Lsa_header {
00030  public:
00031     Lsa_header(OspfTypes::Version version) :
00032     _version(version), _LS_age(0), _options(0), _ls_type(0),
00033     _link_state_id(0), _advertising_router(0),
00034     _ls_sequence_number(OspfTypes::InitialSequenceNumber),
00035     _ls_checksum(0), _length(0)
00036     {}
00037 
00038     Lsa_header(const Lsa_header& rhs) {
00039     copy(rhs);
00040     }
00041 
00042     Lsa_header operator=(const Lsa_header& rhs) {
00043     if(&rhs == this)
00044         return *this;
00045     copy(rhs);
00046     return *this;
00047     }
00048 
00049 #define lsa_copy(var)   var = rhs.var;
00050 
00051     void copy(const Lsa_header& rhs) {
00052     lsa_copy(_version);
00053     lsa_copy(_LS_age);
00054     lsa_copy(_options);
00055     lsa_copy(_ls_type);
00056     lsa_copy(_link_state_id);
00057     lsa_copy(_advertising_router);
00058     lsa_copy(_ls_sequence_number);
00059     lsa_copy(_ls_checksum);
00060     lsa_copy(_length);
00061     }
00062 #undef  lsa_copy
00063 
00067     static size_t length() { return 20; }
00068 
00072     static uint16_t get_lsa_len_from_buffer(uint8_t *ptr);
00073 
00077     Lsa_header decode(uint8_t *ptr) const throw(InvalidPacket);
00078 
00082     void decode_inline(uint8_t *ptr) throw(InvalidPacket);
00083 
00088     size_t copy_out(uint8_t *to_uint8) const;
00089 
00090     OspfTypes::Version get_version() const {
00091     return _version;
00092     }
00093 
00094     // LS age
00095     void set_ls_age(uint16_t ls_age) {
00096     _LS_age = ls_age;
00097     }
00098 
00099     uint16_t get_ls_age() const {
00100     return _LS_age;
00101     }
00102 
00103     // Options
00104     void set_options(uint8_t options) {
00105     XLOG_ASSERT(OspfTypes::V2 == get_version());
00106     _options = options;
00107     }
00108 
00109     uint8_t get_options() const {
00110     XLOG_ASSERT(OspfTypes::V2 == get_version());
00111     return _options;
00112     }
00113 
00114     // LS type
00115     void set_ls_type(uint16_t ls_type) {
00116     switch(get_version()) {
00117     case OspfTypes::V2:
00118         if (ls_type > 0xff)
00119         XLOG_WARNING("Attempt to set %#x in an 8 bit field",
00120                  ls_type);
00121         _ls_type = ls_type & 0xff;
00122         break;
00123     case OspfTypes::V3:
00124         _ls_type = ls_type;
00125         break;
00126     }
00127     }
00128 
00129     uint16_t get_ls_type() const {
00130     return _ls_type;
00131     }
00132 
00133     // Link State ID
00134     void set_link_state_id(uint32_t link_state_id) {
00135     _link_state_id = link_state_id;
00136     }
00137 
00138     uint32_t get_link_state_id() const {
00139     return _link_state_id;
00140     }
00141     
00142     // Advertising Router
00143     void set_advertising_router(uint32_t advertising_router) {
00144     _advertising_router = advertising_router;
00145     }
00146 
00147     uint32_t get_advertising_router() const {
00148     return _advertising_router;
00149     }
00150 
00151     // LS sequence number
00152     void set_ls_sequence_number(int32_t ls_sequence_number) {
00153     _ls_sequence_number = ls_sequence_number;
00154     }
00155 
00156     int32_t get_ls_sequence_number() const {
00157     return _ls_sequence_number;
00158     }
00159 
00160     // LS checksum
00161     void set_ls_checksum(uint16_t ls_checksum) {
00162     _ls_checksum = ls_checksum;
00163     }
00164 
00165     uint16_t get_ls_checksum() const {
00166     return _ls_checksum;
00167     }
00168 
00169     // Length
00170     void set_length(uint16_t length) {
00171     _length = length;
00172     }
00173 
00174     uint16_t get_length() const {
00175     return _length;
00176     }
00177 
00181     string str() const;
00182 
00183  private:
00184     void decode(Lsa_header& header, uint8_t *ptr) const throw(InvalidPacket);
00185 
00186     OspfTypes::Version _version;
00187     uint16_t    _LS_age;
00188     uint8_t _options;   // OSPFv2 Only  
00189     uint16_t    _ls_type;   // OSPFv2 1 byte, OSPFv3 2 bytes.
00190     uint32_t    _link_state_id;
00191     uint32_t    _advertising_router;
00192     int32_t _ls_sequence_number;
00193     uint16_t    _ls_checksum;
00194     uint16_t    _length;
00195 };
00196 
00206 inline
00207 bool
00208 operator==(const Lsa_header& lhs, const Lsa_header& rhs)
00209 {
00210     // We could check for lhs == rhs this will be such a rare
00211     // occurence why bother.
00212     if (lhs.get_ls_type() != rhs.get_ls_type())
00213     return false;
00214 
00215     if (lhs.get_link_state_id() != rhs.get_link_state_id())
00216     return false;
00217 
00218     if (lhs.get_advertising_router() != rhs.get_advertising_router())
00219     return false;
00220 
00221     return true;
00222 }
00223 
00229 inline
00230 bool
00231 compare_all_header_fields(const Lsa_header& lhs, const Lsa_header& rhs)
00232 {
00233     // We could check for lhs == rhs this will be such a rare
00234     // occurence why bother.
00235 
00236     // Try and order the comparisons so in the no match case we blow
00237     // out early.
00238 
00239 #define lsa_header_compare(func)    if (lhs.func != rhs.func) return false;
00240 
00241     lsa_header_compare(get_ls_checksum());
00242     lsa_header_compare(get_length());
00243     switch(lhs.get_version()) {
00244     case OspfTypes::V2:
00245     lsa_header_compare(get_options());
00246     break;
00247     case OspfTypes::V3:
00248     break;
00249     }
00250     lsa_header_compare(get_ls_sequence_number());
00251     lsa_header_compare(get_ls_type());
00252     lsa_header_compare(get_link_state_id());
00253     lsa_header_compare(get_advertising_router());
00254 
00255 #undef lsa_header_compare
00256 
00257     return true;
00258 }
00259 
00265 class Lsa {
00266  public:
00271     typedef ref_ptr<Lsa> LsaRef;
00272 
00273     Lsa(OspfTypes::Version version)
00274     :  _header(version), _version(version), _valid(true),
00275        _self_originating(false),  _initial_age(0), _transmitted(false),
00276        _trace(false), _peerid(OspfTypes::ALLPEERS)
00277     {}
00278 
00283     Lsa(OspfTypes::Version version, uint8_t *buf, size_t len)
00284     :  _header(version), _version(version), _valid(true),
00285        _self_originating(false),  _initial_age(0), _transmitted(false),
00286        _trace(false), _peerid(OspfTypes::ALLPEERS)
00287     {
00288     _pkt.resize(len);
00289     memcpy(&_pkt[0], buf, len);
00290     }
00291 
00292     virtual ~Lsa()
00293     {}
00294 
00295     OspfTypes::Version get_version() const {
00296     return _version;
00297     }
00298 
00305     virtual uint16_t get_ls_type() const = 0;
00306 
00312     virtual bool known() const {
00313     XLOG_ASSERT(OspfTypes::V3 == get_version());
00314     return true;
00315     }
00316 
00320     virtual bool external() const { return false; };
00321 
00325     virtual bool type7() const { return false; }
00326 
00332     virtual size_t min_length() const = 0;
00333 
00342     virtual LsaRef decode(uint8_t *buf, size_t& len) const 
00343     throw(InvalidPacket) = 0;
00344 
00350     virtual bool encode() = 0;
00351 
00359     uint8_t *lsa(size_t &len) {
00360     len = _pkt.size();
00361     XLOG_ASSERT(0 != len);
00362     return &_pkt[0];
00363     }
00364 
00377     bool available() const { return 0 != _pkt.size(); }
00378 
00379     Lsa_header& get_header() {return _header; }
00380 
00381     const Lsa_header& get_header() const {return _header; }
00382 
00386     bool valid() const { return _valid; }
00387 
00392     void invalidate(bool invalidate = true) {
00393     if(invalidate)
00394         _valid = false;
00395     _timer.clear();
00396     }
00397 
00401     bool get_self_originating() const { return _self_originating; }
00402 
00406     void set_self_originating(bool orig) { _self_originating = orig; }
00407 
00412     void record_creation_time(TimeVal now) {
00413     _creation = now;
00414     _initial_age = _header.get_ls_age();
00415     }
00416 
00422     void get_creation_time(TimeVal& now) {
00423     now = _creation;
00424     }
00425 
00430     void revive(const TimeVal& now);
00431 
00436     void update_age_and_seqno(const TimeVal& now);
00437 
00443     void update_age(TimeVal now);
00444 
00451     static void update_age_inftransdelay(uint8_t *ptr, uint16_t inftransdelay);
00452 
00456     void set_maxage();
00457 
00461     bool maxage() const;
00462 
00466     bool max_sequence_number() const;
00467 
00471     int32_t get_ls_sequence_number() const {
00472     return _header.get_ls_sequence_number();
00473     }
00474 
00478     void set_ls_sequence_number(int32_t seqno) {
00479     _header.set_ls_sequence_number(seqno);
00480     }
00481 
00485     void increment_sequence_number() {
00486     int32_t seqno = _header.get_ls_sequence_number();
00487     if (OspfTypes:: MaxSequenceNumber == seqno)
00488         XLOG_FATAL("Bummer sequence number reached %d",
00489                OspfTypes::MaxSequenceNumber);
00490     seqno += 1;
00491     _header.set_ls_sequence_number(seqno);
00492     }
00493 
00497     void add_nack(OspfTypes::NeighbourID nid) {
00498     _nack_list.insert(nid);
00499     }
00500 
00504     void remove_nack(OspfTypes::NeighbourID nid) {
00505     _nack_list.erase(nid);
00506     }
00507 
00511     bool exists_nack(OspfTypes::NeighbourID nid) {
00512     return _nack_list.end() != _nack_list.find(nid);
00513     }
00514 
00519     bool empty_nack() const {
00520     return _nack_list.empty();
00521     }
00522 
00526     bool get_transmitted() { return _transmitted; }
00527 
00531     void set_transmitted(bool t) { _transmitted = t; }
00532 
00536     XorpTimer& get_timer() { return _timer; }
00537 
00538     void set_tracing(bool trace) { _trace = trace; }
00539 
00540     bool tracing() const { return _trace; }
00541 
00546     void set_peerid(OspfTypes::PeerID peerid) {
00547     XLOG_ASSERT(OspfTypes::V3 == get_version());
00548     XLOG_ASSERT(OspfTypes::ALLPEERS == _peerid);
00549     _peerid = peerid;
00550     }
00551 
00556     OspfTypes::PeerID get_peerid() const {
00557     XLOG_ASSERT(OspfTypes::V3 == get_version());
00558     XLOG_ASSERT(OspfTypes::ALLPEERS != _peerid);
00559     return _peerid;
00560     }
00561 
00562 
00563     // OSPFv3 only, if an LSA is not known and does not have the U-bit
00564     // set then it should be treated as if it has Link-local flooding scope.
00565 
00569     bool link_local_scope() const {
00570     XLOG_ASSERT(OspfTypes::V3 == get_version());
00571     if (!understood())
00572         return true;
00573 
00574     return 0 == (get_ls_type() & 0x6000);
00575     }
00576 
00580     bool area_scope() const {
00581     XLOG_ASSERT(OspfTypes::V3 == get_version());
00582     if (!understood())
00583         return false;
00584 
00585     return 0x2000 == (get_ls_type() & 0x6000);
00586     }
00587 
00591     bool as_scope() const {
00592     XLOG_ASSERT(OspfTypes::V3 == get_version());
00593     if (!understood())
00594         return false;
00595 
00596     return 0x4000 == (get_ls_type() & 0x6000);
00597     }
00598 
00602     virtual const char *name() const = 0;
00603 
00607     virtual string str() const = 0;
00608 
00612 //     void install_type(LsaType type, Lsa *lsa);
00613  protected:
00614     Lsa_header _header;     // Common LSA header.
00615     vector<uint8_t> _pkt;   // Raw LSA.
00616 
00617  private:
00618     const OspfTypes::Version    _version;
00619     bool _valid;        // True if this LSA is still valid.
00620     bool _self_originating; // True if this LSA is self originating.
00621 
00622     uint16_t _initial_age;  // Age when this LSA was created.
00623     TimeVal _creation;      // Time when this LSA was created.
00624     
00625     XorpTimer _timer;       // If this is a self originated LSA
00626                 // this timer is used to retransmit
00627                 // the LSA, otherwise this timer fires
00628                 // when MaxAge is reached.
00629 
00630     bool _transmitted;      // Set to true when this LSA is transmitted.
00631 
00632     bool _trace;        // True if this LSA should be traced.
00633 
00634     // List of neighbours that have not yet acknowledged this LSA.
00635 
00636     set<OspfTypes::NeighbourID> _nack_list; 
00637 
00641     void set_ls_age(uint16_t ls_age);
00642 
00648     OspfTypes::PeerID _peerid;
00649 
00655     bool understood() const {
00656     XLOG_ASSERT(OspfTypes::V3 == get_version());
00657     if (known())
00658         return true;
00659     else
00660         return 0x8000 == (get_ls_type() & 0x8000);
00661     }
00662 };
00663 
00667 class LsaDecoder {
00668  public:    
00669     LsaDecoder(OspfTypes::Version version)
00670     : _version(version), _min_lsa_length(0), _unknown_lsa_decoder(0)
00671     {}
00672 
00673     ~LsaDecoder();
00674 
00680     void register_decoder(Lsa *lsa);
00681 
00687     void register_unknown_decoder(Lsa *lsa);
00688 
00698     Lsa::LsaRef decode(uint8_t *ptr, size_t& len) const throw(InvalidPacket);
00699 
00703     size_t min_length() const {
00704     return _min_lsa_length + Lsa_header::length();
00705     }
00706 
00714     bool validate(uint16_t type) const {
00715     if (0 != _unknown_lsa_decoder)
00716         return true;
00717     return _lsa_decoders.end() != _lsa_decoders.find(type);
00718     }
00719 
00725     bool external(uint16_t type) {
00726     map<uint16_t, Lsa *>::iterator i = _lsa_decoders.find(type);
00727     XLOG_ASSERT(_lsa_decoders.end() != i);
00728     return i->second->external();
00729     }
00730 
00734      const char *name(uint16_t type) const {
00735      map<uint16_t, Lsa *>::const_iterator i = _lsa_decoders.find(type);
00736      XLOG_ASSERT(_lsa_decoders.end() != i);
00737      return i->second->name();
00738      }
00739 
00740     OspfTypes::Version get_version() const {
00741     return _version;
00742     }
00743  private:
00744     const OspfTypes::Version    _version;
00745     size_t _min_lsa_length;     // The smallest LSA that can be
00746                     // decoded, excluding LSA header.
00747 
00748     map<uint16_t, Lsa *> _lsa_decoders; // OSPF LSA decoders
00749     Lsa * _unknown_lsa_decoder;     // OSPF Unknown LSA decoder
00750 };
00751 
00756 class IPv6Prefix {
00757 public:
00758     static const uint8_t NU_bit = 0x1;
00759     static const uint8_t LA_bit = 0x2;
00760     static const uint8_t MC_bit = 0x4;
00761     static const uint8_t P_bit = 0x8;
00762     static const uint8_t DN_bit = 0x10;
00763 
00764     IPv6Prefix(OspfTypes::Version version, bool use_metric = false)
00765     : _version(version), _use_metric(use_metric), _metric(0),
00766       _prefix_options(0)
00767     {
00768     }
00769 
00770     IPv6Prefix(const IPv6Prefix& rhs)
00771     : _version(rhs._version), _use_metric(rhs._use_metric)
00772     {
00773     copy(rhs);
00774     }
00775 
00776     IPv6Prefix operator=(const IPv6Prefix& rhs) {
00777     if(&rhs == this)
00778         return *this;
00779     copy(rhs);
00780     return *this;
00781     }
00782 
00783 #define ipv6prefix_copy(var)    var = rhs.var;
00784 
00785     void copy(const IPv6Prefix& rhs) {
00786     ipv6prefix_copy(_network);
00787     ipv6prefix_copy(_metric);
00788     ipv6prefix_copy(_prefix_options);
00789     }
00790 #undef  ipv6prefix_copy
00791 
00795     size_t length() const;
00796 
00808     IPv6Prefix decode(uint8_t *ptr, size_t& len, uint8_t prefixlen,
00809               uint8_t option) const
00810     throw(InvalidPacket);
00811 
00819     size_t copy_out(uint8_t *to_uint8) const;
00820 
00824     static size_t bytes_per_prefix(uint8_t prefix) {
00825     return ((prefix + 31) / 32) * 4;
00826     }
00827 
00828     OspfTypes::Version get_version() const {
00829     return _version;
00830     }
00831 
00832     void set_network(const IPNet<IPv6>& network) {
00833     XLOG_ASSERT(OspfTypes::V3 == get_version());
00834     _network = network;
00835     }
00836 
00837     IPNet<IPv6> get_network() const {
00838     XLOG_ASSERT(OspfTypes::V3 == get_version());
00839     return _network;
00840     }
00841 
00842     bool use_metric() const {
00843     return _use_metric;
00844     }
00845 
00846     void set_metric(uint16_t metric) {
00847     XLOG_ASSERT(_use_metric);
00848     _metric = metric;
00849     }
00850 
00851     uint16_t get_metric() const {
00852     XLOG_ASSERT(_use_metric);
00853     return _metric;
00854     }
00855 
00856     void set_prefix_options(uint8_t prefix_options) {
00857     XLOG_ASSERT(OspfTypes::V3 == get_version());
00858     _prefix_options = prefix_options;
00859     }
00860 
00861     uint8_t get_prefix_options() const {
00862     XLOG_ASSERT(OspfTypes::V3 == get_version());
00863     return _prefix_options;
00864     }
00865     
00866     void set_bit(bool set, uint8_t bit) {
00867      XLOG_ASSERT(OspfTypes::V3 == get_version());
00868      if (set)
00869          _prefix_options |= bit;
00870      else
00871          _prefix_options &= ~bit;
00872     
00873     }
00874 
00875     bool get_bit(uint8_t bit) const {
00876     XLOG_ASSERT(OspfTypes::V3 == get_version());
00877     return _prefix_options & bit ? true : false;
00878     }
00879 
00880     void set_nu_bit(bool set) { set_bit(set, NU_bit); }
00881     bool get_nu_bit() const { return get_bit(NU_bit); }
00882     
00883     void set_la_bit(bool set) { set_bit(set, LA_bit); }
00884     bool get_la_bit() const { return get_bit(LA_bit); }
00885 
00886     void set_mc_bit(bool set) { set_bit(set, MC_bit); }
00887     bool get_mc_bit() const { return get_bit(MC_bit); }
00888 
00889     void set_p_bit(bool set) { set_bit(set, P_bit); }
00890     bool get_p_bit() const { return get_bit(P_bit); }
00891 
00892     void set_dn_bit(bool set) { set_bit(set, DN_bit); }
00893     bool get_dn_bit() const { return get_bit(DN_bit); }
00894 
00898     string str() const;
00899 
00900 private:
00901     const OspfTypes::Version _version;
00902     const bool _use_metric;
00903 
00904     IPNet<IPv6> _network;
00905     uint16_t _metric;
00906     uint8_t _prefix_options;
00907 };
00908 
00912 class RouterLink {
00913  public:
00914     enum Type {
00915     p2p = 1,    // Point-to-point connection to another router
00916     transit = 2,    // Connection to a transit network
00917     stub = 3,   // Connection to a stub network OSPFv2 only
00918     vlink = 4   // Virtual link
00919     };
00920 
00921     RouterLink(OspfTypes::Version version) 
00922     : _version(version), _type(p2p), _metric(0), _link_id(0),
00923       _link_data(0), _interface_id(0), _neighbour_interface_id(0),
00924       _neighbour_router_id(0)
00925     {}
00926 
00927     RouterLink(const RouterLink& rhs) : _version(rhs._version) {
00928     copy(rhs);
00929     }
00930 
00931     RouterLink operator=(const RouterLink& rhs) {
00932     if(&rhs == this)
00933         return *this;
00934     copy(rhs);
00935     return *this;
00936     }
00937 
00938 #define routerlink_copy(var)    var = rhs.var;
00939 
00940     void copy(const RouterLink& rhs) {
00941     routerlink_copy(_type);
00942     routerlink_copy(_metric);
00943     switch (get_version()) {
00944     case OspfTypes::V2:
00945         routerlink_copy(_link_id);
00946         routerlink_copy(_link_data);
00947         break;
00948     case OspfTypes::V3:
00949         routerlink_copy(_interface_id);
00950         routerlink_copy(_neighbour_interface_id);
00951         routerlink_copy(_neighbour_router_id);
00952         break;
00953     }
00954     }
00955 #undef  routerlink_copy
00956     
00957 #define routerlink_compare(var) if (var != rhs.var) return false;
00958     bool operator==(const RouterLink& rhs) {
00959     routerlink_compare(_type);
00960     routerlink_compare(_metric);
00961     switch (get_version()) {
00962     case OspfTypes::V2:
00963         routerlink_compare(_link_id);
00964         routerlink_compare(_link_data);
00965         break;
00966     case OspfTypes::V3:
00967         routerlink_compare(_interface_id);
00968         routerlink_compare(_neighbour_interface_id);
00969         routerlink_compare(_neighbour_router_id);
00970         break;
00971     }
00972 
00973 
00974     return true;
00975     }
00976 #undef  routerlink_compare
00977 
00981     size_t length() const;
00982 
00992     RouterLink
00993     decode(uint8_t *ptr, size_t& len) const throw(InvalidPacket);
00994     
01002     size_t copy_out(uint8_t *to_uint8) const;
01003 
01004     OspfTypes::Version get_version() const {
01005     return _version;
01006     }
01007 
01008     // Type
01009     void set_type(Type t) {
01010     if (stub == t)
01011         XLOG_ASSERT(OspfTypes::V2 == get_version());
01012     _type = t;
01013     }
01014 
01015     Type get_type() const {
01016     return _type;
01017     }
01018 
01019     // Metric
01020     void set_metric(uint16_t metric) {
01021     _metric = metric;
01022     }
01023 
01024     uint16_t get_metric() const {
01025     return _metric;
01026     }
01027 
01028     // Link ID
01029     void set_link_id(uint32_t link_id) {
01030     XLOG_ASSERT(OspfTypes::V2 == get_version());
01031     _link_id = link_id;
01032     }
01033 
01034     uint32_t get_link_id() const {
01035     XLOG_ASSERT(OspfTypes::V2 == get_version());
01036     return _link_id;
01037     }
01038 
01039     // Link Data
01040     void set_link_data(uint32_t link_data) {
01041     XLOG_ASSERT(OspfTypes::V2 == get_version());
01042     _link_data = link_data;
01043     }
01044 
01045     uint32_t get_link_data() const {
01046     XLOG_ASSERT(OspfTypes::V2 == get_version());
01047     return _link_data;
01048     }
01049 
01050     // Interface ID
01051     void set_interface_id(uint32_t interface_id) {
01052     XLOG_ASSERT(OspfTypes::V3 == get_version());
01053     _interface_id = interface_id;
01054     }
01055 
01056     uint32_t get_interface_id() const {
01057     XLOG_ASSERT(OspfTypes::V3 == get_version());
01058     return _interface_id;
01059     }
01060 
01061     // Neighbour Interface ID
01062     void set_neighbour_interface_id(uint32_t neighbour_interface_id) {
01063     XLOG_ASSERT(OspfTypes::V3 == get_version());
01064     _neighbour_interface_id = neighbour_interface_id;
01065     }
01066 
01067     uint32_t get_neighbour_interface_id() const {
01068     XLOG_ASSERT(OspfTypes::V3 == get_version());
01069     return _neighbour_interface_id;
01070     }
01071 
01072     // Neighbour Router ID
01073     void set_neighbour_router_id(uint32_t neighbour_router_id) {
01074     XLOG_ASSERT(OspfTypes::V3 == get_version());
01075     _neighbour_router_id = neighbour_router_id;
01076     }
01077 
01078     uint32_t get_neighbour_router_id() const {
01079     XLOG_ASSERT(OspfTypes::V3 == get_version());
01080     return _neighbour_router_id;
01081     }
01082 
01086     string str() const;
01087 
01088  private:
01089     const OspfTypes::Version    _version;
01090 
01091     Type    _type;
01092     uint16_t    _metric;        // Only store TOS 0 metric
01093 
01094     uint32_t    _link_id;       // OSPFv2 Only
01095     uint32_t    _link_data;     // OSPFv2 Only
01096 
01097     uint32_t    _interface_id;      // OSPFv3 Only
01098     uint32_t    _neighbour_interface_id;// OSPFv3 Only
01099     uint32_t    _neighbour_router_id;   // OSPFv3 Only
01100 };
01101 
01102 class UnknownLsa : public Lsa {
01103 public:
01104     UnknownLsa(OspfTypes::Version version)
01105     : Lsa(version)
01106     {}
01107 
01108     UnknownLsa(OspfTypes::Version version, uint8_t *buf, size_t len)
01109     : Lsa(version, buf, len)
01110     {}
01114     size_t min_length() const {
01115     switch(get_version()) {
01116     case OspfTypes::V2:
01117         XLOG_FATAL("OSPFv3 only");
01118         break;
01119     case OspfTypes::V3:
01120         return 0;
01121         break;
01122     }
01123     XLOG_UNREACHABLE();
01124     return 0;
01125     }
01126 
01127     uint16_t get_ls_type() const {
01128     switch(get_version()) {
01129     case OspfTypes::V2:
01130         XLOG_FATAL("OSPFv3 only");
01131         break;
01132     case OspfTypes::V3:
01133         return _header.get_ls_type();
01134         break;
01135     }
01136     XLOG_UNREACHABLE();
01137     return 0;
01138     }
01139 
01146     bool known() const {
01147     XLOG_ASSERT(OspfTypes::V3 == get_version());
01148     return false;
01149     }
01150 
01159     LsaRef decode(uint8_t *buf, size_t& len) const throw(InvalidPacket);
01160 
01161     bool encode();
01162 
01166     const char *name() const {
01167     return "Unknown";
01168     }
01169 
01173     string str() const;
01174 };
01175 
01176 class RouterLsa : public Lsa {
01177  public:
01178     RouterLsa(OspfTypes::Version version)
01179     : Lsa(version), _nt_bit(false), _w_bit(false), _v_bit(false),
01180       _e_bit(false), _b_bit(false), _options(0)
01181     {
01182     _header.set_ls_type(get_ls_type());
01183     }
01184 
01185     RouterLsa(OspfTypes::Version version, uint8_t *buf, size_t len)
01186     : Lsa(version, buf, len)
01187     {}
01188 
01192     size_t min_length() const {
01193     switch(get_version()) {
01194     case OspfTypes::V2:
01195         return 4;
01196         break;
01197     case OspfTypes::V3:
01198         return 4;
01199         break;
01200     }
01201     XLOG_UNREACHABLE();
01202     return 0;
01203     }
01204 
01205     uint16_t get_ls_type() const {
01206     switch(get_version()) {
01207     case OspfTypes::V2:
01208         return 1;
01209         break;
01210     case OspfTypes::V3:
01211         return 0x2001;
01212         break;
01213     }
01214     XLOG_UNREACHABLE();
01215     return 0;
01216     }
01217 
01226     LsaRef decode(uint8_t *buf, size_t& len) const throw(InvalidPacket);
01227 
01228     bool encode();
01229 
01230     // NSSA translation
01231     void set_nt_bit(bool bit) {
01232     _nt_bit = bit;
01233     }
01234 
01235     bool get_nt_bit() const {
01236     return _nt_bit;
01237     }
01238 
01239     // Wildcard multicast receiver! OSPFv3 Only
01240     void set_w_bit(bool bit) {
01241     XLOG_ASSERT(OspfTypes::V3 == get_version());
01242     _w_bit = bit;
01243     }
01244 
01245     bool get_w_bit() const {
01246     XLOG_ASSERT(OspfTypes::V3 == get_version());
01247     return _w_bit;
01248     }
01249 
01250     // Virtual link endpoint
01251     void set_v_bit(bool bit) {
01252     _v_bit = bit;
01253     }
01254 
01255     bool get_v_bit() const {
01256     return _v_bit;
01257     }
01258 
01259     // AS boundary router (E for external)
01260     void set_e_bit(bool bit) {
01261     _e_bit = bit;
01262     }
01263 
01264     bool get_e_bit() const {
01265     return _e_bit;
01266     }
01267 
01268     // Area border router.
01269     void set_b_bit(bool bit) {
01270     _b_bit = bit;
01271     }
01272 
01273     bool get_b_bit() const {
01274     return _b_bit;
01275     }
01276 
01277     void set_options(uint32_t options) {
01278     XLOG_ASSERT(OspfTypes::V3 == get_version());
01279     if (options  > 0xffffff)
01280         XLOG_WARNING("Attempt to set %#x in a 24 bit field", options);
01281     _options = options & 0xffffff;
01282     }
01283 
01284     uint32_t get_options() const {
01285     XLOG_ASSERT(OspfTypes::V3 == get_version());
01286     return _options;
01287     }
01288 
01289     list<RouterLink>& get_router_links() {
01290     return _router_links;
01291     }
01292 
01296     const char *name() const {
01297     return "Router";
01298     }
01299 
01303     string str() const;
01304 
01305  private:
01306     bool _nt_bit;   // NSSA Translation.
01307     bool _w_bit;    // Wildcard multicast receiver! OSPFv3 Only
01308     bool _v_bit;    // Virtual link endpoint
01309     bool _e_bit;    // AS boundary router (E for external)
01310     bool _b_bit;    // Area border router.
01311 
01312     uint32_t _options;  // OSPFv3 only.
01313 
01314     list<RouterLink> _router_links;
01315 };
01316 
01317 class NetworkLsa : public Lsa {
01318  public:
01319     NetworkLsa(OspfTypes::Version version)
01320     : Lsa(version)
01321     {
01322     _header.set_ls_type(get_ls_type());
01323     }
01324 
01325     NetworkLsa(OspfTypes::Version version, uint8_t *buf, size_t len)
01326     : Lsa(version, buf, len)
01327     {}
01328 
01332     size_t min_length() const {
01333     switch(get_version()) {
01334     case OspfTypes::V2:
01335         return 8;
01336         break;
01337     case OspfTypes::V3:
01338         return 8;
01339         break;
01340     }
01341     XLOG_UNREACHABLE();
01342     return 0;
01343     }
01344 
01345     uint16_t get_ls_type() const {
01346     switch(get_version()) {
01347     case OspfTypes::V2:
01348         return 2;
01349         break;
01350     case OspfTypes::V3:
01351         return 0x2002;
01352         break;
01353     }
01354     XLOG_UNREACHABLE();
01355     return 0;
01356     }
01357 
01366     LsaRef decode(uint8_t *buf, size_t& len) const throw(InvalidPacket);
01367 
01368     bool encode();
01369 
01370     void set_options(uint32_t options) {
01371     XLOG_ASSERT(OspfTypes::V3 == get_version());
01372     if (options  > 0xffffff)
01373         XLOG_WARNING("Attempt to set %#x in a 24 bit field", options);
01374     _options = options & 0xffffff;
01375     }
01376 
01377     uint32_t get_options() const {
01378     XLOG_ASSERT(OspfTypes::V3 == get_version());
01379     return _options;
01380     }
01381 
01382     void set_network_mask(uint32_t network_mask) {
01383     XLOG_ASSERT(OspfTypes::V2 == get_version());
01384     _network_mask = network_mask;
01385     }
01386 
01387     uint32_t get_network_mask() const {
01388     XLOG_ASSERT(OspfTypes::V2 == get_version());
01389     return _network_mask;
01390     }
01391 
01392     list<OspfTypes::RouterID>& get_attached_routers() {
01393     return _attached_routers;
01394     }
01395 
01399     const char *name() const {
01400     return "Network";
01401     }
01402 
01406     string str() const;
01407     
01408  private:
01409     uint32_t _options;          // OSPFv3 only.
01410 
01411     uint32_t _network_mask;     // OSPFv2 only.
01412     list<OspfTypes::RouterID> _attached_routers;
01413 };
01414 
01419 class SummaryNetworkLsa : public Lsa {
01420  public:
01421     static const size_t IPV6_PREFIX_OFFSET = 28;
01422 
01423     SummaryNetworkLsa(OspfTypes::Version version)
01424     : Lsa(version), _ipv6prefix(version)
01425     {
01426     _header.set_ls_type(get_ls_type());
01427     }
01428 
01429     SummaryNetworkLsa(OspfTypes::Version version, uint8_t *buf, size_t len)
01430     : Lsa(version, buf, len), _ipv6prefix(version)
01431     {}
01432 
01436     size_t min_length() const {
01437     switch(get_version()) {
01438     case OspfTypes::V2:
01439         return 8;
01440         break;
01441     case OspfTypes::V3:
01442         return 8;
01443         break;
01444     }
01445     XLOG_UNREACHABLE();
01446     return 0;
01447     }
01448 
01449     uint16_t get_ls_type() const {
01450     switch(get_version()) {
01451     case OspfTypes::V2:
01452         return 3;
01453         break;
01454     case OspfTypes::V3:
01455         return 0x2003;
01456         break;
01457     }
01458     XLOG_UNREACHABLE();
01459     return 0;
01460     }
01461 
01470     LsaRef decode(uint8_t *buf, size_t& len) const throw(InvalidPacket);
01471 
01472     bool encode();
01473 
01474     void set_metric(uint32_t metric) {
01475     _metric = metric;
01476     }
01477 
01478     uint32_t get_metric() const {
01479     return _metric;
01480     }
01481 
01482     void set_network_mask(uint32_t network_mask) {
01483     XLOG_ASSERT(OspfTypes::V2 == get_version());
01484     _network_mask = network_mask;
01485     }
01486 
01487     uint32_t get_network_mask() const {
01488     XLOG_ASSERT(OspfTypes::V2 == get_version());
01489     return _network_mask;
01490     }
01491 
01492     void set_ipv6prefix(const IPv6Prefix& ipv6prefix) {
01493     XLOG_ASSERT(OspfTypes::V3 == get_version());
01494     _ipv6prefix = ipv6prefix;
01495     }
01496 
01497     IPv6Prefix get_ipv6prefix() const {
01498     XLOG_ASSERT(OspfTypes::V3 == get_version());
01499     return _ipv6prefix;;
01500     }
01501 
01505     const char *name() const {
01506     return "SummaryN";
01507     }
01508 
01512     string str() const;
01513     
01514  private:
01515     uint32_t _metric;
01516     uint32_t _network_mask;     // OSPFv2 only.
01517     IPv6Prefix _ipv6prefix;     // OSPFv3 only.
01518 };
01519 
01524 class SummaryRouterLsa : public Lsa {
01525  public:
01526     SummaryRouterLsa(OspfTypes::Version version)
01527     : Lsa(version)
01528     {
01529     _header.set_ls_type(get_ls_type());
01530     }
01531 
01532     SummaryRouterLsa(OspfTypes::Version version, uint8_t *buf, size_t len)
01533     : Lsa(version, buf, len)
01534     {}
01535 
01539     size_t min_length() const {
01540     switch(get_version()) {
01541     case OspfTypes::V2:
01542         return 8;
01543         break;
01544     case OspfTypes::V3:
01545         return 12;
01546         break;
01547     }
01548     XLOG_UNREACHABLE();
01549     return 0;
01550     }
01551 
01552     uint16_t get_ls_type() const {
01553     switch(get_version()) {
01554     case OspfTypes::V2:
01555         return 4;
01556         break;
01557     case OspfTypes::V3:
01558         return 0x2004;
01559         break;
01560     }
01561     XLOG_UNREACHABLE();
01562     return 0;
01563     }
01564 
01573     LsaRef decode(uint8_t *buf, size_t& len) const throw(InvalidPacket);
01574 
01575     bool encode();
01576 
01577     void set_options(uint32_t options) {
01578     XLOG_ASSERT(OspfTypes::V3 == get_version());
01579     if (options  > 0xffffff)
01580         XLOG_WARNING("Attempt to set %#x in a 24 bit field", options);
01581     _options = options & 0xffffff;
01582     }
01583 
01584     uint32_t get_options() const {
01585     XLOG_ASSERT(OspfTypes::V3 == get_version());
01586     return _options;
01587     }
01588 
01589     void set_metric(uint32_t metric) {
01590     _metric = metric;
01591     }
01592 
01593     uint32_t get_metric() const {
01594     return _metric;
01595     }
01596 
01597     void set_network_mask(uint32_t network_mask) {
01598     XLOG_ASSERT(OspfTypes::V2 == get_version());
01599     _network_mask = network_mask;
01600     }
01601 
01602     uint32_t get_network_mask() const {
01603     XLOG_ASSERT(OspfTypes::V2 == get_version());
01604     return _network_mask;
01605     }
01606 
01607     void set_destination_id(OspfTypes::RouterID destination_id) {
01608     XLOG_ASSERT(OspfTypes::V3 == get_version());
01609     _destination_id = destination_id;
01610     }
01611 
01612     OspfTypes::RouterID get_destination_id() const {
01613     XLOG_ASSERT(OspfTypes::V3 == get_version());
01614     return _destination_id;
01615     }
01616 
01620     const char *name() const {
01621     return "SummaryR";
01622     }
01623 
01627     string str() const;
01628     
01629  private:
01630     uint32_t _metric;
01631 
01632     uint32_t _network_mask;     // OSPFv2 only.
01633 
01634     uint8_t _options;           // OSPFv3 only.
01635     OspfTypes::RouterID _destination_id;// OSPFv3 only.
01636 };
01637 
01641 class ASExternalLsa : public Lsa {
01642  public:
01643     static const size_t IPV6_PREFIX_OFFSET = 28;
01644 
01645     ASExternalLsa(OspfTypes::Version version)
01646     : Lsa(version), _network_mask(0), _e_bit(false), _f_bit(false),
01647       _t_bit(false), _ipv6prefix(version), _referenced_ls_type(0),
01648       _metric(0), _external_route_tag(0), _referenced_link_state_id(0)
01649     {
01650     _header.set_ls_type(get_ls_type());
01651     }
01652 
01653     ASExternalLsa(OspfTypes::Version version, uint8_t *buf, size_t len)
01654     : Lsa(version, buf, len), _ipv6prefix(version)
01655     {}
01656 
01660     size_t min_length() const {
01661     switch(get_version()) {
01662     case OspfTypes::V2:
01663         return 16;
01664         break;
01665     case OspfTypes::V3:
01666         return 8;
01667         break;
01668     }
01669     XLOG_UNREACHABLE();
01670     return 0;
01671     }
01672 
01673     uint16_t get_ls_type() const {
01674     switch(get_version()) {
01675     case OspfTypes::V2:
01676         return 5;
01677         break;
01678     case OspfTypes::V3:
01679         return 0x4005;
01680         break;
01681     }
01682     XLOG_UNREACHABLE();
01683     return 0;
01684     }
01685 
01689     bool external() const {return true; };
01690 
01699     LsaRef decode(uint8_t *buf, size_t& len) const throw(InvalidPacket);
01700 
01701     bool encode();
01702 
01703     void set_network_mask(uint32_t network_mask) {
01704     XLOG_ASSERT(OspfTypes::V2 == get_version());
01705     _network_mask = network_mask;
01706     }
01707 
01708     uint32_t get_network_mask() const {
01709     XLOG_ASSERT(OspfTypes::V2 == get_version());
01710     return _network_mask;
01711     }
01712 
01713     void set_ipv6prefix(const IPv6Prefix& ipv6prefix) {
01714     XLOG_ASSERT(OspfTypes::V3 == get_version());
01715     _ipv6prefix = ipv6prefix;
01716     }
01717 
01718     IPv6Prefix get_ipv6prefix() const {
01719     XLOG_ASSERT(OspfTypes::V3 == get_version());
01720     return _ipv6prefix;;
01721     }
01722 
01723     template <typename A>
01724     void set_network(IPNet<A>);
01725 
01726     template <typename A>
01727     IPNet<A> get_network(A) const;
01728 
01729     void set_e_bit(bool bit) {
01730     _e_bit = bit;
01731     }
01732 
01733     bool get_e_bit() const {
01734     return _e_bit;
01735     }
01736 
01737     void set_f_bit(bool bit) {
01738     XLOG_ASSERT(OspfTypes::V3 == get_version());
01739     _f_bit = bit;
01740     }
01741 
01742     bool get_f_bit() const {
01743     XLOG_ASSERT(OspfTypes::V3 == get_version());
01744     return _f_bit;
01745     }
01746 
01747     void set_t_bit(bool bit) {
01748     XLOG_ASSERT(OspfTypes::V3 == get_version());
01749     _t_bit = bit;
01750     }
01751 
01752     bool get_t_bit() const {
01753     XLOG_ASSERT(OspfTypes::V3 == get_version());
01754     return _t_bit;
01755     }
01756 
01757     void set_referenced_ls_type(uint16_t referenced_ls_type) {
01758     XLOG_ASSERT(OspfTypes::V3 == get_version());
01759     _referenced_ls_type = referenced_ls_type;
01760     }
01761 
01762     uint16_t get_referenced_ls_type() const {
01763     XLOG_ASSERT(OspfTypes::V3 == get_version());
01764     return _referenced_ls_type;
01765     }
01766 
01767     void set_forwarding_address_ipv6(IPv6 forwarding_address_ipv6) {
01768     XLOG_ASSERT(OspfTypes::V3 == get_version());
01769     XLOG_ASSERT(_f_bit);
01770     _forwarding_address_ipv6 = forwarding_address_ipv6;
01771     }
01772 
01773     IPv6 get_forwarding_address_ipv6() const {
01774     XLOG_ASSERT(OspfTypes::V3 == get_version());
01775     XLOG_ASSERT(_f_bit);
01776     return _forwarding_address_ipv6;
01777     }
01778 
01779     void set_metric(uint32_t metric) {
01780     _metric = metric;
01781     }
01782 
01783     uint32_t get_metric() const {
01784     return _metric;
01785     }
01786 
01787     void set_forwarding_address_ipv4(IPv4 forwarding_address_ipv4) {
01788     XLOG_ASSERT(OspfTypes::V2 == get_version());
01789     _forwarding_address_ipv4 = forwarding_address_ipv4;
01790     }
01791 
01792     IPv4 get_forwarding_address_ipv4() const {
01793     XLOG_ASSERT(OspfTypes::V2 == get_version());
01794     return _forwarding_address_ipv4;
01795     }
01796 
01797     template <typename A>
01798     void set_forwarding_address(A);
01799 
01800     template <typename A>
01801     A get_forwarding_address(A) const;
01802 
01803     void set_external_route_tag(uint32_t external_route_tag) {
01804     switch(get_version()) {
01805     case OspfTypes::V2:
01806         break;
01807     case OspfTypes::V3:
01808         XLOG_ASSERT(_t_bit);
01809         break;
01810     }
01811     _external_route_tag = external_route_tag;
01812     }
01813 
01814     uint32_t get_external_route_tag() const {
01815     switch(get_version()) {
01816     case OspfTypes::V2:
01817         break;
01818     case OspfTypes::V3:
01819         XLOG_ASSERT(_t_bit);
01820         break;
01821     }
01822     return _external_route_tag;
01823     }
01824 
01825     void set_referenced_link_state_id(uint32_t referenced_link_state_id) {
01826     XLOG_ASSERT(OspfTypes::V3 == get_version());
01827     if (0 == _referenced_ls_type)
01828         XLOG_WARNING("Referenced LS Type is zero");
01829     _referenced_link_state_id = referenced_link_state_id;
01830     }
01831 
01832     uint32_t get_referenced_link_state_id() const {
01833     XLOG_ASSERT(OspfTypes::V3 == get_version());
01834     if (0 == _referenced_ls_type)
01835         XLOG_WARNING("Referenced LS Type is zero");
01836     return _referenced_link_state_id;
01837     }
01838 
01843     virtual ASExternalLsa *donew(OspfTypes::Version version, uint8_t *buf,
01844                  size_t len) const {
01845     return new ASExternalLsa(version, buf, len);
01846     }
01847 
01851     virtual string str_name() const {
01852     return "As-External-LSA";
01853     } 
01854 
01858     const char *name() const {
01859     return get_e_bit() ? "ASExt-2" : "ASExt-1";
01860     }
01861 
01862     void set_suppressed_lsa(Lsa::LsaRef lsar) {
01863     _suppressed_lsa = lsar;
01864     }
01865 
01866     Lsa::LsaRef get_suppressed_lsa() const {
01867     return _suppressed_lsa;
01868     }
01869 
01870     void release_suppressed_lsa() {
01871     _suppressed_lsa.release();
01872     }
01873 
01877     string str() const;
01878     
01879  private:
01880     uint32_t _network_mask;     // OSPFv2 only.
01881     bool _e_bit;
01882     bool _f_bit;            // OSPFv3 only.
01883     bool _t_bit;            // OSPFv3 only.
01884 
01885     IPv6Prefix _ipv6prefix;     // OSPFv3 only.
01886 
01887     uint16_t _referenced_ls_type;   // OSPFv3 only.
01888     IPv6 _forwarding_address;       // OSPFv3 only.
01889     
01890     uint32_t _metric;
01891     IPv4 _forwarding_address_ipv4;  // OSPFv2 only.
01892     IPv6 _forwarding_address_ipv6;  // OSPFv3 only.
01893     uint32_t _external_route_tag;
01894     uint32_t _referenced_link_state_id; // OSPFv3 only.
01895 
01896     Lsa::LsaRef _suppressed_lsa;    // If a self originated LSA is
01897                     // being suppressed here it is.
01898 };
01899 
01903 class Type7Lsa : public ASExternalLsa {
01904  public:
01905     Type7Lsa(OspfTypes::Version version) : ASExternalLsa(version)
01906     {
01907     _header.set_ls_type(get_ls_type());
01908     }
01909 
01910     Type7Lsa(OspfTypes::Version version, uint8_t *buf, size_t len)
01911     : ASExternalLsa(version, buf, len)
01912     {}
01913 
01914     uint16_t get_ls_type() const {
01915     switch(get_version()) {
01916     case OspfTypes::V2:
01917         return 7;
01918         break;
01919     case OspfTypes::V3:
01920         return 0x2007;
01921         break;
01922     }
01923     XLOG_UNREACHABLE();
01924     return 0;
01925     }
01926 
01930     bool external() const {return false; };
01931 
01935     bool type7() const { return true; }
01936 
01937     virtual ASExternalLsa *donew(OspfTypes::Version version, uint8_t *buf,
01938                  size_t len) const {
01939     return new Type7Lsa(version, buf, len);
01940     }
01941 
01945     string str_name() const {
01946     return "Type-7-LSA";
01947     } 
01948 
01952     const char *name() const {
01953     return get_e_bit() ? "Type7-2" : "Type7-1";
01954     }
01955 };
01956 
01960 class LinkLsa : public Lsa {
01961 public:
01962     LinkLsa(OspfTypes::Version version)
01963     : Lsa(version)
01964     {
01965     XLOG_ASSERT(OspfTypes::V3 == get_version());
01966     _header.set_ls_type(get_ls_type());
01967     }
01968 
01969     LinkLsa(OspfTypes::Version version, uint8_t *buf, size_t len)
01970     : Lsa(version, buf, len)
01971     {
01972     XLOG_ASSERT(OspfTypes::V3 == get_version());
01973     }
01974 
01978     size_t min_length() const {
01979     return 24;
01980     }
01981     
01982     uint16_t get_ls_type() const {
01983     return 8;
01984     }
01985 
01994     LsaRef decode(uint8_t *buf, size_t& len) const throw(InvalidPacket);
01995 
01996     bool encode();
01997 
01998     void set_rtr_priority(uint8_t rtr_priority) {
01999     _rtr_priority = rtr_priority;
02000     }
02001 
02002     uint8_t get_rtr_priority() const {
02003     return _rtr_priority;
02004     }
02005 
02006     void set_options(uint32_t options) {
02007     if (options  > 0xffffff)
02008         XLOG_WARNING("Attempt to set %#x in a 24 bit field", options);
02009     _options = options & 0xffffff;
02010     }
02011 
02012     uint32_t get_options() const {
02013     return _options;
02014     }
02015 
02016     void set_link_local_address(IPv6 link_local_address) {
02017     _link_local_address = link_local_address;
02018     }
02019 
02020     IPv6 get_link_local_address() const {
02021     return _link_local_address;
02022     }
02023 
02024     const list<IPv6Prefix>& get_prefixes() const {
02025     return _prefixes;
02026     }
02027 
02028     list<IPv6Prefix>& get_prefixes() {
02029     return _prefixes;
02030     }
02031 
02035     const char *name() const {
02036     return "Link";
02037     }
02038 
02042     string str() const;
02043     
02044 private:
02045     uint8_t _rtr_priority;
02046     uint32_t _options;
02047     IPv6 _link_local_address;
02048     
02049     list<IPv6Prefix> _prefixes;
02050 };
02051 
02055 class IntraAreaPrefixLsa : public Lsa {
02056 public:
02057     IntraAreaPrefixLsa(OspfTypes::Version version)
02058     : Lsa(version)
02059     {
02060     XLOG_ASSERT(OspfTypes::V3 == get_version());
02061     _header.set_ls_type(get_ls_type());
02062     }
02063 
02064     IntraAreaPrefixLsa(OspfTypes::Version version, uint8_t *buf, size_t len)
02065     : Lsa(version, buf, len)
02066     {
02067     XLOG_ASSERT(OspfTypes::V3 == get_version());
02068     }
02069 
02073     size_t min_length() const {
02074     return 12;
02075     }
02076     
02077     uint16_t get_ls_type() const {
02078     return 0x2009;
02079     }
02080 
02089     LsaRef decode(uint8_t *buf, size_t& len) const throw(InvalidPacket);
02090 
02091     bool encode();
02092 
02093     void set_referenced_ls_type(uint16_t referenced_ls_type) {
02094     _referenced_ls_type = referenced_ls_type;
02095     }
02096 
02097     uint16_t get_referenced_ls_type() const {
02098     return _referenced_ls_type;
02099     }
02100 
02101     void set_referenced_link_state_id(uint32_t referenced_link_state_id) {
02102     _referenced_link_state_id = referenced_link_state_id;
02103     }
02104 
02105     uint32_t get_referenced_link_state_id() const {
02106     return _referenced_link_state_id;
02107     }
02108 
02109     void set_referenced_advertising_router(uint32_t referenced_adv_router) {
02110     _referenced_advertising_router = referenced_adv_router;
02111     }
02112 
02113     uint32_t get_referenced_advertising_router() const {
02114     return _referenced_advertising_router;
02115     }
02116 
02117     list<IPv6Prefix>& get_prefixes() {
02118     return _prefixes;
02119     }
02120 
02137     uint32_t create_link_state_id(uint16_t ls_type, uint32_t interface_id)
02138     const
02139     {
02140     XLOG_ASSERT(OspfTypes::V3 == get_version());
02141 
02142     if (RouterLsa(get_version()).get_ls_type() == ls_type) {
02143         return OspfTypes::UNUSED_INTERFACE_ID;
02144     } else if (NetworkLsa(get_version()).get_ls_type() == ls_type) {
02145         return interface_id;
02146     } else {
02147         XLOG_FATAL("Unknown LS Type %#x\n", ls_type);
02148     }
02149 
02150     return 0;
02151     }
02152 
02156     const char *name() const {
02157     return "IntraArPfx";
02158     }
02159 
02163     string str() const;
02164     
02165 private:
02166     uint16_t _referenced_ls_type;
02167     uint32_t _referenced_link_state_id;
02168     uint32_t _referenced_advertising_router;
02169     list<IPv6Prefix> _prefixes;
02170 };
02171 
02172 #if 0
02173 class LsaTransmit : class Transmit {
02174  public:
02175     bool valid();
02176 
02177     bool multiple() { return false;}
02178 
02179     Transmit *clone();
02180 
02181     uint8_t *generate(size_t &len);
02182  private:
02183     LsaRef _lsaref; // LSA.
02184 }
02185 #endif
02186 
02191 class Ls_request {
02192  public:
02193     Ls_request(OspfTypes::Version version) :
02194     _version(version),  _ls_type(0),_link_state_id(0),
02195     _advertising_router(0)
02196     {}
02197 
02198     Ls_request(OspfTypes::Version version, uint32_t ls_type,
02199            uint32_t link_state_id, uint32_t advertising_router) :
02200     _version(version),  _ls_type(ls_type),_link_state_id(link_state_id),
02201     _advertising_router(advertising_router)
02202     {}
02203     
02204     Ls_request(const Ls_request& rhs) {
02205     copy(rhs);
02206     }
02207 
02208     Ls_request operator=(const Ls_request& rhs) {
02209     if(&rhs == this)
02210         return *this;
02211     copy(rhs);
02212     return *this;
02213     }
02214 
02215 #define ls_copy(var)    var = rhs.var;
02216 
02217     void copy(const Ls_request& rhs) {
02218     ls_copy(_version);
02219     ls_copy(_ls_type);
02220     ls_copy(_link_state_id);
02221     ls_copy(_advertising_router);
02222     }
02223 #undef  ls_copy
02224     
02228     static size_t length() { return 12; }
02229     
02233     Ls_request
02234     decode(uint8_t *ptr) throw(InvalidPacket);
02235 
02240     size_t copy_out(uint8_t *to_uint8) const;
02241 
02242     OspfTypes::Version get_version() const {
02243     return _version;
02244     }
02245     
02246     // LS type
02247     void set_ls_type(uint32_t ls_type) {
02248     switch(get_version()) {
02249     case OspfTypes::V2:
02250         _ls_type = ls_type;
02251         break;
02252     case OspfTypes::V3:
02253         if (ls_type > 0xffff)
02254         XLOG_WARNING("Attempt to set %#x in an 16 bit field",
02255                  ls_type);
02256         _ls_type = ls_type & 0xffff;
02257         break;
02258     }
02259     }
02260 
02261     uint32_t get_ls_type() const {
02262     return _ls_type;
02263     }
02264 
02265     // Link State ID
02266     void set_link_state_id(uint32_t link_state_id) {
02267     _link_state_id = link_state_id;
02268     }
02269 
02270     uint32_t get_link_state_id() const {
02271     return _link_state_id;
02272     }
02273     
02274     // Advertising Router
02275     void set_advertising_router(uint32_t advertising_router) {
02276     _advertising_router = advertising_router;
02277     }
02278 
02279     uint32_t get_advertising_router() const {
02280     return _advertising_router;
02281     }
02282 
02286     string str() const;
02287     
02288  private:
02289     OspfTypes::Version _version;
02290     uint32_t    _ls_type;   // OSPFv2 4 bytes, OSPFv3 2 bytes.
02291     uint32_t    _link_state_id;
02292     uint32_t    _advertising_router;
02293 };
02294 
02299 inline
02300 void
02301 initialise_lsa_decoder(OspfTypes::Version version, LsaDecoder& lsa_decoder)
02302 {
02303     switch(version) {
02304     case OspfTypes::V2:
02305     break;
02306     case OspfTypes::V3:
02307     lsa_decoder.register_unknown_decoder(new UnknownLsa(version));
02308     break;
02309     }
02310 
02311     lsa_decoder.register_decoder(new RouterLsa(version));
02312     lsa_decoder.register_decoder(new NetworkLsa(version));
02313     lsa_decoder.register_decoder(new SummaryNetworkLsa(version));
02314     lsa_decoder.register_decoder(new SummaryRouterLsa(version));
02315     lsa_decoder.register_decoder(new ASExternalLsa(version));
02316     lsa_decoder.register_decoder(new Type7Lsa(version));
02317     switch(version) {
02318     case OspfTypes::V2:
02319     break;
02320     case OspfTypes::V3:
02321     lsa_decoder.register_decoder(new LinkLsa(version));
02322     lsa_decoder.register_decoder(new IntraAreaPrefixLsa(version));
02323     break;
02324     }
02325 }
02326 
02331 inline
02332 IPNet<IPv4>
02333 lsa_to_net(uint32_t lsid, uint32_t mask)
02334 {
02335     IPv4 prefix = IPv4(htonl(mask));
02336     IPNet<IPv4> net = IPNet<IPv4>(IPv4(htonl(lsid)), prefix.mask_len());
02337 
02338     return net;
02339 }
02340 
02345 inline
02346 uint32_t
02347 set_host_bits(uint32_t lsid, uint32_t mask)
02348 {
02349     return lsid | ~mask;
02350 }
02351 
02352 #endif // __OSPF_LSA_HH__
 All Classes Namespaces Functions Variables Typedefs Enumerations