Example #1
0
/*
 * Print bootp requests
 */
void
bootp_print(netdissect_options *ndo,
	    register const u_char *cp, u_int length)
{
	register const struct bootp *bp;
	static const u_char vm_cmu[4] = VM_CMU;
	static const u_char vm_rfc1048[4] = VM_RFC1048;

	bp = (const struct bootp *)cp;
	ND_TCHECK(bp->bp_op);

	ND_PRINT((ndo, "BOOTP/DHCP, %s",
		  tok2str(bootp_op_values, "unknown (0x%02x)", bp->bp_op)));

	if (bp->bp_htype == 1 && bp->bp_hlen == 6 && bp->bp_op == BOOTPREQUEST) {
		ND_TCHECK2(bp->bp_chaddr[0], 6);
		ND_PRINT((ndo, " from %s", etheraddr_string(ndo, bp->bp_chaddr)));
	}

	ND_PRINT((ndo, ", length %u", length));

	if (!ndo->ndo_vflag)
		return;

	ND_TCHECK(bp->bp_secs);

	/* The usual hardware address type is 1 (10Mb Ethernet) */
	if (bp->bp_htype != 1)
		ND_PRINT((ndo, ", htype %d", bp->bp_htype));

	/* The usual length for 10Mb Ethernet address is 6 bytes */
	if (bp->bp_htype != 1 || bp->bp_hlen != 6)
		ND_PRINT((ndo, ", hlen %d", bp->bp_hlen));

	/* Only print interesting fields */
	if (bp->bp_hops)
		ND_PRINT((ndo, ", hops %d", bp->bp_hops));
	if (EXTRACT_32BITS(&bp->bp_xid))
		ND_PRINT((ndo, ", xid 0x%x", EXTRACT_32BITS(&bp->bp_xid)));
	if (EXTRACT_16BITS(&bp->bp_secs))
		ND_PRINT((ndo, ", secs %d", EXTRACT_16BITS(&bp->bp_secs)));

	ND_PRINT((ndo, ", Flags [%s]",
		  bittok2str(bootp_flag_values, "none", EXTRACT_16BITS(&bp->bp_flags))));
	if (ndo->ndo_vflag > 1)
		ND_PRINT((ndo, " (0x%04x)", EXTRACT_16BITS(&bp->bp_flags)));

	/* Client's ip address */
	ND_TCHECK(bp->bp_ciaddr);
	if (EXTRACT_32BITS(&bp->bp_ciaddr.s_addr))
		ND_PRINT((ndo, "\n\t  Client-IP %s", ipaddr_string(ndo, &bp->bp_ciaddr)));

	/* 'your' ip address (bootp client) */
	ND_TCHECK(bp->bp_yiaddr);
	if (EXTRACT_32BITS(&bp->bp_yiaddr.s_addr))
		ND_PRINT((ndo, "\n\t  Your-IP %s", ipaddr_string(ndo, &bp->bp_yiaddr)));

	/* Server's ip address */
	ND_TCHECK(bp->bp_siaddr);
	if (EXTRACT_32BITS(&bp->bp_siaddr.s_addr))
		ND_PRINT((ndo, "\n\t  Server-IP %s", ipaddr_string(ndo, &bp->bp_siaddr)));

	/* Gateway's ip address */
	ND_TCHECK(bp->bp_giaddr);
	if (EXTRACT_32BITS(&bp->bp_giaddr.s_addr))
		ND_PRINT((ndo, "\n\t  Gateway-IP %s", ipaddr_string(ndo, &bp->bp_giaddr)));

	/* Client's Ethernet address */
	if (bp->bp_htype == 1 && bp->bp_hlen == 6) {
		ND_TCHECK2(bp->bp_chaddr[0], 6);
		ND_PRINT((ndo, "\n\t  Client-Ethernet-Address %s", etheraddr_string(ndo, bp->bp_chaddr)));
	}

	ND_TCHECK2(bp->bp_sname[0], 1);		/* check first char only */
	if (*bp->bp_sname) {
		ND_PRINT((ndo, "\n\t  sname \""));
		if (fn_print(ndo, bp->bp_sname, ndo->ndo_snapend)) {
			ND_PRINT((ndo, "\""));
			ND_PRINT((ndo, "%s", tstr + 1));
			return;
		}
		ND_PRINT((ndo, "\""));
	}
	ND_TCHECK2(bp->bp_file[0], 1);		/* check first char only */
	if (*bp->bp_file) {
		ND_PRINT((ndo, "\n\t  file \""));
		if (fn_print(ndo, bp->bp_file, ndo->ndo_snapend)) {
			ND_PRINT((ndo, "\""));
			ND_PRINT((ndo, "%s", tstr + 1));
			return;
		}
		ND_PRINT((ndo, "\""));
	}

	/* Decode the vendor buffer */
	ND_TCHECK(bp->bp_vend[0]);
	if (memcmp((const char *)bp->bp_vend, vm_rfc1048,
		    sizeof(uint32_t)) == 0)
		rfc1048_print(ndo, bp->bp_vend);
	else if (memcmp((const char *)bp->bp_vend, vm_cmu,
			sizeof(uint32_t)) == 0)
		cmu_print(ndo, bp->bp_vend);
	else {
		uint32_t ul;

		ul = EXTRACT_32BITS(&bp->bp_vend);
		if (ul != 0)
			ND_PRINT((ndo, "\n\t  Vendor-#0x%x", ul));
	}

	return;
trunc:
	ND_PRINT((ndo, "%s", tstr));
}
Example #2
0
static void
pptp_hostname_print(netdissect_options *ndo,
                    const u_char *hostname)
{
	ND_PRINT(" HOSTNAME(%.64s)", hostname);
}
Example #3
0
static void
pptp_max_channel_print(netdissect_options *ndo,
                       const nd_uint16_t *max_channel)
{
	ND_PRINT(" MAX_CHAN(%u)", EXTRACT_BE_U_2(*max_channel));
}
Example #4
0
static void
pptp_call_ser_print(netdissect_options *ndo,
                    const nd_uint16_t *call_ser)
{
	ND_PRINT(" CALL_SER_NUM(%u)", EXTRACT_BE_U_2(*call_ser));
}
Example #5
0
static void
pptp_conn_speed_print(netdissect_options *ndo,
                      const nd_uint32_t *conn_speed)
{
	ND_PRINT(" CONN_SPEED(%u)", EXTRACT_BE_U_4(*conn_speed));
}
static void
print_trans2(netdissect_options *ndo,
             const u_char *words, const u_char *dat, const u_char *buf, const u_char *maxbuf)
{
    u_int bcc;
    static const struct smbfnsint *fn = &trans2_fns[0];
    const u_char *data, *param;
    const u_char *w = words + 1;
    const char *f1 = NULL, *f2 = NULL;
    int pcnt, dcnt;

    ND_TCHECK(words[0]);
    if (request) {
	ND_TCHECK2(w[14 * 2], 2);
	pcnt = EXTRACT_LE_16BITS(w + 9 * 2);
	param = buf + EXTRACT_LE_16BITS(w + 10 * 2);
	dcnt = EXTRACT_LE_16BITS(w + 11 * 2);
	data = buf + EXTRACT_LE_16BITS(w + 12 * 2);
	fn = smbfindint(EXTRACT_LE_16BITS(w + 14 * 2), trans2_fns);
    } else {
	if (words[0] == 0) {
	    ND_PRINT((ndo, "%s\n", fn->name));
	    ND_PRINT((ndo, "Trans2Interim\n"));
	    return;
	}
	ND_TCHECK2(w[7 * 2], 2);
	pcnt = EXTRACT_LE_16BITS(w + 3 * 2);
	param = buf + EXTRACT_LE_16BITS(w + 4 * 2);
	dcnt = EXTRACT_LE_16BITS(w + 6 * 2);
	data = buf + EXTRACT_LE_16BITS(w + 7 * 2);
    }

    ND_PRINT((ndo, "%s param_length=%d data_length=%d\n", fn->name, pcnt, dcnt));

    if (request) {
	if (words[0] == 8) {
	    smb_fdata(ndo, words + 1,
		"Trans2Secondary\nTotParam=[d]\nTotData=[d]\nParamCnt=[d]\nParamOff=[d]\nParamDisp=[d]\nDataCnt=[d]\nDataOff=[d]\nDataDisp=[d]\nHandle=[d]\n",
		maxbuf, unicodestr);
	    return;
	} else {
	    smb_fdata(ndo, words + 1,
		"TotParam=[d]\nTotData=[d]\nMaxParam=[d]\nMaxData=[d]\nMaxSetup=[b][P1]\nFlags=[w]\nTimeOut=[D]\nRes1=[w]\nParamCnt=[d]\nParamOff=[d]\nDataCnt=[d]\nDataOff=[d]\nSetupCnt=[b][P1]\n",
		words + 1 + 14 * 2, unicodestr);
	}
	f1 = fn->descript.req_f1;
	f2 = fn->descript.req_f2;
    } else {
	smb_fdata(ndo, words + 1,
	    "TotParam=[d]\nTotData=[d]\nRes1=[w]\nParamCnt=[d]\nParamOff=[d]\nParamDisp[d]\nDataCnt=[d]\nDataOff=[d]\nDataDisp=[d]\nSetupCnt=[b][P1]\n",
	    words + 1 + 10 * 2, unicodestr);
	f1 = fn->descript.rep_f1;
	f2 = fn->descript.rep_f2;
    }

    ND_TCHECK2(*dat, 2);
    bcc = EXTRACT_LE_16BITS(dat);
    ND_PRINT((ndo, "smb_bcc=%u\n", bcc));
    if (fn->descript.fn)
	(*fn->descript.fn)(ndo, param, data, pcnt, dcnt);
    else {
	smb_fdata(ndo, param, f1 ? f1 : "Parameters=\n", param + pcnt, unicodestr);
	smb_fdata(ndo, data, f2 ? f2 : "Data=\n", data + dcnt, unicodestr);
    }
    return;
trunc:
    ND_PRINT((ndo, "%s", tstr));
}
Example #7
0
static void
chdlc_slarp_print(netdissect_options *ndo, const u_char *cp, u_int length)
{
	const struct cisco_slarp *slarp;
        u_int sec,min,hrs,days;

	ND_PRINT((ndo, "SLARP (length: %u), ",length));
	if (length < SLARP_MIN_LEN)
		goto trunc;

	slarp = (const struct cisco_slarp *)cp;
	ND_TCHECK2(*slarp, SLARP_MIN_LEN);
	switch (EXTRACT_32BITS(&slarp->code)) {
	case SLARP_REQUEST:
		ND_PRINT((ndo, "request"));
		/*
		 * At least according to William "Chops" Westfield's
		 * message in
		 *
		 *	http://www.nethelp.no/net/cisco-hdlc.txt
		 *
		 * the address and mask aren't used in requests -
		 * they're just zero.
		 */
		break;
	case SLARP_REPLY:
		ND_PRINT((ndo, "reply %s/%s",
			ipaddr_string(ndo, &slarp->un.addr.addr),
			ipaddr_string(ndo, &slarp->un.addr.mask)));
		break;
	case SLARP_KEEPALIVE:
		ND_PRINT((ndo, "keepalive: mineseen=0x%08x, yourseen=0x%08x, reliability=0x%04x",
                       EXTRACT_32BITS(&slarp->un.keep.myseq),
                       EXTRACT_32BITS(&slarp->un.keep.yourseq),
                       EXTRACT_16BITS(&slarp->un.keep.rel)));

                if (length >= SLARP_MAX_LEN) { /* uptime-stamp is optional */
                        cp += SLARP_MIN_LEN;
                        ND_TCHECK2(*cp, 4);
                        sec = EXTRACT_32BITS(cp) / 1000;
                        min = sec / 60; sec -= min * 60;
                        hrs = min / 60; min -= hrs * 60;
                        days = hrs / 24; hrs -= days * 24;
                        ND_PRINT((ndo, ", link uptime=%ud%uh%um%us",days,hrs,min,sec));
                }
		break;
	default:
		ND_PRINT((ndo, "0x%02x unknown", EXTRACT_32BITS(&slarp->code)));
                if (ndo->ndo_vflag <= 1)
                    print_unknown_data(ndo,cp+4,"\n\t",length-4);
		break;
	}

	if (SLARP_MAX_LEN < length && ndo->ndo_vflag)
		ND_PRINT((ndo, ", (trailing junk: %d bytes)", length - SLARP_MAX_LEN));
        if (ndo->ndo_vflag > 1)
            print_unknown_data(ndo,cp+4,"\n\t",length-4);
	return;

trunc:
	ND_PRINT((ndo, "[|slarp]"));
}
Example #8
0
static void
slow_oam_print(netdissect_options *ndo,
               const u_char *tptr, u_int tlen)
{
    uint8_t code;
    uint8_t type, length;
    uint8_t state;
    uint8_t command;
    u_int hexdump;

    struct slow_oam_common_header_t {
        nd_uint16_t flags;
        nd_uint8_t code;
    };

    struct slow_oam_tlv_header_t {
        nd_uint8_t type;
        nd_uint8_t length;
    };

    union {
        const struct slow_oam_common_header_t *slow_oam_common_header;
        const struct slow_oam_tlv_header_t *slow_oam_tlv_header;
    } ptr;

    union {
	const struct slow_oam_info_t *slow_oam_info;
        const struct slow_oam_link_event_t *slow_oam_link_event;
        const struct slow_oam_variablerequest_t *slow_oam_variablerequest;
        const struct slow_oam_variableresponse_t *slow_oam_variableresponse;
        const struct slow_oam_loopbackctrl_t *slow_oam_loopbackctrl;
    } tlv;

    ptr.slow_oam_common_header = (const struct slow_oam_common_header_t *)tptr;
    if (tlen < sizeof(*ptr.slow_oam_common_header))
        goto tooshort;
    ND_TCHECK_SIZE(ptr.slow_oam_common_header);
    tptr += sizeof(struct slow_oam_common_header_t);
    tlen -= sizeof(struct slow_oam_common_header_t);

    code = EXTRACT_U_1(ptr.slow_oam_common_header->code);
    ND_PRINT("\n\tCode %s OAM PDU, Flags [%s]",
           tok2str(slow_oam_code_values, "Unknown (%u)", code),
           bittok2str(slow_oam_flag_values,
                      "none",
                      EXTRACT_BE_U_2(ptr.slow_oam_common_header->flags)));

    switch (code) {
    case SLOW_OAM_CODE_INFO:
        while (tlen > 0) {
            ptr.slow_oam_tlv_header = (const struct slow_oam_tlv_header_t *)tptr;
            if (tlen < sizeof(*ptr.slow_oam_tlv_header))
                goto tooshort;
            ND_TCHECK_SIZE(ptr.slow_oam_tlv_header);
            type = EXTRACT_U_1(ptr.slow_oam_tlv_header->type);
            length = EXTRACT_U_1(ptr.slow_oam_tlv_header->length);
            ND_PRINT("\n\t  %s Information Type (%u), length %u",
                   tok2str(slow_oam_info_type_values, "Reserved", type),
                   type,
                   length);

            if (type == SLOW_OAM_INFO_TYPE_END_OF_TLV) {
                /*
                 * As IEEE Std 802.3-2015 says for the End of TLV Marker,
                 * "(the length and value of the Type 0x00 TLV can be ignored)".
                 */
                return;
            }

            /* length includes the type and length fields */
            if (length < sizeof(struct slow_oam_tlv_header_t)) {
                ND_PRINT("\n\t    ERROR: illegal length - should be >= %u",
                       (u_int)sizeof(struct slow_oam_tlv_header_t));
                return;
            }

            if (tlen < length)
                goto tooshort;
            ND_TCHECK_LEN(tptr, length);

            hexdump = FALSE;
            switch (type) {
            case SLOW_OAM_INFO_TYPE_LOCAL: /* identical format - fall through */
            case SLOW_OAM_INFO_TYPE_REMOTE:
                tlv.slow_oam_info = (const struct slow_oam_info_t *)tptr;

                if (EXTRACT_U_1(tlv.slow_oam_info->info_length) !=
                    sizeof(struct slow_oam_info_t)) {
                    ND_PRINT("\n\t    ERROR: illegal length - should be %lu",
                           (unsigned long) sizeof(struct slow_oam_info_t));
                    hexdump = TRUE;
                    goto badlength_code_info;
                }

                ND_PRINT("\n\t    OAM-Version %u, Revision %u",
                       EXTRACT_U_1(tlv.slow_oam_info->oam_version),
                       EXTRACT_BE_U_2(tlv.slow_oam_info->revision));

                state = EXTRACT_U_1(tlv.slow_oam_info->state);
                ND_PRINT("\n\t    State-Parser-Action %s, State-MUX-Action %s",
                       tok2str(slow_oam_info_type_state_parser_values, "Reserved",
                               state & OAM_INFO_TYPE_PARSER_MASK),
                       tok2str(slow_oam_info_type_state_mux_values, "Reserved",
                               state & OAM_INFO_TYPE_MUX_MASK));
                ND_PRINT("\n\t    OAM-Config Flags [%s], OAM-PDU-Config max-PDU size %u",
                       bittok2str(slow_oam_info_type_oam_config_values, "none",
                                  EXTRACT_U_1(tlv.slow_oam_info->oam_config)),
                       EXTRACT_BE_U_2(tlv.slow_oam_info->oam_pdu_config) &
                       OAM_INFO_TYPE_PDU_SIZE_MASK);
                ND_PRINT("\n\t    OUI %s (0x%06x), Vendor-Private 0x%08x",
                       tok2str(oui_values, "Unknown",
                               EXTRACT_BE_U_3(tlv.slow_oam_info->oui)),
                       EXTRACT_BE_U_3(tlv.slow_oam_info->oui),
                       EXTRACT_BE_U_4(tlv.slow_oam_info->vendor_private));
                break;

            case SLOW_OAM_INFO_TYPE_ORG_SPECIFIC:
                hexdump = TRUE;
                break;

            default:
                hexdump = TRUE;
                break;
            }

        badlength_code_info:
            /* do we also want to see a hex dump ? */
            if (ndo->ndo_vflag > 1 || hexdump==TRUE) {
                print_unknown_data(ndo, tptr, "\n\t  ",
                                   length);
            }

            tlen -= length;
            tptr += length;
        }
        break;

    case SLOW_OAM_CODE_EVENT_NOTIF:
        /* Sequence number */
        if (tlen < 2)
            goto tooshort;
        ND_TCHECK_2(tptr);
        ND_PRINT("\n\t  Sequence Number %u", EXTRACT_BE_U_2(tptr));
        tlen -= 2;
        tptr += 2;

        /* TLVs */
        while (tlen > 0) {
            ptr.slow_oam_tlv_header = (const struct slow_oam_tlv_header_t *)tptr;
            if (tlen < sizeof(*ptr.slow_oam_tlv_header))
                goto tooshort;
            ND_TCHECK_SIZE(ptr.slow_oam_tlv_header);
            type = EXTRACT_U_1(ptr.slow_oam_tlv_header->type);
            length = EXTRACT_U_1(ptr.slow_oam_tlv_header->length);
            ND_PRINT("\n\t  %s Link Event Type (%u), length %u",
                   tok2str(slow_oam_link_event_values, "Reserved",
                           type),
                   type,
                   length);

            if (type == SLOW_OAM_INFO_TYPE_END_OF_TLV) {
                /*
                 * As IEEE Std 802.3-2015 says for the End of TLV Marker,
                 * "(the length and value of the Type 0x00 TLV can be ignored)".
                 */
                return;
            }

            /* length includes the type and length fields */
            if (length < sizeof(struct slow_oam_tlv_header_t)) {
                ND_PRINT("\n\t    ERROR: illegal length - should be >= %u",
                       (u_int)sizeof(struct slow_oam_tlv_header_t));
                return;
            }

            if (tlen < length)
                goto tooshort;
            ND_TCHECK_LEN(tptr, length);

            hexdump = FALSE;
            switch (type) {
            case SLOW_OAM_LINK_EVENT_ERR_SYM_PER: /* identical format - fall through */
            case SLOW_OAM_LINK_EVENT_ERR_FRM:
            case SLOW_OAM_LINK_EVENT_ERR_FRM_PER:
            case SLOW_OAM_LINK_EVENT_ERR_FRM_SUMM:
                tlv.slow_oam_link_event = (const struct slow_oam_link_event_t *)tptr;

                if (EXTRACT_U_1(tlv.slow_oam_link_event->event_length) !=
                    sizeof(struct slow_oam_link_event_t)) {
                    ND_PRINT("\n\t    ERROR: illegal length - should be %lu",
                           (unsigned long) sizeof(struct slow_oam_link_event_t));
                    hexdump = TRUE;
                    goto badlength_event_notif;
                }

                ND_PRINT("\n\t    Timestamp %u ms, Errored Window %" PRIu64
                       "\n\t    Errored Threshold %" PRIu64
                       "\n\t    Errors %" PRIu64
                       "\n\t    Error Running Total %" PRIu64
                       "\n\t    Event Running Total %u",
                       EXTRACT_BE_U_2(tlv.slow_oam_link_event->time_stamp)*100,
                       EXTRACT_BE_U_8(tlv.slow_oam_link_event->window),
                       EXTRACT_BE_U_8(tlv.slow_oam_link_event->threshold),
                       EXTRACT_BE_U_8(tlv.slow_oam_link_event->errors),
                       EXTRACT_BE_U_8(tlv.slow_oam_link_event->errors_running_total),
                       EXTRACT_BE_U_4(tlv.slow_oam_link_event->event_running_total));
                break;

            case SLOW_OAM_LINK_EVENT_ORG_SPECIFIC:
                hexdump = TRUE;
                break;

            default:
                hexdump = TRUE;
                break;
            }

        badlength_event_notif:
            /* do we also want to see a hex dump ? */
            if (ndo->ndo_vflag > 1 || hexdump==TRUE) {
                print_unknown_data(ndo, tptr, "\n\t  ",
                                   length);
            }

            tlen -= length;
            tptr += length;
        }
        break;

    case SLOW_OAM_CODE_LOOPBACK_CTRL:
        tlv.slow_oam_loopbackctrl = (const struct slow_oam_loopbackctrl_t *)tptr;
        if (tlen < sizeof(*tlv.slow_oam_loopbackctrl))
            goto tooshort;
        ND_TCHECK_SIZE(tlv.slow_oam_loopbackctrl);
        command = EXTRACT_U_1(tlv.slow_oam_loopbackctrl->command);
        ND_PRINT("\n\t  Command %s (%u)",
               tok2str(slow_oam_loopbackctrl_cmd_values,
                       "Unknown",
                       command),
               command);
        tptr ++;
        tlen --;
        break;

        /*
         * FIXME those are the defined codes that lack a decoder
         * you are welcome to contribute code ;-)
         */
    case SLOW_OAM_CODE_VAR_REQUEST:
    case SLOW_OAM_CODE_VAR_RESPONSE:
    case SLOW_OAM_CODE_PRIVATE:
    default:
        if (ndo->ndo_vflag <= 1) {
            print_unknown_data(ndo, tptr, "\n\t  ", tlen);
        }
        break;
    }
    return;

tooshort:
    ND_PRINT("\n\t\t packet is too short");
    return;

trunc:
    ND_PRINT("%s", tstr);
}
Example #9
0
/*
 * RFC3032: MPLS label stack encoding
 */
