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 #include <stdio.h>
28 #include <sys/types.h>
29 
30 #include <at.h>
31 #include <snoop.h>
32 
33 static void show_rtmp_tuples(uint8_t *, int);
34 
35 static char *
rtmp_func_long(uint8_t fun)36 rtmp_func_long(uint8_t fun)
37 {
38 	switch (fun) {
39 	case RTMP_REQ:
40 		return ("Request");
41 	case RTMP_RDR_SH:
42 		return ("Route Data Request, split horizon");
43 	case RTMP_RDR_NSH:
44 		return ("Route Data Request, no split horizon");
45 	default:
46 		return ("unknown");
47 	}
48 }
49 
50 static char *
rtmp_func_short(uint8_t fun)51 rtmp_func_short(uint8_t fun)
52 {
53 	switch (fun) {
54 	case RTMP_REQ:
55 		return ("Req");
56 	case RTMP_RDR_SH:
57 		return ("RDR, sh");
58 	case RTMP_RDR_NSH:
59 		return ("RDR, no sh");
60 	default:
61 		return ("unknown");
62 	}
63 }
64 
65 void
interpret_rtmp(int flags,struct ddp_hdr * ddp,int len)66 interpret_rtmp(int flags, struct ddp_hdr *ddp, int len)
67 {
68 	uint8_t *data;
69 	uint16_t snet;
70 	uint8_t node;
71 	int tuples;
72 	int runt;
73 	char extended;
74 
75 	len -= DDPHDR_SIZE;
76 	if (len < 0)
77 		goto out;
78 
79 	data = (uint8_t *)ddp + DDPHDR_SIZE;
80 
81 	switch (ddp->ddp_type) {
82 	case DDP_TYPE_RTMPRQ:		/* simple rtmp */
83 		if (len < 1)
84 			goto out;
85 
86 		if (flags & F_SUM) {
87 			(void) snprintf(get_sum_line(), MAXLINE,
88 			    "RTMP F=%s",
89 			    rtmp_func_short(data[0]));
90 		}
91 
92 		if (flags & F_DTAIL) {
93 			show_header("RTMP: ", "RTMP Header", len);
94 			show_space();
95 
96 			(void) snprintf(get_line(0, 0), get_line_remain(),
97 			    "Func = %d (%s)",
98 			    data[0], rtmp_func_long(data[0]));
99 		}
100 		break;
101 	case DDP_TYPE_RTMPRESP:		/* RTMP data */
102 		if (len < 3)
103 			goto out;
104 
105 		snet = get_short(data);
106 		if (data[2] != 8)	/* ID length is always 8 */
107 			return;
108 		node = data[3];		/* assume id_len == 8 */
109 		extended = (data[6] != RTMP_FILLER) &&
110 		    (get_short(&data[4]) != 0);
111 
112 		tuples = (len - 4) / 3;
113 		runt = (len - 4) % 3; /* integral length? */
114 
115 		if (flags & F_SUM) {
116 			(void) snprintf(get_sum_line(), MAXLINE,
117 			    "RTMP Data Snet=%d, Snode=%d%s",
118 			    snet, node, runt != 0 ? " (short)" : "");
119 		}
120 
121 		if (flags & F_DTAIL) {
122 			show_header("RTMP: ", "RTMP Header", len);
123 			show_space();
124 
125 			(void) snprintf(get_line(0, 0), get_line_remain(),
126 			    "RTMP Data, Length = %d%s",
127 			    len, runt != 0 ? " (short packet)" : "");
128 			(void) snprintf(get_line(0, 0), get_line_remain(),
129 			    "Senders Net = %d, Sender Node %d",
130 			    snet, node);
131 			if (extended)
132 				show_rtmp_tuples(&data[4], tuples);
133 			else
134 				show_rtmp_tuples(&data[7], tuples-1);
135 		}
136 
137 		break;
138 	}
139 	return;
140 out:
141 	if (flags & F_SUM) {
142 		(void) snprintf(get_sum_line(), MAXLINE,
143 		    "RTMP (short packet)");
144 	}
145 
146 	if (flags & F_DTAIL) {
147 		show_header("RTMP: ", "RTMP Header", len);
148 		show_space();
149 
150 		(void) snprintf(get_line(0, 0), get_line_remain(),
151 		    "(short packet)");
152 	}
153 }
154 
155 static void
show_rtmp_tuples(uint8_t * p,int tuples)156 show_rtmp_tuples(uint8_t *p, int tuples)
157 {
158 	while (tuples > 0) {
159 
160 		if (p[2] & RTMP_EXTEND) { /* extended tuple? */
161 
162 			(void) snprintf(get_line(0, 0),
163 			    get_line_remain(),
164 			    "Network = %d-%d, Distance = %d",
165 			    get_short(p), get_short(&p[3]),
166 			    p[2] & RTMP_DIST_MASK);
167 			p += 6;
168 			tuples -= 2;
169 		} else {
170 
171 			(void) snprintf(get_line(0, 0),
172 			    get_line_remain(),
173 			    "Network = %d, Distance = %d",
174 			    get_short(p), p[2]);
175 			p += 3;
176 			tuples--;
177 		}
178 	}
179 }
180