finished up structure for fs replies, though macros still need implemented
[obnox/wireshark/wip.git] / packet-afs-macros.h
1 /* packet-afs-macros.h
2  * Helper macros 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-macros.h,v 1.2 2000/11/03 18:37:24 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
35
36 /*
37  * Macros for helper dissection routines
38  *
39  * The macros are here to save on coding. They assume that
40  * the current offset is in 'curoffset', and that the offset
41  * should be incremented after performing the macro's operation.
42  */
43
44 /* Get the next available integer, be sure and call TRUNC beforehand */
45 #define GETINT() (pntohl(&pd[curoffset]))
46
47 /* Check if enough bytes are present, if not, return to caller
48    after adding a 'Truncated' message to tree */
49 #define TRUNC(bytes) \
50         if(!BYTES_ARE_IN_FRAME(curoffset,(bytes))) \
51         { proto_tree_add_text(tree, NullTVB,curoffset,END_OF_FRAME,"Truncated"); \
52         return; }
53
54 /* Output a unsigned integer, stored into field 'field'
55    Assumes it is in network byte order, converts to host before using */
56 #define OUT_UINT(field) \
57         TRUNC(sizeof(guint32)) \
58         proto_tree_add_uint(tree,field, NullTVB,curoffset,sizeof(guint32), GETINT()); \
59         curoffset += 4;
60         
61 /* Output a unsigned integer, stored into field 'field'
62    Assumes it is in network byte order, converts to host before using, 
63    Note - does not increment offset, so can be used repeatedly for bitfields */
64 #define DISP_UINT(field) \
65         TRUNC(sizeof(guint32)) \
66         proto_tree_add_uint(tree,field, NullTVB,curoffset,sizeof(guint32), GETINT()); 
67
68 /* Output an IPv4 address, stored into field 'field' */
69 #define OUT_IP(field) \
70         TRUNC(sizeof(gint32)) \
71         proto_tree_add_ipv4(tree,field, NullTVB,curoffset,sizeof(gint32),\
72                 *((int*)&pd[curoffset]));\
73         curoffset += 4;
74
75 /* Output a UNIX seconds/microseconds timestamp, after converting to a timeval */
76 #define OUT_TIMESTAMP(field) \
77         { struct timeval tv; \
78         TRUNC(2*sizeof(guint32)); \
79         tv.tv_sec = GETINT(); \
80         tv.tv_usec = GETINT(); \
81         proto_tree_add_time(tree,field, NullTVB,curoffset,2*sizeof(guint32),&tv); \
82         curoffset += 8; \
83         }
84
85 /* Output a UNIX seconds-only timestamp, after converting to a timeval */
86 #define OUT_DATE(field) \
87         { struct timeval tv; \
88         TRUNC(sizeof(guint32)); \
89         tv.tv_sec = GETINT(); \
90         tv.tv_usec = 0; \
91         proto_tree_add_time(tree,field, NullTVB,curoffset,sizeof(guint32),&tv); \
92         curoffset += 4; \
93         }
94
95 /* Output a callback */
96 #define OUT_FS_AFSCallBack() \
97         {       proto_tree *save, *ti; \
98                 ti = proto_tree_add_text(tree, NullTVB, curoffset, 3*4, "Callback"); \
99                 save = tree; \
100                 tree = proto_item_add_subtree(ti, ett_afs_callback); \
101                 TRUNC(3*sizeof(guint32)); \
102                 OUT_UINT(hf_afs_fs_callback_version); \
103                 OUT_TIMESTAMP(hf_afs_fs_callback_expires); \
104                 OUT_UINT(hf_afs_fs_callback_type); \
105                 tree = save; \
106         }
107
108 /* Output a callback */
109 #define CB_CALLBACKOUT() \
110         {       proto_tree *save, *ti; \
111                 ti = proto_tree_add_text(tree, NullTVB, curoffset, 3*4, "Callback"); \
112                 save = tree; \
113                 tree = proto_item_add_subtree(ti, ett_afs_callback); \
114                 TRUNC(3*sizeof(guint32)); \
115                 OUT_UINT(hf_afs_cb_callback_version); \
116                 OUT_DATE(hf_afs_cb_callback_expires); \
117                 OUT_UINT(hf_afs_cb_callback_type); \
118                 tree = save; \
119         }
120
121
122 /* Output a File ID */
123 #define OUT_FS_AFSFid(label) \
124         {       proto_tree *save, *ti; \
125                 ti = proto_tree_add_text(tree, NullTVB, curoffset, 3*4, \
126                         "FileID (%s)", label); \
127                 save = tree; \
128                 tree = proto_item_add_subtree(ti, ett_afs_fid); \
129                 OUT_UINT(hf_afs_fs_fid_volume); \
130                 OUT_UINT(hf_afs_fs_fid_vnode); \
131                 OUT_UINT(hf_afs_fs_fid_uniqifier); \
132                 tree = save; \
133         }
134
135 /* Output a Status mask */
136 #define OUT_FS_STATUSMASK() \
137         {       proto_tree *save, *ti; \
138                 guint32 mask; \
139                 TRUNC(sizeof(guint32)); \
140                 mask = GETINT(); \
141                 ti = proto_tree_add_uint(tree, hf_afs_fs_status_mask, NullTVB, curoffset, \
142                         sizeof(guint32), mask); \
143                 save = tree; \
144                 tree = proto_item_add_subtree(ti, ett_afs_status_mask); \
145                 proto_tree_add_uint(tree, hf_afs_fs_status_mask_setmodtime, \
146                         NullTVB,curoffset,sizeof(guint32), mask); \
147                 proto_tree_add_uint(tree, hf_afs_fs_status_mask_setowner, \
148                         NullTVB,curoffset,sizeof(guint32), mask); \
149                 proto_tree_add_uint(tree, hf_afs_fs_status_mask_setgroup, \
150                         NullTVB,curoffset,sizeof(guint32), mask); \
151                 proto_tree_add_uint(tree, hf_afs_fs_status_mask_setmode, \
152                         NullTVB,curoffset,sizeof(guint32), mask); \
153                 proto_tree_add_uint(tree, hf_afs_fs_status_mask_setsegsize, \
154                         NullTVB,curoffset,sizeof(guint32), mask); \
155                 proto_tree_add_uint(tree, hf_afs_fs_status_mask_fsync, \
156                         NullTVB,curoffset,sizeof(guint32), mask); \
157                 curoffset += 4; \
158                 tree = save; \
159         }
160
161 /* Output a File ID */
162 #define OUT_CB_AFSFid(label) \
163         {       proto_tree *save, *ti; \
164                 ti = proto_tree_add_text(tree, NullTVB, curoffset, 3*4, \
165                         "FileID (%s)", label); \
166                 save = tree; \
167                 tree = proto_item_add_subtree(ti, ett_afs_fid); \
168                 OUT_UINT(hf_afs_cb_fid_volume); \
169                 OUT_UINT(hf_afs_cb_fid_vnode); \
170                 OUT_UINT(hf_afs_cb_fid_uniqifier); \
171                 tree = save; \
172         }
173         
174 /* Output a StoreStatus */
175 #define OUT_FS_AFSStoreStatus(label) \
176         {       proto_tree *save, *ti; \
177                 ti = proto_tree_add_text(tree, NullTVB, curoffset, 6*4, \
178                         label); \
179                 save = tree; \
180                 tree = proto_item_add_subtree(ti, ett_afs_status); \
181                 OUT_FS_STATUSMASK(); \
182                 OUT_DATE(hf_afs_fs_status_clientmodtime); \
183                 OUT_UINT(hf_afs_fs_status_owner); \
184                 OUT_UINT(hf_afs_fs_status_group); \
185                 OUT_UINT(hf_afs_fs_status_mode); \
186                 OUT_UINT(hf_afs_fs_status_segsize); \
187                 tree = save; \
188         }
189
190 /* Output a FetchStatus */
191 #define OUT_FS_AFSFetchStatus(label) \
192         {       proto_tree *save, *ti; \
193                 ti = proto_tree_add_text(tree, NullTVB, curoffset, 21*4, \
194                         label); \
195                 save = tree; \
196                 tree = proto_item_add_subtree(ti, ett_afs_status); \
197                 OUT_UINT(hf_afs_fs_status_interfaceversion); \
198                 OUT_UINT(hf_afs_fs_status_filetype); \
199                 OUT_UINT(hf_afs_fs_status_linkcount); \
200                 OUT_UINT(hf_afs_fs_status_length); \
201                 OUT_UINT(hf_afs_fs_status_dataversion); \
202                 OUT_UINT(hf_afs_fs_status_author); \
203                 OUT_UINT(hf_afs_fs_status_owner); \
204                 OUT_UINT(hf_afs_fs_status_calleraccess); \
205                 OUT_UINT(hf_afs_fs_status_anonymousaccess); \
206                 OUT_UINT(hf_afs_fs_status_mode); \
207                 OUT_UINT(hf_afs_fs_status_parentvnode); \
208                 OUT_UINT(hf_afs_fs_status_parentunique); \
209                 OUT_UINT(hf_afs_fs_status_segsize); \
210                 OUT_DATE(hf_afs_fs_status_clientmodtime); \
211                 OUT_DATE(hf_afs_fs_status_servermodtime); \
212                 OUT_UINT(hf_afs_fs_status_group); \
213                 OUT_UINT(hf_afs_fs_status_synccounter); \
214                 OUT_UINT(hf_afs_fs_status_dataversionhigh); \
215                 OUT_UINT(hf_afs_fs_status_spare2); \
216                 OUT_UINT(hf_afs_fs_status_spare3); \
217                 OUT_UINT(hf_afs_fs_status_spare4); \
218                 tree = save; \
219         }
220
221 /* Output a VolSync */
222 #define OUT_FS_AFSVolSync() \
223         {       proto_tree *save, *ti; \
224                 ti = proto_tree_add_text(tree, NullTVB, curoffset, 6*4, \
225                         "VolSync"); \
226                 save = tree; \
227                 tree = proto_item_add_subtree(ti, ett_afs_volsync); \
228                 OUT_UINT(hf_afs_fs_volsync_spare1); \
229                 OUT_UINT(hf_afs_fs_volsync_spare2); \
230                 OUT_UINT(hf_afs_fs_volsync_spare3); \
231                 OUT_UINT(hf_afs_fs_volsync_spare4); \
232                 OUT_UINT(hf_afs_fs_volsync_spare5); \
233                 OUT_UINT(hf_afs_fs_volsync_spare6); \
234                 tree = save; \
235         }
236
237 /* Output a AFSCBFids */
238 #define OUT_FS_AFSCBFids()
239
240 /* Output a AFSCBs */
241 #define OUT_FS_AFSCBs()
242
243 /* Output a AFSBulkStats */
244 #define OUT_FS_AFSBulkStats()
245
246 /* Output a AFSFetchVolumeStatus */
247 #define OUT_FS_AFSFetchVolumeStatus()
248
249 /* Output a AFSStoreVolumeStatus */
250 #define OUT_FS_AFSStoreVolumeStatus()
251
252 /* Output a ViceStatistics structure */
253 #define OUT_FS_ViceStatistics()
254
255 /* Output a AFS_CollData structure */
256 #define OUT_FS_AFS_CollData()
257
258 /* Output a VolumeInfo structure */
259 #define OUT_FS_VolumeInfo()
260
261 /* Output a AFS acl */
262 #define ACLOUT(who, positive, acl, bytes) \
263         {       proto_tree *save, *ti; \
264                 int tmpoffset; \
265                 int acllen; \
266                 char tmp[10]; \
267                 tmp[0] = 0; \
268                 if ( acl & PRSFS_READ ) strcat(tmp, "r"); \
269                 if ( acl & PRSFS_LOOKUP ) strcat(tmp, "l"); \
270                 if ( acl & PRSFS_INSERT ) strcat(tmp, "i"); \
271                 if ( acl & PRSFS_DELETE ) strcat(tmp, "d"); \
272                 if ( acl & PRSFS_WRITE ) strcat(tmp, "w"); \
273                 if ( acl & PRSFS_LOCK ) strcat(tmp, "k"); \
274                 if ( acl & PRSFS_ADMINISTER ) strcat(tmp, "a"); \
275                 ti = proto_tree_add_text(tree, NullTVB, curoffset, bytes, \
276                         "ACL:  %s %s%s", \
277                         who, tmp, positive ? "" : " (negative)"); \
278                 save = tree; \
279                 tree = proto_item_add_subtree(ti, ett_afs_acl); \
280                 proto_tree_add_string(tree,hf_afs_fs_acl_entity, NullTVB,curoffset,strlen(who), who);\
281                 tmpoffset = curoffset + strlen(who) + 1; \
282                 acllen = bytes - strlen(who) - 1; \
283                 proto_tree_add_uint(tree,hf_afs_fs_acl_r, NullTVB,tmpoffset,acllen,acl);\
284                 proto_tree_add_uint(tree,hf_afs_fs_acl_l, NullTVB,tmpoffset,acllen,acl);\
285                 proto_tree_add_uint(tree,hf_afs_fs_acl_i, NullTVB,tmpoffset,acllen,acl);\
286                 proto_tree_add_uint(tree,hf_afs_fs_acl_d, NullTVB,tmpoffset,acllen,acl);\
287                 proto_tree_add_uint(tree,hf_afs_fs_acl_w, NullTVB,tmpoffset,acllen,acl);\
288                 proto_tree_add_uint(tree,hf_afs_fs_acl_k, NullTVB,tmpoffset,acllen,acl);\
289                 proto_tree_add_uint(tree,hf_afs_fs_acl_a, NullTVB,tmpoffset,acllen,acl);\
290                 tree = save; \
291         }
292
293 /* Skip a certain number of bytes */
294 #define SKIP(bytes) \
295         TRUNC(bytes) \
296         curoffset += bytes;
297
298 /* Raw data - to end of frame */
299 #define OUT_BYTES_ALL(field) OUT_BYTES(field, offset+END_OF_FRAME-curoffset)
300
301 /* Raw data */
302 #define OUT_BYTES(field, bytes) \
303         TRUNC(bytes); \
304         proto_tree_add_bytes(tree,field, NullTVB,curoffset,bytes,\
305                 (void *)&pd[curoffset]); \
306         curoffset += bytes;
307
308 /* Output a rx style string, up to a maximum length first 
309    4 bytes - length, then char data */
310 #define OUT_STRING(field) \
311         {       int i; \
312                 TRUNC(4); \
313                 i = pntohl(&pd[curoffset]); \
314                 curoffset += 4; \
315                 TRUNC(i); \
316                 if ( i > 0 ) { \
317                         proto_tree_add_string(tree, field, NullTVB, curoffset-4, i+4, \
318                         (void *)&pd[curoffset]); \
319                 } else { \
320                         proto_tree_add_string(tree, field, NullTVB, curoffset-4, 4, \
321                         ""); \
322                 } \
323                 curoffset += i; \
324         }
325
326 /* Output a fixed length vectorized string (each char is a 32 bit int) */
327 #define VECOUT(field, length) \
328         {       char tmp[length+1]; \
329                 int i,soff; \
330                 soff = curoffset;\
331                 TRUNC(length * sizeof(guint32));\
332                 for (i=0; i<length; i++)\
333                 {\
334                         tmp[i] = (char) GETINT();\
335                         curoffset += sizeof(guint32);\
336                 }\
337                 tmp[length] = '\0';\
338                 proto_tree_add_string(tree, field, NullTVB, soff, length, tmp);\
339         }
340
341 /* Skip the opcode */
342 #define SKIP_OPCODE() \
343         { \
344                 SKIP(sizeof(guint32)); \
345         }
346
347 /* Output a UBIK version code */
348 #define OUT_UBIKVERSION(label) \
349         {       proto_tree *save, *ti; \
350                 unsigned int epoch,counter; \
351                 struct timeval tv; \
352                 TRUNC(8); \
353                 epoch = GETINT(); \
354                 curoffset += 4; \
355                 counter = GETINT(); \
356                 curoffset += 4; \
357                 tv.tv_sec = epoch; \
358                 tv.tv_usec = 0; \
359                 ti = proto_tree_add_text(tree, NullTVB, curoffset, 3*4, \
360                         "UBIK Version (%s): %u.%u", label, epoch, counter ); \
361                 save = tree; \
362                 tree = proto_item_add_subtree(ti, ett_afs_ubikver); \
363                 proto_tree_add_time(tree,hf_afs_ubik_version_epoch, NullTVB,curoffset-8, \
364                         sizeof(guint32),&tv); \
365                 proto_tree_add_uint(tree,hf_afs_ubik_version_counter, NullTVB,curoffset-4, \
366                         sizeof(guint32),counter); \
367                 tree = save; \
368         }
369
370