aboutsummaryrefslogtreecommitdiffstats
path: root/epan
diff options
context:
space:
mode:
authorRonnie Sahlberg <ronnie_sahlberg@ozemail.com.au>2006-08-20 06:00:16 +0000
committerRonnie Sahlberg <ronnie_sahlberg@ozemail.com.au>2006-08-20 06:00:16 +0000
commitcf6d4692aa8db3656ea275118cf37535808275ee (patch)
tree6e52e21e57b8f0c7140cca267b5347c888d0a81b /epan
parent0adb40dbc07203c2eb673f9e9e2adc2cf20f319b (diff)
in LDAP over TCP
use tcp_dissect_pdus() which works insterad of trying to do the pdu tracking and signalling for reassembly manually. This makes ldap pdu tracking and reassembly work properly for cases when hosts are streaming lpad over tcp and there is little or none alignlemt of pdus to the start of a segment svn path=/trunk/; revision=18965
Diffstat (limited to 'epan')
-rw-r--r--epan/dissectors/packet-ldap.c175
1 files changed, 81 insertions, 94 deletions
diff --git a/epan/dissectors/packet-ldap.c b/epan/dissectors/packet-ldap.c
index c38d601a8f..bef6e2c6c2 100644
--- a/epan/dissectors/packet-ldap.c
+++ b/epan/dissectors/packet-ldap.c
@@ -365,7 +365,6 @@ typedef struct ldap_conv_info_t {
GHashTable *unmatched;
GHashTable *matched;
gboolean is_mscldap;
- gboolean first_time;
guint32 num_results;
} ldap_conv_info_t;
static ldap_conv_info_t *ldap_info_items;
@@ -2775,7 +2774,7 @@ static void dissect_LDAPMessage_PDU(tvbuff_t *tvb, packet_info *pinfo, proto_tre
/*--- End of included file: packet-ldap-fn.c ---*/
-#line 540 "packet-ldap-template.c"
+#line 539 "packet-ldap-template.c"
static void
dissect_ldap_payload(tvbuff_t *tvb, packet_info *pinfo,
@@ -2783,7 +2782,6 @@ dissect_ldap_payload(tvbuff_t *tvb, packet_info *pinfo,
gboolean rest_is_pad, gboolean is_mscldap)
{
int offset = 0;
- gboolean first_time = TRUE;
guint length_remaining;
guint msg_len = 0;
int messageOffset = 0;
@@ -2794,12 +2792,6 @@ dissect_ldap_payload(tvbuff_t *tvb, packet_info *pinfo,
gboolean pc, ind = 0;
gint32 ber_tag;
- while (tvb_reported_length_remaining(tvb, offset) > 0) {
- /*
- * This will throw an exception if we don't have any data left.
- * That's what we want. (See "tcp_dissect_pdus()", which is
- * similar)
- */
length_remaining = tvb_ensure_length_remaining(tvb, offset);
if (rest_is_pad && length_remaining < 6) return;
@@ -2860,8 +2852,6 @@ dissect_ldap_payload(tvbuff_t *tvb, packet_info *pinfo,
* Now dissect the LDAP message.
*/
- /*dissect_ldap_message(msg_tvb, 0, pinfo, msg_tree, msg_item, first_time, ldap_info, is_mscldap);*/
- ldap_info->first_time= first_time;
ldap_info->is_mscldap = is_mscldap;
pinfo->private_data = ldap_info;
dissect_LDAPMessage_PDU(msg_tvb, pinfo, tree);
@@ -2869,8 +2859,6 @@ dissect_ldap_payload(tvbuff_t *tvb, packet_info *pinfo,
offset += msg_len;
- first_time = FALSE;
- }
}
static void
@@ -2934,17 +2922,6 @@ dissect_ldap_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean i
}
}
- while (tvb_reported_length_remaining(tvb, offset) > 0) {
-
- /*
- * This will throw an exception if we don't have any data left.
- * That's what we want. (See "tcp_dissect_pdus()", which is
- * similar, but doesn't have to deal with the SASL issues.
- * XXX - can we make "tcp_dissect_pdus()" provide enough information
- * to the "get_pdu_len" routine so that we could have one dealing
- * with the SASL issues, have that routine deal with SASL and
- * ASN.1, and just use "tcp_dissect_pdus()"?)
- */
length_remaining = tvb_ensure_length_remaining(tvb, offset);
/* It might still be a packet containing a SASL security layer
@@ -3153,10 +3130,7 @@ dissect_ldap_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean i
} else {
/* plain LDAP, so dissect the payload */
dissect_ldap_payload(tvb, pinfo, ldap_tree, ldap_info, FALSE, is_mscldap);
- /* dissect_ldap_payload() has it's own loop so go out here */
- break;
}
- }
}
static int dissect_mscldap_string(tvbuff_t *tvb, int offset, char *str, int maxlen, gboolean prepend_dot)
@@ -3411,11 +3385,11 @@ get_normal_ldap_pdu_len(tvbuff_t *tvb, int offset)
int data_offset;
/* normal ldap is tag+len bytes plus the length
- * offset==0 is where the tag is
- * offset==1 is where length starts
+ * offset is where the tag is
+ * offset+1 is where length starts
*/
- data_offset=get_ber_length(NULL, tvb, 1, &len, &ind);
- return len+data_offset;
+ data_offset=get_ber_length(NULL, tvb, offset+1, &len, &ind);
+ return len+data_offset-offset;
}
static void
@@ -3561,71 +3535,84 @@ dissect_ldap_guid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
}
static void
-dissect_ldap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+dissect_ldap_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
+ guint32 sasl_len;
+ guint32 gss_len;
+ guint32 ldap_len;
+ int offset;
+ gboolean ind;
+
ldm_tree = NULL;
- /* Here we must take care of reassembly but this is tricky since
- * depending on whether SASL is present or not, the heuristics
- * will be very different.
+ /* This is a bit tricky. We have to find out whether SASL is used
+ * so that we know how big a header we are supposed to pass
+ * to tcp_dissect_pdus()
*/
- if(ldap_desegment && (tvb_length(tvb)==tvb_reported_length(tvb))){
- guint32 len;
-
- /* check for a SASL header, i.e. four byte integer where the
- * first two bytes are 0x00 and the value is <64k and >2
- * (>2 to fight false positives, 0x00000000 is a common
- * "random" tcp payload)
- * (no SASL ldap PDUs are ever going to be >64k in size?)
- *
- * Following the SASL header is a GSSAPI blob so the next byte
- * is always 0x60. (only true for MS SASL LDAP, there are other
- * blobs that may follow in real-world)
- */
- len=tvb_get_ntohl(tvb, 0);
- if( (len<65535)
- && (len>2)
- && (tvb_get_guint8(tvb, 4)==0x60)){
- if(len<=tvb_length_remaining(tvb, 4)){
- /* we have a full ldap pdu */
- dissect_ldap_pdu(tvb, pinfo, tree, FALSE);
- return;
- } else {
- /* we have to do reassembly */
- tcp_dissect_pdus(tvb, pinfo, tree, ldap_desegment, 4, get_sasl_ldap_pdu_len, dissect_sasl_ldap_pdu);
- return;
- }
- }
- /* check if it is a normal BER encoded LDAP packet
- * i.e. first byte is 0x30 followed by a length that is
- * <64k
- * (no ldap PDUs are ever >64kb? )
- */
- if(tvb_get_guint8(tvb, 0)==0x30){
- gboolean ind;
- int data_offset;
-
- /* check that length makes sense */
- data_offset=get_ber_length(NULL, tvb, 1, &len, &ind);
-
- /* dont check ind since indefinite length is never used for ldap (famous last words)*/
- if(len<2 || len>65535){
- return;
- }
-
- if(len<=tvb_length_remaining(tvb, data_offset)){
- /* we have a full ldap pdu */
- dissect_ldap_pdu(tvb, pinfo, tree, FALSE);
- return;
- } else {
- /* we have to do reassembly */
- tcp_dissect_pdus(tvb, pinfo, tree, ldap_desegment, 4, get_normal_ldap_pdu_len, dissect_normal_ldap_pdu);
- return;
- }
- }
+ /* check for a SASL header, i.e. assume it is SASL if
+ * 1, first four bytes (SASL length) is an integer
+ * with a value that must be <64k and >2
+ * (>2 to fight false positives, 0x00000000 is a common
+ * "random" tcp payload)
+ * (no SASL ldap PDUs are ever going to be >64k in size?)
+ *
+ * Following the SASL header is a GSSAPI blob so the next byte
+ * is always 0x60. (only true for MS SASL LDAP, there are other
+ * blobs that may follow in real-world)
+ *
+ * 2, Then one byte with the value 0x60 indicating the GSSAPI blob
+ *
+ * 3, Then X bytes describing the BER encoded lengtyh of the blob.
+ * This length should point to the same end-of-pdu as 1,
+ *
+ * 4, finally a byte 0x06 indicating that the next object is an OID
+ */
+ sasl_len=tvb_get_ntohl(tvb, 0);
+
+ if( (sasl_len>65535)
+ || (sasl_len<2) ){
+ goto this_was_not_sasl;
}
- dissect_ldap_pdu(tvb, pinfo, tree, FALSE);
+ if(tvb_get_guint8(tvb, 4)!=0x60){
+ goto this_was_not_sasl;
+ }
+
+ offset=get_ber_length(NULL, tvb, 5, &gss_len, &ind);
+ if(sasl_len!=(gss_len+offset-4)){
+ goto this_was_not_sasl;
+ }
+
+ if(tvb_get_guint8(tvb, offset)!=0x06){
+ goto this_was_not_sasl;
+ }
+
+ tcp_dissect_pdus(tvb, pinfo, tree, ldap_desegment, 4, get_sasl_ldap_pdu_len, dissect_sasl_ldap_pdu);
+
+
+this_was_not_sasl:
+ /* check if it is a normal BER encoded LDAP packet
+ * i.e. first byte is 0x30 followed by a length that is
+ * <64k
+ * (no ldap PDUs are ever >64kb? )
+ */
+ if(tvb_get_guint8(tvb, 0)!=0x30){
+ goto this_was_not_normal_ldap;
+ }
+
+ /* check that length makes sense */
+ offset=get_ber_length(NULL, tvb, 1, &ldap_len, &ind);
+
+ /* dont check ind since indefinite length is never used for ldap (famous last words)*/
+ if(ldap_len<2 || ldap_len>65535){
+ goto this_was_not_normal_ldap;
+ }
+
+ tcp_dissect_pdus(tvb, pinfo, tree, ldap_desegment, 4, get_normal_ldap_pdu_len, dissect_normal_ldap_pdu);
+
+
+this_was_not_normal_ldap:
+
return;
}
@@ -4237,7 +4224,7 @@ void proto_register_ldap(void) {
"ldap.OCTET_STRING", HFILL }},
/*--- End of included file: packet-ldap-hfarr.c ---*/
-#line 1609 "packet-ldap-template.c"
+#line 1596 "packet-ldap-template.c"
};
/* List of subtrees */
@@ -4290,7 +4277,7 @@ void proto_register_ldap(void) {
&ett_ldap_ExtendedResponse,
/*--- End of included file: packet-ldap-ettarr.c ---*/
-#line 1620 "packet-ldap-template.c"
+#line 1607 "packet-ldap-template.c"
};
module_t *ldap_module;
@@ -4302,7 +4289,7 @@ void proto_register_ldap(void) {
proto_register_subtree_array(ett, array_length(ett));
- register_dissector("ldap", dissect_ldap, proto_ldap);
+ register_dissector("ldap", dissect_ldap_tcp, proto_ldap);
ldap_module = prefs_register_protocol(proto_ldap, NULL);
prefs_register_bool_preference(ldap_module, "desegment_ldap_messages",
@@ -4332,7 +4319,7 @@ void
proto_reg_handoff_ldap(void)
{
dissector_handle_t ldap_handle, cldap_handle;
- ldap_handle = create_dissector_handle(dissect_ldap, proto_ldap);
+ ldap_handle = create_dissector_handle(dissect_ldap_tcp, proto_ldap);
dissector_add("tcp.port", ldap_tcp_port, ldap_handle);
dissector_add("tcp.port", TCP_PORT_GLOBALCAT_LDAP, ldap_handle);