Exemplo n.º 1
0
/*
 * Print RRCP requests
 */
void
rrcp_print(netdissect_options *ndo,
	  const u_char *cp,
	  u_int length _U_,
	  const struct lladdr_info *src,
	  const struct lladdr_info *dst)
{
	uint8_t rrcp_proto;
	uint8_t rrcp_opcode;

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

trunc:
	nd_print_trunc(ndo);
}
Exemplo n.º 2
0
void
lwapp_data_print(netdissect_options *ndo,
                 const u_char *pptr, u_int len)
{
    const struct lwapp_transport_header *lwapp_trans_header;
    const u_char *tptr;
    u_int tlen;
    u_int version;

    tptr=pptr;

    /* check if enough bytes for AP identity */
    ND_TCHECK_6(tptr);
    lwapp_trans_header = (const struct lwapp_transport_header *)pptr;
    ND_TCHECK_SIZE(lwapp_trans_header);
    version = EXTRACT_U_1(lwapp_trans_header->version);

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

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

    /* ok they seem to want to know everything - lets fully decode it */
    tlen=EXTRACT_BE_U_2(lwapp_trans_header->length);
    if (tlen < sizeof(struct lwapp_transport_header)) {
        ND_PRINT("LWAPPv%u, %s frame, Radio-id  %u, Flags [%s], length %u < transport header length",
               LWAPP_EXTRACT_VERSION(version),
               LWAPP_EXTRACT_CONTROL_BIT(version) ? "Control" : "Data",
               LWAPP_EXTRACT_RID(version),
               bittok2str(lwapp_header_bits_values,"none",version&0x07),
               tlen);
        return;
    }

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

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

    /* FIX - An IEEE 802.11 frame follows - hexdump for now */
    print_unknown_data(ndo, tptr, "\n\t", tlen);

    return;

trunc:
    ND_PRINT("%s", data_tstr);
}
Exemplo n.º 3
0
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;
    uint8_t version;
    u_int tlen;
    u_int msg_type, msg_tlen;

    tptr=pptr;

    if (has_ap_ident) {
        /* check if enough bytes for AP identity */
        ND_TCHECK_6(tptr);
        lwapp_trans_header = (const struct lwapp_transport_header *)(pptr+6);
    } else {
        lwapp_trans_header = (const struct lwapp_transport_header *)pptr;
    }
    ND_TCHECK_SIZE(lwapp_trans_header);
    version = EXTRACT_U_1(lwapp_trans_header->version);

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

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

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

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

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

    while(tlen!=0) {

        /* did we capture enough for fully decoding the object header ? */
        ND_TCHECK_LEN(tptr, sizeof(struct lwapp_control_header));
        if (tlen < sizeof(struct lwapp_control_header)) {
            ND_PRINT("\n\t  Msg goes past end of PDU");
            break;
        }

        lwapp_control_header = (const struct lwapp_control_header *)tptr;
	msg_tlen = EXTRACT_BE_U_2(lwapp_control_header->len);
        if (tlen < sizeof(struct lwapp_control_header) + msg_tlen) {
            ND_PRINT("\n\t  Msg goes past end of PDU");
            break;
        }

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

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

	/* XXX - Decode sub messages for each message */
        switch(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("%s", control_tstr);
}
Exemplo n.º 4
0
/*
 * Print bootp requests
 */
void
bootp_print(netdissect_options *ndo,
	    const u_char *cp, u_int length)
{
	const struct bootp *bp;
	static const u_char vm_cmu[4] = VM_CMU;
	static const u_char vm_rfc1048[4] = VM_RFC1048;
	uint8_t bp_op, bp_htype, bp_hlen;

	ndo->ndo_protocol = "bootp";
	bp = (const struct bootp *)cp;
	ND_TCHECK_1(bp->bp_op);
	bp_op = EXTRACT_U_1(bp->bp_op);
	ND_PRINT("BOOTP/DHCP, %s",
		  tok2str(bootp_op_values, "unknown (0x%02x)", bp_op));

	ND_TCHECK_1(bp->bp_hlen);
	bp_htype = EXTRACT_U_1(bp->bp_htype);
	bp_hlen = EXTRACT_U_1(bp->bp_hlen);
	if (bp_htype == 1 && bp_hlen == 6 && bp_op == BOOTPREQUEST) {
		ND_TCHECK_6(bp->bp_chaddr);
		ND_PRINT(" from %s", etheraddr_string(ndo, bp->bp_chaddr));
	}

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

	if (!ndo->ndo_vflag)
		return;

	ND_TCHECK_2(bp->bp_secs);

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

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

	/* Only print interesting fields */
	if (EXTRACT_U_1(bp->bp_hops))
		ND_PRINT(", hops %u", EXTRACT_U_1(bp->bp_hops));
	if (EXTRACT_BE_U_4(bp->bp_xid))
		ND_PRINT(", xid 0x%x", EXTRACT_BE_U_4(bp->bp_xid));
	if (EXTRACT_BE_U_2(bp->bp_secs))
		ND_PRINT(", secs %u", EXTRACT_BE_U_2(bp->bp_secs));

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

	/* Client's ip address */
	ND_TCHECK_4(bp->bp_ciaddr);
	if (EXTRACT_IPV4_TO_NETWORK_ORDER(bp->bp_ciaddr))
		ND_PRINT("\n\t  Client-IP %s", ipaddr_string(ndo, bp->bp_ciaddr));

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

	/* Server's ip address */
	ND_TCHECK_4(bp->bp_siaddr);
	if (EXTRACT_IPV4_TO_NETWORK_ORDER(bp->bp_siaddr))
		ND_PRINT("\n\t  Server-IP %s", ipaddr_string(ndo, bp->bp_siaddr));

	/* Gateway's ip address */
	ND_TCHECK_4(bp->bp_giaddr);
	if (EXTRACT_IPV4_TO_NETWORK_ORDER(bp->bp_giaddr))
		ND_PRINT("\n\t  Gateway-IP %s", ipaddr_string(ndo, bp->bp_giaddr));

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

	ND_TCHECK_1(bp->bp_sname);		/* check first char only */
	if (EXTRACT_U_1(bp->bp_sname)) {
		ND_PRINT("\n\t  sname \"");
		if (nd_printztn(ndo, bp->bp_sname, (u_int)sizeof(bp->bp_sname),
				ndo->ndo_snapend) == 0) {
			ND_PRINT("\"");
			nd_print_trunc(ndo);
			return;
		}
		ND_PRINT("\"");
	}
	ND_TCHECK_1(bp->bp_file);		/* check first char only */
	if (EXTRACT_U_1(bp->bp_file)) {
		ND_PRINT("\n\t  file \"");
		if (nd_printztn(ndo, bp->bp_file, (u_int)sizeof(bp->bp_file),
				ndo->ndo_snapend) == 0) {
			ND_PRINT("\"");
			nd_print_trunc(ndo);
			return;
		}
		ND_PRINT("\"");
	}

	/* Decode the vendor buffer */
	ND_TCHECK_4(bp->bp_vend);
	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_BE_U_4(bp->bp_vend);
		if (ul != 0)
			ND_PRINT("\n\t  Vendor-#0x%x", ul);
	}

	return;
trunc:
	nd_print_trunc(ndo);
}
Exemplo n.º 5
0
/* LCP config options */
static u_int
print_lcp_config_options(netdissect_options *ndo,
                         const u_char *p, u_int length)
{
	u_int opt, len;

	if (length < 2)
		return 0;
	ND_TCHECK_2(p);
	opt = EXTRACT_U_1(p);
	len = EXTRACT_U_1(p + 1);
	if (length < len)
		return 0;
	if (len < 2) {
		if (opt < NUM_LCPOPTS)
			ND_PRINT("\n\t  %s Option (0x%02x), length %u (length bogus, should be >= 2)",
			          lcpconfopts[opt], opt, len);
		else
			ND_PRINT("\n\tunknown LCP option 0x%02x", opt);
		return 0;
	}
	if (opt < NUM_LCPOPTS)
		ND_PRINT("\n\t  %s Option (0x%02x), length %u", lcpconfopts[opt], opt, len);
	else {
		ND_PRINT("\n\tunknown LCP option 0x%02x", opt);
		return len;
	}

	switch (opt) {
	case LCPOPT_VEXT:
		if (len < 6) {
			ND_PRINT(" (length bogus, should be >= 6)");
			return len;
		}
		ND_TCHECK_3(p + 2);
		ND_PRINT(": Vendor: %s (%u)",
			tok2str(oui_values,"Unknown",EXTRACT_BE_U_3(p + 2)),
			EXTRACT_BE_U_3(p + 2));
#if 0
		ND_TCHECK_1(p + 5);
		ND_PRINT(", kind: 0x%02x", EXTRACT_U_1(p + 5));
		ND_PRINT(", Value: 0x");
		for (i = 0; i < len - 6; i++) {
			ND_TCHECK_1(p + 6 + i);
			ND_PRINT("%02x", EXTRACT_U_1(p + 6 + i));
		}
#endif
		break;
	case LCPOPT_MRU:
		if (len != 4) {
			ND_PRINT(" (length bogus, should be = 4)");
			return len;
		}
		ND_TCHECK_2(p + 2);
		ND_PRINT(": %u", EXTRACT_BE_U_2(p + 2));
		break;
	case LCPOPT_ACCM:
		if (len != 6) {
			ND_PRINT(" (length bogus, should be = 6)");
			return len;
		}
		ND_TCHECK_4(p + 2);
		ND_PRINT(": 0x%08x", EXTRACT_BE_U_4(p + 2));
		break;
	case LCPOPT_AP:
		if (len < 4) {
			ND_PRINT(" (length bogus, should be >= 4)");
			return len;
		}
		ND_TCHECK_2(p + 2);
		ND_PRINT(": %s", tok2str(ppptype2str, "Unknown Auth Proto (0x04x)", EXTRACT_BE_U_2(p + 2)));

		switch (EXTRACT_BE_U_2(p + 2)) {
		case PPP_CHAP:
			ND_TCHECK_1(p + 4);
			ND_PRINT(", %s", tok2str(authalg_values, "Unknown Auth Alg %u", EXTRACT_U_1(p + 4)));
			break;
		case PPP_PAP: /* fall through */
		case PPP_EAP:
		case PPP_SPAP:
		case PPP_SPAP_OLD:
                        break;
		default:
			print_unknown_data(ndo, p, "\n\t", len);
		}
		break;
	case LCPOPT_QP:
		if (len < 4) {
			ND_PRINT(" (length bogus, should be >= 4)");
			return 0;
		}
		ND_TCHECK_2(p + 2);
		if (EXTRACT_BE_U_2(p + 2) == PPP_LQM)
			ND_PRINT(": LQR");
		else
			ND_PRINT(": unknown");
		break;
	case LCPOPT_MN:
		if (len != 6) {
			ND_PRINT(" (length bogus, should be = 6)");
			return 0;
		}
		ND_TCHECK_4(p + 2);
		ND_PRINT(": 0x%08x", EXTRACT_BE_U_4(p + 2));
		break;
	case LCPOPT_PFC:
		break;
	case LCPOPT_ACFC:
		break;
	case LCPOPT_LD:
		if (len != 4) {
			ND_PRINT(" (length bogus, should be = 4)");
			return 0;
		}
		ND_TCHECK_2(p + 2);
		ND_PRINT(": 0x%04x", EXTRACT_BE_U_2(p + 2));
		break;
	case LCPOPT_CBACK:
		if (len < 3) {
			ND_PRINT(" (length bogus, should be >= 3)");
			return 0;
		}
		ND_PRINT(": ");
		ND_TCHECK_1(p + 2);
		ND_PRINT(": Callback Operation %s (%u)",
                       tok2str(ppp_callback_values, "Unknown", EXTRACT_U_1(p + 2)),
                       EXTRACT_U_1(p + 2));
		break;
	case LCPOPT_MLMRRU:
		if (len != 4) {
			ND_PRINT(" (length bogus, should be = 4)");
			return 0;
		}
		ND_TCHECK_2(p + 2);
		ND_PRINT(": %u", EXTRACT_BE_U_2(p + 2));
		break;
	case LCPOPT_MLED:
		if (len < 3) {
			ND_PRINT(" (length bogus, should be >= 3)");
			return 0;
		}
		ND_TCHECK_1(p + 2);
		switch (EXTRACT_U_1(p + 2)) {		/* class */
		case MEDCLASS_NULL:
			ND_PRINT(": Null");
			break;
		case MEDCLASS_LOCAL:
			ND_PRINT(": Local"); /* XXX */
			break;
		case MEDCLASS_IPV4:
			if (len != 7) {
				ND_PRINT(" (length bogus, should be = 7)");
				return 0;
			}
			ND_TCHECK_4(p + 3);
			ND_PRINT(": IPv4 %s", ipaddr_string(ndo, p + 3));
			break;
		case MEDCLASS_MAC:
			if (len != 9) {
				ND_PRINT(" (length bogus, should be = 9)");
				return 0;
			}
			ND_TCHECK_6(p + 3);
			ND_PRINT(": MAC %s", etheraddr_string(ndo, p + 3));
			break;
		case MEDCLASS_MNB:
			ND_PRINT(": Magic-Num-Block"); /* XXX */
			break;
		case MEDCLASS_PSNDN:
			ND_PRINT(": PSNDN"); /* XXX */
			break;
		default:
			ND_PRINT(": Unknown class %u", EXTRACT_U_1(p + 2));
			break;
		}
		break;

/* XXX: to be supported */
#if 0
	case LCPOPT_DEP6:
	case LCPOPT_FCSALT:
	case LCPOPT_SDP:
	case LCPOPT_NUMMODE:
	case LCPOPT_DEP12:
	case LCPOPT_DEP14:
	case LCPOPT_DEP15:
	case LCPOPT_DEP16:
        case LCPOPT_MLSSNHF:
	case LCPOPT_PROP:
	case LCPOPT_DCEID:
	case LCPOPT_MPP:
	case LCPOPT_LCPAOPT:
	case LCPOPT_COBS:
	case LCPOPT_PE:
	case LCPOPT_MLHF:
	case LCPOPT_I18N:
	case LCPOPT_SDLOS:
	case LCPOPT_PPPMUX:
		break;
#endif
	default:
		/*
		 * Unknown option; dump it as raw bytes now if we're
		 * not going to do so below.
		 */
		if (ndo->ndo_vflag < 2)
			print_unknown_data(ndo, p + 2, "\n\t    ", len - 2);
		break;
	}

	if (ndo->ndo_vflag > 1)
		print_unknown_data(ndo, p + 2, "\n\t    ", len - 2); /* exclude TLV header */

	return len;

trunc:
	ND_PRINT("[|lcp]");
	return 0;
}