1 0 stevel /* 2 0 stevel * CDDL HEADER START 3 0 stevel * 4 0 stevel * The contents of this file are subject to the terms of the 5 0 stevel * Common Development and Distribution License, Version 1.0 only 6 0 stevel * (the "License"). You may not use this file except in compliance 7 0 stevel * with the License. 8 0 stevel * 9 0 stevel * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 0 stevel * or http://www.opensolaris.org/os/licensing. 11 0 stevel * See the License for the specific language governing permissions 12 0 stevel * and limitations under the License. 13 0 stevel * 14 0 stevel * When distributing Covered Code, include this CDDL HEADER in each 15 0 stevel * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 0 stevel * If applicable, add the following below this CDDL HEADER, with the 17 0 stevel * fields enclosed by brackets "[]" replaced with your own identifying 18 0 stevel * information: Portions Copyright [yyyy] [name of copyright owner] 19 0 stevel * 20 0 stevel * CDDL HEADER END 21 0 stevel */ 22 0 stevel /* 23 0 stevel * Copyright (c) 2001 by Sun Microsystems, Inc. 24 0 stevel * All rights reserved. 25 0 stevel */ 26 0 stevel 27 0 stevel #pragma ident "%Z%%M% %I% %E% SMI" 28 0 stevel 29 0 stevel #include <stdio.h> 30 0 stevel #include <sys/types.h> 31 0 stevel 32 0 stevel #include <at.h> 33 0 stevel #include <snoop.h> 34 0 stevel 35 0 stevel static void show_rtmp_tuples(uint8_t *, int); 36 0 stevel 37 0 stevel static char * 38 0 stevel rtmp_func_long(uint8_t fun) 39 0 stevel { 40 0 stevel switch (fun) { 41 0 stevel case RTMP_REQ: 42 0 stevel return ("Request"); 43 0 stevel case RTMP_RDR_SH: 44 0 stevel return ("Route Data Request, split horizon"); 45 0 stevel case RTMP_RDR_NSH: 46 0 stevel return ("Route Data Request, no split horizon"); 47 0 stevel default: 48 0 stevel return ("unknown"); 49 0 stevel } 50 0 stevel } 51 0 stevel 52 0 stevel static char * 53 0 stevel rtmp_func_short(uint8_t fun) 54 0 stevel { 55 0 stevel switch (fun) { 56 0 stevel case RTMP_REQ: 57 0 stevel return ("Req"); 58 0 stevel case RTMP_RDR_SH: 59 0 stevel return ("RDR, sh"); 60 0 stevel case RTMP_RDR_NSH: 61 0 stevel return ("RDR, no sh"); 62 0 stevel default: 63 0 stevel return ("unknown"); 64 0 stevel } 65 0 stevel } 66 0 stevel 67 0 stevel void 68 0 stevel interpret_rtmp(int flags, struct ddp_hdr *ddp, int len) 69 0 stevel { 70 0 stevel uint8_t *data; 71 0 stevel uint16_t snet; 72 0 stevel uint8_t node; 73 0 stevel int tuples; 74 0 stevel int runt; 75 0 stevel char extended; 76 0 stevel 77 0 stevel len -= DDPHDR_SIZE; 78 0 stevel if (len < 0) 79 0 stevel goto out; 80 0 stevel 81 0 stevel data = (uint8_t *)ddp + DDPHDR_SIZE; 82 0 stevel 83 0 stevel switch (ddp->ddp_type) { 84 0 stevel case DDP_TYPE_RTMPRQ: /* simple rtmp */ 85 0 stevel if (len < 1) 86 0 stevel goto out; 87 0 stevel 88 0 stevel if (flags & F_SUM) { 89 0 stevel (void) snprintf(get_sum_line(), MAXLINE, 90 0 stevel "RTMP F=%s", 91 0 stevel rtmp_func_short(data[0])); 92 0 stevel } 93 0 stevel 94 0 stevel if (flags & F_DTAIL) { 95 0 stevel show_header("RTMP: ", "RTMP Header", len); 96 0 stevel show_space(); 97 0 stevel 98 0 stevel (void) snprintf(get_line(0, 0), get_line_remain(), 99 0 stevel "Func = %d (%s)", 100 0 stevel data[0], rtmp_func_long(data[0])); 101 0 stevel } 102 0 stevel break; 103 0 stevel case DDP_TYPE_RTMPRESP: /* RTMP data */ 104 0 stevel if (len < 3) 105 0 stevel goto out; 106 0 stevel 107 0 stevel snet = get_short(data); 108 0 stevel if (data[2] != 8) /* ID length is always 8 */ 109 0 stevel return; 110 0 stevel node = data[3]; /* assume id_len == 8 */ 111 0 stevel extended = (data[6] != RTMP_FILLER) && 112 0 stevel (get_short(&data[4]) != 0); 113 0 stevel 114 0 stevel tuples = (len - 4) / 3; 115 0 stevel runt = (len - 4) % 3; /* integral length? */ 116 0 stevel 117 0 stevel if (flags & F_SUM) { 118 0 stevel (void) snprintf(get_sum_line(), MAXLINE, 119 0 stevel "RTMP Data Snet=%d, Snode=%d%s", 120 0 stevel snet, node, runt != 0 ? " (short)" : ""); 121 0 stevel } 122 0 stevel 123 0 stevel if (flags & F_DTAIL) { 124 0 stevel show_header("RTMP: ", "RTMP Header", len); 125 0 stevel show_space(); 126 0 stevel 127 0 stevel (void) snprintf(get_line(0, 0), get_line_remain(), 128 0 stevel "RTMP Data, Length = %d%s", 129 0 stevel len, runt != 0 ? " (short packet)" : ""); 130 0 stevel (void) snprintf(get_line(0, 0), get_line_remain(), 131 0 stevel "Senders Net = %d, Sender Node %d", 132 0 stevel snet, node); 133 0 stevel if (extended) 134 0 stevel show_rtmp_tuples(&data[4], tuples); 135 0 stevel else 136 0 stevel show_rtmp_tuples(&data[7], tuples-1); 137 0 stevel } 138 0 stevel 139 0 stevel break; 140 0 stevel } 141 0 stevel return; 142 0 stevel out: 143 0 stevel if (flags & F_SUM) { 144 0 stevel (void) snprintf(get_sum_line(), MAXLINE, 145 0 stevel "RTMP (short packet)"); 146 0 stevel } 147 0 stevel 148 0 stevel if (flags & F_DTAIL) { 149 0 stevel show_header("RTMP: ", "RTMP Header", len); 150 0 stevel show_space(); 151 0 stevel 152 0 stevel (void) snprintf(get_line(0, 0), get_line_remain(), 153 0 stevel "(short packet)"); 154 0 stevel } 155 0 stevel } 156 0 stevel 157 0 stevel static void 158 0 stevel show_rtmp_tuples(uint8_t *p, int tuples) 159 0 stevel { 160 0 stevel while (tuples > 0) { 161 0 stevel 162 0 stevel if (p[2] & RTMP_EXTEND) { /* extended tuple? */ 163 0 stevel 164 0 stevel (void) snprintf(get_line(0, 0), 165 0 stevel get_line_remain(), 166 0 stevel "Network = %d-%d, Distance = %d", 167 0 stevel get_short(p), get_short(&p[3]), 168 0 stevel p[2] & RTMP_DIST_MASK); 169 0 stevel p += 6; 170 0 stevel tuples -= 2; 171 0 stevel } else { 172 0 stevel 173 0 stevel (void) snprintf(get_line(0, 0), 174 0 stevel get_line_remain(), 175 0 stevel "Network = %d, Distance = %d", 176 0 stevel get_short(p), p[2]); 177 0 stevel p += 3; 178 0 stevel tuples--; 179 0 stevel } 180 0 stevel } 181 0 stevel } 182