'Forward traffic via libnetfilter_queue
I have a need where i need to forward traffic with libnetfilter_queue to another server, after adding some informations in it.
Problem is that i'm stuck on the forward part , i can do what i want with the packet and add the needed informations, though even while requeing the packet (with NF_REPEAT) with another destination IP, my packet will still be processed by my machine and not sent to the remote host.
From what i understand, the problem lies in the iptables. My iptables config is
iptables -A INPUT -j NFQUEUE --queue-num 0 --queue-bypass
iptables -t nat -m mark --mark 1 -A PREROUTING -s $clientIP -p tcp -j DNAT --to-destination $serverIP
iptables -t nat -A POSTROUTING -j MASQUERADE
The configuration forwards the traffic when i stop my program (and thus the queue is bypassed), so maybe it has something to do with where i put my hook in the iptables flow? It would also help if i can masquerade the traffic but not mandatory (would be better for our logging tools to know where the packet comes from)
If it's usefull, here is the forward function
void reroute(struct iphdr *buffer){
//TODO
printf("The address before rerouting is : %" PRIu32 "\n", buffer->daddr);
fflush(stdout);
buffer->daddr = server_ip;//__bswap_32(server_ip);
printf("The address is : %" PRIu32 "\n", buffer->daddr);
return;
}
Here is the calling function
int ProcessPacket(struct iphdr* buffer)
{
//Get the IP Header part of this packet
struct iphdr *iph = buffer;
printf("IP Protocol is: %d\n", iph->protocol);
switch (iph->protocol) //Check the Protocol and do accordingly
{
case 1: //ICMP Protocol
print_icmp_packet(buffer);
break;
case IPPROTO_TCP: //TCP Protocol
print_tcp_packet(buffer);
process(buffer);
reroute(buffer);
printf("The address after rerouting is: %" PRIu32 "\n", buffer->daddr);
return 2;
break;
default:
return 1;
break;
}
return 0;
}
The libnetfilter interesting part is
if(routing == 2 && !nfq_get_nfmark(nfad)){
printf("destination address is, %x \n", ip->daddr);
struct tcphdr *tcp_header = nfq_tcp_get_hdr(pkBuff);
if(tcp_header != NULL )
{
nfq_tcp_compute_checksum_ipv4(nfq_tcp_get_hdr(pkBuff),ip);
}
return nfq_set_verdict2(queue, ntohl(ph->packet_id), NF_REPEAT, 1, pktb_len(pkBuff), pktb_data(pkBuff)); //queued again so that once marked they can be forwarded
}
else if(routing ==1){
return nfq_set_verdict(queue, ntohl(ph->packet_id), NF_ACCEPT,0, NULL);
}
else{
return nfq_set_verdict(queue, ntohl(ph->packet_id), NF_ACCEPT, 0, NULL);
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|