/* Note: updates *offset */ static void add_notification_data_ipv4addr(tvbuff_t *tvb, proto_tree *tree, int *offset, const char *addrtype) { guint32 ipaddr; proto_tree_add_item(tree, hf_msdp_not_res, tvb, *offset, 3, ENC_BIG_ENDIAN); *offset += 3; ipaddr = tvb_get_ipv4(tvb, *offset); proto_tree_add_ipv4_format(tree, hf_msdp_not_ipv4, tvb, *offset, 4, ipaddr, "%s: %s", addrtype, ip_to_str((guint8 *)&ipaddr)); *offset += 4; return; }
static int dissect_v3_report(tvbuff_t *tvb, proto_tree *parent_tree, int offset) { guint8 m0,m1,m2,m3; guint8 s0,s1,s2,s3; guint8 metric; guint32 ip; while (tvb_reported_length_remaining(tvb, offset) > 0) { proto_tree *tree; proto_item *item; int old_offset_a = offset; item = proto_tree_add_item(parent_tree, hf_route, tvb, offset, -1, ENC_NA); tree = proto_item_add_subtree(item, ett_route); m0 = 0xff; /* read the mask */ m1 = tvb_get_guint8(tvb, offset); m2 = tvb_get_guint8(tvb, offset+1); m3 = tvb_get_guint8(tvb, offset+2); ip = m3; ip = (ip<<8)|m2; ip = (ip<<8)|m1; ip = (ip<<8)|m0; proto_tree_add_ipv4(tree, hf_netmask, tvb, offset, 3, ip); offset += 3; /* read every srcnet, metric pairs */ do { int old_offset_b = offset; m0 = 0xff; s1 = 0; s2 = 0; s3 = 0; s0 = tvb_get_guint8(tvb, offset); offset += 1; if (m1) { s1 = tvb_get_guint8(tvb, offset); offset += 1; } if (m2) { s2 = tvb_get_guint8(tvb, offset); offset += 1; } if (m3) { s3 = tvb_get_guint8(tvb, offset); offset += 1; } /* handle special case for default route V3/3.4.3 */ if ((!m1)&&(!m2)&&(!m3)&&(!s0)) { m0 = 0; } ip = s3; ip = (ip<<8)|s2; ip = (ip<<8)|s1; ip = (ip<<8)|s0; proto_tree_add_ipv4_format(tree, hf_saddr, tvb, old_offset_b, offset-old_offset_b, ip, "%s %d.%d.%d.%d (netmask %d.%d.%d.%d)", m0?"Source Network":"Default Route", s0,s1,s2,s3,m0,m1,m2,m3); metric = tvb_get_guint8(tvb, offset); proto_tree_add_uint(tree, hf_metric, tvb, offset, 1, metric&0x7f); offset += 1; } while (!(metric&0x80)); proto_item_set_len(item, offset-old_offset_a); } return offset; }