[关闭]
@natsumi 2016-03-07T01:53:55.000000Z 字数 3040 阅读 1156

wireshark函数分析get_node_field_value

Wireshark


  1. /* Returns an g_malloced string */
  2. gchar* get_node_field_value(field_info* fi, epan_dissect_t* edt)
  3. {
  4. //处理hf_text_only的情况(如 item 0这种结点)
  5. //如果有representation则用representation
  6. //若没有则get_field_hex_value,目前的MIB、SIB1/2没有遇到这种情况
  7. if (fi->hfinfo->id == hf_text_only) {
  8. /* Text label.
  9. * Get the text */
  10. if (fi->rep) {
  11. return g_strdup(fi->rep->representation);
  12. }
  13. else {
  14. return get_field_hex_value(edt->pi.data_src, fi);
  15. }
  16. }
  17. //处理协议数据
  18. else if (fi->hfinfo->id == proto_data) {
  19. /* Uninterpreted data, i.e., the "Data" protocol, is
  20. * printed as a field instead of a protocol. */
  21. return get_field_hex_value(edt->pi.data_src, fi);
  22. }
  23. //其他正常字段
  24. else {
  25. /* Normal protocols and fields */
  26. gchar *dfilter_string;
  27. switch (fi->hfinfo->type)
  28. {
  29. //没有value的两种类型
  30. case FT_PROTOCOL:
  31. /* Print out the full details for the protocol. */
  32. if (fi->rep) {
  33. return g_strdup(fi->rep->representation);
  34. } else {
  35. /* Just print out the protocol abbreviation */
  36. return g_strdup(fi->hfinfo->abbrev);
  37. }
  38. case FT_NONE:
  39. /* Return "1" so that the presence of a field of type
  40. * FT_NONE can be checked when using -T fields */
  41. return g_strdup("1");
  42. //有数据的类型
  43. default:
  44. dfilter_string = fvalue_to_string_repr(&fi->value, FTREPR_DISPLAY, fi->hfinfo->display, NULL);
  45. if (dfilter_string != NULL) {
  46. return dfilter_string;
  47. } else {
  48. return get_field_hex_value(edt->pi.data_src, fi);
  49. }
  50. }
  51. }
  52. }

多次调用到的get_field_hex_value
排除一些错误情况后调用get_field_data函数,获取到指向数据的guint8*后,以每字节两个字符的形式存储为char类型,并返回指针。

  1. static gchar*
  2. get_field_hex_value(GSList *src_list, field_info *fi)
  3. {
  4. const guint8 *pd;
  5. if (!fi->ds_tvb)
  6. return NULL;
  7. if (fi->length > tvb_captured_length_remaining(fi->ds_tvb, fi->start)) {
  8. return g_strdup("field length invalid!");
  9. }
  10. /* Find the data for this field. */
  11. pd = get_field_data(src_list, fi);
  12. if (pd) {
  13. int i;
  14. gchar *buffer;
  15. gchar *p;
  16. int len;
  17. const int chars_per_byte = 2;
  18. len = chars_per_byte * fi->length;
  19. buffer = (gchar *)g_malloc(sizeof(gchar)*(len + 1));
  20. buffer[len] = '\0'; /* Ensure NULL termination in bad cases */
  21. p = buffer;
  22. /* Print a simple hex dump */
  23. for (i = 0 ; i < fi->length; i++) {
  24. g_snprintf(p, chars_per_byte+1, "%02x", pd[i]);
  25. p += chars_per_byte;
  26. }
  27. return buffer;
  28. } else {
  29. return NULL;
  30. }
  31. }

get_field_data获取数值的过程
协议树结构体epan_dissect_t中的pi.data_src是一个单项列表,存储了所有结点的数据,逐个与fi->ds_tvb对比,找到这个特定字段的原始数据并返回指针,没有找到则返回NULL

  1. /*
  2. * Find the data source for a specified field, and return a pointer
  3. * to the data in it. Returns NULL if the data is out of bounds.
  4. */
  5. /* XXX: What am I missing ?
  6. * Why bother searching for fi->ds_tvb for the matching tvb
  7. * in the data_source list ?
  8. * IOW: Why not just use fi->ds_tvb for the arg to tvb_get_ptr() ?
  9. */
  10. static const guint8 *
  11. get_field_data(GSList *src_list, field_info *fi)
  12. {
  13. GSList *src_le;
  14. tvbuff_t *src_tvb;
  15. gint length, tvbuff_length;
  16. struct data_source *src;
  17. for (src_le = src_list; src_le != NULL; src_le = src_le->next) {
  18. src = (struct data_source *)src_le->data;
  19. src_tvb = get_data_source_tvb(src);
  20. if (fi->ds_tvb == src_tvb) {
  21. /*
  22. * Found it.
  23. *
  24. * XXX - a field can have a length that runs past
  25. * the end of the tvbuff. Ideally, that should
  26. * be fixed when adding an item to the protocol
  27. * tree, but checking the length when doing
  28. * that could be expensive. Until we fix that,
  29. * we'll do the check here.
  30. */
  31. tvbuff_length = tvb_captured_length_remaining(src_tvb,
  32. fi->start);
  33. if (tvbuff_length < 0) {
  34. return NULL;
  35. }
  36. length = fi->length;
  37. if (length > tvbuff_length)
  38. length = tvbuff_length;
  39. return tvb_get_ptr(src_tvb, fi->start, length);
  40. }
  41. }
  42. g_assert_not_reached();
  43. return NULL; /* not found */
  44. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注