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