4 * Ethereal's interface to the Lua Programming Language
6 * (c) 2006, Luis E. Garcia Ontanon <luis.ontanon@gmail.com>
10 * Ethereal - Network traffic analyzer
11 * By Gerald Combs <gerald@ethereal.com>
12 * Copyright 1998 Gerald Combs
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
32 ELUA_CLASS_DEFINE(PseudoHeader,NOP)
34 A pseudoheader to be used to save captured frames.
37 enum lua_pseudoheader_type {
53 struct lua_pseudo_header {
54 enum lua_pseudoheader_type type;
55 union wtap_pseudo_header* wph;
58 ELUA_CONSTRUCTOR PseudoHeader_none(lua_State* L) {
60 Creates a "no" pseudoheader.
63 PseudoHeader ph = g_malloc(sizeof(struct lua_pseudo_header));
67 pushPseudoHeader(L,ph);
70 /* A null pseudoheader */
73 ELUA_CONSTRUCTOR PseudoHeader_eth(lua_State* L) {
75 Creates an ethernet pseudoheader
78 #define ELUA_OPTARG_PseudoHeader_eth_FCSLEN 1 /* the fcs lenght */
80 PseudoHeader ph = g_malloc(sizeof(struct lua_pseudo_header));
82 ph->wph = g_malloc(sizeof(union wtap_pseudo_header));
83 ph->wph->eth.fcs_len = luaL_optint(L,1,-1);
85 pushPseudoHeader(L,ph);
87 ELUA_RETURN(1); /* The ethernet pseudoheader */
90 ELUA_CONSTRUCTOR PseudoHeader_atm(lua_State* L) {
92 Creates an ATM pseudoheader
94 #define ELUA_OPTARG_PseudoHeader_atm_AAL 1 /* AAL number */
95 #define ELUA_OPTARG_PseudoHeader_atm_VPI 2 /* VPI */
96 #define ELUA_OPTARG_PseudoHeader_atm_VCI 3 /* VCI */
97 #define ELUA_OPTARG_PseudoHeader_atm_CHANNEL 4 /* Channel */
98 #define ELUA_OPTARG_PseudoHeader_atm_CELLS 5 /* Number of cells in the PDU */
99 #define ELUA_OPTARG_PseudoHeader_atm_AAL5U2U 6 /* AAL5 User to User indicator */
100 #define ELUA_OPTARG_PseudoHeader_atm_AAL5LEN 7 /* AAL5 Len */
102 PseudoHeader ph = g_malloc(sizeof(struct lua_pseudo_header));
104 ph->wph = g_malloc(sizeof(union wtap_pseudo_header));
105 ph->wph->atm.aal = luaL_optint(L,ELUA_OPTARG_PseudoHeader_atm_AAL,5);
106 ph->wph->atm.vpi = luaL_optint(L,ELUA_OPTARG_PseudoHeader_atm_VPI,1);
107 ph->wph->atm.vci = luaL_optint(L,ELUA_OPTARG_PseudoHeader_atm_VCI,1);
108 ph->wph->atm.channel = luaL_optint(L,ELUA_OPTARG_PseudoHeader_atm_CHANNEL,0);
109 ph->wph->atm.cells = luaL_optint(L,ELUA_OPTARG_PseudoHeader_atm_CELLS,1);
110 ph->wph->atm.aal5t_u2u = luaL_optint(L,ELUA_OPTARG_PseudoHeader_atm_AAL5U2U,1);
111 ph->wph->atm.aal5t_len = luaL_optint(L,ELUA_OPTARG_PseudoHeader_atm_AAL5LEN,0);
113 pushPseudoHeader(L,ph);
115 /* The ATM pseudoheader */
118 ELUA_CONSTRUCTOR PseudoHeader_mtp2(lua_State* L) {
119 /* Creates an MTP2 PseudoHeader */
120 #define ELUA_OPTARG_PseudoHeader_mtp2_SENT /* True if the packet is sent, False if received. */
121 #define ELUA_OPTARG_PseudoHeader_mtp2_ANNEXA /* True if annex A is used */
122 #define ELUA_OPTARG_PseudoHeader_mtp2_LINKNUM /* Link Number */
123 PseudoHeader ph = g_malloc(sizeof(struct lua_pseudo_header));
124 ph->type = PHDR_MTP2;
125 ph->wph = g_malloc(sizeof(union wtap_pseudo_header));
126 ph->wph->mtp2.sent = luaL_optint(L,1,0);
127 ph->wph->mtp2.annex_a_used = luaL_optint(L,2,0);
128 ph->wph->mtp2.link_number = luaL_optint(L,3,0);
130 pushPseudoHeader(L,ph);
131 ELUA_RETURN(1); /* The MTP2 pseudoheader */
135 static int PseudoHeader_x25(lua_State* L) { luaL_error(L,"not implemented"); return 0; }
136 static int PseudoHeader_isdn(lua_State* L) { luaL_error(L,"not implemented"); return 0; }
137 static int PseudoHeader_ascend(lua_State* L) { luaL_error(L,"not implemented"); return 0; }
138 static int PseudoHeader_wifi(lua_State* L) { luaL_error(L,"not implemented"); return 0; }
139 static int PseudoHeader_cosine(lua_State* L) { luaL_error(L,"not implemented"); return 0; }
140 static int PseudoHeader_irda(lua_State* L) { luaL_error(L,"not implemented"); return 0; }
141 static int PseudoHeader_nettl(lua_State* L) { luaL_error(L,"not implemented"); return 0; }
142 static int PseudoHeader_k12(lua_State* L) { luaL_error(L,"not implemented"); return 0; }
145 ELUA_METHODS PseudoHeader_methods[] = {
146 ELUA_CLASS_FNREG(PseudoHeader,mtp2),
147 ELUA_CLASS_FNREG(PseudoHeader,atm),
148 ELUA_CLASS_FNREG(PseudoHeader,eth),
149 ELUA_CLASS_FNREG(PseudoHeader,none),
153 ELUA_META PseudoHeader_meta[] = {
157 int PseudoHeader_register(lua_State* L) {
158 ELUA_REGISTER_CLASS(PseudoHeader)
163 ELUA_CLASS_DEFINE(Dumper,FAIL_ON_NULL("Dumper already closed"))
165 static GHashTable* dumper_encaps = NULL;
166 #define DUMPER_ENCAP(d) GPOINTER_TO_INT(g_hash_table_lookup(dumper_encaps,d))
168 ELUA_CONSTRUCTOR Dumper_new(lua_State* L) {
170 Creates a file to write packets.
171 Dumper:new_for_current() will probably be a better choice.
173 #define ELUA_ARG_Dumper_new_FILENAME 1 /* The name of the capture file to be created */
174 #define ELUA_OPTARG_Dumper_new_FILETYPE 3 /* The type of the file to be created */
175 #define ELUA_OPTARG_Dumper_new_ENCAP 3 /* The encapsulation to be used in the file to be created */
177 const char* filename = luaL_checkstring(L,1);
178 int filetype = luaL_optint(L,2,WTAP_FILE_PCAP);
179 int encap = luaL_optint(L,3,WTAP_ENCAP_ETHERNET);
182 if (! filename) return 0;
184 if (!wtap_dump_can_write_encap(filetype, encap))
185 ELUA_ERROR(Dumper_new,"not every filetype handles every encap");
187 d = wtap_dump_open(filename, filetype, encap,0 , FALSE, &err);
190 /* ELUA_ERROR("error while opening file for writing"); */
191 luaL_error(L,"error while opening `%s': %s",
197 g_hash_table_insert(dumper_encaps,d,GINT_TO_POINTER(encap));
201 /* The newly created Dumper object */
204 ELUA_METHOD Dumper_close(lua_State* L) {
205 /* Closes a dumper */
206 Dumper* dp = (Dumper*)luaL_checkudata(L, 1, "Dumper");
210 ELUA_ERROR(Dumper_close,"Cannot operate on a closed dumper");
212 g_hash_table_remove(dumper_encaps,*dp);
214 if (!wtap_dump_close(*dp, &err)) {
215 luaL_error(L,"error closing: %s",
219 /* this way if we close a dumper any attempt to use it (for everything but GC) will yield an error */
225 ELUA_METHOD Dumper_flush(lua_State* L) {
227 Writes all unsaved data of a dumper to the disk.
229 Dumper d = checkDumper(L,1);
238 ELUA_METHOD Dumper_dump(lua_State* L) {
240 Dumps an arbitrary packet.
241 Note: Dumper:dump_current() will fit best in most cases.
243 #define ELUA_ARG_Dumper_dump_TIMESTAMP 2 /* The absolute timestamp the packet will have */
244 #define ELUA_ARG_Dumper_dump_PSEUDOHEADER 3 /* The Pseudoheader to use. */
245 #define ELUA_ARG_Dumper_dump_BYTEARRAY 4 /* the data to be saved */
247 Dumper d = checkDumper(L,1);
250 struct wtap_pkthdr pkthdr;
256 ts = luaL_checknumber(L,ELUA_ARG_Dumper_dump_TIMESTAMP);
257 ph = checkPseudoHeader(L,ELUA_ARG_Dumper_dump_PSEUDOHEADER);
259 if (!ph) ELUA_ARG_ERROR(Dumper_dump,TIMESTAMP,"need a PseudoHeader");
261 ba = checkByteArray(L,ELUA_ARG_Dumper_dump_BYTEARRAY);
263 if (! ba) ELUA_ARG_ERROR(Dumper_dump,BYTEARRAY,"must be a ByteArray");
265 pkthdr.ts.secs = (int)floor(ts);
266 pkthdr.ts.nsecs = (int)floor(ts - pkthdr.ts.secs) * 1000000000;
267 pkthdr.len = ba->len;
268 pkthdr.caplen = ba->len;
269 pkthdr.pkt_encap = DUMPER_ENCAP(d);
271 if (! wtap_dump(d, &pkthdr, ph->wph, ba->data, &err)) {
272 luaL_error(L,"error while dumping: %s",
280 ELUA_METHOD Dumper_new_for_current(lua_State* L) {
282 Creates a capture file using the same encapsulation as the one of the cuurrent packet
284 #define ELUA_OPTARG_Dumper_new_for_current_FILETYPE 2 /* The file type. Defaults to pcap. */
286 const char* filename = luaL_checkstring(L,1);
287 int filetype = luaL_optint(L,2,WTAP_FILE_PCAP);
292 ELUA_ERROR(Dumper_new_for_current,"cannot be used outside a tap or a dissector");
294 encap = lua_pinfo->fd->lnk_t;
296 if (!wtap_dump_can_write_encap(filetype, encap)) {
297 luaL_error(L,"Cannot write encap %s in filetype %s",
298 wtap_encap_short_string(encap),
299 wtap_file_type_string(filetype));
303 d = wtap_dump_open(filename, filetype, encap, 0 , FALSE, &err);
306 luaL_error(L,"error while opening `%s': %s",
313 ELUA_RETURN(1); /* The newly created Dumper Object */
317 ELUA_METHOD Dumper_dump_current(lua_State* L) {
319 Dumps the current packet as it is.
321 Dumper d = checkDumper(L,1);
322 struct wtap_pkthdr pkthdr;
329 if (! lua_pinfo ) ELUA_ERROR(Dumper_new_for_current,"cannot be used outside a tap or a dissector");
331 data_src = ((data_source*)(lua_pinfo->data_src->data))->tvb;
333 pkthdr.ts.secs = lua_pinfo->fd->abs_ts.secs;
334 pkthdr.ts.nsecs = lua_pinfo->fd->abs_ts.nsecs;
335 pkthdr.len = tvb_reported_length(data_src);
336 pkthdr.caplen = tvb_length(data_src);
337 pkthdr.pkt_encap = lua_pinfo->fd->lnk_t;
339 data = ep_tvb_memdup(data_src,0,pkthdr.caplen);
341 if (! wtap_dump(d, &pkthdr, lua_pinfo->pseudo_header, data, &err)) {
342 luaL_error(L,"error while dumping: %s",
349 static int Dumper__gc(lua_State* L) {
350 Dumper* dp = (Dumper*)luaL_checkudata(L, 1, "Dumper");
353 /* If we are Garbage Collected it means the Dumper is no longer usable. Close it */
356 return 0; /* already closed, nothing to do! */
358 g_hash_table_remove(dumper_encaps,*dp);
360 if (!wtap_dump_close(*dp, &err)) {
361 luaL_error(L,"error closing: %s",
369 ELUA_METHODS Dumper_methods[] = {
371 {"new_for_current", Dumper_new_for_current},
372 {"close", Dumper_close},
373 {"flush", Dumper_flush},
374 {"dump", Dumper_dump},
375 {"dump_current", Dumper_dump_current},
379 ELUA_META Dumper_meta[] = {
380 {"__gc", Dumper__gc},
384 int Dumper_register(lua_State* L) {
385 dumper_encaps = g_hash_table_new(g_direct_hash,g_direct_equal);
386 ELUA_REGISTER_CLASS(Dumper);