internet: (fixes #1109) Add support for multiple hardware types in ArpHeader
This commit is contained in:
committed by
Eduardo Almeida
parent
fd93b6ff7d
commit
e08ae6eaa9
@@ -27,6 +27,7 @@ ArpHeader::SetRequest(Address sourceHardwareAddress,
|
||||
{
|
||||
NS_LOG_FUNCTION(this << sourceHardwareAddress << sourceProtocolAddress
|
||||
<< destinationHardwareAddress << destinationProtocolAddress);
|
||||
m_hardwareType = DetermineHardwareType(sourceHardwareAddress);
|
||||
m_type = ARP_TYPE_REQUEST;
|
||||
m_macSource = sourceHardwareAddress;
|
||||
m_macDest = destinationHardwareAddress;
|
||||
@@ -42,6 +43,7 @@ ArpHeader::SetReply(Address sourceHardwareAddress,
|
||||
{
|
||||
NS_LOG_FUNCTION(this << sourceHardwareAddress << sourceProtocolAddress
|
||||
<< destinationHardwareAddress << destinationProtocolAddress);
|
||||
m_hardwareType = DetermineHardwareType(sourceHardwareAddress);
|
||||
m_type = ARP_TYPE_REPLY;
|
||||
m_macSource = sourceHardwareAddress;
|
||||
m_macDest = destinationHardwareAddress;
|
||||
@@ -49,6 +51,22 @@ ArpHeader::SetReply(Address sourceHardwareAddress,
|
||||
m_ipv4Dest = destinationProtocolAddress;
|
||||
}
|
||||
|
||||
ArpHeader::HardwareType
|
||||
ArpHeader::DetermineHardwareType(const Address& address) const
|
||||
{
|
||||
NS_LOG_FUNCTION(this << address);
|
||||
uint8_t addressLength = address.GetLength();
|
||||
switch (addressLength)
|
||||
{
|
||||
case 6:
|
||||
return HardwareType::ETHERNET;
|
||||
case 8:
|
||||
return HardwareType::EUI_64;
|
||||
default:
|
||||
return HardwareType::UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
ArpHeader::IsRequest() const
|
||||
{
|
||||
@@ -63,6 +81,13 @@ ArpHeader::IsReply() const
|
||||
return m_type == ARP_TYPE_REPLY;
|
||||
}
|
||||
|
||||
ArpHeader::HardwareType
|
||||
ArpHeader::GetHardwareType() const
|
||||
{
|
||||
NS_LOG_FUNCTION(this);
|
||||
return m_hardwareType;
|
||||
}
|
||||
|
||||
Address
|
||||
ArpHeader::GetSourceHardwareAddress() const
|
||||
{
|
||||
@@ -114,7 +139,8 @@ ArpHeader::Print(std::ostream& os) const
|
||||
NS_LOG_FUNCTION(this << &os);
|
||||
if (IsRequest())
|
||||
{
|
||||
os << "request "
|
||||
os << "hardware type: " << GetHardwareType() << " "
|
||||
<< "request "
|
||||
<< "source mac: " << m_macSource << " "
|
||||
<< "source ipv4: " << m_ipv4Source << " "
|
||||
<< "dest ipv4: " << m_ipv4Dest;
|
||||
@@ -122,7 +148,8 @@ ArpHeader::Print(std::ostream& os) const
|
||||
else
|
||||
{
|
||||
NS_ASSERT(IsReply());
|
||||
os << "reply "
|
||||
os << "hardware type: " << GetHardwareType() << " "
|
||||
<< "reply "
|
||||
<< "source mac: " << m_macSource << " "
|
||||
<< "source ipv4: " << m_ipv4Source << " "
|
||||
<< "dest mac: " << m_macDest << " "
|
||||
@@ -151,8 +178,7 @@ ArpHeader::Serialize(Buffer::Iterator start) const
|
||||
Buffer::Iterator i = start;
|
||||
NS_ASSERT(m_macSource.GetLength() == m_macDest.GetLength());
|
||||
|
||||
/* ethernet */
|
||||
i.WriteHtonU16(0x0001);
|
||||
i.WriteHtonU16(static_cast<uint16_t>(m_hardwareType));
|
||||
/* ipv4 */
|
||||
i.WriteHtonU16(0x0800);
|
||||
i.WriteU8(m_macSource.GetLength());
|
||||
@@ -169,10 +195,10 @@ ArpHeader::Deserialize(Buffer::Iterator start)
|
||||
{
|
||||
NS_LOG_FUNCTION(this << &start);
|
||||
Buffer::Iterator i = start;
|
||||
i.Next(2); // Skip HRD
|
||||
uint32_t protocolType = i.ReadNtohU16(); // Read PRO
|
||||
uint32_t hardwareAddressLen = i.ReadU8(); // Read HLN
|
||||
uint32_t protocolAddressLen = i.ReadU8(); // Read PLN
|
||||
m_hardwareType = static_cast<HardwareType>(i.ReadNtohU16()); // Read HTYPE
|
||||
uint32_t protocolType = i.ReadNtohU16(); // Read PRO
|
||||
uint32_t hardwareAddressLen = i.ReadU8(); // Read HLN
|
||||
uint32_t protocolAddressLen = i.ReadU8(); // Read PLN
|
||||
|
||||
//
|
||||
// It is implicit here that we have a protocol type of 0x800 (IP).
|
||||
@@ -185,12 +211,27 @@ ArpHeader::Deserialize(Buffer::Iterator start)
|
||||
return 0;
|
||||
}
|
||||
|
||||
m_type = i.ReadNtohU16(); // Read OP
|
||||
ReadFrom(i, m_macSource, hardwareAddressLen); // Read SHA (size HLN)
|
||||
ReadFrom(i, m_ipv4Source); // Read SPA (size PLN == 4)
|
||||
ReadFrom(i, m_macDest, hardwareAddressLen); // Read THA (size HLN)
|
||||
ReadFrom(i, m_ipv4Dest); // Read TPA (size PLN == 4)
|
||||
m_type = static_cast<ArpType_e>(i.ReadNtohU16()); // Read OP
|
||||
ReadFrom(i, m_macSource, hardwareAddressLen); // Read SHA (size HLN)
|
||||
ReadFrom(i, m_ipv4Source); // Read SPA (size PLN == 4)
|
||||
ReadFrom(i, m_macDest, hardwareAddressLen); // Read THA (size HLN)
|
||||
ReadFrom(i, m_ipv4Dest); // Read TPA (size PLN == 4)
|
||||
return GetSerializedSize();
|
||||
}
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, ArpHeader::HardwareType hardwareType)
|
||||
{
|
||||
switch (hardwareType)
|
||||
{
|
||||
case ArpHeader::HardwareType::ETHERNET:
|
||||
return (os << "Ethernet");
|
||||
case ArpHeader::HardwareType::EUI_64:
|
||||
return (os << "EUI-64");
|
||||
case ArpHeader::HardwareType::UNKNOWN:
|
||||
return (os << "Unknown Hardware Type");
|
||||
}
|
||||
return os << "Unrecognized Hardware Type(" << static_cast<uint16_t>(hardwareType) << ")";
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
@@ -13,8 +13,6 @@
|
||||
#include "ns3/header.h"
|
||||
#include "ns3/ipv4-address.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace ns3
|
||||
{
|
||||
/**
|
||||
@@ -24,6 +22,33 @@ namespace ns3
|
||||
class ArpHeader : public Header
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* \brief Enumeration listing the possible ARP types
|
||||
*
|
||||
* These ARP types are part of the standard ARP packet format as defined in Section
|
||||
* "Definitions" of \RFC{826}.
|
||||
*/
|
||||
enum ArpType_e : uint16_t
|
||||
{
|
||||
ARP_TYPE_REQUEST = 1,
|
||||
ARP_TYPE_REPLY = 2
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Enumeration listing the supported hardware types
|
||||
*
|
||||
* \RFC{826} specifies that the Hardware Type field in the ARP packet indicates the type
|
||||
of hardware used.
|
||||
* For the full list of Hardware Types, refer to:
|
||||
* https://www.iana.org/assignments/arp-parameters/arp-parameters.xhtml
|
||||
*/
|
||||
enum class HardwareType : uint16_t
|
||||
{
|
||||
UNKNOWN = 0,
|
||||
ETHERNET = 1,
|
||||
EUI_64 = 27,
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Set the ARP request parameters
|
||||
* \param sourceHardwareAddress the source hardware address
|
||||
@@ -49,6 +74,22 @@ class ArpHeader : public Header
|
||||
Address destinationHardwareAddress,
|
||||
Ipv4Address destinationProtocolAddress);
|
||||
|
||||
/**
|
||||
* @brief Determines the hardware type based on the length of the address.
|
||||
*
|
||||
* This method determines the hardware type based on the length of the address.
|
||||
* It supports two common hardware address lengths:
|
||||
* - 6 bytes: Assumed to be Ethernet.
|
||||
* - 8 bytes: Assumed to be EUI-64.
|
||||
*
|
||||
* If the length of the address does not match these common lengths, the method defaults
|
||||
* to Unknown hardware type.
|
||||
*
|
||||
* @param address The address whose length is used to determine the hardware type.
|
||||
* @return The corresponding hardware type.
|
||||
*/
|
||||
HardwareType DetermineHardwareType(const Address& address) const;
|
||||
|
||||
/**
|
||||
* \brief Check if the ARP is a request
|
||||
* \returns true if it is a request
|
||||
@@ -61,6 +102,12 @@ class ArpHeader : public Header
|
||||
*/
|
||||
bool IsReply() const;
|
||||
|
||||
/**
|
||||
* \brief Get the hardware type
|
||||
* \return the hardware type
|
||||
*/
|
||||
HardwareType GetHardwareType() const;
|
||||
|
||||
/**
|
||||
* \brief Returns the source hardware address
|
||||
* \returns the source hardware address
|
||||
@@ -96,22 +143,23 @@ class ArpHeader : public Header
|
||||
void Serialize(Buffer::Iterator start) const override;
|
||||
uint32_t Deserialize(Buffer::Iterator start) override;
|
||||
|
||||
/**
|
||||
* \brief Enumeration listing the possible ARP types
|
||||
*/
|
||||
enum ArpType_e
|
||||
{
|
||||
ARP_TYPE_REQUEST = 1,
|
||||
ARP_TYPE_REPLY = 2
|
||||
};
|
||||
|
||||
uint16_t m_type; //!< type of the ICMP (ARP_TYPE_REQUEST)
|
||||
Address m_macSource; //!< hardware source address
|
||||
Address m_macDest; //!< hardware destination address
|
||||
Ipv4Address m_ipv4Source; //!< IP source address
|
||||
Ipv4Address m_ipv4Dest; //!< IP destination address
|
||||
HardwareType m_hardwareType; //!< hardware type
|
||||
ArpType_e m_type; //!< type of the ICMP packet
|
||||
Address m_macSource; //!< hardware source address
|
||||
Address m_macDest; //!< hardware destination address
|
||||
Ipv4Address m_ipv4Source; //!< IP source address
|
||||
Ipv4Address m_ipv4Dest; //!< IP destination address
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Stream insertion operator.
|
||||
*
|
||||
* \param os The reference to the output stream
|
||||
* \param hardwareType the hardware type
|
||||
* \return The reference to the output stream.
|
||||
*/
|
||||
std::ostream& operator<<(std::ostream& os, ArpHeader::HardwareType hardwareType);
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
#endif /* ARP_HEADER_H */
|
||||
|
||||
Reference in New Issue
Block a user