# BRCM_VERSION=3
[bcm963xx.git] / kernel / linux / net / ipv4 / netfilter / ip_conntrack_proto_udp.c
1 /* (C) 1999-2001 Paul `Rusty' Russell
2  * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  */
8
9 #include <linux/types.h>
10 #include <linux/sched.h>
11 #include <linux/timer.h>
12 #include <linux/netfilter.h>
13 #include <linux/in.h>
14 #if defined(CONFIG_MIPS_BRCM)
15 #include <linux/ip.h>
16 #endif
17 #include <linux/udp.h>
18 #include <linux/netfilter_ipv4/ip_conntrack_protocol.h>
19
20 unsigned long ip_ct_udp_timeout = 30*HZ;
21 unsigned long ip_ct_udp_timeout_stream = 180*HZ;
22
23 #if defined(CONFIG_MIPS_BRCM)
24 unsigned long ip_ct_udp_unreplieddns_timeout = 1*HZ;
25 #endif
26
27 static int udp_pkt_to_tuple(const struct sk_buff *skb,
28                              unsigned int dataoff,
29                              struct ip_conntrack_tuple *tuple)
30 {
31         struct udphdr hdr;
32
33         /* Actually only need first 8 bytes. */
34         if (skb_copy_bits(skb, dataoff, &hdr, 8) != 0)
35                 return 0;
36
37         tuple->src.u.udp.port = hdr.source;
38         tuple->dst.u.udp.port = hdr.dest;
39
40         return 1;
41 }
42
43 static int udp_invert_tuple(struct ip_conntrack_tuple *tuple,
44                             const struct ip_conntrack_tuple *orig)
45 {
46         tuple->src.u.udp.port = orig->dst.u.udp.port;
47         tuple->dst.u.udp.port = orig->src.u.udp.port;
48         return 1;
49 }
50
51 /* Print out the per-protocol part of the tuple. */
52 static unsigned int udp_print_tuple(char *buffer,
53                                     const struct ip_conntrack_tuple *tuple)
54 {
55         return sprintf(buffer, "sport=%hu dport=%hu ",
56                        ntohs(tuple->src.u.udp.port),
57                        ntohs(tuple->dst.u.udp.port));
58 }
59
60 /* Print out the private part of the conntrack. */
61 static unsigned int udp_print_conntrack(char *buffer,
62                                         const struct ip_conntrack *conntrack)
63 {
64         return 0;
65 }
66
67 /* Returns verdict for packet, and may modify conntracktype */
68 static int udp_packet(struct ip_conntrack *conntrack,
69                       const struct sk_buff *skb,
70                       enum ip_conntrack_info conntrackinfo)
71 {
72         /* If we've seen traffic both ways, this is some kind of UDP
73            stream.  Extend timeout. */
74         if (test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)) {
75                 ip_ct_refresh(conntrack, ip_ct_udp_timeout_stream);
76                 /* Also, more likely to be important, and not a probe */
77                 set_bit(IPS_ASSURED_BIT, &conntrack->status);
78         } else
79 #if defined(CONFIG_MIPS_BRCM) 
80         {
81                 /* Special handling of UNRPLIED DNS query packet: Song Wang
82                 *  Before NAT and WAN interface are UP, during that time window,
83                 * if a DNS query is sent out, there will be an UNRPLIED DNS connection track entry
84                 * in which expected src/dst are private IP addresses in the tuple.
85                 * After  NAT and WAN interface are UP, the UNRPLIED DNS connection track
86                 * entry should go away ASAP to enable the establishment  of the tuple with
87                 * the expected src/dst that are public IP addresses. 
88                 */
89                 struct iphdr *iph = skb->nh.iph;
90                 struct udphdr *udph = (void *)iph + iph->ihl * 4;
91                 __u16 dport = ntohs(udph->dest);
92
93                 if (dport == 53)
94                         ip_ct_refresh(conntrack, ip_ct_udp_unreplieddns_timeout);
95                 else   
96                         ip_ct_refresh(conntrack, ip_ct_udp_timeout);
97         }
98 #else   
99                 ip_ct_refresh(conntrack, ip_ct_udp_timeout);
100 #endif          
101
102         return NF_ACCEPT;
103 }
104
105 /* Called when a new connection for this protocol found. */
106 static int udp_new(struct ip_conntrack *conntrack, const struct sk_buff *skb)
107 {
108         return 1;
109 }
110
111 struct ip_conntrack_protocol ip_conntrack_protocol_udp
112 = { { NULL, NULL }, IPPROTO_UDP, "udp",
113     udp_pkt_to_tuple, udp_invert_tuple, udp_print_tuple, udp_print_conntrack,
114     udp_packet, udp_new, NULL, NULL, NULL };