version 0.0.1
This commit is contained in:
56
include/PacketDissection/MbufContainer.hpp
Normal file
56
include/PacketDissection/MbufContainer.hpp
Normal file
@@ -0,0 +1,56 @@
|
||||
#pragma once
|
||||
|
||||
#include <rte_ethdev.h>
|
||||
#include <rte_mbuf.h>
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
#include "Definitions.hpp"
|
||||
|
||||
#define ERROR_STR_MBUF_CONTAINER_INDEX_OUT_OF_BOUNDS \
|
||||
"Index is out of bounds of MbufContainer."
|
||||
|
||||
/**
|
||||
* @brief like the PacketContainer but it only holds mbufs plus some minor
|
||||
* performance improvements
|
||||
*
|
||||
* \todo Has to be documented with more details
|
||||
*
|
||||
*/
|
||||
class MbufContainer {
|
||||
protected:
|
||||
uint16_t _nb_mbufs_in_container;
|
||||
|
||||
rte_mbuf* _mbuf_arr[BURST_SIZE];
|
||||
|
||||
rte_mempool* _mempool;
|
||||
|
||||
public:
|
||||
inline MbufContainer(rte_mempool* mempool)
|
||||
: _mempool(mempool), _nb_mbufs_in_container(0) {}
|
||||
|
||||
/**
|
||||
* @brief Get the mbuf at index
|
||||
*
|
||||
* @param index
|
||||
* @return rte_mbuf*
|
||||
*/
|
||||
inline rte_mbuf* get_mbuf_at_index(int index) {
|
||||
check_index(index);
|
||||
return _mbuf_arr[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the number of mbufs
|
||||
*
|
||||
* @return uint16_t
|
||||
*/
|
||||
inline uint16_t get_number_of_mbufs() { return _nb_mbufs_in_container; }
|
||||
|
||||
inline void check_index(int index) {
|
||||
if (unlikely(index >= _nb_mbufs_in_container || index < 0)) {
|
||||
throw std::runtime_error(
|
||||
ERROR_STR_MBUF_CONTAINER_INDEX_OUT_OF_BOUNDS);
|
||||
}
|
||||
}
|
||||
};
|
||||
36
include/PacketDissection/MbufContainerReceiving.hpp
Normal file
36
include/PacketDissection/MbufContainerReceiving.hpp
Normal file
@@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#include <rte_ethdev.h>
|
||||
#include <rte_mbuf.h>
|
||||
|
||||
#include "Definitions.hpp"
|
||||
#include "PacketDissection/MbufContainer.hpp"
|
||||
|
||||
/**
|
||||
* @brief for received mbufs. you poll them, read them and finally... forget
|
||||
* them
|
||||
*
|
||||
*/
|
||||
class MbufContainerReceiving : public MbufContainer {
|
||||
private:
|
||||
uint16_t _rx_port;
|
||||
uint16_t _rx_queue;
|
||||
|
||||
public:
|
||||
inline MbufContainerReceiving(rte_mempool* mempool, uint16_t rx_port,
|
||||
uint16_t rx_queue)
|
||||
: MbufContainer(mempool), _rx_port(rx_port), _rx_queue(rx_queue) {}
|
||||
|
||||
/**
|
||||
* @brief poll mbufs
|
||||
*
|
||||
* @return uint16_t
|
||||
*/
|
||||
inline uint16_t poll_mbufs() {
|
||||
|
||||
_nb_mbufs_in_container =
|
||||
rte_eth_rx_burst(_rx_port, _rx_queue, _mbuf_arr, BURST_SIZE);
|
||||
|
||||
return _nb_mbufs_in_container;
|
||||
}
|
||||
};
|
||||
75
include/PacketDissection/MbufContainerTransmitting.hpp
Normal file
75
include/PacketDissection/MbufContainerTransmitting.hpp
Normal file
@@ -0,0 +1,75 @@
|
||||
#pragma once
|
||||
|
||||
#include <rte_ethdev.h>
|
||||
#include <rte_mbuf.h>
|
||||
|
||||
#include "PacketDissection/MbufContainer.hpp"
|
||||
|
||||
/**
|
||||
* @brief for transmitted mbufs.
|
||||
*
|
||||
*/
|
||||
class MbufContainerTransmitting : public MbufContainer {
|
||||
private:
|
||||
uint16_t _tx_port;
|
||||
uint16_t _tx_queue;
|
||||
|
||||
public:
|
||||
inline MbufContainerTransmitting(rte_mempool* mempool, uint16_t tx_port,
|
||||
uint16_t tx_queue)
|
||||
: MbufContainer(mempool), _tx_port(tx_port), _tx_queue(tx_queue) {}
|
||||
|
||||
/**
|
||||
* @brief add mbuf to container
|
||||
*
|
||||
* This method may delete the mbuf given if the container is full
|
||||
*
|
||||
* @param mbuf
|
||||
*/
|
||||
inline void add_mbuf(rte_mbuf* mbuf) {
|
||||
if (likely(_nb_mbufs_in_container < BURST_SIZE)) {
|
||||
_mbuf_arr[_nb_mbufs_in_container] = mbuf;
|
||||
++_nb_mbufs_in_container;
|
||||
} else {
|
||||
rte_pktmbuf_free(mbuf);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief create new mbuf in the container and return the pointer to it
|
||||
*
|
||||
* @return rte_mbuf*:
|
||||
* - normally: a newly created mbuf is returned
|
||||
* - if container is full and no mbuf can be added anymore: nullptr
|
||||
*/
|
||||
inline rte_mbuf* get_empty_mbuf() {
|
||||
if (likely(_nb_mbufs_in_container < BURST_SIZE)) {
|
||||
_mbuf_arr[_nb_mbufs_in_container] = rte_pktmbuf_alloc(_mempool);
|
||||
return _mbuf_arr[_nb_mbufs_in_container++];
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief send every mbuf contained in the container
|
||||
*
|
||||
*/
|
||||
inline void send_mbufs() {
|
||||
if (likely(_nb_mbufs_in_container > 0)) {
|
||||
|
||||
// send mbufs
|
||||
uint16_t nb_mbufs_sent = rte_eth_tx_burst(
|
||||
_tx_port, _tx_queue, _mbuf_arr, _nb_mbufs_in_container);
|
||||
|
||||
// Free any unsent packets.
|
||||
if (unlikely(nb_mbufs_sent < _nb_mbufs_in_container)) {
|
||||
for (int i = nb_mbufs_sent; i < _nb_mbufs_in_container; ++i) {
|
||||
rte_pktmbuf_free(_mbuf_arr[i]);
|
||||
}
|
||||
}
|
||||
|
||||
_nb_mbufs_in_container = 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
563
include/PacketDissection/PacketContainer.hpp
Normal file
563
include/PacketDissection/PacketContainer.hpp
Normal file
@@ -0,0 +1,563 @@
|
||||
#pragma once
|
||||
|
||||
#include <rte_ethdev.h>
|
||||
#include <rte_mbuf.h>
|
||||
#include <rte_mempool.h>
|
||||
|
||||
#include <boost/log/trivial.hpp>
|
||||
#include <stdexcept>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "Definitions.hpp"
|
||||
#include "PacketDissection/PacketInfo.hpp"
|
||||
#include "PacketDissection/PacketInfoCreator.hpp"
|
||||
|
||||
#define ERROR_STR_INDEX_OUT_OF_BOUNDS \
|
||||
"index is out of bounds of PacketContainer. The highest possible index " \
|
||||
"can be accessed by get_total_number_of_packets()."
|
||||
|
||||
/**
|
||||
* This class can poll, send and hold packets.
|
||||
*
|
||||
* Think of this data type as a list of packets holding the packets themself
|
||||
* as well as meta information per packet. If you want to access a certain
|
||||
* packet (e.g. within a for function) you can use the methods provided with
|
||||
* a packet index.
|
||||
*
|
||||
* You can iterate either only over packets that were polled or over
|
||||
* all packets in the container.
|
||||
* - Usually if you create a packet you also want to send it and do not
|
||||
* look at it anymore after the creation. So the only packets to look at are
|
||||
* those that where being polled. If this is the case it would be more
|
||||
* efficient to only iterate over polled packets.
|
||||
* - The latter includes both packets polled and packets you
|
||||
* created yourselve with one of the corresponding methods. It could be
|
||||
* helpful in other situations.
|
||||
*
|
||||
* The maximum of packets to iterate over is therefore the
|
||||
* number of polled packets / the total number of packets which both can be
|
||||
* accessed each with the corresponding getter method. Remember that the
|
||||
* indices begin at 0 so the last element is at index (nb_packets - 1).
|
||||
*
|
||||
* To manipulate a packet / read data from it you have to get the PacketInfo
|
||||
* object at a cretain index with the corresponding method. Consult the
|
||||
* PacketInfo documentation for further information.
|
||||
*
|
||||
* NOTICE: It is possible that you get nullptr instead of a PacketInfo
|
||||
* pointer if you get a packet with one of the corresponding methods. Test
|
||||
* if this is the case (e.g. ptr == nullptr) before going ahead working with
|
||||
* the PacketInfo object.
|
||||
*
|
||||
* If you want to create a new packet do not construct a new PacketInfo
|
||||
* object. Use the method get_empty_packet instead. This is more efficient.
|
||||
*
|
||||
* An object of this class is initialized with the ID of the rx queue and the
|
||||
* tx queue of the thread that uses the object. Since corresponding [r|t]x
|
||||
* queues each on one port have the same ID it is only necessary to store the ID
|
||||
* of one rx queue and one tx queue.
|
||||
*/
|
||||
class PacketContainer {
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new Packet Container object
|
||||
*
|
||||
* @param pkt_handler
|
||||
* @param mbuf_pool
|
||||
* @param entrance_port
|
||||
* @param exit_port
|
||||
* @param rx_queue_number ID of the rx queues
|
||||
* @param tx_queue_number ID of the tx queues
|
||||
*/
|
||||
inline PacketContainer(struct rte_mempool* mbuf_pool,
|
||||
uint16_t entrance_port, uint16_t exit_port,
|
||||
uint16_t rx_queue_number, uint16_t tx_queue_number)
|
||||
: _mempool(mbuf_pool), _entrance_port(entrance_port),
|
||||
_exit_port(exit_port), _nb_pkts_polled(0), _nb_pkts_total(0),
|
||||
_nb_pkts_dropped(0), _nb_pkt_arrays(1),
|
||||
_rx_queue_number(rx_queue_number), _tx_queue_number(tx_queue_number) {
|
||||
|
||||
for (int i = 0; i < NUM_MBUF_ARRS; ++i) {
|
||||
_nb_mbufs_in_mbuf_arr[i] = 0;
|
||||
|
||||
for (int j = 0; j < BURST_SIZE; ++j) {
|
||||
_mbuf_arrs[i][j] = nullptr;
|
||||
_pkt_info_arrs[i][j] = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
~PacketContainer() { empty_container(); }
|
||||
|
||||
/**
|
||||
* @brief Poll packets into the container
|
||||
*
|
||||
* The operation poll_packets does not guarantee that more than 0 packets
|
||||
* were polled. If there are no packets on the NIC port, nothing can be
|
||||
* polled. So you have to be able to check if packets actually were polled.
|
||||
* This could be important, e.g if you want to skip certain parts of your
|
||||
* program if no packets were polled. For the sake of efficiency you do not
|
||||
* do this with a getter that returns the state but with a pass-by-reference
|
||||
* variable that you pass to the poll_packets operation- After the execution
|
||||
* of poll_packets this variable holds the number of packets actually
|
||||
* polled.
|
||||
*
|
||||
* Also if you poll packets but did not send the packets currently being in
|
||||
* the PacketContainer they are going to be overwritten.
|
||||
*
|
||||
* @param[out] nb_pkts_polled after execution: holds number of packets
|
||||
* actually polled.
|
||||
*/
|
||||
inline void poll_packets(uint16_t& nb_pkts_polled) {
|
||||
empty_container();
|
||||
|
||||
_nb_pkts_polled = rte_eth_rx_burst(_entrance_port, _rx_queue_number,
|
||||
_mbuf_arrs[0], BURST_SIZE);
|
||||
|
||||
_nb_pkts_total = _nb_pkts_polled;
|
||||
|
||||
if (_nb_pkts_polled > 0) {
|
||||
_nb_pkt_arrays = 1;
|
||||
_nb_mbufs_in_mbuf_arr[0] = _nb_pkts_polled;
|
||||
}
|
||||
|
||||
extract_header_info();
|
||||
|
||||
// return
|
||||
nb_pkts_polled = _nb_pkts_polled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Send packets from the container
|
||||
*
|
||||
* Sent packets are no longer available after being sent.
|
||||
* @return total number of packets send
|
||||
*/
|
||||
inline uint send_packets() {
|
||||
uint sum_pkts_send = 0;
|
||||
if (likely(_nb_pkts_total > 0)) {
|
||||
if (_nb_pkts_dropped != 0) {
|
||||
reorder_mbuf_arrays();
|
||||
}
|
||||
|
||||
for (int i = 0; i < _nb_pkt_arrays; ++i) {
|
||||
uint16_t nb_pkts_to_send = _nb_mbufs_in_mbuf_arr[i];
|
||||
|
||||
// send mbufs
|
||||
uint16_t nb_pkts_sent =
|
||||
rte_eth_tx_burst(_exit_port, _tx_queue_number,
|
||||
_mbuf_arrs[i], nb_pkts_to_send);
|
||||
|
||||
#ifdef LOG_PKTS_SENT
|
||||
LOG_INFO << "Number of packets sent: " << nb_pkts_sent
|
||||
<< " and this should have been sent: "
|
||||
<< nb_pkts_to_send << LOG_END;
|
||||
#endif
|
||||
|
||||
sum_pkts_send += nb_pkts_sent;
|
||||
// Free any unsent packets.
|
||||
if (unlikely(nb_pkts_sent < nb_pkts_to_send)) {
|
||||
for (int j = nb_pkts_sent; j < nb_pkts_to_send; ++j) {
|
||||
rte_pktmbuf_free(_mbuf_arrs[i][j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
empty_container();
|
||||
return sum_pkts_send;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Drop packet.
|
||||
*
|
||||
* @param index Index of the packet to drop.
|
||||
*/
|
||||
inline void drop_packet(int index) {
|
||||
if (index >= _nb_pkts_total) {
|
||||
throw std::runtime_error(ERROR_STR_INDEX_OUT_OF_BOUNDS);
|
||||
}
|
||||
|
||||
int i = -1;
|
||||
int j = -1;
|
||||
calculate_array_coordinates_from_index(index, i, j);
|
||||
|
||||
PacketInfoCreator::destroy_pkt_info(_pkt_info_arrs[i][j]);
|
||||
|
||||
if (unlikely(_mbuf_arrs[i][j] != nullptr)) {
|
||||
rte_pktmbuf_free(_mbuf_arrs[i][j]);
|
||||
}
|
||||
|
||||
_pkt_info_arrs[i][j] = nullptr;
|
||||
_mbuf_arrs[i][j] = nullptr;
|
||||
|
||||
++_nb_pkts_dropped;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Drop packet.
|
||||
*
|
||||
* @param index Index of the packet to drop.
|
||||
*/
|
||||
inline void drop_packet(int index, PacketInfoIpv4Tcp* pkt_to_drop) {
|
||||
if (index >= _nb_pkts_total) {
|
||||
throw std::runtime_error(ERROR_STR_INDEX_OUT_OF_BOUNDS);
|
||||
}
|
||||
|
||||
int i = -1;
|
||||
int j = -1;
|
||||
calculate_array_coordinates_from_index(index, i, j);
|
||||
|
||||
delete pkt_to_drop;
|
||||
|
||||
if (unlikely(_mbuf_arrs[i][j] != nullptr)) {
|
||||
rte_pktmbuf_free(_mbuf_arrs[i][j]);
|
||||
}
|
||||
|
||||
_pkt_info_arrs[i][j] = nullptr;
|
||||
_mbuf_arrs[i][j] = nullptr;
|
||||
|
||||
++_nb_pkts_dropped;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Take the packet
|
||||
*
|
||||
* Return a PacketInfo object. The corresponding packet will be removed from
|
||||
* the PacketContainer so it is no longer in there and will not be sent. The
|
||||
* only reference available to the packet is the returned PacketInfo
|
||||
* pointer.
|
||||
*
|
||||
* Because the packet is removed from the container the responsibility for
|
||||
* dropping|sending the packet is up to you. Usually you would add this
|
||||
* packet to a packet container and sen dor drop the packet afterwards.
|
||||
*
|
||||
* If you want to just get the pointer to a PacketInfo object that sould
|
||||
* remain in the container do not use this method.
|
||||
*
|
||||
* @param index
|
||||
* @return PacketInfo*
|
||||
*/
|
||||
inline PacketInfo* take_packet(int index) {
|
||||
if (index >= _nb_pkts_total) {
|
||||
throw std::runtime_error(ERROR_STR_INDEX_OUT_OF_BOUNDS);
|
||||
}
|
||||
|
||||
int i, j;
|
||||
calculate_array_coordinates_from_index(index, i, j);
|
||||
PacketInfo* pkt_info = _pkt_info_arrs[i][j];
|
||||
_pkt_info_arrs[i][j] = nullptr;
|
||||
_mbuf_arrs[i][j] = nullptr;
|
||||
++_nb_pkts_dropped;
|
||||
|
||||
++_nb_pkts_dropped;
|
||||
|
||||
return pkt_info;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief add Packet to Container which already exists but is stored
|
||||
* somewhere else.
|
||||
*
|
||||
* Add Packet to container which already exists but is stored
|
||||
* somewhere else. All values (payload and metadata) of the passed mbuf will
|
||||
* be adopted. These are set as
|
||||
* parameter of the function call.
|
||||
*
|
||||
* @param[in] pkt_container packet container pointer to the packet to be
|
||||
* added
|
||||
* @return index of the newly added packet
|
||||
*/
|
||||
inline int add_packet(PacketInfo* pkt_info) {
|
||||
int i, j;
|
||||
calculate_array_coordinates_from_index(_nb_pkts_total, i, j);
|
||||
_mbuf_arrs[i][j] = pkt_info->get_mbuf();
|
||||
_pkt_info_arrs[i][j] = pkt_info;
|
||||
|
||||
++_nb_pkts_total;
|
||||
++_nb_mbufs_in_mbuf_arr[i];
|
||||
|
||||
if (unlikely(BURST_SIZE * _nb_pkt_arrays < _nb_pkts_total)) {
|
||||
++_nb_pkt_arrays;
|
||||
}
|
||||
|
||||
return _nb_pkts_total - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the PacketInfo object at index
|
||||
*
|
||||
* Use this Method to get a packet and work with it (read, write
|
||||
* information). You do not have to add it to the PacketContainer again. The
|
||||
* packet is still in the Container you only get the reference.
|
||||
*
|
||||
* @param index
|
||||
* @return PacketInfo*
|
||||
*/
|
||||
inline PacketInfo* get_packet_at_index(int index) {
|
||||
if (index >= _nb_pkts_total) {
|
||||
throw std::runtime_error(ERROR_STR_INDEX_OUT_OF_BOUNDS);
|
||||
}
|
||||
|
||||
int i, j;
|
||||
calculate_array_coordinates_from_index(index, i, j);
|
||||
|
||||
return _pkt_info_arrs[i][j];
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get new empty packets PacketInfo to specified packet type
|
||||
*
|
||||
* This method is to get you a pointer to an empty PacketInfo object of
|
||||
* specified type. This pointer is diguised as normal PacketInfo. You can
|
||||
* work with the PacketInfo object as you want then. You have to cast the
|
||||
* pointer to specified PacketInfo version to use specific IP and L4
|
||||
* protocol functions. You do not have to add it to the PacketContainer
|
||||
* again. The packet is still in the Container you only get the reference.
|
||||
* This packetInfo already has a mbuf.
|
||||
*
|
||||
* @param pkt_type specifies type of PacketInfo which should be created
|
||||
* @return PacketInfo*
|
||||
*/
|
||||
inline PacketInfo* get_empty_packet(PacketType pkt_type) {
|
||||
int i, j;
|
||||
calculate_array_coordinates_from_index(_nb_pkts_total, i, j);
|
||||
|
||||
++_nb_pkts_total;
|
||||
++_nb_mbufs_in_mbuf_arr[i];
|
||||
|
||||
if (unlikely(BURST_SIZE * _nb_pkt_arrays < _nb_pkts_total)) {
|
||||
++_nb_pkt_arrays;
|
||||
}
|
||||
_mbuf_arrs[i][j] = rte_pktmbuf_alloc(_mempool);
|
||||
_pkt_info_arrs[i][j] =
|
||||
PacketInfoCreator::create_pkt_info(_mbuf_arrs[i][j], pkt_type);
|
||||
return _pkt_info_arrs[i][j];
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get new empty packets PacketInfo to a IPv4TCP packet
|
||||
*
|
||||
* This method is to get you a pointer to an empty PacketInfoIpv4Tcp object.
|
||||
* This pointer is diguised as normal PacketInfo. You can work with the
|
||||
* PacketInfo object as you want then. You have to cast the pointer to
|
||||
* PacketInfoIpv4Tcp to use specific IPv4 and TCP functions. You do not have
|
||||
* to add it to the PacketContainer again. The packet is still in the
|
||||
* Container you only get the reference. This packetInfo already has a mbuf.
|
||||
*
|
||||
* @return PacketInfo*
|
||||
*/
|
||||
inline PacketInfo* get_empty_packet() { return get_empty_packet(IPv4TCP); }
|
||||
|
||||
/**
|
||||
* @brief Get the number of polled packets
|
||||
*
|
||||
* @return uint16_t
|
||||
*/
|
||||
inline uint16_t get_number_of_polled_packets() { return _nb_pkts_polled; }
|
||||
|
||||
/**
|
||||
* @brief Get the total number of packets in the container
|
||||
*
|
||||
* @return uint16_t
|
||||
*/
|
||||
inline uint16_t get_total_number_of_packets() { return _nb_pkts_total; }
|
||||
|
||||
/**
|
||||
* @brief Get the mempool
|
||||
*
|
||||
* @return rte_mempool*
|
||||
*/
|
||||
inline rte_mempool* get_mempool() { return _mempool; }
|
||||
|
||||
#ifdef TEST
|
||||
uint16_t* get_nb_mbufs_in_mbuf_arr() { return _nb_mbufs_in_mbuf_arr; }
|
||||
|
||||
int get_nb_pkts_dropped() { return _nb_pkts_dropped; }
|
||||
#endif
|
||||
|
||||
protected:
|
||||
struct rte_mempool* _mempool;
|
||||
|
||||
uint16_t _rx_queue_number;
|
||||
uint16_t _tx_queue_number;
|
||||
|
||||
/**
|
||||
* Port ID of the port the packets are to be polled
|
||||
* from
|
||||
*/
|
||||
uint16_t _entrance_port;
|
||||
/**
|
||||
* Port ID of the port the packets are to be sent
|
||||
* to
|
||||
*/
|
||||
uint16_t _exit_port;
|
||||
|
||||
/**
|
||||
* Number of packets that where polled. Newly
|
||||
* created or added packets are not counted.
|
||||
*/
|
||||
uint16_t _nb_pkts_polled;
|
||||
/**
|
||||
* Total number of mbufs their references are
|
||||
* stored in _mbuf_arrs. nullptrs in between valid mbuf pointers are
|
||||
* counted, too.
|
||||
*/
|
||||
uint16_t _nb_pkts_total;
|
||||
|
||||
/**
|
||||
* Number of Arrays that are stored in _mbuf_arrs
|
||||
*/
|
||||
int _nb_pkt_arrays;
|
||||
|
||||
/**
|
||||
* Total number of Packets dropped; is increased when a packet is removed
|
||||
* from the container by take_packet or drop_packet
|
||||
* \todo rename to _nb_pkts_removed
|
||||
*/
|
||||
int _nb_pkts_dropped;
|
||||
|
||||
/**
|
||||
* @brief Array of arrays of [rte_mbuf* |
|
||||
* PacketInfo*]
|
||||
*
|
||||
* A 2d-array is used instead of just a 1d-array to
|
||||
* be able to store multiple arrays with the fixed
|
||||
* size of BURST_SIZE. This is necessary if new
|
||||
* packets are created but the first array is full.
|
||||
* In this case a new array would be used to store
|
||||
* newly created packets. Otherwise only one
|
||||
* 1d-Array is used, the 2d-array-array would have
|
||||
* just one element then.
|
||||
*
|
||||
* Each PacketInfo object is assignet to one and
|
||||
* only one mbuf. PacketInfo at index "i" holds
|
||||
* information to mbuf at index "i".
|
||||
*/
|
||||
/**@{*/
|
||||
struct rte_mbuf* _mbuf_arrs[NUM_MBUF_ARRS][BURST_SIZE];
|
||||
PacketInfo* _pkt_info_arrs[NUM_MBUF_ARRS][BURST_SIZE];
|
||||
/**@}*/
|
||||
|
||||
/**
|
||||
* Number of mbufs in each sub-array of _mbuf_arrs. nullptrs in between
|
||||
* valid mbuf pointers are counted, too.
|
||||
*/
|
||||
uint16_t _nb_mbufs_in_mbuf_arr[NUM_MBUF_ARRS];
|
||||
|
||||
#ifdef TEST
|
||||
public:
|
||||
#endif
|
||||
/**
|
||||
* @brief Reorder the mbuf arrays; meaning remove nullptrs. So no nullptr
|
||||
* will be given to the send_packets_to_port method of the
|
||||
* NetworkPacketHandler.
|
||||
*/
|
||||
inline void reorder_mbuf_arrays() {
|
||||
if (likely(_nb_pkts_total > 0)) {
|
||||
for (int i = 0; i < _nb_pkt_arrays; ++i) {
|
||||
|
||||
// go through mbufs, reorder
|
||||
int len = _nb_mbufs_in_mbuf_arr[i];
|
||||
int nb_elements_to_skip = 0;
|
||||
|
||||
for (int j = 0; j < len; ++j) {
|
||||
if (_mbuf_arrs[i][j] == nullptr) {
|
||||
++nb_elements_to_skip;
|
||||
} else if (nb_elements_to_skip > 0) {
|
||||
_mbuf_arrs[i][j - nb_elements_to_skip] =
|
||||
_mbuf_arrs[i][j];
|
||||
_mbuf_arrs[i][j] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
_nb_mbufs_in_mbuf_arr[i] -= nb_elements_to_skip;
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef TEST
|
||||
protected:
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Calculate the "i" and "j" coordinates for
|
||||
* a 2d array from a 1d integer "index".
|
||||
*
|
||||
* @param[in] index
|
||||
* @param[out] i
|
||||
* @param[out] j
|
||||
*/
|
||||
inline void calculate_array_coordinates_from_index(int index, int& i,
|
||||
int& j) {
|
||||
i = (index - (index % BURST_SIZE)) / BURST_SIZE;
|
||||
j = index % BURST_SIZE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Does the what
|
||||
* calculate_array_coordinates_from_index does but
|
||||
* in the other direction.
|
||||
*
|
||||
* Beware: The order of the arguments is important!
|
||||
*
|
||||
* @param[in] i first dimesnion index
|
||||
* @param[in] j second dimension index
|
||||
* @param[out] index
|
||||
*/
|
||||
inline void calculate_index_from_array_coordinates(int i, int j,
|
||||
int& index) {
|
||||
index = i * BURST_SIZE + j;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the _state of the container to EMPTY
|
||||
* and assign variables to 0.
|
||||
*/
|
||||
inline void empty_container() {
|
||||
int nb_pkts_remaining = _nb_pkts_total;
|
||||
|
||||
for (int i = 0; i < _nb_pkt_arrays; ++i) {
|
||||
int len = _nb_mbufs_in_mbuf_arr[i];
|
||||
|
||||
for (int j = 0; j < len; ++j) {
|
||||
if (_pkt_info_arrs[i][j] != nullptr) {
|
||||
PacketInfoCreator::destroy_pkt_info(_pkt_info_arrs[i][j]);
|
||||
_pkt_info_arrs[i][j] = nullptr;
|
||||
}
|
||||
|
||||
_mbuf_arrs[i][j] = nullptr;
|
||||
}
|
||||
|
||||
_nb_mbufs_in_mbuf_arr[i] = 0;
|
||||
}
|
||||
|
||||
_nb_pkts_polled = 0;
|
||||
_nb_pkts_total = 0;
|
||||
_nb_pkts_dropped = 0;
|
||||
_nb_pkt_arrays = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief creates a PacketInfo for every packet
|
||||
* in PacketContainer and saves them with
|
||||
* corresponding index in PacketInfo Array
|
||||
*
|
||||
*/
|
||||
inline void extract_header_info() {
|
||||
for (int i = 0; i < _nb_pkts_polled; ++i) {
|
||||
_pkt_info_arrs[0][i] =
|
||||
fill_info(_mbuf_arrs[0][i], _pkt_info_arrs[0][i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief creates PacketInfo for given mbuf
|
||||
*
|
||||
* @param[in] mbuf dpdk abstraction of a packet
|
||||
* for which a PacketInfo should be created
|
||||
* @param[out] pkt_inf newly created PacketInfo
|
||||
*/
|
||||
inline PacketInfo* fill_info(rte_mbuf* mbuf, PacketInfo* pkt_inf) {
|
||||
pkt_inf = PacketInfoCreator::create_pkt_info(mbuf);
|
||||
return pkt_inf;
|
||||
}
|
||||
};
|
||||
168
include/PacketDissection/PacketContainerLean.hpp
Normal file
168
include/PacketDissection/PacketContainerLean.hpp
Normal file
@@ -0,0 +1,168 @@
|
||||
#pragma once
|
||||
|
||||
#include "PacketDissection/PacketContainer.hpp"
|
||||
|
||||
/**
|
||||
* @brief This class holds the same functions like the PacketContainer except it
|
||||
* only holds mbufs and no PacketInfo
|
||||
*
|
||||
* only send/reorder etc polled packets. Manually created packets are never
|
||||
* dropped.
|
||||
*/
|
||||
class PacketContainerLean : protected PacketContainer {
|
||||
public:
|
||||
inline PacketContainerLean(struct rte_mempool* mbuf_pool,
|
||||
uint16_t entrance_port, uint16_t exit_port,
|
||||
uint16_t rx_queue_number,
|
||||
uint16_t tx_queue_number)
|
||||
: PacketContainer(mbuf_pool, entrance_port, exit_port, rx_queue_number,
|
||||
tx_queue_number),
|
||||
_nb_polled_pkts_dropped(0) {}
|
||||
|
||||
inline ~PacketContainerLean() { empty_container_lean(); }
|
||||
|
||||
inline void poll_mbufs(uint16_t& nb_mbufs_polled) {
|
||||
empty_container_lean();
|
||||
|
||||
_nb_pkts_polled = rte_eth_rx_burst(_entrance_port, _rx_queue_number,
|
||||
_mbuf_arrs[0], BURST_SIZE);
|
||||
|
||||
_nb_pkts_total = _nb_pkts_polled;
|
||||
|
||||
if (likely(_nb_pkts_polled > 0)) {
|
||||
_nb_pkt_arrays = 1;
|
||||
_nb_mbufs_in_mbuf_arr[0] = _nb_pkts_polled;
|
||||
}
|
||||
|
||||
// return
|
||||
nb_mbufs_polled = _nb_pkts_polled;
|
||||
}
|
||||
|
||||
inline uint send_mbufs() {
|
||||
uint sum_mbufs_send = 0;
|
||||
if (likely(_nb_pkts_total > 0)) {
|
||||
if (unlikely(_nb_polled_pkts_dropped != 0)) {
|
||||
reorder_mbuf_arrays();
|
||||
}
|
||||
|
||||
for (int i = 0; i < _nb_pkt_arrays; ++i) {
|
||||
uint16_t nb_pkts_to_send = _nb_mbufs_in_mbuf_arr[i];
|
||||
|
||||
// send mbufs
|
||||
uint16_t nb_pkts_sent =
|
||||
rte_eth_tx_burst(_exit_port, _tx_queue_number,
|
||||
_mbuf_arrs[i], nb_pkts_to_send);
|
||||
|
||||
#ifdef LOG_PKTS_SENT
|
||||
LOG_INFO << "Number of packets sent: " << nb_pkts_sent
|
||||
<< LOG_END;
|
||||
#endif
|
||||
|
||||
sum_mbufs_send += nb_pkts_sent;
|
||||
// Free any unsent packets.
|
||||
if (unlikely(nb_pkts_sent < nb_pkts_to_send)) {
|
||||
for (int j = nb_pkts_sent; j < nb_pkts_to_send; ++j) {
|
||||
rte_pktmbuf_free(_mbuf_arrs[i][j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
empty_container_lean();
|
||||
return sum_mbufs_send;
|
||||
}
|
||||
|
||||
inline void drop_polled_mbuf(int index) {
|
||||
if (index >= _nb_pkts_polled) {
|
||||
throw std::runtime_error(
|
||||
ERROR_STR_INDEX_OUT_OF_BOUNDS
|
||||
" No... actually it is _nb_pkts_polled that is exceeded");
|
||||
}
|
||||
|
||||
int i = -1;
|
||||
int j = -1;
|
||||
calculate_array_coordinates_from_index(index, i, j);
|
||||
|
||||
if (unlikely(_mbuf_arrs[i][j] != nullptr)) {
|
||||
rte_pktmbuf_free(_mbuf_arrs[i][j]);
|
||||
}
|
||||
|
||||
_pkt_info_arrs[i][j] = nullptr;
|
||||
_mbuf_arrs[i][j] = nullptr;
|
||||
|
||||
++_nb_polled_pkts_dropped;
|
||||
}
|
||||
|
||||
inline rte_mbuf* get_empty_mbuf() {
|
||||
int i, j;
|
||||
calculate_array_coordinates_from_index(_nb_pkts_total, i, j);
|
||||
|
||||
++_nb_pkts_total;
|
||||
++_nb_mbufs_in_mbuf_arr[i];
|
||||
|
||||
if (unlikely(BURST_SIZE * _nb_pkt_arrays < _nb_pkts_total)) {
|
||||
++_nb_pkt_arrays;
|
||||
}
|
||||
_mbuf_arrs[i][j] = rte_pktmbuf_alloc(_mempool);
|
||||
|
||||
return _mbuf_arrs[i][j];
|
||||
}
|
||||
|
||||
inline int add_mbuf(rte_mbuf* mbuf) {
|
||||
int i = -1;
|
||||
int j = -1;
|
||||
calculate_array_coordinates_from_index(_nb_pkts_total, i, j);
|
||||
_mbuf_arrs[i][j] = mbuf;
|
||||
|
||||
++_nb_pkts_total;
|
||||
++_nb_mbufs_in_mbuf_arr[i];
|
||||
|
||||
if (unlikely(BURST_SIZE * _nb_pkt_arrays < _nb_pkts_total)) {
|
||||
++_nb_pkt_arrays;
|
||||
}
|
||||
|
||||
return _nb_pkts_total - 1;
|
||||
}
|
||||
|
||||
inline uint16_t get_number_of_polled_mbufs() { return _nb_pkts_polled; }
|
||||
|
||||
inline rte_mbuf* get_mbuf_at_index(int index) {
|
||||
if (unlikely(index >= _nb_pkts_total)) {
|
||||
throw std::runtime_error(ERROR_STR_INDEX_OUT_OF_BOUNDS);
|
||||
}
|
||||
|
||||
int i = -1;
|
||||
int j = -1;
|
||||
calculate_array_coordinates_from_index(index, i, j);
|
||||
|
||||
return _mbuf_arrs[i][j];
|
||||
}
|
||||
|
||||
inline rte_mempool* get_mempool_lean() { return get_mempool(); }
|
||||
|
||||
private:
|
||||
int _nb_polled_pkts_dropped;
|
||||
|
||||
inline void empty_container_lean() {
|
||||
|
||||
empty_mbuf_arr();
|
||||
|
||||
_nb_pkts_polled = 0;
|
||||
_nb_pkts_total = 0;
|
||||
_nb_pkts_dropped = 0;
|
||||
_nb_polled_pkts_dropped = 0;
|
||||
_nb_pkt_arrays = 0;
|
||||
}
|
||||
|
||||
inline void empty_mbuf_arr() {
|
||||
for (int i = 0; i < _nb_pkt_arrays; ++i) {
|
||||
int len = _nb_mbufs_in_mbuf_arr[i];
|
||||
|
||||
for (int j = 0; j < len; ++j) {
|
||||
_mbuf_arrs[i][j] = nullptr;
|
||||
}
|
||||
|
||||
_nb_mbufs_in_mbuf_arr[i] = 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
93
include/PacketDissection/PacketInfo.hpp
Normal file
93
include/PacketDissection/PacketInfo.hpp
Normal file
@@ -0,0 +1,93 @@
|
||||
/**
|
||||
* @file PacketInfo.hpp
|
||||
* @author Tobias
|
||||
* @brief class to provide general packet information
|
||||
* @date 2021-06-08
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <rte_ether.h>
|
||||
#include <rte_mbuf.h>
|
||||
|
||||
enum PacketType {
|
||||
NONE,
|
||||
IPv4ICMP,
|
||||
IPv4TCP,
|
||||
IPv4UDP,
|
||||
IPv6ICMP,
|
||||
IPv6TCP,
|
||||
IPv6UDP,
|
||||
IPv4,
|
||||
IPv6,
|
||||
ARP
|
||||
};
|
||||
|
||||
class PacketInfo {
|
||||
public:
|
||||
inline PacketInfo() : _type(NONE), _mbuf(nullptr), _eth_hdr(nullptr) {}
|
||||
|
||||
inline PacketInfo(rte_mbuf* const mbuf, rte_ether_hdr* const eth_hdr)
|
||||
: _type(NONE), _mbuf(mbuf), _eth_hdr(eth_hdr) {}
|
||||
|
||||
inline ~PacketInfo() {
|
||||
//_mbuf = nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get pointer to mbuf
|
||||
*
|
||||
* @return rte_mbuf*
|
||||
*/
|
||||
inline rte_mbuf* const get_mbuf() { return _mbuf; }
|
||||
|
||||
/**
|
||||
* @brief Get PacketInfos specialised type
|
||||
*
|
||||
* @return PacketType
|
||||
*/
|
||||
inline PacketType const get_type() { return _type; }
|
||||
|
||||
/**
|
||||
* @brief Get the source MAC-address
|
||||
*
|
||||
* @return rte_ether_addr
|
||||
*/
|
||||
inline rte_ether_addr get_src_mac() { return _eth_hdr->s_addr; }
|
||||
|
||||
/**
|
||||
* @brief Get the destination MAC-address
|
||||
*
|
||||
* @return rte_ether_addr
|
||||
*/
|
||||
inline rte_ether_addr get_dst_mac() { return _eth_hdr->d_addr; }
|
||||
|
||||
protected:
|
||||
inline PacketInfo(PacketType const type, rte_mbuf* const mbuf,
|
||||
rte_ether_hdr* const eth_hdr)
|
||||
: _type(type), _mbuf(mbuf), _eth_hdr(eth_hdr) {}
|
||||
|
||||
inline PacketInfo(PacketType const type, rte_mbuf* const mbuf)
|
||||
: _type(type), _mbuf(mbuf), _eth_hdr(nullptr) {}
|
||||
|
||||
PacketType const _type;
|
||||
rte_ether_hdr* const _eth_hdr;
|
||||
|
||||
inline rte_ether_hdr* const get_eth_hdr() { return _eth_hdr; }
|
||||
|
||||
/**
|
||||
* @brief fill out standart ethernet header
|
||||
*
|
||||
* @param dst_mac MAC-address of destination
|
||||
* @param src_mac MAC-address of claimed source
|
||||
*/
|
||||
inline void fill_eth_hdr(const rte_ether_addr& dst_mac,
|
||||
const rte_ether_addr& src_mac) {
|
||||
_eth_hdr->d_addr = dst_mac;
|
||||
_eth_hdr->s_addr = src_mac;
|
||||
}
|
||||
|
||||
private:
|
||||
rte_mbuf* const _mbuf;
|
||||
};
|
||||
290
include/PacketDissection/PacketInfoCreator.hpp
Normal file
290
include/PacketDissection/PacketInfoCreator.hpp
Normal file
@@ -0,0 +1,290 @@
|
||||
/**
|
||||
* @file PacketInfoCreator.hpp
|
||||
* @author Tobias
|
||||
* @brief
|
||||
* @date 2021-06-16
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <rte_ether.h>
|
||||
|
||||
#include <boost/log/trivial.hpp>
|
||||
|
||||
#include "Definitions.hpp"
|
||||
#include "PacketDissection/PacketInfo.hpp"
|
||||
#include "PacketDissection/PacketInfoIpv4.hpp"
|
||||
#include "PacketDissection/PacketInfoIpv4Icmp.hpp"
|
||||
#include "PacketDissection/PacketInfoIpv4Tcp.hpp"
|
||||
#include "PacketDissection/PacketInfoIpv4Udp.hpp"
|
||||
|
||||
#define RTE_ETHER_ADDR_LEN 6
|
||||
|
||||
#define ETHER_TYPE_IPv4 0x0800
|
||||
|
||||
class PacketInfoCreator {
|
||||
public:
|
||||
/**
|
||||
* @brief Create a PacketInfo object for given mbuf
|
||||
*
|
||||
* @param mbuf dpdk abstraction for one packet
|
||||
* @return PacketInfo*
|
||||
*/
|
||||
inline static PacketInfo* create_pkt_info(rte_mbuf* mbuf) {
|
||||
struct rte_ether_hdr* eth_hdr;
|
||||
eth_hdr = rte_pktmbuf_mtod(mbuf, struct rte_ether_hdr*);
|
||||
uint16_t offset = (uint16_t)sizeof(struct rte_ether_hdr);
|
||||
|
||||
/// from here on we know the l3 type
|
||||
if (rte_be_to_cpu_16(eth_hdr->ether_type) == ETHER_TYPE_IPv4) {
|
||||
struct rte_ipv4_hdr* ip4_hdr;
|
||||
ip4_hdr =
|
||||
rte_pktmbuf_mtod_offset(mbuf, struct rte_ipv4_hdr*, offset);
|
||||
uint8_t protocol_id = ip4_hdr->next_proto_id;
|
||||
|
||||
if (protocol_id == 6) { // TCP
|
||||
// calculate point where TCP-header begins
|
||||
offset = offset + (ip4_hdr->version_ihl - 64) * 4;
|
||||
// map TCP-header on memory
|
||||
struct rte_tcp_hdr* tcp_hdr;
|
||||
tcp_hdr =
|
||||
rte_pktmbuf_mtod_offset(mbuf, struct rte_tcp_hdr*, offset);
|
||||
// create PacketInfo
|
||||
PacketInfoIpv4Tcp* pkt_inf =
|
||||
new PacketInfoIpv4Tcp(mbuf, eth_hdr, ip4_hdr, tcp_hdr);
|
||||
|
||||
return pkt_inf;
|
||||
} else if (protocol_id == 17) { // UDP
|
||||
offset = offset + (ip4_hdr->version_ihl - 64) * 4;
|
||||
struct rte_udp_hdr* udp_hdr;
|
||||
udp_hdr =
|
||||
rte_pktmbuf_mtod_offset(mbuf, struct rte_udp_hdr*, offset);
|
||||
|
||||
PacketInfoIpv4Udp* pkt_inf =
|
||||
new PacketInfoIpv4Udp(mbuf, eth_hdr, ip4_hdr, udp_hdr);
|
||||
|
||||
return pkt_inf;
|
||||
} else if (protocol_id == 1) { // ICMP
|
||||
offset = offset + (ip4_hdr->version_ihl - 64) * 4;
|
||||
struct rte_icmp_hdr* icmp_hdr;
|
||||
icmp_hdr =
|
||||
rte_pktmbuf_mtod_offset(mbuf, struct rte_icmp_hdr*, offset);
|
||||
PacketInfoIpv4Icmp* pkt_inf =
|
||||
new PacketInfoIpv4Icmp(mbuf, eth_hdr, ip4_hdr, icmp_hdr);
|
||||
|
||||
return pkt_inf;
|
||||
} else {
|
||||
printf("packet is neither TCP UDP nor ICMP");
|
||||
return new PacketInfo(mbuf, eth_hdr);
|
||||
}
|
||||
} else if (rte_be_to_cpu_16(eth_hdr->ether_type) == 0x86DD) {
|
||||
/// \TODO: implement IPv6
|
||||
return new PacketInfo(mbuf, eth_hdr);
|
||||
} else if (rte_be_to_cpu_16(eth_hdr->ether_type) == 0x0806) {
|
||||
/// \TODO: implement ARP
|
||||
return new PacketInfo(mbuf, eth_hdr);
|
||||
} else {
|
||||
return new PacketInfo(mbuf, eth_hdr);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Create a PacketInfo object for given packet type
|
||||
*
|
||||
* @param mbuf dpdk abstraction for one packet
|
||||
* @param type specifies Type which PacketInfo should have
|
||||
* @return PacketInfo*
|
||||
*/
|
||||
inline static PacketInfo* create_pkt_info(rte_mbuf* mbuf, PacketType type) {
|
||||
|
||||
int off_set = sizeof(struct rte_ether_hdr);
|
||||
struct rte_ether_hdr* eth_hdr;
|
||||
rte_pktmbuf_append(mbuf, sizeof(struct rte_ether_hdr));
|
||||
eth_hdr = rte_pktmbuf_mtod(mbuf, struct rte_ether_hdr*);
|
||||
|
||||
switch (type) {
|
||||
case IPv4ICMP: {
|
||||
eth_hdr->ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv4);
|
||||
|
||||
struct rte_ipv4_hdr* ip4_hdr;
|
||||
rte_pktmbuf_append(mbuf, sizeof(rte_ipv4_hdr));
|
||||
ip4_hdr =
|
||||
rte_pktmbuf_mtod_offset(mbuf, struct rte_ipv4_hdr*, off_set);
|
||||
off_set = off_set + sizeof(rte_ipv4_hdr);
|
||||
|
||||
rte_pktmbuf_append(mbuf, sizeof(rte_icmp_hdr));
|
||||
rte_icmp_hdr* icmp_hdr;
|
||||
icmp_hdr =
|
||||
rte_pktmbuf_mtod_offset(mbuf, struct rte_icmp_hdr*, off_set);
|
||||
|
||||
return new PacketInfoIpv4Icmp(mbuf, eth_hdr, ip4_hdr, icmp_hdr);
|
||||
} break;
|
||||
|
||||
case IPv4TCP: {
|
||||
eth_hdr->ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv4); // 0x0008
|
||||
|
||||
struct rte_ipv4_hdr* ip4_hdr;
|
||||
rte_pktmbuf_append(mbuf,
|
||||
sizeof(rte_ipv4_hdr) + sizeof(rte_tcp_hdr));
|
||||
ip4_hdr =
|
||||
rte_pktmbuf_mtod_offset(mbuf, struct rte_ipv4_hdr*, off_set);
|
||||
off_set = off_set + sizeof(rte_ipv4_hdr);
|
||||
|
||||
rte_tcp_hdr* tcp_hdr;
|
||||
tcp_hdr =
|
||||
rte_pktmbuf_mtod_offset(mbuf, struct rte_tcp_hdr*, off_set);
|
||||
|
||||
return new PacketInfoIpv4Tcp(mbuf, eth_hdr, ip4_hdr, tcp_hdr);
|
||||
} break;
|
||||
|
||||
case IPv4UDP: {
|
||||
eth_hdr->ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv4);
|
||||
|
||||
struct rte_ipv4_hdr* ip4_hdr;
|
||||
rte_pktmbuf_append(mbuf, sizeof(rte_ipv4_hdr));
|
||||
ip4_hdr =
|
||||
rte_pktmbuf_mtod_offset(mbuf, struct rte_ipv4_hdr*, off_set);
|
||||
off_set = off_set + sizeof(rte_ipv4_hdr);
|
||||
|
||||
rte_pktmbuf_append(mbuf, sizeof(rte_udp_hdr));
|
||||
rte_udp_hdr* udp_hdr;
|
||||
udp_hdr =
|
||||
rte_pktmbuf_mtod_offset(mbuf, struct rte_udp_hdr*, off_set);
|
||||
|
||||
return new PacketInfoIpv4Udp(mbuf, eth_hdr, ip4_hdr, udp_hdr);
|
||||
} break;
|
||||
|
||||
case IPv6ICMP:
|
||||
return new PacketInfo(mbuf, eth_hdr);
|
||||
break;
|
||||
|
||||
case IPv6TCP:
|
||||
return new PacketInfo(mbuf, eth_hdr);
|
||||
break;
|
||||
|
||||
case IPv6UDP:
|
||||
return new PacketInfo(mbuf, eth_hdr);
|
||||
break;
|
||||
|
||||
default:
|
||||
return new PacketInfo(mbuf, eth_hdr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Create a minimalized PacketInfo
|
||||
* this Packet is expected to already have a filled ether header
|
||||
* and is only for IPv4
|
||||
* @param mbuf dpdk abstraction for one packet
|
||||
* @param type specifies Type which PacketInfo should have
|
||||
* @return PacketInfo*
|
||||
*/
|
||||
inline static PacketInfo* create_mini_pkt_info(rte_mbuf* mbuf,
|
||||
PacketType type) {
|
||||
int off_set = sizeof(struct rte_ether_hdr);
|
||||
|
||||
switch (type) {
|
||||
|
||||
case IPv4TCP: {
|
||||
|
||||
struct rte_ipv4_hdr* ip4_hdr;
|
||||
ip4_hdr =
|
||||
rte_pktmbuf_mtod_offset(mbuf, struct rte_ipv4_hdr*, off_set);
|
||||
off_set = off_set + sizeof(rte_ipv4_hdr);
|
||||
|
||||
rte_tcp_hdr* tcp_hdr;
|
||||
tcp_hdr =
|
||||
rte_pktmbuf_mtod_offset(mbuf, struct rte_tcp_hdr*, off_set);
|
||||
|
||||
return new PacketInfoIpv4Tcp(mbuf, ip4_hdr, tcp_hdr);
|
||||
} break;
|
||||
|
||||
case IPv4UDP: {
|
||||
|
||||
struct rte_ipv4_hdr* ip4_hdr;
|
||||
ip4_hdr =
|
||||
rte_pktmbuf_mtod_offset(mbuf, struct rte_ipv4_hdr*, off_set);
|
||||
off_set = off_set + sizeof(rte_ipv4_hdr);
|
||||
|
||||
rte_udp_hdr* udp_hdr;
|
||||
udp_hdr =
|
||||
rte_pktmbuf_mtod_offset(mbuf, struct rte_udp_hdr*, off_set);
|
||||
|
||||
return new PacketInfoIpv4Udp(mbuf, ip4_hdr, udp_hdr);
|
||||
} break;
|
||||
|
||||
default:
|
||||
return nullptr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief returns a packets destiantion ip
|
||||
* This method takes an mbuf and extract the IPv4 IP-adress.
|
||||
* In case the packet inside the mbuf is no IPv4 packet, 0 will be returned
|
||||
* @param mbuf structure to hand packets over
|
||||
* @return uint32_t packets IP-adress; it's 0, in case of no IPv4
|
||||
*/
|
||||
inline static uint32_t get_dst_ip_from_mbuf(rte_mbuf* mbuf) {
|
||||
|
||||
rte_ether_hdr* eth_hdr = rte_pktmbuf_mtod(mbuf, struct rte_ether_hdr*);
|
||||
|
||||
if (eth_hdr->ether_type == rte_cpu_to_be_16(ETHER_TYPE_IPv4)) {
|
||||
|
||||
int off_set = sizeof(struct rte_ether_hdr);
|
||||
rte_ipv4_hdr* ip_hdr =
|
||||
rte_pktmbuf_mtod_offset(mbuf, struct rte_ipv4_hdr*, off_set);
|
||||
return rte_be_to_cpu_32(ip_hdr->dst_addr);
|
||||
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
inline static void destroy_pkt_info(PacketInfo* info) {
|
||||
|
||||
PacketType type = info->get_type();
|
||||
switch (type) {
|
||||
|
||||
case IPv4TCP: {
|
||||
delete static_cast<PacketInfoIpv4Tcp*>(info);
|
||||
} break;
|
||||
|
||||
case IPv4UDP: {
|
||||
delete static_cast<PacketInfoIpv4Udp*>(info);
|
||||
} break;
|
||||
|
||||
case NONE: {
|
||||
delete info;
|
||||
} break;
|
||||
case IPv4ICMP: {
|
||||
delete static_cast<PacketInfoIpv4Icmp*>(info);
|
||||
} break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
inline static bool is_ipv4_tcp(rte_mbuf* mbuf) {
|
||||
struct rte_ether_hdr* eth_hdr;
|
||||
eth_hdr = rte_pktmbuf_mtod(mbuf, struct rte_ether_hdr*);
|
||||
|
||||
if (rte_be_to_cpu_16(eth_hdr->ether_type) == ETHER_TYPE_IPv4) {
|
||||
uint16_t offset = (uint16_t)sizeof(struct rte_ether_hdr);
|
||||
struct rte_ipv4_hdr* ip4_hdr;
|
||||
ip4_hdr =
|
||||
rte_pktmbuf_mtod_offset(mbuf, struct rte_ipv4_hdr*, offset);
|
||||
uint8_t protocol_id = ip4_hdr->next_proto_id;
|
||||
|
||||
if (protocol_id == 6) { // TCP
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
135
include/PacketDissection/PacketInfoIpv4.hpp
Normal file
135
include/PacketDissection/PacketInfoIpv4.hpp
Normal file
@@ -0,0 +1,135 @@
|
||||
/**
|
||||
* @file PacketInfoIpv4.hpp
|
||||
* @author Tobias
|
||||
* @brief class which provides IPv4 header information
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <boost/log/trivial.hpp>
|
||||
|
||||
#include <rte_byteorder.h>
|
||||
#include <rte_ip.h>
|
||||
#include <rte_mbuf.h>
|
||||
|
||||
#include "Definitions.hpp"
|
||||
#include "PacketDissection/PacketInfo.hpp"
|
||||
|
||||
#define IP_HDR_LEN 20
|
||||
#define VERSION_AND_IP_HDR_LEN 0b01000101
|
||||
|
||||
class PacketInfoIpv4 : public PacketInfo {
|
||||
public:
|
||||
PacketInfoIpv4();
|
||||
inline PacketInfoIpv4(rte_mbuf* const mbuf, rte_ether_hdr* const eth_hdr,
|
||||
rte_ipv4_hdr* const ip_hdr)
|
||||
: PacketInfo(IPv4, mbuf, eth_hdr), _ip4_hdr(ip_hdr) {}
|
||||
inline ~PacketInfoIpv4() {
|
||||
// PacketInfo::~PacketInfo();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get packets destination IP address
|
||||
*
|
||||
* @return uint32_t
|
||||
*/
|
||||
inline uint32_t get_dst_ip() {
|
||||
return rte_be_to_cpu_32(_ip4_hdr->dst_addr);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get packets source IP address
|
||||
*
|
||||
* @return uint32_t
|
||||
*/
|
||||
inline uint32_t get_src_ip() {
|
||||
return rte_be_to_cpu_32(_ip4_hdr->src_addr);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set packets source IP address
|
||||
*
|
||||
* @param ip
|
||||
*/
|
||||
inline void set_src_ip(uint32_t ip) {
|
||||
_ip4_hdr->src_addr = rte_cpu_to_be_32(ip);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get packets size in byte
|
||||
*
|
||||
* @return uint16_t
|
||||
*/
|
||||
inline uint16_t get_packet_size() {
|
||||
return rte_be_to_cpu_16(_ip4_hdr->total_length);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the ip header struct
|
||||
*
|
||||
* @return rte_ipv4_hdr*
|
||||
*/
|
||||
inline rte_ipv4_hdr* const get_ip_hdr() { return _ip4_hdr; }
|
||||
|
||||
void set_ip_cksm(uint16_t cksm);
|
||||
|
||||
protected:
|
||||
inline PacketInfoIpv4(PacketType const type, rte_mbuf* const mbuf,
|
||||
rte_ether_hdr* const eth_hdr,
|
||||
rte_ipv4_hdr* const ip_hdr)
|
||||
: PacketInfo(type, mbuf, eth_hdr), _ip4_hdr(ip_hdr) {}
|
||||
|
||||
inline PacketInfoIpv4(PacketType const type, rte_mbuf* const mbuf,
|
||||
rte_ipv4_hdr* const ip_hdr)
|
||||
: PacketInfo(type, mbuf), _ip4_hdr(ip_hdr) {}
|
||||
|
||||
/**
|
||||
* @brief fills this packets IPv4 header with neseceties
|
||||
*
|
||||
* @param src_ip IP from which packet was originally send from
|
||||
* @param dst_ip IP packet is send to
|
||||
* @param proto protocol whose header follows after Ip-header
|
||||
* @param payload_len packets number of bytes without IP-header
|
||||
*/
|
||||
inline void fill_ip_hdr(uint32_t src_ip, uint32_t dst_ip, uint8_t proto,
|
||||
uint16_t payload_len) {
|
||||
|
||||
_ip4_hdr->src_addr = rte_cpu_to_be_32(src_ip);
|
||||
_ip4_hdr->dst_addr = rte_cpu_to_be_32(dst_ip);
|
||||
|
||||
_ip4_hdr->version_ihl = VERSION_AND_IP_HDR_LEN;
|
||||
_ip4_hdr->type_of_service = 0;
|
||||
_ip4_hdr->total_length = rte_be_to_cpu_16(payload_len + IP_HDR_LEN);
|
||||
_ip4_hdr->packet_id = 0;
|
||||
_ip4_hdr->fragment_offset = 0;
|
||||
_ip4_hdr->time_to_live = 128;
|
||||
_ip4_hdr->next_proto_id = proto;
|
||||
_ip4_hdr->hdr_checksum = 0;
|
||||
}
|
||||
|
||||
inline void recalculate_ip_checksum() {
|
||||
_ip4_hdr->hdr_checksum = rte_ipv4_cksum(_ip4_hdr);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get IP pseudo header checksum
|
||||
*
|
||||
* @return uint16_t IP pseudo header checksum
|
||||
*/
|
||||
inline uint16_t get_pseudo_hdr_cksm() {
|
||||
rte_mbuf* mbuf = get_mbuf();
|
||||
mbuf->l2_len = sizeof(struct rte_ether_hdr);
|
||||
mbuf->l3_len = sizeof(struct rte_ipv4_hdr);
|
||||
return rte_ipv4_phdr_cksum(_ip4_hdr, mbuf->ol_flags);
|
||||
}
|
||||
|
||||
inline uint8_t get_ip_hdr_len() {
|
||||
uint8_t len = _ip4_hdr->version_ihl & 0b00001111;
|
||||
len = len * 4;
|
||||
return len;
|
||||
}
|
||||
|
||||
private:
|
||||
rte_ipv4_hdr* const _ip4_hdr;
|
||||
};
|
||||
45
include/PacketDissection/PacketInfoIpv4Icmp.hpp
Normal file
45
include/PacketDissection/PacketInfoIpv4Icmp.hpp
Normal file
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
* @file PacketInfoIpv4Icmp.hpp
|
||||
* @author Tobias
|
||||
* @brief class to provide packets IPv4 and ICMP header information
|
||||
* @date 2021-06-08
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <rte_byteorder.h>
|
||||
#include <rte_icmp.h>
|
||||
|
||||
#include "PacketDissection/PacketInfoIpv4.hpp"
|
||||
|
||||
class PacketInfoIpv4Icmp : public PacketInfoIpv4 {
|
||||
public:
|
||||
inline PacketInfoIpv4Icmp();
|
||||
inline PacketInfoIpv4Icmp(rte_mbuf* mbuf, rte_ether_hdr* eth_hdr,
|
||||
rte_ipv4_hdr* ip_hdr, rte_icmp_hdr* l4_hdr)
|
||||
: PacketInfoIpv4(IPv4ICMP, mbuf, eth_hdr, ip_hdr), _icmp_hdr(l4_hdr) {}
|
||||
inline ~PacketInfoIpv4Icmp() {
|
||||
// PacketInfoIpv4::~PacketInfoIpv4();
|
||||
_icmp_hdr = nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get packets payload size in byte
|
||||
*
|
||||
* @return uint16_t
|
||||
*/
|
||||
inline uint16_t get_payload_size() { return 0; }
|
||||
|
||||
private:
|
||||
rte_icmp_hdr* _icmp_hdr;
|
||||
|
||||
/**
|
||||
* @brief Set the icmp header struct
|
||||
*
|
||||
* @param icmp_hdr
|
||||
*/
|
||||
inline void set_icmp_hdr(rte_icmp_hdr* icmp_hdr) {
|
||||
this->_icmp_hdr = icmp_hdr;
|
||||
}
|
||||
};
|
||||
231
include/PacketDissection/PacketInfoIpv4Tcp.hpp
Normal file
231
include/PacketDissection/PacketInfoIpv4Tcp.hpp
Normal file
@@ -0,0 +1,231 @@
|
||||
/**
|
||||
* @file PacketInfoIpv4Tcp.hpp
|
||||
* @author Tobias
|
||||
* @brief class to provide packets IPv4 and TCP header information
|
||||
* @date 2021-06-08
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <rte_byteorder.h>
|
||||
#include <rte_tcp.h>
|
||||
|
||||
#include "DebugHelper.hpp"
|
||||
#include "Definitions.hpp"
|
||||
#include "PacketDissection/PacketInfoIpv4.hpp"
|
||||
#include "PacketDissection/PacketProtTcp.hpp"
|
||||
|
||||
class PacketInfoIpv4Tcp : public PacketInfoIpv4 {
|
||||
public:
|
||||
inline PacketInfoIpv4Tcp();
|
||||
|
||||
inline PacketInfoIpv4Tcp(rte_mbuf* mbuf)
|
||||
: PacketInfoIpv4(
|
||||
IPv4TCP, mbuf, rte_pktmbuf_mtod(mbuf, struct rte_ether_hdr*),
|
||||
rte_pktmbuf_mtod_offset(mbuf, struct rte_ipv4_hdr*,
|
||||
(uint16_t)sizeof(struct rte_ether_hdr)))
|
||||
, _tcp_hdr(rte_pktmbuf_mtod_offset(
|
||||
mbuf, struct rte_tcp_hdr*,
|
||||
(sizeof(struct rte_ether_hdr) + sizeof(struct rte_ipv4_hdr)))) {}
|
||||
|
||||
inline PacketInfoIpv4Tcp(rte_mbuf* mbuf, rte_ether_hdr* eth_hdr,
|
||||
rte_ipv4_hdr* ip_hdr, rte_tcp_hdr* l4_hdr)
|
||||
: PacketInfoIpv4(IPv4TCP, mbuf, eth_hdr, ip_hdr)
|
||||
, _tcp_hdr(l4_hdr) {}
|
||||
|
||||
inline PacketInfoIpv4Tcp(rte_mbuf* mbuf, rte_ipv4_hdr* ip_hdr,
|
||||
rte_tcp_hdr* l4_hdr)
|
||||
: PacketInfoIpv4(IPv4TCP, mbuf, ip_hdr)
|
||||
, _tcp_hdr(l4_hdr) {}
|
||||
|
||||
inline ~PacketInfoIpv4Tcp() {
|
||||
// PacketInfoIpv4::~PacketInfoIpv4();
|
||||
// _tcp_hdr = nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set packets TCP sequence number
|
||||
*
|
||||
* @param seq_num
|
||||
*/
|
||||
inline void set_seq_num(uint32_t seq_num) {
|
||||
PacketProtTcp::set_seq_num(_tcp_hdr, seq_num);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set packets TCP acknowledgment number
|
||||
*
|
||||
* @param ack_num
|
||||
*/
|
||||
inline void set_ack_num(uint32_t ack_num) {
|
||||
PacketProtTcp::set_ack_num(_tcp_hdr, ack_num);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get packets TCP destination port
|
||||
*
|
||||
* @return uint16_t
|
||||
*/
|
||||
inline uint16_t get_dst_port() {
|
||||
return PacketProtTcp::get_dst_port(_tcp_hdr);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get packets TCP source port
|
||||
*
|
||||
* @return uint16_t
|
||||
*/
|
||||
inline uint16_t get_src_port() {
|
||||
return PacketProtTcp::get_src_port(_tcp_hdr);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get packets TCP flags
|
||||
* MSB is CWR flag, LSB is FIN flag, NS flag not included
|
||||
* @return uint8_t
|
||||
*/
|
||||
inline uint8_t get_flags() {
|
||||
const char desc[] = "mbuf";
|
||||
return PacketProtTcp::get_flags(
|
||||
_tcp_hdr); // these are FIN to CWR flag, but
|
||||
// i am not shure in which order
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get packets payload size in byte
|
||||
*
|
||||
* @return uint16_t
|
||||
*/
|
||||
inline uint16_t get_payload_size() {
|
||||
uint16_t length = get_packet_size();
|
||||
length = length - get_ip_hdr_len();
|
||||
length = length - PacketProtTcp::get_tcp_hdr_len(_tcp_hdr);
|
||||
return length;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get packets TCP window size
|
||||
*
|
||||
* @return uint16_t
|
||||
*/
|
||||
inline uint16_t get_window_size() {
|
||||
return PacketProtTcp::get_window_size(_tcp_hdr);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get packets TCP sequence number
|
||||
*
|
||||
* @return uint32_t
|
||||
*/
|
||||
inline uint32_t get_seq_num() {
|
||||
return PacketProtTcp::get_seq_num(_tcp_hdr);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get packets TCP acknowledgment number
|
||||
*
|
||||
* @return uint32_t
|
||||
*/
|
||||
inline uint32_t get_ack_num() {
|
||||
return PacketProtTcp::get_ack_num(_tcp_hdr);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get packets TCP SYN flag
|
||||
*
|
||||
* @return true if flag is set
|
||||
* @return false if flag is not set
|
||||
*/
|
||||
inline bool get_syn_flag() { return PacketProtTcp::get_syn_flag(_tcp_hdr); }
|
||||
|
||||
/**
|
||||
* @brief Get packets TCP ACK flag
|
||||
*
|
||||
* @return true if flag is set
|
||||
* @return false if flag is not set
|
||||
*/
|
||||
inline bool get_ack_flag() { return PacketProtTcp::get_ack_flag(_tcp_hdr); }
|
||||
|
||||
/**
|
||||
* @brief Get packets TCP RST flag
|
||||
*
|
||||
* @return true if flag is set
|
||||
* @return false if flag is not set
|
||||
*/
|
||||
inline bool get_rst_flag() { return PacketProtTcp::get_rst_flag(_tcp_hdr); }
|
||||
|
||||
/**
|
||||
* @brief Get packets TCP FIN flag
|
||||
*
|
||||
* @return true if flag is set
|
||||
* @return false if flag is not set
|
||||
*/
|
||||
inline bool get_fin_flag() { return PacketProtTcp::get_fin_flag(_tcp_hdr); }
|
||||
|
||||
/**
|
||||
* @brief fills empty mbuf with IP and TCP header
|
||||
* If this PacketInfo has a _mbuf and this _mbuf is empty,
|
||||
* then all IP and TCP header information is filled in.
|
||||
* This function doesn't create a new mbuf.
|
||||
* @param src_mac MAC address packet was send from
|
||||
* @param dst_mac MAC address packet is going to be send to
|
||||
* @param src_ip IP address packet originally originated from
|
||||
* @param dst_ip IP address packet is going to be send to
|
||||
* @param src_port TCP port packet originally was send from
|
||||
* @param dst_port TCP port packet should be recieved on
|
||||
* @param seq_num TCP sequence number
|
||||
* @param ack_num TCP acknowledgment number
|
||||
* @param flags TCP flags wich are going to be set, can't set NS flag
|
||||
* @param tcp_window TCP recive window size
|
||||
*/
|
||||
inline void fill_payloadless_tcp_packet(
|
||||
rte_ether_addr src_mac, rte_ether_addr dst_mac, uint32_t src_ip,
|
||||
uint32_t dst_ip, uint16_t src_port, uint16_t dst_port, uint32_t seq_num,
|
||||
uint32_t ack_num, uint8_t flags, uint16_t tcp_window) {
|
||||
// const char desc[] = "mbuf";
|
||||
|
||||
// let PacketInfo handle ethernet filling
|
||||
fill_eth_hdr(dst_mac, src_mac);
|
||||
|
||||
// let prot objekt handle tcp filling
|
||||
PacketProtTcp::fill_payloadless_tcp_header(_tcp_hdr, get_mbuf(),
|
||||
src_port, dst_port, seq_num,
|
||||
ack_num, flags, tcp_window);
|
||||
|
||||
// let PacketInfoIpv4 handle IPv4 filling
|
||||
fill_ip_hdr(src_ip, dst_ip, 6, 20);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief fills in current checksums
|
||||
* calculates current IPv4 and TCP checksum and changes
|
||||
* them inside the packet
|
||||
*/
|
||||
inline void recalculate_checksums() {
|
||||
rte_ipv4_hdr* ip4_hdr = get_ip_hdr();
|
||||
|
||||
_tcp_hdr->cksum = 0;
|
||||
ip4_hdr->hdr_checksum = 0;
|
||||
_tcp_hdr->cksum = rte_ipv4_udptcp_cksum(ip4_hdr, _tcp_hdr);
|
||||
PacketInfoIpv4::recalculate_ip_checksum();
|
||||
}
|
||||
|
||||
inline void prepare_offloading_checksums() {
|
||||
rte_mbuf* mbuf = get_mbuf();
|
||||
mbuf->ol_flags = PKT_TX_IPV4 | PKT_TX_IP_CKSUM | PKT_TX_TCP_CKSUM;
|
||||
mbuf->l4_len = sizeof(struct rte_tcp_hdr);
|
||||
|
||||
uint16_t cksm = PacketInfoIpv4::get_pseudo_hdr_cksm();
|
||||
PacketProtTcp::fill_tcp_cksm(_tcp_hdr, cksm);
|
||||
}
|
||||
|
||||
inline void set_tcp_cksm(uint16_t cksm) {
|
||||
PacketProtTcp::fill_tcp_cksm(_tcp_hdr, cksm);
|
||||
}
|
||||
|
||||
private:
|
||||
rte_tcp_hdr* _tcp_hdr;
|
||||
};
|
||||
135
include/PacketDissection/PacketInfoIpv4Udp.hpp
Normal file
135
include/PacketDissection/PacketInfoIpv4Udp.hpp
Normal file
@@ -0,0 +1,135 @@
|
||||
/**
|
||||
* @file PacketInfoIpv4Udp.hpp
|
||||
* @author @Tobias
|
||||
* @brief class to provide packets IPv4 and UDP header information
|
||||
* @date 2021-06-08
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <rte_byteorder.h>
|
||||
#include <rte_udp.h>
|
||||
|
||||
#include "PacketDissection/PacketInfoIpv4.hpp"
|
||||
#include "PacketDissection/PacketProtUdp.hpp"
|
||||
|
||||
#define UDP_HDR_LEN 8
|
||||
|
||||
class PacketInfoIpv4Udp : public PacketInfoIpv4 {
|
||||
public:
|
||||
inline PacketInfoIpv4Udp();
|
||||
|
||||
inline PacketInfoIpv4Udp(rte_mbuf* const mbuf, rte_ether_hdr* const eth_hdr,
|
||||
rte_ipv4_hdr* const ip_hdr,
|
||||
rte_udp_hdr* const l4_hdr)
|
||||
: PacketInfoIpv4(IPv4UDP, mbuf, eth_hdr, ip_hdr), _udp_hdr(l4_hdr) {}
|
||||
|
||||
inline PacketInfoIpv4Udp(rte_mbuf* const mbuf, rte_ipv4_hdr* const ip_hdr,
|
||||
rte_udp_hdr* const l4_hdr)
|
||||
: PacketInfoIpv4(IPv4UDP, mbuf, ip_hdr), _udp_hdr(l4_hdr) {}
|
||||
|
||||
// inline PacketInfoIpv4Udp::~PacketInfoIpv4Udp() {
|
||||
// PacketInfoIpv4::~PacketInfoIpv4();
|
||||
// //_udp_hdr = nullptr;
|
||||
//}
|
||||
|
||||
/**
|
||||
* @brief Get packets UDP destination port
|
||||
*
|
||||
* @return uint16_t
|
||||
*/
|
||||
inline uint16_t get_dst_port() {
|
||||
return PacketProtUdp::get_dst_port(_udp_hdr);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get packets UDP source port
|
||||
*
|
||||
* @return uint16_t
|
||||
*/
|
||||
inline uint16_t get_src_port() {
|
||||
return PacketProtUdp::get_src_port(_udp_hdr);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get packets payload size in byte
|
||||
*
|
||||
* @return uint16_t
|
||||
*/
|
||||
inline uint16_t get_payload_size() {
|
||||
uint16_t len = get_packet_size();
|
||||
len = len - get_ip_hdr_len();
|
||||
return len - UDP_HDR_LEN;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief fills empty mbuf with IP and UDP heder
|
||||
* This PacketInfos _mbuf is going to be filled with all
|
||||
* IP and UDP header information, execpt checksums.
|
||||
* This function doesn't create a new mbuf.
|
||||
* @param src_mac MAC address packet was send from
|
||||
* @param dst_mac MAC address packet is going to be send to
|
||||
* @param src_ip IP address packet originally was send from
|
||||
* @param dst_ip IP address packet is going to be send to
|
||||
* @param src_port TCP port packet originally was send from
|
||||
* @param dst_port TCP port packet is going to be send to
|
||||
*/
|
||||
inline void fill_payloadless_udp_packet(rte_ether_addr src_mac,
|
||||
rte_ether_addr dst_mac,
|
||||
uint32_t src_ip, uint32_t dst_ip,
|
||||
uint16_t src_port,
|
||||
uint16_t dst_port) {
|
||||
|
||||
// let PacketInfo handle ethernet filling
|
||||
fill_eth_hdr(dst_mac, src_mac);
|
||||
|
||||
// let prot objekt handle tcp filling
|
||||
PacketProtUdp::fill_payloadless_udp_header(_udp_hdr, src_port,
|
||||
dst_port);
|
||||
|
||||
// let PacketInfoIpv4 handle IPv4 filling
|
||||
fill_ip_hdr(src_ip, dst_ip, 17, 8);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief calculate current checksums and fill them in
|
||||
* Note, udp checksum doesn't have to be set in IPv4.
|
||||
* @param use_udp_cksm if true the UDP checksum is calculated
|
||||
*/
|
||||
inline void recalculate_checksums(bool use_udp_cksm) {
|
||||
|
||||
_udp_hdr->dgram_cksum = 0;
|
||||
|
||||
if (use_udp_cksm == true) {
|
||||
|
||||
rte_ipv4_hdr* ip_hdr = get_ip_hdr();
|
||||
ip_hdr->hdr_checksum = 0;
|
||||
_udp_hdr->dgram_cksum = rte_ipv4_udptcp_cksum(ip_hdr, _udp_hdr);
|
||||
}
|
||||
PacketInfoIpv4::recalculate_ip_checksum();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief prepare mbuf for checksum calculation by hardware
|
||||
* Note, udp checksum doesn't have to be set in IPv4.
|
||||
* @param use_udp_cksm if true the UDP checksum will be calculated
|
||||
*/
|
||||
inline void prepare_offloading_checksums(bool use_udp_cksm) {
|
||||
|
||||
rte_mbuf* mbuf = get_mbuf();
|
||||
mbuf->ol_flags = PKT_TX_IPV4 | PKT_TX_IP_CKSUM;
|
||||
mbuf->l4_len = sizeof(struct rte_udp_hdr);
|
||||
|
||||
if (use_udp_cksm == true) {
|
||||
mbuf->ol_flags |= PKT_TX_UDP_CKSUM;
|
||||
_udp_hdr->dgram_cksum = PacketInfoIpv4::get_pseudo_hdr_cksm();
|
||||
} else {
|
||||
mbuf->l2_len = sizeof(struct rte_ether_hdr);
|
||||
mbuf->l3_len = sizeof(struct rte_ipv4_hdr);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
rte_udp_hdr* const _udp_hdr;
|
||||
};
|
||||
58
include/PacketDissection/PacketInfoIpv6Icmp.hpp
Normal file
58
include/PacketDissection/PacketInfoIpv6Icmp.hpp
Normal file
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
* @file PacketInfoIpv6Icmp.hpp
|
||||
* @author Tobias
|
||||
* @brief class to provide packets IPv6 and ICMP header information
|
||||
* @date 2021-06-09
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <rte_byteorder.h>
|
||||
#include <rte_ether.h>
|
||||
#include <rte_icmp.h>
|
||||
#include <rte_ip.h>
|
||||
#include <rte_lcore.h>
|
||||
#include <rte_mbuf.h>
|
||||
|
||||
#include "PacketDissection/PacketInfo.hpp"
|
||||
|
||||
class PacketInfoIpv6Icmp : public PacketInfo {
|
||||
public:
|
||||
inline PacketInfoIpv6Icmp() { /*set_type(IPv6ICMP);*/
|
||||
}
|
||||
inline void set_ip_hdr(rte_ipv6_hdr* ip6_hdr) { this->_ip6_hdr = ip6_hdr; }
|
||||
inline void set_icmp_hdr(rte_icmp_hdr* icmp_hdr) {
|
||||
this->_icmp_hdr = icmp_hdr;
|
||||
}
|
||||
|
||||
/// IPv6 Functions
|
||||
inline uint32_t get_dst_ip() {
|
||||
/*__uint128_t dest_ip = 0;
|
||||
for (short i = 0; i < 16; i++){
|
||||
dest_ip << 8; /// shift left to make space for next part
|
||||
dest_ip = dest_ip + _ip6_hdr->dst_addr[i]; /// add next part
|
||||
}*/
|
||||
std::cout << "PacketInfoIpv6Icmp not yet implemented! ";
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline uint32_t get_src_ip() {
|
||||
/*__uint128_t src_ip = 0;
|
||||
for (short i = 0; i < 16; i++){
|
||||
src_ip << 8; /// shift left to make space for next part
|
||||
src_ip = src_ip + _ip6_hdr->src_addr[i]; /// add next part
|
||||
}*/
|
||||
printf("PacketInfoIpv6Icmp not yet implemented! ");
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline uint16_t get_packet_size() { return 384; }
|
||||
inline uint16_t get_payload_size() { return 0; }
|
||||
|
||||
private:
|
||||
rte_ipv6_hdr* _ip6_hdr;
|
||||
rte_icmp_hdr* _icmp_hdr;
|
||||
};
|
||||
106
include/PacketDissection/PacketInfoIpv6Tcp.hpp
Normal file
106
include/PacketDissection/PacketInfoIpv6Tcp.hpp
Normal file
@@ -0,0 +1,106 @@
|
||||
/**
|
||||
* @file PacketInfoIpv6Tcp.hpp
|
||||
* @author Tobias
|
||||
* @brief class to provide packets IPv6 and TCP header information
|
||||
* @date 2021-06-09
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <rte_byteorder.h>
|
||||
#include <rte_ether.h>
|
||||
#include <rte_icmp.h>
|
||||
#include <rte_ip.h>
|
||||
#include <rte_lcore.h>
|
||||
#include <rte_mbuf.h>
|
||||
#include <rte_tcp.h>
|
||||
#include <rte_udp.h>
|
||||
|
||||
#include "PacketDissection/PacketInfo.hpp"
|
||||
|
||||
class PacketInfoIpv6Tcp : public PacketInfo {
|
||||
public:
|
||||
inline PacketInfoIpv6Tcp() { /*set_type(IPv6TCP);*/
|
||||
}
|
||||
|
||||
inline void create_reply(rte_mbuf* answ_mbuf, uint32_t seq_num,
|
||||
uint32_t ack_num);
|
||||
|
||||
inline void tear_down_connection(rte_mbuf* return_mbuf,
|
||||
rte_mbuf* forward_mbuf,
|
||||
uint32_t forward_seq_num,
|
||||
uint32_t forward_ack_num);
|
||||
|
||||
inline void set_ip_hdr(rte_ipv6_hdr* ip6_hdr) { this->_ip6_hdr = ip6_hdr; }
|
||||
|
||||
inline void set_tcp_hdr(rte_tcp_hdr* tcp_hdr) { this->_tcp_hdr = tcp_hdr; }
|
||||
|
||||
inline void set_seq_num(uint32_t seq_num) { _tcp_hdr->sent_seq = seq_num; }
|
||||
|
||||
inline void set_ack_num(uint32_t ack_num) { _tcp_hdr->recv_ack = ack_num; }
|
||||
|
||||
/// IPv6 Functions
|
||||
inline uint32_t get_dst_ip() {
|
||||
/*__uint128_t dest_ip = 0;
|
||||
for (short i = 0; i < 16; i++){
|
||||
dest_ip = dest_ip * 256; /// shift left to make space for next
|
||||
part dest_ip = dest_ip + _ip6_hdr->dst_addr[i]; /// add next part
|
||||
}*/
|
||||
std::cout << "PacketInfoIpv6Tcp not yet implemented! ";
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline uint32_t get_src_ip() {
|
||||
/*__uint128_t src_ip = 0;
|
||||
for (short i = 0; i < 16; i++){
|
||||
src_ip = src_ip * 256; /// shift left to make space for next part
|
||||
src_ip = src_ip + _ip6_hdr->src_addr[i]; /// add next part
|
||||
}*/
|
||||
printf("PacketInfoIpv6Tcp not yet implemented! ");
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline uint16_t get_dst_port() { return _tcp_hdr->dst_port; }
|
||||
|
||||
inline uint16_t get_src_port() { return _tcp_hdr->src_port; }
|
||||
|
||||
inline uint8_t get_flags() { return _tcp_hdr->tcp_flags; }
|
||||
|
||||
inline uint16_t get_packet_size() { return _ip6_hdr->payload_len + 320; }
|
||||
|
||||
inline uint16_t get_payload_size() { return _ip6_hdr->payload_len - 20; }
|
||||
|
||||
inline uint16_t get_window_size() { return _tcp_hdr->rx_win; }
|
||||
|
||||
inline uint32_t get_seq_num() { return _tcp_hdr->sent_seq; }
|
||||
|
||||
inline uint32_t get_ack_num() { return _tcp_hdr->recv_ack; }
|
||||
|
||||
/**
|
||||
* @brief NOT YET IMPLEMENTED FOR IPv6
|
||||
* fills empty mbuf with IP and TCP header
|
||||
* If this PacketInfo has a _mbuf and this _mbuf is empty,
|
||||
* then all IP and TCP header information is filled in.
|
||||
* This function doesn't create a new mbuf.
|
||||
* @param src_ip IP address packet originally originated from
|
||||
* @param dst_ip IP address packet is going to be send to
|
||||
* @param src_port TCP port packet originally was send from
|
||||
* @param dst_port TCP port packet should be recieved on
|
||||
* @param seq_num TCP sequence number
|
||||
* @param ack_num TCP acknowledgment number
|
||||
* @param flags TCP flags wich are going to be set, can't set NS flag
|
||||
*/
|
||||
inline void fill_payloadless_tcp_packet(uint32_t src_ip, uint32_t dst_ip,
|
||||
uint16_t src_port,
|
||||
uint16_t dst_port, uint32_t seq_num,
|
||||
uint32_t ack_num, uint8_t flags);
|
||||
|
||||
inline void re_calculate_checksums(); ///> NOT YET IMPLEMENTED FOR IPv6
|
||||
|
||||
private:
|
||||
rte_ipv6_hdr* _ip6_hdr;
|
||||
rte_tcp_hdr* _tcp_hdr;
|
||||
};
|
||||
65
include/PacketDissection/PacketInfoIpv6Udp.hpp
Normal file
65
include/PacketDissection/PacketInfoIpv6Udp.hpp
Normal file
@@ -0,0 +1,65 @@
|
||||
/**
|
||||
* @file PacketInfoIpv6Udp.hpp
|
||||
* @author Tobias
|
||||
* @brief class to provide packets IPv6 and UDP header information
|
||||
* @date 2021-06-09
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <rte_byteorder.h>
|
||||
#include <rte_ether.h>
|
||||
#include <rte_icmp.h>
|
||||
#include <rte_ip.h>
|
||||
#include <rte_lcore.h>
|
||||
#include <rte_mbuf.h>
|
||||
#include <rte_tcp.h>
|
||||
#include <rte_udp.h>
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
#include "PacketDissection/PacketInfo.hpp"
|
||||
|
||||
class PacketInfoIpv6Udp : public PacketInfo {
|
||||
public:
|
||||
inline PacketInfoIpv6Udp() { /*set_type(IPv6UDP);*/
|
||||
}
|
||||
|
||||
inline void set_ip_hdr(rte_ipv6_hdr* ip6_hdr) { this->_ip6_hdr = ip6_hdr; }
|
||||
|
||||
inline void set_udp_hdr(rte_udp_hdr* udp_hdr) { this->_udp_hdr = udp_hdr; }
|
||||
|
||||
/// IPv6 Functions
|
||||
inline uint32_t get_dst_ip() {
|
||||
/*__uint128_t dest_ip = 0;
|
||||
for (short i = 0; i < 16; i++){
|
||||
dest_ip << 8; /// shift left to make space for next part
|
||||
dest_ip = dest_ip + _ip6_hdr->dst_addr[i]; /// add next part
|
||||
}*/
|
||||
printf("PacketInfoIpv6Udp not yet implemented! ");
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline uint32_t get_src_ip() {
|
||||
/*__uint128_t src_ip = 0;
|
||||
for (short i = 0; i < 16; i++){
|
||||
src_ip << 8; /// shift left to make space for next part
|
||||
src_ip = src_ip + _ip6_hdr->src_addr[i]; /// add next part
|
||||
}*/
|
||||
printf("PacketInfoIpv6Udp not yet implemented! ");
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline uint16_t get_dst_port() { return _udp_hdr->dst_port; }
|
||||
|
||||
inline uint16_t get_src_port() { return _udp_hdr->src_port; }
|
||||
|
||||
inline uint16_t get_packet_size() { return _ip6_hdr->payload_len + 320; }
|
||||
|
||||
inline uint16_t get_payload_size() { return _ip6_hdr->payload_len - 8; }
|
||||
|
||||
private:
|
||||
rte_ipv6_hdr* _ip6_hdr;
|
||||
rte_udp_hdr* _udp_hdr;
|
||||
};
|
||||
198
include/PacketDissection/PacketProtTcp.hpp
Normal file
198
include/PacketDissection/PacketProtTcp.hpp
Normal file
@@ -0,0 +1,198 @@
|
||||
/**
|
||||
* @file PacketProtTcp.hpp
|
||||
* @author Tobias
|
||||
* @brief class to extract and change some informations in TCP header
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <boost/log/trivial.hpp>
|
||||
#include <rte_mbuf.h>
|
||||
#include <rte_tcp.h>
|
||||
|
||||
#define FIN_FLAG_POS 0b00000001
|
||||
#define SYN_FLAG_POS 0b00000010
|
||||
#define RST_FLAG_POS 0b00000100
|
||||
#define ACK_FLAG_POS 0b00010000
|
||||
#define FIRST_4_BIT 0b11110000
|
||||
#define TCP_HDR_SIZE_4BYTE_WORD 0b01010000
|
||||
|
||||
class PacketProtTcp {
|
||||
public:
|
||||
// PacketProtTcp(rte_tcp_hdr* tcp_hdr);
|
||||
|
||||
/**
|
||||
* @brief Set packets TCP sequence number
|
||||
*
|
||||
* @param seq_num
|
||||
*/
|
||||
inline static void set_seq_num(rte_tcp_hdr* tcp_hdr, uint32_t seq_num) {
|
||||
tcp_hdr->sent_seq = rte_cpu_to_be_32(seq_num);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set packets TCP acknowledgment number
|
||||
*
|
||||
* @param ack_num
|
||||
*/
|
||||
inline static void set_ack_num(rte_tcp_hdr* tcp_hdr, uint32_t ack_num) {
|
||||
tcp_hdr->recv_ack = rte_cpu_to_be_32(ack_num);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get packets TCP destination port
|
||||
*
|
||||
* @return uint16_t
|
||||
*/
|
||||
inline static uint16_t get_dst_port(rte_tcp_hdr* tcp_hdr) {
|
||||
return rte_be_to_cpu_16(tcp_hdr->dst_port);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get packets TCP source port
|
||||
*
|
||||
* @return uint16_t
|
||||
*/
|
||||
inline static uint16_t get_src_port(rte_tcp_hdr* tcp_hdr) {
|
||||
return rte_be_to_cpu_16(tcp_hdr->src_port);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get packets TCP flags
|
||||
* MSB is CWR flag, LSB is FIN flag, NS flag not included
|
||||
* @return uint8_t
|
||||
*/
|
||||
inline static uint8_t get_flags(rte_tcp_hdr* tcp_hdr) {
|
||||
return tcp_hdr->tcp_flags; // these are FIN to CWR flag, but i am not
|
||||
// shure in which order
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get packets TCP window size
|
||||
*
|
||||
* @return uint16_t
|
||||
*/
|
||||
inline static uint16_t get_window_size(rte_tcp_hdr* tcp_hdr) {
|
||||
return rte_be_to_cpu_16(tcp_hdr->rx_win);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get packets TCP sequence number
|
||||
*
|
||||
* @return uint32_t
|
||||
*/
|
||||
inline static uint32_t get_seq_num(rte_tcp_hdr* tcp_hdr) {
|
||||
return rte_be_to_cpu_32(tcp_hdr->sent_seq);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get packets TCP acknowledgment number
|
||||
*
|
||||
* @return uint32_t
|
||||
*/
|
||||
inline static uint32_t get_ack_num(rte_tcp_hdr* tcp_hdr) {
|
||||
return rte_be_to_cpu_32(tcp_hdr->recv_ack);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get packets TCP-header length
|
||||
*
|
||||
* @return uint16_t
|
||||
*/
|
||||
inline static uint16_t get_tcp_hdr_len(rte_tcp_hdr* tcp_hdr) {
|
||||
return (tcp_hdr->data_off & FIRST_4_BIT) * 4;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get packets TCP SYN flag
|
||||
*
|
||||
* @return true if flag is set
|
||||
* @return false if flag is not set
|
||||
*/
|
||||
inline static bool get_syn_flag(rte_tcp_hdr* tcp_hdr) {
|
||||
if ((tcp_hdr->tcp_flags & SYN_FLAG_POS) == SYN_FLAG_POS) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get packets TCP ACK flag
|
||||
*
|
||||
* @return true if flag is set
|
||||
* @return false if flag is not set
|
||||
*/
|
||||
inline static bool get_ack_flag(rte_tcp_hdr* tcp_hdr) {
|
||||
if ((tcp_hdr->tcp_flags & ACK_FLAG_POS) == ACK_FLAG_POS) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get packets TCP RST flag
|
||||
*
|
||||
* @return true if flag is set
|
||||
* @return false if flag is not set
|
||||
*/
|
||||
inline static bool get_rst_flag(rte_tcp_hdr* tcp_hdr) {
|
||||
if ((tcp_hdr->tcp_flags & RST_FLAG_POS) == RST_FLAG_POS) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get packets TCP FIN flag
|
||||
*
|
||||
* @return true if flag is set
|
||||
* @return false if flag is not set
|
||||
*/
|
||||
inline static bool get_fin_flag(rte_tcp_hdr* tcp_hdr) {
|
||||
if ((tcp_hdr->tcp_flags & FIN_FLAG_POS) == FIN_FLAG_POS) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief fills empty mbuf with IP and TCP header
|
||||
* If this PacketInfo has a _mbuf and this _mbuf is empty,
|
||||
* then all IP and TCP header information is filled in.
|
||||
* This function doesn't create a new mbuf.
|
||||
* @param src_ip IP address packet originally originated from
|
||||
* @param dst_ip IP address packet is going to be send to
|
||||
* @param src_port TCP port packet originally was send from
|
||||
* @param dst_port TCP port packet should be reci#include <rte_ip.h>eved on
|
||||
* @param seq_num TCP sequence number
|
||||
* @param ack_num TCP acknowledgment number
|
||||
* @param flags TCP flags wich are going to be set, can't set NS flag
|
||||
* @param rx_win TCP recive side window
|
||||
*/
|
||||
|
||||
inline static void
|
||||
fill_payloadless_tcp_header(rte_tcp_hdr* tcp_hdr, rte_mbuf* mbuf,
|
||||
uint16_t src_port, uint16_t dst_port,
|
||||
uint32_t seq_num, uint32_t ack_num,
|
||||
uint8_t flags, uint16_t rx_win) {
|
||||
|
||||
tcp_hdr->src_port = rte_cpu_to_be_16(src_port);
|
||||
tcp_hdr->dst_port = rte_cpu_to_be_16(dst_port);
|
||||
tcp_hdr->sent_seq = rte_cpu_to_be_32(seq_num);
|
||||
tcp_hdr->recv_ack = rte_cpu_to_be_32(ack_num);
|
||||
tcp_hdr->data_off = TCP_HDR_SIZE_4BYTE_WORD;
|
||||
tcp_hdr->tcp_flags = flags;
|
||||
tcp_hdr->rx_win = rte_cpu_to_be_16(rx_win);
|
||||
tcp_hdr->tcp_urp = 0;
|
||||
tcp_hdr->cksum = 0;
|
||||
}
|
||||
|
||||
inline static void fill_tcp_cksm(rte_tcp_hdr* tcp_hdr, uint16_t cksm) {
|
||||
tcp_hdr->cksum = rte_cpu_to_be_16(cksm);
|
||||
}
|
||||
};
|
||||
45
include/PacketDissection/PacketProtUdp.hpp
Normal file
45
include/PacketDissection/PacketProtUdp.hpp
Normal file
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
* @file PacketProtUdp.hpp
|
||||
* @author Tobias
|
||||
* @brief provide UDP specific functions
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <rte_byteorder.h>
|
||||
#include <rte_ip.h>
|
||||
#include <rte_lcore.h>
|
||||
#include <rte_mbuf.h>
|
||||
#include <rte_udp.h>
|
||||
|
||||
class PacketProtUdp {
|
||||
public:
|
||||
/**
|
||||
* @brief Get packets UDP destination port
|
||||
*
|
||||
* @return uint16_t
|
||||
*/
|
||||
inline static uint16_t get_dst_port(rte_udp_hdr* const udp_hdr) {
|
||||
return rte_be_to_cpu_16(udp_hdr->dst_port);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get packets UDP source port
|
||||
*
|
||||
* @return uint16_t
|
||||
*/
|
||||
inline static uint16_t get_src_port(rte_udp_hdr* const udp_hdr) {
|
||||
return rte_be_to_cpu_16(udp_hdr->src_port);
|
||||
}
|
||||
|
||||
|
||||
inline static void fill_payloadless_udp_header(rte_udp_hdr* const udp_hdr,
|
||||
uint16_t dst_port, uint16_t src_port) {
|
||||
|
||||
udp_hdr->dst_port = rte_cpu_to_be_16(dst_port);
|
||||
udp_hdr->src_port = rte_cpu_to_be_16(src_port);
|
||||
udp_hdr->dgram_len = rte_cpu_to_be_16(8);
|
||||
udp_hdr->dgram_cksum = 0;
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user