removed some gcc warnings (hopefully)
[obnox/wireshark/wip.git] / epan / dissectors / packet-nt-tpcp.c
1 /* packet-tpcp.c
2 * Routines for Transparent Proxy Cache Protocol packet disassembly
3 * (c) Copyright Giles Scott <giles.scott1 [AT] btinternet.com>
4 *
5 * $Id$
6 *
7 * Ethereal - Network traffic analyzer
8 * By Gerald Combs <gerald@ethereal.com>
9 * Copyright 1998 Gerald Combs
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 <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33
34 #ifdef HAVE_SYS_TYPES_H
35 #  include <sys/types.h>
36 #endif
37
38 #include <glib.h>
39 #include <epan/packet.h>
40 #include <epan/addr_resolv.h> /* this is for get_hostname and get_udp_port */
41
42 #define UDP_PORT_TPCP   3121 
43
44 /* TPCP version1/2 PDU format */
45 typedef struct _tpcppdu_t {
46         guint8  version; /* PDU version 1 */
47         guint8  type;   /* PDU type: 1=request, 2=reply, 3=add filter, 4=rem  filter */
48         /* Version 2 adds 5=add session 6= remove session */
49         guint16 flags;  /* 0x0001: 0=UDP, 1=TCP*/
50         /* 0x0002: 0=NONE, 1=DONT REDIRECT */
51         /* 0x0004: 0=NONE, 1=Xon */
52         /* 0x0008: 0=NONE, 1=Xoff */
53         guint16 id;     /* request/response identification or TTL */
54         guint16 cport;  /* client UDP or TCP port number */
55         guint32 caddr;  /* client IPv4 address */
56         guint32 saddr;  /* server IPV4 address */
57         /* tpcp version 2 only*/
58         guint32 vaddr;  /* Virtual Server IPv4 address */
59         guint32 rasaddr; /* RAS server IPv4 address */
60         guint32 signature; /* 0x74706370 - tpcp */
61 } tpcpdu_t;
62
63
64 static const value_string type_vals[] = {
65         { 1, "Request" },
66         { 2, "Reply" },
67         { 3, "Add Filter" },
68         { 4, "Remove Filter" },
69         /* 5 and 6 are for version 2 only */
70         { 5, "Add Session" },
71         { 6, "Remove Session" },
72         { 0,  NULL }
73 };
74
75 /* TPCP Flags */
76 #define TF_TPCP_UDPTCP 0x0001
77 #define TF_TPCP_DONTREDIRECT 0x0002
78 #define TF_TPCP_XON 0x0004
79 #define TF_TPCP_XOFF 0x0008
80
81
82 /* Version info */
83 #define TPCP_VER_1 1
84 #define TPCP_VER_2 2
85 #define TPCP_VER_1_LENGTH 16
86 #define TPCP_VER_2_LENGTH 28
87
88 /* things we can do filters on */
89 static int hf_tpcp_version = -1;
90 static int hf_tpcp_type = -1;
91 static int hf_tpcp_flags_tcp = -1;
92 static int hf_tpcp_flags_redir = -1;
93 static int hf_tpcp_flags_xon = -1;
94 static int hf_tpcp_flags_xoff = -1;
95 static int hf_tpcp_id = -1;
96 static int hf_tpcp_cport = -1;
97 static int hf_tpcp_caddr = -1;
98 static int hf_tpcp_saddr = -1;
99 static int hf_tpcp_vaddr = -1;
100 static int hf_tpcp_rasaddr = -1;
101
102 static int proto_tpcp = -1;
103
104 static gint ett_tpcp = -1;
105 static gint ett_tpcp_flags = -1;
106
107
108 static void 
109 dissect_tpcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
110 {
111         tpcpdu_t tpcph;
112         proto_tree *tpcp_tree = NULL, *field_tree = NULL;
113         proto_item *ti, *tf;
114         guint8 length = TPCP_VER_1_LENGTH;
115         
116         if (check_col(pinfo->cinfo, COL_PROTOCOL))
117                 col_set_str(pinfo->cinfo, COL_PROTOCOL, "TPCP");
118         if (check_col(pinfo->cinfo, COL_INFO))
119                 col_clear(pinfo->cinfo, COL_INFO);
120         
121         /* need to find out which version!! */
122         tpcph.version = tvb_get_guint8(tvb, 0);
123         /* as version 1 and 2 are so similar use the same structure, just don't use as much for version 1*/
124         if (tpcph.version == TPCP_VER_1) {
125                 length = TPCP_VER_1_LENGTH;
126                 tvb_memcpy(tvb, (guint8 *) &tpcph, 0, length);
127         } else if (tpcph.version == TPCP_VER_2){
128                 length = TPCP_VER_2_LENGTH;
129                 tvb_memcpy(tvb, (guint8 *) &tpcph, 0, length);
130         }
131         
132         
133         tpcph.id = g_ntohs(tpcph.id);
134         tpcph.flags = g_ntohs(tpcph.flags);
135         tpcph.cport = g_ntohs(tpcph.cport);
136         
137         if (check_col(pinfo->cinfo, COL_INFO))
138                 col_add_fstr(pinfo->cinfo, COL_INFO,"%s id %d CPort %s CIP %s SIP %s",
139                 val_to_str(tpcph.type, type_vals, "Unknown"),
140                 tpcph.id,
141                 get_udp_port(tpcph.cport),
142                 ip_to_str((guint8 *)&tpcph.caddr),
143                 ip_to_str((guint8 *)&tpcph.saddr));
144         
145         if (tree) {
146                 ti = proto_tree_add_protocol_format(tree, proto_tpcp, tvb, 0, length,
147                         "Alteon WebSystems - Transparent Proxy Cache Protocol");
148                 
149                 tpcp_tree = proto_item_add_subtree(ti, ett_tpcp);
150                 
151                 proto_tree_add_item(tpcp_tree, hf_tpcp_version, tvb, 0, 1, tpcph.version);
152                 
153                 proto_tree_add_uint_format(tpcp_tree, hf_tpcp_type, tvb, 1, 1, tpcph.type,
154                         "Type: %s (%d)", 
155                         val_to_str(tpcph.type, type_vals, "Unknown"), tpcph.type); 
156                 
157                 /* flags next , i'll do that when I can work out how to do it :-(   */
158                 tf = proto_tree_add_text(tpcp_tree, tvb, 2, 2, "Flags: 0x%04x",tpcph.flags);
159                 
160                 field_tree = proto_item_add_subtree(tf, ett_tpcp_flags);        
161                 proto_tree_add_boolean(field_tree, hf_tpcp_flags_tcp, tvb, 2, 2, tpcph.flags);
162                 proto_tree_add_boolean(field_tree, hf_tpcp_flags_redir, tvb, 2,2, tpcph.flags);
163                 proto_tree_add_boolean(field_tree, hf_tpcp_flags_xon, tvb, 2, 2, tpcph.flags);
164                 proto_tree_add_boolean(field_tree, hf_tpcp_flags_xoff, tvb, 2, 2, tpcph.flags);
165                 
166                 proto_tree_add_uint(tpcp_tree, hf_tpcp_id, tvb, 4, 2, tpcph.id);
167                 
168                 proto_tree_add_uint_format(tpcp_tree, hf_tpcp_cport, tvb, 6, 2, tpcph.cport,
169                         "Client Source port: %s", get_udp_port(tpcph.cport));
170                 
171                 proto_tree_add_ipv4(tpcp_tree, hf_tpcp_caddr, tvb, 8, 4, tpcph.caddr); 
172                 
173                 proto_tree_add_ipv4(tpcp_tree, hf_tpcp_saddr, tvb, 12, 4, tpcph.saddr); 
174                 
175                 if (tpcph.version == TPCP_VER_2) {
176                         proto_tree_add_ipv4(tpcp_tree, hf_tpcp_vaddr, tvb, 16, 4, tpcph.vaddr); 
177                         proto_tree_add_ipv4(tpcp_tree, hf_tpcp_rasaddr, tvb, 20, 4, tpcph.rasaddr); 
178                         proto_tree_add_text(tpcp_tree, tvb, 24, 4, "Signature: %u", tpcph.signature);
179                 }
180                 
181         }
182 }
183
184 void
185 proto_register_tpcp(void)
186 {
187         static hf_register_info hf[] = {
188                 { &hf_tpcp_version,
189                 { "Version",            "tpcp.version", FT_UINT8, BASE_DEC, NULL, 0x0,
190                 "TPCP version", HFILL }},
191                 
192                 { &hf_tpcp_type,
193                 { "Type",               "tpcp.type", FT_UINT8, BASE_DEC,NULL, 0x0,
194                 "PDU type", HFILL }},
195                 
196                 { &hf_tpcp_flags_tcp,
197                 { "UDP/TCP",            "tpcp.flags.tcp", FT_BOOLEAN, 8, TFS(&flags_set_truth), TF_TPCP_UDPTCP,
198                 "Protocol type", HFILL }},
199                 
200                 { &hf_tpcp_flags_redir,
201                 { "No Redirect",        "tpcp.flags.redir", FT_BOOLEAN, 8, TFS(&flags_set_truth), TF_TPCP_DONTREDIRECT,
202                 "Don't redirect client", HFILL }},
203                 
204                 { &hf_tpcp_flags_xon,
205                 { "XON",                "tpcp.flags.xon", FT_BOOLEAN, 8, TFS(&flags_set_truth), TF_TPCP_XON,
206                 "", HFILL }},
207                 
208                 { &hf_tpcp_flags_xoff,
209                 { "XOFF",               "tpcp.flags.xoff", FT_BOOLEAN, 8, TFS(&flags_set_truth), TF_TPCP_XOFF,
210                 "", HFILL }},
211                 
212                 { &hf_tpcp_id,
213                 { "Client indent",      "tpcp.cid", FT_UINT16, BASE_DEC, NULL, 0x0,
214                 "", HFILL }},
215                 
216                 { &hf_tpcp_cport,
217                 { "Client Source Port", "tpcp.cport", FT_UINT16, BASE_DEC, NULL, 0x0,
218                 "", HFILL }},
219                 
220                 { &hf_tpcp_caddr,
221                 { "Client Source IP address",   "tpcp.caddr", FT_IPv4, BASE_NONE, NULL, 0x0,
222                 "", HFILL }},
223                 
224                 { &hf_tpcp_saddr,
225                 { "Server IP address",  "tpcp.saddr", FT_IPv4, BASE_NONE, NULL, 0x0,
226                 "", HFILL }},
227                 
228                 { &hf_tpcp_vaddr,
229                 { "Virtual Server IP address", "tpcp.vaddr", FT_IPv4, BASE_NONE, NULL, 0x0,
230                 "", HFILL }},
231                 
232                 { &hf_tpcp_rasaddr,
233                 { "RAS server IP address", "tpcp.rasaddr", FT_IPv4, BASE_NONE, NULL, 0x0,
234                 "", HFILL }},
235                 
236         };
237         
238         
239     static gint *ett[] = {
240         &ett_tpcp,
241         &ett_tpcp_flags,
242     };
243         
244     proto_tpcp = proto_register_protocol("Alteon - Transparent Proxy Cache Protocol",
245                 "TPCP", "tpcp");
246     proto_register_field_array(proto_tpcp, hf, array_length(hf));
247     proto_register_subtree_array(ett, array_length(ett));
248 }
249
250 void
251 proto_reg_handoff_tpcp(void)
252 {
253     dissector_handle_t tpcp_handle;
254         
255     tpcp_handle = create_dissector_handle(dissect_tpcp, proto_tpcp);
256     dissector_add("udp.port", UDP_PORT_TPCP, tpcp_handle);
257 }