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