~ubuntu-branches/ubuntu/gutsy/wireshark/gutsy-security

« back to all changes in this revision

Viewing changes to epan/wslua/wslua_tvb.c

  • Committer: Bazaar Package Importer
  • Author(s): Frederic Peters
  • Date: 2007-04-01 08:58:40 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20070401085840-or3qhrpv8alt1bwg
Tags: 0.99.5-1
* New upstream release.
* debian/patches/09_idl2wrs.dpatch: updated to patch idl2wrs.sh.in.

Show diffs side-by-side

added added

removed removed

Lines of Context:
5
5
 *
6
6
 * (c) 2006, Luis E. Garcia Ontanon <luis.ontanon@gmail.com>
7
7
 *
8
 
 * $Id: wslua_tvb.c 19676 2006-10-24 22:21:04Z gerald $
 
8
 * $Id: wslua_tvb.c 20628 2007-01-30 19:19:21Z gerald $
9
9
 *
10
10
 * Wireshark - Network traffic analyzer
11
11
 * By Gerald Combs <gerald@wireshark.org>
42
42
 
43
43
    if (lua_gettop(L) == 1) {
44
44
        s = luaL_checkstring(L,WSLUA_OPTARG_ByteArray_new_HEXBYTES);
45
 
        
 
45
 
46
46
        if (!s) {
47
47
            WSLUA_OPTARG_ERROR(ByteArray_new,HEXBYTES,"must be a string");
48
48
            return 0;
49
49
        }
50
 
        
 
50
 
51
51
        /* XXX: slow! */
52
52
        for (; (c = *s); s++) {
53
53
            switch(c) {
70
70
                i = 0;
71
71
            }
72
72
        }
73
 
    } 
74
 
    
 
73
    }
 
74
 
75
75
    pushByteArray(L,ba);
76
76
 
77
77
    WSLUA_RETURN(1); /* The new ByteArray object. */
81
81
    ByteArray ba = checkByteArray(L,1);
82
82
 
83
83
    if (!ba) return 0;
84
 
    
 
84
 
85
85
    g_byte_array_free(ba,TRUE);
86
86
    return 0;
87
87
}
88
88
 
