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) 2001 by Sun Microsystems, Inc.
24 * All rights reserved.
25 */
26
27#pragma ident	"%Z%%M%	%I%	%E% SMI"
28
29#include <stdio.h>
30#include <sys/types.h>
31
32#include <at.h>
33#include <snoop.h>
34
35static void show_nbp_tuples(uint8_t *, int, uint8_t *);
36
37static char *nbp_short[] = {
38	"0",				/* 0 */
39	"BRRQ   ",			/* 1 */
40	"LKUP C ",			/* 2 */
41	"LKUP R ",			/* 3 */
42	"FWD    ",			/* 4 */
43	"5      ",
44	"6      ",
45	"7      ",
46	"8      ",
47	"9      ",
48	"10     ",
49	"11     ",
50	"RGSTR  ",			/* 12 */
51	"UNRGSTR",			/* 13 */
52	"OK     ",			/* 14 */
53	"ERROR  ",			/* 15 */
54};
55
56void
57interpret_nbp(int flags, struct nbp_hdr *nbp, int len)
58{
59	uint8_t *data;
60	int nbp_cnt = nbp->nbp_fun_cnt & 0xf; /* lower four bits */
61	int nbp_op = (nbp->nbp_fun_cnt >> 4) & 0xf; /* upper four bits */
62
63	data = (uint8_t *)(nbp + 1);
64
65	if (flags & F_SUM) {
66		if (len < sizeof (struct nbp_hdr)) {
67			(void) snprintf(get_sum_line(), MAXLINE,
68			    "NBP (short packet)");
69			return;
70		}
71		(void) snprintf(get_sum_line(), MAXLINE,
72		    "NBP F=%s CNT=%d ID=%d", nbp_short[nbp_op],
73		    nbp_cnt, nbp->nbp_id);
74	}
75
76	if (flags & F_DTAIL) {
77		show_header("NBP:  ", "NBP Header", len);
78		show_space();
79
80		if (len < sizeof (struct nbp_hdr)) {
81			(void) snprintf(get_line(0, 0), get_line_remain(),
82			    "NBP (short packet)");
83			return;
84		}
85		(void) snprintf(get_line(0, 0), get_line_remain(),
86		    "Length = %d", len);
87
88		(void) snprintf(get_line(0, 0), get_line_remain(),
89		    "Func = %d (%s)", nbp_op, nbp_short[nbp_op]);
90
91		(void) snprintf(get_line(0, 0), get_line_remain(),
92		    "Tuple count = %d", nbp_cnt);
93		(void) snprintf(get_line(0, 0), get_line_remain(),
94		    "Id = %d", nbp->nbp_id);
95		show_nbp_tuples(data, nbp_cnt, ((uint8_t *)nbp) + len);
96	}
97}
98
99static void
100show_nbp_tuples(uint8_t *p, int tuples, uint8_t *tail)
101{
102	uint16_t net;
103	uint8_t node;
104	uint8_t sock;
105	uint8_t enumer;
106	char obj[100];
107	char *op;
108	char *otail = &obj[sizeof (obj)];
109
110	while (tuples--) {
111		op = obj;
112		if ((p + 5) > tail)
113			goto out;
114		net = get_short(p);
115		p += 2;
116		node = *p++;
117		sock = *p++;
118		enumer = *p++;
119
120		if (p > tail || &p[1]+p[0] > tail)
121			goto out;
122		op += snprintf(op, otail-op, "%.*s", p[0], &p[1]);
123
124		p = &p[1]+p[0];
125		if (p > tail || &p[1]+p[0] > tail)
126			goto out;
127		op += snprintf(op, otail-op, ":%.*s", p[0], &p[1]);
128
129		p = &p[1]+p[0];
130		if (p > tail || &p[1]+p[0] > tail)
131			goto out;
132		(void) snprintf(op, otail-op, "@%.*s", p[0], &p[1]);
133		p = &p[1]+p[0];
134
135		(void) snprintf(get_line(0, 0), get_line_remain(),
136		    "Name = \"%s\"", obj);
137		(void) snprintf(get_line(0, 0), get_line_remain(),
138		    "Net = %d, node = %d, sock = %d, enum = %d",
139		    net, node, sock, enumer);
140	}
141	return;
142out:
143	(void) snprintf(get_line(0, 0), get_line_remain(),
144	    "NBP (short tuple)");
145}
146