2 * Routines for Microsoft Proxy packet dissection
3 * Copyright 2000, Jeffrey C. Foster <jfoste@woodward.com>
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 ************************************************************************/
52 #include <epan/packet.h>
53 #include <epan/resolv.h>
54 #include <epan/conversation.h>
56 #include "packet-tcp.h"
57 #include "packet-udp.h"
59 extern void udp_hash_add(guint16 proto,
60 void (*dissect)(const guchar *, int, frame_data *, proto_tree *));
63 static int proto_msproxy = -1;
65 static int ett_msproxy = -1;
66 static int ett_msproxy_name = -1;
68 static int hf_msproxy_cmd = -1;
69 static int hf_msproxy_clntport = -1;
71 static int hf_msproxy_dstaddr = -1;
73 static int hf_msproxy_srcport = -1;
74 static int hf_msproxy_dstport = -1;
75 static int hf_msproxy_serverport = -1;
76 static int hf_msproxy_serveraddr = -1;
77 static int hf_msproxy_bindport = -1;
78 static int hf_msproxy_bindaddr = -1;
79 static int hf_msproxy_boundport = -1;
80 static int hf_msproxy_bind_id = -1;
81 static int hf_msproxy_resolvaddr = -1;
83 static int hf_msproxy_server_int_addr = -1;
84 static int hf_msproxy_server_int_port = -1;
85 static int hf_msproxy_server_ext_addr = -1;
86 static int hf_msproxy_server_ext_port = -1;
88 static dissector_handle_t msproxy_sub_handle;
91 #define UDP_PORT_MSPROXY 1745
93 #define N_MSPROXY_HELLO 0x05 /* packet 1 from client */
94 #define N_MSPROXY_ACK 0x10 /* packet 1 from server */
95 #define N_MSPROXY_USERINFO_ACK 0x04 /* packet 2 from server */
96 #define N_MSPROXY_AUTH 0x47 /* packet 3 from client */
97 #define N_MSPROXY_RESOLVE 0x07 /* Resolve request */
100 /*$$$ 0x0500 was dante value, I see 0x05ff and 0x0500 */
102 #define MSPROXY_HELLO 0x0500
103 #define MSPROXY_HELLO_2 0x05ff
105 #define MSPROXY_HELLO_ACK 0x1000
107 #define MSPROXY_USERINFO 0x1000
108 #define MSPROXY_USERINFO_ACK 0x0400
110 #define MSPROXY_AUTH 0x4700
111 #define MSPROXY_AUTH_1_ACK 0x4714
112 #define MSPROXY_AUTH_2 0x4701
113 #define MSPROXY_AUTH_2_ACK 0x4715
114 #define MSPROXY_AUTH_2_ACK2 0x4716
116 #define MSPROXY_RESOLVE 0x070d
117 #define MSPROXY_RESOLVE_ACK 0x070f
119 #define MSPROXY_BIND 0x0704
120 #define MSPROXY_BIND_ACK 0x0706
122 #define MSPROXY_TCP_BIND 0x0707
123 #define MSPROXY_TCP_BIND_ACK 0x0708
125 #define MSPROXY_LISTEN 0x0406
127 #define MSPROXY_BINDINFO 0x0709
129 #define MSPROXY_BINDINFO_ACK 0x070a
131 #define MSPROXY_CONNECT 0x071e
132 #define MSPROXY_CONNECT_ACK 0x0703
134 #define MSPROXY_UDPASSOCIATE 0x0705
135 #define MSPROXY_UDPASSOCIATE_ACK 0x0706
137 #define MSPROXY_UDP_BIND_REQ 0x070b
139 #define MSPROXY_CONNECTED 0x042c
140 #define MSPROXY_SESSIONEND 0x251e
142 #define MSPROXY_BIND_AUTHFAILED 0x0804
143 #define MSPROXY_CONNECT_AUTHFAILED 0x081e
144 #define MSPROXY_CONNREFUSED 0x4 /* low 12 bits seem to vary. */
146 #define FROM_SERVER 1 /* direction of packet data for get_msproxy_cmd_name */
147 #define FROM_CLIENT 0
152 /*$$$ should this be the same as redirect_entry_t ?? */
153 /* then the add_conversation could just copy the structure */
154 /* using the same allocation (instance for you object guys) */
155 /* wouldn't work because there may be multiple child conversations */
156 /* from the same MSProxy conversation */
162 guint32 server_int_port;
167 /************** conversation hash stuff ***************/
169 #define hash_init_count 20
170 #define hash_val_length (sizeof(hash_entry_t))
172 static GMemChunk *vals = NULL;
177 guint32 server_int_port;
183 /************** negotiated conversation hash stuff ***************/
185 #define redirect_init_count 20
186 #define redirect_val_length (sizeof(redirect_entry_t))
188 static GMemChunk *redirect_vals = NULL;
191 static guint32 last_row= 0; /* used to see if packet is new */
193 static void msproxy_sub_dissector( tvbuff_t *tvb, packet_info *pinfo,
196 /* Conversation dissector called from TCP or UDP dissector. Decode and */
197 /* display the msproxy header, the pass the rest of the data to the tcp */
198 /* or udp port decode routine to handle the payload. */
201 redirect_entry_t *redirect_info;
202 conversation_t *conversation;
203 proto_tree *msp_tree;
206 conversation = find_conversation( &pinfo->src, &pinfo->dst,
207 pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
209 g_assert( conversation); /* should always find a conversation */
211 redirect_info = conversation_get_proto_data(conversation,
214 if (check_col(pinfo->cinfo, COL_PROTOCOL))
215 col_set_str(pinfo->cinfo, COL_PROTOCOL, "MS Proxy");
217 if (check_col(pinfo->cinfo, COL_INFO))
218 col_set_str(pinfo->cinfo, COL_INFO,
219 (( redirect_info->proto == PT_TCP) ? "TCP stream" :
223 ti = proto_tree_add_item( tree, proto_msproxy, tvb, 0, 0,
226 msp_tree = proto_item_add_subtree(ti, ett_msproxy);
228 proto_tree_add_uint( msp_tree, hf_msproxy_dstport, tvb, 0, 0,
229 redirect_info->remote_port);
231 proto_tree_add_ipv4( msp_tree, hf_msproxy_dstaddr, tvb, 0, 0,
232 redirect_info->remote_addr);
236 /* set pinfo->{src/dst port} and call the UDP sub-dissector lookup */
238 if ( pinfo->srcport == redirect_info->clnt_port)
239 ptr = &pinfo->destport;
241 ptr = &pinfo->srcport;
243 *ptr = redirect_info->remote_port;
245 if ( redirect_info->proto == PT_TCP)
246 decode_tcp_ports( tvb, 0, pinfo, tree, pinfo->srcport,
249 decode_udp_ports( tvb, 0, pinfo, tree, pinfo->srcport,
250 pinfo->destport, -1);
252 *ptr = redirect_info->server_int_port;
257 static void add_msproxy_conversation( packet_info *pinfo,
258 hash_entry_t *hash_info){
260 /* check to see if a conversation already exists, if it does assume */
261 /* it's our conversation and quit. Otherwise create a new conversation. */
262 /* Load the conversation dissector to our dissector and load the */
263 /* conversation data structure with the info needed to call the TCP or */
264 /* UDP port decoder. */
266 /* NOTE: Currently this assume that the conversation will be created */
267 /* during a packet from the server. If that changes, pinfo->src */
268 /* and pinfo->dst will not be correct and this routine will have */
271 conversation_t *conversation;
272 redirect_entry_t *new_conv_info;
274 if (pinfo->fd->flags.visited) {
276 * We've already processed this frame once, so we
277 * should already have done this.
282 conversation = find_conversation( &pinfo->src,
283 &pinfo->dst, hash_info->proto, hash_info->server_int_port,
284 hash_info->clnt_port, 0);
286 if ( !conversation) {
287 conversation = conversation_new( &pinfo->src, &pinfo->dst,
288 hash_info->proto, hash_info->server_int_port,
289 hash_info->clnt_port, 0);
291 conversation_set_dissector(conversation, msproxy_sub_handle);
293 new_conv_info = g_mem_chunk_alloc(redirect_vals);
295 new_conv_info->remote_addr = hash_info->dst_addr;
296 new_conv_info->clnt_port = hash_info->clnt_port;
297 new_conv_info->remote_port = hash_info->dst_port;
298 new_conv_info->server_int_port = hash_info->server_int_port;
299 new_conv_info->proto = hash_info->proto;
301 conversation_add_proto_data(conversation, proto_msproxy,
307 static int display_application_name(tvbuff_t *tvb, int offset,
310 /* display the application name in the proto tree. */
312 /* NOTE: this routine assumes that the tree pointer is valid (not NULL) */
316 length = tvb_strnlen( tvb, offset, 255);
317 proto_tree_add_text( tree, tvb, offset, length, "Application: %.*s",
318 length, tvb_get_ptr( tvb, offset, length));
324 static char *get_msproxy_cmd_name( int cmd, int direction) {
326 /* return the command name string for cmd */
329 case MSPROXY_HELLO_2:
330 case MSPROXY_HELLO: return "Hello";
332 /* MSPROXY_HELLO_ACK & MSPROXY_USERINFO have the same value (0x1000). */
333 /* So use the direction flag to determine which to use. */
335 case MSPROXY_USERINFO:
336 if ( direction == FROM_SERVER)
337 return "Hello Acknowledge";
340 case MSPROXY_USERINFO_ACK: return "User Info Acknowledge";
341 case MSPROXY_AUTH: return "Authentication";
342 case MSPROXY_AUTH_1_ACK: return "Authentication Acknowledge";
343 case MSPROXY_AUTH_2: return "Authentication 2";
344 case MSPROXY_AUTH_2_ACK: return "Authentication 2 Acknowledge";
345 case MSPROXY_RESOLVE: return "Resolve";
346 case MSPROXY_RESOLVE_ACK: return "Resolve Acknowledge";
347 case MSPROXY_BIND: return "Bind";
348 case MSPROXY_TCP_BIND: return "TCP Bind";
349 case MSPROXY_TCP_BIND_ACK: return "TCP Bind Acknowledge";
350 case MSPROXY_LISTEN: return "Listen";
351 case MSPROXY_BINDINFO: return "Bind Info";
352 case MSPROXY_BINDINFO_ACK: return "Bind Info Acknowledge";
353 case MSPROXY_CONNECT: return "Connect";
354 case MSPROXY_CONNECT_ACK: return "Connect Acknowledge";
355 case MSPROXY_UDPASSOCIATE: return "UDP Associate";
356 case MSPROXY_UDP_BIND_REQ: return "UDP Bind";
357 case MSPROXY_UDPASSOCIATE_ACK: return "Bind or Associate Acknowledge";
358 case MSPROXY_CONNECTED: return "Connected";
359 case MSPROXY_SESSIONEND: return "Session End";
361 default: return "Unknown";
367 static void dissect_user_info_2(tvbuff_t *tvb, int offset,
370 /* decode the user, application, computer name */
376 length = tvb_strnlen( tvb, offset, 255);
379 proto_tree_add_text( tree, tvb, offset, length + 1,
380 "User name: %.*s", length,
381 tvb_get_ptr( tvb, offset, length));
382 offset += length + 2;
384 length = tvb_strnlen( tvb, offset, 255);
387 proto_tree_add_text( tree, tvb, offset, length + 1,
388 "Application name: %.*s", length,
389 tvb_get_ptr( tvb, offset, length));
390 offset += length + 1;
392 length = tvb_strnlen( tvb, offset, 255);
395 proto_tree_add_text( tree, tvb, offset, length + 1,
396 "Client computer name: %.*s", length,
397 tvb_get_ptr( tvb, offset, length));
403 static void dissect_msproxy_request_1(tvbuff_t *tvb, int offset,
406 /* decode the request _1 structure */
411 dissect_user_info_2( tvb, offset, tree);
417 static void dissect_bind(tvbuff_t *tvb, int offset,
418 proto_tree *tree, hash_entry_t *conv_info) {
420 /* decode the bind request */
425 proto_tree_add_item( tree, hf_msproxy_bindaddr, tvb, offset, 4,
430 proto_tree_add_item( tree, hf_msproxy_bindport, tvb, offset, 2,
435 proto_tree_add_item( tree, hf_msproxy_clntport, tvb, offset, 2,
439 conv_info->clnt_port = tvb_get_ntohs( tvb, offset);
443 proto_tree_add_item( tree, hf_msproxy_boundport, tvb, offset, 2,
447 display_application_name( tvb, offset, tree);
453 static void dissect_auth(tvbuff_t *tvb, int offset,
456 /* decode the authorization request */
461 proto_tree_add_text( tree, tvb, offset, 7, "NTLMSSP signature: %.7s",
462 tvb_get_ptr( tvb, offset, 7));
469 static void dissect_tcp_bind(tvbuff_t *tvb, int offset,
470 proto_tree *tree, hash_entry_t *conv_info) {
472 /* decode the bind packet. Set the protocol type in the conversation */
473 /* information so the bind_info can use it to create the payload */
477 conv_info->proto = PT_TCP;
482 proto_tree_add_item( tree, hf_msproxy_bind_id, tvb, offset, 4,
486 proto_tree_add_item( tree, hf_msproxy_boundport, tvb, offset, 2,
490 display_application_name( tvb, offset, tree);
495 static void dissect_request_connect(tvbuff_t *tvb, int offset,
496 proto_tree *tree, hash_entry_t *conv_info) {
498 /* decode the connect request, display */
500 conv_info->proto = PT_TCP;
505 proto_tree_add_item( tree, hf_msproxy_dstport, tvb, offset, 2,
508 conv_info->dst_port = tvb_get_ntohs( tvb, offset);
512 proto_tree_add_item( tree, hf_msproxy_dstaddr, tvb, offset, 4,
515 tvb_memcpy( tvb, (guint8 *)&conv_info->dst_addr, offset, sizeof( guint32));
519 conv_info->clnt_port = tvb_get_ntohs( tvb, offset);
522 proto_tree_add_uint( tree, hf_msproxy_clntport, tvb, offset, 2,
523 conv_info->clnt_port);
527 display_application_name( tvb, offset, tree);
532 static void dissect_bind_info_ack(tvbuff_t *tvb, int offset, proto_tree *tree) {
534 /* decode the client bind info ack */
540 proto_tree_add_item( tree, hf_msproxy_bind_id, tvb, offset, 4,
544 proto_tree_add_item( tree, hf_msproxy_dstport, tvb, offset, 2,
548 proto_tree_add_item( tree, hf_msproxy_dstaddr, tvb, offset, 4,
552 proto_tree_add_item( tree, hf_msproxy_server_int_port, tvb,
556 proto_tree_add_item( tree, hf_msproxy_server_ext_port, tvb,
560 proto_tree_add_item( tree, hf_msproxy_server_ext_addr, tvb,
564 display_application_name( tvb, offset, tree);
569 static void dissect_request_resolve(tvbuff_t *tvb, int offset,
572 /* dissect the request resolve structure */
573 /* display a string with a length, characters encoding */
574 /* they are displayed under a tree with the name in Label variable */
575 /* return the length of the string and the length byte */
577 proto_tree *name_tree;
580 int length = tvb_get_guint8( tvb, offset);
583 ti = proto_tree_add_text(tree, tvb, offset, length + 1,
584 "Host Name: %.*s", length,
585 tvb_get_ptr( tvb, offset + 18, length));
587 name_tree = proto_item_add_subtree(ti, ett_msproxy_name);
589 proto_tree_add_text( name_tree, tvb, offset, 1, "Length: %d",
595 proto_tree_add_text( name_tree, tvb, offset, length, "String: %s",
596 tvb_get_ptr( tvb, offset, length));
602 static void dissect_udp_bind(tvbuff_t *tvb, int offset,
603 proto_tree *tree, hash_entry_t *conv_info) {
605 /* Dissect the udp bind request. Load the protocol id (PT_UDP) and the */
606 /* remote address so bind_info can use it to create conversation */
609 conv_info->proto = PT_UDP;
615 proto_tree_add_item( tree, hf_msproxy_bind_id, tvb, offset, 4,
621 proto_tree_add_item( tree, hf_msproxy_dstport, tvb, offset, 2,
626 proto_tree_add_item( tree, hf_msproxy_dstaddr, tvb, offset, 4,
632 display_application_name( tvb, offset, tree);
636 static void dissect_udp_assoc(tvbuff_t *tvb, int offset,
637 proto_tree *tree, hash_entry_t *conv_info) {
639 /* dissect the udp associate request. And load client port into */
640 /* conversation data structure for later. */
646 proto_tree_add_item( tree, hf_msproxy_clntport, tvb, offset, 2,
649 conv_info->clnt_port = tvb_get_ntohs( tvb, offset);
654 display_application_name( tvb, offset, tree);
658 static void dissect_msproxy_request(tvbuff_t *tvb,
659 proto_tree *tree, hash_entry_t *conv_info) {
665 proto_tree_add_text( tree, tvb, offset, 4, "Client id: 0x%0x",
666 tvb_get_letohl( tvb, offset));
669 proto_tree_add_text( tree, tvb, offset, 4, "Version: 0x%04x",
670 tvb_get_letohl( tvb, offset));
673 proto_tree_add_text( tree, tvb, offset, 4, "Server id: 0x%0x",
674 tvb_get_letohl( tvb, offset));
677 proto_tree_add_text( tree, tvb, offset, 1, "Server ack: %u",
678 tvb_get_guint8( tvb, offset));
681 proto_tree_add_text( tree, tvb, offset, 1, "Sequence Number: %u",
682 tvb_get_guint8( tvb, offset));
685 proto_tree_add_text( tree, tvb, offset, 4, "RWSP signature: %.4s",
686 tvb_get_ptr( tvb, offset, 4));
692 cmd = tvb_get_ntohs( tvb, offset);
695 proto_tree_add_uint_format( tree, hf_msproxy_cmd, tvb, offset, 2,
696 cmd, "Command: 0x%02x (%s)", cmd,
697 get_msproxy_cmd_name( cmd, FROM_CLIENT));
703 dissect_auth( tvb, offset, tree);
707 dissect_bind( tvb, offset, tree, conv_info);
710 case MSPROXY_UDP_BIND_REQ:
711 dissect_udp_bind( tvb, offset, tree, conv_info);
714 case MSPROXY_AUTH_2: /*$$ this is probably wrong place for this */
715 case MSPROXY_TCP_BIND:
716 dissect_tcp_bind( tvb, offset, tree, conv_info);
719 case MSPROXY_RESOLVE:
720 dissect_request_resolve( tvb, offset, tree);
723 case MSPROXY_CONNECT:
725 dissect_request_connect( tvb, offset, tree,
729 case MSPROXY_BINDINFO_ACK:
730 dissect_bind_info_ack( tvb, offset, tree);
734 case MSPROXY_HELLO_2:
735 dissect_msproxy_request_1( tvb, offset, tree);
738 case MSPROXY_UDPASSOCIATE:
739 dissect_udp_assoc( tvb, offset, tree, conv_info);
743 proto_tree_add_text( tree, tvb, offset, 0,
744 "Unhandled request command (report this, please)");
750 static void dissect_hello_ack(tvbuff_t *tvb, int offset, proto_tree *tree) {
752 /* decode the hello acknowledge packet */
757 proto_tree_add_item( tree, hf_msproxy_serverport, tvb, offset, 2,
761 proto_tree_add_item( tree, hf_msproxy_serveraddr, tvb, offset, 4,
769 /* XXX - implement me */
770 static void dissect_user_info_ack(tvbuff_t *tvb _U_, int offset,
771 proto_tree *tree _U_) {
773 /* decode the response _2 structure */
783 static void dissect_udpassociate_ack(tvbuff_t *tvb, int offset,
789 proto_tree_add_item( tree, hf_msproxy_bind_id, tvb, offset, 4,
793 proto_tree_add_item( tree, hf_msproxy_server_ext_port, tvb,
797 proto_tree_add_item( tree, hf_msproxy_server_ext_addr, tvb,
801 display_application_name( tvb, offset, tree);
807 static void dissect_auth_1_ack(tvbuff_t *tvb, int offset,
812 proto_tree_add_text( tree, tvb, offset, 7, "NTLMSSP signature: %.7s",
813 tvb_get_ptr( tvb, offset, 7));
816 /* XXX - always 255? */
817 proto_tree_add_text( tree, tvb, offset, 255, "NT domain: %.255s",
818 tvb_get_ptr( tvb, offset, 255));
824 /* XXX - implement me */
825 static void dissect_msproxy_response_4( tvbuff_t *tvb _U_, int offset,
826 proto_tree *tree _U_) {
828 /* decode the response _4 structure */
835 static void dissect_connect_ack( tvbuff_t *tvb, int offset, packet_info *pinfo,
836 proto_tree *tree, hash_entry_t *conv_info) {
838 /* decode the connect ack packet */
842 proto_tree_add_item( tree, hf_msproxy_server_int_port, tvb,
846 conv_info->proto = PT_TCP;
847 conv_info->server_int_port = tvb_get_ntohs( tvb, offset);
851 proto_tree_add_item( tree, hf_msproxy_server_int_addr, tvb,
855 proto_tree_add_item( tree, hf_msproxy_server_ext_port, tvb,
859 proto_tree_add_item( tree, hf_msproxy_server_ext_addr, tvb,
863 display_application_name( tvb, offset, tree);
866 add_msproxy_conversation( pinfo, conv_info);
871 static void dissect_tcp_bind_ack( tvbuff_t *tvb, int offset, proto_tree *tree) {
873 /* decode the tcp bind */
878 proto_tree_add_item( tree, hf_msproxy_bind_id, tvb, offset, 4,
882 proto_tree_add_uint( tree, hf_msproxy_server_int_port, tvb,
886 proto_tree_add_item( tree, hf_msproxy_server_ext_port, tvb,
890 proto_tree_add_item( tree, hf_msproxy_server_ext_addr, tvb,
895 display_application_name( tvb, offset, tree);
901 static void dissect_bind_info( tvbuff_t *tvb, int offset, packet_info *pinfo,
902 proto_tree *tree, hash_entry_t *conv_info) {
904 /* decode the Bind info response from server */
909 proto_tree_add_item( tree, hf_msproxy_bind_id, tvb, offset, 4,
914 conv_info->dst_port = tvb_get_ntohs( tvb, offset);
916 proto_tree_add_uint( tree, hf_msproxy_dstport, tvb, offset, 2,
917 conv_info->dst_port);
920 tvb_memcpy( tvb, (guint8 *)&conv_info->dst_addr, offset, sizeof( guint32));
922 proto_tree_add_item( tree, hf_msproxy_dstaddr, tvb, offset, 4,
926 conv_info->server_int_port = tvb_get_ntohs( tvb, offset);
928 proto_tree_add_uint( tree, hf_msproxy_server_int_port, tvb,
929 offset, 2, conv_info->server_int_port);
933 proto_tree_add_item( tree, hf_msproxy_server_ext_port, tvb,
937 proto_tree_add_item( tree, hf_msproxy_server_ext_addr, tvb,
941 display_application_name( tvb, offset, tree);
945 add_msproxy_conversation( pinfo, conv_info);
950 static void dissect_resolve(tvbuff_t *tvb, int offset, proto_tree *tree) {
952 /* dissect the response resolve structure */
953 /* display a string with a length, characters encoding */
954 /* they are displayed under a tree with the name in Label variable */
955 /* return the length of the string and the length byte */
960 addr_offset = tvb_get_guint8( tvb, offset);
962 proto_tree_add_text( tree, tvb, offset, 1, "Address offset: %d",
969 offset += addr_offset;
971 proto_tree_add_item( tree, hf_msproxy_resolvaddr, tvb, offset, 4,
978 static void dissect_msproxy_response(tvbuff_t *tvb, packet_info *pinfo,
979 proto_tree *tree, hash_entry_t *conv_info) {
985 proto_tree_add_text( tree, tvb, offset, 4, "Client id: 0x%0x",
986 tvb_get_letohl( tvb, offset));
989 proto_tree_add_text( tree, tvb, offset, 4, "Version: 0x%04x",
990 tvb_get_letohl( tvb, offset));
993 proto_tree_add_text( tree, tvb, offset, 4, "Server id: 0x%04x",
994 tvb_get_letohl( tvb, offset));
997 proto_tree_add_text( tree, tvb, offset, 1, "Client ack: 0x%02x",
998 tvb_get_guint8( tvb, offset));
1001 proto_tree_add_text( tree, tvb, offset, 1, "Sequence Number: 0x%02x",
1002 tvb_get_guint8( tvb, offset));
1006 proto_tree_add_text( tree, tvb, offset, 4, "RWSP signature: %.4s",
1007 tvb_get_ptr( tvb, offset, 4));
1014 cmd = tvb_get_ntohs( tvb, offset);
1017 proto_tree_add_uint_format( tree, hf_msproxy_cmd, tvb, offset, 2,
1018 cmd, "Command: 0x%02x (%s)", cmd,
1019 get_msproxy_cmd_name( cmd, FROM_SERVER));
1023 case MSPROXY_HELLO_ACK:
1024 dissect_hello_ack( tvb, offset, tree);
1027 case MSPROXY_USERINFO_ACK:
1028 dissect_user_info_ack( tvb, offset, tree);
1031 case MSPROXY_AUTH_1_ACK:
1032 dissect_auth_1_ack( tvb, offset, tree);
1035 /* this also handle the MSPROXY_BIND_ACK ??? check this */
1037 case MSPROXY_UDPASSOCIATE_ACK:
1038 dissect_udpassociate_ack( tvb, offset, tree);
1041 case MSPROXY_AUTH_2_ACK:
1042 case MSPROXY_AUTH_2_ACK2:
1043 dissect_msproxy_response_4( tvb, offset, tree);
1046 case MSPROXY_TCP_BIND_ACK:
1047 dissect_tcp_bind_ack( tvb, offset, tree);
1050 case MSPROXY_CONNECT_ACK:
1051 dissect_connect_ack( tvb, offset, pinfo, tree,
1055 case MSPROXY_BINDINFO:
1056 dissect_bind_info( tvb, offset, pinfo, tree, conv_info);
1059 case MSPROXY_RESOLVE_ACK:
1060 dissect_resolve( tvb, offset, tree);
1063 case MSPROXY_CONNECT_AUTHFAILED:
1064 case MSPROXY_BIND_AUTHFAILED:
1065 proto_tree_add_text( tree, tvb, offset, 0, "No know information (help wanted)");
1071 (((cmd >> 8) == MSPROXY_CONNREFUSED) ||
1072 ((cmd >> 12) == MSPROXY_CONNREFUSED)))
1073 proto_tree_add_text( tree, tvb, offset, 0,
1074 "No know information (help wanted)");
1077 proto_tree_add_text( tree, tvb, offset, 0,
1078 "Unhandled response command (report this, please)");
1086 static void dissect_msproxy(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
1089 proto_tree *msproxy_tree = NULL;
1094 hash_entry_t *hash_info;
1095 conversation_t *conversation;
1097 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1098 col_set_str(pinfo->cinfo, COL_PROTOCOL, "MSproxy");
1099 if (check_col(pinfo->cinfo, COL_INFO))
1100 col_clear(pinfo->cinfo, COL_INFO);
1102 conversation = find_conversation( &pinfo->src, &pinfo->dst,
1103 pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
1105 if ( !conversation) {
1106 conversation = conversation_new( &pinfo->src, &pinfo->dst,
1107 pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
1109 hash_info = conversation_get_proto_data(conversation, proto_msproxy);
1111 hash_info = g_mem_chunk_alloc(vals);
1112 conversation_add_proto_data(conversation, proto_msproxy,
1116 if (check_col(pinfo->cinfo, COL_INFO)){
1118 cmd = tvb_get_ntohs( tvb, 36);
1120 if ( pinfo->srcport == UDP_PORT_MSPROXY)
1121 col_add_fstr( pinfo->cinfo, COL_INFO, "Server message: %s",
1122 get_msproxy_cmd_name( cmd, FROM_SERVER));
1124 col_add_fstr(pinfo->cinfo, COL_INFO, "Client message: %s",
1125 get_msproxy_cmd_name( cmd, FROM_CLIENT));
1129 if (tree) { /* if proto tree, decode data */
1130 ti = proto_tree_add_item( tree, proto_msproxy, tvb, 0, -1,
1133 msproxy_tree = proto_item_add_subtree(ti, ett_msproxy);
1136 if ( pinfo->srcport == UDP_PORT_MSPROXY)
1137 dissect_msproxy_response( tvb, pinfo, msproxy_tree, hash_info);
1139 dissect_msproxy_request( tvb, msproxy_tree, hash_info);
1144 static void msproxy_reinit( void){
1146 /* Do the cleanup work when a new pass through the packet list is */
1147 /* performed. Reset the highest row seen counter and re-initialize the */
1148 /* conversation memory chunks. */
1153 g_mem_chunk_destroy(vals);
1155 vals = g_mem_chunk_new("msproxy_vals", hash_val_length,
1156 hash_init_count * hash_val_length,
1160 g_mem_chunk_destroy(redirect_vals);
1162 redirect_vals = g_mem_chunk_new("msproxy_redirect_vals", redirect_val_length,
1163 redirect_init_count * redirect_val_length,
1170 proto_register_msproxy( void){
1172 /* Prep the msproxy protocol, for now, just register it */
1174 static gint *ett[] = {
1178 static hf_register_info hf[] = {
1181 { "Command", "msproxy.command", FT_UINT16, BASE_DEC,
1182 NULL, 0x0, "", HFILL
1186 { &hf_msproxy_dstaddr,
1187 { "Destination Address", "msproxy.dstaddr", FT_IPv4, BASE_NONE, NULL,
1192 { &hf_msproxy_srcport,
1193 { "Source Port", "msproxy.srcport", FT_UINT16,
1194 BASE_DEC, NULL, 0x0, "", HFILL
1197 { &hf_msproxy_dstport,
1198 { "Destination Port", "msproxy.dstport", FT_UINT16,
1199 BASE_DEC, NULL, 0x0, "", HFILL
1202 { &hf_msproxy_clntport,
1203 { "Client Port", "msproxy.clntport", FT_UINT16,
1204 BASE_DEC, NULL, 0x0, "", HFILL
1207 { &hf_msproxy_server_ext_addr,
1208 { "Server External Address", "msproxy.server_ext_addr", FT_IPv4, BASE_NONE, NULL,
1213 { &hf_msproxy_server_ext_port,
1214 { "Server External Port", "msproxy.server_ext_port", FT_UINT16,
1215 BASE_DEC, NULL, 0x0, "", HFILL
1219 { &hf_msproxy_server_int_addr,
1220 { "Server Internal Address", "msproxy.server_int_addr", FT_IPv4, BASE_NONE, NULL,
1225 { &hf_msproxy_server_int_port,
1226 { "Server Internal Port", "msproxy.server_int_port", FT_UINT16,
1227 BASE_DEC, NULL, 0x0, "", HFILL
1230 { &hf_msproxy_serverport,
1231 { "Server Port", "msproxy.serverport", FT_UINT16,
1232 BASE_DEC, NULL, 0x0, "", HFILL
1235 { &hf_msproxy_bindport,
1236 { "Bind Port", "msproxy.bindport", FT_UINT16,
1237 BASE_DEC, NULL, 0x0, "", HFILL
1240 { &hf_msproxy_boundport,
1241 { "Bound Port", "msproxy.boundport", FT_UINT16,
1242 BASE_DEC, NULL, 0x0, "", HFILL
1245 { &hf_msproxy_serveraddr,
1246 { "Server Address", "msproxy.serveraddr", FT_IPv4, BASE_NONE, NULL,
1250 { &hf_msproxy_bindaddr,
1251 { "Destination", "msproxy.bindaddr", FT_IPv4, BASE_NONE, NULL,
1255 { &hf_msproxy_bind_id,
1256 { "Bound Port Id", "msproxy.bindid", FT_UINT32,
1257 BASE_HEX, NULL, 0x0, "", HFILL
1260 { &hf_msproxy_resolvaddr,
1261 { "Address", "msproxy.resolvaddr", FT_IPv4, BASE_NONE, NULL,
1268 proto_msproxy = proto_register_protocol( "MS Proxy Protocol",
1269 "MS Proxy", "msproxy");
1271 proto_register_field_array(proto_msproxy, hf, array_length(hf));
1272 proto_register_subtree_array(ett, array_length(ett));
1274 register_init_routine( &msproxy_reinit); /* register re-init routine */
1276 msproxy_sub_handle = create_dissector_handle(msproxy_sub_dissector,
1282 proto_reg_handoff_msproxy(void) {
1284 /* dissector install routine */
1286 dissector_handle_t msproxy_handle;
1288 msproxy_handle = create_dissector_handle(dissect_msproxy,
1290 dissector_add("udp.port", UDP_PORT_MSPROXY, msproxy_handle);