E1000 Driver & Net Stack

- E1000 Driver Near Finished
- Network stack added (Eth->IPv4)
- Other Stuff
- Things.
- This commit message needs to be longer to make it look like I'm doing more work than I actually am.
- Other things.

git-svn-id: https://spexeah.com:8443/svn/Asuro@456 6dbc8c32-bb84-406f-8558-d1cf31a0ab0c
This commit is contained in:
kieron
2018-04-09 20:34:39 +00:00
parent db8376875b
commit d98a81b540
79 changed files with 332 additions and 42 deletions

11
src/driver/net/arp.pas Normal file
View File

@ -0,0 +1,11 @@
unit arp;
interface
uses
nettypes, netutils,
eth2;
implementation
end.

View File

@ -3,8 +3,11 @@ unit eth2;
interface
uses
net, nettypes, console;
nettypes, netutils,
net,
console;
procedure registerType(eType : uint16; RecvCB : TRecvCallback);
procedure register;
implementation
@ -16,21 +19,40 @@ var
procedure registerType(eType : uint16; RecvCB : TRecvCallback);
begin
register;
if EthTypes[eType] = nil then EthTypes[eType]:= RecvCB;
end;
procedure recv(p_data : void; p_len : uint16);
var
src, dst : puint8;
Header : PEthernetHeader;
proto_type : uint16;
buf : puint8;
begin
dst:= puint8(p_data);
src:= puint8(p_data + 6);
console.outputln('net.eth2', 'RECV.');
buf:= puint8(p_data);
Header:= PEthernetHeader(buf);
console.output('net.eth2', 'DEST: ');
writeMACAddress(dst);
writeMACAddress(@Header^.dst[0]);
console.output('net.eth2', 'SRC: ');
writeMACAddress(src);
writeMACAddress(@Header^.src[0]);
proto_type:= Header^.EthTypeHi SHL 8;
proto_type:= proto_type + Header^.EthTypeLo;
console.output('net.eth2', 'PROTO: ');
console.writehexln(proto_type);
buf:= buf + 14;
if MACEqual(@Header^.dst[0], @Header^.src[0]) or MACEqual(@Header^.dst[0], @BROADCAST_MAC[0]) then begin
console.outputln('net.eth2', 'MAC HIT');
if EthTypes[proto_type] <> nil then begin
EthTypes[proto_type](void(buf), p_len - 14);
end;
end;
end;
procedure register;

11
src/driver/net/icmp.pas Normal file
View File

@ -0,0 +1,11 @@
unit icmp;
interface
uses
nettypes, netutils,
ipv4;
implementation
end.

81
src/driver/net/ipv4.pas Normal file
View File

@ -0,0 +1,81 @@
unit ipv4;
interface
uses
util, console,
nettypes, netutils,
eth2;
procedure registerProtocol(Protocol_ID : uint8; recv_callback : TRecvCallback);
procedure register;
implementation
var
Registered : Boolean = false;
Protocols : Array[0..255] of TRecvCallback;
procedure recv(p_data : void; p_len : uint16);
var
Header : PIPV4Header;
AHeader : TIPV4AbstractHeader;
i : Integer;
buf : puint8;
len : uint16;
begin
console.outputln('net.ipv4', 'RECV.');
Header:= PIPV4Header(p_data);
AHeader.version:= Header^.version;
AHeader.header_len:= Header^.header_len;
AHeader.ToS:= Header^.ToS;
AHeader.total_len:= (Header^.total_len_Hi SHL 8) + Header^.total_len_Lo;
AHeader.identifier:= (Header^.identifier_Hi SHL 8) + Header^.identifier_Lo;
AHeader.Flags.RS:= false;
AHeader.Flags.DF:= (Header^.Flags AND $2) > 0;
AHeader.Flags.MF:= (Header^.Flags AND $1) > 0;
AHeader.Fragment_Off:= Header^.Fragment_Off;
AHeader.TTL:= Header^.TTL;
AHeader.Protocol:= Header^.Protocol;
AHeader.HDR_CHK:= (Header^.HDR_CHK_Hi SHL 8) + Header^.HDR_CHK_Lo;
for i:=0 to 3 do begin
AHeader.Src[i]:= Header^.Src[i];
AHeader.Dst[i]:= Header^.Dst[i];
end;
AHeader.Options:= Header^.Options;
console.output('net.ipv4', 'Source: ');
writeIPv4Address(puint8(@AHeader.Src[0]));
console.output('net.ipv4', 'Dest: ');
writeIPv4Address(puint8(@AHeader.Dst[0]));
buf:= puint8(p_data);
buf:= buf + AHeader.header_len;
len:= p_len - AHeader.header_len;
if Protocols[AHeader.Protocol] <> nil then Protocols[AHeader.Protocol](void(buf), len);
end;
procedure register;
var
i : integer;
begin
if not Registered then begin
for i:=0 to 255 do begin
Protocols[i]:= nil;
end;
eth2.registerType($0800, @recv);
Registered:= true;
end;
end;
procedure registerProtocol(Protocol_ID : uint8; recv_callback : TRecvCallback);
begin
register;
if Protocols[Protocol_ID] = nil then Protocols[Protocol_ID]:= recv_callback;
end;
end.

View File

@ -3,7 +3,8 @@ unit net;
interface
uses
nettypes;
console,
nettypes, netutils;
procedure registerNetworkCard(SendCallback : TNetSendCallback; _MAC : puint8);
procedure registerNextLayer(RecvCallback : TRecvCallback);
@ -35,12 +36,13 @@ end;
procedure send(p_data : void; p_len : uint16);
begin
CBSend(p_data, p_len);
if CBSend <> nil then CBSend(p_data, p_len);
end;
procedure recv(p_data : void; p_len : uint16);
begin
CBNext(p_data, p_len);
console.outputln('net', 'RECV.');
if CBNext <> nil then CBNext(p_data, p_len);
end;
function getMAC : puint8;

