⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mtrace.c

📁 mtrace源码
💻 C
📖 第 1 页 / 共 5 页
字号:
#define STATS_MISSING(x)	((x) == 0xFFFFFFFF)    if (!STATS_MISSING(s->tr_vifout) && !STATS_MISSING(r->tr_vifout))	    vhave |= OUTS;    if (STATS_MISSING(s->tr_pktcnt) || STATS_MISSING(r->tr_pktcnt))	    gmissing |= OUTS;    if (!(*rst & BUG_NOPRINT))	    ghave |= OUTS;    if (have_next) {	--r,  --s,  --rst;	if (!STATS_MISSING(s->tr_vifin) && !STATS_MISSING(r->tr_vifin))	    vhave |= INS;	if (STATS_MISSING(s->tr_pktcnt) || STATS_MISSING(r->tr_pktcnt))	    gmissing |= INS;	if (!(*rst & BUG_NOPRINT))	    ghave |= INS;    }    /*     * Stats can be missing for any number of reasons:     * - The hop may not be capable of collecting stats     * - Traffic may be getting dropped at the previous hop     *   and so this hop may not have any state     *     * We need a stronger heuristic to tell between these     * two cases; in case 1 we don't want to print the stats     * and in case 2 we want to print 100% loss.  We used to     * err on the side of not printing, which is less useful     * than printing 100% loss and dealing with it.     */#if 0    /*     * If both hops report as missing, then it's likely that there's just     * no traffic flowing.     *     * If just one hop is missing, then we really don't have it.     */    if (gmissing != BOTH)	ghave &= ~gmissing;#endif    whochar = have_next ? '^' : ' ';    switch (vhave) {      case BOTH:	v_lost = v_out - (ntohl(s->tr_vifin) - ntohl(r->tr_vifin));	if (v_out) v_pct = v_lost * 100 / v_out;	else v_pct = 0;	if (-20 < v_pct && v_pct < 101 && v_out > 10)	  sprintf(v_str, "%3d%%", v_pct);	else if (v_pct < -900 && v_out > 10)	  sprintf(v_str, "%3dx", (int)(-v_pct / 100. + 1.));	else if (v_pct <= -20 && v_out > 10)	  sprintf(v_str, "%1.1fx", -v_pct / 100. + 1.);	else	  memcpy(v_str, " -- ", 5);	if (tunstats)	    printf("%6d/%-5d=%s", v_lost, v_out, v_str);	else	    printf("   ");	printf("%4d pps", v_pps);	if (v_pps && badtime)	    printf("?");	break;      case INS:	v_out = ntohl(s->tr_vifin) - ntohl(r->tr_vifin);	v_pps = v_out / timediff;	whochar = 'v';	/* Fall through */      case OUTS:	if (tunstats)	    printf("      %c%-5d     ", whochar, v_out);	else	    printf("  %c", whochar);	printf("%4d pps", v_pps);	if (v_pps && badtime)	    printf("?");	break;      case NEITHER:	if (ghave != NEITHER)	    if (tunstats)		printf("                         ");	    else		printf("           ");	break;    }    whochar = have_next ? '^' : ' ';    switch (ghave) {      case BOTH:	g_lost = g_out - (ntohl(s->tr_pktcnt) - ntohl(r->tr_pktcnt));	if (g_out) g_pct = g_lost * 100 / g_out;	else g_pct = 0;	if (-20 < g_pct && g_pct < 101 && g_out > 10)	  sprintf(g_str, "%3d%%", g_pct);	else if (g_pct < -900 && g_out > 10)	  sprintf(g_str, "%3dx", (int)(-g_pct / 100. + 1.));	else if (g_pct <= -20 && g_out > 10)	  sprintf(g_str, "%1.1fx", -g_pct / 100. + 1.);	else	  memcpy(g_str, " -- ", 5);	printf("%s%6d/%-5d=%s%4d pps",	       tunstats ? "" : "   ", g_lost, g_out, g_str, g_pps);	if (g_pps && badtime)	    printf("?");	printf("\n");	break;#if 0      case INS:	g_out = ntohl(s->tr_pktcnt) - ntohl(r->tr_pktcnt);	g_pps = g_out / timediff;	whochar = 'v';	/* Fall through */#endif      case OUTS:	printf("%s     ?/%-5d     %4d pps",	       tunstats ? "" : "   ", g_out, g_pps);	if (badtime)	    printf("?");	printf("\n");	break;      case INS:      case NEITHER:	printf("\n");	break;    }    if (debug > 2) {	printf("\t\t\t\tv_in: %ld ", ntohl(s->tr_vifin));	printf("v_out: %ld ", ntohl(s->tr_vifout));	printf("pkts: %ld\n", ntohl(s->tr_pktcnt));	printf("\t\t\t\tv_in: %ld ", ntohl(r->tr_vifin));	printf("v_out: %ld ", ntohl(r->tr_vifout));	printf("pkts: %ld\n", ntohl(r->tr_pktcnt));	printf("\t\t\t\tv_in: %ld ",ntohl(s->tr_vifin)-ntohl(r->tr_vifin));	printf("v_out: %ld ", ntohl(s->tr_vifout) - ntohl(r->tr_vifout));	printf("pkts: %ld ", ntohl(s->tr_pktcnt) - ntohl(r->tr_pktcnt));	printf("time: %d\n", timediff);	printf("\t\t\t\treset: %x hoptime: %lx\n", *rst, ntohl(s->tr_qarr));    }}/* * A fixup to check if any pktcnt has been reset, and to fix the * byteorder bugs in mrouted 3.6 on little-endian machines. * * XXX Since periodic traffic sources are likely to have their *     pktcnt periodically reset, should we save old values when *     the reset occurs to keep slightly better statistics over *     the long term?  (e.g. SAP) */voidfixup_stats(base, prev, new, bugs)    struct resp_buf *base, *prev, *new;    int *bugs;{    int rno = base->len;    struct tr_resp *b = base->resps + rno;    struct tr_resp *p = prev->resps + rno;    struct tr_resp *n = new->resps + rno;    int *r = bugs + rno;    int res;    int cleanup = 0;    /* Check for byte-swappers.  Only check on the first trace,     * since long-running traces can wrap around and falsely trigger. */    while (--rno >= 0) {#ifdef TEST_ONLY	u_int32 nvifout = ntohl(n->tr_vifout);	u_int32 pvifout = ntohl(p->tr_vifout);#endif	--n; --p; --b;#ifdef TEST_ONLY	/*XXX this is still buggy, so disable it for release */	if ((*r & BUG_SWAP) ||	    ((base == prev) &&	     (nvifout - pvifout) > (byteswap(nvifout) - byteswap(pvifout)))) {	    if (1 || debug > 2) {		printf("ip %s swaps; b %08x p %08x n %08x\n",			inet_fmt(n->tr_inaddr, s1),			ntohl(b->tr_vifout), pvifout, nvifout);	    }	    /* This host sends byteswapped reports; swap 'em */	    if (!(*r & BUG_SWAP)) {		*r |= BUG_SWAP;		b->tr_qarr = byteswap(b->tr_qarr);		b->tr_vifin = byteswap(b->tr_vifin);		b->tr_vifout = byteswap(b->tr_vifout);		b->tr_pktcnt = byteswap(b->tr_pktcnt);	    }	    n->tr_qarr = byteswap(n->tr_qarr);	    n->tr_vifin = byteswap(n->tr_vifin);	    n->tr_vifout = byteswap(n->tr_vifout);	    n->tr_pktcnt = byteswap(n->tr_pktcnt);	}#endif	/*	 * A missing parenthesis in mrouted 3.5-3.8's prune.c	 * causes extremely bogus time diff's.	 * One half of the time calculation was	 * inside an htonl() and one half wasn't.  Therefore, on	 * a little-endian machine, both halves of the calculation	 * would get added together in the little end.  Thus, the	 * low-order 2 bytes are either 0000 (no overflow) or	 * 0100 (overflow from the addition).	 *	 * Odds are against these particular bit patterns	 * happening in both prev and new for actual time values.	 */	if ((*r & BUG_BOGUSTIME) || (((ntohl(n->tr_qarr) & 0xfeff) == 0x0000) &&	    ((ntohl(p->tr_qarr) & 0xfeff) == 0x0000))) {	    *r |= BUG_BOGUSTIME;	    n->tr_qarr = new->rtime;	    p->tr_qarr = prev->rtime;	    b->tr_qarr = base->rtime;	}    }    rno = base->len;    b = base->resps + rno;    p = prev->resps + rno;    n = new->resps + rno;    r = bugs + rno;    while (--rno >= 0) {	--n; --p; --b; --r;	/*	 * This hop has reset if:	 * - There were statistics in the base AND previous pass, AND	 *   - There are less packets this time than the first time and	 *     we didn't reset last time, OR	 *   - There are less packets this time than last time, OR	 *   - There are no statistics on this pass.	 *	 * The "and we didn't reset last time" is necessary in the	 * first branch of the OR because if the base is large and	 * we reset last time but the constant-resetter-avoidance	 * code kicked in so we delayed the copy of prev to base,	 * new could still be below base so we trigger the	 * constant-resetter code even though it was really only	 * a single reset.	 */	res = ((b->tr_pktcnt != 0xFFFFFFFF) && (p->tr_pktcnt != 0xFFFFFFFF) &&	       ((!(*r & BUG_RESET) && ntohl(n->tr_pktcnt) < ntohl(b->tr_pktcnt)) ||	        (ntohl(n->tr_pktcnt) < ntohl(p->tr_pktcnt)) ||		(n->tr_pktcnt == 0xFFFFFFFF)));	if (debug > 2) {    	    printf("\t\tip=%s, r=%d, res=%d\n", inet_fmt(b->tr_inaddr, s1), *r, res);	    if (res)		printf("\t\tbase=%ld, prev=%ld, new=%ld\n", ntohl(b->tr_pktcnt),			    ntohl(p->tr_pktcnt), ntohl(n->tr_pktcnt));	}	if (*r & BUG_RESET) {	    if (res || (*r & BUG_RESET2X)) {		/*		 * This router appears to be a 3.4 with that nasty ol'		 * neighbor version bug, which causes it to constantly		 * reset.  Just nuke the statistics for this node, and		 * don't even bother giving it the benefit of the		 * doubt from now on.		 */		p->tr_pktcnt = b->tr_pktcnt = n->tr_pktcnt;		*r |= BUG_RESET2X;	    } else {		/*		 * This is simply the situation that the original		 * fixup_stats was meant to deal with -- that a		 * 3.3 or 3.4 router deleted a cache entry while		 * traffic was still active.		 */		*r &= ~BUG_RESET;		cleanup = 1;	    }	} else	    if (res)		*r |= BUG_RESET;    }    if (cleanup == 0) return;    /*     * If some hop reset its counters and didn't continue to     * reset, then we pretend that the previous     * trace was the first one.     */    rno = base->len;    b = base->resps + rno;    p = prev->resps + rno;    while (--rno >= 0) (--b)->tr_pktcnt = (--p)->tr_pktcnt;    base->qtime = prev->qtime;    base->rtime = prev->rtime;}/* * Check per-source losses along path and compare with threshold. */intcheck_thresh(thresh, base, prev, new)    int thresh;    struct resp_buf *base, *prev, *new;{    int rno = base->len - 1;    struct tr_resp *b = base->resps + rno;    struct tr_resp *p = prev->resps + rno;    struct tr_resp *n = new->resps + rno;    int g_out, g_lost;    while (TRUE) {	if ((n->tr_inaddr != b->tr_inaddr) ||	    (n->tr_outaddr != b->tr_outaddr) ||	    (n->tr_rmtaddr != b->tr_rmtaddr))	  return 1;		/* Route changed */	if (rno-- < 1) break;    	g_out = ntohl(n->tr_pktcnt) - ntohl(p->tr_pktcnt);	b--; n--; p--;	g_lost = g_out - (ntohl(n->tr_pktcnt) - ntohl(p->tr_pktcnt));	if (g_out && ((g_lost * 100 + (g_out >> 1))/ g_out) > thresh) {	    return TRUE;	}    }    return FALSE;}/* * Print responses with statistics for forward path (from src to dst) */intprint_stats(base, prev, new, bugs, names)    struct resp_buf *base, *prev, *new;    int *bugs;    char **names;{    int rtt, hop;    char *ms;    u_int32 smask;    int rno = base->len - 1;    struct tr_resp *b = base->resps + rno;    struct tr_resp *p = prev->resps + rno;    struct tr_resp *n = new->resps + rno;    int *r = bugs + rno;    u_long resptime = new->rtime;    u_long qarrtime = ntohl(n->tr_qarr);    u_int ttl = MaX(1, n->tr_fttl) + 1;    int first = (base == prev);    VAL_TO_MASK(smask, b->tr_smask);    printf("  Source        Response Dest    ");    if (tunstats)	printf("Packet Statistics For     Only For Traffic\n");    else	printf("Overall     Packet Statistics For Traffic From\n");    (void)inet_fmt(base->qhdr.tr_src, s1);    printf("%-15s %-15s  ",	   ((b->tr_inaddr & smask) == (base->qhdr.tr_src & smask)) ?		s1 : "   * * *       ",	   inet_fmt(base->qhdr.tr_raddr, s2));    (void)inet_fmt(base->igmp.igmp_group.s_addr, s2);    if (tunstats)	printf("All Multicast Traffic     From %s\n", s1);    else	printf("Packet      %s To %s\n", s1, s2);    rtt = t_diff(resptime, new->qtime);    ms = scale(&rtt);    printf("     %c       __/  rtt%5d%s    ",	   (first && !verbose) ? 'v' : '|', rtt, ms);    if (tunstats)	printf("Lost/Sent = Pct  Rate       To %s\n", s2);    else	printf(" Rate       Lost/Sent = Pct  Rate\n");    if (!first || verbose) {	hop = t_diff(resptime, qarrtime);	ms = scale(&hop);	printf("     v      /     hop%5d%s    ", hop, ms);	if (tunstats)	    printf("---------------------     --------------------\n");	else	    printf("-------     ---------------------\n");    }    if ((b->tr_inaddr & smask) != (base->qhdr.tr_src & smask) &&	    b->tr_rmtaddr != 0) {	printf("%-15s %-14s is the previous hop\n", inet_fmt(b->tr_rmtaddr, s1),		inet_name(b->tr_rmtaddr));	printf("     v     ^\n");    }    if (debug > 2) {	printf("\t\t\t\tv_in: %ld ", ntohl(n->tr_vifin));	printf("v_out: %ld ", ntohl(n->tr_vifout));	printf("pkts: %ld\n", ntohl(n->tr_pktcnt));	printf("\t\t\t\tv_in: %ld ", ntohl(b->tr_vifin));	printf("v_out: %ld ", ntohl(b->tr_vifout));	printf("pkts: %ld\n", ntohl(b->tr_pktcnt));	printf("\t\t\t\tv_in: %ld ", ntohl(n->tr_vifin) - ntohl(b->tr_vifin));	printf("v_out: %ld ", ntohl(n->tr_vifout) - ntohl(b->tr_vifout));	printf("pkts: %ld\n", ntohl(n->tr_pktcnt) - ntohl(b->tr_pktcnt));	printf("\t\t\t\treset: %x hoptime: %lx\n", *r, ntohl(n->tr_qarr));    }    while (TRUE) {	if ((n->tr_inaddr != b->tr_inaddr) ||	    (n->tr_outaddr != b->tr_outaddr) ||	    (n->tr_rmtaddr != b->tr_rmtaddr))	  return 1;		/* Route changed */	if ((n->tr_inaddr != n->tr_outaddr) && n->tr_inaddr)	  printf("%-15s\n", inet_fmt(n->tr_inaddr, s1));	printf("%-15s %-14s %s%s\n", inet_fmt(n->tr_outaddr, s1), names[rno],		 flag_type(n->tr_rflags),		 (*r & BUG_NOPRINT) ? " [reset counters]" : "");	if (rno-- < 1) break;	printf("     %c     ^      ttl%5d   ", (first && !verbose) ? 'v' : '|',								ttl);	stat_line(p, n, TRUE, r);	if (!first || verbose) {	    resptime = qarrtime;	    qarrtime = ntohl((n-1)->tr_qarr);	    hop = t_diff(resptime, qarrtime);	    ms = scale(&hop);	    printf("     v     |      hop%5d%s", hop, ms);	    if (first)		printf("\n");	    else		stat_line(b, n, TRUE, r);	}	--b, --p, --n, --r;	ttl = MaX(ttl, MaX(1, n->tr_fttl) + base->len - rno);    }	       printf("     %c      \\__   ttl%5d   ", (first && !verbose) ? 'v' : '|',							ttl);    stat_line(p, n, FALSE, r);    if (!first || verbose) {	hop = t_diff(qarrtime, new->qtime);	ms = scale(&hop);	printf("     v         \\  hop%5d%s", hop, ms);	if (first)	    printf("\n");	else	    stat_line(b, n, FALSE, r);    }    printf("%-15s %s\n", inet_fmt(base->qhdr.tr_dst, s1),			!passive ? inet_fmt(lcl_addr, s2) : "   * * *       ");    printf("  Receiver      Query Source\n\n");    return 0;}/* * Determine whether or not the path has changed. */intpath_changed(base, new)    struct resp_buf *base, *new;{    int r

⌨️ 快捷键说明

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