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