/src/wireshark/epan/dissectors/packet-oicq.c
Line | Count | Source |
1 | | /* packet-oicq.c |
2 | | * Routines for OICQ - IM software,popular in China - packet dissection |
3 | | * (c) Copyright Secfire <secfire@gmail.com> |
4 | | * |
5 | | * OICQ is an IM software,which is popular in China. And, |
6 | | * OICQ has more than 10 millions users at present. |
7 | | * The Protocol showed in this file, is found by investigating OICQ's |
8 | | * Packets as a black box. |
9 | | * |
10 | | * The OICQ client software is always changing,and the protocol of |
11 | | * communication is also. |
12 | | * |
13 | | * Wireshark - Network traffic analyzer |
14 | | * By Gerald Combs <gerald@wireshark.org> |
15 | | * Copyright 1998 Gerald Combs |
16 | | * |
17 | | * SPDX-License-Identifier: GPL-2.0-or-later |
18 | | */ |
19 | | |
20 | | #include "config.h" |
21 | | |
22 | | #include <epan/packet.h> |
23 | | |
24 | | void proto_register_oicq(void); |
25 | | void proto_reg_handoff_oicq(void); |
26 | | |
27 | | static dissector_handle_t oicq_handle; |
28 | | |
29 | | /* |
30 | | Protocol Flag: 8bit unsigned |
31 | | Sender Flag: 16bit unsigned |
32 | | Command Number: 16bit unsigned |
33 | | Sequence Number: 16bit unsigned |
34 | | OICQ Number: 32bit unsigned |
35 | | Data: Variable Length data |
36 | | |
37 | | * |
38 | | */ |
39 | | |
40 | | /* By default, but can be completely different */ |
41 | 15 | #define UDP_PORT_OICQ 8000 /* Not IANA registered */ |
42 | | |
43 | | static int proto_oicq; |
44 | | |
45 | | static int hf_oicq_flag; |
46 | | static int hf_oicq_version; |
47 | | static int hf_oicq_command; |
48 | | static int hf_oicq_seq; |
49 | | static int hf_oicq_qqid; |
50 | | static int hf_oicq_data; |
51 | | |
52 | | |
53 | | static int ett_oicq; |
54 | | |
55 | | static const value_string oicq_flag_vals[] = { |
56 | | { 0x02, "Oicq packet" }, |
57 | | { 0, NULL } |
58 | | }; |
59 | | |
60 | | static const value_string oicq_command_vals[] = { |
61 | | { 0x0001, "Log out" }, |
62 | | { 0x0002, "Heart Message" }, |
63 | | { 0x0004, "Update User information" }, |
64 | | { 0x0005, "Search user" }, |
65 | | { 0x0006, "Get User informationBroadcast" }, |
66 | | { 0x0009, "Add friend no auth" }, |
67 | | { 0x000a, "Delete user" }, |
68 | | { 0x000b, "Add friend by auth" }, |
69 | | { 0x000d, "Set status" }, |
70 | | { 0x0012, "Confirmation of receiving message from server" }, |
71 | | { 0x0016, "Send message" }, |
72 | | { 0x0017, "Receive message" }, |
73 | | { 0x0018, "Retrieve information" }, |
74 | | { 0x001a, "Reserved " }, |
75 | | { 0x001c, "Delete Me" }, |
76 | | { 0x001d, "Request KEY" }, |
77 | | { 0x0021, "Cell Phone" }, |
78 | | { 0x0022, "Log in" }, |
79 | | { 0x0026, "Get friend list" }, |
80 | | { 0x0027, "Get friend online" }, |
81 | | { 0x0029, "Cell PHONE" }, |
82 | | { 0x0030, "Operation on group" }, |
83 | | { 0x0031, "Log in test" }, |
84 | | { 0x003c, "Group name operation" }, |
85 | | { 0x003d, "Upload group friend" }, |
86 | | { 0x003e, "MEMO Operation" }, |
87 | | { 0x0058, "Download group friend" }, |
88 | | { 0x005c, "Get level" }, |
89 | | { 0x0062, "Request login" }, |
90 | | { 0x0065, "Request extra information" }, |
91 | | { 0x0067, "Signature operation" }, |
92 | | { 0x0080, "Receive system message" }, |
93 | | { 0x0081, "Get status of friend" }, |
94 | | { 0x00b5, "Get friend's status of group" }, |
95 | | { 0x03f7, "Withdraw message" }, |
96 | | { 0, NULL } |
97 | | }; |
98 | | |
99 | | /* dissect_oicq - dissects oicq packet data |
100 | | * tvb - tvbuff for packet data (IN) |
101 | | * pinfo - packet info |
102 | | * proto_tree - resolved protocol tree |
103 | | */ |
104 | | static int |
105 | | dissect_oicq(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) |
106 | 3 | { |
107 | 3 | proto_tree *oicq_tree; |
108 | 3 | proto_item *ti; |
109 | 3 | int offset = 0; |
110 | | |
111 | | /* Make sure this packet is for us. */ |
112 | | /* heuristic: OICQ iff (([0] == STX) && ([3/4] == <valid_command>) ) */ |
113 | | /* (Supposedly each OICQ message ends with an ETX so a test for */ |
114 | | /* same could also be part of the heuristic). */ |
115 | 3 | if ( (try_val_to_str(tvb_get_uint8(tvb, 0), oicq_flag_vals) == NULL) || |
116 | 0 | (try_val_to_str(tvb_get_ntohs(tvb, 3), oicq_command_vals) == NULL) ) |
117 | 3 | return 0; |
118 | | |
119 | 0 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "OICQ"); |
120 | |
|
121 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "OICQ Protocol "); |
122 | | |
123 | |
|
124 | 0 | if (tree) { |
125 | 0 | ti = proto_tree_add_item(tree, proto_oicq, tvb, 0, -1, ENC_NA); |
126 | 0 | oicq_tree = proto_item_add_subtree(ti, ett_oicq); |
127 | |
|
128 | 0 | proto_tree_add_item(oicq_tree, hf_oicq_flag, tvb, offset, 1, ENC_BIG_ENDIAN); |
129 | 0 | offset += 1; |
130 | |
|
131 | 0 | proto_tree_add_item(oicq_tree, hf_oicq_version, tvb, offset, 2, ENC_BIG_ENDIAN); |
132 | 0 | offset += 2; |
133 | |
|
134 | 0 | proto_tree_add_item(oicq_tree, hf_oicq_command, tvb, offset, 2, ENC_BIG_ENDIAN); |
135 | 0 | offset += 2; |
136 | | |
137 | |
|
138 | 0 | proto_tree_add_item(oicq_tree, hf_oicq_seq, tvb, offset, 2, ENC_BIG_ENDIAN); |
139 | 0 | offset += 2; |
140 | |
|
141 | 0 | proto_tree_add_item(oicq_tree, hf_oicq_qqid, tvb, offset, 4, ENC_BIG_ENDIAN); |
142 | 0 | offset += 4; |
143 | |
|
144 | 0 | proto_tree_add_item(oicq_tree, hf_oicq_data, tvb, offset, -1, ENC_ASCII); |
145 | | |
146 | |
|
147 | 0 | } |
148 | |
|
149 | 0 | return tvb_captured_length(tvb); |
150 | 3 | } |
151 | | |
152 | | void |
153 | | proto_register_oicq(void) |
154 | 15 | { |
155 | 15 | static hf_register_info hf[] = { |
156 | 15 | { &hf_oicq_flag, { |
157 | 15 | "Flag", "oicq.flag", FT_UINT8, BASE_HEX, |
158 | 15 | VALS(oicq_flag_vals), 0, "Protocol Flag", HFILL }}, |
159 | 15 | { &hf_oicq_version, { |
160 | 15 | "Version", "oicq.version", FT_UINT16, BASE_HEX, |
161 | 15 | NULL, 0, "Version-zz", HFILL }}, |
162 | 15 | { &hf_oicq_command, { |
163 | 15 | "Command", "oicq.command", FT_UINT16, BASE_DEC, |
164 | 15 | VALS(oicq_command_vals), 0, NULL, HFILL }}, |
165 | 15 | { &hf_oicq_seq, { |
166 | 15 | "Sequence", "oicq.seq", FT_UINT16, BASE_DEC, |
167 | 15 | NULL, 0, NULL, HFILL }}, |
168 | 15 | { &hf_oicq_qqid, { |
169 | 15 | "Data(OICQ Number,if sender is client)", "oicq.qqid", FT_UINT32, BASE_DEC, |
170 | 15 | NULL, 0, NULL, HFILL }}, |
171 | 15 | { &hf_oicq_data, { |
172 | 15 | "Data", "oicq.data", FT_STRING, BASE_NONE, |
173 | 15 | NULL, 0, NULL, HFILL }}, |
174 | 15 | }; |
175 | 15 | static int *ett[] = { |
176 | 15 | &ett_oicq, |
177 | 15 | }; |
178 | | |
179 | 15 | proto_oicq = proto_register_protocol("OICQ - IM software, popular in China", "OICQ", "oicq"); |
180 | 15 | proto_register_field_array(proto_oicq, hf, array_length(hf)); |
181 | 15 | proto_register_subtree_array(ett, array_length(ett)); |
182 | | |
183 | 15 | oicq_handle = register_dissector("oicq", dissect_oicq, proto_oicq); |
184 | 15 | } |
185 | | |
186 | | void |
187 | | proto_reg_handoff_oicq(void) |
188 | 15 | { |
189 | 15 | dissector_add_uint_with_preference("udp.port", UDP_PORT_OICQ, oicq_handle); |
190 | 15 | } |
191 | | |
192 | | /* |
193 | | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
194 | | * |
195 | | * Local variables: |
196 | | * c-basic-offset: 8 |
197 | | * tab-width: 8 |
198 | | * indent-tabs-mode: t |
199 | | * End: |
200 | | * |
201 | | * vi: set shiftwidth=8 tabstop=8 noexpandtab: |
202 | | * :indentSize=8:tabSize=8:noTabs=false: |
203 | | */ |