?? ppp.c
字號:
return 0;
/* If in/out failed or down done */
else if (prevstate == -1 || IS_MODEM_DIALDOWN(netp)) {
if (IS_MODEM_DIALOUT(netp)) {
PPPSIG_DIALOUT_DOWN(netno);
}
else if (IS_MODEM_DIALIN(netp)) {
PPPSIG_DIALIN_DOWN(netno);
}
else if (prevstate == -1) {
PPPSIG_DIALDOWN_DOWN(netno);
}
else {
PPPSIG_DIALDOWN_UP(netno);
}
WAITNOMORE(SIG_WN(netno));
MODEM_DIALIN(netno);
PPPSIG_PPP_DOWN(netno);
return -1;
}
/* If success and active */
else if (IS_MODEM_DIALOUT(netp)) {
PPPSIG_DIALOUT_UP(netno);
pppForceUp(netno);
}
else {
PPPSIG_DIALIN_UP(netno);
#if IDLE_TOUT
/* If success and passive */
netp->hw.idle_time = TimeMS();
#endif
}
}
#if IDLE_TOUT
/* If remote dialed in without starting PPP, hangup after timeout. */
else if ((netconf[netp->confix].flags & DIAL) && IS_MODEM_DIALIN(netp)) {
if (((TimeMS()-netp->hw.idle_time)>>10) > IDLE_TOUT)
goto term;
}
#endif
else
return -1;
return 0;
#else
return -1;
#endif
}
/* Check for a timeout. */
prevstate = netp->state;
ul2 = TOUTMS;
#if TOUT_GROW
ul2 >>= (netp->hw.opt7/2);
#endif
if ((ul1 - netp->hw.timems) > ul2) {
if (netp->state == PPPclsng) {
if (netp->hw.opt7 <= 0) {
#if NTRACE >= 3
Nprintf("PPP: Terminate counter expired\n");
Nprintf("PPP: Link closed\n");
#endif
netp->state = PPPclsd;
pppDQ(netno);
PPPSIG_LCP_DOWN(netno);
#if DIALD
if ((netconf[netp->confix].flags & DIAL) == 0)
#endif
{
PPPSIG_PPP_DOWN(netno);
}
pppForceDown(netno);
return -1;
}
}
else if (netp->hw.opt7 <= 0) {
#if NTRACE >= 3
Nprintf("PPP: Restart counter expired\n");
#endif
term:
pppForceDown(netno);
}
else if ((netp->state & LCPopen) != LCPopen)
netp->state &= ~(LCPtxREQ | LCPrxACK);
else if (netp->hw.opt4 & AUTHhini)
netp->hw.opt4 &= ~AUTHwait;
else if ((netp->state & IPCPopen) != IPCPopen)
netp->state &= ~(IPCPtxREQ | IPCPrxACK);
/* If we can't get a buffer, make timeouts work normally */
if ((mess = Ngetbuf()) == 0) {
netp->state = prevstate;
return 0;
}
netp->hw.timems = ul1;
mess->netno = netno;
pppNegotiate(mess);
mess->id = bALLOC;
Nrelbuf(mess);
}
return 0; /* Link/modem working */
}
/*
** * * * * * *
** writE() External/Internal function to write out a frame
**
** static int writE(int conno, MESS *mess);
**
** PARAMETERS:
** (in) conno A yfnet connection number
** (in/out) mess A pointer to a buffer to write out
**
** RETURNS:
** -1 Cannot queue packet or driver error
** 0 Frame taken care of (queued)
** 1 Frame sent immediately
**
** DESCRIPTION:
** This function will frame and write a buffer.
**
** * * * * * *
*/
static int writE(int conno, MESS *mess)
{
int i1, netno;
unsigned short us1, protoc;
unsigned char *cp;
struct NET *netp;
#if VJ
MESS *mp2;
#endif
netno = mess->netno;
netp = &nets[netno];
(void) conno;
/*
** If PPP is not Open:
** Queue datagram (if configured)
** Force link open
*/
if (netp->state != PPPopen) {
#if DBUFFER
if (!QUEUE_FULL(netp, future) && netp->hw.opt8 < DBUFFER_SZ) {
netp->hw.opt8++;
mess->conno = conno;
QUEUE_IN(netp, future, mess);
#if NTRACE >= 5
Nprintf("PPP: Datagram queued for con %d\n", conno);
#endif
}
else {
#if NTRACE
Nprintf("PPP: Queue full, datagram dropped on con %d!\n", conno);
#endif
mess->offset = boTXDONE; /* "Send" the packet */
}
#endif
pppForceUp(netno);
YIELD();
#if MP
/* Find the next companion link to open for Multilink */
if (netp->hw.opt5 & MPmrru)
while (++netno < NNETS)
if (nets[netno].netstat &&
nets[netno].hw.opt5 & MPmrru &&
strcmp(netconf[netp->confix].pname,
netconf[nets[netno].confix].pname) == 0)
{
netconf[nets[netno].confix].Iaddr.l =
netconf[netp->confix].Iaddr.l;
nets[netno].haddr.l = netp->haddr.l;
nets[netno].raddr.l = netp->raddr.l;
pppForceUp(netno);
YIELD();
}
#endif
#if DBUFFER
if (mess->offset == boTXDONE) /* Sent immediately */
return 1;
return 0; /* Queued in--not sent yet */
#else
mess->offset = boTXDONE;
return 1;
#endif
}
/*
** Here is the normal link layer write
** Update idle link time (if configured)
** Compress TCP/IP header (if configured)
** Create the PPP frame
** Add protocol (compressed or uncompressed)
** Encapsulate in Multilink frame (if configured)
** Add address/control for AHDLC (if not compressed)
** Create checksum and append it to the frame
** Transmit frame
*/
#if IDLE_TOUT
netp->hw.idle_time = TimeMS();
#endif
/* Call TCP/IP header compression if wanted. */
if ((protoc = PH(mess)->protocol) == NC2(0x0800)) {
protoc = NC2(PROTip);
#if VJ
if (TXslots[netno]) {
protoc = vjWrite(mess, &mp2);
if (protoc == NC2(PROTcomp))
mess = mp2;
}
#endif
}
/* Point to PPP information field */
cp = (unsigned char *)mess + MESSH_SZ + LHDRSZ;
PH(mess)->MACtype = 0; /* No compression (yet) for WRAP driver */
/* Store protocol code */
*--cp = ((char *)&protoc)[1];
#if (COMPRESSION & 1) == 0
*--cp = *((char *)&protoc);
#else
if (netp->hw.remopts & COMPpcmp && *(char *)&protoc == 0) {
*(cp - 1) = 0;
PH(mess)->MACtype |= 1; /* For WRAP driver */
}
else
*--cp = *((char *)&protoc);
#endif
#if MP
/* For multilink protocol, store MP header and get transmit link number */
if (netp->hw.opt5 & MPmrru) {
mess->netno = mpWrite(netno, &cp);
netp = &nets[mess->netno];
#if COMPRESSION & 1
if (netp->hw.remopts & COMPpcmp)
PH(mess)->MACtype |= 1;
#endif
}
#endif
/* Create async framing */
if (netp->ifType == 23) {
#if COMPRESSION & 1
if (netp->hw.remopts & COMPacmp)
PH(mess)->MACtype |= 2; /* For WRAP driver */
else
#endif
{
*--cp = 0x03; /* Control */
*--cp = 0xff; /* Address */
}
/* Set driver offset */
PH(mess)->poffset = cp - (unsigned char *)mess;
i1 = mess->mlen - PH(mess)->poffset;
/* Calculate and append AHDLC checksum */
us1 = 0xffff;
while (i1--)
us1 = (us1 >> 8) ^ fcstab[(us1 ^ *cp++) & 0xff];
us1 ^= 0xffff;
*cp++ = us1;
*cp = us1 >> 8;
}
#ifdef MIB2
netp->ifOutOctets += mess->mlen - PH(mess)->poffset + 2;
netp->ifOutUcastPkts++;
#endif
us1 = mess->id;
/* Write out the packet by calling the driver */
i1 = netp->protoc[1]->writE(netno, mess);
if (i1 != 0 || us1 <= bWACK)
return i1;
WAITFOR(mess->offset == boTXDONE, SIG_WN(netno), netp->tout, i1);
return 1;
}
/*
** * * * * * *
** comec() Character input interrupt routine
**
** static void comec(int cc, struct NET *netp);
**
** PARAMETERS:
** (in) cc A character to input
** (in/out) netp A pointer to a network structure
**
** RETURNS (not implemented):
** 0 Character processed (do nothing)
** 1 Enable host driver transmit interrupt
** -1 Transmit XOFF
**
** DESCRIPTION:
** This function takes in a HDLC framed character and maps it to a
** data entity in the in buffer.
**
** * * * * * *
*/
static void comec(int cc, struct NET *netp)
{
MESS *mess;
/* If first octet in */
if (netp->hw.bufin == 0) {
/* FLAG (0x7e) should always begin and end a PPP HDLC frame */
if (cc != FLAG && netp->hw.lastin != FLAG)
return;
/* Make buffer to put data from network */
if ((netp->bufbas = NgetbufIR()) == 0)
return;
/* netp->hw.bufin = (char *)&PH(netp->bufbas)->flag; */
netp->hw.bufin = (char *)netp->bufbas + MESSH_SZ + HOFF;
netp->hw.buflim = (char *)netp->bufbas + MAXBUF;
mess = netp->bufbas;
PH(mess)->MACtype = 0;
PH(mess)->poffset = MESSH_SZ + HOFF + 1; /* After flag */
netp->hw.opt3 = 0; /* Start of frame */
if (cc == FLAG) /* First character should be 0x7e */
goto lab4;
*netp->hw.bufin++ = FLAG; /* lastin was flag so now use it */
}
if (netp->hw.lastin == CTL_ESC) { /* Current character is escaped */
cc ^= 0x20; /* Decode character */
netp->hw.lastin = 0;
goto lab3;
}
netp->hw.lastin = cc;
if (cc == CTL_ESC) /* Next character is data */
return;
if (cc == FLAG) { /* End of frame flag found */
mess = netp->bufbas;
mess->mlen = netp->hw.bufin - (char *)mess - 2;
mess->netno = netp->netno;
/* If message size is less than header, an error must have occured */
if (mess->mlen <= MESSH_SZ + LHDRSZ) {
/* Flag must have signaled beginning of frame, not end */
netp->hw.bufin = (char *)netp->bufbas + MESSH_SZ + HOFF;
goto lab4;
}
if (QUEUE_FULL(netp, arrive))
NrelbufIR(mess);
else {
PH(mess)->poffset += PH(mess)->MACtype;
QUEUE_IN(netp, arrive, mess);
}
WAITNOMORE_IR(SIG_RN(netp->netno));
netp->hw.bufin = 0;
return;
}
lab3:
/*
** Check only the first three characters for addr/ctl and protocol.
** If there are any problems, let screen() take care of them.
*/
if (netp->hw.opt3 < 4) {
netp->hw.opt3++;
#if COMPRESSION & 1
/*
** If first byte in is not the address and address/control
** compression is enabled, make a note of it and go on. Tell the
** portion of code that looks for the protocol field that it is here
** (opt3 == 3).
*/
if (netp->hw.locopts & COMPacmp &&
cc != 0xff &&
netp->hw.opt3 == 1)
{
PH(netp->bufbas)->MACtype |= 2; /* Addr/Cntl field compressed */
netp->hw.bufin += 2; /* Skip reading them */
netp->hw.opt3 = 3;
}
/*
** If the third byte is here and is the lower byte of a protocol
** code and protocol compression is enabled, make a note that the
** protocol was copmressed.
*/
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -