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