static void dissect_time(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *time_tree; proto_item *ti; col_set_str(pinfo->cinfo, COL_PROTOCOL, "TIME"); col_add_fstr(pinfo->cinfo, COL_INFO, "TIME %s", pinfo->srcport == pinfo->match_uint ? "Response":"Request"); ti = proto_tree_add_item(tree, proto_time, tvb, 0, -1, ENC_NA); time_tree = proto_item_add_subtree(ti, ett_time); proto_tree_add_text(time_tree, tvb, 0, 0, pinfo->srcport==pinfo->match_uint ? "Type: Response":"Type: Request"); if (pinfo->srcport == pinfo->match_uint) { /* seconds since 1900-01-01 00:00:00 GMT, *not* 1970 */ guint32 delta_seconds = tvb_get_ntohl(tvb, 0); proto_tree_add_uint_format(time_tree, hf_time_time, tvb, 0, 4, delta_seconds, "%s", abs_time_secs_to_ep_str(delta_seconds-2208988800U, time_display_type, TRUE)); } }
static proto_tree * add_integer_tree(proto_tree *tree, tvbuff_t *tvb, int offset, int name_length, int value_length, guint8 tag) { proto_item *ti; guint8 bool_val; switch (tag) { case TAG_BOOLEAN: if (value_length != 1) { ti = proto_tree_add_text(tree, tvb, offset, 1 + 2 + name_length + 2 + value_length, "%s: Invalid boolean (length is %u, should be 1)", tvb_format_text(tvb, offset + 1 + 2, name_length), value_length); } else { bool_val = tvb_get_guint8(tvb, offset + 1 + 2 + name_length + 2); ti = proto_tree_add_text(tree, tvb, offset, 1 + 2 + name_length + 2 + value_length, "%s: %s", tvb_format_text(tvb, offset + 1 + 2, name_length), val_to_str(bool_val, bool_vals, "Unknown (0x%02x)")); } break; case TAG_INTEGER: case TAG_ENUM: if (value_length != 4) { ti = proto_tree_add_text(tree, tvb, offset, 1 + 2 + name_length + 2 + value_length, "%s: Invalid integer (length is %u, should be 4)", tvb_format_text(tvb, offset + 1 + 2, name_length), value_length); } else { const char *name_val; /* Some fields in IPP are really unix timestamps but IPP * transports these as 4 byte integers. * A simple heuristic to make the display of these fields * more human readable is to assume that if the field name * ends in '-time' then assume they are timestamps instead * of integers. */ name_val=tvb_get_ptr(tvb, offset + 1 + 2, name_length); if ((name_length > 5) && name_val && !tvb_memeql(tvb, offset + 1 + 2 + name_length - 5, "-time", 5)) { ti = proto_tree_add_text(tree, tvb, offset, 1 + 2 + name_length + 2 + value_length, "%s: %s", format_text(name_val, name_length), abs_time_secs_to_ep_str(tvb_get_ntohl(tvb, offset + 1 + 2 + name_length + 2), ABSOLUTE_TIME_LOCAL, TRUE)); } else if ((name_length > 5) && name_val && !tvb_memeql(tvb, offset + 1 + 2, "printer-state", 13)) { ti = proto_tree_add_text(tree, tvb, offset, 1 + 2 + name_length + 2 + value_length, "%s: %s", format_text(name_val, name_length), val_to_str_const(tvb_get_ntohl(tvb, offset + 1 + 2 + name_length + 2), printer_state_vals, "Unknown Printer State")); } else if ((name_length > 5) && name_val && !tvb_memeql(tvb, offset + 1 + 2, "job-state", 9)) { ti = proto_tree_add_text(tree, tvb, offset, 1 + 2 + name_length + 2 + value_length, "%s: %s", format_text(name_val, name_length), val_to_str_const(tvb_get_ntohl(tvb, offset + 1 + 2 + name_length + 2), job_state_vals, "Unknown Job State")); } else { ti = proto_tree_add_text(tree, tvb, offset, 1 + 2 + name_length + 2 + value_length, "%s: %u", format_text(name_val, name_length), tvb_get_ntohl(tvb, offset + 1 + 2 + name_length + 2)); } } break; default: ti = proto_tree_add_text(tree, tvb, offset, 1 + 2 + name_length + 2 + value_length, "%s: Unknown integer type 0x%02x", tvb_format_text(tvb, offset + 1 + 2, name_length), tag); break; } return proto_item_add_subtree(ti, ett_ipp_attr); }