2 * Routines for Microsoft Proxy packet dissection
3 * Copyright 2000, Jeffrey C. Foster <jfoste@woodward.com>
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
11 * This was derived from the dante socks implementation source code.
12 * Most of the information came from common.h and msproxy_clientprotocol.c
14 * See http://www.inet.no/dante for more information
17 /************************************************************************
19 * Notes: These are possible command values. User input is welcome *
21 * Command = 0x040a - Remote host closed connection (maybe ?? ) *
22 * Command = 0x0411 - Remote host closed connection *
23 * Command = 0x0413 - Local host closed connection or SYN worked *
25 ************************************************************************/
32 #include <epan/packet.h>
33 #include <epan/expert.h>
35 #include "packet-tcp.h"
36 #include "packet-udp.h"
38 void proto_register_msproxy(void);
39 void proto_reg_handoff_msproxy(void);
42 static int proto_msproxy
;
44 static int ett_msproxy
;
45 static int ett_msproxy_name
;
47 static int hf_msproxy_cmd
;
48 static int hf_msproxy_clntport
;
50 static int hf_msproxy_dstaddr
;
52 /* static int hf_msproxy_srcport; */
53 static int hf_msproxy_dstport
;
54 static int hf_msproxy_serverport
;
55 static int hf_msproxy_serveraddr
;
56 static int hf_msproxy_bindport
;
57 static int hf_msproxy_bindaddr
;
58 static int hf_msproxy_boundport
;
59 static int hf_msproxy_bind_id
;
60 static int hf_msproxy_resolvaddr
;
62 static int hf_msproxy_client_id
;
63 static int hf_msproxy_version
;
64 static int hf_msproxy_server_id
;
65 static int hf_msproxy_server_ack
;
66 static int hf_msproxy_client_ack
;
67 static int hf_msproxy_seq_num
;
68 static int hf_msproxy_rwsp_signature
;
69 static int hf_msproxy_ntlmssp_signature
;
71 static int hf_msproxy_server_int_addr
;
72 static int hf_msproxy_server_int_port
;
73 static int hf_msproxy_server_ext_addr
;
74 static int hf_msproxy_server_ext_port
;
76 /* Generated from convert_proto_tree_add_text.pl */
77 static int hf_msproxy_host_name
;
78 static int hf_msproxy_address_offset
;
79 static int hf_msproxy_client_computer_name
;
80 static int hf_msproxy_nt_domain
;
81 static int hf_msproxy_req_resolve_length
;
82 static int hf_msproxy_application_name
;
83 static int hf_msproxy_user_name
;
84 static int hf_msproxy_application
;
86 static expert_field ei_msproxy_unknown
;
87 static expert_field ei_msproxy_unhandled
;
89 static dissector_handle_t msproxy_sub_handle
;
92 #define UDP_PORT_MSPROXY 1745
94 #define N_MSPROXY_HELLO 0x05 /* packet 1 from client */
95 #define N_MSPROXY_ACK 0x10 /* packet 1 from server */
96 #define N_MSPROXY_USERINFO_ACK 0x04 /* packet 2 from server */
97 #define N_MSPROXY_AUTH 0x47 /* packet 3 from client */
98 #define N_MSPROXY_RESOLVE 0x07 /* Resolve request */
101 /*$$$ 0x0500 was dante value, I see 0x05ff and 0x0500 */
103 #define MSPROXY_HELLO 0x0500
104 #define MSPROXY_HELLO_2 0x05ff
106 #define MSPROXY_HELLO_ACK 0x1000
108 #define MSPROXY_USERINFO 0x1000
109 #define MSPROXY_USERINFO_ACK 0x0400
111 #define MSPROXY_AUTH 0x4700
112 #define MSPROXY_AUTH_1_ACK 0x4714
113 #define MSPROXY_AUTH_2 0x4701
114 #define MSPROXY_AUTH_2_ACK 0x4715
115 #define MSPROXY_AUTH_2_ACK2 0x4716
117 #define MSPROXY_RESOLVE 0x070d
118 #define MSPROXY_RESOLVE_ACK 0x070f
120 #define MSPROXY_BIND 0x0704
121 #define MSPROXY_BIND_ACK 0x0706
123 #define MSPROXY_TCP_BIND 0x0707
124 #define MSPROXY_TCP_BIND_ACK 0x0708
126 #define MSPROXY_LISTEN 0x0406
128 #define MSPROXY_BINDINFO 0x0709
130 #define MSPROXY_BINDINFO_ACK 0x070a
132 #define MSPROXY_CONNECT 0x071e
133 #define MSPROXY_CONNECT_ACK 0x0703
135 #define MSPROXY_UDPASSOCIATE 0x0705
136 #define MSPROXY_UDPASSOCIATE_ACK 0x0706
138 #define MSPROXY_UDP_BIND_REQ 0x070b
140 #define MSPROXY_CONNECTED 0x042c
141 #define MSPROXY_SESSIONEND 0x251e
143 #define MSPROXY_BIND_AUTHFAILED 0x0804
144 #define MSPROXY_CONNECT_AUTHFAILED 0x081e
145 #define MSPROXY_CONNREFUSED 0x4 /* low 12 bits seem to vary. */
147 #define FROM_SERVER 1 /* direction of packet data for get_msproxy_cmd_name */
148 #define FROM_CLIENT 0
153 /*$$$ should this be the same as redirect_entry_t ?? */
154 /* then the add_conversation could just copy the structure */
155 /* using the same allocation (instance for you object guys) */
156 /* wouldn't work because there may be multiple child conversations */
157 /* from the same MSProxy conversation */
163 uint32_t server_int_port
;
164 conversation_type ctype
;
168 /************** conversation hash stuff ***************/
171 uint32_t remote_addr
;
173 uint32_t server_int_port
;
174 uint32_t remote_port
;
175 conversation_type ctype
;
179 /************** negotiated conversation hash stuff ***************/
182 static int msproxy_sub_dissector( tvbuff_t
*tvb
, packet_info
*pinfo
,
183 proto_tree
*tree
, void* data _U_
) {
185 /* Conversation dissector called from TCP or UDP dissector. Decode and */
186 /* display the msproxy header, the pass the rest of the data to the tcp */
187 /* or udp port decode routine to handle the payload. */
190 redirect_entry_t
*redirect_info
;
191 conversation_t
*conversation
;
192 proto_tree
*msp_tree
;
195 conversation
= find_conversation_pinfo(pinfo
, 0);
197 DISSECTOR_ASSERT( conversation
); /* should always find a conversation */
199 redirect_info
= (redirect_entry_t
*)conversation_get_proto_data(conversation
,
202 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "MS Proxy");
204 col_set_str(pinfo
->cinfo
, COL_INFO
,
205 (( redirect_info
->ctype
== CONVERSATION_TCP
) ? "TCP stream" :
209 ti
= proto_tree_add_item( tree
, proto_msproxy
, tvb
, 0, 0,
212 msp_tree
= proto_item_add_subtree(ti
, ett_msproxy
);
214 proto_tree_add_uint( msp_tree
, hf_msproxy_dstport
, tvb
, 0, 0,
215 redirect_info
->remote_port
);
217 proto_tree_add_ipv4( msp_tree
, hf_msproxy_dstaddr
, tvb
, 0, 0,
218 redirect_info
->remote_addr
);
222 /* set pinfo->{src/dst port} and call the TCP or UDP sub-dissector lookup */
224 if ( pinfo
->srcport
== redirect_info
->clnt_port
)
225 ptr
= &pinfo
->destport
;
227 ptr
= &pinfo
->srcport
;
229 *ptr
= redirect_info
->remote_port
;
231 if ( redirect_info
->ctype
== CONVERSATION_TCP
)
232 decode_tcp_ports( tvb
, 0, pinfo
, tree
, pinfo
->srcport
,
233 pinfo
->destport
, NULL
, NULL
);
235 decode_udp_ports( tvb
, 0, pinfo
, tree
, pinfo
->srcport
,
236 pinfo
->destport
, -1);
238 *ptr
= redirect_info
->server_int_port
;
239 return tvb_captured_length(tvb
);
244 static void add_msproxy_conversation( packet_info
*pinfo
,
245 hash_entry_t
*hash_info
){
247 /* check to see if a conversation already exists, if it does assume */
248 /* it's our conversation and quit. Otherwise create a new conversation. */
249 /* Load the conversation dissector to our dissector and load the */
250 /* conversation data structure with the info needed to call the TCP or */
251 /* UDP port decoder. */
253 /* NOTE: Currently this assumes that the conversation will be created */
254 /* during a packet from the server. If that changes, pinfo->src */
255 /* and pinfo->dst will not be correct and this routine will have */
258 conversation_t
*conversation
;
259 redirect_entry_t
*new_conv_info
;
261 if (pinfo
->fd
->visited
) {
263 * We've already processed this frame once, so we
264 * should already have done this.
269 conversation
= find_conversation( pinfo
->num
, &pinfo
->src
,
270 &pinfo
->dst
, hash_info
->ctype
, hash_info
->server_int_port
,
271 hash_info
->clnt_port
, 0);
273 if ( !conversation
) {
274 conversation
= conversation_new( pinfo
->num
, &pinfo
->src
, &pinfo
->dst
,
275 hash_info
->ctype
, hash_info
->server_int_port
,
276 hash_info
->clnt_port
, 0);
278 conversation_set_dissector(conversation
, msproxy_sub_handle
);
280 new_conv_info
= wmem_new(wmem_file_scope(), redirect_entry_t
);
282 new_conv_info
->remote_addr
= hash_info
->dst_addr
;
283 new_conv_info
->clnt_port
= hash_info
->clnt_port
;
284 new_conv_info
->remote_port
= hash_info
->dst_port
;
285 new_conv_info
->server_int_port
= hash_info
->server_int_port
;
286 new_conv_info
->ctype
= hash_info
->ctype
;
288 conversation_add_proto_data(conversation
, proto_msproxy
,
294 static int display_application_name(tvbuff_t
*tvb
, int offset
,
297 /* display the application name in the proto tree. */
299 /* NOTE: this routine assumes that the tree pointer is valid (not NULL) */
303 length
= tvb_strnlen( tvb
, offset
, 255);
304 proto_tree_add_item(tree
, hf_msproxy_application
, tvb
, offset
, length
, ENC_ASCII
);
310 static const char *get_msproxy_cmd_name( int cmd
, int direction
) {
312 /* return the command name string for cmd */
315 case MSPROXY_HELLO_2
:
316 case MSPROXY_HELLO
: return "Hello";
318 /* MSPROXY_HELLO_ACK & MSPROXY_USERINFO have the same value (0x1000). */
319 /* So use the direction flag to determine which to use. */
321 case MSPROXY_USERINFO
:
322 if ( direction
== FROM_SERVER
)
323 return "Hello Acknowledge";
326 case MSPROXY_USERINFO_ACK
: return "User Info Acknowledge";
327 case MSPROXY_AUTH
: return "Authentication";
328 case MSPROXY_AUTH_1_ACK
: return "Authentication Acknowledge";
329 case MSPROXY_AUTH_2
: return "Authentication 2";
330 case MSPROXY_AUTH_2_ACK
: return "Authentication 2 Acknowledge";
331 case MSPROXY_RESOLVE
: return "Resolve";
332 case MSPROXY_RESOLVE_ACK
: return "Resolve Acknowledge";
333 case MSPROXY_BIND
: return "Bind";
334 case MSPROXY_TCP_BIND
: return "TCP Bind";
335 case MSPROXY_TCP_BIND_ACK
: return "TCP Bind Acknowledge";
336 case MSPROXY_LISTEN
: return "Listen";
337 case MSPROXY_BINDINFO
: return "Bind Info";
338 case MSPROXY_BINDINFO_ACK
: return "Bind Info Acknowledge";
339 case MSPROXY_CONNECT
: return "Connect";
340 case MSPROXY_CONNECT_ACK
: return "Connect Acknowledge";
341 case MSPROXY_UDPASSOCIATE
: return "UDP Associate";
342 case MSPROXY_UDP_BIND_REQ
: return "UDP Bind";
343 case MSPROXY_UDPASSOCIATE_ACK
: return "Bind or Associate Acknowledge";
344 case MSPROXY_CONNECTED
: return "Connected";
345 case MSPROXY_SESSIONEND
: return "Session End";
347 default: return "Unknown";
353 static void dissect_user_info_2(tvbuff_t
*tvb
, int offset
,
356 /* decode the user, application, computer name */
362 length
= tvb_strnlen( tvb
, offset
, 255);
365 proto_tree_add_item(tree
, hf_msproxy_user_name
, tvb
, offset
, length
+ 1, ENC_ASCII
);
366 offset
+= length
+ 2;
368 length
= tvb_strnlen( tvb
, offset
, 255);
371 proto_tree_add_item(tree
, hf_msproxy_application_name
, tvb
, offset
, length
+ 1, ENC_ASCII
);
372 offset
+= length
+ 1;
374 length
= tvb_strnlen( tvb
, offset
, 255);
377 proto_tree_add_item(tree
, hf_msproxy_client_computer_name
, tvb
, offset
, length
+ 1, ENC_ASCII
);
383 static void dissect_msproxy_request_1(tvbuff_t
*tvb
, int offset
,
386 /* decode the request _1 structure */
391 dissect_user_info_2( tvb
, offset
, tree
);
397 static void dissect_bind(tvbuff_t
*tvb
, int offset
,
398 proto_tree
*tree
, hash_entry_t
*conv_info
) {
400 /* decode the bind request */
405 proto_tree_add_item( tree
, hf_msproxy_bindaddr
, tvb
, offset
, 4,
410 proto_tree_add_item( tree
, hf_msproxy_bindport
, tvb
, offset
, 2,
415 proto_tree_add_item( tree
, hf_msproxy_clntport
, tvb
, offset
, 2,
419 conv_info
->clnt_port
= tvb_get_ntohs( tvb
, offset
);
423 proto_tree_add_item( tree
, hf_msproxy_boundport
, tvb
, offset
, 2,
427 display_application_name( tvb
, offset
, tree
);
433 static int dissect_auth(tvbuff_t
*tvb
, int offset
,
436 /* decode the authorization request */
441 proto_tree_add_item( tree
, hf_msproxy_ntlmssp_signature
, tvb
, offset
, 7, ENC_NA
|ENC_ASCII
);
450 static void dissect_tcp_bind(tvbuff_t
*tvb
, int offset
,
451 proto_tree
*tree
, hash_entry_t
*conv_info
) {
453 /* decode the bind packet. Set the protocol type in the conversation */
454 /* information so the bind_info can use it to create the payload */
458 conv_info
->ctype
= CONVERSATION_TCP
;
463 proto_tree_add_item( tree
, hf_msproxy_bind_id
, tvb
, offset
, 4,
467 proto_tree_add_item( tree
, hf_msproxy_boundport
, tvb
, offset
, 2,
471 display_application_name( tvb
, offset
, tree
);
476 static void dissect_request_connect(tvbuff_t
*tvb
, int offset
,
477 proto_tree
*tree
, hash_entry_t
*conv_info
) {
479 /* decode the connect request, display */
481 conv_info
->ctype
= CONVERSATION_TCP
;
486 proto_tree_add_item( tree
, hf_msproxy_dstport
, tvb
, offset
, 2,
489 conv_info
->dst_port
= tvb_get_ntohs( tvb
, offset
);
493 proto_tree_add_item( tree
, hf_msproxy_dstaddr
, tvb
, offset
, 4,
496 conv_info
->dst_addr
= tvb_get_ipv4( tvb
, offset
);
500 conv_info
->clnt_port
= tvb_get_ntohs( tvb
, offset
);
503 proto_tree_add_uint( tree
, hf_msproxy_clntport
, tvb
, offset
, 2,
504 conv_info
->clnt_port
);
508 display_application_name( tvb
, offset
, tree
);
513 static void dissect_bind_info_ack(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
) {
515 /* decode the client bind info ack */
521 proto_tree_add_item( tree
, hf_msproxy_bind_id
, tvb
, offset
, 4,
525 proto_tree_add_item( tree
, hf_msproxy_dstport
, tvb
, offset
, 2,
529 proto_tree_add_item( tree
, hf_msproxy_dstaddr
, tvb
, offset
, 4,
533 proto_tree_add_item( tree
, hf_msproxy_server_int_port
, tvb
,
534 offset
, 2, ENC_BIG_ENDIAN
);
537 proto_tree_add_item( tree
, hf_msproxy_server_ext_port
, tvb
,
538 offset
, 2, ENC_BIG_ENDIAN
);
541 proto_tree_add_item( tree
, hf_msproxy_server_ext_addr
, tvb
,
542 offset
, 4, ENC_BIG_ENDIAN
);
545 display_application_name( tvb
, offset
, tree
);
550 static void dissect_request_resolve(tvbuff_t
*tvb
, int offset
,
551 proto_tree
*tree
, packet_info
*pinfo
) {
553 /* dissect the request resolve structure */
554 /* display a string with a length, characters encoding */
555 /* they are displayed under a tree with the name in Label variable */
556 /* return the length of the string and the length byte */
558 proto_tree
*name_tree
;
560 int length
= tvb_get_uint8( tvb
, offset
);
563 name_tree
= proto_tree_add_subtree_format(tree
, tvb
, offset
, length
+ 1,
564 ett_msproxy_name
, NULL
, "Host Name: %s",
565 tvb_get_string_enc( pinfo
->pool
, tvb
, offset
+ 18, length
, ENC_ASCII
));
567 proto_tree_add_item(name_tree
, hf_msproxy_req_resolve_length
, tvb
, offset
, 1, ENC_NA
);
572 proto_tree_add_item(name_tree
, hf_msproxy_host_name
, tvb
, offset
, length
, ENC_ASCII
);
578 static void dissect_udp_bind(tvbuff_t
*tvb
, int offset
,
579 proto_tree
*tree
, hash_entry_t
*conv_info
) {
582 * Dissect the udp bind request. Load the conversation key type
583 * (CONVERSATION_UDP) and the remote address so bind_info
584 * can use it to create conversation dissector.
587 conv_info
->ctype
= CONVERSATION_UDP
;
593 proto_tree_add_item( tree
, hf_msproxy_bind_id
, tvb
, offset
, 4,
599 proto_tree_add_item( tree
, hf_msproxy_dstport
, tvb
, offset
, 2,
604 proto_tree_add_item( tree
, hf_msproxy_dstaddr
, tvb
, offset
, 4,
610 display_application_name( tvb
, offset
, tree
);
614 static void dissect_udp_assoc(tvbuff_t
*tvb
, int offset
,
615 proto_tree
*tree
, hash_entry_t
*conv_info
) {
617 /* dissect the udp associate request. And load client port into */
618 /* conversation data structure for later. */
624 proto_tree_add_item( tree
, hf_msproxy_clntport
, tvb
, offset
, 2,
627 conv_info
->clnt_port
= tvb_get_ntohs( tvb
, offset
);
632 display_application_name( tvb
, offset
, tree
);
636 static void dissect_msproxy_request(tvbuff_t
*tvb
, packet_info
*pinfo
,
637 proto_tree
*tree
, hash_entry_t
*conv_info
) {
641 proto_item
* cmd_item
;
643 proto_tree_add_item( tree
, hf_msproxy_client_id
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
646 proto_tree_add_item( tree
, hf_msproxy_version
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
649 proto_tree_add_item( tree
, hf_msproxy_server_id
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
652 proto_tree_add_item( tree
, hf_msproxy_server_ack
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
655 proto_tree_add_item( tree
, hf_msproxy_seq_num
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
658 proto_tree_add_item( tree
, hf_msproxy_rwsp_signature
, tvb
, offset
, 4, ENC_NA
|ENC_ASCII
);
661 cmd
= tvb_get_ntohs( tvb
, offset
);
663 cmd_item
= proto_tree_add_uint_format_value( tree
, hf_msproxy_cmd
, tvb
, offset
, 2,
665 get_msproxy_cmd_name( cmd
, FROM_CLIENT
),
672 dissect_auth( tvb
, offset
, tree
);
676 dissect_bind( tvb
, offset
, tree
, conv_info
);
679 case MSPROXY_UDP_BIND_REQ
:
680 dissect_udp_bind( tvb
, offset
, tree
, conv_info
);
683 case MSPROXY_AUTH_2
: /*$$ this is probably wrong place for this */
684 case MSPROXY_TCP_BIND
:
685 dissect_tcp_bind( tvb
, offset
, tree
, conv_info
);
688 case MSPROXY_RESOLVE
:
689 dissect_request_resolve( tvb
, offset
, tree
, pinfo
);
692 case MSPROXY_CONNECT
:
694 dissect_request_connect( tvb
, offset
, tree
,
698 case MSPROXY_BINDINFO_ACK
:
699 dissect_bind_info_ack( tvb
, offset
, tree
);
703 case MSPROXY_HELLO_2
:
704 dissect_msproxy_request_1( tvb
, offset
, tree
);
707 case MSPROXY_UDPASSOCIATE
:
708 dissect_udp_assoc( tvb
, offset
, tree
, conv_info
);
711 expert_add_info_format(pinfo
, cmd_item
, &ei_msproxy_unhandled
,
712 "Unhandled request command (report this, please)");
718 static int dissect_hello_ack(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
) {
720 /* decode the hello acknowledge packet */
724 proto_tree_add_item( tree
, hf_msproxy_serverport
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
726 proto_tree_add_item( tree
, hf_msproxy_serveraddr
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
734 /* XXX - implement me */
735 static int dissect_user_info_ack(tvbuff_t
*tvb _U_
, int offset
,
736 proto_tree
*tree _U_
) {
738 /* decode the response _2 structure */
749 static void dissect_udpassociate_ack(tvbuff_t
*tvb
, int offset
,
755 proto_tree_add_item( tree
, hf_msproxy_bind_id
, tvb
, offset
, 4,
759 proto_tree_add_item( tree
, hf_msproxy_server_ext_port
, tvb
,
760 offset
, 2, ENC_BIG_ENDIAN
);
763 proto_tree_add_item( tree
, hf_msproxy_server_ext_addr
, tvb
,
764 offset
, 4, ENC_BIG_ENDIAN
);
767 display_application_name( tvb
, offset
, tree
);
773 static void dissect_auth_1_ack(tvbuff_t
*tvb
, int offset
,
778 proto_tree_add_item( tree
, hf_msproxy_ntlmssp_signature
, tvb
, offset
, 7, ENC_NA
|ENC_ASCII
);
781 /* XXX - always 255? */
782 proto_tree_add_item(tree
, hf_msproxy_nt_domain
, tvb
, offset
, 255, ENC_ASCII
);
788 /* XXX - implement me */
789 static int dissect_msproxy_response_4( tvbuff_t
*tvb _U_
, int offset
,
790 proto_tree
*tree _U_
) {
792 /* decode the response _4 structure */
801 static void dissect_connect_ack( tvbuff_t
*tvb
, int offset
, packet_info
*pinfo
,
802 proto_tree
*tree
, hash_entry_t
*conv_info
) {
804 /* decode the connect ack packet */
808 proto_tree_add_item( tree
, hf_msproxy_server_int_port
, tvb
,
809 offset
, 2, ENC_BIG_ENDIAN
);
812 conv_info
->ctype
= CONVERSATION_TCP
;
813 conv_info
->server_int_port
= tvb_get_ntohs( tvb
, offset
);
817 proto_tree_add_item( tree
, hf_msproxy_server_int_addr
, tvb
,
818 offset
, 4, ENC_BIG_ENDIAN
);
821 proto_tree_add_item( tree
, hf_msproxy_server_ext_port
, tvb
,
822 offset
, 2, ENC_BIG_ENDIAN
);
825 proto_tree_add_item( tree
, hf_msproxy_server_ext_addr
, tvb
,
826 offset
, 4, ENC_BIG_ENDIAN
);
829 display_application_name( tvb
, offset
, tree
);
832 add_msproxy_conversation( pinfo
, conv_info
);
837 static void dissect_tcp_bind_ack( tvbuff_t
*tvb
, int offset
, proto_tree
*tree
) {
839 /* decode the tcp bind */
844 proto_tree_add_item( tree
, hf_msproxy_bind_id
, tvb
, offset
, 4,
848 proto_tree_add_item( tree
, hf_msproxy_server_int_port
, tvb
,
849 offset
, 2, ENC_BIG_ENDIAN
);
852 proto_tree_add_item( tree
, hf_msproxy_server_ext_port
, tvb
,
853 offset
, 2, ENC_BIG_ENDIAN
);
856 proto_tree_add_item( tree
, hf_msproxy_server_ext_addr
, tvb
,
857 offset
, 4, ENC_BIG_ENDIAN
);
861 display_application_name( tvb
, offset
, tree
);
867 static void dissect_bind_info( tvbuff_t
*tvb
, int offset
, packet_info
*pinfo
,
868 proto_tree
*tree
, hash_entry_t
*conv_info
) {
870 /* decode the Bind info response from server */
875 proto_tree_add_item( tree
, hf_msproxy_bind_id
, tvb
, offset
, 4,
880 conv_info
->dst_port
= tvb_get_ntohs( tvb
, offset
);
882 proto_tree_add_uint( tree
, hf_msproxy_dstport
, tvb
, offset
, 2,
883 conv_info
->dst_port
);
886 conv_info
->dst_addr
= tvb_get_ipv4( tvb
, offset
);
888 proto_tree_add_item( tree
, hf_msproxy_dstaddr
, tvb
, offset
, 4,
892 conv_info
->server_int_port
= tvb_get_ntohs( tvb
, offset
);
894 proto_tree_add_uint( tree
, hf_msproxy_server_int_port
, tvb
,
895 offset
, 2, conv_info
->server_int_port
);
899 proto_tree_add_item( tree
, hf_msproxy_server_ext_port
, tvb
,
900 offset
, 2, ENC_BIG_ENDIAN
);
903 proto_tree_add_item( tree
, hf_msproxy_server_ext_addr
, tvb
,
904 offset
, 4, ENC_BIG_ENDIAN
);
907 display_application_name( tvb
, offset
, tree
);
911 add_msproxy_conversation( pinfo
, conv_info
);
916 static void dissect_resolve(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
) {
918 /* dissect the response resolve structure */
919 /* display a string with a length, characters encoding */
920 /* they are displayed under a tree with the name in Label variable */
921 /* return the length of the string and the length byte */
926 addr_offset
= tvb_get_uint8( tvb
, offset
);
928 proto_tree_add_item(tree
, hf_msproxy_address_offset
, tvb
, offset
, 1, ENC_NA
);
934 offset
+= addr_offset
;
936 proto_tree_add_item( tree
, hf_msproxy_resolvaddr
, tvb
, offset
, 4,
943 static void dissect_msproxy_response(tvbuff_t
*tvb
, packet_info
*pinfo
,
944 proto_tree
*tree
, hash_entry_t
*conv_info
) {
951 proto_tree_add_item( tree
, hf_msproxy_client_id
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
954 proto_tree_add_item( tree
, hf_msproxy_version
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
957 proto_tree_add_item( tree
, hf_msproxy_server_id
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
960 proto_tree_add_item( tree
, hf_msproxy_client_ack
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
963 proto_tree_add_item( tree
, hf_msproxy_seq_num
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
966 proto_tree_add_item( tree
, hf_msproxy_rwsp_signature
, tvb
, offset
, 4, ENC_NA
|ENC_ASCII
);
972 cmd
= tvb_get_ntohs( tvb
, offset
);
974 ti
= proto_tree_add_uint_format_value( tree
, hf_msproxy_cmd
, tvb
, offset
, 2,
975 cmd
, "0x%02x (%s)", cmd
,
976 get_msproxy_cmd_name( cmd
, FROM_SERVER
));
980 case MSPROXY_HELLO_ACK
:
981 dissect_hello_ack( tvb
, offset
, tree
);
984 case MSPROXY_USERINFO_ACK
:
985 dissect_user_info_ack( tvb
, offset
, tree
);
988 case MSPROXY_AUTH_1_ACK
:
989 dissect_auth_1_ack( tvb
, offset
, tree
);
992 /* this also handle the MSPROXY_BIND_ACK ??? check this */
994 case MSPROXY_UDPASSOCIATE_ACK
:
995 dissect_udpassociate_ack( tvb
, offset
, tree
);
998 case MSPROXY_AUTH_2_ACK
:
999 case MSPROXY_AUTH_2_ACK2
:
1000 dissect_msproxy_response_4( tvb
, offset
, tree
);
1003 case MSPROXY_TCP_BIND_ACK
:
1004 dissect_tcp_bind_ack( tvb
, offset
, tree
);
1007 case MSPROXY_CONNECT_ACK
:
1008 dissect_connect_ack( tvb
, offset
, pinfo
, tree
,
1012 case MSPROXY_BINDINFO
:
1013 dissect_bind_info( tvb
, offset
, pinfo
, tree
, conv_info
);
1016 case MSPROXY_RESOLVE_ACK
:
1017 dissect_resolve( tvb
, offset
, tree
);
1020 case MSPROXY_CONNECT_AUTHFAILED
:
1021 case MSPROXY_BIND_AUTHFAILED
:
1022 expert_add_info(pinfo
, ti
, &ei_msproxy_unknown
);
1027 if ((((cmd
>> 8) == MSPROXY_CONNREFUSED
) ||
1028 ((cmd
>> 12) == MSPROXY_CONNREFUSED
)))
1029 expert_add_info(pinfo
, ti
, &ei_msproxy_unknown
);
1031 expert_add_info(pinfo
, ti
, &ei_msproxy_unhandled
);
1039 static int dissect_msproxy(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
) {
1041 proto_tree
*msproxy_tree
;
1046 hash_entry_t
*hash_info
;
1047 conversation_t
*conversation
;
1049 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "MSproxy");
1050 col_clear(pinfo
->cinfo
, COL_INFO
);
1052 conversation
= find_or_create_conversation(pinfo
);
1054 hash_info
= (hash_entry_t
*)conversation_get_proto_data(conversation
, proto_msproxy
);
1056 hash_info
= wmem_new0(wmem_file_scope(), hash_entry_t
);
1057 conversation_add_proto_data(conversation
, proto_msproxy
,
1061 cmd
= tvb_get_ntohs( tvb
, 36);
1063 if ( pinfo
->srcport
== UDP_PORT_MSPROXY
)
1064 col_add_fstr( pinfo
->cinfo
, COL_INFO
, "Server message: %s",
1065 get_msproxy_cmd_name( cmd
, FROM_SERVER
));
1067 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Client message: %s",
1068 get_msproxy_cmd_name( cmd
, FROM_CLIENT
));
1070 ti
= proto_tree_add_item( tree
, proto_msproxy
, tvb
, 0, -1, ENC_NA
);
1071 msproxy_tree
= proto_item_add_subtree(ti
, ett_msproxy
);
1073 if ( pinfo
->srcport
== UDP_PORT_MSPROXY
)
1074 dissect_msproxy_response( tvb
, pinfo
, msproxy_tree
, hash_info
);
1076 dissect_msproxy_request( tvb
, pinfo
, msproxy_tree
, hash_info
);
1078 return tvb_captured_length(tvb
);
1083 proto_register_msproxy( void){
1085 /* Prep the msproxy protocol, for now, just register it */
1087 static int *ett
[] = {
1091 static hf_register_info hf
[] = {
1094 { "Command", "msproxy.command", FT_UINT16
, BASE_DEC
,
1095 NULL
, 0x0, NULL
, HFILL
1099 { &hf_msproxy_dstaddr
,
1100 { "Destination Address", "msproxy.dstaddr", FT_IPv4
, BASE_NONE
, NULL
,
1106 { &hf_msproxy_srcport
,
1107 { "Source Port", "msproxy.srcport", FT_UINT16
,
1108 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
1112 { &hf_msproxy_dstport
,
1113 { "Destination Port", "msproxy.dstport", FT_UINT16
,
1114 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
1117 { &hf_msproxy_clntport
,
1118 { "Client Port", "msproxy.clntport", FT_UINT16
,
1119 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
1122 { &hf_msproxy_server_ext_addr
,
1123 { "Server External Address", "msproxy.server_ext_addr", FT_IPv4
, BASE_NONE
, NULL
,
1128 { &hf_msproxy_server_ext_port
,
1129 { "Server External Port", "msproxy.server_ext_port", FT_UINT16
,
1130 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
1134 { &hf_msproxy_server_int_addr
,
1135 { "Server Internal Address", "msproxy.server_int_addr", FT_IPv4
, BASE_NONE
, NULL
,
1140 { &hf_msproxy_server_int_port
,
1141 { "Server Internal Port", "msproxy.server_int_port", FT_UINT16
,
1142 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
1145 { &hf_msproxy_serverport
,
1146 { "Server Port", "msproxy.serverport", FT_UINT16
,
1147 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
1150 { &hf_msproxy_bindport
,
1151 { "Bind Port", "msproxy.bindport", FT_UINT16
,
1152 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
1155 { &hf_msproxy_boundport
,
1156 { "Bound Port", "msproxy.boundport", FT_UINT16
,
1157 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
1160 { &hf_msproxy_serveraddr
,
1161 { "Server Address", "msproxy.serveraddr", FT_IPv4
, BASE_NONE
, NULL
,
1165 { &hf_msproxy_bindaddr
,
1166 { "Destination", "msproxy.bindaddr", FT_IPv4
, BASE_NONE
, NULL
,
1170 { &hf_msproxy_bind_id
,
1171 { "Bound Port Id", "msproxy.bindid", FT_UINT32
,
1172 BASE_HEX
, NULL
, 0x0, NULL
, HFILL
1175 { &hf_msproxy_resolvaddr
,
1176 { "Address", "msproxy.resolvaddr", FT_IPv4
, BASE_NONE
, NULL
,
1180 { &hf_msproxy_client_id
,
1181 { "Client Id", "msproxy.client_id", FT_UINT32
,
1182 BASE_HEX
, NULL
, 0x0, NULL
, HFILL
1185 { &hf_msproxy_version
,
1186 { "Version", "msproxy.version", FT_UINT32
,
1187 BASE_HEX
, NULL
, 0x0, NULL
, HFILL
1190 { &hf_msproxy_server_id
,
1191 { "Server id", "msproxy.server_id", FT_UINT32
,
1192 BASE_HEX
, NULL
, 0x0, NULL
, HFILL
1195 { &hf_msproxy_server_ack
,
1196 { "Server ack", "msproxy.server_ack", FT_UINT8
,
1197 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
1200 { &hf_msproxy_client_ack
,
1201 { "Client ack", "msproxy.client_ack", FT_UINT8
,
1202 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
1205 { &hf_msproxy_seq_num
,
1206 { "Sequence Number", "msproxy.seq_num", FT_UINT8
,
1207 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
1210 { &hf_msproxy_rwsp_signature
,
1211 { "RWSP signature", "msproxy.rwsp_signature", FT_STRING
, BASE_NONE
, NULL
,
1215 { &hf_msproxy_ntlmssp_signature
,
1216 { "NTLMSSP signature", "msproxy.ntlmssp_signature", FT_STRING
, BASE_NONE
, NULL
,
1221 /* Generated from convert_proto_tree_add_text.pl */
1222 { &hf_msproxy_application
, { "Application", "msproxy.application", FT_STRING
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
1223 { &hf_msproxy_user_name
, { "User name", "msproxy.user_name", FT_STRING
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
1224 { &hf_msproxy_application_name
, { "Application name", "msproxy.application_name", FT_STRING
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
1225 { &hf_msproxy_client_computer_name
, { "Client computer name", "msproxy.client_computer_name", FT_STRING
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
1226 { &hf_msproxy_req_resolve_length
, { "Length", "msproxy.req_resolve.length", FT_UINT8
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
1227 { &hf_msproxy_host_name
, { "Host Name", "msproxy.host_name", FT_STRING
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
1228 { &hf_msproxy_nt_domain
, { "NT domain", "msproxy.nt_domain", FT_STRING
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
1229 { &hf_msproxy_address_offset
, { "Address offset", "msproxy.address_offset", FT_UINT8
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
1232 static ei_register_info ei
[] = {
1233 { &ei_msproxy_unknown
,
1234 { "msproxy.unknown", PI_UNDECODED
, PI_WARN
, "No know information (help wanted)", EXPFILL
}},
1235 { &ei_msproxy_unhandled
,
1236 { "msproxy.command.unhandled", PI_UNDECODED
, PI_WARN
, "Unhandled response command (report this, please)", EXPFILL
}},
1239 expert_module_t
* expert_msproxy
;
1241 proto_msproxy
= proto_register_protocol( "MS Proxy Protocol", "MS Proxy", "msproxy");
1243 proto_register_field_array(proto_msproxy
, hf
, array_length(hf
));
1244 proto_register_subtree_array(ett
, array_length(ett
));
1245 expert_msproxy
= expert_register_protocol(proto_msproxy
);
1246 expert_register_field_array(expert_msproxy
, ei
, array_length(ei
));
1248 msproxy_sub_handle
= register_dissector("msproxy", msproxy_sub_dissector
,
1254 proto_reg_handoff_msproxy(void) {
1256 /* dissector install routine */
1258 dissector_handle_t msproxy_handle
;
1260 msproxy_handle
= create_dissector_handle(dissect_msproxy
, proto_msproxy
);
1261 dissector_add_uint_with_preference("udp.port", UDP_PORT_MSPROXY
, msproxy_handle
);
1265 * Editor modelines - https://www.wireshark.org/tools/modelines.html
1270 * indent-tabs-mode: t
1273 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
1274 * :indentSize=8:tabSize=8:noTabs=false: