2 * Routines for Microsoft Proxy packet dissection
3 * Copyright 2000, Jeffrey C. Foster <jfoste@woodward.com>
5 * $Id: packet-msproxy.c,v 1.29 2002/05/01 08:14:32 guy Exp $
7 * Ethereal - Network traffic analyzer
8 * By Gerald Combs <gerald@ethereal.com>
9 * Copyright 1998 Gerald Combs
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 * This was derived from the dante socks implementation source code.
26 * Most of the information came from common.h and msproxy_clientprotocol.c
28 * See http://www.inet.no/dante for more information
31 /************************************************************************
33 * Notes: These are possible command values. User input is welcome *
35 * Command = 0x040a - Remote host closed connection (maybe ?? ) *
36 * Command = 0x0411 - Remote host closed connection *
37 * Command = 0x0413 - Local host closed connection or SYN worked *
39 ************************************************************************/
48 #ifdef HAVE_SYS_TYPES_H
49 # include <sys/types.h>
52 #ifdef HAVE_NETINET_IN_H
53 # include <netinet/in.h>
60 #ifdef NEED_SNPRINTF_H
61 # include "snprintf.h"
64 #include <epan/packet.h>
65 #include <epan/resolv.h>
66 #include "alignment.h"
67 #include <epan/conversation.h>
69 #include "packet-tcp.h"
70 #include "packet-udp.h"
72 extern void udp_hash_add(guint16 proto,
73 void (*dissect)(const u_char *, int, frame_data *, proto_tree *));
76 static int proto_msproxy = -1;
78 static int ett_msproxy = -1;
79 static int ett_msproxy_name = -1;
81 static int hf_msproxy_cmd = -1;
82 static int hf_msproxy_clntport = -1;
84 static int hf_msproxy_dstaddr = -1;
86 static int hf_msproxy_srcport = -1;
87 static int hf_msproxy_dstport = -1;
88 static int hf_msproxy_serverport = -1;
89 static int hf_msproxy_serveraddr = -1;
90 static int hf_msproxy_bindport = -1;
91 static int hf_msproxy_bindaddr = -1;
92 static int hf_msproxy_boundport = -1;
93 static int hf_msproxy_bind_id = -1;
94 static int hf_msproxy_resolvaddr = -1;
96 static int hf_msproxy_server_int_addr = -1;
97 static int hf_msproxy_server_int_port = -1;
98 static int hf_msproxy_server_ext_addr = -1;
99 static int hf_msproxy_server_ext_port = -1;
101 static dissector_handle_t msproxy_sub_handle;
104 #define UDP_PORT_MSPROXY 1745
106 #define N_MSPROXY_HELLO 0x05 /* packet 1 from client */
107 #define N_MSPROXY_ACK 0x10 /* packet 1 from server */
108 #define N_MSPROXY_USERINFO_ACK 0x04 /* packet 2 from server */
109 #define N_MSPROXY_AUTH 0x47 /* packet 3 from client */
110 #define N_MSPROXY_RESOLVE 0x07 /* Resolve request */
113 /*$$$ 0x0500 was dante value, I see 0x05ff and 0x0500 */
115 #define MSPROXY_HELLO 0x0500
116 #define MSPROXY_HELLO_2 0x05ff
118 #define MSPROXY_HELLO_ACK 0x1000
120 #define MSPROXY_USERINFO 0x1000
121 #define MSPROXY_USERINFO_ACK 0x0400
123 #define MSPROXY_AUTH 0x4700
124 #define MSPROXY_AUTH_1_ACK 0x4714
125 #define MSPROXY_AUTH_2 0x4701
126 #define MSPROXY_AUTH_2_ACK 0x4715
127 #define MSPROXY_AUTH_2_ACK2 0x4716
129 #define MSPROXY_RESOLVE 0x070d
130 #define MSPROXY_RESOLVE_ACK 0x070f
132 #define MSPROXY_BIND 0x0704
133 #define MSPROXY_BIND_ACK 0x0706
135 #define MSPROXY_TCP_BIND 0x0707
136 #define MSPROXY_TCP_BIND_ACK 0x0708
138 #define MSPROXY_LISTEN 0x0406
140 #define MSPROXY_BINDINFO 0x0709
142 #define MSPROXY_BINDINFO_ACK 0x070a
144 #define MSPROXY_CONNECT 0x071e
145 #define MSPROXY_CONNECT_ACK 0x0703
147 #define MSPROXY_UDPASSOCIATE 0x0705
148 #define MSPROXY_UDPASSOCIATE_ACK 0x0706
150 #define MSPROXY_UDP_BIND_REQ 0x070b
152 #define MSPROXY_CONNECTED 0x042c
153 #define MSPROXY_SESSIONEND 0x251e
155 #define MSPROXY_BIND_AUTHFAILED 0x0804
156 #define MSPROXY_CONNECT_AUTHFAILED 0x081e
157 #define MSPROXY_CONNREFUSED 0x4 /* low 12 bits seem to vary. */
159 #define FROM_SERVER 1 /* direction of packet data for get_msproxy_cmd_name */
160 #define FROM_CLIENT 0
165 /*$$$ should this be the same as redirect_entry_t ?? */
166 /* then the add_conversation could just copy the structure */
167 /* using the same allocation (instance for you object guys) */
168 /* wouldn't work because there may be multiple child conversations */
169 /* from the same MSProxy conversation */
175 guint32 server_int_port;
180 /************** conversation hash stuff ***************/
182 #define hash_init_count 20
183 #define hash_val_length (sizeof(hash_entry_t))
185 static GMemChunk *vals = NULL;
190 guint32 server_int_port;
196 /************** negotiated conversation hash stuff ***************/
198 #define redirect_init_count 20
199 #define redirect_val_length (sizeof(redirect_entry_t))
201 static GMemChunk *redirect_vals = NULL;
204 static guint32 last_row= 0; /* used to see if packet is new */
206 static void msproxy_sub_dissector( tvbuff_t *tvb, packet_info *pinfo,
209 /* Conversation dissector called from TCP or UDP dissector. Decode and */
210 /* display the msproxy header, the pass the rest of the data to the tcp */
211 /* or udp port decode routine to handle the payload. */
214 redirect_entry_t *redirect_info;
215 conversation_t *conversation;
216 proto_tree *msp_tree;
219 conversation = find_conversation( &pinfo->src, &pinfo->dst,
220 pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
222 g_assert( conversation); /* should always find a conversation */
224 redirect_info = conversation_get_proto_data(conversation,
227 if (check_col(pinfo->cinfo, COL_PROTOCOL))
228 col_set_str(pinfo->cinfo, COL_PROTOCOL, "MS Proxy");
230 if (check_col(pinfo->cinfo, COL_INFO))
231 col_set_str(pinfo->cinfo, COL_INFO,
232 (( redirect_info->proto == PT_TCP) ? "TCP stream" :
236 ti = proto_tree_add_item( tree, proto_msproxy, tvb, 0, 0,
239 msp_tree = proto_item_add_subtree(ti, ett_msproxy);
241 proto_tree_add_uint( msp_tree, hf_msproxy_dstport, tvb, 0, 0,
242 redirect_info->remote_port);
244 proto_tree_add_ipv4( msp_tree, hf_msproxy_dstaddr, tvb, 0, 0,
245 redirect_info->remote_addr);
249 /* set pinfo->{src/dst port} and call the UDP sub-dissector lookup */
251 if ( pinfo->srcport == redirect_info->clnt_port)
252 ptr = &pinfo->destport;
254 ptr = &pinfo->srcport;
256 *ptr = redirect_info->remote_port;
258 if ( redirect_info->proto == PT_TCP)
259 decode_tcp_ports( tvb, 0, pinfo, tree, pinfo->srcport,
262 decode_udp_ports( tvb, 0, pinfo, tree, pinfo->srcport,
265 *ptr = redirect_info->server_int_port;
270 static void add_msproxy_conversation( packet_info *pinfo,
271 hash_entry_t *hash_info){
273 /* check to see if a conversation already exists, if it does assume */
274 /* it's our conversation and quit. Otherwise create a new conversation. */
275 /* Load the conversation dissector to our dissector and load the */
276 /* conversation data structure with the info needed to call the TCP or */
277 /* UDP port decoder. */
279 /* NOTE: Currently this assume that the conversation will be created */
280 /* during a packet from the server. If that changes, pinfo->src */
281 /* and pinfo->dst will not be correct and this routine will have */
284 conversation_t *conversation;
285 redirect_entry_t *new_conv_info;
287 if (pinfo->fd->flags.visited) {
289 * We've already processed this frame once, so we
290 * should already have done this.
295 conversation = find_conversation( &pinfo->src,
296 &pinfo->dst, hash_info->proto, hash_info->server_int_port,
297 hash_info->clnt_port, 0);
299 if ( !conversation) {
300 conversation = conversation_new( &pinfo->src, &pinfo->dst,
301 hash_info->proto, hash_info->server_int_port,
302 hash_info->clnt_port, 0);
304 conversation_set_dissector(conversation, msproxy_sub_handle);
306 new_conv_info = g_mem_chunk_alloc(redirect_vals);
308 new_conv_info->remote_addr = hash_info->dst_addr;
309 new_conv_info->clnt_port = hash_info->clnt_port;
310 new_conv_info->remote_port = hash_info->dst_port;
311 new_conv_info->server_int_port = hash_info->server_int_port;
312 new_conv_info->proto = hash_info->proto;
314 conversation_add_proto_data(conversation, proto_msproxy,
320 static int display_application_name(tvbuff_t *tvb, int offset,
323 /* display the application name in the proto tree. */
325 /* NOTE: this routine assumes that the tree pointer is valid (not NULL) */
329 length = tvb_strnlen( tvb, offset, 255);
330 proto_tree_add_text( tree, tvb, offset, length, "Application: %.*s",
331 length, tvb_get_ptr( tvb, offset, length));
337 static char *get_msproxy_cmd_name( int cmd, int direction) {
339 /* return the command name string for cmd */
342 case MSPROXY_HELLO_2:
343 case MSPROXY_HELLO: return "Hello";
345 /* MSPROXY_HELLO_ACK & MSPROXY_USERINFO have the same value (0x1000). */
346 /* So use the direction flag to determine which to use. */
348 case MSPROXY_USERINFO:
349 if ( direction == FROM_SERVER)
350 return "Hello Acknowledge";
353 case MSPROXY_USERINFO_ACK: return "User Info Acknowledge";
354 case MSPROXY_AUTH: return "Authentication";
355 case MSPROXY_AUTH_1_ACK: return "Authentication Acknowledge";
356 case MSPROXY_AUTH_2: return "Authentication 2";
357 case MSPROXY_AUTH_2_ACK: return "Authentication 2 Acknowledge";
358 case MSPROXY_RESOLVE: return "Resolve";
359 case MSPROXY_RESOLVE_ACK: return "Resolve Acknowledge";
360 case MSPROXY_BIND: return "Bind";
361 case MSPROXY_TCP_BIND: return "TCP Bind";
362 case MSPROXY_TCP_BIND_ACK: return "TCP Bind Acknowledge";
363 case MSPROXY_LISTEN: return "Listen";
364 case MSPROXY_BINDINFO: return "Bind Info";
365 case MSPROXY_BINDINFO_ACK: return "Bind Info Acknowledge";
366 case MSPROXY_CONNECT: return "Connect";
367 case MSPROXY_CONNECT_ACK: return "Connect Acknowledge";
368 case MSPROXY_UDPASSOCIATE: return "UDP Associate";
369 case MSPROXY_UDP_BIND_REQ: return "UDP Bind";
370 case MSPROXY_UDPASSOCIATE_ACK: return "Bind or Associate Acknowledge";
371 case MSPROXY_CONNECTED: return "Connected";
372 case MSPROXY_SESSIONEND: return "Session End";
374 default: return "Unknown";
380 static void dissect_user_info_2(tvbuff_t *tvb, int offset,
383 /* decode the user, application, computer name */
389 length = tvb_strnlen( tvb, offset, 255);
392 proto_tree_add_text( tree, tvb, offset, length + 1,
393 "User name: %.*s", length,
394 tvb_get_ptr( tvb, offset, length));
395 offset += length + 2;
397 length = tvb_strnlen( tvb, offset, 255);
400 proto_tree_add_text( tree, tvb, offset, length + 1,
401 "Application name: %.*s", length,
402 tvb_get_ptr( tvb, offset, length));
403 offset += length + 1;
405 length = tvb_strnlen( tvb, offset, 255);
408 proto_tree_add_text( tree, tvb, offset, length + 1,
409 "Client computer name: %.*s", length,
410 tvb_get_ptr( tvb, offset, length));
416 static void dissect_msproxy_request_1(tvbuff_t *tvb, int offset,
419 /* decode the request _1 structure */
424 dissect_user_info_2( tvb, offset, tree);
430 static void dissect_bind(tvbuff_t *tvb, int offset,
431 proto_tree *tree, hash_entry_t *conv_info) {
433 /* decode the bind request */
438 proto_tree_add_item( tree, hf_msproxy_bindaddr, tvb, offset, 4,
443 proto_tree_add_item( tree, hf_msproxy_bindport, tvb, offset, 2,
448 proto_tree_add_item( tree, hf_msproxy_clntport, tvb, offset, 2,
452 conv_info->clnt_port = tvb_get_ntohs( tvb, offset);
456 proto_tree_add_item( tree, hf_msproxy_boundport, tvb, offset, 2,
460 display_application_name( tvb, offset, tree);
466 static void dissect_auth(tvbuff_t *tvb, int offset,
469 /* decode the authorization request */
474 proto_tree_add_text( tree, tvb, offset, 7, "NTLMSSP signature: %.7s",
475 tvb_get_ptr( tvb, offset, 7));
482 static void dissect_tcp_bind(tvbuff_t *tvb, int offset,
483 proto_tree *tree, hash_entry_t *conv_info) {
485 /* decode the bind packet. Set the protocol type in the conversation */
486 /* information so the bind_info can use it to create the payload */
490 conv_info->proto = PT_TCP;
495 proto_tree_add_item( tree, hf_msproxy_bind_id, tvb, offset, 4,
499 proto_tree_add_item( tree, hf_msproxy_boundport, tvb, offset, 2,
503 display_application_name( tvb, offset, tree);
508 static void dissect_request_connect(tvbuff_t *tvb, int offset,
509 proto_tree *tree, hash_entry_t *conv_info) {
511 /* decode the connect request, display */
513 conv_info->proto = PT_TCP;
518 proto_tree_add_item( tree, hf_msproxy_dstport, tvb, offset, 2,
521 conv_info->dst_port = tvb_get_ntohs( tvb, offset);
525 proto_tree_add_item( tree, hf_msproxy_dstaddr, tvb, offset, 4,
528 tvb_memcpy( tvb, (guint8 *)&conv_info->dst_addr, offset, sizeof( guint32));
532 conv_info->clnt_port = tvb_get_ntohs( tvb, offset);
535 proto_tree_add_uint( tree, hf_msproxy_clntport, tvb, offset, 2,
536 conv_info->clnt_port);
540 display_application_name( tvb, offset, tree);
545 static void dissect_bind_info_ack(tvbuff_t *tvb, int offset, proto_tree *tree) {
547 /* decode the client bind info ack */
553 proto_tree_add_item( tree, hf_msproxy_bind_id, tvb, offset, 4,
557 proto_tree_add_item( tree, hf_msproxy_dstport, tvb, offset, 2,
561 proto_tree_add_item( tree, hf_msproxy_dstaddr, tvb, offset, 4,
565 proto_tree_add_item( tree, hf_msproxy_server_int_port, tvb,
569 proto_tree_add_item( tree, hf_msproxy_server_ext_port, tvb,
573 proto_tree_add_item( tree, hf_msproxy_server_ext_addr, tvb,
577 display_application_name( tvb, offset, tree);
582 static void dissect_request_resolve(tvbuff_t *tvb, int offset,
585 /* dissect the request resolve structure */
586 /* display a string with a length, characters encoding */
587 /* they are displayed under a tree with the name in Label variable */
588 /* return the length of the string and the length byte */
590 proto_tree *name_tree;
593 int length = tvb_get_guint8( tvb, offset);
596 ti = proto_tree_add_text(tree, tvb, offset, length + 1,
597 "Host Name: %.*s", length,
598 tvb_get_ptr( tvb, offset + 18, length));
600 name_tree = proto_item_add_subtree(ti, ett_msproxy_name);
602 proto_tree_add_text( name_tree, tvb, offset, 1, "Length: %d",
608 proto_tree_add_text( name_tree, tvb, offset, length, "String: %s",
609 tvb_get_ptr( tvb, offset, length));
615 static void dissect_udp_bind(tvbuff_t *tvb, int offset,
616 proto_tree *tree, hash_entry_t *conv_info) {
618 /* Dissect the udp bind request. Load the protocol id (PT_UDP) and the */
619 /* remote address so bind_info can use it to create conversation */
622 conv_info->proto = PT_UDP;
628 proto_tree_add_item( tree, hf_msproxy_bind_id, tvb, offset, 4,
634 proto_tree_add_item( tree, hf_msproxy_dstport, tvb, offset, 2,
639 proto_tree_add_item( tree, hf_msproxy_dstaddr, tvb, offset, 4,
645 display_application_name( tvb, offset, tree);
649 static void dissect_udp_assoc(tvbuff_t *tvb, int offset,
650 proto_tree *tree, hash_entry_t *conv_info) {
652 /* dissect the udp associate request. And load client port into */
653 /* conversation data structure for later. */
659 proto_tree_add_item( tree, hf_msproxy_clntport, tvb, offset, 2,
662 conv_info->clnt_port = tvb_get_ntohs( tvb, offset);
667 display_application_name( tvb, offset, tree);
671 static void dissect_msproxy_request(tvbuff_t *tvb,
672 proto_tree *tree, hash_entry_t *conv_info) {
678 proto_tree_add_text( tree, tvb, offset, 4, "Client id: 0x%0x",
679 tvb_get_letohl( tvb, offset));
682 proto_tree_add_text( tree, tvb, offset, 4, "Version: 0x%04x",
683 tvb_get_letohl( tvb, offset));
686 proto_tree_add_text( tree, tvb, offset, 4, "Server id: 0x%0x",
687 tvb_get_letohl( tvb, offset));
690 proto_tree_add_text( tree, tvb, offset, 1, "Server ack: %u",
691 tvb_get_guint8( tvb, offset));
694 proto_tree_add_text( tree, tvb, offset, 1, "Sequence Number: %u",
695 tvb_get_guint8( tvb, offset));
698 proto_tree_add_text( tree, tvb, offset, 4, "RWSP signature: %.4s",
699 tvb_get_ptr( tvb, offset, 4));
705 cmd = tvb_get_ntohs( tvb, offset);
708 proto_tree_add_uint_format( tree, hf_msproxy_cmd, tvb, offset, 2,
709 cmd, "Command: 0x%02x (%s)", cmd,
710 get_msproxy_cmd_name( cmd, FROM_CLIENT));
716 dissect_auth( tvb, offset, tree);
720 dissect_bind( tvb, offset, tree, conv_info);
723 case MSPROXY_UDP_BIND_REQ:
724 dissect_udp_bind( tvb, offset, tree, conv_info);
727 case MSPROXY_AUTH_2: /*$$ this is probably wrong place for this */
728 case MSPROXY_TCP_BIND:
729 dissect_tcp_bind( tvb, offset, tree, conv_info);
732 case MSPROXY_RESOLVE:
733 dissect_request_resolve( tvb, offset, tree);
736 case MSPROXY_CONNECT:
738 dissect_request_connect( tvb, offset, tree,
742 case MSPROXY_BINDINFO_ACK:
743 dissect_bind_info_ack( tvb, offset, tree);
747 case MSPROXY_HELLO_2:
748 dissect_msproxy_request_1( tvb, offset, tree);
751 case MSPROXY_UDPASSOCIATE:
752 dissect_udp_assoc( tvb, offset, tree, conv_info);
756 proto_tree_add_text( tree, tvb, offset, 0,
757 "Unhandled request command (report this, please)");
763 static void dissect_hello_ack(tvbuff_t *tvb, int offset, proto_tree *tree) {
765 /* decode the hello acknowledge packet */
770 proto_tree_add_item( tree, hf_msproxy_serverport, tvb, offset, 2,
774 proto_tree_add_item( tree, hf_msproxy_serveraddr, tvb, offset, 4,
782 static void dissect_user_info_ack(tvbuff_t *tvb, int offset,
785 /* decode the response _2 structure */
795 static void dissect_udpassociate_ack(tvbuff_t *tvb, int offset,
801 proto_tree_add_item( tree, hf_msproxy_bind_id, tvb, offset, 4,
805 proto_tree_add_item( tree, hf_msproxy_server_ext_port, tvb,
809 proto_tree_add_item( tree, hf_msproxy_server_ext_addr, tvb,
813 display_application_name( tvb, offset, tree);
819 static void dissect_auth_1_ack(tvbuff_t *tvb, int offset,
824 proto_tree_add_text( tree, tvb, offset, 7, "NTLMSSP signature: %.7s",
825 tvb_get_ptr( tvb, offset, 7));
828 /* XXX - always 255? */
829 proto_tree_add_text( tree, tvb, offset, 255, "NT domain: %.255s",
830 tvb_get_ptr( tvb, offset, 255));
836 static void dissect_msproxy_response_4( tvbuff_t *tvb, int offset,
839 /* decode the response _4 structure */
846 static void dissect_connect_ack( tvbuff_t *tvb, int offset, packet_info *pinfo,
847 proto_tree *tree, hash_entry_t *conv_info) {
849 /* decode the connect ack packet */
853 proto_tree_add_item( tree, hf_msproxy_server_int_port, tvb,
857 conv_info->proto = PT_TCP;
858 conv_info->server_int_port = tvb_get_ntohs( tvb, offset);
862 proto_tree_add_item( tree, hf_msproxy_server_int_addr, tvb,
866 proto_tree_add_item( tree, hf_msproxy_server_ext_port, tvb,
870 proto_tree_add_item( tree, hf_msproxy_server_ext_addr, tvb,
874 display_application_name( tvb, offset, tree);
877 add_msproxy_conversation( pinfo, conv_info);
882 static void dissect_tcp_bind_ack( tvbuff_t *tvb, int offset, proto_tree *tree) {
884 /* decode the tcp bind */
889 proto_tree_add_item( tree, hf_msproxy_bind_id, tvb, offset, 4,
893 proto_tree_add_uint( tree, hf_msproxy_server_int_port, tvb,
897 proto_tree_add_item( tree, hf_msproxy_server_ext_port, tvb,
901 proto_tree_add_item( tree, hf_msproxy_server_ext_addr, tvb,
906 display_application_name( tvb, offset, tree);
912 static void dissect_bind_info( tvbuff_t *tvb, int offset, packet_info *pinfo,
913 proto_tree *tree, hash_entry_t *conv_info) {
915 /* decode the Bind info response from server */
920 proto_tree_add_item( tree, hf_msproxy_bind_id, tvb, offset, 4,
925 conv_info->dst_port = tvb_get_ntohs( tvb, offset);
927 proto_tree_add_uint( tree, hf_msproxy_dstport, tvb, offset, 2,
928 conv_info->dst_port);
931 tvb_memcpy( tvb, (guint8 *)&conv_info->dst_addr, offset, sizeof( guint32));
933 proto_tree_add_item( tree, hf_msproxy_dstaddr, tvb, offset, 4,
937 conv_info->server_int_port = tvb_get_ntohs( tvb, offset);
939 proto_tree_add_uint( tree, hf_msproxy_server_int_port, tvb,
940 offset, 2, conv_info->server_int_port);
944 proto_tree_add_item( tree, hf_msproxy_server_ext_port, tvb,
948 proto_tree_add_item( tree, hf_msproxy_server_ext_addr, tvb,
952 display_application_name( tvb, offset, tree);
956 add_msproxy_conversation( pinfo, conv_info);
961 static void dissect_resolve(tvbuff_t *tvb, int offset, proto_tree *tree) {
963 /* dissect the response resolve structure */
964 /* display a string with a length, characters encoding */
965 /* they are displayed under a tree with the name in Label variable */
966 /* return the length of the string and the length byte */
971 addr_offset = tvb_get_guint8( tvb, offset);
973 proto_tree_add_text( tree, tvb, offset, 1, "Address offset: %d",
980 offset += addr_offset;
982 proto_tree_add_item( tree, hf_msproxy_resolvaddr, tvb, offset, 4,
989 static void dissect_msproxy_response(tvbuff_t *tvb, packet_info *pinfo,
990 proto_tree *tree, hash_entry_t *conv_info) {
996 proto_tree_add_text( tree, tvb, offset, 4, "Client id: 0x%0x",
997 tvb_get_letohl( tvb, offset));
1000 proto_tree_add_text( tree, tvb, offset, 4, "Version: 0x%04x",
1001 tvb_get_letohl( tvb, offset));
1004 proto_tree_add_text( tree, tvb, offset, 4, "Server id: 0x%04x",
1005 tvb_get_letohl( tvb, offset));
1008 proto_tree_add_text( tree, tvb, offset, 1, "Client ack: 0x%02x",
1009 tvb_get_guint8( tvb, offset));
1012 proto_tree_add_text( tree, tvb, offset, 1, "Sequence Number: 0x%02x",
1013 tvb_get_guint8( tvb, offset));
1017 proto_tree_add_text( tree, tvb, offset, 4, "RWSP signature: %.4s",
1018 tvb_get_ptr( tvb, offset, 4));
1025 cmd = tvb_get_ntohs( tvb, offset);
1028 proto_tree_add_uint_format( tree, hf_msproxy_cmd, tvb, offset, 2,
1029 cmd, "Command: 0x%02x (%s)", cmd,
1030 get_msproxy_cmd_name( cmd, FROM_SERVER));
1034 case MSPROXY_HELLO_ACK:
1035 dissect_hello_ack( tvb, offset, tree);
1038 case MSPROXY_USERINFO_ACK:
1039 dissect_user_info_ack( tvb, offset, tree);
1042 case MSPROXY_AUTH_1_ACK:
1043 dissect_auth_1_ack( tvb, offset, tree);
1046 /* this also handle the MSPROXY_BIND_ACK ??? check this */
1048 case MSPROXY_UDPASSOCIATE_ACK:
1049 dissect_udpassociate_ack( tvb, offset, tree);
1052 case MSPROXY_AUTH_2_ACK:
1053 case MSPROXY_AUTH_2_ACK2:
1054 dissect_msproxy_response_4( tvb, offset, tree);
1057 case MSPROXY_TCP_BIND_ACK:
1058 dissect_tcp_bind_ack( tvb, offset, tree);
1061 case MSPROXY_CONNECT_ACK:
1062 dissect_connect_ack( tvb, offset, pinfo, tree,
1066 case MSPROXY_BINDINFO:
1067 dissect_bind_info( tvb, offset, pinfo, tree, conv_info);
1070 case MSPROXY_RESOLVE_ACK:
1071 dissect_resolve( tvb, offset, tree);
1074 case MSPROXY_CONNECT_AUTHFAILED:
1075 case MSPROXY_BIND_AUTHFAILED:
1076 proto_tree_add_text( tree, tvb, offset, 0, "No know information (help wanted)");
1082 (((cmd >> 8) == MSPROXY_CONNREFUSED) ||
1083 ((cmd >> 12) == MSPROXY_CONNREFUSED)))
1084 proto_tree_add_text( tree, tvb, offset, 0,
1085 "No know information (help wanted)");
1088 proto_tree_add_text( tree, tvb, offset, 0,
1089 "Unhandled response command (report this, please)");
1097 static void dissect_msproxy(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
1100 proto_tree *msproxy_tree = NULL;
1105 hash_entry_t *hash_info;
1106 conversation_t *conversation;
1108 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1109 col_set_str(pinfo->cinfo, COL_PROTOCOL, "MSproxy");
1110 if (check_col(pinfo->cinfo, COL_INFO))
1111 col_clear(pinfo->cinfo, COL_INFO);
1113 conversation = find_conversation( &pinfo->src, &pinfo->dst,
1114 pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
1116 if ( !conversation) {
1117 conversation = conversation_new( &pinfo->src, &pinfo->dst,
1118 pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
1120 hash_info = conversation_get_proto_data(conversation, proto_msproxy);
1122 hash_info = g_mem_chunk_alloc(vals);
1123 conversation_add_proto_data(conversation, proto_msproxy,
1127 if (check_col(pinfo->cinfo, COL_INFO)){
1129 cmd = tvb_get_ntohs( tvb, 36);
1131 if ( pinfo->srcport == UDP_PORT_MSPROXY)
1132 col_add_fstr( pinfo->cinfo, COL_INFO, "Server message: %s",
1133 get_msproxy_cmd_name( cmd, FROM_SERVER));
1135 col_add_fstr(pinfo->cinfo, COL_INFO, "Client message: %s",
1136 get_msproxy_cmd_name( cmd, FROM_CLIENT));
1140 if (tree) { /* if proto tree, decode data */
1141 ti = proto_tree_add_item( tree, proto_msproxy, tvb, 0, -1,
1144 msproxy_tree = proto_item_add_subtree(ti, ett_msproxy);
1147 if ( pinfo->srcport == UDP_PORT_MSPROXY)
1148 dissect_msproxy_response( tvb, pinfo, msproxy_tree, hash_info);
1150 dissect_msproxy_request( tvb, msproxy_tree, hash_info);
1155 static void msproxy_reinit( void){
1157 /* Do the cleanup work when a new pass through the packet list is */
1158 /* performed. Reset the highest row seen counter and re-initialize the */
1159 /* conversation memory chunks. */
1164 g_mem_chunk_destroy(vals);
1166 vals = g_mem_chunk_new("msproxy_vals", hash_val_length,
1167 hash_init_count * hash_val_length,
1171 g_mem_chunk_destroy(redirect_vals);
1173 redirect_vals = g_mem_chunk_new("msproxy_redirect_vals", redirect_val_length,
1174 redirect_init_count * redirect_val_length,
1181 proto_register_msproxy( void){
1183 /* Prep the msproxy protocol, for now, just register it */
1185 static gint *ett[] = {
1189 static hf_register_info hf[] = {
1192 { "Command", "msproxy.command", FT_UINT16, BASE_DEC,
1193 NULL, 0x0, "", HFILL
1197 { &hf_msproxy_dstaddr,
1198 { "Destination Address", "msproxy.dstaddr", FT_IPv4, BASE_NONE, NULL,
1203 { &hf_msproxy_srcport,
1204 { "Source Port", "msproxy.srcport", FT_UINT16,
1205 BASE_DEC, NULL, 0x0, "", HFILL
1208 { &hf_msproxy_dstport,
1209 { "Destination Port", "msproxy.dstport", FT_UINT16,
1210 BASE_DEC, NULL, 0x0, "", HFILL
1213 { &hf_msproxy_clntport,
1214 { "Client Port", "msproxy.clntport", FT_UINT16,
1215 BASE_DEC, NULL, 0x0, "", HFILL
1218 { &hf_msproxy_server_ext_addr,
1219 { "Server External Address", "msproxy.server_ext_addr", FT_IPv4, BASE_NONE, NULL,
1224 { &hf_msproxy_server_ext_port,
1225 { "Server External Port", "msproxy.server_ext_port", FT_UINT16,
1226 BASE_DEC, NULL, 0x0, "", HFILL
1230 { &hf_msproxy_server_int_addr,
1231 { "Server Internal Address", "msproxy.server_int_addr", FT_IPv4, BASE_NONE, NULL,
1236 { &hf_msproxy_server_int_port,
1237 { "Server Internal Port", "msproxy.server_int_port", FT_UINT16,
1238 BASE_DEC, NULL, 0x0, "", HFILL
1241 { &hf_msproxy_serverport,
1242 { "Server Port", "msproxy.serverport", FT_UINT16,
1243 BASE_DEC, NULL, 0x0, "", HFILL
1246 { &hf_msproxy_bindport,
1247 { "Bind Port", "msproxy.bindport", FT_UINT16,
1248 BASE_DEC, NULL, 0x0, "", HFILL
1251 { &hf_msproxy_boundport,
1252 { "Bound Port", "msproxy.boundport", FT_UINT16,
1253 BASE_DEC, NULL, 0x0, "", HFILL
1256 { &hf_msproxy_serveraddr,
1257 { "Server Address", "msproxy.serveraddr", FT_IPv4, BASE_NONE, NULL,
1261 { &hf_msproxy_bindaddr,
1262 { "Destination", "msproxy.bindaddr", FT_IPv4, BASE_NONE, NULL,
1266 { &hf_msproxy_bind_id,
1267 { "Bound Port Id", "msproxy.bindid", FT_UINT32,
1268 BASE_HEX, NULL, 0x0, "", HFILL
1271 { &hf_msproxy_resolvaddr,
1272 { "Address", "msproxy.resolvaddr", FT_IPv4, BASE_NONE, NULL,
1279 proto_msproxy = proto_register_protocol( "MS Proxy Protocol",
1280 "MS Proxy", "msproxy");
1282 proto_register_field_array(proto_msproxy, hf, array_length(hf));
1283 proto_register_subtree_array(ett, array_length(ett));
1285 register_init_routine( &msproxy_reinit); /* register re-init routine */
1287 msproxy_sub_handle = create_dissector_handle(msproxy_sub_dissector,
1293 proto_reg_handoff_msproxy(void) {
1295 /* dissector install routine */
1297 dissector_handle_t msproxy_handle;
1299 msproxy_handle = create_dissector_handle(dissect_msproxy,
1301 dissector_add("udp.port", UDP_PORT_MSPROXY, msproxy_handle);