89
89
WSLUA_METAMETHOD ByteArray__concat(lua_State* L) {
90
90
        /* concatenate two ByteArrays */
91
 
#define WSLUA_ARG_ByteArray__cat_FIRST 1
92
 
#define WSLUA_ARG_ByteArray__cat_SECOND 1
93
 
        
 
91
#define WSLUA_ARG_ByteArray__cat_FIRST 1 /* first array */
 
92
#define WSLUA_ARG_ByteArray__cat_SECOND 1 /* second array */
 
93
 
94
94
    ByteArray ba = checkByteArray(L,1);
95
95
    ByteArray ba2 = checkByteArray(L,2);
96
96
 
97
97
        if (! (ba  && ba2) )
98
98
                WSLUA_ERROR(ByteArray__cat,"both arguments must be ByteArrays");
99
 
        
 
99
 
100
100
    g_byte_array_append(ba,ba2->data,ba2->len);
101
101
 
102
102
    pushByteArray(L,ba);
105
105
 
106
106
WSLUA_METHOD ByteArray_prepend(lua_State* L) {
107
107
        /* prepend a ByteArray to this ByteArray */
108
 
#define WSLUA_ARG_ByteArray_prepend_PREPENDED 2
 
108
#define WSLUA_ARG_ByteArray_prepend_PREPENDED 2 /* array to be prepended */
109
109
    ByteArray ba = checkByteArray(L,1);
110
110
    ByteArray ba2 = checkByteArray(L,2);
111
 
    
 
111
 
112
112
        if (! (ba  && ba2) )
113
113
                WSLUA_ERROR(ByteArray_prepend,"both arguments must be ByteArrays");
114
114
 
115
115
    g_byte_array_prepend(ba,ba2->data,ba2->len);
116
 
    
 
116
 
117
117
    pushByteArray(L,ba);
118
118
    return 1;
119
119
}
120
120
 
121
121
WSLUA_METHOD ByteArray_append(lua_State* L) {
122
122
        /* append a ByteArray to this ByteArray */
123
 
#define WSLUA_ARG_ByteArray_append_APPENDED 2
 
123
#define WSLUA_ARG_ByteArray_append_APPENDED 2 /* array to be appended */
124
124
    ByteArray ba = checkByteArray(L,1);
125
125
    ByteArray ba2 = checkByteArray(L,2);
126
 
    
 
126
 
127
127
        if (! (ba  && ba2) )
128
128
                WSLUA_ERROR(ByteArray_prepend,"both arguments must be ByteArrays");
129
 
        
 
129
 
130
130
    g_byte_array_prepend(ba,ba2->data,ba2->len);
131
 
    
 
131
 
132
132
    pushByteArray(L,ba);
133
133
    return 1;
134
134
}
135
135
 
136
136
WSLUA_METHOD ByteArray_set_size(lua_State* L) {
137
137
        /* Sets the size of a ByteArray, either truncating it or filling it with zeros. */
138
 
#define WSLUA_ARG_ByteArray_set_size_SIZE 2
 
138
#define WSLUA_ARG_ByteArray_set_size_SIZE 2 /* new size of the array*/
139
139
 
140
140
    ByteArray ba = checkByteArray(L,1);
141
141
    int siz = luaL_checkint(L,2);
153
153
    ByteArray ba = checkByteArray(L,1);
154
154
    int idx = luaL_checkint(L,2);
155
155
    int v = luaL_checkint(L,3);
156
 
    
 
156
 
157
157
    if (!ba) return 0;
158
158
 
159
159
    if (idx == 0 && ! g_str_equal(luaL_optstring(L,2,""),"0") ) {
160
160
        luaL_argerror(L,2,"bad index");
161
161
        return 0;
162
162
    }
163
 
    
 
163
 
164
164
    if (idx < 0 || (guint)idx >= ba->len) {
165
165
            luaL_argerror(L,2,"index out of range");
166
166
            return 0;
170
170
        luaL_argerror(L,3,"Byte out of range");
171
171
        return 0;
172
172
    }
173
 
    
 
173
 
174
174
    ba->data[idx] = (guint8)v;
175
 
    
 
175
 
176
176
    return 0;
177
177
}
178
178
 
182
182
#define WSLUA_ARG_ByteArray_set_index_INDEX 2 /* the position of the byte to be set */
183
183
    ByteArray ba = checkByteArray(L,1);
184
184
    int idx = luaL_checkint(L,2);
185
 
    
 
185
 
186
186
    if (!ba) return 0;
187
 
    
 
187
 
188
188
    if (idx == 0 && ! g_str_equal(luaL_optstring(L,2,""),"0") ) {
189
189
        luaL_argerror(L,2,"bad index");
190
190
        return 0;
191
191
    }
192
 
    
 
192
 
193
193
    if (idx < 0 || (guint)idx >= ba->len) {
194
194
        luaL_argerror(L,2,"index out of range");
195
195
        return 0;
196
196
    }
197
197
    lua_pushnumber(L,ba->data[idx]);
198
 
    
 
198
 
199
199
    WSLUA_RETURN(1); /* The value [0-255] of the byte. */
200
200
}
201
201
 
202
202
WSLUA_METHOD ByteArray_len(lua_State* L) {
203
203
        /* obtain the length of a ByteArray */
204
204
    ByteArray ba = checkByteArray(L,1);
205
 
    
 
205
 
206
206
    if (!ba) return 0;
207
 
    
 
207
 
208
208
    lua_pushnumber(L,(lua_Number)ba->len);
209
209
 
210
210
    WSLUA_RETURN(1); /* The length of the ByteArray. */
220
220
    ByteArray sub;
221
221
 
222
222
    if (!ba) return 0;
223
 
    
 
223
 
224
224
    if ((offset + len) > (int)ba->len || offset < 0 || len < 1) {
225
225
        luaL_error(L,"Out Of Bounds");
226
226
        return 0;
228
228
 
229
229
    sub = g_byte_array_new();
230
230
    g_byte_array_append(sub,ba->data + offset,len);
231
 
    
 
231
 
232
232
    pushByteArray(L,sub);
233
 
    
 
233
 
234
234
    WSLUA_RETURN(1); /* a ByteArray contaning the requested segment. */
235
235
}
236
236
 
257
257
    ByteArray ba = checkByteArray(L,1);
258
258
    int i;
259
259
    GString* s;
260
 
    
 
260
 
261
261
    if (!ba) return 0;
262
 
    
 
262
 
263
263
    s = g_string_new("");
264
 
    
 
264
 
265
265
    for (i = 0; i < (int)ba->len; i++) {
266
266
        g_string_append(s,byte_to_str[(ba->data)[i]]);
267
267
    }
268
 
    
 
268
 
269
269
    lua_pushstring(L,s->str);
270
270
    g_string_free(s,TRUE);
271
 
    
 
271
 
272
272
    WSLUA_RETURN(1); /* a string contaning a representaion of the ByteArray. */
273
273
}
274
274
 
