Merge to Fedora kernel-2.6.18-1.2224_FC5 patched with stable patch-2.6.18.1-vs2.0...
[linux-2.6.git] / net / netfilter / nf_conntrack_proto_sctp.c
1 /*
2  * Connection tracking protocol helper module for SCTP.
3  * 
4  * SCTP is defined in RFC 2960. References to various sections in this code 
5  * are to this RFC.
6  * 
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 2 as
9  * published by the Free Software Foundation.
10  *
11  * 17 Oct 2004: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
12  *      - enable working with L3 protocol independent connection tracking.
13  *
14  * Derived from net/ipv4/ip_conntrack_sctp.c
15  */
16
17 /*
18  * Added support for proc manipulation of timeouts.
19  */
20
21 #include <linux/types.h>
22 #include <linux/sched.h>
23 #include <linux/timer.h>
24 #include <linux/netfilter.h>
25 #include <linux/module.h>
26 #include <linux/in.h>
27 #include <linux/ip.h>
28 #include <linux/sctp.h>
29 #include <linux/string.h>
30 #include <linux/seq_file.h>
31 #include <linux/spinlock.h>
32 #include <linux/interrupt.h>
33
34 #include <net/netfilter/nf_conntrack.h>
35 #include <net/netfilter/nf_conntrack_protocol.h>
36
37 #if 0
38 #define DEBUGP(format, ...) printk(format, ## __VA_ARGS__)
39 #else
40 #define DEBUGP(format, args...)
41 #endif
42
43 /* Protects conntrack->proto.sctp */
44 static DEFINE_RWLOCK(sctp_lock);
45
46 /* FIXME: Examine ipfilter's timeouts and conntrack transitions more
47    closely.  They're more complex. --RR 
48
49    And so for me for SCTP :D -Kiran */
50
51 static const char *sctp_conntrack_names[] = {
52         "NONE",
53         "CLOSED",
54         "COOKIE_WAIT",
55         "COOKIE_ECHOED",
56         "ESTABLISHED",
57         "SHUTDOWN_SENT",
58         "SHUTDOWN_RECD",
59         "SHUTDOWN_ACK_SENT",
60 };
61
62 #define SECS  * HZ
63 #define MINS  * 60 SECS
64 #define HOURS * 60 MINS
65 #define DAYS  * 24 HOURS
66
67 static unsigned int nf_ct_sctp_timeout_closed            =  10 SECS;
68 static unsigned int nf_ct_sctp_timeout_cookie_wait       =   3 SECS;
69 static unsigned int nf_ct_sctp_timeout_cookie_echoed     =   3 SECS;
70 static unsigned int nf_ct_sctp_timeout_established       =   5 DAYS;
71 static unsigned int nf_ct_sctp_timeout_shutdown_sent     = 300 SECS / 1000;
72 static unsigned int nf_ct_sctp_timeout_shutdown_recd     = 300 SECS / 1000;
73 static unsigned int nf_ct_sctp_timeout_shutdown_ack_sent =   3 SECS;
74
75 static unsigned int * sctp_timeouts[]
76 = { NULL,                                  /* SCTP_CONNTRACK_NONE  */
77     &nf_ct_sctp_timeout_closed,            /* SCTP_CONNTRACK_CLOSED */
78     &nf_ct_sctp_timeout_cookie_wait,       /* SCTP_CONNTRACK_COOKIE_WAIT */
79     &nf_ct_sctp_timeout_cookie_echoed,     /* SCTP_CONNTRACK_COOKIE_ECHOED */
80     &nf_ct_sctp_timeout_established,       /* SCTP_CONNTRACK_ESTABLISHED */
81     &nf_ct_sctp_timeout_shutdown_sent,     /* SCTP_CONNTRACK_SHUTDOWN_SENT */
82     &nf_ct_sctp_timeout_shutdown_recd,     /* SCTP_CONNTRACK_SHUTDOWN_RECD */
83     &nf_ct_sctp_timeout_shutdown_ack_sent  /* SCTP_CONNTRACK_SHUTDOWN_ACK_SENT */
84  };
85
86 #define sNO SCTP_CONNTRACK_NONE
87 #define sCL SCTP_CONNTRACK_CLOSED
88 #define sCW SCTP_CONNTRACK_COOKIE_WAIT
89 #define sCE SCTP_CONNTRACK_COOKIE_ECHOED
90 #define sES SCTP_CONNTRACK_ESTABLISHED
91 #define sSS SCTP_CONNTRACK_SHUTDOWN_SENT
92 #define sSR SCTP_CONNTRACK_SHUTDOWN_RECD
93 #define sSA SCTP_CONNTRACK_SHUTDOWN_ACK_SENT
94 #define sIV SCTP_CONNTRACK_MAX
95
96 /* 
97         These are the descriptions of the states:
98
99 NOTE: These state names are tantalizingly similar to the states of an 
100 SCTP endpoint. But the interpretation of the states is a little different,
101 considering that these are the states of the connection and not of an end 
102 point. Please note the subtleties. -Kiran
103
104 NONE              - Nothing so far.
105 COOKIE WAIT       - We have seen an INIT chunk in the original direction, or also 
106                     an INIT_ACK chunk in the reply direction.
107 COOKIE ECHOED     - We have seen a COOKIE_ECHO chunk in the original direction.
108 ESTABLISHED       - We have seen a COOKIE_ACK in the reply direction.
109 SHUTDOWN_SENT     - We have seen a SHUTDOWN chunk in the original direction.
110 SHUTDOWN_RECD     - We have seen a SHUTDOWN chunk in the reply directoin.
111 SHUTDOWN_ACK_SENT - We have seen a SHUTDOWN_ACK chunk in the direction opposite
112                     to that of the SHUTDOWN chunk.
113 CLOSED            - We have seen a SHUTDOWN_COMPLETE chunk in the direction of 
114                     the SHUTDOWN chunk. Connection is closed.
115 */
116
117 /* TODO
118  - I have assumed that the first INIT is in the original direction. 
119  This messes things when an INIT comes in the reply direction in CLOSED
120  state.
121  - Check the error type in the reply dir before transitioning from 
122 cookie echoed to closed.
123  - Sec 5.2.4 of RFC 2960
124  - Multi Homing support.
125 */
126
127 /* SCTP conntrack state transitions */
128 static enum sctp_conntrack sctp_conntracks[2][9][SCTP_CONNTRACK_MAX] = {
129         {
130 /*      ORIGINAL        */
131 /*                  sNO, sCL, sCW, sCE, sES, sSS, sSR, sSA */
132 /* init         */ {sCW, sCW, sCW, sCE, sES, sSS, sSR, sSA},
133 /* init_ack     */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA},
134 /* abort        */ {sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL},
135 /* shutdown     */ {sCL, sCL, sCW, sCE, sSS, sSS, sSR, sSA},
136 /* shutdown_ack */ {sSA, sCL, sCW, sCE, sES, sSA, sSA, sSA},
137 /* error        */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA},/* Cant have Stale cookie*/
138 /* cookie_echo  */ {sCL, sCL, sCE, sCE, sES, sSS, sSR, sSA},/* 5.2.4 - Big TODO */
139 /* cookie_ack   */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA},/* Cant come in orig dir */
140 /* shutdown_comp*/ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sCL}
141         },
142         {
143 /*      REPLY   */
144 /*                  sNO, sCL, sCW, sCE, sES, sSS, sSR, sSA */
145 /* init         */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA},/* INIT in sCL Big TODO */
146 /* init_ack     */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA},
147 /* abort        */ {sIV, sCL, sCL, sCL, sCL, sCL, sCL, sCL},
148 /* shutdown     */ {sIV, sCL, sCW, sCE, sSR, sSS, sSR, sSA},
149 /* shutdown_ack */ {sIV, sCL, sCW, sCE, sES, sSA, sSA, sSA},
150 /* error        */ {sIV, sCL, sCW, sCL, sES, sSS, sSR, sSA},
151 /* cookie_echo  */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA},/* Cant come in reply dir */
152 /* cookie_ack   */ {sIV, sCL, sCW, sES, sES, sSS, sSR, sSA},
153 /* shutdown_comp*/ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sCL}
154         }
155 };
156
157 static int sctp_pkt_to_tuple(const struct sk_buff *skb,
158                              unsigned int dataoff,
159                              struct nf_conntrack_tuple *tuple)
160 {
161         sctp_sctphdr_t _hdr, *hp;
162
163         DEBUGP(__FUNCTION__);
164         DEBUGP("\n");
165
166         /* Actually only need first 8 bytes. */
167         hp = skb_header_pointer(skb, dataoff, 8, &_hdr);
168         if (hp == NULL)
169                 return 0;
170
171         tuple->src.u.sctp.port = hp->source;
172         tuple->dst.u.sctp.port = hp->dest;
173         return 1;
174 }
175
176 static int sctp_invert_tuple(struct nf_conntrack_tuple *tuple,
177                              const struct nf_conntrack_tuple *orig)
178 {
179         DEBUGP(__FUNCTION__);
180         DEBUGP("\n");
181
182         tuple->src.u.sctp.port = orig->dst.u.sctp.port;
183         tuple->dst.u.sctp.port = orig->src.u.sctp.port;
184         return 1;
185 }
186
187 /* Print out the per-protocol part of the tuple. */
188 static int sctp_print_tuple(struct seq_file *s,
189                             const struct nf_conntrack_tuple *tuple)
190 {
191         DEBUGP(__FUNCTION__);
192         DEBUGP("\n");
193
194         return seq_printf(s, "sport=%hu dport=%hu ",
195                           ntohs(tuple->src.u.sctp.port),
196                           ntohs(tuple->dst.u.sctp.port));
197 }
198
199 /* Print out the private part of the conntrack. */
200 static int sctp_print_conntrack(struct seq_file *s,
201                                 const struct nf_conn *conntrack)
202 {
203         enum sctp_conntrack state;
204
205         DEBUGP(__FUNCTION__);
206         DEBUGP("\n");
207
208         read_lock_bh(&sctp_lock);
209         state = conntrack->proto.sctp.state;
210         read_unlock_bh(&sctp_lock);
211
212         return seq_printf(s, "%s ", sctp_conntrack_names[state]);
213 }
214
215 #define for_each_sctp_chunk(skb, sch, _sch, offset, dataoff, count)     \
216 for (offset = dataoff + sizeof(sctp_sctphdr_t), count = 0;              \
217         offset < skb->len &&                                            \
218         (sch = skb_header_pointer(skb, offset, sizeof(_sch), &_sch));   \
219         offset += (htons(sch->length) + 3) & ~3, count++)
220
221 /* Some validity checks to make sure the chunks are fine */
222 static int do_basic_checks(struct nf_conn *conntrack,
223                            const struct sk_buff *skb,
224                            unsigned int dataoff,
225                            char *map)
226 {
227         u_int32_t offset, count;
228         sctp_chunkhdr_t _sch, *sch;
229         int flag;
230
231         DEBUGP(__FUNCTION__);
232         DEBUGP("\n");
233
234         flag = 0;
235
236         for_each_sctp_chunk (skb, sch, _sch, offset, dataoff, count) {
237                 DEBUGP("Chunk Num: %d  Type: %d\n", count, sch->type);
238
239                 if (sch->type == SCTP_CID_INIT 
240                         || sch->type == SCTP_CID_INIT_ACK
241                         || sch->type == SCTP_CID_SHUTDOWN_COMPLETE) {
242                         flag = 1;
243                 }
244
245                 /*
246                  * Cookie Ack/Echo chunks not the first OR
247                  * Init / Init Ack / Shutdown compl chunks not the only chunks
248                  * OR zero-length.
249                  */
250                 if (((sch->type == SCTP_CID_COOKIE_ACK
251                         || sch->type == SCTP_CID_COOKIE_ECHO
252                         || flag)
253                       && count !=0) || !sch->length) {
254                         DEBUGP("Basic checks failed\n");
255                         return 1;
256                 }
257
258                 if (map) {
259                         set_bit(sch->type, (void *)map);
260                 }
261         }
262
263         DEBUGP("Basic checks passed\n");
264         return count == 0;
265 }
266
267 static int new_state(enum ip_conntrack_dir dir,
268                      enum sctp_conntrack cur_state,
269                      int chunk_type)
270 {
271         int i;
272
273         DEBUGP(__FUNCTION__);
274         DEBUGP("\n");
275
276         DEBUGP("Chunk type: %d\n", chunk_type);
277
278         switch (chunk_type) {
279                 case SCTP_CID_INIT: 
280                         DEBUGP("SCTP_CID_INIT\n");
281                         i = 0; break;
282                 case SCTP_CID_INIT_ACK: 
283                         DEBUGP("SCTP_CID_INIT_ACK\n");
284                         i = 1; break;
285                 case SCTP_CID_ABORT: 
286                         DEBUGP("SCTP_CID_ABORT\n");
287                         i = 2; break;
288                 case SCTP_CID_SHUTDOWN: 
289                         DEBUGP("SCTP_CID_SHUTDOWN\n");
290                         i = 3; break;
291                 case SCTP_CID_SHUTDOWN_ACK: 
292                         DEBUGP("SCTP_CID_SHUTDOWN_ACK\n");
293                         i = 4; break;
294                 case SCTP_CID_ERROR: 
295                         DEBUGP("SCTP_CID_ERROR\n");
296                         i = 5; break;
297                 case SCTP_CID_COOKIE_ECHO: 
298                         DEBUGP("SCTP_CID_COOKIE_ECHO\n");
299                         i = 6; break;
300                 case SCTP_CID_COOKIE_ACK: 
301                         DEBUGP("SCTP_CID_COOKIE_ACK\n");
302                         i = 7; break;
303                 case SCTP_CID_SHUTDOWN_COMPLETE: 
304                         DEBUGP("SCTP_CID_SHUTDOWN_COMPLETE\n");
305                         i = 8; break;
306                 default:
307                         /* Other chunks like DATA, SACK, HEARTBEAT and
308                         its ACK do not cause a change in state */
309                         DEBUGP("Unknown chunk type, Will stay in %s\n", 
310                                                 sctp_conntrack_names[cur_state]);
311                         return cur_state;
312         }
313
314         DEBUGP("dir: %d   cur_state: %s  chunk_type: %d  new_state: %s\n", 
315                         dir, sctp_conntrack_names[cur_state], chunk_type,
316                         sctp_conntrack_names[sctp_conntracks[dir][i][cur_state]]);
317
318         return sctp_conntracks[dir][i][cur_state];
319 }
320
321 /* Returns verdict for packet, or -1 for invalid. */
322 static int sctp_packet(struct nf_conn *conntrack,
323                        const struct sk_buff *skb,
324                        unsigned int dataoff,
325                        enum ip_conntrack_info ctinfo,
326                        int pf,
327                        unsigned int hooknum)
328 {
329         enum sctp_conntrack newconntrack, oldsctpstate;
330         sctp_sctphdr_t _sctph, *sh;
331         sctp_chunkhdr_t _sch, *sch;
332         u_int32_t offset, count;
333         char map[256 / sizeof (char)] = {0};
334
335         DEBUGP(__FUNCTION__);
336         DEBUGP("\n");
337
338         sh = skb_header_pointer(skb, dataoff, sizeof(_sctph), &_sctph);
339         if (sh == NULL)
340                 return -1;
341
342         if (do_basic_checks(conntrack, skb, dataoff, map) != 0)
343                 return -1;
344
345         /* Check the verification tag (Sec 8.5) */
346         if (!test_bit(SCTP_CID_INIT, (void *)map)
347                 && !test_bit(SCTP_CID_SHUTDOWN_COMPLETE, (void *)map)
348                 && !test_bit(SCTP_CID_COOKIE_ECHO, (void *)map)
349                 && !test_bit(SCTP_CID_ABORT, (void *)map)
350                 && !test_bit(SCTP_CID_SHUTDOWN_ACK, (void *)map)
351                 && (sh->vtag != conntrack->proto.sctp.vtag[CTINFO2DIR(ctinfo)])) {
352                 DEBUGP("Verification tag check failed\n");
353                 return -1;
354         }
355
356         oldsctpstate = newconntrack = SCTP_CONNTRACK_MAX;
357         for_each_sctp_chunk (skb, sch, _sch, offset, dataoff, count) {
358                 write_lock_bh(&sctp_lock);
359
360                 /* Special cases of Verification tag check (Sec 8.5.1) */
361                 if (sch->type == SCTP_CID_INIT) {
362                         /* Sec 8.5.1 (A) */
363                         if (sh->vtag != 0) {
364                                 write_unlock_bh(&sctp_lock);
365                                 return -1;
366                         }
367                 } else if (sch->type == SCTP_CID_ABORT) {
368                         /* Sec 8.5.1 (B) */
369                         if (!(sh->vtag == conntrack->proto.sctp.vtag[CTINFO2DIR(ctinfo)])
370                                 && !(sh->vtag == conntrack->proto.sctp.vtag
371                                                         [1 - CTINFO2DIR(ctinfo)])) {
372                                 write_unlock_bh(&sctp_lock);
373                                 return -1;
374                         }
375                 } else if (sch->type == SCTP_CID_SHUTDOWN_COMPLETE) {
376                         /* Sec 8.5.1 (C) */
377                         if (!(sh->vtag == conntrack->proto.sctp.vtag[CTINFO2DIR(ctinfo)])
378                                 && !(sh->vtag == conntrack->proto.sctp.vtag
379                                                         [1 - CTINFO2DIR(ctinfo)] 
380                                         && (sch->flags & 1))) {
381                                 write_unlock_bh(&sctp_lock);
382                                 return -1;
383                         }
384                 } else if (sch->type == SCTP_CID_COOKIE_ECHO) {
385                         /* Sec 8.5.1 (D) */
386                         if (!(sh->vtag == conntrack->proto.sctp.vtag[CTINFO2DIR(ctinfo)])) {
387                                 write_unlock_bh(&sctp_lock);
388                                 return -1;
389                         }
390                 }
391
392                 oldsctpstate = conntrack->proto.sctp.state;
393                 newconntrack = new_state(CTINFO2DIR(ctinfo), oldsctpstate, sch->type);
394
395                 /* Invalid */
396                 if (newconntrack == SCTP_CONNTRACK_MAX) {
397                         DEBUGP("nf_conntrack_sctp: Invalid dir=%i ctype=%u conntrack=%u\n",
398                                CTINFO2DIR(ctinfo), sch->type, oldsctpstate);
399                         write_unlock_bh(&sctp_lock);
400                         return -1;
401                 }
402
403                 /* If it is an INIT or an INIT ACK note down the vtag */
404                 if (sch->type == SCTP_CID_INIT 
405                         || sch->type == SCTP_CID_INIT_ACK) {
406                         sctp_inithdr_t _inithdr, *ih;
407
408                         ih = skb_header_pointer(skb, offset + sizeof(sctp_chunkhdr_t),
409                                                 sizeof(_inithdr), &_inithdr);
410                         if (ih == NULL) {
411                                         write_unlock_bh(&sctp_lock);
412                                         return -1;
413                         }
414                         DEBUGP("Setting vtag %x for dir %d\n", 
415                                         ih->init_tag, !CTINFO2DIR(ctinfo));
416                         conntrack->proto.sctp.vtag[!CTINFO2DIR(ctinfo)] = ih->init_tag;
417                 }
418
419                 conntrack->proto.sctp.state = newconntrack;
420                 if (oldsctpstate != newconntrack)
421                         nf_conntrack_event_cache(IPCT_PROTOINFO, skb);
422                 write_unlock_bh(&sctp_lock);
423         }
424
425         nf_ct_refresh_acct(conntrack, ctinfo, skb, *sctp_timeouts[newconntrack]);
426
427         if (oldsctpstate == SCTP_CONNTRACK_COOKIE_ECHOED
428                 && CTINFO2DIR(ctinfo) == IP_CT_DIR_REPLY
429                 && newconntrack == SCTP_CONNTRACK_ESTABLISHED) {
430                 DEBUGP("Setting assured bit\n");
431                 set_bit(IPS_ASSURED_BIT, &conntrack->status);
432                 nf_conntrack_event_cache(IPCT_STATUS, skb);
433         }
434
435         return NF_ACCEPT;
436 }
437
438 /* Called when a new connection for this protocol found. */
439 static int sctp_new(struct nf_conn *conntrack, const struct sk_buff *skb,
440                     unsigned int dataoff)
441 {
442         enum sctp_conntrack newconntrack;
443         sctp_sctphdr_t _sctph, *sh;
444         sctp_chunkhdr_t _sch, *sch;
445         u_int32_t offset, count;
446         char map[256 / sizeof (char)] = {0};
447
448         DEBUGP(__FUNCTION__);
449         DEBUGP("\n");
450
451         sh = skb_header_pointer(skb, dataoff, sizeof(_sctph), &_sctph);
452         if (sh == NULL)
453                 return 0;
454
455         if (do_basic_checks(conntrack, skb, dataoff, map) != 0)
456                 return 0;
457
458         /* If an OOTB packet has any of these chunks discard (Sec 8.4) */
459         if ((test_bit (SCTP_CID_ABORT, (void *)map))
460                 || (test_bit (SCTP_CID_SHUTDOWN_COMPLETE, (void *)map))
461                 || (test_bit (SCTP_CID_COOKIE_ACK, (void *)map))) {
462                 return 0;
463         }
464
465         newconntrack = SCTP_CONNTRACK_MAX;
466         for_each_sctp_chunk (skb, sch, _sch, offset, dataoff, count) {
467                 /* Don't need lock here: this conntrack not in circulation yet */
468                 newconntrack = new_state(IP_CT_DIR_ORIGINAL, 
469                                          SCTP_CONNTRACK_NONE, sch->type);
470
471                 /* Invalid: delete conntrack */
472                 if (newconntrack == SCTP_CONNTRACK_MAX) {
473                         DEBUGP("nf_conntrack_sctp: invalid new deleting.\n");
474                         return 0;
475                 }
476
477                 /* Copy the vtag into the state info */
478                 if (sch->type == SCTP_CID_INIT) {
479                         if (sh->vtag == 0) {
480                                 sctp_inithdr_t _inithdr, *ih;
481
482                                 ih = skb_header_pointer(skb, offset + sizeof(sctp_chunkhdr_t),
483                                                         sizeof(_inithdr), &_inithdr);
484                                 if (ih == NULL)
485                                         return 0;
486
487                                 DEBUGP("Setting vtag %x for new conn\n", 
488                                         ih->init_tag);
489
490                                 conntrack->proto.sctp.vtag[IP_CT_DIR_REPLY] = 
491                                                                 ih->init_tag;
492                         } else {
493                                 /* Sec 8.5.1 (A) */
494                                 return 0;
495                         }
496                 }
497                 /* If it is a shutdown ack OOTB packet, we expect a return
498                    shutdown complete, otherwise an ABORT Sec 8.4 (5) and (8) */
499                 else {
500                         DEBUGP("Setting vtag %x for new conn OOTB\n", 
501                                 sh->vtag);
502                         conntrack->proto.sctp.vtag[IP_CT_DIR_REPLY] = sh->vtag;
503                 }
504
505                 conntrack->proto.sctp.state = newconntrack;
506         }
507
508         return 1;
509 }
510
511 struct nf_conntrack_protocol nf_conntrack_protocol_sctp4 = { 
512         .l3proto         = PF_INET,
513         .proto           = IPPROTO_SCTP, 
514         .name            = "sctp",
515         .pkt_to_tuple    = sctp_pkt_to_tuple, 
516         .invert_tuple    = sctp_invert_tuple, 
517         .print_tuple     = sctp_print_tuple, 
518         .print_conntrack = sctp_print_conntrack,
519         .packet          = sctp_packet, 
520         .new             = sctp_new, 
521         .destroy         = NULL, 
522         .me              = THIS_MODULE 
523 };
524
525 struct nf_conntrack_protocol nf_conntrack_protocol_sctp6 = { 
526         .l3proto         = PF_INET6,
527         .proto           = IPPROTO_SCTP, 
528         .name            = "sctp",
529         .pkt_to_tuple    = sctp_pkt_to_tuple, 
530         .invert_tuple    = sctp_invert_tuple, 
531         .print_tuple     = sctp_print_tuple, 
532         .print_conntrack = sctp_print_conntrack,
533         .packet          = sctp_packet, 
534         .new             = sctp_new, 
535         .destroy         = NULL, 
536         .me              = THIS_MODULE 
537 };
538
539 #ifdef CONFIG_SYSCTL
540 static ctl_table nf_ct_sysctl_table[] = {
541         {
542                 .ctl_name       = NET_NF_CONNTRACK_SCTP_TIMEOUT_CLOSED,
543                 .procname       = "nf_conntrack_sctp_timeout_closed",
544                 .data           = &nf_ct_sctp_timeout_closed,
545                 .maxlen         = sizeof(unsigned int),
546                 .mode           = 0644,
547                 .proc_handler   = &proc_dointvec_jiffies,
548         },
549         {
550                 .ctl_name       = NET_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_WAIT,
551                 .procname       = "nf_conntrack_sctp_timeout_cookie_wait",
552                 .data           = &nf_ct_sctp_timeout_cookie_wait,
553                 .maxlen         = sizeof(unsigned int),
554                 .mode           = 0644,
555                 .proc_handler   = &proc_dointvec_jiffies,
556         },
557         {
558                 .ctl_name       = NET_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_ECHOED,
559                 .procname       = "nf_conntrack_sctp_timeout_cookie_echoed",
560                 .data           = &nf_ct_sctp_timeout_cookie_echoed,
561                 .maxlen         = sizeof(unsigned int),
562                 .mode           = 0644,
563                 .proc_handler   = &proc_dointvec_jiffies,
564         },
565         {
566                 .ctl_name       = NET_NF_CONNTRACK_SCTP_TIMEOUT_ESTABLISHED,
567                 .procname       = "nf_conntrack_sctp_timeout_established",
568                 .data           = &nf_ct_sctp_timeout_established,
569                 .maxlen         = sizeof(unsigned int),
570                 .mode           = 0644,
571                 .proc_handler   = &proc_dointvec_jiffies,
572         },
573         {
574                 .ctl_name       = NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_SENT,
575                 .procname       = "nf_conntrack_sctp_timeout_shutdown_sent",
576                 .data           = &nf_ct_sctp_timeout_shutdown_sent,
577                 .maxlen         = sizeof(unsigned int),
578                 .mode           = 0644,
579                 .proc_handler   = &proc_dointvec_jiffies,
580         },
581         {
582                 .ctl_name       = NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_RECD,
583                 .procname       = "nf_conntrack_sctp_timeout_shutdown_recd",
584                 .data           = &nf_ct_sctp_timeout_shutdown_recd,
585                 .maxlen         = sizeof(unsigned int),
586                 .mode           = 0644,
587                 .proc_handler   = &proc_dointvec_jiffies,
588         },
589         {
590                 .ctl_name       = NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_ACK_SENT,
591                 .procname       = "nf_conntrack_sctp_timeout_shutdown_ack_sent",
592                 .data           = &nf_ct_sctp_timeout_shutdown_ack_sent,
593                 .maxlen         = sizeof(unsigned int),
594                 .mode           = 0644,
595                 .proc_handler   = &proc_dointvec_jiffies,
596         },
597         { .ctl_name = 0 }
598 };
599
600 static ctl_table nf_ct_netfilter_table[] = {
601         {
602                 .ctl_name       = NET_NETFILTER,
603                 .procname       = "netfilter",
604                 .mode           = 0555,
605                 .child          = nf_ct_sysctl_table,
606         },
607         { .ctl_name = 0 }
608 };
609
610 static ctl_table nf_ct_net_table[] = {
611         {
612                 .ctl_name       = CTL_NET,
613                 .procname       = "net",
614                 .mode           = 0555, 
615                 .child          = nf_ct_netfilter_table,
616         },
617         { .ctl_name = 0 }
618 };
619
620 static struct ctl_table_header *nf_ct_sysctl_header;
621 #endif
622
623 int __init nf_conntrack_proto_sctp_init(void)
624 {
625         int ret;
626
627         ret = nf_conntrack_protocol_register(&nf_conntrack_protocol_sctp4);
628         if (ret) {
629                 printk("nf_conntrack_proto_sctp4: protocol register failed\n");
630                 goto out;
631         }
632         ret = nf_conntrack_protocol_register(&nf_conntrack_protocol_sctp6);
633         if (ret) {
634                 printk("nf_conntrack_proto_sctp6: protocol register failed\n");
635                 goto cleanup_sctp4;
636         }
637
638 #ifdef CONFIG_SYSCTL
639         nf_ct_sysctl_header = register_sysctl_table(nf_ct_net_table, 0);
640         if (nf_ct_sysctl_header == NULL) {
641                 printk("nf_conntrack_proto_sctp: can't register to sysctl.\n");
642                 goto cleanup;
643         }
644 #endif
645
646         return ret;
647
648 #ifdef CONFIG_SYSCTL
649  cleanup:
650         nf_conntrack_protocol_unregister(&nf_conntrack_protocol_sctp6);
651 #endif
652  cleanup_sctp4:
653         nf_conntrack_protocol_unregister(&nf_conntrack_protocol_sctp4);
654  out:
655         DEBUGP("SCTP conntrack module loading %s\n", 
656                                         ret ? "failed": "succeeded");
657         return ret;
658 }
659
660 void __exit nf_conntrack_proto_sctp_fini(void)
661 {
662         nf_conntrack_protocol_unregister(&nf_conntrack_protocol_sctp6);
663         nf_conntrack_protocol_unregister(&nf_conntrack_protocol_sctp4);
664 #ifdef CONFIG_SYSCTL
665         unregister_sysctl_table(nf_ct_sysctl_header);
666 #endif
667         DEBUGP("SCTP conntrack module unloaded\n");
668 }
669
670 module_init(nf_conntrack_proto_sctp_init);
671 module_exit(nf_conntrack_proto_sctp_fini);
672
673 MODULE_LICENSE("GPL");
674 MODULE_AUTHOR("Kiran Kumar Immidi");
675 MODULE_DESCRIPTION("Netfilter connection tracking protocol helper for SCTP");