Exemple #1
0
static void
print_attr_netmask6(netdissect_options *ndo,
                    const u_char *data, u_int length, u_short attr_code _U_)
{
   u_char data2[16];

   if (length < 2 || length > 18)
   {
       ND_PRINT("ERROR: length %u not in range (2..18)", length);
       return;
   }
   ND_TCHECK_LEN(data, length);
   if (EXTRACT_U_1(data + 1) > 128)
   {
      ND_PRINT("ERROR: netmask %u not in range (0..128)", EXTRACT_U_1(data + 1));
      return;
   }

   memset(data2, 0, sizeof(data2));
   if (length > 2)
      memcpy(data2, data+2, length-2);

   ND_PRINT("%s/%u", ip6addr_string(ndo, data2), EXTRACT_U_1(data + 1));

   if (EXTRACT_U_1(data + 1) > 8 * (length - 2))
      ND_PRINT(" (inconsistent prefix length)");

   return;

   trunc:
     nd_print_trunc(ndo);
}
Exemple #2
0
static inline void
ipnet_hdr_print(netdissect_options *ndo, const u_char *bp, u_int length)
{
	const ipnet_hdr_t *hdr;
	hdr = (const ipnet_hdr_t *)bp;

	ND_TCHECK_SIZE(hdr);
	ND_PRINT("%u > %u", EXTRACT_BE_U_4(hdr->iph_zsrc),
		  EXTRACT_BE_U_4(hdr->iph_zdst));

	if (!ndo->ndo_qflag) {
		ND_PRINT(", family %s (%u)",
                          tok2str(ipnet_values, "Unknown",
                                  EXTRACT_U_1(hdr->iph_family)),
                          EXTRACT_U_1(hdr->iph_family));
        } else {
		ND_PRINT(", %s",
                          tok2str(ipnet_values,
                                  "Unknown Ethertype (0x%04x)",
				  EXTRACT_U_1(hdr->iph_family)));
        }

	ND_PRINT(", length %u: ", length);
	return;
trunc:
	ND_PRINT(" %s", tstr);
}
Exemple #3
0
static void
igrp_entry_print(netdissect_options *ndo, const struct igrprte *igr,
    int is_interior, int is_exterior)
{
	u_int delay, bandwidth;
	u_int metric, mtu;

	if (is_interior)
		ND_PRINT(" *.%u.%u.%u", igr->igr_net[0],
		    igr->igr_net[1], igr->igr_net[2]);
	else if (is_exterior)
		ND_PRINT(" X%u.%u.%u.0", igr->igr_net[0],
		    igr->igr_net[1], igr->igr_net[2]);
	else
		ND_PRINT(" %u.%u.%u.0", igr->igr_net[0],
		    igr->igr_net[1], igr->igr_net[2]);

	delay = EXTRACT_BE_U_3(igr->igr_dly);
	bandwidth = EXTRACT_BE_U_3(igr->igr_bw);
	metric = bandwidth + delay;
	if (metric > 0xffffff)
		metric = 0xffffff;
	mtu = EXTRACT_BE_U_2(igr->igr_mtu);

	ND_PRINT(" d=%u b=%u r=%u l=%u M=%u mtu=%u in %u hops",
	    10 * delay, bandwidth == 0 ? 0 : 10000000 / bandwidth,
	    EXTRACT_U_1(igr->igr_rel), EXTRACT_U_1(igr->igr_ld), metric,
	    mtu, EXTRACT_U_1(igr->igr_hct));
}
Exemple #4
0
/* PPP I/F printer */
u_int
ppp_if_print(netdissect_options *ndo,
             const struct pcap_pkthdr *h, const u_char *p)
{
	u_int length = h->len;
	u_int caplen = h->caplen;

	if (caplen < PPP_HDRLEN) {
		ND_PRINT("[|ppp]");
		return (caplen);
	}

#if 0
	/*
	 * XXX: seems to assume that there are 2 octets prepended to an
	 * actual PPP frame. The 1st octet looks like Input/Output flag
	 * while 2nd octet is unknown, at least to me
	 * ([email protected]).
	 *
	 * That was what the original tcpdump code did.
	 *
	 * FreeBSD's "if_ppp.c" *does* set the first octet to 1 for outbound
	 * packets and 0 for inbound packets - but only if the
	 * protocol field has the 0x8000 bit set (i.e., it's a network
	 * control protocol); it does so before running the packet through
	 * "bpf_filter" to see if it should be discarded, and to see
	 * if we should update the time we sent the most recent packet...
	 *
	 * ...but it puts the original address field back after doing
	 * so.
	 *
	 * NetBSD's "if_ppp.c" doesn't set the first octet in that fashion.
	 *
	 * I don't know if any PPP implementation handed up to a BPF
	 * device packets with the first octet being 1 for outbound and
	 * 0 for inbound packets, so I ([email protected]) don't know
	 * whether that ever needs to be checked or not.
	 *
	 * Note that NetBSD has a DLT_PPP_SERIAL, which it uses for PPP,
	 * and its tcpdump appears to assume that the frame always
	 * begins with an address field and a control field, and that
	 * the address field might be 0x0f or 0x8f, for Cisco
	 * point-to-point with HDLC framing as per section 4.3.1 of RFC
	 * 1547, as well as 0xff, for PPP in HDLC-like framing as per
	 * RFC 1662.
	 *
	 * (Is the Cisco framing in question what DLT_C_HDLC, in
	 * BSD/OS, is?)
	 */
	if (ndo->ndo_eflag)
		ND_PRINT("%c %4d %02x ", EXTRACT_U_1(p) ? 'O' : 'I',
		    length, EXTRACT_U_1(p + 1));
#endif

	ppp_print(ndo, p, length);

	return (0);
}
Exemple #5
0
void
timed_print(netdissect_options *ndo,
            const u_char *bp)
{
	const struct tsp *tsp = (const struct tsp *)bp;
	uint8_t tsp_type;
	int sec, usec;

	ndo->ndo_protocol = "timed";
	ND_TCHECK_1(tsp->tsp_type);
	tsp_type = EXTRACT_U_1(tsp->tsp_type);
	if (tsp_type < TSPTYPENUMBER)
		ND_PRINT("TSP_%s", tsptype[tsp_type]);
	else
		ND_PRINT("(tsp_type %#x)", tsp_type);

	ND_TCHECK_1(tsp->tsp_vers);
	ND_PRINT(" vers %u", EXTRACT_U_1(tsp->tsp_vers));

	ND_TCHECK_2(tsp->tsp_seq);
	ND_PRINT(" seq %u", EXTRACT_BE_U_2(tsp->tsp_seq));

	switch (tsp_type) {
	case TSP_LOOP:
		ND_TCHECK_1(tsp->tsp_hopcnt);
		ND_PRINT(" hopcnt %u", EXTRACT_U_1(tsp->tsp_hopcnt));
		break;
	case TSP_SETTIME:
	case TSP_ADJTIME:
	case TSP_SETDATE:
	case TSP_SETDATEREQ:
		ND_TCHECK_8(&tsp->tsp_time);
		sec = EXTRACT_BE_S_4(tsp->tsp_time.tv_sec);
		usec = EXTRACT_BE_S_4(tsp->tsp_time.tv_usec);
		/* XXX The comparison below is always false? */
		if (usec < 0)
			/* invalid, skip the rest of the packet */
			return;
		ND_PRINT(" time ");
		if (sec < 0 && usec != 0) {
			sec++;
			if (sec == 0)
				ND_PRINT("-");
			usec = 1000000 - usec;
		}
		ND_PRINT("%d.%06d", sec, usec);
		break;
	}
	ND_PRINT(" name ");
	if (nd_printzp(ndo, tsp->tsp_name, sizeof(tsp->tsp_name),
		       ndo->ndo_snapend))
		goto trunc;
	return;

trunc:
	nd_print_trunc(ndo);
}
Exemple #6
0
/* IP6CP config options */
static u_int
print_ip6cp_config_options(netdissect_options *ndo,
                           const u_char *p, u_int length)
{
	u_int opt, len;

	if (length < 2)
		return 0;
	ND_TCHECK_2(p);
	opt = EXTRACT_U_1(p);
	len = EXTRACT_U_1(p + 1);
	if (length < len)
		return 0;
	if (len < 2) {
		ND_PRINT("\n\t  %s Option (0x%02x), length %u (length bogus, should be >= 2)",
		       tok2str(ip6cpopt_values,"unknown",opt),
		       opt,
		       len);
		return 0;
	}

	ND_PRINT("\n\t  %s Option (0x%02x), length %u",
	       tok2str(ip6cpopt_values,"unknown",opt),
	       opt,
	       len);

	switch (opt) {
	case IP6CP_IFID:
		if (len != 10) {
			ND_PRINT(" (length bogus, should be = 10)");
			return len;
		}
		ND_TCHECK_8(p + 2);
		ND_PRINT(": %04x:%04x:%04x:%04x",
		       EXTRACT_BE_U_2(p + 2),
		       EXTRACT_BE_U_2(p + 4),
		       EXTRACT_BE_U_2(p + 6),
		       EXTRACT_BE_U_2(p + 8));
		break;
	default:
		/*
		 * Unknown option; dump it as raw bytes now if we're
		 * not going to do so below.
		 */
		if (ndo->ndo_vflag < 2)
			print_unknown_data(ndo, p + 2, "\n\t    ", len - 2);
		break;
	}
	if (ndo->ndo_vflag > 1)
		print_unknown_data(ndo, p + 2, "\n\t    ", len - 2); /* exclude TLV header */

	return len;

trunc:
	ND_PRINT("[|ip6cp]");
	return 0;
}
Exemple #7
0
/*
 * print vendor specific attributes
 */
