Exemple #1
0
void
raw_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p)
{
	u_int length = h->len;
	u_int caplen = h->caplen;

	ts_print(&h->ts);

	/*
	 * 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.
	 */
	packetp = p;
	snapend = p + caplen;

	if (eflag)
		printf("ip: ");

	ip_print(p, length);

	if (xflag)
		default_print(p, caplen);
	putchar('\n');
}
u_int
cip_if_print(const struct pcap_pkthdr *h, const u_char *p)
{
	u_int caplen = h->caplen;
	u_int length = h->len;
	u_short extracted_ethertype;

	if (memcmp(rfcllc, p, sizeof(rfcllc))==0 && caplen < RFC1483LLC_LEN) {
		printf("[|cip]");
		return (0);
	}

	if (eflag)
		cip_print(length);

	if (memcmp(rfcllc, p, sizeof(rfcllc)) == 0) {
		if (llc_print(p, length, caplen, NULL, NULL,
		    &extracted_ethertype) == 0) {
			
			if (!eflag)
				cip_print(length);
			if (extracted_ethertype) {
				printf("(LLC %s) ",
			       etherproto_string(htons(extracted_ethertype)));
			}
			if (!suppress_default_print)
				default_print(p, caplen);
		}
	} else {
		ip_print(gndo, p, length);
	}

	return (0);
}
Exemple #3
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
ap1394_if_print(const struct pcap_pkthdr *h, const u_char *p)
{
	u_int length = h->len;
	u_int caplen = h->caplen;
	struct firewire_header *fp;
	u_short ether_type;

	if (caplen < FIREWIRE_HDRLEN) {
		printf("[|ap1394]");
		return FIREWIRE_HDRLEN;
	}

	if (eflag)
		ap1394_hdr_print(p, length);

	length -= FIREWIRE_HDRLEN;
	caplen -= FIREWIRE_HDRLEN;
	fp = (struct firewire_header *)p;
	p += FIREWIRE_HDRLEN;

	ether_type = EXTRACT_16BITS(&fp->firewire_type);
	if (ethertype_print(ether_type, p, length, caplen) == 0) {
		/* ether_type not known, print raw packet */
		if (!eflag)
			ap1394_hdr_print((u_char *)fp, length + FIREWIRE_HDRLEN);

		if (!suppress_default_print)
			default_print(p, caplen);
	} 

	return FIREWIRE_HDRLEN;
}
void
sl_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p)
{
        register u_int caplen = h->caplen;
        register u_int length = h->len;
        register const struct ip *ip;

        ts_print(&h->ts);

        if (caplen < SLIP_HDRLEN) {
                printf("[|slip]");
                goto out;
        }
        /*
         * 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.
         */
        packetp = p;
        snapend = p + caplen;

        length -= SLIP_HDRLEN;

        ip = (struct ip *)(p + SLIP_HDRLEN);

        if (eflag)
                sliplink_print(p, ip, length);

        ip_print((u_char *)ip, length);

        if (xflag)
                default_print((u_char *)ip, caplen - SLIP_HDRLEN);
 out:
        putchar('\n');
}
/*
 * 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
symantec_if_print(const struct pcap_pkthdr *h, const u_char *p)
{
	u_int length = h->len;
	u_int caplen = h->caplen;
	struct symantec_header *sp;
	u_short ether_type;

	if (caplen < sizeof (struct symantec_header)) {
		printf("[|symantec]");
		return caplen;
	}

	if (eflag)
		symantec_hdr_print(p, length);

	length -= sizeof (struct symantec_header);
	caplen -= sizeof (struct symantec_header);
	sp = (struct symantec_header *)p;
	p += sizeof (struct symantec_header);

	ether_type = EXTRACT_16BITS(&sp->ether_type);

	if (ether_type <= ETHERMTU) {
		/* ether_type not known, print raw packet */
		if (!eflag)
			symantec_hdr_print((u_char *)sp, length + sizeof (struct symantec_header));

		if (!suppress_default_print)
			default_print(p, caplen);
	} else if (ethertype_print(gndo, ether_type, p, length, caplen) == 0) {
		/* ether_type not known, print raw packet */
		if (!eflag)
			symantec_hdr_print((u_char *)sp, length + sizeof (struct symantec_header));

		if (!suppress_default_print)
			default_print(p, caplen);
	} 

	return (sizeof (struct symantec_header));
}
Exemple #6
0
/*
 * This is the top level routine of the printer.  'p' points
 * to the ARCNET 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.  It is quite similar
 * to the non-Linux style printer except that Linux doesn't ever
 * supply packets that look like exception frames, it always supplies
 * reassembled packets rather than raw frames, and headers have an
 * extra "offset" field between the src/dest and packet type.
 */
u_int
arcnet_linux_if_print(const struct pcap_pkthdr *h, const u_char *p)
{
	u_int caplen = h->caplen;
	u_int length = h->len;
	const struct arc_linux_header *ap;

	int archdrlen = 0;
	u_char arc_type;

	if (caplen < ARC_LINUX_HDRLEN) {
		printf("[|arcnet]");
		return (caplen);
	}

	ap = (const struct arc_linux_header *)p;
	arc_type = ap->arc_type;

	switch (arc_type) {
	default:
		archdrlen = ARC_LINUX_HDRNEWLEN;
		if (caplen < ARC_LINUX_HDRNEWLEN) {
			printf("[|arcnet]");
			return (caplen);
		}
		break;
	case ARCTYPE_IP_OLD:
	case ARCTYPE_ARP_OLD:
	case ARCTYPE_DIAGNOSE:
		archdrlen = ARC_LINUX_HDRLEN;
		break;
	}

	if (eflag)
		arcnet_print(p, length, 0, 0, 0);

	/*
	 * Go past the ARCNET header.
	 */
	length -= archdrlen;
	caplen -= archdrlen;
	p += archdrlen;

	if (!arcnet_encap_print(arc_type, p, length, caplen))
		default_print(p, caplen);

	return (archdrlen);
}
Exemple #7
0
/*
 * Print an RFC 1483 LLC-encapsulated ATM frame.
 */
