Exemplo n.º 1
0
void
gre_print_0(const u_char *bp, u_int length)
{
	u_int len = length;
	u_int16_t flags, prot;

	flags = EXTRACT_16BITS(bp);
        if (vflag)
            printf(", Flags [%s]",
                   bittok2str(gre_flag_values,"none",flags));

	len -= 2;
	bp += 2;

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

	if ((flags & GRE_CP) | (flags & GRE_RP)) {
		if (len < 2)
			goto trunc;
		if (vflag)
			printf(", sum 0x%x", EXTRACT_16BITS(bp));
		bp += 2;
		len -= 2;

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

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

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

	if (flags & GRE_RP) {
		for (;;) {
			u_int16_t af;
			u_int8_t sreoff;
			u_int8_t srelen;

			if (len < 4)
				goto trunc;
			af = EXTRACT_16BITS(bp);
			sreoff = *(bp + 2);
			srelen = *(bp + 3);
			bp += 4;
			len -= 4;

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

			gre_sre_print(af, sreoff, srelen, bp, len);

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

        if (eflag)
            printf(", proto %s (0x%04x)",
                   tok2str(ethertype_values,"unknown",prot),
                   prot);

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

        if (vflag < 1)
            printf(": "); /* put in a colon as protocol demarc */
        else
            printf("\n\t"); /* if verbose go multiline */

	switch (prot) {
	case ETHERTYPE_IP:
	        ip_print(gndo, bp, len);
		break;
#ifdef INET6
	case ETHERTYPE_IPV6:
		ip6_print(bp, len);
		break;
#endif
	case ETHERTYPE_MPLS:
		mpls_print(bp, len);
		break;
	case ETHERTYPE_IPX:
		ipx_print(bp, len);
		break;
	case ETHERTYPE_ATALK:
		atalk_print(bp, len);
		break;
	case ETHERTYPE_GRE_ISO:
		isoclns_print(bp, len, len);
		break;
	case ETHERTYPE_TEB:
		ether_print(bp, len, len, NULL, NULL);
		break;
	default:
		printf("gre-proto-0x%x", prot);
	}
	return;

trunc:
	printf("[|gre]");
}
Exemplo n.º 2
0
/*
 * RFC3032: MPLS label stack encoding
 */
void
mpls_print(netdissect_options *ndo, const u_char *bp, u_int length)
{
	const u_char *p;
	uint32_t label_entry;
	uint16_t label_stack_depth = 0;
	enum mpls_packet_type pt = PT_UNKNOWN;

	p = bp;
	ND_PRINT((ndo, "MPLS"));
	do {
		ND_TCHECK2(*p, sizeof(label_entry));
		label_entry = EXTRACT_32BITS(p);
		ND_PRINT((ndo, "%s(label %u",
		       (label_stack_depth && ndo->ndo_vflag) ? "\n\t" : " ",
       		       MPLS_LABEL(label_entry)));
		label_stack_depth++;
		if (ndo->ndo_vflag &&
		    MPLS_LABEL(label_entry) < sizeof(mpls_labelname) / sizeof(mpls_labelname[0]))
			ND_PRINT((ndo, " (%s)", mpls_labelname[MPLS_LABEL(label_entry)]));
		ND_PRINT((ndo, ", exp %u", MPLS_EXP(label_entry)));
		if (MPLS_STACK(label_entry))
			ND_PRINT((ndo, ", [S]"));
		ND_PRINT((ndo, ", ttl %u)", MPLS_TTL(label_entry)));

		p += sizeof(label_entry);
	} while (!MPLS_STACK(label_entry));

	/*
	 * Try to figure out the packet type.
	 */
	switch (MPLS_LABEL(label_entry)) {

	case 0:	/* IPv4 explicit NULL label */
	case 3:	/* IPv4 implicit NULL label */
		pt = PT_IPV4;
		break;

	case 2:	/* IPv6 explicit NULL label */
		pt = PT_IPV6;
		break;

	default:
		/*
		 * Generally there's no indication of protocol in MPLS label
		 * encoding.
		 *
		 * However, draft-hsmit-isis-aal5mux-00.txt describes a
		 * technique for encapsulating IS-IS and IP traffic on the
		 * same ATM virtual circuit; you look at the first payload
		 * byte to determine the network layer protocol, based on
		 * the fact that
		 *
		 *	1) the first byte of an IP header is 0x45-0x4f
		 *	   for IPv4 and 0x60-0x6f for IPv6;
		 *
		 *	2) the first byte of an OSI CLNP packet is 0x81,
		 *	   the first byte of an OSI ES-IS packet is 0x82,
		 *	   and the first byte of an OSI IS-IS packet is
		 *	   0x83;
		 *
		 * so the network layer protocol can be inferred from the
		 * first byte of the packet, if the protocol is one of the
		 * ones listed above.
		 *
		 * Cisco sends control-plane traffic MPLS-encapsulated in
		 * this fashion.
		 */
		switch(*p) {

		case 0x45:
		case 0x46:
		case 0x47:
		case 0x48:
		case 0x49:
		case 0x4a:
		case 0x4b:
		case 0x4c:
		case 0x4d:
		case 0x4e:
		case 0x4f:
			pt = PT_IPV4;
			break;

		case 0x60:
		case 0x61:
		case 0x62:
		case 0x63:
		case 0x64:
		case 0x65:
		case 0x66:
		case 0x67:
		case 0x68:
		case 0x69:
		case 0x6a:
		case 0x6b:
		case 0x6c:
		case 0x6d:
		case 0x6e:
		case 0x6f:
			pt = PT_IPV6;
			break;

		case 0x81:
		case 0x82:
		case 0x83:
			pt = PT_OSI;
			break;

		default:
			/* ok bail out - we did not figure out what it is*/
			break;
		}
	}

	/*
	 * Print the payload.
	 */
	if (pt == PT_UNKNOWN) {
		if (!ndo->ndo_suppress_default_print)
			ND_DEFAULTPRINT(p, length - (p - bp));
		return;
	}
	ND_PRINT((ndo, ndo->ndo_vflag ? "\n\t" : " "));
	switch (pt) {

	case PT_IPV4:
		ip_print(ndo, p, length - (p - bp));
		break;

	case PT_IPV6:
		ip6_print(ndo, p, length - (p - bp));
		break;

	case PT_OSI:
		isoclns_print(ndo, p, length - (p - bp), length - (p - bp));
		break;

	default:
		break;
	}
	return;

trunc:
	ND_PRINT((ndo, "[|MPLS]"));
}
Exemplo n.º 3
0
/*
 * Returns non-zero IFF it succeeds in printing the header
 */
int
llc_print(const u_char *p, u_int length, u_int caplen,
	  const u_char *esrc, const u_char *edst, u_short *extracted_ethertype)
{
	u_int8_t dsap_field, dsap, ssap_field, ssap;
	u_int16_t control;
	int is_u;
	register int ret;

	*extracted_ethertype = 0;

	if (caplen < 3) {
		(void)printf("[|llc]");
		default_print((u_char *)p, caplen);
		return(0);
	}

	dsap_field = *p;
	ssap_field = *(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 = *(p + 2);
	if ((control & LLC_U_FMT) == LLC_U_FMT) {
		/*
		 * U frame.
		 */
		is_u = 1;
	} else {
		/*
		 * The control field in I and S frames is
		 * 2 bytes...
		 */
		if (caplen < 4) {
			(void)printf("[|llc]");
			default_print((u_char *)p, caplen);
			return(0);
		}

		/*
		 * ...and is little-endian.
		 */
		control = EXTRACT_LE_16BITS(p + 2);
		is_u = 0;
	}

	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 <= ETHERMTU, 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 (eflag)
		printf("IPX 802.3: ");

            ipx_print(p, length);
            return (1);
	}

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

	if (eflag) {
                printf("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) {
			printf(", ctrl 0x%02x: ", control);
		} else {
			printf(", ctrl 0x%04x: ", control);
		}
	}

	if (ssap == LLCSAP_8021D && dsap == LLCSAP_8021D &&
	    control == LLC_UI) {
		stp_print(p+3, length-3);
		return (1);
	}

	if (ssap == LLCSAP_IP && dsap == LLCSAP_IP &&
	    control == LLC_UI) {
		ip_print(gndo, p+4, length-4);
		return (1);
	}

	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.
		 *
		 * Skip DSAP, LSAP, and control field.
		 */
                if (eflag)
                        printf("IPX 802.2: ");

		ipx_print(p+3, length-3);
		return (1);
	}

#ifdef TCPDUMP_DO_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).
		 */

		/*
		 * Skip the LLC header.
		 */
		if (is_u) {
			p += 3;
			length -= 3;
			caplen -= 3;
		} else {
			p += 4;
			length -= 4;
			caplen -= 4;
		}
		netbeui_print(control, p, length);
		return (1);
	}
#endif
	if (ssap == LLCSAP_ISONS && dsap == LLCSAP_ISONS
	    && control == LLC_UI) {
		isoclns_print(p + 3, length - 3, caplen - 3);
		return (1);
	}

	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?
		 */
		ret = snap_print(p+3, length-3, caplen-3, 2);
		if (ret)
			return (ret);
	}

	if (!eflag) {
		if (ssap == dsap) {
			if (esrc == NULL || edst == NULL)
				(void)printf("%s ", tok2str(llc_values, "Unknown DSAP 0x%02x", dsap));
			else
				(void)printf("%s > %s %s ",
						etheraddr_string(esrc),
						etheraddr_string(edst),
						tok2str(llc_values, "Unknown DSAP 0x%02x", dsap));
		} else {
			if (esrc == NULL || edst == NULL)
				(void)printf("%s > %s ",
                                        tok2str(llc_values, "Unknown SSAP 0x%02x", ssap),
					tok2str(llc_values, "Unknown DSAP 0x%02x", dsap));
			else
				(void)printf("%s %s > %s %s ",
					etheraddr_string(esrc),
                                        tok2str(llc_values, "Unknown SSAP 0x%02x", ssap),
					etheraddr_string(edst),
					tok2str(llc_values, "Unknown DSAP 0x%02x", dsap));
		}
	}

	if (is_u) {
		printf("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);

		p += 3;
		length -= 3;
		caplen -= 3;

		if ((control & ~LLC_U_POLL) == LLC_XID) {
			if (*p == LLC_XID_FI) {
				printf(": %02x %02x", p[1], p[2]);
				p += 3;
				length -= 3;
				caplen -= 3;
			}
		}
	} else {
		if ((control & LLC_S_FMT) == LLC_S_FMT) {
			(void)printf("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);
		} else {
			(void)printf("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);
		}
		p += 4;
		length -= 4;
		caplen -= 4;
	}
	return(1);
}
Exemplo n.º 4
0
/*
 * Returns non-zero IFF it succeeds in printing the header
 */
int
llc_print(const u_char *p, u_int length, u_int caplen,
	  const u_char *esrc, const u_char *edst, u_short *extracted_ethertype)
{
	u_int8_t dsap, ssap;
	u_int16_t control;
	int is_u;
	register int ret;

	if (caplen < 3) {
		(void)printf("[|llc]");
		default_print((u_char *)p, caplen);
		return(0);
	}

	dsap = *p;
	ssap = *(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 = *(p + 2);
	if ((control & LLC_U_FMT) == LLC_U_FMT) {
		/*
		 * U frame.
		 */
		is_u = 1;
	} else {
		/*
		 * The control field in I and S frames is
		 * 2 bytes...
		 */
		if (caplen < 4) {
			(void)printf("[|llc]");
			default_print((u_char *)p, caplen);
			return(0);
		}

		/*
		 * ...and is little-endian.
		 */
		control = EXTRACT_LE_16BITS(p + 2);
		is_u = 0;
	}

#if !defined(EMBED) || defined(CONFIG_IPX) || defined(CONFIG_IPX_MODULE)
	if (ssap == LLCSAP_GLOBAL && dsap == 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 <= ETHERMTU, 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 (eflag)
		printf("IPX-802.3: ");

            ipx_print(p, length);
            return (1);
	}
#endif

	if (eflag) {
		if (is_u) {
			printf("LLC, dsap %s (0x%02x), ssap %s (0x%02x), cmd 0x%02x: ",
			    tok2str(llc_values, "Unknown", dsap),
			    dsap,
			    tok2str(llc_values, "Unknown", ssap),
			    ssap,
			    control);
		} else {
			printf("LLC, dsap %s (0x%02x), ssap %s (0x%02x), cmd 0x%04x: ",
			    tok2str(llc_values, "Unknown", dsap),
			    dsap,
			    tok2str(llc_values, "Unknown", ssap),
			    ssap,
			    control);
		}
	}

#if !defined(EMBED) || defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
	if (ssap == LLCSAP_8021D && dsap == LLCSAP_8021D &&
	    control == LLC_UI) {
		stp_print(p+3, length-3);
		return (1);
	}
#endif

	if (ssap == LLCSAP_IP && dsap == LLCSAP_IP &&
	    control == LLC_UI) {
		ip_print(gndo, p+4, length-4);
		return (1);
	}

#if !defined(EMBED) || defined(CONFIG_IPX) || defined(CONFIG_IPX_MODULE)
	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.
		 *
		 * Skip DSAP, LSAP, and control field.
		 */
		printf("(NOV-802.2) ");
		ipx_print(p+3, length-3);
		return (1);
	}
#endif

#ifdef TCPDUMP_DO_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).
		 */

		/*
		 * Skip the LLC header.
		 */
		if (is_u) {
			p += 3;
			length -= 3;
			caplen -= 3;
		} else {
			p += 4;
			length -= 4;
			caplen -= 4;
		}
		netbeui_print(control, p, length);
		return (1);
	}
#endif
#if !defined(EMBED)
	if (ssap == LLCSAP_ISONS && dsap == LLCSAP_ISONS
	    && control == LLC_UI) {
		isoclns_print(p + 3, length - 3, caplen - 3);
		return (1);
	}
#endif

	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?
		 */
		ret = snap_print(p+3, length-3, caplen-3, extracted_ethertype,
		    2);
		if (ret)
			return (ret);
	}

	if (!eflag) {
		if ((ssap & ~LLC_GSAP) == dsap) {
			if (esrc == NULL || edst == NULL)
				(void)printf("%s ", llcsap_string(dsap));
			else
				(void)printf("%s > %s %s ",
						etheraddr_string(esrc),
						etheraddr_string(edst),
						llcsap_string(dsap));
		} else {
			if (esrc == NULL || edst == NULL)
				(void)printf("%s > %s ",
					llcsap_string(ssap & ~LLC_GSAP),
					llcsap_string(dsap));
			else
				(void)printf("%s %s > %s %s ",
					etheraddr_string(esrc),
					llcsap_string(ssap & ~LLC_GSAP),
					etheraddr_string(edst),
					llcsap_string(dsap));
		}
	}

	if (is_u) {
		const char *m;
		char f;

		m = tok2str(cmd2str, "%02x", LLC_U_CMD(control));
		switch ((ssap & LLC_GSAP) | (control & LLC_U_POLL)) {
			case 0:			f = 'C'; break;
			case LLC_GSAP:		f = 'R'; break;
			case LLC_U_POLL:	f = 'P'; break;
			case LLC_GSAP|LLC_U_POLL: f = 'F'; break;
			default:		f = '?'; break;
		}

		printf("%s/%c", m, f);

		p += 3;
		length -= 3;
		caplen -= 3;

		if ((control & ~LLC_U_POLL) == LLC_XID) {
			if (*p == LLC_XID_FI) {
				printf(": %02x %02x", p[1], p[2]);
				p += 3;
				length -= 3;
				caplen -= 3;
			}
		}
	} else {
		char f;

		switch ((ssap & LLC_GSAP) | (control & LLC_IS_POLL)) {
			case 0:			f = 'C'; break;
			case LLC_GSAP:		f = 'R'; break;
			case LLC_IS_POLL:	f = 'P'; break;
			case LLC_GSAP|LLC_IS_POLL: f = 'F'; break;
			default:		f = '?'; break;
		}

		if ((control & LLC_S_FMT) == LLC_S_FMT) {
			static const char *llc_s[] = { "rr", "rej", "rnr", "03" };
			(void)printf("%s (r=%d,%c)",
				llc_s[LLC_S_CMD(control)],
				LLC_IS_NR(control),
				f);
		} else {
			(void)printf("I (s=%d,r=%d,%c)",
				LLC_I_NS(control),
				LLC_IS_NR(control),
				f);
		}
		p += 4;
		length -= 4;
		caplen -= 4;
	}
	return(1);
}
Exemplo n.º 5
0
u_int
chdlc_print(netdissect_options *ndo, const u_char *p, u_int length)
{
	u_int proto;
	const u_char *bp = p;

	ndo->ndo_protocol = "chdlc";
	if (length < CHDLC_HDRLEN)
		goto trunc;
	ND_TCHECK_LEN(p, CHDLC_HDRLEN);
	proto = GET_BE_U_2(p + 2);
	if (ndo->ndo_eflag) {
                ND_PRINT("%s, ethertype %s (0x%04x), length %u: ",
                       tok2str(chdlc_cast_values, "0x%02x", GET_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 (GET_U_1(p + 1) == NLPID_CLNP ||
                    GET_U_1(p + 1) == NLPID_ESIS ||
                    GET_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_trunc(ndo);
	return (ND_BYTES_AVAILABLE_AFTER(bp));
}
Exemplo n.º 6
0
/*
 * RFC3032: MPLS label stack encoding
 */
void
mpls_print(const u_char *bp, u_int length)
{
	const u_char *p;
	u_int32_t label_entry;
        u_int16_t label_stack_depth = 0;

	p = bp;
	printf("MPLS");
	do {
		TCHECK2(*p, sizeof(label_entry));
		label_entry = EXTRACT_32BITS(p);
		printf("%s(label %u",
                       label_stack_depth ? "\n\t" : " ",
                       MPLS_LABEL(label_entry));
                label_stack_depth++;
		if (vflag &&
		    MPLS_LABEL(label_entry) < sizeof(mpls_labelname) / sizeof(mpls_labelname[0]))
			printf(" (%s)", mpls_labelname[MPLS_LABEL(label_entry)]);
		printf(", exp %u", MPLS_EXP(label_entry));
		if (MPLS_STACK(label_entry))
			printf(", [S]");
		printf(", ttl %u)", MPLS_TTL(label_entry));

		p += sizeof(label_entry);
	} while (!MPLS_STACK(label_entry));

	switch (MPLS_LABEL(label_entry)) {
	case 0:	/* IPv4 explicit NULL label */
        case 3:	/* IPv4 implicit NULL label */
                if (vflag>0) {
                        printf("\n\t");
                        ip_print(gndo, p, length - (p - bp));
                }
                else printf(", IP, length: %u",length);
		break;
#ifdef INET6
	case 2:	/* IPv6 explicit NULL label */
                if (vflag>0) {
                        printf("\n\t");
                        ip6_print(p, length - (p - bp));
                }
                else printf(", IPv6, length: %u",length);
		break;
#endif
	default:
		/*
		 * Generally there's no indication of protocol in MPLS label
		 * encoding, however draft-hsmit-isis-aal5mux-00.txt describes
                 * a technique that looks at the first payload byte if the BOS (bottom of stack)
                 * bit is set and tries to determine the network layer protocol
                 * 0x45-0x4f is IPv4
                 * 0x60-0x6f is IPv6
                 * 0x81-0x83 is OSI (CLNP,ES-IS,IS-IS)
                 * this technique is sometimes known as NULL encapsulation
                 * and decoding is particularly useful for control-plane traffic [BGP]
                 * which cisco by default sends MPLS encapsulated
		 */

                if (MPLS_STACK(label_entry)) { /* only do this if the stack bit is set */
                    switch(*p) {
                    case 0x45:
                    case 0x46:
                    case 0x47:
                    case 0x48:
                    case 0x49:
                    case 0x4a:
                    case 0x4b:
                    case 0x4c:
                    case 0x4d:
                    case 0x4e:
                    case 0x4f:
		        if (vflag>0) {
                            printf("\n\t");
                            ip_print(gndo, p, length - (p - bp));
			    }
                        else printf(", IP, length: %u",length);
                        break;
#ifdef INET6
                    case 0x60:
                    case 0x61:
                    case 0x62:
                    case 0x63:
                    case 0x64:
                    case 0x65:
                    case 0x66:
                    case 0x67:
                    case 0x68:
                    case 0x69:
                    case 0x6a:
                    case 0x6b:
                    case 0x6c:
                    case 0x6d:
                    case 0x6e:
                    case 0x6f:
		        if (vflag>0) {
                            printf("\n\t");
                            ip6_print(p, length - (p - bp));
                            }
			else printf(", IPv6, length: %u",length);
                        break;
#endif
                    case 0x81:
                    case 0x82:
                    case 0x83:
		        if (vflag>0) {
                            printf("\n\t");
                            isoclns_print(p, length - (p - bp), length - (p - bp));
			    }
			else printf(", OSI, length: %u",length);
                        break;
                    default:
                        /* ok bail out - we did not figure out what it is*/
                        break;
                    }
                }
                return;
	}

trunc:
	printf("[|MPLS]");
}
Exemplo n.º 7
0
int
ethertype_print(netdissect_options *ndo,
                u_short ether_type, const u_char *p,
                u_int length, u_int caplen,
                const struct lladdr_info *src, const struct lladdr_info *dst)
{
	switch (ether_type) {

	case ETHERTYPE_IP:
	        ip_print(ndo, p, length);
		return (1);

	case ETHERTYPE_IPV6:
		ip6_print(ndo, p, length);
		return (1);

	case ETHERTYPE_ARP:
	case ETHERTYPE_REVARP:
	        arp_print(ndo, p, length, caplen);
		return (1);

	case ETHERTYPE_DN:
		decnet_print(ndo, p, length, caplen);
		return (1);

	case ETHERTYPE_ATALK:
		if (ndo->ndo_vflag)
			ND_PRINT((ndo, "et1 "));
		atalk_print(ndo, p, length);
		return (1);

	case ETHERTYPE_AARP:
		aarp_print(ndo, p, length);
		return (1);

	case ETHERTYPE_IPX:
		ND_PRINT((ndo, "(NOV-ETHII) "));
		ipx_print(ndo, p, length);
		return (1);

	case ETHERTYPE_ISO:
		if (length == 0 || caplen == 0) {
			ND_PRINT((ndo, " [|osi]"));
			return (1);
		}
		isoclns_print(ndo, p + 1, length - 1, caplen - 1);
		return(1);

	case ETHERTYPE_PPPOED:
	case ETHERTYPE_PPPOES:
	case ETHERTYPE_PPPOED2:
	case ETHERTYPE_PPPOES2:
		pppoe_print(ndo, p, length);
		return (1);

	case ETHERTYPE_EAPOL:
	        eap_print(ndo, p, length);
		return (1);

	case ETHERTYPE_RRCP:
	        rrcp_print(ndo, p, length, src, dst);
		return (1);

	case ETHERTYPE_PPP:
		if (length) {
			ND_PRINT((ndo, ": "));
			ppp_print(ndo, p, length);
		}
		return (1);

	case ETHERTYPE_MPCP:
	        mpcp_print(ndo, p, length);
		return (1);

	case ETHERTYPE_SLOW:
	        slow_print(ndo, p, length);
		return (1);

	case ETHERTYPE_CFM:
	case ETHERTYPE_CFM_OLD:
		cfm_print(ndo, p, length);
		return (1);

	case ETHERTYPE_LLDP:
		lldp_print(ndo, p, length);
		return (1);

        case ETHERTYPE_NSH:
                nsh_print(ndo, p, length);
                return (1);

        case ETHERTYPE_LOOPBACK:
		loopback_print(ndo, p, length);
                return (1);

	case ETHERTYPE_MPLS:
	case ETHERTYPE_MPLS_MULTI:
		mpls_print(ndo, p, length);
		return (1);

	case ETHERTYPE_TIPC:
		tipc_print(ndo, p, length, caplen);
		return (1);

	case ETHERTYPE_MS_NLB_HB:
		msnlb_print(ndo, p);
		return (1);

        case ETHERTYPE_GEONET_OLD:
        case ETHERTYPE_GEONET:
                geonet_print(ndo, p, length, src);
                return (1);

        case ETHERTYPE_CALM_FAST:
                calm_fast_print(ndo, p, length, src);
                return (1);

	case ETHERTYPE_AOE:
		aoe_print(ndo, p, length);
		return (1);

	case ETHERTYPE_MEDSA:
		medsa_print(ndo, p, length, caplen, src, dst);
		return (1);

	case ETHERTYPE_LAT:
	case ETHERTYPE_SCA:
	case ETHERTYPE_MOPRC:
	case ETHERTYPE_MOPDL:
	case ETHERTYPE_IEEE1905_1:
		/* default_print for now */
	default:
		return (0);
	}
}
Exemplo n.º 8
0
/*
 * This is the top level routine of the printer.  'p' points
 * to the LLC/SNAP header of the packet, 'h->ts' is the timestamp,
 * 'h->len' is the length of the packet off the wire, and 'h->caplen'
 * is the number of bytes actually captured.
 */
u_int
atm_if_print(const struct pcap_pkthdr *h, const u_char *p)
{
	u_int caplen = h->caplen;
	u_int length = h->len;
	u_int32_t llchdr;
	u_int hdrlen = 0;

	if (caplen < 8) {
		printf("[|atm]");
		return (caplen);
	}

        /* Cisco Style NLPID ? */
        if (*p == LLC_UI) {
            if (eflag)
                printf("CNLPID ");
            isoclns_print(p+1, length-1, caplen-1);
            return hdrlen;
        }

	/*
	 * Extract the presumed LLC header into a variable, for quick
	 * testing.
	 * Then check for a header that's neither a header for a SNAP
	 * packet nor an RFC 2684 routed NLPID-formatted PDU nor
	 * an 802.2-but-no-SNAP IP packet.
	 */
	llchdr = EXTRACT_24BITS(p);
	if (llchdr != LLC_UI_HDR(LLCSAP_SNAP) &&
	    llchdr != LLC_UI_HDR(LLCSAP_ISONS) &&
	    llchdr != LLC_UI_HDR(LLCSAP_IP)) {
		/*
		 * XXX - assume 802.6 MAC header from Fore driver.
		 *
		 * Unfortunately, the above list doesn't check for
		 * all known SAPs, doesn't check for headers where
		 * the source and destination SAP aren't the same,
		 * and doesn't check for non-UI frames.  It also
		 * runs the risk of an 802.6 MAC header that happens
		 * to begin with one of those values being
		 * incorrectly treated as an 802.2 header.
		 *
		 * So is that Fore driver still around?  And, if so,
		 * is it still putting 802.6 MAC headers on ATM
		 * packets?  If so, could it be changed to use a
		 * new DLT_IEEE802_6 value if we added it?
		 */
		if (eflag)
			printf("%08x%08x %08x%08x ",
			       EXTRACT_32BITS(p),
			       EXTRACT_32BITS(p+4),
			       EXTRACT_32BITS(p+8),
			       EXTRACT_32BITS(p+12));
		p += 20;
		length -= 20;
		caplen -= 20;
		hdrlen += 20;
	}
	atm_llc_print(p, length, caplen);
	return (hdrlen);
}
Exemplo n.º 9
0
/*
 * Returns non-zero IFF it succeeds in printing the header
 */
int
llc_print(const u_char *p, u_int length, u_int caplen,
	  const u_char *esrc, const u_char *edst)
{
	struct llc llc;
	register u_short et;
	register int ret;

	if (caplen < 3) {
		(void)printf("[|llc]");
		default_print((u_char *)p, caplen);
		return(0);
	}

	/* Watch out for possible alignment problems */
	memcpy((char *)&llc, (char *)p, min(caplen, sizeof(llc)));

	if (llc.ssap == LLCSAP_GLOBAL && llc.dsap == LLCSAP_GLOBAL) {
		ipx_print(p, length);
		return (1);
	}
#ifdef notyet
	else if (p[0] == 0xf0 && p[1] == 0xf0)
		netbios_print(p, length);
#endif
	if (llc.ssap == LLCSAP_ISONS && llc.dsap == LLCSAP_ISONS
	    && llc.llcui == LLC_UI) {
		isoclns_print(p + 3, length - 3, caplen - 3, esrc, edst);
		return (1);
	}

	if (llc.ssap == LLCSAP_SNAP && llc.dsap == LLCSAP_SNAP
	    && llc.llcui == LLC_UI) {
		if (caplen < sizeof(llc)) {
		    (void)printf("[|llc-snap]");
		    default_print((u_char *)p, caplen);
		    return (0);
		}
		if (vflag)
			(void)printf("snap %s ", protoid_string(llc.llcpi));

		caplen -= sizeof(llc);
		length -= sizeof(llc);
		p += sizeof(llc);

		/* This is an encapsulated Ethernet packet */
		et = EXTRACT_16BITS(&llc.ethertype[0]);
		ret = ether_encap_print(et, p, length, caplen);
		if (ret)
			return (ret);
	}

	if ((llc.ssap & ~LLC_GSAP) == llc.dsap) {
		if (eflag)
			(void)printf("%s ", llcsap_string(llc.dsap));
		else
			(void)printf("%s > %s %s ",
					etheraddr_string(esrc),
					etheraddr_string(edst),
					llcsap_string(llc.dsap));
	} else {
		if (eflag)
			(void)printf("%s > %s ",
				llcsap_string(llc.ssap & ~LLC_GSAP),
				llcsap_string(llc.dsap));
		else
			(void)printf("%s %s > %s %s ",
				etheraddr_string(esrc),
				llcsap_string(llc.ssap & ~LLC_GSAP),
				etheraddr_string(edst),
				llcsap_string(llc.dsap));
	}

	if ((llc.llcu & LLC_U_FMT) == LLC_U_FMT) {
		const char *m;
		char f;
		m = tok2str(cmd2str, "%02x", LLC_U_CMD(llc.llcu));
		switch ((llc.ssap & LLC_GSAP) | (llc.llcu & LLC_U_POLL)) {
		    case 0:			f = 'C'; break;
		    case LLC_GSAP:		f = 'R'; break;
		    case LLC_U_POLL:		f = 'P'; break;
		    case LLC_GSAP|LLC_U_POLL:	f = 'F'; break;
		    default:			f = '?'; break;
		}

		printf("%s/%c", m, f);

		p += 3;
		length -= 3;
		caplen -= 3;

		if ((llc.llcu & ~LLC_U_POLL) == LLC_XID) {
		    if (*p == LLC_XID_FI) {
			printf(": %02x %02x", p[1], p[2]);
			p += 3;
			length -= 3;
			caplen -= 3;
		    }
		}
	} else {
		char f;
		llc.llcis = ntohs(llc.llcis);
		switch ((llc.ssap & LLC_GSAP) | (llc.llcu & LLC_U_POLL)) {
		    case 0:			f = 'C'; break;
		    case LLC_GSAP:		f = 'R'; break;
		    case LLC_U_POLL:		f = 'P'; break;
		    case LLC_GSAP|LLC_U_POLL:	f = 'F'; break;
		    default:			f = '?'; break;
		}

		if ((llc.llcu & LLC_S_FMT) == LLC_S_FMT) {
			static char *llc_s[] = { "rr", "rej", "rnr", "03" };
			(void)printf("%s (r=%d,%c)",
				llc_s[LLC_S_CMD(llc.llcis)],
				LLC_IS_NR(llc.llcis),
				f);
		} else {
			(void)printf("I (s=%d,r=%d,%c)",
				LLC_I_NS(llc.llcis),
				LLC_IS_NR(llc.llcis),
				f);
		}
		p += 4;
		length -= 4;
		caplen -= 4;
	}
	(void)printf(" len=%d", length);
	if (caplen > 0) {
		default_print_unaligned(p, caplen);
	}
	return(1);
}
Exemplo n.º 10
0
/*
 * This is the top level routine of the printer.  'p' points
 * to the ether header of the packet, 'h->ts' is the timestamp,
 * 'h->len' is the length of the packet off the wire, and 'h->caplen'
 * is the number of bytes actually captured.
 */
u_int
null_if_print(const struct pcap_pkthdr *h, const u_char *p)
{
	u_int length = h->len;
	u_int caplen = h->caplen;
	u_int family;

	if (caplen < NULL_HDRLEN) {
		printf("[|null]");
		return (NULL_HDRLEN);
	}

	memcpy((char *)&family, (char *)p, sizeof(family));

	/*
	 * This isn't necessarily in our host byte order; if this is
	 * a DLT_LOOP capture, it's in network byte order, and if
	 * this is a DLT_NULL capture from a machine with the opposite
	 * byte-order, it's in the opposite byte order from ours.
	 *
	 * If the upper 16 bits aren't all zero, assume it's byte-swapped.
	 */
	if ((family & 0xFFFF0000) != 0)
		family = SWAPLONG(family);

	if (eflag)
		null_hdr_print(family, length);

	length -= NULL_HDRLEN;
	caplen -= NULL_HDRLEN;
	p += NULL_HDRLEN;

	switch (family) {

	case BSD_AFNUM_INET:
		ip_print(gndo, p, length);
		break;

#ifdef INET6
	case BSD_AFNUM_INET6_BSD:
	case BSD_AFNUM_INET6_FREEBSD:
	case BSD_AFNUM_INET6_DARWIN:
		ip6_print(gndo, p, length);
		break;
#endif

	case BSD_AFNUM_ISO:
		isoclns_print(p, length, caplen);
		break;

	case BSD_AFNUM_APPLETALK:
		atalk_print(p, length);
		break;

	case BSD_AFNUM_IPX:
		ipx_print(p, length);
		break;

	default:
		/* unknown AF_ value */
		if (!eflag)
			null_hdr_print(family, length + NULL_HDRLEN);
		if (!suppress_default_print)
			default_print(p, caplen);
	}

	return (NULL_HDRLEN);
}
Exemplo n.º 11
0
/*
 * This is the top level routine of the printer.  'p' points
 * to the ether header of the packet, 'h->ts' is the timestamp,
 * 'h->len' is the length of the packet off the wire, and 'h->caplen'
 * is the number of bytes actually captured.
 */
u_int
null_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p)
{
	u_int length = h->len;
	u_int caplen = h->caplen;
	uint32_t family;

	ndo->ndo_protocol = "null_if";
	if (caplen < NULL_HDRLEN)
		goto trunc;

	ND_TCHECK_4(p);
	family = GET_HE_U_4(p);

	/*
	 * This isn't necessarily in our host byte order; if this is
	 * a DLT_LOOP capture, it's in network byte order, and if
	 * this is a DLT_NULL capture from a machine with the opposite
	 * byte-order, it's in the opposite byte order from ours.
	 *
	 * If the upper 16 bits aren't all zero, assume it's byte-swapped.
	 */
	if ((family & 0xFFFF0000) != 0)
		family = SWAPLONG(family);

	if (ndo->ndo_eflag)
		null_hdr_print(ndo, family, length);

	length -= NULL_HDRLEN;
	caplen -= NULL_HDRLEN;
	p += NULL_HDRLEN;

	switch (family) {

	case BSD_AFNUM_INET:
		ip_print(ndo, p, length);
		break;

	case BSD_AFNUM_INET6_BSD:
	case BSD_AFNUM_INET6_FREEBSD:
	case BSD_AFNUM_INET6_DARWIN:
		ip6_print(ndo, p, length);
		break;

	case BSD_AFNUM_ISO:
		isoclns_print(ndo, p, length);
		break;

	case BSD_AFNUM_APPLETALK:
		atalk_print(ndo, p, length);
		break;

	case BSD_AFNUM_IPX:
		ipx_print(ndo, p, length);
		break;

	default:
		/* unknown AF_ value */
		if (!ndo->ndo_eflag)
			null_hdr_print(ndo, family, length + NULL_HDRLEN);
		if (!ndo->ndo_suppress_default_print)
			ND_DEFAULTPRINT(p, caplen);
	}

	return (NULL_HDRLEN);
trunc:
	nd_print_trunc(ndo);
	return (NULL_HDRLEN);
}
Exemplo n.º 12
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_trunc(ndo);
}