Example #1
0
u_int
chdlc_print(netdissect_options *ndo, register const u_char *p, u_int length)
{
	u_int proto;
	const u_char *bp = p;

	if (length < CHDLC_HDRLEN)
		goto trunc;
	ND_TCHECK2(*p, CHDLC_HDRLEN);
	proto = EXTRACT_16BITS(&p[2]);
	if (ndo->ndo_eflag) {
                ND_PRINT((ndo, "%s, ethertype %s (0x%04x), length %u: ",
                       tok2str(chdlc_cast_values, "0x%02x", p[0]),
                       tok2str(ethertype_values, "Unknown", proto),
                       proto,
                       length));
	}

	length -= CHDLC_HDRLEN;
	p += CHDLC_HDRLEN;

	switch (proto) {
	case ETHERTYPE_IP:
		ip_print(ndo, p, length);
		break;
	case ETHERTYPE_IPV6:
		ip6_print(ndo, p, length);
		break;
	case CHDLC_TYPE_SLARP:
		chdlc_slarp_print(ndo, p, length);
		break;
#if 0
	case CHDLC_TYPE_CDP:
		chdlc_cdp_print(p, length);
		break;
#endif
        case ETHERTYPE_MPLS:
        case ETHERTYPE_MPLS_MULTI:
                mpls_print(ndo, p, length);
		break;
        case ETHERTYPE_ISO:
                /* is the fudge byte set ? lets verify by spotting ISO headers */
                if (length < 2)
                    goto trunc;
                ND_TCHECK_16BITS(p);
                if (*(p+1) == 0x81 ||
                    *(p+1) == 0x82 ||
                    *(p+1) == 0x83)
                    isoclns_print(ndo, p + 1, length - 1);
                else
                    isoclns_print(ndo, p, length);
                break;
	default:
                if (!ndo->ndo_eflag)
                        ND_PRINT((ndo, "unknown CHDLC protocol (0x%04x)", proto));
                break;
	}

	return (CHDLC_HDRLEN);

trunc:
	ND_PRINT((ndo, "[|chdlc]"));
	return ndo->ndo_snapend - bp;
}
Example #2
0
static int dccp_print_option(netdissect_options *ndo, const u_char *option, u_int hlen)
{
	uint8_t optlen, i;

	ND_TCHECK(*option);

	if (*option >= 32) {
		ND_TCHECK(*(option+1));
		optlen = *(option +1);
		if (optlen < 2) {
			if (*option >= 128)
				ND_PRINT((ndo, "CCID option %u optlen too short", *option));
			else
				ND_PRINT((ndo, "%s optlen too short",
					  tok2str(dccp_option_values, "Option %u", *option)));
			return 0;
		}
	} else
		optlen = 1;

	if (hlen < optlen) {
		if (*option >= 128)
			ND_PRINT((ndo, "CCID option %u optlen goes past header length",
				  *option));
		else
			ND_PRINT((ndo, "%s optlen goes past header length",
				  tok2str(dccp_option_values, "Option %u", *option)));
		return 0;
	}
	ND_TCHECK2(*option, optlen);

	if (*option >= 128) {
		ND_PRINT((ndo, "CCID option %d", *option));
		switch (optlen) {
			case 4:
				ND_PRINT((ndo, " %u", EXTRACT_16BITS(option + 2)));
				break;
			case 6:
				ND_PRINT((ndo, " %u", EXTRACT_32BITS(option + 2)));
				break;
			default:
				break;
		}
	} else {
		ND_PRINT((ndo, "%s", tok2str(dccp_option_values, "Option %u", *option)));
		switch (*option) {
		case 32:
		case 33:
		case 34:
		case 35:
			if (optlen < 3) {
				ND_PRINT((ndo, " optlen too short"));
				return optlen;
			}
			if (*(option + 2) < 10){
				ND_PRINT((ndo, " %s", dccp_feature_nums[*(option + 2)]));
				for (i = 0; i < optlen - 3; i++)
					ND_PRINT((ndo, " %d", *(option + 3 + i)));
			}
			break;
		case 36:
			if (optlen > 2) {
				ND_PRINT((ndo, " 0x"));
				for (i = 0; i < optlen - 2; i++)
					ND_PRINT((ndo, "%02x", *(option + 2 + i)));
			}
			break;
		case 37:
			for (i = 0; i < optlen - 2; i++)
				ND_PRINT((ndo, " %d", *(option + 2 + i)));
			break;
		case 38:
			if (optlen > 2) {
				ND_PRINT((ndo, " 0x"));
				for (i = 0; i < optlen - 2; i++)
					ND_PRINT((ndo, "%02x", *(option + 2 + i)));
			}
			break;
		case 39:
			if (optlen > 2) {
				ND_PRINT((ndo, " 0x"));
				for (i = 0; i < optlen - 2; i++)
					ND_PRINT((ndo, "%02x", *(option + 2 + i)));
			}
			break;
		case 40:
			if (optlen > 2) {
				ND_PRINT((ndo, " 0x"));
				for (i = 0; i < optlen - 2; i++)
					ND_PRINT((ndo, "%02x", *(option + 2 + i)));
			}
			break;
		case 41:
			if (optlen == 4)
				ND_PRINT((ndo, " %u", EXTRACT_32BITS(option + 2)));
			else
				ND_PRINT((ndo, " optlen != 4"));
			break;
		case 42:
			if (optlen == 4)
				ND_PRINT((ndo, " %u", EXTRACT_32BITS(option + 2)));
			else
				ND_PRINT((ndo, " optlen != 4"));
			break;
		case 43:
			if (optlen == 6)
				ND_PRINT((ndo, " %u", EXTRACT_32BITS(option + 2)));
			else if (optlen == 4)
				ND_PRINT((ndo, " %u", EXTRACT_16BITS(option + 2)));
			else
				ND_PRINT((ndo, " optlen != 4 or 6"));
			break;
		case 44:
			if (optlen > 2) {
				ND_PRINT((ndo, " "));
				for (i = 0; i < optlen - 2; i++)
					ND_PRINT((ndo, "%02x", *(option + 2 + i)));
			}
			break;
		}
	}

	return optlen;
trunc:
	ND_PRINT((ndo, "%s", tstr));
	return 0;
}
Example #3
0
int
ldp_tlv_print(register const u_char *tptr) {

    struct ldp_tlv_header {
        u_int8_t type[2];
        u_int8_t length[2];
    };

    const struct ldp_tlv_header *ldp_tlv_header;
    u_short tlv_type,tlv_len,tlv_tlen,af,ft_flags;
    u_char fec_type;
    u_int ui,vc_info_len, vc_info_tlv_type, vc_info_tlv_len,idx;
    char buf[100];
    int i;

    ldp_tlv_header = (const struct ldp_tlv_header *)tptr;    
    tlv_len=EXTRACT_16BITS(ldp_tlv_header->length);
    tlv_tlen=tlv_len;
    tlv_type=LDP_MASK_TLV_TYPE(EXTRACT_16BITS(ldp_tlv_header->type));

    /* FIXME vendor private / experimental check */
    printf("\n\t    %s TLV (0x%04x), length: %u, Flags: [%s and %s forward if unknown]",
           tok2str(ldp_tlv_values,
                   "Unknown",
                   tlv_type),
           tlv_type,
           tlv_len,
           LDP_MASK_U_BIT(EXTRACT_16BITS(&ldp_tlv_header->type)) ? "continue processing" : "ignore",
           LDP_MASK_F_BIT(EXTRACT_16BITS(&ldp_tlv_header->type)) ? "do" : "don't");

    tptr+=sizeof(struct ldp_tlv_header);

    switch(tlv_type) {

    case LDP_TLV_COMMON_HELLO:
        TLV_TCHECK(4);
        printf("\n\t      Hold Time: %us, Flags: [%s Hello%s]",
               EXTRACT_16BITS(tptr),
               (EXTRACT_16BITS(tptr+2)&0x8000) ? "Targeted" : "Link",
               (EXTRACT_16BITS(tptr+2)&0x4000) ? ", Request for targeted Hellos" : "");
        break;

    case LDP_TLV_IPV4_TRANSPORT_ADDR:
        TLV_TCHECK(4);
        printf("\n\t      IPv4 Transport Address: %s", ipaddr_string(tptr));
        break;
#ifdef INET6
    case LDP_TLV_IPV6_TRANSPORT_ADDR:
        TLV_TCHECK(16);
        printf("\n\t      IPv6 Transport Address: %s", ip6addr_string(tptr));
        break;
#endif
    case LDP_TLV_CONFIG_SEQ_NUMBER:
        TLV_TCHECK(4);
        printf("\n\t      Sequence Number: %u", EXTRACT_32BITS(tptr));
        break;

    case LDP_TLV_ADDRESS_LIST:
        TLV_TCHECK(LDP_TLV_ADDRESS_LIST_AFNUM_LEN);
	af = EXTRACT_16BITS(tptr);
	tptr+=LDP_TLV_ADDRESS_LIST_AFNUM_LEN;
        tlv_tlen -= LDP_TLV_ADDRESS_LIST_AFNUM_LEN;
	printf("\n\t      Address Family: %s, addresses",
               tok2str(af_values, "Unknown (%u)", af));
        switch (af) {
        case AFNUM_INET:
	    while(tlv_tlen >= sizeof(struct in_addr)) {
		TCHECK2(*tptr, sizeof(struct in_addr));
		printf(" %s",ipaddr_string(tptr));
		tlv_tlen-=sizeof(struct in_addr);
		tptr+=sizeof(struct in_addr);                
	    }
            break;
#ifdef INET6
        case AFNUM_INET6:
	    while(tlv_tlen >= sizeof(struct in6_addr)) {
		TCHECK2(*tptr, sizeof(struct in6_addr));
		printf(" %s",ip6addr_string(tptr));
		tlv_tlen-=sizeof(struct in6_addr);
		tptr+=sizeof(struct in6_addr);                
	    }
            break;
#endif
        default:
            /* unknown AF */
            break;
        }
	break;

    case LDP_TLV_COMMON_SESSION:
	TLV_TCHECK(8);
	printf("\n\t      Version: %u, Keepalive: %us, Flags: [Downstream %s, Loop Detection %s]",
	       EXTRACT_16BITS(tptr), EXTRACT_16BITS(tptr+2),
	       (EXTRACT_16BITS(tptr+6)&0x8000) ? "On Demand" : "Unsolicited",
	       (EXTRACT_16BITS(tptr+6)&0x4000) ? "Enabled" : "Disabled"
	       );
	break;

    case LDP_TLV_FEC:
        TLV_TCHECK(1);
        fec_type = *tptr;
	printf("\n\t      %s FEC (0x%02x)",
	       tok2str(ldp_fec_values, "Unknown", fec_type),
	       fec_type);

	tptr+=1;
	tlv_tlen-=1;
	switch(fec_type) {

	case LDP_FEC_WILDCARD:
	    break;
	case LDP_FEC_PREFIX:
	    TLV_TCHECK(2);
	    af = EXTRACT_16BITS(tptr);
	    tptr+=LDP_TLV_ADDRESS_LIST_AFNUM_LEN;
	    tlv_tlen-=LDP_TLV_ADDRESS_LIST_AFNUM_LEN;
	    if (af == AFNUM_INET) {
		i=decode_prefix4(tptr,tlv_tlen,buf,sizeof(buf));
		if (i == -2)
		    goto trunc;
		if (i == -3)
		    printf(": IPv4 prefix (goes past end of TLV)");
		else if (i == -1)
		    printf(": IPv4 prefix (invalid length)");
		else
		    printf(": IPv4 prefix %s",buf);
	    }
#ifdef INET6
	    else if (af == AFNUM_INET6) {
		i=decode_prefix6(tptr,tlv_tlen,buf,sizeof(buf));
		if (i == -2)
		    goto trunc;
		if (i == -3)
		    printf(": IPv4 prefix (goes past end of TLV)");
		else if (i == -1)
		    printf(": IPv6 prefix (invalid length)");
		else
		    printf(": IPv6 prefix %s",buf);
	    }
#endif
	    else
		printf(": Address family %u prefix", af);
	    break;
	case LDP_FEC_HOSTADDRESS:
	    break;
	case LDP_FEC_MARTINI_VC:
            /*
	     * According to RFC 4908, the VC info Length field can be zero,
	     * in which case not only are there no interface parameters,
	     * there's no VC ID.
	     */
            TLV_TCHECK(7);
            vc_info_len = *(tptr+2);

            if (vc_info_len == 0) {
                printf(": %s, %scontrol word, group-ID %u, VC-info-length: %u",
                       tok2str(l2vpn_encaps_values, "Unknown", EXTRACT_16BITS(tptr)&0x7fff),
                       EXTRACT_16BITS(tptr)&0x8000 ? "" : "no ",
                       EXTRACT_32BITS(tptr+3),
                       vc_info_len);
                break;
            }

            /* Make sure we have the VC ID as well */
            TLV_TCHECK(11);
	    printf(": %s, %scontrol word, group-ID %u, VC-ID %u, VC-info-length: %u",
		   tok2str(l2vpn_encaps_values, "Unknown", EXTRACT_16BITS(tptr)&0x7fff),
		   EXTRACT_16BITS(tptr)&0x8000 ? "" : "no ",
                   EXTRACT_32BITS(tptr+3),
		   EXTRACT_32BITS(tptr+7),
                   vc_info_len);
            if (vc_info_len < 4)
                goto trunc; /* minimum 4, for the VC ID */
            vc_info_len -= 4; /* subtract out the VC ID, giving the length of the interface parameters */

            /* Skip past the fixed information and the VC ID */
            tptr+=11;
            tlv_tlen-=11;
            TLV_TCHECK(vc_info_len);

            while (vc_info_len > 2) {
                vc_info_tlv_type = *tptr;
                vc_info_tlv_len = *(tptr+1);
                if (vc_info_tlv_len < 2)
                    break;
                if (vc_info_len < vc_info_tlv_len)
                    break;

                printf("\n\t\tInterface Parameter: %s (0x%02x), len %u",
                       tok2str(ldp_fec_martini_ifparm_values,"Unknown",vc_info_tlv_type),
                       vc_info_tlv_type,
                       vc_info_tlv_len);

                switch(vc_info_tlv_type) {
                case LDP_FEC_MARTINI_IFPARM_MTU:
                    printf(": %u",EXTRACT_16BITS(tptr+2));
                    break;

                case LDP_FEC_MARTINI_IFPARM_DESC:
                    printf(": ");
                    for (idx = 2; idx < vc_info_tlv_len; idx++)
                        safeputchar(*(tptr+idx));
                    break;

                case LDP_FEC_MARTINI_IFPARM_VCCV:
                    printf("\n\t\t  Control Channels (0x%02x) = [%s]",
                           *(tptr+2),
                           bittok2str(ldp_fec_martini_ifparm_vccv_cc_values,"none",*(tptr+2)));
                    printf("\n\t\t  CV Types (0x%02x) = [%s]",
                           *(tptr+3),
                           bittok2str(ldp_fec_martini_ifparm_vccv_cv_values,"none",*(tptr+3)));
                    break;

                default:
                    print_unknown_data(tptr+2,"\n\t\t  ",vc_info_tlv_len-2);
                    break;
                }

                vc_info_len -= vc_info_tlv_len;
                tptr += vc_info_tlv_len;
            }
	    break;
	}

	break;

    case LDP_TLV_GENERIC_LABEL:
	TLV_TCHECK(4);
	printf("\n\t      Label: %u", EXTRACT_32BITS(tptr) & 0xfffff);
	break;

    case LDP_TLV_STATUS:
	TLV_TCHECK(8);
	ui = EXTRACT_32BITS(tptr);
	tptr+=4;
	printf("\n\t      Status: 0x%02x, Flags: [%s and %s forward]",
	       ui&0x3fffffff,
	       ui&0x80000000 ? "Fatal error" : "Advisory Notification",
	       ui&0x40000000 ? "do" : "don't");
	ui = EXTRACT_32BITS(tptr);
	tptr+=4;
	if (ui)
	    printf(", causing Message ID: 0x%08x", ui);
	break;

    case LDP_TLV_FT_SESSION:
	TLV_TCHECK(8);
	ft_flags = EXTRACT_16BITS(tptr);
	printf("\n\t      Flags: [%sReconnect, %sSave State, %sAll-Label Protection, %s Checkpoint, %sRe-Learn State]",
	       ft_flags&0x8000 ? "" : "No ",
	       ft_flags&0x8 ? "" : "Don't ",
	       ft_flags&0x4 ? "" : "No ",
	       ft_flags&0x2 ? "Sequence Numbered Label" : "All Labels",
	       ft_flags&0x1 ? "" : "Don't ");
	tptr+=4;
	ui = EXTRACT_32BITS(tptr);
	if (ui)
	    printf(", Reconnect Timeout: %ums", ui);
	tptr+=4;
	ui = EXTRACT_32BITS(tptr);
	if (ui)
	    printf(", Recovery Time: %ums", ui);
	break;

    case LDP_TLV_MTU:
	TLV_TCHECK(2);
	printf("\n\t      MTU: %u", EXTRACT_16BITS(tptr));
	break;


    /*
     *  FIXME those are the defined TLVs that lack a decoder
     *  you are welcome to contribute code ;-)
     */

    case LDP_TLV_HOP_COUNT:
    case LDP_TLV_PATH_VECTOR:
    case LDP_TLV_ATM_LABEL:
    case LDP_TLV_FR_LABEL:
    case LDP_TLV_EXTD_STATUS:
    case LDP_TLV_RETURNED_PDU:
    case LDP_TLV_RETURNED_MSG:
    case LDP_TLV_ATM_SESSION_PARM:
    case LDP_TLV_FR_SESSION_PARM:
    case LDP_TLV_LABEL_REQUEST_MSG_ID:

    default:
        if (vflag <= 1)
            print_unknown_data(tptr,"\n\t      ",tlv_tlen);
        break;
    }
    return(tlv_len+4); /* Type & Length fields not included */
 
trunc:
    printf("\n\t\t packet exceeded snapshot");
    return 0;

badtlv:
    printf("\n\t\t TLV contents go past end of TLV");
    return(tlv_len+4); /* Type & Length fields not included */
}
Example #4
0
static void
atp_print(register const struct atATP *ap, u_int length)
{
    char c;
    u_int32_t data;

    if ((const u_char *)(ap + 1) > snapend) {
        /* Just bail if we don't have the whole chunk. */
        fputs(tstr, stdout);
        return;
    }
    if (length < sizeof(*ap)) {
        (void)printf(" [|atp %u]", length);
        return;
    }
    length -= sizeof(*ap);
    switch (ap->control & 0xc0) {

    case atpReqCode:
        (void)printf(" atp-req%s %d",
                     ap->control & atpXO? " " : "*",
                     EXTRACT_16BITS(&ap->transID));

        atp_bitmap_print(ap->bitmap);

        if (length != 0)
            (void)printf(" [len=%u]", length);

        switch (ap->control & (atpEOM|atpSTS)) {
        case atpEOM:
            (void)printf(" [EOM]");
            break;
        case atpSTS:
            (void)printf(" [STS]");
            break;
        case atpEOM|atpSTS:
            (void)printf(" [EOM,STS]");
            break;
        }
        break;

    case atpRspCode:
        (void)printf(" atp-resp%s%d:%d (%u)",
                     ap->control & atpEOM? "*" : " ",
                     EXTRACT_16BITS(&ap->transID), ap->bitmap, length);
        switch (ap->control & (atpXO|atpSTS)) {
        case atpXO:
            (void)printf(" [XO]");
            break;
        case atpSTS:
            (void)printf(" [STS]");
            break;
        case atpXO|atpSTS:
            (void)printf(" [XO,STS]");
            break;
        }
        break;

    case atpRelCode:
        (void)printf(" atp-rel  %d", EXTRACT_16BITS(&ap->transID));

        atp_bitmap_print(ap->bitmap);

        /* length should be zero */
        if (length)
            (void)printf(" [len=%u]", length);

        /* there shouldn't be any control flags */
        if (ap->control & (atpXO|atpEOM|atpSTS)) {
            c = '[';
            if (ap->control & atpXO) {
                (void)printf("%cXO", c);
                c = ',';
            }
            if (ap->control & atpEOM) {
                (void)printf("%cEOM", c);
                c = ',';
            }
            if (ap->control & atpSTS) {
                (void)printf("%cSTS", c);
                c = ',';
            }
            (void)printf("]");
        }
        break;

    default:
        (void)printf(" atp-0x%x  %d (%u)", ap->control,
                     EXTRACT_16BITS(&ap->transID), length);
        break;
    }
    data = EXTRACT_32BITS(&ap->userData);
    if (data != 0)
        (void)printf(" 0x%x", data);
}
Example #5
0
u_int
token_print(packetbody_t p, u_int length, u_int caplen)
{
	__capability const struct token_header *trp;
	u_short extracted_ethertype;
	struct ether_header ehdr;
	u_int route_len = 0, hdr_len = TOKEN_HDRLEN;
	int seg;

	trp = (__capability const struct token_header *)p;

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

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

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

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

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

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

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

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

	/* Frame Control field determines interpretation of packet */
	if (FRAME_TYPE(trp) == TOKEN_FC_LLC) {
		/* Try to print the LLC-layer header & higher layers */
		if (llc_print(p, length, caplen, cheri_ptr(ESRC(&ehdr), 6),
		    cheri_ptr(EDST(&ehdr), 6),
		    &extracted_ethertype) == 0) {
			/* ether_type not known, print raw packet */
			if (!eflag)
				token_hdr_print(trp,
				    length + TOKEN_HDRLEN + route_len,
				    ESRC(&ehdr), EDST(&ehdr));
			if (extracted_ethertype) {
				printf("(LLC %s) ",
			etherproto_string(htons(extracted_ethertype)));
			}
			if (!suppress_default_print)
				default_print(p, caplen);
		}
	} else {
		/* Some kinds of TR packet we cannot handle intelligently */
		/* XXX - dissect MAC packets if frame type is 0 */
		if (!eflag)
			token_hdr_print(trp, length + TOKEN_HDRLEN + route_len,
			    ESRC(&ehdr), EDST(&ehdr));
		if (!suppress_default_print)
			default_print(p, caplen);
	}
	return (hdr_len);
}
Example #6
0
u_int
token_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen)
{
	const struct token_header *trp;
	int llc_hdrlen;
	struct ether_header ehdr;
	u_int route_len = 0, hdr_len = TOKEN_HDRLEN;
	int seg;

	trp = (const struct token_header *)p;

	if (caplen < TOKEN_HDRLEN) {
		ND_PRINT((ndo, "%s", tstr));
		return hdr_len;
	}

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

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

		if (ndo->ndo_eflag)
			token_hdr_print(ndo, trp, length, ESRC(&ehdr), EDST(&ehdr));

		if (caplen < TOKEN_HDRLEN + 2) {
			ND_PRINT((ndo, "%s", tstr));
			return hdr_len;
		}
		route_len = RIF_LENGTH(trp);
		hdr_len += route_len;
		if (caplen < hdr_len) {
			ND_PRINT((ndo, "%s", tstr));
			return hdr_len;
		}
		if (ndo->ndo_vflag) {
			ND_PRINT((ndo, "%s ", broadcast_indicator[BROADCAST(trp)]));
			ND_PRINT((ndo, "%s", direction[DIRECTION(trp)]));

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

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

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

	/* Frame Control field determines interpretation of packet */
	if (FRAME_TYPE(trp) == TOKEN_FC_LLC) {
		/* Try to print the LLC-layer header & higher layers */
		llc_hdrlen = llc_print(ndo, p, length, caplen, ESRC(&ehdr),
		    EDST(&ehdr));
		if (llc_hdrlen < 0) {
			/* packet type not known, print raw packet */
			if (!ndo->ndo_suppress_default_print)
				ND_DEFAULTPRINT(p, caplen);
			llc_hdrlen = -llc_hdrlen;
		}
		hdr_len += llc_hdrlen;
	} else {
		/* Some kinds of TR packet we cannot handle intelligently */
		/* XXX - dissect MAC packets if frame type is 0 */
		if (!ndo->ndo_eflag)
			token_hdr_print(ndo, trp, length + TOKEN_HDRLEN + route_len,
			    ESRC(&ehdr), EDST(&ehdr));
		if (!ndo->ndo_suppress_default_print)
			ND_DEFAULTPRINT(p, caplen);
	}
	return (hdr_len);
}
Example #7
0
static void
slow_oam_print(netdissect_options *ndo,
               register const u_char *tptr, register u_int tlen) {

    u_int hexdump;

    struct slow_oam_common_header_t {
        uint8_t flags[2];
        uint8_t code;
    };

    struct slow_oam_tlv_header_t {
        uint8_t type;
        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 = (struct slow_oam_common_header_t *)tptr;
    tptr += sizeof(struct slow_oam_common_header_t);
    tlen -= sizeof(struct slow_oam_common_header_t);

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

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

            hexdump = FALSE;
            switch (ptr.slow_oam_tlv_header->type) {
            case SLOW_OAM_INFO_TYPE_END_OF_TLV:
                if (ptr.slow_oam_tlv_header->length != 0) {
                    ND_PRINT((ndo, "\n\t    ERROR: illegal length - should be 0"));
                }
                return;

            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 (tlv.slow_oam_info->info_length !=
                    sizeof(struct slow_oam_info_t)) {
                    ND_PRINT((ndo, "\n\t    ERROR: illegal length - should be %lu",
                           (unsigned long) sizeof(struct slow_oam_info_t)));
                    return;
                }

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

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

            case SLOW_OAM_INFO_TYPE_ORG_SPECIFIC:
                hexdump = TRUE;
                break;

            default:
                hexdump = TRUE;
                break;
            }

            /* infinite loop check */
            if (!ptr.slow_oam_tlv_header->length) {
                return;
            }

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

            tlen -= ptr.slow_oam_tlv_header->length;
            tptr += ptr.slow_oam_tlv_header->length;
        }
        break;

    case SLOW_OAM_CODE_EVENT_NOTIF:
        while (tlen > 0) {
            ptr.slow_oam_tlv_header = (const struct slow_oam_tlv_header_t *)tptr;
            ND_PRINT((ndo, "\n\t  %s Link Event Type (%u), length %u",
                   tok2str(slow_oam_link_event_values, "Reserved",
                           ptr.slow_oam_tlv_header->type),
                   ptr.slow_oam_tlv_header->type,
                   ptr.slow_oam_tlv_header->length));

            hexdump = FALSE;
            switch (ptr.slow_oam_tlv_header->type) {
            case SLOW_OAM_LINK_EVENT_END_OF_TLV:
                if (ptr.slow_oam_tlv_header->length != 0) {
                    ND_PRINT((ndo, "\n\t    ERROR: illegal length - should be 0"));
                }
                return;

            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 (tlv.slow_oam_link_event->event_length !=
                    sizeof(struct slow_oam_link_event_t)) {
                    ND_PRINT((ndo, "\n\t    ERROR: illegal length - should be %lu",
                           (unsigned long) sizeof(struct slow_oam_link_event_t)));
                    return;
                }

                ND_PRINT((ndo, "\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_16BITS(&tlv.slow_oam_link_event->time_stamp)*100,
                       EXTRACT_64BITS(&tlv.slow_oam_link_event->window),
                       EXTRACT_64BITS(&tlv.slow_oam_link_event->threshold),
                       EXTRACT_64BITS(&tlv.slow_oam_link_event->errors),
                       EXTRACT_64BITS(&tlv.slow_oam_link_event->errors_running_total),
                       EXTRACT_32BITS(&tlv.slow_oam_link_event->event_running_total)));
                break;

            case SLOW_OAM_LINK_EVENT_ORG_SPECIFIC:
                hexdump = TRUE;
                break;

            default:
                hexdump = TRUE;
                break;
            }

            /* infinite loop check */
            if (!ptr.slow_oam_tlv_header->length) {
                return;
            }

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

            tlen -= ptr.slow_oam_tlv_header->length;
            tptr += ptr.slow_oam_tlv_header->length;
        }
        break;

    case SLOW_OAM_CODE_LOOPBACK_CTRL:
        tlv.slow_oam_loopbackctrl = (const struct slow_oam_loopbackctrl_t *)tptr;
        ND_PRINT((ndo, "\n\t  Command %s (%u)",
               tok2str(slow_oam_loopbackctrl_cmd_values,
                       "Unknown",
                       tlv.slow_oam_loopbackctrl->command),
               tlv.slow_oam_loopbackctrl->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;
}
Example #8
0
static void
babel_print_v2(netdissect_options *ndo,
               const u_char *cp, u_int length) {
    u_int i;
    u_short bodylen;
    u_char v4_prefix[16] =
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0, 0, 0, 0 };
    u_char v6_prefix[16] = {0};

    ND_TCHECK2(*cp, 4);
    if (length < 4)
        goto corrupt;
    bodylen = EXTRACT_16BITS(cp + 2);
    ND_PRINT((ndo, " (%u)", bodylen));

    /* Process the TLVs in the body */
    i = 0;
    while(i < bodylen) {
        const u_char *message;
        u_int type, len;

        message = cp + 4 + i;

        ND_TCHECK2(*message, 1);
        if((type = message[0]) == MESSAGE_PAD1) {
            ND_PRINT((ndo, ndo->ndo_vflag ? "\n\tPad 1" : " pad1"));
            i += 1;
            continue;
        }

        ND_TCHECK2(*message, 2);
        ICHECK(i, 2);
        len = message[1];

        ND_TCHECK2(*message, 2 + len);
        ICHECK(i, 2 + len);

        switch(type) {
        case MESSAGE_PADN: {
            if (!ndo->ndo_vflag)
                ND_PRINT((ndo, " padN"));
            else
                ND_PRINT((ndo, "\n\tPad %d", len + 2));
        }
            break;

        case MESSAGE_ACK_REQ: {
            u_short nonce, interval;
            if (!ndo->ndo_vflag)
                ND_PRINT((ndo, " ack-req"));
            else {
                ND_PRINT((ndo, "\n\tAcknowledgment Request "));
                if(len < 6) goto corrupt;
                nonce = EXTRACT_16BITS(message + 4);
                interval = EXTRACT_16BITS(message + 6);
                ND_PRINT((ndo, "%04x %s", nonce, format_interval(interval)));
            }
        }
            break;

        case MESSAGE_ACK: {
            u_short nonce;
            if (!ndo->ndo_vflag)
                ND_PRINT((ndo, " ack"));
            else {
                ND_PRINT((ndo, "\n\tAcknowledgment "));
                if(len < 2) goto corrupt;
                nonce = EXTRACT_16BITS(message + 2);
                ND_PRINT((ndo, "%04x", nonce));
            }
        }
            break;

        case MESSAGE_HELLO:  {
            u_short seqno, interval;
            if (!ndo->ndo_vflag)
                ND_PRINT((ndo, " hello"));
            else {
                ND_PRINT((ndo, "\n\tHello "));
                if(len < 6) goto corrupt;
                seqno = EXTRACT_16BITS(message + 4);
                interval = EXTRACT_16BITS(message + 6);
                ND_PRINT((ndo, "seqno %u interval %s", seqno, format_interval(interval)));
            }
        }
            break;

        case MESSAGE_IHU: {
            unsigned short txcost, interval;
            if (!ndo->ndo_vflag)
                ND_PRINT((ndo, " ihu"));
            else {
                u_char address[16];
                int rc;
                ND_PRINT((ndo, "\n\tIHU "));
                if(len < 6) goto corrupt;
                txcost = EXTRACT_16BITS(message + 4);
                interval = EXTRACT_16BITS(message + 6);
                rc = network_address(message[2], message + 8, len - 6, address);
                if(rc < 0) { ND_PRINT((ndo, "%s", tstr)); break; }
                ND_PRINT((ndo, "%s txcost %u interval %s",
                       format_address(ndo, address), txcost, format_interval(interval)));
            }
        }
            break;

        case MESSAGE_ROUTER_ID: {
            if (!ndo->ndo_vflag)
                ND_PRINT((ndo, " router-id"));
            else {
                ND_PRINT((ndo, "\n\tRouter Id"));
                if(len < 10) goto corrupt;
                ND_PRINT((ndo, " %s", format_id(message + 4)));
            }
        }
            break;

        case MESSAGE_NH: {
            if (!ndo->ndo_vflag)
                ND_PRINT((ndo, " nh"));
            else {
                int rc;
                u_char nh[16];
                ND_PRINT((ndo, "\n\tNext Hop"));
                if(len < 2) goto corrupt;
                rc = network_address(message[2], message + 4, len - 2, nh);
                if(rc < 0) goto corrupt;
                ND_PRINT((ndo, " %s", format_address(ndo, nh)));
            }
        }
            break;

        case MESSAGE_UPDATE: {
            if (!ndo->ndo_vflag) {
                ND_PRINT((ndo, " update"));
                if(len < 1)
                    ND_PRINT((ndo, "/truncated"));
                else
                    ND_PRINT((ndo, "%s%s%s",
                           (message[3] & 0x80) ? "/prefix": "",
                           (message[3] & 0x40) ? "/id" : "",
                           (message[3] & 0x3f) ? "/unknown" : ""));
            } else {
                u_short interval, seqno, metric;
                u_char plen;
                int rc;
                u_char prefix[16];
                ND_PRINT((ndo, "\n\tUpdate"));
                if(len < 10) goto corrupt;
                plen = message[4] + (message[2] == 1 ? 96 : 0);
                rc = network_prefix(message[2], message[4], message[5],
                                    message + 12,
                                    message[2] == 1 ? v4_prefix : v6_prefix,
                                    len - 10, prefix);
                if(rc < 0) goto corrupt;
                interval = EXTRACT_16BITS(message + 6);
                seqno = EXTRACT_16BITS(message + 8);
                metric = EXTRACT_16BITS(message + 10);
                ND_PRINT((ndo, "%s%s%s %s metric %u seqno %u interval %s",
                       (message[3] & 0x80) ? "/prefix": "",
                       (message[3] & 0x40) ? "/id" : "",
                       (message[3] & 0x3f) ? "/unknown" : "",
                       format_prefix(ndo, prefix, plen),
                       metric, seqno, format_interval_update(interval)));
                if(message[3] & 0x80) {
                    if(message[2] == 1)
                        memcpy(v4_prefix, prefix, 16);
                    else
                        memcpy(v6_prefix, prefix, 16);
                }
                /* extra data? */
                if((u_int)rc < len - 10)
                    subtlvs_print(ndo, message + 12 + rc, message + 2 + len, type);
            }
        }
            break;

        case MESSAGE_REQUEST: {
            if (!ndo->ndo_vflag)
                ND_PRINT((ndo, " request"));
            else {
                int rc;
                u_char prefix[16], plen;
                ND_PRINT((ndo, "\n\tRequest "));
                if(len < 2) goto corrupt;
                plen = message[3] + (message[2] == 1 ? 96 : 0);
                rc = network_prefix(message[2], message[3], 0,
                                    message + 4, NULL, len - 2, prefix);
                if(rc < 0) goto corrupt;
                ND_PRINT((ndo, "for %s",
                       message[2] == 0 ? "any" : format_prefix(ndo, prefix, plen)));
            }
        }
            break;

        case MESSAGE_MH_REQUEST : {
            if (!ndo->ndo_vflag)
                ND_PRINT((ndo, " mh-request"));
            else {
                int rc;
                u_short seqno;
                u_char prefix[16], plen;
                ND_PRINT((ndo, "\n\tMH-Request "));
                if(len < 14) goto corrupt;
                seqno = EXTRACT_16BITS(message + 4);
                rc = network_prefix(message[2], message[3], 0,
                                    message + 16, NULL, len - 14, prefix);
                if(rc < 0) goto corrupt;
                plen = message[3] + (message[2] == 1 ? 96 : 0);
                ND_PRINT((ndo, "(%u hops) for %s seqno %u id %s",
                       message[6], format_prefix(ndo, prefix, plen),
                       seqno, format_id(message + 8)));
            }
        }
            break;
        case MESSAGE_TSPC :
            if (!ndo->ndo_vflag)
                ND_PRINT((ndo, " tspc"));
            else {
                ND_PRINT((ndo, "\n\tTS/PC "));
                if(len < 6) goto corrupt;
                ND_PRINT((ndo, "timestamp %u packetcounter %u", EXTRACT_32BITS (message + 4),
                       EXTRACT_16BITS(message + 2)));
            }
            break;
        case MESSAGE_HMAC : {
            if (!ndo->ndo_vflag)
                ND_PRINT((ndo, " hmac"));
            else {
                unsigned j;
                ND_PRINT((ndo, "\n\tHMAC "));
                if(len < 18) goto corrupt;
                ND_PRINT((ndo, "key-id %u digest-%u ", EXTRACT_16BITS(message + 2), len - 2));
                for (j = 0; j < len - 2; j++)
                    ND_PRINT((ndo, "%02X", message[4 + j]));
            }
        }
            break;
        default:
            if (!ndo->ndo_vflag)
                ND_PRINT((ndo, " unknown"));
            else
                ND_PRINT((ndo, "\n\tUnknown message type %d", type));
        }
        i += len + 2;
    }
    return;

 trunc:
    ND_PRINT((ndo, " %s", tstr));
    return;

 corrupt:
    ND_PRINT((ndo, " (corrupt)"));
    return;
}
Example #9
0
void
lwapp_control_print(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 */
        if (!TTEST2(*tptr, 6))
            goto trunc;
        lwapp_trans_header = (const struct lwapp_transport_header *)(pptr+6);
    } else {
        lwapp_trans_header = (const struct lwapp_transport_header *)pptr;
    }
    TCHECK(*lwapp_trans_header);

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

    /* non-verbose */
    if (vflag < 1) {
        printf("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);

    printf("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) {
        printf("\n\tAP identity: %s",
               etheraddr_string(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 ? */
        if (!TTEST2(*tptr, sizeof(struct lwapp_control_header)))
            goto trunc;

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

	/* print message header */ 
        printf("\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 */
        if (!TTEST2(*tptr, msg_tlen))
            goto trunc;

	/* 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:
    printf("\n\t\t packet exceeded snapshot");
}
Example #10
0
void
tcp_print(register const u_char *bp, register u_int length,
	  register const u_char *bp2, int fragmented)
{
        register const struct tcphdr *tp;
        register const struct ip *ip;
        register u_char flags;
        register u_int hlen;
        register char ch;
        u_int16_t sport, dport, win, urp;
        u_int32_t seq, ack, thseq, thack;
        u_int utoval;
        u_int16_t magic;
        register int rev;
#ifdef INET6
        register const struct ip6_hdr *ip6;
#endif

        tp = (struct tcphdr *)bp;
        ip = (struct ip *)bp2;
#ifdef INET6
        if (IP_V(ip) == 6)
                ip6 = (struct ip6_hdr *)bp2;
        else
                ip6 = NULL;
#endif /*INET6*/
        ch = '\0';
        if (!TTEST(tp->th_dport)) {
                (void)printf("%s > %s: [|tcp]",
                             ipaddr_string(&ip->ip_src),
                             ipaddr_string(&ip->ip_dst));
                return;
        }

        sport = EXTRACT_16BITS(&tp->th_sport);
        dport = EXTRACT_16BITS(&tp->th_dport);

        hlen = TH_OFF(tp) * 4;

#ifdef INET6
        if (ip6) {
                if (ip6->ip6_nxt == IPPROTO_TCP) {
                        (void)printf("%s.%s > %s.%s: ",
                                     ip6addr_string(&ip6->ip6_src),
                                     tcpport_string(sport),
                                     ip6addr_string(&ip6->ip6_dst),
                                     tcpport_string(dport));
                } else {
                        (void)printf("%s > %s: ",
                                     tcpport_string(sport), tcpport_string(dport));
                }
        } else
#endif /*INET6*/
        {
                if (ip->ip_p == IPPROTO_TCP) {
                        (void)printf("%s.%s > %s.%s: ",
                                     ipaddr_string(&ip->ip_src),
                                     tcpport_string(sport),
                                     ipaddr_string(&ip->ip_dst),
                                     tcpport_string(dport));
                } else {
                        (void)printf("%s > %s: ",
                                     tcpport_string(sport), tcpport_string(dport));
                }
        }

        if (hlen < sizeof(*tp)) {
                (void)printf(" tcp %d [bad hdr length %u - too short, < %lu]",
                             length - hlen, hlen, (unsigned long)sizeof(*tp));
                return;
        }

        TCHECK(*tp);

        seq = EXTRACT_32BITS(&tp->th_seq);
        ack = EXTRACT_32BITS(&tp->th_ack);
        win = EXTRACT_16BITS(&tp->th_win);
        urp = EXTRACT_16BITS(&tp->th_urp);

        if (qflag) {
                (void)printf("tcp %d", length - hlen);
                if (hlen > length) {
                        (void)printf(" [bad hdr length %u - too long, > %u]",
                                     hlen, length);
                }
                return;
        }

        flags = tp->th_flags;
        printf("Flags [%s]", bittok2str_nosep(tcp_flag_values, "none", flags));

        if (!Sflag && (flags & TH_ACK)) {
                /*
                 * Find (or record) the initial sequence numbers for
                 * this conversation.  (we pick an arbitrary
                 * collating order so there's only one entry for
                 * both directions).
                 */
                rev = 0;
#ifdef INET6
                if (ip6) {
                        register struct tcp_seq_hash6 *th;
                        struct tcp_seq_hash6 *tcp_seq_hash;
                        const struct in6_addr *src, *dst;
                        struct tha6 tha;

                        tcp_seq_hash = tcp_seq_hash6;
                        src = &ip6->ip6_src;
                        dst = &ip6->ip6_dst;
                        if (sport > dport)
                                rev = 1;
                        else if (sport == dport) {
                                if (UNALIGNED_MEMCMP(src, dst, sizeof ip6->ip6_dst) > 0)
                                        rev = 1;
                        }
                        if (rev) {
                                UNALIGNED_MEMCPY(&tha.src, dst, sizeof ip6->ip6_dst);
                                UNALIGNED_MEMCPY(&tha.dst, src, sizeof ip6->ip6_src);
                                tha.port = dport << 16 | sport;
                        } else {
                                UNALIGNED_MEMCPY(&tha.dst, dst, sizeof ip6->ip6_dst);
                                UNALIGNED_MEMCPY(&tha.src, src, sizeof ip6->ip6_src);
                                tha.port = sport << 16 | dport;
                        }

                        for (th = &tcp_seq_hash[tha.port % TSEQ_HASHSIZE];
                             th->nxt; th = th->nxt)
                                if (memcmp((char *)&tha, (char *)&th->addr,
                                           sizeof(th->addr)) == 0)
                                        break;

                        if (!th->nxt || (flags & TH_SYN)) {
                                /* didn't find it or new conversation */
                                if (th->nxt == NULL) {
                                        th->nxt = (struct tcp_seq_hash6 *)
                                                calloc(1, sizeof(*th));
                                        if (th->nxt == NULL)
                                                error("tcp_print: calloc");
                                }
                                th->addr = tha;
                                if (rev)
                                        th->ack = seq, th->seq = ack - 1;
                                else
                                        th->seq = seq, th->ack = ack - 1;
                        } else {
                                if (rev)
                                        seq -= th->ack, ack -= th->seq;
                                else
                                        seq -= th->seq, ack -= th->ack;
                        }

                        thseq = th->seq;
                        thack = th->ack;
                } else {
#else  /*INET6*/
                {
#endif /*INET6*/
                        register struct tcp_seq_hash *th;
                        struct tcp_seq_hash *tcp_seq_hash;
                        const struct in_addr *src, *dst;
                        struct tha tha;

                        tcp_seq_hash = tcp_seq_hash4;
                        src = &ip->ip_src;
                        dst = &ip->ip_dst;
                        if (sport > dport)
                                rev = 1;
                        else if (sport == dport) {
                                if (UNALIGNED_MEMCMP(src, dst, sizeof ip->ip_dst) > 0)
                                        rev = 1;
                        }
                        if (rev) {
                                UNALIGNED_MEMCPY(&tha.src, dst, sizeof ip->ip_dst);
                                UNALIGNED_MEMCPY(&tha.dst, src, sizeof ip->ip_src);
                                tha.port = dport << 16 | sport;
                        } else {
                                UNALIGNED_MEMCPY(&tha.dst, dst, sizeof ip->ip_dst);
                                UNALIGNED_MEMCPY(&tha.src, src, sizeof ip->ip_src);
                                tha.port = sport << 16 | dport;
                        }

                        for (th = &tcp_seq_hash[tha.port % TSEQ_HASHSIZE];
                             th->nxt; th = th->nxt)
                                if (memcmp((char *)&tha, (char *)&th->addr,
                                           sizeof(th->addr)) == 0)
                                        break;

                        if (!th->nxt || (flags & TH_SYN)) {
                                /* didn't find it or new conversation */
                                if (th->nxt == NULL) {
                                        th->nxt = (struct tcp_seq_hash *)
                                                calloc(1, sizeof(*th));
                                        if (th->nxt == NULL)
                                                error("tcp_print: calloc");
                                }
                                th->addr = tha;
                                if (rev)
                                        th->ack = seq, th->seq = ack - 1;
                                else
                                        th->seq = seq, th->ack = ack - 1;
                        } else {
                                if (rev)
                                        seq -= th->ack, ack -= th->seq;
                                else
                                        seq -= th->seq, ack -= th->ack;
                        }

                        thseq = th->seq;
                        thack = th->ack;
                }
        } else {
Example #11
0
static void
dhcp6opt_print(const u_char *cp, const u_char *ep)
{
	struct dhcp6opt *dh6o;
	u_char *tp;
	size_t i;
	u_int16_t opttype;
	size_t optlen;
	u_int16_t val16;
	u_int32_t val32;
	struct dhcp6_ia ia;
	struct dhcp6_ia_prefix ia_prefix;
	struct dhcp6_ia_addr ia_addr;
	struct dhcp6_auth authopt;
	u_int authinfolen, authrealmlen;

	if (cp == ep)
		return;
	while (cp < ep) {
		if (ep < cp + sizeof(*dh6o))
			goto trunc;
		dh6o = (struct dhcp6opt *)cp;
		optlen = EXTRACT_16BITS(&dh6o->dh6opt_len);
		if (ep < cp + sizeof(*dh6o) + optlen)
			goto trunc;
		opttype = EXTRACT_16BITS(&dh6o->dh6opt_type);
		printf(" (%s", dhcp6opt_name(opttype));
		switch (opttype) {
		case DH6OPT_CLIENTID:
		case DH6OPT_SERVERID:
			if (optlen < 2) {
				/*(*/
				printf(" ?)");
				break;
			}
			tp = (u_char *)(dh6o + 1);
			switch (EXTRACT_16BITS(tp)) {
			case 1:
				if (optlen >= 2 + 6) {
					printf(" hwaddr/time type %u time %u ",
					    EXTRACT_16BITS(&tp[2]),
					    EXTRACT_32BITS(&tp[4]));
					for (i = 8; i < optlen; i++)
						printf("%02x", tp[i]);
					/*(*/
					printf(")");
				} else {
					/*(*/
					printf(" ?)");
				}
				break;
			case 2:
				if (optlen >= 2 + 8) {
					printf(" vid ");
					for (i = 2; i < 2 + 8; i++)
						printf("%02x", tp[i]);
					/*(*/
					printf(")");
				} else {
					/*(*/
					printf(" ?)");
				}
				break;
			case 3:
				if (optlen >= 2 + 2) {
					printf(" hwaddr type %u ",
					    EXTRACT_16BITS(&tp[2]));
					for (i = 4; i < optlen; i++)
						printf("%02x", tp[i]);
					/*(*/
					printf(")");
				} else {
					/*(*/
					printf(" ?)");
				}
				break;
			default:
				printf(" type %d)", EXTRACT_16BITS(tp));
				break;
			}
			break;
		case DH6OPT_IA_ADDR:
			if (optlen < sizeof(ia_addr) - 4) {
				printf(" ?)");
				break;
			}
			memcpy(&ia_addr, (u_char *)dh6o, sizeof(ia_addr));
			printf(" %s",
			    ip6addr_string(&ia_addr.dh6opt_ia_addr_addr));
			ia_addr.dh6opt_ia_addr_pltime =
			    ntohl(ia_addr.dh6opt_ia_addr_pltime);
			ia_addr.dh6opt_ia_addr_vltime =
			    ntohl(ia_addr.dh6opt_ia_addr_vltime);
			printf(" pltime:%lu vltime:%lu",
			    (unsigned long)ia_addr.dh6opt_ia_addr_pltime,
			    (unsigned long)ia_addr.dh6opt_ia_addr_vltime);
			if (optlen > sizeof(ia_addr) - 4) {
				/* there are sub-options */
				dhcp6opt_print((u_char *)dh6o +
				    sizeof(ia_addr),
				    (u_char *)(dh6o + 1) + optlen);
			}
			printf(")");
			break;
		case DH6OPT_ORO:
			if (optlen % 2) {
				printf(" ?)");
				break;
			}
			tp = (u_char *)(dh6o + 1);
			for (i = 0; i < optlen; i += 2) {
				u_int16_t opt;

				memcpy(&opt, &tp[i], sizeof(opt));
				printf(" %s", dhcp6opt_name(ntohs(opt)));
			}
			printf(")");
			break;
		case DH6OPT_PREFERENCE:
			if (optlen != 1) {
				printf(" ?)");
				break;
			}
			printf(" %d)", *((u_char *)(dh6o + 1) + 1));
			break;
		case DH6OPT_ELAPSED_TIME:
			if (optlen != 2) {
				printf(" ?)");
				break;
			}
			memcpy(&val16, dh6o + 1, sizeof(val16));
			val16 = ntohs(val16);
			printf(" %d)", (int)val16);
			break;
		case DH6OPT_RELAY_MSG:
			printf(" (");
			dhcp6_print((const u_char *)(dh6o + 1), optlen);
			printf(")");
			break;
		case DH6OPT_AUTH:
			if (optlen < sizeof(authopt) - sizeof(*dh6o)) {
				printf(" ?)");
				break;
			}
			memcpy(&authopt, dh6o, sizeof(authopt));
			switch (authopt.dh6opt_auth_proto) {
			case DH6OPT_AUTHPROTO_DELAYED:
				printf(" proto: delayed");
				break;
			case DH6OPT_AUTHPROTO_RECONFIG:
				printf(" proto: reconfigure");
				break;
			default:
				printf(" proto: %d",
				    authopt.dh6opt_auth_proto);
				break;
			}
			switch (authopt.dh6opt_auth_alg) {
			case DH6OPT_AUTHALG_HMACMD5:
				/* XXX: may depend on the protocol */
				printf(", alg: HMAC-MD5");
				break;
			default:
				printf(", alg: %d", authopt.dh6opt_auth_alg);
				break;
			}
			switch (authopt.dh6opt_auth_rdm) {
			case DH6OPT_AUTHRDM_MONOCOUNTER:
				printf(", RDM: mono");
				break;
			default:
				printf(", RDM: %d", authopt.dh6opt_auth_rdm);
				break;
			}
			tp = (u_char *)&authopt.dh6opt_auth_rdinfo;
			printf(", RD:");
			for (i = 0; i < 4; i++, tp += sizeof(val16))
				printf(" %04x", EXTRACT_16BITS(tp));

			/* protocol dependent part */
			tp = (u_char *)dh6o + sizeof(authopt);
			authinfolen =
			    optlen + sizeof(*dh6o) - sizeof(authopt); 
			switch (authopt.dh6opt_auth_proto) {
			case DH6OPT_AUTHPROTO_DELAYED:
				if (authinfolen == 0)
					break;
				if (authinfolen < 20) {
					printf(" ??");
					break;
				}
				authrealmlen = authinfolen - 20;
				if (authrealmlen > 0) {
					printf(", realm: ");
				}
				for (i = 0; i < authrealmlen; i++, tp++)
					printf("%02x", *tp);
				printf(", key ID: %08x", EXTRACT_32BITS(tp));
				tp += 4;
				printf(", HMAC-MD5:");
				for (i = 0; i < 4; i++, tp+= 4)
					printf(" %08x", EXTRACT_32BITS(tp));
				break;
			case DH6OPT_AUTHPROTO_RECONFIG:
				if (authinfolen != 17) {
					printf(" ??");
					break;
				}
				switch (*tp++) {
				case DH6OPT_AUTHRECONFIG_KEY:
					printf(" reconfig-key");
					break;
				case DH6OPT_AUTHRECONFIG_HMACMD5:
					printf(" type: HMAC-MD5");
					break;
				default:
					printf(" type: ??");
					break;
				}
				printf(" value:");
				for (i = 0; i < 4; i++, tp+= 4)
					printf(" %08x", EXTRACT_32BITS(tp));
				break;
			default:
				printf(" ??");
				break;
			}

			printf(")");
			break;
		case DH6OPT_RAPID_COMMIT: /* nothing todo */
			printf(")");
			break;
		case DH6OPT_INTERFACE_ID:
			/*
			 * Since we cannot predict the encoding, print hex dump
			 * at most 10 characters.
			 */
			for (i = 0; i < optlen && i < 10; i++)
				printf("%02x", ((u_char *)(dh6o + 1))[i]);
			break;
		case DH6OPT_RECONF_MSG:
			tp = (u_char *)(dh6o + 1);
			switch (*tp) {
			case DH6_RENEW:
				printf(" for renew)");
				break;
			case DH6_INFORM_REQ:
				printf(" for inf-req)");
				break;
			default:
				printf(" for ?\?\?(%02x))", *tp);
				break;
			}
			break;
		case DH6OPT_RECONF_ACCEPT: /* nothing todo */
			printf(")");
			break;
		case DH6OPT_SIP_SERVER_A:
		case DH6OPT_DNS:
		case DH6OPT_NTP_SERVERS:
		case DH6OPT_NIS_SERVERS:
		case DH6OPT_NISP_SERVERS:
		case DH6OPT_BCMCS_SERVER_A:
			if (optlen % 16) {
				printf(" ?)");
				break;
			}
			tp = (u_char *)(dh6o + 1);
			for (i = 0; i < optlen; i += 16)
				printf(" %s", ip6addr_string(&tp[i]));
			printf(")");
			break;
		case DH6OPT_STATUS_CODE:
			if (optlen < 2) {
				printf(" ?)");
				break;
			}
			memcpy(&val16, (u_char *)(dh6o + 1), sizeof(val16));
			val16 = ntohs(val16);
			printf(" %s)", dhcp6stcode(val16));
			break;
		case DH6OPT_IA_NA:
		case DH6OPT_IA_PD:
			if (optlen < sizeof(ia) - 4) {
				printf(" ?)");
				break;
			}
			memcpy(&ia, (u_char *)dh6o, sizeof(ia));
			ia.dh6opt_ia_iaid = ntohl(ia.dh6opt_ia_iaid);
			ia.dh6opt_ia_t1 = ntohl(ia.dh6opt_ia_t1);
			ia.dh6opt_ia_t2 = ntohl(ia.dh6opt_ia_t2);
			printf(" IAID:%lu T1:%lu T2:%lu",
			    (unsigned long)ia.dh6opt_ia_iaid,
			    (unsigned long)ia.dh6opt_ia_t1,
			    (unsigned long)ia.dh6opt_ia_t2);
			if (optlen > sizeof(ia) - 4) {
				/* there are sub-options */
				dhcp6opt_print((u_char *)dh6o + sizeof(ia),
				    (u_char *)(dh6o + 1) + optlen);
			}
			printf(")");
			break;
		case DH6OPT_IA_PD_PREFIX:
			if (optlen < sizeof(ia_prefix) - 4) {
				printf(" ?)");
				break;
			}
			memcpy(&ia_prefix, (u_char *)dh6o, sizeof(ia_prefix));
			printf(" %s/%d",
			    ip6addr_string(&ia_prefix.dh6opt_ia_prefix_addr),
			    ia_prefix.dh6opt_ia_prefix_plen);
			ia_prefix.dh6opt_ia_prefix_pltime =
			    ntohl(ia_prefix.dh6opt_ia_prefix_pltime);
			ia_prefix.dh6opt_ia_prefix_vltime =
			    ntohl(ia_prefix.dh6opt_ia_prefix_vltime);
			printf(" pltime:%lu vltime:%lu",
			    (unsigned long)ia_prefix.dh6opt_ia_prefix_pltime,
			    (unsigned long)ia_prefix.dh6opt_ia_prefix_vltime);
			if (optlen > sizeof(ia_prefix) - 4) {
				/* there are sub-options */
				dhcp6opt_print((u_char *)dh6o +
				    sizeof(ia_prefix),
				    (u_char *)(dh6o + 1) + optlen);
			}
			printf(")");
			break;
		case DH6OPT_LIFETIME:
			if (optlen != 4) {
				printf(" ?)");
				break;
			}
			memcpy(&val32, dh6o + 1, sizeof(val32));
			val32 = ntohl(val32);
			printf(" %d)", (int)val32);
			break;
		default:
			printf(")");
			break;
		}

		cp += sizeof(*dh6o) + optlen;
	}
	return;

trunc:
	printf("[|dhcp6ext]");
}
Example #12
0
int
snap_print(packetbody_t p, u_int length, u_int caplen, u_int bridge_pad)
{
	u_int32_t orgcode;
	register u_short et;
	register int ret;

	PACKET_HAS_SPACE_OR_TRUNC(p, 5);
	orgcode = EXTRACT_24BITS(p);
	et = EXTRACT_16BITS(p + 3);

	if (eflag) {
		const struct tok *tok = null_values;
		const struct oui_tok *otp;

		for (otp = &oui_to_tok[0]; otp->tok != NULL; otp++) {
			if (otp->oui == orgcode) {
				tok = otp->tok;
				break;
			}
		}
		(void)printf("oui %s (0x%06x), %s %s (0x%04x): ",
		     tok2str(oui_values, "Unknown", orgcode),
		     orgcode,
		     (orgcode == 0x000000 ? "ethertype" : "pid"),
		     tok2str(tok, "Unknown", et),
		     et);
	}
	p += 5;
	length -= 5;
	caplen -= 5;

	switch (orgcode) {
	case OUI_ENCAP_ETHER:
	case OUI_CISCO_90:
		/*
		 * This is an encapsulated Ethernet packet,
		 * or a packet bridged by some piece of
		 * Cisco hardware; the protocol ID is
		 * an Ethernet protocol type.
		 */
		ret = ethertype_print(gndo, et, p, length, caplen);
		if (ret)
			return (ret);
		break;

	case OUI_APPLETALK:
		if (et == ETHERTYPE_ATALK) {
			/*
			 * No, I have no idea why Apple used one
			 * of their own OUIs, rather than
			 * 0x000000, and an Ethernet packet
			 * type, for Appletalk data packets,
			 * but used 0x000000 and an Ethernet
			 * packet type for AARP packets.
			 */
			ret = ethertype_print(gndo, et, p, length, caplen);
			if (ret)
				return (ret);
		}
		break;

	case OUI_CISCO:
                switch (et) {
                case PID_CISCO_CDP:
                        cdp_print(p, length, caplen);
                        return (1);
                case PID_CISCO_DTP:
                        dtp_print(p, length); 
                        return (1);
                case PID_CISCO_UDLD:
                        udld_print(p, length);
                        return (1);
                case PID_CISCO_VTP:
                        vtp_print(p, length);
                        return (1);
                case PID_CISCO_PVST:
                        stp_print(p, length);
                        return (1);
                default:
                        break;
                }

	case OUI_RFC2684:
		switch (et) {

		case PID_RFC2684_ETH_FCS:
		case PID_RFC2684_ETH_NOFCS:
			/*
			 * XXX - remove the last two bytes for
			 * PID_RFC2684_ETH_FCS?
			 */
			/*
			 * Skip the padding.
			 */
			PACKET_HAS_SPACE_OR_TRUNC(p, bridge_pad);
			caplen -= bridge_pad;
			length -= bridge_pad;
			p += bridge_pad;

			/*
			 * What remains is an Ethernet packet.
			 */
			ether_print(gndo, p, length, caplen, NULL, NULL);
			return (1);

		case PID_RFC2684_802_5_FCS:
		case PID_RFC2684_802_5_NOFCS:
			/*
			 * XXX - remove the last two bytes for
			 * PID_RFC2684_ETH_FCS?
			 */
			/*
			 * Skip the padding, but not the Access
			 * Control field.
			 */
			PACKET_HAS_SPACE_OR_TRUNC(p, bridge_pad);
			caplen -= bridge_pad;
			length -= bridge_pad;
			p += bridge_pad;

			/*
			 * What remains is an 802.5 Token Ring
			 * packet.
			 */
			token_print(p, length, caplen);
			return (1);

		case PID_RFC2684_FDDI_FCS:
		case PID_RFC2684_FDDI_NOFCS:
			/*
			 * XXX - remove the last two bytes for
			 * PID_RFC2684_ETH_FCS?
			 */
			/*
			 * Skip the padding.
			 */
			PACKET_HAS_SPACE_OR_TRUNC(p, bridge_pad + 1);
			caplen -= bridge_pad + 1;
			length -= bridge_pad + 1;
			p += bridge_pad + 1;

			/*
			 * What remains is an FDDI packet.
			 */
			fddi_print(p, length, caplen);
			return (1);

		case PID_RFC2684_BPDU:
			stp_print(p, length);
			return (1);
		}
	}
	return (0);

trunc:
	(void)printf("[|snap]");
	return (1);
}
Example #13
0
/*
 * Print trivial file transfer program requests
 */
void
tftp_print(register const u_char *bp, u_int length)
{
	register const struct tftphdr *tp;
	register const char *cp;
	register const u_char *p;
	register int opcode, i;
	static char tstr[] = " [|tftp]";

	tp = (const struct tftphdr *)bp;

	/* Print length */
	printf(" %d", length);

	/* Print tftp request type */
	TCHECK(tp->th_opcode);
	opcode = EXTRACT_16BITS(&tp->th_opcode);
	cp = tok2str(op2str, "tftp-#%d", opcode);
	printf(" %s", cp);
	/* Bail if bogus opcode */
	if (*cp == 't')
		return;

	switch (opcode) {

	case RRQ:
	case WRQ:
	case OACK:
		/*
		 * XXX Not all arpa/tftp.h's specify th_stuff as any
		 * array; use address of th_block instead
		 */
#ifdef notdef
		p = (u_char *)tp->th_stuff;
#else
		p = (u_char *)&tp->th_block;
#endif
		putchar(' ');
		/* Print filename or first option */
		if (opcode != OACK)
			putchar('"');
		i = fn_print(p, snapend);
		if (opcode != OACK)
			putchar('"');

		/* Print the mode (RRQ and WRQ only) and any options */
		while ((p = (const u_char *)strchr((const char *)p, '\0')) != NULL) {
			if (length <= (u_int)(p - (const u_char *)&tp->th_block))
				break;
			p++;
			if (*p != '\0') {
				putchar(' ');
				fn_print(p, snapend);
			}
		}
		
		if (i)
			goto trunc;
		break;

	case ACK:
	case DATA:
		TCHECK(tp->th_block);
		printf(" block %d", EXTRACT_16BITS(&tp->th_block));
		break;

	case TFTP_ERROR:
		/* Print error code string */
		TCHECK(tp->th_code);
		printf(" %s \"", tok2str(err2str, "tftp-err-#%d \"",
				       EXTRACT_16BITS(&tp->th_code)));
		/* Print error message string */
		i = fn_print((const u_char *)tp->th_data, snapend);
		putchar('"');
		if (i)
			goto trunc;
		break;

	default:
		/* We shouldn't get here */
		printf("(unknown #%d)", opcode);
		break;
	}
	return;
trunc:
	fputs(tstr, stdout);
	return;
}
Example #14
0
void
geneve_print(netdissect_options *ndo, const u_char *bp, u_int len)
{
    uint8_t ver_opt;
    u_int 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",
                  opts_len - 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 #15
0
static void
print_16bits_val(__capability const u_int16_t *dat)
{
	printf("%u", EXTRACT_16BITS(dat));
}
Example #16
0
/****************************************************************************
 *
 * Function: TCPOptionValue(Options *o)
 *
 * Purpose: To return a string representing the value of an TCP option
 *
 * Arguments: An Options struct.
 *
 * Returns: char * -- You must free this char * when you are done with it.
 *
 ***************************************************************************/
char *TCPOptionValue(Options *o)
{
    char * rval;
    char * rvalptr;
    u_char tmp[5];
    int x;

    rval = (char *)malloc(SMALLBUFFER);
    rvalptr = rval;

    switch(o->code)
    {
        case TCPOPT_MAXSEG:
            bzero((char *)tmp, 5);
            strncpy(tmp, o->data, 2); 
            snprintf(rval, SMALLBUFFER, "%u", EXTRACT_16BITS(tmp));
            break;

        case TCPOPT_EOL:
            rval[0] = '\0';
            break;

        case TCPOPT_NOP:
            rval[0] = '\0';
            break;

        case TCPOPT_WSCALE:
            snprintf(rval, SMALLBUFFER, "%u", o->data[0]);
            break;

        case TCPOPT_SACK:
            bzero((char *)tmp, 5);
            memcpy(tmp, o->data, 2);
            snprintf(rval, SMALLBUFFER, "%u@", EXTRACT_16BITS(tmp));
            x = strlen(rval);
            rvalptr += x;
            bzero((char *)tmp, 5);
            memcpy(tmp, (o->data)+2, 2);
            snprintf(rvalptr, SMALLBUFFER - x, "%u", EXTRACT_16BITS(tmp));
            break;

        case TCPOPT_SACKOK:
            rval[0] = '\0';
            break;

        case TCPOPT_ECHO:
            bzero((char *)tmp, 5);
            memcpy(tmp, o->data, 4);
            snprintf(rval, SMALLBUFFER, "%u", EXTRACT_32BITS(tmp));
            break;

        case TCPOPT_ECHOREPLY:
            bzero((char *)tmp, 5);
            memcpy(tmp, o->data, 4);
            snprintf(rval, SMALLBUFFER, "%u", EXTRACT_32BITS(tmp));
            break;

        case TCPOPT_TIMESTAMP:
            bzero((char *)tmp, 5);
            memcpy(tmp, o->data, 4);
            snprintf(rval, SMALLBUFFER, "%u ", EXTRACT_32BITS(tmp));
            rvalptr += strlen(rval);
            bzero((char *)tmp, 5);
            memcpy(tmp, (o->data)+4, 4);
            snprintf(rvalptr, SMALLBUFFER, "%u", EXTRACT_32BITS(tmp));
            break;

        case TCPOPT_CC:
            bzero((char *)tmp, 5);
            memcpy(tmp, o->data, 4);
            snprintf(rval, SMALLBUFFER, "%u", EXTRACT_32BITS(tmp));
            break;

        case TCPOPT_CCNEW:
            bzero((char *)tmp, 5);
            memcpy(tmp, o->data, 4);
            snprintf(rval, SMALLBUFFER, "%u", EXTRACT_32BITS(tmp));
            break;

        case TCPOPT_CCECHO:
            bzero((char *)tmp, 5);
            memcpy(tmp, o->data, 4);
            snprintf(rval, SMALLBUFFER, "%u", EXTRACT_32BITS(tmp));
            break;

        default:
            rval[0] = '\0';
            if(o->len > 2)
            {
                for(x = 0; x < (int)(o->len-2); x+=2)
                {
                    snprintf(tmp, 5, "%02X%02X ", o->data[x], o->data[x+1]);
                    if(strlen(rval) < SMALLBUFFER - 5);
                    strncat(rval, tmp, SMALLBUFFER - strlen(rval));
                }
            }
            break;
    }
    return rval;
}
Example #17
0
/**
 * dccp_print - show dccp packet
 * @bp - beginning of dccp packet
 * @data2 - beginning of enclosing
 * @len - lenght of ip packet
 */
void dccp_print(const u_char *bp, const u_char *data2, u_int len)
{
	const struct dccp_hdr *dh;
	const struct ip *ip;
#ifdef INET6
	const struct ip6_hdr *ip6;
#endif
	const u_char *cp;
	u_short sport, dport;
	u_int hlen;
	u_int fixed_hdrlen;

	dh = (const struct dccp_hdr *)bp;

	ip = (struct ip *)data2;
#ifdef INET6
	if (IP_V(ip) == 6)
		ip6 = (const struct ip6_hdr *)data2;
	else
		ip6 = NULL;
#endif /*INET6*/

	/* make sure we have enough data to look at the X bit */
	cp = (const u_char *)(dh + 1);
	if (cp > snapend) {
		printf("[Invalid packet|dccp]");
		return;
	}
	if (len < sizeof(struct dccp_hdr)) {
		printf("truncated-dccp - %u bytes missing!",
			     len - (u_int)sizeof(struct dccp_hdr));
		return;
	}

	/* get the length of the generic header */
	fixed_hdrlen = dccp_basic_hdr_len(dh);
	if (len < fixed_hdrlen) {
		printf("truncated-dccp - %u bytes missing!",
			     len - fixed_hdrlen);
		return;
	}
	TCHECK2(*dh, fixed_hdrlen);

	sport = EXTRACT_16BITS(&dh->dccph_sport);
	dport = EXTRACT_16BITS(&dh->dccph_dport);
	hlen = dh->dccph_doff * 4;

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

	if (qflag) {
		(void)printf(" %d", len - hlen);
		if (hlen > len) {
			(void)printf("dccp [bad hdr length %u - too long, > %u]",
			    hlen, len);
		}
		return;
	}

	/* other variables in generic header */
	if (vflag) {
		(void)printf("CCVal %d, CsCov %d, ", DCCPH_CCVAL(dh), DCCPH_CSCOV(dh));
	}

	/* checksum calculation */
	if (vflag && TTEST2(bp[0], len)) {
		u_int16_t sum = 0, dccp_sum;

		dccp_sum = EXTRACT_16BITS(&dh->dccph_checksum);
		(void)printf("cksum 0x%04x ", dccp_sum);
		if (IP_V(ip) == 4)
			sum = dccp_cksum(ip, dh, len);
#ifdef INET6
		else if (IP_V(ip) == 6)
			sum = dccp6_cksum(ip6, dh, len);
#endif
		if (sum != 0)
			(void)printf("(incorrect -> 0x%04x), ",in_cksum_shouldbe(dccp_sum, sum));
		else
			(void)printf("(correct), ");
	}

	switch (DCCPH_TYPE(dh)) {
	case DCCP_PKT_REQUEST: {
		struct dccp_hdr_request *dhr =
			(struct dccp_hdr_request *)(bp + fixed_hdrlen);
		fixed_hdrlen += 4;
		if (len < fixed_hdrlen) {
			printf("truncated-dccp request - %u bytes missing!",
				     len - fixed_hdrlen);
			return;
		}
		TCHECK(*dhr);
		(void)printf("request (service=%d) ",
			     EXTRACT_32BITS(&dhr->dccph_req_service));
		break;
	}
	case DCCP_PKT_RESPONSE: {
		struct dccp_hdr_response *dhr =
			(struct dccp_hdr_response *)(bp + fixed_hdrlen);
		fixed_hdrlen += 12;
		if (len < fixed_hdrlen) {
			printf("truncated-dccp response - %u bytes missing!",
				     len - fixed_hdrlen);
			return;
		}
		TCHECK(*dhr);
		(void)printf("response (service=%d) ",
			     EXTRACT_32BITS(&dhr->dccph_resp_service));
		break;
	}
	case DCCP_PKT_DATA:
		(void)printf("data ");
		break;
	case DCCP_PKT_ACK: {
		fixed_hdrlen += 8;
		if (len < fixed_hdrlen) {
			printf("truncated-dccp ack - %u bytes missing!",
				     len - fixed_hdrlen);
			return;
		}
		(void)printf("ack ");
		break;
	}
	case DCCP_PKT_DATAACK: {
		fixed_hdrlen += 8;
		if (len < fixed_hdrlen) {
			printf("truncated-dccp dataack - %u bytes missing!",
				     len - fixed_hdrlen);
			return;
		}
		(void)printf("dataack ");
		break;
	}
	case DCCP_PKT_CLOSEREQ:
		fixed_hdrlen += 8;
		if (len < fixed_hdrlen) {
			printf("truncated-dccp closereq - %u bytes missing!",
				     len - fixed_hdrlen);
			return;
		}
		(void)printf("closereq ");
		break;
	case DCCP_PKT_CLOSE:
		fixed_hdrlen += 8;
		if (len < fixed_hdrlen) {
			printf("truncated-dccp close - %u bytes missing!",
				     len - fixed_hdrlen);
			return;
		}
		(void)printf("close ");
		break;
	case DCCP_PKT_RESET: {
		struct dccp_hdr_reset *dhr =
			(struct dccp_hdr_reset *)(bp + fixed_hdrlen);
		fixed_hdrlen += 12;
		if (len < fixed_hdrlen) {
			printf("truncated-dccp reset - %u bytes missing!",
				     len - fixed_hdrlen);
			return;
		}
		TCHECK(*dhr);
		(void)printf("reset (code=%s) ",
			     dccp_reset_code(dhr->dccph_reset_code));
		break;
	}
	case DCCP_PKT_SYNC:
		fixed_hdrlen += 8;
		if (len < fixed_hdrlen) {
			printf("truncated-dccp sync - %u bytes missing!",
				     len - fixed_hdrlen);
			return;
		}
		(void)printf("sync ");
		break;
	case DCCP_PKT_SYNCACK:
		fixed_hdrlen += 8;
		if (len < fixed_hdrlen) {
			printf("truncated-dccp syncack - %u bytes missing!",
				     len - fixed_hdrlen);
			return;
		}
		(void)printf("syncack ");
		break;
	default:
		(void)printf("invalid ");
		break;
	}

	if ((DCCPH_TYPE(dh) != DCCP_PKT_DATA) &&
			(DCCPH_TYPE(dh) != DCCP_PKT_REQUEST))
		dccp_print_ack_no(bp);

	if (vflag < 2)
		return;

	(void)printf("seq %" PRIu64, dccp_seqno(bp));

	/* process options */
	if (hlen > fixed_hdrlen){
		const u_char *cp;
		u_int optlen;
		cp = bp + fixed_hdrlen;
		printf(" <");

		hlen -= fixed_hdrlen;
		while(1){
			optlen = dccp_print_option(cp, hlen);
			if (!optlen)
				break;
			if (hlen <= optlen)
				break;
			hlen -= optlen;
			cp += optlen;
			printf(", ");
		}
		printf(">");
	}
	return;
trunc:
	printf("%s", tstr);
	return;
}
Example #18
0
void
icmp_print(netdissect_options *ndo, const u_char *bp, u_int plen, const u_char *bp2,
           int fragmented)
{
	char *cp;
	const struct icmp *dp;
        const struct icmp_ext_t *ext_dp;
	const struct ip *ip;
	const char *str, *fmt;
	const struct ip *oip;
	const struct udphdr *ouh;
        const uint8_t *obj_tptr;
        uint32_t raw_label;
        const u_char *snapend_save;
	const struct icmp_mpls_ext_object_header_t *icmp_mpls_ext_object_header;
	u_int hlen, dport, mtu, obj_tlen, obj_class_num, obj_ctype;
	char buf[MAXHOSTNAMELEN + 100];
	struct cksum_vec vec[1];

	dp = (const struct icmp *)bp;
        ext_dp = (const struct icmp_ext_t *)bp;
	ip = (const struct ip *)bp2;
	str = buf;

	ND_TCHECK(dp->icmp_code);
	switch (dp->icmp_type) {

	case ICMP_ECHO:
	case ICMP_ECHOREPLY:
		ND_TCHECK(dp->icmp_seq);
		(void)snprintf(buf, sizeof(buf), "echo %s, id %u, seq %u",
                               dp->icmp_type == ICMP_ECHO ?
                               "request" : "reply",
                               EXTRACT_16BITS(&dp->icmp_id),
                               EXTRACT_16BITS(&dp->icmp_seq));
		break;

	case ICMP_UNREACH:
		ND_TCHECK(dp->icmp_ip.ip_dst);
		switch (dp->icmp_code) {

		case ICMP_UNREACH_PROTOCOL:
			ND_TCHECK(dp->icmp_ip.ip_p);
			(void)snprintf(buf, sizeof(buf),
			    "%s protocol %d unreachable",
			    ipaddr_string(ndo, &dp->icmp_ip.ip_dst),
			    dp->icmp_ip.ip_p);
			break;

		case ICMP_UNREACH_PORT:
			ND_TCHECK(dp->icmp_ip.ip_p);
			oip = &dp->icmp_ip;
			hlen = IP_HL(oip) * 4;
			ouh = (const struct udphdr *)(((const u_char *)oip) + hlen);
			ND_TCHECK(ouh->uh_dport);
			dport = EXTRACT_16BITS(&ouh->uh_dport);
			switch (oip->ip_p) {

			case IPPROTO_TCP:
				(void)snprintf(buf, sizeof(buf),
					"%s tcp port %s unreachable",
					ipaddr_string(ndo, &oip->ip_dst),
					tcpport_string(ndo, dport));
				break;

			case IPPROTO_UDP:
				(void)snprintf(buf, sizeof(buf),
					"%s udp port %s unreachable",
					ipaddr_string(ndo, &oip->ip_dst),
					udpport_string(ndo, dport));
				break;

			default:
				(void)snprintf(buf, sizeof(buf),
					"%s protocol %d port %d unreachable",
					ipaddr_string(ndo, &oip->ip_dst),
					oip->ip_p, dport);
				break;
			}
			break;

		case ICMP_UNREACH_NEEDFRAG:
		    {
			register const struct mtu_discovery *mp;
			mp = (const struct mtu_discovery *)(const u_char *)&dp->icmp_void;
			mtu = EXTRACT_16BITS(&mp->nexthopmtu);
			if (mtu) {
				(void)snprintf(buf, sizeof(buf),
				    "%s unreachable - need to frag (mtu %d)",
				    ipaddr_string(ndo, &dp->icmp_ip.ip_dst), mtu);
			} else {
				(void)snprintf(buf, sizeof(buf),
				    "%s unreachable - need to frag",
				    ipaddr_string(ndo, &dp->icmp_ip.ip_dst));
			}
		    }
			break;

		default:
			fmt = tok2str(unreach2str, "#%d %%s unreachable",
			    dp->icmp_code);
			(void)snprintf(buf, sizeof(buf), fmt,
			    ipaddr_string(ndo, &dp->icmp_ip.ip_dst));
			break;
		}
		break;

	case ICMP_REDIRECT:
		ND_TCHECK(dp->icmp_ip.ip_dst);
		fmt = tok2str(type2str, "redirect-#%d %%s to net %%s",
		    dp->icmp_code);
		(void)snprintf(buf, sizeof(buf), fmt,
		    ipaddr_string(ndo, &dp->icmp_ip.ip_dst),
		    ipaddr_string(ndo, &dp->icmp_gwaddr));
		break;

	case ICMP_ROUTERADVERT:
	    {
		register const struct ih_rdiscovery *ihp;
		register const struct id_rdiscovery *idp;
		u_int lifetime, num, size;

		(void)snprintf(buf, sizeof(buf), "router advertisement");
		cp = buf + strlen(buf);

		ihp = (const struct ih_rdiscovery *)&dp->icmp_void;
		ND_TCHECK(*ihp);
		(void)strncpy(cp, " lifetime ", sizeof(buf) - (cp - buf));
		cp = buf + strlen(buf);
		lifetime = EXTRACT_16BITS(&ihp->ird_lifetime);
		if (lifetime < 60) {
			(void)snprintf(cp, sizeof(buf) - (cp - buf), "%u",
			    lifetime);
		} else if (lifetime < 60 * 60) {
			(void)snprintf(cp, sizeof(buf) - (cp - buf), "%u:%02u",
			    lifetime / 60, lifetime % 60);
		} else {
			(void)snprintf(cp, sizeof(buf) - (cp - buf),
			    "%u:%02u:%02u",
			    lifetime / 3600,
			    (lifetime % 3600) / 60,
			    lifetime % 60);
		}
		cp = buf + strlen(buf);

		num = ihp->ird_addrnum;
		(void)snprintf(cp, sizeof(buf) - (cp - buf), " %d:", num);
		cp = buf + strlen(buf);

		size = ihp->ird_addrsiz;
		if (size != 2) {
			(void)snprintf(cp, sizeof(buf) - (cp - buf),
			    " [size %d]", size);
			break;
		}
		idp = (const struct id_rdiscovery *)&dp->icmp_data;
		while (num-- > 0) {
			ND_TCHECK(*idp);
			(void)snprintf(cp, sizeof(buf) - (cp - buf), " {%s %u}",
			    ipaddr_string(ndo, &idp->ird_addr),
			    EXTRACT_32BITS(&idp->ird_pref));
			cp = buf + strlen(buf);
			++idp;
		}
	    }
		break;

	case ICMP_TIMXCEED:
		ND_TCHECK(dp->icmp_ip.ip_dst);
		switch (dp->icmp_code) {

		case ICMP_TIMXCEED_INTRANS:
			str = "time exceeded in-transit";
			break;

		case ICMP_TIMXCEED_REASS:
			str = "ip reassembly time exceeded";
			break;

		default:
			(void)snprintf(buf, sizeof(buf), "time exceeded-#%d",
			    dp->icmp_code);
			break;
		}
		break;

	case ICMP_PARAMPROB:
		if (dp->icmp_code)
			(void)snprintf(buf, sizeof(buf),
			    "parameter problem - code %d", dp->icmp_code);
		else {
			ND_TCHECK(dp->icmp_pptr);
			(void)snprintf(buf, sizeof(buf),
			    "parameter problem - octet %d", dp->icmp_pptr);
		}
		break;

	case ICMP_MASKREPLY:
		ND_TCHECK(dp->icmp_mask);
		(void)snprintf(buf, sizeof(buf), "address mask is 0x%08x",
		    EXTRACT_32BITS(&dp->icmp_mask));
		break;

	case ICMP_TSTAMP:
		ND_TCHECK(dp->icmp_seq);
		(void)snprintf(buf, sizeof(buf),
		    "time stamp query id %u seq %u",
		    EXTRACT_16BITS(&dp->icmp_id),
		    EXTRACT_16BITS(&dp->icmp_seq));
		break;

	case ICMP_TSTAMPREPLY:
		ND_TCHECK(dp->icmp_ttime);
		(void)snprintf(buf, sizeof(buf),
		    "time stamp reply id %u seq %u: org %s",
                               EXTRACT_16BITS(&dp->icmp_id),
                               EXTRACT_16BITS(&dp->icmp_seq),
                               icmp_tstamp_print(EXTRACT_32BITS(&dp->icmp_otime)));

                (void)snprintf(buf+strlen(buf),sizeof(buf)-strlen(buf),", recv %s",
                         icmp_tstamp_print(EXTRACT_32BITS(&dp->icmp_rtime)));
                (void)snprintf(buf+strlen(buf),sizeof(buf)-strlen(buf),", xmit %s",
                         icmp_tstamp_print(EXTRACT_32BITS(&dp->icmp_ttime)));
                break;

	default:
		str = tok2str(icmp2str, "type-#%d", dp->icmp_type);
		break;
	}
	ND_PRINT((ndo, "ICMP %s, length %u", str, plen));
	if (ndo->ndo_vflag && !fragmented) { /* don't attempt checksumming if this is a frag */
		uint16_t sum, icmp_sum;

		if (ND_TTEST2(*bp, plen)) {
			vec[0].ptr = (const uint8_t *)(const void *)dp;
			vec[0].len = plen;
			sum = in_cksum(vec, 1);
			if (sum != 0) {
				icmp_sum = EXTRACT_16BITS(&dp->icmp_cksum);
				ND_PRINT((ndo, " (wrong icmp cksum %x (->%x)!)",
					     icmp_sum,
					     in_cksum_shouldbe(icmp_sum, sum)));
			}
		}
	}

        /*
         * print the remnants of the IP packet.
         * save the snaplength as this may get overidden in the IP printer.
         */
	if (ndo->ndo_vflag >= 1 && ICMP_ERRTYPE(dp->icmp_type)) {
		bp += 8;
		ND_PRINT((ndo, "\n\t"));
		ip = (const struct ip *)bp;
		ndo->ndo_snaplen = ndo->ndo_snapend - bp;
                snapend_save = ndo->ndo_snapend;
		ND_TCHECK_16BITS(&ip->ip_len);
		ip_print(ndo, bp, EXTRACT_16BITS(&ip->ip_len));
                ndo->ndo_snapend = snapend_save;
	}

        /*
         * Attempt to decode the MPLS extensions only for some ICMP types.
         */
        if (ndo->ndo_vflag >= 1 && plen > ICMP_EXTD_MINLEN && ICMP_MPLS_EXT_TYPE(dp->icmp_type)) {

            ND_TCHECK(*ext_dp);

            /*
             * Check first if the mpls extension header shows a non-zero length.
             * If the length field is not set then silently verify the checksum
             * to check if an extension header is present. This is expedient,
             * however not all implementations set the length field proper.
             */
            if (!ext_dp->icmp_length &&
                ND_TTEST2(ext_dp->icmp_ext_version_res, plen - ICMP_EXTD_MINLEN)) {
                vec[0].ptr = (const uint8_t *)(const void *)&ext_dp->icmp_ext_version_res;
                vec[0].len = plen - ICMP_EXTD_MINLEN;
                if (in_cksum(vec, 1)) {
                    return;
                }
            }

            ND_PRINT((ndo, "\n\tMPLS extension v%u",
                   ICMP_MPLS_EXT_EXTRACT_VERSION(*(ext_dp->icmp_ext_version_res))));

            /*
             * Sanity checking of the header.
             */
            if (ICMP_MPLS_EXT_EXTRACT_VERSION(*(ext_dp->icmp_ext_version_res)) !=
                ICMP_MPLS_EXT_VERSION) {
                ND_PRINT((ndo, " packet not supported"));
                return;
            }

            hlen = plen - ICMP_EXTD_MINLEN;
            if (ND_TTEST2(ext_dp->icmp_ext_version_res, hlen)) {
                vec[0].ptr = (const uint8_t *)(const void *)&ext_dp->icmp_ext_version_res;
                vec[0].len = hlen;
                ND_PRINT((ndo, ", checksum 0x%04x (%scorrect), length %u",
                       EXTRACT_16BITS(ext_dp->icmp_ext_checksum),
                       in_cksum(vec, 1) ? "in" : "",
                       hlen));
            }

            hlen -= 4; /* subtract common header size */
            obj_tptr = (const uint8_t *)ext_dp->icmp_ext_data;

            while (hlen > sizeof(struct icmp_mpls_ext_object_header_t)) {

                icmp_mpls_ext_object_header = (const struct icmp_mpls_ext_object_header_t *)obj_tptr;
                ND_TCHECK(*icmp_mpls_ext_object_header);
                obj_tlen = EXTRACT_16BITS(icmp_mpls_ext_object_header->length);
                obj_class_num = icmp_mpls_ext_object_header->class_num;
                obj_ctype = icmp_mpls_ext_object_header->ctype;
                obj_tptr += sizeof(struct icmp_mpls_ext_object_header_t);

                ND_PRINT((ndo, "\n\t  %s Object (%u), Class-Type: %u, length %u",
                       tok2str(icmp_mpls_ext_obj_values,"unknown",obj_class_num),
                       obj_class_num,
                       obj_ctype,
                       obj_tlen));

                hlen-=sizeof(struct icmp_mpls_ext_object_header_t); /* length field includes tlv header */

                /* infinite loop protection */
                if ((obj_class_num == 0) ||
                    (obj_tlen < sizeof(struct icmp_mpls_ext_object_header_t))) {
                    return;
                }
                obj_tlen-=sizeof(struct icmp_mpls_ext_object_header_t);

                switch (obj_class_num) {
                case 1:
                    switch(obj_ctype) {
                    case 1:
                        ND_TCHECK2(*obj_tptr, 4);
                        raw_label = EXTRACT_32BITS(obj_tptr);
                        ND_PRINT((ndo, "\n\t    label %u, exp %u", MPLS_LABEL(raw_label), MPLS_EXP(raw_label)));
                        if (MPLS_STACK(raw_label))
                            ND_PRINT((ndo, ", [S]"));
                        ND_PRINT((ndo, ", ttl %u", MPLS_TTL(raw_label)));
                        break;
                    default:
                        print_unknown_data(ndo, obj_tptr, "\n\t    ", obj_tlen);
                    }
                    break;

               /*
                *  FIXME those are the defined objects that lack a decoder
                *  you are welcome to contribute code ;-)
                */
                case 2:
                default:
                    print_unknown_data(ndo, obj_tptr, "\n\t    ", obj_tlen);
                    break;
                }
                if (hlen < obj_tlen)
                    break;
                hlen -= obj_tlen;
                obj_tptr += obj_tlen;
            }
        }

	return;
trunc:
	ND_PRINT((ndo, "[|icmp]"));
}
Example #19
0
static void
slow_marker_lacp_print(netdissect_options *ndo,
                       register const u_char *tptr, register u_int tlen) {

    const struct tlv_header_t *tlv_header;
    const u_char *tlv_tptr;
    u_int 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) {
        /* did we capture enough for fully decoding the tlv header ? */
        ND_TCHECK2(*tptr, sizeof(struct tlv_header_t));
        tlv_header = (const struct tlv_header_t *)tptr;
        tlv_len = tlv_header->length;

        ND_PRINT((ndo, "\n\t%s TLV (0x%02x), length %u",
               tok2str(slow_tlv_values,
                       "Unknown",
                       (slow_com_header->proto_subtype << 8) + tlv_header->type),
               tlv_header->type,
               tlv_len));

        if ((tlv_len < sizeof(struct tlv_header_t) ||
            tlv_len > tlen) &&
            tlv_header->type != LACP_TLV_TERMINATOR &&
            tlv_header->type != MARKER_TLV_TERMINATOR) {
            ND_PRINT((ndo, "\n\t-----trailing data-----"));
            print_unknown_data(ndo, tptr+sizeof(struct tlv_header_t), "\n\t  ", tlen);
            return;
        }

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

        /* did we capture enough for fully decoding the tlv ? */
        ND_TCHECK2(*tptr, tlv_len);

        switch((slow_com_header->proto_subtype << 8) + tlv_header->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):
            tlv_ptr.lacp_tlv_actor_partner_info = (const struct lacp_tlv_actor_partner_info_t *)tlv_tptr;

            ND_PRINT((ndo, "\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_16BITS(tlv_ptr.lacp_tlv_actor_partner_info->sys_pri),
                   EXTRACT_16BITS(tlv_ptr.lacp_tlv_actor_partner_info->key),
                   EXTRACT_16BITS(tlv_ptr.lacp_tlv_actor_partner_info->port),
                   EXTRACT_16BITS(tlv_ptr.lacp_tlv_actor_partner_info->port_pri),
                   bittok2str(lacp_tlv_actor_partner_info_state_values,
                              "none",
                              tlv_ptr.lacp_tlv_actor_partner_info->state)));

            break;

        case ((SLOW_PROTO_LACP << 8) + LACP_TLV_COLLECTOR_INFO):
            tlv_ptr.lacp_tlv_collector_info = (const struct lacp_tlv_collector_info_t *)tlv_tptr;

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

            break;

        case ((SLOW_PROTO_MARKER << 8) + MARKER_TLV_MARKER_INFO):
            tlv_ptr.marker_tlv_marker_info = (const struct marker_tlv_marker_info_t *)tlv_tptr;

            ND_PRINT((ndo, "\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_16BITS(tlv_ptr.marker_tlv_marker_info->req_port),
                   EXTRACT_32BITS(tlv_ptr.marker_tlv_marker_info->req_trans_id)));

            break;

            /* those two TLVs have the same structure -> fall through */
        case ((SLOW_PROTO_LACP << 8) + LACP_TLV_TERMINATOR):
        case ((SLOW_PROTO_MARKER << 8) + LACP_TLV_TERMINATOR):
            tlv_ptr.lacp_marker_tlv_terminator = (const struct lacp_marker_tlv_terminator_t *)tlv_tptr;
            if (tlv_len == 0) {
                tlv_len = sizeof(tlv_ptr.lacp_marker_tlv_terminator->pad) +
                    sizeof(struct tlv_header_t);
                /* tell the user that we modified the length field  */
                if (ndo->ndo_vflag>1)
                    ND_PRINT((ndo, " (=%u)", tlv_len));
                /* we have messed around with the length field - now we need to check
                 * again if there are enough bytes on the wire for the hexdump */
                ND_TCHECK2(tlv_ptr.lacp_marker_tlv_terminator->pad[0],
                        sizeof(tlv_ptr.lacp_marker_tlv_terminator->pad));
            }

            break;

        default:
            if (ndo->ndo_vflag <= 1)
                print_unknown_data(ndo, tlv_tptr, "\n\t  ", tlv_tlen);
            break;
        }
        /* 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;
trunc:
    ND_PRINT((ndo, "\n\t\t packet exceeded snapshot"));
}
Example #20
0
void
pgm_print(register const u_char *bp, register u_int length,
	  register const u_char *bp2)
{
	register const struct pgm_header *pgm;
	register const struct ip *ip;
	register char ch;
	u_int16_t sport, dport;
	int addr_size;
	const void *nla;
	int nla_af;
#ifdef INET6
	char nla_buf[INET6_ADDRSTRLEN];
	register const struct ip6_hdr *ip6;
#else
	char nla_buf[INET_ADDRSTRLEN];
#endif
	u_int8_t opt_type, opt_len, flags1, flags2;
	u_int32_t seq, opts_len, len, offset;

	pgm = (struct pgm_header *)bp;
	ip = (struct ip *)bp2;
#ifdef INET6
	if (IP_V(ip) == 6)
		ip6 = (struct ip6_hdr *)bp2;
	else
		ip6 = NULL;
#else /* INET6 */
	if (IP_V(ip) == 6) {
		(void)printf("Can't handle IPv6");
		return;
	}
#endif /* INET6 */
	ch = '\0';
	if (!TTEST(pgm->pgm_dport)) {
#ifdef INET6
		if (ip6) {
			(void)printf("%s > %s: [|pgm]",
				ip6addr_string(&ip6->ip6_src),
				ip6addr_string(&ip6->ip6_dst));
			return;
		} else
#endif /* INET6 */
		{
			(void)printf("%s > %s: [|pgm]",
				ipaddr_string(&ip->ip_src),
				ipaddr_string(&ip->ip_dst));
			return;
		}
	}

	sport = EXTRACT_16BITS(&pgm->pgm_sport);
	dport = EXTRACT_16BITS(&pgm->pgm_dport);

#ifdef INET6
	if (ip6) {
		if (ip6->ip6_nxt == IPPROTO_PGM) {
			(void)printf("%s.%s > %s.%s: ",
				ip6addr_string(&ip6->ip6_src),
				tcpport_string(sport),
				ip6addr_string(&ip6->ip6_dst),
				tcpport_string(dport));
		} else {
			(void)printf("%s > %s: ",
				tcpport_string(sport), tcpport_string(dport));
		}
	} else
#endif /*INET6*/
	{
		if (ip->ip_p == IPPROTO_PGM) {
			(void)printf("%s.%s > %s.%s: ",
				ipaddr_string(&ip->ip_src),
				tcpport_string(sport),
				ipaddr_string(&ip->ip_dst),
				tcpport_string(dport));
		} else {
			(void)printf("%s > %s: ",
				tcpport_string(sport), tcpport_string(dport));
		}
	}

	TCHECK(*pgm);

        (void)printf("PGM, length %u", pgm->pgm_length);

        if (!vflag)
            return;

        if (length > pgm->pgm_length)
            length = pgm->pgm_length;

	(void)printf(" 0x%02x%02x%02x%02x%02x%02x ",
		     pgm->pgm_gsid[0],
                     pgm->pgm_gsid[1],
                     pgm->pgm_gsid[2],
		     pgm->pgm_gsid[3],
                     pgm->pgm_gsid[4],
                     pgm->pgm_gsid[5]);
	switch (pgm->pgm_type) {
	case PGM_SPM: {
	    struct pgm_spm *spm;

	    spm = (struct pgm_spm *)(pgm + 1);
	    TCHECK(*spm);

	    switch (EXTRACT_16BITS(&spm->pgms_nla_afi)) {
	    case AFI_IP:
		addr_size = sizeof(struct in_addr);
		nla_af = AF_INET;
		break;
#ifdef INET6
	    case AFI_IP6:
		addr_size = sizeof(struct in6_addr);
		nla_af = AF_INET6;
		break;
#endif
	    default:
		goto trunc;
		break;
	    }
	    bp = (u_char *) (spm + 1);
	    TCHECK2(*bp, addr_size);
	    nla = bp;
	    bp += addr_size;

	    inet_ntop(nla_af, nla, nla_buf, sizeof(nla_buf));
	    (void)printf("SPM seq %u trail %u lead %u nla %s",
			 EXTRACT_32BITS(&spm->pgms_seq),
                         EXTRACT_32BITS(&spm->pgms_trailseq),
			 EXTRACT_32BITS(&spm->pgms_leadseq),
                         nla_buf);
	    break;
	}

	case PGM_POLL: {
	    struct pgm_poll *poll;

	    poll = (struct pgm_poll *)(pgm + 1);
	    TCHECK(*poll);
	    (void)printf("POLL seq %u round %u",
			 EXTRACT_32BITS(&poll->pgmp_seq),
                         EXTRACT_16BITS(&poll->pgmp_round));
	    bp = (u_char *) (poll + 1);
	    break;
	}
	case PGM_POLR: {
	    struct pgm_polr *polr;
	    u_int32_t ivl, rnd, mask;

	    polr = (struct pgm_polr *)(pgm + 1);
	    TCHECK(*polr);

	    switch (EXTRACT_16BITS(&polr->pgmp_nla_afi)) {
	    case AFI_IP:
		addr_size = sizeof(struct in_addr);
		nla_af = AF_INET;
		break;
#ifdef INET6
	    case AFI_IP6:
		addr_size = sizeof(struct in6_addr);
		nla_af = AF_INET6;
		break;
#endif
	    default:
		goto trunc;
		break;
	    }
	    bp = (u_char *) (polr + 1);
	    TCHECK2(*bp, addr_size);
	    nla = bp;
	    bp += addr_size;

	    inet_ntop(nla_af, nla, nla_buf, sizeof(nla_buf));

	    TCHECK2(*bp, sizeof(u_int32_t));
	    ivl = EXTRACT_32BITS(bp);
	    bp += sizeof(u_int32_t);

	    TCHECK2(*bp, sizeof(u_int32_t));
	    rnd = EXTRACT_32BITS(bp);
	    bp += sizeof(u_int32_t);

	    TCHECK2(*bp, sizeof(u_int32_t));
	    mask = EXTRACT_32BITS(bp);
	    bp += sizeof(u_int32_t);

	    (void)printf("POLR seq %u round %u nla %s ivl %u rnd 0x%08x "
			 "mask 0x%08x", EXTRACT_32BITS(&polr->pgmp_seq),
			 EXTRACT_16BITS(&polr->pgmp_round), nla_buf, ivl, rnd, mask);
	    break;
	}
	case PGM_ODATA: {
	    struct pgm_data *odata;

	    odata = (struct pgm_data *)(pgm + 1);
	    TCHECK(*odata);
	    (void)printf("ODATA trail %u seq %u",
			 EXTRACT_32BITS(&odata->pgmd_trailseq),
			 EXTRACT_32BITS(&odata->pgmd_seq));
	    bp = (u_char *) (odata + 1);
	    break;
	}

	case PGM_RDATA: {
	    struct pgm_data *rdata;

	    rdata = (struct pgm_data *)(pgm + 1);
	    TCHECK(*rdata);
	    (void)printf("RDATA trail %u seq %u",
			 EXTRACT_32BITS(&rdata->pgmd_trailseq),
			 EXTRACT_32BITS(&rdata->pgmd_seq));
	    bp = (u_char *) (rdata + 1);
	    break;
	}

	case PGM_NAK:
	case PGM_NULLNAK:
	case PGM_NCF: {
	    struct pgm_nak *nak;
	    const void *source, *group;
	    int source_af, group_af;
#ifdef INET6
	    char source_buf[INET6_ADDRSTRLEN], group_buf[INET6_ADDRSTRLEN];
#else
	    char source_buf[INET_ADDRSTRLEN], group_buf[INET_ADDRSTRLEN];
#endif

	    nak = (struct pgm_nak *)(pgm + 1);
	    TCHECK(*nak);

	    /*
	     * Skip past the source, saving info along the way
	     * and stopping if we don't have enough.
	     */
	    switch (EXTRACT_16BITS(&nak->pgmn_source_afi)) {
	    case AFI_IP:
		addr_size = sizeof(struct in_addr);
		source_af = AF_INET;
		break;
#ifdef INET6
	    case AFI_IP6:
		addr_size = sizeof(struct in6_addr);
		source_af = AF_INET6;
		break;
#endif
	    default:
		goto trunc;
		break;
	    }
	    bp = (u_char *) (nak + 1);
	    TCHECK2(*bp, addr_size);
	    source = bp;
	    bp += addr_size;

	    /*
	     * Skip past the group, saving info along the way
	     * and stopping if we don't have enough.
	     */
	    switch (EXTRACT_16BITS(bp)) {
	    case AFI_IP:
		addr_size = sizeof(struct in_addr);
		group_af = AF_INET;
		break;
#ifdef INET6
	    case AFI_IP6:
		addr_size = sizeof(struct in6_addr);
		group_af = AF_INET6;
		break;
#endif
	    default:
		goto trunc;
		break;
	    }
	    bp += (2 * sizeof(u_int16_t));
	    TCHECK2(*bp, addr_size);
	    group = bp;
	    bp += addr_size;

	    /*
	     * Options decoding can go here.
	     */
	    inet_ntop(source_af, source, source_buf, sizeof(source_buf));
	    inet_ntop(group_af, group, group_buf, sizeof(group_buf));
	    switch (pgm->pgm_type) {
		case PGM_NAK:
		    (void)printf("NAK ");
		    break;
		case PGM_NULLNAK:
		    (void)printf("NNAK ");
		    break;
		case PGM_NCF:
		    (void)printf("NCF ");
		    break;
		default:
                    break;
	    }
	    (void)printf("(%s -> %s), seq %u",
			 source_buf, group_buf, EXTRACT_32BITS(&nak->pgmn_seq));
	    break;
	}

	case PGM_SPMR:
	    (void)printf("SPMR");
	    break;

	default:
	    (void)printf("UNKNOWN type %0x02x", pgm->pgm_type);
	    break;

	}
	if (pgm->pgm_options & PGM_OPT_BIT_PRESENT) {      

	    /*
	     * make sure there's enough for the first option header
	     */
	    if (!TTEST2(*bp, PGM_MIN_OPT_LEN)) {
		(void)printf("[|OPT]");
		return;
	    } 

	    /*
	     * That option header MUST be an OPT_LENGTH option
	     * (see the first paragraph of section 9.1 in RFC 3208).
	     */
	    opt_type = *bp++;
	    if ((opt_type & PGM_OPT_MASK) != PGM_OPT_LENGTH) {
		(void)printf("[First option bad, should be PGM_OPT_LENGTH, is %u]", opt_type & PGM_OPT_MASK);
		return;
	    }
	    opt_len = *bp++;
	    if (opt_len != 4) {
		(void)printf("[Bad OPT_LENGTH option, length %u != 4]", opt_len);
		return;
	    }
	    opts_len = EXTRACT_16BITS(bp);
	    if (opts_len < 4) {
		(void)printf("[Bad total option length %u < 4]", opts_len);
		return;
	    }
	    bp += sizeof(u_int16_t);
	    (void)printf(" OPTS LEN %d", opts_len);
	    opts_len -= 4;

	    while (opts_len) {
		if (opts_len < PGM_MIN_OPT_LEN) {
		    (void)printf("[Total option length leaves no room for final option]");
		    return;
		}
		opt_type = *bp++;
		opt_len = *bp++;
		if (opt_len < PGM_MIN_OPT_LEN) {
		    (void)printf("[Bad option, length %u < %u]", opt_len,
		        PGM_MIN_OPT_LEN);
		    break;
		}
		if (opts_len < opt_len) {
		    (void)printf("[Total option length leaves no room for final option]");
		    return;
		}
		if (!TTEST2(*bp, opt_len - 2)) {
		    (void)printf(" [|OPT]");
		    return;
		} 

		switch (opt_type & PGM_OPT_MASK) {
		case PGM_OPT_LENGTH:
		    if (opt_len != 4) {
			(void)printf("[Bad OPT_LENGTH option, length %u != 4]", opt_len);
			return;
		    }
		    (void)printf(" OPTS LEN (extra?) %d", EXTRACT_16BITS(bp));
		    bp += sizeof(u_int16_t);
		    opts_len -= 4;
		    break;

		case PGM_OPT_FRAGMENT:
		    if (opt_len != 16) {
			(void)printf("[Bad OPT_FRAGMENT option, length %u != 16]", opt_len);
			return;
		    }
		    flags1 = *bp++;
		    flags2 = *bp++;
		    seq = EXTRACT_32BITS(bp);
		    bp += sizeof(u_int32_t);
		    offset = EXTRACT_32BITS(bp);
		    bp += sizeof(u_int32_t);
		    len = EXTRACT_32BITS(bp);
		    bp += sizeof(u_int32_t);
		    (void)printf(" FRAG seq %u off %u len %u", seq, offset, len);
		    opts_len -= 16;
		    break;

		case PGM_OPT_NAK_LIST:
		    flags1 = *bp++;
		    flags2 = *bp++;
		    opt_len -= sizeof(u_int32_t);	/* option header */
		    (void)printf(" NAK LIST");
		    while (opt_len) {
			if (opt_len < sizeof(u_int32_t)) {
			    (void)printf("[Option length not a multiple of 4]");
			    return;
			}
			TCHECK2(*bp, sizeof(u_int32_t));
			(void)printf(" %u", EXTRACT_32BITS(bp));
			bp += sizeof(u_int32_t);
			opt_len -= sizeof(u_int32_t);
			opts_len -= sizeof(u_int32_t);
		    }
		    break;

		case PGM_OPT_JOIN:
		    if (opt_len != 8) {
			(void)printf("[Bad OPT_JOIN option, length %u != 8]", opt_len);
			return;
		    }
		    flags1 = *bp++;
		    flags2 = *bp++;
		    seq = EXTRACT_32BITS(bp);
		    bp += sizeof(u_int32_t);
		    (void)printf(" JOIN %u", seq);
		    opts_len -= 8;
		    break;

		case PGM_OPT_NAK_BO_IVL:
		    if (opt_len != 12) {
			(void)printf("[Bad OPT_NAK_BO_IVL option, length %u != 12]", opt_len);
			return;
		    }
		    flags1 = *bp++;
		    flags2 = *bp++;
		    offset = EXTRACT_32BITS(bp);
		    bp += sizeof(u_int32_t);
		    seq = EXTRACT_32BITS(bp);
		    bp += sizeof(u_int32_t);
		    (void)printf(" BACKOFF ivl %u ivlseq %u", offset, seq);
		    opts_len -= 12;
		    break;

		case PGM_OPT_NAK_BO_RNG:
		    if (opt_len != 12) {
			(void)printf("[Bad OPT_NAK_BO_RNG option, length %u != 12]", opt_len);
			return;
		    }
		    flags1 = *bp++;
		    flags2 = *bp++;
		    offset = EXTRACT_32BITS(bp);
		    bp += sizeof(u_int32_t);
		    seq = EXTRACT_32BITS(bp);
		    bp += sizeof(u_int32_t);
		    (void)printf(" BACKOFF max %u min %u", offset, seq);
		    opts_len -= 12;
		    break;

		case PGM_OPT_REDIRECT:
		    flags1 = *bp++;
		    flags2 = *bp++;
		    switch (EXTRACT_16BITS(bp)) {
		    case AFI_IP:
			addr_size = sizeof(struct in_addr);
			nla_af = AF_INET;
			break;
#ifdef INET6
		    case AFI_IP6:
			addr_size = sizeof(struct in6_addr);
			nla_af = AF_INET6;
			break;
#endif
		    default:
			goto trunc;
			break;
		    }
		    bp += (2 * sizeof(u_int16_t));
		    if (opt_len != 4 + addr_size) {
			(void)printf("[Bad OPT_REDIRECT option, length %u != 4 + address size]", opt_len);
			return;
		    }
		    TCHECK2(*bp, addr_size);
		    nla = bp;
		    bp += addr_size;

		    inet_ntop(nla_af, nla, nla_buf, sizeof(nla_buf));
		    (void)printf(" REDIRECT %s",  (char *)nla);
		    opts_len -= 4 + addr_size;
		    break;

		case PGM_OPT_PARITY_PRM:
		    if (opt_len != 8) {
			(void)printf("[Bad OPT_PARITY_PRM option, length %u != 8]", opt_len);
			return;
		    }
		    flags1 = *bp++;
		    flags2 = *bp++;
		    len = EXTRACT_32BITS(bp);
		    bp += sizeof(u_int32_t);
		    (void)printf(" PARITY MAXTGS %u", len);
		    opts_len -= 8;
		    break;

		case PGM_OPT_PARITY_GRP:
		    if (opt_len != 8) {
			(void)printf("[Bad OPT_PARITY_GRP option, length %u != 8]", opt_len);
			return;
		    }
		    flags1 = *bp++;
		    flags2 = *bp++;
		    seq = EXTRACT_32BITS(bp);
		    bp += sizeof(u_int32_t);
		    (void)printf(" PARITY GROUP %u", seq);
		    opts_len -= 8;
		    break;

		case PGM_OPT_CURR_TGSIZE:
		    if (opt_len != 8) {
			(void)printf("[Bad OPT_CURR_TGSIZE option, length %u != 8]", opt_len);
			return;
		    }
		    flags1 = *bp++;
		    flags2 = *bp++;
		    len = EXTRACT_32BITS(bp);
		    bp += sizeof(u_int32_t);
		    (void)printf(" PARITY ATGS %u", len);
		    opts_len -= 8;
		    break;

		case PGM_OPT_NBR_UNREACH:
		    if (opt_len != 4) {
			(void)printf("[Bad OPT_NBR_UNREACH option, length %u != 4]", opt_len);
			return;
		    }
		    flags1 = *bp++;
		    flags2 = *bp++;
		    (void)printf(" NBR_UNREACH");
		    opts_len -= 4;
		    break;

		case PGM_OPT_PATH_NLA:
		    (void)printf(" PATH_NLA [%d]", opt_len);
		    bp += opt_len;
		    opts_len -= opt_len;
		    break;

		case PGM_OPT_SYN:
		    if (opt_len != 4) {
			(void)printf("[Bad OPT_SYN option, length %u != 4]", opt_len);
			return;
		    }
		    flags1 = *bp++;
		    flags2 = *bp++;
		    (void)printf(" SYN");
		    opts_len -= 4;
		    break;

		case PGM_OPT_FIN:
		    if (opt_len != 4) {
			(void)printf("[Bad OPT_FIN option, length %u != 4]", opt_len);
			return;
		    }
		    flags1 = *bp++;
		    flags2 = *bp++;
		    (void)printf(" FIN");
		    opts_len -= 4;
		    break;

		case PGM_OPT_RST:
		    if (opt_len != 4) {
			(void)printf("[Bad OPT_RST option, length %u != 4]", opt_len);
			return;
		    }
		    flags1 = *bp++;
		    flags2 = *bp++;
		    (void)printf(" RST");
		    opts_len -= 4;
		    break;

		case PGM_OPT_CR:
		    (void)printf(" CR");
		    bp += opt_len;
		    opts_len -= opt_len;
		    break;

		case PGM_OPT_CRQST:
		    if (opt_len != 4) {
			(void)printf("[Bad OPT_CRQST option, length %u != 4]", opt_len);
			return;
		    }
		    flags1 = *bp++;
		    flags2 = *bp++;
		    (void)printf(" CRQST");
		    opts_len -= 4;
		    break;

		default:
		    (void)printf(" OPT_%02X [%d] ", opt_type, opt_len);
		    bp += opt_len;
		    opts_len -= opt_len;
		    break;
		}

		if (opt_type & PGM_OPT_END)
		    break;
	     }
	}

	(void)printf(" [%u]", EXTRACT_16BITS(&pgm->pgm_length));

	return;

trunc:
	fputs("[|pgm]", stdout);
	if (ch != '\0')
		putchar('>');
}
void
udld_print (const u_char *pptr, u_int length)
{
    int code, type, len;
    const u_char *tptr;

    if (length < UDLD_HEADER_LEN)
        goto trunc;

    tptr = pptr; 

    if (!TTEST2(*tptr, UDLD_HEADER_LEN))	
	goto trunc;

    code = UDLD_EXTRACT_OPCODE(*tptr);

    printf("UDLDv%u, Code %s (%x), Flags [%s] (0x%02x), length %u", 
           UDLD_EXTRACT_VERSION(*tptr),
           tok2str(udld_code_values, "Reserved", code),
           code,
           bittok2str(udld_flags_values, "none", *(tptr+1)),
           *(tptr+1),
           length);

    /*
     * In non-verbose mode, just print version and opcode type
     */
    if (vflag < 1) {
	return;
    }

    printf("\n\tChecksum 0x%04x (unverified)", EXTRACT_16BITS(tptr+2));

    tptr += UDLD_HEADER_LEN;

    while (tptr < (pptr+length)) {

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

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

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

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

        switch (type) {
        case UDLD_DEVICE_ID_TLV:
        case UDLD_PORT_ID_TLV:
        case UDLD_ECHO_TLV:
        case UDLD_DEVICE_NAME_TLV: 
            printf(", %s", tptr);
            break;

        case UDLD_MESSAGE_INTERVAL_TLV: 
        case UDLD_TIMEOUT_INTERVAL_TLV:
            printf(", %us", (*tptr));
            break;

        case UDLD_SEQ_NUMBER_TLV:
            printf(", %u", EXTRACT_32BITS(tptr));
            break;

        default:
            break;
        }	
        tptr += len;
    }

    return;

 trunc:
    printf("[|udld]");
}
Example #22
0
void
icmp_print(const u_char *bp, u_int length, const u_char *bp2)
{
	const struct icmp *dp;
	const struct ip *ip;
	const char *str, *fmt;
	const struct ip *oip;
	const struct udphdr *ouh;
	u_int hlen, dport, mtu;
	char buf[MAXHOSTNAMELEN+256];
	char buf2[MAXHOSTNAMELEN+256];

	dp = (struct icmp *)bp;
	ip = (struct ip *)bp2;
	str = buf;

        (void)printf("%s > %s: ",
		ipaddr_string(&ip->ip_src),
		ipaddr_string(&ip->ip_dst));

	TCHECK(dp->icmp_code);
	if (qflag) 
		(void) snprintf(buf, sizeof buf, "%u %u", dp->icmp_type,
		    dp->icmp_code);
	else switch (dp->icmp_type) {

	case ICMP_ECHOREPLY:
	case ICMP_ECHO:
		if (vflag) {
			TCHECK(dp->icmp_seq);
			(void)snprintf(buf, sizeof buf,
				       "echo %s (id:%04x seq:%u)",
				       (dp->icmp_type == ICMP_ECHO)?
				       "request": "reply",
				       ntohs(dp->icmp_id),
				       ntohs(dp->icmp_seq));
		} else
			str = tok2str(icmp2str, "type-#%u", dp->icmp_type);
		break;

	case ICMP_UNREACH:
		TCHECK(dp->icmp_ip.ip_dst);
		switch (dp->icmp_code) {

		case ICMP_UNREACH_PROTOCOL:
			TCHECK(dp->icmp_ip.ip_p);
			(void)snprintf(buf, sizeof buf,
				       "%s protocol %u unreachable",
				       ipaddr_string(&dp->icmp_ip.ip_dst),
				       dp->icmp_ip.ip_p);
			break;

		case ICMP_UNREACH_PORT:
			TCHECK(dp->icmp_ip.ip_p);
			oip = &dp->icmp_ip;
			hlen = oip->ip_hl * 4;
			ouh = (struct udphdr *)(((u_char *)oip) + hlen);
			TCHECK(ouh->uh_dport);
			dport = ntohs(ouh->uh_dport);
			switch (oip->ip_p) {

			case IPPROTO_TCP:
				(void)snprintf(buf, sizeof buf,
					"%s tcp port %s unreachable",
					ipaddr_string(&oip->ip_dst),
					tcpport_string(dport));
				break;

			case IPPROTO_UDP:
				(void)snprintf(buf, sizeof buf,
					"%s udp port %s unreachable",
					ipaddr_string(&oip->ip_dst),
					udpport_string(dport));
				break;

			default:
				(void)snprintf(buf, sizeof buf,
					"%s protocol %u port %u unreachable",
					ipaddr_string(&oip->ip_dst),
					oip->ip_p, dport);
				break;
			}
			break;

		case ICMP_UNREACH_NEEDFRAG:
			{
			const struct mtu_discovery *mp;

			mp = (struct mtu_discovery *)&dp->icmp_void;
                        mtu = EXTRACT_16BITS(&mp->nexthopmtu);
                        if (mtu)
			    (void)snprintf(buf, sizeof buf,
				"%s unreachable - need to frag (mtu %u)",
				ipaddr_string(&dp->icmp_ip.ip_dst), mtu);
                        else
			    (void)snprintf(buf, sizeof buf,
				"%s unreachable - need to frag",
				ipaddr_string(&dp->icmp_ip.ip_dst));
			}
			break;

		default:
			fmt = tok2str(unreach2str, "#%u %%s unreachable",
			    dp->icmp_code);
			(void)snprintf(buf, sizeof buf, fmt,
			    ipaddr_string(&dp->icmp_ip.ip_dst));
			break;
		}
		break;

	case ICMP_REDIRECT:
		TCHECK(dp->icmp_ip.ip_dst);
		fmt = tok2str(type2str, "redirect-#%u %%s to net %%s",
		    dp->icmp_code);
		(void)snprintf(buf, sizeof buf, fmt,
		    ipaddr_string(&dp->icmp_ip.ip_dst),
		    ipaddr_string(&dp->icmp_gwaddr));
		break;

	case ICMP_ROUTERADVERT:
		{
		const struct ih_rdiscovery *ihp;
		const struct id_rdiscovery *idp;
		u_int lifetime, num, size;

		(void)strlcpy(buf, "router advertisement", sizeof(buf));

		ihp = (struct ih_rdiscovery *)&dp->icmp_void;
		TCHECK(*ihp);
		(void)strlcat(buf, " lifetime ", sizeof(buf));
		lifetime = EXTRACT_16BITS(&ihp->ird_lifetime);
		if (lifetime < 60)
			(void)snprintf(buf2, sizeof(buf2), "%u", lifetime);
		else if (lifetime < 60 * 60)
			(void)snprintf(buf2, sizeof(buf2), "%u:%02u",
			    lifetime / 60, lifetime % 60);
		else
			(void)snprintf(buf2, sizeof(buf2), "%u:%02u:%02u",
			    lifetime / 3600, (lifetime % 3600) / 60,
			    lifetime % 60);
		strlcat(buf, buf2, sizeof(buf));

		num = ihp->ird_addrnum;
		(void)snprintf(buf2, sizeof(buf2), " %u:", num);
		strlcat(buf, buf2, sizeof(buf));

		size = ihp->ird_addrsiz;
		if (size != 2) {
			(void)snprintf(buf2, sizeof(buf2), " [size %u]", size);
			strlcat(buf, buf2, sizeof(buf));
			break;
		}
		idp = (struct id_rdiscovery *)&dp->icmp_data;
		while (num-- > 0) {
			TCHECK(*idp);
			(void)snprintf(buf2, sizeof(buf2), " {%s %u}",
			    ipaddr_string(&idp->ird_addr),
			    EXTRACT_32BITS(&idp->ird_pref));
			strlcat(buf, buf2, sizeof(buf));
		}
		}
		break;

	case ICMP_TIMXCEED:
		TCHECK(dp->icmp_ip.ip_dst);
		switch (dp->icmp_code) {

		case ICMP_TIMXCEED_INTRANS:
			str = "time exceeded in-transit";
			break;

		case ICMP_TIMXCEED_REASS:
			str = "ip reassembly time exceeded";
			break;

		default:
			(void)snprintf(buf, sizeof buf,
				"time exceeded-#%u", dp->icmp_code);
			break;
		}
		break;

	case ICMP_PARAMPROB:
		switch (dp->icmp_code) {
		case ICMP_PARAMPROB_OPTABSENT:
			str = "requested option absent";
			break;
		case ICMP_PARAMPROB_LENGTH:
			snprintf(buf, sizeof buf, "bad length %u", dp->icmp_pptr);
			break;
		default:
			TCHECK(dp->icmp_pptr);
			(void)snprintf(buf, sizeof buf,
				"parameter problem - octet %u",
				dp->icmp_pptr);
			break;
		}
		break;

	case ICMP_MASKREPLY:
		TCHECK(dp->icmp_mask);
		(void)snprintf(buf, sizeof buf, "address mask is 0x%08x",
		    (u_int32_t)ntohl(dp->icmp_mask));
		break;

	default:
		str = tok2str(icmp2str, "type-#%u", dp->icmp_type);
		break;
	}
	(void)printf("icmp: %s", str);
	if (vflag) {
		u_int16_t sum;
		if (TTEST2(dp->icmp_type, length)) {
			sum = in_cksum((const u_short *)dp, length, 0);
			if (sum != 0)
				(void)printf(" [bad icmp cksum %x!]", sum);
			else
				(void)printf(" [icmp cksum ok]");
		}
    }
	if (vflag > 1 && !ICMP_INFOTYPE(dp->icmp_type) &&
	    TTEST(dp->icmp_ip)) {
		(void)printf(" for ");
		oip = &dp->icmp_ip;
		ip_print((u_char *)oip, ntohs(oip->ip_len));
	}
	return;
trunc:
	fputs("[|icmp]", stdout);
}
Example #23
0
/*
 * Print AppleTalk LLAP packets.
 */
u_int
llap_print(register const u_char *bp, u_int length)
{
    register const struct LAP *lp;
    register const struct atDDP *dp;
    register const struct atShortDDP *sdp;
    u_short snet;
    u_int hdrlen;

    if (length < sizeof(*lp)) {
        (void)printf(" [|llap %u]", length);
        return (length);
    }
    lp = (const struct LAP *)bp;
    bp += sizeof(*lp);
    length -= sizeof(*lp);
    hdrlen = sizeof(*lp);
    switch (lp->type) {

    case lapShortDDP:
        if (length < ddpSSize) {
            (void)printf(" [|sddp %u]", length);
            return (length);
        }
        sdp = (const struct atShortDDP *)bp;
        printf("%s.%s",
               ataddr_string(0, lp->src), ddpskt_string(sdp->srcSkt));
        printf(" > %s.%s:",
               ataddr_string(0, lp->dst), ddpskt_string(sdp->dstSkt));
        bp += ddpSSize;
        length -= ddpSSize;
        hdrlen += ddpSSize;
        ddp_print(bp, length, sdp->type, 0, lp->src, sdp->srcSkt);
        break;

    case lapDDP:
        if (length < ddpSize) {
            (void)printf(" [|ddp %u]", length);
            return (length);
        }
        dp = (const struct atDDP *)bp;
        snet = EXTRACT_16BITS(&dp->srcNet);
        printf("%s.%s", ataddr_string(snet, dp->srcNode),
               ddpskt_string(dp->srcSkt));
        printf(" > %s.%s:",
               ataddr_string(EXTRACT_16BITS(&dp->dstNet), dp->dstNode),
               ddpskt_string(dp->dstSkt));
        bp += ddpSize;
        length -= ddpSize;
        hdrlen += ddpSize;
        ddp_print(bp, length, dp->type, snet, dp->srcNode, dp->srcSkt);
        break;

#ifdef notdef
    case lapKLAP:
        klap_print(bp, length);
        break;
#endif

    default:
        printf("%d > %d at-lap#%d %u",
               lp->src, lp->dst, lp->type, length);
        break;
    }
    return (hdrlen);
}
Example #24
0
void
msdp_print(netdissect_options *ndo, const u_char *sp, u_int length)
{
	unsigned int type, len;

	ND_TCHECK2(*sp, 3);
	/* See if we think we're at the beginning of a compound packet */
	type = *sp;
	len = EXTRACT_16BITS(sp + 1);
	if (len > 1500 || len < 3 || type == 0 || type > MSDP_TYPE_MAX)
		goto trunc;	/* not really truncated, but still not decodable */
	ND_PRINT((ndo, " msdp:"));
	while (length > 0) {
		ND_TCHECK2(*sp, 3);
		type = *sp;
		len = EXTRACT_16BITS(sp + 1);
		if (len > 1400 || ndo->ndo_vflag)
			ND_PRINT((ndo, " [len %u]", len));
		if (len < 3)
			goto trunc;
		sp += 3;
		length -= 3;
		switch (type) {
		case 1:	/* IPv4 Source-Active */
		case 3: /* IPv4 Source-Active Response */
			if (type == 1)
				ND_PRINT((ndo, " SA"));
			else
				ND_PRINT((ndo, " SA-Response"));
			ND_TCHECK(*sp);
			ND_PRINT((ndo, " %u entries", *sp));
			if ((u_int)((*sp * 12) + 8) < len) {
				ND_PRINT((ndo, " [w/data]"));
				if (ndo->ndo_vflag > 1) {
					ND_PRINT((ndo, " "));
					ip_print(ndo, sp + *sp * 12 + 8 - 3,
					         len - (*sp * 12 + 8));
				}
			}
			break;
		case 2:
			ND_PRINT((ndo, " SA-Request"));
			ND_TCHECK2(*sp, 5);
			ND_PRINT((ndo, " for %s", ipaddr_string(sp + 1)));
			break;
		case 4:
			ND_PRINT((ndo, " Keepalive"));
			if (len != 3)
				ND_PRINT((ndo, "[len=%d] ", len));
			break;
		case 5:
			ND_PRINT((ndo, " Notification"));
			break;
		default:
			ND_PRINT((ndo, " [type=%d len=%d]", type, len));
			break;
		}
		sp += (len - 3);
		length -= (len - 3);
	}
	return;
trunc:
	ND_PRINT((ndo, " [|msdp]"));
}
Example #25
0
/**
 * dccp_print - show dccp packet
 * @bp - beginning of dccp packet
 * @data2 - beginning of enclosing
 * @len - lenght of ip packet
 */
void dccp_print(netdissect_options *ndo, const u_char *bp, const u_char *data2,
		u_int len)
{
	const struct dccp_hdr *dh;
	const struct ip *ip;
#ifdef INET6
	const struct ip6_hdr *ip6;
#endif
	const u_char *cp;
	u_short sport, dport;
	u_int hlen;
	u_int fixed_hdrlen;
	uint8_t	dccph_type;

	dh = (const struct dccp_hdr *)bp;

	ip = (const struct ip *)data2;
#ifdef INET6
	if (IP_V(ip) == 6)
		ip6 = (const struct ip6_hdr *)data2;
	else
		ip6 = NULL;
#endif /*INET6*/

	/* make sure we have enough data to look at the X bit */
	cp = (const u_char *)(dh + 1);
	if (cp > ndo->ndo_snapend) {
		ND_PRINT((ndo, "[Invalid packet|dccp]"));
		return;
	}
	if (len < sizeof(struct dccp_hdr)) {
		ND_PRINT((ndo, "truncated-dccp - %u bytes missing!",
			  len - (u_int)sizeof(struct dccp_hdr)));
		return;
	}

	/* get the length of the generic header */
	fixed_hdrlen = dccp_basic_hdr_len(dh);
	if (len < fixed_hdrlen) {
		ND_PRINT((ndo, "truncated-dccp - %u bytes missing!",
			  len - fixed_hdrlen));
		return;
	}
	ND_TCHECK2(*dh, fixed_hdrlen);

	sport = EXTRACT_16BITS(&dh->dccph_sport);
	dport = EXTRACT_16BITS(&dh->dccph_dport);
	hlen = dh->dccph_doff * 4;

#ifdef INET6
	if (ip6) {
		ND_PRINT((ndo, "%s.%d > %s.%d: ",
			  ip6addr_string(ndo, &ip6->ip6_src), sport,
			  ip6addr_string(ndo, &ip6->ip6_dst), dport));
	} else
#endif /*INET6*/
	{
		ND_PRINT((ndo, "%s.%d > %s.%d: ",
			  ipaddr_string(ndo, &ip->ip_src), sport,
			  ipaddr_string(ndo, &ip->ip_dst), dport));
	}

	ND_PRINT((ndo, "DCCP"));

	if (ndo->ndo_qflag) {
		ND_PRINT((ndo, " %d", len - hlen));
		if (hlen > len) {
			ND_PRINT((ndo, " [bad hdr length %u - too long, > %u]",
				  hlen, len));
		}
		return;
	}

	/* other variables in generic header */
	if (ndo->ndo_vflag) {
		ND_PRINT((ndo, " (CCVal %d, CsCov %d, ", DCCPH_CCVAL(dh), DCCPH_CSCOV(dh)));
	}

	/* checksum calculation */
	if (ndo->ndo_vflag && ND_TTEST2(bp[0], len)) {
		uint16_t sum = 0, dccp_sum;

		dccp_sum = EXTRACT_16BITS(&dh->dccph_checksum);
		ND_PRINT((ndo, "cksum 0x%04x ", dccp_sum));
		if (IP_V(ip) == 4)
			sum = dccp_cksum(ndo, ip, dh, len);
#ifdef INET6
		else if (IP_V(ip) == 6)
			sum = dccp6_cksum(ip6, dh, len);
#endif
		if (sum != 0)
			ND_PRINT((ndo, "(incorrect -> 0x%04x)",in_cksum_shouldbe(dccp_sum, sum)));
		else
			ND_PRINT((ndo, "(correct)"));
	}

	if (ndo->ndo_vflag)
		ND_PRINT((ndo, ")"));
	ND_PRINT((ndo, " "));

	dccph_type = DCCPH_TYPE(dh);
	switch (dccph_type) {
	case DCCP_PKT_REQUEST: {
		const struct dccp_hdr_request *dhr =
			(const struct dccp_hdr_request *)(bp + fixed_hdrlen);
		fixed_hdrlen += 4;
		if (len < fixed_hdrlen) {
			ND_PRINT((ndo, "truncated-%s - %u bytes missing!",
				  tok2str(dccp_pkt_type_str, "", dccph_type),
				  len - fixed_hdrlen));
			return;
		}
		ND_TCHECK(*dhr);
		ND_PRINT((ndo, "%s (service=%d) ",
			  tok2str(dccp_pkt_type_str, "", dccph_type),
			  EXTRACT_32BITS(&dhr->dccph_req_service)));
		break;
	}
	case DCCP_PKT_RESPONSE: {
		const struct dccp_hdr_response *dhr =
			(const struct dccp_hdr_response *)(bp + fixed_hdrlen);
		fixed_hdrlen += 12;
		if (len < fixed_hdrlen) {
			ND_PRINT((ndo, "truncated-%s - %u bytes missing!",
				  tok2str(dccp_pkt_type_str, "", dccph_type),
				  len - fixed_hdrlen));
			return;
		}
		ND_TCHECK(*dhr);
		ND_PRINT((ndo, "%s (service=%d) ",
			  tok2str(dccp_pkt_type_str, "", dccph_type),
			  EXTRACT_32BITS(&dhr->dccph_resp_service)));
		break;
	}
	case DCCP_PKT_DATA:
		ND_PRINT((ndo, "%s ", tok2str(dccp_pkt_type_str, "", dccph_type)));
		break;
	case DCCP_PKT_ACK: {
		fixed_hdrlen += 8;
		if (len < fixed_hdrlen) {
			ND_PRINT((ndo, "truncated-%s - %u bytes missing!",
				  tok2str(dccp_pkt_type_str, "", dccph_type),
				  len - fixed_hdrlen));
			return;
		}
		ND_PRINT((ndo, "%s ", tok2str(dccp_pkt_type_str, "", dccph_type)));
		break;
	}
	case DCCP_PKT_DATAACK: {
		fixed_hdrlen += 8;
		if (len < fixed_hdrlen) {
			ND_PRINT((ndo, "truncated-%s - %u bytes missing!",
				  tok2str(dccp_pkt_type_str, "", dccph_type),
				  len - fixed_hdrlen));
			return;
		}
		ND_PRINT((ndo, "%s ", tok2str(dccp_pkt_type_str, "", dccph_type)));
		break;
	}
	case DCCP_PKT_CLOSEREQ:
		fixed_hdrlen += 8;
		if (len < fixed_hdrlen) {
			ND_PRINT((ndo, "truncated-%s - %u bytes missing!",
				  tok2str(dccp_pkt_type_str, "", dccph_type),
				  len - fixed_hdrlen));
			return;
		}
		ND_PRINT((ndo, "%s ", tok2str(dccp_pkt_type_str, "", dccph_type)));
		break;
	case DCCP_PKT_CLOSE:
		fixed_hdrlen += 8;
		if (len < fixed_hdrlen) {
			ND_PRINT((ndo, "truncated-%s - %u bytes missing!",
				  tok2str(dccp_pkt_type_str, "", dccph_type),
				  len - fixed_hdrlen));
			return;
		}
		ND_PRINT((ndo, "%s ", tok2str(dccp_pkt_type_str, "", dccph_type)));
		break;
	case DCCP_PKT_RESET: {
		const struct dccp_hdr_reset *dhr =
			(const struct dccp_hdr_reset *)(bp + fixed_hdrlen);
		fixed_hdrlen += 12;
		if (len < fixed_hdrlen) {
			ND_PRINT((ndo, "truncated-%s - %u bytes missing!",
				  tok2str(dccp_pkt_type_str, "", dccph_type),
				  len - fixed_hdrlen));
			return;
		}
		ND_TCHECK(*dhr);
		ND_PRINT((ndo, "%s (code=%s) ",
			  tok2str(dccp_pkt_type_str, "", dccph_type),
			  dccp_reset_code(dhr->dccph_reset_code)));
		break;
	}
	case DCCP_PKT_SYNC:
		fixed_hdrlen += 8;
		if (len < fixed_hdrlen) {
			ND_PRINT((ndo, "truncated-%s - %u bytes missing!",
				  tok2str(dccp_pkt_type_str, "", dccph_type),
				  len - fixed_hdrlen));
			return;
		}
		ND_PRINT((ndo, "%s ", tok2str(dccp_pkt_type_str, "", dccph_type)));
		break;
	case DCCP_PKT_SYNCACK:
		fixed_hdrlen += 8;
		if (len < fixed_hdrlen) {
			ND_PRINT((ndo, "truncated-%s - %u bytes missing!",
				  tok2str(dccp_pkt_type_str, "", dccph_type),
				  len - fixed_hdrlen));
			return;
		}
		ND_PRINT((ndo, "%s ", tok2str(dccp_pkt_type_str, "", dccph_type)));
		break;
	default:
		ND_PRINT((ndo, "%s ", tok2str(dccp_pkt_type_str, "unknown-type-%u", dccph_type)));
		break;
	}

	if ((DCCPH_TYPE(dh) != DCCP_PKT_DATA) &&
			(DCCPH_TYPE(dh) != DCCP_PKT_REQUEST))
		dccp_print_ack_no(ndo, bp);

	if (ndo->ndo_vflag < 2)
		return;

	ND_PRINT((ndo, "seq %" PRIu64, dccp_seqno(bp)));

	/* process options */
	if (hlen > fixed_hdrlen){
		const u_char *cp;
		u_int optlen;
		cp = bp + fixed_hdrlen;
		ND_PRINT((ndo, " <"));

		hlen -= fixed_hdrlen;
		while(1){
			optlen = dccp_print_option(ndo, cp, hlen);
			if (!optlen)
				break;
			if (hlen <= optlen)
				break;
			hlen -= optlen;
			cp += optlen;
			ND_PRINT((ndo, ", "));
		}
		ND_PRINT((ndo, ">"));
	}
	return;
trunc:
	ND_PRINT((ndo, "%s", tstr));
	return;
}
Example #26
0
void
_egp_print(netdissect_options *ndo,
          register const uint8_t *bp, register u_int length)
{
	register const struct egp_packet *egp;
	register int status;
	register int code;
	register int type;

	egp = (struct egp_packet *)bp;
        if (!ND_TTEST2(*egp, length)) {
		ND_PRINT((ndo, "[|egp]"));
		return;
	}

        if (!ndo->ndo_vflag) {
            ND_PRINT((ndo, "EGPv%u, AS %u, seq %u, length %u",
                   egp->egp_version,
                   EXTRACT_16BITS(&egp->egp_as),
                   EXTRACT_16BITS(&egp->egp_sequence),
                   length));
            return;
        } else
            ND_PRINT((ndo, "EGPv%u, length %u",
                   egp->egp_version,
                   length));

	if (egp->egp_version != EGP_VERSION) {
		ND_PRINT((ndo, "[version %d]", egp->egp_version));
		return;
	}

	type = egp->egp_type;
	code = egp->egp_code;
	status = egp->egp_status;

	switch (type) {
	case EGPT_ACQUIRE:
		ND_PRINT((ndo, " acquire"));
		switch (code) {
		case EGPC_REQUEST:
		case EGPC_CONFIRM:
			ND_PRINT((ndo, " %s", egp_acquire_codes[code]));
			switch (status) {
			case EGPS_UNSPEC:
			case EGPS_ACTIVE:
			case EGPS_PASSIVE:
				ND_PRINT((ndo, " %s", egp_acquire_status[status]));
				break;

			default:
				ND_PRINT((ndo, " [status %d]", status));
				break;
			}
			ND_PRINT((ndo, " hello:%d poll:%d",
			       EXTRACT_16BITS(&egp->egp_hello),
			       EXTRACT_16BITS(&egp->egp_poll)));
			break;

		case EGPC_REFUSE:
		case EGPC_CEASE:
		case EGPC_CEASEACK:
			ND_PRINT((ndo, " %s", egp_acquire_codes[code]));
			switch (status ) {
			case EGPS_UNSPEC:
			case EGPS_NORES:
			case EGPS_ADMIN:
			case EGPS_GODOWN:
			case EGPS_PARAM:
			case EGPS_PROTO:
				ND_PRINT((ndo, " %s", egp_acquire_status[status]));
				break;

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

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

	case EGPT_REACH:
		switch (code) {

		case EGPC_HELLO:
		case EGPC_HEARDU:
			ND_PRINT((ndo, " %s", egp_reach_codes[code]));
			if (status <= EGPS_DOWN)
				ND_PRINT((ndo, " state:%s", egp_status_updown[status]));
			else
				ND_PRINT((ndo, " [status %d]", status));
			break;

		default:
			ND_PRINT((ndo, "[reach code %d]", code));
			break;
		}
		break;

	case EGPT_POLL:
		ND_PRINT((ndo, " poll"));
		if (egp->egp_status <= EGPS_DOWN)
			ND_PRINT((ndo, " state:%s", egp_status_updown[status]));
		else
			ND_PRINT((ndo, " [status %d]", status));
		ND_PRINT((ndo, " net:%s", ipaddr_string(ndo, &egp->egp_sourcenet)));
		break;

	case EGPT_UPDATE:
		ND_PRINT((ndo, " update"));
		if (status & EGPS_UNSOL) {
			status &= ~EGPS_UNSOL;
			ND_PRINT((ndo, " unsolicited"));
		}
		if (status <= EGPS_DOWN)
			ND_PRINT((ndo, " state:%s", egp_status_updown[status]));
		else
			ND_PRINT((ndo, " [status %d]", status));
		ND_PRINT((ndo, " %s int %d ext %d",
		       ipaddr_string(ndo, &egp->egp_sourcenet),
		       egp->egp_intgw,
		       egp->egp_extgw));
		if (ndo->ndo_vflag)
			egpnrprint(ndo, egp);
		break;

	case EGPT_ERROR:
		ND_PRINT((ndo, " error"));
		if (status <= EGPS_DOWN)
			ND_PRINT((ndo, " state:%s", egp_status_updown[status]));
		else
			ND_PRINT((ndo, " [status %d]", status));

		if (EXTRACT_16BITS(&egp->egp_reason) <= EGPR_UVERSION)
			ND_PRINT((ndo, " %s", egp_reasons[EXTRACT_16BITS(&egp->egp_reason)]));
		else
			ND_PRINT((ndo, " [reason %d]", EXTRACT_16BITS(&egp->egp_reason)));
		break;

	default:
		ND_PRINT((ndo, "[type %d]", type));
		break;
	}
}
Example #27
0
};

void
igrp_print(register const u_char *bp, u_int length, const u_char *bp2 _U_)
{
	register struct igrphdr *hdr;
	register u_char *cp;
	u_int nint, nsys, next;

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

	/* Header */
	TCHECK(*hdr);
	nint = EXTRACT_16BITS(&hdr->ig_ni);
	nsys = EXTRACT_16BITS(&hdr->ig_ns);
	next = EXTRACT_16BITS(&hdr->ig_nx);

	(void)printf(" %s V%d edit=%d AS=%d (%d/%d/%d)",
	    tok2str(op2str, "op-#%d", IGRP_OP(hdr->ig_vop)),
	    IGRP_V(hdr->ig_vop),
	    hdr->ig_ed,
	    EXTRACT_16BITS(&hdr->ig_as),
	    nint,
	    nsys,
	    next);

	length -= sizeof(*hdr);
	while (length >= IGRP_RTE_SIZE) {
		if (nint > 0) {
Example #28
0
void sctp_print(const u_char *bp,        /* beginning of sctp packet */
		const u_char *bp2,       /* beginning of enclosing */
		u_int sctpPacketLength)  /* ip packet */
{
  const struct sctpHeader *sctpPktHdr;
  const struct ip *ip;
#ifdef INET6
  const struct ip6_hdr *ip6;
#endif
  const void *endPacketPtr;
  u_short sourcePort, destPort;
  int chunkCount;
  const struct sctpChunkDesc *chunkDescPtr;
  const void *nextChunk;
  const char *sep;
  int isforces = 0;


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

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

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

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

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

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

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

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

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

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

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

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

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

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

	    printf("[DATA] ");

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

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

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

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

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

	    printf("[TSN: %u] ", EXTRACT_32BITS(&dataHdrPtr->TSN));
	    printf("[SID: %u] ", EXTRACT_16BITS(&dataHdrPtr->streamId));
	    printf("[SSEQ %u] ", EXTRACT_16BITS(&dataHdrPtr->sequence));
	    printf("[PPID 0x%x] ", EXTRACT_32BITS(&dataHdrPtr->payloadtype));
	    fflush(stdout);
	    if (isforces) {
		const u_char *payloadPtr;
		u_int chunksize = sizeof(struct sctpDataPart)+
			          sizeof(struct sctpChunkDesc);
		payloadPtr = (const u_char *) (dataHdrPtr + 1);
		if (EXTRACT_16BITS(&chunkDescPtr->chunkLength) <
			sizeof(struct sctpDataPart)+
			sizeof(struct sctpChunkDesc)+1) {
		/* Less than 1 byte of chunk payload */
			printf("bogus ForCES chunk length %u]",
			    EXTRACT_16BITS(&chunkDescPtr->chunkLength));
			return;
		}

		forces_print(payloadPtr, EXTRACT_16BITS(&chunkDescPtr->chunkLength)- chunksize);
	   } else if (vflag >= 2) {	/* if verbose output is specified */
					/* at the command line */
		const u_char *payloadPtr;

		printf("[Payload");

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

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

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

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

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

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


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


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

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

	    hb=(const struct sctpHBsender*)chunkDescPtr;

	    printf("[HB REQ] ");

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

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

trunc:
    printf("[|sctp]");
    return;
}
Example #29
0
int
ldp_msg_print(register const u_char *pptr) {

    const struct ldp_common_header *ldp_com_header;
    const struct ldp_msg_header *ldp_msg_header;
    const u_char *tptr,*msg_tptr;
    u_short tlen;
    u_short pdu_len,msg_len,msg_type,msg_tlen;
    int hexdump,processed;

    tptr=pptr;
    ldp_com_header = (const struct ldp_common_header *)pptr;
    TCHECK(*ldp_com_header);

    /*
     * Sanity checking of the header.
     */
    if (EXTRACT_16BITS(&ldp_com_header->version) != LDP_VERSION) {
	printf("%sLDP version %u packet not supported",
               (vflag < 1) ? "" : "\n\t",
               EXTRACT_16BITS(&ldp_com_header->version));
	return 0;
    }

    /* print the LSR-ID, label-space & length */
    pdu_len = EXTRACT_16BITS(&ldp_com_header->pdu_length);
    printf("%sLDP, Label-Space-ID: %s:%u, pdu-length: %u",
           (vflag < 1) ? "" : "\n\t",
           ipaddr_string(&ldp_com_header->lsr_id),
           EXTRACT_16BITS(&ldp_com_header->label_space),
           pdu_len);

    /* bail out if non-verbose */ 
    if (vflag < 1)
        return 0;

    /* ok they seem to want to know everything - lets fully decode it */
    tlen=pdu_len;

    tptr += sizeof(const struct ldp_common_header);
    tlen -= sizeof(const struct ldp_common_header)-4;	/* Type & Length fields not included */

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

        ldp_msg_header = (const struct ldp_msg_header *)tptr;
        msg_len=EXTRACT_16BITS(ldp_msg_header->length);
        msg_type=LDP_MASK_MSG_TYPE(EXTRACT_16BITS(ldp_msg_header->type));

        /* FIXME vendor private / experimental check */
        printf("\n\t  %s Message (0x%04x), length: %u, Message ID: 0x%08x, Flags: [%s if unknown]",
               tok2str(ldp_msg_values,
                       "Unknown",
                       msg_type),
               msg_type,
               msg_len,
               EXTRACT_32BITS(&ldp_msg_header->id),
               LDP_MASK_U_BIT(EXTRACT_16BITS(&ldp_msg_header->type)) ? "continue processing" : "ignore");

        if (msg_len == 0) /* infinite loop protection */
            return 0;

        msg_tptr=tptr+sizeof(struct ldp_msg_header);
        msg_tlen=msg_len-sizeof(struct ldp_msg_header)+4; /* Type & Length fields not included */

        /* did we capture enough for fully decoding the message ? */
        TCHECK2(*tptr, msg_len);
        hexdump=FALSE;

        switch(msg_type) {
 
        case LDP_MSG_NOTIF:
        case LDP_MSG_HELLO:
        case LDP_MSG_INIT:
        case LDP_MSG_KEEPALIVE:
        case LDP_MSG_ADDRESS:
        case LDP_MSG_LABEL_MAPPING:
        case LDP_MSG_ADDRESS_WITHDRAW:
        case LDP_MSG_LABEL_WITHDRAW:
            while(msg_tlen >= 4) {
                processed = ldp_tlv_print(msg_tptr);
                if (processed == 0)
                    break;
                msg_tlen-=processed;
                msg_tptr+=processed;
            }
            break;

        /*
         *  FIXME those are the defined messages that lack a decoder
         *  you are welcome to contribute code ;-)
         */

        case LDP_MSG_LABEL_REQUEST:
        case LDP_MSG_LABEL_RELEASE:
        case LDP_MSG_LABEL_ABORT_REQUEST:

        default:
            if (vflag <= 1)
                print_unknown_data(msg_tptr,"\n\t  ",msg_tlen);
            break;
        }
        /* do we want to see an additionally hexdump ? */
        if (vflag > 1 || hexdump==TRUE)
            print_unknown_data(tptr+sizeof(struct ldp_msg_header),"\n\t  ",
                               msg_len);

        tptr += msg_len+4;
        tlen -= msg_len+4;
    }
    return pdu_len+4;
trunc:
    printf("\n\t\t packet exceeded snapshot");
    return 0;
}
Example #30
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]"));
}