Commit | Line | Data |
---|---|---|
1da177e4 LT |
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 | ||
6709dbbb | 16 | #include <linux/netfilter/x_tables.h> |
1da177e4 LT |
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 | |
d3c5ee6d JE |
24 | tos_tg(struct sk_buff *skb, const struct net_device *in, |
25 | const struct net_device *out, unsigned int hooknum, | |
26 | const struct xt_target *target, const void *targinfo) | |
1da177e4 LT |
27 | { |
28 | const struct ipt_tos_target_info *tosinfo = targinfo; | |
3db05fea | 29 | struct iphdr *iph = ip_hdr(skb); |
1da177e4 | 30 | |
da878c8e | 31 | if ((iph->tos & IPTOS_TOS_MASK) != tosinfo->tos) { |
43bc0ca7 | 32 | __u8 oldtos; |
3db05fea | 33 | if (!skb_make_writable(skb, sizeof(struct iphdr))) |
1da177e4 | 34 | return NF_DROP; |
3db05fea | 35 | iph = ip_hdr(skb); |
da878c8e PM |
36 | oldtos = iph->tos; |
37 | iph->tos = (iph->tos & IPTOS_PREC_MASK) | tosinfo->tos; | |
be0ea7d5 | 38 | csum_replace2(&iph->check, htons(oldtos), htons(iph->tos)); |
1da177e4 | 39 | } |
6709dbbb | 40 | return XT_CONTINUE; |
1da177e4 LT |
41 | } |
42 | ||
e1931b78 | 43 | static bool |
d3c5ee6d JE |
44 | tos_tg_check(const char *tablename, const void *e_void, |
45 | const struct xt_target *target, void *targinfo, | |
46 | unsigned int hook_mask) | |
1da177e4 LT |
47 | { |
48 | const u_int8_t tos = ((struct ipt_tos_target_info *)targinfo)->tos; | |
49 | ||
1da177e4 LT |
50 | if (tos != IPTOS_LOWDELAY |
51 | && tos != IPTOS_THROUGHPUT | |
52 | && tos != IPTOS_RELIABILITY | |
53 | && tos != IPTOS_MINCOST | |
54 | && tos != IPTOS_NORMALSVC) { | |
55 | printk(KERN_WARNING "TOS: bad tos value %#x\n", tos); | |
e1931b78 | 56 | return false; |
1da177e4 | 57 | } |
e1931b78 | 58 | return true; |
1da177e4 LT |
59 | } |
60 | ||
d3c5ee6d | 61 | static struct xt_target tos_tg_reg __read_mostly = { |
1da177e4 | 62 | .name = "TOS", |
6709dbbb | 63 | .family = AF_INET, |
d3c5ee6d | 64 | .target = tos_tg, |
1d5cd909 PM |
65 | .targetsize = sizeof(struct ipt_tos_target_info), |
66 | .table = "mangle", | |
d3c5ee6d | 67 | .checkentry = tos_tg_check, |
1da177e4 LT |
68 | .me = THIS_MODULE, |
69 | }; | |
70 | ||
d3c5ee6d | 71 | static int __init tos_tg_init(void) |
1da177e4 | 72 | { |
d3c5ee6d | 73 | return xt_register_target(&tos_tg_reg); |
1da177e4 LT |
74 | } |
75 | ||
d3c5ee6d | 76 | static void __exit tos_tg_exit(void) |
1da177e4 | 77 | { |
d3c5ee6d | 78 | xt_unregister_target(&tos_tg_reg); |
1da177e4 LT |
79 | } |
80 | ||
d3c5ee6d JE |
81 | module_init(tos_tg_init); |
82 | module_exit(tos_tg_exit); |