static void decode_iei_ip_address(nsip_ie_t *ie, build_info_t *bi, int ie_start_offset) { guint8 addr_type; guint32 ip4_addr; struct e_in6_addr ip6_addr; addr_type = tvb_get_guint8(bi->tvb, bi->offset); proto_tree_add_item(bi->nsip_tree, hf_nsip_ip_address_type, bi->tvb, bi->offset, 1, ENC_BIG_ENDIAN); switch (addr_type) { case NSIP_IP_ADDRESS_TYPE_IPV4: ie->total_length = 2 + ipv4_element.address_length; ip4_addr = tvb_get_ipv4(bi->tvb, bi->offset+1); proto_tree_add_ipv4(bi->nsip_tree, hf_nsip_ip_address_ipv4, bi->tvb, ie_start_offset, ie->total_length, ip4_addr); break; case NSIP_IP_ADDRESS_TYPE_IPV6: ie->total_length = 2 + ipv6_element.address_length; tvb_get_ipv6(bi->tvb, bi->offset+1, &ip6_addr); proto_tree_add_ipv6(bi->nsip_tree, hf_nsip_ip_address_ipv4, bi->tvb, ie_start_offset, ie->total_length, (guint8 *)&ip6_addr); break; default: return; /* error */ } bi->offset += ie->value_length; }
static int zebra_route(proto_tree *tree, tvbuff_t *tvb, int offset, guint16 len, guint8 family) { guint32 prefix4; guint8 message, prefixlen, buffer6[16]; proto_tree_add_item(tree, hf_zebra_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(tree, hf_zebra_rtflags, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; message = tvb_get_guint8(tvb, offset); offset = zebra_route_message(tree, tvb, offset, message); prefixlen = tvb_get_guint8(tvb, offset); proto_tree_add_uint(tree, hf_zebra_prefixlen, tvb, offset, 1, prefixlen); offset += 1; if (family == ZEBRA_FAMILY_IPV6) { memset(buffer6, '\0', sizeof buffer6); tvb_memcpy(tvb, buffer6, offset, MIN((unsigned) PSIZE(prefixlen), sizeof buffer6)); proto_tree_add_ipv6(tree, hf_zebra_prefix6, tvb, offset, PSIZE(prefixlen), buffer6); }else { prefix4 = 0; tvb_memcpy(tvb, (guint8 *)&prefix4, offset, MIN((unsigned) PSIZE(prefixlen), sizeof prefix4)); proto_tree_add_ipv4(tree, hf_zebra_prefix4, tvb, offset, PSIZE(prefixlen), prefix4); } offset += PSIZE(prefixlen); if (message & ZEBRA_ZAPI_MESSAGE_NEXTHOP) { offset = zebra_route_nexthop(tree, tvb, offset, len); } if (message & ZEBRA_ZAPI_MESSAGE_IFINDEX) { offset = zebra_route_ifindex(tree, tvb, offset, len); } if (message & ZEBRA_ZAPI_MESSAGE_DISTANCE) { proto_tree_add_item(tree, hf_zebra_distance, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; } if (message & ZEBRA_ZAPI_MESSAGE_METRIC) { proto_tree_add_item(tree, hf_zebra_metric, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; } return offset; }
/* * Name: isis_dissect_ipv6_int_clv() * * Description: * Take apart the CLV that lists all the IPv6 interfaces. The * meaning of which is slightly different for the different base packet * types, but the display is not different. What we have is n ip * addresses, plain and simple. * * Input: * tvbuff_t * : tvbuffer for packet data * proto_tree * : protocol display tree to fill out. May be NULL * int : offset into packet data where we are. * int : length of clv we are decoding * int : tree id to use for proto tree. * * Output: * void, but we will add to proto tree if !NULL. */ void isis_dissect_ipv6_int_clv(tvbuff_t *tvb, proto_tree *tree, int offset, int length, int tree_id) { guint8 addr [16]; if ( length <= 0 ) { return; } while ( length > 0 ) { if ( length < 16 ) { isis_dissect_unknown(tvb, tree, offset, "Short IPv6 interface address (%d vs 16)",length ); return; } tvb_memcpy(tvb, addr, offset, sizeof(addr)); if ( tree ) { proto_tree_add_ipv6(tree, tree_id, tvb, offset, 16, addr); } offset += 16; length -= 16; } }
/* * Name: isis_dissect_ipv6_int_clv() * * Description: * Take apart the CLV that lists all the IPv6 interfaces. The * meaning of which is slightly different for the different base packet * types, but the display is not different. What we have is n ip * addresses, plain and simple. * * Input: * tvbuff_t * : tvbuffer for packet data * proto_tree * : protocol display tree to fill out. May be NULL * int : offset into packet data where we are. * int : length of clv we are decoding * int : tree id to use for proto tree. * * Output: * void, but we will add to proto tree if !NULL. */ void isis_dissect_ipv6_int_clv(proto_tree *tree, packet_info* pinfo, tvbuff_t *tvb, expert_field* expert, int offset, int length, int tree_id) { guint8 addr [16]; if ( length <= 0 ) { return; } while ( length > 0 ) { if ( length < 16 ) { proto_tree_add_expert_format(tree, pinfo, expert, tvb, offset, -1, "Short IPv6 interface address (%d vs 16)",length ); return; } tvb_memcpy(tvb, addr, offset, sizeof(addr)); if ( tree ) { proto_tree_add_ipv6(tree, tree_id, tvb, offset, 16, addr); } offset += 16; length -= 16; } }
static int dissect_pbb_addressblock(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint maxoffset, guint8 addressType, guint8 addressSize) { guint8 addr[MAX_ADDR_SIZE]; guint8 numAddr; guint8 address_flags; guint8 head_length = 0, tail_length = 0; guint block_length = 0, midSize = 0; guint block_index = 0, head_index = 0, tail_index = 0, mid_index = 0, prefix_index = 0; proto_tree *addr_tree = NULL; proto_tree *addrFlags_tree = NULL; proto_tree *addrValue_tree = NULL; proto_item *addr_item = NULL; proto_item *addrFlags_item = NULL; proto_item *addrValue_item = NULL; int i = 0; if (maxoffset - offset < 2) { proto_tree_add_expert_format(tree, pinfo, &ei_packetbb_error, tvb, offset, maxoffset - offset, "Not enough octets for minimal addressblock header"); return tvb_reported_length(tvb); } DISSECTOR_ASSERT(addressSize <= MAX_ADDR_SIZE); memset(addr, 0, addressSize); block_length = 2; block_index = offset; midSize = addressSize; numAddr = tvb_get_guint8(tvb, offset++); address_flags = tvb_get_guint8(tvb, offset++); if ((address_flags & ADDR_HASHEAD) != 0) { head_index = offset; if (maxoffset - offset <= 0) { proto_tree_add_expert_format(tree, pinfo, &ei_packetbb_error, tvb, offset, maxoffset - offset, "Not enough octets for addressblock head"); return tvb_reported_length(tvb); } head_length = tvb_get_guint8(tvb, offset++); if (head_length > addressSize-1) { proto_tree_add_expert_format(tree, pinfo, &ei_packetbb_error, tvb, offset, maxoffset - offset, "address head length is too long"); return tvb_reported_length(tvb); } if (maxoffset - offset < head_length) { proto_tree_add_expert_format(tree, pinfo, &ei_packetbb_error, tvb, offset, maxoffset - offset, "Not enough octets for addressblock head"); return tvb_reported_length(tvb); } tvb_memcpy(tvb, addr, offset, head_length); midSize -= head_length; block_length += (head_length+1); offset += head_length; } if ((address_flags & ADDR_HASZEROTAIL) != 0) { tail_index = offset; if (maxoffset - offset <= 0) { proto_tree_add_expert_format(tree, pinfo, &ei_packetbb_error, tvb, offset, maxoffset - offset, "Not enough octets for addressblock tail"); return tvb_reported_length(tvb); } tail_length = tvb_get_guint8(tvb, offset++); if (tail_length > addressSize-1-head_length) { proto_tree_add_expert_format(tree, pinfo, &ei_packetbb_error, tvb, offset, maxoffset - offset, "address tail length is too long"); return tvb_reported_length(tvb); } midSize -= tail_length; block_length++; } else if ((address_flags & ADDR_HASFULLTAIL) != 0) { tail_index = offset; if (maxoffset - offset <= 0) { proto_tree_add_expert_format(tree, pinfo, &ei_packetbb_error, tvb, offset, maxoffset - offset, "Not enough octets for addressblock tail"); return tvb_reported_length(tvb); } tail_length = tvb_get_guint8(tvb, offset++); if (tail_length > addressSize-1-head_length) { proto_tree_add_expert_format(tree, pinfo, &ei_packetbb_error, tvb, offset, maxoffset - offset, "address tail length is too long"); return tvb_reported_length(tvb); } if (maxoffset - offset < tail_length) { proto_tree_add_expert_format(tree, pinfo, &ei_packetbb_error, tvb, offset, maxoffset - offset, "Not enough octets for addressblock tail"); return tvb_reported_length(tvb); } tvb_memcpy(tvb, &addr[addressSize - tail_length], offset, tail_length); midSize -= tail_length; block_length += (tail_length+1); offset += tail_length; } mid_index = offset; block_length += numAddr * midSize; offset += numAddr * midSize; if ((address_flags & ADDR_HASSINGLEPRELEN) != 0) { prefix_index = offset; block_length++; } else if ((address_flags & ADDR_HASMULTIPRELEN) != 0) { prefix_index = offset; block_length += numAddr; } if (maxoffset < block_index + block_length) { proto_tree_add_expert_format(tree, pinfo, &ei_packetbb_error, tvb, offset, maxoffset - offset, "Not enough octets for address block"); return maxoffset; } /* add address tree */ addr_item = proto_tree_add_item(tree, hf_packetbb_addr, tvb, block_index, block_length, ENC_NA); addr_tree = proto_item_add_subtree(addr_item, ett_packetbb_addr); proto_item_append_text(addr_item, " (%d addresses)", numAddr); /* add num-addr */ proto_tree_add_item(addr_tree, hf_packetbb_addr_num, tvb, block_index, 1, ENC_BIG_ENDIAN); /* add flags */ addrFlags_item = proto_tree_add_item(addr_tree, hf_packetbb_addr_flags, tvb, block_index+1, 1, ENC_BIG_ENDIAN); addrFlags_tree = proto_item_add_subtree(addrFlags_item, ett_packetbb_addr_flags); proto_tree_add_item(addrFlags_tree, hf_packetbb_addr_flags_hashead, tvb, block_index+1, 1, ENC_BIG_ENDIAN); proto_tree_add_item(addrFlags_tree, hf_packetbb_addr_flags_hasfulltail, tvb, block_index+1, 1, ENC_BIG_ENDIAN); proto_tree_add_item(addrFlags_tree, hf_packetbb_addr_flags_haszerotail, tvb, block_index+1, 1, ENC_BIG_ENDIAN); proto_tree_add_item(addrFlags_tree, hf_packetbb_addr_flags_hassingleprelen, tvb, block_index+1, 1, ENC_BIG_ENDIAN); proto_tree_add_item(addrFlags_tree, hf_packetbb_addr_flags_hasmultiprelen, tvb, block_index+1, 1, ENC_BIG_ENDIAN); if ((address_flags & ADDR_HASHEAD) != 0) { /* add head */ proto_tree_add_item(addr_tree, hf_packetbb_addr_head, tvb, head_index, head_length+1, ENC_NA); } if ((address_flags & ADDR_HASFULLTAIL) != 0) { /* add full tail */ proto_tree_add_item(addr_tree, hf_packetbb_addr_tail, tvb, tail_index, tail_length+1, ENC_NA); } else if ((address_flags & ADDR_HASZEROTAIL) != 0) { /* add zero tail */ proto_tree_add_item(addr_tree, hf_packetbb_addr_tail, tvb, tail_index, 1, ENC_NA); } for (i=0; i<numAddr; i++) { guint32 ipv4 = 0; guint8 prefix = addressSize * 8; tvb_memcpy(tvb, &addr[head_length], mid_index + midSize*i, midSize); ipv4 = (addr[3] << 24) + (addr[2] << 16) + (addr[1] << 8) + addr[0]; switch (addressType) { case 0: addrValue_item = proto_tree_add_ipv4(addr_tree, hf_packetbb_addr_value[addressType], tvb, mid_index, block_index + block_length - mid_index, ipv4); break; case 1: addrValue_item = proto_tree_add_ipv6(addr_tree, hf_packetbb_addr_value[addressType], tvb, mid_index, block_index + block_length - mid_index, (struct e_in6_addr *)addr); break; case 2: addrValue_item = proto_tree_add_ether(addr_tree, hf_packetbb_addr_value[addressType], tvb, mid_index, block_index + block_length - mid_index, addr); break; case 3: addrValue_item = proto_tree_add_bytes(addr_tree, hf_packetbb_addr_value[addressType], tvb, mid_index, block_index + block_length - mid_index, addr); break; default: break; } addrValue_tree = proto_item_add_subtree(addrValue_item, ett_packetbb_addr_value); proto_tree_add_item(addrValue_tree, hf_packetbb_addr_value_mid, tvb, mid_index + midSize*i, midSize, ENC_NA); if ((address_flags & ADDR_HASSINGLEPRELEN) != 0) { prefix = tvb_get_guint8(tvb, prefix_index); proto_tree_add_item(addrValue_tree, hf_packetbb_addr_value_prefix, tvb, prefix_index, 1, ENC_BIG_ENDIAN); } else if ((address_flags & ADDR_HASMULTIPRELEN) != 0) { prefix = tvb_get_guint8(tvb, prefix_index + i); proto_tree_add_item(addrValue_tree, hf_packetbb_addr_value_prefix, tvb, prefix_index + i, 1, ENC_BIG_ENDIAN); } proto_item_append_text(addrValue_item, "/%d", prefix); } offset = dissect_pbb_tlvblock(tvb, pinfo, addr_tree, block_index + block_length, maxoffset, numAddr); return offset; }
static int dissect_ppcap_destination_address(tvbuff_t *tvb, packet_info * pinfo, proto_tree * ppcap_tree1, int offset) { int key2; guint16 msg_len; msg_len = tvb_get_ntohs(tvb, offset); proto_tree_add_item( ppcap_tree1, hf_ppcap_length, tvb, offset, 2, ENC_BIG_ENDIAN); offset = offset + 2; proto_tree_add_item(ppcap_tree1, hf_ppcap_destreserved, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; key2 = tvb_get_ntohs(tvb, offset); proto_tree_add_item(ppcap_tree1, hf_ppcap_address_type, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; if (key2 == 1) { ssn = tvb_get_guint8(tvb, offset); proto_tree_add_item(ppcap_tree1, hf_ppcap_ssn1, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(ppcap_tree1, hf_ppcap_spc1, tvb, offset, 3, ENC_BIG_ENDIAN); /*dst_addr1 = (guint32 )tvb_get_ntoh24(tvb, offset);*/ mtp3_addr_dpc = wmem_new0(wmem_packet_scope(), mtp3_addr_pc_t); mtp3_addr_dpc->pc = (guint32)tvb_get_ntoh24(tvb, offset); mtp3_addr_dpc->type = ITU_STANDARD; mtp3_addr_dpc->ni = 0; SET_ADDRESS(&pinfo->dst, AT_SS7PC, sizeof(mtp3_addr_pc_t), (guint8 *) mtp3_addr_dpc); if (msg_len%4) msg_len = msg_len + (4 - (msg_len%4)); offset += msg_len-1; return offset; } else if (key2 == 2) { proto_tree_add_item(ppcap_tree1, hf_ppcap_dpc, tvb, offset, 4, ENC_BIG_ENDIAN); /*dst_addr1 = (guint32 )tvb_get_ntoh24(tvb, offset);*/ mtp3_addr_dpc = wmem_new0(wmem_packet_scope(), mtp3_addr_pc_t); mtp3_addr_dpc->pc = tvb_get_ntohl(tvb, offset); mtp3_addr_dpc->type = ITU_STANDARD; mtp3_addr_dpc->ni = 0; SET_ADDRESS(&pinfo->dst, AT_SS7PC, sizeof(mtp3_addr_pc_t), (guint8 *) mtp3_addr_dpc); } else if (key2 == 3) { if (msg_len%16 != 0) { proto_tree_add_ipv4(ppcap_tree1, hf_ppcap_destination_ip_address1, tvb, offset, msg_len, tvb_get_ipv4(tvb, offset)); TVB_SET_ADDRESS(&pinfo->net_dst, AT_IPv4, tvb, offset, 4); COPY_ADDRESS_SHALLOW(&pinfo->dst, &pinfo->net_dst); } else { struct e_in6_addr value; tvb_get_ipv6(tvb, offset,&value); proto_tree_add_ipv6(ppcap_tree1, hf_ppcap_destination_ip_address2, tvb, offset, msg_len, &value); TVB_SET_ADDRESS(&pinfo->net_dst, AT_IPv6, tvb, offset, 6); COPY_ADDRESS_SHALLOW(&pinfo->dst, &pinfo->net_dst); } } else if (key2 == 4) { char *string; string = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, msg_len, ENC_UTF_8|ENC_NA); proto_tree_add_string(ppcap_tree1, hf_ppcap_destination_nodeid, tvb, offset, msg_len, string); TVB_SET_ADDRESS(&pinfo->net_dst, AT_STRINGZ, tvb, offset, msg_len); COPY_ADDRESS_SHALLOW(&pinfo->dst, &pinfo->net_dst); } if (msg_len%4) msg_len = msg_len+(4-(msg_len%4)); offset += msg_len; return offset; }
static int dissect_ppcap_source_address(tvbuff_t *tvb, packet_info *pinfo, proto_tree * ppcap_tree1, int offset) { int key1; guint16 msg_len; msg_len = tvb_get_ntohs(tvb, offset); proto_tree_add_item( ppcap_tree1, hf_ppcap_length, tvb, offset, 2, ENC_BIG_ENDIAN); offset = offset + 2; proto_tree_add_item(ppcap_tree1, hf_ppcap_reserved, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; key1 = tvb_get_ntohs(tvb, offset); proto_tree_add_item(ppcap_tree1, hf_ppcap_address_type, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; if (key1 == 1) { proto_tree_add_item(ppcap_tree1, hf_ppcap_ssn, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(ppcap_tree1, hf_ppcap_spc, tvb, offset, 3, ENC_BIG_ENDIAN); /*src_addr1 = (guint32 )tvb_get_ntoh24(tvb, offset);*/ mtp3_addr_opc = wmem_new0(wmem_packet_scope(), mtp3_addr_pc_t); mtp3_addr_opc->pc = (guint32 )tvb_get_ntoh24(tvb, offset); mtp3_addr_opc->type = ITU_STANDARD; mtp3_addr_opc->ni = 0; /*SET_ADDRESS(&pinfo->net_src, AT_SS7PC, sizeof(mtp3_addr_pc_t), (guint8 *) mtp3_addr_opc);*/ SET_ADDRESS(&pinfo->src, AT_SS7PC, sizeof(mtp3_addr_pc_t), (guint8 *) mtp3_addr_opc); if (msg_len%4) msg_len = msg_len + (4 - (msg_len%4)); offset += msg_len-1; return offset; } else if (key1 == 2) { proto_tree_add_item(ppcap_tree1, hf_ppcap_opc, tvb, offset, msg_len, ENC_BIG_ENDIAN); /*src_addr1 = (guint32 )tvb_get_ntoh24(tvb, offset);*/ mtp3_addr_opc = wmem_new0(wmem_packet_scope(), mtp3_addr_pc_t); mtp3_addr_opc->pc = tvb_get_ntohl(tvb, offset); mtp3_addr_opc->type = ITU_STANDARD; mtp3_addr_opc->ni = 0; SET_ADDRESS(&pinfo->src, AT_SS7PC, sizeof(mtp3_addr_pc_t), (guint8 *) mtp3_addr_opc); } else if (key1 == 3) { if (msg_len%16 != 0) { proto_tree_add_ipv4(ppcap_tree1, hf_ppcap_source_ip_address1, tvb, offset, msg_len, tvb_get_ipv4(tvb, offset)); TVB_SET_ADDRESS(&pinfo->net_src, AT_IPv4, tvb, offset, 4); COPY_ADDRESS_SHALLOW(&pinfo->src, &pinfo->net_src); } else { struct e_in6_addr value; tvb_get_ipv6(tvb, offset, &value); proto_tree_add_ipv6(ppcap_tree1, hf_ppcap_source_ip_address2, tvb, offset, msg_len, &value); TVB_SET_ADDRESS(&pinfo->net_src, AT_IPv6, tvb, offset, 6); COPY_ADDRESS_SHALLOW(&pinfo->src, &pinfo->net_src); } } else if (key1 == 4) { proto_tree_add_item(ppcap_tree1, hf_ppcap_source_nodeid, tvb, offset, msg_len, ENC_ASCII|ENC_NA); TVB_SET_ADDRESS(&pinfo->net_src, AT_STRINGZ, tvb, offset, msg_len); COPY_ADDRESS_SHALLOW(&pinfo->src, &pinfo->net_src); } if (msg_len%4) msg_len = msg_len + (4 - (msg_len%4)); offset += msg_len; return offset; }
static void dissect_aodv_draft_01_v6_rrep(tvbuff_t *tvb, packet_info *pinfo, proto_tree *aodv_tree, proto_item *ti) { int offset = 1; proto_item *tj; proto_tree *aodv_flags_tree; guint8 flags; guint8 prefix_sz; guint8 hop_count; guint32 dest_seqno; struct e_in6_addr dest_addr_v6; struct e_in6_addr orig_addr_v6; guint32 lifetime; int extlen; flags = tvb_get_guint8(tvb, offset); if (aodv_tree) { tj = proto_tree_add_text(aodv_tree, tvb, offset, 1, "Flags:"); aodv_flags_tree = proto_item_add_subtree(tj, ett_aodv_flags); proto_tree_add_boolean(aodv_flags_tree, hf_aodv_flags_rrep_repair, tvb, offset, 1, flags); proto_tree_add_boolean(aodv_flags_tree, hf_aodv_flags_rrep_ack, tvb, offset, 1, flags); if (flags & RREP_REP) proto_item_append_text(tj, " R"); if (flags & RREP_ACK_REQ) proto_item_append_text(tj, " A"); } offset += 1; prefix_sz = tvb_get_guint8(tvb, offset) & 0x7F; if (aodv_tree) proto_tree_add_uint(aodv_tree, hf_aodv_prefix_sz, tvb, offset, 1, prefix_sz); offset += 1; hop_count = tvb_get_guint8(tvb, offset); if (aodv_tree) proto_tree_add_uint(aodv_tree, hf_aodv_hopcount, tvb, offset, 1, hop_count); offset += 1; dest_seqno = tvb_get_ntohl(tvb, offset); if (aodv_tree) proto_tree_add_uint(aodv_tree, hf_aodv_dest_seqno, tvb, offset, 4, dest_seqno); offset += 4; tvb_get_ipv6(tvb, offset, &dest_addr_v6); if (aodv_tree) { proto_tree_add_ipv6(aodv_tree, hf_aodv_dest_ipv6, tvb, offset, INET6_ADDRLEN, (guint8 *)&dest_addr_v6); proto_item_append_text(ti, ", Dest IP: %s", ip6_to_str(&dest_addr_v6)); } col_append_fstr(pinfo->cinfo, COL_INFO, ", D: %s", ip6_to_str(&dest_addr_v6)); offset += INET6_ADDRLEN; tvb_get_ipv6(tvb, offset, &orig_addr_v6); if (aodv_tree) { proto_tree_add_ipv6(aodv_tree, hf_aodv_orig_ipv6, tvb, offset, INET6_ADDRLEN, (guint8 *)&orig_addr_v6); proto_item_append_text(ti, ", Orig IP: %s", ip6_to_str(&orig_addr_v6)); } col_append_fstr(pinfo->cinfo, COL_INFO, ", O: %s", ip6_to_str(&orig_addr_v6)); offset += INET6_ADDRLEN; lifetime = tvb_get_ntohl(tvb, offset); if (aodv_tree) { proto_tree_add_uint(aodv_tree, hf_aodv_lifetime, tvb, offset, 4, lifetime); proto_item_append_text(ti, ", Lifetime=%u", lifetime); } col_append_fstr(pinfo->cinfo, COL_INFO, " Hcnt=%u DSN=%u Lifetime=%u", hop_count, dest_seqno, lifetime); offset += 4; if (aodv_tree) { extlen = tvb_reported_length_remaining(tvb, offset); if (extlen > 0) dissect_aodv_ext(tvb, offset, aodv_tree); } }
static void dissect_aodv_draft_01_v6_rreq(tvbuff_t *tvb, packet_info *pinfo, proto_tree *aodv_tree, proto_item *ti) { int offset = 1; proto_item *tj; proto_tree *aodv_flags_tree; guint8 flags; guint8 hop_count; guint32 rreq_id; guint32 dest_seqno; guint32 orig_seqno; struct e_in6_addr dest_addr_v6; struct e_in6_addr orig_addr_v6; int extlen; flags = tvb_get_guint8(tvb, offset); if (aodv_tree) { tj = proto_tree_add_text(aodv_tree, tvb, offset, 1, "Flags:"); aodv_flags_tree = proto_item_add_subtree(tj, ett_aodv_flags); proto_tree_add_boolean(aodv_flags_tree, hf_aodv_flags_rreq_join, tvb, offset, 1, flags); proto_tree_add_boolean(aodv_flags_tree, hf_aodv_flags_rreq_repair, tvb, offset, 1, flags); proto_tree_add_boolean(aodv_flags_tree, hf_aodv_flags_rreq_gratuitous, tvb, offset, 1, flags); proto_tree_add_boolean(aodv_flags_tree, hf_aodv_flags_rreq_destinationonly, tvb, offset, 1, flags); proto_tree_add_boolean(aodv_flags_tree, hf_aodv_flags_rreq_unknown, tvb, offset, 1, flags); if (flags & RREQ_JOIN) proto_item_append_text(tj, " J"); if (flags & RREQ_REP) proto_item_append_text(tj, " R"); if (flags & RREQ_GRATRREP) proto_item_append_text(tj, " G"); if (flags & RREQ_DESTONLY) proto_item_append_text(tj, " D"); if (flags & RREQ_UNKNSEQ) proto_item_append_text(tj, " U"); } offset += 2; /* skip reserved byte */ hop_count = tvb_get_guint8(tvb, offset); if (aodv_tree) proto_tree_add_uint(aodv_tree, hf_aodv_hopcount, tvb, offset, 1, hop_count); offset += 1; rreq_id = tvb_get_ntohl(tvb, offset); if (aodv_tree) proto_tree_add_uint(aodv_tree, hf_aodv_rreq_id, tvb, offset, 4, rreq_id); offset += 4; dest_seqno = tvb_get_ntohl(tvb, offset); if (aodv_tree) proto_tree_add_uint(aodv_tree, hf_aodv_dest_seqno, tvb, offset, 4, dest_seqno); offset += 4; orig_seqno = tvb_get_ntohl(tvb, offset); if (aodv_tree) proto_tree_add_uint(aodv_tree, hf_aodv_orig_seqno, tvb, offset, 4, orig_seqno); offset += 4; tvb_get_ipv6(tvb, offset, &dest_addr_v6); if (aodv_tree) { proto_tree_add_ipv6(aodv_tree, hf_aodv_dest_ipv6, tvb, offset, INET6_ADDRLEN, (guint8 *)&dest_addr_v6); proto_item_append_text(ti, ", Dest IP: %s", ip6_to_str(&dest_addr_v6)); } col_append_fstr(pinfo->cinfo, COL_INFO, ", D: %s", ip6_to_str(&dest_addr_v6)); offset += INET6_ADDRLEN; tvb_get_ipv6(tvb, offset, &orig_addr_v6); if (aodv_tree) { proto_tree_add_ipv6(aodv_tree, hf_aodv_orig_ipv6, tvb, offset, INET6_ADDRLEN, (guint8 *)&orig_addr_v6); proto_item_append_text(ti, ", Orig IP: %s", ip6_to_str(&orig_addr_v6)); } col_append_fstr(pinfo->cinfo, COL_INFO, ", O: %s Id=%u Hcnt=%u DSN=%u OSN=%u", ip6_to_str(&orig_addr_v6), rreq_id, hop_count, dest_seqno, orig_seqno); offset += INET6_ADDRLEN; if (aodv_tree) { extlen = tvb_reported_length_remaining(tvb, offset); if (extlen > 0) dissect_aodv_ext(tvb, offset, aodv_tree); } }
static void dissect_ftp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { gboolean is_request; proto_tree *ftp_tree = NULL; proto_tree *reqresp_tree = NULL; proto_item *ti, *hidden_item; gint offset; const guchar *line; guint32 code; gchar code_str[4]; gboolean is_port_request = FALSE; gboolean is_eprt_request = FALSE; gboolean is_pasv_response = FALSE; gboolean is_epasv_response = FALSE; gint next_offset; int linelen; int tokenlen = 0; const guchar *next_token; guint32 pasv_ip; guint32 pasv_offset; guint32 ftp_ip; guint32 ftp_ip_len; guint32 eprt_offset; guint32 eprt_af = 0; guint32 eprt_ip; guint16 eprt_ipv6[8]; guint32 eprt_ip_len = 0; guint16 ftp_port; guint32 ftp_port_len; address ftp_ip_address; gboolean ftp_nat; conversation_t *conversation; ftp_ip_address = pinfo->src; if (pinfo->match_uint == pinfo->destport) is_request = TRUE; else is_request = FALSE; col_set_str(pinfo->cinfo, COL_PROTOCOL, "FTP"); /* * Find the end of the first line. * * Note that "tvb_find_line_end()" will return a value that is * not longer than what's in the buffer, so the "tvb_get_ptr()" * call won't throw an exception. */ linelen = tvb_find_line_end(tvb, 0, -1, &next_offset, FALSE); line = tvb_get_ptr(tvb, 0, linelen); /* * Put the first line from the buffer into the summary * (but leave out the line terminator). */ col_add_fstr(pinfo->cinfo, COL_INFO, "%s: %s", is_request ? "Request" : "Response", format_text(line, linelen)); ti = proto_tree_add_item(tree, proto_ftp, tvb, 0, -1, ENC_NA); ftp_tree = proto_item_add_subtree(ti, ett_ftp); if (is_request) { hidden_item = proto_tree_add_boolean(ftp_tree, hf_ftp_request, tvb, 0, 0, TRUE); PROTO_ITEM_SET_HIDDEN(hidden_item); hidden_item = proto_tree_add_boolean(ftp_tree, hf_ftp_response, tvb, 0, 0, FALSE); PROTO_ITEM_SET_HIDDEN(hidden_item); } else { hidden_item = proto_tree_add_boolean(ftp_tree, hf_ftp_request, tvb, 0, 0, FALSE); PROTO_ITEM_SET_HIDDEN(hidden_item); hidden_item = proto_tree_add_boolean(ftp_tree, hf_ftp_response, tvb, 0, 0, TRUE); PROTO_ITEM_SET_HIDDEN(hidden_item); } /* Put the line into the protocol tree. */ ti = proto_tree_add_text(ftp_tree, tvb, 0, next_offset, "%s", tvb_format_text(tvb, 0, next_offset)); reqresp_tree = proto_item_add_subtree(ti, ett_ftp_reqresp); if (is_request) { /* * Extract the first token, and, if there is a first * token, add it as the request. */ tokenlen = get_token_len(line, line + linelen, &next_token); if (tokenlen != 0) { proto_tree_add_item(reqresp_tree, hf_ftp_request_command, tvb, 0, tokenlen, ENC_ASCII|ENC_NA); if (strncmp(line, "PORT", tokenlen) == 0) is_port_request = TRUE; /* * EPRT request command, as per RFC 2428 */ else if (strncmp(line, "EPRT", tokenlen) == 0) is_eprt_request = TRUE; } } else { /* * This is a response; the response code is 3 digits, * followed by a space or hyphen, possibly followed by * text. * * If the line doesn't start with 3 digits, it's part of * a continuation. * * XXX - keep track of state in the first pass, and * treat non-continuation lines not beginning with digits * as errors? */ if (linelen >= 3 && isdigit(line[0]) && isdigit(line[1]) && isdigit(line[2])) { /* * One-line reply, or first or last line * of a multi-line reply. */ tvb_get_nstringz0(tvb, 0, sizeof(code_str), code_str); code = (guint32)strtoul(code_str, NULL, 10); proto_tree_add_uint(reqresp_tree, hf_ftp_response_code, tvb, 0, 3, code); /* * See if it's a passive-mode response. * * XXX - does anybody do FOOBAR, as per RFC * 1639, or has that been supplanted by RFC 2428? */ if (code == 227) is_pasv_response = TRUE; /* * Responses to EPSV command, as per RFC 2428 */ if (code == 229) is_epasv_response = TRUE; /* * Skip the 3 digits and, if present, the * space or hyphen. */ if (linelen >= 4) next_token = line + 4; else next_token = line + linelen; } else { /* * Line doesn't start with 3 digits; assume it's * a line in the middle of a multi-line reply. */ next_token = line; } } offset = (gint) (next_token - line); linelen -= (int) (next_token - line); line = next_token; /* * Add the rest of the first line as request or * reply data. */ if (linelen != 0) { if (is_request) { proto_tree_add_item(reqresp_tree, hf_ftp_request_arg, tvb, offset, linelen, ENC_ASCII|ENC_NA); } else { proto_tree_add_item(reqresp_tree, hf_ftp_response_arg, tvb, offset, linelen, ENC_ASCII|ENC_NA); } } offset = next_offset; /* * If this is a PORT request or a PASV response, handle it. */ if (is_port_request) { if (parse_port_pasv(line, linelen, &ftp_ip, &ftp_port, &pasv_offset, &ftp_ip_len, &ftp_port_len)) { proto_tree_add_ipv4(reqresp_tree, hf_ftp_active_ip, tvb, pasv_offset + (tokenlen+1) , ftp_ip_len, ftp_ip); proto_tree_add_uint(reqresp_tree, hf_ftp_active_port, tvb, pasv_offset + 1 + (tokenlen+1) + ftp_ip_len, ftp_port_len, ftp_port); SET_ADDRESS(&ftp_ip_address, AT_IPv4, 4, (const guint8 *)&ftp_ip); ftp_nat = !ADDRESSES_EQUAL(&pinfo->src, &ftp_ip_address); if (ftp_nat) { proto_tree_add_boolean(reqresp_tree, hf_ftp_active_nat, tvb, 0, 0, ftp_nat); } } } if (is_pasv_response) { if (linelen != 0) { /* * This frame contains a PASV response; set up a * conversation for the data. */ if (parse_port_pasv(line, linelen, &pasv_ip, &ftp_port, &pasv_offset, &ftp_ip_len, &ftp_port_len)) { proto_tree_add_ipv4(reqresp_tree, hf_ftp_pasv_ip, tvb, pasv_offset + 4, ftp_ip_len, pasv_ip); proto_tree_add_uint(reqresp_tree, hf_ftp_pasv_port, tvb, pasv_offset + 4 + 1 + ftp_ip_len, ftp_port_len, ftp_port); SET_ADDRESS(&ftp_ip_address, AT_IPv4, 4, (const guint8 *)&pasv_ip); ftp_nat = !ADDRESSES_EQUAL(&pinfo->src, &ftp_ip_address); if (ftp_nat) { proto_tree_add_boolean(reqresp_tree, hf_ftp_pasv_nat, tvb, 0, 0, ftp_nat); } /* * We use "ftp_ip_address", so that if * we're NAT'd we look for the un-NAT'd * connection. * * XXX - should this call to * "find_conversation()" just use * "ftp_ip_address" and "server_port", and * wildcard everything else? */ conversation = find_conversation(pinfo->fd->num, &ftp_ip_address, &pinfo->dst, PT_TCP, ftp_port, 0, NO_PORT_B); if (conversation == NULL) { /* * XXX - should this call to "conversation_new()" * just use "ftp_ip_address" and "server_port", * and wildcard everything else? * * XXX - what if we did find a conversation? As * we create it only on the first pass through the * packets, if we find one, it's presumably an * unrelated conversation. Should we remove the * old one from the hash table and put this one in * its place? Can the conversation code handle * conversations not in the hash table? Or should * we make conversations support start and end * frames, as circuits do, and treat this as an * indication that one conversation was closed and * a new one was opened? */ conversation = conversation_new( pinfo->fd->num, &ftp_ip_address, &pinfo->dst, PT_TCP, ftp_port, 0, NO_PORT2); conversation_set_dissector(conversation, ftpdata_handle); } } } } if (is_eprt_request) { /* * RFC2428 - sect. 2 * This frame contains a EPRT request; let's dissect it and set up a * conversation for the data connection. */ if (parse_eprt_request(line, linelen, &eprt_af, &eprt_ip, eprt_ipv6, &ftp_port, &eprt_ip_len, &ftp_port_len)) { /* since parse_eprt_request() returned TRUE, we know that we have a valid address family */ eprt_offset = tokenlen + 1 + 1; /* token, space, 1st delimiter */ proto_tree_add_uint(reqresp_tree, hf_ftp_eprt_af, tvb, eprt_offset, 1, eprt_af); eprt_offset += 1 + 1; /* addr family, 2nd delimiter */ if (eprt_af == EPRT_AF_IPv4) { proto_tree_add_ipv4(reqresp_tree, hf_ftp_eprt_ip, tvb, eprt_offset, eprt_ip_len, eprt_ip); SET_ADDRESS(&ftp_ip_address, AT_IPv4, 4, (const guint8 *)&eprt_ip); } else if (eprt_af == EPRT_AF_IPv6) { proto_tree_add_ipv6(reqresp_tree, hf_ftp_eprt_ipv6, tvb, eprt_offset, eprt_ip_len, (const guint8 *)eprt_ipv6); SET_ADDRESS(&ftp_ip_address, AT_IPv6, 16, (const guint8 *)&eprt_ipv6); } eprt_offset += eprt_ip_len + 1; /* addr, 3rd delimiter */ proto_tree_add_uint(reqresp_tree, hf_ftp_eprt_port, tvb, eprt_offset, ftp_port_len, ftp_port); /* Find/create conversation for data */ conversation = find_conversation(pinfo->fd->num, &pinfo->src, &ftp_ip_address, PT_TCP, ftp_port, 0, NO_PORT_B); if (conversation == NULL) { conversation = conversation_new( pinfo->fd->num, &pinfo->src, &ftp_ip_address, PT_TCP, ftp_port, 0, NO_PORT2); conversation_set_dissector(conversation, ftpdata_handle); } } else { proto_item *item; item = proto_tree_add_text(reqresp_tree, tvb, offset - linelen - 1, linelen, "Invalid EPRT arguments"); expert_add_info_format(pinfo, item, PI_MALFORMED, PI_WARN, "EPRT arguments must have the form: |<family>|<addr>|<port>|"); } } if (is_epasv_response) { if (linelen != 0) { proto_item *addr_it; /* * RFC2428 - sect. 3 * This frame contains an EPSV response; set up a * conversation for the data. */ if (parse_extended_pasv_response(line, linelen, &ftp_port, &pasv_offset, &ftp_port_len)) { /* Add IP address and port number to tree */ if (ftp_ip_address.type == AT_IPv4) { guint32 addr; memcpy(&addr, ftp_ip_address.data, 4); addr_it = proto_tree_add_ipv4(reqresp_tree, hf_ftp_epsv_ip, tvb, 0, 0, addr); PROTO_ITEM_SET_GENERATED(addr_it); } else if (ftp_ip_address.type == AT_IPv6) { addr_it = proto_tree_add_ipv6(reqresp_tree, hf_ftp_epsv_ipv6, tvb, 0, 0, (guint8*)ftp_ip_address.data); PROTO_ITEM_SET_GENERATED(addr_it); } proto_tree_add_uint(reqresp_tree, hf_ftp_epsv_port, tvb, pasv_offset + 4, ftp_port_len, ftp_port); /* Find/create conversation for data */ conversation = find_conversation(pinfo->fd->num, &ftp_ip_address, &pinfo->dst, PT_TCP, ftp_port, 0, NO_PORT_B); if (conversation == NULL) { conversation = conversation_new( pinfo->fd->num, &ftp_ip_address, &pinfo->dst, PT_TCP, ftp_port, 0, NO_PORT2); conversation_set_dissector(conversation, ftpdata_handle); } } else { proto_item *item; item = proto_tree_add_text(reqresp_tree, tvb, offset - linelen - 1, linelen, "Invalid EPSV arguments"); expert_add_info_format(pinfo, item, PI_MALFORMED, PI_WARN, "EPSV arguments must have the form (|||<port>|)"); } } } /* * Show the rest of the request or response as text, * a line at a time. * XXX - only if there's a continuation indicator? */ while (tvb_offset_exists(tvb, offset)) { /* * Find the end of the line. */ tvb_find_line_end(tvb, offset, -1, &next_offset, FALSE); /* * Put this line. */ proto_tree_add_text(ftp_tree, tvb, offset, next_offset - offset, "%s", tvb_format_text(tvb, offset, next_offset - offset)); offset = next_offset; } }
static int dissect_zebra_request(proto_tree *tree, gboolean request, tvbuff_t *tvb, int offset, guint16 len, guint8 command) { guint32 prefix4; guint16 i; guint8 buffer6[16], prefixlen, message; proto_item *ti; proto_tree *msg_tree; proto_tree_add_uint(tree, hf_zebra_len, tvb, offset, 2, len); offset += 2; proto_tree_add_uint(tree, hf_zebra_command, tvb, offset, 1, command); offset += 1; switch(command) { case ZEBRA_INTERFACE_ADD: case ZEBRA_INTERFACE_UP: case ZEBRA_INTERFACE_DOWN: if (request) break; /* Request just subscribes to messages */ proto_tree_add_item(tree, hf_zebra_interface, tvb, offset, INTERFACE_NAMSIZ, ENC_ASCII|ENC_NA); offset += INTERFACE_NAMSIZ; proto_tree_add_item(tree, hf_zebra_index, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; proto_tree_add_item(tree, hf_zebra_intflags, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; proto_tree_add_item(tree, hf_zebra_metric, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; proto_tree_add_item(tree, hf_zebra_mtu, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; proto_tree_add_item(tree, hf_zebra_bandwidth, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; break; case ZEBRA_INTERFACE_DELETE: proto_tree_add_item(tree, hf_zebra_interface, tvb, offset, INTERFACE_NAMSIZ, ENC_ASCII|ENC_NA); offset += INTERFACE_NAMSIZ; proto_tree_add_item(tree, hf_zebra_index, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; break; case ZEBRA_INTERFACE_ADDRESS_ADD: case ZEBRA_INTERFACE_ADDRESS_DELETE: proto_tree_add_item(tree, hf_zebra_index, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; proto_tree_add_item(tree, hf_zebra_family, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; /* XXX - switch on the address family here, instead? */ if (len == 17) { /* IPv4 */ proto_tree_add_item(tree, hf_zebra_prefix4, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; } else if (len == 41) { /* IPv6 */ proto_tree_add_item(tree, hf_zebra_prefix6, tvb, offset, 16, ENC_NA); offset += 16; } else break; proto_tree_add_item(tree, hf_zebra_prefixlen, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; if (len == 17) { /* IPv4 */ proto_tree_add_item(tree, hf_zebra_dest4, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; } else if (len == 41) { /* IPv6 */ proto_tree_add_item(tree, hf_zebra_dest6, tvb, offset, 16, ENC_NA); offset += 16; } break; case ZEBRA_IPV4_ROUTE_ADD: case ZEBRA_IPV4_ROUTE_DELETE: proto_tree_add_item(tree, hf_zebra_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(tree, hf_zebra_rtflags, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; message = tvb_get_guint8(tvb, offset); ti = proto_tree_add_uint(tree, hf_zebra_message, tvb, offset, 1, message); msg_tree = proto_item_add_subtree(ti, ett_message); proto_tree_add_boolean(msg_tree, hf_zebra_msg_nexthop, tvb, offset, 1, message); proto_tree_add_boolean(msg_tree, hf_zebra_msg_index, tvb, offset, 1, message); proto_tree_add_boolean(msg_tree, hf_zebra_msg_distance, tvb, offset, 1, message); proto_tree_add_boolean(msg_tree, hf_zebra_msg_metric, tvb, offset, 1, message); offset += 1; prefixlen = tvb_get_guint8(tvb, offset); proto_tree_add_uint(tree, hf_zebra_prefixlen, tvb, offset, 1, prefixlen); offset += 1; prefix4 = 0; tvb_memcpy(tvb, (guint8 *)&prefix4, offset, MIN((unsigned) PSIZE(prefixlen), sizeof prefix4)); proto_tree_add_ipv4(tree, hf_zebra_prefix4, tvb, offset, PSIZE(prefixlen), prefix4); offset += PSIZE(prefixlen); if (message & ZEBRA_ZAPI_MESSAGE_NEXTHOP) { i = tvb_get_guint8(tvb, offset); proto_tree_add_uint(tree, hf_zebra_nexthopnum, tvb, offset, 1, i); offset += 1; if (i>len) break; /* Sanity */ while (i--) { proto_tree_add_item(tree, hf_zebra_nexthop4, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; } } if (message & ZEBRA_ZAPI_MESSAGE_IFINDEX) { i = tvb_get_guint8(tvb, offset); proto_tree_add_uint(tree, hf_zebra_indexnum, tvb, offset, 1, i); offset += 1; if (i>len) break; /* Sanity */ while (i--) { proto_tree_add_item(tree, hf_zebra_index, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; } } if (message & ZEBRA_ZAPI_MESSAGE_DISTANCE) { proto_tree_add_item(tree, hf_zebra_distance, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; } if (message & ZEBRA_ZAPI_MESSAGE_METRIC) { proto_tree_add_item(tree, hf_zebra_metric, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; } break; case ZEBRA_IPV6_ROUTE_ADD: case ZEBRA_IPV6_ROUTE_DELETE: proto_tree_add_item(tree, hf_zebra_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(tree, hf_zebra_rtflags, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; message = tvb_get_guint8(tvb, offset); ti = proto_tree_add_uint(tree, hf_zebra_message, tvb, offset, 1, message); msg_tree = proto_item_add_subtree(ti, ett_message); proto_tree_add_boolean(msg_tree, hf_zebra_msg_nexthop, tvb, offset, 1, message); proto_tree_add_boolean(msg_tree, hf_zebra_msg_index, tvb, offset, 1, message); proto_tree_add_boolean(msg_tree, hf_zebra_msg_distance, tvb, offset, 1, message); proto_tree_add_boolean(msg_tree, hf_zebra_msg_metric, tvb, offset, 1, message); offset += 1; prefixlen = tvb_get_guint8(tvb, offset); proto_tree_add_uint(tree, hf_zebra_prefixlen, tvb, offset, 1, prefixlen); offset += 1; memset(buffer6, '\0', sizeof buffer6); tvb_memcpy(tvb, buffer6, offset, MIN((unsigned) PSIZE(prefixlen), sizeof buffer6)); proto_tree_add_ipv6(tree, hf_zebra_prefix6, tvb, offset, PSIZE(prefixlen), buffer6); offset += PSIZE(prefixlen); if (message & ZEBRA_ZAPI_MESSAGE_NEXTHOP) { i = tvb_get_guint8(tvb, offset); proto_tree_add_uint(tree, hf_zebra_nexthopnum, tvb, offset, 1, i); offset += 1; if (i>len) break; /* Sanity */ while (i--) { proto_tree_add_item(tree, hf_zebra_nexthop6, tvb, offset, 16, ENC_NA); offset += 16; } } if (message & ZEBRA_ZAPI_MESSAGE_IFINDEX) { i = tvb_get_guint8(tvb, offset); proto_tree_add_uint(tree, hf_zebra_indexnum, tvb, offset, 1, i); offset += 1; if (i>len) break; /* Sanity */ while (i--) { proto_tree_add_item(tree, hf_zebra_index, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; } } if (message & ZEBRA_ZAPI_MESSAGE_DISTANCE) { proto_tree_add_item(tree, hf_zebra_distance, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; } if (message & ZEBRA_ZAPI_MESSAGE_METRIC) { proto_tree_add_item(tree, hf_zebra_metric, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; } break; case ZEBRA_REDISTRIBUTE_ADD: case ZEBRA_REDISTRIBUTE_DELETE: proto_tree_add_item(tree, hf_zebra_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; break; case ZEBRA_REDISTRIBUTE_DEFAULT_ADD: case ZEBRA_REDISTRIBUTE_DEFAULT_DELETE: break; case ZEBRA_IPV4_NEXTHOP_LOOKUP: proto_tree_add_item(tree, hf_zebra_nexthop4, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; proto_tree_add_item(tree, hf_zebra_metric, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; break; case ZEBRA_IPV6_NEXTHOP_LOOKUP: /* Not yet implemeted in ZEBRA */ break; } return offset; }
static int dissect_ppcap_destination_address(tvbuff_t *tvb, packet_info * pinfo, proto_tree * ppcap_tree1, int offset, guint16 msg_len ) { int key2; const guchar *dst_addr; /*guint32 dst_addr1;*/ proto_tree_add_item(ppcap_tree1, hf_ppcap_destreserved, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; key2 = tvb_get_ntohs(tvb, offset); proto_tree_add_item(ppcap_tree1, hf_ppcap_address_type, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; if (key2 == 1) { ssn = tvb_get_guint8(tvb, offset); proto_tree_add_item(ppcap_tree1, hf_ppcap_ssn1, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(ppcap_tree1, hf_ppcap_spc1, tvb, offset, 3, ENC_BIG_ENDIAN); /*dst_addr1 = (guint32 )tvb_get_ntoh24(tvb, offset);*/ mtp3_addr_dpc = ep_alloc0(sizeof(mtp3_addr_pc_t)); mtp3_addr_dpc->pc = (guint32)tvb_get_ntoh24(tvb, offset); mtp3_addr_dpc->type = 1; /* ITU_STANDARD */ mtp3_addr_dpc->ni = 0; SET_ADDRESS(&pinfo->dst, AT_SS7PC, sizeof(mtp3_addr_pc_t), (guint8 *) mtp3_addr_dpc); /*dst_addr = tvb_get_ptr(tvb, offset, msg_len-1); SET_ADDRESS(&pinfo->net_dst, AT_SS7PC, msg_len-1, dst_addr); SET_ADDRESS(&pinfo->dst, AT_SS7PC, msg_len-1, dst_addr);*/ if (msg_len%4) msg_len = msg_len + (4 - (msg_len%4)); offset += msg_len-1; return offset; } else if (key2 == 2) { proto_tree_add_item(ppcap_tree1, hf_ppcap_dpc, tvb, offset, 4, ENC_BIG_ENDIAN); /*dst_addr1 = (guint32 )tvb_get_ntoh24(tvb, offset);*/ mtp3_addr_dpc = ep_alloc0(sizeof(mtp3_addr_pc_t)); mtp3_addr_dpc->pc = tvb_get_ntohl(tvb, offset); mtp3_addr_dpc->type = 1; /* ITU_STANDARD */ mtp3_addr_dpc->ni = 0; SET_ADDRESS(&pinfo->dst, AT_SS7PC, sizeof(mtp3_addr_pc_t), (guint8 *) mtp3_addr_dpc); } else if (key2 == 3) { if (msg_len%4 == 0) { proto_tree_add_ipv4(ppcap_tree1, hf_ppcap_destination_ip_address1, tvb, offset, msg_len, tvb_get_ipv4(tvb, offset)); dst_addr = tvb_get_ptr(tvb, offset, 4); SET_ADDRESS(&pinfo->net_dst, AT_IPv4, 4, dst_addr); SET_ADDRESS(&pinfo->dst, AT_IPv4, 4, dst_addr); } else { struct e_in6_addr value; tvb_get_ipv6(tvb, offset,&value); proto_tree_add_ipv6(ppcap_tree1, hf_ppcap_destination_ip_address2, tvb, offset, msg_len, (guint8*)&value); dst_addr = tvb_get_ptr(tvb, offset, 6); SET_ADDRESS(&pinfo->net_dst, AT_IPv6, 6, dst_addr); SET_ADDRESS(&pinfo->dst, AT_IPv6, 6, dst_addr); } } else if (key2 == 4) { char *string; string = tvb_get_string(tvb, offset, msg_len); proto_tree_add_string(ppcap_tree1, hf_ppcap_destination_nodeid, tvb, offset, msg_len, string); dst_addr = tvb_get_ptr(tvb, offset, msg_len); SET_ADDRESS(&pinfo->net_dst, AT_STRINGZ, msg_len, dst_addr); SET_ADDRESS(&pinfo->dst, AT_STRINGZ, msg_len, dst_addr); /*g_free(string);*/ } if (msg_len%4) msg_len = msg_len+(4-(msg_len%4)); offset += msg_len; return offset; }
static int dissect_ppcap_source_address(tvbuff_t *tvb, packet_info *pinfo, proto_tree * ppcap_tree1, int offset, guint16 msg_len) { int key1; const guchar *src_addr; /*guint32 src_addr1;*/ proto_tree_add_item(ppcap_tree1, hf_ppcap_reserved, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; key1 = tvb_get_ntohs(tvb, offset); proto_tree_add_item(ppcap_tree1, hf_ppcap_address_type, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; if (key1 == 1) { proto_tree_add_item(ppcap_tree1, hf_ppcap_ssn, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(ppcap_tree1, hf_ppcap_spc, tvb, offset, 3, ENC_BIG_ENDIAN); /*src_addr1 = (guint32 )tvb_get_ntoh24(tvb, offset);*/ mtp3_addr_opc = ep_alloc0(sizeof(mtp3_addr_pc_t)); mtp3_addr_opc->pc = (guint32 )tvb_get_ntoh24(tvb, offset); mtp3_addr_opc->type = 1; /* ITU_STANDARD */ mtp3_addr_opc->ni = 0; /*SET_ADDRESS(&pinfo->net_src, AT_SS7PC, sizeof(mtp3_addr_pc_t), (guint8 *) mtp3_addr_opc);*/ SET_ADDRESS(&pinfo->src, AT_SS7PC, sizeof(mtp3_addr_pc_t), (guint8 *) mtp3_addr_opc); if (msg_len%4) msg_len = msg_len + (4 - (msg_len%4)); offset += msg_len-1; return offset; } else if (key1 == 2) { proto_tree_add_item(ppcap_tree1, hf_ppcap_opc, tvb, offset, msg_len, ENC_BIG_ENDIAN); /*src_addr1 = (guint32 )tvb_get_ntoh24(tvb, offset);*/ mtp3_addr_opc = ep_alloc0(sizeof(mtp3_addr_pc_t)); mtp3_addr_opc->pc = tvb_get_ntohl(tvb, offset); mtp3_addr_opc->type = 1; /* ITU_STANDARD */ mtp3_addr_opc->ni = 0; SET_ADDRESS(&pinfo->src, AT_SS7PC, sizeof(mtp3_addr_pc_t), (guint8 *) mtp3_addr_opc); /*src_addr = tvb_get_ptr(tvb, offset, 4);*/ /*SET_ADDRESS(&pinfo->net_src, AT_SS7PC, 4, src_addr);*/ /*SET_ADDRESS(&pinfo->src, AT_SS7PC, 4, src_addr);*/ } else if (key1 == 3) { if (msg_len%4 == 0) { proto_tree_add_ipv4(ppcap_tree1, hf_ppcap_source_ip_address1, tvb, offset, msg_len, tvb_get_ipv4(tvb, offset)); src_addr = tvb_get_ptr(tvb, offset, 4); SET_ADDRESS(&pinfo->net_src, AT_IPv4, 4, src_addr); SET_ADDRESS(&pinfo->src, AT_IPv4, 4, src_addr); } else { struct e_in6_addr value; tvb_get_ipv6(tvb, offset, &value); proto_tree_add_ipv6(ppcap_tree1, hf_ppcap_source_ip_address2, tvb, offset, msg_len, (guint8*)&value); src_addr = tvb_get_ptr(tvb, offset, 6); SET_ADDRESS(&pinfo->net_src, AT_IPv6, 6, src_addr); SET_ADDRESS(&pinfo->src, AT_IPv6, 6, src_addr); } } else if (key1 == 4) { proto_tree_add_item(ppcap_tree1, hf_ppcap_source_nodeid, tvb, offset, msg_len, ENC_BIG_ENDIAN|ENC_ASCII); src_addr = tvb_get_ptr(tvb, offset, msg_len); SET_ADDRESS(&pinfo->net_src, AT_STRINGZ, msg_len, src_addr); SET_ADDRESS(&pinfo->src, AT_STRINGZ, msg_len, src_addr); } if (msg_len%4) msg_len = msg_len + (4 - (msg_len%4)); offset += msg_len; return offset; }