我已经开始为netfilter编写内核模块。
我能够挂钩netfilter并能够访问sk_buff。 现在我正在尝试修改数据包(sk_buff)并尝试在tcp堆栈中重新注入数据包但它无法正常工作。
我的要求是从服务器丢弃SYN-ACK数据包,并将已完成的ack数据包发送回服务器,而不将SYN-ACK发送给客户端。
我在交换源/目标IP,源/目标端口后尝试了dev_queue_xmit 和source / dest MAC并重新计算校验和,然后使用dev_queue_xmit发送数据包。虽然dev_queue_xmit返回成功,但数据包不会注入堆栈。任何帮助将不胜感激。
我的代码:
代码是NF_INET_POST_ROUTING hook的一部分。
void do_exp(struct sk_buff *skb)
{
printk(KERN_INFO "Enering do_exp\n");
struct iphdr *ip_header = (struct iphdr *)skb_network_header(skb);
struct tcphdr *tcp_header = (struct tcphdr *)skb_transport_header(skb);
struct sk_buff *newskb;
struct iphdr *newiph;
struct tcphdr *newtcph;
newskb = skb_copy(skb, GFP_ATOMIC);
//newskb->pkt_type = PACKET_OUTGOING;
// newskb->pkt_type = PACKET_HOST;
/*changing Mac address */
unsigned char srcaddr[6];
struct ethhdr *eth = eth_hdr(skb);
struct ethhdr *neweth = eth_hdr(newskb);
memcpy(srcaddr, eth->h_source, ETH_ALEN);
memcpy(neweth->h_source, eth->h_dest, ETH_ALEN);
memcpy(neweth->h_dest, srcaddr, ETH_ALEN);
newiph = (struct iphdr *) skb_network_header(newskb);
newtcph = (struct tcphdr *) skb_transport_header(newskb);
newiph->saddr = ip_header->daddr;
newiph->daddr = ip_header->saddr;
newtcph->source = tcp_header->dest;
newtcph->dest = tcp_header->source;
newtcph->syn = 0;
newtcph->ack_seq = tcp_header->seq + 1;
newtcph->seq = tcp_header->ack_seq;
newiph->check = ip_fast_csum((unsigned char *)newiph, newiph->ihl);
int ret = dev_queue_xmit(newskb);
}
TCP转储正确显示。