static void socks_udp_dissector(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { /* Conversation dissector called from UDP dissector. Decode and display */ /* the socks header, the pass the rest of the data to the udp port */ /* decode routine to handle the payload. */ int offset = 0; guint32 *ptr; socks_hash_entry_t *hash_info; conversation_t *conversation; proto_tree *socks_tree; proto_item *ti; conversation = find_conversation( pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype, pinfo->srcport, pinfo->destport, 0); DISSECTOR_ASSERT( conversation); /* should always find a conversation */ hash_info = (socks_hash_entry_t *)conversation_get_proto_data(conversation, proto_socks); col_set_str(pinfo->cinfo, COL_PROTOCOL, "Socks"); col_set_str(pinfo->cinfo, COL_INFO, "Version: 5, UDP Associated packet"); if ( tree) { ti = proto_tree_add_protocol_format( tree, proto_socks, tvb, offset, -1, "Socks" ); socks_tree = proto_item_add_subtree(ti, ett_socks); proto_tree_add_item(socks_tree, hf_socks_reserved2, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(socks_tree, hf_socks_fragment_number, tvb, offset, 1, ENC_NA); offset += 1; offset = display_address( tvb, offset, socks_tree); hash_info->udp_remote_port = tvb_get_ntohs(tvb, offset); proto_tree_add_uint( socks_tree, hf_socks_dstport, tvb, offset, 2, hash_info->udp_remote_port); offset += 2; } else { /* no tree, skip past the socks header */ offset += 3; offset = get_address_v5( tvb, offset, 0) + 2; } /* set pi src/dst port and call the udp sub-dissector lookup */ if ( pinfo->srcport == hash_info->port) ptr = &pinfo->destport; else ptr = &pinfo->srcport; *ptr = hash_info->udp_remote_port; decode_udp_ports( tvb, offset, pinfo, tree, pinfo->srcport, pinfo->destport, -1); *ptr = hash_info->udp_port; }
static void state_machine_v5( socks_hash_entry_t *hash_info, tvbuff_t *tvb, int offset, packet_info *pinfo) { /* Decode V5 protocol. This is done on the first pass through the */ /* list. Based upon the current state, decode the packet and determine */ /* what the next state should be. If we had per packet information, */ /* this would be the place to load them up. */ int temp; if ( hash_info->state == None) { col_append_str(pinfo->cinfo, COL_INFO, " Connect to server request"); hash_info->state = Connecting; /* change state */ hash_info->connect_row = get_packet_ptr; temp = tvb_get_guint8(tvb, offset + 1); /* skip past auth methods */ offset = hash_info->connect_offset = offset + 1 + temp; } else if ( hash_info->state == Connecting){ guint AuthMethod = tvb_get_guint8(tvb, offset + 1); col_append_str(pinfo->cinfo, COL_INFO, " Connect to server response"); hash_info->auth_method_row = get_packet_ptr; if ( AuthMethod == NO_AUTHENTICATION) hash_info->state = V5Command; else if ( AuthMethod == USER_NAME_AUTHENTICATION) hash_info->state = UserNameAuth; else if ( AuthMethod == GSS_API_AUTHENTICATION) hash_info->state = GssApiAuth; else hash_info->state = Done; /*Auth failed or error*/ } else if ( hash_info->state == V5Command) { /* Handle V5 Command */ /** ?? guint temp; **/ hash_info->command = tvb_get_guint8(tvb, offset + 1); /* get command */ if (check_col(pinfo->cinfo, COL_INFO)) col_append_fstr(pinfo->cinfo, COL_INFO, " Command Request - %s", get_command_name(hash_info->command)); hash_info->state = V5Reply; hash_info->command_row = get_packet_ptr; offset += 3; /* skip to address type */ offset = get_address_v5(tvb, offset, hash_info); /** temp = tvb_get_guint8(tvb, offset); XX: what was this for ? **/ if (( hash_info->command == CONNECT_COMMAND) || ( hash_info->command == UDP_ASSOCIATE_COMMAND)) /* get remote port */ hash_info->port = tvb_get_ntohs(tvb, offset); } else if ( hash_info->state == V5Reply) { /* V5 Command Reply */ if (check_col(pinfo->cinfo, COL_INFO)) col_append_fstr(pinfo->cinfo, COL_INFO, " Command Response - %s", get_command_name(hash_info->command)); hash_info->cmd_reply_row = get_packet_ptr; if (( hash_info->command == CONNECT_COMMAND) || (hash_info->command == PING_COMMAND) || (hash_info->command == TRACERT_COMMAND)) hash_info->state = Done; else if ( hash_info->command == BIND_COMMAND) hash_info->state = V5BindReply; else if ( hash_info->command == UDP_ASSOCIATE_COMMAND){ offset += 3; /* skip to address type */ offset = get_address_v5(tvb, offset, hash_info); /* save server udp port and create udp conversation */ hash_info->udp_port = tvb_get_ntohs(tvb, offset); if (!pinfo->fd->flags.visited) new_udp_conversation( hash_info, pinfo); /*XXX may need else statement to handle unknowns and generate error message */ } } else if ( hash_info->state == V5BindReply) { /* V5 Bind Second Reply */ col_append_str(pinfo->cinfo, COL_INFO, " Command Response: Bind remote host info"); hash_info->bind_reply_row = get_packet_ptr; hash_info->state = Done; } else if ( hash_info->state == UserNameAuth) { /* Handle V5 User Auth*/ col_append_str(pinfo->cinfo, COL_INFO, " User authentication request"); hash_info->user_name_auth_row = get_packet_ptr; hash_info->state = UserNameAuthReply; } else if ( hash_info->state == GssApiAuth) { col_append_str(pinfo->cinfo, COL_INFO, " GSSAPI Authentication request"); hash_info->gssapi_auth_row = get_packet_ptr; hash_info->state = GssApiAuthReply; } else if ( hash_info->state == GssApiAuthReply) { if (tvb_get_guint8(tvb, offset+1) == 0xFF) { col_append_str(pinfo->cinfo, COL_INFO, " GSSAPI Authentication failure"); hash_info->gssapi_auth_failure_row = get_packet_ptr; } else { col_append_str(pinfo->cinfo, COL_INFO, " GSSAPI Authentication reply"); if (tvb_get_ntohs(tvb, offset+2) == 0) hash_info->state = V5Command; else hash_info->state = GssApiAuth; hash_info->gssapi_auth_reply_row = get_packet_ptr; } } else if ( hash_info->state == UserNameAuthReply){ /* V5 User Auth reply */ hash_info->auth_version = get_packet_ptr; col_append_str(pinfo->cinfo, COL_INFO, " User authentication reply"); hash_info->state = V5Command; } }