What I did?
I tried to add a small piece of my own data to the PSH tcp payload, and it can be seen that the transmission was successful and the server was able to respond to the ACK message. However, the Linux kernel seems to have dropped this reply ACK message and continued to send the message I modified before.
Soure Code
<code>int packet_callback(struct nfq_q_handle* qh, struct nfgenmsg* nfmsg,
struct nfq_data* nfa, void* data)
{
struct nfqnl_msg_packet_hdr* ph;
unsigned char* raw;
int nfp_len, status;
struct pkt_buff* pktbuf;
struct iphdr* iph;
struct tcphdr* tcph;
uint16_t seq;
unsigned char* payload;
int plen;
uint32_t verdict = NF_ACCEPT;
uint8_t local_out = 0;
ph = nfq_get_msg_packet_hdr(nfa);
if (!ph)
{
printf("error: cannot get nf message packet hdrn");
return NF_ACCEPT;
}
nfp_len = nfq_get_payload(nfa, &raw);
if (nfp_len < 0)
{
printf("error: invalid payload length %dn", nfp_len);
return NF_ACCEPT;
}
pktbuf = pktb_alloc(AF_INET, raw, nfp_len, 0x1000);
if (!pktbuf)
{
printf("error: cannot allocate pkt buffn");
return NF_ACCEPT;
}
iph = nfq_ip_get_hdr(pktbuf);
if (iph->protocol != IPPROTO_TCP)
{
pktb_free(pktbuf);
return NF_ACCEPT;
}
status = nfq_ip_set_transport_header(pktbuf, iph);
if (status < 0)
{
printf("error: cannot set transport header to pkt buffn");
pktb_free(pktbuf);
return NF_ACCEPT;
}
tcph = nfq_tcp_get_hdr(pktbuf);
if (!tcph)
{
printf("error: cannot get tcp hdrn");
pktb_free(pktbuf);
return NF_ACCEPT;
}
payload = nfq_tcp_get_payload(tcph, pktbuf);
plen = nfq_get_payload(nfa, &payload);
const char* rep = "hello servern";
if ((local_out = nfq_get_outdev(nfa)))
{
uint32_t tcp_plen = get_tcp_payload_len(iph, tcph);
if (tcph->ack && tcph->psh && !tcph->fin && !tcph->rst&&!injected)
{
printf("injectedn");
nfq_tcp_mangle_ipv4(pktbuf, 0, 0, rep, strlen(rep));
injected = true;
}
}
_print_conn_info(iph, tcph);
nfq_ip_set_checksum(iph);
return nfq_set_verdict(qh, ntohl(ph->packet_id), verdict, pktb_len(pktbuf),
pktb_data(pktbuf));
}
</code>
<code>int packet_callback(struct nfq_q_handle* qh, struct nfgenmsg* nfmsg,
struct nfq_data* nfa, void* data)
{
struct nfqnl_msg_packet_hdr* ph;
unsigned char* raw;
int nfp_len, status;
struct pkt_buff* pktbuf;
struct iphdr* iph;
struct tcphdr* tcph;
uint16_t seq;
unsigned char* payload;
int plen;
uint32_t verdict = NF_ACCEPT;
uint8_t local_out = 0;
ph = nfq_get_msg_packet_hdr(nfa);
if (!ph)
{
printf("error: cannot get nf message packet hdrn");
return NF_ACCEPT;
}
nfp_len = nfq_get_payload(nfa, &raw);
if (nfp_len < 0)
{
printf("error: invalid payload length %dn", nfp_len);
return NF_ACCEPT;
}
pktbuf = pktb_alloc(AF_INET, raw, nfp_len, 0x1000);
if (!pktbuf)
{
printf("error: cannot allocate pkt buffn");
return NF_ACCEPT;
}
iph = nfq_ip_get_hdr(pktbuf);
if (iph->protocol != IPPROTO_TCP)
{
pktb_free(pktbuf);
return NF_ACCEPT;
}
status = nfq_ip_set_transport_header(pktbuf, iph);
if (status < 0)
{
printf("error: cannot set transport header to pkt buffn");
pktb_free(pktbuf);
return NF_ACCEPT;
}
tcph = nfq_tcp_get_hdr(pktbuf);
if (!tcph)
{
printf("error: cannot get tcp hdrn");
pktb_free(pktbuf);
return NF_ACCEPT;
}
payload = nfq_tcp_get_payload(tcph, pktbuf);
plen = nfq_get_payload(nfa, &payload);
const char* rep = "hello servern";
if ((local_out = nfq_get_outdev(nfa)))
{
uint32_t tcp_plen = get_tcp_payload_len(iph, tcph);
if (tcph->ack && tcph->psh && !tcph->fin && !tcph->rst&&!injected)
{
printf("injectedn");
nfq_tcp_mangle_ipv4(pktbuf, 0, 0, rep, strlen(rep));
injected = true;
}
}
_print_conn_info(iph, tcph);
nfq_ip_set_checksum(iph);
return nfq_set_verdict(qh, ntohl(ph->packet_id), verdict, pktb_len(pktbuf),
pktb_data(pktbuf));
}
</code>
int packet_callback(struct nfq_q_handle* qh, struct nfgenmsg* nfmsg,
struct nfq_data* nfa, void* data)
{
struct nfqnl_msg_packet_hdr* ph;
unsigned char* raw;
int nfp_len, status;
struct pkt_buff* pktbuf;
struct iphdr* iph;
struct tcphdr* tcph;
uint16_t seq;
unsigned char* payload;
int plen;
uint32_t verdict = NF_ACCEPT;
uint8_t local_out = 0;
ph = nfq_get_msg_packet_hdr(nfa);
if (!ph)
{
printf("error: cannot get nf message packet hdrn");
return NF_ACCEPT;
}
nfp_len = nfq_get_payload(nfa, &raw);
if (nfp_len < 0)
{
printf("error: invalid payload length %dn", nfp_len);
return NF_ACCEPT;
}
pktbuf = pktb_alloc(AF_INET, raw, nfp_len, 0x1000);
if (!pktbuf)
{
printf("error: cannot allocate pkt buffn");
return NF_ACCEPT;
}
iph = nfq_ip_get_hdr(pktbuf);
if (iph->protocol != IPPROTO_TCP)
{
pktb_free(pktbuf);
return NF_ACCEPT;
}
status = nfq_ip_set_transport_header(pktbuf, iph);
if (status < 0)
{
printf("error: cannot set transport header to pkt buffn");
pktb_free(pktbuf);
return NF_ACCEPT;
}
tcph = nfq_tcp_get_hdr(pktbuf);
if (!tcph)
{
printf("error: cannot get tcp hdrn");
pktb_free(pktbuf);
return NF_ACCEPT;
}
payload = nfq_tcp_get_payload(tcph, pktbuf);
plen = nfq_get_payload(nfa, &payload);
const char* rep = "hello servern";
if ((local_out = nfq_get_outdev(nfa)))
{
uint32_t tcp_plen = get_tcp_payload_len(iph, tcph);
if (tcph->ack && tcph->psh && !tcph->fin && !tcph->rst&&!injected)
{
printf("injectedn");
nfq_tcp_mangle_ipv4(pktbuf, 0, 0, rep, strlen(rep));
injected = true;
}
}
_print_conn_info(iph, tcph);
nfq_ip_set_checksum(iph);
return nfq_set_verdict(qh, ntohl(ph->packet_id), verdict, pktb_len(pktbuf),
pktb_data(pktbuf));
}
Thank you for your reply!