Exemplo n.º 1
0
int
snap_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen,
	const struct lladdr_info *src, const struct lladdr_info *dst,
	u_int bridge_pad)
{
	uint32_t orgcode;
	u_short et;
	int ret;

	ND_TCHECK_5(p);
	if (caplen < 5 || length < 5)
		goto trunc;
	orgcode = EXTRACT_BE_U_3(p);
	et = EXTRACT_BE_U_2(p + 3);

	if (ndo->ndo_eflag) {
		/*
		 * Somebody's already printed the MAC addresses, if there
		 * are any, so just print the SNAP header, not the MAC
		 * addresses.
		 */
		ND_PRINT("oui %s (0x%06x), %s %s (0x%04x), length %u: ",
		     tok2str(oui_values, "Unknown", orgcode),
		     orgcode,
		     (orgcode == 0x000000 ? "ethertype" : "pid"),
		     tok2str(oui_to_struct_tok(orgcode), "Unknown", et),
		     et, length - 5);
	}
	p += 5;
	length -= 5;
	caplen -= 5;

	switch (orgcode) {
	case OUI_ENCAP_ETHER:
	case OUI_CISCO_90:
		/*
		 * This is an encapsulated Ethernet packet,
		 * or a packet bridged by some piece of
		 * Cisco hardware; the protocol ID is
		 * an Ethernet protocol type.
		 */
		ret = ethertype_print(ndo, et, p, length, caplen, src, dst);
		if (ret)
			return (ret);
		break;

	case OUI_APPLETALK:
		if (et == ETHERTYPE_ATALK) {
			/*
			 * No, I have no idea why Apple used one
			 * of their own OUIs, rather than
			 * 0x000000, and an Ethernet packet
			 * type, for Appletalk data packets,
			 * but used 0x000000 and an Ethernet
			 * packet type for AARP packets.
			 */
			ret = ethertype_print(ndo, et, p, length, caplen, src, dst);
			if (ret)
				return (ret);
		}
		break;

	case OUI_CISCO:
                switch (et) {
                case PID_CISCO_CDP:
                        cdp_print(ndo, p, length, caplen);
                        return (1);
                case PID_CISCO_DTP:
                        dtp_print(ndo, p, length);
                        return (1);
                case PID_CISCO_UDLD:
                        udld_print(ndo, p, length);
                        return (1);
                case PID_CISCO_VTP:
                        vtp_print(ndo, p, length);
                        return (1);
                case PID_CISCO_PVST:
                case PID_CISCO_VLANBRIDGE:
                        stp_print(ndo, p, length);
                        return (1);
                default:
                        break;
                }
		break;

	case OUI_RFC2684:
		switch (et) {

		case PID_RFC2684_ETH_FCS:
		case PID_RFC2684_ETH_NOFCS:
			/*
			 * XXX - remove the last two bytes for
			 * PID_RFC2684_ETH_FCS?
			 */
			/*
			 * Skip the padding.
			 */
			ND_TCHECK_LEN(p, bridge_pad);
			caplen -= bridge_pad;
			length -= bridge_pad;
			p += bridge_pad;

			/*
			 * What remains is an Ethernet packet.
			 */
			ether_print(ndo, p, length, caplen, NULL, NULL);
			return (1);

		case PID_RFC2684_802_5_FCS:
		case PID_RFC2684_802_5_NOFCS:
			/*
			 * XXX - remove the last two bytes for
			 * PID_RFC2684_ETH_FCS?
			 */
			/*
			 * Skip the padding, but not the Access
			 * Control field.
			 */
			ND_TCHECK_LEN(p, bridge_pad);
			caplen -= bridge_pad;
			length -= bridge_pad;
			p += bridge_pad;

			/*
			 * What remains is an 802.5 Token Ring
			 * packet.
			 */
			token_print(ndo, p, length, caplen);
			return (1);

		case PID_RFC2684_FDDI_FCS:
		case PID_RFC2684_FDDI_NOFCS:
			/*
			 * XXX - remove the last two bytes for
			 * PID_RFC2684_ETH_FCS?
			 */
			/*
			 * Skip the padding.
			 */
			ND_TCHECK_LEN(p, bridge_pad + 1);
			caplen -= bridge_pad + 1;
			length -= bridge_pad + 1;
			p += bridge_pad + 1;

			/*
			 * What remains is an FDDI packet.
			 */
			fddi_print(ndo, p, length, caplen);
			return (1);

		case PID_RFC2684_BPDU:
			stp_print(ndo, p, length);
			return (1);
		}
	}
	if (!ndo->ndo_eflag) {
		/*
		 * Nobody printed the link-layer addresses, so print them, if
		 * we have any.
		 */
		if (src != NULL && dst != NULL) {
			ND_PRINT("%s > %s ",
				(src->addr_string)(ndo, src->addr),
				(dst->addr_string)(ndo, dst->addr));
		}
		/*
		 * Print the SNAP header, but if the OUI is 000000, don't
		 * bother printing it, and report the PID as being an
		 * ethertype.
		 */
		if (orgcode == 0x000000) {
			ND_PRINT("SNAP, ethertype %s (0x%04x), length %u: ",
			     tok2str(ethertype_values, "Unknown", et),
			     et, length);
		} else {
			ND_PRINT("SNAP, oui %s (0x%06x), pid %s (0x%04x), length %u: ",
			     tok2str(oui_values, "Unknown", orgcode),
			     orgcode,
			     tok2str(oui_to_struct_tok(orgcode), "Unknown", et),
			     et, length);
		}
	}
	return (0);

trunc:
	ND_PRINT("[|snap]");
	return (1);
}
Exemplo n.º 2
0
int
snap_print(const u_char *p, u_int length, u_int caplen,
           u_short *extracted_ethertype, u_int bridge_pad)
{
    u_int32_t orgcode;
    register u_short et;
    register int ret;

    TCHECK2(*p, 5);
    orgcode = EXTRACT_24BITS(p);
    et = EXTRACT_16BITS(p + 3);

    if (eflag) {
        const struct tok *tok = null_values;
        const struct oui_tok *otp;

        for (otp = &oui_to_tok[0]; otp->tok != NULL; otp++) {
            if (otp->oui == orgcode) {
                tok = otp->tok;
                break;
            }
        }
        (void)printf("oui %s (0x%06x), %s %s (0x%04x): ",
                     tok2str(oui_values, "Unknown", orgcode),
                     orgcode,
                     (orgcode == 0x000000 ? "ethertype" : "pid"),
                     tok2str(tok, "Unknown", et),
                     et);
    }
    p += 5;
    length -= 5;
    caplen -= 5;

    switch (orgcode) {
    case OUI_ENCAP_ETHER:
    case OUI_CISCO_90:
        /*
         * This is an encapsulated Ethernet packet,
         * or a packet bridged by some piece of
         * Cisco hardware; the protocol ID is
         * an Ethernet protocol type.
         */
        ret = ether_encap_print(et, p, length, caplen,
                                extracted_ethertype);
        if (ret)
            return (ret);
        break;

    case OUI_APPLETALK:
        if (et == ETHERTYPE_ATALK) {
            /*
             * No, I have no idea why Apple used one
             * of their own OUIs, rather than
             * 0x000000, and an Ethernet packet
             * type, for Appletalk data packets,
             * but used 0x000000 and an Ethernet
             * packet type for AARP packets.
             */
            ret = ether_encap_print(et, p, length, caplen,
                                    extracted_ethertype);
            if (ret)
                return (ret);
        }
        break;

    case OUI_CISCO:
        if (et == PID_CISCO_CDP) {
            cdp_print(p, length, caplen);
            return (1);
        }
        break;

    case OUI_RFC2684:
        switch (et) {

        case PID_RFC2684_ETH_FCS:
        case PID_RFC2684_ETH_NOFCS:
            /*
             * XXX - remove the last two bytes for
             * PID_RFC2684_ETH_FCS?
             */
            /*
             * Skip the padding.
             */
            TCHECK2(*p, bridge_pad);
            caplen -= bridge_pad;
            length -= bridge_pad;
            p += bridge_pad;

            /*
             * What remains is an Ethernet packet.
             */
            ether_print(p, length, caplen);
            return (1);

        case PID_RFC2684_802_5_FCS:
        case PID_RFC2684_802_5_NOFCS:
            /*
             * XXX - remove the last two bytes for
             * PID_RFC2684_ETH_FCS?
             */
            /*
             * Skip the padding, but not the Access
             * Control field.
             */
            TCHECK2(*p, bridge_pad);
            caplen -= bridge_pad;
            length -= bridge_pad;
            p += bridge_pad;

            /*
             * What remains is an 802.5 Token Ring
             * packet.
             */
            token_print(p, length, caplen);
            return (1);

        case PID_RFC2684_FDDI_FCS:
        case PID_RFC2684_FDDI_NOFCS:
            /*
             * XXX - remove the last two bytes for
             * PID_RFC2684_ETH_FCS?
             */
            /*
             * Skip the padding.
             */
            TCHECK2(*p, bridge_pad + 1);
            caplen -= bridge_pad + 1;
            length -= bridge_pad + 1;
            p += bridge_pad + 1;

            /*
             * What remains is an FDDI packet.
             */
            fddi_print(p, length, caplen);
            return (1);

        case PID_RFC2684_BPDU:
            stp_print(p, length);
            return (1);
        }
    }
    return (0);

trunc:
    (void)printf("[|snap]");
    return (1);
}
Exemplo n.º 3
0
/*
 * This is the top level routine of the printer.  'sp' is the points
 * to the FDDI header of the packet, 'tvp' is the timestamp,
 * 'length' is the length of the packet off the wire, and 'caplen'
 * is the number of bytes actually captured.
 */
