Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  1 /* This is a module which is used for setting the TOS field of a packet. */
  2 
  3 /* (C) 1999-2001 Paul `Rusty' Russell
  4  * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
  5  *
  6  * This program is free software; you can redistribute it and/or modify
  7  * it under the terms of the GNU General Public License version 2 as
  8  * published by the Free Software Foundation.
  9  */
 10 
 11 #include <linux/module.h>
 12 #include <linux/skbuff.h>
 13 #include <linux/ip.h>
 14 #include <net/checksum.h>
 15 
 16 #include <linux/netfilter_ipv4/ip_tables.h>
 17 #include <linux/netfilter_ipv4/ipt_TOS.h>
 18 
 19 MODULE_LICENSE("GPL");
 20 MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
 21 MODULE_DESCRIPTION("iptables TOS mangling module");
 22 
 23 static unsigned int
 24 target(struct sk_buff **pskb,
 25        const struct net_device *in,
 26        const struct net_device *out,
 27        unsigned int hooknum,
 28        const void *targinfo,
 29        void *userinfo)
 30 {
 31         const struct ipt_tos_target_info *tosinfo = targinfo;
 32 
 33         if (((*pskb)->nh.iph->tos & IPTOS_TOS_MASK) != tosinfo->tos) {
 34                 u_int16_t diffs[2];
 35 
 36                 if (!skb_ip_make_writable(pskb, sizeof(struct iphdr)))
 37                         return NF_DROP;
 38 
 39                 diffs[0] = htons((*pskb)->nh.iph->tos) ^ 0xFFFF;
 40                 (*pskb)->nh.iph->tos
 41                         = ((*pskb)->nh.iph->tos & IPTOS_PREC_MASK)
 42                         | tosinfo->tos;
 43                 diffs[1] = htons((*pskb)->nh.iph->tos);
 44                 (*pskb)->nh.iph->check
 45                         = csum_fold(csum_partial((char *)diffs,
 46                                                  sizeof(diffs),
 47                                                  (*pskb)->nh.iph->check
 48                                                  ^0xFFFF));
 49                 (*pskb)->nfcache |= NFC_ALTERED;
 50         }
 51         return IPT_CONTINUE;
 52 }
 53 
 54 static int
 55 checkentry(const char *tablename,
 56            const struct ipt_entry *e,
 57            void *targinfo,
 58            unsigned int targinfosize,
 59            unsigned int hook_mask)
 60 {
 61         const u_int8_t tos = ((struct ipt_tos_target_info *)targinfo)->tos;
 62 
 63         if (targinfosize != IPT_ALIGN(sizeof(struct ipt_tos_target_info))) {
 64                 printk(KERN_WARNING "TOS: targinfosize %u != %Zu\n",
 65                        targinfosize,
 66                        IPT_ALIGN(sizeof(struct ipt_tos_target_info)));
 67                 return 0;
 68         }
 69 
 70         if (strcmp(tablename, "mangle") != 0) {
 71                 printk(KERN_WARNING "TOS: can only be called from \"mangle\" table, not \"%s\"\n", tablename);
 72                 return 0;
 73         }
 74 
 75         if (tos != IPTOS_LOWDELAY
 76             && tos != IPTOS_THROUGHPUT
 77             && tos != IPTOS_RELIABILITY
 78             && tos != IPTOS_MINCOST
 79             && tos != IPTOS_NORMALSVC) {
 80                 printk(KERN_WARNING "TOS: bad tos value %#x\n", tos);
 81                 return 0;
 82         }
 83 
 84         return 1;
 85 }
 86 
 87 static struct ipt_target ipt_tos_reg = {
 88         .name           = "TOS",
 89         .target         = target,
 90         .checkentry     = checkentry,
 91         .me             = THIS_MODULE,
 92 };
 93 
 94 static int __init init(void)
 95 {
 96         return ipt_register_target(&ipt_tos_reg);
 97 }
 98 
 99 static void __exit fini(void)
100 {
101         ipt_unregister_target(&ipt_tos_reg);
102 }
103 
104 module_init(init);
105 module_exit(fini);
106 
  This page was automatically generated by the LXR engine.