async.c

来自「PPPoE协议在Psos中的实现源代码」· C语言 代码 · 共 480 行 · 第 1/2 页

C
480
字号
    switch (etype)
    {
    	case ETH_PPPOE_DISCOVERY:
    	{    switch(pppoehdr->code) 
    	     {
    	     	 case CODE_PADO: 
    	     	      recvPADO(&Connection, (u_char *) CurRecvPkt, (int) count);
    	     	      pfree(CurRecvPkt);
                      break;
    	     	 case CODE_PADS: 
    	     	      recvPADS(&Connection, (u_char *) CurRecvPkt, (int) count);
    	     	      pfree(CurRecvPkt);
                      break;
    	     	 case CODE_PADT:
    	     	      recvPADT(&Connection, (u_char *) CurRecvPkt, (int) count);
    	     	      pfree(CurRecvPkt);
    	     	      break;
    	     	 default:
    	     	      ccb->mibstat.inunknownprotos++;
                      syslog(LOG_ERR, "Received unknown discovery code: %x\n", pppoehdr->code);
                      goto error;
    	     }	
    	     break;
        }	     
    	case ETH_PPPOE_SESSION:
    	{    
    	     if (ntohs(pppoehdr->length) + 20 > count) {
	         syslog(LOG_ERR, "error PPPoE length field (%u)",(unsigned int) ntohs(pppoehdr->length));
	         goto error;
             }
    
             if (pppoehdr->ver != 1) {
	         syslog(LOG_ERR, "Unexpected packet version %d", (int) pppoehdr->ver);
	         goto error;
             }
             
             if (pppoehdr->type != 1) {
	         syslog(LOG_ERR, "Unexpected packet type %d", (int) pppoehdr->type);
	         goto error;
             }
    
    	     if (pppoehdr->code != CODE_SESS) {
	         syslog(LOG_ERR, "Unexpected packet session code %d", (int) pppoehdr->code);
	         goto error;
             }
             
             if ( ntohs(pppoehdr->session) != Connection.session ) {
	         syslog(LOG_ERR, "Unexpected packet session id %d", (int) ntohs(pppoehdr->session));
	         goto error;
             }
             
             proto = ntohs(pppoehdr->protocol);
             switch(proto)
             {
                    case PPP_IP:
                         ip_input((u_char *)CurRecvPkt+22, (u_long) count-22, CurRecvPkt, unit);
                         break;
                    case PPP_VJC_UNCOMP:
                    case PPP_VJC_COMP:
                    {
                         u_char *cp = (u_char *)CurRecvPkt+22;
                         u_int type;

                         type = (proto == PPP_VJC_COMP) ? TYPE_COMPRESSED_TCP :
                                             TYPE_UNCOMPRESSED_TCP;
                         len = sl_uncompress_tcp(&cp, (int) count-22, type, &pc->pci_comp);
                         if ((len <= 0) || (len > BUFSIZE+6))
                         {
                              ccb->mibstat.inerrors++;
                              goto error;
                         }
                         else ip_input(cp, (u_long) len, CurRecvPkt, unit);
                         break;
                    }
                    case PPP_LCP:
                    case PPP_IPCP:
                #if CHAPNEEDED
                    case PPP_CHAP:
                #endif
                #if UPAPNEEDED
                    case PPP_PAP:
                #endif
                    {

                         /*----------------------------------------------------------------*/
                         /* First send an event to the calling task, then send a message.  */
                         /*----------------------------------------------------------------*/
                         (*prottbl[pindex(proto)].input)((int)unit, (u_char *) CurRecvPkt+22, (int) count-22);
                         (*prottbl[pindex(proto)].printpkt)((u_char *) CurRecvPkt+22,(int) count-22, (void (*)())logprint, 0);
                         pfree(CurRecvPkt);
                         break;
                    }
                    default:
                         ccb->mibstat.inunknownprotos++;
                         syslog(LOG_ERR, "Received unknown protocol: %x\n", proto);
                         goto error;
             } /* inner switch */
        break;     
        }     
        default:
             ccb->mibstat.inunknownprotos++;
             syslog(LOG_ERR, "Received unknown eth type: %x\n", etype);
             goto error;      

    }    
    return;
error:
    pfree(CurRecvPkt);
    return;
}


/************************************************************************/
/* frame_decode: assemble new char into a packet.                       */
/*  INPUTS: u - unit, bp - packet, ch - char, eopp - end of packet      */
/* RETURNS:                                                             */
/* OUTPUTS:                                                             */
/* NOTE(S): 1. asyncmap 2. PPP header decoding: compression, FCS.       */
/************************************************************************/
static u_int frame_decode(int u, mblk_t *m0, char **rcvpkt)
{
    struct ppp_pccb *ccb = &PPPpccb[u];
    mblk_t *m;
    char *bp;
    u_char *cp;
    int count,len;

    /* initialize return buffer to null */
    *rcvpkt = (char *)0;

    if (!(bp = pmalloc(BUFSIZE + 10)))
    {
        syslog(LOG_WARNING, "frame_decode: Out of PPP buffers");
        ccb->mibstat.indiscards++;
        return;
    }

    /* initialize the recieve ppp buffer */
    count = 0;

    for (m = m0; m; m = m->b_cont)
    {

        len = (m->b_wptr - m->b_rptr);
        cp = m->b_rptr;
        while (len--)
        {
            *(bp+count) = *cp++; 
            count++;	
        }
    }        
    /* check for minimum size */
    if (count < sizeof(PPPoEHeader)) {
        ISRLOG(LOG_WARNING, "received a short frame\n");
        goto error;
    }

    /* check if the packet is good */
    if (count > 1514) {
        ccb->mibstat.inerrors++;
        ccb->mibstat.packettoolongs++;
        ISRLOG(LOG_WARNING, "received a long frame\n");
        goto error;
    }
    
    /* return the received buffer */
    *rcvpkt = bp;
    return((u_int)count);

error:
    pfree(bp);
    return(0);
}

/************************************************************************/
/* AsyncDataInd: Indication routine called by the DISI driver to inform */
/*               data arrival                                           */
/*                                                                      */
/************************************************************************/
void AsyncDataInd(Uid uid, mblk_t *mp, unsigned long flags)
{
    int unit = (int)uid;
    struct ppp_pccb *ccb = &PPPpccb[unit];
    unsigned long msg[4];

    /* Data received from serial driver. Send an input event and a
     * message to the PPP daemon 
     */

    msg[0] = MSG_INPUT;
    msg[1] = unit;
    msg[2] = (long)mp;


    if (q_send(Qid, msg))
        goto error;

    /* send input event to the ppd task */
    if (ev_send(Tid, PEV_QEVENT)) {
error:
        pna_freemsg(mp); /*was gs_freemsg JRC*/

        return;
    }

    return;
}



/************************************************************************/
/* frame_encode: encode a packet for ASYNC PPP and return in new buffer */
/*  INPUTS: u - unit;   abp- new buffer;buf- original packet;len - size */
/* RETURNS: none                                                        */
/* OUTPUTS:                                                             */
/* NOTE(S): len == 0 indicates a chain                                  */
/************************************************************************/
static u_int frame_encode(u_long u, char *buf1 , u_char *buf)
{
    unsigned char *np = (u_char *) buf1;
    unsigned char *op;
    int len,count = 0;
    mblk_t *m = (mblk_t *)buf;

    do
    {
        
        len = m->b_wptr - m->b_rptr;
        op = m->b_rptr;
        
        while (len--)
        {            
            *np++ = *op++;
            count++;
        }
    } while (m = m->b_cont);

    return(count);
}

⌨️ 快捷键说明

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