fix usage of "if(tree) {" to display the right things, even if no coloring rule is set
[obnox/wireshark/wip.git] / epan / dissectors / packet-cpha.c
1 /* packet-cpha.c
2  * Routines for the Check Point High-Availability Protocol (CPHAP)
3  * Copyright 2002, Yaniv Kaul <ykaul-at-netvision.net.il>
4  *
5  * $Id$
6  *
7  * Ethereal - Network traffic analyzer
8  * By Gerald Combs <gerald@ethereal.com>
9  * Copyright 1998 Gerald Combs
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (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
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
24  */
25
26 #ifdef HAVE_CONFIG_H
27 # include "config.h"
28 #endif
29
30 #include <stdio.h>
31 #include <string.h>
32
33 #include <glib.h>
34
35 #ifdef NEED_SNPRINTF_H
36 # include "snprintf.h"
37 #endif
38
39 #include <epan/packet.h>
40 #include <epan/ipproto.h>
41
42 static int proto_cphap = -1;
43
44 static int hf_magic_number = -1;
45 static int hf_cpha_protocol_ver = -1;
46 static int hf_cluster_number = -1;
47 static int hf_opcode = -1;
48 static int hf_src_if_num = -1;
49 static int hf_random_id = -1;
50 static int hf_src_machine_id = -1;
51 static int hf_dst_machine_id = -1;
52 static int hf_policy_id = -1;
53 static int hf_filler = -1;
54 static int hf_id_num = -1;
55 static int hf_report_code = -1;
56 static int hf_ha_mode = -1;
57 static int hf_ha_time_unit = -1;
58 /*static int hf_problem = -1;*/
59 static int hf_num_reported_ifs = -1;
60 static int hf_ethernet_add = -1;
61 static int hf_is_if_trusted = -1;
62 static int hf_ip = -1;
63 static int hf_slot_num = -1;
64 static int hf_machine_num = -1;
65 static int hf_seed = -1;
66 static int hf_hash_len = -1;
67 static int hf_status = -1;
68 static int hf_in_up_num = -1;
69 static int hf_in_assumed_up_num = -1;
70 static int hf_out_up_num = -1;
71 static int hf_out_assumed_up_num = -1;
72 static int hf_ifn = -1;
73
74 static gint ett_cphap = -1;
75
76 #define UDP_PORT_CPHA   8116
77 #define CPHA_MAGIC 0x1A90
78
79 struct cpha_hdr {
80   guint16       magic_number;
81   guint16       ha_protocol_ver;
82   guint16       cluster_number;
83   guint16       opcode;
84   guint16       src_if_num;
85   guint16       random_id;
86   guint16       src_machine_id;
87   guint16       dst_machine_id;
88   guint16       policy_id;
89   guint16       filler;
90   guint32       data;
91 };
92
93 struct fwha_my_state_hdr {
94   guint16       id_num;
95   guint16       report_code;
96   guint16       ha_mode;
97   guint16       ha_time_unit;
98   /*guint16     problem;*/
99 };
100
101 struct conf_reply_hdr {
102   guint32       num_reported_ifs;
103   guint8        ethernet_add[6];
104   guint16       is_if_trusted;
105   guint32       ip;
106 };
107
108 struct lb_conf_hdr {
109   guint16       slot_num;
110   guint16       machine_num;
111   guint32       seed;
112   guint32       hash_list_len;
113 };
114
115 struct fwhap_if_state_s {
116   guint8        in_up_num;
117   guint8        in_assumed_up_num;
118   guint8        out_up_num;
119   guint8        out_assumed_up_num;
120 };
121
122 #define NUM_OPCODE_TYPES 10
123
124 static const char *opcode_type_str_short[NUM_OPCODE_TYPES+1] = {
125   "Unknown",
126   "FWHA_MY_STATE",
127   "FWHA_QUERY_STATE",
128   "FWHA_IF_PROBE_REQ",
129   "FWHA_IF_PROBE_REPLY",
130   "FWHA_IFCONF_REQ",
131   "FWHA_IFCONF_REPLY",
132   "FWHA_LB_CONF",
133   "FWHA_LB_CONFIRM",
134   "FWHA_POLICY_CHANGE",
135   "FWHAP_SYNC"
136 };
137
138 static const char *opcode_type_str_long[NUM_OPCODE_TYPES+1] = {
139   "Unknown OpCode",
140   "Report source machine's state",
141   "Query other machine's state",
142   "Interface active check request",
143   "Interface active check reply",
144   "Interface configuration request",
145   "Interface configuration reply",
146   "LB configuration report request",
147   "LB configuration report reply",
148   "Policy ID change request/notification",
149   "New Sync packet"
150 };
151
152 #define NUM_STATES 5
153 static const char *state_str[NUM_STATES+1] = {
154   "Down/Dead",
155   "Initializing",
156   "Standby",
157   "Ready",
158   "Active/Active-Attention"
159 };
160
161 static const value_string status_vals[] = {
162   { 1, "New policy arrived - no need to modify HA configuration" },
163   { 2, "New policy arrived - need to modify HA configuration" },
164   { 3, "Ready to change configuration" },
165   { 0, NULL }
166 };
167
168 #define NUM_HA_MODES 4
169 static const char *ha_mode_str[NUM_HA_MODES+1] = {
170   "FWHA_UNDEF_MODE",
171   "FWHA_NOT_ACTIVE_MODE - CPHA is not active",
172   "FWHA_BALANCE_MODE - More than one machine active",
173   "FWHA_PRIMARY_UP_MODE",
174   "FWHA_ONE_UP_MODE"
175 };
176
177 static const char *ha_magic_num2str(guint16 magic);
178 static const char *version2str(guint16 version);
179 static const char *opcode2str_short(guint16 opcode);
180 static const char *opcode2str_long(guint16 opcode);
181 static void dissect_my_state(tvbuff_t *, int, proto_tree *);
182 static void dissect_lb_conf(tvbuff_t *, int, proto_tree *);
183 static void dissect_policy_change(tvbuff_t *, int, proto_tree *);
184 static void dissect_probe(tvbuff_t *, int, proto_tree *);
185 static void dissect_conf_reply(tvbuff_t *, int, proto_tree *);
186 int is_report_ifs(guint16);
187 static const char *report_code2str(guint16);
188 static const char *ha_mode2str(guint16);
189 static const char *state2str(guint8);
190
191 static int
192 dissect_cpha(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
193 {
194   int                   offset = 0;
195   struct cpha_hdr       hdr;
196   proto_item *          ti;
197   proto_item *          nti;
198   proto_tree *          cpha_tree = NULL;
199   proto_tree *          ntree = NULL;
200   guint16               opcode;
201
202   /*
203    * If the magic number or protocol version is unknown, don't treat this
204    * frame as a CPHA frame.
205    */
206   if (!tvb_bytes_exist(tvb, 0, 4)) {
207     /* Not enough data for the magic number or protocol version */
208     return 0;
209   }
210   hdr.magic_number = tvb_get_ntohs(tvb, 0);
211   hdr.ha_protocol_ver = tvb_get_ntohs(tvb, 2);
212   if (ha_magic_num2str(hdr.magic_number) == NULL) {
213     /* Bad magic number */
214     return 0;
215   }
216   if (version2str(hdr.ha_protocol_ver) == NULL) {
217     /* Bad version number */
218     return 0;
219   }
220
221   if (check_col(pinfo->cinfo, COL_PROTOCOL))
222     col_set_str(pinfo->cinfo, COL_PROTOCOL, "CPHA");
223   if (check_col(pinfo->cinfo, COL_INFO))
224     col_clear(pinfo->cinfo, COL_INFO);
225
226   tvb_memcpy(tvb, (guint8 *)&hdr, offset, sizeof(hdr));
227   hdr.magic_number = g_ntohs(hdr.magic_number);
228   hdr.ha_protocol_ver = g_ntohs(hdr.ha_protocol_ver);
229   hdr.random_id = g_ntohs(hdr.random_id);
230   hdr.src_if_num = g_ntohs(hdr.src_if_num);
231   hdr.src_machine_id = g_ntohs(hdr.src_machine_id);
232   hdr.dst_machine_id = g_ntohs(hdr.dst_machine_id);
233   hdr.policy_id = g_ntohs(hdr.policy_id);
234   hdr.filler = g_ntohs(hdr.filler);
235   opcode  = g_ntohs(hdr.opcode);
236
237   if (check_col(pinfo->cinfo, COL_INFO))
238     col_add_fstr(pinfo->cinfo, COL_INFO, "CPHAv%d: %s",
239         hdr.ha_protocol_ver, opcode2str_short(opcode));
240
241   if (tree) {
242     ti = proto_tree_add_item(tree, proto_cphap, tvb, offset, -1, FALSE);
243     cpha_tree = proto_item_add_subtree(ti, ett_cphap);
244   }
245   if (tree) {
246     proto_tree_add_uint_format(cpha_tree, hf_magic_number, tvb, offset, sizeof(hdr.magic_number), hdr.magic_number, "Magic Number: 0x%x (%s)", hdr.magic_number, ha_magic_num2str(hdr.magic_number));
247     offset += sizeof(hdr.magic_number);
248
249     proto_tree_add_uint_format(cpha_tree, hf_cpha_protocol_ver, tvb, offset, sizeof(hdr.ha_protocol_ver), hdr.ha_protocol_ver, "Protocol Version: %d (%s)", hdr.ha_protocol_ver,version2str(hdr.ha_protocol_ver));
250     offset += sizeof(hdr.ha_protocol_ver);
251
252     proto_tree_add_uint(cpha_tree, hf_cluster_number, tvb, offset, sizeof(hdr.cluster_number), g_ntohs(hdr.cluster_number));
253     offset += sizeof(hdr.cluster_number);
254
255     proto_tree_add_uint_format(cpha_tree, hf_opcode, tvb, offset, sizeof(hdr.opcode), opcode,
256                         "HA OpCode: %d (%s - %s)", opcode, opcode2str_short(opcode), opcode2str_long(opcode));
257     offset += sizeof(hdr.opcode);
258
259     proto_tree_add_uint(cpha_tree, hf_src_if_num, tvb, offset, sizeof(hdr.src_if_num),
260                         hdr.src_if_num);
261     offset += sizeof(hdr.src_if_num);
262
263     proto_tree_add_uint(cpha_tree, hf_random_id, tvb, offset, sizeof(hdr.random_id), hdr.random_id);
264     offset += sizeof(hdr.random_id);
265
266     proto_tree_add_uint(cpha_tree, hf_src_machine_id, tvb, offset, sizeof(hdr.src_machine_id), hdr.src_machine_id);
267     offset += sizeof(hdr.src_machine_id);
268
269     proto_tree_add_uint(cpha_tree, hf_dst_machine_id, tvb, offset, sizeof(hdr.dst_machine_id), hdr.dst_machine_id);
270     offset += sizeof(hdr.dst_machine_id);
271     if(hdr.ha_protocol_ver != 1) {/* 4.1 - no policy_id and filler*/
272         proto_tree_add_uint(cpha_tree, hf_policy_id, tvb, offset, sizeof(hdr.policy_id), hdr.policy_id);
273         offset += sizeof(hdr.policy_id);
274
275         proto_tree_add_uint(cpha_tree, hf_filler, tvb, offset, sizeof(hdr.filler), g_ntohs(hdr.filler));
276         offset += sizeof(hdr.filler);
277     }
278     nti = proto_tree_add_text(cpha_tree, tvb, offset, -1, opcode2str_short(opcode));
279     ntree = proto_item_add_subtree(nti, ett_cphap);
280
281     switch(opcode) {
282         case 1: dissect_my_state(tvb, offset, ntree); /* FWHAP_MY_STATE */
283                 break;
284         case 2: break;
285         case 3:                                      /* FWHAP_IF_PROBE_REQ */
286         case 4: dissect_probe(tvb, offset, ntree);   /* FWHAP_IF_PROBE_RPLY */
287                 break;
288         case 5: break;
289         case 6: dissect_conf_reply(tvb, offset, ntree); /* FWHAP_IFCONF_RPLY */
290                 break;
291         case 7: dissect_lb_conf(tvb, offset, ntree); /* FWHAP_LB_CONF */
292                 break;
293         case 9: dissect_policy_change(tvb, offset, ntree); /* FWHAP_POLICY_CHANGE */
294                 break;
295         default: break;
296     }
297   }
298
299   return tvb_length(tvb);
300 }
301
302 static void dissect_my_state(tvbuff_t * tvb, int offset, proto_tree * tree) {
303   struct fwha_my_state_hdr hdr;
304   struct fwhap_if_state_s  if_hdr;
305   int rep_mode, i;
306   proto_item *  nti = NULL;
307   proto_tree *  ntree = NULL;
308
309   tvb_memcpy(tvb, (guint8 *)&hdr, offset, sizeof(hdr));
310   hdr.id_num = g_ntohs(hdr.id_num);
311   hdr.report_code = g_ntohs(hdr.report_code);
312   hdr.ha_mode = g_ntohs(hdr.ha_mode);
313   hdr.ha_time_unit = g_ntohs(hdr.ha_time_unit);
314
315   proto_tree_add_uint(tree, hf_id_num, tvb, offset, sizeof(hdr.id_num), hdr.id_num);
316   offset += sizeof(hdr.id_num);
317
318   proto_tree_add_text(tree, tvb, offset, sizeof(hdr.report_code), "Report Code: %s",report_code2str(hdr.report_code));
319   offset += sizeof(hdr.report_code);
320
321   proto_tree_add_uint_format(tree, hf_ha_mode, tvb, offset, sizeof(hdr.ha_mode), hdr.ha_mode, "HA mode: %d (%s)", hdr.ha_mode, ha_mode2str(hdr.ha_mode));
322   offset += sizeof(hdr.ha_mode);
323
324   proto_tree_add_uint_format(tree, hf_ha_time_unit, tvb, offset, sizeof(hdr.ha_time_unit), hdr.ha_time_unit, "HA Time unit: %d miliseconds", hdr.ha_time_unit);
325   offset += sizeof(hdr.ha_time_unit);
326
327   rep_mode = is_report_ifs(hdr.report_code);
328   if (hdr.report_code & 1) {
329         /* states */
330         nti = proto_tree_add_text(tree, tvb, offset, hdr.id_num * sizeof(guint8), "Machine states");
331         ntree = proto_item_add_subtree(nti, ett_cphap);
332         for(i=0; i < hdr.id_num; i++) {
333                 proto_tree_add_text(ntree, tvb, offset, sizeof(guint8), "State of node %d: %d (%s)", i, tvb_get_guint8(tvb, offset), state2str(tvb_get_guint8(tvb, offset)));
334                 offset += sizeof(guint8);
335         }
336   }
337   if (hdr.report_code & 2) {
338         /* interface information */
339         nti = proto_tree_add_text(tree, tvb, offset, sizeof(struct fwhap_if_state_s), "Interface states");
340         ntree = proto_item_add_subtree(nti, ett_cphap);
341         tvb_memcpy(tvb, (guint8 *)&if_hdr, offset, sizeof(if_hdr));
342         proto_tree_add_int(ntree, hf_in_up_num, tvb, offset, sizeof(if_hdr.in_up_num), if_hdr.in_up_num);
343         offset += sizeof(if_hdr.in_up_num);
344         proto_tree_add_int(ntree, hf_in_assumed_up_num, tvb, offset, sizeof(if_hdr.in_assumed_up_num), if_hdr.in_assumed_up_num);
345         offset += sizeof(if_hdr.in_assumed_up_num);
346         proto_tree_add_int(ntree, hf_out_up_num, tvb, offset, sizeof(if_hdr.out_up_num), if_hdr.out_up_num);
347         offset += sizeof(if_hdr.out_up_num);
348         proto_tree_add_int(ntree, hf_out_assumed_up_num, tvb, offset, sizeof(if_hdr.out_assumed_up_num), if_hdr.out_assumed_up_num);
349         offset += sizeof(if_hdr.out_assumed_up_num);
350
351         for(i=0; i < hdr.id_num; i++) {
352                 proto_tree_add_text(tree, tvb, offset, sizeof(guint8), "Cluster %d: last packet seen %d time units ago", i, tvb_get_guint8(tvb, offset));
353                 offset += sizeof(guint8);
354         }
355   }
356
357 }
358
359 static void dissect_lb_conf(tvbuff_t * tvb, int offset, proto_tree * tree) {
360   struct lb_conf_hdr hdr;
361
362   tvb_memcpy(tvb, (guint8 *)&hdr, offset, sizeof(hdr));
363   hdr.slot_num = g_ntohs(hdr.slot_num);
364   hdr.machine_num = g_ntohs(hdr.machine_num);
365   hdr.seed = g_ntohs(hdr.seed);
366   hdr.hash_list_len = g_ntohs(hdr.hash_list_len);
367
368   proto_tree_add_uint(tree, hf_slot_num, tvb, offset, sizeof(hdr.slot_num), hdr.slot_num);
369   offset += sizeof(hdr.slot_num);
370
371   proto_tree_add_int(tree, hf_machine_num, tvb, offset, sizeof(hdr.machine_num), hdr.machine_num);
372   offset += sizeof(hdr.machine_num);
373
374   proto_tree_add_uint(tree, hf_seed, tvb, offset, sizeof(hdr.seed), hdr.seed);
375   offset += sizeof(hdr.seed);
376
377   proto_tree_add_uint(tree, hf_hash_len, tvb, offset, sizeof(hdr.hash_list_len), hdr.hash_list_len);
378   offset += sizeof(hdr.hash_list_len);
379
380 }
381
382 static void dissect_policy_change(tvbuff_t * tvb, int offset, proto_tree * tree) {
383   guint32 status;
384
385   status = tvb_get_ntohl(tvb, offset);
386
387   proto_tree_add_uint(tree, hf_status, tvb, offset, sizeof(status), status);
388   offset += sizeof(guint32);
389 }
390
391 static void dissect_probe(tvbuff_t * tvb, int offset, proto_tree * tree) {
392   guint32 ifn;
393
394   ifn = tvb_get_ntohl(tvb, offset);
395
396   proto_tree_add_uint(tree, hf_ifn, tvb, offset, sizeof(ifn), ifn);
397   offset += sizeof(guint32);
398 }
399
400 static void dissect_conf_reply(tvbuff_t * tvb, int offset, proto_tree * tree) {
401   struct conf_reply_hdr hdr;
402
403   tvb_memcpy(tvb, (guint8 *)&hdr, offset, sizeof(hdr));
404   hdr.num_reported_ifs = g_ntohl(hdr.num_reported_ifs);
405   hdr.is_if_trusted = g_ntohs(hdr.is_if_trusted);
406
407   proto_tree_add_uint(tree, hf_num_reported_ifs, tvb, offset, sizeof(hdr.num_reported_ifs), hdr.num_reported_ifs);
408   offset += sizeof(hdr.num_reported_ifs);
409   proto_tree_add_ether(tree, hf_ethernet_add, tvb, offset, 6, hdr.ethernet_add);
410   offset += 6;
411
412   proto_tree_add_boolean(tree, hf_is_if_trusted, tvb, offset, sizeof(hdr.is_if_trusted), hdr.is_if_trusted);
413   offset += sizeof(hdr.is_if_trusted);
414
415   proto_tree_add_ipv4(tree, hf_ip, tvb, offset, sizeof(hdr.ip), hdr.ip);
416   offset += 4;
417 }
418
419 int is_report_ifs(guint16 report_code) {
420   if(report_code & 2)
421         return 1;
422   return 0;
423 }
424
425 static const char *
426 report_code2str(guint16 report_code) {
427   int ret;
428   ret = is_report_ifs(report_code);
429   if(!(report_code & 1))
430         return "Machine information NOT present";
431   if(ret == 1)
432         return "Interface information included";
433   return "Unknown report code!";
434 }
435 static const char *
436 ha_magic_num2str(guint16 magic) {
437   if(magic == CPHA_MAGIC)
438         return "correct";
439   return NULL;
440 }
441
442 static const char *
443 version2str(guint16 version) {
444   switch(version) {
445         case 1: return "4.1";
446                 break;
447         case 6: return "NG Feature Pack 2";
448                 break;
449         case 530: return "NG Feature Pack 3";
450                 break;
451         case 540: return "NG with Application Intelligence (Early Availability)";
452                 break;
453         case 541: return "NG with Application Intelligence";
454                 break;
455         default: return "Unknown Version";
456         break;  
457   }
458   return NULL;
459 }
460 static const char *
461 opcode2str_short(guint16 opcode) {
462   if(opcode <= NUM_OPCODE_TYPES)
463         return opcode_type_str_short[opcode];
464   return opcode_type_str_short[0];
465 }
466
467 static const char *
468 ha_mode2str(guint16 hamode) {
469   if(hamode <= NUM_HA_MODES)
470         return ha_mode_str[hamode];
471   return "Unknown HA mode";
472 }
473
474 static const char *
475 state2str(guint8 state) {
476   if(state <= NUM_STATES)
477         return state_str[state];
478   return state_str[0];
479 }
480
481
482 static const char *
483 opcode2str_long(guint16 opcode) {
484   if(opcode <= NUM_OPCODE_TYPES)
485         return opcode_type_str_long[opcode];
486   return opcode_type_str_long[0];
487 }
488
489 void
490 proto_register_cpha(void)
491 {
492   static hf_register_info hf[] = {
493     { &hf_magic_number,
494     { "CPHAP Magic Number", "cphap.magic_number", FT_UINT16, BASE_HEX, NULL, 0x0, "CPHAP Magic Number", HFILL}},
495     { &hf_cpha_protocol_ver,
496     { "Protocol Version", "cphap.version", FT_UINT16, BASE_DEC, NULL, 0x0, "CPHAP Version", HFILL}},
497     { &hf_cluster_number,
498     { "Cluster Number", "cphap.cluster_number", FT_UINT16, BASE_DEC, NULL, 0x0, "Cluster Number", HFILL}},
499     { &hf_opcode,
500     { "OpCode", "cphap.opcode", FT_UINT16, BASE_DEC, NULL, 0x0, "OpCode", HFILL}},
501     { &hf_src_if_num,
502     { "Source Interface", "cphap.src_if", FT_UINT16, BASE_DEC, NULL, 0x0, "Source Interface", HFILL}},
503     { &hf_random_id,
504     { "Random ID", "cphap.random_id", FT_UINT16, BASE_DEC, NULL, 0x0, "Random ID", HFILL}},
505     { &hf_src_machine_id,
506     { "Source Machine ID", "cphap.src_id", FT_UINT16, BASE_DEC, NULL, 0x0, "Source Machine ID", HFILL}},
507     { &hf_dst_machine_id,
508     { "Destination Machine ID", "cphap.dst_id", FT_UINT16, BASE_DEC, NULL, 0x0, "Destination Machine ID", HFILL}},
509     { &hf_policy_id,
510     { "Policy ID", "cphap.policy_id", FT_UINT16, BASE_DEC, NULL, 0x0, "Policy ID", HFILL}},
511     { &hf_filler,
512     { "Filler", "cphap.filler", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
513     { &hf_id_num,
514     { "Number of IDs reported", "cphap.id_num", FT_UINT16, BASE_DEC, NULL, 0x0, "Number of IDs reported", HFILL}},
515     { &hf_report_code,
516     { "Report code", "cphap.id_num", FT_UINT16, BASE_DEC, NULL, 0x0, "Report Code", HFILL}},
517     { &hf_ha_mode,
518     { "HA mode", "cphap.ha_mode", FT_UINT16, BASE_DEC, NULL, 0x0, "HA Mode", HFILL}},
519     { &hf_ha_time_unit,
520     { "HA Time unit (ms)", "cphap.ha_time_unit", FT_UINT16, BASE_DEC, NULL, 0x0, "HA Time unit", HFILL}},
521     { &hf_num_reported_ifs,
522     { "Reported Interfaces", "cphap.reported_ifs", FT_UINT32, BASE_DEC, NULL, 0x0, "Reported Interfaces", HFILL}},
523     { &hf_ethernet_add,
524     { "Ethernet Address", "cphap.ethernet_addr", FT_ETHER, BASE_HEX, NULL, 0x0, "Ethernet Address", HFILL}},
525     { &hf_is_if_trusted,
526     { "Interface Trusted", "cphap.if_trusted", FT_BOOLEAN, BASE_DEC, NULL, 0x0, "Interface Trusted", HFILL}},
527     { &hf_ip,
528     { "IP Address", "cphap.ip", FT_IPv4, BASE_DEC, NULL, 0x0, "IP Address", HFILL}},
529     { &hf_slot_num,
530     { "Slot Number", "cphap.slot_num", FT_INT16, BASE_DEC, NULL, 0x0, "Slot Number", HFILL}},
531     { &hf_machine_num,
532     { "Machine Number", "cphap.machine_num", FT_INT16, BASE_DEC, NULL, 0x0, "Machine Number", HFILL}},
533     { &hf_seed,
534     { "Seed", "cphap.seed", FT_UINT32, BASE_DEC, NULL, 0x0, "Seed", HFILL}},
535     { &hf_hash_len,
536     { "Hash list length", "cphap.hash_len", FT_INT32, BASE_DEC, NULL, 0x0, "Hash list length", HFILL}},
537     { &hf_in_up_num,
538     { "Interfaces up in the Inbound", "cphap.in_up", FT_INT8, BASE_DEC, NULL, 0x0, "Interfaces up in the Inbound", HFILL}},
539     { &hf_in_assumed_up_num,
540     { "Interfaces assumed up in the Inbound", "cphap.in_assume_up", FT_INT8, BASE_DEC, NULL, 0x0, "", HFILL}},
541     { &hf_out_up_num,
542     { "Interfaces up in the Outbound", "cphap.out_up", FT_INT8, BASE_DEC, NULL, 0x0, "", HFILL}},
543     { &hf_out_assumed_up_num,
544     { "Interfaces assumed up in the Outbound", "cphap.out_assume_up", FT_INT8, BASE_DEC, NULL, 0x0, "", HFILL}},
545     { &hf_status,
546     { "Status", "cphap.status", FT_UINT32, BASE_DEC, VALS(status_vals), 0x0, "", HFILL}},
547     { &hf_ifn,
548     { "Interface Number", "cpha.ifn", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL}},
549   };
550   static gint *ett[] = {
551     &ett_cphap,
552   };
553
554   proto_cphap = proto_register_protocol("Check Point High Availability Protocol",
555                                                "CPHA", "cpha");
556   proto_register_field_array(proto_cphap, hf, array_length(hf));
557   proto_register_subtree_array(ett, array_length(ett));
558 }
559
560 void
561 proto_reg_handoff_cpha(void)
562 {
563   dissector_handle_t cpha_handle;
564
565   cpha_handle = new_create_dissector_handle(dissect_cpha, proto_cphap);
566   dissector_add("udp.port", UDP_PORT_CPHA, cpha_handle);
567 }