2 * H.323 connection tracking helper
4 * Copyright (c) 2006 Jing Min Zhao <zhaojingmin@users.sourceforge.net>
6 * This source code is licensed under General Public License version 2.
8 * Based on the 'brute force' H.323 connection tracking module by
9 * Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
11 * For more information, please see http://nath323.sourceforge.net/
14 #include <linux/config.h>
15 #include <linux/module.h>
16 #include <linux/netfilter.h>
19 #include <linux/netfilter_ipv4/ip_conntrack.h>
20 #include <linux/netfilter_ipv4/ip_conntrack_core.h>
21 #include <linux/netfilter_ipv4/ip_conntrack_helper.h>
22 #include <linux/netfilter_ipv4/ip_conntrack_tuple.h>
23 #include <linux/netfilter_ipv4/ip_conntrack_h323.h>
24 #include <linux/moduleparam.h>
29 #define DEBUGP(format, args...)
33 static unsigned int default_rrq_ttl = 300;
34 module_param(default_rrq_ttl, uint, 0600);
35 MODULE_PARM_DESC(default_rrq_ttl, "use this TTL if it's missing in RRQ");
37 static int gkrouted_only = 1;
38 module_param(gkrouted_only, int, 0600);
39 MODULE_PARM_DESC(gkrouted_only, "only accept calls from gatekeeper");
42 int (*set_h245_addr_hook) (struct sk_buff ** pskb,
43 unsigned char **data, int dataoff,
44 H245_TransportAddress * addr,
45 u_int32_t ip, u_int16_t port);
46 int (*set_h225_addr_hook) (struct sk_buff ** pskb,
47 unsigned char **data, int dataoff,
48 TransportAddress * addr,
49 u_int32_t ip, u_int16_t port);
50 int (*set_sig_addr_hook) (struct sk_buff ** pskb,
51 struct ip_conntrack * ct,
52 enum ip_conntrack_info ctinfo,
54 TransportAddress * addr, int count);
55 int (*set_ras_addr_hook) (struct sk_buff ** pskb,
56 struct ip_conntrack * ct,
57 enum ip_conntrack_info ctinfo,
59 TransportAddress * addr, int count);
60 int (*nat_rtp_rtcp_hook) (struct sk_buff ** pskb,
61 struct ip_conntrack * ct,
62 enum ip_conntrack_info ctinfo,
63 unsigned char **data, int dataoff,
64 H245_TransportAddress * addr,
65 u_int16_t port, u_int16_t rtp_port,
66 struct ip_conntrack_expect * rtp_exp,
67 struct ip_conntrack_expect * rtcp_exp);
68 int (*nat_t120_hook) (struct sk_buff ** pskb,
69 struct ip_conntrack * ct,
70 enum ip_conntrack_info ctinfo,
71 unsigned char **data, int dataoff,
72 H245_TransportAddress * addr, u_int16_t port,
73 struct ip_conntrack_expect * exp);
74 int (*nat_h245_hook) (struct sk_buff ** pskb,
75 struct ip_conntrack * ct,
76 enum ip_conntrack_info ctinfo,
77 unsigned char **data, int dataoff,
78 TransportAddress * addr, u_int16_t port,
79 struct ip_conntrack_expect * exp);
80 int (*nat_q931_hook) (struct sk_buff ** pskb,
81 struct ip_conntrack * ct,
82 enum ip_conntrack_info ctinfo,
83 unsigned char **data, TransportAddress * addr, int idx,
84 u_int16_t port, struct ip_conntrack_expect * exp);
87 static DEFINE_SPINLOCK(ip_h323_lock);
88 static char *h323_buffer;
90 /****************************************************************************/
91 static int get_tpkt_data(struct sk_buff **pskb, struct ip_conntrack *ct,
92 enum ip_conntrack_info ctinfo,
93 unsigned char **data, int *datalen, int *dataoff)
95 struct ip_ct_h323_master *info = &ct->help.ct_h323_info;
96 int dir = CTINFO2DIR(ctinfo);
97 struct tcphdr _tcph, *th;
105 th = skb_header_pointer(*pskb, (*pskb)->nh.iph->ihl * 4,
106 sizeof(_tcph), &_tcph);
110 /* Get TCP data offset */
111 tcpdataoff = (*pskb)->nh.iph->ihl * 4 + th->doff * 4;
113 /* Get TCP data length */
114 tcpdatalen = (*pskb)->len - tcpdataoff;
115 if (tcpdatalen <= 0) /* No TCP data */
118 if (*data == NULL) { /* first TPKT */
119 /* Get first TPKT pointer */
120 tpkt = skb_header_pointer(*pskb, tcpdataoff, tcpdatalen,
122 BUG_ON(tpkt == NULL);
124 /* Validate TPKT identifier */
125 if (tcpdatalen < 4 || tpkt[0] != 0x03 || tpkt[1] != 0) {
126 /* Netmeeting sends TPKT header and data separately */
127 if (info->tpkt_len[dir] > 0) {
128 DEBUGP("ip_ct_h323: previous packet "
129 "indicated separate TPKT data of %hu "
130 "bytes\n", info->tpkt_len[dir]);
131 if (info->tpkt_len[dir] <= tcpdatalen) {
132 /* Yes, there was a TPKT header
135 *datalen = info->tpkt_len[dir];
140 /* Fragmented TPKT */
142 printk("ip_ct_h323: "
143 "fragmented TPKT\n");
147 /* It is not even a TPKT */
151 } else { /* Next TPKT */
152 tpktoff = *dataoff + *datalen;
153 tcpdatalen -= tpktoff;
154 if (tcpdatalen <= 4) /* No more TPKT */
156 tpkt = *data + *datalen;
158 /* Validate TPKT identifier */
159 if (tpkt[0] != 0x03 || tpkt[1] != 0)
163 /* Validate TPKT length */
164 tpktlen = tpkt[2] * 256 + tpkt[3];
165 if (tpktlen > tcpdatalen) {
166 if (tcpdatalen == 4) { /* Separate TPKT header */
167 /* Netmeeting sends TPKT header and data separately */
168 DEBUGP("ip_ct_h323: separate TPKT header indicates "
169 "there will be TPKT data of %hu bytes\n",
171 info->tpkt_len[dir] = tpktlen - 4;
176 printk("ip_ct_h323: incomplete TPKT (fragmented?)\n");
180 /* This is the encapsulated data */
182 *datalen = tpktlen - 4;
183 *dataoff = tpktoff + 4;
186 /* Clear TPKT length */
187 info->tpkt_len[dir] = 0;
191 info->tpkt_len[dir] = 0;
195 /****************************************************************************/
196 static int get_h245_addr(unsigned char *data, H245_TransportAddress * addr,
197 u_int32_t * ip, u_int16_t * port)
201 if (addr->choice != eH245_TransportAddress_unicastAddress ||
202 addr->unicastAddress.choice != eUnicastAddress_iPAddress)
205 p = data + addr->unicastAddress.iPAddress.network;
206 *ip = htonl((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | (p[3]));
207 *port = (p[4] << 8) | (p[5]);
212 /****************************************************************************/
213 static int expect_rtp_rtcp(struct sk_buff **pskb, struct ip_conntrack *ct,
214 enum ip_conntrack_info ctinfo,
215 unsigned char **data, int dataoff,
216 H245_TransportAddress * addr)
218 int dir = CTINFO2DIR(ctinfo);
223 struct ip_conntrack_expect *rtp_exp;
224 struct ip_conntrack_expect *rtcp_exp;
226 /* Read RTP or RTCP address */
227 if (!get_h245_addr(*data, addr, &ip, &port) ||
228 ip != ct->tuplehash[dir].tuple.src.ip || port == 0)
231 /* RTP port is even */
232 rtp_port = port & (~1);
234 /* Create expect for RTP */
235 if ((rtp_exp = ip_conntrack_expect_alloc(ct)) == NULL)
237 rtp_exp->tuple.src.ip = ct->tuplehash[!dir].tuple.src.ip;
238 rtp_exp->tuple.src.u.udp.port = 0;
239 rtp_exp->tuple.dst.ip = ct->tuplehash[!dir].tuple.dst.ip;
240 rtp_exp->tuple.dst.u.udp.port = htons(rtp_port);
241 rtp_exp->tuple.dst.protonum = IPPROTO_UDP;
242 rtp_exp->mask.src.ip = 0xFFFFFFFF;
243 rtp_exp->mask.src.u.udp.port = 0;
244 rtp_exp->mask.dst.ip = 0xFFFFFFFF;
245 rtp_exp->mask.dst.u.udp.port = 0xFFFF;
246 rtp_exp->mask.dst.protonum = 0xFF;
249 /* Create expect for RTCP */
250 if ((rtcp_exp = ip_conntrack_expect_alloc(ct)) == NULL) {
251 ip_conntrack_expect_put(rtp_exp);
254 rtcp_exp->tuple.src.ip = ct->tuplehash[!dir].tuple.src.ip;
255 rtcp_exp->tuple.src.u.udp.port = 0;
256 rtcp_exp->tuple.dst.ip = ct->tuplehash[!dir].tuple.dst.ip;
257 rtcp_exp->tuple.dst.u.udp.port = htons(rtp_port + 1);
258 rtcp_exp->tuple.dst.protonum = IPPROTO_UDP;
259 rtcp_exp->mask.src.ip = 0xFFFFFFFF;
260 rtcp_exp->mask.src.u.udp.port = 0;
261 rtcp_exp->mask.dst.ip = 0xFFFFFFFF;
262 rtcp_exp->mask.dst.u.udp.port = 0xFFFF;
263 rtcp_exp->mask.dst.protonum = 0xFF;
266 if (ct->tuplehash[dir].tuple.src.ip !=
267 ct->tuplehash[!dir].tuple.dst.ip && nat_rtp_rtcp_hook) {
269 ret = nat_rtp_rtcp_hook(pskb, ct, ctinfo, data, dataoff,
270 addr, port, rtp_port, rtp_exp,
272 } else { /* Conntrack only */
273 rtp_exp->expectfn = NULL;
274 rtcp_exp->expectfn = NULL;
276 if (ip_conntrack_expect_related(rtp_exp) == 0) {
277 if (ip_conntrack_expect_related(rtcp_exp) == 0) {
278 DEBUGP("ip_ct_h323: expect RTP "
279 "%u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
280 NIPQUAD(rtp_exp->tuple.src.ip),
281 ntohs(rtp_exp->tuple.src.u.udp.port),
282 NIPQUAD(rtp_exp->tuple.dst.ip),
283 ntohs(rtp_exp->tuple.dst.u.udp.port));
284 DEBUGP("ip_ct_h323: expect RTCP "
285 "%u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
286 NIPQUAD(rtcp_exp->tuple.src.ip),
287 ntohs(rtcp_exp->tuple.src.u.udp.port),
288 NIPQUAD(rtcp_exp->tuple.dst.ip),
289 ntohs(rtcp_exp->tuple.dst.u.udp.port));
291 ip_conntrack_unexpect_related(rtp_exp);
298 ip_conntrack_expect_put(rtp_exp);
299 ip_conntrack_expect_put(rtcp_exp);
304 /****************************************************************************/
305 static int expect_t120(struct sk_buff **pskb,
306 struct ip_conntrack *ct,
307 enum ip_conntrack_info ctinfo,
308 unsigned char **data, int dataoff,
309 H245_TransportAddress * addr)
311 int dir = CTINFO2DIR(ctinfo);
315 struct ip_conntrack_expect *exp = NULL;
317 /* Read T.120 address */
318 if (!get_h245_addr(*data, addr, &ip, &port) ||
319 ip != ct->tuplehash[dir].tuple.src.ip || port == 0)
322 /* Create expect for T.120 connections */
323 if ((exp = ip_conntrack_expect_alloc(ct)) == NULL)
325 exp->tuple.src.ip = ct->tuplehash[!dir].tuple.src.ip;
326 exp->tuple.src.u.tcp.port = 0;
327 exp->tuple.dst.ip = ct->tuplehash[!dir].tuple.dst.ip;
328 exp->tuple.dst.u.tcp.port = htons(port);
329 exp->tuple.dst.protonum = IPPROTO_TCP;
330 exp->mask.src.ip = 0xFFFFFFFF;
331 exp->mask.src.u.tcp.port = 0;
332 exp->mask.dst.ip = 0xFFFFFFFF;
333 exp->mask.dst.u.tcp.port = 0xFFFF;
334 exp->mask.dst.protonum = 0xFF;
335 exp->flags = IP_CT_EXPECT_PERMANENT; /* Accept multiple channels */
337 if (ct->tuplehash[dir].tuple.src.ip !=
338 ct->tuplehash[!dir].tuple.dst.ip && nat_t120_hook) {
340 ret = nat_t120_hook(pskb, ct, ctinfo, data, dataoff, addr,
342 } else { /* Conntrack only */
343 exp->expectfn = NULL;
344 if (ip_conntrack_expect_related(exp) == 0) {
345 DEBUGP("ip_ct_h323: expect T.120 "
346 "%u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
347 NIPQUAD(exp->tuple.src.ip),
348 ntohs(exp->tuple.src.u.tcp.port),
349 NIPQUAD(exp->tuple.dst.ip),
350 ntohs(exp->tuple.dst.u.tcp.port));
355 ip_conntrack_expect_put(exp);
360 /****************************************************************************/
361 static int process_h245_channel(struct sk_buff **pskb,
362 struct ip_conntrack *ct,
363 enum ip_conntrack_info ctinfo,
364 unsigned char **data, int dataoff,
365 H2250LogicalChannelParameters * channel)
369 if (channel->options & eH2250LogicalChannelParameters_mediaChannel) {
371 ret = expect_rtp_rtcp(pskb, ct, ctinfo, data, dataoff,
372 &channel->mediaChannel);
378 options & eH2250LogicalChannelParameters_mediaControlChannel) {
380 ret = expect_rtp_rtcp(pskb, ct, ctinfo, data, dataoff,
381 &channel->mediaControlChannel);
389 /****************************************************************************/
390 static int process_olc(struct sk_buff **pskb, struct ip_conntrack *ct,
391 enum ip_conntrack_info ctinfo,
392 unsigned char **data, int dataoff,
393 OpenLogicalChannel * olc)
397 DEBUGP("ip_ct_h323: OpenLogicalChannel\n");
399 if (olc->forwardLogicalChannelParameters.multiplexParameters.choice ==
400 eOpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters_h2250LogicalChannelParameters)
402 ret = process_h245_channel(pskb, ct, ctinfo, data, dataoff,
404 forwardLogicalChannelParameters.
406 h2250LogicalChannelParameters);
412 eOpenLogicalChannel_reverseLogicalChannelParameters) &&
413 (olc->reverseLogicalChannelParameters.options &
414 eOpenLogicalChannel_reverseLogicalChannelParameters_multiplexParameters)
415 && (olc->reverseLogicalChannelParameters.multiplexParameters.
417 eOpenLogicalChannel_reverseLogicalChannelParameters_multiplexParameters_h2250LogicalChannelParameters))
420 process_h245_channel(pskb, ct, ctinfo, data, dataoff,
422 reverseLogicalChannelParameters.
424 h2250LogicalChannelParameters);
429 if ((olc->options & eOpenLogicalChannel_separateStack) &&
430 olc->forwardLogicalChannelParameters.dataType.choice ==
432 olc->forwardLogicalChannelParameters.dataType.data.application.
433 choice == eDataApplicationCapability_application_t120 &&
434 olc->forwardLogicalChannelParameters.dataType.data.application.
435 t120.choice == eDataProtocolCapability_separateLANStack &&
436 olc->separateStack.networkAddress.choice ==
437 eNetworkAccessParameters_networkAddress_localAreaAddress) {
438 ret = expect_t120(pskb, ct, ctinfo, data, dataoff,
439 &olc->separateStack.networkAddress.
448 /****************************************************************************/
449 static int process_olca(struct sk_buff **pskb, struct ip_conntrack *ct,
450 enum ip_conntrack_info ctinfo,
451 unsigned char **data, int dataoff,
452 OpenLogicalChannelAck * olca)
454 H2250LogicalChannelAckParameters *ack;
457 DEBUGP("ip_ct_h323: OpenLogicalChannelAck\n");
460 eOpenLogicalChannelAck_reverseLogicalChannelParameters) &&
461 (olca->reverseLogicalChannelParameters.options &
462 eOpenLogicalChannelAck_reverseLogicalChannelParameters_multiplexParameters)
463 && (olca->reverseLogicalChannelParameters.multiplexParameters.
465 eOpenLogicalChannelAck_reverseLogicalChannelParameters_multiplexParameters_h2250LogicalChannelParameters))
467 ret = process_h245_channel(pskb, ct, ctinfo, data, dataoff,
469 reverseLogicalChannelParameters.
471 h2250LogicalChannelParameters);
477 eOpenLogicalChannelAck_forwardMultiplexAckParameters) &&
478 (olca->forwardMultiplexAckParameters.choice ==
479 eOpenLogicalChannelAck_forwardMultiplexAckParameters_h2250LogicalChannelAckParameters))
481 ack = &olca->forwardMultiplexAckParameters.
482 h2250LogicalChannelAckParameters;
484 eH2250LogicalChannelAckParameters_mediaChannel) {
486 ret = expect_rtp_rtcp(pskb, ct, ctinfo, data, dataoff,
493 eH2250LogicalChannelAckParameters_mediaControlChannel) {
495 ret = expect_rtp_rtcp(pskb, ct, ctinfo, data, dataoff,
496 &ack->mediaControlChannel);
505 /****************************************************************************/
506 static int process_h245(struct sk_buff **pskb, struct ip_conntrack *ct,
507 enum ip_conntrack_info ctinfo,
508 unsigned char **data, int dataoff,
509 MultimediaSystemControlMessage * mscm)
511 switch (mscm->choice) {
512 case eMultimediaSystemControlMessage_request:
513 if (mscm->request.choice ==
514 eRequestMessage_openLogicalChannel) {
515 return process_olc(pskb, ct, ctinfo, data, dataoff,
516 &mscm->request.openLogicalChannel);
518 DEBUGP("ip_ct_h323: H.245 Request %d\n",
519 mscm->request.choice);
521 case eMultimediaSystemControlMessage_response:
522 if (mscm->response.choice ==
523 eResponseMessage_openLogicalChannelAck) {
524 return process_olca(pskb, ct, ctinfo, data, dataoff,
526 openLogicalChannelAck);
528 DEBUGP("ip_ct_h323: H.245 Response %d\n",
529 mscm->response.choice);
532 DEBUGP("ip_ct_h323: H.245 signal %d\n", mscm->choice);
539 /****************************************************************************/
540 static int h245_help(struct sk_buff **pskb, struct ip_conntrack *ct,
541 enum ip_conntrack_info ctinfo)
543 static MultimediaSystemControlMessage mscm;
544 unsigned char *data = NULL;
549 /* Until there's been traffic both ways, don't look in packets. */
550 if (ctinfo != IP_CT_ESTABLISHED
551 && ctinfo != IP_CT_ESTABLISHED + IP_CT_IS_REPLY) {
554 DEBUGP("ip_ct_h245: skblen = %u\n", (*pskb)->len);
556 spin_lock_bh(&ip_h323_lock);
558 /* Process each TPKT */
559 while (get_tpkt_data(pskb, ct, ctinfo, &data, &datalen, &dataoff)) {
560 DEBUGP("ip_ct_h245: TPKT %u.%u.%u.%u->%u.%u.%u.%u, len=%d\n",
561 NIPQUAD((*pskb)->nh.iph->saddr),
562 NIPQUAD((*pskb)->nh.iph->daddr), datalen);
564 /* Decode H.245 signal */
565 ret = DecodeMultimediaSystemControlMessage(data, datalen,
569 printk("ip_ct_h245: decoding error: %s\n",
570 ret == H323_ERROR_BOUND ?
571 "out of bound" : "out of range");
572 /* We don't drop when decoding error */
576 /* Process H.245 signal */
577 if (process_h245(pskb, ct, ctinfo, &data, dataoff, &mscm) < 0)
581 spin_unlock_bh(&ip_h323_lock);
585 spin_unlock_bh(&ip_h323_lock);
587 printk("ip_ct_h245: packet dropped\n");
591 /****************************************************************************/
592 static struct ip_conntrack_helper ip_conntrack_helper_h245 = {
595 .max_expected = H323_RTP_CHANNEL_MAX * 4 + 2 /* T.120 */ ,
597 .tuple = {.dst = {.protonum = IPPROTO_TCP}},
598 .mask = {.src = {.u = {0xFFFF}},
599 .dst = {.protonum = 0xFF}},
603 /****************************************************************************/
604 void ip_conntrack_h245_expect(struct ip_conntrack *new,
605 struct ip_conntrack_expect *this)
607 write_lock_bh(&ip_conntrack_lock);
608 new->helper = &ip_conntrack_helper_h245;
609 write_unlock_bh(&ip_conntrack_lock);
612 /****************************************************************************/
613 int get_h225_addr(unsigned char *data, TransportAddress * addr,
614 u_int32_t * ip, u_int16_t * port)
618 if (addr->choice != eTransportAddress_ipAddress)
621 p = data + addr->ipAddress.ip;
622 *ip = htonl((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | (p[3]));
623 *port = (p[4] << 8) | (p[5]);
628 /****************************************************************************/
629 static int expect_h245(struct sk_buff **pskb, struct ip_conntrack *ct,
630 enum ip_conntrack_info ctinfo,
631 unsigned char **data, int dataoff,
632 TransportAddress * addr)
634 int dir = CTINFO2DIR(ctinfo);
638 struct ip_conntrack_expect *exp = NULL;
640 /* Read h245Address */
641 if (!get_h225_addr(*data, addr, &ip, &port) ||
642 ip != ct->tuplehash[dir].tuple.src.ip || port == 0)
645 /* Create expect for h245 connection */
646 if ((exp = ip_conntrack_expect_alloc(ct)) == NULL)
648 exp->tuple.src.ip = ct->tuplehash[!dir].tuple.src.ip;
649 exp->tuple.src.u.tcp.port = 0;
650 exp->tuple.dst.ip = ct->tuplehash[!dir].tuple.dst.ip;
651 exp->tuple.dst.u.tcp.port = htons(port);
652 exp->tuple.dst.protonum = IPPROTO_TCP;
653 exp->mask.src.ip = 0xFFFFFFFF;
654 exp->mask.src.u.tcp.port = 0;
655 exp->mask.dst.ip = 0xFFFFFFFF;
656 exp->mask.dst.u.tcp.port = 0xFFFF;
657 exp->mask.dst.protonum = 0xFF;
660 if (ct->tuplehash[dir].tuple.src.ip !=
661 ct->tuplehash[!dir].tuple.dst.ip && nat_h245_hook) {
663 ret = nat_h245_hook(pskb, ct, ctinfo, data, dataoff, addr,
665 } else { /* Conntrack only */
666 exp->expectfn = ip_conntrack_h245_expect;
668 if (ip_conntrack_expect_related(exp) == 0) {
669 DEBUGP("ip_ct_q931: expect H.245 "
670 "%u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
671 NIPQUAD(exp->tuple.src.ip),
672 ntohs(exp->tuple.src.u.tcp.port),
673 NIPQUAD(exp->tuple.dst.ip),
674 ntohs(exp->tuple.dst.u.tcp.port));
679 ip_conntrack_expect_put(exp);
684 /****************************************************************************/
685 static int process_setup(struct sk_buff **pskb, struct ip_conntrack *ct,
686 enum ip_conntrack_info ctinfo,
687 unsigned char **data, int dataoff,
690 int dir = CTINFO2DIR(ctinfo);
696 DEBUGP("ip_ct_q931: Setup\n");
698 if (setup->options & eSetup_UUIE_h245Address) {
699 ret = expect_h245(pskb, ct, ctinfo, data, dataoff,
700 &setup->h245Address);
705 if ((setup->options & eSetup_UUIE_destCallSignalAddress) &&
706 (set_h225_addr_hook) &&
707 get_h225_addr(*data, &setup->destCallSignalAddress, &ip, &port) &&
708 ip != ct->tuplehash[!dir].tuple.src.ip) {
709 DEBUGP("ip_ct_q931: set destCallSignalAddress "
710 "%u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
712 NIPQUAD(ct->tuplehash[!dir].tuple.src.ip),
713 ntohs(ct->tuplehash[!dir].tuple.src.u.tcp.port));
714 ret = set_h225_addr_hook(pskb, data, dataoff,
715 &setup->destCallSignalAddress,
716 ct->tuplehash[!dir].tuple.src.ip,
717 ntohs(ct->tuplehash[!dir].tuple.src.
723 if ((setup->options & eSetup_UUIE_sourceCallSignalAddress) &&
724 (set_h225_addr_hook) &&
725 get_h225_addr(*data, &setup->sourceCallSignalAddress, &ip, &port)
726 && ip != ct->tuplehash[!dir].tuple.dst.ip) {
727 DEBUGP("ip_ct_q931: set sourceCallSignalAddress "
728 "%u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
730 NIPQUAD(ct->tuplehash[!dir].tuple.dst.ip),
731 ntohs(ct->tuplehash[!dir].tuple.dst.u.tcp.port));
732 ret = set_h225_addr_hook(pskb, data, dataoff,
733 &setup->sourceCallSignalAddress,
734 ct->tuplehash[!dir].tuple.dst.ip,
735 ntohs(ct->tuplehash[!dir].tuple.dst.
741 if (setup->options & eSetup_UUIE_fastStart) {
742 for (i = 0; i < setup->fastStart.count; i++) {
743 ret = process_olc(pskb, ct, ctinfo, data, dataoff,
744 &setup->fastStart.item[i]);
753 /****************************************************************************/
754 static int process_callproceeding(struct sk_buff **pskb,
755 struct ip_conntrack *ct,
756 enum ip_conntrack_info ctinfo,
757 unsigned char **data, int dataoff,
758 CallProceeding_UUIE * callproc)
763 DEBUGP("ip_ct_q931: CallProceeding\n");
765 if (callproc->options & eCallProceeding_UUIE_h245Address) {
766 ret = expect_h245(pskb, ct, ctinfo, data, dataoff,
767 &callproc->h245Address);
772 if (callproc->options & eCallProceeding_UUIE_fastStart) {
773 for (i = 0; i < callproc->fastStart.count; i++) {
774 ret = process_olc(pskb, ct, ctinfo, data, dataoff,
775 &callproc->fastStart.item[i]);
784 /****************************************************************************/
785 static int process_connect(struct sk_buff **pskb, struct ip_conntrack *ct,
786 enum ip_conntrack_info ctinfo,
787 unsigned char **data, int dataoff,
788 Connect_UUIE * connect)
793 DEBUGP("ip_ct_q931: Connect\n");
795 if (connect->options & eConnect_UUIE_h245Address) {
796 ret = expect_h245(pskb, ct, ctinfo, data, dataoff,
797 &connect->h245Address);
802 if (connect->options & eConnect_UUIE_fastStart) {
803 for (i = 0; i < connect->fastStart.count; i++) {
804 ret = process_olc(pskb, ct, ctinfo, data, dataoff,
805 &connect->fastStart.item[i]);
814 /****************************************************************************/
815 static int process_alerting(struct sk_buff **pskb, struct ip_conntrack *ct,
816 enum ip_conntrack_info ctinfo,
817 unsigned char **data, int dataoff,
818 Alerting_UUIE * alert)
823 DEBUGP("ip_ct_q931: Alerting\n");
825 if (alert->options & eAlerting_UUIE_h245Address) {
826 ret = expect_h245(pskb, ct, ctinfo, data, dataoff,
827 &alert->h245Address);
832 if (alert->options & eAlerting_UUIE_fastStart) {
833 for (i = 0; i < alert->fastStart.count; i++) {
834 ret = process_olc(pskb, ct, ctinfo, data, dataoff,
835 &alert->fastStart.item[i]);
844 /****************************************************************************/
845 static int process_information(struct sk_buff **pskb,
846 struct ip_conntrack *ct,
847 enum ip_conntrack_info ctinfo,
848 unsigned char **data, int dataoff,
849 Information_UUIE * info)
854 DEBUGP("ip_ct_q931: Information\n");
856 if (info->options & eInformation_UUIE_fastStart) {
857 for (i = 0; i < info->fastStart.count; i++) {
858 ret = process_olc(pskb, ct, ctinfo, data, dataoff,
859 &info->fastStart.item[i]);
868 /****************************************************************************/
869 static int process_facility(struct sk_buff **pskb, struct ip_conntrack *ct,
870 enum ip_conntrack_info ctinfo,
871 unsigned char **data, int dataoff,
872 Facility_UUIE * facility)
877 DEBUGP("ip_ct_q931: Facility\n");
879 if (facility->options & eFacility_UUIE_h245Address) {
880 ret = expect_h245(pskb, ct, ctinfo, data, dataoff,
881 &facility->h245Address);
886 if (facility->options & eFacility_UUIE_fastStart) {
887 for (i = 0; i < facility->fastStart.count; i++) {
888 ret = process_olc(pskb, ct, ctinfo, data, dataoff,
889 &facility->fastStart.item[i]);
898 /****************************************************************************/
899 static int process_progress(struct sk_buff **pskb, struct ip_conntrack *ct,
900 enum ip_conntrack_info ctinfo,
901 unsigned char **data, int dataoff,
902 Progress_UUIE * progress)
907 DEBUGP("ip_ct_q931: Progress\n");
909 if (progress->options & eProgress_UUIE_h245Address) {
910 ret = expect_h245(pskb, ct, ctinfo, data, dataoff,
911 &progress->h245Address);
916 if (progress->options & eProgress_UUIE_fastStart) {
917 for (i = 0; i < progress->fastStart.count; i++) {
918 ret = process_olc(pskb, ct, ctinfo, data, dataoff,
919 &progress->fastStart.item[i]);
928 /****************************************************************************/
929 static int process_q931(struct sk_buff **pskb, struct ip_conntrack *ct,
930 enum ip_conntrack_info ctinfo,
931 unsigned char **data, int dataoff, Q931 * q931)
933 H323_UU_PDU *pdu = &q931->UUIE.h323_uu_pdu;
937 switch (pdu->h323_message_body.choice) {
938 case eH323_UU_PDU_h323_message_body_setup:
939 ret = process_setup(pskb, ct, ctinfo, data, dataoff,
940 &pdu->h323_message_body.setup);
942 case eH323_UU_PDU_h323_message_body_callProceeding:
943 ret = process_callproceeding(pskb, ct, ctinfo, data, dataoff,
944 &pdu->h323_message_body.
947 case eH323_UU_PDU_h323_message_body_connect:
948 ret = process_connect(pskb, ct, ctinfo, data, dataoff,
949 &pdu->h323_message_body.connect);
951 case eH323_UU_PDU_h323_message_body_alerting:
952 ret = process_alerting(pskb, ct, ctinfo, data, dataoff,
953 &pdu->h323_message_body.alerting);
955 case eH323_UU_PDU_h323_message_body_information:
956 ret = process_information(pskb, ct, ctinfo, data, dataoff,
957 &pdu->h323_message_body.
960 case eH323_UU_PDU_h323_message_body_facility:
961 ret = process_facility(pskb, ct, ctinfo, data, dataoff,
962 &pdu->h323_message_body.facility);
964 case eH323_UU_PDU_h323_message_body_progress:
965 ret = process_progress(pskb, ct, ctinfo, data, dataoff,
966 &pdu->h323_message_body.progress);
969 DEBUGP("ip_ct_q931: Q.931 signal %d\n",
970 pdu->h323_message_body.choice);
977 if (pdu->options & eH323_UU_PDU_h245Control) {
978 for (i = 0; i < pdu->h245Control.count; i++) {
979 ret = process_h245(pskb, ct, ctinfo, data, dataoff,
980 &pdu->h245Control.item[i]);
989 /****************************************************************************/
990 static int q931_help(struct sk_buff **pskb, struct ip_conntrack *ct,
991 enum ip_conntrack_info ctinfo)
994 unsigned char *data = NULL;
999 /* Until there's been traffic both ways, don't look in packets. */
1000 if (ctinfo != IP_CT_ESTABLISHED
1001 && ctinfo != IP_CT_ESTABLISHED + IP_CT_IS_REPLY) {
1004 DEBUGP("ip_ct_q931: skblen = %u\n", (*pskb)->len);
1006 spin_lock_bh(&ip_h323_lock);
1008 /* Process each TPKT */
1009 while (get_tpkt_data(pskb, ct, ctinfo, &data, &datalen, &dataoff)) {
1010 DEBUGP("ip_ct_q931: TPKT %u.%u.%u.%u->%u.%u.%u.%u, len=%d\n",
1011 NIPQUAD((*pskb)->nh.iph->saddr),
1012 NIPQUAD((*pskb)->nh.iph->daddr), datalen);
1014 /* Decode Q.931 signal */
1015 ret = DecodeQ931(data, datalen, &q931);
1017 if (net_ratelimit())
1018 printk("ip_ct_q931: decoding error: %s\n",
1019 ret == H323_ERROR_BOUND ?
1020 "out of bound" : "out of range");
1021 /* We don't drop when decoding error */
1025 /* Process Q.931 signal */
1026 if (process_q931(pskb, ct, ctinfo, &data, dataoff, &q931) < 0)
1030 spin_unlock_bh(&ip_h323_lock);
1034 spin_unlock_bh(&ip_h323_lock);
1035 if (net_ratelimit())
1036 printk("ip_ct_q931: packet dropped\n");
1040 /****************************************************************************/
1041 static struct ip_conntrack_helper ip_conntrack_helper_q931 = {
1044 .max_expected = H323_RTP_CHANNEL_MAX * 4 + 4 /* T.120 and H.245 */ ,
1046 .tuple = {.src = {.u = {__constant_htons(Q931_PORT)}},
1047 .dst = {.protonum = IPPROTO_TCP}},
1048 .mask = {.src = {.u = {0xFFFF}},
1049 .dst = {.protonum = 0xFF}},
1053 /****************************************************************************/
1054 void ip_conntrack_q931_expect(struct ip_conntrack *new,
1055 struct ip_conntrack_expect *this)
1057 write_lock_bh(&ip_conntrack_lock);
1058 new->helper = &ip_conntrack_helper_q931;
1059 write_unlock_bh(&ip_conntrack_lock);
1062 /****************************************************************************/
1063 static unsigned char *get_udp_data(struct sk_buff **pskb, int *datalen)
1065 struct udphdr _uh, *uh;
1068 uh = skb_header_pointer(*pskb, (*pskb)->nh.iph->ihl * 4, sizeof(_uh),
1072 dataoff = (*pskb)->nh.iph->ihl * 4 + sizeof(_uh);
1073 if (dataoff >= (*pskb)->len)
1075 *datalen = (*pskb)->len - dataoff;
1076 return skb_header_pointer(*pskb, dataoff, *datalen, h323_buffer);
1079 /****************************************************************************/
1080 static struct ip_conntrack_expect *find_expect(struct ip_conntrack *ct,
1081 u_int32_t ip, u_int16_t port)
1083 struct ip_conntrack_expect *exp;
1084 struct ip_conntrack_tuple tuple;
1087 tuple.src.u.tcp.port = 0;
1089 tuple.dst.u.tcp.port = htons(port);
1090 tuple.dst.protonum = IPPROTO_TCP;
1092 exp = __ip_conntrack_expect_find(&tuple);
1093 if (exp->master == ct)
1098 /****************************************************************************/
1099 static int set_expect_timeout(struct ip_conntrack_expect *exp,
1102 if (!exp || !del_timer(&exp->timeout))
1105 exp->timeout.expires = jiffies + timeout * HZ;
1106 add_timer(&exp->timeout);
1111 /****************************************************************************/
1112 static int expect_q931(struct sk_buff **pskb, struct ip_conntrack *ct,
1113 enum ip_conntrack_info ctinfo,
1114 unsigned char **data,
1115 TransportAddress * addr, int count)
1117 struct ip_ct_h323_master *info = &ct->help.ct_h323_info;
1118 int dir = CTINFO2DIR(ctinfo);
1123 struct ip_conntrack_expect *exp;
1125 /* Look for the first related address */
1126 for (i = 0; i < count; i++) {
1127 if (get_h225_addr(*data, &addr[i], &ip, &port) &&
1128 ip == ct->tuplehash[dir].tuple.src.ip && port != 0)
1132 if (i >= count) /* Not found */
1135 /* Create expect for Q.931 */
1136 if ((exp = ip_conntrack_expect_alloc(ct)) == NULL)
1138 exp->tuple.src.ip = gkrouted_only ? /* only accept calls from GK? */
1139 ct->tuplehash[!dir].tuple.src.ip : 0;
1140 exp->tuple.src.u.tcp.port = 0;
1141 exp->tuple.dst.ip = ct->tuplehash[!dir].tuple.dst.ip;
1142 exp->tuple.dst.u.tcp.port = htons(port);
1143 exp->tuple.dst.protonum = IPPROTO_TCP;
1144 exp->mask.src.ip = gkrouted_only ? 0xFFFFFFFF : 0;
1145 exp->mask.src.u.tcp.port = 0;
1146 exp->mask.dst.ip = 0xFFFFFFFF;
1147 exp->mask.dst.u.tcp.port = 0xFFFF;
1148 exp->mask.dst.protonum = 0xFF;
1149 exp->flags = IP_CT_EXPECT_PERMANENT; /* Accept multiple calls */
1151 if (nat_q931_hook) { /* Need NAT */
1152 ret = nat_q931_hook(pskb, ct, ctinfo, data, addr, i,
1154 } else { /* Conntrack only */
1155 exp->expectfn = ip_conntrack_q931_expect;
1157 if (ip_conntrack_expect_related(exp) == 0) {
1158 DEBUGP("ip_ct_ras: expect Q.931 "
1159 "%u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
1160 NIPQUAD(exp->tuple.src.ip),
1161 ntohs(exp->tuple.src.u.tcp.port),
1162 NIPQUAD(exp->tuple.dst.ip),
1163 ntohs(exp->tuple.dst.u.tcp.port));
1165 /* Save port for looking up expect in processing RCF */
1166 info->sig_port[dir] = port;
1171 ip_conntrack_expect_put(exp);
1176 /****************************************************************************/
1177 static int process_grq(struct sk_buff **pskb, struct ip_conntrack *ct,
1178 enum ip_conntrack_info ctinfo,
1179 unsigned char **data, GatekeeperRequest * grq)
1181 DEBUGP("ip_ct_ras: GRQ\n");
1183 if (set_ras_addr_hook) /* NATed */
1184 return set_ras_addr_hook(pskb, ct, ctinfo, data,
1185 &grq->rasAddress, 1);
1189 /* Declare before using */
1190 static void ip_conntrack_ras_expect(struct ip_conntrack *new,
1191 struct ip_conntrack_expect *this);
1193 /****************************************************************************/
1194 static int process_gcf(struct sk_buff **pskb, struct ip_conntrack *ct,
1195 enum ip_conntrack_info ctinfo,
1196 unsigned char **data, GatekeeperConfirm * gcf)
1198 int dir = CTINFO2DIR(ctinfo);
1202 struct ip_conntrack_expect *exp;
1204 DEBUGP("ip_ct_ras: GCF\n");
1206 if (!get_h225_addr(*data, &gcf->rasAddress, &ip, &port))
1209 /* Registration port is the same as discovery port */
1210 if (ip == ct->tuplehash[dir].tuple.src.ip &&
1211 port == ntohs(ct->tuplehash[dir].tuple.src.u.udp.port))
1214 /* Avoid RAS expectation loops. A GCF is never expected. */
1215 if (test_bit(IPS_EXPECTED_BIT, &ct->status))
1218 /* Need new expect */
1219 if ((exp = ip_conntrack_expect_alloc(ct)) == NULL)
1221 exp->tuple.src.ip = ct->tuplehash[!dir].tuple.src.ip;
1222 exp->tuple.src.u.tcp.port = 0;
1223 exp->tuple.dst.ip = ip;
1224 exp->tuple.dst.u.tcp.port = htons(port);
1225 exp->tuple.dst.protonum = IPPROTO_UDP;
1226 exp->mask.src.ip = 0xFFFFFFFF;
1227 exp->mask.src.u.tcp.port = 0;
1228 exp->mask.dst.ip = 0xFFFFFFFF;
1229 exp->mask.dst.u.tcp.port = 0xFFFF;
1230 exp->mask.dst.protonum = 0xFF;
1232 exp->expectfn = ip_conntrack_ras_expect;
1233 if (ip_conntrack_expect_related(exp) == 0) {
1234 DEBUGP("ip_ct_ras: expect RAS "
1235 "%u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
1236 NIPQUAD(exp->tuple.src.ip),
1237 ntohs(exp->tuple.src.u.tcp.port),
1238 NIPQUAD(exp->tuple.dst.ip),
1239 ntohs(exp->tuple.dst.u.tcp.port));
1243 ip_conntrack_expect_put(exp);
1248 /****************************************************************************/
1249 static int process_rrq(struct sk_buff **pskb, struct ip_conntrack *ct,
1250 enum ip_conntrack_info ctinfo,
1251 unsigned char **data, RegistrationRequest * rrq)
1253 struct ip_ct_h323_master *info = &ct->help.ct_h323_info;
1256 DEBUGP("ip_ct_ras: RRQ\n");
1258 ret = expect_q931(pskb, ct, ctinfo, data,
1259 rrq->callSignalAddress.item,
1260 rrq->callSignalAddress.count);
1264 if (set_ras_addr_hook) {
1265 ret = set_ras_addr_hook(pskb, ct, ctinfo, data,
1266 rrq->rasAddress.item,
1267 rrq->rasAddress.count);
1272 if (rrq->options & eRegistrationRequest_timeToLive) {
1273 DEBUGP("ip_ct_ras: RRQ TTL = %u seconds\n", rrq->timeToLive);
1274 info->timeout = rrq->timeToLive;
1276 info->timeout = default_rrq_ttl;
1281 /****************************************************************************/
1282 static int process_rcf(struct sk_buff **pskb, struct ip_conntrack *ct,
1283 enum ip_conntrack_info ctinfo,
1284 unsigned char **data, RegistrationConfirm * rcf)
1286 struct ip_ct_h323_master *info = &ct->help.ct_h323_info;
1287 int dir = CTINFO2DIR(ctinfo);
1289 struct ip_conntrack_expect *exp;
1291 DEBUGP("ip_ct_ras: RCF\n");
1293 if (set_sig_addr_hook) {
1294 ret = set_sig_addr_hook(pskb, ct, ctinfo, data,
1295 rcf->callSignalAddress.item,
1296 rcf->callSignalAddress.count);
1301 if (rcf->options & eRegistrationConfirm_timeToLive) {
1302 DEBUGP("ip_ct_ras: RCF TTL = %u seconds\n", rcf->timeToLive);
1303 info->timeout = rcf->timeToLive;
1306 if (info->timeout > 0) {
1308 ("ip_ct_ras: set RAS connection timeout to %u seconds\n",
1310 ip_ct_refresh_acct(ct, ctinfo, NULL, info->timeout * HZ);
1312 /* Set expect timeout */
1313 read_lock_bh(&ip_conntrack_lock);
1314 exp = find_expect(ct, ct->tuplehash[dir].tuple.dst.ip,
1315 info->sig_port[!dir]);
1317 DEBUGP("ip_ct_ras: set Q.931 expect "
1318 "(%u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu) "
1319 "timeout to %u seconds\n",
1320 NIPQUAD(exp->tuple.src.ip),
1321 ntohs(exp->tuple.src.u.tcp.port),
1322 NIPQUAD(exp->tuple.dst.ip),
1323 ntohs(exp->tuple.dst.u.tcp.port),
1325 set_expect_timeout(exp, info->timeout);
1327 read_unlock_bh(&ip_conntrack_lock);
1333 /****************************************************************************/
1334 static int process_urq(struct sk_buff **pskb, struct ip_conntrack *ct,
1335 enum ip_conntrack_info ctinfo,
1336 unsigned char **data, UnregistrationRequest * urq)
1338 struct ip_ct_h323_master *info = &ct->help.ct_h323_info;
1339 int dir = CTINFO2DIR(ctinfo);
1342 DEBUGP("ip_ct_ras: URQ\n");
1344 if (set_sig_addr_hook) {
1345 ret = set_sig_addr_hook(pskb, ct, ctinfo, data,
1346 urq->callSignalAddress.item,
1347 urq->callSignalAddress.count);
1352 /* Clear old expect */
1353 ip_ct_remove_expectations(ct);
1354 info->sig_port[dir] = 0;
1355 info->sig_port[!dir] = 0;
1357 /* Give it 30 seconds for UCF or URJ */
1358 ip_ct_refresh_acct(ct, ctinfo, NULL, 30 * HZ);
1363 /****************************************************************************/
1364 static int process_arq(struct sk_buff **pskb, struct ip_conntrack *ct,
1365 enum ip_conntrack_info ctinfo,
1366 unsigned char **data, AdmissionRequest * arq)
1368 struct ip_ct_h323_master *info = &ct->help.ct_h323_info;
1369 int dir = CTINFO2DIR(ctinfo);
1373 DEBUGP("ip_ct_ras: ARQ\n");
1375 if ((arq->options & eAdmissionRequest_destCallSignalAddress) &&
1376 get_h225_addr(*data, &arq->destCallSignalAddress, &ip, &port) &&
1377 ip == ct->tuplehash[dir].tuple.src.ip &&
1378 port == info->sig_port[dir] && set_h225_addr_hook) {
1380 return set_h225_addr_hook(pskb, data, 0,
1381 &arq->destCallSignalAddress,
1382 ct->tuplehash[!dir].tuple.dst.ip,
1383 info->sig_port[!dir]);
1386 if ((arq->options & eAdmissionRequest_srcCallSignalAddress) &&
1387 get_h225_addr(*data, &arq->srcCallSignalAddress, &ip, &port) &&
1388 ip == ct->tuplehash[dir].tuple.src.ip && set_h225_addr_hook) {
1390 return set_h225_addr_hook(pskb, data, 0,
1391 &arq->srcCallSignalAddress,
1392 ct->tuplehash[!dir].tuple.dst.ip,
1399 /****************************************************************************/
1400 static int process_acf(struct sk_buff **pskb, struct ip_conntrack *ct,
1401 enum ip_conntrack_info ctinfo,
1402 unsigned char **data, AdmissionConfirm * acf)
1404 int dir = CTINFO2DIR(ctinfo);
1408 struct ip_conntrack_expect *exp;
1410 DEBUGP("ip_ct_ras: ACF\n");
1412 if (!get_h225_addr(*data, &acf->destCallSignalAddress, &ip, &port))
1415 if (ip == ct->tuplehash[dir].tuple.dst.ip) { /* Answering ACF */
1416 if (set_sig_addr_hook)
1417 return set_sig_addr_hook(pskb, ct, ctinfo, data,
1418 &acf->destCallSignalAddress,
1423 /* Need new expect */
1424 if ((exp = ip_conntrack_expect_alloc(ct)) == NULL)
1426 exp->tuple.src.ip = ct->tuplehash[!dir].tuple.src.ip;
1427 exp->tuple.src.u.tcp.port = 0;
1428 exp->tuple.dst.ip = ip;
1429 exp->tuple.dst.u.tcp.port = htons(port);
1430 exp->tuple.dst.protonum = IPPROTO_TCP;
1431 exp->mask.src.ip = 0xFFFFFFFF;
1432 exp->mask.src.u.tcp.port = 0;
1433 exp->mask.dst.ip = 0xFFFFFFFF;
1434 exp->mask.dst.u.tcp.port = 0xFFFF;
1435 exp->mask.dst.protonum = 0xFF;
1436 exp->flags = IP_CT_EXPECT_PERMANENT;
1437 exp->expectfn = ip_conntrack_q931_expect;
1439 if (ip_conntrack_expect_related(exp) == 0) {
1440 DEBUGP("ip_ct_ras: expect Q.931 "
1441 "%u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
1442 NIPQUAD(exp->tuple.src.ip),
1443 ntohs(exp->tuple.src.u.tcp.port),
1444 NIPQUAD(exp->tuple.dst.ip),
1445 ntohs(exp->tuple.dst.u.tcp.port));
1449 ip_conntrack_expect_put(exp);
1454 /****************************************************************************/
1455 static int process_lrq(struct sk_buff **pskb, struct ip_conntrack *ct,
1456 enum ip_conntrack_info ctinfo,
1457 unsigned char **data, LocationRequest * lrq)
1459 DEBUGP("ip_ct_ras: LRQ\n");
1461 if (set_ras_addr_hook)
1462 return set_ras_addr_hook(pskb, ct, ctinfo, data,
1463 &lrq->replyAddress, 1);
1467 /****************************************************************************/
1468 static int process_lcf(struct sk_buff **pskb, struct ip_conntrack *ct,
1469 enum ip_conntrack_info ctinfo,
1470 unsigned char **data, LocationConfirm * lcf)
1472 int dir = CTINFO2DIR(ctinfo);
1476 struct ip_conntrack_expect *exp = NULL;
1478 DEBUGP("ip_ct_ras: LCF\n");
1480 if (!get_h225_addr(*data, &lcf->callSignalAddress, &ip, &port))
1483 /* Need new expect for call signal */
1484 if ((exp = ip_conntrack_expect_alloc(ct)) == NULL)
1486 exp->tuple.src.ip = ct->tuplehash[!dir].tuple.src.ip;
1487 exp->tuple.src.u.tcp.port = 0;
1488 exp->tuple.dst.ip = ip;
1489 exp->tuple.dst.u.tcp.port = htons(port);
1490 exp->tuple.dst.protonum = IPPROTO_TCP;
1491 exp->mask.src.ip = 0xFFFFFFFF;
1492 exp->mask.src.u.tcp.port = 0;
1493 exp->mask.dst.ip = 0xFFFFFFFF;
1494 exp->mask.dst.u.tcp.port = 0xFFFF;
1495 exp->mask.dst.protonum = 0xFF;
1496 exp->flags = IP_CT_EXPECT_PERMANENT;
1497 exp->expectfn = ip_conntrack_q931_expect;
1499 if (ip_conntrack_expect_related(exp) == 0) {
1500 DEBUGP("ip_ct_ras: expect Q.931 "
1501 "%u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
1502 NIPQUAD(exp->tuple.src.ip),
1503 ntohs(exp->tuple.src.u.tcp.port),
1504 NIPQUAD(exp->tuple.dst.ip),
1505 ntohs(exp->tuple.dst.u.tcp.port));
1509 ip_conntrack_expect_put(exp);
1511 /* Ignore rasAddress */
1516 /****************************************************************************/
1517 static int process_irr(struct sk_buff **pskb, struct ip_conntrack *ct,
1518 enum ip_conntrack_info ctinfo,
1519 unsigned char **data, InfoRequestResponse * irr)
1523 DEBUGP("ip_ct_ras: IRR\n");
1525 if (set_ras_addr_hook) {
1526 ret = set_ras_addr_hook(pskb, ct, ctinfo, data,
1527 &irr->rasAddress, 1);
1532 if (set_sig_addr_hook) {
1533 ret = set_sig_addr_hook(pskb, ct, ctinfo, data,
1534 irr->callSignalAddress.item,
1535 irr->callSignalAddress.count);
1543 /****************************************************************************/
1544 static int process_ras(struct sk_buff **pskb, struct ip_conntrack *ct,
1545 enum ip_conntrack_info ctinfo,
1546 unsigned char **data, RasMessage * ras)
1548 switch (ras->choice) {
1549 case eRasMessage_gatekeeperRequest:
1550 return process_grq(pskb, ct, ctinfo, data,
1551 &ras->gatekeeperRequest);
1552 case eRasMessage_gatekeeperConfirm:
1553 return process_gcf(pskb, ct, ctinfo, data,
1554 &ras->gatekeeperConfirm);
1555 case eRasMessage_registrationRequest:
1556 return process_rrq(pskb, ct, ctinfo, data,
1557 &ras->registrationRequest);
1558 case eRasMessage_registrationConfirm:
1559 return process_rcf(pskb, ct, ctinfo, data,
1560 &ras->registrationConfirm);
1561 case eRasMessage_unregistrationRequest:
1562 return process_urq(pskb, ct, ctinfo, data,
1563 &ras->unregistrationRequest);
1564 case eRasMessage_admissionRequest:
1565 return process_arq(pskb, ct, ctinfo, data,
1566 &ras->admissionRequest);
1567 case eRasMessage_admissionConfirm:
1568 return process_acf(pskb, ct, ctinfo, data,
1569 &ras->admissionConfirm);
1570 case eRasMessage_locationRequest:
1571 return process_lrq(pskb, ct, ctinfo, data,
1572 &ras->locationRequest);
1573 case eRasMessage_locationConfirm:
1574 return process_lcf(pskb, ct, ctinfo, data,
1575 &ras->locationConfirm);
1576 case eRasMessage_infoRequestResponse:
1577 return process_irr(pskb, ct, ctinfo, data,
1578 &ras->infoRequestResponse);
1580 DEBUGP("ip_ct_ras: RAS message %d\n", ras->choice);
1587 /****************************************************************************/
1588 static int ras_help(struct sk_buff **pskb, struct ip_conntrack *ct,
1589 enum ip_conntrack_info ctinfo)
1591 static RasMessage ras;
1592 unsigned char *data;
1596 DEBUGP("ip_ct_ras: skblen = %u\n", (*pskb)->len);
1598 spin_lock_bh(&ip_h323_lock);
1601 data = get_udp_data(pskb, &datalen);
1604 DEBUGP("ip_ct_ras: RAS message %u.%u.%u.%u->%u.%u.%u.%u, len=%d\n",
1605 NIPQUAD((*pskb)->nh.iph->saddr),
1606 NIPQUAD((*pskb)->nh.iph->daddr), datalen);
1608 /* Decode RAS message */
1609 ret = DecodeRasMessage(data, datalen, &ras);
1611 if (net_ratelimit())
1612 printk("ip_ct_ras: decoding error: %s\n",
1613 ret == H323_ERROR_BOUND ?
1614 "out of bound" : "out of range");
1618 /* Process RAS message */
1619 if (process_ras(pskb, ct, ctinfo, &data, &ras) < 0)
1623 spin_unlock_bh(&ip_h323_lock);
1627 spin_unlock_bh(&ip_h323_lock);
1628 if (net_ratelimit())
1629 printk("ip_ct_ras: packet dropped\n");
1633 /****************************************************************************/
1634 static struct ip_conntrack_helper ip_conntrack_helper_ras = {
1639 .tuple = {.src = {.u = {__constant_htons(RAS_PORT)}},
1640 .dst = {.protonum = IPPROTO_UDP}},
1641 .mask = {.src = {.u = {0xFFFE}},
1642 .dst = {.protonum = 0xFF}},
1646 /****************************************************************************/
1647 static void ip_conntrack_ras_expect(struct ip_conntrack *new,
1648 struct ip_conntrack_expect *this)
1650 write_lock_bh(&ip_conntrack_lock);
1651 new->helper = &ip_conntrack_helper_ras;
1652 write_unlock_bh(&ip_conntrack_lock);
1655 /****************************************************************************/
1656 /* Not __exit - called from init() */
1657 static void fini(void)
1659 ip_conntrack_helper_unregister(&ip_conntrack_helper_ras);
1660 ip_conntrack_helper_unregister(&ip_conntrack_helper_q931);
1662 DEBUGP("ip_ct_h323: fini\n");
1665 /****************************************************************************/
1666 static int __init init(void)
1670 h323_buffer = kmalloc(65536, GFP_KERNEL);
1673 if ((ret = ip_conntrack_helper_register(&ip_conntrack_helper_q931)) ||
1674 (ret = ip_conntrack_helper_register(&ip_conntrack_helper_ras))) {
1679 DEBUGP("ip_ct_h323: init success\n");
1683 /****************************************************************************/
1687 EXPORT_SYMBOL_GPL(get_h225_addr);
1688 EXPORT_SYMBOL_GPL(ip_conntrack_h245_expect);
1689 EXPORT_SYMBOL_GPL(ip_conntrack_q931_expect);
1690 EXPORT_SYMBOL_GPL(set_h245_addr_hook);
1691 EXPORT_SYMBOL_GPL(set_h225_addr_hook);
1692 EXPORT_SYMBOL_GPL(set_sig_addr_hook);
1693 EXPORT_SYMBOL_GPL(set_ras_addr_hook);
1694 EXPORT_SYMBOL_GPL(nat_rtp_rtcp_hook);
1695 EXPORT_SYMBOL_GPL(nat_t120_hook);
1696 EXPORT_SYMBOL_GPL(nat_h245_hook);
1697 EXPORT_SYMBOL_GPL(nat_q931_hook);
1699 MODULE_AUTHOR("Jing Min Zhao <zhaojingmin@users.sourceforge.net>");
1700 MODULE_DESCRIPTION("H.323 connection tracking helper");
1701 MODULE_LICENSE("GPL");