示例#1
0
static int
print_neighbors2(netdissect_options *ndo,
                 register const u_char *bp, register const u_char *ep,
                 register u_int len)
{
	const u_char *laddr;
	register u_char metric, thresh, flags;
	register int ncount;

	ND_PRINT((ndo, " (v %d.%d):",
	       (int)target_level & 0xff,
	       (int)(target_level >> 8) & 0xff));

	while (len > 0 && bp < ep) {
		ND_TCHECK2(bp[0], 8);
		laddr = bp;
		bp += 4;
		metric = *bp++;
		thresh = *bp++;
		flags = *bp++;
		ncount = *bp++;
		len -= 8;
		while (--ncount >= 0 && (len >= 4) && (bp + 4) <= ep) {
			ND_PRINT((ndo, " [%s -> ", ipaddr_string(ndo, laddr)));
			ND_PRINT((ndo, "%s (%d/%d", ipaddr_string(ndo, bp),
				     metric, thresh));
			if (flags & DVMRP_NF_TUNNEL)
				ND_PRINT((ndo, "/tunnel"));
			if (flags & DVMRP_NF_SRCRT)
				ND_PRINT((ndo, "/srcrt"));
			if (flags & DVMRP_NF_QUERIER)
				ND_PRINT((ndo, "/querier"));
			if (flags & DVMRP_NF_DISABLED)
				ND_PRINT((ndo, "/disabled"));
			if (flags & DVMRP_NF_DOWN)
				ND_PRINT((ndo, "/down"));
			ND_PRINT((ndo, ")]"));
			bp += 4;
			len -= 4;
		}
		if (ncount != -1) {
			ND_PRINT((ndo, " [|]"));
			return (0);
		}
	}
	return (0);
trunc:
	return (-1);
}
示例#2
0
static int
ospf6_print_lsaprefix(netdissect_options *ndo,
                      const uint8_t *tptr, u_int lsa_length)
{
	const struct lsa6_prefix *lsapp = (const struct lsa6_prefix *)tptr;
	u_int wordlen;
	struct in6_addr prefix;

	if (lsa_length < sizeof (*lsapp) - IPV6_ADDR_LEN_BYTES)
		goto trunc;
	lsa_length -= sizeof (*lsapp) - IPV6_ADDR_LEN_BYTES;
	ND_TCHECK2(*lsapp, sizeof (*lsapp) - IPV6_ADDR_LEN_BYTES);
	wordlen = (lsapp->lsa_p_len + 31) / 32;
	if (wordlen * 4 > sizeof(struct in6_addr)) {
		ND_PRINT((ndo, " bogus prefixlen /%d", lsapp->lsa_p_len));
		goto trunc;
	}
	if (lsa_length < wordlen * 4)
		goto trunc;
	lsa_length -= wordlen * 4;
	ND_TCHECK2(lsapp->lsa_p_prefix, wordlen * 4);
	memset(&prefix, 0, sizeof(prefix));
	memcpy(&prefix, lsapp->lsa_p_prefix, wordlen * 4);
	ND_PRINT((ndo, "\n\t\t%s/%d", ip6addr_string(ndo, &prefix),
		lsapp->lsa_p_len));
        if (lsapp->lsa_p_opt) {
            ND_PRINT((ndo, ", Options [%s]",
                   bittok2str(ospf6_lsa_prefix_option_values,
                              "none", lsapp->lsa_p_opt)));
        }
        ND_PRINT((ndo, ", metric %u", EXTRACT_16BITS(&lsapp->lsa_p_metric)));
	return sizeof(*lsapp) - IPV6_ADDR_LEN_BYTES + wordlen * 4;

trunc:
	return -1;
}
示例#3
0
/*
 *     0                   1                   2                   3
 *     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 *    |          Parameter Tag        |       Parameter Length        |
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 *    \                                                               \
 *    /                       Parameter Value                         /
 *    \                                                               \
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 */
static void
m3ua_tags_print(netdissect_options *ndo,
                const u_char *buf, const u_int size)
{
  const u_char *p = buf;
  int align;
  uint16_t hdr_tag;
  uint16_t hdr_len;

  while (p < buf + size) {
    if (p + sizeof(struct m3ua_param_header) > buf + size)
      goto corrupt;
    ND_TCHECK2(*p, sizeof(struct m3ua_param_header));
    /* Parameter Tag */
    hdr_tag = EXTRACT_16BITS(p);
    ND_PRINT((ndo, "\n\t\t\t%s: ", tok2str(ParamName, "Unknown Parameter (0x%04x)", hdr_tag)));
    /* Parameter Length */
    hdr_len = EXTRACT_16BITS(p + 2);
    if (hdr_len < sizeof(struct m3ua_param_header))
      goto corrupt;
    /* Parameter Value */
    align = (p + hdr_len - buf) % 4;
    align = align ? 4 - align : 0;
    ND_TCHECK2(*p, hdr_len + align);
    tag_value_print(ndo, p, hdr_tag, hdr_len - sizeof(struct m3ua_param_header));
    p += hdr_len + align;
  }
  return;

corrupt:
  ND_PRINT((ndo, "%s", cstr));
  ND_TCHECK2(*buf, size);
  return;
trunc:
  ND_PRINT((ndo, "%s", tstr));
}
示例#4
0
/* cp points to the Ver/Flags octet */
static void
aoev1_print(netdissect_options *ndo,
            const u_char *cp, const u_int len)
{
	const u_char *ep = cp + len;
	uint8_t flags, command;
	void (*cmd_decoder)(netdissect_options *, const u_char *, const u_int);

	if (len < AOEV1_COMMON_HDR_LEN)
		goto invalid;
	/* Flags */
	flags = *cp & 0x0F;
	ND_PRINT((ndo, ", Flags: [%s]", bittok2str(aoev1_flag_str, "none", flags)));
	cp += 1;
	if (! ndo->ndo_vflag)
		return;
	/* Error */
	ND_TCHECK2(*cp, 1);
	if (flags & AOEV1_FLAG_E)
		ND_PRINT((ndo, "\n\tError: %s", tok2str(aoev1_errcode_str, "Invalid (%u)", *cp)));
	cp += 1;
	/* Major */
	ND_TCHECK2(*cp, 2);
	ND_PRINT((ndo, "\n\tMajor: 0x%04x", EXTRACT_16BITS(cp)));
	cp += 2;
	/* Minor */
	ND_TCHECK2(*cp, 1);
	ND_PRINT((ndo, ", Minor: 0x%02x", *cp));
	cp += 1;
	/* Command */
	ND_TCHECK2(*cp, 1);
	command = *cp;
	cp += 1;
	ND_PRINT((ndo, ", Command: %s", tok2str(cmdcode_str, "Unknown (0x%02x)", command)));
	/* Tag */
	ND_TCHECK2(*cp, 4);
	ND_PRINT((ndo, ", Tag: 0x%08x", EXTRACT_32BITS(cp)));
	cp += 4;
	/* Arg */
	cmd_decoder =
		command == AOEV1_CMD_ISSUE_ATA_COMMAND        ? aoev1_issue_print :
		command == AOEV1_CMD_QUERY_CONFIG_INFORMATION ? aoev1_query_print :
		command == AOEV1_CMD_MAC_MASK_LIST            ? aoev1_mac_print :
		command == AOEV1_CMD_RESERVE_RELEASE          ? aoev1_reserve_print :
		NULL;
	if (cmd_decoder != NULL)
		cmd_decoder(ndo, cp, len - AOEV1_COMMON_HDR_LEN);
	return;

invalid:
	ND_PRINT((ndo, "%s", istr));
	ND_TCHECK2(*cp, ep - cp);
	return;
trunc:
	ND_PRINT((ndo, "%s", tstr));
}
示例#5
0
static void
loopback_message_print(netdissect_options *ndo, const u_char *cp, const u_int len)
{
	const u_char *ep = cp + len;
	uint16_t function;

	if (len < 2)
		goto corrupt;
	/* function */
	ND_TCHECK2(*cp, 2);
	function = EXTRACT_LE_16BITS(cp);
	cp += 2;
	ND_PRINT((ndo, ", %s", tok2str(fcode_str, " invalid (%u)", function)));

	switch (function) {
		case LOOPBACK_REPLY:
			if (len < 4)
				goto corrupt;
			/* receipt number */
			ND_TCHECK2(*cp, 2);
			ND_PRINT((ndo, ", receipt number %u", EXTRACT_LE_16BITS(cp)));
			cp += 2;
			/* data */
			ND_PRINT((ndo, ", data (%u octets)", len - 4));
			ND_TCHECK2(*cp, len - 4);
			break;
		case LOOPBACK_FWDDATA:
			if (len < 8)
				goto corrupt;
			/* forwarding address */
			ND_TCHECK2(*cp, ETHER_ADDR_LEN);
			ND_PRINT((ndo, ", forwarding address %s", etheraddr_string(cp)));
			cp += ETHER_ADDR_LEN;
			/* data */
			ND_PRINT((ndo, ", data (%u octets)", len - 8));
			ND_TCHECK2(*cp, len - 8);
			break;
		default:
			ND_TCHECK2(*cp, len - 2);
			break;
	}
	return;

corrupt:
	ND_PRINT((ndo, "%s", cstr));
	ND_TCHECK2(*cp, ep - cp);
	return;
trunc:
	ND_PRINT((ndo, "%s", tstr));
}
示例#6
0
void
radius_print(netdissect_options *ndo,
             const u_char *dat, u_int length)
{
   register const struct radius_hdr *rad;
   u_int len, auth_idx;

   ND_TCHECK2(*dat, MIN_RADIUS_LEN);
   rad = (struct radius_hdr *)dat;
   len = EXTRACT_16BITS(&rad->len);

   if (len < MIN_RADIUS_LEN)
   {
	  ND_PRINT((ndo, "%s", tstr));
	  return;
   }

   if (len > length)
	  len = length;

   if (ndo->ndo_vflag < 1) {
       ND_PRINT((ndo, "RADIUS, %s (%u), id: 0x%02x length: %u",
              tok2str(radius_command_values,"Unknown Command",rad->code),
              rad->code,
              rad->id,
              len));
       return;
   }
   else {
       ND_PRINT((ndo, "RADIUS, length: %u\n\t%s (%u), id: 0x%02x, Authenticator: ",
              len,
              tok2str(radius_command_values,"Unknown Command",rad->code),
              rad->code,
              rad->id));

       for(auth_idx=0; auth_idx < 16; auth_idx++)
            ND_PRINT((ndo, "%02x", rad->auth[auth_idx]));
   }

   if (len > MIN_RADIUS_LEN)
      radius_attrs_print(ndo, dat + MIN_RADIUS_LEN, len - MIN_RADIUS_LEN);
   return;

trunc:
   ND_PRINT((ndo, "%s", tstr));
}
示例#7
0
static void
aoev1_query_print(netdissect_options *ndo,
                  const u_char *cp, const u_int len)
{
	const u_char *ep = cp + len;
	uint16_t cslen;

	if (len < AOEV1_QUERY_ARG_LEN)
		goto invalid;
	/* Buffer Count */
	ND_TCHECK2(*cp, 2);
	ND_PRINT((ndo, "\n\tBuffer Count: %u", EXTRACT_16BITS(cp)));
	cp += 2;
	/* Firmware Version */
	ND_TCHECK2(*cp, 2);
	ND_PRINT((ndo, ", Firmware Version: %u", EXTRACT_16BITS(cp)));
	cp += 2;
	/* Sector Count */
	ND_TCHECK2(*cp, 1);
	ND_PRINT((ndo, ", Sector Count: %u", *cp));
	cp += 1;
	/* AoE/CCmd */
	ND_TCHECK2(*cp, 1);
	ND_PRINT((ndo, ", AoE: %u, CCmd: %s", (*cp & 0xF0) >> 4,
	          tok2str(aoev1_ccmd_str, "Unknown (0x02x)", *cp & 0x0F)));
	cp += 1;
	/* Config String Length */
	ND_TCHECK2(*cp, 2);
	cslen = EXTRACT_16BITS(cp);
	cp += 2;
	if (cslen > AOEV1_MAX_CONFSTR_LEN || AOEV1_QUERY_ARG_LEN + cslen > len)
		goto invalid;
	/* Config String */
	ND_TCHECK2(*cp, cslen);
	if (cslen) {
		ND_PRINT((ndo, "\n\tConfig String (length %u): ", cslen));
		if (fn_printn(ndo, cp, cslen, ndo->ndo_snapend))
			goto trunc;
	}
	return;

invalid:
	ND_PRINT((ndo, "%s", istr));
	ND_TCHECK2(*cp, ep - cp);
	return;
trunc:
	ND_PRINT((ndo, "%s", tstr));
}
示例#8
0
/* Print a single OpenFlow message. */
static const u_char *
of_header_body_print(netdissect_options *ndo, const u_char *cp, const u_char *ep)
{
	uint8_t version, type;
	uint16_t length;
	uint32_t xid;

	if (ep < cp + OF_HEADER_LEN)
		goto invalid;
	/* version */
	ND_TCHECK2(*cp, 1);
	version = *cp;
	cp += 1;
	/* type */
	ND_TCHECK2(*cp, 1);
	type = *cp;
	cp += 1;
	/* length */
	ND_TCHECK2(*cp, 2);
	length = EXTRACT_16BITS(cp);
	cp += 2;
	/* xid */
	ND_TCHECK2(*cp, 4);
	xid = EXTRACT_32BITS(cp);
	cp += 4;
	/* Message length includes the header length and a message always includes
	 * the basic header. A message length underrun fails decoding of the rest of
	 * the current packet. At the same time, try decoding as much of the current
	 * message as possible even when it does not end within the current TCP
	 * segment. */
	if (length < OF_HEADER_LEN) {
		of_header_print(ndo, version, type, length, xid);
		goto invalid;
	}
	/* Decode known protocol versions further without printing the header (the
	 * type decoding is version-specific. */
	switch (version) {
	case OF_VER_1_0:
		return of10_header_body_print(ndo, cp, ep, type, length, xid);
	default:
		of_header_print(ndo, version, type, length, xid);
		ND_TCHECK2(*cp, length - OF_HEADER_LEN);
		return cp + length - OF_HEADER_LEN; /* done with current message */
	}

invalid: /* fail current packet */
	ND_PRINT((ndo, "%s", istr));
	ND_TCHECK2(*cp, ep - cp);
	return ep;
trunc:
	ND_PRINT((ndo, "%s", tstr));
	return ep;
}
示例#9
0
/*
 * Pre operation attributes. Print only if vflag > 1.
 */