static void
print_vendor_attr(netdissect_options *ndo,
                  const u_char *data, u_int length, u_short attr_code _U_)
{
    u_int idx;
    u_int vendor_id;
    u_int vendor_type;
    u_int vendor_length;

    if (length < 4)
        goto trunc;
    ND_TCHECK_4(data);
    vendor_id = EXTRACT_BE_U_4(data);
    data+=4;
    length-=4;

    ND_PRINT("Vendor: %s (%u)",
           tok2str(smi_values,"Unknown",vendor_id),
           vendor_id);

    while (length >= 2) {
	ND_TCHECK_2(data);

        vendor_type = EXTRACT_U_1(data);
        vendor_length = EXTRACT_U_1(data + 1);

        if (vendor_length < 2)
        {
            ND_PRINT("\n\t    Vendor Attribute: %u, Length: %u (bogus, must be >= 2)",
                   vendor_type,
                   vendor_length);
            return;
        }
        if (vendor_length > length)
        {
            ND_PRINT("\n\t    Vendor Attribute: %u, Length: %u (bogus, goes past end of vendor-specific attribute)",
                   vendor_type,
                   vendor_length);
            return;
        }
        data+=2;
        vendor_length-=2;
        length-=2;
	ND_TCHECK_LEN(data, vendor_length);

        ND_PRINT("\n\t    Vendor Attribute: %u, Length: %u, Value: ",
               vendor_type,
               vendor_length);
        for (idx = 0; idx < vendor_length ; idx++, data++)
            ND_PRINT("%c", ND_ISPRINT(EXTRACT_U_1(data)) ? EXTRACT_U_1(data) : '.');
        length-=vendor_length;
    }
    return;

   trunc:
     nd_print_trunc(ndo);
}
Exemple #8
0
static void
pptp_err_code_print(netdissect_options *ndo,
                    const nd_uint8_t *err_code)
{
	ND_PRINT(" ERR_CODE(%u", EXTRACT_U_1(*err_code));
	if (ndo->ndo_vflag) {
		ND_PRINT(":%s", tok2str(pptp_errcode_str, "?", EXTRACT_U_1(*err_code)));
	}
	ND_PRINT(")");
}
Exemple #9
0
/* BACP config options */
static u_int
print_bacp_config_options(netdissect_options *ndo,
                          const u_char *p, u_int length)
{
	u_int opt, len;

	if (length < 2)
		return 0;
	ND_TCHECK_2(p);
	opt = EXTRACT_U_1(p);
	len = EXTRACT_U_1(p + 1);
	if (length < len)
		return 0;
	if (len < 2) {
		ND_PRINT("\n\t  %s Option (0x%02x), length %u (length bogus, should be >= 2)",
		          tok2str(bacconfopts_values, "Unknown", opt),
		          opt,
		          len);
		return 0;
	}

	ND_PRINT("\n\t  %s Option (0x%02x), length %u",
	          tok2str(bacconfopts_values, "Unknown", opt),
	          opt,
	          len);

	switch (opt) {
	case BACPOPT_FPEER:
		if (len != 6) {
			ND_PRINT(" (length bogus, should be = 6)");
			return len;
		}
		ND_TCHECK_4(p + 2);
		ND_PRINT(": Magic-Num 0x%08x", EXTRACT_BE_U_4(p + 2));
		break;
	default:
		/*
		 * Unknown option; dump it as raw bytes now if we're
		 * not going to do so below.
		 */
		if (ndo->ndo_vflag < 2)
			print_unknown_data(ndo, p + 2, "\n\t    ", len - 2);
		break;
	}
	if (ndo->ndo_vflag > 1)
		print_unknown_data(ndo, p + 2, "\n\t    ", len - 2); /* exclude TLV header */

	return len;

trunc:
	ND_PRINT("[|bacp]");
	return 0;
}
Exemple #10
0
/* Print a single OpenFlow message. */
static const u_char *
of_header_body_print(netdissect_options *ndo, const u_char *cp, const u_char *ep)
{
	uint8_t version, type;
	uint16_t length;
	uint32_t xid;

	if (ep < cp + OF_HEADER_LEN)
		goto invalid;
	/* version */
	ND_TCHECK_1(cp);
	version = EXTRACT_U_1(cp);
	cp += 1;
	/* type */
	ND_TCHECK_1(cp);
	type = EXTRACT_U_1(cp);
	cp += 1;
	/* length */
	ND_TCHECK_2(cp);
	length = EXTRACT_BE_U_2(cp);
	cp += 2;
	/* xid */
	ND_TCHECK_4(cp);
	xid = EXTRACT_BE_U_4(cp);
	cp += 4;
	/* Message length includes the header length and a message always includes
	 * the basic header. A message length underrun fails decoding of the rest of
	 * the current packet. At the same time, try decoding as much of the current
	 * message as possible even when it does not end within the current TCP
	 * segment. */
	if (length < OF_HEADER_LEN) {
		of_header_print(ndo, version, type, length, xid);
		goto invalid;
	}
	/* Decode known protocol versions further without printing the header (the
	 * type decoding is version-specific. */
	switch (version) {
	case OF_VER_1_0:
		return of10_header_body_print(ndo, cp, ep, type, length, xid);
	default:
		of_header_print(ndo, version, type, length, xid);
		ND_TCHECK_LEN(cp, length - OF_HEADER_LEN);
		return cp + length - OF_HEADER_LEN; /* done with current message */
	}

invalid: /* fail current packet */
	ND_PRINT("%s", istr);
	ND_TCHECK_LEN(cp, ep - cp);
	return ep;
trunc:
	ND_PRINT("%s", tstr);
	return ep;
}
Exemple #11
0
void
igrp_print(netdissect_options *ndo, const u_char *bp, u_int length)
{
	const struct igrphdr *hdr;
	const u_char *cp;
	u_int nint, nsys, next;

	hdr = (const struct igrphdr *)bp;
	cp = (const u_char *)(hdr + 1);
	ND_PRINT("igrp:");

	/* Header */
	ND_TCHECK_SIZE(hdr);
	nint = EXTRACT_BE_U_2(hdr->ig_ni);
	nsys = EXTRACT_BE_U_2(hdr->ig_ns);
	next = EXTRACT_BE_U_2(hdr->ig_nx);

	ND_PRINT(" %s V%u edit=%u AS=%u (%u/%u/%u)",
	    tok2str(op2str, "op-#%u", IGRP_OP(EXTRACT_U_1(hdr->ig_vop))),
	    IGRP_V(EXTRACT_U_1(hdr->ig_vop)),
	    EXTRACT_U_1(hdr->ig_ed),
	    EXTRACT_BE_U_2(hdr->ig_as),
	    nint,
	    nsys,
	    next);

	length -= sizeof(*hdr);
	while (length >= IGRP_RTE_SIZE) {
		if (nint > 0) {
			ND_TCHECK_LEN(cp, IGRP_RTE_SIZE);
			igrp_entry_print(ndo, (const struct igrprte *)cp, 1, 0);
			--nint;
		} else if (nsys > 0) {
			ND_TCHECK_LEN(cp, IGRP_RTE_SIZE);
			igrp_entry_print(ndo, (const struct igrprte *)cp, 0, 0);
			--nsys;
		} else if (next > 0) {
			ND_TCHECK_LEN(cp, IGRP_RTE_SIZE);
			igrp_entry_print(ndo, (const struct igrprte *)cp, 0, 1);
			--next;
		} else {
			ND_PRINT(" [extra bytes %u]", length);
			break;
		}
		cp += IGRP_RTE_SIZE;
		length -= IGRP_RTE_SIZE;
	}
	if (nint == 0 && nsys == 0 && next == 0)
		return;
trunc:
	ND_PRINT(" [|igrp]");
}
Exemple #12
0
static void
cmu_print(netdissect_options *ndo,
	  const u_char *bp)
{
	const struct cmu_vend *cmu;
	uint8_t v_flags;

	ND_PRINT(" vend-cmu");
	cmu = (const struct cmu_vend *)bp;

	/* Only print if there are unknown bits */
	ND_TCHECK_4(cmu->v_flags);
	v_flags = EXTRACT_U_1(cmu->v_flags);
	if ((v_flags & ~(VF_SMASK)) != 0)
		ND_PRINT(" F:0x%x", v_flags);
	PRINTCMUADDR(v_dgate, "DG");
	PRINTCMUADDR(v_smask, v_flags & VF_SMASK ? "SM" : "SM*");
	PRINTCMUADDR(v_dns1, "NS1");
	PRINTCMUADDR(v_dns2, "NS2");
	PRINTCMUADDR(v_ins1, "IEN1");
	PRINTCMUADDR(v_ins2, "IEN2");
	PRINTCMUADDR(v_ts1, "TS1");
	PRINTCMUADDR(v_ts2, "TS2");
	return;

trunc:
	nd_print_trunc(ndo);
}
Exemple #13
0
void
vxlan_print(netdissect_options *ndo, const u_char *bp, u_int len)
{
    uint8_t flags;
    uint32_t vni;

    ndo->ndo_protocol = "vxlan";
    if (len < VXLAN_HDR_LEN)
        goto trunc;

    ND_TCHECK_LEN(bp, VXLAN_HDR_LEN);

    flags = EXTRACT_U_1(bp);
    bp += 4;

    vni = EXTRACT_BE_U_3(bp);
    bp += 4;

    ND_PRINT("VXLAN, ");
    ND_PRINT("flags [%s] (0x%02x), ", flags & 0x08 ? "I" : ".", flags);
    ND_PRINT("vni %u\n", vni);

    ether_print(ndo, bp, len - VXLAN_HDR_LEN, ndo->ndo_snapend - bp, NULL, NULL);

    return;

trunc:
    nd_print_trunc(ndo);
}
Exemple #14
0
/*
 * Print EtherTalk/TokenTalk packets (or FDDITalk, or whatever it's called
 * when it runs over FDDI; yes, I've seen FDDI captures with AppleTalk
 * packets in them).
 */
