⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ppp_ping.c

📁 基于C51单片机的PPOE协议栈源代码。
💻 C
📖 第 1 页 / 共 2 页
字号:
//  addr1 is used to control the status LED, 0=off, 1=flash, 2=on
//  returns 0 if timeout, returns 1 if wait string is matched
char sendwait(const char *send, const char *wait, unsigned int timeout) {
   addr2=addr3=0;
   for (TIME_SET(0); TIME<timeout; ) {       // loop until time runs out
      if (!addr1) P2&=0xFB;                  // if addr1=0 turn off status LED
      else if (addr1==1) {                   // if addr1=1 flash status LED
         if (TIME&4) P2&=0xFB;               // flash period is 8 x 10ms 
         else P2|=4;
      } else P2|=4;                          // if addr1>1 turn on status LED
      if (serial_rx_ready()) {               // is there an incoming character
         P2|=1;                              // turn on the Rx LED
         addr4 = serial_get();               // get character
         //if (serial_error()) serial_fix();   // clear serial errors
         if (wait[addr2]==addr4) addr2++;    // does char match wait string
         else addr2=0;                       // otherwise reset match pointer
         P2&=0xFE;                           // turn off the Rx LED
         if (!wait[addr2]) return 1;         // finished if string matches
      } else if (send[addr3] && (serial_tx_ready())) {  // if char to send and Tx ready
         if (send[addr3]=='|') {             // if pause character
            if (TIME>100) {                  // has 1 second expired yet?
               TIME_SET(0);                  // if yes clear timer
               addr3++;                      // and point to next character
            }
         } else {
            P2|=2;                           // turn on Tx LED
            TIME_SET(0);                     // clear timer, timeout starts after last char
            serial_send(send[addr3]);        // send the character
            addr3++;                         // point to next char in tx string
         }
         P2&=0xFD;                           // turn off Tx LED
         if (!send[addr3] && !(*wait))
            return 1;                        // done if end of string and no wait string
      }
   }
   return 0;                                 // return with 0 to indicate timeout
}

void flash(void) {                      // flash all LEDs if catastrophic failure
   for (TIME_SET(0);;) {
      if (TIME&8) P2|=0x07;             // flash period is 16 x 10ms
      else P2&=0xF8;
      if (TIME>3000) P2&=0xF7;          // after 30 seconds turn off the power
   }
}

void pulse(unsigned char dat) {         // pulse Status LED with IP address
   TIME_SET(0);
   for(number=0;number<9;) {            // pulse out 8 address bits and a blank
      if (TIME<100) P2&=0xFB;           // turn off Status LED between bits
      else if (number<8) P2|=4;         // start each address bit here
      if (TIME>200 || (!(dat&0x80) && TIME>120)) {    // end of bit?
         TIME_SET(0);                   // yes, then restart timer for next bit
         number++;                      // increment bit counter
         dat<<=1;                       // position address to send next bit
      }
   }
}