static const uint32_t *
parse_pre_op_attr(netdissect_options *ndo,
                  const uint32_t *dp, int verbose)
{
	ND_TCHECK(dp[0]);
	if (!EXTRACT_32BITS(&dp[0]))
		return (dp + 1);
	dp++;
	ND_TCHECK2(*dp, 24);
	if (verbose > 1) {
		return parse_wcc_attr(ndo, dp);
	} else {
		/* If not verbose enough, just skip over wcc_attr */
		return (dp + 6);
	}
trunc:
	return (NULL);
}
示例#10
0
int
hbhopt_print(netdissect_options *ndo, register const u_char *bp)
{
    const struct ip6_hbh *dp = (const struct ip6_hbh *)bp;
    int hbhlen = 0;

    ND_TCHECK(dp->ip6h_len);
    hbhlen = (int)((dp->ip6h_len + 1) << 3);
    ND_TCHECK2(*dp, hbhlen);
    ND_PRINT((ndo, "HBH "));
    if (ndo->ndo_vflag)
	ip6_opt_print(ndo, (const u_char *)dp + sizeof(*dp), hbhlen - sizeof(*dp));

    return(hbhlen);

  trunc:
    ND_PRINT((ndo, "[|HBH]"));
    return(-1);
}
示例#11
0
/* RFC6506 Section 4.1 */
static int
ospf6_decode_at(netdissect_options *ndo,
                const u_char *cp, const u_int len)
{
	uint16_t authdatalen;

	if (len == 0)
		return 0;
	if (len < OSPF6_AT_HDRLEN)
		goto trunc;
	/* Authentication Type */
	ND_TCHECK2(*cp, 2);
	ND_PRINT((ndo, "\n\tAuthentication Type %s", tok2str(ospf6_auth_type_str, "unknown (0x%04x)", EXTRACT_16BITS(cp))));
	cp += 2;
	/* Auth Data Len */
	ND_TCHECK2(*cp, 2);
	authdatalen = EXTRACT_16BITS(cp);
	ND_PRINT((ndo, ", Length %u", authdatalen));
	if (authdatalen < OSPF6_AT_HDRLEN || authdatalen > len)
		goto trunc;
	cp += 2;
	/* Reserved */
	ND_TCHECK2(*cp, 2);
	cp += 2;
	/* Security Association ID */
	ND_TCHECK2(*cp, 2);
	ND_PRINT((ndo, ", SAID %u", EXTRACT_16BITS(cp)));
	cp += 2;
	/* Cryptographic Sequence Number (High-Order 32 Bits) */
	ND_TCHECK2(*cp, 4);
	ND_PRINT((ndo, ", CSN 0x%08x", EXTRACT_32BITS(cp)));
	cp += 4;
	/* Cryptographic Sequence Number (Low-Order 32 Bits) */
	ND_TCHECK2(*cp, 4);
	ND_PRINT((ndo, ":%08x", EXTRACT_32BITS(cp)));
	cp += 4;
	/* Authentication Data */
	ND_TCHECK2(*cp, authdatalen - OSPF6_AT_HDRLEN);
	if (ndo->ndo_vflag > 1)
		print_unknown_data(ndo,cp, "\n\tAuthentication Data ", authdatalen - OSPF6_AT_HDRLEN);
	return 0;

trunc:
	return 1;
}
示例#12
0
static const u_char *
zmtp1_print_intermediate_part(netdissect_options *ndo, const u_char *cp, const u_int len) {
	u_int frame_offset;
	uint64_t remaining_len;

	ND_TCHECK2(*cp, 2);
	frame_offset = EXTRACT_16BITS(cp);
	ND_PRINT((ndo, "\n\t frame offset 0x%04x", frame_offset));
	cp += 2;
	remaining_len = ndo->ndo_snapend - cp; /* without the frame length */

	if (frame_offset == 0xFFFF)
		frame_offset = len - 2; /* always within the declared length */
	else if (2 + frame_offset > len) {
		ND_PRINT((ndo, " (exceeds datagram declared length)"));
		goto trunc;
	}

	/* offset within declared length of the datagram */
	if (frame_offset) {
		ND_PRINT((ndo, "\n\t frame intermediate part, %u bytes", frame_offset));
		if (frame_offset > remaining_len)
			ND_PRINT((ndo, " (%"PRIu64" captured)", remaining_len));
		if (ndo->ndo_vflag) {
			uint64_t len_printed = min(frame_offset, remaining_len);

			if (ndo->ndo_vflag == 1)
				len_printed = min(VBYTES, len_printed);
			if (len_printed > 1) {
				ND_PRINT((ndo, ", first %"PRIu64" byte(s):", len_printed));
				hex_and_ascii_print(ndo, "\n\t ", cp, len_printed);
				ND_PRINT((ndo, "\n"));
			}
		}
	}
	return cp + frame_offset;

trunc:
	ND_PRINT((ndo, "%s", tstr));
	return cp + len;
}
示例#13
0
int
dstopt_print(netdissect_options *ndo, register const u_char *bp)
{
    const struct ip6_dest *dp = (const struct ip6_dest *)bp;
    int dstoptlen = 0;

    ND_TCHECK(dp->ip6d_len);
    dstoptlen = (int)((dp->ip6d_len + 1) << 3);
    ND_TCHECK2(*dp, dstoptlen);
    ND_PRINT((ndo, "DSTOPT "));
    if (ndo->ndo_vflag) {
	ip6_opt_print(ndo, (const u_char *)dp + sizeof(*dp),
	    dstoptlen - sizeof(*dp));
    }

    return(dstoptlen);

  trunc:
    ND_PRINT((ndo, "[|DSTOPT]"));
    return(-1);
}
示例#14
0
/*
 *     0                   1                   2                   3
 *     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 *    |    Version    |   Reserved    | Message Class | Message Type  |
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 *    |                        Message Length                         |
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 *    \                                                               \
 *    /                                                               /
 */
void
m3ua_print(netdissect_options *ndo,
           const u_char *buf, const u_int size)
{
  const struct m3ua_common_header *hdr = (const struct m3ua_common_header *) buf;
  const struct tok *dict;

  /* size includes the header */
  if (size < sizeof(struct m3ua_common_header))
    goto corrupt;
  ND_TCHECK(*hdr);
  if (hdr->v != M3UA_REL_1_0)
    return;

  dict =
    hdr->msg_class == M3UA_MSGC_MGMT     ? MgmtMessages :
    hdr->msg_class == M3UA_MSGC_TRANSFER ? TransferMessages :
    hdr->msg_class == M3UA_MSGC_SSNM     ? SS7Messages :
    hdr->msg_class == M3UA_MSGC_ASPSM    ? ASPStateMessages :
    hdr->msg_class == M3UA_MSGC_ASPTM    ? ASPTrafficMessages :
    hdr->msg_class == M3UA_MSGC_RKM      ? RoutingKeyMgmtMessages :
    NULL;

  ND_PRINT((ndo, "\n\t\t%s", tok2str(MessageClasses, "Unknown message class %i", hdr->msg_class)));
  if (dict != NULL)
    ND_PRINT((ndo, " %s Message", tok2str(dict, "Unknown (0x%02x)", hdr->msg_type)));

  if (size != EXTRACT_32BITS(&hdr->len))
    ND_PRINT((ndo, "\n\t\t\t@@@@@@ Corrupted length %u of message @@@@@@", EXTRACT_32BITS(&hdr->len)));
  else
    m3ua_tags_print(ndo, buf + sizeof(struct m3ua_common_header), EXTRACT_32BITS(&hdr->len) - sizeof(struct m3ua_common_header));
  return;

corrupt:
  ND_PRINT((ndo, "%s", cstr));
  ND_TCHECK2(*buf, size);
  return;
trunc:
  ND_PRINT((ndo, "%s", tstr));
}
static int
lwres_printaddr(netdissect_options *ndo,
                lwres_addr_t *ap)
{
	uint16_t l;
	const char *p;
	int i;

	ND_TCHECK(ap->length);
	l = EXTRACT_16BITS(&ap->length);
	/* XXX ap points to packed struct */
	p = (const char *)&ap->length + sizeof(ap->length);
	ND_TCHECK2(*p, l);

	switch (EXTRACT_32BITS(&ap->family)) {
	case 1:	/* IPv4 */
		if (l < 4)
			return -1;
		ND_PRINT((ndo, " %s", ipaddr_string(ndo, p)));
		p += sizeof(struct in_addr);
		break;
#ifdef INET6
	case 2:	/* IPv6 */
		if (l < 16)
			return -1;
		ND_PRINT((ndo, " %s", ip6addr_string(ndo, p)));
		p += sizeof(struct in6_addr);
		break;
#endif
	default:
		ND_PRINT((ndo, " %u/", EXTRACT_32BITS(&ap->family)));
		for (i = 0; i < l; i++)
			ND_PRINT((ndo, "%02x", *p++));
	}

	return p - (const char *)ap;

  trunc:
	return -1;
}
示例#16
0
static int
resp_print_string_error_integer(netdissect_options *ndo, register const u_char *bp, int length) {
    int length_cur = length, len, ret_len = 0;
    const u_char *bp_ptr = bp;

    /*
     * MOVE_FORWARD moves past the string that follows the (+-;) opcodes
     * +OK\r\n
     * -ERR ...\r\n
     * :02912309\r\n
     */
    MOVE_FORWARD(bp_ptr, length_cur);
    len = (bp_ptr - bp);
    ND_TCHECK2(*bp, len);
    RESP_PRINT_SEGMENT(ndo, bp+1, len-1);
    ret_len = len /*<1byte>+<string>*/ + 2 /*<CRLF>*/;

    TEST_RET_LEN(ret_len);

trunc:
    return (-1);
}
示例#17
0
static void
trans2_qfsinfo(netdissect_options *ndo,
               const u_char *param, const u_char *data, int pcnt, int dcnt)
{
    static int level = 0;
    const char *fmt="";

    if (request) {
	ND_TCHECK2(*param, 2);
	level = EXTRACT_LE_16BITS(param);
	fmt = "InfoLevel=[d]\n";
	smb_fdata(ndo, param, fmt, param + pcnt, unicodestr);
    } else {
	switch (level) {
	case 1:
	    fmt = "idFileSystem=[W]\nSectorUnit=[D]\nUnit=[D]\nAvail=[D]\nSectorSize=[d]\n";
	    break;
	case 2:
	    fmt = "CreationTime=[T2]VolNameLength=[lb]\nVolumeLabel=[c]\n";
	    break;
	case 0x105:
	    fmt = "Capabilities=[W]\nMaxFileLen=[D]\nVolNameLen=[lD]\nVolume=[C]\n";
	    break;
	default:
	    fmt = "UnknownLevel\n";
	    break;
	}
	smb_fdata(ndo, data, fmt, data + dcnt, unicodestr);
    }
    if (dcnt) {
	ND_PRINT((ndo, "data:\n"));
	smb_print_data(ndo, data, dcnt);
    }
    return;
trunc:
    ND_PRINT((ndo, "%s", tstr));
}
示例#18
0
/*
 * Print out a file name and return pointer to 32-bit word past it.
 * If packet was truncated, return 0.
 */
static const uint32_t *
parsefn(netdissect_options *ndo,
        register const uint32_t *dp)
{
	register uint32_t len;
	register const u_char *cp;

	/* Bail if we don't have the string length */
	ND_TCHECK(*dp);

	/* Fetch string length; convert to host order */
	len = *dp++;
	NTOHL(len);

#ifndef CHERI_TCPDUMP_VULNERABILITY
	ND_TCHECK2(*dp, ((len + 3) & ~3));
#endif

	cp = (u_char *)dp;
	/* Update 32-bit pointer (NFS filenames padded to 32-bit boundaries) */
	dp += ((len + 3) & ~3) / sizeof(*dp);
	ND_PRINT((ndo, "\""));
#ifdef CHERI_TCPDUMP_VULNERABILITY
	(void) fn_printn(ndo, cp, len, NULL);
#else
	if (fn_printn(ndo, cp, len, ndo->ndo_snapend)) {
		ND_PRINT((ndo, "\""));
		goto trunc;
	}
#endif
	ND_PRINT((ndo, "\""));

	return (dp);
trunc:
	return NULL;
}
示例#19
0
void
vqp_print(netdissect_options *ndo, register const u_char *pptr, register u_int len)
{
    const struct vqp_common_header_t *vqp_common_header;
    const struct vqp_obj_tlv_t *vqp_obj_tlv;

    const u_char *tptr;
    uint16_t vqp_obj_len;
    uint32_t vqp_obj_type;
    u_int tlen;
    uint8_t nitems;

    tptr=pptr;
    tlen = len;
    vqp_common_header = (const struct vqp_common_header_t *)pptr;
    ND_TCHECK(*vqp_common_header);
    if (sizeof(struct vqp_common_header_t) > tlen)
        goto trunc;

    /*
     * Sanity checking of the header.
     */
    if (VQP_EXTRACT_VERSION(vqp_common_header->version) != VQP_VERSION) {
	ND_PRINT((ndo, "VQP version %u packet not supported",
               VQP_EXTRACT_VERSION(vqp_common_header->version)));
	return;
    }

    /* in non-verbose mode just lets print the basic Message Type */
    if (ndo->ndo_vflag < 1) {
        ND_PRINT((ndo, "VQPv%u %s Message, error-code %s (%u), length %u",
               VQP_EXTRACT_VERSION(vqp_common_header->version),
               tok2str(vqp_msg_type_values, "unknown (%u)",vqp_common_header->msg_type),
               tok2str(vqp_error_code_values, "unknown (%u)",vqp_common_header->error_code),
	       vqp_common_header->error_code,
               len));
        return;
    }

    /* ok they seem to want to know everything - lets fully decode it */
    nitems = vqp_common_header->nitems;
    ND_PRINT((ndo, "\n\tVQPv%u, %s Message, error-code %s (%u), seq 0x%08x, items %u, length %u",
           VQP_EXTRACT_VERSION(vqp_common_header->version),
	   tok2str(vqp_msg_type_values, "unknown (%u)",vqp_common_header->msg_type),
	   tok2str(vqp_error_code_values, "unknown (%u)",vqp_common_header->error_code),
	   vqp_common_header->error_code,
           EXTRACT_32BITS(&vqp_common_header->sequence),
           nitems,
           len));

    /* skip VQP Common header */
    tptr+=sizeof(const struct vqp_common_header_t);
    tlen-=sizeof(const struct vqp_common_header_t);

    while (nitems > 0 && tlen > 0) {

        vqp_obj_tlv = (const struct vqp_obj_tlv_t *)tptr;
        ND_TCHECK(*vqp_obj_tlv);
        if (sizeof(struct vqp_obj_tlv_t) > tlen)
            goto trunc;
        vqp_obj_type = EXTRACT_32BITS(vqp_obj_tlv->obj_type);
        vqp_obj_len = EXTRACT_16BITS(vqp_obj_tlv->obj_length);
        tptr+=sizeof(struct vqp_obj_tlv_t);
        tlen-=sizeof(struct vqp_obj_tlv_t);

        ND_PRINT((ndo, "\n\t  %s Object (0x%08x), length %u, value: ",
               tok2str(vqp_obj_values, "Unknown", vqp_obj_type),
               vqp_obj_type, vqp_obj_len));

        /* basic sanity check */
        if (vqp_obj_type == 0 || vqp_obj_len ==0) {
            return;
        }

        /* did we capture enough for fully decoding the object ? */
        ND_TCHECK2(*tptr, vqp_obj_len);
        if (vqp_obj_len > tlen)
            goto trunc;

        switch(vqp_obj_type) {
	case VQP_OBJ_IP_ADDRESS:
            if (vqp_obj_len != 4)
                goto trunc;
            ND_PRINT((ndo, "%s (0x%08x)", ipaddr_string(ndo, tptr), EXTRACT_32BITS(tptr)));
            break;
            /* those objects have similar semantics - fall through */
        case VQP_OBJ_PORT_NAME:
	case VQP_OBJ_VLAN_NAME:
	case VQP_OBJ_VTP_DOMAIN:
	case VQP_OBJ_ETHERNET_PKT:
            safeputs(ndo, tptr, vqp_obj_len);
            break;
            /* those objects have similar semantics - fall through */
	case VQP_OBJ_MAC_ADDRESS:
	case VQP_OBJ_MAC_NULL:
            if (vqp_obj_len != ETHER_ADDR_LEN)
                goto trunc;
	      ND_PRINT((ndo, "%s", etheraddr_string(ndo, tptr)));
              break;
        default:
            if (ndo->ndo_vflag <= 1)
                print_unknown_data(ndo,tptr, "\n\t    ", vqp_obj_len);
            break;
        }
	tptr += vqp_obj_len;
	tlen -= vqp_obj_len;
	nitems--;
    }
    return;
trunc:
    ND_PRINT((ndo, "\n\t[|VQP]"));
}
示例#20
0
void
eigrp_print(netdissect_options *ndo, register const u_char *pptr, register u_int len) {

    const struct eigrp_common_header *eigrp_com_header;
    const struct eigrp_tlv_header *eigrp_tlv_header;
    const u_char *tptr,*tlv_tptr;
    u_int tlen,eigrp_tlv_len,eigrp_tlv_type,tlv_tlen, byte_length, bit_length;
    uint8_t prefix[4];

    union {
        const struct eigrp_tlv_general_parm_t *eigrp_tlv_general_parm;
        const struct eigrp_tlv_sw_version_t *eigrp_tlv_sw_version;
        const struct eigrp_tlv_ip_int_t *eigrp_tlv_ip_int;
        const struct eigrp_tlv_ip_ext_t *eigrp_tlv_ip_ext;
        const struct eigrp_tlv_at_cable_setup_t *eigrp_tlv_at_cable_setup;
        const struct eigrp_tlv_at_int_t *eigrp_tlv_at_int;
        const struct eigrp_tlv_at_ext_t *eigrp_tlv_at_ext;
    } tlv_ptr;

    tptr=pptr;
    eigrp_com_header = (const struct eigrp_common_header *)pptr;
    ND_TCHECK(*eigrp_com_header);

    /*
     * Sanity checking of the header.
     */
    if (eigrp_com_header->version != EIGRP_VERSION) {
	ND_PRINT((ndo, "EIGRP version %u packet not supported",eigrp_com_header->version));
	return;
    }

    /* in non-verbose mode just lets print the basic Message Type*/
    if (ndo->ndo_vflag < 1) {
        ND_PRINT((ndo, "EIGRP %s, length: %u",
               tok2str(eigrp_opcode_values, "unknown (%u)",eigrp_com_header->opcode),
               len));
        return;
    }

    /* ok they seem to want to know everything - lets fully decode it */

    tlen=len-sizeof(struct eigrp_common_header);

    /* FIXME print other header info */
    ND_PRINT((ndo, "\n\tEIGRP v%u, opcode: %s (%u), chksum: 0x%04x, Flags: [%s]\n\tseq: 0x%08x, ack: 0x%08x, AS: %u, length: %u",
           eigrp_com_header->version,
           tok2str(eigrp_opcode_values, "unknown, type: %u",eigrp_com_header->opcode),
           eigrp_com_header->opcode,
           EXTRACT_16BITS(&eigrp_com_header->checksum),
           tok2str(eigrp_common_header_flag_values,
                   "none",
                   EXTRACT_32BITS(&eigrp_com_header->flags)),
           EXTRACT_32BITS(&eigrp_com_header->seq),
           EXTRACT_32BITS(&eigrp_com_header->ack),
           EXTRACT_32BITS(&eigrp_com_header->asn),
           tlen));

    tptr+=sizeof(const struct eigrp_common_header);

    while(tlen>0) {
        /* did we capture enough for fully decoding the object header ? */
        ND_TCHECK2(*tptr, sizeof(struct eigrp_tlv_header));

        eigrp_tlv_header = (const struct eigrp_tlv_header *)tptr;
        eigrp_tlv_len=EXTRACT_16BITS(&eigrp_tlv_header->length);
        eigrp_tlv_type=EXTRACT_16BITS(&eigrp_tlv_header->type);


        if (eigrp_tlv_len < sizeof(struct eigrp_tlv_header) ||
            eigrp_tlv_len > tlen) {
            print_unknown_data(ndo,tptr+sizeof(struct eigrp_tlv_header),"\n\t    ",tlen);
            return;
        }

        ND_PRINT((ndo, "\n\t  %s TLV (0x%04x), length: %u",
               tok2str(eigrp_tlv_values,
                       "Unknown",
                       eigrp_tlv_type),
               eigrp_tlv_type,
               eigrp_tlv_len));

        tlv_tptr=tptr+sizeof(struct eigrp_tlv_header);
        tlv_tlen=eigrp_tlv_len-sizeof(struct eigrp_tlv_header);

        /* did we capture enough for fully decoding the object ? */
        ND_TCHECK2(*tptr, eigrp_tlv_len);

        switch(eigrp_tlv_type) {

        case EIGRP_TLV_GENERAL_PARM:
            tlv_ptr.eigrp_tlv_general_parm = (const struct eigrp_tlv_general_parm_t *)tlv_tptr;

            ND_PRINT((ndo, "\n\t    holdtime: %us, k1 %u, k2 %u, k3 %u, k4 %u, k5 %u",
                   EXTRACT_16BITS(tlv_ptr.eigrp_tlv_general_parm->holdtime),
                   tlv_ptr.eigrp_tlv_general_parm->k1,
                   tlv_ptr.eigrp_tlv_general_parm->k2,
                   tlv_ptr.eigrp_tlv_general_parm->k3,
                   tlv_ptr.eigrp_tlv_general_parm->k4,
                   tlv_ptr.eigrp_tlv_general_parm->k5));
            break;

        case EIGRP_TLV_SW_VERSION:
            tlv_ptr.eigrp_tlv_sw_version = (const struct eigrp_tlv_sw_version_t *)tlv_tptr;

            ND_PRINT((ndo, "\n\t    IOS version: %u.%u, EIGRP version %u.%u",
                   tlv_ptr.eigrp_tlv_sw_version->ios_major,
                   tlv_ptr.eigrp_tlv_sw_version->ios_minor,
                   tlv_ptr.eigrp_tlv_sw_version->eigrp_major,
                   tlv_ptr.eigrp_tlv_sw_version->eigrp_minor));
            break;

        case EIGRP_TLV_IP_INT:
            tlv_ptr.eigrp_tlv_ip_int = (const struct eigrp_tlv_ip_int_t *)tlv_tptr;

            bit_length = tlv_ptr.eigrp_tlv_ip_int->plen;
            if (bit_length > 32) {
                ND_PRINT((ndo, "\n\t    illegal prefix length %u",bit_length));
                break;
            }
            byte_length = (bit_length + 7) / 8; /* variable length encoding */
            memset(prefix, 0, 4);
            memcpy(prefix,&tlv_ptr.eigrp_tlv_ip_int->destination,byte_length);

            ND_PRINT((ndo, "\n\t    IPv4 prefix: %15s/%u, nexthop: ",
                   ipaddr_string(ndo, prefix),
                   bit_length));
            if (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_ip_int->nexthop) == 0)
                ND_PRINT((ndo, "self"));
            else
                ND_PRINT((ndo, "%s",ipaddr_string(ndo, &tlv_ptr.eigrp_tlv_ip_int->nexthop)));

            ND_PRINT((ndo, "\n\t      delay %u ms, bandwidth %u Kbps, mtu %u, hop %u, reliability %u, load %u",
                   (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_ip_int->delay)/100),
                   EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_ip_int->bandwidth),
                   EXTRACT_24BITS(&tlv_ptr.eigrp_tlv_ip_int->mtu),
                   tlv_ptr.eigrp_tlv_ip_int->hopcount,
                   tlv_ptr.eigrp_tlv_ip_int->reliability,
                   tlv_ptr.eigrp_tlv_ip_int->load));
            break;

        case EIGRP_TLV_IP_EXT:
            tlv_ptr.eigrp_tlv_ip_ext = (const struct eigrp_tlv_ip_ext_t *)tlv_tptr;

            bit_length = tlv_ptr.eigrp_tlv_ip_ext->plen;
            if (bit_length > 32) {
                ND_PRINT((ndo, "\n\t    illegal prefix length %u",bit_length));
                break;
            }
            byte_length = (bit_length + 7) / 8; /* variable length encoding */
            memset(prefix, 0, 4);
            memcpy(prefix,&tlv_ptr.eigrp_tlv_ip_ext->destination,byte_length);

            ND_PRINT((ndo, "\n\t    IPv4 prefix: %15s/%u, nexthop: ",
                   ipaddr_string(ndo, prefix),
                   bit_length));
            if (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_ip_ext->nexthop) == 0)
                ND_PRINT((ndo, "self"));
            else
                ND_PRINT((ndo, "%s",ipaddr_string(ndo, &tlv_ptr.eigrp_tlv_ip_ext->nexthop)));

            ND_PRINT((ndo, "\n\t      origin-router %s, origin-as %u, origin-proto %s, flags [0x%02x], tag 0x%08x, metric %u",
                   ipaddr_string(ndo, tlv_ptr.eigrp_tlv_ip_ext->origin_router),
                   EXTRACT_32BITS(tlv_ptr.eigrp_tlv_ip_ext->origin_as),
                   tok2str(eigrp_ext_proto_id_values,"unknown",tlv_ptr.eigrp_tlv_ip_ext->proto_id),
                   tlv_ptr.eigrp_tlv_ip_ext->flags,
                   EXTRACT_32BITS(tlv_ptr.eigrp_tlv_ip_ext->tag),
                   EXTRACT_32BITS(tlv_ptr.eigrp_tlv_ip_ext->metric)));

            ND_PRINT((ndo, "\n\t      delay %u ms, bandwidth %u Kbps, mtu %u, hop %u, reliability %u, load %u",
                   (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_ip_ext->delay)/100),
                   EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_ip_ext->bandwidth),
                   EXTRACT_24BITS(&tlv_ptr.eigrp_tlv_ip_ext->mtu),
                   tlv_ptr.eigrp_tlv_ip_ext->hopcount,
                   tlv_ptr.eigrp_tlv_ip_ext->reliability,
                   tlv_ptr.eigrp_tlv_ip_ext->load));
            break;

        case EIGRP_TLV_AT_CABLE_SETUP:
            tlv_ptr.eigrp_tlv_at_cable_setup = (const struct eigrp_tlv_at_cable_setup_t *)tlv_tptr;

            ND_PRINT((ndo, "\n\t    Cable-range: %u-%u, Router-ID %u",
                   EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_cable_setup->cable_start),
                   EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_cable_setup->cable_end),
                   EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_cable_setup->router_id)));
            break;

        case EIGRP_TLV_AT_INT:
            tlv_ptr.eigrp_tlv_at_int = (const struct eigrp_tlv_at_int_t *)tlv_tptr;

            ND_PRINT((ndo, "\n\t     Cable-Range: %u-%u, nexthop: ",
                   EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_int->cable_start),
                   EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_int->cable_end)));

            if (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_int->nexthop) == 0)
                ND_PRINT((ndo, "self"));
            else
                ND_PRINT((ndo, "%u.%u",
                       EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_int->nexthop),
                       EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_int->nexthop[2])));

            ND_PRINT((ndo, "\n\t      delay %u ms, bandwidth %u Kbps, mtu %u, hop %u, reliability %u, load %u",
                   (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_int->delay)/100),
                   EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_int->bandwidth),
                   EXTRACT_24BITS(&tlv_ptr.eigrp_tlv_at_int->mtu),
                   tlv_ptr.eigrp_tlv_at_int->hopcount,
                   tlv_ptr.eigrp_tlv_at_int->reliability,
                   tlv_ptr.eigrp_tlv_at_int->load));
            break;

        case EIGRP_TLV_AT_EXT:
            tlv_ptr.eigrp_tlv_at_ext = (const struct eigrp_tlv_at_ext_t *)tlv_tptr;

            ND_PRINT((ndo, "\n\t     Cable-Range: %u-%u, nexthop: ",
                   EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_ext->cable_start),
                   EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_ext->cable_end)));

            if (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_ext->nexthop) == 0)
                ND_PRINT((ndo, "self"));
            else
                ND_PRINT((ndo, "%u.%u",
                       EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_ext->nexthop),
                       EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_ext->nexthop[2])));

            ND_PRINT((ndo, "\n\t      origin-router %u, origin-as %u, origin-proto %s, flags [0x%02x], tag 0x%08x, metric %u",
                   EXTRACT_32BITS(tlv_ptr.eigrp_tlv_at_ext->origin_router),
                   EXTRACT_32BITS(tlv_ptr.eigrp_tlv_at_ext->origin_as),
                   tok2str(eigrp_ext_proto_id_values,"unknown",tlv_ptr.eigrp_tlv_at_ext->proto_id),
                   tlv_ptr.eigrp_tlv_at_ext->flags,
                   EXTRACT_32BITS(tlv_ptr.eigrp_tlv_at_ext->tag),
                   EXTRACT_16BITS(tlv_ptr.eigrp_tlv_at_ext->metric)));

            ND_PRINT((ndo, "\n\t      delay %u ms, bandwidth %u Kbps, mtu %u, hop %u, reliability %u, load %u",
                   (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_ext->delay)/100),
                   EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_ext->bandwidth),
                   EXTRACT_24BITS(&tlv_ptr.eigrp_tlv_at_ext->mtu),
                   tlv_ptr.eigrp_tlv_at_ext->hopcount,
                   tlv_ptr.eigrp_tlv_at_ext->reliability,
                   tlv_ptr.eigrp_tlv_at_ext->load));
            break;

            /*
             * FIXME those are the defined TLVs that lack a decoder
             * you are welcome to contribute code ;-)
             */

        case EIGRP_TLV_AUTH:
        case EIGRP_TLV_SEQ:
        case EIGRP_TLV_MCAST_SEQ:
        case EIGRP_TLV_IPX_INT:
        case EIGRP_TLV_IPX_EXT:

        default:
            if (ndo->ndo_vflag <= 1)
                print_unknown_data(ndo,tlv_tptr,"\n\t    ",tlv_tlen);
            break;
        }
        /* do we want to see an additionally hexdump ? */
        if (ndo->ndo_vflag > 1)
            print_unknown_data(ndo,tptr+sizeof(struct eigrp_tlv_header),"\n\t    ",
                               eigrp_tlv_len-sizeof(struct eigrp_tlv_header));

        tptr+=eigrp_tlv_len;
        tlen-=eigrp_tlv_len;
    }
    return;