static void
atm_llc_print(const u_char *p, int length, int caplen)
{
	u_short extracted_ethertype;

	if (!llc_print(p, length, caplen, NULL, NULL,
	    &extracted_ethertype)) {
		/* ether_type not known, print raw packet */
		if (extracted_ethertype) {
			printf("(LLC %s) ",
		etherproto_string(htons(extracted_ethertype)));
		}
		if (!suppress_default_print)
			default_print(p, caplen);
	}
}
/*
 * This is the top level routine of the printer.  'p' points
 * to the LLC/SNAP or raw 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
cip_if_print(const struct pcap_pkthdr *h, const u_char *p)
{
	u_int caplen = h->caplen;
	u_int length = h->len;
	u_short extracted_ethertype;

	if (memcmp(rfcllc, p, sizeof(rfcllc))==0 && caplen < RFC1483LLC_LEN) {
		printf("[|cip]");
		return (0);
	}

	if (eflag)
		cip_print(length);

	if (memcmp(rfcllc, p, sizeof(rfcllc)) == 0) {
		/*
		 * LLC header is present.  Try to print it & higher layers.
		 */
		if (llc_print(p, length, caplen, NULL, NULL,
		    &extracted_ethertype) == 0) {
			/* ether_type not known, print raw packet */
			if (!eflag)
				cip_print(length);
			if (extracted_ethertype) {
				printf("(LLC %s) ",
			       etherproto_string(htons(extracted_ethertype)));
			}
			if (!suppress_default_print)
				default_print(p, caplen);
		}
	} else {
		/*
		 * LLC header is absent; treat it as just IP.
		 */
		ip_print(gndo, p, length);
	}

	return (0);
}
Exemple #9
0
void
pfsync_if_print(u_char *user, const struct pcap_pkthdr *h,
    packetbody_t p)
{
	u_int caplen = h->caplen;

	ts_print(&h->ts);

	if (caplen < PFSYNC_HDRLEN) {
		printf("[|pfsync]");
		goto out;
	}

	pfsync_print((struct pfsync_header *)p,
	    p + sizeof(struct pfsync_header),
	    caplen - sizeof(struct pfsync_header));
out:
	if (xflag) {
		default_print((const u_char *)p, caplen);
	}
	putchar('\n');
}
u_int
pfsync_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p)
{
	u_int caplen = h->caplen;

	ts_print(ndo, &h->ts);

	if (caplen < PFSYNC_HDRLEN) {
		ND_PRINT((ndo, "[|pfsync]"));
		goto out;
	}

	pfsync_print((struct pfsync_header *)p,
	    caplen - sizeof(struct pfsync_header));
out:
	if (xflag) {
		default_print((const u_char *)h, caplen);
	}
	//putchar('\n');

	return 0;
}
Exemple #11
0
void
pfsync_if_print(u_char *user, const struct pcap_pkthdr *h,
    register const u_char *p)
{
	u_int caplen = h->caplen;

	ts_print(&h->ts);

	if (caplen < PFSYNC_HDRLEN) {
		ND_PRINT((ndo, "[|pfsync]"));
		goto out;
	}

	pfsync_print((struct pfsync_header *)p,
	    p + sizeof(struct pfsync_header),
	    caplen - sizeof(struct pfsync_header));
out:
	if (xflag) {
		default_print((const u_char *)p, caplen);
	}
	safeputchar(ndo, '\n');
}
Exemple #12
0
/*
 * This is the top level routine of the printer.  'p' points
 * to the bluetooth 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
bt_if_print(const struct pcap_pkthdr *h, const u_char *p)
{
	u_int length = h->len;
	u_int caplen = h->caplen;
	const pcap_bluetooth_h4_header* hdr = (const pcap_bluetooth_h4_header*)p;

	if (caplen < BT_HDRLEN) {
		printf("[|bt]");
		return (BT_HDRLEN);
	}
	caplen -= BT_HDRLEN;
	length -= BT_HDRLEN;
	p += BT_HDRLEN;
	if (eflag)
		(void)printf("hci length %d, direction %s, ", length, (ntohl(hdr->direction)&0x1)?"in":"out");

	if (!suppress_default_print)
		default_print(p, caplen);

	return (BT_HDRLEN);
}
Exemple #13
0
/* Standard PPP printer */
void
ppp_if_print(u_char *user, const struct pcap_pkthdr *h,
	     register const u_char *p)
{
	register u_int length = h->len;
	register u_int caplen = h->caplen;
	const struct ip *ip;

	ts_print(&h->ts);

	if (caplen < PPP_HDRLEN) {
		printf("[|ppp]");
		goto out;
	}

	/*
	 * 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.
	 */
	packetp = p;
	snapend = p + caplen;

	if (eflag)
		printf("%c %4d %02x %04x: ", p[0] ? 'O' : 'I', length,
		       p[1], ntohs(*(u_short *)&p[2]));

	length -= PPP_HDRLEN;
	ip = (struct ip *)(p + PPP_HDRLEN);
	ip_print((const u_char *)ip, length);

	if (xflag)
		default_print((const u_char *)ip, caplen - PPP_HDRLEN);
out:
	putchar('\n');
}
u_int
pflog_if_print(const struct pcap_pkthdr *h, register const u_char *p)
{
	u_int length = h->len;
	u_int hdrlen;
	u_int caplen = h->caplen;
	const struct pfloghdr *hdr;
	u_int8_t af;

	/* check length */
	if (caplen < sizeof(u_int8_t)) {
		printf("[|pflog]");
		return (caplen);
	}

#define MIN_PFLOG_HDRLEN	45
	hdr = (struct pfloghdr *)p;
	if (hdr->length < MIN_PFLOG_HDRLEN) {
		printf("[pflog: invalid header length!]");
		return (hdr->length);	/* XXX: not really */
	}
	hdrlen = BPF_WORDALIGN(hdr->length);

	if (caplen < hdrlen) {
		printf("[|pflog]");
		return (hdrlen);	/* XXX: true? */
	}

	/* print what we know */
	hdr = (struct pfloghdr *)p;
	TCHECK(*hdr);
	if (eflag)
		pflog_print(hdr);
	
	/* skip to the real packet */
	af = hdr->af;
	length -= hdrlen;
	caplen -= hdrlen;
	p += hdrlen;
	switch (af) {

		case AF_INET:
#if OPENBSD_AF_INET != AF_INET
		case OPENBSD_AF_INET:		/* XXX: read pcap files */
#endif
		        ip_print(gndo, p, length);
			break;

#ifdef INET6
		case AF_INET6:
#if OPENBSD_AF_INET6 != AF_INET6
		case OPENBSD_AF_INET6:		/* XXX: read pcap files */
#endif
			ip6_print(gndo, p, length);
			break;
#endif

	default:
		/* address family not handled, print raw packet */
		if (!eflag)
			pflog_print(hdr);
		if (!suppress_default_print)
			default_print(p, caplen);
	}
	
	return (hdrlen);
trunc:
	printf("[|pflog]");
	return (hdrlen);
}
Exemple #15
0
void
pflog_if_print(u_char *user, const struct pcap_pkthdr *h,
     const u_char *p)
{
	u_int length = h->len;
	u_int hdrlen;
	u_int caplen = h->caplen;
	const struct ip *ip;
#ifdef INET6
	const struct ip6_hdr *ip6;
#endif
	const struct pfloghdr *hdr;
	u_int8_t af;

	ts_print(&h->ts);

	/* check length */
	if (caplen < sizeof(u_int8_t)) {
		printf("[|pflog]");
		goto out;
	}

#define MIN_PFLOG_HDRLEN	45
	hdr = (struct pfloghdr *)p;
	if (hdr->length < MIN_PFLOG_HDRLEN) {
		printf("[pflog: invalid header length!]");
		goto out;
	}
	hdrlen = (hdr->length + 3) & 0xfc;

	if (caplen < hdrlen) {
		printf("[|pflog]");
		goto out;
	}

	/*
	 * 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.
	 */
	packetp = p;
	snapend = p + caplen;

	hdr = (struct pfloghdr *)p;
	if (eflag) {
		printf("rule ");
		if (ntohl(hdr->rulenr) == (u_int32_t) -1)
			printf("def");
		else {
			printf("%u", ntohl(hdr->rulenr));
			if (hdr->ruleset[0]) {
				printf(".%s", hdr->ruleset);
				if (ntohl(hdr->subrulenr) == (u_int32_t) -1)
					printf(".def");
				else
					printf(".%u", ntohl(hdr->subrulenr));
			}
		}
		if (hdr->reason < PFRES_MAX)
			printf("/(%s) ", pf_reasons[hdr->reason]);
		else
			printf("/(unkn %u) ", (unsigned)hdr->reason);
		if (vflag)
			printf("[uid %u, pid %u] ", (unsigned)hdr->rule_uid,
			    (unsigned)hdr->rule_pid);

		switch (hdr->action) {
		case PF_MATCH:
			printf("match");
			break;
		case PF_SCRUB:
			printf("scrub");
			break;
		case PF_PASS:
			printf("pass");
			break;
		case PF_DROP:
			printf("block");
			break;
		case PF_NAT:
		case PF_NONAT:
			printf("nat");
			break;
		case PF_BINAT:
		case PF_NOBINAT:
			printf("binat");
			break;
		case PF_RDR:
		case PF_NORDR:
			printf("rdr");
			break;
		}
		printf(" %s on %s: ",
		    hdr->dir == PF_OUT ? "out" : "in",
		    hdr->ifname);
		if (vflag && hdr->pid != NO_PID)
			printf("[uid %u, pid %u] ", (unsigned)hdr->uid,
			    (unsigned)hdr->pid);
		if (vflag && hdr->rewritten) {
			char buf[48];

			if (inet_ntop(hdr->af, &hdr->saddr.v4, buf,
			    sizeof(buf)) == NULL)
				printf("[orig src ?, ");
			else
				printf("[orig src %s:%u, ", buf,
				    ntohs(hdr->sport));
			if (inet_ntop(hdr->af, &hdr->daddr.v4, buf,
			    sizeof(buf)) == NULL)
				printf("dst ?] ");
			else
				printf("dst %s:%u] ", buf,
				    ntohs(hdr->dport));
		}
	}
	af = hdr->naf;
	length -= hdrlen;
	if (af == AF_INET) {
		ip = (struct ip *)(p + hdrlen);
		ip_print((const u_char *)ip, length);
		if (xflag)
			default_print((const u_char *)ip,
			    caplen - hdrlen);
	} else {
#ifdef INET6
		ip6 = (struct ip6_hdr *)(p + hdrlen);
		ip6_print((const u_char *)ip6, length);
		if (xflag)
			default_print((const u_char *)ip6,
			    caplen - hdrlen);
#endif
	}

out:
	putchar('\n');
}
Exemple #16
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;
	enum mpls_packet_type pt = PT_UNKNOWN;

	p = bp;
	printf("MPLS");
	do {
		TCHECK2(*p, sizeof(label_entry));
		label_entry = EXTRACT_32BITS(p);
		printf("%s(label %u",
		       (label_stack_depth && vflag) ? "\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));

	/*
	 * 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 (!suppress_default_print)
			default_print(p, length - (p - bp));
		return;
	}
	if (vflag)
		printf("\n\t");
	else
		printf(" ");
	switch (pt) {

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

	case PT_IPV6:
#ifdef INET6
		ip6_print(gndo, p, length - (p - bp));
#else
		printf("IPv6, length: %u", length);
#endif
		break;

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

	default:
		break;
	}
	return;

trunc:
	printf("[|MPLS]");
}
void sctp_print(const u_char *bp,        
		const u_char *bp2,       
		u_int sctpPacketLength)  
{
  const struct sctpHeader *sctpPktHdr;
  const struct ip *ip;
#ifdef INET6
  const struct ip6_hdr *ip6;
#endif
  const void *endPacketPtr;
  u_short sourcePort, destPort;
  int chunkCount;
  const struct sctpChunkDesc *chunkDescPtr;
  const void *nextChunk;
  const char *sep;

  sctpPktHdr = (const struct sctpHeader*) bp;
  endPacketPtr = (const u_char*)sctpPktHdr+sctpPacketLength;

  if( (u_long) endPacketPtr > (u_long) snapend)
    endPacketPtr = (const void *) snapend;
  ip = (struct ip *)bp2;
#ifdef INET6
  if (IP_V(ip) == 6)
    ip6 = (const struct ip6_hdr *)bp2;
  else
    ip6 = NULL;
#endif 
  TCHECK(*sctpPktHdr);

  if (sctpPacketLength < sizeof(struct sctpHeader))
    {
      (void)printf("truncated-sctp - %ld bytes missing!",
		   (long)sctpPacketLength-sizeof(struct sctpHeader));
      return;
    }

  
  

  sourcePort = EXTRACT_16BITS(&sctpPktHdr->source);
  destPort = EXTRACT_16BITS(&sctpPktHdr->destination);

#ifdef INET6
  if (ip6) {
    (void)printf("%s.%d > %s.%d: sctp",
      ip6addr_string(&ip6->ip6_src),
      sourcePort,
      ip6addr_string(&ip6->ip6_dst),
      destPort);
  } else
#endif 
  {
    (void)printf("%s.%d > %s.%d: sctp",
      ipaddr_string(&ip->ip_src),
      sourcePort,
      ipaddr_string(&ip->ip_dst),
      destPort);
  }
  fflush(stdout);

  if (vflag >= 2)
    sep = "\n\t";
  else
    sep = " (";
  
  for (chunkCount = 0,
	 chunkDescPtr = (const struct sctpChunkDesc *)
	    ((const u_char*) sctpPktHdr + sizeof(struct sctpHeader));
       chunkDescPtr != NULL &&
	 ( (const void *)
	    ((const u_char *) chunkDescPtr + sizeof(struct sctpChunkDesc))
	   <= endPacketPtr);

       chunkDescPtr = (const struct sctpChunkDesc *) nextChunk, chunkCount++)
    {
      u_int16_t chunkLength;
      const u_char *chunkEnd;
      u_int16_t align;

      TCHECK(*chunkDescPtr);
      chunkLength = EXTRACT_16BITS(&chunkDescPtr->chunkLength);
      if (chunkLength < sizeof(*chunkDescPtr)) {
      	printf("%s%d) [Bad chunk length %u]", sep, chunkCount+1, chunkLength);
      	break;
      }

      TCHECK2(*((u_int8_t *)chunkDescPtr), chunkLength);
      chunkEnd = ((const u_char*)chunkDescPtr + chunkLength);

      align=chunkLength % 4;
      if (align != 0)
	align = 4 - align;

      nextChunk = (const void *) (chunkEnd + align);

      printf("%s%d) ", sep, chunkCount+1);
      switch (chunkDescPtr->chunkID)
	{
	case SCTP_DATA :
	  {
	    const struct sctpDataPart *dataHdrPtr;

	    printf("[DATA] ");

	    if ((chunkDescPtr->chunkFlg & SCTP_DATA_UNORDERED)
		== SCTP_DATA_UNORDERED)
	      printf("(U)");

	    if ((chunkDescPtr->chunkFlg & SCTP_DATA_FIRST_FRAG)
		== SCTP_DATA_FIRST_FRAG)
	      printf("(B)");

	    if ((chunkDescPtr->chunkFlg & SCTP_DATA_LAST_FRAG)
		== SCTP_DATA_LAST_FRAG)
	      printf("(E)");

	    if( ((chunkDescPtr->chunkFlg & SCTP_DATA_UNORDERED)
		 == SCTP_DATA_UNORDERED)
		||
		((chunkDescPtr->chunkFlg & SCTP_DATA_FIRST_FRAG)
		 == SCTP_DATA_FIRST_FRAG)
		||
		((chunkDescPtr->chunkFlg & SCTP_DATA_LAST_FRAG)
		 == SCTP_DATA_LAST_FRAG) )
	      printf(" ");

	    dataHdrPtr=(const struct sctpDataPart*)(chunkDescPtr+1);

	    printf("[TSN: %u] ", EXTRACT_32BITS(&dataHdrPtr->TSN));
	    printf("[SID: %u] ", EXTRACT_16BITS(&dataHdrPtr->streamId));
	    printf("[SSEQ %u] ", EXTRACT_16BITS(&dataHdrPtr->sequence));
	    printf("[PPID 0x%x] ", EXTRACT_32BITS(&dataHdrPtr->payloadtype));
	    fflush(stdout);

	    if (vflag >= 2)	   
	      {		           
		const u_char *payloadPtr;

		printf("[Payload");

		if (!suppress_default_print) {
			payloadPtr = (const u_char *) (++dataHdrPtr);
			printf(":");
			if (htons(chunkDescPtr->chunkLength) <
			    sizeof(struct sctpDataPart)+
			    sizeof(struct sctpChunkDesc)+1) {
				
				printf("bogus chunk length %u]",
				    htons(chunkDescPtr->chunkLength));
				return;
			}
			default_print(payloadPtr,
			      htons(chunkDescPtr->chunkLength) -
			      (sizeof(struct sctpDataPart)+
			      sizeof(struct sctpChunkDesc)));
		} else
			printf("]");
	      }
	    break;
	  }
	case SCTP_INITIATION :
	  {
	    const struct sctpInitiation *init;

	    printf("[INIT] ");
	    init=(const struct sctpInitiation*)(chunkDescPtr+1);
	    printf("[init tag: %u] ", EXTRACT_32BITS(&init->initTag));
	    printf("[rwnd: %u] ", EXTRACT_32BITS(&init->rcvWindowCredit));
	    printf("[OS: %u] ", EXTRACT_16BITS(&init->NumPreopenStreams));
	    printf("[MIS: %u] ", EXTRACT_16BITS(&init->MaxInboundStreams));
	    printf("[init TSN: %u] ", EXTRACT_32BITS(&init->initialTSN));

#if(0) 
	    if( (init+1) < chunkEnd )
	      printf(" @@@@@ UNFINISHED @@@@@@%s\n",
		     "Optional params present, but not printed.");
#endif
	    break;
	  }
	case SCTP_INITIATION_ACK :
	  {
	    const struct sctpInitiation *init;

	    printf("[INIT ACK] ");
	    init=(const struct sctpInitiation*)(chunkDescPtr+1);
	    printf("[init tag: %u] ", EXTRACT_32BITS(&init->initTag));
	    printf("[rwnd: %u] ", EXTRACT_32BITS(&init->rcvWindowCredit));
	    printf("[OS: %u] ", EXTRACT_16BITS(&init->NumPreopenStreams));
	    printf("[MIS: %u] ", EXTRACT_16BITS(&init->MaxInboundStreams));
	    printf("[init TSN: %u] ", EXTRACT_32BITS(&init->initialTSN));

#if(0) 
	    if( (init+1) < chunkEnd )
	      printf(" @@@@@ UNFINISHED @@@@@@%s\n",
		     "Optional params present, but not printed.");
#endif
	    break;
	  }
	case SCTP_SELECTIVE_ACK:
	  {
	    const struct sctpSelectiveAck *sack;
	    const struct sctpSelectiveFrag *frag;
	    int fragNo, tsnNo;
	    const u_char *dupTSN;

	    printf("[SACK] ");
	    sack=(const struct sctpSelectiveAck*)(chunkDescPtr+1);
	    printf("[cum ack %u] ", EXTRACT_32BITS(&sack->highestConseqTSN));
	    printf("[a_rwnd %u] ", EXTRACT_32BITS(&sack->updatedRwnd));
	    printf("[#gap acks %u] ", EXTRACT_16BITS(&sack->numberOfdesc));
	    printf("[#dup tsns %u] ", EXTRACT_16BITS(&sack->numDupTsns));


	    
	    for (frag = ( (const struct sctpSelectiveFrag *)
			  ((const struct sctpSelectiveAck *) sack+1)),
		   fragNo=0;
		 (const void *)frag < nextChunk && fragNo < EXTRACT_16BITS(&sack->numberOfdesc);
		 frag++, fragNo++)
	      printf("\n\t\t[gap ack block #%d: start = %u, end = %u] ",
		     fragNo+1,
		     EXTRACT_32BITS(&sack->highestConseqTSN) + EXTRACT_16BITS(&frag->fragmentStart),
		     EXTRACT_32BITS(&sack->highestConseqTSN) + EXTRACT_16BITS(&frag->fragmentEnd));


	    
	    for (dupTSN = (const u_char *)frag, tsnNo=0;
		 (const void *) dupTSN < nextChunk && tsnNo<EXTRACT_16BITS(&sack->numDupTsns);
		 dupTSN += 4, tsnNo++)
	      printf("\n\t\t[dup TSN #%u: %u] ", tsnNo+1,
	          EXTRACT_32BITS(dupTSN));

	    break;
	  }
	case SCTP_HEARTBEAT_REQUEST :
	  {
	    const struct sctpHBsender *hb;

	    hb=(const struct sctpHBsender*)chunkDescPtr;

	    printf("[HB REQ] ");

	    break;
	  }
	case SCTP_HEARTBEAT_ACK :
	  printf("[HB ACK] ");
	  break;
	case SCTP_ABORT_ASSOCIATION :
	  printf("[ABORT] ");
	  break;
	case SCTP_SHUTDOWN :
	  printf("[SHUTDOWN] ");
	  break;
	case SCTP_SHUTDOWN_ACK :
	  printf("[SHUTDOWN ACK] ");
	  break;
	case SCTP_OPERATION_ERR :
	  printf("[OP ERR] ");
	  break;
	case SCTP_COOKIE_ECHO :
	  printf("[COOKIE ECHO] ");
	  break;
	case SCTP_COOKIE_ACK :
	  printf("[COOKIE ACK] ");
	  break;
	case SCTP_ECN_ECHO :
	  printf("[ECN ECHO] ");
	  break;
	case SCTP_ECN_CWR :
	  printf("[ECN CWR] ");
	  break;
	case SCTP_SHUTDOWN_COMPLETE :
	  printf("[SHUTDOWN COMPLETE] ");
	  break;
	case SCTP_FORWARD_CUM_TSN :
	  printf("[FOR CUM TSN] ");
	  break;
	case SCTP_RELIABLE_CNTL :
	  printf("[REL CTRL] ");
	  break;
	case SCTP_RELIABLE_CNTL_ACK :
	  printf("[REL CTRL ACK] ");
	  break;
	default :
	  printf("[Unknown chunk type: 0x%x]", chunkDescPtr->chunkID);
	  return;
	}

	if (vflag < 2)
	  sep = ", (";
    }
    return;

trunc:
    printf("[|sctp]");
    return;
}
/*
 * This is the top level routine of the printer.  'p' is the points
 * to the ether 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
ether_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p)
{
	u_int caplen = h->caplen;
	u_int length = h->len;
	struct ether_header *ep;
	u_short ether_type;
	extern u_short extracted_ethertype;

	ts_print(&h->ts);

	if (caplen < sizeof(struct ether_header)) {
		printf("[|ether]");
		goto out;
	}

	if (eflag)
		ether_print(p, length);

	/*
	 * Some printers want to get back at the ethernet 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.
	 */
	packetp = p;
	snapend = p + caplen;

	length -= sizeof(struct ether_header);
	caplen -= sizeof(struct ether_header);
	ep = (struct ether_header *)p;
	p += sizeof(struct ether_header);

	ether_type = ntohs(ep->ether_type);

	/*
	 * Is it (gag) an 802.3 encapsulation?
	 */
	extracted_ethertype = 0;
	if (ether_type <= ETHERMTU) {
		/* Try to print the LLC-layer header & higher layers */
		if (llc_print(p, length, caplen, ESRC(ep), EDST(ep)) == 0) {
			/* ether_type not known, print raw packet */
			if (!eflag)
				ether_print((u_char *)ep, length);
			if (extracted_ethertype) {
				printf("(LLC %s) ",
			       etherproto_string(htons(extracted_ethertype)));
			}
			if (!xflag && !qflag)
				default_print(p, caplen);
		}
	} else if (ether_encap_print(ether_type, p, length, caplen) == 0) {
		/* ether_type not known, print raw packet */
		if (!eflag)
			ether_print((u_char *)ep, length + sizeof(*ep));
		if (!xflag && !qflag)
			default_print(p, caplen);
	}
	if (xflag)
		default_print(p, caplen);
 out:
	putchar('\n');
}
Exemple #19
0
static void
esis_print(const u_char *p, u_int length)
{
	const u_char *ep;
	int li = p[1];
	const struct esis_hdr *eh = (const struct esis_hdr *) &p[2];
	u_char cksum[2];
	u_char off[2];

	if (length == 2) {
		if (qflag)
			printf(" bad pkt!");
		else
			printf(" no header at all!");
		return;
	}
	ep = p + li;
	if (li > length) {
		if (qflag)
			printf(" bad pkt!");
		else
			printf(" LI(%d) > PDU size (%d)!", li, length);
		return;
	}
	if (li < sizeof(struct esis_hdr) + 2) {
		if (qflag)
			printf(" bad pkt!");
		else {
			printf(" too short for esis header %d:", li);
			while (--length != 0)
				printf("%02X", *p++);
		}
		return;
	}
	switch (eh->type & 0x1f) {

	case ESIS_REDIRECT:
		printf(" redirect");
		break;

	case ESIS_ESH:
		printf(" esh");
		break;

	case ESIS_ISH:
		printf(" ish");
		break;

	default:
		printf(" type %d", eh->type & 0x1f);
		break;
	}
	off[0] = eh->cksum[0];
	off[1] = eh->cksum[1];
	if (vflag && osi_cksum(p, li, eh->cksum, cksum, off)) {
		printf(" bad cksum (got %02x%02x want %02x%02x)",
		       eh->cksum[1], eh->cksum[0], cksum[1], cksum[0]);
		return;
	}
	if (eh->version != 1) {
		printf(" unsupported version %d", eh->version);
		return;
	}
	p += sizeof(*eh) + 2;
	li -= sizeof(*eh) + 2;	/* protoid * li */

	switch (eh->type & 0x1f) {
	case ESIS_REDIRECT: {
		const u_char *dst, *snpa, *is;

		dst = p; p += *p + 1;
		if (p > snapend)
			return;
		printf(" %s", isonsap_string(dst));
		snpa = p; p += *p + 1;
		is = p;   p += *p + 1;
		if (p > snapend)
			return;
		if (p > ep) {
			printf(" [bad li]");
			return;
		}
		if (is[0] == 0)
			printf(" > %s", etheraddr_string(&snpa[1]));
		else
			printf(" > %s", isonsap_string(is));
		li = ep - p;
		break;
	}
	case ESIS_ESH: {
		const u_char *nsap;
		int i, nnsaps;

		nnsaps = *p++;

		/* print NSAPs */
		for (i = 0; i < nnsaps; i++) {
			nsap = p;
			p += *p + 1;
			if (p > ep) {
				printf(" [bad li]");
				return;
			}
			if (p > snapend)
				return;
			printf(" nsap %s", isonsap_string(nsap));
		}
		li = ep - p;
		break;
	}
	case ESIS_ISH: {
		const u_char *is;

		is = p; p += *p + 1;
		if (p > ep) {
			printf(" [bad li]");
			return;
		}
		if (p > snapend)
			return;
		printf(" net %s", isonsap_string(is));
		li = ep - p;
		break;
	}

	default:
		(void)printf(" len=%d", length);
		if (length && p < snapend) {
			length = snapend - p;
			default_print(p, length);
		}
		return;
	}
	if (vflag)
		while (p < ep && li) {
			int op, opli;
			const u_char *q;

			if (snapend - p < 2)
				return;
			if (li < 2) {
				printf(" bad opts/li");
				return;
			}
			op = *p++;
			opli = *p++;
			li -= 2;
			if (opli > li) {
				printf(" opt (%d) too long", op);
				return;
			}
			li -= opli;
			q = p;
			p += opli;
			if (snapend < p)
				return;
			if (op == 198 && opli == 2) {
				printf(" tmo=%d", q[0] * 256 + q[1]);
				continue;
			}
			printf (" %d:<", op);
			while (--opli >= 0)
				printf("%02x", *q++);
			printf (">");
		}
}
Exemple #20
0
/*
 * This is the top level routine of the printer.  'p' points
 * to the ARCNET 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
arcnet_if_print(const struct pcap_pkthdr *h, const u_char *p)
{
	u_int caplen = h->caplen;
	u_int length = h->len;
	const struct arc_header *ap;

	int phds, flag = 0, archdrlen = 0;
	u_int seqid = 0;
	u_char arc_type;

	if (caplen < ARC_HDRLEN) {
		printf("[|arcnet]");
		return (caplen);
	}

	ap = (const struct arc_header *)p;
	arc_type = ap->arc_type;

	switch (arc_type) {
	default:
		phds = 1;
		break;
	case ARCTYPE_IP_OLD:
	case ARCTYPE_ARP_OLD:
	case ARCTYPE_DIAGNOSE:
		phds = 0;
		archdrlen = ARC_HDRLEN;
		break;
	}

	if (phds) {
		if (caplen < ARC_HDRNEWLEN) {
			arcnet_print(p, length, 0, 0, 0);
			printf("[|phds]");
			return (caplen);
		}

		if (ap->arc_flag == 0xff) {
			if (caplen < ARC_HDRNEWLEN_EXC) {
				arcnet_print(p, length, 0, 0, 0);
				printf("[|phds extended]");
				return (caplen);
			}
			flag = ap->arc_flag2;
			seqid = EXTRACT_16BITS(&ap->arc_seqid2);
			archdrlen = ARC_HDRNEWLEN_EXC;
		} else {
			flag = ap->arc_flag;
			seqid = EXTRACT_16BITS(&ap->arc_seqid);
			archdrlen = ARC_HDRNEWLEN;
		}
	}


	if (eflag)
		arcnet_print(p, length, phds, flag, seqid);

	/*
	 * Go past the ARCNET header.
	 */
	length -= archdrlen;
	caplen -= archdrlen;
	p += archdrlen;

	if (phds && flag && (flag & 1) == 0) {
		/*
		 * This is a middle fragment.
		 */
		return (archdrlen);
	}

	if (!arcnet_encap_print(arc_type, p, length, caplen))
		default_print(p, caplen);

	return (archdrlen);
}
Exemple #21
0
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, extracted_ethertype,
                         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);
}
Exemple #22
0
u_int
token_print(const u_char *p, u_int length, u_int caplen)
{
	const struct token_header *trp;
	u_short extracted_ethertype;
	struct ether_header ehdr;
	u_int route_len = 0, hdr_len = TOKEN_HDRLEN;
	int seg;

	trp = (const struct token_header *)p;

	if (caplen < TOKEN_HDRLEN) {
		printf("[|token-ring]");
		return hdr_len;
	}

	/*
	 * Get the TR addresses into a canonical form
	 */
	extract_token_addrs(trp, (char*)ESRC(&ehdr), (char*)EDST(&ehdr));

	/* Adjust for source routing information in the MAC header */
	if (IS_SOURCE_ROUTED(trp)) {
		/* Clear source-routed bit */
		*ESRC(&ehdr) &= 0x7f;

		if (eflag)
			token_hdr_print(trp, length, ESRC(&ehdr), EDST(&ehdr));

		if (caplen < TOKEN_HDRLEN + 2) {
			printf("[|token-ring]");
			return hdr_len;
		}
		route_len = RIF_LENGTH(trp);
		hdr_len += route_len;
		if (caplen < hdr_len) {
			printf("[|token-ring]");
			return hdr_len;
		}
		if (vflag) {
			printf("%s ", broadcast_indicator[BROADCAST(trp)]);
			printf("%s", direction[DIRECTION(trp)]);

			for (seg = 0; seg < SEGMENT_COUNT(trp); seg++)
				printf(" [%d:%d]", RING_NUMBER(trp, seg),
				    BRIDGE_NUMBER(trp, seg));
		} else {
			printf("rt = %x", EXTRACT_16BITS(&trp->token_rcf));

			for (seg = 0; seg < SEGMENT_COUNT(trp); seg++)
				printf(":%x", EXTRACT_16BITS(&trp->token_rseg[seg]));
		}
		printf(" (%s) ", largest_frame[LARGEST_FRAME(trp)]);
	} else {
		if (eflag)
			token_hdr_print(trp, length, ESRC(&ehdr), EDST(&ehdr));
	}

	/* Skip over token ring MAC header and routing information */
	length -= hdr_len;
	p += hdr_len;
	caplen -= hdr_len;

	/* Frame Control field determines interpretation of packet */
	if (FRAME_TYPE(trp) == TOKEN_FC_LLC) {
		/* Try to print the LLC-layer header & higher layers */
		if (llc_print(p, length, caplen, ESRC(&ehdr), EDST(&ehdr),
		    &extracted_ethertype) == 0) {
			/* ether_type not known, print raw packet */
			if (!eflag)
				token_hdr_print(trp,
				    length + TOKEN_HDRLEN + route_len,
				    ESRC(&ehdr), EDST(&ehdr));
			if (extracted_ethertype) {
				printf("(LLC %s) ",
			etherproto_string(htons(extracted_ethertype)));
			}
			if (!suppress_default_print)
				default_print(p, caplen);
		}
	} else {
		/* Some kinds of TR packet we cannot handle intelligently */
		/* XXX - dissect MAC packets if frame type is 0 */
		if (!eflag)
			token_hdr_print(trp, length + TOKEN_HDRLEN + route_len,
			    ESRC(&ehdr), EDST(&ehdr));
		if (!suppress_default_print)
			default_print(p, caplen);
	}
	return (hdr_len);
}
Exemple #23
0
/*
 * Print an Ethernet frame.
 * This might be encapsulated within another frame; we might be passed
 * a pointer to a function that can print header information for that
 * frame's protocol, and an argument to pass to that function.
 */
