This source file includes following definitions.
- masq_irc_init_1
- masq_irc_done_1
- masq_irc_out
- ip_masq_irc_init
- ip_masq_irc_done
- init_module
- cleanup_module
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 #include <linux/module.h>
24
25 #include <linux/types.h>
26 #include <linux/kernel.h>
27 #include <asm/system.h>
28 #include <linux/skbuff.h>
29 #include <linux/in.h>
30 #include <linux/ip.h>
31 #include <net/protocol.h>
32 #include <net/tcp.h>
33 #include <net/ip_masq.h>
34
35 #define DEBUG_CONFIG_IP_MASQ_IRC 0
36
37 static int
38 masq_irc_init_1 (struct ip_masq_app *mapp, struct ip_masq *ms)
39 {
40 MOD_INC_USE_COUNT;
41 return 0;
42 }
43
44 static int
45 masq_irc_done_1 (struct ip_masq_app *mapp, struct ip_masq *ms)
46 {
47 MOD_DEC_USE_COUNT;
48 return 0;
49 }
50
51 int
52 masq_irc_out (struct ip_masq_app *mapp, struct ip_masq *ms, struct sk_buff **skb_p, struct device *dev)
53 {
54 struct sk_buff *skb;
55 struct iphdr *iph;
56 struct tcphdr *th;
57 char *data, *data_limit;
58 __u32 s_addr;
59 __u16 s_port;
60 struct ip_masq *n_ms;
61 char buf[20];
62 unsigned buf_len;
63 int diff;
64 int xtra_args = 0;
65 char *dcc_p, *addr_beg_p, *addr_end_p;
66
67 skb = *skb_p;
68 iph = skb->h.iph;
69 th = (struct tcphdr *)&(((char *)iph)[iph->ihl*4]);
70 data = (char *)&th[1];
71
72
73
74
75
76
77
78
79
80
81
82
83
84 data_limit = skb->h.raw + skb->len;
85
86 while (data < (data_limit - 25) )
87 {
88 if (memcmp(data,"DCC ",4)) {
89 data ++;
90 continue;
91 }
92
93 dcc_p = data;
94 data += 4;
95
96 if (memcmp(data, "CHAT ", 5) == 0 ||
97 memcmp(data, "SEND ", 5) == 0)
98 {
99
100
101
102
103 if (*data == 'S') xtra_args++;
104 data += 5;
105 }
106 else
107 continue;
108
109
110
111
112
113 while( *data++ != ' ')
114
115
116
117
118
119 if (data > (data_limit-12)) return 0;
120
121
122 addr_beg_p = data;
123
124
125
126
127
128 s_addr = simple_strtoul(data,&data,10);
129 if (*data++ !=' ')
130 continue;
131
132
133
134
135
136 s_port = simple_strtoul(data,&data,10);
137 addr_end_p = data;
138
139
140
141
142
143 while(xtra_args) {
144 if (*data != ' ')
145 break;
146 data++;
147 simple_strtoul(data,&data,10);
148 xtra_args--;
149 }
150
151 if (xtra_args != 0) continue;
152
153
154
155
156
157 if (data[0] != 0x01)
158 continue;
159 if (data[1]!='\r' && data[1]!='\n')
160 continue;
161
162
163
164
165
166
167
168 n_ms = ip_masq_new(dev, IPPROTO_TCP,
169 htonl(s_addr),htons(s_port),
170 0, 0,
171 IP_MASQ_F_NO_DPORT|IP_MASQ_F_NO_DADDR
172 );
173 if (n_ms==NULL)
174 return 0;
175
176 ip_masq_set_expire(n_ms, ip_masq_expire->tcp_fin_timeout);
177
178
179
180
181
182 buf_len = sprintf(buf,"%lu %u",
183 ntohl(n_ms->maddr),ntohs(n_ms->mport));
184
185
186
187
188
189 diff = buf_len - (addr_end_p-addr_beg_p);
190
191 #if DEBUG_CONFIG_IP_MASQ_IRC
192 *addr_beg_p = '\0';
193 printk("masq_irc_out(): '%s' %X:%X detected (diff=%d)\n", dcc_p, s_addr,s_port, diff);
194 #endif
195
196
197
198
199 if (diff==0)
200 {
201
202
203
204 memcpy(addr_beg_p,buf,buf_len);
205 return 0;
206 }
207
208 *skb_p = ip_masq_skb_replace(skb, GFP_ATOMIC,
209 addr_beg_p, addr_end_p-addr_beg_p,
210 buf, buf_len);
211 return diff;
212 }
213 return 0;
214
215 }
216
217
218
219
220
221
222
223
224
225 struct ip_masq_app ip_masq_irc = {
226 NULL,
227 "irc",
228 0,
229 0,
230 masq_irc_init_1,
231 masq_irc_done_1,
232 masq_irc_out,
233 NULL
234 };
235
236
237
238
239
240 int ip_masq_irc_init(void)
241 {
242 return register_ip_masq_app(&ip_masq_irc, IPPROTO_TCP, 6667);
243 }
244
245
246
247
248
249 int ip_masq_irc_done(void)
250 {
251 return unregister_ip_masq_app(&ip_masq_irc);
252 }
253
254 #ifdef MODULE
255
256 int init_module(void)
257 {
258 if (ip_masq_irc_init() != 0)
259 return -EIO;
260 register_symtab(NULL);
261 return 0;
262 }
263
264 void cleanup_module(void)
265 {
266 if (ip_masq_irc_done() != 0)
267 printk("ip_masq_irc: can't remove module");
268 }
269
270 #endif