void
mpls_print(netdissect_options *ndo, const u_char *bp, u_int length)
{
	const u_char *p;
	uint32_t label_entry;
	uint16_t label_stack_depth = 0;
	enum mpls_packet_type pt = PT_UNKNOWN;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	default:
		break;
	}
	return;

trunc:
	ND_PRINT((ndo, "[|MPLS]"));
}
Example #10
0
void
slow_print(netdissect_options *ndo,
           const u_char *pptr, u_int len)
{
    int print_version;
    u_int subtype;

    ndo->ndo_protocol = "slow";
    if (len < 1)
        goto tooshort;
    ND_TCHECK_1(pptr);
    subtype = EXTRACT_U_1(pptr);

    /*
     * Sanity checking of the header.
     */
    switch (subtype) {
    case SLOW_PROTO_LACP:
        if (len < 2)
            goto tooshort;
        ND_TCHECK_1(pptr + 1);
        if (EXTRACT_U_1(pptr + 1) != LACP_VERSION) {
            ND_PRINT("LACP version %u packet not supported", EXTRACT_U_1(pptr + 1));
            return;
        }
        print_version = 1;
        break;

    case SLOW_PROTO_MARKER:
        if (len < 2)
            goto tooshort;
        ND_TCHECK_1(pptr + 1);
        if (EXTRACT_U_1(pptr + 1) != MARKER_VERSION) {
            ND_PRINT("MARKER version %u packet not supported", EXTRACT_U_1(pptr + 1));
            return;
        }
        print_version = 1;
        break;

    case SLOW_PROTO_OAM: /* fall through */
        print_version = 0;
        break;

    default:
        /* print basic information and exit */
        print_version = -1;
        break;
    }

    if (print_version == 1) {
        ND_PRINT("%sv%u, length %u",
               tok2str(slow_proto_values, "unknown (%u)", subtype),
               EXTRACT_U_1((pptr + 1)),
               len);
    } else {
        /* some slow protos don't have a version number in the header */
        ND_PRINT("%s, length %u",
               tok2str(slow_proto_values, "unknown (%u)", subtype),
               len);
    }

    /* unrecognized subtype */
    if (print_version == -1) {
        print_unknown_data(ndo, pptr, "\n\t", len);
        return;
    }

    if (!ndo->ndo_vflag)
        return;

    switch (subtype) {
    default: /* should not happen */
        break;

    case SLOW_PROTO_OAM:
        /* skip subtype */
        len -= 1;
        pptr += 1;
        slow_oam_print(ndo, pptr, len);
        break;

    case SLOW_PROTO_LACP:   /* LACP and MARKER share the same semantics */
    case SLOW_PROTO_MARKER:
        /* skip subtype and version */
        len -= 2;
        pptr += 2;
        slow_marker_lacp_print(ndo, pptr, len, subtype);
        break;
    }
    return;

tooshort:
    if (!ndo->ndo_vflag)
        ND_PRINT(" (packet is too short)");
    else
        ND_PRINT("\n\t\t packet is too short");
    return;

trunc:
    ND_PRINT("%s", tstr);
}
Example #11
0
static void
slow_marker_lacp_print(netdissect_options *ndo,
                       const u_char *tptr, u_int tlen,
                       u_int proto_subtype)
{
    const struct tlv_header_t *tlv_header;
    const u_char *tlv_tptr;
    u_int tlv_type, tlv_len, tlv_tlen;

    union {
        const struct lacp_marker_tlv_terminator_t *lacp_marker_tlv_terminator;
        const struct lacp_tlv_actor_partner_info_t *lacp_tlv_actor_partner_info;
        const struct lacp_tlv_collector_info_t *lacp_tlv_collector_info;
        const struct marker_tlv_marker_info_t *marker_tlv_marker_info;
    } tlv_ptr;

    while(tlen>0) {
        /* is the packet big enough to include the tlv header ? */
        if (tlen < sizeof(struct tlv_header_t))
            goto tooshort;
        /* did we capture enough for fully decoding the tlv header ? */
        ND_TCHECK_LEN(tptr, sizeof(struct tlv_header_t));
        tlv_header = (const struct tlv_header_t *)tptr;
        tlv_type = EXTRACT_U_1(tlv_header->type);
        tlv_len = EXTRACT_U_1(tlv_header->length);

        ND_PRINT("\n\t%s TLV (0x%02x), length %u",
               tok2str(slow_tlv_values,
                       "Unknown",
                       (proto_subtype << 8) + tlv_type),
               tlv_type,
               tlv_len);

        if (tlv_type == LACP_MARKER_TLV_TERMINATOR) {
            /*
             * This TLV has a length of zero, and means there are no
             * more TLVs to process.
             */
            return;
        }

        /* length includes the type and length fields */
        if (tlv_len < sizeof(struct tlv_header_t)) {
            ND_PRINT("\n\t    ERROR: illegal length - should be >= %lu",
                   (unsigned long) sizeof(struct tlv_header_t));
            return;
        }

        /* is the packet big enough to include the tlv ? */
        if (tlen < tlv_len)
            goto tooshort;
        /* did we capture enough for fully decoding the tlv ? */
        ND_TCHECK_LEN(tptr, tlv_len);

        tlv_tptr=tptr+sizeof(struct tlv_header_t);
        tlv_tlen=tlv_len-sizeof(struct tlv_header_t);

        switch((proto_subtype << 8) + tlv_type) {

            /* those two TLVs have the same structure -> fall through */
        case ((SLOW_PROTO_LACP << 8) + LACP_TLV_ACTOR_INFO):
        case ((SLOW_PROTO_LACP << 8) + LACP_TLV_PARTNER_INFO):
            if (tlv_tlen !=
                sizeof(struct lacp_tlv_actor_partner_info_t)) {
                ND_PRINT("\n\t    ERROR: illegal length - should be %lu",
                       (unsigned long) (sizeof(struct tlv_header_t) + sizeof(struct lacp_tlv_actor_partner_info_t)));
                goto badlength;
            }

            tlv_ptr.lacp_tlv_actor_partner_info = (const struct lacp_tlv_actor_partner_info_t *)tlv_tptr;

            ND_PRINT("\n\t  System %s, System Priority %u, Key %u"
                   ", Port %u, Port Priority %u\n\t  State Flags [%s]",
                   etheraddr_string(ndo, tlv_ptr.lacp_tlv_actor_partner_info->sys),
                   EXTRACT_BE_U_2(tlv_ptr.lacp_tlv_actor_partner_info->sys_pri),
                   EXTRACT_BE_U_2(tlv_ptr.lacp_tlv_actor_partner_info->key),
                   EXTRACT_BE_U_2(tlv_ptr.lacp_tlv_actor_partner_info->port),
                   EXTRACT_BE_U_2(tlv_ptr.lacp_tlv_actor_partner_info->port_pri),
                   bittok2str(lacp_tlv_actor_partner_info_state_values,
                              "none",
                              EXTRACT_U_1(tlv_ptr.lacp_tlv_actor_partner_info->state)));

            break;

        case ((SLOW_PROTO_LACP << 8) + LACP_TLV_COLLECTOR_INFO):
            if (tlv_tlen !=
                sizeof(struct lacp_tlv_collector_info_t)) {
                ND_PRINT("\n\t    ERROR: illegal length - should be %lu",
                       (unsigned long) (sizeof(struct tlv_header_t) + sizeof(struct lacp_tlv_collector_info_t)));
                goto badlength;
            }

            tlv_ptr.lacp_tlv_collector_info = (const struct lacp_tlv_collector_info_t *)tlv_tptr;

            ND_PRINT("\n\t  Max Delay %u",
                   EXTRACT_BE_U_2(tlv_ptr.lacp_tlv_collector_info->max_delay));

            break;

        case ((SLOW_PROTO_MARKER << 8) + MARKER_TLV_MARKER_INFO):
            if (tlv_tlen !=
                sizeof(struct marker_tlv_marker_info_t)) {
                ND_PRINT("\n\t    ERROR: illegal length - should be %lu",
                       (unsigned long) (sizeof(struct tlv_header_t) + sizeof(struct marker_tlv_marker_info_t)));
                goto badlength;
            }

            tlv_ptr.marker_tlv_marker_info = (const struct marker_tlv_marker_info_t *)tlv_tptr;

            ND_PRINT("\n\t  Request System %s, Request Port %u, Request Transaction ID 0x%08x",
                   etheraddr_string(ndo, tlv_ptr.marker_tlv_marker_info->req_sys),
                   EXTRACT_BE_U_2(tlv_ptr.marker_tlv_marker_info->req_port),
                   EXTRACT_BE_U_4(tlv_ptr.marker_tlv_marker_info->req_trans_id));

            break;

        default:
            if (ndo->ndo_vflag <= 1)
                print_unknown_data(ndo, tlv_tptr, "\n\t  ", tlv_tlen);
            break;
        }

    badlength:
        /* do we want to see an additional hexdump ? */
        if (ndo->ndo_vflag > 1) {
            print_unknown_data(ndo, tptr+sizeof(struct tlv_header_t), "\n\t  ",
                               tlv_len-sizeof(struct tlv_header_t));
        }

        tptr+=tlv_len;
        tlen-=tlv_len;
    }
    return;

tooshort:
    ND_PRINT("\n\t\t packet is too short");
    return;

trunc:
    ND_PRINT("%s", tstr);
}
Example #12
0
static void
print_internal(netdissect_options *ndo, const struct internal_tipc_pkthdr *ap)
{
	u_int32_t w0, w1, w2, w4, w5, w9;
	u_int user;
	u_int hsize;
	u_int msize;
	u_int mtype;
	u_int seq_gap;
	u_int broadcast_ack;
	u_int bc_gap_after;
	u_int bc_gap_to;
	u_int prev_node;
	u_int last_sent_frag;
	u_int next_sent_frag;
	u_int sess_no;
	u_int orig_node;
	u_int dest_node;
	u_int trans_seq;
	u_int msg_cnt;
	u_int link_tol;

	ND_TCHECK(ap->dest_node);
	w0 = EXTRACT_32BITS(&ap->w0);
	user = TIPC_USER(w0);
	hsize = TIPC_HSIZE(w0);
	msize = TIPC_MSIZE(w0);
	w1 = EXTRACT_32BITS(&ap->w1);
	mtype = TIPC_MTYPE(w1);
	orig_node = EXTRACT_32BITS(&ap->orig_node);
	dest_node = EXTRACT_32BITS(&ap->dest_node);
	ND_PRINT((ndo, "TIPC v%u.0 %u.%u.%u > %u.%u.%u, headerlength %u bytes, MessageSize %u bytes, %s, messageType %s (0x%08x)",
	    TIPC_VER(w0),
	    TIPC_ZONE(orig_node), TIPC_CLUSTER(orig_node), TIPC_NODE(orig_node),
	    TIPC_ZONE(dest_node), TIPC_CLUSTER(dest_node), TIPC_NODE(dest_node),
	    hsize*4, msize,
	    tok2str(tipcuser_values, "unknown", user),
	    tok2str(tipcmtype_values, "Unknown", mtype), w1));

	if (ndo->ndo_vflag) {
		ND_TCHECK(*ap);
		seq_gap = TIPC_SEQ_GAP(w1);
		broadcast_ack = TIPC_BROADCAST_ACK(w1);
		w2 = EXTRACT_32BITS(&ap->w2);
		bc_gap_after = TIPC_BC_GAP_AFTER(w2);
		bc_gap_to = TIPC_BC_GAP_TO(w2);
		prev_node = EXTRACT_32BITS(&ap->prev_node);
		w4 = EXTRACT_32BITS(&ap->w4);
		last_sent_frag = TIPC_LAST_SENT_FRAG(w4);
		next_sent_frag = TIPC_NEXT_SENT_FRAG(w4);
		w5 = EXTRACT_32BITS(&ap->w5);
		sess_no = TIPC_SESS_NO(w5);
		trans_seq = EXTRACT_32BITS(&ap->trans_seq);
		w9 = EXTRACT_32BITS(&ap->w9);
		msg_cnt = TIPC_MSG_CNT(w9);
		link_tol = TIPC_LINK_TOL(w9);
		ND_PRINT((ndo, "\n\tPrevious Node %u.%u.%u, Session No. %u, Broadcast Ack %u, Sequence Gap %u,  Broadcast Gap After %u, Broadcast Gap To %u, Last Sent Packet No. %u, Next sent Packet No. %u, Transport Sequence %u, msg_count %u, Link Tolerance %u",
		    TIPC_ZONE(prev_node), TIPC_CLUSTER(prev_node), TIPC_NODE(prev_node),
		    sess_no, broadcast_ack, seq_gap, bc_gap_after, bc_gap_to,
		    last_sent_frag, next_sent_frag, trans_seq, msg_cnt,
		    link_tol));
	}
	return;

trunc:
	ND_PRINT((ndo, "[|TIPC]"));
}
Example #13
0
static void
print_payload(netdissect_options *ndo, const struct payload_tipc_pkthdr *ap)
{
	u_int32_t w0, w1, w2;
	u_int user;
	u_int hsize;
	u_int msize;
	u_int mtype;
	u_int broadcast_ack;
	u_int link_ack;
	u_int link_seq;
	u_int prev_node;
	u_int orig_port;
	u_int dest_port;
	u_int orig_node;
	u_int dest_node;

	ND_TCHECK(ap->dest_port);
	w0 = EXTRACT_32BITS(&ap->w0);
	user = TIPC_USER(w0);
	hsize = TIPC_HSIZE(w0);
	msize = TIPC_MSIZE(w0);
	w1 = EXTRACT_32BITS(&ap->w1);
	mtype = TIPC_MTYPE(w1);
	prev_node = EXTRACT_32BITS(&ap->prev_node);
	orig_port = EXTRACT_32BITS(&ap->orig_port);
	dest_port = EXTRACT_32BITS(&ap->dest_port);
	if (hsize <= 6) {
		ND_PRINT((ndo, "TIPC v%u.0 %u.%u.%u:%u > %u, headerlength %u bytes, MessageSize %u bytes, %s, messageType %s",
		    TIPC_VER(w0),
		    TIPC_ZONE(prev_node), TIPC_CLUSTER(prev_node), TIPC_NODE(prev_node),
		    orig_port, dest_port,
		    hsize*4, msize,
		    tok2str(tipcuser_values, "unknown", user),
		    tok2str(tipcmtype_values, "Unknown", mtype)));
	} else {
		ND_TCHECK(ap->dest_node);
		orig_node = EXTRACT_32BITS(&ap->orig_node);
		dest_node = EXTRACT_32BITS(&ap->dest_node);
		ND_PRINT((ndo, "TIPC v%u.0 %u.%u.%u:%u > %u.%u.%u:%u, headerlength %u bytes, MessageSize %u bytes, %s, messageType %s",
		    TIPC_VER(w0),
		    TIPC_ZONE(orig_node), TIPC_CLUSTER(orig_node), TIPC_NODE(orig_node),
		    orig_port,
		    TIPC_ZONE(dest_node), TIPC_CLUSTER(dest_node), TIPC_NODE(dest_node),
		    dest_port,
		    hsize*4, msize,
		    tok2str(tipcuser_values, "unknown", user),
		    tok2str(tipcmtype_values, "Unknown", mtype)));

		if (ndo->ndo_vflag) {
			broadcast_ack = TIPC_BROADCAST_ACK(w1);
			w2 = EXTRACT_32BITS(&ap->w2);
			link_ack = TIPC_LINK_ACK(w2);
			link_seq = TIPC_LINK_SEQ(w2);
			ND_PRINT((ndo, "\n\tPrevious Node %u.%u.%u, Broadcast Ack %u, Link Ack %u, Link Sequence %u",
			    TIPC_ZONE(prev_node), TIPC_CLUSTER(prev_node), TIPC_NODE(prev_node),
			    broadcast_ack, link_ack, link_seq));
		}
	}
	return;

trunc:
	ND_PRINT((ndo, "[|TIPC]"));
}
Example #14
0
static void
rfc1048_print(netdissect_options *ndo,
	      register const u_char *bp)
{
	register uint16_t tag;
	register u_int len;
	register const char *cp;
	register char c;
	int first, idx;
	uint32_t ul;
	uint16_t us;
	uint8_t uc, subopt, suboptlen;

	ND_PRINT((ndo, "\n\t  Vendor-rfc1048 Extensions"));

	/* Step over magic cookie */
	ND_PRINT((ndo, "\n\t    Magic Cookie 0x%08x", EXTRACT_32BITS(bp)));
	bp += sizeof(int32_t);

	/* Loop while we there is a tag left in the buffer */
	while (ND_TTEST2(*bp, 1)) {
		tag = *bp++;
		if (tag == TAG_PAD && ndo->ndo_vflag < 3)
			continue;
		if (tag == TAG_END && ndo->ndo_vflag < 3)
			return;
		if (tag == TAG_EXTENDED_OPTION) {
			ND_TCHECK2(*(bp + 1), 2);
			tag = EXTRACT_16BITS(bp + 1);
			/* XXX we don't know yet if the IANA will
			 * preclude overlap of 1-byte and 2-byte spaces.
			 * If not, we need to offset tag after this step.
			 */
			cp = tok2str(xtag2str, "?xT%u", tag);
		} else
			cp = tok2str(tag2str, "?T%u", tag);
		c = *cp++;

		if (tag == TAG_PAD || tag == TAG_END)
			len = 0;
		else {
			/* Get the length; check for truncation */
			ND_TCHECK2(*bp, 1);
			len = *bp++;
		}

		ND_PRINT((ndo, "\n\t    %s Option %u, length %u%s", cp, tag, len,
			  len > 0 ? ": " : ""));

		if (tag == TAG_PAD && ndo->ndo_vflag > 2) {
			u_int ntag = 1;
			while (ND_TTEST2(*bp, 1) && *bp == TAG_PAD) {
				bp++;
				ntag++;
			}
			if (ntag > 1)
				ND_PRINT((ndo, ", occurs %u", ntag));
		}

		if (!ND_TTEST2(*bp, len)) {
			ND_PRINT((ndo, "[|rfc1048 %u]", len));
			return;
		}

		if (tag == TAG_DHCP_MESSAGE && len == 1) {
			uc = *bp++;
			ND_PRINT((ndo, "%s", tok2str(dhcp_msg_values, "Unknown (%u)", uc)));
			continue;
		}

		if (tag == TAG_PARM_REQUEST) {
			idx = 0;
			while (len-- > 0) {
				uc = *bp++;
				cp = tok2str(tag2str, "?Option %u", uc);
				if (idx % 4 == 0)
					ND_PRINT((ndo, "\n\t      "));
				else
					ND_PRINT((ndo, ", "));
				ND_PRINT((ndo, "%s", cp + 1));
				idx++;
			}
			continue;
		}

		if (tag == TAG_EXTENDED_REQUEST) {
			first = 1;
			while (len > 1) {
				len -= 2;
				us = EXTRACT_16BITS(bp);
				bp += 2;
				cp = tok2str(xtag2str, "?xT%u", us);
				if (!first)
					ND_PRINT((ndo, "+"));
				ND_PRINT((ndo, "%s", cp + 1));
				first = 0;
			}
			continue;
		}

		/* Print data */
		if (c == '?') {
			/* Base default formats for unknown tags on data size */
			if (len & 1)
				c = 'b';
			else if (len & 2)
				c = 's';
			else
				c = 'l';
		}
		first = 1;
		switch (c) {

		case 'a':
			/* ascii strings */
			ND_PRINT((ndo, "\""));
			if (fn_printn(ndo, bp, len, ndo->ndo_snapend)) {
				ND_PRINT((ndo, "\""));
				goto trunc;
			}
			ND_PRINT((ndo, "\""));
			bp += len;
			len = 0;
			break;

		case 'i':
		case 'l':
		case 'L':
			/* ip addresses/32-bit words */
			while (len >= sizeof(ul)) {
				if (!first)
					ND_PRINT((ndo, ","));
				ul = EXTRACT_32BITS(bp);
				if (c == 'i') {
					ul = htonl(ul);
					ND_PRINT((ndo, "%s", ipaddr_string(ndo, &ul)));
				} else if (c == 'L')
					ND_PRINT((ndo, "%d", ul));
				else
					ND_PRINT((ndo, "%u", ul));
				bp += sizeof(ul);
				len -= sizeof(ul);
				first = 0;
			}
			break;

		case 'p':
			/* IP address pairs */
			while (len >= 2*sizeof(ul)) {
				if (!first)
					ND_PRINT((ndo, ","));
				memcpy((char *)&ul, (const char *)bp, sizeof(ul));
				ND_PRINT((ndo, "(%s:", ipaddr_string(ndo, &ul)));
				bp += sizeof(ul);
				memcpy((char *)&ul, (const char *)bp, sizeof(ul));
				ND_PRINT((ndo, "%s)", ipaddr_string(ndo, &ul)));
				bp += sizeof(ul);
				len -= 2*sizeof(ul);
				first = 0;
			}
			break;

		case 's':
			/* shorts */
			while (len >= sizeof(us)) {
				if (!first)
					ND_PRINT((ndo, ","));
				us = EXTRACT_16BITS(bp);
				ND_PRINT((ndo, "%u", us));
				bp += sizeof(us);
				len -= sizeof(us);
				first = 0;
			}
			break;

		case 'B':
			/* boolean */
			while (len > 0) {
				if (!first)
					ND_PRINT((ndo, ","));
				switch (*bp) {
				case 0:
					ND_PRINT((ndo, "N"));
					break;
				case 1:
					ND_PRINT((ndo, "Y"));
					break;
				default:
					ND_PRINT((ndo, "%u?", *bp));
					break;
				}
				++bp;
				--len;
				first = 0;
			}
			break;

		case 'b':
		case 'x':
		default:
			/* Bytes */
			while (len > 0) {
				if (!first)
					ND_PRINT((ndo, c == 'x' ? ":" : "."));
				if (c == 'x')
					ND_PRINT((ndo, "%02x", *bp));
				else
					ND_PRINT((ndo, "%u", *bp));
				++bp;
				--len;
				first = 0;
			}
			break;

		case '$':
			/* Guys we can't handle with one of the usual cases */
			switch (tag) {

			case TAG_NETBIOS_NODE:
				/* this option should be at least 1 byte long */
				if (len < 1) {
					ND_PRINT((ndo, "ERROR: length < 1 bytes"));
					break;
				}
				tag = *bp++;
				--len;
				ND_PRINT((ndo, "%s", tok2str(nbo2str, NULL, tag)));
				break;

			case TAG_OPT_OVERLOAD:
				/* this option should be at least 1 byte long */
				if (len < 1) {
					ND_PRINT((ndo, "ERROR: length < 1 bytes"));
					break;
				}
				tag = *bp++;
				--len;
				ND_PRINT((ndo, "%s", tok2str(oo2str, NULL, tag)));
				break;

			case TAG_CLIENT_FQDN:
				/* this option should be at least 3 bytes long */
				if (len < 3) {
					ND_PRINT((ndo, "ERROR: length < 3 bytes"));
					bp += len;
					len = 0;
					break;
				}
				if (*bp)
					ND_PRINT((ndo, "[%s] ", client_fqdn_flags(*bp)));
				bp++;
				if (*bp || *(bp+1))
					ND_PRINT((ndo, "%u/%u ", *bp, *(bp+1)));
				bp += 2;
				ND_PRINT((ndo, "\""));
				if (fn_printn(ndo, bp, len - 3, ndo->ndo_snapend)) {
					ND_PRINT((ndo, "\""));
					goto trunc;
				}
				ND_PRINT((ndo, "\""));
				bp += len - 3;
				len = 0;
				break;

			case TAG_CLIENT_ID:
			    {
				int type;

				/* this option should be at least 1 byte long */
				if (len < 1) {
					ND_PRINT((ndo, "ERROR: length < 1 bytes"));
					break;
				}
				type = *bp++;
				len--;
				if (type == 0) {
					ND_PRINT((ndo, "\""));
					if (fn_printn(ndo, bp, len, ndo->ndo_snapend)) {
						ND_PRINT((ndo, "\""));
						goto trunc;
					}
					ND_PRINT((ndo, "\""));
					bp += len;
					len = 0;
					break;
				} else {
					ND_PRINT((ndo, "%s ", tok2str(arp2str, "hardware-type %u,", type)));
					while (len > 0) {
						if (!first)
							ND_PRINT((ndo, ":"));
						ND_PRINT((ndo, "%02x", *bp));
						++bp;
						--len;
						first = 0;
					}
				}
				break;
			    }

			case TAG_AGENT_CIRCUIT:
				while (len >= 2) {
					subopt = *bp++;
					suboptlen = *bp++;
					len -= 2;
					if (suboptlen > len) {
						ND_PRINT((ndo, "\n\t      %s SubOption %u, length %u: length goes past end of option",
							  tok2str(agent_suboption_values, "Unknown", subopt),
							  subopt,
							  suboptlen));
						bp += len;
						len = 0;
						break;
					}
					ND_PRINT((ndo, "\n\t      %s SubOption %u, length %u: ",
						  tok2str(agent_suboption_values, "Unknown", subopt),
						  subopt,
						  suboptlen));
					switch (subopt) {

					case AGENT_SUBOPTION_CIRCUIT_ID: /* fall through */
					case AGENT_SUBOPTION_REMOTE_ID:
					case AGENT_SUBOPTION_SUBSCRIBER_ID:
						if (fn_printn(ndo, bp, suboptlen, ndo->ndo_snapend))
							goto trunc;
						break;

					default:
						print_unknown_data(ndo, bp, "\n\t\t", suboptlen);
					}

					len -= suboptlen;
					bp += suboptlen;
				}
				break;

			case TAG_CLASSLESS_STATIC_RT:
			case TAG_CLASSLESS_STA_RT_MS:
			    {
				u_int mask_width, significant_octets, i;

				/* this option should be at least 5 bytes long */
				if (len < 5) {
					ND_PRINT((ndo, "ERROR: length < 5 bytes"));
					bp += len;
					len = 0;
					break;
				}
				while (len > 0) {
					if (!first)
						ND_PRINT((ndo, ","));
					mask_width = *bp++;
					len--;
					/* mask_width <= 32 */
					if (mask_width > 32) {
						ND_PRINT((ndo, "[ERROR: Mask width (%d) > 32]", mask_width));
						bp += len;
						len = 0;
						break;
					}
					significant_octets = (mask_width + 7) / 8;
					/* significant octets + router(4) */
					if (len < significant_octets + 4) {
						ND_PRINT((ndo, "[ERROR: Remaining length (%u) < %u bytes]", len, significant_octets + 4));
						bp += len;
						len = 0;
						break;
					}
					ND_PRINT((ndo, "("));
					if (mask_width == 0)
						ND_PRINT((ndo, "default"));
					else {
						for (i = 0; i < significant_octets ; i++) {
							if (i > 0)
								ND_PRINT((ndo, "."));
							ND_PRINT((ndo, "%d", *bp++));
						}
						for (i = significant_octets ; i < 4 ; i++)
							ND_PRINT((ndo, ".0"));
						ND_PRINT((ndo, "/%d", mask_width));
					}
					memcpy((char *)&ul, (const char *)bp, sizeof(ul));
					ND_PRINT((ndo, ":%s)", ipaddr_string(ndo, &ul)));
					bp += sizeof(ul);
					len -= (significant_octets + 4);
					first = 0;
				}
				break;
			    }

			case TAG_USER_CLASS:
			    {
				u_int suboptnumber = 1;

				first = 1;
				if (len < 2) {
					ND_PRINT((ndo, "ERROR: length < 2 bytes"));
					bp += len;
					len = 0;
					break;
				}
				while (len > 0) {
					suboptlen = *bp++;
					len--;
					ND_PRINT((ndo, "\n\t      "));
					ND_PRINT((ndo, "instance#%u: ", suboptnumber));
					if (suboptlen == 0) {
						ND_PRINT((ndo, "ERROR: suboption length must be non-zero"));
						bp += len;
						len = 0;
						break;
					}
					if (len < suboptlen) {
						ND_PRINT((ndo, "ERROR: malformed option"));
						bp += len;
						len = 0;
						break;
					}
					ND_PRINT((ndo, "\""));
					if (fn_printn(ndo, bp, suboptlen, ndo->ndo_snapend)) {
						ND_PRINT((ndo, "\""));
						goto trunc;
					}
					ND_PRINT((ndo, "\""));
					ND_PRINT((ndo, ", length %d", suboptlen));
					suboptnumber++;
					len -= suboptlen;
					bp += suboptlen;
				}
				break;
			    }

			default:
				ND_PRINT((ndo, "[unknown special tag %u, size %u]",
					  tag, len));
				bp += len;
				len = 0;
				break;
			}
			break;
		}
		/* Data left over? */
		if (len) {
			ND_PRINT((ndo, "\n\t  trailing data length %u", len));
			bp += len;
		}
	}
	return;
trunc:
	ND_PRINT((ndo, "|[rfc1048]"));
}
Example #15
0
static int
lmp_print_data_link_subobjs(netdissect_options *ndo, const u_char *obj_tptr,
                            int total_subobj_len, int offset)
{
    int hexdump = FALSE;
    int subobj_type, subobj_len;

    union { /* int to float conversion buffer */
        float f;
        uint32_t i;
    } bw;

    while (total_subobj_len > 0 && hexdump == FALSE ) {
	subobj_type = EXTRACT_U_1(obj_tptr + offset);
	subobj_len  = EXTRACT_U_1(obj_tptr + offset + 1);
	ND_PRINT("\n\t    Subobject, Type: %s (%u), Length: %u",
		tok2str(lmp_data_link_subobj,
			"Unknown",
			subobj_type),
			subobj_type,
			subobj_len);
	if (subobj_len < 4) {
	    ND_PRINT(" (too short)");
	    break;
	}
	if ((subobj_len % 4) != 0) {
	    ND_PRINT(" (not a multiple of 4)");
	    break;
	}
	if (total_subobj_len < subobj_len) {
	    ND_PRINT(" (goes past the end of the object)");
	    break;
	}
	switch(subobj_type) {
	case INT_SWITCHING_TYPE_SUBOBJ:
	    ND_PRINT("\n\t      Switching Type: %s (%u)",
		tok2str(gmpls_switch_cap_values,
			"Unknown",
			EXTRACT_U_1(obj_tptr + offset + 2)),
		EXTRACT_U_1(obj_tptr + offset + 2));
	    ND_PRINT("\n\t      Encoding Type: %s (%u)",
		tok2str(gmpls_encoding_values,
			"Unknown",
			EXTRACT_U_1(obj_tptr + offset + 3)),
		EXTRACT_U_1(obj_tptr + offset + 3));
	    bw.i = EXTRACT_BE_U_4(obj_tptr + offset + 4);
	    ND_PRINT("\n\t      Min Reservable Bandwidth: %.3f Mbps",
                bw.f*8/1000000);
	    bw.i = EXTRACT_BE_U_4(obj_tptr + offset + 8);
	    ND_PRINT("\n\t      Max Reservable Bandwidth: %.3f Mbps",
                bw.f*8/1000000);
	    break;
	case WAVELENGTH_SUBOBJ:
	    ND_PRINT("\n\t      Wavelength: %u",
		EXTRACT_BE_U_4(obj_tptr + offset + 4));
	    break;
	default:
	    /* Any Unknown Subobject ==> Exit loop */
	    hexdump=TRUE;
	    break;
	}
	total_subobj_len-=subobj_len;
	offset+=subobj_len;
    }
    return (hexdump);
}
Example #16
0
void
_geneve_print(netdissect_options *ndo, const u_char *bp, u_int len)
{
    uint8_t ver_opt;
    uint version;
    uint8_t flags;
    uint16_t prot;
    uint32_t vni;
    uint8_t reserved;
    u_int opts_len;

    ND_PRINT((ndo, "Geneve"));

    ND_TCHECK2(*bp, 8);

    ver_opt = *bp;
    bp += 1;
    len -= 1;

    version = ver_opt >> VER_SHIFT;
    if (version != 0) {
        ND_PRINT((ndo, " ERROR: unknown-version %u", version));
        return;
    }

    flags = *bp;
    bp += 1;
    len -= 1;

    prot = EXTRACT_16BITS(bp);
    bp += 2;
    len -= 2;

    vni = EXTRACT_24BITS(bp);
    bp += 3;
    len -= 3;

    reserved = *bp;
    bp += 1;
    len -= 1;

    ND_PRINT((ndo, ", Flags [%s]",
              bittok2str_nosep(geneve_flag_values, "none", flags)));
    ND_PRINT((ndo, ", vni 0x%x", vni));

    if (reserved)
        ND_PRINT((ndo, ", rsvd 0x%x", reserved));

    if (ndo->ndo_eflag)
        ND_PRINT((ndo, ", proto %s (0x%04x)",
                  tok2str(ethertype_values, "unknown", prot), prot));

    opts_len = (ver_opt & HDR_OPTS_LEN_MASK) * 4;

    if (len < opts_len) {
        ND_PRINT((ndo, " truncated-geneve - %u bytes missing",
                  len - opts_len));
        return;
    }

    ND_TCHECK2(*bp, opts_len);

    if (opts_len > 0) {
        ND_PRINT((ndo, ", options ["));

        if (ndo->ndo_vflag)
            geneve_opts_print(ndo, bp, opts_len);
        else
            ND_PRINT((ndo, "%u bytes", opts_len));

        ND_PRINT((ndo, "]"));
    }

    bp += opts_len;
    len -= opts_len;

    if (ndo->ndo_vflag < 1)
        ND_PRINT((ndo, ": "));
    else
        ND_PRINT((ndo, "\n\t"));

    if (ethertype_print(ndo, prot, bp, len, len) == 0) {
        if (prot == ETHERTYPE_TEB)
            ether_print(ndo, bp, len, len, NULL, NULL);
        else
            ND_PRINT((ndo, "geneve-proto-0x%x", prot));
    }

    return;

trunc:
    ND_PRINT((ndo, " [|geneve]"));
}
Example #17
0
void
lmp_print(netdissect_options *ndo,
          const u_char *pptr, u_int len)
{
    const struct lmp_common_header *lmp_com_header;
    const struct lmp_object_header *lmp_obj_header;
    const u_char *tptr,*obj_tptr;
    u_int version_res, tlen, lmp_obj_len, lmp_obj_ctype, obj_tlen;
    int hexdump;
    u_int offset;
    u_int link_type;

    union { /* int to float conversion buffer */
        float f;
        uint32_t i;
    } bw;

    ndo->ndo_protocol = "lmp";
    tptr=pptr;
    lmp_com_header = (const struct lmp_common_header *)pptr;
    ND_TCHECK_SIZE(lmp_com_header);

    version_res = EXTRACT_BE_U_2(lmp_com_header->version_res);

    /*
     * Sanity checking of the header.
     */
    if (LMP_EXTRACT_VERSION(version_res) != LMP_VERSION) {
	ND_PRINT("LMP version %u packet not supported",
               LMP_EXTRACT_VERSION(version_res));
	return;
    }

    /* in non-verbose mode just lets print the basic Message Type*/
    if (ndo->ndo_vflag < 1) {
        ND_PRINT("LMPv%u %s Message, length: %u",
               LMP_EXTRACT_VERSION(version_res),
               tok2str(lmp_msg_type_values, "unknown (%u)",EXTRACT_U_1(lmp_com_header->msg_type)),
               len);
        return;
    }

    /* ok they seem to want to know everything - lets fully decode it */

    tlen=EXTRACT_BE_U_2(lmp_com_header->length);

    ND_PRINT("\n\tLMPv%u, msg-type: %s, Flags: [%s], length: %u",
           LMP_EXTRACT_VERSION(version_res),
           tok2str(lmp_msg_type_values, "unknown, type: %u",EXTRACT_U_1(lmp_com_header->msg_type)),
           bittok2str(lmp_header_flag_values,"none",EXTRACT_U_1(lmp_com_header->flags)),
           tlen);
    if (tlen < sizeof(struct lmp_common_header)) {
        ND_PRINT(" (too short)");
        return;
    }
    if (tlen > len) {
        ND_PRINT(" (too long)");
        tlen = len;
    }

    tptr+=sizeof(struct lmp_common_header);
    tlen-=sizeof(struct lmp_common_header);

    while(tlen>0) {
        /* did we capture enough for fully decoding the object header ? */
        ND_TCHECK_LEN(tptr, sizeof(struct lmp_object_header));

        lmp_obj_header = (const struct lmp_object_header *)tptr;
        lmp_obj_len=EXTRACT_BE_U_2(lmp_obj_header->length);
        lmp_obj_ctype=EXTRACT_U_1(lmp_obj_header->ctype)&0x7f;

        ND_PRINT("\n\t  %s Object (%u), Class-Type: %s (%u) Flags: [%snegotiable], length: %u",
               tok2str(lmp_obj_values,
                       "Unknown",
                       EXTRACT_U_1(lmp_obj_header->class_num)),
               EXTRACT_U_1(lmp_obj_header->class_num),
               tok2str(lmp_ctype_values,
                       "Unknown",
                       (EXTRACT_U_1(lmp_obj_header->class_num)<<8)+lmp_obj_ctype),
               lmp_obj_ctype,
               EXTRACT_U_1(lmp_obj_header->ctype)&0x80 ? "" : "non-",
               lmp_obj_len);

        if (lmp_obj_len < 4) {
            ND_PRINT(" (too short)");
            return;
        }
        if ((lmp_obj_len % 4) != 0) {
            ND_PRINT(" (not a multiple of 4)");
            return;
        }

        obj_tptr=tptr+sizeof(struct lmp_object_header);
        obj_tlen=lmp_obj_len-sizeof(struct lmp_object_header);

        /* did we capture enough for fully decoding the object ? */
        ND_TCHECK_LEN(tptr, lmp_obj_len);
        hexdump=FALSE;

        switch(EXTRACT_U_1(lmp_obj_header->class_num)) {

        case LMP_OBJ_CC_ID:
            switch(lmp_obj_ctype) {
            case LMP_CTYPE_LOC:
            case LMP_CTYPE_RMT:
                if (obj_tlen != 4) {
                    ND_PRINT(" (not correct for object)");
                    break;
                }
                ND_PRINT("\n\t    Control Channel ID: %u (0x%08x)",
                       EXTRACT_BE_U_4(obj_tptr),
                       EXTRACT_BE_U_4(obj_tptr));
                break;

            default:
                hexdump=TRUE;
            }
            break;

        case LMP_OBJ_LINK_ID:
        case LMP_OBJ_INTERFACE_ID:
            switch(lmp_obj_ctype) {
            case LMP_CTYPE_IPV4_LOC:
            case LMP_CTYPE_IPV4_RMT:
                if (obj_tlen != 4) {
                    ND_PRINT(" (not correct for object)");
                    break;
                }
                ND_PRINT("\n\t    IPv4 Link ID: %s (0x%08x)",
                       ipaddr_string(ndo, obj_tptr),
                       EXTRACT_BE_U_4(obj_tptr));
                break;
            case LMP_CTYPE_IPV6_LOC:
            case LMP_CTYPE_IPV6_RMT:
                if (obj_tlen != 16) {
                    ND_PRINT(" (not correct for object)");
                    break;
                }
                ND_PRINT("\n\t    IPv6 Link ID: %s (0x%08x)",
                       ip6addr_string(ndo, obj_tptr),
                       EXTRACT_BE_U_4(obj_tptr));
                break;
            case LMP_CTYPE_UNMD_LOC:
            case LMP_CTYPE_UNMD_RMT:
                if (obj_tlen != 4) {
                    ND_PRINT(" (not correct for object)");
                    break;
                }
                ND_PRINT("\n\t    Link ID: %u (0x%08x)",
                       EXTRACT_BE_U_4(obj_tptr),
                       EXTRACT_BE_U_4(obj_tptr));
                break;
            default:
                hexdump=TRUE;
            }
            break;

        case LMP_OBJ_MESSAGE_ID:
            switch(lmp_obj_ctype) {
            case LMP_CTYPE_1:
                if (obj_tlen != 4) {
                    ND_PRINT(" (not correct for object)");
                    break;
                }
                ND_PRINT("\n\t    Message ID: %u (0x%08x)",
                       EXTRACT_BE_U_4(obj_tptr),
                       EXTRACT_BE_U_4(obj_tptr));
                break;
            case LMP_CTYPE_2:
                if (obj_tlen != 4) {
                    ND_PRINT(" (not correct for object)");
                    break;
                }
                ND_PRINT("\n\t    Message ID Ack: %u (0x%08x)",
                       EXTRACT_BE_U_4(obj_tptr),
                       EXTRACT_BE_U_4(obj_tptr));
                break;
            default:
                hexdump=TRUE;
            }
            break;

        case LMP_OBJ_NODE_ID:
            switch(lmp_obj_ctype) {
            case LMP_CTYPE_LOC:
            case LMP_CTYPE_RMT:
                if (obj_tlen != 4) {
                    ND_PRINT(" (not correct for object)");
                    break;
                }
                ND_PRINT("\n\t    Node ID: %s (0x%08x)",
                       ipaddr_string(ndo, obj_tptr),
                       EXTRACT_BE_U_4(obj_tptr));
                break;

            default:
                hexdump=TRUE;
            }
            break;

        case LMP_OBJ_CONFIG:
            switch(lmp_obj_ctype) {
            case LMP_CTYPE_HELLO_CONFIG:
                if (obj_tlen != 4) {
                    ND_PRINT(" (not correct for object)");
                    break;
                }
                ND_PRINT("\n\t    Hello Interval: %u\n\t    Hello Dead Interval: %u",
                       EXTRACT_BE_U_2(obj_tptr),
                       EXTRACT_BE_U_2(obj_tptr + 2));
                break;

            default:
                hexdump=TRUE;
            }
            break;

        case LMP_OBJ_HELLO:
            switch(lmp_obj_ctype) {
	    case LMP_CTYPE_HELLO:
                if (obj_tlen != 8) {
                    ND_PRINT(" (not correct for object)");
                    break;
                }
                ND_PRINT("\n\t    Tx Seq: %u, Rx Seq: %u",
                       EXTRACT_BE_U_4(obj_tptr),
                       EXTRACT_BE_U_4(obj_tptr + 4));
                break;

            default:
                hexdump=TRUE;
            }
            break;

        case LMP_OBJ_TE_LINK:
	    switch(lmp_obj_ctype) {
	    case LMP_CTYPE_IPV4:
                if (obj_tlen != 12) {
                    ND_PRINT(" (not correct for object)");
                    break;
                }
		ND_PRINT("\n\t    Flags: [%s]",
		    bittok2str(lmp_obj_te_link_flag_values,
			"none",
			EXTRACT_U_1(obj_tptr)));

		ND_PRINT("\n\t    Local Link-ID: %s (0x%08x)"
		       "\n\t    Remote Link-ID: %s (0x%08x)",
                       ipaddr_string(ndo, obj_tptr+4),
                       EXTRACT_BE_U_4(obj_tptr + 4),
                       ipaddr_string(ndo, obj_tptr+8),
                       EXTRACT_BE_U_4(obj_tptr + 8));
		break;

	    case LMP_CTYPE_IPV6:
                if (obj_tlen != 36) {
                    ND_PRINT(" (not correct for object)");
                    break;
                }
		ND_PRINT("\n\t    Flags: [%s]",
		    bittok2str(lmp_obj_te_link_flag_values,
			"none",
			EXTRACT_U_1(obj_tptr)));

		ND_PRINT("\n\t    Local Link-ID: %s (0x%08x)"
		       "\n\t    Remote Link-ID: %s (0x%08x)",
                       ip6addr_string(ndo, obj_tptr+4),
                       EXTRACT_BE_U_4(obj_tptr + 4),
                       ip6addr_string(ndo, obj_tptr+20),
                       EXTRACT_BE_U_4(obj_tptr + 20));
                break;

	    case LMP_CTYPE_UNMD:
                if (obj_tlen != 12) {
                    ND_PRINT(" (not correct for object)");
                    break;
                }
		ND_PRINT("\n\t    Flags: [%s]",
		    bittok2str(lmp_obj_te_link_flag_values,
			"none",
			EXTRACT_U_1(obj_tptr)));

		ND_PRINT("\n\t    Local Link-ID: %u (0x%08x)"
		       "\n\t    Remote Link-ID: %u (0x%08x)",
                       EXTRACT_BE_U_4(obj_tptr + 4),
                       EXTRACT_BE_U_4(obj_tptr + 4),
                       EXTRACT_BE_U_4(obj_tptr + 8),
                       EXTRACT_BE_U_4(obj_tptr + 8));
		break;

            default:
                hexdump=TRUE;
            }
            break;

        case LMP_OBJ_DATA_LINK:
	    switch(lmp_obj_ctype) {
	    case LMP_CTYPE_IPV4:
                if (obj_tlen < 12) {
                    ND_PRINT(" (not correct for object)");
                    break;
                }
	        ND_PRINT("\n\t    Flags: [%s]",
		    bittok2str(lmp_obj_data_link_flag_values,
			"none",
			EXTRACT_U_1(obj_tptr)));
                ND_PRINT("\n\t    Local Interface ID: %s (0x%08x)"
                       "\n\t    Remote Interface ID: %s (0x%08x)",
                       ipaddr_string(ndo, obj_tptr+4),
                       EXTRACT_BE_U_4(obj_tptr + 4),
                       ipaddr_string(ndo, obj_tptr+8),
                       EXTRACT_BE_U_4(obj_tptr + 8));

		if (lmp_print_data_link_subobjs(ndo, obj_tptr, obj_tlen - 12, 12))
		    hexdump=TRUE;
		break;

	    case LMP_CTYPE_IPV6:
                if (obj_tlen < 36) {
                    ND_PRINT(" (not correct for object)");
                    break;
                }
	        ND_PRINT("\n\t    Flags: [%s]",
		    bittok2str(lmp_obj_data_link_flag_values,
			"none",
			EXTRACT_U_1(obj_tptr)));
                ND_PRINT("\n\t    Local Interface ID: %s (0x%08x)"
                       "\n\t    Remote Interface ID: %s (0x%08x)",
                       ip6addr_string(ndo, obj_tptr+4),
                       EXTRACT_BE_U_4(obj_tptr + 4),
                       ip6addr_string(ndo, obj_tptr+20),
                       EXTRACT_BE_U_4(obj_tptr + 20));

		if (lmp_print_data_link_subobjs(ndo, obj_tptr, obj_tlen - 36, 36))
		    hexdump=TRUE;
		break;

	    case LMP_CTYPE_UNMD:
                if (obj_tlen < 12) {
                    ND_PRINT(" (not correct for object)");
                    break;
                }
	        ND_PRINT("\n\t    Flags: [%s]",
		    bittok2str(lmp_obj_data_link_flag_values,
			"none",
			EXTRACT_U_1(obj_tptr)));
                ND_PRINT("\n\t    Local Interface ID: %u (0x%08x)"
                       "\n\t    Remote Interface ID: %u (0x%08x)",
                       EXTRACT_BE_U_4(obj_tptr + 4),
                       EXTRACT_BE_U_4(obj_tptr + 4),
                       EXTRACT_BE_U_4(obj_tptr + 8),
                       EXTRACT_BE_U_4(obj_tptr + 8));

		if (lmp_print_data_link_subobjs(ndo, obj_tptr, obj_tlen - 12, 12))
		    hexdump=TRUE;
		break;

            default:
                hexdump=TRUE;
            }
            break;

        case LMP_OBJ_VERIFY_BEGIN:
	    switch(lmp_obj_ctype) {
            case LMP_CTYPE_1:
                if (obj_tlen != 20) {
                    ND_PRINT(" (not correct for object)");
                    break;
                }
		ND_PRINT("\n\t    Flags: %s",
		bittok2str(lmp_obj_begin_verify_flag_values,
			"none",
			EXTRACT_BE_U_2(obj_tptr)));
		ND_PRINT("\n\t    Verify Interval: %u",
			EXTRACT_BE_U_2(obj_tptr + 2));
		ND_PRINT("\n\t    Data links: %u",
			EXTRACT_BE_U_4(obj_tptr + 4));
                ND_PRINT("\n\t    Encoding type: %s",
			tok2str(gmpls_encoding_values, "Unknown", EXTRACT_U_1((obj_tptr + 8))));
                ND_PRINT("\n\t    Verify Transport Mechanism: %u (0x%x)%s",
			EXTRACT_BE_U_2(obj_tptr + 10),
			EXTRACT_BE_U_2(obj_tptr + 10),
			EXTRACT_BE_U_2(obj_tptr + 10)&8000 ? " (Payload test messages capable)" : "");
                bw.i = EXTRACT_BE_U_4(obj_tptr + 12);
		ND_PRINT("\n\t    Transmission Rate: %.3f Mbps",bw.f*8/1000000);
		ND_PRINT("\n\t    Wavelength: %u",
			EXTRACT_BE_U_4(obj_tptr + 16));
		break;

            default:
                hexdump=TRUE;
            }
            break;

        case LMP_OBJ_VERIFY_BEGIN_ACK:
	    switch(lmp_obj_ctype) {
            case LMP_CTYPE_1:
                if (obj_tlen != 4) {
                    ND_PRINT(" (not correct for object)");
                    break;
                }
                ND_PRINT("\n\t    Verify Dead Interval: %u"
                       "\n\t    Verify Transport Response: %u",
                       EXTRACT_BE_U_2(obj_tptr),
                       EXTRACT_BE_U_2(obj_tptr + 2));
                break;

            default:
                hexdump=TRUE;
            }
            break;

	case LMP_OBJ_VERIFY_ID:
	    switch(lmp_obj_ctype) {
            case LMP_CTYPE_1:
                if (obj_tlen != 4) {
                    ND_PRINT(" (not correct for object)");
                    break;
                }
                ND_PRINT("\n\t    Verify ID: %u",
                       EXTRACT_BE_U_4(obj_tptr));
                break;

            default:
                hexdump=TRUE;
            }
            break;

	case LMP_OBJ_CHANNEL_STATUS:
            switch(lmp_obj_ctype) {
	    case LMP_CTYPE_IPV4:
		offset = 0;
		/* Decode pairs: <Interface_ID (4 bytes), Channel_status (4 bytes)> */
		while (offset+8 <= obj_tlen) {
			ND_PRINT("\n\t    Interface ID: %s (0x%08x)",
			ipaddr_string(ndo, obj_tptr+offset),
			EXTRACT_BE_U_4(obj_tptr + offset));

			ND_PRINT("\n\t\t    Active: %s (%u)",
				(EXTRACT_BE_U_4(obj_tptr + offset + 4)>>31) ?
				"Allocated" : "Non-allocated",
				(EXTRACT_BE_U_4(obj_tptr + offset + 4)>>31));

			ND_PRINT("\n\t\t    Direction: %s (%u)",
				(EXTRACT_BE_U_4(obj_tptr + offset + 4)>>30)&0x1 ?
				"Transmit" : "Receive",
				(EXTRACT_BE_U_4(obj_tptr + offset + 4)>>30)&0x1);

			ND_PRINT("\n\t\t    Channel Status: %s (%u)",
					tok2str(lmp_obj_channel_status_values,
			 		"Unknown",
					EXTRACT_BE_U_4(obj_tptr + offset + 4)&0x3FFFFFF),
					EXTRACT_BE_U_4(obj_tptr + offset + 4)&0x3FFFFFF);
			offset+=8;
		}
                break;

	    case LMP_CTYPE_IPV6:
		offset = 0;
		/* Decode pairs: <Interface_ID (16 bytes), Channel_status (4 bytes)> */
		while (offset+20 <= obj_tlen) {
			ND_PRINT("\n\t    Interface ID: %s (0x%08x)",
			ip6addr_string(ndo, obj_tptr+offset),
			EXTRACT_BE_U_4(obj_tptr + offset));

			ND_PRINT("\n\t\t    Active: %s (%u)",
				(EXTRACT_BE_U_4(obj_tptr + offset + 16)>>31) ?
				"Allocated" : "Non-allocated",
				(EXTRACT_BE_U_4(obj_tptr + offset + 16)>>31));

			ND_PRINT("\n\t\t    Direction: %s (%u)",
				(EXTRACT_BE_U_4(obj_tptr + offset + 16)>>30)&0x1 ?
				"Transmit" : "Receive",
				(EXTRACT_BE_U_4(obj_tptr + offset + 16)>>30)&0x1);

			ND_PRINT("\n\t\t    Channel Status: %s (%u)",
					tok2str(lmp_obj_channel_status_values,
					"Unknown",
					EXTRACT_BE_U_4(obj_tptr + offset + 16)&0x3FFFFFF),
					EXTRACT_BE_U_4(obj_tptr + offset + 16)&0x3FFFFFF);
			offset+=20;
		}
                break;

	    case LMP_CTYPE_UNMD:
		offset = 0;
		/* Decode pairs: <Interface_ID (4 bytes), Channel_status (4 bytes)> */
		while (offset+8 <= obj_tlen) {
			ND_PRINT("\n\t    Interface ID: %u (0x%08x)",
			EXTRACT_BE_U_4(obj_tptr + offset),
			EXTRACT_BE_U_4(obj_tptr + offset));

			ND_PRINT("\n\t\t    Active: %s (%u)",
				(EXTRACT_BE_U_4(obj_tptr + offset + 4)>>31) ?
				"Allocated" : "Non-allocated",
				(EXTRACT_BE_U_4(obj_tptr + offset + 4)>>31));

			ND_PRINT("\n\t\t    Direction: %s (%u)",
				(EXTRACT_BE_U_4(obj_tptr + offset + 4)>>30)&0x1 ?
				"Transmit" : "Receive",
				(EXTRACT_BE_U_4(obj_tptr + offset + 4)>>30)&0x1);

			ND_PRINT("\n\t\t    Channel Status: %s (%u)",
					tok2str(lmp_obj_channel_status_values,
					"Unknown",
					EXTRACT_BE_U_4(obj_tptr + offset + 4)&0x3FFFFFF),
					EXTRACT_BE_U_4(obj_tptr + offset + 4)&0x3FFFFFF);
			offset+=8;
		}
                break;

            default:
                hexdump=TRUE;
            }
            break;

	case LMP_OBJ_CHANNEL_STATUS_REQ:
            switch(lmp_obj_ctype) {
	    case LMP_CTYPE_IPV4:
		offset = 0;
		while (offset+4 <= obj_tlen) {
			ND_PRINT("\n\t    Interface ID: %s (0x%08x)",
			ipaddr_string(ndo, obj_tptr+offset),
			EXTRACT_BE_U_4(obj_tptr + offset));
			offset+=4;
		}
                break;

	    case LMP_CTYPE_IPV6:
		offset = 0;
		while (offset+16 <= obj_tlen) {
			ND_PRINT("\n\t    Interface ID: %s (0x%08x)",
			ip6addr_string(ndo, obj_tptr+offset),
			EXTRACT_BE_U_4(obj_tptr + offset));
			offset+=16;
		}
                break;

	    case LMP_CTYPE_UNMD:
		offset = 0;
		while (offset+4 <= obj_tlen) {
			ND_PRINT("\n\t    Interface ID: %u (0x%08x)",
			EXTRACT_BE_U_4(obj_tptr + offset),
			EXTRACT_BE_U_4(obj_tptr + offset));
			offset+=4;
		}
                break;

	    default:
                hexdump=TRUE;
            }
            break;

        case LMP_OBJ_ERROR_CODE:
	    switch(lmp_obj_ctype) {
            case LMP_CTYPE_BEGIN_VERIFY_ERROR:
                if (obj_tlen != 4) {
                    ND_PRINT(" (not correct for object)");
                    break;
                }
		ND_PRINT("\n\t    Error Code: %s",
		bittok2str(lmp_obj_begin_verify_error_values,
			"none",
			EXTRACT_BE_U_4(obj_tptr)));
                break;

            case LMP_CTYPE_LINK_SUMMARY_ERROR:
                if (obj_tlen != 4) {
                    ND_PRINT(" (not correct for object)");
                    break;
                }
		ND_PRINT("\n\t    Error Code: %s",
		bittok2str(lmp_obj_link_summary_error_values,
			"none",
			EXTRACT_BE_U_4(obj_tptr)));
                break;
            default:
                hexdump=TRUE;
            }
            break;

	case LMP_OBJ_SERVICE_CONFIG:
	    switch (lmp_obj_ctype) {
	    case LMP_CTYPE_SERVICE_CONFIG_SP:
                if (obj_tlen != 4) {
                    ND_PRINT(" (not correct for object)");
                    break;
                }
		ND_PRINT("\n\t Flags: %s",
		       bittok2str(lmp_obj_service_config_sp_flag_values,
				  "none",
				  EXTRACT_U_1(obj_tptr)));

		ND_PRINT("\n\t  UNI Version: %u",
		       EXTRACT_U_1(obj_tptr + 1));

		break;

            case LMP_CTYPE_SERVICE_CONFIG_CPSA:
                if (obj_tlen != 16) {
                    ND_PRINT(" (not correct for object)");
                    break;
                }

		link_type = EXTRACT_U_1(obj_tptr);

		ND_PRINT("\n\t Link Type: %s (%u)",
		       tok2str(lmp_sd_service_config_cpsa_link_type_values,
			       "Unknown", link_type),
		       link_type);

		switch (link_type) {
		case LMP_SD_SERVICE_CONFIG_CPSA_LINK_TYPE_SDH:
		    ND_PRINT("\n\t Signal Type: %s (%u)",
			   tok2str(lmp_sd_service_config_cpsa_signal_type_sdh_values,
				   "Unknown",
				   EXTRACT_U_1(obj_tptr + 1)),
			   EXTRACT_U_1(obj_tptr + 1));
		    break;

		case LMP_SD_SERVICE_CONFIG_CPSA_LINK_TYPE_SONET:
		    ND_PRINT("\n\t Signal Type: %s (%u)",
			   tok2str(lmp_sd_service_config_cpsa_signal_type_sonet_values,
				   "Unknown",
				   EXTRACT_U_1(obj_tptr + 1)),
			   EXTRACT_U_1(obj_tptr + 1));
		    break;
		}

		ND_PRINT("\n\t Transparency: %s",
		       bittok2str(lmp_obj_service_config_cpsa_tp_flag_values,
				  "none",
				  EXTRACT_U_1(obj_tptr + 2)));

		ND_PRINT("\n\t Contiguous Concatenation Types: %s",
		       bittok2str(lmp_obj_service_config_cpsa_cct_flag_values,
				  "none",
				  EXTRACT_U_1(obj_tptr + 3)));

		ND_PRINT("\n\t Minimum NCC: %u",
		       EXTRACT_BE_U_2(obj_tptr + 4));

		ND_PRINT("\n\t Maximum NCC: %u",
		       EXTRACT_BE_U_2(obj_tptr + 6));

		ND_PRINT("\n\t Minimum NVC:%u",
		       EXTRACT_BE_U_2(obj_tptr + 8));

		ND_PRINT("\n\t Maximum NVC:%u",
		       EXTRACT_BE_U_2(obj_tptr + 10));

		ND_PRINT("\n\t    Local Interface ID: %s (0x%08x)",
		       ipaddr_string(ndo, obj_tptr+12),
		       EXTRACT_BE_U_4(obj_tptr + 12));

		break;

	    case LMP_CTYPE_SERVICE_CONFIG_TRANSPARENCY_TCM:
                if (obj_tlen != 8) {
                    ND_PRINT(" (not correct for object)");
                    break;
                }

		ND_PRINT("\n\t Transparency Flags: %s",
		       bittok2str(
			   lmp_obj_service_config_nsa_transparency_flag_values,
			   "none",
			   EXTRACT_BE_U_4(obj_tptr)));

		ND_PRINT("\n\t TCM Monitoring Flags: %s",
		       bittok2str(
			   lmp_obj_service_config_nsa_tcm_flag_values,
			   "none",
			   EXTRACT_U_1(obj_tptr + 7)));

		break;

	    case LMP_CTYPE_SERVICE_CONFIG_NETWORK_DIVERSITY:
                if (obj_tlen != 4) {
                    ND_PRINT(" (not correct for object)");
                    break;
                }

		ND_PRINT("\n\t Diversity: Flags: %s",
		       bittok2str(
			   lmp_obj_service_config_nsa_network_diversity_flag_values,
			   "none",
			   EXTRACT_U_1(obj_tptr + 3)));
		break;

	    default:
		hexdump = TRUE;
	    }

	break;

        default:
            if (ndo->ndo_vflag <= 1)
                print_unknown_data(ndo,obj_tptr,"\n\t    ",obj_tlen);
            break;
        }
        /* do we want to see an additionally hexdump ? */
        if (ndo->ndo_vflag > 1 || hexdump==TRUE)
            print_unknown_data(ndo,tptr+sizeof(struct lmp_object_header),"\n\t    ",
                               lmp_obj_len-sizeof(struct lmp_object_header));

        tptr+=lmp_obj_len;
        tlen-=lmp_obj_len;
    }
    return;
trunc:
    nd_print_trunc(ndo);
}
Example #18
0
static void
ip6_opt_print(netdissect_options *ndo, const u_char *bp, int len)
{
    int i;
    int optlen = 0;

    if (len == 0)
        return;
    for (i = 0; i < len; i += optlen) {
	if (bp[i] == IP6OPT_PAD1)
	    optlen = 1;
	else {
	    if (i + 1 < len)
		optlen = bp[i + 1] + 2;
	    else
		goto trunc;
	}
	if (i + optlen > len)
	    goto trunc;

	switch (bp[i]) {
	case IP6OPT_PAD1:
            ND_PRINT((ndo, "(pad1)"));
	    break;
	case IP6OPT_PADN:
	    if (len - i < IP6OPT_MINLEN) {
		ND_PRINT((ndo, "(padn: trunc)"));
		goto trunc;
	    }
            ND_PRINT((ndo, "(padn)"));
	    break;
	case IP6OPT_ROUTER_ALERT:
	    if (len - i < IP6OPT_RTALERT_LEN) {
		ND_PRINT((ndo, "(rtalert: trunc)"));
		goto trunc;
	    }
	    if (bp[i + 1] != IP6OPT_RTALERT_LEN - 2) {
		ND_PRINT((ndo, "(rtalert: invalid len %d)", bp[i + 1]));
		goto trunc;
	    }
	    ND_PRINT((ndo, "(rtalert: 0x%04x) ", EXTRACT_16BITS(&bp[i + 2])));
	    break;
	case IP6OPT_JUMBO:
	    if (len - i < IP6OPT_JUMBO_LEN) {
		ND_PRINT((ndo, "(jumbo: trunc)"));
		goto trunc;
	    }
	    if (bp[i + 1] != IP6OPT_JUMBO_LEN - 2) {
		ND_PRINT((ndo, "(jumbo: invalid len %d)", bp[i + 1]));
		goto trunc;
	    }
	    ND_PRINT((ndo, "(jumbo: %u) ", EXTRACT_32BITS(&bp[i + 2])));
	    break;
        case IP6OPT_HOME_ADDRESS:
	    if (len - i < IP6OPT_HOMEADDR_MINLEN) {
		ND_PRINT((ndo, "(homeaddr: trunc)"));
		goto trunc;
	    }
	    if (bp[i + 1] < IP6OPT_HOMEADDR_MINLEN - 2) {
		ND_PRINT((ndo, "(homeaddr: invalid len %d)", bp[i + 1]));
		goto trunc;
	    }
	    ND_PRINT((ndo, "(homeaddr: %s", ip6addr_string(ndo, &bp[i + 2])));
            if (bp[i + 1] > IP6OPT_HOMEADDR_MINLEN - 2) {
		ip6_sopt_print(ndo, &bp[i + IP6OPT_HOMEADDR_MINLEN],
		    (optlen - IP6OPT_HOMEADDR_MINLEN));
	    }
            ND_PRINT((ndo, ")"));
	    break;
	default:
	    if (len - i < IP6OPT_MINLEN) {
		ND_PRINT((ndo, "(type %d: trunc)", bp[i]));
		goto trunc;
	    }
	    ND_PRINT((ndo, "(opt_type 0x%02x: len=%d)", bp[i], bp[i + 1]));
	    break;
	}
    }
    ND_PRINT((ndo, " "));
    return;

trunc:
    ND_PRINT((ndo, "[trunc] "));
}
static void
print_browse(netdissect_options *ndo,
             const u_char *param, int paramlen, const u_char *data, int datalen)
{
    const u_char *maxbuf = data + datalen;
    int command;

    ND_TCHECK(data[0]);
    command = data[0];

    smb_fdata(ndo, param, "BROWSE PACKET\n|Param ", param+paramlen, unicodestr);

    switch (command) {
    case 0xF:
	data = smb_fdata(ndo, data,
	    "BROWSE PACKET:\nType=[B] (LocalMasterAnnouncement)\nUpdateCount=[w]\nRes1=[B]\nAnnounceInterval=[d]\nName=[n2]\nMajorVersion=[B]\nMinorVersion=[B]\nServerType=[W]\nElectionVersion=[w]\nBrowserConstant=[w]\n",
	    maxbuf, unicodestr);
	break;

    case 0x1:
	data = smb_fdata(ndo, data,
	    "BROWSE PACKET:\nType=[B] (HostAnnouncement)\nUpdateCount=[w]\nRes1=[B]\nAnnounceInterval=[d]\nName=[n2]\nMajorVersion=[B]\nMinorVersion=[B]\nServerType=[W]\nElectionVersion=[w]\nBrowserConstant=[w]\n",
	    maxbuf, unicodestr);
	break;

    case 0x2:
	data = smb_fdata(ndo, data,
	    "BROWSE PACKET:\nType=[B] (AnnouncementRequest)\nFlags=[B]\nReplySystemName=[S]\n",
	    maxbuf, unicodestr);
	break;

    case 0xc:
	data = smb_fdata(ndo, data,
	    "BROWSE PACKET:\nType=[B] (WorkgroupAnnouncement)\nUpdateCount=[w]\nRes1=[B]\nAnnounceInterval=[d]\nName=[n2]\nMajorVersion=[B]\nMinorVersion=[B]\nServerType=[W]\nCommentPointer=[W]\nServerName=[S]\n",
	    maxbuf, unicodestr);
	break;

    case 0x8:
	data = smb_fdata(ndo, data,
	    "BROWSE PACKET:\nType=[B] (ElectionFrame)\nElectionVersion=[B]\nOSSummary=[W]\nUptime=[(W, W)]\nServerName=[S]\n",
	    maxbuf, unicodestr);
	break;

    case 0xb:
	data = smb_fdata(ndo, data,
	    "BROWSE PACKET:\nType=[B] (BecomeBackupBrowser)\nName=[S]\n",
	    maxbuf, unicodestr);
	break;

    case 0x9:
	data = smb_fdata(ndo, data,
	    "BROWSE PACKET:\nType=[B] (GetBackupList)\nListCount?=[B]\nToken=[W]\n",
	    maxbuf, unicodestr);
	break;

    case 0xa:
	data = smb_fdata(ndo, data,
	    "BROWSE PACKET:\nType=[B] (BackupListResponse)\nServerCount?=[B]\nToken=[W]\n*Name=[S]\n",
	    maxbuf, unicodestr);
	break;

    case 0xd:
	data = smb_fdata(ndo, data,
	    "BROWSE PACKET:\nType=[B] (MasterAnnouncement)\nMasterName=[S]\n",
	    maxbuf, unicodestr);
	break;

    case 0xe:
	data = smb_fdata(ndo, data,
	    "BROWSE PACKET:\nType=[B] (ResetBrowser)\nOptions=[B]\n", maxbuf, unicodestr);
	break;

    default:
	data = smb_fdata(ndo, data, "Unknown Browser Frame ", maxbuf, unicodestr);
	break;
    }
    return;
trunc:
    ND_PRINT((ndo, "%s", tstr));
}
Example #20
0
static void
nflog_print(struct netdissect_options *ndo, const u_char *p, u_int length, u_int caplen)
{
	const nflog_hdr_t *hdr;
	const nflog_tlv_t *tlv;
	u_int16_t size;

	if (caplen < (int) sizeof(nflog_hdr_t)) {
		ND_PRINT((ndo, "[|nflog]"));
		return;
	}

	if (ndo->ndo_eflag)
		nflog_hdr_print(ndo, p, length);

	length -= sizeof(nflog_hdr_t);
	caplen -= sizeof(nflog_hdr_t);
	hdr = (const nflog_hdr_t *)p;
	p += sizeof(nflog_hdr_t);

	do {
		tlv = (const nflog_tlv_t *) p;
		size = tlv->tlv_length;

		/* wrong size of the packet */
		if (size > length )
			return;

		/* wrong tlv type */
		if (tlv->tlv_type > NFULA_MAX)
			return;

		if (size % 4 != 0)
			size += 4 - size % 4;

		p += size;
		length = length - size;
		caplen = caplen - size;

	} while (tlv->tlv_type != NFULA_PAYLOAD);

	/* dont skip payload just tlv length and type */
	p = p - size + 4;
	length += size - 4;
	caplen += size - 4;

	switch (hdr->nflog_family) {

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

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

	default:
		if (!ndo->ndo_eflag)
			nflog_hdr_print(ndo, (u_char *)hdr,
				length + sizeof(nflog_hdr_t));

		if (!ndo->ndo_suppress_default_print)
			ndo->ndo_default_print(ndo, p, caplen);
		break;
	}
}
Example #21
0
void
dtp_print (netdissect_options *ndo, const u_char *pptr, u_int length)
{
    int type, len;
    const u_char *tptr;

    if (length < DTP_HEADER_LEN)
        goto trunc;

    tptr = pptr;

    if (!ND_TTEST2(*tptr, DTP_HEADER_LEN))
	goto trunc;

    ND_PRINT((ndo, "DTPv%u, length %u",
           (*tptr),
           length));

    /*
     * In non-verbose mode, just print version.
     */
    if (ndo->ndo_vflag < 1) {
	return;
    }

    tptr += DTP_HEADER_LEN;

    while (tptr < (pptr+length)) {

        if (!ND_TTEST2(*tptr, 4))
            goto trunc;

	type = EXTRACT_16BITS(tptr);
        len  = EXTRACT_16BITS(tptr+2);

        /* infinite loop check */
        if (type == 0 || len == 0) {
            return;
        }

        ND_PRINT((ndo, "\n\t%s (0x%04x) TLV, length %u",
               tok2str(dtp_tlv_values, "Unknown", type),
               type, len));

        switch (type) {
	case DTP_DOMAIN_TLV:
		ND_PRINT((ndo, ", %s", tptr+4));
		break;

	case DTP_STATUS_TLV:
	case DTP_DTP_TYPE_TLV:
                ND_PRINT((ndo, ", 0x%x", *(tptr+4)));
                break;

	case DTP_NEIGHBOR_TLV:
                ND_PRINT((ndo, ", %s", etheraddr_string(ndo, tptr+4)));
                break;

        default:
            break;
        }
        tptr += len;
    }

    return;

 trunc:
    ND_PRINT((ndo, "[|dtp]"));
}
Example #22
0
/*
 * Print a single PDU.
 */
static int
rpki_rtr_pdu_print (netdissect_options *ndo, const u_char *tptr, u_int indent)
{
    const rpki_rtr_pdu *pdu_header;
    u_int pdu_type, pdu_len, hexdump;
    const u_char *msg;

    pdu_header = (const rpki_rtr_pdu *)tptr;
    pdu_type = pdu_header->pdu_type;
    pdu_len = EXTRACT_32BITS(pdu_header->length);
    ND_TCHECK2(*tptr, pdu_len);
    hexdump = FALSE;

    ND_PRINT((ndo, "%sRPKI-RTRv%u, %s PDU (%u), length: %u",
	   indent_string(8),
	   pdu_header->version,
	   tok2str(rpki_rtr_pdu_values, "Unknown", pdu_type),
	   pdu_type, pdu_len));

    switch (pdu_type) {

	/*
	 * The following PDUs share the message format.
	 */
    case RPKI_RTR_SERIAL_NOTIFY_PDU:
    case RPKI_RTR_SERIAL_QUERY_PDU:
    case RPKI_RTR_END_OF_DATA_PDU:
        msg = (const u_char *)(pdu_header + 1);
	ND_PRINT((ndo, "%sSession ID: 0x%04x, Serial: %u",
	       indent_string(indent+2),
	       EXTRACT_16BITS(pdu_header->u.session_id),
	       EXTRACT_32BITS(msg)));
	break;

	/*
	 * The following PDUs share the message format.
	 */
    case RPKI_RTR_RESET_QUERY_PDU:
    case RPKI_RTR_CACHE_RESET_PDU:

	/*
	 * Zero payload PDUs.
	 */
	break;

    case RPKI_RTR_CACHE_RESPONSE_PDU:
	ND_PRINT((ndo, "%sSession ID: 0x%04x",
	       indent_string(indent+2),
	       EXTRACT_16BITS(pdu_header->u.session_id)));
	break;

    case RPKI_RTR_IPV4_PREFIX_PDU:
	{
	    const rpki_rtr_pdu_ipv4_prefix *pdu;

	    pdu = (const rpki_rtr_pdu_ipv4_prefix *)tptr;
	    ND_PRINT((ndo, "%sIPv4 Prefix %s/%u-%u, origin-as %u, flags 0x%02x",
		   indent_string(indent+2),
		   ipaddr_string(ndo, pdu->prefix),
		   pdu->prefix_length, pdu->max_length,
		   EXTRACT_32BITS(pdu->as), pdu->flags));
	}
	break;

    case RPKI_RTR_IPV6_PREFIX_PDU:
	{
	    const rpki_rtr_pdu_ipv6_prefix *pdu;

	    pdu = (const rpki_rtr_pdu_ipv6_prefix *)tptr;
	    ND_PRINT((ndo, "%sIPv6 Prefix %s/%u-%u, origin-as %u, flags 0x%02x",
		   indent_string(indent+2),
		   ip6addr_string(ndo, pdu->prefix),
		   pdu->prefix_length, pdu->max_length,
		   EXTRACT_32BITS(pdu->as), pdu->flags));
	}
	break;

    case RPKI_RTR_ERROR_REPORT_PDU:
	{
	    const rpki_rtr_pdu_error_report *pdu;
	    u_int encapsulated_pdu_length, text_length, tlen, error_code;

	    pdu = (const rpki_rtr_pdu_error_report *)tptr;
	    encapsulated_pdu_length = EXTRACT_32BITS(pdu->encapsulated_pdu_length);
	    ND_TCHECK2(*tptr, encapsulated_pdu_length);
	    tlen = pdu_len;

	    error_code = EXTRACT_16BITS(pdu->pdu_header.u.error_code);
	    ND_PRINT((ndo, "%sError code: %s (%u), Encapsulated PDU length: %u",
		   indent_string(indent+2),
		   tok2str(rpki_rtr_error_codes, "Unknown", error_code),
		   error_code, encapsulated_pdu_length));

	    tptr += sizeof(*pdu);
	    tlen -= sizeof(*pdu);

	    /*
	     * Recurse if there is an encapsulated PDU.
	     */
	    if (encapsulated_pdu_length &&
		(encapsulated_pdu_length <= tlen)) {
		ND_PRINT((ndo, "%s-----encapsulated PDU-----", indent_string(indent+4)));
		if (rpki_rtr_pdu_print(ndo, tptr, indent+2))
			goto trunc;
	    }

	    tptr += encapsulated_pdu_length;
	    tlen -= encapsulated_pdu_length;

	    /*
	     * Extract, trail-zero and print the Error message.
	     */
	    text_length = 0;
	    if (tlen > 4) {
		text_length = EXTRACT_32BITS(tptr);
		tptr += 4;
		tlen -= 4;
	    }
	    ND_TCHECK2(*tptr, text_length);
	    if (text_length && (text_length <= tlen )) {
		ND_PRINT((ndo, "%sError text: ", indent_string(indent+2)));
		if (fn_printn(ndo, tptr, text_length, ndo->ndo_snapend))
			goto trunc;
	    }
	}
	break;

    default:

	/*
	 * Unknown data, please hexdump.
	 */
	hexdump = TRUE;
    }

    /* do we also want to see a hex dump ? */
    if (ndo->ndo_vflag > 1 || (ndo->ndo_vflag && hexdump)) {
	print_unknown_data(ndo,tptr,"\n\t  ", pdu_len);
    }
    return 0;

trunc:
    return 1;
}
Example #23
0
static void
pptp_cause_code_print(netdissect_options *ndo,
                      const nd_uint16_t *cause_code)
{
	ND_PRINT(" CAUSE_CODE(%u)", EXTRACT_BE_U_2(*cause_code));
}
Example #24
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(netdissect_options *ndo,
            const u_char *p, u_int length, u_int caplen,
            void (*print_encap_header)(netdissect_options *ndo, 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) {
		ND_PRINT((ndo, "[|ether]"));
		return;
	}

	if (ndo->ndo_eflag) {
		if (print_encap_header != NULL)
			(*print_encap_header)(ndo, encap_header_arg);
		ether_hdr_print(ndo, 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 (!ndo->ndo_eflag) {
				if (print_encap_header != NULL)
					(*print_encap_header)(ndo, encap_header_arg);
				ether_hdr_print(ndo, (u_char *)ep, orig_length);
			}

			if (!ndo->ndo_suppress_default_print)
				ndo->ndo_default_print(ndo, p, caplen);
		}
	} else if (ether_type == ETHERTYPE_8021Q  ||
                ether_type == ETHERTYPE_8021Q9100 ||
                ether_type == ETHERTYPE_8021Q9200 ||
                ether_type == ETHERTYPE_8021QinQ) {
		/*
		 * Print VLAN information, and then go back and process
		 * the enclosed type field.
		 */
		if (caplen < 4 || length < 4) {
			ND_PRINT((ndo, "[|vlan]"));
			return;
		}
	        if (ndo->ndo_eflag) {
	        	u_int16_t tag = EXTRACT_16BITS(p);

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

		ether_type = EXTRACT_16BITS(p + 2);
		if (ndo->ndo_eflag && ether_type > ETHERMTU)
			ND_PRINT((ndo, "ethertype %s, ", tok2str(ethertype_values,"0x%04x", ether_type)));
		p += 4;
		length -= 4;
		caplen -= 4;
		goto recurse;
	} else if (ether_type == ETHERTYPE_JUMBO) {
Example #25
0
static void
pptp_firm_rev_print(netdissect_options *ndo,
                    const nd_uint16_t *firm_rev)
{
	ND_PRINT(" FIRM_REV(%u)", EXTRACT_BE_U_2(*firm_rev));
}
Example #26
0
void
dvmrp_print(netdissect_options *ndo,
            register const u_char *bp, register u_int len)
{
	register const u_char *ep;
	register u_char type;

	ep = (const u_char *)ndo->ndo_snapend;
	if (bp >= ep)
		return;

	ND_TCHECK(bp[1]);
	type = bp[1];

	/* Skip IGMP header */
	bp += 8;
	len -= 8;

	switch (type) {

	case DVMRP_PROBE:
		ND_PRINT((ndo, " Probe"));
		if (ndo->ndo_vflag) {
			if (print_probe(ndo, bp, ep, len) < 0)
				goto trunc;
		}
		break;

	case DVMRP_REPORT:
		ND_PRINT((ndo, " Report"));
		if (ndo->ndo_vflag > 1) {
			if (print_report(ndo, bp, ep, len) < 0)
				goto trunc;
		}
		break;

	case DVMRP_ASK_NEIGHBORS:
		ND_PRINT((ndo, " Ask-neighbors(old)"));
		break;

	case DVMRP_NEIGHBORS:
		ND_PRINT((ndo, " Neighbors(old)"));
		if (print_neighbors(ndo, bp, ep, len) < 0)
			goto trunc;
		break;

	case DVMRP_ASK_NEIGHBORS2:
		ND_PRINT((ndo, " Ask-neighbors2"));
		break;

	case DVMRP_NEIGHBORS2:
		ND_PRINT((ndo, " Neighbors2"));
		/*
		 * extract version and capabilities from IGMP group
		 * address field
		 */
		bp -= 4;
		ND_TCHECK2(bp[0], 4);
		target_level = (bp[0] << 24) | (bp[1] << 16) |
		    (bp[2] << 8) | bp[3];
		bp += 4;
		if (print_neighbors2(ndo, bp, ep, len) < 0)
			goto trunc;
		break;

	case DVMRP_PRUNE:
		ND_PRINT((ndo, " Prune"));
		if (print_prune(ndo, bp) < 0)
			goto trunc;
		break;

	case DVMRP_GRAFT:
		ND_PRINT((ndo, " Graft"));
		if (print_graft(ndo, bp) < 0)
			goto trunc;
		break;

	case DVMRP_GRAFT_ACK:
		ND_PRINT((ndo, " Graft-ACK"));
		if (print_graft_ack(ndo, bp) < 0)
			goto trunc;
		break;

	default:
		ND_PRINT((ndo, " [type %d]", type));
		break;
	}
	return;

trunc:
	ND_PRINT((ndo, "[|dvmrp]"));
	return;
}
Example #27
0
static void
pptp_id_print(netdissect_options *ndo,
              const nd_uint32_t *id)
{
	ND_PRINT(" ID(%u)", EXTRACT_BE_U_4(*id));
}
void
lwapp_control_print(netdissect_options *ndo,
                    const u_char *pptr, u_int len, int has_ap_ident)
{
    const struct lwapp_transport_header *lwapp_trans_header;
    const struct lwapp_control_header *lwapp_control_header;
    const u_char *tptr;
    int  tlen;
    int  msg_tlen;

    tptr=pptr;

    if (has_ap_ident) {
        /* check if enough bytes for AP identity */
        ND_TCHECK2(*tptr, 6);
        lwapp_trans_header = (const struct lwapp_transport_header *)(pptr+6);
    } else {
        lwapp_trans_header = (const struct lwapp_transport_header *)pptr;
    }
    ND_TCHECK(*lwapp_trans_header);

    /*
     * Sanity checking of the header.
     */
    if (LWAPP_EXTRACT_VERSION(lwapp_trans_header->version) != LWAPP_VERSION) {
	ND_PRINT((ndo, "LWAPP version %u packet not supported",
               LWAPP_EXTRACT_VERSION(lwapp_trans_header->version)));
	return;
    }

    /* non-verbose */
    if (ndo->ndo_vflag < 1) {
        ND_PRINT((ndo, "LWAPPv%u, %s frame, Flags [%s], length %u",
               LWAPP_EXTRACT_VERSION(lwapp_trans_header->version),
               LWAPP_EXTRACT_CONTROL_BIT(lwapp_trans_header->version) ? "Control" : "Data",
               bittok2str(lwapp_header_bits_values,"none",(lwapp_trans_header->version)&0x07),
               len));
        return;
    }

    /* ok they seem to want to know everything - lets fully decode it */
    tlen=EXTRACT_16BITS(lwapp_trans_header->length);

    ND_PRINT((ndo, "LWAPPv%u, %s frame, Radio-id %u, Flags [%s], Frag-id %u, length %u",
           LWAPP_EXTRACT_VERSION(lwapp_trans_header->version),
           LWAPP_EXTRACT_CONTROL_BIT(lwapp_trans_header->version) ? "Control" : "Data",
           LWAPP_EXTRACT_RID(lwapp_trans_header->version),
           bittok2str(lwapp_header_bits_values,"none",(lwapp_trans_header->version)&0x07),
	   lwapp_trans_header->frag_id,
	   tlen));

    if (has_ap_ident) {
        ND_PRINT((ndo, "\n\tAP identity: %s", etheraddr_string(ndo, tptr)));
        tptr+=sizeof(const struct lwapp_transport_header)+6;
    } else {
        tptr+=sizeof(const struct lwapp_transport_header);
    }

    while(tlen>0) {

        /* did we capture enough for fully decoding the object header ? */
        ND_TCHECK2(*tptr, sizeof(struct lwapp_control_header));

        lwapp_control_header = (const struct lwapp_control_header *)tptr;
	msg_tlen = EXTRACT_16BITS(lwapp_control_header->len);

	/* print message header */
        ND_PRINT((ndo, "\n\t  Msg type: %s (%u), Seqnum: %u, Msg len: %d, Session: 0x%08x",
               tok2str(lwapp_msg_type_values,"Unknown",lwapp_control_header->msg_type),
               lwapp_control_header->msg_type,
               lwapp_control_header->seq_num,
               msg_tlen,
               EXTRACT_32BITS(lwapp_control_header->session_id)));

        /* did we capture enough for fully decoding the message */
        ND_TCHECK2(*tptr, msg_tlen);

	/* XXX - Decode sub messages for each message */
        switch(lwapp_control_header->msg_type) {
        case LWAPP_MSGTYPE_DISCOVERY_REQUEST:
        case LWAPP_MSGTYPE_DISCOVERY_RESPONSE:
        case LWAPP_MSGTYPE_JOIN_REQUEST:
        case LWAPP_MSGTYPE_JOIN_RESPONSE:
        case LWAPP_MSGTYPE_JOIN_ACK:
        case LWAPP_MSGTYPE_JOIN_CONFIRM:
        case LWAPP_MSGTYPE_CONFIGURE_REQUEST:
        case LWAPP_MSGTYPE_CONFIGURE_RESPONSE:
        case LWAPP_MSGTYPE_CONF_UPDATE_REQUEST:
        case LWAPP_MSGTYPE_CONF_UPDATE_RESPONSE:
        case LWAPP_MSGTYPE_WTP_EVENT_REQUEST:
        case LWAPP_MSGTYPE_WTP_EVENT_RESPONSE:
        case LWAPP_MSGTYPE_CHANGE_STATE_EVENT_REQUEST:
        case LWAPP_MSGTYPE_CHANGE_STATE_EVENT_RESPONSE:
        case LWAPP_MSGTYPE_ECHO_REQUEST:
        case LWAPP_MSGTYPE_ECHO_RESPONSE:
        case LWAPP_MSGTYPE_IMAGE_DATA_REQUEST:
        case LWAPP_MSGTYPE_IMAGE_DATA_RESPONSE:
        case LWAPP_MSGTYPE_RESET_REQUEST:
        case LWAPP_MSGTYPE_RESET_RESPONSE:
        case LWAPP_MSGTYPE_KEY_UPDATE_REQUEST:
        case LWAPP_MSGTYPE_KEY_UPDATE_RESPONSE:
        case LWAPP_MSGTYPE_PRIMARY_DISCOVERY_REQUEST:
        case LWAPP_MSGTYPE_PRIMARY_DISCOVERY_RESPONSE:
        case LWAPP_MSGTYPE_DATA_TRANSFER_REQUEST:
        case LWAPP_MSGTYPE_DATA_TRANSFER_RESPONSE:
        case LWAPP_MSGTYPE_CLEAR_CONFIG_INDICATION:
        case LWAPP_MSGTYPE_WLAN_CONFIG_REQUEST:
        case LWAPP_MSGTYPE_WLAN_CONFIG_RESPONSE:
        case LWAPP_MSGTYPE_MOBILE_CONFIG_REQUEST:
        case LWAPP_MSGTYPE_MOBILE_CONFIG_RESPONSE:
        default:
            break;
        }

        tptr += sizeof(struct lwapp_control_header) + msg_tlen;
        tlen -= sizeof(struct lwapp_control_header) + msg_tlen;
    }
    return;

 trunc:
    ND_PRINT((ndo, "\n\t\t packet exceeded snapshot"));
}
Example #29
0
static void
pptp_peer_call_id_print(netdissect_options *ndo,
                        const nd_uint16_t *peer_call_id)
{
	ND_PRINT(" PEER_CALL_ID(%u)", EXTRACT_BE_U_2(*peer_call_id));
}
Example #30
0
void
arp_print(netdissect_options *ndo,
	  const u_char *bp, u_int length, u_int caplen)
{
	const struct arp_pkthdr *ap;
	u_short pro, hrd, op, linkaddr;

	ap = (const struct arp_pkthdr *)bp;
	ND_TCHECK(*ap);

	hrd = HRD(ap);
	pro = PRO(ap);
	op = OP(ap);

        
        /* if its ATM then call the ATM ARP printer
           for Frame-relay ARP most of the fields
           are similar to Ethernet so overload the Ethernet Printer
           and set the linkaddr type for linkaddr_string() accordingly */

        switch(hrd) {
        case ARPHRD_ATM2225:
            atmarp_print(ndo, bp, length, caplen);
            return;
        case ARPHRD_FRELAY:
            linkaddr = LINKADDR_FRELAY;
            break;
        default:
            linkaddr = LINKADDR_ETHER;
            break;
	}

	if (!ND_TTEST2(*ar_tpa(ap), PROTO_LEN(ap))) {
		ND_PRINT((ndo, "[|ARP]"));
		ND_DEFAULTPRINT((const u_char *)ap, length);
		return;
	}

        if (!ndo->ndo_eflag) {
            ND_PRINT((ndo, "ARP, "));
        }

        /* print hardware type/len and proto type/len */
        if ((pro != ETHERTYPE_IP && pro != ETHERTYPE_TRAIL) ||
	    PROTO_LEN(ap) != 4 ||
            HRD_LEN(ap) == 0 ||
            ndo->ndo_vflag) {
            ND_PRINT((ndo, "%s (len %u), %s (len %u)",
                      tok2str(arphrd_values, "Unknown Hardware (%u)", hrd),
                      HRD_LEN(ap),
                      tok2str(ethertype_values, "Unknown Protocol (0x%04x)", pro),
                      PROTO_LEN(ap)));

            /* don't know know about the address formats */
            if (!ndo->ndo_vflag) {
                goto out;
            }
	}

        /* print operation */
        printf("%s%s ",
               ndo->ndo_vflag ? ", " : "", 
               tok2str(arpop_values, "Unknown (%u)", op));

	switch (op) {

	case ARPOP_REQUEST:
		ND_PRINT((ndo, "who-has %s", ipaddr_string(TPA(ap))));
		if (memcmp((const char *)ezero, (const char *)THA(ap), HRD_LEN(ap)) != 0)
			ND_PRINT((ndo, " (%s)",
				  linkaddr_string(THA(ap), linkaddr, HRD_LEN(ap))));
		ND_PRINT((ndo, " tell %s", ipaddr_string(SPA(ap))));
		break;

	case ARPOP_REPLY:
		ND_PRINT((ndo, "%s is-at %s",
                          ipaddr_string(SPA(ap)),
                          linkaddr_string(SHA(ap), linkaddr, HRD_LEN(ap))));
		break;

	case ARPOP_REVREQUEST:
		ND_PRINT((ndo, "who-is %s tell %s",
			  linkaddr_string(THA(ap), linkaddr, HRD_LEN(ap)),
			  linkaddr_string(SHA(ap), linkaddr, HRD_LEN(ap))));
		break;

	case ARPOP_REVREPLY:
		ND_PRINT((ndo, "%s at %s",
			  linkaddr_string(THA(ap), linkaddr, HRD_LEN(ap)),
			  ipaddr_string(TPA(ap))));
		break;

	case ARPOP_INVREQUEST:
		ND_PRINT((ndo, "who-is %s tell %s",
			  linkaddr_string(THA(ap), linkaddr, HRD_LEN(ap)),
			  linkaddr_string(SHA(ap), linkaddr, HRD_LEN(ap))));
		break;

	case ARPOP_INVREPLY:
		ND_PRINT((ndo,"%s at %s",
			  linkaddr_string(THA(ap), linkaddr, HRD_LEN(ap)),
			  ipaddr_string(TPA(ap))));
		break;

	default:
		ND_DEFAULTPRINT((const u_char *)ap, caplen);
		return;
	}

 out:
        ND_PRINT((ndo, ", length %u", length));

	return;
trunc:
	ND_PRINT((ndo, "[|ARP]"));
}