void
ether_print(const u_char *p, u_int length, u_int caplen,
            void (*print_encap_header)(const u_char *), const u_char *encap_header_arg)
{
    struct ether_header *ep;
    u_int orig_length;
    u_short ether_type;
    u_short extracted_ether_type;

    if (caplen < ETHER_HDRLEN || length < ETHER_HDRLEN) {
        printf("[|ether]");
        return;
    }

    if (eflag) {
        if (print_encap_header != NULL)
            (*print_encap_header)(encap_header_arg);
        ether_hdr_print(p, length);
    }
    orig_length = length;

    length -= ETHER_HDRLEN;
    caplen -= ETHER_HDRLEN;
    ep = (struct ether_header *)p;
    p += ETHER_HDRLEN;

    ether_type = EXTRACT_16BITS(&ep->ether_type);

recurse:
    /*
     * Is it (gag) an 802.3 encapsulation?
     */
    if (ether_type <= ETHERMTU) {
        /* Try to print the LLC-layer header & higher layers */
        if (llc_print(p, length, caplen, ESRC(ep), EDST(ep),
                      &extracted_ether_type) == 0) {
            /* ether_type not known, print raw packet */
            if (!eflag) {
                if (print_encap_header != NULL)
                    (*print_encap_header)(encap_header_arg);
                ether_hdr_print((u_char *)ep, orig_length);
            }

            if (!suppress_default_print)
                default_print(p, caplen);
        }
    } else if (ether_type == ETHERTYPE_8021Q) {
        /*
         * Print VLAN information, and then go back and process
         * the enclosed type field.
         */
        if (caplen < 4 || length < 4) {
            printf("[|vlan]");
            return;
        }
        if (eflag) {
            u_int16_t tag = EXTRACT_16BITS(p);

            printf("vlan %u, p %u%s, ",
                   tag & 0xfff,
                   tag >> 13,
                   (tag & 0x1000) ? ", CFI" : "");
        }

        ether_type = EXTRACT_16BITS(p + 2);
        if (eflag && ether_type > ETHERMTU)
            printf("ethertype %s, ", tok2str(ethertype_values,"0x%04x", ether_type));
        p += 4;
        length -= 4;
        caplen -= 4;
        goto recurse;
    } else if (ether_type == ETHERTYPE_JUMBO) {
Exemple #24
0
static int
print_decnet_ctlmsg(register const union routehdr *rhp, u_int length,
    u_int caplen)
{
	int mflags = EXTRACT_LE_8BITS(rhp->rh_short.sh_flags);
	register union controlmsg *cmp = (union controlmsg *)rhp;
	int src, dst, info, blksize, eco, ueco, hello, other, vers;
	etheraddr srcea, rtea;
	int priority;
	char *rhpx = (char *)rhp;
	int ret;

	switch (mflags & RMF_CTLMASK) {
	case RMF_INIT:
	    (void)printf("init ");
	    if (length < sizeof(struct initmsg))
		goto trunc;
	    TCHECK(cmp->cm_init);
	    src = EXTRACT_LE_16BITS(cmp->cm_init.in_src);
	    info = EXTRACT_LE_8BITS(cmp->cm_init.in_info);
	    blksize = EXTRACT_LE_16BITS(cmp->cm_init.in_blksize);
	    vers = EXTRACT_LE_8BITS(cmp->cm_init.in_vers);
	    eco = EXTRACT_LE_8BITS(cmp->cm_init.in_eco);
	    ueco = EXTRACT_LE_8BITS(cmp->cm_init.in_ueco);
	    hello = EXTRACT_LE_16BITS(cmp->cm_init.in_hello);
	    print_t_info(info);
	    (void)printf(
		"src %sblksize %d vers %d eco %d ueco %d hello %d",
			dnaddr_string(src), blksize, vers, eco, ueco,
			hello);
	    ret = 1;
	    break;
	case RMF_VER:
	    (void)printf("verification ");
	    if (length < sizeof(struct verifmsg))
		goto trunc;
	    TCHECK(cmp->cm_ver);
	    src = EXTRACT_LE_16BITS(cmp->cm_ver.ve_src);
	    other = EXTRACT_LE_8BITS(cmp->cm_ver.ve_fcnval);
	    (void)printf("src %s fcnval %o", dnaddr_string(src), other);
	    ret = 1;
	    break;
	case RMF_TEST:
	    (void)printf("test ");
	    if (length < sizeof(struct testmsg))
		goto trunc;
	    TCHECK(cmp->cm_test);
	    src = EXTRACT_LE_16BITS(cmp->cm_test.te_src);
	    other = EXTRACT_LE_8BITS(cmp->cm_test.te_data);
	    (void)printf("src %s data %o", dnaddr_string(src), other);
	    ret = 1;
	    break;
	case RMF_L1ROUT:
	    (void)printf("lev-1-routing ");
	    if (length < sizeof(struct l1rout))
		goto trunc;
	    TCHECK(cmp->cm_l1rou);
	    src = EXTRACT_LE_16BITS(cmp->cm_l1rou.r1_src);
	    (void)printf("src %s ", dnaddr_string(src));
	    ret = print_l1_routes(&(rhpx[sizeof(struct l1rout)]),
				length - sizeof(struct l1rout));
	    break;
	case RMF_L2ROUT:
	    (void)printf("lev-2-routing ");
	    if (length < sizeof(struct l2rout))
		goto trunc;
	    TCHECK(cmp->cm_l2rout);
	    src = EXTRACT_LE_16BITS(cmp->cm_l2rout.r2_src);
	    (void)printf("src %s ", dnaddr_string(src));
	    ret = print_l2_routes(&(rhpx[sizeof(struct l2rout)]),
				length - sizeof(struct l2rout));
	    break;
	case RMF_RHELLO:
	    (void)printf("router-hello ");
	    if (length < sizeof(struct rhellomsg))
		goto trunc;
	    TCHECK(cmp->cm_rhello);
	    vers = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_vers);
	    eco = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_eco);
	    ueco = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_ueco);
	    memcpy((char *)&srcea, (char *)&(cmp->cm_rhello.rh_src),
		sizeof(srcea));
	    src = EXTRACT_LE_16BITS(srcea.dne_remote.dne_nodeaddr);
	    info = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_info);
	    blksize = EXTRACT_LE_16BITS(cmp->cm_rhello.rh_blksize);
	    priority = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_priority);
	    hello = EXTRACT_LE_16BITS(cmp->cm_rhello.rh_hello);
	    print_i_info(info);
	    (void)printf(
	    "vers %d eco %d ueco %d src %s blksize %d pri %d hello %d",
			vers, eco, ueco, dnaddr_string(src),
			blksize, priority, hello);
	    ret = print_elist(&(rhpx[sizeof(struct rhellomsg)]),
				length - sizeof(struct rhellomsg));
	    break;
	case RMF_EHELLO:
	    (void)printf("endnode-hello ");
	    if (length < sizeof(struct ehellomsg))
		goto trunc;
	    TCHECK(cmp->cm_ehello);
	    vers = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_vers);
	    eco = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_eco);
	    ueco = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_ueco);
	    memcpy((char *)&srcea, (char *)&(cmp->cm_ehello.eh_src),
		sizeof(srcea));
	    src = EXTRACT_LE_16BITS(srcea.dne_remote.dne_nodeaddr);
	    info = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_info);
	    blksize = EXTRACT_LE_16BITS(cmp->cm_ehello.eh_blksize);
	    /*seed*/
	    memcpy((char *)&rtea, (char *)&(cmp->cm_ehello.eh_router),
		sizeof(rtea));
	    dst = EXTRACT_LE_16BITS(rtea.dne_remote.dne_nodeaddr);
	    hello = EXTRACT_LE_16BITS(cmp->cm_ehello.eh_hello);
	    other = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_data);
	    print_i_info(info);
	    (void)printf(
	"vers %d eco %d ueco %d src %s blksize %d rtr %s hello %d data %o",
			vers, eco, ueco, dnaddr_string(src),
			blksize, dnaddr_string(dst), hello, other);
	    ret = 1;
	    break;

	default:
	    (void)printf("unknown control message");
	    default_print((u_char *)rhp, min(length, caplen));
	    ret = 1;
	    break;
	}
	return (ret);

