1 /*
2 * wslua_column.c
3 *
4 * Wireshark's interface to the Lua Programming Language
5 *
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>
9 * (c) 2014, Hadriel Kaplan <hadrielk@yahoo.com>
10 *
11 * Wireshark - Network traffic analyzer
12 * By Gerald Combs <gerald@wireshark.org>
13 * Copyright 1998 Gerald Combs
14 *
15 * SPDX-License-Identifier: GPL-2.0-or-later
16 */
17 #include "config.h"
18
19 #include "wslua_pinfo_common.h"
20
21
22 /* WSLUA_CONTINUE_MODULE Pinfo */
23
24
25 static GPtrArray* outstanding_Column = NULL;
26 static GPtrArray* outstanding_Columns = NULL;
27
CLEAR_OUTSTANDING(Column,expired,TRUE)28 CLEAR_OUTSTANDING(Column,expired, TRUE)
29 CLEAR_OUTSTANDING(Columns,expired, TRUE)
30
31 #define PUSH_COLUMN(L,c) {g_ptr_array_add(outstanding_Column,c);pushColumn(L,c);}
32
33 void Push_Columns(lua_State *L, Columns c)
34 {
35 g_ptr_array_add(outstanding_Columns, c);
36 pushColumns(L, c);
37 }
38
39
40 WSLUA_CLASS_DEFINE(Column,FAIL_ON_NULL("Column")); /* A Column in the packet list. */
41
42 struct col_names_t {
43 const gchar* name;
44 int id;
45 };
46
47 // Duplicated belown in Columns__newindex.
48 static const struct col_names_t colnames[] = {
49 {"number",COL_NUMBER},
50 {"abs_time",COL_ABS_TIME},
51 {"utc_time",COL_UTC_TIME},
52 {"cls_time",COL_CLS_TIME},
53 {"rel_time",COL_REL_TIME},
54 {"date",COL_ABS_YMD_TIME},
55 {"date_doy",COL_ABS_YDOY_TIME},
56 {"utc_date",COL_UTC_YMD_TIME},
57 {"utc_date_doy",COL_UTC_YDOY_TIME},
58 {"delta_time",COL_DELTA_TIME},
59 {"delta_time_displayed",COL_DELTA_TIME_DIS},
60 {"src",COL_DEF_SRC},
61 {"src_res",COL_RES_SRC},
62 {"src_unres",COL_UNRES_SRC},
63 {"dl_src",COL_DEF_DL_SRC},
64 {"dl_src_res",COL_RES_DL_SRC},
65 {"dl_src_unres",COL_UNRES_DL_SRC},
66 {"net_src",COL_DEF_NET_SRC},
67 {"net_src_res",COL_RES_NET_SRC},
68 {"net_src_unres",COL_UNRES_NET_SRC},
69 {"dst",COL_DEF_DST},
70 {"dst_res",COL_RES_DST},
71 {"dst_unres",COL_UNRES_DST},
72 {"dl_dst",COL_DEF_DL_DST},
73 {"dl_dst_res",COL_RES_DL_DST},
74 {"dl_dst_unres",COL_UNRES_DL_DST},
75 {"net_dst",COL_DEF_NET_DST},
76 {"net_dst_res",COL_RES_NET_DST},
77 {"net_dst_unres",COL_UNRES_NET_DST},
78 {"src_port",COL_DEF_SRC_PORT},
79 {"src_port_res",COL_RES_SRC_PORT},
80 {"src_port_unres",COL_UNRES_SRC_PORT},
81 {"dst_port",COL_DEF_DST_PORT},
82 {"dst_port_res",COL_RES_DST_PORT},
83 {"dst_port_unres",COL_UNRES_DST_PORT},
84 {"protocol",COL_PROTOCOL},
85 {"info",COL_INFO},
86 {"packet_len",COL_PACKET_LENGTH},
87 {"cumulative_bytes",COL_CUMULATIVE_BYTES},
88 {"direction",COL_IF_DIR},
89 {"vsan",COL_VSAN},
90 {"tx_rate",COL_TX_RATE},
91 {"rssi",COL_RSSI},
92 {"dce_call",COL_DCE_CALL},
93 {NULL,0}
94 };
95
col_name_to_id(const gchar * name)96 static gint col_name_to_id(const gchar* name) {
97 const struct col_names_t* cn;
98 for(cn = colnames; cn->name; cn++) {
99 if (g_str_equal(cn->name,name)) {
100 return cn->id;
101 }
102 }
103
104 return 0;
105 }
106
col_id_to_name(gint id)107 static const gchar* col_id_to_name(gint id) {
108 const struct col_names_t* cn;
109 for(cn = colnames; cn->name; cn++) {
110 if ( cn->id == id ) {
111 return cn->name;
112 }
113 }
114 return NULL;
115 }
116
117
Column__tostring(lua_State * L)118 WSLUA_METAMETHOD Column__tostring(lua_State *L) {
119 Column c = checkColumn(L,1);
120 const gchar* text;
121
122 if (!c->cinfo) {
123 text = col_id_to_name(c->col);
124 lua_pushfstring(L, "(%s)", text ? text : "unknown");
125 }
126 else {
127 text = col_get_text(c->cinfo, c->col);
128 lua_pushstring(L, text ? text : "(nil)");
129 }
130
131 WSLUA_RETURN(1); /* The column's string text (in parenthesis if not available). */
132 }
133
134 /* Gets registered as metamethod automatically by WSLUA_REGISTER_CLASS */
Column__gc(lua_State * L)135 static int Column__gc(lua_State* L) {
136 Column col = toColumn(L,1);
137
138 if (!col) return 0;
139
140 if (!col->expired)
141 col->expired = TRUE;
142 else
143 g_free(col);
144
145 return 0;
146
147 }
148
Column_clear(lua_State * L)149 WSLUA_METHOD Column_clear(lua_State *L) {
150 /* Clears a Column. */
151 Column c = checkColumn(L,1);
152
153 if (!(c->cinfo)) return 0;
154
155 col_clear(c->cinfo, c->col);
156
157 return 0;
158 }
159
Column_set(lua_State * L)160 WSLUA_METHOD Column_set(lua_State *L) {
161 /* Sets the text of a Column. */
162 #define WSLUA_ARG_Column_set_TEXT 2 /* The text to which to set the Column. */
163 Column c = checkColumn(L,1);
164 const gchar* s = luaL_checkstring(L,WSLUA_ARG_Column_set_TEXT);
165
166 if (!(c->cinfo))
167 return 0;
168
169 col_add_str(c->cinfo, c->col, s);
170
171 return 0;
172 }
173
Column_append(lua_State * L)174 WSLUA_METHOD Column_append(lua_State *L) {
175 /* Appends text to a Column. */
176 #define WSLUA_ARG_Column_append_TEXT 2 /* The text to append to the Column. */
177 Column c = checkColumn(L,1);
178 const gchar* s = luaL_checkstring(L,WSLUA_ARG_Column_append_TEXT);
179
180 if (!(c->cinfo))
181 return 0;
182
183 col_append_str(c->cinfo, c->col, s);
184
185 return 0;
186 }
187
Column_prepend(lua_State * L)188 WSLUA_METHOD Column_prepend(lua_State *L) {
189 /* Prepends text to a Column. */
190 #define WSLUA_ARG_Column_prepend_TEXT 2 /* The text to prepend to the Column. */
191 Column c = checkColumn(L,1);
192 const gchar* s = luaL_checkstring(L,WSLUA_ARG_Column_prepend_TEXT);
193
194 if (!(c->cinfo))
195 return 0;
196
197 col_prepend_fstr(c->cinfo, c->col, "%s",s);
198
199 return 0;
200 }
201
Column_fence(lua_State * L)202 WSLUA_METHOD Column_fence(lua_State *L) {
203 /* Sets Column text fence, to prevent overwriting.
204
205 @since 1.10.6
206 */
207 Column c = checkColumn(L,1);
208
209 if (c->cinfo)
210 col_set_fence(c->cinfo, c->col);
211
212 return 0;
213 }
214
Column_clear_fence(lua_State * L)215 WSLUA_METHOD Column_clear_fence(lua_State *L) {
216 /* Clear Column text fence.
217
218 @since 1.11.3
219 */
220 Column c = checkColumn(L,1);
221
222 if (c->cinfo)
223 col_clear_fence(c->cinfo, c->col);
224
225 return 0;
226 }
227
228
229 WSLUA_METHODS Column_methods[] = {
230 WSLUA_CLASS_FNREG(Column,clear),
231 WSLUA_CLASS_FNREG(Column,set),
232 WSLUA_CLASS_FNREG(Column,append),
233 WSLUA_CLASS_FNREG(Column,prepend),
234 WSLUA_CLASS_FNREG_ALIAS(Column,preppend,prepend),
235 WSLUA_CLASS_FNREG(Column,fence),
236 WSLUA_CLASS_FNREG(Column,clear_fence),
237 { NULL, NULL }
238 };
239
240
241 WSLUA_META Column_meta[] = {
242 WSLUA_CLASS_MTREG(Column,tostring),
243 { NULL, NULL }
244 };
245
246
Column_register(lua_State * L)247 int Column_register(lua_State *L) {
248 WSLUA_REGISTER_CLASS(Column);
249 outstanding_Column = g_ptr_array_new();
250 return 0;
251 }
252
253
254 WSLUA_CLASS_DEFINE(Columns,NOP); /* The <<lua_class_Column,``Column``>>s of the packet list. */
255
Columns__tostring(lua_State * L)256 WSLUA_METAMETHOD Columns__tostring(lua_State *L) {
257 lua_pushstring(L,"Columns");
258 WSLUA_RETURN(1);
259 /* The string "Columns". This has no real use aside from debugging. */
260 }
261
262 /*
263 * To document this is very odd - it won't make sense to a person reading the
264 * API docs to see this metamethod as a method, but oh well.
265 */
Columns__newindex(lua_State * L)266 WSLUA_METAMETHOD Columns__newindex(lua_State *L) { /*
267 Sets the text of a specific column.
268 Some columns cannot be modified, and no error is raised if attempted.
269 The columns that are known to allow modification are "info" and "protocol".
270 */
271 #define WSLUA_ARG_Columns__newindex_COLUMN 2 /*
272 The name of the column to set.
273 Valid values are:
274
275 [options="header"]
276 |===
277 |Name |Description
278 |number |Frame number
279 |abs_time |Absolute timestamp
280 |utc_time |UTC timestamp
281 |cls_time |CLS timestamp
282 |rel_time |Relative timestamp
283 |date |Absolute date and time
284 |date_doy |Absolute year, day of year, and time
285 |utc_date |UTC date and time
286 |utc_date_doy |UTC year, day of year, and time
287 |delta_time |Delta time from previous packet
288 |delta_time_displayed |Delta time from previous displayed packet
289 |src |Source address
290 |src_res |Resolved source address
291 |src_unres |Numeric source address
292 |dl_src |Source data link address
293 |dl_src_res |Resolved source data link address
294 |dl_src_unres |Numeric source data link address
295 |net_src |Source network address
296 |net_src_res |Resolved source network address
297 |net_src_unres |Numeric source network address
298 |dst |Destination address
299 |dst_res |Resolve destination address
300 |dst_unres |Numeric destination address
301 |dl_dst |Destination data link address
302 |dl_dst_res |Resolved destination data link address
303 |dl_dst_unres |Numeric destination data link address
304 |net_dst |Destination network address
305 |net_dst_res |Resolved destination network address
306 |net_dst_unres |Numeric destination network address
307 |src_port |Source port
308 |src_port_res |Resolved source port
309 |src_port_unres |Numeric source port
310 |dst_port |Destination port
311 |dst_port_res |Resolved destination port
312 |dst_port_unres |Numeric destination port
313 |protocol |Protocol name
314 |info |General packet information
315 |packet_len |Packet length
316 |cumulative_bytes |Cumulative bytes in the capture
317 |direction |Packet direction
318 |vsan |Virtual SAN
319 |tx_rate |Transmit rate
320 |rssi |RSSI value
321 |dce_call |DCE call
322 |===
323
324 ===== Example
325 pinfo.cols['info'] = 'foo bar'
326
327 -- syntactic sugar (equivalent to above)
328 pinfo.cols.info = 'foo bar'
329 */
330 #define WSLUA_ARG_Columns__newindex_TEXT 3 /* The text for the column. */
331 Columns cols = checkColumns(L,1);
332 const struct col_names_t* cn;
333 const char* colname;
334 const char* text;
335
336 if (!cols) return 0;
337 if (cols->expired) {
338 luaL_error(L,"expired column");
339 return 0;
340 }
341
342 colname = luaL_checkstring(L,WSLUA_ARG_Columns__newindex_COLUMN);
343 text = luaL_checkstring(L,WSLUA_ARG_Columns__newindex_TEXT);
344
345 for(cn = colnames; cn->name; cn++) {
346 if( g_str_equal(cn->name,colname) ) {
347 col_add_str(cols->cinfo, cn->id, text);
348 return 0;
349 }
350 }
351
352 WSLUA_ARG_ERROR(Columns__newindex,COLUMN,"the column name must be a valid column");
353 return 0;
354 }
355
Columns__index(lua_State * L)356 WSLUA_METAMETHOD Columns__index(lua_State *L) {
357 /* Get a specific <<lua_class_Column,``Column``>>. */
358 Columns cols = checkColumns(L,1);
359 const struct col_names_t* cn;
360 const char* colname = luaL_checkstring(L,2);
361
362 if (!cols) {
363 Column c = (Column)g_malloc(sizeof(struct _wslua_col_info));
364 c->cinfo = NULL;
365 c->col = col_name_to_id(colname);
366 c->expired = FALSE;
367
368 PUSH_COLUMN(L,c);
369 return 1;
370 }
371
372
373 if (cols->expired) {
374 luaL_error(L,"expired column");
375 return 0;
376 }
377
378 for(cn = colnames; cn->name; cn++) {
379 if( g_str_equal(cn->name,colname) ) {
380 Column c = (Column)g_malloc(sizeof(struct _wslua_col_info));
381 c->cinfo = cols->cinfo;
382 c->col = col_name_to_id(colname);
383 c->expired = FALSE;
384
385 PUSH_COLUMN(L,c);
386 return 1;
387 }
388 }
389
390 return 0;
391 }
392
393 /* for internal use - used by Pinfo */
get_Columns_index(lua_State * L)394 int get_Columns_index(lua_State *L)
395 {
396 return Columns__index(L);
397 }
398
399
400 /* Gets registered as metamethod automatically by WSLUA_REGISTER_META */
Columns__gc(lua_State * L)401 static int Columns__gc(lua_State* L) {
402 Columns cols = toColumns(L,1);
403
404 if (!cols) return 0;
405
406 if (!cols->expired)
407 cols->expired = TRUE;
408 else
409 g_free(cols);
410
411 return 0;
412
413 }
414
415
416 WSLUA_META Columns_meta[] = {
417 WSLUA_CLASS_MTREG(Columns,tostring),
418 WSLUA_CLASS_MTREG(Columns,newindex),
419 WSLUA_CLASS_MTREG(Columns,index),
420 { NULL, NULL }
421 };
422
423
Columns_register(lua_State * L)424 int Columns_register(lua_State *L) {
425 WSLUA_REGISTER_META(Columns);
426 outstanding_Columns = g_ptr_array_new();
427 return 0;
428 }
429
430
431
432 /*
433 * Editor modelines - https://www.wireshark.org/tools/modelines.html
434 *
435 * Local variables:
436 * c-basic-offset: 4
437 * tab-width: 8
438 * indent-tabs-mode: nil
439 * End:
440 *
441 * vi: set shiftwidth=4 tabstop=8 expandtab:
442 * :indentSize=4:tabSize=8:noTabs=true:
443 */
444