/*	$NetBSD: dl.c,v 1.9 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: dl.c,v 1.9 2016/06/08 01:11:49 christos Exp $");
#endif

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

void
mopDumpDL(FILE *fd, const u_char *pkt, int trans)
{
	int	i,idx = 0;
	u_int32_t tmpl;
	u_char	tmpc,c,program[257],code;
	const u_char *ucp;
	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_MLT:
		
		tmpc = mopGetChar(pkt,&idx);	/* Load Number */
		(void)fprintf(fd,"Load Number  :   %02x\n",tmpc);
		
		if (moplen > 6) {
			tmpl = mopGetLong(pkt,&idx);/* Load Address */
			(void)fprintf(fd,"Load Address : %08x\n", tmpl);
		}
		
		if (moplen > 10) {
#ifndef SHORT_PRINT
			for (i = 0; i < (moplen - 10); i++) {
				if ((i % 16) == 0) {
					if ((i / 16) == 0) {
					 	(void)fprintf(fd,
						       "Image Data   : %04x ",
							      moplen-10);
					} 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 - 10;
#endif
		}
		
		tmpl = mopGetLong(pkt,&idx);	/* Load Address */
		(void)fprintf(fd,"Xfer Address : %08x\n", tmpl);
		
		break;
	case MOP_K_CODE_DCM:

		/* Empty Message */

		break;
	case MOP_K_CODE_MLD:
		
		tmpc = mopGetChar(pkt,&idx);	/* Load Number */
		(void)fprintf(fd,"Load Number  :   %02x\n",tmpc);
		
		tmpl = mopGetLong(pkt,&idx);	/* Load Address */
		(void)fprintf(fd,"Load Address : %08x\n", tmpl);
		
		if (moplen > 6) {
#ifndef SHORT_PRINT
			for (i = 0; i < (moplen - 6); i++) {
				if ((i % 16) == 0) {
					if ((i / 16) == 0) {
						(void)fprintf(fd,
						       "Image Data   : %04x ",
							      moplen-6);
					} 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 - 6;
#endif
		}
		
		break;
	case MOP_K_CODE_ASV:
		
		/* Empty Message */
		
		break;
	case MOP_K_CODE_RMD:

		tmpl = mopGetLong(pkt,&idx);	/* Memory Address */
		(void)fprintf(fd,"Mem Address  : %08x\n", tmpl);
		
		tmps = mopGetShort(pkt,&idx);	/* Count */
		(void)fprintf(fd,"Count        : %04x (%d)\n",tmps,tmps);
		
		break;
	case MOP_K_CODE_RPR:
		
		tmpc = mopGetChar(pkt,&idx);	/* Device Type */
		(void)fprintf(fd, "Device Type  :   %02x ",tmpc);
		mopPrintDevice(fd, tmpc); (void)fprintf(fd, "\n");
		
		tmpc = mopGetChar(pkt,&idx);	/* Format Version */
		(void)fprintf(fd,"Format       :   %02x\n",tmpc);
		
		tmpc = mopGetChar(pkt,&idx);	/* Program Type */
		(void)fprintf(fd,"Program Type :   %02x ",tmpc);
		mopPrintPGTY(fd, tmpc); (void)fprintf(fd, "\n");
		
		program[0] = 0;
		tmpc = mopGetChar(pkt,&idx);	/* Software ID Len */
		for (i = 0; i < tmpc; i++) {
			program[i] = mopGetChar(pkt,&idx);
			program[i+1] = '\0';
		}
		
		(void)fprintf(fd,"Software     :   %02x '%s'\n",tmpc,program);
		
		tmpc = mopGetChar(pkt,&idx);	/* Processor */
		(void)fprintf(fd,"Processor    :   %02x ",tmpc);
		mopPrintBPTY(fd, tmpc); (void)fprintf(fd, "\n");
		
		mopPrintInfo(fd, pkt, &idx, moplen, code, trans);
		
		break;
	case MOP_K_CODE_RML:
		
		tmpc = mopGetChar(pkt,&idx);	/* Load Number */
		(void)fprintf(fd,"Load Number  :   %02x\n",tmpc);
		
		tmpc = mopGetChar(pkt,&idx);	/* Error */
		(void)fprintf(fd,"Error        :   %02x (",tmpc);
		if (tmpc == 0) {
			(void)fprintf(fd,"no error)\n");
		} else {
		  	(void)fprintf(fd,"error)\n");
		}
		
		break;
	case MOP_K_CODE_RDS:
		
		tmpc = mopGetChar(pkt,&idx);	/* Device Type */
		(void)fprintf(fd, "Device Type  :   %02x ",tmpc);
		mopPrintDevice(fd, tmpc); (void)fprintf(fd, "\n");
		
		tmpc = mopGetChar(pkt,&idx);	/* Format Version */
		(void)fprintf(fd,"Format       :   %02x\n",tmpc);
		
		tmpl = mopGetLong(pkt,&idx);	/* Memory Size */
		(void)fprintf(fd,"Memory Size  : %08x\n", tmpl);
		
		tmpc = mopGetChar(pkt,&idx);	/* Bits */
		(void)fprintf(fd,"Bits         :   %02x\n",tmpc);
		
		mopPrintInfo(fd, pkt, &idx, moplen, code, trans);
		
		break;
	case MOP_K_CODE_MDD:
		
		tmpl = mopGetLong(pkt,&idx);	/* Memory Address */
		(void)fprintf(fd,"Mem Address  : %08x\n", tmpl);
		
		if (moplen > 5) {
#ifndef SHORT_PRINT
			for (i = 0; i < (moplen - 5); i++) {
				if ((i % 16) == 0) {
					if ((i / 16) == 0) {
						(void)fprintf(fd,
						       "Image Data   : %04x ",
							      moplen-5);
					} 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 - 5;
#endif
		}
		
		break;
	case MOP_K_CODE_PLT:
		
		tmpc = mopGetChar(pkt,&idx);	/* Load Number */
		(void)fprintf(fd,"Load Number  :   %02x\n",tmpc);
		
		tmpc = mopGetChar(pkt,&idx);	/* Parameter Type */
		while (tmpc != MOP_K_PLTP_END) {
			c = mopGetChar(pkt,&idx);	/* Parameter Length */
			switch(tmpc) {
			case MOP_K_PLTP_TSN:		/* Target Name */
				(void)fprintf(fd,"Target Name  :   %02x '",
					      tmpc);
				for (i = 0; i < ((int) c); i++) {
					(void)fprintf(fd,"%c",
						    mopGetChar(pkt,&idx));
				}
				(void)fprintf(fd,"'\n");
				break;
			case MOP_K_PLTP_TSA:		/* Target Address */
				(void)fprintf(fd,"Target Addr  :   %02x ",c);
				for (i = 0; i < ((int) c); i++) {
					(void)fprintf(fd,"%02x ",
						    mopGetChar(pkt,&idx));
				}
				(void)fprintf(fd,"\n");
				break;
			case MOP_K_PLTP_HSN:		/* Host Name */
				(void)fprintf(fd,"Host Name    :   %02x '",
					      tmpc);
				for (i = 0; i < ((int) c); i++) {
					(void)fprintf(fd,"%c",
						    mopGetChar(pkt,&idx));
				}
				(void)fprintf(fd,"'\n");
				break;
			case MOP_K_PLTP_HSA:		/* Host Address */
				(void)fprintf(fd,"Host Addr    :   %02x ",c);
				for (i = 0; i < ((int) c); i++) {
					(void)fprintf(fd,"%02x ",
						    mopGetChar(pkt,&idx));
				}
				(void)fprintf(fd,"\n");
				break;
			case MOP_K_PLTP_HST:		/* Host Time */
				ucp = pkt + idx; idx = idx + 10;
				(void)fprintf(fd,"Host Time    : ");
				mopPrintTime(fd, ucp);
				(void)fprintf(fd,"\n");
				break;
			default:
				break;
			}
			tmpc = mopGetChar(pkt,&idx);/* Parameter Type */
		}
		
		tmpl = mopGetLong(pkt,&idx);	/* Transfer Address */
		(void)fprintf(fd,"Transfer Addr: %08x\n", tmpl);
		
		break;
	default:
		break;
	}
}


