📄 packets.hh
字号:
uint8_t key_id() const { return extract_8(_key_id); } uint8_t auth_bytes() const { return extract_8(_auth_bytes); } uint32_t seqno() const { return extract_32(_seqno); } static const uint16_t ADDR_FAMILY = 0xffff; static const uint16_t AUTH_TYPE = 3;protected: // Sizes of the fields static const size_t _af_sizeof = 2; static const size_t _auth_sizeof = 2; static const size_t _auth_off_sizeof = 2; static const size_t _key_id_sizeof = 1; static const size_t _auth_bytes_sizeof = 1; static const size_t _seqno_sizeof = 4; static const size_t _mbz_sizeof = 8; // Offsets for the fields static const size_t _af_offset = 0; static const size_t _auth_offset = _af_offset + _af_sizeof; static const size_t _auth_off_offset = _auth_offset + _auth_sizeof; static const size_t _key_id_offset = _auth_off_offset + _auth_off_sizeof; static const size_t _auth_bytes_offset = _key_id_offset + _key_id_sizeof; static const size_t _seqno_offset = _auth_bytes_offset + _auth_bytes_sizeof; static const size_t _mbz_offset = _seqno_offset + _seqno_sizeof;private: const uint8_t* _data; // The buffer data // Pointers to the fields const uint8_t* _af; // 0xffff - Authentication header const uint8_t* _auth; // Authentication type const uint8_t* _auth_off; // Offset of authentication data const uint8_t* _key_id; // Key number used const uint8_t* _auth_bytes; // Auth data length at end of packet const uint8_t* _seqno; // Monotonically increasing seqno const uint8_t* _mbz; // Must-be-zero};/** * @short Class for writing data to MD5 authentication entry. */class MD5PacketRouteEntry4Writer : public MD5PacketRouteEntry4 {public: MD5PacketRouteEntry4Writer(uint8_t* data) : MD5PacketRouteEntry4(data), _data(data), _af(_data + _af_offset), _auth(_data + _auth_offset), _auth_off(_data + _auth_off_offset), _key_id(_data + _key_id_offset), _auth_bytes(_data + _auth_bytes_offset), _seqno(_data + _seqno_offset), _mbz(_data + _mbz_offset) {} void set_auth_off(uint16_t b) { embed_16(_auth_off, b); } void set_key_id(uint8_t id) { embed_8(_key_id, id); } void set_auth_bytes(uint8_t b) { embed_8(_auth_bytes, b); } void set_seqno(uint32_t sno) { embed_32(_seqno, sno); } /** * Initialize the entry. */ void initialize(uint16_t pkt_bytes, uint8_t key_id, uint8_t auth_bytes, uint32_t seqno);private: uint8_t* _data; // The buffer data // Pointers to the fields uint8_t* _af; // 0xffff - Authentication header uint8_t* _auth; // Authentication type uint8_t* _auth_off; // Offset of authentication data uint8_t* _key_id; // Key number used uint8_t* _auth_bytes; // Auth data length at end of packet uint8_t* _seqno; // Monotonically increasing seqno uint8_t* _mbz; // Must-be-zero};inline voidMD5PacketRouteEntry4Writer::initialize(uint16_t auth_off, uint8_t key_id, uint8_t auth_bytes, uint32_t seqno){ embed_16(_af, ADDR_FAMILY); embed_16(_auth, AUTH_TYPE); set_auth_off(auth_off); set_key_id(key_id); set_auth_bytes(auth_bytes); set_seqno(seqno); memset(_mbz, 0, _mbz_sizeof);}/** * @short Container for MD5 trailer. * * THE MD5 authentication trailer has the following content: * * af (2 bytes): // 0xffff - Authentication header * one (2 bytes): // 0x01 - RFC2082 defined * auth_data (16 bytes); // 16 bytes of data */class MD5PacketTrailer {public: MD5PacketTrailer(const uint8_t* data) : _data(data), _af(_data + _af_offset), _one(_data + _one_offset), _auth_data(_data + _auth_data_offset) { static_assert(MD5PacketTrailer::SIZE == _af_sizeof + _one_sizeof + _auth_data_sizeof); static_assert(MD5PacketTrailer::SIZE == _auth_data_offset + _auth_data_sizeof); } static const size_t SIZE = 20; // The trailer size /** * Get the RIP IPv4 MD5 authentication trailer size. * * @return the RIP IPv4 MD5 authentication trailer size. */ static size_t size() { return MD5PacketTrailer::SIZE; } uint16_t addr_family() const { return extract_16(_af); } const uint8_t* auth_data() const { return _auth_data; } uint32_t auth_data_bytes() const { return _auth_data_sizeof; } uint32_t auth_data_offset() const { return _auth_data_offset; } bool valid() const;protected: // Sizes of the fields static const size_t _af_sizeof = 2; static const size_t _one_sizeof = 2; static const size_t _auth_data_sizeof = 16; // Offsets for the fields static const size_t _af_offset = 0; static const size_t _one_offset = _af_offset + _af_sizeof; static const size_t _auth_data_offset = _one_offset + _one_sizeof;private: const uint8_t* _data; // The buffer data // Pointers to the fields const uint8_t* _af; // 0xffff - Authentication header const uint8_t* _one; // 0x01 - RFC2082 defined const uint8_t* _auth_data; // 16 bytes of data};inline boolMD5PacketTrailer::valid() const{ return (addr_family() == 0xffff) && (extract_16(_one) == 1);}/** * @short Class for writing data to MD5 authentication trailer. */class MD5PacketTrailerWriter : public MD5PacketTrailer {public: MD5PacketTrailerWriter(uint8_t* data) : MD5PacketTrailer(data), _data(data), _af(_data + _af_offset), _one(_data + _one_offset), _auth_data(_data + _auth_data_offset) {} /** * Initialize the entry. */ void initialize(); uint8_t* auth_data() { return _auth_data; }private: uint8_t* _data; // The buffer data // Pointers to the fields uint8_t* _af; // 0xffff - Authentication header uint8_t* _one; // 0x01 - RFC2082 defined uint8_t* _auth_data; // 16 bytes of data};inline voidMD5PacketTrailerWriter::initialize(){ embed_16(_af, 0xffff); embed_16(_one, 1);}/** * @short Route Entry appearing in RIP packets on IPv6. * * This payload is carried in RIP packets on IPv6. The interpretation * of the fields is defined in RFC2080. * * All fields in this structure are stored in network order. * * The route entry has the following content: * * prefix (16 bytes): // Prefix * tag (2 bytes): // Tag * prefix_len (1 byte): // Prefix length * metric (1 byte): // Metric */template <>class PacketRouteEntry<IPv6> {public: PacketRouteEntry(const uint8_t* data) : _data(data), _prefix(_data + _prefix_offset), _tag(_data + _tag_offset), _prefix_len(_data + _prefix_len_offset), _metric(_data + _metric_offset) { static_assert(PacketRouteEntry<IPv6>::SIZE == _prefix_sizeof + _tag_sizeof + _prefix_len_sizeof + _metric_sizeof); static_assert(PacketRouteEntry<IPv6>::SIZE == _metric_offset + _metric_sizeof); } static const size_t SIZE = 20; // The entry size /** * Get the RIP IPv6 route entry size. * * @return the RIP IPv6 route entry size. */ static size_t size() { return PacketRouteEntry<IPv6>::SIZE; } bool is_nexthop() const; /** * @return true if route entry has properties of a table request. */ bool is_table_request() const; IPv6 nexthop() const; uint16_t tag() const; uint32_t prefix_len() const { return extract_8(_prefix_len); } IPv6Net net() const; uint8_t metric() const; static const uint8_t NEXTHOP_METRIC = 0xff;protected: // Sizes of the fields static const size_t _prefix_sizeof = 16; static const size_t _tag_sizeof = 2; static const size_t _prefix_len_sizeof = 1; static const size_t _metric_sizeof = 1; // Offsets for the fields static const size_t _prefix_offset = 0; static const size_t _tag_offset = _prefix_offset + _prefix_sizeof; static const size_t _prefix_len_offset = _tag_offset + _tag_sizeof; static const size_t _metric_offset = _prefix_len_offset + _prefix_len_sizeof;private: const uint8_t* _data; // The buffer data // Pointers to the fields const uint8_t* _prefix; const uint8_t* _tag; const uint8_t* _prefix_len; const uint8_t* _metric;};inline boolPacketRouteEntry<IPv6>::is_nexthop() const{ return metric() == NEXTHOP_METRIC;}inline IPv6PacketRouteEntry<IPv6>::nexthop() const{ return IPv6(_prefix);}inline uint16_tPacketRouteEntry<IPv6>::tag() const{ return extract_16(_tag);}inline IPv6NetPacketRouteEntry<IPv6>::net() const{ return IPv6Net(IPv6(_prefix), prefix_len());}inline uint8_tPacketRouteEntry<IPv6>::metric() const{ return extract_8(_metric);}inline boolPacketRouteEntry<IPv6>::is_table_request() const{ if (metric() != RIP_INFINITY) { return false; } if (prefix_len() != 0) { return false; } IPv6 addr(_prefix); return (addr.is_zero());}/* * @short Class for writing data to RIP IPv6 route entry. */template <>class PacketRouteEntryWriter<IPv6> : public PacketRouteEntry<IPv6> {public: PacketRouteEntryWriter(uint8_t* data) : PacketRouteEntry<IPv6>(data), _data(data), _prefix(_data + _prefix_offset), _tag(_data + _tag_offset), _prefix_len(_data + _prefix_len_offset), _metric(_data + _metric_offset) {} /** * Initialize fields as a regular routing entry. */ void initialize_route(uint16_t route_tag, const IPv6Net& net, uint8_t cost); /** * Initialize fields as a nexthop entry. */ void initialize_nexthop(const IPv6& nexthop); /** * Initialize fields as a route table request. */ void initialize_table_request();private: uint8_t* _data; // The buffer data // Pointers to the fields uint8_t* _prefix; uint8_t* _tag; uint8_t* _prefix_len; uint8_t* _metric;};inline voidPacketRouteEntryWriter<IPv6>::initialize_route(uint16_t tag, const IPv6Net& net, uint8_t cost){ net.masked_addr().copy_out(_prefix); embed_16(_tag, tag); embed_8(_prefix_len, net.prefix_len()); embed_8(_metric, cost);}inline voidPacketRouteEntryWriter<IPv6>::initialize_nexthop(const IPv6& nexthop){ nexthop.copy_out(_prefix); embed_16(_tag, 0); embed_8(_prefix_len, 0); embed_8(_metric, NEXTHOP_METRIC);}inline voidPacketRouteEntryWriter<IPv6>::initialize_table_request(){ IPv6::ZERO().copy_out(_prefix); embed_16(_tag, 0); embed_8(_prefix_len, 0); embed_8(_metric, RIP_INFINITY);}/** * @short RIP Packet class. * * A container for RIP packet, provides easy to use accessors and modifiers. */template <typename A>class RipPacket {public: typedef A Addr; /** * @return destination address of packet. */ const Addr& address() const { return _addr; } /** * @return destination port of packet. */ uint16_t port() const { return _port; } /** * @return the maximum number of route entries packet may have. */ uint32_t max_entries() const { return _max_entries; } /** * Set the maximum number of route entries a packet may have. * This method should be called before using @ref append_data * methods as it resizes the internal storage and will cause * appended data to be lost. */ void set_max_entries(uint32_t max_entries); RipPacket(const Addr& addr, uint16_t port, uint32_t max_entries = RIPv2_ROUTES_PER_PACKET) : _addr(addr), _port(port), _max_entries(0) { set_max_entries(max_entries); } /** * @return const pointer to the beginning of the RIP packet header. */ const uint8_t* header_ptr() const; /** * @return pointer to the beginning of the RIP packet header. */ uint8_t* header_ptr(); /** * Route entry accessor. * * @param entry_no index of route entry to retrive. * @return const pointer to route entry, or 0 if entry_no is greater than * the maximum route entries associated with packet. */ const uint8_t* route_entry_ptr(uint32_t entry_no) const; /** * Route entry accessor. * * @param entry_no index of route entry to retrive. * @return pointer to route entry, or 0 if entry_no is greater than * the maximum route entries associated with packet. */ uint8_t* route_entry_ptr(uint32_t entry_no); void append_data(const uint8_t* data, uint32_t data_bytes); void append_data(const vector<uint8_t>& data); vector<uint8_t>& data() { return _data; } const vector<uint8_t>& data() const { return _data; } uint32_t data_bytes() const { return _data.size(); } const uint8_t* data_ptr() const { return base_ptr(); } uint8_t* data_ptr() { return base_ptr(); }private: Addr _addr; // Src addr on inbound, dst address on outbound uint16_t _port; // Src port on inbound, dst port on outbound vector<uint8_t> _data; // Data buffer uint32_t _max_entries; // Maximum number of route entries in packet const uint8_t* base_ptr() const { return &(_data[0]); } uint8_t* base_ptr() { return &(_data[0]); }};template <typename A>const uint8_t*RipPacket<A>::header_ptr() const{ return (base_ptr());}template <typename A>uint8_t*RipPacket<A>::header_ptr(){ return (base_ptr());}template <typename A>const uint8_t*RipPacket<A>::route_entry_ptr(uint32_t entry_no) const{ if (entry_no >= _max_entries) return NULL; const uint8_t* p = base_ptr() + RipPacketHeader::size() + entry_no * PacketRouteEntry<A>::size(); return p;}template <typename A>uint8_t*RipPacket<A>::route_entry_ptr(uint32_t entry_no){ if (entry_no >= _max_entries) return NULL; uint8_t* p = base_ptr() + RipPacketHeader::size() + entry_no * PacketRouteEntry<A>::size(); return p;}template <typename A>voidRipPacket<A>::append_data(const uint8_t* data, uint32_t data_bytes){ _data.insert(_data.end(), data, data + data_bytes);}template <typename A>voidRipPacket<A>::append_data(const vector<uint8_t>& data){ _data.insert(_data.end(), data.begin(), data.end());}template <typename A>voidRipPacket<A>::set_max_entries(uint32_t max_entries){ if (max_entries != _max_entries) { _data.resize(PacketRouteEntry<A>::size() * max_entries + RipPacketHeader::size()); _max_entries = max_entries; }}#endif // __RIP_PACKETS_HH__
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -