Ejemplo n.º 1
0
/*
 * Print NTP control message requests and responses
 */
static void
ntp_control_print(netdissect_options *ndo,
		  const struct ntp_control_data *cd, u_int length)
{
	uint8_t control, R, E, M, opcode;
	uint16_t sequence, status, assoc, offset, count;

	if (length < NTP_CTRLMSG_MINLEN)
		goto invalid;

	ND_TCHECK_1(cd->control);
	control = EXTRACT_U_1(cd->control);
	R = (control & 0x80) != 0;
	E = (control & 0x40) != 0;
	M = (control & 0x20) != 0;
	opcode = control & 0x1f;
	ND_PRINT(", %s, %s, %s, OpCode=%u\n",
		  R ? "Response" : "Request", E ? "Error" : "OK",
		  M ? "More" : "Last", opcode);

	ND_TCHECK_2(cd->sequence);
	sequence = EXTRACT_BE_U_2(cd->sequence);
	ND_PRINT("\tSequence=%hu", sequence);

	ND_TCHECK_2(cd->status);
	status = EXTRACT_BE_U_2(cd->status);
	ND_PRINT(", Status=%#hx", status);

	ND_TCHECK_2(cd->assoc);
	assoc = EXTRACT_BE_U_2(cd->assoc);
	ND_PRINT(", Assoc.=%hu", assoc);

	ND_TCHECK_2(cd->offset);
	offset = EXTRACT_BE_U_2(cd->offset);
	ND_PRINT(", Offset=%hu", offset);

	ND_TCHECK_2(cd->count);
	count = EXTRACT_BE_U_2(cd->count);
	ND_PRINT(", Count=%hu", count);

	if (NTP_CTRLMSG_MINLEN + count > length)
		goto invalid;
	if (count != 0) {
		ND_TCHECK_LEN(cd->data, count);
		ND_PRINT("\n\tTO-BE-DONE: data not interpreted");
	}
	return;

invalid:
	nd_print_invalid(ndo);
	ND_TCHECK_LEN(cd, length);
	return;

trunc:
	nd_print_trunc(ndo);
}
Ejemplo n.º 2
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 invalid;
	/* function */
	ND_TCHECK_2(cp);
	function = EXTRACT_LE_U_2(cp);
	cp += 2;
	ND_PRINT(", %s", tok2str(fcode_str, " invalid (%u)", function));

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

invalid:
	ND_PRINT("%s", istr);
	ND_TCHECK_LEN(cp, ep - cp);
	return;
trunc:
	ND_PRINT("%s", tstr);
}
Ejemplo n.º 3
0
void
loopback_print(netdissect_options *ndo, const u_char *cp, const u_int len)
{
	const u_char *ep = cp + len;
	uint16_t skipCount;

	ND_PRINT("Loopback");
	if (len < 2)
		goto invalid;
	/* skipCount */
	ND_TCHECK_2(cp);
	skipCount = EXTRACT_LE_U_2(cp);
	cp += 2;
	ND_PRINT(", skipCount %u", skipCount);
	if (skipCount % 8)
		ND_PRINT(" (bogus)");
	if (skipCount > len - 2)
		goto invalid;
	loopback_message_print(ndo, cp + skipCount, len - 2 - skipCount);
	return;

invalid:
	ND_PRINT("%s", istr);
	ND_TCHECK_LEN(cp, ep - cp);
	return;
trunc:
	ND_PRINT("%s", tstr);
}
Ejemplo n.º 4
0
void
gre_print(netdissect_options *ndo, const u_char *bp, u_int length)
{
	u_int len = length, vers;

	ND_TCHECK_2(bp);
	if (len < 2)
		goto trunc;
	vers = EXTRACT_BE_U_2(bp) & GRE_VERS_MASK;
        ND_PRINT("GREv%u",vers);

        switch(vers) {
        case 0:
            gre_print_0(ndo, bp, len);
            break;
        case 1:
            gre_print_1(ndo, bp, len);
            break;
	default:
            ND_PRINT(" ERROR: unknown-version");
            break;
        }
        return;

trunc:
	ND_PRINT("%s", tstr);
	return;
}
Ejemplo n.º 5
0
/*
 * Print RRCP requests
 */
void
rrcp_print(netdissect_options *ndo,
	  const u_char *cp,
	  u_int length _U_,
	  const struct lladdr_info *src,
	  const struct lladdr_info *dst)
{
	uint8_t rrcp_proto;
	uint8_t rrcp_opcode;

	ndo->ndo_protocol = "rrcp";
	ND_TCHECK_1(cp + RRCP_PROTO_OFFSET);
	rrcp_proto = EXTRACT_U_1(cp + RRCP_PROTO_OFFSET);
	ND_TCHECK_1(cp + RRCP_OPCODE_ISREPLY_OFFSET);
	rrcp_opcode = EXTRACT_U_1((cp + RRCP_OPCODE_ISREPLY_OFFSET)) & RRCP_OPCODE_MASK;
	if (src != NULL && dst != NULL) {
		ND_PRINT("%s > %s, ",
			(src->addr_string)(ndo, src->addr),
			(dst->addr_string)(ndo, dst->addr));
	}
	ND_PRINT("%s %s",
		tok2str(proto_values,"RRCP-0x%02x",rrcp_proto),
		((EXTRACT_U_1(cp + RRCP_OPCODE_ISREPLY_OFFSET)) & RRCP_ISREPLY) ? "reply" : "query");
	if (rrcp_proto==1){
    	    ND_PRINT(": %s",
		     tok2str(opcode_values,"unknown opcode (0x%02x)",rrcp_opcode));
	}
	if (rrcp_opcode==1 || rrcp_opcode==2){
	    ND_TCHECK_6(cp + RRCP_REG_ADDR_OFFSET);
    	    ND_PRINT(" addr=0x%04x, data=0x%08x",
		     EXTRACT_LE_U_2(cp + RRCP_REG_ADDR_OFFSET),
		     EXTRACT_LE_U_4(cp + RRCP_REG_DATA_OFFSET));
	}
	if (rrcp_proto==1){
	    ND_TCHECK_2(cp + RRCP_AUTHKEY_OFFSET);
    	    ND_PRINT(", auth=0x%04x",
		  EXTRACT_BE_U_2(cp + RRCP_AUTHKEY_OFFSET));
	}
	if (rrcp_proto==1 && rrcp_opcode==0 &&
	     ((EXTRACT_U_1(cp + RRCP_OPCODE_ISREPLY_OFFSET)) & RRCP_ISREPLY)){
	    ND_TCHECK_4(cp + RRCP_VENDOR_ID_OFFSET);
	    ND_PRINT(" downlink_port=%u, uplink_port=%u, uplink_mac=%s, vendor_id=%08x ,chip_id=%04x ",
		     EXTRACT_U_1(cp + RRCP_DOWNLINK_PORT_OFFSET),
		     EXTRACT_U_1(cp + RRCP_UPLINK_PORT_OFFSET),
		     etheraddr_string(ndo, cp + RRCP_UPLINK_MAC_OFFSET),
		     EXTRACT_BE_U_4(cp + RRCP_VENDOR_ID_OFFSET),
		     EXTRACT_BE_U_2(cp + RRCP_CHIP_ID_OFFSET));
	}else if (rrcp_opcode==1 || rrcp_opcode==2 || rrcp_proto==2){
	    ND_TCHECK_4(cp + RRCP_COOKIE2_OFFSET);
	    ND_PRINT(", cookie=0x%08x%08x ",
		    EXTRACT_BE_U_4(cp + RRCP_COOKIE2_OFFSET),
		    EXTRACT_BE_U_4(cp + RRCP_COOKIE1_OFFSET));
	}
	return;

trunc:
	nd_print_trunc(ndo);
}
Ejemplo n.º 6
0
/*
 * print vendor specific attributes
 */
static void
print_vendor_attr(netdissect_options *ndo,
                  const u_char *data, u_int length, u_short attr_code _U_)
{
    u_int idx;
    u_int vendor_id;
    u_int vendor_type;
    u_int vendor_length;

    if (length < 4)
        goto trunc;
    ND_TCHECK_4(data);
    vendor_id = EXTRACT_BE_U_4(data);
    data+=4;
    length-=4;

    ND_PRINT("Vendor: %s (%u)",
           tok2str(smi_values,"Unknown",vendor_id),
           vendor_id);

    while (length >= 2) {
	ND_TCHECK_2(data);

        vendor_type = EXTRACT_U_1(data);
        vendor_length = EXTRACT_U_1(data + 1);

        if (vendor_length < 2)
        {
            ND_PRINT("\n\t    Vendor Attribute: %u, Length: %u (bogus, must be >= 2)",
                   vendor_type,
                   vendor_length);
            return;
        }
        if (vendor_length > length)
        {
            ND_PRINT("\n\t    Vendor Attribute: %u, Length: %u (bogus, goes past end of vendor-specific attribute)",
                   vendor_type,
                   vendor_length);
            return;
        }
        data+=2;
        vendor_length-=2;
        length-=2;
	ND_TCHECK_LEN(data, vendor_length);

        ND_PRINT("\n\t    Vendor Attribute: %u, Length: %u, Value: ",
               vendor_type,
               vendor_length);
        for (idx = 0; idx < vendor_length ; idx++, data++)
            ND_PRINT("%c", ND_ISPRINT(EXTRACT_U_1(data)) ? EXTRACT_U_1(data) : '.');
        length-=vendor_length;
    }
    return;

   trunc:
     nd_print_trunc(ndo);
}
Ejemplo n.º 7
0
/* IP6CP config options */
static u_int
print_ip6cp_config_options(netdissect_options *ndo,
                           const u_char *p, u_int length)
{
	u_int opt, len;

	if (length < 2)
		return 0;
	ND_TCHECK_2(p);
	opt = EXTRACT_U_1(p);
	len = EXTRACT_U_1(p + 1);
	if (length < len)
		return 0;
	if (len < 2) {
		ND_PRINT("\n\t  %s Option (0x%02x), length %u (length bogus, should be >= 2)",
		       tok2str(ip6cpopt_values,"unknown",opt),
		       opt,
		       len);
		return 0;
	}

	ND_PRINT("\n\t  %s Option (0x%02x), length %u",
	       tok2str(ip6cpopt_values,"unknown",opt),
	       opt,
	       len);

	switch (opt) {
	case IP6CP_IFID:
		if (len != 10) {
			ND_PRINT(" (length bogus, should be = 10)");
			return len;
		}
		ND_TCHECK_8(p + 2);
		ND_PRINT(": %04x:%04x:%04x:%04x",
		       EXTRACT_BE_U_2(p + 2),
		       EXTRACT_BE_U_2(p + 4),
		       EXTRACT_BE_U_2(p + 6),
		       EXTRACT_BE_U_2(p + 8));
		break;
	default:
		/*
		 * Unknown option; dump it as raw bytes now if we're
		 * not going to do so below.
		 */
		if (ndo->ndo_vflag < 2)
			print_unknown_data(ndo, p + 2, "\n\t    ", len - 2);
		break;
	}
	if (ndo->ndo_vflag > 1)
		print_unknown_data(ndo, p + 2, "\n\t    ", len - 2); /* exclude TLV header */

	return len;

trunc:
	ND_PRINT("[|ip6cp]");
	return 0;
}
Ejemplo n.º 8
0
void
timed_print(netdissect_options *ndo,
            const u_char *bp)
{
	const struct tsp *tsp = (const struct tsp *)bp;
	uint8_t tsp_type;
	int sec, usec;

	ndo->ndo_protocol = "timed";
	ND_TCHECK_1(tsp->tsp_type);
	tsp_type = EXTRACT_U_1(tsp->tsp_type);
	if (tsp_type < TSPTYPENUMBER)
		ND_PRINT("TSP_%s", tsptype[tsp_type]);
	else
		ND_PRINT("(tsp_type %#x)", tsp_type);

	ND_TCHECK_1(tsp->tsp_vers);
	ND_PRINT(" vers %u", EXTRACT_U_1(tsp->tsp_vers));

	ND_TCHECK_2(tsp->tsp_seq);
	ND_PRINT(" seq %u", EXTRACT_BE_U_2(tsp->tsp_seq));

	switch (tsp_type) {
	case TSP_LOOP:
		ND_TCHECK_1(tsp->tsp_hopcnt);
		ND_PRINT(" hopcnt %u", EXTRACT_U_1(tsp->tsp_hopcnt));
		break;
	case TSP_SETTIME:
	case TSP_ADJTIME:
	case TSP_SETDATE:
	case TSP_SETDATEREQ:
		ND_TCHECK_8(&tsp->tsp_time);
		sec = EXTRACT_BE_S_4(tsp->tsp_time.tv_sec);
		usec = EXTRACT_BE_S_4(tsp->tsp_time.tv_usec);
		/* XXX The comparison below is always false? */
		if (usec < 0)
			/* invalid, skip the rest of the packet */
			return;
		ND_PRINT(" time ");
		if (sec < 0 && usec != 0) {
			sec++;
			if (sec == 0)
				ND_PRINT("-");
			usec = 1000000 - usec;
		}
		ND_PRINT("%d.%06d", sec, usec);
		break;
	}
	ND_PRINT(" name ");
	if (nd_printzp(ndo, tsp->tsp_name, sizeof(tsp->tsp_name),
		       ndo->ndo_snapend))
		goto trunc;
	return;

trunc:
	nd_print_trunc(ndo);
}
Ejemplo n.º 9
0
static int
stp_print_config_bpdu(netdissect_options *ndo, const struct stp_bpdu_ *stp_bpdu,
                      u_int length)
{
    uint8_t bpdu_flags;

    ND_TCHECK_1(stp_bpdu->flags);
    bpdu_flags = EXTRACT_U_1(stp_bpdu->flags);
    ND_PRINT(", Flags [%s]",
           bittok2str(stp_bpdu_flag_values, "none", bpdu_flags));

    ND_TCHECK_2(stp_bpdu->port_id);
    ND_PRINT(", bridge-id %s.%04x, length %u",
           stp_print_bridge_id((const u_char *)&stp_bpdu->bridge_id),
           EXTRACT_BE_U_2(stp_bpdu->port_id), length);

    /* in non-verbose mode just print the bridge-id */
    if (!ndo->ndo_vflag) {
        return 1;
    }

    ND_TCHECK_2(stp_bpdu->forward_delay);
    ND_PRINT("\n\tmessage-age %.2fs, max-age %.2fs"
           ", hello-time %.2fs, forwarding-delay %.2fs",
           (float) EXTRACT_BE_U_2(stp_bpdu->message_age) / STP_TIME_BASE,
           (float) EXTRACT_BE_U_2(stp_bpdu->max_age) / STP_TIME_BASE,
           (float) EXTRACT_BE_U_2(stp_bpdu->hello_time) / STP_TIME_BASE,
           (float) EXTRACT_BE_U_2(stp_bpdu->forward_delay) / STP_TIME_BASE);

    ND_PRINT("\n\troot-id %s, root-pathcost %u",
           stp_print_bridge_id((const u_char *)&stp_bpdu->root_id),
           EXTRACT_BE_U_4(stp_bpdu->root_path_cost));

    /* Port role is only valid for 802.1w */
    if (EXTRACT_U_1(stp_bpdu->protocol_version) == STP_PROTO_RAPID) {
        ND_PRINT(", port-role %s",
               tok2str(rstp_obj_port_role_values, "Unknown",
                       RSTP_EXTRACT_PORT_ROLE(bpdu_flags)));
    }
    return 1;

trunc:
    return 0;
}
Ejemplo n.º 10
0
/* BACP config options */
static u_int
print_bacp_config_options(netdissect_options *ndo,
                          const u_char *p, u_int length)
{
	u_int opt, len;

	if (length < 2)
		return 0;
	ND_TCHECK_2(p);
	opt = EXTRACT_U_1(p);
	len = EXTRACT_U_1(p + 1);
	if (length < len)
		return 0;
	if (len < 2) {
		ND_PRINT("\n\t  %s Option (0x%02x), length %u (length bogus, should be >= 2)",
		          tok2str(bacconfopts_values, "Unknown", opt),
		          opt,
		          len);
		return 0;
	}

	ND_PRINT("\n\t  %s Option (0x%02x), length %u",
	          tok2str(bacconfopts_values, "Unknown", opt),
	          opt,
	          len);

	switch (opt) {
	case BACPOPT_FPEER:
		if (len != 6) {
			ND_PRINT(" (length bogus, should be = 6)");
			return len;
		}
		ND_TCHECK_4(p + 2);
		ND_PRINT(": Magic-Num 0x%08x", EXTRACT_BE_U_4(p + 2));
		break;
	default:
		/*
		 * Unknown option; dump it as raw bytes now if we're
		 * not going to do so below.
		 */
		if (ndo->ndo_vflag < 2)
			print_unknown_data(ndo, p + 2, "\n\t    ", len - 2);
		break;
	}
	if (ndo->ndo_vflag > 1)
		print_unknown_data(ndo, p + 2, "\n\t    ", len - 2); /* exclude TLV header */

	return len;

trunc:
	ND_PRINT("[|bacp]");
	return 0;
}
Ejemplo n.º 11
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_TCHECK_1(cp);
	version = EXTRACT_U_1(cp);
	cp += 1;
	/* type */
	ND_TCHECK_1(cp);
	type = EXTRACT_U_1(cp);
	cp += 1;
	/* length */
	ND_TCHECK_2(cp);
	length = EXTRACT_BE_U_2(cp);
	cp += 2;
	/* xid */
	ND_TCHECK_4(cp);
	xid = EXTRACT_BE_U_4(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_TCHECK_LEN(cp, length - OF_HEADER_LEN);
		return cp + length - OF_HEADER_LEN; /* done with current message */
	}