void
atalk_print(netdissect_options *ndo,
            const u_char *bp, u_int length)
{
	const struct atDDP *dp;
	u_short snet;

	ndo->ndo_protocol = "atalk";
        if(!ndo->ndo_eflag)
            ND_PRINT("AT ");

	if (length < ddpSize) {
		ND_PRINT(" [|ddp %u]", length);
		return;
	}
	if (!ND_TTEST_LEN(bp, ddpSize)) {
		ND_PRINT(" [|ddp]");
		return;
	}
	dp = (const struct atDDP *)bp;
	snet = EXTRACT_BE_U_2(dp->srcNet);
	ND_PRINT("%s.%s", ataddr_string(ndo, snet, EXTRACT_U_1(dp->srcNode)),
	       ddpskt_string(ndo, EXTRACT_U_1(dp->srcSkt)));
	ND_PRINT(" > %s.%s: ",
	       ataddr_string(ndo, EXTRACT_BE_U_2(dp->dstNet), EXTRACT_U_1(dp->dstNode)),
	       ddpskt_string(ndo, EXTRACT_U_1(dp->dstSkt)));
	bp += ddpSize;
	length -= ddpSize;
	ddp_print(ndo, bp, length, EXTRACT_U_1(dp->type), snet, EXTRACT_U_1(dp->srcNode), EXTRACT_U_1(dp->srcSkt));
}
Exemple #15
0
/*
 * Print the TR MAC header
 */
