1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License").  You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22/*
23 * Copyright (c) 1993, 1999 by Sun Microsystems, Inc.
24 * All rights reserved.
25 */
26
27#pragma	ident	"%W%	%E% SMI"
28
29#include <sys/types.h>
30#include <sys/errno.h>
31#include <setjmp.h>
32#include <limits.h>
33#include <netinet/in.h>
34#include <string.h>
35
36#include <rpc/types.h>
37#include <rpc/rpc.h>
38#include <rpc/xdr.h>
39#include <rpc/auth.h>
40#include <rpc/clnt.h>
41#include <rpc/rpc_msg.h>
42#include <fw.h>
43#include <fw_rpc.h>
44#include "snoop.h"
45
46extern char *dlc_header;
47extern jmp_buf xdr_err;
48
49static char *procnames_short[] = {
50	"Null",		/*  0 */
51	"INVOKE",	/*  1 */
52	"MORE",		/*  2 */
53	"KILL",		/*  3 */
54};
55
56static char *procnames_long[] = {
57	"Null procedure",	/*  0 */
58	"Invoke operation",	/*  1 */
59	"More data",		/*  2 */
60	"Kill operation",	/*  3 */
61};
62
63#define	MAXPROC	3
64
65enum Rec_type {
66	REC_TYPE_NORM = 0,
67	REC_TYPE_EOR = 1,
68	REC_TYPE_EOF = 2
69};
70typedef enum Rec_type Rec_type;
71
72void
73interpret_solarnet_fw(
74	int flags,
75	int type,
76	int xid,
77	int vers,
78	int proc,
79	char *data,
80	int len)
81{
82	char *line;
83	char buff[CTXTLEN + 1];
84	ulong_t thresh;
85	char op[CTXTLEN + 1];
86	bool_t b;
87	Fw_err e;
88	Rec_type rt;
89	int new_row = 1, row = 0;
90
91	if (proc < 0 || proc > MAXPROC)
92		return;
93
94	if (flags & F_SUM) {
95		if (setjmp(xdr_err)) {
96			return;
97		}
98
99		line = get_sum_line();
100
101		if (type == CALL) {
102			(void) sprintf(line,
103				"SOLARNET C %s",
104				procnames_short[proc]);
105			line += strlen(line);
106
107			switch (proc) {
108			case FW_INVOKE:
109				(void) sprintf(line, " %s",
110				    getxdr_string(buff, CTXTLEN));
111				line += strlen(line);
112				(void) sprintf(line, "/%s",
113				    getxdr_string(buff, CTXTLEN));
114				line += strlen(line);
115				getxdr_string(buff, CTXTLEN);
116				if (strlen(buff) != 0) {
117					(void) sprintf(line, ".%s", buff);
118					line += strlen(line);
119				}
120				(void) getxdr_string(buff, CTXTLEN);
121				thresh = getxdr_u_long();
122				if (thresh == ULONG_MAX)
123					(void) sprintf(line, " (all)");
124				else
125					(void) sprintf(line, " %lu", thresh);
126				line += strlen(line);
127				(void) getxdr_context(buff, CTXTLEN);
128				break;
129			case FW_MORE:
130				(void) getxdr_context(buff, CTXTLEN);
131				sscanf(buff, "%*s %*s %s.%*s", op);
132				op[strlen(op)-1] = '\0';
133				(void) sprintf(line, " %s", op);
134				line += strlen(line);
135				thresh = getxdr_u_long();
136				if (thresh == ULONG_MAX)
137					(void) sprintf(line, " (all)");
138				else
139					(void) sprintf(line, " %lu", thresh);
140				line += strlen(line);
141				break;
142			case FW_KILL:
143				(void) getxdr_context(buff, CTXTLEN);
144				sscanf(buff, "%*s %*s %s.%*s", op);
145				op[strlen(op)-1] = '\0';
146				(void) sprintf(line, " %s", op);
147				line += strlen(line);
148				break;
149			default:
150				break;
151			}
152
153			check_retransmit(line, xid);
154		} else {
155			(void) sprintf(line, "SOLARNET R %s",
156			    procnames_short[proc]);
157			line += strlen(line);
158			b = getxdr_bool();
159			if (b) {
160				e = getxdr_enum();
161				if (e == FW_ERR_FW)
162					sprintf(line, " FW");
163				else if (e == FW_ERR_OP)
164					sprintf(line, " OP");
165				else
166					sprintf(line, " NOERR");
167				line += strlen(line);
168				if (e != FW_ERR_NONE) {
169					sprintf(line, " %lu", getxdr_u_long());
170					line += strlen(line);
171					(void) getxdr_bool();
172					sprintf(line, " %s",
173					    getxdr_string(buff, CTXTLEN));
174					line += strlen(line);
175				}
176			} else {
177				sprintf(line, " Success");
178				line += strlen(line);
179			}
180			b = getxdr_bool();
181			if (b) {
182				sprintf(line, " %lu rows", getxdr_u_long());
183				line += strlen(line);
184			} else {
185				sprintf(line, " (No output)");
186				line += strlen(line);
187			}
188		}
189	}
190
191	if ((flags & F_DTAIL)) {
192		show_header("SOLARNET:  ", "Solarnet Administration Service",
193		    len);
194		show_space();
195		if (setjmp(xdr_err)) {
196			return;
197		}
198		(void) sprintf(get_line(0, 0), "Proc = %d (%s)", proc,
199		    procnames_long[proc]);
200		if (type == CALL) {
201			switch (proc) {
202			case FW_INVOKE:
203				(void) showxdr_string(CTXTLEN, "Category: %s");
204				(void) showxdr_string(CTXTLEN, "Operation: %s");
205				(void) showxdr_string(CTXTLEN, "Version: %s");
206				(void) showxdr_string(CTXTLEN, "Locale: %s");
207				(void) showxdr_u_long("Threshold: %lu rows");
208				(void) showxdr_context("Context: %s");
209				b = getxdr_bool();
210				if (!b) {
211					sprintf(get_line(0, 0),
212					    "No input arguments");
213					break;
214				}
215				thresh = showxdr_u_long("Input rows = %lu");
216				(void) getxdr_bool();
217				do {
218					rt = getxdr_enum();
219					if (rt == REC_TYPE_NORM) {
220						if (new_row) {
221							sprintf(get_line(0, 0),
222							    "Row %d", ++row);
223							new_row = 0;
224						}
225						(void) getxdr_string(buff,
226						    CTXTLEN);
227						(void) getxdr_string(op,
228						    CTXTLEN);
229						sprintf(get_line(0, 0),
230						    "\t%s = %s", buff, op);
231					} else if (rt == REC_TYPE_EOR) {
232						new_row = 1;
233					}
234				} while (rt != REC_TYPE_EOF);
235				break;
236			case FW_MORE:
237				(void) showxdr_context("Context: %s");
238				(void) showxdr_u_long("Threshold: %lu rows");
239				break;
240			case FW_KILL:
241				(void) showxdr_context("Context: %s");
242				break;
243			default:
244				break;
245			}
246		} else {
247			b = getxdr_bool();
248			if (b) {
249				e = getxdr_enum();
250				if (e == FW_ERR_FW) {
251					showxdr_u_long(
252					    "Framework error code %lu");
253				} else if (e == FW_ERR_OP) {
254					showxdr_u_long(
255					    "Operation error code %lu");
256				} else {
257					showxdr_u_long("No error %*lu");
258				}
259				(void) getxdr_bool();
260				(void) getxdr_string(buff, CTXTLEN);
261				if (e != FW_ERR_NONE) {
262					sprintf(get_line(0, 0),
263					    "Error message: %s", buff);
264				} else {
265				}
266			} else {
267				sprintf(get_line(0, 0),
268				    "Operation was successful");
269			}
270			b = getxdr_bool();
271			if (b) {
272				showxdr_u_long("Output rows: %lu");
273				(void) getxdr_bool();
274				do {
275					rt = getxdr_enum();
276					if (rt == REC_TYPE_NORM) {
277						if (new_row) {
278							sprintf(get_line(0, 0),
279							    "Row %d", ++row);
280							new_row = 0;
281						}
282						(void) getxdr_string(buff,
283						    CTXTLEN);
284						(void) getxdr_string(op,
285						    CTXTLEN);
286						sprintf(get_line(0, 0),
287						    "\t%s = %s", buff, op);
288					} else if (rt == REC_TYPE_EOR) {
289						new_row = 1;
290					}
291				} while (rt != REC_TYPE_EOF);
292			} else {
293				sprintf(get_line(0, 0), "No output");
294			}
295		}
296		show_trailer();
297	}
298
299}
300