1*4eaa4710SRishi Srivatsavai /*
2*4eaa4710SRishi Srivatsavai  * CDDL HEADER START
3*4eaa4710SRishi Srivatsavai  *
4*4eaa4710SRishi Srivatsavai  * The contents of this file are subject to the terms of the
5*4eaa4710SRishi Srivatsavai  * Common Development and Distribution License (the "License").
6*4eaa4710SRishi Srivatsavai  * You may not use this file except in compliance with the License.
7*4eaa4710SRishi Srivatsavai  *
8*4eaa4710SRishi Srivatsavai  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*4eaa4710SRishi Srivatsavai  * or http://www.opensolaris.org/os/licensing.
10*4eaa4710SRishi Srivatsavai  * See the License for the specific language governing permissions
11*4eaa4710SRishi Srivatsavai  * and limitations under the License.
12*4eaa4710SRishi Srivatsavai  *
13*4eaa4710SRishi Srivatsavai  * When distributing Covered Code, include this CDDL HEADER in each
14*4eaa4710SRishi Srivatsavai  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*4eaa4710SRishi Srivatsavai  * If applicable, add the following below this CDDL HEADER, with the
16*4eaa4710SRishi Srivatsavai  * fields enclosed by brackets "[]" replaced with your own identifying
17*4eaa4710SRishi Srivatsavai  * information: Portions Copyright [yyyy] [name of copyright owner]
18*4eaa4710SRishi Srivatsavai  *
19*4eaa4710SRishi Srivatsavai  * CDDL HEADER END
20*4eaa4710SRishi Srivatsavai  */
21*4eaa4710SRishi Srivatsavai 
22*4eaa4710SRishi Srivatsavai /*
23*4eaa4710SRishi Srivatsavai  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24*4eaa4710SRishi Srivatsavai  * Use is subject to license terms.
25*4eaa4710SRishi Srivatsavai  */
26*4eaa4710SRishi Srivatsavai 
27*4eaa4710SRishi Srivatsavai #include <stdio.h>
28*4eaa4710SRishi Srivatsavai #include <sys/types.h>
29*4eaa4710SRishi Srivatsavai #include <sys/socket.h>
30*4eaa4710SRishi Srivatsavai #include <sys/ethernet.h>
31*4eaa4710SRishi Srivatsavai #include <sys/vlan.h>
32*4eaa4710SRishi Srivatsavai #include <net/trill.h>
33*4eaa4710SRishi Srivatsavai 
34*4eaa4710SRishi Srivatsavai #include <snoop.h>
35*4eaa4710SRishi Srivatsavai 
36*4eaa4710SRishi Srivatsavai int
interpret_trill(int flags,struct ether_header ** e,char * data,int * alen)37*4eaa4710SRishi Srivatsavai interpret_trill(int flags, struct ether_header **e, char *data, int *alen)
38*4eaa4710SRishi Srivatsavai {
39*4eaa4710SRishi Srivatsavai 	trill_header_t *trillhdr;
40*4eaa4710SRishi Srivatsavai 	struct ether_header *inner_ethhdr;
41*4eaa4710SRishi Srivatsavai 	struct ether_vlan_header *inner_ethvlanhdr;
42*4eaa4710SRishi Srivatsavai 	uint16_t ethertype;
43*4eaa4710SRishi Srivatsavai 	int dlen = *alen;
44*4eaa4710SRishi Srivatsavai 	size_t optslen;
45*4eaa4710SRishi Srivatsavai 	size_t trillhdrlen;
46*4eaa4710SRishi Srivatsavai 
47*4eaa4710SRishi Srivatsavai 	if (dlen < sizeof (trill_header_t)) {
48*4eaa4710SRishi Srivatsavai 		(void) snprintf(get_sum_line(), MAXLINE,
49*4eaa4710SRishi Srivatsavai 		    "TRILL (short packet)");
50*4eaa4710SRishi Srivatsavai 		return (0);
51*4eaa4710SRishi Srivatsavai 	}
52*4eaa4710SRishi Srivatsavai 
53*4eaa4710SRishi Srivatsavai 	trillhdr = (trill_header_t *)data;
54*4eaa4710SRishi Srivatsavai 	optslen = GET_TRILL_OPTS_LEN(trillhdr) * sizeof (uint32_t);
55*4eaa4710SRishi Srivatsavai 
56*4eaa4710SRishi Srivatsavai 	if (flags & F_DTAIL) {
57*4eaa4710SRishi Srivatsavai 		show_header("TRILL: ", "TRILL Data Frame", dlen);
58*4eaa4710SRishi Srivatsavai 		show_space();
59*4eaa4710SRishi Srivatsavai 
60*4eaa4710SRishi Srivatsavai 		(void) snprintf(get_line(0, 0), get_line_remain(),
61*4eaa4710SRishi Srivatsavai 		    "Egress nickname = %d",
62*4eaa4710SRishi Srivatsavai 		    ntohs(trillhdr->th_egressnick));
63*4eaa4710SRishi Srivatsavai 		(void) snprintf(get_line(0, 0), get_line_remain(),
64*4eaa4710SRishi Srivatsavai 		    "Ingress nickname = %d",
65*4eaa4710SRishi Srivatsavai 		    ntohs(trillhdr->th_ingressnick));
66*4eaa4710SRishi Srivatsavai 		(void) snprintf(get_line(0, 0), get_line_remain(),
67*4eaa4710SRishi Srivatsavai 		    "Hop count = %d", trillhdr->th_hopcount);
68*4eaa4710SRishi Srivatsavai 		(void) snprintf(get_line(0, 0), get_line_remain(),
69*4eaa4710SRishi Srivatsavai 		    "Multi-destination = %d", trillhdr->th_multidest);
70*4eaa4710SRishi Srivatsavai 		(void) snprintf(get_line(0, 0), get_line_remain(),
71*4eaa4710SRishi Srivatsavai 		    "Options Len = %d bytes", optslen);
72*4eaa4710SRishi Srivatsavai 		show_trailer();
73*4eaa4710SRishi Srivatsavai 	}
74*4eaa4710SRishi Srivatsavai 
75*4eaa4710SRishi Srivatsavai 	trillhdrlen = sizeof (trill_header_t) + optslen;
76*4eaa4710SRishi Srivatsavai 
77*4eaa4710SRishi Srivatsavai 	if (dlen < trillhdrlen) {
78*4eaa4710SRishi Srivatsavai 		(void) snprintf(get_sum_line(), MAXLINE,
79*4eaa4710SRishi Srivatsavai 		    "TRILL (options truncated)");
80*4eaa4710SRishi Srivatsavai 		return (0);
81*4eaa4710SRishi Srivatsavai 	}
82*4eaa4710SRishi Srivatsavai 
83*4eaa4710SRishi Srivatsavai 	dlen -= trillhdrlen;
84*4eaa4710SRishi Srivatsavai 
85*4eaa4710SRishi Srivatsavai 	if (dlen < sizeof (struct ether_header)) {
86*4eaa4710SRishi Srivatsavai 		(void) snprintf(get_sum_line(), MAXLINE,
87*4eaa4710SRishi Srivatsavai 		    "TRILL (missing required inner MAC)");
88*4eaa4710SRishi Srivatsavai 		return (0);
89*4eaa4710SRishi Srivatsavai 	}
90*4eaa4710SRishi Srivatsavai 
91*4eaa4710SRishi Srivatsavai 	inner_ethhdr = (struct ether_header *)(data + trillhdrlen);
92*4eaa4710SRishi Srivatsavai 	if (inner_ethhdr->ether_type != htons(ETHERTYPE_VLAN)) {
93*4eaa4710SRishi Srivatsavai 		(void) snprintf(get_sum_line(), MAXLINE,
94*4eaa4710SRishi Srivatsavai 		    "TRILL (inner VLAN missing; ethertype %X)",
95*4eaa4710SRishi Srivatsavai 		    ntohs(inner_ethhdr->ether_type));
96*4eaa4710SRishi Srivatsavai 		return (0);
97*4eaa4710SRishi Srivatsavai 	}
98*4eaa4710SRishi Srivatsavai 
99*4eaa4710SRishi Srivatsavai 	inner_ethvlanhdr = (struct ether_vlan_header *)inner_ethhdr;
100*4eaa4710SRishi Srivatsavai 	ethertype = ntohs(inner_ethvlanhdr->ether_type);
101*4eaa4710SRishi Srivatsavai 
102*4eaa4710SRishi Srivatsavai 	if (flags & F_SUM) {
103*4eaa4710SRishi Srivatsavai 		(void) snprintf(get_sum_line(), MAXLINE,
104*4eaa4710SRishi Srivatsavai 		    "TRILL D:%d S:%d HC:%d M:%d O:%d L:%d VLAN:%d %s",
105*4eaa4710SRishi Srivatsavai 		    ntohs(trillhdr->th_egressnick),
106*4eaa4710SRishi Srivatsavai 		    ntohs(trillhdr->th_ingressnick),
107*4eaa4710SRishi Srivatsavai 		    trillhdr->th_hopcount,
108*4eaa4710SRishi Srivatsavai 		    trillhdr->th_multidest,
109*4eaa4710SRishi Srivatsavai 		    optslen,
110*4eaa4710SRishi Srivatsavai 		    dlen, VLAN_ID(inner_ethvlanhdr->ether_tci),
111*4eaa4710SRishi Srivatsavai 		    print_ethertype(ethertype));
112*4eaa4710SRishi Srivatsavai 	}
113*4eaa4710SRishi Srivatsavai 
114*4eaa4710SRishi Srivatsavai 	*alen = dlen;
115*4eaa4710SRishi Srivatsavai 	*e = inner_ethhdr;
116*4eaa4710SRishi Srivatsavai 	return (ethertype);
117*4eaa4710SRishi Srivatsavai }
118