Preparations for dropping the old plugin api.
[obnox/wireshark/wip.git] / plugins / acn / packet-acn.c
1 /* packet-acn.c
2  * Routines for ACN packet disassembly
3  *
4  * $Id$
5  *
6  * Copyright (c) 2003 by Erwin Rol <erwin@erwinrol.com>
7  *
8  * Ethereal - Network traffic analyzer
9  * By Gerald Combs <gerald@ethereal.com>
10  * Copyright 1999 Gerald Combs
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License
14  * as published by the Free Software Foundation; either version 2
15  * of the License, or (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
25  */
26
27 /* Include files */
28
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32
33 #include "moduleinfo.h"
34
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <ctype.h>
38 #include <time.h>
39 #include <string.h>
40
41 #include <glib.h>
42 #include <gmodule.h>
43
44 #include <epan/packet.h>
45 #include <epan/addr_resolv.h>
46 #include <epan/prefs.h>
47 #include <epan/strutil.h>
48
49 #include "acn.h"
50
51 /* Define version if we are not building ethereal statically */
52
53 #ifndef ENABLE_STATIC
54 G_MODULE_EXPORT const gchar version[] = VERSION;
55 #endif
56
57 /*
58  * See
59  *
60  *      http://www.esta.org/tsp/E1-17inst.htm
61  */
62
63 static const value_string acn_proto_vals[] = {
64         { ACN_PDU_PROTO_UNKNOWN,        "Unknown"},
65         { ACN_PDU_PROTO_SDT,            "SDT" },
66         { ACN_PDU_PROTO_DMP,            "DMP" },
67         { 0,                            NULL }
68 };
69
70 static const value_string acn_sdt_type_vals[] = {
71         { ACN_SDT_TYPE_UNKNOWN,         "Unknown"},
72         { ACN_SDT_TYPE_RELSEQDATA,      "RELSEQDATA"},
73         { ACN_SDT_TYPE_UNRELSEQDATA,    "UNRELSEQDATA"},
74         { ACN_SDT_TYPE_UNSEQDATA,       "UNSEQDATA"},
75         { ACN_SDT_TYPE_JOIN,            "JOIN"},
76         { ACN_SDT_TYPE_TRANSFER,        "TRANSFER"},
77         { ACN_SDT_TYPE_JOINREF,         "JOINREF"},
78         { ACN_SDT_TYPE_JOINACC,         "JOINACC"},
79         { ACN_SDT_TYPE_LEAVEREQ,        "LEAVEREQ"},
80         { ACN_SDT_TYPE_LEAVE,           "LEAVE"},
81         { ACN_SDT_TYPE_LEAVING,         "LEAVING"},
82         { ACN_SDT_TYPE_NAKUPON,         "NAKUPON"},
83         { ACN_SDT_TYPE_NAKUPOFF,        "NAKUPOFF"},
84         { ACN_SDT_TYPE_NAKDOWNON,       "NAKDOWNON"},
85         { ACN_SDT_TYPE_NAKDOWNOFF,      "NAKDOWNOFF"},
86         { ACN_SDT_TYPE_REPLOSTSEQON,    "REPLOSTSEQON"},
87         { ACN_SDT_TYPE_REPLOSTSEQOFF,   "REPLOSTSEQOFF"},
88         { ACN_SDT_TYPE_SESSEXPIRY,      "SESEXPIRY"},
89         { ACN_SDT_TYPE_MAK,             "MAK"},
90         { ACN_SDT_TYPE_ACK,             "ACK"},
91         { ACN_SDT_TYPE_NAK,             "NAK"},
92         { ACN_SDT_TYPE_SEQLOST,         "SEQLOST"},
93         { ACN_SDT_TYPE_NAKPARAMS,       "NAKPARAMS"},
94         { 0,                            NULL }
95 };
96
97 static const value_string acn_dmp_type_vals[] = {
98         { ACN_DMP_TYPE_UNKNOWN,         "Unknown"},
99         { 0,                            NULL }
100 };
101
102
103 static const value_string acn_sdt_address_type_vals[] = {
104         { ACN_SDT_ADDR_NULL,            "Unspecified"},
105         { ACN_SDT_ADDR_IPV4,            "IP version 4"},
106         { ACN_SDT_ADDR_IPV6,            "IP version 6"},
107         { 0,                            NULL }
108 };
109
110 static const value_string acn_sdt_des_flag_vals[] = {
111         { 0,                            "Default"},
112         { 1,                            "Protocol Specific"},
113         { 2,                            "CID"},
114         { 3,                            "All"}, 
115         { 0,                            NULL }
116 };
117
118 static const value_string acn_sdt_src_flag_vals[] = {
119         { 0,                            "Default"},
120         { 1,                            "Protocol Specific"},
121         { 2,                            "CID"},
122         { 3,                            "Unspecified"}, 
123         { 0,                            NULL }
124 };
125
126
127 void proto_reg_handoff_acn(void);
128
129 /* Define the acn proto */
130 static int proto_acn = -1;
131
132 /* Define the tree for acn */
133 static int ett_acn = -1;
134
135 /* PDU */
136 static int hf_acn_pdu = -1;
137
138 static int hf_acn_pdu_flags = -1;
139
140 static int hf_acn_pdu_des = -1;
141 static int hf_acn_pdu_src = -1;
142 static int hf_acn_pdu_flag_p = -1;
143 static int hf_acn_pdu_flag_t = -1;
144 static int hf_acn_pdu_flag_res = -1;
145 static int hf_acn_pdu_flag_z = -1;
146 static int hf_acn_pdu_length = -1;
147
148 /* PDU optional */
149 static int hf_acn_pdu_ext_length_16 = -1;
150 static int hf_acn_pdu_ext_length_32 = -1;
151 static int hf_acn_pdu_source_ps = -1;
152 static int hf_acn_pdu_source_cid = -1;
153 static int hf_acn_pdu_destination_ps = -1;
154 static int hf_acn_pdu_destination_cid = -1;
155 static int hf_acn_pdu_protocol = -1;
156 static int hf_acn_pdu_type = -1;
157 static int hf_acn_pdu_type_sdt = -1;
158 static int hf_acn_pdu_type_dmp = -1;
159 static int hf_acn_pdu_data = -1;
160 static int hf_acn_pdu_unknown_data = -1;
161
162 static int hf_acn_pdu_padding = -1;
163
164 /* SDT */
165 static int hf_acn_sdt_session_nr = -1;
166 static int hf_acn_sdt_tot_seq_nr = -1;
167 static int hf_acn_sdt_rel_seq_nr = -1;
168 static int hf_acn_sdt_unavailable_wrappers = -1;
169 static int hf_acn_sdt_refuse_code = -1;
170 static int hf_acn_sdt_last_rel_seq = -1;
171 static int hf_acn_sdt_new_rel_seq = -1;
172 static int hf_acn_sdt_last_rel_wrapper = -1;
173 static int hf_acn_sdt_nr_lost_wrappers = -1;
174 static int hf_acn_sdt_session_exp_time = -1;
175 static int hf_acn_sdt_upstream_address_type = -1;
176 static int hf_acn_sdt_upstream_ipv4_address = -1;
177 static int hf_acn_sdt_upstream_ipv6_address = -1;
178 static int hf_acn_sdt_upstream_port = -1;
179 static int hf_acn_sdt_downstream_address_type = -1;
180 static int hf_acn_sdt_downstream_ipv4_address = -1;
181 static int hf_acn_sdt_downstream_ipv6_address = -1;
182 static int hf_acn_sdt_downstream_port = -1;
183
184 static int hf_acn_sdt_flags = -1;
185 static int hf_acn_sdt_flag_u = -1;
186 static int hf_acn_sdt_flag_d = -1;
187 static int hf_acn_sdt_flag_l = -1;
188
189 static int hf_acn_sdt_mid = -1;
190 static int hf_acn_sdt_nak_holdoff_interval = -1;
191 static int hf_acn_sdt_nak_modulus = -1;
192 static int hf_acn_sdt_max_nak_wait_time = -1;
193 static int hf_acn_sdt_leader_cid = -1;
194 static int hf_acn_sdt_member_cid = -1;
195 static int hf_acn_sdt_ack_threshold = -1;
196
197 /*
198  * Here are the global variables associated with the preferences
199  * for acn
200  */
201
202 static guint global_udp_port_acn = 0;
203 static guint udp_port_acn = 0;
204
205 /* A static handle for the ip dissector */
206 static dissector_handle_t ip_handle;
207
208 static guint dissect_pdu(tvbuff_t *tvb, guint offset, proto_tree *tree, acn_pdu_history_t* parent_hist, guint max_size);
209 static guint dissect_sdt(tvbuff_t *tvb, guint offset, proto_tree *tree, acn_pdu_history_t* parent_hist, guint max_size);
210 static guint dissect_dmp(tvbuff_t *tvb, guint offset, proto_tree *tree, acn_pdu_history_t* parent_hist, guint max_size);
211
212 static guint 
213 dissect_sdt(tvbuff_t *tvb, guint offset, proto_tree *tree, acn_pdu_history_t* parent_hist, guint max_size)
214 {
215         proto_tree *flags_tree, *flags_item;
216         guint start_offset = offset;
217         acn_pdu_history_t hist;
218         guint size = 0;
219         guint flags;
220         guint type;
221         guint count;
222
223         hist = *parent_hist;
224
225         switch( parent_hist->type )
226         {
227                 case ACN_SDT_TYPE_UNKNOWN:
228                         break;
229
230                 case ACN_SDT_TYPE_RELSEQDATA:
231                 case ACN_SDT_TYPE_UNRELSEQDATA:
232                         proto_tree_add_item(tree, hf_acn_sdt_session_nr, tvb,
233                                                 offset, 2, FALSE);
234                         offset += 2;
235                         
236                         proto_tree_add_item(tree, hf_acn_sdt_tot_seq_nr, tvb,
237                                                 offset, 4, FALSE);
238                         offset += 4;
239
240                         proto_tree_add_item(tree, hf_acn_sdt_rel_seq_nr, tvb,
241                                                 offset, 4, FALSE);
242                         offset += 4;
243
244                         proto_tree_add_item(tree, hf_acn_sdt_unavailable_wrappers, tvb,
245                                                 offset, 4, FALSE);
246                         offset += 4;
247
248                         max_size = max_size - (offset - start_offset);
249                         while( max_size >= ACN_PDU_MIN_SIZE) {
250                                 size = dissect_pdu( tvb, offset, tree, &hist, max_size);
251                                 offset += size;
252                                 max_size -= size;
253                         }
254                         
255                         size = offset - start_offset;
256
257                         break;
258
259                 case ACN_SDT_TYPE_UNSEQDATA:
260                         proto_tree_add_item(tree, hf_acn_sdt_session_nr, tvb,
261                                                 offset, 2, FALSE);
262                         offset += 2;
263
264                         max_size = max_size - (offset - start_offset);
265                         while( max_size >= ACN_PDU_MIN_SIZE) {
266                                 size = dissect_pdu( tvb, offset, tree, &hist, max_size);
267                                 offset += size;
268                                 max_size -= size;
269                         }
270                         
271                         size = offset - start_offset;
272
273                         break;
274                         
275                 case ACN_SDT_TYPE_JOIN:
276                         proto_tree_add_item(tree, hf_acn_sdt_session_nr, tvb,
277                                                 offset, 2, FALSE);
278                         offset += 2;
279
280                         flags = tvb_get_guint8(tvb, offset);
281                         flags_item = proto_tree_add_uint(tree, hf_acn_sdt_flags, tvb,
282                                                         offset, 1, flags);
283
284                         flags_tree=proto_item_add_subtree(flags_item, ett_acn);
285                         proto_tree_add_item(flags_tree, hf_acn_sdt_flag_u, tvb, offset, 1, FALSE);
286                         proto_tree_add_item(flags_tree, hf_acn_sdt_flag_d, tvb, offset, 1, FALSE);
287                         proto_tree_add_item(flags_tree, hf_acn_sdt_flag_l, tvb, offset, 1, FALSE);
288                         offset += 1;
289
290                         type = tvb_get_guint8(tvb, offset);
291                         proto_tree_add_item(tree, hf_acn_sdt_upstream_address_type, tvb,
292                                             offset, 1, FALSE);
293                         offset += 1;
294                         
295                         switch( type )
296                         {
297                                 default:
298                                 case ACN_SDT_ADDR_NULL:
299                                         break;
300                                         
301                                 case ACN_SDT_ADDR_IPV4:
302                                         proto_tree_add_item(tree, hf_acn_sdt_upstream_port, tvb,
303                                                                 offset, 2, FALSE);
304                                         offset += 2;
305                                 
306                                         proto_tree_add_item(tree, hf_acn_sdt_upstream_ipv4_address, tvb,
307                                                                 offset, 4, FALSE);
308                                         offset += 4;
309                                 
310                                         break;
311                                         
312                                 case ACN_SDT_ADDR_IPV6:
313                                         proto_tree_add_item(tree, hf_acn_sdt_upstream_port, tvb,
314                                                                 offset, 2, FALSE);
315                                         offset += 2;
316
317                                         proto_tree_add_item(tree, hf_acn_sdt_upstream_ipv6_address, tvb,
318                                                                 offset, 16, FALSE);
319                                         offset += 16;
320                                 
321                                         break;          
322                         }
323                         
324                         flags = tvb_get_guint8(tvb, offset);
325                         flags_item = proto_tree_add_uint(tree, hf_acn_sdt_flags, tvb,
326                                                         offset, 1, flags);
327
328                         flags_tree=proto_item_add_subtree(flags_item, ett_acn);
329                         offset += 1;
330
331                         type = tvb_get_guint8(tvb, offset);
332                         proto_tree_add_item(tree, hf_acn_sdt_downstream_address_type, tvb,
333                                             offset, 1, FALSE);
334                         offset += 1;
335                         
336                         switch( type )
337                         {
338                                 default:
339                                 case ACN_SDT_ADDR_NULL:
340                                         break;
341                                         
342                                 case ACN_SDT_ADDR_IPV4:
343                                         proto_tree_add_item(tree, hf_acn_sdt_downstream_port, tvb,
344                                                                 offset, 2, FALSE);
345                                         offset += 2;
346
347                                         proto_tree_add_item(tree, hf_acn_sdt_downstream_ipv4_address, tvb,
348                                                                 offset, 4, FALSE);
349                                         offset += 4;
350                                 
351                                 
352                                         break;
353                                         
354                                 case ACN_SDT_ADDR_IPV6:
355                                         proto_tree_add_item(tree, hf_acn_sdt_downstream_port, tvb,
356                                                                 offset, 2, FALSE);
357                                         offset += 2;
358
359                                         proto_tree_add_item(tree, hf_acn_sdt_downstream_ipv6_address, tvb,
360                                                                 offset, 16, FALSE);
361                                         offset += 16;
362                                 
363                                         break;          
364                         }
365                         
366                                                         
367                         proto_tree_add_item(tree, hf_acn_sdt_mid, tvb,
368                                                 offset, 2, FALSE);
369                         offset += 2;
370
371                         proto_tree_add_item(tree, hf_acn_sdt_tot_seq_nr, tvb,
372                                                 offset, 4, FALSE);
373                         offset += 4;
374
375                         proto_tree_add_item(tree, hf_acn_sdt_rel_seq_nr, tvb,
376                                                 offset, 4, FALSE);
377                         offset += 4;
378                         
379                         proto_tree_add_item(tree, hf_acn_sdt_session_exp_time, tvb,
380                                                 offset, 2, FALSE);
381                         offset += 2;
382
383                         proto_tree_add_item(tree, hf_acn_sdt_nak_holdoff_interval, tvb,
384                                                 offset, 2, FALSE);
385                         offset += 2;
386                         
387                         proto_tree_add_item(tree, hf_acn_sdt_nak_modulus, tvb,
388                                                 offset, 2, FALSE);
389                         offset += 2;
390                         
391                         proto_tree_add_item(tree, hf_acn_sdt_max_nak_wait_time, tvb,
392                                                 offset, 2, FALSE);
393                         offset += 2;
394                                         
395                         size = offset - start_offset;
396
397                         break;
398
399                 case ACN_SDT_TYPE_TRANSFER:
400                         proto_tree_add_item(tree, hf_acn_sdt_leader_cid, tvb,
401                                                 offset, 16, FALSE);
402                         offset += 16;
403
404                         proto_tree_add_item(tree, hf_acn_sdt_session_nr, tvb,
405                                                 offset, 2, FALSE);
406                         offset += 2;
407
408                         flags = tvb_get_guint8(tvb, offset);
409                         flags_item = proto_tree_add_uint(tree, hf_acn_sdt_flags, tvb,
410                                                         offset, 1, flags);
411
412                         flags_tree=proto_item_add_subtree(flags_item, ett_acn);
413                         proto_tree_add_item(flags_tree, hf_acn_sdt_flag_u, tvb, offset, 1, FALSE);
414                         proto_tree_add_item(flags_tree, hf_acn_sdt_flag_d, tvb, offset, 1, FALSE);
415                         proto_tree_add_item(flags_tree, hf_acn_sdt_flag_l, tvb, offset, 1, FALSE);
416                         offset += 1;
417
418                         type = tvb_get_guint8(tvb, offset);
419                         proto_tree_add_item(tree, hf_acn_sdt_upstream_address_type, tvb,
420                                             offset, 1, FALSE);
421                         offset += 1;
422                         
423                         switch( type )
424                         {
425                                 default:
426                                 case ACN_SDT_ADDR_NULL:
427                                         break;
428                                         
429                                 case ACN_SDT_ADDR_IPV4:
430                                         proto_tree_add_item(tree, hf_acn_sdt_upstream_ipv4_address, tvb,
431                                                                 offset, 4, FALSE);
432                                         offset += 4;
433                                 
434                                         proto_tree_add_item(tree, hf_acn_sdt_upstream_port, tvb,
435                                                                 offset, 2, FALSE);
436                                         offset += 2;
437                                 
438                                         break;
439                                         
440                                 case ACN_SDT_ADDR_IPV6:
441                                         proto_tree_add_item(tree, hf_acn_sdt_upstream_ipv6_address, tvb,
442                                                                 offset, 16, FALSE);
443                                         offset += 16;
444                                 
445                                         proto_tree_add_item(tree, hf_acn_sdt_upstream_port, tvb,
446                                                                 offset, 2, FALSE);
447                                         offset += 2;
448                                         break;          
449                         }
450                         
451                         flags = tvb_get_guint8(tvb, offset);
452                         flags_item = proto_tree_add_uint(tree, hf_acn_sdt_flags, tvb,
453                                                         offset, 1, flags);
454
455                         flags_tree=proto_item_add_subtree(flags_item, ett_acn);
456                         offset += 1;
457
458                         type = tvb_get_guint8(tvb, offset);
459                         proto_tree_add_item(tree, hf_acn_sdt_downstream_address_type, tvb,
460                                             offset, 1, FALSE);
461                         offset += 1;
462                         
463                         switch( type )
464                         {
465                                 default:
466                                 case ACN_SDT_ADDR_NULL:
467                                         break;
468                                         
469                                 case ACN_SDT_ADDR_IPV4:
470                                         proto_tree_add_item(tree, hf_acn_sdt_downstream_ipv4_address, tvb,
471                                                                 offset, 4, FALSE);
472                                         offset += 4;
473                                 
474                                         proto_tree_add_item(tree, hf_acn_sdt_downstream_port, tvb,
475                                                                 offset, 2, FALSE);
476                                         offset += 2;
477                                 
478                                         break;
479                                         
480                                 case ACN_SDT_ADDR_IPV6:
481                                         proto_tree_add_item(tree, hf_acn_sdt_downstream_ipv6_address, tvb,
482                                                                 offset, 16, FALSE);
483                                         offset += 16;
484                                 
485                                         proto_tree_add_item(tree, hf_acn_sdt_downstream_port, tvb,
486                                                                 offset, 2, FALSE);
487                                         offset += 2;
488                                         break;          
489                         }
490                         
491                                                         
492                         proto_tree_add_item(tree, hf_acn_sdt_mid, tvb,
493                                                 offset, 2, FALSE);
494                         offset += 2;
495
496                         proto_tree_add_item(tree, hf_acn_sdt_tot_seq_nr, tvb,
497                                                 offset, 4, FALSE);
498                         offset += 4;
499
500                         proto_tree_add_item(tree, hf_acn_sdt_rel_seq_nr, tvb,
501                                                 offset, 4, FALSE);
502                         offset += 4;
503                         
504                         proto_tree_add_item(tree, hf_acn_sdt_session_exp_time, tvb,
505                                                 offset, 2, FALSE);
506                         offset += 2;
507
508                         proto_tree_add_item(tree, hf_acn_sdt_nak_holdoff_interval, tvb,
509                                                 offset, 2, FALSE);
510                         offset += 2;
511                         
512                         proto_tree_add_item(tree, hf_acn_sdt_nak_modulus, tvb,
513                                                 offset, 2, FALSE);
514                         offset += 2;
515                         
516                         proto_tree_add_item(tree, hf_acn_sdt_max_nak_wait_time, tvb,
517                                                 offset, 2, FALSE);
518                         offset += 2;
519                         
520                         /* CID+MID list */
521                         count = (max_size - (offset - start_offset)) / 18;
522                         while( count > 0) {
523                                 proto_tree_add_item(tree, hf_acn_sdt_member_cid, tvb,
524                                                         offset, 16, FALSE);
525                                 offset += 16;
526
527                                 proto_tree_add_item(tree, hf_acn_sdt_mid, tvb,
528                                                         offset, 2, FALSE);
529                                 offset += 2;
530
531                                 count--;
532                         }
533                         
534                         size = offset - start_offset;
535
536                         break;
537
538                 case ACN_SDT_TYPE_JOINREF:
539                         proto_tree_add_item(tree, hf_acn_sdt_session_nr, tvb,
540                                                 offset, 2, FALSE);
541                         offset += 2;
542
543                         proto_tree_add_item(tree, hf_acn_sdt_refuse_code, tvb,
544                                                 offset, 2, FALSE);
545                         offset += 2;
546
547                         size = offset - start_offset;
548                         break;
549
550                 case ACN_SDT_TYPE_JOINACC:
551                 case ACN_SDT_TYPE_ACK:
552                         proto_tree_add_item(tree, hf_acn_sdt_last_rel_seq, tvb,
553                                                 offset, 4, FALSE);
554                         offset += 4;
555
556                         size = offset - start_offset;
557                         break;
558
559                 case ACN_SDT_TYPE_LEAVING:
560                         proto_tree_add_item(tree, hf_acn_sdt_last_rel_wrapper, tvb,
561                                                 offset, 4, FALSE);
562                         offset += 4;
563
564                         size = offset - start_offset;
565                         break;
566
567
568                 case ACN_SDT_TYPE_SESSEXPIRY:
569                         proto_tree_add_item(tree, hf_acn_sdt_session_exp_time, tvb,
570                                                 offset, 2, FALSE);
571                         offset += 2;
572
573                         size = offset - start_offset;
574                         break;
575
576                 case ACN_SDT_TYPE_MAK:
577                         proto_tree_add_item(tree, hf_acn_sdt_ack_threshold, tvb,
578                                                 offset, 2, FALSE);
579                         offset += 2;
580
581                         count = (max_size - (offset - start_offset)) / 2;
582                         while( count > 0) {
583                                 proto_tree_add_item(tree, hf_acn_sdt_mid, tvb,
584                                                         offset, 2, FALSE);
585                                 offset += 2;
586
587                                 count--;
588                         }
589                         
590                         size = offset - start_offset;
591                         break;
592                         
593                 case ACN_SDT_TYPE_NAK:                          
594                         proto_tree_add_item(tree, hf_acn_sdt_session_nr, tvb,
595                                                 offset, 2, FALSE);
596                         offset += 2;
597
598                         proto_tree_add_item(tree, hf_acn_sdt_mid, tvb,
599                                                 offset, 2, FALSE);
600                         offset += 2;
601
602                         proto_tree_add_item(tree, hf_acn_sdt_last_rel_seq, tvb,
603                                                 offset, 4, FALSE);
604                         offset += 4;
605
606                         proto_tree_add_item(tree, hf_acn_sdt_nr_lost_wrappers, tvb,
607                                                 offset, 2, FALSE);
608                         offset += 2;
609
610                         size = offset - start_offset;
611                         break;
612                         
613                 case ACN_SDT_TYPE_SEQLOST:
614                         proto_tree_add_item(tree, hf_acn_sdt_last_rel_seq, tvb,
615                                                 offset, 4, FALSE);
616                         offset += 4;
617
618                         proto_tree_add_item(tree, hf_acn_sdt_new_rel_seq, tvb,
619                                                 offset, 4, FALSE);
620                         offset += 4;
621                         size = offset - start_offset;
622                         break;
623
624                 case ACN_SDT_TYPE_NAKPARAMS:
625                         proto_tree_add_item(tree, hf_acn_sdt_nak_holdoff_interval, tvb,
626                                                 offset, 2, FALSE);
627                         offset += 2;
628                         
629                         proto_tree_add_item(tree, hf_acn_sdt_nak_modulus, tvb,
630                                                 offset, 2, FALSE);
631                         offset += 2;
632                         
633                         proto_tree_add_item(tree, hf_acn_sdt_max_nak_wait_time, tvb,
634                                                 offset, 2, FALSE);
635                         offset += 2;
636
637                         size = offset - start_offset;
638                         break;
639
640                 case ACN_SDT_TYPE_LEAVEREQ:
641                 case ACN_SDT_TYPE_LEAVE:
642                 case ACN_SDT_TYPE_NAKUPON:
643                 case ACN_SDT_TYPE_NAKUPOFF:
644                 case ACN_SDT_TYPE_NAKDOWNON:
645                 case ACN_SDT_TYPE_NAKDOWNOFF:
646                 case ACN_SDT_TYPE_REPLOSTSEQON:
647                 case ACN_SDT_TYPE_REPLOSTSEQOFF:
648                         /* no data */
649                         size = offset - start_offset;
650                         break;
651
652                 default:
653                         break;
654         }
655         
656         return size;
657 }
658
659 static guint 
660 dissect_dmp(tvbuff_t *tvb _U_, guint offset _U_, proto_tree *tree _U_, acn_pdu_history_t* parent_hist _U_, guint max_size _U_)
661 {
662         return 0;
663 }
664
665 static guint 
666 dissect_pdu(tvbuff_t *tvb, guint offset, proto_tree *tree, acn_pdu_history_t* parent_hist, guint max_size)
667 {
668         guint size,data_size;
669         guint8 flags;
670         guint src,des;
671         proto_tree *ti, *si, *flags_tree, *flags_item, *data_tree, *data_item;
672         guint start_offset = offset;
673         acn_pdu_history_t hist = *parent_hist;
674         
675
676         ti = proto_tree_add_item(tree,
677                                 hf_acn_pdu,
678                                 tvb,
679                                 offset,
680                                 0,
681                                 FALSE);
682  
683         si = proto_item_add_subtree(ti, ett_acn);
684  
685         flags = tvb_get_guint8(tvb, offset);
686         flags_item = proto_tree_add_uint(si, hf_acn_pdu_flags, tvb,
687                                         offset, 1, flags);
688
689         flags_tree=proto_item_add_subtree(flags_item, ett_acn);
690         
691         proto_tree_add_item(flags_tree, hf_acn_pdu_des, tvb, offset, 1, FALSE);
692         proto_tree_add_item(flags_tree, hf_acn_pdu_src, tvb, offset, 1, FALSE);
693         proto_tree_add_item(flags_tree, hf_acn_pdu_flag_p, tvb, offset, 1, FALSE);
694         proto_tree_add_item(flags_tree, hf_acn_pdu_flag_t, tvb, offset, 1, FALSE);
695         proto_tree_add_item(flags_tree, hf_acn_pdu_flag_res, tvb, offset, 1, FALSE);
696         proto_tree_add_item(flags_tree, hf_acn_pdu_flag_z, tvb, offset, 1, FALSE);
697
698         offset += 1;
699
700         size = tvb_get_guint8(tvb, offset);     
701         proto_tree_add_uint(si, hf_acn_pdu_length, tvb,
702                                   offset, 1, size);
703         offset += 1;
704         
705
706         if( size == 0 ){
707                 size = tvb_get_ntohs(tvb, offset);
708                 proto_tree_add_uint(si, hf_acn_pdu_ext_length_16, tvb,
709                                         offset, 2, size);       
710                 offset += 2;    
711         } else if( size == 1 ){
712                 size = tvb_get_ntohl( tvb, offset);
713                 proto_tree_add_uint(si, hf_acn_pdu_ext_length_32, tvb,
714                                         offset, 4, size);       
715                 offset += 4;
716         }
717         
718         if(size > max_size )
719                 size = max_size;
720
721         switch( flags & ACN_PDU_DES )
722         {       
723                 case ACN_PDU_DES_SAME:
724                         break;
725                         
726                 case ACN_PDU_DES_PS:
727                         hist.destination_type = ACN_PDU_DES_PS;
728                         des = tvb_get_ntohs(tvb, offset);
729                         hist.destination.ps = des;
730                         proto_tree_add_uint(si, hf_acn_pdu_destination_ps, tvb,
731                                                 offset, 2, des);        
732                         offset += 2;
733                         break;
734                         
735                 case ACN_PDU_DES_CID:
736                         hist.destination_type = ACN_PDU_DES_CID;
737                         tvb_memcpy(tvb, hist.destination.cid, offset, 16 );
738                         proto_tree_add_item(si, hf_acn_pdu_destination_cid, tvb,
739                                                 offset, 16, FALSE);
740                         offset += 16;
741                         break;
742                         
743                 case ACN_PDU_DES_ALL:
744                         hist.destination_type = ACN_PDU_DES_ALL;
745                         break;  
746         } 
747
748
749         switch( flags & ACN_PDU_SRC )
750         {
751                 case ACN_PDU_SRC_SAME:
752                         break;
753                         
754                 case ACN_PDU_SRC_PS:
755                         hist.source_type = ACN_PDU_SRC_PS;
756                         src = tvb_get_ntohs(tvb, offset);
757                         hist.source.ps = src;
758                         proto_tree_add_uint(si, hf_acn_pdu_source_ps, tvb,
759                                                 offset, 2, src);
760                         offset += 2;
761                         break;
762                         
763                 case ACN_PDU_SRC_CID:
764                         hist.source_type = ACN_PDU_SRC_CID;
765                         tvb_memcpy(tvb, hist.source.cid, offset, 16 );
766                         proto_tree_add_item(si, hf_acn_pdu_source_cid, tvb,
767                                                 offset, 16, FALSE);
768                         offset += 16;
769                         break;
770                         
771                 case ACN_PDU_SRC_UM:
772                         hist.source_type = ACN_PDU_SRC_UM;
773                         break;  
774         } 
775
776
777
778         if( flags & ACN_PDU_FLAG_P )
779         {
780                 hist.protocol = tvb_get_ntohs( tvb, offset );
781                 proto_tree_add_item(si, hf_acn_pdu_protocol, tvb,
782                                         offset, 2, FALSE );
783                 offset += 2;
784         }
785
786         if( flags & ACN_PDU_FLAG_T )
787         {
788                 hist.type = tvb_get_ntohs( tvb, offset );
789         
790                 switch( hist.protocol ) { 
791                         case ACN_PDU_PROTO_SDT:
792                                 proto_tree_add_item(si, hf_acn_pdu_type_sdt, tvb,
793                                                 offset, 2, FALSE );
794                                 break;
795
796                         case ACN_PDU_PROTO_DMP:
797                                 proto_tree_add_item(si, hf_acn_pdu_type_dmp, tvb,
798                                                 offset, 2, FALSE );
799                                 break;
800                                 
801                         default:
802                                 proto_tree_add_item(si, hf_acn_pdu_type, tvb,
803                                                 offset, 2, FALSE );
804                                 break;  
805         
806         
807         
808                 }
809                 
810                 offset += 2;
811         }
812
813         if( flags & ACN_PDU_FLAG_Z )
814         {
815                 data_size = size - (offset - start_offset);
816
817
818                 data_item = proto_tree_add_item(si, hf_acn_pdu_data, tvb,
819                                                 offset, data_size, FALSE);
820
821                 data_tree=proto_item_add_subtree(data_item, ett_acn);
822
823
824                 switch( hist.protocol ) {
825                         case ACN_PDU_PROTO_SDT:
826                                 dissect_sdt( tvb, offset, data_tree, &hist, data_size);
827                                 break;
828                         
829                         case ACN_PDU_PROTO_DMP:
830                                 dissect_dmp( tvb, offset, data_tree, &hist, data_size); 
831                                 break;
832         
833                         default:
834                                 proto_tree_add_item(si, hf_acn_pdu_unknown_data, tvb,
835                                                         offset, data_size, FALSE );
836                                 break;  
837                 }
838
839                 offset += data_size;
840         }
841
842         if( size & 0x00000001 )
843         {
844         
845                 proto_tree_add_item(si, hf_acn_pdu_padding, tvb,
846                                         offset, 1, TRUE );
847                 
848                 size += 1;
849                 offset += 1;
850         }
851
852         proto_item_set_len(si, size);
853
854         return size;
855 }
856
857 static void
858 dissect_acn(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
859         gint offset = 0;
860         guint size,max_size;
861         acn_pdu_history_t hist;
862
863         /* Set the protocol column */
864         if(check_col(pinfo->cinfo,COL_PROTOCOL)){
865                 col_set_str(pinfo->cinfo,COL_PROTOCOL,"ACN");
866         }
867
868         /* Clear out stuff in the info column */
869         if(check_col(pinfo->cinfo,COL_INFO)){
870                 col_clear(pinfo->cinfo,COL_INFO);
871         }
872
873         if (tree) 
874         {
875                 /* history default values */
876                 hist.destination_type = ACN_PDU_DES_ALL; 
877                 hist.source_type = ACN_PDU_SRC_UM;
878                 hist.protocol = ACN_PDU_PROTO_UNKNOWN;
879                 hist.type = ACN_PDU_TYPE_UNKNOWN;
880                 
881                 max_size = tvb_reported_length_remaining(tvb, offset);
882                 
883                 while( max_size >= ACN_PDU_MIN_SIZE) {
884                         size = dissect_pdu( tvb, offset, tree, &hist, max_size);
885                         offset += size;
886                         max_size -= size;
887                 }
888         }
889 }
890
891 void
892 proto_register_acn(void) {
893   static hf_register_info hf[] = {
894         /* PDU */
895         { &hf_acn_pdu,
896             { "ACN PDU", "acn.pdu",
897                 FT_NONE, BASE_NONE, NULL, 0,
898                 "ACN PDU", HFILL }},
899
900         { &hf_acn_pdu_flags,
901             { "Flags","acn.pdu.flags",
902                 FT_UINT8, BASE_HEX, NULL, 0x0,
903                 "Flags", HFILL }},
904
905         { &hf_acn_pdu_des,
906             { "des","acn.pdu.des",
907                 FT_UINT8, BASE_HEX, VALS( acn_sdt_des_flag_vals ), 0xC0,
908                 "des", HFILL }},
909
910         { &hf_acn_pdu_src,
911             { "src","acn.pdu.src",
912                 FT_UINT8, BASE_HEX, VALS( acn_sdt_src_flag_vals ), 0x30,
913                 "src", HFILL }},
914
915         { &hf_acn_pdu_flag_p,
916             { "P","acn.pdu.flag_p",
917                 FT_UINT8, BASE_HEX, NULL, 0x08,
918                 "P", HFILL }},
919
920         { &hf_acn_pdu_flag_t,
921             { "T","acn.pdu.flag_t",
922                 FT_UINT8, BASE_HEX, NULL, 0x04,
923                 "T", HFILL }},
924
925         { &hf_acn_pdu_flag_z,
926             { "Z","acn.pdu.flag_z",
927                 FT_UINT8, BASE_HEX, NULL, 0x01,
928                 "Z", HFILL }},
929
930         { &hf_acn_pdu_flag_res,
931             { "res","acn.pdu.flag_res",
932                 FT_UINT8, BASE_HEX, NULL, 0x02,
933                 "res", HFILL }},
934
935         { &hf_acn_pdu_length,
936             { "Length","acn.pdu.length",
937                 FT_UINT8, BASE_DEC, NULL, 0x0,
938                 "Length", HFILL }},
939
940         { &hf_acn_pdu_ext_length_16,
941             { "Ext Length 16bit","acn.pdu.ext_length_16",
942                 FT_UINT16, BASE_DEC, NULL, 0x0,
943                 "Ext Length 16bit", HFILL }},
944
945         { &hf_acn_pdu_ext_length_32,
946             { "Ext Length 32bit","acn.pdu.ext_length_32",
947                 FT_UINT32, BASE_DEC, NULL, 0x0,
948                 "Ext Length 32bit", HFILL }},
949
950         { &hf_acn_pdu_source_ps,
951             { "Source PS","acn.pdu.source_ps",
952                 FT_UINT16, BASE_HEX, NULL, 0x0,
953                 "Source PS", HFILL }},
954
955         { &hf_acn_pdu_source_cid,
956             { "Source CID","acn.pdu.source_cid",
957                 FT_BYTES, BASE_HEX, NULL, 0x0,
958                 "Source CID", HFILL }},
959
960         { &hf_acn_pdu_destination_ps,
961             { "Destination PS","acn.pdu.destination_ps",
962                 FT_UINT16, BASE_HEX, NULL, 0x0,
963                 "Destination PS", HFILL }},
964
965         { &hf_acn_pdu_destination_cid,
966             { "Destination CID","acn.pdu.destination_cid",
967                 FT_BYTES, BASE_HEX, NULL, 0x0,
968                 "Destination CID", HFILL }},
969
970         { &hf_acn_pdu_protocol,
971             { "Protocol","acn.pdu.protocol",
972                 FT_UINT16, BASE_HEX, VALS(acn_proto_vals), 0x0,
973                 "Protocol", HFILL }},
974
975         { &hf_acn_pdu_type,
976             { "Type","acn.pdu.type",
977                 FT_UINT16, BASE_HEX, NULL, 0x0,
978                 "Type", HFILL }},
979
980         { &hf_acn_pdu_type_sdt,
981             { "SDT Type","acn.pdu.type_sdt",
982                 FT_UINT16, BASE_HEX, VALS(acn_sdt_type_vals), 0x0,
983                 "SDT Type", HFILL }},
984
985         { &hf_acn_pdu_type_dmp,
986             { "DMP Type","acn.pdu.type_dmp",
987                 FT_UINT16, BASE_HEX, VALS(acn_dmp_type_vals), 0x0,
988                 "DMP Type", HFILL }},
989                 
990         { &hf_acn_pdu_data,
991             { "Data","acn.pdu.data",
992                 FT_NONE, BASE_HEX, NULL, 0x0,
993                 "Data", HFILL }},
994
995         { &hf_acn_pdu_unknown_data,
996             { "Unknown Data","acn.pdu.unknown_data",
997                 FT_BYTES, BASE_HEX, NULL, 0x0,
998                 "Unknown Data", HFILL }},
999
1000         { &hf_acn_pdu_padding,
1001             { "Padding","acn.pdu.padding",
1002                 FT_UINT8, BASE_DEC, NULL, 0x0,
1003                 "Padding", HFILL }},
1004
1005         { &hf_acn_sdt_session_nr,
1006             { "SDT Session Nr","acn.sdt.session_nr",
1007                 FT_UINT16, BASE_DEC, NULL, 0x0,
1008                 "SDT Session Nr", HFILL }},
1009
1010         { &hf_acn_sdt_tot_seq_nr,
1011             { "SDT Total Sequence Nr","acn.sdt.tot_seq_nr",
1012                 FT_UINT32, BASE_DEC, NULL, 0x0,
1013                 "SDT Total Sequence Nr", HFILL }},
1014
1015         { &hf_acn_sdt_rel_seq_nr,
1016             { "SDT Rel Seq Nr","acn.sdt.rel_seq_nr",
1017                 FT_UINT32, BASE_DEC, NULL, 0x0,
1018                 "SDT Rel Sequence Nr", HFILL }},
1019
1020         { &hf_acn_sdt_unavailable_wrappers,
1021             { "SDT Unavailable Wrappers","acn.sdt.unavailable_wrappers",
1022                 FT_UINT32, BASE_DEC, NULL, 0x0,
1023                 "SDT Unavailable Wrappers", HFILL }},
1024                 
1025         { &hf_acn_sdt_refuse_code,
1026             { "SDT Refuse code","acn.sdt.refuse_code",
1027                 FT_UINT16, BASE_DEC, NULL, 0x0,
1028                 "SDT Refuse Code", HFILL }},
1029
1030         { &hf_acn_sdt_last_rel_seq,
1031             { "SDT Last reliable seq nr","acn.sdt.last_rel_seq",
1032                 FT_UINT32, BASE_DEC, NULL, 0x0,
1033                 "SDT Last reliable seq nr", HFILL }},
1034
1035         { &hf_acn_sdt_new_rel_seq,
1036             { "SDT reliable seq nr to continue with","acn.sdt.new_rel_seq",
1037                 FT_UINT32, BASE_DEC, NULL, 0x0,
1038                 "SDT reliable seq nr to continue with", HFILL }},
1039
1040         { &hf_acn_sdt_last_rel_wrapper,
1041             { "SDT Last reliable Wrapper","acn.sdt.last_rel_wrapper",
1042                 FT_UINT32, BASE_DEC, NULL, 0x0,
1043                 "SDT Last reliable Wrapper", HFILL }},
1044
1045         { &hf_acn_sdt_nr_lost_wrappers,
1046             { "SDT Nr of lost Wrappers","acn.sdt.nr_lost_wrappers",
1047                 FT_UINT32, BASE_DEC, NULL, 0x0,
1048                 "SDT Nr of lost  Wrappers", HFILL }},
1049
1050         { &hf_acn_sdt_session_exp_time,
1051             { "SDT Session expire time","acn.sdt.session_exp_time",
1052                 FT_UINT16, BASE_DEC, NULL, 0x0,
1053                 "SDT Session expire time", HFILL }},
1054                 
1055         { &hf_acn_sdt_flags,
1056             { "SDT Flags","acn.sdt.flags",
1057                 FT_UINT8, BASE_HEX, NULL, 0x0,
1058                 "SDT Flags", HFILL }},
1059
1060         { &hf_acn_sdt_flag_u,
1061             { "U","acn.sdt.flag_u",
1062                 FT_UINT8, BASE_HEX, NULL, 0x80,
1063                 "U", HFILL }},
1064
1065         { &hf_acn_sdt_flag_d,
1066             { "D","acn.sdt.flag_d",
1067                 FT_UINT8, BASE_HEX, NULL, 0x40,
1068                 "D", HFILL }},
1069
1070         { &hf_acn_sdt_flag_l,
1071             { "L","acn.sdt.flag_l",
1072                 FT_UINT8, BASE_HEX, NULL, 0x20,
1073                 "L", HFILL }},
1074
1075         { &hf_acn_sdt_upstream_address_type,
1076             { "SDT Upstream address type","acn.sdt.upstream_address_type",
1077                 FT_UINT8, BASE_HEX, VALS(acn_sdt_address_type_vals), 0x0,
1078                 "SDT Upstream address type", HFILL }},
1079
1080         { &hf_acn_sdt_downstream_address_type,
1081             { "SDT Downstream address type","acn.sdt.downstream_address_type",
1082                 FT_UINT8, BASE_HEX, VALS(acn_sdt_address_type_vals), 0x0,
1083                 "SDT Downstream address type", HFILL }},
1084
1085         { &hf_acn_sdt_upstream_port,
1086             { "SDT Upstream Port","acn.sdt.upstream_port",
1087                 FT_UINT16, BASE_DEC, NULL, 0x0,
1088                 "SDT Upstream Port", HFILL }},
1089
1090         { &hf_acn_sdt_downstream_port,
1091             { "SDT Donwstream Port","acn.sdt.downstream_port",
1092                 FT_UINT16, BASE_DEC, NULL, 0x0,
1093                 "SDT Downstream Port", HFILL }},
1094
1095         { &hf_acn_sdt_downstream_ipv4_address,
1096             { "SDT Donwstream IPv4 Address","acn.sdt.downstream_ipv4_address",
1097                 FT_IPv4, BASE_DEC, NULL, 0x0,
1098                 "SDT Downstream IPv4 Address", HFILL }},
1099
1100         { &hf_acn_sdt_upstream_ipv4_address,
1101             { "SDT Upstream IPv4 Address","acn.sdt.upstream_ipv4_address",
1102                 FT_IPv4, BASE_DEC, NULL, 0x0,
1103                 "SDT Upstream IPv4 Address", HFILL }},
1104
1105         { &hf_acn_sdt_downstream_ipv6_address,
1106             { "SDT Donwstream IPv6 Address","acn.sdt.downstream_ipv6_address",
1107                 FT_IPv6, BASE_DEC, NULL, 0x0,
1108                 "SDT Downstream IPv6 Address", HFILL }},
1109
1110         { &hf_acn_sdt_upstream_ipv6_address,
1111             { "SDT Upstream IPv6 Address","acn.sdt.upstream_ipv6_address",
1112                 FT_IPv6, BASE_DEC, NULL, 0x0,
1113                 "SDT Upstream IPv6 Address", HFILL }},
1114
1115         { &hf_acn_sdt_mid,
1116             { "SDT Member ID","acn.sdt.mid",
1117                 FT_UINT16, BASE_DEC, NULL, 0x0,
1118                 "SDT Member ID", HFILL }},
1119
1120         { &hf_acn_sdt_nak_holdoff_interval,
1121             { "SDT NAK holdoff interval","acn.sdt.nak_holdoff_interval",
1122                 FT_UINT16, BASE_DEC, NULL, 0x0,
1123                 "SDT NAK holdoff interval", HFILL }},
1124
1125         { &hf_acn_sdt_nak_modulus,
1126             { "SDT NAK modulus","acn.sdt.nak_modulus",
1127                 FT_UINT16, BASE_DEC, NULL, 0x0,
1128                 "SDT NAK modulus", HFILL }},
1129
1130         { &hf_acn_sdt_max_nak_wait_time,
1131             { "SDT Max. NAK wait time","acn.sdt.max_nak_wait_time",
1132                 FT_UINT16, BASE_DEC, NULL, 0x0,
1133                 "SDT Max. NAK wait time ", HFILL }},
1134
1135         { &hf_acn_sdt_ack_threshold,
1136             { "SDT ACK threshold","acn.sdt.ack_threshold",
1137                 FT_UINT16, BASE_DEC, NULL, 0x0,
1138                 "SDT ACK threshold", HFILL }},
1139
1140         { &hf_acn_sdt_member_cid,
1141             { "SDT Memebr CID","acn.sdt.member_cid",
1142                 FT_BYTES, BASE_HEX, NULL, 0x0,
1143                 "SDT Member CID", HFILL }},
1144
1145         { &hf_acn_sdt_leader_cid,
1146             { "SDT Leader CID","acn.sdt.leader_cid",
1147                 FT_BYTES, BASE_HEX, NULL, 0x0,
1148                 "SDT Leader CID", HFILL }}
1149
1150   };
1151
1152   static gint *ett[] = {
1153     &ett_acn,
1154   };
1155
1156   module_t *acn_module;
1157
1158   proto_acn = proto_register_protocol("ACN",
1159                                       "ACN","acn");
1160   proto_register_field_array(proto_acn,hf,array_length(hf));
1161   proto_register_subtree_array(ett,array_length(ett));
1162
1163   acn_module = prefs_register_protocol(proto_acn,
1164                                        proto_reg_handoff_acn);
1165 #if 0
1166   prefs_register_uint_preference(artnet_module, "udp_port",
1167                                  "ARTNET UDP Port",
1168                                  "The UDP port on which "
1169                                  "Art-Net "
1170                                  "packets will be sent",
1171                                  10,&global_udp_port_artnet);
1172 #endif
1173 }
1174
1175 /* The registration hand-off routing */
1176
1177 void
1178 proto_reg_handoff_acn(void) {
1179   static int acn_initialized = FALSE;
1180   static dissector_handle_t acn_handle;
1181
1182   ip_handle = find_dissector("ip");
1183
1184   if(!acn_initialized) {
1185     acn_handle = create_dissector_handle(dissect_acn,proto_acn);
1186     acn_initialized = TRUE;
1187   } else {
1188     dissector_delete("udp.port",udp_port_acn,acn_handle);
1189   }
1190
1191   udp_port_acn = global_udp_port_acn;
1192   
1193   dissector_add("udp.port",global_udp_port_acn,acn_handle);
1194 }
1195
1196 /* Start the functions we need for the plugin stuff */
1197
1198 #ifndef ENABLE_STATIC
1199
1200 G_MODULE_EXPORT void
1201 plugin_reg_handoff(void){
1202   proto_reg_handoff_acn();
1203 }
1204
1205 G_MODULE_EXPORT void
1206 new_plugin_init(void)
1207 {
1208   /* register the new protocol, protocol fields, and subtrees */
1209   if (proto_acn == -1) { /* execute protocol initialization only once */
1210     proto_register_acn();
1211   }
1212 }
1213
1214 #endif
1215
1216 /* End the functions we need for plugin stuff */
1217