2 * Routines for Microsoft Proxy packet dissection
3 * Copyright 2000, Jeffrey C. Foster <jfoste@woodward.com>
5 * $Id: packet-msproxy.c,v 1.22 2001/09/03 10:33:05 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.
26 * This was derived from the dante socks implementation source code.
27 * Most of the information came from common.h and msproxy_clientprotocol.c
29 * See http://www.inet.no/dante for more information
33 /************************************************************************
35 * Notes: These are possible command values. User input is welcome *
37 * Command = 0x040a - Remote host closed connection (maybe ?? ) *
38 * Command = 0x0411 - Remote host closed connection *
39 * Command = 0x0413 - Local host closed connection or SYN worked *
41 ************************************************************************/
50 #ifdef HAVE_SYS_TYPES_H
51 # include <sys/types.h>
54 #ifdef HAVE_NETINET_IN_H
55 # include <netinet/in.h>
62 #ifdef NEED_SNPRINTF_H
63 # include "snprintf.h"
68 #include "alignment.h"
69 #include "conversation.h"
71 #include "packet-tcp.h"
72 #include "packet-udp.h"
74 extern void udp_hash_add(guint16 proto,
75 void (*dissect)(const u_char *, int, frame_data *, proto_tree *));
78 static int proto_msproxy = -1;
80 static int ett_msproxy = -1;
81 static int ett_msproxy_name = -1;
83 static int hf_msproxy_cmd = -1;
84 static int hf_msproxy_clntport = -1;
86 static int hf_msproxy_dstaddr = -1;
88 static int hf_msproxy_srcport = -1;
89 static int hf_msproxy_dstport = -1;
90 static int hf_msproxy_serverport = -1;
91 static int hf_msproxy_serveraddr = -1;
92 static int hf_msproxy_bindport = -1;
93 static int hf_msproxy_bindaddr = -1;
94 static int hf_msproxy_boundport = -1;
95 static int hf_msproxy_bind_id = -1;
96 static int hf_msproxy_resolvaddr = -1;
98 static int hf_msproxy_server_int_addr = -1;
99 static int hf_msproxy_server_int_port = -1;
100 static int hf_msproxy_server_ext_addr = -1;
101 static int hf_msproxy_server_ext_port = -1;
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 socks 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->fd, COL_PROTOCOL))
228 col_set_str(pinfo->fd, COL_PROTOCOL, "MS Proxy");
230 if (check_col(pinfo->fd, COL_INFO))
231 col_set_str(pinfo->fd, 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_dissector);
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,
321 packet_info *pinfo, proto_tree *tree) {
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, packet_info *pinfo,
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,
417 packet_info *pinfo, proto_tree *tree) {
419 /* decode the request _1 structure */
424 dissect_user_info_2( tvb, offset, pinfo, tree);
430 static void dissect_bind(tvbuff_t *tvb, int offset, packet_info *pinfo,
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, pinfo, tree);
466 static void dissect_auth(tvbuff_t *tvb, int offset,
467 packet_info *pinfo, proto_tree *tree) {
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 packet_info *pinfo, 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, pinfo, tree);
508 static void dissect_request_connect(tvbuff_t *tvb, int offset,
509 packet_info *pinfo, 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, pinfo, tree);
545 static void dissect_bind_info_ack(tvbuff_t *tvb, int offset, packet_info *pinfo,
546 proto_tree *tree, hash_entry_t *conv_info) {
548 /* decode the client bind info ack */
554 proto_tree_add_item( tree, hf_msproxy_bind_id, tvb, offset, 4,
558 proto_tree_add_item( tree, hf_msproxy_dstport, tvb, offset, 2,
562 proto_tree_add_item( tree, hf_msproxy_dstaddr, tvb, offset, 4,
566 proto_tree_add_item( tree, hf_msproxy_server_int_port, tvb,
570 proto_tree_add_item( tree, hf_msproxy_server_ext_port, tvb,
574 proto_tree_add_item( tree, hf_msproxy_server_ext_addr, tvb,
578 display_application_name( tvb, offset, pinfo, tree);
583 static void dissect_request_resolve(tvbuff_t *tvb, int offset,
584 packet_info *pinfo, proto_tree *tree) {
586 /* dissect the request resolve structure */
587 /* display a string with a length, characters encoding */
588 /* they are displayed under a tree with the name in Label variable */
589 /* return the length of the string and the length byte */
591 proto_tree *name_tree;
594 int length = tvb_get_guint8( tvb, offset);
597 ti = proto_tree_add_text(tree, tvb, offset, length + 1,
598 "Host Name: %.*s", length,
599 tvb_get_ptr( tvb, offset + 18, length));
601 name_tree = proto_item_add_subtree(ti, ett_msproxy_name);
603 proto_tree_add_text( name_tree, tvb, offset, 1, "Length: %d",
609 proto_tree_add_text( name_tree, tvb, offset, length, "String: %s",
610 tvb_get_ptr( tvb, offset, length));
616 static void dissect_udp_bind(tvbuff_t *tvb, int offset,
617 packet_info *pinfo, proto_tree *tree, hash_entry_t *conv_info) {
619 /* Dissect the udp bind request. Load the protocol id (PT_UDP) and the */
620 /* remote address so bind_info can use it to create conversation */
623 conv_info->proto = PT_UDP;
629 proto_tree_add_item( tree, hf_msproxy_bind_id, tvb, offset, 4,
635 proto_tree_add_item( tree, hf_msproxy_dstport, tvb, offset, 2,
640 proto_tree_add_ipv4( tree, hf_msproxy_dstaddr, tvb, offset, 4,
646 display_application_name( tvb, offset, pinfo, tree);
650 static void dissect_udp_assoc(tvbuff_t *tvb, int offset,
651 packet_info *pinfo, proto_tree *tree, hash_entry_t *conv_info) {
653 /* dissect the udp associate request. And load client port into */
654 /* conversation data structure for later. */
660 proto_tree_add_item( tree, hf_msproxy_clntport, tvb, offset, 2,
663 conv_info->clnt_port = tvb_get_ntohs( tvb, offset);
668 display_application_name( tvb, offset, pinfo, tree);
672 static void dissect_msproxy_request(tvbuff_t *tvb, packet_info *pinfo,
673 proto_tree *tree, hash_entry_t *conv_info) {
679 proto_tree_add_text( tree, tvb, offset, 4, "Client id: 0x%0x",
680 tvb_get_letohl( tvb, offset));
683 proto_tree_add_text( tree, tvb, offset, 4, "Version: 0x%04x",
684 tvb_get_letohl( tvb, offset));
687 proto_tree_add_text( tree, tvb, offset, 4, "Server id: 0x%0x",
688 tvb_get_letohl( tvb, offset));
691 proto_tree_add_text( tree, tvb, offset, 1, "Server ack: %u",
692 tvb_get_guint8( tvb, offset));
695 proto_tree_add_text( tree, tvb, offset, 1, "Sequence Number: %u",
696 tvb_get_guint8( tvb, offset));
699 proto_tree_add_text( tree, tvb, offset, 4, "RWSP signature: %.4s",
700 tvb_get_ptr( tvb, offset, 4));
706 cmd = tvb_get_ntohs( tvb, offset);
709 proto_tree_add_uint_format( tree, hf_msproxy_cmd, tvb, offset, 2,
710 cmd, "Command: 0x%02x (%s)", cmd,
711 get_msproxy_cmd_name( cmd, FROM_CLIENT));
717 dissect_auth( tvb, offset, pinfo, tree);
721 dissect_bind( tvb, offset, pinfo, tree, conv_info);
724 case MSPROXY_UDP_BIND_REQ:
725 dissect_udp_bind( tvb, offset, pinfo, tree, conv_info);
728 case MSPROXY_AUTH_2: /*$$ this is probably wrong place for this */
729 case MSPROXY_TCP_BIND:
730 dissect_tcp_bind( tvb, offset, pinfo, tree, conv_info);
733 case MSPROXY_RESOLVE:
734 dissect_request_resolve( tvb, offset, pinfo, tree);
737 case MSPROXY_CONNECT:
739 dissect_request_connect( tvb, offset, pinfo, tree,
743 case MSPROXY_BINDINFO_ACK:
744 dissect_bind_info_ack( tvb, offset, pinfo, tree,
749 case MSPROXY_HELLO_2:
750 dissect_msproxy_request_1( tvb, offset, pinfo, tree);
753 case MSPROXY_UDPASSOCIATE:
754 dissect_udp_assoc( tvb, offset, pinfo, tree, conv_info);
758 proto_tree_add_text( tree, tvb, offset, 0,
759 "Unhandled request command (report this, please)");
765 static void dissect_hello_ack(tvbuff_t *tvb, int offset, packet_info *pinfo,
766 proto_tree *tree, hash_entry_t *conv_info) {
768 /* decode the hello acknowledge packet */
773 proto_tree_add_item( tree, hf_msproxy_serverport, tvb, offset, 2,
777 proto_tree_add_item( tree, hf_msproxy_serveraddr, tvb, offset, 4,
785 static void dissect_user_info_ack(tvbuff_t *tvb, int offset,
786 packet_info *pinfo, proto_tree *tree) {
788 /* decode the response _2 structure */
798 static void dissect_udpassociate_ack(tvbuff_t *tvb, int offset,
799 packet_info *pinfo, proto_tree *tree) {
804 proto_tree_add_item( tree, hf_msproxy_bind_id, tvb, offset, 4,
808 proto_tree_add_item( tree, hf_msproxy_server_ext_port, tvb,
812 proto_tree_add_item( tree, hf_msproxy_server_ext_addr, tvb,
816 display_application_name( tvb, offset, pinfo, tree);
822 static void dissect_auth_1_ack(tvbuff_t *tvb, int offset, packet_info *pinfo,
827 proto_tree_add_text( tree, tvb, offset, 7, "NTLMSSP signature: %.7s",
828 tvb_get_ptr( tvb, offset, 7));
831 /* XXX - always 255? */
832 proto_tree_add_text( tree, tvb, offset, 255, "NT domain: %.255s",
833 tvb_get_ptr( tvb, offset, 255));
839 static void dissect_msproxy_response_4( tvbuff_t *tvb, int offset,
840 packet_info *pinfo, proto_tree *tree) {
842 /* decode the response _4 structure */
849 static void dissect_connect_ack( tvbuff_t *tvb, int offset, packet_info *pinfo,
850 proto_tree *tree, hash_entry_t *conv_info) {
852 /* decode the connect ack packet */
856 proto_tree_add_item( tree, hf_msproxy_server_int_port, tvb,
860 conv_info->proto = PT_TCP;
861 conv_info->server_int_port = tvb_get_ntohs( tvb, offset);
865 proto_tree_add_item( tree, hf_msproxy_server_int_addr, tvb,
869 proto_tree_add_item( tree, hf_msproxy_server_ext_port, tvb,
873 proto_tree_add_item( tree, hf_msproxy_server_ext_addr, tvb,
877 display_application_name( tvb, offset, pinfo, tree);
880 add_msproxy_conversation( pinfo, conv_info);
885 static void dissect_tcp_bind_ack( tvbuff_t *tvb, int offset, packet_info *pinfo,
888 /* decode the tcp bind */
893 proto_tree_add_item( tree, hf_msproxy_bind_id, tvb, offset, 4,
897 proto_tree_add_uint( tree, hf_msproxy_server_int_port, tvb,
901 proto_tree_add_item( tree, hf_msproxy_server_ext_port, tvb,
905 proto_tree_add_item( tree, hf_msproxy_server_ext_addr, tvb,
910 display_application_name( tvb, offset, pinfo, tree);
916 static void dissect_bind_info( tvbuff_t *tvb, int offset, packet_info *pinfo,
917 proto_tree *tree, hash_entry_t *conv_info) {
919 /* decode the Bind info response from server */
924 proto_tree_add_item( tree, hf_msproxy_bind_id, tvb, offset, 4,
929 conv_info->dst_port = tvb_get_ntohs( tvb, offset);
931 proto_tree_add_uint( tree, hf_msproxy_dstport, tvb, offset, 2,
932 conv_info->dst_port);
935 tvb_memcpy( tvb, (guint8 *)&conv_info->dst_addr, offset, sizeof( guint32));
937 proto_tree_add_item( tree, hf_msproxy_dstaddr, tvb, offset, 4,
941 conv_info->server_int_port = tvb_get_ntohs( tvb, offset);
943 proto_tree_add_uint( tree, hf_msproxy_server_int_port, tvb,
944 offset, 2, conv_info->server_int_port);
948 proto_tree_add_item( tree, hf_msproxy_server_ext_port, tvb,
952 proto_tree_add_item( tree, hf_msproxy_server_ext_addr, tvb,
956 display_application_name( tvb, offset, pinfo, tree);
960 add_msproxy_conversation( pinfo, conv_info);
965 static void dissect_resolve(tvbuff_t *tvb, int offset, packet_info *pinfo,
968 /* dissect the response resolve structure */
969 /* display a string with a length, characters encoding */
970 /* they are displayed under a tree with the name in Label variable */
971 /* return the length of the string and the length byte */
976 addr_offset = tvb_get_guint8( tvb, offset);
978 proto_tree_add_text( tree, tvb, offset, 1, "Address offset: %d",
985 offset += addr_offset;
987 proto_tree_add_item( tree, hf_msproxy_resolvaddr, tvb, offset, 4,
994 static void dissect_msproxy_response(tvbuff_t *tvb, packet_info *pinfo,
995 proto_tree *tree, hash_entry_t *conv_info) {
1001 proto_tree_add_text( tree, tvb, offset, 4, "Client id: 0x%0x",
1002 tvb_get_letohl( tvb, offset));
1005 proto_tree_add_text( tree, tvb, offset, 4, "Version: 0x%04x",
1006 tvb_get_letohl( tvb, offset));
1009 proto_tree_add_text( tree, tvb, offset, 4, "Server id: 0x%04x",
1010 tvb_get_letohl( tvb, offset));
1013 proto_tree_add_text( tree, tvb, offset, 1, "Client ack: 0x%02x",
1014 tvb_get_guint8( tvb, offset));
1017 proto_tree_add_text( tree, tvb, offset, 1, "Sequence Number: 0x%02x",
1018 tvb_get_guint8( tvb, offset));
1022 proto_tree_add_text( tree, tvb, offset, 4, "RWSP signature: %.4s",
1023 tvb_get_ptr( tvb, offset, 4));
1030 cmd = tvb_get_ntohs( tvb, offset);
1033 proto_tree_add_uint_format( tree, hf_msproxy_cmd, tvb, offset, 2,
1034 cmd, "Command: 0x%02x (%s)", cmd,
1035 get_msproxy_cmd_name( cmd, FROM_SERVER));
1039 case MSPROXY_HELLO_ACK:
1040 dissect_hello_ack( tvb, offset, pinfo, tree, conv_info);
1043 case MSPROXY_USERINFO_ACK:
1044 dissect_user_info_ack( tvb, offset, pinfo, tree);
1047 case MSPROXY_AUTH_1_ACK:
1048 dissect_auth_1_ack( tvb, offset, pinfo, tree);
1051 /* this also handle the MSPROXY_BIND_ACK ??? check this */
1053 case MSPROXY_UDPASSOCIATE_ACK:
1054 dissect_udpassociate_ack( tvb, offset, pinfo, tree);
1057 case MSPROXY_AUTH_2_ACK:
1058 case MSPROXY_AUTH_2_ACK2:
1059 dissect_msproxy_response_4( tvb, offset, pinfo, tree);
1062 case MSPROXY_TCP_BIND_ACK:
1063 dissect_tcp_bind_ack( tvb, offset, pinfo, tree);
1066 case MSPROXY_CONNECT_ACK:
1067 dissect_connect_ack( tvb, offset, pinfo, tree,
1071 case MSPROXY_BINDINFO:
1072 dissect_bind_info( tvb, offset, pinfo, tree, conv_info);
1075 case MSPROXY_RESOLVE_ACK:
1076 dissect_resolve( tvb, offset, pinfo, tree);
1079 case MSPROXY_CONNECT_AUTHFAILED:
1080 case MSPROXY_BIND_AUTHFAILED:
1081 proto_tree_add_text( tree, tvb, offset, 0, "No know information (help wanted)");
1087 (((cmd >> 8) == MSPROXY_CONNREFUSED) ||
1088 ((cmd >> 12) == MSPROXY_CONNREFUSED)))
1089 proto_tree_add_text( tree, tvb, offset, 0,
1090 "No know information (help wanted)");
1093 proto_tree_add_text( tree, tvb, offset, 0,
1094 "Unhandled response command (report this, please)");
1102 static void dissect_msproxy(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
1105 proto_tree *msproxy_tree = NULL;
1110 hash_entry_t *hash_info;
1111 conversation_t *conversation;
1113 if (check_col(pinfo->fd, COL_PROTOCOL))
1114 col_set_str(pinfo->fd, COL_PROTOCOL, "MSproxy");
1115 if (check_col(pinfo->fd, COL_INFO))
1116 col_clear(pinfo->fd, COL_INFO);
1118 conversation = find_conversation( &pinfo->src, &pinfo->dst,
1119 pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
1121 if ( !conversation) {
1122 conversation = conversation_new( &pinfo->src, &pinfo->dst,
1123 pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
1125 hash_info = conversation_get_proto_data(conversation, proto_msproxy);
1127 hash_info = g_mem_chunk_alloc(vals);
1128 conversation_add_proto_data(conversation, proto_msproxy,
1132 if (check_col(pinfo->fd, COL_INFO)){
1134 cmd = tvb_get_ntohs( tvb, 36);
1136 if ( pinfo->srcport == UDP_PORT_MSPROXY)
1137 col_add_fstr( pinfo->fd, COL_INFO, "Server message: %s",
1138 get_msproxy_cmd_name( cmd, FROM_SERVER));
1140 col_add_fstr(pinfo->fd, COL_INFO, "Client message: %s",
1141 get_msproxy_cmd_name( cmd, FROM_CLIENT));
1145 if (tree) { /* if proto tree, decode data */
1146 ti = proto_tree_add_item( tree, proto_msproxy, tvb, 0,
1147 tvb_length(tvb), FALSE );
1149 msproxy_tree = proto_item_add_subtree(ti, ett_msproxy);
1152 if ( pinfo->srcport == UDP_PORT_MSPROXY)
1153 dissect_msproxy_response( tvb, pinfo, msproxy_tree, hash_info);
1155 dissect_msproxy_request( tvb, pinfo, msproxy_tree, hash_info);
1160 static void msproxy_reinit( void){
1162 /* Do the cleanup work when a new pass through the packet list is */
1163 /* performed. Reset the highest row seen counter and re-initialize the */
1164 /* conversation memory chunks. */
1169 g_mem_chunk_destroy(vals);
1171 vals = g_mem_chunk_new("msproxy_vals", hash_val_length,
1172 hash_init_count * hash_val_length,
1176 g_mem_chunk_destroy(redirect_vals);
1178 redirect_vals = g_mem_chunk_new("msproxy_redirect_vals", redirect_val_length,
1179 redirect_init_count * redirect_val_length,
1186 proto_register_msproxy( void){
1188 /* Prep the msproxy protocol, for now, just register it */
1190 static gint *ett[] = {
1194 static hf_register_info hf[] = {
1197 { "Command", "msproxy.command", FT_UINT16, BASE_DEC,
1198 NULL, 0x0, "", HFILL
1202 { &hf_msproxy_dstaddr,
1203 { "Destination Address", "msproxy.dstaddr", FT_IPv4, BASE_NONE, NULL,
1208 { &hf_msproxy_srcport,
1209 { "Source Port", "msproxy.srcport", FT_UINT16,
1210 BASE_DEC, NULL, 0x0, "", HFILL
1213 { &hf_msproxy_dstport,
1214 { "Destination Port", "msproxy.dstport", FT_UINT16,
1215 BASE_DEC, NULL, 0x0, "", HFILL
1218 { &hf_msproxy_clntport,
1219 { "Client Port", "msproxy.clntport", FT_UINT16,
1220 BASE_DEC, NULL, 0x0, "", HFILL
1223 { &hf_msproxy_server_ext_addr,
1224 { "Server External Address", "msproxy.server_ext_addr", FT_IPv4, BASE_NONE, NULL,
1229 { &hf_msproxy_server_ext_port,
1230 { "Server External Port", "msproxy.server_ext_port", FT_UINT16,
1231 BASE_DEC, NULL, 0x0, "", HFILL
1235 { &hf_msproxy_server_int_addr,
1236 { "Server Internal Address", "msproxy.server_int_addr", FT_IPv4, BASE_NONE, NULL,
1241 { &hf_msproxy_server_int_port,
1242 { "Server Internal Port", "msproxy.server_int_port", FT_UINT16,
1243 BASE_DEC, NULL, 0x0, "", HFILL
1246 { &hf_msproxy_serverport,
1247 { "Server Port", "msproxy.serverport", FT_UINT16,
1248 BASE_DEC, NULL, 0x0, "", HFILL
1251 { &hf_msproxy_bindport,
1252 { "Bind Port", "msproxy.bindport", FT_UINT16,
1253 BASE_DEC, NULL, 0x0, "", HFILL
1256 { &hf_msproxy_boundport,
1257 { "Bound Port", "msproxy.boundport", FT_UINT16,
1258 BASE_DEC, NULL, 0x0, "", HFILL
1261 { &hf_msproxy_serveraddr,
1262 { "Server Address", "msproxy.serveraddr", FT_IPv4, BASE_NONE, NULL,
1266 { &hf_msproxy_bindaddr,
1267 { "Destination", "msproxy.bindaddr", FT_IPv4, BASE_NONE, NULL,
1271 { &hf_msproxy_bind_id,
1272 { "Bound Port Id", "msproxy.bindid", FT_UINT32,
1273 BASE_HEX, NULL, 0x0, "", HFILL
1276 { &hf_msproxy_resolvaddr,
1277 { "Address", "msproxy.resolvaddr", FT_IPv4, BASE_NONE, NULL,
1284 proto_msproxy = proto_register_protocol( "MS Proxy Protocol",
1285 "MS Proxy", "msproxy");
1287 proto_register_field_array(proto_msproxy, hf, array_length(hf));
1288 proto_register_subtree_array(ett, array_length(ett));
1290 register_init_routine( &msproxy_reinit); /* register re-init routine */
1295 proto_reg_handoff_msproxy(void) {
1297 /* dissector install routine */
1299 dissector_add("udp.port", UDP_PORT_MSPROXY, dissect_msproxy,