1/*	$OpenBSD: print.c,v 1.15 2024/04/23 13:34:51 jsg Exp $ */
2
3/*
4 * Copyright (c) 1993-96 Mats O Jansson.  All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#include <sys/types.h>
28#include <stdio.h>
29
30#include "os.h"
31#include "common/mopdef.h"
32#include "common/nmadef.h"
33#include "common/nma.h"
34#include "common/cmp.h"
35#include "common/get.h"
36
37#define SHORT_PRINT
38
39void
40mopPrintHWA(FILE *fd, u_char *ap)
41{
42	fprintf(fd, "%x:%x:%x:%x:%x:%x", ap[0], ap[1], ap[2], ap[3], ap[4],
43	    ap[5]);
44	if (ap[0] < 16) fprintf(fd, " ");
45	if (ap[1] < 16) fprintf(fd, " ");
46	if (ap[2] < 16) fprintf(fd, " ");
47	if (ap[3] < 16) fprintf(fd, " ");
48	if (ap[4] < 16) fprintf(fd, " ");
49	if (ap[5] < 16) fprintf(fd, " ");
50}
51
52void
53mopPrintBPTY(FILE *fd, u_char bpty)
54{
55	switch (bpty) {
56	case MOP_K_BPTY_SYS:
57		fprintf(fd, "System Processor");
58		break;
59	case MOP_K_BPTY_COM:
60		fprintf(fd, "Communication Processor");
61		break;
62	default:
63		fprintf(fd, "Unknown");
64		break;
65	};
66}
67
68void
69mopPrintPGTY(FILE *fd, u_char pgty)
70{
71	switch (pgty) {
72	case MOP_K_PGTY_SECLDR:
73		fprintf(fd, "Secondary Loader");
74		break;
75	case MOP_K_PGTY_TERLDR:
76		fprintf(fd, "Tertiary Loader");
77		break;
78	case MOP_K_PGTY_OPRSYS:
79		fprintf(fd, "Operating System");
80		break;
81	case MOP_K_PGTY_MGNTFL:
82		fprintf(fd, "Management File");
83		break;
84	default:
85		fprintf(fd, "Unknown");
86		break;
87	};
88}
89
90void
91mopPrintOneline(FILE *fd, u_char *pkt, int trans)
92{
93	int	 idx = 0;
94	u_char	*dst, *src, code;
95	u_short	 proto;
96	int	 len;
97
98	trans = mopGetTrans(pkt, trans);
99	mopGetHeader(pkt, &idx, &dst, &src, &proto, &len, trans);
100	code = mopGetChar(pkt, &idx);
101
102	switch (proto) {
103	case MOP_K_PROTO_DL:
104		fprintf(fd, "MOP DL ");
105		break;
106	case MOP_K_PROTO_RC:
107		fprintf(fd, "MOP RC ");
108		break;
109	case MOP_K_PROTO_LP:
110		fprintf(fd, "MOP LP ");
111		break;
112	default:
113		switch ((proto % 256) * 256 + (proto / 256)) {
114		case MOP_K_PROTO_DL:
115			fprintf(fd, "MOP DL ");
116			proto = MOP_K_PROTO_DL;
117			break;
118		case MOP_K_PROTO_RC:
119			fprintf(fd, "MOP RC ");
120			proto = MOP_K_PROTO_RC;
121			break;
122		case MOP_K_PROTO_LP:
123			fprintf(fd, "MOP LP ");
124			proto = MOP_K_PROTO_LP;
125			break;
126		default:
127			fprintf(fd, "MOP ?? ");
128			break;
129		}
130	}
131
132	if (trans == TRANS_8023)
133		fprintf(fd, "802.3 ");
134
135	mopPrintHWA(fd, src); fprintf(fd, " > ");
136	mopPrintHWA(fd, dst);
137	if (len < 1600)
138		fprintf(fd, " len %4d code %02x ", len, code);
139	else
140		fprintf(fd, " len %4d code %02x ",
141		    (len % 256)*256 + (len /256), code);
142
143	switch (proto) {
144	case MOP_K_PROTO_DL:
145	switch (code) {
146		case MOP_K_CODE_MLT:
147			fprintf(fd, "MLT ");
148			break;
149		case MOP_K_CODE_DCM:
150			fprintf(fd, "DCM ");
151			break;
152		case MOP_K_CODE_MLD:
153			fprintf(fd, "MLD ");
154			break;
155		case MOP_K_CODE_ASV:
156			fprintf(fd, "ASV ");
157			break;
158		case MOP_K_CODE_RMD:
159			fprintf(fd, "RMD ");
160			break;
161		case MOP_K_CODE_RPR:
162			fprintf(fd, "RPR ");
163			break;
164		case MOP_K_CODE_RML:
165			fprintf(fd, "RML ");
166			break;
167		case MOP_K_CODE_RDS:
168			fprintf(fd, "RDS ");
169			break;
170		case MOP_K_CODE_MDD:
171			fprintf(fd, "MDD ");
172			break;
173		case MOP_K_CODE_PLT:
174			fprintf(fd, "PLT ");
175			break;
176		default:
177			fprintf(fd, "??? ");
178			break;
179		}
180		break;
181	case MOP_K_PROTO_RC:
182		switch (code) {
183		case MOP_K_CODE_RID:
184			fprintf(fd, "RID ");
185			break;
186		case MOP_K_CODE_BOT:
187			fprintf(fd, "BOT ");
188			break;
189		case MOP_K_CODE_SID:
190			fprintf(fd, "SID ");
191			break;
192		case MOP_K_CODE_RQC:
193			fprintf(fd, "RQC ");
194			break;
195		case MOP_K_CODE_CNT:
196			fprintf(fd, "CNT ");
197			break;
198		case MOP_K_CODE_RVC:
199			fprintf(fd, "RVC ");
200			break;
201		case MOP_K_CODE_RLC:
202			fprintf(fd, "RLC ");
203			break;
204		case MOP_K_CODE_CCP:
205			fprintf(fd, "CCP ");
206			break;
207		case MOP_K_CODE_CRA:
208			fprintf(fd, "CRA ");
209			break;
210		default:
211			fprintf(fd, "??? ");
212			break;
213		}
214		break;
215	case MOP_K_PROTO_LP:
216		switch (code) {
217		case MOP_K_CODE_ALD:
218			fprintf(fd, "ALD ");
219			break;
220		case MOP_K_CODE_PLD:
221			fprintf(fd, "PLD ");
222			break;
223		default:
224			fprintf(fd, "??? ");
225			break;
226		}
227		break;
228	default:
229		fprintf(fd, "??? ");
230		break;
231	}
232	fprintf(fd, "\n");
233}
234
235void
236mopPrintHeader(FILE *fd, u_char *pkt, int trans)
237{
238	u_char	*dst, *src;
239	u_short	 proto;
240	int	 len, idx = 0;
241
242	trans = mopGetTrans(pkt, trans);
243	mopGetHeader(pkt, &idx, &dst, &src, &proto, &len, trans);
244
245	fprintf(fd, "\nDst          : ");
246	mopPrintHWA(fd, dst);
247	if (mopCmpEAddr(dl_mcst, dst) == 0)
248		fprintf(fd, " MOP Dump/Load Multicast");
249	if (mopCmpEAddr(rc_mcst, dst) == 0)
250		fprintf(fd, " MOP Remote Console Multicast");
251	fprintf(fd, "\n");
252
253	fprintf(fd, "Src          : ");
254	mopPrintHWA(fd, src);
255	fprintf(fd, "\n");
256	fprintf(fd, "Proto        : %04x ", proto);
257
258	switch (proto) {
259	case MOP_K_PROTO_DL:
260		switch (trans) {
261		case TRANS_8023:
262			fprintf(fd, "MOP Dump/Load (802.3)\n");
263			break;
264		default:
265			fprintf(fd, "MOP Dump/Load\n");
266		}
267		break;
268	case MOP_K_PROTO_RC:
269		switch (trans) {
270		case TRANS_8023:
271			fprintf(fd, "MOP Remote Console (802.3)\n");
272			break;
273		default:
274			fprintf(fd, "MOP Remote Console\n");
275		}
276		break;
277	case MOP_K_PROTO_LP:
278		switch (trans) {
279		case TRANS_8023:
280			fprintf(fd, "MOP Loopback (802.3)\n");
281			break;
282		default:
283			fprintf(fd, "MOP Loopback\n");
284		}
285		break;
286	default:
287		fprintf(fd, "\n");
288		break;
289	}
290
291	fprintf(fd, "Length       : %04x (%d)\n", len, len);
292}
293
294void
295mopPrintMopHeader(FILE *fd, u_char *pkt, int trans)
296{
297	u_char	*dst, *src;
298	u_short	 proto;
299	int	 len, idx = 0;
300	u_char   code;
301
302	trans = mopGetTrans(pkt, trans);
303	mopGetHeader(pkt, &idx, &dst, &src, &proto, &len, trans);
304
305	code = mopGetChar(pkt, &idx);
306
307	fprintf(fd, "Code         :   %02x ", code);
308
309	switch (proto) {
310	case MOP_K_PROTO_DL:
311		switch (code) {
312		case MOP_K_CODE_MLT:
313			fprintf(fd, "Memory Load with transfer address\n");
314			break;
315		case MOP_K_CODE_DCM:
316			fprintf(fd, "Dump Complete\n");
317			break;
318		case MOP_K_CODE_MLD:
319			fprintf(fd, "Memory Load\n");
320			break;
321		case MOP_K_CODE_ASV:
322			fprintf(fd, "Assistance volunteer\n");
323			break;
324		case MOP_K_CODE_RMD:
325			fprintf(fd, "Request memory dump\n");
326			break;
327		case MOP_K_CODE_RPR:
328			fprintf(fd, "Request program\n");
329			break;
330		case MOP_K_CODE_RML:
331			fprintf(fd, "Request memory load\n");
332			break;
333		case MOP_K_CODE_RDS:
334			fprintf(fd, "Request Dump Service\n");
335			break;
336		case MOP_K_CODE_MDD:
337			fprintf(fd, "Memory dump data\n");
338			break;
339		case MOP_K_CODE_PLT:
340			fprintf(fd, "Parameter load with transfer address\n");
341			break;
342		default:
343			fprintf(fd, "(unknown)\n");
344			break;
345		}
346		break;
347	case MOP_K_PROTO_RC:
348		switch (code) {
349		case MOP_K_CODE_RID:
350			fprintf(fd, "Request ID\n");
351			break;
352		case MOP_K_CODE_BOT:
353			fprintf(fd, "Boot\n");
354			break;
355		case MOP_K_CODE_SID:
356			fprintf(fd, "System ID\n");
357			break;
358		case MOP_K_CODE_RQC:
359			fprintf(fd, "Request Counters\n");
360			break;
361		case MOP_K_CODE_CNT:
362			fprintf(fd, "Counters\n");
363			break;
364		case MOP_K_CODE_RVC:
365			fprintf(fd, "Reserve Console\n");
366			break;
367		case MOP_K_CODE_RLC:
368			fprintf(fd, "Release Console\n");
369			break;
370		case MOP_K_CODE_CCP:
371			fprintf(fd, "Console Command and Poll\n");
372			break;
373		case MOP_K_CODE_CRA:
374			fprintf(fd, "Console Response and Acknnowledge\n");
375			break;
376		default:
377			fprintf(fd, "(unknown)\n");
378			break;
379		}
380		break;
381	case MOP_K_PROTO_LP:
382		switch (code) {
383		case MOP_K_CODE_ALD:
384			fprintf(fd, "Active loop data\n");
385			break;
386		case MOP_K_CODE_PLD:
387			fprintf(fd, "Passive looped data\n");
388			break;
389		default:
390			fprintf(fd, "(unknown)\n");
391			break;
392		}
393		break;
394	default:
395		fprintf(fd, "(unknown)\n");
396		break;
397	}
398}
399
400void
401mopPrintDevice(FILE *fd, u_char device)
402{
403	char	*sname, *name;
404
405	sname = nmaGetShort((int) device);
406	name = nmaGetDevice((int) device);
407
408	fprintf(fd, "%s '%s'", sname, name);
409}
410
411void
412mopPrintTime(FILE *fd, u_char *ap)
413{
414	fprintf(fd, "%04d-%02d-%02d %02d:%02d:%02d.%02d %d:%02d",
415	    ap[0] * 100 + ap[1], ap[2], ap[3], ap[4], ap[5], ap[6], ap[7],
416	    ap[8], ap[9]);
417}
418
419void
420mopPrintInfo(FILE *fd, u_char *pkt, int *idx, u_short moplen, u_char mopcode,
421    int trans)
422{
423	u_short itype, tmps;
424	u_char  ilen, tmpc, device;
425	u_char  uc1, uc2, uc3, *ucp;
426	int     i;
427
428	device = 0;
429
430	switch (trans) {
431	case TRANS_ETHER:
432		moplen = moplen + 16;
433		break;
434	case TRANS_8023:
435		moplen = moplen + 14;
436		break;
437	}
438
439	itype = mopGetShort(pkt, idx);
440
441	while (*idx < (moplen + 2)) {
442		ilen = mopGetChar(pkt, idx);
443		switch (itype) {
444		case 0:
445			tmpc  = mopGetChar(pkt, idx);
446			*idx = *idx + tmpc;
447			break;
448		case MOP_K_INFO_VER:
449			uc1 = mopGetChar(pkt, idx);
450			uc2 = mopGetChar(pkt, idx);
451			uc3 = mopGetChar(pkt, idx);
452			fprintf(fd, "Maint Version: %d.%d.%d\n", uc1, uc2, uc3);
453			break;
454		case MOP_K_INFO_MFCT:
455			tmps = mopGetShort(pkt, idx);
456			fprintf(fd, "Maint Function: %04x ( ", tmps);
457			if (tmps &   1) fprintf(fd, "Loop ");
458			if (tmps &   2) fprintf(fd, "Dump ");
459			if (tmps &   4) fprintf(fd, "Pldr ");
460			if (tmps &   8) fprintf(fd, "MLdr ");
461			if (tmps &  16) fprintf(fd, "Boot ");
462			if (tmps &  32) fprintf(fd, "CC ");
463			if (tmps &  64) fprintf(fd, "DLC ");
464			if (tmps & 128) fprintf(fd, "CCR ");
465			fprintf(fd, ")\n");
466			break;
467		case MOP_K_INFO_CNU:
468			ucp = pkt + *idx;
469			*idx = *idx + 6;
470			fprintf(fd, "Console User : ");
471			mopPrintHWA(fd, ucp);
472			fprintf(fd, "\n");
473			break;
474		case MOP_K_INFO_RTM:
475			tmps = mopGetShort(pkt, idx);
476			fprintf(fd, "Reserv Timer : %04x (%d)\n", tmps, tmps);
477			break;
478		case MOP_K_INFO_CSZ:
479			tmps = mopGetShort(pkt, idx);
480			fprintf(fd, "Cons Cmd Size: %04x (%d)\n", tmps, tmps);
481			break;
482		case MOP_K_INFO_RSZ:
483			tmps = mopGetShort(pkt, idx);
484			fprintf(fd, "Cons Res Size: %04x (%d)\n", tmps, tmps);
485			break;
486		case MOP_K_INFO_HWA:
487			ucp = pkt + *idx;
488			*idx = *idx + 6;
489			fprintf(fd, "Hardware Addr: ");
490			mopPrintHWA(fd, ucp);
491			fprintf(fd, "\n");
492			break;
493		case MOP_K_INFO_TIME:
494			ucp = pkt + *idx;
495			*idx = *idx + 10;
496			fprintf(fd, "System Time: ");
497			mopPrintTime(fd, ucp);
498			fprintf(fd, "\n");
499			break;
500		case MOP_K_INFO_SOFD:
501			device = mopGetChar(pkt, idx);
502			fprintf(fd, "Comm Device  :   %02x ", device);
503			mopPrintDevice(fd, device);
504			fprintf(fd, "\n");
505			break;
506		case MOP_K_INFO_SFID:
507			tmpc = mopGetChar(pkt, idx);
508			fprintf(fd, "Software ID  :   %02x ", tmpc);
509			if (tmpc == 0)
510				fprintf(fd, "No software id");
511			if (tmpc == 254) {
512				fprintf(fd, "Maintenance system");
513				tmpc = 0;
514			}
515			if (tmpc == 255) {
516				fprintf(fd, "Standard operating system");
517				tmpc = 0;
518			}
519			if (tmpc > 0) {
520				fprintf(fd, "'");
521				for (i = 0; i < ((int) tmpc); i++)
522					fprintf(fd, "%c",
523					    mopGetChar(pkt, idx));
524				fprintf(fd, "'");
525			}
526			fprintf(fd, "\n");
527			break;
528		case MOP_K_INFO_PRTY:
529			tmpc = mopGetChar(pkt, idx);
530			fprintf(fd, "System Proc  :   %02x ", tmpc);
531			switch (tmpc) {
532			case MOP_K_PRTY_11:
533				fprintf(fd, "PDP-11\n");
534				break;
535			case MOP_K_PRTY_CMSV:
536				fprintf(fd, "Communication Server\n");
537				break;
538			case MOP_K_PRTY_PRO:
539				fprintf(fd, "Professional\n");
540				break;
541			case MOP_K_PRTY_SCO:
542				fprintf(fd, "Scorpio\n");
543				break;
544			case MOP_K_PRTY_AMB:
545				fprintf(fd, "Amber\n");
546				break;
547			case MOP_K_PRTY_BRI:
548				fprintf(fd, "XLII Bridge\n");
549				break;
550			default:
551				fprintf(fd, "Unknown\n");
552				break;
553			};
554			break;
555		case MOP_K_INFO_DLTY:
556			tmpc = mopGetChar(pkt, idx);
557			fprintf(fd, "DLnk Type    :   %02x ", tmpc);
558			switch (tmpc) {
559			case MOP_K_DLTY_NI:
560				fprintf(fd, "Ethernet\n");
561				break;
562			case MOP_K_DLTY_DDCMP:
563				fprintf(fd, "DDCMP\n");
564				break;
565			case MOP_K_DLTY_LAPB:
566				fprintf(fd, "LAPB (X.25)\n");
567				break;
568			default:
569				fprintf(fd, "Unknown\n");
570				break;
571			};
572			break;
573		case MOP_K_INFO_DLBSZ:
574			tmps = mopGetShort(pkt, idx);
575			fprintf(fd, "DLnk Buf Size: %04x (%d)\n", tmps, tmps);
576			break;
577		default:
578			if (((device == NMA_C_SOFD_LCS) ||  /* DECserver 100 */
579			     (device == NMA_C_SOFD_DS2) ||  /* DECserver 200 */
580			     (device == NMA_C_SOFD_DP2) ||  /* DECserver 250 */
581			     (device == NMA_C_SOFD_DS3)) && /* DECserver 300 */
582			    ((itype > 101) && (itype < 107)))
583			{
584			switch (itype) {
585				case 102:
586					ucp = pkt + *idx;
587					*idx = *idx + ilen;
588					fprintf(fd, "ROM SW Ver   :   %02x '",
589					    ilen);
590					for (i = 0; i < ilen; i++)
591						fprintf(fd, "%c", ucp[i]);
592					fprintf(fd, "'\n");
593					break;
594				case 103:
595					ucp = pkt + *idx;
596					*idx = *idx + ilen;
597					fprintf(fd, "Loaded SW Ver:   %02x '",
598					    ilen);
599					for (i = 0; i < ilen; i++)
600						fprintf(fd, "%c", ucp[i]);
601					fprintf(fd, "'\n");
602					break;
603				case 104:
604					tmps = mopGetShort(pkt, idx);
605					fprintf(fd,
606					    "DECnet Addr  : %d.%d (%d)\n",
607					    tmps / 1024, tmps % 1024, tmps);
608					break;
609				case 105:
610					ucp = pkt + *idx;
611					*idx = *idx + ilen;
612					fprintf(fd, "Node Name    :   %02x '",
613					    ilen);
614					for (i = 0; i < ilen; i++)
615						fprintf(fd, "%c", ucp[i]);
616					fprintf(fd, "'\n");
617					break;
618				case 106:
619					ucp = pkt + *idx;
620					*idx = *idx + ilen;
621					fprintf(fd, "Node Ident   :   %02x '",
622					    ilen);
623					for (i = 0; i < ilen; i++)
624						fprintf(fd, "%c", ucp[i]);
625					fprintf(fd, "'\n");
626					break;
627				}
628			} else {
629				ucp = pkt + *idx;
630				*idx = *idx + ilen;
631				fprintf(fd, "Info Type    : %04x (%d)\n",
632				    itype, itype);
633				fprintf(fd, "Info Data    :   %02x ", ilen);
634				for (i = 0; i < ilen; i++) {
635					if ((i % 16) == 0)
636						if ((i / 16) != 0)
637							fprintf(fd,
638						     "\n                    ");
639					fprintf(fd, "%02x ", ucp[i]);
640				}
641				fprintf(fd, "\n");
642			}
643		}
644		itype = mopGetShort(pkt, idx);
645	}
646}
647