Example #1
0
void printframe(struct pcap_pkthdr *hdr, char *pkt)
{
  int i;
  struct ether_header *ether = NULL;

  if ( (!hdr) || (!pkt) )
    return;

  if (hdr->caplen != hdr->len)
    fprintf(stderr, "rpld: caplen/len mismatch\n");

  ether = (struct ether_header *)pkt;
  
  printf("\n\nrpld: %s > ", printether(ether->ether_shost));
  printf("%s\n", printether(ether->ether_dhost));
  
  //pkt = 18; /* skip over ethernet headers */
  for (i=0;i<hdr->caplen;i+=2)
    {
      if (!((i)%8))
	printf("\nrpld:\t");
      printf("%02x%02x ", pkt[i] &0xff, pkt[i+1] & 0xff);
    }
}
Example #2
0
uint_t
interpret_tr(int flags, caddr_t e, int elen, int origlen)
{
	struct tr_header *mh;
	struct tr_ri *rh;
	uchar_t fc;
	struct llc_snap_hdr *snaphdr;
	char *off;
	int maclen, len;
	boolean_t data_copied = B_FALSE;
	extern char *dst_name, *src_name;
	int ethertype;
	int is_llc = 0, is_snap = 0, source_routing = 0;
	int blen = MAX(origlen, 17800);

	if (data != NULL && datalen != 0 && datalen < blen) {
		free(data);
		data = NULL;
		datalen = 0;
	}
	if (!data) {
		data = (char *)malloc(blen);
		if (!data)
			pr_err("Warning: malloc failure");
		datalen = blen;
	}

	if (origlen < ACFCDASA_LEN) {
		if (flags & F_SUM) {
			(void) sprintf(get_sum_line(),
			    "RUNT (short packet - %d bytes)",
			    origlen);
		}
		if (flags & F_DTAIL)
			show_header("RUNT:  ", "Short packet", origlen);
		return (elen);
	}
	if (elen < ACFCDASA_LEN)
		return (elen);

	mh = (struct tr_header *)e;
	rh = (struct tr_ri *)&mh->ri;
	fc = mh->fc;

	if (is_llc = tr_machdr_len(e, &maclen, &source_routing)) {
		snaphdr = (struct llc_snap_hdr *)(e + maclen);
		if (snaphdr->d_lsap == LSAP_SNAP &&
		    snaphdr->s_lsap == LSAP_SNAP &&
		    snaphdr->control == CNTL_LLC_UI) {
			is_snap = 1;
		}
	}

	if (memcmp(&mh->dhost, &ether_broadcast,
	    sizeof (struct ether_addr)) == 0)
		dst_name = "(broadcast)";
	else if (memcmp(&mh->dhost, &tokenbroadcastaddr2,
	    sizeof (struct ether_addr)) == 0)
		dst_name = "(mac broadcast)";
	else if (mh->dhost.ether_addr_octet[0] & TR_FN_ADDR)
		dst_name = "(functional)";

	if (is_snap)
		ethertype = ntohs(snaphdr->type);
	else {
		src_name =  print_etherinfo(&mh->shost);
		dst_name =  print_etherinfo(&mh->dhost);
	}

	/*
	 * The 14 byte ether header screws up alignment
	 * of the rest of the packet for 32 bit aligned
	 * architectures like SPARC. Alas, we have to copy
	 * the rest of the packet in order to align it.
	 */
	if (is_llc) {
		if (is_snap) {
			len = elen - (maclen + LLC_SNAP_HDR_LEN);
			off = (char *)(e + maclen + LLC_SNAP_HDR_LEN);
		} else {
			len = elen - (maclen + LLC_HDR1_LEN);
			off = (char *)(e + maclen + LLC_HDR1_LEN);
		}
	} else {
		len = elen - maclen;
		off = (char *)(e + maclen);
	}

	if (len > 0 && (off + len <= (char *)e + elen)) {
		(void) memcpy(data, off, len);
		data_copied = B_TRUE;
	}

	if (flags & F_SUM) {
		if (source_routing)
			sprintf(get_sum_line(), print_sr(rh));

		if (is_llc) {
			if (is_snap) {
				(void) sprintf(get_sum_line(), "TR LLC w/SNAP "
				    "Type=%04X (%s), size=%d bytes",
				    ethertype,
				    print_ethertype(ethertype),
				    origlen);
			} else {
				(void) sprintf(get_sum_line(), "TR LLC, but no "
				    "SNAP encoding, size = %d bytes",
				    origlen);
			}
		} else {
			(void) sprintf(get_sum_line(),
			    "TR MAC FC=%02X (%s), size = %d bytes",
			    fc, print_fc(fc), origlen);
		}
	}

	if (flags & F_DTAIL) {
		show_header("TR:  ", "TR Header", elen);
		show_space();
		(void) sprintf(get_line(0, 0),
		    "Packet %d arrived at %d:%02d:%d.%05d",
		    pi_frame,
		    pi_time_hour, pi_time_min, pi_time_sec,
		    pi_time_usec / 10);
		(void) sprintf(get_line(0, 0),
		    "Packet size = %d bytes",
		    elen);
		(void) sprintf(get_line(0, 1),
		    "Frame Control = %02x (%s)",
		    fc, print_fc(fc));
		(void) sprintf(get_line(2, 6),
		    "Destination = %s, %s",
		    printether(&mh->dhost),
		    print_etherinfo(&mh->dhost));
		(void) sprintf(get_line(8, 6),
		    "Source      = %s, %s",
		    printether(&mh->shost),
		    print_etherinfo(&mh->shost));

		if (source_routing)
			sprintf(get_line(ACFCDASA_LEN, rh->len), print_sr(rh));

		if (is_llc) {
			(void) sprintf(get_line(maclen, 1),
			    "Dest   Service Access Point = %02x",
			    snaphdr->d_lsap);
			(void) sprintf(get_line(maclen+1, 1),
			    "Source Service Access Point = %02x",
			    snaphdr->s_lsap);
			(void) sprintf(get_line(maclen+2, 1),
			    "Control = %02x",
			    snaphdr->control);
			if (is_snap) {
				(void) sprintf(get_line(maclen+3, 3),
				    "SNAP Protocol Id = %02x%02x%02x",
				    snaphdr->org[0], snaphdr->org[1],
				    snaphdr->org[2]);
			}
		}

		if (is_snap) {
			(void) sprintf(get_line(maclen+6, 2),
			    "SNAP Type = %04X (%s)",
			    ethertype, print_ethertype(ethertype));
		}

		show_space();
	}

	/* go to the next protocol layer */
	if (is_snap && data_copied) {
		switch (ethertype) {
		case ETHERTYPE_IP:
			(void) interpret_ip(flags, (struct ip *)data, len);
			break;
		/* Just in case it is decided to add this type */
		case ETHERTYPE_IPV6:
			(void) interpret_ipv6(flags, (ip6_t *)data, len);
			break;
		case ETHERTYPE_ARP:
		case ETHERTYPE_REVARP:
			interpret_arp(flags, (struct arphdr *)data, len);
			break;
		case ETHERTYPE_AARP:	/* AppleTalk */
			interpret_aarp(flags, data, len);
			break;
		case ETHERTYPE_AT:
			interpret_at(flags, (struct ddp_hdr *)data, len);
			break;
		default:
			break;
		}
	}

	return (elen);
}
Example #3
0
uint_t
interpret_ether(int flags, char *header, int elen, int origlen)
{
	struct ether_header *e = (struct ether_header *)header;
	uchar_t *off, *ieeestart;
	int len;
	int ieee8023 = 0;
	extern char *dst_name;
	int ethertype;
	struct ether_vlan_extinfo *evx = NULL;
	int blen = MAX(origlen, ETHERMTU);
	boolean_t trillpkt = B_FALSE;
	uint16_t tci = 0;

	if (data != NULL && datalen != 0 && datalen < blen) {
		free(data);
		data = NULL;
		datalen = 0;
	}
	if (!data) {
		data = (char *)malloc(blen);
		if (!data)
			pr_err("Warning: malloc failure");
		datalen = blen;
	}
inner_pkt:
	if (origlen < 14) {
		if (flags & F_SUM) {
			(void) sprintf(get_sum_line(),
			    "RUNT (short packet - %d bytes)",
			    origlen);
		}
		if (flags & F_DTAIL)
			show_header("RUNT:  ", "Short packet", origlen);
		return (elen);
	}
	if (elen < 14)
		return (elen);

	if (memcmp(&e->ether_dhost, &ether_broadcast,
	    sizeof (struct ether_addr)) == 0)
		dst_name = "(broadcast)";
	else if (e->ether_dhost.ether_addr_octet[0] & 1)
		dst_name = "(multicast)";

	ethertype = ntohs(e->ether_type);

	/*
	 * The 14 byte ether header screws up alignment
	 * of the rest of the packet for 32 bit aligned
	 * architectures like SPARC. Alas, we have to copy
	 * the rest of the packet in order to align it.
	 */
	len = elen - sizeof (struct ether_header);
	off = (uchar_t *)(e + 1);

	if (ethertype == ETHERTYPE_VLAN) {
		if (origlen < sizeof (struct ether_vlan_header)) {
			if (flags & F_SUM) {
				(void) sprintf(get_sum_line(),
				    "RUNT (short VLAN packet - %d bytes)",
				    origlen);
			}
			if (flags & F_DTAIL) {
				show_header("RUNT:  ", "Short VLAN packet",
				    origlen);
			}
			return (elen);
		}
		if (len < sizeof (struct ether_vlan_extinfo))
			return (elen);

		evx = (struct ether_vlan_extinfo *)off;
		off += sizeof (struct ether_vlan_extinfo);
		len -= sizeof (struct ether_vlan_extinfo);

		ethertype = ntohs(evx->ether_type);
		tci = ntohs(evx->ether_tci);
	}

	if (ethertype <= 1514) {
		/*
		 * Fake out the IEEE 802.3 packets.
		 * Should be DSAP=0xAA, SSAP=0xAA, control=0x03
		 * then three padding bytes of zero (OUI),
		 * followed by a normal ethernet-type packet.
		 */
		ieee8023 = ethertype;
		ieeestart = off;
		if (off[0] == 0xAA && off[1] == 0xAA) {
			ethertype = ntohs(*(ushort_t *)(off + 6));
			off += 8;
			len -= 8;
		} else {
			ethertype = 0;
			off += 3;
			len -= 3;
		}
	}

	if (flags & F_SUM) {
		/*
		 * Set the flag that says don't display VLAN information.
		 * If it needs to change, that will be done later if the
		 * packet is VLAN tagged and if snoop is in its default
		 * summary mode.
		 */
		set_vlan_id(0);
		if (evx == NULL) {
			if (ethertype == 0 && ieee8023 > 0) {
				(void) sprintf(get_sum_line(),
				    "ETHER 802.3 SSAP %02X DSAP %02X, "
				    "size=%d bytes", ieeestart[0], ieeestart[1],
				    origlen);
			} else {
				(void) sprintf(get_sum_line(),
				    "ETHER Type=%04X (%s), size=%d bytes",
				    ethertype, print_ethertype(ethertype),
				    origlen);
			}
		} else {
			if (ethertype == 0 && ieee8023 > 0) {
				(void) sprintf(get_sum_line(),
				    "ETHER 802.3 SSAP %02X DSAP %02X, "
				    "VLAN ID=%hu, size=%d bytes", ieeestart[0],
				    ieeestart[1], VLAN_ID(tci), origlen);
			} else {
				(void) sprintf(get_sum_line(),
				    "ETHER Type=%04X (%s), VLAN ID=%hu, "
				    "size=%d bytes", ethertype,
				    print_ethertype(ethertype), VLAN_ID(tci),
				    origlen);
			}

			if (!(flags & F_ALLSUM))
				set_vlan_id(VLAN_ID(tci));
		}
	}

	if (flags & F_DTAIL) {
		show_header("ETHER:  ", "Ether Header", elen);
		show_space();
		if (!trillpkt) {
			(void) sprintf(get_line(0, 0),
			    "Packet %d arrived at %d:%02d:%d.%05d",
			    pi_frame,
			    pi_time_hour, pi_time_min, pi_time_sec,
			    pi_time_usec / 10);
			(void) sprintf(get_line(0, 0),
			    "Packet size = %d bytes",
			    elen, elen);
		}
		(void) sprintf(get_line(0, 6),
		    "Destination = %s, %s",
		    printether(&e->ether_dhost),
		    print_etherinfo(&e->ether_dhost));
		(void) sprintf(get_line(6, 6),
		    "Source      = %s, %s",
		    printether(&e->ether_shost),
		    print_etherinfo(&e->ether_shost));
		if (evx != NULL) {
			(void) sprintf(get_line(0, 0),
			    "VLAN ID     = %hu", VLAN_ID(tci));
			(void) sprintf(get_line(0, 0),
			    "VLAN Priority = %hu", VLAN_PRI(tci));
		}
		if (ieee8023 > 0) {
			(void) sprintf(get_line(12, 2),
			    "IEEE 802.3 length = %d bytes", ieee8023);
			/* Print LLC only for non-TCP/IP packets */
			if (ethertype == 0) {
				(void) snprintf(get_line(0, 0),
				    get_line_remain(),
				    "SSAP = %02X, DSAP = %02X, CTRL = %02X",
				    ieeestart[0], ieeestart[1], ieeestart[2]);
			}
		}
		if (ethertype != 0 || ieee8023 == 0)
			(void) sprintf(get_line(12, 2),
			    "Ethertype = %04X (%s)",
			    ethertype, print_ethertype(ethertype));
		show_space();
	}

	/*
	 * We cannot trust the length field in the header to be correct.
	 * But we should continue to process the packet.  Then user can
	 * notice something funny in the header.
	 * Go to the next protocol layer only if data have been
	 * copied.
	 */
	if (len > 0 && (off + len <= (uchar_t *)e + elen)) {
		(void) memmove(data, off, len);

		if (!trillpkt && ethertype == ETHERTYPE_TRILL) {
			ethertype = interpret_trill(flags, &e, data, &len);
			/* Decode inner Ethernet frame */
			if (ethertype != 0) {
				evx = NULL;
				trillpkt = B_TRUE;
				(void) memmove(data, e, len);
				e = (struct ether_header *)data;
				origlen = len;
				elen = len;
				goto inner_pkt;
			}
		}

		switch (ethertype) {
		case ETHERTYPE_IP:
			(void) interpret_ip(flags, (struct ip *)data, len);
			break;
		/* Just in case it is decided to add this type */
		case ETHERTYPE_IPV6:
			(void) interpret_ipv6(flags, (ip6_t *)data, len);
			break;
		case ETHERTYPE_ARP:
		case ETHERTYPE_REVARP:
			interpret_arp(flags, (struct arphdr *)data, len);
			break;
		case ETHERTYPE_PPPOED:
		case ETHERTYPE_PPPOES:
			(void) interpret_pppoe(flags, (poep_t *)data, len);
			break;
		case ETHERTYPE_AARP:    /* AppleTalk */
			interpret_aarp(flags, data, len);
			break;
		case ETHERTYPE_AT:
			interpret_at(flags, (struct ddp_hdr *)data, len);
			break;
		case 0:
			if (ieee8023 == 0)
				break;
			switch (ieeestart[0]) {
			case 0xFE:
				interpret_isis(flags, data, len,
				    memcmp(&e->ether_dhost, &all_isis_rbridges,
				    sizeof (struct ether_addr)) == 0);
				break;
			case 0x42:
				interpret_bpdu(flags, data, len);
				break;
			}
			break;
		}
	}

	return (elen);
}
Example #4
0
uint_t
interpret_fddi(int flags, caddr_t e, int elen, int origlen)
{
	struct fddi_header fhdr, *f = &fhdr;
	char *off;
	int len;
	boolean_t data_copied = B_FALSE;
	extern char *dst_name, *src_name;
	int ethertype;
	int is_llc = 0, is_smt = 0, is_snap = 0;
	int blen = MAX(origlen, 4500);

	if (data != NULL && datalen != 0 && datalen < blen) {
		free(data);
		data = NULL;
		datalen = 0;
	}
	if (!data) {
		data = (char *)malloc(blen);
		if (!data)
			pr_err("Warning: malloc failure");
		datalen = blen;
	}

	if (origlen < 13) {
		if (flags & F_SUM) {
			(void) sprintf(get_sum_line(),
			    "RUNT (short packet - %d bytes)",
			    origlen);
		}
		if (flags & F_DTAIL)
			show_header("RUNT:  ", "Short packet", origlen);
		return (elen);
	}
	if (elen < 13)
		return (elen);

	(void) memcpy(&f->fc, e, sizeof (f->fc));
	addr_copy_swap(&f->dhost, (struct ether_addr *)(e+1));
	addr_copy_swap(&f->shost, (struct ether_addr *)(e+7));

	if ((f->fc&0x50) == 0x50) {
		is_llc = 1;
		(void) memcpy(&f->dsap, e+13, sizeof (f->dsap));
		(void) memcpy(&f->ssap, e+14, sizeof (f->ssap));
		(void) memcpy(&f->ctl, e+15, sizeof (f->ctl));
		if (f->dsap == 0xaa && f->ssap == 0xaa) {
			is_snap = 1;
			(void) memcpy(&f->proto_id, e+16, sizeof (f->proto_id));
			(void) memcpy(&f->type, e+19, sizeof (f->type));
		}
	} else {
		if ((f->fc&0x41) == 0x41 || (f->fc&0x4f) == 0x4f) {
			is_smt = 1;
		}
	}


	if (memcmp(&f->dhost, &ether_broadcast,
	    sizeof (struct ether_addr)) == 0)
		dst_name = "(broadcast)";
	else if (f->dhost.ether_addr_octet[0] & 0x01)
		dst_name = "(multicast)";

	if (is_snap)
		ethertype = ntohs(f->type);
	else {
		src_name = 	print_etherinfo(&f->shost);
		dst_name =  print_etherinfo(&f->dhost);
	}

	/*
	 * The 14 byte ether header screws up alignment
	 * of the rest of the packet for 32 bit aligned
	 * architectures like SPARC. Alas, we have to copy
	 * the rest of the packet in order to align it.
	 */
	if (is_llc) {
		if (is_snap) {
			len = elen - 21;
			off = (char *)(e + 21);
		} else {
			len = elen - 16;
			off = (char *)(e + 16);
		}
	} else {
		len = elen - 13;
		off = (char *)(e + 13);
	}

	if (len > 0 && (off + len <= (char *)e + elen)) {
		(void) memcpy(data, off, len);
		data_copied = B_TRUE;
	}

	if (flags & F_SUM) {
		if (is_llc) {
			if (is_snap) {
				(void) sprintf(get_sum_line(),
				    "FDDI LLC Type=%04X (%s), size = %d bytes",
				    ethertype,
				    print_ethertype(ethertype),
				    origlen);
			} else {
				(void) sprintf(get_sum_line(), "LLC, but no "
				    "SNAP encoding, size = %d bytes",
				    origlen);
			}
		} else if (is_smt) {
			(void) sprintf(get_sum_line(), "SMT Type=%02X (%s), "
			    "Class = %02X (%s), size = %d bytes",
			    *(uchar_t *)(data+1), print_smttype(*(data+1)),
			    *data, print_smtclass(*data), origlen);
		} else {
			(void) sprintf(get_sum_line(),
			    "FC=%02X (%s), size = %d bytes",
			    f->fc, print_fc(f->fc), origlen);
		}
	}

	if (flags & F_DTAIL) {
		show_header("FDDI:  ", "FDDI Header", elen);
		show_space();
		(void) sprintf(get_line(0, 0),
		    "Packet %d arrived at %d:%02d:%d.%05d",
		    pi_frame,
		    pi_time_hour, pi_time_min, pi_time_sec,
		    pi_time_usec / 10);
		(void) sprintf(get_line(0, 0),
		    "Packet size = %d bytes",
		    elen, elen);
		(void) sprintf(get_line(0, 6),
		    "Destination = %s, %s",
		    printether(&f->dhost),
		    print_etherinfo(&f->dhost));
		(void) sprintf(get_line(6, 6),
		    "Source      = %s, %s",
		    printether(&f->shost),
		    print_etherinfo(&f->shost));

		if (is_llc) {
			(void) sprintf(get_line(12, 2),
			    "Frame Control = %02x (%s)",
			    f->fc, print_fc(f->fc));
			(void) sprintf(get_line(12, 2),
			    "Dest   Service Access Point = %02x",
			    f->dsap);
			(void) sprintf(get_line(12, 2),
			    "Source Service Access Point = %02x",
			    f->ssap);
			(void) sprintf(get_line(12, 2),
			    "Control = %02x",
			    f->ctl);
			if (is_snap) {
				(void) sprintf(get_line(12, 2),
				    "Protocol Id = %02x%02x%02x",
				    f->proto_id[0], f->proto_id[1],
				    f->proto_id[2]);
			}
		} else if (is_smt) {
			(void) sprintf(get_line(12, 2),
			    "Frame Control = %02x (%s)",
			    f->fc, print_fc(f->fc));
			(void) sprintf(get_line(12, 2),
			    "Class = %02x (%s)",
			    (uchar_t)*data, print_smtclass(*data));
			(void) sprintf(get_line(12, 2),
			    "Type = %02x (%s)",
			    *(uchar_t *)(data+1), print_smttype(*(data+1)));
		} else {
			(void) sprintf(get_line(12, 2),
			    "FC=%02X (%s), size = %d bytes",
			    f->fc, print_fc(f->fc), origlen);
		}

		if (is_snap) {
			(void) sprintf(get_line(12, 2),
			    "LLC Type = %04X (%s)",
			    ethertype, print_ethertype(ethertype));
		}

		show_space();
	}

	/* go to the next protocol layer */
	if (is_llc && is_snap && f->ctl == 0x03 && data_copied) {
		switch (ethertype) {
		case ETHERTYPE_IP:
			(void) interpret_ip(flags, (struct ip *)data, len);
			break;
		/* Just in case it is decided to add this type */
		case ETHERTYPE_IPV6:
			(void) interpret_ipv6(flags, (ip6_t *)data, len);
			break;
		case ETHERTYPE_ARP:
		case ETHERTYPE_REVARP:
			interpret_arp(flags, (struct arphdr *)data, len);
			break;
		default:
			break;
		}

	}

	return (elen);
}