/src/wireshark/epan/dissectors/packet-nt-tpcp.c
Line | Count | Source |
1 | | /* packet-nt-tpcp.c |
2 | | * Routines for Transparent Proxy Cache Protocol packet disassembly |
3 | | * (c) Copyright Giles Scott <giles.scott1 [AT] btinternet.com> |
4 | | * |
5 | | * Wireshark - Network traffic analyzer |
6 | | * By Gerald Combs <gerald@wireshark.org> |
7 | | * Copyright 1998 Gerald Combs |
8 | | * |
9 | | * SPDX-License-Identifier: GPL-2.0-or-later |
10 | | */ |
11 | | |
12 | | #include "config.h" |
13 | | |
14 | | |
15 | | #include <epan/packet.h> |
16 | | #include <epan/addr_resolv.h> /* this is for get_hostname and udp_port_to_display */ |
17 | | #include <epan/tfs.h> |
18 | | #include <wsutil/array.h> |
19 | | |
20 | | void proto_register_tpcp(void); |
21 | | void proto_reg_handoff_tpcp(void); |
22 | | |
23 | | static dissector_handle_t tpcp_handle; |
24 | | |
25 | 15 | #define UDP_PORT_TPCP 3121 /* Not IANA registered */ |
26 | | |
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 */ |
44 | | } tpcpdu_t; |
45 | | |
46 | | |
47 | | static const value_string type_vals[] = { |
48 | | { 1, "Request" }, |
49 | | { 2, "Reply" }, |
50 | | { 3, "Add Filter" }, |
51 | | { 4, "Remove Filter" }, |
52 | | /* 5 and 6 are for version 2 only */ |
53 | | { 5, "Add Session" }, |
54 | | { 6, "Remove Session" }, |
55 | | { 0, NULL } |
56 | | }; |
57 | | |
58 | | /* TPCP Flags */ |
59 | 15 | #define TF_TPCP_UDPTCP 0x01 |
60 | 15 | #define TF_TPCP_DONTREDIRECT 0x02 |
61 | 15 | #define TF_TPCP_XON 0x04 |
62 | 15 | #define TF_TPCP_XOFF 0x08 |
63 | | |
64 | | |
65 | | /* Version info */ |
66 | 13 | #define TPCP_VER_1 1 |
67 | 10 | #define TPCP_VER_2 2 |
68 | | |
69 | 0 | #define TPCP_VER_1_LENGTH 16 |
70 | 5 | #define TPCP_VER_2_LENGTH 28 |
71 | | |
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; |
87 | | |
88 | | static int proto_tpcp; |
89 | | |
90 | | static int ett_tpcp; |
91 | | static int ett_tpcp_flags; |
92 | | |
93 | | |
94 | | static int |
95 | | dissect_tpcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) |
96 | 8 | { |
97 | 8 | proto_tree *tpcp_tree = NULL; |
98 | 8 | proto_item *ti; |
99 | 8 | uint8_t version, type; |
100 | 8 | uint16_t id, cport; |
101 | | |
102 | 8 | static int * const tpcp_flags[] = { |
103 | 8 | &hf_tpcp_flags_tcp, |
104 | 8 | &hf_tpcp_flags_redir, |
105 | 8 | &hf_tpcp_flags_xon, |
106 | 8 | &hf_tpcp_flags_xoff, |
107 | 8 | NULL |
108 | 8 | }; |
109 | | |
110 | 8 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "TPCP"); |
111 | 8 | col_clear(pinfo->cinfo, COL_INFO); |
112 | | |
113 | | /* need to find out which version!! */ |
114 | 8 | version = tvb_get_uint8(tvb, 0); |
115 | 8 | if ((version != TPCP_VER_1) && (version != TPCP_VER_2)) { |
116 | | /* Not us */ |
117 | 3 | return 0; |
118 | 3 | } |
119 | | |
120 | 5 | ti = proto_tree_add_protocol_format(tree, proto_tpcp, tvb, 0, -1, |
121 | 5 | "Alteon WebSystems - Transparent Proxy Cache Protocol"); |
122 | | |
123 | 5 | tpcp_tree = proto_item_add_subtree(ti, ett_tpcp); |
124 | | |
125 | 5 | proto_tree_add_item(tpcp_tree, hf_tpcp_version, tvb, 0, 1, ENC_BIG_ENDIAN); |
126 | 5 | proto_tree_add_item_ret_uint8(tpcp_tree, hf_tpcp_type, tvb, 1, 1, ENC_BIG_ENDIAN, &type); |
127 | | |
128 | 5 | proto_tree_add_bitmask(tpcp_tree, tvb, 2, hf_tpcp_flags, ett_tpcp_flags, tpcp_flags, ENC_BIG_ENDIAN); |
129 | | |
130 | | /* N.B., flags are 8 bits, so byte at offset 3 skipped.. */ |
131 | | |
132 | 5 | proto_tree_add_item_ret_uint16(tpcp_tree, hf_tpcp_id, tvb, 4, 2, ENC_BIG_ENDIAN, &id); |
133 | | |
134 | 5 | cport = tvb_get_ntohs(tvb, 6); |
135 | 5 | proto_tree_add_uint_format_value(tpcp_tree, hf_tpcp_cport, tvb, 6, 2, cport, |
136 | 5 | "%s", udp_port_to_display(pinfo->pool, cport)); |
137 | | |
138 | 5 | proto_tree_add_item(tpcp_tree, hf_tpcp_caddr, tvb, 8, 4, ENC_BIG_ENDIAN); |
139 | 5 | proto_tree_add_item(tpcp_tree, hf_tpcp_saddr, tvb, 12, 4, ENC_BIG_ENDIAN); |
140 | | |
141 | 5 | if (version == TPCP_VER_2) { |
142 | 1 | proto_tree_add_item(tpcp_tree, hf_tpcp_vaddr, tvb, 16, 4, ENC_BIG_ENDIAN); |
143 | 1 | proto_tree_add_item(tpcp_tree, hf_tpcp_rasaddr, tvb, 20, 4, ENC_BIG_ENDIAN); |
144 | 1 | proto_tree_add_item(tpcp_tree, hf_tpcp_signature, tvb, 24, 4, ENC_BIG_ENDIAN); |
145 | 1 | } |
146 | | |
147 | 5 | col_add_fstr(pinfo->cinfo, COL_INFO,"%s id %d CPort %s CIP %s SIP %s", |
148 | 5 | val_to_str_const(type, type_vals, "Unknown"), |
149 | 5 | id, |
150 | 5 | udp_port_to_display(pinfo->pool, cport), |
151 | 5 | tvb_ip_to_str(pinfo->pool, tvb, 8), |
152 | 5 | tvb_ip_to_str(pinfo->pool, tvb, 12)); |
153 | | |
154 | 5 | if (version == TPCP_VER_1) |
155 | 0 | return TPCP_VER_1_LENGTH; |
156 | | |
157 | 5 | return TPCP_VER_2_LENGTH; |
158 | 5 | } |
159 | | |
160 | | void |
161 | | proto_register_tpcp(void) |
162 | 15 | { |
163 | 15 | static hf_register_info hf[] = { |
164 | 15 | { &hf_tpcp_version, |
165 | 15 | { "Version", "tpcp.version", FT_UINT8, BASE_DEC, NULL, 0x0, |
166 | 15 | "TPCP version", HFILL }}, |
167 | | |
168 | 15 | { &hf_tpcp_type, |
169 | 15 | { "Type", "tpcp.type", FT_UINT8, BASE_DEC, VALS(type_vals), 0x0, |
170 | 15 | "PDU type", HFILL }}, |
171 | | |
172 | 15 | { &hf_tpcp_flags, |
173 | 15 | { "Flags", "tpcp.flags", FT_UINT16, BASE_HEX, NULL, 0x0, |
174 | 15 | NULL, HFILL }}, |
175 | | |
176 | 15 | { &hf_tpcp_flags_tcp, |
177 | 15 | { "UDP/TCP", "tpcp.flags.tcp", FT_BOOLEAN, 8, TFS(&tfs_set_notset), TF_TPCP_UDPTCP, |
178 | 15 | "Protocol type", HFILL }}, |
179 | | |
180 | 15 | { &hf_tpcp_flags_redir, |
181 | 15 | { "No Redirect", "tpcp.flags.redir", FT_BOOLEAN, 8, TFS(&tfs_set_notset), TF_TPCP_DONTREDIRECT, |
182 | 15 | "Don't redirect client", HFILL }}, |
183 | | |
184 | 15 | { &hf_tpcp_flags_xon, |
185 | 15 | { "XON", "tpcp.flags.xon", FT_BOOLEAN, 8, TFS(&tfs_set_notset), TF_TPCP_XON, |
186 | 15 | NULL, HFILL }}, |
187 | | |
188 | 15 | { &hf_tpcp_flags_xoff, |
189 | 15 | { "XOFF", "tpcp.flags.xoff", FT_BOOLEAN, 8, TFS(&tfs_set_notset), TF_TPCP_XOFF, |
190 | 15 | NULL, HFILL }}, |
191 | | |
192 | 15 | { &hf_tpcp_id, |
193 | 15 | { "Client indent", "tpcp.cid", FT_UINT16, BASE_DEC, NULL, 0x0, |
194 | 15 | NULL, HFILL }}, |
195 | | |
196 | 15 | { &hf_tpcp_cport, |
197 | 15 | { "Client Source Port", "tpcp.cport", FT_UINT16, BASE_DEC, NULL, 0x0, |
198 | 15 | NULL, HFILL }}, |
199 | | |
200 | 15 | { &hf_tpcp_caddr, |
201 | 15 | { "Client Source IP address", "tpcp.caddr", FT_IPv4, BASE_NONE, NULL, 0x0, |
202 | 15 | NULL, HFILL }}, |
203 | | |
204 | 15 | { &hf_tpcp_saddr, |
205 | 15 | { "Server IP address", "tpcp.saddr", FT_IPv4, BASE_NONE, NULL, 0x0, |
206 | 15 | NULL, HFILL }}, |
207 | | |
208 | 15 | { &hf_tpcp_vaddr, |
209 | 15 | { "Virtual Server IP address", "tpcp.vaddr", FT_IPv4, BASE_NONE, NULL, 0x0, |
210 | 15 | NULL, HFILL }}, |
211 | | |
212 | 15 | { &hf_tpcp_rasaddr, |
213 | 15 | { "RAS server IP address", "tpcp.rasaddr", FT_IPv4, BASE_NONE, NULL, 0x0, |
214 | 15 | NULL, HFILL }}, |
215 | | |
216 | 15 | { &hf_tpcp_signature, |
217 | 15 | { "Signature", "tpcp.signature", FT_UINT32, BASE_DEC, NULL, 0x0, |
218 | 15 | NULL, HFILL }}, |
219 | 15 | }; |
220 | | |
221 | | |
222 | 15 | static int *ett[] = { |
223 | 15 | &ett_tpcp, |
224 | 15 | &ett_tpcp_flags, |
225 | 15 | }; |
226 | | |
227 | 15 | proto_tpcp = proto_register_protocol("Alteon - Transparent Proxy Cache Protocol", "TPCP", "tpcp"); |
228 | 15 | proto_register_field_array(proto_tpcp, hf, array_length(hf)); |
229 | 15 | proto_register_subtree_array(ett, array_length(ett)); |
230 | | |
231 | 15 | tpcp_handle = register_dissector("tpcp", dissect_tpcp, proto_tpcp); |
232 | 15 | } |
233 | | |
234 | | void |
235 | | proto_reg_handoff_tpcp(void) |
236 | 15 | { |
237 | 15 | dissector_add_uint_with_preference("udp.port", UDP_PORT_TPCP, tpcp_handle); |
238 | 15 | } |
239 | | |
240 | | /* |
241 | | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
242 | | * |
243 | | * Local variables: |
244 | | * c-basic-offset: 8 |
245 | | * tab-width: 8 |
246 | | * indent-tabs-mode: t |
247 | | * End: |
248 | | * |
249 | | * vi: set shiftwidth=8 tabstop=8 noexpandtab: |
250 | | * :indentSize=8:tabSize=8:noTabs=false: |
251 | | */ |