void
fddi_if_print(u_char *pcap, const struct pcap_pkthdr *h,
	      register const u_char *p)
{
	u_int caplen = h->caplen;
	u_int length = h->len;
	const struct fddi_header *fddip = (struct fddi_header *)p;
	extern u_short extracted_ethertype;
	struct ether_header ehdr;

	ts_print(&h->ts);

	if (caplen < FDDI_HDRLEN) {
		printf("[|fddi]");
		goto out;
	}
	/*
	 * Get the FDDI addresses into a canonical form
	 */
	extract_fddi_addrs(fddip, (char *)ESRC(&ehdr), (char *)EDST(&ehdr));
	/*
	 * Some printers want to get back at the link level addresses,
	 * and/or check that they're not walking off the end of the packet.
	 * Rather than pass them all the way down, we set these globals.
	 */
	snapend = p + caplen;
	/*
	 * Actually, the only printer that uses packetp is print-bootp.c,
	 * and it assumes that packetp points to an Ethernet header.  The
	 * right thing to do is to fix print-bootp.c to know which link
	 * type is in use when it excavates. XXX
	 */
	packetp = (u_char *)&ehdr;

	if (eflag)
		fddi_print(fddip, length, ESRC(&ehdr), EDST(&ehdr));

	/* Skip over FDDI MAC header */
	length -= FDDI_HDRLEN;
	p += FDDI_HDRLEN;
	caplen -= FDDI_HDRLEN;

	/* Frame Control field determines interpretation of packet */
	extracted_ethertype = 0;
	if ((fddip->fddi_fc & FDDIFC_CLFF) == FDDIFC_LLC_ASYNC) {
		/* Try to print the LLC-layer header & higher layers */
		if (llc_print(p, length, caplen, ESRC(&ehdr), EDST(&ehdr))
		    == 0) {
			/*
			 * Some kinds of LLC packet we cannot
			 * handle intelligently
			 */
			if (!eflag)
				fddi_print(fddip, length,
				    ESRC(&ehdr), EDST(&ehdr));
			if (extracted_ethertype) {
				printf("(LLC %s) ",
			etherproto_string(htons(extracted_ethertype)));
			}
			if (!xflag && !qflag)
				default_print(p, caplen);
		}
	} else if ((fddip->fddi_fc & FDDIFC_CLFF) == FDDIFC_SMT)
		fddi_smt_print(p, caplen);
	else {
		/* Some kinds of FDDI packet we cannot handle intelligently */
		if (!eflag)
			fddi_print(fddip, length, ESRC(&ehdr), EDST(&ehdr));
		if (!xflag && !qflag)
			default_print(p, caplen);
	}
	if (xflag)
		default_print(p, caplen);
out:
	putchar('\n');
}