Ejemplo n.º 1
0
static void
dissect_ntp_std(tvbuff_t *tvb, proto_tree *ntp_tree, guint8 flags)
{
	proto_tree      *flags_tree;
	proto_item	*tf;
	guint8		stratum;
	guint8		ppoll;
	gint8		precision;
	double		rootdelay;
	double		rootdispersion;
	const guint8	*refid;
	guint32		refid_addr;
	const guint8	*reftime;
	const guint8	*org;
	const guint8	*rec;
	const guint8	*xmt;
	const gchar	*buffc;
	gchar		*buff;
	int		i;
	int		macofs;
	gint            maclen;

	tf = proto_tree_add_uint(ntp_tree, hf_ntp_flags, tvb, 0, 1, flags);

	/* Adding flag subtree and items */
	flags_tree = proto_item_add_subtree(tf, ett_ntp_flags);
	proto_tree_add_uint(flags_tree, hf_ntp_flags_li, tvb, 0, 1, flags);
	proto_tree_add_uint(flags_tree, hf_ntp_flags_vn, tvb, 0, 1, flags);
	proto_tree_add_uint(flags_tree, hf_ntp_flags_mode, tvb, 0, 1, flags);

	/* Stratum, 1byte field represents distance from primary source
	 */
	stratum = tvb_get_guint8(tvb, 1);
	if (stratum == 0) {
		buffc="Peer Clock Stratum: unspecified or unavailable (%u)";
	} else if (stratum == 1) {
		buffc="Peer Clock Stratum: primary reference (%u)";
	} else if ((stratum >= 2) && (stratum <= 15)) {
		buffc="Peer Clock Stratum: secondary reference (%u)";
	} else {
		buffc="Peer Clock Stratum: reserved: %u";
	}
	proto_tree_add_uint_format(ntp_tree, hf_ntp_stratum, tvb, 1, 1,
				   stratum, buffc, stratum);
	/* Poll interval, 1byte field indicating the maximum interval
	 * between successive messages, in seconds to the nearest
	 * power of two.
	 */
	ppoll = tvb_get_guint8(tvb, 2);
	if ((ppoll >= 4) && (ppoll <= 17)) {
		proto_tree_add_uint_format(ntp_tree, hf_ntp_ppoll, tvb, 2, 1,
				   ppoll, 
				   "Peer Polling Interval: %u (%u sec)",
				   ppoll,
				   1 << ppoll);
	} else {
		proto_tree_add_uint_format(ntp_tree, hf_ntp_ppoll, tvb, 2, 1,
				   ppoll,
				   "Peer Polling Interval: invalid (%u)",
				   ppoll);
	}
	
	/* Precision, 1byte field indicating the precision of the
	 * local clock, in seconds to the nearest power of two.
	 */
	precision = tvb_get_guint8(tvb, 3);
	proto_tree_add_int_format(ntp_tree, hf_ntp_precision, tvb, 3, 1,
				   precision,
				   "Peer Clock Precision: %8.6f sec",
				   pow(2, precision));

	/* Root Delay is a 32-bit signed fixed-point number indicating
	 * the total roundtrip delay to the primary reference source,
	 * in seconds with fraction point between bits 15 and 16.
	 */
	rootdelay = ((gint16)tvb_get_ntohs(tvb, 4)) +
			(tvb_get_ntohs(tvb, 6) / 65536.0);
	proto_tree_add_double_format(ntp_tree, hf_ntp_rootdelay, tvb, 4, 4,
				   rootdelay,
				   "Root Delay: %9.4f sec",
				   rootdelay);

	/* Root Dispersion, 32-bit unsigned fixed-point number indicating
	 * the nominal error relative to the primary reference source, in
	 * seconds with fraction point between bits 15 and 16.
	 */
	rootdispersion = ((gint16)tvb_get_ntohs(tvb, 8)) +
				(tvb_get_ntohs(tvb, 10) / 65536.0);
	proto_tree_add_double_format(ntp_tree, hf_ntp_rootdispersion, tvb, 8, 4,
				   rootdispersion,
				   "Root Dispersion: %9.4f sec",
				   rootdispersion);

	/* Now, there is a problem with secondary servers.  Standards
	 * asks from stratum-2 - stratum-15 servers to set this to the
	 * low order 32 bits of the latest transmit timestamp of the
	 * reference source.
	 * But, all V3 and V4 servers set this to IP adress of their
	 * higher level server. My decision was to resolve this address.
	 */
	refid = tvb_get_ptr(tvb, 12, 4);
	buff = ep_alloc(NTP_TS_SIZE);
	if (stratum <= 1) {
		g_snprintf (buff, NTP_TS_SIZE, "Unidentified reference source '%.4s'",
			refid);
		for (i = 0; primary_sources[i].id; i++) {
			if (memcmp (refid, primary_sources[i].id, 4) == 0) {
				g_snprintf(buff, NTP_TS_SIZE, "%s",
					primary_sources[i].data);
				break;
			}
		}
	} else {
		int buffpos;
		refid_addr = tvb_get_ipv4(tvb, 12);
		buffpos = g_snprintf(buff, NTP_TS_SIZE, "%s", get_hostname (refid_addr));
		if (buffpos >= NTP_TS_SIZE) {
			buff[NTP_TS_SIZE-4]='.';
			buff[NTP_TS_SIZE-3]='.';
			buff[NTP_TS_SIZE-2]='.';
			buff[NTP_TS_SIZE-1]=0;
		}
	}
	proto_tree_add_bytes_format(ntp_tree, hf_ntp_refid, tvb, 12, 4,
				   refid,
				   "Reference Clock ID: %s", buff);

	/* Reference Timestamp: This is the time at which the local clock was
	 * last set or corrected.
	 */
	reftime = tvb_get_ptr(tvb, 16, 8);
	proto_tree_add_bytes_format(ntp_tree, hf_ntp_reftime, tvb, 16, 8,
				   reftime,
			           "Reference Clock Update Time: %s",
				   ntp_fmt_ts(reftime));

	/* Originate Timestamp: This is the time at which the request departed
	 * the client for the server.
	 */
	org = tvb_get_ptr(tvb, 24, 8);
	proto_tree_add_bytes_format(ntp_tree, hf_ntp_org, tvb, 24, 8,
				   org,
			           "Originate Time Stamp: %s",
				   ntp_fmt_ts(org));

	/* Receive Timestamp: This is the time at which the request arrived at
	 * the server.
	 */
	rec = tvb_get_ptr(tvb, 32, 8);
	proto_tree_add_bytes_format(ntp_tree, hf_ntp_rec, tvb, 32, 8,
				   rec,
			           "Receive Time Stamp: %s",
				   ntp_fmt_ts(rec));

	/* Transmit Timestamp: This is the time at which the reply departed the
	 * server for the client.
	 */
	xmt = tvb_get_ptr(tvb, 40, 8);
	proto_tree_add_bytes_format(ntp_tree, hf_ntp_xmt, tvb, 40, 8,
				   xmt,
			           "Transmit Time Stamp: %s",
				   ntp_fmt_ts(xmt));

	/* MAX_MAC_LEN is the largest message authentication code
	 * (MAC) length.  If we have more data left in the packet
	 * after the header than that, the extra data is NTP4
	 * extensions; parse them as such.
	 */
	macofs = 48;
	while (tvb_reported_length_remaining(tvb, macofs) > (gint)MAX_MAC_LEN)
		macofs = dissect_ntp_ext(tvb, ntp_tree, macofs);

	/* When the NTP authentication scheme is implemented, the
	 * Key Identifier and Message Digest fields contain the
	 * message authentication code (MAC) information defined in
	 * Appendix C of RFC-1305. Will print this as hex code for now.
	 */
	if (tvb_reported_length_remaining(tvb, macofs) >= 4)
		proto_tree_add_item(ntp_tree, hf_ntp_keyid, tvb, macofs, 4,
				    FALSE);
	macofs += 4;
	maclen = tvb_reported_length_remaining(tvb, macofs);
	if (maclen > 0)
		proto_tree_add_item(ntp_tree, hf_ntp_mac, tvb, macofs,
				    maclen, FALSE);
}
Ejemplo n.º 2
0
/* Code to actually dissect the packets */
static void
dissect_mip( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
  /* Set up structures we will need to add the protocol subtree and manage it */
  proto_item	*ti;
  proto_tree	*mip_tree=NULL;
  proto_item    *tf;
  proto_tree    *flags_tree;
  guint8         type;
  guint16        flags;
  gint           offset=0;
  const guint8  *reftime;
  tvbuff_t      *next_tvb;

  /* Make entries in Protocol column and Info column on summary display */

  col_set_str(pinfo->cinfo, COL_PROTOCOL, "MobileIP");
  col_clear(pinfo->cinfo, COL_INFO);

  type = tvb_get_guint8(tvb, offset);
  switch (type) {
  case MIP_REGISTRATION_REQUEST:
	col_add_fstr(pinfo->cinfo, COL_INFO,
		       "Reg Request: HoA=%s HA=%s CoA=%s",
		       ip_to_str(tvb_get_ptr(tvb,4,4)),
		       ip_to_str(tvb_get_ptr(tvb,8,4)),
		       ip_to_str(tvb_get_ptr(tvb,12,4)));

	if (tree) {
	  ti = proto_tree_add_item(tree, proto_mip, tvb, offset, -1, FALSE);
	  mip_tree = proto_item_add_subtree(ti, ett_mip);

	  /* type */
	  proto_tree_add_uint(mip_tree, hf_mip_type, tvb, offset, 1, type);
	  offset++;

	  /* flags */
	  flags = tvb_get_guint8(tvb, offset);
	  tf = proto_tree_add_uint(mip_tree, hf_mip_flags, tvb, offset, 1, flags);
	  flags_tree = proto_item_add_subtree(tf, ett_mip_flags);
	  proto_tree_add_boolean(flags_tree, hf_mip_s, tvb, offset, 1, flags);
	  proto_tree_add_boolean(flags_tree, hf_mip_b, tvb, offset, 1, flags);
	  proto_tree_add_boolean(flags_tree, hf_mip_d, tvb, offset, 1, flags);
	  proto_tree_add_boolean(flags_tree, hf_mip_m, tvb, offset, 1, flags);
	  proto_tree_add_boolean(flags_tree, hf_mip_g, tvb, offset, 1, flags);
	  proto_tree_add_boolean(flags_tree, hf_mip_v, tvb, offset, 1, flags);
	  proto_tree_add_boolean(flags_tree, hf_mip_t, tvb, offset, 1, flags);
	  proto_tree_add_boolean(flags_tree, hf_mip_x, tvb, offset, 1, flags);
	  offset++;

	  /* lifetime */
	  proto_tree_add_item(mip_tree, hf_mip_life, tvb, offset, 2, FALSE);
	  offset += 2;

	  /* home address */
	  proto_tree_add_item(mip_tree, hf_mip_homeaddr, tvb, offset, 4, FALSE);
	  offset += 4;

	  /* home agent address */
	  proto_tree_add_item(mip_tree, hf_mip_haaddr, tvb, offset, 4, FALSE);
	  offset += 4;

	  /* Care of Address */
	  proto_tree_add_item(mip_tree, hf_mip_coa, tvb, offset, 4, FALSE);
	  offset += 4;

	  /* Identifier - assumed to be an NTP time here */
	  reftime = tvb_get_ptr(tvb, offset, 8);
	  proto_tree_add_bytes_format(mip_tree, hf_mip_ident, tvb, offset, 8,
				      reftime,
				      "Identification: %s",
				      ntp_fmt_ts(reftime));
	  offset += 8;

	} /* if tree */
	break;
  case MIP_REGISTRATION_REPLY:
	col_add_fstr(pinfo->cinfo, COL_INFO,
		       "Reg Reply: HoA=%s HA=%s, Code=%u",
		       ip_to_str(tvb_get_ptr(tvb,4,4)), 
		       ip_to_str(tvb_get_ptr(tvb,8,4)), 
		       tvb_get_guint8(tvb,1));

	if (tree) {
	  /* Add Subtree */
	  ti = proto_tree_add_item(tree, proto_mip, tvb, offset, -1, FALSE);
	  mip_tree = proto_item_add_subtree(ti, ett_mip);

	  /* Type */
  	  proto_tree_add_uint(mip_tree, hf_mip_type, tvb, offset, 1, type);
	  offset++;

	  /* Reply Code */
	  proto_tree_add_item(mip_tree, hf_mip_code, tvb, offset, 1, FALSE);
	  offset++;

	  /* Registration Lifetime */
	  proto_tree_add_item(mip_tree, hf_mip_life, tvb, offset, 2, FALSE);
	  offset += 2;

	  /* Home address */
	  proto_tree_add_item(mip_tree, hf_mip_homeaddr, tvb, offset, 4, FALSE);
	  offset += 4;

	  /* Home Agent Address */
	  proto_tree_add_item(mip_tree, hf_mip_haaddr, tvb, offset, 4, FALSE);
	  offset += 4;

	  /* Identifier - assumed to be an NTP time here */
	  reftime = tvb_get_ptr(tvb, offset, 8);
	  proto_tree_add_bytes_format(mip_tree, hf_mip_ident, tvb, offset, 8,
				      reftime,
				      "Identification: %s",
				      ntp_fmt_ts(reftime));
	  offset += 8;
	} /* if tree */
	break;
  case MIP_NATT_TUNNEL_DATA:
	col_add_fstr(pinfo->cinfo, COL_INFO, "Tunnel Data: Next Header=%u",
		       tvb_get_guint8(tvb,1));

	if (tree) {
	  /* Add Subtree */
	  ti = proto_tree_add_item(tree, proto_mip, tvb, offset, -1, FALSE);
	  mip_tree = proto_item_add_subtree(ti, ett_mip);

	  /* Type */
  	  proto_tree_add_uint(mip_tree, hf_mip_type, tvb, offset, 1, type);
	  offset++;

	  /* Next Header */
	  proto_tree_add_item(mip_tree, hf_mip_nattt_nexthdr, tvb, offset, 1, FALSE);
	  offset++;

	  /* reserved */
	  proto_tree_add_item(mip_tree, hf_mip_nattt_reserved, tvb, offset, 2, FALSE);
	  offset += 2;
	} /* if tree */
	else {
	  offset += 4;
	}
	/* encapsulated payload */
	next_tvb = tvb_new_subset_remaining(tvb, 4);
	call_dissector(ip_handle, next_tvb, pinfo, mip_tree);
	offset += tvb_reported_length_remaining(tvb, offset);
	break;
  case MIP_REGISTRATION_REVOCATION:
	col_add_fstr(pinfo->cinfo, COL_INFO,
		       "Reg Revocation: HoA=%s HDA=%s FDA=%s",
		       ip_to_str(tvb_get_ptr(tvb,4,4)),
		       ip_to_str(tvb_get_ptr(tvb,8,4)),
		       ip_to_str(tvb_get_ptr(tvb,12,4)));

	if (tree) {
	  ti = proto_tree_add_item(tree, proto_mip, tvb, offset, -1, FALSE);
	  mip_tree = proto_item_add_subtree(ti, ett_mip);

	  /* type */
	  proto_tree_add_uint(mip_tree, hf_mip_type, tvb, offset, 1, type);
	  offset++;

	  /* reserved */
	  proto_tree_add_item(mip_tree, hf_mip_rev_reserved, tvb, offset, 1, FALSE);
	  offset++;

	  /* flags */
	  flags = tvb_get_ntohs(tvb, offset);
	  tf = proto_tree_add_uint(mip_tree, hf_mip_flags, tvb, offset, 2, flags);
	  flags_tree = proto_item_add_subtree(tf, ett_mip_flags);
	  proto_tree_add_boolean(flags_tree, hf_mip_rev_a, tvb, offset, 2, flags);
	  proto_tree_add_boolean(flags_tree, hf_mip_rev_i, tvb, offset, 2, flags);

	  /* reserved */
	  proto_tree_add_uint(flags_tree, hf_mip_rev_reserved, tvb, offset, 2, flags);
	  offset += 2;

	  /* home address */
	  proto_tree_add_item(mip_tree, hf_mip_homeaddr, tvb, offset, 4, FALSE);
	  offset += 4;

	  /* home domain address */
	  proto_tree_add_item(mip_tree, hf_mip_hda, tvb, offset, 4, FALSE);
	  offset += 4;

	  /* foreign domain address */
	  proto_tree_add_item(mip_tree, hf_mip_fda, tvb, offset, 4, FALSE);
	  offset += 4;

	  /* revocation identifier */
	  proto_tree_add_item(mip_tree, hf_mip_revid, tvb, offset, 4, FALSE);
	  offset += 4;
	} /* if tree */
	break;
  case MIP_REGISTRATION_REVOCATION_ACK:
	  col_add_fstr(pinfo->cinfo, COL_INFO, "Reg Revocation Ack: HoA=%s",
		       ip_to_str(tvb_get_ptr(tvb,4,4)));

	if (tree) {
	  ti = proto_tree_add_item(tree, proto_mip, tvb, offset, -1, FALSE);
	  mip_tree = proto_item_add_subtree(ti, ett_mip);

	  /* type */
	  proto_tree_add_uint(mip_tree, hf_mip_type, tvb, offset, 1, type);
	  offset++;

	  /* reserved */
	  proto_tree_add_item(mip_tree, hf_mip_ack_reserved, tvb, offset, 1, FALSE);
	  offset++;

	  /* flags */
	  flags = tvb_get_ntohs(tvb, offset);
	  tf = proto_tree_add_uint(mip_tree, hf_mip_flags, tvb, offset, 2, flags);
	  flags_tree = proto_item_add_subtree(tf, ett_mip_flags);
	  proto_tree_add_boolean(flags_tree, hf_mip_ack_i, tvb, offset, 2, flags);

	  /* reserved */
	  proto_tree_add_uint(flags_tree, hf_mip_ack_reserved, tvb, offset, 2, flags);
	  offset += 2;

	  /* home address */
	  proto_tree_add_item(mip_tree, hf_mip_homeaddr, tvb, offset, 4, FALSE);
	  offset += 4;

	  /* revocation identifier */
	  proto_tree_add_item(mip_tree, hf_mip_revid, tvb, offset, 4, FALSE);
	  offset += 4;
	} /* if tree */
	break;
  } /* End switch */

  if (tree) {
	if (tvb_reported_length_remaining(tvb, offset) > 0)
	  dissect_mip_extensions(tvb, offset, mip_tree);
  }
} /* dissect_mip */