invalid: /* fail current packet */
	ND_PRINT("%s", istr);
	ND_TCHECK_LEN(cp, ep - cp);
	return ep;
trunc:
	ND_PRINT("%s", tstr);
	return ep;
}
Ejemplo n.º 12
0
static void
ahcp1_body_print(netdissect_options *ndo, const u_char *cp, const u_char *ep)
{
	uint8_t type, mbz;
	uint16_t body_len;

	if (cp + AHCP1_BODY_MIN_LEN > ep)
		goto invalid;
	/* Type */
	ND_TCHECK_1(cp);
	type = EXTRACT_U_1(cp);
	cp += 1;
	/* MBZ */
	ND_TCHECK_1(cp);
	mbz = EXTRACT_U_1(cp);
	cp += 1;
	/* Length */
	ND_TCHECK_2(cp);
	body_len = EXTRACT_BE_U_2(cp);
	cp += 2;

	if (ndo->ndo_vflag) {
		ND_PRINT("\n\t%s", tok2str(ahcp1_msg_str, "Unknown-%u", type));
		if (mbz != 0)
			ND_PRINT(", MBZ %u", mbz);
		ND_PRINT(", Length %u", body_len);
	}
	if (cp + body_len > ep)
		goto invalid;

	/* Options */
	if (ndo->ndo_vflag >= 2)
		ahcp1_options_print(ndo, cp, cp + body_len); /* not ep (ignore extra data) */
	else
		ND_TCHECK_LEN(cp, body_len);
	return;

invalid:
	ND_PRINT("%s", istr);
	ND_TCHECK_LEN(cp, ep - cp);
	return;
trunc:
	nd_print_trunc(ndo);
}
Ejemplo n.º 13
0
static int
lwres_printaddr(netdissect_options *ndo,
                const u_char *p0)
{
	const u_char *p;
	const lwres_addr_t *ap;
	uint16_t l;
	int i;

	p = p0;
	ap = (const lwres_addr_t *)p;
	ND_TCHECK_2(ap->length);
	l = EXTRACT_BE_U_2(ap->length);
	p += LWRES_ADDR_LEN;
	ND_TCHECK_LEN(p, l);

	switch (EXTRACT_BE_U_4(ap->family)) {
	case 1:	/* IPv4 */
		if (l < 4)
			return -1;
		ND_PRINT(" %s", ipaddr_string(ndo, p));
		p += sizeof(nd_ipv4);
		break;
	case 2:	/* IPv6 */
		if (l < 16)
			return -1;
		ND_PRINT(" %s", ip6addr_string(ndo, p));
		p += sizeof(nd_ipv6);
		break;
	default:
		ND_PRINT(" %u/", EXTRACT_BE_U_4(ap->family));
		for (i = 0; i < l; i++) {
			ND_PRINT("%02x", EXTRACT_U_1(p));
			p++;
		}
	}

	return p - p0;

  trunc:
	return -1;
}
Ejemplo n.º 14
0
static void
slow_oam_print(netdissect_options *ndo,
               const u_char *tptr, u_int tlen)
{
    uint8_t code;
    uint8_t type, length;
    uint8_t state;
    uint8_t command;
    u_int hexdump;

    struct slow_oam_common_header_t {
        nd_uint16_t flags;
        nd_uint8_t code;
    };

    struct slow_oam_tlv_header_t {
        nd_uint8_t type;
        nd_uint8_t length;
    };

    union {
        const struct slow_oam_common_header_t *slow_oam_common_header;
        const struct slow_oam_tlv_header_t *slow_oam_tlv_header;
    } ptr;

    union {
	const struct slow_oam_info_t *slow_oam_info;
        const struct slow_oam_link_event_t *slow_oam_link_event;
        const struct slow_oam_variablerequest_t *slow_oam_variablerequest;
        const struct slow_oam_variableresponse_t *slow_oam_variableresponse;
        const struct slow_oam_loopbackctrl_t *slow_oam_loopbackctrl;
    } tlv;

    ptr.slow_oam_common_header = (const struct slow_oam_common_header_t *)tptr;
    if (tlen < sizeof(*ptr.slow_oam_common_header))
        goto tooshort;
    ND_TCHECK_SIZE(ptr.slow_oam_common_header);
    tptr += sizeof(struct slow_oam_common_header_t);
    tlen -= sizeof(struct slow_oam_common_header_t);

    code = EXTRACT_U_1(ptr.slow_oam_common_header->code);
    ND_PRINT("\n\tCode %s OAM PDU, Flags [%s]",
           tok2str(slow_oam_code_values, "Unknown (%u)", code),
           bittok2str(slow_oam_flag_values,
                      "none",
                      EXTRACT_BE_U_2(ptr.slow_oam_common_header->flags)));

    switch (code) {
    case SLOW_OAM_CODE_INFO:
        while (tlen > 0) {
            ptr.slow_oam_tlv_header = (const struct slow_oam_tlv_header_t *)tptr;
            if (tlen < sizeof(*ptr.slow_oam_tlv_header))
                goto tooshort;
            ND_TCHECK_SIZE(ptr.slow_oam_tlv_header);
            type = EXTRACT_U_1(ptr.slow_oam_tlv_header->type);
            length = EXTRACT_U_1(ptr.slow_oam_tlv_header->length);
            ND_PRINT("\n\t  %s Information Type (%u), length %u",
                   tok2str(slow_oam_info_type_values, "Reserved", type),
                   type,
                   length);

            if (type == SLOW_OAM_INFO_TYPE_END_OF_TLV) {
                /*
                 * As IEEE Std 802.3-2015 says for the End of TLV Marker,
                 * "(the length and value of the Type 0x00 TLV can be ignored)".
                 */
                return;
            }

            /* length includes the type and length fields */
            if (length < sizeof(struct slow_oam_tlv_header_t)) {
                ND_PRINT("\n\t    ERROR: illegal length - should be >= %u",
                       (u_int)sizeof(struct slow_oam_tlv_header_t));
                return;
            }

            if (tlen < length)
                goto tooshort;
            ND_TCHECK_LEN(tptr, length);

            hexdump = FALSE;
            switch (type) {
            case SLOW_OAM_INFO_TYPE_LOCAL: /* identical format - fall through */
            case SLOW_OAM_INFO_TYPE_REMOTE:
                tlv.slow_oam_info = (const struct slow_oam_info_t *)tptr;

                if (EXTRACT_U_1(tlv.slow_oam_info->info_length) !=
                    sizeof(struct slow_oam_info_t)) {
                    ND_PRINT("\n\t    ERROR: illegal length - should be %lu",
                           (unsigned long) sizeof(struct slow_oam_info_t));
                    hexdump = TRUE;
                    goto badlength_code_info;
                }

                ND_PRINT("\n\t    OAM-Version %u, Revision %u",
                       EXTRACT_U_1(tlv.slow_oam_info->oam_version),
                       EXTRACT_BE_U_2(tlv.slow_oam_info->revision));

                state = EXTRACT_U_1(tlv.slow_oam_info->state);
                ND_PRINT("\n\t    State-Parser-Action %s, State-MUX-Action %s",
                       tok2str(slow_oam_info_type_state_parser_values, "Reserved",
                               state & OAM_INFO_TYPE_PARSER_MASK),
                       tok2str(slow_oam_info_type_state_mux_values, "Reserved",
                               state & OAM_INFO_TYPE_MUX_MASK));
                ND_PRINT("\n\t    OAM-Config Flags [%s], OAM-PDU-Config max-PDU size %u",
                       bittok2str(slow_oam_info_type_oam_config_values, "none",
                                  EXTRACT_U_1(tlv.slow_oam_info->oam_config)),
                       EXTRACT_BE_U_2(tlv.slow_oam_info->oam_pdu_config) &
                       OAM_INFO_TYPE_PDU_SIZE_MASK);
                ND_PRINT("\n\t    OUI %s (0x%06x), Vendor-Private 0x%08x",
                       tok2str(oui_values, "Unknown",
                               EXTRACT_BE_U_3(tlv.slow_oam_info->oui)),
                       EXTRACT_BE_U_3(tlv.slow_oam_info->oui),
                       EXTRACT_BE_U_4(tlv.slow_oam_info->vendor_private));
                break;

            case SLOW_OAM_INFO_TYPE_ORG_SPECIFIC:
                hexdump = TRUE;
                break;

            default:
                hexdump = TRUE;
                break;
            }

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

            tlen -= length;
            tptr += length;
        }
        break;

    case SLOW_OAM_CODE_EVENT_NOTIF:
        /* Sequence number */
        if (tlen < 2)
            goto tooshort;
        ND_TCHECK_2(tptr);
        ND_PRINT("\n\t  Sequence Number %u", EXTRACT_BE_U_2(tptr));
        tlen -= 2;
        tptr += 2;

        /* TLVs */
        while (tlen > 0) {
            ptr.slow_oam_tlv_header = (const struct slow_oam_tlv_header_t *)tptr;
            if (tlen < sizeof(*ptr.slow_oam_tlv_header))
                goto tooshort;
            ND_TCHECK_SIZE(ptr.slow_oam_tlv_header);
            type = EXTRACT_U_1(ptr.slow_oam_tlv_header->type);
            length = EXTRACT_U_1(ptr.slow_oam_tlv_header->length);
            ND_PRINT("\n\t  %s Link Event Type (%u), length %u",
                   tok2str(slow_oam_link_event_values, "Reserved",
                           type),
                   type,
                   length);

            if (type == SLOW_OAM_INFO_TYPE_END_OF_TLV) {
                /*
                 * As IEEE Std 802.3-2015 says for the End of TLV Marker,
                 * "(the length and value of the Type 0x00 TLV can be ignored)".
                 */
                return;
            }

            /* length includes the type and length fields */
            if (length < sizeof(struct slow_oam_tlv_header_t)) {
                ND_PRINT("\n\t    ERROR: illegal length - should be >= %u",
                       (u_int)sizeof(struct slow_oam_tlv_header_t));
                return;
            }

            if (tlen < length)
                goto tooshort;
            ND_TCHECK_LEN(tptr, length);

            hexdump = FALSE;
            switch (type) {
            case SLOW_OAM_LINK_EVENT_ERR_SYM_PER: /* identical format - fall through */
            case SLOW_OAM_LINK_EVENT_ERR_FRM:
            case SLOW_OAM_LINK_EVENT_ERR_FRM_PER:
            case SLOW_OAM_LINK_EVENT_ERR_FRM_SUMM:
                tlv.slow_oam_link_event = (const struct slow_oam_link_event_t *)tptr;

                if (EXTRACT_U_1(tlv.slow_oam_link_event->event_length) !=
                    sizeof(struct slow_oam_link_event_t)) {
                    ND_PRINT("\n\t    ERROR: illegal length - should be %lu",
                           (unsigned long) sizeof(struct slow_oam_link_event_t));
                    hexdump = TRUE;
                    goto badlength_event_notif;
                }

                ND_PRINT("\n\t    Timestamp %u ms, Errored Window %" PRIu64
                       "\n\t    Errored Threshold %" PRIu64
                       "\n\t    Errors %" PRIu64
                       "\n\t    Error Running Total %" PRIu64
                       "\n\t    Event Running Total %u",
                       EXTRACT_BE_U_2(tlv.slow_oam_link_event->time_stamp)*100,
                       EXTRACT_BE_U_8(tlv.slow_oam_link_event->window),
                       EXTRACT_BE_U_8(tlv.slow_oam_link_event->threshold),
                       EXTRACT_BE_U_8(tlv.slow_oam_link_event->errors),
                       EXTRACT_BE_U_8(tlv.slow_oam_link_event->errors_running_total),
                       EXTRACT_BE_U_4(tlv.slow_oam_link_event->event_running_total));
                break;

            case SLOW_OAM_LINK_EVENT_ORG_SPECIFIC:
                hexdump = TRUE;
                break;

            default:
                hexdump = TRUE;
                break;
            }

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

            tlen -= length;
            tptr += length;
        }
        break;

    case SLOW_OAM_CODE_LOOPBACK_CTRL:
        tlv.slow_oam_loopbackctrl = (const struct slow_oam_loopbackctrl_t *)tptr;
        if (tlen < sizeof(*tlv.slow_oam_loopbackctrl))
            goto tooshort;
        ND_TCHECK_SIZE(tlv.slow_oam_loopbackctrl);
        command = EXTRACT_U_1(tlv.slow_oam_loopbackctrl->command);
        ND_PRINT("\n\t  Command %s (%u)",
               tok2str(slow_oam_loopbackctrl_cmd_values,
                       "Unknown",
                       command),
               command);
        tptr ++;
        tlen --;
        break;

        /*
         * FIXME those are the defined codes that lack a decoder
         * you are welcome to contribute code ;-)
         */
    case SLOW_OAM_CODE_VAR_REQUEST:
    case SLOW_OAM_CODE_VAR_RESPONSE:
    case SLOW_OAM_CODE_PRIVATE:
    default:
        if (ndo->ndo_vflag <= 1) {
            print_unknown_data(ndo, tptr, "\n\t  ", tlen);
        }
        break;
    }
    return;

tooshort:
    ND_PRINT("\n\t\t packet is too short");
    return;

trunc:
    ND_PRINT("%s", tstr);
}
Ejemplo n.º 15
0
u_int
chdlc_print(netdissect_options *ndo, const u_char *p, u_int length)
{
	u_int proto;
	const u_char *bp = p;

	if (length < CHDLC_HDRLEN)
		goto trunc;
	ND_TCHECK_LEN(p, CHDLC_HDRLEN);
	proto = EXTRACT_BE_U_2(p + 2);
	if (ndo->ndo_eflag) {
                ND_PRINT("%s, ethertype %s (0x%04x), length %u: ",
                       tok2str(chdlc_cast_values, "0x%02x", EXTRACT_U_1(p)),
                       tok2str(ethertype_values, "Unknown", proto),
                       proto,
                       length);
	}

	length -= CHDLC_HDRLEN;
	p += CHDLC_HDRLEN;

	switch (proto) {
	case ETHERTYPE_IP:
		ip_print(ndo, p, length);
		break;
	case ETHERTYPE_IPV6:
		ip6_print(ndo, p, length);
		break;
	case CHDLC_TYPE_SLARP:
		chdlc_slarp_print(ndo, p, length);
		break;
#if 0
	case CHDLC_TYPE_CDP:
		chdlc_cdp_print(p, length);
		break;
#endif
        case ETHERTYPE_MPLS:
        case ETHERTYPE_MPLS_MULTI:
                mpls_print(ndo, p, length);
		break;
        case ETHERTYPE_ISO:
                /* is the fudge byte set ? lets verify by spotting ISO headers */
                if (length < 2)
                    goto trunc;
                ND_TCHECK_2(p);
                if (EXTRACT_U_1(p + 1) == NLPID_CLNP ||
                    EXTRACT_U_1(p + 1) == NLPID_ESIS ||
                    EXTRACT_U_1(p + 1) == NLPID_ISIS)
                    isoclns_print(ndo, p + 1, length - 1);
                else
                    isoclns_print(ndo, p, length);
                break;
	default:
                if (!ndo->ndo_eflag)
                        ND_PRINT("unknown CHDLC protocol (0x%04x)", proto);
                break;
	}

	return (CHDLC_HDRLEN);

trunc:
	ND_PRINT("[|chdlc]");
	return ndo->ndo_snapend - bp;
}
Ejemplo n.º 16
0
/* Standard PPP printer */
u_int
ppp_print(netdissect_options *ndo,
          const u_char *p, u_int length)
{
	u_int proto,ppp_header;
        u_int olen = length; /* _o_riginal length */
	u_int hdr_len = 0;

	/*
	 * Here, we assume that p points to the Address and Control
	 * field (if they present).
	 */
	if (length < 2)
		goto trunc;
	ND_TCHECK_2(p);
        ppp_header = EXTRACT_BE_U_2(p);

        switch(ppp_header) {
        case (PPP_WITHDIRECTION_IN  << 8 | PPP_CONTROL):
            if (ndo->ndo_eflag) ND_PRINT("In  ");
            p += 2;
            length -= 2;
            hdr_len += 2;
            break;
        case (PPP_WITHDIRECTION_OUT << 8 | PPP_CONTROL):
            if (ndo->ndo_eflag) ND_PRINT("Out ");
            p += 2;
            length -= 2;
            hdr_len += 2;
            break;
        case (PPP_ADDRESS << 8 | PPP_CONTROL):
            p += 2;			/* ACFC not used */
            length -= 2;
            hdr_len += 2;
            break;

        default:
            break;
        }

	if (length < 2)
		goto trunc;
	ND_TCHECK_1(p);
	if (EXTRACT_U_1(p) % 2) {
		proto = EXTRACT_U_1(p);	/* PFC is used */
		p++;
		length--;
		hdr_len++;
	} else {
		ND_TCHECK_2(p);
		proto = EXTRACT_BE_U_2(p);
		p += 2;
		length -= 2;
		hdr_len += 2;
	}

	if (ndo->ndo_eflag)
		ND_PRINT("%s (0x%04x), length %u: ",
		          tok2str(ppptype2str, "unknown", proto),
		          proto,
		          olen);

	handle_ppp(ndo, proto, p, length);
	return (hdr_len);
trunc:
	ND_PRINT("[|ppp]");
	return (0);
}
Ejemplo n.º 17
0
/* PAP (see RFC 1334) */
static void
handle_pap(netdissect_options *ndo,
           const u_char *p, u_int length)
{
	u_int code, len;
	u_int peerid_len, passwd_len, msg_len;
	const u_char *p0;
	u_int i;

	p0 = p;
	if (length < 1) {
		ND_PRINT("[|pap]");
		return;
	} else if (length < 4) {
		ND_TCHECK_1(p);
		ND_PRINT("[|pap 0x%02x]", EXTRACT_U_1(p));
		return;
	}

	ND_TCHECK_1(p);
	code = EXTRACT_U_1(p);
	ND_PRINT("PAP, %s (0x%02x)",
	          tok2str(papcode_values, "unknown", code),
	          code);
	p++;

	ND_TCHECK_1(p);
	ND_PRINT(", id %u", EXTRACT_U_1(p));	/* ID */
	p++;

	ND_TCHECK_2(p);
	len = EXTRACT_BE_U_2(p);
	p += 2;

	if (len > length) {
		ND_PRINT(", length %u > packet size", len);
		return;
	}
	length = len;
	if (length < (size_t)(p - p0)) {
		ND_PRINT(", length %u < PAP header length", length);
		return;
	}

	switch (code) {
	case PAP_AREQ:
		/* A valid Authenticate-Request is 6 or more octets long. */
		if (len < 6)
			goto trunc;
		if (length - (p - p0) < 1)
			return;
		ND_TCHECK_1(p);
		peerid_len = EXTRACT_U_1(p);	/* Peer-ID Length */
		p++;
		if (length - (p - p0) < peerid_len)
			return;
		ND_PRINT(", Peer ");
		for (i = 0; i < peerid_len; i++) {
			ND_TCHECK_1(p);
			safeputchar(ndo, EXTRACT_U_1(p));
			p++;
		}

		if (length - (p - p0) < 1)
			return;
		ND_TCHECK_1(p);
		passwd_len = EXTRACT_U_1(p);	/* Password Length */
		p++;
		if (length - (p - p0) < passwd_len)
			return;
		ND_PRINT(", Name ");
		for (i = 0; i < passwd_len; i++) {
			ND_TCHECK_1(p);
			safeputchar(ndo, EXTRACT_U_1(p));
			p++;
		}
		break;
	case PAP_AACK:
	case PAP_ANAK:
		/* Although some implementations ignore truncation at
		 * this point and at least one generates a truncated
		 * packet, RFC 1334 section 2.2.2 clearly states that
		 * both AACK and ANAK are at least 5 bytes long.
		 */
		if (len < 5)
			goto trunc;
		if (length - (p - p0) < 1)
			return;
		ND_TCHECK_1(p);
		msg_len = EXTRACT_U_1(p);	/* Msg-Length */
		p++;
		if (length - (p - p0) < msg_len)
			return;
		ND_PRINT(", Msg ");
		for (i = 0; i< msg_len; i++) {
			ND_TCHECK_1(p);
			safeputchar(ndo, EXTRACT_U_1(p));
			p++;
		}
		break;
	}
	return;

trunc:
	ND_PRINT("[|pap]");
}
Ejemplo n.º 18
0
/* generic Control Protocol (e.g. LCP, IPCP, CCP, etc.) handler */
static void
handle_ctrl_proto(netdissect_options *ndo,
                  u_int proto, const u_char *pptr, u_int length)
{
	const char *typestr;
	u_int code, len;
	u_int (*pfunc)(netdissect_options *, const u_char *, u_int);
	u_int x, j;
        const u_char *tptr;

        tptr=pptr;

        typestr = tok2str(ppptype2str, "unknown ctrl-proto (0x%04x)", proto);
	ND_PRINT("%s, ", typestr);

	if (length < 4) /* FIXME weak boundary checking */
		goto trunc;
	ND_TCHECK_2(tptr);

	code = EXTRACT_U_1(tptr);
	tptr++;

	ND_PRINT("%s (0x%02x), id %u, length %u",
	          tok2str(cpcodes, "Unknown Opcode",code),
	          code,
	          EXTRACT_U_1(tptr), /* ID */
	          length + 2);
	tptr++;

	if (!ndo->ndo_vflag)
		return;

	ND_TCHECK_2(tptr);
	len = EXTRACT_BE_U_2(tptr);
	tptr += 2;

	if (len < 4) {
		ND_PRINT("\n\tencoded length %u (< 4))", len);
		return;
	}

	if (len > length) {
		ND_PRINT("\n\tencoded length %u (> packet length %u))", len, length);
		return;
	}
	length = len;

	ND_PRINT("\n\tencoded length %u (=Option(s) length %u)", len, len - 4);

	if (length == 4)
		return;    /* there may be a NULL confreq etc. */

	if (ndo->ndo_vflag > 1)
		print_unknown_data(ndo, pptr - 2, "\n\t", 6);


	switch (code) {
	case CPCODES_VEXT:
		if (length < 11)
			break;
		ND_TCHECK_4(tptr);
		ND_PRINT("\n\t  Magic-Num 0x%08x", EXTRACT_BE_U_4(tptr));
		tptr += 4;
		ND_TCHECK_3(tptr);
		ND_PRINT(" Vendor: %s (%u)",
                       tok2str(oui_values,"Unknown",EXTRACT_BE_U_3(tptr)),
                       EXTRACT_BE_U_3(tptr));
		/* XXX: need to decode Kind and Value(s)? */
		break;
	case CPCODES_CONF_REQ:
	case CPCODES_CONF_ACK:
	case CPCODES_CONF_NAK:
	case CPCODES_CONF_REJ:
		x = len - 4;	/* Code(1), Identifier(1) and Length(2) */
		do {
			switch (proto) {
			case PPP_LCP:
				pfunc = print_lcp_config_options;
				break;
			case PPP_IPCP:
				pfunc = print_ipcp_config_options;
				break;
			case PPP_IPV6CP:
				pfunc = print_ip6cp_config_options;
				break;
			case PPP_CCP:
				pfunc = print_ccp_config_options;
				break;
			case PPP_BACP:
				pfunc = print_bacp_config_options;
				break;
			default:
				/*
				 * No print routine for the options for
				 * this protocol.
				 */
				pfunc = NULL;
				break;
			}

			if (pfunc == NULL) /* catch the above null pointer if unknown CP */
				break;

			if ((j = (*pfunc)(ndo, tptr, len)) == 0)
				break;
			x -= j;
			tptr += j;
		} while (x != 0);
		break;

	case CPCODES_TERM_REQ:
	case CPCODES_TERM_ACK:
		/* XXX: need to decode Data? */
		break;
	case CPCODES_CODE_REJ:
		/* XXX: need to decode Rejected-Packet? */
		break;
	case CPCODES_PROT_REJ:
		if (length < 6)
			break;
		ND_TCHECK_2(tptr);
		ND_PRINT("\n\t  Rejected %s Protocol (0x%04x)",
		       tok2str(ppptype2str,"unknown", EXTRACT_BE_U_2(tptr)),
		       EXTRACT_BE_U_2(tptr));
		/* XXX: need to decode Rejected-Information? - hexdump for now */
		if (len > 6) {
			ND_PRINT("\n\t  Rejected Packet");
			print_unknown_data(ndo, tptr + 2, "\n\t    ", len - 2);
		}
		break;
	case CPCODES_ECHO_REQ:
	case CPCODES_ECHO_RPL:
	case CPCODES_DISC_REQ:
		if (length < 8)
			break;
		ND_TCHECK_4(tptr);
		ND_PRINT("\n\t  Magic-Num 0x%08x", EXTRACT_BE_U_4(tptr));
		/* XXX: need to decode Data? - hexdump for now */
		if (len > 8) {
			ND_PRINT("\n\t  -----trailing data-----");
			ND_TCHECK_LEN(tptr + 4, len - 8);
			print_unknown_data(ndo, tptr + 4, "\n\t  ", len - 8);
		}
		break;
	case CPCODES_ID:
		if (length < 8)
			break;
		ND_TCHECK_4(tptr);
		ND_PRINT("\n\t  Magic-Num 0x%08x", EXTRACT_BE_U_4(tptr));
		/* RFC 1661 says this is intended to be human readable */
		if (len > 8) {
			ND_PRINT("\n\t  Message\n\t    ");
			if (fn_printn(ndo, tptr + 4, len - 4, ndo->ndo_snapend))
				goto trunc;
		}
		break;
	case CPCODES_TIME_REM:
		if (length < 12)
			break;
		ND_TCHECK_4(tptr);
		ND_PRINT("\n\t  Magic-Num 0x%08x", EXTRACT_BE_U_4(tptr));
		ND_TCHECK_4(tptr + 4);
		ND_PRINT(", Seconds-Remaining %us", EXTRACT_BE_U_4(tptr + 4));
		/* XXX: need to decode Message? */
		break;
	default:
		/* XXX this is dirty but we do not get the
		 * original pointer passed to the begin
		 * the PPP packet */
		if (ndo->ndo_vflag <= 1)
			print_unknown_data(ndo, pptr - 2, "\n\t  ", length + 2);
		break;
	}
	return;

trunc:
	ND_PRINT("[|%s]", typestr);
}
Ejemplo n.º 19
0
/* CHAP */
static void
handle_chap(netdissect_options *ndo,
            const u_char *p, u_int length)
{
	u_int code, len;
	u_int val_size, name_size, msg_size;
	const u_char *p0;
	u_int i;

	p0 = p;
	if (length < 1) {
		ND_PRINT("[|chap]");
		return;
	} else if (length < 4) {
		ND_TCHECK_1(p);
		ND_PRINT("[|chap 0x%02x]", EXTRACT_U_1(p));
		return;
	}

	ND_TCHECK_1(p);
	code = EXTRACT_U_1(p);
	ND_PRINT("CHAP, %s (0x%02x)",
               tok2str(chapcode_values,"unknown",code),
               code);
	p++;

	ND_TCHECK_1(p);
	ND_PRINT(", id %u", EXTRACT_U_1(p));	/* ID */
	p++;

	ND_TCHECK_2(p);
	len = EXTRACT_BE_U_2(p);
	p += 2;

	/*
	 * Note that this is a generic CHAP decoding routine. Since we
	 * don't know which flavor of CHAP (i.e. CHAP-MD5, MS-CHAPv1,
	 * MS-CHAPv2) is used at this point, we can't decode packet
	 * specifically to each algorithms. Instead, we simply decode
	 * the GCD (Gratest Common Denominator) for all algorithms.
	 */
	switch (code) {
	case CHAP_CHAL:
	case CHAP_RESP:
		if (length - (p - p0) < 1)
			return;
		ND_TCHECK_1(p);
		val_size = EXTRACT_U_1(p);	/* value size */
		p++;
		if (length - (p - p0) < val_size)
			return;
		ND_PRINT(", Value ");
		for (i = 0; i < val_size; i++) {
			ND_TCHECK_1(p);
			ND_PRINT("%02x", EXTRACT_U_1(p));
			p++;
		}
		name_size = len - (p - p0);
		ND_PRINT(", Name ");
		for (i = 0; i < name_size; i++) {
			ND_TCHECK_1(p);
			safeputchar(ndo, EXTRACT_U_1(p));
			p++;
		}
		break;
	case CHAP_SUCC:
	case CHAP_FAIL:
		msg_size = len - (p - p0);
		ND_PRINT(", Msg ");
		for (i = 0; i< msg_size; i++) {
			ND_TCHECK_1(p);
			safeputchar(ndo, EXTRACT_U_1(p));
			p++;
		}
		break;
	}
	return;

trunc:
	ND_PRINT("[|chap]");
}
Ejemplo n.º 20
0
/* CCP config options */
static u_int
print_ccp_config_options(netdissect_options *ndo,
                         const u_char *p, u_int length)
{
	u_int opt, len;

	if (length < 2)
		return 0;
	ND_TCHECK_2(p);
	opt = EXTRACT_U_1(p);
	len = EXTRACT_U_1(p + 1);
	if (length < len)
		return 0;
	if (len < 2) {
		ND_PRINT("\n\t  %s Option (0x%02x), length %u (length bogus, should be >= 2)",
		          tok2str(ccpconfopts_values, "Unknown", opt),
		          opt,
		          len);
		return 0;
	}

	ND_PRINT("\n\t  %s Option (0x%02x), length %u",
	          tok2str(ccpconfopts_values, "Unknown", opt),
	          opt,
	          len);

	switch (opt) {
	case CCPOPT_BSDCOMP:
		if (len < 3) {
			ND_PRINT(" (length bogus, should be >= 3)");
			return len;
		}
		ND_TCHECK_1(p + 2);
		ND_PRINT(": Version: %u, Dictionary Bits: %u",
			EXTRACT_U_1(p + 2) >> 5,
			EXTRACT_U_1(p + 2) & 0x1f);
		break;
	case CCPOPT_MVRCA:
		if (len < 4) {
			ND_PRINT(" (length bogus, should be >= 4)");
			return len;
		}
		ND_TCHECK_1(p + 3);
		ND_PRINT(": Features: %u, PxP: %s, History: %u, #CTX-ID: %u",
				(EXTRACT_U_1(p + 2) & 0xc0) >> 6,
				(EXTRACT_U_1(p + 2) & 0x20) ? "Enabled" : "Disabled",
				EXTRACT_U_1(p + 2) & 0x1f,
				EXTRACT_U_1(p + 3));
		break;
	case CCPOPT_DEFLATE:
		if (len < 4) {
			ND_PRINT(" (length bogus, should be >= 4)");
			return len;
		}
		ND_TCHECK_1(p + 3);
		ND_PRINT(": Window: %uK, Method: %s (0x%x), MBZ: %u, CHK: %u",
			(EXTRACT_U_1(p + 2) & 0xf0) >> 4,
			((EXTRACT_U_1(p + 2) & 0x0f) == 8) ? "zlib" : "unknown",
			EXTRACT_U_1(p + 2) & 0x0f,
			(EXTRACT_U_1(p + 3) & 0xfc) >> 2,
			EXTRACT_U_1(p + 3) & 0x03);
		break;

/* XXX: to be supported */
#if 0
	case CCPOPT_OUI:
	case CCPOPT_PRED1:
	case CCPOPT_PRED2:
	case CCPOPT_PJUMP:
	case CCPOPT_HPPPC:
	case CCPOPT_STACLZS:
	case CCPOPT_MPPC:
	case CCPOPT_GFZA:
	case CCPOPT_V42BIS:
	case CCPOPT_LZSDCP:
	case CCPOPT_DEC:
	case CCPOPT_RESV:
		break;
#endif
	default:
		/*
		 * Unknown option; dump it as raw bytes now if we're
		 * not going to do so below.
		 */
		if (ndo->ndo_vflag < 2)
			print_unknown_data(ndo, p + 2, "\n\t    ", len - 2);
		break;
	}
	if (ndo->ndo_vflag > 1)
		print_unknown_data(ndo, p + 2, "\n\t    ", len - 2); /* exclude TLV header */

	return len;

trunc:
	ND_PRINT("[|ccp]");
	return 0;
}
Ejemplo n.º 21
0
static int
stp_print_mstp_bpdu(netdissect_options *ndo, const struct stp_bpdu_ *stp_bpdu,
                    u_int length)
{
    const u_char *ptr;
    uint8_t	    bpdu_flags;
    uint16_t	    v3len;
    uint16_t	    len;
    uint16_t	    msti;
    u_int	    offset;

    ptr = (const u_char *)stp_bpdu;
    ND_TCHECK_1(stp_bpdu->flags);
    bpdu_flags = EXTRACT_U_1(stp_bpdu->flags);
    ND_PRINT(", CIST Flags [%s], length %u",
           bittok2str(stp_bpdu_flag_values, "none", bpdu_flags), length);

    /*
     * in non-verbose mode just print the flags.
     */
    if (!ndo->ndo_vflag) {
        return 1;
    }

    ND_PRINT("\n\tport-role %s, ",
           tok2str(rstp_obj_port_role_values, "Unknown",
                   RSTP_EXTRACT_PORT_ROLE(bpdu_flags)));

    ND_TCHECK_4(stp_bpdu->root_path_cost);
    ND_PRINT("CIST root-id %s, CIST ext-pathcost %u",
           stp_print_bridge_id((const u_char *)&stp_bpdu->root_id),
           EXTRACT_BE_U_4(stp_bpdu->root_path_cost));

    ND_TCHECK_SIZE(&stp_bpdu->bridge_id);
    ND_PRINT("\n\tCIST regional-root-id %s, ",
           stp_print_bridge_id((const u_char *)&stp_bpdu->bridge_id));

    ND_TCHECK_2(stp_bpdu->port_id);
    ND_PRINT("CIST port-id %04x,", EXTRACT_BE_U_2(stp_bpdu->port_id));

    ND_TCHECK_2(stp_bpdu->forward_delay);
    ND_PRINT("\n\tmessage-age %.2fs, max-age %.2fs"
           ", hello-time %.2fs, forwarding-delay %.2fs",
           (float) EXTRACT_BE_U_2(stp_bpdu->message_age) / STP_TIME_BASE,
           (float) EXTRACT_BE_U_2(stp_bpdu->max_age) / STP_TIME_BASE,
           (float) EXTRACT_BE_U_2(stp_bpdu->hello_time) / STP_TIME_BASE,
           (float) EXTRACT_BE_U_2(stp_bpdu->forward_delay) / STP_TIME_BASE);

    ND_TCHECK_2(ptr + MST_BPDU_VER3_LEN_OFFSET);
    ND_PRINT("\n\tv3len %u, ", EXTRACT_BE_U_2(ptr + MST_BPDU_VER3_LEN_OFFSET));
    ND_TCHECK_4(ptr + MST_BPDU_CONFIG_DIGEST_OFFSET + 12);
    ND_PRINT("MCID Name ");
    if (fn_printzp(ndo, ptr + MST_BPDU_CONFIG_NAME_OFFSET, 32, ndo->ndo_snapend))
	goto trunc;
    ND_PRINT(", rev %u,"
            "\n\t\tdigest %08x%08x%08x%08x, ",
	          EXTRACT_BE_U_2(ptr + MST_BPDU_CONFIG_NAME_OFFSET + 32),
	          EXTRACT_BE_U_4(ptr + MST_BPDU_CONFIG_DIGEST_OFFSET),
	          EXTRACT_BE_U_4(ptr + MST_BPDU_CONFIG_DIGEST_OFFSET + 4),
	          EXTRACT_BE_U_4(ptr + MST_BPDU_CONFIG_DIGEST_OFFSET + 8),
	          EXTRACT_BE_U_4(ptr + MST_BPDU_CONFIG_DIGEST_OFFSET + 12));

    ND_TCHECK_4(ptr + MST_BPDU_CIST_INT_PATH_COST_OFFSET);
    ND_PRINT("CIST int-root-pathcost %u,",
            EXTRACT_BE_U_4(ptr + MST_BPDU_CIST_INT_PATH_COST_OFFSET));

    ND_TCHECK_BRIDGE_ID(ptr + MST_BPDU_CIST_BRIDGE_ID_OFFSET);
    ND_PRINT("\n\tCIST bridge-id %s, ",
           stp_print_bridge_id(ptr + MST_BPDU_CIST_BRIDGE_ID_OFFSET));

    ND_TCHECK_1(ptr + MST_BPDU_CIST_REMAIN_HOPS_OFFSET);
    ND_PRINT("CIST remaining-hops %u", EXTRACT_U_1(ptr + MST_BPDU_CIST_REMAIN_HOPS_OFFSET));

    /* Dump all MSTI's */
    ND_TCHECK_2(ptr + MST_BPDU_VER3_LEN_OFFSET);
    v3len = EXTRACT_BE_U_2(ptr + MST_BPDU_VER3_LEN_OFFSET);
    if (v3len > MST_BPDU_CONFIG_INFO_LENGTH) {
        len = v3len - MST_BPDU_CONFIG_INFO_LENGTH;
        offset = MST_BPDU_MSTI_OFFSET;
        while (len >= MST_BPDU_MSTI_LENGTH) {
            ND_TCHECK_LEN(ptr + offset, MST_BPDU_MSTI_LENGTH);

            msti = EXTRACT_BE_U_2(ptr + offset + MST_BPDU_MSTI_ROOT_PRIO_OFFSET);
            msti = msti & 0x0FFF;

            ND_PRINT("\n\tMSTI %u, Flags [%s], port-role %s",
                   msti, bittok2str(stp_bpdu_flag_values, "none", EXTRACT_U_1(ptr + offset)),
                   tok2str(rstp_obj_port_role_values, "Unknown",
                           RSTP_EXTRACT_PORT_ROLE(EXTRACT_U_1(ptr + offset))));
            ND_PRINT("\n\t\tMSTI regional-root-id %s, pathcost %u",
                   stp_print_bridge_id(ptr + offset +
                                       MST_BPDU_MSTI_ROOT_PRIO_OFFSET),
                   EXTRACT_BE_U_4(ptr + offset + MST_BPDU_MSTI_ROOT_PATH_COST_OFFSET));
            ND_PRINT("\n\t\tMSTI bridge-prio %u, port-prio %u, hops %u",
                   EXTRACT_U_1(ptr + offset + MST_BPDU_MSTI_BRIDGE_PRIO_OFFSET) >> 4,
                   EXTRACT_U_1(ptr + offset + MST_BPDU_MSTI_PORT_PRIO_OFFSET) >> 4,
                   EXTRACT_U_1(ptr + offset + MST_BPDU_MSTI_REMAIN_HOPS_OFFSET));

            len -= MST_BPDU_MSTI_LENGTH;
            offset += MST_BPDU_MSTI_LENGTH;
        }
    }
Ejemplo n.º 22
0
static int
cdp_print_addr(netdissect_options *ndo,
	       const u_char * p, u_int l)
{
	u_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_TCHECK_4(p);
	if (p + 4 > endp)
		goto trunc;
	num = EXTRACT_BE_U_4(p);
	p += 4;

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

		ND_TCHECK_2(p + pl);
		if (p + pl + 2 > endp)
			goto trunc;
		al = EXTRACT_BE_U_2(p + pl);	/* address length */

		if (pt == PT_NLPID && pl == 1 && EXTRACT_U_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_TCHECK_4(p);
			if (p + 4 > endp)
				goto trunc;
			ND_PRINT("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_TCHECK_LEN(p, al);
			if (p + al > endp)
				goto trunc;

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

	return 0;

trunc:
	return -1;
}
Ejemplo n.º 23
0
void
vtp_print(netdissect_options *ndo,
          const u_char *pptr, u_int length)
{
    u_int type, len, name_len, tlv_len, tlv_value, mgmtd_len;
    const u_char *tptr;
    const struct vtp_vlan_ *vtp_vlan;

    ndo->ndo_protocol = "vtp";
    if (length < VTP_HEADER_LEN)
        goto trunc;

    tptr = pptr;

    ND_TCHECK_LEN(tptr, VTP_HEADER_LEN);

    type = EXTRACT_U_1(tptr + 1);
    ND_PRINT("VTPv%u, Message %s (0x%02x), length %u",
	   EXTRACT_U_1(tptr),
	   tok2str(vtp_message_type_values,"Unknown message type", type),
	   type,
	   length);

    /* In non-verbose mode, just print version and message type */
    if (ndo->ndo_vflag < 1) {
        return;
    }

    /* verbose mode print all fields */
    ND_PRINT("\n\tDomain name: ");
    mgmtd_len = EXTRACT_U_1(tptr + 3);
    if (mgmtd_len < 1 ||  mgmtd_len > 32) {
	ND_PRINT(" [invalid MgmtD Len %u]", mgmtd_len);
	return;
    }
    nd_printzp(ndo, tptr + 4, mgmtd_len, NULL);
    ND_PRINT(", %s: %u",
	   tok2str(vtp_header_values, "Unknown", type),
	   EXTRACT_U_1(tptr + 2));

    tptr += VTP_HEADER_LEN;

    switch (type) {

    case VTP_SUMMARY_ADV:

	/*
	 *  SUMMARY ADVERTISEMENT
	 *
	 *  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   |     Code      |    Followers  |    MgmtD Len  |
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *  |       Management Domain Name  (zero-padded to 32 bytes)       |
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *  |                    Configuration revision number              |
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *  |                  Updater Identity IP address                  |
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *  |                    Update Timestamp (12 bytes)                |
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *  |                        MD5 digest (16 bytes)                  |
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *
	 */

	ND_TCHECK_8(tptr);
	ND_PRINT("\n\t  Config Rev %x, Updater %s",
	       EXTRACT_BE_U_4(tptr),
	       ipaddr_string(ndo, tptr+4));
	tptr += 8;
	ND_TCHECK_LEN(tptr, VTP_UPDATE_TIMESTAMP_LEN);
	ND_PRINT(", Timestamp 0x%08x 0x%08x 0x%08x",
	       EXTRACT_BE_U_4(tptr),
	       EXTRACT_BE_U_4(tptr + 4),
	       EXTRACT_BE_U_4(tptr + 8));
	tptr += VTP_UPDATE_TIMESTAMP_LEN;
	ND_TCHECK_LEN(tptr, VTP_MD5_DIGEST_LEN);
	ND_PRINT(", MD5 digest: %08x%08x%08x%08x",
	       EXTRACT_BE_U_4(tptr),
	       EXTRACT_BE_U_4(tptr + 4),
	       EXTRACT_BE_U_4(tptr + 8),
	       EXTRACT_BE_U_4(tptr + 12));
	tptr += VTP_MD5_DIGEST_LEN;
	break;

    case VTP_SUBSET_ADV:

	/*
	 *  SUBSET ADVERTISEMENT
	 *
	 *  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   |     Code      |   Seq number  |    MgmtD Len  |
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *  |       Management Domain Name  (zero-padded to 32 bytes)       |
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *  |                    Configuration revision number              |
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *  |                         VLAN info field 1                     |
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *  |                         ................                      |
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *  |                         VLAN info field N                     |
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *
	 */

	ND_TCHECK_4(tptr);
	ND_PRINT(", Config Rev %x", EXTRACT_BE_U_4(tptr));

	/*
	 *  VLAN INFORMATION
	 *  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
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *  | V info len    |    Status     |  VLAN type    | VLAN name len |
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *  |       ISL vlan id             |            MTU size           |
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *  |                     802.10 index (SAID)                       |
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *  |                         VLAN name                             |
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *
	 */

	tptr += 4;
	while (tptr < (pptr+length)) {

	    ND_TCHECK_1(tptr);
	    len = EXTRACT_U_1(tptr);
	    if (len == 0)
		break;

	    ND_TCHECK_LEN(tptr, len);

	    vtp_vlan = (const struct vtp_vlan_*)tptr;
	    if (len < VTP_VLAN_INFO_FIXED_PART_LEN)
		goto trunc;
	    ND_TCHECK_SIZE(vtp_vlan);
	    ND_PRINT("\n\tVLAN info status %s, type %s, VLAN-id %u, MTU %u, SAID 0x%08x, Name ",
		   tok2str(vtp_vlan_status,"Unknown",EXTRACT_U_1(vtp_vlan->status)),
		   tok2str(vtp_vlan_type_values,"Unknown",EXTRACT_U_1(vtp_vlan->type)),
		   EXTRACT_BE_U_2(vtp_vlan->vlanid),
		   EXTRACT_BE_U_2(vtp_vlan->mtu),
		   EXTRACT_BE_U_4(vtp_vlan->index));
	    len  -= VTP_VLAN_INFO_FIXED_PART_LEN;
	    tptr += VTP_VLAN_INFO_FIXED_PART_LEN;
	    name_len = EXTRACT_U_1(vtp_vlan->name_len);
	    if (len < 4*((name_len + 3)/4))
		goto trunc;
	    ND_TCHECK_LEN(tptr, name_len);
	    nd_printzp(ndo, tptr, name_len, NULL);

	    /*
	     * Vlan names are aligned to 32-bit boundaries.
	     */
	    len  -= 4*((name_len + 3)/4);
	    tptr += 4*((name_len + 3)/4);

            /* TLV information follows */

            while (len > 0) {

                /*
                 * Cisco specs say 2 bytes for type + 2 bytes for length;
                 * see http://docstore.mik.ua/univercd/cc/td/doc/product/lan/trsrb/frames.htm
                 * However, actual packets on the wire appear to use 1
                 * byte for the type and 1 byte for the length, so that's
                 * what we do.
                 */
                if (len < 2)
                    goto trunc;
                ND_TCHECK_2(tptr);
                type = EXTRACT_U_1(tptr);
                tlv_len = EXTRACT_U_1(tptr + 1);

                ND_PRINT("\n\t\t%s (0x%04x) TLV",
                       tok2str(vtp_vlan_tlv_values, "Unknown", type),
                       type);

                if (len < tlv_len * 2 + 2) {
                    ND_PRINT(" (TLV goes past the end of the packet)");
                    return;
                }
                ND_TCHECK_LEN(tptr, tlv_len * 2 + 2);

                /*
                 * We assume the value is a 2-byte integer; the length is
                 * in units of 16-bit words.
                 */
                if (tlv_len != 1) {
                    ND_PRINT(" (invalid TLV length %u != 1)", tlv_len);
                    return;
                } else {
                    tlv_value = EXTRACT_BE_U_2(tptr + 2);

                    switch (type) {
                    case VTP_VLAN_STE_HOP_COUNT:
                        ND_PRINT(", %u", tlv_value);
                        break;

                    case VTP_VLAN_PRUNING:
                        ND_PRINT(", %s (%u)",
                               tlv_value == 1 ? "Enabled" : "Disabled",
                               tlv_value);
                        break;

                    case VTP_VLAN_STP_TYPE:
                        ND_PRINT(", %s (%u)",
                               tok2str(vtp_stp_type_values, "Unknown", tlv_value),
                               tlv_value);
                        break;

                    case VTP_VLAN_BRIDGE_TYPE:
                        ND_PRINT(", %s (%u)",
                               tlv_value == 1 ? "SRB" : "SRT",
                               tlv_value);
                        break;

                    case VTP_VLAN_BACKUP_CRF_MODE:
                        ND_PRINT(", %s (%u)",
                               tlv_value == 1 ? "Backup" : "Not backup",
                               tlv_value);
                        break;

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

                    case VTP_VLAN_SOURCE_ROUTING_RING_NUMBER:
                    case VTP_VLAN_SOURCE_ROUTING_BRIDGE_NUMBER:
                    case VTP_VLAN_PARENT_VLAN:
                    case VTP_VLAN_TRANS_BRIDGED_VLAN:
                    case VTP_VLAN_ARP_HOP_COUNT:
                    default:
                        print_unknown_data(ndo, tptr, "\n\t\t  ", 2 + tlv_len*2);
                        break;
                    }
                }
                len -= 2 + tlv_len*2;
                tptr += 2 + tlv_len*2;
            }
	}
	break;

    case VTP_ADV_REQUEST:

	/*
	 *  ADVERTISEMENT REQUEST
	 *
	 *  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   |     Code      |   Reserved    |    MgmtD Len  |
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *  |       Management Domain Name  (zero-padded to 32 bytes)       |
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *  |                          Start value                          |
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *
	 */

	ND_TCHECK_4(tptr);
	ND_PRINT("\n\tStart value: %u", EXTRACT_BE_U_4(tptr));
	break;

    case VTP_JOIN_MESSAGE:

	/* FIXME - Could not find message format */
	break;

    default:
	break;
    }

    return;

 trunc:
    nd_print_trunc(ndo);
}
Ejemplo n.º 24
0
static void
rfc1048_print(netdissect_options *ndo,
	      const u_char *bp)
{
	uint16_t tag;
	u_int len;
	const char *cp;
	char c;
	int first, idx;
	uint8_t subopt, suboptlen;

	ND_PRINT("\n\t  Vendor-rfc1048 Extensions");

	/* Step over magic cookie */
	ND_PRINT("\n\t    Magic Cookie 0x%08x", EXTRACT_BE_U_4(bp));
	bp += sizeof(int32_t);

	/* Loop while we there is a tag left in the buffer */
	while (ND_TTEST_1(bp)) {
		tag = EXTRACT_U_1(bp);
		bp++;
		if (tag == TAG_PAD && ndo->ndo_vflag < 3)
			continue;
		if (tag == TAG_END && ndo->ndo_vflag < 3)
			return;
		if (tag == TAG_EXTENDED_OPTION) {
			ND_TCHECK_2(bp + 1);
			tag = EXTRACT_BE_U_2(bp + 1);
			/* XXX we don't know yet if the IANA will
			 * preclude overlap of 1-byte and 2-byte spaces.
			 * If not, we need to offset tag after this step.
			 */
			cp = tok2str(xtag2str, "?xT%u", tag);
		} else
			cp = tok2str(tag2str, "?T%u", tag);
		c = *cp++;

		if (tag == TAG_PAD || tag == TAG_END)
			len = 0;
		else {
			/* Get the length; check for truncation */
			ND_TCHECK_1(bp);
			len = EXTRACT_U_1(bp);
			bp++;
		}

		ND_PRINT("\n\t    %s Option %u, length %u%s", cp, tag, len,
			  len > 0 ? ": " : "");

		if (tag == TAG_PAD && ndo->ndo_vflag > 2) {
			u_int ntag = 1;
			while (ND_TTEST_1(bp) &&
			       EXTRACT_U_1(bp) == TAG_PAD) {
				bp++;
				ntag++;
			}
			if (ntag > 1)
				ND_PRINT(", occurs %u", ntag);
		}

		ND_TCHECK_LEN(bp, len);

		if (tag == TAG_DHCP_MESSAGE && len == 1) {
			ND_PRINT("%s", tok2str(dhcp_msg_values, "Unknown (%u)", EXTRACT_U_1(bp)));
			bp++;
			continue;
		}

		if (tag == TAG_PARM_REQUEST) {
			idx = 0;
			while (len > 0) {
				cp = tok2str(tag2str, "?Option %u", EXTRACT_U_1(bp));
				bp++;
				len--;
				if (idx % 4 == 0)
					ND_PRINT("\n\t      ");
				else
					ND_PRINT(", ");
				ND_PRINT("%s", cp + 1);
				idx++;
			}
			continue;
		}

		if (tag == TAG_EXTENDED_REQUEST) {
			first = 1;
			while (len > 1) {
				cp = tok2str(xtag2str, "?xT%u", EXTRACT_BE_U_2(bp));
				bp += 2;
				len -= 2;
				if (!first)
					ND_PRINT("+");
				ND_PRINT("%s", cp + 1);
				first = 0;
			}
			continue;
		}

		/* Print data */
		if (c == '?') {
			/* Base default formats for unknown tags on data size */
			if (len & 1)
				c = 'b';
			else if (len & 2)
				c = 's';
			else
				c = 'l';
		}
		first = 1;
		switch (c) {

		case 'a':
			/* ASCII strings */
			ND_PRINT("\"");
			if (nd_printn(ndo, bp, len, ndo->ndo_snapend)) {
				ND_PRINT("\"");
				goto trunc;
			}
			ND_PRINT("\"");
			bp += len;
			len = 0;
			break;

		case 'i':
		case 'l':
		case 'L':
			/* ip addresses/32-bit words */
			while (len >= 4) {
				if (!first)
					ND_PRINT(",");
				if (c == 'i')
					ND_PRINT("%s", ipaddr_string(ndo, bp));
				else if (c == 'L')
					ND_PRINT("%d", EXTRACT_BE_S_4(bp));
				else
					ND_PRINT("%u", EXTRACT_BE_U_4(bp));
				bp += 4;
				len -= 4;
				first = 0;
			}
			break;

		case 'p':
			/* IP address pairs */
			while (len >= 2*4) {
				if (!first)
					ND_PRINT(",");
				ND_PRINT("(%s:", ipaddr_string(ndo, bp));
				bp += 4;
				len -= 4;
				ND_PRINT("%s)", ipaddr_string(ndo, bp));
				bp += 4;
				len -= 4;
				first = 0;
			}
			break;

		case 's':
			/* shorts */
			while (len >= 2) {
				if (!first)
					ND_PRINT(",");
				ND_PRINT("%u", EXTRACT_BE_U_2(bp));
				bp += 2;
				len -= 2;
				first = 0;
			}
			break;

		case 'B':
			/* boolean */
			while (len > 0) {
				uint8_t bool_value;
				if (!first)
					ND_PRINT(",");
				bool_value = EXTRACT_U_1(bp);
				switch (bool_value) {
				case 0:
					ND_PRINT("N");
					break;
				case 1:
					ND_PRINT("Y");
					break;
				default:
					ND_PRINT("%u?", bool_value);
					break;
				}
				++bp;
				--len;
				first = 0;
			}
			break;

		case 'b':
		case 'x':
		default:
			/* Bytes */
			while (len > 0) {
				uint8_t byte_value;
				if (!first)
					ND_PRINT(c == 'x' ? ":" : ".");
				byte_value = EXTRACT_U_1(bp);
				if (c == 'x')
					ND_PRINT("%02x", byte_value);
				else
					ND_PRINT("%u", byte_value);
				++bp;
				--len;
				first = 0;
			}
			break;

		case '$':
			/* Guys we can't handle with one of the usual cases */
			switch (tag) {

			case TAG_NETBIOS_NODE:
				/* this option should be at least 1 byte long */
				if (len < 1) {
					ND_PRINT("ERROR: length < 1 bytes");
					break;
				}
				tag = EXTRACT_U_1(bp);
				++bp;
				--len;
				ND_PRINT("%s", tok2str(nbo2str, NULL, tag));
				break;

			case TAG_OPT_OVERLOAD:
				/* this option should be at least 1 byte long */
				if (len < 1) {
					ND_PRINT("ERROR: length < 1 bytes");
					break;
				}
				tag = EXTRACT_U_1(bp);
				++bp;
				--len;
				ND_PRINT("%s", tok2str(oo2str, NULL, tag));
				break;

			case TAG_CLIENT_FQDN:
				/* this option should be at least 3 bytes long */
				if (len < 3) {
					ND_PRINT("ERROR: length < 3 bytes");
					bp += len;
					len = 0;
					break;
				}
				if (EXTRACT_U_1(bp))
					ND_PRINT("[%s] ", client_fqdn_flags(EXTRACT_U_1(bp)));
				bp++;
				if (EXTRACT_U_1(bp) || EXTRACT_U_1(bp + 1))
					ND_PRINT("%u/%u ", EXTRACT_U_1(bp), EXTRACT_U_1(bp + 1));
				bp += 2;
				ND_PRINT("\"");
				if (nd_printn(ndo, bp, len - 3, ndo->ndo_snapend)) {
					ND_PRINT("\"");
					goto trunc;
				}
				ND_PRINT("\"");
				bp += len - 3;
				len = 0;
				break;

			case TAG_CLIENT_ID:
			    {
				int type;

				/* this option should be at least 1 byte long */
				if (len < 1) {
					ND_PRINT("ERROR: length < 1 bytes");
					break;
				}
				type = EXTRACT_U_1(bp);
				bp++;
				len--;
				if (type == 0) {
					ND_PRINT("\"");
					if (nd_printn(ndo, bp, len, ndo->ndo_snapend)) {
						ND_PRINT("\"");
						goto trunc;
					}
					ND_PRINT("\"");
					bp += len;
					len = 0;
					break;
				} else {
					ND_PRINT("%s ", tok2str(arp2str, "hardware-type %u,", type));
					while (len > 0) {
						if (!first)
							ND_PRINT(":");
						ND_PRINT("%02x", EXTRACT_U_1(bp));
						++bp;
						--len;
						first = 0;
					}
				}
				break;
			    }

			case TAG_AGENT_CIRCUIT:
				while (len >= 2) {
					subopt = EXTRACT_U_1(bp);
					suboptlen = EXTRACT_U_1(bp + 1);
					bp += 2;
					len -= 2;
					if (suboptlen > len) {
						ND_PRINT("\n\t      %s SubOption %u, length %u: length goes past end of option",
							  tok2str(agent_suboption_values, "Unknown", subopt),
							  subopt,
							  suboptlen);
						bp += len;
						len = 0;
						break;
					}
					ND_PRINT("\n\t      %s SubOption %u, length %u: ",
						  tok2str(agent_suboption_values, "Unknown", subopt),
						  subopt,
						  suboptlen);
					switch (subopt) {

					case AGENT_SUBOPTION_CIRCUIT_ID: /* fall through */
					case AGENT_SUBOPTION_REMOTE_ID:
					case AGENT_SUBOPTION_SUBSCRIBER_ID:
						if (nd_printn(ndo, bp, suboptlen, ndo->ndo_snapend))
							goto trunc;
						break;

					default:
						print_unknown_data(ndo, bp, "\n\t\t", suboptlen);
					}

					len -= suboptlen;
					bp += suboptlen;
				}
				break;

			case TAG_CLASSLESS_STATIC_RT:
			case TAG_CLASSLESS_STA_RT_MS:
			    {
				u_int mask_width, significant_octets, i;

				/* this option should be at least 5 bytes long */
				if (len < 5) {
					ND_PRINT("ERROR: length < 5 bytes");
					bp += len;
					len = 0;
					break;
				}
				while (len > 0) {
					if (!first)
						ND_PRINT(",");
					mask_width = EXTRACT_U_1(bp);
					bp++;
					len--;
					/* mask_width <= 32 */
					if (mask_width > 32) {
						ND_PRINT("[ERROR: Mask width (%u) > 32]", mask_width);
						bp += len;
						len = 0;
						break;
					}
					significant_octets = (mask_width + 7) / 8;
					/* significant octets + router(4) */
					if (len < significant_octets + 4) {
						ND_PRINT("[ERROR: Remaining length (%u) < %u bytes]", len, significant_octets + 4);
						bp += len;
						len = 0;
						break;
					}
					ND_PRINT("(");
					if (mask_width == 0)
						ND_PRINT("default");
					else {
						for (i = 0; i < significant_octets ; i++) {
							if (i > 0)
								ND_PRINT(".");
							ND_PRINT("%u", EXTRACT_U_1(bp));
							bp++;
						}
						for (i = significant_octets ; i < 4 ; i++)
							ND_PRINT(".0");
						ND_PRINT("/%u", mask_width);
					}
					ND_PRINT(":%s)", ipaddr_string(ndo, bp));
					bp += 4;
					len -= (significant_octets + 4);
					first = 0;
				}
				break;
			    }

			case TAG_USER_CLASS:
			    {
				u_int suboptnumber = 1;

				first = 1;
				if (len < 2) {
					ND_PRINT("ERROR: length < 2 bytes");
					bp += len;
					len = 0;
					break;
				}
				while (len > 0) {
					suboptlen = EXTRACT_U_1(bp);
					bp++;
					len--;
					ND_PRINT("\n\t      ");
					ND_PRINT("instance#%u: ", suboptnumber);
					if (suboptlen == 0) {
						ND_PRINT("ERROR: suboption length must be non-zero");
						bp += len;
						len = 0;
						break;
					}
					if (len < suboptlen) {
						ND_PRINT("ERROR: invalid option");
						bp += len;
						len = 0;
						break;
					}
					ND_PRINT("\"");
					if (nd_printn(ndo, bp, suboptlen, ndo->ndo_snapend)) {
						ND_PRINT("\"");
						goto trunc;
					}
					ND_PRINT("\"");
					ND_PRINT(", length %u", suboptlen);
					suboptnumber++;
					len -= suboptlen;
					bp += suboptlen;
				}
				break;
			    }

			default:
				ND_PRINT("[unknown special tag %u, size %u]",
					  tag, len);
				bp += len;
				len = 0;
				break;
			}
			break;
		}
		/* Data left over? */
		if (len) {
			ND_PRINT("\n\t  trailing data length %u", len);
			bp += len;
		}
	}
	return;
trunc:
	nd_print_trunc(ndo);
}
Ejemplo n.º 25
0
/*
 * Print bootp requests
 */
void
bootp_print(netdissect_options *ndo,
	    const u_char *cp, u_int length)
{
	const struct bootp *bp;
	static const u_char vm_cmu[4] = VM_CMU;
	static const u_char vm_rfc1048[4] = VM_RFC1048;
	uint8_t bp_op, bp_htype, bp_hlen;

	ndo->ndo_protocol = "bootp";
	bp = (const struct bootp *)cp;
	ND_TCHECK_1(bp->bp_op);
	bp_op = EXTRACT_U_1(bp->bp_op);
	ND_PRINT("BOOTP/DHCP, %s",
		  tok2str(bootp_op_values, "unknown (0x%02x)", bp_op));

	ND_TCHECK_1(bp->bp_hlen);
	bp_htype = EXTRACT_U_1(bp->bp_htype);
	bp_hlen = EXTRACT_U_1(bp->bp_hlen);
	if (bp_htype == 1 && bp_hlen == 6 && bp_op == BOOTPREQUEST) {
		ND_TCHECK_6(bp->bp_chaddr);
		ND_PRINT(" from %s", etheraddr_string(ndo, bp->bp_chaddr));
	}

	ND_PRINT(", length %u", length);

	if (!ndo->ndo_vflag)
		return;

	ND_TCHECK_2(bp->bp_secs);

	/* The usual hardware address type is 1 (10Mb Ethernet) */
	if (bp_htype != 1)
		ND_PRINT(", htype %u", bp_htype);

	/* The usual length for 10Mb Ethernet address is 6 bytes */
	if (bp_htype != 1 || bp_hlen != 6)
		ND_PRINT(", hlen %u", bp_hlen);

	/* Only print interesting fields */
	if (EXTRACT_U_1(bp->bp_hops))
		ND_PRINT(", hops %u", EXTRACT_U_1(bp->bp_hops));
	if (EXTRACT_BE_U_4(bp->bp_xid))
		ND_PRINT(", xid 0x%x", EXTRACT_BE_U_4(bp->bp_xid));
	if (EXTRACT_BE_U_2(bp->bp_secs))
		ND_PRINT(", secs %u", EXTRACT_BE_U_2(bp->bp_secs));

	ND_TCHECK_2(bp->bp_flags);
	ND_PRINT(", Flags [%s]",
		  bittok2str(bootp_flag_values, "none", EXTRACT_BE_U_2(bp->bp_flags)));
	if (ndo->ndo_vflag > 1)
		ND_PRINT(" (0x%04x)", EXTRACT_BE_U_2(bp->bp_flags));

	/* Client's ip address */
	ND_TCHECK_4(bp->bp_ciaddr);
	if (EXTRACT_IPV4_TO_NETWORK_ORDER(bp->bp_ciaddr))
		ND_PRINT("\n\t  Client-IP %s", ipaddr_string(ndo, bp->bp_ciaddr));

	/* 'your' ip address (bootp client) */
	ND_TCHECK_4(bp->bp_yiaddr);
	if (EXTRACT_IPV4_TO_NETWORK_ORDER(bp->bp_yiaddr))
		ND_PRINT("\n\t  Your-IP %s", ipaddr_string(ndo, bp->bp_yiaddr));

	/* Server's ip address */
	ND_TCHECK_4(bp->bp_siaddr);
	if (EXTRACT_IPV4_TO_NETWORK_ORDER(bp->bp_siaddr))
		ND_PRINT("\n\t  Server-IP %s", ipaddr_string(ndo, bp->bp_siaddr));

	/* Gateway's ip address */
	ND_TCHECK_4(bp->bp_giaddr);
	if (EXTRACT_IPV4_TO_NETWORK_ORDER(bp->bp_giaddr))
		ND_PRINT("\n\t  Gateway-IP %s", ipaddr_string(ndo, bp->bp_giaddr));

	/* Client's Ethernet address */
	if (bp_htype == 1 && bp_hlen == 6) {
		ND_TCHECK_6(bp->bp_chaddr);
		ND_PRINT("\n\t  Client-Ethernet-Address %s", etheraddr_string(ndo, bp->bp_chaddr));
	}

	ND_TCHECK_1(bp->bp_sname);		/* check first char only */
	if (EXTRACT_U_1(bp->bp_sname)) {
		ND_PRINT("\n\t  sname \"");
		if (nd_printztn(ndo, bp->bp_sname, (u_int)sizeof(bp->bp_sname),
				ndo->ndo_snapend) == 0) {
			ND_PRINT("\"");
			nd_print_trunc(ndo);
			return;
		}
		ND_PRINT("\"");
	}
	ND_TCHECK_1(bp->bp_file);		/* check first char only */
	if (EXTRACT_U_1(bp->bp_file)) {
		ND_PRINT("\n\t  file \"");
		if (nd_printztn(ndo, bp->bp_file, (u_int)sizeof(bp->bp_file),
				ndo->ndo_snapend) == 0) {
			ND_PRINT("\"");
			nd_print_trunc(ndo);
			return;
		}
		ND_PRINT("\"");
	}

	/* Decode the vendor buffer */
	ND_TCHECK_4(bp->bp_vend);
	if (memcmp((const char *)bp->bp_vend, vm_rfc1048,
		    sizeof(uint32_t)) == 0)
		rfc1048_print(ndo, bp->bp_vend);
	else if (memcmp((const char *)bp->bp_vend, vm_cmu,
			sizeof(uint32_t)) == 0)
		cmu_print(ndo, bp->bp_vend);
	else {
		uint32_t ul;

		ul = EXTRACT_BE_U_4(bp->bp_vend);
		if (ul != 0)
			ND_PRINT("\n\t  Vendor-#0x%x", ul);
	}

	return;
trunc:
	nd_print_trunc(ndo);
}
Ejemplo n.º 26
0
void
lwres_print(netdissect_options *ndo,
            const u_char *bp, u_int length)
{
	const u_char *p;
	const struct lwres_lwpacket *np;
	uint32_t v;
	const u_char *s;
	int response;
	int advance;
	int unsupported = 0;

	ndo->ndo_protocol = "lwres";
	np = (const struct lwres_lwpacket *)bp;
	ND_TCHECK_2(np->authlength);

	ND_PRINT(" lwres");
	v = EXTRACT_BE_U_2(np->version);
	if (ndo->ndo_vflag || v != LWRES_LWPACKETVERSION_0)
		ND_PRINT(" v%u", v);
	if (v != LWRES_LWPACKETVERSION_0) {
		s = bp + EXTRACT_BE_U_4(np->length);
		goto tail;
	}

	response = EXTRACT_BE_U_2(np->pktflags) & LWRES_LWPACKETFLAG_RESPONSE;

	/* opcode and pktflags */
	v = EXTRACT_BE_U_4(np->opcode);
	ND_PRINT(" %s%s", tok2str(opcode, "#0x%x", v), response ? "" : "?");

	/* pktflags */
	v = EXTRACT_BE_U_2(np->pktflags);
	if (v & ~LWRES_LWPACKETFLAG_RESPONSE)
		ND_PRINT("[0x%x]", v);

	if (ndo->ndo_vflag > 1) {
		ND_PRINT(" (");	/*)*/
		ND_PRINT("serial:0x%x", EXTRACT_BE_U_4(np->serial));
		ND_PRINT(" result:0x%x", EXTRACT_BE_U_4(np->result));
		ND_PRINT(" recvlen:%u", EXTRACT_BE_U_4(np->recvlength));
		/* BIND910: not used */
		if (ndo->ndo_vflag > 2) {
			ND_PRINT(" authtype:0x%x", EXTRACT_BE_U_2(np->authtype));
			ND_PRINT(" authlen:%u", EXTRACT_BE_U_2(np->authlength));
		}
		/*(*/
		ND_PRINT(")");
	}

	/* per-opcode content */
	if (!response) {
		/*
		 * queries
		 */
		const lwres_gabnrequest_t *gabn;
		const lwres_gnbarequest_t *gnba;
		const lwres_grbnrequest_t *grbn;
		uint32_t l;

		gabn = NULL;
		gnba = NULL;
		grbn = NULL;

		p = (const u_char *)(np + 1);
		switch (EXTRACT_BE_U_4(np->opcode)) {
		case LWRES_OPCODE_NOOP:
			s = p;
			break;
		case LWRES_OPCODE_GETADDRSBYNAME:
			gabn = (const lwres_gabnrequest_t *)p;
			ND_TCHECK_2(gabn->namelen);

			/* BIND910: not used */
			if (ndo->ndo_vflag > 2) {
				ND_PRINT(" flags:0x%x",
				    EXTRACT_BE_U_4(gabn->flags));
			}

			v = EXTRACT_BE_U_4(gabn->addrtypes);
			switch (v & (LWRES_ADDRTYPE_V4 | LWRES_ADDRTYPE_V6)) {
			case LWRES_ADDRTYPE_V4:
				ND_PRINT(" IPv4");
				break;
			case LWRES_ADDRTYPE_V6:
				ND_PRINT(" IPv6");
				break;
			case LWRES_ADDRTYPE_V4 | LWRES_ADDRTYPE_V6:
				ND_PRINT(" IPv4/6");
				break;
			}
			if (v & ~(LWRES_ADDRTYPE_V4 | LWRES_ADDRTYPE_V6))
				ND_PRINT("[0x%x]", v);

			s = p + LWRES_GABNREQUEST_LEN;
			l = EXTRACT_BE_U_2(gabn->namelen);
			advance = lwres_printname(ndo, l, s);
			if (advance < 0)
				goto trunc;
			s += advance;
			break;
		case LWRES_OPCODE_GETNAMEBYADDR:
			gnba = (const lwres_gnbarequest_t *)p;
			ND_TCHECK_4(gnba->flags);

			/* BIND910: not used */
			if (ndo->ndo_vflag > 2) {
				ND_PRINT(" flags:0x%x",
				    EXTRACT_BE_U_4(gnba->flags));
			}

			s = p + LWRES_GNBAREQUEST_LEN;
			advance = lwres_printaddr(ndo, s);
			if (advance < 0)
				goto trunc;
			s += advance;
			break;
		case LWRES_OPCODE_GETRDATABYNAME:
			/* XXX no trace, not tested */
			grbn = (const lwres_grbnrequest_t *)p;
			ND_TCHECK_2(grbn->namelen);

			/* BIND910: not used */
			if (ndo->ndo_vflag > 2) {
				ND_PRINT(" flags:0x%x",
				    EXTRACT_BE_U_4(grbn->flags));
			}

			ND_PRINT(" %s", tok2str(ns_type2str, "Type%u",
			    EXTRACT_BE_U_2(grbn->rdtype)));
			if (EXTRACT_BE_U_2(grbn->rdclass) != C_IN) {
				ND_PRINT(" %s", tok2str(ns_class2str, "Class%u",
				    EXTRACT_BE_U_2(grbn->rdclass)));
			}

			s = p + LWRES_GRBNREQUEST_LEN;
			l = EXTRACT_BE_U_2(grbn->namelen);
			advance = lwres_printname(ndo, l, s);
			if (advance < 0)
				goto trunc;
			s += advance;
			break;
		default:
			s = p;
			unsupported++;
			break;
		}
	} else {
		/*
		 * responses
		 */
		const lwres_gabnresponse_t *gabn;
		const lwres_gnbaresponse_t *gnba;
		const lwres_grbnresponse_t *grbn;
		uint32_t l, na;
		uint32_t i;

		gabn = NULL;
		gnba = NULL;
		grbn = NULL;

		p = (const u_char *)(np + 1);
		switch (EXTRACT_BE_U_4(np->opcode)) {
		case LWRES_OPCODE_NOOP:
			s = p;
			break;
		case LWRES_OPCODE_GETADDRSBYNAME:
			gabn = (const lwres_gabnresponse_t *)p;
			ND_TCHECK_2(gabn->realnamelen);

			/* BIND910: not used */
			if (ndo->ndo_vflag > 2) {
				ND_PRINT(" flags:0x%x",
				    EXTRACT_BE_U_4(gabn->flags));
			}

			ND_PRINT(" %u/%u", EXTRACT_BE_U_2(gabn->naliases),
				  EXTRACT_BE_U_2(gabn->naddrs));

			s = p + LWRES_GABNRESPONSE_LEN;
			l = EXTRACT_BE_U_2(gabn->realnamelen);
			advance = lwres_printname(ndo, l, s);
			if (advance < 0)
				goto trunc;
			s += advance;

			/* aliases */
			na = EXTRACT_BE_U_2(gabn->naliases);
			for (i = 0; i < na; i++) {
				advance = lwres_printnamelen(ndo, s);
				if (advance < 0)
					goto trunc;
				s += advance;
			}

			/* addrs */
			na = EXTRACT_BE_U_2(gabn->naddrs);
			for (i = 0; i < na; i++) {
				advance = lwres_printaddr(ndo, s);
				if (advance < 0)
					goto trunc;
				s += advance;
			}
			break;
		case LWRES_OPCODE_GETNAMEBYADDR:
			gnba = (const lwres_gnbaresponse_t *)p;
			ND_TCHECK_2(gnba->realnamelen);

			/* BIND910: not used */
			if (ndo->ndo_vflag > 2) {
				ND_PRINT(" flags:0x%x",
				    EXTRACT_BE_U_4(gnba->flags));
			}

			ND_PRINT(" %u", EXTRACT_BE_U_2(gnba->naliases));

			s = p + LWRES_GNBARESPONSE_LEN;
			l = EXTRACT_BE_U_2(gnba->realnamelen);
			advance = lwres_printname(ndo, l, s);
			if (advance < 0)
				goto trunc;
			s += advance;

			/* aliases */
			na = EXTRACT_BE_U_2(gnba->naliases);
			for (i = 0; i < na; i++) {
				advance = lwres_printnamelen(ndo, s);
				if (advance < 0)
					goto trunc;
				s += advance;
			}
			break;
		case LWRES_OPCODE_GETRDATABYNAME:
			/* XXX no trace, not tested */
			grbn = (const lwres_grbnresponse_t *)p;
			ND_TCHECK_2(grbn->nsigs);

			/* BIND910: not used */
			if (ndo->ndo_vflag > 2) {
				ND_PRINT(" flags:0x%x",
				    EXTRACT_BE_U_4(grbn->flags));
			}

			ND_PRINT(" %s", tok2str(ns_type2str, "Type%u",
			    EXTRACT_BE_U_2(grbn->rdtype)));
			if (EXTRACT_BE_U_2(grbn->rdclass) != C_IN) {
				ND_PRINT(" %s", tok2str(ns_class2str, "Class%u",
				    EXTRACT_BE_U_2(grbn->rdclass)));
			}
			ND_PRINT(" TTL ");
			unsigned_relts_print(ndo,
					     EXTRACT_BE_U_4(grbn->ttl));
			ND_PRINT(" %u/%u", EXTRACT_BE_U_2(grbn->nrdatas),
				  EXTRACT_BE_U_2(grbn->nsigs));

			s = p + LWRES_GRBNRESPONSE_LEN;
			advance = lwres_printnamelen(ndo, s);
			if (advance < 0)
				goto trunc;
			s += advance;

			/* rdatas */
			na = EXTRACT_BE_U_2(grbn->nrdatas);
			for (i = 0; i < na; i++) {
				/* XXX should decode resource data */
				advance = lwres_printbinlen(ndo, s);
				if (advance < 0)
					goto trunc;
				s += advance;
			}

			/* sigs */
			na = EXTRACT_BE_U_2(grbn->nsigs);
			for (i = 0; i < na; i++) {
				/* XXX how should we print it? */
				advance = lwres_printbinlen(ndo, s);
				if (advance < 0)
					goto trunc;
				s += advance;
			}
			break;
		default:
			s = p;
			unsupported++;
			break;
		}
	}

  tail:
	/* length mismatch */
	if (EXTRACT_BE_U_4(np->length) != length) {
		ND_PRINT(" [len: %u != %u]", EXTRACT_BE_U_4(np->length),
			  length);
	}
	if (!unsupported && s < bp + EXTRACT_BE_U_4(np->length))
		ND_PRINT("[extra]");
	return;

  trunc:
	ND_PRINT("[|lwres]");
}
Ejemplo n.º 27
0
static void
gre_print_0(netdissect_options *ndo, const u_char *bp, u_int length)
{
	u_int len = length;
	uint16_t flags, prot;

	/* 16 bits ND_TCHECKed in gre_print() */
	flags = EXTRACT_BE_U_2(bp);
        if (ndo->ndo_vflag)
            ND_PRINT(", Flags [%s]",
                   bittok2str(gre_flag_values,"none",flags));

	len -= 2;
	bp += 2;

	ND_TCHECK_2(bp);
	if (len < 2)
		goto trunc;
	prot = EXTRACT_BE_U_2(bp);
	len -= 2;
	bp += 2;

	if ((flags & GRE_CP) | (flags & GRE_RP)) {
		ND_TCHECK_2(bp);
		if (len < 2)
			goto trunc;
		if (ndo->ndo_vflag)
			ND_PRINT(", sum 0x%x", EXTRACT_BE_U_2(bp));
		bp += 2;
		len -= 2;

		ND_TCHECK_2(bp);
		if (len < 2)
			goto trunc;
		ND_PRINT(", off 0x%x", EXTRACT_BE_U_2(bp));
		bp += 2;
		len -= 2;
	}

	if (flags & GRE_KP) {
		ND_TCHECK_4(bp);
		if (len < 4)
			goto trunc;
		ND_PRINT(", key=0x%x", EXTRACT_BE_U_4(bp));
		bp += 4;
		len -= 4;
	}

	if (flags & GRE_SP) {
		ND_TCHECK_4(bp);
		if (len < 4)
			goto trunc;
		ND_PRINT(", seq %u", EXTRACT_BE_U_4(bp));
		bp += 4;
		len -= 4;
	}

	if (flags & GRE_RP) {
		for (;;) {
			uint16_t af;
			uint8_t sreoff;
			uint8_t srelen;

			ND_TCHECK_4(bp);
			if (len < 4)
				goto trunc;
			af = EXTRACT_BE_U_2(bp);
			sreoff = EXTRACT_U_1(bp + 2);
			srelen = EXTRACT_U_1(bp + 3);
			bp += 4;
			len -= 4;

			if (af == 0 && srelen == 0)
				break;

			if (!gre_sre_print(ndo, af, sreoff, srelen, bp, len))
				goto trunc;

			if (len < srelen)
				goto trunc;
			bp += srelen;
			len -= srelen;
		}
	}

        if (ndo->ndo_eflag)
            ND_PRINT(", proto %s (0x%04x)",
                   tok2str(ethertype_values,"unknown",prot),
                   prot);

        ND_PRINT(", length %u",length);

        if (ndo->ndo_vflag < 1)
            ND_PRINT(": "); /* put in a colon as protocol demarc */
        else
            ND_PRINT("\n\t"); /* if verbose go multiline */

	switch (prot) {
	case ETHERTYPE_IP:
	        ip_print(ndo, bp, len);
		break;
	case ETHERTYPE_IPV6:
		ip6_print(ndo, bp, len);
		break;
	case ETHERTYPE_MPLS:
		mpls_print(ndo, bp, len);
		break;
	case ETHERTYPE_IPX:
		ipx_print(ndo, bp, len);
		break;
	case ETHERTYPE_ATALK:
		atalk_print(ndo, bp, len);
		break;
	case ETHERTYPE_GRE_ISO:
		isoclns_print(ndo, bp, len);
		break;
	case ETHERTYPE_TEB:
		ether_print(ndo, bp, len, ndo->ndo_snapend - bp, NULL, NULL);
		break;
	default:
		ND_PRINT("gre-proto-0x%x", prot);
	}
	return;

trunc:
	ND_PRINT("%s", tstr);
}
Ejemplo n.º 28
0
static void
gre_print_1(netdissect_options *ndo, const u_char *bp, u_int length)
{
	u_int len = length;
	uint16_t flags, prot;

	/* 16 bits ND_TCHECKed in gre_print() */
	flags = EXTRACT_BE_U_2(bp);
	len -= 2;
	bp += 2;

	if (ndo->ndo_vflag)
            ND_PRINT(", Flags [%s]",
                   bittok2str(gre_flag_values,"none",flags));

	ND_TCHECK_2(bp);
	if (len < 2)
		goto trunc;
	prot = EXTRACT_BE_U_2(bp);
	len -= 2;
	bp += 2;


	if (flags & GRE_KP) {
		uint32_t k;

		ND_TCHECK_4(bp);
		if (len < 4)
			goto trunc;
		k = EXTRACT_BE_U_4(bp);
		ND_PRINT(", call %u", k & 0xffff);
		len -= 4;
		bp += 4;
	}

	if (flags & GRE_SP) {
		ND_TCHECK_4(bp);
		if (len < 4)
			goto trunc;
		ND_PRINT(", seq %u", EXTRACT_BE_U_4(bp));
		bp += 4;
		len -= 4;
	}

	if (flags & GRE_AP) {
		ND_TCHECK_4(bp);
		if (len < 4)
			goto trunc;
		ND_PRINT(", ack %u", EXTRACT_BE_U_4(bp));
		bp += 4;
		len -= 4;
	}

	if ((flags & GRE_SP) == 0)
		ND_PRINT(", no-payload");

        if (ndo->ndo_eflag)
            ND_PRINT(", proto %s (0x%04x)",
                   tok2str(ethertype_values,"unknown",prot),
                   prot);

        ND_PRINT(", length %u",length);

        if ((flags & GRE_SP) == 0)
            return;

        if (ndo->ndo_vflag < 1)
            ND_PRINT(": "); /* put in a colon as protocol demarc */
        else
            ND_PRINT("\n\t"); /* if verbose go multiline */

	switch (prot) {
	case ETHERTYPE_PPP:
		ppp_print(ndo, bp, len);
		break;
	default:
		ND_PRINT("gre-proto-0x%x", prot);
		break;
	}
	return;

trunc:
	ND_PRINT("%s", tstr);
}
Ejemplo n.º 29
0
static void
egpnrprint(netdissect_options *ndo,
           const struct egp_packet *egp, u_int length)
{
	const uint8_t *cp;
	uint32_t addr;
	uint32_t net;
	u_int netlen;
	u_int gateways, distances, networks;
	u_int intgw, extgw, t_gateways;
	const char *comma;

	addr = EXTRACT_IPV4_TO_NETWORK_ORDER(egp->egp_sourcenet);
	if (IN_CLASSA(addr)) {
		net = addr & IN_CLASSA_NET;
		netlen = 1;
	} else if (IN_CLASSB(addr)) {
		net = addr & IN_CLASSB_NET;
		netlen = 2;
	} else if (IN_CLASSC(addr)) {
		net = addr & IN_CLASSC_NET;
		netlen = 3;
	} else {
		net = 0;
		netlen = 0;
	}
	cp = (const uint8_t *)(egp + 1);
	length -= sizeof(*egp);

	intgw = EXTRACT_U_1(egp->egp_intgw);
	extgw = EXTRACT_U_1(egp->egp_extgw);
	t_gateways = intgw + extgw;
	for (gateways = 0; gateways < t_gateways; ++gateways) {
		/* Pickup host part of gateway address */
		addr = 0;
		if (length < 4 - netlen)
			goto trunc;
		ND_TCHECK_LEN(cp, 4 - netlen);
		switch (netlen) {

		case 1:
			addr = EXTRACT_U_1(cp);
			cp++;
			/* fall through */
		case 2:
			addr = (addr << 8) | EXTRACT_U_1(cp);
			cp++;
			/* fall through */
		case 3:
			addr = (addr << 8) | EXTRACT_U_1(cp);
			cp++;
			break;
		}
		addr |= net;
		length -= 4 - netlen;
		if (length < 1)
			goto trunc;
		ND_TCHECK_1(cp);
		distances = EXTRACT_U_1(cp);
		cp++;
		length--;
		ND_PRINT(" %s %s ",
		       gateways < intgw ? "int" : "ext",
		       ipaddr_string(ndo, (const u_char *)&addr));

		comma = "";
		ND_PRINT("(");
		while (distances != 0) {
			if (length < 2)
				goto trunc;
			ND_TCHECK_2(cp);
			ND_PRINT("%sd%u:", comma, EXTRACT_U_1(cp));
			cp++;
			comma = ", ";
			networks = EXTRACT_U_1(cp);
			cp++;
			length -= 2;
			while (networks != 0) {
				/* Pickup network number */
				if (length < 1)
					goto trunc;
				ND_TCHECK_1(cp);
				addr = ((uint32_t) EXTRACT_U_1(cp)) << 24;
				cp++;
				length--;
				if (IN_CLASSB(addr)) {
					if (length < 1)
						goto trunc;
					ND_TCHECK_1(cp);
					addr |= ((uint32_t) EXTRACT_U_1(cp)) << 16;
					cp++;
					length--;
				} else if (!IN_CLASSA(addr)) {
					if (length < 2)
						goto trunc;
					ND_TCHECK_2(cp);
					addr |= ((uint32_t) EXTRACT_U_1(cp)) << 16;
					cp++;
					addr |= ((uint32_t) EXTRACT_U_1(cp)) << 8;
					cp++;
					length -= 2;
				}
				ND_PRINT(" %s", ipaddr_string(ndo, (const u_char *)&addr));
				networks--;
			}
			distances--;
		}
		ND_PRINT(")");
	}
	return;
trunc:
	ND_PRINT("[|]");
}
Ejemplo n.º 30
0
/* LCP config options */
static u_int
print_lcp_config_options(netdissect_options *ndo,
                         const u_char *p, u_int length)
{
	u_int opt, len;

	if (length < 2)
		return 0;
	ND_TCHECK_2(p);
	opt = EXTRACT_U_1(p);
	len = EXTRACT_U_1(p + 1);
	if (length < len)
		return 0;
	if (len < 2) {
		if (opt < NUM_LCPOPTS)
			ND_PRINT("\n\t  %s Option (0x%02x), length %u (length bogus, should be >= 2)",
			          lcpconfopts[opt], opt, len);
		else
			ND_PRINT("\n\tunknown LCP option 0x%02x", opt);
		return 0;
	}
	if (opt < NUM_LCPOPTS)
		ND_PRINT("\n\t  %s Option (0x%02x), length %u", lcpconfopts[opt], opt, len);
	else {
		ND_PRINT("\n\tunknown LCP option 0x%02x", opt);
		return len;
	}

	switch (opt) {
	case LCPOPT_VEXT:
		if (len < 6) {
			ND_PRINT(" (length bogus, should be >= 6)");
			return len;
		}
		ND_TCHECK_3(p + 2);
		ND_PRINT(": Vendor: %s (%u)",
			tok2str(oui_values,"Unknown",EXTRACT_BE_U_3(p + 2)),
			EXTRACT_BE_U_3(p + 2));
#if 0
		ND_TCHECK_1(p + 5);
		ND_PRINT(", kind: 0x%02x", EXTRACT_U_1(p + 5));
		ND_PRINT(", Value: 0x");
		for (i = 0; i < len - 6; i++) {
			ND_TCHECK_1(p + 6 + i);
			ND_PRINT("%02x", EXTRACT_U_1(p + 6 + i));
		}
#endif
		break;
	case LCPOPT_MRU:
		if (len != 4) {
			ND_PRINT(" (length bogus, should be = 4)");
			return len;
		}
		ND_TCHECK_2(p + 2);
		ND_PRINT(": %u", EXTRACT_BE_U_2(p + 2));
		break;
	case LCPOPT_ACCM:
		if (len != 6) {
			ND_PRINT(" (length bogus, should be = 6)");
			return len;
		}
		ND_TCHECK_4(p + 2);
		ND_PRINT(": 0x%08x", EXTRACT_BE_U_4(p + 2));
		break;
	case LCPOPT_AP:
		if (len < 4) {
			ND_PRINT(" (length bogus, should be >= 4)");
			return len;
		}
		ND_TCHECK_2(p + 2);
		ND_PRINT(": %s", tok2str(ppptype2str, "Unknown Auth Proto (0x04x)", EXTRACT_BE_U_2(p + 2)));

		switch (EXTRACT_BE_U_2(p + 2)) {
		case PPP_CHAP:
			ND_TCHECK_1(p + 4);
			ND_PRINT(", %s", tok2str(authalg_values, "Unknown Auth Alg %u", EXTRACT_U_1(p + 4)));
			break;
		case PPP_PAP: /* fall through */
		case PPP_EAP:
		case PPP_SPAP:
		case PPP_SPAP_OLD:
                        break;
		default:
			print_unknown_data(ndo, p, "\n\t", len);
		}
		break;
	case LCPOPT_QP:
		if (len < 4) {
			ND_PRINT(" (length bogus, should be >= 4)");
			return 0;
		}
		ND_TCHECK_2(p + 2);
		if (EXTRACT_BE_U_2(p + 2) == PPP_LQM)
			ND_PRINT(": LQR");
		else
			ND_PRINT(": unknown");
		break;
	case LCPOPT_MN:
		if (len != 6) {
			ND_PRINT(" (length bogus, should be = 6)");
			return 0;
		}
		ND_TCHECK_4(p + 2);
		ND_PRINT(": 0x%08x", EXTRACT_BE_U_4(p + 2));
		break;
	case LCPOPT_PFC:
		break;
	case LCPOPT_ACFC:
		break;
	case LCPOPT_LD:
		if (len != 4) {
			ND_PRINT(" (length bogus, should be = 4)");
			return 0;
		}
		ND_TCHECK_2(p + 2);
		ND_PRINT(": 0x%04x", EXTRACT_BE_U_2(p + 2));
		break;
	case LCPOPT_CBACK:
		if (len < 3) {
			ND_PRINT(" (length bogus, should be >= 3)");
			return 0;
		}
		ND_PRINT(": ");
		ND_TCHECK_1(p + 2);
		ND_PRINT(": Callback Operation %s (%u)",
                       tok2str(ppp_callback_values, "Unknown", EXTRACT_U_1(p + 2)),
                       EXTRACT_U_1(p + 2));
		break;
	case LCPOPT_MLMRRU:
		if (len != 4) {
			ND_PRINT(" (length bogus, should be = 4)");
			return 0;
		}
		ND_TCHECK_2(p + 2);
		ND_PRINT(": %u", EXTRACT_BE_U_2(p + 2));
		break;
	case LCPOPT_MLED:
		if (len < 3) {
			ND_PRINT(" (length bogus, should be >= 3)");
			return 0;
		}
		ND_TCHECK_1(p + 2);
		switch (EXTRACT_U_1(p + 2)) {		/* class */
		case MEDCLASS_NULL:
			ND_PRINT(": Null");
			break;
		case MEDCLASS_LOCAL:
			ND_PRINT(": Local"); /* XXX */
			break;
		case MEDCLASS_IPV4:
			if (len != 7) {
				ND_PRINT(" (length bogus, should be = 7)");
				return 0;
			}
			ND_TCHECK_4(p + 3);
			ND_PRINT(": IPv4 %s", ipaddr_string(ndo, p + 3));
			break;
		case MEDCLASS_MAC:
			if (len != 9) {
				ND_PRINT(" (length bogus, should be = 9)");
				return 0;
			}
			ND_TCHECK_6(p + 3);
			ND_PRINT(": MAC %s", etheraddr_string(ndo, p + 3));
			break;
		case MEDCLASS_MNB:
			ND_PRINT(": Magic-Num-Block"); /* XXX */
			break;
		case MEDCLASS_PSNDN:
			ND_PRINT(": PSNDN"); /* XXX */
			break;
		default:
			ND_PRINT(": Unknown class %u", EXTRACT_U_1(p + 2));
			break;
		}
		break;

/* XXX: to be supported */
#if 0
	case LCPOPT_DEP6:
	case LCPOPT_FCSALT:
	case LCPOPT_SDP:
	case LCPOPT_NUMMODE:
	case LCPOPT_DEP12:
	case LCPOPT_DEP14:
	case LCPOPT_DEP15:
	case LCPOPT_DEP16:
        case LCPOPT_MLSSNHF:
	case LCPOPT_PROP:
	case LCPOPT_DCEID:
	case LCPOPT_MPP:
	case LCPOPT_LCPAOPT:
	case LCPOPT_COBS:
	case LCPOPT_PE:
	case LCPOPT_MLHF:
	case LCPOPT_I18N:
	case LCPOPT_SDLOS:
	case LCPOPT_PPPMUX:
		break;
#endif
	default:
		/*
		 * Unknown option; dump it as raw bytes now if we're
		 * not going to do so below.
		 */
		if (ndo->ndo_vflag < 2)
			print_unknown_data(ndo, p + 2, "\n\t    ", len - 2);
		break;
	}

	if (ndo->ndo_vflag > 1)
		print_unknown_data(ndo, p + 2, "\n\t    ", len - 2); /* exclude TLV header */

	return len;

trunc:
	ND_PRINT("[|lcp]");
	return 0;
}