69712815d37642402761fa02201d3a6e1e1e92d3
[obnox/wireshark/wip.git] / epan / dissectors / packet-oicq.c
1 /* packet-oicq.c
2  * Routines for OICQ - IM software,popular in China - packet dissection
3  * (c) Copyright Secfire <secfire@gmail.com>
4  *
5  * $Id$
6  *
7  * OICQ is an IM software,which is popular in China. And,
8  * OICQ has more than 10 millions users at present.
9  * The Protocol showed in this file, is found by investigating OICQ's 
10  * Packets  as a black box.
11  *
12  * The OICQ client software is always changing,and the protocol of 
13  * communication is also.
14  *
15  * Wireshark - Network traffic analyzer
16  * By Gerald Combs <gerald@wireshark.org>
17  * Copyright 1998 Gerald Combs
18  *
19  * This program is free software; you can redistribute it and/or
20  * modify it under the terms of the GNU General Public License
21  * as published by the Free Software Foundation; either version 2
22  * of the License, or (at your option) any later version.
23  *
24  * This program is distributed in the hope that it will be useful,
25  * but WITHOUT ANY WARRANTY; without even the implied warranty of
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
27  * GNU General Public License for more details.
28  *
29  * You should have received a copy of the GNU General Public License
30  * along with this program; if not, write to the Free Software
31  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
32  */
33
34 #ifdef HAVE_CONFIG_H
35 # include "config.h"
36 #endif
37
38 #include <glib.h>
39
40 #include <epan/packet.h>
41
42 /*
43         Protocol Flag:     8bit unsigned
44         Sender Flag:       16bit unsigned
45         Command Number:    16bit unsigned
46         Sequence Number:   16bit unsigned
47         OICQ  Number:      32bit unsigned
48         Data:              Variable Length data
49         
50  *
51  */
52
53 /* By default, but can be completely different */
54 #define UDP_PORT_OICQ   8000
55
56 static int proto_oicq = -1;
57
58 static int hf_oicq_flag = -1;
59 static int hf_oicq_version = -1;
60 static int hf_oicq_command = -1;
61 static int hf_oicq_seq = -1;
62 static int hf_oicq_qqid = -1;
63 static int hf_oicq_data = -1;
64
65
66 static gint ett_oicq = -1;
67
68 static const value_string oicq_flag_vals[] = {
69         { 0x02, "Oicq packet" },
70         { 0,                    NULL }
71 };
72
73 static const value_string oicq_command_vals[] = {
74         { 0x0001,       "Log out" },
75         { 0x0002,       "Heart Message" },
76         { 0x0004,       "Update User information" },
77         { 0x0005,       "Search user" },
78         { 0x0006,       "Get User informationBroadcast" },
79         { 0x0009,       "Add friend no auth" },
80         { 0x000a,       "Delete user" },
81         { 0x000b,       "Add friend by auth" },
82         { 0x000d,       "Set status" },
83         { 0x0012,       "Confirmation of receiving message from server" },
84         { 0x0016,       "Send message" },
85         { 0x0017,       "Receive message" },
86         { 0x0018,       "Retrieve information" },
87         { 0x001a,       "Reserved " },
88         { 0x001c,       "Delete Me" },
89         { 0x001d,       "Request KEY" },
90         { 0x0021,       "Cell Phone" },
91         { 0x0022,       "Log in" },
92         { 0x0026,       "Get friend list" },
93         { 0x0027,       "Get friend online" },
94         { 0x0029,       "Cell PHONE" },
95         { 0x0030,       "Operation on group" },
96         { 0x0031,       "Log in test" },
97         { 0x003c,       "Group name operation" },
98         { 0x003d,       "Upload group friend" },
99         { 0x003e,       "MEMO Operation" },
100         { 0x0058,       "Download group friend" },
101         { 0x005c,       "Get level" },
102         { 0x0062,       "Request login" },
103         { 0x0065,       "Request extra information" },
104         { 0x0067,       "Signature operation" },
105         { 0x0080,       "Receive system message" },
106         { 0x0081,       "Get status of friend" },
107         { 0x00b5,       "Get friend's status of group" },
108         { 0,                    NULL }
109 };
110
111 /* dissect_oicq - dissects oicq packet data
112  * tvb - tvbuff for packet data (IN)
113  * pinfo - packet info
114  * proto_tree - resolved protocol tree
115  */
116 static int
117 dissect_oicq(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
118 {
119         proto_tree      *oicq_tree;
120         proto_item      *ti;
121         int offset = 0;
122
123         /* Make sure this packet is for us.                                  */
124         /* heuristic: OICQ iff (([0] == STX) && ([3/4] == <valid_command>) ) */
125         /*  (Supposedly each OICQ message ends with an ETX so a test for     */
126         /*   same could also be part of the heuristic).                      */
127         if ( (match_strval(tvb_get_guint8(tvb, 0), oicq_flag_vals)    == NULL) ||
128              (match_strval(tvb_get_ntohs(tvb, 3),  oicq_command_vals) == NULL) )
129                 return 0;
130
131         col_set_str(pinfo->cinfo, COL_PROTOCOL, "OICQ");
132
133         if (check_col(pinfo->cinfo, COL_INFO))
134         {
135                 col_set_str(pinfo->cinfo, COL_INFO, "OICQ Protocol ");
136                 
137         }
138
139
140         if (tree) {
141                 ti = proto_tree_add_item(tree, proto_oicq, tvb, 0, -1, FALSE);
142                 oicq_tree = proto_item_add_subtree(ti, ett_oicq);
143
144                 proto_tree_add_item(oicq_tree, hf_oicq_flag, tvb, offset, 1, FALSE);
145                 offset += 1;
146                 
147                 proto_tree_add_item(oicq_tree, hf_oicq_version, tvb, offset, 2, FALSE);
148                 offset += 2;
149
150                 proto_tree_add_item(oicq_tree, hf_oicq_command, tvb, offset, 2, FALSE);
151                 offset += 2;
152
153
154                 proto_tree_add_item(oicq_tree, hf_oicq_seq, tvb, offset, 2, FALSE);
155                 offset += 2;
156
157                 proto_tree_add_item(oicq_tree, hf_oicq_qqid, tvb, offset, 4, FALSE);
158                 offset += 4;
159                 
160                 proto_tree_add_item(oicq_tree, hf_oicq_data, tvb, offset, -1, FALSE);
161                 
162                 
163         }
164         
165         return tvb_length(tvb);
166 }
167
168 void
169 proto_register_oicq(void)
170 {
171         static hf_register_info hf[] = {
172                 { &hf_oicq_flag, {
173                         "Flag", "oicq.flag", FT_UINT8, BASE_HEX,
174                         VALS(oicq_flag_vals), 0, "Protocol Flag", HFILL }},
175                 { &hf_oicq_version, {
176                         "Version", "oicq.version", FT_UINT16, BASE_HEX,
177                         NULL, 0, "Version-zz", HFILL }},
178                 { &hf_oicq_command, {
179                         "Command", "oicq.command", FT_UINT16, BASE_DEC,
180                         VALS(oicq_command_vals), 0, NULL, HFILL }},
181                 { &hf_oicq_seq, {
182                         "Sequence", "oicq.seq", FT_UINT16, BASE_DEC,
183                         NULL, 0, NULL, HFILL }},
184                 { &hf_oicq_qqid, {
185                         "Data(OICQ Number,if sender is client)", "oicq.qqid", FT_UINT32, BASE_DEC,
186                         NULL, 0, NULL, HFILL }},
187                 { &hf_oicq_data, {
188                         "Data", "oicq.data", FT_STRING, BASE_NONE,
189                         NULL, 0, NULL, HFILL }},
190         };
191         static gint *ett[] = {
192                 &ett_oicq,
193         };
194
195         proto_oicq = proto_register_protocol("OICQ - IM software, popular in China", "OICQ",
196             "oicq");
197         proto_register_field_array(proto_oicq, hf, array_length(hf));
198         proto_register_subtree_array(ett, array_length(ett));
199 }
200
201 void
202 proto_reg_handoff_oicq(void)
203 {
204         dissector_handle_t oicq_handle;
205
206         oicq_handle = new_create_dissector_handle(dissect_oicq, proto_oicq);
207         dissector_add("udp.port", UDP_PORT_OICQ, oicq_handle);
208 }
209