2 * Packet matching code.
4 * Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling
5 * Copyright (C) 2009-2002 Netfilter core team <coreteam@netfilter.org>
7 * 19 Jan 2002 Harald Welte <laforge@gnumonks.org>
8 * - increase module usage count as soon as we have rules inside
11 #include <linux/config.h>
12 #include <linux/cache.h>
13 #include <linux/skbuff.h>
14 #include <linux/kmod.h>
15 #include <linux/vmalloc.h>
16 #include <linux/netdevice.h>
17 #include <linux/module.h>
19 #include <linux/tcp.h>
20 #include <linux/udp.h>
22 #include <linux/if_vlan.h>
23 #include <net/route.h>
25 #include <linux/netfilter.h>
26 #include <linux/netfilter_ipv4.h>
27 #include <net/netfilter/nf_nat_core.h>
28 #include <net/netfilter/nf_conntrack.h>
29 #include <net/netfilter/nf_conntrack_core.h>
30 #include <linux/netfilter/nf_conntrack_common.h>
31 #include <linux/netfilter_ipv4/ip_tables.h>
32 #include <linux/proc_fs.h>
35 #define DEBUGP(format, args...)
37 unsigned int dnsmq_ip
=0;
39 unsigned char dnsmq_mac
[ETH_ALEN
] = { 0x00, 0xe0, 0x11, 0x22, 0x33, 0x44 };
40 typedef int (*dnsmqHitHook
)(struct sk_buff
*skb
);
41 dnsmqHitHook dnsmq_hit_hook
= NULL
;
43 static inline void dnsmq_hit_hook_func(dnsmqHitHook hook_func
)
45 dnsmq_hit_hook
= hook_func
;
48 void dump_packet(struct sk_buff
*skb
, char *title
)
52 if(nvram_match("dnsmq_debug", "1")) {
53 printk("dump packet[%s] %x %x %x", title
, skb
->len
, skb
->mac_len
, skb
->data_len
);
54 if(skb
->dev
) printk("%s\n", skb
->dev
->name
);
57 if(skb
&& skb
->data
) {
58 for(i
=0;i
<skb
->len
&&i
<120;i
++) {
59 if(i
%16==0) printk("\n");
60 printk("%x ", skb
->data
[i
]);
67 EXPORT_SYMBOL(dump_packet
);
69 #define MAXDNSNAME 256
70 #pragma pack(1) // let struct be neat by byte
72 typedef struct Flags_Pack
{
85 typedef struct DNS_HEADER
{
94 uint16_t additional_rss
;
97 typedef struct DNS_QUERIES
{
98 char name
[MAXDNSNAME
];
103 typedef struct DNS_REQUEST
{
108 static inline int dnschar_cmp(char a
, char b
)
114 if(a
>='a'&&a
<='z') a1
= 'A' + a
- 'a';
115 else if(a
>='A'&&a
<='Z') a1
= 'a' + a
- 'A';
123 static inline int dnsmq_hit(struct udphdr
*udph
)
125 dns_query_packet
*dns_query
;
128 dns_query
= (dns_query_packet
*)((unsigned char *)udph
+ sizeof(struct udphdr
));
131 //printk("dns hit\n");
132 for(i
=0;dns_query
->queries
.name
[i
]!=0;i
++) {
133 //printk("%x %x %x\n", i, dns_query->queries.name[i], dnsmq_name[i]);
134 if(dnschar_cmp(dns_query
->queries
.name
[i
],dnsmq_name
[j
])) return 0;
140 static inline int dnsmq_func(struct sk_buff
*skb
)
143 struct vlan_ethhdr
*vethh
;
150 if(dnsmq_ip
==0) return 0;
152 if(!skb
|| !skb
->data
) return 0;
154 ethh
= (struct ethhdr
*)skb
->data
;
156 proto
= ntohs(ethh
->h_proto
);
158 if(proto
== ETH_P_IP
) hlen
= ETH_HLEN
;
159 else if (proto
== ETH_P_8021Q
) {
160 vethh
= (struct vlan_ethhdr
*)skb
->data
;
161 if(vethh
->h_vlan_encapsulated_proto
== htons(ETH_P_IP
))
162 hlen
= VLAN_ETH_HLEN
;
167 iph
= (struct iphdr
*)(skb
->data
+hlen
);
169 // IP & DNS & Looking for my host name
170 if(iph
->protocol
==IPPROTO_UDP
) {
171 udph
= (struct udphdr
*)(skb
->data
+hlen
+(iph
->ihl
<<2));
172 if(ntohs(udph
->dest
)==53) {
173 if(dnsmq_hit(udph
)) {
174 memcpy(ethh
->h_dest
, dnsmq_mac
, ETH_ALEN
);
175 //dump_packet(skb, "dnshit");
180 // IP & HTTP & Original Locol IP & Looking for my host name
181 else if(iph
->protocol
==IPPROTO_TCP
) {
182 tcph
= (struct tcphdr
*)(skb
->data
+hlen
+(iph
->ihl
<<2));
183 if(iph
->daddr
==dnsmq_ip
&& ntohs(tcph
->dest
)==80) {
184 memcpy(ethh
->h_dest
, dnsmq_mac
, ETH_ALEN
);
185 //dump_packet(skb, "httphit");
192 static int dnsmq_ctrl(struct file
*file
, const char *buffer
, unsigned long length
, void *data
)
199 // "[dnsmq ip] [dnsmq name]
200 if ((length
> 0) && (length
< 32)) {
201 memcpy(s
, buffer
, length
);
203 for(i
=0;i
<length
;i
++) {
209 dnsmq_ip
= simple_strtoul(s
, NULL
, 16);
211 // convert to dnsname format
216 dnsmq_name
[j
]=strlen(ptr
);
217 memcpy(dnsmq_name
+j
+1, ptr
, strlen(ptr
));
218 j
+= strlen(ptr
) + 1;
222 dnsmq_name
[j
]=strlen(ptr
);
223 memcpy(dnsmq_name
+j
+1, ptr
, strlen(ptr
));
224 dnsmq_name
[j
+1+strlen(ptr
)]=0;
229 printk("dnsmq ctrl: %x %s\n", dnsmq_ip
, dnsmq_name
);
231 if(dnsmq_ip
==0) dnsmq_hit_hook_func (NULL
);
232 else dnsmq_hit_hook_func(dnsmq_func
);
237 static int __init
init(void)
239 #ifdef CONFIG_PROC_FS
240 struct proc_dir_entry
*p
;
242 p
= create_proc_entry("dnsmqctrl", 0200, proc_net
);
245 p
->owner
= THIS_MODULE
;
246 p
->write_proc
= dnsmq_ctrl
;
249 // it will be enabled later
250 dnsmq_hit_hook_func (NULL
);
254 static void __exit
fini(void)
256 dnsmq_hit_hook_func (NULL
);
259 EXPORT_SYMBOL(dnsmq_hit_hook
);
263 MODULE_LICENSE("Proprietary");