static void
token_hdr_print(netdissect_options *ndo,
                const struct token_header *trp, u_int length,
                const u_char *fsrc, const u_char *fdst)
{
	const char *srcname, *dstname;

	srcname = etheraddr_string(ndo, fsrc);
	dstname = etheraddr_string(ndo, fdst);

	if (!ndo->ndo_qflag)
		ND_PRINT("%02x %02x ",
		       EXTRACT_U_1(trp->token_ac),
		       EXTRACT_U_1(trp->token_fc));
	ND_PRINT("%s > %s, length %u: ",
	       srcname, dstname,
	       length);
}
Exemple #16
0
static void
ahcp1_body_print(netdissect_options *ndo, const u_char *cp, const u_char *ep)
{
	uint8_t type, mbz;
	uint16_t body_len;

	if (cp + AHCP1_BODY_MIN_LEN > ep)
		goto invalid;
	/* Type */
	ND_TCHECK_1(cp);
	type = EXTRACT_U_1(cp);
	cp += 1;
	/* MBZ */
	ND_TCHECK_1(cp);
	mbz = EXTRACT_U_1(cp);
	cp += 1;
	/* Length */
	ND_TCHECK_2(cp);
	body_len = EXTRACT_BE_U_2(cp);
	cp += 2;

	if (ndo->ndo_vflag) {
		ND_PRINT("\n\t%s", tok2str(ahcp1_msg_str, "Unknown-%u", type));
		if (mbz != 0)
			ND_PRINT(", MBZ %u", mbz);
		ND_PRINT(", Length %u", body_len);
	}
	if (cp + body_len > ep)
		goto invalid;

	/* Options */
	if (ndo->ndo_vflag >= 2)
		ahcp1_options_print(ndo, cp, cp + body_len); /* not ep (ignore extra data) */
	else
		ND_TCHECK_LEN(cp, body_len);
	return;

invalid:
	ND_PRINT("%s", istr);
	ND_TCHECK_LEN(cp, ep - cp);
	return;
trunc:
	nd_print_trunc(ndo);
}
Exemple #17
0
static int
stp_print_config_bpdu(netdissect_options *ndo, const struct stp_bpdu_ *stp_bpdu,
                      u_int length)
{
    uint8_t bpdu_flags;

    ND_TCHECK_1(stp_bpdu->flags);
    bpdu_flags = EXTRACT_U_1(stp_bpdu->flags);
    ND_PRINT(", Flags [%s]",
           bittok2str(stp_bpdu_flag_values, "none", bpdu_flags));

    ND_TCHECK_2(stp_bpdu->port_id);
    ND_PRINT(", bridge-id %s.%04x, length %u",
           stp_print_bridge_id((const u_char *)&stp_bpdu->bridge_id),
           EXTRACT_BE_U_2(stp_bpdu->port_id), length);

    /* in non-verbose mode just print the bridge-id */
    if (!ndo->ndo_vflag) {
        return 1;
    }

    ND_TCHECK_2(stp_bpdu->forward_delay);
    ND_PRINT("\n\tmessage-age %.2fs, max-age %.2fs"
           ", hello-time %.2fs, forwarding-delay %.2fs",
           (float) EXTRACT_BE_U_2(stp_bpdu->message_age) / STP_TIME_BASE,
           (float) EXTRACT_BE_U_2(stp_bpdu->max_age) / STP_TIME_BASE,
           (float) EXTRACT_BE_U_2(stp_bpdu->hello_time) / STP_TIME_BASE,
           (float) EXTRACT_BE_U_2(stp_bpdu->forward_delay) / STP_TIME_BASE);

    ND_PRINT("\n\troot-id %s, root-pathcost %u",
           stp_print_bridge_id((const u_char *)&stp_bpdu->root_id),
           EXTRACT_BE_U_4(stp_bpdu->root_path_cost));

    /* Port role is only valid for 802.1w */
    if (EXTRACT_U_1(stp_bpdu->protocol_version) == STP_PROTO_RAPID) {
        ND_PRINT(", port-role %s",
               tok2str(rstp_obj_port_role_values, "Unknown",
                       RSTP_EXTRACT_PORT_ROLE(bpdu_flags)));
    }
    return 1;

trunc:
    return 0;
}
Exemple #18
0
/*
 * Print NTP control message requests and responses
 */
