static gboolean val_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_, LogFunc logfunc) { guint32 addr; unsigned int nmask_bits; const char *has_slash; const char *net_str, *addr_str; fvalue_t *nmask_fvalue; /* Look for CIDR: Is there a single slash in the string? */ has_slash = strchr(s, '/'); if (has_slash) { /* Make a copy of the string up to but not including the * slash; that's the address portion. */ addr_str = ep_strndup(s, has_slash - s); } else { addr_str = s; } if (!get_host_ipaddr(addr_str, &addr)) { logfunc("\"%s\" is not a valid hostname or IPv4 address.", addr_str); return FALSE; } ipv4_addr_set_net_order_addr(&(fv->value.ipv4), addr); /* If CIDR, get netmask bits. */ if (has_slash) { /* Skip past the slash */ net_str = has_slash + 1; /* XXX - this is inefficient */ nmask_fvalue = fvalue_from_unparsed(FT_UINT32, net_str, FALSE, logfunc); if (!nmask_fvalue) { return FALSE; } nmask_bits = fvalue_get_uinteger(nmask_fvalue); FVALUE_FREE(nmask_fvalue); if (nmask_bits > 32) { logfunc("Netmask bits in a CIDR IPv4 address should be <= 32, not %u", nmask_bits); return FALSE; } ipv4_addr_set_netmask_bits(&fv->value.ipv4, nmask_bits); } else { /* Not CIDR; mask covers entire address. */ ipv4_addr_set_netmask_bits(&(fv->value.ipv4), 32); } return TRUE; }
static gboolean ipv6_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_, gchar **err_msg) { const char *slash; const char *addr_str; char *addr_str_to_free = NULL; unsigned int nmask_bits; fvalue_t *nmask_fvalue; /* Look for prefix: Is there a single slash in the string? */ slash = strchr(s, '/'); if (slash) { /* Make a copy of the string up to but not including the * slash; that's the address portion. */ addr_str_to_free = wmem_strndup(NULL, s, slash-s); addr_str = addr_str_to_free; } else addr_str = s; if (!get_host_ipaddr6(addr_str, &(fv->value.ipv6.addr))) { if (err_msg != NULL) *err_msg = g_strdup_printf("\"%s\" is not a valid hostname or IPv6 address.", s); if (addr_str_to_free) wmem_free(NULL, addr_str_to_free); return FALSE; } if (addr_str_to_free) wmem_free(NULL, addr_str_to_free); /* If prefix */ if (slash) { /* XXX - this is inefficient */ nmask_fvalue = fvalue_from_unparsed(FT_UINT32, slash+1, FALSE, err_msg); if (!nmask_fvalue) { return FALSE; } nmask_bits = fvalue_get_uinteger(nmask_fvalue); FVALUE_FREE(nmask_fvalue); if (nmask_bits > 128) { if (err_msg != NULL) { *err_msg = g_strdup_printf("Prefix in a IPv6 address should be <= 128, not %u", nmask_bits); } return FALSE; } fv->value.ipv6.prefix = nmask_bits; } else { /* Not CIDR; mask covers entire address. */ fv->value.ipv6.prefix = 128; } 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; }
static gboolean ipv6_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, LogFunc logfunc) { char *has_slash, *addr_str; unsigned int nmask_bits; fvalue_t *nmask_fvalue; /* Look for prefix: Is there a single slash in the string? */ if ((has_slash = strchr(s, '/'))) addr_str = ep_strndup(s, has_slash-s); else addr_str = s; if (!get_host_ipaddr6(addr_str, &(fv->value.ipv6.addr))) { logfunc("\"%s\" is not a valid hostname or IPv6 address.", s); return FALSE; } /* If prefix */ if (has_slash) { /* XXX - this is inefficient */ nmask_fvalue = fvalue_from_unparsed(FT_UINT32, has_slash+1, FALSE, logfunc); if (!nmask_fvalue) { return FALSE; } nmask_bits = fvalue_get_uinteger(nmask_fvalue); FVALUE_FREE(nmask_fvalue); if (nmask_bits > 128) { logfunc("Prefix in a IPv6 address should be <= 128, not %u", nmask_bits); return FALSE; } fv->value.ipv6.prefix = nmask_bits; } else { /* Not CIDR; mask covers entire address. */ fv->value.ipv6.prefix = 128; } return TRUE; }
/* 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"); }
/* Write out a tree's data, and any child nodes, as PDML */ static void proto_tree_write_node_pdml(proto_node *node, gpointer data) { field_info *fi = PNODE_FINFO(node); write_pdml_data *pdata = (write_pdml_data*) data; const gchar *label_ptr; gchar label_str[ITEM_LABEL_LENGTH]; char *dfilter_string; size_t chop_len; int i; gboolean wrap_in_fake_protocol; g_assert(fi && "dissection with an invisible proto tree?"); /* Will wrap up top-level field items inside a fake protocol wrapper to preserve the PDML schema */ wrap_in_fake_protocol = (((fi->hfinfo->type != FT_PROTOCOL) || (fi->hfinfo->id == proto_data)) && (pdata->level == 0)); /* Indent to the correct level */ for (i = -1; i < pdata->level; i++) { fputs(" ", pdata->fh); } if (wrap_in_fake_protocol) { /* Open fake protocol wrapper */ fputs("<proto name=\"fake-field-wrapper\">\n", pdata->fh); /* Indent to increased level before writint out field */ pdata->level++; for (i = -1; i < pdata->level; i++) { fputs(" ", pdata->fh); } } /* Text label. It's printed as a field with no name. */ if (fi->hfinfo->id == hf_text_only) { /* Get the text */ if (fi->rep) { label_ptr = fi->rep->representation; } else { label_ptr = ""; } /* Show empty name since it is a required field */ fputs("<field name=\"", pdata->fh); fputs("\" show=\"", pdata->fh); print_escaped_xml(pdata->fh, label_ptr); fprintf(pdata->fh, "\" size=\"%d", fi->length); fprintf(pdata->fh, "\" pos=\"%d", fi->start); fputs("\" value=\"", pdata->fh); write_pdml_field_hex_value(pdata, fi); if (node->first_child != NULL) { fputs("\">\n", pdata->fh); } else { fputs("\"/>\n", pdata->fh); } } /* Uninterpreted data, i.e., the "Data" protocol, is * printed as a field instead of a protocol. */ else if (fi->hfinfo->id == proto_data) { /* Write out field with data */ fputs("<field name=\"data\" value=\"", pdata->fh); write_pdml_field_hex_value(pdata, fi); fputs("\"/>\n", pdata->fh); } /* Normal protocols and fields */ else { if (fi->hfinfo->type == FT_PROTOCOL) { fputs("<proto name=\"", pdata->fh); } else { fputs("<field name=\"", pdata->fh); } print_escaped_xml(pdata->fh, fi->hfinfo->abbrev); #if 0 /* PDML spec, see: * http://www.nbee.org/doku.php?id=netpdl:pdml_specification * * the show fields contains things in 'human readable' format * showname: contains only the name of the field * show: contains only the data of the field * showdtl: contains additional details of the field data * showmap: contains mappings of the field data (e.g. the hostname to an IP address) * * XXX - the showname shouldn't contain the field data itself * (like it's contained in the fi->rep->representation). * Unfortunately, we don't have the field data representation for * all fields, so this isn't currently possible */ fputs("\" showname=\"", pdata->fh); print_escaped_xml(pdata->fh, fi->hfinfo->name); #endif if (fi->rep) { fputs("\" showname=\"", pdata->fh); print_escaped_xml(pdata->fh, fi->rep->representation); } else { label_ptr = label_str; proto_item_fill_label(fi, label_str); fputs("\" showname=\"", pdata->fh); print_escaped_xml(pdata->fh, label_ptr); } if (PROTO_ITEM_IS_HIDDEN(node)) fprintf(pdata->fh, "\" hide=\"yes"); fprintf(pdata->fh, "\" size=\"%d", fi->length); fprintf(pdata->fh, "\" pos=\"%d", fi->start); /* fprintf(pdata->fh, "\" id=\"%d", fi->hfinfo->id);*/ /* show, value, and unmaskedvalue attributes */ switch (fi->hfinfo->type) { case FT_PROTOCOL: break; case FT_NONE: fputs("\" show=\"\" value=\"", pdata->fh); break; default: /* XXX - this is a hack until we can just call * fvalue_to_string_repr() for *all* FT_* types. */ dfilter_string = proto_construct_match_selected_string(fi, pdata->edt); if (dfilter_string != NULL) { chop_len = strlen(fi->hfinfo->abbrev) + 4; /* for " == " */ /* XXX - Remove double-quotes. Again, once we * can call fvalue_to_string_repr(), we can * ask it not to produce the version for * display-filters, and thus, no * double-quotes. */ if (dfilter_string[strlen(dfilter_string)-1] == '"') { dfilter_string[strlen(dfilter_string)-1] = '\0'; chop_len++; } fputs("\" show=\"", pdata->fh); print_escaped_xml(pdata->fh, &dfilter_string[chop_len]); } /* * XXX - should we omit "value" for any fields? * What should we do for fields whose length is 0? * They might come from a pseudo-header or from * the capture header (e.g., time stamps), or * they might be generated fields. */ if (fi->length > 0) { fputs("\" value=\"", pdata->fh); if (fi->hfinfo->bitmask!=0) { fprintf(pdata->fh, "%X", fvalue_get_uinteger(&fi->value)); fputs("\" unmaskedvalue=\"", pdata->fh); write_pdml_field_hex_value(pdata, fi); } else { write_pdml_field_hex_value(pdata, fi); } } } if (node->first_child != NULL) { fputs("\">\n", pdata->fh); } else if (fi->hfinfo->id == proto_data) { fputs("\">\n", pdata->fh); } else { fputs("\"/>\n", pdata->fh); } } /* We always print all levels for PDML. Recurse here. */ if (node->first_child != NULL) { pdata->level++; proto_tree_children_foreach(node, proto_tree_write_node_pdml, pdata); pdata->level--; } /* Take back the extra level we added for fake wrapper protocol */ if (wrap_in_fake_protocol) { pdata->level--; } if (node->first_child != NULL) { /* Indent to correct level */ for (i = -1; i < pdata->level; i++) { fputs(" ", pdata->fh); } /* Close off current element */ if (fi->hfinfo->id != proto_data) { /* Data protocol uses simple tags */ if (fi->hfinfo->type == FT_PROTOCOL) { fputs("</proto>\n", pdata->fh); } else { fputs("</field>\n", pdata->fh); } } } /* Close off fake wrapper protocol */ if (wrap_in_fake_protocol) { fputs("</proto>\n", pdata->fh); } }
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; } }
static gboolean print_field_value(field_info *finfo, int cmd_line_index) { header_field_info *hfinfo; static char *fs_buf = NULL; char *fs_ptr = fs_buf; static GString *label_s = NULL; int fs_buf_len = FIELD_STR_INIT_LEN, fs_len; guint i; string_fmt_t *sf; guint32 uvalue; gint32 svalue; const true_false_string *tfstring = &tfs_true_false; hfinfo = finfo->hfinfo; if (!fs_buf) { fs_buf = g_malloc(fs_buf_len + 1); fs_ptr = fs_buf; } if (!label_s) { label_s = g_string_new(""); } if(finfo->value.ftype->val_to_string_repr) { /* * this field has an associated value, * e.g: ip.hdr_len */ fs_len = fvalue_string_repr_len(&finfo->value, FTREPR_DFILTER); while (fs_buf_len < fs_len) { fs_buf_len *= 2; fs_buf = g_realloc(fs_buf, fs_buf_len + 1); fs_ptr = fs_buf; } fvalue_to_string_repr(&finfo->value, FTREPR_DFILTER, fs_buf); /* String types are quoted. Remove them. */ if ((finfo->value.ftype->ftype == FT_STRING || finfo->value.ftype->ftype == FT_STRINGZ) && fs_len > 2) { fs_buf[fs_len - 1] = '\0'; fs_ptr++; } } if (string_fmts->len > 0 && finfo->hfinfo->strings) { g_string_truncate(label_s, 0); for (i = 0; i < string_fmts->len; i++) { sf = g_ptr_array_index(string_fmts, i); if (sf->plain) { g_string_append(label_s, sf->plain); } else { switch (sf->format) { case SF_NAME: g_string_append(label_s, hfinfo->name); break; case SF_NUMVAL: g_string_append(label_s, fs_ptr); break; case SF_STRVAL: switch(hfinfo->type) { case FT_BOOLEAN: uvalue = fvalue_get_uinteger(&finfo->value); tfstring = (const struct true_false_string*) hfinfo->strings; g_string_append(label_s, uvalue ? tfstring->true_string : tfstring->false_string); break; case FT_INT8: case FT_INT16: case FT_INT24: case FT_INT32: DISSECTOR_ASSERT(!hfinfo->bitmask); svalue = fvalue_get_sinteger(&finfo->value); if (hfinfo->display & BASE_RANGE_STRING) { g_string_append(label_s, rval_to_str(svalue, hfinfo->strings, "Unknown")); } else { g_string_append(label_s, val_to_str(svalue, cVALS(hfinfo->strings), "Unknown")); } case FT_UINT8: case FT_UINT16: case FT_UINT24: case FT_UINT32: uvalue = fvalue_get_uinteger(&finfo->value); if (!hfinfo->bitmask && hfinfo->display & BASE_RANGE_STRING) { g_string_append(label_s, rval_to_str(uvalue, hfinfo->strings, "Unknown")); } else { g_string_append(label_s, val_to_str(uvalue, cVALS(hfinfo->strings), "Unknown")); } break; default: break; } break; default: break; } } } printf(" %u=\"%s\"", cmd_line_index, label_s->str); return TRUE; } if(finfo->value.ftype->val_to_string_repr) { printf(" %u=\"%s\"", cmd_line_index, fs_ptr); return TRUE; } /* * This field doesn't have an associated value, * e.g. http * We return n.a. */ printf(" %u=\"n.a.\"", cmd_line_index); return TRUE; }
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; }
WSLUA_METAMETHOD FieldInfo__call(lua_State* L) { /* Obtain the Value of the field */ FieldInfo fi = checkFieldInfo(L,1); switch(fi->hfinfo->type) { case FT_NONE: lua_pushnil(L); 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 = g_malloc(sizeof(gint64)); *num = fvalue_get_integer64(&(fi->value)); pushInt64(L,num); return 1; } case FT_UINT64: { UInt64 num = g_malloc(sizeof(guint64)); *num = fvalue_get_integer64(&(fi->value)); pushUInt64(L,num); return 1; } case FT_ETHER: { Address eth = g_malloc(sizeof(address)); eth->type = AT_ETHER; eth->len = fi->length; eth->data = tvb_memdup(fi->ds_tvb,fi->start,fi->length); pushAddress(L,eth); return 1; } case FT_IPv4:{ Address ipv4 = g_malloc(sizeof(address)); ipv4->type = AT_IPv4; ipv4->len = fi->length; ipv4->data = tvb_memdup(fi->ds_tvb,fi->start,fi->length); pushAddress(L,ipv4); return 1; } case FT_IPv6: { Address ipv6 = g_malloc(sizeof(address)); ipv6->type = AT_IPv6; ipv6->len = fi->length; ipv6->data = tvb_memdup(fi->ds_tvb,fi->start,fi->length); pushAddress(L,ipv6); return 1; } case FT_IPXNET:{ Address ipx = g_malloc(sizeof(address)); ipx->type = AT_IPX; ipx->len = fi->length; ipx->data = tvb_memdup(fi->ds_tvb,fi->start,fi->length); pushAddress(L,ipx); 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_BYTES: case FT_UINT_BYTES: case FT_GUID: case FT_OID: { ByteArray ba = g_byte_array_new(); g_byte_array_append(ba, ep_tvb_memdup(fi->ds_tvb,fi->start,fi->length),fi->length); pushByteArray(L,ba); return 1; } default: luaL_error(L,"FT_ not yet supported"); return 1; } }
static gboolean val_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, LogFunc logfunc) { guint32 addr; unsigned int nmask_bits; char *has_slash, *s_copy = NULL; char *net_str, *addr_str; fvalue_t *nmask_fvalue; /* Look for CIDR: Is there a single slash in the string? */ has_slash = strchr(s, '/'); if (has_slash) { /* Make a copy of the string and use strtok() to * get the address portion. */ s_copy = ep_strdup(s); addr_str = strtok(s_copy, "/"); /* I just checked for slash! I shouldn't get NULL here. * Double check just in case. */ if (!addr_str) { logfunc("Unexpected strtok() error parsing IP address: %s", s_copy); return FALSE; } } else { addr_str = s; } if (!get_host_ipaddr(addr_str, &addr)) { logfunc("\"%s\" is not a valid hostname or IPv4 address.", addr_str); return FALSE; } ipv4_addr_set_host_order_addr(&(fv->value.ipv4), addr); /* If CIDR, get netmask bits. */ if (has_slash) { net_str = strtok(NULL, "/"); /* I checked for slash! I shouldn't get NULL here. * Double check just in case. */ if (!net_str) { logfunc("Unexpected strtok() error parsing netmask: %s", s_copy); return FALSE; } /* XXX - this is inefficient */ nmask_fvalue = fvalue_from_unparsed(FT_UINT32, net_str, FALSE, logfunc); if (!nmask_fvalue) { return FALSE; } nmask_bits = fvalue_get_uinteger(nmask_fvalue); FVALUE_FREE(nmask_fvalue); if (nmask_bits > 32) { logfunc("Netmask bits in a CIDR IPv4 address should be <= 32, not %u", nmask_bits); return FALSE; } ipv4_addr_set_netmask_bits(&fv->value.ipv4, nmask_bits); } else { /* Not CIDR; mask covers entire address. */ ipv4_addr_set_netmask_bits(&(fv->value.ipv4), 32); } return TRUE; }