📄 p16_ppp.c
字号:
{
hostip.l = myip.l + 1; // ..give host my IP addr + 1
ipcp_event_handler(EVENT_RCR_ERR); // (for want of anthing else)
if (ipcp_action & SCN)
{ // If OK to NAK, do so
put_byte(IPCP_OPT_ADDR);
put_byte(6);
put_lword(&hostip); // ..with new address as hint
send_ppp(PPP_CFG_NAK, ppp_rxid, 1);
}
}
else // If options OK..
{
ipcp_event_handler(EVENT_RCR_OK);
if (ipcp_action & SCA) // ..and OK to send, do so
{
put_byte(IPCP_OPT_ADDR);
put_byte(6);
put_lword(&hostip);
send_ppp(PPP_CFG_ACK, ppp_rxid, 1);
}
}
}
else if (ppp_code == PPP_CFG_NAK) // If NAK received..
{ // ..and IP address hint..
if (match_byte(IPCP_OPT_ADDR) && match_byte(6))
get_lword(&myip); // ..use it for my address
ipcp_event_handler(EVENT_RCN);
} // Others to state machine..
else if (ppp_code == PPP_TERM_REQ) // ..terminate Request
ipcp_event_handler(EVENT_RTR);
else if (ppp_code == PPP_CFG_ACK) // ..config ACK
ipcp_event_handler(EVENT_RCA);
else if (ppp_code == PPP_TERM_ACK) // ..terminate ACK
ipcp_event_handler(EVENT_RTA);
do_ipcp_actions();
}
/* Handle an IPCP event */
void ipcp_event_handler(BYTE event)
{
BYTE newstate, state;
ppp_pcol = PPP_IPCP;
state = newstate = ipcp_state & 0xf; // Get new state & action
if (state<=PPP_STOPPED || state==PPP_OPENED)
ipcp_reqs = ipcp_terms = 0;
if (state<=PPP_OPENED && event<=EVENT_RXJ_ERR)
{
newstate = lcp_states[event][state];
ipcp_action = lcp_actions[event][state];
if (ipcp_action & SCR) // Send config req?
{
if (ipcp_reqs >= MAX_REQS) // Error if too many requests
{
newstate = lcp_states[EVENT_TO_ERR][state];
ipcp_action = lcp_actions[EVENT_TO_ERR][state];
}
ipcp_reqs++;
}
if (ipcp_action & STR) // Send terminate req?
{
if (ipcp_terms >= MAX_TERMS) // Error if too many requests
{
newstate = lcp_states[EVENT_TO_ERR][state];
ipcp_action = lcp_actions[EVENT_TO_ERR][state];
}
ipcp_terms++;
}
}
#if DEBUG_IPCP
serial_putch(newstate & 0xf);
#endif
if (newstate != XXX)
{
ipcp_state = newstate; // Set new state
}
}
/* Do the IPCP actions (all except config ACK/NAK) */
void do_ipcp_actions(void)
{
ppp_pcol = PPP_IPCP;
if (ipcp_action & SCR) // Send config request?
{
init_txbuff(0);
setpos_txin(PPP_HEADLEN);
put_byte(IPCP_OPT_ADDR);
put_byte(6);
put_lword(&myip);
send_ppp(PPP_CFG_REQ, ++ppp_txid, 1);
} // Send terminate request?
if (ipcp_action & STR)
send_ppp(PPP_TERM_REQ, ppp_txid, 0);
if (ipcp_action & STA) // Send terminate ACK?
send_ppp(PPP_TERM_ACK, ppp_rxid, 0);
if (ipcp_action & SCJ) // Send code reject?
send_ppp(PPP_CODE_REJ, ppp_txid, 0);
if (ipcp_action & IRC) // Init restart count?
ipcp_rest = ipcp_action & STR ? MAX_TERMS : MAX_REQS;
if (ipcp_action & ZRC) // Zero restart count?
ipcp_rest = 0;
}
/* Rx handler for Password Authentication Protocol */
void pap_rx_handler(void)
{
ppp_pcol = PPP_PAP;
if (ppp_code == PPP_CFG_REQ) // Config request?
{ // (incoming authentication)
if (match_data(serverid, strlen(serverid)))
{
send_ppp(PPP_CFG_ACK, ppp_rxid, 0); // ACK if ID and password OK
pap_event_handler(EVENT_RCR_OK);
}
else
{
send_ppp(PPP_CFG_NAK, ppp_rxid, 0); // NAK if wrong
pap_event_handler(EVENT_RCR_ERR);
}
}
else if (ppp_code == PPP_CFG_ACK) // Config ACK, client auth OK
pap_event_handler(EVENT_RCA);
else if (ppp_code == PPP_CFG_NAK) // Config NAK, client auth fail
pap_event_handler(EVENT_RCN);
}
/* Handle an PAP event */
void pap_event_handler(BYTE event)
{
ppp_pcol = PPP_PAP;
init_txbuff(0); // PAP layer up, or timeout?
if (event == EVENT_UP || event==EVENT_TO_OK)
{
if (client_auth) // If client authentication..
{
setpos_txin(PPP_HEADLEN); // ..send ID and password
put_byte(strlen(clientname));
put_ser(clientname);
put_byte(strlen(clientpass));
put_ser(clientpass);
send_ppp(PPP_CFG_REQ, ppp_txid, 1);
}
}
else if (event == EVENT_RCR_OK) // Received config req
server_auth_ok = 1;
else if (event == EVENT_RCA) // ..or config ACK
client_auth_ok = 1;
if ((!client_auth || client_auth_ok) && (!server_auth || server_auth_ok))
{
ipcp_event_handler(EVENT_UP); // If authentication OK
do_ipcp_actions(); // ..start up IPCP
}
}
/* Put a PPP header in the Tx buffer and transmit the frame */
void send_ppp(BYTE code, BYTE id, BYTE withdata)
{
if (withdata)
setpos_txin(0);
else
init_txbuff(0);
put_byte(code);
put_byte(id);
if (withdata)
{
save_txbuff();
put_word(net_txlen);
}
else
put_word(4);
save_txbuff();
transmit();
}
/* Put out a byte using PPP escape codes, update the CRC */
void send_ppp_byte(BYTE b)
{
poll_net();
if (b==PPP_END || b==PPP_ESC || b<0x20)
{
serial_putch(PPP_ESC);
poll_net();
serial_putch(b ^ 0x20);
}
else
serial_putch(b);
poll_net();
txcrc = ppp_crc16(txcrc, b);
}
/* Transmit the PPP frame */
void transmit(void)
{
WORD n;
BYTE hi, lo;
txcrc = 0xffff;
serial_putch(PPP_END); // Start flag
send_ppp_byte(0xff); // HDLC address
send_ppp_byte(3); // ..and control byte
send_ppp_byte((BYTE)(ppp_pcol >> 8)); // PPP protocol word
send_ppp_byte((BYTE)ppp_pcol);
#if NET_TXBUFFERS > 1 // If more than 1 Tx buffer
txbuff_lens[txbuffnum] = net_txlen; // ..save Tx length
#endif
for (n=0; n<net_txlen; n++) // Transmit PPP data
#if NET_TXBUFFERS > 1
{
if (txbuffnum)
send_ppp_byte(txbuff2[n]);
else
send_ppp_byte(txbuff[n]);
}
#else
send_ppp_byte(txbuff[n]);
#endif
hi = ~ (BYTE)(txcrc >> 8); // Append CRC
lo = ~ (BYTE)txcrc;
send_ppp_byte(lo);
send_ppp_byte(hi);
serial_putch(PPP_END); // End flag
}
#if NET_TXBUFFERS > 1
/* Retransmit the Ethernet frame */
void retransmit(BYTE buffnum)
{
txbuffnum = buffnum;
net_txlen = txbuff_lens[txbuffnum];
transmit();
}
#endif
/* Poll the serial interface for Rx and Tx characters */
void poll_net(void)
{
BYTE b, saver=1;
static BYTE lastb=0, pluscount=0;
static WORD crc;
if (serial_kbhit()) // Incoming serial byte?
{
b = serial_getch();
if (lastb == PPP_ESC) // Last char was Escape?
{
lastb = 0;
b ^= 0x20;
}
else if (b == PPP_ESC) // This char is Escape?
{
lastb = PPP_ESC;
saver = 0;
}
else if (b == PPP_END) // No escape; maybe End?
{
if (inframe) // If currently in a frame..
{ // Check CRC & save length
if (crc==0xf0b8 && rxbuffin>2)
net_rxin = rxbuffin - 2;
inframe = saver = 0;
}
else
saver = 0;
rxbuffin = 0;
}
if (!inframe) // If not in PPP frame..
{
if (b == PPP_START) // ..check for start of frame
{
crc = 0xffff;
rxbuffin = 0;
inframe = 1;
}
else if (b=='\r' || b=='\n') // ..or control char
{
mdm_rxin = rxbuffin;
saver = rxbuffin = pluscount = 0;
} // ..or 'CONNECT'
else if (rxbuff[0]== 'C' && rxbuffin==5 && b=='T')
{
mdm_rxin = rxbuffin;
saver = rxbuffin = pluscount = 0;
}
else if (b=='+') // ..or '+++'
{
if (++pluscount >= 3)
{
mdm_rxin = rxbuffin;
saver = rxbuffin = pluscount = 0;
}
}
else
pluscount = 0;
}
if (saver) // If saving the new byte
{
if (inframe)
crc = ppp_crc16(crc, b); // ..do CRC as well
if (rxbuffin < RXBUFFLEN)
{
rxbuff[rxbuffin] = b;
rxbuffin++;
}
}
}
}
/* Return new PPP CRC value, given previous CRC value and new byte */
WORD ppp_crc16(WORD crc, BYTE b)
{
BYTE i;
for (i=0; i<8; i++)
{
if ((crc ^ b) & 1)
crc = (crc >> 1) ^ 0x8408;
else
crc >>= 1;
b >>= 1;
}
return(crc);
}
/* EOF */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -