epan/dissectors/pidl/samr/samr.cnf cnf_dissect_lsa_BinaryString => lsarpc_dissect_str...
[wireshark-sm.git] / epan / dissectors / packet-dcc.c
blobf0eaf2ec31a2ad40bd51b1a0650f96e2c3aecd24
1 /* packet-dcc.c
2 * Routines for Distributed Checksum Clearinghouse packet dissection
3 * DCC Home: http://www.rhyolite.com/anti-spam/dcc/
5 * Copyright 1999, Nathan Neulinger <nneul@umr.edu>
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * Copied from packet-tftp.c
13 * SPDX-License-Identifier: GPL-2.0-or-later
16 #include "config.h"
18 #include <epan/packet.h>
19 #include <epan/expert.h>
21 #include "packet-dcc.h"
23 void proto_register_dcc(void);
24 void proto_reg_handoff_dcc(void);
26 static int proto_dcc;
27 static int hf_dcc_len;
28 static int hf_dcc_pkt_vers;
29 static int hf_dcc_op;
30 static int hf_dcc_clientid;
31 static int hf_dcc_opnums_host;
32 static int hf_dcc_opnums_pid;
33 static int hf_dcc_opnums_report;
34 static int hf_dcc_opnums_retrans;
36 static int hf_dcc_signature;
37 static int hf_dcc_max_pkt_vers;
38 static int hf_dcc_qdelay_ms;
39 static int hf_dcc_brand;
41 static int hf_dcc_ck_type;
42 static int hf_dcc_ck_len;
43 static int hf_dcc_ck_sum;
45 static int hf_dcc_date;
47 static int hf_dcc_target;
48 static int hf_dcc_response_text;
50 static int hf_dcc_adminop;
51 static int hf_dcc_adminval;
52 static int hf_dcc_floodop;
53 static int hf_dcc_trace;
54 static int hf_dcc_trace_admin;
55 static int hf_dcc_trace_anon;
56 static int hf_dcc_trace_client;
57 static int hf_dcc_trace_rlim;
58 static int hf_dcc_trace_query;
59 static int hf_dcc_trace_ridc;
60 static int hf_dcc_trace_flood;
62 static int hf_dcc_addr;
63 static int hf_dcc_id;
64 static int hf_dcc_last_used;
65 static int hf_dcc_requests;
66 static int hf_dcc_pad;
67 static int hf_dcc_unused;
69 static int ett_dcc;
70 static int ett_dcc_opnums;
71 static int ett_dcc_op;
72 static int ett_dcc_ck;
73 static int ett_dcc_trace;
75 static expert_field ei_dcc_len;
77 /* Utility macros */
78 #define D_SIGNATURE() \
79 proto_tree_add_item(dcc_optree, hf_dcc_signature, tvb, \
80 offset, (int)sizeof(DCC_SIGNATURE), ENC_NA); \
81 offset += (int)sizeof(DCC_SIGNATURE);
83 #define D_LABEL(hf_label, len, encoding) \
84 proto_tree_add_item(dcc_optree, hf_label, tvb, offset, len, encoding); \
85 offset += len;
87 #define D_TEXT(hf_label, endpad) { \
88 int next_offset,left; \
89 while (tvb_offset_exists(tvb, offset+endpad)) { \
90 left = tvb_reported_length_remaining(tvb,offset) - endpad; \
91 tvb_find_line_end(tvb, offset, left, &next_offset, \
92 false); \
93 proto_tree_add_item(dcc_optree, hf_label, tvb, offset, \
94 next_offset - offset, ENC_ASCII|ENC_NA); \
95 offset = next_offset; \
96 } \
100 #define D_TARGET() \
101 proto_tree_add_item(dcc_tree, hf_dcc_target, tvb, \
102 offset, (int)sizeof(DCC_TGTS), ENC_BIG_ENDIAN); \
103 offset += (int)sizeof(DCC_TGTS);
105 #define D_DATE() { \
106 proto_tree_add_item(dcc_optree, hf_dcc_date, tvb, offset, 4, ENC_TIME_SECS|ENC_BIG_ENDIAN); \
107 offset += 4; \
111 #define D_CHECKSUM() { \
112 proto_tree *cktree; \
113 cktree = proto_tree_add_subtree_format(dcc_optree, tvb, offset, (int)sizeof(DCC_CK), \
114 ett_dcc_ck, NULL, "Checksum - %s", val_to_str(tvb_get_uint8(tvb,offset), \
115 dcc_cktype_vals, \
116 "Unknown Type: %u")); \
117 proto_tree_add_item(cktree, hf_dcc_ck_type, tvb, offset, 1, ENC_BIG_ENDIAN); \
118 offset += 1; \
119 proto_tree_add_item(cktree, hf_dcc_ck_len, tvb, offset, 1, ENC_BIG_ENDIAN); \
120 offset += 1; \
121 proto_tree_add_item(cktree, hf_dcc_ck_sum, tvb, offset, \
122 (int)sizeof(DCC_SUM), ENC_NA); \
123 offset += (int)sizeof(DCC_SUM); \
127 /* Lookup string tables */
128 static const value_string dcc_op_vals[] = {
129 {DCC_OP_INVALID, "Invalid Op"},
130 {DCC_OP_NOP, "No-Op"},
131 {DCC_OP_REPORT, "Report and Query"},
132 {DCC_OP_QUERY, "Query"},
133 {DCC_OP_QUERY_RESP, "Server Response"},
134 {DCC_OP_ADMN, "Admin"},
135 {DCC_OP_OK, "Ok"},
136 {DCC_OP_ERROR, "Server Failing"},
137 {DCC_OP_DELETE, "Delete Checksum(s)"},
138 {0, NULL}
141 static const value_string dcc_cktype_vals[] = {
142 {DCC_CK_INVALID, "Invalid/Deleted from DB when seen"},
143 {DCC_CK_IP, "MD5 of binary source IPv6 address"},
144 {DCC_CK_ENV_FROM, "MD5 of envelope Mail From value"},
145 {DCC_CK_FROM, "MD5 of header From: line"},
146 {DCC_CK_SUB, "MD5 of substitute header line"},
147 {DCC_CK_MESSAGE_ID, "MD5 of header Message-ID: line"},
148 {DCC_CK_RECEIVED, "MD5 of last header Received: line"},
149 {DCC_CK_BODY, "MD5 of body"},
150 {DCC_CK_FUZ1, "MD5 of filtered body - FUZ1"},
151 {DCC_CK_FUZ2, "MD5 of filtered body - FUZ2"},
152 {DCC_CK_FUZ3, "MD5 of filtered body - FUZ3"},
153 {DCC_CK_FUZ4, "MD5 of filtered body - FUZ4"},
154 {DCC_CK_SRVR_ID, "hostname for server-ID check "},
155 {DCC_CK_ENV_TO, "MD5 of envelope Rcpt To value"},
156 {0, NULL},
159 static const value_string dcc_adminop_vals[] = {
160 {DCC_AOP_OK, "Never sent"},
161 {DCC_AOP_STOP, "Stop Gracefully"},
162 {DCC_AOP_NEW_IDS, "Load keys and client IDs"},
163 {DCC_AOP_FLOD, "Flood control"},
164 {DCC_AOP_DB_UNLOCK, "Start Switch to new database"},
165 {DCC_AOP_DB_NEW, "Finish Switch to new database"},
166 {DCC_AOP_STATS, "Return counters"},
167 {DCC_AOP_STATS_CLEAR, "Return and zero counters"},
168 {DCC_AOP_TRACE_ON, "Enable tracing"},
169 {DCC_AOP_TRACE_OFF, "Disable tracing"},
170 {DCC_AOP_CUR_CLIENTS, "List clients"},
171 {0, NULL},
174 static const value_string dcc_target_vals[] = {
175 {DCC_TGTS_TOO_MANY, "Targets (>= 16777200)"},
176 {DCC_TGTS_OK, "Certified not spam"},
177 {DCC_TGTS_OK2, "Half certified not spam"},
178 {DCC_TGTS_DEL, "Deleted checksum"},
179 {DCC_TGTS_INVALID, "Invalid"},
180 {0, NULL},
183 static const value_string dcc_floodop_vals[] = {
184 {DCC_AOP_FLOD_CHECK, "Check"},
185 {DCC_AOP_FLOD_SHUTDOWN, "Shutdown"},
186 {DCC_AOP_FLOD_HALT, "Halt"},
187 {DCC_AOP_FLOD_RESUME, "Resume"},
188 {DCC_AOP_FLOD_REWIND, "Rewind"},
189 {DCC_AOP_FLOD_LIST, "List"},
190 {DCC_AOP_FLOD_STATS, "Stats"},
191 {DCC_AOP_FLOD_STATS_CLEAR, "Clear Stats"},
192 {0,NULL},
195 static bool
196 dissect_dcc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
198 proto_tree *dcc_tree, *dcc_optree, *dcc_opnumtree, *ti;
199 proto_tree *dcc_tracetree;
200 proto_item *len_item;
201 int offset = 0;
202 int client_is_le = 0;
203 int op = 0;
204 int i, is_response;
206 if (pinfo->srcport != DCC_PORT && pinfo->destport != DCC_PORT) {
207 /* Not the right port - not a DCC packet. */
208 return false;
211 /* get at least a full packet structure */
212 if ( tvb_reported_length(tvb) < sizeof(DCC_HDR) ) {
213 /* Doesn't have enough bytes to contain packet header. */
214 return false;
217 col_set_str(pinfo->cinfo, COL_PROTOCOL, "DCC");
219 offset = 0;
220 is_response = pinfo->srcport == DCC_PORT;
222 col_add_fstr(pinfo->cinfo, COL_INFO,
223 "%s: %s",
224 is_response ? "Response" : "Request",
225 val_to_str(tvb_get_uint8(tvb, offset+3),
226 dcc_op_vals, "Unknown Op: %u"));
228 ti = proto_tree_add_item(tree, proto_dcc, tvb, offset, -1,
229 ENC_NA);
230 dcc_tree = proto_item_add_subtree(ti, ett_dcc);
232 len_item = proto_tree_add_item(dcc_tree, hf_dcc_len, tvb,
233 offset, 2, ENC_BIG_ENDIAN);
235 if ( tvb_reported_length(tvb) < tvb_get_ntohs(tvb, offset)) {
236 /* Doesn't have number of bytes that header claims. */
237 expert_add_info(pinfo, len_item, &ei_dcc_len);
239 offset += 2;
241 if (tree) {
242 proto_tree_add_item(dcc_tree, hf_dcc_pkt_vers, tvb,
243 offset, 1, ENC_BIG_ENDIAN);
244 offset += 1;
246 op = tvb_get_uint8(tvb, offset);
247 proto_tree_add_item(dcc_tree, hf_dcc_op, tvb,
248 offset, 1, ENC_BIG_ENDIAN);
249 offset += 1;
251 proto_tree_add_item(dcc_tree, hf_dcc_clientid, tvb,
252 offset, 4, ENC_BIG_ENDIAN);
253 offset += 4;
255 dcc_opnumtree = proto_tree_add_subtree(dcc_tree, tvb, offset, -1, ett_dcc_opnums, NULL, "Operation Numbers (Opaque to Server)");
257 /* Note - these are indeterminate - they are sortof considered opaque to the client */
258 /* Make some attempt to figure out if this data is little endian, not guaranteed to be
259 correct if connection went through a firewall or similar. */
261 /* Very hokey check - if all three of pid/report/retrans look like little-endian
262 numbers, host is probably little endian. Probably innacurate on super-heavily-used
263 DCC clients though. This should be good enough for now. */
264 client_is_le = ( (tvb_get_uint8(tvb, offset+4) | tvb_get_uint8(tvb, offset+5)) &&
265 (tvb_get_uint8(tvb, offset+8) | tvb_get_uint8(tvb, offset+9)) &&
266 (tvb_get_uint8(tvb, offset+12) | tvb_get_uint8(tvb, offset+13)) );
268 proto_tree_add_item(dcc_opnumtree, hf_dcc_opnums_host, tvb,
269 offset, 4, client_is_le);
270 offset += 4;
272 proto_tree_add_item(dcc_opnumtree, hf_dcc_opnums_pid, tvb,
273 offset, 4, client_is_le);
274 offset += 4;
276 proto_tree_add_item(dcc_opnumtree, hf_dcc_opnums_report, tvb,
277 offset, 4, client_is_le);
278 offset += 4;
280 proto_tree_add_item(dcc_opnumtree, hf_dcc_opnums_retrans, tvb,
281 offset, 4, client_is_le);
282 offset += 4;
284 dcc_optree = proto_tree_add_subtree_format(dcc_tree, tvb, offset, -1, ett_dcc_op, NULL,
285 "Operation: %s", val_to_str(op, dcc_op_vals, "Unknown Op: %u"));
287 switch(op) {
288 case DCC_OP_NOP:
289 D_SIGNATURE();
290 break;
292 case DCC_OP_REPORT:
293 D_TARGET();
294 for (i=0; i<=DCC_QUERY_MAX &&
295 tvb_bytes_exist(tvb, offset+(int)sizeof(DCC_SIGNATURE),1); i++)
297 D_CHECKSUM();
299 D_SIGNATURE();
300 break;
302 case DCC_OP_QUERY_RESP:
303 for (i=0; i<=DCC_QUERY_MAX &&
304 tvb_bytes_exist(tvb, offset+(int)sizeof(DCC_SIGNATURE),1); i++)
306 D_TARGET();
308 D_SIGNATURE();
309 break;
311 case DCC_OP_ADMN:
312 if ( is_response )
314 int left_local = tvb_reported_length_remaining(tvb, offset) -
315 (int)sizeof(DCC_SIGNATURE);
316 if ( left_local == sizeof(DCC_ADMN_RESP_CLIENTS) )
318 D_LABEL(hf_dcc_addr, 16, ENC_NA);
319 D_LABEL(hf_dcc_id, (int)sizeof(DCC_CLNT_ID), ENC_BIG_ENDIAN);
320 D_LABEL(hf_dcc_last_used, 4, ENC_BIG_ENDIAN);
321 D_LABEL(hf_dcc_requests, 4, ENC_BIG_ENDIAN);
323 else
325 D_TEXT(hf_dcc_response_text, (int)sizeof(DCC_SIGNATURE));
327 D_SIGNATURE();
329 else
331 int aop;
333 D_DATE();
335 aop = tvb_get_uint8(tvb, offset+4);
336 proto_tree_add_item(dcc_optree, hf_dcc_adminop, tvb, offset+4,
337 1, ENC_BIG_ENDIAN);
338 col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
339 val_to_str(tvb_get_uint8(tvb,offset+4),
340 dcc_adminop_vals, "Unknown (%u)"));
342 if (aop == DCC_AOP_TRACE_ON || aop == DCC_AOP_TRACE_OFF )
344 ti = proto_tree_add_item(dcc_optree, hf_dcc_trace, tvb, offset,
345 4, ENC_BIG_ENDIAN);
346 dcc_tracetree = proto_item_add_subtree(ti, ett_dcc_trace);
347 proto_tree_add_item(dcc_tracetree, hf_dcc_trace_admin, tvb, offset, 4, ENC_BIG_ENDIAN);
348 proto_tree_add_item(dcc_tracetree, hf_dcc_trace_anon, tvb, offset, 4, ENC_BIG_ENDIAN);
349 proto_tree_add_item(dcc_tracetree, hf_dcc_trace_client, tvb, offset, 4, ENC_BIG_ENDIAN);
350 proto_tree_add_item(dcc_tracetree, hf_dcc_trace_rlim, tvb, offset, 4, ENC_BIG_ENDIAN);
351 proto_tree_add_item(dcc_tracetree, hf_dcc_trace_query, tvb, offset, 4, ENC_BIG_ENDIAN);
352 proto_tree_add_item(dcc_tracetree, hf_dcc_trace_ridc, tvb, offset, 4, ENC_BIG_ENDIAN);
353 proto_tree_add_item(dcc_tracetree, hf_dcc_trace_flood, tvb, offset, 4, ENC_BIG_ENDIAN);
355 else if ( aop == DCC_AOP_FLOD )
357 proto_tree_add_item(dcc_optree, hf_dcc_floodop,
358 tvb, offset, 4, ENC_BIG_ENDIAN);
359 col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
360 val_to_str(tvb_get_ntohl(tvb,offset),
361 dcc_floodop_vals, "Unknown (%u)"));
363 else
365 proto_tree_add_item(dcc_optree, hf_dcc_adminval,
366 tvb, offset, 4, ENC_BIG_ENDIAN);
368 offset += 4;
370 offset += 1; /* admin op we did in reverse order */
371 D_LABEL(hf_dcc_pad, 3, ENC_NA);
372 D_SIGNATURE();
374 break;
376 case DCC_OP_OK:
377 proto_tree_add_item(dcc_optree, hf_dcc_max_pkt_vers, tvb,
378 offset, 1, ENC_BIG_ENDIAN);
379 offset += 1;
381 D_LABEL(hf_dcc_unused, 1, ENC_NA);
383 proto_tree_add_item(dcc_optree, hf_dcc_qdelay_ms, tvb,
384 offset, 2, ENC_BIG_ENDIAN);
385 offset += 2;
387 proto_tree_add_item(dcc_optree, hf_dcc_brand, tvb,
388 offset, (int)sizeof(DCC_BRAND), ENC_ASCII);
389 offset += (int)sizeof(DCC_BRAND);
391 D_SIGNATURE();
392 break;
394 default:
395 /* do nothing */
396 break;
400 return true;
403 void
404 proto_register_dcc(void)
406 static hf_register_info hf[] = {
407 { &hf_dcc_len, {
408 "Packet Length", "dcc.len", FT_UINT16, BASE_DEC,
409 NULL, 0, NULL, HFILL }},
411 { &hf_dcc_pkt_vers, {
412 "Packet Version", "dcc.pkt_vers", FT_UINT16, BASE_DEC,
413 NULL, 0, NULL, HFILL }},
415 { &hf_dcc_op, {
416 "Operation Type", "dcc.op", FT_UINT8, BASE_DEC,
417 VALS(dcc_op_vals), 0, NULL, HFILL }},
419 { &hf_dcc_clientid, {
420 "Client ID", "dcc.clientid", FT_UINT32, BASE_DEC,
421 NULL, 0, NULL, HFILL }},
423 { &hf_dcc_opnums_host, {
424 "Host", "dcc.opnums.host", FT_UINT32, BASE_DEC,
425 NULL, 0, NULL, HFILL }},
427 { &hf_dcc_opnums_pid, {
428 "Process ID", "dcc.opnums.pid", FT_UINT32, BASE_DEC,
429 NULL, 0, NULL, HFILL }},
431 { &hf_dcc_opnums_report, {
432 "Report", "dcc.opnums.report", FT_UINT32, BASE_DEC,
433 NULL, 0, NULL, HFILL }},
435 { &hf_dcc_opnums_retrans, {
436 "Retransmission", "dcc.opnums.retrans", FT_UINT32, BASE_DEC,
437 NULL, 0, NULL, HFILL }},
439 { &hf_dcc_signature, {
440 "Signature", "dcc.signature", FT_BYTES, BASE_NONE,
441 NULL, 0, NULL, HFILL }},
443 { &hf_dcc_max_pkt_vers, {
444 "Maximum Packet Version", "dcc.max_pkt_vers", FT_UINT8, BASE_DEC,
445 NULL, 0, NULL, HFILL }},
447 { &hf_dcc_qdelay_ms, {
448 "Client Delay", "dcc.qdelay_ms", FT_UINT16, BASE_DEC,
449 NULL, 0, NULL, HFILL }},
451 { &hf_dcc_brand, {
452 "Server Brand", "dcc.brand", FT_STRING, BASE_NONE,
453 NULL, 0, NULL, HFILL }},
455 { &hf_dcc_ck_type, {
456 "Type", "dcc.checksum.type", FT_UINT8, BASE_DEC,
457 VALS(dcc_cktype_vals), 0, "Checksum Type", HFILL }},
459 { &hf_dcc_ck_len, {
460 "Length", "dcc.checksum.length", FT_UINT8, BASE_DEC,
461 NULL, 0, "Checksum Length", HFILL }},
463 { &hf_dcc_ck_sum, {
464 "Sum", "dcc.checksum.sum", FT_BYTES, BASE_NONE,
465 NULL, 0, "Checksum", HFILL }},
467 { &hf_dcc_target, {
468 "Target", "dcc.target", FT_UINT32, BASE_HEX,
469 VALS(dcc_target_vals), 0, NULL, HFILL }},
471 { &hf_dcc_response_text, {
472 "Response Text", "dcc.response_text", FT_BYTES, BASE_NONE,
473 NULL, 0, NULL, HFILL }},
475 { &hf_dcc_date, {
476 "Date", "dcc.date", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
477 NULL, 0, NULL, HFILL }},
479 { &hf_dcc_adminop, {
480 "Admin Op", "dcc.adminop", FT_UINT8, BASE_DEC,
481 VALS(dcc_adminop_vals), 0, NULL, HFILL }},
483 { &hf_dcc_adminval, {
484 "Admin Value", "dcc.adminval", FT_UINT32, BASE_DEC,
485 NULL, 0, NULL, HFILL }},
487 { &hf_dcc_trace, {
488 "Trace Bits", "dcc.trace", FT_UINT32, BASE_HEX,
489 NULL, 0, NULL, HFILL }},
491 { &hf_dcc_trace_admin, {
492 "Admin Requests", "dcc.trace.admin", FT_BOOLEAN, 32,
493 NULL, 0x00000001, NULL, HFILL }},
495 { &hf_dcc_trace_anon, {
496 "Anonymous Requests", "dcc.trace.anon", FT_BOOLEAN, 32,
497 NULL, 0x00000002, NULL, HFILL }},
499 { &hf_dcc_trace_client, {
500 "Authenticated Client Requests", "dcc.trace.client", FT_BOOLEAN, 32,
501 NULL, 0x00000004, NULL, HFILL }},
503 { &hf_dcc_trace_rlim, {
504 "Rate-Limited Requests", "dcc.trace.rlim", FT_BOOLEAN, 32,
505 NULL, 0x00000008, NULL, HFILL }},
507 { &hf_dcc_trace_query, {
508 "Queries and Reports", "dcc.trace.query", FT_BOOLEAN, 32,
509 NULL, 0x00000010, NULL, HFILL }},
511 { &hf_dcc_trace_ridc, {
512 "RID Cache Messages", "dcc.trace.ridc", FT_BOOLEAN, 32,
513 NULL, 0x00000020, NULL, HFILL }},
515 { &hf_dcc_trace_flood, {
516 "Input/Output Flooding", "dcc.trace.flood", FT_BOOLEAN, 32,
517 NULL, 0x00000040, NULL, HFILL }},
519 { &hf_dcc_floodop, {
520 "Flood Control Operation", "dcc.floodop", FT_UINT32, BASE_DEC,
521 VALS(dcc_floodop_vals), 0, NULL, HFILL }},
523 { &hf_dcc_id, {
524 "Id", "dcc.id", FT_UINT32, BASE_DEC,
525 NULL, 0, NULL, HFILL }},
527 { &hf_dcc_last_used, {
528 "Last Used", "dcc.last_used", FT_UINT32, BASE_DEC,
529 NULL, 0, NULL, HFILL }},
531 { &hf_dcc_requests, {
532 "Requests", "dcc.requests", FT_UINT32, BASE_DEC,
533 NULL, 0, NULL, HFILL }},
535 { &hf_dcc_addr, {
536 "Addr", "dcc.addr", FT_BYTES, BASE_NONE,
537 NULL, 0, NULL, HFILL }},
539 { &hf_dcc_pad, {
540 "Pad", "dcc.pad", FT_BYTES, BASE_NONE,
541 NULL, 0, NULL, HFILL }},
543 { &hf_dcc_unused, {
544 "Unused", "dcc.unused", FT_BYTES, BASE_NONE,
545 NULL, 0, NULL, HFILL }},
548 static int *ett[] = {
549 &ett_dcc,
550 &ett_dcc_op,
551 &ett_dcc_ck,
552 &ett_dcc_opnums,
553 &ett_dcc_trace,
556 static ei_register_info ei[] = {
557 { &ei_dcc_len, { "dcc.len.short", PI_MALFORMED, PI_ERROR, "Error - packet is shorter than header claims!", EXPFILL }},
560 expert_module_t* expert_dcc;
562 proto_dcc = proto_register_protocol("Distributed Checksum Clearinghouse protocol", "DCC", "dcc");
564 proto_register_field_array(proto_dcc, hf, array_length(hf));
565 proto_register_subtree_array(ett, array_length(ett));
566 expert_dcc = expert_register_protocol(proto_dcc);
567 expert_register_field_array(expert_dcc, ei, array_length(ei));
570 void
571 proto_reg_handoff_dcc(void)
573 heur_dissector_add("udp", dissect_dcc, "Distributed Checksum Clearinghouse over UDP", "dcc_udp", proto_dcc, HEURISTIC_ENABLE);
577 * Editor modelines - https://www.wireshark.org/tools/modelines.html
579 * Local variables:
580 * c-basic-offset: 8
581 * tab-width: 8
582 * indent-tabs-mode: t
583 * End:
585 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
586 * :indentSize=8:tabSize=8:noTabs=false: