Give the code that computes protocol statistics a progress dialog box,
[obnox/wireshark/wip.git] / packet-afs.c
1 /* packet-afs.c
2  * Routines for AFS 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  * Portions based on information/specs retrieved from the OpenAFS sources at
9  *   www.openafs.org, Copyright IBM. 
10  *
11  * $Id: packet-afs.c,v 1.27 2001/03/23 21:42:37 nneul Exp $
12  *
13  * Ethereal - Network traffic analyzer
14  * By Gerald Combs <gerald@zing.org>
15  * Copyright 1998 Gerald Combs
16  *
17  * Copied from packet-tftp.c
18  *
19  * This program is free software; you can redistribute it and/or
20  * modify it under the terms of the GNU General Public License
21  * as published by the Free Software Foundation; either version 2
22  * of the License, or (at your option) any later version.
23  *
24  * This program is distributed in the hope that it will be useful,
25  * but WITHOUT ANY WARRANTY; without even the implied warranty of
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
27  * GNU General Public License for more details.
28  *
29  * You should have received a copy of the GNU General Public License
30  * along with this program; if not, write to the Free Software
31  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
32  */
33
34 #ifdef HAVE_CONFIG_H
35 # include "config.h"
36 #endif
37
38 #include <stdio.h>
39
40 #ifdef HAVE_SYS_TYPES_H
41 # include <sys/types.h>
42 #endif
43
44 #ifdef HAVE_NETINET_IN_H
45 # include <netinet/in.h>
46 #endif
47
48 #include <string.h>
49 #include <glib.h>
50 #include "packet.h"
51 #include "conversation.h"
52 #include "resolv.h"
53
54 #include "packet-rx.h"
55 #include "packet-afs.h"
56 #include "packet-afs-defs.h"
57 #include "packet-afs-macros.h"
58
59
60 int afs_packet_init_count = 100;
61
62 struct afs_request_key {
63   guint32 conversation, callnumber;
64   guint16 service;
65 };
66
67 struct afs_request_val {
68   guint32 opcode;
69 };
70
71 GHashTable *afs_request_hash = NULL;
72 GMemChunk *afs_request_keys = NULL;
73 GMemChunk *afs_request_vals = NULL;
74
75
76
77 /*
78  * Dissector prototypes
79  */
80 static void dissect_fs_request(const u_char *pd,
81         int offset, frame_data *fd, proto_tree *tree, int opcode);
82 static void dissect_fs_reply(const u_char *pd,
83         int offset, frame_data *fd, proto_tree *tree, int opcode);
84 static void dissect_cb_request(const u_char *pd,
85         int offset, frame_data *fd, proto_tree *tree, int opcode);
86 static void dissect_cb_reply(const u_char *pd,
87         int offset, frame_data *fd, proto_tree *tree, int opcode);
88 static void dissect_bos_request(const u_char *pd,
89         int offset, frame_data *fd, proto_tree *tree, int opcode);
90 static void dissect_bos_reply(const u_char *pd,
91         int offset, frame_data *fd, proto_tree *tree, int opcode);
92 static void dissect_vol_request(const u_char *pd,
93         int offset, frame_data *fd, proto_tree *tree, int opcode);
94 static void dissect_vol_reply(const u_char *pd,
95         int offset, frame_data *fd, proto_tree *tree, int opcode);
96 static void dissect_ubik_request(const u_char *pd,
97         int offset, frame_data *fd, proto_tree *tree, int opcode);
98 static void dissect_ubik_reply(const u_char *pd,
99         int offset, frame_data *fd, proto_tree *tree, int opcode);
100 static void dissect_kauth_request(const u_char *pd,
101         int offset, frame_data *fd, proto_tree *tree, int opcode);
102 static void dissect_kauth_reply(const u_char *pd,
103         int offset, frame_data *fd, proto_tree *tree, int opcode);
104 static void dissect_prot_request(const u_char *pd,
105         int offset, frame_data *fd, proto_tree *tree, int opcode);
106 static void dissect_prot_reply(const u_char *pd,
107         int offset, frame_data *fd, proto_tree *tree, int opcode);
108 static void dissect_vldb_request(const u_char *pd,
109         int offset, frame_data *fd, proto_tree *tree, int opcode);
110 static void dissect_vldb_reply(const u_char *pd,
111         int offset, frame_data *fd, proto_tree *tree, int opcode);
112 static void dissect_backup_request(const u_char *pd,
113         int offset, frame_data *fd, proto_tree *tree, int opcode);
114 static void dissect_backup_reply(const u_char *pd,
115         int offset, frame_data *fd, proto_tree *tree, int opcode);
116
117
118 /*
119  * Hash Functions
120  */
121 static gint
122 afs_equal(gconstpointer v, gconstpointer w)
123 {
124   struct afs_request_key *v1 = (struct afs_request_key *)v;
125   struct afs_request_key *v2 = (struct afs_request_key *)w;
126
127   if (v1 -> conversation == v2 -> conversation &&
128       v1 -> service == v2 -> service &&
129       v1 -> callnumber == v2 -> callnumber ) {
130
131     return 1;
132   }
133
134   return 0;
135 }
136
137 static guint
138 afs_hash (gconstpointer v)
139 {
140         struct afs_request_key *key = (struct afs_request_key *)v;
141         guint val;
142
143         val = key -> conversation + key -> service + key -> callnumber;
144
145         return val;
146 }
147
148 /*
149  * Protocol initialization
150  */
151 static void
152 afs_init_protocol(void)
153 {
154         if (afs_request_hash)
155                 g_hash_table_destroy(afs_request_hash);
156         if (afs_request_keys)
157                 g_mem_chunk_destroy(afs_request_keys);
158         if (afs_request_vals)
159                 g_mem_chunk_destroy(afs_request_vals);
160
161         afs_request_hash = g_hash_table_new(afs_hash, afs_equal);
162         afs_request_keys = g_mem_chunk_new("afs_request_keys",
163                 sizeof(struct afs_request_key),
164                 afs_packet_init_count * sizeof(struct afs_request_key),
165                 G_ALLOC_AND_FREE);
166         afs_request_vals = g_mem_chunk_new("afs_request_vals",
167                 sizeof(struct afs_request_val),
168                 afs_packet_init_count * sizeof(struct afs_request_val),
169                 G_ALLOC_AND_FREE);
170 }
171
172
173
174 /*
175  * Dissection routines
176  */
177
178 void
179 dissect_afs(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
180 {
181         proto_tree      *afs_tree, *afs_op_tree, *ti;
182         struct rx_header *rxh;
183         struct afs_header *afsh;
184         int port, node, typenode, opcode;
185         value_string const *vals;
186         int reply = 0;
187         int doffset = 0;
188         conversation_t *conversation;
189         struct afs_request_key request_key, *new_request_key;
190         struct afs_request_val *request_val;
191         void (*dissector)(const u_char *pd, int offset,
192                 frame_data *fd, proto_tree *tree, int opcode);
193
194         OLD_CHECK_DISPLAY_AS_DATA(proto_afs, pd, offset, fd, tree);
195
196         /* get at least a full packet structure */
197         if ( !BYTES_ARE_IN_FRAME(offset, sizeof(struct rx_header)) )
198                 return;
199
200         if (check_col(fd, COL_PROTOCOL))
201                 col_set_str(fd, COL_PROTOCOL, "AFS (RX)");
202
203         rxh = (struct rx_header *) &pd[offset];
204         doffset = offset + sizeof(struct rx_header);
205         afsh = (struct afs_header *) &pd[doffset];
206
207         reply = (rxh->flags & RX_CLIENT_INITIATED) == 0;
208         port = ((reply == 0) ? pi.destport : pi.srcport );
209
210         /*
211          * Find out what conversation this packet is part of.
212          * XXX - this should really be done by the transport-layer protocol,
213          * although for connectionless transports, we may not want to do that
214          * unless we know some higher-level protocol will want it - or we
215          * may want to do it, so you can say e.g. "show only the packets in
216          * this UDP 'connection'".
217          *
218          * Note that we don't have to worry about the direction this packet
219          * was going - the conversation code handles that for us, treating
220          * packets from A:X to B:Y as being part of the same conversation as
221          * packets from B:Y to A:X.
222          */
223         conversation = find_conversation(&pi.src, &pi.dst, pi.ptype,
224             pi.srcport, pi.destport, 0);
225         if (conversation == NULL) {
226                 /* It's not part of any conversation - create a new one. */
227                 conversation = conversation_new(&pi.src, &pi.dst, pi.ptype,
228                     pi.srcport, pi.destport, NULL, 0);
229         }
230
231         request_key.conversation = conversation->index; 
232         request_key.service = pntohs(&rxh->serviceId);
233         request_key.callnumber = pntohl(&rxh->callNumber);
234
235         request_val = (struct afs_request_val *) g_hash_table_lookup(
236                 afs_request_hash, &request_key);
237
238         /* only allocate a new hash element when it's a request */
239         opcode = 0;
240         if ( !request_val && !reply)
241         {
242                 new_request_key = g_mem_chunk_alloc(afs_request_keys);
243                 *new_request_key = request_key;
244
245                 request_val = g_mem_chunk_alloc(afs_request_vals);
246                 request_val -> opcode = pntohl(&afsh->opcode);
247
248                 g_hash_table_insert(afs_request_hash, new_request_key,
249                         request_val);
250         }
251
252         if ( request_val )
253         {
254                 opcode = request_val->opcode;
255         }
256
257         node = 0;
258         typenode = 0;
259         vals = NULL;
260         dissector = NULL;
261         switch (port)
262         {
263                 case AFS_PORT_FS:
264                         typenode = hf_afs_fs;
265                         node = hf_afs_fs_opcode;
266                         vals = fs_req;
267                         dissector = reply ? dissect_fs_reply : dissect_fs_request;
268                         break;
269                 case AFS_PORT_CB:
270                         typenode = hf_afs_cb;
271                         node = hf_afs_cb_opcode;
272                         vals = cb_req;
273                         dissector = reply ? dissect_cb_reply : dissect_cb_request;
274                         break;
275                 case AFS_PORT_PROT:
276                         typenode = hf_afs_prot;
277                         node = hf_afs_prot_opcode;
278                         vals = prot_req;
279                         dissector = reply ? dissect_prot_reply : dissect_prot_request;
280                         break;
281                 case AFS_PORT_VLDB:
282                         typenode = hf_afs_vldb;
283                         node = hf_afs_vldb_opcode;
284                         vals = vldb_req;
285                         dissector = reply ? dissect_vldb_reply : dissect_vldb_request;
286                         break;
287                 case AFS_PORT_KAUTH:
288                         typenode = hf_afs_kauth;
289                         node = hf_afs_kauth_opcode;
290                         vals = kauth_req;
291                         dissector = reply ? dissect_kauth_reply : dissect_kauth_request;
292                         break;
293                 case AFS_PORT_VOL:
294                         typenode = hf_afs_vol;
295                         node = hf_afs_vol_opcode;
296                         vals = vol_req;
297                         dissector = reply ? dissect_vol_reply : dissect_vol_request;
298                         break;
299                 case AFS_PORT_ERROR:
300                         typenode = hf_afs_error;
301                         node = hf_afs_error_opcode;
302                         /* dissector = reply ? dissect_error_reply : dissect_error_request; */
303                         break;
304                 case AFS_PORT_BOS:
305                         typenode = hf_afs_bos;
306                         node = hf_afs_bos_opcode;
307                         vals = bos_req;
308                         dissector = reply ? dissect_bos_reply : dissect_bos_request;
309                         break;
310                 case AFS_PORT_UPDATE:
311                         typenode = hf_afs_update;
312                         node = hf_afs_update_opcode;
313                         vals = update_req;
314                         /* dissector = reply ? dissect_update_reply : dissect_update_request; */
315                         break;
316                 case AFS_PORT_RMTSYS:
317                         typenode = hf_afs_rmtsys;
318                         node = hf_afs_rmtsys_opcode;
319                         vals = rmtsys_req;
320                         /* dissector = reply ? dissect_rmtsys_reply : dissect_rmtsys_request; */
321                         break;
322                 case AFS_PORT_BACKUP:
323                         typenode = hf_afs_backup;
324                         node = hf_afs_backup_opcode;
325                         vals = backup_req;
326                         dissector = reply ? dissect_backup_reply : dissect_backup_request;
327                         break;
328         }
329         if ( (opcode >= VOTE_LOW && opcode <= VOTE_HIGH) ||
330                 (opcode >= DISK_LOW && opcode <= DISK_HIGH) )
331         {
332                 typenode = hf_afs_ubik;
333                 node = hf_afs_ubik_opcode;
334                 vals = ubik_req;
335                 dissector = reply ? dissect_ubik_reply : dissect_ubik_request;
336         }
337
338         if ( vals )
339         {
340                 if (check_col(fd, COL_INFO))
341                         col_add_fstr(fd, COL_INFO, "%s %s: %s (%d)",
342                         val_to_str(port, port_types_short, "Unknown(%d)"),
343                         reply ? "Reply" : "Request",
344                         val_to_str(opcode, vals, "Unknown(%d)"), opcode);
345         }
346         else
347         {
348                 if (check_col(fd, COL_INFO))
349                         col_add_fstr(fd, COL_INFO, "%s %s: Unknown(%d)",
350                         val_to_str(port, port_types_short, "Unknown(%d)"),
351                         reply ? "Reply" : "Request",
352                         opcode);
353         }
354
355         if (tree) {
356                 ti = proto_tree_add_item(tree, proto_afs, NullTVB, doffset, END_OF_FRAME, FALSE);
357                 afs_tree = proto_item_add_subtree(ti, ett_afs);
358
359                 if ( !BYTES_ARE_IN_FRAME(offset, sizeof(struct rx_header) +
360                         sizeof(struct afs_header)) &&
361                         typenode != hf_afs_ubik )
362                 {
363                         proto_tree_add_text(afs_tree, NullTVB, doffset, END_OF_FRAME,
364                                 "Service: %s %s (Truncated)",
365                                 val_to_str(port, port_types, "Unknown(%d)"),
366                                 reply ? "Reply" : "Request");
367                                 return;
368                 }
369                 else
370                 {
371                         proto_tree_add_text(afs_tree, NullTVB, doffset, END_OF_FRAME,
372                                 "Service: %s %s",
373                                 val_to_str(port, port_types, "Unknown(%d)"),
374                                 reply ? "Reply" : "Request");
375                 }
376
377                 /* until we do cache, can't handle replies */
378                 ti = NULL;
379                 if ( !reply && node != 0 )
380                 {
381                         ti = proto_tree_add_uint(afs_tree,
382                                 node, NullTVB, doffset, 4, opcode);
383                 }
384                 else if ( reply && node != 0 )
385                 {
386                         /* the opcode isn't in this packet */
387                         ti = proto_tree_add_uint(afs_tree,
388                                 node, NullTVB, doffset, 0, opcode);
389                 }
390                 else
391                 {
392                         ti = proto_tree_add_text(afs_tree, NullTVB,
393                                 doffset, 0, "Operation: Unknown");
394                 }
395
396                 /* Add the subtree for this particular service */
397                 afs_op_tree = proto_item_add_subtree(ti, ett_afs_op);
398
399                 if ( typenode != 0 )
400                 {
401                         /* indicate the type of request */
402                         proto_tree_add_boolean_hidden(afs_tree, typenode, NullTVB, doffset, 0, 1);
403                 }
404
405                 /* Process the packet according to what service it is */
406                 if ( dissector )
407                 {
408                         (*dissector)(pd,offset,fd,afs_op_tree,opcode);
409                 }
410         }
411
412         /* if it's the last packet, and it's a reply, remove opcode
413                 from hash */
414         /* ignoring for now, I'm not sure how the chunk deallocation works */
415         if ( rxh->flags & RX_LAST_PACKET && reply )
416         {
417
418         }
419 }
420
421
422 /*
423  * Here is a helper routine for adding an AFS acl to the proto tree
424  * This is to be used with FS packets only
425  *
426  * An AFS ACL is a string that has the following format:
427  *
428  * <positive> <negative>
429  * <uid1> <aclbits1>
430  * ....
431  *
432  * "positive" and "negative" are integers which contain the number of
433  * positive and negative ACL's in the string.  The uid/aclbits pair are
434  * ASCII strings containing the UID/PTS record and and a ascii number
435  * representing a logical OR of all the ACL permission bits
436  */
437
438 static void dissect_acl(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
439 {
440         int pos, neg, acl;
441         int n, i, bytes;
442         u_char const *s;
443         u_char const *end;
444         char user[128]; /* Be sure to adjust sscanf()s below if length is changed... */
445         int curoffset;
446         int soff,eoff;
447
448         curoffset = offset;
449
450         TRUNC(sizeof(guint32));
451         bytes = pntohl(&pd[curoffset]);
452         OUT_UINT(hf_afs_fs_acl_datasize);
453
454         TRUNC(bytes);
455
456         soff = curoffset;
457         eoff = curoffset+bytes;
458
459         s = &pd[soff];
460         end = &pd[eoff];
461
462         if (sscanf((char *) s, "%d %n", &pos, &n) != 1)
463                 return;
464         s += n;
465         TRUNC(1);
466         proto_tree_add_uint(tree, hf_afs_fs_acl_count_positive, NullTVB, curoffset, n, pos);
467         curoffset += n;
468
469         if (sscanf((char *) s, "%d %n", &neg, &n) != 1)
470                 return;
471         s += n;
472         TRUNC(1);
473         proto_tree_add_uint(tree, hf_afs_fs_acl_count_negative, NullTVB, curoffset, n, neg);
474         curoffset += n;
475
476
477         /*
478          * This wacky order preserves the order used by the "fs" command
479          */
480
481         for (i = 0; i < pos; i++) {
482                 if (sscanf((char *) s, "%127s %d %n", user, &acl, &n) != 2)
483                         return;
484                 s += n;
485                 ACLOUT(user,1,acl,n);
486                 curoffset += n;
487                 TRUNC(1);
488         }
489
490         for (i = 0; i < neg; i++) {
491                 if (sscanf((char *) s, "%127s %d %n", user, &acl, &n) != 2)
492                         return;
493                 s += n;
494                 ACLOUT(user,0,acl,n);
495                 curoffset += n;
496                 if (s > end)
497                         return;
498         }
499 }
500
501 /*
502  * Here are the helper dissection routines
503  */
504
505 static void
506 dissect_fs_reply(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int opcode)
507 {
508         struct rx_header *rxh;
509         unsigned char *data;
510         int doffset, curoffset;
511         int seq;
512
513         rxh = (struct rx_header *) &pd[offset];
514         data = (char *)rxh + sizeof(struct rx_header);
515         doffset = offset + sizeof(struct rx_header);
516         curoffset = doffset;
517
518         seq = pntohl(&rxh->seq);
519
520         if ( rxh->type == RX_PACKET_TYPE_DATA )
521         {
522                 switch ( opcode )
523                 {
524                         case 130: /* fetch data */
525                                 if ( seq == 1 ) /* only on first packet */
526                                 {
527                                         OUT_FS_AFSFetchStatus("Status");
528                                         OUT_FS_AFSCallBack();
529                                         OUT_FS_AFSVolSync();
530                                 }
531                                 OUT_BYTES_ALL(hf_afs_fs_data);
532                                 break;
533                         case 131: /* fetch acl */
534                                 dissect_acl(pd,curoffset,fd,tree);
535                                 OUT_FS_AFSFetchStatus("Status");
536                                 OUT_FS_AFSVolSync();
537                                 break;
538                         case 132: /* Fetch status */
539                                 OUT_FS_AFSFetchStatus("Status");
540                                 OUT_FS_AFSCallBack();
541                                 OUT_FS_AFSVolSync();
542                                 break;  
543                         case 133: /* Store data */
544                         case 134: /* Store ACL */
545                         case 135: /* Store status */
546                         case 136: /* Remove file */
547                                 OUT_FS_AFSFetchStatus("Status");
548                                 OUT_FS_AFSVolSync();
549                                 break;
550                         case 137: /* create file */
551                         case 141: /* make dir */
552                         case 161: /* lookup */
553                         case 163: /* dfs symlink */
554                                 OUT_FS_AFSFid((opcode == 137)? "New File" : ((opcode == 141)? "New Directory" : "File"));
555                                 OUT_FS_AFSFetchStatus("File Status");
556                                 OUT_FS_AFSFetchStatus("Directory Status");
557                                 OUT_FS_AFSCallBack();
558                                 OUT_FS_AFSVolSync();
559                                 break;
560                         case 138: /* rename */
561                                 OUT_FS_AFSFetchStatus("Old Directory Status");
562                                 OUT_FS_AFSFetchStatus("New Directory Status");
563                                 OUT_FS_AFSVolSync();
564                                 break;
565                         case 139: /* symlink */
566                                 OUT_FS_AFSFid("Symlink");
567                         case 140: /* link */
568                                 OUT_FS_AFSFetchStatus("Symlink Status");
569                         case 142: /* rmdir */
570                                 OUT_FS_AFSFetchStatus("Directory Status");
571                                 OUT_FS_AFSVolSync();
572                                 break;
573                         case 143: /* old set lock */
574                         case 144: /* old extend lock */
575                         case 145: /* old release lock */
576                         case 147: /* give up callbacks */
577                         case 150: /* set volume status */
578                         case 152: /* check token */ 
579                                 /* nothing returned */
580                                 break;
581                         case 146: /* get statistics */
582                                 OUT_FS_ViceStatistics();
583                                 break;
584                         case 148: /* get volume info */
585                         case 154: /* n-get-volume-info */
586                                 OUT_FS_VolumeInfo();
587                                 break;
588                         case 149: /* get volume status */
589                                 OUT_FS_AFSFetchVolumeStatus();
590                                 OUT_STRING(hf_afs_fs_volname);
591                                 OUT_STRING(hf_afs_fs_offlinemsg);
592                                 OUT_STRING(hf_afs_fs_motd);
593                                 break;
594                         case 151: /* root volume */
595                                 OUT_STRING(hf_afs_fs_volname);
596                                 break;
597                         case 153: /* get time */
598                                 OUT_TIMESTAMP(hf_afs_fs_timestamp);
599                                 break;
600                         case 155: /* bulk status */
601                                 OUT_FS_AFSBulkStats();
602                                 OUT_FS_AFSCBs();
603                                 OUT_FS_AFSVolSync();
604                                 break;
605                         case 156: /* set lock */
606                         case 157: /* extend lock */
607                         case 158: /* release lock */
608                                 OUT_FS_AFSVolSync();
609                                 break;
610                         case 159: /* x-stats-version */
611                                 OUT_UINT(hf_afs_fs_xstats_version);
612                                 break;
613                         case 160: /* get xstats */
614                                 OUT_UINT(hf_afs_fs_xstats_version);
615                                 OUT_DATE(hf_afs_fs_xstats_timestamp);
616                                 OUT_FS_AFS_CollData();
617                                 break;
618                         case 162: /* flush cps */
619                                 OUT_UINT(hf_afs_fs_cps_spare2);
620                                 OUT_UINT(hf_afs_fs_cps_spare3);
621                                 break;
622                 }
623         }
624         else if ( rxh->type == RX_PACKET_TYPE_ABORT )
625         {
626                 OUT_UINT(hf_afs_fs_errcode);
627         }
628 }
629
630 static void
631 dissect_fs_request(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int opcode)
632 {
633         struct rx_header *rxh;
634         unsigned char *data;
635         int doffset, curoffset;
636
637         rxh = (struct rx_header *) &pd[offset];
638         data = (char *)rxh + sizeof(struct rx_header);
639         doffset = offset + sizeof(struct rx_header);
640         curoffset = doffset;
641
642         SKIP_OPCODE();
643
644         switch ( opcode )
645         {
646                 case 130: /* Fetch data */
647                         OUT_FS_AFSFid("Source");
648                         OUT_UINT(hf_afs_fs_offset);
649                         OUT_UINT(hf_afs_fs_length);
650                         break;
651                 case 131: /* Fetch ACL */
652                         OUT_FS_AFSFid("Target");
653                         break;          
654                 case 132: /* Fetch Status */
655                         OUT_FS_AFSFid("Target");
656                         break;
657                 case 133: /* Store Data */
658                         OUT_FS_AFSFid("Destination");
659                         OUT_FS_AFSStoreStatus("Status");
660                         OUT_UINT(hf_afs_fs_offset);
661                         OUT_UINT(hf_afs_fs_length);
662                         OUT_UINT(hf_afs_fs_flength);
663                         break;
664                 case 134: /* Store ACL */
665                         OUT_FS_AFSFid("Target");
666                         dissect_acl(pd,curoffset,fd,tree);
667                         break;
668                 case 135: /* Store Status */
669                         OUT_FS_AFSFid("Target");
670                         OUT_FS_AFSStoreStatus("Status");
671                         break;
672                 case 136: /* Remove File */
673                         OUT_FS_AFSFid("Remove File");
674                         OUT_STRING(hf_afs_fs_name);
675                         break;
676                 case 137: /* Create File */
677                         OUT_FS_AFSFid("Target");
678                         OUT_STRING(hf_afs_fs_name);
679                         OUT_FS_AFSStoreStatus("Status");
680                         break;
681                 case 138: /* Rename file */
682                         OUT_FS_AFSFid("Old");
683                         OUT_STRING(hf_afs_fs_oldname);
684                         OUT_FS_AFSFid("New");
685                         OUT_STRING(hf_afs_fs_newname);
686                         break;
687                 case 139: /* Symlink */
688                         OUT_FS_AFSFid("File");
689                         OUT_STRING(hf_afs_fs_symlink_name);
690                         OUT_STRING(hf_afs_fs_symlink_content);
691                         OUT_FS_AFSStoreStatus("Status");
692                         break;
693                 case 140: /* Link */
694                         OUT_FS_AFSFid("Link To (New File)");
695                         OUT_STRING(hf_afs_fs_name);
696                         OUT_FS_AFSFid("Link From (Old File)");
697                         break;
698                 case 141: /* Make dir */
699                         OUT_FS_AFSFid("Target");
700                         OUT_STRING(hf_afs_fs_name);
701                         OUT_FS_AFSStoreStatus("Status");
702                         break;
703                 case 142: /* Remove dir */
704                         OUT_FS_AFSFid("Target");
705                         OUT_STRING(hf_afs_fs_name);
706                         break;
707                 case 143: /* Old Set Lock */
708                         OUT_FS_AFSFid("Target");
709                         OUT_UINT(hf_afs_fs_vicelocktype);
710                         OUT_FS_AFSVolSync();
711                         break;
712                 case 144: /* Old Extend Lock */
713                         OUT_FS_AFSFid("Target");
714                         OUT_FS_AFSVolSync();
715                         break;
716                 case 145: /* Old Release Lock */
717                         OUT_FS_AFSFid("Target");
718                         OUT_FS_AFSVolSync();
719                         break;
720                 case 146: /* Get statistics */
721                         /* no params */
722                         break;
723                 case 147: /* Give up callbacks */
724                         OUT_FS_AFSCBFids();
725                         OUT_FS_AFSCBs();
726                         break;
727                 case 148: /* Get vol info */
728                         OUT_STRING(hf_afs_fs_volname);
729                         break;
730                 case 149: /* Get vol stats */
731                         OUT_UINT(hf_afs_fs_volid);
732                         break;
733                 case 150: /* Set vol stats */
734                         OUT_UINT(hf_afs_fs_volid);
735                         OUT_FS_AFSStoreVolumeStatus();
736                         OUT_STRING(hf_afs_fs_volname);
737                         OUT_STRING(hf_afs_fs_offlinemsg);
738                         OUT_STRING(hf_afs_fs_motd);
739                         break;
740                 case 151: /* get root volume */
741                         /* no params */
742                         break;
743                 case 152: /* check token */
744                         OUT_UINT(hf_afs_fs_viceid);
745                         OUT_FS_AFSTOKEN();
746                         break;
747                 case 153: /* get time */
748                         /* no params */
749                         break;
750                 case 154: /* new get vol info */
751                         OUT_STRING(hf_afs_fs_volname);
752                         break;
753                 case 155: /* bulk stat */
754                         OUT_FS_AFSCBFids();
755                         break;
756                 case 156: /* Set Lock */
757                         OUT_FS_AFSFid("Target");
758                         OUT_UINT(hf_afs_fs_vicelocktype);
759                         break;
760                 case 157: /* Extend Lock */
761                         OUT_FS_AFSFid("Target");
762                         break;
763                 case 158: /* Release Lock */
764                         OUT_FS_AFSFid("Target");
765                         break;
766                 case 159: /* xstats version */
767                         /* no params */
768                         break;
769                 case 160: /* get xstats */
770                         OUT_UINT(hf_afs_fs_xstats_clientversion);
771                         OUT_UINT(hf_afs_fs_xstats_collnumber);
772                         break;
773                 case 161: /* lookup */
774                         OUT_FS_AFSFid("Target");
775                         OUT_STRING(hf_afs_fs_name);
776                         break;
777                 case 162: /* flush cps */
778                         OUT_FS_ViceIds();
779                         OUT_FS_IPAddrs();
780                         OUT_UINT(hf_afs_fs_cps_spare1);
781                         break;
782                 case 163: /* dfs symlink */
783                         OUT_FS_AFSFid("Target");
784                         OUT_STRING(hf_afs_fs_symlink_name);
785                         OUT_STRING(hf_afs_fs_symlink_content);
786                         OUT_FS_AFSStoreStatus("Symlink Status");
787                         break;
788         }
789 }
790
791 /*
792  * BOS Helpers
793  */
794 static void
795 dissect_bos_reply(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int opcode)
796 {
797         struct rx_header *rxh;
798         unsigned char *data;
799         int doffset, curoffset;
800
801         rxh = (struct rx_header *) &pd[offset];
802         data = (char *)rxh + sizeof(struct rx_header);
803         doffset = offset + sizeof(struct rx_header);
804         curoffset = doffset;
805
806         if ( rxh->type == RX_PACKET_TYPE_DATA )
807         {
808                 switch ( opcode )
809                 {
810                         case 80: /* create bnode */
811                                 /* no output */
812                                 break;
813                         case 81: /* delete bnode */
814                                 /* no output */
815                                 break;
816                         case 82: /* set status */
817                                 /* no output */
818                                 break;
819                         case 83: /* get status */
820                                 OUT_INT(hf_afs_bos_status);
821                                 OUT_STRING(hf_afs_bos_statusdesc);
822                                 break;
823                         case 84: /* enumerate instance */
824                                 OUT_STRING(hf_afs_bos_instance);
825                                 break;
826                         case 85: /* get instance info */
827                                 OUT_STRING(hf_afs_bos_type);
828                                 OUT_BOS_STATUS();
829                                 break;
830                         case 86: /* get instance parm */
831                                 OUT_STRING(hf_afs_bos_parm);
832                                 break;
833                         case 87: /* add siperuser */
834                                 /* no output */
835                                 break;
836                         case 88: /* delete superuser */
837                                 /* no output */
838                                 break;
839                         case 89: /* list superusers */
840                                 OUT_STRING(hf_afs_bos_user);
841                                 break;
842                         case 90: /* list keys */
843                                 OUT_UINT(hf_afs_bos_kvno);
844                                 OUT_BOS_KEY();
845                                 OUT_BOS_KEYINFO();
846                                 break;
847                         case 91: /* add key */
848                                 /* no output */
849                                 break;
850                         case 92: /* delete key */
851                                 /* no output */
852                                 break;
853                         case 93: /* set cell name */
854                                 /* no output */
855                                 break;
856                         case 94: /* get cell name */
857                                 OUT_STRING(hf_afs_bos_cell);
858                                 break;
859                         case 95: /* get cell host */
860                                 OUT_STRING(hf_afs_bos_host);
861                                 break;
862                         case 96: /* add cell host */
863                                 /* no output */
864                                 break;
865                         case 97: /* delete cell host */
866                                 /* no output */
867                                 break;
868                         case 98: /* set tstatus */
869                                 /* no output */
870                                 break;
871                         case 99: /* shutdown all */
872                                 /* no output */
873                                 break;
874                         case 100: /* restart all */
875                                 /* no output */
876                                 break;
877                         case 101: /* startup all */
878                                 /* no output */
879                                 break;
880                         case 102: /* set noauth flag */
881                                 /* no output */
882                                 break;
883                         case 103: /* rebozo */
884                                 /* no output */
885                                 break;
886                         case 104: /* restart */
887                                 /* no output */
888                                 break;
889                         case 105: /* install */
890                                 /* no output */
891                                 break;
892                         case 106: /* uninstall */
893                                 /* no output */
894                                 break;
895                         case 107: /* get dates */
896                                 OUT_DATE(hf_afs_bos_newtime);
897                                 OUT_DATE(hf_afs_bos_baktime);
898                                 OUT_DATE(hf_afs_bos_oldtime);
899                                 break;
900                         case 108: /* exec */
901                                 /* no output */
902                                 break;
903                         case 109: /* prune */
904                                 /* no output */
905                                 break;
906                         case 110: /* set restart time */
907                                 /* no output */
908                                 break;
909                         case 111: /* get restart time */
910                                 OUT_BOS_TIME();
911                                 break;
912                         case 112: /* get log */
913                                 /* need to make this dump a big string somehow */
914                                 OUT_BYTES_ALL(hf_afs_bos_data);
915                                 break;
916                         case 113: /* wait all */
917                                 /* no output */
918                                 break;
919                         case 114: /* get instance strings */
920                                 OUT_STRING(hf_afs_bos_error);
921                                 OUT_STRING(hf_afs_bos_spare1);
922                                 OUT_STRING(hf_afs_bos_spare2);
923                                 OUT_STRING(hf_afs_bos_spare3);
924                                 break;
925                 }
926         }
927         else if ( rxh->type == RX_PACKET_TYPE_ABORT )
928         {
929                 OUT_UINT(hf_afs_bos_errcode);
930         }
931 }
932
933 static void
934 dissect_bos_request(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int opcode)
935 {
936         struct rx_header *rxh;
937         unsigned char *data;
938         int doffset, curoffset;
939
940         rxh = (struct rx_header *) &pd[offset];
941         data = (char *)rxh + sizeof(struct rx_header);
942         doffset = offset + sizeof(struct rx_header);
943         curoffset = doffset;
944
945         SKIP_OPCODE();
946         
947         switch ( opcode )
948         {
949                 case 80: /* create b node */
950                         OUT_STRING(hf_afs_bos_type);
951                         OUT_STRING(hf_afs_bos_instance);
952                         OUT_STRING(hf_afs_bos_parm);
953                         OUT_STRING(hf_afs_bos_parm);
954                         OUT_STRING(hf_afs_bos_parm);
955                         OUT_STRING(hf_afs_bos_parm);
956                         OUT_STRING(hf_afs_bos_parm);
957                         OUT_STRING(hf_afs_bos_parm);
958                         break;
959                 case 81: /* delete b node */
960                         OUT_STRING(hf_afs_bos_instance);
961                         break;
962                 case 82: /* set status */
963                         OUT_STRING(hf_afs_bos_instance);
964                         OUT_UINT(hf_afs_bos_status);
965                         break;
966                 case 83: /* get status */
967                         OUT_STRING(hf_afs_bos_instance);
968                         break;
969                 case 84: /* enumerate instance */
970                         OUT_UINT(hf_afs_bos_num);
971                         break;
972                 case 85: /* get instance info */
973                         OUT_STRING(hf_afs_bos_instance);
974                         break;
975                 case 86: /* get instance parm */
976                         OUT_STRING(hf_afs_bos_instance);
977                         OUT_UINT(hf_afs_bos_num);
978                         break;
979                 case 87: /* add super user */
980                         OUT_STRING(hf_afs_bos_user);
981                         break;
982                 case 88: /* delete super user */
983                         OUT_STRING(hf_afs_bos_user);
984                         break;
985                 case 89: /* list super users */
986                         OUT_UINT(hf_afs_bos_num);
987                         break;
988                 case 90: /* list keys */
989                         OUT_UINT(hf_afs_bos_num);
990                         break;
991                 case 91: /* add key */
992                         OUT_UINT(hf_afs_bos_num);
993                         OUT_BOS_KEY();
994                         break;
995                 case 92: /* delete key */
996                         OUT_UINT(hf_afs_bos_num);
997                         break;
998                 case 93: /* set cell name */
999                         OUT_STRING(hf_afs_bos_content);
1000                         break;
1001                 case 95: /* set cell host */
1002                         OUT_UINT(hf_afs_bos_num);
1003                         break;
1004                 case 96: /* add cell host */
1005                         OUT_STRING(hf_afs_bos_content);
1006                         break;
1007                 case 97: /* delete cell host */
1008                         OUT_STRING(hf_afs_bos_content);
1009                         break;
1010                 case 98: /* set t status */
1011                         OUT_STRING(hf_afs_bos_content);
1012                         OUT_UINT(hf_afs_bos_status);
1013                         break;
1014                 case 99: /* shutdown all */
1015                         /* no params */
1016                         break;
1017                 case 100: /* restart all */
1018                         /* no params */
1019                         break;
1020                 case 101: /* startup all */
1021                         /* no params */
1022                         break;
1023                 case 102: /* set no-auth flag */
1024                         OUT_UINT(hf_afs_bos_flags);
1025                         break;
1026                 case 103: /* re-bozo? */
1027                         /* no params */
1028                         break;
1029                 case 104: /* restart */
1030                         OUT_STRING(hf_afs_bos_instance);
1031                         break;
1032                 case 105: /* install */
1033                         OUT_STRING(hf_afs_bos_path);
1034                         OUT_UINT(hf_afs_bos_size);
1035                         OUT_UINT(hf_afs_bos_flags);
1036                         OUT_UINT(hf_afs_bos_date);
1037                         break;
1038                 case 106: /* uninstall */
1039                         OUT_STRING(hf_afs_bos_path);
1040                         break;
1041                 case 107: /* get dates */
1042                         OUT_STRING(hf_afs_bos_path);
1043                         break;
1044                 case 108: /* exec */
1045                         OUT_STRING(hf_afs_bos_cmd);
1046                         break;
1047                 case 109: /* prune */
1048                         OUT_UINT(hf_afs_bos_flags);
1049                         break;
1050                 case 110: /* set restart time */
1051                         OUT_UINT(hf_afs_bos_num);
1052                         OUT_BOS_TIME();
1053                         break;
1054                 case 111: /* get restart time */
1055                         OUT_UINT(hf_afs_bos_num);
1056                         break;
1057                 case 112: /* get log */
1058                         OUT_STRING(hf_afs_bos_file);
1059                         break;
1060                 case 113: /* wait all */
1061                         /* no params */
1062                         break;
1063                 case 114: /* get instance strings */
1064                         OUT_STRING(hf_afs_bos_content);
1065                         break;
1066         }
1067 }
1068
1069 /*
1070  * VOL Helpers
1071  */
1072 static void
1073 dissect_vol_reply(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int opcode)
1074 {
1075         struct rx_header *rxh;
1076         unsigned char *data;
1077         int doffset, curoffset;
1078
1079         rxh = (struct rx_header *) &pd[offset];
1080         data = (char *)rxh + sizeof(struct rx_header);
1081         doffset = offset + sizeof(struct rx_header);
1082         curoffset = doffset;
1083
1084         if ( rxh->type == RX_PACKET_TYPE_DATA )
1085         {
1086                 switch ( opcode )
1087                 {
1088                         case 121:
1089                                 /* should loop here maybe */
1090                                 OUT_UINT(hf_afs_vol_count);
1091                                 VECOUT(hf_afs_vol_name, 32); /* not sure on  */
1092                                 break;
1093                 }
1094         }
1095         else if ( rxh->type == RX_PACKET_TYPE_ABORT )
1096         {
1097                 OUT_UINT(hf_afs_vol_errcode);
1098         }
1099 }
1100
1101 static void
1102 dissect_vol_request(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int opcode)
1103 {
1104         struct rx_header *rxh;
1105         unsigned char *data;
1106         int doffset, curoffset;
1107
1108         rxh = (struct rx_header *) &pd[offset];
1109         data = (char *)rxh + sizeof(struct rx_header);
1110         doffset = offset + sizeof(struct rx_header);
1111         curoffset = doffset;
1112
1113         SKIP_OPCODE();
1114
1115         switch ( opcode )
1116         {
1117                 case 121: /* list one vol */
1118                         OUT_UINT(hf_afs_vol_count);
1119                         OUT_UINT(hf_afs_vol_id);
1120                         break;
1121         }
1122 }
1123
1124 /*
1125  * KAUTH Helpers
1126  */
1127 static void
1128 dissect_kauth_reply(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int opcode)
1129 {
1130         struct rx_header *rxh;
1131         unsigned char *data;
1132         int doffset, curoffset;
1133
1134         rxh = (struct rx_header *) &pd[offset];
1135         data = (char *)rxh + sizeof(struct rx_header);
1136         doffset = offset + sizeof(struct rx_header);
1137         curoffset = doffset;
1138
1139         if ( rxh->type == RX_PACKET_TYPE_DATA )
1140         {
1141                 switch ( opcode )
1142                 {
1143                 }
1144         }
1145         else if ( rxh->type == RX_PACKET_TYPE_ABORT )
1146         {
1147                 OUT_UINT(hf_afs_kauth_errcode);
1148         }
1149 }
1150
1151 static void
1152 dissect_kauth_request(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int opcode)
1153 {
1154         struct rx_header *rxh;
1155         unsigned char *data;
1156         int doffset, curoffset;
1157
1158         rxh = (struct rx_header *) &pd[offset];
1159         data = (char *)rxh + sizeof(struct rx_header);
1160         doffset = offset + sizeof(struct rx_header);
1161         curoffset = doffset;
1162
1163         SKIP_OPCODE();
1164
1165         switch ( opcode )
1166         {
1167                 case 1: /* authenticate old */
1168                 case 21: /* authenticate */
1169                 case 22: /* authenticate v2 */
1170                 case 2: /* change pw */
1171                 case 5: /* set fields */
1172                 case 6: /* create user */
1173                 case 7: /* delete user */
1174                 case 8: /* get entry */
1175                 case 14: /* unlock */
1176                 case 15: /* lock status */
1177                         OUT_STRING(hf_afs_kauth_princ);
1178                         OUT_STRING(hf_afs_kauth_realm);
1179                         OUT_BYTES_ALL(hf_afs_kauth_data);
1180                         break;
1181                 case 3: /* getticket-old */
1182                 case 23: /* getticket */
1183                         OUT_UINT(hf_afs_kauth_kvno);
1184                         OUT_STRING(hf_afs_kauth_domain);
1185                         OUT_STRING(hf_afs_kauth_data);
1186                         OUT_STRING(hf_afs_kauth_princ);
1187                         OUT_STRING(hf_afs_kauth_realm);
1188                         break;
1189                 case 4: /* set pass */
1190                         OUT_STRING(hf_afs_kauth_princ);
1191                         OUT_STRING(hf_afs_kauth_realm);
1192                         OUT_UINT(hf_afs_kauth_kvno);
1193                         break;
1194                 case 12: /* get pass */
1195                         OUT_STRING(hf_afs_kauth_name);
1196                         break;
1197         }
1198 }
1199
1200 /*
1201  * CB Helpers
1202  */
1203 static void
1204 dissect_cb_reply(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int opcode)
1205 {
1206         struct rx_header *rxh;
1207         unsigned char *data;
1208         int doffset, curoffset;
1209
1210         rxh = (struct rx_header *) &pd[offset];
1211         data = (char *)rxh + sizeof(struct rx_header);
1212         doffset = offset + sizeof(struct rx_header);
1213         curoffset = doffset;
1214
1215         if ( rxh->type == RX_PACKET_TYPE_DATA )
1216         {
1217                 switch ( opcode )
1218                 {
1219                 }
1220         }
1221         else if ( rxh->type == RX_PACKET_TYPE_ABORT )
1222         {
1223                 OUT_UINT(hf_afs_cb_errcode);
1224         }
1225 }
1226
1227 static void
1228 dissect_cb_request(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int opcode)
1229 {
1230         struct rx_header *rxh;
1231         unsigned char *data;
1232         int doffset, curoffset;
1233
1234         rxh = (struct rx_header *) &pd[offset];
1235         data = (char *)rxh + sizeof(struct rx_header);
1236         doffset = offset + sizeof(struct rx_header);
1237         curoffset = doffset;
1238
1239         SKIP_OPCODE();
1240
1241         switch ( opcode )
1242         {
1243                 case 204: /* callback */
1244                 {
1245                         unsigned int i,j;
1246
1247                         TRUNC(4);
1248                         j = GETINT();
1249
1250                         for (i=0; i<j; i++)
1251                         {
1252                                 OUT_CB_AFSFid("Target");
1253                         }
1254
1255                         TRUNC(4);
1256                         j = GETINT();
1257                         for (i=0; i<j; i++)
1258                         {
1259                                 OUT_CB_AFSCallBack();
1260                         }
1261                 }
1262         }
1263 }
1264
1265 /*
1266  * PROT Helpers
1267  */
1268 static void
1269 dissect_prot_reply(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int opcode)
1270 {
1271         struct rx_header *rxh;
1272         unsigned char *data;
1273         int doffset, curoffset;
1274
1275         rxh = (struct rx_header *) &pd[offset];
1276         data = (char *)rxh + sizeof(struct rx_header);
1277         doffset = offset + sizeof(struct rx_header);
1278         curoffset = doffset;
1279
1280         if ( rxh->type == RX_PACKET_TYPE_DATA )
1281         {
1282                 switch ( opcode )
1283                 {
1284                         case 504: /* name to id */
1285                                 {
1286                                         unsigned int i, j;
1287
1288                                         TRUNC(4);
1289                                         j = GETINT();
1290                                         OUT_UINT(hf_afs_prot_count);
1291
1292                                         for (i=0; i<j; i++)
1293                                         {
1294                                                 OUT_UINT(hf_afs_prot_id);
1295                                         }
1296                                 }
1297                                 break;
1298                         case 505: /* id to name */
1299                                 {
1300                                         unsigned int i, j;
1301
1302                                         TRUNC(4);
1303                                         j = GETINT();
1304                                         OUT_UINT(hf_afs_prot_count);
1305
1306                                         for (i=0; i<j; i++)
1307                                         {
1308                                                 VECOUT(hf_afs_prot_name, PRNAMEMAX);
1309                                         }
1310                                 }
1311                                 break;
1312                         case 508: /* get cps */
1313                         case 514: /* list elements */
1314                         case 517: /* list owned */
1315                         case 518: /* get cps2 */
1316                         case 519: /* get host cps */
1317                                 {
1318                                         unsigned int i, j;
1319
1320                                         TRUNC(4);
1321                                         j = GETINT();
1322                                         OUT_UINT(hf_afs_prot_count);
1323
1324                                         for (i=0; i<j; i++)
1325                                         {
1326                                                 OUT_UINT(hf_afs_prot_id);
1327                                         }
1328                                 }
1329                                 break;
1330                         case 510: /* list max */
1331                                 OUT_UINT(hf_afs_prot_maxuid);
1332                                 OUT_UINT(hf_afs_prot_maxgid);
1333                                 break;
1334                 }
1335         }
1336         else if ( rxh->type == RX_PACKET_TYPE_ABORT )
1337         {
1338                 OUT_UINT(hf_afs_prot_errcode);
1339         }
1340 }
1341
1342 static void
1343 dissect_prot_request(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int opcode)
1344 {
1345         struct rx_header *rxh;
1346         unsigned char *data;
1347         int doffset, curoffset;
1348
1349         rxh = (struct rx_header *) &pd[offset];
1350         data = (char *)rxh + sizeof(struct rx_header);
1351         doffset = offset + sizeof(struct rx_header);
1352         curoffset = doffset;
1353
1354         SKIP_OPCODE();
1355
1356         switch ( opcode )
1357         {
1358                 case 500: /* new user */
1359                         OUT_STRING(hf_afs_prot_name);
1360                         OUT_UINT(hf_afs_prot_id);
1361                         OUT_UINT(hf_afs_prot_oldid);
1362                         break;
1363                 case 501: /* where is it */
1364                 case 506: /* delete */
1365                 case 508: /* get cps */
1366                 case 512: /* list entry */
1367                 case 514: /* list elements */
1368                 case 517: /* list owned */
1369                 case 519: /* get host cps */
1370                         OUT_UINT(hf_afs_prot_id);
1371                         break;
1372                 case 502: /* dump entry */
1373                         OUT_UINT(hf_afs_prot_pos);
1374                         break;
1375                 case 503: /* add to group */
1376                 case 507: /* remove from group */
1377                 case 515: /* is a member of? */
1378                         OUT_UINT(hf_afs_prot_uid);
1379                         OUT_UINT(hf_afs_prot_gid);
1380                         break;
1381                 case 504: /* name to id */
1382                         {
1383                                 unsigned int i, j;
1384
1385                                 TRUNC(4);
1386                                 j = GETINT();
1387                                 OUT_UINT(hf_afs_prot_count);
1388
1389                                 for (i=0; i<j; i++)
1390                                 {
1391                                         VECOUT(hf_afs_prot_name,PRNAMEMAX);
1392                                 }
1393                         }
1394                         break;
1395                 case 505: /* id to name */
1396                         {
1397                                 unsigned int i, j;
1398
1399                                 TRUNC(4);
1400                                 j = GETINT();
1401                                 OUT_UINT(hf_afs_prot_count);
1402
1403                                 for (i=0; i<j; i++)
1404                                 {
1405                                         OUT_UINT(hf_afs_prot_id);
1406                                 }
1407                         }
1408                         break;
1409                 case 509: /* new entry */
1410                         OUT_STRING(hf_afs_prot_name);
1411                         OUT_UINT(hf_afs_prot_flag);
1412                         OUT_UINT(hf_afs_prot_oldid);
1413                         break;
1414                 case 511: /* set max */
1415                         OUT_UINT(hf_afs_prot_id);
1416                         OUT_UINT(hf_afs_prot_flag);
1417                         break;
1418                 case 513: /* change entry */
1419                         OUT_UINT(hf_afs_prot_id);
1420                         OUT_STRING(hf_afs_prot_name);
1421                         OUT_UINT(hf_afs_prot_oldid);
1422                         OUT_UINT(hf_afs_prot_newid);
1423                         break;
1424                 case 520: /* update entry */
1425                         OUT_UINT(hf_afs_prot_id);
1426                         OUT_STRING(hf_afs_prot_name);
1427                         break;
1428         }
1429 }
1430
1431 /*
1432  * VLDB Helpers
1433  */
1434 static void
1435 dissect_vldb_reply(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int opcode)
1436 {
1437         struct rx_header *rxh;
1438         unsigned char *data;
1439         int doffset, curoffset;
1440
1441         rxh = (struct rx_header *) &pd[offset];
1442         data = (char *)rxh + sizeof(struct rx_header);
1443         doffset = offset + sizeof(struct rx_header);
1444         curoffset = doffset;
1445
1446         if ( rxh->type == RX_PACKET_TYPE_DATA )
1447         {
1448                 switch ( opcode )
1449                 {
1450                         case 510: /* list entry */
1451                                 OUT_UINT(hf_afs_vldb_count);
1452                                 OUT_UINT(hf_afs_vldb_nextindex);
1453                                 break;
1454                         case 503: /* get entry by id */
1455                         case 504: /* get entry by name */
1456                                 {
1457                                         int nservers,i,j;
1458                                         VECOUT(hf_afs_vldb_name, VLNAMEMAX);
1459                                         TRUNC(4);
1460                                         nservers = GETINT();
1461                                         OUT_UINT(hf_afs_vldb_numservers);
1462                                         for (i=0; i<8; i++)
1463                                         {
1464                                                 if ( i<nservers )
1465                                                 {
1466                                                         OUT_IP(hf_afs_vldb_server);
1467                                                 }
1468                                                 else
1469                                                 {
1470                                                         SKIP(4);
1471                                                 }
1472                                         }
1473                                         for (i=0; i<8; i++)
1474                                         {
1475                                                 char part[8];
1476                                                 TRUNC(4);
1477                                                 j = GETINT();
1478                                                 strcpy(part, "/vicepa");
1479                                                 if ( i<nservers && j<=25 )
1480                                                 {
1481                                                         part[6] = 'a' + (char) j;
1482                                                         proto_tree_add_string(tree, hf_afs_vldb_partition, NullTVB,
1483                                                                 curoffset, 4, part);
1484                                                 }
1485                                                 SKIP(4);
1486                                         }
1487                                         SKIP(8 * sizeof(guint32));
1488                                         OUT_UINT(hf_afs_vldb_rwvol);
1489                                         OUT_UINT(hf_afs_vldb_rovol);
1490                                         OUT_UINT(hf_afs_vldb_bkvol);
1491                                 }
1492                                 break;
1493                         case 505: /* get new volume id */
1494                                 OUT_UINT(hf_afs_vldb_id);
1495                                 break;
1496                         case 521: /* list entry */
1497                         case 529: /* list entry U */
1498                                 OUT_UINT(hf_afs_vldb_count);
1499                                 OUT_UINT(hf_afs_vldb_nextindex);
1500                                 break;
1501                         case 518: /* get entry by id n */
1502                         case 519: /* get entry by name N */
1503                                 {
1504                                         int nservers,i,j;
1505                                         VECOUT(hf_afs_vldb_name, VLNAMEMAX);
1506                                         TRUNC(4);
1507                                         nservers = GETINT();
1508                                         OUT_UINT(hf_afs_vldb_numservers);
1509                                         for (i=0; i<13; i++)
1510                                         {
1511                                                 if ( i<nservers )
1512                                                 {
1513                                                         OUT_IP(hf_afs_vldb_server);
1514                                                 }
1515                                                 else
1516                                                 {
1517                                                         SKIP(4);
1518                                                 }
1519                                         }
1520                                         for (i=0; i<13; i++)
1521                                         {
1522                                                 char part[8];
1523                                                 TRUNC(4);
1524                                                 j = GETINT();
1525                                                 strcpy(part, "/vicepa");
1526                                                 if ( i<nservers && j<=25 )
1527                                                 {
1528                                                         part[6] = 'a' + (char) j;
1529                                                         proto_tree_add_string(tree, hf_afs_vldb_partition, NullTVB,
1530                                                                 curoffset, 4, part);
1531                                                 }
1532                                                 SKIP(4);
1533                                         }
1534                                         SKIP(13 * sizeof(guint32));
1535                                         OUT_UINT(hf_afs_vldb_rwvol);
1536                                         OUT_UINT(hf_afs_vldb_rovol);
1537                                         OUT_UINT(hf_afs_vldb_bkvol);
1538                                 }
1539                                 break;
1540                         case 526: /* get entry by id u */
1541                         case 527: /* get entry by name u */
1542                                 {
1543                                         int nservers,i,j;
1544                                         VECOUT(hf_afs_vldb_name, VLNAMEMAX);
1545                                         TRUNC(4);
1546                                         nservers = GETINT();
1547                                         OUT_UINT(hf_afs_vldb_numservers);
1548                                         for (i=0; i<13; i++)
1549                                         {
1550                                                 if ( i<nservers )
1551                                                 {
1552                                                         OUT_BYTES(hf_afs_vldb_serveruuid, 11*sizeof(guint32));
1553                                                 }
1554                                                 else
1555                                                 {
1556                                                         SKIP(11*sizeof(guint32));
1557                                                 }
1558                                         }
1559                                         for (i=0; i<13; i++)
1560                                         {
1561                                                 char part[8];
1562                                                 TRUNC(4);
1563                                                 j = GETINT();
1564                                                 strcpy(part, "/vicepa");
1565                                                 if ( i<nservers && j<=25 )
1566                                                 {
1567                                                         part[6] = 'a' + (char) j;
1568                                                         proto_tree_add_string(tree, hf_afs_vldb_partition, NullTVB,
1569                                                                 curoffset, 4, part);
1570                                                 }
1571                                                 SKIP(4);
1572                                         }
1573                                         SKIP(13 * sizeof(guint32));
1574                                         OUT_UINT(hf_afs_vldb_rwvol);
1575                                         OUT_UINT(hf_afs_vldb_rovol);
1576                                         OUT_UINT(hf_afs_vldb_bkvol);
1577                                 }
1578                                 break;
1579                 }
1580         }
1581         else if ( rxh->type == RX_PACKET_TYPE_ABORT )
1582         {
1583                 OUT_UINT(hf_afs_vldb_errcode);
1584         }
1585 }
1586
1587 static void
1588 dissect_vldb_request(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int opcode)
1589 {
1590         struct rx_header *rxh;
1591         unsigned char *data;
1592         int doffset, curoffset;
1593
1594         rxh = (struct rx_header *) &pd[offset];
1595         data = (char *)rxh + sizeof(struct rx_header);
1596         doffset = offset + sizeof(struct rx_header);
1597         curoffset = doffset;
1598
1599         SKIP_OPCODE();
1600
1601         switch ( opcode )
1602         {
1603                 case 501: /* create new volume */
1604                 case 517: /* create entry N */
1605                         VECOUT(hf_afs_vldb_name, VLNAMEMAX);
1606                         break;
1607                 case 502: /* delete entry */
1608                 case 503: /* get entry by id */
1609                 case 507: /* update entry */
1610                 case 508: /* set lock */
1611                 case 509: /* release lock */
1612                 case 518: /* get entry by id */
1613                         OUT_UINT(hf_afs_vldb_id);
1614                         OUT_UINT(hf_afs_vldb_type);
1615                         break;
1616                 case 504: /* get entry by name */
1617                 case 519: /* get entry by name N */
1618                 case 524: /* update entry by name */
1619                 case 527: /* get entry by name U */
1620                         OUT_STRING(hf_afs_vldb_name);
1621                         break;
1622                 case 505: /* get new vol id */
1623                         OUT_UINT(hf_afs_vldb_bump);
1624                         break;
1625                 case 506: /* replace entry */
1626                 case 520: /* replace entry N */
1627                         OUT_UINT(hf_afs_vldb_id);
1628                         OUT_UINT(hf_afs_vldb_type);
1629                         VECOUT(hf_afs_vldb_name, VLNAMEMAX);
1630                         break;
1631                 case 510: /* list entry */
1632                 case 521: /* list entry N */
1633                         OUT_UINT(hf_afs_vldb_index);
1634                         break;
1635         }
1636 }
1637
1638 /*
1639  * UBIK Helpers
1640  */
1641 static void
1642 dissect_ubik_reply(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int opcode)
1643 {
1644         struct rx_header *rxh;
1645         unsigned char *data;
1646         int doffset, curoffset;
1647
1648         rxh = (struct rx_header *) &pd[offset];
1649         data = (char *)rxh + sizeof(struct rx_header);
1650         doffset = offset + sizeof(struct rx_header);
1651         curoffset = doffset;
1652
1653         switch ( opcode )
1654         {
1655                 case 10000: /* vote-beacon */
1656                         break;
1657                 case 10001: /* vote-debug-old */
1658                         /* ubik_debug_old */
1659                         break;
1660                 case 10002: /* vote-sdebug-old */
1661                         /* ubik_sdebug_old */
1662                         break;
1663                 case 10003: /* vote-get syncsite */
1664                         break;
1665                 case 10004: /* vote-debug */
1666                         /* ubik_debug */
1667                         break;
1668                 case 10005: /* vote-sdebug */
1669                         /* ubik_sdebug */
1670                         break;
1671                 case 10006: /* vote-xdebug */
1672                         /* ubik_debug */
1673                         /* isClone */
1674                         break;
1675                 case 10007: /* vote-xsdebug */
1676                         /* ubik_sdebug */
1677                         /* isClone */
1678                         break;
1679
1680                 case 20000: /* disk-begin */
1681                         break;
1682                 case 20004: /* get version */
1683                         OUT_UBIKVERSION("DB Version");
1684                         break;
1685                 case 20010: /* disk-probe */
1686                         break;
1687
1688         }
1689 }
1690
1691 static void
1692 dissect_ubik_request(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int opcode)
1693 {
1694         struct rx_header *rxh;
1695         unsigned char *data;
1696         int doffset, curoffset;
1697
1698         rxh = (struct rx_header *) &pd[offset];
1699         data = (char *)rxh + sizeof(struct rx_header);
1700         doffset = offset + sizeof(struct rx_header);
1701         curoffset = doffset;
1702
1703         SKIP_OPCODE();
1704
1705         switch ( opcode )
1706         {
1707                 case 10000: /* vote-beacon */
1708                         OUT_UINT(hf_afs_ubik_state);
1709                         OUT_DATE(hf_afs_ubik_votestart);
1710                         OUT_UBIKVERSION("DB Version");
1711                         OUT_UBIKVERSION("TID");
1712                         break;
1713                 case 10001: /* vote-debug-old */
1714                         break;
1715                 case 10002: /* vote-sdebug-old */
1716                         OUT_UINT(hf_afs_ubik_site);
1717                         break;
1718                 case 10003: /* vote-get sync site */
1719                         OUT_IP(hf_afs_ubik_site);
1720                         break;
1721                 case 10004: /* vote-debug */
1722                 case 10005: /* vote-sdebug */
1723                         OUT_IP(hf_afs_ubik_site);
1724                         break;
1725                 case 20000: /* disk-begin */
1726                         OUT_UBIKVERSION("TID");
1727                         break;
1728                 case 20001: /* disk-commit */
1729                         OUT_UBIKVERSION("TID");
1730                         break;
1731                 case 20002: /* disk-lock */
1732                         OUT_UBIKVERSION("TID");
1733                         OUT_UINT(hf_afs_ubik_file);
1734                         OUT_UINT(hf_afs_ubik_pos);
1735                         OUT_UINT(hf_afs_ubik_length);
1736                         OUT_UINT(hf_afs_ubik_locktype);
1737                         break;
1738                 case 20003: /* disk-write */
1739                         OUT_UBIKVERSION("TID");
1740                         OUT_UINT(hf_afs_ubik_file);
1741                         OUT_UINT(hf_afs_ubik_pos);
1742                         break;
1743                 case 20004: /* disk-get version */
1744                         break;
1745                 case 20005: /* disk-get file */
1746                         OUT_UINT(hf_afs_ubik_file);
1747                         break;
1748                 case 20006: /* disk-send file */
1749                         OUT_UINT(hf_afs_ubik_file);
1750                         OUT_UINT(hf_afs_ubik_length);
1751                         OUT_UBIKVERSION("DB Version");
1752                         break;
1753                 case 20007: /* disk-abort */
1754                 case 20008: /* disk-release locks */
1755                 case 20010: /* disk-probe */
1756                         break;
1757                 case 20009: /* disk-truncate */
1758                         OUT_UBIKVERSION("TID");
1759                         OUT_UINT(hf_afs_ubik_file);
1760                         OUT_UINT(hf_afs_ubik_length);
1761                         break;
1762                 case 20011: /* disk-writev */
1763                         OUT_UBIKVERSION("TID");
1764                         break;
1765                 case 20012: /* disk-set version */
1766                         OUT_UBIKVERSION("TID");
1767                         OUT_UBIKVERSION("Old DB Version");
1768                         OUT_UBIKVERSION("New DB Version");
1769                         break;
1770         }
1771 }
1772
1773 /*
1774  * BACKUP Helpers
1775  */
1776 static void
1777 dissect_backup_reply(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int opcode)
1778 {
1779         struct rx_header *rxh;
1780         unsigned char *data;
1781         int doffset, curoffset;
1782
1783         rxh = (struct rx_header *) &pd[offset];
1784         data = (char *)rxh + sizeof(struct rx_header);
1785         doffset = offset + sizeof(struct rx_header);
1786         curoffset = doffset;
1787
1788         if ( rxh->type == RX_PACKET_TYPE_DATA )
1789         {
1790                 switch ( opcode )
1791                 {
1792                 }
1793         }
1794         else if ( rxh->type == RX_PACKET_TYPE_ABORT )
1795         {
1796                 OUT_UINT(hf_afs_backup_errcode);
1797         }
1798 }
1799
1800 static void
1801 dissect_backup_request(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int opcode)
1802 {
1803         struct rx_header *rxh;
1804         unsigned char *data;
1805         int doffset, curoffset;
1806
1807         rxh = (struct rx_header *) &pd[offset];
1808         data = (char *)rxh + sizeof(struct rx_header);
1809         doffset = offset + sizeof(struct rx_header);
1810         curoffset = doffset;
1811
1812         SKIP_OPCODE();
1813
1814         switch ( opcode )
1815         {
1816         }
1817 }
1818
1819 /*
1820  * Registration code for registering the protocol and fields
1821  */
1822
1823 void
1824 proto_register_afs(void)
1825 {
1826         static hf_register_info hf[] = {
1827 #include "packet-afs-register-info.h"
1828         };
1829         static gint *ett[] = {
1830                 &ett_afs,
1831                 &ett_afs_op,
1832                 &ett_afs_acl,
1833                 &ett_afs_fid,
1834                 &ett_afs_callback,
1835                 &ett_afs_ubikver,
1836                 &ett_afs_status,
1837                 &ett_afs_status_mask,
1838                 &ett_afs_volsync,
1839                 &ett_afs_volumeinfo,
1840                 &ett_afs_vicestat,
1841         };
1842
1843         proto_afs = proto_register_protocol("Andrew File System (AFS)",
1844             "AFS (RX)", "afs");
1845         proto_register_field_array(proto_afs, hf, array_length(hf));
1846         proto_register_subtree_array(ett, array_length(ett));
1847         register_init_routine(&afs_init_protocol);
1848 }