寻找有关NF_STOLEN的信息。
从NET-FILTER窃取数据包后;我正在通过扩展SKUBUFFER来添加IP头。之后;想要将数据包发送到相应的接口。我们应该用这个步骤做什么功能???或者,如果我们说; NF_ACCEPT。,我们能否确保内核处理Manipulated Packet正确地将其转发到正确的接口?
期待回复!!!
-Thanks in Advance, VKS
答案 0 :(得分:4)
是的,如果你改变了skbuff结构并计算了适当的校验和,你只需要返回NF_ACCEPT。内核将为您处理剩下的事情。
我在论文中做到了这一点。这里是我已经完成的一些代码(它没有扩展或修改skbuff,但它改变了应用程序有效负载中的一个字段。但是,我还做了一些扩展skbuff的代码,理论是相同的):
unsigned int pre_routing_hook(filter_specs* sp, unsigned int hooknum,
struct sk_buff* skb, const struct net_device* in,
const struct net_device *out,
int(*okfn)(struct sk_buff*)) {
struct iphdr* iph;
struct udphdr* udp;
__tp(pdu)* pdu;
/*Omitted some sanity checks */
iph = ip_hdr(skb);
udp = (struct udphdr*) (((char*) iph) + (iph->ihl << 2));
//I didn't care about udp checksum so I've stored zero in this field.
udp->check = 0;
switch (iph->protocol) {
case IPPROTO_UDP:
pdu = (__tp(pdu)*) (((char*) iph) + (iph->ihl << 2)
+ sizeof(struct udphdr));
swap_pdu_byte_order(pdu);
pdu->timestamp = get_kernel_current_time() -
(pdu->timestamp + pdu->rtt * 1000);
swap_pdu_byte_order(pdu);
break;
default:
printk("\tProtocol not supported.\n");
}
return NF_ACCEPT;
}
编辑:我已经看了你发布的代码,这就是我想出的代码。它对我有用:
#include <linux/ip.h>
#include <linux/in.h>
static uint16_t csum(uint16_t* buff, int nwords) {
uint32_t sum;
for (sum = 0; nwords > 0; nwords--)
sum += *buff++;
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
return ((uint16_t) ~sum);
}
//I'm assuming this will run in PRE_ROUTING
unsigned int main_hook(unsigned int hooknum,
struct sk_buff *skb, const struct net_device *in,
const struct net_device *out, int(*okfn)(struct sk_buff*)) {
uint16_t lets_keep_the_original_size;
struct in_device* ipa;
iph = ip_hdr(sock_buff);
lets_keep_the_original_size = ntohs(iph->tot_len);
if(iph->protocol == 1) {
if(skb_headroom(skb) < sizeof(struct iphdr)) {
if( 0 != pskb_expand_head(skb, (sizeof(struct iphdr))-
skb_headroom(skb),0,GFP_ATOMIC) ){
kfree_skb(skb);
return NF_STOLEN;
}
}
iph = (struct iphdr*) skb_push(skb, sizeof(struct iphdr));
iph->proto = IPPROTO_IP;
iph->ihl = 5;
iph->version = 4;
iph->tos = 0;
iph->tot_len = htons(lets_keep_the_original_size + sizeof(struct iphdr));
iph->id = 0;
iph->frag_off = 0;
iph->ttl = 60;
//This must be zero to be able to calculate it with csum above.
iph->check = 0;
//in is the interface where the packet arrived, provided by netfilters.
//In PRE_ROUTING there is no out interface yet so you'll need to add
//the ip manually:
ipa = (struct in_device*) in->ip_ptr;
iph->saddr = ipa->ifa_list->ifa_address;
//in_aton already gives you the address in network byte order .
//You can just add an integer, but I've chosen to use in_aton
//so the code is more readable
iph->daddr = in_aton("192.168.1.1");
//Here is the important part.
iph->check = csum((uint16_t*) iph, (iph->ihl << 1));
//Let the kernel deal with the rest for us.
return NF_ACCEPT;
}
return NF_ACCEPT;
}
如果有什么我可以帮助您,请告诉我。