trunc:
    ND_PRINT((ndo, "\n\t\t packet exceeded snapshot"));
}
示例#21
0
static int
ldp_pdu_print(netdissect_options *ndo,
              register const u_char *pptr)
{
    const struct ldp_common_header *ldp_com_header;
    const struct ldp_msg_header *ldp_msg_header;
    const u_char *tptr,*msg_tptr;
    u_short tlen;
    u_short pdu_len,msg_len,msg_type,msg_tlen;
    int hexdump,processed;

    ldp_com_header = (const struct ldp_common_header *)pptr;
    ND_TCHECK(*ldp_com_header);

    /*
     * Sanity checking of the header.
     */
    if (EXTRACT_16BITS(&ldp_com_header->version) != LDP_VERSION) {
	ND_PRINT((ndo, "%sLDP version %u packet not supported",
               (ndo->ndo_vflag < 1) ? "" : "\n\t",
               EXTRACT_16BITS(&ldp_com_header->version)));
	return 0;
    }

    pdu_len = EXTRACT_16BITS(&ldp_com_header->pdu_length);
    if (pdu_len < sizeof(const struct ldp_common_header)-4) {
        /* length too short */
        ND_PRINT((ndo, "%sLDP, pdu-length: %u (too short, < %u)",
               (ndo->ndo_vflag < 1) ? "" : "\n\t",
               pdu_len,
               (u_int)(sizeof(const struct ldp_common_header)-4)));
        return 0;
    }

    /* print the LSR-ID, label-space & length */
    ND_PRINT((ndo, "%sLDP, Label-Space-ID: %s:%u, pdu-length: %u",
           (ndo->ndo_vflag < 1) ? "" : "\n\t",
           ipaddr_string(ndo, &ldp_com_header->lsr_id),
           EXTRACT_16BITS(&ldp_com_header->label_space),
           pdu_len));

    /* bail out if non-verbose */
    if (ndo->ndo_vflag < 1)
        return 0;

    /* ok they seem to want to know everything - lets fully decode it */
    tptr = pptr + sizeof(const struct ldp_common_header);
    tlen = pdu_len - (sizeof(const struct ldp_common_header)-4);	/* Type & Length fields not included */

    while(tlen>0) {
        /* did we capture enough for fully decoding the msg header ? */
        ND_TCHECK2(*tptr, sizeof(struct ldp_msg_header));

        ldp_msg_header = (const struct ldp_msg_header *)tptr;
        msg_len=EXTRACT_16BITS(ldp_msg_header->length);
        msg_type=LDP_MASK_MSG_TYPE(EXTRACT_16BITS(ldp_msg_header->type));

        if (msg_len < sizeof(struct ldp_msg_header)-4) {
            /* length too short */
            /* FIXME vendor private / experimental check */
            ND_PRINT((ndo, "\n\t  %s Message (0x%04x), length: %u (too short, < %u)",
                   tok2str(ldp_msg_values,
                           "Unknown",
                           msg_type),
                   msg_type,
                   msg_len,
                   (u_int)(sizeof(struct ldp_msg_header)-4)));
            return 0;
        }

        /* FIXME vendor private / experimental check */
        ND_PRINT((ndo, "\n\t  %s Message (0x%04x), length: %u, Message ID: 0x%08x, Flags: [%s if unknown]",
               tok2str(ldp_msg_values,
                       "Unknown",
                       msg_type),
               msg_type,
               msg_len,
               EXTRACT_32BITS(&ldp_msg_header->id),
               LDP_MASK_U_BIT(EXTRACT_16BITS(&ldp_msg_header->type)) ? "continue processing" : "ignore"));

        msg_tptr=tptr+sizeof(struct ldp_msg_header);
        msg_tlen=msg_len-(sizeof(struct ldp_msg_header)-4); /* Type & Length fields not included */

        /* did we capture enough for fully decoding the message ? */
        ND_TCHECK2(*tptr, msg_len);
        hexdump=FALSE;

        switch(msg_type) {

        case LDP_MSG_NOTIF:
        case LDP_MSG_HELLO:
        case LDP_MSG_INIT:
        case LDP_MSG_KEEPALIVE:
        case LDP_MSG_ADDRESS:
        case LDP_MSG_LABEL_MAPPING:
        case LDP_MSG_ADDRESS_WITHDRAW:
        case LDP_MSG_LABEL_WITHDRAW:
            while(msg_tlen >= 4) {
                processed = ldp_tlv_print(ndo, msg_tptr, msg_tlen);
                if (processed == 0)
                    break;
                msg_tlen-=processed;
                msg_tptr+=processed;
            }
            break;

        /*
         *  FIXME those are the defined messages that lack a decoder
         *  you are welcome to contribute code ;-)
         */

        case LDP_MSG_LABEL_REQUEST:
        case LDP_MSG_LABEL_RELEASE:
        case LDP_MSG_LABEL_ABORT_REQUEST:

        default:
            if (ndo->ndo_vflag <= 1)
                print_unknown_data(ndo, msg_tptr, "\n\t  ", msg_tlen);
            break;
        }
        /* do we want to see an additionally hexdump ? */
        if (ndo->ndo_vflag > 1 || hexdump==TRUE)
            print_unknown_data(ndo, tptr+sizeof(struct ldp_msg_header), "\n\t  ",
                               msg_len);

        tptr += msg_len+4;
        tlen -= msg_len+4;
    }
    return pdu_len+4;
trunc:
    ND_PRINT((ndo, "\n\t\t packet exceeded snapshot"));
    return 0;
}
示例#22
0
static int
ldp_tlv_print(netdissect_options *ndo,
              register const u_char *tptr,
              u_short msg_tlen)
{
    struct ldp_tlv_header {
        uint8_t type[2];
        uint8_t length[2];
    };

    const struct ldp_tlv_header *ldp_tlv_header;
    u_short tlv_type,tlv_len,tlv_tlen,af,ft_flags;
    u_char fec_type;
    u_int ui,vc_info_len, vc_info_tlv_type, vc_info_tlv_len,idx;
    char buf[100];
    int i;

    ldp_tlv_header = (const struct ldp_tlv_header *)tptr;
    ND_TCHECK(*ldp_tlv_header);
    tlv_len=EXTRACT_16BITS(ldp_tlv_header->length);
    if (tlv_len + 4 > msg_tlen) {
        ND_PRINT((ndo, "\n\t\t TLV contents go past end of message"));
        return 0;
    }
    tlv_tlen=tlv_len;
    tlv_type=LDP_MASK_TLV_TYPE(EXTRACT_16BITS(ldp_tlv_header->type));

    /* FIXME vendor private / experimental check */
    ND_PRINT((ndo, "\n\t    %s TLV (0x%04x), length: %u, Flags: [%s and %s forward if unknown]",
           tok2str(ldp_tlv_values,
                   "Unknown",
                   tlv_type),
           tlv_type,
           tlv_len,
           LDP_MASK_U_BIT(EXTRACT_16BITS(&ldp_tlv_header->type)) ? "continue processing" : "ignore",
           LDP_MASK_F_BIT(EXTRACT_16BITS(&ldp_tlv_header->type)) ? "do" : "don't"));

    tptr+=sizeof(struct ldp_tlv_header);

    switch(tlv_type) {

    case LDP_TLV_COMMON_HELLO:
        TLV_TCHECK(4);
        ND_PRINT((ndo, "\n\t      Hold Time: %us, Flags: [%s Hello%s]",
               EXTRACT_16BITS(tptr),
               (EXTRACT_16BITS(tptr+2)&0x8000) ? "Targeted" : "Link",
               (EXTRACT_16BITS(tptr+2)&0x4000) ? ", Request for targeted Hellos" : ""));
        break;

    case LDP_TLV_IPV4_TRANSPORT_ADDR:
        TLV_TCHECK(4);
        ND_PRINT((ndo, "\n\t      IPv4 Transport Address: %s", ipaddr_string(ndo, tptr)));
        break;
    case LDP_TLV_IPV6_TRANSPORT_ADDR:
        TLV_TCHECK(16);
        ND_PRINT((ndo, "\n\t      IPv6 Transport Address: %s", ip6addr_string(ndo, tptr)));
        break;
    case LDP_TLV_CONFIG_SEQ_NUMBER:
        TLV_TCHECK(4);
        ND_PRINT((ndo, "\n\t      Sequence Number: %u", EXTRACT_32BITS(tptr)));
        break;

    case LDP_TLV_ADDRESS_LIST:
        TLV_TCHECK(LDP_TLV_ADDRESS_LIST_AFNUM_LEN);
	af = EXTRACT_16BITS(tptr);
	tptr+=LDP_TLV_ADDRESS_LIST_AFNUM_LEN;
        tlv_tlen -= LDP_TLV_ADDRESS_LIST_AFNUM_LEN;
	ND_PRINT((ndo, "\n\t      Address Family: %s, addresses",
               tok2str(af_values, "Unknown (%u)", af)));
        switch (af) {
        case AFNUM_INET:
	    while(tlv_tlen >= sizeof(struct in_addr)) {
		ND_TCHECK2(*tptr, sizeof(struct in_addr));
		ND_PRINT((ndo, " %s", ipaddr_string(ndo, tptr)));
		tlv_tlen-=sizeof(struct in_addr);
		tptr+=sizeof(struct in_addr);
	    }
            break;
        case AFNUM_INET6:
	    while(tlv_tlen >= sizeof(struct in6_addr)) {
		ND_TCHECK2(*tptr, sizeof(struct in6_addr));
		ND_PRINT((ndo, " %s", ip6addr_string(ndo, tptr)));
		tlv_tlen-=sizeof(struct in6_addr);
		tptr+=sizeof(struct in6_addr);
	    }
            break;
        default:
            /* unknown AF */
            break;
        }
	break;

    case LDP_TLV_COMMON_SESSION:
	TLV_TCHECK(8);
	ND_PRINT((ndo, "\n\t      Version: %u, Keepalive: %us, Flags: [Downstream %s, Loop Detection %s]",
	       EXTRACT_16BITS(tptr), EXTRACT_16BITS(tptr+2),
	       (EXTRACT_16BITS(tptr+6)&0x8000) ? "On Demand" : "Unsolicited",
	       (EXTRACT_16BITS(tptr+6)&0x4000) ? "Enabled" : "Disabled"
	       ));
	break;

    case LDP_TLV_FEC:
        TLV_TCHECK(1);
        fec_type = *tptr;
	ND_PRINT((ndo, "\n\t      %s FEC (0x%02x)",
	       tok2str(ldp_fec_values, "Unknown", fec_type),
	       fec_type));

	tptr+=1;
	tlv_tlen-=1;
	switch(fec_type) {

	case LDP_FEC_WILDCARD:
	    break;
	case LDP_FEC_PREFIX:
	    TLV_TCHECK(2);
	    af = EXTRACT_16BITS(tptr);
	    tptr+=LDP_TLV_ADDRESS_LIST_AFNUM_LEN;
	    tlv_tlen-=LDP_TLV_ADDRESS_LIST_AFNUM_LEN;
	    if (af == AFNUM_INET) {
		i=decode_prefix4(ndo, tptr, tlv_tlen, buf, sizeof(buf));
		if (i == -2)
		    goto trunc;
		if (i == -3)
		    ND_PRINT((ndo, ": IPv4 prefix (goes past end of TLV)"));
		else if (i == -1)
		    ND_PRINT((ndo, ": IPv4 prefix (invalid length)"));
		else
		    ND_PRINT((ndo, ": IPv4 prefix %s", buf));
	    }
	    else if (af == AFNUM_INET6) {
		i=decode_prefix6(ndo, tptr, tlv_tlen, buf, sizeof(buf));
		if (i == -2)
		    goto trunc;
		if (i == -3)
		    ND_PRINT((ndo, ": IPv4 prefix (goes past end of TLV)"));
		else if (i == -1)
		    ND_PRINT((ndo, ": IPv6 prefix (invalid length)"));
		else
		    ND_PRINT((ndo, ": IPv6 prefix %s", buf));
	    }
	    else
		ND_PRINT((ndo, ": Address family %u prefix", af));
	    break;
	case LDP_FEC_HOSTADDRESS:
	    break;
	case LDP_FEC_MARTINI_VC:
            /*
	     * According to RFC 4908, the VC info Length field can be zero,
	     * in which case not only are there no interface parameters,
	     * there's no VC ID.
	     */
            TLV_TCHECK(7);
            vc_info_len = *(tptr+2);

            if (vc_info_len == 0) {
                ND_PRINT((ndo, ": %s, %scontrol word, group-ID %u, VC-info-length: %u",
                       tok2str(l2vpn_encaps_values, "Unknown", EXTRACT_16BITS(tptr)&0x7fff),
                       EXTRACT_16BITS(tptr)&0x8000 ? "" : "no ",
                       EXTRACT_32BITS(tptr+3),
                       vc_info_len));
                break;
            }

            /* Make sure we have the VC ID as well */
            TLV_TCHECK(11);
	    ND_PRINT((ndo, ": %s, %scontrol word, group-ID %u, VC-ID %u, VC-info-length: %u",
		   tok2str(l2vpn_encaps_values, "Unknown", EXTRACT_16BITS(tptr)&0x7fff),
		   EXTRACT_16BITS(tptr)&0x8000 ? "" : "no ",
                   EXTRACT_32BITS(tptr+3),
		   EXTRACT_32BITS(tptr+7),
                   vc_info_len));
            if (vc_info_len < 4) {
                /* minimum 4, for the VC ID */
                ND_PRINT((ndo, " (invalid, < 4"));
                return(tlv_len+4); /* Type & Length fields not included */
	    }
            vc_info_len -= 4; /* subtract out the VC ID, giving the length of the interface parameters */

            /* Skip past the fixed information and the VC ID */
            tptr+=11;
            tlv_tlen-=11;
            TLV_TCHECK(vc_info_len);

            while (vc_info_len > 2) {
                vc_info_tlv_type = *tptr;
                vc_info_tlv_len = *(tptr+1);
                if (vc_info_tlv_len < 2)
                    break;
                if (vc_info_len < vc_info_tlv_len)
                    break;

                ND_PRINT((ndo, "\n\t\tInterface Parameter: %s (0x%02x), len %u",
                       tok2str(ldp_fec_martini_ifparm_values,"Unknown",vc_info_tlv_type),
                       vc_info_tlv_type,
                       vc_info_tlv_len));

                switch(vc_info_tlv_type) {
                case LDP_FEC_MARTINI_IFPARM_MTU:
                    ND_PRINT((ndo, ": %u", EXTRACT_16BITS(tptr+2)));
                    break;

                case LDP_FEC_MARTINI_IFPARM_DESC:
                    ND_PRINT((ndo, ": "));
                    for (idx = 2; idx < vc_info_tlv_len; idx++)
                        safeputchar(ndo, *(tptr + idx));
                    break;

                case LDP_FEC_MARTINI_IFPARM_VCCV:
                    ND_PRINT((ndo, "\n\t\t  Control Channels (0x%02x) = [%s]",
                           *(tptr+2),
                           bittok2str(ldp_fec_martini_ifparm_vccv_cc_values, "none", *(tptr+2))));
                    ND_PRINT((ndo, "\n\t\t  CV Types (0x%02x) = [%s]",
                           *(tptr+3),
                           bittok2str(ldp_fec_martini_ifparm_vccv_cv_values, "none", *(tptr+3))));
                    break;

                default:
                    print_unknown_data(ndo, tptr+2, "\n\t\t  ", vc_info_tlv_len-2);
                    break;
                }

                vc_info_len -= vc_info_tlv_len;
                tptr += vc_info_tlv_len;
            }
	    break;
	}

	break;

    case LDP_TLV_GENERIC_LABEL:
	TLV_TCHECK(4);
	ND_PRINT((ndo, "\n\t      Label: %u", EXTRACT_32BITS(tptr) & 0xfffff));
	break;

    case LDP_TLV_STATUS:
	TLV_TCHECK(8);
	ui = EXTRACT_32BITS(tptr);
	tptr+=4;
	ND_PRINT((ndo, "\n\t      Status: 0x%02x, Flags: [%s and %s forward]",
	       ui&0x3fffffff,
	       ui&0x80000000 ? "Fatal error" : "Advisory Notification",
	       ui&0x40000000 ? "do" : "don't"));
	ui = EXTRACT_32BITS(tptr);
	tptr+=4;
	if (ui)
	    ND_PRINT((ndo, ", causing Message ID: 0x%08x", ui));
	break;

    case LDP_TLV_FT_SESSION:
	TLV_TCHECK(8);
	ft_flags = EXTRACT_16BITS(tptr);
	ND_PRINT((ndo, "\n\t      Flags: [%sReconnect, %sSave State, %sAll-Label Protection, %s Checkpoint, %sRe-Learn State]",
	       ft_flags&0x8000 ? "" : "No ",
	       ft_flags&0x8 ? "" : "Don't ",
	       ft_flags&0x4 ? "" : "No ",
	       ft_flags&0x2 ? "Sequence Numbered Label" : "All Labels",
	       ft_flags&0x1 ? "" : "Don't "));
	tptr+=4;
	ui = EXTRACT_32BITS(tptr);
	if (ui)
	    ND_PRINT((ndo, ", Reconnect Timeout: %ums", ui));
	tptr+=4;
	ui = EXTRACT_32BITS(tptr);
	if (ui)
	    ND_PRINT((ndo, ", Recovery Time: %ums", ui));
	break;

    case LDP_TLV_MTU:
	TLV_TCHECK(2);
	ND_PRINT((ndo, "\n\t      MTU: %u", EXTRACT_16BITS(tptr)));
	break;


    /*
     *  FIXME those are the defined TLVs that lack a decoder
     *  you are welcome to contribute code ;-)
     */

    case LDP_TLV_HOP_COUNT:
    case LDP_TLV_PATH_VECTOR:
    case LDP_TLV_ATM_LABEL:
    case LDP_TLV_FR_LABEL:
    case LDP_TLV_EXTD_STATUS:
    case LDP_TLV_RETURNED_PDU:
    case LDP_TLV_RETURNED_MSG:
    case LDP_TLV_ATM_SESSION_PARM:
    case LDP_TLV_FR_SESSION_PARM:
    case LDP_TLV_LABEL_REQUEST_MSG_ID:

    default:
        if (ndo->ndo_vflag <= 1)
            print_unknown_data(ndo, tptr, "\n\t      ", tlv_tlen);
        break;
    }
    return(tlv_len+4); /* Type & Length fields not included */

trunc:
    ND_PRINT((ndo, "\n\t\t packet exceeded snapshot"));
    return 0;

badtlv:
    ND_PRINT((ndo, "\n\t\t TLV contents go past end of TLV"));
    return(tlv_len+4); /* Type & Length fields not included */
}
示例#23
0
void
cdp_print(netdissect_options *ndo,
          const u_char *pptr, u_int length, u_int caplen)
{
	int type, len, i, j;
	const u_char *tptr;

	if (caplen < CDP_HEADER_LEN) {
		ND_PRINT((ndo, "%s", tstr));
		return;
	}

	tptr = pptr; /* temporary pointer */

	ND_TCHECK2(*tptr, CDP_HEADER_LEN);
	ND_PRINT((ndo, "CDPv%u, ttl: %us", *(tptr + CDP_HEADER_VERSION_OFFSET),
					   *(tptr + CDP_HEADER_TTL_OFFSET)));
	if (ndo->ndo_vflag)
		ND_PRINT((ndo, ", checksum: 0x%04x (unverified), length %u", EXTRACT_16BITS(tptr+CDP_HEADER_CHECKSUM_OFFSET), length));
	tptr += CDP_HEADER_LEN;

	while (tptr < (pptr+length)) {
		ND_TCHECK2(*tptr, CDP_TLV_HEADER_LEN); /* read out Type and Length */
		type = EXTRACT_16BITS(tptr+CDP_TLV_TYPE_OFFSET);
		len  = EXTRACT_16BITS(tptr+CDP_TLV_LEN_OFFSET); /* object length includes the 4 bytes header length */
		if (len < CDP_TLV_HEADER_LEN) {
		    if (ndo->ndo_vflag)
			ND_PRINT((ndo, "\n\t%s (0x%02x), TLV length: %u byte%s (too short)",
			       tok2str(cdp_tlv_values,"unknown field type", type),
			       type,
			       len,
			       PLURAL_SUFFIX(len))); /* plural */
		    else
			ND_PRINT((ndo, ", %s TLV length %u too short",
			       tok2str(cdp_tlv_values,"unknown field type", type),
			       len));
		    break;
		}
		tptr += CDP_TLV_HEADER_LEN;
		len -= CDP_TLV_HEADER_LEN;

		ND_TCHECK2(*tptr, len);

		if (ndo->ndo_vflag || type == 1) { /* in non-verbose mode just print Device-ID */

		    if (ndo->ndo_vflag)
			ND_PRINT((ndo, "\n\t%s (0x%02x), value length: %u byte%s: ",
			       tok2str(cdp_tlv_values,"unknown field type", type),
			       type,
			       len,
			       PLURAL_SUFFIX(len))); /* plural */

		    switch (type) {

		    case 0x01: /* Device-ID */
			if (!ndo->ndo_vflag)
			    ND_PRINT((ndo, ", Device-ID "));
			ND_PRINT((ndo, "'"));
			(void)fn_printn(ndo, tptr, len, NULL);
			ND_PRINT((ndo, "'"));
			break;
		    case 0x02: /* Address */
			if (cdp_print_addr(ndo, tptr, len) < 0)
			    goto trunc;
			break;
		    case 0x03: /* Port-ID */
			ND_PRINT((ndo, "'"));
			(void)fn_printn(ndo, tptr, len, NULL);
			ND_PRINT((ndo, "'"));
			break;
		    case 0x04: /* Capabilities */
			if (len < 4)
			    goto trunc;
			ND_PRINT((ndo, "(0x%08x): %s",
			       EXTRACT_32BITS(tptr),
			       bittok2str(cdp_capability_values, "none", EXTRACT_32BITS(tptr))));
			break;
		    case 0x05: /* Version */
			ND_PRINT((ndo, "\n\t  "));
			for (i=0;i<len;i++) {
			    j = *(tptr+i);
			    if (j == '\n') /* lets rework the version string to
					      get a nice indentation */
				ND_PRINT((ndo, "\n\t  "));
			    else
				fn_print_char(ndo, j);
			}
			break;
		    case 0x06: /* Platform */
			ND_PRINT((ndo, "'"));
			(void)fn_printn(ndo, tptr, len, NULL);
			ND_PRINT((ndo, "'"));
			break;
		    case 0x07: /* Prefixes */
			if (cdp_print_prefixes(ndo, tptr, len) < 0)
			    goto trunc;
			break;
		    case 0x08: /* Protocol Hello Option - not documented */
			break;
		    case 0x09: /* VTP Mgmt Domain  - CDPv2 */
			ND_PRINT((ndo, "'"));
			(void)fn_printn(ndo, tptr, len, NULL);
			ND_PRINT((ndo, "'"));
			break;
		    case 0x0a: /* Native VLAN ID - CDPv2 */
			if (len < 2)
			    goto trunc;
			ND_PRINT((ndo, "%d", EXTRACT_16BITS(tptr)));
			break;
		    case 0x0b: /* Duplex - CDPv2 */
			if (len < 1)
			    goto trunc;
			ND_PRINT((ndo, "%s", *(tptr) ? "full": "half"));
			break;

		    /* http://www.cisco.com/c/en/us/td/docs/voice_ip_comm/cata/186/2_12_m/english/release/notes/186rn21m.html
		     * plus more details from other sources
		     */
		    case 0x0e: /* ATA-186 VoIP VLAN request - incomplete doc. */
			if (len < 3)
			    goto trunc;
			ND_PRINT((ndo, "app %d, vlan %d", *(tptr), EXTRACT_16BITS(tptr + 1)));
			break;
		    case 0x10: /* ATA-186 VoIP VLAN assignment - incomplete doc. */
			ND_PRINT((ndo, "%1.2fW", cdp_get_number(tptr, len) / 1000.0));
			break;
		    case 0x11: /* MTU - not documented */
			if (len < 4)
			    goto trunc;
			ND_PRINT((ndo, "%u bytes", EXTRACT_32BITS(tptr)));
			break;
		    case 0x12: /* AVVID trust bitmap - not documented */
			if (len < 1)
			    goto trunc;
			ND_PRINT((ndo, "0x%02x", *(tptr)));
			break;
		    case 0x13: /* AVVID untrusted port CoS - not documented */
			if (len < 1)
			    goto trunc;
			ND_PRINT((ndo, "0x%02x", *(tptr)));
			break;
		    case 0x14: /* System Name - not documented */
			ND_PRINT((ndo, "'"));
			(void)fn_printn(ndo, tptr, len, NULL);
			ND_PRINT((ndo, "'"));
			break;
		    case 0x16: /* System Object ID - not documented */
			if (cdp_print_addr(ndo, tptr, len) < 0)
				goto trunc;
			break;
		    case 0x17: /* Physical Location - not documented */
			if (len < 1)
			    goto trunc;
			ND_PRINT((ndo, "0x%02x", *(tptr)));
			if (len > 1) {
				ND_PRINT((ndo, "/"));
				(void)fn_printn(ndo, tptr + 1, len - 1, NULL);
			}
			break;
		    default:
			print_unknown_data(ndo, tptr, "\n\t  ", len);
			break;
		    }
		}
		tptr = tptr+len;
	}
	if (ndo->ndo_vflag < 1)
	    ND_PRINT((ndo, ", length %u", caplen));

	return;
trunc:
	ND_PRINT((ndo, "%s", tstr));
}
示例#24
0
static int
cdp_print_addr(netdissect_options *ndo,
	       const u_char * p, int l)
{
	int pt, pl, al, num;
	const u_char *endp = p + l;
	static const u_char prot_ipv6[] = {
		0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00, 0x86, 0xdd
	};

	ND_TCHECK2(*p, 4);
	if (p + 4 > endp)
		goto trunc;
	num = EXTRACT_32BITS(p);
	p += 4;

	while (p < endp && num >= 0) {
		ND_TCHECK2(*p, 2);
		if (p + 2 > endp)
			goto trunc;
		pt = p[0];		/* type of "protocol" field */
		pl = p[1];		/* length of "protocol" field */
		p += 2;

		ND_TCHECK2(p[pl], 2);
		if (p + pl + 2 > endp)
			goto trunc;
		al = EXTRACT_16BITS(&p[pl]);	/* address length */

		if (pt == PT_NLPID && pl == 1 && *p == NLPID_IP && al == 4) {
			/*
			 * IPv4: protocol type = NLPID, protocol length = 1
			 * (1-byte NLPID), protocol = 0xcc (NLPID for IPv4),
			 * address length = 4
			 */
			p += 3;

			ND_TCHECK2(*p, 4);
			if (p + 4 > endp)
				goto trunc;
			ND_PRINT((ndo, "IPv4 (%u) %s", num, ipaddr_string(ndo, p)));
			p += 4;
		}
		else if (pt == PT_IEEE_802_2 && pl == 8 &&
		    memcmp(p, prot_ipv6, 8) == 0 && al == 16) {
			/*
			 * IPv6: protocol type = IEEE 802.2 header,
			 * protocol length = 8 (size of LLC+SNAP header),
			 * protocol = LLC+SNAP header with the IPv6
			 * Ethertype, address length = 16
			 */
			p += 10;
			ND_TCHECK2(*p, al);
			if (p + al > endp)
				goto trunc;

			ND_PRINT((ndo, "IPv6 (%u) %s", num, ip6addr_string(ndo, p)));
			p += al;
		}
		else {
			/*
			 * Generic case: just print raw data
			 */
			ND_TCHECK2(*p, pl);
			if (p + pl > endp)
				goto trunc;
			ND_PRINT((ndo, "pt=0x%02x, pl=%d, pb=", *(p - 2), pl));
			while (pl-- > 0)
				ND_PRINT((ndo, " %02x", *p++));
			ND_TCHECK2(*p, 2);
			if (p + 2 > endp)
				goto trunc;
			al = (*p << 8) + *(p + 1);
			ND_PRINT((ndo, ", al=%d, a=", al));
			p += 2;
			ND_TCHECK2(*p, al);
			if (p + al > endp)
				goto trunc;
			while (al-- > 0)
				ND_PRINT((ndo, " %02x", *p++));
		}
		num--;
		if (num)
			ND_PRINT((ndo, " "));
	}

	return 0;

trunc:
	return -1;
}
示例#25
0
static void
print_trans2(netdissect_options *ndo,
             const u_char *words, const u_char *dat, const u_char *buf, const u_char *maxbuf)
{
    u_int bcc;
    static const struct smbfnsint *fn = &trans2_fns[0];
    const u_char *data, *param;
    const u_char *w = words + 1;
    const char *f1 = NULL, *f2 = NULL;
    int pcnt, dcnt;

    ND_TCHECK(words[0]);
    if (request) {
	ND_TCHECK2(w[14 * 2], 2);
	pcnt = EXTRACT_LE_16BITS(w + 9 * 2);
	param = buf + EXTRACT_LE_16BITS(w + 10 * 2);
	dcnt = EXTRACT_LE_16BITS(w + 11 * 2);
	data = buf + EXTRACT_LE_16BITS(w + 12 * 2);
	fn = smbfindint(EXTRACT_LE_16BITS(w + 14 * 2), trans2_fns);
    } else {
	if (words[0] == 0) {
	    ND_PRINT((ndo, "%s\n", fn->name));
	    ND_PRINT((ndo, "Trans2Interim\n"));
	    return;
	}
	ND_TCHECK2(w[7 * 2], 2);
	pcnt = EXTRACT_LE_16BITS(w + 3 * 2);
	param = buf + EXTRACT_LE_16BITS(w + 4 * 2);
	dcnt = EXTRACT_LE_16BITS(w + 6 * 2);
	data = buf + EXTRACT_LE_16BITS(w + 7 * 2);
    }

    ND_PRINT((ndo, "%s param_length=%d data_length=%d\n", fn->name, pcnt, dcnt));

    if (request) {
	if (words[0] == 8) {
	    smb_fdata(ndo, words + 1,
		"Trans2Secondary\nTotParam=[d]\nTotData=[d]\nParamCnt=[d]\nParamOff=[d]\nParamDisp=[d]\nDataCnt=[d]\nDataOff=[d]\nDataDisp=[d]\nHandle=[d]\n",
		maxbuf, unicodestr);
	    return;
	} else {
	    smb_fdata(ndo, words + 1,
		"TotParam=[d]\nTotData=[d]\nMaxParam=[d]\nMaxData=[d]\nMaxSetup=[b][P1]\nFlags=[w]\nTimeOut=[D]\nRes1=[w]\nParamCnt=[d]\nParamOff=[d]\nDataCnt=[d]\nDataOff=[d]\nSetupCnt=[b][P1]\n",
		words + 1 + 14 * 2, unicodestr);
	}
	f1 = fn->descript.req_f1;
	f2 = fn->descript.req_f2;
    } else {
	smb_fdata(ndo, words + 1,
	    "TotParam=[d]\nTotData=[d]\nRes1=[w]\nParamCnt=[d]\nParamOff=[d]\nParamDisp[d]\nDataCnt=[d]\nDataOff=[d]\nDataDisp=[d]\nSetupCnt=[b][P1]\n",
	    words + 1 + 10 * 2, unicodestr);
	f1 = fn->descript.rep_f1;
	f2 = fn->descript.rep_f2;
    }

    ND_TCHECK2(*dat, 2);
    bcc = EXTRACT_LE_16BITS(dat);
    ND_PRINT((ndo, "smb_bcc=%u\n", bcc));
    if (fn->descript.fn)
	(*fn->descript.fn)(ndo, param, data, pcnt, dcnt);
    else {
	smb_fdata(ndo, param, f1 ? f1 : "Parameters=\n", param + pcnt, unicodestr);
	smb_fdata(ndo, data, f2 ? f2 : "Data=\n", data + dcnt, unicodestr);
    }
    return;
trunc:
    ND_PRINT((ndo, "%s", tstr));
}
示例#26
0
static void
aoev1_issue_print(netdissect_options *ndo,
                  const u_char *cp, const u_int len)
{
	const u_char *ep = cp + len;

	if (len < AOEV1_ISSUE_ARG_LEN)
		goto invalid;
	/* AFlags */
	ND_TCHECK2(*cp, 1);
	ND_PRINT((ndo, "\n\tAFlags: [%s]", bittok2str(aoev1_aflag_str, "none", *cp)));
	cp += 1;
	/* Err/Feature */
	ND_TCHECK2(*cp, 1);
	ND_PRINT((ndo, ", Err/Feature: %u", *cp));
	cp += 1;
	/* Sector Count (not correlated with the length) */
	ND_TCHECK2(*cp, 1);
	ND_PRINT((ndo, ", Sector Count: %u", *cp));
	cp += 1;
	/* Cmd/Status */
	ND_TCHECK2(*cp, 1);
	ND_PRINT((ndo, ", Cmd/Status: %u", *cp));
	cp += 1;
	/* lba0 */
	ND_TCHECK2(*cp, 1);
	ND_PRINT((ndo, "\n\tlba0: %u", *cp));
	cp += 1;
	/* lba1 */
	ND_TCHECK2(*cp, 1);
	ND_PRINT((ndo, ", lba1: %u", *cp));
	cp += 1;
	/* lba2 */
	ND_TCHECK2(*cp, 1);
	ND_PRINT((ndo, ", lba2: %u", *cp));
	cp += 1;
	/* lba3 */
	ND_TCHECK2(*cp, 1);
	ND_PRINT((ndo, ", lba3: %u", *cp));
	cp += 1;
	/* lba4 */
	ND_TCHECK2(*cp, 1);
	ND_PRINT((ndo, ", lba4: %u", *cp));
	cp += 1;
	/* lba5 */
	ND_TCHECK2(*cp, 1);
	ND_PRINT((ndo, ", lba5: %u", *cp));
	cp += 1;
	/* Reserved */
	ND_TCHECK2(*cp, 2);
	cp += 2;
	/* Data */
	if (len > AOEV1_ISSUE_ARG_LEN)
		ND_PRINT((ndo, "\n\tData: %u bytes", len - AOEV1_ISSUE_ARG_LEN));
	return;

invalid:
	ND_PRINT((ndo, "%s", istr));
	ND_TCHECK2(*cp, ep - cp);
	return;
trunc:
	ND_PRINT((ndo, "%s", tstr));
}
示例#27
0
static int dccp_print_option(netdissect_options *ndo, const u_char *option, u_int hlen)
{
	u_int8_t optlen, i;

	ND_TCHECK(*option);

	if (*option >= 32) {
		ND_TCHECK(*(option+1));
		optlen = *(option +1);
		if (optlen < 2) {
			if (*option >= 128)
				ND_PRINT((ndo, "CCID option %u optlen too short", *option));
			else
				ND_PRINT((ndo, "%s optlen too short",
				    tok2str(dccp_option_values, "Option %u", *option)));
			return 0;
		}
	} else
		optlen = 1;

	if (hlen < optlen) {
		if (*option >= 128)
			ND_PRINT((ndo, "CCID option %u optlen goes past header length",
			    *option));
		else
			ND_PRINT((ndo, "%s optlen goes past header length",
			    tok2str(dccp_option_values, "Option %u", *option)));
		return 0;
	}
	ND_TCHECK2(*option, optlen);

	if (*option >= 128) {
		ND_PRINT((ndo, "CCID option %d", *option));
		switch (optlen) {
			case 4:
				ND_PRINT((ndo, " %u", EXTRACT_16BITS(option + 2)));
				break;
			case 6:
				ND_PRINT((ndo, " %u", EXTRACT_32BITS(option + 2)));
				break;
			default:
				break;
		}
	} else {
		ND_PRINT((ndo, "%s", tok2str(dccp_option_values, "Option %u", *option)));
		switch (*option) {
		case 32:
		case 33:
		case 34:
		case 35:
			if (optlen < 3) {
				ND_PRINT((ndo, " optlen too short"));
				return optlen;
			}
			if (*(option + 2) < 10){
				ND_PRINT((ndo, " %s", dccp_feature_nums[*(option + 2)]));
				for (i = 0; i < optlen - 3; i++)
					ND_PRINT((ndo, " %d", *(option + 3 + i)));
			}
			break;
		case 36:
			if (optlen > 2) {
				ND_PRINT((ndo, " 0x"));
				for (i = 0; i < optlen - 2; i++)
					ND_PRINT((ndo, "%02x", *(option + 2 + i)));
			}
			break;
		case 37:
			for (i = 0; i < optlen - 2; i++)
				ND_PRINT((ndo, " %d", *(option + 2 + i)));
			break;
		case 38:
			if (optlen > 2) {
				ND_PRINT((ndo, " 0x"));
				for (i = 0; i < optlen - 2; i++)
					ND_PRINT((ndo, "%02x", *(option + 2 + i)));
			}
			break;
		case 39:
			if (optlen > 2) {
				ND_PRINT((ndo, " 0x"));
				for (i = 0; i < optlen - 2; i++)
					ND_PRINT((ndo, "%02x", *(option + 2 + i)));
			}
			break;
		case 40:
			if (optlen > 2) {
				ND_PRINT((ndo, " 0x"));
				for (i = 0; i < optlen - 2; i++)
					ND_PRINT((ndo, "%02x", *(option + 2 + i)));
			}
			break;
		case 41:
			if (optlen == 4)
				ND_PRINT((ndo, " %u", EXTRACT_32BITS(option + 2)));
			else
				ND_PRINT((ndo, " optlen != 4"));
			break;
		case 42:
			if (optlen == 4)
				ND_PRINT((ndo, " %u", EXTRACT_32BITS(option + 2)));
			else
				ND_PRINT((ndo, " optlen != 4"));
			break;
		case 43:
			if (optlen == 6)
				ND_PRINT((ndo, " %u", EXTRACT_32BITS(option + 2)));
			else if (optlen == 4)
				ND_PRINT((ndo, " %u", EXTRACT_16BITS(option + 2)));
			else
				ND_PRINT((ndo, " optlen != 4 or 6"));
			break;
		case 44:
			if (optlen > 2) {
				ND_PRINT((ndo, " "));
				for (i = 0; i < optlen - 2; i++)
					ND_PRINT((ndo, "%02x", *(option + 2 + i)));
			}
			break;
		}
	}

	return optlen;
trunc:
	ND_PRINT((ndo, "%s", tstr));
	return 0;
}
示例#28
0
/**
 * dccp_print - show dccp packet
 * @bp - beginning of dccp packet
 * @data2 - beginning of enclosing
 * @len - lenght of ip packet
 */
