inline extended_reg<T> extended_mul_unsigned(T lhs, T rhs) { QUAN_STATIC_ASSERT((std::is_unsigned<T>::value)); static const T shift = quan::meta::asm_::nibble_shift<T>::value; static const T lo_mask = quan::meta::asm_::lo_nibble_mask<T>::value; extended_reg<T> res; res.sign = 1; //lo res.lo = lo_nibble(lhs) * lo_nibble(rhs); //mid1 T reg = lo_nibble(lhs) * hi_nibble(rhs); res.hi = hi_nibble(reg); reg &= lo_mask; reg += hi_nibble(res.lo); res.lo = lo_nibble(res.lo) | (lo_nibble(reg) << shift); res.hi += hi_nibble(reg); //mid2 reg = hi_nibble(lhs) * lo_nibble(rhs); res.hi += hi_nibble(reg); reg &= lo_mask; reg += hi_nibble(res.lo); res.lo = lo_nibble(res.lo) | (lo_nibble(reg) << shift); res.hi += hi_nibble(reg); //hi res.hi += hi_nibble(lhs) * hi_nibble(rhs); return res; }
static void dissect_auto_rp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint8 ver_type, rp_count; col_set_str(pinfo->cinfo, COL_PROTOCOL, "Auto-RP"); col_clear(pinfo->cinfo, COL_INFO); ver_type = tvb_get_guint8(tvb, 0); rp_count = tvb_get_guint8(tvb, 1); if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "%s (v%s) for %u RP%s", val_to_str(lo_nibble(ver_type), auto_rp_type_vals, "Unknown"), val_to_str(hi_nibble(ver_type), auto_rp_ver_vals, "Unknown"), rp_count, plurality(rp_count, "", "s")); if (tree) { proto_item *ti, *tv; proto_tree *auto_rp_tree, *ver_type_tree; int i, offset; guint16 holdtime; offset = 0; ti = proto_tree_add_item(tree, proto_auto_rp, tvb, offset, -1, FALSE); auto_rp_tree = proto_item_add_subtree(ti, ett_auto_rp); tv = proto_tree_add_text(auto_rp_tree, tvb, offset, 1, "Version: %s, Packet type: %s", val_to_str(hi_nibble(ver_type), auto_rp_ver_vals, "Unknown"), val_to_str(lo_nibble(ver_type), auto_rp_type_vals, "Unknown")); ver_type_tree = proto_item_add_subtree(tv, ett_auto_rp_ver_type); proto_tree_add_uint(ver_type_tree, hf_auto_rp_version, tvb, offset, 1, ver_type); proto_tree_add_uint(ver_type_tree, hf_auto_rp_type, tvb, offset, 1, ver_type); offset++; proto_tree_add_uint(auto_rp_tree, hf_auto_rp_count, tvb, offset, 1, rp_count); offset++; holdtime = tvb_get_ntohs(tvb, offset); proto_tree_add_uint_format_value(auto_rp_tree, hf_auto_rp_holdtime, tvb, offset, 2, holdtime, "%u second%s", holdtime, plurality(holdtime, "", "s")); offset+=2; proto_tree_add_text(auto_rp_tree, tvb, offset, 4, "Reserved: 0x%x", tvb_get_ntohs(tvb, offset)); offset+=4; for (i = 0; i < rp_count; i++) offset = do_auto_rp_map(tvb, offset, auto_rp_tree); if (tvb_offset_exists(tvb, offset)) proto_tree_add_text(tree, tvb, offset, -1, "Trailing junk"); } return; }
static void dissect_auto_rp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint8 ver_type, rp_count; col_set_str(pinfo->cinfo, COL_PROTOCOL, "Auto-RP"); col_clear(pinfo->cinfo, COL_INFO); ver_type = tvb_get_guint8(tvb, 0); rp_count = tvb_get_guint8(tvb, 1); col_add_fstr(pinfo->cinfo, COL_INFO, "%s (v%s) for %u RP%s", val_to_str_const(lo_nibble(ver_type), auto_rp_type_vals, "Unknown"), val_to_str_const(hi_nibble(ver_type), auto_rp_ver_vals, "Unknown"), rp_count, plurality(rp_count, "", "s")); if (tree) { proto_item *ti; proto_tree *auto_rp_tree, *ver_type_tree; int i, offset; guint16 holdtime; offset = 0; ti = proto_tree_add_item(tree, proto_auto_rp, tvb, offset, -1, ENC_NA); auto_rp_tree = proto_item_add_subtree(ti, ett_auto_rp); ver_type_tree = proto_tree_add_subtree_format(auto_rp_tree, tvb, offset, 1, ett_auto_rp_ver_type, NULL, "Version: %s, Packet type: %s", val_to_str_const(hi_nibble(ver_type), auto_rp_ver_vals, "Unknown"), val_to_str_const(lo_nibble(ver_type), auto_rp_type_vals, "Unknown")); proto_tree_add_uint(ver_type_tree, hf_auto_rp_version, tvb, offset, 1, ver_type); proto_tree_add_uint(ver_type_tree, hf_auto_rp_type, tvb, offset, 1, ver_type); offset++; proto_tree_add_uint(auto_rp_tree, hf_auto_rp_count, tvb, offset, 1, rp_count); offset++; holdtime = tvb_get_ntohs(tvb, offset); proto_tree_add_uint_format_value(auto_rp_tree, hf_auto_rp_holdtime, tvb, offset, 2, holdtime, "%u second%s", holdtime, plurality(holdtime, "", "s")); offset+=2; proto_tree_add_item(auto_rp_tree, hf_auto_rp_reserved, tvb, offset, 4, ENC_BIG_ENDIAN); offset+=4; for (i = 0; i < rp_count; i++) offset = do_auto_rp_map(tvb, offset, auto_rp_tree); if (tvb_reported_length_remaining(tvb, offset) > 0) proto_tree_add_item(tree, hf_auto_rp_trailing_junk, tvb, offset, -1, ENC_NA); } return; }
static void dissect_tcp_tree(tvbuff_t *tvb, packet_info *pinfo, proto_tree *stt_tree) { int offset = 0; proto_tree *tcp_tree; proto_item *tcp_item, *data_offset_item; int data_offset; proto_tree_add_item(stt_tree, hf_stt_stream_id, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(stt_tree, hf_stt_dport, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(stt_tree, hf_stt_pkt_len, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(stt_tree, hf_stt_seg_off, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(stt_tree, hf_stt_pkt_id, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; tcp_item = proto_tree_add_item(stt_tree, hf_stt_tcp_data, tvb, offset, 8, ENC_NA); tcp_tree = proto_item_add_subtree(tcp_item, ett_stt_tcp_data); proto_item_set_text(tcp_item, "TCP Data"); data_offset = hi_nibble(tvb_get_guint8(tvb, offset)) * 4; data_offset_item = proto_tree_add_uint_format_value(tcp_tree, hf_stt_tcp_data_offset, tvb, offset, 1, data_offset, "%u bytes", data_offset); if (data_offset != STT_TCP_HDR_LEN) { expert_add_info(pinfo, data_offset_item, &ei_stt_data_offset_bad); } offset = dissect_tcp_flags(tcp_tree, tvb, offset); proto_tree_add_item(tcp_tree, hf_stt_tcp_window, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; dissect_stt_checksum(tvb, pinfo, stt_tree); offset += 2; proto_tree_add_item(tcp_tree, hf_stt_tcp_urg_ptr, tvb, offset, 2, ENC_BIG_ENDIAN); }
/* code to dissect fairly common sequence in NORM packets */ static guint dissect_grrtetc(proto_tree *tree, tvbuff_t *tvb, guint offset) { guint8 backoff; double gsizex; double grtt; proto_tree_add_item(tree, hf.instance_id, tvb, offset, 2, ENC_BIG_ENDIAN); offset+=2; grtt = UnquantizeRtt(tvb_get_guint8(tvb, offset)); proto_tree_add_double(tree, hf.grtt, tvb, offset, 1, grtt); offset++; backoff = hi_nibble(tvb_get_guint8(tvb, offset)); gsizex = UnquantizeGSize((guint8)lo_nibble(tvb_get_guint8(tvb, offset))); proto_tree_add_uint(tree, hf.backoff, tvb, offset, 1, backoff); proto_tree_add_double(tree, hf.gsize, tvb, offset, 1, gsizex); offset++; return offset; }
/* Routine to return the dissector handle based on heuristic packet inspection */ static dissector_handle_t get_heuristic_handle(tvbuff_t *tvb) { int offset = MIRROR_HDR_SZ; /* Point past the 8 byte mirror header */ int byte0, byte1, byte2, byte3; /* The following section is designed to determine the nature of the mirrored packet. * * The first four bytes will be inspected to deduce the type of traffic. * The bit pattern shown below is the basis. A bit of "x" is a variable field. * * IPv4 Header: 0100 0101 xxxx xx00 ==> Pattern for standard IPv4 20-byte header * IPv6 Header: 0110 xxxx xxxx 0000 0000 0000 0000 0000 ==> Pattern for standard IPv6 header with no flow label * PPP/HDLC: 1111 1111 0000 0011 xx00 0000 0010 0001 ==> HDLC-like framing for PPP (FF 03 x0 21) * PPP/HDLC: 1111 1111 0000 0011 0000 0000 0101 0111 ==> HDLC-like framing for PPP IPv6 (FF 03 00 57) */ if (!tvb_bytes_exist(tvb, offset, 4)) return NULL; /* Not enough bytes for heuristic test */ /* Filter for IPv4 and IPv6 packets */ byte0 = tvb_get_guint8(tvb, offset + 0); byte1 = tvb_get_guint8(tvb, offset + 1); byte2 = tvb_get_guint8(tvb, offset + 2); byte3 = tvb_get_guint8(tvb, offset + 3); /* Look for IPv4 with standard header length */ if ( byte0 == 0x45 && ipv4_handle ) return ipv4_handle; /* Look for IPv6 with no flow label */ else if ( hi_nibble(byte0) == 6 && lo_nibble(byte1) == 0 && byte2 == 0 && byte3 == 0 && ipv6_handle ) return ipv6_handle; /* Look for PPP/HDLC for LCP and IPv4 */ else if ( byte0 == 0xff && byte1 == 0x03 && lo_nibble(byte2) == 0 && byte3 == 0x21 && hdlc_handle ) return hdlc_handle; /* Look for PPP/HDLC for IPv6 */ else if ( byte0 == 0xff && byte1 == 0x03 && byte2 == 0 && byte3 == 0x57 && hdlc_handle ) return hdlc_handle; /* If it's something else entirely return nothing */ else return NULL; }
inline extended_reg<T> extended_add_unsigned(T lhs, T rhs) { QUAN_STATIC_ASSERT((std::is_unsigned<T>::value)); extended_reg<T> res; res.sign = extended_reg<T>::positive; static const T shift = quan::meta::asm_::nibble_shift<T>::value; static const T lo_mask = quan::meta::asm_::lo_nibble_mask<T>::value; res.lo = lo_nibble(lhs) + lo_nibble(rhs); T reg = hi_nibble(res.lo) + hi_nibble(lhs); res.lo = lo_nibble(res.lo) | ( lo_nibble(reg) << shift); res.hi = hi_nibble(reg); reg = hi_nibble(res.lo) + hi_nibble(rhs); res.lo = lo_nibble(res.lo) | ( lo_nibble(reg) << shift); res.hi += hi_nibble(reg); return res; }
static int dissect_ltp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_item *ti = NULL; proto_tree *ltp_tree = NULL; int frame_offset; int header_offset; int segment_offset = 0; int hdr_extn_offset = 0; int trl_extn_offset = 0; guint8 ltp_hdr; gint ltp_type; guint8 ltp_extn_cnt; gint hdr_extn_cnt; gint trl_extn_cnt; guint64 engine_id; guint64 session_num; int engine_id_size; int session_num_size; proto_item *ltp_header_item = NULL; proto_item *ltp_session_item = NULL; proto_tree *ltp_header_tree = NULL; proto_tree *ltp_session_tree = NULL; /* Check that there's enough data */ if(tvb_length(tvb) < LTP_MIN_DATA_BUFFER){ return 0; } frame_offset = 0; header_offset = 0; col_set_str(pinfo->cinfo, COL_PROTOCOL, "LTP Segment"); /* Extract all the header info from the packet */ ltp_hdr = tvb_get_guint8(tvb, frame_offset); header_offset++; engine_id = evaluate_sdnv_64(tvb,frame_offset + header_offset,&engine_id_size); header_offset += engine_id_size; if((unsigned)header_offset >= tvb_length(tvb)){ col_set_str(pinfo->cinfo, COL_INFO, "Protocol Error"); return 0; } session_num = evaluate_sdnv_64(tvb,frame_offset + header_offset,&session_num_size); header_offset += session_num_size; if((unsigned)header_offset >= tvb_length(tvb)){ col_set_str(pinfo->cinfo, COL_INFO, "Protocol Error"); return 0; } ti = proto_tree_add_item(tree, proto_ltp, tvb, 0, -1, ENC_NA); ltp_tree = proto_item_add_subtree(ti, ett_ltp); /* Adding Header Subtree */ ltp_header_item = proto_tree_add_text(ltp_tree, tvb, frame_offset, header_offset+1, "LTP Header"); ltp_header_tree = proto_item_add_subtree(ltp_header_item, ett_ltp_hdr); proto_tree_add_uint(ltp_header_tree,hf_ltp_version,tvb,frame_offset,1,hi_nibble(ltp_hdr)); ltp_type = lo_nibble(ltp_hdr); proto_tree_add_uint_format_value(ltp_header_tree,hf_ltp_type,tvb,frame_offset,1,ltp_type,"%x (%s)", ltp_type,val_to_str(ltp_type,ltp_type_codes,"Invalid")); frame_offset++; /* Adding the session id subtree */ ltp_session_item = proto_tree_add_item(ltp_header_item,hf_ltp_session_id,tvb,frame_offset, engine_id_size + session_num_size,ENC_NA); ltp_session_tree = proto_item_add_subtree(ltp_session_item,ett_hdr_session); proto_tree_add_uint64(ltp_session_tree,hf_ltp_session_orig,tvb,frame_offset,engine_id_size,engine_id); frame_offset+=engine_id_size; proto_tree_add_uint64(ltp_session_tree,hf_ltp_session_no, tvb, frame_offset,session_num_size,session_num); frame_offset+=session_num_size; /* Adding Extension count to the header tree */ ltp_extn_cnt = tvb_get_guint8(tvb,frame_offset); hdr_extn_cnt = hi_nibble(ltp_extn_cnt); trl_extn_cnt = lo_nibble(ltp_extn_cnt); proto_tree_add_uint(ltp_header_tree,hf_ltp_hdr_extn_cnt,tvb,frame_offset,1,hdr_extn_cnt); proto_tree_add_uint(ltp_header_tree,hf_ltp_trl_extn_cnt,tvb,frame_offset,1,trl_extn_cnt); frame_offset++; col_add_str(pinfo->cinfo, COL_INFO, val_to_str_const(ltp_type,ltp_type_col_info,"Protocol Error")); if((unsigned)frame_offset >= tvb_length(tvb)){ col_set_str(pinfo->cinfo, COL_INFO, "Protocol Error"); return 0; } /* Check if there are any header extensions */ if(hdr_extn_cnt > 0){ hdr_extn_offset = dissect_header_extn(ltp_tree, tvb, frame_offset,hdr_extn_cnt); if(hdr_extn_offset == 0){ col_set_str(pinfo->cinfo, COL_INFO, "Protocol Error"); return 0; } frame_offset += hdr_extn_offset; } if((unsigned)frame_offset >= tvb_length(tvb)){ col_set_str(pinfo->cinfo, COL_INFO, "Protocol Error"); return 0; } /* Call sub routines to handle the segment content*/ if((ltp_type >= 0) && (ltp_type < 8)){ segment_offset = dissect_data_segment(ltp_tree,tvb,pinfo,frame_offset,ltp_type,session_num); if(segment_offset == 0){ col_set_str(pinfo->cinfo, COL_INFO, "Protocol Error"); return 0; } } else if(ltp_type == 8){ segment_offset = dissect_report_segment(tvb, pinfo, ltp_tree,frame_offset); if(segment_offset == 0){ col_set_str(pinfo->cinfo, COL_INFO, "Protocol Error"); return 0; } } else if(ltp_type == 9){ segment_offset = dissect_report_ack_segment(ltp_tree,tvb,frame_offset); if(segment_offset == 0){ col_set_str(pinfo->cinfo, COL_INFO, "Protocol Error"); return 0; } } else if(ltp_type == 12 || ltp_type == 14){ segment_offset = dissect_cancel_segment(ltp_tree,tvb,frame_offset); if(segment_offset == 0){ col_set_str(pinfo->cinfo, COL_INFO, "Protocol Error"); return 0; } } frame_offset += segment_offset; /* Check to see if there are any trailer extensions */ if(trl_extn_cnt > 0){ if((unsigned)frame_offset >= tvb_length(tvb)){ col_set_str(pinfo->cinfo, COL_INFO, "Protocol Error"); return 0; } trl_extn_offset = dissect_trailer_extn(ltp_tree, tvb, frame_offset,trl_extn_cnt); if(trl_extn_offset == 0){ col_set_str(pinfo->cinfo, COL_INFO, "Protocol Error"); return 0; } } /* Return the amount of data this dissector was able to dissect */ return tvb_length(tvb); }
/* Turn SYMBOLS into a string suitable for appending onto a URL. This means that we encode special characters, and write name value pairs into a new string. A newly allocated string is returned. */ char * forms_unparse_items (Symbol **symbols) { register int i; char *result = (char *)NULL; int result_index = 0; int result_size = 0; Symbol *symbol; if (symbols == (Symbol **)NULL) return ((char *)NULL); for (i = 0; (symbol = symbols[i]) != (Symbol *)NULL; i++) { register int j; char *name = symbol_full_name (symbol); int name_len = strlen (name); for (j = 0; j < symbol->values_index; j++) { register int from, to, c; char *pair; pair = (char *)xmalloc (1 + (3 * (name_len + strlen (symbol->values[j])))); for (from = 0, to = 0; (c = (name[from])) != '\0'; from++) { if ((isalnum (c)) || (strchr (".-_@:", c) != (char *)NULL)) pair[to++] = c; else if (c == ' ') pair[to++] = '+'; else { pair[to++] = '%'; pair[to++] = hi_nibble (c); pair[to++] = lo_nibble (c); } } pair[to++] = '='; for (from = 0; (c = symbol->values[j][from]) != '\0'; from++) { if ((isalnum (c)) || (strchr (".-_@:", c) != (char *)NULL)) pair[to++] = c; else if (c == ' ') pair[to++] = '+'; else { pair[to++] = '%'; pair[to++] = hi_nibble (c); pair[to++] = lo_nibble (c); } } pair[to] = '\0'; /* Add this pair to our string. */ if ((result_index + strlen (pair) + 2) > result_size) result = (char *)xrealloc (result, (result_size += 100 + strlen (pair))); /* If there is already a pair present, separate it from this one with an ampersand. */ if (result_index != 0) result[result_index++] = '&'; strcpy (result + result_index, pair); result_index += strlen (pair); result[result_index] = '\0'; free (pair); } free (name); } return (result); }
guint offset = 0; /* Set up structures needed to add the protocol subtree and manage it */ proto_item *ti; proto_tree *alc_tree; tvbuff_t *new_tvb; /* Make entries in Protocol column and Info column on summary display */ col_set_str(pinfo->cinfo, COL_PROTOCOL, "ALC"); col_clear(pinfo->cinfo, COL_INFO); /* ALC header dissection */ /* --------------------- */ version = hi_nibble(tvb_get_guint8(tvb, offset)); /* Create subtree for the ALC protocol */ ti = proto_tree_add_item(tree, proto_rmt_alc, tvb, offset, -1, ENC_NA); alc_tree = proto_item_add_subtree(ti, ett_main); /* Fill the ALC subtree */ ti = proto_tree_add_uint(alc_tree, hf_version, tvb, offset, 1, version); /* This dissector supports only ALCv1 packets. * If version > 1 print only version field and quit. */ if (version != 1) { expert_add_info(pinfo, ti, &ei_version1_only); /* Complete entry in Info column on summary display */
static void dissect_alc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { /* Logical packet representation */ struct _alc alc; /* Offset for subpacket dissection */ guint offset; /* Set up structures needed to add the protocol subtree and manage it */ proto_item *ti; proto_tree *alc_tree; /* Flute or not */ tvbuff_t *new_tvb; gboolean is_flute = FALSE; /* Structures and variables initialization */ offset = 0; memset(&alc, 0, sizeof(struct _alc)); /* Update packet info */ pinfo->current_proto = "ALC"; /* Make entries in Protocol column and Info column on summary display */ col_set_str(pinfo->cinfo, COL_PROTOCOL, "ALC"); col_clear(pinfo->cinfo, COL_INFO); /* ALC header dissection */ /* --------------------- */ alc.version = hi_nibble(tvb_get_guint8(tvb, offset)); if (tree) { /* Create subtree for the ALC protocol */ ti = proto_tree_add_item(tree, proto, tvb, offset, -1, ENC_NA); alc_tree = proto_item_add_subtree(ti, ett.main); /* Fill the ALC subtree */ proto_tree_add_uint(alc_tree, hf.version, tvb, offset, 1, alc.version); } else alc_tree = NULL; /* This dissector supports only ALCv1 packets. * If alc.version > 1 print only version field and quit. */ if (alc.version == 1) { struct _lct_ptr l; struct _fec_ptr f; l.lct = &alc.lct; l.hf = &hf.lct; l.ett = &ett.lct; l.prefs = &preferences.lct; f.fec = &alc.fec; f.hf = &hf.fec; f.ett = &ett.fec; f.prefs = &preferences.fec; /* LCT header dissection */ /* --------------------- */ is_flute = lct_dissector(l, f, tvb, alc_tree, &offset); /* FEC header dissection */ /* --------------------- */ /* Only if it's present and if LCT dissector has determined FEC Encoding ID * FEC dissector should be called with fec->encoding_id* and fec->instance_id* filled */ if (alc.fec.encoding_id_present && tvb_length(tvb) > offset) fec_dissector(f, tvb, alc_tree, &offset); /* Add the Payload item */ if (tvb_length(tvb) > offset){ if(is_flute){ new_tvb = tvb_new_subset_remaining(tvb,offset); call_dissector(xml_handle, new_tvb, pinfo, alc_tree); }else{ proto_tree_add_none_format(alc_tree, hf.payload, tvb, offset, -1, "Payload (%u bytes)", tvb_length(tvb) - offset); } } /* Complete entry in Info column on summary display */ /* ------------------------------------------------ */ if (check_col(pinfo->cinfo, COL_INFO)) { lct_info_column(&alc.lct, pinfo); fec_info_column(&alc.fec, pinfo); } /* Free g_allocated memory */ lct_dissector_free(&alc.lct); fec_dissector_free(&alc.fec); } else { if (tree) proto_tree_add_text(alc_tree, tvb, 0, -1, "Sorry, this dissector supports ALC version 1 only"); /* Complete entry in Info column on summary display */ if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "Version: %u (not supported)", alc.version); } }
vec_t cksum_vec[4]; guint32 phdr[2]; gboolean is_ipv6; proto_item *ti, *tv, *hidden_item, *checksum_item; proto_tree *vrrp_tree, *ver_type_tree; guint8 priority, addr_count = 0, auth_type = VRRP_AUTH_TYPE_NONE; guint16 cksum, computed_cksum; is_ipv6 = (pinfo->src.type == AT_IPv6); col_set_str(pinfo->cinfo, COL_PROTOCOL, "VRRP"); col_clear(pinfo->cinfo, COL_INFO); ver_type = tvb_get_guint8(tvb, 0); col_add_fstr(pinfo->cinfo, COL_INFO, "Announcement (v%u)", hi_nibble(ver_type)); ti = proto_tree_add_item(tree, proto_vrrp, tvb, 0, -1, ENC_NA); vrrp_tree = proto_item_add_subtree(ti, ett_vrrp); priority = tvb_get_guint8(tvb, 2); addr_count = tvb_get_guint8(tvb, 3); tv = proto_tree_add_uint_format(vrrp_tree, hf_vrrp_ver_type, tvb, offset, 1, ver_type, "Version %u, Packet type %u (%s)", hi_nibble(ver_type), lo_nibble(ver_type), val_to_str_const(lo_nibble(ver_type), vrrp_type_vals, "Unknown")); ver_type_tree = proto_item_add_subtree(tv, ett_vrrp_ver_type); if(ver_type_tree){
static void display_xip_serval(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *xip_serval_tree; proto_item *ti, *check_ti, *hl_ti; tvbuff_t *next_tvb; vec_t cksum_vec; gint offset; guint16 packet_checksum, actual_checksum; guint8 xsh_len, protocol, bytes_remaining; /* Get XIP Serval header length, stored as number of 32-bit words. */ xsh_len = tvb_get_guint8(tvb, XSRVL_LEN) << 2; /* Create XIP Serval header tree. */ ti = proto_tree_add_item(tree, proto_xip_serval, tvb, 0, xsh_len, ENC_NA); xip_serval_tree = proto_item_add_subtree(ti, ett_xip_serval_tree); /* Add XIP Serval header length. */ hl_ti = proto_tree_add_item(xip_serval_tree, hf_xip_serval_hl, tvb, XSRVL_LEN, 1, ENC_BIG_ENDIAN); proto_item_append_text(hl_ti, " bytes"); if (tvb_captured_length(tvb) < xsh_len) expert_add_info_format(pinfo, hl_ti, &ei_xip_serval_bad_len, "Header Length field (%d bytes) cannot be greater than actual number of bytes left in packet (%d bytes)", xsh_len, tvb_captured_length(tvb)); /* Add XIP Serval protocol. If it's not data, TCP, or UDP, the * packet is malformed. */ proto_tree_add_item(xip_serval_tree, hf_xip_serval_proto, tvb, XSRVL_PRO, 1, ENC_BIG_ENDIAN); protocol = tvb_get_guint8(tvb, XSRVL_PRO); if (!try_val_to_str(protocol, xip_serval_proto_vals)) expert_add_info_format(pinfo, ti, &ei_xip_serval_bad_proto, "Unrecognized protocol type: %d", protocol); /* Compute checksum. */ SET_CKSUM_VEC_TVB(cksum_vec, tvb, 0, xsh_len); actual_checksum = in_cksum(&cksum_vec, 1); /* Get XIP Serval checksum. */ packet_checksum = tvb_get_ntohs(tvb, XSRVL_CHK); if (actual_checksum == 0) { /* Add XIP Serval checksum as correct. */ proto_tree_add_uint_format(xip_serval_tree, hf_xip_serval_check, tvb, XSRVL_CHK, 2, packet_checksum, "Header checksum: 0x%04x [correct]", packet_checksum); } else { /* Add XIP Serval checksum as incorrect. */ check_ti = proto_tree_add_uint_format(xip_serval_tree, hf_xip_serval_check, tvb, XSRVL_CHK, 2, packet_checksum, "Header checksum: 0x%04x [incorrect, should be 0x%04x]", packet_checksum, in_cksum_shouldbe(packet_checksum, actual_checksum)); expert_add_info_format(pinfo, check_ti, &ei_xip_serval_bad_checksum, "Bad checksum"); } offset = XSRVL_EXT; /* If there's still more room, check for extension headers. */ bytes_remaining = xsh_len - offset; while (bytes_remaining >= XIP_SERVAL_EXT_MIN_LEN) { gint8 bytes_displayed = display_xip_serval_ext(tvb, pinfo, ti, xip_serval_tree, offset); /* Extension headers are malformed, so we can't say * what the rest of the packet holds. Stop dissecting. */ if (bytes_displayed <= 0) return; offset += bytes_displayed; bytes_remaining -= bytes_displayed; } switch (protocol) { case XIP_SERVAL_PROTO_DATA: next_tvb = tvb_new_subset_remaining(tvb, offset); call_dissector(data_handle, next_tvb, pinfo, tree); break; case IP_PROTO_TCP: { /* Get the Data Offset field of the TCP header, which is * the high nibble of the 12th octet and represents the * size of the TCP header of 32-bit words. */ guint8 tcp_len = hi_nibble(tvb_get_guint8(tvb, offset + 12))*4; next_tvb = tvb_new_subset(tvb, offset, tcp_len, tcp_len); call_dissector(tcp_handle, next_tvb, pinfo, tree); break; } case IP_PROTO_UDP: /* The UDP header is always 8 bytes. */ next_tvb = tvb_new_subset(tvb, offset, 8, 8); call_dissector(udp_handle, next_tvb, pinfo, tree); break; default: break; } }
{ return (val & 0xF0) >> 4; } static inline uint8_t lo_nibble(uint8_t val) { return val & 0x0F; } uint8_t PreMods__compare(const PreMods *this, uint8_t mods) { uint8_t count = 0; uint8_t lo_mods = lo_nibble(mods); uint8_t hi_mods = hi_nibble(mods); uint8_t lo_std = lo_nibble(this->std); uint8_t hi_std = hi_nibble(this->std); count += bitcount[lo_mods&lo_std]; count += bitcount[hi_mods&hi_std]; count += bitcount[((lo_mods&~lo_std)|(hi_mods&~hi_std))&lo_nibble(this->any)]; return count; } bool PreMods__is_empty(const PreMods *this) { return this->std == NONE && this->any == NONE; } /*