Original Article : http://blog.naver.com/simonsayz/120212895522
코드는 제가...
The time to share with the pascal ... :)CPU : Atmega128 tested
//******************************************************************************
//
// ** **** PPP Driver
//
// 2011.08.08 Rcv오류 수정 (-20 대신 xor 사용)
//
//
// -------------------------------------------------------------------------
//
// API
// -------------------------------------------------------------------------
//
// 1. Function PPP_Open ('s=2')
// 2. Function PPP_Close;
// 3. Function Svr_Open (TCP,80,'www.maxpaper.com' )
// 4. Function Svr_Close;
// 5. Function Svr_Snd (
// 6. Function Svr_Rcv (
//
//
//
// To Do.
//
// 1. 접속,해제 관련 State 정리
//
//
//
// 중요한 부분
// 1. IPCP 의 경우, Address 0.0.0.0 의 Request에 대하여, Nak을 주면서,
// 사용자 PC의 IP를 줌
// 기본적으로는 서버 IP를 되돌려줌.
//
// To Do
// -------------------------------------------------------------------------
//
//
// Ref.
// #1. Intenet
// http://www.apps.ietf.org/rfc/rfc1331.html
// http://www.joinc.co.kr/modules/moniwiki/wiki.php/Site/TCP_IP/IP_Header
//
// #2. Book
// PPP Design Implementation and Debugging 2nd Ed
// p57 A Request ID 1
// B Reject ID 1
// A Request ID 2
// B Nak ID 2
// A Request ID 3
// B Ack ID 3
// B Request ID 1
// A Ack ID 1
//
//
//******************************************************************************
unit PPP_Drv;
interface
Uses
StdCtrls,SysUtils,Windows,VCL_Uart,Forms;
Const
_cFCS_Init = $ffff; // Initial FCS value
//
_cPPPFlag = $7E;
_cEscape = $7D; // 111:1101 -> 뒷 문자 X - $20
_cMaxBuf = 1600;
_cMaxOpts = 7;
// RFC 1331
_cPktLCP = $C021;
_cPktCHAP = $C223;
_cPktIPCP = $8021;
_cPktCTCP = $002D;
_cPktUTCP = $002F;
// LCP,IPCP
_cConf_Req = 1;
_cConf_Ack = 2;
_cConf_Nak = 3;
_cConf_Rej = 4;
_cTerm_Req = 5;
_cTerm_Ack = 6;
_cCode_Rej = 7;
_cProt_Rej = 8;
_cEcho_Req = 9;
_cEcho_Rep = 10;
_cDisc_Req = 11;
_cReserved = 12;
//
_cLCP_MRU = 1; // Maximum_Receive_Unit
_cLCP_ACCM = 2; // Asynchronous Control Character Map
_cLCP_Auth = 3; // Authentication_Protocol
_cLCP_Quality = 4; // Quality_Protocol
_cLCP_Magic = 5; // Magic_Number
_cLCP_PFC = 7; // Protocol_Field_Compression
_cLCP_ACFC = 8; // Address_Control_Field_Compression
_cLCP_MLP = 12; // Deprecated (Multi-Link-Procedure)
_cLCP_CallBack = 13; // $0D CallBack RFC1570
//
_cIPCP_IPComp = 2; // L:6 IP_Compress_Protocol
_cIPCP_IPAddr = 3; // L:6 IP_Address
_cIPCP_1DNSAddr = $81; // L:6 Primary_DNS_Addr
_cIPCP_1NBNSAddr = $82; // L:6 Primary_NBNS_Addr
_cIPCP_2DNSAddr = $83; // L:6 Secondary_DNS_Addr
_cIPCP_2NBNSAddr = $84; // L:6 Secondary_NBNS_Addr
//
_cIP_TCP = $06;
_cIP_UDP = $11;
//
_cProto_DNS = $35;
_cProto_Web = $50;
//
_cURG = $20;
_cACK = $10;
_cPSH = $08;
_cRST = $04;
_cSYN = $02;
_cFIN = $01;
Type
//
TStepState = (ns0_Init, // 초기 상태
ns1_LCP_Req, // 서버 -> PC
nsLCP_1Rcv, // 첫번째 LCP 읽고,
nsLCP_1Ack, // Ack 보내고,
nsIPCP_1Req);
//
TBuf4 = Packed Array[0.. 3] of Byte;
TBufTcpIp = Packed Array[0..39] of Byte; // Header
TStr = String[60];
TFCSWork = (fwStart,
fwWork,
fwEnd);
TCodeState = (csCmd,
csLen,
csDat);
TCRCType = (ctTCP,
ctIP,
ctUDP);
TTcpState = (tsOpen, // Flag 2 UAPRSF (Sync)
tsWork, // Flag
tsClose);
//
TPktType = (ptNone,
ptLCP, // Frame Packet Type
ptCHAP,
ptIPCP,
ptTCP);
TPktState = (psStart, // Frame State
psAddr,
psControl,
psProtocol,
psData,
psFCS,
psStop);
TPktData = Packed Record // Frame Data
Len : Word;
Data : Array[0.._cMaxBuf-1] of Byte;
End;
//
TIPCP_Cmd = (icUnknown, //
icIP_Addr, // IP Addr
icIP_Comp,
icIP_DNS1,
icIP_DNS2);
TOpt = Record
Cmd : Byte;
Len : Byte;
Dat : TBuf4;
End;
TOpts = Record
Cnt : Integer;
DB : Array[0.._cMaxOpts-1] of TOpt;
End;
//
TState_Frame = (sfCode,
sfID,
sfLen,
sfData);
//
TState_TcpIp = (stVerLen, // IP ------------
stTOS,
stLen,
stID,
stFlagIP,
stTTL,
stProtocol,
stChkSumIP,
stSrcIP,
stDstIP,
stSrcPort, // TCP ------------
stDstPort,
stSeqNum,
stAck,
stHLen,
stFlagTCP,
stWin,
stChkSumTCP,
stUrgent,
stData); // Data -----------
//
TPktFrame = Record
State : TState_Frame;
Code : Byte;
ID : Byte;
Len : Word; // Code + ID + Len + Data (ex. Data : 16-> 20)
Opts : TOpts;
End;
TPktTcpIp = Record
State : TState_TCPIP;
// IP ------------------------------------------------------
VerLen : Byte; // 1 $45 : IPV4 / IHL : 5 x 32b = 20 Bytes
TOS : Byte; // 2 $00 : Type of Service
Length : Word; // 4 $00,$2C [44] : Ver ~ Data (TCP+ Data)
ID : Word; // 6 $73,$49
FlagIP : Word; // 7 $40,$00 : 0100:0000
TTL : Byte; // 9 $40, :
Protocol : Byte; // 10 $06, : TCP , $11 : UDP
ChkSumIP : Word; // 12 $74,$74
SrcIP : TBuf4; // 16 $0A,$17,$06,$04
DstIP : TBuf4; // 20 $7C,$D9,$C6,$1A
// TCP -----------------------------------------------------
SrcPort : Word; // 2 $5C,$7A
DstPort : Word; // 4 $00,$50
SegNum : TBuf4; // 8 $B1,$14,$19,$B2
Ack : TBuf4; // 12 $DE,$AC,$94,$D1
HLen : Byte; // 13 $60 [0110:0000 ->
FlagTCP : Byte; // 14 $02 UAPRSF ->Sync
Win : Word; // 16 $01,$FF
ChkSumTCP : Word; // 18 $AC,$EB,
Urgent : Word; // 20 $00,$00
End;
TPktDNS = Record
ID : Word; //
Flags : Word; // 0100 Recursion Desired
QuestionRR : Word; // 0001 Question 1
AnswerRR : Word; // 0000 Query시 0
AuthorityRR : Word; // 0000 Query시 0
AdditionRR : Word; // 0000 Query시 0
// Addr : String[50];
QueryType : Word; // 0001 : IP
QueryClass : Word; // 0001 : Internet
Name : Word; // C00C : Name
TypeRR : Word; // 0001 : Type / A
//ClassRR : Word; // 0001 : Class / In
TTL : TBuf4;// 00000000 :
Length : Word; // 0004 : IP경우 4
//IP : TBuf4;// IP Address
End;
{
//
$01,$EF, // 02 ID
$81,$80, // 04 Flag 1000:0001
$00,$01, // 06 Question Rec
$00,$01, // 08 Answer Rec
$00,$05, // 10 Authority Rec
$00,$05, // 12 Additonal Rec
$03,$77,$77,$77, // Question www
$08,$6D,$61,$78,$70,$61,$70,$65,$72, // maxpaper
$03,$63,$6F,$6D,$00, // com
$00,$01, // Query Type
$00,$01, // Query Class
$C0,$0C, // 06 Name --------------------
$00,$01, // 02 Type A
$00,$01, // 02 Clasee / In
$00,$00,$12,$C1, // 04 TTL
$00,$04, // Length
$7C,$D9,$C6,$1A, // Addr
} // ...
TEnv = Record
ID : Byte;
MagicCode : TBuf4;
IPServer : TBuf4; //
IPClient : TBuf4; // My IP
IPHost : TBuf4; // Host IP
IPComp : TBuf4;
DNS1 : TBuf4;
DNS2 : TBuf4;
TCPState : TTCPState;
End;
TPkt = Record
iEscaped : Boolean; // 내부 변수
iInx : Word; // 내부 변수
iBuf : TBuf4; //
iBufTCP : TBufTcpIp;// TCP/IP Header
iFCS : Word; // 계산 FCS
rFCS : Word; // 실제 FCS
iStep : TStepState;
//
Env : TEnv;
//
Type_ : TPktType;
State : TPktState;
// PPP Packet
Frame : TPktFrame;
TCPIP : TPktTcpIp;
DNS : TPktDNS;
//
Data : TPktData;
End;
Var
_gPkt : TPkt; // 패킷 정보
//
_gDbg : TMemo; // Debug
_gDStr : String; // Debug String
_gUart : TUart; // Hw
// Dev Function
Procedure hwInit (Uart : TUart; Dbg : TMemo);
Procedure hwSndEsc (sByte : Byte ); // PPP Escape
Procedure hwSnd (sByte : Byte ); // PPP Direct
Procedure hwSndBuf (sData : Pointer; sSize : Integer);
// Utility Function
Procedure Dbg (dsStr : String);
Function B2H (ub : Byte ) : String;
Function B2Buf4 (uA,uB,uC,uD : Byte ) : TBuf4;
Function IsSet (inB : TBuf4) : Boolean;
Function B4ToDW (Buf : TBuf4 ) : DWord;
Function DWToB4 (dB : DWord) : TBuf4;
//
Procedure IPCP_Data2Opts (Var Pkt : TPkt);
Procedure IPCP_Opts2Env (ForceEdit : Boolean; Var Pkt : TPkt);
Function IPCP_OptsExist (Var Pkt : TPkt; Cmd : Byte) : Boolean;
Function IPCP_OptsComp (Var Pkt : TPkt; Cmd : Byte; Buf4 : TBuf4) : Boolean;
Procedure IPCP_Env2Data (Var Pkt : TPkt);
Procedure IPCP_Env2DataReject(Var Pkt : TPkt);
//
Function DNS_Query (Var Pkt : TPkt; Host : TStr) : Boolean;
Function DNS_IpPos (Const Buf : TPktData) : Word;
//
Procedure TCP_Send (Var Pkt : TPkt);
Procedure TCP_Open (Var Pkt : TPkt; Ip : TBuf4; Port : Word;Flag : Byte);
Procedure TCP_Reply (Var Pkt : TPkt);
//
Procedure ppp_Init (Var Pkt : TPkt);
Function ppp_Receive (Var Pkt : TPkt; InData : Byte) : Boolean;
//
Function ppp_process (Var Pkt : TPkt; InData : Byte) : Boolean;
//
Procedure Send_IPCP_Req;
Const
//
_cLCP_Req : Packed Array[0..55] of Byte =
($7E, // Start
$FF, // Address
$7D,$23, // Control
$C0,$21, // Protocol : LCP
$7D,$21, // Code : Request
$7D,$21, // ID : 1
$7D,$20,$7D,$38, // Len : 18
$7D,$21,$7D,$24,$7D,$25,$AC, // MRU 01 04 05 AC
$7D,$22,$7D,$26,$7D,$20,$7D,$20,$7D,$20,$7D,$20,// ACCM 02 06 00 00 00 00
$7D,$25,$7D,$26,$7D,$26,$7D,$29,$7D,$22,$7D,$20,// Magic 05 06 06 09 02 00
$7D,$27,$7D,$22, // PFC 02 02 (C0 21)
$7D,$28,$7D,$22, // ACFC 08 02 (FF 03)
$67,$61, // FCS : Field Check Sequence
$7E); // End
_cChap_Res : Packed Array [0..47] of Byte =
($7e,
$c2,$23, // CHAP
$02, // Response
$01, // ID
$00,$2a, // (02) Len (42)
$10, // (01) Value-Size (16)
$95,$38,$af,$c3,$e0,$e0,$7a,$8c, // (16) Option
$8d,$94,$8e,$43,$ed,$bd,$fd,$3a,
$30,$31,$30,$35,$37,$34,$30,$31, // (21) 01057401886@lgt.co.kr
$38,$38,$36,$40,$6c,$67,$74,$2e,
$63,$6f,$2e,$6b,$72,
$72,$b6, // (02) CRC
$7e);
_cIPCP_Req : Packed Array[0..39] of Byte =
($7E, // Start
$FF, // Address
$7D,$23, // Control
$80,$21, // Protocol : IPCP
$7D,$21, // Code : Req
$7D,$30, // ID : 10
$7D,$20,$7D,$30, // Len : 18 ( Code ~ Data )
$7D,$22,$7D,$26,$7D,$20,$2D,$7D,$2F,$7D,$21, // IP Compress Protocol
$7D,$23,$7D,$26,$7D,$20,$7D,$20,$7D,$20,$7D,$20,// IP Addr
$E3,$73, // FCS
$7E); // End
_cIPCP_Req2: Packed Array[0..28] of Byte =
($7E, // Start
$FF, // Address
$7D,$23, // Control
$80,$21, // Protocol : IPCP
$7D,$21, // Code : Req
$7D,$30, // ID : 10
$7D,$20,$7D,$2A, // Len : 10 ( Code ~ Data )
$7D,$23,$7D,$26,$7D,$20,$7D,$20,$7D,$20,$7D,$20,// IP Addr
$7A,$9A, // FCS
$7E); // End
implementation
Uses
PPP_Help;
Const
_cFCSTbl : Array[0..255] of Word =
($0000,$1189,$2312,$329b,$4624,$57ad,$6536,$74bf,
$8c48,$9dc1,$af5a,$bed3,$ca6c,$dbe5,$e97e,$f8f7,
$1081,$0108,$3393,$221a,$56a5,$472c,$75b7,$643e,
$9cc9,$8d40,$bfdb,$ae52,$daed,$cb64,$f9ff,$e876,
$2102,$308b,$0210,$1399,$6726,$76af,$4434,$55bd,
$ad4a,$bcc3,$8e58,$9fd1,$eb6e,$fae7,$c87c,$d9f5,
$3183,$200a,$1291,$0318,$77a7,$662e,$54b5,$453c,
$bdcb,$ac42,$9ed9,$8f50,$fbef,$ea66,$d8fd,$c974,
$4204,$538d,$6116,$709f,$0420,$15a9,$2732,$36bb,
$ce4c,$dfc5,$ed5e,$fcd7,$8868,$99e1,$ab7a,$baf3,
$5285,$430c,$7197,$601e,$14a1,$0528,$37b3,$263a,
$decd,$cf44,$fddf,$ec56,$98e9,$8960,$bbfb,$aa72,
$6306,$728f,$4014,$519d,$2522,$34ab,$0630,$17b9,
$ef4e,$fec7,$cc5c,$ddd5,$a96a,$b8e3,$8a78,$9bf1,
$7387,$620e,$5095,$411c,$35a3,$242a,$16b1,$0738,
$ffcf,$ee46,$dcdd,$cd54,$b9eb,$a862,$9af9,$8b70,
$8408,$9581,$a71a,$b693,$c22c,$d3a5,$e13e,$f0b7,
$0840,$19c9,$2b52,$3adb,$4e64,$5fed,$6d76,$7cff,
$9489,$8500,$b79b,$a612,$d2ad,$c324,$f1bf,$e036,
$18c1,$0948,$3bd3,$2a5a,$5ee5,$4f6c,$7df7,$6c7e,
$a50a,$b483,$8618,$9791,$e32e,$f2a7,$c03c,$d1b5,
$2942,$38cb,$0a50,$1bd9,$6f66,$7eef,$4c74,$5dfd,
$b58b,$a402,$9699,$8710,$f3af,$e226,$d0bd,$c134,
$39c3,$284a,$1ad1,$0b58,$7fe7,$6e6e,$5cf5,$4d7c,
$c60c,$d785,$e51e,$f497,$8028,$91a1,$a33a,$b2b3,
$4a44,$5bcd,$6956,$78df,$0c60,$1de9,$2f72,$3efb,
$d68d,$c704,$f59f,$e416,$90a9,$8120,$b3bb,$a232,
$5ac5,$4b4c,$79d7,$685e,$1ce1,$0d68,$3ff3,$2e7a,
$e70e,$f687,$c41c,$d595,$a12a,$b0a3,$8238,$93b1,
$6b46,$7acf,$4854,$59dd,$2d62,$3ceb,$0e70,$1ff9,
$f78f,$e606,$d49d,$c514,$b1ab,$a022,$92b9,$8330,
$7bc7,$6a4e,$58d5,$495c,$3de3,$2c6a,$1ef1,$0f78);
//*****************************************************************************
//
// HardWare Driver Function
// -------------------------------------------------------------------------
// 추후 HW 환경에 맞도록 Layer 분리
//
//
//*****************************************************************************
// Dev Function
Procedure hwInit (Uart : TUart; Dbg : TMemo);
begin
//
_gUart := Uart;
_gDbg := Dbg;
_gDStr := '';
end;
// PPP Escape
Procedure hwSndEsc(sByte : Byte);
begin
Case (sByte in [$0..$20,$7d,$7e]) of
True : Begin
_gUart.SendByte($7D );
_gUart.SendByte(sByte xor $20);
_gDStr := _gDStr + B2H($7D)+',$' + B2H(sByte xor $20) + ',$';
End;
False : Begin
_gUart.SendByte(sByte);
_gDStr := _gDStr + B2H(sByte) + ',$';
End;
End;
end;
// PPP Direct
Procedure hwSnd (sByte : Byte);
begin
_gUart.SendByte(sByte);
_gDStr := _gDStr + B2H(sByte) + ',$';
end;
//
Procedure hwSndBuf (sData : Pointer; sSize : Integer);
begin
_gUart.SendData(sData,sSize);
end;
//*****************************************************************************
//
// Utility Function
// -------------------------------------------------------------------------
//
//
//*****************************************************************************
//
Procedure Dbg(dsStr : String);
begin
_gDbg.Lines.Add(dsStr);
end;
//
Function B2H (ub : Byte) : String;
begin
Result := IntToHex(ub,2);
end;
//
Function W2H (uW : Word) : String;
begin
Result := IntToHex(uW,4);
end;
//
Function IsSet(inB : TBuf4) : Boolean;
begin
Result := (inB[0] + inB[1] + inB[2] + inB[3]) > 0;
end;
//
Function B4ToDW(Buf : TBuf4 ) : DWord;
begin
Result := (Buf[0] shl 24) or
(Buf[1] shl 16) or
(Buf[2] shl 8) or
(Buf[3] shl 0);
end;
//
Function DWToB4(dB : DWord) : TBuf4;
begin
Result[0] := (db shr 24) and $FF;
Result[1] := (db shr 16) and $FF;
Result[2] := (db shr 8) and $FF;
Result[3] := (db shr 0) and $FF;
end;
//
Function B2Buf4(uA,uB,uC,uD : Byte ) : TBuf4;
begin
Result[0] := uA;
Result[1] := uB;
Result[2] := uC;
Result[3] := uD;
end;
// FCS [Protocol ~ Data]
Procedure hwSndCRC(fcIn : Byte; Work : TFCSWork; Var FCS : Word);
Begin
//
Case fcIn of
_cPPPFlag : begin
hwSnd($7D);
hwSnd(fcIn xor $20);
end;
else hwSnd(fcIn);
End;
//
Case Work of
fwStart,
fwWork : begin
If Work = fwStart then FCS := _cFCS_Init;
FCS := (FCS shr 8) xor _cFCSTbl[(FCS xor fcIn) and $FF];
end;
fwEnd : FCS := Swap((FCS xor $FFFF));
End;
End;
// FCS [Protocol ~ Data]
Procedure CRC_PPP(Work : TFCSWork; fcIn : Byte; Var FCS : Word);
Begin
//
Case Work of
fwStart,
fwWork : begin
If Work = fwStart then FCS := _cFCS_Init;
FCS := (FCS shr 8) xor _cFCSTbl[(FCS xor fcIn) and $FF];
end;
fwEnd : FCS := Swap((FCS xor $FFFF));
End;
End;
// Data : IP 첫번쨰 위치
// IpCSum := CRC_IP(@_cExIP);
Function CRC_IP (data:pointer):word;
var
pw : Pword;
x : word;
csum : longint;
Begin
csum := 0;
//
pw := data;
For x := 1 to 10 do
Begin
csum := csum + pw^;
inc(pw);
end;
//
csum := (csum and $ffff) + (csum shr 16);
csum := csum + (csum shr 16);
csum := (csum and $00ff) shl 8 + (csum shr 8);
Result := csum xor $FFFF;
end;
// Pseudo IP Sum
Function CRC_PseudoIP_Sum(pIP : Pointer) : LongInt;
Var
pw : PWord;
X : Byte;
Begin
// 초기화
Result := 0;
// IP Sum
pw := pIP;
For x := 1 to 6 do
Begin
Result := Result + pw^;
inc(pw);
End;
End;
// TCP : CRC_TcpUdp(cSum, Pkt, 20);
// UDP : CRC_TcpUdp(cSum, Pkt, 8);
Function CRC_TcpUdpCalc(cSum : LongInt;
Var Pkt : TPkt; HdrLen : Integer) : Word;
var
pw : Pword;
x : word;
Begin
// Step #01. Header (IP+TCP,IP+UDP) ------------------------------------------
pw := @Pkt.iBufTCP;
For x := 1 to (HdrLen shr 1) do
Begin
csum := csum + pw^;
inc(pw);
End;
// Step #02. Data -----------------------------------------------------------
pw := @Pkt.Data.Data;
For x := 1 to (Pkt.Data.Len shr 1) do
Begin
csum := csum + pw^;
inc(pw);
End;
If (Pkt.Data.Len mod 2=1) then
Begin
X := PByte(pw)^;
csum := csum + X;
end;
csum := (csum and $ffff) + (csum shr 16);
csum := csum + (csum shr 16);
csum := (csum and $00ff) shl 8 + (csum shr 8);
Result := csum xor $FFFF;
end;
// 전제 조건 : TCPIP ,Data.Len 값이 정확해야 함
Function CRC_TcpUdp(Var Pkt : TPkt; CrcType : TCRCType) : Word;
var
IpSum : LongInt;
begin
//
Case CrcType of
ctIP : begin
// IP
Pkt.iBufTCP[ 0] := Pkt.TCPIP.VerLen;
Pkt.iBufTCP[ 1] := Pkt.TCPIP.TOS;
Pkt.iBufTCP[ 2] := Hi(Pkt.TCPIP.Length);
Pkt.iBufTCP[ 3] := Lo(Pkt.TCPIP.Length);
Pkt.iBufTCP[ 4] := Hi(Pkt.TCPIP.ID );
Pkt.iBufTCP[ 5] := Lo(Pkt.TCPIP.ID );
Pkt.iBufTCP[ 6] := Hi(Pkt.TCPIP.FlagIP);
Pkt.iBufTCP[ 7] := Lo(Pkt.TCPIP.FlagIP);
Pkt.iBufTCP[ 8] := Pkt.TCPIP.TTL;
Pkt.iBufTCP[ 9] := Pkt.TCPIP.Protocol;
Pkt.iBufTCP[10] := 0; // ChkSumIP
Pkt.iBufTCP[11] := 0; // ChkSumIP
Pkt.iBufTCP[12] := Pkt.TCPIP.SrcIP[0];
Pkt.iBufTCP[13] := Pkt.TCPIP.SrcIP[1];
Pkt.iBufTCP[14] := Pkt.TCPIP.SrcIP[2];
Pkt.iBufTCP[15] := Pkt.TCPIP.SrcIP[3];
Pkt.iBufTCP[16] := Pkt.TCPIP.DstIP[0];
Pkt.iBufTCP[17] := Pkt.TCPIP.DstIP[1];
Pkt.iBufTCP[18] := Pkt.TCPIP.DstIP[2];
Pkt.iBufTCP[19] := Pkt.TCPIP.DstIP[3];
//
Result := CRC_IP (@Pkt.iBufTCP);
end;
ctTCP,
ctUDP : begin
// Calc Pseudo Sum
Pkt.iBufTCP[ 0] := Pkt.TCPIP.SrcIP[0];
Pkt.iBufTCP[ 1] := Pkt.TCPIP.SrcIP[1];
Pkt.iBufTCP[ 2] := Pkt.TCPIP.SrcIP[2];
Pkt.iBufTCP[ 3] := Pkt.TCPIP.SrcIP[3];
Pkt.iBufTCP[ 4] := Pkt.TCPIP.DstIP[0];
Pkt.iBufTCP[ 5] := Pkt.TCPIP.DstIP[1];
Pkt.iBufTCP[ 6] := Pkt.TCPIP.DstIP[2];
Pkt.iBufTCP[ 7] := Pkt.TCPIP.DstIP[3];
Pkt.iBufTCP[ 8] := 0; // Pad
Pkt.iBufTCP[ 9] := Pkt.TCPIP.Protocol;
// TCP
Case CrcType of
ctTCP : begin
Pkt.iBufTCP[10] := Hi(20 + Pkt.Data.Len); // TCP + Data Length
Pkt.iBufTCP[11] := Lo(20 + Pkt.Data.Len); // TCP + Data Length
IpSum := CRC_PseudoIP_Sum(@Pkt.iBufTCP);
//
Pkt.iBufTCP[ 0] := Hi(Pkt.TCPIP.SrcPort);
Pkt.iBufTCP[ 1] := Lo(Pkt.TCPIP.SrcPort);
Pkt.iBufTCP[ 2] := Hi(Pkt.TCPIP.DstPort);
Pkt.iBufTCP[ 3] := Lo(Pkt.TCPIP.DstPort);
Pkt.iBufTCP[ 4] := Pkt.TCPIP.SegNum[0];
Pkt.iBufTCP[ 5] := Pkt.TCPIP.SegNum[1];
Pkt.iBufTCP[ 6] := Pkt.TCPIP.SegNum[2];
Pkt.iBufTCP[ 7] := Pkt.TCPIP.SegNum[3];
Pkt.iBufTCP[ 8] := Pkt.TCPIP.Ack [0];
Pkt.iBufTCP[ 9] := Pkt.TCPIP.Ack [1];
Pkt.iBufTCP[10] := Pkt.TCPIP.Ack [2];
Pkt.iBufTCP[11] := Pkt.TCPIP.Ack [3];
Pkt.iBufTCP[12] := Pkt.TCPIP.HLen;
Pkt.iBufTCP[13] := Pkt.TCPIP.FlagTCP;
Pkt.iBufTCP[14] := Hi(Pkt.TCPIP.Win );
Pkt.iBufTCP[15] := Lo(Pkt.TCPIP.Win );
Pkt.iBufTCP[16] := 0; // TCP Check Sum
Pkt.iBufTCP[17] := 0;
Pkt.iBufTCP[18] := Hi(Pkt.TCPIP.Urgent );
Pkt.iBufTCP[19] := Lo(Pkt.TCPIP.Urgent );
Result := CRC_TcpUdpCalc(IpSum,Pkt,20);
end;
ctUDP : begin
Pkt.iBufTCP[10] := Hi(8 + Pkt.Data.Len); // TCP + Data Length
Pkt.iBufTCP[11] := Lo(8 + Pkt.Data.Len); // TCP + Data Length
IpSum := CRC_PseudoIP_Sum(@Pkt.iBufTCP);
//
Pkt.iBufTCP[ 0] := Hi(Pkt.TCPIP.SrcPort);
Pkt.iBufTCP[ 1] := Lo(Pkt.TCPIP.SrcPort);
Pkt.iBufTCP[ 2] := Hi(Pkt.TCPIP.DstPort);
Pkt.iBufTCP[ 3] := Lo(Pkt.TCPIP.DstPort);
Pkt.iBufTCP[ 4] := Hi(Pkt.TCPIP.Win );
Pkt.iBufTCP[ 5] := Lo(Pkt.TCPIP.Win );
Pkt.iBufTCP[ 6] := 0; // UDP Check Sum
Pkt.iBufTCP[ 7] := 0;
Result := CRC_TcpUdpCalc(IpSum,Pkt,8);
end;
End;
//
end;
End;
end;
// Raw 데이터를 Pkt.Frame.Opts에...
// Pkt.Data -> Pkt.Frame.Opts
Procedure IPCP_Data2Opts(Var Pkt : TPkt);
Var
Lp : Integer;
CState : TCodeState;
Dat : Byte;
Inx : Integer;
begin
// 초기화
cState := csCmd;
Inx := 0;
Pkt.Frame.Opts.Cnt := 0;
//
For Lp := 0 to Pkt.Data.Len-1 do
begin
Dat := Pkt.Data.Data[Lp];
//
Case cState of
csCmd : Begin
cState := csLen;
Pkt.Frame.Opts.DB[Pkt.Frame.Opts.Cnt].Cmd := Dat;
End;
csLen : Begin
cState := csDat;
Pkt.Frame.Opts.DB[Pkt.Frame.Opts.Cnt].Len := Dat;
Inx := 0;
Case Pkt.Frame.Opts.DB[Pkt.Frame.Opts.Cnt].Len <= 2 of
True : Begin
cState := csCmd;
Inc(Pkt.Frame.Opts.Cnt);
End;
False : cState := csDat;
End;
End;
csDat : Begin
//
Pkt.Frame.Opts.DB[Pkt.Frame.Opts.Cnt].Dat[Inx] := Dat;
Inc(Inx);
//
If Inx >= Pkt.Frame.Opts.DB[Pkt.Frame.Opts.Cnt].Len-2 then
Begin
cState := csCmd;
Inc(Pkt.Frame.Opts.Cnt);
End;
End;
End;
end;
end;
// Opts값 -> Env변수 Update
Procedure IPCP_Opts2Env (ForceEdit : Boolean; Var Pkt : TPkt);
Var
Lp : Integer;
begin
For Lp := 0 to Pkt.Frame.Opts.Cnt-1 do
Case Pkt.Frame.Opts.DB[Lp].Cmd of
_cIPCP_IPComp : If (ForceEdit)or(Not(IsSet(Pkt.Env.IPComp))) then
Pkt.Env.IPComp := Pkt.Frame.Opts.DB[Lp].Dat;
_cIPCP_IPAddr : Case ForceEdit of
True : Pkt.Env.IPClient := Pkt.Frame.Opts.DB[Lp].Dat;
False: Pkt.Env.IPServer := Pkt.Frame.Opts.DB[Lp].Dat;
End;
_cIPCP_1DNSAddr : If (ForceEdit)or(Not(IsSet(Pkt.Env.DNS1 ))) then
Pkt.Env.DNS1 := Pkt.Frame.Opts.DB[Lp].Dat;
_cIPCP_2DNSAddr : If (ForceEdit)or(Not(IsSet(Pkt.Env.DNS2 ))) then
Pkt.Env.DNS2 := Pkt.Frame.Opts.DB[Lp].Dat;
_cIPCP_1NBNSAddr : ;
_cIPCP_2NBNSAddr : ;
end;
end;
//
Function IPCP_OptsExist(Var Pkt : TPkt; Cmd : Byte) : Boolean;
Var
Lp : Integer;
begin
// 초기화
Result := False;
//
For Lp := 0 to Pkt.Frame.Opts.Cnt-1 do
If Pkt.Frame.Opts.DB[Lp].Cmd = Cmd then
begin
Result := True;
Exit;
end;
end;
//
Function IPCP_OptsComp (Var Pkt : TPkt; Cmd : Byte; Buf4 : TBuf4) : Boolean;
Var
Lp : Integer;
Lp2: Integer;
begin
// 초기화
Result := False;
//
For Lp := 0 to Pkt.Frame.Opts.Cnt-1 do
If Pkt.Frame.Opts.DB[Lp].Cmd = Cmd then
begin
For Lp2 := 0 to 3 do
If Buf4[Lp2] <> Pkt.Frame.Opts.DB[Lp].Dat[Lp2] then
Exit;
//
Result := True;
Exit;
end;
end;
// Env 변수 -> Pkt.Data로 이전
Procedure IPCP_Env2Data (Var Pkt : TPkt);
Var
Ofs : Integer;
begin
//
Ofs := 0;
Pkt.Data.Data[Ofs+0] := _cIPCP_IPAddr;
Pkt.Data.Data[Ofs+1] := 6;
Move(Pkt.Env.IpServer,Pkt.Data.Data[Ofs+2],4);
//
Inc(Ofs,6);
Pkt.Data.Len := Ofs;
end;
//
Procedure IPCP_Env2DataReject(Var Pkt : TPkt);
Var
Ofs : Integer;
begin
//
Ofs := 0;
//
Pkt.Data.Data[Ofs+0] := _cIPCP_IPComp;
Pkt.Data.Data[Ofs+1] := 6;
Move(Pkt.Env.IpComp,Pkt.Data.Data[Ofs+2],4);
//
Inc(Ofs,6);
Pkt.Data.Data[Ofs+0] := _cIPCP_1DNSAddr;
Pkt.Data.Data[Ofs+1] := 6;
Move(Pkt.Env.DNS1,Pkt.Data.Data[Ofs+2],4);
//
Inc(Ofs,6);
Pkt.Data.Data[Ofs+0] := _cIPCP_2DNSAddr;
Pkt.Data.Data[Ofs+1] := 6;
Move(Pkt.Env.DNS2,Pkt.Data.Data[Ofs+2],4);
//
Inc(Ofs,6);
Pkt.Data.Len := Ofs;
end;
//
Procedure Reply_LCP(Var Step : TStepState; Var Pkt : TPkt);
Var
FCS : Word;
Lp : Integer;
begin
_gDStr := '';
hwSnd (_cPPPFlag); // 7E
hwSndEsc($FF ); CRC_PPP(fwStart,$FF,FCS); // Protocol
hwSndEsc($03 ); CRC_PPP(fwWork ,$03,FCS);
hwSndEsc($C0 ); CRC_PPP(fwWork ,$C0,FCS);
hwSndEsc($21 ); CRC_PPP(fwWork ,$21,FCS);
Case Pkt.Frame.Code of // Code
_cConf_Req : begin
Pkt.Frame.Code := _cConf_Ack;
hwSndEsc (Pkt.Frame.Code);
CRC_PPP(fwWork,Pkt.Frame.Code,FCS);
end;
End;
hwSndEsc (Pkt.Frame.ID); CRC_PPP(fwWork ,Pkt.Frame.ID ,FCS);
hwSndEsc (Hi(Pkt.Frame.Len)); CRC_PPP(fwWork ,Hi(Pkt.Frame.Len),FCS);
hwSndEsc (Lo(Pkt.Frame.Len)); CRC_PPP(fwWork ,Lo(Pkt.Frame.Len),FCS);
// Cmd:Len:Data ...
For Lp := 0 to Pkt.Data.Len-1 do
Begin
hwSndEsc (Pkt.Data.Data[Lp]);
CRC_PPP(fwWork ,Pkt.Data.Data[Lp],FCS);
End;
CRC_PPP(fwEnd ,0,FCS);
// FCS
hwSndEsc(Hi(FCS) );
hwSndEsc(Lo(FCS) );
hwSnd (_cPPPFlag);
// Help...
// Dbg('Snd:'+_gDStr);
Help_LCP('Snd:',Pkt );
end;
//
Procedure Reply_IPCP(Var Step : TStepState; Var Pkt : TPkt);
Var
FCS : Word;
Lp : Integer;
begin
// Raw Data 값을 Opts Record로 이동후, 환경 변수에 저장
IPCP_Data2Opts(Pkt);
Case Pkt.Frame.Code of
_cConf_Req : IPCP_Opts2Env(False,Pkt);
_cConf_Nak : IPCP_Opts2Env(True ,Pkt);
_cConf_Ack : Exit;
End;
// Help_Env (Pkt);
_gDStr := '';
hwSnd (_cPPPFlag); // 7E
hwSndEsc($FF ); CRC_PPP(fwStart,$FF,FCS); // Protocol
hwSndEsc($03 ); CRC_PPP(fwWork ,$03,FCS);
hwSndEsc($80 ); CRC_PPP(fwWork ,$80,FCS);
hwSndEsc($21 ); CRC_PPP(fwWork ,$21,FCS);
Case Pkt.Frame.Code of // Code
_cConf_Req : Begin
Dbg('IPCP : Req->Req');
If IPCP_OptsExist(Pkt,_cIPCP_1DNSAddr) or
IPCP_OptsExist(Pkt,_cIPCP_2DNSAddr) then
Begin
IPCP_Env2DataReject(Pkt);
Pkt.Frame.Len := Pkt.Data.Len + 4;
Pkt.Frame.Code := _cConf_Rej;
End
else
Pkt.Frame.Code := _cConf_Ack;
//
hwSndEsc (Pkt.Frame.Code);
CRC_PPP(fwWork,Pkt.Frame.Code,FCS);
End;
_cConf_Nak : Begin
Dbg('IPCP : Nak->Req');
Pkt.Frame.Code := _cConf_Req;
Inc(Pkt.Env.ID);
Pkt.Frame.ID := Pkt.Env.ID;
hwSndEsc(Pkt.Frame.Code);
CRC_PPP (fwWork,Pkt.Frame.Code,FCS);
End;
_cConf_Ack : Begin
Pkt.Frame.Code := _cConf_Req;
Inc(Pkt.Env.ID);
Pkt.Frame.ID := Pkt.Env.ID;
hwSndEsc(Pkt.Frame.Code);
CRC_PPP (fwWork,Pkt.Frame.Code,FCS);
end;
End;
//
hwSndEsc (Pkt.Frame.ID); CRC_PPP(fwWork ,Pkt.Frame.ID ,FCS);
hwSndEsc (Hi(Pkt.Frame.Len)); CRC_PPP(fwWork ,Hi(Pkt.Frame.Len),FCS);
hwSndEsc (Lo(Pkt.Frame.Len)); CRC_PPP(fwWork ,Lo(Pkt.Frame.Len),FCS);
// Cmd:Len:Data ...
For Lp := 0 to Pkt.Data.Len-1 do
Begin
hwSndEsc (Pkt.Data.Data[Lp]);
CRC_PPP(fwWork ,Pkt.Data.Data[Lp],FCS);
End;
CRC_PPP(fwEnd ,0,FCS);
// FCS
hwSndEsc(Hi(FCS) );
hwSndEsc(Lo(FCS) );
hwSnd (_cPPPFlag);
// Help...
// Dbg('Snd:'+_gDStr);
Help_LCP('Snd:', Pkt );
end;
// Pkt.iFCS : Loop
// Pkt.iInx : 갯수
// Pkt.iBuf : '.' 위치
// 중요한점은 7E는 반드시, Escape 시켜야 함
Function DNS_Query (Var Pkt : TPkt; Host : TStr) : Boolean;
Var
Lp : Integer;
FCS : Word;
begin
//
_gDStr := '';
Result := False;
If Host = '' then Exit;
// DNS 관련 -------------------- 12 + 4 +
Pkt.DNS.ID := $01EF;
Pkt.DNS.Flags := $0100;
Pkt.DNS.QuestionRR := $0001;
Pkt.DNS.AnswerRR := $0000;
Pkt.DNS.AuthorityRR := $0000;
Pkt.DNS.AdditionRR := $0000;
Pkt.DNS.QueryType := $0001;
Pkt.DNS.QueryClass := $0001;
// UDP DNS 데이터 설정
Pkt.Data.Len := 0;
Pkt.Data.Data[Pkt.Data.Len] := Hi(Pkt.DNS.ID ); Inc(Pkt.Data.Len);
Pkt.Data.Data[Pkt.Data.Len] := Lo(Pkt.DNS.ID ); Inc(Pkt.Data.Len);
Pkt.Data.Data[Pkt.Data.Len] := Hi(Pkt.DNS.Flags ); Inc(Pkt.Data.Len);
Pkt.Data.Data[Pkt.Data.Len] := Lo(Pkt.DNS.Flags ); Inc(Pkt.Data.Len);
Pkt.Data.Data[Pkt.Data.Len] := Hi(Pkt.DNS.QuestionRR ); Inc(Pkt.Data.Len);
Pkt.Data.Data[Pkt.Data.Len] := Lo(Pkt.DNS.QuestionRR ); Inc(Pkt.Data.Len);
Pkt.Data.Data[Pkt.Data.Len] := Hi(Pkt.DNS.AnswerRR ); Inc(Pkt.Data.Len);
Pkt.Data.Data[Pkt.Data.Len] := Lo(Pkt.DNS.AnswerRR ); Inc(Pkt.Data.Len);
Pkt.Data.Data[Pkt.Data.Len] := Hi(Pkt.DNS.AuthorityRR); Inc(Pkt.Data.Len);
Pkt.Data.Data[Pkt.Data.Len] := Lo(Pkt.DNS.AuthorityRR); Inc(Pkt.Data.Len);
Pkt.Data.Data[Pkt.Data.Len] := Hi(Pkt.DNS.AdditionRR ); Inc(Pkt.Data.Len);
Pkt.Data.Data[Pkt.Data.Len] := Lo(Pkt.DNS.AdditionRR ); Inc(Pkt.Data.Len);
// DNS Name 설정 ( www.maxpaper.com )
Pkt.iInx := Pkt.Data.Len;
Pkt.iFCS := 0;
For Lp := 1 to Length(Host) do
Case host[Lp] = '.' of
False : Begin
Pkt.Data.Data[Pkt.Data.Len+Lp] := Ord(Host[Lp]);
Inc(Pkt.iFCS);
End;
True : Begin
Pkt.Data.Data[Pkt.iInx] := Pkt.iFCS;
Pkt.iInx := Pkt.Data.Len+Lp;
Pkt.iFCS := 0;
End;
End;
//
Pkt.Data.Data[Pkt.iInx] := Pkt.iFCS; Inc(Pkt.Data.Len,Length(host)+1);
Pkt.Data.Data[Pkt.Data.Len] := $00; ; Inc(Pkt.Data.Len);
Pkt.Data.Data[Pkt.Data.Len] := Hi(Pkt.DNS.QueryType ); Inc(Pkt.Data.Len);
Pkt.Data.Data[Pkt.Data.Len] := Lo(Pkt.DNS.QueryType ); Inc(Pkt.Data.Len);
Pkt.Data.Data[Pkt.Data.Len] := Hi(Pkt.DNS.QueryClass ); Inc(Pkt.Data.Len);
Pkt.Data.Data[Pkt.Data.Len] := Lo(Pkt.DNS.QueryClass ); Inc(Pkt.Data.Len);
// IP 관련
Pkt.TCPIP.VerLen := $45;
Pkt.TCPIP.TOS := $00;
Pkt.TCPIP.Length := 20 + (8 + Pkt.Data.Len); // 62 ( 20 + 8 + 34 )
Pkt.TCPIP.ID := $1BA3;
Pkt.TCPIP.FlagIP := $0000;
Pkt.TCPIP.TTL := $80;
Pkt.TCPIP.Protocol := _cIP_UDP;
Pkt.TCPIP.SrcIp := Pkt.Env.IPClient; // B2Buf4($0A,$17,$06,$04);
Pkt.TCPIP.DstIP := Pkt.Env.DNS1; // B2Buf4($96,$02,$7E,$66);
// UDP 관련
Pkt.TCPIP.SrcPort := $04EC; // DE6;
Pkt.TCPIP.DstPort := $0035; // 53
Pkt.TCPIP.Win := 8 + Pkt.Data.Len; // 8 + Data[34]
// Send ----
Pkt.TCPIP.ChkSumIP := CRC_TCPUDP(Pkt,ctIP );
Pkt.TCPIP.ChkSumTCP := CRC_TCPUDP(Pkt,ctUDP);
//
hwSnd (_cPPPFlag); // 7E
// hwSndEsc(rU,Snd);
hwSndCRC($FF,fwStart,FCS); // Protocol
hwSndCRC($03,fwWork ,FCS); // Control
hwSndCRC($00,fwWork ,FCS); // TCP/IP
hwSndCRC($21,fwWork ,FCS); //
// IP -----------------------------------------------------------------------
hwSndCRC($45 ,fwWork,FCS); // VerLen
hwSndCRC($00 ,fwWork,FCS); // TOS
hwSndCRC(Hi(Pkt.TCPIP.Length) ,fwWork,FCS); // Len ( IP + TCP + Data.Len )
hwSndCRC(Lo(Pkt.TCPIP.Length) ,fwWork,FCS); //
hwSndCRC(Hi(Pkt.TCPIP.ID ) ,fwWork,FCS); // ID
hwSndCRC(Lo(Pkt.TCPIP.ID ) ,fwWork,FCS); //
hwSndCRC(Hi(Pkt.TCPIP.FlagIP) ,fwWork,FCS); // FlagIP (3:13)
hwSndCRC(Lo(Pkt.TCPIP.FlagIP) ,fwWork,FCS); //
hwSndCRC( Pkt.TCPIP.TTL ,fwWork,FCS); // TTL
hwSndCRC( Pkt.TCPIP.Protocol ,fwWork,FCS); // Protocol
hwSndCRC(Hi(Pkt.TCPIP.ChkSumIP) ,fwWork,FCS); // IP Check Sum
hwSndCRC(Lo(Pkt.TCPIP.ChkSumIP) ,fwWork,FCS); // IP Check Sum
hwSndCRC( Pkt.TCPIP.SrcIP[0] ,fwWork,FCS); // SrcIP
hwSndCRC( Pkt.TCPIP.SrcIP[1] ,fwWork,FCS); // SrcIP
hwSndCRC( Pkt.TCPIP.SrcIP[2] ,fwWork,FCS); // SrcIP
hwSndCRC( Pkt.TCPIP.SrcIP[3] ,fwWork,FCS); // SrcIP
hwSndCRC( Pkt.TCPIP.DstIP[0] ,fwWork,FCS); // SrcIP
hwSndCRC( Pkt.TCPIP.DstIP[1] ,fwWork,FCS); // SrcIP
hwSndCRC( Pkt.TCPIP.DstIP[2] ,fwWork,FCS); // SrcIP
hwSndCRC( Pkt.TCPIP.DstIP[3] ,fwWork,FCS); // SrcIP
// UDP ----------------------------------------------------------------------
hwSndCRC(Hi(Pkt.TCPIP.SrcPort ),fwWork,FCS); // Src Port
hwSndCRC(Lo(Pkt.TCPIP.SrcPort ),fwWork,FCS); //
hwSndCRC(Hi(Pkt.TCPIP.DstPort ),fwWork,FCS); // Dst Port
hwSndCRC(Lo(Pkt.TCPIP.DstPort ),fwWork,FCS); //
hwSndCRC(Hi(Pkt.TCPIP.Win ),fwWork,FCS); // UDP Len
hwSndCRC(Lo(Pkt.TCPIP.Win ),fwWork,FCS); //
hwSndCRC(Hi(Pkt.TCPIP.ChkSumTCP),fwWork,FCS); // ChkSum
hwSndCRC(Lo(Pkt.TCPIP.ChkSumTCP),fwWork,FCS); //
// TCP Data
If Pkt.Data.Len > 0 then
For Lp := 0 to Pkt.Data.Len-1 do
hwSndCRC(Pkt.Data.Data[Lp],fwWork,FCS);
//
CRC_PPP(fwEnd ,0,FCS);
// FCS
hwSnd(Hi(FCS) );
hwSnd(Lo(FCS) );
hwSnd(_cPPPFlag);
// Help...
// Dbg('Snd:'+_gDStr);
Help_TCP('Snd:',Pkt);
end;
//
Function DNS_IpPos (Const Buf : TPktData) : Word;
Var
Lp : Integer;
Cnt : Integer;
Inx : integer;
DType : Word;
DLen : Word;
begin
//
Result := 0;
If Buf.Len <= 12 then Exit;
If Not( ( (Buf.Data[2] and $80) = $80 ) and // Answer
( (Buf.Data[5] and $01) = $01 ) and // Question
( Buf.Data[7] > $01 ) ) then
Exit;
//
Cnt := Buf.Data[7];
Inx := 0;
For Lp := 12 to Buf.Len-1 do
If Buf.Data[Lp] = 0 then
begin
Inx := Lp + 5 ; // Name Position
Break;
end;
//
For Lp := 1 to Cnt do
begin
Case Buf.Data[Inx] = $C0 of
True : Begin // Compress
Inc(Inx,2);
Move(Buf.Data[Inx],DType,2); // Read Type
End;
False: For DType := Inx to Buf.Len-1 do
If Buf.Data[DType] = 0 then
begin
Inx := DType+1;
Move(Buf.Data[Inx],DType,2); // Read Type
Break;
end;
End;
DType := Swap(DType);
//
Case DType <> 1 of
True : begin
Inc(Inx,8); // Class,TLL,Data
Move(Buf.Data[Inx],DLen,2); // Read Data Len
DLen := Swap(DLen);
Inc(Inx,2+DLen); // Len + Data
end;
False: begin
Inc(Inx,8); // Class,TLL,Data
Move(Buf.Data[Inx],DLen,2);
DLen := Swap(DLen);
Case DLen of
4 : begin
Inc(Inx,2);
Result := Inx;
Exit;
end;
else Inc(Inx,2+DLen); // Len + Data
End;
end;
End;
end;
end;
//
Procedure TCP_Send (Var Pkt : TPkt);
Var
FCS : Word;
Lp : Word;
begin
//
hwSnd (_cPPPFlag); // 7E
hwSndCRC($FF ,fwStart,FCS); // Protocol
hwSndCRC($03 ,fwWork ,FCS); // Control
hwSndCRC($00 ,fwWork ,FCS); // TCP/IP
hwSndCRC($21 ,fwWork ,FCS); //
// IP ------------------------------------------------------------
hwSndCRC($45 ,fwWork ,FCS); // VerLen
hwSndCRC($00 ,fwWork ,FCS); // TOS
hwSndCRC(Hi(Pkt.TCPIP.Length ),fwWork ,FCS); // Len ( IP + TCP + Data.Len )
hwSndCRC(Lo(Pkt.TCPIP.Length ),fwWork ,FCS); //
hwSndCRC(Hi(Pkt.TCPIP.ID ),fwWork ,FCS); // ID
hwSndCRC(Lo(Pkt.TCPIP.ID ),fwWork ,FCS); //
hwSndCRC(Hi(Pkt.TCPIP.FlagIP ),fwWork ,FCS); // FlagIP (3:13)
hwSndCRC(Lo(Pkt.TCPIP.FlagIP ),fwWork ,FCS); //
hwSndCRC( Pkt.TCPIP.TTL ,fwWork ,FCS); // TTL
hwSndCRC( Pkt.TCPIP.Protocol ,fwWork ,FCS); // Protocol
hwSndCRC(Hi(Pkt.TCPIP.ChkSumIP ),fwWork ,FCS); // IP Check Sum
hwSndCRC(Lo(Pkt.TCPIP.ChkSumIP ),fwWork ,FCS); // IP Check Sum
hwSndCRC( Pkt.TCPIP.SrcIP[0] ,fwWork ,FCS); // SrcIP
hwSndCRC( Pkt.TCPIP.SrcIP[1] ,fwWork ,FCS); // SrcIP
hwSndCRC( Pkt.TCPIP.SrcIP[2] ,fwWork ,FCS); // SrcIP
hwSndCRC( Pkt.TCPIP.SrcIP[3] ,fwWork ,FCS); // SrcIP
hwSndCRC( Pkt.TCPIP.DstIP[0] ,fwWork ,FCS); // SrcIP
hwSndCRC( Pkt.TCPIP.DstIP[1] ,fwWork ,FCS); // SrcIP
hwSndCRC( Pkt.TCPIP.DstIP[2] ,fwWork ,FCS); // SrcIP
hwSndCRC( Pkt.TCPIP.DstIP[3] ,fwWork ,FCS); // SrcIP
// TCP --------------------------------------------------------
hwSndCRC(Hi(Pkt.TCPIP.SrcPort) ,fwWork ,FCS); // Src Port
hwSndCRC(Lo(Pkt.TCPIP.SrcPort) ,fwWork ,FCS); //
hwSndCRC(Hi(Pkt.TCPIP.DstPort) ,fwWork ,FCS); // Dst Port
hwSndCRC(Lo(Pkt.TCPIP.DstPort) ,fwWork ,FCS); //
hwSndCRC( Pkt.TCPIP.SegNum[0] ,fwWork ,FCS); // Seg Num.
hwSndCRC( Pkt.TCPIP.SegNum[1] ,fwWork ,FCS); //
hwSndCRC( Pkt.TCPIP.SegNum[2] ,fwWork ,FCS); //
hwSndCRC( Pkt.TCPIP.SegNum[3] ,fwWork ,FCS); //
hwSndCRC( Pkt.TCPIP.Ack [0] ,fwWork ,FCS); // Ack
hwSndCRC( Pkt.TCPIP.Ack [1] ,fwWork ,FCS); //
hwSndCRC( Pkt.TCPIP.Ack [2] ,fwWork ,FCS); //
hwSndCRC( Pkt.TCPIP.Ack [3] ,fwWork ,FCS); //
hwSndCRC( Pkt.TCPIP.HLen ,fwWork ,FCS); // Header Len (4*X)
hwSndCRC( Pkt.TCPIP.FlagTCP ,fwWork ,FCS); //
hwSndCRC(Hi(Pkt.TCPIP.Win ),fwWork ,FCS); // Win
hwSndCRC(Lo(Pkt.TCPIP.Win ),fwWork ,FCS); //
hwSndCRC(Hi(Pkt.TCPIP.ChkSumTCP),fwWork ,FCS); // TCP Check Sum
hwSndCRC(Lo(Pkt.TCPIP.ChkSumTCP),fwWork ,FCS); //
hwSndCRC(Hi(Pkt.TCPIP.Urgent ),fwWork ,FCS); // Urgent
hwSndCRC(Lo(Pkt.TCPIP.Urgent ),fwWork ,FCS); //
// TCP Data
If Pkt.Data.Len > 0 then
For Lp := 0 to Pkt.Data.Len-1 do
hwSndCRC(Pkt.Data.Data[Lp],fwWork,FCS);
//
CRC_PPP(fwEnd ,0,FCS);
// FCS
hwSnd(Hi(FCS) );
hwSnd(Lo(FCS) );
hwSnd(_cPPPFlag);
// Help...
// Dbg('Snd:'+_gDStr);
Help_TCP('Snd:',Pkt);
end;
//
Procedure TCP_Open (Var Pkt : TPkt; Ip : TBuf4; Port : Word; Flag : Byte);
Var
Sav4 : TBuf4;
Len : Word;
begin
//
Pkt.Env.TCPState := tsOpen;
// IP 설정 ------------------------------------------------------------------
Pkt.TCPIP.VerLen := $45;
Pkt.TCPIP.TOS := $00;
Pkt.TCPIP.Length := $2C;
Pkt.TCPIP.ID := $4040; // 3D31;
Pkt.TCPIP.FlagIP := $4000;
Pkt.TCPIP.TTL := $40;
Pkt.TCPIP.Protocol := _cIP_TCP;
Pkt.TCPIP.SrcIp := Pkt.Env.IPClient; // B2Buf4($0A,$17,$06,$04); //
Pkt.TCPIP.DstIP := IP; // B2Buf4($76,$21,$72,$E8);
// TCP 설정 -----------------------------------------------------------------
Pkt.TCPIP.SrcPort := $764A;
Pkt.TCPIP.DstPort := Port;
Case (Flag and _cSyn) = _cSyn of
True : begin
Pkt.TCPIP.SegNum := B2Buf4($00,$42,$24,$5C);
Pkt.TCPIP.Ack := B2Buf4($00,$00,$00,$00);
end;
False: begin
Sav4 := Pkt.TCPIP.SegNum; // Ack,Seq Swap
Pkt.TCPIP.SegNum := Pkt.TCPIP.Ack;
Pkt.TCPIP.Ack := Sav4;
//
Len := Pkt.TCPIP.HLen shr 4;
Case Len > 5 of
True : Len := (Len-5)*4;
False : Len := 0;
End;
Pkt.TCPIP.Ack := DWToB4(B4ToDW(Pkt.TCPIP.ACk)+
Pkt.Data.Len - Len);
end;
End;
Pkt.TCPIP.FlagTCP := Flag;
Pkt.TCPIP.Win := $01FF; // Buffer 사이즈
Pkt.TCPIP.Urgent := $0000;
// ------------------------------------------------------------------
Case (Flag and _cSyn) = _cSyn of
True : begin
Pkt.TCPIP.HLen := $60;
Pkt.Data.Len := 4;
Pkt.Data.Data[0] := $02;
Pkt.Data.Data[1] := $04;
Pkt.Data.Data[2] := $00;
Pkt.Data.Data[3] := $D2;
end;
False: begin
Pkt.TCPIP.HLen := $50;
Pkt.Data.Len := 0;
end;
End;
// Check Sum ----------------------------------------------------------------
Pkt.TCPIP.ChkSumIP := CRC_TCPUDP(Pkt,ctIP );
Pkt.TCPIP.ChkSumTCP := CRC_TCPUDP(Pkt,ctTCP);
//
TCP_Send(Pkt);
end;
//
Procedure TCP_Reply(Var Pkt : TPkt);
Var
Lp : Byte;
Sav4 : TBuf4;
Sav2 : Word;
Len : Integer;
begin
_gDStr := '';
//
If Pkt.TCPIP.Protocol = _cIP_UDP then
begin
Dbg('### Rcv UDP , Pass... ###');
Exit;
end;
// ---------------------------------------------------------------
Case Pkt.Env.TCPState of
tsOpen : Begin
// IP 관련 설정 ---------------------------------------------------
Pkt.TCPIP.ID := $3D32;
Pkt.TCPIP.FlagIP := $4000;
Pkt.TCPIP.TTL := $40;
Pkt.TCPIP.Protocol := _cIP_TCP;
Sav4 := Pkt.TCPIP.SrcIP; // IP Swap
Pkt.TCPIP.SrcIp := Pkt.TCPIP.DstIP;
Pkt.TCPIP.DstIP := Sav4;
// TCP 관련 설정 --------------------------------------------------
Sav2 := Pkt.TCPIP.SrcPort; // Port Swap
Pkt.TCPIP.SrcPort := Pkt.TCPIP.DstPort;
Pkt.TCPIP.DstPort := Sav2;
Sav4 := Pkt.TCPIP.SegNum; // Ack,Seq Swap
Pkt.TCPIP.SegNum := Pkt.TCPIP.Ack;
Pkt.TCPIP.Ack := Sav4;
Pkt.TCPIP.HLen := $50;
Pkt.TCPIP.Win := $01FF; // Buffer 사이즈
//
Pkt.Data.Len := 0;
Pkt.TCPIP.Length := 20 + 20 + Pkt.Data.Len;
//
Case (Pkt.TCPIP.FlagTCP and _cSyn) = _cSyn of
True : Begin
Pkt.TCPIP.Ack := DWToB4(B4ToDW(Pkt.TCPIP.Ack)+1);
Pkt.Env.TCPState := tsWork;
Pkt.TcpIp.FlagTCP := _cAck;
Dbg('### TCP/IP : Open / ');
End;
False: Begin
Dbg('### TCP/IP : Open / Exit #### 문제 발생 #### ');
Pkt.TCPIP.Ack := DWToB4(B4ToDW(Pkt.TCPIP.Ack)+1);
Pkt.Env.TCPState := tsWork;
Pkt.TcpIp.FlagTCP := _cAck;
End;
End;
End;
tsWork : Begin
Exit;
Len := Pkt.TCPIP.HLen shr 4;
Case Len > 5 of
True : Len := (Len-5)*4;
False : Len := 0;
End;
Pkt.TCPIP.Ack := DWToB4(B4ToDW(Pkt.TCPIP.ACk)+
Pkt.Data.Len - Len);
Pkt.TcpIp.FlagTCP := _cAck;
Dbg('### TCP/IP : Work ' +
IntToStr(Pkt.Data.Len));
//
Pkt.Data.Len := 0;
Pkt.TCPIP.Length := 20 + 20 + Pkt.Data.Len;
End;
End;
//
Pkt.TCPIP.ChkSumIP := CRC_TCPUDP(Pkt,ctIP );
Pkt.TCPIP.ChkSumTCP := CRC_TCPUDP(Pkt,ctTCP);
//
TCP_Send(Pkt);
end;
//
Procedure ppp_Init (Var Pkt : TPkt);
begin
Pkt.iEscaped := False;
Pkt.iInx := 0;
//FillChar(Pkt.Env,SizeOf(Pkt.Env),#0);
Pkt.State := psStart;
Pkt.Frame.State := sfCode;
Pkt.TcpIp.State := stVerLen;
//
Pkt.Type_ := ptLCP;
end;
//
Procedure Frame_Receive (Var Pkt : TPkt;InData : Byte);
begin
//
Case Pkt.Frame.State of
sfCode : Begin
Pkt.Frame.Code := InData;
Pkt.Frame.State := sfID;
End;
sfID : Begin
Pkt.Frame.ID := InData;
Pkt.Frame.State := sfLen;
Pkt.iInx := 0;
End;
sfLen : Begin
Case Pkt.iInx of
0 : Pkt.Frame.Len := InData;
1 : Pkt.Frame.Len := (Pkt.Frame.Len shl 8) or InData;
End;
Inc(Pkt.iInx);
If Pkt.iInx >= 2 then
begin
Pkt.Frame.State := sfData;
Pkt.Data.Len := 0;
end;
End;
sfData : Begin
Pkt.Data.Data[Pkt.Data.Len] := InData;
Inc(Pkt.Data.Len);
// 4 = Code[1] + ID[1] + Len[2]
If Pkt.Data.Len >= (Pkt.Frame.Len - 4) then
begin
Pkt.State := psFCS;
Pkt.iInx := 0;
end;
End;
End;
end;
Function Hdr_Len(Protocol : Byte ) : Byte;
begin
//
Result := 40;
If Protocol = _cIP_UDP then
Result := 28;
end;
//
Procedure TCP_Receive(Var Pkt : TPkt;InData : Byte);
Var
ChkSum : Word;
begin
//
Case Pkt.TcpIp.State of
// IP -----------------------------------------------------
stVerLen : Begin
Pkt.TcpIp.VerLen := InData;
Pkt.TcpIp.State := stTOS;
End;
stTOS : Begin
Pkt.TcpIp.TOS := InData;
Pkt.TcpIp.State := stLen;
Pkt.iInx := 0;
End;
stLen : Case Pkt.iInx of
0 : Begin
Pkt.TcpIp.Length := InData;
Inc(Pkt.iInx);
End;
1 : Begin
Pkt.TcpIp.Length := (Pkt.TcpIp.Length shl 8) or InData;
Pkt.TcpIp.State := stID;
Pkt.iInx := 0;
End;
End;
stID : Case Pkt.iInx of
0 : Begin
Pkt.TcpIp.ID := InData;
Inc(Pkt.iInx);
End;
1 : Begin
Pkt.TcpIp.ID := (Pkt.TcpIp.ID shl 8) or InData;
Pkt.TcpIp.State := stFlagIP;
Pkt.iInx := 0;
End;
End;
stFlagIP : Case Pkt.iInx of
0 : Begin
Pkt.TcpIp.FlagIP := InData;
Inc(Pkt.iInx);
End;
1 : Begin
Pkt.TcpIp.FlagIP := (Pkt.TcpIp.FlagIP shl 8) or InData;
Pkt.TcpIp.State := stTTL;
Pkt.iInx := 0;
End;
End;
stTTL : Begin
Pkt.TcpIp.TTL := InData;
Pkt.TcpIp.State := stProtocol;
End;
stProtocol : Begin
Pkt.TcpIp.Protocol := InData;
Pkt.TcpIp.State := stChkSumIP;
Pkt.iInx := 0;
End;
stChkSumIP : Case Pkt.iInx of
0 : begin
Pkt.TcpIp.ChkSumIP := InData;
Inc(Pkt.iInx);
end;
1 : begin
Pkt.TcpIp.ChkSumIP := (Pkt.TcpIp.ChkSumIP shl 8) or InData;
Pkt.TcpIp.State := stSrcIP;
Pkt.iInx := 0;
end;
End;
stSrcIP : Begin
Pkt.TcpIp.SrcIP[Pkt.iInx] := InData;
Inc(Pkt.iInx);
If Pkt.iInx >= 4 then
begin
Pkt.TcpIp.State := stDstIP;
Pkt.iInx := 0;
end;
End;
stDstIP : Begin
Pkt.TcpIp.DstIP[Pkt.iInx] := InData;
Inc(Pkt.iInx);
If Pkt.iInx >= 4 then
begin
Pkt.TcpIp.State := stSrcPort;
Pkt.iInx := 0;
end;
End;
// TCP ---------------------------------------------------------
stSrcPort : Case Pkt.iInx of
0 : Begin
Pkt.TcpIp.SrcPort := InData;
Inc(Pkt.iInx);
End;
1 : Begin
Pkt.TcpIp.SrcPort := (Pkt.TcpIp.SrcPort shl 8) or InData;
Pkt.TcpIp.State := stDstPort;
Pkt.iInx := 0;
End;
End;
stDstPort : Case Pkt.iInx of
0 : Begin
Pkt.TcpIp.DstPort := InData;
Inc(Pkt.iInx);
End;
1 : Begin
Pkt.TcpIp.DstPort := (Pkt.TcpIp.DstPort shl 8) or InData;
Pkt.iInx := 0;
//
Case Pkt.TcpIp.Protocol of
_cIP_TCP : Pkt.TcpIp.State := stSeqNum;
_cIP_UDP : Pkt.TcpIp.State := stWin;
End;
End;
End;
stSeqNum : Begin
Pkt.TcpIp.SegNum[Pkt.iInx] := InData;
Inc(Pkt.iInx);
If Pkt.iInx >= 4 then
begin
Pkt.TcpIp.State := stAck;
Pkt.iInx := 0;
end;
End;
stAck : Begin
Pkt.TcpIp.Ack[Pkt.iInx] := InData;
Inc(Pkt.iInx);
If Pkt.iInx >= 4 then
begin
Pkt.TcpIp.State := stHLen;
Pkt.iInx := 0;
end;
End;
stHLen : Begin
Pkt.TcpIp.HLen := InData;
Pkt.TcpIp.State := stFlagTCP;
End;
stFlagTCP : Begin
Pkt.TcpIp.FlagTCP := InData;
Pkt.TcpIp.State := stWin;
Pkt.iInx := 0;
End;
stWin : Case Pkt.iInx of
0 : Begin
Pkt.TcpIp.Win := InData;
Inc(Pkt.iInx);
End;
1 : Begin
Pkt.TcpIp.Win := (Pkt.TcpIp.Win shl 8) or InData;
Pkt.TcpIp.State := stChkSumTCP;
Pkt.iInx := 0;
End;
End;
stChkSumTCP: Case Pkt.iInx of
0 : Begin
Pkt.TcpIp.ChkSumTCP := InData;
Inc(Pkt.iInx);
End;
1 : Begin
Pkt.TcpIp.ChkSumTCP := (Pkt.TcpIp.ChkSumTCP shl 8) or InData;
Pkt.iInx := 0;
Pkt.Data.Len := 0;
//
Case Pkt.TcpIp.Protocol of
_cIP_TCP : Pkt.TcpIp.State := stUrgent;
_cIP_UDP : Pkt.TcpIp.State := stData;
End;
End;
End;
stUrgent : Case Pkt.iInx of
0 : Begin
Pkt.TcpIp.Urgent := InData;
Inc(Pkt.iInx);
End;
1 : Begin
Pkt.TcpIp.Urgent := (Pkt.TcpIp.Urgent shl 8) or InData;
Pkt.TcpIp.State := stData;
Pkt.iInx := 0;
Pkt.Data.Len := 0;
If Pkt.TcpIp.Length = Hdr_Len(Pkt.TcpIp.Protocol) then
begin
Pkt.State := psFCS;
Pkt.iInx := 0;
end;
End;
End;
stData : Begin
Pkt.Data.Data[Pkt.Data.Len] := InData;
Inc(Pkt.Data.Len);
If Pkt.Data.Len >= (Pkt.TCPIP.Length - Hdr_Len(Pkt.TcpIp.Protocol)) then
begin
Pkt.State := psFCS;
Pkt.iInx := 0;
//
ChkSum := CRC_TcpUDP(Pkt,ctIP);
If Pkt.TCPIP.ChkSumIP <> ChkSum then
Dbg('#### Err IP CRC : Pkt:' + W2H(Pkt.TCPIP.ChkSumIP) +
'/Calc:' + W2H(ChkSum));
//
Case Pkt.TCPIP.Protocol of
_cIP_TCP : ChkSum := CRC_TcpUDP(Pkt,ctTCP);
_cIP_UDP : ChkSum := CRC_TcpUDP(Pkt,ctUDP);
End;
If Pkt.TCPIP.ChkSumTCP <> ChkSum then
Dbg('#### Err TCP/UDP CRC : Pkt:' + W2H(Pkt.TCPIP.ChkSumTCP) +
'/Calc:' + W2H(ChkSum));
end;
End;
End;
end;
//
Function ppp_Receive(Var Pkt : TPkt; InData : Byte) : Boolean;
begin
//
Result := False;
// Process Escape Sequence --------------------------------------------------
If InData = _cEscape then begin
Pkt.iEscaped := True;
Exit;
end;
If Pkt.iEscaped then begin
InData := InData xor $20;
Pkt.iEscaped := False;
end;
// State --------------------------------------------------------------------
Case Pkt.State of
psStart : If InData = _cPPPFlag then
begin
ppp_Init(_gPkt);
Pkt.State := psAddr;
end;
psAddr : // $7E $FF $03 $C0 $21 : LCP
// $7E $80 $21 : IPCP
// $7E $21 : TCP,IP
// $7E $FF $03 $00 $2F : Uncomp TCP/IP
// $7E $2F : Uncomp TCP/IP
// $7E $FF $03 $00 $2D : Comp TCP/IP
// $7E $2D : Comp TCP/IP
Case InData of
$21, // UnCompressed
$2F, // UnCompressed
$2D : // Compressed
begin
Pkt.Type_ := ptTCP;
Pkt.State := psData;
CRC_PPP(fwStart,InData,Pkt.iFCS);
end;
$7E : ;
$80 : begin
Pkt.iInx := 0;
Pkt.iBuf[Pkt.iInx] := InData;
Inc(Pkt.iInx);
Pkt.State := psProtocol;
CRC_PPP(fwStart,InData,Pkt.iFCS);
end;
$FF : begin
Pkt.Type_ := ptNone;
Pkt.State := psControl;
CRC_PPP(fwStart,InData,Pkt.iFCS);
end
else Pkt.State := psStart;
End;
psControl : Begin
Pkt.State := psProtocol;
Pkt.iInx := 0;
CRC_PPP(fwWork,InData,Pkt.iFCS);
End;
psProtocol: Begin
Pkt.iBuf[Pkt.iInx] := InData;
//
CRC_PPP(fwWork ,InData,Pkt.iFCS);
//
Inc(Pkt.iInx);
If Pkt.iInx >= 2 then
Begin
//
Case (Pkt.iBuf[0] shl 8) or
(Pkt.iBuf[1] ) of
_cPktLCP : Pkt.Type_ := ptLCP; // LCP
_cPktCHAP : Pkt.Type_ := ptChap; // Chap
_cPktIPCP : Pkt.Type_ := ptIPCP; // IPCP
$0021, // UnComp
$002F, // UnComp
_cPktCTCP : // Comp
Pkt.Type_ := ptTCP; // TCP,UDP
else Pkt.State := psStart;
end;
//
If Pkt.State <> psStart then
Pkt.State := psData;
End;
End;
psData : // 타입별로 Parsing
Begin
Case Pkt.Type_ of
ptLCP,
ptChap,
ptIPCP : Frame_Receive(Pkt,InData);
ptTCP : TCP_Receive (Pkt,InData);
else Pkt.State := psStart;
End;
CRC_PPP(fwWork,InData,Pkt.iFCS);
End;
psFCS : Begin
Pkt.iBuf[Pkt.iInx] := InData;
Inc(Pkt.iInx);
If Pkt.iInx >= 2 then
begin
CRC_PPP(fwEnd,InData,Pkt.iFCS);
Pkt.rFCS := (Pkt.iBuf[0] shl 8) or
(Pkt.iBuf[1] );
Pkt.State := psStop;
If Pkt.iFCS <> Pkt.rFCS then
Dbg('#### Err FCS : Pkt:'+W2H(Pkt.iFCS)+
'/Calc:'+W2H(Pkt.rFCS));
end;
End;
psStop : //
Begin
Pkt.State := psStart;
If InData = _cPPPFlag then
Result := True;
End;
End;
end;
Function ppp_process (Var Pkt : TPkt; InData : Byte) : Boolean;
Var
Lp : Integer;
begin
Result := PPP_Receive(Pkt,InData);
If Result then
Begin
// 받은 패킷 보여주고...
Help_Pkt('Rcv:',_gPkt);
//
Case _gPkt.Type_ of
ptLCP : Case _gPkt.Frame.Code of
_cConf_Req : begin
Case Pkt.iStep of
ns0_Init : begin
Dbg('Snd LCP Request / 신규 채널 ##');
hwSndBuf(@_cLCP_Req,SizeOf(_cLCP_Req));
end;
End;
// 처음 패킷 응답
Reply_LCP(Pkt.iStep,_gPkt);
Pkt.iStep := ns1_LCP_Req;
end;
_cConf_Ack : Begin
Dbg('####### Chap Send XXXXXXXXX');
hwSndBuf(@_cChap_Res,SizeOf(_cChap_Res));
//For Lp := 0 to 10 do
// begin
// Sleep(20);
// Application.ProcessMessages;
// end;
//Dbg('####### LCP 종료/ IPCP Request 보냄 #1 ###');
//hwSndBuf(@_cIPCP_Req,SizeOf(_cIPCP_Req));
End;
End;
ptChap : Case _gPkt.Frame.Code of
_cConf_Req : Dbg('Rcv Chap Req ');
_cConf_Ack : Dbg('Rcv Chap Ack ');
End;
ptIPCP : Reply_IPCP(Pkt.iStep,_gPkt);
ptTCP : TCP_Reply (_gPkt);
End;
End;
end;
Procedure Send_IPCP_Req;
begin
Dbg('####### 수동 IPCP Request 보냄 #1 ###');
hwSndBuf( @_cIPCP_Req2,
SizeOf(_cIPCP_Req2));
end;
Initialization
FillChar(_gPkt.Env,SizeOf(_gPkt.Env),#0);
ppp_Init(_gPkt);
end.
댓글 없음:
댓글 쓰기