2 * Routines for UA (Universal Alcatel) packet dissection.
3 * Copyright 2011, Marek Tews <marek@trx.com.pl>
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * Copied from WHATEVER_FILE_YOU_USED (where "WHATEVER_FILE_YOU_USED"
12 * is a dissector file; if you just copied this from README.developer,
13 * don't bother with the "Copied from" - you don't even need to put
14 * in a "Copied from" if you copied an existing dissector, especially
15 * if the bulk of the code in the new dissector is your code)
17 * This program is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU General Public License
19 * as published by the Free Software Foundation; either version 2
20 * of the License, or (at your option) any later version.
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
27 * You should have received a copy of the GNU General Public License
28 * along with this program; if not, write to the Free Software
29 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
36 #ifdef HAVE_SYS_TYPES_H
37 # include <sys/types.h>
40 #ifdef HAVE_NETINET_IN_H
41 #include <netinet/in.h>
44 #include <epan/packet.h>
46 static void DissectNOE(tvbuff_t *pTvb, proto_tree *pRootUA);
47 static void DissectNOE_type(tvbuff_t *pTvb, proto_tree *pNoeItem);
48 static void DissectNOE_voicemode(tvbuff_t *pTvb, proto_tree *pNoeItem);
49 static void DissectNOE_callserver(tvbuff_t *pTvb, proto_tree *pNoeItem);
50 static void DissectNOE_ip(tvbuff_t *pTvb, proto_tree *pNoeItem);
51 static void DissectNOE_ip_startrtp(tvbuff_t *pTvb, proto_tree *pNoeItem);
52 static void DissectNOE_ip_startrtp_properties(tvbuff_t *pTvb, proto_tree *pNoeItem);
54 static void DissectTLV(tvbuff_t *pTvb, proto_tree *pNoeItem, gboolean bIsArrIndex);
55 static void DissectTLV_data(tvbuff_t *pTvb, proto_tree *pTlv, guint8 u8Property);
58 * Here are the global variables associated with
59 * the various user definable characteristics of the dissection
62 /* Define the UA proto */
63 static int proto_ua = -1;
65 /* Define many header fields for UA (Universal Alcatel Protocol) */
66 static int hf_noe = -1;
67 static int hf_noe_length = -1;
68 static int hf_noe_type = -1;
69 static int hf_noe_method = -1;
70 static int hf_noe_class = -1;
71 static int hf_noe_objid = -1;
72 static int hf_noe_event = -1;
73 static int hf_noe_keychar = -1;
74 static int hf_noe_action = -1;
75 static int hf_noe_reserved = -1;
76 static int hf_noe_property = -1;
77 static int hf_noe_id = -1;
78 static int hf_noe_size = -1;
79 static int hf_noe_local_port = -1;
80 static int hf_noe_remote_ip = -1;
81 static int hf_noe_remote_port = -1;
82 static int hf_noe_data = -1;
83 static int hf_noe_compressor = -1;
84 static int hf_noe_typeofservice = -1;
85 static int hf_noe_payloadconcat = -1;
86 static int hf_noe_voicemode = -1;
88 static int hf_tlv = -1;
89 static int hf_tlv_property = -1;
90 static int hf_tlv_arrindex = -1;
91 static int hf_tlv_propsize = -1;
92 static int hf_tlv_label = -1;
93 static int hf_tlv_data = -1;
94 static int hf_tlv_year = -1;
95 static int hf_tlv_number = -1;
97 /* Define the trees for UA (Universal Alcatel Protocol) */
98 static int ett_ua = -1;
100 static int ett_noe = -1;
101 static int ett_noe_property = -1;
103 static int ett_tlv = -1;
104 static int ett_tlv_sub = -1;
107 /************************************************************
109 ************************************************************/
114 static const value_string szNoeType[] =
117 { 0x01, "HandsetOffHook" },
118 { 0x02, "HandsetOnHook" },
119 { 0x03, "DigitDialed" },
121 { 0x15, "CallServer" },
122 { 0x20, "KeyPushed" },
124 { 0x27, "WriteLine1" },
125 { 0x28, "WriteLine2" },
126 { 0x29, "VoiceMode" },
127 { 0x31, "SetClockComd" },
128 { 0x35, "CursorBlink" },
129 { 0x38, "ClockTimerPosition" },
130 { 0x3a, "Error_0x3a" },
131 { 0x3d, "SideTone" },
133 { 0x46, "AllIconsOff" },
134 { 0x47, "IconsCmd" },
135 { 0x48, "AmplifiedHandset" },
136 { 0x49, "DPIConfiguration" },
137 { 0x4a, "AudioPaddedPath" },
138 { 0x4f, "Error_0x4f" },
142 static const value_string szCallServerMethod[] =
146 { 0x02, "SetProperty" },
151 static const value_string szCallServerClass[] =
163 { 133, "ActionBox" },
167 { 145, "TelephonicBox" },
168 { 146, "KeyboardContext" },
169 { 151, "TelephonicBoxItem" },
170 { 158, "HeaderBox" },
174 static const value_string szCallServerEvent[] =
177 { 4, "KeyShortPress" },
181 { 133, "ActionBox" },
182 { 152, "DialogBoxDismissed" },
186 static const value_string szStartRtpPropID[] =
188 { 0x00, "LocalUDPPort" },
189 { 0x01, "RemoteIP" },
190 { 0x02, "RemoteUDPPort" },
191 { 0x03, "TypeOfService" },
193 { 0x05, "PayloadConcatenation" }, /* in ms */
194 { 0x06, "EchoCancelationEnabler" },
195 { 0x07, "SilenceCompression" },
196 { 0x08, "_802_1QUserPriority" },
197 { 0x0A, "PostFiltering" },
198 { 0x0B, "HighPassFilter" },
202 static const value_string szStartRtpPayload[] =
204 { 0, "G.711 A-law" },
205 { 1, "G.711 mu-law" },
206 { 2, "G.723.1 5.3 kbps" },
207 { 3, "G.723.1 6.3 kbps" },
208 { 0x11, "G.729A 8kbps"},
212 static const value_string szNoeAction[] =
214 { 0x01, "Start RTP" },
215 { 0x02, "Stop RTP" },
219 static const value_string szNoeVoiceMode[] =
230 static const value_string szTlvProperty[] =
233 { 11, "NavigatorOwnerShip" },
234 { 15, "NumpadEvent" },
258 { 131, "Key Ownership" },
262 { 138, "Label_138" },
263 { 141, "State_141" },
271 /************************************************************
272 * Check whether it can be protocol data
273 ************************************************************/
274 gboolean is_ua(tvbuff_t *tvb)
279 nLen = tvb_length(tvb);
280 for(iOffs = 0; iOffs < nLen; )
282 nNoeLen = tvb_get_letohs(tvb, iOffs) +2;
283 if(nNoeLen > nLen -iOffs)
290 /************************************************************
292 ************************************************************/
295 * DissectUA - The dissector for UA (Universal Alcatel Protocol)
297 static int DissectUA(tvbuff_t *pTvb, packet_info *pInfo, proto_tree *pTree)
302 proto_tree *pSubTreeUA;
305 /* Check whether it can be protocol data */
310 col_append_str(pInfo->cinfo, COL_INFO, " - UA");
312 nLen = tvb_length(pTvb);
315 /* root element "UA Protocol, ..." */
316 pRootUA = proto_tree_add_item(pTree, proto_ua, pTvb, 0, -1, ENC_NA);
317 pSubTreeUA = proto_item_add_subtree(pRootUA, ett_ua);
320 for(iOffs = 0; iOffs < nLen; )
322 nNoeLen = tvb_get_letohs(pTvb, iOffs);
325 pTvbNoe = tvb_new_subset(pTvb, iOffs, nNoeLen, nNoeLen);
326 DissectNOE(pTvbNoe, pSubTreeUA);
336 /**********************************************
338 ***********************************************
346 NoeCallServerSetProperty
348 NoeCallServerNotifyKeyPress
349 NoeCallServerNotifyKeyShortPress
350 ***********************************************/
351 static void DissectNOE(tvbuff_t *pTvb, proto_tree *pRootUA)
353 proto_item *pNoeItem = proto_tree_add_item(pRootUA, hf_noe, pTvb, 0, -1, ENC_NA);
356 proto_tree* pSubTreeNOE;
358 pSubTreeNOE = proto_item_add_subtree(pNoeItem, ett_noe);
359 proto_tree_add_item(pSubTreeNOE, hf_noe_length, pTvb, 0, 2, ENC_LITTLE_ENDIAN);
360 DissectNOE_type(tvb_new_subset_remaining(pTvb, 2), pSubTreeNOE);
364 static void DissectNOE_type(tvbuff_t *pTvb, proto_tree *pNoeItem)
366 proto_item_append_text(pNoeItem, ": %s", val_to_str_const(tvb_get_guint8(pTvb, 0), szNoeType, "Unknown"));
367 proto_tree_add_item(pNoeItem, hf_noe_type, pTvb, 0, 1, ENC_NA);
369 switch(tvb_get_guint8(pTvb, 0))
373 DissectNOE_ip(tvb_new_subset_remaining(pTvb, 1), pNoeItem);
376 case 0x15: /*CallServer*/
378 DissectNOE_callserver(tvb_new_subset_remaining(pTvb, 1), pNoeItem);
381 case 0x29: /*VoiceMode*/
383 DissectNOE_voicemode(tvb_new_subset_remaining(pTvb, 1), pNoeItem);
389 static void DissectNOE_voicemode(tvbuff_t *pTvb, proto_tree *pNoeItem)
391 proto_tree_add_item(pNoeItem, hf_noe_voicemode, pTvb, 0, 1, ENC_NA);
392 if(tvb_length(pTvb) > 1)
393 proto_tree_add_item(pNoeItem, hf_noe_data, pTvb, 1, -1, ENC_NA);
396 static void DissectNOE_callserver(tvbuff_t *pTvb, proto_tree *pNoeItem)
403 nLen = tvb_length(pTvb);
404 u8Method = tvb_get_guint8(pTvb, 0);
406 proto_item_append_text(pNoeItem, ", %s", val_to_str(u8Method, szCallServerMethod, "Unknown"));
407 proto_tree_add_item(pNoeItem, hf_noe_method, pTvb, 0, 1, ENC_NA);
411 case 0x00: /*Create*/
412 case 0x01: /*Delete*/
413 case 0x02: /*SetProperty*/
415 guint8 u8Class; gint iOffs;
417 u8Class = tvb_get_guint8(pTvb, 1);
418 proto_item_append_text(pNoeItem, ", %s", val_to_str(u8Class, szCallServerClass, "Unknown"));
419 proto_tree_add_item(pNoeItem, hf_noe_class, pTvb, 1, 1, ENC_NA);
424 proto_item_append_text(pNoeItem, ", Id(0x%04x)", tvb_get_ntohs(pTvb, 2));
425 proto_tree_add_item(pNoeItem, hf_noe_objid, pTvb, 2, 2, ENC_LITTLE_ENDIAN);
430 for(; iOffs < nLen; )
434 gboolean bIsArrIndex;
436 nTlvProperty = tvb_get_guint8(pTvb, iOffs);
437 /* for property of more than 100 and equal 120 before the field is still arrindex propsize */
438 if((nTlvProperty < 100) || (nTlvProperty == 120))
440 nTlvLen = tvb_get_guint8(pTvb, iOffs+1);
446 nTlvLen = tvb_get_guint8(pTvb, iOffs+2);
450 pTvbTlv = tvb_new_subset(pTvb, iOffs, nTlvLen, nTlvLen);
451 DissectTLV(pTvbTlv, pNoeItem, bIsArrIndex);
457 case 0x04: /*Notify*/
461 u8Event = tvb_get_guint8(pTvb, 1);
462 proto_tree_add_item(pNoeItem, hf_noe_event, pTvb, 1, 1, ENC_NA);
468 proto_tree_add_item(pNoeItem, hf_noe_keychar, pTvb, 2, -1, ENC_NA);
471 case 4: /*KeyShortPress*/
473 proto_tree_add_item(pNoeItem, hf_noe_keychar, pTvb, 2, 2, ENC_NA);
482 static void DissectNOE_ip(tvbuff_t *pTvb, proto_tree *pNoeItem)
487 u8Action = tvb_get_guint8(pTvb, 0);
488 proto_item_append_text(pNoeItem, " %s", val_to_str(u8Action, szNoeAction, "Unknown"));
489 proto_tree_add_item(pNoeItem, hf_noe_action, pTvb, 0, 1, ENC_NA);
493 case 0x01: /*Start RTP*/
495 DissectNOE_ip_startrtp(tvb_new_subset_remaining(pTvb, 1), pNoeItem);
498 case 0x02: /*Stop RTP*/
505 static void DissectNOE_ip_startrtp(tvbuff_t *pTvb, proto_tree *pNoeItem)
508 nLen = tvb_length(pTvb);
511 proto_tree_add_item(pNoeItem, hf_noe_reserved, pTvb, 0, 1, ENC_NA);
514 for(iOffs = 1; iOffs < nLen; )
519 u8PropSize = tvb_get_guint8(pTvb, iOffs+1) + 2;
520 pTvbTlv = tvb_new_subset(pTvb, iOffs, u8PropSize, u8PropSize);
522 DissectNOE_ip_startrtp_properties(pTvbTlv, pNoeItem);
527 static void DissectNOE_ip_startrtp_properties(tvbuff_t *pTvb, proto_tree *pNoeItem)
531 pProp = proto_tree_add_item(pNoeItem, hf_noe_property, pTvb, 0, -1, ENC_NA);
535 proto_tree* pSubTreeProp;
537 pSubTreeProp = proto_item_add_subtree(pProp, ett_noe_property);
539 u8ID = tvb_get_guint8(pTvb, 0);
540 proto_item_append_text(pProp, " - %25s", val_to_str(u8ID, szStartRtpPropID, "Unknown"));
541 proto_tree_add_item(pSubTreeProp, hf_noe_id, pTvb, 0, 1, ENC_NA);
544 u8Size = tvb_get_guint8(pTvb, 1);
545 proto_tree_add_item(pSubTreeProp, hf_noe_size, pTvb, 1, 1, ENC_NA);
552 proto_item_append_text(pProp, ": %s", tvb_bytes_to_str(pTvb, 2, u8Size));
553 proto_tree_add_item(pSubTreeProp, hf_noe_data, pTvb, 2, -1, ENC_NA);
556 case 0x00: /*LocalUDPPort*/
558 proto_item_append_text(pProp, ": %u", tvb_get_ntohs(pTvb, 2));
559 proto_tree_add_item(pSubTreeProp, hf_noe_local_port, pTvb, 2, -1, ENC_LITTLE_ENDIAN);
562 case 0x01: /*RemoteIP*/
564 proto_item_append_text(pProp, ": %s", tvb_ip_to_str(pTvb, 2));
565 proto_tree_add_item(pSubTreeProp, hf_noe_remote_ip, pTvb, 2, -1, ENC_NA);
568 case 0x02: /*RemoteUDPPort*/
570 proto_item_append_text(pProp, ": %u", tvb_get_ntohs(pTvb, 2));
571 proto_tree_add_item(pSubTreeProp, hf_noe_remote_port, pTvb, 2, -1, ENC_LITTLE_ENDIAN);
574 case 0x03: /*TypeOfService*/
576 proto_item_append_text(pProp, ": %u", tvb_get_guint8(pTvb, 2));
577 proto_tree_add_item(pSubTreeProp, hf_noe_typeofservice, pTvb, 2, -1, ENC_NA);
580 case 0x04: /*Payload*/
582 proto_item_append_text(pProp, ": %s", val_to_str_const(tvb_get_guint8(pTvb, 2), szStartRtpPayload, "Unknown"));
583 proto_tree_add_item(pSubTreeProp, hf_noe_compressor, pTvb, 2, -1, ENC_NA);
586 case 0x05: /*PayloadConcatenation*/
588 proto_item_append_text(pProp, ": %u ms", tvb_get_guint8(pTvb, 2));
589 proto_tree_add_item(pSubTreeProp, hf_noe_payloadconcat, pTvb, 2, -1, ENC_NA);
596 /***********************************************
598 ***********************************************/
599 static void DissectTLV(tvbuff_t *pTvb, proto_tree *pNoeItem, gboolean bIsArrIndex)
603 pTlv = proto_tree_add_item(pNoeItem, hf_tlv, pTvb, 0, -1, ENC_NA);
607 guint8 u8Property, u8PropSize;
608 proto_tree* pSubTreeTLV;
611 pSubTreeTLV = proto_item_add_subtree(pTlv, ett_tlv);
612 u8Property = tvb_get_guint8(pTvb, iOffs);
613 proto_item_append_text(pTlv, "%u %s ", u8Property, val_to_str(u8Property, szTlvProperty, "Unknown"));
614 proto_tree_add_item(pSubTreeTLV, hf_tlv_property, pTvb, iOffs++, 1, ENC_NA);
617 proto_tree_add_item(pTlv, hf_tlv_arrindex, pTvb, iOffs++, 1, ENC_NA);
619 u8PropSize = tvb_get_guint8(pTvb, iOffs);
620 proto_tree_add_item(pSubTreeTLV, hf_tlv_propsize, pTvb, iOffs++, 1, ENC_NA);
623 DissectTLV_data(tvb_new_subset(pTvb, iOffs, u8PropSize, u8PropSize), pSubTreeTLV, u8Property);
628 static void DissectTLV_data(tvbuff_t *pTvb, proto_tree *pTlv, guint8 u8Property)
630 proto_tree* pNoeItem;
635 proto_item_append_text(pTlv, "%s", tvb_bytes_to_str(pTvb, 0, tvb_length(pTvb)));
636 proto_tree_add_item(pTlv, hf_tlv_data, pTvb, 0, -1, ENC_NA);
642 proto_item_append_text(pTlv, "%u", tvb_get_ntohs(pTvb, 0));
643 proto_tree_add_item(pTlv, hf_tlv_year, pTvb, 0, 2, ENC_BIG_ENDIAN);
648 case 138: /*Label_138*/
650 proto_item_append_text(pTlv, "'%s'", tvb_get_string(pTvb, 0, tvb_length(pTvb)));
651 proto_tree_add_item(pTlv, hf_tlv_label, pTvb, 0, -1, ENC_ASCII|ENC_NA);
653 /* append text on NOE level */
654 pNoeItem = proto_item_get_parent(pTlv);
655 proto_item_append_text(pNoeItem, ", Label='%s'", tvb_get_string(pTvb, 0, tvb_length(pTvb)));
659 case 143: /*Phone number*/
661 proto_item_append_text(pTlv, "%s", tvb_get_string(pTvb, 0, tvb_length(pTvb)));
662 proto_tree_add_item(pTlv, hf_tlv_number, pTvb, 0, -1, ENC_NA);
667 case 148: /*Tomorrow*/
669 proto_item_append_text(pTlv, "'%s'", tvb_get_string(pTvb, 0, tvb_length(pTvb)));
670 proto_tree_add_item(pTlv, hf_tlv_data, pTvb, 0, -1, ENC_NA);
678 /* Register all the bits needed by the filtering engine */
679 void proto_register_ua(void)
681 static hf_register_info hf[] =
685 FT_NONE, BASE_NONE, NULL, 0x0,
688 { "Length", "ua.noe.length",
689 FT_UINT16, BASE_DEC, NULL, 0x0,
690 "NOE item length (without 2 bytes containing the length)", HFILL }},
692 { "Type", "ua.noe.type",
693 FT_UINT8, BASE_DEC, VALS(szNoeType), 0x0,
694 "NOE item type", HFILL }},
696 { "Method", "ua.noe.method",
697 FT_UINT8, BASE_DEC, VALS(szCallServerMethod), 0x0,
698 "Call Server method", HFILL }},
700 { "Class", "ua.noe.class",
701 FT_UINT8, BASE_DEC, VALS(szCallServerClass), 0x0,
702 "Call Server class", HFILL }},
704 { "ObjectID", "ua.noe.objid",
705 FT_UINT16, BASE_HEX_DEC, NULL, 0x0,
706 "Call Server object id", HFILL }},
708 { "Event", "ua.noe.event",
709 FT_UINT8, BASE_DEC, VALS(szCallServerEvent), 0x0,
710 "Call Server event", HFILL }},
712 { "KeyChar", "ua.noe.event.keychar",
713 FT_BYTES, BASE_NONE, NULL, 0x0,
714 "Event key char", HFILL }},
716 { "VoiceMode", "ua.noe.voicemode",
717 FT_UINT8, BASE_DEC, VALS(szNoeVoiceMode), 0x0,
721 { "Action", "ua.noe.action",
722 FT_UINT8, BASE_DEC, VALS(szNoeAction), 0x0,
723 "IP action", HFILL }},
725 { "Reserved", "ua.noe.action.startrtp.reserved",
726 FT_UINT8, BASE_DEC, NULL, 0x0,
727 "IP start rtp reserved", HFILL }},
729 { "Property", "ua.noe.action.startrtp.property",
730 FT_NONE, BASE_NONE, NULL, 0x0,
731 "IP property", HFILL }},
733 { "ID", "ua.noe.action.startrtp.property.id",
734 FT_UINT8, BASE_DEC, VALS(szStartRtpPropID), 0x0,
735 "IP property id", HFILL }},
737 { "Size", "ua.noe.action.startrtp.property.size",
738 FT_UINT8, BASE_DEC, NULL, 0x0,
739 "IP property size", HFILL }},
741 { "Data", "ua.noe.action.startrtp.data",
742 FT_BYTES, BASE_NONE, NULL, 0x0,
745 { &hf_noe_local_port,
746 { "LocalPort", "ua.noe.action.startrtp.localport",
747 FT_UINT16, BASE_DEC, NULL, 0x0,
748 "IP start rtp property localport", HFILL }},
750 { "RemoteIP", "ua.noe.action.startrtp.remoteip",
751 FT_IPv4, BASE_NONE, NULL, 0x0,
752 "IP start rtp property remote ipv4", HFILL }},
753 { &hf_noe_remote_port,
754 { "RemotePort", "ua.noe.action.startrtp.remoteport",
755 FT_UINT16, BASE_DEC, NULL, 0x0,
756 "IP start rtp property remoteport", HFILL }},
757 { &hf_noe_compressor,
758 { "Payload", "ua.noe.action.startrtp.payload",
759 FT_UINT8, BASE_DEC, VALS(szStartRtpPayload), 0x0,
760 "IP start rtp property payload", HFILL }},
761 { &hf_noe_typeofservice,
762 { "TypeOfService", "ua.noe.action.startrtp.typeofservice",
763 FT_UINT8, BASE_DEC, NULL, 0x0,
764 "IP start rtp property type of service", HFILL }},
765 { &hf_noe_payloadconcat,
766 { "Payld Concat", "ua.noe.action.startrtp.payldconcat",
767 FT_UINT8, BASE_DEC, NULL, 0x0,
768 "IP start rtp property payload concatenation (in ms)", HFILL }},
771 { "TLV", "ua.noe.tlv",
772 FT_NONE, BASE_NONE, NULL, 0x0,
775 { "Property", "ua.noe.tlv.property",
776 FT_UINT8, BASE_DEC, VALS(szTlvProperty), 0x0,
777 "TLV property", HFILL }},
779 { "ArrIndex", "ua.noe.tlv.arrindex",
780 FT_UINT8, BASE_DEC, NULL, 0x0,
781 "TLV array index", HFILL }},
783 { "PropSize", "ua.noe.tlv.propsize",
784 FT_UINT8, BASE_DEC, NULL, 0x0,
785 "TLV property size", HFILL }},
787 { "Data", "ua.noe.tlv.data",
788 FT_BYTES, BASE_NONE, NULL, 0x0,
789 "TLV data", HFILL }},
791 { "Label", "ua.noe.tlv.label",
792 FT_STRING, BASE_NONE, NULL, 0x0,
793 "TLV label", HFILL }},
795 { "Year", "ua.noe.tlv.year",
796 FT_UINT16, BASE_DEC, NULL, 0x0,
797 "TLV year", HFILL }},
799 { "Number", "ua.noe.tlv.number",
800 FT_STRING, BASE_NONE, NULL, 0x0,
801 "TLV remote phone number", HFILL }},
812 proto_ua = proto_register_protocol("UA Protocol (Universal Alcatel Protocol)", "UA", "ua");
813 proto_register_field_array(proto_ua, hf, array_length(hf));
814 proto_register_subtree_array(ett, array_length(ett));
818 /* The registration hand-off routine is called at startup */
819 void proto_reg_handoff_ua(void)
821 dissector_handle_t hDis = new_create_dissector_handle(DissectUA, proto_ua);
822 dissector_add_uint("uaudp.opcode", 7, hDis);
825 * Editor modelines - http://www.wireshark.org/tools/modelines.html
830 * indent-tabs-mode: nil
833 * ex: set shiftwidth=4 tabstop=8 expandtab:
834 * :indentSize=4:tabSize=8:noTabs=true: