WinPcap 2.1 allows you to capture on Token Ring, so remove the note
[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.7 2001/03/26 15:27:55 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         {       \
52                 proto_tree_add_text(tree, NullTVB,curoffset, \
53                         END_OF_FRAME,"Truncated"); \
54                 /* not sure why, but this didn't work */ \
55                 /* if (check_col(fd, COL_INFO)) */ \
56                         /* col_append_fstr(fd, COL_INFO, " (TRUNCATED)"); */ \
57                 return; \
58         } 
59
60 /* Output a unsigned integer, stored into field 'field'
61    Assumes it is in network byte order, converts to host before using */
62 #define OUT_UINT(field) \
63         TRUNC(sizeof(guint32)) \
64         proto_tree_add_uint(tree,field, NullTVB,curoffset,sizeof(guint32), GETINT()); \
65         curoffset += 4;
66
67 /* Output a unsigned integer, stored into field 'field'
68    Assumes it is in network byte order, converts to host before using */
69 #define OUT_INT(field) \
70         TRUNC(sizeof(guint32)) \
71         proto_tree_add_int(tree,field, NullTVB,curoffset,sizeof(gint32), GETINT()); \
72         curoffset += 4;
73         
74 /* Output a unsigned integer, stored into field 'field'
75    Assumes it is in network byte order, converts to host before using, 
76    Note - does not increment offset, so can be used repeatedly for bitfields */
77 #define DISP_UINT(field) \
78         TRUNC(sizeof(guint32)) \
79         proto_tree_add_uint(tree,field, NullTVB,curoffset,sizeof(guint32), GETINT()); 
80
81 /* Output an IPv4 address, stored into field 'field' */
82 #define OUT_IP(field) \
83         TRUNC(sizeof(gint32)) \
84         proto_tree_add_ipv4(tree,field, NullTVB,curoffset,sizeof(gint32),\
85                 *((int*)&pd[curoffset]));\
86         curoffset += 4;
87
88 /* Output a UNIX seconds/microseconds timestamp, after converting to a timeval */
89 #define OUT_TIMESTAMP(field) \
90         { struct timeval tv; \
91         TRUNC(2*sizeof(guint32)); \
92         tv.tv_sec = GETINT(); \
93         tv.tv_usec = GETINT(); \
94         proto_tree_add_time(tree,field, NullTVB,curoffset,2*sizeof(guint32),&tv); \
95         curoffset += 8; \
96         }
97
98 /* Output a UNIX seconds-only timestamp, after converting to a timeval */
99 #define OUT_DATE(field) \
100         { struct timeval tv; \
101         TRUNC(sizeof(guint32)); \
102         tv.tv_sec = GETINT(); \
103         tv.tv_usec = 0; \
104         proto_tree_add_time(tree,field, NullTVB,curoffset,sizeof(guint32),&tv); \
105         curoffset += 4; \
106         }
107
108 /* Output a callback */
109 #define OUT_FS_AFSCallBack() \
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_fs_callback_version); \
116                 OUT_DATE(hf_afs_fs_callback_expires); \
117                 OUT_UINT(hf_afs_fs_callback_type); \
118                 tree = save; \
119         }
120
121 /* Output a callback */
122 #define OUT_CB_AFSCallBack() \
123         {       proto_tree *save, *ti; \
124                 ti = proto_tree_add_text(tree, NullTVB, curoffset, 3*4, "Callback"); \
125                 save = tree; \
126                 tree = proto_item_add_subtree(ti, ett_afs_callback); \
127                 TRUNC(3*sizeof(guint32)); \
128                 OUT_UINT(hf_afs_cb_callback_version); \
129                 OUT_DATE(hf_afs_cb_callback_expires); \
130                 OUT_UINT(hf_afs_cb_callback_type); \
131                 tree = save; \
132         }
133
134
135 /* Output a File ID */
136 #define OUT_FS_AFSFid(label) \
137         {       proto_tree *save, *ti; \
138                 ti = proto_tree_add_text(tree, NullTVB, curoffset, 3*4, \
139                         "FileID (%s)", label); \
140                 save = tree; \
141                 tree = proto_item_add_subtree(ti, ett_afs_fid); \
142                 OUT_UINT(hf_afs_fs_fid_volume); \
143                 OUT_UINT(hf_afs_fs_fid_vnode); \
144                 OUT_UINT(hf_afs_fs_fid_uniqifier); \
145                 tree = save; \
146         }
147
148 /* Output a Status mask */
149 #define OUT_FS_STATUSMASK() \
150         {       proto_tree *save, *ti; \
151                 guint32 mask; \
152                 TRUNC(sizeof(guint32)); \
153                 mask = GETINT(); \
154                 ti = proto_tree_add_uint(tree, hf_afs_fs_status_mask, NullTVB, curoffset, \
155                         sizeof(guint32), mask); \
156                 save = tree; \
157                 tree = proto_item_add_subtree(ti, ett_afs_status_mask); \
158                 proto_tree_add_uint(tree, hf_afs_fs_status_mask_setmodtime, \
159                         NullTVB,curoffset,sizeof(guint32), mask); \
160                 proto_tree_add_uint(tree, hf_afs_fs_status_mask_setowner, \
161                         NullTVB,curoffset,sizeof(guint32), mask); \
162                 proto_tree_add_uint(tree, hf_afs_fs_status_mask_setgroup, \
163                         NullTVB,curoffset,sizeof(guint32), mask); \
164                 proto_tree_add_uint(tree, hf_afs_fs_status_mask_setmode, \
165                         NullTVB,curoffset,sizeof(guint32), mask); \
166                 proto_tree_add_uint(tree, hf_afs_fs_status_mask_setsegsize, \
167                         NullTVB,curoffset,sizeof(guint32), mask); \
168                 proto_tree_add_uint(tree, hf_afs_fs_status_mask_fsync, \
169                         NullTVB,curoffset,sizeof(guint32), mask); \
170                 curoffset += 4; \
171                 tree = save; \
172         }
173
174 /* Output a File ID */
175 #define OUT_CB_AFSFid(label) \
176         {       proto_tree *save, *ti; \
177                 ti = proto_tree_add_text(tree, NullTVB, curoffset, 3*4, \
178                         "FileID (%s)", label); \
179                 save = tree; \
180                 tree = proto_item_add_subtree(ti, ett_afs_fid); \
181                 OUT_UINT(hf_afs_cb_fid_volume); \
182                 OUT_UINT(hf_afs_cb_fid_vnode); \
183                 OUT_UINT(hf_afs_cb_fid_uniqifier); \
184                 tree = save; \
185         }
186         
187 /* Output a StoreStatus */
188 #define OUT_FS_AFSStoreStatus(label) \
189         {       proto_tree *save, *ti; \
190                 ti = proto_tree_add_text(tree, NullTVB, curoffset, 6*4, \
191                         label); \
192                 save = tree; \
193                 tree = proto_item_add_subtree(ti, ett_afs_status); \
194                 OUT_FS_STATUSMASK(); \
195                 OUT_DATE(hf_afs_fs_status_clientmodtime); \
196                 OUT_UINT(hf_afs_fs_status_owner); \
197                 OUT_UINT(hf_afs_fs_status_group); \
198                 OUT_UINT(hf_afs_fs_status_mode); \
199                 OUT_UINT(hf_afs_fs_status_segsize); \
200                 tree = save; \
201         }
202
203 /* Output a FetchStatus */
204 #define OUT_FS_AFSFetchStatus(label) \
205         {       proto_tree *save, *ti; \
206                 ti = proto_tree_add_text(tree, NullTVB, curoffset, 21*4, \
207                         label); \
208                 save = tree; \
209                 tree = proto_item_add_subtree(ti, ett_afs_status); \
210                 OUT_UINT(hf_afs_fs_status_interfaceversion); \
211                 OUT_UINT(hf_afs_fs_status_filetype); \
212                 OUT_UINT(hf_afs_fs_status_linkcount); \
213                 OUT_UINT(hf_afs_fs_status_length); \
214                 OUT_UINT(hf_afs_fs_status_dataversion); \
215                 OUT_UINT(hf_afs_fs_status_author); \
216                 OUT_UINT(hf_afs_fs_status_owner); \
217                 OUT_UINT(hf_afs_fs_status_calleraccess); \
218                 OUT_UINT(hf_afs_fs_status_anonymousaccess); \
219                 OUT_UINT(hf_afs_fs_status_mode); \
220                 OUT_UINT(hf_afs_fs_status_parentvnode); \
221                 OUT_UINT(hf_afs_fs_status_parentunique); \
222                 OUT_UINT(hf_afs_fs_status_segsize); \
223                 OUT_DATE(hf_afs_fs_status_clientmodtime); \
224                 OUT_DATE(hf_afs_fs_status_servermodtime); \
225                 OUT_UINT(hf_afs_fs_status_group); \
226                 OUT_UINT(hf_afs_fs_status_synccounter); \
227                 OUT_UINT(hf_afs_fs_status_dataversionhigh); \
228                 OUT_UINT(hf_afs_fs_status_spare2); \
229                 OUT_UINT(hf_afs_fs_status_spare3); \
230                 OUT_UINT(hf_afs_fs_status_spare4); \
231                 tree = save; \
232         }
233
234 /* Output a VolSync */
235 #define OUT_FS_AFSVolSync() \
236         {       proto_tree *save, *ti; \
237                 ti = proto_tree_add_text(tree, NullTVB, curoffset, 6*4, \
238                         "VolSync"); \
239                 save = tree; \
240                 tree = proto_item_add_subtree(ti, ett_afs_volsync); \
241                 OUT_UINT(hf_afs_fs_volsync_spare1); \
242                 OUT_UINT(hf_afs_fs_volsync_spare2); \
243                 OUT_UINT(hf_afs_fs_volsync_spare3); \
244                 OUT_UINT(hf_afs_fs_volsync_spare4); \
245                 OUT_UINT(hf_afs_fs_volsync_spare5); \
246                 OUT_UINT(hf_afs_fs_volsync_spare6); \
247                 tree = save; \
248         }
249
250 /* Output a AFSCBFids */
251 #define OUT_FS_AFSCBFids() \
252         { \
253                 unsigned int j,i; \
254                 TRUNC(1); \
255                 j = pntohl(&pd[curoffset]); \
256                 curoffset += 1; \
257                 for (i=0; i<j; i++) { \
258                         OUT_FS_AFSFid("Target"); \
259                 } \
260         }       
261
262 /* Output a ViceIds */
263 #define OUT_FS_ViceIds() \
264         { \
265                 unsigned int j,i; \
266                 TRUNC(1); \
267                 j = pntohl(&pd[curoffset]); \
268                 curoffset += 1; \
269                 for (i=0; i<j; i++) { \
270                         OUT_UINT(hf_afs_fs_viceid); \
271                 } \
272         }
273
274 /* Output a IPAddrs */
275 #define OUT_FS_IPAddrs() \
276         { \
277                 unsigned int j,i; \
278                 TRUNC(1); \
279                 j = pntohl(&pd[curoffset]); \
280                 curoffset += 1; \
281                 for (i=0; i<j; i++) { \
282                         OUT_IP(hf_afs_fs_ipaddr); \
283                 } \
284         }
285
286 /* Output a AFSCBs */
287 #define OUT_FS_AFSCBs() \
288         { \
289                 unsigned int j,i; \
290                 TRUNC(1); \
291                 j = pntohl(&pd[curoffset]); \
292                 curoffset += 1; \
293                 for (i=0; i<j; i++) { \
294                         OUT_FS_AFSCallBack(); \
295                 } \
296         }
297
298
299 /* Output a AFSBulkStats */
300 #define OUT_FS_AFSBulkStats() \
301         { \
302                 unsigned int j,i; \
303                 TRUNC(1); \
304                 j = pntohl(&pd[curoffset]); \
305                 curoffset += 1; \
306                 for (i=0; i<j; i++) { \
307                         OUT_FS_AFSFetchStatus("Status"); \
308                 } \
309         }
310
311 /* Output a AFSFetchVolumeStatus */
312 #define OUT_FS_AFSFetchVolumeStatus()
313
314 /* Output a AFSStoreVolumeStatus */
315 #define OUT_FS_AFSStoreVolumeStatus()
316
317 /* Output a ViceStatistics structure */
318 #define OUT_FS_ViceStatistics()
319
320 /* Output a AFS_CollData structure */
321 #define OUT_FS_AFS_CollData()
322
323 /* Output a VolumeInfo structure */
324 #define OUT_FS_VolumeInfo()
325
326 /* Output an AFS Token - might just be bytes though */
327 #define OUT_FS_AFSTOKEN() VECOUT(hf_afs_fs_token, 1024)
328
329 /* Output a AFS acl */
330 #define ACLOUT(who, positive, acl, bytes) \
331         {       proto_tree *save, *ti; \
332                 int tmpoffset; \
333                 int acllen; \
334                 char tmp[10]; \
335                 tmp[0] = 0; \
336                 if ( acl & PRSFS_READ ) strcat(tmp, "r"); \
337                 if ( acl & PRSFS_LOOKUP ) strcat(tmp, "l"); \
338                 if ( acl & PRSFS_INSERT ) strcat(tmp, "i"); \
339                 if ( acl & PRSFS_DELETE ) strcat(tmp, "d"); \
340                 if ( acl & PRSFS_WRITE ) strcat(tmp, "w"); \
341                 if ( acl & PRSFS_LOCK ) strcat(tmp, "k"); \
342                 if ( acl & PRSFS_ADMINISTER ) strcat(tmp, "a"); \
343                 ti = proto_tree_add_text(tree, NullTVB, curoffset, bytes, \
344                         "ACL:  %s %s%s", \
345                         who, tmp, positive ? "" : " (negative)"); \
346                 save = tree; \
347                 tree = proto_item_add_subtree(ti, ett_afs_acl); \
348                 proto_tree_add_string(tree,hf_afs_fs_acl_entity, NullTVB,curoffset,strlen(who), who);\
349                 tmpoffset = curoffset + strlen(who) + 1; \
350                 acllen = bytes - strlen(who) - 1; \
351                 proto_tree_add_uint(tree,hf_afs_fs_acl_r, NullTVB,tmpoffset,acllen,acl);\
352                 proto_tree_add_uint(tree,hf_afs_fs_acl_l, NullTVB,tmpoffset,acllen,acl);\
353                 proto_tree_add_uint(tree,hf_afs_fs_acl_i, NullTVB,tmpoffset,acllen,acl);\
354                 proto_tree_add_uint(tree,hf_afs_fs_acl_d, NullTVB,tmpoffset,acllen,acl);\
355                 proto_tree_add_uint(tree,hf_afs_fs_acl_w, NullTVB,tmpoffset,acllen,acl);\
356                 proto_tree_add_uint(tree,hf_afs_fs_acl_k, NullTVB,tmpoffset,acllen,acl);\
357                 proto_tree_add_uint(tree,hf_afs_fs_acl_a, NullTVB,tmpoffset,acllen,acl);\
358                 tree = save; \
359         }
360
361 /* output a bozo_key */
362 #define OUT_BOS_KEY() \
363         OUT_BYTES(hf_afs_bos_key, 8);
364
365 /* output a bozo_key */
366 #define OUT_BOS_KEYINFO() \
367         OUT_TIMESTAMP(hf_afs_bos_keymodtime); \
368         OUT_UINT(hf_afs_bos_keychecksum); \
369         OUT_UINT(hf_afs_bos_keyspare2);
370
371 /* output a bozo_netKTime */
372 #define OUT_BOS_TIME() \
373         SKIP(4); SKIP(2); SKIP(2); SKIP(2); SKIP(2);
374
375 /* output a bozo_status */
376 #define OUT_BOS_STATUS() \
377         SKIP(10 * 4);
378
379 /* output a ubik interface addr array */
380 #define OUT_UBIK_InterfaceAddrs() \
381     { \
382         unsigned int i,j,seen_null=0; \
383         for (i=0; i<255; i++) { \
384                         j = GETINT(); \
385                         if ( j != 0 ) { \
386                                 OUT_IP(hf_afs_ubik_interface); \
387                                 seen_null = 0; \
388                         } else { \
389                                 if ( ! seen_null ) { \
390                                 TRUNC(4); \
391                                 proto_tree_add_text(tree, NullTVB,curoffset,END_OF_FRAME, \
392                                         "Null Interface Addresses"); \
393                                         seen_null = 1; \
394                                 } \
395                                 curoffset += 4; \
396                         }\
397         } \
398     }
399
400 #define OUT_UBIK_DebugOld() \
401         { \
402                 OUT_DATE(hf_afs_ubik_now); \
403                 OUT_DATE(hf_afs_ubik_lastyestime); \
404                 OUT_IP(hf_afs_ubik_lastyeshost); \
405                 OUT_UINT(hf_afs_ubik_lastyesstate); \
406                 OUT_DATE(hf_afs_ubik_lastyesclaim); \
407                 OUT_IP(hf_afs_ubik_lowesthost); \
408                 OUT_DATE(hf_afs_ubik_lowesttime); \
409                 OUT_IP(hf_afs_ubik_synchost); \
410                 OUT_DATE(hf_afs_ubik_synctime); \
411                 OUT_UBIKVERSION("Sync Version"); \
412                 OUT_UBIKVERSION("Sync TID"); \
413                 OUT_UINT(hf_afs_ubik_amsyncsite); \
414                 OUT_DATE(hf_afs_ubik_syncsiteuntil); \
415                 OUT_UINT(hf_afs_ubik_nservers); \
416                 OUT_UINT(hf_afs_ubik_lockedpages); \
417                 OUT_UINT(hf_afs_ubik_writelockedpages); \
418                 OUT_UBIKVERSION("Local Version"); \
419                 OUT_UINT(hf_afs_ubik_activewrite); \
420                 OUT_UINT(hf_afs_ubik_tidcounter); \
421                 OUT_UINT(hf_afs_ubik_anyreadlocks); \
422                 OUT_UINT(hf_afs_ubik_anywritelocks); \
423                 OUT_UINT(hf_afs_ubik_recoverystate); \
424                 OUT_UINT(hf_afs_ubik_currenttrans); \
425                 OUT_UINT(hf_afs_ubik_writetrans); \
426                 OUT_DATE(hf_afs_ubik_epochtime); \
427         }
428
429 #define OUT_UBIK_SDebugOld() \
430         { \
431                 OUT_IP(hf_afs_ubik_addr); \
432                 OUT_DATE(hf_afs_ubik_lastvotetime); \
433                 OUT_DATE(hf_afs_ubik_lastbeaconsent); \
434                 OUT_UINT(hf_afs_ubik_lastvote); \
435                 OUT_UBIKVERSION("Remote Version"); \
436                 OUT_UINT(hf_afs_ubik_currentdb); \
437                 OUT_UINT(hf_afs_ubik_beaconsincedown); \
438                 OUT_UINT(hf_afs_ubik_up); \
439         }
440
441 /* Skip a certain number of bytes */
442 #define SKIP(bytes) \
443         TRUNC(bytes) \
444         curoffset += bytes;
445         
446 /* Raw data - to end of frame */
447 #define OUT_BYTES_ALL(field) OUT_BYTES(field, offset+END_OF_FRAME-curoffset)
448
449 /* Raw data */
450 #define OUT_BYTES(field, bytes) \
451         TRUNC(bytes); \
452         proto_tree_add_bytes(tree,field, NullTVB,curoffset,bytes,\
453                 (void *)&pd[curoffset]); \
454         curoffset += bytes;
455
456 /* Output a rx style string, up to a maximum length first 
457    4 bytes - length, then char data */
458 #define OUT_STRING(field) \
459         {       int i; \
460                 TRUNC(4); \
461                 i = GETINT(); \
462                 curoffset += 4; \
463                 if ( i > 0 ) { \
464                         char *tmp; \
465                         TRUNC(i); \
466                         tmp = g_malloc(i+1); \
467                         memcpy(tmp, &pd[curoffset], i); \
468                         tmp[i] = '\0'; \
469                         proto_tree_add_string(tree, field, NullTVB, curoffset-4, i+4, \
470                         (void *)tmp); \
471                         g_free(tmp); \
472                 } else { \
473                         proto_tree_add_string(tree, field, NullTVB, curoffset-4, 4, \
474                         ""); \
475                 } \
476                 curoffset += i; \
477         }
478
479 /* Output a fixed length vectorized string (each char is a 32 bit int) */
480 #define VECOUT(field, length) \
481         {       char tmp[length+1]; \
482                 int i,soff; \
483                 soff = curoffset;\
484                 TRUNC(length * sizeof(guint32));\
485                 for (i=0; i<length; i++)\
486                 {\
487                         tmp[i] = (char) GETINT();\
488                         curoffset += sizeof(guint32);\
489                 }\
490                 tmp[length] = '\0';\
491                 proto_tree_add_string(tree, field, NullTVB, soff, length, tmp);\
492         }
493
494 /* Skip the opcode */
495 #define SKIP_OPCODE() \
496         { \
497                 SKIP(sizeof(guint32)); \
498         }
499
500 /* Output a UBIK version code */
501 #define OUT_UBIKVERSION(label) \
502         {       proto_tree *save, *ti; \
503                 unsigned int epoch,counter; \
504                 struct timeval tv; \
505                 TRUNC(8); \
506                 epoch = GETINT(); \
507                 curoffset += 4; \
508                 counter = GETINT(); \
509                 curoffset += 4; \
510                 tv.tv_sec = epoch; \
511                 tv.tv_usec = 0; \
512                 ti = proto_tree_add_text(tree, NullTVB, curoffset-8, 8, \
513                         "UBIK Version (%s): %u.%u", label, epoch, counter ); \
514                 save = tree; \
515                 tree = proto_item_add_subtree(ti, ett_afs_ubikver); \
516                 if ( epoch != 0 ) \
517                 proto_tree_add_time(tree,hf_afs_ubik_version_epoch, NullTVB,curoffset-8, \
518                         sizeof(guint32),&tv); \
519                 else \
520                         proto_tree_add_text(tree, NullTVB, curoffset-8, \
521                         sizeof(guint32),"Epoch: 0"); \
522                 proto_tree_add_uint(tree,hf_afs_ubik_version_counter, NullTVB,curoffset-4, \
523                         sizeof(guint32),counter); \
524                 tree = save; \
525         }
526
527