HACK: pinfo->private_data points to smb_info again
[wireshark-wip.git] / epan / dissectors / packet-nt-tpcp.c
blob2b08a159fa0c8e46fd9053c9c59baecda8f9e0da
1 /* packet-tpcp.c
2 * Routines for Transparent Proxy Cache Protocol packet disassembly
3 * (c) Copyright Giles Scott <giles.scott1 [AT] btinternet.com>
5 * $Id$
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
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.
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.
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 #include "config.h"
28 #include <string.h>
30 #include <glib.h>
32 #include <epan/packet.h>
33 #include <epan/addr_resolv.h> /* this is for get_hostname and get_udp_port */
35 #define UDP_PORT_TPCP 3121
37 /* TPCP version1/2 PDU format */
38 typedef struct _tpcppdu_t {
39 guint8 version; /* PDU version 1 */
40 guint8 type; /* PDU type: 1=request, 2=reply, 3=add filter, 4=rem filter */
41 /* Version 2 adds 5=add session 6= remove session */
42 guint16 flags; /* 0x0001: 0=UDP, 1=TCP*/
43 /* 0x0002: 0=NONE, 1=DONT REDIRECT */
44 /* 0x0004: 0=NONE, 1=Xon */
45 /* 0x0008: 0=NONE, 1=Xoff */
46 guint16 id; /* request/response identification or TTL */
47 guint16 cport; /* client UDP or TCP port number */
48 guint32 caddr; /* client IPv4 address */
49 guint32 saddr; /* server IPV4 address */
50 /* tpcp version 2 only*/
51 guint32 vaddr; /* Virtual Server IPv4 address */
52 guint32 rasaddr; /* RAS server IPv4 address */
53 guint32 signature; /* 0x74706370 - tpcp */
54 } tpcpdu_t;
57 static const value_string type_vals[] = {
58 { 1, "Request" },
59 { 2, "Reply" },
60 { 3, "Add Filter" },
61 { 4, "Remove Filter" },
62 /* 5 and 6 are for version 2 only */
63 { 5, "Add Session" },
64 { 6, "Remove Session" },
65 { 0, NULL }
68 /* TPCP Flags */
69 #define TF_TPCP_UDPTCP 0x0001
70 #define TF_TPCP_DONTREDIRECT 0x0002
71 #define TF_TPCP_XON 0x0004
72 #define TF_TPCP_XOFF 0x0008
75 /* Version info */
76 #define TPCP_VER_1 1
77 #define TPCP_VER_2 2
79 #define TPCP_VER_1_LENGTH 16
80 #define TPCP_VER_2_LENGTH 28
82 /* things we can do filters on */
83 static int hf_tpcp_version = -1;
84 static int hf_tpcp_type = -1;
85 static int hf_tpcp_flags_tcp = -1;
86 static int hf_tpcp_flags_redir = -1;
87 static int hf_tpcp_flags_xon = -1;
88 static int hf_tpcp_flags_xoff = -1;
89 static int hf_tpcp_id = -1;
90 static int hf_tpcp_cport = -1;
91 static int hf_tpcp_caddr = -1;
92 static int hf_tpcp_saddr = -1;
93 static int hf_tpcp_vaddr = -1;
94 static int hf_tpcp_rasaddr = -1;
96 static int proto_tpcp = -1;
98 static gint ett_tpcp = -1;
99 static gint ett_tpcp_flags = -1;
102 static void
103 dissect_tpcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
105 tpcpdu_t tpcph;
106 proto_tree *tpcp_tree = NULL, *field_tree = NULL;
107 proto_item *ti, *tf;
108 guint8 length = TPCP_VER_1_LENGTH;
110 col_set_str(pinfo->cinfo, COL_PROTOCOL, "TPCP");
111 col_clear(pinfo->cinfo, COL_INFO);
113 /* need to find out which version!! */
114 tpcph.version = tvb_get_guint8(tvb, 0);
115 /* as version 1 and 2 are so similar use the same structure, just don't use as much for version 1*/
116 /* XXX: Doing a memcpy into a struct is *not* kosher */
117 if (tpcph.version == TPCP_VER_1) {
118 length = TPCP_VER_1_LENGTH;
119 tvb_memcpy(tvb, (guint8 *) &tpcph, 0, length);
120 } else if (tpcph.version == TPCP_VER_2){
121 length = TPCP_VER_2_LENGTH;
122 tvb_memcpy(tvb, (guint8 *) &tpcph, 0, length);
123 } else {
124 memset (&tpcph, 0, sizeof (tpcph));
128 tpcph.id = g_ntohs(tpcph.id);
129 tpcph.flags = g_ntohs(tpcph.flags);
130 tpcph.cport = g_ntohs(tpcph.cport);
131 tpcph.signature = g_ntohl(tpcph.signature);
133 col_add_fstr(pinfo->cinfo, COL_INFO,"%s id %d CPort %s CIP %s SIP %s",
134 val_to_str_const(tpcph.type, type_vals, "Unknown"),
135 tpcph.id,
136 get_udp_port(tpcph.cport),
137 ip_to_str((guint8 *)&tpcph.caddr),
138 ip_to_str((guint8 *)&tpcph.saddr));
140 if (tree) {
141 ti = proto_tree_add_protocol_format(tree, proto_tpcp, tvb, 0, length,
142 "Alteon WebSystems - Transparent Proxy Cache Protocol");
144 tpcp_tree = proto_item_add_subtree(ti, ett_tpcp);
146 proto_tree_add_uint(tpcp_tree, hf_tpcp_version, tvb, 0, 1, tpcph.version);
147 proto_tree_add_uint(tpcp_tree, hf_tpcp_type, tvb, 1, 1, tpcph.type);
149 /* flags next , i'll do that when I can work out how to do it :-( */
150 tf = proto_tree_add_text(tpcp_tree, tvb, 2, 2, "Flags: 0x%04x",tpcph.flags);
152 field_tree = proto_item_add_subtree(tf, ett_tpcp_flags);
153 proto_tree_add_boolean(field_tree, hf_tpcp_flags_tcp, tvb, 2, 2, tpcph.flags);
154 proto_tree_add_boolean(field_tree, hf_tpcp_flags_redir, tvb, 2,2, tpcph.flags);
155 proto_tree_add_boolean(field_tree, hf_tpcp_flags_xon, tvb, 2, 2, tpcph.flags);
156 proto_tree_add_boolean(field_tree, hf_tpcp_flags_xoff, tvb, 2, 2, tpcph.flags);
158 proto_tree_add_uint(tpcp_tree, hf_tpcp_id, tvb, 4, 2, tpcph.id);
160 proto_tree_add_uint_format_value(tpcp_tree, hf_tpcp_cport, tvb, 6, 2, tpcph.cport,
161 "%s", get_udp_port(tpcph.cport));
163 proto_tree_add_ipv4(tpcp_tree, hf_tpcp_caddr, tvb, 8, 4, tpcph.caddr);
165 proto_tree_add_ipv4(tpcp_tree, hf_tpcp_saddr, tvb, 12, 4, tpcph.saddr);
167 if (tpcph.version == TPCP_VER_2) {
168 proto_tree_add_ipv4(tpcp_tree, hf_tpcp_vaddr, tvb, 16, 4, tpcph.vaddr);
169 proto_tree_add_ipv4(tpcp_tree, hf_tpcp_rasaddr, tvb, 20, 4, tpcph.rasaddr);
170 proto_tree_add_text(tpcp_tree, tvb, 24, 4, "Signature: %u", tpcph.signature);
176 void
177 proto_register_tpcp(void)
179 static hf_register_info hf[] = {
180 { &hf_tpcp_version,
181 { "Version", "tpcp.version", FT_UINT8, BASE_DEC, NULL, 0x0,
182 "TPCP version", HFILL }},
184 { &hf_tpcp_type,
185 { "Type", "tpcp.type", FT_UINT8, BASE_DEC, VALS(type_vals), 0x0,
186 "PDU type", HFILL }},
188 { &hf_tpcp_flags_tcp,
189 { "UDP/TCP", "tpcp.flags.tcp", FT_BOOLEAN, 8, TFS(&tfs_set_notset), TF_TPCP_UDPTCP,
190 "Protocol type", HFILL }},
192 { &hf_tpcp_flags_redir,
193 { "No Redirect", "tpcp.flags.redir", FT_BOOLEAN, 8, TFS(&tfs_set_notset), TF_TPCP_DONTREDIRECT,
194 "Don't redirect client", HFILL }},
196 { &hf_tpcp_flags_xon,
197 { "XON", "tpcp.flags.xon", FT_BOOLEAN, 8, TFS(&tfs_set_notset), TF_TPCP_XON,
198 NULL, HFILL }},
200 { &hf_tpcp_flags_xoff,
201 { "XOFF", "tpcp.flags.xoff", FT_BOOLEAN, 8, TFS(&tfs_set_notset), TF_TPCP_XOFF,
202 NULL, HFILL }},
204 { &hf_tpcp_id,
205 { "Client indent", "tpcp.cid", FT_UINT16, BASE_DEC, NULL, 0x0,
206 NULL, HFILL }},
208 { &hf_tpcp_cport,
209 { "Client Source Port", "tpcp.cport", FT_UINT16, BASE_DEC, NULL, 0x0,
210 NULL, HFILL }},
212 { &hf_tpcp_caddr,
213 { "Client Source IP address", "tpcp.caddr", FT_IPv4, BASE_NONE, NULL, 0x0,
214 NULL, HFILL }},
216 { &hf_tpcp_saddr,
217 { "Server IP address", "tpcp.saddr", FT_IPv4, BASE_NONE, NULL, 0x0,
218 NULL, HFILL }},
220 { &hf_tpcp_vaddr,
221 { "Virtual Server IP address", "tpcp.vaddr", FT_IPv4, BASE_NONE, NULL, 0x0,
222 NULL, HFILL }},
224 { &hf_tpcp_rasaddr,
225 { "RAS server IP address", "tpcp.rasaddr", FT_IPv4, BASE_NONE, NULL, 0x0,
226 NULL, HFILL }},
231 static gint *ett[] = {
232 &ett_tpcp,
233 &ett_tpcp_flags,
236 proto_tpcp = proto_register_protocol("Alteon - Transparent Proxy Cache Protocol",
237 "TPCP", "tpcp");
238 proto_register_field_array(proto_tpcp, hf, array_length(hf));
239 proto_register_subtree_array(ett, array_length(ett));
242 void
243 proto_reg_handoff_tpcp(void)
245 dissector_handle_t tpcp_handle;
247 tpcp_handle = create_dissector_handle(dissect_tpcp, proto_tpcp);
248 dissector_add_uint("udp.port", UDP_PORT_TPCP, tpcp_handle);