4 * Wireshark's interface to the Lua Programming Language
6 * (c) 2006, Luis E. Garcia Ontanon <luis.ontanon@gmail.com>
10 * Wireshark - Network traffic analyzer
11 * By Gerald Combs <gerald@wireshark.org>
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.
29 /* WSLUA_MODULE Dumper saving capture files */
34 WSLUA_CLASS_DEFINE(PseudoHeader,NOP,NOP);
36 A pseudoheader to be used to save captured frames.
39 enum lua_pseudoheader_type {
55 struct lua_pseudo_header {
56 enum lua_pseudoheader_type type;
57 union wtap_pseudo_header* wph;
60 WSLUA_CONSTRUCTOR PseudoHeader_none(lua_State* L) {
62 Creates a "no" pseudoheader.
65 PseudoHeader ph = g_malloc(sizeof(struct lua_pseudo_header));
69 pushPseudoHeader(L,ph);
72 /* A null pseudoheader */
75 WSLUA_CONSTRUCTOR PseudoHeader_eth(lua_State* L) {
77 Creates an ethernet pseudoheader
80 #define WSLUA_OPTARG_PseudoHeader_eth_FCSLEN 1 /* the fcs length */
82 PseudoHeader ph = g_malloc(sizeof(struct lua_pseudo_header));
84 ph->wph = g_malloc(sizeof(union wtap_pseudo_header));
85 ph->wph->eth.fcs_len = luaL_optint(L,1,-1);
87 pushPseudoHeader(L,ph);
89 WSLUA_RETURN(1); /* The ethernet pseudoheader */
92 WSLUA_CONSTRUCTOR PseudoHeader_atm(lua_State* L) {
94 Creates an ATM pseudoheader
96 #define WSLUA_OPTARG_PseudoHeader_atm_AAL 1 /* AAL number */
97 #define WSLUA_OPTARG_PseudoHeader_atm_VPI 2 /* VPI */
98 #define WSLUA_OPTARG_PseudoHeader_atm_VCI 3 /* VCI */
99 #define WSLUA_OPTARG_PseudoHeader_atm_CHANNEL 4 /* Channel */
100 #define WSLUA_OPTARG_PseudoHeader_atm_CELLS 5 /* Number of cells in the PDU */
101 #define WSLUA_OPTARG_PseudoHeader_atm_AAL5U2U 6 /* AAL5 User to User indicator */
102 #define WSLUA_OPTARG_PseudoHeader_atm_AAL5LEN 7 /* AAL5 Len */
104 PseudoHeader ph = g_malloc(sizeof(struct lua_pseudo_header));
106 ph->wph = g_malloc(sizeof(union wtap_pseudo_header));
107 ph->wph->atm.aal = luaL_optint(L,WSLUA_OPTARG_PseudoHeader_atm_AAL,5);
108 ph->wph->atm.vpi = luaL_optint(L,WSLUA_OPTARG_PseudoHeader_atm_VPI,1);
109 ph->wph->atm.vci = luaL_optint(L,WSLUA_OPTARG_PseudoHeader_atm_VCI,1);
110 ph->wph->atm.channel = luaL_optint(L,WSLUA_OPTARG_PseudoHeader_atm_CHANNEL,0);
111 ph->wph->atm.cells = luaL_optint(L,WSLUA_OPTARG_PseudoHeader_atm_CELLS,1);
112 ph->wph->atm.aal5t_u2u = luaL_optint(L,WSLUA_OPTARG_PseudoHeader_atm_AAL5U2U,1);
113 ph->wph->atm.aal5t_len = luaL_optint(L,WSLUA_OPTARG_PseudoHeader_atm_AAL5LEN,0);
115 pushPseudoHeader(L,ph);
117 /* The ATM pseudoheader */
120 WSLUA_CONSTRUCTOR PseudoHeader_mtp2(lua_State* L) {
121 /* Creates an MTP2 PseudoHeader */
122 #define WSLUA_OPTARG_PseudoHeader_mtp2_SENT 1 /* True if the packet is sent, False if received. */
123 #define WSLUA_OPTARG_PseudoHeader_mtp2_ANNEXA 2 /* True if annex A is used */
124 #define WSLUA_OPTARG_PseudoHeader_mtp2_LINKNUM 3 /* Link Number */
125 PseudoHeader ph = g_malloc(sizeof(struct lua_pseudo_header));
126 ph->type = PHDR_MTP2;
127 ph->wph = g_malloc(sizeof(union wtap_pseudo_header));
128 ph->wph->mtp2.sent = luaL_optint(L,1,0);
129 ph->wph->mtp2.annex_a_used = luaL_optint(L,2,0);
130 ph->wph->mtp2.link_number = luaL_optint(L,3,0);
132 pushPseudoHeader(L,ph);
133 WSLUA_RETURN(1); /* The MTP2 pseudoheader */
137 static int PseudoHeader_x25(lua_State* L) { luaL_error(L,"not implemented"); return 0; }
138 static int PseudoHeader_isdn(lua_State* L) { luaL_error(L,"not implemented"); return 0; }
139 static int PseudoHeader_ascend(lua_State* L) { luaL_error(L,"not implemented"); return 0; }
140 static int PseudoHeader_wifi(lua_State* L) { luaL_error(L,"not implemented"); return 0; }
141 static int PseudoHeader_cosine(lua_State* L) { luaL_error(L,"not implemented"); return 0; }
142 static int PseudoHeader_irda(lua_State* L) { luaL_error(L,"not implemented"); return 0; }
143 static int PseudoHeader_nettl(lua_State* L) { luaL_error(L,"not implemented"); return 0; }
144 static int PseudoHeader_k12(lua_State* L) { luaL_error(L,"not implemented"); return 0; }
147 WSLUA_METHODS PseudoHeader_methods[] = {
148 WSLUA_CLASS_FNREG(PseudoHeader,mtp2),
149 WSLUA_CLASS_FNREG(PseudoHeader,atm),
150 WSLUA_CLASS_FNREG(PseudoHeader,eth),
151 WSLUA_CLASS_FNREG(PseudoHeader,none),
155 WSLUA_META PseudoHeader_meta[] = {
159 int PseudoHeader_register(lua_State* L) {
160 WSLUA_REGISTER_CLASS(PseudoHeader)
165 WSLUA_CLASS_DEFINE(Dumper,FAIL_ON_NULL("Dumper already closed"),NOP);
167 static GHashTable* dumper_encaps = NULL;
168 #define DUMPER_ENCAP(d) GPOINTER_TO_INT(g_hash_table_lookup(dumper_encaps,d))
170 static const char* cross_plat_fname(const char* fname) {
171 static char fname_clean[256];
174 strncpy(fname_clean,fname,256);
176 for(f = fname_clean; *f; f++) {
179 *f = *(G_DIR_SEPARATOR_S);
189 WSLUA_CONSTRUCTOR Dumper_new(lua_State* L) {
191 Creates a file to write packets.
192 Dumper:new_for_current() will probably be a better choice.
194 #define WSLUA_ARG_Dumper_new_FILENAME 1 /* The name of the capture file to be created */
195 #define WSLUA_OPTARG_Dumper_new_FILETYPE 2 /* The type of the file to be created */
196 #define WSLUA_OPTARG_Dumper_new_ENCAP 3 /* The encapsulation to be used in the file to be created */
198 const char* fname = luaL_checkstring(L,1);
199 int filetype = luaL_optint(L,2,WTAP_FILE_PCAP);
200 int encap = luaL_optint(L,3,WTAP_ENCAP_ETHERNET);
202 const char* filename;
204 if (! fname) return 0;
206 filename = cross_plat_fname(fname);
208 if (!wtap_dump_can_write_encap(filetype, encap))
209 WSLUA_ERROR(Dumper_new,"not every filetype handles every encap");
211 d = wtap_dump_open(filename, filetype, encap,0 , FALSE, &err);
214 /* WSLUA_ERROR("error while opening file for writing"); */
215 luaL_error(L,"error while opening `%s': %s",
221 g_hash_table_insert(dumper_encaps,d,GINT_TO_POINTER(encap));
225 /* The newly created Dumper object */
228 WSLUA_METHOD Dumper_close(lua_State* L) {
229 /* Closes a dumper */
230 Dumper* dp = (Dumper*)luaL_checkudata(L, 1, "Dumper");
234 WSLUA_ERROR(Dumper_close,"Cannot operate on a closed dumper");
236 g_hash_table_remove(dumper_encaps,*dp);
238 if (!wtap_dump_close(*dp, &err)) {
239 luaL_error(L,"error closing: %s",
243 /* this way if we close a dumper any attempt to use it (for everything but GC) will yield an error */
249 WSLUA_METHOD Dumper_flush(lua_State* L) {
251 Writes all unsaved data of a dumper to the disk.
253 Dumper d = checkDumper(L,1);
262 WSLUA_METHOD Dumper_dump(lua_State* L) {
264 Dumps an arbitrary packet.
265 Note: Dumper:dump_current() will fit best in most cases.
267 #define WSLUA_ARG_Dumper_dump_TIMESTAMP 2 /* The absolute timestamp the packet will have */
268 #define WSLUA_ARG_Dumper_dump_PSEUDOHEADER 3 /* The Pseudoheader to use. */
269 #define WSLUA_ARG_Dumper_dump_BYTEARRAY 4 /* the data to be saved */
271 Dumper d = checkDumper(L,1);
274 struct wtap_pkthdr pkthdr;
280 ts = luaL_checknumber(L,WSLUA_ARG_Dumper_dump_TIMESTAMP);
281 ph = checkPseudoHeader(L,WSLUA_ARG_Dumper_dump_PSEUDOHEADER);
283 if (!ph) WSLUA_ARG_ERROR(Dumper_dump,TIMESTAMP,"need a PseudoHeader");
285 ba = checkByteArray(L,WSLUA_ARG_Dumper_dump_BYTEARRAY);
287 if (! ba) WSLUA_ARG_ERROR(Dumper_dump,BYTEARRAY,"must be a ByteArray");
289 pkthdr.ts.secs = (unsigned)floor(ts);
290 pkthdr.ts.nsecs = (unsigned)floor((ts - (double)pkthdr.ts.secs) * 1000000000);
292 pkthdr.len = ba->len;
293 pkthdr.caplen = ba->len;
294 pkthdr.pkt_encap = DUMPER_ENCAP(d);
296 if (! wtap_dump(d, &pkthdr, ph->wph, ba->data, &err)) {
297 luaL_error(L,"error while dumping: %s",
305 WSLUA_METHOD Dumper_new_for_current(lua_State* L) {
307 Creates a capture file using the same encapsulation as the one of the cuurrent packet
309 #define WSLUA_OPTARG_Dumper_new_for_current_FILETYPE 2 /* The file type. Defaults to pcap. */
311 const char* fname = luaL_checkstring(L,1);
312 int filetype = luaL_optint(L,2,WTAP_FILE_PCAP);
315 const char* filename;
317 if (! fname) return 0;
319 filename = cross_plat_fname(fname);
322 WSLUA_ERROR(Dumper_new_for_current,"cannot be used outside a tap or a dissector");
324 encap = lua_pinfo->fd->lnk_t;
326 if (!wtap_dump_can_write_encap(filetype, encap)) {
327 luaL_error(L,"Cannot write encap %s in filetype %s",
328 wtap_encap_short_string(encap),
329 wtap_file_type_string(filetype));
333 d = wtap_dump_open(filename, filetype, encap, 0 , FALSE, &err);
336 luaL_error(L,"error while opening `%s': %s",
343 WSLUA_RETURN(1); /* The newly created Dumper Object */
347 WSLUA_METHOD Dumper_dump_current(lua_State* L) {
349 Dumps the current packet as it is.
351 Dumper d = checkDumper(L,1);
352 struct wtap_pkthdr pkthdr;
359 if (! lua_pinfo ) WSLUA_ERROR(Dumper_new_for_current,"cannot be used outside a tap or a dissector");
361 data_src = ((data_source*)(lua_pinfo->data_src->data))->tvb;
363 pkthdr.ts.secs = lua_pinfo->fd->abs_ts.secs;
364 pkthdr.ts.nsecs = lua_pinfo->fd->abs_ts.nsecs;
365 pkthdr.len = tvb_reported_length(data_src);
366 pkthdr.caplen = tvb_length(data_src);
367 pkthdr.pkt_encap = lua_pinfo->fd->lnk_t;
369 data = ep_tvb_memdup(data_src,0,pkthdr.caplen);
371 if (! wtap_dump(d, &pkthdr, lua_pinfo->pseudo_header, data, &err)) {
372 luaL_error(L,"error while dumping: %s",
379 static int Dumper__gc(lua_State* L) {
380 Dumper* dp = (Dumper*)luaL_checkudata(L, 1, "Dumper");
383 /* If we are Garbage Collected it means the Dumper is no longer usable. Close it */
386 return 0; /* already closed, nothing to do! */
388 g_hash_table_remove(dumper_encaps,*dp);
390 if (!wtap_dump_close(*dp, &err)) {
391 luaL_error(L,"error closing: %s",
399 WSLUA_METHODS Dumper_methods[] = {
401 {"new_for_current", Dumper_new_for_current},
402 {"close", Dumper_close},
403 {"flush", Dumper_flush},
404 {"dump", Dumper_dump},
405 {"dump_current", Dumper_dump_current},
409 WSLUA_META Dumper_meta[] = {
410 {"__gc", Dumper__gc},
414 int Dumper_register(lua_State* L) {
415 dumper_encaps = g_hash_table_new(g_direct_hash,g_direct_equal);
416 WSLUA_REGISTER_CLASS(Dumper);