void dccp_print(netdissect_options *ndo, const u_char *bp, const u_char *data2,
                u_int len)
{
	const struct dccp_hdr *dh;
	const struct ip *ip;
#ifdef INET6
	const struct ip6_hdr *ip6;
#endif
	const u_char *cp;
	u_short sport, dport;
	u_int hlen;
	u_int fixed_hdrlen;

	dh = (const struct dccp_hdr *)bp;

	ip = (struct ip *)data2;
#ifdef INET6
	if (IP_V(ip) == 6)
		ip6 = (const struct ip6_hdr *)data2;
	else
		ip6 = NULL;
#endif /*INET6*/

	/* make sure we have enough data to look at the X bit */
	cp = (const u_char *)(dh + 1);
	if (cp > ndo->ndo_snapend) {
		ND_PRINT((ndo, "[Invalid packet|dccp]"));
		return;
	}
	if (len < sizeof(struct dccp_hdr)) {
		ND_PRINT((ndo, "truncated-dccp - %u bytes missing!",
			     len - (u_int)sizeof(struct dccp_hdr)));
		return;
	}

	/* get the length of the generic header */
	fixed_hdrlen = dccp_basic_hdr_len(dh);
	if (len < fixed_hdrlen) {
		ND_PRINT((ndo, "truncated-dccp - %u bytes missing!",
			     len - fixed_hdrlen));
		return;
	}
	ND_TCHECK2(*dh, fixed_hdrlen);

	sport = EXTRACT_16BITS(&dh->dccph_sport);
	dport = EXTRACT_16BITS(&dh->dccph_dport);
	hlen = dh->dccph_doff * 4;

#ifdef INET6
	if (ip6) {
		ND_PRINT((ndo, "%s.%d > %s.%d: ",
			     ip6addr_string(ndo, &ip6->ip6_src), sport,
			     ip6addr_string(ndo, &ip6->ip6_dst), dport));
	} else
#endif /*INET6*/
	{
		ND_PRINT((ndo, "%s.%d > %s.%d: ",
			     ipaddr_string(ndo, &ip->ip_src), sport,
			     ipaddr_string(ndo, &ip->ip_dst), dport));
	}

	if (ndo->ndo_qflag) {
		ND_PRINT((ndo, " %d", len - hlen));
		if (hlen > len) {
			ND_PRINT((ndo, "dccp [bad hdr length %u - too long, > %u]",
			    hlen, len));
		}
		return;
	}

	/* other variables in generic header */
	if (ndo->ndo_vflag) {
		ND_PRINT((ndo, "CCVal %d, CsCov %d, ", DCCPH_CCVAL(dh), DCCPH_CSCOV(dh)));
	}

	/* checksum calculation */
	if (ndo->ndo_vflag && ND_TTEST2(bp[0], len)) {
		u_int16_t sum = 0, dccp_sum;

		dccp_sum = EXTRACT_16BITS(&dh->dccph_checksum);
		ND_PRINT((ndo, "cksum 0x%04x ", dccp_sum));
		if (IP_V(ip) == 4)
			sum = dccp_cksum(ndo, ip, dh, len);
#ifdef INET6
		else if (IP_V(ip) == 6)
			sum = dccp6_cksum(ip6, dh, len);
#endif
		if (sum != 0)
			ND_PRINT((ndo, "(incorrect -> 0x%04x), ",in_cksum_shouldbe(dccp_sum, sum)));
		else
			ND_PRINT((ndo, "(correct), "));
	}

	switch (DCCPH_TYPE(dh)) {
	case DCCP_PKT_REQUEST: {
		struct dccp_hdr_request *dhr =
			(struct dccp_hdr_request *)(bp + fixed_hdrlen);
		fixed_hdrlen += 4;
		if (len < fixed_hdrlen) {
			ND_PRINT((ndo, "truncated-dccp request - %u bytes missing!",
				     len - fixed_hdrlen));
			return;
		}
		ND_TCHECK(*dhr);
		ND_PRINT((ndo, "request (service=%d) ",
			     EXTRACT_32BITS(&dhr->dccph_req_service)));
		break;
	}
	case DCCP_PKT_RESPONSE: {
		struct dccp_hdr_response *dhr =
			(struct dccp_hdr_response *)(bp + fixed_hdrlen);
		fixed_hdrlen += 12;
		if (len < fixed_hdrlen) {
			ND_PRINT((ndo, "truncated-dccp response - %u bytes missing!",
				     len - fixed_hdrlen));
			return;
		}
		ND_TCHECK(*dhr);
		ND_PRINT((ndo, "response (service=%d) ",
			     EXTRACT_32BITS(&dhr->dccph_resp_service)));
		break;
	}
	case DCCP_PKT_DATA:
		ND_PRINT((ndo, "data "));
		break;
	case DCCP_PKT_ACK: {
		fixed_hdrlen += 8;
		if (len < fixed_hdrlen) {
			ND_PRINT((ndo, "truncated-dccp ack - %u bytes missing!",
				     len - fixed_hdrlen));
			return;
		}
		ND_PRINT((ndo, "ack "));
		break;
	}
	case DCCP_PKT_DATAACK: {
		fixed_hdrlen += 8;
		if (len < fixed_hdrlen) {
			ND_PRINT((ndo, "truncated-dccp dataack - %u bytes missing!",
				     len - fixed_hdrlen));
			return;
		}
		ND_PRINT((ndo, "dataack "));
		break;
	}
	case DCCP_PKT_CLOSEREQ:
		fixed_hdrlen += 8;
		if (len < fixed_hdrlen) {
			ND_PRINT((ndo, "truncated-dccp closereq - %u bytes missing!",
				     len - fixed_hdrlen));
			return;
		}
		ND_PRINT((ndo, "closereq "));
		break;
	case DCCP_PKT_CLOSE:
		fixed_hdrlen += 8;
		if (len < fixed_hdrlen) {
			ND_PRINT((ndo, "truncated-dccp close - %u bytes missing!",
				     len - fixed_hdrlen));
			return;
		}
		ND_PRINT((ndo, "close "));
		break;
	case DCCP_PKT_RESET: {
		struct dccp_hdr_reset *dhr =
			(struct dccp_hdr_reset *)(bp + fixed_hdrlen);
		fixed_hdrlen += 12;
		if (len < fixed_hdrlen) {
			ND_PRINT((ndo, "truncated-dccp reset - %u bytes missing!",
				     len - fixed_hdrlen));
			return;
		}
		ND_TCHECK(*dhr);
		ND_PRINT((ndo, "reset (code=%s) ",
			     dccp_reset_code(dhr->dccph_reset_code)));
		break;
	}
	case DCCP_PKT_SYNC:
		fixed_hdrlen += 8;
		if (len < fixed_hdrlen) {
			ND_PRINT((ndo, "truncated-dccp sync - %u bytes missing!",
				     len - fixed_hdrlen));
			return;
		}
		ND_PRINT((ndo, "sync "));
		break;
	case DCCP_PKT_SYNCACK:
		fixed_hdrlen += 8;
		if (len < fixed_hdrlen) {
			ND_PRINT((ndo, "truncated-dccp syncack - %u bytes missing!",
				     len - fixed_hdrlen));
			return;
		}
		ND_PRINT((ndo, "syncack "));
		break;
	default:
		ND_PRINT((ndo, "invalid "));
		break;
	}

	if ((DCCPH_TYPE(dh) != DCCP_PKT_DATA) &&
			(DCCPH_TYPE(dh) != DCCP_PKT_REQUEST))
		dccp_print_ack_no(ndo, bp);

	if (ndo->ndo_vflag < 2)
		return;

	ND_PRINT((ndo, "seq %" PRIu64, dccp_seqno(bp)));

	/* process options */
	if (hlen > fixed_hdrlen){
		const u_char *cp;
		u_int optlen;
		cp = bp + fixed_hdrlen;
		ND_PRINT((ndo, " <"));

		hlen -= fixed_hdrlen;
		while(1){
			optlen = dccp_print_option(ndo, cp, hlen);
			if (!optlen)
				break;
			if (hlen <= optlen)
				break;
			hlen -= optlen;
			cp += optlen;
			ND_PRINT((ndo, ", "));
		}
		ND_PRINT((ndo, ">"));
	}
	return;
trunc:
	ND_PRINT((ndo, "%s", tstr));
	return;
}
示例#29
0
/*
 * Print a single PDU.
 */
