1511b41d2SMark Murray /* 2511b41d2SMark Murray * Author: Tatu Ylonen <ylo@cs.hut.fi> 3511b41d2SMark Murray * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4511b41d2SMark Murray * All rights reserved 5b66f2d16SKris Kennaway * 6b66f2d16SKris Kennaway * As far as I am concerned, the code I have written for this software 7b66f2d16SKris Kennaway * can be used freely for any purpose. Any derived versions of this 8b66f2d16SKris Kennaway * software must be clearly marked as such, and if the derived work is 9b66f2d16SKris Kennaway * incompatible with the protocol description in the RFC file, it must be 10b66f2d16SKris Kennaway * called by a name other than "ssh" or "Secure Shell". 11511b41d2SMark Murray */ 12511b41d2SMark Murray 131e8db6e2SBrian Feldman /* 141e8db6e2SBrian Feldman * SSH2 tty modes support by Kevin Steves. 151e8db6e2SBrian Feldman * Copyright (c) 2001 Kevin Steves. All rights reserved. 161e8db6e2SBrian Feldman * 171e8db6e2SBrian Feldman * Redistribution and use in source and binary forms, with or without 181e8db6e2SBrian Feldman * modification, are permitted provided that the following conditions 191e8db6e2SBrian Feldman * are met: 201e8db6e2SBrian Feldman * 1. Redistributions of source code must retain the above copyright 211e8db6e2SBrian Feldman * notice, this list of conditions and the following disclaimer. 221e8db6e2SBrian Feldman * 2. Redistributions in binary form must reproduce the above copyright 231e8db6e2SBrian Feldman * notice, this list of conditions and the following disclaimer in the 241e8db6e2SBrian Feldman * documentation and/or other materials provided with the distribution. 251e8db6e2SBrian Feldman * 261e8db6e2SBrian Feldman * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 271e8db6e2SBrian Feldman * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 281e8db6e2SBrian Feldman * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 291e8db6e2SBrian Feldman * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 301e8db6e2SBrian Feldman * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 311e8db6e2SBrian Feldman * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 321e8db6e2SBrian Feldman * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 331e8db6e2SBrian Feldman * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 341e8db6e2SBrian Feldman * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 351e8db6e2SBrian Feldman * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 361e8db6e2SBrian Feldman */ 371e8db6e2SBrian Feldman 381e8db6e2SBrian Feldman /* 391e8db6e2SBrian Feldman * Encoding and decoding of terminal modes in a portable way. 401e8db6e2SBrian Feldman * Much of the format is defined in ttymodes.h; it is included multiple times 411e8db6e2SBrian Feldman * into this file with the appropriate macro definitions to generate the 421e8db6e2SBrian Feldman * suitable code. 431e8db6e2SBrian Feldman */ 441e8db6e2SBrian Feldman 45511b41d2SMark Murray #include "includes.h" 46d95e11bfSDag-Erling Smørgrav RCSID("$OpenBSD: ttymodes.c,v 1.19 2003/04/08 20:21:29 itojun Exp $"); 47511b41d2SMark Murray 48511b41d2SMark Murray #include "packet.h" 491e8db6e2SBrian Feldman #include "log.h" 501e8db6e2SBrian Feldman #include "ssh1.h" 511e8db6e2SBrian Feldman #include "compat.h" 521e8db6e2SBrian Feldman #include "buffer.h" 531e8db6e2SBrian Feldman #include "bufaux.h" 54511b41d2SMark Murray 55511b41d2SMark Murray #define TTY_OP_END 0 561e8db6e2SBrian Feldman /* 571e8db6e2SBrian Feldman * uint32 (u_int) follows speed in SSH1 and SSH2 581e8db6e2SBrian Feldman */ 591e8db6e2SBrian Feldman #define TTY_OP_ISPEED_PROTO1 192 601e8db6e2SBrian Feldman #define TTY_OP_OSPEED_PROTO1 193 611e8db6e2SBrian Feldman #define TTY_OP_ISPEED_PROTO2 128 621e8db6e2SBrian Feldman #define TTY_OP_OSPEED_PROTO2 129 63511b41d2SMark Murray 64511b41d2SMark Murray /* 65511b41d2SMark Murray * Converts POSIX speed_t to a baud rate. The values of the 66511b41d2SMark Murray * constants for speed_t are not themselves portable. 67511b41d2SMark Murray */ 68511b41d2SMark Murray static int 69511b41d2SMark Murray speed_to_baud(speed_t speed) 70511b41d2SMark Murray { 71511b41d2SMark Murray switch (speed) { 72511b41d2SMark Murray case B0: 73511b41d2SMark Murray return 0; 74511b41d2SMark Murray case B50: 75511b41d2SMark Murray return 50; 76511b41d2SMark Murray case B75: 77511b41d2SMark Murray return 75; 78511b41d2SMark Murray case B110: 79511b41d2SMark Murray return 110; 80511b41d2SMark Murray case B134: 81511b41d2SMark Murray return 134; 82511b41d2SMark Murray case B150: 83511b41d2SMark Murray return 150; 84511b41d2SMark Murray case B200: 85511b41d2SMark Murray return 200; 86511b41d2SMark Murray case B300: 87511b41d2SMark Murray return 300; 88511b41d2SMark Murray case B600: 89511b41d2SMark Murray return 600; 90511b41d2SMark Murray case B1200: 91511b41d2SMark Murray return 1200; 92511b41d2SMark Murray case B1800: 93511b41d2SMark Murray return 1800; 94511b41d2SMark Murray case B2400: 95511b41d2SMark Murray return 2400; 96511b41d2SMark Murray case B4800: 97511b41d2SMark Murray return 4800; 98511b41d2SMark Murray case B9600: 99511b41d2SMark Murray return 9600; 100511b41d2SMark Murray 101511b41d2SMark Murray #ifdef B19200 102511b41d2SMark Murray case B19200: 103511b41d2SMark Murray return 19200; 104511b41d2SMark Murray #else /* B19200 */ 105511b41d2SMark Murray #ifdef EXTA 106511b41d2SMark Murray case EXTA: 107511b41d2SMark Murray return 19200; 108511b41d2SMark Murray #endif /* EXTA */ 109511b41d2SMark Murray #endif /* B19200 */ 110511b41d2SMark Murray 111511b41d2SMark Murray #ifdef B38400 112511b41d2SMark Murray case B38400: 113511b41d2SMark Murray return 38400; 114511b41d2SMark Murray #else /* B38400 */ 115511b41d2SMark Murray #ifdef EXTB 116511b41d2SMark Murray case EXTB: 117511b41d2SMark Murray return 38400; 118511b41d2SMark Murray #endif /* EXTB */ 119511b41d2SMark Murray #endif /* B38400 */ 120511b41d2SMark Murray 121511b41d2SMark Murray #ifdef B7200 122511b41d2SMark Murray case B7200: 123511b41d2SMark Murray return 7200; 124511b41d2SMark Murray #endif /* B7200 */ 125511b41d2SMark Murray #ifdef B14400 126511b41d2SMark Murray case B14400: 127511b41d2SMark Murray return 14400; 128511b41d2SMark Murray #endif /* B14400 */ 129511b41d2SMark Murray #ifdef B28800 130511b41d2SMark Murray case B28800: 131511b41d2SMark Murray return 28800; 132511b41d2SMark Murray #endif /* B28800 */ 133511b41d2SMark Murray #ifdef B57600 134511b41d2SMark Murray case B57600: 135511b41d2SMark Murray return 57600; 136511b41d2SMark Murray #endif /* B57600 */ 137511b41d2SMark Murray #ifdef B76800 138511b41d2SMark Murray case B76800: 139511b41d2SMark Murray return 76800; 140511b41d2SMark Murray #endif /* B76800 */ 141511b41d2SMark Murray #ifdef B115200 142511b41d2SMark Murray case B115200: 143511b41d2SMark Murray return 115200; 144511b41d2SMark Murray #endif /* B115200 */ 145511b41d2SMark Murray #ifdef B230400 146511b41d2SMark Murray case B230400: 147511b41d2SMark Murray return 230400; 148511b41d2SMark Murray #endif /* B230400 */ 149511b41d2SMark Murray default: 150511b41d2SMark Murray return 9600; 151511b41d2SMark Murray } 152511b41d2SMark Murray } 153511b41d2SMark Murray 154511b41d2SMark Murray /* 155511b41d2SMark Murray * Converts a numeric baud rate to a POSIX speed_t. 156511b41d2SMark Murray */ 157511b41d2SMark Murray static speed_t 158511b41d2SMark Murray baud_to_speed(int baud) 159511b41d2SMark Murray { 160511b41d2SMark Murray switch (baud) { 161511b41d2SMark Murray case 0: 162511b41d2SMark Murray return B0; 163511b41d2SMark Murray case 50: 164511b41d2SMark Murray return B50; 165511b41d2SMark Murray case 75: 166511b41d2SMark Murray return B75; 167511b41d2SMark Murray case 110: 168511b41d2SMark Murray return B110; 169511b41d2SMark Murray case 134: 170511b41d2SMark Murray return B134; 171511b41d2SMark Murray case 150: 172511b41d2SMark Murray return B150; 173511b41d2SMark Murray case 200: 174511b41d2SMark Murray return B200; 175511b41d2SMark Murray case 300: 176511b41d2SMark Murray return B300; 177511b41d2SMark Murray case 600: 178511b41d2SMark Murray return B600; 179511b41d2SMark Murray case 1200: 180511b41d2SMark Murray return B1200; 181511b41d2SMark Murray case 1800: 182511b41d2SMark Murray return B1800; 183511b41d2SMark Murray case 2400: 184511b41d2SMark Murray return B2400; 185511b41d2SMark Murray case 4800: 186511b41d2SMark Murray return B4800; 187511b41d2SMark Murray case 9600: 188511b41d2SMark Murray return B9600; 189511b41d2SMark Murray 190511b41d2SMark Murray #ifdef B19200 191511b41d2SMark Murray case 19200: 192511b41d2SMark Murray return B19200; 193511b41d2SMark Murray #else /* B19200 */ 194511b41d2SMark Murray #ifdef EXTA 195511b41d2SMark Murray case 19200: 196511b41d2SMark Murray return EXTA; 197511b41d2SMark Murray #endif /* EXTA */ 198511b41d2SMark Murray #endif /* B19200 */ 199511b41d2SMark Murray 200511b41d2SMark Murray #ifdef B38400 201511b41d2SMark Murray case 38400: 202511b41d2SMark Murray return B38400; 203511b41d2SMark Murray #else /* B38400 */ 204511b41d2SMark Murray #ifdef EXTB 205511b41d2SMark Murray case 38400: 206511b41d2SMark Murray return EXTB; 207511b41d2SMark Murray #endif /* EXTB */ 208511b41d2SMark Murray #endif /* B38400 */ 209511b41d2SMark Murray 210511b41d2SMark Murray #ifdef B7200 211511b41d2SMark Murray case 7200: 212511b41d2SMark Murray return B7200; 213511b41d2SMark Murray #endif /* B7200 */ 214511b41d2SMark Murray #ifdef B14400 215511b41d2SMark Murray case 14400: 216511b41d2SMark Murray return B14400; 217511b41d2SMark Murray #endif /* B14400 */ 218511b41d2SMark Murray #ifdef B28800 219511b41d2SMark Murray case 28800: 220511b41d2SMark Murray return B28800; 221511b41d2SMark Murray #endif /* B28800 */ 222511b41d2SMark Murray #ifdef B57600 223511b41d2SMark Murray case 57600: 224511b41d2SMark Murray return B57600; 225511b41d2SMark Murray #endif /* B57600 */ 226511b41d2SMark Murray #ifdef B76800 227511b41d2SMark Murray case 76800: 228511b41d2SMark Murray return B76800; 229511b41d2SMark Murray #endif /* B76800 */ 230511b41d2SMark Murray #ifdef B115200 231511b41d2SMark Murray case 115200: 232511b41d2SMark Murray return B115200; 233511b41d2SMark Murray #endif /* B115200 */ 234511b41d2SMark Murray #ifdef B230400 235511b41d2SMark Murray case 230400: 236511b41d2SMark Murray return B230400; 237511b41d2SMark Murray #endif /* B230400 */ 238511b41d2SMark Murray default: 239511b41d2SMark Murray return B9600; 240511b41d2SMark Murray } 241511b41d2SMark Murray } 242511b41d2SMark Murray 243511b41d2SMark Murray /* 244511b41d2SMark Murray * Encodes terminal modes for the terminal referenced by fd 2451e8db6e2SBrian Feldman * or tiop in a portable manner, and appends the modes to a packet 246511b41d2SMark Murray * being constructed. 247511b41d2SMark Murray */ 248511b41d2SMark Murray void 2491e8db6e2SBrian Feldman tty_make_modes(int fd, struct termios *tiop) 250511b41d2SMark Murray { 251511b41d2SMark Murray struct termios tio; 252511b41d2SMark Murray int baud; 2531e8db6e2SBrian Feldman Buffer buf; 2541e8db6e2SBrian Feldman int tty_op_ospeed, tty_op_ispeed; 2551e8db6e2SBrian Feldman void (*put_arg)(Buffer *, u_int); 256511b41d2SMark Murray 2571e8db6e2SBrian Feldman buffer_init(&buf); 2581e8db6e2SBrian Feldman if (compat20) { 2591e8db6e2SBrian Feldman tty_op_ospeed = TTY_OP_OSPEED_PROTO2; 2601e8db6e2SBrian Feldman tty_op_ispeed = TTY_OP_ISPEED_PROTO2; 2611e8db6e2SBrian Feldman put_arg = buffer_put_int; 2621e8db6e2SBrian Feldman } else { 2631e8db6e2SBrian Feldman tty_op_ospeed = TTY_OP_OSPEED_PROTO1; 2641e8db6e2SBrian Feldman tty_op_ispeed = TTY_OP_ISPEED_PROTO1; 2651e8db6e2SBrian Feldman put_arg = (void (*)(Buffer *, u_int)) buffer_put_char; 266511b41d2SMark Murray } 2671e8db6e2SBrian Feldman 2681e8db6e2SBrian Feldman if (tiop == NULL) { 2691e8db6e2SBrian Feldman if (tcgetattr(fd, &tio) == -1) { 270d95e11bfSDag-Erling Smørgrav logit("tcgetattr: %.100s", strerror(errno)); 2711e8db6e2SBrian Feldman goto end; 2721e8db6e2SBrian Feldman } 2731e8db6e2SBrian Feldman } else 2741e8db6e2SBrian Feldman tio = *tiop; 2751e8db6e2SBrian Feldman 276511b41d2SMark Murray /* Store input and output baud rates. */ 277511b41d2SMark Murray baud = speed_to_baud(cfgetospeed(&tio)); 278ae1f160dSDag-Erling Smørgrav debug3("tty_make_modes: ospeed %d", baud); 2791e8db6e2SBrian Feldman buffer_put_char(&buf, tty_op_ospeed); 2801e8db6e2SBrian Feldman buffer_put_int(&buf, baud); 281511b41d2SMark Murray baud = speed_to_baud(cfgetispeed(&tio)); 282ae1f160dSDag-Erling Smørgrav debug3("tty_make_modes: ispeed %d", baud); 2831e8db6e2SBrian Feldman buffer_put_char(&buf, tty_op_ispeed); 2841e8db6e2SBrian Feldman buffer_put_int(&buf, baud); 285511b41d2SMark Murray 286511b41d2SMark Murray /* Store values of mode flags. */ 287511b41d2SMark Murray #define TTYCHAR(NAME, OP) \ 288ae1f160dSDag-Erling Smørgrav debug3("tty_make_modes: %d %d", OP, tio.c_cc[NAME]); \ 2891e8db6e2SBrian Feldman buffer_put_char(&buf, OP); \ 2901e8db6e2SBrian Feldman put_arg(&buf, tio.c_cc[NAME]); 2911e8db6e2SBrian Feldman 292511b41d2SMark Murray #define TTYMODE(NAME, FIELD, OP) \ 293ae1f160dSDag-Erling Smørgrav debug3("tty_make_modes: %d %d", OP, ((tio.FIELD & NAME) != 0)); \ 2941e8db6e2SBrian Feldman buffer_put_char(&buf, OP); \ 2951e8db6e2SBrian Feldman put_arg(&buf, ((tio.FIELD & NAME) != 0)); 296511b41d2SMark Murray 297511b41d2SMark Murray #include "ttymodes.h" 298511b41d2SMark Murray 299511b41d2SMark Murray #undef TTYCHAR 300511b41d2SMark Murray #undef TTYMODE 301511b41d2SMark Murray 3021e8db6e2SBrian Feldman end: 303511b41d2SMark Murray /* Mark end of mode data. */ 3041e8db6e2SBrian Feldman buffer_put_char(&buf, TTY_OP_END); 3051e8db6e2SBrian Feldman if (compat20) 3061e8db6e2SBrian Feldman packet_put_string(buffer_ptr(&buf), buffer_len(&buf)); 3071e8db6e2SBrian Feldman else 3081e8db6e2SBrian Feldman packet_put_raw(buffer_ptr(&buf), buffer_len(&buf)); 3091e8db6e2SBrian Feldman buffer_free(&buf); 310511b41d2SMark Murray } 311511b41d2SMark Murray 312511b41d2SMark Murray /* 313511b41d2SMark Murray * Decodes terminal modes for the terminal referenced by fd in a portable 314511b41d2SMark Murray * manner from a packet being read. 315511b41d2SMark Murray */ 316511b41d2SMark Murray void 317511b41d2SMark Murray tty_parse_modes(int fd, int *n_bytes_ptr) 318511b41d2SMark Murray { 319511b41d2SMark Murray struct termios tio; 320511b41d2SMark Murray int opcode, baud; 321511b41d2SMark Murray int n_bytes = 0; 322511b41d2SMark Murray int failure = 0; 3231e8db6e2SBrian Feldman u_int (*get_arg)(void); 3241e8db6e2SBrian Feldman int arg, arg_size; 3251e8db6e2SBrian Feldman 3261e8db6e2SBrian Feldman if (compat20) { 3271e8db6e2SBrian Feldman *n_bytes_ptr = packet_get_int(); 328ae1f160dSDag-Erling Smørgrav debug3("tty_parse_modes: SSH2 n_bytes %d", *n_bytes_ptr); 3291e8db6e2SBrian Feldman if (*n_bytes_ptr == 0) 3301e8db6e2SBrian Feldman return; 3311e8db6e2SBrian Feldman get_arg = packet_get_int; 3321e8db6e2SBrian Feldman arg_size = 4; 3331e8db6e2SBrian Feldman } else { 3341e8db6e2SBrian Feldman get_arg = packet_get_char; 3351e8db6e2SBrian Feldman arg_size = 1; 3361e8db6e2SBrian Feldman } 337511b41d2SMark Murray 338511b41d2SMark Murray /* 339511b41d2SMark Murray * Get old attributes for the terminal. We will modify these 340511b41d2SMark Murray * flags. I am hoping that if there are any machine-specific 341511b41d2SMark Murray * modes, they will initially have reasonable values. 342511b41d2SMark Murray */ 3431e8db6e2SBrian Feldman if (tcgetattr(fd, &tio) == -1) { 344d95e11bfSDag-Erling Smørgrav logit("tcgetattr: %.100s", strerror(errno)); 345511b41d2SMark Murray failure = -1; 3461e8db6e2SBrian Feldman } 347511b41d2SMark Murray 348511b41d2SMark Murray for (;;) { 349511b41d2SMark Murray n_bytes += 1; 350511b41d2SMark Murray opcode = packet_get_char(); 351511b41d2SMark Murray switch (opcode) { 352511b41d2SMark Murray case TTY_OP_END: 353511b41d2SMark Murray goto set; 354511b41d2SMark Murray 3551e8db6e2SBrian Feldman /* XXX: future conflict possible */ 3561e8db6e2SBrian Feldman case TTY_OP_ISPEED_PROTO1: 3571e8db6e2SBrian Feldman case TTY_OP_ISPEED_PROTO2: 358511b41d2SMark Murray n_bytes += 4; 359511b41d2SMark Murray baud = packet_get_int(); 360ae1f160dSDag-Erling Smørgrav debug3("tty_parse_modes: ispeed %d", baud); 3611e8db6e2SBrian Feldman if (failure != -1 && cfsetispeed(&tio, baud_to_speed(baud)) == -1) 362511b41d2SMark Murray error("cfsetispeed failed for %d", baud); 363511b41d2SMark Murray break; 364511b41d2SMark Murray 3651e8db6e2SBrian Feldman /* XXX: future conflict possible */ 3661e8db6e2SBrian Feldman case TTY_OP_OSPEED_PROTO1: 3671e8db6e2SBrian Feldman case TTY_OP_OSPEED_PROTO2: 368511b41d2SMark Murray n_bytes += 4; 369511b41d2SMark Murray baud = packet_get_int(); 370ae1f160dSDag-Erling Smørgrav debug3("tty_parse_modes: ospeed %d", baud); 3711e8db6e2SBrian Feldman if (failure != -1 && cfsetospeed(&tio, baud_to_speed(baud)) == -1) 372511b41d2SMark Murray error("cfsetospeed failed for %d", baud); 373511b41d2SMark Murray break; 374511b41d2SMark Murray 375511b41d2SMark Murray #define TTYCHAR(NAME, OP) \ 376511b41d2SMark Murray case OP: \ 3771e8db6e2SBrian Feldman n_bytes += arg_size; \ 3781e8db6e2SBrian Feldman tio.c_cc[NAME] = get_arg(); \ 379ae1f160dSDag-Erling Smørgrav debug3("tty_parse_modes: %d %d", OP, tio.c_cc[NAME]); \ 380511b41d2SMark Murray break; 381511b41d2SMark Murray #define TTYMODE(NAME, FIELD, OP) \ 382511b41d2SMark Murray case OP: \ 3831e8db6e2SBrian Feldman n_bytes += arg_size; \ 3841e8db6e2SBrian Feldman if ((arg = get_arg())) \ 385511b41d2SMark Murray tio.FIELD |= NAME; \ 386511b41d2SMark Murray else \ 387511b41d2SMark Murray tio.FIELD &= ~NAME; \ 388ae1f160dSDag-Erling Smørgrav debug3("tty_parse_modes: %d %d", OP, arg); \ 389511b41d2SMark Murray break; 390511b41d2SMark Murray 391511b41d2SMark Murray #include "ttymodes.h" 392511b41d2SMark Murray 393511b41d2SMark Murray #undef TTYCHAR 394511b41d2SMark Murray #undef TTYMODE 395511b41d2SMark Murray 396511b41d2SMark Murray default: 397511b41d2SMark Murray debug("Ignoring unsupported tty mode opcode %d (0x%x)", 398511b41d2SMark Murray opcode, opcode); 3991e8db6e2SBrian Feldman if (!compat20) { 400511b41d2SMark Murray /* 4011e8db6e2SBrian Feldman * SSH1: 4021e8db6e2SBrian Feldman * Opcodes 1 to 127 are defined to have 403511b41d2SMark Murray * a one-byte argument. 404511b41d2SMark Murray * Opcodes 128 to 159 are defined to have 405511b41d2SMark Murray * an integer argument. 406511b41d2SMark Murray */ 4071e8db6e2SBrian Feldman if (opcode > 0 && opcode < 128) { 4081e8db6e2SBrian Feldman n_bytes += 1; 4091e8db6e2SBrian Feldman (void) packet_get_char(); 4101e8db6e2SBrian Feldman break; 4111e8db6e2SBrian Feldman } else if (opcode >= 128 && opcode < 160) { 412511b41d2SMark Murray n_bytes += 4; 413511b41d2SMark Murray (void) packet_get_int(); 414511b41d2SMark Murray break; 4151e8db6e2SBrian Feldman } else { 416511b41d2SMark Murray /* 417511b41d2SMark Murray * It is a truly undefined opcode (160 to 255). 418511b41d2SMark Murray * We have no idea about its arguments. So we 419511b41d2SMark Murray * must stop parsing. Note that some data may be 420511b41d2SMark Murray * left in the packet; hopefully there is nothing 421511b41d2SMark Murray * more coming after the mode data. 422511b41d2SMark Murray */ 423d95e11bfSDag-Erling Smørgrav logit("parse_tty_modes: unknown opcode %d", opcode); 424511b41d2SMark Murray goto set; 425511b41d2SMark Murray } 4261e8db6e2SBrian Feldman } else { 4271e8db6e2SBrian Feldman /* 4281e8db6e2SBrian Feldman * SSH2: 4291e8db6e2SBrian Feldman * Opcodes 1 to 159 are defined to have 4301e8db6e2SBrian Feldman * a uint32 argument. 4311e8db6e2SBrian Feldman * Opcodes 160 to 255 are undefined and 4321e8db6e2SBrian Feldman * cause parsing to stop. 4331e8db6e2SBrian Feldman */ 4341e8db6e2SBrian Feldman if (opcode > 0 && opcode < 160) { 4351e8db6e2SBrian Feldman n_bytes += 4; 4361e8db6e2SBrian Feldman (void) packet_get_int(); 4371e8db6e2SBrian Feldman break; 4381e8db6e2SBrian Feldman } else { 439d95e11bfSDag-Erling Smørgrav logit("parse_tty_modes: unknown opcode %d", opcode); 4401e8db6e2SBrian Feldman goto set; 4411e8db6e2SBrian Feldman } 4421e8db6e2SBrian Feldman } 4431e8db6e2SBrian Feldman } 444511b41d2SMark Murray } 445511b41d2SMark Murray 446511b41d2SMark Murray set: 447511b41d2SMark Murray if (*n_bytes_ptr != n_bytes) { 448511b41d2SMark Murray *n_bytes_ptr = n_bytes; 449d95e11bfSDag-Erling Smørgrav logit("parse_tty_modes: n_bytes_ptr != n_bytes: %d %d", 4501e8db6e2SBrian Feldman *n_bytes_ptr, n_bytes); 451511b41d2SMark Murray return; /* Don't process bytes passed */ 452511b41d2SMark Murray } 453511b41d2SMark Murray if (failure == -1) 4541e8db6e2SBrian Feldman return; /* Packet parsed ok but tcgetattr() failed */ 455511b41d2SMark Murray 456511b41d2SMark Murray /* Set the new modes for the terminal. */ 4571e8db6e2SBrian Feldman if (tcsetattr(fd, TCSANOW, &tio) == -1) 458d95e11bfSDag-Erling Smørgrav logit("Setting tty modes failed: %.100s", strerror(errno)); 459511b41d2SMark Murray } 460