static void
ntp_control_print(netdissect_options *ndo,
		  const struct ntp_control_data *cd, u_int length)
{
	uint8_t control, R, E, M, opcode;
	uint16_t sequence, status, assoc, offset, count;

	if (length < NTP_CTRLMSG_MINLEN)
		goto invalid;

	ND_TCHECK_1(cd->control);
	control = EXTRACT_U_1(cd->control);
	R = (control & 0x80) != 0;
	E = (control & 0x40) != 0;
	M = (control & 0x20) != 0;
	opcode = control & 0x1f;
	ND_PRINT(", %s, %s, %s, OpCode=%u\n",
		  R ? "Response" : "Request", E ? "Error" : "OK",
		  M ? "More" : "Last", opcode);

	ND_TCHECK_2(cd->sequence);
	sequence = EXTRACT_BE_U_2(cd->sequence);
	ND_PRINT("\tSequence=%hu", sequence);

	ND_TCHECK_2(cd->status);
	status = EXTRACT_BE_U_2(cd->status);
	ND_PRINT(", Status=%#hx", status);

	ND_TCHECK_2(cd->assoc);
	assoc = EXTRACT_BE_U_2(cd->assoc);
	ND_PRINT(", Assoc.=%hu", assoc);

	ND_TCHECK_2(cd->offset);
	offset = EXTRACT_BE_U_2(cd->offset);
	ND_PRINT(", Offset=%hu", offset);

	ND_TCHECK_2(cd->count);
	count = EXTRACT_BE_U_2(cd->count);
	ND_PRINT(", Count=%hu", count);

	if (NTP_CTRLMSG_MINLEN + count > length)
		goto invalid;
	if (count != 0) {
		ND_TCHECK_LEN(cd->data, count);
		ND_PRINT("\n\tTO-BE-DONE: data not interpreted");
	}
	return;

invalid:
	nd_print_invalid(ndo);
	ND_TCHECK_LEN(cd, length);
	return;

trunc:
	nd_print_trunc(ndo);
}
Exemple #19
0
static void
pflog_print(netdissect_options *ndo, const struct pfloghdr *hdr)
{
	uint32_t rulenr, subrulenr;

	ndo->ndo_protocol = "pflog";
	rulenr = EXTRACT_BE_U_4(&hdr->rulenr);
	subrulenr = EXTRACT_BE_U_4(&hdr->subrulenr);
	if (subrulenr == (uint32_t)-1)
		ND_PRINT("rule %u/", rulenr);
	else
		ND_PRINT("rule %u.%s.%u/", rulenr, hdr->ruleset, subrulenr);

	ND_PRINT("%s: %s %s on %s: ",
	    tok2str(pf_reasons, "unkn(%u)", EXTRACT_U_1(&hdr->reason)),
	    tok2str(pf_actions, "unkn(%u)", EXTRACT_U_1(&hdr->action)),
	    tok2str(pf_directions, "unkn(%u)", EXTRACT_U_1(&hdr->dir)),
	    hdr->ifname);
}
Exemple #20
0
/* read in a <n>-byte number, MSB first
 * (of course this can handle max sizeof(int))
 */
