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 * 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 * 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 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 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