Blame view
net/netfilter/nf_conntrack_h323_main.c
52 KB
f587de0e2 [NETFILTER]: nf_c... |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
/* * H.323 connection tracking helper * * Copyright (c) 2006 Jing Min Zhao <zhaojingmin@users.sourceforge.net> * * This source code is licensed under General Public License version 2. * * Based on the 'brute force' H.323 connection tracking module by * Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> * * For more information, please see http://nath323.sourceforge.net/ */ #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/ctype.h> #include <linux/inet.h> #include <linux/in.h> #include <linux/ip.h> |
5a0e3ad6a include cleanup: ... |
20 |
#include <linux/slab.h> |
f587de0e2 [NETFILTER]: nf_c... |
21 22 23 24 25 26 27 28 29 30 31 32 |
#include <linux/udp.h> #include <linux/tcp.h> #include <linux/skbuff.h> #include <net/route.h> #include <net/ip6_route.h> #include <net/netfilter/nf_conntrack.h> #include <net/netfilter/nf_conntrack_core.h> #include <net/netfilter/nf_conntrack_tuple.h> #include <net/netfilter/nf_conntrack_expect.h> #include <net/netfilter/nf_conntrack_ecache.h> #include <net/netfilter/nf_conntrack_helper.h> |
5d0aa2ccd netfilter: nf_con... |
33 |
#include <net/netfilter/nf_conntrack_zones.h> |
f587de0e2 [NETFILTER]: nf_c... |
34 |
#include <linux/netfilter/nf_conntrack_h323.h> |
f587de0e2 [NETFILTER]: nf_c... |
35 36 37 38 39 40 41 42 |
/* Parameters */ static unsigned int default_rrq_ttl __read_mostly = 300; module_param(default_rrq_ttl, uint, 0600); MODULE_PARM_DESC(default_rrq_ttl, "use this TTL if it's missing in RRQ"); static int gkrouted_only __read_mostly = 1; module_param(gkrouted_only, int, 0600); MODULE_PARM_DESC(gkrouted_only, "only accept calls from gatekeeper"); |
eb9399220 module_param: mak... |
43 |
static bool callforward_filter __read_mostly = true; |
f587de0e2 [NETFILTER]: nf_c... |
44 45 |
module_param(callforward_filter, bool, 0600); MODULE_PARM_DESC(callforward_filter, "only create call forwarding expectations " |
601e68e10 [NETFILTER]: Fix ... |
46 |
"if both endpoints are on different sides " |
f587de0e2 [NETFILTER]: nf_c... |
47 48 49 |
"(determined by routing information)"); /* Hooks for NAT */ |
3db05fea5 [NETFILTER]: Repl... |
50 |
int (*set_h245_addr_hook) (struct sk_buff *skb, |
f587de0e2 [NETFILTER]: nf_c... |
51 52 |
unsigned char **data, int dataoff, H245_TransportAddress *taddr, |
643a2c15a [NETFILTER]: Intr... |
53 |
union nf_inet_addr *addr, __be16 port) |
f587de0e2 [NETFILTER]: nf_c... |
54 |
__read_mostly; |
3db05fea5 [NETFILTER]: Repl... |
55 |
int (*set_h225_addr_hook) (struct sk_buff *skb, |
f587de0e2 [NETFILTER]: nf_c... |
56 57 |
unsigned char **data, int dataoff, TransportAddress *taddr, |
643a2c15a [NETFILTER]: Intr... |
58 |
union nf_inet_addr *addr, __be16 port) |
f587de0e2 [NETFILTER]: nf_c... |
59 |
__read_mostly; |
3db05fea5 [NETFILTER]: Repl... |
60 |
int (*set_sig_addr_hook) (struct sk_buff *skb, |
f587de0e2 [NETFILTER]: nf_c... |
61 62 63 64 |
struct nf_conn *ct, enum ip_conntrack_info ctinfo, unsigned char **data, TransportAddress *taddr, int count) __read_mostly; |
3db05fea5 [NETFILTER]: Repl... |
65 |
int (*set_ras_addr_hook) (struct sk_buff *skb, |
f587de0e2 [NETFILTER]: nf_c... |
66 67 68 69 |
struct nf_conn *ct, enum ip_conntrack_info ctinfo, unsigned char **data, TransportAddress *taddr, int count) __read_mostly; |
3db05fea5 [NETFILTER]: Repl... |
70 |
int (*nat_rtp_rtcp_hook) (struct sk_buff *skb, |
f587de0e2 [NETFILTER]: nf_c... |
71 72 73 74 75 76 77 |
struct nf_conn *ct, enum ip_conntrack_info ctinfo, unsigned char **data, int dataoff, H245_TransportAddress *taddr, __be16 port, __be16 rtp_port, struct nf_conntrack_expect *rtp_exp, struct nf_conntrack_expect *rtcp_exp) __read_mostly; |
3db05fea5 [NETFILTER]: Repl... |
78 |
int (*nat_t120_hook) (struct sk_buff *skb, |
f587de0e2 [NETFILTER]: nf_c... |
79 80 81 82 83 |
struct nf_conn *ct, enum ip_conntrack_info ctinfo, unsigned char **data, int dataoff, H245_TransportAddress *taddr, __be16 port, struct nf_conntrack_expect *exp) __read_mostly; |
3db05fea5 [NETFILTER]: Repl... |
84 |
int (*nat_h245_hook) (struct sk_buff *skb, |
f587de0e2 [NETFILTER]: nf_c... |
85 86 87 88 89 |
struct nf_conn *ct, enum ip_conntrack_info ctinfo, unsigned char **data, int dataoff, TransportAddress *taddr, __be16 port, struct nf_conntrack_expect *exp) __read_mostly; |
3db05fea5 [NETFILTER]: Repl... |
90 |
int (*nat_callforwarding_hook) (struct sk_buff *skb, |
f587de0e2 [NETFILTER]: nf_c... |
91 92 93 94 95 |
struct nf_conn *ct, enum ip_conntrack_info ctinfo, unsigned char **data, int dataoff, TransportAddress *taddr, __be16 port, struct nf_conntrack_expect *exp) __read_mostly; |
3db05fea5 [NETFILTER]: Repl... |
96 |
int (*nat_q931_hook) (struct sk_buff *skb, |
f587de0e2 [NETFILTER]: nf_c... |
97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
struct nf_conn *ct, enum ip_conntrack_info ctinfo, unsigned char **data, TransportAddress *taddr, int idx, __be16 port, struct nf_conntrack_expect *exp) __read_mostly; static DEFINE_SPINLOCK(nf_h323_lock); static char *h323_buffer; static struct nf_conntrack_helper nf_conntrack_helper_h245; static struct nf_conntrack_helper nf_conntrack_helper_q931[]; static struct nf_conntrack_helper nf_conntrack_helper_ras[]; /****************************************************************************/ |
3db05fea5 [NETFILTER]: Repl... |
111 |
static int get_tpkt_data(struct sk_buff *skb, unsigned int protoff, |
f587de0e2 [NETFILTER]: nf_c... |
112 113 114 115 116 |
struct nf_conn *ct, enum ip_conntrack_info ctinfo, unsigned char **data, int *datalen, int *dataoff) { struct nf_ct_h323_master *info = &nfct_help(ct)->help.ct_h323_info; int dir = CTINFO2DIR(ctinfo); |
905e3e8ec [NETFILTER]: nf_c... |
117 118 |
const struct tcphdr *th; struct tcphdr _tcph; |
f587de0e2 [NETFILTER]: nf_c... |
119 120 121 122 123 124 125 |
int tcpdatalen; int tcpdataoff; unsigned char *tpkt; int tpktlen; int tpktoff; /* Get TCP header */ |
3db05fea5 [NETFILTER]: Repl... |
126 |
th = skb_header_pointer(skb, protoff, sizeof(_tcph), &_tcph); |
f587de0e2 [NETFILTER]: nf_c... |
127 128 129 130 131 132 133 |
if (th == NULL) return 0; /* Get TCP data offset */ tcpdataoff = protoff + th->doff * 4; /* Get TCP data length */ |
3db05fea5 [NETFILTER]: Repl... |
134 |
tcpdatalen = skb->len - tcpdataoff; |
f587de0e2 [NETFILTER]: nf_c... |
135 136 137 138 139 |
if (tcpdatalen <= 0) /* No TCP data */ goto clear_out; if (*data == NULL) { /* first TPKT */ /* Get first TPKT pointer */ |
3db05fea5 [NETFILTER]: Repl... |
140 |
tpkt = skb_header_pointer(skb, tcpdataoff, tcpdatalen, |
f587de0e2 [NETFILTER]: nf_c... |
141 142 143 144 145 146 147 |
h323_buffer); BUG_ON(tpkt == NULL); /* Validate TPKT identifier */ if (tcpdatalen < 4 || tpkt[0] != 0x03 || tpkt[1] != 0) { /* Netmeeting sends TPKT header and data separately */ if (info->tpkt_len[dir] > 0) { |
0d53778e8 [NETFILTER]: Conv... |
148 149 150 151 |
pr_debug("nf_ct_h323: previous packet " "indicated separate TPKT data of %hu " "bytes ", info->tpkt_len[dir]); |
f587de0e2 [NETFILTER]: nf_c... |
152 153 154 155 156 157 158 159 160 161 |
if (info->tpkt_len[dir] <= tcpdatalen) { /* Yes, there was a TPKT header * received */ *data = tpkt; *datalen = info->tpkt_len[dir]; *dataoff = 0; goto out; } /* Fragmented TPKT */ |
0d53778e8 [NETFILTER]: Conv... |
162 163 |
pr_debug("nf_ct_h323: fragmented TPKT "); |
f587de0e2 [NETFILTER]: nf_c... |
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 |
goto clear_out; } /* It is not even a TPKT */ return 0; } tpktoff = 0; } else { /* Next TPKT */ tpktoff = *dataoff + *datalen; tcpdatalen -= tpktoff; if (tcpdatalen <= 4) /* No more TPKT */ goto clear_out; tpkt = *data + *datalen; /* Validate TPKT identifier */ if (tpkt[0] != 0x03 || tpkt[1] != 0) goto clear_out; } /* Validate TPKT length */ tpktlen = tpkt[2] * 256 + tpkt[3]; if (tpktlen < 4) goto clear_out; if (tpktlen > tcpdatalen) { if (tcpdatalen == 4) { /* Separate TPKT header */ /* Netmeeting sends TPKT header and data separately */ |
0d53778e8 [NETFILTER]: Conv... |
190 191 192 193 |
pr_debug("nf_ct_h323: separate TPKT header indicates " "there will be TPKT data of %hu bytes ", tpktlen - 4); |
f587de0e2 [NETFILTER]: nf_c... |
194 195 196 |
info->tpkt_len[dir] = tpktlen - 4; return 0; } |
e772c349a netfilter: nf_ct_... |
197 198 |
pr_debug("nf_ct_h323: incomplete TPKT (fragmented?) "); |
f587de0e2 [NETFILTER]: nf_c... |
199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 |
goto clear_out; } /* This is the encapsulated data */ *data = tpkt + 4; *datalen = tpktlen - 4; *dataoff = tpktoff + 4; out: /* Clear TPKT length */ info->tpkt_len[dir] = 0; return 1; clear_out: info->tpkt_len[dir] = 0; return 0; } /****************************************************************************/ |
905e3e8ec [NETFILTER]: nf_c... |
218 |
static int get_h245_addr(struct nf_conn *ct, const unsigned char *data, |
f587de0e2 [NETFILTER]: nf_c... |
219 |
H245_TransportAddress *taddr, |
643a2c15a [NETFILTER]: Intr... |
220 |
union nf_inet_addr *addr, __be16 *port) |
f587de0e2 [NETFILTER]: nf_c... |
221 |
{ |
905e3e8ec [NETFILTER]: nf_c... |
222 |
const unsigned char *p; |
f587de0e2 [NETFILTER]: nf_c... |
223 224 225 226 227 228 229 |
int len; if (taddr->choice != eH245_TransportAddress_unicastAddress) return 0; switch (taddr->unicastAddress.choice) { case eUnicastAddress_iPAddress: |
5e8fbe2ac [NETFILTER]: nf_c... |
230 |
if (nf_ct_l3num(ct) != AF_INET) |
f587de0e2 [NETFILTER]: nf_c... |
231 232 233 234 235 |
return 0; p = data + taddr->unicastAddress.iPAddress.network; len = 4; break; case eUnicastAddress_iP6Address: |
5e8fbe2ac [NETFILTER]: nf_c... |
236 |
if (nf_ct_l3num(ct) != AF_INET6) |
f587de0e2 [NETFILTER]: nf_c... |
237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 |
return 0; p = data + taddr->unicastAddress.iP6Address.network; len = 16; break; default: return 0; } memcpy(addr, p, len); memset((void *)addr + len, 0, sizeof(*addr) - len); memcpy(port, p + len, sizeof(__be16)); return 1; } /****************************************************************************/ |
3db05fea5 [NETFILTER]: Repl... |
253 |
static int expect_rtp_rtcp(struct sk_buff *skb, struct nf_conn *ct, |
f587de0e2 [NETFILTER]: nf_c... |
254 255 256 257 258 259 260 261 |
enum ip_conntrack_info ctinfo, unsigned char **data, int dataoff, H245_TransportAddress *taddr) { int dir = CTINFO2DIR(ctinfo); int ret = 0; __be16 port; __be16 rtp_port, rtcp_port; |
643a2c15a [NETFILTER]: Intr... |
262 |
union nf_inet_addr addr; |
f587de0e2 [NETFILTER]: nf_c... |
263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 |
struct nf_conntrack_expect *rtp_exp; struct nf_conntrack_expect *rtcp_exp; typeof(nat_rtp_rtcp_hook) nat_rtp_rtcp; /* Read RTP or RTCP address */ if (!get_h245_addr(ct, *data, taddr, &addr, &port) || memcmp(&addr, &ct->tuplehash[dir].tuple.src.u3, sizeof(addr)) || port == 0) return 0; /* RTP port is even */ port &= htons(~1); rtp_port = port; rtcp_port = htons(ntohs(port) + 1); /* Create expect for RTP */ |
6823645d6 [NETFILTER]: nf_c... |
279 |
if ((rtp_exp = nf_ct_expect_alloc(ct)) == NULL) |
f587de0e2 [NETFILTER]: nf_c... |
280 |
return -1; |
5e8fbe2ac [NETFILTER]: nf_c... |
281 |
nf_ct_expect_init(rtp_exp, NF_CT_EXPECT_CLASS_DEFAULT, nf_ct_l3num(ct), |
6823645d6 [NETFILTER]: nf_c... |
282 283 284 |
&ct->tuplehash[!dir].tuple.src.u3, &ct->tuplehash[!dir].tuple.dst.u3, IPPROTO_UDP, NULL, &rtp_port); |
f587de0e2 [NETFILTER]: nf_c... |
285 286 |
/* Create expect for RTCP */ |
6823645d6 [NETFILTER]: nf_c... |
287 288 |
if ((rtcp_exp = nf_ct_expect_alloc(ct)) == NULL) { nf_ct_expect_put(rtp_exp); |
f587de0e2 [NETFILTER]: nf_c... |
289 290 |
return -1; } |
5e8fbe2ac [NETFILTER]: nf_c... |
291 |
nf_ct_expect_init(rtcp_exp, NF_CT_EXPECT_CLASS_DEFAULT, nf_ct_l3num(ct), |
6823645d6 [NETFILTER]: nf_c... |
292 293 294 |
&ct->tuplehash[!dir].tuple.src.u3, &ct->tuplehash[!dir].tuple.dst.u3, IPPROTO_UDP, NULL, &rtcp_port); |
f587de0e2 [NETFILTER]: nf_c... |
295 296 |
if (memcmp(&ct->tuplehash[dir].tuple.src.u3, |
601e68e10 [NETFILTER]: Fix ... |
297 |
&ct->tuplehash[!dir].tuple.dst.u3, |
f587de0e2 [NETFILTER]: nf_c... |
298 299 300 301 |
sizeof(ct->tuplehash[dir].tuple.src.u3)) && (nat_rtp_rtcp = rcu_dereference(nat_rtp_rtcp_hook)) && ct->status & IPS_NAT_MASK) { /* NAT needed */ |
3db05fea5 [NETFILTER]: Repl... |
302 |
ret = nat_rtp_rtcp(skb, ct, ctinfo, data, dataoff, |
f587de0e2 [NETFILTER]: nf_c... |
303 304 |
taddr, port, rtp_port, rtp_exp, rtcp_exp); } else { /* Conntrack only */ |
6823645d6 [NETFILTER]: nf_c... |
305 306 |
if (nf_ct_expect_related(rtp_exp) == 0) { if (nf_ct_expect_related(rtcp_exp) == 0) { |
0d53778e8 [NETFILTER]: Conv... |
307 |
pr_debug("nf_ct_h323: expect RTP "); |
3c9fba656 [NETFILTER]: nf_c... |
308 |
nf_ct_dump_tuple(&rtp_exp->tuple); |
0d53778e8 [NETFILTER]: Conv... |
309 |
pr_debug("nf_ct_h323: expect RTCP "); |
3c9fba656 [NETFILTER]: nf_c... |
310 |
nf_ct_dump_tuple(&rtcp_exp->tuple); |
f587de0e2 [NETFILTER]: nf_c... |
311 |
} else { |
6823645d6 [NETFILTER]: nf_c... |
312 |
nf_ct_unexpect_related(rtp_exp); |
f587de0e2 [NETFILTER]: nf_c... |
313 314 315 316 317 |
ret = -1; } } else ret = -1; } |
6823645d6 [NETFILTER]: nf_c... |
318 319 |
nf_ct_expect_put(rtp_exp); nf_ct_expect_put(rtcp_exp); |
f587de0e2 [NETFILTER]: nf_c... |
320 321 322 323 324 |
return ret; } /****************************************************************************/ |
3db05fea5 [NETFILTER]: Repl... |
325 |
static int expect_t120(struct sk_buff *skb, |
f587de0e2 [NETFILTER]: nf_c... |
326 327 328 329 330 331 332 333 |
struct nf_conn *ct, enum ip_conntrack_info ctinfo, unsigned char **data, int dataoff, H245_TransportAddress *taddr) { int dir = CTINFO2DIR(ctinfo); int ret = 0; __be16 port; |
643a2c15a [NETFILTER]: Intr... |
334 |
union nf_inet_addr addr; |
f587de0e2 [NETFILTER]: nf_c... |
335 336 337 338 339 340 341 342 343 344 |
struct nf_conntrack_expect *exp; typeof(nat_t120_hook) nat_t120; /* Read T.120 address */ if (!get_h245_addr(ct, *data, taddr, &addr, &port) || memcmp(&addr, &ct->tuplehash[dir].tuple.src.u3, sizeof(addr)) || port == 0) return 0; /* Create expect for T.120 connections */ |
6823645d6 [NETFILTER]: nf_c... |
345 |
if ((exp = nf_ct_expect_alloc(ct)) == NULL) |
f587de0e2 [NETFILTER]: nf_c... |
346 |
return -1; |
5e8fbe2ac [NETFILTER]: nf_c... |
347 |
nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, nf_ct_l3num(ct), |
6823645d6 [NETFILTER]: nf_c... |
348 349 350 |
&ct->tuplehash[!dir].tuple.src.u3, &ct->tuplehash[!dir].tuple.dst.u3, IPPROTO_TCP, NULL, &port); |
f587de0e2 [NETFILTER]: nf_c... |
351 352 353 354 355 356 357 358 |
exp->flags = NF_CT_EXPECT_PERMANENT; /* Accept multiple channels */ if (memcmp(&ct->tuplehash[dir].tuple.src.u3, &ct->tuplehash[!dir].tuple.dst.u3, sizeof(ct->tuplehash[dir].tuple.src.u3)) && (nat_t120 = rcu_dereference(nat_t120_hook)) && ct->status & IPS_NAT_MASK) { /* NAT needed */ |
3db05fea5 [NETFILTER]: Repl... |
359 |
ret = nat_t120(skb, ct, ctinfo, data, dataoff, taddr, |
f587de0e2 [NETFILTER]: nf_c... |
360 361 |
port, exp); } else { /* Conntrack only */ |
6823645d6 [NETFILTER]: nf_c... |
362 |
if (nf_ct_expect_related(exp) == 0) { |
0d53778e8 [NETFILTER]: Conv... |
363 |
pr_debug("nf_ct_h323: expect T.120 "); |
3c9fba656 [NETFILTER]: nf_c... |
364 |
nf_ct_dump_tuple(&exp->tuple); |
f587de0e2 [NETFILTER]: nf_c... |
365 366 367 |
} else ret = -1; } |
6823645d6 [NETFILTER]: nf_c... |
368 |
nf_ct_expect_put(exp); |
f587de0e2 [NETFILTER]: nf_c... |
369 370 371 372 373 |
return ret; } /****************************************************************************/ |
3db05fea5 [NETFILTER]: Repl... |
374 |
static int process_h245_channel(struct sk_buff *skb, |
f587de0e2 [NETFILTER]: nf_c... |
375 376 377 378 379 380 381 382 383 |
struct nf_conn *ct, enum ip_conntrack_info ctinfo, unsigned char **data, int dataoff, H2250LogicalChannelParameters *channel) { int ret; if (channel->options & eH2250LogicalChannelParameters_mediaChannel) { /* RTP */ |
3db05fea5 [NETFILTER]: Repl... |
384 |
ret = expect_rtp_rtcp(skb, ct, ctinfo, data, dataoff, |
f587de0e2 [NETFILTER]: nf_c... |
385 386 387 388 389 390 391 392 |
&channel->mediaChannel); if (ret < 0) return -1; } if (channel-> options & eH2250LogicalChannelParameters_mediaControlChannel) { /* RTCP */ |
3db05fea5 [NETFILTER]: Repl... |
393 |
ret = expect_rtp_rtcp(skb, ct, ctinfo, data, dataoff, |
f587de0e2 [NETFILTER]: nf_c... |
394 395 396 397 398 399 400 401 402 |
&channel->mediaControlChannel); if (ret < 0) return -1; } return 0; } /****************************************************************************/ |
3db05fea5 [NETFILTER]: Repl... |
403 |
static int process_olc(struct sk_buff *skb, struct nf_conn *ct, |
f587de0e2 [NETFILTER]: nf_c... |
404 405 406 407 408 |
enum ip_conntrack_info ctinfo, unsigned char **data, int dataoff, OpenLogicalChannel *olc) { int ret; |
0d53778e8 [NETFILTER]: Conv... |
409 410 |
pr_debug("nf_ct_h323: OpenLogicalChannel "); |
f587de0e2 [NETFILTER]: nf_c... |
411 412 413 414 |
if (olc->forwardLogicalChannelParameters.multiplexParameters.choice == eOpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters_h2250LogicalChannelParameters) { |
3db05fea5 [NETFILTER]: Repl... |
415 |
ret = process_h245_channel(skb, ct, ctinfo, data, dataoff, |
f587de0e2 [NETFILTER]: nf_c... |
416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 |
&olc-> forwardLogicalChannelParameters. multiplexParameters. h2250LogicalChannelParameters); if (ret < 0) return -1; } if ((olc->options & eOpenLogicalChannel_reverseLogicalChannelParameters) && (olc->reverseLogicalChannelParameters.options & eOpenLogicalChannel_reverseLogicalChannelParameters_multiplexParameters) && (olc->reverseLogicalChannelParameters.multiplexParameters. choice == eOpenLogicalChannel_reverseLogicalChannelParameters_multiplexParameters_h2250LogicalChannelParameters)) { ret = |
3db05fea5 [NETFILTER]: Repl... |
433 |
process_h245_channel(skb, ct, ctinfo, data, dataoff, |
f587de0e2 [NETFILTER]: nf_c... |
434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 |
&olc-> reverseLogicalChannelParameters. multiplexParameters. h2250LogicalChannelParameters); if (ret < 0) return -1; } if ((olc->options & eOpenLogicalChannel_separateStack) && olc->forwardLogicalChannelParameters.dataType.choice == eDataType_data && olc->forwardLogicalChannelParameters.dataType.data.application. choice == eDataApplicationCapability_application_t120 && olc->forwardLogicalChannelParameters.dataType.data.application. t120.choice == eDataProtocolCapability_separateLANStack && olc->separateStack.networkAddress.choice == eNetworkAccessParameters_networkAddress_localAreaAddress) { |
3db05fea5 [NETFILTER]: Repl... |
451 |
ret = expect_t120(skb, ct, ctinfo, data, dataoff, |
f587de0e2 [NETFILTER]: nf_c... |
452 453 454 455 456 457 458 459 460 461 |
&olc->separateStack.networkAddress. localAreaAddress); if (ret < 0) return -1; } return 0; } /****************************************************************************/ |
3db05fea5 [NETFILTER]: Repl... |
462 |
static int process_olca(struct sk_buff *skb, struct nf_conn *ct, |
f587de0e2 [NETFILTER]: nf_c... |
463 464 465 466 467 468 |
enum ip_conntrack_info ctinfo, unsigned char **data, int dataoff, OpenLogicalChannelAck *olca) { H2250LogicalChannelAckParameters *ack; int ret; |
0d53778e8 [NETFILTER]: Conv... |
469 470 |
pr_debug("nf_ct_h323: OpenLogicalChannelAck "); |
f587de0e2 [NETFILTER]: nf_c... |
471 472 473 474 475 476 477 478 479 |
if ((olca->options & eOpenLogicalChannelAck_reverseLogicalChannelParameters) && (olca->reverseLogicalChannelParameters.options & eOpenLogicalChannelAck_reverseLogicalChannelParameters_multiplexParameters) && (olca->reverseLogicalChannelParameters.multiplexParameters. choice == eOpenLogicalChannelAck_reverseLogicalChannelParameters_multiplexParameters_h2250LogicalChannelParameters)) { |
3db05fea5 [NETFILTER]: Repl... |
480 |
ret = process_h245_channel(skb, ct, ctinfo, data, dataoff, |
f587de0e2 [NETFILTER]: nf_c... |
481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 |
&olca-> reverseLogicalChannelParameters. multiplexParameters. h2250LogicalChannelParameters); if (ret < 0) return -1; } if ((olca->options & eOpenLogicalChannelAck_forwardMultiplexAckParameters) && (olca->forwardMultiplexAckParameters.choice == eOpenLogicalChannelAck_forwardMultiplexAckParameters_h2250LogicalChannelAckParameters)) { ack = &olca->forwardMultiplexAckParameters. h2250LogicalChannelAckParameters; if (ack->options & eH2250LogicalChannelAckParameters_mediaChannel) { /* RTP */ |
3db05fea5 [NETFILTER]: Repl... |
499 |
ret = expect_rtp_rtcp(skb, ct, ctinfo, data, dataoff, |
f587de0e2 [NETFILTER]: nf_c... |
500 501 502 503 504 505 506 507 |
&ack->mediaChannel); if (ret < 0) return -1; } if (ack->options & eH2250LogicalChannelAckParameters_mediaControlChannel) { /* RTCP */ |
3db05fea5 [NETFILTER]: Repl... |
508 |
ret = expect_rtp_rtcp(skb, ct, ctinfo, data, dataoff, |
f587de0e2 [NETFILTER]: nf_c... |
509 510 511 512 513 |
&ack->mediaControlChannel); if (ret < 0) return -1; } } |
f8f1c08ea [NETFILTER]: nf_c... |
514 515 516 |
if ((olca->options & eOpenLogicalChannelAck_separateStack) && olca->separateStack.networkAddress.choice == eNetworkAccessParameters_networkAddress_localAreaAddress) { |
3db05fea5 [NETFILTER]: Repl... |
517 |
ret = expect_t120(skb, ct, ctinfo, data, dataoff, |
f8f1c08ea [NETFILTER]: nf_c... |
518 519 520 521 522 |
&olca->separateStack.networkAddress. localAreaAddress); if (ret < 0) return -1; } |
f587de0e2 [NETFILTER]: nf_c... |
523 524 525 526 |
return 0; } /****************************************************************************/ |
3db05fea5 [NETFILTER]: Repl... |
527 |
static int process_h245(struct sk_buff *skb, struct nf_conn *ct, |
f587de0e2 [NETFILTER]: nf_c... |
528 529 530 531 532 533 534 535 |
enum ip_conntrack_info ctinfo, unsigned char **data, int dataoff, MultimediaSystemControlMessage *mscm) { switch (mscm->choice) { case eMultimediaSystemControlMessage_request: if (mscm->request.choice == eRequestMessage_openLogicalChannel) { |
3db05fea5 [NETFILTER]: Repl... |
536 |
return process_olc(skb, ct, ctinfo, data, dataoff, |
f587de0e2 [NETFILTER]: nf_c... |
537 538 |
&mscm->request.openLogicalChannel); } |
0d53778e8 [NETFILTER]: Conv... |
539 540 541 |
pr_debug("nf_ct_h323: H.245 Request %d ", mscm->request.choice); |
f587de0e2 [NETFILTER]: nf_c... |
542 543 544 545 |
break; case eMultimediaSystemControlMessage_response: if (mscm->response.choice == eResponseMessage_openLogicalChannelAck) { |
3db05fea5 [NETFILTER]: Repl... |
546 |
return process_olca(skb, ct, ctinfo, data, dataoff, |
f587de0e2 [NETFILTER]: nf_c... |
547 548 549 |
&mscm->response. openLogicalChannelAck); } |
0d53778e8 [NETFILTER]: Conv... |
550 551 552 |
pr_debug("nf_ct_h323: H.245 Response %d ", mscm->response.choice); |
f587de0e2 [NETFILTER]: nf_c... |
553 554 |
break; default: |
0d53778e8 [NETFILTER]: Conv... |
555 556 |
pr_debug("nf_ct_h323: H.245 signal %d ", mscm->choice); |
f587de0e2 [NETFILTER]: nf_c... |
557 558 559 560 561 562 563 |
break; } return 0; } /****************************************************************************/ |
3db05fea5 [NETFILTER]: Repl... |
564 |
static int h245_help(struct sk_buff *skb, unsigned int protoff, |
f587de0e2 [NETFILTER]: nf_c... |
565 566 567 568 569 570 571 572 573 |
struct nf_conn *ct, enum ip_conntrack_info ctinfo) { static MultimediaSystemControlMessage mscm; unsigned char *data = NULL; int datalen; int dataoff; int ret; /* Until there's been traffic both ways, don't look in packets. */ |
fb0488337 netfilter: add mo... |
574 |
if (ctinfo != IP_CT_ESTABLISHED && ctinfo != IP_CT_ESTABLISHED_REPLY) |
f587de0e2 [NETFILTER]: nf_c... |
575 |
return NF_ACCEPT; |
fb0488337 netfilter: add mo... |
576 |
|
3db05fea5 [NETFILTER]: Repl... |
577 578 |
pr_debug("nf_ct_h245: skblen = %u ", skb->len); |
f587de0e2 [NETFILTER]: nf_c... |
579 580 581 582 |
spin_lock_bh(&nf_h323_lock); /* Process each TPKT */ |
3db05fea5 [NETFILTER]: Repl... |
583 |
while (get_tpkt_data(skb, protoff, ct, ctinfo, |
f587de0e2 [NETFILTER]: nf_c... |
584 |
&data, &datalen, &dataoff)) { |
0d53778e8 [NETFILTER]: Conv... |
585 |
pr_debug("nf_ct_h245: TPKT len=%d ", datalen); |
3c9fba656 [NETFILTER]: nf_c... |
586 |
nf_ct_dump_tuple(&ct->tuplehash[CTINFO2DIR(ctinfo)].tuple); |
f587de0e2 [NETFILTER]: nf_c... |
587 588 589 590 591 |
/* Decode H.245 signal */ ret = DecodeMultimediaSystemControlMessage(data, datalen, &mscm); if (ret < 0) { |
0d53778e8 [NETFILTER]: Conv... |
592 593 594 595 |
pr_debug("nf_ct_h245: decoding error: %s ", ret == H323_ERROR_BOUND ? "out of bound" : "out of range"); |
f587de0e2 [NETFILTER]: nf_c... |
596 597 598 599 600 |
/* We don't drop when decoding error */ break; } /* Process H.245 signal */ |
3db05fea5 [NETFILTER]: Repl... |
601 |
if (process_h245(skb, ct, ctinfo, &data, dataoff, &mscm) < 0) |
f587de0e2 [NETFILTER]: nf_c... |
602 603 604 605 606 607 608 609 610 |
goto drop; } spin_unlock_bh(&nf_h323_lock); return NF_ACCEPT; drop: spin_unlock_bh(&nf_h323_lock); if (net_ratelimit()) |
654d0fbdc netfilter: cleanu... |
611 612 |
pr_info("nf_ct_h245: packet dropped "); |
f587de0e2 [NETFILTER]: nf_c... |
613 614 615 616 |
return NF_DROP; } /****************************************************************************/ |
6002f266b [NETFILTER]: nf_c... |
617 618 619 620 |
static const struct nf_conntrack_expect_policy h245_exp_policy = { .max_expected = H323_RTP_CHANNEL_MAX * 4 + 2 /* T.120 */, .timeout = 240, }; |
f587de0e2 [NETFILTER]: nf_c... |
621 622 623 |
static struct nf_conntrack_helper nf_conntrack_helper_h245 __read_mostly = { .name = "H.245", .me = THIS_MODULE, |
a56b8f815 netfilter: nf_con... |
624 |
.tuple.src.l3num = AF_UNSPEC, |
f587de0e2 [NETFILTER]: nf_c... |
625 |
.tuple.dst.protonum = IPPROTO_UDP, |
6002f266b [NETFILTER]: nf_c... |
626 627 |
.help = h245_help, .expect_policy = &h245_exp_policy, |
f587de0e2 [NETFILTER]: nf_c... |
628 629 630 631 632 |
}; /****************************************************************************/ int get_h225_addr(struct nf_conn *ct, unsigned char *data, TransportAddress *taddr, |
643a2c15a [NETFILTER]: Intr... |
633 |
union nf_inet_addr *addr, __be16 *port) |
f587de0e2 [NETFILTER]: nf_c... |
634 |
{ |
905e3e8ec [NETFILTER]: nf_c... |
635 |
const unsigned char *p; |
f587de0e2 [NETFILTER]: nf_c... |
636 637 638 639 |
int len; switch (taddr->choice) { case eTransportAddress_ipAddress: |
5e8fbe2ac [NETFILTER]: nf_c... |
640 |
if (nf_ct_l3num(ct) != AF_INET) |
f587de0e2 [NETFILTER]: nf_c... |
641 642 643 644 645 |
return 0; p = data + taddr->ipAddress.ip; len = 4; break; case eTransportAddress_ip6Address: |
5e8fbe2ac [NETFILTER]: nf_c... |
646 |
if (nf_ct_l3num(ct) != AF_INET6) |
f587de0e2 [NETFILTER]: nf_c... |
647 |
return 0; |
bb807245e [NETFILTER]: nf_c... |
648 |
p = data + taddr->ip6Address.ip; |
f587de0e2 [NETFILTER]: nf_c... |
649 650 651 652 653 654 655 656 657 658 659 660 661 662 |
len = 16; break; default: return 0; } memcpy(addr, p, len); memset((void *)addr + len, 0, sizeof(*addr) - len); memcpy(port, p + len, sizeof(__be16)); return 1; } /****************************************************************************/ |
3db05fea5 [NETFILTER]: Repl... |
663 |
static int expect_h245(struct sk_buff *skb, struct nf_conn *ct, |
f587de0e2 [NETFILTER]: nf_c... |
664 665 666 667 668 669 670 |
enum ip_conntrack_info ctinfo, unsigned char **data, int dataoff, TransportAddress *taddr) { int dir = CTINFO2DIR(ctinfo); int ret = 0; __be16 port; |
643a2c15a [NETFILTER]: Intr... |
671 |
union nf_inet_addr addr; |
f587de0e2 [NETFILTER]: nf_c... |
672 673 674 675 676 677 678 679 680 681 |
struct nf_conntrack_expect *exp; typeof(nat_h245_hook) nat_h245; /* Read h245Address */ if (!get_h225_addr(ct, *data, taddr, &addr, &port) || memcmp(&addr, &ct->tuplehash[dir].tuple.src.u3, sizeof(addr)) || port == 0) return 0; /* Create expect for h245 connection */ |
6823645d6 [NETFILTER]: nf_c... |
682 |
if ((exp = nf_ct_expect_alloc(ct)) == NULL) |
f587de0e2 [NETFILTER]: nf_c... |
683 |
return -1; |
5e8fbe2ac [NETFILTER]: nf_c... |
684 |
nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, nf_ct_l3num(ct), |
6823645d6 [NETFILTER]: nf_c... |
685 686 687 |
&ct->tuplehash[!dir].tuple.src.u3, &ct->tuplehash[!dir].tuple.dst.u3, IPPROTO_TCP, NULL, &port); |
f587de0e2 [NETFILTER]: nf_c... |
688 689 690 691 692 693 694 695 |
exp->helper = &nf_conntrack_helper_h245; if (memcmp(&ct->tuplehash[dir].tuple.src.u3, &ct->tuplehash[!dir].tuple.dst.u3, sizeof(ct->tuplehash[dir].tuple.src.u3)) && (nat_h245 = rcu_dereference(nat_h245_hook)) && ct->status & IPS_NAT_MASK) { /* NAT needed */ |
3db05fea5 [NETFILTER]: Repl... |
696 |
ret = nat_h245(skb, ct, ctinfo, data, dataoff, taddr, |
f587de0e2 [NETFILTER]: nf_c... |
697 698 |
port, exp); } else { /* Conntrack only */ |
6823645d6 [NETFILTER]: nf_c... |
699 |
if (nf_ct_expect_related(exp) == 0) { |
0d53778e8 [NETFILTER]: Conv... |
700 |
pr_debug("nf_ct_q931: expect H.245 "); |
3c9fba656 [NETFILTER]: nf_c... |
701 |
nf_ct_dump_tuple(&exp->tuple); |
f587de0e2 [NETFILTER]: nf_c... |
702 703 704 |
} else ret = -1; } |
6823645d6 [NETFILTER]: nf_c... |
705 |
nf_ct_expect_put(exp); |
f587de0e2 [NETFILTER]: nf_c... |
706 707 708 709 710 711 |
return ret; } /* If the calling party is on the same side of the forward-to party, * we don't need to track the second call */ |
905e3e8ec [NETFILTER]: nf_c... |
712 |
static int callforward_do_filter(const union nf_inet_addr *src, |
76108cea0 netfilter: Use un... |
713 714 |
const union nf_inet_addr *dst, u_int8_t family) |
f587de0e2 [NETFILTER]: nf_c... |
715 |
{ |
1e796fda0 [NETFILTER]: cons... |
716 |
const struct nf_afinfo *afinfo; |
f587de0e2 [NETFILTER]: nf_c... |
717 |
int ret = 0; |
1841a4c7a [NETFILTER]: nf_c... |
718 719 720 721 |
/* rcu_read_lock()ed by nf_hook_slow() */ afinfo = nf_get_afinfo(family); if (!afinfo) return 0; |
f587de0e2 [NETFILTER]: nf_c... |
722 723 |
switch (family) { case AF_INET: { |
5a49d0e04 netfilter: Use fl... |
724 |
struct flowi4 fl1, fl2; |
f587de0e2 [NETFILTER]: nf_c... |
725 |
struct rtable *rt1, *rt2; |
5a49d0e04 netfilter: Use fl... |
726 727 728 729 730 |
memset(&fl1, 0, sizeof(fl1)); fl1.daddr = src->ip; memset(&fl2, 0, sizeof(fl2)); fl2.daddr = dst->ip; |
31ad3dd64 netfilter: af_inf... |
731 |
if (!afinfo->route(&init_net, (struct dst_entry **)&rt1, |
0fae2e774 netfilter: af_inf... |
732 |
flowi4_to_flowi(&fl1), false)) { |
31ad3dd64 netfilter: af_inf... |
733 |
if (!afinfo->route(&init_net, (struct dst_entry **)&rt2, |
0fae2e774 netfilter: af_inf... |
734 |
flowi4_to_flowi(&fl2), false)) { |
f587de0e2 [NETFILTER]: nf_c... |
735 |
if (rt1->rt_gateway == rt2->rt_gateway && |
d8d1f30b9 net-next: remove ... |
736 |
rt1->dst.dev == rt2->dst.dev) |
f587de0e2 [NETFILTER]: nf_c... |
737 |
ret = 1; |
d8d1f30b9 net-next: remove ... |
738 |
dst_release(&rt2->dst); |
f587de0e2 [NETFILTER]: nf_c... |
739 |
} |
d8d1f30b9 net-next: remove ... |
740 |
dst_release(&rt1->dst); |
f587de0e2 [NETFILTER]: nf_c... |
741 742 743 |
} break; } |
c0cd11566 net:netfilter: us... |
744 |
#if IS_ENABLED(CONFIG_NF_CONNTRACK_IPV6) |
f587de0e2 [NETFILTER]: nf_c... |
745 |
case AF_INET6: { |
5a49d0e04 netfilter: Use fl... |
746 |
struct flowi6 fl1, fl2; |
f587de0e2 [NETFILTER]: nf_c... |
747 |
struct rt6_info *rt1, *rt2; |
5a49d0e04 netfilter: Use fl... |
748 |
memset(&fl1, 0, sizeof(fl1)); |
4e3fd7a06 net: remove ipv6_... |
749 |
fl1.daddr = src->in6; |
5a49d0e04 netfilter: Use fl... |
750 751 |
memset(&fl2, 0, sizeof(fl2)); |
4e3fd7a06 net: remove ipv6_... |
752 |
fl2.daddr = dst->in6; |
31ad3dd64 netfilter: af_inf... |
753 |
if (!afinfo->route(&init_net, (struct dst_entry **)&rt1, |
0fae2e774 netfilter: af_inf... |
754 |
flowi6_to_flowi(&fl1), false)) { |
31ad3dd64 netfilter: af_inf... |
755 |
if (!afinfo->route(&init_net, (struct dst_entry **)&rt2, |
0fae2e774 netfilter: af_inf... |
756 |
flowi6_to_flowi(&fl2), false)) { |
f587de0e2 [NETFILTER]: nf_c... |
757 |
if (!memcmp(&rt1->rt6i_gateway, &rt2->rt6i_gateway, |
601e68e10 [NETFILTER]: Fix ... |
758 |
sizeof(rt1->rt6i_gateway)) && |
d8d1f30b9 net-next: remove ... |
759 |
rt1->dst.dev == rt2->dst.dev) |
f587de0e2 [NETFILTER]: nf_c... |
760 |
ret = 1; |
d8d1f30b9 net-next: remove ... |
761 |
dst_release(&rt2->dst); |
f587de0e2 [NETFILTER]: nf_c... |
762 |
} |
d8d1f30b9 net-next: remove ... |
763 |
dst_release(&rt1->dst); |
f587de0e2 [NETFILTER]: nf_c... |
764 765 766 767 768 769 770 771 772 773 |
} break; } #endif } return ret; } /****************************************************************************/ |
3db05fea5 [NETFILTER]: Repl... |
774 |
static int expect_callforwarding(struct sk_buff *skb, |
f587de0e2 [NETFILTER]: nf_c... |
775 776 777 778 779 780 781 782 |
struct nf_conn *ct, enum ip_conntrack_info ctinfo, unsigned char **data, int dataoff, TransportAddress *taddr) { int dir = CTINFO2DIR(ctinfo); int ret = 0; __be16 port; |
643a2c15a [NETFILTER]: Intr... |
783 |
union nf_inet_addr addr; |
f587de0e2 [NETFILTER]: nf_c... |
784 785 786 787 788 789 790 791 792 793 794 |
struct nf_conntrack_expect *exp; typeof(nat_callforwarding_hook) nat_callforwarding; /* Read alternativeAddress */ if (!get_h225_addr(ct, *data, taddr, &addr, &port) || port == 0) return 0; /* If the calling party is on the same side of the forward-to party, * we don't need to track the second call */ if (callforward_filter && callforward_do_filter(&addr, &ct->tuplehash[!dir].tuple.src.u3, |
5e8fbe2ac [NETFILTER]: nf_c... |
795 |
nf_ct_l3num(ct))) { |
0d53778e8 [NETFILTER]: Conv... |
796 797 |
pr_debug("nf_ct_q931: Call Forwarding not tracked "); |
f587de0e2 [NETFILTER]: nf_c... |
798 799 800 801 |
return 0; } /* Create expect for the second call leg */ |
6823645d6 [NETFILTER]: nf_c... |
802 |
if ((exp = nf_ct_expect_alloc(ct)) == NULL) |
f587de0e2 [NETFILTER]: nf_c... |
803 |
return -1; |
5e8fbe2ac [NETFILTER]: nf_c... |
804 |
nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, nf_ct_l3num(ct), |
6823645d6 [NETFILTER]: nf_c... |
805 806 |
&ct->tuplehash[!dir].tuple.src.u3, &addr, IPPROTO_TCP, NULL, &port); |
f587de0e2 [NETFILTER]: nf_c... |
807 808 809 810 811 812 813 814 |
exp->helper = nf_conntrack_helper_q931; if (memcmp(&ct->tuplehash[dir].tuple.src.u3, &ct->tuplehash[!dir].tuple.dst.u3, sizeof(ct->tuplehash[dir].tuple.src.u3)) && (nat_callforwarding = rcu_dereference(nat_callforwarding_hook)) && ct->status & IPS_NAT_MASK) { /* Need NAT */ |
3db05fea5 [NETFILTER]: Repl... |
815 |
ret = nat_callforwarding(skb, ct, ctinfo, data, dataoff, |
f587de0e2 [NETFILTER]: nf_c... |
816 817 |
taddr, port, exp); } else { /* Conntrack only */ |
6823645d6 [NETFILTER]: nf_c... |
818 |
if (nf_ct_expect_related(exp) == 0) { |
0d53778e8 [NETFILTER]: Conv... |
819 |
pr_debug("nf_ct_q931: expect Call Forwarding "); |
3c9fba656 [NETFILTER]: nf_c... |
820 |
nf_ct_dump_tuple(&exp->tuple); |
f587de0e2 [NETFILTER]: nf_c... |
821 822 823 |
} else ret = -1; } |
6823645d6 [NETFILTER]: nf_c... |
824 |
nf_ct_expect_put(exp); |
f587de0e2 [NETFILTER]: nf_c... |
825 826 827 828 829 |
return ret; } /****************************************************************************/ |
3db05fea5 [NETFILTER]: Repl... |
830 |
static int process_setup(struct sk_buff *skb, struct nf_conn *ct, |
f587de0e2 [NETFILTER]: nf_c... |
831 832 833 834 835 836 837 838 |
enum ip_conntrack_info ctinfo, unsigned char **data, int dataoff, Setup_UUIE *setup) { int dir = CTINFO2DIR(ctinfo); int ret; int i; __be16 port; |
643a2c15a [NETFILTER]: Intr... |
839 |
union nf_inet_addr addr; |
f587de0e2 [NETFILTER]: nf_c... |
840 |
typeof(set_h225_addr_hook) set_h225_addr; |
0d53778e8 [NETFILTER]: Conv... |
841 842 |
pr_debug("nf_ct_q931: Setup "); |
f587de0e2 [NETFILTER]: nf_c... |
843 844 |
if (setup->options & eSetup_UUIE_h245Address) { |
3db05fea5 [NETFILTER]: Repl... |
845 |
ret = expect_h245(skb, ct, ctinfo, data, dataoff, |
f587de0e2 [NETFILTER]: nf_c... |
846 847 848 849 850 851 852 |
&setup->h245Address); if (ret < 0) return -1; } set_h225_addr = rcu_dereference(set_h225_addr_hook); if ((setup->options & eSetup_UUIE_destCallSignalAddress) && |
6aebb9b28 [NETFILTER]: nf_c... |
853 |
(set_h225_addr) && ct->status & IPS_NAT_MASK && |
f587de0e2 [NETFILTER]: nf_c... |
854 |
get_h225_addr(ct, *data, &setup->destCallSignalAddress, |
601e68e10 [NETFILTER]: Fix ... |
855 |
&addr, &port) && |
f587de0e2 [NETFILTER]: nf_c... |
856 |
memcmp(&addr, &ct->tuplehash[!dir].tuple.src.u3, sizeof(addr))) { |
5b095d989 net: replace %p6 ... |
857 858 |
pr_debug("nf_ct_q931: set destCallSignalAddress %pI6:%hu->%pI6:%hu ", |
38ff4fa49 netfilter: replac... |
859 |
&addr, ntohs(port), &ct->tuplehash[!dir].tuple.src.u3, |
0d53778e8 [NETFILTER]: Conv... |
860 |
ntohs(ct->tuplehash[!dir].tuple.src.u.tcp.port)); |
3db05fea5 [NETFILTER]: Repl... |
861 |
ret = set_h225_addr(skb, data, dataoff, |
f587de0e2 [NETFILTER]: nf_c... |
862 863 864 865 866 867 868 869 870 871 |
&setup->destCallSignalAddress, &ct->tuplehash[!dir].tuple.src.u3, ct->tuplehash[!dir].tuple.src.u.tcp.port); if (ret < 0) return -1; } if ((setup->options & eSetup_UUIE_sourceCallSignalAddress) && (set_h225_addr) && ct->status & IPS_NAT_MASK && get_h225_addr(ct, *data, &setup->sourceCallSignalAddress, |
601e68e10 [NETFILTER]: Fix ... |
872 |
&addr, &port) && |
f587de0e2 [NETFILTER]: nf_c... |
873 |
memcmp(&addr, &ct->tuplehash[!dir].tuple.dst.u3, sizeof(addr))) { |
5b095d989 net: replace %p6 ... |
874 875 |
pr_debug("nf_ct_q931: set sourceCallSignalAddress %pI6:%hu->%pI6:%hu ", |
38ff4fa49 netfilter: replac... |
876 |
&addr, ntohs(port), &ct->tuplehash[!dir].tuple.dst.u3, |
0d53778e8 [NETFILTER]: Conv... |
877 |
ntohs(ct->tuplehash[!dir].tuple.dst.u.tcp.port)); |
3db05fea5 [NETFILTER]: Repl... |
878 |
ret = set_h225_addr(skb, data, dataoff, |
f587de0e2 [NETFILTER]: nf_c... |
879 880 881 882 883 884 885 886 887 |
&setup->sourceCallSignalAddress, &ct->tuplehash[!dir].tuple.dst.u3, ct->tuplehash[!dir].tuple.dst.u.tcp.port); if (ret < 0) return -1; } if (setup->options & eSetup_UUIE_fastStart) { for (i = 0; i < setup->fastStart.count; i++) { |
3db05fea5 [NETFILTER]: Repl... |
888 |
ret = process_olc(skb, ct, ctinfo, data, dataoff, |
f587de0e2 [NETFILTER]: nf_c... |
889 890 891 892 893 894 895 896 897 898 |
&setup->fastStart.item[i]); if (ret < 0) return -1; } } return 0; } /****************************************************************************/ |
3db05fea5 [NETFILTER]: Repl... |
899 |
static int process_callproceeding(struct sk_buff *skb, |
f587de0e2 [NETFILTER]: nf_c... |
900 901 902 903 904 905 906 |
struct nf_conn *ct, enum ip_conntrack_info ctinfo, unsigned char **data, int dataoff, CallProceeding_UUIE *callproc) { int ret; int i; |
0d53778e8 [NETFILTER]: Conv... |
907 908 |
pr_debug("nf_ct_q931: CallProceeding "); |
f587de0e2 [NETFILTER]: nf_c... |
909 910 |
if (callproc->options & eCallProceeding_UUIE_h245Address) { |
3db05fea5 [NETFILTER]: Repl... |
911 |
ret = expect_h245(skb, ct, ctinfo, data, dataoff, |
f587de0e2 [NETFILTER]: nf_c... |
912 913 914 915 916 917 918 |
&callproc->h245Address); if (ret < 0) return -1; } if (callproc->options & eCallProceeding_UUIE_fastStart) { for (i = 0; i < callproc->fastStart.count; i++) { |
3db05fea5 [NETFILTER]: Repl... |
919 |
ret = process_olc(skb, ct, ctinfo, data, dataoff, |
f587de0e2 [NETFILTER]: nf_c... |
920 921 922 923 924 925 926 927 928 929 |
&callproc->fastStart.item[i]); if (ret < 0) return -1; } } return 0; } /****************************************************************************/ |
3db05fea5 [NETFILTER]: Repl... |
930 |
static int process_connect(struct sk_buff *skb, struct nf_conn *ct, |
f587de0e2 [NETFILTER]: nf_c... |
931 932 933 934 935 936 |
enum ip_conntrack_info ctinfo, unsigned char **data, int dataoff, Connect_UUIE *connect) { int ret; int i; |
0d53778e8 [NETFILTER]: Conv... |
937 938 |
pr_debug("nf_ct_q931: Connect "); |
f587de0e2 [NETFILTER]: nf_c... |
939 940 |
if (connect->options & eConnect_UUIE_h245Address) { |
3db05fea5 [NETFILTER]: Repl... |
941 |
ret = expect_h245(skb, ct, ctinfo, data, dataoff, |
f587de0e2 [NETFILTER]: nf_c... |
942 943 944 945 946 947 948 |
&connect->h245Address); if (ret < 0) return -1; } if (connect->options & eConnect_UUIE_fastStart) { for (i = 0; i < connect->fastStart.count; i++) { |
3db05fea5 [NETFILTER]: Repl... |
949 |
ret = process_olc(skb, ct, ctinfo, data, dataoff, |
f587de0e2 [NETFILTER]: nf_c... |
950 951 952 953 954 955 956 957 958 959 |
&connect->fastStart.item[i]); if (ret < 0) return -1; } } return 0; } /****************************************************************************/ |
3db05fea5 [NETFILTER]: Repl... |
960 |
static int process_alerting(struct sk_buff *skb, struct nf_conn *ct, |
f587de0e2 [NETFILTER]: nf_c... |
961 962 963 964 965 966 |
enum ip_conntrack_info ctinfo, unsigned char **data, int dataoff, Alerting_UUIE *alert) { int ret; int i; |
0d53778e8 [NETFILTER]: Conv... |
967 968 |
pr_debug("nf_ct_q931: Alerting "); |
f587de0e2 [NETFILTER]: nf_c... |
969 970 |
if (alert->options & eAlerting_UUIE_h245Address) { |
3db05fea5 [NETFILTER]: Repl... |
971 |
ret = expect_h245(skb, ct, ctinfo, data, dataoff, |
f587de0e2 [NETFILTER]: nf_c... |
972 973 974 975 976 977 978 |
&alert->h245Address); if (ret < 0) return -1; } if (alert->options & eAlerting_UUIE_fastStart) { for (i = 0; i < alert->fastStart.count; i++) { |
3db05fea5 [NETFILTER]: Repl... |
979 |
ret = process_olc(skb, ct, ctinfo, data, dataoff, |
f587de0e2 [NETFILTER]: nf_c... |
980 981 982 983 984 985 986 987 988 989 |
&alert->fastStart.item[i]); if (ret < 0) return -1; } } return 0; } /****************************************************************************/ |
3db05fea5 [NETFILTER]: Repl... |
990 |
static int process_facility(struct sk_buff *skb, struct nf_conn *ct, |
f587de0e2 [NETFILTER]: nf_c... |
991 992 993 994 995 996 |
enum ip_conntrack_info ctinfo, unsigned char **data, int dataoff, Facility_UUIE *facility) { int ret; int i; |
0d53778e8 [NETFILTER]: Conv... |
997 998 |
pr_debug("nf_ct_q931: Facility "); |
f587de0e2 [NETFILTER]: nf_c... |
999 1000 1001 |
if (facility->reason.choice == eFacilityReason_callForwarded) { if (facility->options & eFacility_UUIE_alternativeAddress) |
3db05fea5 [NETFILTER]: Repl... |
1002 |
return expect_callforwarding(skb, ct, ctinfo, data, |
f587de0e2 [NETFILTER]: nf_c... |
1003 1004 1005 1006 1007 1008 1009 |
dataoff, &facility-> alternativeAddress); return 0; } if (facility->options & eFacility_UUIE_h245Address) { |
3db05fea5 [NETFILTER]: Repl... |
1010 |
ret = expect_h245(skb, ct, ctinfo, data, dataoff, |
f587de0e2 [NETFILTER]: nf_c... |
1011 1012 1013 1014 1015 1016 1017 |
&facility->h245Address); if (ret < 0) return -1; } if (facility->options & eFacility_UUIE_fastStart) { for (i = 0; i < facility->fastStart.count; i++) { |
3db05fea5 [NETFILTER]: Repl... |
1018 |
ret = process_olc(skb, ct, ctinfo, data, dataoff, |
f587de0e2 [NETFILTER]: nf_c... |
1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 |
&facility->fastStart.item[i]); if (ret < 0) return -1; } } return 0; } /****************************************************************************/ |
3db05fea5 [NETFILTER]: Repl... |
1029 |
static int process_progress(struct sk_buff *skb, struct nf_conn *ct, |
f587de0e2 [NETFILTER]: nf_c... |
1030 1031 1032 1033 1034 1035 |
enum ip_conntrack_info ctinfo, unsigned char **data, int dataoff, Progress_UUIE *progress) { int ret; int i; |
0d53778e8 [NETFILTER]: Conv... |
1036 1037 |
pr_debug("nf_ct_q931: Progress "); |
f587de0e2 [NETFILTER]: nf_c... |
1038 1039 |
if (progress->options & eProgress_UUIE_h245Address) { |
3db05fea5 [NETFILTER]: Repl... |
1040 |
ret = expect_h245(skb, ct, ctinfo, data, dataoff, |
f587de0e2 [NETFILTER]: nf_c... |
1041 1042 1043 1044 1045 1046 1047 |
&progress->h245Address); if (ret < 0) return -1; } if (progress->options & eProgress_UUIE_fastStart) { for (i = 0; i < progress->fastStart.count; i++) { |
3db05fea5 [NETFILTER]: Repl... |
1048 |
ret = process_olc(skb, ct, ctinfo, data, dataoff, |
f587de0e2 [NETFILTER]: nf_c... |
1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 |
&progress->fastStart.item[i]); if (ret < 0) return -1; } } return 0; } /****************************************************************************/ |
3db05fea5 [NETFILTER]: Repl... |
1059 |
static int process_q931(struct sk_buff *skb, struct nf_conn *ct, |
f587de0e2 [NETFILTER]: nf_c... |
1060 1061 1062 1063 1064 1065 1066 1067 1068 |
enum ip_conntrack_info ctinfo, unsigned char **data, int dataoff, Q931 *q931) { H323_UU_PDU *pdu = &q931->UUIE.h323_uu_pdu; int i; int ret = 0; switch (pdu->h323_message_body.choice) { case eH323_UU_PDU_h323_message_body_setup: |
3db05fea5 [NETFILTER]: Repl... |
1069 |
ret = process_setup(skb, ct, ctinfo, data, dataoff, |
f587de0e2 [NETFILTER]: nf_c... |
1070 1071 1072 |
&pdu->h323_message_body.setup); break; case eH323_UU_PDU_h323_message_body_callProceeding: |
3db05fea5 [NETFILTER]: Repl... |
1073 |
ret = process_callproceeding(skb, ct, ctinfo, data, dataoff, |
f587de0e2 [NETFILTER]: nf_c... |
1074 1075 1076 1077 |
&pdu->h323_message_body. callProceeding); break; case eH323_UU_PDU_h323_message_body_connect: |
3db05fea5 [NETFILTER]: Repl... |
1078 |
ret = process_connect(skb, ct, ctinfo, data, dataoff, |
f587de0e2 [NETFILTER]: nf_c... |
1079 1080 1081 |
&pdu->h323_message_body.connect); break; case eH323_UU_PDU_h323_message_body_alerting: |
3db05fea5 [NETFILTER]: Repl... |
1082 |
ret = process_alerting(skb, ct, ctinfo, data, dataoff, |
f587de0e2 [NETFILTER]: nf_c... |
1083 1084 |
&pdu->h323_message_body.alerting); break; |
f587de0e2 [NETFILTER]: nf_c... |
1085 |
case eH323_UU_PDU_h323_message_body_facility: |
3db05fea5 [NETFILTER]: Repl... |
1086 |
ret = process_facility(skb, ct, ctinfo, data, dataoff, |
f587de0e2 [NETFILTER]: nf_c... |
1087 1088 1089 |
&pdu->h323_message_body.facility); break; case eH323_UU_PDU_h323_message_body_progress: |
3db05fea5 [NETFILTER]: Repl... |
1090 |
ret = process_progress(skb, ct, ctinfo, data, dataoff, |
f587de0e2 [NETFILTER]: nf_c... |
1091 1092 1093 |
&pdu->h323_message_body.progress); break; default: |
0d53778e8 [NETFILTER]: Conv... |
1094 1095 1096 |
pr_debug("nf_ct_q931: Q.931 signal %d ", pdu->h323_message_body.choice); |
f587de0e2 [NETFILTER]: nf_c... |
1097 1098 1099 1100 1101 1102 1103 1104 |
break; } if (ret < 0) return -1; if (pdu->options & eH323_UU_PDU_h245Control) { for (i = 0; i < pdu->h245Control.count; i++) { |
3db05fea5 [NETFILTER]: Repl... |
1105 |
ret = process_h245(skb, ct, ctinfo, data, dataoff, |
f587de0e2 [NETFILTER]: nf_c... |
1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 |
&pdu->h245Control.item[i]); if (ret < 0) return -1; } } return 0; } /****************************************************************************/ |
3db05fea5 [NETFILTER]: Repl... |
1116 |
static int q931_help(struct sk_buff *skb, unsigned int protoff, |
f587de0e2 [NETFILTER]: nf_c... |
1117 1118 1119 1120 1121 1122 1123 1124 1125 |
struct nf_conn *ct, enum ip_conntrack_info ctinfo) { static Q931 q931; unsigned char *data = NULL; int datalen; int dataoff; int ret; /* Until there's been traffic both ways, don't look in packets. */ |
fb0488337 netfilter: add mo... |
1126 |
if (ctinfo != IP_CT_ESTABLISHED && ctinfo != IP_CT_ESTABLISHED_REPLY) |
f587de0e2 [NETFILTER]: nf_c... |
1127 |
return NF_ACCEPT; |
fb0488337 netfilter: add mo... |
1128 |
|
3db05fea5 [NETFILTER]: Repl... |
1129 1130 |
pr_debug("nf_ct_q931: skblen = %u ", skb->len); |
f587de0e2 [NETFILTER]: nf_c... |
1131 1132 1133 1134 |
spin_lock_bh(&nf_h323_lock); /* Process each TPKT */ |
3db05fea5 [NETFILTER]: Repl... |
1135 |
while (get_tpkt_data(skb, protoff, ct, ctinfo, |
f587de0e2 [NETFILTER]: nf_c... |
1136 |
&data, &datalen, &dataoff)) { |
0d53778e8 [NETFILTER]: Conv... |
1137 |
pr_debug("nf_ct_q931: TPKT len=%d ", datalen); |
3c9fba656 [NETFILTER]: nf_c... |
1138 |
nf_ct_dump_tuple(&ct->tuplehash[CTINFO2DIR(ctinfo)].tuple); |
f587de0e2 [NETFILTER]: nf_c... |
1139 1140 1141 1142 |
/* Decode Q.931 signal */ ret = DecodeQ931(data, datalen, &q931); if (ret < 0) { |
0d53778e8 [NETFILTER]: Conv... |
1143 1144 1145 1146 |
pr_debug("nf_ct_q931: decoding error: %s ", ret == H323_ERROR_BOUND ? "out of bound" : "out of range"); |
f587de0e2 [NETFILTER]: nf_c... |
1147 1148 1149 1150 1151 |
/* We don't drop when decoding error */ break; } /* Process Q.931 signal */ |
3db05fea5 [NETFILTER]: Repl... |
1152 |
if (process_q931(skb, ct, ctinfo, &data, dataoff, &q931) < 0) |
f587de0e2 [NETFILTER]: nf_c... |
1153 1154 1155 1156 1157 1158 1159 1160 1161 |
goto drop; } spin_unlock_bh(&nf_h323_lock); return NF_ACCEPT; drop: spin_unlock_bh(&nf_h323_lock); if (net_ratelimit()) |
654d0fbdc netfilter: cleanu... |
1162 1163 |
pr_info("nf_ct_q931: packet dropped "); |
f587de0e2 [NETFILTER]: nf_c... |
1164 1165 1166 1167 |
return NF_DROP; } /****************************************************************************/ |
6002f266b [NETFILTER]: nf_c... |
1168 1169 1170 1171 1172 |
static const struct nf_conntrack_expect_policy q931_exp_policy = { /* T.120 and H.245 */ .max_expected = H323_RTP_CHANNEL_MAX * 4 + 4, .timeout = 240, }; |
f587de0e2 [NETFILTER]: nf_c... |
1173 1174 1175 1176 |
static struct nf_conntrack_helper nf_conntrack_helper_q931[] __read_mostly = { { .name = "Q.931", .me = THIS_MODULE, |
f587de0e2 [NETFILTER]: nf_c... |
1177 |
.tuple.src.l3num = AF_INET, |
09640e636 net: replace uses... |
1178 |
.tuple.src.u.tcp.port = cpu_to_be16(Q931_PORT), |
f587de0e2 [NETFILTER]: nf_c... |
1179 |
.tuple.dst.protonum = IPPROTO_TCP, |
6002f266b [NETFILTER]: nf_c... |
1180 1181 |
.help = q931_help, .expect_policy = &q931_exp_policy, |
f587de0e2 [NETFILTER]: nf_c... |
1182 1183 1184 1185 |
}, { .name = "Q.931", .me = THIS_MODULE, |
f587de0e2 [NETFILTER]: nf_c... |
1186 |
.tuple.src.l3num = AF_INET6, |
09640e636 net: replace uses... |
1187 |
.tuple.src.u.tcp.port = cpu_to_be16(Q931_PORT), |
f587de0e2 [NETFILTER]: nf_c... |
1188 |
.tuple.dst.protonum = IPPROTO_TCP, |
6002f266b [NETFILTER]: nf_c... |
1189 1190 |
.help = q931_help, .expect_policy = &q931_exp_policy, |
f587de0e2 [NETFILTER]: nf_c... |
1191 1192 1193 1194 |
}, }; /****************************************************************************/ |
3db05fea5 [NETFILTER]: Repl... |
1195 |
static unsigned char *get_udp_data(struct sk_buff *skb, unsigned int protoff, |
f587de0e2 [NETFILTER]: nf_c... |
1196 1197 |
int *datalen) { |
905e3e8ec [NETFILTER]: nf_c... |
1198 1199 |
const struct udphdr *uh; struct udphdr _uh; |
f587de0e2 [NETFILTER]: nf_c... |
1200 |
int dataoff; |
3db05fea5 [NETFILTER]: Repl... |
1201 |
uh = skb_header_pointer(skb, protoff, sizeof(_uh), &_uh); |
f587de0e2 [NETFILTER]: nf_c... |
1202 1203 1204 |
if (uh == NULL) return NULL; dataoff = protoff + sizeof(_uh); |
3db05fea5 [NETFILTER]: Repl... |
1205 |
if (dataoff >= skb->len) |
f587de0e2 [NETFILTER]: nf_c... |
1206 |
return NULL; |
3db05fea5 [NETFILTER]: Repl... |
1207 1208 |
*datalen = skb->len - dataoff; return skb_header_pointer(skb, dataoff, *datalen, h323_buffer); |
f587de0e2 [NETFILTER]: nf_c... |
1209 1210 1211 1212 |
} /****************************************************************************/ static struct nf_conntrack_expect *find_expect(struct nf_conn *ct, |
643a2c15a [NETFILTER]: Intr... |
1213 |
union nf_inet_addr *addr, |
f587de0e2 [NETFILTER]: nf_c... |
1214 1215 |
__be16 port) { |
84541cc13 netfilter: netns ... |
1216 |
struct net *net = nf_ct_net(ct); |
f587de0e2 [NETFILTER]: nf_c... |
1217 1218 1219 1220 1221 1222 1223 1224 |
struct nf_conntrack_expect *exp; struct nf_conntrack_tuple tuple; memset(&tuple.src.u3, 0, sizeof(tuple.src.u3)); tuple.src.u.tcp.port = 0; memcpy(&tuple.dst.u3, addr, sizeof(tuple.dst.u3)); tuple.dst.u.tcp.port = port; tuple.dst.protonum = IPPROTO_TCP; |
5d0aa2ccd netfilter: nf_con... |
1225 |
exp = __nf_ct_expect_find(net, nf_ct_zone(ct), &tuple); |
f587de0e2 [NETFILTER]: nf_c... |
1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 |
if (exp && exp->master == ct) return exp; return NULL; } /****************************************************************************/ static int set_expect_timeout(struct nf_conntrack_expect *exp, unsigned timeout) { if (!exp || !del_timer(&exp->timeout)) return 0; exp->timeout.expires = jiffies + timeout * HZ; add_timer(&exp->timeout); return 1; } /****************************************************************************/ |
3db05fea5 [NETFILTER]: Repl... |
1245 |
static int expect_q931(struct sk_buff *skb, struct nf_conn *ct, |
f587de0e2 [NETFILTER]: nf_c... |
1246 1247 1248 1249 1250 1251 1252 1253 1254 |
enum ip_conntrack_info ctinfo, unsigned char **data, TransportAddress *taddr, int count) { struct nf_ct_h323_master *info = &nfct_help(ct)->help.ct_h323_info; int dir = CTINFO2DIR(ctinfo); int ret = 0; int i; __be16 port; |
643a2c15a [NETFILTER]: Intr... |
1255 |
union nf_inet_addr addr; |
f587de0e2 [NETFILTER]: nf_c... |
1256 1257 1258 1259 1260 1261 1262 |
struct nf_conntrack_expect *exp; typeof(nat_q931_hook) nat_q931; /* Look for the first related address */ for (i = 0; i < count; i++) { if (get_h225_addr(ct, *data, &taddr[i], &addr, &port) && memcmp(&addr, &ct->tuplehash[dir].tuple.src.u3, |
601e68e10 [NETFILTER]: Fix ... |
1263 |
sizeof(addr)) == 0 && port != 0) |
f587de0e2 [NETFILTER]: nf_c... |
1264 1265 1266 1267 1268 1269 1270 |
break; } if (i >= count) /* Not found */ return 0; /* Create expect for Q.931 */ |
6823645d6 [NETFILTER]: nf_c... |
1271 |
if ((exp = nf_ct_expect_alloc(ct)) == NULL) |
f587de0e2 [NETFILTER]: nf_c... |
1272 |
return -1; |
5e8fbe2ac [NETFILTER]: nf_c... |
1273 |
nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, nf_ct_l3num(ct), |
6823645d6 [NETFILTER]: nf_c... |
1274 1275 1276 1277 |
gkrouted_only ? /* only accept calls from GK? */ &ct->tuplehash[!dir].tuple.src.u3 : NULL, &ct->tuplehash[!dir].tuple.dst.u3, IPPROTO_TCP, NULL, &port); |
f587de0e2 [NETFILTER]: nf_c... |
1278 1279 1280 1281 1282 |
exp->helper = nf_conntrack_helper_q931; exp->flags = NF_CT_EXPECT_PERMANENT; /* Accept multiple calls */ nat_q931 = rcu_dereference(nat_q931_hook); if (nat_q931 && ct->status & IPS_NAT_MASK) { /* Need NAT */ |
3db05fea5 [NETFILTER]: Repl... |
1283 |
ret = nat_q931(skb, ct, ctinfo, data, taddr, i, port, exp); |
f587de0e2 [NETFILTER]: nf_c... |
1284 |
} else { /* Conntrack only */ |
6823645d6 [NETFILTER]: nf_c... |
1285 |
if (nf_ct_expect_related(exp) == 0) { |
0d53778e8 [NETFILTER]: Conv... |
1286 |
pr_debug("nf_ct_ras: expect Q.931 "); |
3c9fba656 [NETFILTER]: nf_c... |
1287 |
nf_ct_dump_tuple(&exp->tuple); |
f587de0e2 [NETFILTER]: nf_c... |
1288 1289 1290 1291 1292 1293 |
/* Save port for looking up expect in processing RCF */ info->sig_port[dir] = port; } else ret = -1; } |
6823645d6 [NETFILTER]: nf_c... |
1294 |
nf_ct_expect_put(exp); |
f587de0e2 [NETFILTER]: nf_c... |
1295 1296 1297 1298 1299 |
return ret; } /****************************************************************************/ |
3db05fea5 [NETFILTER]: Repl... |
1300 |
static int process_grq(struct sk_buff *skb, struct nf_conn *ct, |
f587de0e2 [NETFILTER]: nf_c... |
1301 1302 1303 1304 |
enum ip_conntrack_info ctinfo, unsigned char **data, GatekeeperRequest *grq) { typeof(set_ras_addr_hook) set_ras_addr; |
0d53778e8 [NETFILTER]: Conv... |
1305 1306 |
pr_debug("nf_ct_ras: GRQ "); |
f587de0e2 [NETFILTER]: nf_c... |
1307 1308 1309 |
set_ras_addr = rcu_dereference(set_ras_addr_hook); if (set_ras_addr && ct->status & IPS_NAT_MASK) /* NATed */ |
3db05fea5 [NETFILTER]: Repl... |
1310 |
return set_ras_addr(skb, ct, ctinfo, data, |
f587de0e2 [NETFILTER]: nf_c... |
1311 1312 1313 1314 1315 |
&grq->rasAddress, 1); return 0; } /****************************************************************************/ |
3db05fea5 [NETFILTER]: Repl... |
1316 |
static int process_gcf(struct sk_buff *skb, struct nf_conn *ct, |
f587de0e2 [NETFILTER]: nf_c... |
1317 1318 1319 1320 1321 1322 |
enum ip_conntrack_info ctinfo, unsigned char **data, GatekeeperConfirm *gcf) { int dir = CTINFO2DIR(ctinfo); int ret = 0; __be16 port; |
643a2c15a [NETFILTER]: Intr... |
1323 |
union nf_inet_addr addr; |
f587de0e2 [NETFILTER]: nf_c... |
1324 |
struct nf_conntrack_expect *exp; |
0d53778e8 [NETFILTER]: Conv... |
1325 1326 |
pr_debug("nf_ct_ras: GCF "); |
f587de0e2 [NETFILTER]: nf_c... |
1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 |
if (!get_h225_addr(ct, *data, &gcf->rasAddress, &addr, &port)) return 0; /* Registration port is the same as discovery port */ if (!memcmp(&addr, &ct->tuplehash[dir].tuple.src.u3, sizeof(addr)) && port == ct->tuplehash[dir].tuple.src.u.udp.port) return 0; /* Avoid RAS expectation loops. A GCF is never expected. */ if (test_bit(IPS_EXPECTED_BIT, &ct->status)) return 0; /* Need new expect */ |
6823645d6 [NETFILTER]: nf_c... |
1341 |
if ((exp = nf_ct_expect_alloc(ct)) == NULL) |
f587de0e2 [NETFILTER]: nf_c... |
1342 |
return -1; |
5e8fbe2ac [NETFILTER]: nf_c... |
1343 |
nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, nf_ct_l3num(ct), |
6823645d6 [NETFILTER]: nf_c... |
1344 1345 |
&ct->tuplehash[!dir].tuple.src.u3, &addr, IPPROTO_UDP, NULL, &port); |
f587de0e2 [NETFILTER]: nf_c... |
1346 |
exp->helper = nf_conntrack_helper_ras; |
6823645d6 [NETFILTER]: nf_c... |
1347 |
if (nf_ct_expect_related(exp) == 0) { |
0d53778e8 [NETFILTER]: Conv... |
1348 |
pr_debug("nf_ct_ras: expect RAS "); |
3c9fba656 [NETFILTER]: nf_c... |
1349 |
nf_ct_dump_tuple(&exp->tuple); |
f587de0e2 [NETFILTER]: nf_c... |
1350 1351 |
} else ret = -1; |
6823645d6 [NETFILTER]: nf_c... |
1352 |
nf_ct_expect_put(exp); |
f587de0e2 [NETFILTER]: nf_c... |
1353 1354 1355 1356 1357 |
return ret; } /****************************************************************************/ |
3db05fea5 [NETFILTER]: Repl... |
1358 |
static int process_rrq(struct sk_buff *skb, struct nf_conn *ct, |
f587de0e2 [NETFILTER]: nf_c... |
1359 1360 1361 1362 1363 1364 |
enum ip_conntrack_info ctinfo, unsigned char **data, RegistrationRequest *rrq) { struct nf_ct_h323_master *info = &nfct_help(ct)->help.ct_h323_info; int ret; typeof(set_ras_addr_hook) set_ras_addr; |
0d53778e8 [NETFILTER]: Conv... |
1365 1366 |
pr_debug("nf_ct_ras: RRQ "); |
f587de0e2 [NETFILTER]: nf_c... |
1367 |
|
3db05fea5 [NETFILTER]: Repl... |
1368 |
ret = expect_q931(skb, ct, ctinfo, data, |
f587de0e2 [NETFILTER]: nf_c... |
1369 1370 1371 1372 1373 1374 1375 |
rrq->callSignalAddress.item, rrq->callSignalAddress.count); if (ret < 0) return -1; set_ras_addr = rcu_dereference(set_ras_addr_hook); if (set_ras_addr && ct->status & IPS_NAT_MASK) { |
3db05fea5 [NETFILTER]: Repl... |
1376 |
ret = set_ras_addr(skb, ct, ctinfo, data, |
f587de0e2 [NETFILTER]: nf_c... |
1377 1378 1379 1380 1381 1382 1383 |
rrq->rasAddress.item, rrq->rasAddress.count); if (ret < 0) return -1; } if (rrq->options & eRegistrationRequest_timeToLive) { |
0d53778e8 [NETFILTER]: Conv... |
1384 1385 |
pr_debug("nf_ct_ras: RRQ TTL = %u seconds ", rrq->timeToLive); |
f587de0e2 [NETFILTER]: nf_c... |
1386 1387 1388 1389 1390 1391 1392 1393 |
info->timeout = rrq->timeToLive; } else info->timeout = default_rrq_ttl; return 0; } /****************************************************************************/ |
3db05fea5 [NETFILTER]: Repl... |
1394 |
static int process_rcf(struct sk_buff *skb, struct nf_conn *ct, |
f587de0e2 [NETFILTER]: nf_c... |
1395 1396 1397 1398 1399 1400 1401 1402 |
enum ip_conntrack_info ctinfo, unsigned char **data, RegistrationConfirm *rcf) { struct nf_ct_h323_master *info = &nfct_help(ct)->help.ct_h323_info; int dir = CTINFO2DIR(ctinfo); int ret; struct nf_conntrack_expect *exp; typeof(set_sig_addr_hook) set_sig_addr; |
0d53778e8 [NETFILTER]: Conv... |
1403 1404 |
pr_debug("nf_ct_ras: RCF "); |
f587de0e2 [NETFILTER]: nf_c... |
1405 1406 1407 |
set_sig_addr = rcu_dereference(set_sig_addr_hook); if (set_sig_addr && ct->status & IPS_NAT_MASK) { |
3db05fea5 [NETFILTER]: Repl... |
1408 |
ret = set_sig_addr(skb, ct, ctinfo, data, |
f587de0e2 [NETFILTER]: nf_c... |
1409 1410 1411 1412 1413 1414 1415 |
rcf->callSignalAddress.item, rcf->callSignalAddress.count); if (ret < 0) return -1; } if (rcf->options & eRegistrationConfirm_timeToLive) { |
0d53778e8 [NETFILTER]: Conv... |
1416 1417 |
pr_debug("nf_ct_ras: RCF TTL = %u seconds ", rcf->timeToLive); |
f587de0e2 [NETFILTER]: nf_c... |
1418 1419 1420 1421 |
info->timeout = rcf->timeToLive; } if (info->timeout > 0) { |
0d53778e8 [NETFILTER]: Conv... |
1422 1423 1424 |
pr_debug("nf_ct_ras: set RAS connection timeout to " "%u seconds ", info->timeout); |
3db05fea5 [NETFILTER]: Repl... |
1425 |
nf_ct_refresh(ct, skb, info->timeout * HZ); |
f587de0e2 [NETFILTER]: nf_c... |
1426 1427 |
/* Set expect timeout */ |
f8ba1affa [NETFILTER]: nf_c... |
1428 |
spin_lock_bh(&nf_conntrack_lock); |
f587de0e2 [NETFILTER]: nf_c... |
1429 1430 1431 |
exp = find_expect(ct, &ct->tuplehash[dir].tuple.dst.u3, info->sig_port[!dir]); if (exp) { |
0d53778e8 [NETFILTER]: Conv... |
1432 1433 1434 |
pr_debug("nf_ct_ras: set Q.931 expect " "timeout to %u seconds for", info->timeout); |
3c9fba656 [NETFILTER]: nf_c... |
1435 |
nf_ct_dump_tuple(&exp->tuple); |
f587de0e2 [NETFILTER]: nf_c... |
1436 1437 |
set_expect_timeout(exp, info->timeout); } |
f8ba1affa [NETFILTER]: nf_c... |
1438 |
spin_unlock_bh(&nf_conntrack_lock); |
f587de0e2 [NETFILTER]: nf_c... |
1439 1440 1441 1442 1443 1444 |
} return 0; } /****************************************************************************/ |
3db05fea5 [NETFILTER]: Repl... |
1445 |
static int process_urq(struct sk_buff *skb, struct nf_conn *ct, |
f587de0e2 [NETFILTER]: nf_c... |
1446 1447 1448 1449 1450 1451 1452 |
enum ip_conntrack_info ctinfo, unsigned char **data, UnregistrationRequest *urq) { struct nf_ct_h323_master *info = &nfct_help(ct)->help.ct_h323_info; int dir = CTINFO2DIR(ctinfo); int ret; typeof(set_sig_addr_hook) set_sig_addr; |
0d53778e8 [NETFILTER]: Conv... |
1453 1454 |
pr_debug("nf_ct_ras: URQ "); |
f587de0e2 [NETFILTER]: nf_c... |
1455 1456 1457 |
set_sig_addr = rcu_dereference(set_sig_addr_hook); if (set_sig_addr && ct->status & IPS_NAT_MASK) { |
3db05fea5 [NETFILTER]: Repl... |
1458 |
ret = set_sig_addr(skb, ct, ctinfo, data, |
f587de0e2 [NETFILTER]: nf_c... |
1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 |
urq->callSignalAddress.item, urq->callSignalAddress.count); if (ret < 0) return -1; } /* Clear old expect */ nf_ct_remove_expectations(ct); info->sig_port[dir] = 0; info->sig_port[!dir] = 0; /* Give it 30 seconds for UCF or URJ */ |
3db05fea5 [NETFILTER]: Repl... |
1471 |
nf_ct_refresh(ct, skb, 30 * HZ); |
f587de0e2 [NETFILTER]: nf_c... |
1472 1473 1474 1475 1476 |
return 0; } /****************************************************************************/ |
3db05fea5 [NETFILTER]: Repl... |
1477 |
static int process_arq(struct sk_buff *skb, struct nf_conn *ct, |
f587de0e2 [NETFILTER]: nf_c... |
1478 1479 1480 |
enum ip_conntrack_info ctinfo, unsigned char **data, AdmissionRequest *arq) { |
905e3e8ec [NETFILTER]: nf_c... |
1481 |
const struct nf_ct_h323_master *info = &nfct_help(ct)->help.ct_h323_info; |
f587de0e2 [NETFILTER]: nf_c... |
1482 1483 |
int dir = CTINFO2DIR(ctinfo); __be16 port; |
643a2c15a [NETFILTER]: Intr... |
1484 |
union nf_inet_addr addr; |
f587de0e2 [NETFILTER]: nf_c... |
1485 |
typeof(set_h225_addr_hook) set_h225_addr; |
0d53778e8 [NETFILTER]: Conv... |
1486 1487 |
pr_debug("nf_ct_ras: ARQ "); |
f587de0e2 [NETFILTER]: nf_c... |
1488 1489 1490 1491 |
set_h225_addr = rcu_dereference(set_h225_addr_hook); if ((arq->options & eAdmissionRequest_destCallSignalAddress) && get_h225_addr(ct, *data, &arq->destCallSignalAddress, |
601e68e10 [NETFILTER]: Fix ... |
1492 |
&addr, &port) && |
f587de0e2 [NETFILTER]: nf_c... |
1493 1494 1495 1496 |
!memcmp(&addr, &ct->tuplehash[dir].tuple.src.u3, sizeof(addr)) && port == info->sig_port[dir] && set_h225_addr && ct->status & IPS_NAT_MASK) { /* Answering ARQ */ |
3db05fea5 [NETFILTER]: Repl... |
1497 |
return set_h225_addr(skb, data, 0, |
f587de0e2 [NETFILTER]: nf_c... |
1498 1499 1500 1501 1502 1503 1504 |
&arq->destCallSignalAddress, &ct->tuplehash[!dir].tuple.dst.u3, info->sig_port[!dir]); } if ((arq->options & eAdmissionRequest_srcCallSignalAddress) && get_h225_addr(ct, *data, &arq->srcCallSignalAddress, |
601e68e10 [NETFILTER]: Fix ... |
1505 |
&addr, &port) && |
f587de0e2 [NETFILTER]: nf_c... |
1506 1507 1508 |
!memcmp(&addr, &ct->tuplehash[dir].tuple.src.u3, sizeof(addr)) && set_h225_addr && ct->status & IPS_NAT_MASK) { /* Calling ARQ */ |
3db05fea5 [NETFILTER]: Repl... |
1509 |
return set_h225_addr(skb, data, 0, |
f587de0e2 [NETFILTER]: nf_c... |
1510 1511 1512 1513 1514 1515 1516 1517 1518 |
&arq->srcCallSignalAddress, &ct->tuplehash[!dir].tuple.dst.u3, port); } return 0; } /****************************************************************************/ |
3db05fea5 [NETFILTER]: Repl... |
1519 |
static int process_acf(struct sk_buff *skb, struct nf_conn *ct, |
f587de0e2 [NETFILTER]: nf_c... |
1520 1521 1522 1523 1524 1525 |
enum ip_conntrack_info ctinfo, unsigned char **data, AdmissionConfirm *acf) { int dir = CTINFO2DIR(ctinfo); int ret = 0; __be16 port; |
643a2c15a [NETFILTER]: Intr... |
1526 |
union nf_inet_addr addr; |
f587de0e2 [NETFILTER]: nf_c... |
1527 1528 |
struct nf_conntrack_expect *exp; typeof(set_sig_addr_hook) set_sig_addr; |
0d53778e8 [NETFILTER]: Conv... |
1529 1530 |
pr_debug("nf_ct_ras: ACF "); |
f587de0e2 [NETFILTER]: nf_c... |
1531 1532 1533 1534 1535 1536 1537 1538 1539 |
if (!get_h225_addr(ct, *data, &acf->destCallSignalAddress, &addr, &port)) return 0; if (!memcmp(&addr, &ct->tuplehash[dir].tuple.dst.u3, sizeof(addr))) { /* Answering ACF */ set_sig_addr = rcu_dereference(set_sig_addr_hook); if (set_sig_addr && ct->status & IPS_NAT_MASK) |
3db05fea5 [NETFILTER]: Repl... |
1540 |
return set_sig_addr(skb, ct, ctinfo, data, |
f587de0e2 [NETFILTER]: nf_c... |
1541 1542 1543 1544 1545 |
&acf->destCallSignalAddress, 1); return 0; } /* Need new expect */ |
6823645d6 [NETFILTER]: nf_c... |
1546 |
if ((exp = nf_ct_expect_alloc(ct)) == NULL) |
f587de0e2 [NETFILTER]: nf_c... |
1547 |
return -1; |
5e8fbe2ac [NETFILTER]: nf_c... |
1548 |
nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, nf_ct_l3num(ct), |
6823645d6 [NETFILTER]: nf_c... |
1549 1550 |
&ct->tuplehash[!dir].tuple.src.u3, &addr, IPPROTO_TCP, NULL, &port); |
f587de0e2 [NETFILTER]: nf_c... |
1551 1552 |
exp->flags = NF_CT_EXPECT_PERMANENT; exp->helper = nf_conntrack_helper_q931; |
6823645d6 [NETFILTER]: nf_c... |
1553 |
if (nf_ct_expect_related(exp) == 0) { |
0d53778e8 [NETFILTER]: Conv... |
1554 |
pr_debug("nf_ct_ras: expect Q.931 "); |
3c9fba656 [NETFILTER]: nf_c... |
1555 |
nf_ct_dump_tuple(&exp->tuple); |
f587de0e2 [NETFILTER]: nf_c... |
1556 1557 |
} else ret = -1; |
6823645d6 [NETFILTER]: nf_c... |
1558 |
nf_ct_expect_put(exp); |
f587de0e2 [NETFILTER]: nf_c... |
1559 1560 1561 1562 1563 |
return ret; } /****************************************************************************/ |
3db05fea5 [NETFILTER]: Repl... |
1564 |
static int process_lrq(struct sk_buff *skb, struct nf_conn *ct, |
f587de0e2 [NETFILTER]: nf_c... |
1565 1566 1567 1568 |
enum ip_conntrack_info ctinfo, unsigned char **data, LocationRequest *lrq) { typeof(set_ras_addr_hook) set_ras_addr; |
0d53778e8 [NETFILTER]: Conv... |
1569 1570 |
pr_debug("nf_ct_ras: LRQ "); |
f587de0e2 [NETFILTER]: nf_c... |
1571 1572 1573 |
set_ras_addr = rcu_dereference(set_ras_addr_hook); if (set_ras_addr && ct->status & IPS_NAT_MASK) |
3db05fea5 [NETFILTER]: Repl... |
1574 |
return set_ras_addr(skb, ct, ctinfo, data, |
f587de0e2 [NETFILTER]: nf_c... |
1575 1576 1577 1578 1579 |
&lrq->replyAddress, 1); return 0; } /****************************************************************************/ |
3db05fea5 [NETFILTER]: Repl... |
1580 |
static int process_lcf(struct sk_buff *skb, struct nf_conn *ct, |
f587de0e2 [NETFILTER]: nf_c... |
1581 1582 1583 1584 1585 1586 |
enum ip_conntrack_info ctinfo, unsigned char **data, LocationConfirm *lcf) { int dir = CTINFO2DIR(ctinfo); int ret = 0; __be16 port; |
643a2c15a [NETFILTER]: Intr... |
1587 |
union nf_inet_addr addr; |
f587de0e2 [NETFILTER]: nf_c... |
1588 |
struct nf_conntrack_expect *exp; |
0d53778e8 [NETFILTER]: Conv... |
1589 1590 |
pr_debug("nf_ct_ras: LCF "); |
f587de0e2 [NETFILTER]: nf_c... |
1591 1592 1593 1594 1595 1596 |
if (!get_h225_addr(ct, *data, &lcf->callSignalAddress, &addr, &port)) return 0; /* Need new expect for call signal */ |
6823645d6 [NETFILTER]: nf_c... |
1597 |
if ((exp = nf_ct_expect_alloc(ct)) == NULL) |
f587de0e2 [NETFILTER]: nf_c... |
1598 |
return -1; |
5e8fbe2ac [NETFILTER]: nf_c... |
1599 |
nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, nf_ct_l3num(ct), |
6823645d6 [NETFILTER]: nf_c... |
1600 1601 |
&ct->tuplehash[!dir].tuple.src.u3, &addr, IPPROTO_TCP, NULL, &port); |
f587de0e2 [NETFILTER]: nf_c... |
1602 1603 |
exp->flags = NF_CT_EXPECT_PERMANENT; exp->helper = nf_conntrack_helper_q931; |
6823645d6 [NETFILTER]: nf_c... |
1604 |
if (nf_ct_expect_related(exp) == 0) { |
0d53778e8 [NETFILTER]: Conv... |
1605 |
pr_debug("nf_ct_ras: expect Q.931 "); |
3c9fba656 [NETFILTER]: nf_c... |
1606 |
nf_ct_dump_tuple(&exp->tuple); |
f587de0e2 [NETFILTER]: nf_c... |
1607 1608 |
} else ret = -1; |
6823645d6 [NETFILTER]: nf_c... |
1609 |
nf_ct_expect_put(exp); |
f587de0e2 [NETFILTER]: nf_c... |
1610 1611 1612 1613 1614 1615 1616 |
/* Ignore rasAddress */ return ret; } /****************************************************************************/ |
3db05fea5 [NETFILTER]: Repl... |
1617 |
static int process_irr(struct sk_buff *skb, struct nf_conn *ct, |
f587de0e2 [NETFILTER]: nf_c... |
1618 1619 1620 1621 1622 1623 |
enum ip_conntrack_info ctinfo, unsigned char **data, InfoRequestResponse *irr) { int ret; typeof(set_ras_addr_hook) set_ras_addr; typeof(set_sig_addr_hook) set_sig_addr; |
0d53778e8 [NETFILTER]: Conv... |
1624 1625 |
pr_debug("nf_ct_ras: IRR "); |
f587de0e2 [NETFILTER]: nf_c... |
1626 1627 1628 |
set_ras_addr = rcu_dereference(set_ras_addr_hook); if (set_ras_addr && ct->status & IPS_NAT_MASK) { |
3db05fea5 [NETFILTER]: Repl... |
1629 |
ret = set_ras_addr(skb, ct, ctinfo, data, |
f587de0e2 [NETFILTER]: nf_c... |
1630 1631 1632 1633 1634 1635 1636 |
&irr->rasAddress, 1); if (ret < 0) return -1; } set_sig_addr = rcu_dereference(set_sig_addr_hook); if (set_sig_addr && ct->status & IPS_NAT_MASK) { |
3db05fea5 [NETFILTER]: Repl... |
1637 |
ret = set_sig_addr(skb, ct, ctinfo, data, |
f587de0e2 [NETFILTER]: nf_c... |
1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 |
irr->callSignalAddress.item, irr->callSignalAddress.count); if (ret < 0) return -1; } return 0; } /****************************************************************************/ |
3db05fea5 [NETFILTER]: Repl... |
1648 |
static int process_ras(struct sk_buff *skb, struct nf_conn *ct, |
f587de0e2 [NETFILTER]: nf_c... |
1649 1650 1651 1652 1653 |
enum ip_conntrack_info ctinfo, unsigned char **data, RasMessage *ras) { switch (ras->choice) { case eRasMessage_gatekeeperRequest: |
3db05fea5 [NETFILTER]: Repl... |
1654 |
return process_grq(skb, ct, ctinfo, data, |
f587de0e2 [NETFILTER]: nf_c... |
1655 1656 |
&ras->gatekeeperRequest); case eRasMessage_gatekeeperConfirm: |
3db05fea5 [NETFILTER]: Repl... |
1657 |
return process_gcf(skb, ct, ctinfo, data, |
f587de0e2 [NETFILTER]: nf_c... |
1658 1659 |
&ras->gatekeeperConfirm); case eRasMessage_registrationRequest: |
3db05fea5 [NETFILTER]: Repl... |
1660 |
return process_rrq(skb, ct, ctinfo, data, |
f587de0e2 [NETFILTER]: nf_c... |
1661 1662 |
&ras->registrationRequest); case eRasMessage_registrationConfirm: |
3db05fea5 [NETFILTER]: Repl... |
1663 |
return process_rcf(skb, ct, ctinfo, data, |
f587de0e2 [NETFILTER]: nf_c... |
1664 1665 |
&ras->registrationConfirm); case eRasMessage_unregistrationRequest: |
3db05fea5 [NETFILTER]: Repl... |
1666 |
return process_urq(skb, ct, ctinfo, data, |
f587de0e2 [NETFILTER]: nf_c... |
1667 1668 |
&ras->unregistrationRequest); case eRasMessage_admissionRequest: |
3db05fea5 [NETFILTER]: Repl... |
1669 |
return process_arq(skb, ct, ctinfo, data, |
f587de0e2 [NETFILTER]: nf_c... |
1670 1671 |
&ras->admissionRequest); case eRasMessage_admissionConfirm: |
3db05fea5 [NETFILTER]: Repl... |
1672 |
return process_acf(skb, ct, ctinfo, data, |
f587de0e2 [NETFILTER]: nf_c... |
1673 1674 |
&ras->admissionConfirm); case eRasMessage_locationRequest: |
3db05fea5 [NETFILTER]: Repl... |
1675 |
return process_lrq(skb, ct, ctinfo, data, |
f587de0e2 [NETFILTER]: nf_c... |
1676 1677 |
&ras->locationRequest); case eRasMessage_locationConfirm: |
3db05fea5 [NETFILTER]: Repl... |
1678 |
return process_lcf(skb, ct, ctinfo, data, |
f587de0e2 [NETFILTER]: nf_c... |
1679 1680 |
&ras->locationConfirm); case eRasMessage_infoRequestResponse: |
3db05fea5 [NETFILTER]: Repl... |
1681 |
return process_irr(skb, ct, ctinfo, data, |
f587de0e2 [NETFILTER]: nf_c... |
1682 1683 |
&ras->infoRequestResponse); default: |
0d53778e8 [NETFILTER]: Conv... |
1684 1685 |
pr_debug("nf_ct_ras: RAS message %d ", ras->choice); |
f587de0e2 [NETFILTER]: nf_c... |
1686 1687 1688 1689 1690 1691 1692 |
break; } return 0; } /****************************************************************************/ |
3db05fea5 [NETFILTER]: Repl... |
1693 |
static int ras_help(struct sk_buff *skb, unsigned int protoff, |
f587de0e2 [NETFILTER]: nf_c... |
1694 1695 1696 1697 1698 1699 |
struct nf_conn *ct, enum ip_conntrack_info ctinfo) { static RasMessage ras; unsigned char *data; int datalen = 0; int ret; |
3db05fea5 [NETFILTER]: Repl... |
1700 1701 |
pr_debug("nf_ct_ras: skblen = %u ", skb->len); |
f587de0e2 [NETFILTER]: nf_c... |
1702 1703 1704 1705 |
spin_lock_bh(&nf_h323_lock); /* Get UDP data */ |
3db05fea5 [NETFILTER]: Repl... |
1706 |
data = get_udp_data(skb, protoff, &datalen); |
f587de0e2 [NETFILTER]: nf_c... |
1707 1708 |
if (data == NULL) goto accept; |
0d53778e8 [NETFILTER]: Conv... |
1709 |
pr_debug("nf_ct_ras: RAS message len=%d ", datalen); |
3c9fba656 [NETFILTER]: nf_c... |
1710 |
nf_ct_dump_tuple(&ct->tuplehash[CTINFO2DIR(ctinfo)].tuple); |
f587de0e2 [NETFILTER]: nf_c... |
1711 1712 1713 1714 |
/* Decode RAS message */ ret = DecodeRasMessage(data, datalen, &ras); if (ret < 0) { |
0d53778e8 [NETFILTER]: Conv... |
1715 1716 1717 1718 |
pr_debug("nf_ct_ras: decoding error: %s ", ret == H323_ERROR_BOUND ? "out of bound" : "out of range"); |
f587de0e2 [NETFILTER]: nf_c... |
1719 1720 1721 1722 |
goto accept; } /* Process RAS message */ |
3db05fea5 [NETFILTER]: Repl... |
1723 |
if (process_ras(skb, ct, ctinfo, &data, &ras) < 0) |
f587de0e2 [NETFILTER]: nf_c... |
1724 1725 1726 1727 1728 1729 1730 1731 1732 |
goto drop; accept: spin_unlock_bh(&nf_h323_lock); return NF_ACCEPT; drop: spin_unlock_bh(&nf_h323_lock); if (net_ratelimit()) |
654d0fbdc netfilter: cleanu... |
1733 1734 |
pr_info("nf_ct_ras: packet dropped "); |
f587de0e2 [NETFILTER]: nf_c... |
1735 1736 1737 1738 |
return NF_DROP; } /****************************************************************************/ |
6002f266b [NETFILTER]: nf_c... |
1739 1740 1741 1742 |
static const struct nf_conntrack_expect_policy ras_exp_policy = { .max_expected = 32, .timeout = 240, }; |
f587de0e2 [NETFILTER]: nf_c... |
1743 1744 1745 1746 |
static struct nf_conntrack_helper nf_conntrack_helper_ras[] __read_mostly = { { .name = "RAS", .me = THIS_MODULE, |
f587de0e2 [NETFILTER]: nf_c... |
1747 |
.tuple.src.l3num = AF_INET, |
09640e636 net: replace uses... |
1748 |
.tuple.src.u.udp.port = cpu_to_be16(RAS_PORT), |
f587de0e2 [NETFILTER]: nf_c... |
1749 |
.tuple.dst.protonum = IPPROTO_UDP, |
f587de0e2 [NETFILTER]: nf_c... |
1750 |
.help = ras_help, |
6002f266b [NETFILTER]: nf_c... |
1751 |
.expect_policy = &ras_exp_policy, |
f587de0e2 [NETFILTER]: nf_c... |
1752 1753 1754 1755 |
}, { .name = "RAS", .me = THIS_MODULE, |
f587de0e2 [NETFILTER]: nf_c... |
1756 |
.tuple.src.l3num = AF_INET6, |
09640e636 net: replace uses... |
1757 |
.tuple.src.u.udp.port = cpu_to_be16(RAS_PORT), |
f587de0e2 [NETFILTER]: nf_c... |
1758 |
.tuple.dst.protonum = IPPROTO_UDP, |
f587de0e2 [NETFILTER]: nf_c... |
1759 |
.help = ras_help, |
6002f266b [NETFILTER]: nf_c... |
1760 |
.expect_policy = &ras_exp_policy, |
f587de0e2 [NETFILTER]: nf_c... |
1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 |
}, }; /****************************************************************************/ static void __exit nf_conntrack_h323_fini(void) { nf_conntrack_helper_unregister(&nf_conntrack_helper_ras[1]); nf_conntrack_helper_unregister(&nf_conntrack_helper_ras[0]); nf_conntrack_helper_unregister(&nf_conntrack_helper_q931[1]); nf_conntrack_helper_unregister(&nf_conntrack_helper_q931[0]); |
a56b8f815 netfilter: nf_con... |
1771 |
nf_conntrack_helper_unregister(&nf_conntrack_helper_h245); |
f587de0e2 [NETFILTER]: nf_c... |
1772 |
kfree(h323_buffer); |
0d53778e8 [NETFILTER]: Conv... |
1773 1774 |
pr_debug("nf_ct_h323: fini "); |
f587de0e2 [NETFILTER]: nf_c... |
1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 |
} /****************************************************************************/ static int __init nf_conntrack_h323_init(void) { int ret; h323_buffer = kmalloc(65536, GFP_KERNEL); if (!h323_buffer) return -ENOMEM; |
a56b8f815 netfilter: nf_con... |
1785 |
ret = nf_conntrack_helper_register(&nf_conntrack_helper_h245); |
f587de0e2 [NETFILTER]: nf_c... |
1786 1787 |
if (ret < 0) goto err1; |
a56b8f815 netfilter: nf_con... |
1788 |
ret = nf_conntrack_helper_register(&nf_conntrack_helper_q931[0]); |
f587de0e2 [NETFILTER]: nf_c... |
1789 1790 |
if (ret < 0) goto err2; |
a56b8f815 netfilter: nf_con... |
1791 |
ret = nf_conntrack_helper_register(&nf_conntrack_helper_q931[1]); |
f587de0e2 [NETFILTER]: nf_c... |
1792 1793 |
if (ret < 0) goto err3; |
a56b8f815 netfilter: nf_con... |
1794 |
ret = nf_conntrack_helper_register(&nf_conntrack_helper_ras[0]); |
f587de0e2 [NETFILTER]: nf_c... |
1795 1796 |
if (ret < 0) goto err4; |
a56b8f815 netfilter: nf_con... |
1797 1798 1799 |
ret = nf_conntrack_helper_register(&nf_conntrack_helper_ras[1]); if (ret < 0) goto err5; |
0d53778e8 [NETFILTER]: Conv... |
1800 1801 |
pr_debug("nf_ct_h323: init success "); |
f587de0e2 [NETFILTER]: nf_c... |
1802 |
return 0; |
a56b8f815 netfilter: nf_con... |
1803 |
err5: |
f587de0e2 [NETFILTER]: nf_c... |
1804 |
nf_conntrack_helper_unregister(&nf_conntrack_helper_ras[0]); |
a56b8f815 netfilter: nf_con... |
1805 |
err4: |
f587de0e2 [NETFILTER]: nf_c... |
1806 |
nf_conntrack_helper_unregister(&nf_conntrack_helper_q931[1]); |
a56b8f815 netfilter: nf_con... |
1807 |
err3: |
f587de0e2 [NETFILTER]: nf_c... |
1808 |
nf_conntrack_helper_unregister(&nf_conntrack_helper_q931[0]); |
a56b8f815 netfilter: nf_con... |
1809 1810 |
err2: nf_conntrack_helper_unregister(&nf_conntrack_helper_h245); |
f587de0e2 [NETFILTER]: nf_c... |
1811 |
err1: |
8a548868d netfilter: nf_con... |
1812 |
kfree(h323_buffer); |
f587de0e2 [NETFILTER]: nf_c... |
1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 |
return ret; } /****************************************************************************/ module_init(nf_conntrack_h323_init); module_exit(nf_conntrack_h323_fini); EXPORT_SYMBOL_GPL(get_h225_addr); EXPORT_SYMBOL_GPL(set_h245_addr_hook); EXPORT_SYMBOL_GPL(set_h225_addr_hook); EXPORT_SYMBOL_GPL(set_sig_addr_hook); EXPORT_SYMBOL_GPL(set_ras_addr_hook); EXPORT_SYMBOL_GPL(nat_rtp_rtcp_hook); EXPORT_SYMBOL_GPL(nat_t120_hook); EXPORT_SYMBOL_GPL(nat_h245_hook); EXPORT_SYMBOL_GPL(nat_callforwarding_hook); EXPORT_SYMBOL_GPL(nat_q931_hook); MODULE_AUTHOR("Jing Min Zhao <zhaojingmin@users.sourceforge.net>"); MODULE_DESCRIPTION("H.323 connection tracking helper"); MODULE_LICENSE("GPL"); MODULE_ALIAS("ip_conntrack_h323"); |
4dc06f963 netfilter: nf_con... |
1835 |
MODULE_ALIAS_NFCT_HELPER("h323"); |