📄 ppp_ping.c
字号:
///////////////////////////////////////////////////////////////////////////////////////
//
// PING.C version 1.10 July 29/99 (C)opyright by Microchip Technology Inc
//
// Modified by ZeRoN, 2003.01.23
// for KEIL C51 Compiler, uVision1, C51 v5.1
//
// - used P2 for PORTB, Status LEDs
//
///////////////////////////////////////////////////////////////////////////////////////
//
// For more documentation read the Microchip Application Note 724
// This code is ready to compile with the HiTech C compiler demo for the PIC16C63A.
//
// You will need these additional things to make this code work:
//
// - the simple hardware described in application note
//
// - an Internet account with PPP dialup access (not compatible with all ISPs)
//
// - replace 5551234 with your ISP's phone number in the line like this
// if (sendwait("5551234\r","NNECT",3000)) {
//
// - replace userid with your account userid in the line like this:
// if (sendwait("userid\r","word:",200))
//
// - replace password with your account password in the line like this:
// if (sendwait("password\r","tion:",1000))
//
// - replace the entire string in the line like this:
// MakePacket(PAP,REQ,number,"\x14\x06userid\x08password");
//
// C converts the \x## in the string to a character with that ASCII value
// ## is a hexadecimal value, so the following character cannot be
// if the next character is 0-9 or A-F or a-f then it will confuse the compiler
// the solution is to convert the next characters to \x## until a non hex char
// if in doubt look at the assembly output from the compiler
// or try MakePacket(PAP,REQ,number,"\x14\x06" "userid\x08" "password");
// replace the userid with yours and the \x06 with your userid length
// replace the password with yours and the \x08 with your password length
// replace the first value in the string, it must be the string length plus 4
//
// Once login is working you should also change the IP address of the Internet host to ping
// if you can not ping 207.161.117.67 with your PC this code will not work either
// It is CF.A1.75.43, the characters 2 to 5, in the string in the line like this:
// MakePacket(IP,0,1,"\x10\xCF\xA1\x75\x43\x8\x0\xF7\xFE\x0\x1\x0\x0");
// Convert the address you want to hexadecimal and replace the four values.
//
// Make sure the power-on reset and brownout detect config bits are enabled
//
///////////////////////////////////////////////////////////////////////////////////////
//-------------------------------------------------------------------------------------
// My additions portion for P89C51RD2
//-------------------------------------------------------------------------------------
#define __KEIL__
#define CHIP_89C51RD2
typedef unsigned char UCHAR;
typedef unsigned int UINT;
typedef unsigned long ULONG;
#include <stdio.h>
#include <intrins.h>
#include "reg51rd2.h"
// Defines
#define XTALFREQ 11059200
#define TIMERINTERVAL 0.010 /* Timer Interval 10mS. */
#ifdef CHIP_89C51RD2
#define FCYCLE (XTALFREQ/6)
#else
#define FCYCLE (XTALFREQ/12)
#endif
#define TCONST (65536-((UINT)(TIMERINTERVAL*FCYCLE)))
#define HiTCONST (UCHAR)(TCONST/256)
#define LoTCONST (UCHAR)(TCONST%256)
#define TIMER0STOP (TR0=0)
#define TIMER0RUN (TR0=1)
#define GOIDLE (PCON|=1)
#define TIMER_0S 0
#define TIMER_10MS 1
#define TIMER_50MS 5
#define TIMER_100MS 10
#define TIMER_500MS 50
#define TIMER_1S 100
#define TIMER_2S 200
#define SCIBPS57K6 57600
#define SCIBPS19K2 19200
#define SCIBPS4K8 4800
#ifdef CHIP_89C51RD2
#define BRG (XTALFREQ/16)
#else
#define BRG (XTALFREQ/32)
#endif
#define T2BRG57K6 (65536-((UINT)(BRG/SCIBPS57K6)))
#define HiT2BRG57K6 (UCHAR)(T2BRG57K6/256)
#define LoT2BRG57K6 (UCHAR)(T2BRG57K6%256)
#define T2BRG19K2 (65536-((UINT)(BRG/SCIBPS19K2)))
#define HiT2BRG19K2 (UCHAR)(T2BRG19K2/256)
#define LoT2BRG19K2 (UCHAR)(T2BRG19K2%256)
#define T2BRG4K8 (65536-((UINT)(BRG/SCIBPS4K8)))
#define HiT2BRG4K8 (UCHAR)(T2BRG4K8/256)
#define LoT2BRG4K8 (UCHAR)(T2BRG4K8%256)
#define ENABLE_INT (EA=1) /* enable interrupts */
#define DISABLE_INT (EA=0) /* disable interrupts */
//-------------------------------------------------------------------------------------
// Defines for Internet constants
#define REQ 1 // Request options list for PPP negotiations
#define ACK 2 // Acknowledge options list for PPP negotiations
#define NAK 3 // Not acknowledged options list for PPP negotiations
#define REJ 4 // Reject options list for PPP negotiations
#define TERM 5 // Termination packet for LCP to close connection
#define IP 0x0021 // Internet Protocol packet
#define IPCP 0x8021 // Internet Protocol Configure Protocol packet
#define CCP 0x80FD // Compression Configure Protocol packet
#define LCP 0xC021 // Link Configure Protocol packet
#define PAP 0xC023 // Password Authenication Protocol packet
#define MaxRx 46 // Maximum size of receive buffer
#define MaxTx 46 // Maximum size of transmit buffer
unsigned char addr1, addr2, addr3, addr4; // Assigned IP address
unsigned int rx_ptr, tx_ptr, tx_end; // pointers into buffers
unsigned int checksum1, checksum2; // Rx and Tx checksums
unsigned char number; // Unique packet id
#define serial_tx_ready() TI // Transmitter empty
#define serial_send(a) putchar(a) // Transmit char a
#define serial_rx_ready() RI // Receiver full
#define serial_get() getchar() // Receive char
#define serial_error() OERR // USART error
#define serial_fix() {CREN=0;CREN=1;} // Clear error
unsigned int TIME; // 10 millseconds counter
#define TIME_SET(a) TIME=a // Set 10 millisecond counter to value 'a'
idata unsigned char tx_str[MaxRx+1]; // Transmitter buffer
idata unsigned char rx_str[MaxTx+1]; // Receiver buffer
//-------------------------------------------------------------------------------------
// My additions portion for P89C51RD2
//-------------------------------------------------------------------------------------
// Timer0 ISR
void timer0int_isr(void) interrupt 1 using 0 /* USED REGISTERS BANK 0 (NO R0-R7 USED) */
{
TIMER0STOP;
TH0=HiTCONST;
TL0=LoTCONST;
TIMER0RUN;
TIME++; // Increment 10 ms counter
}
void timer0_init(void)
{
TH0=HiTCONST;
TL0=LoTCONST;
TMOD=(TMOD&0xF0)|0x01; /* 16 bits Timer */
ET0=1; /* Timer 0 Interrupt enabled */
TIMER0RUN; /* Timer 0 Started */
}
void serial_init(void)
{
RCAP2H=HiT2BRG57K6;
RCAP2L=LoT2BRG57K6;
PCON=0x00; /* SMOD: SMOD=0 for 1x BuadRate by T1 */
SCON=0x50; /* SCON: mode 1, 8-bit UART, enable rcvr */
T2CON=0x30; /* T2 as Baudrate Generator */
TR2=1; /* TR2: timer 2 run */
TI=1; /* TI: set TI to send first char of UART */
}
//-------------------------------------------------------------------------------------
// Add next character to the CRC checksum for PPP packets
unsigned int calc(unsigned int c) {
char i; // Just a loop index
c &= 0xFF; // Only calculate CRC on low byte
for (i=0;i<8;i++) { // Loop eight times, once for each bit
if (c&1) { // Is bit high?
c /= 2; // Position for next bit
c ^= 0x8408; // Toggle the feedback bits
} else c /= 2; // Just position for next bit
} // This routine would be best optimized in assembly
return c; // Return the 16 bit checksum
}
// Add character to the new packet
void add(unsigned char c) {
checksum2 = calc(c^checksum2) ^ (checksum2/256); // Add CRC from this char to running total
tx_str[tx_ptr] = c; // Store character in the transmit buffer
tx_ptr++; // Point to next empty spot in buffer
}
// Create packet of type, code, length, and data string specified
// packet is the type, like LCP or IP
// code is the LCP type of packet like REQ, not used for IP packets
// num is the packet ID for LCP, or the IP data type for IP packets
// *str is the packet data to be added after the header
// returns the packet as a string in tx_str
void MakePacket(unsigned int packet, unsigned char pcode, unsigned char num, const unsigned char *str) {
unsigned int length; // Just a dual use temp variable
tx_ptr = 1; // Point to second character in transmit buffer
tx_str[0] = ' '; // Set first character to a space for now
checksum2 = 0xFFFF; // Initialize checksum
add(0xFF); // Insert PPP header OxFF
add(3); // Insert PPP header 0x03
add(packet/256); // Insert high byte of protocol field
add(packet&255); // Insert low byte of protocol field
if (packet==IP) { // If Internet Protocol
add(0x45); // Insert header version and length
add(0); // Insert type of service
add(0); // Insert total packet length high byte
add((*str)+12); // Insert total packet length low byte
add(0x88); // Insert identification high byte
add(0x10); // Insert identification low byte
add(0x40); // Insert flags and fragement offset
add(0); // Insert rest of fragment offset
add(127); // Insert time to live countdown
add(num); // insert the protocol field
length = 0x45+0x88+0x40+127+addr1+addr3+str[1]+str[3]; // high byte checksum
packet = *str + 12 + 0x10 + num + addr2 + addr4 + str[2] + str[4];
// low byte checksum
packet += length/256; // make 1's complement
length = (length&255) + packet/256; // by adding low carry to high byte
packet = (packet&255) + length/256; // and adding high carry to low byte
length += packet/256; // fix new adding carries
add(~length); // Insert 1's complement checksum high byte
add(~packet); // Insert 1's complement checksum low byte
add(addr1); // Insert the 4 bytes of this login's IP address
add(addr2);
add(addr3);
add(addr4);
length = *str - 4; // save the number of following data bytes
str++; // point to the first data byte
} else {
add(pcode); // Insert packet type, like REQ or NAK
add(num); // Insert packet ID number
add(0); // Insert most significant byte of length
length = *str - 3; // point to the first data byte
}
while (length) { // copy the whole string into packet
length--; // decrement packet length
add(*str); // add current character to packet
str++; // point to next character
}
length = ~checksum2; // invert the checksum
add(length&255); // Insert checksum msb
add(length/256); // Insert checksum lsb
tx_end=tx_ptr; // Set end of buffer marker to end of packet
tx_ptr = 0; // Point to the beginning of the packet
}
// Test the option list in packet for valid passwords
// option is the 16 bit field, where a high accepts the option one greater than the
// bit #
// returns 2 for LCP NAK, 1 is only correct fields found, and zero means bad options
// return also modifies RX_STR to list unacceptable options if NAK or REJ required
unsigned char TestOptions(unsigned int option){
unsigned int size; // size is length of option string
unsigned ptr1 = 8, // ptr1 points data insert location
ptr2 = 8; // ptr2 points to data origin
char pass = 3; // pass is the return value
size = rx_str[7]+4; // size if length of packet
if (size>MaxRx) size=MaxRx; // truncate packet if larger than buffer
while (ptr1<size) { // scan options in receiver buffer
if (rx_str[ptr1]==3 && rx_str[ptr1+2]!=0x80 && rx_str[2]==0xc2)
pass&=0xfd; // found a CHAP request, mark for NAK
if (!((1<<(rx_str[ptr1]-1))&option))
pass=0; // found illegal options, mark for REJ
ptr1 += rx_str[ptr1+1]; // point to start of next option
}
if (!(pass&2)) { // If marked for NAK or REJ
if (pass&1) { // save state for NAK
option=0xfffb;
}
for (ptr1=8; ptr1<size;) {
if (!((1<<(rx_str[ptr1]-1))&option)) { // if illegal option
for (pass=rx_str[ptr1+1]; ptr1<size && pass; ptr1++) { // move option
rx_str[ptr2]=rx_str[ptr1]; // move current byte to new storage
ptr2++; // increment storage pointer
pass--; // decrement number of characters
}
} else {
ptr1+=rx_str[ptr1+1]; // point to next option
}
}
rx_str[7] = ptr2-4; // save new option string length
pass=0; // restore state for REJ
if (option==0xfffb) pass=1; // restore state for NAK
}
return pass;
}
// Send a string and loop until wait string arrives or it times out
// send is the string to transmit
// wait is the string to wait for
// timeout is in multiples of 10 milliseconds
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -