Check for SYS/GL during library init. Reason is that
[AROS.git] / workbench / devs / networks / ppp / ppp.c
blobaf231442dd51a6e2eabf23306c6b9f0cb443841e
1 /*
2 * $Id$
3 */
5 #include "ppp.h"
6 #include "device_protos.h"
8 #define MAXPSIZE 4096
9 #define CONTROL_SEARCH_BEGIN 1
10 #define CONTROL_SKIP_HEADER1 2
11 #define CONTROL_SKIP_HEADER2 3
12 #define CONTROL_READ_DATA 4
14 #define LCP 0xc021
15 #define PAP 0xc023
16 #define IPCP 0x8021
17 #define IP 0x0021
19 #define REQUEST 1
20 #define ACK 2
21 #define NAK 3
22 #define REJECT 4
23 #define TERMINATE_REQUEST 5
24 #define TERMINATE_ACK 6
25 #define PROTOCOL_REJECT 8
26 #define ECHO_REQUEST 9
27 #define ECHO_REPLY 10
28 #define DISCARD_REQUEST 11
30 struct packet {
31 ULONG packetsize;
32 UBYTE header[4];
33 UBYTE data[MAXPSIZE];
36 void init_ppp(LIBBASETYPEPTR LIBBASE);
37 void Set_phase(UBYTE ph);
39 void ProcessPacket(struct packet * p);
40 void SendPPP_Packet(struct packet *);
41 void EscapePacket(struct packet *);
43 void AddChkSum(struct packet * );
45 void AddBytes(struct packet *p,const BYTE *data,const ULONG len);
46 void AddByte(struct packet *p,const BYTE b);
48 void LCP_packet(struct packet *);
49 void SendConfReq();
50 void SendEchoReply(struct packet *);
51 void SendTerminateReq();
52 void SendEchoRequest();
54 void IPCP_Packet(struct packet * );
55 void Send_IPCP_req();
57 void PAP_Packet(struct packet * );
58 void Send_PAP_Req();
60 unsigned char LocalIP[4]={0,0,0,0};
61 unsigned char RemoteIP[4]={0,0,0,0};
62 unsigned char PrimaryDNS[4]={0,0,0,0};
63 unsigned char SecondaryDNS[4]={0,0,0,0};
65 ULONG async_map,mru;
66 int Control=0;
67 int number = 0;
68 UBYTE *username,*password;
70 UBYTE phase;
71 BOOL my_conf_ok;
72 BOOL device_conf_ok;
73 UBYTE authentication;
75 #define TIMEOUT 6
76 #define MAX_TRY 10
78 int trycounter,timer;
80 struct PPPBase *ppp_libbase;
82 BOOL escape;
83 struct packet recdpacket;
85 unsigned long threadid, bytesrecd,byteswritten;
88 unsigned char writestr[200],ctemp;
91 static unsigned short fcstab[256] = {
92 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
93 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
94 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
95 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
96 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
97 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
98 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
99 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
100 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
101 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
102 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
103 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
104 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
105 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
106 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
107 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
108 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
109 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
110 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
111 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
112 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
113 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
114 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
115 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
116 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
117 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
118 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
119 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
120 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
121 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
122 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
123 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
126 #define PPPINITFCS16 0xffff
127 #define PPPGOODFCS16 0xf0b8
128 #define PPP_FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
130 void AddChkSum(struct packet *p){
132 unsigned char *cp;
133 unsigned short fcs;
134 int i;
136 fcs = PPPINITFCS16;
137 fcs = PPP_FCS(fcs, 0xff); // header simulation...
138 fcs = PPP_FCS(fcs, 0x03);
140 cp = p->data;
141 for( i=0 ;i < p->packetsize ; i++ ){
142 fcs = PPP_FCS(fcs, *cp);
143 cp++;
146 fcs = fcs ^ 0xffff;
147 AddByte( p , (fcs & 0x00ff) );
148 AddByte( p ,((fcs >> 8 ) & 0x00ff));
153 void ppp_timer(int dt){
155 // No timeouts in network & dead phases.
156 if( (phase == PPP_PHASE_NETWORK) || (phase == PPP_PHASE_DEAD)) return;
158 timer += dt;
160 if(phase == PPP_PHASE_PROTOCOL_CONF ){ // sometimes IPCP takes a looong time...
161 if( timer > 60 ){
162 bug("PPP Giveup :-(\n");
163 Set_phase( PPP_PHASE_DEAD );
165 return;
168 if( timer < TIMEOUT ) return;
169 timer = 0;
171 if( ++trycounter > MAX_TRY ){
172 bug("PPP Giveup :-(\n");
173 Set_phase( PPP_PHASE_DEAD );
176 bug("PPP Retrying...\n");
177 Set_phase( phase ); // Retry
182 BYTE Phase(){ return phase;}
184 void Set_phase(UBYTE ph){
185 bug("\nPPP PHASE: ");
187 timer = 0;
188 if( phase != ph )trycounter = 0; // first try
190 switch ( ph ){
192 case PPP_PHASE_CONFIGURATION :
193 bug("CONFIGURATION\n");
194 phase = ph;
196 async_map = 0xffffffff;
197 authentication = 0;
198 my_conf_ok = FALSE;
199 device_conf_ok = FALSE;
200 SendConfReq();
202 break;
204 case PPP_PHASE_AUTHENTICATION :
205 bug("AUTHENTICATION\n");
206 phase = ph;
208 if( authentication ){
209 Send_PAP_Req();
210 }else{
211 bug("no authentication configured -> next phase\n");
212 Set_phase( PPP_PHASE_PROTOCOL_CONF );
214 break;
216 case PPP_PHASE_PROTOCOL_CONF :
217 bug("PROTOCOL_CONF\n");
218 phase = ph;
220 my_conf_ok = FALSE;
221 device_conf_ok = FALSE;
223 LocalIP[0]=0;
224 LocalIP[1]=0;
225 LocalIP[2]=0;
226 LocalIP[3]=0;
228 RemoteIP[0]=0;
229 RemoteIP[1]=0;
230 RemoteIP[2]=0;
231 RemoteIP[3]=0;
233 PrimaryDNS[0]=0;
234 PrimaryDNS[1]=0;
235 PrimaryDNS[2]=0;
236 PrimaryDNS[3]=0;
238 SecondaryDNS[0]=0;
239 SecondaryDNS[1]=0;
240 SecondaryDNS[2]=0;
241 SecondaryDNS[3]=0;
243 Send_IPCP_req();
244 break;
246 case PPP_PHASE_NETWORK :
247 bug("NETWORK\n");
248 phase = ph;
250 if( (RemoteIP[0] | RemoteIP[1] | RemoteIP[2] | RemoteIP[3]) == 0 ){
251 bug("\nCould not determine remote IP address !! defaulting to 10.64.64.64\n");
252 RemoteIP[0]=10;
253 RemoteIP[1]=64;
254 RemoteIP[2]=64;
255 RemoteIP[3]=64;
257 memcpy( ppp_libbase->LocalIP , LocalIP , 4 );
258 memcpy( ppp_libbase->RemoteIP , RemoteIP , 4 );
259 memcpy( ppp_libbase->PrimaryDNS , PrimaryDNS , 4 );
260 memcpy( ppp_libbase->SecondaryDNS , SecondaryDNS , 4 );
262 SendEchoRequest();
264 break;
266 case PPP_PHASE_TERMINATE :
267 bug("TERMINATE\n");
268 phase = ph;
269 SendTerminateReq();
270 break;
272 case PPP_PHASE_DEAD :
273 bug("DEAD\n");
274 phase = ph;
275 break;
277 default:
278 bug("ERROR unknown phase:%d\n",ph);
279 break;
285 void init_ppp(LIBBASETYPEPTR LIBBASE){
286 mru = 1500;
287 number=1;
288 Control=CONTROL_SEARCH_BEGIN;
289 escape = FALSE;
290 recdpacket.packetsize = 0;
292 ppp_libbase = LIBBASE;
294 username = LIBBASE->username ;
295 password = LIBBASE->password ;
297 Set_phase( PPP_PHASE_DEAD );
301 void printpacket(struct packet * p){
302 unsigned int i;
303 for( i=0 ;i < p->packetsize ; i++ ) bug("%x,",p->data[i]);
304 bug("\n");
307 void AddBytes(struct packet *p,const BYTE *data,const ULONG len){
309 if( p->packetsize + len >= MAXPSIZE ){
310 bug("\nPPP ERROR:AddBytes MAXPSIZE\n");
311 return;
314 memcpy( &p->data[ p->packetsize ] , data , len);
315 p->packetsize += len;
319 void AddByte(struct packet *p,const BYTE b){
321 if( p->packetsize >= MAXPSIZE ){
322 bug("\nPPP ERROR:AddByte MAXPSIZE\n");
323 return;
325 p->data[p->packetsize] = b;
326 p->packetsize ++;
329 void bytes_received( UBYTE *bytes,ULONG len ){
330 UBYTE c;
331 ULONG lenT=len;
333 while(lenT--){
334 c = *bytes++;
336 // bug("Control=%d c=%d,%c,%x \n",Control,c,c,c);
338 if( c == 0x7e ){ // start/end mark
340 if( Control == CONTROL_READ_DATA ){
341 // bug("stop\n");
342 Control = CONTROL_SEARCH_BEGIN;
343 ProcessPacket(&recdpacket);
344 recdpacket.packetsize = 0;
345 break;
346 }else if( Control == CONTROL_SEARCH_BEGIN ){
347 // bug("start\n");
348 recdpacket.packetsize=0;
349 Control = CONTROL_SKIP_HEADER1;
350 break;
352 bug("PPP control sync error, unexpected start/end mark!\n");
354 }else if( c == 0x7d ){ // next byte is escaped
355 escape = TRUE;
356 break;
359 if( escape ){
360 c ^= 0x20;
361 escape = FALSE;
364 if( Control == CONTROL_READ_DATA ){
365 AddByte(&recdpacket,c);
366 break;
369 else if( Control == CONTROL_SKIP_HEADER1 ){
370 if( c == 0xff ){
371 Control = CONTROL_SKIP_HEADER2;
372 break;
374 bug("PPP control sync error, byte=0x%x, should be 0xff\n",c);
375 Control = CONTROL_SEARCH_BEGIN;
376 break;
379 else if( Control == CONTROL_SKIP_HEADER2 ){
380 if( c == 0x03 ){
381 Control = CONTROL_READ_DATA;
382 }else{
383 bug("PPP control sync error, byte=0x%x, should be 0x03\n",c);
384 Control = CONTROL_SEARCH_BEGIN;
387 }while(0);
392 void ProcessPacket(struct packet * p){
394 unsigned int type;
396 if( p->packetsize < 8 ){
397 bug("Too short PPP packet received\n");
398 return;
401 p->packetsize-=2; // -checksum
403 // bug("ProcessPacket size=%d\n",p->packetsize);
404 // printpacket(p);
406 type = ( p->data[0] << 8 ) | p->data[1];
407 switch ( type ){
409 case LCP:
410 LCP_packet(p);
411 break;
413 case IPCP:
414 IPCP_Packet(p);
415 break;
417 case PAP:
418 PAP_Packet(p);
419 break;
421 case IP:
422 // bug("IP packet received,size %d\n",p->packetsize);
423 if( ( p->packetsize - 2 ) <= 1500 ){
424 Incoming_IP_Packet( ppp_libbase , p->data + 2 , p->packetsize - 2 );
425 }else{
426 bug("OVERSIZE Incoming IP packet !!!!!!!!!!!!!!!!! %d bytes\n",p->packetsize - 2 );
429 break;
431 case 0xc025:
432 bug("Link Quality Report protocol not supported :-(\n");
433 break;
435 case 0x80fd:
436 bug("Compression Control Protocol not supported :-(\n");
437 break;
439 default:
441 bug("Received unknown packet: type=%x\n",type);
442 break;
448 void PAP_Packet(struct packet * f){
449 bug("\nPAP packet size=%d\n",f->packetsize);
450 printpacket(f);
452 switch ( f->data[2] ){
454 case REQUEST:
455 bug("PAP Req Received\n");
456 break;
458 case ACK:
459 bug("PAP Ack Received: PAP authentication succeeded\n");
461 if( phase == PPP_PHASE_AUTHENTICATION ){
462 Set_phase( PPP_PHASE_PROTOCOL_CONF );
465 break;
467 case NAK:
468 bug("PAP Nak received\n");
469 break;
471 case REJECT:
472 bug("PAP Reject received\n");
473 Set_phase( PPP_PHASE_DEAD );
474 break;
476 default:
477 bug("PAP unknown type received\n");
478 break;
483 void Send_PAP_Req(){
485 struct packet p;
486 ULONG i;
488 bug("\nSend PAP req \"%s\",\"%s\"\n",username,password);
489 p.packetsize=0;
490 AddByte( &p , 0xc0 );//PAP
491 AddByte( &p , 0x23 );
492 AddByte( &p , REQUEST ); // req.
493 AddByte( &p , ++number ); // number
494 AddByte( &p , 0x00 ); // size
495 AddByte( &p , 0x00 ); // size <- p.data[5]
497 AddByte( &p , strlen( username ) );
498 for( i=0 ; i < strlen( username ) ; i++ ) AddByte( &p , username[i] );
500 AddByte( &p , strlen( password ) );
501 for( i=0 ; i < strlen( password ) ; i++ ) AddByte( &p , password[i] );
503 p.data[5] = p.packetsize - 2; // size
505 printpacket(&p);
507 AddChkSum(&p);
508 SendPPP_Packet(&p);
511 void Send_response( UWORD type,UBYTE code,UBYTE *ptr,ULONG len,BYTE num){
513 struct packet p;
514 ULONG i;
515 bug("\nsend ");
516 if(type==IPCP){ bug("IPCP "); }else
517 if(type==LCP){ bug("LCP "); }else
518 bug("unknown type 0x%x\n",type);
520 if(code==NAK){ bug("Nak\n"); }else
521 if(code==REJECT){ bug("Reject\n"); }else
522 bug("unknown code 0x%x\n",code);
524 p.packetsize=0;
525 AddByte( &p , type >> 8 );
526 AddByte( &p , type & 0x00ff );
527 AddByte( &p , code);
528 AddByte( &p , num ); // number
529 AddByte( &p , 0x00 ); // size
530 AddByte( &p , 0x00 ); // <- data[5]
532 for( i=0 ; i<len ;i++ ) AddByte( &p , ptr[i] );
534 p.data[5] = p.packetsize - 2; // size
535 printpacket(&p);
536 AddChkSum(&p);
537 SendPPP_Packet(&p);
540 void Send_Ack(struct packet *p){
541 bug("\nsend Ack\n");
542 p->data[2]=ACK;
543 printpacket(p);
544 AddChkSum(p);
545 SendPPP_Packet(p);
548 void IPCP_Packet(struct packet * p){
549 bug("\nIPCP_Packet size=%d\n",p->packetsize);
550 printpacket(p);
552 ULONG i;
553 UBYTE *ptr = p->data + 6 ;
554 UBYTE type,len;
556 switch ( p->data[2] ){
558 case REQUEST:
560 bug("ipcp Req Received\n");
561 BOOL ok = TRUE;
562 ptr = p->data + 6 ;
563 while( (IPTR)ptr < (IPTR)( p->data + p->packetsize ) ){
564 type = ptr[0];
565 len = ptr[1];
566 bug(" Type %d,len %d: ",type,len);
567 for( i=0 ; i < len ; i++ ) bug("%x,",ptr[i]);bug("\n");
569 if( type == 3 ){ // remote IP address
570 RemoteIP[0]=ptr[2];
571 RemoteIP[1]=ptr[3];
572 RemoteIP[2]=ptr[4];
573 RemoteIP[3]=ptr[5];
574 bug("remote IP address is %d.%d.%d.%d\n",RemoteIP[0],RemoteIP[1],
575 RemoteIP[2],RemoteIP[3]);
578 else {
579 bug(" Unknown type %d ,send reject response...\n",type);
580 Send_response( IPCP , REJECT , ptr , len , p->data[3] );
581 ok = FALSE;
582 break;
585 ptr += len;
588 if(ok){
590 Send_Ack(p);
592 device_conf_ok = TRUE;
593 if( ( phase == PPP_PHASE_PROTOCOL_CONF ) && my_conf_ok ){
594 Set_phase( PPP_PHASE_NETWORK );
598 break;
600 case ACK:
602 bug("IPCP Ack Received\n");
603 if( (LocalIP[0] | LocalIP[1] | LocalIP[2] | LocalIP[3]) == 0 ){
604 bug(" LocalIP still 0.0.0.0 -> Resend IPCP_req\n");
605 Send_IPCP_req();
606 }else{
607 my_conf_ok = TRUE;
608 if( phase == PPP_PHASE_PROTOCOL_CONF && device_conf_ok ){
609 Set_phase( PPP_PHASE_NETWORK );
613 break;
615 case NAK:
617 bug("ipcp Nak received\n");
619 ptr = p->data + 6 ;
620 while( (IPTR)ptr < (IPTR)( p->data + p->packetsize ) ){
621 type = ptr[0];
622 len = ptr[1];
623 bug(" Type %d,len %d: ",type,len);
624 for( i=0 ; i < len ; i++ ) bug("%x,",ptr[i]);bug("\n");
626 if( type == 3 ){ // local IP address
627 LocalIP[0]=ptr[2];
628 LocalIP[1]=ptr[3];
629 LocalIP[2]=ptr[4];
630 LocalIP[3]=ptr[5];
631 bug("Local IP address is %d.%d.%d.%d\n",LocalIP[0],LocalIP[1],
632 LocalIP[2],LocalIP[3]);
634 }else if( type == 129 ){ // PrimaryDNS address
635 PrimaryDNS[0]=ptr[2];
636 PrimaryDNS[1]=ptr[3];
637 PrimaryDNS[2]=ptr[4];
638 PrimaryDNS[3]=ptr[5];
639 bug("PrimaryDNS address is %d.%d.%d.%d\n",PrimaryDNS[0],PrimaryDNS[1],
640 PrimaryDNS[2],PrimaryDNS[3]);
641 }else if( type == 131 ){ // SecondaryDNS address
642 SecondaryDNS[0]=ptr[2];
643 SecondaryDNS[1]=ptr[3];
644 SecondaryDNS[2]=ptr[4];
645 SecondaryDNS[3]=ptr[5];
646 bug("SecondaryDNS address is %d.%d.%d.%d\n",SecondaryDNS[0],SecondaryDNS[1],
647 SecondaryDNS[2],SecondaryDNS[3]);
649 else {
650 bug(" Unknown type %d\n",type);
653 ptr += len;
656 Send_IPCP_req();
658 break;
660 case REJECT:
661 bug("IPCP Reject received\n");
662 break;
664 default:
665 bug("unknow IPCP Received:%d\n",p->data[2]);
666 break;
671 void Send_IPCP_req(){
672 struct packet p;
673 bug("\nsend IPCP req\n");
675 Delay(100);
677 p.packetsize=0;
678 AddByte( &p, 0x80 );
679 AddByte( &p, 0x21 );
680 AddByte( &p, REQUEST );
681 AddByte( &p, ++number );
682 AddByte( &p, 0x00 );
683 AddByte( &p, 0x00 ); //size
685 AddByte( &p, 0x03 );
686 AddByte( &p, 0x06 );
687 AddByte( &p,LocalIP[0] );
688 AddByte( &p,LocalIP[1] );
689 AddByte( &p,LocalIP[2] );
690 AddByte( &p,LocalIP[3] );
692 //if( ppp_libbase->enable_dns ){ // ask DNS addresses too...
693 AddByte( &p, 129 );
694 AddByte( &p, 0x06 );
695 AddByte( &p, PrimaryDNS[0] );
696 AddByte( &p, PrimaryDNS[1] );
697 AddByte( &p, PrimaryDNS[2] );
698 AddByte( &p, PrimaryDNS[3] );
700 AddByte( &p, 131 );
701 AddByte( &p, 0x06 );
702 AddByte( &p, SecondaryDNS[0] );
703 AddByte( &p, SecondaryDNS[1] );
704 AddByte( &p, SecondaryDNS[2] );
705 AddByte( &p, SecondaryDNS[3] );
707 p.data[5] = p.packetsize - 2; // size
709 printpacket(&p);
710 AddChkSum(&p);
711 SendPPP_Packet(&p);
715 void LCP_packet(struct packet *p){
717 bug("\nLCP packet size=%d\n",p->packetsize);
718 printpacket(p);
720 ULONG i;
721 UBYTE *ptr ;
722 UBYTE type,len;
724 switch ( p->data[2] ){
726 case REQUEST:
727 bug("LCP Request Received\n");
729 BOOL ok = TRUE;
731 ptr = p->data + 6 ;
732 while( (IPTR)ptr < (IPTR)( p->data + p->packetsize ) ){
733 type = ptr[0];
734 len = ptr[1];
736 bug(" Type %d,len %d: ",type,len);
737 for( i=0 ; i < len ; i++ ) bug("%x,",ptr[i]);bug("\n");
739 if( type == 2 ){ // async control character map
740 async_map = ( ptr[2] << 24) | ( ptr[3] << 16) | ( ptr[4] << 8) | (ptr[5] );
741 bug(" Async_map = %x\n",async_map);
742 }else if( type == 1 ){ // maximum receive unit
743 mru = ( ptr[2] << 8) | (ptr[3] );
744 bug(" MRU = %d\n",mru);
745 // if( mru !=1500 ){ // unlikely
746 // ptr[2] = 0x05;
747 // ptr[3] = 0xdc;
748 // SendConfNak( ptr , len , p->data[3] );
749 // ok = FALSE;
750 // break;
751 // }
754 else if( type == 3 ){ // authentication
755 if( ptr[2] == 0xc0 && ptr[3] == 0x23 ){
756 bug(" Authentication = PAP\n");
757 authentication = 0xc0;
758 }else{
759 ptr[2] = 0xc0; // PAP
760 ptr[3] = 0x23;
761 Send_response( LCP , NAK , ptr , len , p->data[3] );
762 ok = FALSE;
763 break;
766 ptr[2] = 0xc2; // CHAP md5
767 ptr[3] = 0x23;
768 ptr[4] = 0x5;
769 SendConfNak( ptr , 5 , p->data[3] );
770 ok = FALSE;
771 break;
776 else {
777 bug(" Unknown type %d ,send reject response...\n",type);
778 Send_response( LCP , REJECT , ptr , len , p->data[3] );
779 ok = FALSE;
780 break;
783 ptr += len;
786 if(ok){
787 Send_Ack(p);
788 device_conf_ok = TRUE;
791 break;
793 case ACK:
794 bug("LCP Ack Received !\n");
795 my_conf_ok = TRUE;
796 break;
798 case NAK:
799 bug("LCP Nak Received HELP !\n");
800 break;
802 case REJECT:
803 bug("LCP Reject Received HELP !\n");
804 break;
806 case ECHO_REQUEST:
807 bug("LCP ECHO_REQUEST Received\n");
808 SendEchoReply(p);
809 break;
811 case ECHO_REPLY:
812 bug("LCP ECHO_REPLY Received\n");
813 break;
815 case PROTOCOL_REJECT:
816 bug("LCP Protocol-Reject ( %d bytes ) Received WTF!???????\n" , p->packetsize );
817 break;
819 case TERMINATE_REQUEST:
820 bug("LCP Terminate request Received :-(\n");
821 Set_phase( PPP_PHASE_DEAD );
822 break;
824 case TERMINATE_ACK:
825 bug("LCP Terminate Act Received\n");
826 Set_phase( PPP_PHASE_DEAD );
827 break;
829 case DISCARD_REQUEST:
830 bug("LCP Discard-Request Received ????\n");
831 break;
833 case 12:
834 bug("LCP Link-Quality Report Received ????\n");
835 break;
837 default:
838 bug("unknow lcp Received:%d\n",p->data[2]);
839 break;
842 if( phase == PPP_PHASE_CONFIGURATION &&
843 my_conf_ok && device_conf_ok
845 Set_phase( PPP_PHASE_AUTHENTICATION );
850 void SendEchoRequest(){
851 struct packet p;
852 bug("\nsend ECHO_REQUEST\n");
853 p.packetsize=0;
854 AddByte( &p , 0xc0 );//LPC
855 AddByte( &p , 0x21 );
856 AddByte( &p , ECHO_REQUEST );
857 AddByte( &p , ++number ); // number
858 AddByte( &p , 0x00 ); // size
859 AddByte( &p , 0x00 );
860 p.data[5] = p.packetsize - 2; // size
861 printpacket(&p);
862 AddChkSum(&p);
863 SendPPP_Packet(&p);
866 void SendEchoReply(struct packet *p){
867 bug("\nLCP Send Echo Reply \n");
868 p->data[2] = ECHO_REPLY;
869 printpacket(p);
870 AddChkSum(p);
871 SendPPP_Packet(p);
874 void SendConfReq(){
876 struct packet p;
877 bug("\nsend LCP Req\n");
879 p.packetsize=0;
880 AddByte( &p , 0xc0 );//LPC
881 AddByte( &p , 0x21 );
883 AddByte( &p , REQUEST ); // conf req
885 AddByte( &p , ++number ); // number
887 AddByte( &p , 0x00 ); // size
888 AddByte( &p , 0x00 ); // <- data[5]
890 AddByte( &p , 0x01 ); // max receive unit 1500 (default)
891 AddByte( &p , 0x04 );
892 AddByte( &p , 0x05 );
893 AddByte( &p , 0xdc );
895 AddByte( &p , 0x02 ); // async control char map 0000
896 AddByte( &p , 0x06 );
897 AddByte( &p , 0x00 );
898 AddByte( &p , 0x00 );
899 AddByte( &p , 0x00 );
900 AddByte( &p , 0x00 );
902 p.data[5] = p.packetsize - 2; // size
903 printpacket(&p);
904 AddChkSum(&p);
905 SendPPP_Packet(&p);
910 void SendTerminateReq(){
912 struct packet p;
913 bug("\nsend LCP Terminate request \n");
914 p.packetsize=0;
915 AddByte( &p , 0xc0 );//LPC
916 AddByte( &p , 0x21 );
918 AddByte( &p , TERMINATE_REQUEST ); // terminate req
920 AddByte( &p , ++number ); // number
922 AddByte( &p , 0x00 ); // size
923 AddByte( &p , 0x00 ); // <- data[5]
925 p.data[5] = p.packetsize - 2; // size
927 printpacket(&p);
928 AddChkSum(&p);
929 SendPPP_Packet(&p);
935 void send_IP_packet( BYTE *data ,ULONG len ){
937 struct packet p;
938 // bug( "Send IP packet:%d bytes\n" , len );
940 p.packetsize=0;
942 p.header[0] = 0x7e; // escaped header
943 p.header[1] = 0xff;
944 p.header[2] = 0x7d;
945 p.header[3] = 0x23;
947 AddByte( &p , 0x00 ); // IP
948 AddByte( &p , 0x21 );
950 AddBytes( &p , data , len );
952 AddChkSum(&p);
953 EscapePacket(&p);
954 AddByte( &p , 0x7e );
955 SendBYTES( ppp_libbase->ser , p.header , p.packetsize + 4 );
960 void EscapePacket(struct packet * p){
961 struct packet dummy;
962 unsigned int i,j;
964 for(i=0;i<p->packetsize;i++){
965 dummy.data[i]=p->data[i];
967 dummy.packetsize=p->packetsize;
969 for(j=0,i=0;i<dummy.packetsize;i++,j++){
971 if( j >= MAXPSIZE-1 ){
972 bug( "PPP ERROR: EscapePacket MAXPSIZE\n" );
973 p->packetsize = 0;
974 return;
977 if( dummy.data[i] < 32 ){
978 if( async_map & ( 1L << dummy.data[i] ) ){
979 p->data[j]=0x7d;
980 j++;
981 p->data[j]=dummy.data[i]^0x20;
982 }else{
983 p->data[j]=dummy.data[i];
985 continue;
988 if( dummy.data[i] == 0x7e || dummy.data[i]== 0x7d ){
989 p->data[j]=0x7d;
990 j++;
991 p->data[j]=dummy.data[i]^0x20;
992 continue;
995 p->data[j]=dummy.data[i];
997 p->packetsize=j;
1001 void SendPPP_Packet(struct packet * p){
1003 // bug("SendPPP_Packet size=%d\n",p->packetsize);
1004 //printpacket(p);
1006 p->header[0] = 0x7e; // escaped header
1007 p->header[1] = 0xff;
1008 p->header[2] = 0x7d;
1009 p->header[3] = 0x23;
1011 EscapePacket(p);
1012 AddByte( p , 0x7e );// end mark
1014 DoBYTES( ppp_libbase->ser , p->header , p->packetsize + 4 ); // 4 = header size