Home | History | Annotate | Download | only in snoop
      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 *
     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 *
     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
     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
    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