Do one or more of the following:
[metze/wireshark/wip.git] / epan / dissectors / packet-sasp.c
1 /* packet-sasp.c
2  * Routines for sasp packet dissection
3  * Copyright 2010, Venkateshwaran Dorai<venkateshwaran.d@gmail.com>
4  *
5  * $Id$
6  *
7  * Wireshark - Network traffic analyzer
8  * By Gerald Combs <gerald@wireshark.org>
9  * Copyright 1998 Gerald Combs
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License along
22  * with this program; if not, write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24  */
25
26
27 #include "config.h"
28 #include <glib.h>
29 #include <epan/wmem/wmem.h>
30 #include <epan/packet.h>
31 #include <epan/expert.h>
32 #include "packet-tcp.h"
33 #include <epan/prefs.h>
34
35 /* forward reference */
36 void proto_register_sasp(void);
37 void proto_reg_handoff_sasp(void);
38
39 static void dissect_reg_req(tvbuff_t *tvb, proto_tree *tree, guint32 offset);
40 static void dissect_dereg_req(tvbuff_t *tvb, proto_tree *tree, guint32 offset);
41 static void dissect_reg_rep(tvbuff_t *tvb, proto_tree *tree, guint32 offset);
42 static void dissect_dereg_rep(tvbuff_t *tvb, proto_tree *tree, guint32 offset);
43 static void dissect_sendwt(tvbuff_t *tvb, proto_tree *tree, guint32 offset);
44 static void dissect_setmemstate_req(tvbuff_t *tvb, proto_tree *tree, guint32 offset);
45 static void dissect_setmemstate_rep(tvbuff_t *tvb, proto_tree *tree, guint32 offset);
46 static void dissect_setlbstate_req(tvbuff_t *tvb, proto_tree *tree, guint32 offset);
47 static void dissect_setlbstate_rep(tvbuff_t *tvb, proto_tree *tree, guint32 offset);
48 static void dissect_wt_req(tvbuff_t *tvb, proto_tree *tree, guint32 offset);
49 static void dissect_wt_rep(tvbuff_t *tvb, proto_tree *tree, guint32 offset);
50 static guint32 dissect_memdatacomp(tvbuff_t *tvb, proto_tree *tree, guint32 offset, proto_tree **mdct_p);
51 static guint32 dissect_grpdatacomp(tvbuff_t *tvb, proto_tree *tree, guint32 offset);
52 static guint32 dissect_grp_memdatacomp(tvbuff_t *tvb, proto_tree *tree, guint32 offset);
53 static guint32 dissect_grp_memstatedatacomp(tvbuff_t *tvb, proto_tree *tree, guint32 offset);
54 static guint32 dissect_memstatedatacomp(tvbuff_t *tvb, proto_tree *tree, guint32 offset);
55 static guint32 dissect_weight_entry_data_comp(tvbuff_t *tvb, proto_tree *pay_load, guint32 offset);
56 static guint32 dissect_grp_wt_entry_datacomp(tvbuff_t *tvb, proto_tree *tree, guint32 offset);
57
58 /* Initialize the protocol and registered fields */
59 static int proto_sasp = -1;
60 static int hf_sasp_type = -1;
61 static int hf_sasp_length = -1;
62 static int hf_sasp_vrsn = -1;
63 static int hf_msg_len = -1;
64 static int hf_msg_id = -1;
65 static int hf_msg_type = -1;
66
67 /*reg reply*/
68 static int hf_sasp_reg_rep_rcode = -1;
69 static int hf_sasp_reg_rep_sz = -1;
70
71 /*reg req*/
72 static int hf_sasp_reg_req_sz = -1;
73 static int hf_reg_req_lbflag = -1;
74 static int hf_sasp_gmd_cnt = -1;
75
76 /*dereg req*/
77 static int hf_sasp_dereg_req_sz = -1;
78 static int hf_dereg_req_lbflag = -1;
79 /* static int hf_dereg_req_reason = -1; */
80 static int hf_dereg_req_reason_flag = -1;
81
82 /*dereg reply*/
83 static int hf_sasp_dereg_rep_rcode = -1;
84 static int hf_sasp_dereg_rep_sz = -1;
85
86 /*send wt*/
87 static int hf_sasp_sendwt_gwedcnt = -1;
88 static int hf_sasp_sendwt_sz = -1;
89
90 /*setmemstate req*/
91 static int hf_sasp_setmemstate_req_sz = -1;
92 static int hf_setmemstate_req_lbflag = -1;
93 /*static int hf_sasp_setmemstate_req_data = -1;*/
94 static int hf_sasp_setmemstate_req_gmsd_cnt = -1;
95
96 /*setmemstate reply*/
97 /* static int hf_sasp_setmemstate_rep = -1; */
98 static int hf_sasp_setmemstate_rep_rcode = -1;
99 static int hf_sasp_setmemstate_rep_sz = -1;
100
101 /*mem data comp */
102 static int hf_sasp_memdatacomp_type = -1;
103 static int hf_sasp_memdatacomp_sz = -1;
104 static int hf_sasp_memdatacomp_protocol = -1;
105 static int hf_sasp_memdatacomp_port = -1;
106 static int hf_sasp_memdatacomp_ip = -1;
107 static int hf_sasp_memdatacomp_lab_len = -1;
108 static int hf_sasp_memdatacomp_label = -1;
109
110 /*grp data comp */
111 static int hf_sasp_grpdatacomp = -1;
112 static int hf_sasp_grpdatacomp_sz = -1;
113 static int hf_sasp_grpdatacomp_LB_uid_len = -1;
114 static int hf_sasp_grpdatacomp_LB_uid = -1;
115 static int hf_sasp_grpdatacomp_grp_name_len = -1;
116 static int hf_sasp_grpdatacomp_grp_name = -1;
117
118 /*grp mem data comp */
119 static int hf_sasp_grp_memdatacomp = -1;
120 static int hf_sasp_grp_memdatacomp_sz = -1;
121 static int hf_sasp_grp_memdatacomp_cnt = -1;
122
123 /*weight req*/
124 static int hf_sasp_wt_req_sz = -1;
125 static int hf_sasp_wt_req_gd_cnt = -1;
126
127 /*weight rep*/
128 static int hf_sasp_wt_rep_sz = -1;
129 static int hf_sasp_wt_rep_rcode = -1;
130 static int hf_sasp_wt_rep_interval = -1;
131 static int hf_sasp_wt_rep_gwed_cnt = -1;
132
133 /*setlbstate req*/
134 static int hf_sasp_setlbstate_req_sz  = -1;
135 static int hf_sasp_setlbstate_req_LB_uid_len  = -1;
136 static int hf_sasp_setlbstate_req_LB_uid  = -1;
137 static int hf_sasp_setlbstate_req_LB_health  = -1;
138 /*static int hf_sasp_setlbstate_req_LB_flag = -1;*/
139 /* static int hf_lbstate_flag = -1; */
140 static int hf_sasp_pushflag = -1;
141 static int hf_sasp_trustflag = -1;
142 static int hf_sasp_nochangeflag = -1;
143
144 /*setlbstate reply*/
145 /* static int hf_sasp_setlbstate_rep = -1; */
146 static int hf_sasp_setlbstate_rep_rcode = -1;
147 static int hf_sasp_setlbstate_rep_sz = -1;
148
149 /*grp mem state data*/
150 static int hf_sasp_grp_memstatedatacomp = -1;
151 static int hf_sasp_grp_memstatedatacomp_sz = -1;
152 static int hf_sasp_grp_memstatedatacomp_cnt = -1;
153
154 /*mem state data comp*/
155 static int hf_sasp_memstatedatacomp_instance = -1;
156 static int hf_sasp_memstatedatacomp_sz = -1;
157 static int hf_sasp_memstatedatacomp_state = -1;
158 static int hf_sasp_memstatedatacomp_quiesce_flag = -1;
159
160 /*wt entry dat  comp*/
161 static int hf_sasp_weight_entry_data_comp_type = -1;
162 static int hf_sasp_weight_entry_data_comp_sz = -1;
163 static int hf_sasp_weight_entry_data_comp_state = -1;
164 /* static int hf_wtstate_flag = -1; */
165 static int hf_sasp_wed_contactsuccess_flag = -1;
166 static int hf_sasp_wed_quiesce_flag = -1;
167 static int hf_sasp_wed_registration_flag = -1;
168 static int hf_sasp_wed_confident_flag = -1;
169 static int hf_sasp_weight_entry_data_comp_weight = -1;
170
171 /*grp wt entry data comp */
172 static int hf_sasp_grp_wt_entry_datacomp_type = -1;
173 static int hf_sasp_grp_wt_entry_datacomp_sz = -1;
174 static int hf_sasp_grp_wt_entry_datacomp_cnt = -1;
175
176 /* Initialize the subtree pointers */
177 static gint ett_sasp_data = -1;
178 static gint ett_sasp_header = -1;
179 static gint ett_sasp_msg = -1;
180 static gint ett_sasp_payload = -1;
181 static gint ett_sasp_reg_req = -1;
182 static gint ett_sasp_reg_rep = -1;
183 static gint ett_sasp_reg_req_sz = -1;
184 static gint ett_sasp_dereg_req_sz= -1;
185 static gint ett_sasp_dereg_rep = -1;
186 static gint ett_sasp_sendwt = -1;
187 static gint ett_sasp_setmemstate_rep = -1;
188 static gint ett_sasp_memdatacomp = -1;
189 static gint ett_sasp_grpdatacomp = -1;
190 static gint ett_sasp_grp_memdatacomp = -1;
191 static gint ett_sasp_setlbstate_req = -1;
192 static gint ett_sasp_setlbstate_rep = -1;
193 static gint ett_sasp_getwt= -1;
194 static gint ett_sasp_setmemstate_req = -1;
195 static gint ett_setlbstate_req_lbflag = -1;
196 static gint ett_sasp_grp_memstatedatacomp = -1;
197 static gint ett_sasp_memstatedatacomp = -1;
198 /*static gint ett_dereg_req_reason_flag = -1;*/
199 static gint ett_sasp_grp_wt_entry_datacomp = -1;
200 static gint ett_sasp_weight_entry_data_comp = -1;
201 static gint ett_wt_entry_data_flag = -1;
202 static gint ett_sasp_wt_rep = -1;
203
204 static expert_field ei_msg_type_invalid = EI_INIT;
205
206 /* desegmentation of SASP over TCP */
207 static gboolean sasp_desegment = TRUE;
208
209 static const value_string msg_table[] = {
210     { 0x1010, "Registration Request" },
211     { 0x1015, "Registration Reply"},
212     { 0x1020, "DeRegistration Request"},
213     { 0x1025, "DeRegistration Reply"},
214     { 0x1030, "Get Weights Request"},
215     { 0x1035, "Get Weights Reply" },
216     { 0x1040, "Send Weights"},
217     { 0x1050, "Set LB State Request"},
218     { 0x1055, "Set LB State Reply"},
219     { 0x1060, "Set Member State Request"},
220     { 0x1065, "Set Member State Reply"},
221     { 0x3010, "Member Data Component"},
222     { 0x3011, "Group Data Component"},
223     { 0x3012, "Weight Entry Data Component"},
224     { 0x3013, "Member State Instance"},
225     { 0x4010, "Group of Member Data"},
226     { 0x4011, "Group of Weight Entry Data" },
227     { 0x4012, "Group of Member State Data" },
228     {      0,  NULL }
229 };
230 static value_string_ext msg_table_ext = VALUE_STRING_EXT_INIT(msg_table);
231
232 static const value_string protocol_table[] = {
233     { 0x06, "TCP" },
234     { 0x11, "UDP" },
235     {    0,  NULL }
236 };
237
238 static const value_string lbstate_healthtable[] = {
239     { 0x00, "Least Healthy" },
240     { 0x7f, "Most Healthy" },
241     {    0, NULL }
242 };
243
244 static const value_string reg_reply_response_code[] = {
245     { 0x00, "Successful" },
246     { 0x10, "Message not understood" },
247     { 0x11, "GWM will not accept this message from the sender" },
248     { 0x40, "Member already registered" },
249     { 0x44, "Duplicate Member in Request" },
250     { 0x45, "Invalid Group (determined by the GWM)"},
251     { 0x50, "Invalid Group Name Size (size == 0)"},
252     { 0x51, "Invalid LB uid Size (size == 0 or > max)"},
253     { 0x61, "Member is registering itself, but LB hasn't yet contacted the GWM."
254         "  This registration will not be processed."},
255     {    0, NULL }
256 };
257
258 static const value_string dereg_reply_response_code[] = {
259     { 0x00, "Successful" },
260     { 0x10, "Message not understood" },
261     { 0x11, "GWM will not accept this message from the sender" },
262     { 0x41, "Application or System not registered" },
263     { 0x42, "Unknown Group Name" },
264     { 0x43, "Unknown LB uid" },
265     { 0x44, "Duplicate Member in Request"},
266     { 0x46, "Duplicate Group in Request (for remove all members/groups requests)"},
267     { 0x51, "Invalid LB uid Size (size == 0 or > max)"},
268     { 0x61, "Member is deregistering itself, but LB hasn't yet contacted the GWM."
269         "  This deregistration will not be processed."},
270     {    0, NULL }
271 };
272
273 static const value_string get_weights_reply_response_code[] = {
274     { 0x00, "Successful" },
275     { 0x10, "Message not understood" },
276     { 0x11, "GWM will not accept this message from the sender" },
277     { 0x42, "Unknown Group Name" },
278     { 0x43, "Unknown LB uid" },
279     { 0x46, "Duplicate Group in Request"},
280     { 0x51, "Invalid LB uid Size (size == 0 or > max)"},
281     {    0, NULL }
282 };
283
284 static const value_string set_lb_state_reply_response_code[] = {
285     { 0x00, "Successful" },
286     { 0x10, "Message not understood" },
287     { 0x11, "GWM will not accept this message from the sender" },
288     { 0x51, "Invalid LB uid Size (size == 0 or > max)"},
289     {    0, NULL }
290 };
291
292 static const value_string set_mem_state_reply_response_code[] = {
293     { 0x00, "Successful" },
294     { 0x10, "Message not understood" },
295     { 0x11, "GWM will not accept this message from the sender" },
296     { 0x41, "Application or System not registered" },
297     { 0x42, "Unknown Group Name" },
298     { 0x43, "Unknown LB uid" },
299     { 0x44, "Duplicate Member in Request"},
300     { 0x46, "Duplicate Group in Request (for remove all members/groups requests)"},
301     { 0x50, "Invalid Group Name Size (size == 0)"},
302     { 0x51, "Invalid LB uid Size (size == 0 or > max)"},
303     {    0, NULL }
304 };
305
306
307 #define SASP_GLOBAL_PORT        3860
308 #define SASP_MIN_PACKET_LEN     13
309
310 #define SASP_DEREG_REQ_REASON_LEARNED   0x01
311 #define SASP_DEREG_REQ_NOREASON_FLAG    0x00
312 #define SASP_HDR_TYPE           0x2010
313 #define SASP_WED_CONTACT_SUCCESS_FLAG   0x01
314 #define SASP_WED_QUIESCE_FLAG       0x02
315 #define SASP_WED_REG_FLAG       0x04
316 #define SASP_WED_CONF_FLAG      0x08
317 #define SASP_PUSH_FLAG          0x01
318 #define SASP_TRUST_FLAG         0x02
319 #define SASP_NOCHANGE_FLAG      0x04
320 #define SASP_QUIESCE_FLAG       0x01
321
322
323 static guint
324 get_sasp_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset)
325 {
326     /* Get the length of the SASP packet. */
327     return tvb_get_ntohl(tvb, offset + 5);
328 }
329
330 /* Called from tcp_dissect_pdus with a complete SASP pdu */
331 static int
332 dissect_sasp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
333 {
334     /* Set up structures needed to add the protocol subtree and manage it */
335     proto_item *ti;
336     proto_item *hti;
337     proto_item *mti;
338     proto_tree *sasp_tree;
339     proto_tree *msg_tree;
340     proto_tree *pay_load;
341     guint16     msg_type;
342     guint16     hdr_type;
343     guint32     offset = 0;
344
345     /*protocol is being displayed*/
346
347     col_set_str(pinfo->cinfo, COL_PROTOCOL, "SASP");
348     col_clear(pinfo->cinfo, COL_INFO);
349
350     ti = proto_tree_add_item(tree, proto_sasp, tvb, offset, -1, ENC_NA);
351     sasp_tree = proto_item_add_subtree(ti, ett_sasp_header);
352
353     hdr_type = tvb_get_ntohs(tvb, offset);
354     hti = proto_tree_add_uint_format_value(sasp_tree, hf_sasp_type, tvb, offset, 2, hdr_type,
355         "%s", (hdr_type == SASP_HDR_TYPE) ? "SASP" : "[Invalid]");
356     if (hdr_type != SASP_HDR_TYPE)
357     {
358         expert_add_info_format(pinfo, hti, &ei_msg_type_invalid,
359             "Invalid SASP Header Type [0x%04x]", hdr_type);
360         /* XXX: The folowing should actually happen automatically ? */
361         col_set_str(pinfo->cinfo, COL_INFO, "[Malformed: Invalid SASP Header Type]");
362         return tvb_length(tvb);
363     }
364     offset += 2;
365
366     /*length*/
367     proto_tree_add_item(sasp_tree, hf_sasp_length, tvb, offset, 2, ENC_BIG_ENDIAN);
368     offset += 2;
369
370     /*Header Version */
371     proto_tree_add_item(sasp_tree, hf_sasp_vrsn, tvb, offset, 1, ENC_BIG_ENDIAN);
372     offset += 1;
373
374     /*Message*/
375     msg_tree = proto_item_add_subtree(ti, ett_sasp_msg);
376
377     /*Message Len*/
378     proto_tree_add_item(msg_tree, hf_msg_len, tvb, offset, 4, ENC_BIG_ENDIAN);
379     offset += 4;
380
381     /*Message Id*/
382     proto_tree_add_item(msg_tree, hf_msg_id, tvb, offset, 4, ENC_BIG_ENDIAN);
383     offset += 4;
384
385     /*Message Type*/
386     msg_type = tvb_get_ntohs(tvb, offset);
387     mti = proto_tree_add_item(msg_tree, hf_msg_type, tvb, offset, 2, ENC_BIG_ENDIAN);
388     pay_load = proto_item_add_subtree(ti, ett_sasp_payload);
389     offset += 2;
390
391     switch(msg_type)
392     {
393         case 0x1010:
394             /* Registration  Request */
395             col_set_str(pinfo->cinfo, COL_INFO, "Registration Request");
396             dissect_reg_req(tvb, pay_load, offset);
397             break;
398
399         case 0x1015:
400             /* Registration Reply */
401             col_set_str(pinfo->cinfo, COL_INFO, "Registration Reply");
402             dissect_reg_rep(tvb, pay_load, offset);
403             break;
404
405         case 0x1020:
406             /* Deregistration Request */
407             col_set_str(pinfo->cinfo, COL_INFO, "Deregistration Request");
408             dissect_dereg_req(tvb, pay_load, offset);
409             break;
410
411         case 0x1025:
412             /* Deregistration Reply */
413             col_set_str(pinfo->cinfo, COL_INFO, "Deregistration Reply");
414             dissect_dereg_rep(tvb, pay_load, offset);
415             break;
416
417         case 0x1030:
418             /* Get Weights Request */
419             col_set_str(pinfo->cinfo, COL_INFO, "Get Weights Request");
420             dissect_wt_req(tvb, pay_load, offset);
421             break;
422
423         case 0x1035:
424             /* Get Weights Response */
425             col_set_str(pinfo->cinfo, COL_INFO, "Get Weights Response");
426             dissect_wt_rep(tvb, pay_load, offset);
427             break;
428
429         case 0x1040:
430             /* Send Weights Request */
431             col_set_str(pinfo->cinfo, COL_INFO, "Send Weights Request");
432             dissect_sendwt(tvb, pay_load, offset);
433             break;
434
435         case 0x1050:
436             /* Set LB State Request */
437             col_set_str(pinfo->cinfo, COL_INFO, "Set LB State Request");
438             dissect_setlbstate_req(tvb, pay_load, offset);
439             break;
440
441         case 0x1055:
442             /* Set LB state Reply */
443             col_set_str(pinfo->cinfo, COL_INFO, "Set LB State Reply");
444             dissect_setlbstate_rep(tvb, pay_load, offset);
445             break;
446
447         case 0x1060:
448             /* Set Member State Request*/
449             col_set_str(pinfo->cinfo, COL_INFO, "Set Member State Request");
450             dissect_setmemstate_req(tvb, pay_load, offset);
451             break;
452
453         case 0x1065:
454             /* Set Member State Reply */
455             col_set_str(pinfo->cinfo, COL_INFO, "Set Member State Reply");
456             dissect_setmemstate_rep(tvb, pay_load, offset);
457             break;
458
459         default:
460             /* Unknown SASP Message Type */
461             col_add_fstr(pinfo->cinfo, COL_INFO,
462                 "[Malformed: Unknown Message Type [0x%04x]", msg_type);
463             expert_add_info_format(pinfo, mti, &ei_msg_type_invalid,
464                 "Unknown SASP Message Type: 0x%4x", msg_type);
465             break;
466     }
467     return tvb_length(tvb);
468 }
469
470
471 static int
472 dissect_sasp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
473 {
474     tcp_dissect_pdus(tvb, pinfo, tree, sasp_desegment, SASP_MIN_PACKET_LEN, get_sasp_pdu_len,
475                         dissect_sasp_pdu, data);
476     return tvb_length(tvb);
477 }
478
479
480 static void dissect_reg_req(tvbuff_t *tvb, proto_tree *pay_load, guint32 offset)
481 {
482     proto_item *reg_tree;
483     proto_tree *reg_req_data;
484     guint16     gmd_cnt, i;
485
486     reg_tree = proto_tree_add_text(pay_load, tvb, offset, -1, "Reg Request");
487     reg_req_data = proto_item_add_subtree(reg_tree, ett_sasp_reg_req_sz);
488
489     /* Reg Req Size */
490     proto_tree_add_item(reg_req_data, hf_sasp_reg_req_sz, tvb, offset, 2, ENC_BIG_ENDIAN);
491     offset += 2;
492
493     /* Reg Req LB Flag */
494     proto_tree_add_item(reg_req_data, hf_reg_req_lbflag, tvb, offset, 1, ENC_BIG_ENDIAN);
495     offset += 1;
496
497     gmd_cnt = tvb_get_ntohs(tvb, offset);
498
499     /* Group MEM Data Count */
500     proto_tree_add_item(reg_req_data, hf_sasp_gmd_cnt, tvb, offset, 2, ENC_BIG_ENDIAN);
501     offset += 2;
502
503     for (i=0; i<gmd_cnt; i++)
504         offset = dissect_grp_memdatacomp(tvb, reg_req_data, offset);
505 }
506
507
508 static void dissect_reg_rep(tvbuff_t *tvb, proto_tree *pay_load, guint32 offset)
509 {
510     proto_item *reg_rep;
511     proto_tree *reg_rep_tree;
512
513     reg_rep = proto_tree_add_text(pay_load, tvb, offset, -1 , "Reg Reply");
514     reg_rep_tree = proto_item_add_subtree(reg_rep, ett_sasp_reg_rep);
515
516     /* Size */
517     proto_tree_add_item(reg_rep_tree, hf_sasp_reg_rep_sz, tvb, offset, 2, ENC_BIG_ENDIAN);
518     offset += 2;
519
520     /* Response Code */
521     proto_tree_add_item(reg_rep_tree, hf_sasp_reg_rep_rcode, tvb, offset, 1, ENC_BIG_ENDIAN);
522 }
523
524
525 static void dissect_dereg_req(tvbuff_t *tvb, proto_tree *pay_load, guint32 offset)
526 {
527     /*proto_item *dereg_req_reason_flag;*/
528     /*proto_tree *dereg_req_reason_flag_tree;*/
529     guint16          gmd_cnt, i;
530     proto_item      *dereg_tree;
531     proto_tree      *dereg_req_data;
532     guint8           reason_flag;
533     static gboolean  first_flag         = TRUE;
534     wmem_strbuf_t   *reasonflags_strbuf = wmem_strbuf_new_label(wmem_packet_scope());
535     static const gchar *fstr[] = {"No Reason", "Learned & Purposeful" };
536
537     dereg_tree = proto_tree_add_text(pay_load, tvb, offset, -1 , "DeReg Request");
538     dereg_req_data = proto_item_add_subtree(dereg_tree, ett_sasp_dereg_req_sz);
539
540     /* Size */
541     proto_tree_add_item(dereg_req_data, hf_sasp_dereg_req_sz, tvb, offset, 2, ENC_BIG_ENDIAN);
542     offset += 2;
543
544     /* LB Flag */
545     proto_tree_add_item(dereg_req_data, hf_dereg_req_lbflag, tvb, offset, 1, ENC_BIG_ENDIAN);
546     offset += 1;
547
548     /* Reason */
549     wmem_strbuf_truncate(reasonflags_strbuf, 0);
550     reason_flag = tvb_get_guint8(tvb, offset);
551
552     if ((reason_flag & SASP_DEREG_REQ_REASON_LEARNED) == 0)
553         wmem_strbuf_append_printf(reasonflags_strbuf, "%s%s", first_flag ? "" : ", ", fstr[0]);
554     else
555         wmem_strbuf_append_printf(reasonflags_strbuf, "%s%s", first_flag ? "" : ", ", fstr[1]);
556     first_flag = FALSE;
557
558     /*dereg_req_reason_flag =*/
559     proto_tree_add_uint_format(dereg_req_data, hf_dereg_req_reason_flag, tvb,
560         offset, 1, reason_flag, "Reason: 0x%02x (%s)", reason_flag,
561         wmem_strbuf_get_str(reasonflags_strbuf));
562 #if 0   /* XXX: ToDo?? Flags to be displayed under a subtree ? */
563     dereg_req_reason_flag_tree = proto_item_add_subtree(dereg_req_reason_flag, ett_dereg_req_reason_flag);
564 #endif
565     offset += 1;
566
567     gmd_cnt = tvb_get_ntohs(tvb, offset);
568
569     /* Group Mem Data Count */
570     proto_tree_add_item(dereg_req_data, hf_sasp_gmd_cnt, tvb, offset, 2, ENC_BIG_ENDIAN);
571     offset += 2;
572
573     /*Group Mem Data */
574     for (i=0; i<gmd_cnt; i++)
575         offset = dissect_grp_memdatacomp(tvb, dereg_req_data, offset);
576 }
577
578
579 static void dissect_dereg_rep(tvbuff_t *tvb, proto_tree *pay_load, guint32 offset)
580 {
581     proto_item *dereg_rep;
582     proto_tree *dereg_rep_tree;
583
584     dereg_rep = proto_tree_add_text(pay_load, tvb, offset, -1 , "Dereg Reply");
585     dereg_rep_tree = proto_item_add_subtree(dereg_rep, ett_sasp_dereg_rep);
586
587     /* Size */
588     proto_tree_add_item(dereg_rep_tree, hf_sasp_dereg_rep_sz, tvb, offset, 2, ENC_BIG_ENDIAN);
589     offset += 2;
590
591     /* Return Code */
592     proto_tree_add_item(dereg_rep_tree, hf_sasp_dereg_rep_rcode, tvb, offset, 1, ENC_BIG_ENDIAN);
593 }
594
595
596 static void dissect_sendwt(tvbuff_t *tvb, proto_tree *pay_load, guint32 offset)
597 {
598     proto_item *sendwt;
599     proto_tree *sendwt_tree;
600     guint16     gwed_cnt, i;
601
602     sendwt = proto_tree_add_text(pay_load, tvb, offset, -1 , "Send Weight");
603     sendwt_tree = proto_item_add_subtree(sendwt, ett_sasp_sendwt);
604
605     /* Size */
606     proto_tree_add_item(sendwt_tree, hf_sasp_sendwt_sz, tvb, offset, 2, ENC_BIG_ENDIAN);
607     offset += 2;
608
609     gwed_cnt = tvb_get_ntohs(tvb, offset);
610
611     /* Group Wt Entry Data Count */
612     proto_tree_add_item(sendwt_tree, hf_sasp_sendwt_gwedcnt, tvb, offset, 2, ENC_BIG_ENDIAN);
613     offset += 2;
614
615     for (i=0; i<gwed_cnt; i++)
616         offset = dissect_grp_wt_entry_datacomp(tvb, sendwt_tree, offset);
617 }
618
619
620 static void dissect_setmemstate_req(tvbuff_t *tvb, proto_tree *pay_load, guint32 offset)
621 {
622     proto_item *setmemstate;
623     proto_tree *setmemstate_req_data;
624     guint16     gmsd_cnt, i;
625
626     setmemstate = proto_tree_add_text(pay_load, tvb, offset, -1 , "Set Mem State Request");
627     setmemstate_req_data = proto_item_add_subtree(setmemstate, ett_sasp_setmemstate_req);
628
629     /* Size */
630     proto_tree_add_item(setmemstate_req_data, hf_sasp_setmemstate_req_sz, tvb, offset, 2, ENC_BIG_ENDIAN);
631     offset += 2;
632
633     /*LB Flag*/
634     proto_tree_add_item(setmemstate_req_data, hf_setmemstate_req_lbflag, tvb, offset, 1, ENC_BIG_ENDIAN);
635     offset += 1;
636
637     /*Group Data Count*/
638     gmsd_cnt = tvb_get_ntohs(tvb, offset);
639     proto_tree_add_item(setmemstate_req_data, hf_sasp_setmemstate_req_gmsd_cnt, tvb, offset, 2, ENC_BIG_ENDIAN);
640     offset += 2;
641
642     for (i=0; i<gmsd_cnt; i++)
643         offset = dissect_grp_memstatedatacomp(tvb, setmemstate_req_data, offset);
644 }
645
646 static void dissect_setmemstate_rep(tvbuff_t *tvb, proto_tree *pay_load, guint32 offset)
647 {
648     proto_item *setmemstate_rep;
649     proto_tree *setmemstate_rep_tree;
650
651     setmemstate_rep = proto_tree_add_text(pay_load, tvb, offset, -1 , "Set Mem State Reply");
652     setmemstate_rep_tree = proto_item_add_subtree(setmemstate_rep, ett_sasp_setmemstate_rep);
653
654     /* Size */
655     proto_tree_add_item(setmemstate_rep_tree, hf_sasp_setmemstate_rep_sz, tvb, offset, 2, ENC_BIG_ENDIAN);
656     offset += 2;
657
658     /* Response Code */
659     proto_tree_add_item(setmemstate_rep_tree, hf_sasp_setmemstate_rep_rcode, tvb, offset, 1, ENC_BIG_ENDIAN);
660 }
661
662
663 static guint32 dissect_memdatacomp(tvbuff_t *tvb, proto_tree *pay_load, guint32 offset, proto_tree **mdct_p)
664 {
665     proto_item  *memdatacomp;
666     proto_tree  *memdatacomp_tree;
667     guint8       lab_len;
668     const gchar *ip_str;
669     struct e_in6_addr ipv6_address;
670
671     tvb_get_ipv6(tvb, offset+7, &ipv6_address);
672     ip_str = ip6_to_str(&ipv6_address);
673
674     lab_len = tvb_get_guint8(tvb, offset+23);
675
676     memdatacomp = proto_tree_add_ipv6_format(pay_load, hf_sasp_memdatacomp_ip,
677         tvb, offset, 24+lab_len, (guint8*)&ipv6_address,
678         "Member Data Comp (%s)", ip_str);
679
680     memdatacomp_tree = proto_item_add_subtree(memdatacomp, ett_sasp_memdatacomp);
681
682     /* Message Type */
683     proto_tree_add_item(memdatacomp_tree, hf_sasp_memdatacomp_type, tvb, offset, 2, ENC_BIG_ENDIAN);
684     offset += 2;
685
686     /* Size */
687     proto_tree_add_item(memdatacomp_tree, hf_sasp_memdatacomp_sz, tvb, offset, 2, ENC_BIG_ENDIAN);
688     offset += 2;
689
690     /* Protocol */
691     proto_tree_add_item(memdatacomp_tree, hf_sasp_memdatacomp_protocol, tvb, offset, 1, ENC_BIG_ENDIAN);
692     offset += 1;
693
694     /* Port */
695     proto_tree_add_item(memdatacomp_tree, hf_sasp_memdatacomp_port, tvb, offset, 2, ENC_BIG_ENDIAN);
696     offset += 2;
697
698     /*Ip*/
699     proto_tree_add_item(memdatacomp_tree, hf_sasp_memdatacomp_ip, tvb, offset, 16, ENC_NA);
700     offset += 16;
701
702     /*Label Len*/
703     proto_tree_add_item(memdatacomp_tree, hf_sasp_memdatacomp_lab_len, tvb, offset, 1, ENC_BIG_ENDIAN);
704     offset += 1;
705
706     /*Label*/
707     proto_tree_add_item(memdatacomp_tree, hf_sasp_memdatacomp_label, tvb, offset, lab_len, ENC_ASCII|ENC_NA);
708     offset += lab_len;
709
710     if (mdct_p != NULL)
711         *mdct_p = memdatacomp_tree;
712
713     return offset;
714 }
715
716
717 static guint32 dissect_grpdatacomp(tvbuff_t *tvb, proto_tree *pay_load, guint32 offset)
718 {
719     proto_item *grpdatacomp;
720     proto_tree *grpdatacomp_tree;
721     guint8      LB_uid_len;
722     guint8      grp_name_len;
723
724     grpdatacomp = proto_tree_add_text(pay_load, tvb, offset, -1 , "Group Data Component");
725     grpdatacomp_tree = proto_item_add_subtree(grpdatacomp, ett_sasp_grpdatacomp);
726
727     /*Type*/
728     proto_tree_add_item(grpdatacomp_tree, hf_sasp_grpdatacomp, tvb, offset, 2, ENC_BIG_ENDIAN);
729     offset += 2;
730
731     /*Size*/
732     proto_tree_add_item(grpdatacomp_tree, hf_sasp_grpdatacomp_sz, tvb, offset, 2, ENC_BIG_ENDIAN);
733     offset += 2;
734
735     LB_uid_len = tvb_get_guint8(tvb, offset);
736
737     /* LB UID Len*/
738     proto_tree_add_item(grpdatacomp_tree, hf_sasp_grpdatacomp_LB_uid_len,
739         tvb, offset, 1, ENC_BIG_ENDIAN);
740     offset += 1;
741
742     proto_tree_add_item(grpdatacomp_tree, hf_sasp_grpdatacomp_LB_uid,
743         tvb, offset, LB_uid_len, ENC_ASCII|ENC_NA);
744     offset += (guint8)LB_uid_len;
745
746     grp_name_len = tvb_get_guint8(tvb, offset);
747
748     /*Group Name Len */
749     proto_tree_add_item(grpdatacomp_tree, hf_sasp_grpdatacomp_grp_name_len,
750         tvb, offset, 1, ENC_BIG_ENDIAN);
751     offset += 1;
752
753     /*Group Name*/
754     proto_tree_add_item(grpdatacomp_tree, hf_sasp_grpdatacomp_grp_name,
755         tvb, offset, grp_name_len, ENC_ASCII|ENC_NA);
756     offset += grp_name_len;
757
758     return offset;
759 }
760
761
762 static guint32 dissect_grp_memdatacomp(tvbuff_t *tvb, proto_tree *pay_load, guint32 offset)
763 {
764     proto_item *grp_memdatacomp;
765     proto_tree *grp_memdatacomp_tree;
766     guint16     mem_cnt;
767     guint16     i;
768
769     grp_memdatacomp = proto_tree_add_text(pay_load, tvb, offset, -1 , "Group Of Member Data");
770     grp_memdatacomp_tree = proto_item_add_subtree(grp_memdatacomp, ett_sasp_grp_memdatacomp);
771
772     /* Group MEM Data */
773     proto_tree_add_item(grp_memdatacomp_tree, hf_sasp_grp_memdatacomp, tvb, offset, 2, ENC_BIG_ENDIAN);
774     offset += 2;
775
776     /* Group MEM Data Size*/
777     proto_tree_add_item(grp_memdatacomp_tree, hf_sasp_grp_memdatacomp_sz, tvb, offset, 2, ENC_BIG_ENDIAN);
778     offset += 2;
779
780     mem_cnt = tvb_get_ntohs(tvb, offset);
781
782     /* Group MEM Data Count*/
783     proto_tree_add_item(grp_memdatacomp_tree, hf_sasp_grp_memdatacomp_cnt, tvb, offset, 2, ENC_BIG_ENDIAN);
784     offset += 2;
785
786     offset = dissect_grpdatacomp(tvb, grp_memdatacomp_tree, offset);
787
788     /* array of memdata */
789     for (i=0; i<mem_cnt; i++)
790         offset = dissect_memdatacomp(tvb, grp_memdatacomp_tree, offset, NULL);
791
792     return offset;
793 }
794
795
796 static void dissect_wt_req(tvbuff_t *tvb, proto_tree *pay_load, guint32 offset)
797 {
798     proto_item *get_wt_data;
799     proto_tree *get_wt_tree;
800     guint16     gd_cnt, i;
801
802     get_wt_data = proto_tree_add_text(pay_load, tvb, offset, -1 , "Get Wt Req");
803     get_wt_tree = proto_item_add_subtree(get_wt_data, ett_sasp_getwt);
804
805     /* Size */
806     proto_tree_add_item(get_wt_tree, hf_sasp_wt_req_sz, tvb, offset, 2, ENC_BIG_ENDIAN);
807     offset += 2;
808
809     gd_cnt = tvb_get_ntohs(tvb, offset);
810
811     /* Group Data Count */
812     proto_tree_add_item(get_wt_tree, hf_sasp_wt_req_gd_cnt, tvb, offset, 2, ENC_BIG_ENDIAN);
813     offset += 2;
814
815     for (i=0; i<gd_cnt; i++)
816         offset = dissect_grpdatacomp(tvb, get_wt_tree, offset);
817 }
818
819
820 static void dissect_wt_rep(tvbuff_t *tvb, proto_tree *pay_load, guint32 offset)
821 {
822     proto_item *wt_rep;
823     proto_tree *wt_rep_tree;
824     guint16     gwed_cnt, i;
825
826     wt_rep = proto_tree_add_text(pay_load, tvb, offset, -1 , "Get Weights Reply");
827     wt_rep_tree = proto_item_add_subtree(wt_rep, ett_sasp_wt_rep);
828
829     /* Size */
830     proto_tree_add_item(wt_rep_tree, hf_sasp_wt_rep_sz, tvb, offset, 2, ENC_BIG_ENDIAN);
831     offset += 2;
832
833     /* Response Code */
834     proto_tree_add_item(wt_rep_tree, hf_sasp_wt_rep_rcode, tvb, offset, 1, ENC_BIG_ENDIAN);
835     offset += 1;
836
837     /* Interval */
838     proto_tree_add_item(wt_rep_tree, hf_sasp_wt_rep_interval, tvb, offset, 2, ENC_BIG_ENDIAN);
839     offset += 2;
840
841     gwed_cnt = tvb_get_ntohs(tvb, offset);
842
843     /* Count of Group of Wt Entry Data */
844     proto_tree_add_item(wt_rep_tree, hf_sasp_wt_rep_gwed_cnt, tvb, offset, 2, ENC_BIG_ENDIAN);
845     offset += 2;
846
847     for (i=0; i<gwed_cnt; i++)
848         offset = dissect_grp_wt_entry_datacomp(tvb, wt_rep_tree, offset);
849 }
850
851
852 static void dissect_setlbstate_req(tvbuff_t *tvb, proto_tree *pay_load, guint32 offset)
853 {
854     guint8 LB_uid_len;
855
856     static const int *lbflags[] = {
857         &hf_sasp_pushflag,
858         &hf_sasp_trustflag,
859         &hf_sasp_nochangeflag,
860         NULL
861     };
862
863     proto_item *setlbstate_req;
864     proto_tree *setlbstate_req_tree;
865
866     setlbstate_req = proto_tree_add_text(pay_load, tvb, offset, -1 , "Set LB State Req");
867     setlbstate_req_tree = proto_item_add_subtree(setlbstate_req, ett_sasp_setlbstate_req);
868
869     /* Size*/
870     proto_tree_add_item(setlbstate_req_tree, hf_sasp_setlbstate_req_sz,
871         tvb, offset, 2, ENC_BIG_ENDIAN);
872     offset += 2;
873
874     LB_uid_len = tvb_get_guint8(tvb, offset);
875
876     /* LB UID Len */
877     proto_tree_add_item(setlbstate_req_tree, hf_sasp_setlbstate_req_LB_uid_len,
878         tvb, offset, 1, ENC_BIG_ENDIAN);
879     offset += 1;
880
881     /*LB UID*/
882     proto_tree_add_item(setlbstate_req_tree, hf_sasp_setlbstate_req_LB_uid,
883         tvb, offset, LB_uid_len, ENC_ASCII|ENC_NA);
884     offset += (guint8)LB_uid_len;
885
886     /*LB Health*/
887     proto_tree_add_item(setlbstate_req_tree, hf_sasp_setlbstate_req_LB_health,
888         tvb, offset, 1, ENC_BIG_ENDIAN);
889     offset += 1;
890
891     proto_tree_add_bitmask_text(setlbstate_req_tree, tvb, offset, 1, "LB Flags:", NULL,
892         ett_setlbstate_req_lbflag, lbflags, ENC_BIG_ENDIAN, 0);
893 }
894
895
896 static void dissect_setlbstate_rep(tvbuff_t *tvb, proto_tree *pay_load, guint32 offset)
897 {
898     proto_item *setlbstate_rep;
899     proto_tree *setlbstate_rep_tree;
900
901     setlbstate_rep = proto_tree_add_text(pay_load, tvb, offset, -1 , "Set LB State Rep");
902     setlbstate_rep_tree = proto_item_add_subtree(setlbstate_rep, ett_sasp_setlbstate_rep);
903
904     /* Size */
905     proto_tree_add_item(setlbstate_rep_tree, hf_sasp_setlbstate_rep_sz,
906         tvb, offset, 2, ENC_BIG_ENDIAN);
907     offset += 2;
908
909     /* Response Code */
910     proto_tree_add_item(setlbstate_rep_tree, hf_sasp_setlbstate_rep_rcode,
911         tvb, offset, 1, ENC_BIG_ENDIAN);
912 }
913
914
915 static guint32 dissect_grp_memstatedatacomp(tvbuff_t *tvb, proto_tree *pay_load, guint32 offset)
916 {
917     proto_item *grp_memstatedatacomp;
918     proto_tree *grp_memstatedatacomp_tree;
919     guint16     mem_cnt;
920     guint16     i;
921
922     grp_memstatedatacomp = proto_tree_add_text(pay_load, tvb, offset, -1 , "Group Mem State Comp");
923     grp_memstatedatacomp_tree = proto_item_add_subtree(grp_memstatedatacomp,
924         ett_sasp_grp_memstatedatacomp);
925
926     /* Type */
927     proto_tree_add_item(grp_memstatedatacomp_tree, hf_sasp_grp_memstatedatacomp,
928         tvb, offset, 2, ENC_BIG_ENDIAN);
929     offset += 2;
930
931     /* Size */
932     proto_tree_add_item(grp_memstatedatacomp_tree, hf_sasp_grp_memstatedatacomp_sz,
933         tvb, offset, 2, ENC_BIG_ENDIAN);
934     offset += 2;
935
936     mem_cnt = tvb_get_ntohs(tvb, offset);
937
938     /* Count */
939     proto_tree_add_item(grp_memstatedatacomp_tree, hf_sasp_grp_memstatedatacomp_cnt,
940         tvb, offset, 2, ENC_BIG_ENDIAN);
941     offset += 2;
942
943     /* Group Data TLV */
944     offset = dissect_grpdatacomp(tvb, grp_memstatedatacomp_tree, offset);
945
946     /* Array of Mem State Data */
947     for (i=0; i<mem_cnt; i++)
948         offset = dissect_memstatedatacomp(tvb, grp_memstatedatacomp_tree, offset);
949
950     return offset;
951 }
952
953
954 static guint32 dissect_memstatedatacomp(tvbuff_t *tvb, proto_tree *pay_load, guint32 offset)
955 {
956     proto_tree *memstatedatacomp_tree;
957     proto_item *memstatedatacomp;
958     proto_tree *memdatacomp_tree;
959     guint8      memstate_flag;
960
961     offset = dissect_memdatacomp(tvb, pay_load, offset, &memdatacomp_tree);
962
963     memstatedatacomp = proto_tree_add_text(memdatacomp_tree, tvb, offset, -1 , "Member State Data");
964     memstatedatacomp_tree = proto_item_add_subtree(memstatedatacomp, ett_sasp_memstatedatacomp);
965
966     /* Type */
967     proto_tree_add_item(memstatedatacomp_tree, hf_sasp_memstatedatacomp_instance,
968         tvb, offset, 2, ENC_BIG_ENDIAN);
969     offset += 2;
970
971     /* Size */
972     proto_tree_add_item(memstatedatacomp_tree, hf_sasp_memstatedatacomp_sz,
973         tvb, offset, 2, ENC_BIG_ENDIAN);
974     offset += 2;
975
976     /* State */
977     proto_tree_add_item(memstatedatacomp_tree, hf_sasp_memstatedatacomp_state,
978         tvb, offset, 1, ENC_BIG_ENDIAN);
979     offset += 1;
980
981     /* Quiesce flag*/
982     memstate_flag = tvb_get_guint8(tvb, offset);
983     proto_tree_add_boolean(memstatedatacomp_tree, hf_sasp_memstatedatacomp_quiesce_flag,
984         tvb, offset, 1, memstate_flag);
985     offset += 1;
986
987     return offset;
988 }
989
990
991 static guint32 dissect_weight_entry_data_comp(tvbuff_t *tvb, proto_tree *pay_load, guint32 offset)
992 {
993     proto_tree *weight_entry_data_comp_tree;
994     proto_item *weight_entry_data_comp;
995
996     static const int *wtflags[] = {
997         &hf_sasp_wed_contactsuccess_flag,
998         &hf_sasp_wed_quiesce_flag,
999         &hf_sasp_wed_registration_flag,
1000         &hf_sasp_wed_confident_flag,
1001         NULL
1002     };
1003
1004     offset = dissect_memdatacomp(tvb, pay_load, offset, NULL);
1005
1006     weight_entry_data_comp = proto_tree_add_text(pay_load, tvb, offset, -1 , "Weight Entry Data");
1007     weight_entry_data_comp_tree = proto_item_add_subtree(weight_entry_data_comp,
1008         ett_sasp_weight_entry_data_comp);
1009
1010     /* Type */
1011     proto_tree_add_item(weight_entry_data_comp_tree, hf_sasp_weight_entry_data_comp_type,
1012         tvb, offset, 2, ENC_BIG_ENDIAN);
1013     offset += 2;
1014
1015     /* Size */
1016     proto_tree_add_item(weight_entry_data_comp_tree, hf_sasp_weight_entry_data_comp_sz,
1017         tvb, offset, 2, ENC_BIG_ENDIAN);
1018     offset += 2;
1019
1020     proto_tree_add_item(weight_entry_data_comp_tree, hf_sasp_weight_entry_data_comp_state,
1021         tvb, offset, 1, ENC_BIG_ENDIAN);
1022     offset += 1;
1023
1024     proto_tree_add_bitmask_text(weight_entry_data_comp_tree, tvb, offset, 1, "Flags:", NULL,
1025         ett_wt_entry_data_flag, wtflags, ENC_BIG_ENDIAN, 0);
1026     offset += 1;
1027
1028     /* Weight */
1029     proto_tree_add_item(weight_entry_data_comp_tree, hf_sasp_weight_entry_data_comp_weight,
1030         tvb, offset, 2, ENC_BIG_ENDIAN);
1031     offset += 2;
1032
1033     return offset;
1034 }
1035
1036
1037 static guint32 dissect_grp_wt_entry_datacomp(tvbuff_t *tvb, proto_tree *pay_load, guint32 offset)
1038 {
1039     proto_item *grp_wt_entry_datacomp;
1040     proto_tree *grp_wt_entry_datacomp_tree;
1041     guint16     wt_entry_cnt;
1042     guint16     i;
1043
1044     grp_wt_entry_datacomp = proto_tree_add_text(pay_load, tvb, offset, -1 , "Group of Wt Entry Data");
1045     grp_wt_entry_datacomp_tree = proto_item_add_subtree(grp_wt_entry_datacomp,
1046         ett_sasp_grp_wt_entry_datacomp);
1047
1048     /* Type */
1049     proto_tree_add_item(grp_wt_entry_datacomp_tree, hf_sasp_grp_wt_entry_datacomp_type,
1050         tvb, offset, 2, ENC_BIG_ENDIAN);
1051     offset += 2;
1052
1053     /* Size */
1054     proto_tree_add_item(grp_wt_entry_datacomp_tree, hf_sasp_grp_wt_entry_datacomp_sz,
1055         tvb, offset, 2, ENC_BIG_ENDIAN);
1056     offset += 2;
1057
1058     wt_entry_cnt = tvb_get_ntohs(tvb, offset);
1059
1060     /* Wt Entry Count*/
1061     proto_tree_add_item(grp_wt_entry_datacomp_tree, hf_sasp_grp_wt_entry_datacomp_cnt,
1062         tvb, offset, 2, ENC_BIG_ENDIAN);
1063     offset += 2;
1064
1065     /* Group Data */
1066     offset = dissect_grpdatacomp(tvb, grp_wt_entry_datacomp_tree, offset);
1067
1068     /* Member Data */
1069     for (i=0; i<wt_entry_cnt; i++)
1070         offset = dissect_weight_entry_data_comp(tvb, grp_wt_entry_datacomp_tree, offset);
1071
1072     return offset;
1073 }
1074
1075
1076 /* sasp protocol register */
1077 void proto_register_sasp(void)
1078 {
1079     static hf_register_info hf[] = {
1080         /*SASP Header */
1081         { &hf_sasp_type,
1082           { "Type", "sasp.msg.type",
1083             FT_UINT16, BASE_HEX, NULL, 0x0,
1084             "SASP Header", HFILL }
1085         },
1086
1087         { &hf_sasp_length,
1088           { "Length", "sasp.header.Len",
1089             FT_UINT16, BASE_DEC, NULL, 0x0,
1090             "SASP Header Length", HFILL }
1091         },
1092
1093         { &hf_sasp_vrsn,
1094           { "Version", "sasp.version",
1095             FT_UINT8, BASE_DEC, NULL, 0x0,
1096             "SASP Version", HFILL }
1097         },
1098
1099         { &hf_msg_len,
1100           { "Message Len", "sasp.msg.len",
1101             FT_UINT32, BASE_DEC, NULL, 0x0,
1102             "SASP Msg Len", HFILL }
1103         },
1104
1105         { &hf_msg_id,
1106           { "Message Id", "sasp.msg.id",
1107             FT_UINT32, BASE_DEC, NULL, 0x0,
1108             "SASP Msg Id", HFILL }
1109         },
1110
1111         /*Message Type*/
1112         { &hf_msg_type,
1113           { "Message Type", "sasp.msg.type",
1114             FT_UINT16, BASE_HEX|BASE_EXT_STRING, &msg_table_ext, 0x0,
1115             "SASP Msg Type", HFILL }
1116         },
1117
1118         /*Reg Request*/
1119         { &hf_sasp_reg_req_sz,
1120           { "Reg Req-Size", "sasp.reg-req.size",
1121             FT_UINT32, BASE_DEC, NULL, 0x0,
1122             "SASP Reg Req Size", HFILL }
1123         },
1124
1125         { &hf_reg_req_lbflag,
1126           { "Reg Req-LB Flag", "sasp.reg-req.lbflag",
1127             FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1128             "SASP Reg Req LB Flag", HFILL } },
1129
1130         { &hf_sasp_gmd_cnt,
1131           { "Grp Mem Data-Count", "sasp.grp-mem-data.count",
1132             FT_UINT16, BASE_DEC, NULL, 0x0,
1133             "SASP Grp Mem Data Count", HFILL } },
1134
1135         /* Reg Reply */
1136
1137         { &hf_sasp_reg_rep_sz,
1138           { "Reg Reply-Size", "sasp.reg-rep.size",
1139             FT_UINT16, BASE_DEC, NULL, 0x0,
1140             "SASP Reg Reply size", HFILL } },
1141
1142         { &hf_sasp_reg_rep_rcode,
1143           { "Reg Reply-Return Code", "sasp.reg-rep.retcode",
1144             FT_UINT8, BASE_HEX, VALS(reg_reply_response_code), 0x0,
1145             "SASP Reg Rep Return Code", HFILL } },
1146
1147         /* Dereg Req */
1148         { &hf_sasp_dereg_req_sz,
1149           { "Dereg Req-Size", "sasp.dereg-req.size",
1150             FT_UINT32, BASE_DEC, NULL, 0x0,
1151             "SASP Dereg Req Size", HFILL } },
1152
1153         { &hf_dereg_req_lbflag,
1154           { "Dereg Req-LB Flag", "sasp.dereg-req.lbflag",
1155             FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1156             "SASP Dereg Req LB Flag", HFILL } },
1157
1158         { &hf_dereg_req_reason_flag,
1159           { "Reason Flags", "sasp.flags.reason",
1160             FT_UINT8, BASE_HEX, NULL, 0x0,
1161             NULL, HFILL } },
1162
1163 #if 0
1164         { &hf_dereg_req_reason,
1165           { "Dereg Req-Reason", "sasp.dereg-req.reason",
1166             FT_UINT8, BASE_HEX, NULL, 0x0,
1167             "SASP Dereg Req Reason", HFILL } },
1168 #endif
1169
1170         /* Dereg Rep */
1171         { &hf_sasp_dereg_rep_sz,
1172           { "Dereg Rep-Size", "sasp.dereg-rep.size",
1173             FT_UINT16, BASE_DEC, NULL, 0x0,
1174             "SASP Dereg Rep Size", HFILL } },
1175
1176         { &hf_sasp_dereg_rep_rcode,
1177           { "Dereg Rep-Return Code", "sasp.dereg-rep.retcode",
1178             FT_UINT8, BASE_HEX, VALS(dereg_reply_response_code), 0x0,
1179             "SASP Dereg Rep Return Code", HFILL } },
1180
1181         /* Send weight */
1182
1183         { &hf_sasp_sendwt_sz,
1184           { "Sendwt-Size", "sasp.sendwt.size",
1185             FT_UINT16, BASE_DEC, NULL, 0x0,
1186             "SASP Sendwt-Size", HFILL } },
1187
1188         { &hf_sasp_sendwt_gwedcnt,
1189           { "Sendwt-Grp Wt EntryData Count", "sasp.sendwt-grp-wtentrydata.count",
1190             FT_UINT16, BASE_DEC, NULL, 0x0,
1191             "SASP Sendwt Grp Wt Entry Data Count", HFILL } },
1192
1193         /*Set Mem State Req*/
1194
1195         { &hf_sasp_setmemstate_req_sz,
1196           { "Set Memstate Req-Size", "sasp.setmemstate-req.size",
1197             FT_UINT16, BASE_DEC, NULL, 0x0,
1198             "SASP Set Memstate Req Size", HFILL } },
1199
1200         { &hf_setmemstate_req_lbflag,
1201           { "Set Memstate Req-LB Flag", "sasp.setmemstate-req.lbflag",
1202             FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1203             "SASP Set Memstate Req LB Flag", HFILL } },
1204
1205         { &hf_sasp_setmemstate_req_gmsd_cnt,
1206           { "Set Memstate Req-Gmsd Count", "sasp.group-memstate.count",
1207             FT_UINT16, BASE_DEC, NULL, 0x0,
1208             "Group Of Member State Data Count", HFILL } },
1209
1210         /* Set Mem State Reply */
1211 #if 0
1212         { &hf_sasp_setmemstate_rep,
1213           { "Set Memstate Reply", "sasp.setmemstate-rep",
1214             FT_UINT32, BASE_HEX, NULL, 0x0,
1215             "SASP Set Memstate Reply", HFILL } },
1216 #endif
1217
1218         { &hf_sasp_setmemstate_rep_sz,
1219           { "Set Memstate Rep-Size", "sasp.setmemstate-rep.size",
1220             FT_UINT16, BASE_DEC, NULL, 0x0,
1221             "SASP Set Memstate Rep Size", HFILL } },
1222
1223         { &hf_sasp_setmemstate_rep_rcode,
1224           { "Set Memstate Rep-Return Code", "sasp.setmemstate-rep.retcode",
1225             FT_UINT8, BASE_HEX, VALS(set_mem_state_reply_response_code), 0x0,
1226             "SASP Set Memstate Rep Return Code", HFILL } },
1227
1228         /*Mem Data Component*/
1229
1230         { &hf_sasp_memdatacomp_type,
1231           { "Message Type", "sasp.msg.type",
1232             FT_UINT16, BASE_HEX|BASE_EXT_STRING, &msg_table_ext, 0x0,
1233             "SASP Mem Data Comp", HFILL } },
1234
1235         { &hf_sasp_memdatacomp_sz,
1236           { "Mem Data Comp-Size", "sasp.memdatacomp.size",
1237             FT_UINT16, BASE_DEC, NULL, 0x0,
1238             "SASP Mem Data Comp Size", HFILL } },
1239
1240         { &hf_sasp_memdatacomp_protocol,
1241           { "Mem Data Comp-Protocol", "sasp.memdatacomp.protocol",
1242             FT_UINT8, BASE_HEX, VALS(protocol_table), 0x0,
1243             "SASP Mem Data Comp Protocol", HFILL } },
1244
1245         { &hf_sasp_memdatacomp_port,
1246           { "Mem Data Comp-Port", "sasp.memdatacomp.port",
1247             FT_UINT16, BASE_DEC, NULL, 0x0,
1248             "SASP Mem Data Comp Port", HFILL } },
1249
1250         { &hf_sasp_memdatacomp_ip,
1251           { "Mem Data Comp-Ip", "sasp.memdatacomp.ip",
1252             FT_IPv6, BASE_NONE, NULL, 0x0,
1253             "SASP Mem Data Comp Ip", HFILL } },
1254
1255         { &hf_sasp_memdatacomp_lab_len,
1256           { "Mem Data Comp-Label Len", "sasp.memdatacomp.label.len",
1257             FT_UINT8, BASE_DEC, NULL, 0x0,
1258             "SASP Mem Data Comp Label Length", HFILL } },
1259
1260         { &hf_sasp_memdatacomp_label,
1261           { "Mem Data Comp-Label", "sasp.memdatacomp.label",
1262             FT_STRING, BASE_NONE, NULL, 0x0,
1263             "SASP Mem Data Comp Label", HFILL } },
1264
1265         /*Get Weight Request*/
1266
1267         { &hf_sasp_wt_req_sz,
1268           { "Get Wt Req-Size", "sasp.getwt.req.size",
1269             FT_UINT16, BASE_DEC, NULL, 0x0,
1270             "SASP Get Wt Req Size", HFILL } },
1271
1272         { &hf_sasp_wt_req_gd_cnt,
1273           { "Get Wt Req-Grp Data Count", "sasp.getwt-req-grpdata.count",
1274             FT_UINT16, BASE_DEC, NULL, 0x0,
1275             "SASP Get Wt Grp Data Count", HFILL } },
1276
1277         /*Get Weight Reply*/
1278
1279         { &hf_sasp_wt_rep_sz,
1280           { "Get Wt Rep-Size", "sasp.getwt.rep.size",
1281             FT_UINT16, BASE_DEC, NULL, 0x0,
1282             "SASP Get Wt Rep Size", HFILL } },
1283
1284         { &hf_sasp_wt_rep_rcode,
1285           { "Get Wt Rep-Return Code", "sasp.getwt-rep.retcode",
1286             FT_UINT8, BASE_HEX, VALS(get_weights_reply_response_code), 0x0,
1287             "SASP Get Wt Rep Return Code", HFILL } },
1288
1289         { &hf_sasp_wt_rep_interval,
1290           { "Get Wt Rep-Interval", "sasp.getwt-rep.interval",
1291             FT_UINT8, BASE_DEC, NULL, 0x0,
1292             "SASP Get Wt Rep Interval", HFILL } },
1293
1294         { &hf_sasp_wt_rep_gwed_cnt,
1295           { "Get Wt Rep-Grp WtEntry Data Cnt", "sasp.getwt-rep-grpwtentrydata.count",
1296             FT_UINT16, BASE_DEC, NULL, 0x0,
1297             "SASP Get Wt Rep Grp Wt Entry Data Cnt", HFILL } },
1298
1299         /*Set LB State Rep */
1300
1301 #if 0
1302         { &hf_sasp_setlbstate_rep,
1303           { "Set Lbstate Rep", "sasp.msg.type",
1304             FT_UINT32, BASE_HEX, NULL, 0x0,
1305             "SASP Set Lbstate Rep", HFILL } },
1306 #endif
1307
1308         { &hf_sasp_setlbstate_rep_sz,
1309           { "Set Lbstate Rep-Size", "sasp.setlbstate-rep.size",
1310             FT_UINT16, BASE_DEC, NULL, 0x0,
1311             "SASP Set Lbstate Rep Size", HFILL } },
1312
1313         { &hf_sasp_setlbstate_rep_rcode,
1314           { "Set Lbstate Rep-Return Code", "sasp.setlbstate-rep.retcode",
1315             FT_UINT8, BASE_HEX, VALS(set_lb_state_reply_response_code), 0x0,
1316             "SASP Set Lbstate Rep Return Code", HFILL } },
1317
1318
1319         /*grp data comp */
1320
1321         { &hf_sasp_grpdatacomp,
1322           { "Message Type", "sasp.msg.type",
1323             FT_UINT16, BASE_HEX|BASE_EXT_STRING, &msg_table_ext, 0x0,
1324             "SASP Grp Data Comp", HFILL } },
1325
1326         { &hf_sasp_grpdatacomp_sz,
1327           { "Grp Data Comp-Size", "sasp.grpdatacomp.size",
1328             FT_UINT16, BASE_DEC, NULL, 0x0,
1329             "SASP Grp Data Comp size", HFILL } },
1330
1331         { &hf_sasp_grpdatacomp_LB_uid_len,
1332           { "Grp Data Comp-Label UID Len", "sasp.grpdatacomp.label.uid.len",
1333             FT_UINT8, BASE_DEC, NULL, 0x0,
1334             "SASP Grp Data Comp Label Uid Len", HFILL } },
1335
1336         { &hf_sasp_grpdatacomp_LB_uid,
1337           { "Grp Data Comp-Label UID", "sasp.grpdatacomp.label.uid",
1338             FT_STRING, BASE_NONE, NULL, 0x0,
1339             "SASP Grp Data Comp Label Uid", HFILL } },
1340
1341         { &hf_sasp_grpdatacomp_grp_name_len,
1342           { "Grp Data Comp-Grp Name Len", "sasp.grpdatacomp.grpname.len",
1343             FT_UINT8, BASE_DEC, NULL, 0x0,
1344             "SASP Grp Data Comp Grp Name Len", HFILL } },
1345
1346         { &hf_sasp_grpdatacomp_grp_name,
1347           { "Grp Data Comp-Grp Name", "sasp.grpdatacomp.grpname",
1348             FT_STRING, BASE_NONE, NULL, 0x0,
1349             "SASP Grp Data Comp Grp Name", HFILL } },
1350
1351         /*grp mem data comp */
1352
1353         { &hf_sasp_grp_memdatacomp,
1354           { "Message Type", "sasp.msg.type",
1355             FT_UINT16, BASE_HEX|BASE_EXT_STRING, &msg_table_ext, 0x0,
1356             "SASP Grp Mem Data Comp", HFILL } },
1357
1358
1359         { &hf_sasp_grp_memdatacomp_sz,
1360           { "Grp Mem Data Comp-Size", "sasp.grp-memdatacomp.size",
1361             FT_UINT16, BASE_DEC, NULL, 0x0,
1362             "SASP Grp Mem Data Comp Size", HFILL } },
1363
1364         { &hf_sasp_grp_memdatacomp_cnt,
1365           { "Grp Mem Data Comp-Count", "sasp.grp.memdatacomp.count",
1366             FT_UINT16, BASE_DEC, NULL, 0x0,
1367             "SASP Grp Mem Data Comp Cnt", HFILL } },
1368
1369
1370         /*set LB state req*/
1371
1372         { &hf_sasp_setlbstate_req_sz,
1373           { "Set LB State Req-Size", "sasp.setlbstate-req.size",
1374             FT_UINT16, BASE_DEC, NULL, 0x0,
1375             "SASP Set LB State Req  Size", HFILL } },
1376
1377         { &hf_sasp_setlbstate_req_LB_uid_len,
1378           { "Set LB State Req-LB UID Len", "sasp.setlbstate-req.lbuid.len",
1379             FT_UINT8, BASE_DEC, NULL, 0x0,
1380             "SASP Set LB State Req  LB Uid Len", HFILL } },
1381
1382         { &hf_sasp_setlbstate_req_LB_uid,
1383           { "Set LB State Req-LB UID", "sasp.setlbstate-req.lbuid",
1384             FT_STRING, BASE_NONE, NULL, 0x0,
1385             "SASP Set LB State Req LB UID", HFILL } },
1386
1387         { &hf_sasp_setlbstate_req_LB_health,
1388           { "Set LB State Req-LB Health", "sasp.setlbstate-req.lbhealth",
1389             FT_UINT8, BASE_HEX, VALS(lbstate_healthtable), 0x0,
1390             "SASP Set LB State Req LB Health", HFILL } },
1391
1392 #if 0
1393         { &hf_lbstate_flag,
1394           { "Flags", "sasp.flags.lbstate",
1395             FT_UINT8, BASE_HEX, NULL, 0x0,
1396             NULL, HFILL } },
1397 #endif
1398
1399         { &hf_sasp_pushflag,
1400           { "PUSH", "sasp.flags.push",
1401             FT_BOOLEAN, 8, NULL, SASP_PUSH_FLAG,
1402             "SASP Push Flag", HFILL } },
1403
1404         { &hf_sasp_trustflag,
1405           { "TRUST", "sasp.flags.trust",
1406             FT_BOOLEAN, 8, NULL, SASP_TRUST_FLAG,
1407             "SASP Trust Flag", HFILL } },
1408
1409         { &hf_sasp_nochangeflag,
1410           { "NOCHANGE", "sasp.flags.nochange",
1411             FT_BOOLEAN, 8, NULL, SASP_NOCHANGE_FLAG,
1412             "SASP Nochange Flag", HFILL } },
1413
1414         /*grp mem state data comp */
1415
1416         { &hf_sasp_grp_memstatedatacomp,
1417           { "Message Type", "sasp.msg.type",
1418             FT_UINT16, BASE_HEX|BASE_EXT_STRING, &msg_table_ext, 0x0,
1419             "SASP Message Type", HFILL } },
1420
1421
1422         { &hf_sasp_grp_memstatedatacomp_sz,
1423           { "Grp Mem State-Size", "sasp.grp.memstate.size",
1424             FT_UINT16, BASE_DEC, NULL, 0x0,
1425             "SASP Grp Mem State Data Comp Size", HFILL } },
1426
1427         { &hf_sasp_grp_memstatedatacomp_cnt,
1428           { "Grp Mem State-Count", "sasp.grp.memstate.count",
1429             FT_UINT16, BASE_DEC, NULL, 0x0,
1430             "SASP Grp Mem State Data Comp Count", HFILL } },
1431
1432         /*mem state instance */
1433
1434         { &hf_sasp_memstatedatacomp_instance,
1435           { "Message Type", "sasp.msg.type",
1436             FT_UINT16, BASE_HEX|BASE_EXT_STRING, &msg_table_ext, 0x0,
1437             "SASP Message Type", HFILL } },
1438
1439
1440         { &hf_sasp_memstatedatacomp_sz,
1441           { "Mem State-Size", "sasp.memstate.size",
1442             FT_UINT16, BASE_DEC, NULL, 0x0,
1443             "SASP Mem State Data Comp Size", HFILL } },
1444
1445         { &hf_sasp_memstatedatacomp_state,
1446           { "Mem State-State", "sasp.memstate.state",
1447             FT_UINT8, BASE_HEX, NULL, 0x0,
1448             "SASP Mem State Data Comp State", HFILL } },
1449
1450         { &hf_sasp_memstatedatacomp_quiesce_flag,
1451           { "Mem State-Quiesce Flag", "sasp.flags.quiesce",
1452             FT_BOOLEAN, 8, NULL, SASP_QUIESCE_FLAG,
1453             "SASP Quiesce Flag", HFILL } },
1454
1455         /*weight entry data comp*/
1456
1457         { &hf_sasp_weight_entry_data_comp_type,
1458           { "Wt Entry Data Comp", "sasp.msg.type",
1459             FT_UINT16, BASE_HEX|BASE_EXT_STRING, &msg_table_ext, 0x0,
1460             "SASP Wt Entry Data Comp", HFILL } },
1461
1462         { &hf_sasp_weight_entry_data_comp_sz,
1463           { "Wt Entry Data Comp-Size", "sasp.wtentry.size",
1464             FT_UINT16, BASE_DEC, NULL, 0x0,
1465             "SASP Wt Entry Data Comp Size", HFILL } },
1466
1467         { &hf_sasp_weight_entry_data_comp_state,
1468           { "Wt Entry Data Comp-state", "sasp.wtentry.state",
1469             FT_UINT8, BASE_HEX, NULL, 0x0,
1470             "SASP Wt Entry Data Comp State", HFILL } },
1471
1472 #if 0
1473         { &hf_wtstate_flag,
1474           { "Flags", "sasp.flags.wtstate",
1475             FT_UINT8, BASE_HEX, NULL, 0x0,
1476             NULL, HFILL } },
1477 #endif
1478
1479         { &hf_sasp_wed_contactsuccess_flag,
1480           { "Contact Success", "sasp.flags.contactsuccess",
1481             FT_BOOLEAN, 8, NULL, SASP_WED_CONTACT_SUCCESS_FLAG,
1482             "SASP Contact Success Flag", HFILL } },
1483
1484         { &hf_sasp_wed_quiesce_flag,
1485           { "Quiesce", "sasp.flags.quiesce",
1486             FT_BOOLEAN, 8, NULL, SASP_WED_QUIESCE_FLAG,
1487             "SASP Quiesce Flag", HFILL } },
1488
1489         { &hf_sasp_wed_registration_flag,
1490           { "Registration", "sasp.flags.registration",
1491             FT_BOOLEAN, 8, NULL, SASP_WED_REG_FLAG,
1492             "SASP Registration Flag", HFILL } },
1493
1494         { &hf_sasp_wed_confident_flag,
1495           { "Confident", "sasp.flags.confident",
1496             FT_BOOLEAN, 8, NULL, SASP_WED_CONF_FLAG,
1497             "SASP Confident Flag", HFILL } },
1498
1499         { &hf_sasp_weight_entry_data_comp_weight,
1500           { "Wt Entry Data Comp-weight", "sasp.wtentrydatacomp.weight",
1501             FT_UINT16, BASE_DEC, NULL, 0x0,
1502             "SASP Wt Entry Data Comp weight", HFILL } },
1503
1504
1505         /*grp wt entry data comp */
1506
1507         { &hf_sasp_grp_wt_entry_datacomp_type,
1508           { "Grp Wt Entry Data Comp", "sasp.msg.type",
1509             FT_UINT16, BASE_HEX|BASE_EXT_STRING, &msg_table_ext, 0x0,
1510             "SASP Grp Wt Entry Data Comp", HFILL } },
1511
1512         { &hf_sasp_grp_wt_entry_datacomp_sz,
1513           { "Grp Wt Entry Data Comp Size", "sasp.grp-wtentrydata.size",
1514             FT_UINT16, BASE_DEC, NULL, 0x0,
1515             "SASP Grp Wt Entry Data Comp Size", HFILL } },
1516
1517         { &hf_sasp_grp_wt_entry_datacomp_cnt,
1518           { "Grp Wt Entry Data Comp Cnt", "sasp.grp-wtentrydata.count",
1519             FT_UINT16, BASE_DEC, NULL, 0x0,
1520             "SASP Grp Wt Entry Data Comp Cnt", HFILL } }
1521     };
1522
1523     /* Setup protocol subtree array */
1524
1525     static gint *ett[] = {
1526         &ett_sasp_data,
1527         &ett_sasp_header,
1528         &ett_sasp_msg,
1529         &ett_sasp_payload,
1530         &ett_sasp_reg_req,
1531         &ett_sasp_reg_rep,
1532         &ett_sasp_reg_req_sz,
1533         &ett_sasp_dereg_req_sz,
1534         &ett_sasp_dereg_rep,
1535         &ett_sasp_sendwt,
1536         &ett_sasp_setmemstate_req,
1537         &ett_sasp_setmemstate_rep,
1538         &ett_sasp_memdatacomp,
1539         &ett_sasp_grpdatacomp,
1540         &ett_sasp_grp_memdatacomp,
1541         &ett_sasp_setlbstate_req,
1542         &ett_sasp_setlbstate_rep,
1543         &ett_sasp_getwt,
1544         &ett_setlbstate_req_lbflag,
1545         &ett_sasp_grp_memstatedatacomp,
1546         &ett_sasp_memstatedatacomp,
1547 /*      &ett_dereg_req_reason_flag, */
1548         &ett_sasp_grp_wt_entry_datacomp,
1549         &ett_sasp_weight_entry_data_comp,
1550         &ett_wt_entry_data_flag,
1551         &ett_sasp_wt_rep
1552     };
1553
1554     static ei_register_info ei[] = {
1555         { &ei_msg_type_invalid, { "sasp.msg.type.invalid", PI_PROTOCOL, PI_WARN, "Invalid Type", EXPFILL }}
1556     };
1557
1558     module_t *sasp_module;
1559     expert_module_t* expert_sasp;
1560
1561     proto_sasp = proto_register_protocol("Server/Application State Protocol", "SASP", "sasp");
1562
1563     proto_register_field_array(proto_sasp, hf, array_length(hf));
1564     proto_register_subtree_array(ett, array_length(ett));
1565     expert_sasp = expert_register_protocol(proto_sasp);
1566     expert_register_field_array(expert_sasp, ei, array_length(ei));
1567
1568     sasp_module = prefs_register_protocol(proto_sasp, NULL);
1569     prefs_register_bool_preference(sasp_module, "desegment_sasp_messages",
1570         "Reassemble SASP messages spanning multiple TCP segments",
1571         "Whether the SASP dissector should reassemble messages"
1572         " spanning multiple TCP segments."
1573         " To use this option, you must also enable"
1574         " \"Allow subdissectors to reassemble TCP streams\""
1575         " in the TCP protocol settings.",
1576         &sasp_desegment);
1577 }
1578
1579
1580 /* Handing off to TCP */
1581 void
1582 proto_reg_handoff_sasp(void)
1583 {
1584     dissector_handle_t sasp_handle;
1585
1586     sasp_handle = new_create_dissector_handle(dissect_sasp, proto_sasp);
1587     dissector_add_uint("tcp.port", SASP_GLOBAL_PORT, sasp_handle);
1588 }
1589
1590 /*
1591  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
1592  *
1593  * Local variables:
1594  * c-basic-offset: 4
1595  * tab-width: 8
1596  * indent-tabs-mode: nil
1597  * End:
1598  *
1599  * vi: set shiftwidth=4 tabstop=8 expandtab:
1600  * :indentSize=4:tabSize=8:noTabs=true:
1601  */