2 * Routines for Microsoft Proxy packet dissection
3 * Copyright 2000, Jeffrey C. Foster <jfoste@woodward.com>
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 ************************************************************************/
49 #include <epan/packet.h>
50 #include <epan/addr_resolv.h>
51 #include <epan/conversation.h>
52 #include <epan/wmem/wmem.h>
53 #include <epan/expert.h>
55 #include "packet-tcp.h"
56 #include "packet-udp.h"
58 extern void udp_hash_add(guint16 proto
,
59 void (*dissect
)(const guchar
*, int, frame_data
*, proto_tree
*));
62 static int proto_msproxy
= -1;
64 static int ett_msproxy
= -1;
65 static int ett_msproxy_name
= -1;
67 static int hf_msproxy_cmd
= -1;
68 static int hf_msproxy_clntport
= -1;
70 static int hf_msproxy_dstaddr
= -1;
72 /* static int hf_msproxy_srcport = -1; */
73 static int hf_msproxy_dstport
= -1;
74 static int hf_msproxy_serverport
= -1;
75 static int hf_msproxy_serveraddr
= -1;
76 static int hf_msproxy_bindport
= -1;
77 static int hf_msproxy_bindaddr
= -1;
78 static int hf_msproxy_boundport
= -1;
79 static int hf_msproxy_bind_id
= -1;
80 static int hf_msproxy_resolvaddr
= -1;
82 static int hf_msproxy_client_id
= -1;
83 static int hf_msproxy_version
= -1;
84 static int hf_msproxy_server_id
= -1;
85 static int hf_msproxy_server_ack
= -1;
86 static int hf_msproxy_client_ack
= -1;
87 static int hf_msproxy_seq_num
= -1;
88 static int hf_msproxy_rwsp_signature
= -1;
89 static int hf_msproxy_ntlmssp_signature
= -1;
91 static int hf_msproxy_server_int_addr
= -1;
92 static int hf_msproxy_server_int_port
= -1;
93 static int hf_msproxy_server_ext_addr
= -1;
94 static int hf_msproxy_server_ext_port
= -1;
96 static expert_field ei_msproxy_unknown
= EI_INIT
;
97 static expert_field ei_msproxy_unhandled
= EI_INIT
;
99 static dissector_handle_t msproxy_sub_handle
;
102 #define UDP_PORT_MSPROXY 1745
104 #define N_MSPROXY_HELLO 0x05 /* packet 1 from client */
105 #define N_MSPROXY_ACK 0x10 /* packet 1 from server */
106 #define N_MSPROXY_USERINFO_ACK 0x04 /* packet 2 from server */
107 #define N_MSPROXY_AUTH 0x47 /* packet 3 from client */
108 #define N_MSPROXY_RESOLVE 0x07 /* Resolve request */
111 /*$$$ 0x0500 was dante value, I see 0x05ff and 0x0500 */
113 #define MSPROXY_HELLO 0x0500
114 #define MSPROXY_HELLO_2 0x05ff
116 #define MSPROXY_HELLO_ACK 0x1000
118 #define MSPROXY_USERINFO 0x1000
119 #define MSPROXY_USERINFO_ACK 0x0400
121 #define MSPROXY_AUTH 0x4700
122 #define MSPROXY_AUTH_1_ACK 0x4714
123 #define MSPROXY_AUTH_2 0x4701
124 #define MSPROXY_AUTH_2_ACK 0x4715
125 #define MSPROXY_AUTH_2_ACK2 0x4716
127 #define MSPROXY_RESOLVE 0x070d
128 #define MSPROXY_RESOLVE_ACK 0x070f
130 #define MSPROXY_BIND 0x0704
131 #define MSPROXY_BIND_ACK 0x0706
133 #define MSPROXY_TCP_BIND 0x0707
134 #define MSPROXY_TCP_BIND_ACK 0x0708
136 #define MSPROXY_LISTEN 0x0406
138 #define MSPROXY_BINDINFO 0x0709
140 #define MSPROXY_BINDINFO_ACK 0x070a
142 #define MSPROXY_CONNECT 0x071e
143 #define MSPROXY_CONNECT_ACK 0x0703
145 #define MSPROXY_UDPASSOCIATE 0x0705
146 #define MSPROXY_UDPASSOCIATE_ACK 0x0706
148 #define MSPROXY_UDP_BIND_REQ 0x070b
150 #define MSPROXY_CONNECTED 0x042c
151 #define MSPROXY_SESSIONEND 0x251e
153 #define MSPROXY_BIND_AUTHFAILED 0x0804
154 #define MSPROXY_CONNECT_AUTHFAILED 0x081e
155 #define MSPROXY_CONNREFUSED 0x4 /* low 12 bits seem to vary. */
157 #define FROM_SERVER 1 /* direction of packet data for get_msproxy_cmd_name */
158 #define FROM_CLIENT 0
163 /*$$$ should this be the same as redirect_entry_t ?? */
164 /* then the add_conversation could just copy the structure */
165 /* using the same allocation (instance for you object guys) */
166 /* wouldn't work because there may be multiple child conversations */
167 /* from the same MSProxy conversation */
173 guint32 server_int_port
;
178 /************** conversation hash stuff ***************/
183 guint32 server_int_port
;
189 /************** negotiated conversation hash stuff ***************/
192 static guint32 last_row
= 0; /* used to see if packet is new */
194 static void msproxy_sub_dissector( tvbuff_t
*tvb
, packet_info
*pinfo
,
197 /* Conversation dissector called from TCP or UDP dissector. Decode and */
198 /* display the msproxy header, the pass the rest of the data to the tcp */
199 /* or udp port decode routine to handle the payload. */
202 redirect_entry_t
*redirect_info
;
203 conversation_t
*conversation
;
204 proto_tree
*msp_tree
;
207 conversation
= find_conversation( pinfo
->fd
->num
, &pinfo
->src
, &pinfo
->dst
,
208 pinfo
->ptype
, pinfo
->srcport
, pinfo
->destport
, 0);
210 DISSECTOR_ASSERT( conversation
); /* should always find a conversation */
212 redirect_info
= (redirect_entry_t
*)conversation_get_proto_data(conversation
,
215 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "MS Proxy");
217 col_set_str(pinfo
->cinfo
, COL_INFO
,
218 (( redirect_info
->proto
== PT_TCP
) ? "TCP stream" :
222 ti
= proto_tree_add_item( tree
, proto_msproxy
, tvb
, 0, 0,
225 msp_tree
= proto_item_add_subtree(ti
, ett_msproxy
);
227 proto_tree_add_uint( msp_tree
, hf_msproxy_dstport
, tvb
, 0, 0,
228 redirect_info
->remote_port
);
230 proto_tree_add_ipv4( msp_tree
, hf_msproxy_dstaddr
, tvb
, 0, 0,
231 redirect_info
->remote_addr
);
235 /* set pinfo->{src/dst port} and call the TCP or UDP sub-dissector lookup */
237 if ( pinfo
->srcport
== redirect_info
->clnt_port
)
238 ptr
= &pinfo
->destport
;
240 ptr
= &pinfo
->srcport
;
242 *ptr
= redirect_info
->remote_port
;
244 if ( redirect_info
->proto
== PT_TCP
)
245 decode_tcp_ports( tvb
, 0, pinfo
, tree
, pinfo
->srcport
,
246 pinfo
->destport
, NULL
, NULL
);
248 decode_udp_ports( tvb
, 0, pinfo
, tree
, pinfo
->srcport
,
249 pinfo
->destport
, -1);
251 *ptr
= redirect_info
->server_int_port
;
256 static void add_msproxy_conversation( packet_info
*pinfo
,
257 hash_entry_t
*hash_info
){
259 /* check to see if a conversation already exists, if it does assume */
260 /* it's our conversation and quit. Otherwise create a new conversation. */
261 /* Load the conversation dissector to our dissector and load the */
262 /* conversation data structure with the info needed to call the TCP or */
263 /* UDP port decoder. */
265 /* NOTE: Currently this assume that the conversation will be created */
266 /* during a packet from the server. If that changes, pinfo->src */
267 /* and pinfo->dst will not be correct and this routine will have */
270 conversation_t
*conversation
;
271 redirect_entry_t
*new_conv_info
;
273 if (pinfo
->fd
->flags
.visited
) {
275 * We've already processed this frame once, so we
276 * should already have done this.
281 conversation
= find_conversation( pinfo
->fd
->num
, &pinfo
->src
,
282 &pinfo
->dst
, (port_type
)hash_info
->proto
, hash_info
->server_int_port
,
283 hash_info
->clnt_port
, 0);
285 if ( !conversation
) {
286 conversation
= conversation_new( pinfo
->fd
->num
, &pinfo
->src
, &pinfo
->dst
,
287 (port_type
)hash_info
->proto
, hash_info
->server_int_port
,
288 hash_info
->clnt_port
, 0);
290 conversation_set_dissector(conversation
, msproxy_sub_handle
);
292 new_conv_info
= wmem_new(wmem_file_scope(), redirect_entry_t
);
294 new_conv_info
->remote_addr
= hash_info
->dst_addr
;
295 new_conv_info
->clnt_port
= hash_info
->clnt_port
;
296 new_conv_info
->remote_port
= hash_info
->dst_port
;
297 new_conv_info
->server_int_port
= hash_info
->server_int_port
;
298 new_conv_info
->proto
= hash_info
->proto
;
300 conversation_add_proto_data(conversation
, proto_msproxy
,
306 static int display_application_name(tvbuff_t
*tvb
, int offset
,
309 /* display the application name in the proto tree. */
311 /* NOTE: this routine assumes that the tree pointer is valid (not NULL) */
315 length
= tvb_strnlen( tvb
, offset
, 255);
316 proto_tree_add_text( tree
, tvb
, offset
, length
, "Application: %.*s",
317 length
, tvb_get_string( wmem_packet_scope(), tvb
, offset
, length
));
323 static const char *get_msproxy_cmd_name( int cmd
, int direction
) {
325 /* return the command name string for cmd */
328 case MSPROXY_HELLO_2
:
329 case MSPROXY_HELLO
: return "Hello";
331 /* MSPROXY_HELLO_ACK & MSPROXY_USERINFO have the same value (0x1000). */
332 /* So use the direction flag to determine which to use. */
334 case MSPROXY_USERINFO
:
335 if ( direction
== FROM_SERVER
)
336 return "Hello Acknowledge";
339 case MSPROXY_USERINFO_ACK
: return "User Info Acknowledge";
340 case MSPROXY_AUTH
: return "Authentication";
341 case MSPROXY_AUTH_1_ACK
: return "Authentication Acknowledge";
342 case MSPROXY_AUTH_2
: return "Authentication 2";
343 case MSPROXY_AUTH_2_ACK
: return "Authentication 2 Acknowledge";
344 case MSPROXY_RESOLVE
: return "Resolve";
345 case MSPROXY_RESOLVE_ACK
: return "Resolve Acknowledge";
346 case MSPROXY_BIND
: return "Bind";
347 case MSPROXY_TCP_BIND
: return "TCP Bind";
348 case MSPROXY_TCP_BIND_ACK
: return "TCP Bind Acknowledge";
349 case MSPROXY_LISTEN
: return "Listen";
350 case MSPROXY_BINDINFO
: return "Bind Info";
351 case MSPROXY_BINDINFO_ACK
: return "Bind Info Acknowledge";
352 case MSPROXY_CONNECT
: return "Connect";
353 case MSPROXY_CONNECT_ACK
: return "Connect Acknowledge";
354 case MSPROXY_UDPASSOCIATE
: return "UDP Associate";
355 case MSPROXY_UDP_BIND_REQ
: return "UDP Bind";
356 case MSPROXY_UDPASSOCIATE_ACK
: return "Bind or Associate Acknowledge";
357 case MSPROXY_CONNECTED
: return "Connected";
358 case MSPROXY_SESSIONEND
: return "Session End";
360 default: return "Unknown";
366 static void dissect_user_info_2(tvbuff_t
*tvb
, int offset
,
369 /* decode the user, application, computer name */
375 length
= tvb_strnlen( tvb
, offset
, 255);
378 proto_tree_add_text( tree
, tvb
, offset
, length
+ 1,
379 "User name: %.*s", length
,
380 tvb_get_string( wmem_packet_scope(), tvb
, offset
, length
));
381 offset
+= length
+ 2;
383 length
= tvb_strnlen( tvb
, offset
, 255);
386 proto_tree_add_text( tree
, tvb
, offset
, length
+ 1,
387 "Application name: %.*s", length
,
388 tvb_get_string( wmem_packet_scope(), tvb
, offset
, length
));
389 offset
+= length
+ 1;
391 length
= tvb_strnlen( tvb
, offset
, 255);
394 proto_tree_add_text( tree
, tvb
, offset
, length
+ 1,
395 "Client computer name: %.*s", length
,
396 tvb_get_string( wmem_packet_scope(), tvb
, offset
, length
));
402 static void dissect_msproxy_request_1(tvbuff_t
*tvb
, int offset
,
405 /* decode the request _1 structure */
410 dissect_user_info_2( tvb
, offset
, tree
);
416 static void dissect_bind(tvbuff_t
*tvb
, int offset
,
417 proto_tree
*tree
, hash_entry_t
*conv_info
) {
419 /* decode the bind request */
424 proto_tree_add_item( tree
, hf_msproxy_bindaddr
, tvb
, offset
, 4,
429 proto_tree_add_item( tree
, hf_msproxy_bindport
, tvb
, offset
, 2,
434 proto_tree_add_item( tree
, hf_msproxy_clntport
, tvb
, offset
, 2,
438 conv_info
->clnt_port
= tvb_get_ntohs( tvb
, offset
);
442 proto_tree_add_item( tree
, hf_msproxy_boundport
, tvb
, offset
, 2,
446 display_application_name( tvb
, offset
, tree
);
452 static int dissect_auth(tvbuff_t
*tvb
, int offset
,
455 /* decode the authorization request */
460 proto_tree_add_item( tree
, hf_msproxy_ntlmssp_signature
, tvb
, offset
, 7, ENC_NA
|ENC_ASCII
);
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 conv_info
->dst_addr
= tvb_get_ipv4( tvb
, offset
);
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
,
553 offset
, 2, ENC_BIG_ENDIAN
);
556 proto_tree_add_item( tree
, hf_msproxy_server_ext_port
, tvb
,
557 offset
, 2, ENC_BIG_ENDIAN
);
560 proto_tree_add_item( tree
, hf_msproxy_server_ext_addr
, tvb
,
561 offset
, 4, ENC_BIG_ENDIAN
);
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_string( wmem_packet_scope(), 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_string( wmem_packet_scope(), 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_item( tree
, hf_msproxy_client_id
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
668 proto_tree_add_item( tree
, hf_msproxy_version
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
671 proto_tree_add_item( tree
, hf_msproxy_server_id
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
674 proto_tree_add_item( tree
, hf_msproxy_server_ack
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
677 proto_tree_add_item( tree
, hf_msproxy_seq_num
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
680 proto_tree_add_item( tree
, hf_msproxy_rwsp_signature
, tvb
, offset
, 4, ENC_NA
|ENC_ASCII
);
686 cmd
= tvb_get_ntohs( tvb
, offset
);
689 proto_tree_add_uint_format_value( tree
, hf_msproxy_cmd
, tvb
, offset
, 2,
691 get_msproxy_cmd_name( cmd
, FROM_CLIENT
),
698 dissect_auth( tvb
, offset
, tree
);
702 dissect_bind( tvb
, offset
, tree
, conv_info
);
705 case MSPROXY_UDP_BIND_REQ
:
706 dissect_udp_bind( tvb
, offset
, tree
, conv_info
);
709 case MSPROXY_AUTH_2
: /*$$ this is probably wrong place for this */
710 case MSPROXY_TCP_BIND
:
711 dissect_tcp_bind( tvb
, offset
, tree
, conv_info
);
714 case MSPROXY_RESOLVE
:
715 dissect_request_resolve( tvb
, offset
, tree
);
718 case MSPROXY_CONNECT
:
720 dissect_request_connect( tvb
, offset
, tree
,
724 case MSPROXY_BINDINFO_ACK
:
725 dissect_bind_info_ack( tvb
, offset
, tree
);
729 case MSPROXY_HELLO_2
:
730 dissect_msproxy_request_1( tvb
, offset
, tree
);
733 case MSPROXY_UDPASSOCIATE
:
734 dissect_udp_assoc( tvb
, offset
, tree
, conv_info
);
738 proto_tree_add_text( tree
, tvb
, offset
, 0,
739 "Unhandled request command (report this, please)");
745 static int dissect_hello_ack(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
) {
747 /* decode the hello acknowledge packet */
752 proto_tree_add_item( tree
, hf_msproxy_serverport
, tvb
, offset
, 2,
757 proto_tree_add_item( tree
, hf_msproxy_serveraddr
, tvb
, offset
, 4,
767 /* XXX - implement me */
768 static int dissect_user_info_ack(tvbuff_t
*tvb _U_
, int offset
,
769 proto_tree
*tree _U_
) {
771 /* decode the response _2 structure */
782 static void dissect_udpassociate_ack(tvbuff_t
*tvb
, int offset
,
788 proto_tree_add_item( tree
, hf_msproxy_bind_id
, tvb
, offset
, 4,
792 proto_tree_add_item( tree
, hf_msproxy_server_ext_port
, tvb
,
793 offset
, 2, ENC_BIG_ENDIAN
);
796 proto_tree_add_item( tree
, hf_msproxy_server_ext_addr
, tvb
,
797 offset
, 4, ENC_BIG_ENDIAN
);
800 display_application_name( tvb
, offset
, tree
);
806 static void dissect_auth_1_ack(tvbuff_t
*tvb
, int offset
,
811 proto_tree_add_item( tree
, hf_msproxy_ntlmssp_signature
, tvb
, offset
, 7, ENC_NA
|ENC_ASCII
);
814 /* XXX - always 255? */
815 proto_tree_add_text( tree
, tvb
, offset
, 255, "NT domain: %.255s",
816 tvb_get_string( wmem_packet_scope(), tvb
, offset
, 255));
822 /* XXX - implement me */
823 static int dissect_msproxy_response_4( tvbuff_t
*tvb _U_
, int offset
,
824 proto_tree
*tree _U_
) {
826 /* 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
,
843 offset
, 2, ENC_BIG_ENDIAN
);
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
,
852 offset
, 4, ENC_BIG_ENDIAN
);
855 proto_tree_add_item( tree
, hf_msproxy_server_ext_port
, tvb
,
856 offset
, 2, ENC_BIG_ENDIAN
);
859 proto_tree_add_item( tree
, hf_msproxy_server_ext_addr
, tvb
,
860 offset
, 4, ENC_BIG_ENDIAN
);
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_item( tree
, hf_msproxy_server_int_port
, tvb
,
883 offset
, 2, ENC_BIG_ENDIAN
);
886 proto_tree_add_item( tree
, hf_msproxy_server_ext_port
, tvb
,
887 offset
, 2, ENC_BIG_ENDIAN
);
890 proto_tree_add_item( tree
, hf_msproxy_server_ext_addr
, tvb
,
891 offset
, 4, ENC_BIG_ENDIAN
);
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 conv_info
->dst_addr
= tvb_get_ipv4( tvb
, offset
);
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
,
934 offset
, 2, ENC_BIG_ENDIAN
);
937 proto_tree_add_item( tree
, hf_msproxy_server_ext_addr
, tvb
,
938 offset
, 4, ENC_BIG_ENDIAN
);
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
) {
986 proto_tree_add_item( tree
, hf_msproxy_client_id
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
989 proto_tree_add_item( tree
, hf_msproxy_version
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
992 proto_tree_add_item( tree
, hf_msproxy_server_id
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
995 proto_tree_add_item( tree
, hf_msproxy_client_ack
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
998 proto_tree_add_item( tree
, hf_msproxy_seq_num
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1001 proto_tree_add_item( tree
, hf_msproxy_rwsp_signature
, tvb
, offset
, 4, ENC_NA
|ENC_ASCII
);
1007 cmd
= tvb_get_ntohs( tvb
, offset
);
1009 ti
= proto_tree_add_uint_format_value( tree
, hf_msproxy_cmd
, tvb
, offset
, 2,
1010 cmd
, "0x%02x (%s)", cmd
,
1011 get_msproxy_cmd_name( cmd
, FROM_SERVER
));
1015 case MSPROXY_HELLO_ACK
:
1016 dissect_hello_ack( tvb
, offset
, tree
);
1019 case MSPROXY_USERINFO_ACK
:
1020 dissect_user_info_ack( tvb
, offset
, tree
);
1023 case MSPROXY_AUTH_1_ACK
:
1024 dissect_auth_1_ack( tvb
, offset
, tree
);
1027 /* this also handle the MSPROXY_BIND_ACK ??? check this */
1029 case MSPROXY_UDPASSOCIATE_ACK
:
1030 dissect_udpassociate_ack( tvb
, offset
, tree
);
1033 case MSPROXY_AUTH_2_ACK
:
1034 case MSPROXY_AUTH_2_ACK2
:
1035 dissect_msproxy_response_4( tvb
, offset
, tree
);
1038 case MSPROXY_TCP_BIND_ACK
:
1039 dissect_tcp_bind_ack( tvb
, offset
, tree
);
1042 case MSPROXY_CONNECT_ACK
:
1043 dissect_connect_ack( tvb
, offset
, pinfo
, tree
,
1047 case MSPROXY_BINDINFO
:
1048 dissect_bind_info( tvb
, offset
, pinfo
, tree
, conv_info
);
1051 case MSPROXY_RESOLVE_ACK
:
1052 dissect_resolve( tvb
, offset
, tree
);
1055 case MSPROXY_CONNECT_AUTHFAILED
:
1056 case MSPROXY_BIND_AUTHFAILED
:
1057 expert_add_info(pinfo
, ti
, &ei_msproxy_unknown
);
1062 if ((((cmd
>> 8) == MSPROXY_CONNREFUSED
) ||
1063 ((cmd
>> 12) == MSPROXY_CONNREFUSED
)))
1064 expert_add_info(pinfo
, ti
, &ei_msproxy_unknown
);
1066 expert_add_info(pinfo
, ti
, &ei_msproxy_unhandled
);
1074 static void dissect_msproxy(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
) {
1077 proto_tree
*msproxy_tree
;
1082 hash_entry_t
*hash_info
;
1083 conversation_t
*conversation
;
1085 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "MSproxy");
1086 col_clear(pinfo
->cinfo
, COL_INFO
);
1088 conversation
= find_or_create_conversation(pinfo
);
1090 hash_info
= (hash_entry_t
*)conversation_get_proto_data(conversation
, proto_msproxy
);
1092 hash_info
= wmem_new(wmem_file_scope(), hash_entry_t
);
1093 conversation_add_proto_data(conversation
, proto_msproxy
,
1097 cmd
= tvb_get_ntohs( tvb
, 36);
1099 if ( pinfo
->srcport
== UDP_PORT_MSPROXY
)
1100 col_add_fstr( pinfo
->cinfo
, COL_INFO
, "Server message: %s",
1101 get_msproxy_cmd_name( cmd
, FROM_SERVER
));
1103 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Client message: %s",
1104 get_msproxy_cmd_name( cmd
, FROM_CLIENT
));
1106 ti
= proto_tree_add_item( tree
, proto_msproxy
, tvb
, 0, -1, ENC_NA
);
1107 msproxy_tree
= proto_item_add_subtree(ti
, ett_msproxy
);
1109 if ( pinfo
->srcport
== UDP_PORT_MSPROXY
)
1110 dissect_msproxy_response( tvb
, pinfo
, msproxy_tree
, hash_info
);
1112 dissect_msproxy_request( tvb
, msproxy_tree
, hash_info
);
1117 static void msproxy_reinit( void){
1119 /* Do the cleanup work when a new pass through the packet list is */
1120 /* performed. Reset the highest row seen counter */
1128 proto_register_msproxy( void){
1130 /* Prep the msproxy protocol, for now, just register it */
1132 static gint
*ett
[] = {
1136 static hf_register_info hf
[] = {
1139 { "Command", "msproxy.command", FT_UINT16
, BASE_DEC
,
1140 NULL
, 0x0, NULL
, HFILL
1144 { &hf_msproxy_dstaddr
,
1145 { "Destination Address", "msproxy.dstaddr", FT_IPv4
, BASE_NONE
, NULL
,
1151 { &hf_msproxy_srcport
,
1152 { "Source Port", "msproxy.srcport", FT_UINT16
,
1153 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
1157 { &hf_msproxy_dstport
,
1158 { "Destination Port", "msproxy.dstport", FT_UINT16
,
1159 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
1162 { &hf_msproxy_clntport
,
1163 { "Client Port", "msproxy.clntport", FT_UINT16
,
1164 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
1167 { &hf_msproxy_server_ext_addr
,
1168 { "Server External Address", "msproxy.server_ext_addr", FT_IPv4
, BASE_NONE
, NULL
,
1173 { &hf_msproxy_server_ext_port
,
1174 { "Server External Port", "msproxy.server_ext_port", FT_UINT16
,
1175 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
1179 { &hf_msproxy_server_int_addr
,
1180 { "Server Internal Address", "msproxy.server_int_addr", FT_IPv4
, BASE_NONE
, NULL
,
1185 { &hf_msproxy_server_int_port
,
1186 { "Server Internal Port", "msproxy.server_int_port", FT_UINT16
,
1187 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
1190 { &hf_msproxy_serverport
,
1191 { "Server Port", "msproxy.serverport", FT_UINT16
,
1192 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
1195 { &hf_msproxy_bindport
,
1196 { "Bind Port", "msproxy.bindport", FT_UINT16
,
1197 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
1200 { &hf_msproxy_boundport
,
1201 { "Bound Port", "msproxy.boundport", FT_UINT16
,
1202 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
1205 { &hf_msproxy_serveraddr
,
1206 { "Server Address", "msproxy.serveraddr", FT_IPv4
, BASE_NONE
, NULL
,
1210 { &hf_msproxy_bindaddr
,
1211 { "Destination", "msproxy.bindaddr", FT_IPv4
, BASE_NONE
, NULL
,
1215 { &hf_msproxy_bind_id
,
1216 { "Bound Port Id", "msproxy.bindid", FT_UINT32
,
1217 BASE_HEX
, NULL
, 0x0, NULL
, HFILL
1220 { &hf_msproxy_resolvaddr
,
1221 { "Address", "msproxy.resolvaddr", FT_IPv4
, BASE_NONE
, NULL
,
1225 { &hf_msproxy_client_id
,
1226 { "Client Id", "msproxy.client_id", FT_UINT32
,
1227 BASE_HEX
, NULL
, 0x0, NULL
, HFILL
1230 { &hf_msproxy_version
,
1231 { "Version", "msproxy.version", FT_UINT32
,
1232 BASE_HEX
, NULL
, 0x0, NULL
, HFILL
1235 { &hf_msproxy_server_id
,
1236 { "Server id", "msproxy.server_id", FT_UINT32
,
1237 BASE_HEX
, NULL
, 0x0, NULL
, HFILL
1240 { &hf_msproxy_server_ack
,
1241 { "Server ack", "msproxy.server_ack", FT_UINT8
,
1242 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
1245 { &hf_msproxy_client_ack
,
1246 { "Client ack", "msproxy.client_ack", FT_UINT8
,
1247 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
1250 { &hf_msproxy_seq_num
,
1251 { "Sequence Number", "msproxy.seq_num", FT_UINT8
,
1252 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
1255 { &hf_msproxy_rwsp_signature
,
1256 { "RWSP signature", "msproxy.rwsp_signature", FT_STRING
, BASE_NONE
, NULL
,
1260 { &hf_msproxy_ntlmssp_signature
,
1261 { "NTLMSSP signature", "msproxy.ntlmssp_signature", FT_STRING
, BASE_NONE
, NULL
,
1267 static ei_register_info ei
[] = {
1268 { &ei_msproxy_unknown
, { "msproxy.unknown", PI_UNDECODED
, PI_WARN
, "No know information (help wanted)", EXPFILL
}},
1269 { &ei_msproxy_unhandled
, { "msproxy.command.unhandled", PI_UNDECODED
, PI_WARN
, "Unhandled response command (report this, please)", EXPFILL
}},
1272 expert_module_t
* expert_msproxy
;
1274 proto_msproxy
= proto_register_protocol( "MS Proxy Protocol", "MS Proxy", "msproxy");
1276 proto_register_field_array(proto_msproxy
, hf
, array_length(hf
));
1277 proto_register_subtree_array(ett
, array_length(ett
));
1278 expert_msproxy
= expert_register_protocol(proto_msproxy
);
1279 expert_register_field_array(expert_msproxy
, ei
, array_length(ei
));
1281 register_init_routine( &msproxy_reinit
); /* register re-init routine */
1283 msproxy_sub_handle
= create_dissector_handle(msproxy_sub_dissector
,
1289 proto_reg_handoff_msproxy(void) {
1291 /* dissector install routine */
1293 dissector_handle_t msproxy_handle
;
1295 msproxy_handle
= create_dissector_handle(dissect_msproxy
,
1297 dissector_add_uint("udp.port", UDP_PORT_MSPROXY
, msproxy_handle
);