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 
46 extern char *dlc_header;
47 extern jmp_buf xdr_err;
48 
49 static char *procnames_short[] = {
50 	"Null",		/*  0 */
51 	"INVOKE",	/*  1 */
52 	"MORE",		/*  2 */
53 	"KILL",		/*  3 */
54 };
55 
56 static 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 
65 enum Rec_type {
66 	REC_TYPE_NORM = 0,
67 	REC_TYPE_EOR = 1,
68 	REC_TYPE_EOF = 2
69 };
70 typedef enum Rec_type Rec_type;
71 
72 void
73 interpret_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