Source: ../../rip/packets.hh
|
|
|
|
// -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*-
// Copyright (c) 2001-2003 International Computer Science Institute
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software")
// to deal in the Software without restriction, subject to the conditions
// listed in the XORP LICENSE file. These conditions include: you must
// preserve this copyright notice, and you cannot mention the copyright
// holders in advertising related to the Software without their permission.
// The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This
// notice is a summary of the XORP LICENSE file; the license in that file is
// legally binding.
// $XORP: xorp/rip/packets.hh,v 1.4 2003/04/23 17:06:48 hodson Exp $
#ifndef __RIP_PACKETS_HH__
#define __RIP_PACKETS_HH__
#include "libxorp/ipv4.hh"
#include "libxorp/ipv4net.hh"
#include "libxorp/ipv6.hh"
#include "libxorp/ipv6net.hh"
#include "constants.hh"
/**
* @short Header appearing at the start of each RIP packet.
*/
struct RipPacketHeader {
uint8_t command; // 1 - request, 2 - response
uint8_t version; // 1 - IPv4 RIPv1/IPv6 RIPng, 2 - IPv4 RIP v2
uint8_t unused[2];
inline void initialize(uint8_t cmd, uint8_t vers);
inline bool valid_command() const;
inline bool valid_version(uint8_t v) const { return version == v; }
inline bool valid_padding() const;
static const uint8_t REQUEST = 1;
static const uint8_t RESPONSE = 2;
};
inline void
RipPacketHeader::initialize(uint8_t cmd, uint8_t vers)
{
command = cmd;
version = vers;
unused[0] = unused[1] = 0;
}
inline bool
RipPacketHeader::valid_command() const
{
return command == REQUEST || command == RESPONSE;
}
inline bool
RipPacketHeader::valid_padding() const
{
return (unused[0] | unused[1]) == 0;
}
/**
* @short Route Entry as it appears in a RIP Packet.
*
* This structure is useful only it's specialized forms
* @ref PacketRouteEntry<IPv4> and @ref PacketRouteEntry<IPv6>.
*/
template <typename A>
struct PacketRouteEntry {
};
/**
* Smallest RIPv2 packet size.
*/
static const size_t RIPv2_MIN_PACKET_BYTES = 4;
/**
* Smallest authenticated RIPv2 packet size.
*/
static const size_t RIPv2_MIN_AUTH_PACKET_BYTES = 4 + 20;
/**
* Largest RIPv2 packet size.
*/
static const size_t RIPv2_MAX_PACKET_BYTES = 4 + 20 * RIPv2_ROUTES_PER_PACKET;
/**
* @short Route Entry appearing in RIP packets on IPv4.
*
* This payload is carried in RIP packets on IPv4. The entry contains
* all the fields for RIPv2. RIPv1 and RIPv2 use the same size
* structure, except RIPv1 treats the route tag, subnet mask and
* nexthop fields as Must-Be-Zero (MBZ) items. The interpretation of
* the fields is described in RFC2453.
*
* All items in the route entry are stored in network order. The
* accessor methods provide values in host order, and the modifiers
* take arguments in host order.
*/
struct PacketRouteEntry<IPv4> {
protected:
uint16_t _af;
uint16_t _tag;
uint32_t _addr;
uint32_t _mask;
uint32_t _nh;
uint32_t _metric;
public:
inline void initialize(uint16_t tag,
const IPv4Net& net,
IPv4 nh,
uint32_t cost);
inline uint16_t addr_family() const { return ntohs(_af); }
inline uint16_t tag() const { return ntohs(_tag); }
inline IPv4Net net() const;
inline IPv4 nexthop() const { return IPv4(_nh); }
inline uint32_t metric() const { return ntohl(_metric); }
static const uint16_t ADDR_FAMILY = 2;
static const uint16_t AUTH_ADDR_FAMILY = 0xffff;
};
inline void
PacketRouteEntry<IPv4>::initialize(uint16_t tag,
const IPv4Net& net,
IPv4 nh,
uint32_t cost)
{
_af = htons(ADDR_FAMILY);
_tag = htons(tag);
_addr = net.masked_addr().addr();
_mask = net.netmask().addr();
_nh = nh.addr();
_metric = htonl(cost);
}
inline IPv4Net
PacketRouteEntry<IPv4>::net() const
{
return IPv4Net(IPv4(_addr), IPv4(_mask).prefix_length());
}
/**
* @short Route Entry for Plaintext password.
*
* The PlaintextPacketRouteEntry4 may appear as the first route entry
* in a RIPv2 packet. It has the same size as an @ref
* PacketRouteEntry<IPv4>. The address family has the special value
* 0xffff which imples authentication. The authentication type is
* overlaid in the route tag field and takes the special value 2.
*
* All items in the route entry are stored in network order. The
* accessor methods provide values in host order, and the modifiers
* take arguments in host order.
*/
struct PlaintextPacketRouteEntry4 {
protected:
uint16_t _af;
uint16_t _auth;
char _pw[16];
public:
inline uint16_t addr_family() const { return ntohs(_af); }
inline uint16_t auth_type() const { return ntohs(_auth); }
inline string password() const { return string(_pw, 0, 16); }
inline void initialize(const string& s)
{
_af = ADDR_FAMILY;
_auth = htons(AUTH_TYPE);
memset(_pw, 0, sizeof(_pw));
s.copy(_pw, 16);
}
static const uint16_t ADDR_FAMILY = 0xffff;
static const uint16_t AUTH_TYPE = 2;
};
/**
* @short Route Entry for MD5 data.
*
* The MD5PacketRouteEntry4 may appear as the first route entry
* in a RIPv2 packet. It has the same size as an @ref
* PacketRouteEntry<IPv4>. The address family has the special value
* 0xffff which imples authentication. The authentication type is
* overlaid in the route tag field and takes the special value 3. With
* MD5 the authentication data appears after the remaining route entries.
* Details are disclosed in RFC2082.
*
* All items in the route entry are stored in network order. The
* accessor methods provide values in host order, and the modifiers
* take arguments in host order.
*
* NB We describe the field labelled as "RIP-2 Packet Length" on page 5 of
* RFC 2082 as the "auth_offset". This matches the textual description in
* the RFC.
*/
struct MD5PacketRouteEntry4 {
protected:
uint16_t _af; // 0xffff - Authentication header
uint16_t _auth; // authentication type
uint16_t _auth_offset; // Offset of authentication data
uint8_t _key_id; // Key number used
uint8_t _auth_bytes; // auth data length at end of packet
uint32_t _seqno; // monotonically increasing seqno
uint32_t _mbz[2]; // must-be-zero
public:
inline uint16_t addr_family() const { return ntohs(_af); }
inline uint16_t auth_type() const { return ntohs(_auth); }
inline uint16_t auth_offset() const { return ntohs(_auth_offset); }
inline uint8_t key_id() const { return _key_id; }
inline uint8_t auth_bytes() const { return _auth_bytes; }
inline uint32_t seqno() const { return htonl(_seqno); }
inline void set_auth_offset(uint16_t b) { _auth_offset = htons(b); }
inline void set_key_id(uint8_t id) { _key_id = id; }
inline void set_auth_bytes(uint8_t b) { _auth_bytes = b; }
inline void set_seqno(uint32_t sno) { _seqno = htonl(sno); }
inline void initialize(uint16_t pkt_bytes,
uint8_t key_id,
uint8_t auth_bytes,
uint32_t seqno);
static const uint16_t ADDR_FAMILY = 0xffff;
static const uint16_t AUTH_TYPE = 3;
};
inline void
MD5PacketRouteEntry4::initialize(uint16_t auth_offset,
uint8_t key_id,
uint8_t auth_bytes,
uint32_t seqno)
{
_af = ADDR_FAMILY;
_auth = htons(AUTH_TYPE);
_mbz[0] = _mbz[1] = 0;
set_auth_offset(auth_offset);
set_key_id(key_id);
set_auth_bytes(auth_bytes);
set_seqno(seqno);
}
/**
* @short Container for MD5 trailer.
*/
class MD5PacketTrailer {
public:
inline void initialize();
inline uint8_t* data() { return _data; }
inline const uint8_t* data() const { return _data; }
inline uint32_t data_bytes() const { return 16; }
inline bool valid() const;
protected:
uint16_t _af; // 0xffff - Authentication header
uint16_t _one; // 0x01 - RFC2082 defined
uint8_t _data[16]; // 16 bytes of data
};
inline void
MD5PacketTrailer::initialize()
{
_af = 0xffff;
_one = htons(1);
}
bool
MD5PacketTrailer::valid() const
{
return _af == 0xffff && htons(_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.
*/
struct PacketRouteEntry<IPv6> {
uint32_t prefix[4];
uint16_t route_tag;
uint8_t prefix_length;
uint8_t metric;
};
#endif // __RIP_PACKETS_HH__
Generated by: pavlin on possum.icir.org on Mon Jun 9 13:24:02 2003, using kdoc 2.0a54+XORP. |