diff options
author | Guy Harris <guy@alum.mit.edu> | 2001-05-27 01:48:25 +0000 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2001-05-27 01:48:25 +0000 |
commit | d2ef0cf51afeae48d891f3d352434aeee55ccc42 (patch) | |
tree | 068f0b1cf236d105eff7f2e8b63852acdeb28bbf | |
parent | b2cbb503a339799691cdd43c60ce34652e59f248 (diff) | |
download | wireshark-d2ef0cf51afeae48d891f3d352434aeee55ccc42.tar.gz wireshark-d2ef0cf51afeae48d891f3d352434aeee55ccc42.tar.bz2 wireshark-d2ef0cf51afeae48d891f3d352434aeee55ccc42.zip |
RX and AFS dissectors tvbuffified, and bugs fixed, by Ronnie Sahlberg.
svn path=/trunk/; revision=3454
-rw-r--r-- | AUTHORS | 1 | ||||
-rw-r--r-- | epan/packet_info.h | 11 | ||||
-rw-r--r-- | packet-afs-macros.h | 194 | ||||
-rw-r--r-- | packet-afs.c | 629 | ||||
-rw-r--r-- | packet-afs.h | 4 | ||||
-rw-r--r-- | packet-rx.c | 578 | ||||
-rw-r--r-- | packet-rx.h | 33 |
7 files changed, 834 insertions, 616 deletions
@@ -516,6 +516,7 @@ Ronnie Sahlberg <rsahlber@bigpond.net.au> { XDR array support NIS+ support Rewritten IGMP dissector + Tvbuffified and bug-fixed RX and AFS dissectors } Borosa Tomislav <tomislav.borosa@SIEMENS.HR> { diff --git a/epan/packet_info.h b/epan/packet_info.h index ac07e34ddc..cb4466e9c3 100644 --- a/epan/packet_info.h +++ b/epan/packet_info.h @@ -1,7 +1,7 @@ /* packet_info.h * Definitions for packet info structures and routines * - * $Id: packet_info.h,v 1.1 2001/04/01 04:50:42 hagbard Exp $ + * $Id: packet_info.h,v 1.2 2001/05/27 01:48:25 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@zing.org> @@ -92,6 +92,15 @@ typedef struct _packet_info { int iplen; int iphdrlen; int p2p_dir; + union { + struct { + guint8 type; + guint8 flags; + guint16 serviceid; + guint32 callnumber; + guint32 seq; + } rx; /* fields specific for RX protocol */ + } ps; /* protocol specific data */ } packet_info; void blank_packetinfo(void); diff --git a/packet-afs-macros.h b/packet-afs-macros.h index e9c50afaa5..bdb17c6c7c 100644 --- a/packet-afs-macros.h +++ b/packet-afs-macros.h @@ -8,7 +8,7 @@ * Portions based on information/specs retrieved from the OpenAFS sources at * www.openafs.org, Copyright IBM. * - * $Id: packet-afs-macros.h,v 1.7 2001/03/26 15:27:55 nneul Exp $ + * $Id: packet-afs-macros.h,v 1.8 2001/05/27 01:48:23 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@zing.org> @@ -37,81 +37,59 @@ * Macros for helper dissection routines * * The macros are here to save on coding. They assume that - * the current offset is in 'curoffset', and that the offset + * the current offset is in 'offset', and that the offset * should be incremented after performing the macro's operation. */ -/* Get the next available integer, be sure and call TRUNC beforehand */ -#define GETINT() (pntohl(&pd[curoffset])) - -/* Check if enough bytes are present, if not, return to caller - after adding a 'Truncated' message to tree */ -#define TRUNC(bytes) \ - if(!BYTES_ARE_IN_FRAME(curoffset,(bytes))) \ - { \ - proto_tree_add_text(tree, NullTVB,curoffset, \ - END_OF_FRAME,"Truncated"); \ - /* not sure why, but this didn't work */ \ - /* if (check_col(fd, COL_INFO)) */ \ - /* col_append_fstr(fd, COL_INFO, " (TRUNCATED)"); */ \ - return; \ - } /* Output a unsigned integer, stored into field 'field' Assumes it is in network byte order, converts to host before using */ #define OUT_UINT(field) \ - TRUNC(sizeof(guint32)) \ - proto_tree_add_uint(tree,field, NullTVB,curoffset,sizeof(guint32), GETINT()); \ - curoffset += 4; + proto_tree_add_uint(tree, field, tvb, offset, sizeof(guint32), tvb_get_ntohl(tvb, offset)); \ + offset += 4; /* Output a unsigned integer, stored into field 'field' Assumes it is in network byte order, converts to host before using */ #define OUT_INT(field) \ - TRUNC(sizeof(guint32)) \ - proto_tree_add_int(tree,field, NullTVB,curoffset,sizeof(gint32), GETINT()); \ - curoffset += 4; + proto_tree_add_int(tree, field, tvb, offset, sizeof(gint32), tvb_get_ntohl(tvb, offset)); \ + offset += 4; /* Output a unsigned integer, stored into field 'field' Assumes it is in network byte order, converts to host before using, Note - does not increment offset, so can be used repeatedly for bitfields */ #define DISP_UINT(field) \ - TRUNC(sizeof(guint32)) \ - proto_tree_add_uint(tree,field, NullTVB,curoffset,sizeof(guint32), GETINT()); + proto_tree_add_uint(tree,field,tvb,offset,sizeof(guint32),tvb_get_ntohl(tvb, offset)); /* Output an IPv4 address, stored into field 'field' */ #define OUT_IP(field) \ - TRUNC(sizeof(gint32)) \ - proto_tree_add_ipv4(tree,field, NullTVB,curoffset,sizeof(gint32),\ - *((int*)&pd[curoffset]));\ - curoffset += 4; + proto_tree_add_ipv4(tree,field,tvb,offset,sizeof(gint32),\ + tvb_get_letohl(tvb, offset));\ + offset += 4; /* Output a UNIX seconds/microseconds timestamp, after converting to a timeval */ #define OUT_TIMESTAMP(field) \ { struct timeval tv; \ - TRUNC(2*sizeof(guint32)); \ - tv.tv_sec = GETINT(); \ - tv.tv_usec = GETINT(); \ - proto_tree_add_time(tree,field, NullTVB,curoffset,2*sizeof(guint32),&tv); \ - curoffset += 8; \ + tv.tv_sec = tvb_get_ntohl(tvb, offset); \ + tv.tv_usec = tvb_get_ntohl(tvb, offset); \ + proto_tree_add_time(tree,field, tvb,offset,2*sizeof(guint32),&tv); \ + offset += 8; \ } /* Output a UNIX seconds-only timestamp, after converting to a timeval */ #define OUT_DATE(field) \ { struct timeval tv; \ - TRUNC(sizeof(guint32)); \ - tv.tv_sec = GETINT(); \ + tv.tv_sec = tvb_get_ntohl(tvb, offset); \ tv.tv_usec = 0; \ - proto_tree_add_time(tree,field, NullTVB,curoffset,sizeof(guint32),&tv); \ - curoffset += 4; \ + proto_tree_add_time(tree,field, tvb,offset,sizeof(guint32),&tv); \ + offset += 4; \ } /* Output a callback */ #define OUT_FS_AFSCallBack() \ { proto_tree *save, *ti; \ - ti = proto_tree_add_text(tree, NullTVB, curoffset, 3*4, "Callback"); \ + ti = proto_tree_add_text(tree, tvb, offset, 3*4, "Callback"); \ save = tree; \ tree = proto_item_add_subtree(ti, ett_afs_callback); \ - TRUNC(3*sizeof(guint32)); \ OUT_UINT(hf_afs_fs_callback_version); \ OUT_DATE(hf_afs_fs_callback_expires); \ OUT_UINT(hf_afs_fs_callback_type); \ @@ -121,10 +99,9 @@ /* Output a callback */ #define OUT_CB_AFSCallBack() \ { proto_tree *save, *ti; \ - ti = proto_tree_add_text(tree, NullTVB, curoffset, 3*4, "Callback"); \ + ti = proto_tree_add_text(tree, tvb, offset, 3*4, "Callback"); \ save = tree; \ tree = proto_item_add_subtree(ti, ett_afs_callback); \ - TRUNC(3*sizeof(guint32)); \ OUT_UINT(hf_afs_cb_callback_version); \ OUT_DATE(hf_afs_cb_callback_expires); \ OUT_UINT(hf_afs_cb_callback_type); \ @@ -135,7 +112,7 @@ /* Output a File ID */ #define OUT_FS_AFSFid(label) \ { proto_tree *save, *ti; \ - ti = proto_tree_add_text(tree, NullTVB, curoffset, 3*4, \ + ti = proto_tree_add_text(tree, tvb, offset, 3*4, \ "FileID (%s)", label); \ save = tree; \ tree = proto_item_add_subtree(ti, ett_afs_fid); \ @@ -149,32 +126,31 @@ #define OUT_FS_STATUSMASK() \ { proto_tree *save, *ti; \ guint32 mask; \ - TRUNC(sizeof(guint32)); \ - mask = GETINT(); \ - ti = proto_tree_add_uint(tree, hf_afs_fs_status_mask, NullTVB, curoffset, \ + mask = tvb_get_ntohl(tvb, offset); \ + ti = proto_tree_add_uint(tree, hf_afs_fs_status_mask, tvb, offset, \ sizeof(guint32), mask); \ save = tree; \ tree = proto_item_add_subtree(ti, ett_afs_status_mask); \ proto_tree_add_uint(tree, hf_afs_fs_status_mask_setmodtime, \ - NullTVB,curoffset,sizeof(guint32), mask); \ + tvb,offset,sizeof(guint32), mask); \ proto_tree_add_uint(tree, hf_afs_fs_status_mask_setowner, \ - NullTVB,curoffset,sizeof(guint32), mask); \ + tvb,offset,sizeof(guint32), mask); \ proto_tree_add_uint(tree, hf_afs_fs_status_mask_setgroup, \ - NullTVB,curoffset,sizeof(guint32), mask); \ + tvb,offset,sizeof(guint32), mask); \ proto_tree_add_uint(tree, hf_afs_fs_status_mask_setmode, \ - NullTVB,curoffset,sizeof(guint32), mask); \ + tvb,offset,sizeof(guint32), mask); \ proto_tree_add_uint(tree, hf_afs_fs_status_mask_setsegsize, \ - NullTVB,curoffset,sizeof(guint32), mask); \ + tvb,offset,sizeof(guint32), mask); \ proto_tree_add_uint(tree, hf_afs_fs_status_mask_fsync, \ - NullTVB,curoffset,sizeof(guint32), mask); \ - curoffset += 4; \ + tvb,offset,sizeof(guint32), mask); \ + offset += 4; \ tree = save; \ } /* Output a File ID */ #define OUT_CB_AFSFid(label) \ { proto_tree *save, *ti; \ - ti = proto_tree_add_text(tree, NullTVB, curoffset, 3*4, \ + ti = proto_tree_add_text(tree, tvb, offset, 3*4, \ "FileID (%s)", label); \ save = tree; \ tree = proto_item_add_subtree(ti, ett_afs_fid); \ @@ -187,7 +163,7 @@ /* Output a StoreStatus */ #define OUT_FS_AFSStoreStatus(label) \ { proto_tree *save, *ti; \ - ti = proto_tree_add_text(tree, NullTVB, curoffset, 6*4, \ + ti = proto_tree_add_text(tree, tvb, offset, 6*4, \ label); \ save = tree; \ tree = proto_item_add_subtree(ti, ett_afs_status); \ @@ -203,7 +179,7 @@ /* Output a FetchStatus */ #define OUT_FS_AFSFetchStatus(label) \ { proto_tree *save, *ti; \ - ti = proto_tree_add_text(tree, NullTVB, curoffset, 21*4, \ + ti = proto_tree_add_text(tree, tvb, offset, 21*4, \ label); \ save = tree; \ tree = proto_item_add_subtree(ti, ett_afs_status); \ @@ -234,7 +210,7 @@ /* Output a VolSync */ #define OUT_FS_AFSVolSync() \ { proto_tree *save, *ti; \ - ti = proto_tree_add_text(tree, NullTVB, curoffset, 6*4, \ + ti = proto_tree_add_text(tree, tvb, offset, 6*4, \ "VolSync"); \ save = tree; \ tree = proto_item_add_subtree(ti, ett_afs_volsync); \ @@ -251,9 +227,8 @@ #define OUT_FS_AFSCBFids() \ { \ unsigned int j,i; \ - TRUNC(1); \ - j = pntohl(&pd[curoffset]); \ - curoffset += 1; \ + j = tvb_get_guint8(tvb, offset); \ + offset += 1; \ for (i=0; i<j; i++) { \ OUT_FS_AFSFid("Target"); \ } \ @@ -263,9 +238,8 @@ #define OUT_FS_ViceIds() \ { \ unsigned int j,i; \ - TRUNC(1); \ - j = pntohl(&pd[curoffset]); \ - curoffset += 1; \ + j = tvb_get_guint8(tvb,offset); \ + offset += 1; \ for (i=0; i<j; i++) { \ OUT_UINT(hf_afs_fs_viceid); \ } \ @@ -275,9 +249,8 @@ #define OUT_FS_IPAddrs() \ { \ unsigned int j,i; \ - TRUNC(1); \ - j = pntohl(&pd[curoffset]); \ - curoffset += 1; \ + j = tvb_get_guint8(tvb, offset); \ + offset += 1; \ for (i=0; i<j; i++) { \ OUT_IP(hf_afs_fs_ipaddr); \ } \ @@ -287,9 +260,8 @@ #define OUT_FS_AFSCBs() \ { \ unsigned int j,i; \ - TRUNC(1); \ - j = pntohl(&pd[curoffset]); \ - curoffset += 1; \ + j = tvb_get_guint8(tvb,offset); \ + offset += 1; \ for (i=0; i<j; i++) { \ OUT_FS_AFSCallBack(); \ } \ @@ -300,9 +272,8 @@ #define OUT_FS_AFSBulkStats() \ { \ unsigned int j,i; \ - TRUNC(1); \ - j = pntohl(&pd[curoffset]); \ - curoffset += 1; \ + j = tvb_get_guint8(tvb,offset); \ + offset += 1; \ for (i=0; i<j; i++) { \ OUT_FS_AFSFetchStatus("Status"); \ } \ @@ -340,21 +311,21 @@ if ( acl & PRSFS_WRITE ) strcat(tmp, "w"); \ if ( acl & PRSFS_LOCK ) strcat(tmp, "k"); \ if ( acl & PRSFS_ADMINISTER ) strcat(tmp, "a"); \ - ti = proto_tree_add_text(tree, NullTVB, curoffset, bytes, \ + ti = proto_tree_add_text(tree, tvb, offset, bytes, \ "ACL: %s %s%s", \ who, tmp, positive ? "" : " (negative)"); \ save = tree; \ tree = proto_item_add_subtree(ti, ett_afs_acl); \ - proto_tree_add_string(tree,hf_afs_fs_acl_entity, NullTVB,curoffset,strlen(who), who);\ - tmpoffset = curoffset + strlen(who) + 1; \ + proto_tree_add_string(tree,hf_afs_fs_acl_entity, tvb,offset,strlen(who), who);\ + tmpoffset = offset + strlen(who) + 1; \ acllen = bytes - strlen(who) - 1; \ - proto_tree_add_uint(tree,hf_afs_fs_acl_r, NullTVB,tmpoffset,acllen,acl);\ - proto_tree_add_uint(tree,hf_afs_fs_acl_l, NullTVB,tmpoffset,acllen,acl);\ - proto_tree_add_uint(tree,hf_afs_fs_acl_i, NullTVB,tmpoffset,acllen,acl);\ - proto_tree_add_uint(tree,hf_afs_fs_acl_d, NullTVB,tmpoffset,acllen,acl);\ - proto_tree_add_uint(tree,hf_afs_fs_acl_w, NullTVB,tmpoffset,acllen,acl);\ - proto_tree_add_uint(tree,hf_afs_fs_acl_k, NullTVB,tmpoffset,acllen,acl);\ - proto_tree_add_uint(tree,hf_afs_fs_acl_a, NullTVB,tmpoffset,acllen,acl);\ + proto_tree_add_uint(tree,hf_afs_fs_acl_r, tvb,tmpoffset,acllen,acl);\ + proto_tree_add_uint(tree,hf_afs_fs_acl_l, tvb,tmpoffset,acllen,acl);\ + proto_tree_add_uint(tree,hf_afs_fs_acl_i, tvb,tmpoffset,acllen,acl);\ + proto_tree_add_uint(tree,hf_afs_fs_acl_d, tvb,tmpoffset,acllen,acl);\ + proto_tree_add_uint(tree,hf_afs_fs_acl_w, tvb,tmpoffset,acllen,acl);\ + proto_tree_add_uint(tree,hf_afs_fs_acl_k, tvb,tmpoffset,acllen,acl);\ + proto_tree_add_uint(tree,hf_afs_fs_acl_a, tvb,tmpoffset,acllen,acl);\ tree = save; \ } @@ -381,18 +352,17 @@ { \ unsigned int i,j,seen_null=0; \ for (i=0; i<255; i++) { \ - j = GETINT(); \ + j = tvb_get_ntohl(tvb, offset); \ if ( j != 0 ) { \ OUT_IP(hf_afs_ubik_interface); \ seen_null = 0; \ } else { \ if ( ! seen_null ) { \ - TRUNC(4); \ - proto_tree_add_text(tree, NullTVB,curoffset,END_OF_FRAME, \ + proto_tree_add_text(tree, tvb,offset,END_OF_FRAME, \ "Null Interface Addresses"); \ seen_null = 1; \ } \ - curoffset += 4; \ + offset += 4; \ }\ } \ } @@ -440,55 +410,50 @@ /* Skip a certain number of bytes */ #define SKIP(bytes) \ - TRUNC(bytes) \ - curoffset += bytes; + offset += bytes; /* Raw data - to end of frame */ -#define OUT_BYTES_ALL(field) OUT_BYTES(field, offset+END_OF_FRAME-curoffset) +#define OUT_BYTES_ALL(field) OUT_BYTES(field, tvb_length_remaining(tvb,offset)) /* Raw data */ #define OUT_BYTES(field, bytes) \ - TRUNC(bytes); \ - proto_tree_add_bytes(tree,field, NullTVB,curoffset,bytes,\ - (void *)&pd[curoffset]); \ - curoffset += bytes; + proto_tree_add_bytes(tree,field, tvb,offset,bytes,\ + tvb_get_ptr(tvb,offset,bytes)); \ + offset += bytes; /* Output a rx style string, up to a maximum length first 4 bytes - length, then char data */ #define OUT_STRING(field) \ { int i; \ - TRUNC(4); \ - i = GETINT(); \ - curoffset += 4; \ + i = tvb_get_ntohl(tvb, offset); \ + offset += 4; \ if ( i > 0 ) { \ char *tmp; \ - TRUNC(i); \ tmp = g_malloc(i+1); \ - memcpy(tmp, &pd[curoffset], i); \ + memcpy(tmp, tvb_get_ptr(tvb,offset,i), i); \ tmp[i] = '\0'; \ - proto_tree_add_string(tree, field, NullTVB, curoffset-4, i+4, \ + proto_tree_add_string(tree, field, tvb, offset-4, i+4, \ (void *)tmp); \ g_free(tmp); \ } else { \ - proto_tree_add_string(tree, field, NullTVB, curoffset-4, 4, \ + proto_tree_add_string(tree, field, tvb, offset-4, 4, \ ""); \ } \ - curoffset += i; \ + offset += i; \ } /* Output a fixed length vectorized string (each char is a 32 bit int) */ #define VECOUT(field, length) \ { char tmp[length+1]; \ int i,soff; \ - soff = curoffset;\ - TRUNC(length * sizeof(guint32));\ + soff = offset;\ for (i=0; i<length; i++)\ {\ - tmp[i] = (char) GETINT();\ - curoffset += sizeof(guint32);\ + tmp[i] = (char) tvb_get_ntohl(tvb, offset);\ + offset += sizeof(guint32);\ }\ tmp[length] = '\0';\ - proto_tree_add_string(tree, field, NullTVB, soff, length, tmp);\ + proto_tree_add_string(tree, field, tvb, soff, length, tmp);\ } /* Skip the opcode */ @@ -502,24 +467,23 @@ { proto_tree *save, *ti; \ unsigned int epoch,counter; \ struct timeval tv; \ - TRUNC(8); \ - epoch = GETINT(); \ - curoffset += 4; \ - counter = GETINT(); \ - curoffset += 4; \ + epoch = tvb_get_ntohl(tvb, offset); \ + offset += 4; \ + counter = tvb_get_ntohl(tvb, offset); \ + offset += 4; \ tv.tv_sec = epoch; \ tv.tv_usec = 0; \ - ti = proto_tree_add_text(tree, NullTVB, curoffset-8, 8, \ + ti = proto_tree_add_text(tree, tvb, offset-8, 8, \ "UBIK Version (%s): %u.%u", label, epoch, counter ); \ save = tree; \ tree = proto_item_add_subtree(ti, ett_afs_ubikver); \ if ( epoch != 0 ) \ - proto_tree_add_time(tree,hf_afs_ubik_version_epoch, NullTVB,curoffset-8, \ + proto_tree_add_time(tree,hf_afs_ubik_version_epoch, tvb,offset-8, \ sizeof(guint32),&tv); \ else \ - proto_tree_add_text(tree, NullTVB, curoffset-8, \ + proto_tree_add_text(tree, tvb, offset-8, \ sizeof(guint32),"Epoch: 0"); \ - proto_tree_add_uint(tree,hf_afs_ubik_version_counter, NullTVB,curoffset-4, \ + proto_tree_add_uint(tree,hf_afs_ubik_version_counter, tvb,offset-4, \ sizeof(guint32),counter); \ tree = save; \ } diff --git a/packet-afs.c b/packet-afs.c index 60bb217fe8..2881bf0ee2 100644 --- a/packet-afs.c +++ b/packet-afs.c @@ -8,7 +8,7 @@ * Portions based on information/specs retrieved from the OpenAFS sources at * www.openafs.org, Copyright IBM. * - * $Id: packet-afs.c,v 1.29 2001/04/02 19:10:06 nneul Exp $ + * $Id: packet-afs.c,v 1.30 2001/05/27 01:48:23 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@zing.org> @@ -56,6 +56,8 @@ #include "packet-afs-defs.h" #include "packet-afs-macros.h" +#define GETSTR tvb_get_ptr(tvb,offset,tvb_length_remaining(tvb,offset)) + #define VALID_OPCODE(opcode) ((opcode >= OPCODE_LOW && opcode <= OPCODE_HIGH) || \ (opcode >= VOTE_LOW && opcode <= VOTE_HIGH) || \ (opcode >= DISK_LOW && opcode <= DISK_HIGH)) @@ -80,43 +82,44 @@ GMemChunk *afs_request_vals = NULL; /* * Dissector prototypes */ -static void dissect_fs_request(const u_char *pd, - int offset, frame_data *fd, proto_tree *tree, int opcode); -static void dissect_fs_reply(const u_char *pd, - int offset, frame_data *fd, proto_tree *tree, int opcode); -static void dissect_cb_request(const u_char *pd, - int offset, frame_data *fd, proto_tree *tree, int opcode); -static void dissect_cb_reply(const u_char *pd, - int offset, frame_data *fd, proto_tree *tree, int opcode); -static void dissect_bos_request(const u_char *pd, - int offset, frame_data *fd, proto_tree *tree, int opcode); -static void dissect_bos_reply(const u_char *pd, - int offset, frame_data *fd, proto_tree *tree, int opcode); -static void dissect_vol_request(const u_char *pd, - int offset, frame_data *fd, proto_tree *tree, int opcode); -static void dissect_vol_reply(const u_char *pd, - int offset, frame_data *fd, proto_tree *tree, int opcode); -static void dissect_ubik_request(const u_char *pd, - int offset, frame_data *fd, proto_tree *tree, int opcode); -static void dissect_ubik_reply(const u_char *pd, - int offset, frame_data *fd, proto_tree *tree, int opcode); -static void dissect_kauth_request(const u_char *pd, - int offset, frame_data *fd, proto_tree *tree, int opcode); -static void dissect_kauth_reply(const u_char *pd, - int offset, frame_data *fd, proto_tree *tree, int opcode); -static void dissect_prot_request(const u_char *pd, - int offset, frame_data *fd, proto_tree *tree, int opcode); -static void dissect_prot_reply(const u_char *pd, - int offset, frame_data *fd, proto_tree *tree, int opcode); -static void dissect_vldb_request(const u_char *pd, - int offset, frame_data *fd, proto_tree *tree, int opcode); -static void dissect_vldb_reply(const u_char *pd, - int offset, frame_data *fd, proto_tree *tree, int opcode); -static void dissect_backup_request(const u_char *pd, - int offset, frame_data *fd, proto_tree *tree, int opcode); -static void dissect_backup_reply(const u_char *pd, - int offset, frame_data *fd, proto_tree *tree, int opcode); - +static int dissect_acl(tvbuff_t *tvb, packet_info *pinfo, + proto_tree *tree, int offset); +static void dissect_fs_reply(tvbuff_t *tvb, packet_info *pinfo, + proto_tree *tree, int offset, int opcode); +static void dissect_fs_request(tvbuff_t *tvb, packet_info *pinfo, + proto_tree *tree, int offset, int opcode); +static void dissect_bos_reply(tvbuff_t *tvb, packet_info *pinfo, + proto_tree *tree, int offset, int opcode); +static void dissect_bos_request(tvbuff_t *tvb, packet_info *pinfo, + proto_tree *tree, int offset, int opcode); +static void dissect_vol_reply(tvbuff_t *tvb, packet_info *pinfo, + proto_tree *tree, int offset, int opcode); +static void dissect_vol_request(tvbuff_t *tvb, packet_info *pinfo, + proto_tree *tree, int offset, int opcode); +static void dissect_kauth_reply(tvbuff_t *tvb, packet_info *pinfo, + proto_tree *tree, int offset, int opcode); +static void dissect_kauth_request(tvbuff_t *tvb, packet_info *pinfo, + proto_tree *tree, int offset, int opcode); +static void dissect_cb_reply(tvbuff_t *tvb, packet_info *pinfo, + proto_tree *tree, int offset, int opcode); +static void dissect_cb_request(tvbuff_t *tvb, packet_info *pinfo, + proto_tree *tree, int offset, int opcode); +static void dissect_prot_reply(tvbuff_t *tvb, packet_info *pinfo, + proto_tree *tree, int offset, int opcode); +static void dissect_prot_request(tvbuff_t *tvb, packet_info *pinfo, + proto_tree *tree, int offset, int opcode); +static void dissect_vldb_reply(tvbuff_t *tvb, packet_info *pinfo, + proto_tree *tree, int offset, int opcode); +static void dissect_vldb_request(tvbuff_t *tvb, packet_info *pinfo, + proto_tree *tree, int offset, int opcode); +static void dissect_ubik_reply(tvbuff_t *tvb, packet_info *pinfo, + proto_tree *tree, int offset, int opcode); +static void dissect_ubik_request(tvbuff_t *tvb, packet_info *pinfo, + proto_tree *tree, int offset, int opcode); +static void dissect_backup_reply(tvbuff_t *tvb, packet_info *pinfo, + proto_tree *tree, int offset, int opcode); +static void dissect_backup_request(tvbuff_t *tvb, packet_info *pinfo, + proto_tree *tree, int offset, int opcode); /* * Hash Functions @@ -179,36 +182,28 @@ afs_init_protocol(void) */ void -dissect_afs(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) +dissect_afs(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { - proto_tree *afs_tree, *afs_op_tree, *ti; - struct rx_header *rxh; - struct afs_header *afsh; - int port, node, typenode, opcode; - value_string const *vals; int reply = 0; - int doffset = 0; conversation_t *conversation; struct afs_request_key request_key, *new_request_key; struct afs_request_val *request_val; - void (*dissector)(const u_char *pd, int offset, - frame_data *fd, proto_tree *tree, int opcode); - - OLD_CHECK_DISPLAY_AS_DATA(proto_afs, pd, offset, fd, tree); - - /* get at least a full packet structure */ - if ( !BYTES_ARE_IN_FRAME(offset, sizeof(struct rx_header)) ) - return; + proto_tree *afs_tree, *afs_op_tree, *ti; + int port, node, typenode, opcode; + value_string const *vals; + int offset = 0; + void (*dissector)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int opcode); - if (check_col(fd, COL_PROTOCOL)) - col_set_str(fd, COL_PROTOCOL, "AFS (RX)"); - rxh = (struct rx_header *) &pd[offset]; - doffset = offset + sizeof(struct rx_header); - afsh = (struct afs_header *) &pd[doffset]; + if (check_col(pinfo->fd, COL_PROTOCOL)) { + col_set_str(pinfo->fd, COL_PROTOCOL, "AFS (RX)"); + } + if (check_col(pinfo->fd, COL_INFO)) { + col_clear(pinfo->fd, COL_INFO); + } - reply = (rxh->flags & RX_CLIENT_INITIATED) == 0; - port = ((reply == 0) ? pi.destport : pi.srcport ); + reply = (pinfo->ps.rx.flags & RX_CLIENT_INITIATED) == 0; + port = ((reply == 0) ? pinfo->destport : pinfo->srcport ); /* * Find out what conversation this packet is part of. @@ -223,37 +218,35 @@ dissect_afs(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) * packets from A:X to B:Y as being part of the same conversation as * packets from B:Y to A:X. */ - conversation = find_conversation(&pi.src, &pi.dst, pi.ptype, - pi.srcport, pi.destport, 0); + conversation = find_conversation(&pinfo->src, &pinfo->dst, pinfo->ptype, + pinfo->srcport, pinfo->destport, 0); if (conversation == NULL) { /* It's not part of any conversation - create a new one. */ - conversation = conversation_new(&pi.src, &pi.dst, pi.ptype, - pi.srcport, pi.destport, NULL, 0); + conversation = conversation_new(&pinfo->src, &pinfo->dst, + pinfo->ptype, pinfo->srcport, pinfo->destport, NULL, 0); } request_key.conversation = conversation->index; - request_key.service = pntohs(&rxh->serviceId); - request_key.callnumber = pntohl(&rxh->callNumber); + request_key.service = pinfo->ps.rx.serviceid; + request_key.callnumber = pinfo->ps.rx.callnumber; request_val = (struct afs_request_val *) g_hash_table_lookup( afs_request_hash, &request_key); /* only allocate a new hash element when it's a request */ opcode = 0; - if ( !request_val && !reply) - { + if ( !request_val && !reply) { new_request_key = g_mem_chunk_alloc(afs_request_keys); *new_request_key = request_key; request_val = g_mem_chunk_alloc(afs_request_vals); - request_val -> opcode = pntohl(&afsh->opcode); + request_val -> opcode = tvb_get_ntohl(tvb, offset); g_hash_table_insert(afs_request_hash, new_request_key, request_val); } - if ( request_val ) - { + if ( request_val ) { opcode = request_val->opcode; } @@ -261,8 +254,7 @@ dissect_afs(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) typenode = 0; vals = NULL; dissector = NULL; - switch (port) - { + switch (port) { case AFS_PORT_FS: typenode = hf_afs_fs; node = hf_afs_fs_opcode; @@ -329,105 +321,79 @@ dissect_afs(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) dissector = reply ? dissect_backup_reply : dissect_backup_request; break; } + if ( (opcode >= VOTE_LOW && opcode <= VOTE_HIGH) || - (opcode >= DISK_LOW && opcode <= DISK_HIGH) ) - { + (opcode >= DISK_LOW && opcode <= DISK_HIGH) ) { typenode = hf_afs_ubik; node = hf_afs_ubik_opcode; vals = ubik_req; dissector = reply ? dissect_ubik_reply : dissect_ubik_request; } - if ( VALID_OPCODE(opcode) ) - { - if ( vals ) - { - if (check_col(fd, COL_INFO)) - col_add_fstr(fd, COL_INFO, "%s%s %s: %s (%d)", + + if ( VALID_OPCODE(opcode) ) { + if ( vals ) { + if (check_col(pinfo->fd, COL_INFO)) + col_add_fstr(pinfo->fd, COL_INFO, "%s%s %s: %s (%d)", typenode == hf_afs_ubik ? "UBIK-" : "", val_to_str(port, port_types_short, "Unknown(%d)"), reply ? "Reply" : "Request", val_to_str(opcode, vals, "Unknown(%d)"), opcode); - } - else - { - if (check_col(fd, COL_INFO)) - col_add_fstr(fd, COL_INFO, "%s%s %s: Unknown(%d)", + } else { + if (check_col(pinfo->fd, COL_INFO)) + col_add_fstr(pinfo->fd, COL_INFO, "%s%s %s: Unknown(%d)", typenode == hf_afs_ubik ? "UBIK-" : "", val_to_str(port, port_types_short, "Unknown(%d)"), reply ? "Reply" : "Request", opcode); } - } - else - { - if (check_col(fd, COL_INFO)) - col_add_fstr(fd, COL_INFO, "Encrypted %s %s", + } else { + if (check_col(pinfo->fd, COL_INFO)) + col_add_fstr(pinfo->fd, COL_INFO, "Encrypted %s %s", val_to_str(port, port_types_short, "Unknown(%d)"), reply ? "Reply" : "Request" ); } if (tree) { - ti = proto_tree_add_item(tree, proto_afs, NullTVB, doffset, END_OF_FRAME, FALSE); + ti = proto_tree_add_item(tree, proto_afs, tvb, offset, + tvb_length_remaining(tvb, offset), FALSE); afs_tree = proto_item_add_subtree(ti, ett_afs); - if ( !BYTES_ARE_IN_FRAME(offset, sizeof(struct rx_header) + - sizeof(struct afs_header)) && - typenode != hf_afs_ubik ) - { - proto_tree_add_text(afs_tree, NullTVB, doffset, END_OF_FRAME, - "Service: %s%s%s %s (Truncated)", - VALID_OPCODE(opcode) ? "" : "Encrypted ", - typenode == hf_afs_ubik ? "UBIK - " : "", - val_to_str(port, port_types, "Unknown(%d)"), - reply ? "Reply" : "Request"); - return; - } - else - { - proto_tree_add_text(afs_tree, NullTVB, doffset, END_OF_FRAME, - "Service: %s%s%s %s", - VALID_OPCODE(opcode) ? "" : "Encrypted ", - typenode == hf_afs_ubik ? "UBIK - " : "", - val_to_str(port, port_types, "Unknown(%d)"), - reply ? "Reply" : "Request"); - } + proto_tree_add_text(afs_tree, tvb, + offset, tvb_length_remaining(tvb, offset), + "Service: %s%s%s %s", + VALID_OPCODE(opcode) ? "" : "Encrypted ", + typenode == hf_afs_ubik ? "UBIK - " : "", + val_to_str(port, port_types, "Unknown(%d)"), + reply ? "Reply" : "Request"); - if ( VALID_OPCODE(opcode) ) - { + if ( VALID_OPCODE(opcode) ) { /* until we do cache, can't handle replies */ ti = NULL; - if ( !reply && node != 0 ) - { + if ( !reply && node != 0 ) { ti = proto_tree_add_uint(afs_tree, - node, NullTVB, doffset, 4, opcode); - } - else if ( reply && node != 0 ) - { + node, tvb, offset, 4, opcode); + } else if ( reply && node != 0 ) { /* the opcode isn't in this packet */ ti = proto_tree_add_uint(afs_tree, - node, NullTVB, doffset, 0, opcode); - } - else - { - ti = proto_tree_add_text(afs_tree, NullTVB, - doffset, 0, "Operation: Unknown"); + node, tvb, offset, 0, opcode); + } else { + ti = proto_tree_add_text(afs_tree, tvb, + offset, 0, "Operation: Unknown"); } /* Add the subtree for this particular service */ afs_op_tree = proto_item_add_subtree(ti, ett_afs_op); - if ( typenode != 0 ) - { + if ( typenode != 0 ) { /* indicate the type of request */ - proto_tree_add_boolean_hidden(afs_tree, typenode, NullTVB, doffset, 0, 1); + proto_tree_add_boolean_hidden(afs_tree, typenode, tvb, offset, 0, 1); } /* Process the packet according to what service it is */ - if ( dissector ) - { - (*dissector)(pd,offset,fd,afs_op_tree,opcode); + if ( dissector ) { + (*dissector)(tvb, pinfo, afs_op_tree, offset, opcode); } } } @@ -435,8 +401,7 @@ dissect_afs(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) /* if it's the last packet, and it's a reply, remove opcode from hash */ /* ignoring for now, I'm not sure how the chunk deallocation works */ - if ( rxh->flags & RX_LAST_PACKET && reply ) - { + if ( pinfo->ps.rx.flags & RX_LAST_PACKET && reply ){ } } @@ -457,68 +422,62 @@ dissect_afs(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) * ASCII strings containing the UID/PTS record and and a ascii number * representing a logical OR of all the ACL permission bits */ - -static void dissect_acl(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) +/* FIXME: sscanf is probably quite dangerous if we run outside the packet. */ +static int +dissect_acl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset) { - int pos, neg, acl; - int n, i, bytes; - u_char const *s; - u_char const *end; + int old_offset; + guint32 bytes; + int i, n, pos, neg, acl; char user[128]; /* Be sure to adjust sscanf()s below if length is changed... */ - int curoffset; - int soff,eoff; - - curoffset = offset; - TRUNC(sizeof(guint32)); - bytes = pntohl(&pd[curoffset]); + old_offset = offset; + bytes = tvb_get_ntohl(tvb, offset); OUT_UINT(hf_afs_fs_acl_datasize); - TRUNC(bytes); - soff = curoffset; - eoff = curoffset+bytes; - - s = &pd[soff]; - end = &pd[eoff]; - - if (sscanf((char *) s, "%d %n", &pos, &n) != 1) - return; - s += n; - TRUNC(1); - proto_tree_add_uint(tree, hf_afs_fs_acl_count_positive, NullTVB, curoffset, n, pos); - curoffset += n; + if (sscanf((char *) GETSTR, "%d %n", &pos, &n) != 1) { + /* does not matter what we return, if this fails, + * we cant dissect anything else in the packet either. + */ + return offset; + } + proto_tree_add_uint(tree, hf_afs_fs_acl_count_positive, tvb, + offset, n, pos); + offset += n; - if (sscanf((char *) s, "%d %n", &neg, &n) != 1) - return; - s += n; - TRUNC(1); - proto_tree_add_uint(tree, hf_afs_fs_acl_count_negative, NullTVB, curoffset, n, neg); - curoffset += n; + if (sscanf((char *) GETSTR, "%d %n", &neg, &n) != 1) { + return offset; + } + proto_tree_add_uint(tree, hf_afs_fs_acl_count_negative, tvb, + offset, n, neg); + offset += n; /* * This wacky order preserves the order used by the "fs" command */ - for (i = 0; i < pos; i++) { - if (sscanf((char *) s, "%127s %d %n", user, &acl, &n) != 2) - return; - s += n; + if (sscanf((char *) GETSTR, + "%127s %d %n", user, &acl, &n) != 2) { + return offset; + } ACLOUT(user,1,acl,n); - curoffset += n; - TRUNC(1); + offset += n; } - for (i = 0; i < neg; i++) { - if (sscanf((char *) s, "%127s %d %n", user, &acl, &n) != 2) - return; - s += n; + if (sscanf((char *) GETSTR, + "%127s %d %n", user, &acl, &n) != 2) { + return offset; + } ACLOUT(user,0,acl,n); - curoffset += n; - if (s > end) - return; + offset += n; + if (offset >= old_offset+bytes ) { + return offset; + } } + + return offset; } /* @@ -526,26 +485,15 @@ static void dissect_acl(const u_char *pd, int offset, frame_data *fd, proto_tree */ static void -dissect_fs_reply(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int opcode) +dissect_fs_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int opcode) { - struct rx_header *rxh; - unsigned char *data; - int doffset, curoffset; - int seq; - - rxh = (struct rx_header *) &pd[offset]; - data = (char *)rxh + sizeof(struct rx_header); - doffset = offset + sizeof(struct rx_header); - curoffset = doffset; - - seq = pntohl(&rxh->seq); - - if ( rxh->type == RX_PACKET_TYPE_DATA ) + if ( pinfo->ps.rx.type == RX_PACKET_TYPE_DATA ) { switch ( opcode ) { case 130: /* fetch data */ - if ( seq == 1 ) /* only on first packet */ + /* only on first packet */ + if ( pinfo->ps.rx.seq == 1 ) { OUT_FS_AFSFetchStatus("Status"); OUT_FS_AFSCallBack(); @@ -554,7 +502,7 @@ dissect_fs_reply(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, OUT_BYTES_ALL(hf_afs_fs_data); break; case 131: /* fetch acl */ - dissect_acl(pd,curoffset,fd,tree); + offset = dissect_acl(tvb, pinfo, tree, offset); OUT_FS_AFSFetchStatus("Status"); OUT_FS_AFSVolSync(); break; @@ -644,25 +592,16 @@ dissect_fs_reply(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, break; } } - else if ( rxh->type == RX_PACKET_TYPE_ABORT ) + else if ( pinfo->ps.rx.type == RX_PACKET_TYPE_ABORT ) { OUT_UINT(hf_afs_fs_errcode); } } static void -dissect_fs_request(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int opcode) +dissect_fs_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int opcode) { - struct rx_header *rxh; - unsigned char *data; - int doffset, curoffset; - - rxh = (struct rx_header *) &pd[offset]; - data = (char *)rxh + sizeof(struct rx_header); - doffset = offset + sizeof(struct rx_header); - curoffset = doffset; - - SKIP_OPCODE(); + offset += 4; /* skip the opcode */ switch ( opcode ) { @@ -686,7 +625,7 @@ dissect_fs_request(const u_char *pd, int offset, frame_data *fd, proto_tree *tre break; case 134: /* Store ACL */ OUT_FS_AFSFid("Target"); - dissect_acl(pd,curoffset,fd,tree); + offset = dissect_acl(tvb, pinfo, tree, offset); break; case 135: /* Store Status */ OUT_FS_AFSFid("Target"); @@ -815,18 +754,9 @@ dissect_fs_request(const u_char *pd, int offset, frame_data *fd, proto_tree *tre * BOS Helpers */ static void -dissect_bos_reply(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int opcode) +dissect_bos_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int opcode) { - struct rx_header *rxh; - unsigned char *data; - int doffset, curoffset; - - rxh = (struct rx_header *) &pd[offset]; - data = (char *)rxh + sizeof(struct rx_header); - doffset = offset + sizeof(struct rx_header); - curoffset = doffset; - - if ( rxh->type == RX_PACKET_TYPE_DATA ) + if ( pinfo->ps.rx.type == RX_PACKET_TYPE_DATA ) { switch ( opcode ) { @@ -947,26 +877,17 @@ dissect_bos_reply(const u_char *pd, int offset, frame_data *fd, proto_tree *tree break; } } - else if ( rxh->type == RX_PACKET_TYPE_ABORT ) + else if ( pinfo->ps.rx.type == RX_PACKET_TYPE_ABORT ) { OUT_UINT(hf_afs_bos_errcode); } } static void -dissect_bos_request(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int opcode) +dissect_bos_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int opcode) { - struct rx_header *rxh; - unsigned char *data; - int doffset, curoffset; - - rxh = (struct rx_header *) &pd[offset]; - data = (char *)rxh + sizeof(struct rx_header); - doffset = offset + sizeof(struct rx_header); - curoffset = doffset; + offset += 4; /* skip the opcode */ - SKIP_OPCODE(); - switch ( opcode ) { case 80: /* create b node */ @@ -1093,18 +1014,9 @@ dissect_bos_request(const u_char *pd, int offset, frame_data *fd, proto_tree *tr * VOL Helpers */ static void -dissect_vol_reply(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int opcode) +dissect_vol_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int opcode) { - struct rx_header *rxh; - unsigned char *data; - int doffset, curoffset; - - rxh = (struct rx_header *) &pd[offset]; - data = (char *)rxh + sizeof(struct rx_header); - doffset = offset + sizeof(struct rx_header); - curoffset = doffset; - - if ( rxh->type == RX_PACKET_TYPE_DATA ) + if ( pinfo->ps.rx.type == RX_PACKET_TYPE_DATA ) { switch ( opcode ) { @@ -1115,25 +1027,16 @@ dissect_vol_reply(const u_char *pd, int offset, frame_data *fd, proto_tree *tree break; } } - else if ( rxh->type == RX_PACKET_TYPE_ABORT ) + else if ( pinfo->ps.rx.type == RX_PACKET_TYPE_ABORT ) { OUT_UINT(hf_afs_vol_errcode); } } static void -dissect_vol_request(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int opcode) +dissect_vol_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int opcode) { - struct rx_header *rxh; - unsigned char *data; - int doffset, curoffset; - - rxh = (struct rx_header *) &pd[offset]; - data = (char *)rxh + sizeof(struct rx_header); - doffset = offset + sizeof(struct rx_header); - curoffset = doffset; - - SKIP_OPCODE(); + offset += 4; /* skip the opcode */ switch ( opcode ) { @@ -1148,42 +1051,24 @@ dissect_vol_request(const u_char *pd, int offset, frame_data *fd, proto_tree *tr * KAUTH Helpers */ static void -dissect_kauth_reply(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int opcode) +dissect_kauth_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int opcode) { - struct rx_header *rxh; - unsigned char *data; - int doffset, curoffset; - - rxh = (struct rx_header *) &pd[offset]; - data = (char *)rxh + sizeof(struct rx_header); - doffset = offset + sizeof(struct rx_header); - curoffset = doffset; - - if ( rxh->type == RX_PACKET_TYPE_DATA ) + if ( pinfo->ps.rx.type == RX_PACKET_TYPE_DATA ) { switch ( opcode ) { } } - else if ( rxh->type == RX_PACKET_TYPE_ABORT ) + else if ( pinfo->ps.rx.type == RX_PACKET_TYPE_ABORT ) { OUT_UINT(hf_afs_kauth_errcode); } } static void -dissect_kauth_request(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int opcode) +dissect_kauth_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int opcode) { - struct rx_header *rxh; - unsigned char *data; - int doffset, curoffset; - - rxh = (struct rx_header *) &pd[offset]; - data = (char *)rxh + sizeof(struct rx_header); - doffset = offset + sizeof(struct rx_header); - curoffset = doffset; - - SKIP_OPCODE(); + offset += 4; /* skip the opcode */ switch ( opcode ) { @@ -1224,42 +1109,24 @@ dissect_kauth_request(const u_char *pd, int offset, frame_data *fd, proto_tree * * CB Helpers */ static void -dissect_cb_reply(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int opcode) +dissect_cb_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int opcode) { - struct rx_header *rxh; - unsigned char *data; - int doffset, curoffset; - - rxh = (struct rx_header *) &pd[offset]; - data = (char *)rxh + sizeof(struct rx_header); - doffset = offset + sizeof(struct rx_header); - curoffset = doffset; - - if ( rxh->type == RX_PACKET_TYPE_DATA ) + if ( pinfo->ps.rx.type == RX_PACKET_TYPE_DATA ) { switch ( opcode ) { } } - else if ( rxh->type == RX_PACKET_TYPE_ABORT ) + else if ( pinfo->ps.rx.type == RX_PACKET_TYPE_ABORT ) { OUT_UINT(hf_afs_cb_errcode); } } static void -dissect_cb_request(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int opcode) +dissect_cb_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int opcode) { - struct rx_header *rxh; - unsigned char *data; - int doffset, curoffset; - - rxh = (struct rx_header *) &pd[offset]; - data = (char *)rxh + sizeof(struct rx_header); - doffset = offset + sizeof(struct rx_header); - curoffset = doffset; - - SKIP_OPCODE(); + offset += 4; /* skip the opcode */ switch ( opcode ) { @@ -1267,16 +1134,16 @@ dissect_cb_request(const u_char *pd, int offset, frame_data *fd, proto_tree *tre { unsigned int i,j; - TRUNC(4); - j = GETINT(); + j = tvb_get_ntohl(tvb, offset); + offset += 4; for (i=0; i<j; i++) { OUT_CB_AFSFid("Target"); } - TRUNC(4); - j = GETINT(); + j = tvb_get_ntohl(tvb, offset); + offset += 4; for (i=0; i<j; i++) { OUT_CB_AFSCallBack(); @@ -1289,18 +1156,9 @@ dissect_cb_request(const u_char *pd, int offset, frame_data *fd, proto_tree *tre * PROT Helpers */ static void -dissect_prot_reply(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int opcode) +dissect_prot_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int opcode) { - struct rx_header *rxh; - unsigned char *data; - int doffset, curoffset; - - rxh = (struct rx_header *) &pd[offset]; - data = (char *)rxh + sizeof(struct rx_header); - doffset = offset + sizeof(struct rx_header); - curoffset = doffset; - - if ( rxh->type == RX_PACKET_TYPE_DATA ) + if ( pinfo->ps.rx.type == RX_PACKET_TYPE_DATA ) { switch ( opcode ) { @@ -1308,8 +1166,7 @@ dissect_prot_reply(const u_char *pd, int offset, frame_data *fd, proto_tree *tre { unsigned int i, j; - TRUNC(4); - j = GETINT(); + j = tvb_get_ntohl(tvb, offset); OUT_UINT(hf_afs_prot_count); for (i=0; i<j; i++) @@ -1322,8 +1179,7 @@ dissect_prot_reply(const u_char *pd, int offset, frame_data *fd, proto_tree *tre { unsigned int i, j; - TRUNC(4); - j = GETINT(); + j = tvb_get_ntohl(tvb, offset); OUT_UINT(hf_afs_prot_count); for (i=0; i<j; i++) @@ -1340,8 +1196,7 @@ dissect_prot_reply(const u_char *pd, int offset, frame_data *fd, proto_tree *tre { unsigned int i, j; - TRUNC(4); - j = GETINT(); + j = tvb_get_ntohl(tvb, offset); OUT_UINT(hf_afs_prot_count); for (i=0; i<j; i++) @@ -1356,25 +1211,16 @@ dissect_prot_reply(const u_char *pd, int offset, frame_data *fd, proto_tree *tre break; } } - else if ( rxh->type == RX_PACKET_TYPE_ABORT ) + else if ( pinfo->ps.rx.type == RX_PACKET_TYPE_ABORT ) { OUT_UINT(hf_afs_prot_errcode); } } static void -dissect_prot_request(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int opcode) +dissect_prot_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int opcode) { - struct rx_header *rxh; - unsigned char *data; - int doffset, curoffset; - - rxh = (struct rx_header *) &pd[offset]; - data = (char *)rxh + sizeof(struct rx_header); - doffset = offset + sizeof(struct rx_header); - curoffset = doffset; - - SKIP_OPCODE(); + offset += 4; /* skip the opcode */ switch ( opcode ) { @@ -1405,8 +1251,7 @@ dissect_prot_request(const u_char *pd, int offset, frame_data *fd, proto_tree *t { unsigned int i, j; - TRUNC(4); - j = GETINT(); + j = tvb_get_ntohl(tvb, offset); OUT_UINT(hf_afs_prot_count); for (i=0; i<j; i++) @@ -1419,8 +1264,7 @@ dissect_prot_request(const u_char *pd, int offset, frame_data *fd, proto_tree *t { unsigned int i, j; - TRUNC(4); - j = GETINT(); + j = tvb_get_ntohl(tvb, offset); OUT_UINT(hf_afs_prot_count); for (i=0; i<j; i++) @@ -1455,18 +1299,9 @@ dissect_prot_request(const u_char *pd, int offset, frame_data *fd, proto_tree *t * VLDB Helpers */ static void -dissect_vldb_reply(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int opcode) +dissect_vldb_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int opcode) { - struct rx_header *rxh; - unsigned char *data; - int doffset, curoffset; - - rxh = (struct rx_header *) &pd[offset]; - data = (char *)rxh + sizeof(struct rx_header); - doffset = offset + sizeof(struct rx_header); - curoffset = doffset; - - if ( rxh->type == RX_PACKET_TYPE_DATA ) + if ( pinfo->ps.rx.type == RX_PACKET_TYPE_DATA ) { switch ( opcode ) { @@ -1479,8 +1314,7 @@ dissect_vldb_reply(const u_char *pd, int offset, frame_data *fd, proto_tree *tre { int nservers,i,j; VECOUT(hf_afs_vldb_name, VLNAMEMAX); - TRUNC(4); - nservers = GETINT(); + nservers = tvb_get_ntohl(tvb, offset); OUT_UINT(hf_afs_vldb_numservers); for (i=0; i<8; i++) { @@ -1496,14 +1330,13 @@ dissect_vldb_reply(const u_char *pd, int offset, frame_data *fd, proto_tree *tre for (i=0; i<8; i++) { char part[8]; - TRUNC(4); - j = GETINT(); + j = tvb_get_ntohl(tvb, offset); strcpy(part, "/vicepa"); if ( i<nservers && j<=25 ) { part[6] = 'a' + (char) j; - proto_tree_add_string(tree, hf_afs_vldb_partition, NullTVB, - curoffset, 4, part); + proto_tree_add_string(tree, hf_afs_vldb_partition, tvb, + offset, 4, part); } SKIP(4); } @@ -1526,8 +1359,7 @@ dissect_vldb_reply(const u_char *pd, int offset, frame_data *fd, proto_tree *tre { int nservers,i,j; VECOUT(hf_afs_vldb_name, VLNAMEMAX); - TRUNC(4); - nservers = GETINT(); + nservers = tvb_get_ntohl(tvb, offset); OUT_UINT(hf_afs_vldb_numservers); for (i=0; i<13; i++) { @@ -1543,14 +1375,13 @@ dissect_vldb_reply(const u_char *pd, int offset, frame_data *fd, proto_tree *tre for (i=0; i<13; i++) { char part[8]; - TRUNC(4); - j = GETINT(); + j = tvb_get_ntohl(tvb, offset); strcpy(part, "/vicepa"); if ( i<nservers && j<=25 ) { part[6] = 'a' + (char) j; - proto_tree_add_string(tree, hf_afs_vldb_partition, NullTVB, - curoffset, 4, part); + proto_tree_add_string(tree, hf_afs_vldb_partition, tvb, + offset, 4, part); } SKIP(4); } @@ -1565,8 +1396,7 @@ dissect_vldb_reply(const u_char *pd, int offset, frame_data *fd, proto_tree *tre { int nservers,i,j; VECOUT(hf_afs_vldb_name, VLNAMEMAX); - TRUNC(4); - nservers = GETINT(); + nservers = tvb_get_ntohl(tvb, offset); OUT_UINT(hf_afs_vldb_numservers); for (i=0; i<13; i++) { @@ -1582,14 +1412,13 @@ dissect_vldb_reply(const u_char *pd, int offset, frame_data *fd, proto_tree *tre for (i=0; i<13; i++) { char part[8]; - TRUNC(4); - j = GETINT(); + j = tvb_get_ntohl(tvb, offset); strcpy(part, "/vicepa"); if ( i<nservers && j<=25 ) { part[6] = 'a' + (char) j; - proto_tree_add_string(tree, hf_afs_vldb_partition, NullTVB, - curoffset, 4, part); + proto_tree_add_string(tree, hf_afs_vldb_partition, tvb, + offset, 4, part); } SKIP(4); } @@ -1601,25 +1430,16 @@ dissect_vldb_reply(const u_char *pd, int offset, frame_data *fd, proto_tree *tre break; } } - else if ( rxh->type == RX_PACKET_TYPE_ABORT ) + else if ( pinfo->ps.rx.type == RX_PACKET_TYPE_ABORT ) { OUT_UINT(hf_afs_vldb_errcode); } } static void -dissect_vldb_request(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int opcode) +dissect_vldb_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int opcode) { - struct rx_header *rxh; - unsigned char *data; - int doffset, curoffset; - - rxh = (struct rx_header *) &pd[offset]; - data = (char *)rxh + sizeof(struct rx_header); - doffset = offset + sizeof(struct rx_header); - curoffset = doffset; - - SKIP_OPCODE(); + offset += 4; /* skip the opcode */ switch ( opcode ) { @@ -1662,17 +1482,8 @@ dissect_vldb_request(const u_char *pd, int offset, frame_data *fd, proto_tree *t * UBIK Helpers */ static void -dissect_ubik_reply(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int opcode) +dissect_ubik_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int opcode) { - struct rx_header *rxh; - unsigned char *data; - int doffset, curoffset; - - rxh = (struct rx_header *) &pd[offset]; - data = (char *)rxh + sizeof(struct rx_header); - doffset = offset + sizeof(struct rx_header); - curoffset = doffset; - switch ( opcode ) { case 10000: /* vote-beacon */ @@ -1717,18 +1528,9 @@ dissect_ubik_reply(const u_char *pd, int offset, frame_data *fd, proto_tree *tre } static void -dissect_ubik_request(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int opcode) +dissect_ubik_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int opcode) { - struct rx_header *rxh; - unsigned char *data; - int doffset, curoffset; - - rxh = (struct rx_header *) &pd[offset]; - data = (char *)rxh + sizeof(struct rx_header); - doffset = offset + sizeof(struct rx_header); - curoffset = doffset; - - SKIP_OPCODE(); + offset += 4; /* skip the opcode */ switch ( opcode ) { @@ -1805,42 +1607,24 @@ dissect_ubik_request(const u_char *pd, int offset, frame_data *fd, proto_tree *t * BACKUP Helpers */ static void -dissect_backup_reply(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int opcode) +dissect_backup_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int opcode) { - struct rx_header *rxh; - unsigned char *data; - int doffset, curoffset; - - rxh = (struct rx_header *) &pd[offset]; - data = (char *)rxh + sizeof(struct rx_header); - doffset = offset + sizeof(struct rx_header); - curoffset = doffset; - - if ( rxh->type == RX_PACKET_TYPE_DATA ) + if ( pinfo->ps.rx.type == RX_PACKET_TYPE_DATA ) { switch ( opcode ) { } } - else if ( rxh->type == RX_PACKET_TYPE_ABORT ) + else if ( pinfo->ps.rx.type == RX_PACKET_TYPE_ABORT ) { OUT_UINT(hf_afs_backup_errcode); } } static void -dissect_backup_request(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int opcode) +dissect_backup_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int opcode) { - struct rx_header *rxh; - unsigned char *data; - int doffset, curoffset; - - rxh = (struct rx_header *) &pd[offset]; - data = (char *)rxh + sizeof(struct rx_header); - doffset = offset + sizeof(struct rx_header); - curoffset = doffset; - - SKIP_OPCODE(); + offset += 4; /* skip the opcode */ switch ( opcode ) { @@ -1877,3 +1661,4 @@ proto_register_afs(void) proto_register_subtree_array(ett, array_length(ett)); register_init_routine(&afs_init_protocol); } + diff --git a/packet-afs.h b/packet-afs.h index 74087c1aba..2bc699f2f9 100644 --- a/packet-afs.h +++ b/packet-afs.h @@ -1,7 +1,7 @@ /* packet-afs.h * Definitions for packet disassembly structures and routines * - * $Id: packet-afs.h,v 1.5 2001/04/17 00:46:03 guy Exp $ + * $Id: packet-afs.h,v 1.6 2001/05/27 01:48:23 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@zing.org> @@ -26,7 +26,7 @@ #ifndef PACKET_AFS_H #define PACKET_AFS_H -void dissect_afs(const u_char *, int, frame_data *, proto_tree *); +void dissect_afs(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree); #define AFS_PORT_FS 7000 #define AFS_PORT_CB 7001 diff --git a/packet-rx.c b/packet-rx.c index 0895093e8f..e63d504751 100644 --- a/packet-rx.c +++ b/packet-rx.c @@ -4,7 +4,7 @@ * Based on routines from tcpdump patches by * Ken Hornstein <kenh@cmf.nrl.navy.mil> * - * $Id: packet-rx.c,v 1.19 2001/03/26 15:27:55 nneul Exp $ + * $Id: packet-rx.c,v 1.20 2001/05/27 01:48:24 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@zing.org> @@ -75,8 +75,25 @@ static const value_string rx_flags[] = { { 0, NULL } }; -static int proto_rx = -1; +static const value_string rx_reason[] = { + { RX_ACK_REQUESTED, "Ack Requested" }, + { RX_ACK_DUPLICATE, "Duplicate Packet" }, + { RX_ACK_OUT_OF_SEQUENCE, "Out Of Sequence" }, + { RX_ACK_EXEEDS_WINDOW, "Exceeds Window" }, + { RX_ACK_NOSPACE, "No Space" }, + { RX_ACK_PING, "Ping" }, + { RX_ACK_PING_RESPONSE, "Ping Response" }, + { RX_ACK_DELAY, "Delay" }, + { 0, NULL } +}; + +static const value_string rx_ack_type[] = { + { RX_ACK_TYPE_NACK, "NACK" }, + { RX_ACK_TYPE_ACK, "ACK" }, + { 0, NULL } +}; +static int proto_rx = -1; static int hf_rx_epoch = -1; static int hf_rx_cid = -1; static int hf_rx_seq = -1; @@ -93,99 +110,418 @@ static int hf_rx_userstatus = -1; static int hf_rx_securityindex = -1; static int hf_rx_spare = -1; static int hf_rx_serviceid = -1; +static int hf_rx_bufferspace = -1; +static int hf_rx_maxskew = -1; +static int hf_rx_first_packet = -1; +static int hf_rx_prev_packet = -1; +static int hf_rx_reason = -1; +static int hf_rx_numacks = -1; +static int hf_rx_ack_type = -1; +static int hf_rx_ack = -1; +static int hf_rx_challenge = -1; +static int hf_rx_version = -1; +static int hf_rx_nonce = -1; +static int hf_rx_inc_nonce = -1; +static int hf_rx_min_level = -1; +static int hf_rx_level = -1; +static int hf_rx_response = -1; +static int hf_rx_encrypted = -1; +static int hf_rx_kvno = -1; +static int hf_rx_ticket_len = -1; +static int hf_rx_ticket = -1; static gint ett_rx = -1; static gint ett_rx_flags = -1; +static gint ett_rx_ack = -1; +static gint ett_rx_challenge = -1; +static gint ett_rx_response = -1; +static gint ett_rx_encrypted = -1; -static void -dissect_rx(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) +static int +dissect_rx_response_encrypted(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset) { - proto_tree *rx_tree, *rx_tree_flags, *rx_flags, *ti; - struct rx_header *rxh; - int reply; + proto_tree *tree; + proto_item *item; + int old_offset=offset; + int i; + guint32 callnumber; + + item = proto_tree_add_item(parent_tree, hf_rx_encrypted, tvb, offset, 0, FALSE); + tree = proto_item_add_subtree(item, ett_rx_encrypted); + + /* epoch : 4 bytes */ + { + struct timeval tv; + tv.tv_sec = tvb_get_ntohl(tvb, offset); + tv.tv_usec = 0; + + proto_tree_add_time(tree, hf_rx_epoch, tvb, + offset, 4, &tv); + offset += 4; + } + + /* cid : 4 bytes */ + proto_tree_add_uint(tree, hf_rx_cid, tvb, + offset, 4, tvb_get_ntohl(tvb, offset)); + offset += 4; + + /*FIXME dont know how to handle this checksum, skipping it */ + offset += 4; + + /* sequrityindex : 1 byte */ + proto_tree_add_uint(tree, hf_rx_securityindex, tvb, + offset, 1, tvb_get_guint8(tvb, offset)); + offset += 4; + + for (i=0; i<RX_MAXCALLS; i++) { + /* callnumber : 4 bytes */ + callnumber = tvb_get_ntohl(tvb, offset); + proto_tree_add_uint(tree, hf_rx_callnumber, tvb, + offset, 4, callnumber); + offset += 4; + } - OLD_CHECK_DISPLAY_AS_DATA(proto_rx, pd, offset, fd, tree); + /* inc nonce : 4 bytes */ + proto_tree_add_uint(tree, hf_rx_inc_nonce, tvb, + offset, 4, tvb_get_ntohl(tvb, offset)); + offset += 4; - rxh = (struct rx_header *) &pd[offset]; + /* level : 4 bytes */ + proto_tree_add_uint(tree, hf_rx_level, tvb, + offset, 4, tvb_get_ntohl(tvb, offset)); + offset += 4; + + proto_item_set_len(item, offset-old_offset); + return offset; +} + - /* get at least a full packet structure */ - if ( !BYTES_ARE_IN_FRAME(offset, sizeof(struct rx_header)) ) - return; +static int +dissect_rx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, guint32 seq, guint32 callnumber) +{ + proto_tree *tree; + proto_item *item; + guint32 version, tl; + int old_offset=offset; - if (check_col(fd, COL_PROTOCOL)) - col_set_str(fd, COL_PROTOCOL, "RX"); + if (check_col(pinfo->fd, COL_INFO)) { + col_add_fstr(pinfo->fd, COL_INFO, + "RESPONSE " + "Seq: %lu " + "Call: %lu " + "Source Port: %s " + "Destination Port: %s ", + (unsigned long)seq, + (unsigned long)callnumber, + get_udp_port(pinfo->srcport), + get_udp_port(pinfo->destport) + ); + } + + item = proto_tree_add_item(parent_tree, hf_rx_response, tvb, offset, 0, FALSE); + tree = proto_item_add_subtree(item, ett_rx_response); + version = tvb_get_ntohl(tvb, offset); + proto_tree_add_uint(tree, hf_rx_version, tvb, + offset, 4, version); + offset += 4; - if (tree) { - ti = proto_tree_add_protocol_format(tree, proto_rx, NullTVB, offset, - sizeof(struct rx_header), "RX Protocol"); - rx_tree = proto_item_add_subtree(ti, ett_rx); + if (version==2) { + /* skip unused */ + offset += 4; - { - struct timeval tv; - tv.tv_sec = pntohl(&rxh->epoch); - tv.tv_usec = 0; + /* encrypted : struct */ + offset = dissect_rx_response_encrypted(tvb, pinfo, tree, offset); + + /* kvno */ + proto_tree_add_uint(tree, hf_rx_kvno, tvb, + offset, 4, tvb_get_ntohl(tvb, offset)); + offset += 4; - proto_tree_add_time(rx_tree,hf_rx_epoch, NullTVB, - offset,sizeof(guint32),&tv); - } + /* ticket_len */ + tl = tvb_get_ntohl(tvb, offset); + proto_tree_add_uint(tree, hf_rx_ticket_len, tvb, + offset, 4, tl); + offset += 4; + + proto_tree_add_item(tree, hf_rx_ticket, tvb, offset, tl, FALSE); + offset += tl; + } + + proto_item_set_len(item, offset-old_offset); + return offset; +} - proto_tree_add_uint(rx_tree, hf_rx_cid, NullTVB, - offset+4, 4, pntohl(&rxh->cid)); - proto_tree_add_uint(rx_tree, hf_rx_callnumber, NullTVB, - offset+8, 4, pntohl(&rxh->callNumber)); - proto_tree_add_uint(rx_tree, hf_rx_seq, NullTVB, - offset+12, 4, pntohl(&rxh->seq)); - proto_tree_add_uint(rx_tree, hf_rx_serial, NullTVB, - offset+16, 4, pntohl(&rxh->serial)); - - proto_tree_add_uint(rx_tree, hf_rx_type, NullTVB, - offset+20, 1, rxh->type); - - rx_flags = proto_tree_add_uint(rx_tree, hf_rx_flags, NullTVB, - offset+21, 1, rxh->flags); - rx_tree_flags = proto_item_add_subtree(rx_flags, ett_rx_flags); - proto_tree_add_uint(rx_tree_flags, hf_rx_flags_free_packet, NullTVB, - offset+21, 1, rxh->flags); - proto_tree_add_uint(rx_tree_flags, hf_rx_flags_more_packets, NullTVB, - offset+21, 1, rxh->flags); - proto_tree_add_uint(rx_tree_flags, hf_rx_flags_last_packet, NullTVB, - offset+21, 1, rxh->flags); - proto_tree_add_uint(rx_tree_flags, hf_rx_flags_request_ack, NullTVB, - offset+21, 1, rxh->flags); - proto_tree_add_uint(rx_tree_flags, hf_rx_flags_clientinit, NullTVB, - offset+21, 1, rxh->flags); - - proto_tree_add_uint(rx_tree, hf_rx_userstatus, NullTVB, - offset+22, 1, rxh->userStatus); - proto_tree_add_uint(rx_tree, hf_rx_securityindex, NullTVB, - offset+23, 1, rxh->securityIndex); - proto_tree_add_uint(rx_tree, hf_rx_spare, NullTVB, - offset+24, 2, pntohs(&rxh->spare)); - proto_tree_add_uint(rx_tree, hf_rx_serviceid, NullTVB, - offset+26, 2, pntohs(&rxh->serviceId)); +static int +dissect_rx_challenge(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, guint32 seq, guint32 callnumber) +{ + proto_tree *tree; + proto_item *item; + guint32 version; + int old_offset=offset; + + if (check_col(pinfo->fd, COL_INFO)) { + col_add_fstr(pinfo->fd, COL_INFO, + "CHALLENGE " + "Seq: %lu " + "Call: %lu " + "Source Port: %s " + "Destination Port: %s ", + (unsigned long)seq, + (unsigned long)callnumber, + get_udp_port(pinfo->srcport), + get_udp_port(pinfo->destport) + ); } - if (check_col(fd, COL_INFO)) - col_add_fstr(fd, COL_INFO, - "Type: %s " + item = proto_tree_add_item(parent_tree, hf_rx_challenge, tvb, offset, 0, FALSE); + tree = proto_item_add_subtree(item, ett_rx_challenge); + + version = tvb_get_ntohl(tvb, offset); + proto_tree_add_uint(tree, hf_rx_version, tvb, + offset, 4, version); + offset += 4; + + if (version==2) { + proto_tree_add_uint(tree, hf_rx_nonce, tvb, + offset, 4, tvb_get_ntohl(tvb, offset)); + offset += 4; + + proto_tree_add_uint(tree, hf_rx_min_level, tvb, + offset, 4, tvb_get_ntohl(tvb, offset)); + offset += 4; + } + + proto_item_set_len(item, offset-old_offset); + return offset; +} + +static int +dissect_rx_acks(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, guint32 seq, guint32 callnumber) +{ + proto_tree *tree; + proto_item *item; + guint8 num; + int old_offset = offset; + + if (check_col(pinfo->fd, COL_INFO)) { + col_add_fstr(pinfo->fd, COL_INFO, + "ACK " "Seq: %lu " "Call: %lu " "Source Port: %s " "Destination Port: %s ", - val_to_str(rxh->type, rx_types, "%d"), - (unsigned long)pntohl(&rxh->seq), - (unsigned long)pntohl(&rxh->callNumber), - get_udp_port(pi.srcport), - get_udp_port(pi.destport) + (unsigned long)seq, + (unsigned long)callnumber, + get_udp_port(pinfo->srcport), + get_udp_port(pinfo->destport) ); + } + + item = proto_tree_add_item(parent_tree, hf_rx_ack, tvb, offset, 0, FALSE); + tree = proto_item_add_subtree(item, ett_rx_ack); + + + /* bufferspace: 2 bytes*/ + proto_tree_add_uint(tree, hf_rx_bufferspace, tvb, + offset, 2, tvb_get_ntohs(tvb, offset)); + offset += 2; + + /* maxskew: 2 bytes*/ + proto_tree_add_uint(tree, hf_rx_maxskew, tvb, + offset, 2, tvb_get_ntohs(tvb, offset)); + offset += 2; + + /* first packet: 4 bytes*/ + proto_tree_add_uint(tree, hf_rx_first_packet, tvb, + offset, 4, tvb_get_ntohl(tvb, offset)); + offset += 4; + + /* prev packet: 4 bytes*/ + proto_tree_add_uint(tree, hf_rx_prev_packet, tvb, + offset, 4, tvb_get_ntohl(tvb, offset)); + offset += 4; + + /* serial : 4 bytes */ + proto_tree_add_uint(tree, hf_rx_serial, tvb, + offset, 4, tvb_get_ntohl(tvb, offset) ); + offset += 4; + + /* reason : 1 byte */ + proto_tree_add_uint(tree, hf_rx_reason, tvb, + offset, 1, tvb_get_guint8(tvb, offset) ); + offset += 1; + + /* nACKs */ + num = tvb_get_guint8(tvb, offset); + proto_tree_add_uint(tree, hf_rx_numacks, tvb, + offset, 1, tvb_get_guint8(tvb, offset) ); + offset += 1; + + while(num--){ + proto_tree_add_uint(tree, hf_rx_ack_type, tvb, + offset, 1, tvb_get_guint8(tvb, offset) ); + offset += 1; + } + + proto_item_set_len(item, offset-old_offset); + return offset; +} + + +static int +dissect_rx_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset) +{ + proto_tree *tree; + proto_item *item; + guint8 flags; + + flags = tvb_get_guint8(tvb, offset); + pinfo->ps.rx.flags = flags; - reply = (rxh->flags & RX_CLIENT_INITIATED) == 0; - if ( (rxh->type == RX_PACKET_TYPE_ABORT && reply) || - rxh->type == RX_PACKET_TYPE_DATA ) + item = proto_tree_add_uint(parent_tree, hf_rx_flags, tvb, + offset, 1, flags); + tree = proto_item_add_subtree(item, ett_rx_flags); + + proto_tree_add_uint(tree, hf_rx_flags_free_packet, tvb, + offset, 1, flags); + proto_tree_add_uint(tree, hf_rx_flags_more_packets, tvb, + offset, 1, flags); + proto_tree_add_uint(tree, hf_rx_flags_last_packet, tvb, + offset, 1, flags); + proto_tree_add_uint(tree, hf_rx_flags_request_ack, tvb, + offset, 1, flags); + proto_tree_add_uint(tree, hf_rx_flags_clientinit, tvb, + offset, 1, flags); + + offset += 1; + return offset; +} + +static void +dissect_rx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree) +{ + proto_tree *tree; + proto_item *item; + int offset = 0; + guint8 type; + guint32 seq, callnumber; + guint16 serviceid; + + if (check_col(pinfo->fd, COL_PROTOCOL)) + col_set_str(pinfo->fd, COL_PROTOCOL, "RX"); + if (check_col(pinfo->fd, COL_INFO)) + col_clear(pinfo->fd, COL_INFO); + + item = proto_tree_add_protocol_format(parent_tree, proto_rx, tvb, + offset, 28, "RX Protocol"); + tree = proto_item_add_subtree(item, ett_rx); + + /* epoch : 4 bytes */ { - dissect_afs(pd,offset,fd,tree); + struct timeval tv; + tv.tv_sec = tvb_get_ntohl(tvb, offset); + tv.tv_usec = 0; + + proto_tree_add_time(tree, hf_rx_epoch, tvb, + offset, 4, &tv); + offset += 4; + } + + /* cid : 4 bytes */ + proto_tree_add_uint(tree, hf_rx_cid, tvb, + offset, 4, tvb_get_ntohl(tvb, offset)); + offset += 4; + + /* callnumber : 4 bytes */ + callnumber = tvb_get_ntohl(tvb, offset); + proto_tree_add_uint(tree, hf_rx_callnumber, tvb, + offset, 4, callnumber); + offset += 4; + pinfo->ps.rx.callnumber = callnumber; + + /* seq : 4 bytes */ + seq = tvb_get_ntohl(tvb, offset); + proto_tree_add_uint(tree, hf_rx_seq, tvb, + offset, 4, seq); + offset += 4; + pinfo->ps.rx.seq = seq; + + /* serial : 4 bytes */ + proto_tree_add_uint(tree, hf_rx_serial, tvb, + offset, 4, tvb_get_ntohl(tvb, offset)); + offset += 4; + + /* type : 1 byte */ + type = tvb_get_guint8(tvb, offset); + proto_tree_add_uint(tree, hf_rx_type, tvb, + offset, 1, type); + offset += 1; + pinfo->ps.rx.type = type; + + /* flags : 1 byte */ + offset = dissect_rx_flags(tvb, pinfo, tree, offset); + + /* userstatus : 1 byte */ + proto_tree_add_uint(tree, hf_rx_userstatus, tvb, + offset, 1, tvb_get_guint8(tvb, offset)); + offset += 1; + + /* sequrityindex : 1 byte */ + proto_tree_add_uint(tree, hf_rx_securityindex, tvb, + offset, 1, tvb_get_guint8(tvb, offset)); + offset += 1; + + /* spare */ + proto_tree_add_uint(tree, hf_rx_spare, tvb, + offset, 2, tvb_get_ntohs(tvb, offset)); + offset += 2; + + /* service id : 2 bytes */ + serviceid = tvb_get_ntohs(tvb, offset); + proto_tree_add_uint(tree, hf_rx_serviceid, tvb, + offset, 2, serviceid); + offset += 2; + pinfo->ps.rx.serviceid = serviceid; + + switch (type) { + case RX_PACKET_TYPE_ACK: + /*dissect_rx_acks(tvb, pinfo, parent_tree, offset, + cant create it in a parallell tree, then ett seasrch + wont work */ + dissect_rx_acks(tvb, pinfo, tree, offset, + seq, callnumber); + break; + case RX_PACKET_TYPE_ACKALL: + /* does not contain any payload */ + if (check_col(pinfo->fd, COL_INFO)) { + col_add_fstr(pinfo->fd, COL_INFO, + "ACKALL " + "Seq: %lu " + "Call: %lu " + "Source Port: %s " + "Destination Port: %s ", + (unsigned long)seq, + (unsigned long)callnumber, + get_udp_port(pinfo->srcport), + get_udp_port(pinfo->destport) + ); + } + break; + case RX_PACKET_TYPE_CHALLENGE: + dissect_rx_challenge(tvb, pinfo, tree, offset, seq, callnumber); + break; + case RX_PACKET_TYPE_RESPONSE: + dissect_rx_response(tvb, pinfo, tree, offset, seq, callnumber); + break; + case RX_PACKET_TYPE_DATA: { + tvbuff_t *next_tvb; + next_tvb = tvb_new_subset(tvb, offset, -1, -1); + dissect_afs(next_tvb, pinfo, parent_tree); + }; + break; } + } void @@ -195,55 +531,151 @@ proto_register_rx(void) { &hf_rx_epoch, { "Epoch", "rx.epoch", FT_ABSOLUTE_TIME, BASE_DEC, NULL, 0, "Epoch" }}, + { &hf_rx_cid, { "CID", "rx.cid", FT_UINT32, BASE_DEC, NULL, 0, "CID" }}, + { &hf_rx_callnumber, { "Call Number", "rx.callnumber", FT_UINT32, BASE_DEC, NULL, 0, "Call Number" }}, + { &hf_rx_seq, { "Sequence Number", "rx.seq", FT_UINT32, BASE_DEC, NULL, 0, "Sequence Number" }}, + { &hf_rx_serial, { "Serial", "rx.serial", FT_UINT32, BASE_DEC, NULL, 0, "Serial" }}, + { &hf_rx_type, { "Type", "rx.type", FT_UINT8, BASE_DEC, VALS(rx_types), 0, "Type" }}, + { &hf_rx_flags, { "Flags", "rx.flags", FT_UINT8, BASE_HEX, NULL, 0, "Flags" }}, + { &hf_rx_flags_clientinit, { "Client Initiated", "rx.flags.client_init", FT_UINT8, BASE_BIN, NULL, RX_CLIENT_INITIATED, "Client Initiated" }}, + { &hf_rx_flags_request_ack, { "Request Ack", "rx.flags.request_ack", FT_UINT8, BASE_BIN, NULL, RX_REQUEST_ACK, "Request Ack" }}, + { &hf_rx_flags_last_packet, { "Last Packet", "rx.flags.last_packet", FT_UINT8, BASE_BIN, NULL, RX_LAST_PACKET, "Last Packet" }}, + { &hf_rx_flags_more_packets, { "More Packets", "rx.flags.more_packets", FT_UINT8, BASE_BIN, NULL, RX_MORE_PACKETS, "More Packets" }}, + { &hf_rx_flags_free_packet, { "Free Packet", "rx.flags.free_packet", FT_UINT8, BASE_BIN, NULL, RX_FREE_PACKET, "Free Packet" }}, + { &hf_rx_userstatus, { "User Status", "rx.userstatus", FT_UINT32, BASE_DEC, NULL, 0, "User Status" }}, + { &hf_rx_securityindex, { "Security Index", "rx.securityindex", FT_UINT32, BASE_DEC, NULL, 0, "Security Index" }}, + { &hf_rx_spare, { "Spare/Checksum", "rx.spare", FT_UINT16, BASE_DEC, NULL, 0, "Spare/Checksum" }}, + { &hf_rx_serviceid, { "Service ID", "rx.serviceid", FT_UINT16, BASE_DEC, NULL, 0, "Service ID" }}, + + { &hf_rx_bufferspace, { + "Bufferspace", "rx.bufferspace", FT_UINT16, BASE_DEC, + NULL, 0, "Number Of Packets Available" }}, + + { &hf_rx_maxskew, { + "Max Skew", "rx.maxskew", FT_UINT16, BASE_DEC, + NULL, 0, "Max Skew" }}, + + { &hf_rx_first_packet, { + "First Packet", "rx.first", FT_UINT32, BASE_DEC, + NULL, 0, "First Packet" }}, + + { &hf_rx_prev_packet, { + "Prev Packet", "rx.prev", FT_UINT32, BASE_DEC, + NULL, 0, "Previous Packet" }}, + + { &hf_rx_reason, { + "Reason", "rx.reason", FT_UINT8, BASE_DEC, + VALS(rx_reason), 0, "Reason For This ACK" }}, + + { &hf_rx_numacks, { + "Num ACKs", "rx.num_acks", FT_UINT8, BASE_DEC, + NULL, 0, "Number Of ACKs" }}, + + { &hf_rx_ack_type, { + "ACK Type", "rx.ack_type", FT_UINT8, BASE_DEC, + VALS(rx_ack_type), 0, "Type Of ACKs" }}, + + { &hf_rx_ack, { + "ACK Packet", "rx.ack", FT_NONE, BASE_NONE, + NULL, 0, "ACK Packet" }}, + + { &hf_rx_challenge, { + "CHALLENGE Packet", "rx.challenge", FT_NONE, BASE_NONE, + NULL, 0, "CHALLENGE Packet" }}, + + { &hf_rx_version, { + "Version", "rx.version", FT_UINT32, BASE_DEC, + NULL, 0, "Version Of Challenge/Response" }}, + + { &hf_rx_nonce, { + "Nonce", "rx.nonce", FT_UINT32, BASE_HEX, + NULL, 0, "Nonce" }}, + + { &hf_rx_inc_nonce, { + "Inc Nonce", "rx.inc_nonce", FT_UINT32, BASE_HEX, + NULL, 0, "Incremented Nonce" }}, + + { &hf_rx_min_level, { + "Min Level", "rx.min_level", FT_UINT32, BASE_DEC, + NULL, 0, "Min Level" }}, + + { &hf_rx_level, { + "Level", "rx.level", FT_UINT32, BASE_DEC, + NULL, 0, "Level" }}, + + { &hf_rx_response, { + "RESPONSE Packet", "rx.response", FT_NONE, BASE_NONE, + NULL, 0, "RESPONSE Packet" }}, + + { &hf_rx_encrypted, { + "Encrypted", "rx.encrypted", FT_NONE, BASE_NONE, + NULL, 0, "Encrypted part of response packet" }}, + + { &hf_rx_kvno, { + "kvno", "rx.kvno", FT_UINT32, BASE_DEC, + NULL, 0, "kvno" }}, + + { &hf_rx_ticket_len, { + "Ticket len", "rx.ticket_len", FT_UINT32, BASE_DEC, + NULL, 0, "Ticket Length" }}, + + { &hf_rx_ticket, { + "ticket", "rx.ticket", FT_BYTES, BASE_HEX, + NULL, 0, "Ticket" }}, + }; static gint *ett[] = { &ett_rx, &ett_rx_flags, + &ett_rx_ack, + &ett_rx_challenge, + &ett_rx_response, + &ett_rx_encrypted, }; proto_rx = proto_register_protocol("RX Protocol", "RX", "rx"); @@ -259,7 +691,7 @@ proto_reg_handoff_rx(void) /* Ports in the range UDP_PORT_RX_LOW to UDP_PORT_RX_HIGH are all used for various AFS services. */ for (port = UDP_PORT_RX_LOW; port <= UDP_PORT_RX_HIGH; port++) - old_dissector_add("udp.port", port, dissect_rx, proto_rx); - old_dissector_add("udp.port", UDP_PORT_RX_AFS_BACKUPS, dissect_rx, + dissector_add("udp.port", port, dissect_rx, proto_rx); + dissector_add("udp.port", UDP_PORT_RX_AFS_BACKUPS, dissect_rx, proto_rx); } diff --git a/packet-rx.h b/packet-rx.h index 128e2e8a91..b39a5627c4 100644 --- a/packet-rx.h +++ b/packet-rx.h @@ -1,7 +1,7 @@ /* packet-rx.h * Definitions for packet disassembly structures and routines * - * $Id: packet-rx.h,v 1.4 2001/04/17 00:46:03 guy Exp $ + * $Id: packet-rx.h,v 1.5 2001/05/27 01:48:24 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@zing.org> @@ -56,7 +56,7 @@ struct rx_header { }; /* serviceId is first, it's really */ /* encoded _after_ the spare field */ /* I wasted a day figuring that out! */ - +#define RX_MAXACKS 255 struct rx_ack_header { guint16 bufferspace; /* # of packet buffers available */ guint16 maxskew; @@ -64,7 +64,8 @@ struct rx_ack_header { guint32 prevpacket; guint32 serial; /* Packet that prompted this one */ u_char reason; /* rx_ack_reason */ - /* some other stuff I think */ + u_char nAcks; /* number of acks*/ + u_char acks[RX_MAXACKS]; }; #define RX_ACK_TYPE_NACK 0 @@ -79,5 +80,31 @@ struct rx_ack_header { #define RX_ACK_PING_RESPONSE 7 #define RX_ACK_DELAY 8 +struct rxkad_challenge { + guint32 version; + guint32 nonce; + guint32 min_level; + guint32 unused; +}; + +#define RX_MAXCALLS 4 +struct rxkad_response { + guint32 version; + guint32 unused; + struct { + guint32 epoch; + guint32 cid; + guint32 cksum; + guint32 security_index; + guint32 call_numbers[RX_MAXCALLS]; + guint32 inc_nonce; + guint32 level; + } encrypted; + guint32 kvno; + guint32 ticket_len; + u_char the_ticket[0]; +}; + + #endif |