/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright (c) 2001 by Sun Microsystems, Inc. * All rights reserved. */ #include #include #include #include static void show_rtmp_tuples(uint8_t *, int); static char * rtmp_func_long(uint8_t fun) { switch (fun) { case RTMP_REQ: return ("Request"); case RTMP_RDR_SH: return ("Route Data Request, split horizon"); case RTMP_RDR_NSH: return ("Route Data Request, no split horizon"); default: return ("unknown"); } } static char * rtmp_func_short(uint8_t fun) { switch (fun) { case RTMP_REQ: return ("Req"); case RTMP_RDR_SH: return ("RDR, sh"); case RTMP_RDR_NSH: return ("RDR, no sh"); default: return ("unknown"); } } void interpret_rtmp(int flags, struct ddp_hdr *ddp, int len) { uint8_t *data; uint16_t snet; uint8_t node; int tuples; int runt; char extended; len -= DDPHDR_SIZE; if (len < 0) goto out; data = (uint8_t *)ddp + DDPHDR_SIZE; switch (ddp->ddp_type) { case DDP_TYPE_RTMPRQ: /* simple rtmp */ if (len < 1) goto out; if (flags & F_SUM) { (void) snprintf(get_sum_line(), MAXLINE, "RTMP F=%s", rtmp_func_short(data[0])); } if (flags & F_DTAIL) { show_header("RTMP: ", "RTMP Header", len); show_space(); (void) snprintf(get_line(0, 0), get_line_remain(), "Func = %d (%s)", data[0], rtmp_func_long(data[0])); } break; case DDP_TYPE_RTMPRESP: /* RTMP data */ if (len < 3) goto out; snet = get_short(data); if (data[2] != 8) /* ID length is always 8 */ return; node = data[3]; /* assume id_len == 8 */ extended = (data[6] != RTMP_FILLER) && (get_short(&data[4]) != 0); tuples = (len - 4) / 3; runt = (len - 4) % 3; /* integral length? */ if (flags & F_SUM) { (void) snprintf(get_sum_line(), MAXLINE, "RTMP Data Snet=%d, Snode=%d%s", snet, node, runt != 0 ? " (short)" : ""); } if (flags & F_DTAIL) { show_header("RTMP: ", "RTMP Header", len); show_space(); (void) snprintf(get_line(0, 0), get_line_remain(), "RTMP Data, Length = %d%s", len, runt != 0 ? " (short packet)" : ""); (void) snprintf(get_line(0, 0), get_line_remain(), "Senders Net = %d, Sender Node %d", snet, node); if (extended) show_rtmp_tuples(&data[4], tuples); else show_rtmp_tuples(&data[7], tuples-1); } break; } return; out: if (flags & F_SUM) { (void) snprintf(get_sum_line(), MAXLINE, "RTMP (short packet)"); } if (flags & F_DTAIL) { show_header("RTMP: ", "RTMP Header", len); show_space(); (void) snprintf(get_line(0, 0), get_line_remain(), "(short packet)"); } } static void show_rtmp_tuples(uint8_t *p, int tuples) { while (tuples > 0) { if (p[2] & RTMP_EXTEND) { /* extended tuple? */ (void) snprintf(get_line(0, 0), get_line_remain(), "Network = %d-%d, Distance = %d", get_short(p), get_short(&p[3]), p[2] & RTMP_DIST_MASK); p += 6; tuples -= 2; } else { (void) snprintf(get_line(0, 0), get_line_remain(), "Network = %d, Distance = %d", get_short(p), p[2]); p += 3; tuples--; } } }