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

📄 mtrace.c

📁 mtrace源码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * mtrace.c * * This tool traces the branch of a multicast tree from a source to a * receiver for a particular multicast group and gives statistics * about packet rate and loss for each hop along the path.  It can * usually be invoked just as * * 	mtrace source * * to trace the route from that source to the local host for a default * group when only the route is desired and not group-specific packet * counts.  See the usage line for more complex forms. * * * Released 4 Apr 1995.  This program was adapted by Steve Casner * (USC/ISI) from a prototype written by Ajit Thyagarajan (UDel and * Xerox PARC).  It attempts to parallel in command syntax and output * format the unicast traceroute program written by Van Jacobson (LBL) * for the parts where that makes sense. *  * Copyright (c) 1995 by the University of Southern California * All rights reserved. * * Permission to use, copy, modify, and distribute this software and its * documentation in source and binary forms for any purposes and without * fee is hereby granted, provided that the above copyright notice * appear in all copies and that both the copyright notice and this * permission notice appear in supporting documentation, and that any * documentation, advertising materials, and other materials related to * such distribution and use acknowledge that the software was developed * by the University of Southern California, Information Sciences * Institute.  The name of the University may not be used to endorse or * promote products derived from this software without specific prior * written permission. * * THE UNIVERSITY OF SOUTHERN CALIFORNIA makes no representations about * the suitability of this software for any purpose.  THIS SOFTWARE IS * PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * * Other copyrights might apply to parts of this software and are so * noted when applicable. * * Parts of this software are derived from mrouted, which has the * following license: *  * The mrouted program is covered by the following license.  Use of the * mrouted program represents acceptance of these terms and conditions. *  * 1. STANFORD grants to LICENSEE a nonexclusive and nontransferable * license to use, copy and modify the computer software ``mrouted'' * (hereinafter called the ``Program''), upon the terms and conditions * hereinafter set out and until Licensee discontinues use of the Licensed * Program. *  * 2. LICENSEE acknowledges that the Program is a research tool still in * the development state, that it is being supplied ``as is,'' without any * accompanying services from STANFORD, and that this license is entered * into in order to encourage scientific collaboration aimed at further * development and application of the Program. *  * 3. LICENSEE may copy the Program and may sublicense others to use * object code copies of the Program or any derivative version of the * Program.  All copies must contain all copyright and other proprietary * notices found in the Program as provided by STANFORD.  Title to * copyright to the Program remains with STANFORD. *  * 4. LICENSEE may create derivative versions of the Program.  LICENSEE * hereby grants STANFORD a royalty-free license to use, copy, modify, * distribute and sublicense any such derivative works.  At the time * LICENSEE provides a copy of a derivative version of the Program to a * third party, LICENSEE shall provide STANFORD with one copy of the * source code of the derivative version at no charge to STANFORD. *  * 5. STANFORD MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR * IMPLIED.  By way of example, but not limitation, STANFORD MAKES NO * REPRESENTATION OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY * PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED PROGRAM WILL NOT * INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. STANFORD * shall not be held liable for any liability nor for any direct, indirect * or consequential damages with respect to any claim by LICENSEE or any * third party on account of or arising from this Agreement or use of the * Program. *  * 6. This agreement shall be construed, interpreted and applied in * accordance with the State of California and any legal action arising * out of this Agreement or use of the Program shall be filed in a court * in the State of California. *  * 7. Nothing in this Agreement shall be construed as conferring rights to * use in advertising, publicity or otherwise any trademark or the name * of ``Stanford''. *  * The mrouted program is COPYRIGHT 1989 by The Board of Trustees of * Leland Stanford Junior University. * * * The mtrace program has been modified and improved by Xerox * Corporation.  Xerox grants to LICENSEE a non-exclusive and * non-transferable license to use, copy, and modify the Xerox modified * and improved mrouted software on the same terms and conditions which * govern the license Stanford and ISI grant with respect to the mtrace * program.  These terms and conditions are incorporated in this grant * by reference and shall be deemed to have been accepted by LICENSEE * to cover its relationship with Xerox Corporation with respect to any * use of the Xerox improved program. *  * The mtrace program is COPYRIGHT 1998 by Xerox Corporation. * */#ifndef lintstatic char rcsid[] =    "@(#) mtrace.c,v 5.2 1998/12/04 04:48:19 fenner Exp";#endif#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <memory.h>#include <string.h>#include <ctype.h>#include <errno.h>#include <syslog.h>#include <netdb.h>#include <sys/param.h>#include <sys/types.h>#include <sys/socket.h>#include <sys/time.h>#include <net/if.h>#include <netinet/in.h>#include <netinet/in_systm.h>#include <netinet/ip.h>#include <netinet/igmp.h>#include <sys/ioctl.h>#ifdef SYSV#include <sys/sockio.h>#endif#include <arpa/inet.h>#ifdef __STDC__#include <stdarg.h>#else#include <varargs.h>#endif#ifdef SUNOS5#include <sys/systeminfo.h>#endiftypedef unsigned int u_int32;	/* XXX */#include "mtrace.h"#define DEFAULT_TIMEOUT	3	/* How long to wait before retrying requests */#define DEFAULT_RETRIES 3	/* How many times to try */#define DEFAULT_EXTRAHOPS 3	/* How many hops past a non-responding rtr */#define MAXHOPS 60		/* Don't need more hops than this */#define UNICAST_TTL 255		/* TTL for unicast response */#define MULTICAST_TTL1 127	/* Default TTL for multicast query/response */#define MULTICAST_TTL_INC 32	/* TTL increment for increase after timeout */#define MULTICAST_TTL_MAX 192	/* Maximum TTL allowed (protect low-BW links */#define TRUE 1#define FALSE 0#define DVMRP_ASK_NEIGHBORS2	5	/* DVMRP msg requesting neighbors */#define DVMRP_NEIGHBORS2	6	/* reply to above */#define DVMRP_NF_DOWN		0x10	/* kernel state of interface */#define DVMRP_NF_DISABLED	0x20	/* administratively disabled */#define MAX_IP_PACKET_LEN	576#define MIN_IP_HEADER_LEN	20#define MAX_IP_HEADER_LEN	60#define MAX_DVMRP_DATA_LEN \		( MAX_IP_PACKET_LEN - MAX_IP_HEADER_LEN - IGMP_MINLEN )struct resp_buf {    u_long qtime;		/* Time query was issued */    u_long rtime;		/* Time response was received */    int	len;			/* Number of reports or length of data */    struct igmp igmp;		/* IGMP header */    union {	struct {	    struct tr_query q;		/* Query/response header */	    struct tr_resp r[MAXHOPS];	/* Per-hop reports */	} t;	char d[MAX_DVMRP_DATA_LEN];	/* Neighbor data */    } u;} base, incr[2];#define qhdr u.t.q#define resps u.t.r#define ndata u.dchar *names[MAXHOPS];/* * In mrouted 3.3 and 3.4 (and in some Cisco IOS releases), * cache entries can get deleted even if there is traffic * flowing, which will reset the per-source/group counters. */#define		BUG_RESET	0x01/* * Also in mrouted 3.3 and 3.4, there's a bug in neighbor * version processing which can cause them to believe that * the neighbor is constantly resetting.  This causes them * to constantly delete all their state. */#define		BUG_RESET2X	0x02/* * Pre-3.7 mrouted's forget to byte-swap their reports. */#define		BUG_SWAP	0x04/* * Pre-3.9 mrouted's forgot a parenthesis in the htonl() * on the time calculation so supply bogus times. */#define		BUG_BOGUSTIME	0x08#define BUG_NOPRINT	(BUG_RESET | BUG_RESET2X)int bugs[MAXHOPS];			/* List of bugs noticed at each hop */struct mtrace {	struct mtrace	*next;	struct resp_buf	 base, incr[2];	struct resp_buf	*new, *prev;	int		 nresp;	struct timeval	 last;	int		 bugs[MAXHOPS];	char		*names[MAXHOPS];	int		 lastqid;};int timeout = DEFAULT_TIMEOUT;int nqueries = DEFAULT_RETRIES;int numeric = FALSE;int debug = 0;int passive = FALSE;int multicast = FALSE;int unicast = FALSE;int statint = 10;int verbose = FALSE;int tunstats = FALSE;int weak = FALSE;int extrahops = DEFAULT_EXTRAHOPS;int printstats = TRUE;int sendopts = TRUE;int lossthresh = 0;int fflag = FALSE;int staticqid = 0;u_int32 defgrp;				/* Default group if not specified */u_int32 query_cast;			/* All routers multicast addr */u_int32 resp_cast;			/* Mtrace response multicast addr */u_int32 lcl_addr = 0;			/* This host address, in NET order */u_int32 dst_netmask = 0;		/* netmask to go with qdst *//* * Query/response parameters, all initialized to zero and set later * to default values or from options. */u_int32 qsrc = 0;		/* Source address in the query */u_int32 qgrp = 0;		/* Group address in the query */u_int32 qdst = 0;		/* Destination (receiver) address in query */u_char qno  = 0;		/* Max number of hops to query */u_int32 raddr = 0;		/* Address where response should be sent */int    qttl = 0;		/* TTL for the query packet */u_char rttl = 0;		/* TTL for the response packet */u_int32 gwy = 0;		/* User-supplied last-hop router address */u_int32 tdst = 0;		/* Address where trace is sent (last-hop) */char s1[19];		/* buffers to hold the string representations  */char s2[19];		/* of IP addresses, to be passed to inet_fmt() */char s3[19];		/* or inet_fmts().                             */#if !(defined(BSD) && (BSD >= 199103))extern int		errno;extern int		sys_nerr;extern char *		sys_errlist[];#endif#define RECV_BUF_SIZE 8192char	*send_buf, *recv_buf;int	igmp_socket;u_int32	allrtrs_group;char	router_alert[4];	     	/* Router Alert IP Option	    */#ifndef	IPOPT_RA#define	IPOPT_RA		148#endif#ifdef SUNOS5char	eol[4];		     		/* EOL IP Option		    */int ip_addlen = 0;		     	/* Workaround for Option bug #2     */#endif/* * max macro, with weird case to avoid conflicts */#define	MaX(a,b)	((a) > (b) ? (a) : (b))#ifndef __P#ifdef __STDC__#define __P(x)	x#else#define __P(x)	()#endif#endiftypedef int (*callback_t) __P((int, u_char *, int, struct igmp *, int,			struct sockaddr *, int *, struct timeval *));void			init_igmp __P((void));void			send_igmp __P((u_int32 src, u_int32 dst, int type,						int code, u_int32 group,						int datalen));int			inet_cksum __P((u_short *addr, u_int len));void			k_set_rcvbuf __P((int bufsize));void			k_hdr_include __P((int bool));void			k_set_ttl __P((int t));void			k_set_loop __P((int l));void			k_set_if __P((u_int32 ifa));void			k_join __P((u_int32 grp, u_int32 ifa));void			k_leave __P((u_int32 grp, u_int32 ifa));char *			inet_fmt __P((u_int32 addr, char *s));char *			inet_fmts __P((u_int32 addr, u_int32 mask, char *s));char *			inet_name __P((u_int32 addr));u_int32			host_addr __P((char *name));/* u_int is promoted u_char */char *			proto_type __P((u_int type));char *			flag_type __P((u_int type));u_int32			get_netmask __P((int s, u_int32 *dst));int			get_ttl __P((struct resp_buf *buf));int			t_diff __P((u_long a, u_long b));u_long			byteswap __P((u_long v));int			mtrace_callback __P((int, u_char *, int, struct igmp *,					int, struct sockaddr *, int *,					struct timeval *));int			send_recv __P((u_int32 dst, int type, int code,					int tries, struct resp_buf *save,					callback_t callback));void			passive_mode __P((void));char *			print_host __P((u_int32 addr));char *			print_host2 __P((u_int32 addr1, u_int32 addr2));void			print_trace __P((int idx, struct resp_buf *buf,					char **names));int			what_kind __P((struct resp_buf *buf, char *why));char *			scale __P((int *hop));void			stat_line __P((struct tr_resp *r, struct tr_resp *s,					int have_next, int *res));void			fixup_stats __P((struct resp_buf *base,					struct resp_buf *prev,					struct resp_buf *new,					int *bugs));int			check_thresh __P((int thresh,					struct resp_buf *base,					struct resp_buf *prev,					struct resp_buf *new));int			print_stats __P((struct resp_buf *base,					struct resp_buf *prev,					struct resp_buf *new,					int *bugs,					char **names));int			path_changed __P((struct resp_buf *base,					struct resp_buf *new));void			check_vif_state __P((void));int			main __P((int argc, char *argv[]));void			log __P((int, int, char *, ...));/* * Open and initialize the igmp socket, and fill in the non-changing * IP header fields in the output packet buffer. */voidinit_igmp(){    struct ip *ip;    recv_buf = (char *)malloc(RECV_BUF_SIZE);    if (recv_buf == 0)	log(LOG_ERR, 0, "Out of memory allocating recv_buf!");    send_buf = (char *)malloc(RECV_BUF_SIZE);    if (send_buf == 0)	log(LOG_ERR, 0, "Out of memory allocating send_buf!");    if ((igmp_socket = socket(AF_INET, SOCK_RAW, IPPROTO_IGMP)) < 0) 	log(LOG_ERR, errno, "IGMP socket");    k_hdr_include(TRUE);	/* include IP header when sending */    k_set_rcvbuf(48*1024);	/* lots of input buffering        */    k_set_ttl(1);		/* restrict multicasts to one hop */    k_set_loop(FALSE);		/* disable multicast loopback     */    ip         = (struct ip *)send_buf;    ip->ip_hl  = sizeof(struct ip) >> 2;    ip->ip_v   = IPVERSION;    ip->ip_tos = 0;    ip->ip_off = 0;    ip->ip_p   = IPPROTO_IGMP;    ip->ip_ttl = MAXTTL;	/* applies to unicasts only */#ifndef INADDR_ALLRTRS_GROUP#define	INADDR_ALLRTRS_GROUP	0xe0000002	/* 224.0.0.2 */#endif    allrtrs_group  = htonl(INADDR_ALLRTRS_GROUP);    router_alert[0] = IPOPT_RA;	/* Router Alert */    router_alert[1] = 4;	/* 4 bytes */    router_alert[2] = 0;    router_alert[3] = 0;}#ifdef SUNOS5voidcheckforsolarisbug(){    u_int32 localhost = htonl(0x7f000001);    eol[0] = IPOPT_EOL;    eol[1] = IPOPT_EOL;    eol[2] = IPOPT_EOL;    eol[3] = IPOPT_EOL;    setsockopt(igmp_socket, IPPROTO_IP, IP_OPTIONS, eol, sizeof(eol));    /*     * Check if the kernel adds the options length to the packet     * length.  Send myself an IGMP packet of type 0 (illegal),     * with 4 IPOPT_EOL options, my PID (for collision detection)     * and 4 bytes of zero (so that the checksum works whether     * the 4 bytes of zero get truncated or not).     */    bzero(send_buf + MIN_IP_HEADER_LEN + IGMP_MINLEN, 8);    *(int *)(send_buf + MIN_IP_HEADER_LEN + IGMP_MINLEN) = getpid();    send_igmp(localhost, localhost, 0, 0, 0, 8);    while (1) {	int recvlen, dummy = 0;	recvlen = recvfrom(igmp_socket, recv_buf, RECV_BUF_SIZE,				0, NULL, &dummy);	/* 8 == 4 bytes of options and 4 bytes of PID */	if (recvlen >= MIN_IP_HEADER_LEN + IGMP_MINLEN + 8) {	    struct ip *ip = (struct ip *)recv_buf;	    struct igmp *igmp;	    int *p;	    if (ip->ip_hl != 6 ||		ip->ip_p != IPPROTO_IGMP ||	        ip->ip_src.s_addr != localhost ||		ip->ip_dst.s_addr != localhost)		continue;	    igmp = (struct igmp *)(recv_buf + (ip->ip_hl << 2));	    if (igmp->igmp_group.s_addr != 0)		continue;	    if (igmp->igmp_type != 0 || igmp->igmp_code != 0)		continue;	    p = (int *)((char *)igmp + IGMP_MINLEN);	    if (*p != getpid())		continue;#ifdef RAW_INPUT_IS_RAW	    ip->ip_len = ntohs(ip->ip_len);#endif	    if (ip->ip_len == IGMP_MINLEN + 4)		ip_addlen = 4;	    else if (ip->ip_len == IGMP_MINLEN + 8)		ip_addlen = 0;

⌨️ 快捷键说明

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