2012-11-16 28 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值的位我的Internet停止工作。 有沒有其他方式,或者如果有人能指出我做錯了什麼,這將是非常有益的。

回答

0

您可以使用增量IP校驗和,即:由於IP校驗的總和,你可以在。減去原值和添加新的。 Linux在net/checksum.h中支持csum_replace*()功能。請做:

csum_replace2(&iph->check, htons(oldtos), htons(iph->tos));