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>
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.
33 /* WSLUA_MODULE Pinfo Obtaining packet information */
38 #include <epan/addr_resolv.h>
43 * Track pointers to wireshark's structures.
44 * see comment on wslua_tvb.c
47 static GPtrArray* outstanding_Pinfo = NULL;
48 static GPtrArray* outstanding_Column = NULL;
49 static GPtrArray* outstanding_Columns = NULL;
50 static GPtrArray* outstanding_PrivateTable = NULL;
52 CLEAR_OUTSTANDING(Pinfo,expired, TRUE)
53 CLEAR_OUTSTANDING(Column,expired, TRUE)
54 CLEAR_OUTSTANDING(Columns,expired, TRUE)
55 CLEAR_OUTSTANDING(PrivateTable,expired, TRUE)
57 Pinfo* push_Pinfo(lua_State* L, packet_info* ws_pinfo) {
60 pinfo = g_malloc(sizeof(struct _wslua_pinfo));
61 pinfo->ws_pinfo = ws_pinfo;
62 pinfo->expired = FALSE;
63 g_ptr_array_add(outstanding_Pinfo,pinfo);
65 return pushPinfo(L,pinfo);
68 #define PUSH_COLUMN(L,c) {g_ptr_array_add(outstanding_Column,c);pushColumn(L,c);}
69 #define PUSH_COLUMNS(L,c) {g_ptr_array_add(outstanding_Columns,c);pushColumns(L,c);}
70 #define PUSH_PRIVATE_TABLE(L,c) {g_ptr_array_add(outstanding_PrivateTable,c);pushPrivateTable(L,c);}
72 WSLUA_CLASS_DEFINE(NSTime,NOP,NOP);
73 /* NSTime represents a nstime_t. This is an object with seconds and nano seconds. */
75 WSLUA_CONSTRUCTOR NSTime_new(lua_State *L) {
76 /* Creates a new NSTime object */
77 #define WSLUA_OPTARG_NSTime_new_SECONDS 1 /* Seconds */
78 #define WSLUA_OPTARG_NSTime_new_NSECONDS 2 /* Nano seconds */
79 NSTime time = g_malloc(sizeof(nstime_t));
83 time->secs = (time_t) luaL_optint(L,WSLUA_OPTARG_NSTime_new_SECONDS,0);
84 time->nsecs = luaL_optint(L,WSLUA_OPTARG_NSTime_new_NSECONDS,0);
88 WSLUA_RETURN(1); /* The new NSTime object. */
91 WSLUA_METAMETHOD NSTime__tostring(lua_State* L) {
92 NSTime nstime = checkNSTime(L,1);
94 if (!nstime) return 0;
96 lua_pushstring(L,ep_strdup_printf("%ld.%09d", (long)nstime->secs, nstime->nsecs));
98 WSLUA_RETURN(1); /* The string representing the nstime. */
100 WSLUA_METAMETHOD NSTime__add(lua_State* L) { /* Calculates the sum of two NSTimes */
101 NSTime time1 = checkNSTime(L,1);
102 NSTime time2 = checkNSTime(L,2);
103 NSTime time3 = g_malloc (sizeof (nstime_t));
105 nstime_sum (time3, time1, time2);
106 pushNSTime (L, time3);
111 WSLUA_METAMETHOD NSTime__sub(lua_State* L) { /* Calculates the diff of two NSTimes */
112 NSTime time1 = checkNSTime(L,1);
113 NSTime time2 = checkNSTime(L,2);
114 NSTime time3 = g_malloc (sizeof (nstime_t));
116 nstime_delta (time3, time1, time2);
117 pushNSTime (L, time3);
122 WSLUA_METAMETHOD NSTime__unm(lua_State* L) { /* Calculates the negative NSTime */
123 NSTime time1 = checkNSTime(L,1);
124 NSTime time2 = g_malloc (sizeof (nstime_t));
126 nstime_set_zero (time2);
127 nstime_subtract (time2, time1);
128 pushNSTime (L, time2);
133 WSLUA_METAMETHOD NSTime__eq(lua_State* L) { /* Compares two NSTimes */
134 NSTime time1 = checkNSTime(L,1);
135 NSTime time2 = checkNSTime(L,2);
136 gboolean result = FALSE;
138 if (!time1 || !time2)
139 WSLUA_ERROR(FieldInfo__eq,"Data source must be the same for both fields");
141 if (nstime_cmp(time1, time2) == 0)
144 lua_pushboolean(L,result);
149 WSLUA_METAMETHOD NSTime__le(lua_State* L) { /* Compares two NSTimes */
150 NSTime time1 = checkNSTime(L,1);
151 NSTime time2 = checkNSTime(L,2);
152 gboolean result = FALSE;
154 if (!time1 || !time2)
155 WSLUA_ERROR(FieldInfo__eq,"Data source must be the same for both fields");
157 if (nstime_cmp(time1, time2) <= 0)
160 lua_pushboolean(L,result);
165 WSLUA_METAMETHOD NSTime__lt(lua_State* L) { /* Compares two NSTimes */
166 NSTime time1 = checkNSTime(L,1);
167 NSTime time2 = checkNSTime(L,2);
168 gboolean result = FALSE;
170 if (!time1 || !time2)
171 WSLUA_ERROR(FieldInfo__eq,"Data source must be the same for both fields");
173 if (nstime_cmp(time1, time2) < 0)
176 lua_pushboolean(L,result);
187 static int NSTime_get_secs(lua_State* L) {
188 NSTime time = toNSTime(L,1);
190 lua_pushnumber (L,(lua_Number)(time->secs));
195 static int NSTime_set_secs(lua_State* L)
197 NSTime time = toNSTime(L,1);
198 time_t secs = luaL_checkint(L,3);
205 static int NSTime_get_nsecs(lua_State* L) {
206 NSTime time = toNSTime(L,1);
208 lua_pushnumber (L,(lua_Number)(time->nsecs));
213 static int NSTime_set_nsecs(lua_State* L) {
214 NSTime time = toNSTime(L,1);
215 int nsecs = luaL_checkint(L,3);
222 static const nstime_actions_t nstime_actions[] = {
223 /* WSLUA_ATTRIBUTE NSTime_secs RW The NSTime seconds */
224 {"secs", NSTime_get_secs, NSTime_set_secs},
226 /* WSLUA_ATTRIBUTE NSTime_nsecs RW The NSTime nano seconds */
227 {"nsecs", NSTime_get_nsecs, NSTime_set_nsecs},
232 static int NSTime__index(lua_State* L) {
233 NSTime time = checkNSTime(L,1);
234 const gchar* name = luaL_checkstring(L,2);
235 const nstime_actions_t* pa;
237 if (! (time && name) ) return 0;
239 for (pa = nstime_actions; pa->name; pa++) {
240 if ( g_str_equal(name,pa->name) ) {
244 luaL_error(L,"You cannot get the `%s' attribute of a nstime",name);
250 luaL_error(L,"A protocol doesn't have a `%s' nstime",name);
254 static int NSTime__newindex(lua_State* L) {
255 NSTime time = checkNSTime(L,1);
256 const gchar* name = luaL_checkstring(L,2);
257 const nstime_actions_t* pa;
259 if (! (time && name) ) return 0;
261 for (pa = nstime_actions; pa->name; pa++) {
262 if ( g_str_equal(name,pa->name) ) {
266 luaL_error(L,"You cannot set the `%s' attribute of a nstime",name);
272 luaL_error(L,"A protocol doesn't have a `%s' nstime",name);
276 static int NSTime__gc(lua_State* L) {
277 NSTime nstime = checkNSTime(L,1);
279 if (!nstime) return 0;
285 WSLUA_META NSTime_meta[] = {
286 {"__index", NSTime__index},
287 {"__newindex", NSTime__newindex},
288 {"__tostring", NSTime__tostring},
289 {"__add", NSTime__add},
290 {"__sub", NSTime__sub},
291 {"__unm", NSTime__unm},
292 {"__eq", NSTime__eq},
293 {"__le", NSTime__le},
294 {"__lt", NSTime__lt},
295 {"__gc", NSTime__gc},
299 int NSTime_register(lua_State* L) {
300 WSLUA_REGISTER_META(NSTime);
302 lua_pushcfunction(L, NSTime_new);
303 lua_setglobal(L, "NSTime");
308 WSLUA_CLASS_DEFINE(Address,NOP,NOP); /* Represents an address */
310 WSLUA_CONSTRUCTOR Address_ip(lua_State* L) {
311 /* Creates an Address Object representing an IP address. */
313 #define WSLUA_ARG_Address_ip_HOSTNAME 1 /* The address or name of the IP host. */
314 Address addr = g_malloc(sizeof(address));
315 guint32* ip_addr = g_malloc(sizeof(guint32));
316 const gchar* name = luaL_checkstring(L,WSLUA_ARG_Address_ip_HOSTNAME);
318 if (! get_host_ipaddr(name, (guint32*)ip_addr)) {
322 SET_ADDRESS(addr, AT_IPv4, 4, ip_addr);
324 WSLUA_RETURN(1); /* The Address object */
329 static int Address_ipv6(lua_State* L) {
330 Address addr = g_malloc(sizeof(address));
332 SET_ADDRESS(addr, AT_NONE, 4, g_malloc(4));
337 static int Address_ss7(lua_State* L) {
338 Address addr = g_malloc(sizeof(address));
340 SET_ADDRESS(addr, AT_NONE, 4, g_malloc(4));
345 static int Address_eth(lua_State* L) {
346 Address addr = g_malloc(sizeof(address));
348 SET_ADDRESS(addr, AT_NONE, 4, g_malloc(4));
353 static int Address_sna(lua_State* L) {
354 Address addr = g_malloc(sizeof(address));
356 SET_ADDRESS(addr, AT_NONE, 4, g_malloc(4));
361 static int Address_atalk(lua_State* L) {
362 Address addr = g_malloc(sizeof(address));
364 SET_ADDRESS(addr, AT_NONE, 4, g_malloc(4));
369 static int Address_vines(lua_State* L) {
370 Address addr = g_malloc(sizeof(address));
372 SET_ADDRESS(addr, AT_NONE, 4, g_malloc(4));
377 static int Address_osi(lua_State* L) {
378 Address addr = g_malloc(sizeof(address));
380 SET_ADDRESS(addr, AT_NONE, 4, g_malloc(4));
385 static int Address_arcnet(lua_State* L) {
386 Address addr = g_malloc(sizeof(address));
388 SET_ADDRESS(addr, AT_NONE, 4, g_malloc(4));
393 static int Address_fc(lua_State* L) {
394 Address addr = g_malloc(sizeof(address));
396 SET_ADDRESS(addr, AT_NONE, 4, g_malloc(4));
401 static int Address_string(lua_State* L) {
402 Address addr = g_malloc(sizeof(address));
404 SET_ADDRESS(addr, AT_NONE, 4, g_malloc(4));
409 static int Address_eui64(lua_State* L) {
410 Address addr = g_malloc(sizeof(address));
412 SET_ADDRESS(addr, AT_NONE, 4, g_malloc(4));
417 static int Address_uri(lua_State* L) {
418 Address addr = g_malloc(sizeof(address));
420 SET_ADDRESS(addr, AT_NONE, 4, g_malloc(4));
425 static int Address_tipc(lua_State* L) {
426 Address addr = g_malloc(sizeof(address));
428 SET_ADDRESS(addr, AT_NONE, 4, g_malloc(4));
435 WSLUA_METHODS Address_methods[] = {
437 {"ipv4", Address_ip },
439 {"ipv6", Address_ipv6 },
440 {"ss7pc", Address_ss7 },
441 {"eth", Address_eth },
442 {"sna", Address_sna },
443 {"atalk", Address_atalk },
444 {"vines", Address_vines },
445 {"osi", Address_osi },
446 {"arcnet", Address_arcnet },
448 {"string", Address_string },
449 {"eui64", Address_eui64 },
450 {"uri", Address_uri },
451 {"tipc", Address_tipc },
456 WSLUA_METAMETHOD Address__tostring(lua_State* L) {
457 Address addr = checkAddress(L,1);
459 lua_pushstring(L,get_addr_name(addr));
461 WSLUA_RETURN(1); /* The string representing the address. */
464 static int Address__gc(lua_State* L) {
465 Address addr = checkAddress(L,1);
468 g_free((void*)addr->data);
475 WSLUA_METAMETHOD Address__eq(lua_State* L) { /* Compares two Addresses */
476 Address addr1 = checkAddress(L,1);
477 Address addr2 = checkAddress(L,2);
478 gboolean result = FALSE;
480 if (ADDRESSES_EQUAL(addr1, addr2))
483 lua_pushboolean(L,result);
488 WSLUA_METAMETHOD Address__le(lua_State* L) { /* Compares two Addresses */
489 Address addr1 = checkAddress(L,1);
490 Address addr2 = checkAddress(L,2);
491 gboolean result = FALSE;
493 if (CMP_ADDRESS(addr1, addr2) <= 0)
496 lua_pushboolean(L,result);
501 WSLUA_METAMETHOD Address__lt(lua_State* L) { /* Compares two Addresses */
502 Address addr1 = checkAddress(L,1);
503 Address addr2 = checkAddress(L,2);
504 gboolean result = FALSE;
506 if (CMP_ADDRESS(addr1, addr2) < 0)
509 lua_pushboolean(L,result);
514 WSLUA_META Address_meta[] = {
515 {"__gc", Address__gc },
516 {"__tostring", Address__tostring },
517 {"__eq",Address__eq},
518 {"__le",Address__le},
519 {"__lt",Address__lt},
524 int Address_register(lua_State *L) {
525 WSLUA_REGISTER_CLASS(Address);
530 WSLUA_CLASS_DEFINE(Column,FAIL_ON_NULL("expired column"),NOP); /* A Column in the packet list */
537 static const struct col_names_t colnames[] = {
538 {"number",COL_NUMBER},
539 {"abs_time",COL_ABS_TIME},
540 {"utc_time",COL_UTC_TIME},
541 {"cls_time",COL_CLS_TIME},
542 {"rel_time",COL_REL_TIME},
543 {"date",COL_ABS_DATE_TIME},
544 {"utc_date",COL_UTC_DATE_TIME},
545 {"delta_time",COL_DELTA_TIME},
546 {"delta_time_displayed",COL_DELTA_TIME_DIS},
548 {"src_res",COL_RES_SRC},
549 {"src_unres",COL_UNRES_SRC},
550 {"dl_src",COL_DEF_DL_SRC},
551 {"dl_src_res",COL_RES_DL_SRC},
552 {"dl_src_unres",COL_UNRES_DL_SRC},
553 {"net_src",COL_DEF_NET_SRC},
554 {"net_src_res",COL_RES_NET_SRC},
555 {"net_src_unres",COL_UNRES_NET_SRC},
557 {"dst_res",COL_RES_DST},
558 {"dst_unres",COL_UNRES_DST},
559 {"dl_dst",COL_DEF_DL_DST},
560 {"dl_dst_res",COL_RES_DL_DST},
561 {"dl_dst_unres",COL_UNRES_DL_DST},
562 {"net_dst",COL_DEF_NET_DST},
563 {"net_dst_res",COL_RES_NET_DST},
564 {"net_dst_unres",COL_UNRES_NET_DST},
565 {"src_port",COL_DEF_SRC_PORT},
566 {"src_port_res",COL_RES_SRC_PORT},
567 {"src_port_unres",COL_UNRES_SRC_PORT},
568 {"dst_port",COL_DEF_DST_PORT},
569 {"dst_port_res",COL_RES_DST_PORT},
570 {"dst_port_unres",COL_UNRES_DST_PORT},
571 {"protocol",COL_PROTOCOL},
573 {"packet_len",COL_PACKET_LENGTH},
574 {"cumulative_bytes",COL_CUMULATIVE_BYTES},
575 {"direction",COL_IF_DIR},
577 {"tx_rate",COL_TX_RATE},
579 {"dce_call",COL_DCE_CALL},
583 static gint col_name_to_id(const gchar* name) {
584 const struct col_names_t* cn;
585 for(cn = colnames; cn->name; cn++) {
586 if (g_str_equal(cn->name,name)) {
594 static const gchar* col_id_to_name(gint id) {
595 const struct col_names_t* cn;
596 for(cn = colnames; cn->name; cn++) {
597 if ( cn->id == id ) {
605 WSLUA_METAMETHOD Column__tostring(lua_State *L) {
606 Column c = checkColumn(L,1);
613 /* XXX: should return the column's text ! */
614 name = col_id_to_name(c->col);
615 lua_pushstring(L,name ? name : "Unknown Column");
617 WSLUA_RETURN(1); /* A string representing the column */
620 static int Column__gc(lua_State* L) {
621 Column col = checkColumn(L,1);
634 WSLUA_METHOD Column_clear(lua_State *L) {
635 /* Clears a Column */
636 Column c = checkColumn(L,1);
638 if (!(c && c->cinfo)) return 0;
640 col_clear(c->cinfo, c->col);
645 WSLUA_METHOD Column_set(lua_State *L) {
646 /* Sets the text of a Column */
647 #define WSLUA_ARG_Column_set_TEXT 2 /* The text to which to set the Column */
648 Column c = checkColumn(L,1);
649 const gchar* s = luaL_checkstring(L,WSLUA_ARG_Column_set_TEXT);
651 if (!(c && c->cinfo))
654 if (!s) WSLUA_ARG_ERROR(Column_set,TEXT,"must be a string");
656 col_add_str(c->cinfo, c->col, s);
661 WSLUA_METHOD Column_append(lua_State *L) {
662 /* Appends text to a Column */
663 #define WSLUA_ARG_Column_append_TEXT 2 /* The text to append to the Column */
664 Column c = checkColumn(L,1);
665 const gchar* s = luaL_checkstring(L,WSLUA_ARG_Column_append_TEXT);
667 if (!(c && c->cinfo))
670 if (!s) WSLUA_ARG_ERROR(Column_append,TEXT,"must be a string");
672 col_append_str(c->cinfo, c->col, s);
677 WSLUA_METHOD Column_preppend(lua_State *L) {
678 /* Prepends text to a Column */
679 #define WSLUA_ARG_Column_prepend_TEXT 2 /* The text to prepend to the Column */
680 Column c = checkColumn(L,1);
681 const gchar* s = luaL_checkstring(L,WSLUA_ARG_Column_prepend_TEXT);
683 if (!(c && c->cinfo))
686 if (!s) WSLUA_ARG_ERROR(Column_prepend,TEXT,"must be a string");
688 if (check_col(c->cinfo, c->col))
689 col_prepend_fstr(c->cinfo, c->col, "%s",s);
694 WSLUA_METHODS Column_methods[] = {
695 {"clear", Column_clear },
696 {"set", Column_set },
697 {"append", Column_append },
698 {"preppend", Column_preppend },
703 WSLUA_META Column_meta[] = {
704 {"__tostring", Column__tostring },
705 {"__gc", Column__gc },
710 int Column_register(lua_State *L) {
711 WSLUA_REGISTER_CLASS(Column);
720 WSLUA_CLASS_DEFINE(Columns,NOP,NOP);
721 /* The Columns of the packet list. */
723 WSLUA_METAMETHOD Columns__tostring(lua_State *L) {
724 lua_pushstring(L,"Columns");
726 /* The string "Columns", no real use, just for debugging purposes. */
729 WSLUA_METAMETHOD Columns__newindex(lua_State *L) {
730 /* Sets the text of a specific column */
731 #define WSLUA_ARG_Columns__newindex_COLUMN 2 /* The name of the column to set */
732 #define WSLUA_ARG_Columns__newindex_TEXT 3 /* The text for the column */
733 Columns cols = checkColumns(L,1);
734 const struct col_names_t* cn;
740 luaL_error(L,"expired column");
744 colname = luaL_checkstring(L,WSLUA_ARG_Columns__newindex_COLUMN);
745 text = luaL_checkstring(L,WSLUA_ARG_Columns__newindex_TEXT);
747 for(cn = colnames; cn->name; cn++) {
748 if( g_str_equal(cn->name,colname) ) {
749 col_add_str(cols->cinfo, cn->id, text);
754 WSLUA_ARG_ERROR(Columns__newindex,COLUMN,"the column name must be a valid column");
757 WSLUA_METAMETHOD Columns_index(lua_State *L) {
758 Columns cols = checkColumns(L,1);
759 const struct col_names_t* cn;
760 const char* colname = luaL_checkstring(L,2);
763 Column c = g_malloc(sizeof(struct _wslua_col_info));
765 c->col = col_name_to_id(colname);
774 luaL_error(L,"expired column");
778 if (!colname) return 0;
780 for(cn = colnames; cn->name; cn++) {
781 if( g_str_equal(cn->name,colname) ) {
782 Column c = g_malloc(sizeof(struct _wslua_col_info));
783 c->cinfo = cols->cinfo;
784 c->col = col_name_to_id(colname);
795 static int Columns_gc(lua_State* L) {
796 Columns cols = checkColumns(L,1);
801 cols->expired = TRUE;
810 static const luaL_Reg Columns_meta[] = {
811 {"__tostring", Columns__tostring },
812 {"__newindex", Columns__newindex },
813 {"__index", Columns_index},
814 {"__gc", Columns_gc},
819 int Columns_register(lua_State *L) {
820 WSLUA_REGISTER_META(Columns);
824 WSLUA_CLASS_DEFINE(PrivateTable,NOP,NOP);
825 /* PrivateTable represents the pinfo->private_table. */
827 WSLUA_METAMETHOD PrivateTable__tostring(lua_State* L) {
828 PrivateTable priv = checkPrivateTable(L,1);
834 key_string = g_string_new ("");
835 keys = g_hash_table_get_keys (priv->table);
836 key = g_list_first (keys);
838 key_string = g_string_append (key_string, key->data);
839 key = g_list_next (key);
841 key_string = g_string_append_c (key_string, ',');
845 lua_pushstring(L,key_string->str);
847 g_string_free (key_string, TRUE);
850 WSLUA_RETURN(1); /* A string with all keys in the table, mostly for debugging. */
853 static int PrivateTable__index(lua_State* L) {
854 /* Gets the text of a specific entry */
855 PrivateTable priv = checkPrivateTable(L,1);
856 const gchar* name = luaL_checkstring(L,2);
859 if (! (priv && name) ) return 0;
862 luaL_error(L,"expired private_table");
866 string = g_hash_table_lookup (priv->table, (gpointer) name);
869 lua_pushstring(L, string);
877 static int PrivateTable__newindex(lua_State* L) {
878 /* Sets the text of a specific entry */
879 PrivateTable priv = checkPrivateTable(L,1);
880 const gchar* name = luaL_checkstring(L,2);
881 const gchar* string = NULL;
883 if (! (priv && name) ) return 0;
886 luaL_error(L,"expired private_table");
890 if (lua_isstring(L,3)) {
891 /* This also catches numbers, which is converted to string */
892 string = luaL_checkstring(L,3);
893 } else if (lua_isboolean(L,3)) {
894 /* We support boolean by setting a empty string if true and NULL if false */
895 string = lua_toboolean(L,3) ? "" : NULL;
896 } else if (!lua_isnil(L,3)) {
897 luaL_error(L,"unsupported type: %s", lua_typename(L,3));
902 g_hash_table_replace (priv->table, (gpointer) ep_strdup(name), (gpointer) ep_strdup(string));
904 g_hash_table_remove (priv->table, (gpointer) name);
910 static int PrivateTable__gc(lua_State* L) {
911 PrivateTable priv = checkPrivateTable(L,1);
915 if (!priv->expired) {
916 priv->expired = TRUE;
918 if (priv->is_allocated) {
919 g_hash_table_destroy (priv->table);
927 WSLUA_META PrivateTable_meta[] = {
928 {"__index", PrivateTable__index},
929 {"__newindex", PrivateTable__newindex},
930 {"__tostring", PrivateTable__tostring},
931 {"__gc", PrivateTable__gc},
935 int PrivateTable_register(lua_State* L) {
936 WSLUA_REGISTER_META(PrivateTable);
941 WSLUA_CLASS_DEFINE(Pinfo,FAIL_ON_NULL("expired pinfo"),NOP);
942 /* Packet information */
944 static int Pinfo_tostring(lua_State *L) { lua_pushstring(L,"a Pinfo"); return 1; }
946 #define PINFO_GET_BOOLEAN(name,val) static int name(lua_State *L) { \
947 Pinfo pinfo = checkPinfo(L,1); \
948 if (!pinfo) return 0;\
949 if (pinfo->expired) { \
950 luaL_error(L,"expired_pinfo"); \
953 lua_pushboolean(L,val);\
957 #define PINFO_GET_NUMBER(name,val) static int name(lua_State *L) { \
958 Pinfo pinfo = checkPinfo(L,1); \
959 if (!pinfo) return 0;\
960 if (pinfo->expired) { \
961 luaL_error(L,"expired_pinfo"); \
964 lua_pushnumber(L,(lua_Number)(val));\
968 #define PINFO_GET_STRING(name,val) static int name(lua_State *L) { \
969 Pinfo pinfo = checkPinfo(L,1); \
970 const gchar* value; \
971 if (!pinfo) return 0; \
972 if (pinfo->expired) { \
973 luaL_error(L,"expired_pinfo"); \
977 if (value) lua_pushstring(L,(const char*)(value)); else lua_pushnil(L); \
981 #define PINFO_GET_ADDRESS(name,role) static int name(lua_State *L) { \
982 Pinfo pinfo = checkPinfo(L,1); \
984 if (!pinfo) return 0; \
985 if (pinfo->expired) { \
986 luaL_error(L,"expired_pinfo"); \
989 addr = g_new(address,1); \
990 COPY_ADDRESS(addr, &(pinfo->ws_pinfo->role)); \
991 pushAddress(L,addr); \
995 #define PINFO_GET_LIGHTUSERDATA(name, val) static int name(lua_State *L) { \
996 Pinfo pinfo = checkPinfo(L, 1); \
997 if (!pinfo) return 0; \
998 if (pinfo->expired) { \
999 luaL_error(L, "expired_pinfo"); \
1002 lua_pushlightuserdata(L, (void *) (val)); \
1006 PINFO_GET_BOOLEAN(Pinfo_fragmented,pinfo->ws_pinfo->fragmented)
1007 PINFO_GET_BOOLEAN(Pinfo_in_error_pkt,pinfo->ws_pinfo->flags.in_error_pkt)
1008 PINFO_GET_BOOLEAN(Pinfo_visited,pinfo->ws_pinfo->fd->flags.visited)
1010 PINFO_GET_NUMBER(Pinfo_number,pinfo->ws_pinfo->fd->num)
1011 PINFO_GET_NUMBER(Pinfo_len,pinfo->ws_pinfo->fd->pkt_len)
1012 PINFO_GET_NUMBER(Pinfo_caplen,pinfo->ws_pinfo->fd->cap_len)
1013 PINFO_GET_NUMBER(Pinfo_abs_ts,(((double)pinfo->ws_pinfo->fd->abs_ts.secs) + (((double)pinfo->ws_pinfo->fd->abs_ts.nsecs) / 1000000000.0) ))
1014 PINFO_GET_NUMBER(Pinfo_rel_ts,(((double)pinfo->ws_pinfo->fd->rel_ts.secs) + (((double)pinfo->ws_pinfo->fd->rel_ts.nsecs) / 1000000000.0) ))
1015 PINFO_GET_NUMBER(Pinfo_delta_ts,(((double)pinfo->ws_pinfo->fd->del_cap_ts.secs) + (((double)pinfo->ws_pinfo->fd->del_cap_ts.nsecs) / 1000000000.0) ))
1016 PINFO_GET_NUMBER(Pinfo_delta_dis_ts,(((double)pinfo->ws_pinfo->fd->del_dis_ts.secs) + (((double)pinfo->ws_pinfo->fd->del_dis_ts.nsecs) / 1000000000.0) ))
1017 PINFO_GET_NUMBER(Pinfo_ipproto,pinfo->ws_pinfo->ipproto)
1018 PINFO_GET_NUMBER(Pinfo_circuit_id,pinfo->ws_pinfo->circuit_id)
1019 PINFO_GET_NUMBER(Pinfo_desegment_len,pinfo->ws_pinfo->desegment_len)
1020 PINFO_GET_NUMBER(Pinfo_desegment_offset,pinfo->ws_pinfo->desegment_offset)
1021 PINFO_GET_NUMBER(Pinfo_ptype,pinfo->ws_pinfo->ptype)
1022 PINFO_GET_NUMBER(Pinfo_src_port,pinfo->ws_pinfo->srcport)
1023 PINFO_GET_NUMBER(Pinfo_dst_port,pinfo->ws_pinfo->destport)
1024 PINFO_GET_NUMBER(Pinfo_ethertype,pinfo->ws_pinfo->ethertype)
1025 PINFO_GET_NUMBER(Pinfo_match_uint,pinfo->ws_pinfo->match_uint)
1027 PINFO_GET_STRING(Pinfo_curr_proto,pinfo->ws_pinfo->current_proto)
1028 PINFO_GET_STRING(Pinfo_match_string,pinfo->ws_pinfo->match_string)
1030 PINFO_GET_ADDRESS(Pinfo_net_src,net_src)
1031 PINFO_GET_ADDRESS(Pinfo_net_dst,net_dst)
1032 PINFO_GET_ADDRESS(Pinfo_dl_src,dl_src)
1033 PINFO_GET_ADDRESS(Pinfo_dl_dst,dl_dst)
1034 PINFO_GET_ADDRESS(Pinfo_src,src)
1035 PINFO_GET_ADDRESS(Pinfo_dst,dst)
1037 PINFO_GET_LIGHTUSERDATA(Pinfo_private_data, pinfo->ws_pinfo->private_data)
1039 static int Pinfo_match(lua_State *L) {
1040 Pinfo pinfo = checkPinfo(L,1);
1042 if (!pinfo) return 0;
1043 if (pinfo->expired) {
1044 luaL_error(L,"expired_pinfo");
1048 if (pinfo->ws_pinfo->match_string) {
1049 lua_pushstring(L,pinfo->ws_pinfo->match_string);
1051 lua_pushnumber(L,(lua_Number)(pinfo->ws_pinfo->match_uint));
1057 static int Pinfo_columns(lua_State *L) {
1058 Columns cols = NULL;
1059 Pinfo pinfo = checkPinfo(L,1);
1060 const gchar* colname = luaL_optstring(L,2,NULL);
1062 if (pinfo->expired) {
1063 luaL_error(L,"expired_pinfo");
1067 cols = g_malloc(sizeof(struct _wslua_cols));
1068 cols->cinfo = pinfo->ws_pinfo->cinfo;
1069 cols->expired = FALSE;
1072 PUSH_COLUMNS(L,cols);
1075 PUSH_COLUMNS(L,cols);
1076 lua_pushstring(L,colname);
1077 return Columns_index(L);
1082 static int Pinfo_private(lua_State *L) {
1083 PrivateTable priv = NULL;
1084 Pinfo pinfo = checkPinfo(L,1);
1085 const gchar* privname = luaL_optstring(L,2,NULL);
1086 gboolean is_allocated = FALSE;
1088 if (!pinfo) return 0;
1090 if (pinfo->expired) {
1091 luaL_error(L,"expired private_table");
1095 if (!pinfo->ws_pinfo->private_table) {
1096 pinfo->ws_pinfo->private_table = g_hash_table_new(g_str_hash,g_str_equal);
1097 is_allocated = TRUE;
1100 priv = g_malloc(sizeof(struct _wslua_private_table));
1101 priv->table = pinfo->ws_pinfo->private_table;
1102 priv->is_allocated = is_allocated;
1103 priv->expired = FALSE;
1106 PUSH_PRIVATE_TABLE(L,priv);
1109 PUSH_PRIVATE_TABLE(L,priv);
1110 lua_pushstring(L,privname);
1111 return PrivateTable__index(L);
1127 PARAM_DESEGMENT_LEN,
1128 PARAM_DESEGMENT_OFFSET,
1131 } pinfo_param_type_t;
1133 static int pushnil_param(lua_State* L, packet_info* pinfo _U_, pinfo_param_type_t pt _U_ ) {
1138 static int Pinfo_set_addr(lua_State* L, packet_info* pinfo, pinfo_param_type_t pt) {
1139 const address* from = checkAddress(L,1);
1143 luaL_error(L,"Not an OK address");
1148 luaL_error(L,"expired_pinfo");
1153 case PARAM_ADDR_SRC:
1156 case PARAM_ADDR_DST:
1159 case PARAM_ADDR_DL_SRC:
1160 to = &(pinfo->dl_src);
1162 case PARAM_ADDR_DL_DST:
1163 to = &(pinfo->dl_dst);
1165 case PARAM_ADDR_NET_SRC:
1166 to = &(pinfo->net_src);
1168 case PARAM_ADDR_NET_DST:
1169 to = &(pinfo->net_dst);
1172 g_assert(!"BUG: A bad parameter");
1176 COPY_ADDRESS(to,from);
1180 static int Pinfo_set_int(lua_State* L, packet_info* pinfo, pinfo_param_type_t pt) {
1181 gint64 v = luaL_checkint(L,1);
1184 luaL_error(L,"expired_pinfo");
1189 case PARAM_PORT_SRC:
1190 pinfo->srcport = (guint32)v;
1192 case PARAM_PORT_DST:
1193 pinfo->destport = (guint32)v;
1195 case PARAM_CIRCUIT_ID:
1196 pinfo->circuit_id = (guint32)v;
1198 case PARAM_DESEGMENT_LEN:
1199 pinfo->desegment_len = (guint32)v;
1201 case PARAM_DESEGMENT_OFFSET:
1202 pinfo->desegment_offset = (int)v;
1204 case PARAM_ETHERTYPE:
1205 pinfo->ethertype = (guint32)v;
1208 g_assert(!"BUG: A bad parameter");
1214 typedef struct _pinfo_method_t {
1217 int (*set)(lua_State*, packet_info*, pinfo_param_type_t);
1218 pinfo_param_type_t param;
1221 static int Pinfo_hi(lua_State *L) {
1222 Pinfo pinfo = checkPinfo(L,1);
1225 if (!pinfo) return 0;
1226 if (pinfo->expired) {
1227 luaL_error(L,"expired_pinfo");
1231 addr = g_malloc(sizeof(address));
1232 if (CMP_ADDRESS(&(pinfo->ws_pinfo->src), &(pinfo->ws_pinfo->dst) ) >= 0) {
1233 COPY_ADDRESS(addr, &(pinfo->ws_pinfo->src));
1235 COPY_ADDRESS(addr, &(pinfo->ws_pinfo->dst));
1238 pushAddress(L,addr);
1242 static int Pinfo_lo(lua_State *L) {
1243 Pinfo pinfo = checkPinfo(L,1);
1246 if (!pinfo) return 0;
1247 if (pinfo->expired) {
1248 luaL_error(L,"expired_pinfo");
1252 addr = g_malloc(sizeof(address));
1253 if (CMP_ADDRESS(&(pinfo->ws_pinfo->src), &(pinfo->ws_pinfo->dst) ) < 0) {
1254 COPY_ADDRESS(addr, &(pinfo->ws_pinfo->src));
1256 COPY_ADDRESS(addr, &(pinfo->ws_pinfo->dst));
1259 pushAddress(L,addr);
1264 static const pinfo_method_t Pinfo_methods[] = {
1266 /* WSLUA_ATTRIBUTE Pinfo_number RO The number of this packet in the current file */
1267 {"number", Pinfo_number, pushnil_param, PARAM_NONE},
1269 /* WSLUA_ATTRIBUTE Pinfo_len RO The length of the frame */
1270 {"len", Pinfo_len, pushnil_param, PARAM_NONE },
1272 /* WSLUA_ATTRIBUTE Pinfo_caplen RO The captured length of the frame */
1273 {"caplen", Pinfo_caplen, pushnil_param, PARAM_NONE },
1275 /* WSLUA_ATTRIBUTE Pinfo_abs_ts RO When the packet was captured */
1276 {"abs_ts",Pinfo_abs_ts, pushnil_param, PARAM_NONE },
1278 /* WSLUA_ATTRIBUTE Pinfo_rel_ts RO Number of seconds passed since beginning of capture */
1279 {"rel_ts",Pinfo_rel_ts, pushnil_param, PARAM_NONE },
1281 /* WSLUA_ATTRIBUTE Pinfo_delta_ts RO Number of seconds passed since the last captured packet */
1282 {"delta_ts",Pinfo_delta_ts, pushnil_param, PARAM_NONE },
1284 /* WSLUA_ATTRIBUTE Pinfo_delta_dis_ts RO Number of seconds passed since the last displayed packet */
1285 {"delta_dis_ts",Pinfo_delta_dis_ts, pushnil_param, PARAM_NONE },
1287 /* WSLUA_ATTRIBUTE Pinfo_visited RO Whether this packet hass been already visited */
1288 {"visited",Pinfo_visited, pushnil_param, PARAM_NONE },
1290 /* WSLUA_ATTRIBUTE Pinfo_src RW Source Address of this Packet */
1291 {"src", Pinfo_src, Pinfo_set_addr, PARAM_ADDR_SRC },
1293 /* WSLUA_ATTRIBUTE Pinfo_dst RW Destination Address of this Packet */
1294 {"dst", Pinfo_dst, Pinfo_set_addr, PARAM_ADDR_DST },
1296 /* WSLUA_ATTRIBUTE Pinfo_lo RO lower Address of this Packet */
1297 {"lo", Pinfo_lo, pushnil_param, PARAM_NONE },
1299 /* WSLUA_ATTRIBUTE Pinfo_hi RW higher Address of this Packet */
1300 {"hi", Pinfo_hi, pushnil_param, PARAM_NONE },
1302 /* WSLUA_ATTRIBUTE Pinfo_dl_src RW Data Link Source Address of this Packet */
1303 {"dl_src", Pinfo_dl_src, Pinfo_set_addr, PARAM_ADDR_DL_SRC },
1305 /* WSLUA_ATTRIBUTE Pinfo_dl_dst RW Data Link Destination Address of this Packet */
1306 {"dl_dst", Pinfo_dl_dst, Pinfo_set_addr, PARAM_ADDR_DL_DST },
1308 /* WSLUA_ATTRIBUTE Pinfo_net_src RW Network Layer Source Address of this Packet */
1309 {"net_src", Pinfo_net_src, Pinfo_set_addr, PARAM_ADDR_NET_SRC },
1311 /* WSLUA_ATTRIBUTE Pinfo_net_dst RW Network Layer Destination Address of this Packet */
1312 {"net_dst", Pinfo_net_dst, Pinfo_set_addr, PARAM_ADDR_NET_DST },
1314 /* WSLUA_ATTRIBUTE Pinfo_ptype RW Type of Port of .src_port and .dst_port */
1315 {"port_type", Pinfo_ptype, pushnil_param, PARAM_NONE },
1317 /* WSLUA_ATTRIBUTE Pinfo_src_port RW Source Port of this Packet */
1318 {"src_port", Pinfo_src_port, Pinfo_set_int, PARAM_PORT_SRC },
1320 /* WSLUA_ATTRIBUTE Pinfo_dst_port RW Source Address of this Packet */
1321 {"dst_port", Pinfo_dst_port, Pinfo_set_int, PARAM_PORT_SRC },
1323 /* WSLUA_ATTRIBUTE Pinfo_ipproto RO IP Protocol id */
1324 {"ipproto", Pinfo_ipproto, pushnil_param, PARAM_NONE },
1326 /* WSLUA_ATTRIBUTE Pinfo_circuit_id RO For circuit based protocols */
1327 {"circuit_id", Pinfo_circuit_id, Pinfo_set_int, PARAM_CIRCUIT_ID },
1329 /* WSLUA_ATTRIBUTE Pinfo_match RO Port/Data we are matching */
1330 {"match", Pinfo_match, pushnil_param, PARAM_NONE },
1332 /* WSLUA_ATTRIBUTE Pinfo_curr_proto RO Which Protocol are we dissecting */
1333 {"curr_proto", Pinfo_curr_proto, pushnil_param, PARAM_NONE },
1335 /* WSLUA_ATTRIBUTE Pinfo_columns RO Accesss to the packet list columns */
1336 {"columns", Pinfo_columns, pushnil_param, PARAM_NONE },
1338 /* WSLUA_ATTRIBUTE Pinfo_cols RO Accesss to the packet list columns (equivalent to pinfo.columns) */
1339 {"cols", Pinfo_columns, pushnil_param, PARAM_NONE },
1341 /* WSLUA_ATTRIBUTE Pinfo_desegment_len RW Estimated number of additional bytes required for completing the PDU */
1342 {"desegment_len", Pinfo_desegment_len, Pinfo_set_int, PARAM_DESEGMENT_LEN },
1344 /* WSLUA_ATTRIBUTE Pinfo_desegment_offset RW Offset in the tvbuff at which the dissector will continue processing when next called*/
1345 {"desegment_offset", Pinfo_desegment_offset, Pinfo_set_int, PARAM_DESEGMENT_OFFSET },
1347 /* WSLUA_ATTRIBUTE Pinfo_private_data RO Access to private data */
1348 {"private_data", Pinfo_private_data, pushnil_param, PARAM_NONE},
1350 /* WSLUA_ATTRIBUTE Pinfo_private RW Access to the private table entries */
1351 {"private", Pinfo_private, pushnil_param, PARAM_NONE},
1353 /* WSLUA_ATTRIBUTE Pinfo_ethertype RW Ethernet Type Code, if this is an Ethernet packet */
1354 {"ethertype", Pinfo_ethertype, Pinfo_set_int, PARAM_ETHERTYPE},
1356 /* WSLUA_ATTRIBUTE Pinfo_fragmented RO If the protocol is only a fragment */
1357 {"fragmented", Pinfo_fragmented, pushnil_param, PARAM_NONE},
1359 /* WSLUA_ATTRIBUTE Pinfo_in_error_pkt RO If we're inside an error packet */
1360 {"in_error_pkt", Pinfo_in_error_pkt, pushnil_param, PARAM_NONE},
1362 /* WSLUA_ATTRIBUTE Pinfo_match_uint RO Matched uint for calling subdissector from table */
1363 {"match_uint", Pinfo_match_uint, pushnil_param, PARAM_NONE },
1365 /* WSLUA_ATTRIBUTE Pinfo_match_string RO Matched string for calling subdissector from table */
1366 {"match_string", Pinfo_match_string, pushnil_param, PARAM_NONE },
1368 {NULL,NULL,NULL,PARAM_NONE}
1372 static int pushnil(lua_State* L) {
1377 static int Pinfo_index(lua_State* L) {
1378 Pinfo pinfo = checkPinfo(L,1);
1379 const gchar* name = luaL_checkstring(L,2);
1380 lua_CFunction method = pushnil;
1381 const pinfo_method_t* curr;
1383 if (! (pinfo && name) ) {
1387 if (pinfo->expired) {
1388 luaL_error(L,"expired_pinfo");
1392 for (curr = Pinfo_methods ; curr->name ; curr++) {
1393 if (g_str_equal(curr->name,name)) {
1403 static int Pinfo_setindex(lua_State* L) {
1404 Pinfo pinfo = checkPinfo(L,1);
1405 const gchar* name = luaL_checkstring(L,2);
1406 int (*method)(lua_State*, packet_info* pinfo, pinfo_param_type_t) = pushnil_param;
1407 const pinfo_method_t* curr;
1408 pinfo_param_type_t param_type = PARAM_NONE;
1410 if (! (pinfo && name) ) {
1413 if (pinfo->expired) {
1414 luaL_error(L,"expired_pinfo");
1418 for (curr = Pinfo_methods ; curr->name ; curr++) {
1419 if (g_str_equal(curr->name,name)) {
1421 param_type = curr->param;
1428 return method(L,pinfo->ws_pinfo,param_type);
1431 static int Pinfo_gc(lua_State* L) {
1432 Pinfo pinfo = checkPinfo(L,1);
1434 if (!pinfo) return 0;
1436 if (!pinfo->expired)
1437 pinfo->expired = TRUE;
1445 static const luaL_Reg Pinfo_meta[] = {
1446 {"__index", Pinfo_index},
1447 {"__newindex",Pinfo_setindex},
1448 {"__tostring", Pinfo_tostring},
1453 int Pinfo_register(lua_State* L) {
1454 WSLUA_REGISTER_META(Pinfo);
1455 outstanding_Pinfo = g_ptr_array_new();
1456 outstanding_Column = g_ptr_array_new();
1457 outstanding_Columns = g_ptr_array_new();
1458 outstanding_PrivateTable = g_ptr_array_new();