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

📄 if_sl.c

📁 Tornado 2.0.2 source code!vxworks的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
			    break;			sc->sc_if.if_obytes += numch;			len -= numch;			cp  += numch;			}		    /*		     * If there are characters left in the mbuf,		     * the first one must be special..		     * Put it out in a different form.		     */		    if (len)			{			ch = FRAME_ESCAPE;			if (write (fd, &ch, 1) != 1)			    break;			++sc->sc_if.if_obytes;			ch = (*cp == FRAME_ESCAPE) ?			     TRANS_FRAME_ESCAPE :			     TRANS_FRAME_END;			if (write (fd, &ch, 1) != 1)			    break;			++sc->sc_if.if_obytes;			++cp;			--len;			}		    }		m2 = m_free (m); 		m = m2;		}	   /*	    * indicate the end-of-packet.	    */	    ch = FRAME_END;	    if (write (fd, &ch, 1) != 1)		{		/*		 * This shouldn't happen but if it does we try one		 * more time (just for the hack of it) and increment		 * the if_collisions and if_oerrors.		 */		ch = FRAME_END;		(void) write (fd, &ch, 1);		sc->sc_if.if_collisions++;		sc->sc_if.if_oerrors++;		}	    else		{		++sc->sc_if.if_obytes;		sc->sc_if.if_opackets++;		}	    }	}    }/********************************************************************************* slintr - SLIP tty protocol hook routine** Called at interrupt level by the tty driver input nterrupt routine.* It is our "protocol hook" routine set by an FIOPROTOHOOK ioctl() call.* slintr() examines each character coming in and keeps a count* of input characters in the ring buffer of the tty driver until* a full packet is indicated by FRAME_END.* When detected, enqueue a call to slread() via netJobAdd() to* be processed later at task level.* A net job will not be added if the first character of the packet* won't fit into the ring buffer.  In that case the entire packet* must be discarded at interrupt level.** This routine will return FALSE to tyIRd() to indicate* that normal processing should continue within tyIRd() when* this routine returns.** RETURNS: FALSE so tyIRd continues processing*/LOCAL BOOL slintr    (    int unit,   /* SLIP unit number */    int inchar  /* incoming character */    )    {    FAST SL_SOFTC *sc = sl_softc [unit];    TY_DEV * pTyDev;    RING_ID ringId;    /* Set discard flag if this is a new packet and ring buffer full */    if ( sc->sc_qlen == 0 )	{        pTyDev = (TY_DEV *) iosFdDevFind(sc->sc_fd);        ringId = pTyDev->rdBuf;        if (rngIsFull (ringId))	    sc->sc_flags |= SL_INTR_PACKET_DISCARD;        else	    sc->sc_flags &= ~SL_INTR_PACKET_DISCARD;        }    ++sc->sc_qlen;    if ((inchar & 0xff) == FRAME_END || sc->sc_qlen == SLBUF_HI)	{	/* schedule a read for this packet */        if (sc->sc_flags & SL_INTR_PACKET_DISCARD)	    sc->sc_if.if_ierrors++;        else	    {	    if (sc->sc_qlen == 1)	/* Single FRAME_END character */		{		sc->sc_qlen = 0;		return (TRUE);          /* Don't put it in ring buffer */		}            else	        (void) netJobAdd ((FUNCPTR) slread, (int) sc, sc->sc_qlen, 				  0, 0, 0);            }	sc->sc_qlen = 0;	}    return (FALSE);	/* continue ty processing */    }/********************************************************************************* slread - read a whole SLIP packet and call slinput to process each char** slread() is called only when FRAME_END is encountered when* we have a SLIP packet waiting for us to read in the tty's* input ring buffer.*/LOCAL void slread    (    FAST SL_SOFTC *sc,  /* SLIP interface */    FAST int count      /* number of characters to be read */    )    {    BOOL firstCluster = TRUE;    char *builtCluster;    char *nextBuf = sc->sc_buf;    FAST u_char *c1 = (u_char *) sc->sc_buf;    FAST u_char *c2 = c1;    FAST u_char *end;    int len;    if ((len = read (sc->sc_fd, sc->sc_buf, count)) == 0)	return;    end = (u_char *) (sc->sc_buf + len);    while (c1 < end)	{	++sc->sc_if.if_ibytes;	/* increment the recieved bytes */        	if (sc->sc_ilen > sc->sc_if.if_mtu)            {	    sc->sc_if.if_ierrors++;	    break;	    }	switch (*c1)	    {	    case FRAME_END:	        {                if (sc->sc_ilen > 0)		    {	            if ((builtCluster = slRecv (sc, firstCluster)) != NULL)		        {		        nextBuf = builtCluster;		        firstCluster = FALSE;			}                    sc->sc_ilen = 0;		    }	        sc->sc_buf = (char *) ++c1;		c2 = c1;		break;	        }	    case FRAME_ESCAPE:		{		c1++;	        if (*c1 == TRANS_FRAME_ESCAPE)	            *c1 = FRAME_ESCAPE;	        else if (*c1 == TRANS_FRAME_END)		    *c1 = FRAME_END;	        else 		    {	            sc->sc_if.if_ierrors++;                    sc->sc_ilen = 0;	            sc->sc_buf = (char *) c1;		    c2 = c1;		    break;		    }		}            default:		{		sc->sc_ilen++;                *c2++ = *c1++;		}            }	}    sc->sc_buf = nextBuf;    sc->sc_ilen = 0;    }/********************************************************************************* slRecv - process an input frame** This routine processes an input frame, then passes it up to the higher* level in a form it expects.  Buffer loaning, etherInputHookRtns, and* CSLIP uncompression are all supported.  Trailer protocols are not supported.** RETURNS: N/A*/LOCAL char *slRecv    (    FAST SL_SOFTC *sc,		/* SLIP interface */    BOOL firstCluster    )    {    FAST  struct mbuf *m = NULL;    FAST  char type;    char  *nextBuf = NULL;    char  *origBuf = sc->sc_buf;    UINT8 *origRef = sc->sc_pRefC[(sc->sc_nLoanRxBuf - 1)];    int	   s;	    type = *sc->sc_buf & 0xf0;    if (type != (IPVERSION << 4))        {        if (type & 0x80)	    type = TYPE_COMPRESSED_TCP;        else if (type == TYPE_UNCOMPRESSED_TCP)            *sc->sc_buf &= 0x4f;        /*         * we've got something that's not an IP packet.         * If compression is enabled, try to uncompress         * it.  Otherwise, if `auto-enable' compression         * is on and it's a reasonable packet,         * uncompress it then enable compression.         * Otherwise, drop it.         */        if ((sc->sc_flags & SL_COMPRESS) || ((sc->sc_flags & SL_COMPRESS_RX) &&             (type == TYPE_UNCOMPRESSED_TCP) && (sc->sc_ilen >= 40)))	    {            if ((sc->sc_ilen = sl_uncompress_tcp ((u_char **)&sc->sc_buf, 						  sc->sc_ilen, (u_int) type,						  &sc->sc_comp)) <= 0)                {	        sc->sc_if.if_ierrors++;	        return (NULL);                }            sc->sc_flags |= SL_COMPRESS;            }        else            {	    sc->sc_if.if_ierrors++;	    return (NULL);            }        }    if ((etherInputHookRtn != NULL) && ((*etherInputHookRtn)        (&sc->sc_if, sc->sc_buf, sc->sc_ilen) != 0))        return (NULL);    if ((firstCluster) && (sc->sc_nLoanRxBuf > 0) &&	(USE_CLUSTER (sc->sc_ilen)))        m = build_cluster (sc->sc_buf, sc->sc_ilen, &sc->sc_if,            MC_SL, sc->sc_pRefC[(sc->sc_nLoanRxBuf - 1)], slLoanFree,            (int) sc, (int) origBuf, (int) origRef);    /* if buffer was successfully turned into mbuf cluster */     if (m != NULL)        nextBuf = sc->sc_lPool[--sc->sc_nLoanRxBuf];    else        {        /* else do same ol' copy to mbuf */        m = copy_to_mbufs (sc->sc_buf, sc->sc_ilen, 0, &sc->sc_if);	if (m == NULL)	    {	    sc->sc_if.if_ierrors++;	    return (NULL);            }        }    /* send up to protocol */    sc->sc_if.if_ipackets++;    sc->sc_if.if_lastchange = tickGet();     s = splimp();    if (IF_QFULL(&ipintrq)) 	{	IF_DROP(&ipintrq);	sc->sc_if.if_ierrors++;	sc->sc_if.if_iqdrops++;	m_freem(m);	}     else	{	IF_ENQUEUE(&ipintrq, m);	schednetisr(NETISR_IP);	}    splx(s);    return (nextBuf);    }/********************************************************************************* slioctl - SLIP ioctl routine** Process an ioctl request.** RETURNS: 0 or errno*/LOCAL int slioctl    (    FAST struct ifnet *ifp,     /* pointer to SLIP interface */    int cmd,                    /* command */    caddr_t data                /* data */    )    {    FAST struct ifaddr *	ifa = (struct ifaddr *)data;    FAST struct ifreq *		ifr;    int				error = 0;    int 			s;    s = splimp ();    switch (cmd)        {        case SIOCGIFFLAGS:            *(short *)data = ifp->if_flags;            break;        case SIOCSIFADDR:	    if (ifa->ifa_addr->sa_family == AF_INET)                {		slinit (ifp->if_unit);                ifa->ifa_rtrequest = slRtRequest;                }	    else		error = EAFNOSUPPORT;	    break;	case SIOCSIFDSTADDR:            if (ifa->ifa_dstaddr->sa_family != AF_INET)		error = EAFNOSUPPORT;   	    break;	case SIOCADDMULTI:	case SIOCDELMULTI:	    ifr = (struct ifreq *)data;	    if (ifr == 0) 		{		error = EAFNOSUPPORT;		/* XXX */		break;		}	    switch (ifr->ifr_addr.sa_family)		{#ifdef INET		case AF_INET:		    break;#endif		default:		    error = EAFNOSUPPORT;		    break;		}	    break;        default:    	    error = EINVAL;        }    splx (s);    return (error);    }/********************************************************************************* numCharsToMask - scan the buffer for a mask** numcharsToMask finds out how many characters are in a string* before a character that matches the 'mask'.** RETURNS: number of chars up to the mask*/LOCAL int numCharsToMask    (    FAST u_char mask1,    FAST u_char mask2,    u_int size,    FAST u_char *cp    )    {    FAST u_char *end = &cp [size];    u_char *start = cp;    while ((cp < end) && (*cp != mask1) && (*cp != mask2))    	cp++;    return (cp - start);    }/********************************************************************************* slLoanFree - return the given buffer to loaner pool** This routine returns <pRxBuf> to the pool of available loaner buffers.* It also returns <pRef> to the pool of available loaner reference counters,* then zeroes the reference count.** RETURNS: N/A*/ LOCAL void slLoanFree    (    SL_SOFTC *sc,    char *pRxBuf,    UINT8 *pRef    )    {    /* return loaned buffer to pool */    sc->sc_lPool[sc->sc_nLoanRxBuf] = pRxBuf;     /* return loaned reference count to pool */     sc->sc_pRefC[sc->sc_nLoanRxBuf++] = pRef;     /* reset reference count - should have been done from above, but... */     *pRef = 0;    }/********************************************************************************* slRtRequest - perform special routing.** This function performs special processing when adding a route to itself* on a slip interface. It intializes the interface pointer to the loop back* so that the packet can be rerouted through the loopback instead of actually* sending the packet out on the wire and have the other end loop back the* packet. The capability can be turned off by intializing the global flag* slipLoopBack to 0. By default it is turned on. ** NOMANUAL** RETURNS: N/A*/static void slRtRequest    (    int 		cmd,		/* route command */    struct rtentry * 	pRtEntry,	/* pointer to the route entry */    struct sockaddr * 	pSockAddr	/* pointer to the sock addr */    )    {    /* only when adding a route to itself */    if (cmd == RTM_ADD)        {        if (slipLoopBack && (pRtEntry->rt_flags & RTF_HOST) &&            (SIN(rt_key(pRtEntry))->sin_addr.s_addr ==             (IA_SIN(pRtEntry->rt_ifa))->sin_addr.s_addr))            {            pRtEntry->rt_rmx.rmx_expire = 0;            pRtEntry->rt_ifp = &loif;	/* initialize to the loop back */             }        }    }

⌨️ 快捷键说明

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