void asn1_stack_frame_push(asn1_ctx_t *actx, const gchar *name) { asn1_stack_frame_t *frame; frame = ep_alloc0(sizeof(asn1_stack_frame_t)); frame->name = name; frame->next = actx->stack; actx->stack = frame; }
/* Generic Extensible Framework */ gef_ctx_t* gef_ctx_alloc(gef_ctx_t *parent, const gchar *type) { gef_ctx_t *gefx; gefx = ep_alloc0(sizeof(gef_ctx_t)); gefx->signature = GEF_CTX_SIGNATURE; gefx->parent = parent; gefx->type = type; return gefx; }
static void proto_tree_add_item_ucs2string (proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start ) { guint16 ucs2_len; gboolean dump_bytes = FALSE; ucs2_len = tvb_get_ntohs( tvb, start ); if ( ucs2_iconv != (GIConv)-1 && ucs2_len <= MC_MAX_UCS2LEN ) { gchar *in, *out, *out_const; gsize in_len, out_len, rv_iconv; in_len = ucs2_len * 2; in = (gchar*)tvb_get_ptr(tvb, start + MC_TYPELEN_UCS2LEN, in_len); if ( in ) { out_len = ucs2_len*2; out_const = ep_alloc0( (size_t)out_len + 1); out = out_const; } if ( in != NULL && out != NULL ) { rv_iconv = g_iconv( ucs2_iconv, &in, &in_len, &out, &out_len ); if ( -1 != rv_iconv ) { proto_tree_add_bytes_format_value( tree, hfindex, tvb, start, ucs2_len*2 + MC_TYPELEN_UCS2LEN, tvb_get_ptr( tvb, start, ucs2_len*2 + MC_TYPELEN_UCS2LEN), "%s", out_const ); } else { g_iconv( ucs2_iconv, NULL, 0, NULL, 0 ); dump_bytes = TRUE; } } else { dump_bytes = TRUE; } } else { dump_bytes = TRUE; } if ( dump_bytes ) { proto_tree_add_item(tree, hfindex, tvb, start, MC_TYPELEN_UCS2LEN + ucs2_len * 2, FALSE); } }
static asn1_par_t *push_new_par(asn1_ctx_t *actx) { asn1_par_t *par, **pp; DISSECTOR_ASSERT(actx->stack); par = ep_alloc0(sizeof(asn1_par_t)); pp = &(actx->stack->par); while (*pp) pp = &((*pp)->next); *pp = par; return par; }
/* Calculates a CRC32 checksum from the tvb zeroing out four bytes at the offset and checks it with the given crc32 and adds the result to the tree * Returns true if the calculated CRC32 matches the passed CRC32. * */ static gboolean ts2_add_checked_crc32(proto_tree *tree, int hf_item, tvbuff_t *tvb, guint16 offset, guint32 icrc32 ) { guint8 *zero; guint32 ocrc32; zero = ep_alloc0(4); ocrc32 = crc32_ccitt_tvb(tvb, offset); ocrc32 = crc32_ccitt_seed(zero, 4, 0xffffffff-ocrc32); ocrc32 = crc32_ccitt_tvb_offset_seed(tvb, offset+4, tvb_reported_length_remaining(tvb, offset+4), 0xffffffff-ocrc32); if(icrc32==ocrc32) { proto_tree_add_uint_format(tree, hf_item, tvb, offset, 4, tvb_get_letohl(tvb, 16), "crc32: 0x%04x [correct]", tvb_get_letohl(tvb, offset)); return TRUE; } else { proto_tree_add_uint_format(tree, hf_item, tvb, offset, 4, tvb_get_letohl(tvb,16), "crc32: 0x%04x [incorrect, should be 0x%04x]", tvb_get_letohl(tvb, offset),ocrc32); return FALSE; } }
double asn1_get_real(const guint8 *real_ptr, gint real_len) { guint8 octet; const guint8 *p; guint8 *buf; double val = 0; if (real_len < 1) return val; octet = real_ptr[0]; p = real_ptr + 1; real_len -= 1; if (octet & 0x80) { /* binary encoding */ } else if (octet & 0x40) { /* SpecialRealValue */ switch (octet & 0x3F) { case 0x00: val = HUGE_VAL; break; case 0x01: val = -HUGE_VAL; break; } } else { /* decimal encoding */ buf = ep_alloc0(real_len + 1); memcpy(buf, p, real_len); val = atof(buf); } return val; }
static tvbuff_t * dissect_pft_fec_detailed(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, guint32 findex, guint32 fcount, guint16 seq, gint offset, guint16 plen, gboolean fec _U_, guint16 rsk, guint16 rsz, fragment_data *fdx ) { guint16 decoded_size; guint32 c_max; guint32 rx_min; gboolean first, last; tvbuff_t *new_tvb=NULL; if (fcount > MAX_FRAGMENTS) { if (tree) proto_tree_add_text(tree, tvb , 0, -1, "[Reassembly of %d fragments not attempted]", fcount); return NULL; } first = findex == 0; last = fcount == (findex+1); decoded_size = fcount*plen; c_max = fcount*plen/(rsk+PFT_RS_P); /* rounded down */ rx_min = c_max*rsk/plen; if(rx_min*plen<c_max*rsk) rx_min++; if (fdx) new_tvb = process_reassembled_data (tvb, offset, pinfo, "Reassembled DCP (ETSI)", fdx, &dcp_frag_items, NULL, tree); else { guint fragments=0; guint32 *got; fragment_data *fd; fragment_data *fd_head; if(tree) proto_tree_add_text (tree, tvb, 0, -1, "want %d, got %d need %d", fcount, fragments, rx_min ); got = ep_alloc(fcount*sizeof(guint32)); /* make a list of the findex (offset) numbers of the fragments we have */ fd = fragment_get(pinfo, seq, dcp_fragment_table); for (fd_head = fd; fd_head != NULL; fd_head = fd_head->next) { if(fd_head->data) { got[fragments++] = fd_head->offset; /* this is the findex of the fragment */ } } /* put a sentinel at the end */ got[fragments++] = fcount; /* have we got enough for Reed Solomon to try to correct ? */ if(fragments>=rx_min) { /* yes, in theory */ guint i,current_findex; fragment_data *frag=NULL; guint8 *dummy_data = (guint8*) ep_alloc0 (plen); tvbuff_t *dummytvb = tvb_new_real_data(dummy_data, plen, plen); /* try and decode with missing fragments */ if(tree) proto_tree_add_text (tree, tvb, 0, -1, "want %d, got %d need %d", fcount, fragments, rx_min ); /* fill the fragment table with empty fragments */ current_findex = 0; for(i=0; i<fragments; i++) { guint next_fragment_we_have = got[i]; if (next_fragment_we_have > MAX_FRAGMENTS) { if (tree) proto_tree_add_text(tree, tvb , 0, -1, "[Reassembly of %d fragments not attempted]", next_fragment_we_have); return NULL; } for(; current_findex<next_fragment_we_have; current_findex++) { frag = fragment_add_seq_check (dummytvb, 0, pinfo, seq, dcp_fragment_table, dcp_reassembled_table, current_findex, plen, (current_findex+1!=fcount)); } current_findex++; /* skip over the fragment we have */ } if(frag) new_tvb = process_reassembled_data (tvb, offset, pinfo, "Reassembled DCP (ETSI)", frag, &dcp_frag_items, NULL, tree); } } if(new_tvb) { gboolean decoded = TRUE; tvbuff_t *dtvb = NULL; const guint8 *input = tvb_get_ptr(new_tvb, 0, -1); guint16 reassembled_size = tvb_length(new_tvb); guint8 *deinterleaved = (guint8*) g_malloc (reassembled_size); guint8 *output = (guint8*) g_malloc (decoded_size); rs_deinterleave(input, deinterleaved, plen, fcount); dtvb = tvb_new_child_real_data(tvb, deinterleaved, reassembled_size, reassembled_size); add_new_data_source(pinfo, dtvb, "Deinterleaved"); tvb_set_free_cb(dtvb, g_free); decoded = rs_correct_data(deinterleaved, output, c_max, rsk, rsz); if(tree) proto_tree_add_boolean (tree, hf_edcp_rs_ok, tvb, offset, 2, decoded); new_tvb = tvb_new_child_real_data(dtvb, output, decoded_size, decoded_size); add_new_data_source(pinfo, new_tvb, "RS Error Corrected Data"); tvb_set_free_cb(new_tvb, g_free); } return new_tvb; }
/* Code to actually dissect the packets */ static void dissect_mtp3(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { void* pd_save; mtp3_tap_rec_t* tap_rec = ep_alloc0(sizeof(mtp3_tap_rec_t)); gint heuristic_standard; guint8 si; /* Set up structures needed to add the protocol subtree and manage it */ proto_item *mtp3_item = NULL, *gen_item; proto_tree *mtp3_tree = NULL; pref_mtp3_standard = mtp3_standard; mtp3_item = proto_tree_add_item(tree, proto_mtp3, tvb, 0, 0, ENC_NA); si = tvb_get_guint8(tvb, SIO_OFFSET) & SERVICE_INDICATOR_MASK; if (mtp3_heuristic_standard) { heuristic_standard = heur_mtp3_standard(tvb, pinfo, si); if (heuristic_standard == HEURISTIC_FAILED_STANDARD) { gen_item = proto_tree_add_text(tree, tvb, 0, 0, "Could not determine Heuristic using %s", val_to_str(mtp3_standard, mtp3_standard_vals, "unknown")); } else { gen_item = proto_tree_add_text(tree, tvb, 0, 0, "%s", val_to_str(heuristic_standard, mtp3_standard_vals, "unknown")); mtp3_standard = heuristic_standard; /* Register a frame-end routine to ensure mtp3_standard is set * back, even if an exception is thrown. */ register_frame_end_routine(reset_mtp3_standard); } PROTO_ITEM_SET_GENERATED(gen_item); } /* Make entries in Protocol column on summary display */ switch(mtp3_standard) { case ITU_STANDARD: col_set_str(pinfo->cinfo, COL_PROTOCOL, "MTP3 (Int. ITU)"); proto_item_set_len(mtp3_item, ITU_HEADER_LENGTH); break; case ANSI_STANDARD: col_set_str(pinfo->cinfo, COL_PROTOCOL, "MTP3 (ANSI)"); proto_item_set_len(mtp3_item, ANSI_HEADER_LENGTH); break; case CHINESE_ITU_STANDARD: col_set_str(pinfo->cinfo, COL_PROTOCOL, "MTP3 (Chin. ITU)"); proto_item_set_len(mtp3_item, ANSI_HEADER_LENGTH); break; case JAPAN_STANDARD: col_set_str(pinfo->cinfo, COL_PROTOCOL, "MTP3 (Japan)"); proto_item_set_len(mtp3_item, JAPAN_HEADER_LENGTH); break; }; if (tree) { /* create display subtree for the protocol */ mtp3_tree = proto_item_add_subtree(mtp3_item, ett_mtp3); } mtp3_addr_opc = ep_alloc0(sizeof(mtp3_addr_pc_t)); mtp3_addr_dpc = ep_alloc0(sizeof(mtp3_addr_pc_t)); /* Dissect the packet (even if !tree so can call sub-dissectors and update * the source and destination address columns) */ dissect_mtp3_sio(tvb, pinfo, mtp3_tree, &pd_save); dissect_mtp3_routing_label(tvb, pinfo, mtp3_tree); memcpy(&(tap_rec->addr_opc), mtp3_addr_opc, sizeof(mtp3_addr_pc_t)); memcpy(&(tap_rec->addr_dpc), mtp3_addr_dpc, sizeof(mtp3_addr_pc_t)); tap_rec->si_code = (tvb_get_guint8(tvb, SIO_OFFSET) & SERVICE_INDICATOR_MASK); tap_rec->size = tvb_length(tvb); tap_queue_packet(mtp3_tap, pinfo, tap_rec); dissect_mtp3_payload(tvb, pinfo, tree); pinfo->private_data = pd_save; mtp3_standard = pref_mtp3_standard; }
static void dissect_xtp_ecntl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset) { guint32 len = tvb_length_remaining(tvb, offset); guint32 start = offset; proto_item *top_ti, *ti; proto_tree *xtp_subtree; struct xtp_ecntl ecntl[1]; guint64 *spans, *p; guint32 spans_len; guint i; top_ti = proto_tree_add_text(tree, tvb, offset, len, "Error Control Segment"); xtp_subtree = proto_item_add_subtree(top_ti, ett_xtp_ecntl); if (len < MIN_XTP_ECNTL_PKT_LEN) { proto_item_append_text(top_ti, ", bogus length (%u, must be at least %u)", len, MIN_XTP_ECNTL_PKT_LEN); return; } /** parse **/ /* rseq(8) */ ecntl->rseq = tvb_get_ntohl(tvb, offset); ecntl->rseq <<= 32; ecntl->rseq += tvb_get_ntohl(tvb, offset+4); offset += 8; /* alloc(8) */ ecntl->alloc = tvb_get_ntohl(tvb, offset); ecntl->alloc <<= 32; ecntl->alloc += tvb_get_ntohl(tvb, offset+4); offset += 8; /* echo(4) */ ecntl->echo = tvb_get_ntohl(tvb, offset); offset += 4; /* nspan(4) */ ecntl->nspan = tvb_get_ntohl(tvb, offset); offset += 4; len = len + XTP_HEADER_LEN - offset; spans_len = 16 * ecntl->nspan; if (len != spans_len) { proto_item_append_text(top_ti, ", bogus spans field length (%u, must be %u)", len, spans_len); return; } /* spans(16n) */ spans = ep_alloc0(spans_len); p = spans; for (i = 0; i < ecntl->nspan*2; i++) { guint64 span = tvb_get_ntohl(tvb, offset); span <<= 32; span += tvb_get_ntohl(tvb, offset+4); *p++ = span; offset += 8; } /** add summary **/ if (check_col(pinfo->cinfo, COL_INFO)) { col_append_fstr(pinfo->cinfo, COL_INFO, " Recv-Seq=%" G_GINT64_MODIFIER "u", ecntl->rseq); col_append_fstr(pinfo->cinfo, COL_INFO, " Alloc=%" G_GINT64_MODIFIER "u", ecntl->alloc); } proto_item_append_text(top_ti, ", Recv-Seq: %" G_GINT64_MODIFIER "u", ecntl->rseq); /** display **/ offset = start; /* rseq(8) */ proto_tree_add_uint64(xtp_subtree, hf_xtp_ecntl_rseq, tvb, offset, 8, ecntl->rseq); offset += 8; /* alloc(8) */ proto_tree_add_uint64(xtp_subtree, hf_xtp_ecntl_alloc, tvb, offset, 8, ecntl->alloc); offset += 8; /* echo(4) */ proto_tree_add_uint(xtp_subtree, hf_xtp_ecntl_echo, tvb, offset, 4, ecntl->echo); offset += 4; /* nspan(4) */ ti = proto_tree_add_uint(xtp_subtree, hf_xtp_ecntl_nspan, tvb, offset, 4, ecntl->nspan); offset += 4; /* spans(16n) */ p = spans; for (i = 0; i < ecntl->nspan; i++) { proto_tree_add_uint64(xtp_subtree, hf_xtp_ecntl_span_left, tvb, offset, 8, *p); p++; offset += 8; proto_tree_add_uint64(xtp_subtree, hf_xtp_ecntl_span_right, tvb, offset, 8, *p); p++; offset += 8; } return; }
static gint ett_http = -1; static int proto_http = -1; static int hf_http_is_response = -1; static int hf_http_request_method = -1; static int hf_http_response_code = -1; static int hf_http_transfer_encoding = -1; static int hf_http_content_length = -1; static int hf_http_media = -1; static int hf_http_host = -1; static int hf_http_request_uri = -1; static dissector_handle_t http_handle; static void dissect_http(tvbuff_t* tvb, packet_info* pinfo _U_, proto_tree* tree) { http_info_value_t* msgdata = ep_alloc0(sizeof(http_info_value_t)); tvbparse_elem_t* reqresp; tpg_parser_data_t* tpg; proto_item* pi = proto_tree_add_item(tree,proto_http,tvb,0,-1,FALSE); proto_tree* pt = proto_item_add_subtree(pi,ett_http); tpg = tpg_start(pt,tvb,0,-1,http_tpg_data.wanted_http_sp, msgdata); if (( reqresp = TPG_GET(tpg,http_tpg_data.wanted_http_req_resp) )) { tvbparse_elem_t* hdr; while(( hdr = TPG_GET(tpg,http_tpg_data.wanted_http_header) )) ; if ( TPG_GET(tpg,http_tpg_data.wanted_http_crlf) ) { pi = proto_tree_add_boolean(pt,hf_http_is_response,tvb,0,0,msgdata->is_response);
static int dissect_ppcap_destination_address(tvbuff_t *tvb, packet_info * pinfo, proto_tree * ppcap_tree1, int offset, guint16 msg_len ) { int key2; 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); 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)); 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, (guint8*)&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(tvb, offset, msg_len); 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, 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; }