print-icmp6.c

来自「TCPDUMP的C语言源代码,是在数据链路层的应用」· C语言 代码 · 共 1,288 行 · 第 1/3 页

C
1,288
字号
trunc:    (void)printf("[|icmp6]");    return;}voiddnsname_print(const u_char *cp, const u_char *ep){	int i;	/* DNS name decoding - no decompression */	printf(", \"");	while (cp < ep) {		i = *cp++;		if (i) {			if (i > ep - cp) {				printf("???");				break;			}			while (i-- && cp < ep) {				safeputchar(*cp);				cp++;			}			if (cp + 1 < ep && *cp)				printf(".");		} else {			if (cp == ep) {				/* FQDN */				printf(".");			} else if (cp + 1 == ep && *cp == '\0') {				/* truncated */			} else {				/* invalid */				printf("???");			}			break;		}	}	printf("\"");}static voidicmp6_nodeinfo_print(u_int icmp6len, const u_char *bp, const u_char *ep){	struct icmp6_nodeinfo *ni6;	struct icmp6_hdr *dp;	const u_char *cp;	size_t siz, i;	int needcomma;	if (ep < bp)		return;	dp = (struct icmp6_hdr *)bp;	ni6 = (struct icmp6_nodeinfo *)bp;	siz = ep - bp;	switch (ni6->ni_type) {	case ICMP6_NI_QUERY:		if (siz == sizeof(*dp) + 4) {			/* KAME who-are-you */			printf(" who-are-you request");			break;		}		printf(" node information query");		TCHECK2(*dp, sizeof(*ni6));		ni6 = (struct icmp6_nodeinfo *)dp;		printf(" (");	/*)*/		switch (EXTRACT_16BITS(&ni6->ni_qtype)) {		case NI_QTYPE_NOOP:			printf("noop");			break;		case NI_QTYPE_SUPTYPES:			printf("supported qtypes");			i = EXTRACT_16BITS(&ni6->ni_flags);			if (i)				printf(" [%s]", (i & 0x01) ? "C" : "");			break;			break;		case NI_QTYPE_FQDN:			printf("DNS name");			break;		case NI_QTYPE_NODEADDR:			printf("node addresses");			i = ni6->ni_flags;			if (!i)				break;			/* NI_NODEADDR_FLAG_TRUNCATE undefined for query */			printf(" [%s%s%s%s%s%s]",			    (i & NI_NODEADDR_FLAG_ANYCAST) ? "a" : "",			    (i & NI_NODEADDR_FLAG_GLOBAL) ? "G" : "",			    (i & NI_NODEADDR_FLAG_SITELOCAL) ? "S" : "",			    (i & NI_NODEADDR_FLAG_LINKLOCAL) ? "L" : "",			    (i & NI_NODEADDR_FLAG_COMPAT) ? "C" : "",			    (i & NI_NODEADDR_FLAG_ALL) ? "A" : "");			break;		default:			printf("unknown");			break;		}		if (ni6->ni_qtype == NI_QTYPE_NOOP ||		    ni6->ni_qtype == NI_QTYPE_SUPTYPES) {			if (siz != sizeof(*ni6))				if (vflag)					printf(", invalid len");			/*(*/			printf(")");			break;		}		/* XXX backward compat, icmp-name-lookup-03 */		if (siz == sizeof(*ni6)) {			printf(", 03 draft");			/*(*/			printf(")");			break;		}		switch (ni6->ni_code) {		case ICMP6_NI_SUBJ_IPV6:			if (!TTEST2(*dp,			    sizeof(*ni6) + sizeof(struct in6_addr)))				break;			if (siz != sizeof(*ni6) + sizeof(struct in6_addr)) {				if (vflag)					printf(", invalid subject len");				break;			}			printf(", subject=%s",			    getname6((const u_char *)(ni6 + 1)));			break;		case ICMP6_NI_SUBJ_FQDN:			printf(", subject=DNS name");			cp = (const u_char *)(ni6 + 1);			if (cp[0] == ep - cp - 1) {				/* icmp-name-lookup-03, pascal string */				if (vflag)					printf(", 03 draft");				cp++;				printf(", \"");				while (cp < ep) {					safeputchar(*cp);					cp++;				}				printf("\"");			} else				dnsname_print(cp, ep);			break;		case ICMP6_NI_SUBJ_IPV4:			if (!TTEST2(*dp, sizeof(*ni6) + sizeof(struct in_addr)))				break;			if (siz != sizeof(*ni6) + sizeof(struct in_addr)) {				if (vflag)					printf(", invalid subject len");				break;			}			printf(", subject=%s",			    getname((const u_char *)(ni6 + 1)));			break;		default:			printf(", unknown subject");			break;		}		/*(*/		printf(")");		break;	case ICMP6_NI_REPLY:		if (icmp6len > siz) {			printf("[|icmp6: node information reply]");			break;		}		needcomma = 0;		ni6 = (struct icmp6_nodeinfo *)dp;		printf(" node information reply");		printf(" (");	/*)*/		switch (ni6->ni_code) {		case ICMP6_NI_SUCCESS:			if (vflag) {				printf("success");				needcomma++;			}			break;		case ICMP6_NI_REFUSED:			printf("refused");			needcomma++;			if (siz != sizeof(*ni6))				if (vflag)					printf(", invalid length");			break;		case ICMP6_NI_UNKNOWN:			printf("unknown");			needcomma++;			if (siz != sizeof(*ni6))				if (vflag)					printf(", invalid length");			break;		}		if (ni6->ni_code != ICMP6_NI_SUCCESS) {			/*(*/			printf(")");			break;		}		switch (EXTRACT_16BITS(&ni6->ni_qtype)) {		case NI_QTYPE_NOOP:			if (needcomma)				printf(", ");			printf("noop");			if (siz != sizeof(*ni6))				if (vflag)					printf(", invalid length");			break;		case NI_QTYPE_SUPTYPES:			if (needcomma)				printf(", ");			printf("supported qtypes");			i = EXTRACT_16BITS(&ni6->ni_flags);			if (i)				printf(" [%s]", (i & 0x01) ? "C" : "");			break;		case NI_QTYPE_FQDN:			if (needcomma)				printf(", ");			printf("DNS name");			cp = (const u_char *)(ni6 + 1) + 4;			if (cp[0] == ep - cp - 1) {				/* icmp-name-lookup-03, pascal string */				if (vflag)					printf(", 03 draft");				cp++;				printf(", \"");				while (cp < ep) {					safeputchar(*cp);					cp++;				}				printf("\"");			} else				dnsname_print(cp, ep);			if ((EXTRACT_16BITS(&ni6->ni_flags) & 0x01) != 0)				printf(" [TTL=%u]", *(u_int32_t *)(ni6 + 1));			break;		case NI_QTYPE_NODEADDR:			if (needcomma)				printf(", ");			printf("node addresses");			i = sizeof(*ni6);			while (i < siz) {				if (i + sizeof(struct in6_addr) + sizeof(int32_t) > siz)					break;				printf(" %s", getname6(bp + i));				i += sizeof(struct in6_addr);				printf("(%d)", (int32_t)EXTRACT_32BITS(bp + i));				i += sizeof(int32_t);			}			i = ni6->ni_flags;			if (!i)				break;			printf(" [%s%s%s%s%s%s%s]",			    (i & NI_NODEADDR_FLAG_ANYCAST) ? "a" : "",			    (i & NI_NODEADDR_FLAG_GLOBAL) ? "G" : "",			    (i & NI_NODEADDR_FLAG_SITELOCAL) ? "S" : "",			    (i & NI_NODEADDR_FLAG_LINKLOCAL) ? "L" : "",			    (i & NI_NODEADDR_FLAG_COMPAT) ? "C" : "",			    (i & NI_NODEADDR_FLAG_ALL) ? "A" : "",			    (i & NI_NODEADDR_FLAG_TRUNCATE) ? "T" : "");			break;		default:			if (needcomma)				printf(", ");			printf("unknown");			break;		}		/*(*/		printf(")");		break;	}	return;trunc:	fputs("[|icmp6]", stdout);}static voidicmp6_rrenum_print(const u_char *bp, const u_char *ep){	struct icmp6_router_renum *rr6;	const char *cp;	struct rr_pco_match *match;	struct rr_pco_use *use;	char hbuf[NI_MAXHOST];	int n;	if (ep < bp)		return;	rr6 = (struct icmp6_router_renum *)bp;	cp = (const char *)(rr6 + 1);	TCHECK(rr6->rr_reserved);	switch (rr6->rr_code) {	case ICMP6_ROUTER_RENUMBERING_COMMAND:		printf("router renum: command");		break;	case ICMP6_ROUTER_RENUMBERING_RESULT:		printf("router renum: result");		break;	case ICMP6_ROUTER_RENUMBERING_SEQNUM_RESET:		printf("router renum: sequence number reset");		break;	default:		printf("router renum: code-#%d", rr6->rr_code);		break;	}	printf(", seq=%u", EXTRACT_32BITS(&rr6->rr_seqnum));	if (vflag) {#define F(x, y)	((rr6->rr_flags) & (x) ? (y) : "")		printf("[");	/*]*/		if (rr6->rr_flags) {			printf("%s%s%s%s%s,", F(ICMP6_RR_FLAGS_TEST, "T"),			    F(ICMP6_RR_FLAGS_REQRESULT, "R"),			    F(ICMP6_RR_FLAGS_FORCEAPPLY, "A"),			    F(ICMP6_RR_FLAGS_SPECSITE, "S"),			    F(ICMP6_RR_FLAGS_PREVDONE, "P"));		}		printf("seg=%u,", rr6->rr_segnum);		printf("maxdelay=%u", EXTRACT_16BITS(&rr6->rr_maxdelay));		if (rr6->rr_reserved)			printf("rsvd=0x%x", EXTRACT_32BITS(&rr6->rr_reserved));		/*[*/		printf("]");#undef F	}	if (rr6->rr_code == ICMP6_ROUTER_RENUMBERING_COMMAND) {		match = (struct rr_pco_match *)cp;		cp = (const char *)(match + 1);		TCHECK(match->rpm_prefix);		if (vflag > 1)			printf("\n\t");		else			printf(" ");		printf("match(");	/*)*/		switch (match->rpm_code) {		case RPM_PCO_ADD:	printf("add"); break;		case RPM_PCO_CHANGE:	printf("change"); break;		case RPM_PCO_SETGLOBAL:	printf("setglobal"); break;		default:		printf("#%u", match->rpm_code); break;		}		if (vflag) {			printf(",ord=%u", match->rpm_ordinal);			printf(",min=%u", match->rpm_minlen);			printf(",max=%u", match->rpm_maxlen);		}		if (inet_ntop(AF_INET6, &match->rpm_prefix, hbuf, sizeof(hbuf)))			printf(",%s/%u", hbuf, match->rpm_matchlen);		else			printf(",?/%u", match->rpm_matchlen);		/*(*/		printf(")");		n = match->rpm_len - 3;		if (n % 4)			goto trunc;		n /= 4;		while (n-- > 0) {			use = (struct rr_pco_use *)cp;			cp = (const char *)(use + 1);			TCHECK(use->rpu_prefix);			if (vflag > 1)				printf("\n\t");			else				printf(" ");			printf("use(");	/*)*/			if (use->rpu_flags) {#define F(x, y)	((use->rpu_flags) & (x) ? (y) : "")				printf("%s%s,",				    F(ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME, "V"),				    F(ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME, "P"));#undef F			}			if (vflag) {				printf("mask=0x%x,", use->rpu_ramask);				printf("raflags=0x%x,", use->rpu_raflags);				if (~use->rpu_vltime == 0)					printf("vltime=infty,");				else					printf("vltime=%u,",					    EXTRACT_32BITS(&use->rpu_vltime));				if (~use->rpu_pltime == 0)					printf("pltime=infty,");				else					printf("pltime=%u,",					    EXTRACT_32BITS(&use->rpu_pltime));			}			if (inet_ntop(AF_INET6, &use->rpu_prefix, hbuf,			    sizeof(hbuf)))				printf("%s/%u/%u", hbuf, use->rpu_uselen,				    use->rpu_keeplen);			else				printf("?/%u/%u", use->rpu_uselen,				    use->rpu_keeplen);			/*(*/			printf(")");		}	}	return;trunc:	fputs("[|icmp6]", stdout);}#endif /* INET6 */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?