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

📄 nettest.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
******************************************************************************/int	make_sock (test_net, sock_type)int	test_net;int	sock_type;{    struct	protoent *proto;    struct	sockaddr_in from;    int		dontblock = 1;    int		psock = 0;    func_name = "make_sock";    TRACE_IN    if (!(proto = getprotobyname ("icmp")))     {	send_message (-NO_PROTOCOL_ENTRY, FATAL,		      "%s No protocol entry for ICMP %s",		      test_name, errmsg (errno));    }    if (sock_type == SOCK_DGRAM)    {       if ((psock = socket (AF_INET, SOCK_DGRAM, 0)) < 0)        {        send_message (-NO_XMIT_SOCKET, FATAL, "%s socket open failed %s",                      test_name, errmsg (errno));       }    }    if (sock_type == SOCK_RAW)    {        if ((psock = socket (AF_INET, SOCK_RAW, proto->p_proto)) < 0)         {	    send_message (-NO_XMIT_SOCKET, FATAL, "%s  socket open failed %s",		      test_name, errmsg (errno));        }    }    bzero ((char *) &from, sizeof (from));    from.sin_family = AF_INET;    from.sin_addr = valid_if[test_net].my_addr;    from.sin_port = 0;    if ((bind (psock, (char *) &from, sizeof (from))) < 0)     {	send_message (-NO_XMIT_SOCKET, FATAL, "%s socket bind failed %s",		      test_name, errmsg (errno));    }    (void) ioctl (psock, FIONBIO, (char *) &dontblock);    TRACE_OUT    return (psock);}/******************************************************************************  in_cksum	(fudged from ping.c)  Checksum routine for Internet Protocol family headers (C Version)******************************************************************************/u_short	in_cksum (addr, len)u_short	*addr;int	len;{    register int    sum = 0;		       /* accumulator for checksum */    register int    nleft = len;	       /* remaining bytes in buffer */    register u_short *w = addr;		       /* word pointer in buffer */    /*     * Our algorithm is simple: using a 32 bit accumulator (sum), we add     * sequential 16 bit words to it, and at the end, fold back all the carry     * bits from the top 16 bits into the lower 16 bits.     */    func_name = "in_chsum";    TRACE_IN    while (nleft > 1)     {	sum += *w++;			/* add 16 bits at a time */	nleft -= 2;    }    if (nleft == 1) sum += (int) (*(u_char *) w);    /*     * add back carry outs from top 16 bits to low 16 bits     */    sum = (sum >> 16) + (sum & 0xffff);	       /* add hi 16 to low 16 */    sum += (sum >> 16);			       /* add carry */    TRACE_OUT    return ((u_short) ~sum);}/******************************************************************************  net_dtablesize  Return max # of possible file descriptors******************************************************************************/int	net_dtablesize (){    static int  called_already;    if (!called_already)     {	called_already = getdtablesize ();    }    return (called_already);}/******************************************************************************  do_select  This function calls the driver call 'select' with the 'what_select' status.  It returns the residual 'time_count' to the calling routine.  A return value  of 0 should be interpreted as a timeout condition by the calling routine.******************************************************************************/int	do_select (sock, what_select, time_count)int	sock;int	what_select;int	time_count;{    fd_set	sel_mask;    int		nfds = 0;  /* total number of ready descriptors in all sets */			   /* returned by calling select */    func_name = "do_select";    TRACE_IN    for ( ; ((time_count > 0) && (nfds <= 0)); time_count--)     {	/*	 * get size of descriptor table size for this process and then	 * using it and then call select to get a mask of those descriptors	 * which are ready.  The total number of ready descriptors is	 * returned in nfds.  Select examines the I/O descriptors  specified	 * by  the  bit masks  readfds,  writefds,  and exceptfds to see if	 * they are ready for reading, writing, or have an exceptional	 * condition  pending,  respectively.  Descriptor masks are reset 	 * after each call to select since they are modified if no errors         * occur.  Resetting descriptor masks after each call to select         * helps prevent bogus error reports when a timeout occurs.	 */    FD_ZERO (&sel_mask);       /* initializing descriptor masks to null */    FD_SET (sock, &sel_mask);  /* set/reset descriptor masks */	if (what_select == WRITE_SELECT)  	{	    nfds = select (net_dtablesize (), (fd_set *) NULL, &sel_mask,			   (fd_set *) NULL, &sel_time);	}	else  	{	    nfds = select (net_dtablesize (), &sel_mask, (fd_set *) NULL,			   (fd_set *) NULL, &sel_time);	}	if (nfds < 0)  	{ 	    send_message (-SELECT_ERROR, ERROR, "%s select %s",			  test_name, errmsg (errno));	}    }    TRACE_OUT    return (time_count);}/******************************************************************************  ping_send  This function sends out a ICMP packet out on the network.  It sets up the  packet with the appropriate information, generates the checksum, and then  calls the function 'do_select' to check if the interface is ready for  transmission.  After this the packet is is shot out and the function returns.  If it encounters any errors during this, the program is exited with an  appropriate error code.******************************************************************************/void	ping_send (sock, to, device)int	sock;struct	sockaddr_in *to;char	*device;{    static	u_char   pack[MAXPACKLEN];    struct	icmp    *icmp_p = (struct icmp *) pack;    struct	timeval *time_p = (struct timeval *) & pack[8];    int		len;    func_name = "ping_send";    TRACE_IN    (void) gettimeofday (&current_time[seqno], (struct timezone *) NULL);    bcopy ((char *) &current_time[seqno], (char *) time_p,	   sizeof (struct timeval));    icmp_p->icmp_type = ICMP_ECHO;    icmp_p->icmp_code = 0;    icmp_p->icmp_cksum = 0;    icmp_p->icmp_seq = seqno++;    icmp_p->icmp_id = id_pid;    icmp_p->icmp_cksum = in_cksum ((u_short *) icmp_p, packetsize);    if (do_select (sock, WRITE_SELECT, WAIT_TIME) == 0)     {	send_message (-TRANSMIT_BC_TIMEOUT, ERROR,		      "%s could not broadcast (timeout) on %s",		      test_name, device);    }    send_message (0, DEBUG,		  "%s: Broadcasting ICMP Packet (sendto), ICMP hdr info:",		  func_name);    send_message (0, DEBUG, "Type=0x%x, Code=0x%x, Cksum=0x%x, Seq=0x%x, ID=0x%x, B-addr=%sData = 0x%x",			icmp_p->icmp_type, icmp_p->icmp_code,			icmp_p->icmp_cksum, icmp_p->icmp_seq,			icmp_p->icmp_id, inet_ntoa (to->sin_addr),			*time_p);    /* is packet sent out = packetsize */    if ((len = sendto (sock, (char *) pack, packetsize, 0,		       (struct sockaddr *) to, sizeof (*to))) != packetsize)     {	send_message (0, DEBUG,		      "%s: send len=%d, packetsize=%d, System errno = %d",		      func_name, len, packetsize, errno);	send_message (-NO_TRANSMIT_BC, ERROR, 		      "%s Transmit failed on %s, broadcast packet %s",		      test_name, device, errmsg (errno));    }    TRACE_OUT}/******************************************************************************  check_reply  This function checks a packet for integrity.  It checks all the information  in the packet for correctness.  Any error/mismatch results in the termination  of checking the reply and displaying an appropriate message.******************************************************************************/int 	check_reply (buf, cc, from, device)char	*buf;			/* IP packet received */int	cc;			/* received packet length */struct	sockaddr_in *from;	/* INTERNET style socket address received */char	*device;{    struct ip      *ip;	     /* Struct of an INTERNET hdr, naked of options. */    struct icmp    *icp;    struct timeval *time_p;    int		hdr_len, c;    int         valid_reply = 1;    u_short	tmp, cksum_save;    func_name = "check_reply";    TRACE_IN    ip = (struct ip *) buf;		       /* convert to IP structure */    hdr_len = ip->ip_hl << 2;    c = cc - hdr_len;    icp = (struct icmp *) (buf + hdr_len);    time_p = (struct timeval *) (buf + hdr_len + 8);    /*     * Start checking the packet now:     *     *   packet type must be ICMP_ECHO.  If the type is ICMP_UNREACH, then the     *		packet is not tagged as an error, instead it is ignored.     *   packet size     *   Verify checksum     *   Must be our packet (that is same process ID)     *   Must have the right sequence number     *   Must have the same time stamp for a valid sequence number     */        if (icp->icmp_type != ICMP_ECHOREPLY)     {        if ((icp->icmp_type != ICMP_UNREACH) &&	     (icp->icmp_type != ICMP_REDIRECT))         {	    if (print_warning)	    {	    	send_message (0, WARNING,	        "%s type = %d, should be ICMP_ECHOREPLY, from %s, on %s",		test_name, icp->icmp_type, inet_ntoa (from->sin_addr), device);	    }	}	TRACE_OUT	return(!valid_reply);    }    if ((cc < hdr_len + ICMP_MINLEN) || (c != packetsize))     {	if (print_warning)	{	    send_message (0, WARNING,	    "%s bad pkt size %d should be %d, from %s, on %s",	    test_name, cc, packetsize, inet_ntoa (from->sin_addr), device);	}        TRACE_OUT        return(!valid_reply);    }    cksum_save = icp->icmp_cksum;    icp->icmp_cksum = 0;    if ((tmp = in_cksum ((u_short *) icp, packetsize)) != cksum_save)     {        if (print_warning) 	{	    send_message (0, WARNING, "%s bad cksum:\tExpect 0x%hx\tGot: 0x%hx", test_name, icp->icmp_cksum, tmp);	}        TRACE_OUT        return(!valid_reply);    }    icp->icmp_cksum = cksum_save;    if (icp->icmp_id != id_pid)     {	if (print_warning)	{            send_message (0, WARNING,	    "%s pkt id (%d) not our pkt id (%d), from %s, on %s",	     test_name,icp->icmp_id,id_pid,inet_ntoa (from->sin_addr), device);	}        TRACE_OUT        return(!valid_reply);    }    if (icp->icmp_seq >= seqno)     {	if (print_warning)	{	    send_message (0, WARNING,"%s bad seq num:\tExp less than: %d\tGot: %d", test_name, seqno, icp->icmp_seq);	}        TRACE_OUT        return(!valid_reply);    }    if (bcmp ((char *) &current_time[icp->icmp_seq], (char *) time_p,	     sizeof (struct timeval)) != 0)     {	if (print_warning)	{	    send_message (0, WARNING,            "%s packet data mis-compare (different time stamp), from %s, on %s", test_name, inet_ntoa (from->sin_addr), device);	}        TRACE_OUT        return(!valid_reply);    }    TRACE_OUT    return(valid_reply);}/******************************************************************************  test_reply  This function tests a host that has replied to the broadcast net.  It makes sure that the replying host has not previously failed.  Then it does 3 tests.  First it sprays large packets.  Second  it sprays small packets.  Third, it tests UDP transmit.  Once all three tests pass, this function is done and won't test further.  Return status is true if tests have passed.******************************************************************************/int	test_reply (from, test_net)struct          sockaddr_in from;       /* address of the responding node */int     	test_net;{    int		test_succeeded = 0;    struct hostent	*replying_host;    static char old_host_that_failed[256];    float       packets_dropped = 0;    /* percentage of packets dropped */                                        /* after spraying host: hp->h_name */    int         sundiag_and_delay = 0;  /* if sundiag flag (s) and spray */                                        /* delay option (D=) are specified */       /*     * if sundiag_and_delay, use spray_cnt_large and spray_cnt_small instead      * of the default spray_cnt value = 10000.  spray_cnt_large and      * spray_cnt_small are the number of packets required to make the       * total  stream  size 100000 bytes     */    int    spray_cnt_large = 100000/1502;        int    spray_cnt_small = 100000/86;         func_name = "test_reply";

⌨️ 快捷键说明

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