#include "ethernet_header.hh" #include "util.hh" #include #include using namespace std; ParseResult EthernetHeader::parse(NetParser &p) { if (p.buffer().size() < EthernetHeader::LENGTH) { return ParseResult::PacketTooShort; } /* read destination address */ for (auto &byte : dst) { byte = p.u8(); } /* read source address */ for (auto &byte : src) { byte = p.u8(); } /* read the frame's type (e.g. IPv4, ARP, or something else) */ type = p.u16(); return p.get_error(); } string EthernetHeader::serialize() const { string ret; ret.reserve(LENGTH); /* write destination address */ for (auto &byte : dst) { NetUnparser::u8(ret, byte); } /* write source address */ for (auto &byte : src) { NetUnparser::u8(ret, byte); } /* write the frame's type (e.g. IPv4, ARP or something else) */ NetUnparser::u16(ret, type); return ret; } //! \returns A string with a textual representation of an Ethernet address string to_string(const EthernetAddress address) { stringstream ss{}; for (auto it = address.begin(); it != address.end(); it++) { ss.width(2); ss << setfill('0') << hex << int(*it); if (it != address.end() - 1) { ss << ":"; } } return ss.str(); } //! \returns A string with the header's contents string EthernetHeader::to_string() const { stringstream ss{}; ss << "dst=" << ::to_string(dst); ss << ", src=" << ::to_string(src); ss << ", type="; switch (type) { case TYPE_IPv4: ss << "IPv4"; break; case TYPE_ARP: ss << "ARP"; break; default: ss << "[unknown type " << hex << type << "!]"; break; } return ss.str(); }