Coverage Report

Created: 2026-05-14 06:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
 */