trunc:
	return (0);
}
Exemple #25
0
/*
 * This is the top level routine of the printer.  'p' is the points
 * to the LLC/SNAP 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
atm_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p)
{
	u_int caplen = h->caplen;
	u_int length = h->len;
	u_short ethertype;

	ts_print(&h->ts);

	if (caplen < 8) {
		printf("[|atm]");
		goto out;
	}
	if (p[0] != 0xaa || p[1] != 0xaa || p[2] != 0x03) {
		/*XXX assume 802.6 MAC header from fore driver */
		if (eflag)
			printf("%04x%04x %04x%04x ",
			       p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3],
			       p[4] << 24 | p[5] << 16 | p[6] << 8 | p[7],
			       p[8] << 24 | p[9] << 16 | p[10] << 8 | p[11],
			       p[12] << 24 | p[13] << 16 | p[14] << 8 | p[15]);
		p += 20;
		length -= 20;
		caplen -= 20;
	}
	ethertype = p[6] << 8 | p[7];
	if (eflag)
		printf("%02x %02x %02x %02x-%02x-%02x %04x: ",
		       p[0], p[1], p[2], /* dsap/ssap/ctrl */
		       p[3], p[4], p[5], /* manufacturer's code */
		       ethertype);

	/*
	 * Some printers want to get back at the ethernet 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.
	 */
	packetp = p;
	snapend = p + caplen;

	length -= 8;
	caplen -= 8;
	p += 8;

	switch (ethertype) {

	case ETHERTYPE_IP:
		ip_print(p, length);
		break;

#ifdef INET6
	case ETHERTYPE_IPV6:
		ip6_print(p, length);
		break;
#endif /*INET6*/

		/*XXX this probably isn't right */
	case ETHERTYPE_ARP:
	case ETHERTYPE_REVARP:
		arp_print(p, length, caplen);
		break;
#ifdef notyet
	case ETHERTYPE_DN:
		decnet_print(p, length, caplen);
		break;

	case ETHERTYPE_ATALK:
		if (vflag)
			fputs("et1 ", stdout);
		atalk_print(p, length);
		break;

	case ETHERTYPE_AARP:
		aarp_print(p, length);
		break;

	case ETHERTYPE_LAT:
	case ETHERTYPE_MOPRC:
	case ETHERTYPE_MOPDL:
		/* default_print for now */
#endif
	default:
		/* ether_type not known, print raw packet */
		if (!eflag)
			printf("%02x %02x %02x %02x-%02x-%02x %04x: ",
			       p[0], p[1], p[2], /* dsap/ssap/ctrl */
			       p[3], p[4], p[5], /* manufacturer's code */
			       ethertype);
		if (!xflag && !qflag)
			default_print(p, caplen);
	}
	if (xflag)
		default_print(p, caplen);
 out:
	putchar('\n');
}
Exemple #26
0
void
decnet_print(register const u_char *ap, register u_int length,
	     register u_int caplen)
{
	register const union routehdr *rhp;
	register int mflags;
	int dst, src, hops;
	u_int nsplen, pktlen;
	const u_char *nspp;

	if (length < sizeof(struct shorthdr)) {
		(void)printf("[|decnet]");
		return;
	}

	TCHECK2(*ap, sizeof(short));
	pktlen = EXTRACT_LE_16BITS(ap);
	if (pktlen < sizeof(struct shorthdr)) {
		(void)printf("[|decnet]");
		return;
	}
	if (pktlen > length) {
		(void)printf("[|decnet]");
		return;
	}
	length = pktlen;

	rhp = (const union routehdr *)&(ap[sizeof(short)]);
	TCHECK(rhp->rh_short.sh_flags);
	mflags = EXTRACT_LE_8BITS(rhp->rh_short.sh_flags);

	if (mflags & RMF_PAD) {
	    /* pad bytes of some sort in front of message */
	    u_int padlen = mflags & RMF_PADMASK;
	    if (vflag)
		(void) printf("[pad:%d] ", padlen);
	    if (length < padlen + 2) {
		(void)printf("[|decnet]");
		return;
	    }
	    TCHECK2(ap[sizeof(short)], padlen);
	    ap += padlen;
	    length -= padlen;
	    caplen -= padlen;
	    rhp = (const union routehdr *)&(ap[sizeof(short)]);
	    mflags = EXTRACT_LE_8BITS(rhp->rh_short.sh_flags);
	}

	if (mflags & RMF_FVER) {
		(void) printf("future-version-decnet");
		default_print(ap, min(length, caplen));
		return;
	}

	/* is it a control message? */
	if (mflags & RMF_CTLMSG) {
		if (!print_decnet_ctlmsg(rhp, length, caplen))
			goto trunc;
		return;
	}

	switch (mflags & RMF_MASK) {
	case RMF_LONG:
	    if (length < sizeof(struct longhdr)) {
		(void)printf("[|decnet]");
		return;
	    }
	    TCHECK(rhp->rh_long);
	    dst =
		EXTRACT_LE_16BITS(rhp->rh_long.lg_dst.dne_remote.dne_nodeaddr);
	    src =
		EXTRACT_LE_16BITS(rhp->rh_long.lg_src.dne_remote.dne_nodeaddr);
	    hops = EXTRACT_LE_8BITS(rhp->rh_long.lg_visits);
	    nspp = &(ap[sizeof(short) + sizeof(struct longhdr)]);
	    nsplen = length - sizeof(struct longhdr);
	    break;
	case RMF_SHORT:
	    TCHECK(rhp->rh_short);
	    dst = EXTRACT_LE_16BITS(rhp->rh_short.sh_dst);
	    src = EXTRACT_LE_16BITS(rhp->rh_short.sh_src);
	    hops = (EXTRACT_LE_8BITS(rhp->rh_short.sh_visits) & VIS_MASK)+1;
	    nspp = &(ap[sizeof(short) + sizeof(struct shorthdr)]);
	    nsplen = length - sizeof(struct shorthdr);
	    break;
	default:
	    (void) printf("unknown message flags under mask");
	    default_print((u_char *)ap, min(length, caplen));
	    return;
	}

	(void)printf("%s > %s %d ",
			dnaddr_string(src), dnaddr_string(dst), pktlen);
	if (vflag) {
	    if (mflags & RMF_RQR)
		(void)printf("RQR ");
	    if (mflags & RMF_RTS)
		(void)printf("RTS ");
	    if (mflags & RMF_IE)
		(void)printf("IE ");
	    (void)printf("%d hops ", hops);
	}

	if (!print_nsp(nspp, nsplen))
		goto trunc;
	return;

trunc:
	(void)printf("[|decnet]");
	return;
}
Exemple #27
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');
}
Exemple #28
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);
}
Exemple #29
0
/*
 * This is the top level routine of the printer.  'p' points to the
 * Linux "cooked capture" 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
sll_if_print(const struct pcap_pkthdr *h, const u_char *p)
{
	u_int caplen = h->caplen;
	u_int length = h->len;
	register const struct sll_header *sllp;
	u_short ether_type;
	u_short extracted_ethertype;

	if (caplen < SLL_HDR_LEN) {
		/*
		 * XXX - this "can't happen" because "pcap-linux.c" always
		 * adds this many bytes of header to every packet in a
		 * cooked socket capture.
		 */
		printf("[|sll]");
		return (caplen);
	}

	sllp = (const struct sll_header *)p;

	if (eflag)
		sll_print(sllp, length);

	/*
	 * Go past the cooked-mode header.
	 */
	length -= SLL_HDR_LEN;
	caplen -= SLL_HDR_LEN;
	p += SLL_HDR_LEN;

	ether_type = EXTRACT_16BITS(&sllp->sll_protocol);

