Try to improve the "Kerberos requested but not OpenSSL" message.
[jelmer/wireshark.git] / epan / tvbtest.c
1 /* Standalone program to test functionality of tvbuffs.
2  *
3  * tvbtest : tvbtest.o tvbuff.o except.o
4  *
5  * Copyright (c) 2000 by Gilbert Ramirez <gram@alumni.rice.edu>
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  */
22
23 #include "config.h"
24
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28
29 #include "tvbuff.h"
30 #include "exceptions.h"
31 #include "wsutil/pint.h"
32
33 gboolean failed = FALSE;
34
35 /* Tests a tvbuff against the expected pattern/length.
36  * Returns TRUE if all tests succeeed, FALSE if any test fails */
37 gboolean
38 test(tvbuff_t *tvb, const gchar* name,
39      guint8* expected_data, guint expected_length, guint expected_reported_length)
40 {
41         guint                   length;
42         guint                   reported_length;
43         guint8                  *ptr;
44         volatile gboolean       ex_thrown;
45         volatile guint32        val32;
46         guint32                 expected32;
47         guint                   incr, i;
48
49         length = tvb_length(tvb);
50
51         if (length != expected_length) {
52                 printf("01: Failed TVB=%s Length of tvb=%u while expected length=%u\n",
53                                 name, length, expected_length);
54                 failed = TRUE;
55                 return FALSE;
56         }
57
58         reported_length = tvb_reported_length(tvb);
59
60         if (reported_length != expected_reported_length) {
61                 printf("01: Failed TVB=%s Reported length of tvb=%u while expected reported length=%u\n",
62                                 name, reported_length, expected_reported_length);
63                 failed = TRUE;
64                 return FALSE;
65         }
66
67         /* Test boundary case. A BoundsError exception should be thrown. */
68         ex_thrown = FALSE;
69         TRY {
70                 tvb_get_ptr(tvb, 0, length + 1);
71         }
72         CATCH(BoundsError) {
73                 ex_thrown = TRUE;
74         }
75         CATCH(FragmentBoundsError) {
76                 printf("02: Caught wrong exception: FragmentBoundsError\n");
77         }
78         CATCH(ReportedBoundsError) {
79                 printf("02: Caught wrong exception: ReportedBoundsError\n");
80         }
81         CATCH_ALL {
82                 printf("02: Caught wrong exception: %lu, exc->except_id.except_code\n");
83         }
84         ENDTRY;
85
86         if (!ex_thrown) {
87                 printf("02: Failed TVB=%s No BoundsError when retrieving %u bytes\n",
88                                 name, length + 1);
89                 failed = TRUE;
90                 return FALSE;
91         }
92
93         /* Test boundary case with reported_length+1. A ReportedBoundsError
94            exception should be thrown. */
95         ex_thrown = FALSE;
96         TRY {
97                 tvb_get_ptr(tvb, 0, reported_length + 1);
98         }
99         CATCH(BoundsError) {
100                 printf("03: Caught wrong exception: BoundsError\n");
101         }
102         CATCH(FragmentBoundsError) {
103                 printf("03: Caught wrong exception: FragmentBoundsError\n");
104         }
105         CATCH(ReportedBoundsError) {
106                 ex_thrown = TRUE;
107         }
108         CATCH_ALL {
109                 printf("02: Caught wrong exception: %lu, exc->except_id.except_code\n");
110         }
111         ENDTRY;
112
113         if (!ex_thrown) {
114                 printf("03: Failed TVB=%s No ReportedBoundsError when retrieving %u bytes\n",
115                                 name, reported_length + 1);
116                 failed = TRUE;
117                 return FALSE;
118         }
119
120         /* Test boundary case. A BoundsError exception should be thrown. */
121         ex_thrown = FALSE;
122         TRY {
123                 tvb_get_ptr(tvb, -1, 2);
124         }
125         CATCH(BoundsError) {
126                 ex_thrown = TRUE;
127         }
128         CATCH(FragmentBoundsError) {
129                 printf("04: Caught wrong exception: FragmentBoundsError\n");
130         }
131         CATCH(ReportedBoundsError) {
132                 printf("04: Caught wrong exception: ReportedBoundsError\n");
133         }
134         CATCH_ALL {
135                 printf("02: Caught wrong exception: %lu, exc->except_id.except_code\n");
136         }
137         ENDTRY;
138
139         if (!ex_thrown) {
140                 printf("04: Failed TVB=%s No BoundsError when retrieving 2 bytes from"
141                                 " offset -1\n", name);
142                 failed = TRUE;
143                 return FALSE;
144         }
145
146         /* Test boundary case. A BoundsError exception should not be thrown. */
147         ex_thrown = FALSE;
148         TRY {
149                 tvb_get_ptr(tvb, 0, 1);
150         }
151         CATCH(BoundsError) {
152                 ex_thrown = TRUE;
153         }
154         CATCH(FragmentBoundsError) {
155                 printf("05: Caught wrong exception: FragmentBoundsError\n");
156         }
157         CATCH(ReportedBoundsError) {
158                 printf("05: Caught wrong exception: ReportedBoundsError\n");
159         }
160         CATCH_ALL {
161                 printf("02: Caught wrong exception: %lu, exc->except_id.except_code\n");
162         }
163         ENDTRY;
164
165         if (ex_thrown) {
166                 printf("05: Failed TVB=%s BoundsError when retrieving 1 bytes from"
167                                 " offset 0\n", name);
168                 failed = TRUE;
169                 return FALSE;
170         }
171
172         /* Test boundary case. A BoundsError exception should not be thrown. */
173         ex_thrown = FALSE;
174         TRY {
175                 tvb_get_ptr(tvb, -1, 1);
176         }
177         CATCH(BoundsError) {
178                 ex_thrown = TRUE;
179         }
180         CATCH(FragmentBoundsError) {
181                 printf("06: Caught wrong exception: FragmentBoundsError\n");
182         }
183         CATCH(ReportedBoundsError) {
184                 printf("06: Caught wrong exception: ReportedBoundsError\n");
185         }
186         CATCH_ALL {
187                 printf("02: Caught wrong exception: %lu, exc->except_id.except_code\n");
188         }
189         ENDTRY;
190
191         if (ex_thrown) {
192                 printf("06: Failed TVB=%s BoundsError when retrieving 1 bytes from"
193                                 " offset -1\n", name);
194                 failed = TRUE;
195                 return FALSE;
196         }
197
198
199         /* Check data at boundary. An exception should not be thrown. */
200         if (length >= 4) {
201                 ex_thrown = FALSE;
202                 TRY {
203                         val32 = tvb_get_ntohl(tvb, 0);
204                 }
205                 CATCH_ALL {
206                         ex_thrown = TRUE;
207                 }
208                 ENDTRY;
209
210                 if (ex_thrown) {
211                         printf("07: Failed TVB=%s Exception when retrieving "
212                                         "guint32 from offset 0\n", name);
213                         failed = TRUE;
214                         return FALSE;
215                 }
216
217                 expected32 = pntoh32(expected_data);
218                 if (val32 != expected32) {
219                         printf("08: Failed TVB=%s  guint32 @ 0 %u != expected %u\n",
220                                         name, val32, expected32);
221                         failed = TRUE;
222                         return FALSE;
223                 }
224         }
225
226         /* Check data at boundary. An exception should not be thrown. */
227         if (length >= 4) {
228                 ex_thrown = FALSE;
229                 TRY {
230                         val32 = tvb_get_ntohl(tvb, -4);
231                 }
232                 CATCH_ALL {
233                         ex_thrown = TRUE;
234                 }
235                 ENDTRY;
236
237                 if (ex_thrown) {
238                         printf("09: Failed TVB=%s Exception when retrieving "
239                                         "guint32 from offset 0\n", name);
240                         failed = TRUE;
241                         return FALSE;
242                 }
243
244                 expected32 = pntoh32(&expected_data[length-4]);
245                 if (val32 != expected32) {
246                         printf("10: Failed TVB=%s guint32 @ -4 %u != expected %u\n",
247                                         name, val32, expected32);
248                         failed = TRUE;
249                         return FALSE;
250                 }
251         }
252
253         /* Sweep across data in various sized increments checking
254          * tvb_memdup() */
255         for (incr = 1; incr < length; incr++) {
256                 for (i = 0; i < length - incr; i += incr) {
257                         ptr = tvb_memdup(NULL, tvb, i, incr);
258                         if (memcmp(ptr, &expected_data[i], incr) != 0) {
259                                 printf("11: Failed TVB=%s Offset=%d Length=%d "
260                                                 "Bad memdup\n",
261                                                 name, i, incr);
262                                 failed = TRUE;
263                                 g_free(ptr);
264                                 return FALSE;
265                         }
266                         g_free(ptr);
267                 }
268         }
269
270         /* One big memdup */
271         ptr = tvb_memdup(NULL, tvb, 0, -1);
272         if (memcmp(ptr, expected_data, length) != 0) {
273                 printf("12: Failed TVB=%s Offset=0 Length=-1 "
274                                 "Bad memdup\n", name);
275                 failed = TRUE;
276                 g_free(ptr);
277                 return FALSE;
278         }
279         g_free(ptr);
280
281
282         printf("Passed TVB=%s\n", name);
283
284         return TRUE;
285 }
286
287 gboolean
288 skip(tvbuff_t *tvb _U_, gchar* name,
289                 guint8* expected_data _U_, guint expected_length _U_)
290 {
291         printf("Skipping TVB=%s\n", name);
292         return FALSE;
293 }
294
295
296 void
297 run_tests(void)
298 {
299         int             i, j;
300
301         tvbuff_t        *tvb_parent;
302         tvbuff_t        *tvb_small[3];
303         tvbuff_t        *tvb_large[3];
304         tvbuff_t        *tvb_subset[6];
305         guint8          *small[3];
306         guint           small_length[3];
307         guint           small_reported_length[3];
308         guint8          *large[3];
309         guint           large_length[3];
310         guint           large_reported_length[3];
311         guint8          *subset[6];
312         guint           subset_length[6];
313         guint           subset_reported_length[6];
314         guint8          temp;
315         guint8          *comp[6];
316         tvbuff_t        *tvb_comp[6];
317         guint           comp_length[6];
318         guint           comp_reported_length[6];
319         int             len;
320
321         tvb_parent = tvb_new_real_data("", 0, 0);
322         for (i = 0; i < 3; i++) {
323                 small[i] = g_new(guint8, 16);
324
325                 temp = 16 * i;
326                 for (j = 0; j < 16; j++) {
327                         small[i][j] = temp + j;
328                 }
329                 small_length[i] = 16;
330                 small_reported_length[i] = 17;
331                 tvb_small[i] = tvb_new_child_real_data(tvb_parent, small[i], 16, 17);
332                 tvb_set_free_cb(tvb_small[i], g_free);
333         }
334
335         for (i = 0; i < 3; i++) {
336                 large[i] = g_new(guint8, 19);
337
338                 temp = 19 * i;
339                 for (j = 0; j < 19; j++) {
340                         large[i][j] = temp + j;
341                 }
342
343                 large_length[i] = 19;
344                 large_reported_length[i] = 20;
345                 tvb_large[i] = tvb_new_child_real_data(tvb_parent, large[i], 19, 20);
346                 tvb_set_free_cb(tvb_large[i], g_free);
347         }
348
349         /* Test the TVBUFF_REAL_DATA objects. */
350         test(tvb_small[0], "Small 0", small[0], small_length[0], small_reported_length[0]);
351         test(tvb_small[1], "Small 1", small[1], small_length[1], small_reported_length[1]);
352         test(tvb_small[2], "Small 2", small[2], small_length[2], small_reported_length[2]);
353
354         test(tvb_large[0], "Large 0", large[0], large_length[0], large_reported_length[0]);
355         test(tvb_large[1], "Large 1", large[1], large_length[1], large_reported_length[1]);
356         test(tvb_large[2], "Large 2", large[2], large_length[2], large_reported_length[2]);
357
358         subset_length[0]          = 8;
359         subset_reported_length[0] = 9;
360         tvb_subset[0]             = tvb_new_subset(tvb_small[0], 0, 8, 9);
361         subset[0]                 = &small[0][0];
362
363         subset_length[1]          = 10;
364         subset_reported_length[1] = 11;
365         tvb_subset[1]             = tvb_new_subset(tvb_large[0], -10, 10, 11);
366         subset[1]                 = &large[0][9];
367
368         subset_length[2]          = 16;
369         subset_reported_length[2] = 17;
370         tvb_subset[2]             = tvb_new_subset(tvb_small[1], -16, -1, 17);
371         subset[2]                 = &small[1][0];
372
373         subset_length[3]          = 3;
374         subset_reported_length[3] = 4;
375         tvb_subset[3]             = tvb_new_subset(tvb_subset[0], 0, 3, 4);
376         subset[3]                 = &small[0][0];
377
378         subset_length[4]          = 5;
379         subset_reported_length[4] = 6;
380         tvb_subset[4]             = tvb_new_subset(tvb_subset[1], -5, 5, 6);
381         subset[4]                 = &large[0][14];
382
383         subset_length[5]          = 8;
384         subset_reported_length[5] = 9;
385         tvb_subset[5]             = tvb_new_subset(tvb_subset[2], 4, 8, 9);
386         subset[5]                 = &small[1][4];
387
388         /* Test the TVBUFF_SUBSET objects. */
389         test(tvb_subset[0], "Subset 0", subset[0], subset_length[0], subset_reported_length[0]);
390         test(tvb_subset[1], "Subset 1", subset[1], subset_length[1], subset_reported_length[1]);
391         test(tvb_subset[2], "Subset 2", subset[2], subset_length[2], subset_reported_length[2]);
392         test(tvb_subset[3], "Subset 3", subset[3], subset_length[3], subset_reported_length[3]);
393         test(tvb_subset[4], "Subset 4", subset[4], subset_length[4], subset_reported_length[4]);
394         test(tvb_subset[5], "Subset 5", subset[5], subset_length[5], subset_reported_length[5]);
395
396         /* One Real */
397         printf("Making Composite 0\n");
398         tvb_comp[0]             = tvb_new_composite();
399         comp_length[0]          = small_length[0];
400         comp_reported_length[0] = small_reported_length[0];
401         comp[0]                 = small[0];
402         tvb_composite_append(tvb_comp[0], tvb_small[0]);
403         tvb_composite_finalize(tvb_comp[0]);
404
405         /* Two Reals */
406         printf("Making Composite 1\n");
407         tvb_comp[1]             = tvb_new_composite();
408         comp_length[1]          = small_length[0] + small_length[1];
409         comp_reported_length[1] = small_reported_length[0] + small_reported_length[1];
410         comp[1]                 = g_malloc(comp_length[1]);
411         memcpy(comp[1], small[0], small_length[0]);
412         memcpy(&comp[1][small_length[0]], small[1], small_length[1]);
413         tvb_composite_append(tvb_comp[1], tvb_small[0]);
414         tvb_composite_append(tvb_comp[1], tvb_small[1]);
415         tvb_composite_finalize(tvb_comp[1]);
416
417         /* One subset */
418         printf("Making Composite 2\n");
419         tvb_comp[2]             = tvb_new_composite();
420         comp_length[2]          = subset_length[1];
421         comp_reported_length[2] = subset_reported_length[1];
422         comp[2]                 = subset[1];
423         tvb_composite_append(tvb_comp[2], tvb_subset[1]);
424         tvb_composite_finalize(tvb_comp[2]);
425
426         /* Two subsets */
427         printf("Making Composite 3\n");
428         tvb_comp[3]             = tvb_new_composite();
429         comp_length[3]          = subset_length[4] + subset_length[5];
430         comp_reported_length[3] = subset_reported_length[4] + subset_reported_length[5];
431         comp[3]                 = g_malloc(comp_length[3]);
432         memcpy(comp[3], subset[4], subset_length[4]);
433         memcpy(&comp[3][subset_length[4]], subset[5], subset_length[5]);
434         tvb_composite_append(tvb_comp[3], tvb_subset[4]);
435         tvb_composite_append(tvb_comp[3], tvb_subset[5]);
436         tvb_composite_finalize(tvb_comp[3]);
437
438         /* One real, one subset */
439         printf("Making Composite 4\n");
440         tvb_comp[4]             = tvb_new_composite();
441         comp_length[4]          = small_length[0] + subset_length[1];
442         comp_reported_length[4] = small_reported_length[0] + subset_reported_length[1];
443         comp[4]                 = g_malloc(comp_length[4]);
444         memcpy(&comp[4][0], small[0], small_length[0]);
445         memcpy(&comp[4][small_length[0]], subset[1], subset_length[1]);
446         tvb_composite_append(tvb_comp[4], tvb_small[0]);
447         tvb_composite_append(tvb_comp[4], tvb_subset[1]);
448         tvb_composite_finalize(tvb_comp[4]);
449
450         /* 4 composites */
451         printf("Making Composite 5\n");
452         tvb_comp[5]             = tvb_new_composite();
453         comp_length[5]          = comp_length[0] +
454                                         comp_length[1] +
455                                         comp_length[2] +
456                                         comp_length[3];
457         comp_reported_length[5] = comp_reported_length[0] +
458                                         comp_reported_length[1] +
459                                         comp_reported_length[2] +
460                                         comp_reported_length[3];
461         comp[5]                 = g_malloc(comp_length[5]);
462
463         len = 0;
464         memcpy(&comp[5][len], comp[0], comp_length[0]);
465         len += comp_length[0];
466         memcpy(&comp[5][len], comp[1], comp_length[1]);
467         len += comp_length[1];
468         memcpy(&comp[5][len], comp[2], comp_length[2]);
469         len += comp_length[2];
470         memcpy(&comp[5][len], comp[3], comp_length[3]);
471
472         tvb_composite_append(tvb_comp[5], tvb_comp[0]);
473         tvb_composite_append(tvb_comp[5], tvb_comp[1]);
474         tvb_composite_append(tvb_comp[5], tvb_comp[2]);
475         tvb_composite_append(tvb_comp[5], tvb_comp[3]);
476         tvb_composite_finalize(tvb_comp[5]);
477
478         /* Test the TVBUFF_COMPOSITE objects. */
479         test(tvb_comp[0], "Composite 0", comp[0], comp_length[0], comp_reported_length[0]);
480         test(tvb_comp[1], "Composite 1", comp[1], comp_length[1], comp_reported_length[1]);
481         test(tvb_comp[2], "Composite 2", comp[2], comp_length[2], comp_reported_length[2]);
482         test(tvb_comp[3], "Composite 3", comp[3], comp_length[3], comp_reported_length[3]);
483         test(tvb_comp[4], "Composite 4", comp[4], comp_length[4], comp_reported_length[4]);
484         test(tvb_comp[5], "Composite 5", comp[5], comp_length[5], comp_reported_length[5]);
485
486         /* free memory. */
487         /* Don't free: comp[0] */
488         g_free(comp[1]);
489         /* Don't free: comp[2] */
490         g_free(comp[3]);
491         g_free(comp[4]);
492         g_free(comp[5]);
493
494         tvb_free_chain(tvb_parent);  /* should free all tvb's and associated data */
495 }
496
497 /* Note: valgrind can be used to check for tvbuff memory leaks */
498 int
499 main(void)
500 {
501         /* For valgrind: See GLib documentation: "Running GLib Applications" */
502         g_setenv("G_DEBUG", "gc-friendly", 1);
503         g_setenv("G_SLICE", "always-malloc", 1);
504
505         except_init();
506         run_tests();
507         except_deinit();
508         exit(failed?1:0);
509 }