示例#1
0
/**
 * dccp_print - show dccp packet
 * @bp - beginning of dccp packet
 * @data2 - beginning of enclosing
 * @len - length 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;
	const struct ip6_hdr *ip6;
	const u_char *cp;
	u_short sport, dport;
	u_int hlen;
	u_int fixed_hdrlen;
	uint8_t	dccph_type;

	ndo->ndo_protocol = "dccp";
	dh = (const struct dccp_hdr *)bp;

	ip = (const struct ip *)data2;
	if (IP_V(ip) == 6)
		ip6 = (const struct ip6_hdr *)data2;
	else
		ip6 = NULL;

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

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

	sport = GET_BE_U_2(dh->dccph_sport);
	dport = GET_BE_U_2(dh->dccph_dport);
	hlen = GET_U_1(dh->dccph_doff) * 4;

	if (ip6) {
		ND_PRINT("%s.%u > %s.%u: ",
			  ip6addr_string(ndo, ip6->ip6_src), sport,
			  ip6addr_string(ndo, ip6->ip6_dst), dport);
	} else {
		ND_PRINT("%s.%u > %s.%u: ",
			  ipaddr_string(ndo, ip->ip_src), sport,
			  ipaddr_string(ndo, ip->ip_dst), dport);
	}

	ND_PRINT("DCCP");

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

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

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

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

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

	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("truncated-%s - %u bytes missing!",
				  tok2str(dccp_pkt_type_str, "", dccph_type),
				  fixed_hdrlen - len);
			return;
		}
		ND_TCHECK_SIZE(dhr);
		ND_PRINT("%s (service=%u) ",
			  tok2str(dccp_pkt_type_str, "", dccph_type),
			  GET_BE_U_4(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("truncated-%s - %u bytes missing!",
				  tok2str(dccp_pkt_type_str, "", dccph_type),
				  fixed_hdrlen - len);
			return;
		}
		ND_TCHECK_SIZE(dhr);
		ND_PRINT("%s (service=%u) ",
			  tok2str(dccp_pkt_type_str, "", dccph_type),
			  GET_BE_U_4(dhr->dccph_resp_service));
		break;
	}
	case DCCP_PKT_DATA:
		ND_PRINT("%s ", tok2str(dccp_pkt_type_str, "", dccph_type));
		break;
	case DCCP_PKT_ACK: {
		fixed_hdrlen += 8;
		if (len < fixed_hdrlen) {
			ND_PRINT("truncated-%s - %u bytes missing!",
				  tok2str(dccp_pkt_type_str, "", dccph_type),
				  fixed_hdrlen - len);
			return;
		}
		ND_PRINT("%s ", tok2str(dccp_pkt_type_str, "", dccph_type));
		break;
	}
	case DCCP_PKT_DATAACK: {
		fixed_hdrlen += 8;
		if (len < fixed_hdrlen) {
			ND_PRINT("truncated-%s - %u bytes missing!",
				  tok2str(dccp_pkt_type_str, "", dccph_type),
				  fixed_hdrlen - len);
			return;
		}
		ND_PRINT("%s ", tok2str(dccp_pkt_type_str, "", dccph_type));
		break;
	}
	case DCCP_PKT_CLOSEREQ:
		fixed_hdrlen += 8;
		if (len < fixed_hdrlen) {
			ND_PRINT("truncated-%s - %u bytes missing!",
				  tok2str(dccp_pkt_type_str, "", dccph_type),
				  fixed_hdrlen - len);
			return;
		}
		ND_PRINT("%s ", tok2str(dccp_pkt_type_str, "", dccph_type));
		break;
	case DCCP_PKT_CLOSE:
		fixed_hdrlen += 8;
		if (len < fixed_hdrlen) {
			ND_PRINT("truncated-%s - %u bytes missing!",
				  tok2str(dccp_pkt_type_str, "", dccph_type),
				  fixed_hdrlen - len);
			return;
		}
		ND_PRINT("%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("truncated-%s - %u bytes missing!",
				  tok2str(dccp_pkt_type_str, "", dccph_type),
				  fixed_hdrlen - len);
			return;
		}
		ND_TCHECK_SIZE(dhr);
		ND_PRINT("%s (code=%s) ",
			  tok2str(dccp_pkt_type_str, "", dccph_type),
			  dccp_reset_code(GET_U_1(dhr->dccph_reset_code)));
		break;
	}
	case DCCP_PKT_SYNC:
		fixed_hdrlen += 8;
		if (len < fixed_hdrlen) {
			ND_PRINT("truncated-%s - %u bytes missing!",
				  tok2str(dccp_pkt_type_str, "", dccph_type),
				  fixed_hdrlen - len);
			return;
		}
		ND_PRINT("%s ", tok2str(dccp_pkt_type_str, "", dccph_type));
		break;
	case DCCP_PKT_SYNCACK:
		fixed_hdrlen += 8;
		if (len < fixed_hdrlen) {
			ND_PRINT("truncated-%s - %u bytes missing!",
				  tok2str(dccp_pkt_type_str, "", dccph_type),
				  fixed_hdrlen - len);
			return;
		}
		ND_PRINT("%s ", tok2str(dccp_pkt_type_str, "", dccph_type));
		break;
	default:
		ND_PRINT("%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("seq %" PRIu64, dccp_seqno(ndo, bp));

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

		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(", ");
		}
		ND_PRINT(">");
	}
	return;
trunc:
	nd_print_trunc(ndo);
	return;
}
示例#2
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;

	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 > 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));
	}

	if (ndo->ndo_qflag) {
		ND_PRINT((ndo, " %d", len - hlen));
		if (hlen > len) {
			ND_PRINT((ndo, "dccp [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)) {
		u_int16_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), "));
	}

	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) {
			ND_PRINT((ndo, "truncated-dccp request - %u bytes missing!",
				     len - fixed_hdrlen));
			return;
		}
		ND_TCHECK(*dhr);
		ND_PRINT((ndo, "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) {
			ND_PRINT((ndo, "truncated-dccp response - %u bytes missing!",
				     len - fixed_hdrlen));
			return;
		}
		ND_TCHECK(*dhr);
		ND_PRINT((ndo, "response (service=%d) ",
			     EXTRACT_32BITS(&dhr->dccph_resp_service)));
		break;
	}
	case DCCP_PKT_DATA:
		ND_PRINT((ndo, "data "));
		break;
	case DCCP_PKT_ACK: {
		fixed_hdrlen += 8;
		if (len < fixed_hdrlen) {
			ND_PRINT((ndo, "truncated-dccp ack - %u bytes missing!",
				     len - fixed_hdrlen));
			return;
		}
		ND_PRINT((ndo, "ack "));
		break;
	}
	case DCCP_PKT_DATAACK: {
		fixed_hdrlen += 8;
		if (len < fixed_hdrlen) {
			ND_PRINT((ndo, "truncated-dccp dataack - %u bytes missing!",
				     len - fixed_hdrlen));
			return;
		}
		ND_PRINT((ndo, "dataack "));
		break;
	}
	case DCCP_PKT_CLOSEREQ:
		fixed_hdrlen += 8;
		if (len < fixed_hdrlen) {
			ND_PRINT((ndo, "truncated-dccp closereq - %u bytes missing!",
				     len - fixed_hdrlen));
			return;
		}
		ND_PRINT((ndo, "closereq "));
		break;
	case DCCP_PKT_CLOSE:
		fixed_hdrlen += 8;
		if (len < fixed_hdrlen) {
			ND_PRINT((ndo, "truncated-dccp close - %u bytes missing!",
				     len - fixed_hdrlen));
			return;
		}
		ND_PRINT((ndo, "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) {
			ND_PRINT((ndo, "truncated-dccp reset - %u bytes missing!",
				     len - fixed_hdrlen));
			return;
		}
		ND_TCHECK(*dhr);
		ND_PRINT((ndo, "reset (code=%s) ",
			     dccp_reset_code(dhr->dccph_reset_code)));
		break;
	}
	case DCCP_PKT_SYNC:
		fixed_hdrlen += 8;
		if (len < fixed_hdrlen) {
			ND_PRINT((ndo, "truncated-dccp sync - %u bytes missing!",
				     len - fixed_hdrlen));
			return;
		}
		ND_PRINT((ndo, "sync "));
		break;
	case DCCP_PKT_SYNCACK:
		fixed_hdrlen += 8;
		if (len < fixed_hdrlen) {
			ND_PRINT((ndo, "truncated-dccp syncack - %u bytes missing!",
				     len - fixed_hdrlen));
			return;
		}
		ND_PRINT((ndo, "syncack "));
		break;
	default:
		ND_PRINT((ndo, "invalid "));
		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;
}
示例#3
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 extlen = 0;

	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*/
	cp = (const u_char *)(dh + 1);
	if (cp > snapend) {
		printf("[Invalid packet|dccp]");
		return;
	}

	if (len < sizeof(struct dccp_hdr)) {
		printf("truncated-dccp - %ld bytes missing!",
			     (long)len - sizeof(struct dccp_hdr));
		return;
	}

	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 + dccp_basic_hdr_len(dh));
		TCHECK(*dhr);
		(void)printf("request (service=%d) ",
			     EXTRACT_32BITS(&dhr->dccph_req_service));
		extlen += 4;
		break;
	}
	case DCCP_PKT_RESPONSE: {
		struct dccp_hdr_response *dhr =
			(struct dccp_hdr_response *)(bp + dccp_basic_hdr_len(dh));
		TCHECK(*dhr);
		(void)printf("response (service=%d) ",
			     EXTRACT_32BITS(&dhr->dccph_resp_service));
		extlen += 12;
		break;
	}
	case DCCP_PKT_DATA:
		(void)printf("data ");
		break;
	case DCCP_PKT_ACK: {
		(void)printf("ack ");
		extlen += 8;
		break;
	}
	case DCCP_PKT_DATAACK: {
		(void)printf("dataack ");
		extlen += 8;
		break;
	}
	case DCCP_PKT_CLOSEREQ:
		(void)printf("closereq ");
		extlen += 8;
		break;
	case DCCP_PKT_CLOSE:
		(void)printf("close ");
		extlen += 8;
		break;
	case DCCP_PKT_RESET: {
		struct dccp_hdr_reset *dhr =
			(struct dccp_hdr_reset *)(bp + dccp_basic_hdr_len(dh));
		TCHECK(*dhr);
		(void)printf("reset (code=%s) ",
			     dccp_reset_code(dhr->dccph_reset_code));
		extlen += 12;
		break;
	}
	case DCCP_PKT_SYNC:
		(void)printf("sync ");
		extlen += 8;
		break;
	case DCCP_PKT_SYNCACK:
		(void)printf("syncack ");
		extlen += 8;
		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(dh));

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

		hlen -= dccp_basic_hdr_len(dh) + extlen;
		while(1){
			TCHECK(*cp);
			optlen = dccp_print_option(cp);
			if (!optlen) goto trunc2;
			if (hlen <= optlen) break;
			hlen -= optlen;
			cp += optlen;
			printf(", ");
		}
		printf(">");
	}
	return;
trunc:
	printf("%s", tstr);
trunc2:
	return;
}