diff --git a/include/bootp.h b/include/bootp.h index 1dc4e12..4230771 100644 --- a/include/bootp.h +++ b/include/bootp.h @@ -28,6 +28,7 @@ #include "pdu.h" + namespace Tins { /** @@ -39,16 +40,192 @@ namespace Tins { /** * \brief Enum which contains the different opcodes BootP messages. */ - enum OpCodes { + enum OpCodes { BOOTREQUEST = 1, - BOOTREPLY = 2 - } - + BOOTREPLY = 2 + }; + + /** \brief Creates an instance of BootP. + * + * This sets the size of the vend field to 64, as the BootP RFC + * states. + */ + BootP(); + + /** \brief BootP destructor. + * + * This frees the memory allocated to hold the vend field. + */ + ~BootP(); + + /* Getters */ + + /** \brief Getter for the opcode field. + * \return The opcode field for this BootP PDU. + */ + uint8_t opcode() const { return _bootp.opcode; } + + /** \brief Getter for the htype field. + * \return The htype field for this BootP PDU. + */ + uint8_t htype() const { return _bootp.htype; } + + /** \brief Getter for the hlen field. + * \return The hlen field for this BootP PDU. + */ + uint8_t hlen() const { return _bootp.hlen; } + + /** \brief Getter for the hops field. + * \return The hops field for this BootP PDU. + */ + uint8_t hops() const { return _bootp.hops; } + + /** \brief Getter for the xid field. + * \return The xid field for this BootP PDU. + */ + uint32_t xid() const { return _bootp.xid; } + + /** \brief Getter for the secs field. + * \return The secs field for this BootP PDU. + */ + uint16_t secs() const { return _bootp.secs; } + + /** \brief Getter for the padding field. + * \return The padding field for this BootP PDU. + */ + uint16_t padding() const { return _bootp.padding; } + + /** \brief Getter for the ciaddr field. + * \return The ciaddr field for this BootP PDU. + */ + uint32_t ciaddr() const { return _bootp.ciaddr; } + + /** \brief Getter for the yiaddr field. + * \return The yiaddr field for this BootP PDU. + */ + uint32_t yiaddr() const { return _bootp.yiaddr; } + + /** \brief Getter for the siaddr field. + * \return The siaddr field for this BootP PDU. + */ + uint32_t siaddr() const { return _bootp.siaddr; } + + /** \brief Getter for the giaddr field. + * \return The giaddr field for this BootP PDU. + */ + uint32_t giaddr() const { return _bootp.giaddr; } + + /** \brief Getter for the chaddr field. + * \return The chddr field for this BootP PDU. + */ + const uint8_t *chaddr() const { return _bootp.chaddr; } + + /** \brief Getter for the sname field. + * \return The sname field for this BootP PDU. + */ + const uint8_t *sname() const { return _bootp.sname; } + + /** \brief Getter for the file field. + * \return The file field for this BootP PDU. + */ + const uint8_t *file() const { return _bootp.file; } + + /** \brief Getter for the vend field. + * \return The vend field for this BootP PDU. + */ + uint8_t *vend() { return _bootp.vend; } + + /** \brief Getter for the vend field. + */ + uint32_t vend_size() const { return _vend_size; } + + /** \brief Getter for the header size. + * \return Returns the ARP header size. + * \sa PDU::header_size + */ + uint32_t header_size() const; + /* Setters */ + + /** \brief Setter for the opcode field. + * \param new_opcode The opcode to be set. + */ + void opcode(uint8_t new_opcode); + + /** \brief Setter for the htype field. + * \param new_htype The htype to be set. + */ + void htype(uint8_t new_htype); + + /** \brief Setter for the hlen field. + * \param new_hlen The hlen to be set. + */ + void hlen(uint8_t new_hlen); + + /** \brief Setter for the hops field. + * \param new_hops The hops to be set. + */ + void hops(uint8_t new_hops); + + /** \brief Setter for the xid field. + * \param new_xid The xid to be set. + */ + void xid(uint32_t new_xid); + + /** \brief Setter for the secs field. + * \param new_secs The secs to be set. + */ + void secs(uint16_t new_secs); + + /** \brief Setter for the padding field. + * \param new_padding The padding to be set. + */ + void padding(uint16_t new_padding); + + /** \brief Setter for the ciaddr field. + * \param new_ciaddr The ciaddr to be set. + */ + void ciaddr(uint32_t new_ciaddr); + + /** \brief Setter for the yiaddr field. + * \param new_yiaddr The yiaddr to be set. + */ + void yiaddr(uint32_t new_yiaddr); + + /** \brief Setter for the siaddr field. + * \param new_siaddr The siaddr to be set. + */ + void siaddr(uint32_t new_siaddr); + + /** \brief Setter for the giaddr field. + * \param new_giaddr The giaddr to be set. + */ + void giaddr(uint32_t new_giaddr); + + /** \brief Setter for the chaddr field. + * \param new_chaddr The chaddr to be set. + */ + void chaddr(uint8_t *new_chaddr); + + /** \brief Setter for the sname field. + * \param new_sname The sname to be set. + */ + void sname(uint8_t *new_sname); + + /** \brief Setter for the file field. + * \param new_file The file to be set. + */ + void file(uint8_t *new_file); + + /** \brief Setter for the vend field. + * \param new_vend The vend to be set. + * \param size The size of the new vend field. + */ + void vend(uint8_t *new_vend, uint32_t size); private: /** * Struct that represents the Bootp datagram. */ - struct bootp { + struct bootphdr { uint8_t opcode; uint8_t htype; uint8_t hlen; @@ -63,12 +240,14 @@ namespace Tins { uint8_t chaddr[16]; uint8_t sname[64]; uint8_t file[128]; - uint8_t vend[64]; } __attribute__((__packed__)); - - - } - -} + + void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent); + + bootphdr _bootp; + uint8_t *_vend; + uint32_t _vend_size; + }; +}; #endif diff --git a/src/bootp.cpp b/src/bootp.cpp new file mode 100644 index 0000000..8fd512e --- /dev/null +++ b/src/bootp.cpp @@ -0,0 +1,85 @@ +#include +#include +#include "bootp.h" +#include "utils.h" + + +Tins::BootP::BootP() : PDU(255) { + _vend = new uint8_t[64]; +} + +Tins::BootP::~BootP() { + delete[] vend; +} + +uint32_t Tins::BootP::header_size() const { + return sizeof(bootphdr); +} + +void Tins::BootP::opcode(uint8_t new_opcode) { + _bootp.opcode = new_opcode; +} + +void Tins::BootP::htype(uint8_t new_htype) { + _bootp.htype = new_htype; +} + +void Tins::BootP::hlen(uint8_t new_hlen) { + _bootp.hlen = new_hlen; +} + +void Tins::BootP::hops(uint8_t new_hops) { + _bootp.hops = new_hops; +} + +void Tins::BootP::xid(uint32_t new_xid) { + _bootp.xid = Utils::net_to_host_l(new_xid); +} + +void Tins::BootP::secs(uint16_t new_secs) { + _bootp.secs = Utils::net_to_host_s(new_secs); +} + +void Tins::BootP::padding(uint16_t new_padding) { + _bootp.padding = Utils::net_to_host_s(new_padding); +} + +void Tins::BootP::ciaddr(uint32_t new_ciaddr) { + _bootp.ciaddr = Utils::net_to_host_l(new_ciaddr); +} + +void Tins::BootP::yiaddr(uint32_t new_yiaddr) { + _bootp.yiaddr = Utils::net_to_host_l(new_yiaddr); +} + +void Tins::BootP::siaddr(uint32_t new_siaddr) { + _bootp.siaddr = Utils::net_to_host_l(new_siaddr); +} + +void Tins::BootP::giaddr(uint32_t new_giaddr) { + _bootp.giaddr = Utils::net_to_host_l(new_giaddr); +} + +void Tins::BootP::chaddr(uint8_t *new_chaddr) { + std::memcpy(_bootp.chaddr, new_chaddr, sizeof(_bootp.chaddr)); +} + +void Tins::BootP::sname(uint8_t *new_sname) { + std::memcpy(_bootp.sname, new_sname, sizeof(_bootp.sname)); +} + +void Tins::BootP::file(uint8_t *new_file) { + std::memcpy(_bootp.file, new_file, sizeof(_bootp.file)); +} + +void Tins::BootP::vend(uint8_t *new_vend, uint32_t size) { + delete[] _vend; + _vend_size = size; + _vend = new uint8_t[size]; + std::memcpy(_vend, new_vend, size); +} + +void Tins::BootP::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent) { + assert(total_sz >= sizeof(bootphdr)); + std::memcpy(buffer, &_bootp, sizeof(bootphdr)); +}