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

📄 entest.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
  This function sends out a SIF packet out on the interface.  It initializes  the destination address before doing so.*****************************************************************************/void	send_sif_packet (addr)mac_addr_t*	addr;{    struct sockaddr	sock_addr;    struct strbuf	data, ctl;    machdr_t*		machdr;        func_name = "send_sif_packet";    TRACE_IN    /*      * Initialize the stream buffer structures for send/recv calls     */    ctl.len = sizeof (struct sockaddr);    data.len = sizeof (smthdr_t);    ctl.buf = (char*) &sock_addr;    data.buf = (char*) &sif;        /*      * Initialize the fields of the structure sock_addr.     */    sock_addr.sa_family = AF_UNSPEC;    machdr = (machdr_t*) sock_addr.sa_data;    memcpy (machdr->da.octet, (char*) addr, sizeof (mac_addr_t));    memcpy (machdr->sa.octet, our_addr.octet, sizeof (mac_addr_t));    machdr->type = MAC_FC;    if (putmsg (fd, &ctl, &data, 0) < 0)     {	send_message (-SEND_FAIL, FATAL, "%s could not send: %s",		   test_name, errmsg (errno));    }    send_message (0, VERBOSE, "%s Sent the SIF packet successfully",		  test_name);    TRACE_OUT}/*****************************************************************************  cmp_fddi_addr (addr1, addr2)  This function compares the address' addr1 and addr2.  The address 'addr1' is  in the normal form and the address 'addr2' is in the FDDI format with the  most significant bit in bit 0 and the least significant bit in bit 7.  This  function returns a non-zero value on miscompare.*****************************************************************************/int	cmp_fddi_addr (addr1, addr2)u_char*	addr1;u_char*	addr2;{    int		status = 0;    u_char	j;    u_char	i = 0;    u_char	tmp;    func_name = "cmp_fddi_addr";    TRACE_IN    while ((!status) && (i < 6))     {	tmp = 0;	for (j = 1 ; j != 0; j <<= 1)         {		  			/* format the FDDI addr */	    if (j & *(addr2 + i)) 	    {		tmp += 128 / j;	    }	}	if (tmp != *(addr1 + i)) 	{	    status = 1;	}	i++;    }    TRACE_OUT    return (status);}	/*****************************************************************************  receive_sif_packet ()  This function reads the stream.  The global buffers 'recv_cntl' and  'recv_data' will hold the packet on return.  The function 'getmsg' is  used to read the stream head.  We wait a maximum of 30 seconds for a  successful read from the stream.  If after the 30 seconds there is no  message at the stream head we exit the program.*****************************************************************************/void	receive_sif_packet (){    int			mode = 0;    int			done = 0;    int			i = 30;			  /* 30 seconds */    struct strbuf	l_cntl;    struct strbuf	l_data;        func_name = "receive_sif_packet";    TRACE_IN    l_cntl.len = l_data.len = 0;    l_cntl.maxlen = l_data.maxlen = BUFSIZ;    l_cntl.buf = (char*) recv_cntl;    l_data.buf = (char*) recv_data;    while ((!done) && (i > 0))     {	switch (getmsg (fd, &l_cntl, &l_data, &mode)) 	{	    case EAGAIN:		send_message (0, DEBUG, "%s stream empty: %s",			      test_name, errmsg (errno));		i--;		sleep (1);			  /* wait for a second */		break;	    case 0:		done = 1;		send_message (0, VERBOSE,			      "%s Received the SIF packet successfully",			      test_name);		break;	    default:		send_message (-RECV_FAIL, FATAL, "%s couldn't receive: %s",			      test_name, errmsg (errno));		break;	}    }    if (!i)     {	send_message (-RECV_TMOUT, FATAL, "%s getmsg timed out", test_name);    }    TRACE_OUT}/*****************************************************************************  get_neighbor_address ()  This function finds out the Upstream and Downstream neighbor addresses of  this node.  Then it examines each packets MAC field to determine if it is our  immediate Upstream or Downstream neighbor.  When this function returns the  global variables 'una' and 'dna' contain valid addresses of the Upstream and  Downstream neighbor respectively.  	- Send out a SIF Configuration Request to everybody by broadcasting	- Read the stream untill we find out the Upstream/Downstream neighbors  NOTE: The SIF Response packet information field varies from revision to	revision.  This may affect where exactly you will find the Up/Down	stream neighbor address.  The testing for the neighbor address should	be modifed as the version specifies.*****************************************************************************/void	get_neighbor_address (){    int			done = 0;    u_short		index = 0;    u_short		param_type = 0;    sif_resp_t*		sif_resp;        func_name = "get_neighbor_address";    TRACE_IN    send_sif_packet (&broadcast);    sif_resp = (sif_resp_t*) recv_data;    while (done != 2)  			/* until UNA & DNA are found */    {	param_type = 0;	receive_sif_packet ();	/* 	 * Check that we have the right kind of frame.  The packet 	 * filter just checks to see that we have a SMT frame.  We 	 * check in the following order:	 * 	 * 	- frame class should be SIF	 * 	- frame type should be an response	 * 	- transaction id should match with our own copy	 * 		 * If this condition is satisfied then we check the MAC 	 * neighbor field of the packets info field.  If the upstream 	 * or the downstream neighbors address match our address then 	 * we have a neighbor!  Save the source address appropriately	 */	if ((sif_resp->smt.frame_class == SMT_SIF_CLASS) &&	    (sif_resp->smt.frame_type == SMT_SIF_RESPONSE) &&	    (sif_resp->smt.transaction_id == 0x12345678))         {	    /* 	     * Figure out the index for the MAC Neighbors field in the 	     * information field	     */	    while ((param_type = * (u_short*) &sif_resp->sif_info_field[index])		   != MAC_NEIGHBOR)             {		index += * (u_short*) &sif_resp->sif_info_field[index + 2] + 4;	    }	    if (!cmp_fddi_addr (our_addr.octet,				&sif_resp->sif_info_field[index + 8])) 	    {		memcpy (dna.octet, &sif_resp->machdr.sa, sizeof (mac_addr_t));		send_message (0, VERBOSE, "%s DNA: %d:%d:%d:%d:%d:%d",			      test_name,			      dna.octet[0], dna.octet[1], dna.octet[2],			      dna.octet[3], dna.octet[4], dna.octet[5]);		done++;	    }	    if (!cmp_fddi_addr (our_addr.octet,				&sif_resp->sif_info_field[index + 14]))    	    {		memcpy (una.octet, &sif_resp->machdr.sa, sizeof (mac_addr_t));		send_message (0, VERBOSE, "%s UNA: %d:%d:%d:%d:%d:%d",			      test_name,			      una.octet[0], una.octet[1], una.octet[2],			      una.octet[3], una.octet[4], una.octet[5]);		done++;	    }	}    }    TRACE_OUT}/*****************************************************************************  run_fddi_tests (num_passes)  This function runs the actual test until 'num_passes' number of passes are  registered.  If we hit the error threshold as specified in ERROR_LIMIT then  the function is exited also.  This function returns the number of errors  encountered during the test.*****************************************************************************/int	run_fddi_tests (num_passes){    int		l_passes = 0;    int		l_errors = 0;    int		i = 0;    int		done = 0;    sif_resp_t*	sif_resp;    mac_addr_t	dest;        func_name = "run_fddi_tests";    TRACE_IN        /*      * arbitrary, but different from the broadcast SIF packet which is     * 0x12345678     */    sif.transaction_id = 0x87654321;        /*      * Talk a while with the Upstream Neighbor untill we are bored     */        sif_resp = (sif_resp_t*) recv_data;    while ((l_passes < (num_passes * 2)) && (!done))     {	send_message (0, VERBOSE, "%s Loop #: %d", test_name, l_passes);	if (i++ % 2)         {	    send_message (0, VERBOSE, "Talking to Upstream Neighbor");	    memcpy (dest.octet, una.octet, sizeof (mac_addr_t));	}	else         {	    send_message (0, VERBOSE, "Talking to Downstream Neighbor");	    memcpy (dest.octet, dna.octet, sizeof (mac_addr_t));	}	send_sif_packet (&dest);	receive_sif_packet ();	if ((sif_resp->smt.frame_class == SMT_SIF_CLASS) &&	    (sif_resp->smt.frame_type == SMT_SIF_RESPONSE) &&	    (sif_resp->smt.transaction_id == 0x87654321))         {	    if (memcmp(&sif_resp->machdr.sa, &dest, sizeof (mac_addr_t)) == 0)             {		l_passes++;	    }	    else 	    {		done++;		send_message (-SA_MISMATCH, ERROR, "Bad SA in SIF response");		if (++l_errors >= ERROR_LIMIT) 		{		    send_message (-TOOMANY_ERR, ERROR, "Too many errors");		    TRACE_OUT		    return (l_errors);		}		else 		{		    if (!run_on_error) 		    {			send_message (-EXIT_ON_ERROR, ERROR,				      "Exiting on first error");			TRACE_OUT			return (1);		    }		}	    }	}    }    TRACE_OUT    return (l_errors);}/*****************************************************************************  clean_up ()  This function is called before exiting program in any way.  This function  closes all the open file descriptors, programs the FDDI firmware to its  default state.*****************************************************************************/clean_up(){    func_name = "clean_up";    close (fd);					  /* close /dev/nit */    if (fw_reconfigured == RECONFIGURED)     {	fddi_fw_setup (ENABLE);    }}/*****************************************************************************  fddi_test *****************************************************************************/voidfddi_test(){    func_name = "fddi_test";        /*      * Initialize all the necessary stuff like the test name, parse      * the command line....     */    TRACE_IN    versionid = "1.1";    device_name = DEVICE_NAME;    /*      * If we are running from within SunDiag, then no need to do      * verify that the interface is present.  Because SunDiag will not      * allow the user to call the test if the interface is not present.     */    if (!exec_by_sundiag)     {/*    test_init (argc, argv, NULL, NULL, NULL);*/	fddi_probe ();    }    /*      * Set up the FDDI board to respond and pass up all SMT frames.       * This is required to run this test.  We send out SIF frames,      * which belong to the broad class of SMT frames, during the      * course of test to establish the upstream and downstream      * neighbor addresses and communicate with them.  This involves     * setting a bit in the FDDI firmware.     */    fddi_fw_setup (DISABLE);    fw_reconfigured = RECONFIGURED;    /*      * Open a streams interface to the FDDI     */    fd = nit_open ();    /*      * Initialize the different fields of a SIF Configuration Request packet.     */    init_sif_packet ();        /*      * Build neighbor addresses by sending out a SIF configuration request     * packet.     */    get_neighbor_address ();        /*      * The function run_fddi_tests actually executes the test.  If the      * variable 'single_pass' dictates how long the test will take.     */    run_fddi_tests ((single_pass || quick_test) ? 1 : TOTAL_PASS);        /*      * Reset the FDDI firmware to its default state.     */    fddi_fw_setup (ENABLE);    TRACE_OUT}

⌨️ 快捷键说明

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