304
304
/*
305
305
 * Tvb & TvbRange
306
306
 *
307
 
 * a Tvb represents a tvbuff_t in Lua. 
308
 
 * a TvbRange represents a range in a tvb (tvb,offset,lenght) it's main purpose is to do bounds checking, 
 
307
 * a Tvb represents a tvbuff_t in Lua.
 
308
 * a TvbRange represents a range in a tvb (tvb,offset,lenght) it's main purpose is to do bounds checking,
309
309
 *            it helps too simplifing argument passing to Tree. In wireshark terms this is worthless nothing
310
310
 *            not already done by the TVB itself. In lua's terms is necessary to avoid abusing TRY{}CATCH(){}
311
 
 *            via preemptive bounds checking. 
 
311
 *            via preemptive bounds checking.
312
312
 *
313
313
 * These lua objects have to be "NULLified after use", that is, we cannot leave pointers in the
314
 
 * lua machine to a tvb or a tvbr that might exist anymore. 
 
314
 * lua machine to a tvb or a tvbr that might exist anymore.
315
315
 *
316
 
 * To do so we are going to keep a pointer to every "box" in which lua has placed a pointer to our object 
 
316
 * To do so we are going to keep a pointer to every "box" in which lua has placed a pointer to our object
317
317
 * and then NULLify the object lua points to.
318
318
 *
319
319
 * Other than that we are going to check every instance of a potentialy NULLified object before using it
324
324
/* a Tvb represents the packet's buffer. It is passed as an argument to listeners and dissectors,
325
325
and can be used to extract information (via TvbRange) from the packet's data. Beware that Tvbs are usable only by the current
326
326
listener or dissector call and are destroyed as soon as the listener/dissector returns, so references
327
 
to them are unusable once the function has returned. 
 
327
to them are unusable once the function has returned.
328
328
To create a tvbrange the tvb must be called with offset and length as optional arguments ( the offset defaults to 0 and the length to tvb:len() )*/
329
329
 
330
330
static GPtrArray* outstanding_stuff = NULL;
358
358
    const gchar* name = luaL_optstring(L,2,"Unnamed") ;
359
359
    guint8* data;
360
360
    Tvb tvb;
361
 
    
 
361
 
362
362
    if (!ba) return 0;
363
 
    
 
363
 
364
364
    if (!lua_tvb) {
365
365
        luaL_error(L,"Tvbs can only be created and used in dissectors");
366
366
        return 0;
367
367
    }
368
 
    
 
368
 
369
369
    data = g_memdup(ba->data, ba->len);
370
 
    
 
370
 
371
371
    tvb = tvb_new_real_data(data, ba->len,ba->len);
372
372
    tvb_set_free_cb(tvb, g_free);
373
 
    
 
373
 
374
374
    add_new_data_source(lua_pinfo, tvb, name);
375
375
    PUSH_TVB(L,tvb);
376
376
    WSLUA_RETURN(1); /* the created Tvb. */
381
381
#define WSLUA_ARG_Tvb_new_subset_RANGE 2 /* the TvbRange from which to create the new Tvb. */
382
382
 
383
383
    TvbRange tvbr = checkTvbRange(L,1);
384
 
    
 
384
 
385
385
    if (! tvbr) return 0;
386
 
        
 
386
 
