4b21e6aee67ca32a83c0304bdd2e0ba7c23b70ee
[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 DuBingyao <dubingyao@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 statur of friend" },
107         { 0x00b5,       "Get friend's statur 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 void
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         if (check_col(pinfo->cinfo, COL_PROTOCOL))
124                 col_set_str(pinfo->cinfo, COL_PROTOCOL, "OICQ");
125
126         if (check_col(pinfo->cinfo, COL_INFO))
127         {
128                 col_clear(pinfo->cinfo, COL_INFO);
129                 col_set_str(pinfo->cinfo, COL_INFO, "OICQ Protocol ");
130                 
131         }
132
133
134         if (tree) {
135                 ti = proto_tree_add_item(tree, proto_oicq, tvb, 0, -1, FALSE);
136                 oicq_tree = proto_item_add_subtree(ti, ett_oicq);
137
138                 proto_tree_add_item(oicq_tree, hf_oicq_flag, tvb, offset, 1, FALSE);
139                 offset += 1;
140                 
141                 proto_tree_add_item(oicq_tree, hf_oicq_version, tvb, offset, 2, FALSE);
142                 offset += 2;
143
144                 proto_tree_add_item(oicq_tree, hf_oicq_command, tvb, offset, 2, FALSE);
145                 offset += 2;
146
147
148                 proto_tree_add_item(oicq_tree, hf_oicq_seq, tvb, offset, 2, FALSE);
149                 offset += 2;
150
151                 proto_tree_add_item(oicq_tree, hf_oicq_qqid, tvb, offset, 4, FALSE);
152                 offset += 4;
153                 
154                 proto_tree_add_item(oicq_tree, hf_oicq_data, tvb, offset, -1, FALSE);
155                 
156                 
157         }
158 }
159
160 void
161 proto_register_oicq(void)
162 {
163         static hf_register_info hf[] = {
164                 { &hf_oicq_flag, {
165                         "Flag", "oicq.flag", FT_UINT8, BASE_HEX,
166                         VALS(oicq_flag_vals), 0, "Protocol Flag", HFILL }},
167                 { &hf_oicq_version, {
168                         "Version", "oicq.version", FT_UINT16, BASE_HEX,
169                         NULL, 0, "Version-zz", HFILL }},
170                 { &hf_oicq_command, {
171                         "Command", "oicq.command", FT_UINT16, BASE_DEC,
172                         VALS(oicq_command_vals), 0, "Command", HFILL }},
173                 { &hf_oicq_seq, {
174                         "Sequence", "oicq.seq", FT_UINT16, BASE_DEC,
175                         NULL, 0, "Sequence", HFILL }},
176                 { &hf_oicq_qqid, {
177                         "Data(OICQ Number,if sender is client)", "oicq.qqid", FT_UINT32, BASE_DEC,
178                         NULL, 0, "", HFILL }},
179                 { &hf_oicq_data, {
180                         "Data", "oicq.data", FT_STRING, 0,
181                         NULL, 0, "Data", HFILL }},
182         };
183         static gint *ett[] = {
184                 &ett_oicq,
185         };
186
187         proto_oicq = proto_register_protocol("OICQ - IM software, popular in China", "OICQ",
188             "oicq");
189         proto_register_field_array(proto_oicq, hf, array_length(hf));
190         proto_register_subtree_array(ett, array_length(ett));
191 }
192
193 void
194 proto_reg_handoff_oicq(void)
195 {
196         dissector_handle_t oicq_handle;
197
198         oicq_handle = create_dissector_handle(dissect_oicq, proto_oicq);
199         dissector_add("udp.port", UDP_PORT_OICQ, oicq_handle);
200 }
201