View File

@ -2,28 +2,64 @@ unit nettypes;
interface
uses
console;
type
TNetSendCallback = function(p_data : void; p_len : uint16) : sint32;
TRecvCallback = procedure(p_data : void; p_len : uint16);
procedure writeMACAddress(mac : puint8);
PEthernetHeader = ^TEthernetHeader;
TEthernetHeader = bitpacked record
dst : array[0..5] of uint8;
src : array[0..5] of uint8;
EthTypeHi : uint8;
EthTypeLo : uint8;
end;
PIPV4Header = ^TIPV4Header;
TIPV4Header = bitpacked record
version : ubit4;
header_len : ubit4;
ToS : uint8;
total_len_Hi : uint8;
total_len_Lo : uint8;
identifier_Hi : uint8;
identifier_Lo : uint8;
Flags : ubit3;
Fragment_Off : ubit13;
TTL : uint8;
Protocol : uint8;
HDR_CHK_Hi : uint8;
HDR_CHK_Lo : uint8;
Src : Array[0..3] of uint8;
Dst : Array[0..3] of uint8;
Options : ubit24;
Padding : uint8;
end;
TTCPFlags = record
RS : Boolean;
DF : Boolean;
MF : Boolean;
end;
TIPV4AbstractHeader = record
version : uint8;
header_len : uint8;
ToS : uint8;
total_len : uint16;
identifier : uint16;
Flags : TTCPFlags;
Fragment_Off : uint16;
TTL : uint8;
Protocol : uint8;
HDR_CHK : uint16;
Src : Array[0..3] of uint8;
Dst : Array[0..3] of uint8;
Options : uint32;
end;
const
BROADCAST_MAC : Array[0..5] of uint8 = ($FF, $FF, $FF, $FF, $FF, $FF);
implementation
procedure writeMACAddress(mac : puint8);
var
i : integer;
begin
console.writehexpair(mac[0]);
for i:=1 to 5 do begin
console.writestring(':');
console.writehexpair(mac[i]);
end;
console.writestringln(' ');
end;
end.

View File

@ -0,0 +1,54 @@
unit netutils;
interface
uses
nettypes, console;
procedure writeMACAddress(mac : puint8);
procedure writeIPv4Address(ip : puint8);
function MACEqual(mac1 : puint8; mac2 : puint8) : boolean;
implementation
function MACEqual(mac1 : puint8; mac2 : puint8) : boolean;
var
i : uint8;
begin
MACEqual:= true;
for i:=0 to 5 do begin
if mac1[i] <> mac2[i] then begin
MACEqual:= false;
exit;
end;
end;
end;
procedure writeIPv4Address(ip : puint8);
var
i : integer;
begin
console.writeint(ip[0]);
for i:=1 to 3 do begin
console.writestring('.');
console.writeint(ip[i]);
end;
console.writestringln(' ');
end;
procedure writeMACAddress(mac : puint8);
var
i : integer;
begin
console.writehexpair(mac[0]);
for i:=1 to 5 do begin
console.writestring(':');
console.writehexpair(mac[i]);
end;
console.writestringln(' ');
end;
end.

11
src/driver/net/tcp.pas Normal file
View File

@ -0,0 +1,11 @@
unit tcp;
interface
uses
nettypes, netutils,
ipv4;
implementation
end.

11
src/driver/net/udp.pas Normal file
View File

@ -0,0 +1,11 @@
unit udp;
interface
uses
nettypes, netutils,
ipv4;
implementation
end.

View File

@ -14,7 +14,8 @@ uses
PCI,
terminal,
net,
nettypes;
nettypes,
netutils;
const
INTEL_VEND = $8086;
@ -146,8 +147,10 @@ var
mac : array[0..5] of uint8;
rx_descs : array[0..E1000_NUM_RX_DESC-1] of PE1000_rx_desc;
tx_descs : array[0..E1000_NUM_TX_DESC-1] of PE1000_tx_desc;
rx_buffs : array[0..E1000_NUM_RX_DESC-1] of puint8;
rx_curr : uint16;
tx_curr : uint16;
mem_aloc : boolean = false;
procedure writeCommand(p_address : uint16; p_value : uint32);
var
@ -269,7 +272,8 @@ begin
descs:= PE1000_rx_desc(ptr);
for i:=0 to E1000_NUM_RX_DESC do begin
rx_descs[i]:= @descs[i];//PE1000_rx_desc(uint32(descs) + i*16);
rx_descs[i]^.address:= uint64(kalloc(8192 + 16));
rx_buffs[i]:= puint8(kalloc(8192 + 16));
rx_descs[i]^.address:= uint64(vtop(uint32(rx_buffs[i])));
rx_descs[i]^.status:= 0;
end;
@ -349,15 +353,15 @@ var
got_packet : boolean;
buf : puint8;
len : uint16;
i : uint16;
begin
while (rx_descs[rx_curr]^.status AND $1) > 0 do begin
got_packet:= true;
buf:= puint8(rx_descs[rx_curr]^.address);
buf:= rx_buffs[rx_curr];
len:= rx_descs[rx_curr]^.length;
//Inject Packet into Network Stack
kpalloc(uint32(buf));
net.recv(void(buf), len);
rx_descs[rx_curr]^.status:= 0;
@ -384,6 +388,8 @@ var
data : uint32;
begin
console.outputln('E1000 Driver', 'FIRED.');
status:= readCommand($C0);
//console.output('E1000 Driver', 'Int Status: ');
//console.writehexln(status);