Get the Windows build going again.
[obnox/wireshark/wip.git] / epan / reassemble_test.c
1 /* Standalone program to test functionality of reassemble.h API
2  *
3  * These aren't particularly complete - they just test a few corners of
4  * functionality which I was interested in. In particular, they only test the
5  * fragment_add_seq_* (ie, FD_BLOCKSEQUENCE) family of routines. However,
6  * hopefully they will inspire people to write additional tests, and provide a
7  * useful basis on which to do so.
8  *
9  * $Id$
10  *
11  * Copyright (c) 2007 MX Telecom Ltd. <richardv@mxtelecom.com>
12  *
13  * Wireshark - Network traffic analyzer
14  * By Gerald Combs <gerald@wireshark.org>
15  * Copyright 1998
16  *
17  * This program is free software; you can redistribute it and/or
18  * modify it under the terms of the GNU General Public License
19  * as published by the Free Software Foundation; either version 2
20  * of the License, or (at your option) any later version.
21  *
22  * This program is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25  * GNU General Public License for more details.
26  *
27  * You should have received a copy of the GNU General Public License
28  * along with this program; if not, write to the Free Software
29  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
30  */
31
32 #include <stdarg.h>
33 #include <stdlib.h>
34 #include <stdio.h>
35 #include <string.h>
36
37 #include <glib.h>
38
39 #ifdef HAVE_CONFIG_H
40 # include "config.h"
41 #endif
42
43 #include <epan/emem.h>
44 #include <epan/packet.h>
45 #include <epan/packet_info.h>
46 #include <epan/proto.h>
47 #include <epan/tvbuff.h>
48 #include <epan/reassemble.h>
49
50 #include <epan/dissectors/packet-dcerpc.h>
51
52 #define ASSERT(b) do_test((b),"Assertion failed at line %i: %s\n", __LINE__, #b)
53 #define ASSERT_EQ(exp,act) do_test((exp)==(act),"Assertion failed at line %i: %s==%s (%i==%i)\n", __LINE__, #exp, #act, exp, act)
54 #define ASSERT_NE(exp,act) do_test((exp)!=(act),"Assertion failed at line %i: %s!=%s (%i!=%i)\n", __LINE__, #exp, #act, exp, act)
55
56 static int failure = 0;
57
58 static void
59 do_test(gboolean condition, const char *format, ...)
60 {
61     va_list ap;
62
63     if (condition)
64         return;
65
66     va_start(ap, format);
67     vfprintf(stderr, format, ap);
68     va_end(ap);
69     failure = 1;
70
71     /* many of the tests assume this routine doesn't return on failure; if we
72      * do, it may provide more information, but may cause a segfault. Uncomment
73      * this line if you wish.
74      */
75     exit(1);
76 }
77
78 #define DATA_LEN 256
79
80 static char *data;
81 static tvbuff_t *tvb;
82 static packet_info pinfo;
83
84 /* fragment_table maps from datagram ids to head of fragment_data list
85    reassembled_table maps from <packet number,datagram id> to head of
86    fragment_data list */
87 static GHashTable *fragment_table;
88 static GHashTable *reassembled_table;
89
90 /**********************************************************************************
91  *
92  * fragment_add_seq
93  *
94  *********************************************************************************/
95
96 /* Simple test case for fragment_add_seq.
97  * Adds three fragments (out of order, with one for a different datagram in between),
98  * and checks that they are reassembled correctly.
99  */
100 static void
101 test_simple_fragment_add_seq(void)
102 {
103     fragment_data *fd_head, *fdh0;
104
105     printf("Starting test test_simple_fragment_add_seq\n");
106
107     pinfo.fd->num = 1;
108     fd_head=fragment_add_seq(tvb, 10, &pinfo, 12, fragment_table,
109                              0, 50, TRUE);
110
111     ASSERT_EQ(1,g_hash_table_size(fragment_table));
112     ASSERT_EQ(NULL,fd_head);
113
114     /* adding the same fragment again should do nothing, even with different
115      * offset etc */
116     pinfo.fd->flags.visited = 1;
117     fd_head=fragment_add_seq(tvb, 5, &pinfo, 12, fragment_table,
118                              0, 60, TRUE);
119     ASSERT_EQ(1,g_hash_table_size(fragment_table));
120     ASSERT_EQ(NULL,fd_head);
121
122     /* start another pdu (just to confuse things) */
123     pinfo.fd->flags.visited = 0;
124     pinfo.fd->num = 2;
125     fd_head=fragment_add_seq(tvb, 15, &pinfo, 13, fragment_table,
126                              0, 60, TRUE);
127     ASSERT_EQ(2,g_hash_table_size(fragment_table));
128     ASSERT_EQ(NULL,fd_head);
129
130     /* now we add the terminal fragment of the first datagram */
131     pinfo.fd->num = 3;
132     fd_head=fragment_add_seq(tvb, 5, &pinfo, 12, fragment_table,
133                              2, 60, FALSE);
134
135     /* we haven't got all the fragments yet ... */
136     ASSERT_EQ(2,g_hash_table_size(fragment_table));
137     ASSERT_EQ(NULL,fd_head);
138
139     /* finally, add the missing fragment */
140     pinfo.fd->num = 4;
141     fd_head=fragment_add_seq(tvb, 15, &pinfo, 12, fragment_table,
142                              1, 60, TRUE);
143
144     ASSERT_EQ(2,g_hash_table_size(fragment_table));
145     ASSERT_NE(NULL,fd_head);
146
147     /* check the contents of the structure */
148     ASSERT_EQ(0,fd_head->frame);  /* unused */
149     ASSERT_EQ(0,fd_head->offset); /* unused */
150     ASSERT_EQ(170,fd_head->len); /* the length of data we have */
151     ASSERT_EQ(2,fd_head->datalen); /* seqno of the last fragment we have */
152     ASSERT_EQ(4,fd_head->reassembled_in);
153     ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET,fd_head->flags);
154     ASSERT_NE(NULL,fd_head->data);
155     ASSERT_NE(NULL,fd_head->next);
156
157     ASSERT_EQ(1,fd_head->next->frame);
158     ASSERT_EQ(0,fd_head->next->offset);  /* seqno */
159     ASSERT_EQ(50,fd_head->next->len);    /* segment length */
160     ASSERT_EQ(0,fd_head->next->flags);
161     ASSERT_EQ(NULL,fd_head->next->data);
162     ASSERT_NE(NULL,fd_head->next->next);
163
164     ASSERT_EQ(4,fd_head->next->next->frame);
165     ASSERT_EQ(1,fd_head->next->next->offset);  /* seqno */
166     ASSERT_EQ(60,fd_head->next->next->len);    /* segment length */
167     ASSERT_EQ(0,fd_head->next->next->flags);
168     ASSERT_EQ(NULL,fd_head->next->next->data);
169     ASSERT_NE(NULL,fd_head->next->next->next);
170
171     ASSERT_EQ(3,fd_head->next->next->next->frame);
172     ASSERT_EQ(2,fd_head->next->next->next->offset);  /* seqno */
173     ASSERT_EQ(60,fd_head->next->next->next->len);    /* segment length */
174     ASSERT_EQ(0,fd_head->next->next->next->flags);
175     ASSERT_EQ(NULL,fd_head->next->next->next->data);
176     ASSERT_EQ(NULL,fd_head->next->next->next->next);
177
178     /* test the actual reassembly */
179     ASSERT(!memcmp(fd_head->data,data+10,50));
180     ASSERT(!memcmp(fd_head->data+50,data+15,60));
181     ASSERT(!memcmp(fd_head->data+110,data+5,60));
182
183     /* what happens if we revisit the packets now? */
184     fdh0 = fd_head;
185     pinfo.fd->flags.visited = 1;
186     pinfo.fd->num = 1;
187     fd_head=fragment_add_seq(tvb, 10, &pinfo, 12, fragment_table,
188                              0, 50, TRUE);
189     /*
190      * this api relies on the caller to check fd_head -> reassembled_in
191      *
192      * Redoing all the tests seems like overkill - just check the pointer
193      */
194     ASSERT_EQ(fdh0,fd_head);
195
196     pinfo.fd->num = 3;
197     fd_head=fragment_add_seq(tvb, 5, &pinfo, 12, fragment_table,
198                              2, 60, FALSE);
199     ASSERT_EQ(fdh0,fd_head);
200
201     pinfo.fd->num = 4;
202     fd_head=fragment_add_seq(tvb, 15, &pinfo, 12, fragment_table,
203                              1, 60, TRUE);
204     ASSERT_EQ(fdh0,fd_head);
205 }
206
207 /* XXX ought to have some tests for overlapping fragments */
208
209 /* This tests the functionality of fragment_set_partial_reassembly for
210  * FD_BLOCKSEQUENCE reassembly.
211  *
212  * We add a sequence of fragments thus:
213  *    seqno   frame  offset   len   (initial) more_frags
214  *    -----   -----  ------   ---   --------------------
215  *      0       1       10       50   false
216  *      1       2        0       40   true
217  *      1       3        0       40   true (a duplicate fragment)
218  *      2       4       20      100   false
219  *      3       5        0       40   false
220  */
221 static void
222 test_fragment_add_seq_partial_reassembly(void)
223 {
224     fragment_data *fd_head, *fd;
225
226     printf("Starting test test_fragment_add_seq_partial_reassembly\n");
227
228     /* generally it's probably fair to assume that we will be called with
229      * more_frags=FALSE.
230      */
231     pinfo.fd->num = 1;
232     fd_head=fragment_add_seq(tvb, 10, &pinfo, 12, fragment_table,
233                              0, 50, FALSE);
234
235     ASSERT_EQ(1,g_hash_table_size(fragment_table));
236     ASSERT_NE(NULL,fd_head);
237
238     /* check the contents of the structure */
239     ASSERT_EQ(0,fd_head->frame);  /* unused */
240     ASSERT_EQ(0,fd_head->offset); /* unused */
241     ASSERT_EQ(50,fd_head->len); /* the length of data we have */
242     ASSERT_EQ(0,fd_head->datalen); /* seqno of the last fragment we have */
243     ASSERT_EQ(1,fd_head->reassembled_in);
244     ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET,fd_head->flags);
245     ASSERT_NE(NULL,fd_head->data);
246     ASSERT_NE(NULL,fd_head->next);
247
248     ASSERT_EQ(1,fd_head->next->frame);
249     ASSERT_EQ(0,fd_head->next->offset);  /* seqno */
250     ASSERT_EQ(50,fd_head->next->len);    /* segment length */
251     ASSERT_EQ(0,fd_head->next->flags);
252     ASSERT_EQ(NULL,fd_head->next->data);
253     ASSERT_EQ(NULL,fd_head->next->next);
254
255     /* test the actual reassembly */
256     ASSERT(!memcmp(fd_head->data,data+10,50));
257
258     /* now we announce that the reassembly wasn't complete after all. */
259     fragment_set_partial_reassembly(&pinfo,12,fragment_table);
260
261     /* and add another segment. To mix things up slightly (and so that we can
262      * check on the state of things), we're going to set the more_frags flag
263      * here
264      */
265     pinfo.fd->num = 2;
266     fd_head=fragment_add_seq(tvb, 0, &pinfo, 12, fragment_table,
267                              1, 40, TRUE);
268
269     ASSERT_EQ(1,g_hash_table_size(fragment_table));
270     ASSERT_EQ(NULL,fd_head);
271
272     fd_head=fragment_get(&pinfo,12,fragment_table);
273     ASSERT_NE(NULL,fd_head);
274
275     /* check the contents of the structure */
276     ASSERT_EQ(0,fd_head->frame);   /* unused */
277     ASSERT_EQ(0,fd_head->offset);  /* unused */
278     /* ASSERT_EQ(50,fd_head->len);     the length of data we have */
279     ASSERT_EQ(0,fd_head->datalen); /* seqno of the last fragment we have */
280     ASSERT_EQ(0,fd_head->reassembled_in);
281     ASSERT_EQ(FD_BLOCKSEQUENCE,fd_head->flags);
282     ASSERT_NE(NULL,fd_head->data);
283     ASSERT_NE(NULL,fd_head->next);
284
285     fd=fd_head->next;
286     ASSERT_EQ(1,fd->frame);
287     ASSERT_EQ(0,fd->offset);  /* seqno */
288     ASSERT_EQ(50,fd->len);    /* segment length */
289     ASSERT_EQ(FD_NOT_MALLOCED,fd->flags);
290     ASSERT_EQ(fd_head->data,fd->data);
291     ASSERT_NE(NULL,fd->next);
292
293     fd=fd->next;
294     ASSERT_EQ(2,fd->frame);
295     ASSERT_EQ(1,fd->offset);  /* seqno */
296     ASSERT_EQ(40,fd->len);    /* segment length */
297     ASSERT_EQ(0,fd->flags);
298     ASSERT_NE(NULL,fd->data);
299     ASSERT_EQ(NULL,fd->next);
300
301     /* Another copy of the second segment.
302      */
303     pinfo.fd->num = 3;
304     fd_head=fragment_add_seq(tvb, 0, &pinfo, 12, fragment_table,
305                              1, 40, TRUE);
306
307     ASSERT_EQ(1,g_hash_table_size(fragment_table));
308     ASSERT_EQ(NULL,fd_head);
309     fd_head=fragment_get(&pinfo,12,fragment_table);
310     ASSERT_NE(NULL,fd_head);
311     ASSERT_EQ(0,fd_head->frame);   /* unused */
312     ASSERT_EQ(0,fd_head->offset);  /* unused */
313     /* ASSERT_EQ(50,fd_head->len);     the length of data we have */
314     ASSERT_EQ(0,fd_head->datalen); /* seqno of the last fragment we have */
315     ASSERT_EQ(0,fd_head->reassembled_in);
316     ASSERT_EQ(FD_BLOCKSEQUENCE,fd_head->flags);
317     ASSERT_NE(NULL,fd_head->data);
318     ASSERT_NE(NULL,fd_head->next);
319
320     fd=fd_head->next;
321     ASSERT_EQ(1,fd->frame);
322     ASSERT_EQ(0,fd->offset);  /* seqno */
323     ASSERT_EQ(50,fd->len);    /* segment length */
324     ASSERT_EQ(FD_NOT_MALLOCED,fd->flags);
325     ASSERT_EQ(fd_head->data,fd->data);
326     ASSERT_NE(NULL,fd->next);
327
328     fd=fd->next;
329     ASSERT_EQ(2,fd->frame);
330     ASSERT_EQ(1,fd->offset);  /* seqno */
331     ASSERT_EQ(40,fd->len);    /* segment length */
332     ASSERT_EQ(0,fd->flags);
333     ASSERT_NE(NULL,fd->data);
334     ASSERT_NE(NULL,fd->next);
335
336     fd=fd->next;
337     ASSERT_EQ(3,fd->frame);
338     ASSERT_EQ(1,fd->offset);  /* seqno */
339     ASSERT_EQ(40,fd->len);    /* segment length */
340     ASSERT_EQ(0,fd->flags);
341     ASSERT_NE(NULL,fd->data);
342     ASSERT_EQ(NULL,fd->next);
343
344
345
346     /* have another go at wrapping things up */
347     pinfo.fd->num = 4;
348     fd_head=fragment_add_seq(tvb, 20, &pinfo, 12, fragment_table,
349                              2, 100, FALSE);
350
351     ASSERT_EQ(1,g_hash_table_size(fragment_table));
352     ASSERT_NE(NULL,fd_head);
353
354     /* check the contents of the structure */
355     ASSERT_EQ(0,fd_head->frame);  /* unused */
356     ASSERT_EQ(0,fd_head->offset); /* unused */
357     ASSERT_EQ(190,fd_head->len); /* the length of data we have */
358     ASSERT_EQ(2,fd_head->datalen); /* seqno of the last fragment we have */
359     ASSERT_EQ(4,fd_head->reassembled_in);
360     ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
361     ASSERT_NE(NULL,fd_head->data);
362     ASSERT_NE(NULL,fd_head->next);
363
364     fd=fd_head->next;
365     ASSERT_EQ(1,fd->frame);
366     ASSERT_EQ(0,fd->offset);  /* seqno */
367     ASSERT_EQ(50,fd->len);    /* segment length */
368     ASSERT_EQ(0,fd->flags);
369     ASSERT_EQ(NULL,fd->data);
370     ASSERT_NE(NULL,fd->next);
371
372     fd=fd->next;
373     ASSERT_EQ(2,fd->frame);
374     ASSERT_EQ(1,fd->offset);  /* seqno */
375     ASSERT_EQ(40,fd->len);    /* segment length */
376     ASSERT_EQ(0,fd->flags);
377     ASSERT_EQ(NULL,fd->data);
378     ASSERT_NE(NULL,fd->next);
379
380     fd=fd->next;
381     ASSERT_EQ(3,fd->frame);
382     ASSERT_EQ(1,fd->offset);  /* seqno */
383     ASSERT_EQ(40,fd->len);    /* segment length */
384     ASSERT_EQ(FD_OVERLAP,fd->flags);
385     ASSERT_EQ(NULL,fd->data);
386     ASSERT_NE(NULL,fd->next);
387
388     fd=fd->next;
389     ASSERT_EQ(4,fd->frame);
390     ASSERT_EQ(2,fd->offset);  /* seqno */
391     ASSERT_EQ(100,fd->len);    /* segment length */
392     ASSERT_EQ(0,fd->flags);
393     ASSERT_EQ(NULL,fd->data);
394     ASSERT_EQ(NULL,fd->next);
395
396     /* test the actual reassembly */
397     ASSERT(!memcmp(fd_head->data,data+10,50));
398     ASSERT(!memcmp(fd_head->data+50,data,40));
399     ASSERT(!memcmp(fd_head->data+90,data+20,100));
400
401
402     /* do it again (this time it is more complicated, with an overlap in the
403      * reassembly) */
404
405     fragment_set_partial_reassembly(&pinfo,12,fragment_table);
406
407     pinfo.fd->num = 5;
408     fd_head=fragment_add_seq(tvb, 0, &pinfo, 12, fragment_table,
409                              3, 40, FALSE);
410
411     fd_head=fragment_get(&pinfo,12,fragment_table);
412     ASSERT_NE(NULL,fd_head);
413     ASSERT_EQ(0,fd_head->frame);   /* unused */
414     ASSERT_EQ(0,fd_head->offset);  /* unused */
415     ASSERT_EQ(230,fd_head->len);   /* the length of data we have */
416     ASSERT_EQ(3,fd_head->datalen); /* seqno of the last fragment we have */
417     ASSERT_EQ(5,fd_head->reassembled_in);
418     ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
419     ASSERT_NE(NULL,fd_head->data);
420     ASSERT_NE(NULL,fd_head->next);
421
422     fd=fd_head->next;
423     ASSERT_EQ(1,fd->frame);
424     ASSERT_EQ(0,fd->offset);  /* seqno */
425     ASSERT_EQ(50,fd->len);    /* segment length */
426     ASSERT_EQ(0,fd->flags);
427     ASSERT_EQ(NULL,fd->data);
428     ASSERT_NE(NULL,fd->next);
429
430     fd=fd->next;
431     ASSERT_EQ(2,fd->frame);
432     ASSERT_EQ(1,fd->offset);  /* seqno */
433     ASSERT_EQ(40,fd->len);    /* segment length */
434     ASSERT_EQ(0,fd->flags);
435     ASSERT_EQ(NULL,fd->data);
436     ASSERT_NE(NULL,fd->next);
437
438     fd=fd->next;
439     ASSERT_EQ(3,fd->frame);
440     ASSERT_EQ(1,fd->offset);  /* seqno */
441     ASSERT_EQ(40,fd->len);    /* segment length */
442     ASSERT_EQ(FD_OVERLAP,fd->flags);
443     ASSERT_EQ(NULL,fd->data);
444     ASSERT_NE(NULL,fd->next);
445
446     fd=fd->next;
447     ASSERT_EQ(4,fd->frame);
448     ASSERT_EQ(2,fd->offset);  /* seqno */
449     ASSERT_EQ(100,fd->len);   /* segment length */
450     ASSERT_EQ(0,fd->flags);
451     ASSERT_EQ(NULL,fd->data);
452     ASSERT_NE(NULL,fd->next);
453
454     fd=fd->next;
455     ASSERT_EQ(5,fd->frame);
456     ASSERT_EQ(3,fd->offset);  /* seqno */
457     ASSERT_EQ(40,fd->len);    /* segment length */
458     ASSERT_EQ(0,fd->flags);
459     ASSERT_EQ(NULL,fd->data);
460     ASSERT_EQ(NULL,fd->next);
461
462     /* test the actual reassembly */
463     ASSERT(!memcmp(fd_head->data,data+10,50));
464     ASSERT(!memcmp(fd_head->data+50,data,40));
465     ASSERT(!memcmp(fd_head->data+90,data+20,100));
466     ASSERT(!memcmp(fd_head->data+190,data,40));
467 }
468
469 /**********************************************************************************
470  *
471  * fragment_add_dcerpc_dg
472  *
473  *********************************************************************************/
474
475 /* This can afford to be reasonably minimal, as it's just the same logic with a
476  * different hash key to fragment_add_seq
477  */
478 static void
479 test_fragment_add_dcerpc_dg(void)
480 {
481     e_uuid_t act_id = {1,2,3,{4,5,6,7,8,9,10,11}};
482
483     fragment_data *fd_head, *fdh0;
484     GHashTable *fragment_table = NULL;
485
486     printf("Starting test test_fragment_add_dcerpc_dg\n");
487
488     /* we need our own fragment table */
489     dcerpc_fragment_table_init(&fragment_table);
490     fd_head=fragment_add_dcerpc_dg(tvb, 10, &pinfo, 12, &act_id, fragment_table,
491                                    0, 50, TRUE);
492
493     ASSERT_EQ(1,g_hash_table_size(fragment_table));
494     ASSERT_EQ(NULL,fd_head);
495
496     /* start another pdu (just to confuse things) */
497     pinfo.fd->num = 2;
498     fd_head=fragment_add_dcerpc_dg(tvb, 15, &pinfo, 13, &act_id, fragment_table,
499                              0, 60, TRUE);
500     ASSERT_EQ(2,g_hash_table_size(fragment_table));
501     ASSERT_EQ(NULL,fd_head);
502
503     /* another pdu, with the same fragment_id, but a different act_id, to the
504      * first one */
505     pinfo.fd->num = 3;
506     act_id.Data1=2;
507     fd_head=fragment_add_dcerpc_dg(tvb, 15, &pinfo, 12, &act_id, fragment_table,
508                                    0, 60, TRUE);
509     ASSERT_EQ(3,g_hash_table_size(fragment_table));
510     ASSERT_EQ(NULL,fd_head);
511     act_id.Data1=1;
512
513     /* now we add the terminal fragment of the first datagram */
514     pinfo.fd->num = 4;
515     fd_head=fragment_add_dcerpc_dg(tvb, 5, &pinfo, 12, &act_id, fragment_table,
516                                    1, 60, FALSE);
517
518     ASSERT_EQ(3,g_hash_table_size(fragment_table));
519     ASSERT_NE(NULL,fd_head);
520
521     /* check the contents of the structure */
522     ASSERT_EQ(0,fd_head->frame);  /* unused */
523     ASSERT_EQ(0,fd_head->offset); /* unused */
524     ASSERT_EQ(110,fd_head->len); /* the length of data we have */
525     ASSERT_EQ(1,fd_head->datalen); /* seqno of the last fragment we have */
526     ASSERT_EQ(4,fd_head->reassembled_in);
527     ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET,fd_head->flags);
528     ASSERT_NE(NULL,fd_head->data);
529     ASSERT_NE(NULL,fd_head->next);
530
531     /* test the actual reassembly */
532     ASSERT(!memcmp(fd_head->data,data+10,50));
533     ASSERT(!memcmp(fd_head->data+50,data+5,60));
534
535     /* what happens if we revisit the packets now? */
536     fdh0 = fd_head;
537     pinfo.fd->flags.visited = 1;
538     pinfo.fd->num = 1;
539     fd_head=fragment_add_dcerpc_dg(tvb, 10, &pinfo, 12, &act_id, fragment_table,
540                                    0, 50, TRUE);
541     /*
542      * this api relies on the caller to check fd_head -> reassembled_in
543      *
544      * Redoing all the tests seems like overkill - just check the pointer
545      */
546     ASSERT_EQ(fdh0,fd_head);
547 }
548
549 /**********************************************************************************
550  *
551  * fragment_add_seq_check
552  *
553  *********************************************************************************/
554
555
556 /* This routine is used for both fragment_add_seq_802_11 and
557  * fragment_add_seq_check.
558  *
559  * Adds a couple of out-of-order fragments and checks their reassembly.
560  */
561 static void
562 test_fragment_add_seq_check_work(fragment_data *(*fn)(tvbuff_t *, const int,
563                                  const packet_info *, const guint32, GHashTable *,
564                                  GHashTable *, const guint32, const guint32, const gboolean))
565 {
566     fragment_data *fd_head;
567
568     pinfo.fd -> num = 1;
569     fd_head=fn(tvb, 10, &pinfo, 12, fragment_table,
570                reassembled_table, 0, 50, TRUE);
571
572     ASSERT_EQ(1,g_hash_table_size(fragment_table));
573     ASSERT_EQ(0,g_hash_table_size(reassembled_table));
574     ASSERT_EQ(NULL,fd_head);
575
576     /* start another pdu (just to confuse things) */
577     pinfo.fd->num = 2;
578     fd_head=fn(tvb, 15, &pinfo, 13, fragment_table,
579                reassembled_table, 0, 60, TRUE);
580     ASSERT_EQ(2,g_hash_table_size(fragment_table));
581     ASSERT_EQ(0,g_hash_table_size(reassembled_table));
582     ASSERT_EQ(NULL,fd_head);
583
584     /* add the terminal fragment of the first datagram */
585     pinfo.fd->num = 3;
586     fd_head=fn(tvb, 5, &pinfo, 12, fragment_table,
587                reassembled_table, 2, 60, FALSE);
588
589     /* we haven't got all the fragments yet ... */
590     ASSERT_EQ(2,g_hash_table_size(fragment_table));
591     ASSERT_EQ(0,g_hash_table_size(reassembled_table));
592     ASSERT_EQ(NULL,fd_head);
593
594     /* finally, add the missing fragment */
595     pinfo.fd->num = 4;
596     fd_head=fn(tvb, 15, &pinfo, 12, fragment_table,
597                reassembled_table, 1, 60, TRUE);
598
599     ASSERT_EQ(1,g_hash_table_size(fragment_table));
600     ASSERT_EQ(3,g_hash_table_size(reassembled_table));
601     ASSERT_NE(NULL,fd_head);
602
603     /* check the contents of the structure */
604     ASSERT_EQ(0,fd_head->frame);  /* unused */
605     ASSERT_EQ(0,fd_head->offset); /* unused */
606     ASSERT_EQ(170,fd_head->len); /* the length of data we have */
607     ASSERT_EQ(2,fd_head->datalen); /* seqno of the last fragment we have */
608     ASSERT_EQ(4,fd_head->reassembled_in);
609     ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET,fd_head->flags);
610     ASSERT_NE(NULL,fd_head->data);
611     ASSERT_NE(NULL,fd_head->next);
612
613     ASSERT_EQ(1,fd_head->next->frame);
614     ASSERT_EQ(0,fd_head->next->offset);  /* seqno */
615     ASSERT_EQ(50,fd_head->next->len);    /* segment length */
616     ASSERT_EQ(0,fd_head->next->flags);
617     ASSERT_EQ(NULL,fd_head->next->data);
618     ASSERT_NE(NULL,fd_head->next->next);
619
620     ASSERT_EQ(4,fd_head->next->next->frame);
621     ASSERT_EQ(1,fd_head->next->next->offset);  /* seqno */
622     ASSERT_EQ(60,fd_head->next->next->len);    /* segment length */
623     ASSERT_EQ(0,fd_head->next->next->flags);
624     ASSERT_EQ(NULL,fd_head->next->next->data);
625     ASSERT_NE(NULL,fd_head->next->next->next);
626
627     ASSERT_EQ(3,fd_head->next->next->next->frame);
628     ASSERT_EQ(2,fd_head->next->next->next->offset);  /* seqno */
629     ASSERT_EQ(60,fd_head->next->next->next->len);    /* segment length */
630     ASSERT_EQ(0,fd_head->next->next->next->flags);
631     ASSERT_EQ(NULL,fd_head->next->next->next->data);
632     ASSERT_EQ(NULL,fd_head->next->next->next->next);
633
634     /* test the actual reassembly */
635     ASSERT(!memcmp(fd_head->data,data+10,50));
636     ASSERT(!memcmp(fd_head->data+50,data+15,60));
637     ASSERT(!memcmp(fd_head->data+110,data+5,60));
638 }
639
640 /* Simple test case for fragment_add_seq_check
641  */
642 static void
643 test_fragment_add_seq_check(void)
644 {
645     printf("Starting test test_fragment_add_seq_check\n");
646
647     test_fragment_add_seq_check_work(fragment_add_seq_check);
648 }
649
650
651 /* This tests the case that the 802.11 hack does something different for: when
652  * the terminal segment in a fragmented datagram arrives first.
653  */
654 static void
655 test_fragment_add_seq_check_1(void)
656 {
657     fragment_data *fd_head;
658
659     printf("Starting test test_fragment_add_seq_check_1\n");
660
661     pinfo.fd->num = 1;
662     fd_head=fragment_add_seq_check(tvb, 10, &pinfo, 12, fragment_table,
663                                    reassembled_table, 1, 50, FALSE);
664
665     ASSERT_EQ(1,g_hash_table_size(fragment_table));
666     ASSERT_EQ(0,g_hash_table_size(reassembled_table));
667     ASSERT_EQ(NULL,fd_head);
668
669     /* Now add the missing segment */
670     pinfo.fd->num = 2;
671     fd_head=fragment_add_seq_check(tvb, 5, &pinfo, 12, fragment_table,
672                                    reassembled_table, 0, 60, TRUE);
673
674     ASSERT_EQ(0,g_hash_table_size(fragment_table));
675     ASSERT_EQ(2,g_hash_table_size(reassembled_table));
676     ASSERT_NE(NULL,fd_head);
677
678     /* check the contents of the structure */
679     ASSERT_EQ(0,fd_head->frame);  /* unused */
680     ASSERT_EQ(0,fd_head->offset); /* unused */
681     ASSERT_EQ(110,fd_head->len); /* the length of data we have */
682     ASSERT_EQ(1,fd_head->datalen); /* seqno of the last fragment we have */
683     ASSERT_EQ(2,fd_head->reassembled_in);
684     ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET,fd_head->flags);
685     ASSERT_NE(NULL,fd_head->data);
686     ASSERT_NE(NULL,fd_head->next);
687
688     ASSERT_EQ(2,fd_head->next->frame);
689     ASSERT_EQ(0,fd_head->next->offset);  /* seqno */
690     ASSERT_EQ(60,fd_head->next->len);    /* segment length */
691     ASSERT_EQ(0,fd_head->next->flags);
692     ASSERT_EQ(NULL,fd_head->next->data);
693     ASSERT_NE(NULL,fd_head->next->next);
694
695     ASSERT_EQ(1,fd_head->next->next->frame);
696     ASSERT_EQ(1,fd_head->next->next->offset);  /* seqno */
697     ASSERT_EQ(50,fd_head->next->next->len);    /* segment length */
698     ASSERT_EQ(0,fd_head->next->next->flags);
699     ASSERT_EQ(NULL,fd_head->next->next->data);
700     ASSERT_EQ(NULL,fd_head->next->next->next);
701
702     /* test the actual reassembly */
703     ASSERT(!memcmp(fd_head->data,data+5,60));
704     ASSERT(!memcmp(fd_head->data+60,data+10,50));
705 }
706
707 /**********************************************************************************
708  *
709  * fragment_add_seq_802_11
710  *
711  *********************************************************************************/
712
713 /* Tests the 802.11 hack.
714  */
715 static void
716 test_fragment_add_seq_802_11_0(void)
717 {
718     fragment_data *fd_head;
719
720     printf("Starting test test_fragment_add_seq_802_11_0\n");
721
722     /* the 802.11 hack is that some non-fragmented datagrams have non-zero
723      * fragment_number; test for this. */
724
725     pinfo.fd->num = 1;
726     fd_head=fragment_add_seq_802_11(tvb, 10, &pinfo, 12, fragment_table,
727                                     reassembled_table, 10, 50, FALSE);
728
729     ASSERT_EQ(0,g_hash_table_size(fragment_table));
730     ASSERT_EQ(1,g_hash_table_size(reassembled_table));
731     ASSERT_NE(NULL,fd_head);
732
733     /* check the contents of the structure */
734     ASSERT_EQ(0,fd_head->frame);  /* unused */
735     ASSERT_EQ(0,fd_head->offset); /* unused */
736     ASSERT_EQ(0,fd_head->len);    /* unused */
737     ASSERT_EQ(0,fd_head->datalen); /* unused */
738     ASSERT_EQ(1,fd_head->reassembled_in);
739     ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE,fd_head->flags);
740     ASSERT_EQ(NULL,fd_head->data);
741     ASSERT_EQ(NULL,fd_head->next);
742 }
743
744 /* Reuse the fragment_add_seq_check testcases */
745 static void test_fragment_add_seq_802_11_1(void)
746 {
747     printf("Starting test test_fragment_add_seq_802_11_1\n");
748     test_fragment_add_seq_check_work(fragment_add_seq_802_11);
749 }
750
751 /**********************************************************************************
752  *
753  * fragment_add_seq_next
754  *
755  *********************************************************************************/
756
757 /* Simple test case for fragment_add_seq_next.
758  * Adds a couple of fragments (with one for a different datagram in between),
759  * and checks that they are reassembled correctly.
760  */
761 static void
762 test_simple_fragment_add_seq_next(void)
763 {
764     fragment_data *fd_head;
765
766     printf("Starting test test_simple_fragment_add_seq_next\n");
767
768     pinfo.fd->num = 1;
769     fd_head=fragment_add_seq_next(tvb, 10, &pinfo, 12, fragment_table,
770                                   reassembled_table, 50, TRUE);
771
772     ASSERT_EQ(1,g_hash_table_size(fragment_table));
773     ASSERT_EQ(0,g_hash_table_size(reassembled_table));
774     ASSERT_EQ(NULL,fd_head);
775
776     /* adding the same fragment again should do nothing, even with different
777      * offset etc */
778     pinfo.fd->flags.visited = 1;
779     fd_head=fragment_add_seq_next(tvb, 5, &pinfo, 12, fragment_table,
780                                   reassembled_table, 60, TRUE);
781     ASSERT_EQ(1,g_hash_table_size(fragment_table));
782     ASSERT_EQ(0,g_hash_table_size(reassembled_table));
783     ASSERT_EQ(NULL,fd_head);
784
785     /* start another pdu (just to confuse things) */
786     pinfo.fd->flags.visited = 0;
787     pinfo.fd->num = 2;
788     fd_head=fragment_add_seq_next(tvb, 15, &pinfo, 13, fragment_table,
789                                   reassembled_table, 60, TRUE);
790     ASSERT_EQ(2,g_hash_table_size(fragment_table));
791     ASSERT_EQ(0,g_hash_table_size(reassembled_table));
792     ASSERT_EQ(NULL,fd_head);
793
794
795     /* now we add the terminal fragment of the first datagram */
796     pinfo.fd->num = 3;
797     fd_head=fragment_add_seq_next(tvb, 5, &pinfo, 12, fragment_table,
798                                   reassembled_table, 60, FALSE);
799
800     ASSERT_EQ(1,g_hash_table_size(fragment_table));
801     ASSERT_EQ(2,g_hash_table_size(reassembled_table));
802     ASSERT_NE(NULL,fd_head);
803
804     /* check the contents of the structure */
805     ASSERT_EQ(0,fd_head->frame);  /* unused */
806     ASSERT_EQ(0,fd_head->offset); /* unused */
807     ASSERT_EQ(110,fd_head->len); /* the length of data we have */
808     ASSERT_EQ(1,fd_head->datalen); /* seqno of the last fragment we have */
809     ASSERT_EQ(3,fd_head->reassembled_in);
810     ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET,fd_head->flags);
811     ASSERT_NE(NULL,fd_head->data);
812     ASSERT_NE(NULL,fd_head->next);
813
814     ASSERT_EQ(1,fd_head->next->frame);
815     ASSERT_EQ(0,fd_head->next->offset);  /* seqno */
816     ASSERT_EQ(50,fd_head->next->len);    /* segment length */
817     ASSERT_EQ(0,fd_head->next->flags);
818     ASSERT_EQ(NULL,fd_head->next->data);
819     ASSERT_NE(NULL,fd_head->next->next);
820
821     ASSERT_EQ(3,fd_head->next->next->frame);
822     ASSERT_EQ(1,fd_head->next->next->offset);  /* seqno */
823     ASSERT_EQ(60,fd_head->next->next->len);    /* segment length */
824     ASSERT_EQ(0,fd_head->next->next->flags);
825     ASSERT_EQ(NULL,fd_head->next->next->data);
826     ASSERT_EQ(NULL,fd_head->next->next->next);
827
828     /* test the actual reassembly */
829     ASSERT(!memcmp(fd_head->data,data+10,50));
830     ASSERT(!memcmp(fd_head->data+50,data+5,60));
831 }
832
833
834 /* This tests the case where some data is missing from one of the fragments.
835  * It should prevent reassembly.
836  */
837 static void
838 test_missing_data_fragment_add_seq_next(void)
839 {
840     fragment_data *fd_head;
841
842     printf("Starting test test_missing_data_fragment_add_seq_next\n");
843
844     /* attempt to add a fragment which is longer than the data available */
845     pinfo.fd->num = 1;
846     fd_head=fragment_add_seq_next(tvb, 10, &pinfo, 12, fragment_table,
847                                   reassembled_table, DATA_LEN-9, TRUE);
848
849     ASSERT_EQ(1,g_hash_table_size(fragment_table));
850     ASSERT_EQ(0,g_hash_table_size(reassembled_table));
851     ASSERT_NE(NULL,fd_head);
852
853     /* check the contents of the structure. Reassembly failed so everything
854      * should be null (meaning, just use the original tvb)  */
855     ASSERT_EQ(0,fd_head->frame);  /* unused */
856     ASSERT_EQ(0,fd_head->offset); /* unused */
857     ASSERT_EQ(0,fd_head->len); /* the length of data we have */
858     ASSERT_EQ(0,fd_head->datalen); /* seqno of the last fragment we have */
859     ASSERT_EQ(0,fd_head->reassembled_in);
860     ASSERT_EQ(FD_BLOCKSEQUENCE,fd_head->flags & 0x1ff);
861     ASSERT_EQ(NULL,fd_head->data);
862     ASSERT_EQ(NULL,fd_head->next);
863
864     /* add another fragment (with all data present) */
865     pinfo.fd->num = 4;
866     fd_head=fragment_add_seq_next(tvb, 5, &pinfo, 12, fragment_table,
867                                   reassembled_table, 60, FALSE);
868
869     /* XXX: it's not clear that this is the right result; however it's what the
870      * code does...
871      */
872     ASSERT_EQ(1,g_hash_table_size(fragment_table));
873     ASSERT_EQ(0,g_hash_table_size(reassembled_table));
874     ASSERT_EQ(NULL,fd_head);
875
876
877     /* check what happens when we revisit the packets */
878     pinfo.fd->flags.visited = TRUE;
879     pinfo.fd->num = 1;
880
881     fd_head=fragment_add_seq_next(tvb, 10, &pinfo, 12, fragment_table,
882                                   reassembled_table, DATA_LEN-9, TRUE);
883
884     /* We just look in the reassembled_table for this packet. It never got put
885      * there, so this always returns null.
886      *
887      * That's crazy, because it means that the subdissector will see the data
888      * exactly once - on the first pass through the capture (well, assuming it
889      * doesn't bother to check fd_head->reassembled_in); however, that's
890      * what the code does...
891      */
892     ASSERT_EQ(1,g_hash_table_size(fragment_table));
893     ASSERT_EQ(0,g_hash_table_size(reassembled_table));
894     ASSERT_EQ(NULL,fd_head);
895
896     pinfo.fd->num = 4;
897     fd_head=fragment_add_seq_next(tvb, 5, &pinfo, 12, fragment_table,
898                                   reassembled_table, 60, FALSE);
899     ASSERT_EQ(1,g_hash_table_size(fragment_table));
900     ASSERT_EQ(0,g_hash_table_size(reassembled_table));
901     ASSERT_EQ(NULL,fd_head);
902 }
903
904
905 /*
906  * we're going to do something similar now, but this time it is the second
907  * fragment which has something missing.
908  */
909 static void
910 test_missing_data_fragment_add_seq_next_2(void)
911 {
912     fragment_data *fd_head;
913
914     printf("Starting test test_missing_data_fragment_add_seq_next_2\n");
915
916     pinfo.fd->num = 11;
917     fd_head=fragment_add_seq_next(tvb, 10, &pinfo, 24, fragment_table,
918                                   reassembled_table, 50, TRUE);
919
920     ASSERT_EQ(1,g_hash_table_size(fragment_table));
921     ASSERT_EQ(0,g_hash_table_size(reassembled_table));
922     ASSERT_EQ(NULL,fd_head);
923
924     pinfo.fd->num = 12;
925     fd_head=fragment_add_seq_next(tvb, 5, &pinfo, 24, fragment_table,
926                                   reassembled_table, DATA_LEN-4, FALSE);
927
928     /* XXX: again, i'm really dubious about this. Surely this should return all
929      * the data we had, for a best-effort attempt at dissecting it?
930      * And it ought to go into the reassembled table?
931      */
932     ASSERT_EQ(0,g_hash_table_size(fragment_table));
933     ASSERT_EQ(0,g_hash_table_size(reassembled_table));
934     ASSERT_EQ(NULL,fd_head);
935
936     /* check what happens when we revisit the packets */
937     pinfo.fd->flags.visited = TRUE;
938     pinfo.fd->num = 11;
939
940     fd_head=fragment_add_seq_next(tvb, 10, &pinfo, 24, fragment_table,
941                                   reassembled_table, 50, TRUE);
942
943     /* As before, this returns NULL because the fragment isn't in the
944      * reassembled_table. At least this is a bit more consistent than before.
945      */
946     ASSERT_EQ(0,g_hash_table_size(fragment_table));
947     ASSERT_EQ(0,g_hash_table_size(reassembled_table));
948     ASSERT_EQ(NULL,fd_head);
949
950     pinfo.fd->num = 12;
951     fd_head=fragment_add_seq_next(tvb, 5, &pinfo, 24, fragment_table,
952                                   reassembled_table, DATA_LEN-4, FALSE);
953     ASSERT_EQ(0,g_hash_table_size(fragment_table));
954     ASSERT_EQ(0,g_hash_table_size(reassembled_table));
955     ASSERT_EQ(NULL,fd_head);
956
957 }
958
959 /*
960  * This time, our datagram only has one segment, but it has data missing.
961  */
962 static void
963 test_missing_data_fragment_add_seq_next_3(void)
964 {
965     fragment_data *fd_head;
966
967     printf("Starting test test_missing_data_fragment_add_seq_next_3\n");
968
969     pinfo.fd->num = 20;
970     fd_head=fragment_add_seq_next(tvb, 5, &pinfo, 30, fragment_table,
971                                   reassembled_table, DATA_LEN-4, FALSE);
972
973     ASSERT_EQ(0,g_hash_table_size(fragment_table));
974     ASSERT_EQ(1,g_hash_table_size(reassembled_table));
975     ASSERT_NE(NULL,fd_head);
976
977     /* check the contents of the structure. */
978     ASSERT_EQ(0,fd_head->frame);  /* unused */
979     ASSERT_EQ(0,fd_head->offset); /* unused */
980     ASSERT_EQ(0,fd_head->len); /* the length of data we have */
981     ASSERT_EQ(0,fd_head->datalen); /* seqno of the last fragment we have */
982     ASSERT_EQ(20,fd_head->reassembled_in);
983     ASSERT_EQ(FD_BLOCKSEQUENCE|FD_DEFRAGMENTED,fd_head->flags);
984     ASSERT_EQ(NULL,fd_head->data);
985     ASSERT_EQ(NULL,fd_head->next);
986
987     /* revisiting the packet ought to produce the same result. */
988     pinfo.fd->flags.visited = TRUE;
989
990     pinfo.fd->num = 20;
991     fd_head=fragment_add_seq_next(tvb, 5, &pinfo, 30, fragment_table,
992                                   reassembled_table, DATA_LEN-4, FALSE);
993
994     ASSERT_EQ(0,g_hash_table_size(fragment_table));
995     ASSERT_EQ(1,g_hash_table_size(reassembled_table));
996     ASSERT_NE(NULL,fd_head);
997     ASSERT_EQ(0,fd_head->frame);  /* unused */
998     ASSERT_EQ(0,fd_head->offset); /* unused */
999     ASSERT_EQ(0,fd_head->len); /* the length of data we have */
1000     ASSERT_EQ(0,fd_head->datalen); /* seqno of the last fragment we have */
1001     ASSERT_EQ(20,fd_head->reassembled_in);
1002     ASSERT_EQ(FD_BLOCKSEQUENCE|FD_DEFRAGMENTED,fd_head->flags);
1003     ASSERT_EQ(NULL,fd_head->data);
1004     ASSERT_EQ(NULL,fd_head->next);
1005 }
1006
1007
1008 /**********************************************************************************
1009  *
1010  * main
1011  *
1012  *********************************************************************************/
1013
1014 int
1015 main(int argc _U_, char **argv _U_)
1016 {
1017     frame_data fd;
1018     char src[] = {1,2,3,4}, dst[] = {5,6,7,8};
1019     unsigned int i;
1020     void (*tests[])(void) = {
1021         test_simple_fragment_add_seq,
1022         test_fragment_add_seq_partial_reassembly,
1023         test_fragment_add_dcerpc_dg,
1024         test_fragment_add_seq_check,
1025         test_fragment_add_seq_check_1,
1026         test_fragment_add_seq_802_11_0,
1027         test_fragment_add_seq_802_11_1,
1028         test_simple_fragment_add_seq_next,
1029         test_missing_data_fragment_add_seq_next,
1030         test_missing_data_fragment_add_seq_next_2,
1031         test_missing_data_fragment_add_seq_next_3
1032     };
1033
1034     /* initialise stuff */
1035     emem_init();
1036     tvbuff_init();
1037     reassemble_init();
1038
1039     /* a tvbuff for testing with */
1040     data = g_malloc(DATA_LEN);
1041     /* make sure it's full of stuff */
1042     for(i=0; i<DATA_LEN; i++) {
1043         data[i]=i & 0xFF;
1044     }
1045     tvb = tvb_new_real_data(data, DATA_LEN, DATA_LEN*2);
1046
1047     /* other test stuff */
1048     pinfo.fd = &fd;
1049     fd.flags.visited = 0;
1050     SET_ADDRESS(&pinfo.src,AT_IPv4,4,src);
1051     SET_ADDRESS(&pinfo.dst,AT_IPv4,4,dst);
1052
1053     /*************************************************************************/
1054     for(i=0; i < sizeof(tests)/sizeof(tests[0]); i++ ) {
1055         /* re-init the fragment tables */
1056         fragment_table_init(&fragment_table);
1057         ASSERT(fragment_table != NULL);
1058
1059         reassembled_table_init(&reassembled_table);
1060         ASSERT(reassembled_table != NULL);
1061
1062         pinfo.fd->flags.visited = FALSE;
1063
1064         tests[i]();
1065     }
1066
1067     printf(failure?"FAILURE\n":"SUCCESS\n");
1068     return failure;
1069 }
1070
1071
1072 /* stubs */
1073 void add_new_data_source(packet_info *pinfo _U_, tvbuff_t *tvb _U_,
1074                         const char *name _U_)
1075 {}
1076
1077 proto_item *
1078 proto_tree_add_uint(proto_tree *tree _U_, int hfindex _U_, tvbuff_t *tvb _U_,
1079                     gint start _U_, gint length _U_, guint32 value _U_)
1080 { return NULL; }
1081
1082 void proto_item_prepend_text(proto_item *ti _U_, const char *format _U_, ...)
1083 {}
1084
1085 void proto_item_append_text(proto_item *ti _U_, const char *format _U_, ...)
1086 {}
1087
1088 proto_item *proto_tree_add_uint_format(proto_tree *tree _U_, int hfindex _U_,
1089                                        tvbuff_t *tvb _U_, gint start _U_,
1090                                        gint length _U_, guint32 value _U_,
1091                                        const char *format _U_, ...)
1092 { return NULL; }
1093
1094 proto_tree* proto_item_add_subtree(proto_item *ti _U_, const gint idx _U_)
1095 { return NULL; }
1096
1097 proto_item *proto_tree_add_boolean(proto_tree *tree _U_, int hfindex _U_,
1098                                    tvbuff_t *tvb _U_, gint start _U_,
1099                                    gint length _U_, guint32 value _U_)
1100 { return NULL; }
1101
1102 proto_item *proto_tree_add_item(proto_tree *tree _U_, const int hfindex _U_,
1103                                 tvbuff_t *tvb _U_, const gint start _U_,
1104                                 gint length _U_,
1105                                 const guint encoding _U_)
1106 { return NULL; }
1107
1108 gint check_col(column_info *cinfo _U_, const gint col _U_)
1109 { return 0; }
1110
1111 void col_add_fstr(column_info *cinfo _U_, const gint col _U_, const gchar *format _U_,
1112                        ...)
1113 {}
1114
1115 const char* proto_registrar_get_name(const int n _U_)
1116 { return ""; }
1117
1118 void proto_item_set_text(proto_item *ti _U_, const char *format _U_, ...)
1119 { }