Mercurial > pidgin
comparison libpurple/protocols/qq/packet_parse.c @ 23048:9a5d140400f1
patch-02-fix-multiarch
author | SHiNE CsyFeK <csyfek@gmail.com> |
---|---|
date | Tue, 24 Jun 2008 11:58:57 +0000 |
parents | 44b4e8bd759b |
children | 190bc4ecf6c3 |
comparison
equal
deleted
inserted
replaced
23046:13a9b56f83b0 | 23048:9a5d140400f1 |
---|---|
23 */ | 23 */ |
24 | 24 |
25 #include <string.h> | 25 #include <string.h> |
26 | 26 |
27 #include "packet_parse.h" | 27 #include "packet_parse.h" |
28 #include "debug.h" | |
29 | |
30 | |
31 /*------------------------------------------------PUT------------------------------------------------*/ | |
32 | |
33 /* note: | |
34 * 1, in these functions, 'b' stands for byte, 'w' stands for word, 'dw' stands for double word. | |
35 * 2, we use '*cursor' and 'buf' as two addresses to calculate the length. | |
36 * 3, fixed obscure bugs, thanks ccpaging. | |
37 * 4, change '0' to '1', if want to get more info about the packet parsing. | |
38 * by s3e, 20070717 */ | |
39 | |
40 #if 0 | |
41 #define PARSER_DEBUG | |
42 #endif | |
28 | 43 |
29 /* read one byte from buf, | 44 /* read one byte from buf, |
30 * return the number of bytes read if succeeds, otherwise return -1 */ | 45 * return the number of bytes read if succeeds, otherwise return -1 */ |
46 /* | |
31 gint read_packet_b(guint8 *buf, guint8 **cursor, gint buflen, guint8 *b) | 47 gint read_packet_b(guint8 *buf, guint8 **cursor, gint buflen, guint8 *b) |
32 { | 48 { |
49 guint8 *b_ship = NULL; | |
50 #ifdef PARSER_DEBUG | |
51 purple_debug(PURPLE_DEBUG_INFO, "QQ_DEBUGGER", | |
52 "[read_b] buf addr: 0x%x\n", (gpointer)buf); | |
53 #endif | |
33 if (*cursor <= buf + buflen - sizeof(*b)) { | 54 if (*cursor <= buf + buflen - sizeof(*b)) { |
34 *b = **(guint8 **) cursor; | 55 #ifdef PARSER_DEBUG |
56 purple_debug(PURPLE_DEBUG_INFO, "QQ_DEBUGGER", | |
57 "[read_b] *cursor addr: 0x%x, buf expected addr: 0x%x\n", | |
58 (gpointer)*cursor, (gpointer)(buf + buflen - sizeof(*b))); | |
59 #endif | |
60 b_ship = g_new0(guint8, sizeof(guint8)); | |
61 g_memmove(b_ship, *cursor, sizeof(guint8)); | |
62 *b = *b_ship; | |
63 #ifdef PARSER_DEBUG | |
64 purple_debug(PURPLE_DEBUG_INFO, "QQ_DEBUGGER", | |
65 "[read_b] data: 0x%02x->0x%02x\n", | |
66 **(guint8 **)cursor, *b); | |
67 #endif | |
35 *cursor += sizeof(*b); | 68 *cursor += sizeof(*b); |
69 // free | |
70 g_free(b_ship); | |
71 b_ship = NULL; | |
72 | |
36 return sizeof(*b); | 73 return sizeof(*b); |
37 } else { | 74 } else { |
38 return -1; | 75 return -1; |
39 } | 76 } |
40 } | 77 } |
78 */ | |
79 gint qq_get8(guint8 *b, guint8 *buf) | |
80 { | |
81 guint8 b_dest; | |
82 memcpy(&b_dest, buf, sizeof(b_dest)); | |
83 *b = b_dest; | |
84 purple_debug(PURPLE_DEBUG_ERROR, "QQ", "[DBG][get8] buf %d\n", (void *)buf); | |
85 purple_debug(PURPLE_DEBUG_ERROR, "QQ", "[DBG][get8] b_dest 0x%2x, *b 0x%02x\n", b_dest, *b); | |
86 return sizeof(b_dest); | |
87 } | |
88 | |
41 | 89 |
42 /* read two bytes as "guint16" from buf, | 90 /* read two bytes as "guint16" from buf, |
43 * return the number of bytes read if succeeds, otherwise return -1 */ | 91 * return the number of bytes read if succeeds, otherwise return -1 */ |
92 /* | |
44 gint read_packet_w(guint8 *buf, guint8 **cursor, gint buflen, guint16 *w) | 93 gint read_packet_w(guint8 *buf, guint8 **cursor, gint buflen, guint16 *w) |
45 { | 94 { |
95 guint8 *w_ship = NULL; | |
96 guint16 w_dest; | |
97 #ifdef PARSER_DEBUG | |
98 purple_debug(PURPLE_DEBUG_INFO, "QQ_DEBUGGER", | |
99 "[read_w] buf addr: 0x%x\n", (gpointer)buf); | |
100 #endif | |
46 if (*cursor <= buf + buflen - sizeof(*w)) { | 101 if (*cursor <= buf + buflen - sizeof(*w)) { |
47 *w = g_ntohs(**(guint16 **) cursor); | 102 #ifdef PARSER_DEBUG |
103 purple_debug(PURPLE_DEBUG_INFO, "QQ_DEBUGGER", | |
104 "[read_w] *cursor addr: 0x%x, buf expected addr: 0x%x\n", | |
105 (gpointer)*cursor, (gpointer)(buf + buflen - sizeof(*w))); | |
106 #endif | |
107 // type should match memory buffer | |
108 w_ship = (guint8 *)g_new0(guint16, 1); | |
109 // copy bytes into temporary buffer | |
110 g_memmove(w_ship, *cursor, sizeof(guint16)); | |
111 // type convert and assign value | |
112 w_dest = *(guint16 *)w_ship; | |
113 // ntohs | |
114 *w = g_ntohs(w_dest); | |
115 #ifdef PARSER_DEBUG | |
116 purple_debug(PURPLE_DEBUG_INFO, "QQ_DEBUGGER", | |
117 "[read_w] data: 0x%04x->0x%04x-g_ntohs->0x%04x\n", | |
118 **(guint16 **)cursor, w_dest, *w); | |
119 #endif | |
120 // *cursor goes on | |
48 *cursor += sizeof(*w); | 121 *cursor += sizeof(*w); |
122 | |
123 // free mem | |
124 g_free(w_ship); | |
125 w_ship = NULL; | |
126 | |
49 return sizeof(*w); | 127 return sizeof(*w); |
50 } else { | 128 } else { |
51 return -1; | 129 return -1; |
52 } | 130 } |
53 } | 131 } |
132 */ | |
133 gint qq_get16(guint16 *w, guint8 *buf) | |
134 { | |
135 guint16 w_dest; | |
136 memcpy(&w_dest, buf, sizeof(w_dest)); | |
137 *w = g_ntohs(w_dest); | |
138 purple_debug(PURPLE_DEBUG_ERROR, "QQ", "[DBG][get16] buf %d\n", (void *)buf); | |
139 purple_debug(PURPLE_DEBUG_ERROR, "QQ", "[DBG][get16] w_dest 0x%04x, *w 0x%04x\n", w_dest, *w); | |
140 return sizeof(w_dest); | |
141 } | |
142 | |
54 | 143 |
55 /* read four bytes as "guint32" from buf, | 144 /* read four bytes as "guint32" from buf, |
56 * return the number of bytes read if succeeds, otherwise return -1 */ | 145 * return the number of bytes read if succeeds, otherwise return -1 */ |
146 /* | |
57 gint read_packet_dw(guint8 *buf, guint8 **cursor, gint buflen, guint32 *dw) | 147 gint read_packet_dw(guint8 *buf, guint8 **cursor, gint buflen, guint32 *dw) |
58 { | 148 { |
149 guint8 *dw_ship = NULL; | |
150 guint32 dw_dest; | |
151 #ifdef PARSER_DEBUG | |
152 purple_debug(PURPLE_DEBUG_INFO, "QQ_DEBUGGER", | |
153 "[read_dw] buf addr: 0x%x\n", (gpointer)buf); | |
154 #endif | |
59 if (*cursor <= buf + buflen - sizeof(*dw)) { | 155 if (*cursor <= buf + buflen - sizeof(*dw)) { |
60 *dw = g_ntohl(**(guint32 **) cursor); | 156 #ifdef PARSER_DEBUG |
157 purple_debug(PURPLE_DEBUG_INFO, "QQ_DEBUGGER", | |
158 "[read_dw] *cursor addr: 0x%x, buf expected addr: 0x%x\n", | |
159 (gpointer)*cursor, (gpointer)(buf + buflen - sizeof(*dw))); | |
160 #endif | |
161 dw_ship = (guint8 *)g_new0(guint32, 1); | |
162 g_memmove(dw_ship, *cursor, sizeof(guint32)); | |
163 dw_dest = *(guint32 *)dw_ship; | |
164 *dw = g_ntohl(dw_dest); | |
165 #ifdef PARSER_DEBUG | |
166 purple_debug(PURPLE_DEBUG_INFO, "QQ_DEBUGGER", | |
167 "[read_dw] data: 0x%08x->0x%08x-g_ntohl->0x%08x\n", | |
168 **(guint32 **)cursor, dw_dest, *dw); | |
169 #endif | |
61 *cursor += sizeof(*dw); | 170 *cursor += sizeof(*dw); |
171 | |
172 g_free(dw_ship); | |
173 dw_ship = NULL; | |
174 | |
62 return sizeof(*dw); | 175 return sizeof(*dw); |
63 } else { | 176 } else { |
64 return -1; | 177 return -1; |
65 } | 178 } |
66 } | 179 } |
180 */ | |
181 gint qq_get32(guint32 *dw, guint8 *buf) | |
182 { | |
183 guint32 dw_dest; | |
184 memcpy(&dw_dest, buf, sizeof(dw_dest)); | |
185 *dw = g_ntohl(dw_dest); | |
186 purple_debug(PURPLE_DEBUG_ERROR, "QQ", "[DBG][get32] buf %d\n", (void *)buf); | |
187 purple_debug(PURPLE_DEBUG_ERROR, "QQ", "[DBG][get32] dw_dest 0x%08x, *dw 0x%08x\n", dw_dest, *dw); | |
188 return sizeof(dw_dest); | |
189 } | |
190 | |
191 | |
192 /* read datalen bytes from buf, | |
193 * return the number of bytes read if succeeds, otherwise return -1 */ | |
194 /* | |
195 gint read_packet_data(guint8 *buf, guint8 **cursor, gint buflen, guint8 *data, gint datalen) { | |
196 #ifdef PARSER_DEBUG | |
197 purple_debug(PURPLE_DEBUG_INFO, "QQ_DEBUGGER", | |
198 "[read_data] buf addr: 0x%x\n", (gpointer)buf); | |
199 #endif | |
200 if (*cursor <= buf + buflen - datalen) { | |
201 #ifdef PARSER_DEBUG | |
202 purple_debug(PURPLE_DEBUG_INFO, "QQ_DEBUGGER", | |
203 "[read_data] *cursor addr: 0x%x, buf expected addr: 0x%x\n", | |
204 (gpointer)*cursor, (gpointer)(buf + buflen - datalen)); | |
205 #endif | |
206 g_memmove(data, *cursor, datalen); | |
207 *cursor += datalen; | |
208 return datalen; | |
209 } else { | |
210 return -1; | |
211 } | |
212 } | |
213 */ | |
214 gint qq_getdata(guint8 *data, gint datalen, guint8 *buf) | |
215 { | |
216 memcpy(data, buf, datalen); | |
217 purple_debug(PURPLE_DEBUG_ERROR, "QQ", "[DBG][getdata] buf %d\n", (void *)buf); | |
218 return datalen; | |
219 } | |
220 | |
67 | 221 |
68 /* read four bytes as "time_t" from buf, | 222 /* read four bytes as "time_t" from buf, |
69 * return the number of bytes read if succeeds, otherwise return -1 | 223 * return the number of bytes read if succeeds, otherwise return -1 |
70 * This function is a wrapper around read_packet_dw() to avoid casting. */ | 224 * This function is a wrapper around read_packet_dw() to avoid casting. */ |
225 /* | |
71 gint read_packet_time(guint8 *buf, guint8 **cursor, gint buflen, time_t *t) | 226 gint read_packet_time(guint8 *buf, guint8 **cursor, gint buflen, time_t *t) |
72 { | 227 { |
73 guint32 time; | 228 guint32 time; |
74 gint ret = read_packet_dw(buf, cursor, buflen, &time); | 229 gint ret = read_packet_dw(buf, cursor, buflen, &time); |
75 if (ret != -1 ) { | 230 if (ret != -1 ) { |
76 *t = time; | 231 *t = time; |
77 } | 232 } |
78 return ret; | 233 return ret; |
79 } | 234 } |
80 | 235 */ |
81 /* read datalen bytes from buf, | 236 gint qq_getime(time_t *t, guint8 *buf) |
82 * return the number of bytes read if succeeds, otherwise return -1 */ | 237 { |
83 gint read_packet_data(guint8 *buf, guint8 **cursor, gint buflen, guint8 *data, gint datalen) { | 238 guint32 dw_dest; |
84 if (*cursor <= buf + buflen - datalen) { | 239 memcpy(&dw_dest, buf, sizeof(dw_dest)); |
85 g_memmove(data, *cursor, datalen); | 240 purple_debug(PURPLE_DEBUG_ERROR, "QQ", "[DBG][getime] buf %d\n", (void *)buf); |
86 *cursor += datalen; | 241 purple_debug(PURPLE_DEBUG_ERROR, "QQ", "[DBG][getime] dw_dest before 0x%08x\n", dw_dest); |
87 return datalen; | 242 dw_dest = g_ntohl(dw_dest); |
88 } else { | 243 purple_debug(PURPLE_DEBUG_ERROR, "QQ", "[DBG][getime] dw_dest after 0x%08x\n", dw_dest); |
89 return -1; | 244 memcpy(t, &dw_dest, sizeof(dw_dest)); |
90 } | 245 return sizeof(dw_dest); |
91 } | 246 } |
92 | 247 |
248 /*------------------------------------------------PUT------------------------------------------------*/ | |
93 /* pack one byte into buf | 249 /* pack one byte into buf |
94 * return the number of bytes packed, otherwise return -1 */ | 250 * return the number of bytes packed, otherwise return -1 */ |
251 /* | |
95 gint create_packet_b(guint8 *buf, guint8 **cursor, guint8 b) | 252 gint create_packet_b(guint8 *buf, guint8 **cursor, guint8 b) |
96 { | 253 { |
97 if (*cursor <= buf + MAX_PACKET_SIZE - sizeof(guint8)) { | 254 guint8 b_dest; |
98 **(guint8 **) cursor = b; | 255 #ifdef PARSER_DEBUG |
256 // show me the address! | |
257 purple_debug(PURPLE_DEBUG_INFO, "QQ_DEBUGGER", | |
258 "[create_b] buf addr: 0x%x\n", (gpointer)buf); | |
259 #endif | |
260 // using gpointer is more safe, s3e, 20070704 | |
261 if ((gpointer)*cursor <= (gpointer)(buf + MAX_PACKET_SIZE - sizeof(guint8))) { | |
262 #ifdef PARSER_DEBUG | |
263 purple_debug(PURPLE_DEBUG_INFO, "QQ_DEBUGGER", | |
264 "[create_b] *cursor addr: 0x%x, buf expected addr: 0x%x\n", | |
265 (gpointer)*cursor, | |
266 (gpointer)(buf + MAX_PACKET_SIZE - sizeof(guint8))); | |
267 #endif | |
268 b_dest = b; | |
269 g_memmove(*cursor, &b_dest, sizeof(guint8)); | |
270 #ifdef PARSER_DEBUG | |
271 // show data | |
272 purple_debug(PURPLE_DEBUG_INFO, "QQ_DEBUGGER", | |
273 "[create_b] data: 0x%02x->0x%02x\n", b, **(guint8 **)cursor); | |
274 #endif | |
99 *cursor += sizeof(guint8); | 275 *cursor += sizeof(guint8); |
100 return sizeof(guint8); | 276 return sizeof(guint8); |
101 } else { | 277 } else { |
102 return -1; | 278 return -1; |
103 } | 279 } |
104 } | 280 } |
281 */ | |
282 gint qq_put8(guint8 *buf, guint8 b) | |
283 { | |
284 memcpy(buf, &b, sizeof(b)); | |
285 purple_debug(PURPLE_DEBUG_ERROR, "QQ", "[DBG][put8] buf %d\n", (void *)buf); | |
286 purple_debug(PURPLE_DEBUG_ERROR, "QQ", "[DBG][put8] b 0x%02x\n", b); | |
287 return sizeof(b); | |
288 } | |
289 | |
105 | 290 |
106 /* pack two bytes as "guint16" into buf | 291 /* pack two bytes as "guint16" into buf |
107 * return the number of bytes packed, otherwise return -1 */ | 292 * return the number of bytes packed, otherwise return -1 */ |
293 /* | |
108 gint create_packet_w(guint8 *buf, guint8 **cursor, guint16 w) | 294 gint create_packet_w(guint8 *buf, guint8 **cursor, guint16 w) |
109 { | 295 { |
110 if (*cursor <= buf + MAX_PACKET_SIZE - sizeof(guint16)) { | 296 guint16 w_dest; |
111 **(guint16 **) cursor = g_htons(w); | 297 guint8 *w_ship = NULL; |
298 #ifdef PARSER_DEBUG | |
299 purple_debug(PURPLE_DEBUG_INFO, "QQ_DEBUGGER", | |
300 "[create_w] buf addr: 0x%x\n", (gpointer)buf); | |
301 #endif | |
302 if ((gpointer)*cursor <= (gpointer)(buf + MAX_PACKET_SIZE - sizeof(guint16))) { | |
303 #ifdef PARSER_DEBUG | |
304 purple_debug(PURPLE_DEBUG_INFO, "QQ_DEBUGGER", | |
305 "[create_w] *cursor addr: 0x%x, buf expected addr: 0x%x\n", | |
306 (gpointer)*cursor, | |
307 (gpointer)(buf + MAX_PACKET_SIZE - sizeof(guint16))); | |
308 #endif | |
309 // obscure bugs found by ccpaging, patches from him. | |
310 // similar bugs have been fixed, s3e, 20070710 | |
311 w_dest = g_htons(w); | |
312 w_ship = (guint8 *)&w_dest; | |
313 g_memmove(*cursor, w_ship, sizeof(guint16)); | |
314 #ifdef PARSER_DEBUG | |
315 purple_debug(PURPLE_DEBUG_INFO, "QQ_DEBUGGER", | |
316 "[create_w] data: 0x%04x-g_htons->0x%04x->0x%04x\n", | |
317 w, w_dest, **(guint16 **)cursor); | |
318 #endif | |
112 *cursor += sizeof(guint16); | 319 *cursor += sizeof(guint16); |
113 return sizeof(guint16); | 320 return sizeof(guint16); |
114 } else { | 321 } else { |
115 return -1; | 322 return -1; |
116 } | 323 } |
117 } | 324 } |
325 */ | |
326 gint qq_put16(guint8 *buf, guint16 w) | |
327 { | |
328 guint16 w_porter; | |
329 w_porter = g_htons(w); | |
330 purple_debug(PURPLE_DEBUG_ERROR, "QQ", "[DBG][put16] buf %d\n", (void *)buf); | |
331 purple_debug(PURPLE_DEBUG_ERROR, "QQ", "[DBG][put16] w 0x%04x, w_porter 0x%04x\n", w, w_porter); | |
332 memcpy(buf, &w_porter, sizeof(w_porter)); | |
333 return sizeof(w_porter); | |
334 } | |
335 | |
118 | 336 |
119 /* pack four bytes as "guint32" into buf | 337 /* pack four bytes as "guint32" into buf |
120 * return the number of bytes packed, otherwise return -1 */ | 338 * return the number of bytes packed, otherwise return -1 */ |
339 /* | |
121 gint create_packet_dw(guint8 *buf, guint8 **cursor, guint32 dw) | 340 gint create_packet_dw(guint8 *buf, guint8 **cursor, guint32 dw) |
122 { | 341 { |
123 if (*cursor <= buf + MAX_PACKET_SIZE - sizeof(guint32)) { | 342 guint32 dw_dest; |
124 **(guint32 **) cursor = g_htonl(dw); | 343 guint8 *dw_ship = NULL; |
344 #ifdef PARSER_DEBUG | |
345 purple_debug(PURPLE_DEBUG_INFO, "QQ_DEBUGGER", "[create_dw] buf addr: 0x%x\n", (gpointer)buf); | |
346 #endif | |
347 if ((gpointer)*cursor <= (gpointer)(buf + MAX_PACKET_SIZE - sizeof(guint32))) { | |
348 #ifdef PARSER_DEBUG | |
349 purple_debug(PURPLE_DEBUG_INFO, "QQ_DEBUGGER", | |
350 "[create_dw] *cursor addr: 0x%x, buf expected addr: 0x%x\n", | |
351 (gpointer)*cursor, | |
352 (gpointer)(buf + MAX_PACKET_SIZE -sizeof(guint32))); | |
353 #endif | |
354 dw_dest = g_htonl(dw); | |
355 dw_ship = (guint8 *)&dw_dest; | |
356 g_memmove(*cursor, dw_ship, sizeof(guint32)); | |
357 #ifdef PARSER_DEBUG | |
358 purple_debug(PURPLE_DEBUG_INFO, "QQ_DEBUGGER", | |
359 "[create_dw] data: 0x%08x-g_htonl->0x%08x->0x%08x\n", | |
360 dw, dw_dest, **(guint32 **)cursor); | |
361 #endif | |
125 *cursor += sizeof(guint32); | 362 *cursor += sizeof(guint32); |
126 return sizeof(guint32); | 363 return sizeof(guint32); |
127 } else { | 364 } else { |
128 return -1; | 365 return -1; |
129 } | 366 } |
130 } | 367 } |
368 */ | |
369 gint qq_put32(guint8 *buf, guint32 dw) | |
370 { | |
371 guint32 dw_porter; | |
372 dw_porter = g_htonl(dw); | |
373 purple_debug(PURPLE_DEBUG_ERROR, "QQ", "[DBG][put32] buf %d\n", (void *)buf); | |
374 purple_debug(PURPLE_DEBUG_ERROR, "QQ", "[DBG][put32] dw 0x%08x, dw_porter 0x%08x\n", dw, dw_porter); | |
375 memcpy(buf, &dw_porter, sizeof(dw_porter)); | |
376 return sizeof(dw_porter); | |
377 } | |
378 | |
131 | 379 |
132 /* pack datalen bytes into buf | 380 /* pack datalen bytes into buf |
133 * return the number of bytes packed, otherwise return -1 */ | 381 * return the number of bytes packed, otherwise return -1 */ |
382 /* | |
134 gint create_packet_data(guint8 *buf, guint8 **cursor, guint8 *data, gint datalen) | 383 gint create_packet_data(guint8 *buf, guint8 **cursor, guint8 *data, gint datalen) |
135 { | 384 { |
136 if (*cursor <= buf + MAX_PACKET_SIZE - datalen) { | 385 #ifdef PARSER_DEBUG |
386 purple_debug(PURPLE_DEBUG_INFO, "QQ_DEBUGGER", | |
387 "[create_data] buf addr: 0x%x\n", (gpointer)buf); | |
388 #endif | |
389 if ((gpointer)*cursor <= (gpointer)(buf + MAX_PACKET_SIZE - datalen)) { | |
390 #ifdef PARSER_DEBUG | |
391 purple_debug(PURPLE_DEBUG_INFO, "QQ_DEBUGGER", | |
392 "[create_data] *cursor addr: 0x%x, buf expected addr: 0x%x\n", | |
393 (gpointer)*cursor, | |
394 (gpointer)(buf + MAX_PACKET_SIZE - datalen)); | |
395 #endif | |
137 g_memmove(*cursor, data, datalen); | 396 g_memmove(*cursor, data, datalen); |
138 *cursor += datalen; | 397 *cursor += datalen; |
139 return datalen; | 398 return datalen; |
140 } else { | 399 } else { |
141 return -1; | 400 return -1; |
142 } | 401 } |
143 } | 402 } |
403 */ | |
404 gint qq_putdata(guint8 *buf, guint8 *data, const int datalen) | |
405 { | |
406 memcpy(buf, data, datalen); | |
407 purple_debug(PURPLE_DEBUG_ERROR, "QQ", "[DBG][putdata] buf %d\n", (void *)buf); | |
408 return datalen; | |
409 } | |
410 | |
411 |