00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef QOLYESTER_DAEMON_MSG_HNA_HXX
00020 # define QOLYESTER_DAEMON_MSG_HNA_HXX 1
00021
00022 # include "set/gate.hh"
00023 # include "set/hna.hh"
00024 # include "set/neighbors.hh"
00025 # include "utl/args.hh"
00026
00027 # include "hna.hh"
00028
00029 namespace olsr {
00030
00031 extern std::ostream dump_hna;
00032 extern gateset_t gate_set;
00033 extern hnaset_t hna_set;
00034
00035 namespace msg {
00036
00037 HNAMessage::HNAMessage() : _data() {}
00038
00039 HNAMessage::HNAMessage(const utl::Data& d) : _data(d) {}
00040
00041 bool
00042 HNAMessage::dump(utl::Data& d, const address_t& interface) const {
00043 bool ret = false;
00044
00045 if (_data.empty()) {
00046
00047 assert(!gate_set.empty());
00048
00049 if (d.size() < Message::min_length + min_length)
00050 return true;
00051
00052 if (do_dump_hna)
00053 dump_hna << "HNA preparation (" << interface << ") "
00054 << Message::seqnum << " {\n";
00055
00056 Message::raw* mraw = reinterpret_cast<Message::raw*>(d.raw());
00057
00058 d += sizeof *mraw;
00059
00060 mraw->type = HNA_MESSAGE;
00061 mraw->vtime = utl::Vtime(cst::hna_hold_time);
00062 mraw->size = 0;
00063 main_addr.dump(mraw->addr);
00064 mraw->ttl = 255;
00065 mraw->hopcount = 0;
00066 mraw->seqnum = htons(Message::seqnum);
00067
00068 typedef std::list<gateset_t::hna_gset_t::iterator> hset_t;
00069 hset_t h_set;
00070
00071 # ifdef QOLYESTER_ENABLE_NUMPREFIX
00072 for (gateset_t::hna_gset_t::iterator i =
00073 gate_set.hna_gset().begin(interface);
00074 i != gate_set.hna_gset().end(interface);
00075 d += ADDRESS_SIZE + sizeof (HNAMessage::raw), ++i) {
00076
00077 if (gate_set.hna_gset().stamp(i) == timeval_t::now())
00078 break;
00079
00080 if (d.size() < ADDRESS_SIZE + sizeof (HNAMessage::raw)) {
00081 if (gate_set.hna_gset().expired(i,
00082 cst::hna_interval,
00083 timeval_t::in(cst::hna_interval)))
00084 ret = true;
00085 break;
00086 }
00087
00088 if (do_dump_hna)
00089 dump_hna << " " << i->net_addr() << '/' << i->prefix() << '\n';
00090
00091 HNAMessage::raw* hnaraw = reinterpret_cast<HNAMessage::raw*>(d.raw());
00092 i->net_addr().dump(hnaraw->addr);
00093 hnaraw->prefix = htons(i->prefix());
00094 hnaraw->reserved0 = 0;
00095
00096 h_set.push_back(i);
00097 }
00098 # else
00099 for (gateset_t::hna_gset_t::iterator i =
00100 gate_set.hna_gset().begin(interface);
00101 i != gate_set.hna_gset().end(interface);
00102 d += ADDRESS_SIZE * 2, ++i) {
00103
00104 if (gate_set.hna_gset().stamp(i) == timeval_t::now())
00105 break;
00106
00107 if (d.size() < ADDRESS_SIZE * 2) {
00108 if (gate_set.hna_gset().expired(i,
00109 cst::hna_interval,
00110 timeval_t::in(cst::hna_interval)))
00111 ret = true;
00112 break;
00113 }
00114
00115 if (do_dump_hna)
00116 dump_hna << " " << i->net_addr() << '/' << i->prefix() << '\n';
00117
00118 i->net_addr().dump(d.raw());
00119 i->netmask_addr().dump((d + ADDRESS_SIZE).raw());
00120
00121 h_set.push_back(i);
00122 }
00123 # endif
00124
00125 mraw->size = htons(d.raw() - reinterpret_cast<u_int8_t*>(mraw));
00126
00127 for (hset_t::const_iterator i = h_set.begin();
00128 i != h_set.end(); ++i)
00129 gate_set.hna_gset().set_stamp(*i);
00130
00131 if (do_dump_hna)
00132 dump_hna << '}' << std::endl;
00133
00134 } else {
00135
00136 if (d.size() < _data.size())
00137 return true;
00138
00139 _data.dump(d);
00140 d += _data.size();
00141 }
00142
00143 return ret;
00144 }
00145
00146 void
00147 HNAMessage::parse(const utl::ConstData& d, const Message::header& mh) {
00148 if (do_dump_hna)
00149 dump_hna << "HNA from " << mh.originator
00150 << " (" << mh.sender << " -> " << mh.receiver << ") M("
00151 << mh.mseqnum << ") P(" << mh.pseqnum << ") {\n";
00152
00153 cproxy_t::linkset_t::iterator l =
00154 cproxy.linkset().find(set::Link::make_key(mh.receiver, mh.sender));
00155
00156 if (l == cproxy.linkset().end() || !l->is_sym()) {
00157
00158 if (do_dump_hna)
00159 dump_hna << " (ignored since not from symmetric neighbor)\n}"
00160 << std::endl;
00161 return;
00162 }
00163
00164 # ifdef QOLYESTER_ENABLE_NUMPREFIX
00165 const HNAMessage::raw* hraw = reinterpret_cast<const HNAMessage::raw*>(d.raw());
00166
00167 unsigned len = d.size() / sizeof (HNAMessage::raw);
00168
00169 for (unsigned i = 0; i < len; ++i) {
00170 address_t net_addr(hraw[i].addr, ADDRESS_SIZE);
00171 unsigned prefix = ntohs(hraw[i].prefix);
00172 if (prefix > ADDRESS_SIZE * 8)
00173 prefix = ADDRESS_SIZE * 8;
00174
00175 if (do_dump_hna)
00176 dump_hna << " " << net_addr << '/' << prefix << '\n';
00177
00178 hna_set.insert(set::HNAEntry(mh.originator,
00179 net_addr,
00180 prefix,
00181 mh.validity));
00182 }
00183 # else
00184 const u_int8_t (*addrs)[ADDRESS_SIZE] =
00185 reinterpret_cast<const u_int8_t (*)[ADDRESS_SIZE]>(d.raw());
00186 unsigned len = d.size() / ADDRESS_SIZE;
00187
00188 for (unsigned i = 0; i < len; i += 2) {
00189 address_t net_addr(addrs[i], ADDRESS_SIZE);
00190 unsigned prefix =
00191 address_t::netmask_to_prefix(address_t(addrs[i + 1], ADDRESS_SIZE));
00192
00193 if (do_dump_hna)
00194 dump_hna << " " << net_addr << '/' << prefix << '\n';
00195
00196 hna_set.insert(set::HNAEntry(mh.originator,
00197 net_addr,
00198 prefix,
00199 mh.validity));
00200 }
00201 # endif
00202
00203 if (do_dump_hna)
00204 dump_hna << '}' << std::endl;
00205 }
00206
00207 }
00208
00209 }
00210
00211 #endif // ! QOLYESTER_DAEMON_MSG_HNA_HXX