static unsigned int cdp_get_number(const u_char * p, u_int l)
{
    unsigned int res=0;
    while( l>0 )
    {
	res = (res<<8) + EXTRACT_U_1(p);
	p++; l--;
    }
    return res;
}
Exemple #21
0
static u_int
dccp_csum_coverage(const struct dccp_hdr* dh, u_int len)
{
	u_int cov;

	if (DCCPH_CSCOV(dh) == 0)
		return len;
	cov = (EXTRACT_U_1(dh->dccph_doff) + DCCPH_CSCOV(dh) - 1) * sizeof(uint32_t);
	return (cov > len)? len : cov;
}
Exemple #22
0
static void
geneve_opts_print(netdissect_options *ndo, const u_char *bp, u_int len)
{
    const char *sep = "";

    while (len > 0) {
        uint16_t opt_class;
        uint8_t opt_type;
        uint8_t opt_len;

        ND_PRINT("%s", sep);
        sep = ", ";

        opt_class = EXTRACT_BE_U_2(bp);
        opt_type = EXTRACT_U_1(bp + 2);
        opt_len = 4 + ((EXTRACT_U_1(bp + 3) & OPT_LEN_MASK) * 4);

        ND_PRINT("class %s (0x%x) type 0x%x%s len %u",
                  format_opt_class(opt_class), opt_class, opt_type,
                  opt_type & OPT_TYPE_CRITICAL ? "(C)" : "", opt_len);

        if (opt_len > len) {
            ND_PRINT(" [bad length]");
            return;
        }

        if (ndo->ndo_vflag > 1 && opt_len > 4) {
            const uint32_t *data = (const uint32_t *)(bp + 4);
            int i;

            ND_PRINT(" data");

            for (i = 4; i < opt_len; i += 4) {
                ND_PRINT(" %08x", EXTRACT_BE_U_4(data));
                data++;
            }
        }

        bp += opt_len;
        len -= opt_len;
    }
}
Exemple #23
0
static char *
stp_print_bridge_id(const u_char *p)
{
    static char bridge_id_str[sizeof("pppp.aa:bb:cc:dd:ee:ff")];

    nd_snprintf(bridge_id_str, sizeof(bridge_id_str),
             "%.2x%.2x.%.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
             EXTRACT_U_1(p), EXTRACT_U_1(p + 1), EXTRACT_U_1(p + 2),
             EXTRACT_U_1(p + 3), EXTRACT_U_1(p + 4), EXTRACT_U_1(p + 5),
             EXTRACT_U_1(p + 6), EXTRACT_U_1(p + 7));

    return bridge_id_str;
}
Exemple #24
0
/* XXX should probably pass in the snap header and do checks like arp_print() */
void
aarp_print(netdissect_options *ndo,
           const u_char *bp, u_int length)
{
	const struct aarp *ap;

#define AT(member) ataddr_string(ndo, (ap->member[1]<<8)|ap->member[2],ap->member[3])

	ndo->ndo_protocol = "aarp";
	ND_PRINT("aarp ");
	ap = (const struct aarp *)bp;
	if (!ND_TTEST_SIZE(ap)) {
		/* Just bail if we don't have the whole chunk. */
		nd_print_trunc(ndo);
		return;
	}
	if (length < sizeof(*ap)) {
		ND_PRINT(" [|aarp %u]", length);
		return;
	}
	if (EXTRACT_BE_U_2(ap->htype) == 1 &&
	    EXTRACT_BE_U_2(ap->ptype) == ETHERTYPE_ATALK &&
	    EXTRACT_U_1(ap->halen) == 6 && EXTRACT_U_1(ap->palen) == 4 )
		switch (EXTRACT_BE_U_2(ap->op)) {

		case 1:				/* request */
			ND_PRINT("who-has %s tell %s", AT(pdaddr), AT(psaddr));
			return;

		case 2:				/* response */
			ND_PRINT("reply %s is-at %s", AT(psaddr), etheraddr_string(ndo, ap->hsaddr));
			return;

		case 3:				/* probe (oy!) */
			ND_PRINT("probe %s tell %s", AT(pdaddr), AT(psaddr));
			return;
		}
	ND_PRINT("len %u op %u htype %u ptype %#x halen %u palen %u",
	    length, EXTRACT_BE_U_2(ap->op), EXTRACT_BE_U_2(ap->htype),
	    EXTRACT_BE_U_2(ap->ptype), EXTRACT_U_1(ap->halen), EXTRACT_U_1(ap->palen));
}
Exemple #25
0
static void
ahcp1_options_print(netdissect_options *ndo, const u_char *cp, const u_char *ep)
{
	uint8_t option_no, option_len;

	while (cp < ep) {
		/* Option no */
		ND_TCHECK_1(cp);
		option_no = EXTRACT_U_1(cp);
		cp += 1;
		ND_PRINT("\n\t %s", tok2str(ahcp1_opt_str, "Unknown-%u", option_no));
		if (option_no == AHCP1_OPT_PAD || option_no == AHCP1_OPT_MANDATORY)
			continue;
		/* Length */
		if (cp + 1 > ep)
			goto invalid;
		ND_TCHECK_1(cp);
		option_len = EXTRACT_U_1(cp);
		cp += 1;
		if (cp + option_len > ep)
			goto invalid;
		/* Value */
		if (option_no <= AHCP1_OPT_MAX && data_decoders[option_no] != NULL) {
			if (data_decoders[option_no](ndo, cp, cp + option_len) < 0)
				break; /* truncated and already marked up */
		} else {
			ND_PRINT(" (Length %u)", option_len);
			ND_TCHECK_LEN(cp, option_len);
		}
		cp += option_len;
	}
	return;

invalid:
	ND_PRINT("%s", istr);
	ND_TCHECK_LEN(cp, ep - cp);
	return;
trunc:
	nd_print_trunc(ndo);
}
Exemple #26
0
/*
 * Print dhcp6 packets
 */
