1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate * Copyright 1994-2002 Sun Microsystems, Inc. All rights reserved.
3*7c478bd9Sstevel@tonic-gate * Use is subject to license terms.
4*7c478bd9Sstevel@tonic-gate */
5*7c478bd9Sstevel@tonic-gate
6*7c478bd9Sstevel@tonic-gate /*
7*7c478bd9Sstevel@tonic-gate * usr/src/cmd/cmd-inet/usr.bin/telnet/utilities.c
8*7c478bd9Sstevel@tonic-gate */
9*7c478bd9Sstevel@tonic-gate
10*7c478bd9Sstevel@tonic-gate /*
11*7c478bd9Sstevel@tonic-gate * Copyright (c) 1988, 1993
12*7c478bd9Sstevel@tonic-gate * The Regents of the University of California. All rights reserved.
13*7c478bd9Sstevel@tonic-gate *
14*7c478bd9Sstevel@tonic-gate * Redistribution and use in source and binary forms, with or without
15*7c478bd9Sstevel@tonic-gate * modification, are permitted provided that the following conditions
16*7c478bd9Sstevel@tonic-gate * are met:
17*7c478bd9Sstevel@tonic-gate * 1. Redistributions of source code must retain the above copyright
18*7c478bd9Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer.
19*7c478bd9Sstevel@tonic-gate * 2. Redistributions in binary form must reproduce the above copyright
20*7c478bd9Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer in the
21*7c478bd9Sstevel@tonic-gate * documentation and/or other materials provided with the distribution.
22*7c478bd9Sstevel@tonic-gate * 3. All advertising materials mentioning features or use of this software
23*7c478bd9Sstevel@tonic-gate * must display the following acknowledgement:
24*7c478bd9Sstevel@tonic-gate * This product includes software developed by the University of
25*7c478bd9Sstevel@tonic-gate * California, Berkeley and its contributors.
26*7c478bd9Sstevel@tonic-gate * 4. Neither the name of the University nor the names of its contributors
27*7c478bd9Sstevel@tonic-gate * may be used to endorse or promote products derived from this software
28*7c478bd9Sstevel@tonic-gate * without specific prior written permission.
29*7c478bd9Sstevel@tonic-gate *
30*7c478bd9Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
31*7c478bd9Sstevel@tonic-gate * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
32*7c478bd9Sstevel@tonic-gate * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33*7c478bd9Sstevel@tonic-gate * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
34*7c478bd9Sstevel@tonic-gate * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
35*7c478bd9Sstevel@tonic-gate * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
36*7c478bd9Sstevel@tonic-gate * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
37*7c478bd9Sstevel@tonic-gate * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
38*7c478bd9Sstevel@tonic-gate * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
39*7c478bd9Sstevel@tonic-gate * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
40*7c478bd9Sstevel@tonic-gate * SUCH DAMAGE.
41*7c478bd9Sstevel@tonic-gate */
42*7c478bd9Sstevel@tonic-gate
43*7c478bd9Sstevel@tonic-gate #ifndef lint
44*7c478bd9Sstevel@tonic-gate static char sccsid[] = "@(#)utilities.c 8.1 (Berkeley) 6/6/93";
45*7c478bd9Sstevel@tonic-gate #endif /* not lint */
46*7c478bd9Sstevel@tonic-gate
47*7c478bd9Sstevel@tonic-gate #define TELOPTS
48*7c478bd9Sstevel@tonic-gate #ifdef lint
49*7c478bd9Sstevel@tonic-gate static char *telcmds[] = {0};
50*7c478bd9Sstevel@tonic-gate static char *slc_names[] = {0};
51*7c478bd9Sstevel@tonic-gate static char *encrypt_names[] = {0};
52*7c478bd9Sstevel@tonic-gate static char *enctype_names[] = {0};
53*7c478bd9Sstevel@tonic-gate #else /* lint */
54*7c478bd9Sstevel@tonic-gate #define TELCMDS
55*7c478bd9Sstevel@tonic-gate #define SLC_NAMES
56*7c478bd9Sstevel@tonic-gate #endif /* lint */
57*7c478bd9Sstevel@tonic-gate #include <arpa/telnet.h>
58*7c478bd9Sstevel@tonic-gate #include <sys/types.h>
59*7c478bd9Sstevel@tonic-gate #include <sys/time.h>
60*7c478bd9Sstevel@tonic-gate #include <sys/param.h>
61*7c478bd9Sstevel@tonic-gate #include <sys/socket.h>
62*7c478bd9Sstevel@tonic-gate #include <errno.h>
63*7c478bd9Sstevel@tonic-gate
64*7c478bd9Sstevel@tonic-gate #include <ctype.h>
65*7c478bd9Sstevel@tonic-gate
66*7c478bd9Sstevel@tonic-gate #include "general.h"
67*7c478bd9Sstevel@tonic-gate
68*7c478bd9Sstevel@tonic-gate #include "ring.h"
69*7c478bd9Sstevel@tonic-gate
70*7c478bd9Sstevel@tonic-gate #include "defines.h"
71*7c478bd9Sstevel@tonic-gate
72*7c478bd9Sstevel@tonic-gate #include "externs.h"
73*7c478bd9Sstevel@tonic-gate
74*7c478bd9Sstevel@tonic-gate FILE *NetTrace = 0; /* Not in bss, since needs to stay */
75*7c478bd9Sstevel@tonic-gate int prettydump;
76*7c478bd9Sstevel@tonic-gate
77*7c478bd9Sstevel@tonic-gate /*
78*7c478bd9Sstevel@tonic-gate * upcase()
79*7c478bd9Sstevel@tonic-gate *
80*7c478bd9Sstevel@tonic-gate * Upcase (in place) the argument.
81*7c478bd9Sstevel@tonic-gate */
82*7c478bd9Sstevel@tonic-gate
83*7c478bd9Sstevel@tonic-gate void
upcase(argument)84*7c478bd9Sstevel@tonic-gate upcase(argument)
85*7c478bd9Sstevel@tonic-gate register char *argument;
86*7c478bd9Sstevel@tonic-gate {
87*7c478bd9Sstevel@tonic-gate register int c;
88*7c478bd9Sstevel@tonic-gate
89*7c478bd9Sstevel@tonic-gate while ((c = *argument) != 0) {
90*7c478bd9Sstevel@tonic-gate if (islower(c)) {
91*7c478bd9Sstevel@tonic-gate *argument = toupper(c);
92*7c478bd9Sstevel@tonic-gate }
93*7c478bd9Sstevel@tonic-gate argument++;
94*7c478bd9Sstevel@tonic-gate }
95*7c478bd9Sstevel@tonic-gate }
96*7c478bd9Sstevel@tonic-gate
97*7c478bd9Sstevel@tonic-gate /*
98*7c478bd9Sstevel@tonic-gate * SetSockOpt()
99*7c478bd9Sstevel@tonic-gate *
100*7c478bd9Sstevel@tonic-gate * Compensate for differences in 4.2 and 4.3 systems.
101*7c478bd9Sstevel@tonic-gate */
102*7c478bd9Sstevel@tonic-gate
103*7c478bd9Sstevel@tonic-gate int
SetSockOpt(fd,level,option,yesno)104*7c478bd9Sstevel@tonic-gate SetSockOpt(fd, level, option, yesno)
105*7c478bd9Sstevel@tonic-gate int fd, level, option, yesno;
106*7c478bd9Sstevel@tonic-gate {
107*7c478bd9Sstevel@tonic-gate return (setsockopt(fd, level, option, &yesno, sizeof (yesno)));
108*7c478bd9Sstevel@tonic-gate }
109*7c478bd9Sstevel@tonic-gate
110*7c478bd9Sstevel@tonic-gate /*
111*7c478bd9Sstevel@tonic-gate * The following are routines used to print out debugging information.
112*7c478bd9Sstevel@tonic-gate */
113*7c478bd9Sstevel@tonic-gate
114*7c478bd9Sstevel@tonic-gate unsigned char NetTraceFile[MAXPATHLEN] = "(standard output)";
115*7c478bd9Sstevel@tonic-gate
116*7c478bd9Sstevel@tonic-gate void
SetNetTrace(file)117*7c478bd9Sstevel@tonic-gate SetNetTrace(file)
118*7c478bd9Sstevel@tonic-gate register char *file;
119*7c478bd9Sstevel@tonic-gate {
120*7c478bd9Sstevel@tonic-gate if (NetTrace && NetTrace != stdout)
121*7c478bd9Sstevel@tonic-gate (void) fclose(NetTrace);
122*7c478bd9Sstevel@tonic-gate if (file && (strcmp(file, "-") != 0)) {
123*7c478bd9Sstevel@tonic-gate NetTrace = fopen(file, "w");
124*7c478bd9Sstevel@tonic-gate if (NetTrace) {
125*7c478bd9Sstevel@tonic-gate (void) strcpy((char *)NetTraceFile, file);
126*7c478bd9Sstevel@tonic-gate return;
127*7c478bd9Sstevel@tonic-gate }
128*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "Cannot open %s.\n", file);
129*7c478bd9Sstevel@tonic-gate }
130*7c478bd9Sstevel@tonic-gate NetTrace = stdout;
131*7c478bd9Sstevel@tonic-gate (void) strcpy((char *)NetTraceFile, "(standard output)");
132*7c478bd9Sstevel@tonic-gate }
133*7c478bd9Sstevel@tonic-gate
134*7c478bd9Sstevel@tonic-gate void
Dump(direction,buffer,length)135*7c478bd9Sstevel@tonic-gate Dump(direction, buffer, length)
136*7c478bd9Sstevel@tonic-gate char direction;
137*7c478bd9Sstevel@tonic-gate unsigned char *buffer;
138*7c478bd9Sstevel@tonic-gate int length;
139*7c478bd9Sstevel@tonic-gate {
140*7c478bd9Sstevel@tonic-gate #define BYTES_PER_LINE 32
141*7c478bd9Sstevel@tonic-gate #define min(x, y) ((x < y) ? x:y)
142*7c478bd9Sstevel@tonic-gate unsigned char *pThis;
143*7c478bd9Sstevel@tonic-gate int offset;
144*7c478bd9Sstevel@tonic-gate
145*7c478bd9Sstevel@tonic-gate offset = 0;
146*7c478bd9Sstevel@tonic-gate
147*7c478bd9Sstevel@tonic-gate while (length) {
148*7c478bd9Sstevel@tonic-gate /* print one line */
149*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%c 0x%x\t", direction, offset);
150*7c478bd9Sstevel@tonic-gate pThis = buffer;
151*7c478bd9Sstevel@tonic-gate if (prettydump) {
152*7c478bd9Sstevel@tonic-gate buffer = buffer + min(length, BYTES_PER_LINE/2);
153*7c478bd9Sstevel@tonic-gate while (pThis < buffer) {
154*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%c%.2x",
155*7c478bd9Sstevel@tonic-gate (((*pThis)&0xff) == 0xff) ? '*' : ' ',
156*7c478bd9Sstevel@tonic-gate (*pThis)&0xff);
157*7c478bd9Sstevel@tonic-gate pThis++;
158*7c478bd9Sstevel@tonic-gate }
159*7c478bd9Sstevel@tonic-gate length -= BYTES_PER_LINE/2;
160*7c478bd9Sstevel@tonic-gate offset += BYTES_PER_LINE/2;
161*7c478bd9Sstevel@tonic-gate } else {
162*7c478bd9Sstevel@tonic-gate buffer = buffer + min(length, BYTES_PER_LINE);
163*7c478bd9Sstevel@tonic-gate while (pThis < buffer) {
164*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%.2x", (*pThis)&0xff);
165*7c478bd9Sstevel@tonic-gate pThis++;
166*7c478bd9Sstevel@tonic-gate }
167*7c478bd9Sstevel@tonic-gate length -= BYTES_PER_LINE;
168*7c478bd9Sstevel@tonic-gate offset += BYTES_PER_LINE;
169*7c478bd9Sstevel@tonic-gate }
170*7c478bd9Sstevel@tonic-gate if (NetTrace == stdout) {
171*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "\r\n");
172*7c478bd9Sstevel@tonic-gate } else {
173*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "\n");
174*7c478bd9Sstevel@tonic-gate }
175*7c478bd9Sstevel@tonic-gate if (length < 0) {
176*7c478bd9Sstevel@tonic-gate (void) fflush(NetTrace);
177*7c478bd9Sstevel@tonic-gate return;
178*7c478bd9Sstevel@tonic-gate }
179*7c478bd9Sstevel@tonic-gate /* find next unique line */
180*7c478bd9Sstevel@tonic-gate }
181*7c478bd9Sstevel@tonic-gate (void) fflush(NetTrace);
182*7c478bd9Sstevel@tonic-gate }
183*7c478bd9Sstevel@tonic-gate
184*7c478bd9Sstevel@tonic-gate
185*7c478bd9Sstevel@tonic-gate void
printoption(direction,cmd,option)186*7c478bd9Sstevel@tonic-gate printoption(direction, cmd, option)
187*7c478bd9Sstevel@tonic-gate char *direction;
188*7c478bd9Sstevel@tonic-gate int cmd, option;
189*7c478bd9Sstevel@tonic-gate {
190*7c478bd9Sstevel@tonic-gate if (!showoptions)
191*7c478bd9Sstevel@tonic-gate return;
192*7c478bd9Sstevel@tonic-gate if (cmd == IAC) {
193*7c478bd9Sstevel@tonic-gate if (TELCMD_OK(option))
194*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%s IAC %s", direction,
195*7c478bd9Sstevel@tonic-gate TELCMD(option));
196*7c478bd9Sstevel@tonic-gate else
197*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%s IAC %d", direction,
198*7c478bd9Sstevel@tonic-gate option);
199*7c478bd9Sstevel@tonic-gate } else {
200*7c478bd9Sstevel@tonic-gate register char *fmt;
201*7c478bd9Sstevel@tonic-gate fmt = (cmd == WILL) ? "WILL" : (cmd == WONT) ? "WONT" :
202*7c478bd9Sstevel@tonic-gate (cmd == DO) ? "DO" : (cmd == DONT) ? "DONT" : 0;
203*7c478bd9Sstevel@tonic-gate if (fmt) {
204*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%s %s ", direction, fmt);
205*7c478bd9Sstevel@tonic-gate if (TELOPT_OK(option))
206*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%s", TELOPT(option));
207*7c478bd9Sstevel@tonic-gate else if (option == TELOPT_EXOPL)
208*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "EXOPL");
209*7c478bd9Sstevel@tonic-gate else
210*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%d", option);
211*7c478bd9Sstevel@tonic-gate } else
212*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%s %d %d", direction, cmd,
213*7c478bd9Sstevel@tonic-gate option);
214*7c478bd9Sstevel@tonic-gate }
215*7c478bd9Sstevel@tonic-gate if (NetTrace == stdout) {
216*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "\r\n");
217*7c478bd9Sstevel@tonic-gate (void) fflush(NetTrace);
218*7c478bd9Sstevel@tonic-gate } else {
219*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "\n");
220*7c478bd9Sstevel@tonic-gate }
221*7c478bd9Sstevel@tonic-gate }
222*7c478bd9Sstevel@tonic-gate
223*7c478bd9Sstevel@tonic-gate void
optionstatus()224*7c478bd9Sstevel@tonic-gate optionstatus()
225*7c478bd9Sstevel@tonic-gate {
226*7c478bd9Sstevel@tonic-gate register int i;
227*7c478bd9Sstevel@tonic-gate extern char will_wont_resp[], do_dont_resp[];
228*7c478bd9Sstevel@tonic-gate
229*7c478bd9Sstevel@tonic-gate for (i = 0; i < SUBBUFSIZE; i++) {
230*7c478bd9Sstevel@tonic-gate if (do_dont_resp[i]) {
231*7c478bd9Sstevel@tonic-gate if (TELOPT_OK(i))
232*7c478bd9Sstevel@tonic-gate (void) printf("resp DO_DONT %s: %d\n",
233*7c478bd9Sstevel@tonic-gate TELOPT(i), do_dont_resp[i]);
234*7c478bd9Sstevel@tonic-gate else if (TELCMD_OK(i))
235*7c478bd9Sstevel@tonic-gate (void) printf("resp DO_DONT %s: %d\n",
236*7c478bd9Sstevel@tonic-gate TELCMD(i), do_dont_resp[i]);
237*7c478bd9Sstevel@tonic-gate else
238*7c478bd9Sstevel@tonic-gate (void) printf("resp DO_DONT %d: %d\n", i,
239*7c478bd9Sstevel@tonic-gate do_dont_resp[i]);
240*7c478bd9Sstevel@tonic-gate if (my_want_state_is_do(i)) {
241*7c478bd9Sstevel@tonic-gate if (TELOPT_OK(i))
242*7c478bd9Sstevel@tonic-gate (void) printf("want DO %s\n",
243*7c478bd9Sstevel@tonic-gate TELOPT(i));
244*7c478bd9Sstevel@tonic-gate else if (TELCMD_OK(i))
245*7c478bd9Sstevel@tonic-gate (void) printf("want DO %s\n",
246*7c478bd9Sstevel@tonic-gate TELCMD(i));
247*7c478bd9Sstevel@tonic-gate else
248*7c478bd9Sstevel@tonic-gate (void) printf("want DO %d\n", i);
249*7c478bd9Sstevel@tonic-gate } else {
250*7c478bd9Sstevel@tonic-gate if (TELOPT_OK(i))
251*7c478bd9Sstevel@tonic-gate (void) printf("want DONT %s\n",
252*7c478bd9Sstevel@tonic-gate TELOPT(i));
253*7c478bd9Sstevel@tonic-gate else if (TELCMD_OK(i))
254*7c478bd9Sstevel@tonic-gate (void) printf("want DONT %s\n",
255*7c478bd9Sstevel@tonic-gate TELCMD(i));
256*7c478bd9Sstevel@tonic-gate else
257*7c478bd9Sstevel@tonic-gate (void) printf("want DONT %d\n", i);
258*7c478bd9Sstevel@tonic-gate }
259*7c478bd9Sstevel@tonic-gate } else {
260*7c478bd9Sstevel@tonic-gate if (my_state_is_do(i)) {
261*7c478bd9Sstevel@tonic-gate if (TELOPT_OK(i))
262*7c478bd9Sstevel@tonic-gate (void) printf(" DO %s\n",
263*7c478bd9Sstevel@tonic-gate TELOPT(i));
264*7c478bd9Sstevel@tonic-gate else if (TELCMD_OK(i))
265*7c478bd9Sstevel@tonic-gate (void) printf(" DO %s\n",
266*7c478bd9Sstevel@tonic-gate TELCMD(i));
267*7c478bd9Sstevel@tonic-gate else
268*7c478bd9Sstevel@tonic-gate (void) printf(" DO %d\n", i);
269*7c478bd9Sstevel@tonic-gate }
270*7c478bd9Sstevel@tonic-gate }
271*7c478bd9Sstevel@tonic-gate if (will_wont_resp[i]) {
272*7c478bd9Sstevel@tonic-gate if (TELOPT_OK(i))
273*7c478bd9Sstevel@tonic-gate (void) printf("resp WILL_WONT %s: %d\n",
274*7c478bd9Sstevel@tonic-gate TELOPT(i), will_wont_resp[i]);
275*7c478bd9Sstevel@tonic-gate else if (TELCMD_OK(i))
276*7c478bd9Sstevel@tonic-gate (void) printf("resp WILL_WONT %s: %d\n",
277*7c478bd9Sstevel@tonic-gate TELCMD(i), will_wont_resp[i]);
278*7c478bd9Sstevel@tonic-gate else
279*7c478bd9Sstevel@tonic-gate (void) printf("resp WILL_WONT %d: %d\n",
280*7c478bd9Sstevel@tonic-gate i, will_wont_resp[i]);
281*7c478bd9Sstevel@tonic-gate if (my_want_state_is_will(i)) {
282*7c478bd9Sstevel@tonic-gate if (TELOPT_OK(i))
283*7c478bd9Sstevel@tonic-gate (void) printf("want WILL %s\n",
284*7c478bd9Sstevel@tonic-gate TELOPT(i));
285*7c478bd9Sstevel@tonic-gate else if (TELCMD_OK(i))
286*7c478bd9Sstevel@tonic-gate (void) printf("want WILL %s\n",
287*7c478bd9Sstevel@tonic-gate TELCMD(i));
288*7c478bd9Sstevel@tonic-gate else
289*7c478bd9Sstevel@tonic-gate (void) printf("want WILL %d\n", i);
290*7c478bd9Sstevel@tonic-gate } else {
291*7c478bd9Sstevel@tonic-gate if (TELOPT_OK(i))
292*7c478bd9Sstevel@tonic-gate (void) printf("want WONT %s\n",
293*7c478bd9Sstevel@tonic-gate TELOPT(i));
294*7c478bd9Sstevel@tonic-gate else if (TELCMD_OK(i))
295*7c478bd9Sstevel@tonic-gate (void) printf("want WONT %s\n",
296*7c478bd9Sstevel@tonic-gate TELCMD(i));
297*7c478bd9Sstevel@tonic-gate else
298*7c478bd9Sstevel@tonic-gate (void) printf("want WONT %d\n", i);
299*7c478bd9Sstevel@tonic-gate }
300*7c478bd9Sstevel@tonic-gate } else {
301*7c478bd9Sstevel@tonic-gate if (my_state_is_will(i)) {
302*7c478bd9Sstevel@tonic-gate if (TELOPT_OK(i))
303*7c478bd9Sstevel@tonic-gate (void) printf(" WILL %s\n",
304*7c478bd9Sstevel@tonic-gate TELOPT(i));
305*7c478bd9Sstevel@tonic-gate else if (TELCMD_OK(i))
306*7c478bd9Sstevel@tonic-gate (void) printf(" WILL %s\n",
307*7c478bd9Sstevel@tonic-gate TELCMD(i));
308*7c478bd9Sstevel@tonic-gate else
309*7c478bd9Sstevel@tonic-gate (void) printf(" WILL %d\n", i);
310*7c478bd9Sstevel@tonic-gate }
311*7c478bd9Sstevel@tonic-gate }
312*7c478bd9Sstevel@tonic-gate }
313*7c478bd9Sstevel@tonic-gate
314*7c478bd9Sstevel@tonic-gate }
315*7c478bd9Sstevel@tonic-gate
316*7c478bd9Sstevel@tonic-gate void
printsub(direction,pointer,length)317*7c478bd9Sstevel@tonic-gate printsub(direction, pointer, length)
318*7c478bd9Sstevel@tonic-gate char direction; /* '<' or '>' */
319*7c478bd9Sstevel@tonic-gate unsigned char *pointer; /* where suboption data sits */
320*7c478bd9Sstevel@tonic-gate int length; /* length of suboption data */
321*7c478bd9Sstevel@tonic-gate {
322*7c478bd9Sstevel@tonic-gate register int i;
323*7c478bd9Sstevel@tonic-gate char buf[512];
324*7c478bd9Sstevel@tonic-gate extern int want_status_response;
325*7c478bd9Sstevel@tonic-gate
326*7c478bd9Sstevel@tonic-gate if (showoptions || direction == 0 ||
327*7c478bd9Sstevel@tonic-gate (want_status_response && (pointer[0] == TELOPT_STATUS))) {
328*7c478bd9Sstevel@tonic-gate if (direction) {
329*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%s IAC SB ",
330*7c478bd9Sstevel@tonic-gate (direction == '<')? "RCVD":"SENT");
331*7c478bd9Sstevel@tonic-gate if (length >= 3) {
332*7c478bd9Sstevel@tonic-gate register int j;
333*7c478bd9Sstevel@tonic-gate
334*7c478bd9Sstevel@tonic-gate i = pointer[length-2];
335*7c478bd9Sstevel@tonic-gate j = pointer[length-1];
336*7c478bd9Sstevel@tonic-gate
337*7c478bd9Sstevel@tonic-gate if (i != IAC || j != SE) {
338*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace,
339*7c478bd9Sstevel@tonic-gate "(terminated by ");
340*7c478bd9Sstevel@tonic-gate if (TELOPT_OK(i))
341*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%s ",
342*7c478bd9Sstevel@tonic-gate TELOPT(i));
343*7c478bd9Sstevel@tonic-gate else if (TELCMD_OK(i))
344*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%s ",
345*7c478bd9Sstevel@tonic-gate TELCMD(i));
346*7c478bd9Sstevel@tonic-gate else
347*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%d ",
348*7c478bd9Sstevel@tonic-gate i);
349*7c478bd9Sstevel@tonic-gate if (TELOPT_OK(j))
350*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%s",
351*7c478bd9Sstevel@tonic-gate TELOPT(j));
352*7c478bd9Sstevel@tonic-gate else if (TELCMD_OK(j))
353*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%s",
354*7c478bd9Sstevel@tonic-gate TELCMD(j));
355*7c478bd9Sstevel@tonic-gate else
356*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%d",
357*7c478bd9Sstevel@tonic-gate j);
358*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace,
359*7c478bd9Sstevel@tonic-gate ", not IAC SE!) ");
360*7c478bd9Sstevel@tonic-gate }
361*7c478bd9Sstevel@tonic-gate }
362*7c478bd9Sstevel@tonic-gate length -= 2;
363*7c478bd9Sstevel@tonic-gate }
364*7c478bd9Sstevel@tonic-gate if (length < 1) {
365*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "(Empty suboption??\?)");
366*7c478bd9Sstevel@tonic-gate if (NetTrace == stdout)
367*7c478bd9Sstevel@tonic-gate (void) fflush(NetTrace);
368*7c478bd9Sstevel@tonic-gate return;
369*7c478bd9Sstevel@tonic-gate }
370*7c478bd9Sstevel@tonic-gate switch (pointer[0]) {
371*7c478bd9Sstevel@tonic-gate case TELOPT_TTYPE:
372*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "TERMINAL-TYPE ");
373*7c478bd9Sstevel@tonic-gate switch (pointer[1]) {
374*7c478bd9Sstevel@tonic-gate case TELQUAL_IS:
375*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "IS \"%.*s\"",
376*7c478bd9Sstevel@tonic-gate length-2,
377*7c478bd9Sstevel@tonic-gate (char *)pointer+2);
378*7c478bd9Sstevel@tonic-gate break;
379*7c478bd9Sstevel@tonic-gate case TELQUAL_SEND:
380*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "SEND");
381*7c478bd9Sstevel@tonic-gate break;
382*7c478bd9Sstevel@tonic-gate default:
383*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace,
384*7c478bd9Sstevel@tonic-gate "- unknown qualifier %d (0x%x).",
385*7c478bd9Sstevel@tonic-gate pointer[1], pointer[1]);
386*7c478bd9Sstevel@tonic-gate }
387*7c478bd9Sstevel@tonic-gate break;
388*7c478bd9Sstevel@tonic-gate case TELOPT_TSPEED:
389*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "TERMINAL-SPEED");
390*7c478bd9Sstevel@tonic-gate if (length < 2) {
391*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace,
392*7c478bd9Sstevel@tonic-gate " (empty suboption??\?)");
393*7c478bd9Sstevel@tonic-gate break;
394*7c478bd9Sstevel@tonic-gate }
395*7c478bd9Sstevel@tonic-gate switch (pointer[1]) {
396*7c478bd9Sstevel@tonic-gate case TELQUAL_IS:
397*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " IS ");
398*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%.*s", length-2,
399*7c478bd9Sstevel@tonic-gate (char *)pointer+2);
400*7c478bd9Sstevel@tonic-gate break;
401*7c478bd9Sstevel@tonic-gate default:
402*7c478bd9Sstevel@tonic-gate if (pointer[1] == 1)
403*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " SEND");
404*7c478bd9Sstevel@tonic-gate else
405*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace,
406*7c478bd9Sstevel@tonic-gate " %d (unknown)", pointer[1]);
407*7c478bd9Sstevel@tonic-gate for (i = 2; i < length; i++)
408*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " ?%d?",
409*7c478bd9Sstevel@tonic-gate pointer[i]);
410*7c478bd9Sstevel@tonic-gate break;
411*7c478bd9Sstevel@tonic-gate }
412*7c478bd9Sstevel@tonic-gate break;
413*7c478bd9Sstevel@tonic-gate
414*7c478bd9Sstevel@tonic-gate case TELOPT_LFLOW:
415*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "TOGGLE-FLOW-CONTROL");
416*7c478bd9Sstevel@tonic-gate if (length < 2) {
417*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace,
418*7c478bd9Sstevel@tonic-gate " (empty suboption??\?)");
419*7c478bd9Sstevel@tonic-gate break;
420*7c478bd9Sstevel@tonic-gate }
421*7c478bd9Sstevel@tonic-gate switch (pointer[1]) {
422*7c478bd9Sstevel@tonic-gate case LFLOW_OFF:
423*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " OFF");
424*7c478bd9Sstevel@tonic-gate break;
425*7c478bd9Sstevel@tonic-gate case LFLOW_ON:
426*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " ON");
427*7c478bd9Sstevel@tonic-gate break;
428*7c478bd9Sstevel@tonic-gate case LFLOW_RESTART_ANY:
429*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " RESTART-ANY");
430*7c478bd9Sstevel@tonic-gate break;
431*7c478bd9Sstevel@tonic-gate case LFLOW_RESTART_XON:
432*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " RESTART-XON");
433*7c478bd9Sstevel@tonic-gate break;
434*7c478bd9Sstevel@tonic-gate default:
435*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " %d (unknown)",
436*7c478bd9Sstevel@tonic-gate pointer[1]);
437*7c478bd9Sstevel@tonic-gate }
438*7c478bd9Sstevel@tonic-gate for (i = 2; i < length; i++)
439*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " ?%d?",
440*7c478bd9Sstevel@tonic-gate pointer[i]);
441*7c478bd9Sstevel@tonic-gate break;
442*7c478bd9Sstevel@tonic-gate
443*7c478bd9Sstevel@tonic-gate case TELOPT_NAWS:
444*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "NAWS");
445*7c478bd9Sstevel@tonic-gate if (length < 2) {
446*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace,
447*7c478bd9Sstevel@tonic-gate " (empty suboption??\?)");
448*7c478bd9Sstevel@tonic-gate break;
449*7c478bd9Sstevel@tonic-gate }
450*7c478bd9Sstevel@tonic-gate if (length == 2) {
451*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " ?%d?", pointer[1]);
452*7c478bd9Sstevel@tonic-gate break;
453*7c478bd9Sstevel@tonic-gate }
454*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " %d %d (%d)",
455*7c478bd9Sstevel@tonic-gate pointer[1], pointer[2],
456*7c478bd9Sstevel@tonic-gate (int)((((unsigned int)pointer[1])<<8)|
457*7c478bd9Sstevel@tonic-gate ((unsigned int)pointer[2])));
458*7c478bd9Sstevel@tonic-gate if (length == 4) {
459*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " ?%d?", pointer[3]);
460*7c478bd9Sstevel@tonic-gate break;
461*7c478bd9Sstevel@tonic-gate }
462*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " %d %d (%d)",
463*7c478bd9Sstevel@tonic-gate pointer[3], pointer[4],
464*7c478bd9Sstevel@tonic-gate (int)((((unsigned int)pointer[3])<<8)|
465*7c478bd9Sstevel@tonic-gate ((unsigned int)pointer[4])));
466*7c478bd9Sstevel@tonic-gate for (i = 5; i < length; i++)
467*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " ?%d?", pointer[i]);
468*7c478bd9Sstevel@tonic-gate break;
469*7c478bd9Sstevel@tonic-gate
470*7c478bd9Sstevel@tonic-gate case TELOPT_AUTHENTICATION:
471*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "AUTHENTICATION");
472*7c478bd9Sstevel@tonic-gate if (length < 2) {
473*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace,
474*7c478bd9Sstevel@tonic-gate " (empty suboption??\?)");
475*7c478bd9Sstevel@tonic-gate break;
476*7c478bd9Sstevel@tonic-gate }
477*7c478bd9Sstevel@tonic-gate switch (pointer[1]) {
478*7c478bd9Sstevel@tonic-gate case TELQUAL_REPLY:
479*7c478bd9Sstevel@tonic-gate case TELQUAL_IS:
480*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " %s ",
481*7c478bd9Sstevel@tonic-gate (pointer[1] == TELQUAL_IS) ?
482*7c478bd9Sstevel@tonic-gate "IS" : "REPLY");
483*7c478bd9Sstevel@tonic-gate if (AUTHTYPE_NAME_OK(pointer[2]))
484*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%s ",
485*7c478bd9Sstevel@tonic-gate AUTHTYPE_NAME(pointer[2]));
486*7c478bd9Sstevel@tonic-gate else
487*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%d ",
488*7c478bd9Sstevel@tonic-gate pointer[2]);
489*7c478bd9Sstevel@tonic-gate if (length < 3) {
490*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace,
491*7c478bd9Sstevel@tonic-gate "(partial suboption??\?)");
492*7c478bd9Sstevel@tonic-gate break;
493*7c478bd9Sstevel@tonic-gate }
494*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%s|%s",
495*7c478bd9Sstevel@tonic-gate ((pointer[3] & AUTH_WHO_MASK) ==
496*7c478bd9Sstevel@tonic-gate AUTH_WHO_CLIENT) ? "CLIENT" : "SERVER",
497*7c478bd9Sstevel@tonic-gate ((pointer[3] & AUTH_HOW_MASK) ==
498*7c478bd9Sstevel@tonic-gate AUTH_HOW_MUTUAL) ? "MUTUAL" : "ONE-WAY");
499*7c478bd9Sstevel@tonic-gate
500*7c478bd9Sstevel@tonic-gate auth_printsub(&pointer[1], length - 1,
501*7c478bd9Sstevel@tonic-gate (uchar_t *)buf, sizeof (buf));
502*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%s", buf);
503*7c478bd9Sstevel@tonic-gate break;
504*7c478bd9Sstevel@tonic-gate
505*7c478bd9Sstevel@tonic-gate case TELQUAL_SEND:
506*7c478bd9Sstevel@tonic-gate i = 2;
507*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " SEND ");
508*7c478bd9Sstevel@tonic-gate while (i < length) {
509*7c478bd9Sstevel@tonic-gate if (AUTHTYPE_NAME_OK(pointer[i]))
510*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%s ",
511*7c478bd9Sstevel@tonic-gate AUTHTYPE_NAME(pointer[i]));
512*7c478bd9Sstevel@tonic-gate else
513*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%d ",
514*7c478bd9Sstevel@tonic-gate pointer[i]);
515*7c478bd9Sstevel@tonic-gate if (++i >= length) {
516*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace,
517*7c478bd9Sstevel@tonic-gate "(partial "
518*7c478bd9Sstevel@tonic-gate "suboption??\?)");
519*7c478bd9Sstevel@tonic-gate break;
520*7c478bd9Sstevel@tonic-gate }
521*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%s|%s ",
522*7c478bd9Sstevel@tonic-gate ((pointer[i] & AUTH_WHO_MASK) ==
523*7c478bd9Sstevel@tonic-gate AUTH_WHO_CLIENT) ?
524*7c478bd9Sstevel@tonic-gate "CLIENT" : "SERVER",
525*7c478bd9Sstevel@tonic-gate ((pointer[i] & AUTH_HOW_MASK) ==
526*7c478bd9Sstevel@tonic-gate AUTH_HOW_MUTUAL) ?
527*7c478bd9Sstevel@tonic-gate "MUTUAL" : "ONE-WAY");
528*7c478bd9Sstevel@tonic-gate ++i;
529*7c478bd9Sstevel@tonic-gate }
530*7c478bd9Sstevel@tonic-gate break;
531*7c478bd9Sstevel@tonic-gate
532*7c478bd9Sstevel@tonic-gate case TELQUAL_NAME:
533*7c478bd9Sstevel@tonic-gate i = 2;
534*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " NAME \"");
535*7c478bd9Sstevel@tonic-gate while (i < length)
536*7c478bd9Sstevel@tonic-gate (void) putc(pointer[i++], NetTrace);
537*7c478bd9Sstevel@tonic-gate (void) putc('"', NetTrace);
538*7c478bd9Sstevel@tonic-gate break;
539*7c478bd9Sstevel@tonic-gate
540*7c478bd9Sstevel@tonic-gate default:
541*7c478bd9Sstevel@tonic-gate for (i = 2; i < length; i++)
542*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " ?%d?", pointer[i]);
543*7c478bd9Sstevel@tonic-gate break;
544*7c478bd9Sstevel@tonic-gate }
545*7c478bd9Sstevel@tonic-gate break;
546*7c478bd9Sstevel@tonic-gate
547*7c478bd9Sstevel@tonic-gate case TELOPT_ENCRYPT:
548*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "ENCRYPT");
549*7c478bd9Sstevel@tonic-gate if (length < 2) {
550*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace,
551*7c478bd9Sstevel@tonic-gate " (empty suboption??\?)");
552*7c478bd9Sstevel@tonic-gate break;
553*7c478bd9Sstevel@tonic-gate }
554*7c478bd9Sstevel@tonic-gate switch (pointer[1]) {
555*7c478bd9Sstevel@tonic-gate case ENCRYPT_START:
556*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " START");
557*7c478bd9Sstevel@tonic-gate break;
558*7c478bd9Sstevel@tonic-gate
559*7c478bd9Sstevel@tonic-gate case ENCRYPT_END:
560*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " END");
561*7c478bd9Sstevel@tonic-gate break;
562*7c478bd9Sstevel@tonic-gate
563*7c478bd9Sstevel@tonic-gate case ENCRYPT_REQSTART:
564*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " REQUEST-START");
565*7c478bd9Sstevel@tonic-gate break;
566*7c478bd9Sstevel@tonic-gate
567*7c478bd9Sstevel@tonic-gate case ENCRYPT_REQEND:
568*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " REQUEST-END");
569*7c478bd9Sstevel@tonic-gate break;
570*7c478bd9Sstevel@tonic-gate
571*7c478bd9Sstevel@tonic-gate case ENCRYPT_IS:
572*7c478bd9Sstevel@tonic-gate case ENCRYPT_REPLY:
573*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " %s ",
574*7c478bd9Sstevel@tonic-gate (pointer[1] == ENCRYPT_IS) ?
575*7c478bd9Sstevel@tonic-gate "IS" : "REPLY");
576*7c478bd9Sstevel@tonic-gate if (length < 3) {
577*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " (partial "
578*7c478bd9Sstevel@tonic-gate "suboption??\?)");
579*7c478bd9Sstevel@tonic-gate break;
580*7c478bd9Sstevel@tonic-gate }
581*7c478bd9Sstevel@tonic-gate if (ENCTYPE_NAME_OK(pointer[2]))
582*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%s ",
583*7c478bd9Sstevel@tonic-gate ENCTYPE_NAME(pointer[2]));
584*7c478bd9Sstevel@tonic-gate else
585*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace,
586*7c478bd9Sstevel@tonic-gate " %d (unknown)", pointer[2]);
587*7c478bd9Sstevel@tonic-gate
588*7c478bd9Sstevel@tonic-gate encrypt_printsub(&pointer[1], length - 1,
589*7c478bd9Sstevel@tonic-gate (uchar_t *)buf, sizeof (buf));
590*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%s", buf);
591*7c478bd9Sstevel@tonic-gate break;
592*7c478bd9Sstevel@tonic-gate
593*7c478bd9Sstevel@tonic-gate case ENCRYPT_SUPPORT:
594*7c478bd9Sstevel@tonic-gate i = 2;
595*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " SUPPORT ");
596*7c478bd9Sstevel@tonic-gate while (i < length) {
597*7c478bd9Sstevel@tonic-gate if (ENCTYPE_NAME_OK(pointer[i]))
598*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%s ",
599*7c478bd9Sstevel@tonic-gate ENCTYPE_NAME(pointer[i]));
600*7c478bd9Sstevel@tonic-gate else
601*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%d ",
602*7c478bd9Sstevel@tonic-gate pointer[i]);
603*7c478bd9Sstevel@tonic-gate i++;
604*7c478bd9Sstevel@tonic-gate }
605*7c478bd9Sstevel@tonic-gate break;
606*7c478bd9Sstevel@tonic-gate
607*7c478bd9Sstevel@tonic-gate case ENCRYPT_ENC_KEYID:
608*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " ENC_KEYID ");
609*7c478bd9Sstevel@tonic-gate goto encommon;
610*7c478bd9Sstevel@tonic-gate
611*7c478bd9Sstevel@tonic-gate case ENCRYPT_DEC_KEYID:
612*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " DEC_KEYID ");
613*7c478bd9Sstevel@tonic-gate goto encommon;
614*7c478bd9Sstevel@tonic-gate
615*7c478bd9Sstevel@tonic-gate default:
616*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " %d (unknown)",
617*7c478bd9Sstevel@tonic-gate pointer[1]);
618*7c478bd9Sstevel@tonic-gate encommon:
619*7c478bd9Sstevel@tonic-gate for (i = 2; i < length; i++)
620*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " %d",
621*7c478bd9Sstevel@tonic-gate pointer[i]);
622*7c478bd9Sstevel@tonic-gate break;
623*7c478bd9Sstevel@tonic-gate }
624*7c478bd9Sstevel@tonic-gate break;
625*7c478bd9Sstevel@tonic-gate
626*7c478bd9Sstevel@tonic-gate case TELOPT_LINEMODE:
627*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "LINEMODE ");
628*7c478bd9Sstevel@tonic-gate if (length < 2) {
629*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace,
630*7c478bd9Sstevel@tonic-gate " (empty suboption??\?)");
631*7c478bd9Sstevel@tonic-gate break;
632*7c478bd9Sstevel@tonic-gate }
633*7c478bd9Sstevel@tonic-gate switch (pointer[1]) {
634*7c478bd9Sstevel@tonic-gate case WILL:
635*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "WILL ");
636*7c478bd9Sstevel@tonic-gate goto common;
637*7c478bd9Sstevel@tonic-gate case WONT:
638*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "WONT ");
639*7c478bd9Sstevel@tonic-gate goto common;
640*7c478bd9Sstevel@tonic-gate case DO:
641*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "DO ");
642*7c478bd9Sstevel@tonic-gate goto common;
643*7c478bd9Sstevel@tonic-gate case DONT:
644*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "DONT ");
645*7c478bd9Sstevel@tonic-gate common:
646*7c478bd9Sstevel@tonic-gate if (length < 3) {
647*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace,
648*7c478bd9Sstevel@tonic-gate "(no option??\?)");
649*7c478bd9Sstevel@tonic-gate break;
650*7c478bd9Sstevel@tonic-gate }
651*7c478bd9Sstevel@tonic-gate switch (pointer[2]) {
652*7c478bd9Sstevel@tonic-gate case LM_FORWARDMASK:
653*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace,
654*7c478bd9Sstevel@tonic-gate "Forward Mask");
655*7c478bd9Sstevel@tonic-gate for (i = 3; i < length; i++)
656*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " %x",
657*7c478bd9Sstevel@tonic-gate pointer[i]);
658*7c478bd9Sstevel@tonic-gate break;
659*7c478bd9Sstevel@tonic-gate default:
660*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%d (unknown)",
661*7c478bd9Sstevel@tonic-gate pointer[2]);
662*7c478bd9Sstevel@tonic-gate for (i = 3; i < length; i++)
663*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace,
664*7c478bd9Sstevel@tonic-gate " %d", pointer[i]);
665*7c478bd9Sstevel@tonic-gate break;
666*7c478bd9Sstevel@tonic-gate }
667*7c478bd9Sstevel@tonic-gate break;
668*7c478bd9Sstevel@tonic-gate
669*7c478bd9Sstevel@tonic-gate case LM_SLC:
670*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "SLC");
671*7c478bd9Sstevel@tonic-gate for (i = 2; i < length - 2; i += 3) {
672*7c478bd9Sstevel@tonic-gate if (SLC_NAME_OK(pointer[i+SLC_FUNC]))
673*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " %s",
674*7c478bd9Sstevel@tonic-gate SLC_NAME(pointer[
675*7c478bd9Sstevel@tonic-gate i+SLC_FUNC]));
676*7c478bd9Sstevel@tonic-gate else
677*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " %d",
678*7c478bd9Sstevel@tonic-gate pointer[i+SLC_FUNC]);
679*7c478bd9Sstevel@tonic-gate switch (pointer[i+SLC_FLAGS] &
680*7c478bd9Sstevel@tonic-gate SLC_LEVELBITS) {
681*7c478bd9Sstevel@tonic-gate case SLC_NOSUPPORT:
682*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace,
683*7c478bd9Sstevel@tonic-gate " NOSUPPORT");
684*7c478bd9Sstevel@tonic-gate break;
685*7c478bd9Sstevel@tonic-gate case SLC_CANTCHANGE:
686*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace,
687*7c478bd9Sstevel@tonic-gate " CANTCHANGE");
688*7c478bd9Sstevel@tonic-gate break;
689*7c478bd9Sstevel@tonic-gate case SLC_VARIABLE:
690*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace,
691*7c478bd9Sstevel@tonic-gate " VARIABLE");
692*7c478bd9Sstevel@tonic-gate break;
693*7c478bd9Sstevel@tonic-gate case SLC_DEFAULT:
694*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace,
695*7c478bd9Sstevel@tonic-gate " DEFAULT");
696*7c478bd9Sstevel@tonic-gate break;
697*7c478bd9Sstevel@tonic-gate }
698*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%s%s%s",
699*7c478bd9Sstevel@tonic-gate pointer[i+SLC_FLAGS]&SLC_ACK ?
700*7c478bd9Sstevel@tonic-gate "|ACK" : "",
701*7c478bd9Sstevel@tonic-gate pointer[i+SLC_FLAGS]&SLC_FLUSHIN ?
702*7c478bd9Sstevel@tonic-gate "|FLUSHIN" : "",
703*7c478bd9Sstevel@tonic-gate pointer[i+SLC_FLAGS]&SLC_FLUSHOUT ?
704*7c478bd9Sstevel@tonic-gate "|FLUSHOUT" : "");
705*7c478bd9Sstevel@tonic-gate if (pointer[i+SLC_FLAGS] &
706*7c478bd9Sstevel@tonic-gate ~(SLC_ACK|SLC_FLUSHIN|
707*7c478bd9Sstevel@tonic-gate SLC_FLUSHOUT| SLC_LEVELBITS))
708*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "(0x%x)",
709*7c478bd9Sstevel@tonic-gate pointer[i+SLC_FLAGS]);
710*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " %d;",
711*7c478bd9Sstevel@tonic-gate pointer[i+SLC_VALUE]);
712*7c478bd9Sstevel@tonic-gate if ((pointer[i+SLC_VALUE] == IAC) &&
713*7c478bd9Sstevel@tonic-gate (pointer[i+SLC_VALUE+1] == IAC))
714*7c478bd9Sstevel@tonic-gate i++;
715*7c478bd9Sstevel@tonic-gate }
716*7c478bd9Sstevel@tonic-gate for (; i < length; i++)
717*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " ?%d?",
718*7c478bd9Sstevel@tonic-gate pointer[i]);
719*7c478bd9Sstevel@tonic-gate break;
720*7c478bd9Sstevel@tonic-gate
721*7c478bd9Sstevel@tonic-gate case LM_MODE:
722*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "MODE ");
723*7c478bd9Sstevel@tonic-gate if (length < 3) {
724*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace,
725*7c478bd9Sstevel@tonic-gate "(no mode??\?)");
726*7c478bd9Sstevel@tonic-gate break;
727*7c478bd9Sstevel@tonic-gate }
728*7c478bd9Sstevel@tonic-gate {
729*7c478bd9Sstevel@tonic-gate char tbuf[64];
730*7c478bd9Sstevel@tonic-gate (void) sprintf(tbuf, "%s%s%s%s%s",
731*7c478bd9Sstevel@tonic-gate pointer[2]&MODE_EDIT ? "|EDIT" : "",
732*7c478bd9Sstevel@tonic-gate pointer[2]&MODE_TRAPSIG ?
733*7c478bd9Sstevel@tonic-gate "|TRAPSIG" : "",
734*7c478bd9Sstevel@tonic-gate pointer[2]&MODE_SOFT_TAB ?
735*7c478bd9Sstevel@tonic-gate "|SOFT_TAB" : "",
736*7c478bd9Sstevel@tonic-gate pointer[2]&MODE_LIT_ECHO ?
737*7c478bd9Sstevel@tonic-gate "|LIT_ECHO" : "",
738*7c478bd9Sstevel@tonic-gate pointer[2]&MODE_ACK ? "|ACK" : "");
739*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%s", tbuf[1] ?
740*7c478bd9Sstevel@tonic-gate &tbuf[1] : "0");
741*7c478bd9Sstevel@tonic-gate }
742*7c478bd9Sstevel@tonic-gate if (pointer[2]&~(MODE_MASK))
743*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " (0x%x)",
744*7c478bd9Sstevel@tonic-gate pointer[2]);
745*7c478bd9Sstevel@tonic-gate for (i = 3; i < length; i++)
746*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " ?0x%x?",
747*7c478bd9Sstevel@tonic-gate pointer[i]);
748*7c478bd9Sstevel@tonic-gate break;
749*7c478bd9Sstevel@tonic-gate default:
750*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%d (unknown)",
751*7c478bd9Sstevel@tonic-gate pointer[1]);
752*7c478bd9Sstevel@tonic-gate for (i = 2; i < length; i++)
753*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " %d",
754*7c478bd9Sstevel@tonic-gate pointer[i]);
755*7c478bd9Sstevel@tonic-gate }
756*7c478bd9Sstevel@tonic-gate break;
757*7c478bd9Sstevel@tonic-gate
758*7c478bd9Sstevel@tonic-gate case TELOPT_STATUS: {
759*7c478bd9Sstevel@tonic-gate register char *cp;
760*7c478bd9Sstevel@tonic-gate register int j, k;
761*7c478bd9Sstevel@tonic-gate
762*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "STATUS");
763*7c478bd9Sstevel@tonic-gate
764*7c478bd9Sstevel@tonic-gate switch (pointer[1]) {
765*7c478bd9Sstevel@tonic-gate default:
766*7c478bd9Sstevel@tonic-gate if (pointer[1] == TELQUAL_SEND)
767*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace,
768*7c478bd9Sstevel@tonic-gate " SEND");
769*7c478bd9Sstevel@tonic-gate else
770*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace,
771*7c478bd9Sstevel@tonic-gate " %d (unknown)",
772*7c478bd9Sstevel@tonic-gate pointer[1]);
773*7c478bd9Sstevel@tonic-gate for (i = 2; i < length; i++)
774*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " ?%d?",
775*7c478bd9Sstevel@tonic-gate pointer[i]);
776*7c478bd9Sstevel@tonic-gate break;
777*7c478bd9Sstevel@tonic-gate case TELQUAL_IS:
778*7c478bd9Sstevel@tonic-gate if (--want_status_response < 0)
779*7c478bd9Sstevel@tonic-gate want_status_response = 0;
780*7c478bd9Sstevel@tonic-gate if (NetTrace == stdout)
781*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace,
782*7c478bd9Sstevel@tonic-gate " IS\r\n");
783*7c478bd9Sstevel@tonic-gate else
784*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace,
785*7c478bd9Sstevel@tonic-gate " IS\n");
786*7c478bd9Sstevel@tonic-gate
787*7c478bd9Sstevel@tonic-gate for (i = 2; i < length; i++) {
788*7c478bd9Sstevel@tonic-gate switch (pointer[i]) {
789*7c478bd9Sstevel@tonic-gate case DO:
790*7c478bd9Sstevel@tonic-gate cp = "DO";
791*7c478bd9Sstevel@tonic-gate goto common2;
792*7c478bd9Sstevel@tonic-gate case DONT:
793*7c478bd9Sstevel@tonic-gate cp = "DONT";
794*7c478bd9Sstevel@tonic-gate goto common2;
795*7c478bd9Sstevel@tonic-gate case WILL:
796*7c478bd9Sstevel@tonic-gate cp = "WILL";
797*7c478bd9Sstevel@tonic-gate goto common2;
798*7c478bd9Sstevel@tonic-gate case WONT:
799*7c478bd9Sstevel@tonic-gate cp = "WONT";
800*7c478bd9Sstevel@tonic-gate goto common2;
801*7c478bd9Sstevel@tonic-gate common2:
802*7c478bd9Sstevel@tonic-gate i++;
803*7c478bd9Sstevel@tonic-gate if (TELOPT_OK(
804*7c478bd9Sstevel@tonic-gate (int)pointer[i]))
805*7c478bd9Sstevel@tonic-gate (void) fprintf(
806*7c478bd9Sstevel@tonic-gate NetTrace,
807*7c478bd9Sstevel@tonic-gate " %s %s",
808*7c478bd9Sstevel@tonic-gate cp,
809*7c478bd9Sstevel@tonic-gate TELOPT(
810*7c478bd9Sstevel@tonic-gate pointer[
811*7c478bd9Sstevel@tonic-gate i]));
812*7c478bd9Sstevel@tonic-gate else
813*7c478bd9Sstevel@tonic-gate (void) fprintf(
814*7c478bd9Sstevel@tonic-gate NetTrace,
815*7c478bd9Sstevel@tonic-gate " %s %d",
816*7c478bd9Sstevel@tonic-gate cp,
817*7c478bd9Sstevel@tonic-gate pointer[i]);
818*7c478bd9Sstevel@tonic-gate
819*7c478bd9Sstevel@tonic-gate if (NetTrace == stdout)
820*7c478bd9Sstevel@tonic-gate (void) fprintf(
821*7c478bd9Sstevel@tonic-gate NetTrace,
822*7c478bd9Sstevel@tonic-gate "\r\n");
823*7c478bd9Sstevel@tonic-gate else
824*7c478bd9Sstevel@tonic-gate (void) fprintf(
825*7c478bd9Sstevel@tonic-gate NetTrace,
826*7c478bd9Sstevel@tonic-gate "\n");
827*7c478bd9Sstevel@tonic-gate break;
828*7c478bd9Sstevel@tonic-gate
829*7c478bd9Sstevel@tonic-gate case SB:
830*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace,
831*7c478bd9Sstevel@tonic-gate " SB ");
832*7c478bd9Sstevel@tonic-gate i++;
833*7c478bd9Sstevel@tonic-gate j = k = i;
834*7c478bd9Sstevel@tonic-gate while (j < length) {
835*7c478bd9Sstevel@tonic-gate if (pointer[j] == SE) {
836*7c478bd9Sstevel@tonic-gate if (j+1 == length)
837*7c478bd9Sstevel@tonic-gate break;
838*7c478bd9Sstevel@tonic-gate if (pointer[j+1] == SE)
839*7c478bd9Sstevel@tonic-gate j++;
840*7c478bd9Sstevel@tonic-gate else
841*7c478bd9Sstevel@tonic-gate break;
842*7c478bd9Sstevel@tonic-gate }
843*7c478bd9Sstevel@tonic-gate pointer[k++] = pointer[j++];
844*7c478bd9Sstevel@tonic-gate }
845*7c478bd9Sstevel@tonic-gate printsub(0,
846*7c478bd9Sstevel@tonic-gate &pointer[i], k - i);
847*7c478bd9Sstevel@tonic-gate if (i < length) {
848*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " SE");
849*7c478bd9Sstevel@tonic-gate i = j;
850*7c478bd9Sstevel@tonic-gate } else
851*7c478bd9Sstevel@tonic-gate i = j - 1;
852*7c478bd9Sstevel@tonic-gate
853*7c478bd9Sstevel@tonic-gate if (NetTrace == stdout)
854*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "\r\n");
855*7c478bd9Sstevel@tonic-gate else
856*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "\n");
857*7c478bd9Sstevel@tonic-gate
858*7c478bd9Sstevel@tonic-gate break;
859*7c478bd9Sstevel@tonic-gate
860*7c478bd9Sstevel@tonic-gate default:
861*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace,
862*7c478bd9Sstevel@tonic-gate " %d", pointer[i]);
863*7c478bd9Sstevel@tonic-gate break;
864*7c478bd9Sstevel@tonic-gate }
865*7c478bd9Sstevel@tonic-gate }
866*7c478bd9Sstevel@tonic-gate break;
867*7c478bd9Sstevel@tonic-gate }
868*7c478bd9Sstevel@tonic-gate break;
869*7c478bd9Sstevel@tonic-gate }
870*7c478bd9Sstevel@tonic-gate
871*7c478bd9Sstevel@tonic-gate case TELOPT_XDISPLOC:
872*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "X-DISPLAY-LOCATION ");
873*7c478bd9Sstevel@tonic-gate switch (pointer[1]) {
874*7c478bd9Sstevel@tonic-gate case TELQUAL_IS:
875*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "IS \"%.*s\"",
876*7c478bd9Sstevel@tonic-gate length-2, (char *)pointer+2);
877*7c478bd9Sstevel@tonic-gate break;
878*7c478bd9Sstevel@tonic-gate case TELQUAL_SEND:
879*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "SEND");
880*7c478bd9Sstevel@tonic-gate break;
881*7c478bd9Sstevel@tonic-gate default:
882*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace,
883*7c478bd9Sstevel@tonic-gate "- unknown qualifier %d (0x%x).",
884*7c478bd9Sstevel@tonic-gate pointer[1], pointer[1]);
885*7c478bd9Sstevel@tonic-gate }
886*7c478bd9Sstevel@tonic-gate break;
887*7c478bd9Sstevel@tonic-gate
888*7c478bd9Sstevel@tonic-gate case TELOPT_NEW_ENVIRON:
889*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "NEW-ENVIRON ");
890*7c478bd9Sstevel@tonic-gate #ifdef OLD_ENVIRON
891*7c478bd9Sstevel@tonic-gate goto env_common1;
892*7c478bd9Sstevel@tonic-gate case TELOPT_OLD_ENVIRON:
893*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "OLD-ENVIRON ");
894*7c478bd9Sstevel@tonic-gate env_common1:
895*7c478bd9Sstevel@tonic-gate #endif
896*7c478bd9Sstevel@tonic-gate switch (pointer[1]) {
897*7c478bd9Sstevel@tonic-gate case TELQUAL_IS:
898*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "IS ");
899*7c478bd9Sstevel@tonic-gate goto env_common;
900*7c478bd9Sstevel@tonic-gate case TELQUAL_SEND:
901*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "SEND ");
902*7c478bd9Sstevel@tonic-gate goto env_common;
903*7c478bd9Sstevel@tonic-gate case TELQUAL_INFO:
904*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "INFO ");
905*7c478bd9Sstevel@tonic-gate env_common:
906*7c478bd9Sstevel@tonic-gate {
907*7c478bd9Sstevel@tonic-gate register int noquote = 2;
908*7c478bd9Sstevel@tonic-gate #if defined(ENV_HACK) && defined(OLD_ENVIRON)
909*7c478bd9Sstevel@tonic-gate extern int old_env_var, old_env_value;
910*7c478bd9Sstevel@tonic-gate #endif
911*7c478bd9Sstevel@tonic-gate for (i = 2; i < length; i++) {
912*7c478bd9Sstevel@tonic-gate switch (pointer[i]) {
913*7c478bd9Sstevel@tonic-gate case NEW_ENV_VALUE:
914*7c478bd9Sstevel@tonic-gate #ifdef OLD_ENVIRON
915*7c478bd9Sstevel@tonic-gate /* case NEW_ENV_OVAR: */
916*7c478bd9Sstevel@tonic-gate if (pointer[0] == TELOPT_OLD_ENVIRON) {
917*7c478bd9Sstevel@tonic-gate #ifdef ENV_HACK
918*7c478bd9Sstevel@tonic-gate if (old_env_var == OLD_ENV_VALUE)
919*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace,
920*7c478bd9Sstevel@tonic-gate "\" (VALUE) " + noquote);
921*7c478bd9Sstevel@tonic-gate else
922*7c478bd9Sstevel@tonic-gate #endif
923*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace,
924*7c478bd9Sstevel@tonic-gate "\" VAR " + noquote);
925*7c478bd9Sstevel@tonic-gate } else
926*7c478bd9Sstevel@tonic-gate #endif /* OLD_ENVIRON */
927*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "\" VALUE " + noquote);
928*7c478bd9Sstevel@tonic-gate noquote = 2;
929*7c478bd9Sstevel@tonic-gate break;
930*7c478bd9Sstevel@tonic-gate
931*7c478bd9Sstevel@tonic-gate case NEW_ENV_VAR:
932*7c478bd9Sstevel@tonic-gate #ifdef OLD_ENVIRON
933*7c478bd9Sstevel@tonic-gate /* case OLD_ENV_VALUE: */
934*7c478bd9Sstevel@tonic-gate if (pointer[0] == TELOPT_OLD_ENVIRON) {
935*7c478bd9Sstevel@tonic-gate #ifdef ENV_HACK
936*7c478bd9Sstevel@tonic-gate if (old_env_value == OLD_ENV_VAR)
937*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace,
938*7c478bd9Sstevel@tonic-gate "\" (VAR) " + noquote);
939*7c478bd9Sstevel@tonic-gate else
940*7c478bd9Sstevel@tonic-gate #endif
941*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace,
942*7c478bd9Sstevel@tonic-gate "\" VALUE " + noquote);
943*7c478bd9Sstevel@tonic-gate } else
944*7c478bd9Sstevel@tonic-gate #endif /* OLD_ENVIRON */
945*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "\" VAR " + noquote);
946*7c478bd9Sstevel@tonic-gate noquote = 2;
947*7c478bd9Sstevel@tonic-gate break;
948*7c478bd9Sstevel@tonic-gate
949*7c478bd9Sstevel@tonic-gate case ENV_ESC:
950*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "\" ESC " + noquote);
951*7c478bd9Sstevel@tonic-gate noquote = 2;
952*7c478bd9Sstevel@tonic-gate break;
953*7c478bd9Sstevel@tonic-gate
954*7c478bd9Sstevel@tonic-gate case ENV_USERVAR:
955*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "\" USERVAR " + noquote);
956*7c478bd9Sstevel@tonic-gate noquote = 2;
957*7c478bd9Sstevel@tonic-gate break;
958*7c478bd9Sstevel@tonic-gate
959*7c478bd9Sstevel@tonic-gate default:
960*7c478bd9Sstevel@tonic-gate def_case:
961*7c478bd9Sstevel@tonic-gate if (isprint(pointer[i]) && pointer[i] != '"') {
962*7c478bd9Sstevel@tonic-gate if (noquote) {
963*7c478bd9Sstevel@tonic-gate (void) putc('"', NetTrace);
964*7c478bd9Sstevel@tonic-gate noquote = 0;
965*7c478bd9Sstevel@tonic-gate }
966*7c478bd9Sstevel@tonic-gate (void) putc(pointer[i], NetTrace);
967*7c478bd9Sstevel@tonic-gate } else {
968*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "\" %03o " + noquote,
969*7c478bd9Sstevel@tonic-gate pointer[i]);
970*7c478bd9Sstevel@tonic-gate noquote = 2;
971*7c478bd9Sstevel@tonic-gate }
972*7c478bd9Sstevel@tonic-gate break;
973*7c478bd9Sstevel@tonic-gate }
974*7c478bd9Sstevel@tonic-gate }
975*7c478bd9Sstevel@tonic-gate if (!noquote)
976*7c478bd9Sstevel@tonic-gate (void) putc('"', NetTrace);
977*7c478bd9Sstevel@tonic-gate break;
978*7c478bd9Sstevel@tonic-gate }
979*7c478bd9Sstevel@tonic-gate }
980*7c478bd9Sstevel@tonic-gate break;
981*7c478bd9Sstevel@tonic-gate
982*7c478bd9Sstevel@tonic-gate default:
983*7c478bd9Sstevel@tonic-gate if (TELOPT_OK(pointer[0]))
984*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%s (unknown)", TELOPT(pointer[0]));
985*7c478bd9Sstevel@tonic-gate else
986*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%d (unknown)", pointer[0]);
987*7c478bd9Sstevel@tonic-gate for (i = 1; i < length; i++)
988*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " %d", pointer[i]);
989*7c478bd9Sstevel@tonic-gate break;
990*7c478bd9Sstevel@tonic-gate }
991*7c478bd9Sstevel@tonic-gate if (direction) {
992*7c478bd9Sstevel@tonic-gate if (NetTrace == stdout)
993*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "\r\n");
994*7c478bd9Sstevel@tonic-gate else
995*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "\n");
996*7c478bd9Sstevel@tonic-gate }
997*7c478bd9Sstevel@tonic-gate if (NetTrace == stdout)
998*7c478bd9Sstevel@tonic-gate (void) fflush(NetTrace);
999*7c478bd9Sstevel@tonic-gate }
1000*7c478bd9Sstevel@tonic-gate }
1001*7c478bd9Sstevel@tonic-gate
1002*7c478bd9Sstevel@tonic-gate /*
1003*7c478bd9Sstevel@tonic-gate * EmptyTerminal - called to make sure that the terminal buffer is empty.
1004*7c478bd9Sstevel@tonic-gate * Note that we consider the buffer to run all the
1005*7c478bd9Sstevel@tonic-gate * way to the kernel (thus the select).
1006*7c478bd9Sstevel@tonic-gate */
1007*7c478bd9Sstevel@tonic-gate
1008*7c478bd9Sstevel@tonic-gate static void
EmptyTerminal()1009*7c478bd9Sstevel@tonic-gate EmptyTerminal()
1010*7c478bd9Sstevel@tonic-gate {
1011*7c478bd9Sstevel@tonic-gate fd_set o;
1012*7c478bd9Sstevel@tonic-gate
1013*7c478bd9Sstevel@tonic-gate FD_ZERO(&o);
1014*7c478bd9Sstevel@tonic-gate
1015*7c478bd9Sstevel@tonic-gate if (TTYBYTES() == 0) {
1016*7c478bd9Sstevel@tonic-gate FD_SET(tout, &o);
1017*7c478bd9Sstevel@tonic-gate /* wait for TTLOWAT */
1018*7c478bd9Sstevel@tonic-gate (void) select(tout+1, NULL, &o, NULL, NULL);
1019*7c478bd9Sstevel@tonic-gate } else {
1020*7c478bd9Sstevel@tonic-gate while (TTYBYTES()) {
1021*7c478bd9Sstevel@tonic-gate if (ttyflush(0) == -2) {
1022*7c478bd9Sstevel@tonic-gate /* This will not return. */
1023*7c478bd9Sstevel@tonic-gate fatal_tty_error("write");
1024*7c478bd9Sstevel@tonic-gate }
1025*7c478bd9Sstevel@tonic-gate FD_SET(tout, &o);
1026*7c478bd9Sstevel@tonic-gate /* wait for TTLOWAT */
1027*7c478bd9Sstevel@tonic-gate (void) select(tout+1, NULL, &o, NULL, NULL);
1028*7c478bd9Sstevel@tonic-gate }
1029*7c478bd9Sstevel@tonic-gate }
1030*7c478bd9Sstevel@tonic-gate }
1031*7c478bd9Sstevel@tonic-gate
1032*7c478bd9Sstevel@tonic-gate static void
SetForExit()1033*7c478bd9Sstevel@tonic-gate SetForExit()
1034*7c478bd9Sstevel@tonic-gate {
1035*7c478bd9Sstevel@tonic-gate setconnmode(0);
1036*7c478bd9Sstevel@tonic-gate do {
1037*7c478bd9Sstevel@tonic-gate (void) telrcv(); /* Process any incoming data */
1038*7c478bd9Sstevel@tonic-gate EmptyTerminal();
1039*7c478bd9Sstevel@tonic-gate } while (ring_full_count(&netiring)); /* While there is any */
1040*7c478bd9Sstevel@tonic-gate setcommandmode();
1041*7c478bd9Sstevel@tonic-gate (void) fflush(stdout);
1042*7c478bd9Sstevel@tonic-gate (void) fflush(stderr);
1043*7c478bd9Sstevel@tonic-gate setconnmode(0);
1044*7c478bd9Sstevel@tonic-gate EmptyTerminal(); /* Flush the path to the tty */
1045*7c478bd9Sstevel@tonic-gate setcommandmode();
1046*7c478bd9Sstevel@tonic-gate }
1047*7c478bd9Sstevel@tonic-gate
1048*7c478bd9Sstevel@tonic-gate void
Exit(returnCode)1049*7c478bd9Sstevel@tonic-gate Exit(returnCode)
1050*7c478bd9Sstevel@tonic-gate int returnCode;
1051*7c478bd9Sstevel@tonic-gate {
1052*7c478bd9Sstevel@tonic-gate SetForExit();
1053*7c478bd9Sstevel@tonic-gate exit(returnCode);
1054*7c478bd9Sstevel@tonic-gate }
1055*7c478bd9Sstevel@tonic-gate
1056*7c478bd9Sstevel@tonic-gate void
ExitString(string,returnCode)1057*7c478bd9Sstevel@tonic-gate ExitString(string, returnCode)
1058*7c478bd9Sstevel@tonic-gate char *string;
1059*7c478bd9Sstevel@tonic-gate int returnCode;
1060*7c478bd9Sstevel@tonic-gate {
1061*7c478bd9Sstevel@tonic-gate SetForExit();
1062*7c478bd9Sstevel@tonic-gate (void) fwrite(string, 1, strlen(string), stderr);
1063*7c478bd9Sstevel@tonic-gate exit(returnCode);
1064*7c478bd9Sstevel@tonic-gate }
1065*7c478bd9Sstevel@tonic-gate
1066*7c478bd9Sstevel@tonic-gate #define BUFFER_CHUNK_SIZE 64
1067*7c478bd9Sstevel@tonic-gate
1068*7c478bd9Sstevel@tonic-gate /* Round up to a multiple of BUFFER_CHUNK_SIZE */
1069*7c478bd9Sstevel@tonic-gate #define ROUND_CHUNK_SIZE(s) ((((s) + BUFFER_CHUNK_SIZE - 1) / \
1070*7c478bd9Sstevel@tonic-gate BUFFER_CHUNK_SIZE) * BUFFER_CHUNK_SIZE)
1071*7c478bd9Sstevel@tonic-gate
1072*7c478bd9Sstevel@tonic-gate /*
1073*7c478bd9Sstevel@tonic-gate * Optionally allocate a buffer, and optionally read a string from a stream
1074*7c478bd9Sstevel@tonic-gate * into the buffer, starting at the given offset. If the buffer isn't
1075*7c478bd9Sstevel@tonic-gate * large enough for the given offset, or if buffer space is exhausted
1076*7c478bd9Sstevel@tonic-gate * when reading the string, the size of the buffer is increased.
1077*7c478bd9Sstevel@tonic-gate *
1078*7c478bd9Sstevel@tonic-gate * A buffer can be supplied when the function is called, passing the
1079*7c478bd9Sstevel@tonic-gate * buffer address via the first argument. The buffer size can be
1080*7c478bd9Sstevel@tonic-gate * passed as well, in the second argument. If the second argument is
1081*7c478bd9Sstevel@tonic-gate * NULL, the function makes no assumptions about the buffer size.
1082*7c478bd9Sstevel@tonic-gate * The address of the buffer is returned via the first argument, and the
1083*7c478bd9Sstevel@tonic-gate * buffer size via the second argument if this is not NULL.
1084*7c478bd9Sstevel@tonic-gate * These returned values may differ from the supplied values if the buffer
1085*7c478bd9Sstevel@tonic-gate * was reallocated.
1086*7c478bd9Sstevel@tonic-gate *
1087*7c478bd9Sstevel@tonic-gate * If no buffer is to be supplied, specify a buffer address of NULL, via
1088*7c478bd9Sstevel@tonic-gate * the first argument.
1089*7c478bd9Sstevel@tonic-gate *
1090*7c478bd9Sstevel@tonic-gate * If the pointer to the buffer address is NULL, the function just returns
1091*7c478bd9Sstevel@tonic-gate * NULL, and performs no other processing.
1092*7c478bd9Sstevel@tonic-gate *
1093*7c478bd9Sstevel@tonic-gate * If a NULL stream is passed, the function will just make sure the
1094*7c478bd9Sstevel@tonic-gate * supplied buffer is large enough to hold the supplied offset,
1095*7c478bd9Sstevel@tonic-gate * reallocating it if is too small or too large.
1096*7c478bd9Sstevel@tonic-gate *
1097*7c478bd9Sstevel@tonic-gate * The returned buffer will be a multiple of BUFFER_CHUNK_SIZE in size.
1098*7c478bd9Sstevel@tonic-gate *
1099*7c478bd9Sstevel@tonic-gate * The function stops reading from the stream when a newline is read,
1100*7c478bd9Sstevel@tonic-gate * end of file is reached, or an error occurs. The newline is not
1101*7c478bd9Sstevel@tonic-gate * returned in the buffer. The returned string will be NULL terminated.
1102*7c478bd9Sstevel@tonic-gate *
1103*7c478bd9Sstevel@tonic-gate * The function returns the address of the buffer if any characters
1104*7c478bd9Sstevel@tonic-gate * are read and no error occurred, otherwise it returns NULL.
1105*7c478bd9Sstevel@tonic-gate *
1106*7c478bd9Sstevel@tonic-gate * If the function returns NULL, a buffer may have been allocated. The
1107*7c478bd9Sstevel@tonic-gate * buffer address will be returned via the first argument, together with
1108*7c478bd9Sstevel@tonic-gate * the buffer size if the second argument is not NULL.
1109*7c478bd9Sstevel@tonic-gate *
1110*7c478bd9Sstevel@tonic-gate */
1111*7c478bd9Sstevel@tonic-gate static char *
GetStringAtOffset(bufp,cbufsiz,off,st)1112*7c478bd9Sstevel@tonic-gate GetStringAtOffset(bufp, cbufsiz, off, st)
1113*7c478bd9Sstevel@tonic-gate char **bufp;
1114*7c478bd9Sstevel@tonic-gate unsigned int *cbufsiz;
1115*7c478bd9Sstevel@tonic-gate unsigned int off;
1116*7c478bd9Sstevel@tonic-gate FILE *st;
1117*7c478bd9Sstevel@tonic-gate {
1118*7c478bd9Sstevel@tonic-gate unsigned int bufsiz;
1119*7c478bd9Sstevel@tonic-gate char *buf;
1120*7c478bd9Sstevel@tonic-gate char *nbuf;
1121*7c478bd9Sstevel@tonic-gate unsigned int idx = off;
1122*7c478bd9Sstevel@tonic-gate
1123*7c478bd9Sstevel@tonic-gate if (bufp == NULL)
1124*7c478bd9Sstevel@tonic-gate return (NULL);
1125*7c478bd9Sstevel@tonic-gate
1126*7c478bd9Sstevel@tonic-gate buf = *bufp;
1127*7c478bd9Sstevel@tonic-gate
1128*7c478bd9Sstevel@tonic-gate bufsiz = ROUND_CHUNK_SIZE(off + 1);
1129*7c478bd9Sstevel@tonic-gate
1130*7c478bd9Sstevel@tonic-gate if (buf == NULL || cbufsiz == NULL || *cbufsiz != bufsiz) {
1131*7c478bd9Sstevel@tonic-gate if ((nbuf = realloc(buf, bufsiz)) == NULL)
1132*7c478bd9Sstevel@tonic-gate return (NULL);
1133*7c478bd9Sstevel@tonic-gate
1134*7c478bd9Sstevel@tonic-gate buf = nbuf;
1135*7c478bd9Sstevel@tonic-gate *bufp = buf;
1136*7c478bd9Sstevel@tonic-gate if (cbufsiz != NULL)
1137*7c478bd9Sstevel@tonic-gate *cbufsiz = bufsiz;
1138*7c478bd9Sstevel@tonic-gate }
1139*7c478bd9Sstevel@tonic-gate
1140*7c478bd9Sstevel@tonic-gate
1141*7c478bd9Sstevel@tonic-gate if (st == NULL)
1142*7c478bd9Sstevel@tonic-gate return (buf);
1143*7c478bd9Sstevel@tonic-gate
1144*7c478bd9Sstevel@tonic-gate clearerr(st);
1145*7c478bd9Sstevel@tonic-gate for (;;) {
1146*7c478bd9Sstevel@tonic-gate int c = getc(st);
1147*7c478bd9Sstevel@tonic-gate
1148*7c478bd9Sstevel@tonic-gate /* Expand the buffer as needed. */
1149*7c478bd9Sstevel@tonic-gate if (idx == bufsiz) {
1150*7c478bd9Sstevel@tonic-gate bufsiz += BUFFER_CHUNK_SIZE;
1151*7c478bd9Sstevel@tonic-gate if ((nbuf = realloc(buf, bufsiz)) == NULL) {
1152*7c478bd9Sstevel@tonic-gate /* Discard everything we read. */
1153*7c478bd9Sstevel@tonic-gate buf[off] = 0;
1154*7c478bd9Sstevel@tonic-gate buf = NULL;
1155*7c478bd9Sstevel@tonic-gate break;
1156*7c478bd9Sstevel@tonic-gate }
1157*7c478bd9Sstevel@tonic-gate buf = nbuf;
1158*7c478bd9Sstevel@tonic-gate *bufp = buf;
1159*7c478bd9Sstevel@tonic-gate if (cbufsiz != NULL)
1160*7c478bd9Sstevel@tonic-gate *cbufsiz = bufsiz;
1161*7c478bd9Sstevel@tonic-gate }
1162*7c478bd9Sstevel@tonic-gate
1163*7c478bd9Sstevel@tonic-gate if (c == EOF || c == '\n') {
1164*7c478bd9Sstevel@tonic-gate buf[idx] = 0;
1165*7c478bd9Sstevel@tonic-gate if (ferror(st) != 0) {
1166*7c478bd9Sstevel@tonic-gate /* Retry if interrupted by a signal. */
1167*7c478bd9Sstevel@tonic-gate if (errno == EINTR) {
1168*7c478bd9Sstevel@tonic-gate clearerr(st);
1169*7c478bd9Sstevel@tonic-gate continue;
1170*7c478bd9Sstevel@tonic-gate }
1171*7c478bd9Sstevel@tonic-gate buf = NULL;
1172*7c478bd9Sstevel@tonic-gate } else if (feof(st) != 0) {
1173*7c478bd9Sstevel@tonic-gate /* No characters transferred? */
1174*7c478bd9Sstevel@tonic-gate if (off == idx)
1175*7c478bd9Sstevel@tonic-gate buf = NULL;
1176*7c478bd9Sstevel@tonic-gate }
1177*7c478bd9Sstevel@tonic-gate break;
1178*7c478bd9Sstevel@tonic-gate }
1179*7c478bd9Sstevel@tonic-gate buf[idx++] = c;
1180*7c478bd9Sstevel@tonic-gate }
1181*7c478bd9Sstevel@tonic-gate return (buf);
1182*7c478bd9Sstevel@tonic-gate }
1183*7c478bd9Sstevel@tonic-gate
1184*7c478bd9Sstevel@tonic-gate /*
1185*7c478bd9Sstevel@tonic-gate * Read a string from the supplied stream. Stop reading when a newline
1186*7c478bd9Sstevel@tonic-gate * is read, end of file reached, or an error occurs.
1187*7c478bd9Sstevel@tonic-gate *
1188*7c478bd9Sstevel@tonic-gate * A buffer can be supplied by specifying the buffer address via the
1189*7c478bd9Sstevel@tonic-gate * first argument. The buffer size can be passed via the second argument.
1190*7c478bd9Sstevel@tonic-gate * If the second argument is NULL, the function makes no assumptions
1191*7c478bd9Sstevel@tonic-gate * about the buffer size. The buffer will be reallocated if it is too
1192*7c478bd9Sstevel@tonic-gate * small or too large for the returned string.
1193*7c478bd9Sstevel@tonic-gate *
1194*7c478bd9Sstevel@tonic-gate * If no buffer is to be supplied, specify a buffer address of NULL,
1195*7c478bd9Sstevel@tonic-gate * via the first argument.
1196*7c478bd9Sstevel@tonic-gate *
1197*7c478bd9Sstevel@tonic-gate * If the first argument is NULL, the function just returns NULL, and
1198*7c478bd9Sstevel@tonic-gate * performs no other processing.
1199*7c478bd9Sstevel@tonic-gate *
1200*7c478bd9Sstevel@tonic-gate * The function returns the address of the buffer if any characters are
1201*7c478bd9Sstevel@tonic-gate * read and no error occurred.
1202*7c478bd9Sstevel@tonic-gate *
1203*7c478bd9Sstevel@tonic-gate * If the function returns NULL, a buffer may have been allocated. The
1204*7c478bd9Sstevel@tonic-gate * buffer address and buffer size will be returned via the first argument,
1205*7c478bd9Sstevel@tonic-gate * and the buffer size via the second argument, if this isn't NULL.
1206*7c478bd9Sstevel@tonic-gate */
1207*7c478bd9Sstevel@tonic-gate char *
GetString(bufp,bufsiz,st)1208*7c478bd9Sstevel@tonic-gate GetString(bufp, bufsiz, st)
1209*7c478bd9Sstevel@tonic-gate char **bufp;
1210*7c478bd9Sstevel@tonic-gate unsigned int *bufsiz;
1211*7c478bd9Sstevel@tonic-gate FILE *st;
1212*7c478bd9Sstevel@tonic-gate {
1213*7c478bd9Sstevel@tonic-gate return (GetStringAtOffset(bufp, bufsiz, 0, st));
1214*7c478bd9Sstevel@tonic-gate }
1215*7c478bd9Sstevel@tonic-gate
1216*7c478bd9Sstevel@tonic-gate /*
1217*7c478bd9Sstevel@tonic-gate * Allocate a buffer to hold a string of given length.
1218*7c478bd9Sstevel@tonic-gate *
1219*7c478bd9Sstevel@tonic-gate * An existing buffer can be reallocated by passing its address and via
1220*7c478bd9Sstevel@tonic-gate * the first argument. The buffer size can be passed via the second
1221*7c478bd9Sstevel@tonic-gate * argument. If the second argument is NULL, the function makes no
1222*7c478bd9Sstevel@tonic-gate * assumptions about the buffer size.
1223*7c478bd9Sstevel@tonic-gate *
1224*7c478bd9Sstevel@tonic-gate * If no existing buffer is to be supplied, pass a NULL buffer address via
1225*7c478bd9Sstevel@tonic-gate * the first argument.
1226*7c478bd9Sstevel@tonic-gate *
1227*7c478bd9Sstevel@tonic-gate * If the first argument is NULL, the function just returns NULL,
1228*7c478bd9Sstevel@tonic-gate * and performs no other processing.
1229*7c478bd9Sstevel@tonic-gate */
1230*7c478bd9Sstevel@tonic-gate char *
AllocStringBuffer(bufp,bufsiz,size)1231*7c478bd9Sstevel@tonic-gate AllocStringBuffer(bufp, bufsiz, size)
1232*7c478bd9Sstevel@tonic-gate char **bufp;
1233*7c478bd9Sstevel@tonic-gate unsigned int *bufsiz;
1234*7c478bd9Sstevel@tonic-gate unsigned int size;
1235*7c478bd9Sstevel@tonic-gate {
1236*7c478bd9Sstevel@tonic-gate return (GetStringAtOffset(bufp, bufsiz, size, (FILE *)NULL));
1237*7c478bd9Sstevel@tonic-gate }
1238*7c478bd9Sstevel@tonic-gate
1239*7c478bd9Sstevel@tonic-gate /*
1240*7c478bd9Sstevel@tonic-gate * This function is similar to GetString(), except that the string read
1241*7c478bd9Sstevel@tonic-gate * from the stream is appended to the supplied string.
1242*7c478bd9Sstevel@tonic-gate */
1243*7c478bd9Sstevel@tonic-gate char *
GetAndAppendString(bufp,bufsiz,str,st)1244*7c478bd9Sstevel@tonic-gate GetAndAppendString(bufp, bufsiz, str, st)
1245*7c478bd9Sstevel@tonic-gate char **bufp;
1246*7c478bd9Sstevel@tonic-gate unsigned int *bufsiz;
1247*7c478bd9Sstevel@tonic-gate char *str;
1248*7c478bd9Sstevel@tonic-gate FILE *st;
1249*7c478bd9Sstevel@tonic-gate {
1250*7c478bd9Sstevel@tonic-gate unsigned int off = strlen(str);
1251*7c478bd9Sstevel@tonic-gate
1252*7c478bd9Sstevel@tonic-gate if (GetStringAtOffset(bufp, bufsiz, off, st) == NULL)
1253*7c478bd9Sstevel@tonic-gate return (NULL);
1254*7c478bd9Sstevel@tonic-gate
1255*7c478bd9Sstevel@tonic-gate return (memcpy(*bufp, str, off));
1256*7c478bd9Sstevel@tonic-gate }
1257