root/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_solarnet.c
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*
 * Copyright (c) 1993, 1999 by Sun Microsystems, Inc.
 * All rights reserved.
 */

#include <sys/types.h>
#include <sys/errno.h>
#include <setjmp.h>
#include <limits.h>
#include <netinet/in.h>
#include <string.h>

#include <rpc/types.h>
#include <rpc/rpc.h>
#include <rpc/xdr.h>
#include <rpc/auth.h>
#include <rpc/clnt.h>
#include <rpc/rpc_msg.h>
#include <fw.h>
#include <fw_rpc.h>
#include "snoop.h"

extern char *dlc_header;
extern jmp_buf xdr_err;

static char *procnames_short[] = {
        "Null",         /*  0 */
        "INVOKE",       /*  1 */
        "MORE",         /*  2 */
        "KILL",         /*  3 */
};

static char *procnames_long[] = {
        "Null procedure",       /*  0 */
        "Invoke operation",     /*  1 */
        "More data",            /*  2 */
        "Kill operation",       /*  3 */
};

#define MAXPROC 3

enum Rec_type {
        REC_TYPE_NORM = 0,
        REC_TYPE_EOR = 1,
        REC_TYPE_EOF = 2
};
typedef enum Rec_type Rec_type;

void
interpret_solarnet_fw(
        int flags,
        int type,
        int xid,
        int vers,
        int proc,
        char *data,
        int len)
{
        char *line;
        char buff[CTXTLEN + 1];
        ulong_t thresh;
        char op[CTXTLEN + 1];
        bool_t b;
        Fw_err e;
        Rec_type rt;
        int new_row = 1, row = 0;

        if (proc < 0 || proc > MAXPROC)
                return;

        if (flags & F_SUM) {
                if (setjmp(xdr_err)) {
                        return;
                }

                line = get_sum_line();

                if (type == CALL) {
                        (void) sprintf(line,
                                "SOLARNET C %s",
                                procnames_short[proc]);
                        line += strlen(line);

                        switch (proc) {
                        case FW_INVOKE:
                                (void) sprintf(line, " %s",
                                    getxdr_string(buff, CTXTLEN));
                                line += strlen(line);
                                (void) sprintf(line, "/%s",
                                    getxdr_string(buff, CTXTLEN));
                                line += strlen(line);
                                getxdr_string(buff, CTXTLEN);
                                if (strlen(buff) != 0) {
                                        (void) sprintf(line, ".%s", buff);
                                        line += strlen(line);
                                }
                                (void) getxdr_string(buff, CTXTLEN);
                                thresh = getxdr_u_long();
                                if (thresh == ULONG_MAX)
                                        (void) sprintf(line, " (all)");
                                else
                                        (void) sprintf(line, " %lu", thresh);
                                line += strlen(line);
                                (void) getxdr_context(buff, CTXTLEN);
                                break;
                        case FW_MORE:
                                (void) getxdr_context(buff, CTXTLEN);
                                sscanf(buff, "%*s %*s %s.%*s", op);
                                op[strlen(op)-1] = '\0';
                                (void) sprintf(line, " %s", op);
                                line += strlen(line);
                                thresh = getxdr_u_long();
                                if (thresh == ULONG_MAX)
                                        (void) sprintf(line, " (all)");
                                else
                                        (void) sprintf(line, " %lu", thresh);
                                line += strlen(line);
                                break;
                        case FW_KILL:
                                (void) getxdr_context(buff, CTXTLEN);
                                sscanf(buff, "%*s %*s %s.%*s", op);
                                op[strlen(op)-1] = '\0';
                                (void) sprintf(line, " %s", op);
                                line += strlen(line);
                                break;
                        default:
                                break;
                        }

                        check_retransmit(line, xid);
                } else {
                        (void) sprintf(line, "SOLARNET R %s",
                            procnames_short[proc]);
                        line += strlen(line);
                        b = getxdr_bool();
                        if (b) {
                                e = getxdr_enum();
                                if (e == FW_ERR_FW)
                                        sprintf(line, " FW");
                                else if (e == FW_ERR_OP)
                                        sprintf(line, " OP");
                                else
                                        sprintf(line, " NOERR");
                                line += strlen(line);
                                if (e != FW_ERR_NONE) {
                                        sprintf(line, " %lu", getxdr_u_long());
                                        line += strlen(line);
                                        (void) getxdr_bool();
                                        sprintf(line, " %s",
                                            getxdr_string(buff, CTXTLEN));
                                        line += strlen(line);
                                }
                        } else {
                                sprintf(line, " Success");
                                line += strlen(line);
                        }
                        b = getxdr_bool();
                        if (b) {
                                sprintf(line, " %lu rows", getxdr_u_long());
                                line += strlen(line);
                        } else {
                                sprintf(line, " (No output)");
                                line += strlen(line);
                        }
                }
        }

        if ((flags & F_DTAIL)) {
                show_header("SOLARNET:  ", "Solarnet Administration Service",
                    len);
                show_space();
                if (setjmp(xdr_err)) {
                        return;
                }
                (void) sprintf(get_line(0, 0), "Proc = %d (%s)", proc,
                    procnames_long[proc]);
                if (type == CALL) {
                        switch (proc) {
                        case FW_INVOKE:
                                (void) showxdr_string(CTXTLEN, "Category: %s");
                                (void) showxdr_string(CTXTLEN, "Operation: %s");
                                (void) showxdr_string(CTXTLEN, "Version: %s");
                                (void) showxdr_string(CTXTLEN, "Locale: %s");
                                (void) showxdr_u_long("Threshold: %lu rows");
                                (void) showxdr_context("Context: %s");
                                b = getxdr_bool();
                                if (!b) {
                                        sprintf(get_line(0, 0),
                                            "No input arguments");
                                        break;
                                }
                                thresh = showxdr_u_long("Input rows = %lu");
                                (void) getxdr_bool();
                                do {
                                        rt = getxdr_enum();
                                        if (rt == REC_TYPE_NORM) {
                                                if (new_row) {
                                                        sprintf(get_line(0, 0),
                                                            "Row %d", ++row);
                                                        new_row = 0;
                                                }
                                                (void) getxdr_string(buff,
                                                    CTXTLEN);
                                                (void) getxdr_string(op,
                                                    CTXTLEN);
                                                sprintf(get_line(0, 0),
                                                    "\t%s = %s", buff, op);
                                        } else if (rt == REC_TYPE_EOR) {
                                                new_row = 1;
                                        }
                                } while (rt != REC_TYPE_EOF);
                                break;
                        case FW_MORE:
                                (void) showxdr_context("Context: %s");
                                (void) showxdr_u_long("Threshold: %lu rows");
                                break;
                        case FW_KILL:
                                (void) showxdr_context("Context: %s");
                                break;
                        default:
                                break;
                        }
                } else {
                        b = getxdr_bool();
                        if (b) {
                                e = getxdr_enum();
                                if (e == FW_ERR_FW) {
                                        showxdr_u_long(
                                            "Framework error code %lu");
                                } else if (e == FW_ERR_OP) {
                                        showxdr_u_long(
                                            "Operation error code %lu");
                                } else {
                                        showxdr_u_long("No error %*lu");
                                }
                                (void) getxdr_bool();
                                (void) getxdr_string(buff, CTXTLEN);
                                if (e != FW_ERR_NONE) {
                                        sprintf(get_line(0, 0),
                                            "Error message: %s", buff);
                                } else {
                                }
                        } else {
                                sprintf(get_line(0, 0),
                                    "Operation was successful");
                        }
                        b = getxdr_bool();
                        if (b) {
                                showxdr_u_long("Output rows: %lu");
                                (void) getxdr_bool();
                                do {
                                        rt = getxdr_enum();
                                        if (rt == REC_TYPE_NORM) {
                                                if (new_row) {
                                                        sprintf(get_line(0, 0),
                                                            "Row %d", ++row);
                                                        new_row = 0;
                                                }
                                                (void) getxdr_string(buff,
                                                    CTXTLEN);
                                                (void) getxdr_string(op,
                                                    CTXTLEN);
                                                sprintf(get_line(0, 0),
                                                    "\t%s = %s", buff, op);
                                        } else if (rt == REC_TYPE_EOR) {
                                                new_row = 1;
                                        }
                                } while (rt != REC_TYPE_EOF);
                        } else {
                                sprintf(get_line(0, 0), "No output");
                        }
                }
                show_trailer();
        }

}