void
dhcp6_print(netdissect_options *ndo,
            const u_char *cp, u_int length)
{
	const struct dhcp6 *dh6;
	const struct dhcp6_relay *dh6relay;
	uint8_t msgtype;
	const u_char *ep;
	const u_char *extp;
	const char *name;

	ND_PRINT("dhcp6");

	ep = ndo->ndo_snapend;
	if (cp + length < ep)
		ep = cp + length;

	dh6 = (const struct dhcp6 *)cp;
	dh6relay = (const struct dhcp6_relay *)cp;
	ND_TCHECK_4(dh6->dh6_msgtypexid.xid);
	msgtype = EXTRACT_U_1(dh6->dh6_msgtypexid.msgtype);
	name = tok2str(dh6_msgtype_str, "msgtype-%u", msgtype);

	if (!ndo->ndo_vflag) {
		ND_PRINT(" %s", name);
		return;
	}

	/* XXX relay agent messages have to be handled differently */

	ND_PRINT(" %s (", name);	/*)*/
	if (msgtype != DH6_RELAY_FORW && msgtype != DH6_RELAY_REPLY) {
		ND_PRINT("xid=%x",
			 EXTRACT_BE_U_4(dh6->dh6_msgtypexid.xid) & DH6_XIDMASK);
		extp = (const u_char *)(dh6 + 1);
		dhcp6opt_print(ndo, extp, ep);
	} else {		/* relay messages */
		ND_TCHECK_16(dh6relay->dh6relay_peeraddr);

		ND_PRINT("linkaddr=%s", ip6addr_string(ndo, dh6relay->dh6relay_linkaddr));

		ND_PRINT(" peeraddr=%s", ip6addr_string(ndo, dh6relay->dh6relay_peeraddr));

		dhcp6opt_print(ndo, (const u_char *)(dh6relay + 1), ep);
	}
	/*(*/
	ND_PRINT(")");
	return;

trunc:
	ND_PRINT("[|dhcp6]");
}
Exemple #27
0
static int
cdp_print_prefixes(netdissect_options *ndo,
		   const u_char * p, u_int l)
{
	if (l % 5)
		goto trunc;

	ND_PRINT(" IPv4 Prefixes (%u):", l / 5);

	while (l > 0) {
		ND_PRINT(" %u.%u.%u.%u/%u",
			  EXTRACT_U_1(p), EXTRACT_U_1(p + 1), EXTRACT_U_1(p + 2),
			  EXTRACT_U_1(p + 3), EXTRACT_U_1(p + 4));
		l -= 5;
		p += 5;
	}

	return 0;

trunc:
	return -1;
}
Exemple #28
0
static int
cfm_network_addr_print(netdissect_options *ndo,
                       const u_char *tptr, const u_int length)
{
    u_int network_addr_type;
    u_int hexdump =  FALSE;

    /*
     * Although AFIs are typically 2 octects wide,
     * 802.1ab specifies that this field width
     * is only one octet.
     */
    if (length < 1) {
        ND_PRINT("\n\t  Network Address Type (invalid, no data");
        return hexdump;
    }
    /* The calling function must make any due ND_TCHECK calls. */
    network_addr_type = EXTRACT_U_1(tptr);
    ND_PRINT("\n\t  Network Address Type %s (%u)",
           tok2str(af_values, "Unknown", network_addr_type),
           network_addr_type);

    /*
     * Resolve the passed in Address.
     */
    switch(network_addr_type) {
    case AFNUM_INET:
        if (length != 1 + 4) {
            ND_PRINT("(invalid IPv4 address length %u)", length - 1);
            hexdump = TRUE;
            break;
        }
        ND_PRINT(", %s", ipaddr_string(ndo, tptr + 1));
        break;

    case AFNUM_INET6:
        if (length != 1 + 16) {
            ND_PRINT("(invalid IPv6 address length %u)", length - 1);
            hexdump = TRUE;
            break;
        }
        ND_PRINT(", %s", ip6addr_string(ndo, tptr + 1));
        break;

    default:
        hexdump = TRUE;
        break;
    }

    return hexdump;
}
Exemple #29
0
/*
 * Print RRCP requests
 */
