Пример #1
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);
}
Пример #2
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);
}
Пример #3
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);
}
Пример #4
0
/*
 * If we printed information about the payload, returns the length of the LLC
 * header, plus the length of any SNAP header following it.
 *
 * Otherwise (for example, if the packet has unknown SAPs or has a SNAP
 * header with an unknown OUI/PID combination), returns the *negative*
 * of that value.
 */
int
llc_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen,
	  const struct lladdr_info *src, const struct lladdr_info *dst)
{
	uint8_t dsap_field, dsap, ssap_field, ssap;
	uint16_t control;
	int hdrlen;
	int is_u;

	if (caplen < 3) {
		ND_PRINT("[|llc]");
		ND_DEFAULTPRINT((const u_char *)p, caplen);
		return (caplen);
	}
	if (length < 3) {
		ND_PRINT("[|llc]");
		ND_DEFAULTPRINT((const u_char *)p, caplen);
		return (length);
	}

	dsap_field = EXTRACT_U_1(p);
	ssap_field = EXTRACT_U_1(p + 1);

	/*
	 * OK, what type of LLC frame is this?  The length
	 * of the control field depends on that - I frames
	 * have a two-byte control field, and U frames have
	 * a one-byte control field.
	 */
	control = EXTRACT_U_1(p + 2);
	if ((control & LLC_U_FMT) == LLC_U_FMT) {
		/*
		 * U frame.
		 */
		is_u = 1;
		hdrlen = 3;	/* DSAP, SSAP, 1-byte control field */
	} else {
		/*
		 * The control field in I and S frames is
		 * 2 bytes...
		 */
		if (caplen < 4) {
			ND_PRINT("[|llc]");
			ND_DEFAULTPRINT((const u_char *)p, caplen);
			return (caplen);
		}
		if (length < 4) {
			ND_PRINT("[|llc]");
			ND_DEFAULTPRINT((const u_char *)p, caplen);
			return (length);
		}

		/*
		 * ...and is little-endian.
		 */
		control = EXTRACT_LE_U_2(p + 2);
		is_u = 0;
		hdrlen = 4;	/* DSAP, SSAP, 2-byte control field */
	}

	if (ssap_field == LLCSAP_GLOBAL && dsap_field == LLCSAP_GLOBAL) {
		/*
		 * This is an Ethernet_802.3 IPX frame; it has an
		 * 802.3 header (i.e., an Ethernet header where the
		 * type/length field is <= MAX_ETHERNET_LENGTH_VAL,
		 * i.e. it's a length field, not a type field), but
		 * has no 802.2 header - the IPX packet starts right
		 * after the Ethernet header, with a signature of two
		 * bytes of 0xFF (which is LLCSAP_GLOBAL).
		 *
		 * (It might also have been an Ethernet_802.3 IPX at
		 * one time, but got bridged onto another network,
		 * such as an 802.11 network; this has appeared in at
		 * least one capture file.)
		 */

            if (ndo->ndo_eflag)
		ND_PRINT("IPX 802.3: ");

            ipx_print(ndo, p, length);
            return (0);		/* no LLC header */
	}

	dsap = dsap_field & ~LLC_IG;
	ssap = ssap_field & ~LLC_GSAP;

	if (ndo->ndo_eflag) {
                ND_PRINT("LLC, dsap %s (0x%02x) %s, ssap %s (0x%02x) %s",
                       tok2str(llc_values, "Unknown", dsap),
                       dsap,
                       tok2str(llc_ig_flag_values, "Unknown", dsap_field & LLC_IG),
                       tok2str(llc_values, "Unknown", ssap),
                       ssap,
                       tok2str(llc_flag_values, "Unknown", ssap_field & LLC_GSAP));

		if (is_u) {
			ND_PRINT(", ctrl 0x%02x: ", control);
		} else {
			ND_PRINT(", ctrl 0x%04x: ", control);
		}
	}

	/*
	 * Skip LLC header.
	 */
	p += hdrlen;
	length -= hdrlen;
	caplen -= hdrlen;

	if (ssap == LLCSAP_SNAP && dsap == LLCSAP_SNAP
	    && control == LLC_UI) {
		/*
		 * XXX - what *is* the right bridge pad value here?
		 * Does anybody ever bridge one form of LAN traffic
		 * over a networking type that uses 802.2 LLC?
		 */
		if (!snap_print(ndo, p, length, caplen, src, dst, 2)) {
			/*
			 * Unknown packet type; tell our caller, by
			 * returning a negative value, so they
			 * can print the raw packet.
			 */
			return (-(hdrlen + 5));	/* include LLC and SNAP header */
		} else
			return (hdrlen + 5);	/* include LLC and SNAP header */
	}

	if (ssap == LLCSAP_8021D && dsap == LLCSAP_8021D &&
	    control == LLC_UI) {
		stp_print(ndo, p, length);
		return (hdrlen);
	}

	if (ssap == LLCSAP_IP && dsap == LLCSAP_IP &&
	    control == LLC_UI) {
		/*
		 * This is an RFC 948-style IP packet, with
		 * an 802.3 header and an 802.2 LLC header
		 * with the source and destination SAPs being
		 * the IP SAP.
		 */
		ip_print(ndo, p, length);
		return (hdrlen);
	}

	if (ssap == LLCSAP_IPX && dsap == LLCSAP_IPX &&
	    control == LLC_UI) {
		/*
		 * This is an Ethernet_802.2 IPX frame, with an 802.3
		 * header and an 802.2 LLC header with the source and
		 * destination SAPs being the IPX SAP.
		 */
                if (ndo->ndo_eflag)
                        ND_PRINT("IPX 802.2: ");

		ipx_print(ndo, p, length);
		return (hdrlen);
	}

#ifdef ENABLE_SMB
	if (ssap == LLCSAP_NETBEUI && dsap == LLCSAP_NETBEUI
	    && (!(control & LLC_S_FMT) || control == LLC_U_FMT)) {
		/*
		 * we don't actually have a full netbeui parser yet, but the
		 * smb parser can handle many smb-in-netbeui packets, which
		 * is very useful, so we call that
		 *
		 * We don't call it for S frames, however, just I frames
		 * (which are frames that don't have the low-order bit,
		 * LLC_S_FMT, set in the first byte of the control field)
		 * and UI frames (whose control field is just 3, LLC_U_FMT).
		 */
		netbeui_print(ndo, control, p, length);
		return (hdrlen);
	}
#endif
	if (ssap == LLCSAP_ISONS && dsap == LLCSAP_ISONS
	    && control == LLC_UI) {
		isoclns_print(ndo, p, length);
		return (hdrlen);
	}

	if (!ndo->ndo_eflag) {
		if (ssap == dsap) {
			if (src == NULL || dst == NULL)
				ND_PRINT("%s ", tok2str(llc_values, "Unknown DSAP 0x%02x", dsap));
			else
				ND_PRINT("%s > %s %s ",
						(src->addr_string)(ndo, src->addr),
						(dst->addr_string)(ndo, dst->addr),
						tok2str(llc_values, "Unknown DSAP 0x%02x", dsap));
		} else {
			if (src == NULL || dst == NULL)
				ND_PRINT("%s > %s ",
                                        tok2str(llc_values, "Unknown SSAP 0x%02x", ssap),
					tok2str(llc_values, "Unknown DSAP 0x%02x", dsap));
			else
				ND_PRINT("%s %s > %s %s ",
					(src->addr_string)(ndo, src->addr),
                                        tok2str(llc_values, "Unknown SSAP 0x%02x", ssap),
					(dst->addr_string)(ndo, dst->addr),
					tok2str(llc_values, "Unknown DSAP 0x%02x", dsap));
		}
	}

	if (is_u) {
		ND_PRINT("Unnumbered, %s, Flags [%s], length %u",
                       tok2str(llc_cmd_values, "%02x", LLC_U_CMD(control)),
                       tok2str(llc_flag_values,"?",(ssap_field & LLC_GSAP) | (control & LLC_U_POLL)),
                       length + hdrlen);

		if ((control & ~LLC_U_POLL) == LLC_XID) {
			if (length == 0) {
				/*
				 * XID with no payload.
				 * This could, for example, be an SNA
				 * "short form" XID.
                                 */
				return (hdrlen);
			}
			if (caplen < 1) {
				ND_PRINT("[|llc]");
				if (caplen > 0)
					ND_DEFAULTPRINT((const u_char *)p, caplen);
				return (hdrlen);
			}
			if (EXTRACT_U_1(p) == LLC_XID_FI) {
				if (caplen < 3 || length < 3) {
					ND_PRINT("[|llc]");
					if (caplen > 0)
						ND_DEFAULTPRINT((const u_char *)p, caplen);
				} else
					ND_PRINT(": %02x %02x",
						  EXTRACT_U_1(p + 1),
						  EXTRACT_U_1(p + 2));
				return (hdrlen);
			}
		}
	} else {
		if ((control & LLC_S_FMT) == LLC_S_FMT) {
			ND_PRINT("Supervisory, %s, rcv seq %u, Flags [%s], length %u",
				tok2str(llc_supervisory_values,"?",LLC_S_CMD(control)),
				LLC_IS_NR(control),
				tok2str(llc_flag_values,"?",(ssap_field & LLC_GSAP) | (control & LLC_IS_POLL)),
                                length + hdrlen);
			return (hdrlen);	/* no payload to print */
		} else {
			ND_PRINT("Information, send seq %u, rcv seq %u, Flags [%s], length %u",
				LLC_I_NS(control),
				LLC_IS_NR(control),
				tok2str(llc_flag_values,"?",(ssap_field & LLC_GSAP) | (control & LLC_IS_POLL)),
                                length + hdrlen);
		}
	}
	return (-hdrlen);
}