Sponge
CS144's user-space TCP library
arp_message.cc
Go to the documentation of this file.
1 #include "arp_message.hh"
2 
3 #include <arpa/inet.h>
4 #include <iomanip>
5 #include <sstream>
6 
7 using namespace std;
8 
10  NetParser p{buffer};
11 
12  if (p.buffer().size() < ARPMessage::LENGTH) {
14  }
15 
16  hardware_type = p.u16();
17  protocol_type = p.u16();
18  hardware_address_size = p.u8();
19  protocol_address_size = p.u8();
20  opcode = p.u16();
21 
22  if (not supported()) {
24  }
25 
26  // read sender addresses (Ethernet and IP)
27  for (auto &byte : sender_ethernet_address) {
28  byte = p.u8();
29  }
30  sender_ip_address = p.u32();
31 
32  // read target addresses (Ethernet and IP)
33  for (auto &byte : target_ethernet_address) {
34  byte = p.u8();
35  }
36  target_ip_address = p.u32();
37 
38  return p.get_error();
39 }
40 
41 bool ARPMessage::supported() const {
42  return hardware_type == TYPE_ETHERNET and protocol_type == EthernetHeader::TYPE_IPv4 and
43  hardware_address_size == sizeof(EthernetHeader::src) and protocol_address_size == sizeof(IPv4Header::src) and
44  ((opcode == OPCODE_REQUEST) or (opcode == OPCODE_REPLY));
45 }
46 
47 string ARPMessage::serialize() const {
48  if (not supported()) {
49  throw runtime_error(
50  "ARPMessage::serialize(): unsupported field combination (must be Ethernet/IP, and request or reply)");
51  }
52 
53  string ret;
54  NetUnparser::u16(ret, hardware_type);
55  NetUnparser::u16(ret, protocol_type);
56  NetUnparser::u8(ret, hardware_address_size);
57  NetUnparser::u8(ret, protocol_address_size);
58  NetUnparser::u16(ret, opcode);
59 
60  /* write sender addresses */
61  for (auto &byte : sender_ethernet_address) {
62  NetUnparser::u8(ret, byte);
63  }
64  NetUnparser::u32(ret, sender_ip_address);
65 
66  /* write target addresses */
67  for (auto &byte : target_ethernet_address) {
68  NetUnparser::u8(ret, byte);
69  }
70  NetUnparser::u32(ret, target_ip_address);
71 
72  return ret;
73 }
74 
75 string ARPMessage::to_string() const {
76  stringstream ss{};
77  string opcode_str = "(unknown type)";
78  if (opcode == OPCODE_REQUEST) {
79  opcode_str = "REQUEST";
80  }
81  if (opcode == OPCODE_REPLY) {
82  opcode_str = "REPLY";
83  }
84  ss << "opcode=" << opcode_str << ", sender=" << ::to_string(sender_ethernet_address) << "/"
85  << inet_ntoa({htobe32(sender_ip_address)}) << ", target=" << ::to_string(target_ethernet_address) << "/"
86  << inet_ntoa({htobe32(target_ip_address)});
87  return ss.str();
88 }
arp_message.hh
NetUnparser::u8
static void u8(std::string &s, const uint8_t val)
Write an 8-bit integer into the data stream in network byte order.
Definition: parser.cc:72
ARPMessage::LENGTH
static constexpr size_t LENGTH
ARP message length in bytes.
Definition: arp_message.hh:11
EthernetHeader::src
EthernetAddress src
Definition: ethernet_header.hh:26
std::stringstream
IPv4Header::src
uint32_t src
src address
Definition: ipv4_header.hh:45
buffer
std::string buffer
Definition: parser_example.cc:7
NetUnparser::u16
static void u16(std::string &s, const uint16_t val)
Write a 16-bit integer into the data stream in network byte order.
Definition: parser.cc:70
Buffer
A reference-counted read-only string that can discard bytes from the front.
Definition: buffer.hh:14
ParseResult::Unsupported
@ Unsupported
Packet uses unsupported features.
std::to_string
T to_string(T... args)
EthernetHeader::TYPE_IPv4
static constexpr uint16_t TYPE_IPv4
Type number for IPv4.
Definition: ethernet_header.hh:20
ParseResult
ParseResult
The result of parsing or unparsing an IP datagram, TCP segment, Ethernet frame, or ARP message.
Definition: parser.hh:12
std::runtime_error
ARPMessage::serialize
std::string serialize() const
Serialize the ARP message to a string.
Definition: arp_message.cc:47
ARPMessage::supported
bool supported() const
Is this type of ARP message supported by the parser?
Definition: arp_message.cc:41
NetParser
Definition: parser.hh:25
NetUnparser::u32
static void u32(std::string &s, const uint32_t val)
Write a 32-bit integer into the data stream in network byte order.
Definition: parser.cc:68
std
ARPMessage::parse
ParseResult parse(const Buffer buffer)
Parse the ARP message from a string.
Definition: arp_message.cc:9
ParseResult::PacketTooShort
@ PacketTooShort
Not enough data to finish parsing.
ARPMessage::to_string
std::string to_string() const
Return a string containing the ARP message in human-readable format.
Definition: arp_message.cc:75