100 lines
2.4 KiB
ObjectPascal
100 lines
2.4 KiB
ObjectPascal
unit eth2;
|
|
|
|
interface
|
|
|
|
uses
|
|
lmemorymanager, util,
|
|
tracer,
|
|
nettypes, netutils,
|
|
net,
|
|
netlog,
|
|
console;
|
|
|
|
procedure send(p_data : void; p_len : uint16; p_context : PPacketContext);
|
|
procedure registerType(eType : uint16; RecvCB : TRecvCallback);
|
|
procedure register;
|
|
|
|
implementation
|
|
|
|
uses
|
|
arp;
|
|
|
|
var
|
|
Registered : Boolean = false;
|
|
EthTypes : Array[0..65535] of TRecvCallback;
|
|
MAC : puint8;
|
|
|
|
procedure registerType(eType : uint16; RecvCB : TRecvCallback);
|
|
begin
|
|
push_trace('eth2.registerType');
|
|
register;
|
|
if EthTypes[eType] = nil then EthTypes[eType]:= RecvCB;
|
|
pop_trace;
|
|
end;
|
|
|
|
procedure send(p_data : void; p_len : uint16; p_context : PPacketContext);
|
|
var
|
|
buffer : void;
|
|
hdr : TEthernetHeader;
|
|
|
|
begin
|
|
push_trace('eth2.send');
|
|
writeToLogLn(' L2: eth2.send');
|
|
if p_context <> nil then begin
|
|
buffer:= kalloc(p_len + sizeof(TEthernetHeader));
|
|
copyMAC(@p_context^.MAC.Source[0], @hdr.src[0]);
|
|
copyMAC(@p_context^.MAC.Destination[0], @hdr.dst[0]);
|
|
hdr.EthTypeHi:= 0;
|
|
hdr.EthTypeLo:= 1;
|
|
memcpy(uint32(@hdr), uint32(buffer), sizeof(TEthernetHeader));
|
|
memcpy(uint32(p_data), uint32(buffer+sizeof(TEthernetHeader)), p_len);
|
|
net.send(buffer, p_len + sizeof(TEthernetHeader));
|
|
kfree(buffer);
|
|
end;
|
|
end;
|
|
|
|
procedure recv(p_data : void; p_len : uint16; p_context : PPacketContext);
|
|
var
|
|
Header : PEthernetHeader;
|
|
proto_type : uint16;
|
|
buf : puint8;
|
|
|
|
begin
|
|
push_trace('eth2.recv');
|
|
writeToLogLn(' L2: eth2.recv');
|
|
buf:= puint8(p_data);
|
|
|
|
Header:= PEthernetHeader(buf);
|
|
proto_type:= Header^.EthTypeHi SHL 8;
|
|
proto_type:= proto_type + Header^.EthTypeLo;
|
|
buf:= buf + 14;
|
|
|
|
copyMAC(@Header^.src[0], @p_context^.MAC.Source[0]);
|
|
copyMAC(@Header^.dst[0], @p_context^.MAC.Destination[0]);
|
|
|
|
if MACEqual(@Header^.dst[0], @Header^.src[0]) or MACEqual(@Header^.dst[0], @BROADCAST_MAC[0]) then begin
|
|
if EthTypes[proto_type] <> nil then begin
|
|
EthTypes[proto_type](void(buf), p_len - 14, p_context);
|
|
end;
|
|
end;
|
|
pop_trace;
|
|
end;
|
|
|
|
procedure register;
|
|
var
|
|
i : uint16;
|
|
|
|
begin
|
|
push_trace('eth2.register');
|
|
if not Registered then begin
|
|
for i:=0 to 65535 do begin
|
|
EthTypes[i]:= nil;
|
|
end;
|
|
net.registerNextLayer(@recv);
|
|
MAC:= net.getMAC;
|
|
Registered:= true;
|
|
end;
|
|
pop_trace;
|
|
end;
|
|
|
|
end. |