Add the relative time to the frame tree, at the request of Manfred Young.
[obnox/wireshark/wip.git] / packet-socks.c
index 30e9692d6fd3dc77b1a7bf92d112529f9f372d4f..1d7b489fe7791103f7f834bf8fb3575c4ed27af9 100644 (file)
@@ -2,7 +2,7 @@
  * Routines for socks versions 4 &5  packet dissection
  * Copyright 2000, Jeffrey C. Foster <jfoste@woodward.com>
  *
- * $Id: packet-socks.c,v 1.1 2000/04/12 22:53:14 guy Exp $
+ * $Id: packet-socks.c,v 1.15 2000/11/19 08:54:08 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
 #include <stdio.h>
 #include <string.h>
 #include <glib.h>
+
+#ifdef NEED_SNPRINTF_H
+# include "snprintf.h"
+#endif
+
 #include "packet.h"
 #include "resolv.h"
 #include "globals.h"
 
 #include "packet-tcp.h"
 #include "packet-udp.h"
+#include "strutil.h"
 
-#ifdef NEED_SNPRINTF_H
-# ifdef HAVE_STDARG_H
-#  include <stdarg.h>
-# else
-#  include <varargs.h>
-# endif
-# include "snprintf.h"
-#endif
 
-
-
-#define CHECK_PACKET_LENGTH(X) if ((offset+X) > fd->cap_len){  \
-        proto_tree_add_text(tree, offset, 0, "*** FRAME TOO SHORT ***"); \
+#define CHECK_PACKET_LENGTH(X) if (!BYTES_ARE_IN_FRAME(offset, X)){  \
+        proto_tree_add_text(tree, NullTVB, offset, 0, "*** FRAME TOO SHORT ***"); \
         return; }
 
 #define compare_packet(X) (X == (fd->num))
