xref: /freebsd/crypto/openssh/ttymodes.c (revision 47dd1d1b619cc035b82b49a91a25544309ff95ae)
1*47dd1d1bSDag-Erling Smørgrav /* $OpenBSD: ttymodes.c,v 1.33 2018/02/16 04:43:11 dtucker Exp $ */
2511b41d2SMark Murray /*
3511b41d2SMark Murray  * Author: Tatu Ylonen <ylo@cs.hut.fi>
4511b41d2SMark Murray  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
5511b41d2SMark Murray  *                    All rights reserved
6b66f2d16SKris Kennaway  *
7b66f2d16SKris Kennaway  * As far as I am concerned, the code I have written for this software
8b66f2d16SKris Kennaway  * can be used freely for any purpose.  Any derived versions of this
9b66f2d16SKris Kennaway  * software must be clearly marked as such, and if the derived work is
10b66f2d16SKris Kennaway  * incompatible with the protocol description in the RFC file, it must be
11b66f2d16SKris Kennaway  * called by a name other than "ssh" or "Secure Shell".
12511b41d2SMark Murray  */
13511b41d2SMark Murray 
141e8db6e2SBrian Feldman /*
151e8db6e2SBrian Feldman  * SSH2 tty modes support by Kevin Steves.
161e8db6e2SBrian Feldman  * Copyright (c) 2001 Kevin Steves.  All rights reserved.
171e8db6e2SBrian Feldman  *
181e8db6e2SBrian Feldman  * Redistribution and use in source and binary forms, with or without
191e8db6e2SBrian Feldman  * modification, are permitted provided that the following conditions
201e8db6e2SBrian Feldman  * are met:
211e8db6e2SBrian Feldman  * 1. Redistributions of source code must retain the above copyright
221e8db6e2SBrian Feldman  *    notice, this list of conditions and the following disclaimer.
231e8db6e2SBrian Feldman  * 2. Redistributions in binary form must reproduce the above copyright
241e8db6e2SBrian Feldman  *    notice, this list of conditions and the following disclaimer in the
251e8db6e2SBrian Feldman  *    documentation and/or other materials provided with the distribution.
261e8db6e2SBrian Feldman  *
271e8db6e2SBrian Feldman  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
281e8db6e2SBrian Feldman  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
291e8db6e2SBrian Feldman  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
301e8db6e2SBrian Feldman  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
311e8db6e2SBrian Feldman  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
321e8db6e2SBrian Feldman  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
331e8db6e2SBrian Feldman  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
341e8db6e2SBrian Feldman  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
351e8db6e2SBrian Feldman  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
361e8db6e2SBrian Feldman  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
371e8db6e2SBrian Feldman  */
381e8db6e2SBrian Feldman 
391e8db6e2SBrian Feldman /*
401e8db6e2SBrian Feldman  * Encoding and decoding of terminal modes in a portable way.
411e8db6e2SBrian Feldman  * Much of the format is defined in ttymodes.h; it is included multiple times
421e8db6e2SBrian Feldman  * into this file with the appropriate macro definitions to generate the
431e8db6e2SBrian Feldman  * suitable code.
441e8db6e2SBrian Feldman  */
451e8db6e2SBrian Feldman 
46511b41d2SMark Murray #include "includes.h"
47761efaa7SDag-Erling Smørgrav 
48761efaa7SDag-Erling Smørgrav #include <sys/types.h>
49761efaa7SDag-Erling Smørgrav 
50761efaa7SDag-Erling Smørgrav #include <errno.h>
51761efaa7SDag-Erling Smørgrav #include <string.h>
52761efaa7SDag-Erling Smørgrav #include <termios.h>
53761efaa7SDag-Erling Smørgrav #include <stdarg.h>
54511b41d2SMark Murray 
55511b41d2SMark Murray #include "packet.h"
561e8db6e2SBrian Feldman #include "log.h"
571e8db6e2SBrian Feldman #include "compat.h"
581e8db6e2SBrian Feldman #include "buffer.h"
59*47dd1d1bSDag-Erling Smørgrav #include "compat.h"
60511b41d2SMark Murray 
61511b41d2SMark Murray #define TTY_OP_END		0
621e8db6e2SBrian Feldman /*
634f52dfbbSDag-Erling Smørgrav  * uint32 (u_int) follows speed.
641e8db6e2SBrian Feldman  */
654f52dfbbSDag-Erling Smørgrav #define TTY_OP_ISPEED	128
664f52dfbbSDag-Erling Smørgrav #define TTY_OP_OSPEED	129
67511b41d2SMark Murray 
68511b41d2SMark Murray /*
69511b41d2SMark Murray  * Converts POSIX speed_t to a baud rate.  The values of the
70511b41d2SMark Murray  * constants for speed_t are not themselves portable.
71511b41d2SMark Murray  */
72511b41d2SMark Murray static int
73511b41d2SMark Murray speed_to_baud(speed_t speed)
74511b41d2SMark Murray {
75511b41d2SMark Murray 	switch (speed) {
76511b41d2SMark Murray 	case B0:
77511b41d2SMark Murray 		return 0;
78511b41d2SMark Murray 	case B50:
79511b41d2SMark Murray 		return 50;
80511b41d2SMark Murray 	case B75:
81511b41d2SMark Murray 		return 75;
82511b41d2SMark Murray 	case B110:
83511b41d2SMark Murray 		return 110;
84511b41d2SMark Murray 	case B134:
85511b41d2SMark Murray 		return 134;
86511b41d2SMark Murray 	case B150:
87511b41d2SMark Murray 		return 150;
88511b41d2SMark Murray 	case B200:
89511b41d2SMark Murray 		return 200;
90511b41d2SMark Murray 	case B300:
91511b41d2SMark Murray 		return 300;
92511b41d2SMark Murray 	case B600:
93511b41d2SMark Murray 		return 600;
94511b41d2SMark Murray 	case B1200:
95511b41d2SMark Murray 		return 1200;
96511b41d2SMark Murray 	case B1800:
97511b41d2SMark Murray 		return 1800;
98511b41d2SMark Murray 	case B2400:
99511b41d2SMark Murray 		return 2400;
100511b41d2SMark Murray 	case B4800:
101511b41d2SMark Murray 		return 4800;
102511b41d2SMark Murray 	case B9600:
103511b41d2SMark Murray 		return 9600;
104511b41d2SMark Murray 
105511b41d2SMark Murray #ifdef B19200
106511b41d2SMark Murray 	case B19200:
107511b41d2SMark Murray 		return 19200;
108511b41d2SMark Murray #else /* B19200 */
109511b41d2SMark Murray #ifdef EXTA
110511b41d2SMark Murray 	case EXTA:
111511b41d2SMark Murray 		return 19200;
112511b41d2SMark Murray #endif /* EXTA */
113511b41d2SMark Murray #endif /* B19200 */
114511b41d2SMark Murray 
115511b41d2SMark Murray #ifdef B38400
116511b41d2SMark Murray 	case B38400:
117511b41d2SMark Murray 		return 38400;
118511b41d2SMark Murray #else /* B38400 */
119511b41d2SMark Murray #ifdef EXTB
120511b41d2SMark Murray 	case EXTB:
121511b41d2SMark Murray 		return 38400;
122511b41d2SMark Murray #endif /* EXTB */
123511b41d2SMark Murray #endif /* B38400 */
124511b41d2SMark Murray 
125511b41d2SMark Murray #ifdef B7200
126511b41d2SMark Murray 	case B7200:
127511b41d2SMark Murray 		return 7200;
128511b41d2SMark Murray #endif /* B7200 */
129511b41d2SMark Murray #ifdef B14400
130511b41d2SMark Murray 	case B14400:
131511b41d2SMark Murray 		return 14400;
132511b41d2SMark Murray #endif /* B14400 */
133511b41d2SMark Murray #ifdef B28800
134511b41d2SMark Murray 	case B28800:
135511b41d2SMark Murray 		return 28800;
136511b41d2SMark Murray #endif /* B28800 */
137511b41d2SMark Murray #ifdef B57600
138511b41d2SMark Murray 	case B57600:
139511b41d2SMark Murray 		return 57600;
140511b41d2SMark Murray #endif /* B57600 */
141511b41d2SMark Murray #ifdef B76800
142511b41d2SMark Murray 	case B76800:
143511b41d2SMark Murray 		return 76800;
144511b41d2SMark Murray #endif /* B76800 */
145511b41d2SMark Murray #ifdef B115200
146511b41d2SMark Murray 	case B115200:
147511b41d2SMark Murray 		return 115200;
148511b41d2SMark Murray #endif /* B115200 */
149511b41d2SMark Murray #ifdef B230400
150511b41d2SMark Murray 	case B230400:
151511b41d2SMark Murray 		return 230400;
152511b41d2SMark Murray #endif /* B230400 */
153511b41d2SMark Murray 	default:
154511b41d2SMark Murray 		return 9600;
155511b41d2SMark Murray 	}
156511b41d2SMark Murray }
157511b41d2SMark Murray 
158511b41d2SMark Murray /*
159511b41d2SMark Murray  * Converts a numeric baud rate to a POSIX speed_t.
160511b41d2SMark Murray  */
161511b41d2SMark Murray static speed_t
162511b41d2SMark Murray baud_to_speed(int baud)
163511b41d2SMark Murray {
164511b41d2SMark Murray 	switch (baud) {
165511b41d2SMark Murray 	case 0:
166511b41d2SMark Murray 		return B0;
167511b41d2SMark Murray 	case 50:
168511b41d2SMark Murray 		return B50;
169511b41d2SMark Murray 	case 75:
170511b41d2SMark Murray 		return B75;
171511b41d2SMark Murray 	case 110:
172511b41d2SMark Murray 		return B110;
173511b41d2SMark Murray 	case 134:
174511b41d2SMark Murray 		return B134;
175511b41d2SMark Murray 	case 150:
176511b41d2SMark Murray 		return B150;
177511b41d2SMark Murray 	case 200:
178511b41d2SMark Murray 		return B200;
179511b41d2SMark Murray 	case 300:
180511b41d2SMark Murray 		return B300;
181511b41d2SMark Murray 	case 600:
182511b41d2SMark Murray 		return B600;
183511b41d2SMark Murray 	case 1200:
184511b41d2SMark Murray 		return B1200;
185511b41d2SMark Murray 	case 1800:
186511b41d2SMark Murray 		return B1800;
187511b41d2SMark Murray 	case 2400:
188511b41d2SMark Murray 		return B2400;
189511b41d2SMark Murray 	case 4800:
190511b41d2SMark Murray 		return B4800;
191511b41d2SMark Murray 	case 9600:
192511b41d2SMark Murray 		return B9600;
193511b41d2SMark Murray 
194511b41d2SMark Murray #ifdef B19200
195511b41d2SMark Murray 	case 19200:
196511b41d2SMark Murray 		return B19200;
197511b41d2SMark Murray #else /* B19200 */
198511b41d2SMark Murray #ifdef EXTA
199511b41d2SMark Murray 	case 19200:
200511b41d2SMark Murray 		return EXTA;
201511b41d2SMark Murray #endif /* EXTA */
202511b41d2SMark Murray #endif /* B19200 */
203511b41d2SMark Murray 
204511b41d2SMark Murray #ifdef B38400
205511b41d2SMark Murray 	case 38400:
206511b41d2SMark Murray 		return B38400;
207511b41d2SMark Murray #else /* B38400 */
208511b41d2SMark Murray #ifdef EXTB
209511b41d2SMark Murray 	case 38400:
210511b41d2SMark Murray 		return EXTB;
211511b41d2SMark Murray #endif /* EXTB */
212511b41d2SMark Murray #endif /* B38400 */
213511b41d2SMark Murray 
214511b41d2SMark Murray #ifdef B7200
215511b41d2SMark Murray 	case 7200:
216511b41d2SMark Murray 		return B7200;
217511b41d2SMark Murray #endif /* B7200 */
218511b41d2SMark Murray #ifdef B14400
219511b41d2SMark Murray 	case 14400:
220511b41d2SMark Murray 		return B14400;
221511b41d2SMark Murray #endif /* B14400 */
222511b41d2SMark Murray #ifdef B28800
223511b41d2SMark Murray 	case 28800:
224511b41d2SMark Murray 		return B28800;
225511b41d2SMark Murray #endif /* B28800 */
226511b41d2SMark Murray #ifdef B57600
227511b41d2SMark Murray 	case 57600:
228511b41d2SMark Murray 		return B57600;
229511b41d2SMark Murray #endif /* B57600 */
230511b41d2SMark Murray #ifdef B76800
231511b41d2SMark Murray 	case 76800:
232511b41d2SMark Murray 		return B76800;
233511b41d2SMark Murray #endif /* B76800 */
234511b41d2SMark Murray #ifdef B115200
235511b41d2SMark Murray 	case 115200:
236511b41d2SMark Murray 		return B115200;
237511b41d2SMark Murray #endif /* B115200 */
238511b41d2SMark Murray #ifdef B230400
239511b41d2SMark Murray 	case 230400:
240511b41d2SMark Murray 		return B230400;
241511b41d2SMark Murray #endif /* B230400 */
242511b41d2SMark Murray 	default:
243511b41d2SMark Murray 		return B9600;
244511b41d2SMark Murray 	}
245511b41d2SMark Murray }
246511b41d2SMark Murray 
247511b41d2SMark Murray /*
248043840dfSDag-Erling Smørgrav  * Encode a special character into SSH line format.
249043840dfSDag-Erling Smørgrav  */
250043840dfSDag-Erling Smørgrav static u_int
251043840dfSDag-Erling Smørgrav special_char_encode(cc_t c)
252043840dfSDag-Erling Smørgrav {
253043840dfSDag-Erling Smørgrav #ifdef _POSIX_VDISABLE
254043840dfSDag-Erling Smørgrav 	if (c == _POSIX_VDISABLE)
255043840dfSDag-Erling Smørgrav 		return 255;
256043840dfSDag-Erling Smørgrav #endif /* _POSIX_VDISABLE */
257043840dfSDag-Erling Smørgrav 	return c;
258043840dfSDag-Erling Smørgrav }
259043840dfSDag-Erling Smørgrav 
260043840dfSDag-Erling Smørgrav /*
261043840dfSDag-Erling Smørgrav  * Decode a special character from SSH line format.
262043840dfSDag-Erling Smørgrav  */
263043840dfSDag-Erling Smørgrav static cc_t
264043840dfSDag-Erling Smørgrav special_char_decode(u_int c)
265043840dfSDag-Erling Smørgrav {
266043840dfSDag-Erling Smørgrav #ifdef _POSIX_VDISABLE
267043840dfSDag-Erling Smørgrav 	if (c == 255)
268043840dfSDag-Erling Smørgrav 		return _POSIX_VDISABLE;
269043840dfSDag-Erling Smørgrav #endif /* _POSIX_VDISABLE */
270043840dfSDag-Erling Smørgrav 	return c;
271043840dfSDag-Erling Smørgrav }
272043840dfSDag-Erling Smørgrav 
273043840dfSDag-Erling Smørgrav /*
274511b41d2SMark Murray  * Encodes terminal modes for the terminal referenced by fd
2751e8db6e2SBrian Feldman  * or tiop in a portable manner, and appends the modes to a packet
276511b41d2SMark Murray  * being constructed.
277511b41d2SMark Murray  */
278511b41d2SMark Murray void
2791e8db6e2SBrian Feldman tty_make_modes(int fd, struct termios *tiop)
280511b41d2SMark Murray {
281511b41d2SMark Murray 	struct termios tio;
282511b41d2SMark Murray 	int baud;
2831e8db6e2SBrian Feldman 	Buffer buf;
284511b41d2SMark Murray 
2851e8db6e2SBrian Feldman 	buffer_init(&buf);
2861e8db6e2SBrian Feldman 
2871e8db6e2SBrian Feldman 	if (tiop == NULL) {
288d4af9e69SDag-Erling Smørgrav 		if (fd == -1) {
289d4af9e69SDag-Erling Smørgrav 			debug("tty_make_modes: no fd or tio");
290d4af9e69SDag-Erling Smørgrav 			goto end;
291d4af9e69SDag-Erling Smørgrav 		}
2921e8db6e2SBrian Feldman 		if (tcgetattr(fd, &tio) == -1) {
293d95e11bfSDag-Erling Smørgrav 			logit("tcgetattr: %.100s", strerror(errno));
2941e8db6e2SBrian Feldman 			goto end;
2951e8db6e2SBrian Feldman 		}
2961e8db6e2SBrian Feldman 	} else
2971e8db6e2SBrian Feldman 		tio = *tiop;
2981e8db6e2SBrian Feldman 
299511b41d2SMark Murray 	/* Store input and output baud rates. */
300511b41d2SMark Murray 	baud = speed_to_baud(cfgetospeed(&tio));
3014f52dfbbSDag-Erling Smørgrav 	buffer_put_char(&buf, TTY_OP_OSPEED);
3021e8db6e2SBrian Feldman 	buffer_put_int(&buf, baud);
303511b41d2SMark Murray 	baud = speed_to_baud(cfgetispeed(&tio));
3044f52dfbbSDag-Erling Smørgrav 	buffer_put_char(&buf, TTY_OP_ISPEED);
3051e8db6e2SBrian Feldman 	buffer_put_int(&buf, baud);
306511b41d2SMark Murray 
307511b41d2SMark Murray 	/* Store values of mode flags. */
308511b41d2SMark Murray #define TTYCHAR(NAME, OP) \
3091e8db6e2SBrian Feldman 	buffer_put_char(&buf, OP); \
3104f52dfbbSDag-Erling Smørgrav 	buffer_put_int(&buf, special_char_encode(tio.c_cc[NAME]));
3111e8db6e2SBrian Feldman 
312*47dd1d1bSDag-Erling Smørgrav #define SSH_TTYMODE_IUTF8 42  /* for SSH_BUG_UTF8TTYMODE */
313*47dd1d1bSDag-Erling Smørgrav 
314511b41d2SMark Murray #define TTYMODE(NAME, FIELD, OP) \
315*47dd1d1bSDag-Erling Smørgrav 	if (OP == SSH_TTYMODE_IUTF8 && (datafellows & SSH_BUG_UTF8TTYMODE)) { \
316*47dd1d1bSDag-Erling Smørgrav 		debug3("%s: SSH_BUG_UTF8TTYMODE", __func__); \
317*47dd1d1bSDag-Erling Smørgrav 	} else { \
3181e8db6e2SBrian Feldman 		buffer_put_char(&buf, OP); \
319*47dd1d1bSDag-Erling Smørgrav 		buffer_put_int(&buf, ((tio.FIELD & NAME) != 0)); \
320*47dd1d1bSDag-Erling Smørgrav 	}
321511b41d2SMark Murray 
322511b41d2SMark Murray #include "ttymodes.h"
323511b41d2SMark Murray 
324511b41d2SMark Murray #undef TTYCHAR
325511b41d2SMark Murray #undef TTYMODE
326511b41d2SMark Murray 
3271e8db6e2SBrian Feldman end:
328511b41d2SMark Murray 	/* Mark end of mode data. */
3291e8db6e2SBrian Feldman 	buffer_put_char(&buf, TTY_OP_END);
3301e8db6e2SBrian Feldman 	packet_put_string(buffer_ptr(&buf), buffer_len(&buf));
3311e8db6e2SBrian Feldman 	buffer_free(&buf);
332511b41d2SMark Murray }
333511b41d2SMark Murray 
334511b41d2SMark Murray /*
335511b41d2SMark Murray  * Decodes terminal modes for the terminal referenced by fd in a portable
336511b41d2SMark Murray  * manner from a packet being read.
337511b41d2SMark Murray  */
338511b41d2SMark Murray void
339511b41d2SMark Murray tty_parse_modes(int fd, int *n_bytes_ptr)
340511b41d2SMark Murray {
341511b41d2SMark Murray 	struct termios tio;
342511b41d2SMark Murray 	int opcode, baud;
343511b41d2SMark Murray 	int n_bytes = 0;
344511b41d2SMark Murray 	int failure = 0;
3451e8db6e2SBrian Feldman 
3461e8db6e2SBrian Feldman 	*n_bytes_ptr = packet_get_int();
3471e8db6e2SBrian Feldman 	if (*n_bytes_ptr == 0)
3481e8db6e2SBrian Feldman 		return;
349511b41d2SMark Murray 
350511b41d2SMark Murray 	/*
351511b41d2SMark Murray 	 * Get old attributes for the terminal.  We will modify these
352511b41d2SMark Murray 	 * flags. I am hoping that if there are any machine-specific
353511b41d2SMark Murray 	 * modes, they will initially have reasonable values.
354511b41d2SMark Murray 	 */
3551e8db6e2SBrian Feldman 	if (tcgetattr(fd, &tio) == -1) {
356d95e11bfSDag-Erling Smørgrav 		logit("tcgetattr: %.100s", strerror(errno));
357511b41d2SMark Murray 		failure = -1;
3581e8db6e2SBrian Feldman 	}
359511b41d2SMark Murray 
360511b41d2SMark Murray 	for (;;) {
361511b41d2SMark Murray 		n_bytes += 1;
362511b41d2SMark Murray 		opcode = packet_get_char();
363511b41d2SMark Murray 		switch (opcode) {
364511b41d2SMark Murray 		case TTY_OP_END:
365511b41d2SMark Murray 			goto set;
366511b41d2SMark Murray 
3674f52dfbbSDag-Erling Smørgrav 		case TTY_OP_ISPEED:
368511b41d2SMark Murray 			n_bytes += 4;
369511b41d2SMark Murray 			baud = packet_get_int();
370761efaa7SDag-Erling Smørgrav 			if (failure != -1 &&
371761efaa7SDag-Erling Smørgrav 			    cfsetispeed(&tio, baud_to_speed(baud)) == -1)
372511b41d2SMark Murray 				error("cfsetispeed failed for %d", baud);
373511b41d2SMark Murray 			break;
374511b41d2SMark Murray 
3754f52dfbbSDag-Erling Smørgrav 		case TTY_OP_OSPEED:
376511b41d2SMark Murray 			n_bytes += 4;
377511b41d2SMark Murray 			baud = packet_get_int();
378761efaa7SDag-Erling Smørgrav 			if (failure != -1 &&
379761efaa7SDag-Erling Smørgrav 			    cfsetospeed(&tio, baud_to_speed(baud)) == -1)
380511b41d2SMark Murray 				error("cfsetospeed failed for %d", baud);
381511b41d2SMark Murray 			break;
382511b41d2SMark Murray 
383511b41d2SMark Murray #define TTYCHAR(NAME, OP) \
384511b41d2SMark Murray 	case OP: \
3854f52dfbbSDag-Erling Smørgrav 	  n_bytes += 4; \
3864f52dfbbSDag-Erling Smørgrav 	  tio.c_cc[NAME] = special_char_decode(packet_get_int()); \
387511b41d2SMark Murray 	  break;
388511b41d2SMark Murray #define TTYMODE(NAME, FIELD, OP) \
389511b41d2SMark Murray 	case OP: \
3904f52dfbbSDag-Erling Smørgrav 	  n_bytes += 4; \
3914f52dfbbSDag-Erling Smørgrav 	  if (packet_get_int()) \
392511b41d2SMark Murray 	    tio.FIELD |= NAME; \
393511b41d2SMark Murray 	  else \
394511b41d2SMark Murray 	    tio.FIELD &= ~NAME;	\
395511b41d2SMark Murray 	  break;
396511b41d2SMark Murray 
397511b41d2SMark Murray #include "ttymodes.h"
398511b41d2SMark Murray 
399511b41d2SMark Murray #undef TTYCHAR
400511b41d2SMark Murray #undef TTYMODE
401511b41d2SMark Murray 
402511b41d2SMark Murray 		default:
403511b41d2SMark Murray 			debug("Ignoring unsupported tty mode opcode %d (0x%x)",
404511b41d2SMark Murray 			    opcode, opcode);
4051e8db6e2SBrian Feldman 			/*
4061e8db6e2SBrian Feldman 			 * SSH2:
4074f52dfbbSDag-Erling Smørgrav 			 * Opcodes 1 to 159 are defined to have a uint32
4084f52dfbbSDag-Erling Smørgrav 			 * argument.
4094f52dfbbSDag-Erling Smørgrav 			 * Opcodes 160 to 255 are undefined and cause parsing
4104f52dfbbSDag-Erling Smørgrav 			 * to stop.
4111e8db6e2SBrian Feldman 			 */
4121e8db6e2SBrian Feldman 			if (opcode > 0 && opcode < 160) {
4131e8db6e2SBrian Feldman 				n_bytes += 4;
4141e8db6e2SBrian Feldman 				(void) packet_get_int();
4151e8db6e2SBrian Feldman 				break;
4161e8db6e2SBrian Feldman 			} else {
417761efaa7SDag-Erling Smørgrav 				logit("parse_tty_modes: unknown opcode %d",
418761efaa7SDag-Erling Smørgrav 				    opcode);
4191e8db6e2SBrian Feldman 				goto set;
4201e8db6e2SBrian Feldman 			}
4211e8db6e2SBrian Feldman 		}
4221e8db6e2SBrian Feldman 	}
423511b41d2SMark Murray 
424511b41d2SMark Murray set:
425511b41d2SMark Murray 	if (*n_bytes_ptr != n_bytes) {
426511b41d2SMark Murray 		*n_bytes_ptr = n_bytes;
427d95e11bfSDag-Erling Smørgrav 		logit("parse_tty_modes: n_bytes_ptr != n_bytes: %d %d",
4281e8db6e2SBrian Feldman 		    *n_bytes_ptr, n_bytes);
429511b41d2SMark Murray 		return;		/* Don't process bytes passed */
430511b41d2SMark Murray 	}
431511b41d2SMark Murray 	if (failure == -1)
4321e8db6e2SBrian Feldman 		return;		/* Packet parsed ok but tcgetattr() failed */
433511b41d2SMark Murray 
434511b41d2SMark Murray 	/* Set the new modes for the terminal. */
4351e8db6e2SBrian Feldman 	if (tcsetattr(fd, TCSANOW, &tio) == -1)
436d95e11bfSDag-Erling Smørgrav 		logit("Setting tty modes failed: %.100s", strerror(errno));
437511b41d2SMark Murray }
438