utilities.c revision 272461
11592Srgrimes/* 21592Srgrimes * Copyright (c) 1988, 1993 31592Srgrimes * The Regents of the University of California. All rights reserved. 41592Srgrimes * 51592Srgrimes * Redistribution and use in source and binary forms, with or without 61592Srgrimes * modification, are permitted provided that the following conditions 71592Srgrimes * are met: 81592Srgrimes * 1. Redistributions of source code must retain the above copyright 91592Srgrimes * notice, this list of conditions and the following disclaimer. 101592Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111592Srgrimes * notice, this list of conditions and the following disclaimer in the 121592Srgrimes * documentation and/or other materials provided with the distribution. 131592Srgrimes * 3. All advertising materials mentioning features or use of this software 141592Srgrimes * must display the following acknowledgement: 151592Srgrimes * This product includes software developed by the University of 161592Srgrimes * California, Berkeley and its contributors. 171592Srgrimes * 4. Neither the name of the University nor the names of its contributors 181592Srgrimes * may be used to endorse or promote products derived from this software 191592Srgrimes * without specific prior written permission. 201592Srgrimes * 211592Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 221592Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 231592Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 241592Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 251592Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 261592Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 271592Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 281592Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 291592Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 301592Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 311592Srgrimes * SUCH DAMAGE. 321592Srgrimes */ 331592Srgrimes 341592Srgrimes#if 0 351592Srgrimes#ifndef lint 361592Srgrimesstatic const char sccsid[] = "@(#)utilities.c 8.3 (Berkeley) 5/30/95"; 371592Srgrimes#endif 381592Srgrimes#endif 391592Srgrimes#include <sys/cdefs.h> 401592Srgrimes__FBSDID("$FreeBSD: releng/10.1/contrib/telnet/telnet/utilities.c 228651 2011-12-17 18:18:36Z dim $"); 411592Srgrimes 421592Srgrimes#define TELOPTS 431592Srgrimes#define TELCMDS 441592Srgrimes#define SLC_NAMES 451592Srgrimes#include <arpa/telnet.h> 461592Srgrimes#include <sys/types.h> 471592Srgrimes#include <sys/socket.h> 481592Srgrimes#include <sys/time.h> 491592Srgrimes#include <ctype.h> 501592Srgrimes#include <stdlib.h> 511592Srgrimes#include <unistd.h> 521592Srgrimes 531592Srgrimes#include "general.h" 541592Srgrimes 551592Srgrimes#include "fdset.h" 561592Srgrimes 571592Srgrimes#include "ring.h" 581592Srgrimes 591592Srgrimes#include "defines.h" 601592Srgrimes 611592Srgrimes#include "externs.h" 621592Srgrimes 631592Srgrimes#ifdef AUTHENTICATION 641592Srgrimes#include <libtelnet/auth.h> 651592Srgrimes#endif 661592Srgrimes#ifdef ENCRYPTION 671592Srgrimes#include <libtelnet/encrypt.h> 681592Srgrimes#endif 691592Srgrimes 701592SrgrimesFILE *NetTrace = 0; /* Not in bss, since needs to stay */ 711592Srgrimesint prettydump; 721592Srgrimes 731592Srgrimes/* 741592Srgrimes * upcase() 751592Srgrimes * 761592Srgrimes * Upcase (in place) the argument. 771592Srgrimes */ 781592Srgrimes 791592Srgrimesvoid 801592Srgrimesupcase(char *argument) 811592Srgrimes{ 821592Srgrimes int c; 831592Srgrimes 841592Srgrimes while ((c = *argument) != 0) { 851592Srgrimes if (islower(c)) { 861592Srgrimes *argument = toupper(c); 871592Srgrimes } 881592Srgrimes argument++; 891592Srgrimes } 901592Srgrimes} 911592Srgrimes 921592Srgrimes/* 931592Srgrimes * SetSockOpt() 941592Srgrimes * 951592Srgrimes * Compensate for differences in 4.2 and 4.3 systems. 961592Srgrimes */ 971592Srgrimes 981592Srgrimesint 991592SrgrimesSetSockOpt(int fd, int level, int option, int yesno) 1001592Srgrimes{ 1011592Srgrimes return setsockopt(fd, level, option, 1021592Srgrimes (char *)&yesno, sizeof yesno); 1031592Srgrimes} 1041592Srgrimes 1051592Srgrimes/* 1061592Srgrimes * The following are routines used to print out debugging information. 1071592Srgrimes */ 1081592Srgrimes 1091592Srgrimesunsigned char NetTraceFile[256] = "(standard output)"; 1101592Srgrimes 1111592Srgrimesvoid 1121592SrgrimesSetNetTrace(char *file) 1131592Srgrimes{ 1141592Srgrimes if (NetTrace && NetTrace != stdout) 1151592Srgrimes fclose(NetTrace); 1161592Srgrimes if (file && (strcmp(file, "-") != 0)) { 1171592Srgrimes NetTrace = fopen(file, "w"); 1181592Srgrimes if (NetTrace) { 1191592Srgrimes strcpy((char *)NetTraceFile, file); 1201592Srgrimes return; 1211592Srgrimes } 1221592Srgrimes fprintf(stderr, "Cannot open %s.\n", file); 1231592Srgrimes } 1241592Srgrimes NetTrace = stdout; 1251592Srgrimes strcpy((char *)NetTraceFile, "(standard output)"); 1261592Srgrimes} 1271592Srgrimes 1281592Srgrimesvoid 1291592SrgrimesDump(char direction, unsigned char *buffer, int length) 1301592Srgrimes{ 1311592Srgrimes# define BYTES_PER_LINE 32 1321592Srgrimes# define min(x,y) ((x<y)? x:y) 1331592Srgrimes unsigned char *pThis; 1341592Srgrimes int offset; 1351592Srgrimes 1361592Srgrimes offset = 0; 1371592Srgrimes 1381592Srgrimes while (length) { 1391592Srgrimes /* print one line */ 1401592Srgrimes fprintf(NetTrace, "%c 0x%x\t", direction, offset); 1411592Srgrimes pThis = buffer; 1421592Srgrimes if (prettydump) { 1431592Srgrimes buffer = buffer + min(length, BYTES_PER_LINE/2); 1441592Srgrimes while (pThis < buffer) { 1451592Srgrimes fprintf(NetTrace, "%c%.2x", 1461592Srgrimes (((*pThis)&0xff) == 0xff) ? '*' : ' ', 1471592Srgrimes (*pThis)&0xff); 1481592Srgrimes pThis++; 1491592Srgrimes } 1501592Srgrimes length -= BYTES_PER_LINE/2; 1511592Srgrimes offset += BYTES_PER_LINE/2; 1521592Srgrimes } else { 1531592Srgrimes buffer = buffer + min(length, BYTES_PER_LINE); 1541592Srgrimes while (pThis < buffer) { 1551592Srgrimes fprintf(NetTrace, "%.2x", (*pThis)&0xff); 1561592Srgrimes pThis++; 1571592Srgrimes } 1581592Srgrimes length -= BYTES_PER_LINE; 1591592Srgrimes offset += BYTES_PER_LINE; 1601592Srgrimes } 1611592Srgrimes if (NetTrace == stdout) { 1621592Srgrimes fprintf(NetTrace, "\r\n"); 1631592Srgrimes } else { 1641592Srgrimes fprintf(NetTrace, "\n"); 1651592Srgrimes } 1661592Srgrimes if (length < 0) { 1671592Srgrimes fflush(NetTrace); 1681592Srgrimes return; 1691592Srgrimes } 1701592Srgrimes /* find next unique line */ 1711592Srgrimes } 1721592Srgrimes fflush(NetTrace); 1731592Srgrimes} 1741592Srgrimes 1751592Srgrimes 1761592Srgrimesvoid 1771592Srgrimesprintoption(const char *direction, int cmd, int option) 1781592Srgrimes{ 1791592Srgrimes if (!showoptions) 1801592Srgrimes return; 1811592Srgrimes if (cmd == IAC) { 1821592Srgrimes if (TELCMD_OK(option)) 1831592Srgrimes fprintf(NetTrace, "%s IAC %s", direction, TELCMD(option)); 1841592Srgrimes else 1851592Srgrimes fprintf(NetTrace, "%s IAC %d", direction, option); 1861592Srgrimes } else { 1871592Srgrimes const char *fmt; 1881592Srgrimes fmt = (cmd == WILL) ? "WILL" : (cmd == WONT) ? "WONT" : 1891592Srgrimes (cmd == DO) ? "DO" : (cmd == DONT) ? "DONT" : 0; 1901592Srgrimes if (fmt) { 1911592Srgrimes fprintf(NetTrace, "%s %s ", direction, fmt); 1921592Srgrimes if (TELOPT_OK(option)) 1931592Srgrimes fprintf(NetTrace, "%s", TELOPT(option)); 1941592Srgrimes else if (option == TELOPT_EXOPL) 1951592Srgrimes fprintf(NetTrace, "EXOPL"); 1961592Srgrimes else 1971592Srgrimes fprintf(NetTrace, "%d", option); 1981592Srgrimes } else 1991592Srgrimes fprintf(NetTrace, "%s %d %d", direction, cmd, option); 2001592Srgrimes } 2011592Srgrimes if (NetTrace == stdout) { 2021592Srgrimes fprintf(NetTrace, "\r\n"); 2031592Srgrimes fflush(NetTrace); 2041592Srgrimes } else { 2051592Srgrimes fprintf(NetTrace, "\n"); 2061592Srgrimes } 2071592Srgrimes return; 2081592Srgrimes} 2091592Srgrimes 2101592Srgrimesvoid 2111592Srgrimesoptionstatus(void) 2121592Srgrimes{ 2131592Srgrimes int i; 2141592Srgrimes extern char will_wont_resp[], do_dont_resp[]; 2151592Srgrimes 2161592Srgrimes for (i = 0; i < 256; i++) { 2171592Srgrimes if (do_dont_resp[i]) { 2181592Srgrimes if (TELOPT_OK(i)) 2191592Srgrimes printf("resp DO_DONT %s: %d\n", TELOPT(i), do_dont_resp[i]); 2201592Srgrimes else if (TELCMD_OK(i)) 2211592Srgrimes printf("resp DO_DONT %s: %d\n", TELCMD(i), do_dont_resp[i]); 2221592Srgrimes else 2231592Srgrimes printf("resp DO_DONT %d: %d\n", i, 2241592Srgrimes do_dont_resp[i]); 2251592Srgrimes if (my_want_state_is_do(i)) { 2261592Srgrimes if (TELOPT_OK(i)) 2271592Srgrimes printf("want DO %s\n", TELOPT(i)); 2281592Srgrimes else if (TELCMD_OK(i)) 2291592Srgrimes printf("want DO %s\n", TELCMD(i)); 2301592Srgrimes else 2311592Srgrimes printf("want DO %d\n", i); 2321592Srgrimes } else { 2331592Srgrimes if (TELOPT_OK(i)) 2341592Srgrimes printf("want DONT %s\n", TELOPT(i)); 2351592Srgrimes else if (TELCMD_OK(i)) 2361592Srgrimes printf("want DONT %s\n", TELCMD(i)); 2371592Srgrimes else 2381592Srgrimes printf("want DONT %d\n", i); 2391592Srgrimes } 2401592Srgrimes } else { 2411592Srgrimes if (my_state_is_do(i)) { 2421592Srgrimes if (TELOPT_OK(i)) 2431592Srgrimes printf(" DO %s\n", TELOPT(i)); 2441592Srgrimes else if (TELCMD_OK(i)) 2451592Srgrimes printf(" DO %s\n", TELCMD(i)); 2461592Srgrimes else 2471592Srgrimes printf(" DO %d\n", i); 2481592Srgrimes } 2491592Srgrimes } 2501592Srgrimes if (will_wont_resp[i]) { 2511592Srgrimes if (TELOPT_OK(i)) 2521592Srgrimes printf("resp WILL_WONT %s: %d\n", TELOPT(i), will_wont_resp[i]); 2531592Srgrimes else if (TELCMD_OK(i)) 2541592Srgrimes printf("resp WILL_WONT %s: %d\n", TELCMD(i), will_wont_resp[i]); 2551592Srgrimes else 2561592Srgrimes printf("resp WILL_WONT %d: %d\n", 2571592Srgrimes i, will_wont_resp[i]); 2581592Srgrimes if (my_want_state_is_will(i)) { 2591592Srgrimes if (TELOPT_OK(i)) 2601592Srgrimes printf("want WILL %s\n", TELOPT(i)); 2611592Srgrimes else if (TELCMD_OK(i)) 2621592Srgrimes printf("want WILL %s\n", TELCMD(i)); 2631592Srgrimes else 2641592Srgrimes printf("want WILL %d\n", i); 2651592Srgrimes } else { 2661592Srgrimes if (TELOPT_OK(i)) 2671592Srgrimes printf("want WONT %s\n", TELOPT(i)); 2681592Srgrimes else if (TELCMD_OK(i)) 2691592Srgrimes printf("want WONT %s\n", TELCMD(i)); 2701592Srgrimes else 2711592Srgrimes printf("want WONT %d\n", i); 2721592Srgrimes } 2731592Srgrimes } else { 2741592Srgrimes if (my_state_is_will(i)) { 2751592Srgrimes if (TELOPT_OK(i)) 2761592Srgrimes printf(" WILL %s\n", TELOPT(i)); 2771592Srgrimes else if (TELCMD_OK(i)) 2781592Srgrimes printf(" WILL %s\n", TELCMD(i)); 2791592Srgrimes else 2801592Srgrimes printf(" WILL %d\n", i); 2811592Srgrimes } 2821592Srgrimes } 2831592Srgrimes } 2841592Srgrimes 2851592Srgrimes} 2861592Srgrimes 2871592Srgrimesvoid 2881592Srgrimesprintsub(char direction, unsigned char *pointer, int length) 2891592Srgrimes{ 2901592Srgrimes int i; 2911592Srgrimes#ifdef AUTHENTICATION 2921592Srgrimes char buf[512]; 2931592Srgrimes#endif 2941592Srgrimes extern int want_status_response; 2951592Srgrimes 2961592Srgrimes if (showoptions || direction == 0 || 2971592Srgrimes (want_status_response && (pointer[0] == TELOPT_STATUS))) { 2981592Srgrimes if (direction) { 2991592Srgrimes fprintf(NetTrace, "%s IAC SB ", 3001592Srgrimes (direction == '<')? "RCVD":"SENT"); 3011592Srgrimes if (length >= 3) { 3021592Srgrimes int j; 3031592Srgrimes 3041592Srgrimes i = pointer[length-2]; 3051592Srgrimes j = pointer[length-1]; 3061592Srgrimes 3071592Srgrimes if (i != IAC || j != SE) { 3081592Srgrimes fprintf(NetTrace, "(terminated by "); 3091592Srgrimes if (TELOPT_OK(i)) 3101592Srgrimes fprintf(NetTrace, "%s ", TELOPT(i)); 3111592Srgrimes else if (TELCMD_OK(i)) 3121592Srgrimes fprintf(NetTrace, "%s ", TELCMD(i)); 3131592Srgrimes else 3141592Srgrimes fprintf(NetTrace, "%d ", i); 3151592Srgrimes if (TELOPT_OK(j)) 3161592Srgrimes fprintf(NetTrace, "%s", TELOPT(j)); 3171592Srgrimes else if (TELCMD_OK(j)) 3181592Srgrimes fprintf(NetTrace, "%s", TELCMD(j)); 3191592Srgrimes else 3201592Srgrimes fprintf(NetTrace, "%d", j); 3211592Srgrimes fprintf(NetTrace, ", not IAC SE!) "); 3221592Srgrimes } 3231592Srgrimes } 3241592Srgrimes length -= 2; 3251592Srgrimes } 3261592Srgrimes if (length < 1) { 3271592Srgrimes fprintf(NetTrace, "(Empty suboption??\?)"); 3281592Srgrimes if (NetTrace == stdout) 3291592Srgrimes fflush(NetTrace); 3301592Srgrimes return; 3311592Srgrimes } 3321592Srgrimes switch (pointer[0]) { 3331592Srgrimes case TELOPT_TTYPE: 3341592Srgrimes fprintf(NetTrace, "TERMINAL-TYPE "); 3351592Srgrimes switch (pointer[1]) { 3361592Srgrimes case TELQUAL_IS: 3371592Srgrimes fprintf(NetTrace, "IS \"%.*s\"", length-2, (char *)pointer+2); 3381592Srgrimes break; 3391592Srgrimes case TELQUAL_SEND: 3401592Srgrimes fprintf(NetTrace, "SEND"); 3411592Srgrimes break; 3421592Srgrimes default: 3431592Srgrimes fprintf(NetTrace, 3441592Srgrimes "- unknown qualifier %d (0x%x).", 3451592Srgrimes pointer[1], pointer[1]); 3461592Srgrimes } 3471592Srgrimes break; 3481592Srgrimes case TELOPT_TSPEED: 3491592Srgrimes fprintf(NetTrace, "TERMINAL-SPEED"); 3501592Srgrimes if (length < 2) { 3511592Srgrimes fprintf(NetTrace, " (empty suboption??\?)"); 3521592Srgrimes break; 3531592Srgrimes } 3541592Srgrimes switch (pointer[1]) { 3551592Srgrimes case TELQUAL_IS: 3561592Srgrimes fprintf(NetTrace, " IS "); 3571592Srgrimes fprintf(NetTrace, "%.*s", length-2, (char *)pointer+2); 3581592Srgrimes break; 3591592Srgrimes default: 3601592Srgrimes if (pointer[1] == 1) 3611592Srgrimes fprintf(NetTrace, " SEND"); 3621592Srgrimes else 3631592Srgrimes fprintf(NetTrace, " %d (unknown)", pointer[1]); 3641592Srgrimes for (i = 2; i < length; i++) 3651592Srgrimes fprintf(NetTrace, " ?%d?", pointer[i]); 3661592Srgrimes break; 3671592Srgrimes } 3681592Srgrimes break; 3691592Srgrimes 3701592Srgrimes case TELOPT_LFLOW: 3711592Srgrimes fprintf(NetTrace, "TOGGLE-FLOW-CONTROL"); 3721592Srgrimes if (length < 2) { 3731592Srgrimes fprintf(NetTrace, " (empty suboption??\?)"); 3741592Srgrimes break; 3751592Srgrimes } 3761592Srgrimes switch (pointer[1]) { 3771592Srgrimes case LFLOW_OFF: 3781592Srgrimes fprintf(NetTrace, " OFF"); break; 3791592Srgrimes case LFLOW_ON: 3801592Srgrimes fprintf(NetTrace, " ON"); break; 3811592Srgrimes case LFLOW_RESTART_ANY: 3821592Srgrimes fprintf(NetTrace, " RESTART-ANY"); break; 3831592Srgrimes case LFLOW_RESTART_XON: 3841592Srgrimes fprintf(NetTrace, " RESTART-XON"); break; 3851592Srgrimes default: 3861592Srgrimes fprintf(NetTrace, " %d (unknown)", pointer[1]); 3871592Srgrimes } 3881592Srgrimes for (i = 2; i < length; i++) 3891592Srgrimes fprintf(NetTrace, " ?%d?", pointer[i]); 3901592Srgrimes break; 3911592Srgrimes 3921592Srgrimes case TELOPT_NAWS: 3931592Srgrimes fprintf(NetTrace, "NAWS"); 3941592Srgrimes if (length < 2) { 3951592Srgrimes fprintf(NetTrace, " (empty suboption??\?)"); 3961592Srgrimes break; 3971592Srgrimes } 3981592Srgrimes if (length == 2) { 3991592Srgrimes fprintf(NetTrace, " ?%d?", pointer[1]); 4001592Srgrimes break; 4011592Srgrimes } 4021592Srgrimes fprintf(NetTrace, " %d %d (%d)", 4031592Srgrimes pointer[1], pointer[2], 4041592Srgrimes (int)((((unsigned int)pointer[1])<<8)|((unsigned int)pointer[2]))); 4051592Srgrimes if (length == 4) { 4061592Srgrimes fprintf(NetTrace, " ?%d?", pointer[3]); 4071592Srgrimes break; 4081592Srgrimes } 4091592Srgrimes fprintf(NetTrace, " %d %d (%d)", 4101592Srgrimes pointer[3], pointer[4], 4111592Srgrimes (int)((((unsigned int)pointer[3])<<8)|((unsigned int)pointer[4]))); 4121592Srgrimes for (i = 5; i < length; i++) 4131592Srgrimes fprintf(NetTrace, " ?%d?", pointer[i]); 4141592Srgrimes break; 4151592Srgrimes 4161592Srgrimes#ifdef AUTHENTICATION 4171592Srgrimes case TELOPT_AUTHENTICATION: 4181592Srgrimes fprintf(NetTrace, "AUTHENTICATION"); 4191592Srgrimes if (length < 2) { 4201592Srgrimes fprintf(NetTrace, " (empty suboption??\?)"); 4211592Srgrimes break; 4221592Srgrimes } 4231592Srgrimes switch (pointer[1]) { 4241592Srgrimes case TELQUAL_REPLY: 4251592Srgrimes case TELQUAL_IS: 4261592Srgrimes fprintf(NetTrace, " %s ", (pointer[1] == TELQUAL_IS) ? 4271592Srgrimes "IS" : "REPLY"); 4281592Srgrimes if (AUTHTYPE_NAME_OK(pointer[2])) 4291592Srgrimes fprintf(NetTrace, "%s ", AUTHTYPE_NAME(pointer[2])); 4301592Srgrimes else 4311592Srgrimes fprintf(NetTrace, "%d ", pointer[2]); 4321592Srgrimes if (length < 3) { 4331592Srgrimes fprintf(NetTrace, "(partial suboption??\?)"); 4341592Srgrimes break; 4351592Srgrimes } 4361592Srgrimes fprintf(NetTrace, "%s|%s", 4371592Srgrimes ((pointer[3] & AUTH_WHO_MASK) == AUTH_WHO_CLIENT) ? 4381592Srgrimes "CLIENT" : "SERVER", 4391592Srgrimes ((pointer[3] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) ? 4401592Srgrimes "MUTUAL" : "ONE-WAY"); 4411592Srgrimes 4421592Srgrimes auth_printsub(&pointer[1], length - 1, buf, sizeof(buf)); 4431592Srgrimes fprintf(NetTrace, "%s", buf); 4441592Srgrimes break; 4451592Srgrimes 4461592Srgrimes case TELQUAL_SEND: 4471592Srgrimes i = 2; 4481592Srgrimes fprintf(NetTrace, " SEND "); 4491592Srgrimes while (i < length) { 4501592Srgrimes if (AUTHTYPE_NAME_OK(pointer[i])) 4511592Srgrimes fprintf(NetTrace, "%s ", AUTHTYPE_NAME(pointer[i])); 4521592Srgrimes else 4531592Srgrimes fprintf(NetTrace, "%d ", pointer[i]); 4541592Srgrimes if (++i >= length) { 4551592Srgrimes fprintf(NetTrace, "(partial suboption??\?)"); 4561592Srgrimes break; 4571592Srgrimes } 4581592Srgrimes fprintf(NetTrace, "%s|%s ", 4591592Srgrimes ((pointer[i] & AUTH_WHO_MASK) == AUTH_WHO_CLIENT) ? 4601592Srgrimes "CLIENT" : "SERVER", 4611592Srgrimes ((pointer[i] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) ? 4621592Srgrimes "MUTUAL" : "ONE-WAY"); 4631592Srgrimes ++i; 4641592Srgrimes } 4651592Srgrimes break; 4661592Srgrimes 4671592Srgrimes case TELQUAL_NAME: 4681592Srgrimes i = 2; 4691592Srgrimes fprintf(NetTrace, " NAME \""); 4701592Srgrimes while (i < length) 4711592Srgrimes putc(pointer[i++], NetTrace); 4721592Srgrimes putc('"', NetTrace); 4731592Srgrimes break; 4741592Srgrimes 4751592Srgrimes default: 4761592Srgrimes for (i = 2; i < length; i++) 4771592Srgrimes fprintf(NetTrace, " ?%d?", pointer[i]); 4781592Srgrimes break; 4791592Srgrimes } 4801592Srgrimes break; 4811592Srgrimes#endif 4821592Srgrimes 4831592Srgrimes#ifdef ENCRYPTION 4841592Srgrimes case TELOPT_ENCRYPT: 4851592Srgrimes fprintf(NetTrace, "ENCRYPT"); 4861592Srgrimes if (length < 2) { 4871592Srgrimes fprintf(NetTrace, " (empty suboption??\?)"); 4881592Srgrimes break; 4891592Srgrimes } 4901592Srgrimes switch (pointer[1]) { 4911592Srgrimes case ENCRYPT_START: 4921592Srgrimes fprintf(NetTrace, " START"); 4931592Srgrimes break; 4941592Srgrimes 4951592Srgrimes case ENCRYPT_END: 4961592Srgrimes fprintf(NetTrace, " END"); 4971592Srgrimes break; 4981592Srgrimes 4991592Srgrimes case ENCRYPT_REQSTART: 5001592Srgrimes fprintf(NetTrace, " REQUEST-START"); 5011592Srgrimes break; 5021592Srgrimes 5031592Srgrimes case ENCRYPT_REQEND: 5041592Srgrimes fprintf(NetTrace, " REQUEST-END"); 5051592Srgrimes break; 5061592Srgrimes 5071592Srgrimes case ENCRYPT_IS: 5081592Srgrimes case ENCRYPT_REPLY: 5091592Srgrimes fprintf(NetTrace, " %s ", (pointer[1] == ENCRYPT_IS) ? 5101592Srgrimes "IS" : "REPLY"); 5111592Srgrimes if (length < 3) { 5121592Srgrimes fprintf(NetTrace, " (partial suboption??\?)"); 5131592Srgrimes break; 5141592Srgrimes } 5151592Srgrimes if (ENCTYPE_NAME_OK(pointer[2])) 5161592Srgrimes fprintf(NetTrace, "%s ", ENCTYPE_NAME(pointer[2])); 5171592Srgrimes else 5181592Srgrimes fprintf(NetTrace, " %d (unknown)", pointer[2]); 5191592Srgrimes 5201592Srgrimes encrypt_printsub(&pointer[1], length - 1, buf, sizeof(buf)); 5211592Srgrimes fprintf(NetTrace, "%s", buf); 5221592Srgrimes break; 5231592Srgrimes 5241592Srgrimes case ENCRYPT_SUPPORT: 5251592Srgrimes i = 2; 5261592Srgrimes fprintf(NetTrace, " SUPPORT "); 5271592Srgrimes while (i < length) { 5281592Srgrimes if (ENCTYPE_NAME_OK(pointer[i])) 5291592Srgrimes fprintf(NetTrace, "%s ", ENCTYPE_NAME(pointer[i])); 5301592Srgrimes else 5311592Srgrimes fprintf(NetTrace, "%d ", pointer[i]); 5321592Srgrimes i++; 5331592Srgrimes } 5341592Srgrimes break; 5351592Srgrimes 5361592Srgrimes case ENCRYPT_ENC_KEYID: 5371592Srgrimes fprintf(NetTrace, " ENC_KEYID "); 5381592Srgrimes goto encommon; 5391592Srgrimes 5401592Srgrimes case ENCRYPT_DEC_KEYID: 5411592Srgrimes fprintf(NetTrace, " DEC_KEYID "); 5421592Srgrimes goto encommon; 5431592Srgrimes 5441592Srgrimes default: 5451592Srgrimes fprintf(NetTrace, " %d (unknown)", pointer[1]); 5461592Srgrimes encommon: 5471592Srgrimes for (i = 2; i < length; i++) 5481592Srgrimes fprintf(NetTrace, " %d", pointer[i]); 5491592Srgrimes break; 5501592Srgrimes } 5511592Srgrimes break; 5521592Srgrimes#endif /* ENCRYPTION */ 5531592Srgrimes 5541592Srgrimes case TELOPT_LINEMODE: 5551592Srgrimes fprintf(NetTrace, "LINEMODE "); 5561592Srgrimes if (length < 2) { 5571592Srgrimes fprintf(NetTrace, " (empty suboption??\?)"); 5581592Srgrimes break; 5591592Srgrimes } 5601592Srgrimes switch (pointer[1]) { 5611592Srgrimes case WILL: 5621592Srgrimes fprintf(NetTrace, "WILL "); 5631592Srgrimes goto common; 5641592Srgrimes case WONT: 5651592Srgrimes fprintf(NetTrace, "WONT "); 5661592Srgrimes goto common; 5671592Srgrimes case DO: 5681592Srgrimes fprintf(NetTrace, "DO "); 5691592Srgrimes goto common; 5701592Srgrimes case DONT: 5711592Srgrimes fprintf(NetTrace, "DONT "); 5721592Srgrimes common: 5731592Srgrimes if (length < 3) { 5741592Srgrimes fprintf(NetTrace, "(no option??\?)"); 5751592Srgrimes break; 5761592Srgrimes } 5771592Srgrimes switch (pointer[2]) { 5781592Srgrimes case LM_FORWARDMASK: 5791592Srgrimes fprintf(NetTrace, "Forward Mask"); 5801592Srgrimes for (i = 3; i < length; i++) 5811592Srgrimes fprintf(NetTrace, " %x", pointer[i]); 5821592Srgrimes break; 5831592Srgrimes default: 5841592Srgrimes fprintf(NetTrace, "%d (unknown)", pointer[2]); 5851592Srgrimes for (i = 3; i < length; i++) 5861592Srgrimes fprintf(NetTrace, " %d", pointer[i]); 5871592Srgrimes break; 5881592Srgrimes } 5891592Srgrimes break; 5901592Srgrimes 5911592Srgrimes case LM_SLC: 5921592Srgrimes fprintf(NetTrace, "SLC"); 5931592Srgrimes for (i = 2; i < length - 2; i += 3) { 5941592Srgrimes if (SLC_NAME_OK(pointer[i+SLC_FUNC])) 5951592Srgrimes fprintf(NetTrace, " %s", SLC_NAME(pointer[i+SLC_FUNC])); 5961592Srgrimes else 5971592Srgrimes fprintf(NetTrace, " %d", pointer[i+SLC_FUNC]); 5981592Srgrimes switch (pointer[i+SLC_FLAGS]&SLC_LEVELBITS) { 5991592Srgrimes case SLC_NOSUPPORT: 6001592Srgrimes fprintf(NetTrace, " NOSUPPORT"); break; 6011592Srgrimes case SLC_CANTCHANGE: 6021592Srgrimes fprintf(NetTrace, " CANTCHANGE"); break; 6031592Srgrimes case SLC_VARIABLE: 6041592Srgrimes fprintf(NetTrace, " VARIABLE"); break; 6051592Srgrimes case SLC_DEFAULT: 6061592Srgrimes fprintf(NetTrace, " DEFAULT"); break; 6071592Srgrimes } 6081592Srgrimes fprintf(NetTrace, "%s%s%s", 6091592Srgrimes pointer[i+SLC_FLAGS]&SLC_ACK ? "|ACK" : "", 6101592Srgrimes pointer[i+SLC_FLAGS]&SLC_FLUSHIN ? "|FLUSHIN" : "", 6111592Srgrimes pointer[i+SLC_FLAGS]&SLC_FLUSHOUT ? "|FLUSHOUT" : ""); 6121592Srgrimes if (pointer[i+SLC_FLAGS]& ~(SLC_ACK|SLC_FLUSHIN| 6131592Srgrimes SLC_FLUSHOUT| SLC_LEVELBITS)) 6141592Srgrimes fprintf(NetTrace, "(0x%x)", pointer[i+SLC_FLAGS]); 6151592Srgrimes fprintf(NetTrace, " %d;", pointer[i+SLC_VALUE]); 6161592Srgrimes if ((pointer[i+SLC_VALUE] == IAC) && 6171592Srgrimes (pointer[i+SLC_VALUE+1] == IAC)) 6181592Srgrimes i++; 6191592Srgrimes } 6201592Srgrimes for (; i < length; i++) 6211592Srgrimes fprintf(NetTrace, " ?%d?", pointer[i]); 6221592Srgrimes break; 6231592Srgrimes 6241592Srgrimes case LM_MODE: 6251592Srgrimes fprintf(NetTrace, "MODE "); 6261592Srgrimes if (length < 3) { 6271592Srgrimes fprintf(NetTrace, "(no mode??\?)"); 6281592Srgrimes break; 6291592Srgrimes } 6301592Srgrimes { 6311592Srgrimes char tbuf[64]; 6321592Srgrimes sprintf(tbuf, "%s%s%s%s%s", 6331592Srgrimes pointer[2]&MODE_EDIT ? "|EDIT" : "", 6341592Srgrimes pointer[2]&MODE_TRAPSIG ? "|TRAPSIG" : "", 6351592Srgrimes pointer[2]&MODE_SOFT_TAB ? "|SOFT_TAB" : "", 6361592Srgrimes pointer[2]&MODE_LIT_ECHO ? "|LIT_ECHO" : "", 6371592Srgrimes pointer[2]&MODE_ACK ? "|ACK" : ""); 6381592Srgrimes fprintf(NetTrace, "%s", tbuf[1] ? &tbuf[1] : "0"); 6391592Srgrimes } 6401592Srgrimes if (pointer[2]&~(MODE_MASK)) 6411592Srgrimes fprintf(NetTrace, " (0x%x)", pointer[2]); 6421592Srgrimes for (i = 3; i < length; i++) 6431592Srgrimes fprintf(NetTrace, " ?0x%x?", pointer[i]); 6441592Srgrimes break; 6451592Srgrimes default: 6461592Srgrimes fprintf(NetTrace, "%d (unknown)", pointer[1]); 6471592Srgrimes for (i = 2; i < length; i++) 6481592Srgrimes fprintf(NetTrace, " %d", pointer[i]); 6491592Srgrimes } 6501592Srgrimes break; 6511592Srgrimes 6521592Srgrimes case TELOPT_STATUS: { 6531592Srgrimes const char *cp; 6541592Srgrimes int j, k; 6551592Srgrimes 6561592Srgrimes fprintf(NetTrace, "STATUS"); 6571592Srgrimes 6581592Srgrimes switch (pointer[1]) { 6591592Srgrimes default: 6601592Srgrimes if (pointer[1] == TELQUAL_SEND) 6611592Srgrimes fprintf(NetTrace, " SEND"); 6621592Srgrimes else 6631592Srgrimes fprintf(NetTrace, " %d (unknown)", pointer[1]); 6641592Srgrimes for (i = 2; i < length; i++) 6651592Srgrimes fprintf(NetTrace, " ?%d?", pointer[i]); 6661592Srgrimes break; 6671592Srgrimes case TELQUAL_IS: 6681592Srgrimes if (--want_status_response < 0) 6691592Srgrimes want_status_response = 0; 6701592Srgrimes if (NetTrace == stdout) 6711592Srgrimes fprintf(NetTrace, " IS\r\n"); 6721592Srgrimes else 6731592Srgrimes fprintf(NetTrace, " IS\n"); 6741592Srgrimes 6751592Srgrimes for (i = 2; i < length; i++) { 6761592Srgrimes switch(pointer[i]) { 6771592Srgrimes case DO: cp = "DO"; goto common2; 6781592Srgrimes case DONT: cp = "DONT"; goto common2; 6791592Srgrimes case WILL: cp = "WILL"; goto common2; 6801592Srgrimes case WONT: cp = "WONT"; goto common2; 6811592Srgrimes common2: 6821592Srgrimes i++; 6831592Srgrimes if (TELOPT_OK((int)pointer[i])) 6841592Srgrimes fprintf(NetTrace, " %s %s", cp, TELOPT(pointer[i])); 6851592Srgrimes else 6861592Srgrimes fprintf(NetTrace, " %s %d", cp, pointer[i]); 6871592Srgrimes 6881592Srgrimes if (NetTrace == stdout) 6891592Srgrimes fprintf(NetTrace, "\r\n"); 6901592Srgrimes else 6911592Srgrimes fprintf(NetTrace, "\n"); 6921592Srgrimes break; 6931592Srgrimes 6941592Srgrimes case SB: 6951592Srgrimes fprintf(NetTrace, " SB "); 6961592Srgrimes i++; 6971592Srgrimes j = k = i; 6981592Srgrimes while (j < length) { 6991592Srgrimes if (pointer[j] == SE) { 7001592Srgrimes if (j+1 == length) 7011592Srgrimes break; 7021592Srgrimes if (pointer[j+1] == SE) 7031592Srgrimes j++; 7041592Srgrimes else 7051592Srgrimes break; 7061592Srgrimes } 7071592Srgrimes pointer[k++] = pointer[j++]; 7081592Srgrimes } 7091592Srgrimes printsub(0, &pointer[i], k - i); 7101592Srgrimes if (i < length) { 7111592Srgrimes fprintf(NetTrace, " SE"); 7121592Srgrimes i = j; 7131592Srgrimes } else 7141592Srgrimes i = j - 1; 7151592Srgrimes 7161592Srgrimes if (NetTrace == stdout) 7171592Srgrimes fprintf(NetTrace, "\r\n"); 7181592Srgrimes else 7191592Srgrimes fprintf(NetTrace, "\n"); 7201592Srgrimes 7211592Srgrimes break; 7221592Srgrimes 7231592Srgrimes default: 7241592Srgrimes fprintf(NetTrace, " %d", pointer[i]); 7251592Srgrimes break; 7261592Srgrimes } 7271592Srgrimes } 7281592Srgrimes break; 7291592Srgrimes } 7301592Srgrimes break; 7311592Srgrimes } 7321592Srgrimes 7331592Srgrimes case TELOPT_XDISPLOC: 7341592Srgrimes fprintf(NetTrace, "X-DISPLAY-LOCATION "); 7351592Srgrimes switch (pointer[1]) { 7361592Srgrimes case TELQUAL_IS: 7371592Srgrimes fprintf(NetTrace, "IS \"%.*s\"", length-2, (char *)pointer+2); 7381592Srgrimes break; 7391592Srgrimes case TELQUAL_SEND: 7401592Srgrimes fprintf(NetTrace, "SEND"); 7411592Srgrimes break; 7421592Srgrimes default: 7431592Srgrimes fprintf(NetTrace, "- unknown qualifier %d (0x%x).", 7441592Srgrimes pointer[1], pointer[1]); 7451592Srgrimes } 7461592Srgrimes break; 7471592Srgrimes 7481592Srgrimes case TELOPT_NEW_ENVIRON: 7491592Srgrimes fprintf(NetTrace, "NEW-ENVIRON "); 7501592Srgrimes#ifdef OLD_ENVIRON 7511592Srgrimes goto env_common1; 7521592Srgrimes case TELOPT_OLD_ENVIRON: 7531592Srgrimes fprintf(NetTrace, "OLD-ENVIRON"); 7541592Srgrimes env_common1: 7551592Srgrimes#endif 7561592Srgrimes switch (pointer[1]) { 7571592Srgrimes case TELQUAL_IS: 7581592Srgrimes fprintf(NetTrace, "IS "); 7591592Srgrimes goto env_common; 7601592Srgrimes case TELQUAL_SEND: 7611592Srgrimes fprintf(NetTrace, "SEND "); 7621592Srgrimes goto env_common; 7631592Srgrimes case TELQUAL_INFO: 7641592Srgrimes fprintf(NetTrace, "INFO "); 7651592Srgrimes env_common: 7661592Srgrimes { 7671592Srgrimes int noquote = 2; 7681592Srgrimes#if defined(ENV_HACK) && defined(OLD_ENVIRON) 7691592Srgrimes extern int old_env_var, old_env_value; 7701592Srgrimes#endif 7711592Srgrimes for (i = 2; i < length; i++ ) { 7721592Srgrimes switch (pointer[i]) { 7731592Srgrimes case NEW_ENV_VALUE: 7741592Srgrimes#ifdef OLD_ENVIRON 7751592Srgrimes /* case NEW_ENV_OVAR: */ 7761592Srgrimes if (pointer[0] == TELOPT_OLD_ENVIRON) { 7771592Srgrimes# ifdef ENV_HACK 7781592Srgrimes if (old_env_var == OLD_ENV_VALUE) 7791592Srgrimes fprintf(NetTrace, "\" (VALUE) " + noquote); 7801592Srgrimes else 7811592Srgrimes# endif 7821592Srgrimes fprintf(NetTrace, "\" VAR " + noquote); 7831592Srgrimes } else 7841592Srgrimes#endif /* OLD_ENVIRON */ 7851592Srgrimes fprintf(NetTrace, "%s", "\" VALUE " + noquote); 7861592Srgrimes noquote = 2; 7871592Srgrimes break; 7881592Srgrimes 7891592Srgrimes case NEW_ENV_VAR: 7901592Srgrimes#ifdef OLD_ENVIRON 7911592Srgrimes /* case OLD_ENV_VALUE: */ 7921592Srgrimes if (pointer[0] == TELOPT_OLD_ENVIRON) { 7931592Srgrimes# ifdef ENV_HACK 7941592Srgrimes if (old_env_value == OLD_ENV_VAR) 7951592Srgrimes fprintf(NetTrace, "\" (VAR) " + noquote); 7961592Srgrimes else 7971592Srgrimes# endif 7981592Srgrimes fprintf(NetTrace, "\" VALUE " + noquote); 7991592Srgrimes } else 8001592Srgrimes#endif /* OLD_ENVIRON */ 8011592Srgrimes fprintf(NetTrace, "%s", "\" VAR " + noquote); 8021592Srgrimes noquote = 2; 8031592Srgrimes break; 8041592Srgrimes 8051592Srgrimes case ENV_ESC: 8061592Srgrimes fprintf(NetTrace, "%s", "\" ESC " + noquote); 8071592Srgrimes noquote = 2; 8081592Srgrimes break; 8091592Srgrimes 8101592Srgrimes case ENV_USERVAR: 8111592Srgrimes fprintf(NetTrace, "%s", "\" USERVAR " + noquote); 8121592Srgrimes noquote = 2; 8131592Srgrimes break; 8141592Srgrimes 8151592Srgrimes default: 8161592Srgrimes if (isprint(pointer[i]) && pointer[i] != '"') { 8171592Srgrimes if (noquote) { 8181592Srgrimes putc('"', NetTrace); 8191592Srgrimes noquote = 0; 8201592Srgrimes } 8211592Srgrimes putc(pointer[i], NetTrace); 8221592Srgrimes } else { 8231592Srgrimes fprintf(NetTrace, "\" %03o " + noquote, 8241592Srgrimes pointer[i]); 8251592Srgrimes noquote = 2; 8261592Srgrimes } 8271592Srgrimes break; 8281592Srgrimes } 8291592Srgrimes } 8301592Srgrimes if (!noquote) 8311592Srgrimes putc('"', NetTrace); 8321592Srgrimes break; 8331592Srgrimes } 8341592Srgrimes } 8351592Srgrimes break; 8361592Srgrimes 8371592Srgrimes default: 8381592Srgrimes if (TELOPT_OK(pointer[0])) 8391592Srgrimes fprintf(NetTrace, "%s (unknown)", TELOPT(pointer[0])); 8401592Srgrimes else 8411592Srgrimes fprintf(NetTrace, "%d (unknown)", pointer[0]); 8421592Srgrimes for (i = 1; i < length; i++) 8431592Srgrimes fprintf(NetTrace, " %d", pointer[i]); 8441592Srgrimes break; 8451592Srgrimes } 8461592Srgrimes if (direction) { 8471592Srgrimes if (NetTrace == stdout) 8481592Srgrimes fprintf(NetTrace, "\r\n"); 8491592Srgrimes else 8501592Srgrimes fprintf(NetTrace, "\n"); 8511592Srgrimes } 8521592Srgrimes if (NetTrace == stdout) 8531592Srgrimes fflush(NetTrace); 8541592Srgrimes } 8551592Srgrimes} 8561592Srgrimes 8571592Srgrimes/* EmptyTerminal - called to make sure that the terminal buffer is empty. 8581592Srgrimes * Note that we consider the buffer to run all the 8591592Srgrimes * way to the kernel (thus the select). 8601592Srgrimes */ 8611592Srgrimes 8621592Srgrimesstatic void 8631592SrgrimesEmptyTerminal(void) 8641592Srgrimes{ 8651592Srgrimes fd_set o; 8661592Srgrimes 8671592Srgrimes FD_ZERO(&o); 8681592Srgrimes 8691592Srgrimes if (TTYBYTES() == 0) { 8701592Srgrimes FD_SET(tout, &o); 8711592Srgrimes (void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0, 8721592Srgrimes (struct timeval *) 0); /* wait for TTLOWAT */ 8731592Srgrimes } else { 8741592Srgrimes while (TTYBYTES()) { 8751592Srgrimes (void) ttyflush(0); 8761592Srgrimes FD_SET(tout, &o); 8771592Srgrimes (void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0, 8781592Srgrimes (struct timeval *) 0); /* wait for TTLOWAT */ 8791592Srgrimes } 8801592Srgrimes } 8811592Srgrimes} 8821592Srgrimes 8831592Srgrimesstatic void 8841592SrgrimesSetForExit(void) 8851592Srgrimes{ 8861592Srgrimes setconnmode(0); 8871592Srgrimes do { 8881592Srgrimes (void)telrcv(); /* Process any incoming data */ 8891592Srgrimes EmptyTerminal(); 8901592Srgrimes } while (ring_full_count(&netiring)); /* While there is any */ 8911592Srgrimes setcommandmode(); 8921592Srgrimes fflush(stdout); 8931592Srgrimes fflush(stderr); 8941592Srgrimes setconnmode(0); 8951592Srgrimes EmptyTerminal(); /* Flush the path to the tty */ 8961592Srgrimes setcommandmode(); 8971592Srgrimes} 8981592Srgrimes 8991592Srgrimesvoid 9001592SrgrimesExit(int returnCode) 9011592Srgrimes{ 9021592Srgrimes SetForExit(); 9031592Srgrimes exit(returnCode); 9041592Srgrimes} 9051592Srgrimes 9061592Srgrimesvoid 9071592SrgrimesExitString(const char *string, int returnCode) 9081592Srgrimes{ 9091592Srgrimes SetForExit(); 9101592Srgrimes fwrite(string, 1, strlen(string), stderr); 9111592Srgrimes exit(returnCode); 9121592Srgrimes} 9131592Srgrimes