dpdk发送RST报文(一)—— 构建RST包
作者:互联网
suricata中阻断报文函数“RejectSendLibnet11IPv4TCP”使用libnet11构造阻断报文。今天试一下自己手动构建RST报文,然后通过dpdk发送出去。
dpdk-response-reject.h
#ifndef __DPDK_RESPONSE_REJECT_H__
#define __DPDK_RESPONSE_REJECT_H__
#include "rte_mbuf.h"
enum RejectDirection {
REJECT_DIR_SRC = 0,
REJECT_DIR_DST = 1,
};
rte_mbuf * DpdkRejectBuildIpv4TCP(rte_mbuf *originalMbuf, enum RejectDirection dir);
#endif
dpdk-response-reject.c
#include "dpdk-response-reject.h"
// 构造tcp头
static int BuildTCP(struct rte_ipv4_hdr *ip, struct rte_tcp_hdr *tcp, uint16_t payloadLen enum RejectDirection dir)
{
uint16_t tmpPort;
uint32_t uTmpSeq;
// 更改tcp头
switch (dir)
{
case REJECT_DIR_SRC:
tmpPort = tcp->src_port;
tcp->src_port = tcp->dst_port;
tcp->dst_port = tmpPort;
uTmpSeq = ntohl(tcp->sent_seq);
if(0 == (tcp->tcp_flags & TH_ACK))
{
tcp->sent_seq = 0; // 没有ack标致,seq应该为0
tcp->recv_ack = htonl(uTmpSeq + payloadLen + 1);
}
else
{
tcp->sent_seq = tcp->recv_ack;
tcp->recv_ack = htonl(uTmpSeq + payloadLen + 1);
}
break;
case REJECT_DIR_DST:
default:
break;
}
tcp->tcp_flags = 0x014; // 置位rst, TH_ACK | TH_RST
tcp->cksum = 0;
tcp->cksum = rte_ipv4_udptcp_cksum(ip, (const void *)tcp);
return 0;
}
// 构造ip头
static int BuildIpv4(struct rte_ipv4_hdr *ip, enum RejectDirection dir)
{
uint16_t ident;
uint32_t tmpAddr;
// 更改ip头
switch (dir)
{
case REJECT_DIR_SRC:
ident = ntohs(ip->packet_id) + 27; /* 改写ident */
ip->packet_id = htons(ident);
ip->fragment_offset = 0;
tmpAddr = ip->src_addr;
ip->src_addr = ip->dst_addr;
ip->dst_addr = tmpAddr;
break;
case REJECT_DIR_DST:
default:
break;
}
ip->hdr_checksum = 0;
ip->hdr_checksum = rte_ipv4_cksum((const struct rte_ipv4_hdr *)ip);
return 0;
}
// 构造以太头
static int BuildEther(struct rte_ether_hdr *eth_hdr, enum RejectDirection dir)
{
struct rte_ether_addr stTmpMac;
// 更改以太头
switch (dir)
{
case REJECT_DIR_SRC:
memcpy( &stTmpMac, ðhdr->s_addr, sizeof(struct rte_ether_addr));
memcpy( ðhdr->s_addr, ðhdr->d_addr, sizeof(struct rte_ether_addr));
memcpy( ðhdr->d_addr, &stTmpMac, sizeof(struct rte_ether_addr));
break;
case REJECT_DIR_DST:
default:
break;
}
return 0;
}
// 构造tcp阻断报文
rte_mbuf * DpdkRejectBuildIpv4TCP(rte_mbuf *originalMbuf, enum RejectDirection dir)
{
// 申请新mbuf用于存储Rst报文内容
struct rte_mbuf *mbuf = rte_pktmbuf_alloc(originalMbuf->pool);
/* 从原mbuf拷贝内容到新mbuf */
memcpy(rte_pktmbuf_mtod(mbuf, void *), rte_pktmbuf_mtod(originalMbuf, void *), originalMbuf->data_len);
mbuf->packet_type = originalMbuf->packet_type;
mbuf->pkt_len = originalMbuf->pkt_len;
mbuf->data_len = originalMbuf->data_len;
mbuf->hash.rss = originalMbuf->hash.rss;
struct rte_ether_hdr *eth_hdr = rte_pktmbuf_mtod(mbuf, struct rte_ether_hdr *); //获取以太头地址
struct rte_ipv4_hdr *ipv4_hdr = (struct rte_ipv4_hdr *)(eth_hdr + 1); //获取ip头地址
struct rte_tcp_hdr *tcp_hdr = (struct rte_tcp_hdr *)(ipv4_hdr + 1); //获取tcp头地址
uint16_t usTcpPayloadLen = rte_pktmbuf_data_len(mbuf) - sizeof(struct rte_ether_hdr) - sizeof(struct rte_ipv4_hdr) - sizeof(struct rte_tcp_hdr); //计算tcp payload长度,填ack number时用到
/* 在原始包上更改,组Rst报文 */
BuildTCP( ipv4_hdr, tcp_hdr, usTcpPayloadLen, dir );
BuildIpv4( ipv4_hdr, dir );
BuildEther( eth_hdr, dir );
return mbuf;
}
标签:rte,hdr,ip,报文,mbuf,struct,tcp,RST,dpdk 来源: https://blog.csdn.net/superbfly/article/details/123125611