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

📄 entest.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
static char sccsid[] = "@(#)entest.c	1.1 7/30/92 17:35:48, Copyright Sun Microsystems";/*****************************************************************************  Date:		Mon Sep 25 10:58:39 1989  File:		entest.c  Author:	Anantha Srirama  Description:  This file contains the functions and the main routine which  		constitute the ENTest.  Refer to the header of each function		for detailed description on their operation (I am not kidding		this time, I have actually completed the headers not just		inserting a header template!!)  Copyright (c) 1989 Sun Microsystems, Inc.*****************************************************************************/#include <stdio.h>#include <errno.h>#include <sgtty.h>#include <sys/types.h>#include <sys/file.h>#include <sys/stropts.h>#include <sys/time.h>#include <sys/socket.h>#include <sys/sockio.h>#include <sys/fcntl.h>#include <sys/stat.h>#include <net/if.h>#include <net/nit.h>#include <net/nit_if.h>#include <net/nit_pf.h>#include <net/packetfilt.h>#include <netinet/in.h>#include <netinet/if_ether.h>/*  * FDDI specific includes */#include "fddi_types.h"	/* change to <sunfw/fddi/fddi_types.h> when ready */#include "commands.h"	/* change to <sunfw/fddi/commands.h> when ready   *//*  * Test specific includes */#include "entest.h"/*  * Sundiag specific includes */#include	<signal.h>/*#include	"entest_msgs.h"*/#include	"sdrtns.h"#include	"../../../lib/include/libonline.h" /*  * Broadcast, Our, Upstream and Downstream neighbor adresses */mac_addr_t broadcast = {			  /* Broadcast  */    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};mac_addr_t una;					  /* Upstream   */mac_addr_t dna;					  /* Downstream */mac_addr_t our_addr;				  /* Our        *//* * File descriptor for the open device /dev/nit */int	fd;/* * SIF Configuration Request frame structure */smthdr_t	sif;/* * This is a global variable which has a non-zero value if the FW has been * reconfigured. */u_long	fw_reconfigured = !RECONFIGURED;u_char	recv_data[BUFSIZ], recv_cntl[BUFSIZ];/*****************************************************************************  probe_fddi ()  This function verifies that the FDDI is indeed available in the system.  This function is called if the test is being executed from the command line  instead of the SunDiag.  This is so because SunDiag will not call the test  if the FDDI is not available.  We verify the existance of the FDDI as  follows	- Open a socket	- perform a 'ioctl' with fddi0 as the interface name and request	  status  If the interface is not present 'ioctl' returns a -ve value.  This function will not return in case there is no FDDI.*****************************************************************************/void fddi_probe (){    int	sock;    struct fddi_status_struct fsb;    struct ifreq ifr;        func_name = "fddi_probe";    TRACE_IN    if ((sock = socket (AF_INET, SOCK_DGRAM, 0)) < 0)     {	send_message (-NO_SOCKET, FATAL, "%s could not open socket: %s",		      test_name, errmsg (errno));    }    /*      * Initialize the 'ifr' structure with proper values and call 'ioctl'     * function to find out if we have a FDDI interface in the system     */    strncpy (ifr.ifr_name, DEVICE_NAME, sizeof (ifr.ifr_name));    ifr.ifr_fddi_stat.stat_size = sizeof (fsb);    ifr.ifr_fddi_stat.fddi_stats = (caddr_t) &fsb;    if (ioctl (sock, SIOCGETFDSTAT, (caddr_t) &ifr) < 0)     {	send_message (-NO_FDDI_IF, FATAL, "%s no fddi interface: %s",		      test_name, errmsg (errno));    }    close (sock);    TRACE_OUT}/*****************************************************************************  fddi_fw_setup (fw_agent)  This function sets up the FDDI firmware so that it passes up all the SMT  frames to the host.  In the default mode of the firmware, these frames are  handled by the firmware.  We need to access all the SMT frames because we use  SMT frames to perform the tests.  Before exiting the test the FDDI firmware  MUST be reprogrammed to its default state.  fw_agent = DISABLE ====> program the FDDI firmware to pass up all the SMT  			   frames except NIF, SIF: config and operation  fw_agent = ENABLE =====> default operation of FDDI, all SMT frames handled  			   by firmware.  Host sees no SMT packets.  The reprogramming of the FDDI firmware switches are done by the use of  'ioctl' calls.  Note: Since this function is called from within clean_up it exits directly*****************************************************************************/void fddi_fw_setup (fw_agent)int fw_agent;{    int sock;    struct fddi_smt_config fsc;    struct ifreq ifr;        func_name = "fddi_fw_setup";    TRACE_IN    strcpy (ifr.ifr_name, device_name);    ifr.ifr_fddi_gstruct.ifru_fddi_gioctl = FDDI_SMT_SWITCHES;    ifr.ifr_fddi_gstruct.ifru_fddi_gaddr = (caddr_t) &fsc;    if (fw_agent == ENABLE)     {	send_message (0, VERBOSE, "%s Enabling FW", test_name);    }    else     {	send_message (0, VERBOSE, "%s Disabling FW", test_name);    }    fsc.resp_frame_sw = fw_agent;    fsc.nif_frame_sw = ENABLE;			  /* enabled all the time */    fsc.disable_fw_agent = ENABLE;		  /* enabled all the time */    if ((sock = socket (AF_INET, SOCK_DGRAM, 0)) < 0)     {	send_message (-NO_SOCKET, FATAL, "%s could not open socket: %s",		      test_name, errmsg (errno));    }    if (ioctl (sock, SIOCFDGIOCTL, (caddr_t) &ifr) < 0)     {	send_message (-RECONFIG_ERROR, FATAL, "%s reconfig failed: %s",		      test_name, errmsg (errno));	send_message (-RECONFIG_ERROR, FATAL, "%s REMEMBER TO RECONFIG THE FIRMWARE",		      test_name);    }    close (sock);    TRACE_OUT}/*****************************************************************************  nit_open ()  This function opens the device '/dev/nit' and then binds it to the FDDI  after pushing a packet filter on to it as follows:  	- opens the device '/dev/nit'	- puts the device in message-discard mode, refer to streamio(4) for	  more info on this mode.	- pushes a filter packet onto the stream effectively filtering the	  unnecessary packets.	- binds this device to FDDI, this binding is done after pushing the	  filter so as to prevent us being flooded with unwanted packets.	- flush the readside of the stream  This function returns the file descriptor pointing to the '/dev/nit'.*****************************************************************************/int	nit_open (){    int			nit_fddi;    u_short*		fwp;    struct packetfilt	pf;    struct ifreq	ifr;    machdr_t		machdr;    struct strioctl	si;        func_name = "nit_open";    TRACE_IN    if ((nit_fddi = open ("/dev/nit", (O_RDWR | O_NDELAY))) < 0)     {	send_message (-NIT_OPEN_FAIL, FATAL, "%s unable to open /dev/nit: %s",		      test_name, errmsg (errno));    }    send_message (0, VERBOSE, "%s /dev/nit open succeded", test_name);        /*      * Set up the stream to be in 'message-discard' mode.  For more     * description of this mode refer to streamio(4) and read (2v) of the man     * pages     */    if (ioctl (nit_fddi, I_SRDOPT, (char*) RMSGD) < 0)     {	send_message (-NIT_RMSGD_FAIL, FATAL,		      "%s unable to set message-discard mode: %s",		      test_name, errmsg (errno));    }    send_message (0, VERBOSE, "%s settting of message-discard succeceded",		  test_name);    /*      * Push the packet filtering mechanism     */    if (ioctl (nit_fddi, I_PUSH, "pf") < 0)     {	send_message (-FILT_PUSH_FAIL, FATAL, "%s filter push failed: %s",		      test_name, errmsg (errno));    }    send_message (0, VERBOSE, "%s Packet Filter PUSH succeceded", test_name);    /*      * Set up the filtering criteria to discard any packet that is     * not of SMT type.  The streams module maintains an internal stack     * upon which it performs actions (the stack elements are all 2 octets)     * The filter works as follows:     *     *		- Push the 13th and 14th byte of the incoming packet     *		- Push the FDDI_MASK which is a predefined constant     *		- request a logical AND operation by pushing ENF_AND     *		  This operation takes the top two elements of the stack     *		  and performs a logical AND leaving the result on top of     *		  the stack.     *		- Then we push the Frame class type on the stack     *		- Request an equality test.  This compares the top two elements     *		  of the stack leaving a non-zero value on top of the stack if     *		  the two values are equal.     *     * The stream will deliver the packet only if the value on top of the     * stack is non-zero, meaning it meets the criteria we set.     */    fwp = &pf.Pf_Filter[0];    *fwp++ = ENF_PUSHWORD +	((u_int) &machdr.type - (u_int) &machdr.da) / sizeof (u_short);    *fwp++ = ENF_PUSHLIT;    *fwp++ = FDDI_MASK;    *fwp++ = ENF_AND;    *fwp++ = ENF_PUSHLIT;    *fwp++ = MAC_FC;    *fwp++ = ENF_EQ;    pf.Pf_FilterLen = fwp - &pf.Pf_Filter[0];    pf.Pf_Priority = 5;			/* meaningless, shoul be > 5 */    /*      * Now set the filter using ioctl.     */    si.ic_cmd = NIOCSETF;    si.ic_timout = -1;    si.ic_len = sizeof (struct packetfilt);    si.ic_dp = (char*) &pf;    if (ioctl (nit_fddi, I_STR, &si) < 0)     {	send_message (-SET_FILT_FAIL, FATAL,		      "%s setting packet filter failed: %s",		      test_name, errmsg (errno));    }    send_message (0, VERBOSE, "%s Packet Filter in place", test_name);    /*      * Now we go ahead and bind the device 'fddi0' to the NIT device.       * This deferral is done so that we are not swamped with packets      * which are of no interest to us.     */    strcpy (ifr.ifr_name, DEVICE_NAME);    si.ic_cmd = NIOCBIND;    si.ic_timout = 0;    si.ic_len = sizeof (struct ifreq);    si.ic_dp = (char*) &ifr;    if (ioctl (nit_fddi, I_STR, &si) < 0)     {	send_message (-NIT_BIND_FAIL, FATAL,		      "%s could not bind fddi to /dev/nit: %s",		      test_name, errmsg (errno));    }    send_message (0, VERBOSE, "%s /dev/nit bound to %s",		  test_name, DEVICE_NAME);    /*      * Flush the readside of the stream     */    if (ioctl (nit_fddi, I_FLUSH, (char*) FLUSHR) < 0)     {	send_message (-NIT_FLUSH_FAIL, FATAL, "%s read flush failed: %s",		      test_name, errmsg (errno));    }    send_message (0, VERBOSE, "%s Flush of readside of stream succeceded",		  test_name, DEVICE_NAME);    TRACE_OUT    return (nit_fddi);}/*****************************************************************************  init_sif_packet ()  This function intializes a SIF packet.  We have one global buffer, of octets,  which is cast here appropriately and initialized.  The packet by the way is  SIF Configuration Request type of SMT packet.  The transaction_id of the  packet is set to broadcast (0x12345678).  This transaction_id is not a part  of the FDDI standard.  This transaction_id is copied by the responding node  into the response packets transaction_id.*****************************************************************************/void	init_sif_packet (){    struct ifreq	ifr;    struct strioctl	si;        func_name = "init_sif_packet";    TRACE_IN    /*      * Figure out our own address.  After the 'ioctl' call the field     * ifr.ifr_addr.sa_data will hold our address.     */    strcpy (ifr.ifr_name, DEVICE_NAME);    si.ic_cmd = SIOCGIFADDR;    si.ic_timout = -1;    si.ic_len = sizeof (struct ifreq);    si.ic_dp = (char*) &ifr;    if (ioctl (fd, I_STR, (char*) &si) < 0)     {	send_message (-IF_ADDR_FAIL, FATAL,		      "%s could not get interface address: %s",		      test_name, errmsg (errno));    }    memcpy (our_addr.octet, ifr.ifr_addr.sa_data, sizeof (mac_addr_t));    send_message (0, DEBUG, "%s Our MAC addr: %d:%d:%d:%d:%d:%d",		  test_name,		  our_addr.octet[0], our_addr.octet[1], our_addr.octet[2],		  our_addr.octet[3], our_addr.octet[4], our_addr.octet[5]);        /*      * Initialize the different fields of the the SMT header     */    sif.frame_class = SMT_SIF_CLASS;    sif.frame_type = SMT_SIF_REQUEST;    sif.smt_version = SMT_VERSION;    sif.transaction_id = 0x12345678;		  /* arbitrary */    sif.station_id[0] = sif.station_id[1] = 0;    memcpy (&sif.station_id[2], our_addr.octet, sizeof (mac_addr_t));    sif.pad =  sif.info_field_len = 0;    TRACE_OUT}/*****************************************************************************  send_sif_packet (addr)

⌨️ 快捷键说明

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