Don't guard col_set_str (COL_PROTOCOL) with col_check
[metze/wireshark/wip.git] / epan / dissectors / packet-dlm3.c
1 /* packet-dlm3.c
2  * Routines for dlm3 dissection
3  * Copyright 2007, Masatake YAMATO <jet@gyve.org>
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
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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
24  */
25
26 /* This dissector supports version 3.0 of the dlm(Distributed Lock Manager)
27    protocol
28
29    Actual implementation for the protocol is in linux kernel.
30    See files under linux/fs/dlm/ */
31
32 /*
33  * #defines are mostly copied from
34  * *.[ch] files in linux/fs/dlm/ and linux/include/linux/dlm.h
35  *
36  * dlm_internal.h:
37  * -----------------------------------------------------------------------
38  **  Copyright (C) Sistina Software, Inc.  1997-2003  All rights reserved.
39  **  Copyright (C) 2004-2005 Red Hat, Inc.  All rights reserved.
40  **
41  **  This copyrighted material is made available to anyone wishing to use,
42  **  modify, copy, or redistribute it subject to the terms and conditions
43  **  of the GNU General Public License v.2.
44  * -----------------------------------------------------------------------
45  */
46
47
48 #ifdef HAVE_CONFIG_H
49 # include "config.h"
50 #endif
51
52 #include <stdio.h>
53 #include <stdlib.h>
54 #include <string.h>
55
56 #include <glib.h>
57
58 #include <epan/packet.h>
59 #include <epan/prefs.h>
60
61
62
63 #define TCP_PORT_DLM3           21064
64 #define SCTP_PORT_DLM3          TCP_PORT_DLM3
65
66 #define DLM3_MAJOR_VERSION      0x00030000
67 #define DLM3_MINOR_VERSION      0x00000000
68
69 #define DLM3_MSG                1
70 #define DLM3_RCOM               2
71
72 #define DLM3_MSG_REQUEST        1
73 #define DLM3_MSG_CONVERT        2
74 #define DLM3_MSG_UNLOCK         3
75 #define DLM3_MSG_CANCEL         4
76 #define DLM3_MSG_REQUEST_REPLY  5
77 #define DLM3_MSG_CONVERT_REPLY  6
78 #define DLM3_MSG_UNLOCK_REPLY   7
79 #define DLM3_MSG_CANCEL_REPLY   8
80 #define DLM3_MSG_GRANT          9
81 #define DLM3_MSG_BAST           10
82 #define DLM3_MSG_LOOKUP         11
83 #define DLM3_MSG_REMOVE         12
84 #define DLM3_MSG_LOOKUP_REPLY   13
85 #define DLM3_MSG_PURGE          14
86
87 #define DLM3_LKF_NOQUEUE        0x00000001
88 #define DLM3_LKF_CANCEL         0x00000002
89 #define DLM3_LKF_CONVERT        0x00000004
90 #define DLM3_LKF_VALBLK         0x00000008
91 #define DLM3_LKF_QUECVT         0x00000010
92 #define DLM3_LKF_IVVALBLK       0x00000020
93 #define DLM3_LKF_CONVDEADLK     0x00000040
94 #define DLM3_LKF_PERSISTENT     0x00000080
95 #define DLM3_LKF_NODLCKWT       0x00000100
96 #define DLM3_LKF_NODLCKBLK      0x00000200
97 #define DLM3_LKF_EXPEDITE       0x00000400
98 #define DLM3_LKF_NOQUEUEBAST    0x00000800
99 #define DLM3_LKF_HEADQUE        0x00001000
100 #define DLM3_LKF_NOORDER        0x00002000
101 #define DLM3_LKF_ORPHAN         0x00004000
102 #define DLM3_LKF_ALTPR          0x00008000
103 #define DLM3_LKF_ALTCW          0x00010000
104 #define DLM3_LKF_FORCEUNLOCK    0x00020000
105 #define DLM3_LKF_TIMEOUT        0x00040000
106
107 #define DLM3_SBF_DEMOTED        0x01
108 #define DLM3_SBF_VALNOTVALID    0x02
109 #define DLM3_SBF_ALTMODE        0x04
110
111 #define DLM3_IFL_USER           0x00000001
112 #define DLM3_IFL_ORPHAN         0x00000002
113 /* They may not be used in receiver side.
114    --------------------------------------
115    #define DLM3_IFL_MSTCPY          0x00010000
116    #define DLM3_IFL_RESEND          0x00020000
117    #define DLM3_IFL_DEAD            0x00040000
118    #define DLM3_IFL_OVERLAP_UNLOCK  0x00080000
119    #define DLM3_IFL_OVERLAP_CANCEL  0x00100000
120    #define DLM3_IFL_ENDOFLIFE       0x00200000
121    #define DLM3_IFL_WATCH_TIMEWARN  0x00400000
122    #define DLM3_IFL_TIMEOUT_CANCEL  0x00800000
123    #define DLM3_IFL_DEADLOCK_CANCEL 0x01000000 */
124
125 #define DLM3_LKSTS_WAITING      1
126 #define DLM3_LKSTS_GRANTED      2
127 #define DLM3_LKSTS_CONVERT      3
128
129 #define DLM3_LOCK_IV            -1
130 #define DLM3_LOCK_NL            0
131 #define DLM3_LOCK_CR            1
132 #define DLM3_LOCK_CW            2
133 #define DLM3_LOCK_PR            3
134 #define DLM3_LOCK_PW            4
135 #define DLM3_LOCK_EX            5
136
137 #define DLM3_AST_COMP           1
138 #define DLM3_AST_BAST           2
139
140
141 /* see asm-generic/errno-base.h about LINUX_*  */
142 #define LINUX_EAGAIN            11
143 #define LINUX_ENOMEM            12
144 #define LINUX_INVAL             22
145
146 #define DLM3_ECANCEL            0x10001
147 #define DLM3_EUNLOCK            0x10002
148
149
150 #define DLM3_RCOM_STATUS        1
151 #define DLM3_RCOM_NAMES         2
152 #define DLM3_RCOM_LOOKUP        3
153 #define DLM3_RCOM_LOCK          4
154 #define DLM3_RCOM_STATUS_REPLY  5
155 #define DLM3_RCOM_NAMES_REPLY   6
156 #define DLM3_RCOM_LOOKUP_REPLY  7
157 #define DLM3_RCOM_LOCK_REPLY    8
158
159 #define DLM3_RS_NODES           0x00000001
160 #define DLM3_RS_NODES_ALL       0x00000002
161 #define DLM3_RS_DIR             0x00000004
162 #define DLM3_RS_DIR_ALL         0x00000008
163 #define DLM3_RS_LOCKS           0x00000010
164 #define DLM3_RS_LOCKS_ALL       0x00000020
165 #define DLM3_RS_DONE            0x00000040
166 #define DLM3_RS_DONE_ALL        0x00000080
167
168 #define DLM3_RESNAME_MAXLEN     64
169
170 /* Forward declaration we need below */
171 void proto_reg_handoff_dlm3(void);
172
173
174 /* Initialize the protocol and registered fields */
175 static int proto_dlm3 = -1;
176
177 /* fields for struct dlm_header(h) */
178 static int hf_dlm3_h_version   = -1;
179 static int hf_dlm3_h_major_version = -1;
180 static int hf_dlm3_h_minor_version = -1;
181 static int hf_dlm3_h_lockspace = -1;
182 static int hf_dlm3_h_nodeid    = -1;
183 static int hf_dlm3_h_length    = -1;
184 static int hf_dlm3_h_cmd       = -1;
185 static int hf_dlm3_h_pad       = -1;
186
187 /* fields for struct dlm_message(m) */
188 static int hf_dlm3_m_type         = -1;
189 static int hf_dlm3_m_nodeid       = -1;
190 static int hf_dlm3_m_pid          = -1;
191 static int hf_dlm3_m_lkid         = -1;
192 static int hf_dlm3_m_remid        = -1;
193 static int hf_dlm3_m_parent_lkid  = -1;
194 static int hf_dlm3_m_parent_remid = -1;
195
196 /* bit fields for dlm_message::exflags */
197 #define DLM3_DEFINE_HF_EXFLAGS(NAME)            \
198   static int hf_dlm3_##NAME      = -1;          \
199   static int hf_dlm3_##NAME##_noqueue     = -1; \
200   static int hf_dlm3_##NAME##_cancel      = -1; \
201   static int hf_dlm3_##NAME##_convert     = -1; \
202   static int hf_dlm3_##NAME##_valblk      = -1; \
203   static int hf_dlm3_##NAME##_quecvt      = -1; \
204   static int hf_dlm3_##NAME##_ivvalblk    = -1; \
205   static int hf_dlm3_##NAME##_convdeadlk  = -1; \
206   static int hf_dlm3_##NAME##_persistent  = -1; \
207   static int hf_dlm3_##NAME##_nodlckwt    = -1; \
208   static int hf_dlm3_##NAME##_nodlckblk   = -1; \
209   static int hf_dlm3_##NAME##_expedite    = -1; \
210   static int hf_dlm3_##NAME##_noqueuebast = -1; \
211   static int hf_dlm3_##NAME##_headque     = -1; \
212   static int hf_dlm3_##NAME##_noorder     = -1; \
213   static int hf_dlm3_##NAME##_orphan      = -1; \
214   static int hf_dlm3_##NAME##_altpr       = -1; \
215   static int hf_dlm3_##NAME##_altcw       = -1; \
216   static int hf_dlm3_##NAME##_forceunlock = -1; \
217   static int hf_dlm3_##NAME##_timeout     = -1
218 DLM3_DEFINE_HF_EXFLAGS(m_exflags);
219
220 /* bit fields for dlm_message::sbflags */
221 static int hf_dlm3_m_sbflags             = -1;
222 static int hf_dlm3_m_sbflags_demoted     = -1;
223 static int hf_dlm3_m_sbflags_valnotvalid = -1;
224 static int hf_dlm3_m_sbflags_altmode     = -1;
225
226 /* bit fields for dlm_message::flags */
227 #define DLM3_DEFINE_HF_FLAGS(NAME)              \
228   static int hf_dlm3_##NAME          = -1;      \
229   static int hf_dlm3_##NAME##_user   = -1;      \
230   static int hf_dlm3_##NAME##_orphan = -1
231 DLM3_DEFINE_HF_FLAGS(m_flags);
232
233 static int hf_dlm3_m_lvbseq       = -1;
234 static int hf_dlm3_m_hash         = -1;
235 static int hf_dlm3_m_status       = -1;
236 static int hf_dlm3_m_grmode       = -1;
237 static int hf_dlm3_m_rqmode       = -1;
238 static int hf_dlm3_m_bastmode     = -1;
239
240 /* bit fields for dlm_message::asts */
241 #define DLM3_DEFINE_HF_ASTS(NAME)                       \
242   static int hf_dlm3_##NAME##_asts         = -1;        \
243   static int hf_dlm3_##NAME##_asts_comp    = -1;        \
244   static int hf_dlm3_##NAME##_asts_bast    = -1
245 DLM3_DEFINE_HF_ASTS(m);
246
247 static int hf_dlm3_m_result       = -1;
248 static int hf_dlm3_m_extra        = -1;
249
250 /* fields for struct dlm_rcom(rc) */
251 static int hf_dlm3_rc_type      = -1;
252 static int hf_dlm3_rc_result    = -1;
253 static int hf_dlm3_rc_id        = -1;
254 static int hf_dlm3_rc_seq       = -1;
255 static int hf_dlm3_rc_seq_reply = -1;
256 static int hf_dlm3_rc_buf       = -1;
257
258 /* fields for struct rcom_config(rf) */
259 static int hf_dlm3_rf_lvblen    = -1;
260 DLM3_DEFINE_HF_EXFLAGS(rf_lsflags);
261 static int hf_dlm3_rf_unused    = -1;
262
263 /* fields for struct rcom_lock(rl) */
264 static int hf_dlm3_rl_ownpid        = -1;
265 static int hf_dlm3_rl_lkid          = -1;
266 static int hf_dlm3_rl_remid         = -1;
267 static int hf_dlm3_rl_parent_lkid   = -1;
268 static int hf_dlm3_rl_parent_remid  = -1;
269 DLM3_DEFINE_HF_EXFLAGS(rl_exflags);
270 DLM3_DEFINE_HF_FLAGS(rl_flags);
271 static int hf_dlm3_rl_lvbseq        = -1;
272 static int hf_dlm3_rl_result        = -1;
273 static int hf_dlm3_rl_rqmode        = -1;
274 static int hf_dlm3_rl_grmode        = -1;
275 static int hf_dlm3_rl_status        = -1;
276 DLM3_DEFINE_HF_ASTS(rl);
277 static int hf_dlm3_rl_wait_type     = -1;
278 static int hf_dlm3_rl_namelen       = -1;
279 static int hf_dlm3_rl_name          = -1;
280 static int hf_dlm3_rl_name_contents = -1;
281 static int hf_dlm3_rl_name_padding  = -1;
282 static int hf_dlm3_rl_lvb           = -1;
283
284 /* Initialize the subtree pointers */
285 static gint ett_dlm3         = -1;
286 static gint ett_dlm3_version = -1;
287
288 static gint ett_dlm3_msg       = -1;
289 static gint ett_dlm3_m_exflags = -1;
290 static gint ett_dlm3_sbflags   = -1;
291 static gint ett_dlm3_m_flags   = -1;
292 static gint ett_dlm3_m_asts    = -1;
293
294 static gint ett_dlm3_rcom        = -1;
295 static gint ett_dlm3_rcom_lock   = -1;
296 static gint ett_dlm3_rcom_config = -1;
297
298 static gint ett_dlm3_rf_lsflags  = -1;
299 static gint ett_dlm3_rl_exflags  = -1;
300 static gint ett_dlm3_rl_flags    = -1;
301 static gint ett_dlm3_rl_asts     = -1;
302 static gint ett_dlm3_rl_name     = -1;
303
304
305 /* configurable parameters */
306 static guint dlm3_tcp_port  = TCP_PORT_DLM3;
307 static guint dlm3_sctp_port = SCTP_PORT_DLM3;
308
309 /*
310  * Value strings
311  */
312 static const value_string dlm3_cmd[] = {
313   { DLM3_MSG,  "message"          },
314   { DLM3_RCOM, "recovery command" },
315   { 0,         NULL               }
316 };
317
318 static const value_string dlm3_msg[] = {
319   { DLM3_MSG_REQUEST,       "request message"    },
320   { DLM3_MSG_CONVERT,       "conversion message" },
321   { DLM3_MSG_UNLOCK,        "unlock message"     },
322   { DLM3_MSG_CANCEL,        "cancel message"     },
323   { DLM3_MSG_REQUEST_REPLY, "request reply"      },
324   { DLM3_MSG_CONVERT_REPLY, "conversion reply"   },
325   { DLM3_MSG_UNLOCK_REPLY,  "unlock reply"       },
326   { DLM3_MSG_CANCEL_REPLY,  "cancel reply"       },
327   { DLM3_MSG_GRANT,         "grant message"      },
328   { DLM3_MSG_BAST,          "bast message"       },
329   { DLM3_MSG_LOOKUP,        "lookup message"     },
330   { DLM3_MSG_REMOVE,        "remove message"     },
331   { DLM3_MSG_LOOKUP_REPLY,  "lookup reply"       },
332   { DLM3_MSG_PURGE,         "purge orphans"      },
333   { 0,                      NULL                 }
334 };
335
336 static const value_string dlm3_status[] = {
337   { DLM3_LKSTS_WAITING, "waiting"  },
338   { DLM3_LKSTS_GRANTED, "granted"  },
339   { DLM3_LKSTS_CONVERT, "convert"  },
340   { 0,                  NULL       }
341 };
342
343 static const value_string dlm3_mode[] = {
344   { DLM3_LOCK_IV, "invalid"          },
345   { DLM3_LOCK_NL, "null"             },
346   { DLM3_LOCK_CR, "concurrent read"  },
347   { DLM3_LOCK_CW, "concurrent write" },
348   { DLM3_LOCK_PR, "protected read"   },
349   { DLM3_LOCK_PW, "protected write"  },
350   { DLM3_LOCK_EX, "exclusive"        },
351   { 0,            NULL               }
352 };
353
354 static const value_string dlm3_result[] = {
355   { -LINUX_EAGAIN, "blocked"                       },
356   { -LINUX_ENOMEM, "no memory"                     },
357   { -LINUX_INVAL,  "invalid parameters"            },
358   { -DLM3_ECANCEL, "cancel completed successfully" },
359   { -DLM3_EUNLOCK, "unlock request was successful" },
360   { 0,             "successful"                    },
361   { 0,             NULL                            }
362 };
363
364 static const value_string dlm3_rcom[] = {
365   { DLM3_RCOM_STATUS,       "status command" },
366   { DLM3_RCOM_NAMES,        "names command"  },
367   { DLM3_RCOM_LOOKUP,       "lookup command" },
368   { DLM3_RCOM_LOCK,         "lock command"   },
369   { DLM3_RCOM_STATUS_REPLY, "status reply"   },
370   { DLM3_RCOM_NAMES_REPLY,  "names reply"    },
371   { DLM3_RCOM_LOOKUP_REPLY, "lookup reply"   },
372   { DLM3_RCOM_LOCK_REPLY,   "lock reply"     },
373   { 0,                      NULL             }
374 };
375
376 static const value_string dlm3_rs[] = {
377   { DLM3_RS_NODES,     "recovering nodes"                    },
378   { DLM3_RS_NODES_ALL, "recovering all nodes"                },
379   { DLM3_RS_DIR,       "recovering resource directory"       },
380   { DLM3_RS_DIR_ALL,   "recovering all resource directories" },
381   { DLM3_RS_LOCKS,     "recovering lock"                     },
382   { DLM3_RS_LOCKS_ALL, "recovering all locks"                },
383   { DLM3_RS_DONE,      "recovering is done"                  },
384   { DLM3_RS_DONE_ALL,  "all recovering is done"              },
385   { 0,                 NULL                                  }
386 };
387
388 /*
389  * Fields
390  */
391 #define DLM3_DEFINE_EXFLAGS_FIELDS(NAME)        \
392   static const int* NAME##_fields[] = {         \
393     &hf_dlm3_##NAME##_timeout ,                 \
394     &hf_dlm3_##NAME##_forceunlock ,             \
395     &hf_dlm3_##NAME##_altcw       ,             \
396     &hf_dlm3_##NAME##_altpr       ,             \
397     &hf_dlm3_##NAME##_orphan      ,             \
398     &hf_dlm3_##NAME##_noorder     ,             \
399     &hf_dlm3_##NAME##_headque     ,             \
400     &hf_dlm3_##NAME##_noqueuebast ,             \
401     &hf_dlm3_##NAME##_expedite    ,             \
402     &hf_dlm3_##NAME##_nodlckblk   ,             \
403     &hf_dlm3_##NAME##_nodlckwt    ,             \
404     &hf_dlm3_##NAME##_persistent  ,             \
405     &hf_dlm3_##NAME##_convdeadlk  ,             \
406     &hf_dlm3_##NAME##_ivvalblk    ,             \
407     &hf_dlm3_##NAME##_quecvt      ,             \
408     &hf_dlm3_##NAME##_valblk      ,             \
409     &hf_dlm3_##NAME##_convert     ,             \
410     &hf_dlm3_##NAME##_cancel      ,             \
411     &hf_dlm3_##NAME##_noqueue     ,             \
412     NULL                                        \
413   }
414 DLM3_DEFINE_EXFLAGS_FIELDS(m_exflags);
415
416 static const int *m_sbflags_fields[] = {
417   &hf_dlm3_m_sbflags_altmode     ,
418   &hf_dlm3_m_sbflags_valnotvalid ,
419   &hf_dlm3_m_sbflags_demoted     ,
420   NULL
421 };
422
423 #define DLM3_DEFINE_FLAGS_FIELDS(NAME)          \
424   static const int* NAME##_fields[] = {         \
425     &hf_dlm3_##NAME##_orphan        ,           \
426     &hf_dlm3_##NAME##_user          ,           \
427     NULL                                        \
428   }
429 DLM3_DEFINE_FLAGS_FIELDS(m_flags);
430
431 #define DLM3_DEFINE_ASTS_FIELDS(NAME)           \
432   static const int* NAME##_asts_fields[] = {    \
433     &hf_dlm3_##NAME##_asts_bast           ,     \
434     &hf_dlm3_##NAME##_asts_comp           ,     \
435     NULL                                        \
436   }
437 DLM3_DEFINE_ASTS_FIELDS(m);
438
439 DLM3_DEFINE_EXFLAGS_FIELDS(rf_lsflags);
440
441 DLM3_DEFINE_EXFLAGS_FIELDS(rl_exflags);
442 DLM3_DEFINE_FLAGS_FIELDS(rl_flags);
443 DLM3_DEFINE_ASTS_FIELDS(rl);
444
445 /* Code to actually dissect the packets */
446 static void
447 dissect_dlm3_msg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
448                  guint length, int offset)
449 {
450   guint32     m_type;
451   proto_item *sub_item;
452
453   m_type   = tvb_get_letohl(tvb, offset);
454   proto_tree_add_uint(tree,
455                       hf_dlm3_m_type, tvb, offset, 4, m_type);
456   if (check_col(pinfo->cinfo, COL_INFO))
457     col_append_fstr(pinfo->cinfo, COL_INFO,
458                     ": %s",
459                     val_to_str(m_type,
460                                dlm3_msg,
461                                "Unknown"));
462
463   offset += 4;
464   proto_tree_add_item(tree,
465                       hf_dlm3_m_nodeid, tvb, offset, 4, TRUE);
466
467   offset += 4;
468   proto_tree_add_item(tree,
469                       hf_dlm3_m_pid, tvb, offset, 4, TRUE);
470
471   offset += 4;
472   proto_tree_add_item(tree,
473                       hf_dlm3_m_lkid, tvb, offset, 4, TRUE);
474   /* TODO: See `create_lkb'
475      lkid has some structure. We dissect more. */
476
477   offset += 4;
478   proto_tree_add_item(tree,
479                       hf_dlm3_m_remid, tvb, offset, 4, TRUE);
480
481   offset += 4;
482   proto_tree_add_item(tree,
483                       hf_dlm3_m_parent_lkid, tvb, offset, 4, TRUE);
484
485   offset += 4;
486   proto_tree_add_item(tree,
487                       hf_dlm3_m_parent_remid, tvb, offset, 4, TRUE);
488
489   offset += 4;
490   proto_tree_add_bitmask(tree, tvb, offset,
491                          hf_dlm3_m_exflags, ett_dlm3_m_exflags,
492                          m_exflags_fields, TRUE);
493
494   offset += 4;
495   proto_tree_add_bitmask(tree, tvb, offset,
496                          hf_dlm3_m_sbflags, ett_dlm3_sbflags,
497                          m_sbflags_fields, TRUE);
498
499   offset += 4;
500   proto_tree_add_bitmask(tree, tvb, offset,
501                          hf_dlm3_m_flags, ett_dlm3_m_flags,
502                          m_flags_fields, TRUE);
503
504   offset += 4;
505   proto_tree_add_item(tree,
506                       hf_dlm3_m_lvbseq, tvb, offset, 4, TRUE);
507
508   offset += 4;
509   proto_tree_add_item(tree,
510                       hf_dlm3_m_hash, tvb, offset, 4, TRUE);
511
512   offset += 4;
513   proto_tree_add_item(tree,
514                       hf_dlm3_m_status, tvb, offset, 4, TRUE);
515
516   offset += 4;
517   proto_tree_add_item(tree,
518                       hf_dlm3_m_grmode, tvb, offset, 4, TRUE);
519
520   offset += 4;
521   proto_tree_add_item(tree,
522                       hf_dlm3_m_rqmode, tvb, offset, 4, TRUE);
523
524   offset += 4;
525   proto_tree_add_item(tree,
526                       hf_dlm3_m_bastmode, tvb, offset, 4, TRUE);
527
528
529   offset += 4;
530   proto_tree_add_bitmask(tree, tvb, offset,
531                          hf_dlm3_m_asts, ett_dlm3_m_asts,
532                          m_asts_fields, TRUE);
533   offset += 4;
534   proto_tree_add_item(tree,
535                       hf_dlm3_m_result, tvb, offset, 4, TRUE);
536
537   offset += 4;
538   if ((length - offset) > 0) {
539     sub_item = proto_tree_add_item(tree,
540                                    hf_dlm3_m_extra,
541                                    tvb,
542                                    offset,
543                                    -1,
544                                    TRUE);
545   }
546 }
547
548
549
550 static void
551 dissect_dlm3_rcom_lock(tvbuff_t *tvb, proto_tree *tree,
552                        guint length, int offset)
553 {
554   proto_item *sub_item;
555   proto_tree *sub_tree;
556   int         sub_offset;
557   guint16     namelen;
558   guint32     exflags;
559
560
561   if ((length - offset) < ( 4 * 8 + 4 + 1 * 4 + 2 * 2
562                             + DLM3_RESNAME_MAXLEN ))
563     return;
564
565
566   proto_tree_add_item(tree,
567                       hf_dlm3_rl_ownpid, tvb, offset, 4, TRUE);
568
569   offset += 4;
570   proto_tree_add_item(tree,
571                       hf_dlm3_rl_lkid, tvb, offset, 4, TRUE);
572
573   offset += 4;
574   proto_tree_add_item(tree,
575                       hf_dlm3_rl_remid, tvb, offset, 4, TRUE);
576
577   offset += 4;
578   proto_tree_add_item(tree,
579                       hf_dlm3_rl_parent_lkid, tvb, offset, 4, TRUE);
580
581   offset += 4;
582   proto_tree_add_item(tree,
583                       hf_dlm3_rl_parent_remid, tvb, offset, 4, TRUE);
584
585   offset += 4;
586   proto_tree_add_bitmask(tree, tvb, offset,
587                          hf_dlm3_rl_exflags, ett_dlm3_rl_exflags,
588                          rl_exflags_fields, TRUE);
589   exflags = tvb_get_letohl(tvb, offset);
590
591
592   offset += 4;
593   proto_tree_add_bitmask(tree, tvb, offset,
594                          hf_dlm3_rl_flags, ett_dlm3_rl_flags,
595                          rl_flags_fields, TRUE);
596
597   offset += 4;
598   proto_tree_add_item(tree,
599                       hf_dlm3_rl_lvbseq, tvb, offset, 4, TRUE);
600
601   offset += 4;
602   proto_tree_add_item(tree,
603                       hf_dlm3_rl_result, tvb, offset, 4, TRUE);
604
605   offset += 4;
606   proto_tree_add_item(tree,
607                       hf_dlm3_rl_rqmode, tvb, offset, 1, TRUE);
608
609   offset += 1;
610   proto_tree_add_item(tree,
611                       hf_dlm3_rl_grmode, tvb, offset, 1, TRUE);
612
613   offset += 1;
614   proto_tree_add_item(tree,
615                       hf_dlm3_rl_status, tvb, offset, 1, TRUE);
616
617   offset += 1;
618   proto_tree_add_bitmask(tree, tvb, offset,
619                          hf_dlm3_rl_asts, ett_dlm3_rl_asts,
620                          rl_asts_fields, TRUE);
621
622   offset += 1;
623   proto_tree_add_item(tree,
624                       hf_dlm3_rl_wait_type, tvb, offset, 2, TRUE);
625
626   offset += 2;
627   namelen = tvb_get_letohs(tvb, offset);
628   proto_tree_add_uint(tree,
629                       hf_dlm3_rl_namelen, tvb, offset, 2,
630                       namelen);
631
632   offset += 2;
633   sub_item = proto_tree_add_item(tree,
634                                  hf_dlm3_rl_name, tvb, offset,
635                                  DLM3_RESNAME_MAXLEN, TRUE);
636
637   sub_tree = proto_item_add_subtree(sub_item,
638                                     ett_dlm3_rl_name);
639   sub_offset = offset;
640   proto_tree_add_item(sub_tree,
641                       hf_dlm3_rl_name_contents, tvb, sub_offset,
642                       namelen, TRUE);
643
644   sub_offset += namelen;
645   proto_tree_add_item(sub_tree,
646                       hf_dlm3_rl_name_padding, tvb, sub_offset,
647                       DLM3_RESNAME_MAXLEN - namelen, TRUE);
648
649   offset += DLM3_RESNAME_MAXLEN;
650   if (((length - offset) > 0) && (exflags & DLM3_LKF_VALBLK))
651     proto_tree_add_item(tree,
652                         hf_dlm3_rl_lvb, tvb, offset,
653                         -1,
654                         TRUE);
655 }
656
657
658 static void
659 dissect_dlm3_rcom_config(tvbuff_t *tvb, proto_tree *tree,
660                          guint length, int offset)
661 {
662   if ((length - offset) < ( 4 + 4 + 8 ))
663     return;
664
665   proto_tree_add_item(tree,
666                       hf_dlm3_rf_lvblen, tvb, offset, 4, TRUE);
667
668   offset += 4;
669   proto_tree_add_bitmask(tree, tvb, offset,
670                          hf_dlm3_rf_lsflags, ett_dlm3_rf_lsflags,
671                          rf_lsflags_fields, TRUE);
672
673   offset += 4;
674   proto_tree_add_item(tree,
675                       hf_dlm3_rf_unused, tvb, offset, 8, TRUE);
676
677
678   offset += 8;
679   /* END */
680 }
681
682 static void
683 dissect_dlm3_rcom(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
684                   guint length, int offset)
685 {
686   guint32     rc_type;
687
688   proto_item *sub_item;
689   proto_tree *sub_tree;
690
691
692   rc_type  = tvb_get_letohl(tvb, offset);
693   proto_tree_add_uint(tree,
694                       hf_dlm3_rc_type, tvb, offset, 4, rc_type);
695   if (check_col(pinfo->cinfo, COL_INFO))
696     col_append_fstr(pinfo->cinfo, COL_INFO,
697                     ": %s",
698                     val_to_str(rc_type,
699                                dlm3_rcom,
700                                "Unknown"));
701
702   offset += 4;
703   proto_tree_add_item(tree,
704                       hf_dlm3_rc_result, tvb, offset, 4, TRUE);
705
706   offset += 4;
707   proto_tree_add_item(tree,
708                       hf_dlm3_rc_id, tvb, offset, 8, TRUE);
709
710   offset += 8;
711   proto_tree_add_item(tree,
712                       hf_dlm3_rc_seq, tvb, offset, 8, TRUE);
713
714   offset += 8;
715   proto_tree_add_item(tree,
716                       hf_dlm3_rc_seq_reply, tvb, offset, 8, TRUE);
717
718   offset += 8;
719   if ((length - offset) == 0) {
720     /* No rc_buf: Just return */
721     return;
722   }
723
724   /* Decode rc_buf */
725   sub_item = proto_tree_add_item(tree,
726                                  hf_dlm3_rc_buf,
727                                  tvb,
728                                  offset,
729                                  -1,
730                                  TRUE);
731
732   offset += 0;
733   if (rc_type == DLM3_RCOM_LOCK) {
734     sub_tree = proto_item_add_subtree(sub_item,
735                                       ett_dlm3_rcom_lock);
736     dissect_dlm3_rcom_lock(tvb, sub_tree, length, offset);
737   } else if (rc_type == DLM3_RCOM_STATUS_REPLY) {
738     sub_tree = proto_item_add_subtree(sub_item,
739                                       ett_dlm3_rcom_config);
740     dissect_dlm3_rcom_config(tvb, sub_tree, length, offset);
741   }
742
743 }
744
745 static int
746 dissect_dlm3(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
747 {
748   proto_item *item, *sub_item;
749   proto_tree *tree, *sub_tree;
750
751   int        offset;
752   guint      length;
753   guint32    h_version;
754   guint8     h_cmd;
755
756
757   /* Check that there's enough data */
758   length = tvb_length(tvb);
759   if (length < 4 + 4 + 4 + 2 + 1 + 1)
760     return 0;
761
762   /* Check the protocol version  */
763   h_version = tvb_get_letohl(tvb, 0);
764   if (h_version != (DLM3_MAJOR_VERSION|DLM3_MINOR_VERSION))
765     return 0;
766
767   /* Check the command */
768   h_cmd = tvb_get_guint8(tvb, 4 + 4 + 4 + 2) ;
769   if ((h_cmd != DLM3_MSG) && (h_cmd != DLM3_RCOM))
770     return 0;
771
772   if ((h_cmd == DLM3_MSG) && (length < ((4 + 4 + 4 + 2 + 1 + 1)
773                                         + (4 * 12 + 4 * 6))))
774     return 0;
775   else if ((h_cmd == DLM3_RCOM) && (length < 4 + 4 + 8 + 8 + 8))
776     return 0;
777
778
779   col_set_str(pinfo->cinfo, COL_PROTOCOL, "DLM3");
780
781
782   if (check_col(pinfo->cinfo, COL_INFO))
783     col_clear(pinfo->cinfo, COL_INFO);
784   if (check_col(pinfo->cinfo, COL_INFO))
785     col_set_str(pinfo->cinfo, COL_INFO,
786                 "DLM3");
787
788   if (check_col(pinfo->cinfo, COL_INFO))
789     col_set_str(pinfo->cinfo, COL_INFO,
790                 val_to_str(h_cmd,
791                            dlm3_cmd,
792                            "packet-dlm3.c internal bug"));
793
794   if (parent_tree) {
795     offset = 0;
796
797     item = proto_tree_add_item(parent_tree, proto_dlm3, tvb, offset,
798                                -1, TRUE);
799     tree = proto_item_add_subtree(item, ett_dlm3);
800
801     sub_item = proto_tree_add_uint(tree,
802                                    hf_dlm3_h_version, tvb, offset, 4,
803                                    h_version);
804     sub_tree = proto_item_add_subtree(sub_item, ett_dlm3_version);
805     proto_tree_add_uint(sub_tree,
806                         hf_dlm3_h_major_version, tvb, offset + 0, 2,
807                         (h_version & 0xFFFF0000) >> 16);
808     proto_tree_add_uint(sub_tree,
809                         hf_dlm3_h_minor_version, tvb, offset + 2, 2,
810                         (h_version & 0x0000FFFF));
811
812
813     offset += 4;
814     proto_tree_add_item(tree,
815                         hf_dlm3_h_lockspace, tvb, offset, 4, TRUE);
816
817     offset += 4;
818     proto_tree_add_item(tree,
819                         hf_dlm3_h_nodeid, tvb, offset, 4, TRUE);
820     offset += 4;
821     proto_tree_add_item(tree,
822                         hf_dlm3_h_length, tvb, offset, 2, TRUE);
823
824     offset += 2;
825     sub_item = proto_tree_add_uint(tree,
826                                    hf_dlm3_h_cmd, tvb, offset, 1, h_cmd);
827
828     offset += 1;
829     proto_tree_add_item(tree,
830                         hf_dlm3_h_pad, tvb, offset, 1, TRUE);
831
832
833     offset += 1;
834     if (h_cmd == DLM3_MSG) {
835       sub_tree = proto_item_add_subtree(sub_item, ett_dlm3_msg);
836       dissect_dlm3_msg(tvb, pinfo, sub_tree, length, offset);
837     } else if (h_cmd== DLM3_RCOM) {
838       sub_tree = proto_item_add_subtree(sub_item, ett_dlm3_rcom);
839       dissect_dlm3_rcom(tvb, pinfo, sub_item, length, offset);
840     }
841   }
842   return tvb_length(tvb);
843 }
844
845
846 /* Register the protocol with Wireshark */
847
848 #define DLM3_REGISTER_HF_LOCKID(NAME)                                   \
849   { &hf_dlm3_##NAME##_lkid,                                             \
850       { "Lock ID on Sender", "dlm3." #NAME ".lkid",                     \
851           FT_UINT32, BASE_DEC_HEX, NULL, 0x0,                           \
852           NULL, HFILL}},                                                \
853 { &hf_dlm3_##NAME##_remid,                                              \
854     { "Lock ID on Receiver", "dlm3." #NAME ".remid",                    \
855         FT_UINT32, BASE_DEC_HEX, NULL, 0x0,                             \
856         NULL, HFILL}},                                                  \
857 { &hf_dlm3_##NAME##_parent_lkid,                                        \
858     { "Parent Lock ID on Sender", "dlm3." #NAME ".parent_lkid",         \
859         FT_UINT32, BASE_DEC_HEX, NULL, 0x0,                             \
860         NULL, HFILL}},                                                  \
861 { &hf_dlm3_##NAME##_parent_remid,                                       \
862     { "Parent Lock ID on Receiver", "dlm3." #NAME ".parent_remid",      \
863         FT_UINT32, BASE_DEC_HEX, NULL, 0x0,                             \
864         NULL, HFILL}}
865
866 #define DLM3_REGISTER_HF_EXFLAGS(SYMNAME,STRNAME)                       \
867 { &hf_dlm3_##SYMNAME,                                                   \
868   { "External Flags", "dlm3." STRNAME "",                               \
869     FT_UINT32, BASE_HEX, NULL, 0x0,                                     \
870     NULL, HFILL}},                                                      \
871 { &hf_dlm3_##SYMNAME##_noqueue,                                         \
872   { "Don't queue", "dlm3." STRNAME ".noqueue",                          \
873     FT_BOOLEAN, 32, NULL, DLM3_LKF_NOQUEUE,                             \
874     NULL, HFILL}},                                                      \
875 { &hf_dlm3_##SYMNAME##_cancel,                                          \
876   { "Cancel", "dlm3." STRNAME ".cancel",                                \
877     FT_BOOLEAN, 32, NULL, DLM3_LKF_CANCEL,                              \
878     NULL, HFILL}},                                                      \
879 { &hf_dlm3_##SYMNAME##_convert,                                         \
880   { "Convert", "dlm3." STRNAME ".convert",                              \
881     FT_BOOLEAN, 32, NULL, DLM3_LKF_CONVERT,                             \
882     NULL, HFILL}},                                                      \
883 { &hf_dlm3_##SYMNAME##_valblk,                                          \
884   { "Return the contents of the lock value block", "dlm3." STRNAME ".valblk", \
885     FT_BOOLEAN, 32, NULL, DLM3_LKF_VALBLK,                              \
886     NULL, HFILL}},                                                      \
887 { &hf_dlm3_##SYMNAME##_quecvt,                                          \
888   { "Force a conversion request to be queued", "dlm3." STRNAME ".quecvt", \
889     FT_BOOLEAN, 32, NULL, DLM3_LKF_QUECVT,                              \
890     NULL, HFILL}},                                                      \
891 { &hf_dlm3_##SYMNAME##_ivvalblk,                                        \
892   { "Invalidate the lock value block", "dlm3." STRNAME ".ivvalblk",     \
893     FT_BOOLEAN, 32, NULL, DLM3_LKF_IVVALBLK,                            \
894     NULL, HFILL}},                                                      \
895 { &hf_dlm3_##SYMNAME##_convdeadlk,                                      \
896   { "Forced down to NL to resolve a conversion deadlock", "dlm3." STRNAME ".convdeadlk", \
897     FT_BOOLEAN, 32, NULL, DLM3_LKF_CONVDEADLK,                          \
898     NULL, HFILL}},                                                      \
899 { &hf_dlm3_##SYMNAME##_persistent,                                      \
900   { "Persistent", "dlm3." STRNAME ".persistent",                        \
901     FT_BOOLEAN, 32, NULL, DLM3_LKF_PERSISTENT,                          \
902     NULL, HFILL}},                                                      \
903 { &hf_dlm3_##SYMNAME##_nodlckwt,                                        \
904   { "Don't cancel the lock if it gets into conversion deadlock", "dlm3." STRNAME ".nodlckwt", \
905     FT_BOOLEAN, 32, NULL, DLM3_LKF_NODLCKWT,                            \
906     NULL, HFILL}},                                                      \
907 { &hf_dlm3_##SYMNAME##_nodlckblk,                                       \
908   { "Nodlckblk", "dlm3." STRNAME ".nodlckblk",                          \
909     FT_BOOLEAN, 32, NULL, DLM3_LKF_NODLCKBLK,                           \
910     NULL, HFILL}},                                                      \
911 { &hf_dlm3_##SYMNAME##_expedite,                                        \
912   { "Grant a NL lock immediately", "dlm3." STRNAME ".expedite",         \
913     FT_BOOLEAN, 32, NULL, DLM3_LKF_EXPEDITE,                            \
914     NULL, HFILL}},                                                      \
915 { &hf_dlm3_##SYMNAME##_noqueuebast,                                     \
916   { "Send blocking ASTs even for NOQUEUE operations", "dlm3." STRNAME ".noqueuebast", \
917     FT_BOOLEAN, 32, NULL, DLM3_LKF_NOQUEUEBAST,                         \
918     NULL, HFILL}},                                                      \
919 { &hf_dlm3_##SYMNAME##_headque,                                         \
920   { "Add a lock to the head of the queue", "dlm3." STRNAME ".headque",  \
921     FT_BOOLEAN, 32, NULL, DLM3_LKF_HEADQUE,                             \
922     NULL, HFILL}},                                                      \
923 { &hf_dlm3_##SYMNAME##_noorder,                                         \
924   { "Disregard the standard grant order rules", "dlm3." STRNAME ".noorder", \
925     FT_BOOLEAN, 32, NULL, DLM3_LKF_NOORDER,                             \
926     NULL, HFILL}},                                                      \
927 { &hf_dlm3_##SYMNAME##_orphan,                                          \
928   { "Orphan", "dlm3." STRNAME ".orphan",                                \
929     FT_BOOLEAN, 32, NULL, DLM3_LKF_ORPHAN,                              \
930     NULL, HFILL}},                                                      \
931 { &hf_dlm3_##SYMNAME##_altpr,                                           \
932   { "Try to grant the lock in `protected read' mode", "dlm3." STRNAME ".altpr", \
933     FT_BOOLEAN, 32, NULL, DLM3_LKF_ALTPR,                               \
934     NULL, HFILL}},                                                      \
935 { &hf_dlm3_##SYMNAME##_altcw,                                           \
936   { "Try to grant the lock in `concurrent read' mode", "dlm3." STRNAME ".altcw", \
937     FT_BOOLEAN, 32, NULL, DLM3_LKF_ALTCW,                               \
938     NULL, HFILL}},                                                      \
939 { &hf_dlm3_##SYMNAME##_forceunlock,                                     \
940   { "Force unlock", "dlm3." STRNAME ".forceunlock",                     \
941     FT_BOOLEAN, 32, NULL, DLM3_LKF_FORCEUNLOCK,                         \
942     NULL, HFILL}},                                                      \
943 { &hf_dlm3_##SYMNAME##_timeout,                                         \
944   { "Timeout", "dlm3." STRNAME ".timeout",                              \
945     FT_BOOLEAN, 32, NULL, DLM3_LKF_TIMEOUT,                             \
946     NULL, HFILL}}
947
948
949 #define DLM3_REGISTER_HF_FLAGS(SYMNAME,STRNAME)         \
950 { &hf_dlm3_##SYMNAME,                                   \
951   { "Internal Flags", "dlm3." STRNAME,                  \
952     FT_UINT32, BASE_HEX, NULL, 0x0,                     \
953     NULL, HFILL}},                                      \
954 { &hf_dlm3_##SYMNAME##_user,                            \
955   { "User space lock realted", "dlm3." STRNAME ".user", \
956     FT_BOOLEAN, 32, NULL, DLM3_IFL_USER,                \
957     NULL, HFILL}},                                      \
958 { &hf_dlm3_##SYMNAME##_orphan,                          \
959   { "Orphaned lock", "dlm3." STRNAME ".orphan",         \
960     FT_BOOLEAN, 32, NULL, DLM3_IFL_ORPHAN,              \
961     NULL, HFILL}}
962
963 #define DLM3_REGISTER_HF_ASTS(NAME,SIZE)         \
964 { &hf_dlm3_##NAME##_asts,                        \
965   { "Asynchronous Traps", "dlm3." #NAME ".asts", \
966     FT_UINT##SIZE, BASE_HEX, NULL, 0x0,           \
967     NULL, HFILL}},                               \
968 { &hf_dlm3_##NAME##_asts_comp,                   \
969   { "Completion", "dlm3." #NAME ".asts.comp",    \
970     FT_BOOLEAN, SIZE, NULL, DLM3_AST_COMP,       \
971     NULL, HFILL }},                              \
972 { &hf_dlm3_##NAME##_asts_bast,                   \
973   { "Blocking", "dlm3." #NAME ".asts.bast",      \
974     FT_BOOLEAN, SIZE, NULL, DLM3_AST_BAST,       \
975     NULL, HFILL }}
976
977 void
978 proto_register_dlm3(void)
979 {
980   module_t *dlm3_module;
981
982
983   static hf_register_info hf[] = {
984     /* dlm_header */
985     { &hf_dlm3_h_version,
986       { "Version", "dlm3.h.version",
987         FT_UINT32, BASE_HEX, NULL, 0x0,
988         NULL, HFILL }},
989     { &hf_dlm3_h_major_version,
990       { "Major Version", "dlm3.h.major_version",
991         FT_UINT16, BASE_HEX, NULL, 0x0,
992         NULL, HFILL }},
993     { &hf_dlm3_h_minor_version,
994       { "Minor Version", "dlm3.h.minor_version",
995         FT_UINT16, BASE_HEX, NULL, 0x0,
996         NULL, HFILL }},
997     { &hf_dlm3_h_lockspace,
998       { "Lockspace Global ID", "dlm3.h.lockspac",
999         FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
1000         NULL, HFILL }},
1001     { &hf_dlm3_h_nodeid,
1002       { "Sender Node ID", "dlm3.h.nodeid",
1003         FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
1004         NULL, HFILL }},
1005     { &hf_dlm3_h_length,
1006       { "Length", "dlm3.h.length",
1007         FT_UINT16, BASE_DEC, NULL, 0x0,
1008         NULL, HFILL }},
1009     { &hf_dlm3_h_cmd,
1010       { "Command", "dlm3.h.cmd",
1011         FT_UINT8, BASE_DEC, VALS(dlm3_cmd), 0x0,
1012         NULL, HFILL }},
1013     { &hf_dlm3_h_pad,
1014       { "Padding", "dlm3.h.pad",
1015         FT_UINT8, BASE_DEC, NULL, 0x0,
1016         NULL, HFILL }},
1017
1018     /* dlm_message */
1019     { &hf_dlm3_m_type,
1020       { "Message Type", "dlm3.m.type",
1021         FT_UINT32, BASE_DEC, VALS(dlm3_msg), 0x0,
1022         NULL, HFILL }},
1023     { &hf_dlm3_m_nodeid,
1024       { "Receiver Node ID", "dlm3.m.nodeid",
1025         FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
1026         NULL, HFILL }},
1027     { &hf_dlm3_m_pid,
1028       { "Process ID of Lock Owner", "dlm3.m.pid",
1029         FT_UINT32, BASE_DEC, NULL, 0x0,
1030         NULL, HFILL }},
1031     DLM3_REGISTER_HF_LOCKID(m),
1032
1033     /* dlm_message::exflags */
1034     DLM3_REGISTER_HF_EXFLAGS(m_exflags, "m.exflags"),
1035
1036     /* dlm_message::sbflags */
1037     { &hf_dlm3_m_sbflags,
1038       { "Status Block Flags", "dlm3.m.sbflags",
1039         FT_UINT32, BASE_HEX, NULL, 0x0,
1040         NULL, HFILL}},
1041     { &hf_dlm3_m_sbflags_demoted,
1042       { "Demoted for deadlock resolution", "dlm3.m.sbflags.demoted",
1043         FT_BOOLEAN, 32, NULL, DLM3_SBF_DEMOTED,
1044         NULL, HFILL}},
1045     { &hf_dlm3_m_sbflags_valnotvalid,
1046       { "Lock Value Block Is Invalid", "dlm3.m.sbflags.valnotvalid",
1047         FT_BOOLEAN, 32, NULL, DLM3_SBF_VALNOTVALID,
1048         NULL, HFILL}},
1049     { &hf_dlm3_m_sbflags_altmode,
1050       { "Try to Grant in Alternative Mode", "dlm3.m.sbflags.altmode",
1051         FT_BOOLEAN, 32, NULL, DLM3_SBF_ALTMODE,
1052         NULL, HFILL}},
1053
1054     /* dlm_message::flags */
1055     DLM3_REGISTER_HF_FLAGS(m_flags, "m.flags"),
1056
1057     { &hf_dlm3_m_lvbseq,
1058       { "Lock Value Block Sequence Number", "dlm3.m.lvbseq",
1059         FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
1060         NULL, HFILL}},
1061
1062     { &hf_dlm3_m_hash,
1063       { "Hash value", "dlm3.m.hash",
1064         FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
1065         NULL, HFILL}},
1066
1067     { &hf_dlm3_m_status,
1068       { "Status", "dlm3.m.status",
1069         FT_INT32, BASE_DEC, VALS(dlm3_status), 0x0,
1070         NULL, HFILL}},
1071
1072     { &hf_dlm3_m_grmode,
1073       { "Granted Mode", "dlm3.m.grmode",
1074         FT_INT32, BASE_DEC, VALS(dlm3_mode), 0x0,
1075         NULL, HFILL}},
1076     { &hf_dlm3_m_rqmode,
1077       { "Request Mode", "dlm3.m.rqmode",
1078         FT_INT32, BASE_DEC, VALS(dlm3_mode), 0x0,
1079         NULL, HFILL}},
1080     { &hf_dlm3_m_bastmode,
1081       { "Mode requested by another node", "dlm3.m.bastmode",
1082         FT_INT32, BASE_DEC, VALS(dlm3_mode), 0x0,
1083         NULL, HFILL}},
1084
1085     /* dlm_message::asts */
1086     DLM3_REGISTER_HF_ASTS(m, 32),
1087
1088     { &hf_dlm3_m_result,
1089       { "Message Result(errno)", "dlm3.m.result",
1090         FT_INT32, BASE_DEC, VALS(dlm3_result), 0x0,
1091         NULL, HFILL}},
1092     { &hf_dlm3_m_extra,
1093       { "Extra Message", "dlm3.m.extra",
1094         FT_BYTES, BASE_NONE, NULL, 0x0,
1095         NULL, HFILL}},
1096
1097     /* dlm_rcom */
1098     { &hf_dlm3_rc_type,
1099       { "Recovery Command Type", "dlm3.rc.type",
1100         FT_UINT32, BASE_DEC, VALS(dlm3_rcom), 0x0,
1101         NULL, HFILL}},
1102     { &hf_dlm3_rc_result,
1103       { "Recovery Command Result", "dlm3.rc.result",
1104         FT_INT32, BASE_DEC, NULL, 0x0,
1105         NULL, HFILL}},
1106     { &hf_dlm3_rc_id,
1107       { "Recovery Command ID", "dlm3.rc.id",
1108         FT_UINT64, BASE_DEC, NULL, 0x0,
1109         NULL, HFILL}},
1110     { &hf_dlm3_rc_seq,
1111       { "Recovery Command Sequence Number of Sender", "dlm3.rc.seq",
1112         FT_UINT64, BASE_DEC, NULL, 0x0,
1113         NULL, HFILL}},
1114     { &hf_dlm3_rc_seq_reply,
1115       { "Recovery Command Sequence Number of Receiver", "dlm3.rc.seq_reply",
1116         FT_UINT64, BASE_DEC, NULL, 0x0,
1117         NULL, HFILL}},
1118     { &hf_dlm3_rc_buf,
1119       { "Recovery Buffer", "dlm3.rc.buf",
1120         FT_BYTES, BASE_NONE, NULL, 0x0,
1121         NULL, HFILL}},
1122
1123     /* rcom_config */
1124     { &hf_dlm3_rf_lvblen,
1125       { "Lock Value Block Length", "dlm3.rf.lvblen",
1126         FT_UINT32, BASE_DEC, NULL, 0x0,
1127         NULL, HFILL}},
1128
1129     /* rcom_config::rf_lsflags */
1130     DLM3_REGISTER_HF_EXFLAGS(rf_lsflags, "rf.lsflags"),
1131
1132     { &hf_dlm3_rf_unused,
1133       { "Unsed area", "dlm3.rf.lsflags.unused",
1134         FT_UINT64, BASE_HEX, NULL, 0x0,
1135         NULL, HFILL}},
1136
1137     /* rcom_lock */
1138     { &hf_dlm3_rl_ownpid,
1139       { "Process ID of Lock Owner", "dlm3.rl.ownpid",
1140         FT_UINT32, BASE_DEC, NULL, 0x0,
1141         NULL, HFILL}},
1142
1143     DLM3_REGISTER_HF_LOCKID(rl),
1144     DLM3_REGISTER_HF_EXFLAGS(rl_exflags, "rl.exflags"),
1145     DLM3_REGISTER_HF_FLAGS(rl_flags, "rl.flags"),
1146
1147     { &hf_dlm3_rl_lvbseq,
1148       { "Lock Value Block Sequence Number", "dlm3.rl.lvbseq",
1149         FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
1150         NULL, HFILL}},
1151     { &hf_dlm3_rl_result,
1152       { "Result of Recovering master copy", "dlm3.rl.result",
1153         FT_INT32, BASE_DEC, VALS(dlm3_result), 0x0,
1154         NULL, HFILL}},
1155     { &hf_dlm3_rl_rqmode,
1156       { "Request Mode", "dlm3.rl.rqmode",
1157         FT_INT8, BASE_DEC, VALS(dlm3_mode), 0x0,
1158         NULL, HFILL}},
1159     { &hf_dlm3_rl_grmode,
1160       { "Granted Mode", "dlm3.rl.grmode",
1161         FT_INT8, BASE_DEC, VALS(dlm3_mode), 0x0,
1162         NULL, HFILL}},
1163     { &hf_dlm3_rl_status,
1164       { "Status", "dlm3.rl.status",
1165         FT_INT8, BASE_DEC, VALS(dlm3_rs), 0x0,
1166         NULL, HFILL}},
1167     DLM3_REGISTER_HF_ASTS(rl, 8),
1168
1169     { &hf_dlm3_rl_wait_type,
1170       { "Message Type the waiter is waiting for", "dlm3.rl.wait_type",
1171         FT_UINT16, BASE_DEC, VALS(dlm3_msg), 0x0,
1172         NULL, HFILL }},
1173
1174     { &hf_dlm3_rl_namelen,
1175       { "Length of `name' field", "dlm3.rl.namelen",
1176         FT_UINT16, BASE_DEC, NULL, 0x0,
1177         NULL, HFILL }},
1178     { &hf_dlm3_rl_name,
1179       { "Name of Resource", "dlm.rl.name",
1180         FT_BYTES, BASE_NONE, NULL, 0x0,
1181         NULL, HFILL }},
1182     { &hf_dlm3_rl_name_contents,
1183       { "Contents actually occupying `name' field", "dlm.rl.name_contents",
1184         FT_STRING, BASE_NONE, NULL, 0x0,
1185         NULL, HFILL }},
1186     { &hf_dlm3_rl_name_padding,
1187       { "Padding", "dlm.rl.name_padding",
1188         FT_BYTES, BASE_NONE, NULL, 0x0,
1189         NULL, HFILL }},
1190     { &hf_dlm3_rl_lvb,
1191       { "Lock Value Block", "dlm.rl.lvb",
1192         FT_BYTES, BASE_NONE, NULL, 0x0,
1193         NULL, HFILL }}
1194   };
1195
1196   static gint *ett[] = {
1197     &ett_dlm3,
1198     &ett_dlm3_version,
1199
1200     &ett_dlm3_msg,
1201     &ett_dlm3_m_exflags,
1202     &ett_dlm3_sbflags,
1203     &ett_dlm3_m_flags,
1204     &ett_dlm3_m_asts,
1205
1206     &ett_dlm3_rcom,
1207     &ett_dlm3_rcom_lock,
1208     &ett_dlm3_rcom_config,
1209
1210     &ett_dlm3_rf_lsflags,
1211     &ett_dlm3_rl_exflags,
1212     &ett_dlm3_rl_flags,
1213     &ett_dlm3_rl_asts,
1214     &ett_dlm3_rl_name
1215   };
1216
1217   proto_dlm3 = proto_register_protocol("Distributed Lock Manager",
1218                                        "DLM3", "dlm3");
1219   proto_register_field_array(proto_dlm3, hf, array_length(hf));
1220   proto_register_subtree_array(ett, array_length(ett));
1221
1222   dlm3_module = prefs_register_protocol(proto_dlm3,
1223                                         proto_reg_handoff_dlm3);
1224
1225   prefs_register_uint_preference(dlm3_module, "tcp.port",
1226                                  "DLM3 TCP Port",
1227                                  "Set the TCP port for Distributed Lock Manager",
1228                                  10,
1229                                  &dlm3_tcp_port);
1230   prefs_register_uint_preference(dlm3_module, "sctp.port",
1231                                  "DLM3 SCTP Port",
1232                                  "Set the SCTP port for Distributed Lock Manager",
1233                                  10,
1234                                  &dlm3_sctp_port);
1235 }
1236
1237
1238 void
1239 proto_reg_handoff_dlm3(void)
1240 {
1241   static gboolean dissector_registered = FALSE;
1242
1243   static guint tcp_port;
1244   static guint sctp_port;
1245
1246   static dissector_handle_t dlm3_tcp_handle;
1247   static dissector_handle_t dlm3_sctp_handle;
1248
1249   if (!dissector_registered) {
1250     dlm3_sctp_handle = new_create_dissector_handle(dissect_dlm3, proto_dlm3);
1251     dlm3_tcp_handle = new_create_dissector_handle(dissect_dlm3, proto_dlm3);
1252     dissector_registered = TRUE;
1253   } else {
1254     dissector_delete("tcp.port",  tcp_port,  dlm3_tcp_handle);
1255     dissector_delete("sctp.port", sctp_port, dlm3_sctp_handle);
1256   }
1257
1258   tcp_port  = dlm3_tcp_port;
1259   sctp_port = dlm3_sctp_port;
1260   dissector_add("tcp.port",  tcp_port,  dlm3_tcp_handle);
1261   dissector_add("sctp.port", sctp_port, dlm3_sctp_handle);
1262 }
1263
1264 /* packet-dlm3.c ends here. */