git-svn-id: https://spexeah.com:8443/svn/Asuro@746 6dbc8c32-bb84-406f-8558-d1cf31a0ab0c
This commit is contained in:
@ -3,7 +3,7 @@ unit serial;
|
||||
interface
|
||||
|
||||
uses
|
||||
util, isrmanager;
|
||||
util, isrmanager, strings;
|
||||
|
||||
const
|
||||
COM1 = $3F8;
|
||||
@ -14,6 +14,7 @@ const
|
||||
procedure init();
|
||||
function receive(PORT : uint16; timeout : uint32) : uint8;
|
||||
function send(PORT : uint16; data : uint8; timeout : uint32) : boolean;
|
||||
function sendString(str : pchar) : boolean;
|
||||
|
||||
implementation
|
||||
|
||||
@ -85,4 +86,17 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
function sendString(str : pchar) : boolean;
|
||||
var
|
||||
i : uint32;
|
||||
|
||||
begin
|
||||
sendString:= true;
|
||||
for i:=0 to StringSize(str)-1 do begin
|
||||
sendString:= sendString AND send(COM1, uint8(str[i]), 10000);
|
||||
end;
|
||||
sendString:= sendString AND send(COM1, uint8(13), 10000);
|
||||
sendString:= sendString AND send(COM1, uint8(10), 10000);
|
||||
end;
|
||||
|
||||
end.
|
@ -22,6 +22,7 @@ function MACToIIPv4(mac : puint8) : puint8;
|
||||
procedure sendGratuitous;
|
||||
procedure sendRequest(ip : puint8);
|
||||
procedure send(hType : uint16; pType : uint16; op : uint16; p_context : PPacketContext);
|
||||
function resolveIP(ip : puint8) : puint8;
|
||||
|
||||
implementation
|
||||
|
||||
@ -67,18 +68,6 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
function findCacheRecord(ip : puint8) : PARPCacheRecord;
|
||||
var
|
||||
CacheRecord : PARPCacheRecord;
|
||||
|
||||
begin
|
||||
CacheRecord:= findCacheRecordByIP(ip);
|
||||
if CacheRecord = nil then begin
|
||||
|
||||
end;
|
||||
findCacheRecord:= CacheRecord;
|
||||
end;
|
||||
|
||||
procedure send(hType : uint16; pType : uint16; op : uint16; p_context : PPacketContext);
|
||||
var
|
||||
buf : void;
|
||||
@ -171,6 +160,21 @@ begin
|
||||
sendRequestGateway(ip);
|
||||
end;
|
||||
|
||||
function resolveIP(ip : puint8) : puint8;
|
||||
var
|
||||
CacheRecord : PARPCacheRecord;
|
||||
|
||||
begin
|
||||
CacheRecord:= findCacheRecordByIP(ip);
|
||||
resolveIP:= nil;
|
||||
if CacheRecord = nil then begin
|
||||
sendRequest(ip);
|
||||
sendRequestGateway(ip);
|
||||
end else begin
|
||||
resolveIP:= @CacheRecord^.MAC[0];
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure recv(p_data : void; p_len : uint16; p_context : PPacketContext);
|
||||
var
|
||||
Header : PARPHeader;
|
||||
|
@ -3,26 +3,114 @@ unit icmp;
|
||||
interface
|
||||
|
||||
uses
|
||||
net, nettypes, netutils, ipv4, console, terminal;
|
||||
bios_data_area,
|
||||
lmemorymanager,
|
||||
net, nettypes, netutils, ipv4, console, terminal, arp, util;
|
||||
|
||||
type
|
||||
TARPErrorCode = (aecFailedToResolveHost, aecNoRouteToHost, aecTimeout, aecTTLExpired);
|
||||
TARPReplyCallback = procedure(hdr : PICMPHeader);
|
||||
TARPErrorCallback = procedure(hdr : PICMPHeader; Reason : TARPErrorCode);
|
||||
TARPHandler = record
|
||||
Active : Boolean;
|
||||
OnReply : TARPReplyCallback;
|
||||
OnError : TARPErrorCallback;
|
||||
end;
|
||||
|
||||
procedure register;
|
||||
procedure sendICMPRequest(ip : puint8; Sequence : uint16; TTL : uint8; OnRep : TARPReplyCallback; OnErr : TARPErrorCallback);
|
||||
|
||||
procedure ping_err(hdr : PICMPHeader; Reason : TARPErrorCode);
|
||||
procedure ping_rep(hdr : PICMPHeader);
|
||||
|
||||
implementation
|
||||
|
||||
var
|
||||
Handlers : Array[0..255] of TARPHandler;
|
||||
|
||||
function nextInactiveHandler : uint8;
|
||||
var
|
||||
i : uint8;
|
||||
|
||||
begin
|
||||
nextInactiveHandler:= 0;
|
||||
for i:=1 to 255 do begin
|
||||
if not Handlers[i].Active then begin
|
||||
nextInactiveHandler:= i;
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure sendResponse(p_context : PPacketContext);
|
||||
begin
|
||||
|
||||
end;
|
||||
|
||||
procedure sendRequest(ip : puint8);
|
||||
procedure sendICMPRequest(ip : puint8; Sequence : uint16; TTL : uint8; OnRep : TARPReplyCallback; OnErr : TARPErrorCallback);
|
||||
var
|
||||
handle : uint8;
|
||||
dest_mac : puint8;
|
||||
context : PPacketContext;
|
||||
Header : PICMPHeader;
|
||||
Buffer : void;
|
||||
CHK : uint16;
|
||||
Size : uint32;
|
||||
|
||||
begin
|
||||
handle:= nextInactiveHandler;
|
||||
Handlers[handle].Active:= true;
|
||||
Handlers[handle].OnReply:= OnRep;
|
||||
Handlers[handle].OnError:= OnErr;
|
||||
if SameSubnetIPv4(ip, @getIPv4Config^.Address[0], @getIPv4Config^.Netmask[0]) then begin
|
||||
dest_mac:= arp.resolveIP(ip);
|
||||
end else begin
|
||||
dest_mac:= arp.resolveIP(@getIPv4Config^.Gateway[0]);
|
||||
end;
|
||||
if dest_mac = nil then begin
|
||||
if Handlers[handle].OnError <> nil then Handlers[handle].OnError(nil, aecFailedToResolveHost);
|
||||
Handlers[handle].Active:= false;
|
||||
end else begin
|
||||
context:= newPacketContext;
|
||||
copyMAC(getMAC, @context^.MAC.Source[0]);
|
||||
copyIPv4(@getIPv4Config^.Address[0], @context^.IP.Source[0]);
|
||||
copyMAC(dest_mac, @context^.MAC.Destination[0]);
|
||||
copyIPv4(ip, @context^.IP.Destination[0]);
|
||||
context^.TTL:= TTL;
|
||||
context^.Protocol.L4:= $01;
|
||||
|
||||
Size:= sizeof(TICMPHeader) + sizeof(ICMP_DATA_GENERIC);
|
||||
Buffer:= kalloc(Size);
|
||||
Header:= PICMPHeader(Buffer);
|
||||
Header^.ICMP_Type:= $08;
|
||||
Header^.ICMP_CHK_Hi:= 0;
|
||||
Header^.ICMP_CHK_Lo:= 0;
|
||||
Header^.Identifier:= handle;
|
||||
Header^.Sequence:= Sequence;
|
||||
|
||||
memcpy(uint32(@ICMP_DATA_GENERIC[0]), uint32(Buffer) + sizeof(TICMPHeader), sizeof(ICMP_DATA_GENERIC));
|
||||
|
||||
CHK:= calculateChecksum(puint16(Buffer), Size);
|
||||
|
||||
Header^.ICMP_CHK_Hi:= CHK AND $FF;
|
||||
Header^.ICMP_CHK_Lo:= CHK SHR 8;
|
||||
|
||||
ipv4.send(Buffer, size, context);
|
||||
|
||||
freePacketContext(context);
|
||||
end;
|
||||
end;
|
||||
|
||||
{procedure sendRequest(ip : puint8);
|
||||
begin
|
||||
|
||||
end;
|
||||
end;}
|
||||
|
||||
procedure recv(p_data : void; p_len : uint16; p_context : PPacketContext);
|
||||
var
|
||||
Header : PICMPHeader;
|
||||
CHK : uint16;
|
||||
Handle : uint8;
|
||||
|
||||
begin
|
||||
writeToLogLn(' L4: icmp.recv');
|
||||
@ -45,13 +133,100 @@ begin
|
||||
end;
|
||||
$00:begin //Reply
|
||||
writeToLogLn(' L4: icmp.reply');
|
||||
Handle:= Header^.Identifier;
|
||||
if (Handle > 0) and (Handle < 256) then begin
|
||||
If Handlers[Handle].Active then begin
|
||||
If Handlers[Handle].OnReply <> nil then Handlers[Handle].OnReply(Header);
|
||||
Handlers[Handle].Active:= false;
|
||||
Handlers[Handle].OnError:= nil;
|
||||
Handlers[Handle].OnReply:= nil;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure register;
|
||||
var
|
||||
PING_T1 : uint64;
|
||||
PING_N : uint16;
|
||||
PING_C : uint16;
|
||||
PING_L : uint32;
|
||||
PING_IP : puint8;
|
||||
|
||||
procedure ping_err(hdr : PICMPHeader; Reason : TARPErrorCode);
|
||||
begin
|
||||
writestringWND('Ping Error: ', getTerminalHWND);
|
||||
case Reason of
|
||||
aecFailedToResolveHost:writestringlnWND('Failed to resolve host.', getTerminalHWND);
|
||||
aecNoRouteToHost:writestringlnWND('No route to host.', getTerminalHWND);
|
||||
aecTimeout:writestringlnWND('Timeout expired.', getTerminalHWND);
|
||||
aecTTLExpired:writestringlnWND('TTL Expired.', getTerminalHWND);
|
||||
end;
|
||||
PING_T1:= Counters.c64;
|
||||
INC(PING_C);
|
||||
if PING_C < PING_N then begin
|
||||
sendICMPRequest(PING_IP, PING_C, 128, @ping_rep, @ping_err);
|
||||
end else begin
|
||||
terminal.done(PING_L);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure ping_rep(hdr : PICMPHeader);
|
||||
var
|
||||
PING_T2 : uint64;
|
||||
|
||||
begin
|
||||
PING_T2:= Counters.c64;
|
||||
writestringWND('Ping Reply: ', getTerminalHWND);
|
||||
writeIntWND(PING_T2-PING_T1, getTerminalHWND);
|
||||
writeStringlnWND('ms.', getTerminalHWND);
|
||||
PING_T1:= PING_T2;
|
||||
INC(PING_C);
|
||||
if PING_C < PING_N then begin
|
||||
sendICMPRequest(PING_IP, PING_C, 128, @ping_rep, @ping_err);
|
||||
end else begin
|
||||
terminal.done(PING_L);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure ping_terminate();
|
||||
begin
|
||||
PING_N:= 0;
|
||||
end;
|
||||
|
||||
procedure terminal_command_ping(Params : PParamList);
|
||||
var
|
||||
ip_str : pchar;
|
||||
ip : puint8;
|
||||
|
||||
begin
|
||||
if ParamCount(Params) > 0 then begin
|
||||
ip_str:= getParam(0, Params);
|
||||
ip:= stringToIPv4(ip_str);
|
||||
if ip <> nil then begin
|
||||
terminal.halt(PING_L, @ping_terminate);
|
||||
PING_L:= Counters.c32;
|
||||
PING_N:= 10;
|
||||
PING_C:= 0;
|
||||
PING_T1:= Counters.c64;
|
||||
PING_IP:= ip;
|
||||
sendICMPRequest(PING_IP, PING_C, 128, @ping_rep, @ping_err);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure register;
|
||||
var
|
||||
i : uint32;
|
||||
|
||||
begin
|
||||
for i:=0 to 255 do begin
|
||||
Handlers[i].Active:= false;
|
||||
Handlers[i].OnError:= nil;
|
||||
Handlers[i].OnReply:= nil;
|
||||
end;
|
||||
ipv4.registerProtocol($01, @recv);
|
||||
terminal.registerCommand('PING', @terminal_command_ping, 'Ping a host.');
|
||||
end;
|
||||
|
||||
end.
|
@ -45,9 +45,7 @@ procedure register();
|
||||
begin
|
||||
if not registered then begin
|
||||
asm
|
||||
mov al, $36
|
||||
out $46, al
|
||||
mov ax, 1165
|
||||
mov ax, 1193
|
||||
out $40, al
|
||||
mov al, ah
|
||||
out $40, al
|
||||
|
Reference in New Issue
Block a user