2 * Routines for Microsoft Proxy packet dissection
3 * Copyright 2000, Jeffrey C. Foster <jfoste@woodward.com>
5 * $Id: packet-msproxy.c,v 1.2 2000/05/11 08:15:23 gram 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>
65 #include "alignment.h"
66 #include "conversation.h"
68 #include "packet-tcp.h"
69 #include "packet-udp.h"
72 #ifdef NEED_SNPRINTF_H
78 # include "snprintf.h"
81 #define CHECK_PACKET_LENGTH(X) if ((offset+X) > fd->cap_len){ \
82 proto_tree_add_text(tree, NullTVB, offset, 0, "****FRAME TOO SHORT***"); return;}
84 extern void udp_hash_add(guint16 proto,
85 void (*dissect)(const u_char *, int, frame_data *, proto_tree *));
88 static int proto_msproxy = -1;
90 static int ett_msproxy = -1;
91 static int ett_msproxy_name = -1;
93 static int hf_msproxy_cmd = -1;
94 static int hf_msproxy_clntport = -1;
96 static int hf_msproxy_dstaddr = -1;
98 static int hf_msproxy_srcport = -1;
99 static int hf_msproxy_dstport = -1;
100 static int hf_msproxy_serverport = -1;
101 static int hf_msproxy_serveraddr = -1;
102 static int hf_msproxy_bindport = -1;
103 static int hf_msproxy_bindaddr = -1;
104 static int hf_msproxy_boundport = -1;
105 static int hf_msproxy_bind_id = -1;
106 static int hf_msproxy_resolvaddr = -1;
108 static int hf_msproxy_server_int_addr = -1;
109 static int hf_msproxy_server_int_port = -1;
110 static int hf_msproxy_server_ext_addr = -1;
111 static int hf_msproxy_server_ext_port = -1;
114 #define UDP_PORT_MSPROXY 1745
116 #define N_MSPROXY_HELLO 0x05 /* packet 1 from client */
117 #define N_MSPROXY_ACK 0x10 /* packet 1 from server */
118 #define N_MSPROXY_USERINFO_ACK 0x04 /* packet 2 from server */
119 #define N_MSPROXY_AUTH 0x47 /* packet 3 from client */
120 #define N_MSPROXY_RESOLVE 0x07 /* Resolve request */
123 /*$$$ 0x0500 was dante value, I see 0x05ff and 0x0500 */
125 #define MSPROXY_HELLO 0x0500
126 #define MSPROXY_HELLO_2 0x05ff
128 #define MSPROXY_HELLO_ACK 0x1000
130 #define MSPROXY_USERINFO 0x1000
131 #define MSPROXY_USERINFO_ACK 0x0400
133 #define MSPROXY_AUTH 0x4700
134 #define MSPROXY_AUTH_1_ACK 0x4714
135 #define MSPROXY_AUTH_2 0x4701
136 #define MSPROXY_AUTH_2_ACK 0x4715
137 #define MSPROXY_AUTH_2_ACK2 0x4716
139 #define MSPROXY_RESOLVE 0x070d
140 #define MSPROXY_RESOLVE_ACK 0x070f
142 #define MSPROXY_BIND 0x0704
143 #define MSPROXY_BIND_ACK 0x0706
145 #define MSPROXY_TCP_BIND 0x0707
146 #define MSPROXY_TCP_BIND_ACK 0x0708
148 #define MSPROXY_LISTEN 0x0406
150 #define MSPROXY_BINDINFO 0x0709
152 #define MSPROXY_BINDINFO_ACK 0x070a
154 #define MSPROXY_CONNECT 0x071e
155 #define MSPROXY_CONNECT_ACK 0x0703
157 #define MSPROXY_UDPASSOCIATE 0x0705
158 #define MSPROXY_UDPASSOCIATE_ACK 0x0706
160 #define MSPROXY_UDP_BIND_REQ 0x070b
162 #define MSPROXY_CONNECTED 0x042c
163 #define MSPROXY_SESSIONEND 0x251e
165 #define MSPROXY_BIND_AUTHFAILED 0x0804
166 #define MSPROXY_CONNECT_AUTHFAILED 0x081e
167 #define MSPROXY_CONNREFUSED 0x4 /* low 12 bits seem to vary. */
169 #define FROM_SERVER 1 /* direction of packet data for get_msproxy_cmd_name */
170 #define FROM_CLIENT 0
175 /*$$$ should this be the same as redirect_entry_t ?? */
176 /* then the add_conversation could just copy the structure */
177 /* using the same allocation (instance for you object guys) */
178 /* wouldn't work because there may be multiple child conversations */
179 /* from the same MSProxy conversation */
185 guint32 server_int_port;
190 /************** conversation hash stuff ***************/
192 #define hash_init_count 20
193 #define hash_val_length (sizeof(hash_entry_t))
195 static GMemChunk *vals = NULL;
200 guint32 server_int_port;
206 /************** negotiated conversation hash stuff ***************/
208 #define redirect_init_count 20
209 #define redirect_val_length (sizeof(redirect_entry_t))
211 static GMemChunk *redirect_vals = NULL;
214 static guint32 last_row= 0; /* used to see if packet is new */
216 static void msproxy_sub_dissector( const u_char *pd, int offset, frame_data *fd,
219 /* Conversation dissector called from TCP or UDP dissector. Decode and */
220 /* display the socks header, the pass the rest of the data to the tcp */
221 /* or udp port decode routine to handle the payload. */
224 redirect_entry_t *redirect_info;
225 conversation_t *conversation;
226 proto_tree *msp_tree;
229 conversation = find_conversation( &pi.src, &pi.dst, pi.ptype,
230 pi.srcport, pi.destport);
232 g_assert( conversation); /* should always find a conversation */
234 redirect_info = (redirect_entry_t*)conversation->data;
236 if (check_col(fd, COL_PROTOCOL))
237 col_add_str(fd, COL_PROTOCOL, "MS Proxy");
239 if (check_col(fd, COL_INFO))
240 col_add_fstr(fd, COL_INFO, "%s",
241 (( redirect_info->proto == PT_TCP) ? "TCP stream" :
245 ti = proto_tree_add_item( tree, proto_msproxy, NullTVB, offset, 0,
248 msp_tree = proto_item_add_subtree(ti, ett_msproxy);
250 proto_tree_add_item( msp_tree, hf_msproxy_dstport, NullTVB,
251 offset, 0, redirect_info->remote_port);
253 proto_tree_add_item( msp_tree, hf_msproxy_dstaddr, NullTVB, offset, 0,
254 redirect_info->remote_addr);
258 /* set pi src/dst port and call the udp sub-dissector lookup */
260 if ( pi.srcport == redirect_info->clnt_port)
265 *ptr = redirect_info->remote_port;
267 if ( redirect_info->proto == PT_TCP)
268 decode_tcp_ports( pd, offset, fd, tree, pi.srcport, pi.destport);
270 decode_udp_ports( pd, offset, fd, tree, pi.srcport, pi.destport);
272 *ptr = redirect_info->server_int_port;
277 static void add_msproxy_conversation( hash_entry_t *hash_info){
279 /* check to see if a conversation already exists, if it does assume */
280 /* it's our conversation and quit. Otherwise create a new conversation. */
281 /* Load the conversation dissector to our dissector and load the */
282 /* conversation data structure with the info needed to call the TCP or */
283 /* UDP port decoder. */
285 /* NOTE: Currently this assume that the conversataion will be created */
286 /* during a packet from the server. If that changes, the pi.src */
287 /* and pi.dst will not be correct and this routine will have to */
290 redirect_entry_t *new_conv_info;
292 conversation_t *conversation = find_conversation( &pi.src, &pi.dst,
293 hash_info->proto, hash_info->server_int_port,
294 hash_info->clnt_port);
299 new_conv_info = g_mem_chunk_alloc(redirect_vals);
300 conversation = conversation_new( &pi.src, &pi.dst, hash_info->proto,
301 hash_info->server_int_port, hash_info->clnt_port, new_conv_info);
303 g_assert( new_conv_info);
304 g_assert( conversation);
306 new_conv_info->remote_addr = hash_info->dst_addr;
307 new_conv_info->clnt_port = hash_info->clnt_port;
308 new_conv_info->remote_port = hash_info->dst_port;
309 new_conv_info->server_int_port = hash_info->server_int_port;
310 new_conv_info->proto = hash_info->proto;
312 conversation->dissector = msproxy_sub_dissector;
317 static int display_application_name(const u_char *pd, int offset,
318 frame_data *fd, proto_tree *tree) {
320 /* display the application name in the proto tree. */
322 /* NOTE: this routine assumes that the tree pointer is valid (not NULL) */
326 if ((offset+ 1) > fd->cap_len){
327 proto_tree_add_text(tree, NullTVB, offset, 0, "****FRAME TOO SHORT***");
331 strncpy( temp, &pd[ offset], MIN( 255, END_OF_FRAME));
332 temp[ MIN( 255, END_OF_FRAME)] = 0;
333 proto_tree_add_text( tree, NullTVB, offset, strlen(temp), "Application: %s", temp);
340 static char *get_msproxy_cmd_name( int cmd, int direction) {
342 /* return the command name string for cmd */
345 case MSPROXY_HELLO_2:
346 case MSPROXY_HELLO: return "Hello";
348 /* MSPROXY_HELLO_ACK & MSPROXY_USERINFO have the same value (0x1000). */
349 /* So use the direction flag to determine which to use. */
351 case MSPROXY_USERINFO:
352 if ( direction == FROM_SERVER)
353 return "Hello Acknowledge";
356 case MSPROXY_USERINFO_ACK: return "User Info Acknowledge";
357 case MSPROXY_AUTH: return "Authentication";
358 case MSPROXY_AUTH_1_ACK: return "Authentication Acknowledge";
359 case MSPROXY_AUTH_2: return "Authentication 2";
360 case MSPROXY_AUTH_2_ACK: return "Authentication 2 Acknowledge";
361 case MSPROXY_RESOLVE: return "Resolve";
362 case MSPROXY_RESOLVE_ACK: return "Resolve Acknowledge";
363 case MSPROXY_BIND: return "Bind";
364 case MSPROXY_TCP_BIND: return "TCP Bind";
365 case MSPROXY_TCP_BIND_ACK: return "TCP Bind Acknowledge";
366 case MSPROXY_LISTEN: return "Listen";
367 case MSPROXY_BINDINFO: return "Bind Info";
368 case MSPROXY_BINDINFO_ACK: return "Bind Info Acknowledge";
369 case MSPROXY_CONNECT: return "Connect";
370 case MSPROXY_CONNECT_ACK: return "Connect Acknowledge";
371 case MSPROXY_UDPASSOCIATE: return "UDP Associate";
372 case MSPROXY_UDP_BIND_REQ: return "UDP Bind";
373 case MSPROXY_UDPASSOCIATE_ACK: return "Bind or Associate Acknowledge";
374 case MSPROXY_CONNECTED: return "Connected";
375 case MSPROXY_SESSIONEND: return "Session End";
377 default: return "Unknown";
383 static void dissect_user_info_2(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
385 /* decode the user, application, computer name */
391 strncpy( str, &pd[ offset], MIN( 255, END_OF_FRAME));
392 str[ MIN( 255, END_OF_FRAME)] = 0;
394 proto_tree_add_text( tree, NullTVB, offset, strlen( str) + 1,
395 "User name: %s", str);
396 offset += strlen( str) + 2;
398 strncpy( str, &pd[ offset], MIN( 255, END_OF_FRAME));
399 str[ MIN( 255, END_OF_FRAME)] = 0;
401 proto_tree_add_text( tree, NullTVB, offset, strlen( str) + 1,
402 "Application name: %s", str);
403 offset += strlen( str) + 1;
405 strncpy( str, &pd[ offset], MIN( 255, END_OF_FRAME));
406 str[ MIN( 255, END_OF_FRAME)] = 0;
408 proto_tree_add_text( tree, NullTVB, offset, strlen( str) + 1,
409 "Client computer name: %s", str);
415 static void dissect_msproxy_request_1(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
417 /* decode the request _1 structure */
422 dissect_user_info_2( pd, 262, fd, tree);
428 static void dissect_bind(const u_char *pd, int offset, frame_data *fd,
429 proto_tree *tree, hash_entry_t *conv_info) {
431 /* decode the bind request */
435 CHECK_PACKET_LENGTH( 4);
437 proto_tree_add_item( tree, hf_msproxy_bindaddr, NullTVB, offset, 4,
441 CHECK_PACKET_LENGTH( 2);
443 proto_tree_add_item( tree, hf_msproxy_bindport, NullTVB, offset, 2,
444 pntohs( &pd[ offset]));
447 CHECK_PACKET_LENGTH( 2);
449 proto_tree_add_item( tree, hf_msproxy_clntport, NullTVB, offset, 2,
450 pntohs( &pd[ offset]));
453 conv_info->clnt_port = pntohs( &pd[ offset]);
457 CHECK_PACKET_LENGTH( 2);
458 proto_tree_add_item( tree, hf_msproxy_boundport, NullTVB, offset, 2,
459 pntohs( &pd[ offset]));
462 display_application_name( pd, offset, fd, tree);
468 static void dissect_auth(const u_char *pd, int offset,
469 frame_data *fd, proto_tree *tree) {
471 /* decode the authorization request */
478 strncpy( temp, &pd[ offset], 7);
480 proto_tree_add_text( tree, NullTVB, offset, 7, "NTLMSSP signature: %s",
488 static void dissect_tcp_bind(const u_char *pd, int offset,
489 frame_data *fd, proto_tree *tree, hash_entry_t *conv_info) {
491 /* decode the bind packet. Set the protocol type in the conversation */
492 /* information so the bind_info can use it to create the payload */
496 conv_info->proto = PT_TCP;
501 CHECK_PACKET_LENGTH( 4);
502 proto_tree_add_item( tree, hf_msproxy_bind_id, NullTVB, offset, 4, pntohl( &pd[ offset]));
505 CHECK_PACKET_LENGTH( 2);
506 proto_tree_add_item( tree, hf_msproxy_boundport, NullTVB, offset, 2,
507 pntohs( &pd[ offset]));
510 display_application_name( pd, offset, fd, tree);
515 static void dissect_request_connect(const u_char *pd, int offset, frame_data *fd,
516 proto_tree *tree, hash_entry_t *conv_info) {
518 /* decode the connect request, display */
520 conv_info->proto = PT_TCP;
524 CHECK_PACKET_LENGTH( 2);
526 proto_tree_add_item( tree, hf_msproxy_dstport, NullTVB, offset, 2,
527 pntohs( &pd[ offset]));
529 conv_info->dst_port = pntohs( &pd[ offset]);
532 CHECK_PACKET_LENGTH( 4);
534 proto_tree_add_item( tree, hf_msproxy_dstaddr, NullTVB, offset, 4,
537 memcpy( &conv_info->dst_addr, &pd[ offset], sizeof( guint32));
541 CHECK_PACKET_LENGTH( 2);
542 conv_info->clnt_port = pntohs( &pd[ offset]);
545 proto_tree_add_item( tree, hf_msproxy_clntport, NullTVB, offset, 2,
546 pntohs( &pd[ offset]));
550 display_application_name( pd, offset, fd, tree);
555 static void dissect_bind_info_ack(const u_char *pd, int offset, frame_data *fd,
556 proto_tree *tree, hash_entry_t *conv_info) {
558 /* decode the client bind info ack */
564 CHECK_PACKET_LENGTH( 4);
565 proto_tree_add_item( tree, hf_msproxy_bind_id, NullTVB, offset, 4, pntohl( &pd[ offset]));
568 CHECK_PACKET_LENGTH( 2);
569 proto_tree_add_item( tree, hf_msproxy_dstport, NullTVB, offset, 2,
570 pntohs( &pd[ offset]));
573 CHECK_PACKET_LENGTH( 4);
574 proto_tree_add_item( tree, hf_msproxy_dstaddr, NullTVB, offset, 4,
578 CHECK_PACKET_LENGTH( 2);
579 proto_tree_add_item( tree, hf_msproxy_server_int_port, NullTVB, offset,
580 2, pntohs( &pd[ offset]));
583 CHECK_PACKET_LENGTH( 2);
584 proto_tree_add_item( tree, hf_msproxy_server_ext_port, NullTVB, offset,
585 2, pntohs( &pd[ offset]));
588 CHECK_PACKET_LENGTH( 4);
589 proto_tree_add_item( tree, hf_msproxy_server_ext_addr, NullTVB, offset,
590 4, GWORD( pd, offset));
593 display_application_name( pd, offset, fd, tree);
598 static void dissect_request_resolve(const u_char *pd, int offset,
599 frame_data *fd, proto_tree *tree) {
601 /* dissect the request resolve structure */
602 /* display a string with a length, characters encoding */
603 /* they are displayed under a tree with the name in Label variable */
604 /* return the length of the string and the length byte */
606 proto_tree *name_tree;
610 int length = GBYTE( pd, offset);
613 strncpy( temp, &pd[ offset + 18], length);
616 ti = proto_tree_add_text(tree, NullTVB, offset, length + 1,
617 "Host Name: %s", temp);
619 name_tree = proto_item_add_subtree(ti, ett_msproxy_name);
621 proto_tree_add_text( name_tree, NullTVB, offset, 1, "Length: %d", length);
626 proto_tree_add_text( name_tree, NullTVB, offset, length, "String: %s",
633 static void dissect_udp_bind(const u_char *pd, int offset,
634 frame_data *fd, proto_tree *tree, hash_entry_t *conv_info) {
636 /* Dissect the udp bind request. Load the protocol id (PT_UDP) and the */
637 /* remote address so bind_info can use it to create conversation */
640 conv_info->proto = PT_UDP;
645 CHECK_PACKET_LENGTH( 4);
647 proto_tree_add_item( tree, hf_msproxy_bind_id, NullTVB, offset, 4, pntohl( &pd[ offset]));
651 CHECK_PACKET_LENGTH( 2);
653 proto_tree_add_item( tree, hf_msproxy_dstport, NullTVB, offset, 2,
654 pntohs( &pd[ offset]));
657 CHECK_PACKET_LENGTH( 4);
659 proto_tree_add_item( tree, hf_msproxy_dstaddr, NullTVB, offset, 4,
665 display_application_name( pd, offset, fd, tree);
669 static void dissect_udp_assoc(const u_char *pd, int offset,
670 frame_data *fd, proto_tree *tree, hash_entry_t *conv_info) {
672 /* dissect the udp associate request. And load client port into */
673 /* conversation data structure for later. */
678 CHECK_PACKET_LENGTH( 2);
680 proto_tree_add_item( tree, hf_msproxy_clntport, NullTVB, offset, 2,
681 pntohs( &pd[ offset]));
683 conv_info->clnt_port = pntohs( &pd[ offset]);
688 display_application_name( pd, offset, fd, tree);
694 static void dissect_msproxy_request(const u_char *pd, int offset, frame_data *fd,
695 proto_tree *tree, hash_entry_t *conv_info) {
701 CHECK_PACKET_LENGTH( 4);
702 proto_tree_add_text( tree, NullTVB, offset, 4, "Client id: 0x%0x",
706 CHECK_PACKET_LENGTH( 4);
707 proto_tree_add_text( tree, NullTVB, offset, 4, "Version: 0x%04x",
711 CHECK_PACKET_LENGTH( 4);
712 proto_tree_add_text( tree, NullTVB, offset, 4, "Server id: 0x%0x",
716 CHECK_PACKET_LENGTH( 2);
717 proto_tree_add_text( tree, NullTVB, offset, 1, "Server ack: %u",
721 CHECK_PACKET_LENGTH( 1);
722 proto_tree_add_text( tree, NullTVB, offset, 1, "Sequence Number: %u",
726 CHECK_PACKET_LENGTH( 4);
727 strncpy( temp, &pd[ offset], 4);
729 proto_tree_add_text( tree, NullTVB, offset, 4, "RWSP signature: %s", temp);
735 CHECK_PACKET_LENGTH( 1);
736 cmd = pntohs( &pd[offset]);
739 proto_tree_add_uint_format( tree, hf_msproxy_cmd, NullTVB, offset, 2,
740 cmd, "Command: 0x%02x (%s)", cmd,
741 get_msproxy_cmd_name( cmd, FROM_CLIENT));
747 dissect_auth( pd, offset, fd, tree);
751 dissect_bind( pd, offset, fd, tree, conv_info);
754 case MSPROXY_UDP_BIND_REQ:
755 dissect_udp_bind( pd, offset, fd, tree, conv_info);
758 case MSPROXY_AUTH_2: /*$$ this is probably wrong place for this */
759 case MSPROXY_TCP_BIND:
760 dissect_tcp_bind( pd, offset, fd, tree, conv_info);
763 case MSPROXY_RESOLVE:
764 dissect_request_resolve( pd, offset, fd, tree);
767 case MSPROXY_CONNECT:
769 dissect_request_connect( pd, offset, fd, tree,
773 case MSPROXY_BINDINFO_ACK:
774 dissect_bind_info_ack( pd, offset, fd, tree, conv_info);
778 case MSPROXY_HELLO_2:
779 dissect_msproxy_request_1( pd, offset, fd, tree);
782 case MSPROXY_UDPASSOCIATE:
783 dissect_udp_assoc( pd, offset, fd, tree, conv_info);
787 proto_tree_add_text( tree, NullTVB, offset, 0,
788 "Unhandled request command (report this, please)");
794 static void dissect_hello_ack(const u_char *pd, int offset, frame_data *fd,
795 proto_tree *tree, hash_entry_t *conv_info) {
797 /* decode the hello acknowledge packet */
802 CHECK_PACKET_LENGTH( 2);
803 proto_tree_add_item( tree, hf_msproxy_serverport, NullTVB, offset, 2,
804 pntohs( &pd[ offset]));
807 CHECK_PACKET_LENGTH( 4);
808 proto_tree_add_item( tree, hf_msproxy_serveraddr, NullTVB, offset, 4,
816 static void dissect_user_info_ack(const u_char *pd, int offset,
817 frame_data *fd, proto_tree *tree) {
819 /* decode the response _2 structure */
829 static void dissect_udpassociate_ack( const u_char *pd, int offset,
830 frame_data *fd, proto_tree *tree) {
836 CHECK_PACKET_LENGTH( 4);
837 proto_tree_add_item( tree, hf_msproxy_bind_id, NullTVB, offset, 4, pntohl( &pd[ offset]));
840 CHECK_PACKET_LENGTH( 2);
841 proto_tree_add_item( tree, hf_msproxy_server_ext_port, NullTVB, offset, 2, pntohs( &pd[ offset]));
844 CHECK_PACKET_LENGTH( 4);
845 proto_tree_add_item( tree, hf_msproxy_server_ext_addr, NullTVB, offset, 4, GWORD( pd, offset));
848 display_application_name( pd, offset, fd, tree);
854 static void dissect_auth_1_ack(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
862 CHECK_PACKET_LENGTH( 7);
863 strncpy( temp, &pd[ offset], 7);
865 proto_tree_add_text( tree, NullTVB, offset, 7, "NTLMSSP signature: %s", temp);
868 strncpy( temp, &pd[ offset], MIN( 255, END_OF_FRAME));
869 temp[ MIN( 255, END_OF_FRAME)] = 0;
870 proto_tree_add_text( tree, NullTVB, offset, 255, "NT domain: %s", temp);
877 static void dissect_msproxy_response_4( const u_char *pd, int offset,
878 frame_data *fd, proto_tree *tree) {
880 /* decode the response _4 structure */
887 static void dissect_connect_ack( const u_char *pd, int offset, frame_data *fd,
888 proto_tree *tree, hash_entry_t *conv_info) {
890 /* decode the connect ack packet */
893 CHECK_PACKET_LENGTH( 2);
896 proto_tree_add_item( tree, hf_msproxy_server_int_port, NullTVB, offset, 2, pntohs( &pd[ offset]));
899 conv_info->proto = PT_TCP;
900 conv_info->server_int_port = pntohs( &pd[ offset]);
904 CHECK_PACKET_LENGTH( 2);
905 proto_tree_add_item( tree, hf_msproxy_server_int_addr, NullTVB, offset, 2, GWORD( pd, offset));
908 CHECK_PACKET_LENGTH( 2);
909 proto_tree_add_item( tree, hf_msproxy_server_ext_port, NullTVB, offset, 2, pntohs( &pd[ offset]));
912 CHECK_PACKET_LENGTH( 4);
913 proto_tree_add_item( tree, hf_msproxy_server_ext_addr, NullTVB, offset, 4, GWORD( pd, offset));
916 display_application_name( pd, offset, fd, tree);
919 add_msproxy_conversation( conv_info);
924 static void dissect_tcp_bind_ack( const u_char *pd, int offset, frame_data *fd,
927 /* decode the tcp bind */
932 CHECK_PACKET_LENGTH( 4);
933 proto_tree_add_item( tree, hf_msproxy_bind_id, NullTVB, offset, 4, pntohl( &pd[ offset]));
936 CHECK_PACKET_LENGTH( 2);
937 proto_tree_add_item( tree, hf_msproxy_server_int_port, NullTVB, offset,
938 2, pntohs( &pd[ offset]));
941 CHECK_PACKET_LENGTH( 2);
942 proto_tree_add_item( tree, hf_msproxy_server_ext_port, NullTVB, offset,
943 2, pntohs( &pd[ offset]));
946 CHECK_PACKET_LENGTH( 4);
947 proto_tree_add_item( tree, hf_msproxy_server_ext_addr, NullTVB, offset,
948 4, GWORD( pd, offset));
952 display_application_name( pd, offset, fd, tree);
958 static void dissect_bind_info( const u_char *pd, int offset, frame_data *fd,
959 proto_tree *tree, hash_entry_t *conv_info) {
961 /* decode the Bind info response from server */
965 CHECK_PACKET_LENGTH( 4);
967 proto_tree_add_item( tree, hf_msproxy_bind_id, NullTVB, offset, 4, pntohl( &pd[ offset]));
971 CHECK_PACKET_LENGTH( 2);
973 proto_tree_add_item( tree, hf_msproxy_dstport, NullTVB, offset, 2,
974 pntohs( &pd[ offset]));
975 conv_info->dst_port = pntohs( &pd[ offset]);
978 CHECK_PACKET_LENGTH( 4);
980 proto_tree_add_item( tree, hf_msproxy_dstaddr, NullTVB, offset, 4,
983 memcpy( &conv_info->dst_addr, &pd[ offset], sizeof( guint32));
987 CHECK_PACKET_LENGTH( 2);
989 proto_tree_add_item( tree, hf_msproxy_server_int_port, NullTVB, offset,
990 2, pntohs( &pd[ offset]));
991 conv_info->server_int_port = pntohs( &pd[ offset]);
996 CHECK_PACKET_LENGTH( 2);
997 proto_tree_add_item( tree, hf_msproxy_server_ext_port, NullTVB, offset,
998 2, pntohs( &pd[ offset]));
1001 CHECK_PACKET_LENGTH( 4);
1002 proto_tree_add_item( tree, hf_msproxy_server_ext_addr, NullTVB, offset,
1003 4, GWORD( pd, offset));
1006 display_application_name( pd, offset, fd, tree);
1010 add_msproxy_conversation( conv_info);
1015 static void dissect_resolve(const u_char *pd, int offset, frame_data *fd,
1018 /* dissect the response resolve structure */
1019 /* display a string with a length, characters encoding */
1020 /* they are displayed under a tree with the name in Label variable */
1021 /* return the length of the string and the length byte */
1025 int addr_offset = GBYTE( pd, offset);
1027 proto_tree_add_text( tree, NullTVB, offset, 1, "Address offset: %d",
1034 offset += addr_offset;
1036 CHECK_PACKET_LENGTH( 4);
1037 proto_tree_add_item( tree, hf_msproxy_resolvaddr, NullTVB, offset, 4,
1038 GWORD( pd, offset));
1044 static void dissect_msproxy_response(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, hash_entry_t *conv_info) {
1051 CHECK_PACKET_LENGTH( 4);
1052 proto_tree_add_text( tree, NullTVB, offset, 4, "Client id: 0x%0x",
1053 GWORD( pd, offset));
1056 CHECK_PACKET_LENGTH( 4);
1057 proto_tree_add_text( tree, NullTVB, offset, 4, "Version: 0x%04x",
1058 GWORD( pd, offset));
1061 CHECK_PACKET_LENGTH( 4);
1062 proto_tree_add_text( tree, NullTVB, offset, 4, "Server id: 0x%04x",
1063 GWORD( pd, offset));
1066 CHECK_PACKET_LENGTH( 1);
1067 proto_tree_add_text( tree, NullTVB, offset, 1, "Client ack: 0x%02x",
1068 GBYTE( pd, offset));
1072 CHECK_PACKET_LENGTH( 1);
1073 proto_tree_add_text( tree, NullTVB, offset, 1, "Sequence Number: 0x%02x",
1074 GBYTE( pd, offset));
1078 CHECK_PACKET_LENGTH( 4);
1079 strncpy( temp, &pd[ offset], 4);
1081 proto_tree_add_text( tree, NullTVB, offset, 4, "RWSP signature: %s", temp);
1088 CHECK_PACKET_LENGTH( 2);
1089 cmd = pntohs( &pd[offset]);
1092 proto_tree_add_uint_format( tree, hf_msproxy_cmd, NullTVB, offset, 2,
1093 cmd, "Command: 0x%02x (%s)", cmd,
1094 get_msproxy_cmd_name( cmd, FROM_SERVER));
1098 case MSPROXY_HELLO_ACK:
1099 dissect_hello_ack( pd, offset, fd, tree, conv_info);
1102 case MSPROXY_USERINFO_ACK:
1103 dissect_user_info_ack( pd, offset, fd, tree);
1106 case MSPROXY_AUTH_1_ACK:
1107 dissect_auth_1_ack( pd, offset, fd, tree);
1110 /* this also handle the MSPROXY_BIND_ACK ??? check this */
1112 case MSPROXY_UDPASSOCIATE_ACK:
1113 dissect_udpassociate_ack( pd, offset, fd, tree);
1116 case MSPROXY_AUTH_2_ACK:
1117 case MSPROXY_AUTH_2_ACK2:
1118 dissect_msproxy_response_4( pd, offset, fd, tree);
1121 case MSPROXY_TCP_BIND_ACK:
1122 dissect_tcp_bind_ack( pd, offset, fd, tree);
1125 case MSPROXY_CONNECT_ACK:
1126 dissect_connect_ack( pd, offset, fd, tree, conv_info);
1129 case MSPROXY_BINDINFO:
1130 dissect_bind_info( pd, offset, fd, tree, conv_info);
1133 case MSPROXY_RESOLVE_ACK:
1134 dissect_resolve( pd, offset, fd, tree);
1137 case MSPROXY_CONNECT_AUTHFAILED:
1138 case MSPROXY_BIND_AUTHFAILED:
1139 proto_tree_add_text( tree, NullTVB, offset, 0, "No know information (help wanted)");
1145 (((cmd >> 8) == MSPROXY_CONNREFUSED) ||
1146 ((cmd >> 12) == MSPROXY_CONNREFUSED)))
1147 proto_tree_add_text( tree, NullTVB, offset, 0,
1148 "No know information (help wanted)");
1151 proto_tree_add_text( tree, NullTVB, offset, 0,
1152 "Unhandled response command (report this, please)");
1160 static void dissect_msproxy(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
1163 proto_tree *msproxy_tree = NULL;
1168 hash_entry_t *hash_info;
1169 conversation_t *conversation;
1172 conversation = find_conversation( &pi.src, &pi.dst, pi.ptype,
1173 pi.srcport, pi.destport);
1175 if ( conversation) /* conversation found */
1176 hash_info = conversation->data;
1178 /* new conversation create local data structure */
1180 hash_info = g_mem_chunk_alloc(vals);
1182 conversation_new( &pi.src, &pi.dst, pi.ptype,
1183 pi.srcport, pi.destport, hash_info);
1186 if (check_col(fd, COL_PROTOCOL))
1187 col_add_str(fd, COL_PROTOCOL, "MSproxy");
1190 /* display packet info */
1191 if (check_col(fd, COL_INFO)){
1193 cmd = pntohs( &pd[offset + 36]);
1195 if ( pi.srcport == UDP_PORT_MSPROXY)
1196 col_add_fstr( fd, COL_INFO, "Server message: %s",
1197 get_msproxy_cmd_name( cmd, FROM_SERVER));
1199 col_add_fstr(fd, COL_INFO, "Client message: %s",
1200 get_msproxy_cmd_name( cmd, FROM_CLIENT));
1204 if (tree) { /* if proto tree, decode data */
1205 ti = proto_tree_add_item( tree, proto_msproxy, NullTVB, offset,
1206 END_OF_FRAME, NULL, "MSproxy:" );
1208 msproxy_tree = proto_item_add_subtree(ti, ett_msproxy);
1211 if ( pi.srcport == UDP_PORT_MSPROXY)
1212 dissect_msproxy_response( pd, offset, fd, msproxy_tree, hash_info);
1214 dissect_msproxy_request( pd, offset, fd, msproxy_tree, hash_info);
1219 static void msproxy_reinit( void){
1221 /* Do the cleanup work when a new pass through the packet list is */
1222 /* performed. Reset the highest row seen counter and re-initialize the */
1223 /* conversation memory chunks. */
1228 g_mem_chunk_destroy(vals);
1230 vals = g_mem_chunk_new("msproxy_vals", hash_val_length,
1231 hash_init_count * hash_val_length,
1235 g_mem_chunk_destroy(redirect_vals);
1237 redirect_vals = g_mem_chunk_new("msproxy_redirect_vals", redirect_val_length,
1238 redirect_init_count * redirect_val_length,
1245 proto_register_msproxy( void){
1247 /* Prep the msproxy protocol, for now, just register it */
1249 static gint *ett[] = {
1253 static hf_register_info hf[] = {
1256 { "Command", "msproxy.command", FT_UINT16, BASE_DEC,
1261 { &hf_msproxy_dstaddr,
1262 { "Destination Address", "msproxy.dstaddr", FT_IPv4, BASE_NONE, NULL,
1267 { &hf_msproxy_srcport,
1268 { "Source Port", "msproxy.srcport", FT_UINT16,
1269 BASE_DEC, NULL, 0x0, ""
1272 { &hf_msproxy_dstport,
1273 { "Destination Port", "msproxy.dstport", FT_UINT16,
1274 BASE_DEC, NULL, 0x0, ""
1277 { &hf_msproxy_clntport,
1278 { "Client Port", "msproxy.clntport", FT_UINT16,
1279 BASE_DEC, NULL, 0x0, ""
1282 { &hf_msproxy_server_ext_addr,
1283 { "Server External Address", "msproxy.server_ext_addr", FT_IPv4, BASE_NONE, NULL,
1288 { &hf_msproxy_server_ext_port,
1289 { "Server External Port", "msproxy.server_ext_port", FT_UINT16,
1290 BASE_DEC, NULL, 0x0, ""
1294 { &hf_msproxy_server_int_addr,
1295 { "Server Internal Address", "msproxy.server_int_addr", FT_IPv4, BASE_NONE, NULL,
1300 { &hf_msproxy_server_int_port,
1301 { "Server Internal Port", "msproxy.server_int_port", FT_UINT16,
1302 BASE_DEC, NULL, 0x0, ""
1305 { &hf_msproxy_serverport,
1306 { "Server Port", "msproxy.serverport", FT_UINT16,
1307 BASE_DEC, NULL, 0x0, ""
1310 { &hf_msproxy_bindport,
1311 { "Bind Port", "msproxy.bindport", FT_UINT16,
1312 BASE_DEC, NULL, 0x0, ""
1315 { &hf_msproxy_boundport,
1316 { "Bound Port", "msproxy.boundport", FT_UINT16,
1317 BASE_DEC, NULL, 0x0, ""
1320 { &hf_msproxy_serveraddr,
1321 { "Server Address", "msproxy.serveraddr", FT_IPv4, BASE_NONE, NULL,
1325 { &hf_msproxy_bindaddr,
1326 { "Destination", "msproxy.bindaddr", FT_IPv4, BASE_NONE, NULL,
1330 { &hf_msproxy_bind_id,
1331 { "Bound Port Id", "msproxy.bindid", FT_UINT32,
1332 BASE_HEX, NULL, 0x0, ""
1335 { &hf_msproxy_resolvaddr,
1336 { "Address", "msproxy.resolvaddr", FT_IPv4, BASE_NONE, NULL,
1343 proto_msproxy = proto_register_protocol ( "MSProxy Protocol", "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 dissector_add("udp.port", UDP_PORT_MSPROXY, dissect_msproxy);