To quote section "7.2.1 Type" of RFC 2068, "Hypertext Transfer Protocol
authorguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>
Tue, 14 Feb 2012 06:00:14 +0000 (06:00 +0000)
committerguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>
Tue, 14 Feb 2012 06:00:14 +0000 (06:00 +0000)
-- HTTP/1.1":

   Any HTTP/1.1 message containing an entity-body SHOULD include a
   Content-Type header field defining the media type of that body. If
   and only if the media type is not given by a Content-Type field, the
   recipient MAY attempt to guess the media type via inspection of its
   content and/or the name extension(s) of the URL used to identify the
   resource. If the media type remains unknown, the recipient SHOULD
   treat it as type "application/octet-stream".

To quote section "4. Encoding of Transport Layer" of RFC 2565, "Internet
Printing Protocol/1.0: Encoding and Transport":

   HTTP/1.1 [RFC2068] is the transport layer for this protocol.

...

   Note: even though port 631 is the IPP default, port 80 remains the
   default for an HTTP URI.  Thus a URI for a printer using port 631
   MUST contain an explicit port, e.g. "http://forest:631/pinetree".  An
   HTTP URI for IPP with no explicit port implicitly reference port 80,
   which is consistent with the rules for HTTP/1.1. Each HTTP operation
   MUST use the POST method where the request-URI is the object target
   of the operation, and where the "Content-Type" of the message-body in
   each request and response MUST be "application/ipp". The message-body
   MUST contain the operation layer and MUST have the syntax described
   in section 3.2 "Syntax of Encoding". A client implementation MUST
   adhere to the rules for a client described for HTTP1.1 [RFC2068]. A
   printer (server) implementation MUST adhere the rules for an origin
   server described for HTTP1.1 [RFC2068].

So, when choosing a subdissector for HTTP request bodies, search based
on the media type first, and only if we *don't* find a dissector for the
media type, do other stuff such as heuristics or choosing a subdissector
based on the port number.

This fixes a number of problems; in particular, it fixes bug 6765
"non-IPP packets to or from port 631 are dissected as IPP" without
requiring the IPP dissector to attempt to determine whether an entity
body looks like IPP.  It also ensures that the default dissector for
HTTP entity bodies, the "media" dissector, will get the media type
passed to it in pinfo->match_string.

Don't use "!str*cmp()" while we're at it - it's valid C, but the "!" can
make it look as if it's checking for something not being the case when,
in fact, you're checking for equality rather than inequality.  (The
str*cmp() routines don't return Boolean results.)

git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@41025 f5534014-38df-0310-8fa8-9805f1628bb7

epan/dissectors/packet-http.c

index faba3d305a23799004914398aded144c8ca4afc0..cea297868f9faa9e005f3a81d4e262ba4221e9da 100644 (file)
@@ -1193,13 +1193,11 @@ dissect_http_message(tvbuff_t *tvb, int offset, packet_info *pinfo,
                /*
                 * Do subdissector checks.
                 *
-                * First, check whether some subdissector asked that they
-                * be called if something was on some particular port.
+                * First, if we have a Content-Type value, check whether
+                * there's a subdissector for that media type.
                 */
-
-               handle = dissector_get_uint_handle(port_subdissector_table,
-                   pinfo->match_uint);
-               if (handle == NULL && headers.content_type != NULL) {
+               handle = NULL;
+               if (headers.content_type != NULL) {
                        /*
                         * We didn't find any subdissector that
                         * registered for the port, and we have a
@@ -1223,7 +1221,7 @@ dissect_http_message(tvbuff_t *tvb, int offset, packet_info *pinfo,
                            media_type_subdissector_table,
                            headers.content_type);
                        if (handle == NULL &&
-                           !strncmp(headers.content_type, "multipart/", sizeof("multipart/")-1)) {
+                           strncmp(headers.content_type, "multipart/", sizeof("multipart/")-1) == 0) {
                                /* Try to decode the unknown multipart subtype anyway */
                                handle = dissector_get_string_handle(
                                    media_type_subdissector_table,
@@ -1231,6 +1229,18 @@ dissect_http_message(tvbuff_t *tvb, int offset, packet_info *pinfo,
                        }
                }
 
+               /*
+                * Now, if we didn't find such a subdissector, check
+                * whether some subdissector asked that they be called
+                * if HTTP traffic was on some particular port.  This
+                * handles protocols that use HTTP syntax but don't have
+                * a media type and instead use a specified port.
+                */
+               if (handle == NULL) {
+                       handle = dissector_get_uint_handle(port_subdissector_table,
+                           pinfo->match_uint);
+               }
+
                if (handle != NULL) {
                        /*
                         * We have a subdissector - call it.