/*      $NetBSD: rc.c,v 1.8 2016/06/08 01:11:49 christos Exp $  */

/*
* Copyright (c) 1993-95 Mats O Jansson.  All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
*    notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
*    notice, this list of conditions and the following disclaimer in the
*    documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include "port.h"
#ifndef lint
__RCSID("$NetBSD: rc.c,v 1.8 2016/06/08 01:11:49 christos Exp $");
#endif

#include "os.h"
#include "get.h"
#include "mopdef.h"
#include "print.h"
#include "rc.h"

void
mopDumpRC(FILE *fd, const u_char *pkt, int trans)
{
       int     i,idx = 0;
       int32_t tmpl;
       u_char  tmpc,code,control;
       u_short len,tmps,moplen;

       len = mopGetLength(pkt, trans);

       switch (trans) {
       case TRANS_8023:
               idx = 22;
               moplen = len - 8;
               break;
       default:
               idx = 16;
               moplen = len;
       }
       code = mopGetChar(pkt,&idx);

       switch (code) {
       case MOP_K_CODE_RID:

               tmpc = mopGetChar(pkt,&idx);
               (void)fprintf(fd,"Reserved     :   %02x\n",tmpc);

               tmps = mopGetShort(pkt,&idx);
               (void)fprintf(fd,"Receipt Nbr  : %04x\n",tmps);

               break;
       case MOP_K_CODE_BOT:

               if (moplen == 5) {
                       tmps = mopGetShort(pkt,&idx);
                       (void)fprintf(fd,"Verification : %04x\n",tmps);
               } else {

                       tmpl = mopGetLong(pkt,&idx);
                       (void)fprintf(fd,"Verification : %08x\n",tmpl);

                       tmpc = mopGetChar(pkt,&idx);    /* Processor */
                       (void)fprintf(fd,"Processor    :   %02x ",tmpc);
                       mopPrintBPTY(fd, tmpc);  (void)fprintf(fd, "\n");

                       control = mopGetChar(pkt,&idx); /* Control */
                       (void)fprintf(fd,"Control    :   %02x ",control);
                       if ((control & (1>>MOP_K_BOT_CNTL_SERVER))) {
                               (void)fprintf(fd,
                                             "Bootserver Requesting system ");
                       } else {
                               (void)fprintf(fd,
                                             "Bootserver System default ");
                       }
                       if ((control & (1>>MOP_K_BOT_CNTL_DEVICE))) {
                               (void)fprintf(fd,
                                             "Bootdevice Specified device");
                       } else {
                               (void)fprintf(fd,
                                             "Bootdevice System default");
                       }
                       (void)fprintf(fd,"\n");

                       if ((control & (1>>MOP_K_BOT_CNTL_DEVICE))) {
                               tmpc = mopGetChar(pkt,&idx);/* Device ID */
                               (void)fprintf(fd,
                                             "Device ID    :   %02x '",tmpc);
                               for (i = 0; i < ((int) tmpc); i++) {
                                 (void)fprintf(fd,"%c",
                                               mopGetChar(pkt,&idx));
                               }
                               (void)fprintf(fd,"'\n");
                       }

                       tmpc = mopGetChar(pkt,&idx);      /* Software ID */
                       (void)fprintf(fd,"Software ID  :   %02x ",tmpc);
                       if (tmpc == 0) {
                               (void)fprintf(fd,"No software id");
                       }
                       if (tmpc == 254) {
                               (void)fprintf(fd,"Maintenance system");
                               tmpc = 0;
                       }
                       if (tmpc == 255) {
                               (void)fprintf(fd,"Standard operating system");
                               tmpc = 0;
                       }
                       if (tmpc > 0) {
                               (void)fprintf(fd,"'");
                               for (i = 0; i < ((int) tmpc); i++) {
                                       (void)fprintf(fd,"%c",
                                                    mopGetChar(pkt,&idx));
                               }
                               (void)fprintf(fd,"'");
                       }
                       (void)fprintf(fd,"'\n");

               }
               break;
       case MOP_K_CODE_SID:

               tmpc = mopGetChar(pkt,&idx);            /* Reserved */
               (void)fprintf(fd, "Reserved     :   %02x\n",tmpc);

               tmps = mopGetShort(pkt,&idx);           /* Receipt # */
               (void)fprintf(fd, "Receipt Nbr  : %04x\n",tmpc);

               mopPrintInfo(fd, pkt, &idx, moplen, code, trans);

               break;
       case MOP_K_CODE_RQC:

               tmps = mopGetShort(pkt,&idx);
               (void)fprintf(fd,"Receipt Nbr  : %04x\n",tmps);

               break;
       case MOP_K_CODE_CNT:

               tmps = mopGetShort(pkt,&idx);
               (void)fprintf(fd,"Receipt Nbr  : %04x %d\n",tmps,tmps);

               tmps = mopGetShort(pkt,&idx);
               (void)fprintf(fd,"Last Zeroed  : %04x %d\n",tmps,tmps);

               tmpl = mopGetLong(pkt,&idx);
               (void)fprintf(fd,"Bytes rec    : %08x %d\n",tmpl,tmpl);

               tmpl = mopGetLong(pkt,&idx);
               (void)fprintf(fd,"Bytes snd    : %08x %d\n",tmpl,tmpl);

               tmpl = mopGetLong(pkt,&idx);
               (void)fprintf(fd,"Frames rec   : %08x %d\n",tmpl,tmpl);

               tmpl = mopGetLong(pkt,&idx);
               (void)fprintf(fd,"Frames snd   : %08x %d\n",tmpl,tmpl);

               tmpl = mopGetLong(pkt,&idx);
               (void)fprintf(fd,"Mcst Bytes re: %08x %d\n",tmpl,tmpl);

               tmpl = mopGetLong(pkt,&idx);
               (void)fprintf(fd,"Mcst Frame re: %08x %d\n",tmpl,tmpl);

               tmpl = mopGetLong(pkt,&idx);
               (void)fprintf(fd,"Frame snd,def: %08x %d\n",tmpl,tmpl);

               tmpl = mopGetLong(pkt,&idx);
               (void)fprintf(fd,"Frame snd,col: %08x %d\n",tmpl,tmpl);

               tmpl = mopGetLong(pkt,&idx);
               (void)fprintf(fd,"Frame snd,mcl: %08x %d\n",tmpl,tmpl);

               tmps = mopGetShort(pkt,&idx);
               (void)fprintf(fd,"Snd failure  : %04x %d\n",tmps,tmps);

               tmps = mopGetShort(pkt,&idx);
               (void)fprintf(fd,"Snd fail reas: %04x ",tmps);
               if ((tmps &  1)) (void)fprintf(fd,"Excess col  ");
               if ((tmps &  2)) (void)fprintf(fd,"Carrier chk fail  ");
               if ((tmps &  4)) (void)fprintf(fd,"Short circ  ");
               if ((tmps &  8)) (void)fprintf(fd,"Open circ  ");
               if ((tmps & 16)) (void)fprintf(fd,"Frm to long  ");
               if ((tmps & 32)) (void)fprintf(fd,"Rem fail to defer  ");
               (void)fprintf(fd,"\n");

               tmps = mopGetShort(pkt,&idx);
               (void)fprintf(fd,"Rec failure  : %04x %d\n",tmps,tmps);

               tmps = mopGetShort(pkt,&idx);
               (void)fprintf(fd,"Rec fail reas: %04x ",tmps);
               if ((tmps &  1)) (void)fprintf(fd,"Block chk err  ");
               if ((tmps &  2)) (void)fprintf(fd,"Framing err  ");
               if ((tmps &  4)) (void)fprintf(fd,"Frm to long  ");
               (void)fprintf(fd,"\n");

               tmps = mopGetShort(pkt,&idx);
               (void)fprintf(fd,"Unrec frm dst: %04x %d\n",tmps,tmps);

               tmps = mopGetShort(pkt,&idx);
               (void)fprintf(fd,"Data overrun : %04x %d\n",tmps,tmps);

               tmps = mopGetShort(pkt,&idx);
               (void)fprintf(fd,"Sys Buf Unava: %04x %d\n",tmps,tmps);

               tmps = mopGetShort(pkt,&idx);
               (void)fprintf(fd,"Usr Buf Unava: %04x %d\n",tmps,tmps);

               break;
       case MOP_K_CODE_RVC:

               tmpl = mopGetLong(pkt,&idx);
               (void)fprintf(fd,"Verification : %08x\n",tmpl);

               break;
       case MOP_K_CODE_RLC:

               /* Empty message */

               break;
       case MOP_K_CODE_CCP:

               tmpc = mopGetChar(pkt,&idx);
               (void)fprintf(fd,
                             "Control Flags: %02x Message %d ",tmpc,tmpc & 1);
               if ((tmpc & 2))
                       (void)fprintf(fd,"Break");
               (void)fprintf(fd,"\n");

               if (moplen > 2) {
#ifndef SHORT_PRINT
                       for (i = 0; i < (moplen - 2); i++) {
                               if ((i % 16) == 0) {
                                       if ((i / 16) == 0) {
                                               (void)fprintf(fd,
                                                       "Image Data   : %04x ",
                                                             moplen-2);
                                       } else {
                                               (void)fprintf(fd,
                                                      "                    ");
                                       }
                               }
                               (void)fprintf(fd,"%02x ",
                                             mopGetChar(pkt,&idx));
                               if ((i % 16) == 15)
                                       (void)fprintf(fd,"\n");
                       }
                       if ((i % 16) != 15)
                               (void)fprintf(fd,"\n");
#else
                       idx = idx + moplen - 2;
#endif
               }

               break;
       case MOP_K_CODE_CRA:

               tmpc = mopGetChar(pkt,&idx);
               (void)fprintf(fd,
                             "Control Flags: %02x Message %d ",tmpc,tmpc & 1);
               if ((tmpc & 2))
                       (void)fprintf(fd,"Cmd Data Lost ");
               if ((tmpc & 4))
                       (void)fprintf(fd,"Resp Data Lost ");
               (void)fprintf(fd,"\n");

               if (moplen > 2) {
#ifndef SHORT_PRINT
                       for (i = 0; i < (moplen - 2); i++) {
                               if ((i % 16) == 0) {
                                       if ((i / 16) == 0) {
                                               (void)fprintf(fd,
                                                       "Image Data   : %04x ",
                                                             moplen-2);
                                       } else {
                                               (void)fprintf(fd,
                                                      "                    ");
                                       }
                               }
                               (void)fprintf(fd,"%02x ",
                                             mopGetChar(pkt,&idx));
                               if ((i % 16) == 15)
                                       (void)fprintf(fd,"\n");
                       }
                       if ((i % 16) != 15)
                               (void)fprintf(fd,"\n");
#else
                       idx = idx + moplen - 2;
#endif
               }

               break;
       default:
               break;
       }
}