mirror of
https://github.com/mfontanini/libtins
synced 2026-01-23 02:35:57 +01:00
Added PPPoE.
This commit is contained in:
@@ -13,6 +13,7 @@ AM_CXXFLAGS = -Wall -pedantic -I@LIBTINS_INCLUDE_DIR@
|
||||
|
||||
libtins_la_SOURCES=src/arp.cpp \
|
||||
src/bootp.cpp \
|
||||
src/pppoe.cpp \
|
||||
src/crypto.cpp \
|
||||
src/dhcp.cpp \
|
||||
src/dhcpv6.cpp \
|
||||
@@ -57,6 +58,7 @@ libtins_include_HEADERS = include/internals.h \
|
||||
include/dns_record.h \
|
||||
include/eapol.h \
|
||||
include/tcp_stream.h \
|
||||
include/pppoe.h \
|
||||
include/ipv6.h \
|
||||
include/icmpv6.h \
|
||||
include/endianness.h \
|
||||
|
||||
26
Makefile.in
26
Makefile.in
@@ -100,16 +100,16 @@ am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkgconfigdir)" \
|
||||
LTLIBRARIES = $(lib_LTLIBRARIES)
|
||||
libtins_la_LIBADD =
|
||||
am__dirstamp = $(am__leading_dot)dirstamp
|
||||
am_libtins_la_OBJECTS = src/arp.lo src/bootp.lo src/crypto.lo \
|
||||
src/dhcp.lo src/dhcpv6.lo src/dns.lo src/dns_record.lo \
|
||||
src/dot11.lo src/dot3.lo src/dot1q.lo src/eapol.lo \
|
||||
src/ethernetII.lo src/icmp.lo src/icmpv6.lo src/internals.lo \
|
||||
src/ip.lo src/ip_address.lo src/ipv6.lo src/ipv6_address.lo \
|
||||
src/llc.lo src/loopback.lo src/network_interface.lo \
|
||||
src/packet_sender.lo src/packet_writer.lo src/pdu.lo \
|
||||
src/radiotap.lo src/rawpdu.lo src/rsn_information.lo \
|
||||
src/sll.lo src/snap.lo src/sniffer.lo src/tcp.lo \
|
||||
src/tcp_stream.lo src/udp.lo src/utils.lo
|
||||
am_libtins_la_OBJECTS = src/arp.lo src/bootp.lo src/pppoe.lo \
|
||||
src/crypto.lo src/dhcp.lo src/dhcpv6.lo src/dns.lo \
|
||||
src/dns_record.lo src/dot11.lo src/dot3.lo src/dot1q.lo \
|
||||
src/eapol.lo src/ethernetII.lo src/icmp.lo src/icmpv6.lo \
|
||||
src/internals.lo src/ip.lo src/ip_address.lo src/ipv6.lo \
|
||||
src/ipv6_address.lo src/llc.lo src/loopback.lo \
|
||||
src/network_interface.lo src/packet_sender.lo \
|
||||
src/packet_writer.lo src/pdu.lo src/radiotap.lo src/rawpdu.lo \
|
||||
src/rsn_information.lo src/sll.lo src/snap.lo src/sniffer.lo \
|
||||
src/tcp.lo src/tcp_stream.lo src/udp.lo src/utils.lo
|
||||
libtins_la_OBJECTS = $(am_libtins_la_OBJECTS)
|
||||
libtins_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
|
||||
$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
|
||||
@@ -285,6 +285,7 @@ libtins_la_LDFLAGS = -version-info @LIBTINS_VERSION@
|
||||
AM_CXXFLAGS = -Wall -pedantic -I@LIBTINS_INCLUDE_DIR@
|
||||
libtins_la_SOURCES = src/arp.cpp \
|
||||
src/bootp.cpp \
|
||||
src/pppoe.cpp \
|
||||
src/crypto.cpp \
|
||||
src/dhcp.cpp \
|
||||
src/dhcpv6.cpp \
|
||||
@@ -329,6 +330,7 @@ libtins_include_HEADERS = include/internals.h \
|
||||
include/dns_record.h \
|
||||
include/eapol.h \
|
||||
include/tcp_stream.h \
|
||||
include/pppoe.h \
|
||||
include/ipv6.h \
|
||||
include/icmpv6.h \
|
||||
include/endianness.h \
|
||||
@@ -446,6 +448,7 @@ src/$(DEPDIR)/$(am__dirstamp):
|
||||
@: > src/$(DEPDIR)/$(am__dirstamp)
|
||||
src/arp.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
|
||||
src/bootp.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
|
||||
src/pppoe.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
|
||||
src/crypto.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
|
||||
src/dhcp.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
|
||||
src/dhcpv6.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
|
||||
@@ -538,6 +541,8 @@ mostlyclean-compile:
|
||||
-rm -f src/packet_writer.lo
|
||||
-rm -f src/pdu.$(OBJEXT)
|
||||
-rm -f src/pdu.lo
|
||||
-rm -f src/pppoe.$(OBJEXT)
|
||||
-rm -f src/pppoe.lo
|
||||
-rm -f src/radiotap.$(OBJEXT)
|
||||
-rm -f src/radiotap.lo
|
||||
-rm -f src/rawpdu.$(OBJEXT)
|
||||
@@ -587,6 +592,7 @@ distclean-compile:
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/packet_sender.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/packet_writer.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/pdu.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/pppoe.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/radiotap.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/rawpdu.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/rsn_information.Plo@am__quote@
|
||||
|
||||
@@ -84,6 +84,7 @@ namespace Tins {
|
||||
VLAN = 0x8100, /* IEEE 802.1Q VLAN tagging */
|
||||
IPX = 0x8137, /* IPX */
|
||||
IPV6 = 0x86dd, /* IP protocol version 6 */
|
||||
PPPOED = 0x8863, /* PPPoE Discovery */
|
||||
EAPOL = 0x888e, /* EAPOL */
|
||||
LOOPBACK = 0x9000 /* used to test interfaces */
|
||||
};
|
||||
|
||||
@@ -41,6 +41,7 @@ public:
|
||||
* This PDU's flag.
|
||||
*/
|
||||
static const PDU::PDUType pdu_flag = PDU::DOT1Q;
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
*/
|
||||
@@ -177,6 +178,7 @@ public:
|
||||
private:
|
||||
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent);
|
||||
|
||||
TINS_BEGIN_PACK
|
||||
struct dot1q_hdr {
|
||||
#if TINS_IS_BIG_ENDIAN
|
||||
uint16_t priority:3,
|
||||
@@ -190,7 +192,7 @@ private:
|
||||
idL:8;
|
||||
uint16_t type;
|
||||
#endif
|
||||
};
|
||||
} TINS_END_PACK;
|
||||
|
||||
static uint16_t get_id(const dot1q_hdr *hdr);
|
||||
|
||||
|
||||
@@ -40,6 +40,11 @@
|
||||
namespace Tins {
|
||||
|
||||
class PacketSender;
|
||||
|
||||
/**
|
||||
* The type used to store several PDU option values.
|
||||
*/
|
||||
typedef std::vector<uint8_t> byte_array;
|
||||
|
||||
/** \brief Base class for protocol data units.
|
||||
*
|
||||
@@ -55,7 +60,7 @@ namespace Tins {
|
||||
/**
|
||||
* The type that will be returned when serializing PDUs.
|
||||
*/
|
||||
typedef std::vector<uint8_t> serialization_type;
|
||||
typedef byte_array serialization_type;
|
||||
|
||||
/**
|
||||
* \brief Enum which identifies each type of PDU.
|
||||
@@ -107,7 +112,8 @@ namespace Tins {
|
||||
ICMPv6,
|
||||
SLL,
|
||||
DHCPv6,
|
||||
DOT1Q
|
||||
DOT1Q,
|
||||
PPPOE
|
||||
};
|
||||
|
||||
/** \brief PDU constructor
|
||||
|
||||
@@ -93,6 +93,25 @@ public:
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Constructs a PDUOption from iterators, which
|
||||
* indicate the data to be stored in it.
|
||||
*
|
||||
* The length parameter indicates the contents of the length field
|
||||
* when this option is serialized. Note that this can be different
|
||||
* to std::distance(start, end).
|
||||
*
|
||||
* \param opt The option type.
|
||||
* \param length The length of this option.
|
||||
* \param start The beginning of the option data.
|
||||
* \param end The end of the option data.
|
||||
*/
|
||||
template<typename ForwardIterator>
|
||||
PDUOption(option_type opt, size_t length, ForwardIterator start, ForwardIterator end)
|
||||
: option_(opt), size_(length), value_(start, end) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves this option's type.
|
||||
* \return uint8_t containing this option's size.
|
||||
@@ -123,9 +142,22 @@ public:
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the length of this option's data.
|
||||
* \brief Retrieves the length of this option's data.
|
||||
*
|
||||
* This is the actual size of the data.
|
||||
*/
|
||||
size_t data_size() const {
|
||||
return value_.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Retrieves the data length field.
|
||||
*
|
||||
* This may be different to the actual size of the data.
|
||||
*
|
||||
* \sa data_size.
|
||||
*/
|
||||
size_t length_field() const {
|
||||
return size_;
|
||||
}
|
||||
private:
|
||||
|
||||
430
include/pppoe.h
Normal file
430
include/pppoe.h
Normal file
@@ -0,0 +1,430 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Nasel
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TINS_PPPoE_H
|
||||
#define TINS_PPPoE_H
|
||||
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "pdu.h"
|
||||
#include "endianness.h"
|
||||
#include "small_uint.h"
|
||||
#include "pdu_option.h"
|
||||
#include "cxxstd.h"
|
||||
|
||||
namespace Tins {
|
||||
class PPPoE : public PDU {
|
||||
public:
|
||||
/**
|
||||
* The tag types enum.
|
||||
*/
|
||||
enum tag_identifiers {
|
||||
END_OF_LIST = 0,
|
||||
SERVICE_NAME = 0x101,
|
||||
#if TINS_IS_LITTLE_ENDIAN
|
||||
AC_NAME = 0x201,
|
||||
HOST_UNIQ = 0x301,
|
||||
AC_COOKIE = 0x401,
|
||||
VENDOR_SPECIFIC = 0x501,
|
||||
RELAY_SESSION_ID = 0x101,
|
||||
SERVICE_NAME_ERROR = 0x201,
|
||||
AC_SYSTEM_ERROR = 0x202,
|
||||
GENERIC_ERROR = 0x302
|
||||
#else
|
||||
AC_NAME = 0x102,
|
||||
HOST_UNIQ = 0x103,
|
||||
AC_COOKIE = 0x104,
|
||||
VENDOR_SPECIFIC = 0x105,
|
||||
RELAY_SESSION_ID = 0x110,
|
||||
SERVICE_NAME_ERROR = 0x201,
|
||||
AC_SYSTEM_ERROR = 0x202,
|
||||
GENERIC_ERROR = 0x203
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* The type used to store a TLV option.
|
||||
*/
|
||||
typedef PDUOption<tag_identifiers> pppoe_tag;
|
||||
|
||||
/**
|
||||
* The type used to store the options.
|
||||
*/
|
||||
typedef std::list<pppoe_tag> tags_type;
|
||||
|
||||
/**
|
||||
* The type used to store the Vendor-Specific tag's value.
|
||||
*/
|
||||
struct vendor_spec_type {
|
||||
typedef std::vector<uint8_t> data_type;
|
||||
|
||||
uint32_t vendor_id;
|
||||
data_type data;
|
||||
|
||||
vendor_spec_type(uint32_t vendor_id = 0, const data_type &data = data_type())
|
||||
: vendor_id(vendor_id), data(data) { }
|
||||
};
|
||||
|
||||
/**
|
||||
* This PDU's flag.
|
||||
*/
|
||||
static const PDU::PDUType pdu_flag = PDU::PPPOE;
|
||||
|
||||
/**
|
||||
* \brief Default constructor.
|
||||
*
|
||||
* This sets the version and type fields to 0x1.
|
||||
*/
|
||||
PPPoE();
|
||||
|
||||
/**
|
||||
* \brief Constructor which creates an PPPoE object from a buffer.
|
||||
*
|
||||
* \param buffer The buffer from which this PDU will be constructed.
|
||||
* \param total_sz The total size of the buffer.
|
||||
*/
|
||||
PPPoE(const uint8_t *buffer, uint32_t total_sz);
|
||||
|
||||
// Getters
|
||||
|
||||
/**
|
||||
* \brief Getter for the version field.
|
||||
* \return The stored version field value.
|
||||
*/
|
||||
small_uint<4> version() const {
|
||||
return _header.version;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the type field.
|
||||
* \return The stored type field value.
|
||||
*/
|
||||
small_uint<4> type() const {
|
||||
return _header.type;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the code field.
|
||||
* \return The stored code field value.
|
||||
*/
|
||||
uint8_t code() const {
|
||||
return _header.code;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the session_id field.
|
||||
* \return The stored session_id field value.
|
||||
*/
|
||||
uint16_t session_id() const {
|
||||
return Endian::be_to_host(_header.session_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the payload_length field.
|
||||
* \return The stored payload_length field value.
|
||||
*/
|
||||
uint16_t payload_length() const {
|
||||
return Endian::be_to_host(_header.payload_length);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns the header size.
|
||||
*
|
||||
* This metod overrides PDU::header_size. \sa PDU::header_size
|
||||
*/
|
||||
uint32_t header_size() const;
|
||||
|
||||
/**
|
||||
* \brief Returns the list of tags.
|
||||
*/
|
||||
const tags_type &tags() const {
|
||||
return _tags;
|
||||
}
|
||||
|
||||
/**
|
||||
* \sa PDU::clone
|
||||
*/
|
||||
PPPoE *clone() const {
|
||||
return new PPPoE(*this);
|
||||
}
|
||||
|
||||
const pppoe_tag *search_tag(tag_identifiers identifier) const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the PDU's type.
|
||||
* \sa PDU::pdu_type
|
||||
*/
|
||||
PDUType pdu_type() const { return pdu_flag; }
|
||||
|
||||
// Setters
|
||||
|
||||
/**
|
||||
* \brief Setter for the version field.
|
||||
* \param new_version The new version field value.
|
||||
*/
|
||||
void version(small_uint<4> new_version);
|
||||
|
||||
/**
|
||||
* \brief Setter for the type field.
|
||||
* \param new_type The new type field value.
|
||||
*/
|
||||
void type(small_uint<4> new_type);
|
||||
|
||||
/**
|
||||
* \brief Setter for the code field.
|
||||
* \param new_code The new code field value.
|
||||
*/
|
||||
void code(uint8_t new_code);
|
||||
|
||||
/**
|
||||
* \brief Setter for the session_id field.
|
||||
* \param new_session_id The new session_id field value.
|
||||
*/
|
||||
void session_id(uint16_t new_session_id);
|
||||
|
||||
/**
|
||||
* \brief Setter for the payload_length field.
|
||||
* \param new_payload_length The new payload_length field value.
|
||||
*/
|
||||
void payload_length(uint16_t new_payload_length);
|
||||
|
||||
/**
|
||||
* \brief Adds a PPPoE tag.
|
||||
*
|
||||
* \param option The option to be added.
|
||||
*/
|
||||
void add_tag(const pppoe_tag &option);
|
||||
|
||||
#if TINS_IS_CXX11
|
||||
/**
|
||||
* \brief Adds a PPPoE tag.
|
||||
*
|
||||
* This move-constructs the option.
|
||||
*
|
||||
* \param option The option to be added.
|
||||
*/
|
||||
void add_tag(pppoe_tag &&option);
|
||||
#endif
|
||||
|
||||
// Option setters
|
||||
|
||||
/**
|
||||
* \brief Adds an end-of-list tag.
|
||||
*/
|
||||
void end_of_list();
|
||||
|
||||
/**
|
||||
* \brief Adds a service-name tag.
|
||||
*
|
||||
* \param value The service name.
|
||||
*/
|
||||
void service_name(const std::string &value);
|
||||
|
||||
/**
|
||||
* \brief Adds a AC-name tag.
|
||||
*
|
||||
* \param value The AC name.
|
||||
*/
|
||||
void ac_name(const std::string &value);
|
||||
|
||||
/**
|
||||
* \brief Adds a host-uniq tag.
|
||||
*
|
||||
* \param value The tag's value.
|
||||
*/
|
||||
void host_uniq(const byte_array &value);
|
||||
|
||||
/**
|
||||
* \brief Adds a AC-Cookie tag.
|
||||
*
|
||||
* \param value The tag's value.
|
||||
*/
|
||||
void ac_cookie(const byte_array &value);
|
||||
|
||||
/**
|
||||
* \brief Adds a Vendor-Specific tag.
|
||||
*
|
||||
* \param value The tag's value.
|
||||
*/
|
||||
void vendor_specific(const vendor_spec_type &value);
|
||||
|
||||
/**
|
||||
* \brief Adds a Relay-Session-Id tag.
|
||||
*
|
||||
* \param value The tag's value.
|
||||
*/
|
||||
void relay_session_id(const byte_array &value);
|
||||
|
||||
/**
|
||||
* \brief Adds a Service-Name-Error tag.
|
||||
*
|
||||
* \param value The tag's value.
|
||||
*/
|
||||
void service_name_error(const std::string &value);
|
||||
|
||||
/**
|
||||
* \brief Adds a AC-System-Error tag.
|
||||
*
|
||||
* \param value The tag's value.
|
||||
*/
|
||||
void ac_system_error(const std::string &value);
|
||||
|
||||
/**
|
||||
* \brief Adds a Generic-Error tag.
|
||||
*
|
||||
* \param value The tag's value.
|
||||
*/
|
||||
void generic_error(const std::string &value);
|
||||
|
||||
// Option getters
|
||||
|
||||
/**
|
||||
* \brief Getter for the service-name tag.
|
||||
*
|
||||
* This method will throw an option_not_found exception if the
|
||||
* option is not found.
|
||||
*/
|
||||
std::string service_name() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the AC-name tag.
|
||||
*
|
||||
* This method will throw an option_not_found exception if the
|
||||
* option is not found.
|
||||
*/
|
||||
std::string ac_name() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the host-uniq tag.
|
||||
*
|
||||
* This method will throw an option_not_found exception if the
|
||||
* option is not found.
|
||||
*/
|
||||
byte_array host_uniq() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the AC-Cookie tag.
|
||||
*
|
||||
* This method will throw an option_not_found exception if the
|
||||
* option is not found.
|
||||
*/
|
||||
byte_array ac_cookie() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the Vendor-Specific tag.
|
||||
*
|
||||
* This method will throw an option_not_found exception if the
|
||||
* option is not found.
|
||||
*/
|
||||
vendor_spec_type vendor_specific() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the Vendor-Specific tag.
|
||||
*
|
||||
* This method will throw an option_not_found exception if the
|
||||
* option is not found.
|
||||
*/
|
||||
byte_array relay_session_id() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the Service-Name-Error tag.
|
||||
*
|
||||
* This method will throw an option_not_found exception if the
|
||||
* option is not found.
|
||||
*/
|
||||
std::string service_name_error() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the AC-System-Error tag.
|
||||
*
|
||||
* This method will throw an option_not_found exception if the
|
||||
* option is not found.
|
||||
*/
|
||||
std::string ac_system_error() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the Generic-Error tag.
|
||||
*
|
||||
* This method will throw an option_not_found exception if the
|
||||
* option is not found.
|
||||
*/
|
||||
std::string generic_error() const;
|
||||
private:
|
||||
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *);
|
||||
|
||||
template<typename T>
|
||||
void add_tag_iterable(tag_identifiers id, const T &data) {
|
||||
add_tag(
|
||||
pppoe_tag(
|
||||
id,
|
||||
data.begin(),
|
||||
data.end()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T retrieve_tag_iterable(tag_identifiers id) const {
|
||||
const pppoe_tag *tag = search_tag(id);
|
||||
if(!tag)
|
||||
throw option_not_found();
|
||||
return T(tag->data_ptr(), tag->data_ptr() + tag->data_size());
|
||||
}
|
||||
|
||||
template<template <typename> class Functor>
|
||||
const pppoe_tag *safe_search_tag(tag_identifiers opt, uint32_t size) const {
|
||||
const pppoe_tag *option = search_tag(opt);
|
||||
if(!option || Functor<uint32_t>()(option->data_size(), size))
|
||||
throw option_not_found();
|
||||
return option;
|
||||
}
|
||||
|
||||
TINS_BEGIN_PACK
|
||||
struct pppoe_hdr {
|
||||
#if TINS_IS_LITTLE_ENDIAN
|
||||
uint8_t version:4,
|
||||
type:4;
|
||||
uint8_t code;
|
||||
#else
|
||||
uint16_t version:4,
|
||||
type:4,
|
||||
code:8;
|
||||
#endif
|
||||
uint16_t session_id;
|
||||
uint16_t payload_length;
|
||||
} TINS_END_PACK;
|
||||
|
||||
pppoe_hdr _header;
|
||||
tags_type _tags;
|
||||
uint16_t _tags_size;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // TINS_PPPoE_H
|
||||
@@ -65,5 +65,6 @@
|
||||
#include "timestamp.h"
|
||||
#include "sll.h"
|
||||
#include "dhcpv6.h"
|
||||
#include "pppoe.h"
|
||||
|
||||
#endif // TINS_TINS_H
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include "eapol.h"
|
||||
#include "rawpdu.h"
|
||||
#include "dot1q.h"
|
||||
#include "pppoe.h"
|
||||
|
||||
using std::string;
|
||||
|
||||
@@ -76,6 +77,8 @@ Tins::PDU *pdu_from_flag(Constants::Ethernet::e flag, const uint8_t *buffer,
|
||||
return new Tins::IPv6(buffer, size);
|
||||
case Tins::Constants::Ethernet::ARP:
|
||||
return new Tins::ARP(buffer, size);
|
||||
case Tins::Constants::Ethernet::PPPOED:
|
||||
return new Tins::PPPoE(buffer, size);
|
||||
case Tins::Constants::Ethernet::EAPOL:
|
||||
return Tins::EAPOL::from_bytes(buffer, size);
|
||||
case Tins::Constants::Ethernet::VLAN:
|
||||
@@ -100,6 +103,8 @@ Tins::PDU *pdu_from_flag(PDU::PDUType type, const uint8_t *buffer, uint32_t size
|
||||
return new Tins::IEEE802_3(buffer, size);
|
||||
case Tins::PDU::RADIOTAP:
|
||||
return new Tins::RadioTap(buffer, size);
|
||||
case Tins::PDU::PPPOE:
|
||||
return new Tins::PPPoE(buffer, size);
|
||||
case Tins::PDU::DOT11:
|
||||
case Tins::PDU::DOT11_ACK:
|
||||
case Tins::PDU::DOT11_ASSOC_REQ:
|
||||
@@ -138,6 +143,8 @@ Constants::Ethernet::e pdu_flag_to_ether_type(PDU::PDUType flag) {
|
||||
return Constants::Ethernet::ARP;
|
||||
case PDU::DOT1Q:
|
||||
return Constants::Ethernet::VLAN;
|
||||
case PDU::PPPOE:
|
||||
return Constants::Ethernet::PPPOED;
|
||||
default:
|
||||
return Constants::Ethernet::UNKNOWN;
|
||||
}
|
||||
|
||||
53
src/ip.cpp
53
src/ip.cpp
@@ -88,45 +88,26 @@ IP::IP(const uint8_t *buffer, uint32_t total_sz)
|
||||
option_identifier opt_type;
|
||||
memcpy(&opt_type, ptr_buffer, sizeof(uint8_t));
|
||||
ptr_buffer++;
|
||||
switch (opt_type.number) {
|
||||
if(opt_type.number > NOOP) {
|
||||
/* Multibyte options with length as second byte */
|
||||
case SEC:
|
||||
case LSSR:
|
||||
case TIMESTAMP:
|
||||
case EXTSEC:
|
||||
case RR:
|
||||
case SID:
|
||||
case SSRR:
|
||||
case MTUPROBE:
|
||||
case MTUREPLY:
|
||||
case EIP:
|
||||
case TR:
|
||||
case ADDEXT:
|
||||
case RTRALT:
|
||||
case SDB:
|
||||
case DPS:
|
||||
case UMP:
|
||||
case QS:
|
||||
if(ptr_buffer == buffer || *ptr_buffer == 0)
|
||||
throw std::runtime_error(msg);
|
||||
|
||||
{
|
||||
const uint8_t data_size = *ptr_buffer - 2;
|
||||
if(data_size > 0) {
|
||||
ptr_buffer++;
|
||||
if(buffer - ptr_buffer < data_size)
|
||||
throw std::runtime_error(msg);
|
||||
_ip_options.push_back(ip_option(opt_type, ptr_buffer, ptr_buffer + data_size));
|
||||
}
|
||||
else
|
||||
_ip_options.push_back(ip_option(opt_type));
|
||||
}
|
||||
if(ptr_buffer == buffer || *ptr_buffer == 0)
|
||||
throw std::runtime_error(msg);
|
||||
|
||||
ptr_buffer += _ip_options.back().data_size() + 1;
|
||||
break;
|
||||
default:
|
||||
const uint8_t data_size = *ptr_buffer - 2;
|
||||
if(data_size > 0) {
|
||||
ptr_buffer++;
|
||||
if(buffer - ptr_buffer < data_size)
|
||||
throw std::runtime_error(msg);
|
||||
_ip_options.push_back(ip_option(opt_type, ptr_buffer, ptr_buffer + data_size));
|
||||
}
|
||||
else
|
||||
_ip_options.push_back(ip_option(opt_type));
|
||||
break;
|
||||
|
||||
ptr_buffer += _ip_options.back().data_size() + 1;
|
||||
}
|
||||
else {
|
||||
_ip_options.push_back(ip_option(opt_type));
|
||||
break;
|
||||
}
|
||||
_options_size += _ip_options.back().data_size() + 2;
|
||||
}
|
||||
|
||||
245
src/pppoe.cpp
Normal file
245
src/pppoe.cpp
Normal file
@@ -0,0 +1,245 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Nasel
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef TINS_DEBUG
|
||||
#include <cassert>
|
||||
#endif
|
||||
#include <cstring>
|
||||
#include "pppoe.h"
|
||||
|
||||
namespace Tins {
|
||||
|
||||
PPPoE::PPPoE()
|
||||
: _header(), _tags_size()
|
||||
{
|
||||
version(1);
|
||||
type(1);
|
||||
}
|
||||
|
||||
PPPoE::PPPoE(const uint8_t *buffer, uint32_t total_sz)
|
||||
: _tags_size()
|
||||
{
|
||||
const char *err_msg = "Not enough size for a PPPoE";
|
||||
if(total_sz < sizeof(_header))
|
||||
throw std::runtime_error(err_msg);
|
||||
std::memcpy(&_header, buffer, sizeof(_header));
|
||||
buffer += sizeof(_header);
|
||||
total_sz -= sizeof(_header);
|
||||
const uint8_t *end = buffer + total_sz;
|
||||
while(buffer < end) {
|
||||
if(buffer + sizeof(uint32_t) * 2 > end)
|
||||
throw std::runtime_error(err_msg);
|
||||
uint16_t opt_type = *(const uint16_t*)buffer;
|
||||
uint16_t opt_len = *(const uint16_t*)(buffer + sizeof(uint16_t));
|
||||
buffer += sizeof(uint16_t) * 2;
|
||||
total_sz -= sizeof(uint16_t) * 2;
|
||||
if(Endian::be_to_host(opt_len) > total_sz)
|
||||
throw std::runtime_error(err_msg);
|
||||
add_tag(
|
||||
pppoe_tag(
|
||||
static_cast<tag_identifiers>(opt_type),
|
||||
Endian::be_to_host(opt_len),
|
||||
buffer
|
||||
)
|
||||
);
|
||||
buffer += Endian::be_to_host(opt_len);
|
||||
total_sz -= Endian::be_to_host(opt_len);
|
||||
}
|
||||
}
|
||||
|
||||
const PPPoE::pppoe_tag *PPPoE::search_tag(tag_identifiers identifier) const {
|
||||
for(tags_type::const_iterator it = _tags.begin(); it != _tags.end(); ++it) {
|
||||
if(it->option() == identifier)
|
||||
return &*it;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PPPoE::version(small_uint<4> new_version) {
|
||||
_header.version = new_version;
|
||||
}
|
||||
|
||||
void PPPoE::type(small_uint<4> new_type) {
|
||||
_header.type = new_type;
|
||||
}
|
||||
|
||||
void PPPoE::code(uint8_t new_code) {
|
||||
_header.code = new_code;
|
||||
}
|
||||
|
||||
void PPPoE::session_id(uint16_t new_session_id) {
|
||||
_header.session_id = Endian::host_to_be(new_session_id);
|
||||
}
|
||||
|
||||
void PPPoE::payload_length(uint16_t new_payload_length) {
|
||||
_header.payload_length = Endian::host_to_be(new_payload_length);
|
||||
}
|
||||
|
||||
uint32_t PPPoE::header_size() const {
|
||||
return sizeof(_header) + _tags_size;
|
||||
}
|
||||
|
||||
void PPPoE::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *)
|
||||
{
|
||||
#ifdef TINS_DEBUG
|
||||
assert(total_sz == sizeof(_header) + _tags_size);
|
||||
#endif
|
||||
std::memcpy(buffer, &_header, sizeof(_header));
|
||||
if(_tags_size > 0)
|
||||
((pppoe_hdr*)buffer)->payload_length = Endian::host_to_be(_tags_size);
|
||||
buffer += sizeof(_header);
|
||||
for(tags_type::const_iterator it = _tags.begin(); it != _tags.end(); ++it) {
|
||||
*(uint16_t*)buffer = it->option();
|
||||
*(uint16_t*)(buffer + sizeof(uint16_t)) = Endian::host_to_be<uint16_t>(it->length_field());
|
||||
std::copy(
|
||||
it->data_ptr(),
|
||||
it->data_ptr() + it->data_size(),
|
||||
buffer + sizeof(uint16_t) * 2
|
||||
);
|
||||
buffer += sizeof(uint16_t) * 2 + it->data_size();
|
||||
}
|
||||
}
|
||||
|
||||
void PPPoE::add_tag(const pppoe_tag &option) {
|
||||
_tags_size += option.data_size() + sizeof(uint16_t) * 2;
|
||||
_tags.push_back(option);
|
||||
}
|
||||
|
||||
#if TINS_IS_CXX11
|
||||
void PPPoE::add_tag(pppoe_tag &&option) {
|
||||
_tags_size += option.data_size() + sizeof(uint16_t) * 2;
|
||||
_tags.push_back(std::move(option));
|
||||
}
|
||||
#endif
|
||||
|
||||
// *********************** Setters *************************
|
||||
|
||||
void PPPoE::end_of_list() {
|
||||
add_tag(
|
||||
END_OF_LIST
|
||||
);
|
||||
}
|
||||
|
||||
void PPPoE::service_name(const std::string &value) {
|
||||
add_tag_iterable(SERVICE_NAME, value);
|
||||
}
|
||||
|
||||
void PPPoE::ac_name(const std::string &value) {
|
||||
add_tag_iterable(AC_NAME, value);
|
||||
}
|
||||
|
||||
void PPPoE::host_uniq(const byte_array &value) {
|
||||
add_tag_iterable(HOST_UNIQ, value);
|
||||
}
|
||||
|
||||
void PPPoE::ac_cookie(const byte_array &value) {
|
||||
add_tag_iterable(AC_COOKIE, value);
|
||||
}
|
||||
|
||||
void PPPoE::vendor_specific(const vendor_spec_type &value) {
|
||||
std::vector<uint8_t> buffer(sizeof(uint32_t) + value.data.size());
|
||||
*(uint32_t*)&buffer[0] = Endian::host_to_be(value.vendor_id);
|
||||
std::copy(
|
||||
value.data.begin(),
|
||||
value.data.end(),
|
||||
buffer.begin() + sizeof(uint32_t)
|
||||
);
|
||||
add_tag(
|
||||
pppoe_tag(
|
||||
VENDOR_SPECIFIC,
|
||||
buffer.begin(),
|
||||
buffer.end()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
void PPPoE::relay_session_id(const byte_array &value) {
|
||||
add_tag_iterable(RELAY_SESSION_ID, value);
|
||||
}
|
||||
|
||||
void PPPoE::service_name_error(const std::string &value) {
|
||||
add_tag_iterable(SERVICE_NAME_ERROR, value);
|
||||
}
|
||||
|
||||
void PPPoE::ac_system_error(const std::string &value) {
|
||||
add_tag_iterable(AC_SYSTEM_ERROR, value);
|
||||
}
|
||||
|
||||
void PPPoE::generic_error(const std::string &value) {
|
||||
add_tag_iterable(GENERIC_ERROR, value);
|
||||
}
|
||||
|
||||
// *********************** Getters *************************
|
||||
|
||||
std::string PPPoE::service_name() const {
|
||||
return retrieve_tag_iterable<std::string>(SERVICE_NAME);
|
||||
}
|
||||
|
||||
std::string PPPoE::ac_name() const {
|
||||
return retrieve_tag_iterable<std::string>(AC_NAME);
|
||||
}
|
||||
|
||||
byte_array PPPoE::host_uniq() const {
|
||||
return retrieve_tag_iterable<byte_array>(HOST_UNIQ);
|
||||
}
|
||||
|
||||
byte_array PPPoE::ac_cookie() const {
|
||||
return retrieve_tag_iterable<byte_array>(AC_COOKIE);
|
||||
}
|
||||
|
||||
PPPoE::vendor_spec_type PPPoE::vendor_specific() const {
|
||||
const pppoe_tag *tag = safe_search_tag<std::less>(
|
||||
VENDOR_SPECIFIC, sizeof(uint32_t)
|
||||
);
|
||||
vendor_spec_type output;
|
||||
output.vendor_id = Endian::be_to_host(*(const uint32_t*)tag->data_ptr());
|
||||
output.data.assign(
|
||||
tag->data_ptr() + sizeof(uint32_t),
|
||||
tag->data_ptr() + tag->data_size()
|
||||
);
|
||||
return output;
|
||||
}
|
||||
|
||||
byte_array PPPoE::relay_session_id() const {
|
||||
return retrieve_tag_iterable<byte_array>(RELAY_SESSION_ID);
|
||||
}
|
||||
|
||||
std::string PPPoE::service_name_error() const {
|
||||
return retrieve_tag_iterable<std::string>(SERVICE_NAME_ERROR);
|
||||
}
|
||||
|
||||
std::string PPPoE::ac_system_error() const {
|
||||
return retrieve_tag_iterable<std::string>(AC_SYSTEM_ERROR);
|
||||
}
|
||||
|
||||
std::string PPPoE::generic_error() const {
|
||||
return retrieve_tag_iterable<std::string>(GENERIC_ERROR);
|
||||
}
|
||||
} //namespace Tins
|
||||
|
||||
@@ -721,6 +721,23 @@
|
||||
../include/hw_address.h:
|
||||
|
||||
../include/ip_address.h:
|
||||
../src/pppoe.o: ../src/pppoe.cpp ../include/pppoe.h ../include/pdu.h \
|
||||
../include/macros.h ../include/endianness.h ../include/small_uint.h \
|
||||
../include/pdu_option.h ../include/cxxstd.h
|
||||
|
||||
../include/pppoe.h:
|
||||
|
||||
../include/pdu.h:
|
||||
|
||||
../include/macros.h:
|
||||
|
||||
../include/endianness.h:
|
||||
|
||||
../include/small_uint.h:
|
||||
|
||||
../include/pdu_option.h:
|
||||
|
||||
../include/cxxstd.h:
|
||||
../src/radiotap.o: ../src/radiotap.cpp ../include/macros.h \
|
||||
../include/radiotap.h ../include/macros.h ../include/pdu.h \
|
||||
../include/endianness.h ../include/network_interface.h \
|
||||
@@ -2074,6 +2091,23 @@ src/pdu.o: src/pdu.cpp ../include/ip.h ../include/pdu.h \
|
||||
../include/packet.h:
|
||||
|
||||
../include/timestamp.h:
|
||||
src/pppoe.o: src/pppoe.cpp ../include/pppoe.h ../include/pdu.h \
|
||||
../include/macros.h ../include/endianness.h ../include/small_uint.h \
|
||||
../include/pdu_option.h ../include/cxxstd.h
|
||||
|
||||
../include/pppoe.h:
|
||||
|
||||
../include/pdu.h:
|
||||
|
||||
../include/macros.h:
|
||||
|
||||
../include/endianness.h:
|
||||
|
||||
../include/small_uint.h:
|
||||
|
||||
../include/pdu_option.h:
|
||||
|
||||
../include/cxxstd.h:
|
||||
src/radiotap.o: src/radiotap.cpp ../include/radiotap.h \
|
||||
../include/macros.h ../include/pdu.h ../include/endianness.h \
|
||||
../include/network_interface.h ../include/hw_address.h \
|
||||
|
||||
176
tests/src/pppoe.cpp
Normal file
176
tests/src/pppoe.cpp
Normal file
@@ -0,0 +1,176 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <stdint.h>
|
||||
#include "pppoe.h"
|
||||
#include "ethernetII.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace Tins;
|
||||
|
||||
class PPPoETest : public testing::Test {
|
||||
public:
|
||||
static const uint8_t expected_packet[];
|
||||
};
|
||||
|
||||
const uint8_t PPPoETest::expected_packet[] = {
|
||||
17, 9, 0, 0, 0, 16, 1, 1, 0, 0, 1, 2, 0, 0, 1, 3, 0, 4, 97, 98, 99, 100
|
||||
};
|
||||
|
||||
TEST_F(PPPoETest, DefaultConstructor) {
|
||||
PPPoE pdu;
|
||||
EXPECT_EQ(1, pdu.version());
|
||||
EXPECT_EQ(1, pdu.type());
|
||||
EXPECT_EQ(0, pdu.code());
|
||||
EXPECT_EQ(0, pdu.session_id());
|
||||
EXPECT_EQ(0, pdu.payload_length());
|
||||
}
|
||||
|
||||
TEST_F(PPPoETest, ConstructorFromBuffer) {
|
||||
PPPoE pdu(expected_packet, sizeof(expected_packet));
|
||||
EXPECT_EQ(1, pdu.version());
|
||||
EXPECT_EQ(1, pdu.type());
|
||||
EXPECT_EQ(0x09, pdu.code());
|
||||
EXPECT_EQ(0, pdu.session_id());
|
||||
EXPECT_EQ(16, pdu.payload_length());
|
||||
EXPECT_EQ(3, pdu.tags().size());
|
||||
|
||||
EXPECT_EQ("", pdu.service_name());
|
||||
ASSERT_TRUE(pdu.search_tag(PPPoE::SERVICE_NAME));
|
||||
}
|
||||
|
||||
TEST_F(PPPoETest, StackedOnEthernet) {
|
||||
EthernetII eth = EthernetII() / PPPoE();
|
||||
PDU::serialization_type buffer = eth.serialize();
|
||||
EthernetII eth2(&buffer[0], buffer.size());
|
||||
ASSERT_TRUE(eth2.find_pdu<PPPoE>());
|
||||
}
|
||||
|
||||
TEST_F(PPPoETest, Serialize) {
|
||||
PPPoE pdu(expected_packet, sizeof(expected_packet));
|
||||
PPPoE::serialization_type buffer = pdu.serialize();
|
||||
EXPECT_EQ(
|
||||
PPPoE::serialization_type(expected_packet, expected_packet + sizeof(expected_packet)),
|
||||
buffer
|
||||
);
|
||||
}
|
||||
|
||||
TEST_F(PPPoETest, Version) {
|
||||
PPPoE pdu;
|
||||
pdu.version(6);
|
||||
EXPECT_EQ(6, pdu.version());
|
||||
}
|
||||
|
||||
TEST_F(PPPoETest, Type) {
|
||||
PPPoE pdu;
|
||||
pdu.type(6);
|
||||
EXPECT_EQ(6, pdu.type());
|
||||
}
|
||||
|
||||
TEST_F(PPPoETest, Code) {
|
||||
PPPoE pdu;
|
||||
pdu.code(0x7a);
|
||||
EXPECT_EQ(0x7a, pdu.code());
|
||||
}
|
||||
|
||||
TEST_F(PPPoETest, SessionID) {
|
||||
PPPoE pdu;
|
||||
pdu.session_id(0x9182);
|
||||
EXPECT_EQ(0x9182, pdu.session_id());
|
||||
}
|
||||
|
||||
TEST_F(PPPoETest, PayloadLength) {
|
||||
PPPoE pdu;
|
||||
pdu.payload_length(0x9182);
|
||||
EXPECT_EQ(0x9182, pdu.payload_length());
|
||||
}
|
||||
|
||||
TEST_F(PPPoETest, ServiceName) {
|
||||
PPPoE pdu;
|
||||
pdu.service_name("carlos");
|
||||
EXPECT_EQ("carlos", pdu.service_name());
|
||||
}
|
||||
|
||||
TEST_F(PPPoETest, ACName) {
|
||||
PPPoE pdu;
|
||||
pdu.ac_name("carlos");
|
||||
EXPECT_EQ("carlos", pdu.ac_name());
|
||||
}
|
||||
|
||||
TEST_F(PPPoETest, HostUniq) {
|
||||
PPPoE pdu;
|
||||
uint8_t a[] = { 1,2,3,4,5,6 };
|
||||
byte_array data(a, a + sizeof(a));
|
||||
pdu.host_uniq(data);
|
||||
EXPECT_EQ(data, pdu.host_uniq());
|
||||
}
|
||||
|
||||
TEST_F(PPPoETest, ACCookie) {
|
||||
PPPoE pdu;
|
||||
uint8_t a[] = { 1,2,3,4,5,6 };
|
||||
byte_array data(a, a + sizeof(a));
|
||||
pdu.ac_cookie(data);
|
||||
EXPECT_EQ(data, pdu.ac_cookie());
|
||||
}
|
||||
|
||||
TEST_F(PPPoETest, VendorSpecific) {
|
||||
PPPoE pdu;
|
||||
uint8_t a[] = { 1,2,3,4,5,6 };
|
||||
PPPoE::vendor_spec_type output, data(
|
||||
0x9283f78,
|
||||
PPPoE::vendor_spec_type::data_type(a, a + sizeof(a))
|
||||
);
|
||||
pdu.vendor_specific(data);
|
||||
output = pdu.vendor_specific();
|
||||
EXPECT_EQ(data.data, output.data);
|
||||
EXPECT_EQ(data.vendor_id, output.vendor_id);
|
||||
}
|
||||
|
||||
TEST_F(PPPoETest, RelaySessionID) {
|
||||
PPPoE pdu;
|
||||
uint8_t a[] = { 1,2,3,4,5,6 };
|
||||
byte_array data(a, a + sizeof(a));
|
||||
pdu.relay_session_id(data);
|
||||
EXPECT_EQ(data, pdu.relay_session_id());
|
||||
}
|
||||
|
||||
TEST_F(PPPoETest, ServiceNameError) {
|
||||
{
|
||||
PPPoE pdu;
|
||||
pdu.service_name_error("carlos");
|
||||
EXPECT_EQ("carlos", pdu.service_name_error());
|
||||
}
|
||||
{
|
||||
PPPoE pdu;
|
||||
pdu.service_name_error("");
|
||||
EXPECT_EQ("", pdu.service_name_error());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(PPPoETest, ACSystemError) {
|
||||
PPPoE pdu;
|
||||
pdu.ac_system_error("carlos");
|
||||
EXPECT_EQ("carlos", pdu.ac_system_error());
|
||||
}
|
||||
|
||||
TEST_F(PPPoETest, GenericError) {
|
||||
PPPoE pdu;
|
||||
pdu.generic_error("carlos");
|
||||
EXPECT_EQ("carlos", pdu.generic_error());
|
||||
}
|
||||
|
||||
TEST_F(PPPoETest, SpoofedOptions) {
|
||||
PPPoE pdu;
|
||||
uint8_t a[] = { 1,2,3,4,5,6 };
|
||||
pdu.add_tag(
|
||||
PPPoE::pppoe_tag(PPPoE::VENDOR_SPECIFIC, 65000, a, a + sizeof(a))
|
||||
);
|
||||
pdu.add_tag(
|
||||
PPPoE::pppoe_tag(PPPoE::VENDOR_SPECIFIC, 65000, a, a + sizeof(a))
|
||||
);
|
||||
pdu.add_tag(
|
||||
PPPoE::pppoe_tag(PPPoE::VENDOR_SPECIFIC, 65000, a, a + sizeof(a))
|
||||
);
|
||||
// probably we'd expect it to crash if it's not working, valgrind plx
|
||||
EXPECT_EQ(3, pdu.tags().size());
|
||||
}
|
||||
Reference in New Issue
Block a user