/src/wireshark/epan/dissectors/packet-nt-tpcp.c
Line | Count | Source (jump to first uncovered line) |
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 | 14 | #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 | 14 | #define TF_TPCP_UDPTCP 0x01 |
60 | 14 | #define TF_TPCP_DONTREDIRECT 0x02 |
61 | 14 | #define TF_TPCP_XON 0x04 |
62 | 14 | #define TF_TPCP_XOFF 0x08 |
63 | | |
64 | | |
65 | | /* Version info */ |
66 | 8 | #define TPCP_VER_1 1 |
67 | 6 | #define TPCP_VER_2 2 |
68 | | |
69 | 1 | #define TPCP_VER_1_LENGTH 16 |
70 | 3 | #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 | 4 | { |
97 | 4 | proto_tree *tpcp_tree = NULL; |
98 | 4 | proto_item *ti; |
99 | 4 | uint8_t version, type; |
100 | 4 | uint16_t id, cport; |
101 | | |
102 | 4 | static int * const tpcp_flags[] = { |
103 | 4 | &hf_tpcp_flags_tcp, |
104 | 4 | &hf_tpcp_flags_redir, |
105 | 4 | &hf_tpcp_flags_xon, |
106 | 4 | &hf_tpcp_flags_xoff, |
107 | 4 | NULL |
108 | 4 | }; |
109 | | |
110 | 4 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "TPCP"); |
111 | 4 | col_clear(pinfo->cinfo, COL_INFO); |
112 | | |
113 | | /* need to find out which version!! */ |
114 | 4 | version = tvb_get_uint8(tvb, 0); |
115 | 4 | if ((version != TPCP_VER_1) && (version != TPCP_VER_2)) { |
116 | | /* Not us */ |
117 | 0 | return 0; |
118 | 0 | } |
119 | | |
120 | 4 | ti = proto_tree_add_protocol_format(tree, proto_tpcp, tvb, 0, -1, |
121 | 4 | "Alteon WebSystems - Transparent Proxy Cache Protocol"); |
122 | | |
123 | 4 | tpcp_tree = proto_item_add_subtree(ti, ett_tpcp); |
124 | | |
125 | 4 | proto_tree_add_item(tpcp_tree, hf_tpcp_version, tvb, 0, 1, ENC_BIG_ENDIAN); |
126 | 4 | type = tvb_get_uint8(tvb, 1); |
127 | 4 | proto_tree_add_item(tpcp_tree, hf_tpcp_type, tvb, 1, 1, ENC_BIG_ENDIAN); |
128 | | |
129 | 4 | proto_tree_add_bitmask(tpcp_tree, tvb, 2, hf_tpcp_flags, ett_tpcp_flags, tpcp_flags, ENC_NA); |
130 | | |
131 | | /* N.B., flags are 8 bits, so byte at offset 3 skipped.. */ |
132 | | |
133 | 4 | id = tvb_get_ntohs(tvb, 4); |
134 | 4 | proto_tree_add_item(tpcp_tree, hf_tpcp_id, tvb, 4, 2, ENC_BIG_ENDIAN); |
135 | | |
136 | 4 | cport = tvb_get_ntohs(tvb, 6); |
137 | 4 | proto_tree_add_uint_format_value(tpcp_tree, hf_tpcp_cport, tvb, 6, 2, cport, |
138 | 4 | "%s", udp_port_to_display(pinfo->pool, cport)); |
139 | | |
140 | 4 | proto_tree_add_item(tpcp_tree, hf_tpcp_caddr, tvb, 8, 4, ENC_BIG_ENDIAN); |
141 | 4 | proto_tree_add_item(tpcp_tree, hf_tpcp_saddr, tvb, 12, 4, ENC_BIG_ENDIAN); |
142 | | |
143 | 4 | if (version == TPCP_VER_2) { |
144 | 1 | proto_tree_add_item(tpcp_tree, hf_tpcp_vaddr, tvb, 16, 4, ENC_BIG_ENDIAN); |
145 | 1 | proto_tree_add_item(tpcp_tree, hf_tpcp_rasaddr, tvb, 20, 4, ENC_BIG_ENDIAN); |
146 | 1 | proto_tree_add_item(tpcp_tree, hf_tpcp_signature, tvb, 24, 4, ENC_BIG_ENDIAN); |
147 | 1 | } |
148 | | |
149 | 4 | col_add_fstr(pinfo->cinfo, COL_INFO,"%s id %d CPort %s CIP %s SIP %s", |
150 | 4 | val_to_str_const(type, type_vals, "Unknown"), |
151 | 4 | id, |
152 | 4 | udp_port_to_display(pinfo->pool, cport), |
153 | 4 | tvb_ip_to_str(pinfo->pool, tvb, 8), |
154 | 4 | tvb_ip_to_str(pinfo->pool, tvb, 12)); |
155 | | |
156 | 4 | if (version == TPCP_VER_1) |
157 | 1 | return TPCP_VER_1_LENGTH; |
158 | | |
159 | 3 | return TPCP_VER_2_LENGTH; |
160 | 4 | } |
161 | | |
162 | | void |
163 | | proto_register_tpcp(void) |
164 | 14 | { |
165 | 14 | static hf_register_info hf[] = { |
166 | 14 | { &hf_tpcp_version, |
167 | 14 | { "Version", "tpcp.version", FT_UINT8, BASE_DEC, NULL, 0x0, |
168 | 14 | "TPCP version", HFILL }}, |
169 | | |
170 | 14 | { &hf_tpcp_type, |
171 | 14 | { "Type", "tpcp.type", FT_UINT8, BASE_DEC, VALS(type_vals), 0x0, |
172 | 14 | "PDU type", HFILL }}, |
173 | | |
174 | 14 | { &hf_tpcp_flags, |
175 | 14 | { "Flags", "tpcp.flags", FT_UINT16, BASE_HEX, NULL, 0x0, |
176 | 14 | NULL, HFILL }}, |
177 | | |
178 | 14 | { &hf_tpcp_flags_tcp, |
179 | 14 | { "UDP/TCP", "tpcp.flags.tcp", FT_BOOLEAN, 8, TFS(&tfs_set_notset), TF_TPCP_UDPTCP, |
180 | 14 | "Protocol type", HFILL }}, |
181 | | |
182 | 14 | { &hf_tpcp_flags_redir, |
183 | 14 | { "No Redirect", "tpcp.flags.redir", FT_BOOLEAN, 8, TFS(&tfs_set_notset), TF_TPCP_DONTREDIRECT, |
184 | 14 | "Don't redirect client", HFILL }}, |
185 | | |
186 | 14 | { &hf_tpcp_flags_xon, |
187 | 14 | { "XON", "tpcp.flags.xon", FT_BOOLEAN, 8, TFS(&tfs_set_notset), TF_TPCP_XON, |
188 | 14 | NULL, HFILL }}, |
189 | | |
190 | 14 | { &hf_tpcp_flags_xoff, |
191 | 14 | { "XOFF", "tpcp.flags.xoff", FT_BOOLEAN, 8, TFS(&tfs_set_notset), TF_TPCP_XOFF, |
192 | 14 | NULL, HFILL }}, |
193 | | |
194 | 14 | { &hf_tpcp_id, |
195 | 14 | { "Client indent", "tpcp.cid", FT_UINT16, BASE_DEC, NULL, 0x0, |
196 | 14 | NULL, HFILL }}, |
197 | | |
198 | 14 | { &hf_tpcp_cport, |
199 | 14 | { "Client Source Port", "tpcp.cport", FT_UINT16, BASE_DEC, NULL, 0x0, |
200 | 14 | NULL, HFILL }}, |
201 | | |
202 | 14 | { &hf_tpcp_caddr, |
203 | 14 | { "Client Source IP address", "tpcp.caddr", FT_IPv4, BASE_NONE, NULL, 0x0, |
204 | 14 | NULL, HFILL }}, |
205 | | |
206 | 14 | { &hf_tpcp_saddr, |
207 | 14 | { "Server IP address", "tpcp.saddr", FT_IPv4, BASE_NONE, NULL, 0x0, |
208 | 14 | NULL, HFILL }}, |
209 | | |
210 | 14 | { &hf_tpcp_vaddr, |
211 | 14 | { "Virtual Server IP address", "tpcp.vaddr", FT_IPv4, BASE_NONE, NULL, 0x0, |
212 | 14 | NULL, HFILL }}, |
213 | | |
214 | 14 | { &hf_tpcp_rasaddr, |
215 | 14 | { "RAS server IP address", "tpcp.rasaddr", FT_IPv4, BASE_NONE, NULL, 0x0, |
216 | 14 | NULL, HFILL }}, |
217 | | |
218 | 14 | { &hf_tpcp_signature, |
219 | 14 | { "Signature", "tpcp.signature", FT_UINT32, BASE_DEC, NULL, 0x0, |
220 | 14 | NULL, HFILL }}, |
221 | 14 | }; |
222 | | |
223 | | |
224 | 14 | static int *ett[] = { |
225 | 14 | &ett_tpcp, |
226 | 14 | &ett_tpcp_flags, |
227 | 14 | }; |
228 | | |
229 | 14 | proto_tpcp = proto_register_protocol("Alteon - Transparent Proxy Cache Protocol", "TPCP", "tpcp"); |
230 | 14 | proto_register_field_array(proto_tpcp, hf, array_length(hf)); |
231 | 14 | proto_register_subtree_array(ett, array_length(ett)); |
232 | | |
233 | 14 | tpcp_handle = register_dissector("tpcp", dissect_tpcp, proto_tpcp); |
234 | 14 | } |
235 | | |
236 | | void |
237 | | proto_reg_handoff_tpcp(void) |
238 | 14 | { |
239 | 14 | dissector_add_uint_with_preference("udp.port", UDP_PORT_TPCP, tpcp_handle); |
240 | 14 | } |
241 | | |
242 | | /* |
243 | | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
244 | | * |
245 | | * Local variables: |
246 | | * c-basic-offset: 8 |
247 | | * tab-width: 8 |
248 | | * indent-tabs-mode: t |
249 | | * End: |
250 | | * |
251 | | * vi: set shiftwidth=8 tabstop=8 noexpandtab: |
252 | | * :indentSize=8:tabSize=8:noTabs=false: |
253 | | */ |