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

📄 if_sl.c

📁 Tornado 2.0.2 source code!vxworks的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
     */    if (ifDstAddrSet (slipName, peerAddr) == ERROR	||        ifAddrSet (slipName, myAddr) == ERROR		||	routeAdd (myAddr, myAddr) == ERROR)	{	(void) close (slipFd);	return (ERROR);	}    /* start up the SLIP output task for this interface */    sc->sc_wrtTaskId = taskSpawn (slipWrtName, slipTaskPriority,		                  slipTaskOptions, slipTaskStackSize,		                  (FUNCPTR) slipWrtTask, (int) sc,				  0, 0, 0, 0, 0, 0, 0, 0, 0);    if (sc->sc_wrtTaskId == ERROR)	{	(void) close (slipFd);	return (ERROR);	}    return (OK);    }/********************************************************************************* slipBaudSet - set the baud rate for a SLIP interface** This routine adjusts the baud rate of a tty device attached to a SLIP* interface.  It provides a way to modify the baud rate of a tty* device being used as a SLIP interface.** RETURNS: OK, or ERROR if the unit number is invalid or uninitialized.*/STATUS slipBaudSet    (    int unit,           /* SLIP device unit number */    int baud            /* baud rate */    )    {    SL_SOFTC *sc;    /* check for valid unit number */    if (unit < 0 || unit >= NSLIP)	{	(void)errnoSet (S_if_sl_INVALID_UNIT_NUMBER);	return (ERROR);	}    /* make sure that the sl_softc for the 'unit' is initialized properly */    if ((sc = sl_softc [unit]) == NULL)	{	(void)errnoSet (S_if_sl_UNIT_UNINITIALIZED);	return (ERROR);	}    return (ioctl (sc->sc_fd, FIOBAUDRATE, baud));    }/********************************************************************************* slattach - publish the `sl' network interface and initialize the driver and device** This routine publishes the `sl' interface by filling in a network interface* record and adding this record to the system list.  It also initializes* the driver and the device to the operational state.** This routine is usually called by slipInit().** RETURNS: OK or ERROR.*/STATUS slattach    (    int		unit,		/* SLIP device unit number */    int		fd,		/* fd of tty device for SLIP interface */    BOOL	compressEnable,	/* explicitly enable CSLIP compression */    BOOL	compressAllow,	/* enable CSLIP compression on Rx */    int		mtu		/* user setable MTU */    )    {    SL_SOFTC		*sc;    struct ifnet	*ifp;    int			ix;    if (sl_softc [unit] != NULL)	{	(void)errnoSet (S_if_sl_UNIT_ALREADY_INITIALIZED);	return (ERROR);	}    if ((sc = (SL_SOFTC *) calloc (1, sizeof (SL_SOFTC))) == (SL_SOFTC *) NULL)	return (ERROR);    if (mtu <= 0 || mtu > 2048)	mtu = SLMTU;    sl_softc [unit] = sc;    ifp = &sc->sc_if;	/* get a pointer to ifnet structure */    ifp->if_name 	   = "sl";    ifp->if_unit 	   = unit;    ifp->if_mtu 	   = mtu;    ifp->if_flags 	   = IFF_POINTOPOINT | IFF_MULTICAST;    sc->sc_if.if_type 	   = IFT_SLIP;    ifp->if_ioctl 	   = slioctl;    ifp->if_init	   = (FUNCPTR) slinit;    ifp->if_output 	   = sloutput;    ifp->if_reset 	   = slipDelete;    ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;    if_attach (ifp);	/* attach SLIP to linked list of all interfaces */    sc->sc_flags	= 0;    sc->sc_ilen		= 0;    sc->sc_qlen		= 0;    sc->sc_nLoanRxBuf	= L_POOL;    /* set CSLIP options in the SL_SOFTC flags */    if (compressEnable || compressAllow)	{        sl_compress_init (&sc->sc_comp);        if (compressEnable)            sc->sc_flags |= SL_COMPRESS;	else            sc->sc_flags |= SL_COMPRESS_RX;        }    /* allocate SLIP input buffer space, including loaner buffers */    if ((sc->sc_orig = (char *) calloc (L_POOL, (u_int) SLBUFSIZE)) == NULL)	{	slSoftcFree (sc, unit);	return (ERROR);	}    sc->sc_buf = sc->sc_orig + SLBUF_OFF;	/* leave space for uncompress */    /* assign loaner buffer addresses */    for (ix = 0; ix < L_POOL; ix++)	{	sc->sc_lPool[ix] = (sc->sc_buf + (ix * SLBUFSIZE));	sc->sc_refC[ix]  = 0;	sc->sc_pRefC[ix] = &sc->sc_refC[ix];	}    if ((sc->sc_wrtSem = semBCreate (SEM_Q_PRIORITY, SEM_EMPTY)) == NULL)	{	slSoftcFree (sc, unit);	return (ERROR);	}    /*     * Make sure that the tty device described by 'fd' is     * indeed a tty device.     */    if (ioctl (fd, FIOISATTY, 0 /*XXX*/) == TRUE)	sc->sc_fd = fd;    else        {	slSoftcFree (sc, unit);	return (ERROR);        }    /*     * call ioctl to,     *   FIOFLUSH     - flush out everything on this tty dev     *   FIOOPTIONS   - set the tty dev in RAW mode     *   FIOPROTOHOOK - specify the protocol interface hook routine for SLIP     *   FIOPROTOARG  - specify the SLIP unit number for this tty dev     */    if (ioctl (fd, FIOFLUSH, 0 /*XXX*/)        == ERROR ||	ioctl (fd, FIOOPTIONS, OPT_RAW)        == ERROR ||	ioctl (fd, FIOPROTOHOOK, (int) slintr) == ERROR ||	ioctl (fd, FIOPROTOARG, unit)          == ERROR)	{	slSoftcFree (sc, unit);	return (ERROR);	}    return (OK);    }/********************************************************************************* slipDelete - delete a SLIP interface** This routine resets a specified SLIP interface.  It detaches the tty from* the `sl' unit and deletes the specified SLIP interface from the list of* network interfaces.  For example, the following call will delete the first* SLIP interface from the list of network interfaces:* .CS*     slipDelete (0);* .CE** RETURNS: OK, or ERROR if the unit number is invalid or uninitialized.*/STATUS slipDelete    (    int unit                    /* SLIP unit number */    )    {    SL_SOFTC	*sc;    struct mbuf	*pMbuf;    int		s;    if (unit >= 0 && unit < NSLIP)    	sc = sl_softc [unit];    else	{	(void)errnoSet (S_if_sl_INVALID_UNIT_NUMBER);    	return (ERROR);	}    if (sc == NULL)	{	(void)errnoSet (S_if_sl_UNIT_UNINITIALIZED);	return (ERROR);	}    /* flush write side of the tty ringer buffer */    (void) ioctl (sc->sc_fd, FIOWFLUSH, 0 /*XXX*/);    (void) ioctl (sc->sc_fd, FIOPROTOHOOK, NULL);    s = splimp ();		/* paranoid; splnet probably ok */    if_down (&sc->sc_if);		/* mark it down */    (void) close (sc->sc_fd);		/* close the tty device */    for (;;)			/* flush the wrt task queue and free mbufs */	{	IF_DEQUEUE (&sc->sc_if.if_snd, pMbuf);	if (pMbuf == NULL)	    break;	m_freem (pMbuf);	}    if (sc->sc_wrtTaskId != ERROR)        taskDelete (sc->sc_wrtTaskId);    /*     * Delete all routes associated with this SLIP interface.     * This will effectively delete the point-to-point routes for this SLIP.     */    (void) ifRouteDelete ("sl", unit);    slSoftcFree (sc, unit);    splx (s);    return (OK);    }/********************************************************************************* slSoftcFree - free the allocated sl_softc structure** This is called by slattach to free the allocated sl_softc structure* when error occurs within slattach.  The reason for having this routine* is to get rid of the repetitive code within slattach ().* This routine is also called by slipDelete ().*/LOCAL void slSoftcFree    (    SL_SOFTC *sc,    int       unit    )    {    /* Take the pointer to this SLIP interface out of the linked list     * of all available network interfaces.  The if_dettach () will un-do     * the action taken by if_attach ().     */    if_dettach (&sc->sc_if);    semDelete (sc->sc_wrtSem);		/* delete write semaphore */    if (sc->sc_buf)	{	(void) free (sc->sc_orig);	sc->sc_buf = NULL;	}    (void) free ((char *) sc);    sl_softc [unit] = (SL_SOFTC *) NULL;    }/********************************************************************************* slinit - initialize SLIP interface*/LOCAL void slinit    (    int unit    )    {    SL_SOFTC *sc = sl_softc [unit];    sc->sc_if.if_flags |= IFF_UP|IFF_RUNNING; /* open for business */    }/********************************************************************************* sloutput - output a packet over the SLIP line** Queue a packet and trigger the slipWrtTask if a packet is ready* by releasing the semaphore.  CSLIP compression for TCP/IP headers is* supported if (enabled).** RETURNS: OK, or ERROR if the output queue is full.*/LOCAL STATUS sloutput    (    FAST struct ifnet   *ifp,           /* SLIP interface pointer */    FAST struct mbuf    *m,             /* SLIP packet to be sent out */    struct sockaddr     *dst,           /* address of the destination */    struct rtentry	*rtp		/* pointer to the route entry */    )    {    FAST SL_SOFTC *sc;    FAST struct ip *ip;    FAST int 	   s;    FAST int 	   unit;    if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))	{        m_freem (m);        return (ENETDOWN);	}    /*     * Check and see if protocol family is equal to AF_INET.     * Currently only AF_INET is support for SLIP.     */    if (dst->sa_family != AF_INET)        {        m_freem (m);	return (EAFNOSUPPORT);        }    unit = ifp->if_unit;    sc = sl_softc [unit];    /*     * n.b.-- the `40' below checks that we have a least a min length     * tcp/ip header contiguous in an mbuf.  We don't do `sizeof' on     * some struct because too many compilers add random padding.     */    if (sc->sc_flags & SL_COMPRESS)		/* compress enabled ? */	{        ip = mtod(m, struct ip *);        if ((ip->ip_p == IPPROTO_TCP) && (m->m_len >= 40))            *mtod(m, u_char *) |= sl_compress_tcp (m, ip, &sc->sc_comp, 1);        }    s = splimp ();    /*     * If send queue is full drop the packet.     */    if (IF_QFULL (&ifp->if_snd))        {        IF_DROP (&ifp->if_snd);        m_freem (m);        ++sc->sc_if.if_oerrors;        splx (s);        return (ENOBUFS);        }    /* enqueue the packet for IP module to read later */    IF_ENQUEUE (&ifp->if_snd, m);    ifp->if_lastchange = tickGet ();     splx (s);    /* wake the SLIP ouput task to let it send out this packet */    semGive (sc->sc_wrtSem);    return (OK);    }/********************************************************************************* slipWrtTask - SLIP writer task** This is our write side task.  It waits for a semaphore and* when sloutput() yields the semaphore, it will try to send out* the packet that's been queue up so far.  Each SLIP interface* has its own slipWrtTask which is spawned in slipInit().* Start output on interface.  Get another datagram* to send from the interface queue and map it to* the interface before starting output.** NOMANUAL*/void slipWrtTask    (    FAST SL_SOFTC *sc           /* SLIP softc pointer */    )    {    FAST struct mbuf 	*m;    FAST u_char 	*cp;    FAST int 		 len;    int 	 	 fd;    struct mbuf	 	*m2;    int 		 rdCount;    int 		 numch;    char 		 ch;    int 		 s;    fd = sc->sc_fd;    FOREVER	{	semTake (sc->sc_wrtSem, WAIT_FOREVER); /* sync w/ sloutput */	FOREVER	    {	    /* get a packet off of the queue */	    s = splimp ();	    IF_DEQUEUE (&sc->sc_if.if_snd, m);	    splx (s);	    if (m == NULL)		break;	    /*	     * Check if the serial line has been idle for awhile.	     * If it has been idle for awhile, we send out a FRAME_END	     * character to clear out any garbage in transit and start	     * fresh with a new packet.  We find out whether or not	     * the line has been idle for awhile by looking at the	     * read side of the tty ring buffer queue.  It is assumed	     * that if there is nothing to read from the queue, we	     * must have been idle for awhile.  If our assumption	     * is incorrect, we only have wasted the amount of work	     * and bandwidth it takes to send a character over SLIP.	     * More than likely, though, this is better than sending	     * out a large packet and clobbering the whole packet	     * because of the bad data.	     */	    (void) ioctl (fd, FIONREAD, (int) &rdCount);	    if (rdCount == 0)		{		ch = FRAME_END;		++sc->sc_if.if_obytes;		(void) write (fd, &ch, 1);		}	    /*	     * send the packet.	     */	    while (m)		{		cp  = mtod (m, u_char *);		len = m->m_len;		while (len > 0)		    {		    /*		     * Find out how many bytes in the string we can		     * handle without doing something special.		     */		    if ((numch = numCharsToMask (FRAME_ESCAPE, FRAME_END,			(u_int) len, cp)) > 0)			{			/*			 * Put numch characters at once			 * into the tty output queue.			 */			if (write (fd, (char *)cp, numch) != numch)

⌨️ 快捷键说明

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