Provide a way by which protocols that run atop HTTP, such as IPP, can

register their port as being for XXX-over-HTTP; the HTTP dissector
registers that port in the "tcp.port" table as an HTTP port, and
registers it in its *own* table with the dissector and protocol provided
to it.

Parse the HTTP MIME headers regardless of whether we're building a
protocol tree or not; we have to do so in order to find the offset of
the payload, to hand to an XXX-over-HTTP dissector.

svn path=/trunk/; revision=2872
This commit is contained in:
Guy Harris 2001-01-11 06:30:54 +00:00
parent 8470a8e9a1
commit b7a0290c66
4 changed files with 167 additions and 136 deletions

View File

@ -1,7 +1,7 @@
# Makefile.am
# Automake file for Ethereal
#
# $Id: Makefile.am,v 1.271 2001/01/11 05:41:47 guy Exp $
# $Id: Makefile.am,v 1.272 2001/01/11 06:30:54 guy Exp $
#
# Ethereal - Network traffic analyzer
# By Gerald Combs <gerald@zing.org>
@ -206,6 +206,7 @@ noinst_HEADERS = \
packet-frame.h \
packet-gvrp.h \
packet-h261.h \
packet-http.h \
packet-ieee80211.h \
packet-ip.h \
packet-ipsec.h \

View File

