📄 pppchar.c
字号:
if (pkt->nb_plen < (PPP_HDRLEN + PPP_FCS_LEN))
{
if(pkt->nb_plen)
{
// ConPrintf("ppp_inchar: ppp:%p short pkt (%d)\n", mppp, pkt->nb_plen);
mppp->io_errors++;
pkt->nb_plen = 0;
}
return;
}
/* Fall to here if we have received a complete error free packet.
* unlink packet for inpkt and pass to packet input routine
*/
pkt = mppp->inpkt;
mppp->inpkt = NULL; /* clear inpkt */
/* reset prot pointer to the beginning of the received data after
* the two AC bytes
*/
pkt->nb_prot = pkt->nb_buff + MaxLnh + 2; /* 2 is for A/C bytes */
pkt->nb_plen -= 4; /* ALL_STATIONS + UI + ??? */
pkt->net = mppp->ifp;
#ifdef PPP_MULTILINK
pkt->link = mppp; /* save received link */
#endif
#ifdef LB_XOVER
putq(&ppp_rcvdq, (qp)pkt); /* put pkt in input queue */
SignalPPPDemux(); /* wake demuxer */
#else /* not LB_XOVER */
ppp_inpkt(mppp, pkt);
#endif
return;
}
if (mppp->sc_flags & SC_FLUSH)
{
flushed++;
return;
}
if (c == PPP_ESCAPE)
{
mppp->sc_flags |= SC_ESCAPED;
return;
}
/* If this character value should be escaped (per our asyncmap) then
* assume we have received a control code and punt it.
*/
if ((c < 0x20) && (mppp->my_asyncmap & (1L << c)))
return;
if (mppp->sc_flags & SC_ESCAPED)
{
mppp->sc_flags &= ~SC_ESCAPED;
c ^= PPP_TRANS;
}
/*
* Initialize buffer on first octet received.
* First octet could be address, or protocol when compressing
* address/control bytes away.
* Second octet is control.
* Third octet is first or second (when compressing protocol)
* octet of protocol.
* Fourth octet is second octet of protocol.
*/
if(pkt->nb_plen == 0)
{
mppp->sc_fcs = PPP_INITFCS;
if (c != PPP_ALLSTATIONS)
{
if (mppp->sc_flags & SC_REJ_COMP_AC)
{
//ConPrintf("ppp %p: missing ALLSTATIONS, got 0x%x; flags %x\n",
//mppp, c, mppp->sc_flags);
goto flush;
}
/* Stuff the missing compressed bytes into the inbuf */
*(u_char*)pkt->nb_prot++ = PPP_ALLSTATIONS;
*pkt->nb_prot++ = PPP_UI;
pkt->nb_plen = 2;
}
}
if ((pkt->nb_plen == 1) && (c != PPP_UI))
{
//ConPrintf("ppp %p: missing UI, got 0x%x\n", mppp, c);
goto flush;
}
if ((pkt->nb_plen == 2) && ((c & 1) == 1) )
{
/* RFC1331 says we have to accept a compressed protocol */
*pkt->nb_prot++ = (u_char)0; /* insert the zero that was compressed out */
pkt->nb_plen++;
/* code below will put the lower protocol byte after it */
}
*pkt->nb_prot++ = (u_char)c;
pkt->nb_plen++;
mppp->sc_fcs = PPP_FCS(mppp->sc_fcs, c);
return;
flush:
mppp->io_errors++;
mppp->sc_flags |= SC_FLUSH;
/* drop any partially filled data packets. */
if(mppp->inpkt && (mppp->inpkt->nb_plen > 0))
{
LOCK_NET_RESOURCE(FREEQ_RESID);
pk_free(mppp->inpkt);
UNLOCK_NET_RESOURCE(FREEQ_RESID);
mppp->inpkt = NULL;
}
return;
}
/* FUNCTION: ppp_sendchars()
*
* Send all the bytes in a packet. This includes HDLC stuffing and PPP header
* compression. (Note - not VJ compression).
*
* PARAM1: M_PPP mppp
* PARAM2: PACKET pkt
*
* RETURNS:
*/
int
ppp_sendchars(M_PPP mppp, PACKET pkt)
{
int i;
int err;
u_char c;
u_short protocol;
u_short fcs;
u_short testfcs;
u_char hdlc_hdr[4];
int hdlc_len;
/* first 16 bits of data should be PPP protocl (LCP, IPCP, etc.) Get
* This value so we can make compression decisions.
*/
protocol = ppp_getshort((u_char*)pkt->nb_prot);
/* bump pkt past protocol field */
pkt->nb_prot += 2;
pkt->nb_plen -= 2;
fcs = PPP_INITFCS;
/* Send addess/control (AC). See if we can "compress" it. */
if((!mppp->lcp_gotoptions.neg_accompression) ||
(protocol == PPP_LCP))
{
/* Can't compress AC away; put A/C bytes in hdr buf. */
hdlc_hdr[0] = PPP_ALLSTATIONS;
hdlc_hdr[1] = PPP_UI;
hdlc_len = 2;
}
else
hdlc_len = 0; /* compressed AC bytes away */
if((!mppp->lcp_gotoptions.neg_pcompression) ||
(protocol >= 0x100))
{
/* Can't compress protocol to one byte; need to send high byte too. */
hdlc_hdr[hdlc_len++] = (u_char)(protocol >> 8);
}
/* load low byte of protocol */
hdlc_hdr[hdlc_len++] = (u_char)(protocol & 0xFF);
/* hdlc header is now prepared, prepend it to pkt data */
pkt->nb_prot -= hdlc_len;
pkt->nb_plen += hdlc_len;
#ifdef NPDEBUG
if(pkt->nb_prot < pkt->nb_buff)
panic("pppchar prepend");
#endif
MEMCPY(pkt->nb_prot, hdlc_hdr, hdlc_len);
/* send a PPP flag byte to "reset" the other guy's line state. We test
* The result of each ln_putc call and return if error.
*/
err = mppp->line.ln_putc(&mppp->line, PPP_FLAG);
if(err)
{
//ConPrintf("ppp: ln_putc error %d on link %p\n", err, mppp);
goto ppp_putc_err;
}
/* loop through the chars in the packet buffer, encoding and sending
* as we go.
*/
for(i = 0; i < (int)pkt->nb_plen; i++)
{
c = (u_char)*(pkt->nb_prot + i);
fcs = PPP_FCS(fcs, c); /* Update FCS for each byte */
if (ESCAPE_P(c))
{
mppp->line.ln_putc(&mppp->line, PPP_ESCAPE);
err = mppp->line.ln_putc(&mppp->line, (u_char)(c ^ PPP_TRANS));
}
else /* no escape needed, just send & test */
{
err = mppp->line.ln_putc(&mppp->line, c);
}
if (err)
{
mppp->io_errors++;
goto ppp_putc_err;
}
}
/* End of sending pkt data, Send FCS value. We have to "escape" encode
* these bytes too.
*/
c = (u_char)(~fcs & 0xFF);
if (ESCAPE_P(c))
{
err = mppp->line.ln_putc(&mppp->line, PPP_ESCAPE);
err = mppp->line.ln_putc(&mppp->line, (c ^ PPP_TRANS));
}
else
{
err = mppp->line.ln_putc(&mppp->line, c);
}
testfcs = PPP_FCS(fcs, c);
c = (u_char)((~fcs >> 8) & 0xFF);
if (ESCAPE_P(c))
{
err = mppp->line.ln_putc(&mppp->line, PPP_ESCAPE);
err = mppp->line.ln_putc(&mppp->line, (c ^ PPP_TRANS));
}
else
{
err = mppp->line.ln_putc(&mppp->line, c);
}
testfcs = PPP_FCS(testfcs, c);
#ifdef NPDEBUG /* sanity check our FCS logic */
if (testfcs != PPP_GOODFCS)
;//ConPrintf("fcs not ok ??\n");
#endif
/* send a final PPP flag for end of packet */
mppp->line.ln_putc(&mppp->line, PPP_FLAG);
ppp_putc_err:
LOCK_NET_RESOURCE(FREEQ_RESID);
pk_free(pkt);
UNLOCK_NET_RESOURCE(FREEQ_RESID);
return err;
}
#endif /* PPP_CHARIO - whole file can be ifdeffed out */
#endif /* USE_PPP - whole file can be ifdeffed out */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -