HACK: pinfo->private_data points to smb_info again
[wireshark-wip.git] / epan / wslua / wslua_pinfo.c
blob70aa79a8b5400d32dfe08aa4feb3855e7e33c5d9
1 /*
2 * wslua_pinfo.c
4 * Wireshark's interface to the Lua Programming Language
6 * (c) 2006, Luis E. Garcia Ontanon <luis@ontanon.org>
7 * (c) 2008, Balint Reczey <balint.reczey@ericsson.com>
8 * (c) 2011, Stig Bjorlykke <stig@bjorlykke.org>
10 * $Id$
12 * Wireshark - Network traffic analyzer
13 * By Gerald Combs <gerald@wireshark.org>
14 * Copyright 1998 Gerald Combs
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * as published by the Free Software Foundation; either version 2
19 * of the License, or (at your option) any later version.
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
31 #include "config.h"
33 #include <epan/emem.h>
35 /* WSLUA_MODULE Pinfo Obtaining packet information */
38 #include "wslua.h"
40 #include <epan/addr_resolv.h>
41 #include <string.h>
45 * Track pointers to wireshark's structures.
46 * see comment on wslua_tvb.c
49 static GPtrArray* outstanding_Pinfo = NULL;
50 static GPtrArray* outstanding_Column = NULL;
51 static GPtrArray* outstanding_Columns = NULL;
52 static GPtrArray* outstanding_PrivateTable = NULL;
54 CLEAR_OUTSTANDING(Pinfo,expired, TRUE)
55 CLEAR_OUTSTANDING(Column,expired, TRUE)
56 CLEAR_OUTSTANDING(Columns,expired, TRUE)
57 CLEAR_OUTSTANDING(PrivateTable,expired, TRUE)
59 Pinfo* push_Pinfo(lua_State* L, packet_info* ws_pinfo) {
60 Pinfo pinfo = NULL;
61 if (ws_pinfo) {
62 pinfo = (Pinfo)g_malloc(sizeof(struct _wslua_pinfo));
63 pinfo->ws_pinfo = ws_pinfo;
64 pinfo->expired = FALSE;
65 g_ptr_array_add(outstanding_Pinfo,pinfo);
67 return pushPinfo(L,pinfo);
70 #define PUSH_COLUMN(L,c) {g_ptr_array_add(outstanding_Column,c);pushColumn(L,c);}
71 #define PUSH_COLUMNS(L,c) {g_ptr_array_add(outstanding_Columns,c);pushColumns(L,c);}
72 #define PUSH_PRIVATE_TABLE(L,c) {g_ptr_array_add(outstanding_PrivateTable,c);pushPrivateTable(L,c);}
74 WSLUA_CLASS_DEFINE(NSTime,NOP,NOP);
75 /* NSTime represents a nstime_t. This is an object with seconds and nano seconds. */
77 WSLUA_CONSTRUCTOR NSTime_new(lua_State *L) {
78 /* Creates a new NSTime object */
79 #define WSLUA_OPTARG_NSTime_new_SECONDS 1 /* Seconds */
80 #define WSLUA_OPTARG_NSTime_new_NSECONDS 2 /* Nano seconds */
81 NSTime nstime = (NSTime)g_malloc(sizeof(nstime_t));
83 if (!nstime) return 0;
85 nstime->secs = (time_t) luaL_optint(L,WSLUA_OPTARG_NSTime_new_SECONDS,0);
86 nstime->nsecs = luaL_optint(L,WSLUA_OPTARG_NSTime_new_NSECONDS,0);
88 pushNSTime(L,nstime);
90 WSLUA_RETURN(1); /* The new NSTime object. */
93 WSLUA_METAMETHOD NSTime__tostring(lua_State* L) {
94 NSTime nstime = checkNSTime(L,1);
96 if (!nstime) return 0;
98 lua_pushstring(L,ep_strdup_printf("%ld.%09d", (long)nstime->secs, nstime->nsecs));
100 WSLUA_RETURN(1); /* The string representing the nstime. */
102 WSLUA_METAMETHOD NSTime__add(lua_State* L) { /* Calculates the sum of two NSTimes */
103 NSTime time1 = checkNSTime(L,1);
104 NSTime time2 = checkNSTime(L,2);
105 NSTime time3 = (NSTime)g_malloc (sizeof (nstime_t));
107 nstime_sum (time3, time1, time2);
108 pushNSTime (L, time3);
110 return 1;
113 WSLUA_METAMETHOD NSTime__sub(lua_State* L) { /* Calculates the diff of two NSTimes */
114 NSTime time1 = checkNSTime(L,1);
115 NSTime time2 = checkNSTime(L,2);
116 NSTime time3 = (NSTime)g_malloc (sizeof (nstime_t));
118 nstime_delta (time3, time1, time2);
119 pushNSTime (L, time3);
121 return 1;
124 WSLUA_METAMETHOD NSTime__unm(lua_State* L) { /* Calculates the negative NSTime */
125 NSTime time1 = checkNSTime(L,1);
126 NSTime time2 = (NSTime)g_malloc (sizeof (nstime_t));
128 nstime_set_zero (time2);
129 nstime_subtract (time2, time1);
130 pushNSTime (L, time2);
132 return 1;
135 WSLUA_METAMETHOD NSTime__eq(lua_State* L) { /* Compares two NSTimes */
136 NSTime time1 = checkNSTime(L,1);
137 NSTime time2 = checkNSTime(L,2);
138 gboolean result = FALSE;
140 if (!time1 || !time2)
141 WSLUA_ERROR(NSTime__eq,"Both values must be a NSTime");
143 if (nstime_cmp(time1, time2) == 0)
144 result = TRUE;
146 lua_pushboolean(L,result);
148 return 1;
151 WSLUA_METAMETHOD NSTime__le(lua_State* L) { /* Compares two NSTimes */
152 NSTime time1 = checkNSTime(L,1);
153 NSTime time2 = checkNSTime(L,2);
154 gboolean result = FALSE;
156 if (!time1 || !time2)
157 WSLUA_ERROR(NSTime__le,"Both values must be a NSTime");
159 if (nstime_cmp(time1, time2) <= 0)
160 result = TRUE;
162 lua_pushboolean(L,result);
164 return 1;
167 WSLUA_METAMETHOD NSTime__lt(lua_State* L) { /* Compares two NSTimes */
168 NSTime time1 = checkNSTime(L,1);
169 NSTime time2 = checkNSTime(L,2);
170 gboolean result = FALSE;
172 if (!time1 || !time2)
173 WSLUA_ERROR(NSTime__lt,"Both values must be a NSTime");
175 if (nstime_cmp(time1, time2) < 0)
176 result = TRUE;
178 lua_pushboolean(L,result);
180 return 1;
183 typedef struct {
184 const gchar* name;
185 lua_CFunction get;
186 lua_CFunction set;
187 } nstime_actions_t;
189 static int NSTime_get_secs(lua_State* L) {
190 NSTime nstime = toNSTime(L,1);
192 lua_pushnumber (L,(lua_Number)(nstime->secs));
194 return 1;
197 static int NSTime_set_secs(lua_State* L)
199 NSTime nstime = toNSTime(L,1);
200 time_t secs = luaL_checkint(L,3);
202 nstime->secs = secs;
204 return 0;
207 static int NSTime_get_nsecs(lua_State* L) {
208 NSTime nstime = toNSTime(L,1);
210 lua_pushnumber (L,(lua_Number)(nstime->nsecs));
212 return 1;
215 static int NSTime_set_nsecs(lua_State* L) {
216 NSTime nstime = toNSTime(L,1);
217 int nsecs = luaL_checkint(L,3);
219 nstime->nsecs = nsecs;
221 return 0;
224 static const nstime_actions_t nstime_actions[] = {
225 /* WSLUA_ATTRIBUTE NSTime_secs RW The NSTime seconds */
226 {"secs", NSTime_get_secs, NSTime_set_secs},
228 /* WSLUA_ATTRIBUTE NSTime_nsecs RW The NSTime nano seconds */
229 {"nsecs", NSTime_get_nsecs, NSTime_set_nsecs},
231 {NULL,NULL,NULL}
234 static int NSTime__index(lua_State* L) {
235 NSTime nstime = checkNSTime(L,1);
236 const gchar* name = luaL_checkstring(L,2);
237 const nstime_actions_t* pa;
239 if (! (nstime && name) ) return 0;
241 for (pa = nstime_actions; pa->name; pa++) {
242 if ( g_str_equal(name,pa->name) ) {
243 if (pa->get) {
244 return pa->get(L);
245 } else {
246 luaL_error(L,"You cannot get the `%s' attribute of a nstime",name);
247 return 0;
252 luaL_error(L,"A protocol doesn't have a `%s' nstime",name);
253 return 0;
256 static int NSTime__newindex(lua_State* L) {
257 NSTime nstime = checkNSTime(L,1);
258 const gchar* name = luaL_checkstring(L,2);
259 const nstime_actions_t* pa;
261 if (! (nstime && name) ) return 0;
263 for (pa = nstime_actions; pa->name; pa++) {
264 if ( g_str_equal(name,pa->name) ) {
265 if (pa->set) {
266 return pa->set(L);
267 } else {
268 luaL_error(L,"You cannot set the `%s' attribute of a nstime",name);
269 return 0;
274 luaL_error(L,"A protocol doesn't have a `%s' nstime",name);
275 return 0;
278 /* Gets registered as metamethod automatically by WSLUA_REGISTER_CLASS/META */
279 static int NSTime__gc(lua_State* L) {
280 NSTime nstime = checkNSTime(L,1);
282 if (!nstime) return 0;
284 g_free (nstime);
285 return 0;
288 WSLUA_META NSTime_meta[] = {
289 {"__index", NSTime__index},
290 {"__newindex", NSTime__newindex},
291 {"__tostring", NSTime__tostring},
292 {"__add", NSTime__add},
293 {"__sub", NSTime__sub},
294 {"__unm", NSTime__unm},
295 {"__eq", NSTime__eq},
296 {"__le", NSTime__le},
297 {"__lt", NSTime__lt},
298 { NULL, NULL}
301 int NSTime_register(lua_State* L) {
302 WSLUA_REGISTER_META(NSTime);
304 lua_pushcfunction(L, NSTime_new);
305 lua_setglobal(L, "NSTime");
307 return 1;
310 WSLUA_CLASS_DEFINE(Address,NOP,NOP); /* Represents an address */
312 WSLUA_CONSTRUCTOR Address_ip(lua_State* L) {
313 /* Creates an Address Object representing an IP address. */
315 #define WSLUA_ARG_Address_ip_HOSTNAME 1 /* The address or name of the IP host. */
316 Address addr = (Address)g_malloc(sizeof(address));
317 guint32* ip_addr = (guint32 *)g_malloc(sizeof(guint32));
318 const gchar* name = luaL_checkstring(L,WSLUA_ARG_Address_ip_HOSTNAME);
320 if (! get_host_ipaddr(name, (guint32*)ip_addr)) {
321 *ip_addr = 0;
324 SET_ADDRESS(addr, AT_IPv4, 4, ip_addr);
325 pushAddress(L,addr);
326 WSLUA_RETURN(1); /* The Address object */
329 #if 0
330 /* TODO */
331 static int Address_ipv6(lua_State* L) {
332 Address addr = g_malloc(sizeof(address));
334 SET_ADDRESS(addr, AT_NONE, 4, g_malloc(4));
336 pushAddress(L,addr);
337 return 1;
339 static int Address_ss7(lua_State* L) {
340 Address addr = g_malloc(sizeof(address));
342 SET_ADDRESS(addr, AT_NONE, 4, g_malloc(4));
344 pushAddress(L,addr);
345 return 1;
347 static int Address_eth(lua_State* L) {
348 Address addr = g_malloc(sizeof(address));
350 SET_ADDRESS(addr, AT_NONE, 4, g_malloc(4));
352 pushAddress(L,addr);
353 return 1;
355 static int Address_sna(lua_State* L) {
356 Address addr = g_malloc(sizeof(address));
358 SET_ADDRESS(addr, AT_NONE, 4, g_malloc(4));
360 pushAddress(L,addr);
361 return 1;
363 static int Address_atalk(lua_State* L) {
364 Address addr = g_malloc(sizeof(address));
366 SET_ADDRESS(addr, AT_NONE, 4, g_malloc(4));
368 pushAddress(L,addr);
369 return 1;
371 static int Address_vines(lua_State* L) {
372 Address addr = g_malloc(sizeof(address));
374 SET_ADDRESS(addr, AT_NONE, 4, g_malloc(4));
376 pushAddress(L,addr);
377 return 1;
379 static int Address_osi(lua_State* L) {
380 Address addr = g_malloc(sizeof(address));
382 SET_ADDRESS(addr, AT_NONE, 4, g_malloc(4));
384 pushAddress(L,addr);
385 return 1;
387 static int Address_arcnet(lua_State* L) {
388 Address addr = g_malloc(sizeof(address));
390 SET_ADDRESS(addr, AT_NONE, 4, g_malloc(4));
392 pushAddress(L,addr);
393 return 1;
395 static int Address_fc(lua_State* L) {
396 Address addr = g_malloc(sizeof(address));
398 SET_ADDRESS(addr, AT_NONE, 4, g_malloc(4));
400 pushAddress(L,addr);
401 return 1;
403 static int Address_string(lua_State* L) {
404 Address addr = g_malloc(sizeof(address));
406 SET_ADDRESS(addr, AT_NONE, 4, g_malloc(4));
408 pushAddress(L,addr);
409 return 1;
411 static int Address_eui64(lua_State* L) {
412 Address addr = g_malloc(sizeof(address));
414 SET_ADDRESS(addr, AT_NONE, 4, g_malloc(4));
416 pushAddress(L,addr);
417 return 1;
419 static int Address_uri(lua_State* L) {
420 Address addr = g_malloc(sizeof(address));
422 SET_ADDRESS(addr, AT_NONE, 4, g_malloc(4));
424 pushAddress(L,addr);
425 return 1;
427 static int Address_tipc(lua_State* L) {
428 Address addr = g_malloc(sizeof(address));
430 SET_ADDRESS(addr, AT_NONE, 4, g_malloc(4));
432 pushAddress(L,addr);
433 return 1;
435 #endif
437 WSLUA_METHODS Address_methods[] = {
438 WSLUA_CLASS_FNREG(Address,ip),
439 WSLUA_CLASS_FNREG_ALIAS(Address,ipv4,ip),
440 #if 0
441 WSLUA_CLASS_FNREG(Address,ipv6),
442 WSLUA_CLASS_FNREG_ALIAS(Address,ss7pc,ss7),
443 WSLUA_CLASS_FNREG(Address,eth),
444 WSLUA_CLASS_FNREG(Address,sna},
445 WSLUA_CLASS_FNREG(Address,atalk),
446 WSLUA_CLASS_FNREG(Address,vines),
447 WSLUA_CLASS_FNREG(Address,osi),
448 WSLUA_CLASS_FNREG(Address,arcnet),
449 WSLUA_CLASS_FNREG(Address,fc),
450 WSLUA_CLASS_FNREG(Address,string),
451 WSLUA_CLASS_FNREG(Address,eui64),
452 WSLUA_CLASS_FNREG(Address,uri),
453 WSLUA_CLASS_FNREG(Address,tipc),
454 #endif
455 {0,0}
458 WSLUA_METAMETHOD Address__tostring(lua_State* L) {
459 Address addr = checkAddress(L,1);
461 lua_pushstring(L,get_addr_name(addr));
463 WSLUA_RETURN(1); /* The string representing the address. */
466 /* Gets registered as metamethod automatically by WSLUA_REGISTER_CLASS/META */
467 static int Address__gc(lua_State* L) {
468 Address addr = checkAddress(L,1);
470 if (addr) {
471 g_free((void*)addr->data);
472 g_free((void*)addr);
475 return 0;
478 WSLUA_METAMETHOD Address__eq(lua_State* L) { /* Compares two Addresses */
479 Address addr1 = checkAddress(L,1);
480 Address addr2 = checkAddress(L,2);
481 gboolean result = FALSE;
483 if (ADDRESSES_EQUAL(addr1, addr2))
484 result = TRUE;
486 lua_pushboolean(L,result);
488 return 1;
491 WSLUA_METAMETHOD Address__le(lua_State* L) { /* Compares two Addresses */
492 Address addr1 = checkAddress(L,1);
493 Address addr2 = checkAddress(L,2);
494 gboolean result = FALSE;
496 if (CMP_ADDRESS(addr1, addr2) <= 0)
497 result = TRUE;
499 lua_pushboolean(L,result);
501 return 1;
504 WSLUA_METAMETHOD Address__lt(lua_State* L) { /* Compares two Addresses */
505 Address addr1 = checkAddress(L,1);
506 Address addr2 = checkAddress(L,2);
507 gboolean result = FALSE;
509 if (CMP_ADDRESS(addr1, addr2) < 0)
510 result = TRUE;
512 lua_pushboolean(L,result);
514 return 1;
517 WSLUA_META Address_meta[] = {
518 {"__tostring", Address__tostring },
519 {"__eq",Address__eq},
520 {"__le",Address__le},
521 {"__lt",Address__lt},
522 {0,0}
526 int Address_register(lua_State *L) {
527 WSLUA_REGISTER_CLASS(Address);
528 return 1;
532 WSLUA_CLASS_DEFINE(Column,FAIL_ON_NULL("expired column"),NOP); /* A Column in the packet list */
534 struct col_names_t {
535 const gchar* name;
536 int id;
539 static const struct col_names_t colnames[] = {
540 {"number",COL_NUMBER},
541 {"abs_time",COL_ABS_TIME},
542 {"utc_time",COL_UTC_TIME},
543 {"cls_time",COL_CLS_TIME},
544 {"rel_time",COL_REL_TIME},
545 {"date",COL_ABS_YMD_TIME},
546 {"date_doy",COL_ABS_YDOY_TIME},
547 {"utc_date",COL_UTC_YMD_TIME},
548 {"utc_date_doy",COL_UTC_YDOY_TIME},
549 {"delta_time",COL_DELTA_TIME},
550 {"delta_time_displayed",COL_DELTA_TIME_DIS},
551 {"src",COL_DEF_SRC},
552 {"src_res",COL_RES_SRC},
553 {"src_unres",COL_UNRES_SRC},
554 {"dl_src",COL_DEF_DL_SRC},
555 {"dl_src_res",COL_RES_DL_SRC},
556 {"dl_src_unres",COL_UNRES_DL_SRC},
557 {"net_src",COL_DEF_NET_SRC},
558 {"net_src_res",COL_RES_NET_SRC},
559 {"net_src_unres",COL_UNRES_NET_SRC},
560 {"dst",COL_DEF_DST},
561 {"dst_res",COL_RES_DST},
562 {"dst_unres",COL_UNRES_DST},
563 {"dl_dst",COL_DEF_DL_DST},
564 {"dl_dst_res",COL_RES_DL_DST},
565 {"dl_dst_unres",COL_UNRES_DL_DST},
566 {"net_dst",COL_DEF_NET_DST},
567 {"net_dst_res",COL_RES_NET_DST},
568 {"net_dst_unres",COL_UNRES_NET_DST},
569 {"src_port",COL_DEF_SRC_PORT},
570 {"src_port_res",COL_RES_SRC_PORT},
571 {"src_port_unres",COL_UNRES_SRC_PORT},
572 {"dst_port",COL_DEF_DST_PORT},
573 {"dst_port_res",COL_RES_DST_PORT},
574 {"dst_port_unres",COL_UNRES_DST_PORT},
575 {"protocol",COL_PROTOCOL},
576 {"info",COL_INFO},
577 {"packet_len",COL_PACKET_LENGTH},
578 {"cumulative_bytes",COL_CUMULATIVE_BYTES},
579 {"direction",COL_IF_DIR},
580 {"vsan",COL_VSAN},
581 {"tx_rate",COL_TX_RATE},
582 {"rssi",COL_RSSI},
583 {"dce_call",COL_DCE_CALL},
584 {NULL,0}
587 static gint col_name_to_id(const gchar* name) {
588 const struct col_names_t* cn;
589 for(cn = colnames; cn->name; cn++) {
590 if (g_str_equal(cn->name,name)) {
591 return cn->id;
595 return 0;
598 static const gchar* col_id_to_name(gint id) {
599 const struct col_names_t* cn;
600 for(cn = colnames; cn->name; cn++) {
601 if ( cn->id == id ) {
602 return cn->name;
605 return NULL;
609 WSLUA_METAMETHOD Column__tostring(lua_State *L) {
610 Column c = checkColumn(L,1);
611 const gchar* text;
613 if (!c) {
614 lua_pushstring(L,"(nil)");
616 else if (!c->cinfo) {
617 text = col_id_to_name(c->col);
618 lua_pushfstring(L, "(%s)", text ? text : "unknown");
620 else {
621 text = col_get_text(c->cinfo, c->col);
622 lua_pushstring(L, text ? text : "(nil)");
625 WSLUA_RETURN(1); /* The column's string text (in parenthesis if not available) */
628 /* Gets registered as metamethod automatically by WSLUA_REGISTER_CLASS */
629 static int Column__gc(lua_State* L) {
630 Column col = checkColumn(L,1);
632 if (!col) return 0;
634 if (!col->expired)
635 col->expired = TRUE;
636 else
637 g_free(col);
639 return 0;
643 WSLUA_METHOD Column_clear(lua_State *L) {
644 /* Clears a Column */
645 Column c = checkColumn(L,1);
647 if (!(c && c->cinfo)) return 0;
649 col_clear(c->cinfo, c->col);
651 return 0;
654 WSLUA_METHOD Column_set(lua_State *L) {
655 /* Sets the text of a Column */
656 #define WSLUA_ARG_Column_set_TEXT 2 /* The text to which to set the Column */
657 Column c = checkColumn(L,1);
658 const gchar* s = luaL_checkstring(L,WSLUA_ARG_Column_set_TEXT);
660 if (!(c && c->cinfo))
661 return 0;
663 if (!s) WSLUA_ARG_ERROR(Column_set,TEXT,"must be a string");
665 col_add_str(c->cinfo, c->col, s);
667 return 0;
670 WSLUA_METHOD Column_append(lua_State *L) {
671 /* Appends text to a Column */
672 #define WSLUA_ARG_Column_append_TEXT 2 /* The text to append to the Column */
673 Column c = checkColumn(L,1);
674 const gchar* s = luaL_checkstring(L,WSLUA_ARG_Column_append_TEXT);
676 if (!(c && c->cinfo))
677 return 0;
679 if (!s) WSLUA_ARG_ERROR(Column_append,TEXT,"must be a string");
681 col_append_str(c->cinfo, c->col, s);
683 return 0;
686 WSLUA_METHOD Column_prepend(lua_State *L) {
687 /* Prepends text to a Column */
688 #define WSLUA_ARG_Column_prepend_TEXT 2 /* The text to prepend to the Column */
689 Column c = checkColumn(L,1);
690 const gchar* s = luaL_checkstring(L,WSLUA_ARG_Column_prepend_TEXT);
692 if (!(c && c->cinfo))
693 return 0;
695 if (!s) WSLUA_ARG_ERROR(Column_prepend,TEXT,"must be a string");
697 col_prepend_fstr(c->cinfo, c->col, "%s",s);
699 return 0;
702 WSLUA_METHOD Column_fence(lua_State *L) {
703 /* Sets Column text fence, to prevent overwriting */
704 Column c = checkColumn(L,1);
706 if (c && c->cinfo)
707 col_set_fence(c->cinfo, c->col);
709 return 0;
713 WSLUA_METHODS Column_methods[] = {
714 WSLUA_CLASS_FNREG(Column,clear),
715 WSLUA_CLASS_FNREG(Column,set),
716 WSLUA_CLASS_FNREG(Column,append),
717 WSLUA_CLASS_FNREG(Column,prepend),
718 WSLUA_CLASS_FNREG_ALIAS(Column,preppend,prepend),
719 WSLUA_CLASS_FNREG(Column,fence),
720 {0,0}
724 WSLUA_META Column_meta[] = {
725 {"__tostring", Column__tostring },
726 {0,0}
730 int Column_register(lua_State *L) {
731 WSLUA_REGISTER_CLASS(Column);
732 return 1;
740 WSLUA_CLASS_DEFINE(Columns,NOP,NOP);
741 /* The Columns of the packet list. */
743 WSLUA_METAMETHOD Columns__tostring(lua_State *L) {
744 lua_pushstring(L,"Columns");
745 WSLUA_RETURN(1);
746 /* The string "Columns", no real use, just for debugging purposes. */
750 * To document this is very odd - it won't make sense to a person reading the
751 * API docs to see this metamethod as a method, but oh well.
753 WSLUA_METAMETHOD Columns__newindex(lua_State *L) {
754 /* Sets the text of a specific column */
755 #define WSLUA_ARG_Columns__newindex_COLUMN 2 /* The name of the column to set */
756 #define WSLUA_ARG_Columns__newindex_TEXT 3 /* The text for the column */
757 Columns cols = checkColumns(L,1);
758 const struct col_names_t* cn;
759 const char* colname;
760 const char* text;
762 if (!cols) return 0;
763 if (cols->expired) {
764 luaL_error(L,"expired column");
765 return 0;
768 colname = luaL_checkstring(L,WSLUA_ARG_Columns__newindex_COLUMN);
769 text = luaL_checkstring(L,WSLUA_ARG_Columns__newindex_TEXT);
771 for(cn = colnames; cn->name; cn++) {
772 if( g_str_equal(cn->name,colname) ) {
773 col_add_str(cols->cinfo, cn->id, text);
774 return 0;
778 WSLUA_ARG_ERROR(Columns__newindex,COLUMN,"the column name must be a valid column");
781 WSLUA_METAMETHOD Columns_index(lua_State *L) {
782 Columns cols = checkColumns(L,1);
783 const struct col_names_t* cn;
784 const char* colname = luaL_checkstring(L,2);
786 if (!cols) {
787 Column c = (Column)g_malloc(sizeof(struct _wslua_col_info));
788 c->cinfo = NULL;
789 c->col = col_name_to_id(colname);
790 c->expired = FALSE;
792 PUSH_COLUMN(L,c);
793 return 1;
797 if (cols->expired) {
798 luaL_error(L,"expired column");
799 return 0;
802 if (!colname) return 0;
804 for(cn = colnames; cn->name; cn++) {
805 if( g_str_equal(cn->name,colname) ) {
806 Column c = (Column)g_malloc(sizeof(struct _wslua_col_info));
807 c->cinfo = cols->cinfo;
808 c->col = col_name_to_id(colname);
809 c->expired = FALSE;
811 PUSH_COLUMN(L,c);
812 return 1;
816 return 0;
819 /* Gets registered as metamethod automatically by WSLUA_REGISTER_META */
820 static int Columns__gc(lua_State* L) {
821 Columns cols = checkColumns(L,1);
823 if (!cols) return 0;
825 if (!cols->expired)
826 cols->expired = TRUE;
827 else
828 g_free(cols);
830 return 0;
835 static const luaL_Reg Columns_meta[] = {
836 {"__tostring", Columns__tostring },
837 {"__newindex", Columns__newindex },
838 {"__index", Columns_index},
839 { NULL, NULL }
843 int Columns_register(lua_State *L) {
844 WSLUA_REGISTER_META(Columns);
845 return 1;
848 WSLUA_CLASS_DEFINE(PrivateTable,NOP,NOP);
849 /* PrivateTable represents the pinfo->private_table. */
851 WSLUA_METAMETHOD PrivateTable__tostring(lua_State* L) {
852 PrivateTable priv = checkPrivateTable(L,1);
853 GString *key_string;
854 GList *keys, *key;
856 if (!priv) return 0;
858 key_string = g_string_new ("");
859 keys = g_hash_table_get_keys (priv->table);
860 key = g_list_first (keys);
861 while (key) {
862 key_string = g_string_append (key_string, (const gchar *)key->data);
863 key = g_list_next (key);
864 if (key) {
865 key_string = g_string_append_c (key_string, ',');
869 lua_pushstring(L,key_string->str);
871 g_string_free (key_string, TRUE);
872 g_list_free (keys);
874 WSLUA_RETURN(1); /* A string with all keys in the table, mostly for debugging. */
877 static int PrivateTable__index(lua_State* L) {
878 /* Gets the text of a specific entry */
879 PrivateTable priv = checkPrivateTable(L,1);
880 const gchar* name = luaL_checkstring(L,2);
881 const gchar* string;
883 if (! (priv && name) ) return 0;
885 if (priv->expired) {
886 luaL_error(L,"expired private_table");
887 return 0;
890 string = (const gchar *)g_hash_table_lookup (priv->table, (gpointer) name);
892 if (string) {
893 lua_pushstring(L, string);
894 } else {
895 lua_pushnil(L);
898 return 1;
901 static int PrivateTable__newindex(lua_State* L) {
902 /* Sets the text of a specific entry */
903 PrivateTable priv = checkPrivateTable(L,1);
904 const gchar* name = luaL_checkstring(L,2);
905 const gchar* string = NULL;
907 if (! (priv && name) ) return 0;
909 if (priv->expired) {
910 luaL_error(L,"expired private_table");
911 return 0;
914 if (lua_isstring(L,3)) {
915 /* This also catches numbers, which is converted to string */
916 string = luaL_checkstring(L,3);
917 } else if (lua_isboolean(L,3)) {
918 /* We support boolean by setting a empty string if true and NULL if false */
919 string = lua_toboolean(L,3) ? "" : NULL;
920 } else if (!lua_isnil(L,3)) {
921 luaL_error(L,"unsupported type: %s", lua_typename(L,3));
922 return 0;
925 if (string) {
926 g_hash_table_replace (priv->table, (gpointer) ep_strdup(name), (gpointer) ep_strdup(string));
927 } else {
928 g_hash_table_remove (priv->table, (gpointer) name);
931 return 1;
934 /* Gets registered as metamethod automatically by WSLUA_REGISTER_CLASS/META */
935 static int PrivateTable__gc(lua_State* L) {
936 PrivateTable priv = checkPrivateTable(L,1);
938 if (!priv) return 0;
940 if (!priv->expired) {
941 priv->expired = TRUE;
942 } else {
943 if (priv->is_allocated) {
944 g_hash_table_destroy (priv->table);
946 g_free(priv);
949 return 0;
952 WSLUA_META PrivateTable_meta[] = {
953 {"__index", PrivateTable__index},
954 {"__newindex", PrivateTable__newindex},
955 {"__tostring", PrivateTable__tostring},
956 { NULL, NULL}
959 int PrivateTable_register(lua_State* L) {
960 WSLUA_REGISTER_META(PrivateTable);
961 return 1;
965 WSLUA_CLASS_DEFINE(Pinfo,FAIL_ON_NULL("expired pinfo"),NOP);
966 /* Packet information */
968 static int Pinfo_tostring(lua_State *L) { lua_pushstring(L,"a Pinfo"); return 1; }
970 #define PINFO_GET(name,block) static int name(lua_State *L) { \
971 Pinfo pinfo = checkPinfo(L,1); \
972 if (!pinfo) return 0;\
973 if (pinfo->expired) { \
974 luaL_error(L,"expired_pinfo"); \
975 return 0; \
977 block \
978 return 1;\
981 #define PINFO_GET_BOOLEAN(name,val) \
982 PINFO_GET(name,{lua_pushboolean(L,val);})
984 #define PINFO_GET_NUMBER(name,val) \
985 PINFO_GET(name,{lua_pushnumber(L,(lua_Number)(val));})
987 #define PINFO_GET_STRING(name,val) \
988 PINFO_GET(name, { \
989 const gchar* value; \
990 value = val; \
991 if (value) lua_pushstring(L,(const char*)(value)); else lua_pushnil(L); \
994 #define PINFO_GET_ADDRESS(name,role) \
995 PINFO_GET(name, { \
996 Address addr; \
997 addr = g_new(address,1); \
998 COPY_ADDRESS(addr, &(pinfo->ws_pinfo->role)); \
999 pushAddress(L,addr); \
1002 #define PINFO_GET_LIGHTUSERDATA(name, val) \
1003 PINFO_GET(name,{lua_pushlightuserdata(L, (void *) (val));})
1005 static double
1006 lua_nstime_to_sec(const nstime_t *nstime)
1008 return (((double)nstime->secs) + (((double)nstime->nsecs) / 1000000000.0));
1011 static double
1012 lua_delta_nstime_to_sec(const Pinfo pinfo, const frame_data *fd, guint32 prev_num)
1014 nstime_t del;
1016 frame_delta_abs_time(pinfo->ws_pinfo->epan, fd, prev_num, &del);
1017 return lua_nstime_to_sec(&del);
1020 PINFO_GET_BOOLEAN(Pinfo_fragmented,pinfo->ws_pinfo->fragmented)
1021 PINFO_GET_BOOLEAN(Pinfo_in_error_pkt,pinfo->ws_pinfo->flags.in_error_pkt)
1022 PINFO_GET_BOOLEAN(Pinfo_visited,pinfo->ws_pinfo->fd->flags.visited)
1024 PINFO_GET_NUMBER(Pinfo_number,pinfo->ws_pinfo->fd->num)
1025 PINFO_GET_NUMBER(Pinfo_len,pinfo->ws_pinfo->fd->pkt_len)
1026 PINFO_GET_NUMBER(Pinfo_caplen,pinfo->ws_pinfo->fd->cap_len)
1027 PINFO_GET_NUMBER(Pinfo_abs_ts,lua_nstime_to_sec(&pinfo->ws_pinfo->fd->abs_ts))
1028 PINFO_GET_NUMBER(Pinfo_rel_ts,lua_nstime_to_sec(&pinfo->ws_pinfo->rel_ts))
1029 PINFO_GET_NUMBER(Pinfo_delta_ts,lua_delta_nstime_to_sec(pinfo, pinfo->ws_pinfo->fd, pinfo->ws_pinfo->fd->num - 1))
1030 PINFO_GET_NUMBER(Pinfo_delta_dis_ts,lua_delta_nstime_to_sec(pinfo, pinfo->ws_pinfo->fd, pinfo->ws_pinfo->fd->prev_dis_num))
1031 PINFO_GET_NUMBER(Pinfo_ipproto,pinfo->ws_pinfo->ipproto)
1032 PINFO_GET_NUMBER(Pinfo_circuit_id,pinfo->ws_pinfo->circuit_id)
1033 PINFO_GET_NUMBER(Pinfo_can_desegment,pinfo->ws_pinfo->can_desegment)
1034 PINFO_GET_NUMBER(Pinfo_desegment_len,pinfo->ws_pinfo->desegment_len)
1035 PINFO_GET_NUMBER(Pinfo_desegment_offset,pinfo->ws_pinfo->desegment_offset)
1036 PINFO_GET_NUMBER(Pinfo_ptype,pinfo->ws_pinfo->ptype)
1037 PINFO_GET_NUMBER(Pinfo_src_port,pinfo->ws_pinfo->srcport)
1038 PINFO_GET_NUMBER(Pinfo_dst_port,pinfo->ws_pinfo->destport)
1039 PINFO_GET_NUMBER(Pinfo_ethertype,pinfo->ws_pinfo->ethertype)
1040 PINFO_GET_NUMBER(Pinfo_match_uint,pinfo->ws_pinfo->match_uint)
1042 PINFO_GET_STRING(Pinfo_curr_proto,pinfo->ws_pinfo->current_proto)
1043 PINFO_GET_STRING(Pinfo_match_string,pinfo->ws_pinfo->match_string)
1045 PINFO_GET_ADDRESS(Pinfo_net_src,net_src)
1046 PINFO_GET_ADDRESS(Pinfo_net_dst,net_dst)
1047 PINFO_GET_ADDRESS(Pinfo_dl_src,dl_src)
1048 PINFO_GET_ADDRESS(Pinfo_dl_dst,dl_dst)
1049 PINFO_GET_ADDRESS(Pinfo_src,src)
1050 PINFO_GET_ADDRESS(Pinfo_dst,dst)
1052 PINFO_GET_LIGHTUSERDATA(Pinfo_private_data, pinfo->ws_pinfo->private_data)
1054 static int Pinfo_match(lua_State *L) {
1055 Pinfo pinfo = checkPinfo(L,1);
1057 if (!pinfo) return 0;
1058 if (pinfo->expired) {
1059 luaL_error(L,"expired_pinfo");
1060 return 0;
1063 if (pinfo->ws_pinfo->match_string) {
1064 lua_pushstring(L,pinfo->ws_pinfo->match_string);
1065 } else {
1066 lua_pushnumber(L,(lua_Number)(pinfo->ws_pinfo->match_uint));
1069 return 1;
1072 static int Pinfo_columns(lua_State *L) {
1073 Columns cols = NULL;
1074 Pinfo pinfo = checkPinfo(L,1);
1075 const gchar* colname = luaL_optstring(L,2,NULL);
1077 if (pinfo->expired) {
1078 luaL_error(L,"expired_pinfo");
1079 return 0;
1082 cols = (Columns)g_malloc(sizeof(struct _wslua_cols));
1083 cols->cinfo = pinfo->ws_pinfo->cinfo;
1084 cols->expired = FALSE;
1086 if (!colname) {
1087 PUSH_COLUMNS(L,cols);
1088 } else {
1089 lua_settop(L,0);
1090 PUSH_COLUMNS(L,cols);
1091 lua_pushstring(L,colname);
1092 return Columns_index(L);
1094 return 1;
1097 static int Pinfo_private(lua_State *L) {
1098 PrivateTable priv = NULL;
1099 Pinfo pinfo = checkPinfo(L,1);
1100 const gchar* privname = luaL_optstring(L,2,NULL);
1101 gboolean is_allocated = FALSE;
1103 if (!pinfo) return 0;
1105 if (pinfo->expired) {
1106 luaL_error(L,"expired private_table");
1107 return 0;
1110 if (!pinfo->ws_pinfo->private_table) {
1111 pinfo->ws_pinfo->private_table = g_hash_table_new(g_str_hash,g_str_equal);
1112 is_allocated = TRUE;
1115 priv = (PrivateTable)g_malloc(sizeof(struct _wslua_private_table));
1116 priv->table = pinfo->ws_pinfo->private_table;
1117 priv->is_allocated = is_allocated;
1118 priv->expired = FALSE;
1120 if (!privname) {
1121 PUSH_PRIVATE_TABLE(L,priv);
1122 } else {
1123 lua_settop(L,0);
1124 PUSH_PRIVATE_TABLE(L,priv);
1125 lua_pushstring(L,privname);
1126 return PrivateTable__index(L);
1128 return 1;
1131 typedef enum {
1132 PARAM_NONE,
1133 PARAM_ADDR_SRC,
1134 PARAM_ADDR_DST,
1135 PARAM_ADDR_DL_SRC,
1136 PARAM_ADDR_DL_DST,
1137 PARAM_ADDR_NET_SRC,
1138 PARAM_ADDR_NET_DST,
1139 PARAM_PORT_SRC,
1140 PARAM_PORT_DST,
1141 PARAM_CIRCUIT_ID,
1142 PARAM_CAN_DESEGMENT,
1143 PARAM_DESEGMENT_LEN,
1144 PARAM_DESEGMENT_OFFSET,
1145 PARAM_PORT_TYPE,
1146 PARAM_ETHERTYPE
1147 } pinfo_param_type_t;
1149 static int pushnil_param(lua_State* L, packet_info* pinfo _U_, pinfo_param_type_t pt _U_ ) {
1150 lua_pushnil(L);
1151 return 1;
1154 static int Pinfo_set_addr(lua_State* L, packet_info* pinfo, pinfo_param_type_t pt) {
1155 const address* from = checkAddress(L,1);
1156 address* to;
1158 if (! from ) {
1159 luaL_error(L,"Not an OK address");
1160 return 0;
1163 if (!pinfo) {
1164 luaL_error(L,"expired_pinfo");
1165 return 0;
1168 switch(pt) {
1169 case PARAM_ADDR_SRC:
1170 to = &(pinfo->src);
1171 break;
1172 case PARAM_ADDR_DST:
1173 to = &(pinfo->dst);
1174 break;
1175 case PARAM_ADDR_DL_SRC:
1176 to = &(pinfo->dl_src);
1177 break;
1178 case PARAM_ADDR_DL_DST:
1179 to = &(pinfo->dl_dst);
1180 break;
1181 case PARAM_ADDR_NET_SRC:
1182 to = &(pinfo->net_src);
1183 break;
1184 case PARAM_ADDR_NET_DST:
1185 to = &(pinfo->net_dst);
1186 break;
1187 default:
1188 g_assert(!"BUG: A bad parameter");
1189 return 0;
1192 COPY_ADDRESS(to,from);
1193 return 0;
1196 static int Pinfo_set_int(lua_State* L, packet_info* pinfo, pinfo_param_type_t pt) {
1197 gint64 v = luaL_checkint(L,1);
1199 if (!pinfo) {
1200 luaL_error(L,"expired_pinfo");
1201 return 0;
1204 switch(pt) {
1205 case PARAM_PORT_SRC:
1206 pinfo->srcport = (guint32)v;
1207 return 0;
1208 case PARAM_PORT_DST:
1209 pinfo->destport = (guint32)v;
1210 return 0;
1211 case PARAM_CIRCUIT_ID:
1212 pinfo->circuit_id = (guint32)v;
1213 return 0;
1214 case PARAM_CAN_DESEGMENT:
1215 pinfo->can_desegment = (guint16)v;
1216 return 0;
1217 case PARAM_DESEGMENT_LEN:
1218 pinfo->desegment_len = (guint32)v;
1219 return 0;
1220 case PARAM_DESEGMENT_OFFSET:
1221 pinfo->desegment_offset = (int)v;
1222 return 0;
1223 case PARAM_ETHERTYPE:
1224 pinfo->ethertype = (guint32)v;
1225 return 0;
1226 default:
1227 g_assert(!"BUG: A bad parameter");
1230 return 0;
1233 typedef struct _pinfo_method_t {
1234 const gchar* name;
1235 lua_CFunction get;
1236 int (*set)(lua_State*, packet_info*, pinfo_param_type_t);
1237 pinfo_param_type_t param;
1238 } pinfo_method_t;
1240 static int Pinfo_hi(lua_State *L) {
1241 Pinfo pinfo = checkPinfo(L,1);
1242 Address addr;
1244 if (!pinfo) return 0;
1245 if (pinfo->expired) {
1246 luaL_error(L,"expired_pinfo");
1247 return 0;
1250 addr = (Address)g_malloc(sizeof(address));
1251 if (CMP_ADDRESS(&(pinfo->ws_pinfo->src), &(pinfo->ws_pinfo->dst) ) >= 0) {
1252 COPY_ADDRESS(addr, &(pinfo->ws_pinfo->src));
1253 } else {
1254 COPY_ADDRESS(addr, &(pinfo->ws_pinfo->dst));
1257 pushAddress(L,addr);
1258 return 1;
1261 static int Pinfo_lo(lua_State *L) {
1262 Pinfo pinfo = checkPinfo(L,1);
1263 Address addr;
1265 if (!pinfo) return 0;
1266 if (pinfo->expired) {
1267 luaL_error(L,"expired_pinfo");
1268 return 0;
1271 addr = (Address)g_malloc(sizeof(address));
1272 if (CMP_ADDRESS(&(pinfo->ws_pinfo->src), &(pinfo->ws_pinfo->dst) ) < 0) {
1273 COPY_ADDRESS(addr, &(pinfo->ws_pinfo->src));
1274 } else {
1275 COPY_ADDRESS(addr, &(pinfo->ws_pinfo->dst));
1278 pushAddress(L,addr);
1279 return 1;
1283 static const pinfo_method_t Pinfo_methods[] = {
1285 /* WSLUA_ATTRIBUTE Pinfo_number RO The number of this packet in the current file */
1286 {"number", Pinfo_number, pushnil_param, PARAM_NONE},
1288 /* WSLUA_ATTRIBUTE Pinfo_len RO The length of the frame */
1289 {"len", Pinfo_len, pushnil_param, PARAM_NONE },
1291 /* WSLUA_ATTRIBUTE Pinfo_caplen RO The captured length of the frame */
1292 {"caplen", Pinfo_caplen, pushnil_param, PARAM_NONE },
1294 /* WSLUA_ATTRIBUTE Pinfo_abs_ts RO When the packet was captured */
1295 {"abs_ts",Pinfo_abs_ts, pushnil_param, PARAM_NONE },
1297 /* WSLUA_ATTRIBUTE Pinfo_rel_ts RO Number of seconds passed since beginning of capture */
1298 {"rel_ts",Pinfo_rel_ts, pushnil_param, PARAM_NONE },
1300 /* WSLUA_ATTRIBUTE Pinfo_delta_ts RO Number of seconds passed since the last captured packet */
1301 {"delta_ts",Pinfo_delta_ts, pushnil_param, PARAM_NONE },
1303 /* WSLUA_ATTRIBUTE Pinfo_delta_dis_ts RO Number of seconds passed since the last displayed packet */
1304 {"delta_dis_ts",Pinfo_delta_dis_ts, pushnil_param, PARAM_NONE },
1306 /* WSLUA_ATTRIBUTE Pinfo_visited RO Whether this packet hass been already visited */
1307 {"visited",Pinfo_visited, pushnil_param, PARAM_NONE },
1309 /* WSLUA_ATTRIBUTE Pinfo_src RW Source Address of this Packet */
1310 {"src", Pinfo_src, Pinfo_set_addr, PARAM_ADDR_SRC },
1312 /* WSLUA_ATTRIBUTE Pinfo_dst RW Destination Address of this Packet */
1313 {"dst", Pinfo_dst, Pinfo_set_addr, PARAM_ADDR_DST },
1315 /* WSLUA_ATTRIBUTE Pinfo_lo RO lower Address of this Packet */
1316 {"lo", Pinfo_lo, pushnil_param, PARAM_NONE },
1318 /* WSLUA_ATTRIBUTE Pinfo_hi RW higher Address of this Packet */
1319 {"hi", Pinfo_hi, pushnil_param, PARAM_NONE },
1321 /* WSLUA_ATTRIBUTE Pinfo_dl_src RW Data Link Source Address of this Packet */
1322 {"dl_src", Pinfo_dl_src, Pinfo_set_addr, PARAM_ADDR_DL_SRC },
1324 /* WSLUA_ATTRIBUTE Pinfo_dl_dst RW Data Link Destination Address of this Packet */
1325 {"dl_dst", Pinfo_dl_dst, Pinfo_set_addr, PARAM_ADDR_DL_DST },
1327 /* WSLUA_ATTRIBUTE Pinfo_net_src RW Network Layer Source Address of this Packet */
1328 {"net_src", Pinfo_net_src, Pinfo_set_addr, PARAM_ADDR_NET_SRC },
1330 /* WSLUA_ATTRIBUTE Pinfo_net_dst RW Network Layer Destination Address of this Packet */
1331 {"net_dst", Pinfo_net_dst, Pinfo_set_addr, PARAM_ADDR_NET_DST },
1333 /* WSLUA_ATTRIBUTE Pinfo_ptype RW Type of Port of .src_port and .dst_port */
1334 {"port_type", Pinfo_ptype, pushnil_param, PARAM_NONE },
1336 /* WSLUA_ATTRIBUTE Pinfo_src_port RW Source Port of this Packet */
1337 {"src_port", Pinfo_src_port, Pinfo_set_int, PARAM_PORT_SRC },
1339 /* WSLUA_ATTRIBUTE Pinfo_dst_port RW Source Address of this Packet */
1340 {"dst_port", Pinfo_dst_port, Pinfo_set_int, PARAM_PORT_SRC },
1342 /* WSLUA_ATTRIBUTE Pinfo_ipproto RO IP Protocol id */
1343 {"ipproto", Pinfo_ipproto, pushnil_param, PARAM_NONE },
1345 /* WSLUA_ATTRIBUTE Pinfo_circuit_id RO For circuit based protocols */
1346 {"circuit_id", Pinfo_circuit_id, Pinfo_set_int, PARAM_CIRCUIT_ID },
1348 /* WSLUA_ATTRIBUTE Pinfo_match RO Port/Data we are matching */
1349 {"match", Pinfo_match, pushnil_param, PARAM_NONE },
1351 /* WSLUA_ATTRIBUTE Pinfo_curr_proto RO Which Protocol are we dissecting */
1352 {"curr_proto", Pinfo_curr_proto, pushnil_param, PARAM_NONE },
1354 /* WSLUA_ATTRIBUTE Pinfo_columns RO Accesss to the packet list columns */
1355 {"columns", Pinfo_columns, pushnil_param, PARAM_NONE },
1357 /* WSLUA_ATTRIBUTE Pinfo_cols RO Accesss to the packet list columns (equivalent to pinfo.columns) */
1358 {"cols", Pinfo_columns, pushnil_param, PARAM_NONE },
1360 /* WSLUA_ATTRIBUTE Pinfo_can_desegment RW Set if this segment could be desegmented */
1361 {"can_desegment", Pinfo_can_desegment, Pinfo_set_int, PARAM_CAN_DESEGMENT },
1363 /* WSLUA_ATTRIBUTE Pinfo_desegment_len RW Estimated number of additional bytes required for completing the PDU */
1364 {"desegment_len", Pinfo_desegment_len, Pinfo_set_int, PARAM_DESEGMENT_LEN },
1366 /* WSLUA_ATTRIBUTE Pinfo_desegment_offset RW Offset in the tvbuff at which the dissector will continue processing when next called*/
1367 {"desegment_offset", Pinfo_desegment_offset, Pinfo_set_int, PARAM_DESEGMENT_OFFSET },
1369 /* WSLUA_ATTRIBUTE Pinfo_private_data RO Access to private data */
1370 {"private_data", Pinfo_private_data, pushnil_param, PARAM_NONE},
1372 /* WSLUA_ATTRIBUTE Pinfo_private RW Access to the private table entries */
1373 {"private", Pinfo_private, pushnil_param, PARAM_NONE},
1375 /* WSLUA_ATTRIBUTE Pinfo_ethertype RW Ethernet Type Code, if this is an Ethernet packet */
1376 {"ethertype", Pinfo_ethertype, Pinfo_set_int, PARAM_ETHERTYPE},
1378 /* WSLUA_ATTRIBUTE Pinfo_fragmented RO If the protocol is only a fragment */
1379 {"fragmented", Pinfo_fragmented, pushnil_param, PARAM_NONE},
1381 /* WSLUA_ATTRIBUTE Pinfo_in_error_pkt RO If we're inside an error packet */
1382 {"in_error_pkt", Pinfo_in_error_pkt, pushnil_param, PARAM_NONE},
1384 /* WSLUA_ATTRIBUTE Pinfo_match_uint RO Matched uint for calling subdissector from table */
1385 {"match_uint", Pinfo_match_uint, pushnil_param, PARAM_NONE },
1387 /* WSLUA_ATTRIBUTE Pinfo_match_string RO Matched string for calling subdissector from table */
1388 {"match_string", Pinfo_match_string, pushnil_param, PARAM_NONE },
1390 {NULL,NULL,NULL,PARAM_NONE}
1394 static int pushnil(lua_State* L) {
1395 lua_pushnil(L);
1396 return 1;
1399 static int Pinfo_index(lua_State* L) {
1400 Pinfo pinfo = checkPinfo(L,1);
1401 const gchar* name = luaL_checkstring(L,2);
1402 lua_CFunction method = pushnil;
1403 const pinfo_method_t* curr;
1405 if (! (pinfo && name) ) {
1406 lua_pushnil(L);
1407 return 1;
1409 if (pinfo->expired) {
1410 luaL_error(L,"expired_pinfo");
1411 return 0;
1414 for (curr = Pinfo_methods ; curr->name ; curr++) {
1415 if (g_str_equal(curr->name,name)) {
1416 method = curr->get;
1417 break;
1421 lua_settop(L,1);
1422 return method(L);
1425 static int Pinfo_setindex(lua_State* L) {
1426 Pinfo pinfo = checkPinfo(L,1);
1427 const gchar* name = luaL_checkstring(L,2);
1428 int (*method)(lua_State*, packet_info* pinfo, pinfo_param_type_t) = pushnil_param;
1429 const pinfo_method_t* curr;
1430 pinfo_param_type_t param_type = PARAM_NONE;
1432 if (! (pinfo && name) ) {
1433 return 0;
1435 if (pinfo->expired) {
1436 luaL_error(L,"expired_pinfo");
1437 return 0;
1440 for (curr = Pinfo_methods ; curr->name ; curr++) {
1441 if (g_str_equal(curr->name,name)) {
1442 method = curr->set;
1443 param_type = curr->param;
1444 break;
1448 lua_remove(L,1);
1449 lua_remove(L,1);
1450 return method(L,pinfo->ws_pinfo,param_type);
1453 /* Gets registered as metamethod automatically by WSLUA_REGISTER_CLASS/META */
1454 static int Pinfo__gc(lua_State* L) {
1455 Pinfo pinfo = checkPinfo(L,1);
1457 if (!pinfo) return 0;
1459 if (!pinfo->expired)
1460 pinfo->expired = TRUE;
1461 else
1462 g_free(pinfo);
1464 return 0;
1468 static const luaL_Reg Pinfo_meta[] = {
1469 {"__index", Pinfo_index},
1470 {"__newindex",Pinfo_setindex},
1471 {"__tostring", Pinfo_tostring},
1472 { NULL, NULL }
1475 int Pinfo_register(lua_State* L) {
1476 WSLUA_REGISTER_META(Pinfo);
1477 outstanding_Pinfo = g_ptr_array_new();
1478 outstanding_Column = g_ptr_array_new();
1479 outstanding_Columns = g_ptr_array_new();
1480 outstanding_PrivateTable = g_ptr_array_new();
1481 return 1;