Add a inflateEnd() call to free up the stream in the re-init block.
[obnox/wireshark/wip.git] / epan / dissectors / packet-irc.c
1 /* packet-irc.c
2  * Routines for IRC packet dissection
3  *
4  * See
5  *
6  *      http://www.irchelp.org/irchelp/rfc/
7  *
8  * and the RFCs and other documents it mentions, such as RFC 1459, RFCs
9  * 2810, 2811, 2812, and 2813,
10  *
11  *      http://www.irchelp.org/irchelp/rfc/ctcpspec.html
12  *
13  * and
14  *
15  *      http://www.invlogic.com/irc/ctcp.html
16  *
17  * $Id$
18  *
19  * Wireshark - Network traffic analyzer
20  * By Gerald Combs <gerald@wireshark.org>
21  * Copyright 1998 Gerald Combs
22  *
23  * Copied from packet-tftp.c
24  *
25  * This program is free software; you can redistribute it and/or
26  * modify it under the terms of the GNU General Public License
27  * as published by the Free Software Foundation; either version 2
28  * of the License, or (at your option) any later version.
29  *
30  * This program is distributed in the hope that it will be useful,
31  * but WITHOUT ANY WARRANTY; without even the implied warranty of
32  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
33  * GNU General Public License for more details.
34  *
35  * You should have received a copy of the GNU General Public License
36  * along with this program; if not, write to the Free Software
37  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
38  */
39
40 #ifdef HAVE_CONFIG_H
41 # include "config.h"
42 #endif
43
44 #include <stdio.h>
45
46 #include <string.h>
47 #include <glib.h>
48 #include <epan/packet.h>
49
50 static int proto_irc = -1;
51 static int hf_irc_request = -1;
52 static int hf_irc_response = -1;
53
54 static gint ett_irc = -1;
55
56 #define TCP_PORT_IRC                    6667
57         /* good candidate for dynamic port specification */
58
59 static void
60 dissect_irc_request(proto_tree *tree, tvbuff_t *tvb, int offset, int linelen)
61 {
62         proto_tree_add_item(tree, hf_irc_request, tvb, offset, linelen, TRUE);
63 }
64
65 static void
66 dissect_irc_response(proto_tree *tree, tvbuff_t *tvb, int offset, int linelen)
67 {
68         proto_tree_add_item(tree, hf_irc_response, tvb, offset, linelen, TRUE);
69 }
70
71 static void
72 dissect_irc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
73 {
74         proto_tree      *irc_tree, *ti;
75         gint            offset = 0;
76         gint            next_offset;
77         int             linelen;
78
79         if (check_col(pinfo->cinfo, COL_PROTOCOL))
80                 col_set_str(pinfo->cinfo, COL_PROTOCOL, "IRC");
81
82         if (check_col(pinfo->cinfo, COL_INFO))
83         {
84                 col_set_str(pinfo->cinfo, COL_INFO,
85                     (pinfo->match_port == pinfo->destport) ? "Request" : "Response");
86         }
87
88         if (tree)
89         {
90                 ti = proto_tree_add_item(tree, proto_irc, tvb, 0, -1, FALSE);
91                 irc_tree = proto_item_add_subtree(ti, ett_irc);
92
93                 /*
94                  * Process the packet data, a line at a time.
95                  */
96                 while (tvb_reported_length_remaining(tvb, offset) > 0)
97                 {
98                         /*
99                          * Find the end of the line.
100                          */
101                         linelen = tvb_find_line_end(tvb, offset, -1, &next_offset, FALSE);
102                         if (next_offset == offset) {
103                                 /*
104                                  * XXX - we really want the "show data a
105                                  * line at a time" loops in various
106                                  * dissectors to do reassembly and to
107                                  * throw an exception if there's no
108                                  * line ending in the current packet
109                                  * and we're not doing reassembly.
110                                  */
111                                 break;
112                         }
113
114                         if (linelen != 0)
115                         {
116                                 if (pinfo->match_port == pinfo->destport)
117                                 {
118                                         dissect_irc_request(irc_tree, tvb, offset, linelen);
119                                 }
120                                 else
121                                 {
122                                         dissect_irc_response(irc_tree, tvb, offset, linelen);
123                                 }
124                         }
125                         offset = next_offset;
126                 }
127         }
128 }
129
130 void
131 proto_register_irc(void)
132 {
133         static hf_register_info hf[] = {
134           { &hf_irc_response,
135             { "Response",           "irc.response",
136               FT_STRING, BASE_NONE, NULL, 0x0,
137               "Line of response message", HFILL }},
138
139           { &hf_irc_request,
140             { "Request",            "irc.request",
141               FT_STRING, BASE_NONE, NULL, 0x0,
142               "Line of request message", HFILL }},
143         };
144
145         static gint *ett[] = {
146                 &ett_irc,
147         };
148         proto_irc = proto_register_protocol("Internet Relay Chat", "IRC", "irc");
149         proto_register_field_array(proto_irc, hf, array_length(hf));
150         proto_register_subtree_array(ett, array_length(ett));
151 }
152
153 void
154 proto_reg_handoff_irc(void)
155 {
156         dissector_handle_t irc_handle;
157
158         irc_handle = create_dissector_handle(dissect_irc, proto_irc);
159         dissector_add("tcp.port", TCP_PORT_IRC, irc_handle);
160 }