@@ -214,8 +210,6 @@ static char *reply_table_v5[] = {
 
 static GMemChunk *socks_vals = NULL;
 
-static guint32 last_row= 0;    /* used to see if packet is new */
-
 
 /************************* Support routines ***************************/
 
@@ -235,25 +229,25 @@ static int display_string( const u_char *pd, int offset, frame_data *fd,
        char temp[ 256];
        int length = GBYTE( pd, offset);
 
-       if ((offset + 8) > fd->cap_len){  
-                       proto_tree_add_text(tree, offset, 0, "*** FRAME TOO SHORT ***");
+       if (!BYTES_ARE_IN_FRAME(offset, 8)){  
+                       proto_tree_add_text(tree, NullTVB, offset, 0, "*** FRAME TOO SHORT ***");
                return 0;
        }
 
        strncpy( temp, &pd[ offset + 1], length);
        temp[ length ] = 0;
   
-       ti = proto_tree_add_text(tree, offset, length + 1,
+       ti = proto_tree_add_text(tree, NullTVB, offset, length + 1,
                "%s: %s" , label, temp);
 
 
        name_tree = proto_item_add_subtree(ti, ett_socks_name);
 
-       proto_tree_add_text( name_tree, offset, 1, "Length: %d", length);
+       proto_tree_add_text( name_tree, NullTVB, offset, 1, "Length: %d", length);
 
        ++offset;
 
-       proto_tree_add_text( name_tree, offset, length, "String: %s", temp);
+       proto_tree_add_text( name_tree, NullTVB, offset, length, "String: %s", temp);
 
        return length + 1;
 }      
@@ -299,7 +293,7 @@ static int display_address( const u_char *pd, int offset,
 
        int a_type = GBYTE( pd, offset);
 
-       proto_tree_add_text( tree, offset, 1,
+       proto_tree_add_text( tree, NullTVB, offset, 1,
                        "Address Type: %d (%s)", a_type, 
                        address_type_table[ MAX( 0, MIN( a_type,
                                array_length( address_type_table)-1))]);
@@ -307,10 +301,10 @@ static int display_address( const u_char *pd, int offset,
        ++offset;
 
        if ( a_type == 1){              /* IPv4 address */
-               if ( (offset + 4) > fd->cap_len
-                               proto_tree_add_text(tree, offset, 0, "*** FRAME TOO SHORT ***");
+               if (!BYTES_ARE_IN_FRAME(offset, 4)
+                               proto_tree_add_text(tree, NullTVB, offset, 0, "*** FRAME TOO SHORT ***");
 
-               proto_tree_add_item( tree, hf_socks_ip_dst, offset,
+               proto_tree_add_ipv4( tree, hf_socks_ip_dst, NullTVB, offset,
                                        4, GWORD( pd, offset));
                offset += 4;
        }       
@@ -320,11 +314,11 @@ static int display_address( const u_char *pd, int offset,
                        "Remote name");
        }
        else if ( a_type == 4){ /* IPv6 address */
-               if ((offset + 16) > fd->cap_len
-                               proto_tree_add_text(tree, offset, 0, "*** FRAME TOO SHORT ***");
+               if (!BYTES_ARE_IN_FRAME(offset, 16)
+                               proto_tree_add_text(tree, NullTVB, offset, 0, "*** FRAME TOO SHORT ***");
 
-               proto_tree_add_item( tree, hf_socks_ip6_dst, offset,
-                               4, GWORD( pd, offset));
+               proto_tree_add_ipv6( tree, hf_socks_ip6_dst, NullTVB, offset,
+                               4, &pd[offset]);
                offset += 16;
        }
 
@@ -372,32 +366,33 @@ static void socks_udp_dissector( const u_char *pd, int offset, frame_data *fd,
        conversation_t *conversation;
        proto_tree      *socks_tree;
        proto_item      *ti;
+       tvbuff_t        *tvb;
        
        conversation = find_conversation( &pi.src, &pi.dst, pi.ptype,
-               pi.srcport, pi.destport);
+               pi.srcport, pi.destport, 0);
 
        g_assert( conversation);        /* should always find a conversation */
 
        hash_info = (socks_hash_entry_t*)conversation->data;
 
        if (check_col(fd, COL_PROTOCOL))
-               col_add_str(fd, COL_PROTOCOL, "Socks");
+               col_set_str(fd, COL_PROTOCOL, "Socks");
 
        if (check_col(fd, COL_INFO))
                col_add_fstr(fd, COL_INFO, "Version: 5, UDP Associated packet");
                        
        if ( tree) {
-               ti = proto_tree_add_item( tree, proto_socks, offset,
-                       END_OF_FRAME, NULL, "Socks:" );
+               ti = proto_tree_add_protocol_format( tree, proto_socks, NullTVB, offset,
+                       END_OF_FRAME, "Socks" );
 
                socks_tree = proto_item_add_subtree(ti, ett_socks);
 
                CHECK_PACKET_LENGTH( 3);
 
-                       proto_tree_add_text( socks_tree, offset, 2, "Reserved");
+                       proto_tree_add_text( socks_tree, NullTVB, offset, 2, "Reserved");
                offset += 2;
                
-                       proto_tree_add_text( socks_tree, offset, 1, "Fragment Number: %d", GBYTE( pd,offset));
+                       proto_tree_add_text( socks_tree, NullTVB, offset, 1, "Fragment Number: %d", GBYTE( pd,offset));
                ++offset;
        
 
@@ -405,7 +400,7 @@ static void socks_udp_dissector( const u_char *pd, int offset, frame_data *fd,
                hash_info->udp_remote_port = pntohs( &pd[ offset]);
                
                CHECK_PACKET_LENGTH( 2);
-               proto_tree_add_item( socks_tree, hf_socks_dstport,
+               proto_tree_add_uint( socks_tree, hf_socks_dstport, NullTVB,
                        offset, 2, hash_info->udp_remote_port);
                        
                offset += 2;
@@ -426,7 +421,8 @@ static void socks_udp_dissector( const u_char *pd, int offset, frame_data *fd,
 
         *ptr = hash_info->udp_remote_port;
        
-       decode_udp_ports( pd, offset, fd, tree, pi.srcport, pi.destport);
+       tvb = tvb_create_from_top(0);
+       decode_udp_ports( tvb, offset, &pi, tree, pi.srcport, pi.destport);
  
         *ptr = hash_info->udp_port;
 
@@ -436,11 +432,11 @@ static void socks_udp_dissector( const u_char *pd, int offset, frame_data *fd,
 void new_udp_conversation( socks_hash_entry_t *hash_info){
 
        conversation_t *conversation = conversation_new( &pi.src, &pi.dst,  PT_UDP,
-                       hash_info->udp_port, hash_info->port, hash_info);
+                       hash_info->udp_port, hash_info->port, hash_info, 0);
                        
        g_assert( conversation);
        
-       conversation->dissector = socks_udp_dissector;
+       old_conversation_set_dissector(conversation, socks_udp_dissector);
 }
 
 
@@ -466,30 +462,30 @@ void display_socks_v4( const u_char *pd, int offset, frame_data *fd,
        if (compare_packet( hash_info->connect_row)){
 
                CHECK_PACKET_LENGTH( 8);
-               proto_tree_add_text( tree, offset, 1,
+               proto_tree_add_text( tree, NullTVB, offset, 1,
                                "Version: %u ", hash_info->version);
                ++offset;
                command = GBYTE( pd, offset);
 
-               proto_tree_add_text( tree, offset, 1,
+               proto_tree_add_text( tree, NullTVB, offset, 1,
                        "Command: %u (%s)", command, 
                                get_command_name( command));
                ++offset;
 
                                                /* Do remote port       */
-               proto_tree_add_item( tree, hf_socks_dstport, offset, 2,
+               proto_tree_add_uint( tree, hf_socks_dstport, NullTVB, offset, 2,
                                pntohs( &pd[ offset]));
                offset += 2;
 
                                                /* Do destination address */
-               proto_tree_add_item( tree, hf_socks_ip_dst, offset,
+               proto_tree_add_ipv4( tree, hf_socks_ip_dst, NullTVB, offset,
                                4, GWORD( pd, offset));
 
                offset += 4;
 
 /*$$ check this, needs to do length checking    */             
                                                /* display user name    */
-                       proto_tree_add_item( tree, hf_user_name, offset, 
+                       proto_tree_add_string( tree, hf_user_name, NullTVB, offset, 
                                strlen( &pd[offset]) + 1,
                                &pd[offset]);
 
@@ -499,28 +495,28 @@ void display_socks_v4( const u_char *pd, int offset, frame_data *fd,
        else if ( compare_packet( hash_info->cmd_reply_row)){
                                 
                CHECK_PACKET_LENGTH( 8);
-               proto_tree_add_text( tree, offset, 1,
+               proto_tree_add_text( tree, NullTVB, offset, 1,
                        "Version: %u (should be 0) ", GBYTE( pd, offset));
                ++offset;
                                                /* Do results code      */
-               proto_tree_add_text( tree, offset, 1,
+               proto_tree_add_text( tree, NullTVB, offset, 1,
                        "Result Code: %u (%s)", GBYTE( pd, offset) ,
                        reply_table_v4[ MAX(0, MIN( GBYTE( pd, offset) - 90, 4))]);
                ++offset;
 
                                                /* Do remote port       */
-               proto_tree_add_item( tree, hf_socks_dstport, offset, 2,
+               proto_tree_add_uint( tree, hf_socks_dstport, NullTVB, offset, 2,
                                pntohs( &pd[ offset]));
                offset += 2;;
                                                /* Do remote address    */
-               proto_tree_add_item( tree, hf_socks_ip_dst, offset, 4,
+               proto_tree_add_ipv4( tree, hf_socks_ip_dst, NullTVB, offset, 4,
                        GWORD( pd, offset));
        }
        
        else if ( compare_packet( hash_info->v4_user_name_row)){
                         
 /*$$ check this, needs to do length checking    */             
-               proto_tree_add_text( tree, offset, strlen( &pd[offset]),
+               proto_tree_add_text( tree, NullTVB, offset, strlen( &pd[offset]),
                                "User Name: %s", &pd[offset]);
        }
 }                      
@@ -548,18 +544,18 @@ void display_socks_v5( const u_char *pd, int offset, frame_data *fd,
 
                CHECK_PACKET_LENGTH( 2);
                                                /* Do version   */
-               proto_tree_add_item( tree, hf_socks_ver, offset, 1,
+               proto_tree_add_uint( tree, hf_socks_ver, NullTVB, offset, 1,
                                hash_info->version);
                ++offset;
 
                temp = GBYTE( pd, offset);      /* Get Auth method count */
                                                        /* build auth tree */
-               ti = proto_tree_add_text( tree, offset, 1,
+               ti = proto_tree_add_text( tree, NullTVB, offset, 1,
                                "Client Authentication Methods");
                                
                AuthTree = proto_item_add_subtree(ti, ett_socks_auth);
 
-               proto_tree_add_text( AuthTree, offset, 1,
+               proto_tree_add_text( AuthTree, NullTVB, offset, 1,
                                "Count: %u ", temp);
                ++offset;
 
@@ -569,7 +565,7 @@ void display_socks_v5( const u_char *pd, int offset, frame_data *fd,
 
                        AuthMethodStr = get_auth_method_name(
                                GBYTE( pd, offset + i));
-                       proto_tree_add_text( AuthTree, offset + i, 1,
+                       proto_tree_add_text( AuthTree, NullTVB, offset + i, 1,
                                "Method[%d]: %u (%s)", i,
                                GBYTE( pd, offset + i), AuthMethodStr); 
                }
@@ -580,7 +576,7 @@ void display_socks_v5( const u_char *pd, int offset, frame_data *fd,
                ++offset;
                CHECK_PACKET_LENGTH( 1);
 
-               proto_tree_add_text( tree, offset, 1,
+               proto_tree_add_text( tree, NullTVB, offset, 1,
                        "Accepted Auth Method: 0x%0x (%s)", GBYTE( pd, offset),
                                get_auth_method_name( GBYTE( pd, offset)));
 
@@ -588,7 +584,7 @@ void display_socks_v5( const u_char *pd, int offset, frame_data *fd,
        }                                       /* handle user/password auth */
        else if (compare_packet( hash_info->user_name_auth_row)) {
 
-               proto_tree_add_text( tree, offset, 1,
+               proto_tree_add_text( tree, NullTVB, offset, 1,
                                "Version: %u ", hash_info->version);
                ++offset;
                                                /* process user name    */
@@ -604,7 +600,7 @@ void display_socks_v5( const u_char *pd, int offset, frame_data *fd,
                 (compare_packet( hash_info->cmd_reply_row)) ||
                 (compare_packet( hash_info->bind_reply_row))){
 
-               proto_tree_add_text( tree, offset, 1,
+               proto_tree_add_text( tree, NullTVB, offset, 1,
                        "Version: %u ", hash_info->version);
 
                CHECK_PACKET_LENGTH( 1);
@@ -614,15 +610,15 @@ void display_socks_v5( const u_char *pd, int offset, frame_data *fd,
                command = GBYTE( pd, offset);
                
                if (compare_packet( hash_info->command_row))
-                       proto_tree_add_text( tree, offset, 1, "Command: %u (%s)",
+                       proto_tree_add_text( tree, NullTVB, offset, 1, "Command: %u (%s)",
                                command,  get_command_name( command));
                else
-                       proto_tree_add_text( tree, offset, 1, "Status: %d (%s)",
+                       proto_tree_add_text( tree, NullTVB, offset, 1, "Status: %d (%s)",
                                GBYTE( pd, offset), reply_table_v5[ MAX( 0,
                                MIN(GBYTE( pd, offset) - 90, 9))]);
                ++offset;
 
-               proto_tree_add_text( tree, offset, 1,
+               proto_tree_add_text( tree, NullTVB, offset, 1,
                        "Reserved: 0x%0x (should = 0x00)", GBYTE( pd, offset)); 
                ++offset;
 
@@ -630,8 +626,8 @@ void display_socks_v5( const u_char *pd, int offset, frame_data *fd,
 
                CHECK_PACKET_LENGTH( 2);
                                                /* Do remote port       */
-               proto_tree_add_text( tree, offset, 2,
-                               "%s Port: %d",
+               proto_tree_add_text( tree, NullTVB, offset, 2,
+                               "%sPort: %d",
                                (compare_packet( hash_info->bind_reply_row) ?
                                        "Remote Host " : ""),
                                 pntohs( &pd[ offset]));
@@ -741,7 +737,7 @@ static void state_machine_v5( socks_hash_entry_t *hash_info, const u_char *pd,
                hash_info->state = Connecting;  /* change state         */
                hash_info->connect_row = get_packet_ptr;        
 
-               if (( offset+ 1) > fd->cap_len){ 
+               if (!BYTES_ARE_IN_FRAME(offset, 1)){ 
                        hash_info->state = Done;        /* change state         */
                        return; 
                }
@@ -777,7 +773,7 @@ static void state_machine_v5( socks_hash_entry_t *hash_info, const u_char *pd,
 
                guint temp;
 
-               if (( offset+ 1) > fd->cap_len){ 
+               if (!BYTES_ARE_IN_FRAME(offset, 1)){ 
                        hash_info->state = Done;        /* change state         */
                        return; 
                }
@@ -795,7 +791,7 @@ static void state_machine_v5( socks_hash_entry_t *hash_info, const u_char *pd,
 
                offset = get_address_v5( pd, offset, hash_info);
 
-               if (( offset+ 1) > fd->cap_len){ 
+               if (!BYTES_ARE_IN_FRAME(offset, 1)){ 
                        hash_info->state = Done;
                        return; 
                }
@@ -829,7 +825,7 @@ static void state_machine_v5( socks_hash_entry_t *hash_info, const u_char *pd,
                        offset = get_address_v5( pd, offset, hash_info);
 
        /* save server udp port and create upd conversation */
-                       if (( offset+ 2) > fd->cap_len){ 
+                       if (!BYTES_ARE_IN_FRAME(offset, 2)){ 
                                hash_info->state = Done;
                                return; 
                        }
@@ -884,7 +880,7 @@ static void display_ping_and_tracert( const u_char *pd, int offset,
                        col_append_str(fd, COL_INFO, ", Terminate Request");
                
                if ( tree)
-                       proto_tree_add_text(tree, offset, 1,
+                       proto_tree_add_text(tree, NullTVB, offset, 1,
                                (hash_info->command  == PING_COMMAND) ?
                                "Ping: End command" :
                                "Traceroute: End command");
@@ -894,7 +890,7 @@ static void display_ping_and_tracert( const u_char *pd, int offset,
                        col_append_str(fd, COL_INFO, ", Results");
 
                if ( tree){
-                       proto_tree_add_text(tree, offset, END_OF_FRAME,
+                       proto_tree_add_text(tree, NullTVB, offset, END_OF_FRAME,
                                (hash_info->command  == PING_COMMAND) ?
                                "Ping Results:" :
                                "Traceroute Results");
@@ -907,7 +903,7 @@ static void display_ping_and_tracert( const u_char *pd, int offset,
                                lineend = find_line_end(data, dataend, &eol);
                                linelen = lineend - data;
 
-                                       proto_tree_add_text( tree, offset, linelen,
+                                       proto_tree_add_text( tree, NullTVB, offset, linelen,
                                                format_text(data, linelen));
                                        offset += linelen;
                                        data = lineend;
@@ -929,6 +925,7 @@ static void call_next_dissector( const u_char *pd, int offset, frame_data *fd,
 /* payload, and restore the pi port after that is done.                        */
 
        guint32 *ptr;
+       tvbuff_t *tvb;
  
        if (( hash_info->command  == PING_COMMAND) ||
            ( hash_info->command  == TRACERT_COMMAND))
@@ -945,7 +942,8 @@ static void call_next_dissector( const u_char *pd, int offset, frame_data *fd,
                        ptr = &pi.srcport;
 
                *ptr = hash_info->port;
-               decode_tcp_ports( pd, offset, fd, tree, pi.srcport, pi.destport);
+               tvb = tvb_create_from_top(0);
+               decode_tcp_ports( tvb, offset, &pi, tree, pi.srcport, pi.destport);
                *ptr = TCP_PORT_SOCKS;
        }
 }                
@@ -960,9 +958,10 @@ dissect_socks(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
        socks_hash_entry_t *hash_info;
        conversation_t *conversation;
        
+       OLD_CHECK_DISPLAY_AS_DATA(proto_socks, pd, offset, fd, tree);
 
        conversation = find_conversation( &pi.src, &pi.dst, pi.ptype,
-               pi.srcport, pi.destport);
+               pi.srcport, pi.destport, 0);
 
        if ( conversation)                      /* conversation found */
                hash_info = conversation->data;
@@ -980,13 +979,13 @@ dissect_socks(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
                        hash_info->state = Done;
 
                conversation_new( &pi.src, &pi.dst, pi.ptype,
-                       pi.srcport, pi.destport, hash_info);
+                       pi.srcport, pi.destport, hash_info, 0);
        }
 
 /* display summary window information  */
 
        if (check_col(fd, COL_PROTOCOL))
-               col_add_str(fd, COL_PROTOCOL, "Socks");
+               col_set_str(fd, COL_PROTOCOL, "Socks");
 
        if (check_col(fd, COL_INFO)){
                if (( hash_info->version == 4) || ( hash_info->version == 5)){
@@ -994,7 +993,7 @@ dissect_socks(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
                                hash_info->version);
                }               
                else                    /* unknown version display error */
-                       col_add_str(fd, COL_INFO, "Unknown");
+                       col_set_str(fd, COL_INFO, "Unknown");
                
 
                if ( hash_info->command == PING_COMMAND)
@@ -1010,8 +1009,7 @@ dissect_socks(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
 
 /* run state machine if needed */
 
-       if ((hash_info->state != Done) && ( fd->num > last_row)){
-               last_row = fd->num;
+       if ((hash_info->state != Done) && ( !fd->flags.visited)){
 
                if ( hash_info->version == 4)
                        state_machine_v4( hash_info, pd, offset, fd);
@@ -1027,8 +1025,8 @@ dissect_socks(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
 /* if proto tree, decode and display */
 
        if (tree) {                     
-               ti = proto_tree_add_item( tree, proto_socks, offset,
-                       END_OF_FRAME, NULL, "Socks:" );
+               ti = proto_tree_add_item( tree, proto_socks, NullTVB, offset,
+                       END_OF_FRAME, FALSE );
 
                socks_tree = proto_item_add_subtree(ti, ett_socks);
 
@@ -1043,18 +1041,18 @@ dissect_socks(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
                                /* if past startup, add the faked stuff */
                if ( fd->num >  hash_info->start_done_row){
                                                /*  add info to tree */
-                       proto_tree_add_text( socks_tree, offset, 0,
+                       proto_tree_add_text( socks_tree, NullTVB, offset, 0,
                                "Command: %d (%s)", hash_info->command,
                                get_command_name(hash_info->command));
 
-                       proto_tree_add_item( socks_tree, hf_socks_ip_dst,
+                       proto_tree_add_ipv4( socks_tree, hf_socks_ip_dst, NullTVB,
                                        offset, 0, hash_info->dst_addr);
 
                                /* no fake address for ping & traceroute */
                                
                        if (( hash_info->command != PING_COMMAND) &&
                            ( hash_info->command != TRACERT_COMMAND)){
-                               proto_tree_add_item( socks_tree, hf_socks_dstport,
+                               proto_tree_add_uint( socks_tree, hf_socks_dstport, NullTVB,
                                        offset, 0, hash_info->port);
                        }
                }
@@ -1077,8 +1075,6 @@ static void socks_reinit( void){
 /* performed. Reset the highest row seen counter and re-initialize the */
 /* conversation memory chunks.                                         */
 
-       last_row = 0;                   
-       
        if (socks_vals)
                g_mem_chunk_destroy(socks_vals);
 
@@ -1155,7 +1151,5 @@ proto_reg_handoff_socks(void) {
 
        /* dissector install routine */ 
  
-       dissector_add("tcp.port", TCP_PORT_SOCKS, dissect_socks);
+       old_dissector_add("tcp.port", TCP_PORT_SOCKS, dissect_socks);
 }
-
-