Pascal PPP
Pascal
Download (.zip)
{DEFINE DEBUG} {DEFINE SHOWINFO} {DEFINE IPDEBUG} {DEFINE IP2DEBUG} {DEFINE TERMINAL}
Unit PPP;
Interface
Const SEND = 0; RECEIVE = 1;
_dead = 0; _lcp = 1; _ncd = 2; _open = 3;
DEFAULT_PROTOCOL_OFFSET = 3; {I wouldn't change this :)}
IP_Protocol = $0021; {IP Datagram} LCD_Protocol = $C021; {Link Control Data - ref: LCP} NCD_Protocol = $8021; {Network Control Data}
Configure_Request = 1; {Packet Codes} Configure_ACK = 2; Configure_NAK = 3; Configure_Reject = 4; Terminate_Request = 5; Terminate_ACK = 6; Code_Reject = 7; Protocol_Reject = 8; Echo_Request = 9; Echo_Reply = 10; Discard_Request = 11;
Complement = $7D; {next character after Complement nc := nc XOR $32} Flag = $7E; {Start of PPP Packet, End of PPP Packet} Address = $FF; {Address field of PPP packet} Control = $03; {Control field of PPP packet}
Maximum_Receive_Unit = 1; {LCP Configuration Options} Authentication_Protocol = 3; Quality_Protocol = 4; Magic_Number = 5; Protocol_Field_Compression = 7; Address_Control_Field_Compression = 8;
Max_Frame_Size = 16000; Default_Frame_Size = 1500;
Type IPTYPE = array[1..4] of byte; pbyte = ^byte; proc = procedure;
pFrame = ^PPP_Frame; PPP_FRAME = Record Frame_Data : pbyte; Frame_Ptr : pbyte; Frame_Size : word; Frame_Complete : Boolean; Frame_Type : word; Frame_Length : longint; Comp : boolean; Prev,Next : pFrame; end;
pLCPFrame = ^LCP_Frame; LCP_Frame = Record Code : Byte; Identifier : Byte; Length : Word; Data : pbyte; data_ptr : pbyte; datasize : longint; sendorreceive : byte; {send = 0/receive = 1} prev,next : pLCPFrame; end;
pNCDFrame = ^NCD_Frame; NCD_Frame = Record Code : Byte; Identifier : Byte; Length : Word; Data : pbyte; data_ptr : pbyte; datasize : longint; sendorreceive : byte; {send = 0/receive = 1} prev,next : pNCDFrame; end; pIPFrame = ^IP_Frame; IP_Frame = Record Data : pbyte; data_ptr : pbyte; datasize : longint; sendorreceive : byte; {send = 0/receive = 1} prev,next : pIPFrame; end;
PPP_Object = Object Private PIP : Boolean; {Packet in Progress?} r_packetcrc : word;
phase : byte; {0 - dead, 1 - LCP, 2 - NCD, 3 - Open}
vj_hdrc : boolean; maxslotid, compslotid : byte; ipcp : word;
userinit : boolean; initfunc : proc; First_Frame, Last_Frame, Cur_Frame : pFrame;
First_LCP_Frame, Last_LCP_Frame, Cur_LCP_Frame : pLCPFrame;
First_NCD_Frame, Last_NCD_Frame, Cur_NCD_Frame : pNCDFrame;
First_IP_Frame, Last_IP_Frame, Cur_IP_Frame : pIPFrame;
NumIPFrames : word; NumLCPFrames : word; NumNCDFrames : word;
Function B(var frame:pbyte):byte; Function GetChar(var frame:pbyte):char; Function GetByte(var frame:pbyte):byte; Function GetInteger(var frame:pbyte):Integer; Function GetWord(var frame:pbyte):Word; {Function GetLongint(var frame:pbyte):Longint;}
{Procedure NewIPFrame(frame:pFrame);} Procedure DisposeIPFrame(frame:pIPFrame); Function GetIPFrame:pIPFrame;
Procedure NewLCPFrame(frame:pFrame); Procedure DisposeLCPFrame(frame:pLCPFrame); Function GetLCPFrame:pLCPFrame;
Procedure NewNCDFrame(frame:pFrame); Procedure DisposeNCDFrame(frame:pNCDFrame); Function GetNCDFrame:pNCDFrame;
Procedure Request_MRU(var frame:pLCPFrame); Procedure Set_MRU(var frame:pLCPFrame); Procedure Request_PFC(var frame:pLCPFrame);
Procedure ProcessLCPFrame(frame:pLCPFrame); Procedure SendLCPFrame(Code:byte;Identifier:byte; datalength:word;data:pLCPframe); Procedure HandleLCPFrames;
Procedure SendIPFrame(datalength:word;data:pIPframe); Procedure HandleIPFrames;
Procedure Set_IP(var frame:pNCDFrame); Procedure Set_VJ_hdrc(var frame:pNCDFrame);
Procedure ProcessNCDFrame(frame:pNCDFrame); Procedure SendNCDFrame(Code:byte;Identifier:byte; datalength:word;data:pNCDframe); Procedure HandleNCDFrames;
Procedure NewFrame; Procedure AddtoFrame(bte:byte); Procedure EndFrame; Procedure DisposeFrame(frame:pFrame); Procedure SendPPP(protocol:word;data:pointer); Procedure HandleIncoming;
Public use_PFC : boolean; use_ADFC : boolean; IPADDR : IPTYPE; {32-bit int form of Client IP} IPSTRING : string[16]; {000.000.000.000 form of Client IP} Terminate_OK : boolean; {OK to terminate PPP session?} Frame_Size : word; {IP Datagram MAXIMUM Size} protocol_ofs : byte;
Function GetLongint(var frame:pbyte):Longint;
Function MakePtr(var variable):pbyte; Procedure SendLCP(Code:byte; Identifier:byte; datalength:longint;data:pbyte);
Procedure SendNCD(Code:byte; Identifier:byte; datalength:longint;data:pbyte);
Procedure SendIP(datalength:longint;data:pbyte); Function Carrier:boolean; Constructor Init(comport:byte;baudrate:longint;ifunc:proc); {Initializes PPP Packet Driver} Destructor Done; {Destroys PPP Packet Driver} Procedure Terminal; Procedure Dial(username,password,phone,scriptfile:string); Procedure Packet_Driver; Procedure FormatIP (b1,b2,b3,b4:byte; var ipt:iptype); Function IPstr (ip:iptype):string; Function ValidIP (s:string):boolean; Function StoIP(s:string;var IP:iptype):boolean; Function CanWrite:Boolean; end;
Var oPPP : PPP_Object;
Implementation
Uses MODEM, {Interface to Modem} CRT, {used for arbitrary delays} CRC16, {calculates 16-bit CRC's (cyclic redundancy check's)} IP {$IFDEF TERMINAL},vesa,win,global{$ENDIF};
{$IFDEF TERMINAL} var modem_win : longint;
Procedure Modem_Window; var x1,y1,x2,y2 : integer; s : string; Begin if get_handle_dialog(modem_win)<>nil then exit; x1 := maxx shr 1 - 240; y1 := maxy shr 1 - 180; x2 := x1 + 480; y2 := y1 + 360;
modem_win := unique_id; Create_Dialog(modem_win,'Modem Dialog',x1,y1,x2,y2,standard_dialog, close_button+help_button+moveable+modal+minimize_button+maximize_button+sizeable, 0,0,0,0,0,0,0,0,0); Add_ListBox(modem_win,cur_dialog,'',-2,-1,(x2-x1)-4,(y2-y1)-22,unique_id,unique_id,0,nil,0); setactive(modem_win); end;
Procedure MODEMWIN(s:string); var hlb : handle_listbox; Begin if get_handle_listbox(modem_win)=nil then exit; Add_Listbox_Item(get_handle_listbox(modem_win),s,80,0); if cur_dialog=get_handle_dialog(modem_win) then Begin hlb := get_handle_listbox(modem_win); if (hlb^.numitems>hlb^.vert_sb^.curpos+22) then Begin inc(hlb^.vert_sb^.curpos,1); draw_listbox(cur_dialog,hlb,true); end else draw_listbox(cur_dialog,hlb,false); end; end;
Procedure MODEMWIN2(s:string); Begin if get_handle_listbox(modem_win)=nil then exit; Add_Listbox_Item(get_handle_listbox(modem_win),s,80,0); end;
Procedure MODEMWINC(c:char); var s : string; hlb : handle_listbox; Begin hlb := get_handle_listbox(modem_win); if hlb=nil then exit; if c=#10 then exit; if c=#13 then MODEMWIN('') else Begin s := hlb^.last_item^.data.pstr; s := s + c; delete_listbox_item(hlb,hlb^.last_item,false); MODEMWIN2(s); end; end; {$ENDIF}
Function itos(s:byte):string; var t : string; Begin str(s,t); itos := t; end;
Constructor PPP_Object.Init; Begin InitializeAsync; Setparam(comport,baudrate,FALSE,TRUE); {com baud parity 8n1} PIP := false; {Packet in Progress?} vj_hdrc := false; terminate_ok := false; initfunc := ifunc; userinit := false; phase := _dead; use_PFC := false; {use Protocol Field Compression?} use_ADFC := false; {use Address Control Field Compression} fillchar(ipaddr,sizeof(ipaddr),0); ipstring := ''; Frame_Size := Default_Frame_Size; NumIPFrames := 0; NumLCPFrames := 0; NumNCDFrames := 0; protocol_ofs := DEFAULT_PROTOCOL_OFFSET;
First_Frame := nil; Last_Frame := nil; Cur_Frame := nil; First_LCP_Frame := nil; Last_LCP_Frame := nil; Cur_LCP_Frame := nil; First_NCD_Frame := nil; Last_NCD_Frame := nil; Cur_NCD_Frame := nil; First_IP_Frame := nil; Last_IP_Frame := nil; Cur_IP_Frame := nil;
if carrier then Begin SendInit('+++'); delay(1000); sendinit('ATH0'#13); delay(1000); end; end;
Destructor PPP_Object.Done; Begin repeat SendInit('+++'); delay(1000); sendinit('ATH0'#13); delay(1000); until not(carrier) or keypressed; Closeport; while (first_lcp_frame<>nil) do disposelcpframe(first_lcp_frame); while (first_ncd_frame<>nil) do disposencdframe(first_ncd_frame); while (first_ip_frame<>nil) do disposeipframe(first_ip_frame); while (first_frame<>nil) do disposeframe(first_frame) end;
Function PPP_Object.B(var frame:pbyte):byte; Begin if frame<>nil then Begin b := frame^; inc(frame); end else b := 255; end;
Function PPP_Object.GetChar(var frame:pbyte):char; Begin GetChar := chr(b(frame)); end;
Function PPP_Object.GetByte(var frame:pbyte):byte; Begin GetByte := b(frame); end;
Function PPP_Object.GetInteger(var frame:pbyte):Integer; var i : integer; Begin i := b(frame) shl 8; i := i + b(frame); GetInteger := i; end;
Function PPP_Object.GetWord(var frame:pbyte):Word; var i : word; Begin i := b(frame) shl 8; i := i+b(frame); GetWord := i; end;
Function PPP_Object.GetLongint(var frame:pbyte):Longint; var l : longint; Begin l := (getword(frame)*65536)+getword(frame); GetLongint := l; end;
{$I TIMETICK.INC} Function stor(s:string):real; var r : real; e : integer; Procedure strip(var s:string;c:char); begin while pos(c,s)>0 do delete(s,pos(c,s),1); end; Begin strip(s,' '); strip(s,'$'); val(s,r,e); stor := r; end;
Function Waitfor(s:string;t:real) : Boolean; var buf : string; c : char; Begin buf := ''; starttiming; repeat if numchars>0 then Begin c := getchar; buf := buf + c; write(buf[length(buf)]); if length(buf)>length(s) then Begin move(buf[2],buf[1],240); buf[0] := chr(length(s)); end; end; stoptiming; if stor(elapsed)>t then Begin waitfor := false; exit; end; {$IFDEF TERMINAL}dialogmouseroutine;{$ENDIF} until (pos(s,buf)>0); end;
Procedure PPP_Object.Dial(username,password,phone,scriptfile:string); Begin clearreceivebuffer; cleartransmitbuffer; sendinit('AT&F1'#13); delay(250); sendinit('ATM0'#13); delay(250);
sendinit('ATDT'+phone+#13); { repeat handlemouse; until (carrier) or (keypressed); sendinit(#13); waitfor('name>',10);sendinit(username+#13); waitfor('word>',10);sendinit(password+#13); waitfor('Dialz>>>>',10);sendinit('c ppp'#13); waitfor('session',10);} end;
Function PPP_Object.Carrier:boolean; Begin if modem.carrier then carrier := true else carrier := false; end;
Procedure PPP_Object.Terminal; Const PFC : Array[1..4] of byte = (7,2,8,2); var ch : char; Begin {$IFDEF TERMINAL} MODEM_WINDOW; MODEMWIN('Internet Access Port Opened'); MODEMWIN(''); {$ENDIF}
ch := ' '; repeat while numchars>0 do Begin ch := modem.getchar; {if ch in ['a'..'z','A'..'Z','0'..'9',#32,'-','+','!','@','#','$','%','^','&','*','(',')',')','|','\','/','[',']', #10,#13] then write(ch);} {$IFDEF TERMINAL} MODEMWINC(ch);{$ENDIF} ch := ' '; end; if keypressed then Begin ch := readkey; if ch>=#0 then sendchar(ch); end; {$IFDEF TERMINAL}dialogmouseroutine;{$ENDIF} until (ch=#27); phase := _LCP; sendlcp(1,random(256),4,makeptr(PFC)); {$IFDEF TERMINAL} standard_close(true);{close_dialog(get_handle_dialog(modem_win));}{$ENDIF} end;
Procedure PPP_Object.DisposeFrame; Begin; if frame=nil then exit; if frame=first_frame then first_frame := first_frame^.next; if frame=last_frame then last_frame := last_frame^.prev; if frame=cur_frame then cur_frame := cur_frame^.next; if cur_frame=nil then cur_frame := first_frame;
if frame^.prev<>nil then frame^.prev^.next := frame^.next; if frame^.next<>nil then frame^.next^.prev := frame^.prev;
if (frame^.frame_type = IP_Protocol) then dec(NumIPFrames) else if (frame^.frame_type = LCD_Protocol) then dec(NumLCPFrames) else if (frame^.frame_type = NCD_Protocol) then dec(NumNCDFrames);
freemem(frame^.frame_data,frame^.frame_size); dispose(frame); end;
Procedure PPP_Object.SendIPFrame(datalength:word;data:pIPFrame); var lframe : pIPFrame; Begin if datalength=0 then exit; new(lframe); lframe^.sendorreceive := send; if datalength>0 then getmem(lframe^.data,datalength) else lframe^.data := nil; lframe^.datasize := datalength; lframe^.data_ptr := lframe^.data; if datalength>0 then move(data^.data_ptr^,lframe^.data_ptr^,datalength); lframe^.data_ptr := lframe^.data; lframe^.prev := last_IP_frame; cur_ip_frame := lframe; last_ip_frame := lframe; lframe^.next := nil; if first_ip_frame=nil then first_ip_frame := lframe; if lframe^.prev<>nil then lframe^.prev^.next := lframe; end;
Procedure PPP_Object.SendLCPFrame(Code:byte;Identifier:byte; datalength:word;data:pLCPFrame); var lframe : pLCPFrame; Begin new(lframe); lframe^.code := code; lframe^.identifier := identifier; lframe^.length := datalength+4; lframe^.sendorreceive := send; if datalength>0 then getmem(lframe^.data,datalength) else lframe^.data := nil; lframe^.datasize := datalength; lframe^.data_ptr := lframe^.data; if datalength>0 then move(data^.data_ptr^,lframe^.data_ptr^,datalength); lframe^.data_ptr := lframe^.data; lframe^.prev := last_LCP_frame; cur_lcp_frame := lframe; last_lcp_frame := lframe; lframe^.next := nil; if first_lcp_frame=nil then first_lcp_frame := lframe; if lframe^.prev<>nil then lframe^.prev^.next := lframe; end;
Procedure PPP_Object.SendNCDFrame(Code:byte;Identifier:byte; datalength:word;data:pNCDFrame); var lframe : pNCDFrame; Begin new(lframe); lframe^.code := code; lframe^.identifier := identifier; lframe^.length := datalength+4; lframe^.sendorreceive := send; if datalength>0 then getmem(lframe^.data,datalength) else lframe^.data := nil; lframe^.datasize := datalength; lframe^.data_ptr := lframe^.data; if datalength>0 then move(data^.data_ptr^,lframe^.data^,datalength); lframe^.prev := last_NCD_frame; cur_NCD_frame := lframe; last_NCD_frame := lframe; lframe^.next := nil; if first_NCD_frame=nil then first_NCD_frame := lframe; if lframe^.prev<>nil then lframe^.prev^.next := lframe; {$IFDEF SHOWINFO} writeln('---------------[NCD FRAME]-------------'); writeln('Code : ',lframe^.code); writeln('Identifier : ',lframe^.identifier); writeln('Length : ',lframe^.length); writeln('Datasize : ',lframe^.datasize); writeln('-------------[END NCD FRAME]-----------'); {$ENDIF} end;
Procedure PPP_Object.Request_MRU(var frame:pLCPFrame); var fs : word; data : pbyte; begin {$IFDEF DEBUG} writeln('Configure_Request MRU');{$ENDIF} fs := getword(frame^.data_ptr); frame^.data_ptr := frame^.data;
{if (fs<=max_frame_size) then Begin} Frame_Size := fs; {$IFDEF DEBUG} {writeln('MRU : ',frame_size);}{$ENDIF} {SendLCPFrame(Configure_Ack, frame^.identifier, frame^.datasize,frame);} (*end else Begin {$IFDEF DEBUG} writeln('MRU : <NAK>');{$ENDIF} SendLCPFrame(Configure_Nak, frame^.identifier, frame^.datasize,frame); end;*) end;
Procedure PPP_Object.Set_MRU(var frame:pLCPFrame); var fs : word; data : pbyte; begin {$IFDEF DEBUG} writeln('Set MRU ');{$ENDIF} fs := getword(frame^.data_ptr); {frame^.data_ptr := frame^.data;} if (fs<=max_frame_size) then Begin Frame_Size := fs; {$IFDEF DEBUG} writeln('MRU : ',frame_size);{$ENDIF} end; end;
Procedure PPP_Object.Request_PFC(var frame:pLCPFrame); var data : pbyte; Begin frame^.data_ptr := frame^.data; {$IFDEF DEBUG} writeln('Configure_Request PFC : <ACK>');{$ENDIF} SendLCPFrame(Configure_ACK, frame^.identifier, frame^.datasize, frame); use_pfc := true; end;
(*Procedure PPP_Object.ProcessLCPFrame(frame:pLCPFrame); var LCP : Record _type : byte; _length : byte; end; Begin if frame=nil then exit; if (frame^.datasize>=2) then Begin lcp._type := getbyte(frame^.data_ptr); lcp._length := getbyte(frame^.data_ptr); end else fillchar(lcp,2,0); {$IFDEF DEBUG} writeln('ProcessLCPFrame'); writeln('Type : ',lcp._type); writeln('Length : ',lcp._length); {$ENDIF} case (frame^.code) of Configure_Request : case lcp._type of 0 : Begin SendLCPFrame(Configure_Ack,frame^.identifier,frame^.datasize,frame); if not(userinit) then if (addr(initfunc)<>nil) then Begin initfunc; userinit := true; end; phase := _ncd; end; Maximum_Receive_Unit : Request_MRU(frame); {Authentication_Protocol : writeln('Configure_Request Authentication'); Quality_Protocol : writeln('Configure_Request Quality'); Magic_Number : writeln('Configure_Request Magic Number');} Protocol_Field_Compression : Request_PFC(frame); {Address_Control_Field_Compression : writeln('Configure_Request Control Field Compression');} else Begin {$IFDEF DEBUG} writeln('LCP_Configure_Reject : ',lcp._type); {$ENDIF} frame^.data_ptr := frame^.data; SendLCPFrame(Configure_Reject, frame^.identifier, frame^.datasize,frame); end; end; Configure_Ack : case lcp._type of {0 : SendLCPFrame(Configure_ACK,frame^.identifier,0,frame);} Protocol_Field_Compression : use_pfc := true; Maximum_Receive_Unit : Set_MRU(frame); end; {Configure_NAK : ; Configure_Reject : ;} Terminate_Request : Begin Terminate_ok := true; phase := _lcp; SendLCPFrame(Terminate_ACK, frame^.identifier, frame^.datasize,frame); {$IFDEF DEBUG} writeln ('Terminate Request Received'); {$ENDIF} end; Terminate_ACK : Begin phase := _lcp; Terminate_ok := true; {$IFDEF DEBUG} writeln('Terminate ACK Received'); {$ENDIF} end; Code_Reject : ; Protocol_Reject : ; Echo_Request : ; Echo_Reply : ; Discard_Request : ; else SendLCPFrame(CODE_REJECT, frame^.identifier, frame^.datasize,frame); end; if not(userinit) then if (addr(initfunc)<>nil) then Begin initfunc; userinit := true; end; end; *)
Procedure PPP_Object.ProcesslcpFrame(frame:plcpFrame); Const CIP : Array[1..6] of byte = (3,6,0,0,0,0); var cr : byte; LCP: Record _type : byte; _length : byte; end; lcp_nak : pbyte; lcp_ptr : pbyte; pos2 : word; lcp_pos : word; x : word; pl : word; Begin if frame=nil then exit; getmem(lcp_nak,1024); lcp_ptr := lcp_nak; lcp_pos := 0; pos2 :=3; {$IFDEF DEBUG} writeln('lcp Code : ',frame^.code); {$ENDIF}
pl := frame^.length-4; while (pl>0) do Begin {while (frame^.length-2>=pos2) do Begin} {$IFDEF DEBUG} writeln('Packet Length : ',frame^.length); {$ENDIF} lcp._type := getbyte(frame^.data_ptr); lcp._length := getbyte(frame^.data_ptr); dec(pl,2); {$IFDEF DEBUG} writeln('lcp Type : ',lcp._type); writeln(' Length : ',lcp._length); {$ENDIF} case (frame^.code) of Configure_ACK, Configure_Request : case (lcp._type) of Maximum_Receive_Unit : Begin Request_MRU(frame); dec(pl,2); end; Protocol_Field_Compression : Begin use_pfc := true; {inc(pos2,);} {$IFDEF DEBUG} writeln ('[ACK PFC]'); {$ENDIF} end; Address_Control_Field_Compression : Begin use_adfc := true; protocol_ofs := 1; {$IFDEF DEBUG} writeln ('[ACK ADFC]');{$ENDIF} {inc(pos2,2);} end; else Begin lcp_ptr^ := lcp._type; inc(lcp_ptr); inc(lcp_pos); lcp_ptr^ := lcp._length; inc(lcp_ptr); inc(lcp_pos); if lcp._length-2>0 then for x := 1 to (lcp._length-2) do Begin lcp_ptr^ := getbyte(frame^.data_ptr); inc(lcp_ptr); inc(lcp_pos); dec(pl);{inc(pos2);} end; end; end; Configure_NAK, Configure_Reject : Begin Sendlcp(CONFIGURE_REQUEST,random(256),0,nil); freemem(lcp_nak,1024); exit; end; Terminate_ACK : Begin freemem(lcp_nak,1024); terminate_ok := true; exit; end; Terminate_REQUEST : Begin freemem(lcp_nak,1024); terminate_ok := true; sendlcpframe(Terminate_ack,frame^.identifier,frame^.datasize,frame); exit; end;
Echo_Request : Begin freemem(lcp_nak,1024); sendlcpframe(Echo_Reply,frame^.identifier,frame^.datasize,frame); exit; end; Echo_Reply : Begin freemem(lcp_nak,1024); exit; end; Protocol_Reject : Begin {$IFDEF DEBUG} writeln('Protocol Reject!!!!!!'); {$ENDIF} freemem(lcp_nak,1024); exit; end; Code_Reject : Begin {$IFDEF DEBUG} writeln('CODE Reject!!!!!!'); {$ENDIF} freemem(lcp_nak,1024); exit; end; Discard_Request : Begin freemem(lcp_nak,1024); exit; end; else Begin SendlcpFrame(CODE_REJECT, frame^.identifier, frame^.datasize,frame); freemem(lcp_nak,1024); exit; end; end; end;
frame^.data_ptr := frame^.data; if (lcp_pos>0) then Begin freemem(frame^.data,frame^.datasize); getmem(frame^.data,lcp_pos); frame^.datasize := lcp_pos; frame^.data_ptr := frame^.data; lcp_ptr := lcp_nak; for x := 1 to lcp_pos do Begin frame^.data_ptr^ := lcp_ptr^; inc(frame^.data_ptr); inc(lcp_ptr); end; frame^.data_ptr := frame^.data; {$IFDEF DEBUG} writeln('Configure NAK : ',frame^.datasize); {$ENDIF} if frame^.code=CONFIGURE_REQUEST then SendlcpFrame(Configure_NAK, frame^.identifier, frame^.datasize, frame); end else Begin if frame^.code=Configure_REQUEST then Begin {$IFDEF DEBUG} writeln('Configure ACK : ',frame^.datasize); {$ENDIF} sendlcpFrame(Configure_ACK, frame^.identifier, frame^.datasize,frame); end else if frame^.code=Configure_Ack then Begin phase := _NCD; sendncd(Configure_Request,random(256),4,makeptr(CIP)); freemem(lcp_nak,1024); exit; end; end;
freemem(lcp_nak,1024); end;
Function PPP_Object.GetLCPFrame:pLCPFrame; var frame : pFrame; Begin GetLCPFrame := nil; if NumLCPFrames=0 then exit; frame := First_Frame; while frame<>nil do Begin if (frame^.frame_complete) and (frame^.frame_type=LCD_Protocol) then Begin newLCPFrame(frame); disposeframe(frame); GetLCPFrame := cur_LCP_Frame; exit; end; frame := frame^.next; end; end;
Procedure PPP_Object.Set_IP(var frame:pNCDFrame); var x : byte; data : string[16]; begin {$IFDEF DEBUG} writeln('Set IP ');{$ENDIF} for x := 1 to 4 do ipaddr[x] := getbyte(frame^.data_ptr); {frame^.data_ptr := frame^.data;} ipstring := itos(ipaddr[1])+'.'+itos(ipaddr[2])+'.'+itos(ipaddr[3])+'.'+itos(ipaddr[4]); {$IFDEF DEBUG} writeln('IP Address : ',ipstring); {$ENDIF} end;
Procedure PPP_Object.Set_VJ_hdrc(var frame:pNCDFrame); var x : byte; data : string[16]; begin {$IFDEF DEBUG} writeln('Van Jacobson TCP/IP Header Compression <ACK>');{$ENDIF} vj_hdrc := true; ipcp := getword(frame^.data_ptr); maxslotid := getbyte(frame^.data_ptr); compslotid := getbyte(frame^.data_ptr); end;
Procedure PPP_Object.ProcessNCDFrame(frame:pNCDFrame); Const CIP : Array[1..6] of byte = (3,6,0,0,0,0); var NCD : Record _type : byte; _length : byte; end; ncd_nak : pbyte; ncd_ptr : pbyte; ncd_pos : word; x : word; pl : word; Begin { if (phase>_NCD) then phase := _NCD;} {if (phase<_NCD) then exit;} if frame=nil then exit; getmem(ncd_nak,1024); ncd_ptr := ncd_nak; ncd_pos := 0; {$IFDEF DEBUG} writeln('NCD Code : ',frame^.code); {$ENDIF} pl := frame^.length-4; while (pl>0) do Begin {$IFDEF DEBUG} writeln('Packet Length : ',frame^.length); {$ENDIF} NCD._type := getbyte(frame^.data_ptr); NCD._length := getbyte(frame^.data_ptr); dec(pl,2); {$IFDEF DEBUG} writeln('NCD Type : ',NCD._type); writeln(' Length : ',NCD._length); {$ENDIF} case (frame^.code) of Configure_ACK, Configure_Request : case (ncd._type) of {2 : Begin Set_VJ_hdrc(frame); dec(pl,4); end;} 3 : Begin Set_IP(frame); dec(pl,4); end; else Begin ncd_ptr^ := ncd._type; inc(ncd_ptr); inc(ncd_pos); ncd_ptr^ := ncd._length; inc(ncd_ptr); inc(ncd_pos); if ncd._length-2>0 then for x := 1 to (ncd._length-2) do Begin ncd_ptr^ := getbyte(frame^.data_ptr); inc(ncd_ptr); inc(ncd_pos); dec(pl); end; end; end; Configure_NAK : case (ncd._type) of 3 : Begin Set_IP(frame); dec(pl,4); cip[3] := ipAddr[1]; cip[4] := ipAddr[2]; cip[5] := ipAddr[3]; cip[6] := ipAddr[4]; SendNCD(CONFIGURE_REQUEST,random(256),6,makeptr(CIP)); freemem(ncd_nak,1024); exit; end; end; Configure_Reject : Begin phase := _NCD; SendNCD(CONFIGURE_REQUEST,random(256),0,nil); freemem(ncd_nak,1024); exit; end; else Begin SendNCDFrame(CODE_REJECT, frame^.identifier, frame^.datasize,frame); freemem(ncd_nak,1024); exit; end; end; end;
frame^.data_ptr := frame^.data; if (ncd_pos>0) then Begin freemem(frame^.data,frame^.datasize); getmem(frame^.data,ncd_pos); frame^.datasize := ncd_pos; frame^.data_ptr := frame^.data; ncd_ptr := ncd_nak; for x := 1 to ncd_pos do Begin frame^.data_ptr^ := ncd_ptr^; inc(frame^.data_ptr); inc(ncd_ptr); end; frame^.data_ptr := frame^.data; {$IFDEF DEBUG} writeln('Configure NAK : ',frame^.datasize); {$ENDIF} phase := _NCD; {if frame^.code=CONFIGURE_REQUEST then} SendNCDFrame(Configure_NAK, frame^.identifier, frame^.datasize, frame); end else Begin if (frame^.code=Configure_REQUEST) {or (frame^.code=CONFIGURE_NAK)} then Begin {$IFDEF DEBUG} writeln('NCD Configure ACK : ',frame^.datasize,' ',frame^.code); {$ENDIF} phase := _OPEN; sendNCDFrame(Configure_ACK, frame^.identifier, frame^.datasize,frame); end; end;
freemem(ncd_nak,1024); end;
Function PPP_Object.GetNCDFrame:pNCDFrame; var frame : pFrame; Begin GetNCDFrame := nil; if NumNCDFrames=0 then exit; frame := First_Frame; while frame<>nil do Begin if (frame^.frame_complete) and (frame^.frame_type=NCD_Protocol) then Begin newNCDFrame(frame); disposeframe(frame); GetNCDFrame := cur_NCD_Frame; exit; end; frame := frame^.next; end; end;
Function PPP_Object.GetIPFrame:pIPFrame; var frame : pFrame; Begin GetIPFrame := nil; if NumIPFrames=0 then exit; frame := First_Frame; while frame<>nil do Begin if (frame^.frame_complete) and (frame^.frame_type=IP_Protocol) then Begin oIP.AddIPFrame(frame); {$IFDEF SHOWINFO} delay(1000); {$ENDIF} disposeframe(frame); GetIPFrame := cur_IP_Frame; exit; end; frame := frame^.next; end; end;
Procedure PPP_Object.AddtoFrame; Begin if cur_frame=nil then Begin {$IFDEF DEBUG} writeln('[Attemting to Write to a NIL FRAME!]'); {$ENDIF} PIP := false; exit; end; if (bte=complement) and not(cur_frame^.comp) then cur_frame^.comp := true else Begin inc(cur_frame^.frame_ptr); if cur_frame^.comp then Begin bte := bte xor $20; cur_frame^.comp := false; end; cur_frame^.frame_ptr^ := bte; inc(cur_frame^.frame_length); r_packetcrc := updatecrc(r_packetcrc,bte); {$IFDEF SHOWINFO} write(bte:3,'/'); {$ENDIF} end; end;
Procedure PPP_Object.DisposeLCPFrame(frame:pLCPFrame); Begin if frame=nil then exit;
if frame=first_lcp_frame then first_lcp_frame := first_lcp_frame^.next; if frame=last_lcp_frame then last_lcp_frame := last_lcp_frame^.prev; if frame=cur_lcp_frame then cur_lcp_frame := cur_lcp_frame^.next;
if frame^.prev<>nil then frame^.prev^.next := frame^.next; if frame^.next<>nil then frame^.next^.prev := frame^.prev;
if frame^.datasize>0 then freemem(frame^.data,frame^.datasize); dispose(frame); end;
Procedure PPP_Object.DisposeNCDFrame(frame:pNCDFrame); Begin if frame=nil then exit;
if frame=first_ncd_frame then first_ncd_frame := first_ncd_frame^.next; if frame=last_ncd_frame then last_ncd_frame := last_ncd_frame^.prev; if frame=cur_ncd_frame then cur_ncd_frame := cur_ncd_frame^.next;
if frame^.prev<>nil then frame^.prev^.next := frame^.next; if frame^.next<>nil then frame^.next^.prev := frame^.prev;
if frame^.datasize>0 then freemem(frame^.data,frame^.datasize); dispose(frame); end;
Procedure PPP_Object.DisposeIPFrame(frame:pIPFrame); Begin if frame=nil then exit;
if frame=first_ip_frame then first_ip_frame := first_ip_frame^.next; if frame=last_ip_frame then last_ip_frame := last_ip_frame^.prev; if frame=cur_ip_frame then cur_ip_frame := cur_ip_frame^.next;
if frame^.prev<>nil then frame^.prev^.next := frame^.next; if frame^.next<>nil then frame^.next^.prev := frame^.prev;
if frame^.datasize>0 then freemem(frame^.data,frame^.datasize); dispose(frame); end;
Procedure PPP_Object.NewLCPFrame(frame:Pframe); var lframe : pLCPFrame; Begin new(lframe); lframe^.code := getbyte(frame^.frame_ptr); lframe^.identifier := getbyte(frame^.frame_ptr); lframe^.length := getword(frame^.frame_ptr); lframe^.sendorreceive := receive; lframe^.data := nil; if (lframe^.length-4)>0 then Begin getmem(lframe^.data,lframe^.length-4); move(frame^.frame_ptr^,lframe^.data^,lframe^.length-4); end; lframe^.datasize := lframe^.length-4; lframe^.data_ptr := lframe^.data; lframe^.prev := last_LCP_frame; last_lcp_frame := lframe; cur_lcp_frame := lframe; lframe^.next := nil; if first_lcp_frame=nil then first_lcp_frame := lframe; if lframe^.prev<>nil then lframe^.prev^.next := lframe; cur_lcp_frame := lframe; end;
{Procedure PPP_Object.NewIPFrame(frame:Pframe); var lframe : pIPFrame; Begin if frame^.frame_length-(Protocol_ofs+4)<1 then exit; new(lframe); lframe^.datasize := frame^.frame_length-(Protocol_Ofs+4); lframe^.sendorreceive := receive; lframe^.data := nil; getmem(lframe^.data,lframe^.datasize); move(frame^.frame_ptr^,lframe^.data^,lframe^.datasize); lframe^.data_ptr := lframe^.data; lframe^.prev := last_IP_frame; last_ip_frame := lframe; cur_ip_frame := lframe; lframe^.next := nil; if first_ip_frame=nil then first_ip_frame := lframe; if lframe^.prev<>nil then lframe^.prev^.next := lframe; cur_ip_frame := lframe; end; }
Procedure PPP_Object.NewNCDFrame(frame:Pframe); var lframe : pNCDFrame; Begin new(lframe); {if phase<_NCD then phase := _NCD;} lframe^.code := getbyte(frame^.frame_ptr); lframe^.identifier := getbyte(frame^.frame_ptr); lframe^.length := getword(frame^.frame_ptr); lframe^.sendorreceive := receive; lframe^.data := nil; if (lframe^.length-4)>0 then Begin getmem(lframe^.data,lframe^.length-4); move(frame^.frame_ptr^,lframe^.data^,lframe^.length-4); end; lframe^.datasize := lframe^.length-4; lframe^.data_ptr := lframe^.data; lframe^.prev := last_NCD_frame; last_ncd_frame := lframe; cur_ncd_frame := lframe; lframe^.next := nil; if first_ncd_frame=nil then first_ncd_frame := lframe; if lframe^.prev<>nil then lframe^.prev^.next := lframe; cur_ncd_frame := lframe; end;
Procedure PPP_Object.HandleLCPFrames; var frame : pLCPFrame; x : word; Begin {if (phase<_LCP) then exit;} frame := First_LCP_Frame; while (frame<>nil) do Begin if (frame^.sendorreceive=send) then Begin SendPPP(LCD_Protocol,frame); DisposeLCPFrame(frame); exit; end else Begin ProcessLCPFrame(frame); DisposeLCPFrame(frame); exit; end; frame := frame^.next; end; end;
Procedure PPP_Object.HandleIPFrames; var frame : pIPFrame; x : word; Begin {if (phase<_OPEN) then exit;} frame := First_IP_Frame; while (frame<>nil) do Begin if (frame^.sendorreceive=send) then Begin SendPPP(IP_Protocol,frame); DisposeIPFrame(frame); exit; end; frame := frame^.next; end; end;
Procedure PPP_Object.HandleNCDFrames; var frame : pNCDFrame; x : word; Begin {if (phase<_NCD) then exit;} frame := First_NCD_Frame; while (frame<>nil) do Begin if (frame^.sendorreceive=send) then Begin SendPPP(NCD_Protocol,frame); DisposeNCDFrame(frame); exit; end else Begin ProcessNCDFrame(frame); DisposeNCDFrame(frame); exit; end; frame := frame^.next; end; end;
Procedure PPP_Object.NewFrame; var frame : pFrame; Begin pip := true; r_packetcrc := $ffff; new(frame); frame^.frame_complete := false; frame^.frame_size := Frame_Size; frame^.frame_type := 0; frame^.frame_length := 0; frame^.comp := false; getmem(frame^.frame_data,frame^.frame_size); frame^.frame_ptr := frame^.frame_data; frame^.frame_ptr^ := Flag; frame^.prev := last_frame; last_frame := frame; cur_frame := frame; frame^.next := nil; if first_frame=nil then first_frame := frame; if cur_frame=nil then cur_frame := frame; if frame^.prev<>nil then frame^.prev^.next := frame; {$IFDEF SHOWINFO} writeln;writeln('[FRAME]'); {$ENDIF} end;
Procedure PPP_Object.EndFrame; var pfc : word; b1,b2 : byte;
Begin pip := false; inc(Cur_Frame^.frame_ptr); Cur_frame^.frame_ptr^ := Flag; cur_frame^.frame_complete := true; {$IFDEF SHOWINFO} writeln;{$ENDIF}
if not(r_packetcrc=$f0b8) then Begin disposeframe(cur_frame); {$IFDEF DEBUG} writeln('Invalid CRC in Packet!'); {$ENDIF} end else Begin cur_frame^.frame_ptr := cur_frame^.frame_data; inc(cur_frame^.frame_ptr,protocol_ofs); if (use_pfc) then Begin b1 := getbyte(cur_frame^.frame_ptr); b2 := getbyte(cur_frame^.frame_ptr); if (b1=address) and (b2=control) then Begin b1 := getbyte(cur_frame^.frame_ptr); b2 := getbyte(cur_frame^.frame_ptr); end; if (b1 and 1)=1 then Begin {$IFDEF SHOWINFO} writeln('[CPF Frame Received!]');{$ENDIF} cur_frame^.frame_type := b1; dec(cur_frame^.frame_ptr); end else cur_frame^.frame_type := b1 shl 8 + b2; end else Begin cur_frame^.frame_type := getword(cur_frame^.frame_ptr); if cur_frame^.frame_Type = address shl 8 + control then cur_frame^.frame_type := getword(cur_frame^.frame_ptr); end; {$IFDEF SHOWINFO} writeln('Frame Type : ',cur_frame^.frame_type); {$ENDIF} if (cur_frame^.frame_type = IP_Protocol) then inc(NumIPFrames) else if (cur_frame^.frame_type = LCD_Protocol) then inc(NumLCPFrames) else if (cur_frame^.frame_type = NCD_Protocol) then inc(NumNCDFrames); end; {$IFDEF SHOWINFO} {sound(500); delay(5); nosound;} writeln;writeln('[FRAME END]');{$ENDIF} end;
Procedure PPP_Object.SendPPP; var lcp_frame : pLCPFrame; ncd_frame : pNCDFRAME; ip_frame : pIPFrame; packetcrc : word; pc : word; x : word; Begin packetcrc := $ffff; {$IFDEF SHOWINFO2} writeln; writeln('----------------- [ Send Packet ] -------------------'); writeln('PFC : ',use_pfc,' ADFC : ',use_adfc,' VANJ : ',vj_hdrc); writeln; case protocol of IP_Protocol : Writeln('IP Datagram'); NCD_Protocol : Writeln('NCD Packet'); LCD_Protocol : Writeln('LCP Packet'); else writeln('*INVALID PROTOCOL*'); end; {$ENDIF}
sendchar(chr(flag)); {PPP Header Flag} if ((use_adfc) and (not(protocol=IP_PROTOCOL))) or (not(use_adfc)) then Begin sendbyte(address); packetcrc := updatecrc(packetcrc,address); sendbyte(control); packetcrc := updatecrc(packetcrc,control); end;
if protocol=LCD_Protocol then Begin {$IFDEF DEBUG} writeln('Sending LCP Frame'); {$ENDIF} lcp_frame := pLCPFrame(data); lcp_frame^.data_ptr := lcp_frame^.data;
sendword(lcd_protocol); packetcrc := updatecrc(packetcrc,lcd_protocol shr 8); packetcrc := updatecrc(packetcrc,lcd_protocol and $00ff);
sendbyte(lcp_frame^.code); packetcrc := updatecrc(packetcrc,lcp_frame^.code);
sendbyte(lcp_frame^.identifier); packetcrc := updatecrc(packetcrc,lcp_frame^.identifier);
sendword(lcp_frame^.length); packetcrc := updatecrc(packetcrc,lcp_frame^.length shr 8); packetcrc := updatecrc(packetcrc,lcp_frame^.length and $00ff);
for x := 1 to lcp_frame^.datasize do Begin packetcrc := updatecrc(packetcrc,lcp_frame^.data_ptr^); sendbyte(lcp_frame^.data_ptr^); {$IFDEF DEBUG} write (lcp_frame^.data_ptr^,'/'); {$ENDIF} inc(lcp_frame^.data_ptr); end; lcp_frame^.data_ptr := lcp_frame^.data; end else
if protocol=NCD_Protocol then Begin {$IFDEF DEBUG} writeln('Sending NCD Frame'); {$ENDIF} ncd_frame := pNCDFrame(data); ncd_frame^.data_ptr := ncd_frame^.data;
sendword(ncd_protocol); packetcrc := updatecrc(packetcrc,ncd_protocol shr 8); packetcrc := updatecrc(packetcrc,ncd_protocol and $00ff);
sendbyte(ncd_frame^.code); packetcrc := updatecrc(packetcrc,ncd_frame^.code);
sendbyte(ncd_frame^.identifier); packetcrc := updatecrc(packetcrc,ncd_frame^.identifier);
sendword(ncd_frame^.length); packetcrc := updatecrc(packetcrc,ncd_frame^.length shr 8); packetcrc := updatecrc(packetcrc,ncd_frame^.length and $00ff);
for x := 1 to ncd_frame^.datasize do Begin sendbyte(ncd_frame^.data_ptr^); packetcrc := updatecrc(packetcrc,ncd_frame^.data_ptr^); {$IFDEF DEBUG} write('[',ncd_frame^.data_ptr^,']');{$ENDIF} inc(ncd_frame^.data_ptr); end; ncd_frame^.data_ptr := ncd_frame^.data; end else
if protocol=IP_Protocol then Begin {$IFDEF DEBUG} writeln; writeln('[Sending IP Frame]'); {$ENDIF} ip_frame := pIPFrame(data); ip_frame^.data_ptr := ip_frame^.data;
if not(use_pfc) then Begin sendword(ip_protocol); packetcrc := updatecrc(packetcrc,ip_protocol shr 8); packetcrc := updatecrc(packetcrc,ip_protocol and $00ff); end else Begin sendbyte(ip_protocol and $00ff); packetcrc := updatecrc(packetcrc,ip_protocol and $00ff); end;
for x := 1 to ip_frame^.datasize do Begin sendbyte(ip_frame^.data_ptr^); packetcrc := updatecrc(packetcrc,ip_frame^.data_ptr^); {$IFDEF IP2DEBUG} write(ip_frame^.data_ptr^,'³');{$ENDIF} inc(ip_frame^.data_ptr); end; ip_frame^.data_ptr := ip_frame^.data; end;
packetcrc := finalcrc(packetcrc); sendword(packetcrc); sendchar(chr(flag)); end;
Procedure PPP_Object.HandleIncoming; var bte : byte; Begin while numchars>0 do Begin bte := ord(modem.getchar); case bte of Flag : If (PIP) then Begin if (cur_frame^.frame_ptr<>cur_frame^.frame_data) then EndFrame end else NewFrame; else AddtoFrame(bte); end; end; end;
Procedure PPP_Object.Packet_Driver; Begin HandleIncoming; {Handles ALL Incoming Data}
GetLCPFrame; {Loads LCP Frames into pLCPFRAME}
GetNCDFrame; {Loads NCD Frames into pNCDFRAME}
GetIPFrame; {Loads IP Frames into pIPFRAME}
HandleLCPFrames; {Processes all LCP Frames} HandleNCDFrames; {Processes all NCD Frames}
if (transmitbufferused<defaultbuffersize-2048) then HandleIPFrames; {Processes all OUTGOING IP Frames} oIP.ProcessIPFrames; {Processes IP Packets} end;
Function PPP_Object.MakePtr(var variable):pbyte; Begin Makeptr := addr(variable){ptr(seg(variable),ofs(variable))}; end;
Procedure PPP_Object.SendLCP(Code:byte; Identifier:byte; datalength:longint;data:pbyte); var lframe : pLCPFrame; x : byte; Begin new(lframe); lframe^.code := code; lframe^.identifier := identifier; lframe^.length := datalength+4; lframe^.sendorreceive := send; if datalength>0 then getmem(lframe^.data,datalength) else lframe^.data := nil; lframe^.datasize := datalength; lframe^.data_ptr := lframe^.data; if datalength>0 then move(data^,lframe^.data_ptr^,datalength); lframe^.prev := last_LCP_frame; cur_lcp_frame := lframe; last_lcp_frame := lframe; lframe^.next := nil; if first_lcp_frame=nil then first_lcp_frame := lframe; if lframe^.prev<>nil then lframe^.prev^.next := lframe; end;
Procedure PPP_Object.SendNCD(Code:byte; Identifier:byte; datalength:longint;data:pbyte); var lframe : pNCDFrame; x : byte; Begin new(lframe); lframe^.code := code; lframe^.identifier := identifier; lframe^.length := datalength+4; lframe^.sendorreceive := send; if datalength>0 then getmem(lframe^.data,datalength) else lframe^.data := nil; lframe^.datasize := datalength; lframe^.data_ptr := lframe^.data; if (datalength>0) then move(data^,lframe^.data_ptr^,datalength); lframe^.prev := last_NCD_frame; cur_ncd_frame := lframe; last_ncd_frame := lframe; lframe^.next := nil; if first_ncd_frame=nil then first_ncd_frame := lframe; if lframe^.prev<>nil then lframe^.prev^.next := lframe; end;
Procedure PPP_Object.SendIP(datalength:longint;data:pbyte); var lframe : pIPFrame; x : byte; Begin if datalength=0 then exit; new(lframe); lframe^.sendorreceive := send; if datalength>0 then getmem(lframe^.data,datalength) else lframe^.data := nil; lframe^.datasize := datalength; lframe^.data_ptr := lframe^.data; if (datalength>0) then move(data^,lframe^.data_ptr^,datalength); lframe^.prev := last_IP_frame; cur_IP_frame := lframe; last_IP_frame := lframe; lframe^.next := nil; if first_IP_frame=nil then first_IP_frame := lframe; if lframe^.prev<>nil then lframe^.prev^.next := lframe; end;
Procedure PPP_Object.FormatIP (b1,b2,b3,b4:byte; var ipt:iptype); Begin ipt[1] := b1; ipt[2] := b2; ipt[3] := b3; ipt[4] := b4; end;
Function PPP_Object.IPstr (ip:iptype):string; var s : string; x : integer; Begin s := ''; for x := 1 to 4 do Begin s := s + itos(ip[x]); if x<4 then s := s +'.'; end; ipstr := s; end;
Function PPP_Object.ValidIP (s:string):boolean; var z : byte; Begin validIP := false; z := 0; while (pos('.',s)>0) do Begin inc(z); s[pos('.',s)] := ' '; end; if z=3 then ValidIP := true; end;
Function PPP_Object.StoIP(s:string;var IP:iptype):boolean; var x,y : byte; ts : string; Function stoi(s:string):byte; var x : byte; e : integer; Begin val(s,x,e); stoi := x; end; Begin stoip := false; if not(validip(s)) then exit;
for y := 1 to 4 do Begin ts := ''; for x := 1 to pos('.',s)-1 do ts := ts + s[x]; ip[y] := stoi(ts); delete(s,1,pos('.',s)); end; stoip := true; end;
Function PPP_Object.CanWrite:Boolean; Begin CanWrite := TransmitBufferUsed=0; end;
end.
|