aegis-dos-protection/include/PacketDissection/PacketInfoCreator.hpp

290 lines
9.4 KiB
C++
Raw Normal View History

2021-10-23 14:53:40 +00:00
/**
* @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;
}
}
};