void
rrcp_print(netdissect_options *ndo,
	  const u_char *cp,
	  u_int length _U_,
	  const struct lladdr_info *src,
	  const struct lladdr_info *dst)
{
	uint8_t rrcp_proto;
	uint8_t rrcp_opcode;

	ndo->ndo_protocol = "rrcp";
	ND_TCHECK_1(cp + RRCP_PROTO_OFFSET);
	rrcp_proto = EXTRACT_U_1(cp + RRCP_PROTO_OFFSET);
	ND_TCHECK_1(cp + RRCP_OPCODE_ISREPLY_OFFSET);
	rrcp_opcode = EXTRACT_U_1((cp + RRCP_OPCODE_ISREPLY_OFFSET)) & RRCP_OPCODE_MASK;
	if (src != NULL && dst != NULL) {
		ND_PRINT("%s > %s, ",
			(src->addr_string)(ndo, src->addr),
			(dst->addr_string)(ndo, dst->addr));
	}
	ND_PRINT("%s %s",
		tok2str(proto_values,"RRCP-0x%02x",rrcp_proto),
		((EXTRACT_U_1(cp + RRCP_OPCODE_ISREPLY_OFFSET)) & RRCP_ISREPLY) ? "reply" : "query");
	if (rrcp_proto==1){
    	    ND_PRINT(": %s",
		     tok2str(opcode_values,"unknown opcode (0x%02x)",rrcp_opcode));
	}
	if (rrcp_opcode==1 || rrcp_opcode==2){
	    ND_TCHECK_6(cp + RRCP_REG_ADDR_OFFSET);
    	    ND_PRINT(" addr=0x%04x, data=0x%08x",
		     EXTRACT_LE_U_2(cp + RRCP_REG_ADDR_OFFSET),
		     EXTRACT_LE_U_4(cp + RRCP_REG_DATA_OFFSET));
	}
	if (rrcp_proto==1){
	    ND_TCHECK_2(cp + RRCP_AUTHKEY_OFFSET);
    	    ND_PRINT(", auth=0x%04x",
		  EXTRACT_BE_U_2(cp + RRCP_AUTHKEY_OFFSET));
	}
	if (rrcp_proto==1 && rrcp_opcode==0 &&
	     ((EXTRACT_U_1(cp + RRCP_OPCODE_ISREPLY_OFFSET)) & RRCP_ISREPLY)){
	    ND_TCHECK_4(cp + RRCP_VENDOR_ID_OFFSET);
	    ND_PRINT(" downlink_port=%u, uplink_port=%u, uplink_mac=%s, vendor_id=%08x ,chip_id=%04x ",
		     EXTRACT_U_1(cp + RRCP_DOWNLINK_PORT_OFFSET),
		     EXTRACT_U_1(cp + RRCP_UPLINK_PORT_OFFSET),
		     etheraddr_string(ndo, cp + RRCP_UPLINK_MAC_OFFSET),
		     EXTRACT_BE_U_4(cp + RRCP_VENDOR_ID_OFFSET),
		     EXTRACT_BE_U_2(cp + RRCP_CHIP_ID_OFFSET));
	}else if (rrcp_opcode==1 || rrcp_opcode==2 || rrcp_proto==2){
	    ND_TCHECK_4(cp + RRCP_COOKIE2_OFFSET);
	    ND_PRINT(", cookie=0x%08x%08x ",
		    EXTRACT_BE_U_4(cp + RRCP_COOKIE2_OFFSET),
		    EXTRACT_BE_U_4(cp + RRCP_COOKIE1_OFFSET));
	}
	return;

trunc:
	nd_print_trunc(ndo);
}
Exemple #30
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(netdissect_options *ndo, 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 || length < ARC_LINUX_HDRLEN) {
		ND_PRINT("[|arcnet]");
		return (caplen);
	}

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

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

	if (ndo->ndo_eflag)
		arcnet_print(ndo, p, length, 0, 0, 0);

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

	if (!arcnet_encap_print(ndo, arc_type, p, length, caplen))
		ND_DEFAULTPRINT(p, caplen);

	return (archdrlen);
}