387
387
    if (tvb_offset_exists(tvbr->tvb,  tvbr->offset + tvbr->len -1 )) {
388
388
        PUSH_TVB(L, tvb_new_subset(tvbr->tvb,tvbr->offset,tvbr->len, tvbr->len) );
389
389
        return 1;
398
398
    Tvb tvb = checkTvb(L,1);
399
399
    int len;
400
400
    gchar* str;
401
 
    
 
401
 
402
402
    if (!tvb) return 0;
403
403
 
404
404
    len = tvb_length(tvb);
411
411
WSLUA_METHOD Tvb_len(lua_State* L) {
412
412
        /* obtain the length of a TVB */
413
413
    Tvb tvb = checkTvb(L,1);
414
 
    
 
414
 
415
415
    if (!tvb) return 0;
416
 
    
 
416
 
417
417
    lua_pushnumber(L,tvb_length(tvb));
418
418
    WSLUA_RETURN(1); /* the lenght of the Tvb. */
419
419
}
421
421
WSLUA_METHOD Tvb_offset(lua_State* L) {
422
422
        /* returns the raw offset (from the beginning of the source Tvb) of a sub Tvb. */
423
423
    Tvb tvb = checkTvb(L,1);
424
 
    
 
424
 
425
425
    if (!tvb) return 0;
426
 
        
 
426
 
427
427
    lua_pushnumber(L,TVB_RAW_OFFSET(tvb));
428
428
    WSLUA_RETURN(1); /* the raw offset of the Tvb. */
429
429
}
430
430
 
431
431
 
432
 
static const luaL_reg Tvb_methods[] = {
433
 
    {"len", Tvb_len},
434
 
    {"offset", Tvb_offset},
435
 
    {0,0}
436
 
};
437
 
 
438
 
static int Tvb_range(lua_State* L);
439
 
 
440
 
static const luaL_reg Tvb_meta[] = {
441
 
    {"__call", Tvb_range},
442
 
    {"__tostring", Tvb__tostring},
443
 
    {0, 0}
444
 
};
445
 
 
446
 
int Tvb_register(lua_State* L) {
447
 
        WSLUA_REGISTER_CLASS(Tvb);
448
 
    return 1;
 
432
#if USED_FOR_DOC_PURPOSES
 
433
WSLUA_METAMETHOD Tvb__call(lua_State* L) {
 
434
        /* equivalent to tvb:range(...) */
 
435
        return 0;
449
436
}
 
437
#endif
450
438
 
451
439
WSLUA_CLASS_DEFINE(TvbRange,FAIL_ON_NULL("expired tvbrange"),NOP);
452
440
/*
456
444
 
457
445
TvbRange new_TvbRange(lua_State* L, tvbuff_t* tvb, int offset, int len) {
458
446
    TvbRange tvbr;
459
 
    
 
447
 
460
448
    if (len == -1) {
461
449
        len = tvb_length_remaining(tvb,offset);
462
450
        if (len < 0) {
463
451
            luaL_error(L,"out of bounds");
464
452
            return 0;
465
 
        }        
 
453
        }
466
454
    } else if ( (guint)(len + offset) > tvb_length(tvb)) {
467
455
        luaL_error(L,"Range is out of bounds");
468
456
        return NULL;
469
457
    }
470
 
    
 
458
 
471
459
    tvbr = ep_alloc(sizeof(struct _wslua_tvbrange));
472
460
    tvbr->tvb = tvb;
473
461
    tvbr->offset = offset;
474
462
    tvbr->len = len;
475
 
    
 
463
 
476
464
    return tvbr;
477
465
}
478
466
 
 
467
 
479
468
WSLUA_METHOD Tvb_range(lua_State* L) {
480
469
        /* creates a tvbr from this Tvb. This is used also as the Tvb:__call() metamethod. */
481
470
#define WSLUA_OPTARG_Tvb_range_OFFSET 2 /* The offset (in octets) from the begining of the Tvb. Defaults to 0. */
482
471
#define WSLUA_OPTARG_Tvb_range_LENGTH 2 /* The length (in octets) of the range. Defaults to until the end of the Tvb. */
483
 
        
 
472
 
484
473
    Tvb tvb = checkTvb(L,1);
485
474
    int offset = luaL_optint(L,2,0);
486
475
    int len = luaL_optint(L,3,-1);
492
481
        PUSH_TVBRANGE(L,tvbr);
493
482
                WSLUA_RETURN(1); /* the TvbRange */
494
483
    }
495
 
    
 
484
 
496
485
    return 0;
497
486
}
498
487
 
 
488
static const luaL_reg Tvb_methods[] = {
 
489
    {"range", Tvb_range},
 
490
    {"len", Tvb_len},
 
491
    {"offset", Tvb_offset},
 
492
    {0,0}
 
493
};
 
