aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJing Min Zhao <zhaojignmin@hotmail.com>2006-03-21 02:41:17 -0500
committerDavid S. Miller <davem@davemloft.net>2006-03-21 02:41:17 -0500
commit5e35941d990123f155b02d5663e51a24f816b6f3 (patch)
tree90499f3247e64210213d7b4da936f739d7a9711c
parent30ca3e376e82cc44488b1d377adfb10b5818548e (diff)
[NETFILTER]: Add H.323 conntrack/NAT helper
Signed-off-by: Jing Min Zhao <zhaojignmin@hotmail.com> Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/linux/netfilter_ipv4/ip_conntrack.h2
-rw-r--r--include/linux/netfilter_ipv4/ip_conntrack_h323.h30
-rw-r--r--net/ipv4/netfilter/Kconfig26
-rw-r--r--net/ipv4/netfilter/Makefile5
-rw-r--r--net/ipv4/netfilter/ip_conntrack_helper_h323.c1731
-rw-r--r--net/ipv4/netfilter/ip_conntrack_helper_h323_asn1.c870
-rw-r--r--net/ipv4/netfilter/ip_conntrack_helper_h323_asn1.h98
-rw-r--r--net/ipv4/netfilter/ip_conntrack_helper_h323_types.c1926
-rw-r--r--net/ipv4/netfilter/ip_conntrack_helper_h323_types.h938
-rw-r--r--net/ipv4/netfilter/ip_nat_helper_h323.c605
10 files changed, 6231 insertions, 0 deletions
diff --git a/include/linux/netfilter_ipv4/ip_conntrack.h b/include/linux/netfilter_ipv4/ip_conntrack.h
index 215765f043e6..f32d75c4f4cf 100644
--- a/include/linux/netfilter_ipv4/ip_conntrack.h
+++ b/include/linux/netfilter_ipv4/ip_conntrack.h
@@ -29,6 +29,7 @@ union ip_conntrack_expect_proto {
29}; 29};
30 30
31/* Add protocol helper include file here */ 31/* Add protocol helper include file here */
32#include <linux/netfilter_ipv4/ip_conntrack_h323.h>
32#include <linux/netfilter_ipv4/ip_conntrack_pptp.h> 33#include <linux/netfilter_ipv4/ip_conntrack_pptp.h>
33#include <linux/netfilter_ipv4/ip_conntrack_amanda.h> 34#include <linux/netfilter_ipv4/ip_conntrack_amanda.h>
34#include <linux/netfilter_ipv4/ip_conntrack_ftp.h> 35#include <linux/netfilter_ipv4/ip_conntrack_ftp.h>
@@ -37,6 +38,7 @@ union ip_conntrack_expect_proto {
37/* per conntrack: application helper private data */ 38/* per conntrack: application helper private data */
38union ip_conntrack_help { 39union ip_conntrack_help {
39 /* insert conntrack helper private data (master) here */ 40 /* insert conntrack helper private data (master) here */
41 struct ip_ct_h323_master ct_h323_info;
40 struct ip_ct_pptp_master ct_pptp_info; 42 struct ip_ct_pptp_master ct_pptp_info;
41 struct ip_ct_ftp_master ct_ftp_info; 43 struct ip_ct_ftp_master ct_ftp_info;
42 struct ip_ct_irc_master ct_irc_info; 44 struct ip_ct_irc_master ct_irc_info;
diff --git a/include/linux/netfilter_ipv4/ip_conntrack_h323.h b/include/linux/netfilter_ipv4/ip_conntrack_h323.h
new file mode 100644
index 000000000000..0987cea53840
--- /dev/null
+++ b/include/linux/netfilter_ipv4/ip_conntrack_h323.h
@@ -0,0 +1,30 @@
1#ifndef _IP_CONNTRACK_H323_H
2#define _IP_CONNTRACK_H323_H
3
4#ifdef __KERNEL__
5
6#define RAS_PORT 1719
7#define Q931_PORT 1720
8#define H323_RTP_CHANNEL_MAX 4 /* Audio, video, FAX and other */
9
10/* This structure exists only once per master */
11struct ip_ct_h323_master {
12
13 /* Original and NATed Q.931 or H.245 signal ports */
14 u_int16_t sig_port[IP_CT_DIR_MAX];
15
16 /* Original and NATed RTP ports */
17 u_int16_t rtp_port[H323_RTP_CHANNEL_MAX][IP_CT_DIR_MAX];
18
19 union {
20 /* RAS connection timeout */
21 u_int32_t timeout;
22
23 /* Next TPKT length (for separate TPKT header and data) */
24 u_int16_t tpkt_len[IP_CT_DIR_MAX];
25 };
26};
27
28#endif
29
30#endif
diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
index 933ee7a9efdf..882b842c25d4 100644
--- a/net/ipv4/netfilter/Kconfig
+++ b/net/ipv4/netfilter/Kconfig
@@ -168,6 +168,26 @@ config IP_NF_PPTP
168 If you want to compile it as a module, say M here and read 168 If you want to compile it as a module, say M here and read
169 Documentation/modules.txt. If unsure, say `N'. 169 Documentation/modules.txt. If unsure, say `N'.
170 170
171config IP_NF_H323
172 tristate 'H.323 protocol support'
173 depends on IP_NF_CONNTRACK
174 help
175 H.323 is a VoIP signalling protocol from ITU-T. As one of the most
176 important VoIP protocols, it is widely used by voice hardware and
177 software including voice gateways, IP phones, Netmeeting, OpenPhone,
178 Gnomemeeting, etc.
179
180 With this module you can support H.323 on a connection tracking/NAT
181 firewall.
182
183 This module supports RAS, Fast-start, H.245 tunnelling, RTP/RTCP
184 and T.120 based data and applications including audio, video, FAX,
185 chat, whiteboard, file transfer, etc. For more information, please
186 see http://nath323.sourceforge.net/.
187
188 If you want to compile it as a module, say 'M' here and read
189 Documentation/modules.txt. If unsure, say 'N'.
190
171config IP_NF_QUEUE 191config IP_NF_QUEUE
172 tristate "IP Userspace queueing via NETLINK (OBSOLETE)" 192 tristate "IP Userspace queueing via NETLINK (OBSOLETE)"
173 help 193 help
@@ -484,6 +504,12 @@ config IP_NF_NAT_PPTP
484 default IP_NF_NAT if IP_NF_PPTP=y 504 default IP_NF_NAT if IP_NF_PPTP=y
485 default m if IP_NF_PPTP=m 505 default m if IP_NF_PPTP=m
486 506
507config IP_NF_NAT_H323
508 tristate
509 depends on IP_NF_IPTABLES!=n && IP_NF_CONNTRACK!=n && IP_NF_NAT!=n
510 default IP_NF_NAT if IP_NF_H323=y
511 default m if IP_NF_H323=m
512
487# mangle + specific targets 513# mangle + specific targets
488config IP_NF_MANGLE 514config IP_NF_MANGLE
489 tristate "Packet mangling" 515 tristate "Packet mangling"
diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile
index 3fe80924ac54..f2cd9a6c5b91 100644
--- a/net/ipv4/netfilter/Makefile
+++ b/net/ipv4/netfilter/Makefile
@@ -10,6 +10,9 @@ iptable_nat-objs := ip_nat_rule.o ip_nat_standalone.o
10ip_conntrack_pptp-objs := ip_conntrack_helper_pptp.o ip_conntrack_proto_gre.o 10ip_conntrack_pptp-objs := ip_conntrack_helper_pptp.o ip_conntrack_proto_gre.o
11ip_nat_pptp-objs := ip_nat_helper_pptp.o ip_nat_proto_gre.o 11ip_nat_pptp-objs := ip_nat_helper_pptp.o ip_nat_proto_gre.o
12 12
13ip_conntrack_h323-objs := ip_conntrack_helper_h323.o ip_conntrack_helper_h323_asn1.o
14ip_nat_h323-objs := ip_nat_helper_h323.o
15
13# connection tracking 16# connection tracking
14obj-$(CONFIG_IP_NF_CONNTRACK) += ip_conntrack.o 17obj-$(CONFIG_IP_NF_CONNTRACK) += ip_conntrack.o
15obj-$(CONFIG_IP_NF_NAT) += ip_nat.o 18obj-$(CONFIG_IP_NF_NAT) += ip_nat.o
@@ -22,6 +25,7 @@ obj-$(CONFIG_IP_NF_CONNTRACK_NETLINK) += ip_conntrack_netlink.o
22obj-$(CONFIG_IP_NF_CT_PROTO_SCTP) += ip_conntrack_proto_sctp.o 25obj-$(CONFIG_IP_NF_CT_PROTO_SCTP) += ip_conntrack_proto_sctp.o
23 26
24# connection tracking helpers 27# connection tracking helpers
28obj-$(CONFIG_IP_NF_H323) += ip_conntrack_h323.o
25obj-$(CONFIG_IP_NF_PPTP) += ip_conntrack_pptp.o 29obj-$(CONFIG_IP_NF_PPTP) += ip_conntrack_pptp.o
26obj-$(CONFIG_IP_NF_AMANDA) += ip_conntrack_amanda.o 30obj-$(CONFIG_IP_NF_AMANDA) += ip_conntrack_amanda.o
27obj-$(CONFIG_IP_NF_TFTP) += ip_conntrack_tftp.o 31obj-$(CONFIG_IP_NF_TFTP) += ip_conntrack_tftp.o
@@ -30,6 +34,7 @@ obj-$(CONFIG_IP_NF_IRC) += ip_conntrack_irc.o
30obj-$(CONFIG_IP_NF_NETBIOS_NS) += ip_conntrack_netbios_ns.o 34obj-$(CONFIG_IP_NF_NETBIOS_NS) += ip_conntrack_netbios_ns.o
31 35
32# NAT helpers 36# NAT helpers
37obj-$(CONFIG_IP_NF_NAT_H323) += ip_nat_h323.o
33obj-$(CONFIG_IP_NF_NAT_PPTP) += ip_nat_pptp.o 38obj-$(CONFIG_IP_NF_NAT_PPTP) += ip_nat_pptp.o
34obj-$(CONFIG_IP_NF_NAT_AMANDA) += ip_nat_amanda.o 39obj-$(CONFIG_IP_NF_NAT_AMANDA) += ip_nat_amanda.o
35obj-$(CONFIG_IP_NF_NAT_TFTP) += ip_nat_tftp.o 40obj-$(CONFIG_IP_NF_NAT_TFTP) += ip_nat_tftp.o
diff --git a/net/ipv4/netfilter/ip_conntrack_helper_h323.c b/net/ipv4/netfilter/ip_conntrack_helper_h323.c
new file mode 100644
index 000000000000..20da6730b860
--- /dev/null
+++ b/net/ipv4/netfilter/ip_conntrack_helper_h323.c
@@ -0,0 +1,1731 @@
1/*
2 * H.323 connection tracking helper
3 *
4 * Copyright (c) 2006 Jing Min Zhao <zhaojingmin@users.sourceforge.net>
5 *
6 * This source code is licensed under General Public License version 2.
7 *
8 * Based on the 'brute force' H.323 connection tracking module by
9 * Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
10 *
11 * For more information, please see http://nath323.sourceforge.net/
12 *
13 * Changes:
14 * 2006-02-01 - initial version 0.1
15 *
16 * 2006-02-20 - version 0.2
17 * 1. Changed source format to follow kernel conventions
18 * 2. Deleted some unnecessary structures
19 * 3. Minor fixes
20 *
21 * 2006-03-10 - version 0.3
22 * 1. Added support for multiple TPKTs in one packet (suggested by
23 * Patrick McHardy)
24 * 2. Avoid excessive stack usage (based on Patrick McHardy's patch)
25 * 3. Added support for non-linear skb (based on Patrick McHardy's patch)
26 * 4. Fixed missing H.245 module owner (Patrick McHardy)
27 * 5. Avoid long RAS expectation chains (Patrick McHardy)
28 * 6. Fixed incorrect __exit attribute (Patrick McHardy)
29 * 7. Eliminated unnecessary return code
30 * 8. Fixed incorrect use of NAT data from conntrack code (suggested by
31 * Patrick McHardy)
32 * 9. Fixed TTL calculation error in RCF
33 * 10. Added TTL support in RRQ
34 * 11. Better support for separate TPKT header and data
35 *
36 * 2006-03-15 - version 0.4
37 * 1. Added support for T.120 channels
38 * 2. Added parameter gkrouted_only (suggested by Patrick McHardy)
39 * 3. Splitted ASN.1 code and data (suggested by Patrick McHardy)
40 * 4. Sort ASN.1 data to avoid forwarding declarations (suggested by
41 * Patrick McHardy)
42 * 5. Reset next TPKT data length in get_tpkt_data()
43 */
44
45#include <linux/config.h>
46#include <linux/module.h>
47#include <linux/netfilter.h>
48#include <linux/ip.h>
49#include <net/tcp.h>
50#include <linux/netfilter_ipv4/ip_conntrack.h>
51#include <linux/netfilter_ipv4/ip_conntrack_core.h>
52#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
53#include <linux/netfilter_ipv4/ip_conntrack_tuple.h>
54#include <linux/netfilter_ipv4/ip_conntrack_h323.h>
55#include <linux/moduleparam.h>
56
57#include "ip_conntrack_helper_h323_asn1.h"
58
59#if 0
60#define DEBUGP printk
61#else
62#define DEBUGP(format, args...)
63#endif
64
65/* Parameters */
66static int gkrouted_only = 1;
67module_param(gkrouted_only, int, 0600);
68MODULE_PARM_DESC(gkrouted_only, "only accept calls from gatekeeper");
69
70/* Hooks for NAT */
71int (*set_h245_addr_hook) (struct sk_buff ** pskb,
72 unsigned char **data, int dataoff,
73 H245_TransportAddress * addr,
74 u_int32_t ip, u_int16_t port);
75int (*set_h225_addr_hook) (struct sk_buff ** pskb,
76 unsigned char **data, int dataoff,
77 TransportAddress * addr,
78 u_int32_t ip, u_int16_t port);
79int (*set_sig_addr_hook) (struct sk_buff ** pskb,
80 struct ip_conntrack * ct,
81 enum ip_conntrack_info ctinfo,
82 unsigned char **data,
83 TransportAddress * addr, int count);
84int (*set_ras_addr_hook) (struct sk_buff ** pskb,
85 struct ip_conntrack * ct,
86 enum ip_conntrack_info ctinfo,
87 unsigned char **data,
88 TransportAddress * addr, int count);
89int (*nat_rtp_rtcp_hook) (struct sk_buff ** pskb,
90 struct ip_conntrack * ct,
91 enum ip_conntrack_info ctinfo,
92 unsigned char **data, int dataoff,
93 H245_TransportAddress * addr,
94 u_int16_t port, u_int16_t rtp_port,
95 struct ip_conntrack_expect * rtp_exp,
96 struct ip_conntrack_expect * rtcp_exp);
97int (*nat_t120_hook) (struct sk_buff ** pskb,
98 struct ip_conntrack * ct,
99 enum ip_conntrack_info ctinfo,
100 unsigned char **data, int dataoff,
101 H245_TransportAddress * addr, u_int16_t port,
102 struct ip_conntrack_expect * exp);
103int (*nat_h245_hook) (struct sk_buff ** pskb,
104 struct ip_conntrack * ct,
105 enum ip_conntrack_info ctinfo,
106 unsigned char **data, int dataoff,
107 TransportAddress * addr, u_int16_t port,
108 struct ip_conntrack_expect * exp);
109int (*nat_q931_hook) (struct sk_buff ** pskb,
110 struct ip_conntrack * ct,
111 enum ip_conntrack_info ctinfo,
112 unsigned char **data, TransportAddress * addr, int idx,
113 u_int16_t port, struct ip_conntrack_expect * exp);
114
115
116static DEFINE_SPINLOCK(ip_h323_lock);
117static char *h323_buffer;
118
119/****************************************************************************/
120static int get_tpkt_data(struct sk_buff **pskb, struct ip_conntrack *ct,
121 enum ip_conntrack_info ctinfo,
122 unsigned char **data, int *datalen, int *dataoff)
123{
124 struct ip_ct_h323_master *info = &ct->help.ct_h323_info;
125 int dir = CTINFO2DIR(ctinfo);
126 struct tcphdr _tcph, *th;
127 int tcpdatalen;
128 int tcpdataoff;
129 unsigned char *tpkt;
130 int tpktlen;
131 int tpktoff;
132
133 /* Get TCP header */
134 th = skb_header_pointer(*pskb, (*pskb)->nh.iph->ihl * 4,
135 sizeof(_tcph), &_tcph);
136 if (th == NULL)
137 return 0;
138
139 /* Get TCP data offset */
140 tcpdataoff = (*pskb)->nh.iph->ihl * 4 + th->doff * 4;
141
142 /* Get TCP data length */
143 tcpdatalen = (*pskb)->len - tcpdataoff;
144 if (tcpdatalen <= 0) /* No TCP data */
145 goto clear_out;
146
147 if (*data == NULL) { /* first TPKT */
148 /* Get first TPKT pointer */
149 tpkt = skb_header_pointer(*pskb, tcpdataoff, tcpdatalen,
150 h323_buffer);
151 BUG_ON(tpkt == NULL);
152
153 /* Validate TPKT identifier */
154 if (tcpdatalen < 4 || tpkt[0] != 0x03 || tpkt[1] != 0) {
155 /* Netmeeting sends TPKT header and data separately */
156 if (info->tpkt_len[dir] > 0) {
157 DEBUGP("ip_ct_h323: previous packet "
158 "indicated separate TPKT data of %hu "
159 "bytes\n", info->tpkt_len[dir]);
160 if (info->tpkt_len[dir] <= tcpdatalen) {
161 /* Yes, there was a TPKT header
162 * received */
163 *data = tpkt;
164 *datalen = info->tpkt_len[dir];
165 *dataoff = 0;
166 goto out;
167 }
168
169 /* Fragmented TPKT */
170 if (net_ratelimit())
171 printk("ip_ct_h323: "
172 "fragmented TPKT\n");
173 goto clear_out;
174 }
175
176 /* It is not even a TPKT */
177 return 0;
178 }
179 tpktoff = 0;
180 } else { /* Next TPKT */
181 tpktoff = *dataoff + *datalen;
182 tcpdatalen -= tpktoff;
183 if (tcpdatalen <= 4) /* No more TPKT */
184 goto clear_out;
185 tpkt = *data + *datalen;
186
187 /* Validate TPKT identifier */
188 if (tpkt[0] != 0x03 || tpkt[1] != 0)
189 goto clear_out;
190 }
191
192 /* Validate TPKT length */
193 tpktlen = tpkt[2] * 256 + tpkt[3];
194 if (tpktlen > tcpdatalen) {
195 if (tcpdatalen == 4) { /* Separate TPKT header */
196 /* Netmeeting sends TPKT header and data separately */
197 DEBUGP("ip_ct_h323: separate TPKT header indicates "
198 "there will be TPKT data of %hu bytes\n",
199 tpktlen - 4);
200 info->tpkt_len[dir] = tpktlen - 4;
201 return 0;
202 }
203
204 if (net_ratelimit())
205 printk("ip_ct_h323: incomplete TPKT (fragmented?)\n");
206 goto clear_out;
207 }
208
209 /* This is the encapsulated data */
210 *data = tpkt + 4;
211 *datalen = tpktlen - 4;
212 *dataoff = tpktoff + 4;
213
214 out:
215 /* Clear TPKT length */
216 info->tpkt_len[dir] = 0;
217 return 1;
218
219 clear_out:
220 info->tpkt_len[dir] = 0;
221 return 0;
222}
223
224/****************************************************************************/
225int get_h245_addr(unsigned char *data, H245_TransportAddress * addr,
226 u_int32_t * ip, u_int16_t * port)
227{
228 unsigned char *p;
229
230 if (addr->choice != eH245_TransportAddress_unicastAddress ||
231 addr->unicastAddress.choice != eUnicastAddress_iPAddress)
232 return 0;
233
234 p = data + addr->unicastAddress.iPAddress.network;
235 *ip = htonl((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | (p[3]));
236 *port = (p[4] << 8) | (p[5]);
237
238 return 1;
239}
240
241/****************************************************************************/
242static int expect_rtp_rtcp(struct sk_buff **pskb, struct ip_conntrack *ct,
243 enum ip_conntrack_info ctinfo,
244 unsigned char **data, int dataoff,
245 H245_TransportAddress * addr)
246{
247 int dir = CTINFO2DIR(ctinfo);
248 int ret = 0;
249 u_int32_t ip;
250 u_int16_t port;
251 u_int16_t rtp_port;
252 struct ip_conntrack_expect *rtp_exp;
253 struct ip_conntrack_expect *rtcp_exp;
254
255 /* Read RTP or RTCP address */
256 if (!get_h245_addr(*data, addr, &ip, &port) ||
257 ip != ct->tuplehash[dir].tuple.src.ip || port == 0)
258 return 0;
259
260 /* RTP port is even */
261 rtp_port = port & (~1);
262
263 /* Create expect for RTP */
264 if ((rtp_exp = ip_conntrack_expect_alloc(ct)) == NULL)
265 return -1;
266 rtp_exp->tuple.src.ip = ct->tuplehash[!dir].tuple.src.ip;
267 rtp_exp->tuple.src.u.udp.port = 0;
268 rtp_exp->tuple.dst.ip = ct->tuplehash[!dir].tuple.dst.ip;
269 rtp_exp->tuple.dst.u.udp.port = htons(rtp_port);
270 rtp_exp->tuple.dst.protonum = IPPROTO_UDP;
271 rtp_exp->mask.src.ip = 0xFFFFFFFF;
272 rtp_exp->mask.src.u.udp.port = 0;
273 rtp_exp->mask.dst.ip = 0xFFFFFFFF;
274 rtp_exp->mask.dst.u.udp.port = 0xFFFF;
275 rtp_exp->mask.dst.protonum = 0xFF;
276 rtp_exp->flags = 0;
277
278 /* Create expect for RTCP */
279 if ((rtcp_exp = ip_conntrack_expect_alloc(ct)) == NULL) {
280 ip_conntrack_expect_put(rtp_exp);
281 return -1;
282 }
283 rtcp_exp->tuple.src.ip = ct->tuplehash[!dir].tuple.src.ip;
284 rtcp_exp->tuple.src.u.udp.port = 0;
285 rtcp_exp->tuple.dst.ip = ct->tuplehash[!dir].tuple.dst.ip;
286 rtcp_exp->tuple.dst.u.udp.port = htons(rtp_port + 1);
287 rtcp_exp->tuple.dst.protonum = IPPROTO_UDP;
288 rtcp_exp->mask.src.ip = 0xFFFFFFFF;
289 rtcp_exp->mask.src.u.udp.port = 0;
290 rtcp_exp->mask.dst.ip = 0xFFFFFFFF;
291 rtcp_exp->mask.dst.u.udp.port = 0xFFFF;
292 rtcp_exp->mask.dst.protonum = 0xFF;
293 rtcp_exp->flags = 0;
294
295 if (ct->tuplehash[dir].tuple.src.ip !=
296 ct->tuplehash[!dir].tuple.dst.ip && nat_rtp_rtcp_hook) {
297 /* NAT needed */
298 ret = nat_rtp_rtcp_hook(pskb, ct, ctinfo, data, dataoff,
299 addr, port, rtp_port, rtp_exp,
300 rtcp_exp);
301 } else { /* Conntrack only */
302 rtp_exp->expectfn = NULL;
303 rtcp_exp->expectfn = NULL;
304
305 if (ip_conntrack_expect_related(rtp_exp) == 0) {
306 if (ip_conntrack_expect_related(rtcp_exp) == 0) {
307 DEBUGP("ip_ct_h323: expect RTP "
308 "%u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
309 NIPQUAD(rtp_exp->tuple.src.ip),
310 ntohs(rtp_exp->tuple.src.u.udp.port),
311 NIPQUAD(rtp_exp->tuple.dst.ip),
312 ntohs(rtp_exp->tuple.dst.u.udp.port));
313 DEBUGP("ip_ct_h323: expect RTCP "
314 "%u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
315 NIPQUAD(rtcp_exp->tuple.src.ip),
316 ntohs(rtcp_exp->tuple.src.u.udp.port),
317 NIPQUAD(rtcp_exp->tuple.dst.ip),
318 ntohs(rtcp_exp->tuple.dst.u.udp.port));
319 } else {
320 ip_conntrack_unexpect_related(rtp_exp);
321 ret = -1;
322 }
323 } else
324 ret = -1;
325 }
326
327 ip_conntrack_expect_put(rtp_exp);
328 ip_conntrack_expect_put(rtcp_exp);
329
330 return ret;
331}
332
333/****************************************************************************/
334static int expect_t120(struct sk_buff **pskb,
335 struct ip_conntrack *ct,
336 enum ip_conntrack_info ctinfo,
337 unsigned char **data, int dataoff,
338 H245_TransportAddress * addr)
339{
340 int dir = CTINFO2DIR(ctinfo);
341 int ret = 0;
342 u_int32_t ip;
343 u_int16_t port;
344 struct ip_conntrack_expect *exp = NULL;
345
346 /* Read T.120 address */
347 if (!get_h245_addr(*data, addr, &ip, &port) ||
348 ip != ct->tuplehash[dir].tuple.src.ip || port == 0)
349 return 0;
350
351 /* Create expect for T.120 connections */
352 if ((exp = ip_conntrack_expect_alloc(ct)) == NULL)
353 return -1;
354 exp->tuple.src.ip = ct->tuplehash[!dir].tuple.src.ip;
355 exp->tuple.src.u.tcp.port = 0;
356 exp->tuple.dst.ip = ct->tuplehash[!dir].tuple.dst.ip;
357 exp->tuple.dst.u.tcp.port = htons(port);
358 exp->tuple.dst.protonum = IPPROTO_TCP;
359 exp->mask.src.ip = 0xFFFFFFFF;
360 exp->mask.src.u.tcp.port = 0;
361 exp->mask.dst.ip = 0xFFFFFFFF;
362 exp->mask.dst.u.tcp.port = 0xFFFF;
363 exp->mask.dst.protonum = 0xFF;
364 exp->flags = IP_CT_EXPECT_PERMANENT; /* Accept multiple channels */
365
366 if (ct->tuplehash[dir].tuple.src.ip !=
367 ct->tuplehash[!dir].tuple.dst.ip && nat_t120_hook) {
368 /* NAT needed */
369 ret = nat_t120_hook(pskb, ct, ctinfo, data, dataoff, addr,
370 port, exp);
371 } else { /* Conntrack only */
372 exp->expectfn = NULL;
373 if (ip_conntrack_expect_related(exp) == 0) {
374 DEBUGP("ip_ct_h323: expect T.120 "
375 "%u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
376 NIPQUAD(exp->tuple.src.ip),
377 ntohs(exp->tuple.src.u.tcp.port),
378 NIPQUAD(exp->tuple.dst.ip),
379 ntohs(exp->tuple.dst.u.tcp.port));
380 } else
381 ret = -1;
382 }
383
384 ip_conntrack_expect_put(exp);
385
386 return ret;
387}
388
389/****************************************************************************/
390static int process_h245_channel(struct sk_buff **pskb,
391 struct ip_conntrack *ct,
392 enum ip_conntrack_info ctinfo,
393 unsigned char **data, int dataoff,
394 H2250LogicalChannelParameters * channel)
395{
396 int ret;
397
398 if (channel->options & eH2250LogicalChannelParameters_mediaChannel) {
399 /* RTP */
400 ret = expect_rtp_rtcp(pskb, ct, ctinfo, data, dataoff,
401 &channel->mediaChannel);
402 if (ret < 0)
403 return -1;
404 }
405
406 if (channel->
407 options & eH2250LogicalChannelParameters_mediaControlChannel) {
408 /* RTCP */
409 ret = expect_rtp_rtcp(pskb, ct, ctinfo, data, dataoff,
410 &channel->mediaControlChannel);
411 if (ret < 0)
412 return -1;
413 }
414
415 return 0;
416}
417
418/****************************************************************************/
419static int process_olc(struct sk_buff **pskb, struct ip_conntrack *ct,
420 enum ip_conntrack_info ctinfo,
421 unsigned char **data, int dataoff,
422 OpenLogicalChannel * olc)
423{
424 int ret;
425
426 DEBUGP("ip_ct_h323: OpenLogicalChannel\n");
427
428 if (olc->forwardLogicalChannelParameters.multiplexParameters.choice ==
429 eOpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters_h2250LogicalChannelParameters)
430 {
431 ret = process_h245_channel(pskb, ct, ctinfo, data, dataoff,
432 &olc->
433 forwardLogicalChannelParameters.
434 multiplexParameters.
435 h2250LogicalChannelParameters);
436 if (ret < 0)
437 return -1;
438 }
439
440 if ((olc->options &
441 eOpenLogicalChannel_reverseLogicalChannelParameters) &&
442 (olc->reverseLogicalChannelParameters.options &
443 eOpenLogicalChannel_reverseLogicalChannelParameters_multiplexParameters)
444 && (olc->reverseLogicalChannelParameters.multiplexParameters.
445 choice ==
446 eOpenLogicalChannel_reverseLogicalChannelParameters_multiplexParameters_h2250LogicalChannelParameters))
447 {
448 ret =
449 process_h245_channel(pskb, ct, ctinfo, data, dataoff,
450 &olc->
451 reverseLogicalChannelParameters.
452 multiplexParameters.
453 h2250LogicalChannelParameters);
454 if (ret < 0)
455 return -1;
456 }
457
458 if ((olc->options & eOpenLogicalChannel_separateStack) &&
459 olc->forwardLogicalChannelParameters.dataType.choice ==
460 eDataType_data &&
461 olc->forwardLogicalChannelParameters.dataType.data.application.
462 choice == eDataApplicationCapability_application_t120 &&
463 olc->forwardLogicalChannelParameters.dataType.data.application.
464 t120.choice == eDataProtocolCapability_separateLANStack &&
465 olc->separateStack.networkAddress.choice ==
466 eNetworkAccessParameters_networkAddress_localAreaAddress) {
467 ret = expect_t120(pskb, ct, ctinfo, data, dataoff,
468 &olc->separateStack.networkAddress.
469 localAreaAddress);
470 if (ret < 0)
471 return -1;
472 }
473
474 return 0;
475}
476
477/****************************************************************************/
478static int process_olca(struct sk_buff **pskb, struct ip_conntrack *ct,
479 enum ip_conntrack_info ctinfo,
480 unsigned char **data, int dataoff,
481 OpenLogicalChannelAck * olca)
482{
483 H2250LogicalChannelAckParameters *ack;
484 int ret;
485
486 DEBUGP("ip_ct_h323: OpenLogicalChannelAck\n");
487
488 if ((olca->options &
489 eOpenLogicalChannelAck_reverseLogicalChannelParameters) &&
490 (olca->reverseLogicalChannelParameters.options &
491 eOpenLogicalChannelAck_reverseLogicalChannelParameters_multiplexParameters)
492 && (olca->reverseLogicalChannelParameters.multiplexParameters.
493 choice ==
494 eOpenLogicalChannelAck_reverseLogicalChannelParameters_multiplexParameters_h2250LogicalChannelParameters))
495 {
496 ret = process_h245_channel(pskb, ct, ctinfo, data, dataoff,
497 &olca->
498 reverseLogicalChannelParameters.
499 multiplexParameters.
500 h2250LogicalChannelParameters);
501 if (ret < 0)
502 return -1;
503 }
504
505 if ((olca->options &
506 eOpenLogicalChannelAck_forwardMultiplexAckParameters) &&
507 (olca->forwardMultiplexAckParameters.choice ==
508 eOpenLogicalChannelAck_forwardMultiplexAckParameters_h2250LogicalChannelAckParameters))
509 {
510 ack = &olca->forwardMultiplexAckParameters.
511 h2250LogicalChannelAckParameters;
512 if (ack->options &
513 eH2250LogicalChannelAckParameters_mediaChannel) {
514 /* RTP */
515 ret = expect_rtp_rtcp(pskb, ct, ctinfo, data, dataoff,
516 &ack->mediaChannel);
517 if (ret < 0)
518 return -1;
519 }
520
521 if (ack->options &
522 eH2250LogicalChannelAckParameters_mediaControlChannel) {
523 /* RTCP */
524 ret = expect_rtp_rtcp(pskb, ct, ctinfo, data, dataoff,
525 &ack->mediaControlChannel);
526 if (ret < 0)
527 return -1;
528 }
529 }
530
531 return 0;
532}
533
534/****************************************************************************/
535static int process_h245(struct sk_buff **pskb, struct ip_conntrack *ct,
536 enum ip_conntrack_info ctinfo,
537 unsigned char **data, int dataoff,
538 MultimediaSystemControlMessage * mscm)
539{
540 switch (mscm->choice) {
541 case eMultimediaSystemControlMessage_request:
542 if (mscm->request.choice ==
543 eRequestMessage_openLogicalChannel) {
544 return process_olc(pskb, ct, ctinfo, data, dataoff,
545 &mscm->request.openLogicalChannel);
546 }
547 DEBUGP("ip_ct_h323: H.245 Request %d\n",
548 mscm->request.choice);
549 break;
550 case eMultimediaSystemControlMessage_response:
551 if (mscm->response.choice ==
552 eResponseMessage_openLogicalChannelAck) {
553 return process_olca(pskb, ct, ctinfo, data, dataoff,
554 &mscm->response.
555 openLogicalChannelAck);
556 }
557 DEBUGP("ip_ct_h323: H.245 Response %d\n",
558 mscm->response.choice);
559 break;
560 default:
561 DEBUGP("ip_ct_h323: H.245 signal %d\n", mscm->choice);
562 break;
563 }
564
565 return 0;
566}
567
568/****************************************************************************/
569static int h245_help(struct sk_buff **pskb, struct ip_conntrack *ct,
570 enum ip_conntrack_info ctinfo)
571{
572 static MultimediaSystemControlMessage mscm;
573 unsigned char *data = NULL;
574 int datalen;
575 int dataoff;
576 int ret;
577
578 /* Until there's been traffic both ways, don't look in packets. */
579 if (ctinfo != IP_CT_ESTABLISHED
580 && ctinfo != IP_CT_ESTABLISHED + IP_CT_IS_REPLY) {
581 return NF_ACCEPT;
582 }
583 DEBUGP("ip_ct_h245: skblen = %u\n", (*pskb)->len);
584
585 spin_lock_bh(&ip_h323_lock);
586
587 /* Process each TPKT */
588 while (get_tpkt_data(pskb, ct, ctinfo, &data, &datalen, &dataoff)) {
589 DEBUGP("ip_ct_h245: TPKT %u.%u.%u.%u->%u.%u.%u.%u, len=%d\n",
590 NIPQUAD((*pskb)->nh.iph->saddr),
591 NIPQUAD((*pskb)->nh.iph->daddr), datalen);
592
593 /* Decode H.245 signal */
594 ret = DecodeMultimediaSystemControlMessage(data, datalen,
595 &mscm);
596 if (ret < 0) {
597 if (net_ratelimit())
598 printk("ip_ct_h245: decoding error: %s\n",
599 ret == H323_ERROR_BOUND ?
600 "out of bound" : "out of range");
601 /* We don't drop when decoding error */
602 break;
603 }
604
605 /* Process H.245 signal */
606 if (process_h245(pskb, ct, ctinfo, &data, dataoff, &mscm) < 0)
607 goto drop;
608 }
609
610 spin_unlock_bh(&ip_h323_lock);
611 return NF_ACCEPT;
612
613 drop:
614 spin_unlock_bh(&ip_h323_lock);
615 if (net_ratelimit())
616 printk("ip_ct_h245: packet dropped\n");
617 return NF_DROP;
618}
619
620/****************************************************************************/
621static struct ip_conntrack_helper ip_conntrack_helper_h245 = {
622 .name = "H.245",
623 .me = THIS_MODULE,
624 .max_expected = H323_RTP_CHANNEL_MAX * 4 + 2 /* T.120 */ ,
625 .timeout = 240,
626 .tuple = {.dst = {.protonum = IPPROTO_TCP}},
627 .mask = {.src = {.u = {0xFFFF}},
628 .dst = {.protonum = 0xFF}},
629 .help = h245_help
630};
631
632/****************************************************************************/
633void ip_conntrack_h245_expect(struct ip_conntrack *new,
634 struct ip_conntrack_expect *this)
635{
636 write_lock_bh(&ip_conntrack_lock);
637 new->helper = &ip_conntrack_helper_h245;
638 write_unlock_bh(&ip_conntrack_lock);
639}
640
641/****************************************************************************/
642static int get_h225_addr(unsigned char *data, TransportAddress * addr,
643 u_int32_t * ip, u_int16_t * port)
644{
645 unsigned char *p;
646
647 if (addr->choice != eTransportAddress_ipAddress)
648 return 0;
649
650 p = data + addr->ipAddress.ip;
651 *ip = htonl((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | (p[3]));
652 *port = (p[4] << 8) | (p[5]);
653
654 return 1;
655}
656
657/****************************************************************************/
658static int expect_h245(struct sk_buff **pskb, struct ip_conntrack *ct,
659 enum ip_conntrack_info ctinfo,
660 unsigned char **data, int dataoff,
661 TransportAddress * addr)
662{
663 int dir = CTINFO2DIR(ctinfo);
664 int ret = 0;
665 u_int32_t ip;
666 u_int16_t port;
667 struct ip_conntrack_expect *exp = NULL;
668
669 /* Read h245Address */
670 if (!get_h225_addr(*data, addr, &ip, &port) ||
671 ip != ct->tuplehash[dir].tuple.src.ip || port == 0)
672 return 0;
673
674 /* Create expect for h245 connection */
675 if ((exp = ip_conntrack_expect_alloc(ct)) == NULL)
676 return -1;
677 exp->tuple.src.ip = ct->tuplehash[!dir].tuple.src.ip;
678 exp->tuple.src.u.tcp.port = 0;
679 exp->tuple.dst.ip = ct->tuplehash[!dir].tuple.dst.ip;
680 exp->tuple.dst.u.tcp.port = htons(port);
681 exp->tuple.dst.protonum = IPPROTO_TCP;
682 exp->mask.src.ip = 0xFFFFFFFF;
683 exp->mask.src.u.tcp.port = 0;
684 exp->mask.dst.ip = 0xFFFFFFFF;
685 exp->mask.dst.u.tcp.port = 0xFFFF;
686 exp->mask.dst.protonum = 0xFF;
687 exp->flags = 0;
688
689 if (ct->tuplehash[dir].tuple.src.ip !=
690 ct->tuplehash[!dir].tuple.dst.ip && nat_h245_hook) {
691 /* NAT needed */
692 ret = nat_h245_hook(pskb, ct, ctinfo, data, dataoff, addr,
693 port, exp);
694 } else { /* Conntrack only */
695 exp->expectfn = ip_conntrack_h245_expect;
696
697 if (ip_conntrack_expect_related(exp) == 0) {
698 DEBUGP("ip_ct_q931: expect H.245 "
699 "%u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
700 NIPQUAD(exp->tuple.src.ip),
701 ntohs(exp->tuple.src.u.tcp.port),
702 NIPQUAD(exp->tuple.dst.ip),
703 ntohs(exp->tuple.dst.u.tcp.port));
704 } else
705 ret = -1;
706 }
707
708 ip_conntrack_expect_put(exp);
709
710 return ret;
711}
712
713/****************************************************************************/
714static int process_setup(struct sk_buff **pskb, struct ip_conntrack *ct,
715 enum ip_conntrack_info ctinfo,
716 unsigned char **data, int dataoff,
717 Setup_UUIE * setup)
718{
719 int dir = CTINFO2DIR(ctinfo);
720 int ret;
721 int i;
722 u_int32_t ip;
723 u_int16_t port;
724
725 DEBUGP("ip_ct_q931: Setup\n");
726
727 if (setup->options & eSetup_UUIE_h245Address) {
728 ret = expect_h245(pskb, ct, ctinfo, data, dataoff,
729 &setup->h245Address);
730 if (ret < 0)
731 return -1;
732 }
733
734 if ((setup->options & eSetup_UUIE_destCallSignalAddress) &&
735 (set_h225_addr_hook) &&
736 get_h225_addr(*data, &setup->destCallSignalAddress, &ip, &port) &&
737 ip != ct->tuplehash[!dir].tuple.src.ip) {
738 DEBUGP("ip_ct_q931: set destCallSignalAddress "
739 "%u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
740 NIPQUAD(ip), port,
741 NIPQUAD(ct->tuplehash[!dir].tuple.src.ip),
742 ntohs(ct->tuplehash[!dir].tuple.src.u.tcp.port));
743 ret = set_h225_addr_hook(pskb, data, dataoff,
744 &setup->destCallSignalAddress,
745 ct->tuplehash[!dir].tuple.src.ip,
746 ntohs(ct->tuplehash[!dir].tuple.src.
747 u.tcp.port));
748 if (ret < 0)
749 return -1;
750 }
751
752 if ((setup->options & eSetup_UUIE_sourceCallSignalAddress) &&
753 (set_h225_addr_hook) &&
754 get_h225_addr(*data, &setup->sourceCallSignalAddress, &ip, &port)
755 && ip != ct->tuplehash[!dir].tuple.dst.ip) {
756 DEBUGP("ip_ct_q931: set sourceCallSignalAddress "
757 "%u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
758 NIPQUAD(ip), port,
759 NIPQUAD(ct->tuplehash[!dir].tuple.dst.ip),
760 ntohs(ct->tuplehash[!dir].tuple.dst.u.tcp.port));
761 ret = set_h225_addr_hook(pskb, data, dataoff,
762 &setup->sourceCallSignalAddress,
763 ct->tuplehash[!dir].tuple.dst.ip,
764 ntohs(ct->tuplehash[!dir].tuple.dst.
765 u.tcp.port));
766 if (ret < 0)
767 return -1;
768 }
769
770 if (setup->options & eSetup_UUIE_fastStart) {
771 for (i = 0; i < setup->fastStart.count; i++) {
772 ret = process_olc(pskb, ct, ctinfo, data, dataoff,
773 &setup->fastStart.item[i]);
774 if (ret < 0)
775 return -1;
776 }
777 }
778
779 return 0;
780}
781
782/****************************************************************************/
783static int process_callproceeding(struct sk_buff **pskb,
784 struct ip_conntrack *ct,
785 enum ip_conntrack_info ctinfo,
786 unsigned char **data, int dataoff,
787 CallProceeding_UUIE * callproc)
788{
789 int ret;
790 int i;
791
792 DEBUGP("ip_ct_q931: CallProceeding\n");
793
794 if (callproc->options & eCallProceeding_UUIE_h245Address) {
795 ret = expect_h245(pskb, ct, ctinfo, data, dataoff,
796 &callproc->h245Address);
797 if (ret < 0)
798 return -1;
799 }
800
801 if (callproc->options & eCallProceeding_UUIE_fastStart) {
802 for (i = 0; i < callproc->fastStart.count; i++) {
803 ret = process_olc(pskb, ct, ctinfo, data, dataoff,
804 &callproc->fastStart.item[i]);
805 if (ret < 0)
806 return -1;
807 }
808 }
809
810 return 0;
811}
812
813/****************************************************************************/
814static int process_connect(struct sk_buff **pskb, struct ip_conntrack *ct,
815 enum ip_conntrack_info ctinfo,
816 unsigned char **data, int dataoff,
817 Connect_UUIE * connect)
818{
819 int ret;
820 int i;
821
822 DEBUGP("ip_ct_q931: Connect\n");
823
824 if (connect->options & eConnect_UUIE_h245Address) {
825 ret = expect_h245(pskb, ct, ctinfo, data, dataoff,
826 &connect->h245Address);
827 if (ret < 0)
828 return -1;
829 }
830
831 if (connect->options & eConnect_UUIE_fastStart) {
832 for (i = 0; i < connect->fastStart.count; i++) {
833 ret = process_olc(pskb, ct, ctinfo, data, dataoff,
834 &connect->fastStart.item[i]);
835 if (ret < 0)
836 return -1;
837 }
838 }
839
840 return 0;
841}
842
843/****************************************************************************/
844static int process_alerting(struct sk_buff **pskb, struct ip_conntrack *ct,
845 enum ip_conntrack_info ctinfo,
846 unsigned char **data, int dataoff,
847 Alerting_UUIE * alert)
848{
849 int ret;
850 int i;
851
852 DEBUGP("ip_ct_q931: Alerting\n");
853
854 if (alert->options & eAlerting_UUIE_h245Address) {
855 ret = expect_h245(pskb, ct, ctinfo, data, dataoff,
856 &alert->h245Address);
857 if (ret < 0)
858 return -1;
859 }
860
861 if (alert->options & eAlerting_UUIE_fastStart) {
862 for (i = 0; i < alert->fastStart.count; i++) {
863 ret = process_olc(pskb, ct, ctinfo, data, dataoff,
864 &alert->fastStart.item[i]);
865 if (ret < 0)
866 return -1;
867 }
868 }
869
870 return 0;
871}
872
873/****************************************************************************/
874static int process_information(struct sk_buff **pskb,
875 struct ip_conntrack *ct,
876 enum ip_conntrack_info ctinfo,
877 unsigned char **data, int dataoff,
878 Information_UUIE * info)
879{
880 int ret;
881 int i;
882
883 DEBUGP("ip_ct_q931: Information\n");
884
885 if (info->options & eInformation_UUIE_fastStart) {
886 for (i = 0; i < info->fastStart.count; i++) {
887 ret = process_olc(pskb, ct, ctinfo, data, dataoff,
888 &info->fastStart.item[i]);
889 if (ret < 0)
890 return -1;
891 }
892 }
893
894 return 0;
895}
896
897/****************************************************************************/
898static int process_facility(struct sk_buff **pskb, struct ip_conntrack *ct,
899 enum ip_conntrack_info ctinfo,
900 unsigned char **data, int dataoff,
901 Facility_UUIE * facility)
902{
903 int ret;
904 int i;
905
906 DEBUGP("ip_ct_q931: Facility\n");
907
908 if (facility->options & eFacility_UUIE_h245Address) {
909 ret = expect_h245(pskb, ct, ctinfo, data, dataoff,
910 &facility->h245Address);
911 if (ret < 0)
912 return -1;
913 }
914
915 if (facility->options & eFacility_UUIE_fastStart) {
916 for (i = 0; i < facility->fastStart.count; i++) {
917 ret = process_olc(pskb, ct, ctinfo, data, dataoff,
918 &facility->fastStart.item[i]);
919 if (ret < 0)
920 return -1;
921 }
922 }
923
924 return 0;
925}
926
927/****************************************************************************/
928static int process_progress(struct sk_buff **pskb, struct ip_conntrack *ct,
929 enum ip_conntrack_info ctinfo,
930 unsigned char **data, int dataoff,
931 Progress_UUIE * progress)
932{
933 int ret;
934 int i;
935
936 DEBUGP("ip_ct_q931: Progress\n");
937
938 if (progress->options & eProgress_UUIE_h245Address) {
939 ret = expect_h245(pskb, ct, ctinfo, data, dataoff,
940 &progress->h245Address);
941 if (ret < 0)
942 return -1;
943 }
944
945 if (progress->options & eProgress_UUIE_fastStart) {
946 for (i = 0; i < progress->fastStart.count; i++) {
947 ret = process_olc(pskb, ct, ctinfo, data, dataoff,
948 &progress->fastStart.item[i]);
949 if (ret < 0)
950 return -1;
951 }
952 }
953
954 return 0;
955}
956
957/****************************************************************************/
958static int process_q931(struct sk_buff **pskb, struct ip_conntrack *ct,
959 enum ip_conntrack_info ctinfo,
960 unsigned char **data, int dataoff, Q931 * q931)
961{
962 H323_UU_PDU *pdu = &q931->UUIE.h323_uu_pdu;
963 int i;
964 int ret = 0;
965
966 switch (pdu->h323_message_body.choice) {
967 case eH323_UU_PDU_h323_message_body_setup:
968 ret = process_setup(pskb, ct, ctinfo, data, dataoff,
969 &pdu->h323_message_body.setup);
970 break;
971 case eH323_UU_PDU_h323_message_body_callProceeding:
972 ret = process_callproceeding(pskb, ct, ctinfo, data, dataoff,
973 &pdu->h323_message_body.
974 callProceeding);
975 break;
976 case eH323_UU_PDU_h323_message_body_connect:
977 ret = process_connect(pskb, ct, ctinfo, data, dataoff,
978 &pdu->h323_message_body.connect);
979 break;
980 case eH323_UU_PDU_h323_message_body_alerting:
981 ret = process_alerting(pskb, ct, ctinfo, data, dataoff,
982 &pdu->h323_message_body.alerting);
983 break;
984 case eH323_UU_PDU_h323_message_body_information:
985 ret = process_information(pskb, ct, ctinfo, data, dataoff,
986 &pdu->h323_message_body.
987 information);
988 break;
989 case eH323_UU_PDU_h323_message_body_facility:
990 ret = process_facility(pskb, ct, ctinfo, data, dataoff,
991 &pdu->h323_message_body.facility);
992 break;
993 case eH323_UU_PDU_h323_message_body_progress:
994 ret = process_progress(pskb, ct, ctinfo, data, dataoff,
995 &pdu->h323_message_body.progress);
996 break;
997 default:
998 DEBUGP("ip_ct_q931: Q.931 signal %d\n",
999 pdu->h323_message_body.choice);
1000 break;
1001 }
1002
1003 if (ret < 0)
1004 return -1;
1005
1006 if (pdu->options & eH323_UU_PDU_h245Control) {
1007 for (i = 0; i < pdu->h245Control.count; i++) {
1008 ret = process_h245(pskb, ct, ctinfo, data, dataoff,
1009 &pdu->h245Control.item[i]);
1010 if (ret < 0)
1011 return -1;
1012 }
1013 }
1014
1015 return 0;
1016}
1017
1018/****************************************************************************/
1019static int q931_help(struct sk_buff **pskb, struct ip_conntrack *ct,
1020 enum ip_conntrack_info ctinfo)
1021{
1022 static Q931 q931;
1023 unsigned char *data = NULL;
1024 int datalen;
1025 int dataoff;
1026 int ret;
1027
1028 /* Until there's been traffic both ways, don't look in packets. */
1029 if (ctinfo != IP_CT_ESTABLISHED
1030 && ctinfo != IP_CT_ESTABLISHED + IP_CT_IS_REPLY) {
1031 return NF_ACCEPT;
1032 }
1033 DEBUGP("ip_ct_q931: skblen = %u\n", (*pskb)->len);
1034
1035 spin_lock_bh(&ip_h323_lock);
1036
1037 /* Process each TPKT */
1038 while (get_tpkt_data(pskb, ct, ctinfo, &data, &datalen, &dataoff)) {
1039 DEBUGP("ip_ct_q931: TPKT %u.%u.%u.%u->%u.%u.%u.%u, len=%d\n",
1040 NIPQUAD((*pskb)->nh.iph->saddr),
1041 NIPQUAD((*pskb)->nh.iph->daddr), datalen);
1042
1043 /* Decode Q.931 signal */
1044 ret = DecodeQ931(data, datalen, &q931);
1045 if (ret < 0) {
1046 if (net_ratelimit())
1047 printk("ip_ct_q931: decoding error: %s\n",
1048 ret == H323_ERROR_BOUND ?
1049 "out of bound" : "out of range");
1050 /* We don't drop when decoding error */
1051 break;
1052 }
1053
1054 /* Process Q.931 signal */
1055 if (process_q931(pskb, ct, ctinfo, &data, dataoff, &q931) < 0)
1056 goto drop;
1057 }
1058
1059 spin_unlock_bh(&ip_h323_lock);
1060 return NF_ACCEPT;
1061
1062 drop:
1063 spin_unlock_bh(&ip_h323_lock);
1064 if (net_ratelimit())
1065 printk("ip_ct_q931: packet dropped\n");
1066 return NF_DROP;
1067}
1068
1069/****************************************************************************/
1070static struct ip_conntrack_helper ip_conntrack_helper_q931 = {
1071 .name = "Q.931",
1072 .me = THIS_MODULE,
1073 .max_expected = H323_RTP_CHANNEL_MAX * 4 + 4 /* T.120 and H.245 */ ,
1074 .timeout = 240,
1075 .tuple = {.src = {.u = {__constant_htons(Q931_PORT)}},
1076 .dst = {.protonum = IPPROTO_TCP}},
1077 .mask = {.src = {.u = {0xFFFF}},
1078 .dst = {.protonum = 0xFF}},
1079 .help = q931_help
1080};
1081
1082/****************************************************************************/
1083void ip_conntrack_q931_expect(struct ip_conntrack *new,
1084 struct ip_conntrack_expect *this)
1085{
1086 write_lock_bh(&ip_conntrack_lock);
1087 new->helper = &ip_conntrack_helper_q931;
1088 write_unlock_bh(&ip_conntrack_lock);
1089}
1090
1091/****************************************************************************/
1092static unsigned char *get_udp_data(struct sk_buff **pskb, int *datalen)
1093{
1094 struct udphdr _uh, *uh;
1095 int dataoff;
1096
1097 uh = skb_header_pointer(*pskb, (*pskb)->nh.iph->ihl * 4, sizeof(_uh),
1098 &_uh);
1099 if (uh == NULL)
1100 return NULL;
1101 dataoff = (*pskb)->nh.iph->ihl * 4 + sizeof(_uh);
1102 if (dataoff >= (*pskb)->len)
1103 return NULL;
1104 *datalen = (*pskb)->len - dataoff;
1105 return skb_header_pointer(*pskb, dataoff, *datalen, h323_buffer);
1106}
1107
1108/****************************************************************************/
1109static struct ip_conntrack_expect *find_expect(struct ip_conntrack *ct,
1110 u_int32_t ip, u_int16_t port)
1111{
1112 struct ip_conntrack_expect *exp;
1113 struct ip_conntrack_tuple tuple;
1114
1115 tuple.src.ip = 0;
1116 tuple.src.u.tcp.port = 0;
1117 tuple.dst.ip = ip;
1118 tuple.dst.u.tcp.port = htons(port);
1119 tuple.dst.protonum = IPPROTO_TCP;
1120
1121 exp = __ip_conntrack_expect_find(&tuple);
1122 if (exp->master == ct)
1123 return exp;
1124 return NULL;
1125}
1126
1127/****************************************************************************/
1128static int set_expect_timeout(struct ip_conntrack_expect *exp,
1129 unsigned timeout)
1130{
1131 if (!exp || !del_timer(&exp->timeout))
1132 return 0;
1133
1134 exp->timeout.expires = jiffies + timeout * HZ;
1135 add_timer(&exp->timeout);
1136
1137 return 1;
1138}
1139
1140/****************************************************************************/
1141static int expect_q931(struct sk_buff **pskb, struct ip_conntrack *ct,
1142 enum ip_conntrack_info ctinfo,
1143 unsigned char **data,
1144 TransportAddress * addr, int count)
1145{
1146 struct ip_ct_h323_master *info = &ct->help.ct_h323_info;
1147 int dir = CTINFO2DIR(ctinfo);
1148 int ret = 0;
1149 int i;
1150 u_int32_t ip;
1151 u_int16_t port;
1152 struct ip_conntrack_expect *exp;
1153
1154 /* Look for the first related address */
1155 for (i = 0; i < count; i++) {
1156 if (get_h225_addr(*data, &addr[i], &ip, &port) &&
1157 ip == ct->tuplehash[dir].tuple.src.ip && port != 0)
1158 break;
1159 }
1160
1161 if (i >= count) /* Not found */
1162 return 0;
1163
1164 /* Create expect for Q.931 */
1165 if ((exp = ip_conntrack_expect_alloc(ct)) == NULL)
1166 return -1;
1167 exp->tuple.src.ip = gkrouted_only ? /* only accept calls from GK? */
1168 ct->tuplehash[!dir].tuple.src.ip : 0;
1169 exp->tuple.src.u.tcp.port = 0;
1170 exp->tuple.dst.ip = ct->tuplehash[!dir].tuple.dst.ip;
1171 exp->tuple.dst.u.tcp.port = htons(port);
1172 exp->tuple.dst.protonum = IPPROTO_TCP;
1173 exp->mask.src.ip = gkrouted_only ? 0xFFFFFFFF : 0;
1174 exp->mask.src.u.tcp.port = 0;
1175 exp->mask.dst.ip = 0xFFFFFFFF;
1176 exp->mask.dst.u.tcp.port = 0xFFFF;
1177 exp->mask.dst.protonum = 0xFF;
1178 exp->flags = IP_CT_EXPECT_PERMANENT; /* Accept multiple calls */
1179
1180 if (nat_q931_hook) { /* Need NAT */
1181 ret = nat_q931_hook(pskb, ct, ctinfo, data, addr, i,
1182 port, exp);
1183 } else { /* Conntrack only */
1184 exp->expectfn = ip_conntrack_q931_expect;
1185
1186 if (ip_conntrack_expect_related(exp) == 0) {
1187 DEBUGP("ip_ct_ras: expect Q.931 "
1188 "%u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
1189 NIPQUAD(exp->tuple.src.ip),
1190 ntohs(exp->tuple.src.u.tcp.port),
1191 NIPQUAD(exp->tuple.dst.ip),
1192 ntohs(exp->tuple.dst.u.tcp.port));
1193
1194 /* Save port for looking up expect in processing RCF */
1195 info->sig_port[dir] = port;
1196 } else
1197 ret = -1;
1198 }
1199
1200 ip_conntrack_expect_put(exp);
1201
1202 return ret;
1203}
1204
1205/****************************************************************************/
1206static int process_grq(struct sk_buff **pskb, struct ip_conntrack *ct,
1207 enum ip_conntrack_info ctinfo,
1208 unsigned char **data, GatekeeperRequest * grq)
1209{
1210 DEBUGP("ip_ct_ras: GRQ\n");
1211
1212 if (set_ras_addr_hook) /* NATed */
1213 return set_ras_addr_hook(pskb, ct, ctinfo, data,
1214 &grq->rasAddress, 1);
1215 return 0;
1216}
1217
1218/* Declare before using */
1219static void ip_conntrack_ras_expect(struct ip_conntrack *new,
1220 struct ip_conntrack_expect *this);
1221
1222/****************************************************************************/
1223static int process_gcf(struct sk_buff **pskb, struct ip_conntrack *ct,
1224 enum ip_conntrack_info ctinfo,
1225 unsigned char **data, GatekeeperConfirm * gcf)
1226{
1227 int dir = CTINFO2DIR(ctinfo);
1228 int ret = 0;
1229 u_int32_t ip;
1230 u_int16_t port;
1231 struct ip_conntrack_expect *exp;
1232
1233 DEBUGP("ip_ct_ras: GCF\n");
1234
1235 if (!get_h225_addr(*data, &gcf->rasAddress, &ip, &port))
1236 return 0;
1237
1238 /* Registration port is the same as discovery port */
1239 if (ip == ct->tuplehash[dir].tuple.src.ip &&
1240 port == ntohs(ct->tuplehash[dir].tuple.src.u.udp.port))
1241 return 0;
1242
1243 /* Avoid RAS expectation loops. A GCF is never expected. */
1244 if (test_bit(IPS_EXPECTED_BIT, &ct->status))
1245 return 0;
1246
1247 /* Need new expect */
1248 if ((exp = ip_conntrack_expect_alloc(ct)) == NULL)
1249 return -1;
1250 exp->tuple.src.ip = ct->tuplehash[!dir].tuple.src.ip;
1251 exp->tuple.src.u.tcp.port = 0;
1252 exp->tuple.dst.ip = ip;
1253 exp->tuple.dst.u.tcp.port = htons(port);
1254 exp->tuple.dst.protonum = IPPROTO_UDP;
1255 exp->mask.src.ip = 0xFFFFFFFF;
1256 exp->mask.src.u.tcp.port = 0;
1257 exp->mask.dst.ip = 0xFFFFFFFF;
1258 exp->mask.dst.u.tcp.port = 0xFFFF;
1259 exp->mask.dst.protonum = 0xFF;
1260 exp->flags = 0;
1261 exp->expectfn = ip_conntrack_ras_expect;
1262 if (ip_conntrack_expect_related(exp) == 0) {
1263 DEBUGP("ip_ct_ras: expect RAS "
1264 "%u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
1265 NIPQUAD(exp->tuple.src.ip),
1266 ntohs(exp->tuple.src.u.tcp.port),
1267 NIPQUAD(exp->tuple.dst.ip),
1268 ntohs(exp->tuple.dst.u.tcp.port));
1269 } else
1270 ret = -1;
1271
1272 ip_conntrack_expect_put(exp);
1273
1274 return ret;
1275}
1276
1277/****************************************************************************/
1278static int process_rrq(struct sk_buff **pskb, struct ip_conntrack *ct,
1279 enum ip_conntrack_info ctinfo,
1280 unsigned char **data, RegistrationRequest * rrq)
1281{
1282 struct ip_ct_h323_master *info = &ct->help.ct_h323_info;
1283 int ret;
1284
1285 DEBUGP("ip_ct_ras: RRQ\n");
1286
1287 ret = expect_q931(pskb, ct, ctinfo, data,
1288 rrq->callSignalAddress.item,
1289 rrq->callSignalAddress.count);
1290 if (ret < 0)
1291 return -1;
1292
1293 if (set_ras_addr_hook) {
1294 ret = set_ras_addr_hook(pskb, ct, ctinfo, data,
1295 rrq->rasAddress.item,
1296 rrq->rasAddress.count);
1297 if (ret < 0)
1298 return -1;
1299 }
1300
1301 if (rrq->options & eRegistrationRequest_timeToLive) {
1302 DEBUGP("ip_ct_ras: RRQ TTL = %u seconds\n", rrq->timeToLive);
1303 info->timeout = rrq->timeToLive;
1304 } else
1305 info->timeout = 0;
1306
1307 return 0;
1308}
1309
1310/****************************************************************************/
1311static int process_rcf(struct sk_buff **pskb, struct ip_conntrack *ct,
1312 enum ip_conntrack_info ctinfo,
1313 unsigned char **data, RegistrationConfirm * rcf)
1314{
1315 struct ip_ct_h323_master *info = &ct->help.ct_h323_info;
1316 int dir = CTINFO2DIR(ctinfo);
1317 int ret;
1318 struct ip_conntrack_expect *exp;
1319
1320 DEBUGP("ip_ct_ras: RCF\n");
1321
1322 if (set_sig_addr_hook) {
1323 ret = set_sig_addr_hook(pskb, ct, ctinfo, data,
1324 rcf->callSignalAddress.item,
1325 rcf->callSignalAddress.count);
1326 if (ret < 0)
1327 return -1;
1328 }
1329
1330 if (rcf->options & eRegistrationConfirm_timeToLive) {
1331 DEBUGP("ip_ct_ras: RCF TTL = %u seconds\n", rcf->timeToLive);
1332 info->timeout = rcf->timeToLive;
1333 }
1334
1335 if (info->timeout > 0) {
1336 DEBUGP
1337 ("ip_ct_ras: set RAS connection timeout to %u seconds\n",
1338 info->timeout);
1339 ip_ct_refresh_acct(ct, ctinfo, NULL, info->timeout * HZ);
1340
1341 /* Set expect timeout */
1342 read_lock_bh(&ip_conntrack_lock);
1343 exp = find_expect(ct, ct->tuplehash[dir].tuple.dst.ip,
1344 info->sig_port[!dir]);
1345 if (exp) {
1346 DEBUGP("ip_ct_ras: set Q.931 expect "
1347 "(%u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu) "
1348 "timeout to %u seconds\n",
1349 NIPQUAD(exp->tuple.src.ip),
1350 ntohs(exp->tuple.src.u.tcp.port),
1351 NIPQUAD(exp->tuple.dst.ip),
1352 ntohs(exp->tuple.dst.u.tcp.port),
1353 info->timeout);
1354 set_expect_timeout(exp, info->timeout);
1355 }
1356 read_unlock_bh(&ip_conntrack_lock);
1357 }
1358
1359 return 0;
1360}
1361
1362/****************************************************************************/
1363static int process_urq(struct sk_buff **pskb, struct ip_conntrack *ct,
1364 enum ip_conntrack_info ctinfo,
1365 unsigned char **data, UnregistrationRequest * urq)
1366{
1367 struct ip_ct_h323_master *info = &ct->help.ct_h323_info;
1368 int dir = CTINFO2DIR(ctinfo);
1369 int ret;
1370
1371 DEBUGP("ip_ct_ras: URQ\n");
1372
1373 if (set_sig_addr_hook) {
1374 ret = set_sig_addr_hook(pskb, ct, ctinfo, data,
1375 urq->callSignalAddress.item,
1376 urq->callSignalAddress.count);
1377 if (ret < 0)
1378 return -1;
1379 }
1380
1381 /* Clear old expect */
1382 ip_ct_remove_expectations(ct);
1383 info->sig_port[dir] = 0;
1384 info->sig_port[!dir] = 0;
1385
1386 /* Give it 30 seconds for UCF or URJ */
1387 ip_ct_refresh_acct(ct, ctinfo, NULL, 30 * HZ);
1388
1389 return 0;
1390}
1391
1392/****************************************************************************/
1393static int process_arq(struct sk_buff **pskb, struct ip_conntrack *ct,
1394 enum ip_conntrack_info ctinfo,
1395 unsigned char **data, AdmissionRequest * arq)
1396{
1397 struct ip_ct_h323_master *info = &ct->help.ct_h323_info;
1398 int dir = CTINFO2DIR(ctinfo);
1399 u_int32_t ip;
1400 u_int16_t port;
1401
1402 DEBUGP("ip_ct_ras: ARQ\n");
1403
1404 if ((arq->options & eAdmissionRequest_destCallSignalAddress) &&
1405 get_h225_addr(*data, &arq->destCallSignalAddress, &ip, &port) &&
1406 ip == ct->tuplehash[dir].tuple.src.ip &&
1407 port == info->sig_port[dir] && set_h225_addr_hook) {
1408 /* Answering ARQ */
1409 return set_h225_addr_hook(pskb, data, 0,
1410 &arq->destCallSignalAddress,
1411 ct->tuplehash[!dir].tuple.dst.ip,
1412 info->sig_port[!dir]);
1413 }
1414
1415 if ((arq->options & eAdmissionRequest_srcCallSignalAddress) &&
1416 get_h225_addr(*data, &arq->srcCallSignalAddress, &ip, &port) &&
1417 ip == ct->tuplehash[dir].tuple.src.ip && set_h225_addr_hook) {
1418 /* Calling ARQ */
1419 return set_h225_addr_hook(pskb, data, 0,
1420 &arq->srcCallSignalAddress,
1421 ct->tuplehash[!dir].tuple.dst.ip,
1422 port);
1423 }
1424
1425 return 0;
1426}
1427
1428/****************************************************************************/
1429static int process_acf(struct sk_buff **pskb, struct ip_conntrack *ct,
1430 enum ip_conntrack_info ctinfo,
1431 unsigned char **data, AdmissionConfirm * acf)
1432{
1433 int dir = CTINFO2DIR(ctinfo);
1434 int ret = 0;
1435 u_int32_t ip;
1436 u_int16_t port;
1437 struct ip_conntrack_expect *exp;
1438
1439 DEBUGP("ip_ct_ras: ACF\n");
1440
1441 if (!get_h225_addr(*data, &acf->destCallSignalAddress, &ip, &port))
1442 return 0;
1443
1444 if (ip == ct->tuplehash[dir].tuple.dst.ip) { /* Answering ACF */
1445 if (set_sig_addr_hook)
1446 return set_sig_addr_hook(pskb, ct, ctinfo, data,
1447 &acf->destCallSignalAddress,
1448 1);
1449 return 0;
1450 }
1451
1452 /* Need new expect */
1453 if ((exp = ip_conntrack_expect_alloc(ct)) == NULL)
1454 return -1;
1455 exp->tuple.src.ip = ct->tuplehash[!dir].tuple.src.ip;
1456 exp->tuple.src.u.tcp.port = 0;
1457 exp->tuple.dst.ip = ip;
1458 exp->tuple.dst.u.tcp.port = htons(port);
1459 exp->tuple.dst.protonum = IPPROTO_TCP;
1460 exp->mask.src.ip = 0xFFFFFFFF;
1461 exp->mask.src.u.tcp.port = 0;
1462 exp->mask.dst.ip = 0xFFFFFFFF;
1463 exp->mask.dst.u.tcp.port = 0xFFFF;
1464 exp->mask.dst.protonum = 0xFF;
1465 exp->flags = IP_CT_EXPECT_PERMANENT;
1466 exp->expectfn = ip_conntrack_q931_expect;
1467
1468 if (ip_conntrack_expect_related(exp) == 0) {
1469 DEBUGP("ip_ct_ras: expect Q.931 "
1470 "%u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
1471 NIPQUAD(exp->tuple.src.ip),
1472 ntohs(exp->tuple.src.u.tcp.port),
1473 NIPQUAD(exp->tuple.dst.ip),
1474 ntohs(exp->tuple.dst.u.tcp.port));
1475 } else
1476 ret = -1;
1477
1478 ip_conntrack_expect_put(exp);
1479
1480 return ret;
1481}
1482
1483/****************************************************************************/
1484static int process_lrq(struct sk_buff **pskb, struct ip_conntrack *ct,
1485 enum ip_conntrack_info ctinfo,
1486 unsigned char **data, LocationRequest * lrq)
1487{
1488 DEBUGP("ip_ct_ras: LRQ\n");
1489
1490 if (set_ras_addr_hook)
1491 return set_ras_addr_hook(pskb, ct, ctinfo, data,
1492 &lrq->replyAddress, 1);
1493 return 0;
1494}
1495
1496/****************************************************************************/
1497static int process_lcf(struct sk_buff **pskb, struct ip_conntrack *ct,
1498 enum ip_conntrack_info ctinfo,
1499 unsigned char **data, LocationConfirm * lcf)
1500{
1501 int dir = CTINFO2DIR(ctinfo);
1502 int ret = 0;
1503 u_int32_t ip;
1504 u_int16_t port;
1505 struct ip_conntrack_expect *exp = NULL;
1506
1507 DEBUGP("ip_ct_ras: LCF\n");
1508
1509 if (!get_h225_addr(*data, &lcf->callSignalAddress, &ip, &port))
1510 return 0;
1511
1512 /* Need new expect for call signal */
1513 if ((exp = ip_conntrack_expect_alloc(ct)) == NULL)
1514 return -1;
1515 exp->tuple.src.ip = ct->tuplehash[!dir].tuple.src.ip;
1516 exp->tuple.src.u.tcp.port = 0;
1517 exp->tuple.dst.ip = ip;
1518 exp->tuple.dst.u.tcp.port = htons(port);
1519 exp->tuple.dst.protonum = IPPROTO_TCP;
1520 exp->mask.src.ip = 0xFFFFFFFF;
1521 exp->mask.src.u.tcp.port = 0;
1522 exp->mask.dst.ip = 0xFFFFFFFF;
1523 exp->mask.dst.u.tcp.port = 0xFFFF;
1524 exp->mask.dst.protonum = 0xFF;
1525 exp->flags = IP_CT_EXPECT_PERMANENT;
1526 exp->expectfn = ip_conntrack_q931_expect;
1527
1528 if (ip_conntrack_expect_related(exp) == 0) {
1529 DEBUGP("ip_ct_ras: expect Q.931 "
1530 "%u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
1531 NIPQUAD(exp->tuple.src.ip),
1532 ntohs(exp->tuple.src.u.tcp.port),
1533 NIPQUAD(exp->tuple.dst.ip),
1534 ntohs(exp->tuple.dst.u.tcp.port));
1535 } else
1536 ret = -1;
1537
1538 ip_conntrack_expect_put(exp);
1539
1540 /* Ignore rasAddress */
1541
1542 return ret;
1543}
1544
1545/****************************************************************************/
1546static int process_irr(struct sk_buff **pskb, struct ip_conntrack *ct,
1547 enum ip_conntrack_info ctinfo,
1548 unsigned char **data, InfoRequestResponse * irr)
1549{
1550 int ret;
1551
1552 DEBUGP("ip_ct_ras: IRR\n");
1553
1554 if (set_ras_addr_hook) {
1555 ret = set_ras_addr_hook(pskb, ct, ctinfo, data,
1556 &irr->rasAddress, 1);
1557 if (ret < 0)
1558 return -1;
1559 }
1560
1561 if (set_sig_addr_hook) {
1562 ret = set_sig_addr_hook(pskb, ct, ctinfo, data,
1563 irr->callSignalAddress.item,
1564 irr->callSignalAddress.count);
1565 if (ret < 0)
1566 return -1;
1567 }
1568
1569 return 0;
1570}
1571
1572/****************************************************************************/
1573static int process_ras(struct sk_buff **pskb, struct ip_conntrack *ct,
1574 enum ip_conntrack_info ctinfo,
1575 unsigned char **data, RasMessage * ras)
1576{
1577 switch (ras->choice) {
1578 case eRasMessage_gatekeeperRequest:
1579 return process_grq(pskb, ct, ctinfo, data,
1580 &ras->gatekeeperRequest);
1581 case eRasMessage_gatekeeperConfirm:
1582 return process_gcf(pskb, ct, ctinfo, data,
1583 &ras->gatekeeperConfirm);
1584 case eRasMessage_registrationRequest:
1585 return process_rrq(pskb, ct, ctinfo, data,
1586 &ras->registrationRequest);
1587 case eRasMessage_registrationConfirm:
1588 return process_rcf(pskb, ct, ctinfo, data,
1589 &ras->registrationConfirm);
1590 case eRasMessage_unregistrationRequest:
1591 return process_urq(pskb, ct, ctinfo, data,
1592 &ras->unregistrationRequest);
1593 case eRasMessage_admissionRequest:
1594 return process_arq(pskb, ct, ctinfo, data,
1595 &ras->admissionRequest);
1596 case eRasMessage_admissionConfirm:
1597 return process_acf(pskb, ct, ctinfo, data,
1598 &ras->admissionConfirm);
1599 case eRasMessage_locationRequest:
1600 return process_lrq(pskb, ct, ctinfo, data,
1601 &ras->locationRequest);
1602 case eRasMessage_locationConfirm:
1603 return process_lcf(pskb, ct, ctinfo, data,
1604 &ras->locationConfirm);
1605 case eRasMessage_infoRequestResponse:
1606 return process_irr(pskb, ct, ctinfo, data,
1607 &ras->infoRequestResponse);
1608 default:
1609 DEBUGP("ip_ct_ras: RAS message %d\n", ras->choice);
1610 break;
1611 }
1612
1613 return 0;
1614}
1615
1616/****************************************************************************/
1617static int ras_help(struct sk_buff **pskb, struct ip_conntrack *ct,
1618 enum ip_conntrack_info ctinfo)
1619{
1620 static RasMessage ras;
1621 unsigned char *data;
1622 int datalen = 0;
1623 int ret;
1624
1625 DEBUGP("ip_ct_ras: skblen = %u\n", (*pskb)->len);
1626
1627 spin_lock_bh(&ip_h323_lock);
1628
1629 /* Get UDP data */
1630 data = get_udp_data(pskb, &datalen);
1631 if (data == NULL)
1632 goto accept;
1633 DEBUGP("ip_ct_ras: RAS message %u.%u.%u.%u->%u.%u.%u.%u, len=%d\n",
1634 NIPQUAD((*pskb)->nh.iph->saddr),
1635 NIPQUAD((*pskb)->nh.iph->daddr), datalen);
1636
1637 /* Decode RAS message */
1638 ret = DecodeRasMessage(data, datalen, &ras);
1639 if (ret < 0) {
1640 if (net_ratelimit())
1641 printk("ip_ct_ras: decoding error: %s\n",
1642 ret == H323_ERROR_BOUND ?
1643 "out of bound" : "out of range");
1644 goto accept;
1645 }
1646
1647 /* Process RAS message */
1648 if (process_ras(pskb, ct, ctinfo, &data, &ras) < 0)
1649 goto drop;
1650
1651 accept:
1652 spin_unlock_bh(&ip_h323_lock);
1653 return NF_ACCEPT;
1654
1655 drop:
1656 spin_unlock_bh(&ip_h323_lock);
1657 if (net_ratelimit())
1658 printk("ip_ct_ras: packet dropped\n");
1659 return NF_DROP;
1660}
1661
1662/****************************************************************************/
1663static struct ip_conntrack_helper ip_conntrack_helper_ras = {
1664 .name = "RAS",
1665 .me = THIS_MODULE,
1666 .max_expected = 32,
1667 .timeout = 240,
1668 .tuple = {.src = {.u = {__constant_htons(RAS_PORT)}},
1669 .dst = {.protonum = IPPROTO_UDP}},
1670 .mask = {.src = {.u = {0xFFFE}},
1671 .dst = {.protonum = 0xFF}},
1672 .help = ras_help,
1673};
1674
1675/****************************************************************************/
1676static void ip_conntrack_ras_expect(struct ip_conntrack *new,
1677 struct ip_conntrack_expect *this)
1678{
1679 write_lock_bh(&ip_conntrack_lock);
1680 new->helper = &ip_conntrack_helper_ras;
1681 write_unlock_bh(&ip_conntrack_lock);
1682}
1683
1684/****************************************************************************/
1685/* Not __exit - called from init() */
1686static void fini(void)
1687{
1688 ip_conntrack_helper_unregister(&ip_conntrack_helper_ras);
1689 ip_conntrack_helper_unregister(&ip_conntrack_helper_q931);
1690 kfree(h323_buffer);
1691 DEBUGP("ip_ct_h323: fini\n");
1692}
1693
1694/****************************************************************************/
1695static int __init init(void)
1696{
1697 int ret;
1698
1699 h323_buffer = kmalloc(65536, GFP_KERNEL);
1700 if (!h323_buffer)
1701 return -ENOMEM;
1702 if ((ret = ip_conntrack_helper_register(&ip_conntrack_helper_q931)) ||
1703 (ret = ip_conntrack_helper_register(&ip_conntrack_helper_ras))) {
1704 fini();
1705 return ret;
1706 }
1707
1708 DEBUGP("ip_ct_h323: init success\n");
1709 return 0;
1710}
1711
1712/****************************************************************************/
1713module_init(init);
1714module_exit(fini);
1715
1716EXPORT_SYMBOL(get_h245_addr);
1717EXPORT_SYMBOL(get_h225_addr);
1718EXPORT_SYMBOL(ip_conntrack_h245_expect);
1719EXPORT_SYMBOL(ip_conntrack_q931_expect);
1720EXPORT_SYMBOL(set_h245_addr_hook);
1721EXPORT_SYMBOL(set_h225_addr_hook);
1722EXPORT_SYMBOL(set_sig_addr_hook);
1723EXPORT_SYMBOL(set_ras_addr_hook);
1724EXPORT_SYMBOL(nat_rtp_rtcp_hook);
1725EXPORT_SYMBOL(nat_t120_hook);
1726EXPORT_SYMBOL(nat_h245_hook);
1727EXPORT_SYMBOL(nat_q931_hook);
1728
1729MODULE_AUTHOR("Jing Min Zhao <zhaojingmin@users.sourceforge.net>");
1730MODULE_DESCRIPTION("H.323 connection tracking helper");
1731MODULE_LICENSE("GPL");
diff --git a/net/ipv4/netfilter/ip_conntrack_helper_h323_asn1.c b/net/ipv4/netfilter/ip_conntrack_helper_h323_asn1.c
new file mode 100644
index 000000000000..afa525129b51
--- /dev/null
+++ b/net/ipv4/netfilter/ip_conntrack_helper_h323_asn1.c
@@ -0,0 +1,870 @@
1/****************************************************************************
2 * ip_conntrack_helper_h323_asn1.c - BER and PER decoding library for H.323
3 * conntrack/NAT module.
4 *
5 * Copyright (c) 2006 by Jing Min Zhao <zhaojingmin@hotmail.com>
6 *
7 * This source code is licensed under General Public License version 2.
8 *
9 * See ip_conntrack_helper_h323_asn1.h for details.
10 *
11 ****************************************************************************/
12
13#ifdef __KERNEL__
14#include <linux/kernel.h>
15#else
16#include <stdio.h>
17#endif
18#include "ip_conntrack_helper_h323_asn1.h"
19
20/* Trace Flag */
21#ifndef H323_TRACE
22#define H323_TRACE 0
23#endif
24
25#if H323_TRACE
26#define TAB_SIZE 4
27#define IFTHEN(cond, act) if(cond){act;}
28#ifdef __KERNEL__
29#define PRINT printk
30#else
31#define PRINT printf
32#endif
33#define FNAME(name) name,
34#else
35#define IFTHEN(cond, act)
36#define PRINT(fmt, args...)
37#define FNAME(name)
38#endif
39
40/* ASN.1 Types */
41#define NUL 0
42#define BOOL 1
43#define OID 2
44#define INT 3
45#define ENUM 4
46#define BITSTR 5
47#define NUMSTR 6
48#define NUMDGT 6
49#define TBCDSTR 6
50#define OCTSTR 7
51#define PRTSTR 7
52#define IA5STR 7
53#define GENSTR 7
54#define BMPSTR 8
55#define SEQ 9
56#define SET 9
57#define SEQOF 10
58#define SETOF 10
59#define CHOICE 11
60
61/* Constraint Types */
62#define FIXD 0
63/* #define BITS 1-8 */
64#define BYTE 9
65#define WORD 10
66#define CONS 11
67#define SEMI 12
68#define UNCO 13
69
70/* ASN.1 Type Attributes */
71#define SKIP 0
72#define STOP 1
73#define DECODE 2
74#define EXT 4
75#define OPEN 8
76#define OPT 16
77
78
79/* ASN.1 Field Structure */
80typedef struct field_t {
81#if H323_TRACE
82 char *name;
83#endif
84 unsigned char type;
85 unsigned char sz;
86 unsigned char lb;
87 unsigned char ub;
88 unsigned short attr;
89 unsigned short offset;
90 struct field_t *fields;
91} field_t;
92
93/* Bit Stream */
94typedef struct {
95 unsigned char *buf;
96 unsigned char *beg;
97 unsigned char *end;
98 unsigned char *cur;
99 unsigned bit;
100} bitstr_t;
101
102/* Tool Functions */
103#define INC_BIT(bs) if((++bs->bit)>7){bs->cur++;bs->bit=0;}
104#define INC_BITS(bs,b) if((bs->bit+=b)>7){bs->cur+=bs->bit>>3;bs->bit&=7;}
105#define BYTE_ALIGN(bs) if(bs->bit){bs->cur++;bs->bit=0;}
106#define CHECK_BOUND(bs,n) if(bs->cur+(n)>bs->end)return(H323_ERROR_BOUND)
107static unsigned get_len(bitstr_t * bs);
108static unsigned get_bit(bitstr_t * bs);
109static unsigned get_bits(bitstr_t * bs, unsigned b);
110static unsigned get_bitmap(bitstr_t * bs, unsigned b);
111static unsigned get_uint(bitstr_t * bs, int b);
112
113/* Decoder Functions */
114static int decode_nul(bitstr_t * bs, field_t * f, char *base, int level);
115static int decode_bool(bitstr_t * bs, field_t * f, char *base, int level);
116static int decode_oid(bitstr_t * bs, field_t * f, char *base, int level);
117static int decode_int(bitstr_t * bs, field_t * f, char *base, int level);
118static int decode_enum(bitstr_t * bs, field_t * f, char *base, int level);
119static int decode_bitstr(bitstr_t * bs, field_t * f, char *base, int level);
120static int decode_numstr(bitstr_t * bs, field_t * f, char *base, int level);
121static int decode_octstr(bitstr_t * bs, field_t * f, char *base, int level);
122static int decode_bmpstr(bitstr_t * bs, field_t * f, char *base, int level);
123static int decode_seq(bitstr_t * bs, field_t * f, char *base, int level);
124static int decode_seqof(bitstr_t * bs, field_t * f, char *base, int level);
125static int decode_choice(bitstr_t * bs, field_t * f, char *base, int level);
126
127/* Decoder Functions Vector */
128typedef int (*decoder_t) (bitstr_t *, field_t *, char *, int);
129static decoder_t Decoders[] = {
130 decode_nul,
131 decode_bool,
132 decode_oid,
133 decode_int,
134 decode_enum,
135 decode_bitstr,
136 decode_numstr,
137 decode_octstr,
138 decode_bmpstr,
139 decode_seq,
140 decode_seqof,
141 decode_choice,
142};
143
144/****************************************************************************
145 * H.323 Types
146 ****************************************************************************/
147#include "ip_conntrack_helper_h323_types.c"
148
149/****************************************************************************
150 * Functions
151 ****************************************************************************/
152/* Assume bs is aligned && v < 16384 */
153unsigned get_len(bitstr_t * bs)
154{
155 unsigned v;
156
157 v = *bs->cur++;
158
159 if (v & 0x80) {
160 v &= 0x3f;
161 v <<= 8;
162 v += *bs->cur++;
163 }
164
165 return v;
166}
167
168/****************************************************************************/
169unsigned get_bit(bitstr_t * bs)
170{
171 unsigned b = (*bs->cur) & (0x80 >> bs->bit);
172
173 INC_BIT(bs);
174
175 return b;
176}
177
178/****************************************************************************/
179/* Assume b <= 8 */
180unsigned get_bits(bitstr_t * bs, unsigned b)
181{
182 unsigned v, l;
183
184 v = (*bs->cur) & (0xffU >> bs->bit);
185 l = b + bs->bit;
186
187 if (l < 8) {
188 v >>= 8 - l;
189 bs->bit = l;
190 } else if (l == 8) {
191 bs->cur++;
192 bs->bit = 0;
193 } else { /* l > 8 */
194
195 v <<= 8;
196 v += *(++bs->cur);
197 v >>= 16 - l;
198 bs->bit = l - 8;
199 }
200
201 return v;
202}
203
204/****************************************************************************/
205/* Assume b <= 32 */
206unsigned get_bitmap(bitstr_t * bs, unsigned b)
207{
208 unsigned v, l, shift, bytes;
209
210 if (!b)
211 return 0;
212
213 l = bs->bit + b;
214
215 if (l < 8) {
216 v = (unsigned) (*bs->cur) << (bs->bit + 24);
217 bs->bit = l;
218 } else if (l == 8) {
219 v = (unsigned) (*bs->cur++) << (bs->bit + 24);
220 bs->bit = 0;
221 } else {
222 for (bytes = l >> 3, shift = 24, v = 0; bytes;
223 bytes--, shift -= 8)
224 v |= (unsigned) (*bs->cur++) << shift;
225
226 if (l < 32) {
227 v |= (unsigned) (*bs->cur) << shift;
228 v <<= bs->bit;
229 } else if (l > 32) {
230 v <<= bs->bit;
231 v |= (*bs->cur) >> (8 - bs->bit);
232 }
233
234 bs->bit = l & 0x7;
235 }
236
237 v &= 0xffffffff << (32 - b);
238
239 return v;
240}
241
242/****************************************************************************
243 * Assume bs is aligned and sizeof(unsigned int) == 4
244 ****************************************************************************/
245unsigned get_uint(bitstr_t * bs, int b)
246{
247 unsigned v = 0;
248
249 switch (b) {
250 case 4:
251 v |= *bs->cur++;
252 v <<= 8;
253 case 3:
254 v |= *bs->cur++;
255 v <<= 8;
256 case 2:
257 v |= *bs->cur++;
258 v <<= 8;
259 case 1:
260 v |= *bs->cur++;
261 break;
262 }
263 return v;
264}
265
266/****************************************************************************/
267int decode_nul(bitstr_t * bs, field_t * f, char *base, int level)
268{
269 PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
270
271 return H323_ERROR_NONE;
272}
273
274/****************************************************************************/
275int decode_bool(bitstr_t * bs, field_t * f, char *base, int level)
276{
277 PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
278
279 INC_BIT(bs);
280
281 CHECK_BOUND(bs, 0);
282 return H323_ERROR_NONE;
283}
284
285/****************************************************************************/
286int decode_oid(bitstr_t * bs, field_t * f, char *base, int level)
287{
288 int len;
289
290 PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
291
292 BYTE_ALIGN(bs);
293 CHECK_BOUND(bs, 1);
294 len = *bs->cur++;
295 bs->cur += len;
296
297 CHECK_BOUND(bs, 0);
298 return H323_ERROR_NONE;
299}
300
301/****************************************************************************/
302int decode_int(bitstr_t * bs, field_t * f, char *base, int level)
303{
304 unsigned len;
305
306 PRINT("%*.s%s", level * TAB_SIZE, " ", f->name);
307
308 switch (f->sz) {
309 case BYTE: /* Range == 256 */
310 BYTE_ALIGN(bs);
311 bs->cur++;
312 break;
313 case WORD: /* 257 <= Range <= 64K */
314 BYTE_ALIGN(bs);
315 bs->cur += 2;
316 break;
317 case CONS: /* 64K < Range < 4G */
318 len = get_bits(bs, 2) + 1;
319 BYTE_ALIGN(bs);
320 if (base && (f->attr & DECODE)) { /* timeToLive */
321 unsigned v = get_uint(bs, len) + f->lb;
322 PRINT(" = %u", v);
323 *((unsigned *) (base + f->offset)) = v;
324 }
325 bs->cur += len;
326 break;
327 case UNCO:
328 BYTE_ALIGN(bs);
329 CHECK_BOUND(bs, 2);
330 len = get_len(bs);
331 bs->cur += len;
332 break;
333 default: /* 2 <= Range <= 255 */
334 INC_BITS(bs, f->sz);
335 break;
336 }
337
338 PRINT("\n");
339
340 CHECK_BOUND(bs, 0);
341 return H323_ERROR_NONE;
342}
343
344/****************************************************************************/
345int decode_enum(bitstr_t * bs, field_t * f, char *base, int level)
346{
347 PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
348
349 if ((f->attr & EXT) && get_bit(bs)) {
350 INC_BITS(bs, 7);
351 } else {
352 INC_BITS(bs, f->sz);
353 }
354
355 CHECK_BOUND(bs, 0);
356 return H323_ERROR_NONE;
357}
358
359/****************************************************************************/
360int decode_bitstr(bitstr_t * bs, field_t * f, char *base, int level)
361{
362 unsigned len;
363
364 PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
365
366 BYTE_ALIGN(bs);
367 switch (f->sz) {
368 case FIXD: /* fixed length > 16 */
369 len = f->lb;
370 break;
371 case WORD: /* 2-byte length */
372 CHECK_BOUND(bs, 2);
373 len = (*bs->cur++) << 8;
374 len += (*bs->cur++) + f->lb;
375 break;
376 case SEMI:
377 CHECK_BOUND(bs, 2);
378 len = get_len(bs);
379 break;
380 default:
381 len = 0;
382 break;
383 }
384
385 bs->cur += len >> 3;
386 bs->bit = len & 7;
387
388 CHECK_BOUND(bs, 0);
389 return H323_ERROR_NONE;
390}
391
392/****************************************************************************/
393int decode_numstr(bitstr_t * bs, field_t * f, char *base, int level)
394{
395 unsigned len;
396
397 PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
398
399 /* 2 <= Range <= 255 */
400 len = get_bits(bs, f->sz) + f->lb;
401
402 BYTE_ALIGN(bs);
403 INC_BITS(bs, (len << 2));
404
405 CHECK_BOUND(bs, 0);
406 return H323_ERROR_NONE;
407}
408
409/****************************************************************************/
410int decode_octstr(bitstr_t * bs, field_t * f, char *base, int level)
411{
412 unsigned len;
413
414 PRINT("%*.s%s", level * TAB_SIZE, " ", f->name);
415
416 switch (f->sz) {
417 case FIXD: /* Range == 1 */
418 if (f->lb > 2) {
419 BYTE_ALIGN(bs);
420 if (base && (f->attr & DECODE)) {
421 /* The IP Address */
422 IFTHEN(f->lb == 4,
423 PRINT(" = %d.%d.%d.%d:%d",
424 bs->cur[0], bs->cur[1],
425 bs->cur[2], bs->cur[3],
426 bs->cur[4] * 256 + bs->cur[5]));
427 *((unsigned *) (base + f->offset)) =
428 bs->cur - bs->buf;
429 }
430 }
431 len = f->lb;
432 break;
433 case BYTE: /* Range == 256 */
434 BYTE_ALIGN(bs);
435 CHECK_BOUND(bs, 1);
436 len = (*bs->cur++) + f->lb;
437 break;
438 case SEMI:
439 BYTE_ALIGN(bs);
440 CHECK_BOUND(bs, 2);
441 len = get_len(bs) + f->lb;
442 break;
443 default: /* 2 <= Range <= 255 */
444 len = get_bits(bs, f->sz) + f->lb;
445 BYTE_ALIGN(bs);
446 break;
447 }
448
449 bs->cur += len;
450
451 PRINT("\n");
452
453 CHECK_BOUND(bs, 0);
454 return H323_ERROR_NONE;
455}
456
457/****************************************************************************/
458int decode_bmpstr(bitstr_t * bs, field_t * f, char *base, int level)
459{
460 unsigned len;
461
462 PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
463
464 switch (f->sz) {
465 case BYTE: /* Range == 256 */
466 BYTE_ALIGN(bs);
467 CHECK_BOUND(bs, 1);
468 len = (*bs->cur++) + f->lb;
469 break;
470 default: /* 2 <= Range <= 255 */
471 len = get_bits(bs, f->sz) + f->lb;
472 BYTE_ALIGN(bs);
473 break;
474 }
475
476 bs->cur += len << 1;
477
478 CHECK_BOUND(bs, 0);
479 return H323_ERROR_NONE;
480}
481
482/****************************************************************************/
483int decode_seq(bitstr_t * bs, field_t * f, char *base, int level)
484{
485 unsigned ext, bmp, i, opt, len = 0, bmp2, bmp2_len;
486 int err;
487 field_t *son;
488 unsigned char *beg = NULL;
489
490 PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
491
492 /* Decode? */
493 base = (base && (f->attr & DECODE)) ? base + f->offset : NULL;
494
495 /* Extensible? */
496 ext = (f->attr & EXT) ? get_bit(bs) : 0;
497
498 /* Get fields bitmap */
499 bmp = get_bitmap(bs, f->sz);
500 if (base)
501 *(unsigned *) base = bmp;
502
503 /* Decode the root components */
504 for (i = opt = 0, son = f->fields; i < f->lb; i++, son++) {
505 if (son->attr & STOP) {
506 PRINT("%*.s%s\n", (level + 1) * TAB_SIZE, " ",
507 son->name);
508 return H323_ERROR_STOP;
509 }
510
511 if (son->attr & OPT) { /* Optional component */
512 if (!((0x80000000U >> (opt++)) & bmp)) /* Not exist */
513 continue;
514 }
515
516 /* Decode */
517 if (son->attr & OPEN) { /* Open field */
518 CHECK_BOUND(bs, 2);
519 len = get_len(bs);
520 CHECK_BOUND(bs, len);
521 if (!base) {
522 PRINT("%*.s%s\n", (level + 1) * TAB_SIZE,
523 " ", son->name);
524 bs->cur += len;
525 continue;
526 }
527 beg = bs->cur;
528
529 /* Decode */
530 if ((err = (Decoders[son->type]) (bs, son, base,
531 level + 1)) >
532 H323_ERROR_STOP)
533 return err;
534
535 bs->cur = beg + len;
536 bs->bit = 0;
537 } else if ((err = (Decoders[son->type]) (bs, son, base,
538 level + 1)))
539 return err;
540 }
541
542 /* No extension? */
543 if (!ext)
544 return H323_ERROR_NONE;
545
546 /* Get the extension bitmap */
547 bmp2_len = get_bits(bs, 7) + 1;
548 CHECK_BOUND(bs, (bmp2_len + 7) >> 3);
549 bmp2 = get_bitmap(bs, bmp2_len);
550 bmp |= bmp2 >> f->sz;
551 if (base)
552 *(unsigned *) base = bmp;
553 BYTE_ALIGN(bs);
554
555 /* Decode the extension components */
556 for (opt = 0; opt < bmp2_len; opt++, i++, son++) {
557 if (son->attr & STOP) {
558 PRINT("%*.s%s\n", (level + 1) * TAB_SIZE, " ",
559 son->name);
560 return H323_ERROR_STOP;
561 }
562
563 if (!((0x80000000 >> opt) & bmp2)) /* Not present */
564 continue;
565
566 /* Check Range */
567 if (i >= f->ub) { /* Newer Version? */
568 CHECK_BOUND(bs, 2);
569 len = get_len(bs);
570 CHECK_BOUND(bs, len);
571 bs->cur += len;
572 continue;
573 }
574
575 CHECK_BOUND(bs, 2);
576 len = get_len(bs);
577 CHECK_BOUND(bs, len);
578 if (!base || !(son->attr & DECODE)) {
579 PRINT("%*.s%s\n", (level + 1) * TAB_SIZE, " ",
580 son->name);
581 bs->cur += len;
582 continue;
583 }
584 beg = bs->cur;
585
586 if ((err = (Decoders[son->type]) (bs, son, base,
587 level + 1)) >
588 H323_ERROR_STOP)
589 return err;
590
591 bs->cur = beg + len;
592 bs->bit = 0;
593 }
594 return H323_ERROR_NONE;
595}
596
597/****************************************************************************/
598int decode_seqof(bitstr_t * bs, field_t * f, char *base, int level)
599{
600 unsigned count, effective_count = 0, i, len = 0;
601 int err;
602 field_t *son;
603 unsigned char *beg = NULL;
604
605 PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
606
607 /* Decode? */
608 base = (base && (f->attr & DECODE)) ? base + f->offset : NULL;
609
610 /* Decode item count */
611 switch (f->sz) {
612 case BYTE:
613 BYTE_ALIGN(bs);
614 CHECK_BOUND(bs, 1);
615 count = *bs->cur++;
616 break;
617 case WORD:
618 BYTE_ALIGN(bs);
619 CHECK_BOUND(bs, 2);
620 count = *bs->cur++;
621 count <<= 8;
622 count = *bs->cur++;
623 break;
624 case SEMI:
625 BYTE_ALIGN(bs);
626 CHECK_BOUND(bs, 2);
627 count = get_len(bs);
628 break;
629 default:
630 count = get_bits(bs, f->sz);
631 break;
632 }
633 count += f->lb;
634
635 /* Write Count */
636 if (base) {
637 effective_count = count > f->ub ? f->ub : count;
638 *(unsigned *) base = effective_count;
639 base += sizeof(unsigned);
640 }
641
642 /* Decode nested field */
643 son = f->fields;
644 if (base)
645 base -= son->offset;
646 for (i = 0; i < count; i++) {
647 if (son->attr & OPEN) {
648 BYTE_ALIGN(bs);
649 len = get_len(bs);
650 CHECK_BOUND(bs, len);
651 if (!base || !(son->attr & DECODE)) {
652 PRINT("%*.s%s\n", (level + 1) * TAB_SIZE,
653 " ", son->name);
654 bs->cur += len;
655 continue;
656 }
657 beg = bs->cur;
658
659 if ((err = (Decoders[son->type]) (bs, son,
660 i <
661 effective_count ?
662 base : NULL,
663 level + 1)) >
664 H323_ERROR_STOP)
665 return err;
666
667 bs->cur = beg + len;
668 bs->bit = 0;
669 } else
670 if ((err = (Decoders[son->type]) (bs, son,
671 i < effective_count ?
672 base : NULL,
673 level + 1)))
674 return err;
675
676 if (base)
677 base += son->offset;
678 }
679
680 return H323_ERROR_NONE;
681}
682
683
684/****************************************************************************/
685int decode_choice(bitstr_t * bs, field_t * f, char *base, int level)
686{
687 unsigned type, ext, len = 0;
688 int err;
689 field_t *son;
690 unsigned char *beg = NULL;
691
692 PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
693
694 /* Decode? */
695 base = (base && (f->attr & DECODE)) ? base + f->offset : NULL;
696
697 /* Decode the choice index number */
698 if ((f->attr & EXT) && get_bit(bs)) {
699 ext = 1;
700 type = get_bits(bs, 7) + f->lb;
701 } else {
702 ext = 0;
703 type = get_bits(bs, f->sz);
704 }
705
706 /* Check Range */
707 if (type >= f->ub) { /* Newer version? */
708 BYTE_ALIGN(bs);
709 len = get_len(bs);
710 CHECK_BOUND(bs, len);
711 bs->cur += len;
712 return H323_ERROR_NONE;
713 }
714
715 /* Write Type */
716 if (base)
717 *(unsigned *) base = type;
718
719 /* Transfer to son level */
720 son = &f->fields[type];
721 if (son->attr & STOP) {
722 PRINT("%*.s%s\n", (level + 1) * TAB_SIZE, " ", son->name);
723 return H323_ERROR_STOP;
724 }
725
726 if (ext || (son->attr & OPEN)) {
727 BYTE_ALIGN(bs);
728 len = get_len(bs);
729 CHECK_BOUND(bs, len);
730 if (!base || !(son->attr & DECODE)) {
731 PRINT("%*.s%s\n", (level + 1) * TAB_SIZE, " ",
732 son->name);
733 bs->cur += len;
734 return H323_ERROR_NONE;
735 }
736 beg = bs->cur;
737
738 if ((err = (Decoders[son->type]) (bs, son, base, level + 1)) >
739 H323_ERROR_STOP)
740 return err;
741
742 bs->cur = beg + len;
743 bs->bit = 0;
744 } else if ((err = (Decoders[son->type]) (bs, son, base, level + 1)))
745 return err;
746
747 return H323_ERROR_NONE;
748}
749
750/****************************************************************************/
751int DecodeRasMessage(unsigned char *buf, size_t sz, RasMessage * ras)
752{
753 static field_t ras_message = {
754 FNAME("RasMessage") CHOICE, 5, 24, 32, DECODE | EXT,
755 0, _RasMessage
756 };
757 bitstr_t bs;
758
759 bs.buf = bs.beg = bs.cur = buf;
760 bs.end = buf + sz;
761 bs.bit = 0;
762
763 return decode_choice(&bs, &ras_message, (char *) ras, 0);
764}
765
766/****************************************************************************/
767static int DecodeH323_UserInformation(unsigned char *buf, unsigned char *beg,
768 size_t sz, H323_UserInformation * uuie)
769{
770 static field_t h323_userinformation = {
771 FNAME("H323-UserInformation") SEQ, 1, 2, 2, DECODE | EXT,
772 0, _H323_UserInformation
773 };
774 bitstr_t bs;
775
776 bs.buf = buf;
777 bs.beg = bs.cur = beg;
778 bs.end = beg + sz;
779 bs.bit = 0;
780
781 return decode_seq(&bs, &h323_userinformation, (char *) uuie, 0);
782}
783
784/****************************************************************************/
785int DecodeMultimediaSystemControlMessage(unsigned char *buf, size_t sz,
786 MultimediaSystemControlMessage *
787 mscm)
788{
789 static field_t multimediasystemcontrolmessage = {
790 FNAME("MultimediaSystemControlMessage") CHOICE, 2, 4, 4,
791 DECODE | EXT, 0, _MultimediaSystemControlMessage
792 };
793 bitstr_t bs;
794
795 bs.buf = bs.beg = bs.cur = buf;
796 bs.end = buf + sz;
797 bs.bit = 0;
798
799 return decode_choice(&bs, &multimediasystemcontrolmessage,
800 (char *) mscm, 0);
801}
802
803/****************************************************************************/
804int DecodeQ931(unsigned char *buf, size_t sz, Q931 * q931)
805{
806 unsigned char *p = buf;
807 int len;
808
809 if (!p || sz < 1)
810 return H323_ERROR_BOUND;
811
812 /* Protocol Discriminator */
813 if (*p != 0x08) {
814 PRINT("Unknown Protocol Discriminator\n");
815 return H323_ERROR_RANGE;
816 }
817 p++;
818 sz--;
819
820 /* CallReferenceValue */
821 if (sz < 1)
822 return H323_ERROR_BOUND;
823 len = *p++;
824 sz--;
825 if (sz < len)
826 return H323_ERROR_BOUND;
827 p += len;
828 sz -= len;
829
830 /* Message Type */
831 if (sz < 1)
832 return H323_ERROR_BOUND;
833 q931->MessageType = *p++;
834 PRINT("MessageType = %02X\n", q931->MessageType);
835 if (*p & 0x80) {
836 p++;
837 sz--;
838 }
839
840 /* Decode Information Elements */
841 while (sz > 0) {
842 if (*p == 0x7e) { /* UserUserIE */
843 if (sz < 3)
844 break;
845 p++;
846 len = *p++ << 8;
847 len |= *p++;
848 sz -= 3;
849 if (sz < len)
850 break;
851 p++;
852 len--;
853 return DecodeH323_UserInformation(buf, p, len,
854 &q931->UUIE);
855 }
856 p++;
857 sz--;
858 if (sz < 1)
859 break;
860 len = *p++;
861 if (sz < len)
862 break;
863 p += len;
864 sz -= len;
865 }
866
867 PRINT("Q.931 UUIE not found\n");
868
869 return H323_ERROR_BOUND;
870}
diff --git a/net/ipv4/netfilter/ip_conntrack_helper_h323_asn1.h b/net/ipv4/netfilter/ip_conntrack_helper_h323_asn1.h
new file mode 100644
index 000000000000..0bd828081c0c
--- /dev/null
+++ b/net/ipv4/netfilter/ip_conntrack_helper_h323_asn1.h
@@ -0,0 +1,98 @@
1/****************************************************************************
2 * ip_conntrack_helper_h323_asn1.h - BER and PER decoding library for H.323
3 * conntrack/NAT module.
4 *
5 * Copyright (c) 2006 by Jing Min Zhao <zhaojingmin@hotmail.com>
6 *
7 * This source code is licensed under General Public License version 2.
8 *
9 *
10 * This library is based on H.225 version 4, H.235 version 2 and H.245
11 * version 7. It is extremely optimized to decode only the absolutely
12 * necessary objects in a signal for Linux kernel NAT module use, so don't
13 * expect it to be a full ASN.1 library.
14 *
15 * Features:
16 *
17 * 1. Small. The total size of code plus data is less than 20 KB (IA32).
18 * 2. Fast. Decoding Netmeeting's Setup signal 1 million times on a PIII 866
19 * takes only 3.9 seconds.
20 * 3. No memory allocation. It uses a static object. No need to initialize or
21 * cleanup.
22 * 4. Thread safe.
23 * 5. Support embedded architectures that has no misaligned memory access
24 * support.
25 *
26 * Limitations:
27 *
28 * 1. At most 30 faststart entries. Actually this is limited by ethernet's MTU.
29 * If a Setup signal contains more than 30 faststart, the packet size will
30 * very likely exceed the MTU size, then the TPKT will be fragmented. I
31 * don't know how to handle this in a Netfilter module. Anybody can help?
32 * Although I think 30 is enough for most of the cases.
33 * 2. IPv4 addresses only.
34 *
35 ****************************************************************************/
36
37#ifndef _IP_CONNTRACK_HELPER_H323_ASN1_H_
38#define _IP_CONNTRACK_HELPER_H323_ASN1_H_
39
40/*****************************************************************************
41 * H.323 Types
42 ****************************************************************************/
43#include "ip_conntrack_helper_h323_types.h"
44
45typedef struct {
46 enum {
47 Q931_NationalEscape = 0x00,
48 Q931_Alerting = 0x01,
49 Q931_CallProceeding = 0x02,
50 Q931_Connect = 0x07,
51 Q931_ConnectAck = 0x0F,
52 Q931_Progress = 0x03,
53 Q931_Setup = 0x05,
54 Q931_SetupAck = 0x0D,
55 Q931_Resume = 0x26,
56 Q931_ResumeAck = 0x2E,
57 Q931_ResumeReject = 0x22,
58 Q931_Suspend = 0x25,
59 Q931_SuspendAck = 0x2D,
60 Q931_SuspendReject = 0x21,
61 Q931_UserInformation = 0x20,
62 Q931_Disconnect = 0x45,
63 Q931_Release = 0x4D,
64 Q931_ReleaseComplete = 0x5A,
65 Q931_Restart = 0x46,
66 Q931_RestartAck = 0x4E,
67 Q931_Segment = 0x60,
68 Q931_CongestionCtrl = 0x79,
69 Q931_Information = 0x7B,
70 Q931_Notify = 0x6E,
71 Q931_Status = 0x7D,
72 Q931_StatusEnquiry = 0x75,
73 Q931_Facility = 0x62
74 } MessageType;
75 H323_UserInformation UUIE;
76} Q931;
77
78/*****************************************************************************
79 * Decode Functions Return Codes
80 ****************************************************************************/
81
82#define H323_ERROR_NONE 0 /* Decoded successfully */
83#define H323_ERROR_STOP 1 /* Decoding stopped, not really an error */
84#define H323_ERROR_BOUND -1
85#define H323_ERROR_RANGE -2
86
87
88/*****************************************************************************
89 * Decode Functions
90 ****************************************************************************/
91
92int DecodeRasMessage(unsigned char *buf, size_t sz, RasMessage * ras);
93int DecodeQ931(unsigned char *buf, size_t sz, Q931 * q931);
94int DecodeMultimediaSystemControlMessage(unsigned char *buf, size_t sz,
95 MultimediaSystemControlMessage *
96 mscm);
97
98#endif
diff --git a/net/ipv4/netfilter/ip_conntrack_helper_h323_types.c b/net/ipv4/netfilter/ip_conntrack_helper_h323_types.c
new file mode 100644
index 000000000000..022c47b9f6c9
--- /dev/null
+++ b/net/ipv4/netfilter/ip_conntrack_helper_h323_types.c
@@ -0,0 +1,1926 @@
1/* Generated by Jing Min Zhao's ASN.1 parser, Mar 15 2006
2 *
3 * Copyright (c) 2006 Jing Min Zhao <zhaojingmin@users.sourceforge.net>
4 *
5 * This source code is licensed under General Public License version 2.
6 */
7
8static field_t _TransportAddress_ipAddress[] = { /* SEQUENCE */
9 {FNAME("ip") OCTSTR, FIXD, 4, 0, DECODE,
10 offsetof(TransportAddress_ipAddress, ip), NULL},
11 {FNAME("port") INT, WORD, 0, 0, SKIP, 0, NULL},
12};
13
14static field_t _TransportAddress_ipSourceRoute_route[] = { /* SEQUENCE OF */
15 {FNAME("item") OCTSTR, FIXD, 4, 0, SKIP, 0, NULL},
16};
17
18static field_t _TransportAddress_ipSourceRoute_routing[] = { /* CHOICE */
19 {FNAME("strict") NUL, FIXD, 0, 0, SKIP, 0, NULL},
20 {FNAME("loose") NUL, FIXD, 0, 0, SKIP, 0, NULL},
21};
22
23static field_t _TransportAddress_ipSourceRoute[] = { /* SEQUENCE */
24 {FNAME("ip") OCTSTR, FIXD, 4, 0, SKIP, 0, NULL},
25 {FNAME("port") INT, WORD, 0, 0, SKIP, 0, NULL},
26 {FNAME("route") SEQOF, SEMI, 0, 0, SKIP, 0,
27 _TransportAddress_ipSourceRoute_route},
28 {FNAME("routing") CHOICE, 1, 2, 2, SKIP | EXT, 0,
29 _TransportAddress_ipSourceRoute_routing},
30};
31
32static field_t _TransportAddress_ipxAddress[] = { /* SEQUENCE */
33 {FNAME("node") OCTSTR, FIXD, 6, 0, SKIP, 0, NULL},
34 {FNAME("netnum") OCTSTR, FIXD, 4, 0, SKIP, 0, NULL},
35 {FNAME("port") OCTSTR, FIXD, 2, 0, SKIP, 0, NULL},
36};
37
38static field_t _TransportAddress_ip6Address[] = { /* SEQUENCE */
39 {FNAME("ip") OCTSTR, FIXD, 16, 0, SKIP, 0, NULL},
40 {FNAME("port") INT, WORD, 0, 0, SKIP, 0, NULL},
41};
42
43static field_t _H221NonStandard[] = { /* SEQUENCE */
44 {FNAME("t35CountryCode") INT, BYTE, 0, 0, SKIP, 0, NULL},
45 {FNAME("t35Extension") INT, BYTE, 0, 0, SKIP, 0, NULL},
46 {FNAME("manufacturerCode") INT, WORD, 0, 0, SKIP, 0, NULL},
47};
48
49static field_t _NonStandardIdentifier[] = { /* CHOICE */
50 {FNAME("object") OID, BYTE, 0, 0, SKIP, 0, NULL},
51 {FNAME("h221NonStandard") SEQ, 0, 3, 3, SKIP | EXT, 0,
52 _H221NonStandard},
53};
54
55static field_t _NonStandardParameter[] = { /* SEQUENCE */
56 {FNAME("nonStandardIdentifier") CHOICE, 1, 2, 2, SKIP | EXT, 0,
57 _NonStandardIdentifier},
58 {FNAME("data") OCTSTR, SEMI, 0, 0, SKIP, 0, NULL},
59};
60
61static field_t _TransportAddress[] = { /* CHOICE */
62 {FNAME("ipAddress") SEQ, 0, 2, 2, DECODE,
63 offsetof(TransportAddress, ipAddress), _TransportAddress_ipAddress},
64 {FNAME("ipSourceRoute") SEQ, 0, 4, 4, SKIP | EXT, 0,
65 _TransportAddress_ipSourceRoute},
66 {FNAME("ipxAddress") SEQ, 0, 3, 3, SKIP, 0,
67 _TransportAddress_ipxAddress},
68 {FNAME("ip6Address") SEQ, 0, 2, 2, SKIP | EXT, 0,
69 _TransportAddress_ip6Address},
70 {FNAME("netBios") OCTSTR, FIXD, 16, 0, SKIP, 0, NULL},
71 {FNAME("nsap") OCTSTR, 5, 1, 0, SKIP, 0, NULL},
72 {FNAME("nonStandardAddress") SEQ, 0, 2, 2, SKIP, 0,
73 _NonStandardParameter},
74};
75
76static field_t _AliasAddress[] = { /* CHOICE */
77 {FNAME("dialedDigits") NUMDGT, 7, 1, 0, SKIP, 0, NULL},
78 {FNAME("h323-ID") BMPSTR, BYTE, 1, 0, SKIP, 0, NULL},
79 {FNAME("url-ID") IA5STR, WORD, 1, 0, SKIP, 0, NULL},
80 {FNAME("transportID") CHOICE, 3, 7, 7, SKIP | EXT, 0, NULL},
81 {FNAME("email-ID") IA5STR, WORD, 1, 0, SKIP, 0, NULL},
82 {FNAME("partyNumber") CHOICE, 3, 5, 5, SKIP | EXT, 0, NULL},
83 {FNAME("mobileUIM") CHOICE, 1, 2, 2, SKIP | EXT, 0, NULL},
84};
85
86static field_t _Setup_UUIE_sourceAddress[] = { /* SEQUENCE OF */
87 {FNAME("item") CHOICE, 1, 2, 7, SKIP | EXT, 0, _AliasAddress},
88};
89
90static field_t _VendorIdentifier[] = { /* SEQUENCE */
91 {FNAME("vendor") SEQ, 0, 3, 3, SKIP | EXT, 0, _H221NonStandard},
92 {FNAME("productId") OCTSTR, BYTE, 1, 0, SKIP | OPT, 0, NULL},
93 {FNAME("versionId") OCTSTR, BYTE, 1, 0, SKIP | OPT, 0, NULL},
94};
95
96static field_t _GatekeeperInfo[] = { /* SEQUENCE */
97 {FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
98 _NonStandardParameter},
99};
100
101static field_t _H310Caps[] = { /* SEQUENCE */
102 {FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
103 _NonStandardParameter},
104 {FNAME("dataRatesSupported") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
105 {FNAME("supportedPrefixes") SEQOF, SEMI, 0, 0, SKIP, 0, NULL},
106};
107
108static field_t _H320Caps[] = { /* SEQUENCE */
109 {FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
110 _NonStandardParameter},
111 {FNAME("dataRatesSupported") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
112 {FNAME("supportedPrefixes") SEQOF, SEMI, 0, 0, SKIP, 0, NULL},
113};
114
115static field_t _H321Caps[] = { /* SEQUENCE */
116 {FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
117 _NonStandardParameter},
118 {FNAME("dataRatesSupported") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
119 {FNAME("supportedPrefixes") SEQOF, SEMI, 0, 0, SKIP, 0, NULL},
120};
121
122static field_t _H322Caps[] = { /* SEQUENCE */
123 {FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
124 _NonStandardParameter},
125 {FNAME("dataRatesSupported") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
126 {FNAME("supportedPrefixes") SEQOF, SEMI, 0, 0, SKIP, 0, NULL},
127};
128
129static field_t _H323Caps[] = { /* SEQUENCE */
130 {FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
131 _NonStandardParameter},
132 {FNAME("dataRatesSupported") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
133 {FNAME("supportedPrefixes") SEQOF, SEMI, 0, 0, SKIP, 0, NULL},
134};
135
136static field_t _H324Caps[] = { /* SEQUENCE */
137 {FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
138 _NonStandardParameter},
139 {FNAME("dataRatesSupported") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
140 {FNAME("supportedPrefixes") SEQOF, SEMI, 0, 0, SKIP, 0, NULL},
141};
142
143static field_t _VoiceCaps[] = { /* SEQUENCE */
144 {FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
145 _NonStandardParameter},
146 {FNAME("dataRatesSupported") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
147 {FNAME("supportedPrefixes") SEQOF, SEMI, 0, 0, SKIP, 0, NULL},
148};
149
150static field_t _T120OnlyCaps[] = { /* SEQUENCE */
151 {FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
152 _NonStandardParameter},
153 {FNAME("dataRatesSupported") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
154 {FNAME("supportedPrefixes") SEQOF, SEMI, 0, 0, SKIP, 0, NULL},
155};
156
157static field_t _SupportedProtocols[] = { /* CHOICE */
158 {FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP, 0,
159 _NonStandardParameter},
160 {FNAME("h310") SEQ, 1, 1, 3, SKIP | EXT, 0, _H310Caps},
161 {FNAME("h320") SEQ, 1, 1, 3, SKIP | EXT, 0, _H320Caps},
162 {FNAME("h321") SEQ, 1, 1, 3, SKIP | EXT, 0, _H321Caps},
163 {FNAME("h322") SEQ, 1, 1, 3, SKIP | EXT, 0, _H322Caps},
164 {FNAME("h323") SEQ, 1, 1, 3, SKIP | EXT, 0, _H323Caps},
165 {FNAME("h324") SEQ, 1, 1, 3, SKIP | EXT, 0, _H324Caps},
166 {FNAME("voice") SEQ, 1, 1, 3, SKIP | EXT, 0, _VoiceCaps},
167 {FNAME("t120-only") SEQ, 1, 1, 3, SKIP | EXT, 0, _T120OnlyCaps},
168 {FNAME("nonStandardProtocol") SEQ, 2, 3, 3, SKIP | EXT, 0, NULL},
169 {FNAME("t38FaxAnnexbOnly") SEQ, 2, 5, 5, SKIP | EXT, 0, NULL},
170};
171
172static field_t _GatewayInfo_protocol[] = { /* SEQUENCE OF */
173 {FNAME("item") CHOICE, 4, 9, 11, SKIP | EXT, 0, _SupportedProtocols},
174};
175
176static field_t _GatewayInfo[] = { /* SEQUENCE */
177 {FNAME("protocol") SEQOF, SEMI, 0, 0, SKIP | OPT, 0,
178 _GatewayInfo_protocol},
179 {FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
180 _NonStandardParameter},
181};
182
183static field_t _McuInfo[] = { /* SEQUENCE */
184 {FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
185 _NonStandardParameter},
186 {FNAME("protocol") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
187};
188
189static field_t _TerminalInfo[] = { /* SEQUENCE */
190 {FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
191 _NonStandardParameter},
192};
193
194static field_t _EndpointType[] = { /* SEQUENCE */
195 {FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
196 _NonStandardParameter},
197 {FNAME("vendor") SEQ, 2, 3, 3, SKIP | EXT | OPT, 0,
198 _VendorIdentifier},
199 {FNAME("gatekeeper") SEQ, 1, 1, 1, SKIP | EXT | OPT, 0,
200 _GatekeeperInfo},
201 {FNAME("gateway") SEQ, 2, 2, 2, SKIP | EXT | OPT, 0, _GatewayInfo},
202 {FNAME("mcu") SEQ, 1, 1, 2, SKIP | EXT | OPT, 0, _McuInfo},
203 {FNAME("terminal") SEQ, 1, 1, 1, SKIP | EXT | OPT, 0, _TerminalInfo},
204 {FNAME("mc") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
205 {FNAME("undefinedNode") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
206 {FNAME("set") BITSTR, FIXD, 32, 0, SKIP | OPT, 0, NULL},
207 {FNAME("supportedTunnelledProtocols") SEQOF, SEMI, 0, 0, SKIP | OPT,
208 0, NULL},
209};
210
211static field_t _Setup_UUIE_destinationAddress[] = { /* SEQUENCE OF */
212 {FNAME("item") CHOICE, 1, 2, 7, SKIP | EXT, 0, _AliasAddress},
213};
214
215static field_t _Setup_UUIE_destExtraCallInfo[] = { /* SEQUENCE OF */
216 {FNAME("item") CHOICE, 1, 2, 7, SKIP | EXT, 0, _AliasAddress},
217};
218
219static field_t _Setup_UUIE_destExtraCRV[] = { /* SEQUENCE OF */
220 {FNAME("item") INT, WORD, 0, 0, SKIP, 0, NULL},
221};
222
223static field_t _Setup_UUIE_conferenceGoal[] = { /* CHOICE */
224 {FNAME("create") NUL, FIXD, 0, 0, SKIP, 0, NULL},
225 {FNAME("join") NUL, FIXD, 0, 0, SKIP, 0, NULL},
226 {FNAME("invite") NUL, FIXD, 0, 0, SKIP, 0, NULL},
227 {FNAME("capability-negotiation") NUL, FIXD, 0, 0, SKIP, 0, NULL},
228 {FNAME("callIndependentSupplementaryService") NUL, FIXD, 0, 0, SKIP,
229 0, NULL},
230};
231
232static field_t _Q954Details[] = { /* SEQUENCE */
233 {FNAME("conferenceCalling") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
234 {FNAME("threePartyService") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
235};
236
237static field_t _QseriesOptions[] = { /* SEQUENCE */
238 {FNAME("q932Full") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
239 {FNAME("q951Full") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
240 {FNAME("q952Full") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
241 {FNAME("q953Full") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
242 {FNAME("q955Full") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
243 {FNAME("q956Full") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
244 {FNAME("q957Full") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
245 {FNAME("q954Info") SEQ, 0, 2, 2, SKIP | EXT, 0, _Q954Details},
246};
247
248static field_t _CallType[] = { /* CHOICE */
249 {FNAME("pointToPoint") NUL, FIXD, 0, 0, SKIP, 0, NULL},
250 {FNAME("oneToN") NUL, FIXD, 0, 0, SKIP, 0, NULL},
251 {FNAME("nToOne") NUL, FIXD, 0, 0, SKIP, 0, NULL},
252 {FNAME("nToN") NUL, FIXD, 0, 0, SKIP, 0, NULL},
253};
254
255static field_t _H245_NonStandardIdentifier_h221NonStandard[] = { /* SEQUENCE */
256 {FNAME("t35CountryCode") INT, BYTE, 0, 0, SKIP, 0, NULL},
257 {FNAME("t35Extension") INT, BYTE, 0, 0, SKIP, 0, NULL},
258 {FNAME("manufacturerCode") INT, WORD, 0, 0, SKIP, 0, NULL},
259};
260
261static field_t _H245_NonStandardIdentifier[] = { /* CHOICE */
262 {FNAME("object") OID, BYTE, 0, 0, SKIP, 0, NULL},
263 {FNAME("h221NonStandard") SEQ, 0, 3, 3, SKIP, 0,
264 _H245_NonStandardIdentifier_h221NonStandard},
265};
266
267static field_t _H245_NonStandardParameter[] = { /* SEQUENCE */
268 {FNAME("nonStandardIdentifier") CHOICE, 1, 2, 2, SKIP, 0,
269 _H245_NonStandardIdentifier},
270 {FNAME("data") OCTSTR, SEMI, 0, 0, SKIP, 0, NULL},
271};
272
273static field_t _H261VideoCapability[] = { /* SEQUENCE */
274 {FNAME("qcifMPI") INT, 2, 1, 0, SKIP | OPT, 0, NULL},
275 {FNAME("cifMPI") INT, 2, 1, 0, SKIP | OPT, 0, NULL},
276 {FNAME("temporalSpatialTradeOffCapability") BOOL, FIXD, 0, 0, SKIP, 0,
277 NULL},
278 {FNAME("maxBitRate") INT, WORD, 1, 0, SKIP, 0, NULL},
279 {FNAME("stillImageTransmission") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
280 {FNAME("videoBadMBsCap") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
281};
282
283static field_t _H262VideoCapability[] = { /* SEQUENCE */
284 {FNAME("profileAndLevel-SPatML") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
285 {FNAME("profileAndLevel-MPatLL") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
286 {FNAME("profileAndLevel-MPatML") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
287 {FNAME("profileAndLevel-MPatH-14") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
288 {FNAME("profileAndLevel-MPatHL") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
289 {FNAME("profileAndLevel-SNRatLL") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
290 {FNAME("profileAndLevel-SNRatML") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
291 {FNAME("profileAndLevel-SpatialatH-14") BOOL, FIXD, 0, 0, SKIP, 0,
292 NULL},
293 {FNAME("profileAndLevel-HPatML") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
294 {FNAME("profileAndLevel-HPatH-14") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
295 {FNAME("profileAndLevel-HPatHL") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
296 {FNAME("videoBitRate") INT, CONS, 0, 0, SKIP | OPT, 0, NULL},
297 {FNAME("vbvBufferSize") INT, CONS, 0, 0, SKIP | OPT, 0, NULL},
298 {FNAME("samplesPerLine") INT, WORD, 0, 0, SKIP | OPT, 0, NULL},
299 {FNAME("linesPerFrame") INT, WORD, 0, 0, SKIP | OPT, 0, NULL},
300 {FNAME("framesPerSecond") INT, 4, 0, 0, SKIP | OPT, 0, NULL},
301 {FNAME("luminanceSampleRate") INT, CONS, 0, 0, SKIP | OPT, 0, NULL},
302 {FNAME("videoBadMBsCap") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
303};
304
305static field_t _H263VideoCapability[] = { /* SEQUENCE */
306 {FNAME("sqcifMPI") INT, 5, 1, 0, SKIP | OPT, 0, NULL},
307 {FNAME("qcifMPI") INT, 5, 1, 0, SKIP | OPT, 0, NULL},
308 {FNAME("cifMPI") INT, 5, 1, 0, SKIP | OPT, 0, NULL},
309 {FNAME("cif4MPI") INT, 5, 1, 0, SKIP | OPT, 0, NULL},
310 {FNAME("cif16MPI") INT, 5, 1, 0, SKIP | OPT, 0, NULL},
311 {FNAME("maxBitRate") INT, CONS, 1, 0, SKIP, 0, NULL},
312 {FNAME("unrestrictedVector") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
313 {FNAME("arithmeticCoding") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
314 {FNAME("advancedPrediction") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
315 {FNAME("pbFrames") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
316 {FNAME("temporalSpatialTradeOffCapability") BOOL, FIXD, 0, 0, SKIP, 0,
317 NULL},
318 {FNAME("hrd-B") INT, CONS, 0, 0, SKIP | OPT, 0, NULL},
319 {FNAME("bppMaxKb") INT, WORD, 0, 0, SKIP | OPT, 0, NULL},
320 {FNAME("slowSqcifMPI") INT, WORD, 1, 0, SKIP | OPT, 0, NULL},
321 {FNAME("slowQcifMPI") INT, WORD, 1, 0, SKIP | OPT, 0, NULL},
322 {FNAME("slowCifMPI") INT, WORD, 1, 0, SKIP | OPT, 0, NULL},
323 {FNAME("slowCif4MPI") INT, WORD, 1, 0, SKIP | OPT, 0, NULL},
324 {FNAME("slowCif16MPI") INT, WORD, 1, 0, SKIP | OPT, 0, NULL},
325 {FNAME("errorCompensation") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
326 {FNAME("enhancementLayerInfo") SEQ, 3, 4, 4, SKIP | EXT | OPT, 0,
327 NULL},
328 {FNAME("h263Options") SEQ, 5, 29, 31, SKIP | EXT | OPT, 0, NULL},
329};
330
331static field_t _IS11172VideoCapability[] = { /* SEQUENCE */
332 {FNAME("constrainedBitstream") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
333 {FNAME("videoBitRate") INT, CONS, 0, 0, SKIP | OPT, 0, NULL},
334 {FNAME("vbvBufferSize") INT, CONS, 0, 0, SKIP | OPT, 0, NULL},
335 {FNAME("samplesPerLine") INT, WORD, 0, 0, SKIP | OPT, 0, NULL},
336 {FNAME("linesPerFrame") INT, WORD, 0, 0, SKIP | OPT, 0, NULL},
337 {FNAME("pictureRate") INT, 4, 0, 0, SKIP | OPT, 0, NULL},
338 {FNAME("luminanceSampleRate") INT, CONS, 0, 0, SKIP | OPT, 0, NULL},
339 {FNAME("videoBadMBsCap") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
340};
341
342static field_t _VideoCapability[] = { /* CHOICE */
343 {FNAME("nonStandard") SEQ, 0, 2, 2, SKIP, 0,
344 _H245_NonStandardParameter},
345 {FNAME("h261VideoCapability") SEQ, 2, 5, 6, SKIP | EXT, 0,
346 _H261VideoCapability},
347 {FNAME("h262VideoCapability") SEQ, 6, 17, 18, SKIP | EXT, 0,
348 _H262VideoCapability},
349 {FNAME("h263VideoCapability") SEQ, 7, 13, 21, SKIP | EXT, 0,
350 _H263VideoCapability},
351 {FNAME("is11172VideoCapability") SEQ, 6, 7, 8, SKIP | EXT, 0,
352 _IS11172VideoCapability},
353 {FNAME("genericVideoCapability") SEQ, 5, 6, 6, SKIP | EXT, 0, NULL},
354};
355
356static field_t _AudioCapability_g7231[] = { /* SEQUENCE */
357 {FNAME("maxAl-sduAudioFrames") INT, BYTE, 1, 0, SKIP, 0, NULL},
358 {FNAME("silenceSuppression") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
359};
360
361static field_t _IS11172AudioCapability[] = { /* SEQUENCE */
362 {FNAME("audioLayer1") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
363 {FNAME("audioLayer2") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
364 {FNAME("audioLayer3") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
365 {FNAME("audioSampling32k") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
366 {FNAME("audioSampling44k1") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
367 {FNAME("audioSampling48k") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
368 {FNAME("singleChannel") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
369 {FNAME("twoChannels") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
370 {FNAME("bitRate") INT, WORD, 1, 0, SKIP, 0, NULL},
371};
372
373static field_t _IS13818AudioCapability[] = { /* SEQUENCE */
374 {FNAME("audioLayer1") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
375 {FNAME("audioLayer2") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
376 {FNAME("audioLayer3") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
377 {FNAME("audioSampling16k") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
378 {FNAME("audioSampling22k05") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
379 {FNAME("audioSampling24k") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
380 {FNAME("audioSampling32k") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
381 {FNAME("audioSampling44k1") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
382 {FNAME("audioSampling48k") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
383 {FNAME("singleChannel") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
384 {FNAME("twoChannels") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
385 {FNAME("threeChannels2-1") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
386 {FNAME("threeChannels3-0") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
387 {FNAME("fourChannels2-0-2-0") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
388 {FNAME("fourChannels2-2") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
389 {FNAME("fourChannels3-1") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
390 {FNAME("fiveChannels3-0-2-0") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
391 {FNAME("fiveChannels3-2") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
392 {FNAME("lowFrequencyEnhancement") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
393 {FNAME("multilingual") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
394 {FNAME("bitRate") INT, WORD, 1, 0, SKIP, 0, NULL},
395};
396
397static field_t _AudioCapability[] = { /* CHOICE */
398 {FNAME("nonStandard") SEQ, 0, 2, 2, SKIP, 0,
399 _H245_NonStandardParameter},
400 {FNAME("g711Alaw64k") INT, BYTE, 1, 0, SKIP, 0, NULL},
401 {FNAME("g711Alaw56k") INT, BYTE, 1, 0, SKIP, 0, NULL},
402 {FNAME("g711Ulaw64k") INT, BYTE, 1, 0, SKIP, 0, NULL},
403 {FNAME("g711Ulaw56k") INT, BYTE, 1, 0, SKIP, 0, NULL},
404 {FNAME("g722-64k") INT, BYTE, 1, 0, SKIP, 0, NULL},
405 {FNAME("g722-56k") INT, BYTE, 1, 0, SKIP, 0, NULL},
406 {FNAME("g722-48k") INT, BYTE, 1, 0, SKIP, 0, NULL},
407 {FNAME("g7231") SEQ, 0, 2, 2, SKIP, 0, _AudioCapability_g7231},
408 {FNAME("g728") INT, BYTE, 1, 0, SKIP, 0, NULL},
409 {FNAME("g729") INT, BYTE, 1, 0, SKIP, 0, NULL},
410 {FNAME("g729AnnexA") INT, BYTE, 1, 0, SKIP, 0, NULL},
411 {FNAME("is11172AudioCapability") SEQ, 0, 9, 9, SKIP | EXT, 0,
412 _IS11172AudioCapability},
413 {FNAME("is13818AudioCapability") SEQ, 0, 21, 21, SKIP | EXT, 0,
414 _IS13818AudioCapability},
415 {FNAME("g729wAnnexB") INT, BYTE, 1, 0, SKIP, 0, NULL},
416 {FNAME("g729AnnexAwAnnexB") INT, BYTE, 1, 0, SKIP, 0, NULL},
417 {FNAME("g7231AnnexCCapability") SEQ, 1, 3, 3, SKIP | EXT, 0, NULL},
418 {FNAME("gsmFullRate") SEQ, 0, 3, 3, SKIP | EXT, 0, NULL},
419 {FNAME("gsmHalfRate") SEQ, 0, 3, 3, SKIP | EXT, 0, NULL},
420 {FNAME("gsmEnhancedFullRate") SEQ, 0, 3, 3, SKIP | EXT, 0, NULL},
421 {FNAME("genericAudioCapability") SEQ, 5, 6, 6, SKIP | EXT, 0, NULL},
422 {FNAME("g729Extensions") SEQ, 1, 8, 8, SKIP | EXT, 0, NULL},
423};
424
425static field_t _DataProtocolCapability[] = { /* CHOICE */
426 {FNAME("nonStandard") SEQ, 0, 2, 2, SKIP, 0,
427 _H245_NonStandardParameter},
428 {FNAME("v14buffered") NUL, FIXD, 0, 0, SKIP, 0, NULL},
429 {FNAME("v42lapm") NUL, FIXD, 0, 0, SKIP, 0, NULL},
430 {FNAME("hdlcFrameTunnelling") NUL, FIXD, 0, 0, SKIP, 0, NULL},
431 {FNAME("h310SeparateVCStack") NUL, FIXD, 0, 0, SKIP, 0, NULL},
432 {FNAME("h310SingleVCStack") NUL, FIXD, 0, 0, SKIP, 0, NULL},
433 {FNAME("transparent") NUL, FIXD, 0, 0, SKIP, 0, NULL},
434 {FNAME("segmentationAndReassembly") NUL, FIXD, 0, 0, SKIP, 0, NULL},
435 {FNAME("hdlcFrameTunnelingwSAR") NUL, FIXD, 0, 0, SKIP, 0, NULL},
436 {FNAME("v120") NUL, FIXD, 0, 0, SKIP, 0, NULL},
437 {FNAME("separateLANStack") NUL, FIXD, 0, 0, SKIP, 0, NULL},
438 {FNAME("v76wCompression") CHOICE, 2, 3, 3, SKIP | EXT, 0, NULL},
439 {FNAME("tcp") NUL, FIXD, 0, 0, SKIP, 0, NULL},
440 {FNAME("udp") NUL, FIXD, 0, 0, SKIP, 0, NULL},
441};
442
443static field_t _T84Profile_t84Restricted[] = { /* SEQUENCE */
444 {FNAME("qcif") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
445 {FNAME("cif") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
446 {FNAME("ccir601Seq") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
447 {FNAME("ccir601Prog") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
448 {FNAME("hdtvSeq") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
449 {FNAME("hdtvProg") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
450 {FNAME("g3FacsMH200x100") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
451 {FNAME("g3FacsMH200x200") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
452 {FNAME("g4FacsMMR200x100") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
453 {FNAME("g4FacsMMR200x200") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
454 {FNAME("jbig200x200Seq") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
455 {FNAME("jbig200x200Prog") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
456 {FNAME("jbig300x300Seq") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
457 {FNAME("jbig300x300Prog") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
458 {FNAME("digPhotoLow") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
459 {FNAME("digPhotoMedSeq") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
460 {FNAME("digPhotoMedProg") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
461 {FNAME("digPhotoHighSeq") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
462 {FNAME("digPhotoHighProg") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
463};
464
465static field_t _T84Profile[] = { /* CHOICE */
466 {FNAME("t84Unrestricted") NUL, FIXD, 0, 0, SKIP, 0, NULL},
467 {FNAME("t84Restricted") SEQ, 0, 19, 19, SKIP | EXT, 0,
468 _T84Profile_t84Restricted},
469};
470
471static field_t _DataApplicationCapability_application_t84[] = { /* SEQUENCE */
472 {FNAME("t84Protocol") CHOICE, 3, 7, 14, SKIP | EXT, 0,
473 _DataProtocolCapability},
474 {FNAME("t84Profile") CHOICE, 1, 2, 2, SKIP, 0, _T84Profile},
475};
476
477static field_t _DataApplicationCapability_application_nlpid[] = { /* SEQUENCE */
478 {FNAME("nlpidProtocol") CHOICE, 3, 7, 14, SKIP | EXT, 0,
479 _DataProtocolCapability},
480 {FNAME("nlpidData") OCTSTR, SEMI, 0, 0, SKIP, 0, NULL},
481};
482
483static field_t _DataApplicationCapability_application[] = { /* CHOICE */
484 {FNAME("nonStandard") SEQ, 0, 2, 2, SKIP, 0,
485 _H245_NonStandardParameter},
486 {FNAME("t120") CHOICE, 3, 7, 14, DECODE | EXT,
487 offsetof(DataApplicationCapability_application, t120),
488 _DataProtocolCapability},
489 {FNAME("dsm-cc") CHOICE, 3, 7, 14, SKIP | EXT, 0,
490 _DataProtocolCapability},
491 {FNAME("userData") CHOICE, 3, 7, 14, SKIP | EXT, 0,
492 _DataProtocolCapability},
493 {FNAME("t84") SEQ, 0, 2, 2, SKIP, 0,
494 _DataApplicationCapability_application_t84},
495 {FNAME("t434") CHOICE, 3, 7, 14, SKIP | EXT, 0,
496 _DataProtocolCapability},
497 {FNAME("h224") CHOICE, 3, 7, 14, SKIP | EXT, 0,
498 _DataProtocolCapability},
499 {FNAME("nlpid") SEQ, 0, 2, 2, SKIP, 0,
500 _DataApplicationCapability_application_nlpid},
501 {FNAME("dsvdControl") NUL, FIXD, 0, 0, SKIP, 0, NULL},
502 {FNAME("h222DataPartitioning") CHOICE, 3, 7, 14, SKIP | EXT, 0,
503 _DataProtocolCapability},
504 {FNAME("t30fax") CHOICE, 3, 7, 14, SKIP | EXT, 0, NULL},
505 {FNAME("t140") CHOICE, 3, 7, 14, SKIP | EXT, 0, NULL},
506 {FNAME("t38fax") SEQ, 0, 2, 2, SKIP, 0, NULL},
507 {FNAME("genericDataCapability") SEQ, 5, 6, 6, SKIP | EXT, 0, NULL},
508};
509
510static field_t _DataApplicationCapability[] = { /* SEQUENCE */
511 {FNAME("application") CHOICE, 4, 10, 14, DECODE | EXT,
512 offsetof(DataApplicationCapability, application),
513 _DataApplicationCapability_application},
514 {FNAME("maxBitRate") INT, CONS, 0, 0, SKIP, 0, NULL},
515};
516
517static field_t _EncryptionMode[] = { /* CHOICE */
518 {FNAME("nonStandard") SEQ, 0, 2, 2, SKIP, 0,
519 _H245_NonStandardParameter},
520 {FNAME("h233Encryption") NUL, FIXD, 0, 0, SKIP, 0, NULL},
521};
522
523static field_t _DataType[] = { /* CHOICE */
524 {FNAME("nonStandard") SEQ, 0, 2, 2, SKIP, 0,
525 _H245_NonStandardParameter},
526 {FNAME("nullData") NUL, FIXD, 0, 0, SKIP, 0, NULL},
527 {FNAME("videoData") CHOICE, 3, 5, 6, SKIP | EXT, 0, _VideoCapability},
528 {FNAME("audioData") CHOICE, 4, 14, 22, SKIP | EXT, 0,
529 _AudioCapability},
530 {FNAME("data") SEQ, 0, 2, 2, DECODE | EXT, offsetof(DataType, data),
531 _DataApplicationCapability},
532 {FNAME("encryptionData") CHOICE, 1, 2, 2, SKIP | EXT, 0,
533 _EncryptionMode},
534 {FNAME("h235Control") SEQ, 0, 2, 2, SKIP, 0, NULL},
535 {FNAME("h235Media") SEQ, 0, 2, 2, SKIP | EXT, 0, NULL},
536 {FNAME("multiplexedStream") SEQ, 0, 2, 2, SKIP | EXT, 0, NULL},
537};
538
539static field_t _H222LogicalChannelParameters[] = { /* SEQUENCE */
540 {FNAME("resourceID") INT, WORD, 0, 0, SKIP, 0, NULL},
541 {FNAME("subChannelID") INT, WORD, 0, 0, SKIP, 0, NULL},
542 {FNAME("pcr-pid") INT, WORD, 0, 0, SKIP | OPT, 0, NULL},
543 {FNAME("programDescriptors") OCTSTR, SEMI, 0, 0, SKIP | OPT, 0, NULL},
544 {FNAME("streamDescriptors") OCTSTR, SEMI, 0, 0, SKIP | OPT, 0, NULL},
545};
546
547static field_t _H223LogicalChannelParameters_adaptationLayerType_al3[] = { /* SEQUENCE */
548 {FNAME("controlFieldOctets") INT, 2, 0, 0, SKIP, 0, NULL},
549 {FNAME("sendBufferSize") INT, CONS, 0, 0, SKIP, 0, NULL},
550};
551
552static field_t _H223LogicalChannelParameters_adaptationLayerType[] = { /* CHOICE */
553 {FNAME("nonStandard") SEQ, 0, 2, 2, SKIP, 0,
554 _H245_NonStandardParameter},
555 {FNAME("al1Framed") NUL, FIXD, 0, 0, SKIP, 0, NULL},
556 {FNAME("al1NotFramed") NUL, FIXD, 0, 0, SKIP, 0, NULL},
557 {FNAME("al2WithoutSequenceNumbers") NUL, FIXD, 0, 0, SKIP, 0, NULL},
558 {FNAME("al2WithSequenceNumbers") NUL, FIXD, 0, 0, SKIP, 0, NULL},
559 {FNAME("al3") SEQ, 0, 2, 2, SKIP, 0,
560 _H223LogicalChannelParameters_adaptationLayerType_al3},
561 {FNAME("al1M") SEQ, 0, 7, 8, SKIP | EXT, 0, NULL},
562 {FNAME("al2M") SEQ, 0, 2, 2, SKIP | EXT, 0, NULL},
563 {FNAME("al3M") SEQ, 0, 5, 6, SKIP | EXT, 0, NULL},
564};
565
566static field_t _H223LogicalChannelParameters[] = { /* SEQUENCE */
567 {FNAME("adaptationLayerType") CHOICE, 3, 6, 9, SKIP | EXT, 0,
568 _H223LogicalChannelParameters_adaptationLayerType},
569 {FNAME("segmentableFlag") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
570};
571
572static field_t _CRCLength[] = { /* CHOICE */
573 {FNAME("crc8bit") NUL, FIXD, 0, 0, SKIP, 0, NULL},
574 {FNAME("crc16bit") NUL, FIXD, 0, 0, SKIP, 0, NULL},
575 {FNAME("crc32bit") NUL, FIXD, 0, 0, SKIP, 0, NULL},
576};
577
578static field_t _V76HDLCParameters[] = { /* SEQUENCE */
579 {FNAME("crcLength") CHOICE, 2, 3, 3, SKIP | EXT, 0, _CRCLength},
580 {FNAME("n401") INT, WORD, 1, 0, SKIP, 0, NULL},
581 {FNAME("loopbackTestProcedure") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
582};
583
584static field_t _V76LogicalChannelParameters_suspendResume[] = { /* CHOICE */
585 {FNAME("noSuspendResume") NUL, FIXD, 0, 0, SKIP, 0, NULL},
586 {FNAME("suspendResumewAddress") NUL, FIXD, 0, 0, SKIP, 0, NULL},
587 {FNAME("suspendResumewoAddress") NUL, FIXD, 0, 0, SKIP, 0, NULL},
588};
589
590static field_t _V76LogicalChannelParameters_mode_eRM_recovery[] = { /* CHOICE */
591 {FNAME("rej") NUL, FIXD, 0, 0, SKIP, 0, NULL},
592 {FNAME("sREJ") NUL, FIXD, 0, 0, SKIP, 0, NULL},
593 {FNAME("mSREJ") NUL, FIXD, 0, 0, SKIP, 0, NULL},
594};
595
596static field_t _V76LogicalChannelParameters_mode_eRM[] = { /* SEQUENCE */
597 {FNAME("windowSize") INT, 7, 1, 0, SKIP, 0, NULL},
598 {FNAME("recovery") CHOICE, 2, 3, 3, SKIP | EXT, 0,
599 _V76LogicalChannelParameters_mode_eRM_recovery},
600};
601
602static field_t _V76LogicalChannelParameters_mode[] = { /* CHOICE */
603 {FNAME("eRM") SEQ, 0, 2, 2, SKIP | EXT, 0,
604 _V76LogicalChannelParameters_mode_eRM},
605 {FNAME("uNERM") NUL, FIXD, 0, 0, SKIP, 0, NULL},
606};
607
608static field_t _V75Parameters[] = { /* SEQUENCE */
609 {FNAME("audioHeaderPresent") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
610};
611
612static field_t _V76LogicalChannelParameters[] = { /* SEQUENCE */
613 {FNAME("hdlcParameters") SEQ, 0, 3, 3, SKIP | EXT, 0,
614 _V76HDLCParameters},
615 {FNAME("suspendResume") CHOICE, 2, 3, 3, SKIP | EXT, 0,
616 _V76LogicalChannelParameters_suspendResume},
617 {FNAME("uIH") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
618 {FNAME("mode") CHOICE, 1, 2, 2, SKIP | EXT, 0,
619 _V76LogicalChannelParameters_mode},
620 {FNAME("v75Parameters") SEQ, 0, 1, 1, SKIP | EXT, 0, _V75Parameters},
621};
622
623static field_t _H2250LogicalChannelParameters_nonStandard[] = { /* SEQUENCE OF */
624 {FNAME("item") SEQ, 0, 2, 2, SKIP, 0, _H245_NonStandardParameter},
625};
626
627static field_t _UnicastAddress_iPAddress[] = { /* SEQUENCE */
628 {FNAME("network") OCTSTR, FIXD, 4, 0, DECODE,
629 offsetof(UnicastAddress_iPAddress, network), NULL},
630 {FNAME("tsapIdentifier") INT, WORD, 0, 0, SKIP, 0, NULL},
631};
632
633static field_t _UnicastAddress_iPXAddress[] = { /* SEQUENCE */
634 {FNAME("node") OCTSTR, FIXD, 6, 0, SKIP, 0, NULL},
635 {FNAME("netnum") OCTSTR, FIXD, 4, 0, SKIP, 0, NULL},
636 {FNAME("tsapIdentifier") OCTSTR, FIXD, 2, 0, SKIP, 0, NULL},
637};
638
639static field_t _UnicastAddress_iP6Address[] = { /* SEQUENCE */
640 {FNAME("network") OCTSTR, FIXD, 16, 0, SKIP, 0, NULL},
641 {FNAME("tsapIdentifier") INT, WORD, 0, 0, SKIP, 0, NULL},
642};
643
644static field_t _UnicastAddress_iPSourceRouteAddress_routing[] = { /* CHOICE */
645 {FNAME("strict") NUL, FIXD, 0, 0, SKIP, 0, NULL},
646 {FNAME("loose") NUL, FIXD, 0, 0, SKIP, 0, NULL},
647};
648
649static field_t _UnicastAddress_iPSourceRouteAddress_route[] = { /* SEQUENCE OF */
650 {FNAME("item") OCTSTR, FIXD, 4, 0, SKIP, 0, NULL},
651};
652
653static field_t _UnicastAddress_iPSourceRouteAddress[] = { /* SEQUENCE */
654 {FNAME("routing") CHOICE, 1, 2, 2, SKIP, 0,
655 _UnicastAddress_iPSourceRouteAddress_routing},
656 {FNAME("network") OCTSTR, FIXD, 4, 0, SKIP, 0, NULL},
657 {FNAME("tsapIdentifier") INT, WORD, 0, 0, SKIP, 0, NULL},
658 {FNAME("route") SEQOF, SEMI, 0, 0, SKIP, 0,
659 _UnicastAddress_iPSourceRouteAddress_route},
660};
661
662static field_t _UnicastAddress[] = { /* CHOICE */
663 {FNAME("iPAddress") SEQ, 0, 2, 2, DECODE | EXT,
664 offsetof(UnicastAddress, iPAddress), _UnicastAddress_iPAddress},
665 {FNAME("iPXAddress") SEQ, 0, 3, 3, SKIP | EXT, 0,
666 _UnicastAddress_iPXAddress},
667 {FNAME("iP6Address") SEQ, 0, 2, 2, SKIP | EXT, 0,
668 _UnicastAddress_iP6Address},
669 {FNAME("netBios") OCTSTR, FIXD, 16, 0, SKIP, 0, NULL},
670 {FNAME("iPSourceRouteAddress") SEQ, 0, 4, 4, SKIP | EXT, 0,
671 _UnicastAddress_iPSourceRouteAddress},
672 {FNAME("nsap") OCTSTR, 5, 1, 0, SKIP, 0, NULL},
673 {FNAME("nonStandardAddress") SEQ, 0, 2, 2, SKIP, 0, NULL},
674};
675
676static field_t _MulticastAddress_iPAddress[] = { /* SEQUENCE */
677 {FNAME("network") OCTSTR, FIXD, 4, 0, SKIP, 0, NULL},
678 {FNAME("tsapIdentifier") INT, WORD, 0, 0, SKIP, 0, NULL},
679};
680
681static field_t _MulticastAddress_iP6Address[] = { /* SEQUENCE */
682 {FNAME("network") OCTSTR, FIXD, 16, 0, SKIP, 0, NULL},
683 {FNAME("tsapIdentifier") INT, WORD, 0, 0, SKIP, 0, NULL},
684};
685
686static field_t _MulticastAddress[] = { /* CHOICE */
687 {FNAME("iPAddress") SEQ, 0, 2, 2, SKIP | EXT, 0,
688 _MulticastAddress_iPAddress},
689 {FNAME("iP6Address") SEQ, 0, 2, 2, SKIP | EXT, 0,
690 _MulticastAddress_iP6Address},
691 {FNAME("nsap") OCTSTR, 5, 1, 0, SKIP, 0, NULL},
692 {FNAME("nonStandardAddress") SEQ, 0, 2, 2, SKIP, 0, NULL},
693};
694
695static field_t _H245_TransportAddress[] = { /* CHOICE */
696 {FNAME("unicastAddress") CHOICE, 3, 5, 7, DECODE | EXT,
697 offsetof(H245_TransportAddress, unicastAddress), _UnicastAddress},
698 {FNAME("multicastAddress") CHOICE, 1, 2, 4, SKIP | EXT, 0,
699 _MulticastAddress},
700};
701
702static field_t _H2250LogicalChannelParameters[] = { /* SEQUENCE */
703 {FNAME("nonStandard") SEQOF, SEMI, 0, 0, SKIP | OPT, 0,
704 _H2250LogicalChannelParameters_nonStandard},
705 {FNAME("sessionID") INT, BYTE, 0, 0, SKIP, 0, NULL},
706 {FNAME("associatedSessionID") INT, 8, 1, 0, SKIP | OPT, 0, NULL},
707 {FNAME("mediaChannel") CHOICE, 1, 2, 2, DECODE | EXT | OPT,
708 offsetof(H2250LogicalChannelParameters, mediaChannel),
709 _H245_TransportAddress},
710 {FNAME("mediaGuaranteedDelivery") BOOL, FIXD, 0, 0, SKIP | OPT, 0,
711 NULL},
712 {FNAME("mediaControlChannel") CHOICE, 1, 2, 2, DECODE | EXT | OPT,
713 offsetof(H2250LogicalChannelParameters, mediaControlChannel),
714 _H245_TransportAddress},
715 {FNAME("mediaControlGuaranteedDelivery") BOOL, FIXD, 0, 0, STOP | OPT,
716 0, NULL},
717 {FNAME("silenceSuppression") BOOL, FIXD, 0, 0, STOP | OPT, 0, NULL},
718 {FNAME("destination") SEQ, 0, 2, 2, STOP | EXT | OPT, 0, NULL},
719 {FNAME("dynamicRTPPayloadType") INT, 5, 96, 0, STOP | OPT, 0, NULL},
720 {FNAME("mediaPacketization") CHOICE, 0, 1, 2, STOP | EXT | OPT, 0,
721 NULL},
722 {FNAME("transportCapability") SEQ, 3, 3, 3, STOP | EXT | OPT, 0,
723 NULL},
724 {FNAME("redundancyEncoding") SEQ, 1, 2, 2, STOP | EXT | OPT, 0, NULL},
725 {FNAME("source") SEQ, 0, 2, 2, SKIP | EXT | OPT, 0, NULL},
726};
727
728static field_t _OpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters[] = { /* CHOICE */
729 {FNAME("h222LogicalChannelParameters") SEQ, 3, 5, 5, SKIP | EXT, 0,
730 _H222LogicalChannelParameters},
731 {FNAME("h223LogicalChannelParameters") SEQ, 0, 2, 2, SKIP | EXT, 0,
732 _H223LogicalChannelParameters},
733 {FNAME("v76LogicalChannelParameters") SEQ, 0, 5, 5, SKIP | EXT, 0,
734 _V76LogicalChannelParameters},
735 {FNAME("h2250LogicalChannelParameters") SEQ, 10, 11, 14, DECODE | EXT,
736 offsetof
737 (OpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters,
738 h2250LogicalChannelParameters), _H2250LogicalChannelParameters},
739 {FNAME("none") NUL, FIXD, 0, 0, SKIP, 0, NULL},
740};
741
742static field_t _OpenLogicalChannel_forwardLogicalChannelParameters[] = { /* SEQUENCE */
743 {FNAME("portNumber") INT, WORD, 0, 0, SKIP | OPT, 0, NULL},
744 {FNAME("dataType") CHOICE, 3, 6, 9, DECODE | EXT,
745 offsetof(OpenLogicalChannel_forwardLogicalChannelParameters,
746 dataType), _DataType},
747 {FNAME("multiplexParameters") CHOICE, 2, 3, 5, DECODE | EXT,
748 offsetof(OpenLogicalChannel_forwardLogicalChannelParameters,
749 multiplexParameters),
750 _OpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters},
751 {FNAME("forwardLogicalChannelDependency") INT, WORD, 1, 0, SKIP | OPT,
752 0, NULL},
753 {FNAME("replacementFor") INT, WORD, 1, 0, SKIP | OPT, 0, NULL},
754};
755
756static field_t _OpenLogicalChannel_reverseLogicalChannelParameters_multiplexParameters[] = { /* CHOICE */
757 {FNAME("h223LogicalChannelParameters") SEQ, 0, 2, 2, SKIP | EXT, 0,
758 _H223LogicalChannelParameters},
759 {FNAME("v76LogicalChannelParameters") SEQ, 0, 5, 5, SKIP | EXT, 0,
760 _V76LogicalChannelParameters},
761 {FNAME("h2250LogicalChannelParameters") SEQ, 10, 11, 14, DECODE | EXT,
762 offsetof
763 (OpenLogicalChannel_reverseLogicalChannelParameters_multiplexParameters,
764 h2250LogicalChannelParameters), _H2250LogicalChannelParameters},
765};
766
767static field_t _OpenLogicalChannel_reverseLogicalChannelParameters[] = { /* SEQUENCE */
768 {FNAME("dataType") CHOICE, 3, 6, 9, SKIP | EXT, 0, _DataType},
769 {FNAME("multiplexParameters") CHOICE, 1, 2, 3, DECODE | EXT | OPT,
770 offsetof(OpenLogicalChannel_reverseLogicalChannelParameters,
771 multiplexParameters),
772 _OpenLogicalChannel_reverseLogicalChannelParameters_multiplexParameters},
773 {FNAME("reverseLogicalChannelDependency") INT, WORD, 1, 0, SKIP | OPT,
774 0, NULL},
775 {FNAME("replacementFor") INT, WORD, 1, 0, SKIP | OPT, 0, NULL},
776};
777
778static field_t _NetworkAccessParameters_distribution[] = { /* CHOICE */
779 {FNAME("unicast") NUL, FIXD, 0, 0, SKIP, 0, NULL},
780 {FNAME("multicast") NUL, FIXD, 0, 0, SKIP, 0, NULL},
781};
782
783static field_t _Q2931Address_address[] = { /* CHOICE */
784 {FNAME("internationalNumber") NUMSTR, 4, 1, 0, SKIP, 0, NULL},
785 {FNAME("nsapAddress") OCTSTR, 5, 1, 0, SKIP, 0, NULL},
786};
787
788static field_t _Q2931Address[] = { /* SEQUENCE */
789 {FNAME("address") CHOICE, 1, 2, 2, SKIP | EXT, 0,
790 _Q2931Address_address},
791 {FNAME("subaddress") OCTSTR, 5, 1, 0, SKIP | OPT, 0, NULL},
792};
793
794static field_t _NetworkAccessParameters_networkAddress[] = { /* CHOICE */
795 {FNAME("q2931Address") SEQ, 1, 2, 2, SKIP | EXT, 0, _Q2931Address},
796 {FNAME("e164Address") NUMDGT, 7, 1, 0, SKIP, 0, NULL},
797 {FNAME("localAreaAddress") CHOICE, 1, 2, 2, DECODE | EXT,
798 offsetof(NetworkAccessParameters_networkAddress, localAreaAddress),
799 _H245_TransportAddress},
800};
801
802static field_t _NetworkAccessParameters[] = { /* SEQUENCE */
803 {FNAME("distribution") CHOICE, 1, 2, 2, SKIP | EXT | OPT, 0,
804 _NetworkAccessParameters_distribution},
805 {FNAME("networkAddress") CHOICE, 2, 3, 3, DECODE | EXT,
806 offsetof(NetworkAccessParameters, networkAddress),
807 _NetworkAccessParameters_networkAddress},
808 {FNAME("associateConference") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
809 {FNAME("externalReference") OCTSTR, 8, 1, 0, SKIP | OPT, 0, NULL},
810 {FNAME("t120SetupProcedure") CHOICE, 2, 3, 3, SKIP | EXT | OPT, 0,
811 NULL},
812};
813
814static field_t _OpenLogicalChannel[] = { /* SEQUENCE */
815 {FNAME("forwardLogicalChannelNumber") INT, WORD, 1, 0, SKIP, 0, NULL},
816 {FNAME("forwardLogicalChannelParameters") SEQ, 1, 3, 5, DECODE | EXT,
817 offsetof(OpenLogicalChannel, forwardLogicalChannelParameters),
818 _OpenLogicalChannel_forwardLogicalChannelParameters},
819 {FNAME("reverseLogicalChannelParameters") SEQ, 1, 2, 4,
820 DECODE | EXT | OPT, offsetof(OpenLogicalChannel,
821 reverseLogicalChannelParameters),
822 _OpenLogicalChannel_reverseLogicalChannelParameters},
823 {FNAME("separateStack") SEQ, 2, 4, 5, DECODE | EXT | OPT,
824 offsetof(OpenLogicalChannel, separateStack),
825 _NetworkAccessParameters},
826 {FNAME("encryptionSync") SEQ, 2, 4, 4, STOP | EXT | OPT, 0, NULL},
827};
828
829static field_t _Setup_UUIE_fastStart[] = { /* SEQUENCE OF */
830 {FNAME("item") SEQ, 1, 3, 5, DECODE | OPEN | EXT,
831 sizeof(OpenLogicalChannel), _OpenLogicalChannel}
832 ,
833};
834
835static field_t _Setup_UUIE[] = { /* SEQUENCE */
836 {FNAME("protocolIdentifier") OID, BYTE, 0, 0, SKIP, 0, NULL},
837 {FNAME("h245Address") CHOICE, 3, 7, 7, DECODE | EXT | OPT,
838 offsetof(Setup_UUIE, h245Address), _TransportAddress},
839 {FNAME("sourceAddress") SEQOF, SEMI, 0, 0, SKIP | OPT, 0,
840 _Setup_UUIE_sourceAddress},
841 {FNAME("sourceInfo") SEQ, 6, 8, 10, SKIP | EXT, 0, _EndpointType},
842 {FNAME("destinationAddress") SEQOF, SEMI, 0, 0, SKIP | OPT, 0,
843 _Setup_UUIE_destinationAddress},
844 {FNAME("destCallSignalAddress") CHOICE, 3, 7, 7, DECODE | EXT | OPT,
845 offsetof(Setup_UUIE, destCallSignalAddress), _TransportAddress},
846 {FNAME("destExtraCallInfo") SEQOF, SEMI, 0, 0, SKIP | OPT, 0,
847 _Setup_UUIE_destExtraCallInfo},
848 {FNAME("destExtraCRV") SEQOF, SEMI, 0, 0, SKIP | OPT, 0,
849 _Setup_UUIE_destExtraCRV},
850 {FNAME("activeMC") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
851 {FNAME("conferenceID") OCTSTR, FIXD, 16, 0, SKIP, 0, NULL},
852 {FNAME("conferenceGoal") CHOICE, 2, 3, 5, SKIP | EXT, 0,
853 _Setup_UUIE_conferenceGoal},
854 {FNAME("callServices") SEQ, 0, 8, 8, SKIP | EXT | OPT, 0,
855 _QseriesOptions},
856 {FNAME("callType") CHOICE, 2, 4, 4, SKIP | EXT, 0, _CallType},
857 {FNAME("sourceCallSignalAddress") CHOICE, 3, 7, 7, DECODE | EXT | OPT,
858 offsetof(Setup_UUIE, sourceCallSignalAddress), _TransportAddress},
859 {FNAME("remoteExtensionAddress") CHOICE, 1, 2, 7, SKIP | EXT | OPT, 0,
860 NULL},
861 {FNAME("callIdentifier") SEQ, 0, 1, 1, SKIP | EXT, 0, NULL},
862 {FNAME("h245SecurityCapability") SEQOF, SEMI, 0, 0, SKIP | OPT, 0,
863 NULL},
864 {FNAME("tokens") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
865 {FNAME("cryptoTokens") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
866 {FNAME("fastStart") SEQOF, SEMI, 0, 30, DECODE | OPT,
867 offsetof(Setup_UUIE, fastStart), _Setup_UUIE_fastStart},
868 {FNAME("mediaWaitForConnect") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
869 {FNAME("canOverlapSend") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
870 {FNAME("endpointIdentifier") BMPSTR, 7, 1, 0, STOP | OPT, 0, NULL},
871 {FNAME("multipleCalls") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
872 {FNAME("maintainConnection") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
873 {FNAME("connectionParameters") SEQ, 0, 3, 3, SKIP | EXT | OPT, 0,
874 NULL},
875 {FNAME("language") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
876 {FNAME("presentationIndicator") CHOICE, 2, 3, 3, SKIP | EXT | OPT, 0,
877 NULL},
878 {FNAME("screeningIndicator") ENUM, 2, 0, 0, SKIP | EXT | OPT, 0,
879 NULL},
880 {FNAME("serviceControl") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
881 {FNAME("symmetricOperationRequired") NUL, FIXD, 0, 0, SKIP | OPT, 0,
882 NULL},
883 {FNAME("capacity") SEQ, 2, 2, 2, SKIP | EXT | OPT, 0, NULL},
884 {FNAME("circuitInfo") SEQ, 3, 3, 3, SKIP | EXT | OPT, 0, NULL},
885 {FNAME("desiredProtocols") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
886 {FNAME("neededFeatures") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
887 {FNAME("desiredFeatures") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
888 {FNAME("supportedFeatures") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
889 {FNAME("parallelH245Control") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
890 {FNAME("additionalSourceAddresses") SEQOF, SEMI, 0, 0, SKIP | OPT, 0,
891 NULL},
892};
893
894static field_t _CallProceeding_UUIE_fastStart[] = { /* SEQUENCE OF */
895 {FNAME("item") SEQ, 1, 3, 5, DECODE | OPEN | EXT,
896 sizeof(OpenLogicalChannel), _OpenLogicalChannel}
897 ,
898};
899
900static field_t _CallProceeding_UUIE[] = { /* SEQUENCE */
901 {FNAME("protocolIdentifier") OID, BYTE, 0, 0, SKIP, 0, NULL},
902 {FNAME("destinationInfo") SEQ, 6, 8, 10, SKIP | EXT, 0,
903 _EndpointType},
904 {FNAME("h245Address") CHOICE, 3, 7, 7, DECODE | EXT | OPT,
905 offsetof(CallProceeding_UUIE, h245Address), _TransportAddress},
906 {FNAME("callIdentifier") SEQ, 0, 1, 1, SKIP | EXT, 0, NULL},
907 {FNAME("h245SecurityMode") CHOICE, 2, 4, 4, SKIP | EXT | OPT, 0,
908 NULL},
909 {FNAME("tokens") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
910 {FNAME("cryptoTokens") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
911 {FNAME("fastStart") SEQOF, SEMI, 0, 30, DECODE | OPT,
912 offsetof(CallProceeding_UUIE, fastStart),
913 _CallProceeding_UUIE_fastStart},
914 {FNAME("multipleCalls") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
915 {FNAME("maintainConnection") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
916 {FNAME("fastConnectRefused") NUL, FIXD, 0, 0, SKIP | OPT, 0, NULL},
917 {FNAME("featureSet") SEQ, 3, 4, 4, SKIP | EXT | OPT, 0, NULL},
918};
919
920static field_t _Connect_UUIE_fastStart[] = { /* SEQUENCE OF */
921 {FNAME("item") SEQ, 1, 3, 5, DECODE | OPEN | EXT,
922 sizeof(OpenLogicalChannel), _OpenLogicalChannel}
923 ,
924};
925
926static field_t _Connect_UUIE[] = { /* SEQUENCE */
927 {FNAME("protocolIdentifier") OID, BYTE, 0, 0, SKIP, 0, NULL},
928 {FNAME("h245Address") CHOICE, 3, 7, 7, DECODE | EXT | OPT,
929 offsetof(Connect_UUIE, h245Address), _TransportAddress},
930 {FNAME("destinationInfo") SEQ, 6, 8, 10, SKIP | EXT, 0,
931 _EndpointType},
932 {FNAME("conferenceID") OCTSTR, FIXD, 16, 0, SKIP, 0, NULL},
933 {FNAME("callIdentifier") SEQ, 0, 1, 1, SKIP | EXT, 0, NULL},
934 {FNAME("h245SecurityMode") CHOICE, 2, 4, 4, SKIP | EXT | OPT, 0,
935 NULL},
936 {FNAME("tokens") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
937 {FNAME("cryptoTokens") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
938 {FNAME("fastStart") SEQOF, SEMI, 0, 30, DECODE | OPT,
939 offsetof(Connect_UUIE, fastStart), _Connect_UUIE_fastStart},
940 {FNAME("multipleCalls") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
941 {FNAME("maintainConnection") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
942 {FNAME("language") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
943 {FNAME("connectedAddress") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
944 {FNAME("presentationIndicator") CHOICE, 2, 3, 3, SKIP | EXT | OPT, 0,
945 NULL},
946 {FNAME("screeningIndicator") ENUM, 2, 0, 0, SKIP | EXT | OPT, 0,
947 NULL},
948 {FNAME("fastConnectRefused") NUL, FIXD, 0, 0, SKIP | OPT, 0, NULL},
949 {FNAME("serviceControl") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
950 {FNAME("capacity") SEQ, 2, 2, 2, SKIP | EXT | OPT, 0, NULL},
951 {FNAME("featureSet") SEQ, 3, 4, 4, SKIP | EXT | OPT, 0, NULL},
952};
953
954static field_t _Alerting_UUIE_fastStart[] = { /* SEQUENCE OF */
955 {FNAME("item") SEQ, 1, 3, 5, DECODE | OPEN | EXT,
956 sizeof(OpenLogicalChannel), _OpenLogicalChannel}
957 ,
958};
959
960static field_t _Alerting_UUIE[] = { /* SEQUENCE */
961 {FNAME("protocolIdentifier") OID, BYTE, 0, 0, SKIP, 0, NULL},
962 {FNAME("destinationInfo") SEQ, 6, 8, 10, SKIP | EXT, 0,
963 _EndpointType},
964 {FNAME("h245Address") CHOICE, 3, 7, 7, DECODE | EXT | OPT,
965 offsetof(Alerting_UUIE, h245Address), _TransportAddress},
966 {FNAME("callIdentifier") SEQ, 0, 1, 1, SKIP | EXT, 0, NULL},
967 {FNAME("h245SecurityMode") CHOICE, 2, 4, 4, SKIP | EXT | OPT, 0,
968 NULL},
969 {FNAME("tokens") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
970 {FNAME("cryptoTokens") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
971 {FNAME("fastStart") SEQOF, SEMI, 0, 30, DECODE | OPT,
972 offsetof(Alerting_UUIE, fastStart), _Alerting_UUIE_fastStart},
973 {FNAME("multipleCalls") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
974 {FNAME("maintainConnection") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
975 {FNAME("alertingAddress") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
976 {FNAME("presentationIndicator") CHOICE, 2, 3, 3, SKIP | EXT | OPT, 0,
977 NULL},
978 {FNAME("screeningIndicator") ENUM, 2, 0, 0, SKIP | EXT | OPT, 0,
979 NULL},
980 {FNAME("fastConnectRefused") NUL, FIXD, 0, 0, SKIP | OPT, 0, NULL},
981 {FNAME("serviceControl") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
982 {FNAME("capacity") SEQ, 2, 2, 2, SKIP | EXT | OPT, 0, NULL},
983 {FNAME("featureSet") SEQ, 3, 4, 4, SKIP | EXT | OPT, 0, NULL},
984};
985
986static field_t _Information_UUIE_fastStart[] = { /* SEQUENCE OF */
987 {FNAME("item") SEQ, 1, 3, 5, DECODE | OPEN | EXT,
988 sizeof(OpenLogicalChannel), _OpenLogicalChannel}
989 ,
990};
991
992static field_t _Information_UUIE[] = { /* SEQUENCE */
993 {FNAME("protocolIdentifier") OID, BYTE, 0, 0, SKIP, 0, NULL},
994 {FNAME("callIdentifier") SEQ, 0, 1, 1, SKIP | EXT, 0, NULL},
995 {FNAME("tokens") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
996 {FNAME("cryptoTokens") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
997 {FNAME("fastStart") SEQOF, SEMI, 0, 30, DECODE | OPT,
998 offsetof(Information_UUIE, fastStart), _Information_UUIE_fastStart},
999 {FNAME("fastConnectRefused") NUL, FIXD, 0, 0, SKIP | OPT, 0, NULL},
1000 {FNAME("circuitInfo") SEQ, 3, 3, 3, SKIP | EXT | OPT, 0, NULL},
1001};
1002
1003static field_t _ReleaseCompleteReason[] = { /* CHOICE */
1004 {FNAME("noBandwidth") NUL, FIXD, 0, 0, SKIP, 0, NULL},
1005 {FNAME("gatekeeperResources") NUL, FIXD, 0, 0, SKIP, 0, NULL},
1006 {FNAME("unreachableDestination") NUL, FIXD, 0, 0, SKIP, 0, NULL},
1007 {FNAME("destinationRejection") NUL, FIXD, 0, 0, SKIP, 0, NULL},
1008 {FNAME("invalidRevision") NUL, FIXD, 0, 0, SKIP, 0, NULL},
1009 {FNAME("noPermission") NUL, FIXD, 0, 0, SKIP, 0, NULL},
1010 {FNAME("unreachableGatekeeper") NUL, FIXD, 0, 0, SKIP, 0, NULL},
1011 {FNAME("gatewayResources") NUL, FIXD, 0, 0, SKIP, 0, NULL},
1012 {FNAME("badFormatAddress") NUL, FIXD, 0, 0, SKIP, 0, NULL},
1013 {FNAME("adaptiveBusy") NUL, FIXD, 0, 0, SKIP, 0, NULL},
1014 {FNAME("inConf") NUL, FIXD, 0, 0, SKIP, 0, NULL},
1015 {FNAME("undefinedReason") NUL, FIXD, 0, 0, SKIP, 0, NULL},
1016 {FNAME("facilityCallDeflection") NUL, FIXD, 0, 0, SKIP, 0, NULL},
1017 {FNAME("securityDenied") NUL, FIXD, 0, 0, SKIP, 0, NULL},
1018 {FNAME("calledPartyNotRegistered") NUL, FIXD, 0, 0, SKIP, 0, NULL},
1019 {FNAME("callerNotRegistered") NUL, FIXD, 0, 0, SKIP, 0, NULL},
1020 {FNAME("newConnectionNeeded") NUL, FIXD, 0, 0, SKIP, 0, NULL},
1021 {FNAME("nonStandardReason") SEQ, 0, 2, 2, SKIP, 0, NULL},
1022 {FNAME("replaceWithConferenceInvite") OCTSTR, FIXD, 16, 0, SKIP, 0,
1023 NULL},
1024 {FNAME("genericDataReason") NUL, FIXD, 0, 0, SKIP, 0, NULL},
1025 {FNAME("neededFeatureNotSupported") NUL, FIXD, 0, 0, SKIP, 0, NULL},
1026 {FNAME("tunnelledSignallingRejected") NUL, FIXD, 0, 0, SKIP, 0, NULL},
1027};
1028
1029static field_t _ReleaseComplete_UUIE[] = { /* SEQUENCE */
1030 {FNAME("protocolIdentifier") OID, BYTE, 0, 0, SKIP, 0, NULL},
1031 {FNAME("reason") CHOICE, 4, 12, 22, SKIP | EXT | OPT, 0,
1032 _ReleaseCompleteReason},
1033 {FNAME("callIdentifier") SEQ, 0, 1, 1, SKIP | EXT, 0, NULL},
1034 {FNAME("tokens") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
1035 {FNAME("cryptoTokens") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
1036 {FNAME("busyAddress") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
1037 {FNAME("presentationIndicator") CHOICE, 2, 3, 3, SKIP | EXT | OPT, 0,
1038 NULL},
1039 {FNAME("screeningIndicator") ENUM, 2, 0, 0, SKIP | EXT | OPT, 0,
1040 NULL},
1041 {FNAME("capacity") SEQ, 2, 2, 2, SKIP | EXT | OPT, 0, NULL},
1042 {FNAME("serviceControl") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
1043 {FNAME("featureSet") SEQ, 3, 4, 4, SKIP | EXT | OPT, 0, NULL},
1044};
1045
1046static field_t _Facility_UUIE_alternativeAliasAddress[] = { /* SEQUENCE OF */
1047 {FNAME("item") CHOICE, 1, 2, 7, SKIP | EXT, 0, _AliasAddress},
1048};
1049
1050static field_t _FacilityReason[] = { /* CHOICE */
1051 {FNAME("routeCallToGatekeeper") NUL, FIXD, 0, 0, SKIP, 0, NULL},
1052 {FNAME("callForwarded") NUL, FIXD, 0, 0, SKIP, 0, NULL},
1053 {FNAME("routeCallToMC") NUL, FIXD, 0, 0, SKIP, 0, NULL},
1054 {FNAME("undefinedReason") NUL, FIXD, 0, 0, SKIP, 0, NULL},
1055 {FNAME("conferenceListChoice") NUL, FIXD, 0, 0, SKIP, 0, NULL},
1056 {FNAME("startH245") NUL, FIXD, 0, 0, SKIP, 0, NULL},
1057 {FNAME("noH245") NUL, FIXD, 0, 0, SKIP, 0, NULL},
1058 {FNAME("newTokens") NUL, FIXD, 0, 0, SKIP, 0, NULL},
1059 {FNAME("featureSetUpdate") NUL, FIXD, 0, 0, SKIP, 0, NULL},
1060 {FNAME("forwardedElements") NUL, FIXD, 0, 0, SKIP, 0, NULL},
1061 {FNAME("transportedInformation") NUL, FIXD, 0, 0, SKIP, 0, NULL},
1062};
1063
1064static field_t _Facility_UUIE_fastStart[] = { /* SEQUENCE OF */
1065 {FNAME("item") SEQ, 1, 3, 5, DECODE | OPEN | EXT,
1066 sizeof(OpenLogicalChannel), _OpenLogicalChannel}
1067 ,
1068};
1069
1070static field_t _Facility_UUIE[] = { /* SEQUENCE */
1071 {FNAME("protocolIdentifier") OID, BYTE, 0, 0, SKIP, 0, NULL},
1072 {FNAME("alternativeAddress") CHOICE, 3, 7, 7, SKIP | EXT | OPT, 0,
1073 _TransportAddress},
1074 {FNAME("alternativeAliasAddress") SEQOF, SEMI, 0, 0, SKIP | OPT, 0,
1075 _Facility_UUIE_alternativeAliasAddress},
1076 {FNAME("conferenceID") OCTSTR, FIXD, 16, 0, SKIP | OPT, 0, NULL},
1077 {FNAME("reason") CHOICE, 2, 4, 11, DECODE | EXT,
1078 offsetof(Facility_UUIE, reason), _FacilityReason},
1079 {FNAME("callIdentifier") SEQ, 0, 1, 1, SKIP | EXT, 0, NULL},
1080 {FNAME("destExtraCallInfo") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
1081 {FNAME("remoteExtensionAddress") CHOICE, 1, 2, 7, SKIP | EXT | OPT, 0,
1082 NULL},
1083 {FNAME("tokens") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
1084 {FNAME("cryptoTokens") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
1085 {FNAME("conferences") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
1086 {FNAME("h245Address") CHOICE, 3, 7, 7, DECODE | EXT | OPT,
1087 offsetof(Facility_UUIE, h245Address), _TransportAddress},
1088 {FNAME("fastStart") SEQOF, SEMI, 0, 30, DECODE | OPT,
1089 offsetof(Facility_UUIE, fastStart), _Facility_UUIE_fastStart},
1090 {FNAME("multipleCalls") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
1091 {FNAME("maintainConnection") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
1092 {FNAME("fastConnectRefused") NUL, FIXD, 0, 0, SKIP | OPT, 0, NULL},
1093 {FNAME("serviceControl") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
1094 {FNAME("circuitInfo") SEQ, 3, 3, 3, SKIP | EXT | OPT, 0, NULL},
1095 {FNAME("featureSet") SEQ, 3, 4, 4, SKIP | EXT | OPT, 0, NULL},
1096 {FNAME("destinationInfo") SEQ, 6, 8, 10, SKIP | EXT | OPT, 0, NULL},
1097 {FNAME("h245SecurityMode") CHOICE, 2, 4, 4, SKIP | EXT | OPT, 0,
1098 NULL},
1099};
1100
1101static field_t _CallIdentifier[] = { /* SEQUENCE */
1102 {FNAME("guid") OCTSTR, FIXD, 16, 0, SKIP, 0, NULL},
1103};
1104
1105static field_t _SecurityServiceMode[] = { /* CHOICE */
1106 {FNAME("nonStandard") SEQ, 0, 2, 2, SKIP, 0, _NonStandardParameter},
1107 {FNAME("none") NUL, FIXD, 0, 0, SKIP, 0, NULL},
1108 {FNAME("default") NUL, FIXD, 0, 0, SKIP, 0, NULL},
1109};
1110
1111static field_t _SecurityCapabilities[] = { /* SEQUENCE */
1112 {FNAME("nonStandard") SEQ, 0, 2, 2, SKIP | OPT, 0,
1113 _NonStandardParameter},
1114 {FNAME("encryption") CHOICE, 2, 3, 3, SKIP | EXT, 0,
1115 _SecurityServiceMode},
1116 {FNAME("authenticaton") CHOICE, 2, 3, 3, SKIP | EXT, 0,
1117 _SecurityServiceMode},
1118 {FNAME("integrity") CHOICE, 2, 3, 3, SKIP | EXT, 0,
1119 _SecurityServiceMode},
1120};
1121
1122static field_t _H245Security[] = { /* CHOICE */
1123 {FNAME("nonStandard") SEQ, 0, 2, 2, SKIP, 0, _NonStandardParameter},
1124 {FNAME("noSecurity") NUL, FIXD, 0, 0, SKIP, 0, NULL},
1125 {FNAME("tls") SEQ, 1, 4, 4, SKIP | EXT, 0, _SecurityCapabilities},
1126 {FNAME("ipsec") SEQ, 1, 4, 4, SKIP | EXT, 0, _SecurityCapabilities},
1127};
1128
1129static field_t _DHset[] = { /* SEQUENCE */
1130 {FNAME("halfkey") BITSTR, WORD, 0, 0, SKIP, 0, NULL},
1131 {FNAME("modSize") BITSTR, WORD, 0, 0, SKIP, 0, NULL},
1132 {FNAME("generator") BITSTR, WORD, 0, 0, SKIP, 0, NULL},
1133};
1134
1135static field_t _TypedCertificate[] = { /* SEQUENCE */
1136 {FNAME("type") OID, BYTE, 0, 0, SKIP, 0, NULL},
1137 {FNAME("certificate") OCTSTR, SEMI, 0, 0, SKIP, 0, NULL},
1138};
1139
1140static field_t _H235_NonStandardParameter[] = { /* SEQUENCE */
1141 {FNAME("nonStandardIdentifier") OID, BYTE, 0, 0, SKIP, 0, NULL},
1142 {FNAME("data") OCTSTR, SEMI, 0, 0, SKIP, 0, NULL},
1143};
1144
1145static field_t _ClearToken[] = { /* SEQUENCE */
1146 {FNAME("tokenOID") OID, BYTE, 0, 0, SKIP, 0, NULL},
1147 {FNAME("timeStamp") INT, CONS, 1, 0, SKIP | OPT, 0, NULL},
1148 {FNAME("password") BMPSTR, 7, 1, 0, SKIP | OPT, 0, NULL},
1149 {FNAME("dhkey") SEQ, 0, 3, 3, SKIP | EXT | OPT, 0, _DHset},
1150 {FNAME("challenge") OCTSTR, 7, 8, 0, SKIP | OPT, 0, NULL},
1151 {FNAME("random") INT, UNCO, 0, 0, SKIP | OPT, 0, NULL},
1152 {FNAME("certificate") SEQ, 0, 2, 2, SKIP | EXT | OPT, 0,
1153 _TypedCertificate},
1154 {FNAME("generalID") BMPSTR, 7, 1, 0, SKIP | OPT, 0, NULL},
1155 {FNAME("nonStandard") SEQ, 0, 2, 2, SKIP | OPT, 0,
1156 _H235_NonStandardParameter},
1157 {FNAME("eckasdhkey") CHOICE, 1, 2, 2, SKIP | EXT | OPT, 0, NULL},
1158 {FNAME("sendersID") BMPSTR, 7, 1, 0, SKIP | OPT, 0, NULL},
1159};
1160
1161static field_t _Progress_UUIE_tokens[] = { /* SEQUENCE OF */
1162 {FNAME("item") SEQ, 8, 9, 11, SKIP | EXT, 0, _ClearToken},
1163};
1164
1165static field_t _Params[] = { /* SEQUENCE */
1166 {FNAME("ranInt") INT, UNCO, 0, 0, SKIP | OPT, 0, NULL},
1167 {FNAME("iv8") OCTSTR, FIXD, 8, 0, SKIP | OPT, 0, NULL},
1168 {FNAME("iv16") OCTSTR, FIXD, 16, 0, SKIP | OPT, 0, NULL},
1169};
1170
1171static field_t _CryptoH323Token_cryptoEPPwdHash_token[] = { /* SEQUENCE */
1172 {FNAME("algorithmOID") OID, BYTE, 0, 0, SKIP, 0, NULL},
1173 {FNAME("paramS") SEQ, 2, 2, 3, SKIP | EXT, 0, _Params},
1174 {FNAME("hash") BITSTR, SEMI, 0, 0, SKIP, 0, NULL},
1175};
1176
1177static field_t _CryptoH323Token_cryptoEPPwdHash[] = { /* SEQUENCE */
1178 {FNAME("alias") CHOICE, 1, 2, 7, SKIP | EXT, 0, _AliasAddress},
1179 {FNAME("timeStamp") INT, CONS, 1, 0, SKIP, 0, NULL},
1180 {FNAME("token") SEQ, 0, 3, 3, SKIP, 0,
1181 _CryptoH323Token_cryptoEPPwdHash_token},
1182};
1183
1184static field_t _CryptoH323Token_cryptoGKPwdHash_token[] = { /* SEQUENCE */
1185 {FNAME("algorithmOID") OID, BYTE, 0, 0, SKIP, 0, NULL},
1186 {FNAME("paramS") SEQ, 2, 2, 3, SKIP | EXT, 0, _Params},
1187 {FNAME("hash") BITSTR, SEMI, 0, 0, SKIP, 0, NULL},
1188};
1189
1190static field_t _CryptoH323Token_cryptoGKPwdHash[] = { /* SEQUENCE */
1191 {FNAME("gatekeeperId") BMPSTR, 7, 1, 0, SKIP, 0, NULL},
1192 {FNAME("timeStamp") INT, CONS, 1, 0, SKIP, 0, NULL},
1193 {FNAME("token") SEQ, 0, 3, 3, SKIP, 0,
1194 _CryptoH323Token_cryptoGKPwdHash_token},
1195};
1196
1197static field_t _CryptoH323Token_cryptoEPPwdEncr[] = { /* SEQUENCE */
1198 {FNAME("algorithmOID") OID, BYTE, 0, 0, SKIP, 0, NULL},
1199 {FNAME("paramS") SEQ, 2, 2, 3, SKIP | EXT, 0, _Params},
1200 {FNAME("encryptedData") OCTSTR, SEMI, 0, 0, SKIP, 0, NULL},
1201};
1202
1203static field_t _CryptoH323Token_cryptoGKPwdEncr[] = { /* SEQUENCE */
1204 {FNAME("algorithmOID") OID, BYTE, 0, 0, SKIP, 0, NULL},
1205 {FNAME("paramS") SEQ, 2, 2, 3, SKIP | EXT, 0, _Params},
1206 {FNAME("encryptedData") OCTSTR, SEMI, 0, 0, SKIP, 0, NULL},
1207};
1208
1209static field_t _CryptoH323Token_cryptoEPCert[] = { /* SEQUENCE */
1210 {FNAME("toBeSigned") SEQ, 8, 9, 11, SKIP | OPEN | EXT, 0, NULL},
1211 {FNAME("algorithmOID") OID, BYTE, 0, 0, SKIP, 0, NULL},
1212 {FNAME("paramS") SEQ, 2, 2, 3, SKIP | EXT, 0, _Params},
1213 {FNAME("signature") BITSTR, SEMI, 0, 0, SKIP, 0, NULL},
1214};
1215
1216static field_t _CryptoH323Token_cryptoGKCert[] = { /* SEQUENCE */
1217 {FNAME("toBeSigned") SEQ, 8, 9, 11, SKIP | OPEN | EXT, 0, NULL},
1218 {FNAME("algorithmOID") OID, BYTE, 0, 0, SKIP, 0, NULL},
1219 {FNAME("paramS") SEQ, 2, 2, 3, SKIP | EXT, 0, _Params},
1220 {FNAME("signature") BITSTR, SEMI, 0, 0, SKIP, 0, NULL},
1221};
1222
1223static field_t _CryptoH323Token_cryptoFastStart[] = { /* SEQUENCE */
1224 {FNAME("toBeSigned") SEQ, 8, 9, 11, SKIP | OPEN | EXT, 0, NULL},
1225 {FNAME("algorithmOID") OID, BYTE, 0, 0, SKIP, 0, NULL},
1226 {FNAME("paramS") SEQ, 2, 2, 3, SKIP | EXT, 0, _Params},
1227 {FNAME("signature") BITSTR, SEMI, 0, 0, SKIP, 0, NULL},
1228};
1229
1230static field_t _CryptoToken_cryptoEncryptedToken_token[] = { /* SEQUENCE */
1231 {FNAME("algorithmOID") OID, BYTE, 0, 0, SKIP, 0, NULL},
1232 {FNAME("paramS") SEQ, 2, 2, 3, SKIP | EXT, 0, _Params},
1233 {FNAME("encryptedData") OCTSTR, SEMI, 0, 0, SKIP, 0, NULL},
1234};
1235
1236static field_t _CryptoToken_cryptoEncryptedToken[] = { /* SEQUENCE */
1237 {FNAME("tokenOID") OID, BYTE, 0, 0, SKIP, 0, NULL},
1238 {FNAME("token") SEQ, 0, 3, 3, SKIP, 0,
1239 _CryptoToken_cryptoEncryptedToken_token},
1240};
1241
1242static field_t _CryptoToken_cryptoSignedToken_token[] = { /* SEQUENCE */
1243 {FNAME("toBeSigned") SEQ, 8, 9, 11, SKIP | OPEN | EXT, 0, NULL},
1244 {FNAME("algorithmOID") OID, BYTE, 0, 0, SKIP, 0, NULL},
1245 {FNAME("paramS") SEQ, 2, 2, 3, SKIP | EXT, 0, _Params},
1246 {FNAME("signature") BITSTR, SEMI, 0, 0, SKIP, 0, NULL},
1247};
1248
1249static field_t _CryptoToken_cryptoSignedToken[] = { /* SEQUENCE */
1250 {FNAME("tokenOID") OID, BYTE, 0, 0, SKIP, 0, NULL},
1251 {FNAME("token") SEQ, 0, 4, 4, SKIP, 0,
1252 _CryptoToken_cryptoSignedToken_token},
1253};
1254
1255static field_t _CryptoToken_cryptoHashedToken_token[] = { /* SEQUENCE */
1256 {FNAME("algorithmOID") OID, BYTE, 0, 0, SKIP, 0, NULL},
1257 {FNAME("paramS") SEQ, 2, 2, 3, SKIP | EXT, 0, _Params},
1258 {FNAME("hash") BITSTR, SEMI, 0, 0, SKIP, 0, NULL},
1259};
1260
1261static field_t _CryptoToken_cryptoHashedToken[] = { /* SEQUENCE */
1262 {FNAME("tokenOID") OID, BYTE, 0, 0, SKIP, 0, NULL},
1263 {FNAME("hashedVals") SEQ, 8, 9, 11, SKIP | EXT, 0, _ClearToken},
1264 {FNAME("token") SEQ, 0, 3, 3, SKIP, 0,
1265 _CryptoToken_cryptoHashedToken_token},
1266};
1267
1268static field_t _CryptoToken_cryptoPwdEncr[] = { /* SEQUENCE */
1269 {FNAME("algorithmOID") OID, BYTE, 0, 0, SKIP, 0, NULL},
1270 {FNAME("paramS") SEQ, 2, 2, 3, SKIP | EXT, 0, _Params},
1271 {FNAME("encryptedData") OCTSTR, SEMI, 0, 0, SKIP, 0, NULL},
1272};
1273
1274static field_t _CryptoToken[] = { /* CHOICE */
1275 {FNAME("cryptoEncryptedToken") SEQ, 0, 2, 2, SKIP, 0,
1276 _CryptoToken_cryptoEncryptedToken},
1277 {FNAME("cryptoSignedToken") SEQ, 0, 2, 2, SKIP, 0,
1278 _CryptoToken_cryptoSignedToken},
1279 {FNAME("cryptoHashedToken") SEQ, 0, 3, 3, SKIP, 0,
1280 _CryptoToken_cryptoHashedToken},
1281 {FNAME("cryptoPwdEncr") SEQ, 0, 3, 3, SKIP, 0,
1282 _CryptoToken_cryptoPwdEncr},
1283};
1284
1285static field_t _CryptoH323Token[] = { /* CHOICE */
1286 {FNAME("cryptoEPPwdHash") SEQ, 0, 3, 3, SKIP, 0,
1287 _CryptoH323Token_cryptoEPPwdHash},
1288 {FNAME("cryptoGKPwdHash") SEQ, 0, 3, 3, SKIP, 0,
1289 _CryptoH323Token_cryptoGKPwdHash},
1290 {FNAME("cryptoEPPwdEncr") SEQ, 0, 3, 3, SKIP, 0,
1291 _CryptoH323Token_cryptoEPPwdEncr},
1292 {FNAME("cryptoGKPwdEncr") SEQ, 0, 3, 3, SKIP, 0,
1293 _CryptoH323Token_cryptoGKPwdEncr},
1294 {FNAME("cryptoEPCert") SEQ, 0, 4, 4, SKIP, 0,
1295 _CryptoH323Token_cryptoEPCert},
1296 {FNAME("cryptoGKCert") SEQ, 0, 4, 4, SKIP, 0,
1297 _CryptoH323Token_cryptoGKCert},
1298 {FNAME("cryptoFastStart") SEQ, 0, 4, 4, SKIP, 0,
1299 _CryptoH323Token_cryptoFastStart},
1300 {FNAME("nestedcryptoToken") CHOICE, 2, 4, 4, SKIP | EXT, 0,
1301 _CryptoToken},
1302};
1303
1304static field_t _Progress_UUIE_cryptoTokens[] = { /* SEQUENCE OF */
1305 {FNAME("item") CHOICE, 3, 8, 8, SKIP | EXT, 0, _CryptoH323Token},
1306};
1307
1308static field_t _Progress_UUIE_fastStart[] = { /* SEQUENCE OF */
1309 {FNAME("item") SEQ, 1, 3, 5, DECODE | OPEN | EXT,
1310 sizeof(OpenLogicalChannel), _OpenLogicalChannel}
1311 ,
1312};
1313
1314static field_t _Progress_UUIE[] = { /* SEQUENCE */
1315 {FNAME("protocolIdentifier") OID, BYTE, 0, 0, SKIP, 0, NULL},
1316 {FNAME("destinationInfo") SEQ, 6, 8, 10, SKIP | EXT, 0,
1317 _EndpointType},
1318 {FNAME("h245Address") CHOICE, 3, 7, 7, DECODE | EXT | OPT,
1319 offsetof(Progress_UUIE, h245Address), _TransportAddress},
1320 {FNAME("callIdentifier") SEQ, 0, 1, 1, SKIP | EXT, 0,
1321 _CallIdentifier},
1322 {FNAME("h245SecurityMode") CHOICE, 2, 4, 4, SKIP | EXT | OPT, 0,
1323 _H245Security},
1324 {FNAME("tokens") SEQOF, SEMI, 0, 0, SKIP | OPT, 0,
1325 _Progress_UUIE_tokens},
1326 {FNAME("cryptoTokens") SEQOF, SEMI, 0, 0, SKIP | OPT, 0,
1327 _Progress_UUIE_cryptoTokens},
1328 {FNAME("fastStart") SEQOF, SEMI, 0, 30, DECODE | OPT,
1329 offsetof(Progress_UUIE, fastStart), _Progress_UUIE_fastStart},
1330 {FNAME("multipleCalls") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
1331 {FNAME("maintainConnection") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
1332 {FNAME("fastConnectRefused") NUL, FIXD, 0, 0, SKIP | OPT, 0, NULL},
1333};
1334
1335static field_t _H323_UU_PDU_h323_message_body[] = { /* CHOICE */
1336 {FNAME("setup") SEQ, 7, 13, 39, DECODE | EXT,
1337 offsetof(H323_UU_PDU_h323_message_body, setup), _Setup_UUIE},
1338 {FNAME("callProceeding") SEQ, 1, 3, 12, DECODE | EXT,
1339 offsetof(H323_UU_PDU_h323_message_body, callProceeding),
1340 _CallProceeding_UUIE},
1341 {FNAME("connect") SEQ, 1, 4, 19, DECODE | EXT,
1342 offsetof(H323_UU_PDU_h323_message_body, connect), _Connect_UUIE},
1343 {FNAME("alerting") SEQ, 1, 3, 17, DECODE | EXT,
1344 offsetof(H323_UU_PDU_h323_message_body, alerting), _Alerting_UUIE},
1345 {FNAME("information") SEQ, 0, 1, 7, DECODE | EXT,
1346 offsetof(H323_UU_PDU_h323_message_body, information),
1347 _Information_UUIE},
1348 {FNAME("releaseComplete") SEQ, 1, 2, 11, SKIP | EXT, 0,
1349 _ReleaseComplete_UUIE},
1350 {FNAME("facility") SEQ, 3, 5, 21, DECODE | EXT,
1351 offsetof(H323_UU_PDU_h323_message_body, facility), _Facility_UUIE},
1352 {FNAME("progress") SEQ, 5, 8, 11, DECODE | EXT,
1353 offsetof(H323_UU_PDU_h323_message_body, progress), _Progress_UUIE},
1354 {FNAME("empty") NUL, FIXD, 0, 0, SKIP, 0, NULL},
1355 {FNAME("status") SEQ, 2, 4, 4, SKIP | EXT, 0, NULL},
1356 {FNAME("statusInquiry") SEQ, 2, 4, 4, SKIP | EXT, 0, NULL},
1357 {FNAME("setupAcknowledge") SEQ, 2, 4, 4, SKIP | EXT, 0, NULL},
1358 {FNAME("notify") SEQ, 2, 4, 4, SKIP | EXT, 0, NULL},
1359};
1360
1361static field_t _RequestMessage[] = { /* CHOICE */
1362 {FNAME("nonStandard") SEQ, 0, 1, 1, STOP | EXT, 0, NULL},
1363 {FNAME("masterSlaveDetermination") SEQ, 0, 2, 2, STOP | EXT, 0, NULL},
1364 {FNAME("terminalCapabilitySet") SEQ, 3, 5, 5, STOP | EXT, 0, NULL},
1365 {FNAME("openLogicalChannel") SEQ, 1, 3, 5, DECODE | EXT,
1366 offsetof(RequestMessage, openLogicalChannel), _OpenLogicalChannel},
1367 {FNAME("closeLogicalChannel") SEQ, 0, 2, 3, STOP | EXT, 0, NULL},
1368 {FNAME("requestChannelClose") SEQ, 0, 1, 3, STOP | EXT, 0, NULL},
1369 {FNAME("multiplexEntrySend") SEQ, 0, 2, 2, STOP | EXT, 0, NULL},
1370 {FNAME("requestMultiplexEntry") SEQ, 0, 1, 1, STOP | EXT, 0, NULL},
1371 {FNAME("requestMode") SEQ, 0, 2, 2, STOP | EXT, 0, NULL},
1372 {FNAME("roundTripDelayRequest") SEQ, 0, 1, 1, STOP | EXT, 0, NULL},
1373 {FNAME("maintenanceLoopRequest") SEQ, 0, 1, 1, STOP | EXT, 0, NULL},
1374 {FNAME("communicationModeRequest") SEQ, 0, 0, 0, STOP | EXT, 0, NULL},
1375 {FNAME("conferenceRequest") CHOICE, 3, 8, 16, STOP | EXT, 0, NULL},
1376 {FNAME("multilinkRequest") CHOICE, 3, 5, 5, STOP | EXT, 0, NULL},
1377 {FNAME("logicalChannelRateRequest") SEQ, 0, 3, 3, STOP | EXT, 0,
1378 NULL},
1379};
1380
1381static field_t _OpenLogicalChannelAck_reverseLogicalChannelParameters_multiplexParameters[] = { /* CHOICE */
1382 {FNAME("h222LogicalChannelParameters") SEQ, 3, 5, 5, SKIP | EXT, 0,
1383 _H222LogicalChannelParameters},
1384 {FNAME("h2250LogicalChannelParameters") SEQ, 10, 11, 14, DECODE | EXT,
1385 offsetof
1386 (OpenLogicalChannelAck_reverseLogicalChannelParameters_multiplexParameters,
1387 h2250LogicalChannelParameters), _H2250LogicalChannelParameters},
1388};
1389
1390static field_t _OpenLogicalChannelAck_reverseLogicalChannelParameters[] = { /* SEQUENCE */
1391 {FNAME("reverseLogicalChannelNumber") INT, WORD, 1, 0, SKIP, 0, NULL},
1392 {FNAME("portNumber") INT, WORD, 0, 0, SKIP | OPT, 0, NULL},
1393 {FNAME("multiplexParameters") CHOICE, 0, 1, 2, DECODE | EXT | OPT,
1394 offsetof(OpenLogicalChannelAck_reverseLogicalChannelParameters,
1395 multiplexParameters),
1396 _OpenLogicalChannelAck_reverseLogicalChannelParameters_multiplexParameters},
1397 {FNAME("replacementFor") INT, WORD, 1, 0, SKIP | OPT, 0, NULL},
1398};
1399
1400static field_t _H2250LogicalChannelAckParameters_nonStandard[] = { /* SEQUENCE OF */
1401 {FNAME("item") SEQ, 0, 2, 2, SKIP, 0, _H245_NonStandardParameter},
1402};
1403
1404static field_t _H2250LogicalChannelAckParameters[] = { /* SEQUENCE */
1405 {FNAME("nonStandard") SEQOF, SEMI, 0, 0, SKIP | OPT, 0,
1406 _H2250LogicalChannelAckParameters_nonStandard},
1407 {FNAME("sessionID") INT, 8, 1, 0, SKIP | OPT, 0, NULL},
1408 {FNAME("mediaChannel") CHOICE, 1, 2, 2, DECODE | EXT | OPT,
1409 offsetof(H2250LogicalChannelAckParameters, mediaChannel),
1410 _H245_TransportAddress},
1411 {FNAME("mediaControlChannel") CHOICE, 1, 2, 2, DECODE | EXT | OPT,
1412 offsetof(H2250LogicalChannelAckParameters, mediaControlChannel),
1413 _H245_TransportAddress},
1414 {FNAME("dynamicRTPPayloadType") INT, 5, 96, 0, SKIP | OPT, 0, NULL},
1415 {FNAME("flowControlToZero") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
1416 {FNAME("portNumber") INT, WORD, 0, 0, SKIP | OPT, 0, NULL},
1417};
1418
1419static field_t _OpenLogicalChannelAck_forwardMultiplexAckParameters[] = { /* CHOICE */
1420 {FNAME("h2250LogicalChannelAckParameters") SEQ, 5, 5, 7, DECODE | EXT,
1421 offsetof(OpenLogicalChannelAck_forwardMultiplexAckParameters,
1422 h2250LogicalChannelAckParameters),
1423 _H2250LogicalChannelAckParameters},
1424};
1425
1426static field_t _OpenLogicalChannelAck[] = { /* SEQUENCE */
1427 {FNAME("forwardLogicalChannelNumber") INT, WORD, 1, 0, SKIP, 0, NULL},
1428 {FNAME("reverseLogicalChannelParameters") SEQ, 2, 3, 4,
1429 DECODE | EXT | OPT, offsetof(OpenLogicalChannelAck,
1430 reverseLogicalChannelParameters),
1431 _OpenLogicalChannelAck_reverseLogicalChannelParameters},
1432 {FNAME("separateStack") SEQ, 2, 4, 5, SKIP | EXT | OPT, 0, NULL},
1433 {FNAME("forwardMultiplexAckParameters") CHOICE, 0, 1, 1,
1434 DECODE | EXT | OPT, offsetof(OpenLogicalChannelAck,
1435 forwardMultiplexAckParameters),
1436 _OpenLogicalChannelAck_forwardMultiplexAckParameters},
1437 {FNAME("encryptionSync") SEQ, 2, 4, 4, STOP | EXT | OPT, 0, NULL},
1438};
1439
1440static field_t _ResponseMessage[] = { /* CHOICE */
1441 {FNAME("nonStandard") SEQ, 0, 1, 1, STOP | EXT, 0, NULL},
1442 {FNAME("masterSlaveDeterminationAck") SEQ, 0, 1, 1, STOP | EXT, 0,
1443 NULL},
1444 {FNAME("masterSlaveDeterminationReject") SEQ, 0, 1, 1, STOP | EXT, 0,
1445 NULL},
1446 {FNAME("terminalCapabilitySetAck") SEQ, 0, 1, 1, STOP | EXT, 0, NULL},
1447 {FNAME("terminalCapabilitySetReject") SEQ, 0, 2, 2, STOP | EXT, 0,
1448 NULL},
1449 {FNAME("openLogicalChannelAck") SEQ, 1, 2, 5, DECODE | EXT,
1450 offsetof(ResponseMessage, openLogicalChannelAck),
1451 _OpenLogicalChannelAck},
1452 {FNAME("openLogicalChannelReject") SEQ, 0, 2, 2, STOP | EXT, 0, NULL},
1453 {FNAME("closeLogicalChannelAck") SEQ, 0, 1, 1, STOP | EXT, 0, NULL},
1454 {FNAME("requestChannelCloseAck") SEQ, 0, 1, 1, STOP | EXT, 0, NULL},
1455 {FNAME("requestChannelCloseReject") SEQ, 0, 2, 2, STOP | EXT, 0,
1456 NULL},
1457 {FNAME("multiplexEntrySendAck") SEQ, 0, 2, 2, STOP | EXT, 0, NULL},
1458 {FNAME("multiplexEntrySendReject") SEQ, 0, 2, 2, STOP | EXT, 0, NULL},
1459 {FNAME("requestMultiplexEntryAck") SEQ, 0, 1, 1, STOP | EXT, 0, NULL},
1460 {FNAME("requestMultiplexEntryReject") SEQ, 0, 2, 2, STOP | EXT, 0,
1461 NULL},
1462 {FNAME("requestModeAck") SEQ, 0, 2, 2, STOP | EXT, 0, NULL},
1463 {FNAME("requestModeReject") SEQ, 0, 2, 2, STOP | EXT, 0, NULL},
1464 {FNAME("roundTripDelayResponse") SEQ, 0, 1, 1, STOP | EXT, 0, NULL},
1465 {FNAME("maintenanceLoopAck") SEQ, 0, 1, 1, STOP | EXT, 0, NULL},
1466 {FNAME("maintenanceLoopReject") SEQ, 0, 2, 2, STOP | EXT, 0, NULL},
1467 {FNAME("communicationModeResponse") CHOICE, 0, 1, 1, STOP | EXT, 0,
1468 NULL},
1469 {FNAME("conferenceResponse") CHOICE, 3, 8, 16, STOP | EXT, 0, NULL},
1470 {FNAME("multilinkResponse") CHOICE, 3, 5, 5, STOP | EXT, 0, NULL},
1471 {FNAME("logicalChannelRateAcknowledge") SEQ, 0, 3, 3, STOP | EXT, 0,
1472 NULL},
1473 {FNAME("logicalChannelRateReject") SEQ, 1, 4, 4, STOP | EXT, 0, NULL},
1474};
1475
1476static field_t _MultimediaSystemControlMessage[] = { /* CHOICE */
1477 {FNAME("request") CHOICE, 4, 11, 15, DECODE | EXT,
1478 offsetof(MultimediaSystemControlMessage, request), _RequestMessage},
1479 {FNAME("response") CHOICE, 5, 19, 24, DECODE | EXT,
1480 offsetof(MultimediaSystemControlMessage, response),
1481 _ResponseMessage},
1482 {FNAME("command") CHOICE, 3, 7, 12, STOP | EXT, 0, NULL},
1483 {FNAME("indication") CHOICE, 4, 14, 23, STOP | EXT, 0, NULL},
1484};
1485
1486static field_t _H323_UU_PDU_h245Control[] = { /* SEQUENCE OF */
1487 {FNAME("item") CHOICE, 2, 4, 4, DECODE | OPEN | EXT,
1488 sizeof(MultimediaSystemControlMessage),
1489 _MultimediaSystemControlMessage}
1490 ,
1491};
1492
1493static field_t _H323_UU_PDU[] = { /* SEQUENCE */
1494 {FNAME("h323-message-body") CHOICE, 3, 7, 13, DECODE | EXT,
1495 offsetof(H323_UU_PDU, h323_message_body),
1496 _H323_UU_PDU_h323_message_body},
1497 {FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
1498 _NonStandardParameter},
1499 {FNAME("h4501SupplementaryService") SEQOF, SEMI, 0, 0, SKIP | OPT, 0,
1500 NULL},
1501 {FNAME("h245Tunneling") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
1502 {FNAME("h245Control") SEQOF, SEMI, 0, 4, DECODE | OPT,
1503 offsetof(H323_UU_PDU, h245Control), _H323_UU_PDU_h245Control},
1504 {FNAME("nonStandardControl") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
1505 {FNAME("callLinkage") SEQ, 2, 2, 2, STOP | EXT | OPT, 0, NULL},
1506 {FNAME("tunnelledSignallingMessage") SEQ, 2, 4, 4, STOP | EXT | OPT,
1507 0, NULL},
1508 {FNAME("provisionalRespToH245Tunneling") NUL, FIXD, 0, 0, STOP | OPT,
1509 0, NULL},
1510 {FNAME("stimulusControl") SEQ, 3, 3, 3, STOP | EXT | OPT, 0, NULL},
1511 {FNAME("genericData") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
1512};
1513
1514static field_t _H323_UserInformation[] = { /* SEQUENCE */
1515 {FNAME("h323-uu-pdu") SEQ, 1, 2, 11, DECODE | EXT,
1516 offsetof(H323_UserInformation, h323_uu_pdu), _H323_UU_PDU},
1517 {FNAME("user-data") SEQ, 0, 2, 2, STOP | EXT | OPT, 0, NULL},
1518};
1519
1520static field_t _GatekeeperRequest[] = { /* SEQUENCE */
1521 {FNAME("requestSeqNum") INT, WORD, 1, 0, SKIP, 0, NULL},
1522 {FNAME("protocolIdentifier") OID, BYTE, 0, 0, SKIP, 0, NULL},
1523 {FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
1524 _NonStandardParameter},
1525 {FNAME("rasAddress") CHOICE, 3, 7, 7, DECODE | EXT,
1526 offsetof(GatekeeperRequest, rasAddress), _TransportAddress},
1527 {FNAME("endpointType") SEQ, 6, 8, 10, STOP | EXT, 0, NULL},
1528 {FNAME("gatekeeperIdentifier") BMPSTR, 7, 1, 0, STOP | OPT, 0, NULL},
1529 {FNAME("callServices") SEQ, 0, 8, 8, STOP | EXT | OPT, 0, NULL},
1530 {FNAME("endpointAlias") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
1531 {FNAME("alternateEndpoints") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
1532 {FNAME("tokens") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
1533 {FNAME("cryptoTokens") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
1534 {FNAME("authenticationCapability") SEQOF, SEMI, 0, 0, STOP | OPT, 0,
1535 NULL},
1536 {FNAME("algorithmOIDs") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
1537 {FNAME("integrity") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
1538 {FNAME("integrityCheckValue") SEQ, 0, 2, 2, STOP | OPT, 0, NULL},
1539 {FNAME("supportsAltGK") NUL, FIXD, 0, 0, STOP | OPT, 0, NULL},
1540 {FNAME("featureSet") SEQ, 3, 4, 4, STOP | EXT | OPT, 0, NULL},
1541 {FNAME("genericData") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
1542};
1543
1544static field_t _GatekeeperConfirm[] = { /* SEQUENCE */
1545 {FNAME("requestSeqNum") INT, WORD, 1, 0, SKIP, 0, NULL},
1546 {FNAME("protocolIdentifier") OID, BYTE, 0, 0, SKIP, 0, NULL},
1547 {FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
1548 _NonStandardParameter},
1549 {FNAME("gatekeeperIdentifier") BMPSTR, 7, 1, 0, SKIP | OPT, 0, NULL},
1550 {FNAME("rasAddress") CHOICE, 3, 7, 7, DECODE | EXT,
1551 offsetof(GatekeeperConfirm, rasAddress), _TransportAddress},
1552 {FNAME("alternateGatekeeper") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
1553 {FNAME("authenticationMode") CHOICE, 3, 7, 8, STOP | EXT | OPT, 0,
1554 NULL},
1555 {FNAME("tokens") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
1556 {FNAME("cryptoTokens") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
1557 {FNAME("algorithmOID") OID, BYTE, 0, 0, STOP | OPT, 0, NULL},
1558 {FNAME("integrity") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
1559 {FNAME("integrityCheckValue") SEQ, 0, 2, 2, STOP | OPT, 0, NULL},
1560 {FNAME("featureSet") SEQ, 3, 4, 4, STOP | EXT | OPT, 0, NULL},
1561 {FNAME("genericData") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
1562};
1563
1564static field_t _RegistrationRequest_callSignalAddress[] = { /* SEQUENCE OF */
1565 {FNAME("item") CHOICE, 3, 7, 7, DECODE | EXT,
1566 sizeof(TransportAddress), _TransportAddress}
1567 ,
1568};
1569
1570static field_t _RegistrationRequest_rasAddress[] = { /* SEQUENCE OF */
1571 {FNAME("item") CHOICE, 3, 7, 7, DECODE | EXT,
1572 sizeof(TransportAddress), _TransportAddress}
1573 ,
1574};
1575
1576static field_t _RegistrationRequest_terminalAlias[] = { /* SEQUENCE OF */
1577 {FNAME("item") CHOICE, 1, 2, 7, SKIP | EXT, 0, _AliasAddress},
1578};
1579
1580static field_t _RegistrationRequest[] = { /* SEQUENCE */
1581 {FNAME("requestSeqNum") INT, WORD, 1, 0, SKIP, 0, NULL},
1582 {FNAME("protocolIdentifier") OID, BYTE, 0, 0, SKIP, 0, NULL},
1583 {FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
1584 _NonStandardParameter},
1585 {FNAME("discoveryComplete") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
1586 {FNAME("callSignalAddress") SEQOF, SEMI, 0, 10, DECODE,
1587 offsetof(RegistrationRequest, callSignalAddress),
1588 _RegistrationRequest_callSignalAddress},
1589 {FNAME("rasAddress") SEQOF, SEMI, 0, 10, DECODE,
1590 offsetof(RegistrationRequest, rasAddress),
1591 _RegistrationRequest_rasAddress},
1592 {FNAME("terminalType") SEQ, 6, 8, 10, SKIP | EXT, 0, _EndpointType},
1593 {FNAME("terminalAlias") SEQOF, SEMI, 0, 0, SKIP | OPT, 0,
1594 _RegistrationRequest_terminalAlias},
1595 {FNAME("gatekeeperIdentifier") BMPSTR, 7, 1, 0, SKIP | OPT, 0, NULL},
1596 {FNAME("endpointVendor") SEQ, 2, 3, 3, SKIP | EXT, 0,
1597 _VendorIdentifier},
1598 {FNAME("alternateEndpoints") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
1599 {FNAME("timeToLive") INT, CONS, 1, 0, DECODE | OPT,
1600 offsetof(RegistrationRequest, timeToLive), NULL},
1601 {FNAME("tokens") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
1602 {FNAME("cryptoTokens") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
1603 {FNAME("integrityCheckValue") SEQ, 0, 2, 2, STOP | OPT, 0, NULL},
1604 {FNAME("keepAlive") BOOL, FIXD, 0, 0, STOP, 0, NULL},
1605 {FNAME("endpointIdentifier") BMPSTR, 7, 1, 0, STOP | OPT, 0, NULL},
1606 {FNAME("willSupplyUUIEs") BOOL, FIXD, 0, 0, STOP, 0, NULL},
1607 {FNAME("maintainConnection") BOOL, FIXD, 0, 0, STOP, 0, NULL},
1608 {FNAME("alternateTransportAddresses") SEQ, 1, 1, 1, STOP | EXT | OPT,
1609 0, NULL},
1610 {FNAME("additiveRegistration") NUL, FIXD, 0, 0, STOP | OPT, 0, NULL},
1611 {FNAME("terminalAliasPattern") SEQOF, SEMI, 0, 0, STOP | OPT, 0,
1612 NULL},
1613 {FNAME("supportsAltGK") NUL, FIXD, 0, 0, STOP | OPT, 0, NULL},
1614 {FNAME("usageReportingCapability") SEQ, 3, 4, 4, STOP | EXT | OPT, 0,
1615 NULL},
1616 {FNAME("multipleCalls") BOOL, FIXD, 0, 0, STOP | OPT, 0, NULL},
1617 {FNAME("supportedH248Packages") SEQOF, SEMI, 0, 0, STOP | OPT, 0,
1618 NULL},
1619 {FNAME("callCreditCapability") SEQ, 2, 2, 2, STOP | EXT | OPT, 0,
1620 NULL},
1621 {FNAME("capacityReportingCapability") SEQ, 0, 1, 1, STOP | EXT | OPT,
1622 0, NULL},
1623 {FNAME("capacity") SEQ, 2, 2, 2, STOP | EXT | OPT, 0, NULL},
1624 {FNAME("featureSet") SEQ, 3, 4, 4, STOP | EXT | OPT, 0, NULL},
1625 {FNAME("genericData") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
1626};
1627
1628static field_t _RegistrationConfirm_callSignalAddress[] = { /* SEQUENCE OF */
1629 {FNAME("item") CHOICE, 3, 7, 7, DECODE | EXT,
1630 sizeof(TransportAddress), _TransportAddress}
1631 ,
1632};
1633
1634static field_t _RegistrationConfirm_terminalAlias[] = { /* SEQUENCE OF */
1635 {FNAME("item") CHOICE, 1, 2, 7, SKIP | EXT, 0, _AliasAddress},
1636};
1637
1638static field_t _RegistrationConfirm[] = { /* SEQUENCE */
1639 {FNAME("requestSeqNum") INT, WORD, 1, 0, SKIP, 0, NULL},
1640 {FNAME("protocolIdentifier") OID, BYTE, 0, 0, SKIP, 0, NULL},
1641 {FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
1642 _NonStandardParameter},
1643 {FNAME("callSignalAddress") SEQOF, SEMI, 0, 10, DECODE,
1644 offsetof(RegistrationConfirm, callSignalAddress),
1645 _RegistrationConfirm_callSignalAddress},
1646 {FNAME("terminalAlias") SEQOF, SEMI, 0, 0, SKIP | OPT, 0,
1647 _RegistrationConfirm_terminalAlias},
1648 {FNAME("gatekeeperIdentifier") BMPSTR, 7, 1, 0, SKIP | OPT, 0, NULL},
1649 {FNAME("endpointIdentifier") BMPSTR, 7, 1, 0, SKIP, 0, NULL},
1650 {FNAME("alternateGatekeeper") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
1651 {FNAME("timeToLive") INT, CONS, 1, 0, DECODE | OPT,
1652 offsetof(RegistrationConfirm, timeToLive), NULL},
1653 {FNAME("tokens") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
1654 {FNAME("cryptoTokens") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
1655 {FNAME("integrityCheckValue") SEQ, 0, 2, 2, STOP | OPT, 0, NULL},
1656 {FNAME("willRespondToIRR") BOOL, FIXD, 0, 0, STOP, 0, NULL},
1657 {FNAME("preGrantedARQ") SEQ, 0, 4, 8, STOP | EXT | OPT, 0, NULL},
1658 {FNAME("maintainConnection") BOOL, FIXD, 0, 0, STOP, 0, NULL},
1659 {FNAME("serviceControl") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
1660 {FNAME("supportsAdditiveRegistration") NUL, FIXD, 0, 0, STOP | OPT, 0,
1661 NULL},
1662 {FNAME("terminalAliasPattern") SEQOF, SEMI, 0, 0, STOP | OPT, 0,
1663 NULL},
1664 {FNAME("supportedPrefixes") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
1665 {FNAME("usageSpec") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
1666 {FNAME("featureServerAlias") CHOICE, 1, 2, 7, STOP | EXT | OPT, 0,
1667 NULL},
1668 {FNAME("capacityReportingSpec") SEQ, 0, 1, 1, STOP | EXT | OPT, 0,
1669 NULL},
1670 {FNAME("featureSet") SEQ, 3, 4, 4, STOP | EXT | OPT, 0, NULL},
1671 {FNAME("genericData") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
1672};
1673
1674static field_t _UnregistrationRequest_callSignalAddress[] = { /* SEQUENCE OF */
1675 {FNAME("item") CHOICE, 3, 7, 7, DECODE | EXT,
1676 sizeof(TransportAddress), _TransportAddress}
1677 ,
1678};
1679
1680static field_t _UnregistrationRequest[] = { /* SEQUENCE */
1681 {FNAME("requestSeqNum") INT, WORD, 1, 0, SKIP, 0, NULL},
1682 {FNAME("callSignalAddress") SEQOF, SEMI, 0, 10, DECODE,
1683 offsetof(UnregistrationRequest, callSignalAddress),
1684 _UnregistrationRequest_callSignalAddress},
1685 {FNAME("endpointAlias") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
1686 {FNAME("nonStandardData") SEQ, 0, 2, 2, STOP | OPT, 0, NULL},
1687 {FNAME("endpointIdentifier") BMPSTR, 7, 1, 0, STOP | OPT, 0, NULL},
1688 {FNAME("alternateEndpoints") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
1689 {FNAME("gatekeeperIdentifier") BMPSTR, 7, 1, 0, STOP | OPT, 0, NULL},
1690 {FNAME("tokens") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
1691 {FNAME("cryptoTokens") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
1692 {FNAME("integrityCheckValue") SEQ, 0, 2, 2, STOP | OPT, 0, NULL},
1693 {FNAME("reason") CHOICE, 2, 4, 5, STOP | EXT | OPT, 0, NULL},
1694 {FNAME("endpointAliasPattern") SEQOF, SEMI, 0, 0, STOP | OPT, 0,
1695 NULL},
1696 {FNAME("supportedPrefixes") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
1697 {FNAME("alternateGatekeeper") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
1698 {FNAME("genericData") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
1699};
1700
1701static field_t _CallModel[] = { /* CHOICE */
1702 {FNAME("direct") NUL, FIXD, 0, 0, SKIP, 0, NULL},
1703 {FNAME("gatekeeperRouted") NUL, FIXD, 0, 0, SKIP, 0, NULL},
1704};
1705
1706static field_t _AdmissionRequest_destinationInfo[] = { /* SEQUENCE OF */
1707 {FNAME("item") CHOICE, 1, 2, 7, SKIP | EXT, 0, _AliasAddress},
1708};
1709
1710static field_t _AdmissionRequest_destExtraCallInfo[] = { /* SEQUENCE OF */
1711 {FNAME("item") CHOICE, 1, 2, 7, SKIP | EXT, 0, _AliasAddress},
1712};
1713
1714static field_t _AdmissionRequest_srcInfo[] = { /* SEQUENCE OF */
1715 {FNAME("item") CHOICE, 1, 2, 7, SKIP | EXT, 0, _AliasAddress},
1716};
1717
1718static field_t _AdmissionRequest[] = { /* SEQUENCE */
1719 {FNAME("requestSeqNum") INT, WORD, 1, 0, SKIP, 0, NULL},
1720 {FNAME("callType") CHOICE, 2, 4, 4, SKIP | EXT, 0, _CallType},
1721 {FNAME("callModel") CHOICE, 1, 2, 2, SKIP | EXT | OPT, 0, _CallModel},
1722 {FNAME("endpointIdentifier") BMPSTR, 7, 1, 0, SKIP, 0, NULL},
1723 {FNAME("destinationInfo") SEQOF, SEMI, 0, 0, SKIP | OPT, 0,
1724 _AdmissionRequest_destinationInfo},
1725 {FNAME("destCallSignalAddress") CHOICE, 3, 7, 7, DECODE | EXT | OPT,
1726 offsetof(AdmissionRequest, destCallSignalAddress),
1727 _TransportAddress},
1728 {FNAME("destExtraCallInfo") SEQOF, SEMI, 0, 0, SKIP | OPT, 0,
1729 _AdmissionRequest_destExtraCallInfo},
1730 {FNAME("srcInfo") SEQOF, SEMI, 0, 0, SKIP, 0,
1731 _AdmissionRequest_srcInfo},
1732 {FNAME("srcCallSignalAddress") CHOICE, 3, 7, 7, DECODE | EXT | OPT,
1733 offsetof(AdmissionRequest, srcCallSignalAddress), _TransportAddress},
1734 {FNAME("bandWidth") INT, CONS, 0, 0, STOP, 0, NULL},
1735 {FNAME("callReferenceValue") INT, WORD, 0, 0, STOP, 0, NULL},
1736 {FNAME("nonStandardData") SEQ, 0, 2, 2, STOP | OPT, 0, NULL},
1737 {FNAME("callServices") SEQ, 0, 8, 8, STOP | EXT | OPT, 0, NULL},
1738 {FNAME("conferenceID") OCTSTR, FIXD, 16, 0, STOP, 0, NULL},
1739 {FNAME("activeMC") BOOL, FIXD, 0, 0, STOP, 0, NULL},
1740 {FNAME("answerCall") BOOL, FIXD, 0, 0, STOP, 0, NULL},
1741 {FNAME("canMapAlias") BOOL, FIXD, 0, 0, STOP, 0, NULL},
1742 {FNAME("callIdentifier") SEQ, 0, 1, 1, STOP | EXT, 0, NULL},
1743 {FNAME("srcAlternatives") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
1744 {FNAME("destAlternatives") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
1745 {FNAME("gatekeeperIdentifier") BMPSTR, 7, 1, 0, STOP | OPT, 0, NULL},
1746 {FNAME("tokens") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
1747 {FNAME("cryptoTokens") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
1748 {FNAME("integrityCheckValue") SEQ, 0, 2, 2, STOP | OPT, 0, NULL},
1749 {FNAME("transportQOS") CHOICE, 2, 3, 3, STOP | EXT | OPT, 0, NULL},
1750 {FNAME("willSupplyUUIEs") BOOL, FIXD, 0, 0, STOP, 0, NULL},
1751 {FNAME("callLinkage") SEQ, 2, 2, 2, STOP | EXT | OPT, 0, NULL},
1752 {FNAME("gatewayDataRate") SEQ, 2, 3, 3, STOP | EXT | OPT, 0, NULL},
1753 {FNAME("capacity") SEQ, 2, 2, 2, STOP | EXT | OPT, 0, NULL},
1754 {FNAME("circuitInfo") SEQ, 3, 3, 3, STOP | EXT | OPT, 0, NULL},
1755 {FNAME("desiredProtocols") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
1756 {FNAME("desiredTunnelledProtocol") SEQ, 1, 2, 2, STOP | EXT | OPT, 0,
1757 NULL},
1758 {FNAME("featureSet") SEQ, 3, 4, 4, STOP | EXT | OPT, 0, NULL},
1759 {FNAME("genericData") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
1760};
1761
1762static field_t _AdmissionConfirm[] = { /* SEQUENCE */
1763 {FNAME("requestSeqNum") INT, WORD, 1, 0, SKIP, 0, NULL},
1764 {FNAME("bandWidth") INT, CONS, 0, 0, SKIP, 0, NULL},
1765 {FNAME("callModel") CHOICE, 1, 2, 2, SKIP | EXT, 0, _CallModel},
1766 {FNAME("destCallSignalAddress") CHOICE, 3, 7, 7, DECODE | EXT,
1767 offsetof(AdmissionConfirm, destCallSignalAddress),
1768 _TransportAddress},
1769 {FNAME("irrFrequency") INT, WORD, 1, 0, STOP | OPT, 0, NULL},
1770 {FNAME("nonStandardData") SEQ, 0, 2, 2, STOP | OPT, 0, NULL},
1771 {FNAME("destinationInfo") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
1772 {FNAME("destExtraCallInfo") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
1773 {FNAME("destinationType") SEQ, 6, 8, 10, STOP | EXT | OPT, 0, NULL},
1774 {FNAME("remoteExtensionAddress") SEQOF, SEMI, 0, 0, STOP | OPT, 0,
1775 NULL},
1776 {FNAME("alternateEndpoints") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
1777 {FNAME("tokens") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
1778 {FNAME("cryptoTokens") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
1779 {FNAME("integrityCheckValue") SEQ, 0, 2, 2, STOP | OPT, 0, NULL},
1780 {FNAME("transportQOS") CHOICE, 2, 3, 3, STOP | EXT | OPT, 0, NULL},
1781 {FNAME("willRespondToIRR") BOOL, FIXD, 0, 0, STOP, 0, NULL},
1782 {FNAME("uuiesRequested") SEQ, 0, 9, 13, STOP | EXT, 0, NULL},
1783 {FNAME("language") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
1784 {FNAME("alternateTransportAddresses") SEQ, 1, 1, 1, STOP | EXT | OPT,
1785 0, NULL},
1786 {FNAME("useSpecifiedTransport") CHOICE, 1, 2, 2, STOP | EXT | OPT, 0,
1787 NULL},
1788 {FNAME("circuitInfo") SEQ, 3, 3, 3, STOP | EXT | OPT, 0, NULL},
1789 {FNAME("usageSpec") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
1790 {FNAME("supportedProtocols") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
1791 {FNAME("serviceControl") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
1792 {FNAME("multipleCalls") BOOL, FIXD, 0, 0, STOP | OPT, 0, NULL},
1793 {FNAME("featureSet") SEQ, 3, 4, 4, STOP | EXT | OPT, 0, NULL},
1794 {FNAME("genericData") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
1795};
1796
1797static field_t _LocationRequest_destinationInfo[] = { /* SEQUENCE OF */
1798 {FNAME("item") CHOICE, 1, 2, 7, SKIP | EXT, 0, _AliasAddress},
1799};
1800
1801static field_t _LocationRequest[] = { /* SEQUENCE */
1802 {FNAME("requestSeqNum") INT, WORD, 1, 0, SKIP, 0, NULL},
1803 {FNAME("endpointIdentifier") BMPSTR, 7, 1, 0, SKIP | OPT, 0, NULL},
1804 {FNAME("destinationInfo") SEQOF, SEMI, 0, 0, SKIP, 0,
1805 _LocationRequest_destinationInfo},
1806 {FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
1807 _NonStandardParameter},
1808 {FNAME("replyAddress") CHOICE, 3, 7, 7, DECODE | EXT,
1809 offsetof(LocationRequest, replyAddress), _TransportAddress},
1810 {FNAME("sourceInfo") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
1811 {FNAME("canMapAlias") BOOL, FIXD, 0, 0, STOP, 0, NULL},
1812 {FNAME("gatekeeperIdentifier") BMPSTR, 7, 1, 0, STOP | OPT, 0, NULL},
1813 {FNAME("tokens") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
1814 {FNAME("cryptoTokens") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
1815 {FNAME("integrityCheckValue") SEQ, 0, 2, 2, STOP | OPT, 0, NULL},
1816 {FNAME("desiredProtocols") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
1817 {FNAME("desiredTunnelledProtocol") SEQ, 1, 2, 2, STOP | EXT | OPT, 0,
1818 NULL},
1819 {FNAME("featureSet") SEQ, 3, 4, 4, STOP | EXT | OPT, 0, NULL},
1820 {FNAME("genericData") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
1821 {FNAME("hopCount") INT, 8, 1, 0, STOP | OPT, 0, NULL},
1822 {FNAME("circuitInfo") SEQ, 3, 3, 3, STOP | EXT | OPT, 0, NULL},
1823};
1824
1825static field_t _LocationConfirm[] = { /* SEQUENCE */
1826 {FNAME("requestSeqNum") INT, WORD, 1, 0, SKIP, 0, NULL},
1827 {FNAME("callSignalAddress") CHOICE, 3, 7, 7, DECODE | EXT,
1828 offsetof(LocationConfirm, callSignalAddress), _TransportAddress},
1829 {FNAME("rasAddress") CHOICE, 3, 7, 7, DECODE | EXT,
1830 offsetof(LocationConfirm, rasAddress), _TransportAddress},
1831 {FNAME("nonStandardData") SEQ, 0, 2, 2, STOP | OPT, 0, NULL},
1832 {FNAME("destinationInfo") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
1833 {FNAME("destExtraCallInfo") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
1834 {FNAME("destinationType") SEQ, 6, 8, 10, STOP | EXT | OPT, 0, NULL},
1835 {FNAME("remoteExtensionAddress") SEQOF, SEMI, 0, 0, STOP | OPT, 0,
1836 NULL},
1837 {FNAME("alternateEndpoints") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
1838 {FNAME("tokens") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
1839 {FNAME("cryptoTokens") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
1840 {FNAME("integrityCheckValue") SEQ, 0, 2, 2, STOP | OPT, 0, NULL},
1841 {FNAME("alternateTransportAddresses") SEQ, 1, 1, 1, STOP | EXT | OPT,
1842 0, NULL},
1843 {FNAME("supportedProtocols") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
1844 {FNAME("multipleCalls") BOOL, FIXD, 0, 0, STOP | OPT, 0, NULL},
1845 {FNAME("featureSet") SEQ, 3, 4, 4, STOP | EXT | OPT, 0, NULL},
1846 {FNAME("genericData") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
1847 {FNAME("circuitInfo") SEQ, 3, 3, 3, STOP | EXT | OPT, 0, NULL},
1848 {FNAME("serviceControl") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
1849};
1850
1851static field_t _InfoRequestResponse_callSignalAddress[] = { /* SEQUENCE OF */
1852 {FNAME("item") CHOICE, 3, 7, 7, DECODE | EXT,
1853 sizeof(TransportAddress), _TransportAddress}
1854 ,
1855};
1856
1857static field_t _InfoRequestResponse[] = { /* SEQUENCE */
1858 {FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
1859 _NonStandardParameter},
1860 {FNAME("requestSeqNum") INT, WORD, 1, 0, SKIP, 0, NULL},
1861 {FNAME("endpointType") SEQ, 6, 8, 10, SKIP | EXT, 0, _EndpointType},
1862 {FNAME("endpointIdentifier") BMPSTR, 7, 1, 0, SKIP, 0, NULL},
1863 {FNAME("rasAddress") CHOICE, 3, 7, 7, DECODE | EXT,
1864 offsetof(InfoRequestResponse, rasAddress), _TransportAddress},
1865 {FNAME("callSignalAddress") SEQOF, SEMI, 0, 10, DECODE,
1866 offsetof(InfoRequestResponse, callSignalAddress),
1867 _InfoRequestResponse_callSignalAddress},
1868 {FNAME("endpointAlias") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
1869 {FNAME("perCallInfo") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
1870 {FNAME("tokens") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
1871 {FNAME("cryptoTokens") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
1872 {FNAME("integrityCheckValue") SEQ, 0, 2, 2, STOP | OPT, 0, NULL},
1873 {FNAME("needResponse") BOOL, FIXD, 0, 0, STOP, 0, NULL},
1874 {FNAME("capacity") SEQ, 2, 2, 2, STOP | EXT | OPT, 0, NULL},
1875 {FNAME("irrStatus") CHOICE, 2, 4, 4, STOP | EXT | OPT, 0, NULL},
1876 {FNAME("unsolicited") BOOL, FIXD, 0, 0, STOP, 0, NULL},
1877 {FNAME("genericData") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
1878};
1879
1880static field_t _RasMessage[] = { /* CHOICE */
1881 {FNAME("gatekeeperRequest") SEQ, 4, 8, 18, DECODE | EXT,
1882 offsetof(RasMessage, gatekeeperRequest), _GatekeeperRequest},
1883 {FNAME("gatekeeperConfirm") SEQ, 2, 5, 14, DECODE | EXT,
1884 offsetof(RasMessage, gatekeeperConfirm), _GatekeeperConfirm},
1885 {FNAME("gatekeeperReject") SEQ, 2, 5, 11, STOP | EXT, 0, NULL},
1886 {FNAME("registrationRequest") SEQ, 3, 10, 31, DECODE | EXT,
1887 offsetof(RasMessage, registrationRequest), _RegistrationRequest},
1888 {FNAME("registrationConfirm") SEQ, 3, 7, 24, DECODE | EXT,
1889 offsetof(RasMessage, registrationConfirm), _RegistrationConfirm},
1890 {FNAME("registrationReject") SEQ, 2, 5, 11, STOP | EXT, 0, NULL},
1891 {FNAME("unregistrationRequest") SEQ, 3, 5, 15, DECODE | EXT,
1892 offsetof(RasMessage, unregistrationRequest), _UnregistrationRequest},
1893 {FNAME("unregistrationConfirm") SEQ, 1, 2, 6, STOP | EXT, 0, NULL},
1894 {FNAME("unregistrationReject") SEQ, 1, 3, 8, STOP | EXT, 0, NULL},
1895 {FNAME("admissionRequest") SEQ, 7, 16, 34, DECODE | EXT,
1896 offsetof(RasMessage, admissionRequest), _AdmissionRequest},
1897 {FNAME("admissionConfirm") SEQ, 2, 6, 27, DECODE | EXT,
1898 offsetof(RasMessage, admissionConfirm), _AdmissionConfirm},
1899 {FNAME("admissionReject") SEQ, 1, 3, 11, STOP | EXT, 0, NULL},
1900 {FNAME("bandwidthRequest") SEQ, 2, 7, 18, STOP | EXT, 0, NULL},
1901 {FNAME("bandwidthConfirm") SEQ, 1, 3, 8, STOP | EXT, 0, NULL},
1902 {FNAME("bandwidthReject") SEQ, 1, 4, 9, STOP | EXT, 0, NULL},
1903 {FNAME("disengageRequest") SEQ, 1, 6, 19, STOP | EXT, 0, NULL},
1904 {FNAME("disengageConfirm") SEQ, 1, 2, 9, STOP | EXT, 0, NULL},
1905 {FNAME("disengageReject") SEQ, 1, 3, 8, STOP | EXT, 0, NULL},
1906 {FNAME("locationRequest") SEQ, 2, 5, 17, DECODE | EXT,
1907 offsetof(RasMessage, locationRequest), _LocationRequest},
1908 {FNAME("locationConfirm") SEQ, 1, 4, 19, DECODE | EXT,
1909 offsetof(RasMessage, locationConfirm), _LocationConfirm},
1910 {FNAME("locationReject") SEQ, 1, 3, 10, STOP | EXT, 0, NULL},
1911 {FNAME("infoRequest") SEQ, 2, 4, 15, STOP | EXT, 0, NULL},
1912 {FNAME("infoRequestResponse") SEQ, 3, 8, 16, DECODE | EXT,
1913 offsetof(RasMessage, infoRequestResponse), _InfoRequestResponse},
1914 {FNAME("nonStandardMessage") SEQ, 0, 2, 7, STOP | EXT, 0, NULL},
1915 {FNAME("unknownMessageResponse") SEQ, 0, 1, 5, STOP | EXT, 0, NULL},
1916 {FNAME("requestInProgress") SEQ, 4, 6, 6, STOP | EXT, 0, NULL},
1917 {FNAME("resourcesAvailableIndicate") SEQ, 4, 9, 11, STOP | EXT, 0,
1918 NULL},
1919 {FNAME("resourcesAvailableConfirm") SEQ, 4, 6, 7, STOP | EXT, 0,
1920 NULL},
1921 {FNAME("infoRequestAck") SEQ, 4, 5, 5, STOP | EXT, 0, NULL},
1922 {FNAME("infoRequestNak") SEQ, 5, 7, 7, STOP | EXT, 0, NULL},
1923 {FNAME("serviceControlIndication") SEQ, 8, 10, 10, STOP | EXT, 0,
1924 NULL},
1925 {FNAME("serviceControlResponse") SEQ, 7, 8, 8, STOP | EXT, 0, NULL},
1926};
diff --git a/net/ipv4/netfilter/ip_conntrack_helper_h323_types.h b/net/ipv4/netfilter/ip_conntrack_helper_h323_types.h
new file mode 100644
index 000000000000..cc98f7aa5abe
--- /dev/null
+++ b/net/ipv4/netfilter/ip_conntrack_helper_h323_types.h
@@ -0,0 +1,938 @@
1/* Generated by Jing Min Zhao's ASN.1 parser, Mar 15 2006
2 *
3 * Copyright (c) 2006 Jing Min Zhao <zhaojingmin@users.sourceforge.net>
4 *
5 * This source code is licensed under General Public License version 2.
6 */
7
8typedef struct TransportAddress_ipAddress { /* SEQUENCE */
9 int options; /* No use */
10 unsigned ip;
11} TransportAddress_ipAddress;
12
13typedef struct TransportAddress { /* CHOICE */
14 enum {
15 eTransportAddress_ipAddress,
16 eTransportAddress_ipSourceRoute,
17 eTransportAddress_ipxAddress,
18 eTransportAddress_ip6Address,
19 eTransportAddress_netBios,
20 eTransportAddress_nsap,
21 eTransportAddress_nonStandardAddress,
22 } choice;
23 union {
24 TransportAddress_ipAddress ipAddress;
25 };
26} TransportAddress;
27
28typedef struct DataProtocolCapability { /* CHOICE */
29 enum {
30 eDataProtocolCapability_nonStandard,
31 eDataProtocolCapability_v14buffered,
32 eDataProtocolCapability_v42lapm,
33 eDataProtocolCapability_hdlcFrameTunnelling,
34 eDataProtocolCapability_h310SeparateVCStack,
35 eDataProtocolCapability_h310SingleVCStack,
36 eDataProtocolCapability_transparent,
37 eDataProtocolCapability_segmentationAndReassembly,
38 eDataProtocolCapability_hdlcFrameTunnelingwSAR,
39 eDataProtocolCapability_v120,
40 eDataProtocolCapability_separateLANStack,
41 eDataProtocolCapability_v76wCompression,
42 eDataProtocolCapability_tcp,
43 eDataProtocolCapability_udp,
44 } choice;
45} DataProtocolCapability;
46
47typedef struct DataApplicationCapability_application { /* CHOICE */
48 enum {
49 eDataApplicationCapability_application_nonStandard,
50 eDataApplicationCapability_application_t120,
51 eDataApplicationCapability_application_dsm_cc,
52 eDataApplicationCapability_application_userData,
53 eDataApplicationCapability_application_t84,
54 eDataApplicationCapability_application_t434,
55 eDataApplicationCapability_application_h224,
56 eDataApplicationCapability_application_nlpid,
57 eDataApplicationCapability_application_dsvdControl,
58 eDataApplicationCapability_application_h222DataPartitioning,
59 eDataApplicationCapability_application_t30fax,
60 eDataApplicationCapability_application_t140,
61 eDataApplicationCapability_application_t38fax,
62 eDataApplicationCapability_application_genericDataCapability,
63 } choice;
64 union {
65 DataProtocolCapability t120;
66 };
67} DataApplicationCapability_application;
68
69typedef struct DataApplicationCapability { /* SEQUENCE */
70 int options; /* No use */
71 DataApplicationCapability_application application;
72} DataApplicationCapability;
73
74typedef struct DataType { /* CHOICE */
75 enum {
76 eDataType_nonStandard,
77 eDataType_nullData,
78 eDataType_videoData,
79 eDataType_audioData,
80 eDataType_data,
81 eDataType_encryptionData,
82 eDataType_h235Control,
83 eDataType_h235Media,
84 eDataType_multiplexedStream,
85 } choice;
86 union {
87 DataApplicationCapability data;
88 };
89} DataType;
90
91typedef struct UnicastAddress_iPAddress { /* SEQUENCE */
92 int options; /* No use */
93 unsigned network;
94} UnicastAddress_iPAddress;
95
96typedef struct UnicastAddress { /* CHOICE */
97 enum {
98 eUnicastAddress_iPAddress,
99 eUnicastAddress_iPXAddress,
100 eUnicastAddress_iP6Address,
101 eUnicastAddress_netBios,
102 eUnicastAddress_iPSourceRouteAddress,
103 eUnicastAddress_nsap,
104 eUnicastAddress_nonStandardAddress,
105 } choice;
106 union {
107 UnicastAddress_iPAddress iPAddress;
108 };
109} UnicastAddress;
110
111typedef struct H245_TransportAddress { /* CHOICE */
112 enum {
113 eH245_TransportAddress_unicastAddress,
114 eH245_TransportAddress_multicastAddress,
115 } choice;
116 union {
117 UnicastAddress unicastAddress;
118 };
119} H245_TransportAddress;
120
121typedef struct H2250LogicalChannelParameters { /* SEQUENCE */
122 enum {
123 eH2250LogicalChannelParameters_nonStandard = (1 << 31),
124 eH2250LogicalChannelParameters_associatedSessionID =
125 (1 << 30),
126 eH2250LogicalChannelParameters_mediaChannel = (1 << 29),
127 eH2250LogicalChannelParameters_mediaGuaranteedDelivery =
128 (1 << 28),
129 eH2250LogicalChannelParameters_mediaControlChannel =
130 (1 << 27),
131 eH2250LogicalChannelParameters_mediaControlGuaranteedDelivery
132 = (1 << 26),
133 eH2250LogicalChannelParameters_silenceSuppression = (1 << 25),
134 eH2250LogicalChannelParameters_destination = (1 << 24),
135 eH2250LogicalChannelParameters_dynamicRTPPayloadType =
136 (1 << 23),
137 eH2250LogicalChannelParameters_mediaPacketization = (1 << 22),
138 eH2250LogicalChannelParameters_transportCapability =
139 (1 << 21),
140 eH2250LogicalChannelParameters_redundancyEncoding = (1 << 20),
141 eH2250LogicalChannelParameters_source = (1 << 19),
142 } options;
143 H245_TransportAddress mediaChannel;
144 H245_TransportAddress mediaControlChannel;
145} H2250LogicalChannelParameters;
146
147typedef struct OpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters { /* CHOICE */
148 enum {
149 eOpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters_h222LogicalChannelParameters,
150 eOpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters_h223LogicalChannelParameters,
151 eOpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters_v76LogicalChannelParameters,
152 eOpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters_h2250LogicalChannelParameters,
153 eOpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters_none,
154 } choice;
155 union {
156 H2250LogicalChannelParameters h2250LogicalChannelParameters;
157 };
158} OpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters;
159
160typedef struct OpenLogicalChannel_forwardLogicalChannelParameters { /* SEQUENCE */
161 enum {
162 eOpenLogicalChannel_forwardLogicalChannelParameters_portNumber
163 = (1 << 31),
164 eOpenLogicalChannel_forwardLogicalChannelParameters_forwardLogicalChannelDependency
165 = (1 << 30),
166 eOpenLogicalChannel_forwardLogicalChannelParameters_replacementFor
167 = (1 << 29),
168 } options;
169 DataType dataType;
170 OpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters
171 multiplexParameters;
172} OpenLogicalChannel_forwardLogicalChannelParameters;
173
174typedef struct OpenLogicalChannel_reverseLogicalChannelParameters_multiplexParameters { /* CHOICE */
175 enum {
176 eOpenLogicalChannel_reverseLogicalChannelParameters_multiplexParameters_h223LogicalChannelParameters,
177 eOpenLogicalChannel_reverseLogicalChannelParameters_multiplexParameters_v76LogicalChannelParameters,
178 eOpenLogicalChannel_reverseLogicalChannelParameters_multiplexParameters_h2250LogicalChannelParameters,
179 } choice;
180 union {
181 H2250LogicalChannelParameters h2250LogicalChannelParameters;
182 };
183} OpenLogicalChannel_reverseLogicalChannelParameters_multiplexParameters;
184
185typedef struct OpenLogicalChannel_reverseLogicalChannelParameters { /* SEQUENCE */
186 enum {
187 eOpenLogicalChannel_reverseLogicalChannelParameters_multiplexParameters
188 = (1 << 31),
189 eOpenLogicalChannel_reverseLogicalChannelParameters_reverseLogicalChannelDependency
190 = (1 << 30),
191 eOpenLogicalChannel_reverseLogicalChannelParameters_replacementFor
192 = (1 << 29),
193 } options;
194 OpenLogicalChannel_reverseLogicalChannelParameters_multiplexParameters
195 multiplexParameters;
196} OpenLogicalChannel_reverseLogicalChannelParameters;
197
198typedef struct NetworkAccessParameters_networkAddress { /* CHOICE */
199 enum {
200 eNetworkAccessParameters_networkAddress_q2931Address,
201 eNetworkAccessParameters_networkAddress_e164Address,
202 eNetworkAccessParameters_networkAddress_localAreaAddress,
203 } choice;
204 union {
205 H245_TransportAddress localAreaAddress;
206 };
207} NetworkAccessParameters_networkAddress;
208
209typedef struct NetworkAccessParameters { /* SEQUENCE */
210 enum {
211 eNetworkAccessParameters_distribution = (1 << 31),
212 eNetworkAccessParameters_externalReference = (1 << 30),
213 eNetworkAccessParameters_t120SetupProcedure = (1 << 29),
214 } options;
215 NetworkAccessParameters_networkAddress networkAddress;
216} NetworkAccessParameters;
217
218typedef struct OpenLogicalChannel { /* SEQUENCE */
219 enum {
220 eOpenLogicalChannel_reverseLogicalChannelParameters =
221 (1 << 31),
222 eOpenLogicalChannel_separateStack = (1 << 30),
223 eOpenLogicalChannel_encryptionSync = (1 << 29),
224 } options;
225 OpenLogicalChannel_forwardLogicalChannelParameters
226 forwardLogicalChannelParameters;
227 OpenLogicalChannel_reverseLogicalChannelParameters
228 reverseLogicalChannelParameters;
229 NetworkAccessParameters separateStack;
230} OpenLogicalChannel;
231
232typedef struct Setup_UUIE_fastStart { /* SEQUENCE OF */
233 int count;
234 OpenLogicalChannel item[30];
235} Setup_UUIE_fastStart;
236
237typedef struct Setup_UUIE { /* SEQUENCE */
238 enum {
239 eSetup_UUIE_h245Address = (1 << 31),
240 eSetup_UUIE_sourceAddress = (1 << 30),
241 eSetup_UUIE_destinationAddress = (1 << 29),
242 eSetup_UUIE_destCallSignalAddress = (1 << 28),
243 eSetup_UUIE_destExtraCallInfo = (1 << 27),
244 eSetup_UUIE_destExtraCRV = (1 << 26),
245 eSetup_UUIE_callServices = (1 << 25),
246 eSetup_UUIE_sourceCallSignalAddress = (1 << 24),
247 eSetup_UUIE_remoteExtensionAddress = (1 << 23),
248 eSetup_UUIE_callIdentifier = (1 << 22),
249 eSetup_UUIE_h245SecurityCapability = (1 << 21),
250 eSetup_UUIE_tokens = (1 << 20),
251 eSetup_UUIE_cryptoTokens = (1 << 19),
252 eSetup_UUIE_fastStart = (1 << 18),
253 eSetup_UUIE_mediaWaitForConnect = (1 << 17),
254 eSetup_UUIE_canOverlapSend = (1 << 16),
255 eSetup_UUIE_endpointIdentifier = (1 << 15),
256 eSetup_UUIE_multipleCalls = (1 << 14),
257 eSetup_UUIE_maintainConnection = (1 << 13),
258 eSetup_UUIE_connectionParameters = (1 << 12),
259 eSetup_UUIE_language = (1 << 11),
260 eSetup_UUIE_presentationIndicator = (1 << 10),
261 eSetup_UUIE_screeningIndicator = (1 << 9),
262 eSetup_UUIE_serviceControl = (1 << 8),
263 eSetup_UUIE_symmetricOperationRequired = (1 << 7),
264 eSetup_UUIE_capacity = (1 << 6),
265 eSetup_UUIE_circuitInfo = (1 << 5),
266 eSetup_UUIE_desiredProtocols = (1 << 4),
267 eSetup_UUIE_neededFeatures = (1 << 3),
268 eSetup_UUIE_desiredFeatures = (1 << 2),
269 eSetup_UUIE_supportedFeatures = (1 << 1),
270 eSetup_UUIE_parallelH245Control = (1 << 0),
271 } options;
272 TransportAddress h245Address;
273 TransportAddress destCallSignalAddress;
274 TransportAddress sourceCallSignalAddress;
275 Setup_UUIE_fastStart fastStart;
276} Setup_UUIE;
277
278typedef struct CallProceeding_UUIE_fastStart { /* SEQUENCE OF */
279 int count;
280 OpenLogicalChannel item[30];
281} CallProceeding_UUIE_fastStart;
282
283typedef struct CallProceeding_UUIE { /* SEQUENCE */
284 enum {
285 eCallProceeding_UUIE_h245Address = (1 << 31),
286 eCallProceeding_UUIE_callIdentifier = (1 << 30),
287 eCallProceeding_UUIE_h245SecurityMode = (1 << 29),
288 eCallProceeding_UUIE_tokens = (1 << 28),
289 eCallProceeding_UUIE_cryptoTokens = (1 << 27),
290 eCallProceeding_UUIE_fastStart = (1 << 26),
291 eCallProceeding_UUIE_multipleCalls = (1 << 25),
292 eCallProceeding_UUIE_maintainConnection = (1 << 24),
293 eCallProceeding_UUIE_fastConnectRefused = (1 << 23),
294 eCallProceeding_UUIE_featureSet = (1 << 22),
295 } options;
296 TransportAddress h245Address;
297 CallProceeding_UUIE_fastStart fastStart;
298} CallProceeding_UUIE;
299
300typedef struct Connect_UUIE_fastStart { /* SEQUENCE OF */
301 int count;
302 OpenLogicalChannel item[30];
303} Connect_UUIE_fastStart;
304
305typedef struct Connect_UUIE { /* SEQUENCE */
306 enum {
307 eConnect_UUIE_h245Address = (1 << 31),
308 eConnect_UUIE_callIdentifier = (1 << 30),
309 eConnect_UUIE_h245SecurityMode = (1 << 29),
310 eConnect_UUIE_tokens = (1 << 28),
311 eConnect_UUIE_cryptoTokens = (1 << 27),
312 eConnect_UUIE_fastStart = (1 << 26),
313 eConnect_UUIE_multipleCalls = (1 << 25),
314 eConnect_UUIE_maintainConnection = (1 << 24),
315 eConnect_UUIE_language = (1 << 23),
316 eConnect_UUIE_connectedAddress = (1 << 22),
317 eConnect_UUIE_presentationIndicator = (1 << 21),
318 eConnect_UUIE_screeningIndicator = (1 << 20),
319 eConnect_UUIE_fastConnectRefused = (1 << 19),
320 eConnect_UUIE_serviceControl = (1 << 18),
321 eConnect_UUIE_capacity = (1 << 17),
322 eConnect_UUIE_featureSet = (1 << 16),
323 } options;
324 TransportAddress h245Address;
325 Connect_UUIE_fastStart fastStart;
326} Connect_UUIE;
327
328typedef struct Alerting_UUIE_fastStart { /* SEQUENCE OF */
329 int count;
330 OpenLogicalChannel item[30];
331} Alerting_UUIE_fastStart;
332
333typedef struct Alerting_UUIE { /* SEQUENCE */
334 enum {
335 eAlerting_UUIE_h245Address = (1 << 31),
336 eAlerting_UUIE_callIdentifier = (1 << 30),
337 eAlerting_UUIE_h245SecurityMode = (1 << 29),
338 eAlerting_UUIE_tokens = (1 << 28),
339 eAlerting_UUIE_cryptoTokens = (1 << 27),
340 eAlerting_UUIE_fastStart = (1 << 26),
341 eAlerting_UUIE_multipleCalls = (1 << 25),
342 eAlerting_UUIE_maintainConnection = (1 << 24),
343 eAlerting_UUIE_alertingAddress = (1 << 23),
344 eAlerting_UUIE_presentationIndicator = (1 << 22),
345 eAlerting_UUIE_screeningIndicator = (1 << 21),
346 eAlerting_UUIE_fastConnectRefused = (1 << 20),
347 eAlerting_UUIE_serviceControl = (1 << 19),
348 eAlerting_UUIE_capacity = (1 << 18),
349 eAlerting_UUIE_featureSet = (1 << 17),
350 } options;
351 TransportAddress h245Address;
352 Alerting_UUIE_fastStart fastStart;
353} Alerting_UUIE;
354
355typedef struct Information_UUIE_fastStart { /* SEQUENCE OF */
356 int count;
357 OpenLogicalChannel item[30];
358} Information_UUIE_fastStart;
359
360typedef struct Information_UUIE { /* SEQUENCE */
361 enum {
362 eInformation_UUIE_callIdentifier = (1 << 31),
363 eInformation_UUIE_tokens = (1 << 30),
364 eInformation_UUIE_cryptoTokens = (1 << 29),
365 eInformation_UUIE_fastStart = (1 << 28),
366 eInformation_UUIE_fastConnectRefused = (1 << 27),
367 eInformation_UUIE_circuitInfo = (1 << 26),
368 } options;
369 Information_UUIE_fastStart fastStart;
370} Information_UUIE;
371
372typedef struct FacilityReason { /* CHOICE */
373 enum {
374 eFacilityReason_routeCallToGatekeeper,
375 eFacilityReason_callForwarded,
376 eFacilityReason_routeCallToMC,
377 eFacilityReason_undefinedReason,
378 eFacilityReason_conferenceListChoice,
379 eFacilityReason_startH245,
380 eFacilityReason_noH245,
381 eFacilityReason_newTokens,
382 eFacilityReason_featureSetUpdate,
383 eFacilityReason_forwardedElements,
384 eFacilityReason_transportedInformation,
385 } choice;
386} FacilityReason;
387
388typedef struct Facility_UUIE_fastStart { /* SEQUENCE OF */
389 int count;
390 OpenLogicalChannel item[30];
391} Facility_UUIE_fastStart;
392
393typedef struct Facility_UUIE { /* SEQUENCE */
394 enum {
395 eFacility_UUIE_alternativeAddress = (1 << 31),
396 eFacility_UUIE_alternativeAliasAddress = (1 << 30),
397 eFacility_UUIE_conferenceID = (1 << 29),
398 eFacility_UUIE_callIdentifier = (1 << 28),
399 eFacility_UUIE_destExtraCallInfo = (1 << 27),
400 eFacility_UUIE_remoteExtensionAddress = (1 << 26),
401 eFacility_UUIE_tokens = (1 << 25),
402 eFacility_UUIE_cryptoTokens = (1 << 24),
403 eFacility_UUIE_conferences = (1 << 23),
404 eFacility_UUIE_h245Address = (1 << 22),
405 eFacility_UUIE_fastStart = (1 << 21),
406 eFacility_UUIE_multipleCalls = (1 << 20),
407 eFacility_UUIE_maintainConnection = (1 << 19),
408 eFacility_UUIE_fastConnectRefused = (1 << 18),
409 eFacility_UUIE_serviceControl = (1 << 17),
410 eFacility_UUIE_circuitInfo = (1 << 16),
411 eFacility_UUIE_featureSet = (1 << 15),
412 eFacility_UUIE_destinationInfo = (1 << 14),
413 eFacility_UUIE_h245SecurityMode = (1 << 13),
414 } options;
415 FacilityReason reason;
416 TransportAddress h245Address;
417 Facility_UUIE_fastStart fastStart;
418} Facility_UUIE;
419
420typedef struct Progress_UUIE_fastStart { /* SEQUENCE OF */
421 int count;
422 OpenLogicalChannel item[30];
423} Progress_UUIE_fastStart;
424
425typedef struct Progress_UUIE { /* SEQUENCE */
426 enum {
427 eProgress_UUIE_h245Address = (1 << 31),
428 eProgress_UUIE_h245SecurityMode = (1 << 30),
429 eProgress_UUIE_tokens = (1 << 29),
430 eProgress_UUIE_cryptoTokens = (1 << 28),
431 eProgress_UUIE_fastStart = (1 << 27),
432 eProgress_UUIE_multipleCalls = (1 << 26),
433 eProgress_UUIE_maintainConnection = (1 << 25),
434 eProgress_UUIE_fastConnectRefused = (1 << 24),
435 } options;
436 TransportAddress h245Address;
437 Progress_UUIE_fastStart fastStart;
438} Progress_UUIE;
439
440typedef struct H323_UU_PDU_h323_message_body { /* CHOICE */
441 enum {
442 eH323_UU_PDU_h323_message_body_setup,
443 eH323_UU_PDU_h323_message_body_callProceeding,
444 eH323_UU_PDU_h323_message_body_connect,
445 eH323_UU_PDU_h323_message_body_alerting,
446 eH323_UU_PDU_h323_message_body_information,
447 eH323_UU_PDU_h323_message_body_releaseComplete,
448 eH323_UU_PDU_h323_message_body_facility,
449 eH323_UU_PDU_h323_message_body_progress,
450 eH323_UU_PDU_h323_message_body_empty,
451 eH323_UU_PDU_h323_message_body_status,
452 eH323_UU_PDU_h323_message_body_statusInquiry,
453 eH323_UU_PDU_h323_message_body_setupAcknowledge,
454 eH323_UU_PDU_h323_message_body_notify,
455 } choice;
456 union {
457 Setup_UUIE setup;
458 CallProceeding_UUIE callProceeding;
459 Connect_UUIE connect;
460 Alerting_UUIE alerting;
461 Information_UUIE information;
462 Facility_UUIE facility;
463 Progress_UUIE progress;
464 };
465} H323_UU_PDU_h323_message_body;
466
467typedef struct RequestMessage { /* CHOICE */
468 enum {
469 eRequestMessage_nonStandard,
470 eRequestMessage_masterSlaveDetermination,
471 eRequestMessage_terminalCapabilitySet,
472 eRequestMessage_openLogicalChannel,
473 eRequestMessage_closeLogicalChannel,
474 eRequestMessage_requestChannelClose,
475 eRequestMessage_multiplexEntrySend,
476 eRequestMessage_requestMultiplexEntry,
477 eRequestMessage_requestMode,
478 eRequestMessage_roundTripDelayRequest,
479 eRequestMessage_maintenanceLoopRequest,
480 eRequestMessage_communicationModeRequest,
481 eRequestMessage_conferenceRequest,
482 eRequestMessage_multilinkRequest,
483 eRequestMessage_logicalChannelRateRequest,
484 } choice;
485 union {
486 OpenLogicalChannel openLogicalChannel;
487 };
488} RequestMessage;
489
490typedef struct OpenLogicalChannelAck_reverseLogicalChannelParameters_multiplexParameters { /* CHOICE */
491 enum {
492 eOpenLogicalChannelAck_reverseLogicalChannelParameters_multiplexParameters_h222LogicalChannelParameters,
493 eOpenLogicalChannelAck_reverseLogicalChannelParameters_multiplexParameters_h2250LogicalChannelParameters,
494 } choice;
495 union {
496 H2250LogicalChannelParameters h2250LogicalChannelParameters;
497 };
498} OpenLogicalChannelAck_reverseLogicalChannelParameters_multiplexParameters;
499
500typedef struct OpenLogicalChannelAck_reverseLogicalChannelParameters { /* SEQUENCE */
501 enum {
502 eOpenLogicalChannelAck_reverseLogicalChannelParameters_portNumber
503 = (1 << 31),
504 eOpenLogicalChannelAck_reverseLogicalChannelParameters_multiplexParameters
505 = (1 << 30),
506 eOpenLogicalChannelAck_reverseLogicalChannelParameters_replacementFor
507 = (1 << 29),
508 } options;
509 OpenLogicalChannelAck_reverseLogicalChannelParameters_multiplexParameters
510 multiplexParameters;
511} OpenLogicalChannelAck_reverseLogicalChannelParameters;
512
513typedef struct H2250LogicalChannelAckParameters { /* SEQUENCE */
514 enum {
515 eH2250LogicalChannelAckParameters_nonStandard = (1 << 31),
516 eH2250LogicalChannelAckParameters_sessionID = (1 << 30),
517 eH2250LogicalChannelAckParameters_mediaChannel = (1 << 29),
518 eH2250LogicalChannelAckParameters_mediaControlChannel =
519 (1 << 28),
520 eH2250LogicalChannelAckParameters_dynamicRTPPayloadType =
521 (1 << 27),
522 eH2250LogicalChannelAckParameters_flowControlToZero =
523 (1 << 26),
524 eH2250LogicalChannelAckParameters_portNumber = (1 << 25),
525 } options;
526 H245_TransportAddress mediaChannel;
527 H245_TransportAddress mediaControlChannel;
528} H2250LogicalChannelAckParameters;
529
530typedef struct OpenLogicalChannelAck_forwardMultiplexAckParameters { /* CHOICE */
531 enum {
532 eOpenLogicalChannelAck_forwardMultiplexAckParameters_h2250LogicalChannelAckParameters,
533 } choice;
534 union {
535 H2250LogicalChannelAckParameters
536 h2250LogicalChannelAckParameters;
537 };
538} OpenLogicalChannelAck_forwardMultiplexAckParameters;
539
540typedef struct OpenLogicalChannelAck { /* SEQUENCE */
541 enum {
542 eOpenLogicalChannelAck_reverseLogicalChannelParameters =
543 (1 << 31),
544 eOpenLogicalChannelAck_separateStack = (1 << 30),
545 eOpenLogicalChannelAck_forwardMultiplexAckParameters =
546 (1 << 29),
547 eOpenLogicalChannelAck_encryptionSync = (1 << 28),
548 } options;
549 OpenLogicalChannelAck_reverseLogicalChannelParameters
550 reverseLogicalChannelParameters;
551 OpenLogicalChannelAck_forwardMultiplexAckParameters
552 forwardMultiplexAckParameters;
553} OpenLogicalChannelAck;
554
555typedef struct ResponseMessage { /* CHOICE */
556 enum {
557 eResponseMessage_nonStandard,
558 eResponseMessage_masterSlaveDeterminationAck,
559 eResponseMessage_masterSlaveDeterminationReject,
560 eResponseMessage_terminalCapabilitySetAck,
561 eResponseMessage_terminalCapabilitySetReject,
562 eResponseMessage_openLogicalChannelAck,
563 eResponseMessage_openLogicalChannelReject,
564 eResponseMessage_closeLogicalChannelAck,
565 eResponseMessage_requestChannelCloseAck,
566 eResponseMessage_requestChannelCloseReject,
567 eResponseMessage_multiplexEntrySendAck,
568 eResponseMessage_multiplexEntrySendReject,
569 eResponseMessage_requestMultiplexEntryAck,
570 eResponseMessage_requestMultiplexEntryReject,
571 eResponseMessage_requestModeAck,
572 eResponseMessage_requestModeReject,
573 eResponseMessage_roundTripDelayResponse,
574 eResponseMessage_maintenanceLoopAck,
575 eResponseMessage_maintenanceLoopReject,
576 eResponseMessage_communicationModeResponse,
577 eResponseMessage_conferenceResponse,
578 eResponseMessage_multilinkResponse,
579 eResponseMessage_logicalChannelRateAcknowledge,
580 eResponseMessage_logicalChannelRateReject,
581 } choice;
582 union {
583 OpenLogicalChannelAck openLogicalChannelAck;
584 };
585} ResponseMessage;
586
587typedef struct MultimediaSystemControlMessage { /* CHOICE */
588 enum {
589 eMultimediaSystemControlMessage_request,
590 eMultimediaSystemControlMessage_response,
591 eMultimediaSystemControlMessage_command,
592 eMultimediaSystemControlMessage_indication,
593 } choice;
594 union {
595 RequestMessage request;
596 ResponseMessage response;
597 };
598} MultimediaSystemControlMessage;
599
600typedef struct H323_UU_PDU_h245Control { /* SEQUENCE OF */
601 int count;
602 MultimediaSystemControlMessage item[4];
603} H323_UU_PDU_h245Control;
604
605typedef struct H323_UU_PDU { /* SEQUENCE */
606 enum {
607 eH323_UU_PDU_nonStandardData = (1 << 31),
608 eH323_UU_PDU_h4501SupplementaryService = (1 << 30),
609 eH323_UU_PDU_h245Tunneling = (1 << 29),
610 eH323_UU_PDU_h245Control = (1 << 28),
611 eH323_UU_PDU_nonStandardControl = (1 << 27),
612 eH323_UU_PDU_callLinkage = (1 << 26),
613 eH323_UU_PDU_tunnelledSignallingMessage = (1 << 25),
614 eH323_UU_PDU_provisionalRespToH245Tunneling = (1 << 24),
615 eH323_UU_PDU_stimulusControl = (1 << 23),
616 eH323_UU_PDU_genericData = (1 << 22),
617 } options;
618 H323_UU_PDU_h323_message_body h323_message_body;
619 H323_UU_PDU_h245Control h245Control;
620} H323_UU_PDU;
621
622typedef struct H323_UserInformation { /* SEQUENCE */
623 enum {
624 eH323_UserInformation_user_data = (1 << 31),
625 } options;
626 H323_UU_PDU h323_uu_pdu;
627} H323_UserInformation;
628
629typedef struct GatekeeperRequest { /* SEQUENCE */
630 enum {
631 eGatekeeperRequest_nonStandardData = (1 << 31),
632 eGatekeeperRequest_gatekeeperIdentifier = (1 << 30),
633 eGatekeeperRequest_callServices = (1 << 29),
634 eGatekeeperRequest_endpointAlias = (1 << 28),
635 eGatekeeperRequest_alternateEndpoints = (1 << 27),
636 eGatekeeperRequest_tokens = (1 << 26),
637 eGatekeeperRequest_cryptoTokens = (1 << 25),
638 eGatekeeperRequest_authenticationCapability = (1 << 24),
639 eGatekeeperRequest_algorithmOIDs = (1 << 23),
640 eGatekeeperRequest_integrity = (1 << 22),
641 eGatekeeperRequest_integrityCheckValue = (1 << 21),
642 eGatekeeperRequest_supportsAltGK = (1 << 20),
643 eGatekeeperRequest_featureSet = (1 << 19),
644 eGatekeeperRequest_genericData = (1 << 18),
645 } options;
646 TransportAddress rasAddress;
647} GatekeeperRequest;
648
649typedef struct GatekeeperConfirm { /* SEQUENCE */
650 enum {
651 eGatekeeperConfirm_nonStandardData = (1 << 31),
652 eGatekeeperConfirm_gatekeeperIdentifier = (1 << 30),
653 eGatekeeperConfirm_alternateGatekeeper = (1 << 29),
654 eGatekeeperConfirm_authenticationMode = (1 << 28),
655 eGatekeeperConfirm_tokens = (1 << 27),
656 eGatekeeperConfirm_cryptoTokens = (1 << 26),
657 eGatekeeperConfirm_algorithmOID = (1 << 25),
658 eGatekeeperConfirm_integrity = (1 << 24),
659 eGatekeeperConfirm_integrityCheckValue = (1 << 23),
660 eGatekeeperConfirm_featureSet = (1 << 22),
661 eGatekeeperConfirm_genericData = (1 << 21),
662 } options;
663 TransportAddress rasAddress;
664} GatekeeperConfirm;
665
666typedef struct RegistrationRequest_callSignalAddress { /* SEQUENCE OF */
667 int count;
668 TransportAddress item[10];
669} RegistrationRequest_callSignalAddress;
670
671typedef struct RegistrationRequest_rasAddress { /* SEQUENCE OF */
672 int count;
673 TransportAddress item[10];
674} RegistrationRequest_rasAddress;
675
676typedef struct RegistrationRequest { /* SEQUENCE */
677 enum {
678 eRegistrationRequest_nonStandardData = (1 << 31),
679 eRegistrationRequest_terminalAlias = (1 << 30),
680 eRegistrationRequest_gatekeeperIdentifier = (1 << 29),
681 eRegistrationRequest_alternateEndpoints = (1 << 28),
682 eRegistrationRequest_timeToLive = (1 << 27),
683 eRegistrationRequest_tokens = (1 << 26),
684 eRegistrationRequest_cryptoTokens = (1 << 25),
685 eRegistrationRequest_integrityCheckValue = (1 << 24),
686 eRegistrationRequest_keepAlive = (1 << 23),
687 eRegistrationRequest_endpointIdentifier = (1 << 22),
688 eRegistrationRequest_willSupplyUUIEs = (1 << 21),
689 eRegistrationRequest_maintainConnection = (1 << 20),
690 eRegistrationRequest_alternateTransportAddresses = (1 << 19),
691 eRegistrationRequest_additiveRegistration = (1 << 18),
692 eRegistrationRequest_terminalAliasPattern = (1 << 17),
693 eRegistrationRequest_supportsAltGK = (1 << 16),
694 eRegistrationRequest_usageReportingCapability = (1 << 15),
695 eRegistrationRequest_multipleCalls = (1 << 14),
696 eRegistrationRequest_supportedH248Packages = (1 << 13),
697 eRegistrationRequest_callCreditCapability = (1 << 12),
698 eRegistrationRequest_capacityReportingCapability = (1 << 11),
699 eRegistrationRequest_capacity = (1 << 10),
700 eRegistrationRequest_featureSet = (1 << 9),
701 eRegistrationRequest_genericData = (1 << 8),
702 } options;
703 RegistrationRequest_callSignalAddress callSignalAddress;
704 RegistrationRequest_rasAddress rasAddress;
705 unsigned timeToLive;
706} RegistrationRequest;
707
708typedef struct RegistrationConfirm_callSignalAddress { /* SEQUENCE OF */
709 int count;
710 TransportAddress item[10];
711} RegistrationConfirm_callSignalAddress;
712
713typedef struct RegistrationConfirm { /* SEQUENCE */
714 enum {
715 eRegistrationConfirm_nonStandardData = (1 << 31),
716 eRegistrationConfirm_terminalAlias = (1 << 30),
717 eRegistrationConfirm_gatekeeperIdentifier = (1 << 29),
718 eRegistrationConfirm_alternateGatekeeper = (1 << 28),
719 eRegistrationConfirm_timeToLive = (1 << 27),
720 eRegistrationConfirm_tokens = (1 << 26),
721 eRegistrationConfirm_cryptoTokens = (1 << 25),
722 eRegistrationConfirm_integrityCheckValue = (1 << 24),
723 eRegistrationConfirm_willRespondToIRR = (1 << 23),
724 eRegistrationConfirm_preGrantedARQ = (1 << 22),
725 eRegistrationConfirm_maintainConnection = (1 << 21),
726 eRegistrationConfirm_serviceControl = (1 << 20),
727 eRegistrationConfirm_supportsAdditiveRegistration = (1 << 19),
728 eRegistrationConfirm_terminalAliasPattern = (1 << 18),
729 eRegistrationConfirm_supportedPrefixes = (1 << 17),
730 eRegistrationConfirm_usageSpec = (1 << 16),
731 eRegistrationConfirm_featureServerAlias = (1 << 15),
732 eRegistrationConfirm_capacityReportingSpec = (1 << 14),
733 eRegistrationConfirm_featureSet = (1 << 13),
734 eRegistrationConfirm_genericData = (1 << 12),
735 } options;
736 RegistrationConfirm_callSignalAddress callSignalAddress;
737 unsigned timeToLive;
738} RegistrationConfirm;
739
740typedef struct UnregistrationRequest_callSignalAddress { /* SEQUENCE OF */
741 int count;
742 TransportAddress item[10];
743} UnregistrationRequest_callSignalAddress;
744
745typedef struct UnregistrationRequest { /* SEQUENCE */
746 enum {
747 eUnregistrationRequest_endpointAlias = (1 << 31),
748 eUnregistrationRequest_nonStandardData = (1 << 30),
749 eUnregistrationRequest_endpointIdentifier = (1 << 29),
750 eUnregistrationRequest_alternateEndpoints = (1 << 28),
751 eUnregistrationRequest_gatekeeperIdentifier = (1 << 27),
752 eUnregistrationRequest_tokens = (1 << 26),
753 eUnregistrationRequest_cryptoTokens = (1 << 25),
754 eUnregistrationRequest_integrityCheckValue = (1 << 24),
755 eUnregistrationRequest_reason = (1 << 23),
756 eUnregistrationRequest_endpointAliasPattern = (1 << 22),
757 eUnregistrationRequest_supportedPrefixes = (1 << 21),
758 eUnregistrationRequest_alternateGatekeeper = (1 << 20),
759 eUnregistrationRequest_genericData = (1 << 19),
760 } options;
761 UnregistrationRequest_callSignalAddress callSignalAddress;
762} UnregistrationRequest;
763
764typedef struct AdmissionRequest { /* SEQUENCE */
765 enum {
766 eAdmissionRequest_callModel = (1 << 31),
767 eAdmissionRequest_destinationInfo = (1 << 30),
768 eAdmissionRequest_destCallSignalAddress = (1 << 29),
769 eAdmissionRequest_destExtraCallInfo = (1 << 28),
770 eAdmissionRequest_srcCallSignalAddress = (1 << 27),
771 eAdmissionRequest_nonStandardData = (1 << 26),
772 eAdmissionRequest_callServices = (1 << 25),
773 eAdmissionRequest_canMapAlias = (1 << 24),
774 eAdmissionRequest_callIdentifier = (1 << 23),
775 eAdmissionRequest_srcAlternatives = (1 << 22),
776 eAdmissionRequest_destAlternatives = (1 << 21),
777 eAdmissionRequest_gatekeeperIdentifier = (1 << 20),
778 eAdmissionRequest_tokens = (1 << 19),
779 eAdmissionRequest_cryptoTokens = (1 << 18),
780 eAdmissionRequest_integrityCheckValue = (1 << 17),
781 eAdmissionRequest_transportQOS = (1 << 16),
782 eAdmissionRequest_willSupplyUUIEs = (1 << 15),
783 eAdmissionRequest_callLinkage = (1 << 14),
784 eAdmissionRequest_gatewayDataRate = (1 << 13),
785 eAdmissionRequest_capacity = (1 << 12),
786 eAdmissionRequest_circuitInfo = (1 << 11),
787 eAdmissionRequest_desiredProtocols = (1 << 10),
788 eAdmissionRequest_desiredTunnelledProtocol = (1 << 9),
789 eAdmissionRequest_featureSet = (1 << 8),
790 eAdmissionRequest_genericData = (1 << 7),
791 } options;
792 TransportAddress destCallSignalAddress;
793 TransportAddress srcCallSignalAddress;
794} AdmissionRequest;
795
796typedef struct AdmissionConfirm { /* SEQUENCE */
797 enum {
798 eAdmissionConfirm_irrFrequency = (1 << 31),
799 eAdmissionConfirm_nonStandardData = (1 << 30),
800 eAdmissionConfirm_destinationInfo = (1 << 29),
801 eAdmissionConfirm_destExtraCallInfo = (1 << 28),
802 eAdmissionConfirm_destinationType = (1 << 27),
803 eAdmissionConfirm_remoteExtensionAddress = (1 << 26),
804 eAdmissionConfirm_alternateEndpoints = (1 << 25),
805 eAdmissionConfirm_tokens = (1 << 24),
806 eAdmissionConfirm_cryptoTokens = (1 << 23),
807 eAdmissionConfirm_integrityCheckValue = (1 << 22),
808 eAdmissionConfirm_transportQOS = (1 << 21),
809 eAdmissionConfirm_willRespondToIRR = (1 << 20),
810 eAdmissionConfirm_uuiesRequested = (1 << 19),
811 eAdmissionConfirm_language = (1 << 18),
812 eAdmissionConfirm_alternateTransportAddresses = (1 << 17),
813 eAdmissionConfirm_useSpecifiedTransport = (1 << 16),
814 eAdmissionConfirm_circuitInfo = (1 << 15),
815 eAdmissionConfirm_usageSpec = (1 << 14),
816 eAdmissionConfirm_supportedProtocols = (1 << 13),
817 eAdmissionConfirm_serviceControl = (1 << 12),
818 eAdmissionConfirm_multipleCalls = (1 << 11),
819 eAdmissionConfirm_featureSet = (1 << 10),
820 eAdmissionConfirm_genericData = (1 << 9),
821 } options;
822 TransportAddress destCallSignalAddress;
823} AdmissionConfirm;
824
825typedef struct LocationRequest { /* SEQUENCE */
826 enum {
827 eLocationRequest_endpointIdentifier = (1 << 31),
828 eLocationRequest_nonStandardData = (1 << 30),
829 eLocationRequest_sourceInfo = (1 << 29),
830 eLocationRequest_canMapAlias = (1 << 28),
831 eLocationRequest_gatekeeperIdentifier = (1 << 27),
832 eLocationRequest_tokens = (1 << 26),
833 eLocationRequest_cryptoTokens = (1 << 25),
834 eLocationRequest_integrityCheckValue = (1 << 24),
835 eLocationRequest_desiredProtocols = (1 << 23),
836 eLocationRequest_desiredTunnelledProtocol = (1 << 22),
837 eLocationRequest_featureSet = (1 << 21),
838 eLocationRequest_genericData = (1 << 20),
839 eLocationRequest_hopCount = (1 << 19),
840 eLocationRequest_circuitInfo = (1 << 18),
841 } options;
842 TransportAddress replyAddress;
843} LocationRequest;
844
845typedef struct LocationConfirm { /* SEQUENCE */
846 enum {
847 eLocationConfirm_nonStandardData = (1 << 31),
848 eLocationConfirm_destinationInfo = (1 << 30),
849 eLocationConfirm_destExtraCallInfo = (1 << 29),
850 eLocationConfirm_destinationType = (1 << 28),
851 eLocationConfirm_remoteExtensionAddress = (1 << 27),
852 eLocationConfirm_alternateEndpoints = (1 << 26),
853 eLocationConfirm_tokens = (1 << 25),
854 eLocationConfirm_cryptoTokens = (1 << 24),
855 eLocationConfirm_integrityCheckValue = (1 << 23),
856 eLocationConfirm_alternateTransportAddresses = (1 << 22),
857 eLocationConfirm_supportedProtocols = (1 << 21),
858 eLocationConfirm_multipleCalls = (1 << 20),
859 eLocationConfirm_featureSet = (1 << 19),
860 eLocationConfirm_genericData = (1 << 18),
861 eLocationConfirm_circuitInfo = (1 << 17),
862 eLocationConfirm_serviceControl = (1 << 16),
863 } options;
864 TransportAddress callSignalAddress;
865 TransportAddress rasAddress;
866} LocationConfirm;
867
868typedef struct InfoRequestResponse_callSignalAddress { /* SEQUENCE OF */
869 int count;
870 TransportAddress item[10];
871} InfoRequestResponse_callSignalAddress;
872
873typedef struct InfoRequestResponse { /* SEQUENCE */
874 enum {
875 eInfoRequestResponse_nonStandardData = (1 << 31),
876 eInfoRequestResponse_endpointAlias = (1 << 30),
877 eInfoRequestResponse_perCallInfo = (1 << 29),
878 eInfoRequestResponse_tokens = (1 << 28),
879 eInfoRequestResponse_cryptoTokens = (1 << 27),
880 eInfoRequestResponse_integrityCheckValue = (1 << 26),
881 eInfoRequestResponse_needResponse = (1 << 25),
882 eInfoRequestResponse_capacity = (1 << 24),
883 eInfoRequestResponse_irrStatus = (1 << 23),
884 eInfoRequestResponse_unsolicited = (1 << 22),
885 eInfoRequestResponse_genericData = (1 << 21),
886 } options;
887 TransportAddress rasAddress;
888 InfoRequestResponse_callSignalAddress callSignalAddress;
889} InfoRequestResponse;
890
891typedef struct RasMessage { /* CHOICE */
892 enum {
893 eRasMessage_gatekeeperRequest,
894 eRasMessage_gatekeeperConfirm,
895 eRasMessage_gatekeeperReject,
896 eRasMessage_registrationRequest,
897 eRasMessage_registrationConfirm,
898 eRasMessage_registrationReject,
899 eRasMessage_unregistrationRequest,
900 eRasMessage_unregistrationConfirm,
901 eRasMessage_unregistrationReject,
902 eRasMessage_admissionRequest,
903 eRasMessage_admissionConfirm,
904 eRasMessage_admissionReject,
905 eRasMessage_bandwidthRequest,
906 eRasMessage_bandwidthConfirm,
907 eRasMessage_bandwidthReject,
908 eRasMessage_disengageRequest,
909 eRasMessage_disengageConfirm,
910 eRasMessage_disengageReject,
911 eRasMessage_locationRequest,
912 eRasMessage_locationConfirm,
913 eRasMessage_locationReject,
914 eRasMessage_infoRequest,
915 eRasMessage_infoRequestResponse,
916 eRasMessage_nonStandardMessage,
917 eRasMessage_unknownMessageResponse,
918 eRasMessage_requestInProgress,
919 eRasMessage_resourcesAvailableIndicate,
920 eRasMessage_resourcesAvailableConfirm,
921 eRasMessage_infoRequestAck,
922 eRasMessage_infoRequestNak,
923 eRasMessage_serviceControlIndication,
924 eRasMessage_serviceControlResponse,
925 } choice;
926 union {
927 GatekeeperRequest gatekeeperRequest;
928 GatekeeperConfirm gatekeeperConfirm;
929 RegistrationRequest registrationRequest;
930 RegistrationConfirm registrationConfirm;
931 UnregistrationRequest unregistrationRequest;
932 AdmissionRequest admissionRequest;
933 AdmissionConfirm admissionConfirm;
934 LocationRequest locationRequest;
935 LocationConfirm locationConfirm;
936 InfoRequestResponse infoRequestResponse;
937 };
938} RasMessage;
diff --git a/net/ipv4/netfilter/ip_nat_helper_h323.c b/net/ipv4/netfilter/ip_nat_helper_h323.c
new file mode 100644
index 000000000000..a0bc883928c0
--- /dev/null
+++ b/net/ipv4/netfilter/ip_nat_helper_h323.c
@@ -0,0 +1,605 @@
1/*
2 * H.323 extension for NAT alteration.
3 *
4 * Copyright (c) 2006 Jing Min Zhao <zhaojingmin@users.sourceforge.net>
5 *
6 * This source code is licensed under General Public License version 2.
7 *
8 * Based on the 'brute force' H.323 NAT module by
9 * Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
10 *
11 * Changes:
12 * 2006-02-01 - initial version 0.1
13 *
14 * 2006-02-20 - version 0.2
15 * 1. Changed source format to follow kernel conventions
16 * 2. Deleted some unnecessary structures
17 * 3. Minor fixes
18 *
19 * 2006-03-10 - version 0.3
20 * 1. Added support for multiple TPKTs in one packet (suggested by
21 * Patrick McHardy)
22 * 2. Added support for non-linear skb (based on Patrick McHardy's patch)
23 * 3. Eliminated unnecessary return code
24 *
25 * 2006-03-15 - version 0.4
26 * 1. Added support for T.120 channels
27 * 2. Added parameter gkrouted_only (suggested by Patrick McHardy)
28 */
29
30#include <linux/module.h>
31#include <linux/netfilter_ipv4.h>
32#include <linux/netfilter.h>
33#include <linux/ip.h>
34#include <linux/tcp.h>
35#include <linux/moduleparam.h>
36#include <net/tcp.h>
37#include <linux/netfilter_ipv4/ip_nat.h>
38#include <linux/netfilter_ipv4/ip_nat_helper.h>
39#include <linux/netfilter_ipv4/ip_nat_rule.h>
40#include <linux/netfilter_ipv4/ip_conntrack_tuple.h>
41#include <linux/netfilter_ipv4/ip_conntrack_h323.h>
42#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
43
44#include "ip_conntrack_helper_h323_asn1.h"
45
46#if 0
47#define DEBUGP printk
48#else
49#define DEBUGP(format, args...)
50#endif
51
52extern int get_h245_addr(unsigned char *data, H245_TransportAddress * addr,
53 u_int32_t * ip, u_int16_t * port);
54extern int get_h225_addr(unsigned char *data, TransportAddress * addr,
55 u_int32_t * ip, u_int16_t * port);
56extern void ip_conntrack_h245_expect(struct ip_conntrack *new,
57 struct ip_conntrack_expect *this);
58extern void ip_conntrack_q931_expect(struct ip_conntrack *new,
59 struct ip_conntrack_expect *this);
60extern int (*set_h245_addr_hook) (struct sk_buff ** pskb,
61 unsigned char **data, int dataoff,
62 H245_TransportAddress * addr,
63 u_int32_t ip, u_int16_t port);
64extern int (*set_h225_addr_hook) (struct sk_buff ** pskb,
65 unsigned char **data, int dataoff,
66 TransportAddress * addr,
67 u_int32_t ip, u_int16_t port);
68extern int (*set_sig_addr_hook) (struct sk_buff ** pskb,
69 struct ip_conntrack * ct,
70 enum ip_conntrack_info ctinfo,
71 unsigned char **data,
72 TransportAddress * addr, int count);
73extern int (*set_ras_addr_hook) (struct sk_buff ** pskb,
74 struct ip_conntrack * ct,
75 enum ip_conntrack_info ctinfo,
76 unsigned char **data,
77 TransportAddress * addr, int count);
78extern int (*nat_rtp_rtcp_hook) (struct sk_buff ** pskb,
79 struct ip_conntrack * ct,
80 enum ip_conntrack_info ctinfo,
81 unsigned char **data, int dataoff,
82 H245_TransportAddress * addr,
83 u_int16_t port, u_int16_t rtp_port,
84 struct ip_conntrack_expect * rtp_exp,
85 struct ip_conntrack_expect * rtcp_exp);
86extern int (*nat_t120_hook) (struct sk_buff ** pskb, struct ip_conntrack * ct,
87 enum ip_conntrack_info ctinfo,
88 unsigned char **data, int dataoff,
89 H245_TransportAddress * addr, u_int16_t port,
90 struct ip_conntrack_expect * exp);
91extern int (*nat_h245_hook) (struct sk_buff ** pskb, struct ip_conntrack * ct,
92 enum ip_conntrack_info ctinfo,
93 unsigned char **data, int dataoff,
94 TransportAddress * addr, u_int16_t port,
95 struct ip_conntrack_expect * exp);
96extern int (*nat_q931_hook) (struct sk_buff ** pskb, struct ip_conntrack * ct,
97 enum ip_conntrack_info ctinfo,
98 unsigned char **data, TransportAddress * addr,
99 int idx, u_int16_t port,
100 struct ip_conntrack_expect * exp);
101
102
103/****************************************************************************/
104static int set_addr(struct sk_buff **pskb,
105 unsigned char **data, int dataoff,
106 unsigned int addroff, u_int32_t ip, u_int16_t port)
107{
108 enum ip_conntrack_info ctinfo;
109 struct ip_conntrack *ct = ip_conntrack_get(*pskb, &ctinfo);
110 struct {
111 u_int32_t ip;
112 u_int16_t port;
113 } __attribute__ ((__packed__)) buf;
114 struct tcphdr _tcph, *th;
115
116 buf.ip = ip;
117 buf.port = htons(port);
118 addroff += dataoff;
119
120 if ((*pskb)->nh.iph->protocol == IPPROTO_TCP) {
121 if (!ip_nat_mangle_tcp_packet(pskb, ct, ctinfo,
122 addroff, sizeof(buf),
123 (char *) &buf, sizeof(buf))) {
124 if (net_ratelimit())
125 printk("ip_nat_h323: ip_nat_mangle_tcp_packet"
126 " error\n");
127 return -1;
128 }
129
130 /* Relocate data pointer */
131 th = skb_header_pointer(*pskb, (*pskb)->nh.iph->ihl * 4,
132 sizeof(_tcph), &_tcph);
133 if (th == NULL)
134 return -1;
135 *data = (*pskb)->data + (*pskb)->nh.iph->ihl * 4 +
136 th->doff * 4 + dataoff;
137 } else {
138 if (!ip_nat_mangle_udp_packet(pskb, ct, ctinfo,
139 addroff, sizeof(buf),
140 (char *) &buf, sizeof(buf))) {
141 if (net_ratelimit())
142 printk("ip_nat_h323: ip_nat_mangle_udp_packet"
143 " error\n");
144 return -1;
145 }
146 /* ip_nat_mangle_udp_packet uses skb_make_writable() to copy
147 * or pull everything in a linear buffer, so we can safely
148 * use the skb pointers now */
149 *data = (*pskb)->data + (*pskb)->nh.iph->ihl * 4 +
150 sizeof(struct udphdr);
151 }
152
153 return 0;
154}
155
156/****************************************************************************/
157static int set_h225_addr(struct sk_buff **pskb,
158 unsigned char **data, int dataoff,
159 TransportAddress * addr,
160 u_int32_t ip, u_int16_t port)
161{
162 return set_addr(pskb, data, dataoff, addr->ipAddress.ip, ip, port);
163}
164
165/****************************************************************************/
166static int set_h245_addr(struct sk_buff **pskb,
167 unsigned char **data, int dataoff,
168 H245_TransportAddress * addr,
169 u_int32_t ip, u_int16_t port)
170{
171 return set_addr(pskb, data, dataoff,
172 addr->unicastAddress.iPAddress.network, ip, port);
173}
174
175/****************************************************************************/
176static int set_sig_addr(struct sk_buff **pskb, struct ip_conntrack *ct,
177 enum ip_conntrack_info ctinfo,
178 unsigned char **data,
179 TransportAddress * addr, int count)
180{
181 struct ip_ct_h323_master *info = &ct->help.ct_h323_info;
182 int dir = CTINFO2DIR(ctinfo);
183 int i;
184 u_int32_t ip;
185 u_int16_t port;
186
187 for (i = 0; i < count; i++) {
188 if (get_h225_addr(*data, &addr[i], &ip, &port)) {
189 if (ip == ct->tuplehash[dir].tuple.src.ip &&
190 port == info->sig_port[dir]) {
191 /* GW->GK */
192
193 /* Fix for Gnomemeeting */
194 if (i > 0 &&
195 get_h225_addr(*data, &addr[0],
196 &ip, &port) &&
197 (ntohl(ip) & 0xff000000) == 0x7f000000)
198 i = 0;
199
200 DEBUGP
201 ("ip_nat_ras: set signal address "
202 "%u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
203 NIPQUAD(ip), port,
204 NIPQUAD(ct->tuplehash[!dir].tuple.dst.
205 ip), info->sig_port[!dir]);
206 return set_h225_addr(pskb, data, 0, &addr[i],
207 ct->tuplehash[!dir].
208 tuple.dst.ip,
209 info->sig_port[!dir]);
210 } else if (ip == ct->tuplehash[dir].tuple.dst.ip &&
211 port == info->sig_port[dir]) {
212 /* GK->GW */
213 DEBUGP
214 ("ip_nat_ras: set signal address "
215 "%u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
216 NIPQUAD(ip), port,
217 NIPQUAD(ct->tuplehash[!dir].tuple.src.
218 ip), info->sig_port[!dir]);
219 return set_h225_addr(pskb, data, 0, &addr[i],
220 ct->tuplehash[!dir].
221 tuple.src.ip,
222 info->sig_port[!dir]);
223 }
224 }
225 }
226
227 return 0;
228}
229
230/****************************************************************************/
231static int set_ras_addr(struct sk_buff **pskb, struct ip_conntrack *ct,
232 enum ip_conntrack_info ctinfo,
233 unsigned char **data,
234 TransportAddress * addr, int count)
235{
236 int dir = CTINFO2DIR(ctinfo);
237 int i;
238 u_int32_t ip;
239 u_int16_t port;
240
241 for (i = 0; i < count; i++) {
242 if (get_h225_addr(*data, &addr[i], &ip, &port) &&
243 ip == ct->tuplehash[dir].tuple.src.ip &&
244 port == ntohs(ct->tuplehash[dir].tuple.src.u.udp.port)) {
245 DEBUGP("ip_nat_ras: set rasAddress "
246 "%u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
247 NIPQUAD(ip), port,
248 NIPQUAD(ct->tuplehash[!dir].tuple.dst.ip),
249 ntohs(ct->tuplehash[!dir].tuple.dst.u.udp.
250 port));
251 return set_h225_addr(pskb, data, 0, &addr[i],
252 ct->tuplehash[!dir].tuple.dst.ip,
253 ntohs(ct->tuplehash[!dir].tuple.
254 dst.u.udp.port));
255 }
256 }
257
258 return 0;
259}
260
261/****************************************************************************/
262static int nat_rtp_rtcp(struct sk_buff **pskb, struct ip_conntrack *ct,
263 enum ip_conntrack_info ctinfo,
264 unsigned char **data, int dataoff,
265 H245_TransportAddress * addr,
266 u_int16_t port, u_int16_t rtp_port,
267 struct ip_conntrack_expect *rtp_exp,
268 struct ip_conntrack_expect *rtcp_exp)
269{
270 struct ip_ct_h323_master *info = &ct->help.ct_h323_info;
271 int dir = CTINFO2DIR(ctinfo);
272 int i;
273 u_int16_t nated_port;
274
275 /* Set expectations for NAT */
276 rtp_exp->saved_proto.udp.port = rtp_exp->tuple.dst.u.udp.port;
277 rtp_exp->expectfn = ip_nat_follow_master;
278 rtp_exp->dir = !dir;
279 rtcp_exp->saved_proto.udp.port = rtcp_exp->tuple.dst.u.udp.port;
280 rtcp_exp->expectfn = ip_nat_follow_master;
281 rtcp_exp->dir = !dir;
282
283 /* Lookup existing expects */
284 for (i = 0; i < H323_RTP_CHANNEL_MAX; i++) {
285 if (info->rtp_port[i][dir] == rtp_port) {
286 /* Expected */
287
288 /* Use allocated ports first. This will refresh
289 * the expects */
290 rtp_exp->tuple.dst.u.udp.port =
291 htons(info->rtp_port[i][dir]);
292 rtcp_exp->tuple.dst.u.udp.port =
293 htons(info->rtp_port[i][dir] + 1);
294 break;
295 } else if (info->rtp_port[i][dir] == 0) {
296 /* Not expected */
297 break;
298 }
299 }
300
301 /* Run out of expectations */
302 if (i >= H323_RTP_CHANNEL_MAX) {
303 if (net_ratelimit())
304 printk("ip_nat_h323: out of expectations\n");
305 return 0;
306 }
307
308 /* Try to get a pair of ports. */
309 for (nated_port = ntohs(rtp_exp->tuple.dst.u.udp.port);
310 nated_port != 0; nated_port += 2) {
311 rtp_exp->tuple.dst.u.udp.port = htons(nated_port);
312 if (ip_conntrack_expect_related(rtp_exp) == 0) {
313 rtcp_exp->tuple.dst.u.udp.port =
314 htons(nated_port + 1);
315 if (ip_conntrack_expect_related(rtcp_exp) == 0)
316 break;
317 ip_conntrack_unexpect_related(rtp_exp);
318 }
319 }
320
321 if (nated_port == 0) { /* No port available */
322 if (net_ratelimit())
323 printk("ip_nat_h323: out of RTP ports\n");
324 return 0;
325 }
326
327 /* Modify signal */
328 if (set_h245_addr(pskb, data, dataoff, addr,
329 ct->tuplehash[!dir].tuple.dst.ip,
330 (port & 1) ? nated_port + 1 : nated_port) == 0) {
331 /* Save ports */
332 info->rtp_port[i][dir] = rtp_port;
333 info->rtp_port[i][!dir] = nated_port;
334 } else {
335 ip_conntrack_unexpect_related(rtp_exp);
336 ip_conntrack_unexpect_related(rtcp_exp);
337 return -1;
338 }
339
340 /* Success */
341 DEBUGP("ip_nat_h323: expect RTP %u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
342 NIPQUAD(rtp_exp->tuple.src.ip),
343 ntohs(rtp_exp->tuple.src.u.udp.port),
344 NIPQUAD(rtp_exp->tuple.dst.ip),
345 ntohs(rtp_exp->tuple.dst.u.udp.port));
346 DEBUGP("ip_nat_h323: expect RTCP %u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
347 NIPQUAD(rtcp_exp->tuple.src.ip),
348 ntohs(rtcp_exp->tuple.src.u.udp.port),
349 NIPQUAD(rtcp_exp->tuple.dst.ip),
350 ntohs(rtcp_exp->tuple.dst.u.udp.port));
351
352 return 0;
353}
354
355/****************************************************************************/
356static int nat_t120(struct sk_buff **pskb, struct ip_conntrack *ct,
357 enum ip_conntrack_info ctinfo,
358 unsigned char **data, int dataoff,
359 H245_TransportAddress * addr, u_int16_t port,
360 struct ip_conntrack_expect *exp)
361{
362 int dir = CTINFO2DIR(ctinfo);
363 u_int16_t nated_port = port;
364
365 /* Set expectations for NAT */
366 exp->saved_proto.tcp.port = exp->tuple.dst.u.tcp.port;
367 exp->expectfn = ip_nat_follow_master;
368 exp->dir = !dir;
369
370 /* Try to get same port: if not, try to change it. */
371 for (; nated_port != 0; nated_port++) {
372 exp->tuple.dst.u.tcp.port = htons(nated_port);
373 if (ip_conntrack_expect_related(exp) == 0)
374 break;
375 }
376
377 if (nated_port == 0) { /* No port available */
378 if (net_ratelimit())
379 printk("ip_nat_h323: out of TCP ports\n");
380 return 0;
381 }
382
383 /* Modify signal */
384 if (set_h245_addr(pskb, data, dataoff, addr,
385 ct->tuplehash[!dir].tuple.dst.ip, nated_port) < 0) {
386 ip_conntrack_unexpect_related(exp);
387 return -1;
388 }
389
390 DEBUGP("ip_nat_h323: expect T.120 %u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
391 NIPQUAD(exp->tuple.src.ip), ntohs(exp->tuple.src.u.tcp.port),
392 NIPQUAD(exp->tuple.dst.ip), ntohs(exp->tuple.dst.u.tcp.port));
393
394 return 0;
395}
396
397/****************************************************************************
398 * This conntrack expect function replaces ip_conntrack_h245_expect()
399 * which was set by ip_conntrack_helper_h323.c. It calls both
400 * ip_nat_follow_master() and ip_conntrack_h245_expect()
401 ****************************************************************************/
402static void ip_nat_h245_expect(struct ip_conntrack *new,
403 struct ip_conntrack_expect *this)
404{
405 ip_nat_follow_master(new, this);
406 ip_conntrack_h245_expect(new, this);
407}
408
409/****************************************************************************/
410static int nat_h245(struct sk_buff **pskb, struct ip_conntrack *ct,
411 enum ip_conntrack_info ctinfo,
412 unsigned char **data, int dataoff,
413 TransportAddress * addr, u_int16_t port,
414 struct ip_conntrack_expect *exp)
415{
416 struct ip_ct_h323_master *info = &ct->help.ct_h323_info;
417 int dir = CTINFO2DIR(ctinfo);
418 u_int16_t nated_port = port;
419
420 /* Set expectations for NAT */
421 exp->saved_proto.tcp.port = exp->tuple.dst.u.tcp.port;
422 exp->expectfn = ip_nat_h245_expect;
423 exp->dir = !dir;
424
425 /* Check existing expects */
426 if (info->sig_port[dir] == port)
427 nated_port = info->sig_port[!dir];
428
429 /* Try to get same port: if not, try to change it. */
430 for (; nated_port != 0; nated_port++) {
431 exp->tuple.dst.u.tcp.port = htons(nated_port);
432 if (ip_conntrack_expect_related(exp) == 0)
433 break;
434 }
435
436 if (nated_port == 0) { /* No port available */
437 if (net_ratelimit())
438 printk("ip_nat_q931: out of TCP ports\n");
439 return 0;
440 }
441
442 /* Modify signal */
443 if (set_h225_addr(pskb, data, dataoff, addr,
444 ct->tuplehash[!dir].tuple.dst.ip,
445 nated_port) == 0) {
446 /* Save ports */
447 info->sig_port[dir] = port;
448 info->sig_port[!dir] = nated_port;
449 } else {
450 ip_conntrack_unexpect_related(exp);
451 return -1;
452 }
453
454 DEBUGP("ip_nat_q931: expect H.245 %u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
455 NIPQUAD(exp->tuple.src.ip), ntohs(exp->tuple.src.u.tcp.port),
456 NIPQUAD(exp->tuple.dst.ip), ntohs(exp->tuple.dst.u.tcp.port));
457
458 return 0;
459}
460
461/****************************************************************************
462 * This conntrack expect function replaces ip_conntrack_q931_expect()
463 * which was set by ip_conntrack_helper_h323.c.
464 ****************************************************************************/
465static void ip_nat_q931_expect(struct ip_conntrack *new,
466 struct ip_conntrack_expect *this)
467{
468 struct ip_nat_range range;
469
470 if (this->tuple.src.ip != 0) { /* Only accept calls from GK */
471 ip_nat_follow_master(new, this);
472 goto out;
473 }
474
475 /* This must be a fresh one. */
476 BUG_ON(new->status & IPS_NAT_DONE_MASK);
477
478 /* Change src to where master sends to */
479 range.flags = IP_NAT_RANGE_MAP_IPS;
480 range.min_ip = range.max_ip = new->tuplehash[!this->dir].tuple.src.ip;
481
482 /* hook doesn't matter, but it has to do source manip */
483 ip_nat_setup_info(new, &range, NF_IP_POST_ROUTING);
484
485 /* For DST manip, map port here to where it's expected. */
486 range.flags = (IP_NAT_RANGE_MAP_IPS | IP_NAT_RANGE_PROTO_SPECIFIED);
487 range.min = range.max = this->saved_proto;
488 range.min_ip = range.max_ip =
489 new->master->tuplehash[!this->dir].tuple.src.ip;
490
491 /* hook doesn't matter, but it has to do destination manip */
492 ip_nat_setup_info(new, &range, NF_IP_PRE_ROUTING);
493
494 out:
495 ip_conntrack_q931_expect(new, this);
496}
497
498/****************************************************************************/
499static int nat_q931(struct sk_buff **pskb, struct ip_conntrack *ct,
500 enum ip_conntrack_info ctinfo,
501 unsigned char **data, TransportAddress * addr, int idx,
502 u_int16_t port, struct ip_conntrack_expect *exp)
503{
504 struct ip_ct_h323_master *info = &ct->help.ct_h323_info;
505 int dir = CTINFO2DIR(ctinfo);
506 u_int16_t nated_port = port;
507 u_int32_t ip;
508
509 /* Set expectations for NAT */
510 exp->saved_proto.tcp.port = exp->tuple.dst.u.tcp.port;
511 exp->expectfn = ip_nat_q931_expect;
512 exp->dir = !dir;
513
514 /* Check existing expects */
515 if (info->sig_port[dir] == port)
516 nated_port = info->sig_port[!dir];
517
518 /* Try to get same port: if not, try to change it. */
519 for (; nated_port != 0; nated_port++) {
520 exp->tuple.dst.u.tcp.port = htons(nated_port);
521 if (ip_conntrack_expect_related(exp) == 0)
522 break;
523 }
524
525 if (nated_port == 0) { /* No port available */
526 if (net_ratelimit())
527 printk("ip_nat_ras: out of TCP ports\n");
528 return 0;
529 }
530
531 /* Modify signal */
532 if (set_h225_addr(pskb, data, 0, &addr[idx],
533 ct->tuplehash[!dir].tuple.dst.ip,
534 nated_port) == 0) {
535 /* Save ports */
536 info->sig_port[dir] = port;
537 info->sig_port[!dir] = nated_port;
538
539 /* Fix for Gnomemeeting */
540 if (idx > 0 &&
541 get_h225_addr(*data, &addr[0], &ip, &port) &&
542 (ntohl(ip) & 0xff000000) == 0x7f000000) {
543 set_h225_addr_hook(pskb, data, 0, &addr[0],
544 ct->tuplehash[!dir].tuple.dst.ip,
545 info->sig_port[!dir]);
546 }
547 } else {
548 ip_conntrack_unexpect_related(exp);
549 return -1;
550 }
551
552 /* Success */
553 DEBUGP("ip_nat_ras: expect Q.931 %u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
554 NIPQUAD(exp->tuple.src.ip), ntohs(exp->tuple.src.u.tcp.port),
555 NIPQUAD(exp->tuple.dst.ip), ntohs(exp->tuple.dst.u.tcp.port));
556
557 return 0;
558}
559
560/****************************************************************************/
561static int __init init(void)
562{
563 BUG_ON(set_h245_addr_hook != NULL);
564 BUG_ON(set_h225_addr_hook != NULL);
565 BUG_ON(set_sig_addr_hook != NULL);
566 BUG_ON(set_ras_addr_hook != NULL);
567 BUG_ON(nat_rtp_rtcp_hook != NULL);
568 BUG_ON(nat_t120_hook != NULL);
569 BUG_ON(nat_h245_hook != NULL);
570 BUG_ON(nat_q931_hook != NULL);
571
572 set_h245_addr_hook = set_h245_addr;
573 set_h225_addr_hook = set_h225_addr;
574 set_sig_addr_hook = set_sig_addr;
575 set_ras_addr_hook = set_ras_addr;
576 nat_rtp_rtcp_hook = nat_rtp_rtcp;
577 nat_t120_hook = nat_t120;
578 nat_h245_hook = nat_h245;
579 nat_q931_hook = nat_q931;
580
581 DEBUGP("ip_nat_h323: init success\n");
582 return 0;
583}
584
585/****************************************************************************/
586static void __exit fini(void)
587{
588 set_h245_addr_hook = NULL;
589 set_h225_addr_hook = NULL;
590 set_sig_addr_hook = NULL;
591 set_ras_addr_hook = NULL;
592 nat_rtp_rtcp_hook = NULL;
593 nat_t120_hook = NULL;
594 nat_h245_hook = NULL;
595 nat_q931_hook = NULL;
596 synchronize_net();
597}
598
599/****************************************************************************/
600module_init(init);
601module_exit(fini);
602
603MODULE_AUTHOR("Jing Min Zhao <zhaojingmin@users.sourceforge.net>");
604MODULE_DESCRIPTION("H.323 NAT helper");
605MODULE_LICENSE("GPL");