/src/wireshark/epan/dissectors/packet-laplink.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* packet-laplink.c |
2 | | * Routines for laplink dissection |
3 | | * Copyright 2003, Brad Hards <bradh@frogmouth.net> |
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 | | #include <epan/packet.h> |
15 | | |
16 | | #include "packet-tcp.h" |
17 | | #include <epan/prefs.h> |
18 | | |
19 | | void proto_register_laplink(void); |
20 | | void proto_reg_handoff_laplink(void); |
21 | | |
22 | | static dissector_handle_t laplink_udp_handle; |
23 | | static dissector_handle_t laplink_tcp_handle; |
24 | | |
25 | 14 | #define TCP_PORT_LAPLINK 1547 |
26 | 14 | #define UDP_PORT_LAPLINK 1547 |
27 | | |
28 | | /* Initialize the protocol and registered fields */ |
29 | | static int proto_laplink; |
30 | | static int hf_laplink_udp_ident; |
31 | | static int hf_laplink_udp_name; |
32 | | static int hf_laplink_tcp_ident; |
33 | | static int hf_laplink_tcp_length; |
34 | | static int hf_laplink_tcp_data; |
35 | | |
36 | | /* Initialize the subtree pointers */ |
37 | | static int ett_laplink; |
38 | | |
39 | | static const value_string laplink_udp_magic[] = { |
40 | | { 0x0f010000, "Name Solicitation" }, |
41 | | { 0xf0000200, "Name Reply" }, |
42 | | { 0, NULL } |
43 | | }; |
44 | | |
45 | | static const value_string laplink_tcp_magic[] = { |
46 | | { 0xff08c000, "Unknown TCP query - connection?" }, |
47 | | { 0xff08c200, "Unknown TCP query - connection?" }, |
48 | | { 0xff0bc000, "Unknown TCP query - connection?" }, |
49 | | { 0xff0bc200, "Unknown TCP query - connection?" }, |
50 | | { 0xff10c000, "Unknown TCP response - connection?" }, |
51 | | { 0xff10c200, "Unknown TCP response - connection?" }, |
52 | | { 0xff11c000, "Unknown TCP query/response - directory list or file transfer?" }, |
53 | | { 0xff11c200, "Unknown TCP query - directory list or file request?" }, |
54 | | { 0xff13c000, "Unknown TCP response - connection?" }, |
55 | | { 0xff13c200, "Unknown TCP response - connection?" }, |
56 | | { 0xff14c000, "Unknown TCP response - directory list or file transfer?" }, |
57 | | { 0, NULL } |
58 | | }; |
59 | | |
60 | | static bool laplink_desegment = true; |
61 | | |
62 | | /* Code to actually dissect the packets - UDP */ |
63 | | static int |
64 | | dissect_laplink_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) |
65 | 6 | { |
66 | 6 | int offset = 0; |
67 | 6 | proto_item *ti; |
68 | 6 | proto_tree *laplink_tree; |
69 | 6 | uint32_t udp_ident; |
70 | 6 | const char *udp_ident_string; |
71 | | |
72 | | /* |
73 | | * Make sure the identifier is reasonable. |
74 | | */ |
75 | 6 | if (!tvb_bytes_exist(tvb, offset, 4)) |
76 | 0 | return 0; /* not enough bytes to check */ |
77 | 6 | udp_ident = tvb_get_ntohl(tvb, offset); |
78 | 6 | udp_ident_string = try_val_to_str(udp_ident, laplink_udp_magic); |
79 | 6 | if (udp_ident_string == NULL) |
80 | 6 | return 0; /* unknown */ |
81 | | |
82 | | /* Make entries in Protocol column and Info column on summary display */ |
83 | 0 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "Laplink"); |
84 | |
|
85 | 0 | col_add_str(pinfo->cinfo, COL_INFO, udp_ident_string); |
86 | |
|
87 | 0 | if (tree){ |
88 | 0 | ti = proto_tree_add_item(tree, proto_laplink, tvb, 0, -1, ENC_NA); |
89 | 0 | laplink_tree = proto_item_add_subtree(ti, ett_laplink); |
90 | |
|
91 | 0 | proto_tree_add_uint(laplink_tree, hf_laplink_udp_ident, tvb, offset, 4, udp_ident); |
92 | 0 | offset += 4; |
93 | |
|
94 | 0 | proto_tree_add_item(laplink_tree, hf_laplink_udp_name, tvb, offset, -1, ENC_ASCII); |
95 | 0 | } |
96 | 0 | return tvb_captured_length(tvb); |
97 | 6 | } |
98 | | |
99 | | /* Code to actually dissect the packets - TCP aspects*/ |
100 | | static int |
101 | | dissect_laplink_tcp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) |
102 | 205 | { |
103 | 205 | int offset = 0; |
104 | 205 | int length = 0; |
105 | 205 | proto_item *ti; |
106 | 205 | proto_tree *laplink_tree; |
107 | 205 | uint32_t tcp_ident; |
108 | | |
109 | | /* Make entries in Protocol column and Info column on summary display */ |
110 | 205 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "Laplink"); |
111 | | |
112 | 205 | tcp_ident = tvb_get_ntohl(tvb, offset); |
113 | 205 | col_add_str(pinfo->cinfo, COL_INFO, |
114 | 205 | val_to_str(tcp_ident, laplink_tcp_magic, "TCP TBA (%u)")); |
115 | | |
116 | 205 | if (tree){ |
117 | 205 | ti = proto_tree_add_item(tree, proto_laplink, tvb, 0, -1, ENC_NA); |
118 | | |
119 | | |
120 | 205 | laplink_tree = proto_item_add_subtree(ti, ett_laplink); |
121 | | |
122 | 205 | proto_tree_add_item(laplink_tree, hf_laplink_tcp_ident, tvb, offset, 4, ENC_BIG_ENDIAN); |
123 | 205 | offset += 4; |
124 | | |
125 | 205 | length = tvb_get_ntohs(tvb, offset); |
126 | 205 | proto_tree_add_item(laplink_tree, hf_laplink_tcp_length, tvb, offset, 2, ENC_BIG_ENDIAN); |
127 | 205 | offset += 2; |
128 | | |
129 | 205 | proto_tree_add_item(laplink_tree, hf_laplink_tcp_data, tvb, offset, length, ENC_NA); |
130 | | |
131 | | /* Continue adding tree items to process the packet here */ |
132 | | |
133 | 205 | } |
134 | | |
135 | 205 | return tvb_captured_length(tvb); |
136 | | /* If this protocol has a sub-dissector call it here, see section 1.8 */ |
137 | 205 | } |
138 | | |
139 | | static unsigned |
140 | | get_laplink_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_) |
141 | 207 | { |
142 | 207 | unsigned plen; |
143 | | /* |
144 | | * The length doesn't include the length or ident fields; add those in. |
145 | | */ |
146 | 207 | plen = (tvb_get_ntohs(tvb, offset+4) + 2 + 4); |
147 | 207 | return plen; |
148 | 207 | } |
149 | | |
150 | | static int |
151 | | dissect_laplink_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data) |
152 | 10 | { |
153 | 10 | tcp_dissect_pdus(tvb, pinfo, tree, laplink_desegment, |
154 | 10 | 6, get_laplink_pdu_len, |
155 | 10 | dissect_laplink_tcp_pdu, data); |
156 | 10 | return tvb_captured_length(tvb); |
157 | 10 | } |
158 | | |
159 | | |
160 | | /* Register the protocol with Wireshark */ |
161 | | |
162 | | void |
163 | | proto_register_laplink(void) |
164 | 14 | { |
165 | | |
166 | | /* Setup list of header fields See Section 1.6.1 for details*/ |
167 | 14 | static hf_register_info hf[] = { |
168 | 14 | { &hf_laplink_udp_ident, |
169 | 14 | { "UDP Ident", "laplink.udp_ident", |
170 | 14 | FT_UINT32, BASE_HEX, VALS(laplink_udp_magic), 0x0, |
171 | 14 | "Unknown magic", HFILL } |
172 | 14 | }, |
173 | 14 | { &hf_laplink_udp_name, |
174 | 14 | { "UDP Name", "laplink.udp_name", |
175 | 14 | FT_STRINGZ, BASE_NONE, NULL, 0x0, |
176 | 14 | "Machine name", HFILL } |
177 | 14 | }, |
178 | 14 | { &hf_laplink_tcp_ident, |
179 | 14 | { "TCP Ident", "laplink.tcp_ident", |
180 | 14 | FT_UINT32, BASE_HEX, VALS(laplink_tcp_magic), 0x0, |
181 | 14 | "Unknown magic", HFILL } |
182 | 14 | }, |
183 | 14 | { &hf_laplink_tcp_length, |
184 | 14 | { "TCP Data payload length", "laplink.tcp_length", |
185 | 14 | FT_UINT16, BASE_DEC, NULL, 0x0, |
186 | 14 | "Length of remaining payload", HFILL } |
187 | 14 | }, |
188 | 14 | { &hf_laplink_tcp_data, |
189 | 14 | { "Unknown TCP data", "laplink.tcp_data", |
190 | 14 | FT_BYTES, BASE_NONE, NULL, 0x0, |
191 | 14 | NULL, HFILL } |
192 | 14 | }, |
193 | 14 | }; |
194 | | |
195 | | /* Setup protocol subtree array */ |
196 | 14 | static int *ett[] = { |
197 | 14 | &ett_laplink, |
198 | 14 | }; |
199 | | |
200 | 14 | module_t *laplink_module; |
201 | | |
202 | | /* Register the protocol name and description */ |
203 | 14 | proto_laplink = proto_register_protocol("Laplink", "Laplink", "laplink"); |
204 | | |
205 | | /* Required function calls to register the header fields and subtrees used */ |
206 | 14 | proto_register_field_array(proto_laplink, hf, array_length(hf)); |
207 | 14 | proto_register_subtree_array(ett, array_length(ett)); |
208 | | |
209 | 14 | laplink_module = prefs_register_protocol(proto_laplink, NULL); |
210 | 14 | prefs_register_bool_preference(laplink_module, "desegment_laplink_over_tcp", |
211 | 14 | "Reassemble Laplink over TCP messages spanning multiple TCP segments", |
212 | 14 | "Whether the Laplink dissector should reassemble messages spanning multiple TCP segments." |
213 | 14 | " To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.", |
214 | 14 | &laplink_desegment); |
215 | | |
216 | 14 | laplink_tcp_handle = register_dissector("laplink.tcp", dissect_laplink_tcp, proto_laplink); |
217 | 14 | laplink_udp_handle = register_dissector("laplink.udp", dissect_laplink_udp, proto_laplink); |
218 | 14 | } |
219 | | |
220 | | |
221 | | /* If this dissector uses sub-dissector registration add a registration routine. |
222 | | This format is required because a script is used to find these routines and |
223 | | create the code that calls these routines. |
224 | | */ |
225 | | void |
226 | | proto_reg_handoff_laplink(void) |
227 | 14 | { |
228 | 14 | dissector_add_uint_with_preference("tcp.port", TCP_PORT_LAPLINK, laplink_tcp_handle); |
229 | 14 | dissector_add_uint_with_preference("udp.port", UDP_PORT_LAPLINK, laplink_udp_handle); |
230 | 14 | } |
231 | | |
232 | | /* |
233 | | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
234 | | * |
235 | | * Local variables: |
236 | | * c-basic-offset: 8 |
237 | | * tab-width: 8 |
238 | | * indent-tabs-mode: t |
239 | | * End: |
240 | | * |
241 | | * vi: set shiftwidth=8 tabstop=8 noexpandtab: |
242 | | * :indentSize=8:tabSize=8:noTabs=false: |
243 | | */ |