2 * Routines for hclnfsd (Hummingbird NFS Daemon) dissection
3 * Copyright 2001, Mike Frisch <frisch@hummingbird.com>
5 * $Id: packet-hclnfsd.c,v 1.3 2001/02/06 18:43:24 guy Exp $
7 * Ethereal - Network traffic analyzer
8 * By Gerald Combs <gerald@zing.org>
9 * Copyright 1998 Gerald Combs
11 * Copied from packet-ypserv.c
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
33 #ifdef HAVE_SYS_TYPES_H
34 #include <sys/types.h>
38 #include "packet-rpc.h"
39 #include "packet-hclnfsd.h"
41 static int proto_hclnfsd = -1;
43 static int hf_hclnfsd_request_type = -1;
44 static int hf_hclnfsd_device = -1;
45 static int hf_hclnfsd_login = -1;
46 static int hf_hclnfsd_lockname = -1;
47 static int hf_hclnfsd_unknown_data = -1;
48 static int hf_hclnfsd_lockowner = -1;
49 static int hf_hclnfsd_printername = -1;
50 static int hf_hclnfsd_filename = -1;
51 static int hf_hclnfsd_grpname = -1;
52 static int hf_hclnfsd_hostname = -1;
53 static int hf_hclnfsd_username = -1;
54 static int hf_hclnfsd_queuename = -1;
55 static int hf_hclnfsd_queuecomment = -1;
56 static int hf_hclnfsd_printparams = -1;
57 static int hf_hclnfsd_status = -1;
59 static gint ett_hclnfsd = -1;
60 static gint ett_hclnfsd_gids = -1;
61 static gint ett_hclnfsd_groups = -1;
62 static gint ett_hclnfsd_uids = -1;
63 static gint ett_hclnfsd_usernames = -1;
64 static gint ett_hclnfsd_printqueues = -1;
65 static gint ett_hclnfsd_printjob = -1;
68 /* defined in 'packet-nfs.c' */
70 dissect_nfs_fh3(const u_char *, int, frame_data *, proto_tree *, char *);
74 dissect_hclnfsd_gids(const u_char *pd, int offset, frame_data *fd,
77 guint ngids, ngids_i, gid;
78 proto_tree *gidtree = NULL;
79 proto_item *giditem = NULL;
81 if (!tree) return offset;
83 ngids = EXTRACT_UINT(pd, offset);
86 giditem = proto_tree_add_text(tree, NullTVB, offset, 4, "GIDs: %d",
89 gidtree = proto_item_add_subtree(giditem, ett_hclnfsd_gids);
95 for (ngids_i = 0; ngids_i < ngids; ngids_i++)
97 gid = EXTRACT_UINT(pd, offset + (4 * ngids_i));
98 proto_tree_add_text(gidtree, NullTVB, offset + (4 * ngids_i), 4,
108 dissect_hclnfsd_spool_inquire_call(const u_char *pd, int offset,
109 frame_data *fd, proto_tree *tree)
111 offset = dissect_rpc_uint32(pd, offset, fd, tree, "status");
113 offset = dissect_nfs_fh3(pd, offset, fd, tree, "spool filehandle");
120 dissect_hclnfsd_spool_file_call(const u_char *pd, int offset,
121 frame_data *fd, proto_tree *tree)
123 offset = dissect_rpc_string(pd, offset, fd, tree, hf_hclnfsd_printername,
126 offset = dissect_rpc_string(pd, offset, fd, tree, hf_hclnfsd_filename,
129 offset = dissect_rpc_uint32(pd, offset, fd, tree, "File Extension");
135 static const value_string names_request_type[] = {
136 #define HCLNFSD_DISK_REQUEST 4
137 { HCLNFSD_DISK_REQUEST, "DISK" },
138 #define HCLNFSD_PRINT_REQUEST 3
139 { HCLNFSD_PRINT_REQUEST, "PRINTER" },
145 dissect_hclnfsd_authorize_call(const u_char *pd, int offset,
146 frame_data *fd, proto_tree *tree)
150 offset = dissect_rpc_uint32(pd, offset, fd, tree, "Server IP");
152 request_type = EXTRACT_UINT(pd, offset);
154 proto_tree_add_uint(tree, hf_hclnfsd_request_type, NullTVB, offset,
158 offset = dissect_rpc_string(pd, offset, fd, tree, hf_hclnfsd_device, NULL);
160 offset = dissect_rpc_string(pd, offset, fd, tree, hf_hclnfsd_login, NULL);
167 dissect_hclnfsd_authorize_reply(const u_char *pd, int offset,
168 frame_data *fd, proto_tree *tree)
172 status = EXTRACT_UINT(pd, offset);
173 if (!tree) return offset;
179 proto_tree_add_uint(tree, hf_hclnfsd_status, NullTVB, offset, 4, status);
181 offset = dissect_rpc_uint32(pd, offset, fd, tree, "UID");
183 offset = dissect_rpc_uint32(pd, offset, fd, tree, "GID");
185 offset = dissect_hclnfsd_gids(pd, offset, fd, tree);
191 dissect_hclnfsd_grp_name_to_numb_call(const u_char *pd, int offset,
192 frame_data *fd, proto_tree *tree)
194 offset = dissect_rpc_string(pd, offset, fd, tree, hf_hclnfsd_grpname,
202 dissect_hclnfsd_grp_name_to_numb_reply(const u_char *pd, int offset,
203 frame_data *fd, proto_tree *tree)
205 offset = dissect_rpc_uint32(pd, offset, fd, tree, "GID");
212 dissect_hclnfsd_grp_to_number_call(const u_char *pd, int offset,
213 frame_data *fd, proto_tree *tree)
216 offset = dissect_hclnfsd_gids(pd, offset, fd, tree);
223 dissect_hclnfsd_grp_to_number_reply(const u_char *pd, int offset,
224 frame_data *fd, proto_tree *tree)
226 guint ngrpnames, ngrpnames_i;
227 proto_tree *grptree = NULL;
228 proto_item *grpitem = NULL;
230 ngrpnames = EXTRACT_UINT(pd, offset);
233 grpitem = proto_tree_add_text(tree, NullTVB, offset, 4, "Groups: %d",
237 grptree = proto_item_add_subtree(grpitem, ett_hclnfsd_groups);
244 for (ngrpnames_i = 0; ngrpnames_i < ngrpnames ; ngrpnames_i++)
245 offset = dissect_rpc_string(pd, offset, fd, grptree,
246 hf_hclnfsd_grpname, NULL);
253 dissect_hclnfsd_return_host_call(const u_char *pd, int offset,
254 frame_data *fd, proto_tree *tree)
256 offset = dissect_rpc_uint32(pd, offset, fd, tree, "IP");
263 dissect_hclnfsd_return_host_reply(const u_char *pd, int offset,
264 frame_data *fd, proto_tree *tree)
266 offset = dissect_rpc_string(pd, offset, fd, tree, hf_hclnfsd_hostname, NULL);
273 dissect_hclnfsd_uid_to_name_call(const u_char *pd, int offset,
274 frame_data *fd, proto_tree *tree)
276 guint nuids, nuids_i;
277 proto_tree *uidtree = NULL;
278 proto_item *uiditem = NULL;
280 nuids = EXTRACT_UINT(pd, offset);
283 uiditem = proto_tree_add_text(tree, NullTVB, offset, 4, "UIDs: %d",
287 uidtree = proto_item_add_subtree(uiditem, ett_hclnfsd_uids);
294 for (nuids_i = 0; nuids_i < nuids; nuids_i++)
295 offset = dissect_rpc_uint32(pd, offset, fd, uidtree, "UID");
302 dissect_hclnfsd_uid_to_name_reply(const u_char *pd, int offset,
303 frame_data *fd, proto_tree *tree)
305 guint nusers, nusers_i;
306 proto_tree *usertree = NULL;
307 proto_item *useritem = NULL;
309 nusers = EXTRACT_UINT(pd, offset);
312 useritem = proto_tree_add_text(tree, NullTVB, offset, 4, "UIDs: %d",
316 usertree = proto_item_add_subtree(useritem, ett_hclnfsd_usernames);
323 for (nusers_i = 0; nusers_i < nusers; nusers_i++)
324 offset = dissect_rpc_string(pd, offset, fd, usertree,
325 hf_hclnfsd_username, NULL);
332 dissect_hclnfsd_name_to_uid_call(const u_char *pd, int offset,
333 frame_data *fd, proto_tree *tree)
335 offset = dissect_rpc_string(pd, offset, fd, tree, hf_hclnfsd_username, NULL);
342 dissect_hclnfsd_name_to_uid_reply(const u_char *pd, int offset,
343 frame_data *fd, proto_tree *tree)
345 offset = dissect_rpc_uint32(pd, offset, fd, tree, "UID");
352 dissect_hclnfsd_share_call(const u_char *pd, int offset,
353 frame_data *fd, proto_tree *tree)
357 request_type = EXTRACT_UINT(pd, offset);
359 proto_tree_add_uint(tree, hf_hclnfsd_request_type, NullTVB, offset,
363 offset = dissect_rpc_uint32(pd, offset, fd, tree, "Cookie");
365 offset = dissect_rpc_string(pd, offset, fd, tree, hf_hclnfsd_lockname, NULL);
367 offset = dissect_nfs_fh3(pd, offset, fd, tree, "Filehandle");
369 offset = dissect_rpc_data(pd, offset, fd, tree, hf_hclnfsd_unknown_data);
371 offset = dissect_rpc_uint32(pd, offset, fd, tree, "Mode");
373 offset = dissect_rpc_uint32(pd, offset, fd, tree, "Access");
375 offset = dissect_rpc_uint32(pd, offset, fd, tree, "unused");
382 dissect_hclnfsd_share_reply(const u_char *pd, int offset,
383 frame_data *fd, proto_tree *tree)
387 request_type = EXTRACT_UINT(pd, offset);
389 proto_tree_add_uint(tree, hf_hclnfsd_request_type, NullTVB, offset,
393 offset = dissect_rpc_uint32(pd, offset, fd, tree, "Cookie");
395 offset = dissect_rpc_uint32(pd, offset, fd, tree, "Stat");
397 offset = dissect_rpc_uint32(pd, offset, fd, tree, "Sequence");
404 dissect_hclnfsd_unshare_call(const u_char *pd, int offset,
405 frame_data *fd, proto_tree *tree)
407 return dissect_hclnfsd_share_call(pd, offset, fd, tree);
412 dissect_hclnfsd_unshare_reply(const u_char *pd, int offset,
413 frame_data *fd, proto_tree *tree)
415 return dissect_hclnfsd_share_reply(pd, offset, fd, tree);
420 dissect_hclnfsd_lock_call(const u_char *pd, int offset,
421 frame_data *fd, proto_tree *tree)
423 offset = dissect_rpc_uint32(pd, offset, fd, tree, "Status");
425 offset = dissect_rpc_uint32(pd, offset, fd, tree, "Cookie");
427 offset = dissect_rpc_uint32(pd, offset, fd, tree, "unused");
429 offset = dissect_rpc_uint32(pd, offset, fd, tree, "Exclusive");
431 offset = dissect_rpc_string(pd, offset, fd, tree, hf_hclnfsd_lockname, NULL);
433 offset = dissect_nfs_fh3(pd, offset, fd, tree, "Filehandle");
435 offset = dissect_rpc_data(pd, offset, fd, tree, hf_hclnfsd_lockowner);
437 offset = dissect_rpc_uint32(pd, offset, fd, tree, "unused");
439 offset = dissect_rpc_uint32(pd, offset, fd, tree, "Offset");
441 offset = dissect_rpc_uint32(pd, offset, fd, tree, "Length");
448 dissect_hclnfsd_lock_reply(const u_char *pd, int offset,
449 frame_data *fd, proto_tree *tree)
453 request_type = EXTRACT_UINT(pd, offset);
455 proto_tree_add_uint(tree, hf_hclnfsd_request_type, NullTVB, offset,
459 offset = dissect_rpc_uint32(pd, offset, fd, tree, "Cookie");
461 offset = dissect_rpc_uint32(pd, offset, fd, tree, "Stat");
468 dissect_hclnfsd_remove_call(const u_char *pd, int offset,
469 frame_data *fd, proto_tree *tree)
471 offset = dissect_rpc_string(pd, offset, fd, tree, hf_hclnfsd_lockname, NULL);
473 offset = dissect_rpc_uint32(pd, offset, fd, tree, "unused");
480 dissect_hclnfsd_unlock_call(const u_char *pd, int offset,
481 frame_data *fd, proto_tree *tree)
483 offset = dissect_rpc_uint32(pd, offset, fd, tree, "unused");
485 offset = dissect_rpc_uint32(pd, offset, fd, tree, "Cookie");
487 offset = dissect_rpc_string(pd, offset, fd, tree, hf_hclnfsd_lockname, NULL);
489 offset = dissect_nfs_fh3(pd, offset, fd, tree, "Filehandle");
491 offset = dissect_rpc_data(pd, offset, fd, tree, hf_hclnfsd_unknown_data);
493 offset = dissect_rpc_uint32(pd, offset, fd, tree, "unused");
495 offset = dissect_rpc_uint32(pd, offset, fd, tree, "Offset");
497 offset = dissect_rpc_uint32(pd, offset, fd, tree, "Length");
504 dissect_hclnfsd_unlock_reply(const u_char *pd, int offset,
505 frame_data *fd, proto_tree *tree)
507 return dissect_hclnfsd_lock_reply(pd, offset, fd, tree);
512 dissect_hclnfsd_get_printers_reply(const u_char *pd, int offset,
513 frame_data *fd, proto_tree *tree)
515 guint nqueues, nqueues_i;
516 proto_item *queuesitem = NULL;
517 proto_tree *queuestree = NULL;
519 nqueues = EXTRACT_UINT(pd, offset);
522 queuesitem = proto_tree_add_text(tree, NullTVB, offset, 4,
523 "Print Queues: %d", nqueues);
526 queuestree = proto_item_add_subtree(queuesitem,
527 ett_hclnfsd_printqueues);
534 for (nqueues_i = 0; nqueues_i < nqueues; nqueues_i++)
536 /* create new item for print queue */
537 offset = dissect_rpc_string(pd, offset, fd, queuestree,
538 hf_hclnfsd_queuename, NULL);
540 /* create subtree on new item with print queue comment */
542 offset = dissect_rpc_string(pd, offset, fd, queuestree,
543 hf_hclnfsd_queuecomment, NULL);
551 dissect_hclnfsd_get_printq_call(const u_char *pd, int offset,
552 frame_data *fd, proto_tree *tree)
554 offset = dissect_rpc_string(pd, offset, fd, tree, hf_hclnfsd_queuename,
557 offset = dissect_rpc_string(pd, offset, fd, tree, hf_hclnfsd_username, NULL);
564 dissect_hclnfsd_get_printq_reply(const u_char *pd, int offset,
565 frame_data *fd, proto_tree *tree)
567 guint datafollows, jobid;
568 proto_item *queueitem = NULL;
569 proto_tree *queuetree = NULL;
573 offset = dissect_rpc_uint32(pd, offset, fd, tree, "Print Queue Number");
575 offset = dissect_rpc_string(pd, offset, fd, tree, hf_hclnfsd_queuecomment,
578 offset = dissect_rpc_uint32(pd, offset, fd, tree, "Queue Status");
580 offset = dissect_rpc_uint32(pd, offset, fd, tree,
581 "Number of Physical Printers");
583 datafollows = EXTRACT_UINT(pd, offset);
586 queueitem = proto_tree_add_text(tree, NullTVB, offset, 4,
587 "Print Jobs: %d", datafollows);
589 queuetree = proto_item_add_subtree(queueitem, ett_hclnfsd_printqueues);
598 jobid = EXTRACT_UINT(pd, offset);
599 jobitem = proto_tree_add_text(queuetree, NullTVB, offset, 4, "Job ID: %d",
603 jobtree = proto_item_add_subtree(jobitem, ett_hclnfsd_printjob);
605 offset = dissect_rpc_string(pd, offset, fd, jobtree,
606 hf_hclnfsd_username, NULL);
607 offset = dissect_rpc_string(pd, offset, fd, jobtree,
608 hf_hclnfsd_printparams, NULL);
609 offset = dissect_rpc_uint32(pd, offset, fd, jobtree, "Queue Position");
610 offset = dissect_rpc_uint32(pd, offset, fd, jobtree, "Job Status");
611 offset = dissect_rpc_uint32(pd, offset, fd, jobtree, "Time Submitted");
612 offset = dissect_rpc_uint32(pd, offset, fd, jobtree, "Size");
613 offset = dissect_rpc_uint32(pd, offset, fd, jobtree, "Copies");
614 offset = dissect_rpc_string(pd, offset, fd, jobtree,
615 hf_hclnfsd_queuecomment, NULL);
616 datafollows = EXTRACT_UINT(pd, offset);
624 /* proc number, "proc name", dissect_request, dissect_reply */
625 /* NULL as function pointer means: take the generic one. */
627 static const old_vsff hclnfsd1_proc[] = {
628 { HCLNFSDPROC_NULL, "NULL",
630 { HCLNFSDPROC_SPOOL_INQUIRE, "SPOOL_INQUIRE",
631 dissect_hclnfsd_spool_inquire_call, NULL },
632 { HCLNFSDPROC_SPOOL_FILE, "SPOOL_FILE",
633 dissect_hclnfsd_spool_file_call, NULL },
634 { HCLNFSDPROC_AUTHORIZE, "AUTHORIZE",
635 dissect_hclnfsd_authorize_call, dissect_hclnfsd_authorize_reply },
636 { HCLNFSDPROC_GRP_NAME_TO_NUMB, "GRP_NAME_TO_NUMB",
637 dissect_hclnfsd_grp_name_to_numb_call, dissect_hclnfsd_grp_name_to_numb_reply },
638 { HCLNFSDPROC_GRP_TO_NUMBER, "GRP_TO_NUMBER",
639 dissect_hclnfsd_grp_to_number_call, dissect_hclnfsd_grp_to_number_reply },
640 { HCLNFSDPROC_RETURN_HOST, "RETURN_HOST",
641 dissect_hclnfsd_return_host_call, dissect_hclnfsd_return_host_reply },
642 { HCLNFSDPROC_UID_TO_NAME, "UID_TO_NAME",
643 dissect_hclnfsd_uid_to_name_call, dissect_hclnfsd_uid_to_name_reply },
644 { HCLNFSDPROC_NAME_TO_UID, "NAME_TO_UID",
645 dissect_hclnfsd_name_to_uid_call, dissect_hclnfsd_name_to_uid_reply },
646 { HCLNFSDPROC_SHARE, "SHARE",
647 dissect_hclnfsd_share_call, dissect_hclnfsd_share_reply },
648 { HCLNFSDPROC_UNSHARE, "UNSHARE",
649 dissect_hclnfsd_unshare_call, dissect_hclnfsd_unshare_reply },
650 { HCLNFSDPROC_LOCK, "LOCK",
651 dissect_hclnfsd_lock_call, dissect_hclnfsd_lock_reply },
652 { HCLNFSDPROC_REMOVE, "REMOVE",
653 dissect_hclnfsd_remove_call, NULL },
654 { HCLNFSDPROC_UNLOCK, "UNLOCK",
655 dissect_hclnfsd_unlock_call, dissect_hclnfsd_unlock_reply },
656 { HCLNFSDPROC_GET_PRINTERS, "GET_PRINTERS",
657 NULL, dissect_hclnfsd_get_printers_reply },
658 { HCLNFSDPROC_GET_PRINTQ, "GET_PRINTQ",
659 dissect_hclnfsd_get_printq_call, dissect_hclnfsd_get_printq_reply },
660 { HCLNFSDPROC_CANCEL_PRJOB, "CANCEL_PRJOB",
662 { HCLNFSDPROC_ZAP_LOCKS, "ZAP_LOCKS",
664 { 0, NULL, NULL, NULL }
666 /* end of hclnfsd version 1 */
670 proto_register_hclnfsd(void)
673 static struct true_false_string okfailed = { "Ok", "Failed" };
674 static struct true_false_string yesno = { "Yes", "No" };
677 static hf_register_info hf[] = {
678 { &hf_hclnfsd_request_type, {
679 "Request Type", "hclnfsd.request_type", FT_UINT32, BASE_DEC,
680 VALS(names_request_type), 0, "Request Type" }},
682 { &hf_hclnfsd_device, {
683 "Device", "hclnfsd.device", FT_STRING, BASE_DEC,
684 NULL, 0, "Device" }},
686 { &hf_hclnfsd_login, {
687 "Login Text", "hclnfsd.logintext", FT_STRING, BASE_DEC,
688 NULL, 0, "Login Text" }},
690 { &hf_hclnfsd_lockname, {
691 "Lockname", "hclnfsd.lockname", FT_STRING, BASE_DEC,
692 NULL, 0, "Lockname" }},
694 { &hf_hclnfsd_unknown_data, {
695 "Unknown", "hclnfsd.unknown_data", FT_STRING, BASE_DEC,
698 { &hf_hclnfsd_lockowner, {
699 "Lockowner", "hclnfsd.lockowner", FT_STRING, BASE_DEC,
700 NULL, 0, "Lockowner" }},
702 { &hf_hclnfsd_printername, {
703 "Printer Name", "hclnfsd.printername", FT_STRING, BASE_DEC,
704 NULL, 0, "Printer name" }},
706 { &hf_hclnfsd_filename, {
707 "Filename", "hclnfsd.filename", FT_STRING, BASE_DEC,
708 NULL, 0, "Filename" }},
710 { &hf_hclnfsd_grpname, {
711 "Group", "hclnfsd.group", FT_STRING, BASE_DEC,
714 { &hf_hclnfsd_hostname, {
715 "Hostname", "hclnfsd.hostname", FT_STRING, BASE_DEC,
716 NULL, 0, "Hostname" }},
718 { &hf_hclnfsd_username, {
719 "Username", "hclnfsd.username", FT_STRING, BASE_DEC,
720 NULL, 0, "Username" }},
722 { &hf_hclnfsd_queuename, {
723 "Name", "hclnfsd.printqueuename", FT_STRING, BASE_DEC,
724 NULL, 0, "Print Queue Name" }},
726 { &hf_hclnfsd_queuecomment, {
727 "Comment", "hclnfsd.printqueuecomment", FT_STRING, BASE_DEC,
728 NULL, 0, "Print Queue Comment" }},
730 { &hf_hclnfsd_printparams, {
731 "Print Parameters", "hclnfsd.printparameters", FT_STRING, BASE_DEC,
732 NULL, 0, "Print Parameters" }},
734 { &hf_hclnfsd_status, {
735 "Status", "hclnfsd.status", FT_UINT32, BASE_DEC,
738 static gint *ett[] = {
743 &ett_hclnfsd_usernames,
744 &ett_hclnfsd_printqueues,
745 &ett_hclnfsd_printjob,
748 proto_hclnfsd = proto_register_protocol("Hummingbird NFS Daemon",
749 "HCLNFSD", "hclnfsd");
750 proto_register_field_array(proto_hclnfsd, hf, array_length(hf));
751 proto_register_subtree_array(ett, array_length(ett));
755 proto_reg_handoff_hclnfsd(void)
757 /* Register the protocol as RPC */
758 rpc_init_prog(proto_hclnfsd, HCLNFSD_PROGRAM, ett_hclnfsd);
760 /* Register the procedure tables */
761 old_rpc_init_proc_table(HCLNFSD_PROGRAM, 1, hclnfsd1_proc);