static void
rpki_rtr_pdu_print (netdissect_options *ndo, const u_char *tptr, u_int indent)
{
    const rpki_rtr_pdu *pdu_header;
    u_int pdu_type, pdu_len, hexdump;
    const u_char *msg;

    pdu_header = (const rpki_rtr_pdu *)tptr;
    pdu_type = pdu_header->pdu_type;
    pdu_len = EXTRACT_32BITS(pdu_header->length);
    ND_TCHECK2(*tptr, pdu_len);
    hexdump = FALSE;

    ND_PRINT((ndo, "%sRPKI-RTRv%u, %s PDU (%u), length: %u",
	   indent_string(8),
	   pdu_header->version,
	   tok2str(rpki_rtr_pdu_values, "Unknown", pdu_type),
	   pdu_type, pdu_len));

    switch (pdu_type) {

	/*
	 * The following PDUs share the message format.
	 */
    case RPKI_RTR_SERIAL_NOTIFY_PDU:
    case RPKI_RTR_SERIAL_QUERY_PDU:
    case RPKI_RTR_END_OF_DATA_PDU:
        msg = (const u_char *)(pdu_header + 1);
	ND_PRINT((ndo, "%sSession ID: 0x%04x, Serial: %u",
	       indent_string(indent+2),
	       EXTRACT_16BITS(pdu_header->u.session_id),
	       EXTRACT_32BITS(msg)));
	break;

	/*
	 * The following PDUs share the message format.
	 */
    case RPKI_RTR_RESET_QUERY_PDU:
    case RPKI_RTR_CACHE_RESET_PDU:

	/*
	 * Zero payload PDUs.
	 */
	break;

    case RPKI_RTR_CACHE_RESPONSE_PDU:
	ND_PRINT((ndo, "%sSession ID: 0x%04x",
	       indent_string(indent+2),
	       EXTRACT_16BITS(pdu_header->u.session_id)));
	break;

    case RPKI_RTR_IPV4_PREFIX_PDU:
	{
	    const rpki_rtr_pdu_ipv4_prefix *pdu;

	    pdu = (const rpki_rtr_pdu_ipv4_prefix *)tptr;
	    ND_PRINT((ndo, "%sIPv4 Prefix %s/%u-%u, origin-as %u, flags 0x%02x",
		   indent_string(indent+2),
		   ipaddr_string(ndo, pdu->prefix),
		   pdu->prefix_length, pdu->max_length,
		   EXTRACT_32BITS(pdu->as), pdu->flags));
	}
	break;

    case RPKI_RTR_IPV6_PREFIX_PDU:
	{
	    const rpki_rtr_pdu_ipv6_prefix *pdu;

	    pdu = (const rpki_rtr_pdu_ipv6_prefix *)tptr;
	    ND_PRINT((ndo, "%sIPv6 Prefix %s/%u-%u, origin-as %u, flags 0x%02x",
		   indent_string(indent+2),
		   ip6addr_string(ndo, pdu->prefix),
		   pdu->prefix_length, pdu->max_length,
		   EXTRACT_32BITS(pdu->as), pdu->flags));
	}
	break;

    case RPKI_RTR_ERROR_REPORT_PDU:
	{
	    const rpki_rtr_pdu_error_report *pdu;
	    u_int encapsulated_pdu_length, text_length, tlen, error_code;

	    pdu = (const rpki_rtr_pdu_error_report *)tptr;
	    encapsulated_pdu_length = EXTRACT_32BITS(pdu->encapsulated_pdu_length);
	    ND_TCHECK2(*tptr, encapsulated_pdu_length);
	    tlen = pdu_len;

	    error_code = EXTRACT_16BITS(pdu->pdu_header.u.error_code);
	    ND_PRINT((ndo, "%sError code: %s (%u), Encapsulated PDU length: %u",
		   indent_string(indent+2),
		   tok2str(rpki_rtr_error_codes, "Unknown", error_code),
		   error_code, encapsulated_pdu_length));

	    tptr += sizeof(*pdu);
	    tlen -= sizeof(*pdu);

	    /*
	     * Recurse if there is an encapsulated PDU.
	     */
	    if (encapsulated_pdu_length &&
		(encapsulated_pdu_length <= tlen)) {
		ND_PRINT((ndo, "%s-----encapsulated PDU-----", indent_string(indent+4)));
		rpki_rtr_pdu_print(ndo, tptr, indent+2);
	    }

	    tptr += encapsulated_pdu_length;
	    tlen -= encapsulated_pdu_length;

	    /*
	     * Extract, trail-zero and print the Error message.
	     */
	    text_length = 0;
	    if (tlen > 4) {
		text_length = EXTRACT_32BITS(tptr);
		tptr += 4;
		tlen -= 4;
	    }
	    ND_TCHECK2(*tptr, text_length);
	    if (text_length && (text_length <= tlen )) {
		ND_PRINT((ndo, "%sError text: ", indent_string(indent+2)));
		fn_printn(ndo, tptr, text_length, ndo->ndo_snapend);
	    }
	}
	break;

    default:

	/*
	 * Unknown data, please hexdump.
	 */
	hexdump = TRUE;
    }

    /* do we also want to see a hex dump ? */
    if (ndo->ndo_vflag > 1 || (ndo->ndo_vflag && hexdump)) {
	print_unknown_data(ndo,tptr,"\n\t  ", pdu_len);
    }
    return;

 trunc:
    ND_PRINT((ndo, "|trunc"));
    return;
}
示例#30
0
static void
krb4_print(netdissect_options *ndo,
           const u_char *cp)
{
	register const struct krb *kp;
	u_char type;
	u_short len;

#define PRINT		if ((cp = c_print(ndo, cp, ndo->ndo_snapend)) == NULL) goto trunc
/*  True if struct krb is little endian */
#define IS_LENDIAN(kp)	(((kp)->type & 0x01) != 0)
#define KTOHSP(kp, cp)	(IS_LENDIAN(kp) ? EXTRACT_LE_16BITS(cp) : EXTRACT_16BITS(cp))

	kp = (const struct krb *)cp;

	if ((&kp->type) >= ndo->ndo_snapend) {
		ND_PRINT((ndo, "%s", tstr));
		return;
	}

	type = kp->type & (0xFF << 1);

	ND_PRINT((ndo, " %s %s: ",
	    IS_LENDIAN(kp) ? "le" : "be", tok2str(type2str, NULL, type)));

	switch (type) {

	case AUTH_MSG_KDC_REQUEST:
		if ((cp = krb4_print_hdr(ndo, cp)) == NULL)
			return;
		cp += 4;	/* ctime */
		ND_TCHECK(*cp);
		ND_PRINT((ndo, " %dmin ", *cp++ * 5));
		PRINT;
		ND_PRINT((ndo, "."));
		PRINT;
		break;

	case AUTH_MSG_APPL_REQUEST:
		cp += 2;
		ND_TCHECK(*cp);
		ND_PRINT((ndo, "v%d ", *cp++));
		PRINT;
		ND_TCHECK(*cp);
		ND_PRINT((ndo, " (%d)", *cp++));
		ND_TCHECK(*cp);
		ND_PRINT((ndo, " (%d)", *cp));
		break;

	case AUTH_MSG_KDC_REPLY:
		if ((cp = krb4_print_hdr(ndo, cp)) == NULL)
			return;
		cp += 10;	/* timestamp + n + exp + kvno */
		ND_TCHECK2(*cp, sizeof(short));
		len = KTOHSP(kp, cp);
		ND_PRINT((ndo, " (%d)", len));
		break;

	case AUTH_MSG_ERR_REPLY:
		if ((cp = krb4_print_hdr(ndo, cp)) == NULL)
			return;
		cp += 4; 	  /* timestamp */
		ND_TCHECK2(*cp, sizeof(short));
		ND_PRINT((ndo, " %s ", tok2str(kerr2str, NULL, KTOHSP(kp, cp))));
		cp += 4;
		PRINT;
		break;

	default:
		ND_PRINT((ndo, "(unknown)"));
		break;
	}

	return;
trunc:
	ND_PRINT((ndo, "%s", tstr));
}