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