recurse:
	/*
	 * Is it (gag) an 802.3 encapsulation, or some non-Ethernet
	 * packet type?
	 */
	if (ether_type <= ETHERMTU) {
		/*
		 * Yes - what type is it?
		 */
		switch (ether_type) {

		case LINUX_SLL_P_802_3:
			/*
			 * Ethernet_802.3 IPX frame.
			 */
			ipx_print(p, length);
			break;

		case LINUX_SLL_P_802_2:
			/*
			 * 802.2.
			 * Try to print the LLC-layer header & higher layers.
			 */
			if (llc_print(p, length, caplen, NULL, NULL,
			    &extracted_ethertype) == 0)
				goto unknown;	/* unknown LLC type */
			break;

		default:
			extracted_ethertype = 0;
			/*FALLTHROUGH*/

		unknown:
			/* ether_type not known, print raw packet */
			if (!eflag)
				sll_print(sllp, length + SLL_HDR_LEN);
			if (extracted_ethertype) {
				printf("(LLC %s) ",
			       etherproto_string(htons(extracted_ethertype)));
			}
			if (!suppress_default_print)
				default_print(p, caplen);
			break;
		}
	} else if (ether_type == ETHERTYPE_8021Q) {
		/*
		 * Print VLAN information, and then go back and process
		 * the enclosed type field.
		 */
		if (caplen < 4 || length < 4) {
			printf("[|vlan]");
			return (SLL_HDR_LEN);
		}
	        if (eflag) {
	        	u_int16_t tag = EXTRACT_16BITS(p);

			printf("vlan %u, p %u%s, ",
			    tag & 0xfff,
			    tag >> 13,
			    (tag & 0x1000) ? ", CFI" : "");
		}

		ether_type = EXTRACT_16BITS(p + 2);
		if (ether_type <= ETHERMTU)
			ether_type = LINUX_SLL_P_802_2;
		if (!qflag) {
			(void)printf("ethertype %s, ",
			    tok2str(ethertype_values, "Unknown", ether_type));
		}
		p += 4;
		length -= 4;
		caplen -= 4;
		goto recurse;
	} else {
		if (ethertype_print(gndo, ether_type, p, length, caplen) == 0) {
Exemple #30
0
void sctp_print(const u_char *bp,        /* beginning of sctp packet */
		const u_char *bp2,       /* beginning of enclosing */
		u_int sctpPacketLength)  /* ip packet */
{
  const struct sctpHeader *sctpPktHdr;
  const struct ip *ip;
#ifdef INET6
  const struct ip6_hdr *ip6;
#endif
  const void *endPacketPtr;
  u_short sourcePort, destPort;
  int chunkCount;
  const struct sctpChunkDesc *chunkDescPtr;
  const void *nextChunk;
  const char *sep;
  int isforces = 0;


  sctpPktHdr = (const struct sctpHeader*) bp;
  endPacketPtr = (const u_char*)sctpPktHdr+sctpPacketLength;

  if( (u_long) endPacketPtr > (u_long) snapend)
    endPacketPtr = (const void *) snapend;
  ip = (struct ip *)bp2;
#ifdef INET6
  if (IP_V(ip) == 6)
    ip6 = (const struct ip6_hdr *)bp2;
  else
    ip6 = NULL;
#endif /*INET6*/
  TCHECK(*sctpPktHdr);

  if (sctpPacketLength < sizeof(struct sctpHeader))
    {
      (void)printf("truncated-sctp - %ld bytes missing!",
		   (long)sctpPacketLength-sizeof(struct sctpHeader));
      return;
    }

  /*    sctpPacketLength -= sizeof(struct sctpHeader);  packet length  */
  /*  			      is now only as long as the payload  */

  sourcePort = EXTRACT_16BITS(&sctpPktHdr->source);
  destPort = EXTRACT_16BITS(&sctpPktHdr->destination);

#ifdef INET6
  if (ip6) {
    (void)printf("%s.%d > %s.%d: sctp",
      ip6addr_string(&ip6->ip6_src),
      sourcePort,
      ip6addr_string(&ip6->ip6_dst),
      destPort);
  } else
#endif /*INET6*/
  {
    (void)printf("%s.%d > %s.%d: sctp",
      ipaddr_string(&ip->ip_src),
      sourcePort,
      ipaddr_string(&ip->ip_dst),
      destPort);
  }
  fflush(stdout);

  if (isForCES_port(sourcePort)) {
         printf("[%s]", tok2str(ForCES_channels, NULL, sourcePort));
         isforces = 1;
  }
  if (isForCES_port(destPort)) {
         printf("[%s]", tok2str(ForCES_channels, NULL, destPort));
         isforces = 1;
  }

  if (vflag >= 2)
    sep = "\n\t";
  else
    sep = " (";
  /* cycle through all chunks, printing information on each one */
  for (chunkCount = 0,
	 chunkDescPtr = (const struct sctpChunkDesc *)
	    ((const u_char*) sctpPktHdr + sizeof(struct sctpHeader));
       chunkDescPtr != NULL &&
	 ( (const void *)
	    ((const u_char *) chunkDescPtr + sizeof(struct sctpChunkDesc))
	   <= endPacketPtr);

       chunkDescPtr = (const struct sctpChunkDesc *) nextChunk, chunkCount++)
    {
      u_int16_t chunkLength;
      const u_char *chunkEnd;
      u_int16_t align;

      TCHECK(*chunkDescPtr);
      chunkLength = EXTRACT_16BITS(&chunkDescPtr->chunkLength);
      if (chunkLength < sizeof(*chunkDescPtr)) {
      	printf("%s%d) [Bad chunk length %u]", sep, chunkCount+1, chunkLength);
      	break;
      }

      TCHECK2(*((u_int8_t *)chunkDescPtr), chunkLength);
      chunkEnd = ((const u_char*)chunkDescPtr + chunkLength);

      align=chunkLength % 4;
      if (align != 0)
	align = 4 - align;

      nextChunk = (const void *) (chunkEnd + align);

      printf("%s%d) ", sep, chunkCount+1);
      switch (chunkDescPtr->chunkID)
	{
	case SCTP_DATA :
	  {
	    const struct sctpDataPart *dataHdrPtr;

	    printf("[DATA] ");

	    if ((chunkDescPtr->chunkFlg & SCTP_DATA_UNORDERED)
		== SCTP_DATA_UNORDERED)
	      printf("(U)");

	    if ((chunkDescPtr->chunkFlg & SCTP_DATA_FIRST_FRAG)
		== SCTP_DATA_FIRST_FRAG)
	      printf("(B)");

	    if ((chunkDescPtr->chunkFlg & SCTP_DATA_LAST_FRAG)
		== SCTP_DATA_LAST_FRAG)
	      printf("(E)");

	    if( ((chunkDescPtr->chunkFlg & SCTP_DATA_UNORDERED)
		 == SCTP_DATA_UNORDERED)
		||
		((chunkDescPtr->chunkFlg & SCTP_DATA_FIRST_FRAG)
		 == SCTP_DATA_FIRST_FRAG)
		||
		((chunkDescPtr->chunkFlg & SCTP_DATA_LAST_FRAG)
		 == SCTP_DATA_LAST_FRAG) )
	      printf(" ");

	    dataHdrPtr=(const struct sctpDataPart*)(chunkDescPtr+1);

	    u_int32_t ppid = EXTRACT_32BITS(&dataHdrPtr->payloadtype);

	    printf("[TSN: %u] ", EXTRACT_32BITS(&dataHdrPtr->TSN));
	    printf("[SID: %u] ", EXTRACT_16BITS(&dataHdrPtr->streamId));
	    printf("[SSEQ %u] ", EXTRACT_16BITS(&dataHdrPtr->sequence));
	    printf("[PPID %s] ",
		    tok2str(PayloadProto_idents, "0x%x", ppid));
	    fflush(stdout);


	    if (!isforces) {
		isforces = (ppid == SCTP_PPID_FORCES_HP) ||
		    (ppid == SCTP_PPID_FORCES_MP) ||
		    (ppid == SCTP_PPID_FORCES_LP);
	    }

	    const u_char *payloadPtr = (const u_char *) (dataHdrPtr + 1);
	    if (EXTRACT_16BITS(&chunkDescPtr->chunkLength) <
		    sizeof(struct sctpDataPart) + sizeof(struct sctpChunkDesc) + 1) {
		printf("bogus chunk length %u]", EXTRACT_16BITS(&chunkDescPtr->chunkLength));
		return;
	    }

	    u_int payload_size = EXTRACT_16BITS(&chunkDescPtr->chunkLength) -
		(sizeof(struct sctpDataPart) + sizeof(struct sctpChunkDesc));
	    if (isforces) {
		forces_print(payloadPtr, payload_size);
	    } else if (vflag >= 2) {	/* if verbose output is specified */
					/* at the command line */
		switch (ppid) {
		case SCTP_PPID_M3UA :
			print_m3ua(payloadPtr, payload_size);
			break;
		default:
			printf("[Payload");
			if (!suppress_default_print) {
				printf(":");
				default_print(payloadPtr, payload_size);
			}
			printf("]");
			break;
		}
	    }
	    break;
	  }
	case SCTP_INITIATION :
	  {
	    const struct sctpInitiation *init;

	    printf("[INIT] ");
	    init=(const struct sctpInitiation*)(chunkDescPtr+1);
	    printf("[init tag: %u] ", EXTRACT_32BITS(&init->initTag));
	    printf("[rwnd: %u] ", EXTRACT_32BITS(&init->rcvWindowCredit));
	    printf("[OS: %u] ", EXTRACT_16BITS(&init->NumPreopenStreams));
	    printf("[MIS: %u] ", EXTRACT_16BITS(&init->MaxInboundStreams));
	    printf("[init TSN: %u] ", EXTRACT_32BITS(&init->initialTSN));

#if(0) /* ALC you can add code for optional params here */
	    if( (init+1) < chunkEnd )
	      printf(" @@@@@ UNFINISHED @@@@@@%s\n",
		     "Optional params present, but not printed.");
#endif
	    break;
	  }
	case SCTP_INITIATION_ACK :
	  {
	    const struct sctpInitiation *init;

	    printf("[INIT ACK] ");
	    init=(const struct sctpInitiation*)(chunkDescPtr+1);
	    printf("[init tag: %u] ", EXTRACT_32BITS(&init->initTag));
	    printf("[rwnd: %u] ", EXTRACT_32BITS(&init->rcvWindowCredit));
	    printf("[OS: %u] ", EXTRACT_16BITS(&init->NumPreopenStreams));
	    printf("[MIS: %u] ", EXTRACT_16BITS(&init->MaxInboundStreams));
	    printf("[init TSN: %u] ", EXTRACT_32BITS(&init->initialTSN));

#if(0) /* ALC you can add code for optional params here */
	    if( (init+1) < chunkEnd )
	      printf(" @@@@@ UNFINISHED @@@@@@%s\n",
		     "Optional params present, but not printed.");
#endif
	    break;
	  }
	case SCTP_SELECTIVE_ACK:
	  {
	    const struct sctpSelectiveAck *sack;
	    const struct sctpSelectiveFrag *frag;
	    int fragNo, tsnNo;
	    const u_char *dupTSN;

	    printf("[SACK] ");
	    sack=(const struct sctpSelectiveAck*)(chunkDescPtr+1);
	    printf("[cum ack %u] ", EXTRACT_32BITS(&sack->highestConseqTSN));
	    printf("[a_rwnd %u] ", EXTRACT_32BITS(&sack->updatedRwnd));
	    printf("[#gap acks %u] ", EXTRACT_16BITS(&sack->numberOfdesc));
	    printf("[#dup tsns %u] ", EXTRACT_16BITS(&sack->numDupTsns));


	    /* print gaps */
	    for (frag = ( (const struct sctpSelectiveFrag *)
			  ((const struct sctpSelectiveAck *) sack+1)),
		   fragNo=0;
		 (const void *)frag < nextChunk && fragNo < EXTRACT_16BITS(&sack->numberOfdesc);
		 frag++, fragNo++)
	      printf("\n\t\t[gap ack block #%d: start = %u, end = %u] ",
		     fragNo+1,
		     EXTRACT_32BITS(&sack->highestConseqTSN) + EXTRACT_16BITS(&frag->fragmentStart),
		     EXTRACT_32BITS(&sack->highestConseqTSN) + EXTRACT_16BITS(&frag->fragmentEnd));


	    /* print duplicate TSNs */
	    for (dupTSN = (const u_char *)frag, tsnNo=0;
		 (const void *) dupTSN < nextChunk && tsnNo<EXTRACT_16BITS(&sack->numDupTsns);
		 dupTSN += 4, tsnNo++)
	      printf("\n\t\t[dup TSN #%u: %u] ", tsnNo+1,
	          EXTRACT_32BITS(dupTSN));

	    break;
	  }
	case SCTP_HEARTBEAT_REQUEST :
	  printf("[HB REQ] ");
	  break;
	case SCTP_HEARTBEAT_ACK :
	  printf("[HB ACK] ");
	  break;
	case SCTP_ABORT_ASSOCIATION :
	  printf("[ABORT] ");
	  break;
	case SCTP_SHUTDOWN :
	  printf("[SHUTDOWN] ");
	  break;
	case SCTP_SHUTDOWN_ACK :
	  printf("[SHUTDOWN ACK] ");
	  break;
	case SCTP_OPERATION_ERR :
	  printf("[OP ERR] ");
	  break;
	case SCTP_COOKIE_ECHO :
	  printf("[COOKIE ECHO] ");
	  break;
	case SCTP_COOKIE_ACK :
	  printf("[COOKIE ACK] ");
	  break;
	case SCTP_ECN_ECHO :
	  printf("[ECN ECHO] ");
	  break;
	case SCTP_ECN_CWR :
	  printf("[ECN CWR] ");
	  break;
	case SCTP_SHUTDOWN_COMPLETE :
	  printf("[SHUTDOWN COMPLETE] ");
	  break;
	case SCTP_FORWARD_CUM_TSN :
	  printf("[FOR CUM TSN] ");
	  break;
	case SCTP_RELIABLE_CNTL :
	  printf("[REL CTRL] ");
	  break;
	case SCTP_RELIABLE_CNTL_ACK :
	  printf("[REL CTRL ACK] ");
	  break;
	default :
	  printf("[Unknown chunk type: 0x%x]", chunkDescPtr->chunkID);
	  return;
	}

	if (vflag < 2)
	  sep = ", (";
    }
    return;

trunc:
    printf("[|sctp]");
    return;
}