494
 
 
495
static int Tvb_range(lua_State* L);
 
496
 
 
497
static const luaL_reg Tvb_meta[] = {
 
498
    {"__call", Tvb_range},
 
499
    {"__tostring", Tvb__tostring},
 
500
    {0, 0}
 
501
};
 
502
 
 
503
int Tvb_register(lua_State* L) {
 
504
        WSLUA_REGISTER_CLASS(Tvb);
 
505
    return 1;
 
506
}
499
507
 
500
508
/*
501
509
 *  read access to tvbr's data
502
510
 */
503
511
static int TvbRange_get_index(lua_State* L) {
504
 
        /* WSLUA_ATTRIBUTE TvbRange_tvb RO The Tvb from which this TvbRange was generated */    
505
 
        /* WSLUA_ATTRIBUTE TvbRange_len RW The lenght (in octets) of this TvbRange */   
 
512
        /* WSLUA_ATTRIBUTE TvbRange_tvb RO The Tvb from which this TvbRange was generated */
 
513
        /* WSLUA_ATTRIBUTE TvbRange_len RW The lenght (in octets) of this TvbRange */
506
514
        /* WSLUA_ATTRIBUTE TvbRange_offset RW The offset (in octets) of this TvbRange */
507
515
 
508
516
    TvbRange tvbr = checkTvbRange(L,1);
509
517
    const gchar* index = luaL_checkstring(L,2);
510
 
    
 
518
 
511
519
    if (!(tvbr && index)) return 0;
512
 
    
 
520
 
513
521
    if (g_str_equal(index,"offset")) {
514
522
        lua_pushnumber(L,(lua_Number)tvbr->offset);
515
523
        return 1;
522
530
    } else {
523
531
        luaL_error(L,"TvbRange has no `%s' attribute",index);
524
532
    }
525
 
    
 
533
 
526
534
    return 0;
527
535
}
528
536
 
534
542
    const gchar* index = luaL_checkstring(L,2);
535
543
 
536
544
    if (!tvbr) return 0;
537
 
    
 
545
 
538
546
    if (g_str_equal(index,"offset")) {
539
547
        int offset = (int)lua_tonumber(L,3);
540
 
    
 
548
 
541
549
        if ( (guint)(tvbr->len + offset) > tvb_length(tvbr->tvb)) {
542
550
            luaL_error(L,"out of bounds");
543
551
            return 0;
548
556
        }
549
557
    } else if (g_str_equal(index,"len")) {
550
558
        int len = (int)lua_tonumber(L,3);
551
 
        
 
559
 
552
560
        if ( (guint)(tvbr->offset + len) > tvb_length(tvbr->tvb)) {
553
561
            luaL_error(L,"out of bounds");
554
562
            return 0;
561
569
        luaL_error(L,"cannot set `%s' attribute on TvbRange",index);
562
570
        return 0;
563
571
    }
564
 
    
 
572
 
565
573
    return 0;
566
574
}
567
575
 
573
581
        There's no support yet for 64 bit integers*/
574
582
    TvbRange tvbr = checkTvbRange(L,1);
575
583
    if (!tvbr) return 0;
576
 
    
 
584
 
