Added support for Router-Alert IP option (RFC2113)
[obnox/wireshark/wip.git] / packet-irc.c
1 /* packet-irc.c
2  * Routines for MSX irc packet dissection
3  *
4  * $Id: packet-irc.c,v 1.9 2000/11/19 08:53:58 guy Exp $
5  *
6  * Ethereal - Network traffic analyzer
7  * By Gerald Combs <gerald@zing.org>
8  * Copyright 1998 Gerald Combs
9  *
10  * Copied from packet-tftp.c
11  * 
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License
14  * as published by the Free Software Foundation; either version 2
15  * of the License, or (at your option) any later version.
16  * 
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  * 
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
25  */
26
27 #ifdef HAVE_CONFIG_H
28 # include "config.h"
29 #endif
30
31 #include <stdio.h>
32
33 #ifdef HAVE_SYS_TYPES_H
34 # include <sys/types.h>
35 #endif
36
37 #ifdef HAVE_NETINET_IN_H
38 # include <netinet/in.h>
39 #endif
40
41 #include <string.h>
42 #include <glib.h>
43 #include "packet.h"
44
45 static int proto_irc = -1;
46 static int hf_irc_request = -1;
47 static int hf_irc_response = -1;
48 static int hf_irc_command = -1;
49
50 static gint ett_irc = -1;
51
52 #define TCP_PORT_IRC                    6667
53         /* good candidate for dynamic port specification */
54
55 static void
56 dissect_irc_request(proto_tree *tree, char *line, int offset, int len)
57 {
58         proto_tree_add_boolean_hidden(tree, hf_irc_request, NullTVB,
59                 offset, len, TRUE);
60         proto_tree_add_text(tree, NullTVB, offset, 
61                 len, "Request Line: %s", line);
62 }
63
64 static void
65 dissect_irc_response(proto_tree *tree, char *line, int offset, int len)
66 {
67         proto_tree_add_boolean_hidden(tree, hf_irc_response, NullTVB,
68                 offset, len, TRUE);
69         proto_tree_add_text(tree, NullTVB, offset, 
70                 len, "Response Line: %s", line);
71 }
72
73 static void
74 dissect_irc(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
75 {
76         proto_tree      *irc_tree, *ti;
77         char *tmpline;
78         int start, cur, len;
79         const u_char *i;
80
81         OLD_CHECK_DISPLAY_AS_DATA(proto_irc, pd, offset, fd, tree);
82
83         if (check_col(fd, COL_PROTOCOL))
84         col_set_str(fd, COL_PROTOCOL, "IRC");
85
86         if (check_col(fd, COL_INFO))
87         {
88                 col_add_fstr(fd, COL_INFO, "%s", 
89                         (pi.match_port == pi.destport) ? "Request" : "Response");         
90         }
91
92         if (tree) 
93         {
94                 ti = proto_tree_add_item(tree, proto_irc, NullTVB, offset, END_OF_FRAME, FALSE);
95                 irc_tree = proto_item_add_subtree(ti, ett_irc);
96
97                 tmpline = (char *)g_malloc( pi.captured_len );
98                 i = pd+offset;
99                 while ( i < pd + pi.captured_len )
100                 {
101                         start = i - pd;
102                         cur = 0;
103                         len = 0;
104                         tmpline[cur] = 0;
105
106                         /* copy up to end or cr/nl */
107                         while ( i < pd + pi.captured_len && *i != '\r' && *i != '\n' )
108                         {
109                                 tmpline[cur++] = *(i++);
110                                 len++;
111                         }
112                         tmpline[cur] = 0;
113
114                         /* skip any CR/NL */
115                         while ( i < pd + pi.captured_len && 
116                                 (*i == '\r' || *i == '\n') )
117                         {
118                                 i++;
119                                 len++;
120                         }
121
122                         if ( strlen(tmpline) > 0 )
123                         {
124                                 if (pi.match_port == pi.destport)
125                                 {
126                                         dissect_irc_request(irc_tree, tmpline, start, len);
127                                 }
128                                 else
129                                 {
130                                         dissect_irc_response(irc_tree, tmpline, start, len);
131                                 }
132                         }
133                 }
134                 g_free(tmpline);
135                 tmpline = 0;
136         }
137 }
138
139 void
140 proto_register_irc(void)
141 {
142         static hf_register_info hf[] = {
143           { &hf_irc_response,
144             { "Response",           "irc.response",
145               FT_BOOLEAN, BASE_NONE, NULL, 0x0,
146               "TRUE if IRC response" }},
147           
148           { &hf_irc_request,
149             { "Request",            "irc.request",
150               FT_BOOLEAN, BASE_NONE, NULL, 0x0,
151               "TRUE if IRC request" }},
152
153           { &hf_irc_command,
154             { "Command",            "irc.command",
155               FT_STRING, BASE_NONE, NULL, 0x0,
156               "Command associated with request" }}
157         };
158
159         static gint *ett[] = {
160                 &ett_irc,
161         };
162         proto_irc = proto_register_protocol("Internet Relay Chat", "irc");
163         proto_register_field_array(proto_irc, hf, array_length(hf));
164         proto_register_subtree_array(ett, array_length(ett));
165 }
166
167 void
168 proto_reg_handoff_irc(void)
169 {
170         old_dissector_add("tcp.port", TCP_PORT_IRC, dissect_irc);
171 }
172