kernel-power v47 -> kernel-bfs
[kernel-bfs] / kernel-bfs-2.6.28 / debian / patches / joikuspot.diff
1 --- kernel-power-2.6.28/drivers/misc/Makefile   2011-04-16 03:01:15.000000000 +0200
2 +++ kernel-power-2.6.28/drivers/misc/Makefile   2011-04-16 03:01:45.000000000 +0200
3 @@ -3,6 +3,8 @@
4  #
5  obj- := misc.o # Dummy rule to force built-in.o to be made
6  
7 +obj-m += JoikuSpot_Bouncer.o
8 +
9  obj-$(CONFIG_IBM_ASM)          += ibmasm/
10  obj-$(CONFIG_HDPU_FEATURES)    += hdpuftrs/
11  obj-$(CONFIG_OMAP_STI)         += sti/
12 --- kernel-power-2.6.28/drivers/misc/JoikuSpot_Bouncer.c        2011-04-15 15:30:29.223356000 +0200
13 +++ kernel-power-2.6.28/drivers/misc/JoikuSpot_Bouncer.c        2011-04-16 03:00:40.000000000 +0200
14 @@ -0,0 +1,196 @@
15 +/* 
16 + * Implementation of JoikuSpotBouncer module
17 + * JoikuSpot_Bouncer.c
18 + *
19 + * This program is free software; you can redistribute it and/or
20 + * modify it under the terms of the GNU General Public License
21 + * as published by the Free Software Foundation; either version
22 + * 2 of the license, or ( at your option ) any later version
23 + */
24 +
25 +#include <linux/module.h>         /* needed by all kernel modules          */
26 +#include <linux/init.h>           /* needed for custom init/exit functions */
27 +#include <linux/kernel.h>         /* needed for KERN_ALERT macro           */
28 +#include <linux/netfilter.h>      /* Hook register/unregister              */
29 +#include <linux/netfilter_ipv4.h> /* nf_hook_priorities                    */
30 +#include <linux/ip.h>             /* Ip header                             */
31 +#include <linux/tcp.h>            /* Tcp Header                            */
32 +#include <linux/udp.h>            /* Udp Header                            */
33 +#include <net/inet_hashtables.h>  /* __inet_lookup()                       */
34 +#include <net/inet_sock.h>        /* struct inet_sock                      */
35 +
36 +
37 +/* Special macro to indicate license (to avoid tainting the kernel) */
38 +
39 +MODULE_LICENSE( "Dual MIT/GPL" );
40 +MODULE_AUTHOR ( "JoikuSoft Oy Ltd <info@joikusoft.com>" );
41 +
42 +extern struct inet_hashinfo tcp_hashinfo;
43 +extern struct proto udp_prot;
44 +extern struct rwlock_t udp_hash_lock;
45 +
46 +static struct sock *__udp4_lib_lookup( struct net *net ,
47 +    unsigned long int saddr ,
48 +    unsigned short int sport ,
49 +    unsigned long int daddr ,
50 +    unsigned short int dport ,
51 +    int dif ,
52 +    struct hlist_head udptable[] )
53 +    {
54 +    struct sock *sk , *result = NULL;
55 +    struct hlist_node *node;
56 +    unsigned short int hnum = ntohs( dport );
57 +    int badness = -1;
58 +
59 +    read_lock( &udp_hash_lock );
60 +
61 +    sk_for_each ( sk , node , &udptable[ udp_hashfn ( net , hnum ) ] )
62 +        {
63 +        struct inet_sock *inet = inet_sk( sk );
64 +
65 +        if ( net_eq ( sock_net( sk ) , net ) && sk->sk_hash == hnum &&
66 +            !ipv6_only_sock( sk ) )
67 +            {
68 +
69 +            int score = ( sk->sk_family == PF_INET ? 1 : 0 );
70 +
71 +            if ( inet->rcv_saddr )
72 +                {
73 +                if ( inet->rcv_saddr != daddr )
74 +                    {
75 +                    continue;
76 +                    }
77 +                score += 2;
78 +                }
79 +            if ( inet->daddr )
80 +                {
81 +                if ( inet->daddr != saddr )
82 +                    {
83 +                    continue;
84 +                    }
85 +                score += 2;
86 +                }
87 +            if ( inet->dport )
88 +                {
89 +                if ( inet->dport != sport )
90 +                    {
91 +                    continue;
92 +                    }
93 +                score += 2;
94 +                }
95 +            if ( sk->sk_bound_dev_if )
96 +                {
97 +                if ( sk->sk_bound_dev_if != dif )
98 +                    {
99 +                    continue;
100 +                    }
101 +                score += 2;
102 +                }
103 +            if ( score == 9 )
104 +                {
105 +                result = sk;
106 +                break;
107 +                }
108 +                else if ( score > badness )
109 +                {
110 +                result  = sk;
111 +                badness = score;
112 +                }
113 +            }
114 +        }
115 +    if ( result )
116 +        {
117 +        sock_hold ( result );
118 +        }
119 +    read_unlock ( &udp_hash_lock );
120 +    return result;
121 +    }
122 +
123 +
124 +static unsigned int joikuspot_nf_hook ( unsigned int hook ,
125 +    struct sk_buff *pskb ,
126 +    const struct net_device *in ,
127 +    const struct net_device *out ,
128 +    int ( *okfn ) ( struct sk_buff * ) )
129 +    {
130 +    struct sock *sk;
131 +    struct iphdr *iph = ipip_hdr ( pskb );
132 +
133 +    if ( iph->protocol == 6 )
134 +        {
135 +        struct tcphdr *th, tcph;
136 +
137 +        th = skb_header_pointer (
138 +            pskb , iph->ihl << 2 , sizeof( tcph ) , &tcph );
139 +
140 +        sk = __inet_lookup( dev_net ( pskb->dst->dev ) , &tcp_hashinfo , 
141 +            iph->saddr , th->source , iph->daddr , th->dest , inet_iif ( pskb ) );
142 +
143 +        if( !sk )
144 +            {
145 +            return NF_DROP;
146 +            }
147 +        else
148 +            {
149 +            return NF_ACCEPT;
150 +            }
151 +        }
152 +
153 +    if ( iph->protocol == 17 )
154 +        {
155 +        struct udphdr *uh, udph;
156 +
157 +        uh = skb_header_pointer (
158 +            pskb , iph->ihl << 2 , sizeof( udph ) , &udph );
159 +
160 +        sk = __udp4_lib_lookup( dev_net ( pskb->dst->dev ) , iph->saddr , uh->source ,
161 +            iph->daddr , uh->dest , inet_iif ( pskb ) , udp_prot.h.udp_hash );
162 +
163 +        if ( sk != NULL )
164 +            {
165 +            return NF_ACCEPT;
166 +            }
167 +        else
168 +            {
169 +            return NF_DROP;
170 +            }
171 +        }
172 +
173 +    return NF_ACCEPT;
174 +    }
175 +
176 +
177 +static struct nf_hook_ops joikuspot_ops =
178 +    {
179 +    .hook     = joikuspot_nf_hook,
180 +    .owner    = THIS_MODULE,
181 +    .pf       = PF_INET,
182 +    .hooknum  = NF_INET_LOCAL_IN,
183 +    .priority = NF_IP_PRI_FIRST
184 +    };
185 +
186 +static int joikuspot_init( void )
187 +    {
188 +    int retval = 0;
189 +
190 +    printk( KERN_DEBUG "JoikuSpot Bouncer Kernel Module init\n" );
191 +
192 +    retval = nf_register_hook( &joikuspot_ops );
193 +
194 +    if ( retval < 0 )
195 +        {
196 +        return retval;
197 +        }
198 +
199 +    return retval;
200 +    }
201 +
202 +static void joikuspot_exit( void ) 
203 +    {
204 +    nf_unregister_hook ( &joikuspot_ops );
205 +    printk( KERN_DEBUG "JoikuSpot Bouncer Kernel Module exit\n" );
206 +    }
207 +
208 +module_init( joikuspot_init ); 
209 +module_exit( joikuspot_exit );
210 +