1 /* -*- c-basic-offset: 8 -*-
2 rdesktop: A Remote Desktop Protocol client.
3 Protocol services - Multipoint Communications Service
4 Copyright (C) Matthew Chapman 1999-2002
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 extern VCHANNEL g_channels[];
25 extern unsigned int g_num_channels;
27 /* Parse an ASN.1 BER header */
29 ber_parse_header(STREAM s, int tagval, int *length)
43 error("expected tag %d, got %d\n", tagval, tag);
62 /* Output an ASN.1 BER header */
64 ber_out_header(STREAM s, int tagval, int length)
68 out_uint16_be(s, tagval);
78 out_uint16_be(s, length);
84 /* Output an ASN.1 BER integer */
86 ber_out_integer(STREAM s, int value)
88 ber_out_header(s, BER_TAG_INTEGER, 2);
89 out_uint16_be(s, value);
93 ber_out_uint8(STREAM s, uint8 value)
95 ber_out_header(s, BER_TAG_INTEGER, 1);
100 ber_in_integer(STREAM s, int *value)
103 ber_parse_header(s, BER_TAG_INTEGER, &length);
104 in_uint16_be(s, *value);
107 /* Output a DOMAIN_PARAMS structure (ASN.1 BER) */
109 mcs_out_domain_params(STREAM s, int max_channels, int max_users, int max_tokens, int max_pdusize)
111 ber_out_header(s, MCS_TAG_DOMAIN_PARAMS, 26);
112 ber_out_uint8(s, 34); // max_channels
113 ber_out_uint8(s, 3); // max_users
114 ber_out_uint8(s, 0); // max_tokens
115 ber_out_uint8(s, 1); // num_priorities
116 ber_out_uint8(s, 0); // min_throughput
117 ber_out_uint8(s, 1); // max_height
118 ber_out_header(s, BER_TAG_INTEGER, 3); // pdu size
122 ber_out_uint8(s, 2); // ver_protocol
125 /* Parse a DOMAIN_PARAMS structure (ASN.1 BER) */
127 mcs_parse_domain_params(STREAM s)
130 int max_channels, max_users, max_tokens, max_pdusize;
131 int num_priorities, min_throughput, max_height;
134 ber_parse_header(s, MCS_TAG_DOMAIN_PARAMS, &length);
135 printf("MCS_TAG_DOMAIN_PARAMS, len %u (expected 32)\n", length);
137 ber_in_integer(s, &max_channels);
138 ber_in_integer(s, &max_users);
139 ber_in_integer(s, &max_tokens);
140 ber_in_integer(s, &num_priorities);
141 ber_in_integer(s, &min_throughput);
142 ber_in_integer(s, &max_height);
143 ber_in_integer(s, &max_pdusize);
144 ber_in_integer(s, &ver_protocol);
146 printf("max_channels=%u\n", max_channels);
147 printf("max_users=%u\n", max_users);
148 printf("max_tokens=%u\n", max_tokens);
149 printf("num_priorities=%u\n", num_priorities);
150 printf("min_throughput=%u\n", min_throughput);
151 printf("max_pdusize=%u\n", max_pdusize);
152 printf("ver_protocol=%u\n", ver_protocol);
154 hexdump(s->p, length);
155 in_uint8s(s, length);
161 /* Expect a MCS_CONNECT_RESPONSE message (ASN.1 BER) */
163 mcs_recv_connect_initial()
174 ber_parse_header(s, MCS_CONNECT_INITIAL, &length);
175 printf("parsing MCS_CONNECT_INITIAL (len=%u)\n", length);
176 ber_parse_header(s, BER_TAG_OCTET_STRING, &length); /* calling domain */
178 ber_parse_header(s, BER_TAG_OCTET_STRING, &length); /* called domain */
181 ber_parse_header(s, BER_TAG_BOOLEAN, &length);
184 mcs_parse_domain_params(s);
185 mcs_parse_domain_params(s);
186 mcs_parse_domain_params(s);
188 ber_parse_header(s, BER_TAG_OCTET_STRING, &length);
189 in_uint8p(s, buf, length);
191 printf("Data from MCS connect: '%*s'\n", length, buf);
193 return s_check_end(s);
196 /* keys grabbed from rdpproxy, look at http://www.cse.unsw.edu.au/~matthewc/rdesktop/rdpproxy/openssl/ */
197 unsigned char cacert[] = {
198 0x30, 0x82, 0x01, 0x6b, 0x30, 0x82, 0x01, 0x19, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x08, 0x01,
199 0x9d, 0xfb, 0xeb, 0x46, 0x78, 0x5b, 0x00, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d,
200 0x05, 0x00, 0x30, 0x34, 0x31, 0x32, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x03, 0x1e, 0x0e, 0x00,
201 0x56, 0x00, 0x49, 0x00, 0x56, 0x00, 0x41, 0x00, 0x4c, 0x00, 0x44, 0x00, 0x49, 0x30, 0x19, 0x06,
202 0x03, 0x55, 0x04, 0x07, 0x1e, 0x12, 0x00, 0x57, 0x00, 0x4f, 0x00, 0x52, 0x00, 0x4b, 0x00, 0x47,
203 0x00, 0x52, 0x00, 0x4f, 0x00, 0x55, 0x00, 0x50, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x32, 0x30, 0x36,
204 0x33, 0x30, 0x31, 0x35, 0x31, 0x31, 0x31, 0x39, 0x5a, 0x17, 0x0d, 0x30, 0x33, 0x30, 0x36, 0x33,
205 0x30, 0x31, 0x35, 0x31, 0x31, 0x31, 0x39, 0x5a, 0x30, 0x34, 0x31, 0x32, 0x30, 0x15, 0x06, 0x03,
206 0x55, 0x04, 0x03, 0x1e, 0x0e, 0x00, 0x56, 0x00, 0x49, 0x00, 0x56, 0x00, 0x41, 0x00, 0x4c, 0x00,
207 0x44, 0x00, 0x49, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x07, 0x1e, 0x12, 0x00, 0x57, 0x00, 0x4f,
208 0x00, 0x52, 0x00, 0x4b, 0x00, 0x47, 0x00, 0x52, 0x00, 0x4f, 0x00, 0x55, 0x00, 0x50, 0x30, 0x5c,
209 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03,
210 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41, 0x00, 0xc8, 0xc6, 0xb4, 0xd6, 0x31, 0x35, 0x5e, 0x6f, 0x01,
211 0x06, 0x1a, 0x02, 0x1d, 0x55, 0x46, 0x91, 0xe6, 0xa0, 0x19, 0x28, 0x4d, 0x87, 0x28, 0x5d, 0x22,
212 0xc8, 0xba, 0x8b, 0x6b, 0x93, 0x18, 0xbb, 0x93, 0x47, 0x14, 0xe5, 0x85, 0xe4, 0xfc, 0x49, 0x3d,
213 0x94, 0xbd, 0x5b, 0x2f, 0x7d, 0x0e, 0xa4, 0xa8, 0xc2, 0x79, 0x7c, 0x74, 0x6e, 0x39, 0x5d, 0x8a,
214 0xe4, 0x71, 0x22, 0xca, 0x37, 0x7e, 0x49, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x13, 0x30, 0x11,
215 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01,
216 0x00, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d, 0x05, 0x00, 0x03, 0x41, 0x00, 0x12,
217 0x79, 0xdd, 0xf9, 0x90, 0xb0, 0x39, 0x24, 0x35, 0x4d, 0x0b, 0xc6, 0xff, 0x8a, 0x96, 0x10, 0x4b,
218 0xac, 0xd0, 0x26, 0x5e, 0x44, 0xe1, 0x09, 0x72, 0x1b, 0xad, 0x4e, 0x34, 0x78, 0x32, 0xde, 0x29,
219 0x11, 0x08, 0x31, 0xba, 0x6d, 0x1b, 0x42, 0x7a, 0xa7, 0x45, 0xc6, 0xb7, 0xd3, 0xd3, 0x0f, 0x8b,
220 0xf3, 0xe5, 0x57, 0xde, 0x0d, 0x0c, 0xc1, 0x75, 0x60, 0x57, 0x1c, 0x0e, 0xf8, 0xf3, 0x0c
222 unsigned char server_cert[] = {
223 0x30, 0x82, 0x03, 0x79, 0x30, 0x82, 0x03, 0x27, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x05, 0x01,
224 0x00, 0x00, 0x00, 0x03, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d, 0x05, 0x00, 0x30,
225 0x34, 0x31, 0x32, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x03, 0x1e, 0x0e, 0x00, 0x56, 0x00, 0x49,
226 0x00, 0x56, 0x00, 0x41, 0x00, 0x4c, 0x00, 0x44, 0x00, 0x49, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04,
227 0x07, 0x1e, 0x12, 0x00, 0x57, 0x00, 0x4f, 0x00, 0x52, 0x00, 0x4b, 0x00, 0x47, 0x00, 0x52, 0x00,
228 0x4f, 0x00, 0x55, 0x00, 0x50, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x32, 0x30, 0x36, 0x33, 0x30, 0x31,
229 0x35, 0x31, 0x32, 0x30, 0x38, 0x5a, 0x17, 0x0d, 0x30, 0x33, 0x30, 0x36, 0x33, 0x30, 0x31, 0x35,
230 0x31, 0x32, 0x30, 0x38, 0x5a, 0x30, 0x81, 0x92, 0x31, 0x81, 0x8f, 0x30, 0x25, 0x06, 0x03, 0x55,
231 0x04, 0x03, 0x1e, 0x1e, 0x00, 0x6e, 0x00, 0x63, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x72, 0x00, 0x70,
232 0x00, 0x63, 0x00, 0x3a, 0x00, 0x56, 0x00, 0x49, 0x00, 0x56, 0x00, 0x41, 0x00, 0x4c, 0x00, 0x44,
233 0x00, 0x49, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x07, 0x1e, 0x1e, 0x00, 0x6e, 0x00, 0x63, 0x00,
234 0x61, 0x00, 0x6c, 0x00, 0x72, 0x00, 0x70, 0x00, 0x63, 0x00, 0x3a, 0x00, 0x56, 0x00, 0x49, 0x00,
235 0x56, 0x00, 0x41, 0x00, 0x4c, 0x00, 0x44, 0x00, 0x49, 0x30, 0x3f, 0x06, 0x03, 0x55, 0x04, 0x05,
236 0x1e, 0x38, 0x00, 0x31, 0x00, 0x42, 0x00, 0x63, 0x00, 0x4b, 0x00, 0x65, 0x00, 0x57, 0x00, 0x39,
237 0x00, 0x64, 0x00, 0x34, 0x00, 0x43, 0x00, 0x4f, 0x00, 0x59, 0x00, 0x44, 0x00, 0x48, 0x00, 0x2f,
238 0x00, 0x56, 0x00, 0x35, 0x00, 0x65, 0x00, 0x67, 0x00, 0x45, 0x00, 0x72, 0x00, 0x70, 0x00, 0x66,
239 0x00, 0x55, 0x00, 0x55, 0x00, 0x4f, 0x00, 0x63, 0x00, 0x3d, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09,
240 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48,
241 0x02, 0x41, 0x00, 0xb6, 0x88, 0xff, 0x4a, 0x6d, 0x44, 0x59, 0x6c, 0x3a, 0xe8, 0x5b, 0x53, 0x72,
242 0x2e, 0x0a, 0x3f, 0x0b, 0xbf, 0x33, 0x87, 0x25, 0x30, 0xeb, 0x82, 0xf7, 0xd4, 0x98, 0xf1, 0x60,
243 0xee, 0x6e, 0x99, 0xdd, 0x6f, 0x07, 0xd9, 0xc0, 0xa1, 0x6c, 0x1c, 0x50, 0xd7, 0xc1, 0x18, 0xe1,
244 0x5e, 0x70, 0x89, 0x3e, 0x6a, 0x98, 0x2c, 0x8b, 0xef, 0x76, 0x6d, 0x9b, 0x70, 0xb8, 0xd7, 0x41,
245 0x25, 0xa1, 0x01, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0xc3, 0x30, 0x82, 0x01, 0xbf,
246 0x30, 0x14, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x12, 0x04, 0x01, 0x01, 0xff,
247 0x04, 0x04, 0x01, 0x00, 0x05, 0x00, 0x30, 0x3c, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82,
248 0x37, 0x12, 0x02, 0x01, 0x01, 0xff, 0x04, 0x2c, 0x4d, 0x00, 0x69, 0x00, 0x63, 0x00, 0x72, 0x00,
249 0x6f, 0x00, 0x73, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x74, 0x00, 0x20, 0x00, 0x43, 0x00, 0x6f, 0x00,
250 0x72, 0x00, 0x70, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x61, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6f, 0x00,
251 0x6e, 0x00, 0x00, 0x00, 0x30, 0x81, 0xcd, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37,
252 0x12, 0x05, 0x01, 0x01, 0xff, 0x04, 0x81, 0xbc, 0x00, 0x30, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
253 0x02, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00, 0x1c, 0x00, 0x4a, 0x00, 0x66, 0x00, 0x4a, 0x00,
254 0xb0, 0x00, 0x01, 0x00, 0x33, 0x00, 0x64, 0x00, 0x32, 0x00, 0x36, 0x00, 0x37, 0x00, 0x39, 0x00,
255 0x35, 0x00, 0x34, 0x00, 0x2d, 0x00, 0x65, 0x00, 0x65, 0x00, 0x62, 0x00, 0x37, 0x00, 0x2d, 0x00,
256 0x31, 0x00, 0x31, 0x00, 0x64, 0x00, 0x31, 0x00, 0x2d, 0x00, 0x62, 0x00, 0x39, 0x00, 0x34, 0x00,
257 0x65, 0x00, 0x2d, 0x00, 0x30, 0x00, 0x30, 0x00, 0x63, 0x00, 0x30, 0x00, 0x34, 0x00, 0x66, 0x00,
258 0x61, 0x00, 0x33, 0x00, 0x30, 0x00, 0x38, 0x00, 0x30, 0x00, 0x64, 0x00, 0x00, 0x00, 0x33, 0x00,
259 0x64, 0x00, 0x32, 0x00, 0x36, 0x00, 0x37, 0x00, 0x39, 0x00, 0x35, 0x00, 0x34, 0x00, 0x2d, 0x00,
260 0x65, 0x00, 0x65, 0x00, 0x62, 0x00, 0x37, 0x00, 0x2d, 0x00, 0x31, 0x00, 0x31, 0x00, 0x64, 0x00,
261 0x31, 0x00, 0x2d, 0x00, 0x62, 0x00, 0x39, 0x00, 0x34, 0x00, 0x65, 0x00, 0x2d, 0x00, 0x30, 0x00,
262 0x30, 0x00, 0x63, 0x00, 0x30, 0x00, 0x34, 0x00, 0x66, 0x00, 0x61, 0x00, 0x33, 0x00, 0x30, 0x00,
263 0x38, 0x00, 0x30, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x80, 0xd4, 0x00,
264 0x00, 0x00, 0x00, 0x00, 0x30, 0x70, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x12,
265 0x06, 0x01, 0x01, 0xff, 0x04, 0x60, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x40, 0x00,
266 0x56, 0x00, 0x49, 0x00, 0x56, 0x00, 0x41, 0x00, 0x4c, 0x00, 0x44, 0x00, 0x49, 0x00, 0x00, 0x00,
267 0x35, 0x00, 0x31, 0x00, 0x38, 0x00, 0x37, 0x00, 0x39, 0x00, 0x2d, 0x00, 0x33, 0x00, 0x33, 0x00,
268 0x35, 0x00, 0x2d, 0x00, 0x38, 0x00, 0x33, 0x00, 0x39, 0x00, 0x31, 0x00, 0x30, 0x00, 0x30, 0x00,
269 0x37, 0x00, 0x2d, 0x00, 0x35, 0x00, 0x39, 0x00, 0x33, 0x00, 0x37, 0x00, 0x38, 0x00, 0x00, 0x00,
270 0x57, 0x00, 0x4f, 0x00, 0x52, 0x00, 0x4b, 0x00, 0x47, 0x00, 0x52, 0x00, 0x4f, 0x00, 0x55, 0x00,
271 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x27, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x01, 0x01, 0xff,
272 0x04, 0x1d, 0x30, 0x1b, 0xa1, 0x12, 0xa4, 0x10, 0x56, 0x00, 0x49, 0x00, 0x56, 0x00, 0x41, 0x00,
273 0x4c, 0x00, 0x44, 0x00, 0x49, 0x00, 0x00, 0x00, 0x82, 0x05, 0x01, 0x00, 0x00, 0x00, 0x03, 0x30,
274 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d, 0x05, 0x00, 0x03, 0x41, 0x00, 0xa8, 0x61, 0x11,
275 0x69, 0xab, 0x41, 0xee, 0x71, 0xd0, 0xa8, 0x4c, 0x8f, 0x65, 0x9d, 0x9d, 0xaf, 0xab, 0x4f, 0x43,
276 0xaf, 0xa8, 0x21, 0xb7, 0xf2, 0x2c, 0x3a, 0xa5, 0xfe, 0x9e, 0x2c, 0xbc, 0xbb, 0x5c, 0x64, 0x31,
277 0x15, 0x3c, 0xdc, 0x09, 0x4c, 0x36, 0x9a, 0x2b, 0x5e, 0xe0, 0xe6, 0x07, 0x79, 0xfd, 0xcd, 0x1d,
278 0x06, 0x63, 0xfa, 0xb4, 0x2c, 0xcc, 0x00, 0x25, 0x43, 0x71, 0x65, 0xff, 0xf7
282 mcs_send_connect_response()
287 s = iso_init(174 + sizeof(cacert) + sizeof(server_cert));
288 printf("INITLEN: %u\n", s->p - s->iso_hdr);
290 ber_out_header(s, MCS_CONNECT_RESPONSE, 169 + sizeof(cacert) + sizeof(server_cert) );
291 ber_out_header(s, BER_TAG_RESULT, 1);
294 ber_out_header(s, BER_TAG_INTEGER, 1);
295 out_uint8(s, 0); // connect id
297 mcs_out_domain_params(s, 34, 2, 0, 0xffff); // dumdidum?
299 ber_out_header(s, BER_TAG_OCTET_STRING, 131 + sizeof(cacert) + sizeof(server_cert));
301 // some unknown header of sorts
324 length = 108 + sizeof(cacert) + sizeof(server_cert);
326 // two bytes of length
327 out_uint8(s, 0x80 | (length >> 8));
328 out_uint8(s, length & 0xff);
330 // server info -- we claim to support RDP5
331 out_uint16_le(s, SEC_TAG_SRV_INFO);
332 out_uint16_le(s, 8); // length
333 out_uint16_le(s, 4); // version
334 out_uint16_le(s, 8); // unknown
336 // channel info -- open a few channels
337 out_uint16_le(s, SEC_TAG_SRV_CHANNELS);
338 out_uint16_le(s, 16); // length
339 out_uint16_le(s, 1003);
341 out_uint16_le(s, 1004);
342 out_uint16_le(s, 1005);
343 out_uint16_le(s, 1006);
347 out_uint16_le(s, SEC_TAG_SRV_CRYPT);
348 out_uint16_le(s, 84 + sizeof(cacert) + sizeof(server_cert)); // length
349 out_uint32_le(s, 8); // 128-bit
350 out_uint32_le(s, 2); // medium
352 out_uint32_le(s, SEC_RANDOM_SIZE); // random_len
353 out_uint32_le(s, 32 + sizeof(cacert) + sizeof(server_cert)); // rsa_info_len
354 out_uint8p(s, cacert, SEC_RANDOM_SIZE); // server_"random"
355 out_uint32_le(s, 0x80000002); // X.509
356 out_uint32_le(s, 2); // number of certificates
359 out_uint32_le(s, sizeof(cacert));
360 out_uint8p(s, cacert, sizeof(cacert));
362 // server certificate
363 out_uint32_le(s, sizeof(server_cert));
364 out_uint8p(s, server_cert, sizeof(server_cert));
366 out_uint8s(s, 16); // padding
373 /* Send an EDrq message (ASN.1 PER) */
381 out_uint8(s, (MCS_EDRQ << 2));
382 out_uint16_be(s, 1); /* height */
383 out_uint16_be(s, 1); /* interval */
389 /* Send an AUrq message (ASN.1 PER) */
397 out_uint8(s, (MCS_AURQ << 2));
403 /* Send a AUcf message (ASN.1 PER) */
405 mcs_send_aucf(uint16 mcs_userid)
411 out_uint8(s, (MCS_AUCF << 2) | 2); // | 2 = send user ID
412 out_uint8(s, 0); // success
419 /* Send a CJrq message (ASN.1 PER) */
421 mcs_send_cjrq(uint16 chanid)
425 DEBUG_RDP5(("Sending CJRQ for channel #%d\n", chanid));
429 out_uint8(s, (MCS_CJRQ << 2));
430 out_uint16_be(s, g_mcs_userid);
431 out_uint16_be(s, chanid);
437 /* Expect a CJcf message (ASN.1 PER) */
439 mcs_send_cjcf(uint16 userid, uint16 chanid)
445 out_uint8(s, (MCS_CJCF << 2) | 2);
446 out_uint8(s, 0); // success
448 out_uint16_be(s, chanid);
449 out_uint16_be(s, chanid);
455 /* Initialise an MCS transport data packet */
461 s = iso_init(length + 8);
462 s_push_layer(s, mcs_hdr, 8);
467 /* Send an MCS transport data packet to a specific channel */
469 mcs_send_to_channel(STREAM s, uint16 channel)
473 s_pop_layer(s, mcs_hdr);
474 length = s->end - s->p - 8;
477 out_uint8(s, (MCS_SDIN << 2));
478 out_uint16_be(s, g_mcs_userid);
479 out_uint16_be(s, channel);
480 out_uint8(s, 0x70); /* flags */
481 out_uint16_be(s, length);
486 /* Send an MCS transport data packet to the global channel */
490 mcs_send_to_channel(s, MCS_GLOBAL_CHANNEL);
493 /* Receive an MCS transport data packet */
495 mcs_recv(uint16 * channel)
497 uint8 opcode, appid, length, userid;
509 in_uint8s(s, 2); /* userid */
510 in_uint16_be(s, *channel);
511 in_uint8s(s, 1); /* flags */
514 in_uint8s(s, 1); /* second byte of length */
518 printf("Received DPUM (?)\n");
521 // Erect Domain (ignore)
522 printf("Received EDrq\n");
525 // Attach User Request, respond with AUcf (Attach User Confirm)
526 printf("Received AUrq, sending AUcf\n");
530 // Channel Join Request, respond with CJcf (Channel Join Confirm);
531 in_uint16_be(s, userid);
532 in_uint16_be(s, *channel);
533 printf("Received CJrq for channel %hu, sending CJcf\n", *channel);
534 mcs_send_cjcf(userid, *channel);
537 error("expected data, got %d\n", opcode);
543 /* Disconnect from the MCS layer */