577
585
    switch (tvbr->len) {
578
586
        case 1:
579
587
            lua_pushnumber(L,tvb_get_guint8(tvbr->tvb,tvbr->offset));
608
616
        There's no support yet for 64 bit integers*/
609
617
    TvbRange tvbr = checkTvbRange(L,1);
610
618
    if (!tvbr) return 0;
611
 
    
 
619
 
612
620
    switch (tvbr->len) {
613
621
        case 1:
614
622
            /* XXX unsigned anyway */
636
644
        /* get a Big Endian (network order) floating point number from a TvbRange. The range must be 4 or 8 octets long. */
637
645
    TvbRange tvbr = checkTvbRange(L,1);
638
646
    if (!tvbr) return 0;
639
 
    
 
647
 
640
648
    switch (tvbr->len) {
641
649
        case 4:
642
650
            lua_pushnumber(L,(double)tvb_get_ntohieee_float(tvbr->tvb,tvbr->offset));
657
665
        /* get a Little Endian floating point number from a TvbRange. The range must be 4 or 8 octets long. */
658
666
    TvbRange tvbr = checkTvbRange(L,1);
659
667
    if (!tvbr) return 0;
660
 
    
 
668
 
661
669
    switch (tvbr->len) {
662
670
        case 4:
663
671
            lua_pushnumber(L,tvb_get_letohieee_float(tvbr->tvb,tvbr->offset));
677
685
    TvbRange tvbr = checkTvbRange(L,1);
678
686
    Address addr;
679
687
    guint32* ip_addr;
680
 
    
 
688
 
681
689
    if ( !tvbr ) return 0;
682
 
    
683
 
        if (tvbr->len != 4) 
 
690
 
 
691
        if (tvbr->len != 4)
684
692
                WSLUA_ERROR(TvbRange_get_ipv4,"The range must be 4 octets long");
685
 
        
 
693
 
686
694
    addr = g_malloc(sizeof(address));
687
695
 
688
696
    ip_addr = g_malloc(sizeof(guint32));
689
697
    *ip_addr = tvb_get_ntohl(tvbr->tvb,tvbr->offset);
690
 
    
691
 
    SET_ADDRESS(addr, AT_IPv4, 4, ip_addr); 
 
698
 
 
699
    SET_ADDRESS(addr, AT_IPv4, 4, ip_addr);
692
700
    pushAddress(L,addr);
693
701
 
694
702
        WSLUA_RETURN(1); /* the IPv4 Address */
699
707
    TvbRange tvbr = checkTvbRange(L,1);
700
708
    Address addr;
701
709
    guint8* buff;
702
 
    
 
710
 
703
711
    if ( !tvbr ) return 0;
704
 
    
 
712
 
705
713
    addr = g_malloc(sizeof(address));
706
 
    
 
714
 
707
715
        if (tvbr->len != 6)
708
716
                WSLUA_ERROR(TvbRange_get_ether,"The range must be 6 bytes long");
709
 
        
 
717
 
710
718
    buff = tvb_memdup(tvbr->tvb,tvbr->offset,tvbr->len);
711
 
    
712
 
    SET_ADDRESS(addr, AT_ETHER, 6, buff); 
 
719
 
 
720
    SET_ADDRESS(addr, AT_ETHER, 6, buff);
713
721
    pushAddress(L,addr);
714
 
    
 
722
 
715
723
        WSLUA_RETURN(1); /* the Ethernet Address */
716
724
}
717
725
 
719
727
WSLUA_METHOD TvbRange_get_string(lua_State* L) {
720
728
        /* obtain a string from a TvbRange */
721
729
    TvbRange tvbr = checkTvbRange(L,1);
722
 
    
 
730
 
723
731
    if ( !tvbr ) return 0;
724
 
    
 
732
 
725
733
    lua_pushstring(L, (gchar*)tvb_get_ephemeral_string(tvbr->tvb,tvbr->offset,tvbr->len) );
726
 
    
 
734
 
727
735
        WSLUA_RETURN(1); /* the string */
728
736
}
729
737
 
731
739
        /* obtain a ByteArray */
732
740
    TvbRange tvbr = checkTvbRange(L,1);
733
741
    GByteArray* ba;
734
 
    
 
742
 
735
743
    if ( !tvbr ) return 0;
736
 
    
 
744
 
737
745
    ba = g_byte_array_new();
738
746
    g_byte_array_append(ba,ep_tvb_memdup(tvbr->tvb,tvbr->offset,tvbr->len),tvbr->len);
739
 
    
 
747
 
740
748
    pushByteArray(L,ba);
741
 
    
 
749
 
742
750
        WSLUA_RETURN(1); /* the ByteArray */
743
751
}
744
752
 
749
757
    TvbRange tvbr = checkTvbRange(L,1);
750
758
 
751
759
    if (!tvbr) return 0;
752
 
    
 
760
 
753
761
    lua_pushstring(L,tvb_bytes_to_str(tvbr->tvb,tvbr->offset,tvbr->len));
754
762
    return 1;
755
763
}