PPP
{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.