@ -3,7 +3,7 @@
*
* Guy Harris <guy@alum.mit.edu>
*
* $Id: packet-http.c,v 1.35 2001/01/11 05:41:47 guy Exp $
* $Id: packet-http.c,v 1.36 2001/01/11 06:30:54 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -42,6 +42,8 @@
#include "packet.h"
#include "strutil.h"
#include "packet-http.h"
typedef enum _http_type {
HTTP_REQUEST,
HTTP_RESPONSE,
@ -62,12 +64,7 @@ static gint ett_http = -1;
#define TCP_ALT_PORT_HTTP 8080
/*
* IPP is encapsulated in HTTP.
*/
#define TCP_PORT_IPP 631
/*
* So is SSDP (yes, it really *does* run over UDP).
* SSDP is implemented atop HTTP (yes, it really *does* run over UDP).
*/
#define TCP_PORT_SSDP 1900
#define UDP_PORT_SSDP 1900
@ -77,13 +74,12 @@ static gint ett_http = -1;
*/
typedef enum {
PROTO_HTTP, /* just HTTP */
PROTO_IPP, /* Internet Printing Protocol */
PROTO_SSDP /* Simple Service Discovery Protocol */
} http_proto_t;
static int is_http_request_or_reply(const u_char *data, int linelen, http_type_t *type);
static dissector_handle_t ipp_handle;
static dissector_table_t subdissector_table;
static void
dissect_http(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
@ -107,11 +103,6 @@ dissect_http(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
switch (pinfo->match_port) {
case TCP_PORT_IPP:
proto = PROTO_IPP;
proto_tag = "IPP";
break;
case TCP_PORT_SSDP: /* TCP_PORT_SSDP = UDP_PORT_SSDP */
proto = PROTO_SSDP;
proto_tag = "SSDP";
@ -146,101 +137,101 @@ dissect_http(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
ti = proto_tree_add_item(tree, proto_http, tvb, offset,
tvb_length_remaining(tvb, offset), FALSE);
http_tree = proto_item_add_subtree(ti, ett_http);
}
/*
* Process the packet data, a line at a time.
*/
http_type = HTTP_OTHERS; /* type not known yet */
while (tvb_offset_exists(tvb, offset)) {
/*
* Find the end of the line.
*/
linelen = tvb_find_line_end(tvb, offset, -1, &next_offset);
/*
* Process the packet data, a line at a time.
* Get a buffer that refers to the line.
*/
http_type = HTTP_OTHERS; /* type not known yet */
while (tvb_offset_exists(tvb, offset)) {
/*
* Find the end of the line.
*/
linelen = tvb_find_line_end(tvb, offset, -1,
&next_offset);
line = tvb_get_ptr(tvb, offset, linelen);
lineend = line + linelen;
/*
* Get a buffer that refers to the line.
*/
line = tvb_get_ptr(tvb, offset, linelen);
lineend = line + linelen;
/*
* OK, does it look like an HTTP request or response?
*/
if (is_http_request_or_reply(line, linelen, &http_type))
goto is_http;
/*
* OK, does it look like an HTTP request or
* response?
*/
if (is_http_request_or_reply(line, linelen, &http_type))
/*
* No. Does it look like a blank line (as would appear
* at the end of an HTTP request)?
*/
if (linelen == 0)
goto is_http;
/*
* No. Does it look like a MIME header?
*/
linep = line;
while (linep < lineend) {
c = *linep++;
if (!isprint(c))
break; /* not printable, not a MIME header */
switch (c) {
case '(':
case ')':
case '<':
case '>':
case '@':
case ',':
case ';':
case '\\':
case '"':
case '/':
case '[':
case ']':
case '?':
case '=':
case '{':
case '}':
/*
* It's a tspecial, so it's not part of a
* token, so it's not a field name for the
* beginning of a MIME header.
*/
goto not_http;
case ':':
/*
* This ends the token; we consider this
* to be a MIME header.
*/
goto is_http;
/*
* No. Does it look like a blank line (as would
* appear at the end of an HTTP request)?
*/
if (linelen == 0)
goto is_http;
/*
* No. Does it look like a MIME header?
*/
linep = line;
while (linep < lineend) {
c = *linep++;
if (!isprint(c))
break; /* not printable, not a MIME header */
switch (c) {
case '(':
case ')':
case '<':
case '>':
case '@':
case ',':
case ';':
case '\\':
case '"':
case '/':
case '[':
case ']':
case '?':
case '=':
case '{':
case '}':
/*
* It's a tspecial, so it's not
* part of a token, so it's not
* a field name for the beginning
* of a MIME header.
*/
goto not_http;
case ':':
/*
* This ends the token; we consider
* this to be a MIME header.
*/
goto is_http;
}
}
}
not_http:
/*
* We don't consider this part of an HTTP request or
* reply, so we don't display it.
* (Yeah, that means we don't display, say, a
* text/http page, but you can get that from the
* data pane.)
*/
break;
not_http:
/*
* We don't consider this part of an HTTP request or
* reply, so we don't display it.
* (Yeah, that means we don't display, say, a text/http
* page, but you can get that from the data pane.)
*/
break;
is_http:
/*
* Put this line.
*/
is_http:
/*
* Put this line.
*/
if (tree) {
proto_tree_add_text(http_tree, tvb, offset,
next_offset - offset, "%s",
tvb_format_text(tvb, offset, next_offset - offset));
offset = next_offset;
}
offset = next_offset;
}
if (tree) {
switch (http_type) {
case HTTP_NOTIFICATION:
@ -266,17 +257,20 @@ dissect_http(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
datalen = tvb_length_remaining(tvb, offset);
if (datalen > 0) {
if (proto == PROTO_IPP) {
tvbuff_t *new_tvb = tvb_new_subset(tvb, offset, -1, -1);
tvbuff_t *next_tvb = tvb_new_subset(tvb, offset, -1, -1);
/*
* OK, has some subdissector asked that they be called
* if something was on some particular port?
*/
if (dissector_try_port(subdissector_table, pinfo->match_port,
next_tvb, pinfo, tree)) {
/*
* Fix up the top-level item so that it doesn't
* include the IPP stuff.
* Yes. Fix up the top-level item so that it
* doesn't include the stuff for that protocol.
*/
if (ti != NULL)
proto_item_set_len(ti, offset);
call_dissector(ipp_handle, new_tvb, pinfo, tree);
} else
dissect_data(tvb, offset, pinfo, http_tree);
}
@ -398,6 +392,35 @@ proto_register_http(void)
"HTTP", "http");
proto_register_field_array(proto_http, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
/*
* Dissectors shouldn't register themselves in this table;
* instead, they should call "http_dissector_add()", and
* we'll register the port number they specify as a port
* for HTTP, and register them in our subdissector table.
*
* This only works for protocols such as IPP that run over
* HTTP on a specific non-HTTP port.
*/
subdissector_table = register_dissector_table("http.port");
}
/*
* Called by dissectors for protocols that run atop HTTP/TCP.
*/
void
http_dissector_add(guint32 port, dissector_t dissector, int proto)
{
/*
* Register ourselves as the handler for that port number
* over TCP.
*/
dissector_add("tcp.port", port, dissect_http, proto_http);
/*
* And register them in *our* table for that port.
*/
dissector_add("http.port", port, dissector, proto);
}
void
@ -410,35 +433,10 @@ proto_reg_handoff_http(void)
dissector_add("tcp.port", TCP_PORT_PROXY_ADMIN_HTTP, dissect_http,
proto_http);
/*
* XXX - this is a bit ugly; we probably really want to have
* protocols based atop HTTP call a routine to register
* themselves with the HTTP dissector, giving an optional
* port number (if the port number is "missing", e.g. -1 or 0,
* the protocol would be assumed to use a standard HTTP port),
* and an optional Content-Type: value (or some other way for
* the dissector to tell what the next protocol is).
*
* The HTTP dissector would register itself for the port in
* question (if it's not missing), and would use either the
* port number or the Content-Type: (or whatever) value to
* determine whether to hand the payload to that dissector.
*
* It would also pass a protocol number, so we could arrange
* that the HTTP part of an IPP packet be dissected iff HTTP
* is enabled, and the IPP part be dissected iff IPP is enabled.
*/
dissector_add("tcp.port", TCP_PORT_IPP, dissect_http, proto_http);
/*
* XXX - is there anything to dissect in the body of an SSDP
* request or reply? I.e., should there be an SSDP dissector?
*/
dissector_add("tcp.port", TCP_PORT_SSDP, dissect_http, proto_http);
dissector_add("udp.port", UDP_PORT_SSDP, dissect_http, proto_http);
/*
* Get a handle for the IPP dissector.
*/
ipp_handle = find_dissector("ipp");
}

30
packet-http.h Normal file
View File

@ -0,0 +1,30 @@
/* packet-http.h
*
* $Id: packet-http.h,v 1.5 2001/01/11 06:30:54 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
* Copyright 1998 Gerald Combs
*
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __PACKET_HTTP_H__
#define __PACKET_HTTP_H__
void http_dissector_add(guint32 port, dissector_t dissector, int proto);
#endif

View File

@ -3,7 +3,7 @@
*
* Guy Harris <guy@alum.mit.edu>
*
* $Id: packet-ipp.c,v 1.21 2001/01/11 05:41:47 guy Exp $
* $Id: packet-ipp.c,v 1.22 2001/01/11 06:30:54 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -41,6 +41,7 @@
#include <glib.h>
#include "packet.h"
#include "strutil.h"
#include "packet-http.h"
static int proto_ipp = -1;
@ -559,12 +560,13 @@ proto_register_ipp(void)
"IPP", "ipp");
/* proto_register_field_array(proto_ipp, hf, array_length(hf));*/
proto_register_subtree_array(ett, array_length(ett));
/*
* Register the dissector by name, so other dissectors can
* grab it by name rather than just referring to it directly
* (you can't refer to it directly from a plugin dissector
* on Windows without stuffing it into the Big Transfer Vector).
*/
register_dissector("ipp", dissect_ipp, proto_ipp);
}
void
proto_reg_handoff_ipp(void)
{
/*
* Register ourselves as running atop HTTP and using port 631.
*/
http_dissector_add(631, dissect_ipp, proto_ipp);
}