2 * Routines for Microsoft Proxy packet dissection
3 * Copyright 2000, Jeffrey C. Foster <jfoste@woodward.com>
5 * $Id: packet-msproxy.c,v 1.15 2001/01/03 06:55:30 guy Exp $
7 * Ethereal - Network traffic analyzer
8 * By Gerald Combs <gerald@zing.org>
9 * Copyright 1998 Gerald Combs
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27 * This was derived from the dante socks implimentation source code.
28 * Most of the information came from common.h and msproxy_clientprotocol.c
30 * See http://www.inet.no/dante for more information
34 /************************************************************************
36 * Notes: These are possible command values. User input is welcome *
38 * Command = 0x040a - Remote host closed connection (maybe ?? ) *
39 * Command = 0x0411 - Remote host closed connection *
40 * Command = 0x0413 - Local host closed connection or SYN worked *
42 ************************************************************************/
51 #ifdef HAVE_SYS_TYPES_H
52 # include <sys/types.h>
55 #ifdef HAVE_NETINET_IN_H
56 # include <netinet/in.h>
63 #ifdef NEED_SNPRINTF_H
64 # include "snprintf.h"
70 #include "alignment.h"
71 #include "conversation.h"
73 #include "packet-tcp.h"
74 #include "packet-udp.h"
76 #define CHECK_PACKET_LENGTH(X) if (!BYTES_ARE_IN_FRAME(offset, X)){ \
77 proto_tree_add_text(tree, NullTVB, offset, 0, "****FRAME TOO SHORT***"); return;}
79 extern void udp_hash_add(guint16 proto,
80 void (*dissect)(const u_char *, int, frame_data *, proto_tree *));
83 static int proto_msproxy = -1;
85 static int ett_msproxy = -1;
86 static int ett_msproxy_name = -1;
88 static int hf_msproxy_cmd = -1;
89 static int hf_msproxy_clntport = -1;
91 static int hf_msproxy_dstaddr = -1;
93 static int hf_msproxy_srcport = -1;
94 static int hf_msproxy_dstport = -1;
95 static int hf_msproxy_serverport = -1;
96 static int hf_msproxy_serveraddr = -1;
97 static int hf_msproxy_bindport = -1;
98 static int hf_msproxy_bindaddr = -1;
99 static int hf_msproxy_boundport = -1;
100 static int hf_msproxy_bind_id = -1;
101 static int hf_msproxy_resolvaddr = -1;
103 static int hf_msproxy_server_int_addr = -1;
104 static int hf_msproxy_server_int_port = -1;
105 static int hf_msproxy_server_ext_addr = -1;
106 static int hf_msproxy_server_ext_port = -1;
109 #define UDP_PORT_MSPROXY 1745
111 #define N_MSPROXY_HELLO 0x05 /* packet 1 from client */
112 #define N_MSPROXY_ACK 0x10 /* packet 1 from server */
113 #define N_MSPROXY_USERINFO_ACK 0x04 /* packet 2 from server */
114 #define N_MSPROXY_AUTH 0x47 /* packet 3 from client */
115 #define N_MSPROXY_RESOLVE 0x07 /* Resolve request */
118 /*$$$ 0x0500 was dante value, I see 0x05ff and 0x0500 */
120 #define MSPROXY_HELLO 0x0500
121 #define MSPROXY_HELLO_2 0x05ff
123 #define MSPROXY_HELLO_ACK 0x1000
125 #define MSPROXY_USERINFO 0x1000
126 #define MSPROXY_USERINFO_ACK 0x0400
128 #define MSPROXY_AUTH 0x4700
129 #define MSPROXY_AUTH_1_ACK 0x4714
130 #define MSPROXY_AUTH_2 0x4701
131 #define MSPROXY_AUTH_2_ACK 0x4715
132 #define MSPROXY_AUTH_2_ACK2 0x4716
134 #define MSPROXY_RESOLVE 0x070d
135 #define MSPROXY_RESOLVE_ACK 0x070f
137 #define MSPROXY_BIND 0x0704
138 #define MSPROXY_BIND_ACK 0x0706
140 #define MSPROXY_TCP_BIND 0x0707
141 #define MSPROXY_TCP_BIND_ACK 0x0708
143 #define MSPROXY_LISTEN 0x0406
145 #define MSPROXY_BINDINFO 0x0709
147 #define MSPROXY_BINDINFO_ACK 0x070a
149 #define MSPROXY_CONNECT 0x071e
150 #define MSPROXY_CONNECT_ACK 0x0703
152 #define MSPROXY_UDPASSOCIATE 0x0705
153 #define MSPROXY_UDPASSOCIATE_ACK 0x0706
155 #define MSPROXY_UDP_BIND_REQ 0x070b
157 #define MSPROXY_CONNECTED 0x042c
158 #define MSPROXY_SESSIONEND 0x251e
160 #define MSPROXY_BIND_AUTHFAILED 0x0804
161 #define MSPROXY_CONNECT_AUTHFAILED 0x081e
162 #define MSPROXY_CONNREFUSED 0x4 /* low 12 bits seem to vary. */
164 #define FROM_SERVER 1 /* direction of packet data for get_msproxy_cmd_name */
165 #define FROM_CLIENT 0
170 /*$$$ should this be the same as redirect_entry_t ?? */
171 /* then the add_conversation could just copy the structure */
172 /* using the same allocation (instance for you object guys) */
173 /* wouldn't work because there may be multiple child conversations */
174 /* from the same MSProxy conversation */
180 guint32 server_int_port;
185 /************** conversation hash stuff ***************/
187 #define hash_init_count 20
188 #define hash_val_length (sizeof(hash_entry_t))
190 static GMemChunk *vals = NULL;
195 guint32 server_int_port;
201 /************** negotiated conversation hash stuff ***************/
203 #define redirect_init_count 20
204 #define redirect_val_length (sizeof(redirect_entry_t))
206 static GMemChunk *redirect_vals = NULL;
209 static guint32 last_row= 0; /* used to see if packet is new */
211 static void msproxy_sub_dissector( const u_char *pd, int offset, frame_data *fd,
214 /* Conversation dissector called from TCP or UDP dissector. Decode and */
215 /* display the socks header, the pass the rest of the data to the tcp */
216 /* or udp port decode routine to handle the payload. */
219 redirect_entry_t *redirect_info;
220 conversation_t *conversation;
221 proto_tree *msp_tree;
225 conversation = find_conversation( &pi.src, &pi.dst, pi.ptype,
226 pi.srcport, pi.destport, 0);
228 g_assert( conversation); /* should always find a conversation */
230 redirect_info = (redirect_entry_t*)conversation->data;
232 if (check_col(fd, COL_PROTOCOL))
233 col_set_str(fd, COL_PROTOCOL, "MS Proxy");
235 if (check_col(fd, COL_INFO))
236 col_add_fstr(fd, COL_INFO, "%s",
237 (( redirect_info->proto == PT_TCP) ? "TCP stream" :
241 ti = proto_tree_add_item( tree, proto_msproxy, NullTVB, offset, 0,
244 msp_tree = proto_item_add_subtree(ti, ett_msproxy);
246 proto_tree_add_uint( msp_tree, hf_msproxy_dstport, NullTVB,
247 offset, 0, redirect_info->remote_port);
249 proto_tree_add_ipv4( msp_tree, hf_msproxy_dstaddr, NullTVB, offset, 0,
250 redirect_info->remote_addr);
254 /* set pi src/dst port and call the udp sub-dissector lookup */
256 if ( pi.srcport == redirect_info->clnt_port)
261 *ptr = redirect_info->remote_port;
263 tvb = tvb_create_from_top(0);
264 if ( redirect_info->proto == PT_TCP)
265 decode_tcp_ports( tvb, offset, &pi, tree, pi.srcport, pi.destport);
267 decode_udp_ports( tvb, offset, &pi, tree, pi.srcport, pi.destport);
269 *ptr = redirect_info->server_int_port;
274 static void add_msproxy_conversation( hash_entry_t *hash_info){
276 /* check to see if a conversation already exists, if it does assume */
277 /* it's our conversation and quit. Otherwise create a new conversation. */
278 /* Load the conversation dissector to our dissector and load the */
279 /* conversation data structure with the info needed to call the TCP or */
280 /* UDP port decoder. */
282 /* NOTE: Currently this assume that the conversation will be created */
283 /* during a packet from the server. If that changes, the pi.src */
284 /* and pi.dst will not be correct and this routine will have to */
287 redirect_entry_t *new_conv_info;
289 conversation_t *conversation = find_conversation( &pi.src, &pi.dst,
290 hash_info->proto, hash_info->server_int_port,
291 hash_info->clnt_port, 0);
296 new_conv_info = g_mem_chunk_alloc(redirect_vals);
297 conversation = conversation_new( &pi.src, &pi.dst, hash_info->proto,
298 hash_info->server_int_port, hash_info->clnt_port,
301 g_assert( new_conv_info);
302 g_assert( conversation);
304 new_conv_info->remote_addr = hash_info->dst_addr;
305 new_conv_info->clnt_port = hash_info->clnt_port;
306 new_conv_info->remote_port = hash_info->dst_port;
307 new_conv_info->server_int_port = hash_info->server_int_port;
308 new_conv_info->proto = hash_info->proto;
310 old_conversation_set_dissector(conversation, msproxy_sub_dissector);
315 static int display_application_name(const u_char *pd, int offset,
316 frame_data *fd, proto_tree *tree) {
318 /* display the application name in the proto tree. */
320 /* NOTE: this routine assumes that the tree pointer is valid (not NULL) */
324 if (!IS_DATA_IN_FRAME(offset)){
325 proto_tree_add_text(tree, NullTVB, offset, 0, "****FRAME TOO SHORT***");
329 strncpy( temp, &pd[ offset], MIN( 255, END_OF_FRAME));
330 temp[ MIN( 255, END_OF_FRAME)] = 0;
331 proto_tree_add_text( tree, NullTVB, offset, strlen(temp), "Application: %s", temp);
338 static char *get_msproxy_cmd_name( int cmd, int direction) {
340 /* return the command name string for cmd */
343 case MSPROXY_HELLO_2:
344 case MSPROXY_HELLO: return "Hello";
346 /* MSPROXY_HELLO_ACK & MSPROXY_USERINFO have the same value (0x1000). */
347 /* So use the direction flag to determine which to use. */
349 case MSPROXY_USERINFO:
350 if ( direction == FROM_SERVER)
351 return "Hello Acknowledge";
354 case MSPROXY_USERINFO_ACK: return "User Info Acknowledge";
355 case MSPROXY_AUTH: return "Authentication";
356 case MSPROXY_AUTH_1_ACK: return "Authentication Acknowledge";
357 case MSPROXY_AUTH_2: return "Authentication 2";
358 case MSPROXY_AUTH_2_ACK: return "Authentication 2 Acknowledge";
359 case MSPROXY_RESOLVE: return "Resolve";
360 case MSPROXY_RESOLVE_ACK: return "Resolve Acknowledge";
361 case MSPROXY_BIND: return "Bind";
362 case MSPROXY_TCP_BIND: return "TCP Bind";
363 case MSPROXY_TCP_BIND_ACK: return "TCP Bind Acknowledge";
364 case MSPROXY_LISTEN: return "Listen";
365 case MSPROXY_BINDINFO: return "Bind Info";
366 case MSPROXY_BINDINFO_ACK: return "Bind Info Acknowledge";
367 case MSPROXY_CONNECT: return "Connect";
368 case MSPROXY_CONNECT_ACK: return "Connect Acknowledge";
369 case MSPROXY_UDPASSOCIATE: return "UDP Associate";
370 case MSPROXY_UDP_BIND_REQ: return "UDP Bind";
371 case MSPROXY_UDPASSOCIATE_ACK: return "Bind or Associate Acknowledge";
372 case MSPROXY_CONNECTED: return "Connected";
373 case MSPROXY_SESSIONEND: return "Session End";
375 default: return "Unknown";
381 static void dissect_user_info_2(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
383 /* decode the user, application, computer name */
389 strncpy( str, &pd[ offset], MIN( 255, END_OF_FRAME));
390 str[ MIN( 255, END_OF_FRAME)] = 0;
392 proto_tree_add_text( tree, NullTVB, offset, strlen( str) + 1,
393 "User name: %s", str);
394 offset += strlen( str) + 2;
396 strncpy( str, &pd[ offset], MIN( 255, END_OF_FRAME));
397 str[ MIN( 255, END_OF_FRAME)] = 0;
399 proto_tree_add_text( tree, NullTVB, offset, strlen( str) + 1,
400 "Application name: %s", str);
401 offset += strlen( str) + 1;
403 strncpy( str, &pd[ offset], MIN( 255, END_OF_FRAME));
404 str[ MIN( 255, END_OF_FRAME)] = 0;
406 proto_tree_add_text( tree, NullTVB, offset, strlen( str) + 1,
407 "Client computer name: %s", str);
413 static void dissect_msproxy_request_1(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
415 /* decode the request _1 structure */
420 dissect_user_info_2( pd, 262, fd, tree);
426 static void dissect_bind(const u_char *pd, int offset, frame_data *fd,
427 proto_tree *tree, hash_entry_t *conv_info) {
429 /* decode the bind request */
433 CHECK_PACKET_LENGTH( 4);
435 proto_tree_add_ipv4( tree, hf_msproxy_bindaddr, NullTVB, offset, 4,
439 CHECK_PACKET_LENGTH( 2);
441 proto_tree_add_uint( tree, hf_msproxy_bindport, NullTVB, offset, 2,
442 pntohs( &pd[ offset]));
445 CHECK_PACKET_LENGTH( 2);
447 proto_tree_add_uint( tree, hf_msproxy_clntport, NullTVB, offset, 2,
448 pntohs( &pd[ offset]));
451 conv_info->clnt_port = pntohs( &pd[ offset]);
455 CHECK_PACKET_LENGTH( 2);
456 proto_tree_add_uint( tree, hf_msproxy_boundport, NullTVB, offset, 2,
457 pntohs( &pd[ offset]));
460 display_application_name( pd, offset, fd, tree);
466 static void dissect_auth(const u_char *pd, int offset,
467 frame_data *fd, proto_tree *tree) {
469 /* decode the authorization request */
476 strncpy( temp, &pd[ offset], 7);
478 proto_tree_add_text( tree, NullTVB, offset, 7, "NTLMSSP signature: %s",
486 static void dissect_tcp_bind(const u_char *pd, int offset,
487 frame_data *fd, proto_tree *tree, hash_entry_t *conv_info) {
489 /* decode the bind packet. Set the protocol type in the conversation */
490 /* information so the bind_info can use it to create the payload */
494 conv_info->proto = PT_TCP;
499 CHECK_PACKET_LENGTH( 4);
500 proto_tree_add_uint( tree, hf_msproxy_bind_id, NullTVB, offset, 4, pntohl( &pd[ offset]));
503 CHECK_PACKET_LENGTH( 2);
504 proto_tree_add_uint( tree, hf_msproxy_boundport, NullTVB, offset, 2,
505 pntohs( &pd[ offset]));
508 display_application_name( pd, offset, fd, tree);
513 static void dissect_request_connect(const u_char *pd, int offset, frame_data *fd,
514 proto_tree *tree, hash_entry_t *conv_info) {
516 /* decode the connect request, display */
518 conv_info->proto = PT_TCP;
522 CHECK_PACKET_LENGTH( 2);
524 proto_tree_add_uint( tree, hf_msproxy_dstport, NullTVB, offset, 2,
525 pntohs( &pd[ offset]));
527 conv_info->dst_port = pntohs( &pd[ offset]);
530 CHECK_PACKET_LENGTH( 4);
532 proto_tree_add_ipv4( tree, hf_msproxy_dstaddr, NullTVB, offset, 4,
535 memcpy( &conv_info->dst_addr, &pd[ offset], sizeof( guint32));
539 CHECK_PACKET_LENGTH( 2);
540 conv_info->clnt_port = pntohs( &pd[ offset]);
543 proto_tree_add_uint( tree, hf_msproxy_clntport, NullTVB, offset, 2,
544 pntohs( &pd[ offset]));
548 display_application_name( pd, offset, fd, tree);
553 static void dissect_bind_info_ack(const u_char *pd, int offset, frame_data *fd,
554 proto_tree *tree, hash_entry_t *conv_info) {
556 /* decode the client bind info ack */
562 CHECK_PACKET_LENGTH( 4);
563 proto_tree_add_uint( tree, hf_msproxy_bind_id, NullTVB, offset, 4, pntohl( &pd[ offset]));
566 CHECK_PACKET_LENGTH( 2);
567 proto_tree_add_uint( tree, hf_msproxy_dstport, NullTVB, offset, 2,
568 pntohs( &pd[ offset]));
571 CHECK_PACKET_LENGTH( 4);
572 proto_tree_add_ipv4( tree, hf_msproxy_dstaddr, NullTVB, offset, 4,
576 CHECK_PACKET_LENGTH( 2);
577 proto_tree_add_uint( tree, hf_msproxy_server_int_port, NullTVB, offset,
578 2, pntohs( &pd[ offset]));
581 CHECK_PACKET_LENGTH( 2);
582 proto_tree_add_uint( tree, hf_msproxy_server_ext_port, NullTVB, offset,
583 2, pntohs( &pd[ offset]));
586 CHECK_PACKET_LENGTH( 4);
587 proto_tree_add_ipv4( tree, hf_msproxy_server_ext_addr, NullTVB, offset,
588 4, GWORD( pd, offset));
591 display_application_name( pd, offset, fd, tree);
596 static void dissect_request_resolve(const u_char *pd, int offset,
597 frame_data *fd, proto_tree *tree) {
599 /* dissect the request resolve structure */
600 /* display a string with a length, characters encoding */
601 /* they are displayed under a tree with the name in Label variable */
602 /* return the length of the string and the length byte */
604 proto_tree *name_tree;
608 int length = GBYTE( pd, offset);
611 strncpy( temp, &pd[ offset + 18], length);
614 ti = proto_tree_add_text(tree, NullTVB, offset, length + 1,
615 "Host Name: %s", temp);
617 name_tree = proto_item_add_subtree(ti, ett_msproxy_name);
619 proto_tree_add_text( name_tree, NullTVB, offset, 1, "Length: %d", length);
624 proto_tree_add_text( name_tree, NullTVB, offset, length, "String: %s",
631 static void dissect_udp_bind(const u_char *pd, int offset,
632 frame_data *fd, proto_tree *tree, hash_entry_t *conv_info) {
634 /* Dissect the udp bind request. Load the protocol id (PT_UDP) and the */
635 /* remote address so bind_info can use it to create conversation */
638 conv_info->proto = PT_UDP;
643 CHECK_PACKET_LENGTH( 4);
645 proto_tree_add_uint( tree, hf_msproxy_bind_id, NullTVB, offset, 4, pntohl( &pd[ offset]));
649 CHECK_PACKET_LENGTH( 2);
651 proto_tree_add_uint( tree, hf_msproxy_dstport, NullTVB, offset, 2,
652 pntohs( &pd[ offset]));
655 CHECK_PACKET_LENGTH( 4);
657 proto_tree_add_ipv4( tree, hf_msproxy_dstaddr, NullTVB, offset, 4,
663 display_application_name( pd, offset, fd, tree);
667 static void dissect_udp_assoc(const u_char *pd, int offset,
668 frame_data *fd, proto_tree *tree, hash_entry_t *conv_info) {
670 /* dissect the udp associate request. And load client port into */
671 /* conversation data structure for later. */
676 CHECK_PACKET_LENGTH( 2);
678 proto_tree_add_uint( tree, hf_msproxy_clntport, NullTVB, offset, 2,
679 pntohs( &pd[ offset]));
681 conv_info->clnt_port = pntohs( &pd[ offset]);
686 display_application_name( pd, offset, fd, tree);
692 static void dissect_msproxy_request(const u_char *pd, int offset, frame_data *fd,
693 proto_tree *tree, hash_entry_t *conv_info) {
699 CHECK_PACKET_LENGTH( 4);
700 proto_tree_add_text( tree, NullTVB, offset, 4, "Client id: 0x%0x",
704 CHECK_PACKET_LENGTH( 4);
705 proto_tree_add_text( tree, NullTVB, offset, 4, "Version: 0x%04x",
709 CHECK_PACKET_LENGTH( 4);
710 proto_tree_add_text( tree, NullTVB, offset, 4, "Server id: 0x%0x",
714 CHECK_PACKET_LENGTH( 2);
715 proto_tree_add_text( tree, NullTVB, offset, 1, "Server ack: %u",
719 CHECK_PACKET_LENGTH( 1);
720 proto_tree_add_text( tree, NullTVB, offset, 1, "Sequence Number: %u",
724 CHECK_PACKET_LENGTH( 4);
725 strncpy( temp, &pd[ offset], 4);
727 proto_tree_add_text( tree, NullTVB, offset, 4, "RWSP signature: %s", temp);
733 CHECK_PACKET_LENGTH( 1);
734 cmd = pntohs( &pd[offset]);
737 proto_tree_add_uint_format( tree, hf_msproxy_cmd, NullTVB, offset, 2,
738 cmd, "Command: 0x%02x (%s)", cmd,
739 get_msproxy_cmd_name( cmd, FROM_CLIENT));
745 dissect_auth( pd, offset, fd, tree);
749 dissect_bind( pd, offset, fd, tree, conv_info);
752 case MSPROXY_UDP_BIND_REQ:
753 dissect_udp_bind( pd, offset, fd, tree, conv_info);
756 case MSPROXY_AUTH_2: /*$$ this is probably wrong place for this */
757 case MSPROXY_TCP_BIND:
758 dissect_tcp_bind( pd, offset, fd, tree, conv_info);
761 case MSPROXY_RESOLVE:
762 dissect_request_resolve( pd, offset, fd, tree);
765 case MSPROXY_CONNECT:
767 dissect_request_connect( pd, offset, fd, tree,
771 case MSPROXY_BINDINFO_ACK:
772 dissect_bind_info_ack( pd, offset, fd, tree, conv_info);
776 case MSPROXY_HELLO_2:
777 dissect_msproxy_request_1( pd, offset, fd, tree);
780 case MSPROXY_UDPASSOCIATE:
781 dissect_udp_assoc( pd, offset, fd, tree, conv_info);
785 proto_tree_add_text( tree, NullTVB, offset, 0,
786 "Unhandled request command (report this, please)");
792 static void dissect_hello_ack(const u_char *pd, int offset, frame_data *fd,
793 proto_tree *tree, hash_entry_t *conv_info) {
795 /* decode the hello acknowledge packet */
800 CHECK_PACKET_LENGTH( 2);
801 proto_tree_add_uint( tree, hf_msproxy_serverport, NullTVB, offset, 2,
802 pntohs( &pd[ offset]));
805 CHECK_PACKET_LENGTH( 4);
806 proto_tree_add_ipv4( tree, hf_msproxy_serveraddr, NullTVB, offset, 4,
814 static void dissect_user_info_ack(const u_char *pd, int offset,
815 frame_data *fd, proto_tree *tree) {
817 /* decode the response _2 structure */
827 static void dissect_udpassociate_ack( const u_char *pd, int offset,
828 frame_data *fd, proto_tree *tree) {
834 CHECK_PACKET_LENGTH( 4);
835 proto_tree_add_uint( tree, hf_msproxy_bind_id, NullTVB, offset, 4, pntohl( &pd[ offset]));
838 CHECK_PACKET_LENGTH( 2);
839 proto_tree_add_uint( tree, hf_msproxy_server_ext_port, NullTVB, offset, 2, pntohs( &pd[ offset]));
842 CHECK_PACKET_LENGTH( 4);
843 proto_tree_add_ipv4( tree, hf_msproxy_server_ext_addr, NullTVB, offset, 4, GWORD( pd, offset));
846 display_application_name( pd, offset, fd, tree);
852 static void dissect_auth_1_ack(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
860 CHECK_PACKET_LENGTH( 7);
861 strncpy( temp, &pd[ offset], 7);
863 proto_tree_add_text( tree, NullTVB, offset, 7, "NTLMSSP signature: %s", temp);
866 strncpy( temp, &pd[ offset], MIN( 255, END_OF_FRAME));
867 temp[ MIN( 255, END_OF_FRAME)] = 0;
868 proto_tree_add_text( tree, NullTVB, offset, 255, "NT domain: %s", temp);
875 static void dissect_msproxy_response_4( const u_char *pd, int offset,
876 frame_data *fd, proto_tree *tree) {
878 /* decode the response _4 structure */
885 static void dissect_connect_ack( const u_char *pd, int offset, frame_data *fd,
886 proto_tree *tree, hash_entry_t *conv_info) {
888 /* decode the connect ack packet */
891 CHECK_PACKET_LENGTH( 2);
894 proto_tree_add_uint( tree, hf_msproxy_server_int_port, NullTVB, offset, 2, pntohs( &pd[ offset]));
897 conv_info->proto = PT_TCP;
898 conv_info->server_int_port = pntohs( &pd[ offset]);
902 CHECK_PACKET_LENGTH( 2);
903 proto_tree_add_ipv4( tree, hf_msproxy_server_int_addr, NullTVB, offset, 2, GWORD( pd, offset));
906 CHECK_PACKET_LENGTH( 2);
907 proto_tree_add_uint( tree, hf_msproxy_server_ext_port, NullTVB, offset, 2, pntohs( &pd[ offset]));
910 CHECK_PACKET_LENGTH( 4);
911 proto_tree_add_ipv4( tree, hf_msproxy_server_ext_addr, NullTVB, offset, 4, GWORD( pd, offset));
914 display_application_name( pd, offset, fd, tree);
917 add_msproxy_conversation( conv_info);
922 static void dissect_tcp_bind_ack( const u_char *pd, int offset, frame_data *fd,
925 /* decode the tcp bind */
930 CHECK_PACKET_LENGTH( 4);
931 proto_tree_add_uint( tree, hf_msproxy_bind_id, NullTVB, offset, 4, pntohl( &pd[ offset]));
934 CHECK_PACKET_LENGTH( 2);
935 proto_tree_add_uint( tree, hf_msproxy_server_int_port, NullTVB, offset,
936 2, pntohs( &pd[ offset]));
939 CHECK_PACKET_LENGTH( 2);
940 proto_tree_add_uint( tree, hf_msproxy_server_ext_port, NullTVB, offset,
941 2, pntohs( &pd[ offset]));
944 CHECK_PACKET_LENGTH( 4);
945 proto_tree_add_ipv4( tree, hf_msproxy_server_ext_addr, NullTVB, offset,
946 4, GWORD( pd, offset));
950 display_application_name( pd, offset, fd, tree);
956 static void dissect_bind_info( const u_char *pd, int offset, frame_data *fd,
957 proto_tree *tree, hash_entry_t *conv_info) {
959 /* decode the Bind info response from server */
963 CHECK_PACKET_LENGTH( 4);
965 proto_tree_add_uint( tree, hf_msproxy_bind_id, NullTVB, offset, 4, pntohl( &pd[ offset]));
969 CHECK_PACKET_LENGTH( 2);
971 proto_tree_add_uint( tree, hf_msproxy_dstport, NullTVB, offset, 2,
972 pntohs( &pd[ offset]));
973 conv_info->dst_port = pntohs( &pd[ offset]);
976 CHECK_PACKET_LENGTH( 4);
978 proto_tree_add_ipv4( tree, hf_msproxy_dstaddr, NullTVB, offset, 4,
981 memcpy( &conv_info->dst_addr, &pd[ offset], sizeof( guint32));
985 CHECK_PACKET_LENGTH( 2);
987 proto_tree_add_uint( tree, hf_msproxy_server_int_port, NullTVB, offset,
988 2, pntohs( &pd[ offset]));
989 conv_info->server_int_port = pntohs( &pd[ offset]);
994 CHECK_PACKET_LENGTH( 2);
995 proto_tree_add_uint( tree, hf_msproxy_server_ext_port, NullTVB, offset,
996 2, pntohs( &pd[ offset]));
999 CHECK_PACKET_LENGTH( 4);
1000 proto_tree_add_ipv4( tree, hf_msproxy_server_ext_addr, NullTVB, offset,
1001 4, GWORD( pd, offset));
1004 display_application_name( pd, offset, fd, tree);
1008 add_msproxy_conversation( conv_info);
1013 static void dissect_resolve(const u_char *pd, int offset, frame_data *fd,
1016 /* dissect the response resolve structure */
1017 /* display a string with a length, characters encoding */
1018 /* they are displayed under a tree with the name in Label variable */
1019 /* return the length of the string and the length byte */
1023 int addr_offset = GBYTE( pd, offset);
1025 proto_tree_add_text( tree, NullTVB, offset, 1, "Address offset: %d",
1032 offset += addr_offset;
1034 CHECK_PACKET_LENGTH( 4);
1035 proto_tree_add_ipv4( tree, hf_msproxy_resolvaddr, NullTVB, offset, 4,
1036 GWORD( pd, offset));
1042 static void dissect_msproxy_response(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, hash_entry_t *conv_info) {
1049 CHECK_PACKET_LENGTH( 4);
1050 proto_tree_add_text( tree, NullTVB, offset, 4, "Client id: 0x%0x",
1051 GWORD( pd, offset));
1054 CHECK_PACKET_LENGTH( 4);
1055 proto_tree_add_text( tree, NullTVB, offset, 4, "Version: 0x%04x",
1056 GWORD( pd, offset));
1059 CHECK_PACKET_LENGTH( 4);
1060 proto_tree_add_text( tree, NullTVB, offset, 4, "Server id: 0x%04x",
1061 GWORD( pd, offset));
1064 CHECK_PACKET_LENGTH( 1);
1065 proto_tree_add_text( tree, NullTVB, offset, 1, "Client ack: 0x%02x",
1066 GBYTE( pd, offset));
1070 CHECK_PACKET_LENGTH( 1);
1071 proto_tree_add_text( tree, NullTVB, offset, 1, "Sequence Number: 0x%02x",
1072 GBYTE( pd, offset));
1076 CHECK_PACKET_LENGTH( 4);
1077 strncpy( temp, &pd[ offset], 4);
1079 proto_tree_add_text( tree, NullTVB, offset, 4, "RWSP signature: %s", temp);
1086 CHECK_PACKET_LENGTH( 2);
1087 cmd = pntohs( &pd[offset]);
1090 proto_tree_add_uint_format( tree, hf_msproxy_cmd, NullTVB, offset, 2,
1091 cmd, "Command: 0x%02x (%s)", cmd,
1092 get_msproxy_cmd_name( cmd, FROM_SERVER));
1096 case MSPROXY_HELLO_ACK:
1097 dissect_hello_ack( pd, offset, fd, tree, conv_info);
1100 case MSPROXY_USERINFO_ACK:
1101 dissect_user_info_ack( pd, offset, fd, tree);
1104 case MSPROXY_AUTH_1_ACK:
1105 dissect_auth_1_ack( pd, offset, fd, tree);
1108 /* this also handle the MSPROXY_BIND_ACK ??? check this */
1110 case MSPROXY_UDPASSOCIATE_ACK:
1111 dissect_udpassociate_ack( pd, offset, fd, tree);
1114 case MSPROXY_AUTH_2_ACK:
1115 case MSPROXY_AUTH_2_ACK2:
1116 dissect_msproxy_response_4( pd, offset, fd, tree);
1119 case MSPROXY_TCP_BIND_ACK:
1120 dissect_tcp_bind_ack( pd, offset, fd, tree);
1123 case MSPROXY_CONNECT_ACK:
1124 dissect_connect_ack( pd, offset, fd, tree, conv_info);
1127 case MSPROXY_BINDINFO:
1128 dissect_bind_info( pd, offset, fd, tree, conv_info);
1131 case MSPROXY_RESOLVE_ACK:
1132 dissect_resolve( pd, offset, fd, tree);
1135 case MSPROXY_CONNECT_AUTHFAILED:
1136 case MSPROXY_BIND_AUTHFAILED:
1137 proto_tree_add_text( tree, NullTVB, offset, 0, "No know information (help wanted)");
1143 (((cmd >> 8) == MSPROXY_CONNREFUSED) ||
1144 ((cmd >> 12) == MSPROXY_CONNREFUSED)))
1145 proto_tree_add_text( tree, NullTVB, offset, 0,
1146 "No know information (help wanted)");
1149 proto_tree_add_text( tree, NullTVB, offset, 0,
1150 "Unhandled response command (report this, please)");
1158 static void dissect_msproxy(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
1161 proto_tree *msproxy_tree = NULL;
1166 hash_entry_t *hash_info;
1167 conversation_t *conversation;
1169 OLD_CHECK_DISPLAY_AS_DATA(proto_msproxy, pd, offset, fd, tree);
1171 conversation = find_conversation( &pi.src, &pi.dst, pi.ptype,
1172 pi.srcport, pi.destport, 0);
1174 if ( conversation) /* conversation found */
1175 hash_info = conversation->data;
1177 /* new conversation create local data structure */
1179 hash_info = g_mem_chunk_alloc(vals);
1181 conversation_new( &pi.src, &pi.dst, pi.ptype,
1182 pi.srcport, pi.destport, hash_info, 0);
1185 if (check_col(fd, COL_PROTOCOL))
1186 col_set_str(fd, COL_PROTOCOL, "MSproxy");
1189 /* display packet info */
1190 if (check_col(fd, COL_INFO)){
1192 cmd = pntohs( &pd[offset + 36]);
1194 if ( pi.srcport == UDP_PORT_MSPROXY)
1195 col_add_fstr( fd, COL_INFO, "Server message: %s",
1196 get_msproxy_cmd_name( cmd, FROM_SERVER));
1198 col_add_fstr(fd, COL_INFO, "Client message: %s",
1199 get_msproxy_cmd_name( cmd, FROM_CLIENT));
1203 if (tree) { /* if proto tree, decode data */
1204 ti = proto_tree_add_item( tree, proto_msproxy, NullTVB, offset,
1205 END_OF_FRAME, FALSE );
1207 msproxy_tree = proto_item_add_subtree(ti, ett_msproxy);
1210 if ( pi.srcport == UDP_PORT_MSPROXY)
1211 dissect_msproxy_response( pd, offset, fd, msproxy_tree, hash_info);
1213 dissect_msproxy_request( pd, offset, fd, msproxy_tree, hash_info);
1218 static void msproxy_reinit( void){
1220 /* Do the cleanup work when a new pass through the packet list is */
1221 /* performed. Reset the highest row seen counter and re-initialize the */
1222 /* conversation memory chunks. */
1227 g_mem_chunk_destroy(vals);
1229 vals = g_mem_chunk_new("msproxy_vals", hash_val_length,
1230 hash_init_count * hash_val_length,
1234 g_mem_chunk_destroy(redirect_vals);
1236 redirect_vals = g_mem_chunk_new("msproxy_redirect_vals", redirect_val_length,
1237 redirect_init_count * redirect_val_length,
1244 proto_register_msproxy( void){
1246 /* Prep the msproxy protocol, for now, just register it */
1248 static gint *ett[] = {
1252 static hf_register_info hf[] = {
1255 { "Command", "msproxy.command", FT_UINT16, BASE_DEC,
1260 { &hf_msproxy_dstaddr,
1261 { "Destination Address", "msproxy.dstaddr", FT_IPv4, BASE_NONE, NULL,
1266 { &hf_msproxy_srcport,
1267 { "Source Port", "msproxy.srcport", FT_UINT16,
1268 BASE_DEC, NULL, 0x0, ""
1271 { &hf_msproxy_dstport,
1272 { "Destination Port", "msproxy.dstport", FT_UINT16,
1273 BASE_DEC, NULL, 0x0, ""
1276 { &hf_msproxy_clntport,
1277 { "Client Port", "msproxy.clntport", FT_UINT16,
1278 BASE_DEC, NULL, 0x0, ""
1281 { &hf_msproxy_server_ext_addr,
1282 { "Server External Address", "msproxy.server_ext_addr", FT_IPv4, BASE_NONE, NULL,
1287 { &hf_msproxy_server_ext_port,
1288 { "Server External Port", "msproxy.server_ext_port", FT_UINT16,
1289 BASE_DEC, NULL, 0x0, ""
1293 { &hf_msproxy_server_int_addr,
1294 { "Server Internal Address", "msproxy.server_int_addr", FT_IPv4, BASE_NONE, NULL,
1299 { &hf_msproxy_server_int_port,
1300 { "Server Internal Port", "msproxy.server_int_port", FT_UINT16,
1301 BASE_DEC, NULL, 0x0, ""
1304 { &hf_msproxy_serverport,
1305 { "Server Port", "msproxy.serverport", FT_UINT16,
1306 BASE_DEC, NULL, 0x0, ""
1309 { &hf_msproxy_bindport,
1310 { "Bind Port", "msproxy.bindport", FT_UINT16,
1311 BASE_DEC, NULL, 0x0, ""
1314 { &hf_msproxy_boundport,
1315 { "Bound Port", "msproxy.boundport", FT_UINT16,
1316 BASE_DEC, NULL, 0x0, ""
1319 { &hf_msproxy_serveraddr,
1320 { "Server Address", "msproxy.serveraddr", FT_IPv4, BASE_NONE, NULL,
1324 { &hf_msproxy_bindaddr,
1325 { "Destination", "msproxy.bindaddr", FT_IPv4, BASE_NONE, NULL,
1329 { &hf_msproxy_bind_id,
1330 { "Bound Port Id", "msproxy.bindid", FT_UINT32,
1331 BASE_HEX, NULL, 0x0, ""
1334 { &hf_msproxy_resolvaddr,
1335 { "Address", "msproxy.resolvaddr", FT_IPv4, BASE_NONE, NULL,
1342 proto_msproxy = proto_register_protocol( "MS Proxy Protocol",
1343 "MS Proxy", "msproxy");
1345 proto_register_field_array(proto_msproxy, hf, array_length(hf));
1346 proto_register_subtree_array(ett, array_length(ett));
1348 register_init_routine( &msproxy_reinit); /* register re-init routine */
1353 proto_reg_handoff_msproxy(void) {
1355 /* dissector install routine */
1357 old_dissector_add("udp.port", UDP_PORT_MSPROXY, dissect_msproxy);