⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 packets.hh

📁 RIP 协议实现
💻 HH
📖 第 1 页 / 共 2 页
字号:
    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 + -