root/net/ipv4/netfilter/nf_nat_h323.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. set_addr
  2. set_h225_addr
  3. set_h245_addr
  4. set_sig_addr
  5. set_ras_addr
  6. nat_rtp_rtcp
  7. nat_t120
  8. nat_h245
  9. ip_nat_q931_expect
  10. nat_q931
  11. ip_nat_callforwarding_expect
  12. nat_callforwarding
  13. fini

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * H.323 extension for NAT alteration.
   4  *
   5  * Copyright (c) 2006 Jing Min Zhao <zhaojingmin@users.sourceforge.net>
   6  * Copyright (c) 2006-2012 Patrick McHardy <kaber@trash.net>
   7  *
   8  * Based on the 'brute force' H.323 NAT module by
   9  * Jozsef Kadlecsik <kadlec@netfilter.org>
  10  */
  11 
  12 #include <linux/module.h>
  13 #include <linux/tcp.h>
  14 #include <net/tcp.h>
  15 
  16 #include <net/netfilter/nf_nat.h>
  17 #include <net/netfilter/nf_nat_helper.h>
  18 #include <net/netfilter/nf_conntrack_helper.h>
  19 #include <net/netfilter/nf_conntrack_expect.h>
  20 #include <linux/netfilter/nf_conntrack_h323.h>
  21 
  22 /****************************************************************************/
  23 static int set_addr(struct sk_buff *skb, unsigned int protoff,
  24                     unsigned char **data, int dataoff,
  25                     unsigned int addroff, __be32 ip, __be16 port)
  26 {
  27         enum ip_conntrack_info ctinfo;
  28         struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
  29         struct {
  30                 __be32 ip;
  31                 __be16 port;
  32         } __attribute__ ((__packed__)) buf;
  33         const struct tcphdr *th;
  34         struct tcphdr _tcph;
  35 
  36         buf.ip = ip;
  37         buf.port = port;
  38         addroff += dataoff;
  39 
  40         if (ip_hdr(skb)->protocol == IPPROTO_TCP) {
  41                 if (!nf_nat_mangle_tcp_packet(skb, ct, ctinfo,
  42                                               protoff, addroff, sizeof(buf),
  43                                               (char *) &buf, sizeof(buf))) {
  44                         net_notice_ratelimited("nf_nat_h323: nf_nat_mangle_tcp_packet error\n");
  45                         return -1;
  46                 }
  47 
  48                 /* Relocate data pointer */
  49                 th = skb_header_pointer(skb, ip_hdrlen(skb),
  50                                         sizeof(_tcph), &_tcph);
  51                 if (th == NULL)
  52                         return -1;
  53                 *data = skb->data + ip_hdrlen(skb) + th->doff * 4 + dataoff;
  54         } else {
  55                 if (!nf_nat_mangle_udp_packet(skb, ct, ctinfo,
  56                                               protoff, addroff, sizeof(buf),
  57                                               (char *) &buf, sizeof(buf))) {
  58                         net_notice_ratelimited("nf_nat_h323: nf_nat_mangle_udp_packet error\n");
  59                         return -1;
  60                 }
  61                 /* nf_nat_mangle_udp_packet uses skb_ensure_writable() to copy
  62                  * or pull everything in a linear buffer, so we can safely
  63                  * use the skb pointers now */
  64                 *data = skb->data + ip_hdrlen(skb) + sizeof(struct udphdr);
  65         }
  66 
  67         return 0;
  68 }
  69 
  70 /****************************************************************************/
  71 static int set_h225_addr(struct sk_buff *skb, unsigned int protoff,
  72                          unsigned char **data, int dataoff,
  73                          TransportAddress *taddr,
  74                          union nf_inet_addr *addr, __be16 port)
  75 {
  76         return set_addr(skb, protoff, data, dataoff, taddr->ipAddress.ip,
  77                         addr->ip, port);
  78 }
  79 
  80 /****************************************************************************/
  81 static int set_h245_addr(struct sk_buff *skb, unsigned protoff,
  82                          unsigned char **data, int dataoff,
  83                          H245_TransportAddress *taddr,
  84                          union nf_inet_addr *addr, __be16 port)
  85 {
  86         return set_addr(skb, protoff, data, dataoff,
  87                         taddr->unicastAddress.iPAddress.network,
  88                         addr->ip, port);
  89 }
  90 
  91 /****************************************************************************/
  92 static int set_sig_addr(struct sk_buff *skb, struct nf_conn *ct,
  93                         enum ip_conntrack_info ctinfo,
  94                         unsigned int protoff, unsigned char **data,
  95                         TransportAddress *taddr, int count)
  96 {
  97         const struct nf_ct_h323_master *info = nfct_help_data(ct);
  98         int dir = CTINFO2DIR(ctinfo);
  99         int i;
 100         __be16 port;
 101         union nf_inet_addr addr;
 102 
 103         for (i = 0; i < count; i++) {
 104                 if (get_h225_addr(ct, *data, &taddr[i], &addr, &port)) {
 105                         if (addr.ip == ct->tuplehash[dir].tuple.src.u3.ip &&
 106                             port == info->sig_port[dir]) {
 107                                 /* GW->GK */
 108 
 109                                 /* Fix for Gnomemeeting */
 110                                 if (i > 0 &&
 111                                     get_h225_addr(ct, *data, &taddr[0],
 112                                                   &addr, &port) &&
 113                                     (ntohl(addr.ip) & 0xff000000) == 0x7f000000)
 114                                         i = 0;
 115 
 116                                 pr_debug("nf_nat_ras: set signal address %pI4:%hu->%pI4:%hu\n",
 117                                          &addr.ip, port,
 118                                          &ct->tuplehash[!dir].tuple.dst.u3.ip,
 119                                          info->sig_port[!dir]);
 120                                 return set_h225_addr(skb, protoff, data, 0,
 121                                                      &taddr[i],
 122                                                      &ct->tuplehash[!dir].
 123                                                      tuple.dst.u3,
 124                                                      info->sig_port[!dir]);
 125                         } else if (addr.ip == ct->tuplehash[dir].tuple.dst.u3.ip &&
 126                                    port == info->sig_port[dir]) {
 127                                 /* GK->GW */
 128                                 pr_debug("nf_nat_ras: set signal address %pI4:%hu->%pI4:%hu\n",
 129                                          &addr.ip, port,
 130                                          &ct->tuplehash[!dir].tuple.src.u3.ip,
 131                                          info->sig_port[!dir]);
 132                                 return set_h225_addr(skb, protoff, data, 0,
 133                                                      &taddr[i],
 134                                                      &ct->tuplehash[!dir].
 135                                                      tuple.src.u3,
 136                                                      info->sig_port[!dir]);
 137                         }
 138                 }
 139         }
 140 
 141         return 0;
 142 }
 143 
 144 /****************************************************************************/
 145 static int set_ras_addr(struct sk_buff *skb, struct nf_conn *ct,
 146                         enum ip_conntrack_info ctinfo,
 147                         unsigned int protoff, unsigned char **data,
 148                         TransportAddress *taddr, int count)
 149 {
 150         int dir = CTINFO2DIR(ctinfo);
 151         int i;
 152         __be16 port;
 153         union nf_inet_addr addr;
 154 
 155         for (i = 0; i < count; i++) {
 156                 if (get_h225_addr(ct, *data, &taddr[i], &addr, &port) &&
 157                     addr.ip == ct->tuplehash[dir].tuple.src.u3.ip &&
 158                     port == ct->tuplehash[dir].tuple.src.u.udp.port) {
 159                         pr_debug("nf_nat_ras: set rasAddress %pI4:%hu->%pI4:%hu\n",
 160                                  &addr.ip, ntohs(port),
 161                                  &ct->tuplehash[!dir].tuple.dst.u3.ip,
 162                                  ntohs(ct->tuplehash[!dir].tuple.dst.u.udp.port));
 163                         return set_h225_addr(skb, protoff, data, 0, &taddr[i],
 164                                              &ct->tuplehash[!dir].tuple.dst.u3,
 165                                              ct->tuplehash[!dir].tuple.
 166                                                                 dst.u.udp.port);
 167                 }
 168         }
 169 
 170         return 0;
 171 }
 172 
 173 /****************************************************************************/
 174 static int nat_rtp_rtcp(struct sk_buff *skb, struct nf_conn *ct,
 175                         enum ip_conntrack_info ctinfo,
 176                         unsigned int protoff, unsigned char **data, int dataoff,
 177                         H245_TransportAddress *taddr,
 178                         __be16 port, __be16 rtp_port,
 179                         struct nf_conntrack_expect *rtp_exp,
 180                         struct nf_conntrack_expect *rtcp_exp)
 181 {
 182         struct nf_ct_h323_master *info = nfct_help_data(ct);
 183         int dir = CTINFO2DIR(ctinfo);
 184         int i;
 185         u_int16_t nated_port;
 186 
 187         /* Set expectations for NAT */
 188         rtp_exp->saved_proto.udp.port = rtp_exp->tuple.dst.u.udp.port;
 189         rtp_exp->expectfn = nf_nat_follow_master;
 190         rtp_exp->dir = !dir;
 191         rtcp_exp->saved_proto.udp.port = rtcp_exp->tuple.dst.u.udp.port;
 192         rtcp_exp->expectfn = nf_nat_follow_master;
 193         rtcp_exp->dir = !dir;
 194 
 195         /* Lookup existing expects */
 196         for (i = 0; i < H323_RTP_CHANNEL_MAX; i++) {
 197                 if (info->rtp_port[i][dir] == rtp_port) {
 198                         /* Expected */
 199 
 200                         /* Use allocated ports first. This will refresh
 201                          * the expects */
 202                         rtp_exp->tuple.dst.u.udp.port = info->rtp_port[i][dir];
 203                         rtcp_exp->tuple.dst.u.udp.port =
 204                             htons(ntohs(info->rtp_port[i][dir]) + 1);
 205                         break;
 206                 } else if (info->rtp_port[i][dir] == 0) {
 207                         /* Not expected */
 208                         break;
 209                 }
 210         }
 211 
 212         /* Run out of expectations */
 213         if (i >= H323_RTP_CHANNEL_MAX) {
 214                 net_notice_ratelimited("nf_nat_h323: out of expectations\n");
 215                 return 0;
 216         }
 217 
 218         /* Try to get a pair of ports. */
 219         for (nated_port = ntohs(rtp_exp->tuple.dst.u.udp.port);
 220              nated_port != 0; nated_port += 2) {
 221                 int ret;
 222 
 223                 rtp_exp->tuple.dst.u.udp.port = htons(nated_port);
 224                 ret = nf_ct_expect_related(rtp_exp, 0);
 225                 if (ret == 0) {
 226                         rtcp_exp->tuple.dst.u.udp.port =
 227                             htons(nated_port + 1);
 228                         ret = nf_ct_expect_related(rtcp_exp, 0);
 229                         if (ret == 0)
 230                                 break;
 231                         else if (ret == -EBUSY) {
 232                                 nf_ct_unexpect_related(rtp_exp);
 233                                 continue;
 234                         } else if (ret < 0) {
 235                                 nf_ct_unexpect_related(rtp_exp);
 236                                 nated_port = 0;
 237                                 break;
 238                         }
 239                 } else if (ret != -EBUSY) {
 240                         nated_port = 0;
 241                         break;
 242                 }
 243         }
 244 
 245         if (nated_port == 0) {  /* No port available */
 246                 net_notice_ratelimited("nf_nat_h323: out of RTP ports\n");
 247                 return 0;
 248         }
 249 
 250         /* Modify signal */
 251         if (set_h245_addr(skb, protoff, data, dataoff, taddr,
 252                           &ct->tuplehash[!dir].tuple.dst.u3,
 253                           htons((port & htons(1)) ? nated_port + 1 :
 254                                                     nated_port))) {
 255                 nf_ct_unexpect_related(rtp_exp);
 256                 nf_ct_unexpect_related(rtcp_exp);
 257                 return -1;
 258         }
 259 
 260         /* Save ports */
 261         info->rtp_port[i][dir] = rtp_port;
 262         info->rtp_port[i][!dir] = htons(nated_port);
 263 
 264         /* Success */
 265         pr_debug("nf_nat_h323: expect RTP %pI4:%hu->%pI4:%hu\n",
 266                  &rtp_exp->tuple.src.u3.ip,
 267                  ntohs(rtp_exp->tuple.src.u.udp.port),
 268                  &rtp_exp->tuple.dst.u3.ip,
 269                  ntohs(rtp_exp->tuple.dst.u.udp.port));
 270         pr_debug("nf_nat_h323: expect RTCP %pI4:%hu->%pI4:%hu\n",
 271                  &rtcp_exp->tuple.src.u3.ip,
 272                  ntohs(rtcp_exp->tuple.src.u.udp.port),
 273                  &rtcp_exp->tuple.dst.u3.ip,
 274                  ntohs(rtcp_exp->tuple.dst.u.udp.port));
 275 
 276         return 0;
 277 }
 278 
 279 /****************************************************************************/
 280 static int nat_t120(struct sk_buff *skb, struct nf_conn *ct,
 281                     enum ip_conntrack_info ctinfo,
 282                     unsigned int protoff, unsigned char **data, int dataoff,
 283                     H245_TransportAddress *taddr, __be16 port,
 284                     struct nf_conntrack_expect *exp)
 285 {
 286         int dir = CTINFO2DIR(ctinfo);
 287         u_int16_t nated_port = ntohs(port);
 288 
 289         /* Set expectations for NAT */
 290         exp->saved_proto.tcp.port = exp->tuple.dst.u.tcp.port;
 291         exp->expectfn = nf_nat_follow_master;
 292         exp->dir = !dir;
 293 
 294         /* Try to get same port: if not, try to change it. */
 295         for (; nated_port != 0; nated_port++) {
 296                 int ret;
 297 
 298                 exp->tuple.dst.u.tcp.port = htons(nated_port);
 299                 ret = nf_ct_expect_related(exp, 0);
 300                 if (ret == 0)
 301                         break;
 302                 else if (ret != -EBUSY) {
 303                         nated_port = 0;
 304                         break;
 305                 }
 306         }
 307 
 308         if (nated_port == 0) {  /* No port available */
 309                 net_notice_ratelimited("nf_nat_h323: out of TCP ports\n");
 310                 return 0;
 311         }
 312 
 313         /* Modify signal */
 314         if (set_h245_addr(skb, protoff, data, dataoff, taddr,
 315                           &ct->tuplehash[!dir].tuple.dst.u3,
 316                           htons(nated_port)) < 0) {
 317                 nf_ct_unexpect_related(exp);
 318                 return -1;
 319         }
 320 
 321         pr_debug("nf_nat_h323: expect T.120 %pI4:%hu->%pI4:%hu\n",
 322                  &exp->tuple.src.u3.ip,
 323                  ntohs(exp->tuple.src.u.tcp.port),
 324                  &exp->tuple.dst.u3.ip,
 325                  ntohs(exp->tuple.dst.u.tcp.port));
 326 
 327         return 0;
 328 }
 329 
 330 /****************************************************************************/
 331 static int nat_h245(struct sk_buff *skb, struct nf_conn *ct,
 332                     enum ip_conntrack_info ctinfo,
 333                     unsigned int protoff, unsigned char **data, int dataoff,
 334                     TransportAddress *taddr, __be16 port,
 335                     struct nf_conntrack_expect *exp)
 336 {
 337         struct nf_ct_h323_master *info = nfct_help_data(ct);
 338         int dir = CTINFO2DIR(ctinfo);
 339         u_int16_t nated_port = ntohs(port);
 340 
 341         /* Set expectations for NAT */
 342         exp->saved_proto.tcp.port = exp->tuple.dst.u.tcp.port;
 343         exp->expectfn = nf_nat_follow_master;
 344         exp->dir = !dir;
 345 
 346         /* Check existing expects */
 347         if (info->sig_port[dir] == port)
 348                 nated_port = ntohs(info->sig_port[!dir]);
 349 
 350         /* Try to get same port: if not, try to change it. */
 351         for (; nated_port != 0; nated_port++) {
 352                 int ret;
 353 
 354                 exp->tuple.dst.u.tcp.port = htons(nated_port);
 355                 ret = nf_ct_expect_related(exp, 0);
 356                 if (ret == 0)
 357                         break;
 358                 else if (ret != -EBUSY) {
 359                         nated_port = 0;
 360                         break;
 361                 }
 362         }
 363 
 364         if (nated_port == 0) {  /* No port available */
 365                 net_notice_ratelimited("nf_nat_q931: out of TCP ports\n");
 366                 return 0;
 367         }
 368 
 369         /* Modify signal */
 370         if (set_h225_addr(skb, protoff, data, dataoff, taddr,
 371                           &ct->tuplehash[!dir].tuple.dst.u3,
 372                           htons(nated_port))) {
 373                 nf_ct_unexpect_related(exp);
 374                 return -1;
 375         }
 376 
 377         /* Save ports */
 378         info->sig_port[dir] = port;
 379         info->sig_port[!dir] = htons(nated_port);
 380 
 381         pr_debug("nf_nat_q931: expect H.245 %pI4:%hu->%pI4:%hu\n",
 382                  &exp->tuple.src.u3.ip,
 383                  ntohs(exp->tuple.src.u.tcp.port),
 384                  &exp->tuple.dst.u3.ip,
 385                  ntohs(exp->tuple.dst.u.tcp.port));
 386 
 387         return 0;
 388 }
 389 
 390 /****************************************************************************
 391  * This conntrack expect function replaces nf_conntrack_q931_expect()
 392  * which was set by nf_conntrack_h323.c.
 393  ****************************************************************************/
 394 static void ip_nat_q931_expect(struct nf_conn *new,
 395                                struct nf_conntrack_expect *this)
 396 {
 397         struct nf_nat_range2 range;
 398 
 399         if (this->tuple.src.u3.ip != 0) {       /* Only accept calls from GK */
 400                 nf_nat_follow_master(new, this);
 401                 return;
 402         }
 403 
 404         /* This must be a fresh one. */
 405         BUG_ON(new->status & IPS_NAT_DONE_MASK);
 406 
 407         /* Change src to where master sends to */
 408         range.flags = NF_NAT_RANGE_MAP_IPS;
 409         range.min_addr = range.max_addr =
 410             new->tuplehash[!this->dir].tuple.src.u3;
 411         nf_nat_setup_info(new, &range, NF_NAT_MANIP_SRC);
 412 
 413         /* For DST manip, map port here to where it's expected. */
 414         range.flags = (NF_NAT_RANGE_MAP_IPS | NF_NAT_RANGE_PROTO_SPECIFIED);
 415         range.min_proto = range.max_proto = this->saved_proto;
 416         range.min_addr = range.max_addr =
 417             new->master->tuplehash[!this->dir].tuple.src.u3;
 418         nf_nat_setup_info(new, &range, NF_NAT_MANIP_DST);
 419 }
 420 
 421 /****************************************************************************/
 422 static int nat_q931(struct sk_buff *skb, struct nf_conn *ct,
 423                     enum ip_conntrack_info ctinfo,
 424                     unsigned int protoff, unsigned char **data,
 425                     TransportAddress *taddr, int idx,
 426                     __be16 port, struct nf_conntrack_expect *exp)
 427 {
 428         struct nf_ct_h323_master *info = nfct_help_data(ct);
 429         int dir = CTINFO2DIR(ctinfo);
 430         u_int16_t nated_port = ntohs(port);
 431         union nf_inet_addr addr;
 432 
 433         /* Set expectations for NAT */
 434         exp->saved_proto.tcp.port = exp->tuple.dst.u.tcp.port;
 435         exp->expectfn = ip_nat_q931_expect;
 436         exp->dir = !dir;
 437 
 438         /* Check existing expects */
 439         if (info->sig_port[dir] == port)
 440                 nated_port = ntohs(info->sig_port[!dir]);
 441 
 442         /* Try to get same port: if not, try to change it. */
 443         for (; nated_port != 0; nated_port++) {
 444                 int ret;
 445 
 446                 exp->tuple.dst.u.tcp.port = htons(nated_port);
 447                 ret = nf_ct_expect_related(exp, 0);
 448                 if (ret == 0)
 449                         break;
 450                 else if (ret != -EBUSY) {
 451                         nated_port = 0;
 452                         break;
 453                 }
 454         }
 455 
 456         if (nated_port == 0) {  /* No port available */
 457                 net_notice_ratelimited("nf_nat_ras: out of TCP ports\n");
 458                 return 0;
 459         }
 460 
 461         /* Modify signal */
 462         if (set_h225_addr(skb, protoff, data, 0, &taddr[idx],
 463                           &ct->tuplehash[!dir].tuple.dst.u3,
 464                           htons(nated_port))) {
 465                 nf_ct_unexpect_related(exp);
 466                 return -1;
 467         }
 468 
 469         /* Save ports */
 470         info->sig_port[dir] = port;
 471         info->sig_port[!dir] = htons(nated_port);
 472 
 473         /* Fix for Gnomemeeting */
 474         if (idx > 0 &&
 475             get_h225_addr(ct, *data, &taddr[0], &addr, &port) &&
 476             (ntohl(addr.ip) & 0xff000000) == 0x7f000000) {
 477                 if (set_h225_addr(skb, protoff, data, 0, &taddr[0],
 478                                   &ct->tuplehash[!dir].tuple.dst.u3,
 479                                   info->sig_port[!dir])) {
 480                         nf_ct_unexpect_related(exp);
 481                         return -1;
 482                 }
 483         }
 484 
 485         /* Success */
 486         pr_debug("nf_nat_ras: expect Q.931 %pI4:%hu->%pI4:%hu\n",
 487                  &exp->tuple.src.u3.ip,
 488                  ntohs(exp->tuple.src.u.tcp.port),
 489                  &exp->tuple.dst.u3.ip,
 490                  ntohs(exp->tuple.dst.u.tcp.port));
 491 
 492         return 0;
 493 }
 494 
 495 /****************************************************************************/
 496 static void ip_nat_callforwarding_expect(struct nf_conn *new,
 497                                          struct nf_conntrack_expect *this)
 498 {
 499         struct nf_nat_range2 range;
 500 
 501         /* This must be a fresh one. */
 502         BUG_ON(new->status & IPS_NAT_DONE_MASK);
 503 
 504         /* Change src to where master sends to */
 505         range.flags = NF_NAT_RANGE_MAP_IPS;
 506         range.min_addr = range.max_addr =
 507             new->tuplehash[!this->dir].tuple.src.u3;
 508         nf_nat_setup_info(new, &range, NF_NAT_MANIP_SRC);
 509 
 510         /* For DST manip, map port here to where it's expected. */
 511         range.flags = (NF_NAT_RANGE_MAP_IPS | NF_NAT_RANGE_PROTO_SPECIFIED);
 512         range.min_proto = range.max_proto = this->saved_proto;
 513         range.min_addr = range.max_addr = this->saved_addr;
 514         nf_nat_setup_info(new, &range, NF_NAT_MANIP_DST);
 515 }
 516 
 517 /****************************************************************************/
 518 static int nat_callforwarding(struct sk_buff *skb, struct nf_conn *ct,
 519                               enum ip_conntrack_info ctinfo,
 520                               unsigned int protoff,
 521                               unsigned char **data, int dataoff,
 522                               TransportAddress *taddr, __be16 port,
 523                               struct nf_conntrack_expect *exp)
 524 {
 525         int dir = CTINFO2DIR(ctinfo);
 526         u_int16_t nated_port;
 527 
 528         /* Set expectations for NAT */
 529         exp->saved_addr = exp->tuple.dst.u3;
 530         exp->tuple.dst.u3.ip = ct->tuplehash[!dir].tuple.dst.u3.ip;
 531         exp->saved_proto.tcp.port = exp->tuple.dst.u.tcp.port;
 532         exp->expectfn = ip_nat_callforwarding_expect;
 533         exp->dir = !dir;
 534 
 535         /* Try to get same port: if not, try to change it. */
 536         for (nated_port = ntohs(port); nated_port != 0; nated_port++) {
 537                 int ret;
 538 
 539                 exp->tuple.dst.u.tcp.port = htons(nated_port);
 540                 ret = nf_ct_expect_related(exp, 0);
 541                 if (ret == 0)
 542                         break;
 543                 else if (ret != -EBUSY) {
 544                         nated_port = 0;
 545                         break;
 546                 }
 547         }
 548 
 549         if (nated_port == 0) {  /* No port available */
 550                 net_notice_ratelimited("nf_nat_q931: out of TCP ports\n");
 551                 return 0;
 552         }
 553 
 554         /* Modify signal */
 555         if (set_h225_addr(skb, protoff, data, dataoff, taddr,
 556                           &ct->tuplehash[!dir].tuple.dst.u3,
 557                           htons(nated_port))) {
 558                 nf_ct_unexpect_related(exp);
 559                 return -1;
 560         }
 561 
 562         /* Success */
 563         pr_debug("nf_nat_q931: expect Call Forwarding %pI4:%hu->%pI4:%hu\n",
 564                  &exp->tuple.src.u3.ip,
 565                  ntohs(exp->tuple.src.u.tcp.port),
 566                  &exp->tuple.dst.u3.ip,
 567                  ntohs(exp->tuple.dst.u.tcp.port));
 568 
 569         return 0;
 570 }
 571 
 572 static struct nf_ct_helper_expectfn q931_nat = {
 573         .name           = "Q.931",
 574         .expectfn       = ip_nat_q931_expect,
 575 };
 576 
 577 static struct nf_ct_helper_expectfn callforwarding_nat = {
 578         .name           = "callforwarding",
 579         .expectfn       = ip_nat_callforwarding_expect,
 580 };
 581 
 582 /****************************************************************************/
 583 static int __init init(void)
 584 {
 585         BUG_ON(set_h245_addr_hook != NULL);
 586         BUG_ON(set_h225_addr_hook != NULL);
 587         BUG_ON(set_sig_addr_hook != NULL);
 588         BUG_ON(set_ras_addr_hook != NULL);
 589         BUG_ON(nat_rtp_rtcp_hook != NULL);
 590         BUG_ON(nat_t120_hook != NULL);
 591         BUG_ON(nat_h245_hook != NULL);
 592         BUG_ON(nat_callforwarding_hook != NULL);
 593         BUG_ON(nat_q931_hook != NULL);
 594 
 595         RCU_INIT_POINTER(set_h245_addr_hook, set_h245_addr);
 596         RCU_INIT_POINTER(set_h225_addr_hook, set_h225_addr);
 597         RCU_INIT_POINTER(set_sig_addr_hook, set_sig_addr);
 598         RCU_INIT_POINTER(set_ras_addr_hook, set_ras_addr);
 599         RCU_INIT_POINTER(nat_rtp_rtcp_hook, nat_rtp_rtcp);
 600         RCU_INIT_POINTER(nat_t120_hook, nat_t120);
 601         RCU_INIT_POINTER(nat_h245_hook, nat_h245);
 602         RCU_INIT_POINTER(nat_callforwarding_hook, nat_callforwarding);
 603         RCU_INIT_POINTER(nat_q931_hook, nat_q931);
 604         nf_ct_helper_expectfn_register(&q931_nat);
 605         nf_ct_helper_expectfn_register(&callforwarding_nat);
 606         return 0;
 607 }
 608 
 609 /****************************************************************************/
 610 static void __exit fini(void)
 611 {
 612         RCU_INIT_POINTER(set_h245_addr_hook, NULL);
 613         RCU_INIT_POINTER(set_h225_addr_hook, NULL);
 614         RCU_INIT_POINTER(set_sig_addr_hook, NULL);
 615         RCU_INIT_POINTER(set_ras_addr_hook, NULL);
 616         RCU_INIT_POINTER(nat_rtp_rtcp_hook, NULL);
 617         RCU_INIT_POINTER(nat_t120_hook, NULL);
 618         RCU_INIT_POINTER(nat_h245_hook, NULL);
 619         RCU_INIT_POINTER(nat_callforwarding_hook, NULL);
 620         RCU_INIT_POINTER(nat_q931_hook, NULL);
 621         nf_ct_helper_expectfn_unregister(&q931_nat);
 622         nf_ct_helper_expectfn_unregister(&callforwarding_nat);
 623         synchronize_rcu();
 624 }
 625 
 626 /****************************************************************************/
 627 module_init(init);
 628 module_exit(fini);
 629 
 630 MODULE_AUTHOR("Jing Min Zhao <zhaojingmin@users.sourceforge.net>");
 631 MODULE_DESCRIPTION("H.323 NAT helper");
 632 MODULE_LICENSE("GPL");
 633 MODULE_ALIAS_NF_NAT_HELPER("h323");

/* [<][>][^][v][top][bottom][index][help] */