// The main loop, login script, PPP state machine, and ping transponder
void main(void) {
   signed int c;                   // serial character received
   unsigned int packet = 0;        // Type of the last received packet, reused as temp
   unsigned char state = 0;        // PPP negotiation state, from dialing=0 to done=6
   unsigned char extended = 0;     // flag if last character was an escape sequence

   timer0_init();
   serial_init();                  // Initalize serial port to 2400 baud format N81
   ENABLE_INT;
   
   TIME_SET(0);
   while (TIME<25);                // 250 millisecond delay to prevent false power up
   P2=8;                           // Turn on the power so user can release power button

   for(number=1;;number++) {       // Redial indefinately every 30 seconds
      if (number==10) P2&=0xF7;    // Turn off power if dialing fails
      addr1=0;                     // Set flag to keep the Status LED off
      if(!sendwait("|+++|\rath\r|atz\r|at&fs11=55\r|atdt","atdt",3000))    // Init modem
         flash();
      addr1=1;                          // Set flag to flash Status LED

      // Modify this line with your ISP phone number 
      //if (sendwait("5551234\r","NNECT",3000)) {
      // I changed to direct connection under windows
      if (sendwait("CLIENT","CLIENTSERVER",3000)) {
         addr1=2;                       // Set flag to keep the Status LED on
         //if (sendwait("",": ",1000)) {  // Wait for user id prompt
         //   if (sendwait("userid\r","word:",200))   // Modify these lines as described
         //      if (sendwait("password\r","tion:",1000))
         //         if (!sendwait("ppp\r","IP address",200))    
         //            // Modify is start PPP command is not ppp or 2
         //            sendwait("2\r","IP address",200);
         //}
         //else {
            if (sendwait("\x7e\xff\x7d\x23\x08\x08\x08\x08","~~",1000)) 
               break;                   // Start PPP
            else
               flash();
         //}
      }
   }

   // State machine loop until successful ping or PPP negotiation timeout
   for (TIME_SET(0);;) {
      if (TIME>7000 || number>20) P2&=0xF7;
      if (serial_rx_ready()) {          // Incoming character?
         P2 ^=1;                        // Turn on Rx LED
         c = serial_get();              // get the character
         //if (serial_error()) serial_fix();   // clear Rx errors
         if (c == 0x7E) {               // start or end of a packet 
            if (rx_ptr && (checksum1==0xF0B8))
               packet = rx_str[2]*256 + rx_str[3]; // if CRC passes accept packet
            extended &= 0x7E;           // clear escape character flag
            rx_ptr = 0;                 // get ready for next packet
            checksum1 = 0xFFFF;         // start new checksum
         } else if (c == 0x7D) {        // if tilde character set escape flag
            extended |= 1;
         } else {
            if (extended&1) {           // if escape flag
               c ^= 0x20;               // recover next character
               extended &= 0xFE;        // clear Rx escape flag
            }
            if (rx_ptr==0 && c!=0xff) rx_str[rx_ptr++] = 0xff; // uncompress PPP header
            if (rx_ptr==1 && c!=3) rx_str[rx_ptr++] = 3;
            if (rx_ptr==2 && (c&1)) rx_str[rx_ptr++] = 0;
            rx_str[rx_ptr++] = c;       // insert character in buffer
            if (rx_ptr>MaxRx) rx_ptr = MaxRx;     // Inc pointer up to end of buffer
            checksum1 = calc(c^checksum1) ^ (checksum1/256); // calculate CRC checksum
         }
         P2&=0xFE;                      // turn off Status LED
      } else if (tx_end && (serial_tx_ready())) { // Data to send and Tx empty?
         P2|=2;                         // turn on Tx LED
         c = tx_str[tx_ptr];            // get character from buffer
         if (tx_ptr==tx_end) {          // was it the last character
            tx_end=0;                   // mark buffer empty
            c='~';                      // send tilde character last
            P2&=0xFD;                   // turn off Tx LED
         } else if (extended&2) {       // sending escape sequence?
            c^=0x20;                    // yes then convert character
            extended &= 0xFD;           // clear Tx escape flag
            tx_ptr++;                   // point to next char
         } else if (c<0x20 || c==0x7D || c==0x7E) { // if escape sequence required?
            extended |= 2;              // set Tx escape flag
            c = 0x7D;                   // send escape character
         } else {
           if (!tx_ptr) c='~';          // send ~ if first character of packet
           tx_ptr++;
         }
         serial_send(c);                // Put character in transmitter
      }

      if (packet == LCP) {
         switch (rx_str[4]) {           // Switch on packet type
            case REQ:
               state &= 0xfd;           // clear remote ready state bit
               if (c=TestOptions(0x00c6)) {  // is option request list OK?
                  if (c>1) {
                     c = ACK;           // ACK packet
                     if (state<3) state |= 2;     // set remote ready state bit
                  } else {
                     rx_str[10]=0xc0;   // else NAK password authentication
                     c = NAK;
                  }
               } else {                 // else REJ bad options
                  c = REJ;
               }
               TIME_SET(0);
               MakePacket(LCP,c,rx_str[5],rx_str+7); // create LCP packet from Rx buffer
               break;
            case ACK:
               if (rx_str[5]!=number) break; // does reply id match the rrquest
               if (state<3) state |= 1;      // Set the local ready flag
               break;
            case NAK:
               state &= 0xfe;           // Clear the local ready flag
               break;
            case REJ:
               state &= 0xfe;           // Clear the local ready flag
               break;
            case TERM:
               break;
         }
         if (state==3) state = 4;       // When both ends ready, go to state 4
      } else if (packet == PAP) {
         switch (rx_str[4]) {           // Switch on packet type
            case REQ:                   
               break;                   // Ignore incoming PAP REQ
            case ACK:
               state = 5;               // PAP ack means this state is done
               break;
            case NAK:
               break;                   // Ignore incoming PAP NAK
         }
      } else if (packet == IPCP) {
         switch (rx_str[4]) {           // Switch on packet type
            case REQ:
               if (TestOptions(0x0004)) {    // move to next state on ACK
                  c = ACK;
                  state = 6;
               } else {                 // otherwise reject bad options
                  c = REJ;
               }
               MakePacket(IPCP,c,rx_str[5],rx_str+7);
               break;                   // Create IPCP packet from Rx buffer
            case ACK:
               if (rx_str[5]==number) { // If IPCP response id matches request id
                  state = 7;            // Move into final state
                  pulse(addr1);         // Pulse Status LED to show the 
                  pulse(addr2);         // IP address
                  pulse(addr3);
                  pulse(addr4);
                  P2|=4;                // Turn on Status LED after pulsing
                  TIME_SET(5800);       // Move timer ahead for quicker PING
               }
               break;
            case NAK:                   // This is where we get our address
               addr1 = rx_str[10];
               addr2 = rx_str[11];      // Store address for use in IP packets 
               addr3 = rx_str[12];
               addr4 = rx_str[13];
               MakePacket(IPCP,REQ,rx_str[5],rx_str+7);
               break;                   // Make IPCP packet from Rx buffer
            case REJ:
               break;                   // Ignore incoming IPCP REJ
            case TERM:
               break;                   // Ignore incoming IPCP TERM
         }
      } else if (packet == IP) {
         if (state<7 || (rx_str[19]==addr4 && rx_str[18]==addr3 && 
                         rx_str[17]==addr2 && rx_str[16]==addr1)) {
                    // ignore echoed packets from our address or before we reach state 7
                    // may power down here because echos are good indications that modem
                    // connection hungup
                    // This would be a good place to insert a traceroute test and 
                    // response
         } else if (rx_str[13]==1) {         // IP packet with ICMP payload
            if (rx_str[24]==8) {             // Received PING request
               rx_str[20]=rx_str[16];        // Copy 4 origin address bytes to
                                             // destination address
               rx_str[21]=rx_str[17];
               rx_str[22]=rx_str[18];
               rx_str[23]=rx_str[19];
               rx_str[19]=16;                // Length of IP address(4) + ping protocol(8) + 4
               rx_str[24]=0;                 // Change received ping request(8) to ping reply(0)
               packet = rx_str[28]+rx_str[30];    // Calculate 1's comp checksum
               rx_str[26] = packet&255;
               rx_str[27] = packet/256;
               packet = rx_str[27]+rx_str[29]+rx_str[31];
               rx_str[27] = packet&255;
               packet = packet/256 + rx_str[26];
               rx_str[26] = packet&255;
               rx_str[27] += packet/256;
               rx_str[26] = ~rx_str[26];     // Invert the checksum bits
               rx_str[27] = ~rx_str[27];
               MakePacket(IP,0,1,rx_str+19); // Make IP packet from modified Rx buffer
            } else if (rx_str[24]==0) {      // Received PING reply
               if ((rx_str[28]|rx_str[30]|rx_str[31])+rx_str[29]==1) {
                  P2&=0xF7;                  // Turn off the power after successful ping
               }
            }
         }
      } else if (packet == CCP) {
         switch (rx_str[4]) {                // If CCP response id matches request id
            case REQ:
               c = REJ;
               if (TestOptions(0x0004)) c = ACK; // ACK option 3 only, REJ anything else
               MakePacket(CCP,c,rx_str[5],rx_str+7);   // Create CCP ACK or REJ packet
                                             // from Rx buffer
         }
      } else if (packet) {                   // Ignore any other received packet types
      } else if (!tx_end && (state==0 || state==2) && TIME>100) { 
                                             // Once a second try negotiating LCP
         number++;                           // Increment Id to make packets unique
         TIME_SET(0);                        // Reset timer
         MakePacket(LCP,REQ,number,"\x0E\x02\x06\x00\x0A\x00\x00\x07\x02\x08\x02"); 
                                             // Reqest LCP options 2,7,8
      } else if (!tx_end && state == 4 && TIME>100) {  
                                             // Once a second try negotiating password
         TIME_SET(0);                        // Reset timer
         number++;
         // format like printf("%c%c%s%c%s",strlen(name)+strlen(password)+6,
         //strlen(name),name,strlen(password),password);
         // Modify this line as described above
         MakePacket(PAP,REQ,number,"\x14\x06userid\x08password"); 
      } else if (!tx_end && state == 6 && TIME>100) {
                                             // Once a second try negotiating IPCP
         number++;                           // Increment Id to make packets unique
         TIME_SET(0);                        // Reset timer
         MakePacket(IPCP,REQ,number,"\xA\x3\x6\x0\x0\x0\x0");
                                             // Request IPCP option 3 with addr 0.0.0.0
      } else if (!tx_end && state == 7 && TIME>3000) { // Every 30 seconds do a ping
         TIME_SET(0);                        // Reset timer
         number++;                           // Increment ping count
         MakePacket(IP,0,1,"\x10\xCF\xA1\x75\x43\x8\x0\xF7\xFE\x0\x1\x0\x0"); 
                                             // Ping 207.161.117.67
      }
      packet = 0;                            // Indicate that packet is processed
   }
}


⌨️ 快捷键说明

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