2 * Routines for Microsoft Proxy packet dissection
3 * Copyright 2000, Jeffrey C. Foster <jfoste@woodward.com>
5 * $Id: packet-msproxy.c,v 1.25 2001/12/10 00:25:30 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;
103 static dissector_handle_t msproxy_sub_handle;
106 #define UDP_PORT_MSPROXY 1745
108 #define N_MSPROXY_HELLO 0x05 /* packet 1 from client */
109 #define N_MSPROXY_ACK 0x10 /* packet 1 from server */
110 #define N_MSPROXY_USERINFO_ACK 0x04 /* packet 2 from server */
111 #define N_MSPROXY_AUTH 0x47 /* packet 3 from client */
112 #define N_MSPROXY_RESOLVE 0x07 /* Resolve request */
115 /*$$$ 0x0500 was dante value, I see 0x05ff and 0x0500 */
117 #define MSPROXY_HELLO 0x0500
118 #define MSPROXY_HELLO_2 0x05ff
120 #define MSPROXY_HELLO_ACK 0x1000
122 #define MSPROXY_USERINFO 0x1000
123 #define MSPROXY_USERINFO_ACK 0x0400
125 #define MSPROXY_AUTH 0x4700
126 #define MSPROXY_AUTH_1_ACK 0x4714
127 #define MSPROXY_AUTH_2 0x4701
128 #define MSPROXY_AUTH_2_ACK 0x4715
129 #define MSPROXY_AUTH_2_ACK2 0x4716
131 #define MSPROXY_RESOLVE 0x070d
132 #define MSPROXY_RESOLVE_ACK 0x070f
134 #define MSPROXY_BIND 0x0704
135 #define MSPROXY_BIND_ACK 0x0706
137 #define MSPROXY_TCP_BIND 0x0707
138 #define MSPROXY_TCP_BIND_ACK 0x0708
140 #define MSPROXY_LISTEN 0x0406
142 #define MSPROXY_BINDINFO 0x0709
144 #define MSPROXY_BINDINFO_ACK 0x070a
146 #define MSPROXY_CONNECT 0x071e
147 #define MSPROXY_CONNECT_ACK 0x0703
149 #define MSPROXY_UDPASSOCIATE 0x0705
150 #define MSPROXY_UDPASSOCIATE_ACK 0x0706
152 #define MSPROXY_UDP_BIND_REQ 0x070b
154 #define MSPROXY_CONNECTED 0x042c
155 #define MSPROXY_SESSIONEND 0x251e
157 #define MSPROXY_BIND_AUTHFAILED 0x0804
158 #define MSPROXY_CONNECT_AUTHFAILED 0x081e
159 #define MSPROXY_CONNREFUSED 0x4 /* low 12 bits seem to vary. */
161 #define FROM_SERVER 1 /* direction of packet data for get_msproxy_cmd_name */
162 #define FROM_CLIENT 0
167 /*$$$ should this be the same as redirect_entry_t ?? */
168 /* then the add_conversation could just copy the structure */
169 /* using the same allocation (instance for you object guys) */
170 /* wouldn't work because there may be multiple child conversations */
171 /* from the same MSProxy conversation */
177 guint32 server_int_port;
182 /************** conversation hash stuff ***************/
184 #define hash_init_count 20
185 #define hash_val_length (sizeof(hash_entry_t))
187 static GMemChunk *vals = NULL;
192 guint32 server_int_port;
198 /************** negotiated conversation hash stuff ***************/
200 #define redirect_init_count 20
201 #define redirect_val_length (sizeof(redirect_entry_t))
203 static GMemChunk *redirect_vals = NULL;
206 static guint32 last_row= 0; /* used to see if packet is new */
208 static void msproxy_sub_dissector( tvbuff_t *tvb, packet_info *pinfo,
211 /* Conversation dissector called from TCP or UDP dissector. Decode and */
212 /* display the msproxy header, the pass the rest of the data to the tcp */
213 /* or udp port decode routine to handle the payload. */
216 redirect_entry_t *redirect_info;
217 conversation_t *conversation;
218 proto_tree *msp_tree;
221 conversation = find_conversation( &pinfo->src, &pinfo->dst,
222 pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
224 g_assert( conversation); /* should always find a conversation */
226 redirect_info = conversation_get_proto_data(conversation,
229 if (check_col(pinfo->cinfo, COL_PROTOCOL))
230 col_set_str(pinfo->cinfo, COL_PROTOCOL, "MS Proxy");
232 if (check_col(pinfo->cinfo, COL_INFO))
233 col_set_str(pinfo->cinfo, COL_INFO,
234 (( redirect_info->proto == PT_TCP) ? "TCP stream" :
238 ti = proto_tree_add_item( tree, proto_msproxy, tvb, 0, 0,
241 msp_tree = proto_item_add_subtree(ti, ett_msproxy);
243 proto_tree_add_uint( msp_tree, hf_msproxy_dstport, tvb, 0, 0,
244 redirect_info->remote_port);
246 proto_tree_add_ipv4( msp_tree, hf_msproxy_dstaddr, tvb, 0, 0,
247 redirect_info->remote_addr);
251 /* set pinfo->{src/dst port} and call the UDP sub-dissector lookup */
253 if ( pinfo->srcport == redirect_info->clnt_port)
254 ptr = &pinfo->destport;
256 ptr = &pinfo->srcport;
258 *ptr = redirect_info->remote_port;
260 if ( redirect_info->proto == PT_TCP)
261 decode_tcp_ports( tvb, 0, pinfo, tree, pinfo->srcport,
264 decode_udp_ports( tvb, 0, pinfo, tree, pinfo->srcport,
267 *ptr = redirect_info->server_int_port;
272 static void add_msproxy_conversation( packet_info *pinfo,
273 hash_entry_t *hash_info){
275 /* check to see if a conversation already exists, if it does assume */
276 /* it's our conversation and quit. Otherwise create a new conversation. */
277 /* Load the conversation dissector to our dissector and load the */
278 /* conversation data structure with the info needed to call the TCP or */
279 /* UDP port decoder. */
281 /* NOTE: Currently this assume that the conversation will be created */
282 /* during a packet from the server. If that changes, pinfo->src */
283 /* and pinfo->dst will not be correct and this routine will have */
286 conversation_t *conversation;
287 redirect_entry_t *new_conv_info;
289 if (pinfo->fd->flags.visited) {
291 * We've already processed this frame once, so we
292 * should already have done this.
297 conversation = find_conversation( &pinfo->src,
298 &pinfo->dst, hash_info->proto, hash_info->server_int_port,
299 hash_info->clnt_port, 0);
301 if ( !conversation) {
302 conversation = conversation_new( &pinfo->src, &pinfo->dst,
303 hash_info->proto, hash_info->server_int_port,
304 hash_info->clnt_port, 0);
306 conversation_set_dissector(conversation, msproxy_sub_handle);
308 new_conv_info = g_mem_chunk_alloc(redirect_vals);
310 new_conv_info->remote_addr = hash_info->dst_addr;
311 new_conv_info->clnt_port = hash_info->clnt_port;
312 new_conv_info->remote_port = hash_info->dst_port;
313 new_conv_info->server_int_port = hash_info->server_int_port;
314 new_conv_info->proto = hash_info->proto;
316 conversation_add_proto_data(conversation, proto_msproxy,
322 static int display_application_name(tvbuff_t *tvb, int offset,
323 packet_info *pinfo, proto_tree *tree) {
325 /* display the application name in the proto tree. */
327 /* NOTE: this routine assumes that the tree pointer is valid (not NULL) */
331 length = tvb_strnlen( tvb, offset, 255);
332 proto_tree_add_text( tree, tvb, offset, length, "Application: %.*s",
333 length, tvb_get_ptr( tvb, offset, length));
339 static char *get_msproxy_cmd_name( int cmd, int direction) {
341 /* return the command name string for cmd */
344 case MSPROXY_HELLO_2:
345 case MSPROXY_HELLO: return "Hello";
347 /* MSPROXY_HELLO_ACK & MSPROXY_USERINFO have the same value (0x1000). */
348 /* So use the direction flag to determine which to use. */
350 case MSPROXY_USERINFO:
351 if ( direction == FROM_SERVER)
352 return "Hello Acknowledge";
355 case MSPROXY_USERINFO_ACK: return "User Info Acknowledge";
356 case MSPROXY_AUTH: return "Authentication";
357 case MSPROXY_AUTH_1_ACK: return "Authentication Acknowledge";
358 case MSPROXY_AUTH_2: return "Authentication 2";
359 case MSPROXY_AUTH_2_ACK: return "Authentication 2 Acknowledge";
360 case MSPROXY_RESOLVE: return "Resolve";
361 case MSPROXY_RESOLVE_ACK: return "Resolve Acknowledge";
362 case MSPROXY_BIND: return "Bind";
363 case MSPROXY_TCP_BIND: return "TCP Bind";
364 case MSPROXY_TCP_BIND_ACK: return "TCP Bind Acknowledge";
365 case MSPROXY_LISTEN: return "Listen";
366 case MSPROXY_BINDINFO: return "Bind Info";
367 case MSPROXY_BINDINFO_ACK: return "Bind Info Acknowledge";
368 case MSPROXY_CONNECT: return "Connect";
369 case MSPROXY_CONNECT_ACK: return "Connect Acknowledge";
370 case MSPROXY_UDPASSOCIATE: return "UDP Associate";
371 case MSPROXY_UDP_BIND_REQ: return "UDP Bind";
372 case MSPROXY_UDPASSOCIATE_ACK: return "Bind or Associate Acknowledge";
373 case MSPROXY_CONNECTED: return "Connected";
374 case MSPROXY_SESSIONEND: return "Session End";
376 default: return "Unknown";
382 static void dissect_user_info_2(tvbuff_t *tvb, int offset, packet_info *pinfo,
385 /* decode the user, application, computer name */
391 length = tvb_strnlen( tvb, offset, 255);
394 proto_tree_add_text( tree, tvb, offset, length + 1,
395 "User name: %.*s", length,
396 tvb_get_ptr( tvb, offset, length));
397 offset += length + 2;
399 length = tvb_strnlen( tvb, offset, 255);
402 proto_tree_add_text( tree, tvb, offset, length + 1,
403 "Application name: %.*s", length,
404 tvb_get_ptr( tvb, offset, length));
405 offset += length + 1;
407 length = tvb_strnlen( tvb, offset, 255);
410 proto_tree_add_text( tree, tvb, offset, length + 1,
411 "Client computer name: %.*s", length,
412 tvb_get_ptr( tvb, offset, length));
418 static void dissect_msproxy_request_1(tvbuff_t *tvb, int offset,
419 packet_info *pinfo, proto_tree *tree) {
421 /* decode the request _1 structure */
426 dissect_user_info_2( tvb, offset, pinfo, tree);
432 static void dissect_bind(tvbuff_t *tvb, int offset, packet_info *pinfo,
433 proto_tree *tree, hash_entry_t *conv_info) {
435 /* decode the bind request */
440 proto_tree_add_item( tree, hf_msproxy_bindaddr, tvb, offset, 4,
445 proto_tree_add_item( tree, hf_msproxy_bindport, tvb, offset, 2,
450 proto_tree_add_item( tree, hf_msproxy_clntport, tvb, offset, 2,
454 conv_info->clnt_port = tvb_get_ntohs( tvb, offset);
458 proto_tree_add_item( tree, hf_msproxy_boundport, tvb, offset, 2,
462 display_application_name( tvb, offset, pinfo, tree);
468 static void dissect_auth(tvbuff_t *tvb, int offset,
469 packet_info *pinfo, proto_tree *tree) {
471 /* decode the authorization request */
476 proto_tree_add_text( tree, tvb, offset, 7, "NTLMSSP signature: %.7s",
477 tvb_get_ptr( tvb, offset, 7));
484 static void dissect_tcp_bind(tvbuff_t *tvb, int offset,
485 packet_info *pinfo, proto_tree *tree, hash_entry_t *conv_info) {
487 /* decode the bind packet. Set the protocol type in the conversation */
488 /* information so the bind_info can use it to create the payload */
492 conv_info->proto = PT_TCP;
497 proto_tree_add_item( tree, hf_msproxy_bind_id, tvb, offset, 4,
501 proto_tree_add_item( tree, hf_msproxy_boundport, tvb, offset, 2,
505 display_application_name( tvb, offset, pinfo, tree);
510 static void dissect_request_connect(tvbuff_t *tvb, int offset,
511 packet_info *pinfo, proto_tree *tree, hash_entry_t *conv_info) {
513 /* decode the connect request, display */
515 conv_info->proto = PT_TCP;
520 proto_tree_add_item( tree, hf_msproxy_dstport, tvb, offset, 2,
523 conv_info->dst_port = tvb_get_ntohs( tvb, offset);
527 proto_tree_add_item( tree, hf_msproxy_dstaddr, tvb, offset, 4,
530 tvb_memcpy( tvb, (guint8 *)&conv_info->dst_addr, offset, sizeof( guint32));
534 conv_info->clnt_port = tvb_get_ntohs( tvb, offset);
537 proto_tree_add_uint( tree, hf_msproxy_clntport, tvb, offset, 2,
538 conv_info->clnt_port);
542 display_application_name( tvb, offset, pinfo, tree);
547 static void dissect_bind_info_ack(tvbuff_t *tvb, int offset, packet_info *pinfo,
548 proto_tree *tree, hash_entry_t *conv_info) {
550 /* decode the client bind info ack */
556 proto_tree_add_item( tree, hf_msproxy_bind_id, tvb, offset, 4,
560 proto_tree_add_item( tree, hf_msproxy_dstport, tvb, offset, 2,
564 proto_tree_add_item( tree, hf_msproxy_dstaddr, tvb, offset, 4,
568 proto_tree_add_item( tree, hf_msproxy_server_int_port, tvb,
572 proto_tree_add_item( tree, hf_msproxy_server_ext_port, tvb,
576 proto_tree_add_item( tree, hf_msproxy_server_ext_addr, tvb,
580 display_application_name( tvb, offset, pinfo, tree);
585 static void dissect_request_resolve(tvbuff_t *tvb, int offset,
586 packet_info *pinfo, proto_tree *tree) {
588 /* dissect the request resolve structure */
589 /* display a string with a length, characters encoding */
590 /* they are displayed under a tree with the name in Label variable */
591 /* return the length of the string and the length byte */
593 proto_tree *name_tree;
596 int length = tvb_get_guint8( tvb, offset);
599 ti = proto_tree_add_text(tree, tvb, offset, length + 1,
600 "Host Name: %.*s", length,
601 tvb_get_ptr( tvb, offset + 18, length));
603 name_tree = proto_item_add_subtree(ti, ett_msproxy_name);
605 proto_tree_add_text( name_tree, tvb, offset, 1, "Length: %d",
611 proto_tree_add_text( name_tree, tvb, offset, length, "String: %s",
612 tvb_get_ptr( tvb, offset, length));
618 static void dissect_udp_bind(tvbuff_t *tvb, int offset,
619 packet_info *pinfo, proto_tree *tree, hash_entry_t *conv_info) {
621 /* Dissect the udp bind request. Load the protocol id (PT_UDP) and the */
622 /* remote address so bind_info can use it to create conversation */
625 conv_info->proto = PT_UDP;
631 proto_tree_add_item( tree, hf_msproxy_bind_id, tvb, offset, 4,
637 proto_tree_add_item( tree, hf_msproxy_dstport, tvb, offset, 2,
642 proto_tree_add_ipv4( tree, hf_msproxy_dstaddr, tvb, offset, 4,
648 display_application_name( tvb, offset, pinfo, tree);
652 static void dissect_udp_assoc(tvbuff_t *tvb, int offset,
653 packet_info *pinfo, proto_tree *tree, hash_entry_t *conv_info) {
655 /* dissect the udp associate request. And load client port into */
656 /* conversation data structure for later. */
662 proto_tree_add_item( tree, hf_msproxy_clntport, tvb, offset, 2,
665 conv_info->clnt_port = tvb_get_ntohs( tvb, offset);
670 display_application_name( tvb, offset, pinfo, tree);
674 static void dissect_msproxy_request(tvbuff_t *tvb, packet_info *pinfo,
675 proto_tree *tree, hash_entry_t *conv_info) {
681 proto_tree_add_text( tree, tvb, offset, 4, "Client id: 0x%0x",
682 tvb_get_letohl( tvb, offset));
685 proto_tree_add_text( tree, tvb, offset, 4, "Version: 0x%04x",
686 tvb_get_letohl( tvb, offset));
689 proto_tree_add_text( tree, tvb, offset, 4, "Server id: 0x%0x",
690 tvb_get_letohl( tvb, offset));
693 proto_tree_add_text( tree, tvb, offset, 1, "Server ack: %u",
694 tvb_get_guint8( tvb, offset));
697 proto_tree_add_text( tree, tvb, offset, 1, "Sequence Number: %u",
698 tvb_get_guint8( tvb, offset));
701 proto_tree_add_text( tree, tvb, offset, 4, "RWSP signature: %.4s",
702 tvb_get_ptr( tvb, offset, 4));
708 cmd = tvb_get_ntohs( tvb, offset);
711 proto_tree_add_uint_format( tree, hf_msproxy_cmd, tvb, offset, 2,
712 cmd, "Command: 0x%02x (%s)", cmd,
713 get_msproxy_cmd_name( cmd, FROM_CLIENT));
719 dissect_auth( tvb, offset, pinfo, tree);
723 dissect_bind( tvb, offset, pinfo, tree, conv_info);
726 case MSPROXY_UDP_BIND_REQ:
727 dissect_udp_bind( tvb, offset, pinfo, tree, conv_info);
730 case MSPROXY_AUTH_2: /*$$ this is probably wrong place for this */
731 case MSPROXY_TCP_BIND:
732 dissect_tcp_bind( tvb, offset, pinfo, tree, conv_info);
735 case MSPROXY_RESOLVE:
736 dissect_request_resolve( tvb, offset, pinfo, tree);
739 case MSPROXY_CONNECT:
741 dissect_request_connect( tvb, offset, pinfo, tree,
745 case MSPROXY_BINDINFO_ACK:
746 dissect_bind_info_ack( tvb, offset, pinfo, tree,
751 case MSPROXY_HELLO_2:
752 dissect_msproxy_request_1( tvb, offset, pinfo, tree);
755 case MSPROXY_UDPASSOCIATE:
756 dissect_udp_assoc( tvb, offset, pinfo, tree, conv_info);
760 proto_tree_add_text( tree, tvb, offset, 0,
761 "Unhandled request command (report this, please)");
767 static void dissect_hello_ack(tvbuff_t *tvb, int offset, packet_info *pinfo,
768 proto_tree *tree, hash_entry_t *conv_info) {
770 /* decode the hello acknowledge packet */
775 proto_tree_add_item( tree, hf_msproxy_serverport, tvb, offset, 2,
779 proto_tree_add_item( tree, hf_msproxy_serveraddr, tvb, offset, 4,
787 static void dissect_user_info_ack(tvbuff_t *tvb, int offset,
788 packet_info *pinfo, proto_tree *tree) {
790 /* decode the response _2 structure */
800 static void dissect_udpassociate_ack(tvbuff_t *tvb, int offset,
801 packet_info *pinfo, proto_tree *tree) {
806 proto_tree_add_item( tree, hf_msproxy_bind_id, tvb, offset, 4,
810 proto_tree_add_item( tree, hf_msproxy_server_ext_port, tvb,
814 proto_tree_add_item( tree, hf_msproxy_server_ext_addr, tvb,
818 display_application_name( tvb, offset, pinfo, tree);
824 static void dissect_auth_1_ack(tvbuff_t *tvb, int offset, packet_info *pinfo,
829 proto_tree_add_text( tree, tvb, offset, 7, "NTLMSSP signature: %.7s",
830 tvb_get_ptr( tvb, offset, 7));
833 /* XXX - always 255? */
834 proto_tree_add_text( tree, tvb, offset, 255, "NT domain: %.255s",
835 tvb_get_ptr( tvb, offset, 255));
841 static void dissect_msproxy_response_4( tvbuff_t *tvb, int offset,
842 packet_info *pinfo, proto_tree *tree) {
844 /* decode the response _4 structure */
851 static void dissect_connect_ack( tvbuff_t *tvb, int offset, packet_info *pinfo,
852 proto_tree *tree, hash_entry_t *conv_info) {
854 /* decode the connect ack packet */
858 proto_tree_add_item( tree, hf_msproxy_server_int_port, tvb,
862 conv_info->proto = PT_TCP;
863 conv_info->server_int_port = tvb_get_ntohs( tvb, offset);
867 proto_tree_add_item( tree, hf_msproxy_server_int_addr, tvb,
871 proto_tree_add_item( tree, hf_msproxy_server_ext_port, tvb,
875 proto_tree_add_item( tree, hf_msproxy_server_ext_addr, tvb,
879 display_application_name( tvb, offset, pinfo, tree);
882 add_msproxy_conversation( pinfo, conv_info);
887 static void dissect_tcp_bind_ack( tvbuff_t *tvb, int offset, packet_info *pinfo,
890 /* decode the tcp bind */
895 proto_tree_add_item( tree, hf_msproxy_bind_id, tvb, offset, 4,
899 proto_tree_add_uint( tree, hf_msproxy_server_int_port, tvb,
903 proto_tree_add_item( tree, hf_msproxy_server_ext_port, tvb,
907 proto_tree_add_item( tree, hf_msproxy_server_ext_addr, tvb,
912 display_application_name( tvb, offset, pinfo, tree);
918 static void dissect_bind_info( tvbuff_t *tvb, int offset, packet_info *pinfo,
919 proto_tree *tree, hash_entry_t *conv_info) {
921 /* decode the Bind info response from server */
926 proto_tree_add_item( tree, hf_msproxy_bind_id, tvb, offset, 4,
931 conv_info->dst_port = tvb_get_ntohs( tvb, offset);
933 proto_tree_add_uint( tree, hf_msproxy_dstport, tvb, offset, 2,
934 conv_info->dst_port);
937 tvb_memcpy( tvb, (guint8 *)&conv_info->dst_addr, offset, sizeof( guint32));
939 proto_tree_add_item( tree, hf_msproxy_dstaddr, tvb, offset, 4,
943 conv_info->server_int_port = tvb_get_ntohs( tvb, offset);
945 proto_tree_add_uint( tree, hf_msproxy_server_int_port, tvb,
946 offset, 2, conv_info->server_int_port);
950 proto_tree_add_item( tree, hf_msproxy_server_ext_port, tvb,
954 proto_tree_add_item( tree, hf_msproxy_server_ext_addr, tvb,
958 display_application_name( tvb, offset, pinfo, tree);
962 add_msproxy_conversation( pinfo, conv_info);
967 static void dissect_resolve(tvbuff_t *tvb, int offset, packet_info *pinfo,
970 /* dissect the response resolve structure */
971 /* display a string with a length, characters encoding */
972 /* they are displayed under a tree with the name in Label variable */
973 /* return the length of the string and the length byte */
978 addr_offset = tvb_get_guint8( tvb, offset);
980 proto_tree_add_text( tree, tvb, offset, 1, "Address offset: %d",
987 offset += addr_offset;
989 proto_tree_add_item( tree, hf_msproxy_resolvaddr, tvb, offset, 4,
996 static void dissect_msproxy_response(tvbuff_t *tvb, packet_info *pinfo,
997 proto_tree *tree, hash_entry_t *conv_info) {
1003 proto_tree_add_text( tree, tvb, offset, 4, "Client id: 0x%0x",
1004 tvb_get_letohl( tvb, offset));
1007 proto_tree_add_text( tree, tvb, offset, 4, "Version: 0x%04x",
1008 tvb_get_letohl( tvb, offset));
1011 proto_tree_add_text( tree, tvb, offset, 4, "Server id: 0x%04x",
1012 tvb_get_letohl( tvb, offset));
1015 proto_tree_add_text( tree, tvb, offset, 1, "Client ack: 0x%02x",
1016 tvb_get_guint8( tvb, offset));
1019 proto_tree_add_text( tree, tvb, offset, 1, "Sequence Number: 0x%02x",
1020 tvb_get_guint8( tvb, offset));
1024 proto_tree_add_text( tree, tvb, offset, 4, "RWSP signature: %.4s",
1025 tvb_get_ptr( tvb, offset, 4));
1032 cmd = tvb_get_ntohs( tvb, offset);
1035 proto_tree_add_uint_format( tree, hf_msproxy_cmd, tvb, offset, 2,
1036 cmd, "Command: 0x%02x (%s)", cmd,
1037 get_msproxy_cmd_name( cmd, FROM_SERVER));
1041 case MSPROXY_HELLO_ACK:
1042 dissect_hello_ack( tvb, offset, pinfo, tree, conv_info);
1045 case MSPROXY_USERINFO_ACK:
1046 dissect_user_info_ack( tvb, offset, pinfo, tree);
1049 case MSPROXY_AUTH_1_ACK:
1050 dissect_auth_1_ack( tvb, offset, pinfo, tree);
1053 /* this also handle the MSPROXY_BIND_ACK ??? check this */
1055 case MSPROXY_UDPASSOCIATE_ACK:
1056 dissect_udpassociate_ack( tvb, offset, pinfo, tree);
1059 case MSPROXY_AUTH_2_ACK:
1060 case MSPROXY_AUTH_2_ACK2:
1061 dissect_msproxy_response_4( tvb, offset, pinfo, tree);
1064 case MSPROXY_TCP_BIND_ACK:
1065 dissect_tcp_bind_ack( tvb, offset, pinfo, tree);
1068 case MSPROXY_CONNECT_ACK:
1069 dissect_connect_ack( tvb, offset, pinfo, tree,
1073 case MSPROXY_BINDINFO:
1074 dissect_bind_info( tvb, offset, pinfo, tree, conv_info);
1077 case MSPROXY_RESOLVE_ACK:
1078 dissect_resolve( tvb, offset, pinfo, tree);
1081 case MSPROXY_CONNECT_AUTHFAILED:
1082 case MSPROXY_BIND_AUTHFAILED:
1083 proto_tree_add_text( tree, tvb, offset, 0, "No know information (help wanted)");
1089 (((cmd >> 8) == MSPROXY_CONNREFUSED) ||
1090 ((cmd >> 12) == MSPROXY_CONNREFUSED)))
1091 proto_tree_add_text( tree, tvb, offset, 0,
1092 "No know information (help wanted)");
1095 proto_tree_add_text( tree, tvb, offset, 0,
1096 "Unhandled response command (report this, please)");
1104 static void dissect_msproxy(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
1107 proto_tree *msproxy_tree = NULL;
1112 hash_entry_t *hash_info;
1113 conversation_t *conversation;
1115 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1116 col_set_str(pinfo->cinfo, COL_PROTOCOL, "MSproxy");
1117 if (check_col(pinfo->cinfo, COL_INFO))
1118 col_clear(pinfo->cinfo, COL_INFO);
1120 conversation = find_conversation( &pinfo->src, &pinfo->dst,
1121 pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
1123 if ( !conversation) {
1124 conversation = conversation_new( &pinfo->src, &pinfo->dst,
1125 pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
1127 hash_info = conversation_get_proto_data(conversation, proto_msproxy);
1129 hash_info = g_mem_chunk_alloc(vals);
1130 conversation_add_proto_data(conversation, proto_msproxy,
1134 if (check_col(pinfo->cinfo, COL_INFO)){
1136 cmd = tvb_get_ntohs( tvb, 36);
1138 if ( pinfo->srcport == UDP_PORT_MSPROXY)
1139 col_add_fstr( pinfo->cinfo, COL_INFO, "Server message: %s",
1140 get_msproxy_cmd_name( cmd, FROM_SERVER));
1142 col_add_fstr(pinfo->cinfo, COL_INFO, "Client message: %s",
1143 get_msproxy_cmd_name( cmd, FROM_CLIENT));
1147 if (tree) { /* if proto tree, decode data */
1148 ti = proto_tree_add_item( tree, proto_msproxy, tvb, 0,
1149 tvb_length(tvb), FALSE );
1151 msproxy_tree = proto_item_add_subtree(ti, ett_msproxy);
1154 if ( pinfo->srcport == UDP_PORT_MSPROXY)
1155 dissect_msproxy_response( tvb, pinfo, msproxy_tree, hash_info);
1157 dissect_msproxy_request( tvb, pinfo, msproxy_tree, hash_info);
1162 static void msproxy_reinit( void){
1164 /* Do the cleanup work when a new pass through the packet list is */
1165 /* performed. Reset the highest row seen counter and re-initialize the */
1166 /* conversation memory chunks. */
1171 g_mem_chunk_destroy(vals);
1173 vals = g_mem_chunk_new("msproxy_vals", hash_val_length,
1174 hash_init_count * hash_val_length,
1178 g_mem_chunk_destroy(redirect_vals);
1180 redirect_vals = g_mem_chunk_new("msproxy_redirect_vals", redirect_val_length,
1181 redirect_init_count * redirect_val_length,
1188 proto_register_msproxy( void){
1190 /* Prep the msproxy protocol, for now, just register it */
1192 static gint *ett[] = {
1196 static hf_register_info hf[] = {
1199 { "Command", "msproxy.command", FT_UINT16, BASE_DEC,
1200 NULL, 0x0, "", HFILL
1204 { &hf_msproxy_dstaddr,
1205 { "Destination Address", "msproxy.dstaddr", FT_IPv4, BASE_NONE, NULL,
1210 { &hf_msproxy_srcport,
1211 { "Source Port", "msproxy.srcport", FT_UINT16,
1212 BASE_DEC, NULL, 0x0, "", HFILL
1215 { &hf_msproxy_dstport,
1216 { "Destination Port", "msproxy.dstport", FT_UINT16,
1217 BASE_DEC, NULL, 0x0, "", HFILL
1220 { &hf_msproxy_clntport,
1221 { "Client Port", "msproxy.clntport", FT_UINT16,
1222 BASE_DEC, NULL, 0x0, "", HFILL
1225 { &hf_msproxy_server_ext_addr,
1226 { "Server External Address", "msproxy.server_ext_addr", FT_IPv4, BASE_NONE, NULL,
1231 { &hf_msproxy_server_ext_port,
1232 { "Server External Port", "msproxy.server_ext_port", FT_UINT16,
1233 BASE_DEC, NULL, 0x0, "", HFILL
1237 { &hf_msproxy_server_int_addr,
1238 { "Server Internal Address", "msproxy.server_int_addr", FT_IPv4, BASE_NONE, NULL,
1243 { &hf_msproxy_server_int_port,
1244 { "Server Internal Port", "msproxy.server_int_port", FT_UINT16,
1245 BASE_DEC, NULL, 0x0, "", HFILL
1248 { &hf_msproxy_serverport,
1249 { "Server Port", "msproxy.serverport", FT_UINT16,
1250 BASE_DEC, NULL, 0x0, "", HFILL
1253 { &hf_msproxy_bindport,
1254 { "Bind Port", "msproxy.bindport", FT_UINT16,
1255 BASE_DEC, NULL, 0x0, "", HFILL
1258 { &hf_msproxy_boundport,
1259 { "Bound Port", "msproxy.boundport", FT_UINT16,
1260 BASE_DEC, NULL, 0x0, "", HFILL
1263 { &hf_msproxy_serveraddr,
1264 { "Server Address", "msproxy.serveraddr", FT_IPv4, BASE_NONE, NULL,
1268 { &hf_msproxy_bindaddr,
1269 { "Destination", "msproxy.bindaddr", FT_IPv4, BASE_NONE, NULL,
1273 { &hf_msproxy_bind_id,
1274 { "Bound Port Id", "msproxy.bindid", FT_UINT32,
1275 BASE_HEX, NULL, 0x0, "", HFILL
1278 { &hf_msproxy_resolvaddr,
1279 { "Address", "msproxy.resolvaddr", FT_IPv4, BASE_NONE, NULL,
1286 proto_msproxy = proto_register_protocol( "MS Proxy Protocol",
1287 "MS Proxy", "msproxy");
1289 proto_register_field_array(proto_msproxy, hf, array_length(hf));
1290 proto_register_subtree_array(ett, array_length(ett));
1292 register_init_routine( &msproxy_reinit); /* register re-init routine */
1294 msproxy_sub_handle = create_dissector_handle(msproxy_sub_dissector,
1300 proto_reg_handoff_msproxy(void) {
1302 /* dissector install routine */
1304 dissector_handle_t msproxy_handle;
1306 msproxy_handle = create_dissector_handle(dissect_msproxy,
1308 dissector_add("udp.port", UDP_PORT_MSPROXY, msproxy_handle);