/* Convert an FT_STRING using a callback function */ static gboolean string_walk(GList* arg1list, GList **retval, gchar(*conv_func)(gchar)) { GList *arg1; fvalue_t *arg_fvalue; fvalue_t *new_ft_string; char *s, *c; arg1 = arg1list; while (arg1) { arg_fvalue = (fvalue_t *)arg1->data; /* XXX - it would be nice to handle FT_TVBUFF, too */ if (IS_FT_STRING(fvalue_type_ftenum(arg_fvalue))) { s = (char *)ep_strdup((gchar *)fvalue_get(arg_fvalue)); for (c = s; *c; c++) { /**c = string_ascii_to_lower(*c);*/ *c = conv_func(*c); } new_ft_string = fvalue_new(FT_STRING); fvalue_set_string(new_ft_string, s); *retval = g_list_append(*retval, new_ft_string); } arg1 = arg1->next; } return TRUE; }
/* Convert an FT_STRING using a callback function */ static gboolean string_walk(GList* arg1list, GList **retval, gchar(*conv_func)(gchar)) { GList *arg1; fvalue_t *arg_fvalue; fvalue_t *new_ft_string; char *s, *c; arg1 = arg1list; while (arg1) { arg_fvalue = arg1->data; switch (fvalue_ftype(arg_fvalue)->ftype) { case FT_STRING: s = ep_strdup(fvalue_get(arg1->data)); for (c = s; *c; c++) { /**c = string_ascii_to_lower(*c);*/ *c = conv_func(*c); } new_ft_string = fvalue_new(FT_STRING); fvalue_set(new_ft_string, s, FALSE); *retval = g_list_append(*retval, new_ft_string); break; /* XXX - it would be nice to handle FT_TVBUFF, too */ default: break; } arg1 = arg1->next; } return TRUE; }
static gpointer pyshark_format_field(gpointer item, gchar *format) { if(strcmp(format, "s") == 0) { return Py_BuildValue(format, item); } else if(strcmp(format, "N") == 0) { return Py_BuildValue(""); // None object } else if(strcmp(format, "T") == 0) { nstime_t *tmp_timestamp = fvalue_get(item); /* Use fn in $wireshark/epan/nstime.c to convert timestamp to a float */ double tmp_double = nstime_to_sec(tmp_timestamp); /* TODO: create a Python-native time or timedelta object instead (?) */ return Py_BuildValue("f", tmp_double); } else if(strcmp(format, "f") == 0) { double tmp_double = fvalue_get_floating(item); return Py_BuildValue(format, tmp_double); } else if(strcmp(format, "K") == 0) { unsigned long long tmp_unsigned_long_long = fvalue_get_integer64(item); return Py_BuildValue(format, tmp_unsigned_long_long); } else if(strcmp(format, "i") == 0) { /* FIXME: does fvalue_get_sinteger() work properly with FT_INT{8,16,24} types? */ unsigned long tmp_long = fvalue_get_sinteger(item); return Py_BuildValue(format, tmp_long); } else if(strcmp(format, "k") == 0) { unsigned long tmp_unsigned_long = fvalue_get_uinteger(item); return Py_BuildValue(format, tmp_unsigned_long); } else if(strcmp(format, "B") == 0) { /* Wireshark implements FT_BOOLEANs as uintegers. See epan/ftype/ftype-integer.c */ unsigned long tmp_unsigned_long = fvalue_get_uinteger(item); return PyBool_FromLong(tmp_unsigned_long); } else return NULL; }
/** * This function is called for each node on the dissector tree, for a each packet, * First, this function sees if this node is one of the keys (e.g. 'frame.number') * we are looking for (nodes store the key in PITEM_FINFO(node)->hfinfo->abbrev). * If we found an appropriate field, copy the native value or string representation * of the value as appropriate. * * Finally, recurse on child nodes. */ static void proto_tree_get_node_field_values(proto_node *node, gpointer data) { stdata_edt_tuple_t *args; field_info *fi; gpointer field_index; gpointer orig_key; gboolean key_found; args = data; fi = PITEM_FINFO(node); dprintf("fi->hfinfo->abbrev = %s\n", fi->hfinfo->abbrev); key_found = g_hash_table_lookup_extended(args->stdata->field_indicies, fi->hfinfo->abbrev, &orig_key, &field_index); const gchar* val_str; gulong actual_index = (gulong)(field_index); if(key_found) { gulong type = fi->hfinfo->type; if(type == FT_STRING) { dprintf("found a string!\n"); dprintf("string is: %s\n", (char*)fvalue_get(&(fi->value))); dprintf("string as gnfvas: %s\n", get_node_field_value_as_string(fi, args->edt)); } if(type == FT_NONE) { args->stdata->field_values_str[actual_index] = NULL; args->stdata->field_values_native[actual_index] = 0; args->stdata->field_types[actual_index] = FT_NONE; } else if(is_native_type(type) == TRUE) { // If we can natively store the type, // do that and don't convert to a string args->stdata->field_values_str[actual_index] = NULL; memcpy(args->stdata->field_values_native[actual_index], &(fi->value), sizeof(fvalue_t)); args->stdata->field_types[actual_index] = type; } else { // As a last ditch options, convert the value to a string, // and don't bother storing the native type val_str = get_node_field_value_as_string(fi, args->edt); args->stdata->field_values_str[actual_index] = val_str; args->stdata->field_types[actual_index] = type; } } /* Recurse here. */ if (node->first_child != NULL) { proto_tree_children_foreach(node, proto_tree_get_node_field_values, args); } }
/* Print info for a 'geninfo' pseudo-protocol. This is required by * the PDML spec. The information is contained in Wireshark's 'frame' protocol, * but we produce a 'geninfo' protocol in the PDML to conform to spec. * The 'frame' protocol follows the 'geninfo' protocol in the PDML. */ static void print_pdml_geninfo(proto_tree *tree, FILE *fh) { guint32 num, len, caplen; nstime_t *timestamp; GPtrArray *finfo_array; field_info *frame_finfo; /* Get frame protocol's finfo. */ finfo_array = proto_find_finfo(tree, proto_frame); if (g_ptr_array_len(finfo_array) < 1) { return; } frame_finfo = (field_info *)finfo_array->pdata[0]; g_ptr_array_free(finfo_array, TRUE); /* frame.number --> geninfo.num */ finfo_array = proto_find_finfo(tree, hf_frame_number); if (g_ptr_array_len(finfo_array) < 1) { return; } num = fvalue_get_uinteger(&((field_info*)finfo_array->pdata[0])->value); g_ptr_array_free(finfo_array, TRUE); /* frame.frame_len --> geninfo.len */ finfo_array = proto_find_finfo(tree, hf_frame_len); if (g_ptr_array_len(finfo_array) < 1) { return; } len = fvalue_get_uinteger(&((field_info*)finfo_array->pdata[0])->value); g_ptr_array_free(finfo_array, TRUE); /* frame.cap_len --> geninfo.caplen */ finfo_array = proto_find_finfo(tree, hf_frame_capture_len); if (g_ptr_array_len(finfo_array) < 1) { return; } caplen = fvalue_get_uinteger(&((field_info*)finfo_array->pdata[0])->value); g_ptr_array_free(finfo_array, TRUE); /* frame.time --> geninfo.timestamp */ finfo_array = proto_find_finfo(tree, hf_frame_arrival_time); if (g_ptr_array_len(finfo_array) < 1) { return; } timestamp = (nstime_t *)fvalue_get(&((field_info*)finfo_array->pdata[0])->value); g_ptr_array_free(finfo_array, TRUE); /* Print geninfo start */ fprintf(fh, " <proto name=\"geninfo\" pos=\"0\" showname=\"General information\" size=\"%u\">\n", frame_finfo->length); /* Print geninfo.num */ fprintf(fh, " <field name=\"num\" pos=\"0\" show=\"%u\" showname=\"Number\" value=\"%x\" size=\"%u\"/>\n", num, num, frame_finfo->length); /* Print geninfo.len */ fprintf(fh, " <field name=\"len\" pos=\"0\" show=\"%u\" showname=\"Frame Length\" value=\"%x\" size=\"%u\"/>\n", len, len, frame_finfo->length); /* Print geninfo.caplen */ fprintf(fh, " <field name=\"caplen\" pos=\"0\" show=\"%u\" showname=\"Captured Length\" value=\"%x\" size=\"%u\"/>\n", caplen, caplen, frame_finfo->length); /* Print geninfo.timestamp */ fprintf(fh, " <field name=\"timestamp\" pos=\"0\" show=\"%s\" showname=\"Captured Time\" value=\"%d.%09d\" size=\"%u\"/>\n", abs_time_to_str(timestamp, ABSOLUTE_TIME_LOCAL, TRUE), (int) timestamp->secs, timestamp->nsecs, frame_finfo->length); /* Print geninfo end */ fprintf(fh, " </proto>\n"); }
WSLUA_METAMETHOD FieldInfo__call(lua_State* L) { /* Obtain the Value of the field */ FieldInfo fi = checkFieldInfo(L,1); switch(fi->hfinfo->type) { case FT_BOOLEAN: lua_pushboolean(L,(int)fvalue_get_uinteger(&(fi->value))); return 1; case FT_UINT8: case FT_UINT16: case FT_UINT24: case FT_UINT32: case FT_FRAMENUM: lua_pushnumber(L,(lua_Number)fvalue_get_uinteger(&(fi->value))); return 1; case FT_INT8: case FT_INT16: case FT_INT24: case FT_INT32: lua_pushnumber(L,(lua_Number)fvalue_get_sinteger(&(fi->value))); return 1; case FT_FLOAT: case FT_DOUBLE: lua_pushnumber(L,(lua_Number)fvalue_get_floating(&(fi->value))); return 1; case FT_INT64: { Int64 num = (Int64)g_malloc(sizeof(gint64)); *num = fvalue_get_integer64(&(fi->value)); pushInt64(L,num); return 1; } case FT_UINT64: { UInt64 num = (UInt64)g_malloc(sizeof(guint64)); *num = fvalue_get_integer64(&(fi->value)); pushUInt64(L,num); return 1; } case FT_ETHER: { Address eth = (Address)g_malloc(sizeof(address)); eth->type = AT_ETHER; eth->len = fi->length; eth->data = tvb_memdup(NULL,fi->ds_tvb,fi->start,fi->length); pushAddress(L,eth); return 1; } case FT_IPv4:{ Address ipv4 = (Address)g_malloc(sizeof(address)); ipv4->type = AT_IPv4; ipv4->len = fi->length; ipv4->data = tvb_memdup(NULL,fi->ds_tvb,fi->start,fi->length); pushAddress(L,ipv4); return 1; } case FT_IPv6: { Address ipv6 = (Address)g_malloc(sizeof(address)); ipv6->type = AT_IPv6; ipv6->len = fi->length; ipv6->data = tvb_memdup(NULL,fi->ds_tvb,fi->start,fi->length); pushAddress(L,ipv6); return 1; } case FT_IPXNET:{ Address ipx = (Address)g_malloc(sizeof(address)); ipx->type = AT_IPX; ipx->len = fi->length; ipx->data = tvb_memdup(NULL,fi->ds_tvb,fi->start,fi->length); pushAddress(L,ipx); return 1; } case FT_ABSOLUTE_TIME: case FT_RELATIVE_TIME: { NSTime nstime = (NSTime)g_malloc(sizeof(nstime_t)); *nstime = *(NSTime)fvalue_get(&(fi->value)); pushNSTime(L,nstime); return 1; } case FT_STRING: case FT_STRINGZ: { gchar* repr = fvalue_to_string_repr(&fi->value,FTREPR_DISPLAY,NULL); if (repr) lua_pushstring(L,repr); else luaL_error(L,"field cannot be represented as string because it may contain invalid characters"); return 1; } case FT_NONE: if (fi->length == 0) { lua_pushnil(L); return 1; } /* FALLTHROUGH */ case FT_BYTES: case FT_UINT_BYTES: case FT_GUID: case FT_PROTOCOL: case FT_REL_OID: case FT_SYSTEM_ID: case FT_OID: { ByteArray ba = g_byte_array_new(); g_byte_array_append(ba, (const guint8 *)tvb_memdup(wmem_packet_scope(),fi->ds_tvb,fi->start,fi->length),fi->length); pushByteArray(L,ba); return 1; } default: luaL_error(L,"FT_ not yet supported"); return 1; } }
/* WSLUA_ATTRIBUTE FieldInfo_value RO The value of this field. */ WSLUA_METAMETHOD FieldInfo__call(lua_State* L) { /* Obtain the Value of the field. Previous to 1.11.4, this function retrieved the value for most field types, but for `ftypes.UINT_BYTES` it retrieved the `ByteArray` of the field's entire `TvbRange`. In other words, it returned a `ByteArray` that included the leading length byte(s), instead of just the *value* bytes. That was a bug, and has been changed in 1.11.4. Furthermore, it retrieved an `ftypes.GUID` as a `ByteArray`, which is also incorrect. If you wish to still get a `ByteArray` of the `TvbRange`, use `FieldInfo:get_range()` to get the `TvbRange`, and then use `Tvb:bytes()` to convert it to a `ByteArray`. */ FieldInfo fi = checkFieldInfo(L,1); switch(fi->ws_fi->hfinfo->type) { case FT_BOOLEAN: lua_pushboolean(L,(int)fvalue_get_uinteger(&(fi->ws_fi->value))); return 1; case FT_UINT8: case FT_UINT16: case FT_UINT24: case FT_UINT32: case FT_FRAMENUM: lua_pushnumber(L,(lua_Number)(fvalue_get_uinteger(&(fi->ws_fi->value)))); return 1; case FT_INT8: case FT_INT16: case FT_INT24: case FT_INT32: lua_pushnumber(L,(lua_Number)(fvalue_get_sinteger(&(fi->ws_fi->value)))); return 1; case FT_FLOAT: case FT_DOUBLE: lua_pushnumber(L,(lua_Number)(fvalue_get_floating(&(fi->ws_fi->value)))); return 1; case FT_INT64: { pushInt64(L,(Int64)(fvalue_get_sinteger64(&(fi->ws_fi->value)))); return 1; } case FT_UINT64: { pushUInt64(L,fvalue_get_uinteger64(&(fi->ws_fi->value))); return 1; } case FT_ETHER: { Address eth = (Address)g_malloc(sizeof(address)); eth->type = AT_ETHER; eth->len = fi->ws_fi->length; eth->data = tvb_memdup(NULL,fi->ws_fi->ds_tvb,fi->ws_fi->start,fi->ws_fi->length); pushAddress(L,eth); return 1; } case FT_IPv4:{ Address ipv4 = (Address)g_malloc(sizeof(address)); ipv4->type = AT_IPv4; ipv4->len = fi->ws_fi->length; ipv4->data = tvb_memdup(NULL,fi->ws_fi->ds_tvb,fi->ws_fi->start,fi->ws_fi->length); pushAddress(L,ipv4); return 1; } case FT_IPv6: { Address ipv6 = (Address)g_malloc(sizeof(address)); ipv6->type = AT_IPv6; ipv6->len = fi->ws_fi->length; ipv6->data = tvb_memdup(NULL,fi->ws_fi->ds_tvb,fi->ws_fi->start,fi->ws_fi->length); pushAddress(L,ipv6); return 1; } case FT_FCWWN: { Address fcwwn = (Address)g_malloc(sizeof(address)); fcwwn->type = AT_FCWWN; fcwwn->len = fi->ws_fi->length; fcwwn->data = tvb_memdup(NULL,fi->ws_fi->ds_tvb,fi->ws_fi->start,fi->ws_fi->length); pushAddress(L,fcwwn); return 1; } case FT_IPXNET:{ Address ipx = (Address)g_malloc(sizeof(address)); ipx->type = AT_IPX; ipx->len = fi->ws_fi->length; ipx->data = tvb_memdup(NULL,fi->ws_fi->ds_tvb,fi->ws_fi->start,fi->ws_fi->length); pushAddress(L,ipx); return 1; } case FT_ABSOLUTE_TIME: case FT_RELATIVE_TIME: { NSTime nstime = (NSTime)g_malloc(sizeof(nstime_t)); *nstime = *(NSTime)fvalue_get(&(fi->ws_fi->value)); pushNSTime(L,nstime); return 1; } case FT_STRING: case FT_STRINGZ: { gchar* repr = fvalue_to_string_repr(&fi->ws_fi->value,FTREPR_DISPLAY,BASE_NONE,NULL); if (repr) lua_pushstring(L,repr); else luaL_error(L,"field cannot be represented as string because it may contain invalid characters"); return 1; } case FT_NONE: if (fi->ws_fi->length > 0 && fi->ws_fi->rep) { /* it has a length, but calling fvalue_get() on an FT_NONE asserts, so get the label instead (it's a FT_NONE, so a label is what it basically is) */ lua_pushstring(L, fi->ws_fi->rep->representation); return 1; } return 0; case FT_BYTES: case FT_UINT_BYTES: case FT_REL_OID: case FT_SYSTEM_ID: case FT_OID: { ByteArray ba = g_byte_array_new(); g_byte_array_append(ba, (const guint8 *) fvalue_get(&fi->ws_fi->value), fvalue_length(&fi->ws_fi->value)); pushByteArray(L,ba); return 1; } case FT_PROTOCOL: { ByteArray ba = g_byte_array_new(); tvbuff_t* tvb = (tvbuff_t *) fvalue_get(&fi->ws_fi->value); g_byte_array_append(ba, (const guint8 *)tvb_memdup(wmem_packet_scope(), tvb, 0, tvb_captured_length(tvb)), tvb_captured_length(tvb)); pushByteArray(L,ba); return 1; } case FT_GUID: default: luaL_error(L,"FT_ not yet supported"); return 1; } }
gpointer cb_row_set(sharktools_callbacks *cb, void *row, void *key, gulong type, GPtrArray *tree_values) { static nstime_t *tmp_timestamp; double tmp_double; // Bomb out; I haven't updated this app... fvalue_t *val_native; const gchar *val_string; g_assert_not_reached(); //printf("%s (%d)\t\t", val_string, (int)type); switch(type) { case FT_NONE: /* used for text labels with no value */ printf("None"); break; //case FT_PROTOCOL: //case FT_BOOLEAN: /* TRUE and FALSE come from <glib.h> */ case FT_UINT8: case FT_UINT16: case FT_UINT24: /* really a UINT32, but displayed as 3 hex-digits if FD_HEX*/ case FT_UINT32: /* FIXME: does fvalue_get_uinteger() work properly with FT_UINT{8,16,24} types? */ printf("%u", fvalue_get_uinteger(val_native)); break; case FT_INT64: /* Wireshark doesn't seem to make a difference between INT64 and UINT64 */ case FT_UINT64: //guint64 tmp = printf("%llu", (long long unsigned int)fvalue_get_integer64(val_native));// tmp); break; case FT_INT8: case FT_INT16: case FT_INT24: /* same as for UINT24 */ case FT_INT32: /* FIXME: does fvalue_get_sinteger() work properly with FT_INT{8,16,24} types? */ printf("%d", fvalue_get_sinteger(val_native)); break; case FT_FLOAT: case FT_DOUBLE: printf("%f", fvalue_get_floating(val_native)); break; case FT_ABSOLUTE_TIME: case FT_RELATIVE_TIME: tmp_timestamp = fvalue_get(val_native); // Use fn in $wireshark/epan/nstime.c to convert timestamp to a float tmp_double = nstime_to_sec(tmp_timestamp); printf("%f", tmp_double); break; //case FT_UINT_STRING: /* for use with proto_tree_add_item() */ //case FT_ETHER: //case FT_BYTES: //case FT_UINT_BYTES: //case FT_IPv4: //case FT_IPv6: //case FT_IPXNET: //case FT_FRAMENUM: /* a UINT32, but if selected lets you go to frame with that numbe */ //case FT_PCRE: /* a compiled Perl-Compatible Regular Expression object */ //case FT_GUID: /* GUID, UUID */ //case FT_OID: /* OBJECT IDENTIFIER */ default: printf("%s", val_string); break; } printf(" (%d)\t\t", (int)type); /* if(type == FT_UINT32) { //printf("%d (%d)\t\t", val_native->value.uinteger, (int)type); printf("%d (%d)\t\t", fvalue_get_uinteger(val_native), (int)type); } */ return NULL; }