print-ip.c

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

C
741
字号
};static voidip_print_demux(netdissect_options *ndo,	       struct ip_print_demux_state *ipds){	struct protoent *proto;again:	switch (ipds->nh) {	case IPPROTO_AH:		ipds->nh = *ipds->cp;		ipds->advance = ah_print(ipds->cp);		if (ipds->advance <= 0)			break;		ipds->cp += ipds->advance;		ipds->len -= ipds->advance;		goto again;	case IPPROTO_ESP:	{		int enh, padlen;		ipds->advance = esp_print(ndo, ipds->cp, ipds->len,				    (const u_char *)ipds->ip,				    &enh, &padlen);		if (ipds->advance <= 0)			break;		ipds->cp += ipds->advance;		ipds->len -= ipds->advance + padlen;		ipds->nh = enh & 0xff;		goto again;	}		case IPPROTO_IPCOMP:	{		int enh;		ipds->advance = ipcomp_print(ipds->cp, &enh);		if (ipds->advance <= 0)			break;		ipds->cp += ipds->advance;		ipds->len -= ipds->advance;		ipds->nh = enh & 0xff;		goto again;	}	case IPPROTO_SCTP:		sctp_print(ipds->cp, (const u_char *)ipds->ip, ipds->len);		break;	case IPPROTO_DCCP:		dccp_print(ipds->cp, (const u_char *)ipds->ip, ipds->len);		break;			case IPPROTO_TCP:		/* pass on the MF bit plus the offset to detect fragments */		tcp_print(ipds->cp, ipds->len, (const u_char *)ipds->ip,			  ipds->off & (IP_MF|IP_OFFMASK));		break;			case IPPROTO_UDP:		/* pass on the MF bit plus the offset to detect fragments */		udp_print(ipds->cp, ipds->len, (const u_char *)ipds->ip,			  ipds->off & (IP_MF|IP_OFFMASK));		break;			case IPPROTO_ICMP:		/* pass on the MF bit plus the offset to detect fragments */		icmp_print(ipds->cp, ipds->len, (const u_char *)ipds->ip,			   ipds->off & (IP_MF|IP_OFFMASK));		break;			case IPPROTO_PIGP:		/*		 * XXX - the current IANA protocol number assignments		 * page lists 9 as "any private interior gateway		 * (used by Cisco for their IGRP)" and 88 as		 * "EIGRP" from Cisco.		 *		 * Recent BSD <netinet/in.h> headers define		 * IP_PROTO_PIGP as 9 and IP_PROTO_IGRP as 88.		 * We define IP_PROTO_PIGP as 9 and		 * IP_PROTO_EIGRP as 88; those names better		 * match was the current protocol number		 * assignments say.		 */		igrp_print(ipds->cp, ipds->len, (const u_char *)ipds->ip);		break;			case IPPROTO_EIGRP:		eigrp_print(ipds->cp, ipds->len);		break;			case IPPROTO_ND:		ND_PRINT((ndo, " nd %d", ipds->len));		break;	case IPPROTO_EGP:		egp_print(ipds->cp, ipds->len);		break;	case IPPROTO_OSPF:		ospf_print(ipds->cp, ipds->len, (const u_char *)ipds->ip);		break;	case IPPROTO_IGMP:		igmp_print(ipds->cp, ipds->len);		break;	case IPPROTO_IPV4:		/* DVMRP multicast tunnel (ip-in-ip encapsulation) */		ip_print(gndo, ipds->cp, ipds->len);		if (! vflag) {			ND_PRINT((ndo, " (ipip-proto-4)"));			return;		}		break;		#ifdef INET6	case IPPROTO_IPV6:		/* ip6-in-ip encapsulation */		ip6_print(ipds->cp, ipds->len);		break;#endif /*INET6*/	case IPPROTO_RSVP:		rsvp_print(ipds->cp, ipds->len);		break;	case IPPROTO_GRE:		/* do it */		gre_print(ipds->cp, ipds->len);		break;	case IPPROTO_MOBILE:		mobile_print(ipds->cp, ipds->len);		break;	case IPPROTO_PIM:		pim_print(ipds->cp,  ipds->len);		break;	case IPPROTO_VRRP:		vrrp_print(ipds->cp, ipds->len, ipds->ip->ip_ttl);		break;	case IPPROTO_PGM:		pgm_print(ipds->cp, ipds->len, (const u_char *)ipds->ip);		break;	default:		if ((proto = getprotobynumber(ipds->nh)) != NULL)			ND_PRINT((ndo, " %s", proto->p_name));		else			ND_PRINT((ndo, " ip-proto-%d", ipds->nh));		ND_PRINT((ndo, " %d", ipds->len));		break;	}}	       voidip_print_inner(netdissect_options *ndo,	       const u_char *bp,	       u_int length, u_int nh,	       const u_char *bp2){	struct ip_print_demux_state  ipd;	ipd.ip = (const struct ip *)bp2;	ipd.cp = bp;	ipd.len  = length;	ipd.off  = 0;	ipd.nh   = nh;	ipd.advance = 0;	ip_print_demux(ndo, &ipd);}/* * print an IP datagram. */voidip_print(netdissect_options *ndo,	 const u_char *bp,	 u_int length){	struct ip_print_demux_state  ipd;	struct ip_print_demux_state *ipds=&ipd;	const u_char *ipend;	u_int hlen;	u_int16_t sum, ip_sum;	struct protoent *proto;	ipds->ip = (const struct ip *)bp;	if (IP_V(ipds->ip) != 4) { /* print version if != 4 */	    printf("IP%u ", IP_V(ipds->ip));	    if (IP_V(ipds->ip) == 6)		printf(", wrong link-layer encapsulation");	}        else if (!eflag)	    printf("IP ");	if ((u_char *)(ipds->ip + 1) > snapend) {		printf("[|ip]");		return;	}	if (length < sizeof (struct ip)) {		(void)printf("truncated-ip %u", length);		return;	}	hlen = IP_HL(ipds->ip) * 4;	if (hlen < sizeof (struct ip)) {		(void)printf("bad-hlen %u", hlen);		return;	}	ipds->len = EXTRACT_16BITS(&ipds->ip->ip_len);	if (length < ipds->len)		(void)printf("truncated-ip - %u bytes missing! ",			ipds->len - length);	if (ipds->len < hlen) {#ifdef GUESS_TSO            if (ipds->len) {                (void)printf("bad-len %u", ipds->len);                return;            }            else {                /* we guess that it is a TSO send */                ipds->len = length;            }#else            (void)printf("bad-len %u", ipds->len);            return;#endif /* GUESS_TSO */	}	/*	 * Cut off the snapshot length to the end of the IP payload.	 */	ipend = bp + ipds->len;	if (ipend < snapend)		snapend = ipend;	ipds->len -= hlen;	ipds->off = EXTRACT_16BITS(&ipds->ip->ip_off);        if (vflag) {            (void)printf("(tos 0x%x", (int)ipds->ip->ip_tos);            /* ECN bits */            if (ipds->ip->ip_tos & 0x03) {                switch (ipds->ip->ip_tos & 0x03) {                case 1:                    (void)printf(",ECT(1)");                    break;                case 2:                    (void)printf(",ECT(0)");                    break;                case 3:                    (void)printf(",CE");                }            }            if (ipds->ip->ip_ttl >= 1)                (void)printf(", ttl %u", ipds->ip->ip_ttl);    	    /*	     * for the firewall guys, print id, offset.             * On all but the last stick a "+" in the flags portion.	     * For unfragmented datagrams, note the don't fragment flag.	     */	    (void)printf(", id %u, offset %u, flags [%s], proto %s (%u)",                         EXTRACT_16BITS(&ipds->ip->ip_id),                         (ipds->off & 0x1fff) * 8,                         bittok2str(ip_frag_values, "none", ipds->off&0xe000),                         tok2str(ipproto_values,"unknown",ipds->ip->ip_p),                         ipds->ip->ip_p);            (void)printf(", length %u", EXTRACT_16BITS(&ipds->ip->ip_len));            if ((hlen - sizeof(struct ip)) > 0) {                printf(", options (");                ip_optprint((u_char *)(ipds->ip + 1), hlen - sizeof(struct ip));                printf(")");            }	    if ((u_char *)ipds->ip + hlen <= snapend) {	        sum = in_cksum((const u_short *)ipds->ip, hlen, 0);		if (sum != 0) {		    ip_sum = EXTRACT_16BITS(&ipds->ip->ip_sum);		    (void)printf(", bad cksum %x (->%x)!", ip_sum,			     in_cksum_shouldbe(ip_sum, sum));		}	    }            printf(")\n    ");	}	/*	 * If this is fragment zero, hand it to the next higher	 * level protocol.	 */	if ((ipds->off & 0x1fff) == 0) {		ipds->cp = (const u_char *)ipds->ip + hlen;		ipds->nh = ipds->ip->ip_p;		if (ipds->nh != IPPROTO_TCP && ipds->nh != IPPROTO_UDP &&		    ipds->nh != IPPROTO_SCTP && ipds->nh != IPPROTO_DCCP) {			(void)printf("%s > %s: ",				     ipaddr_string(&ipds->ip->ip_src),				     ipaddr_string(&ipds->ip->ip_dst));		}		ip_print_demux(ndo, ipds);	} else {	    /* Ultra quiet now means that all this stuff should be suppressed */	    if (qflag > 1) return;	    /*	     * if this isn't the first frag, we're missing the	     * next level protocol header.  print the ip addr	     * and the protocol.	     */	    if (ipds->off & 0x1fff) {	        (void)printf("%s > %s:", ipaddr_string(&ipds->ip->ip_src),			     ipaddr_string(&ipds->ip->ip_dst));		if ((proto = getprotobynumber(ipds->ip->ip_p)) != NULL)		    (void)printf(" %s", proto->p_name);		else		    (void)printf(" ip-proto-%d", ipds->ip->ip_p);	    } 	}}voidipN_print(register const u_char *bp, register u_int length){	struct ip *ip, hdr;	ip = (struct ip *)bp;	if (length < 4) {		(void)printf("truncated-ip %d", length);		return;	}	memcpy (&hdr, (char *)ip, 4);	switch (IP_V(&hdr)) {	case 4:		ip_print (gndo, bp, length);		return;#ifdef INET6	case 6:		ip6_print (bp, length);		return;#endif	default:		(void)printf("unknown ip %d", IP_V(&hdr));		return;	}}/* * Local Variables: * c-style: whitesmith * c-basic-offset: 8 * End: */

⌨️ 快捷键说明

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