2 * Routines for Transparent Proxy Cache Protocol packet disassembly
3 * (c) Copyright Giles Scott <giles.scott1 [AT] btinternet.com>
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
15 #include <epan/packet.h>
16 #include <epan/addr_resolv.h> /* this is for get_hostname and udp_port_to_display */
18 #include <wsutil/array.h>
20 void proto_register_tpcp(void);
21 void proto_reg_handoff_tpcp(void);
23 static dissector_handle_t tpcp_handle
;
25 #define UDP_PORT_TPCP 3121 /* Not IANA registered */
27 /* TPCP version1/2 PDU format */
28 typedef struct _tpcppdu_t
{
29 uint8_t version
; /* PDU version 1 */
30 uint8_t type
; /* PDU type: 1=request, 2=reply, 3=add filter, 4=rem filter */
31 /* Version 2 adds 5=add session 6= remove session */
32 uint16_t flags
; /* 0x0001: 0=UDP, 1=TCP*/
33 /* 0x0002: 0=NONE, 1=DONT_REDIRECT */
34 /* 0x0004: 0=NONE, 1=Xon */
35 /* 0x0008: 0=NONE, 1=Xoff */
36 uint16_t id
; /* request/response identification or TTL */
37 uint16_t cport
; /* client UDP or TCP port number */
38 uint32_t caddr
; /* client IPv4 address */
39 uint32_t saddr
; /* server IPV4 address */
40 /* tpcp version 2 only*/
41 uint32_t vaddr
; /* Virtual Server IPv4 address */
42 uint32_t rasaddr
; /* RAS server IPv4 address */
43 uint32_t signature
; /* 0x74706370 - tpcp */
47 static const value_string type_vals
[] = {
51 { 4, "Remove Filter" },
52 /* 5 and 6 are for version 2 only */
54 { 6, "Remove Session" },
59 #define TF_TPCP_UDPTCP 0x01
60 #define TF_TPCP_DONTREDIRECT 0x02
61 #define TF_TPCP_XON 0x04
62 #define TF_TPCP_XOFF 0x08
69 #define TPCP_VER_1_LENGTH 16
70 #define TPCP_VER_2_LENGTH 28
72 /* things we can do filters on */
73 static int hf_tpcp_version
;
74 static int hf_tpcp_type
;
75 static int hf_tpcp_flags
;
76 static int hf_tpcp_flags_tcp
;
77 static int hf_tpcp_flags_redir
;
78 static int hf_tpcp_flags_xon
;
79 static int hf_tpcp_flags_xoff
;
80 static int hf_tpcp_id
;
81 static int hf_tpcp_cport
;
82 static int hf_tpcp_caddr
;
83 static int hf_tpcp_saddr
;
84 static int hf_tpcp_vaddr
;
85 static int hf_tpcp_rasaddr
;
86 static int hf_tpcp_signature
;
88 static int proto_tpcp
;
91 static int ett_tpcp_flags
;
95 dissect_tpcp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
97 proto_tree
*tpcp_tree
= NULL
;
99 uint8_t version
, type
;
102 static int * const tpcp_flags
[] = {
104 &hf_tpcp_flags_redir
,
110 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "TPCP");
111 col_clear(pinfo
->cinfo
, COL_INFO
);
113 /* need to find out which version!! */
114 version
= tvb_get_uint8(tvb
, 0);
115 if ((version
!= TPCP_VER_1
) && (version
!= TPCP_VER_2
)) {
120 ti
= proto_tree_add_protocol_format(tree
, proto_tpcp
, tvb
, 0, -1,
121 "Alteon WebSystems - Transparent Proxy Cache Protocol");
123 tpcp_tree
= proto_item_add_subtree(ti
, ett_tpcp
);
125 proto_tree_add_item(tpcp_tree
, hf_tpcp_version
, tvb
, 0, 1, ENC_BIG_ENDIAN
);
126 type
= tvb_get_uint8(tvb
, 1);
127 proto_tree_add_item(tpcp_tree
, hf_tpcp_type
, tvb
, 1, 1, ENC_BIG_ENDIAN
);
129 proto_tree_add_bitmask(tpcp_tree
, tvb
, 2, hf_tpcp_flags
, ett_tpcp_flags
, tpcp_flags
, ENC_NA
);
131 /* N.B., flags are 8 bits, so byte at offset 3 skipped.. */
133 id
= tvb_get_ntohs(tvb
, 4);
134 proto_tree_add_item(tpcp_tree
, hf_tpcp_id
, tvb
, 4, 2, ENC_BIG_ENDIAN
);
136 cport
= tvb_get_ntohs(tvb
, 6);
137 proto_tree_add_uint_format_value(tpcp_tree
, hf_tpcp_cport
, tvb
, 6, 2, cport
,
138 "%s", udp_port_to_display(pinfo
->pool
, cport
));
140 proto_tree_add_item(tpcp_tree
, hf_tpcp_caddr
, tvb
, 8, 4, ENC_BIG_ENDIAN
);
141 proto_tree_add_item(tpcp_tree
, hf_tpcp_saddr
, tvb
, 12, 4, ENC_BIG_ENDIAN
);
143 if (version
== TPCP_VER_2
) {
144 proto_tree_add_item(tpcp_tree
, hf_tpcp_vaddr
, tvb
, 16, 4, ENC_BIG_ENDIAN
);
145 proto_tree_add_item(tpcp_tree
, hf_tpcp_rasaddr
, tvb
, 20, 4, ENC_BIG_ENDIAN
);
146 proto_tree_add_item(tpcp_tree
, hf_tpcp_signature
, tvb
, 24, 4, ENC_BIG_ENDIAN
);
149 col_add_fstr(pinfo
->cinfo
, COL_INFO
,"%s id %d CPort %s CIP %s SIP %s",
150 val_to_str_const(type
, type_vals
, "Unknown"),
152 udp_port_to_display(pinfo
->pool
, cport
),
153 tvb_ip_to_str(pinfo
->pool
, tvb
, 8),
154 tvb_ip_to_str(pinfo
->pool
, tvb
, 12));
156 if (version
== TPCP_VER_1
)
157 return TPCP_VER_1_LENGTH
;
159 return TPCP_VER_2_LENGTH
;
163 proto_register_tpcp(void)
165 static hf_register_info hf
[] = {
167 { "Version", "tpcp.version", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
168 "TPCP version", HFILL
}},
171 { "Type", "tpcp.type", FT_UINT8
, BASE_DEC
, VALS(type_vals
), 0x0,
172 "PDU type", HFILL
}},
175 { "Flags", "tpcp.flags", FT_UINT16
, BASE_HEX
, NULL
, 0x0,
178 { &hf_tpcp_flags_tcp
,
179 { "UDP/TCP", "tpcp.flags.tcp", FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), TF_TPCP_UDPTCP
,
180 "Protocol type", HFILL
}},
182 { &hf_tpcp_flags_redir
,
183 { "No Redirect", "tpcp.flags.redir", FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), TF_TPCP_DONTREDIRECT
,
184 "Don't redirect client", HFILL
}},
186 { &hf_tpcp_flags_xon
,
187 { "XON", "tpcp.flags.xon", FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), TF_TPCP_XON
,
190 { &hf_tpcp_flags_xoff
,
191 { "XOFF", "tpcp.flags.xoff", FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), TF_TPCP_XOFF
,
195 { "Client indent", "tpcp.cid", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
199 { "Client Source Port", "tpcp.cport", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
203 { "Client Source IP address", "tpcp.caddr", FT_IPv4
, BASE_NONE
, NULL
, 0x0,
207 { "Server IP address", "tpcp.saddr", FT_IPv4
, BASE_NONE
, NULL
, 0x0,
211 { "Virtual Server IP address", "tpcp.vaddr", FT_IPv4
, BASE_NONE
, NULL
, 0x0,
215 { "RAS server IP address", "tpcp.rasaddr", FT_IPv4
, BASE_NONE
, NULL
, 0x0,
218 { &hf_tpcp_signature
,
219 { "Signature", "tpcp.signature", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
224 static int *ett
[] = {
229 proto_tpcp
= proto_register_protocol("Alteon - Transparent Proxy Cache Protocol", "TPCP", "tpcp");
230 proto_register_field_array(proto_tpcp
, hf
, array_length(hf
));
231 proto_register_subtree_array(ett
, array_length(ett
));
233 tpcp_handle
= register_dissector("tpcp", dissect_tpcp
, proto_tpcp
);
237 proto_reg_handoff_tpcp(void)
239 dissector_add_uint_with_preference("udp.port", UDP_PORT_TPCP
, tpcp_handle
);
243 * Editor modelines - https://www.wireshark.org/tools/modelines.html
248 * indent-tabs-mode: t
251 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
252 * :indentSize=8:tabSize=8:noTabs=false: