PageRenderTime 45ms CodeModel.GetById 11ms RepoModel.GetById 1ms app.codeStats 0ms

/epan/wslua/wslua_field.c

https://bitbucket.org/stevexiao/wireshark
C | 485 lines | 331 code | 77 blank | 77 comment | 39 complexity | cbb2d98ad58668380d72db90e72658cf MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause
  1. /*
  2. * wslua_field.c
  3. *
  4. * Wireshark's interface to the Lua Programming Language
  5. *
  6. * (c) 2006, Luis E. Garcia Ontanon <luis@ontanon.org>
  7. *
  8. * $Id: wslua_field.c 36751 2011-04-21 13:13:39Z stig $
  9. *
  10. * Wireshark - Network traffic analyzer
  11. * By Gerald Combs <gerald@wireshark.org>
  12. * Copyright 1998 Gerald Combs
  13. *
  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.
  18. *
  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.
  23. *
  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.
  27. */
  28. #ifdef HAVE_CONFIG_H
  29. #include "config.h"
  30. #endif
  31. /* WSLUA_MODULE Field Obtaining dissection data */
  32. #include "wslua.h"
  33. WSLUA_CLASS_DEFINE(FieldInfo,NOP,NOP);
  34. /*
  35. An extracted Field
  36. */
  37. WSLUA_METAMETHOD FieldInfo__len(lua_State* L) {
  38. /*
  39. Obtain the Length of the field
  40. */
  41. FieldInfo fi = checkFieldInfo(L,1);
  42. lua_pushnumber(L,fi->length);
  43. return 1;
  44. }
  45. WSLUA_METAMETHOD FieldInfo__unm(lua_State* L) {
  46. /*
  47. Obtain the Offset of the field
  48. */
  49. FieldInfo fi = checkFieldInfo(L,1);
  50. lua_pushnumber(L,fi->start);
  51. return 1;
  52. }
  53. WSLUA_METAMETHOD FieldInfo__call(lua_State* L) {
  54. /*
  55. Obtain the Value of the field
  56. */
  57. FieldInfo fi = checkFieldInfo(L,1);
  58. switch(fi->hfinfo->type) {
  59. case FT_NONE:
  60. lua_pushnil(L);
  61. return 1;
  62. case FT_BOOLEAN:
  63. lua_pushboolean(L,(int)fvalue_get_uinteger(&(fi->value)));
  64. return 1;
  65. case FT_UINT8:
  66. case FT_UINT16:
  67. case FT_UINT24:
  68. case FT_UINT32:
  69. case FT_FRAMENUM:
  70. lua_pushnumber(L,(lua_Number)fvalue_get_uinteger(&(fi->value)));
  71. return 1;
  72. case FT_INT8:
  73. case FT_INT16:
  74. case FT_INT24:
  75. case FT_INT32:
  76. lua_pushnumber(L,(lua_Number)fvalue_get_sinteger(&(fi->value)));
  77. return 1;
  78. case FT_FLOAT:
  79. case FT_DOUBLE:
  80. lua_pushnumber(L,(lua_Number)fvalue_get_floating(&(fi->value)));
  81. return 1;
  82. case FT_INT64: {
  83. Int64 num = g_malloc(sizeof(gint64));
  84. *num = fvalue_get_integer64(&(fi->value));
  85. pushInt64(L,num);
  86. return 1;
  87. }
  88. case FT_UINT64: {
  89. UInt64 num = g_malloc(sizeof(guint64));
  90. *num = fvalue_get_integer64(&(fi->value));
  91. pushUInt64(L,num);
  92. return 1;
  93. }
  94. case FT_ETHER: {
  95. Address eth = g_malloc(sizeof(address));
  96. eth->type = AT_ETHER;
  97. eth->len = fi->length;
  98. eth->data = tvb_memdup(fi->ds_tvb,fi->start,fi->length);
  99. pushAddress(L,eth);
  100. return 1;
  101. }
  102. case FT_IPv4:{
  103. Address ipv4 = g_malloc(sizeof(address));
  104. ipv4->type = AT_IPv4;
  105. ipv4->len = fi->length;
  106. ipv4->data = tvb_memdup(fi->ds_tvb,fi->start,fi->length);
  107. pushAddress(L,ipv4);
  108. return 1;
  109. }
  110. case FT_IPv6: {
  111. Address ipv6 = g_malloc(sizeof(address));
  112. ipv6->type = AT_IPv6;
  113. ipv6->len = fi->length;
  114. ipv6->data = tvb_memdup(fi->ds_tvb,fi->start,fi->length);
  115. pushAddress(L,ipv6);
  116. return 1;
  117. }
  118. case FT_IPXNET:{
  119. Address ipx = g_malloc(sizeof(address));
  120. ipx->type = AT_IPX;
  121. ipx->len = fi->length;
  122. ipx->data = tvb_memdup(fi->ds_tvb,fi->start,fi->length);
  123. pushAddress(L,ipx);
  124. return 1;
  125. }
  126. case FT_STRING:
  127. case FT_STRINGZ: {
  128. gchar* repr = fvalue_to_string_repr(&fi->value,FTREPR_DISPLAY,NULL);
  129. if (repr)
  130. lua_pushstring(L,repr);
  131. else
  132. luaL_error(L,"field cannot be represented as string because it may contain invalid characters");
  133. return 1;
  134. }
  135. case FT_BYTES:
  136. case FT_UINT_BYTES:
  137. case FT_GUID:
  138. case FT_PROTOCOL:
  139. case FT_OID: {
  140. ByteArray ba = g_byte_array_new();
  141. g_byte_array_append(ba, ep_tvb_memdup(fi->ds_tvb,fi->start,fi->length),fi->length);
  142. pushByteArray(L,ba);
  143. return 1;
  144. }
  145. default:
  146. luaL_error(L,"FT_ not yet supported");
  147. return 1;
  148. }
  149. }
  150. WSLUA_METAMETHOD FieldInfo__tostring(lua_State* L) {
  151. /* The string representation of the field */
  152. FieldInfo fi = checkFieldInfo(L,1);
  153. if (fi) {
  154. if (fi->value.ftype->val_to_string_repr) {
  155. gchar* repr = fvalue_to_string_repr(&fi->value,FTREPR_DISPLAY,NULL);
  156. if (repr)
  157. lua_pushstring(L,repr);
  158. else
  159. luaL_error(L,"field cannot be represented as string because it may contain invalid characters");
  160. } else
  161. luaL_error(L,"field has no string representation");
  162. }
  163. return 1;
  164. }
  165. static int FieldInfo_get_range(lua_State* L) {
  166. /* The TvbRange covering this field */
  167. FieldInfo fi = checkFieldInfo(L,1);
  168. TvbRange r = ep_alloc(sizeof(struct _wslua_tvbrange));
  169. r->tvb = ep_alloc(sizeof(struct _wslua_tvb));
  170. r->tvb->ws_tvb = fi->ds_tvb;
  171. r->offset = fi->start;
  172. r->len = fi->length;
  173. pushTvbRange(L,r);
  174. return 1;
  175. }
  176. static int FieldInfo_get_generated(lua_State* L) {
  177. /* Whether this field was marked as generated. */
  178. FieldInfo fi = checkFieldInfo(L,1);
  179. lua_pushboolean(L,FI_GET_FLAG(fi, FI_GENERATED));
  180. return 1;
  181. }
  182. static int FieldInfo_get_name(lua_State* L) {
  183. /* The filter name of this field. */
  184. FieldInfo fi = checkFieldInfo(L,1);
  185. lua_pushstring(L,fi->hfinfo->abbrev);
  186. return 1;
  187. }
  188. static const luaL_reg FieldInfo_get[] = {
  189. /* {"data_source", FieldInfo_get_data_source }, */
  190. {"range", FieldInfo_get_range},
  191. /* {"hidden", FieldInfo_get_hidden}, */
  192. {"generated", FieldInfo_get_generated},
  193. /* WSLUA_ATTRIBUTE FieldInfo_name RO The name of this field */
  194. {"name", FieldInfo_get_name},
  195. /* WSLUA_ATTRIBUTE FieldInfo_label RO The string representing this field */
  196. {"label", FieldInfo__tostring},
  197. /* WSLUA_ATTRIBUTE FieldInfo_value RO The value of this field */
  198. {"value", FieldInfo__call},
  199. /* WSLUA_ATTRIBUTE FieldInfo_len RO The length of this field */
  200. {"len", FieldInfo__len},
  201. /* WSLUA_ATTRIBUTE FieldInfo_offset RO The offset of this field */
  202. {"offset", FieldInfo__unm},
  203. { NULL, NULL }
  204. };
  205. static int FieldInfo__index(lua_State* L) {
  206. /*
  207. Other attributes:
  208. */
  209. const gchar* idx = luaL_checkstring(L,2);
  210. const luaL_reg* r;
  211. checkFieldInfo(L,1);
  212. for (r = FieldInfo_get; r->name; r++) {
  213. if (g_str_equal(r->name, idx)) {
  214. return r->func(L);
  215. }
  216. }
  217. return 0;
  218. }
  219. WSLUA_METAMETHOD FieldInfo__eq(lua_State* L) {
  220. /* Checks whether lhs is within rhs */
  221. FieldInfo l = checkFieldInfo(L,1);
  222. FieldInfo r = checkFieldInfo(L,2);
  223. if (l->ds_tvb != r->ds_tvb)
  224. WSLUA_ERROR(FieldInfo__eq,"Data source must be the same for both fields");
  225. if (l->start <= r->start && r->start + r->length <= l->start + r->length) {
  226. lua_pushboolean(L,1);
  227. return 1;
  228. } else {
  229. return 0;
  230. }
  231. }
  232. WSLUA_METAMETHOD FieldInfo__le(lua_State* L) {
  233. /* Checks whether the end byte of lhs is before the end of rhs */
  234. FieldInfo l = checkFieldInfo(L,1);
  235. FieldInfo r = checkFieldInfo(L,2);
  236. if (l->ds_tvb != r->ds_tvb)
  237. return 0;
  238. if (r->start + r->length <= l->start + r->length) {
  239. lua_pushboolean(L,1);
  240. return 1;
  241. } else {
  242. return 0;
  243. }
  244. }
  245. WSLUA_METAMETHOD FieldInfo__lt(lua_State* L) {
  246. /* Checks whether the end byte of rhs is before the beginning of rhs */
  247. FieldInfo l = checkFieldInfo(L,1);
  248. FieldInfo r = checkFieldInfo(L,2);
  249. if (l->ds_tvb != r->ds_tvb)
  250. WSLUA_ERROR(FieldInfo__eq,"Data source must be the same for both fields");
  251. if ( r->start + r->length < l->start ) {
  252. lua_pushboolean(L,1);
  253. return 1;
  254. } else {
  255. return 0;
  256. }
  257. }
  258. static const luaL_reg FieldInfo_meta[] = {
  259. {"__tostring", FieldInfo__tostring},
  260. {"__call", FieldInfo__call},
  261. {"__index", FieldInfo__index},
  262. {"__len", FieldInfo__len},
  263. {"__unm", FieldInfo__unm},
  264. {"__eq", FieldInfo__eq},
  265. {"__le", FieldInfo__le},
  266. {"__lt", FieldInfo__lt},
  267. { NULL, NULL }
  268. };
  269. int FieldInfo_register(lua_State* L) {
  270. WSLUA_REGISTER_META(FieldInfo);
  271. return 1;
  272. }
  273. WSLUA_FUNCTION wslua_all_field_infos(lua_State* L) {
  274. /* Obtain all fields from the current tree */
  275. GPtrArray* found;
  276. int items_found = 0;
  277. guint i;
  278. if (! lua_tree || ! lua_tree->tree ) {
  279. WSLUA_ERROR(wslua_all_field_infos,"Cannot be called outside a listener or dissector");
  280. }
  281. found = proto_all_finfos(lua_tree->tree);
  282. if (found) {
  283. for (i=0; i<found->len; i++) {
  284. pushFieldInfo(L,g_ptr_array_index(found,i));
  285. items_found++;
  286. }
  287. g_ptr_array_free(found,TRUE);
  288. }
  289. return items_found;
  290. }
  291. WSLUA_CLASS_DEFINE(Field,NOP,NOP);
  292. /*
  293. A Field extractor to to obtain field values.
  294. */
  295. static GPtrArray* wanted_fields = NULL;
  296. /*
  297. * field extractor registartion is tricky, In order to allow
  298. * the user to define them in the body of the script we will
  299. * populate the Field value with a pointer of the abbrev of it
  300. * to later replace it with the hfi.
  301. *
  302. * This will be added to the wanted_fields array that will
  303. * exists only while they can be defined, and be cleared right
  304. * after the fields are primed.
  305. */
  306. void lua_prime_all_fields(proto_tree* tree _U_) {
  307. GString* fake_tap_filter = g_string_new("frame");
  308. guint i;
  309. static gboolean fake_tap = FALSE;
  310. for(i=0; i < wanted_fields->len; i++) {
  311. Field f = g_ptr_array_index(wanted_fields,i);
  312. gchar* name = *((gchar**)f);
  313. *f = proto_registrar_get_byname(name);
  314. if (!*f) {
  315. report_failure("Could not find field `%s'",name);
  316. *f = NULL;
  317. g_free(name);
  318. continue;
  319. }
  320. g_free(name);
  321. g_string_append_printf(fake_tap_filter," || %s",(*f)->abbrev);
  322. fake_tap = TRUE;
  323. }
  324. g_ptr_array_free(wanted_fields,TRUE);
  325. wanted_fields = NULL;
  326. if (fake_tap) {
  327. /* a boring tap :-) */
  328. GString* error = register_tap_listener("frame",
  329. &fake_tap,
  330. fake_tap_filter->str,
  331. 0, /* XXX - do we need the protocol tree or columns? */
  332. NULL, NULL, NULL);
  333. if (error) {
  334. report_failure("while registering lua_fake_tap:\n%s",error->str);
  335. g_string_free(error,TRUE);
  336. }
  337. }
  338. }
  339. WSLUA_CONSTRUCTOR Field_new(lua_State *L) {
  340. /*
  341. Create a Field extractor
  342. */
  343. #define WSLUA_ARG_Field_new_FIELDNAME 1 /* The filter name of the field (e.g. ip.addr) */
  344. const gchar* name = luaL_checkstring(L,WSLUA_ARG_Field_new_FIELDNAME);
  345. Field f;
  346. if (!name) return 0;
  347. if (!proto_registrar_get_byname(name))
  348. WSLUA_ARG_ERROR(Field_new,FIELDNAME,"a field with this name must exist");
  349. if (!wanted_fields)
  350. WSLUA_ERROR(Field_get,"A Field extractor must be defined before Taps or Dissectors get called");
  351. f = g_malloc(sizeof(void*));
  352. *f = (header_field_info*)g_strdup(name); /* cheating */
  353. g_ptr_array_add(wanted_fields,f);
  354. pushField(L,f);
  355. WSLUA_RETURN(1); /* The field extractor */
  356. }
  357. WSLUA_METAMETHOD Field__call (lua_State* L) {
  358. /* Obtain all values (see FieldInfo) for this field. */
  359. Field f = checkField(L,1);
  360. header_field_info* in = *f;
  361. int items_found = 0;
  362. if (! in) {
  363. luaL_error(L,"invalid field");
  364. return 0;
  365. }
  366. if (! lua_pinfo ) {
  367. WSLUA_ERROR(Field__call,"Fields cannot be used outside dissectors or taps");
  368. }
  369. for (;in;in = in->same_name_next) {
  370. GPtrArray* found = proto_get_finfo_ptr_array(lua_tree->tree, in->id);
  371. guint i;
  372. if (found) {
  373. for (i=0; i<found->len; i++) {
  374. pushFieldInfo(L,g_ptr_array_index(found,i));
  375. items_found++;
  376. }
  377. }
  378. }
  379. WSLUA_RETURN(items_found); /* All the values of this field */
  380. }
  381. WSLUA_METAMETHOD Field_tostring(lua_State* L) {
  382. /* Obtain a srting with the field name */
  383. Field f = checkField(L,1);
  384. if ( !(f && *f) ) {
  385. luaL_error(L,"invalid Field");
  386. return 0;
  387. }
  388. if (wanted_fields) {
  389. lua_pushstring(L,*((gchar**)f));
  390. } else {
  391. lua_pushstring(L,(*f)->abbrev);
  392. }
  393. return 1;
  394. }
  395. static const luaL_reg Field_methods[] = {
  396. {"new", Field_new},
  397. { NULL, NULL }
  398. };
  399. static const luaL_reg Field_meta[] = {
  400. {"__tostring", Field_tostring},
  401. {"__call", Field__call},
  402. { NULL, NULL }
  403. };
  404. int Field_register(lua_State* L) {
  405. wanted_fields = g_ptr_array_new();
  406. WSLUA_REGISTER_CLASS(Field);
  407. return 1;
  408. }