2012-11-16 4 views
3

IP 헤더의 tos 비트 값을 변경하는 방법은 무엇입니까? iphdr 구조를 사용하여 직접 수정 해 보았습니다. netfilter를 사용하여 커널 수준에서 수행됩니다. 다음과 같이 내가 쓴 코드는 다음과 같습니다헤더를 손상시키지 않고 ip 헤더의 tos 비트를 변경하는 방법

// Including the required header files 

#include <linux/kernel.h> 
#include <linux/module.h> 
#include <linux/netfilter.h> 
#include <linux/netfilter_ipv4.h> 
#include <linux/init.h> 
#include <linux/kthread.h> 
#include <linux/signal.h> 
#include <linux/errno.h> 
#include <linux/sched.h> 
#include <linux/wait.h> 
#include <linux/types.h> 
#include <linux/netdevice.h> 
#include <linux/ip.h> 
#include <linux/tcp.h> 
#include <linux/in.h> 
#include <linux/inet.h> 
#include <linux/delay.h> 
#include <linux/string.h> 
#include <linux/socket.h> 
#include <linux/net.h> 
#include <net/sock.h> 
#include <asm/processor.h> 
#include <asm/uaccess.h> 
#include <linux/file.h> 
#include <linux/fs.h> 
#include <linux/stat.h> 
#include <linux/proc_fs.h> 

// Defining the name of the module 
#define MODULE_NAME "TOS_setter" 

// Structure definition for processing outgoing packets 
static struct nf_hook_ops nf_ops_out; 

//=========================================================== 
// Function that modifies the TOS bits 
unsigned int tos_setter(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; 
unsigned char tosbits; 

if (!skb)return NF_ACCEPT; 

iph = ip_hdr(skb); 

if (!iph)return NF_ACCEPT; 
//if(iph->protocol==IPPROTO_TCP)return NF_ACCEPT; 

if (iph->protocol==IPPROTO_TCP) 
    { 
printk(KERN_ALERT " The total length is : %d\n" , (int)iph->tot_len); 
iph->tos = tosbits | (unsigned char)2; 
tosbits = iph->tos; 
printk(KERN_ALERT " The tos bits are : %d\n" , (int)tosbits); 
printk(KERN_ALERT " The total length is : %d\n" , (int)iph->tot_len); 
} 
return NF_ACCEPT; 
} 


//=========================================================== 
//Initialisation function 
static int __init init(void){ 

    printk(KERN_ALERT " Initialization Started \n"); 

// Initialize Hook Functions 
    nf_ops_out.hook = tos_setter; 
    nf_ops_out.pf = PF_INET; 
    nf_ops_out.hooknum =4; 
    nf_ops_out.priority = NF_IP_PRI_FIRST; 
// Register the Hook functions 
    nf_register_hook(&nf_ops_out); 
    printk(KERN_ALERT "hook functions registered\n"); 

    printk(KERN_ALERT " KSTAT Initialization Completed \n"); 
    return 0; 
} 

static void __exit cleanup(void){ 

    printk(KERN_ALERT "KSTAT Exit Started\n"); 

// Unregister the hook functions 
    nf_unregister_hook(&nf_ops_out); 
    printk("Unregistered the hooks\n"); 


    printk(KERN_ALERT "KSTAT Exit Completed\n"); 
} 

/* init and cleanup functions */ 
module_init(init); 
module_exit(cleanup); 

MODULE_LICENSE("GPL"); 

문제는 내 인터넷 비트 TOS의 값을 변경하려고 할 때 작동을 중지한다는 것입니다. 다른 방법이 있거나 누군가 내가 잘못하고있는 것을 지적 할 수 있다면 그것이 정말로 도움이 될 것입니다.

답변

0

당신은 즉 증분 IP 체크섬을 사용할 수는 IP 체크섬 이 합이이기 때문에, 당신은 이전 값을 빼지하고 새로운 하나를 추가 할 수 있습니다. 리눅스는 csum_replace*() 함수를 가진 함수를 net/checksum.h으로 지원합니다. 다음과 같이하십시오 :

csum_replace2(&iph->check, htons(oldtos), htons(iph->tos)); 
관련 문제