Added Nathan's patch for AFS and RX dissection.
[obnox/wireshark/wip.git] / packet-afs.c
1 /* packet-rx.c
2  * Routines for RX packet dissection
3  * Copyright 1999, Nathan Neulinger <nneul@umr.edu>
4  * Based on routines from tcpdump patches by
5  *   Ken Hornstein <kenh@cmf.nrl.navy.mil>
6  * Portions based on information retrieved from the RX definitions
7  *   in Arla, the free AFS client at http://www.stacken.kth.se/project/arla/
8  *
9  * $Id: packet-afs.c,v 1.1 1999/10/20 16:41:17 gram Exp $
10  *
11  * Ethereal - Network traffic analyzer
12  * By Gerald Combs <gerald@unicom.net>
13  * Copyright 1998 Gerald Combs
14  *
15  * Copied from packet-tftp.c
16  *
17  * This program is free software; you can redistribute it and/or
18  * modify it under the terms of the GNU General Public License
19  * as published by the Free Software Foundation; either version 2
20  * of the License, or (at your option) any later version.
21  *
22  * This program is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25  * GNU General Public License for more details.
26  *
27  * You should have received a copy of the GNU General Public License
28  * along with this program; if not, write to the Free Software
29  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
30  */
31
32 #ifdef HAVE_CONFIG_H
33 # include "config.h"
34 #endif
35
36 #include <stdio.h>
37
38 #ifdef HAVE_SYS_TYPES_H
39 # include <sys/types.h>
40 #endif
41
42 #ifdef HAVE_NETINET_IN_H
43 # include <netinet/in.h>
44 #endif
45
46 #include <string.h>
47 #include <glib.h>
48 #include "packet.h"
49 #include "packet-rx.h"
50 #include "packet-afs.h"
51 #include "resolv.h"
52
53 static const value_string fs_req[] = {
54         { 130,          "fetch-data" },
55         { 131,          "fetch-acl" },
56         { 132,          "fetch-status" },
57         { 133,          "store-data" },
58         { 134,          "store-acl" },
59         { 135,          "store-status" },
60         { 136,          "remove-file" },
61         { 137,          "create-file" },
62         { 138,          "rename" },
63         { 139,          "symlink" },
64         { 140,          "link" },
65         { 141,          "makedir" },
66         { 142,          "rmdir" },
67         { 143,          "oldsetlock" },
68         { 144,          "oldextlock" },
69         { 145,          "oldrellock" },
70         { 146,          "get-stats" },
71         { 147,          "give-cbs" },
72         { 148,          "get-vlinfo" },
73         { 149,          "get-vlstats" },
74         { 150,          "set-vlstats" },
75         { 151,          "get-rootvl" },
76         { 152,          "check-token" },
77         { 153,          "get-time" },
78         { 154,          "nget-vlinfo" },
79         { 155,          "bulk-stat" },
80         { 156,          "setlock" },
81         { 157,          "extlock" },
82         { 158,          "rellock" },
83         { 159,          "xstat-ver" },
84         { 160,          "get-xstat" },
85         { 161,          "dfs-lookup" },
86         { 162,          "dfs-flushcps" },
87         { 163,          "dfs-symlink" },
88         { 0,            NULL },
89 };
90
91 static const value_string cb_req[] = {
92         { 204,          "callback" },
93         { 205,          "initcb" },
94         { 206,          "probe" },
95         { 207,          "getlock" },
96         { 208,          "getce" },
97         { 209,          "xstatver" },
98         { 210,          "getxstat" },
99         { 211,          "initcb2" },
100         { 212,          "whoareyou" },
101         { 213,          "initcb3" },
102         { 214,          "probeuuid" },
103         { 0,            NULL },
104 };
105
106 static const value_string prot_req[] = {
107         { 500,          "new-user" },
108         { 501,          "where-is-it" },
109         { 502,          "dump-entry" },
110         { 503,          "add-to-group" },
111         { 504,          "name-to-id" },
112         { 505,          "id-to-name" },
113         { 506,          "delete" },
114         { 507,          "remove-from-group" },
115         { 508,          "get-cps" },
116         { 509,          "new-entry" },
117         { 510,          "list-max" },
118         { 511,          "set-max" },
119         { 512,          "list-entry" },
120         { 513,          "change-entry" },
121         { 514,          "list-elements" },
122         { 515,          "same-mbr-of" },
123         { 516,          "set-fld-sentry" },
124         { 517,          "list-owned" },
125         { 518,          "get-cps2" },
126         { 519,          "get-host-cps" },
127         { 520,          "update-entry" },
128         { 0,            NULL },
129 };
130
131 static const value_string vldb_req[] = {
132         { 501,          "create-entry" },
133         { 502,          "delete-entry" },
134         { 503,          "get-entry-by-id" },
135         { 504,          "get-entry-by-name" },
136         { 505,          "get-new-volume-id" },
137         { 506,          "replace-entry" },
138         { 507,          "update-entry" },
139         { 508,          "setlock" },
140         { 509,          "releaselock" },
141         { 510,          "list-entry" },
142         { 511,          "list-attrib" },
143         { 512,          "linked-list" },
144         { 513,          "get-stats" },
145         { 514,          "probe" },
146         { 515,          "get-addrs" },
147         { 516,          "change-addr" },
148         { 517,          "create-entry-n" },
149         { 518,          "get-entry-by-id-n" },
150         { 519,          "get-entry-by-name-n" },
151         { 520,          "replace-entry-n" },
152         { 521,          "list-entry-n" },
153         { 522,          "list-attrib-n" },
154         { 523,          "linked-list-n" },
155         { 524,          "update-entry-by-name" },
156         { 525,          "create-entry-u" },
157         { 526,          "get-entry-by-id-u" },
158         { 527,          "get-entry-by-name-u" },
159         { 528,          "replace-entry-u" },
160         { 529,          "list-entry-u" },
161         { 530,          "list-attrib-u" },
162         { 531,          "linked-list-u" },
163         { 532,          "regaddr" },
164         { 533,          "get-addrs-u" },
165         { 0,            NULL },
166 };
167
168 static const value_string kauth_req[] = {
169         { 1,            "auth-old" },
170         { 21,           "authenticate" },
171         { 22,           "authenticate-v2" },
172         { 2,            "change-pw" },
173         { 3,            "get-ticket-old" },
174         { 23,           "get-ticket" },
175         { 4,            "set-pw" },
176         { 5,            "set-fields" },
177         { 6,            "create-user" },
178         { 7,            "delete-user" },
179         { 8,            "get-entry" },
180         { 9,            "list-entry" },
181         { 10,           "get-stats" },
182         { 11,           "debug" },
183         { 12,           "get-pw" },
184         { 13,           "get-random-key" },
185         { 14,           "unlock" },
186         { 15,           "lock-status" },
187         { 0,            NULL },
188 };
189
190 static const value_string vol_req[] = {
191         { 100,          "create-volume" },
192         { 101,          "delete-volume" },
193         { 102,          "restore" },
194         { 103,          "forward" },
195         { 104,          "end-trans" },
196         { 105,          "clone" },
197         { 106,          "set-flags" },
198         { 107,          "get-flags" },
199         { 108,          "trans-create" },
200         { 109,          "dump" },
201         { 110,          "get-nth-volume" },
202         { 111,          "set-forwarding" },
203         { 112,          "get-name" },
204         { 113,          "get-status" },
205         { 114,          "sig-restore" },
206         { 115,          "list-partitions" },
207         { 116,          "list-volumes" },
208         { 117,          "set-id-types" },
209         { 118,          "monitor" },
210         { 119,          "partition-info" },
211         { 120,          "reclone" },
212         { 121,          "list-one-volume" },
213         { 122,          "nuke" },
214         { 123,          "set-date" },
215         { 124,          "x-list-volumes" },
216         { 125,          "x-list-one-volume" },
217         { 126,          "set-info" },
218         { 127,          "x-list-partitions" },
219         { 128,          "forward-multiple" },
220         { 0,            NULL },
221 };
222
223 static const value_string bos_req[] = {
224         { 80,           "create-bnode" },
225         { 81,           "delete-bnode" },
226         { 82,           "set-status" },
227         { 83,           "get-status" },
228         { 84,           "enumerate-instance" },
229         { 85,           "get-instance-info" },
230         { 86,           "get-instance-parm" },
231         { 87,           "add-superuser" },
232         { 88,           "delete-superuser" },
233         { 89,           "list-superusers" },
234         { 90,           "list-keys" },
235         { 91,           "add-key" },
236         { 92,           "delete-key" },
237         { 93,           "set-cell-name" },
238         { 94,           "get-cell-name" },
239         { 95,           "get-cell-host" },
240         { 96,           "add-cell-host" },
241         { 97,           "delete-cell-host" },
242         { 98,           "set-t-status" },
243         { 99,           "shutdown-all" },
244         { 100,          "restart-all" },
245         { 101,          "startup-all" },
246         { 102,          "set-noauth-flag" },
247         { 103,          "re-bozo" },
248         { 104,          "restart" },
249         { 105,          "start-bozo-install" },
250         { 106,          "uninstall" },
251         { 107,          "get-dates" },
252         { 108,          "exec" },
253         { 109,          "prune" },
254         { 110,          "set-restart-time" },
255         { 111,          "get-restart-time" },
256         { 112,          "start-bozo-log" },
257         { 113,          "wait-all" },
258         { 114,          "get-instance-strings" },
259         { 0,            NULL },
260 };
261
262 static const value_string ubik_req[] = {
263         { 10000,        "vote-beacon" },
264         { 10001,        "vote-debug-old" },
265         { 10002,        "vote-sdebug-old" },
266         { 10003,        "vote-getsyncsite" },
267         { 10004,        "vote-debug" },
268         { 10005,        "vote-sdebug" },
269         { 20000,        "disk-begin" },
270         { 20001,        "disk-commit" },
271         { 20002,        "disk-lock" },
272         { 20003,        "disk-write" },
273         { 20004,        "disk-getversion" },
274         { 20005,        "disk-getfile" },
275         { 20006,        "disk-sendfile" },
276         { 20007,        "disk-abort" },
277         { 20008,        "disk-releaselocks" },
278         { 20009,        "disk-truncate" },
279         { 20010,        "disk-probe" },
280         { 20011,        "disk-writev" },
281         { 20012,        "disk-interfaceaddr" },
282         { 20013,        "disk-setversion" },
283         { 0,            NULL },
284 };
285
286 static const value_string cb_types[] = {
287         { CB_TYPE_EXCLUSIVE, "exclusive" },
288         { CB_TYPE_SHARED, "shared" },
289         { CB_TYPE_DROPPED, "dropped" },
290         { 0, NULL },
291 };
292
293 static const value_string afs_errors[] = {
294         /* VOL Errors */
295         { 363520, "ID Exists"},
296         { 363521, "IO Error"},
297         { 363522, "Name Exists"},
298         { 363523, "Create Failed"},
299         { 363524, "Entry Not Found"},
300         { 363525, "Empty"},
301         { 363526, "Entry Deleted"},
302         { 363527, "Bad Name"},
303         { 363528, "Bad Index"},
304         { 363529, "Bad Volume Type"},
305         { 363530, "Bad Partition"},
306         { 363531, "Bad Server"},
307         { 363532, "Bad Replicate Server"},
308         { 363533, "No Replicate Server"},
309         { 363534, "Duplicate Replicate Server"},
310         { 363535, "ReadWrite Volume Not Found"},
311         { 363536, "Bad Reference Count"},
312         { 363537, "Size Exceeded"},
313         { 363538, "Bad Entry"},
314         { 363539, "Bad Volume ID Bump"},
315         { 363540, "VL_IDALREADHASED"},
316         { 363541, "Entry Locked"},
317         { 363542, "Bad Volume Operation"},
318         { 363543, "Bad Rel Lock Type"},
319         { 363544, "Rerelease"},
320         { 363545, "Bad Server"},
321         { 363546, "Permission Denied"},
322         { 363547, "Out of Memory"},
323
324         /* KAUTH Errors */
325         { 180488, "No Authentication"},
326         { 180490, "Bad Request"},
327
328         /* someone please add more of these errors to decode the errcode responses */
329
330         { 0, NULL },
331 };
332
333 static const value_string port_types[] = {
334         { AFS_PORT_FS, "File Server" },
335         { AFS_PORT_CB, "Callback Server" },
336         { AFS_PORT_BOS, "BOS Server" },
337         { AFS_PORT_PROT, "Protection Server" },
338         { AFS_PORT_VLDB, "Volume Location Database Server" },
339         { AFS_PORT_KAUTH, "Kerberos Authentication Server" },
340         { AFS_PORT_ERROR, "Error Server" },
341         { AFS_PORT_VOL, "Volume Server" },
342         { AFS_PORT_RMTSYS, "Rmtsys? Server" },
343         { AFS_PORT_UPDATE, "Update? Server" },
344         { AFS_PORT_BACKUP, "Backup Server" },
345         { 0, NULL }
346 };
347
348 static const value_string port_types_short[] = {
349         { AFS_PORT_FS, "FS" },
350         { AFS_PORT_CB, "CB" },
351         { AFS_PORT_BOS, "BOS" },
352         { AFS_PORT_PROT, "PROT" },
353         { AFS_PORT_VLDB, "VLDB" },
354         { AFS_PORT_KAUTH, "KAUTH" },
355         { AFS_PORT_ERROR, "ERR" },
356         { AFS_PORT_VOL, "VOL" },
357         { AFS_PORT_RMTSYS, "RMT" },
358         { AFS_PORT_UPDATE, "UPD" },
359         { AFS_PORT_BACKUP, "BKUP" },
360         { 0, NULL }
361 };
362
363 static const value_string ubik_lock_types[] = {
364         { 1,            "read" },
365         { 2,            "write" },
366         { 3,            "wait" },
367         { 0,            NULL },
368 };
369
370 static const value_string volume_types[] = {
371         { 0,            "read-write" },
372         { 1,            "read-only" },
373         { 2,            "backup" },
374         { 0,            NULL },
375 };
376
377 int afs_packet_init_count = 100;
378
379 struct afs_request_key {
380   guint32 ip_src, ip_dst, callnumber;
381   guint16 port_src, port_dst, service;
382 };
383
384 struct afs_request_val {
385   guint32 opcode;
386 };
387
388 GHashTable *afs_request_hash = NULL;
389 GMemChunk *afs_request_keys = NULL;
390 GMemChunk *afs_request_vals = NULL;
391
392 static int proto_afs = -1;
393 static int hf_afs_fs = -1;
394 static int hf_afs_cb = -1;
395 static int hf_afs_prot = -1;
396 static int hf_afs_vldb = -1;
397 static int hf_afs_kauth = -1;
398 static int hf_afs_vol = -1;
399 static int hf_afs_error = -1;
400 static int hf_afs_bos = -1;
401 static int hf_afs_update = -1;
402 static int hf_afs_rmtsys = -1;
403 static int hf_afs_ubik = -1;
404 static int hf_afs_backup = -1;
405
406 static int hf_afs_fs_opcode = -1;
407 static int hf_afs_cb_opcode = -1;
408 static int hf_afs_prot_opcode = -1;
409 static int hf_afs_vldb_opcode = -1;
410 static int hf_afs_kauth_opcode = -1;
411 static int hf_afs_vol_opcode = -1;
412 static int hf_afs_error_opcode = -1;
413 static int hf_afs_bos_opcode = -1;
414 static int hf_afs_update_opcode = -1;
415 static int hf_afs_rmtsys_opcode = -1;
416 static int hf_afs_ubik_opcode = -1;
417 static int hf_afs_backup_opcode = -1;
418
419 static int hf_afs_fs_fid_volume = -1;
420 static int hf_afs_fs_fid_vnode = -1;
421 static int hf_afs_fs_fid_uniqifier = -1;
422 static int hf_afs_fs_offset = -1;
423 static int hf_afs_fs_length = -1;
424 static int hf_afs_fs_flength = -1;
425 static int hf_afs_fs_errcode = -1;
426 static int hf_afs_fs_data = -1;
427 static int hf_afs_fs_name = -1;
428 static int hf_afs_fs_oldname = -1;
429 static int hf_afs_fs_newname = -1;
430 static int hf_afs_fs_symlink_name = -1;
431 static int hf_afs_fs_symlink_content = -1;
432 static int hf_afs_fs_volid = -1;
433 static int hf_afs_fs_volname = -1;
434 static int hf_afs_fs_timestamp = -1;
435
436 static int hf_afs_fs_acl_datasize = -1;
437 static int hf_afs_fs_acl_count_negative = -1;
438 static int hf_afs_fs_acl_count_positive = -1;
439 static int hf_afs_fs_acl_entity = -1;
440 static int hf_afs_fs_acl_r = -1;
441 static int hf_afs_fs_acl_l = -1;
442 static int hf_afs_fs_acl_i = -1;
443 static int hf_afs_fs_acl_d = -1;
444 static int hf_afs_fs_acl_w = -1;
445 static int hf_afs_fs_acl_k = -1;
446 static int hf_afs_fs_acl_a = -1;
447
448 static int hf_afs_fs_callback_version = -1;
449 static int hf_afs_fs_callback_expires = -1;
450 static int hf_afs_fs_callback_type = -1;
451
452 static int hf_afs_bos_errcode = -1;
453 static int hf_afs_bos_type = -1;
454 static int hf_afs_bos_instance = -1;
455 static int hf_afs_bos_status = -1;
456 static int hf_afs_bos_num = -1;
457 static int hf_afs_bos_size = -1;
458 static int hf_afs_bos_flags = -1;
459 static int hf_afs_bos_date = -1;
460 static int hf_afs_bos_content = -1;
461
462 static int hf_afs_vldb_errcode = -1;
463 static int hf_afs_vldb_name = -1;
464 static int hf_afs_vldb_id = -1;
465 static int hf_afs_vldb_type = -1;
466 static int hf_afs_vldb_bump = -1;
467 static int hf_afs_vldb_index = -1;
468 static int hf_afs_vldb_nextindex = -1;
469 static int hf_afs_vldb_count = -1;
470 static int hf_afs_vldb_numservers = -1;
471 static int hf_afs_vldb_server = -1;
472 static int hf_afs_vldb_serveruuid = -1;
473 static int hf_afs_vldb_partition = -1;
474 static int hf_afs_vldb_rovol = -1;
475 static int hf_afs_vldb_rwvol = -1;
476 static int hf_afs_vldb_bkvol = -1;
477
478 static int hf_afs_kauth_errcode = -1;
479 static int hf_afs_kauth_princ = -1;
480 static int hf_afs_kauth_realm = -1;
481 static int hf_afs_kauth_domain = -1;
482 static int hf_afs_kauth_kvno = -1;
483 static int hf_afs_kauth_name = -1;
484 static int hf_afs_kauth_data = -1;
485
486 static int hf_afs_vol_errcode = -1;
487 static int hf_afs_vol_count = -1;
488 static int hf_afs_vol_id = -1;
489 static int hf_afs_vol_name = -1;
490
491 static int hf_afs_cb_errcode = -1;
492 static int hf_afs_cb_callback_version = -1;
493 static int hf_afs_cb_callback_type = -1;
494 static int hf_afs_cb_callback_expires = -1;
495 static int hf_afs_cb_fid_volume = -1;
496 static int hf_afs_cb_fid_vnode = -1;
497 static int hf_afs_cb_fid_uniqifier = -1;
498
499 static int hf_afs_prot_errcode = -1;
500 static int hf_afs_prot_name = -1;
501 static int hf_afs_prot_id = -1;
502 static int hf_afs_prot_count = -1;
503 static int hf_afs_prot_oldid = -1;
504 static int hf_afs_prot_newid = -1;
505 static int hf_afs_prot_pos = -1;
506 static int hf_afs_prot_flag = -1;
507 static int hf_afs_prot_uid = -1;
508 static int hf_afs_prot_gid = -1;
509 static int hf_afs_prot_maxuid = -1;
510 static int hf_afs_prot_maxgid = -1;
511
512 static int hf_afs_backup_errcode = -1;
513
514 static int hf_afs_ubik_errcode = -1;
515 static int hf_afs_ubik_version_epoch = -1;
516 static int hf_afs_ubik_version_counter = -1;
517 static int hf_afs_ubik_votestart = -1;
518 static int hf_afs_ubik_syncsite = -1;
519 static int hf_afs_ubik_site = -1;
520 static int hf_afs_ubik_file = -1;
521 static int hf_afs_ubik_pos = -1;
522 static int hf_afs_ubik_length = -1;
523 static int hf_afs_ubik_locktype = -1;
524 static int hf_afs_ubik_voteend = -1;
525 static int hf_afs_ubik_votetype = -1;
526
527 /*
528  * Dissector prototypes
529  */
530 static void dissect_fs_request(const u_char *pd,
531         int offset, frame_data *fd, proto_tree *tree, int opcode);
532 static void dissect_fs_reply(const u_char *pd,
533         int offset, frame_data *fd, proto_tree *tree, int opcode);
534 static void dissect_cb_request(const u_char *pd,
535         int offset, frame_data *fd, proto_tree *tree, int opcode);
536 static void dissect_cb_reply(const u_char *pd,
537         int offset, frame_data *fd, proto_tree *tree, int opcode);
538 static void dissect_bos_request(const u_char *pd,
539         int offset, frame_data *fd, proto_tree *tree, int opcode);
540 static void dissect_bos_reply(const u_char *pd,
541         int offset, frame_data *fd, proto_tree *tree, int opcode);
542 static void dissect_vol_request(const u_char *pd,
543         int offset, frame_data *fd, proto_tree *tree, int opcode);
544 static void dissect_vol_reply(const u_char *pd,
545         int offset, frame_data *fd, proto_tree *tree, int opcode);
546 static void dissect_ubik_request(const u_char *pd,
547         int offset, frame_data *fd, proto_tree *tree, int opcode);
548 static void dissect_ubik_reply(const u_char *pd,
549         int offset, frame_data *fd, proto_tree *tree, int opcode);
550 static void dissect_kauth_request(const u_char *pd,
551         int offset, frame_data *fd, proto_tree *tree, int opcode);
552 static void dissect_kauth_reply(const u_char *pd,
553         int offset, frame_data *fd, proto_tree *tree, int opcode);
554 static void dissect_prot_request(const u_char *pd,
555         int offset, frame_data *fd, proto_tree *tree, int opcode);
556 static void dissect_prot_reply(const u_char *pd,
557         int offset, frame_data *fd, proto_tree *tree, int opcode);
558 static void dissect_vldb_request(const u_char *pd,
559         int offset, frame_data *fd, proto_tree *tree, int opcode);
560 static void dissect_vldb_reply(const u_char *pd,
561         int offset, frame_data *fd, proto_tree *tree, int opcode);
562 static void dissect_backup_request(const u_char *pd,
563         int offset, frame_data *fd, proto_tree *tree, int opcode);
564 static void dissect_backup_reply(const u_char *pd,
565         int offset, frame_data *fd, proto_tree *tree, int opcode);
566
567
568 /*
569  * Hash Functions - copied from packet-afs.c
570  */
571 gint
572 afs_equal(gconstpointer v, gconstpointer w)
573 {
574   struct afs_request_key *v1 = (struct afs_request_key *)v;
575   struct afs_request_key *v2 = (struct afs_request_key *)w;
576
577   if (v1 -> ip_src   == v2 -> ip_src &&
578       v1 -> ip_dst   == v2 -> ip_dst &&
579       v1 -> port_src == v2 -> port_src &&
580       v1 -> port_dst == v2 -> port_dst &&
581       v1 -> service  == v2 -> service &&
582       v1 -> callnumber == v2 -> callnumber ) {
583
584     return 1;
585   }
586
587   return 0;
588 }
589
590 guint
591 afs_hash (gconstpointer v)
592 {
593         struct afs_request_key *key = (struct afs_request_key *)v;
594         guint val;
595
596         val = key -> ip_src + key -> ip_dst +
597                 key -> port_src + key -> port_dst +
598                 key -> service + key -> callnumber;
599
600         return val;
601 }
602
603 /*
604  * Protocol initialization
605  */
606 void
607 afs_init_protocol(void)
608 {
609         if (afs_request_hash)
610                 g_hash_table_destroy(afs_request_hash);
611         if (afs_request_keys)
612                 g_mem_chunk_destroy(afs_request_keys);
613         if (afs_request_vals)
614                 g_mem_chunk_destroy(afs_request_vals);
615
616         afs_request_hash = g_hash_table_new(afs_hash, afs_equal);
617         afs_request_keys = g_mem_chunk_new("afs_request_keys",
618                 sizeof(struct afs_request_key),
619                 afs_packet_init_count * sizeof(struct afs_request_key),
620                 G_ALLOC_AND_FREE);
621         afs_request_vals = g_mem_chunk_new("afs_request_vals",
622                 sizeof(struct afs_request_val),
623                 afs_packet_init_count * sizeof(struct afs_request_val),
624                 G_ALLOC_AND_FREE);
625 }
626
627
628
629 /*
630  * Dissection routines
631  */
632
633 void
634 dissect_afs(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
635 {
636         proto_tree      *afs_tree, *afs_op_tree, *ti;
637         struct rx_header *rxh;
638         struct afs_header *afsh;
639         int port, node, typenode, opcode;
640         value_string const *vals;
641         int reply = 0;
642         int doffset = 0;
643         struct afs_request_key request_key, *new_request_key;
644         struct afs_request_val *request_val;
645         void (*dissector)(const u_char *pd, int offset,
646                 frame_data *fd, proto_tree *tree, int opcode);
647
648         rxh = (struct rx_header *) &pd[offset];
649         doffset = offset + sizeof(struct rx_header);
650         afsh = (struct afs_header *) &pd[doffset];
651
652         /* get at least a full packet structure */
653         if ( !BYTES_ARE_IN_FRAME(offset, sizeof(struct rx_header)) )
654                 return;
655
656         if (check_col(fd, COL_PROTOCOL))
657                 col_add_str(fd, COL_PROTOCOL, "AFS (RX)");
658
659         reply = (rxh->flags & RX_CLIENT_INITIATED) == 0;
660         port = ((reply == 0) ? pi.destport : pi.srcport );
661
662         request_key.ip_src   = ((reply == 0) ? pi.ip_src : pi.ip_dst);
663         request_key.ip_dst   = ((reply == 0) ? pi.ip_dst : pi.ip_src);
664         request_key.port_src = ((reply == 0) ? pi.srcport : pi.destport);
665         request_key.port_dst = ((reply == 0) ? pi.destport : pi.srcport);
666         request_key.service = ntohs(rxh->serviceId);
667         request_key.callnumber = ntohl(rxh->callNumber);
668
669         request_val = (struct afs_request_val *) g_hash_table_lookup(
670                 afs_request_hash, &request_key);
671
672         /* only allocate a new hash element when it's a request */
673         opcode = 0;
674         if ( !request_val && !reply)
675         {
676                 new_request_key = g_mem_chunk_alloc(afs_request_keys);
677                 *new_request_key = request_key;
678
679                 request_val = g_mem_chunk_alloc(afs_request_vals);
680                 request_val -> opcode = ntohl(afsh->opcode);
681                 opcode = request_val->opcode;
682
683                 g_hash_table_insert(afs_request_hash, new_request_key,
684                         request_val);
685         }
686
687         if ( request_val )
688         {
689                 opcode = request_val->opcode;
690         }
691
692         node = 0;
693         typenode = 0;
694         vals = NULL;
695         dissector = NULL;
696         switch (port)
697         {
698                 case AFS_PORT_FS:
699                         typenode = hf_afs_fs;
700                         node = hf_afs_fs_opcode;
701                         vals = fs_req;
702                         dissector = reply ? dissect_fs_reply : dissect_fs_request;
703                         break;
704                 case AFS_PORT_CB:
705                         typenode = hf_afs_cb;
706                         node = hf_afs_cb_opcode;
707                         vals = cb_req;
708                         dissector = reply ? dissect_cb_reply : dissect_cb_request;
709                         break;
710                 case AFS_PORT_PROT:
711                         typenode = hf_afs_prot;
712                         node = hf_afs_prot_opcode;
713                         vals = prot_req;
714                         dissector = reply ? dissect_prot_reply : dissect_prot_request;
715                         break;
716                 case AFS_PORT_VLDB:
717                         typenode = hf_afs_vldb;
718                         node = hf_afs_vldb_opcode;
719                         vals = vldb_req;
720                         dissector = reply ? dissect_vldb_reply : dissect_vldb_request;
721                         break;
722                 case AFS_PORT_KAUTH:
723                         typenode = hf_afs_kauth;
724                         node = hf_afs_kauth_opcode;
725                         vals = kauth_req;
726                         dissector = reply ? dissect_kauth_reply : dissect_kauth_request;
727                         break;
728                 case AFS_PORT_VOL:
729                         typenode = hf_afs_vol;
730                         node = hf_afs_vol_opcode;
731                         vals = vol_req;
732                         dissector = reply ? dissect_vol_reply : dissect_vol_request;
733                         break;
734                 case AFS_PORT_ERROR:
735                         typenode = hf_afs_error;
736                         node = hf_afs_error_opcode;
737 //                      dissector = reply ? dissect_error_reply : dissect_error_request;
738                         break;
739                 case AFS_PORT_BOS:
740                         typenode = hf_afs_bos;
741                         node = hf_afs_bos_opcode;
742                         vals = bos_req;
743                         dissector = reply ? dissect_bos_reply : dissect_bos_request;
744                         break;
745                 case AFS_PORT_UPDATE:
746                         typenode = hf_afs_update;
747                         node = hf_afs_update_opcode;
748 //                      dissector = reply ? dissect_update_reply : dissect_update_request;
749                         break;
750                 case AFS_PORT_RMTSYS:
751                         typenode = hf_afs_rmtsys;
752                         node = hf_afs_rmtsys_opcode;
753 //                      dissector = reply ? dissect_rmtsys_reply : dissect_rmtsys_request;
754                         break;
755                 case AFS_PORT_BACKUP:
756                         typenode = hf_afs_backup;
757                         node = hf_afs_backup_opcode;
758                         dissector = reply ? dissect_backup_reply : dissect_backup_request;
759                         break;
760         }
761         if ( (opcode >= VOTE_LOW && opcode <= VOTE_HIGH) ||
762                 (opcode >= DISK_LOW && opcode <= DISK_HIGH) )
763         {
764                 typenode = hf_afs_ubik;
765                 node = hf_afs_ubik_opcode;
766                 vals = ubik_req;
767                 dissector = reply ? dissect_ubik_reply : dissect_ubik_request;
768         }
769
770         if ( vals )
771         {
772                 if (check_col(fd, COL_INFO))
773                         col_add_fstr(fd, COL_INFO, "%s %s: %s (%d)",
774                         val_to_str(port, port_types_short, "Unknown(%d)"),
775                         reply ? "Reply" : "Request",
776                         val_to_str(opcode, vals, "Unknown(%d)"), opcode);
777         }
778         else
779         {
780                 if (check_col(fd, COL_INFO))
781                         col_add_fstr(fd, COL_INFO, "%s %s: Unknown(%d)",
782                         val_to_str(port, port_types_short, "Unknown(%d)"),
783                         reply ? "Reply" : "Request",
784                         opcode);
785         }
786
787         if (tree) {
788                 ti = proto_tree_add_item(tree, proto_afs, doffset, END_OF_FRAME);
789                 afs_tree = proto_item_add_subtree(ti, ETT_AFS);
790
791                 if ( !BYTES_ARE_IN_FRAME(offset, sizeof(struct rx_header) +
792                         sizeof(struct afs_header)) )
793                 {
794                         proto_tree_add_text(afs_tree, doffset, END_OF_FRAME,
795                                 "Service: %s %s (Truncated)",
796                                 val_to_str(port, port_types, "Unknown(%d)"),
797                                 reply ? "Reply" : "Request");
798                                 return;
799                 }
800                 else
801                 {
802                         proto_tree_add_text(afs_tree, doffset, END_OF_FRAME,
803                                 "Service: %s %s",
804                                 val_to_str(port, port_types, "Unknown(%d)"),
805                                 reply ? "Reply" : "Request");
806                 }
807
808                 /* until we do cache, can't handle replies */
809                 ti = NULL;
810                 if ( !reply && node != 0 )
811                 {
812                         ti = proto_tree_add_item(afs_tree,
813                                 node, doffset, 4, opcode);
814                 }
815                 else if ( reply && node != 0 )
816                 {
817                         /* the opcode isn't in this packet */
818                         ti = proto_tree_add_item(afs_tree,
819                                 node, doffset, 0, opcode);
820                 }
821                 else
822                 {
823                         ti = proto_tree_add_text(afs_tree,
824                                 doffset, 0, "Operation: Unknown");
825                 }
826
827                 /* Add the subtree for this particular service */
828                 afs_op_tree = proto_item_add_subtree(ti, ETT_AFS_OP);
829
830                 if ( typenode != 0 )
831                 {
832                         /* indicate the type of request */
833                         proto_tree_add_item_hidden(afs_tree, typenode, doffset, 0, 1);
834                 }
835
836                 /* Process the packet according to what service it is */
837                 if ( dissector )
838                 {
839                         (*dissector)(pd,offset,fd,afs_op_tree,opcode);
840                 }
841         }
842
843         /* if it's the last packet, and it's a reply, remove opcode
844                 from hash */
845         /* ignoring for now, I'm not sure how the chunk deallocation works */
846         if ( rxh->flags & RX_LAST_PACKET && reply )
847         {
848
849         }
850 }
851
852 /*
853  * Macros for helper dissection routines
854  *
855  * The macros are here to save on coding. They assume that
856  * the current offset is in 'curoffset', and that the offset
857  * should be incremented after performing the macro's operation.
858  */
859
860 // Get the next available integer, be sure and call TRUNC beforehand
861 #define GETINT() (ntohl( *((int*)&pd[curoffset]) ))
862
863 // Check if enough bytes are present, if not, return to caller
864 // after adding a 'Truncated' message to tree
865 #define TRUNC(bytes) \
866         if(!BYTES_ARE_IN_FRAME(curoffset,(bytes))) \
867         { proto_tree_add_text(tree,curoffset,END_OF_FRAME,"Truncated"); \
868         return; }
869
870 // Output a unsigned integer, stored into field 'field'
871 // Assumes it is in network byte order, converts to host before using
872 #define UINTOUT(field) \
873         TRUNC(sizeof(guint32)) \
874         proto_tree_add_item(tree,field,curoffset,sizeof(guint32), GETINT()); \
875         curoffset += 4;
876
877 // Output a unsigned integer, stored into field 'field'
878 // Assumes it is in network byte order, converts to host before using
879 #define IPOUT(field) \
880         TRUNC(sizeof(gint32)) \
881         proto_tree_add_item(tree,field,curoffset,sizeof(gint32),\
882                 *((int*)&pd[curoffset]));\
883         curoffset += 4;
884
885 // Output a unix timestamp, after converting to a timeval
886 #define BIGDATEOUT(field) \
887         { struct timeval tv; \
888         TRUNC(2*sizeof(guint32)); \
889         tv.tv_sec = GETINT(); \
890         tv.tv_usec = GETINT(); \
891         proto_tree_add_item(tree,field,curoffset,2*sizeof(guint32),&tv); \
892         curoffset += 8; \
893         }
894
895 // Output a unix timestamp, after converting to a timeval
896 #define DATEOUT(field) \
897         { struct timeval tv; \
898         TRUNC(sizeof(guint32)); \
899         tv.tv_sec = GETINT(); \
900         tv.tv_usec = 0; \
901         proto_tree_add_item(tree,field,curoffset,sizeof(guint32),&tv); \
902         curoffset += 4; \
903         }
904
905
906 // Output a callback
907 #define FS_CALLBACKOUT() \
908         {       proto_tree *save, *ti; \
909                 ti = proto_tree_add_text(tree, curoffset, 3*4, "Callback"); \
910                 save = tree; \
911                 tree = proto_item_add_subtree(ti, ETT_AFS_CALLBACK); \
912                 TRUNC(3*sizeof(guint32)); \
913                 UINTOUT(hf_afs_fs_callback_version); \
914                 BIGDATEOUT(hf_afs_fs_callback_expires); \
915                 UINTOUT(hf_afs_fs_callback_type); \
916                 tree = save; \
917         }
918
919 // Output a callback
920 #define CB_CALLBACKOUT() \
921         {       proto_tree *save, *ti; \
922                 ti = proto_tree_add_text(tree, curoffset, 3*4, "Callback"); \
923                 save = tree; \
924                 tree = proto_item_add_subtree(ti, ETT_AFS_CALLBACK); \
925                 TRUNC(3*sizeof(guint32)); \
926                 UINTOUT(hf_afs_cb_callback_version); \
927                 DATEOUT(hf_afs_cb_callback_expires); \
928                 UINTOUT(hf_afs_cb_callback_type); \
929                 tree = save; \
930         }
931
932
933 // Output a File ID
934 #define FS_FIDOUT(label) \
935         {       proto_tree *save, *ti; \
936                 ti = proto_tree_add_text(tree, curoffset, 3*4, \
937                         "FileID (%s)", label); \
938                 save = tree; \
939                 tree = proto_item_add_subtree(ti, ETT_AFS_FID); \
940                 UINTOUT(hf_afs_fs_fid_volume); \
941                 UINTOUT(hf_afs_fs_fid_vnode); \
942                 UINTOUT(hf_afs_fs_fid_uniqifier); \
943                 tree = save; \
944         }
945
946 // Output a File ID
947 #define CB_FIDOUT(label) \
948         {       proto_tree *save, *ti; \
949                 ti = proto_tree_add_text(tree, curoffset, 3*4, \
950                         "FileID (%s)", label); \
951                 save = tree; \
952                 tree = proto_item_add_subtree(ti, ETT_AFS_FID); \
953                 UINTOUT(hf_afs_cb_fid_volume); \
954                 UINTOUT(hf_afs_cb_fid_vnode); \
955                 UINTOUT(hf_afs_cb_fid_uniqifier); \
956                 tree = save; \
957         }
958
959 // Output a AFS acl
960 //
961 #define ACLOUT(who, positive, acl, bytes) \
962         {       proto_tree *save, *ti; \
963                 int tmpoffset; \
964                 int acllen; \
965                 char tmp[10]; \
966                 tmp[0] = 0; \
967                 if ( acl & PRSFS_READ ) strcat(tmp, "r"); \
968                 if ( acl & PRSFS_LOOKUP ) strcat(tmp, "l"); \
969                 if ( acl & PRSFS_INSERT ) strcat(tmp, "i"); \
970                 if ( acl & PRSFS_DELETE ) strcat(tmp, "d"); \
971                 if ( acl & PRSFS_WRITE ) strcat(tmp, "w"); \
972                 if ( acl & PRSFS_LOCK ) strcat(tmp, "k"); \
973                 if ( acl & PRSFS_ADMINISTER ) strcat(tmp, "a"); \
974                 ti = proto_tree_add_text(tree, curoffset, bytes, \
975                         "ACL:  %s %s%s", \
976                         who, tmp, positive ? "" : " (negative)"); \
977                 save = tree; \
978                 tree = proto_item_add_subtree(ti, ETT_AFS_ACL); \
979                 proto_tree_add_item(tree,hf_afs_fs_acl_entity,curoffset,strlen(who), who);\
980                 tmpoffset = curoffset + strlen(who) + 1; \
981                 acllen = bytes - strlen(who) - 1; \
982                 proto_tree_add_item(tree,hf_afs_fs_acl_r,tmpoffset,acllen,acl);\
983                 proto_tree_add_item(tree,hf_afs_fs_acl_l,tmpoffset,acllen,acl);\
984                 proto_tree_add_item(tree,hf_afs_fs_acl_i,tmpoffset,acllen,acl);\
985                 proto_tree_add_item(tree,hf_afs_fs_acl_d,tmpoffset,acllen,acl);\
986                 proto_tree_add_item(tree,hf_afs_fs_acl_w,tmpoffset,acllen,acl);\
987                 proto_tree_add_item(tree,hf_afs_fs_acl_k,tmpoffset,acllen,acl);\
988                 proto_tree_add_item(tree,hf_afs_fs_acl_a,tmpoffset,acllen,acl);\
989                 tree = save; \
990         }
991
992 // Skip a certain number of bytes
993 #define SKIP(bytes) \
994         TRUNC(bytes) \
995         curoffset += bytes;
996
997 // Raw data - to end of frame
998 #define RAWOUT(field) BYTESOUT(field, offset+END_OF_FRAME-curoffset)
999
1000 // Raw data
1001 #define BYTESOUT(field, bytes) \
1002         TRUNC(bytes); \
1003         proto_tree_add_item(tree,field,curoffset,bytes,\
1004                 (void *)&pd[curoffset]); \
1005         curoffset += bytes;
1006
1007 // Output a rx style string, up to a maximum length
1008 // first 4 bytes - length, then char data
1009 #define STROUT(field) \
1010         {       int i; \
1011                 TRUNC(4); \
1012                 i = ntohl(*((int *) &pd[curoffset])); \
1013                 curoffset += 4; \
1014                 TRUNC(i); \
1015                 if ( i > 0 ) { \
1016                         proto_tree_add_item(tree, field, curoffset-4, i+4, \
1017                         (void *)&pd[curoffset]); \
1018                 } else { \
1019                         proto_tree_add_item(tree, field, curoffset-4, 4, \
1020                         ""); \
1021                 } \
1022                 curoffset += i; \
1023         }
1024
1025 // Output a fixed length vectorized string (each char is a 32 bit int)
1026 #define VECOUT(field, length) \
1027         {       char tmp[length+1]; \
1028                 int i,soff; \
1029                 soff = curoffset;\
1030                 TRUNC(length * sizeof(guint32));\
1031                 for (i=0; i<length; i++)\
1032                 {\
1033                         tmp[i] = (char) GETINT();\
1034                         curoffset += sizeof(guint32);\
1035                 }\
1036                 tmp[length] = '\0';\
1037                 proto_tree_add_item(tree, field, soff, length, tmp);\
1038         }
1039
1040 // Output a UBIK version code
1041 #define UBIK_VERSIONOUT(label) \
1042         {       proto_tree *save, *ti; \
1043                 unsigned int epoch,counter; \
1044                 struct timeval tv; \
1045                 TRUNC(8); \
1046                 epoch = GETINT(); \
1047                 curoffset += 4; \
1048                 counter = GETINT(); \
1049                 curoffset += 4; \
1050                 tv.tv_sec = epoch; \
1051                 tv.tv_usec = 0; \
1052                 ti = proto_tree_add_text(tree, curoffset, 3*4, \
1053                         "UBIK Version (%s): %u.%u", label, epoch, counter ); \
1054                 save = tree; \
1055                 tree = proto_item_add_subtree(ti, ETT_AFS_UBIKVER); \
1056                 proto_tree_add_item(tree,hf_afs_ubik_version_epoch,curoffset-8, \
1057                         sizeof(guint32),&tv); \
1058                 proto_tree_add_item(tree,hf_afs_ubik_version_counter,curoffset-4, \
1059                         sizeof(guint32),counter); \
1060                 tree = save; \
1061         }
1062
1063 /*
1064  * Here is a helper routine for adding an AFS acl to the proto tree
1065  * This is to be used with FS packets only
1066  *
1067  * An AFS ACL is a string that has the following format:
1068  *
1069  * <positive> <negative>
1070  * <uid1> <aclbits1>
1071  * ....
1072  *
1073  * "positive" and "negative" are integers which contain the number of
1074  * positive and negative ACL's in the string.  The uid/aclbits pair are
1075  * ASCII strings containing the UID/PTS record and and a ascii number
1076  * representing a logical OR of all the ACL permission bits
1077  */
1078
1079 static void dissect_acl(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
1080 {
1081         int pos, neg, acl;
1082         int n, i, bytes;
1083         u_char const *s;
1084         u_char const *end;
1085         char user[128];
1086         int curoffset;
1087         int soff,eoff;
1088
1089         curoffset = offset;
1090
1091         TRUNC(sizeof(guint32));
1092         bytes = ntohl(*((int *) &pd[curoffset]));
1093         UINTOUT(hf_afs_fs_acl_datasize);
1094
1095         TRUNC(bytes);
1096
1097         soff = curoffset;
1098         eoff = curoffset+bytes;
1099
1100         s = &pd[soff];
1101         end = &pd[eoff];
1102
1103         if (sscanf((char *) s, "%d %n", &pos, &n) != 1)
1104                 return;
1105         s += n;
1106         TRUNC(1);
1107         proto_tree_add_item(tree, hf_afs_fs_acl_count_positive, curoffset, n, pos);
1108         curoffset += n;
1109
1110         if (sscanf((char *) s, "%d %n", &neg, &n) != 1)
1111                 return;
1112         s += n;
1113         TRUNC(1);
1114         proto_tree_add_item(tree, hf_afs_fs_acl_count_negative, curoffset, n, neg);
1115         curoffset += n;
1116
1117
1118         /*
1119          * This wacky order preserves the order used by the "fs" command
1120          */
1121
1122         for (i = 0; i < pos; i++) {
1123                 if (sscanf((char *) s, "%s %d %n", user, &acl, &n) != 2)
1124                         return;
1125                 s += n;
1126                 ACLOUT(user,1,acl,n);
1127                 curoffset += n;
1128                 TRUNC(1);
1129         }
1130
1131         for (i = 0; i < neg; i++) {
1132                 if (sscanf((char *) s, "%s %d %n", user, &acl, &n) != 2)
1133                         return;
1134                 s += n;
1135                 ACLOUT(user,0,acl,n);
1136                 curoffset += n;
1137                 if (s > end)
1138                         return;
1139         }
1140 }
1141
1142 /*
1143  * Here are the helper dissection routines
1144  */
1145
1146 static void
1147 dissect_fs_reply(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int opcode)
1148 {
1149         struct rx_header *rxh;
1150         unsigned char *data;
1151         int doffset, curoffset;
1152
1153         rxh = (struct rx_header *) &pd[offset];
1154         data = (char *)rxh + sizeof(struct rx_header);
1155         doffset = offset + sizeof(struct rx_header);
1156         curoffset = doffset;
1157
1158         if ( rxh->type == RX_PACKET_TYPE_DATA )
1159         {
1160                 switch ( opcode )
1161                 {
1162                         case 130: /* fetch data */
1163                                 RAWOUT(hf_afs_fs_data);
1164                                 break;
1165                         case 131: /* fetch acl */
1166                                 dissect_acl(pd,curoffset,fd,tree);
1167                                 break;
1168                         case 137: /* create file */
1169                                 FS_FIDOUT("New File");
1170                                 break;
1171                         case 141: /* make dir */
1172                                 FS_FIDOUT("New Directory");
1173                                 break;
1174                         case 151: /* root volume */
1175                                 STROUT(hf_afs_fs_volname);
1176                                 break;
1177                         case 153: /* get time */
1178                                 BIGDATEOUT(hf_afs_fs_timestamp);
1179                                 break;
1180                 }
1181         }
1182         else if ( rxh->type == RX_PACKET_TYPE_ABORT )
1183         {
1184                 UINTOUT(hf_afs_fs_errcode);
1185         }
1186 }
1187
1188 static void
1189 dissect_fs_request(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int opcode)
1190 {
1191         struct rx_header *rxh;
1192         unsigned char *data;
1193         int doffset, curoffset;
1194
1195         rxh = (struct rx_header *) &pd[offset];
1196         data = (char *)rxh + sizeof(struct rx_header);
1197         doffset = offset + sizeof(struct rx_header);
1198         curoffset = doffset;
1199
1200         /* skip opcode */
1201         SKIP(sizeof(guint32));
1202
1203         switch ( opcode )
1204         {
1205                 case 130: /* Fetch data */
1206                         FS_FIDOUT("Source");
1207                         UINTOUT(hf_afs_fs_offset);
1208                         UINTOUT(hf_afs_fs_length);
1209                         break;
1210                 case 131: /* Fetch ACL */
1211                 case 132: /* Fetch Status */
1212                 case 135: /* Store Status */
1213                 case 143: /* Old Set Lock */
1214                 case 144: /* Old Extend Lock */
1215                 case 145: /* Old Release Lock */
1216                 case 156: /* Set Lock */
1217                 case 157: /* Extend Lock */
1218                 case 158: /* Release Lock */
1219                         FS_FIDOUT("Target");
1220                         break;
1221                 case 133: /* Store Data */
1222                         FS_FIDOUT("Destination");
1223                         SKIP(6*sizeof(guint32));
1224                         UINTOUT(hf_afs_fs_offset);
1225                         UINTOUT(hf_afs_fs_length);
1226                         UINTOUT(hf_afs_fs_flength);
1227                         break;
1228                 case 134: /* Store ACL */
1229                         FS_FIDOUT("Target");
1230                         dissect_acl(pd,curoffset,fd,tree);
1231                         /* print acl */
1232                         break;
1233                 case 136: /* Remove File */
1234                 case 137: /* Create File */
1235                 case 141: /* Make dir */
1236                 case 142: /* Remove dir */
1237                         FS_FIDOUT("Target");
1238                         STROUT(hf_afs_fs_name);
1239                         break;
1240                 case 138: /* Rename file */
1241                         FS_FIDOUT("Old");
1242                         STROUT(hf_afs_fs_oldname);
1243                         FS_FIDOUT("New");
1244                         STROUT(hf_afs_fs_newname);
1245                         break;
1246                 case 139: /* Symlink */
1247                         FS_FIDOUT("File");
1248                         STROUT(hf_afs_fs_symlink_name);
1249                         STROUT(hf_afs_fs_symlink_content);
1250                         break;
1251                 case 140: /* Link */
1252                         FS_FIDOUT("Link From (Old File)");
1253                         STROUT(hf_afs_fs_name);
1254                         FS_FIDOUT("Link To (New File)");
1255                         break;
1256                 case 148: /* Get vol info */
1257                         STROUT(hf_afs_fs_volname);
1258                         break;
1259                 case 149: /* Get vol stats */
1260                 case 150: /* Set vol stats */
1261                         UINTOUT(hf_afs_fs_volid);
1262                         break;
1263                 case 154: /* new get vol info */
1264                         STROUT(hf_afs_fs_volname);
1265                         break;
1266                 case 155: /* bulk stat */
1267                 {
1268                         unsigned int j,i;
1269                         TRUNC(1);
1270
1271                         j = ntohl( *((int*)&pd[curoffset]) );
1272                         curoffset += 1;
1273                         for (i=0; i<j; i++)
1274                         {
1275                                 FS_FIDOUT("Target");
1276                         }
1277                         break;
1278                 }
1279         }
1280 }
1281
1282 /*
1283  * BOS Helpers
1284  */
1285 static void
1286 dissect_bos_reply(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int opcode)
1287 {
1288         struct rx_header *rxh;
1289         unsigned char *data;
1290         int doffset, curoffset;
1291
1292         rxh = (struct rx_header *) &pd[offset];
1293         data = (char *)rxh + sizeof(struct rx_header);
1294         doffset = offset + sizeof(struct rx_header);
1295         curoffset = doffset;
1296
1297         if ( rxh->type == RX_PACKET_TYPE_DATA )
1298         {
1299                 switch ( opcode )
1300                 {
1301                         case 85: /* get instance info */
1302                                 STROUT(hf_afs_bos_type);
1303                                 break;
1304                 }
1305         }
1306         else if ( rxh->type == RX_PACKET_TYPE_ABORT )
1307         {
1308                 UINTOUT(hf_afs_bos_errcode);
1309         }
1310 }
1311
1312 static void
1313 dissect_bos_request(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int opcode)
1314 {
1315         struct rx_header *rxh;
1316         unsigned char *data;
1317         int doffset, curoffset;
1318
1319         rxh = (struct rx_header *) &pd[offset];
1320         data = (char *)rxh + sizeof(struct rx_header);
1321         doffset = offset + sizeof(struct rx_header);
1322         curoffset = doffset;
1323
1324         /* skip opcode */
1325         SKIP(sizeof(guint32));
1326
1327         switch ( opcode )
1328         {
1329                 case 80: /* create b node */
1330                         STROUT(hf_afs_bos_type);
1331                         STROUT(hf_afs_bos_instance);
1332                         break;
1333                 case 81: /* delete b node */
1334                 case 83: /* get status */
1335                 case 85: /* get instance info */
1336                 case 87: /* add super user */
1337                 case 88: /* delete super user */
1338                 case 93: /* set cell name */
1339                 case 96: /* add cell host */
1340                 case 97: /* delete cell host */
1341                 case 104: /* restart */
1342                 case 106: /* uninstall */
1343                 case 108: /* exec */
1344                 case 112: /* get log */
1345                 case 114: /* get instance strings */
1346                         STROUT(hf_afs_bos_content);
1347                         break;
1348                 case 82: /* set status */
1349                 case 98: /* set t status */
1350                         STROUT(hf_afs_bos_content);
1351                         UINTOUT(hf_afs_bos_status);
1352                         break;
1353                 case 86: /* get instance parm */
1354                         STROUT(hf_afs_bos_instance);
1355                         UINTOUT(hf_afs_bos_num);
1356                         break;
1357                 case 84: /* enumerate instance */
1358                 case 89: /* list super users */
1359                 case 90: /* list keys */
1360                 case 91: /* add key */
1361                 case 92: /* delete key */
1362                 case 95: /* set cell host */
1363                         UINTOUT(hf_afs_bos_num);
1364                         break;
1365                 case 105: /* install */
1366                         STROUT(hf_afs_bos_content);
1367                         UINTOUT(hf_afs_bos_size);
1368                         UINTOUT(hf_afs_bos_flags);
1369                         UINTOUT(hf_afs_bos_date);
1370                         break;
1371         }
1372 }
1373
1374 /*
1375  * VOL Helpers
1376  */
1377 static void
1378 dissect_vol_reply(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int opcode)
1379 {
1380         struct rx_header *rxh;
1381         unsigned char *data;
1382         int doffset, curoffset;
1383
1384         rxh = (struct rx_header *) &pd[offset];
1385         data = (char *)rxh + sizeof(struct rx_header);
1386         doffset = offset + sizeof(struct rx_header);
1387         curoffset = doffset;
1388
1389         if ( rxh->type == RX_PACKET_TYPE_DATA )
1390         {
1391                 switch ( opcode )
1392                 {
1393                         case 121:
1394                                 /* should loop here maybe */
1395                                 UINTOUT(hf_afs_vol_count);
1396                                 VECOUT(hf_afs_vol_name, 32); /* not sure on  */
1397                                 break;
1398                 }
1399         }
1400         else if ( rxh->type == RX_PACKET_TYPE_ABORT )
1401         {
1402                 UINTOUT(hf_afs_vol_errcode);
1403         }
1404 }
1405
1406 static void
1407 dissect_vol_request(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int opcode)
1408 {
1409         struct rx_header *rxh;
1410         unsigned char *data;
1411         int doffset, curoffset;
1412
1413         rxh = (struct rx_header *) &pd[offset];
1414         data = (char *)rxh + sizeof(struct rx_header);
1415         doffset = offset + sizeof(struct rx_header);
1416         curoffset = doffset;
1417
1418         /* skip opcode */
1419         SKIP(sizeof(guint32));
1420
1421         switch ( opcode )
1422         {
1423                 case 121: /* list one vol */
1424                         UINTOUT(hf_afs_vol_count);
1425                         UINTOUT(hf_afs_vol_id);
1426                         break;
1427         }
1428 }
1429
1430 /*
1431  * KAUTH Helpers
1432  */
1433 static void
1434 dissect_kauth_reply(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int opcode)
1435 {
1436         struct rx_header *rxh;
1437         unsigned char *data;
1438         int doffset, curoffset;
1439
1440         rxh = (struct rx_header *) &pd[offset];
1441         data = (char *)rxh + sizeof(struct rx_header);
1442         doffset = offset + sizeof(struct rx_header);
1443         curoffset = doffset;
1444
1445         if ( rxh->type == RX_PACKET_TYPE_DATA )
1446         {
1447                 switch ( opcode )
1448                 {
1449                 }
1450         }
1451         else if ( rxh->type == RX_PACKET_TYPE_ABORT )
1452         {
1453                 UINTOUT(hf_afs_kauth_errcode);
1454         }
1455 }
1456
1457 static void
1458 dissect_kauth_request(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int opcode)
1459 {
1460         struct rx_header *rxh;
1461         unsigned char *data;
1462         int doffset, curoffset;
1463
1464         rxh = (struct rx_header *) &pd[offset];
1465         data = (char *)rxh + sizeof(struct rx_header);
1466         doffset = offset + sizeof(struct rx_header);
1467         curoffset = doffset;
1468
1469         /* skip opcode */
1470         SKIP(sizeof(guint32));
1471
1472         switch ( opcode )
1473         {
1474                 case 1: /* authenticate old */
1475                 case 21: /* authenticate */
1476                 case 22: /* authenticate v2 */
1477                 case 2: /* change pw */
1478                 case 5: /* set fields */
1479                 case 6: /* create user */
1480                 case 7: /* delete user */
1481                 case 8: /* get entry */
1482                 case 14: /* unlock */
1483                 case 15: /* lock status */
1484                         STROUT(hf_afs_kauth_princ);
1485                         STROUT(hf_afs_kauth_realm);
1486                         RAWOUT(hf_afs_kauth_data);
1487                         break;
1488                 case 3: /* getticket-old */
1489                 case 23: /* getticket */
1490                         UINTOUT(hf_afs_kauth_kvno);
1491                         STROUT(hf_afs_kauth_domain);
1492                         STROUT(hf_afs_kauth_data);
1493                         STROUT(hf_afs_kauth_princ);
1494                         STROUT(hf_afs_kauth_realm);
1495                         break;
1496                 case 4: /* set pass */
1497                         STROUT(hf_afs_kauth_princ);
1498                         STROUT(hf_afs_kauth_realm);
1499                         UINTOUT(hf_afs_kauth_kvno);
1500                         break;
1501                 case 12: /* get pass */
1502                         STROUT(hf_afs_kauth_name);
1503                         break;
1504         }
1505 }
1506
1507 /*
1508  * CB Helpers
1509  */
1510 static void
1511 dissect_cb_reply(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int opcode)
1512 {
1513         struct rx_header *rxh;
1514         unsigned char *data;
1515         int doffset, curoffset;
1516
1517         rxh = (struct rx_header *) &pd[offset];
1518         data = (char *)rxh + sizeof(struct rx_header);
1519         doffset = offset + sizeof(struct rx_header);
1520         curoffset = doffset;
1521
1522         if ( rxh->type == RX_PACKET_TYPE_DATA )
1523         {
1524                 switch ( opcode )
1525                 {
1526                 }
1527         }
1528         else if ( rxh->type == RX_PACKET_TYPE_ABORT )
1529         {
1530                 UINTOUT(hf_afs_cb_errcode);
1531         }
1532 }
1533
1534 static void
1535 dissect_cb_request(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int opcode)
1536 {
1537         struct rx_header *rxh;
1538         unsigned char *data;
1539         int doffset, curoffset;
1540
1541         rxh = (struct rx_header *) &pd[offset];
1542         data = (char *)rxh + sizeof(struct rx_header);
1543         doffset = offset + sizeof(struct rx_header);
1544         curoffset = doffset;
1545
1546         /* skip opcode */
1547         SKIP(sizeof(guint32));
1548
1549         switch ( opcode )
1550         {
1551                 case 204: /* callback */
1552                 {
1553                         unsigned int i,j;
1554
1555                         TRUNC(4);
1556                         j = GETINT();
1557
1558                         for (i=0; i<j; i++)
1559                         {
1560                                 CB_FIDOUT("Target");
1561                         }
1562
1563                         TRUNC(4);
1564                         j = GETINT();
1565                         for (i=0; i<j; i++)
1566                         {
1567                                 CB_CALLBACKOUT();
1568                         }
1569                 }
1570         }
1571 }
1572
1573 /*
1574  * PROT Helpers
1575  */
1576 static void
1577 dissect_prot_reply(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int opcode)
1578 {
1579         struct rx_header *rxh;
1580         unsigned char *data;
1581         int doffset, curoffset;
1582
1583         rxh = (struct rx_header *) &pd[offset];
1584         data = (char *)rxh + sizeof(struct rx_header);
1585         doffset = offset + sizeof(struct rx_header);
1586         curoffset = doffset;
1587
1588         if ( rxh->type == RX_PACKET_TYPE_DATA )
1589         {
1590                 switch ( opcode )
1591                 {
1592                         case 504: /* name to id */
1593                                 {
1594                                         unsigned int i, j;
1595
1596                                         TRUNC(4);
1597                                         j = GETINT();
1598                                         UINTOUT(hf_afs_prot_count);
1599
1600                                         for (i=0; i<j; i++)
1601                                         {
1602                                                 UINTOUT(hf_afs_prot_id);
1603                                         }
1604                                 }
1605                                 break;
1606                         case 505: /* id to name */
1607                                 {
1608                                         unsigned int i, j;
1609
1610                                         TRUNC(4);
1611                                         j = GETINT();
1612                                         UINTOUT(hf_afs_prot_count);
1613
1614                                         for (i=0; i<j; i++)
1615                                         {
1616                                                 VECOUT(hf_afs_prot_name, PRNAMEMAX);
1617                                         }
1618                                 }
1619                                 break;
1620                         case 508: /* get cps */
1621                         case 514: /* list elements */
1622                         case 517: /* list owned */
1623                         case 518: /* get cps2 */
1624                         case 519: /* get host cps */
1625                                 {
1626                                         unsigned int i, j;
1627
1628                                         TRUNC(4);
1629                                         j = GETINT();
1630                                         UINTOUT(hf_afs_prot_count);
1631
1632                                         for (i=0; i<j; i++)
1633                                         {
1634                                                 UINTOUT(hf_afs_prot_id);
1635                                         }
1636                                 }
1637                                 break;
1638                         case 510: /* list max */
1639                                 UINTOUT(hf_afs_prot_maxuid);
1640                                 UINTOUT(hf_afs_prot_maxgid);
1641                                 break;
1642                 }
1643         }
1644         else if ( rxh->type == RX_PACKET_TYPE_ABORT )
1645         {
1646                 UINTOUT(hf_afs_prot_errcode);
1647         }
1648 }
1649
1650 static void
1651 dissect_prot_request(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int opcode)
1652 {
1653         struct rx_header *rxh;
1654         unsigned char *data;
1655         int doffset, curoffset;
1656
1657         rxh = (struct rx_header *) &pd[offset];
1658         data = (char *)rxh + sizeof(struct rx_header);
1659         doffset = offset + sizeof(struct rx_header);
1660         curoffset = doffset;
1661
1662         /* skip opcode */
1663         SKIP(sizeof(guint32));
1664
1665         switch ( opcode )
1666         {
1667                 case 500: /* new user */
1668                         STROUT(hf_afs_prot_name);
1669                         UINTOUT(hf_afs_prot_id);
1670                         UINTOUT(hf_afs_prot_oldid);
1671                         break;
1672                 case 501: /* where is it */
1673                 case 506: /* delete */
1674                 case 508: /* get cps */
1675                 case 512: /* list entry */
1676                 case 514: /* list elements */
1677                 case 517: /* list owned */
1678                 case 519: /* get host cps */
1679                         UINTOUT(hf_afs_prot_id);
1680                         break;
1681                 case 502: /* dump entry */
1682                         UINTOUT(hf_afs_prot_pos);
1683                         break;
1684                 case 503: /* add to group */
1685                 case 507: /* remove from group */
1686                 case 515: /* is a member of? */
1687                         UINTOUT(hf_afs_prot_uid);
1688                         UINTOUT(hf_afs_prot_gid);
1689                         break;
1690                 case 504: /* name to id */
1691                         {
1692                                 unsigned int i, j;
1693
1694                                 TRUNC(4);
1695                                 j = GETINT();
1696                                 UINTOUT(hf_afs_prot_count);
1697
1698                                 for (i=0; i<j; i++)
1699                                 {
1700                                         VECOUT(hf_afs_prot_name,PRNAMEMAX);
1701                                 }
1702                         }
1703                         break;
1704                 case 505: /* id to name */
1705                         {
1706                                 unsigned int i, j;
1707
1708                                 TRUNC(4);
1709                                 j = GETINT();
1710                                 UINTOUT(hf_afs_prot_count);
1711
1712                                 for (i=0; i<j; i++)
1713                                 {
1714                                         UINTOUT(hf_afs_prot_id);
1715                                 }
1716                         }
1717                         break;
1718                 case 509: /* new entry */
1719                         STROUT(hf_afs_prot_name);
1720                         UINTOUT(hf_afs_prot_flag);
1721                         UINTOUT(hf_afs_prot_oldid);
1722                         break;
1723                 case 511: /* set max */
1724                         UINTOUT(hf_afs_prot_id);
1725                         UINTOUT(hf_afs_prot_flag);
1726                         break;
1727                 case 513: /* change entry */
1728                         UINTOUT(hf_afs_prot_id);
1729                         STROUT(hf_afs_prot_name);
1730                         UINTOUT(hf_afs_prot_oldid);
1731                         UINTOUT(hf_afs_prot_newid);
1732                         break;
1733                 case 520: /* update entry */
1734                         UINTOUT(hf_afs_prot_id);
1735                         STROUT(hf_afs_prot_name);
1736                         break;
1737         }
1738 }
1739
1740 /*
1741  * VLDB Helpers
1742  */
1743 static void
1744 dissect_vldb_reply(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int opcode)
1745 {
1746         struct rx_header *rxh;
1747         unsigned char *data;
1748         int doffset, curoffset;
1749
1750         rxh = (struct rx_header *) &pd[offset];
1751         data = (char *)rxh + sizeof(struct rx_header);
1752         doffset = offset + sizeof(struct rx_header);
1753         curoffset = doffset;
1754
1755         if ( rxh->type == RX_PACKET_TYPE_DATA )
1756         {
1757                 switch ( opcode )
1758                 {
1759                         case 510: /* list entry */
1760                                 UINTOUT(hf_afs_vldb_count);
1761                                 UINTOUT(hf_afs_vldb_nextindex);
1762                                 break;
1763                         case 503: /* get entry by id */
1764                         case 504: /* get entry by name */
1765                                 {
1766                                         int nservers,i,j;
1767                                         VECOUT(hf_afs_vldb_name, VLNAMEMAX);
1768                                         TRUNC(4);
1769                                         nservers = GETINT();
1770                                         UINTOUT(hf_afs_vldb_numservers);
1771                                         for (i=0; i<8; i++)
1772                                         {
1773                                                 if ( i<nservers )
1774                                                 {
1775                                                         IPOUT(hf_afs_vldb_server);
1776                                                 }
1777                                                 else
1778                                                 {
1779                                                         SKIP(4);
1780                                                 }
1781                                         }
1782                                         for (i=0; i<8; i++)
1783                                         {
1784                                                 char part[8];
1785                                                 TRUNC(4);
1786                                                 j = GETINT();
1787                                                 strcpy(part, "/vicepa");
1788                                                 if ( i<nservers && j<=26 )
1789                                                 {
1790                                                         part[6] = (char) j;
1791                                                         proto_tree_add_item(tree, hf_afs_vldb_partition,
1792                                                                 curoffset, 4, part);
1793                                                 }
1794                                                 SKIP(4);
1795                                         }
1796                                         SKIP(8 * sizeof(guint32));
1797                                         UINTOUT(hf_afs_vldb_rwvol);
1798                                         UINTOUT(hf_afs_vldb_rovol);
1799                                         UINTOUT(hf_afs_vldb_bkvol);
1800                                 }
1801                                 break;
1802                         case 505: /* get new volume id */
1803                                 UINTOUT(hf_afs_vldb_id);
1804                                 break;
1805                         case 521: /* list entry */
1806                         case 529: /* list entry U */
1807                                 UINTOUT(hf_afs_vldb_count);
1808                                 UINTOUT(hf_afs_vldb_nextindex);
1809                                 break;
1810                         case 518: /* get entry by id n */
1811                         case 519: /* get entry by name N */
1812                                 {
1813                                         int nservers,i,j;
1814                                         VECOUT(hf_afs_vldb_name, VLNAMEMAX);
1815                                         TRUNC(4);
1816                                         nservers = GETINT();
1817                                         UINTOUT(hf_afs_vldb_numservers);
1818                                         for (i=0; i<13; i++)
1819                                         {
1820                                                 if ( i<nservers )
1821                                                 {
1822                                                         IPOUT(hf_afs_vldb_server);
1823                                                 }
1824                                                 else
1825                                                 {
1826                                                         SKIP(4);
1827                                                 }
1828                                         }
1829                                         for (i=0; i<13; i++)
1830                                         {
1831                                                 char part[8];
1832                                                 TRUNC(4);
1833                                                 j = GETINT();
1834                                                 strcpy(part, "/vicepa");
1835                                                 if ( i<nservers && j<=26 )
1836                                                 {
1837                                                         part[6] = (char) j;
1838                                                         proto_tree_add_item(tree, hf_afs_vldb_partition,
1839                                                                 curoffset, 4, part);
1840                                                 }
1841                                                 SKIP(4);
1842                                         }
1843                                         SKIP(13 * sizeof(guint32));
1844                                         UINTOUT(hf_afs_vldb_rwvol);
1845                                         UINTOUT(hf_afs_vldb_rovol);
1846                                         UINTOUT(hf_afs_vldb_bkvol);
1847                                 }
1848                                 break;
1849                         case 526: /* get entry by id u */
1850                         case 527: /* get entry by name u */
1851                                 {
1852                                         int nservers,i,j;
1853                                         VECOUT(hf_afs_vldb_name, VLNAMEMAX);
1854                                         TRUNC(4);
1855                                         nservers = GETINT();
1856                                         UINTOUT(hf_afs_vldb_numservers);
1857                                         for (i=0; i<13; i++)
1858                                         {
1859                                                 if ( i<nservers )
1860                                                 {
1861                                                         BYTESOUT(hf_afs_vldb_serveruuid, 11*sizeof(guint32));
1862                                                 }
1863                                                 else
1864                                                 {
1865                                                         SKIP(11*sizeof(guint32));
1866                                                 }
1867                                         }
1868                                         for (i=0; i<13; i++)
1869                                         {
1870                                                 char part[8];
1871                                                 TRUNC(4);
1872                                                 j = GETINT();
1873                                                 strcpy(part, "/vicepa");
1874                                                 if ( i<nservers && j<=26 )
1875                                                 {
1876                                                         part[6] = (char) j;
1877                                                         proto_tree_add_item(tree, hf_afs_vldb_partition,
1878                                                                 curoffset, 4, part);
1879                                                 }
1880                                                 SKIP(4);
1881                                         }
1882                                         SKIP(13 * sizeof(guint32));
1883                                         UINTOUT(hf_afs_vldb_rwvol);
1884                                         UINTOUT(hf_afs_vldb_rovol);
1885                                         UINTOUT(hf_afs_vldb_bkvol);
1886                                 }
1887                                 break;
1888                 }
1889         }
1890         else if ( rxh->type == RX_PACKET_TYPE_ABORT )
1891         {
1892                 UINTOUT(hf_afs_vldb_errcode);
1893         }
1894 }
1895
1896 static void
1897 dissect_vldb_request(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int opcode)
1898 {
1899         struct rx_header *rxh;
1900         unsigned char *data;
1901         int doffset, curoffset;
1902
1903         rxh = (struct rx_header *) &pd[offset];
1904         data = (char *)rxh + sizeof(struct rx_header);
1905         doffset = offset + sizeof(struct rx_header);
1906         curoffset = doffset;
1907
1908         /* skip opcode */
1909         SKIP(sizeof(guint32));
1910
1911         switch ( opcode )
1912         {
1913                 case 501: /* create new volume */
1914                 case 517: /* create entry N */
1915                         VECOUT(hf_afs_vldb_name, VLNAMEMAX);
1916                         break;
1917                 case 502: /* delete entry */
1918                 case 503: /* get entry by id */
1919                 case 507: /* update entry */
1920                 case 508: /* set lock */
1921                 case 509: /* release lock */
1922                 case 518: /* get entry by id */
1923                         UINTOUT(hf_afs_vldb_id);
1924                         UINTOUT(hf_afs_vldb_type);
1925                         break;
1926                 case 504: /* get entry by name */
1927                 case 519: /* get entry by name N */
1928                 case 524: /* update entry by name */
1929                 case 527: /* get entry by name U */
1930                         STROUT(hf_afs_vldb_name);
1931                         break;
1932                 case 505: /* get new vol id */
1933                         UINTOUT(hf_afs_vldb_bump);
1934                         break;
1935                 case 506: /* replace entry */
1936                 case 520: /* replace entry N */
1937                         UINTOUT(hf_afs_vldb_id);
1938                         UINTOUT(hf_afs_vldb_type);
1939                         VECOUT(hf_afs_vldb_name, VLNAMEMAX);
1940                         break;
1941                 case 510: /* list entry */
1942                 case 521: /* list entry N */
1943                         UINTOUT(hf_afs_vldb_index);
1944                         break;
1945         }
1946 }
1947
1948 /*
1949  * UBIK Helpers
1950  */
1951 static void
1952 dissect_ubik_reply(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int opcode)
1953 {
1954         struct rx_header *rxh;
1955         unsigned char *data;
1956         int doffset, curoffset;
1957
1958         rxh = (struct rx_header *) &pd[offset];
1959         data = (char *)rxh + sizeof(struct rx_header);
1960         doffset = offset + sizeof(struct rx_header);
1961         curoffset = doffset;
1962
1963         if ( rxh->type == RX_PACKET_TYPE_DATA )
1964         {
1965                 switch ( opcode )
1966                 {
1967                         case 10000: /* beacon */
1968                                 proto_tree_add_item(tree,hf_afs_ubik_votetype,0,0,0);
1969                                 break;
1970                         case 20004: /* get version */
1971                                 UBIK_VERSIONOUT("DB Version");
1972                                 break;
1973                 }
1974         }
1975         else if ( rxh->type == RX_PACKET_TYPE_ABORT )
1976         {
1977                 switch ( opcode )
1978                 {
1979                         case 10000:
1980                                 proto_tree_add_item(tree,hf_afs_ubik_votetype,0,0,1);
1981                                 DATEOUT(hf_afs_ubik_voteend);
1982                                 break;
1983                         default:
1984                                 UINTOUT(hf_afs_ubik_errcode);
1985                                 break;
1986                 }
1987         }
1988 }
1989
1990 static void
1991 dissect_ubik_request(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int opcode)
1992 {
1993         struct rx_header *rxh;
1994         unsigned char *data;
1995         int doffset, curoffset;
1996
1997         rxh = (struct rx_header *) &pd[offset];
1998         data = (char *)rxh + sizeof(struct rx_header);
1999         doffset = offset + sizeof(struct rx_header);
2000         curoffset = doffset;
2001
2002         /* skip opcode */
2003         SKIP(sizeof(guint32));
2004
2005         switch ( opcode )
2006         {
2007                 case 10000: /* beacon */
2008                         UINTOUT(hf_afs_ubik_syncsite);
2009                         DATEOUT(hf_afs_ubik_votestart);
2010                         UBIK_VERSIONOUT("DB Version");
2011                         UBIK_VERSIONOUT("TID");
2012                         break;
2013                 case 10003: /* get sync site */
2014                         IPOUT(hf_afs_ubik_site);
2015                         break;
2016                 case 20000: /* begin */
2017                 case 20001: /* commit */
2018                 case 20007: /* abort */
2019                 case 20008: /* release locks */
2020                 case 20010: /* writev */
2021                         UBIK_VERSIONOUT("TID");
2022                         break;
2023                 case 20002: /* lock */
2024                         UBIK_VERSIONOUT("TID");
2025                         UINTOUT(hf_afs_ubik_file);
2026                         UINTOUT(hf_afs_ubik_pos);
2027                         UINTOUT(hf_afs_ubik_length);
2028                         UINTOUT(hf_afs_ubik_locktype);
2029                         break;
2030                 case 20003: /* write */
2031                         UBIK_VERSIONOUT("TID");
2032                         UINTOUT(hf_afs_ubik_file);
2033                         UINTOUT(hf_afs_ubik_pos);
2034                         break;
2035                 case 20005: /* get file */
2036                         UINTOUT(hf_afs_ubik_file);
2037                         break;
2038                 case 20006: /* send file */
2039                         UINTOUT(hf_afs_ubik_file);
2040                         UINTOUT(hf_afs_ubik_length);
2041                         UBIK_VERSIONOUT("DB Version");
2042                         break;
2043                 case 20009: /* truncate */
2044                         UBIK_VERSIONOUT("TID");
2045                         UINTOUT(hf_afs_ubik_file);
2046                         UINTOUT(hf_afs_ubik_length);
2047                         break;
2048                 case 20012: /* set version */
2049                         UBIK_VERSIONOUT("TID");
2050                         UBIK_VERSIONOUT("Old DB Version");
2051                         UBIK_VERSIONOUT("New DB Version");
2052                         break;
2053         }
2054 }
2055
2056 /*
2057  * BACKUP Helpers
2058  */
2059 static void
2060 dissect_backup_reply(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int opcode)
2061 {
2062         struct rx_header *rxh;
2063         unsigned char *data;
2064         int doffset, curoffset;
2065
2066         rxh = (struct rx_header *) &pd[offset];
2067         data = (char *)rxh + sizeof(struct rx_header);
2068         doffset = offset + sizeof(struct rx_header);
2069         curoffset = doffset;
2070
2071         if ( rxh->type == RX_PACKET_TYPE_DATA )
2072         {
2073                 switch ( opcode )
2074                 {
2075                 }
2076         }
2077         else if ( rxh->type == RX_PACKET_TYPE_ABORT )
2078         {
2079                 UINTOUT(hf_afs_backup_errcode);
2080         }
2081 }
2082
2083 static void
2084 dissect_backup_request(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int opcode)
2085 {
2086         struct rx_header *rxh;
2087         unsigned char *data;
2088         int doffset, curoffset;
2089
2090         rxh = (struct rx_header *) &pd[offset];
2091         data = (char *)rxh + sizeof(struct rx_header);
2092         doffset = offset + sizeof(struct rx_header);
2093         curoffset = doffset;
2094
2095         /* skip opcode */
2096         SKIP(sizeof(guint32));
2097
2098         switch ( opcode )
2099         {
2100         }
2101 }
2102
2103 /*
2104  * Registration code for registering the protocol and fields
2105  */
2106
2107 void
2108 proto_register_afs(void)
2109 {
2110         static hf_register_info hf[] = {
2111
2112                 { &hf_afs_fs, {
2113                         "File Server", "afs.fs", FT_BOOLEAN, BASE_NONE,
2114                         0, 0, "File Server" }},
2115                 { &hf_afs_cb, {
2116                         "Callback", "afs.cb", FT_BOOLEAN, BASE_NONE,
2117                         0, 0, "Callback" }},
2118                 { &hf_afs_prot, {
2119                         "Protection", "afs.prot", FT_BOOLEAN, BASE_NONE,
2120                         0, 0, "Protection" }},
2121                 { &hf_afs_vldb, {
2122                         "VLDB", "afs.vldb", FT_BOOLEAN, BASE_NONE,
2123                         0, 0, "VLDB" }},
2124                 { &hf_afs_kauth, {
2125                         "Kauth", "afs.kauth", FT_BOOLEAN, BASE_NONE,
2126                         0, 0, "Kauth" }},
2127                 { &hf_afs_vol, {
2128                         "Volume Server", "afs.vol", FT_BOOLEAN, BASE_NONE,
2129                         0, 0, "Volume Server" }},
2130                 { &hf_afs_error, {
2131                         "Error", "afs.error", FT_BOOLEAN, BASE_NONE,
2132                         0, 0, "Error" }},
2133                 { &hf_afs_bos, {
2134                         "BOS", "afs.bos", FT_BOOLEAN, BASE_NONE,
2135                         0, 0, "BOS" }},
2136                 { &hf_afs_update, {
2137                         "Update", "afs.update", FT_BOOLEAN, BASE_NONE,
2138                         0, 0, "Update" }},
2139                 { &hf_afs_rmtsys, {
2140                         "Rmtsys", "afs.rmtsys", FT_BOOLEAN, BASE_NONE,
2141                         0, 0, "Rmtsys" }},
2142                 { &hf_afs_ubik, {
2143                         "Ubik", "afs.ubik", FT_BOOLEAN, BASE_NONE,
2144                         0, 0, "Ubik" }},
2145                 { &hf_afs_backup, {
2146                         "Backup", "afs.backup", FT_BOOLEAN, BASE_NONE,
2147                         0, 0, "Backup" }},
2148
2149                 { &hf_afs_fs_opcode, {
2150                         "Operation", "afs.fs.opcode", FT_UINT32, BASE_DEC,
2151                         VALS(fs_req), 0, "Operation" }},
2152                 { &hf_afs_cb_opcode, {
2153                         "Operation", "afs.cb.opcode", FT_UINT32, BASE_DEC,
2154                         VALS(cb_req), 0, "Operation" }},
2155                 { &hf_afs_prot_opcode, {
2156                         "Operation", "afs.prot.opcode", FT_UINT32, BASE_DEC,
2157                         VALS(prot_req), 0, "Operation" }},
2158                 { &hf_afs_vldb_opcode, {
2159                         "Operation", "afs.vldb.opcode", FT_UINT32, BASE_DEC,
2160                         VALS(vldb_req), 0, "Operation" }},
2161                 { &hf_afs_kauth_opcode, {
2162                         "Operation", "afs.kauth.opcode", FT_UINT32, BASE_DEC,
2163                         VALS(kauth_req), 0, "Operation" }},
2164                 { &hf_afs_vol_opcode, {
2165                         "Operation", "afs.vol.opcode", FT_UINT32, BASE_DEC,
2166                         VALS(vol_req), 0, "Operation" }},
2167                 { &hf_afs_bos_opcode, {
2168                         "Operation", "afs.bos.opcode", FT_UINT32, BASE_DEC,
2169                         VALS(bos_req), 0, "Operation" }},
2170                 { &hf_afs_update_opcode, {
2171                         "Operation", "afs.update.opcode", FT_UINT32, BASE_DEC,
2172                         0, 0, "Operation" }},
2173                 { &hf_afs_rmtsys_opcode, {
2174                         "Operation", "afs.rmtsys.opcode", FT_UINT32, BASE_DEC,
2175                         0, 0, "Operation" }},
2176                 { &hf_afs_error_opcode, {
2177                         "Operation", "afs.error.opcode", FT_UINT32, BASE_DEC,
2178                         0, 0, "Operation" }},
2179                 { &hf_afs_backup_opcode, {
2180                         "Operation", "afs.backup.opcode", FT_UINT32, BASE_DEC,
2181                         0, 0, "Operation" }},
2182                 { &hf_afs_ubik_opcode, {
2183                         "Operation", "afs.ubik.opcode", FT_UINT32, BASE_DEC,
2184                         VALS(ubik_req), 0, "Operation" }},
2185
2186
2187                 /* File Server Fields */
2188                 { &hf_afs_fs_fid_volume, {
2189                         "FileID (Volume)", "afs.fs.fid.volume", FT_UINT32, BASE_DEC,
2190                         0, 0, "File ID (Volume)" }},
2191                 { &hf_afs_fs_fid_vnode, {
2192                         "FileID (VNode)", "afs.fs.fid.vnode", FT_UINT32, BASE_DEC,
2193                         0, 0, "File ID (VNode)" }},
2194                 { &hf_afs_fs_fid_uniqifier, {
2195                         "FileID (Uniqifier)", "afs.fs.fid.uniq", FT_UINT32, BASE_DEC,
2196                         0, 0, "File ID (Uniqifier)" }},
2197                 { &hf_afs_fs_offset, {
2198                         "Offset", "afs.fs.offset", FT_UINT32, BASE_DEC,
2199                         0, 0, "Offset" }},
2200                 { &hf_afs_fs_length, {
2201                         "Length", "afs.fs.length", FT_UINT32, BASE_DEC,
2202                         0, 0, "Length" }},
2203                 { &hf_afs_fs_flength, {
2204                         "FLength", "afs.fs.flength", FT_UINT32, BASE_DEC,
2205                         0, 0, "FLength" }},
2206                 { &hf_afs_fs_errcode, {
2207                         "Error Code", "afs.fs.errcode", FT_UINT32, BASE_DEC,
2208                         VALS(afs_errors), 0, "Error Code" }},
2209                 { &hf_afs_fs_data, {
2210                         "Data", "afs.fs.data", FT_BYTES, BASE_HEX,
2211                         0, 0, "Data" }},
2212                 { &hf_afs_fs_oldname, {
2213                         "Old Name", "afs.fs.oldname", FT_STRING, BASE_HEX,
2214                         0, 0, "Old Name" }},
2215                 { &hf_afs_fs_newname, {
2216                         "New Name", "afs.fs.newname", FT_STRING, BASE_HEX,
2217                         0, 0, "New Name" }},
2218                 { &hf_afs_fs_name, {
2219                         "Name", "afs.fs.name", FT_STRING, BASE_HEX,
2220                         0, 0, "Name" }},
2221                 { &hf_afs_fs_symlink_name, {
2222                         "Symlink Name", "afs.fs.symlink.name", FT_STRING, BASE_HEX,
2223                         0, 0, "Symlink Name" }},
2224                 { &hf_afs_fs_symlink_content, {
2225                         "Symlink Content", "afs.fs.symlink.content", FT_STRING, BASE_HEX,
2226                         0, 0, "Symlink Content" }},
2227                 { &hf_afs_fs_volid, {
2228                         "Volume ID", "afs.fs.volid", FT_UINT32, BASE_DEC,
2229                         0, 0, "Volume ID" }},
2230                 { &hf_afs_fs_volname, {
2231                         "Volume Name", "afs.fs.volname", FT_STRING, BASE_HEX,
2232                         0, 0, "Volume Name" }},
2233                 { &hf_afs_fs_timestamp, {
2234                         "Timestamp", "afs.fs.timestamp", FT_ABSOLUTE_TIME, BASE_DEC,
2235                         0, 0, "Timestamp" }},
2236
2237                 { &hf_afs_fs_acl_count_positive, {
2238                         "ACL Count (Positive)", "afs.fs.acl.count.positive", FT_UINT32, BASE_DEC,
2239                         0, 0, "Number of Positive ACLs" }},
2240                 { &hf_afs_fs_acl_count_negative, {
2241                         "ACL Count (Negative)", "afs.fs.acl.count.negative", FT_UINT32, BASE_DEC,
2242                         0, 0, "Number of Negative ACLs" }},
2243                 { &hf_afs_fs_acl_datasize, {
2244                         "ACL Size", "afs.fs.acl.datasize", FT_UINT32, BASE_DEC,
2245                         0, 0, "ACL Data Size" }},
2246                 { &hf_afs_fs_acl_entity, {
2247                         "Entity (User/Group)", "afs.fs.acl.entity", FT_STRING, BASE_HEX,
2248                         0, 0, "ACL Entity (User/Group)" }},
2249                 { &hf_afs_fs_acl_r, {
2250                         "_R_ead", "afs.fs.acl.r", FT_UINT8, BASE_BIN,
2251                         0, PRSFS_READ, "Read" }},
2252                 { &hf_afs_fs_acl_l, {
2253                         "_L_ookup", "afs.fs.acl.l", FT_UINT8, BASE_BIN,
2254                         0, PRSFS_LOOKUP, "Lookup" }},
2255                 { &hf_afs_fs_acl_i, {
2256                         "_I_nsert", "afs.fs.acl.i", FT_UINT8, BASE_BIN,
2257                         0, PRSFS_INSERT, "Insert" }},
2258                 { &hf_afs_fs_acl_d, {
2259                         "_D_elete", "afs.fs.acl.d", FT_UINT8, BASE_BIN,
2260                         0, PRSFS_DELETE, "Delete" }},
2261                 { &hf_afs_fs_acl_w, {
2262                         "_W_rite", "afs.fs.acl.w", FT_UINT8, BASE_BIN,
2263                         0, PRSFS_WRITE, "Write" }},
2264                 { &hf_afs_fs_acl_k, {
2265                         "_L_ock", "afs.fs.acl.k", FT_UINT8, BASE_BIN,
2266                         0, PRSFS_LOCK, "Lock" }},
2267                 { &hf_afs_fs_acl_a, {
2268                         "_A_dminister", "afs.fs.acl.a", FT_UINT8, BASE_BIN,
2269                         0, PRSFS_ADMINISTER, "Administer" }},
2270
2271                 { &hf_afs_fs_callback_version, {
2272                         "Version", "afs.fs.callback.version", FT_UINT32, BASE_DEC,
2273                         0, 0, "Version" }},
2274                 { &hf_afs_fs_callback_expires, {
2275                         "Expires", "afs.fs.callback.expires", FT_ABSOLUTE_TIME, BASE_DEC,
2276                         0, 0, "Expires" }},
2277                 { &hf_afs_fs_callback_type, {
2278                         "Type", "afs.fs.callback.type", FT_UINT32, BASE_DEC,
2279                         VALS(cb_types), 0, "Type" }},
2280
2281                 /* BOS Server Fields */
2282                 { &hf_afs_bos_errcode, {
2283                         "Error Code", "afs.bos.errcode", FT_UINT32, BASE_DEC,
2284                         VALS(afs_errors), 0, "Error Code" }},
2285                 { &hf_afs_bos_type, {
2286                         "Type", "afs.bos.type", FT_STRING, BASE_HEX,
2287                         0, 0, "Type" }},
2288                 { &hf_afs_bos_content, {
2289                         "Content", "afs.bos.content", FT_STRING, BASE_HEX,
2290                         0, 0, "Content" }},
2291                 { &hf_afs_bos_instance, {
2292                         "Instance", "afs.bos.instance", FT_STRING, BASE_HEX,
2293                         0, 0, "Instance" }},
2294                 { &hf_afs_bos_status, {
2295                         "Status", "afs.bos.status", FT_INT32, BASE_DEC,
2296                         0, 0, "Status" }},
2297                 { &hf_afs_bos_num, {
2298                         "Number", "afs.bos.number", FT_UINT32, BASE_DEC,
2299                         0, 0, "Number" }},
2300                 { &hf_afs_bos_size, {
2301                         "Size", "afs.bos.size", FT_UINT32, BASE_DEC,
2302                         0, 0, "Size" }},
2303                 { &hf_afs_bos_flags, {
2304                         "Flags", "afs.bos.flags", FT_UINT32, BASE_DEC,
2305                         0, 0, "Flags" }},
2306                 { &hf_afs_bos_date, {
2307                         "Date", "afs.bos.date", FT_UINT32, BASE_DEC,
2308                         0, 0, "Date" }},
2309
2310                 /* KAUTH Server Fields */
2311                 { &hf_afs_kauth_errcode, {
2312                         "Error Code", "afs.kauth.errcode", FT_UINT32, BASE_DEC,
2313                         VALS(afs_errors), 0, "Error Code" }},
2314                 { &hf_afs_kauth_princ, {
2315                         "Principal", "afs.kauth.princ", FT_STRING, BASE_HEX,
2316                         0, 0, "Principal" }},
2317                 { &hf_afs_kauth_realm, {
2318                         "Realm", "afs.kauth.realm", FT_STRING, BASE_HEX,
2319                         0, 0, "Realm" }},
2320                 { &hf_afs_kauth_domain, {
2321                         "Domain", "afs.kauth.domain", FT_STRING, BASE_HEX,
2322                         0, 0, "Domain" }},
2323                 { &hf_afs_kauth_name, {
2324                         "Name", "afs.kauth.name", FT_STRING, BASE_HEX,
2325                         0, 0, "Name" }},
2326                 { &hf_afs_kauth_data, {
2327                         "Data", "afs.kauth.data", FT_BYTES, BASE_HEX,
2328                         0, 0, "Data" }},
2329                 { &hf_afs_kauth_kvno, {
2330                         "Key Version Number", "afs.kauth.kvno", FT_UINT32, BASE_DEC,
2331                         0, 0, "Key Version Number" }},
2332
2333                 /* VOL Server Fields */
2334                 { &hf_afs_vol_errcode, {
2335                         "Error Code", "afs.vol.errcode", FT_UINT32, BASE_DEC,
2336                         VALS(afs_errors), 0, "Error Code" }},
2337                 { &hf_afs_vol_id, {
2338                         "Volume ID", "afs.vol.id", FT_UINT32, BASE_DEC,
2339                         0, 0, "Volume ID" }},
2340                 { &hf_afs_vol_count, {
2341                         "Volume Count", "afs.vol.count", FT_UINT32, BASE_DEC,
2342                         0, 0, "Volume Count" }},
2343                 { &hf_afs_vol_name, {
2344                         "Volume Name", "afs.vol.name", FT_STRING, BASE_HEX,
2345                         0, 0, "Volume Name" }},
2346
2347                 /* VLDB Server Fields */
2348                 { &hf_afs_vldb_errcode, {
2349                         "Error Code", "afs.vldb.errcode", FT_UINT32, BASE_DEC,
2350                         VALS(afs_errors), 0, "Error Code" }},
2351                 { &hf_afs_vldb_type, {
2352                         "Volume Type", "afs.vldb.type", FT_UINT32, BASE_DEC,
2353                         VALS(volume_types), 0, "Volume Type" }},
2354                 { &hf_afs_vldb_id, {
2355                         "Volume ID", "afs.vldb.id", FT_UINT32, BASE_DEC,
2356                         0, 0, "Volume ID" }},
2357                 { &hf_afs_vldb_bump, {
2358                         "Bumped Volume ID", "afs.vldb.bump", FT_UINT32, BASE_DEC,
2359                         0, 0, "Bumped Volume ID" }},
2360                 { &hf_afs_vldb_index, {
2361                         "Volume Index", "afs.vldb.index", FT_UINT32, BASE_DEC,
2362                         0, 0, "Volume Index" }},
2363                 { &hf_afs_vldb_count, {
2364                         "Volume Count", "afs.vldb.count", FT_UINT32, BASE_DEC,
2365                         0, 0, "Volume Count" }},
2366                 { &hf_afs_vldb_numservers, {
2367                         "Number of Servers", "afs.vldb.numservers", FT_UINT32, BASE_DEC,
2368                         0, 0, "Number of Servers" }},
2369                 { &hf_afs_vldb_nextindex, {
2370                         "Next Volume Index", "afs.vldb.nextindex", FT_UINT32, BASE_DEC,
2371                         0, 0, "Next Volume Index" }},
2372                 { &hf_afs_vldb_rovol, {
2373                         "Read-Only Volume ID", "afs.vldb.rovol", FT_UINT32, BASE_DEC,
2374                         0, 0, "Read-Only Volume ID" }},
2375                 { &hf_afs_vldb_rwvol, {
2376                         "Read-Write Volume ID", "afs.vldb.rwvol", FT_UINT32, BASE_DEC,
2377                         0, 0, "Read-Only Volume ID" }},
2378                 { &hf_afs_vldb_bkvol, {
2379                         "Backup Volume ID", "afs.vldb.bkvol", FT_UINT32, BASE_DEC,
2380                         0, 0, "Read-Only Volume ID" }},
2381                 { &hf_afs_vldb_name, {
2382                         "Volume Name", "afs.vldb.name", FT_STRING, BASE_HEX,
2383                         0, 0, "Volume Name" }},
2384                 { &hf_afs_vldb_partition, {
2385                         "Partition", "afs.vldb.partition", FT_STRING, BASE_HEX,
2386                         0, 0, "Partition" }},
2387                 { &hf_afs_vldb_server, {
2388                         "Server", "afs.vldb.server", FT_IPv4, BASE_HEX,
2389                         0, 0, "Server" }},
2390                 { &hf_afs_vldb_serveruuid, {
2391                         "Server UUID", "afs.vldb.serveruuid", FT_BYTES, BASE_HEX,
2392                         0, 0, "Server UUID" }},
2393
2394                 /* BACKUP Server Fields */
2395                 { &hf_afs_backup_errcode, {
2396                         "Error Code", "afs.backup.errcode", FT_UINT32, BASE_DEC,
2397                         VALS(afs_errors), 0, "Error Code" }},
2398
2399                 /* CB Server Fields */
2400                 { &hf_afs_cb_errcode, {
2401                         "Error Code", "afs.cb.errcode", FT_UINT32, BASE_DEC,
2402                         VALS(afs_errors), 0, "Error Code" }},
2403                 { &hf_afs_cb_callback_version, {
2404                         "Version", "afs.cb.callback.version", FT_UINT32, BASE_DEC,
2405                         0, 0, "Version" }},
2406                 { &hf_afs_cb_callback_expires, {
2407                         "Expires", "afs.cb.callback.expires", FT_ABSOLUTE_TIME, BASE_DEC,
2408                         0, 0, "Expires" }},
2409                 { &hf_afs_cb_callback_type, {
2410                         "Type", "afs.cb.callback.type", FT_UINT32, BASE_DEC,
2411                         VALS(cb_types), 0, "Type" }},
2412                 { &hf_afs_cb_fid_volume, {
2413                         "FileID (Volume)", "afs.cb.fid.volume", FT_UINT32, BASE_DEC,
2414                         0, 0, "File ID (Volume)" }},
2415                 { &hf_afs_cb_fid_vnode, {
2416                         "FileID (VNode)", "afs.cb.fid.vnode", FT_UINT32, BASE_DEC,
2417                         0, 0, "File ID (VNode)" }},
2418                 { &hf_afs_cb_fid_uniqifier, {
2419                         "FileID (Uniqifier)", "afs.cb.fid.uniq", FT_UINT32, BASE_DEC,
2420                         0, 0, "File ID (Uniqifier)" }},
2421
2422                 /* PROT Server Fields */
2423                 { &hf_afs_prot_errcode, {
2424                         "Error Code", "afs.prot.errcode", FT_UINT32, BASE_DEC,
2425                         VALS(afs_errors), 0, "Error Code" }},
2426                 { &hf_afs_prot_name, {
2427                         "Name", "afs.prot.name", FT_STRING, BASE_HEX,
2428                         0, 0, "Name" }},
2429                 { &hf_afs_prot_id, {
2430                         "ID", "afs.prot.id", FT_UINT32, BASE_DEC,
2431                         0, 0, "ID" }},
2432                 { &hf_afs_prot_oldid, {
2433                         "Old ID", "afs.prot.oldid", FT_UINT32, BASE_DEC,
2434                         0, 0, "Old ID" }},
2435                 { &hf_afs_prot_newid, {
2436                         "New ID", "afs.prot.newid", FT_UINT32, BASE_DEC,
2437                         0, 0, "New ID" }},
2438                 { &hf_afs_prot_gid, {
2439                         "Group ID", "afs.prot.gid", FT_UINT32, BASE_DEC,
2440                         0, 0, "Group ID" }},
2441                 { &hf_afs_prot_uid, {
2442                         "User ID", "afs.prot.uid", FT_UINT32, BASE_DEC,
2443                         0, 0, "User ID" }},
2444                 { &hf_afs_prot_count, {
2445                         "Count", "afs.prot.count", FT_UINT32, BASE_DEC,
2446                         0, 0, "Count" }},
2447                 { &hf_afs_prot_maxgid, {
2448                         "Maximum Group ID", "afs.prot.maxgid", FT_UINT32, BASE_DEC,
2449                         0, 0, "Maximum Group ID" }},
2450                 { &hf_afs_prot_maxuid, {
2451                         "Maximum User ID", "afs.prot.maxuid", FT_UINT32, BASE_DEC,
2452                         0, 0, "Maximum User ID" }},
2453                 { &hf_afs_prot_pos, {
2454                         "Position", "afs.prot.pos", FT_UINT32, BASE_DEC,
2455                         0, 0, "Position" }},
2456                 { &hf_afs_prot_flag, {
2457                         "Flag", "afs.prot.flag", FT_UINT32, BASE_HEX,
2458                         0, 0, "Flag" }},
2459
2460                 /* UBIK Fields */
2461                 { &hf_afs_ubik_errcode, {
2462                         "Error Code", "afs.ubik.errcode", FT_UINT32, BASE_DEC,
2463                         VALS(afs_errors), 0, "Error Code" }},
2464                 { &hf_afs_ubik_version_epoch, {
2465                         "Epoch", "afs.ubik.version.epoch", FT_ABSOLUTE_TIME, BASE_DEC,
2466                         0, 0, "Epoch" }},
2467                 { &hf_afs_ubik_votestart, {
2468                         "Vote Started", "afs.ubik.votestart", FT_ABSOLUTE_TIME, BASE_DEC,
2469                         0, 0, "Vote Started" }},
2470                 { &hf_afs_ubik_voteend, {
2471                         "Vote Ends", "afs.ubik.voteend", FT_ABSOLUTE_TIME, BASE_DEC,
2472                         0, 0, "Vote Ends" }},
2473                 { &hf_afs_ubik_version_counter, {
2474                         "Counter", "afs.ubik.version.counter", FT_UINT32, BASE_DEC,
2475                         0, 0, "Counter" }},
2476                 { &hf_afs_ubik_file, {
2477                         "File", "afs.ubik.file", FT_UINT32, BASE_DEC,
2478                         0, 0, "File" }},
2479                 { &hf_afs_ubik_pos, {
2480                         "Position", "afs.ubik.position", FT_UINT32, BASE_DEC,
2481                         0, 0, "Position" }},
2482                 { &hf_afs_ubik_length, {
2483                         "Length", "afs.ubik.length", FT_UINT32, BASE_DEC,
2484                         0, 0, "Length" }},
2485                 { &hf_afs_ubik_locktype, {
2486                         "Lock Type", "afs.ubik.locktype", FT_UINT32, BASE_DEC,
2487                         VALS(ubik_lock_types), 0, "Lock Type" }},
2488                 { &hf_afs_ubik_votetype, {
2489                         "Vote Type", "afs.ubik.votetype", FT_BOOLEAN, BASE_HEX,
2490                         0, 0, "Vote Type" }},
2491                 { &hf_afs_ubik_syncsite, {
2492                         "Syncsite", "afs.ubik.syncsite", FT_BOOLEAN, BASE_HEX,
2493                         0, 0, "Syncsite" }},
2494                 { &hf_afs_ubik_site, {
2495                         "Site", "afs.ubik.site", FT_IPv4, BASE_HEX,
2496                         0, 0, "Site" }},
2497
2498         };
2499
2500         proto_afs = proto_register_protocol("Andrew File System (AFS)", "afs");
2501         proto_register_field_array(proto_afs, hf, array_length(hf));
2502 }