some compilers dont like unnamed unions and structs
[obnox/wireshark/wip.git] / epan / dissectors / packet-redback.c
1 /* packet-redback.c
2  *
3  * $Id$
4  *
5  * Wireshark - Network traffic analyzer
6  * By Gerald Combs <gerald@wireshark.org>
7  *
8  * Start of RedBack SE400/800 tcpdump trace disassembly
9  * Copyright 2005,2006 Florian Lohoff <flo@rfc822.org>
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
24  */
25
26 #ifdef HAVE_CONFIG_H
27 # include "config.h"
28 #endif
29
30 #include <glib.h>
31 #include <epan/packet.h>
32 #include <epan/etypes.h>
33 #include <epan/prefs.h>
34 #include <epan/addr_resolv.h>
35 #include "packet-ip.h"
36
37 static int proto_redback = -1;
38 static gint ett_redback = -1;
39
40 static dissector_handle_t ipv4_handle;
41 static dissector_handle_t eth_handle;
42 static dissector_handle_t clnp_handle;
43 static dissector_handle_t arp_handle;
44
45 /* wrapper for passing the PIC type to the generic ATM dissector */
46 static void
47 dissect_redback(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
48 {
49   guint8     l3off, dataoff, proto;
50   guint32    context, flags;
51   guint64    circuit;
52   guint16    length;
53   proto_item *ti,*tisub;
54   proto_tree *subtree = NULL;
55   tvbuff_t   *next_tvb;
56
57   context = tvb_get_ntohl(tvb, 0);
58   flags = tvb_get_ntohl(tvb, 4);
59   circuit = tvb_get_ntoh64(tvb, 8);
60
61   length = tvb_get_ntohs(tvb, 16);
62
63   proto = (guint8) tvb_get_ntohs(tvb, 18);
64   l3off = (guint8) tvb_get_ntohs(tvb, 20);
65   dataoff = (guint8) tvb_get_ntohs(tvb, 22);
66
67   ti = proto_tree_add_text(tree, tvb, 0, length, "Redback");
68
69   subtree = proto_item_add_subtree(ti, ett_redback);  
70   tisub = proto_tree_add_text (subtree, tvb, 0, 4,
71                             "Context: 0x%08x", context);
72   tisub = proto_tree_add_text (subtree, tvb, 4, 4,
73                             "Flags: 0x%08x", flags);
74   tisub = proto_tree_add_text (subtree, tvb, 8, 8,
75                             "Circuit: 0x%" PRIx64, circuit);
76   tisub = proto_tree_add_text (subtree, tvb, 16, 2,
77                             "Length: %u", length);
78   tisub = proto_tree_add_text (subtree, tvb, 18, 2,
79                             "Protocol: %u", proto);
80   tisub = proto_tree_add_text (subtree, tvb, 20, 2,
81                             "Layer3 Offset: %u", l3off);
82   tisub = proto_tree_add_text (subtree, tvb, 22, 2,
83                             "Data Offset: %u", dataoff);
84   next_tvb = tvb_new_subset(tvb, l3off, -1, -1);
85
86   /* Mark the gap as "Data" for now */
87   if (dataoff > l3off) {
88         proto_tree_add_text (subtree, tvb, 24, l3off-24, "Data (%d bytes)", l3off-24);  
89   }
90
91   /*
92    * Just a guess - In case we see a difference in dataoff vs l3off
93    * we assume there is an ethernet header. Traces from an OC12 didnt
94    * show any header in here
95    */
96   if (dataoff > l3off) {
97     call_dissector(eth_handle, next_tvb, pinfo, tree);
98   } else {
99     switch(proto) {
100       case 0x01:
101         /*
102          * IP - We assume IPv6 has a different protocol although
103          * i might be wrong - Havent seen any traces
104          */
105         call_dissector(ipv4_handle, next_tvb, pinfo, tree);
106         break;
107       case 0x02:
108         /*
109          * It is CLNP although it seem the Packet Asic fills
110          * some data in the packet so we have a "broken" packet in
111          * the trace
112          */
113         call_dissector(clnp_handle, next_tvb, pinfo, tree);
114         break;
115       case 0x03: /* Unicast Ethernet tx - Seen with PPPoE PADO */
116       case 0x04: /* Unicast Ethernet rx - Seen with ARP  */
117       case 0x08: /* Broadcast Ethernet rx - Seen with PPPoE PADI */
118         call_dissector(eth_handle, next_tvb, pinfo, tree);
119         break;
120       default:
121         tisub = proto_tree_add_text (subtree, tvb, 24, length-24,
122                                 "Unknown Protocol Data %u", proto);
123         break;
124     }
125   }
126   return;
127 }
128
129 void
130 proto_register_redback(void)
131 {
132   static gint *ett[] = {
133     &ett_redback,
134   };
135
136   proto_redback = proto_register_protocol("Redback", "Redback", "redback");
137   proto_register_subtree_array(ett, array_length(ett));
138
139 }
140
141 void
142 proto_reg_handoff_redback(void)
143 {
144   dissector_handle_t redback_handle;
145
146   ipv4_handle = find_dissector("ip");
147   eth_handle = find_dissector("eth_withoutfcs");
148   clnp_handle = find_dissector("clnp");
149   arp_handle = find_dissector("arp");
150
151   redback_handle = create_dissector_handle(dissect_redback, proto_redback);
152   dissector_add("wtap_encap", WTAP_ENCAP_REDBACK, redback_handle);
153 }
154
155