DHCP Works now.

git-svn-id: https://spexeah.com:8443/svn/Asuro@1034 6dbc8c32-bb84-406f-8558-d1cf31a0ab0c
This commit is contained in:
kieron 2020-07-12 17:02:14 +00:00
parent 46cb414b43
commit fbc59a1617
12 changed files with 389 additions and 166 deletions

View File

@ -92,8 +92,8 @@ end;
procedure send(p_data : void; p_len : uint16); procedure send(p_data : void; p_len : uint16);
begin begin
push_trace('net.send'); //push_trace('net.send');
writeToLogLn('L1: net.send'); //writeToLogLn('L1: net.send');
if CBSend <> nil then CBSend(p_data, p_len); if CBSend <> nil then CBSend(p_data, p_len);
pop_trace; pop_trace;
end; end;
@ -103,8 +103,8 @@ var
context : PPacketContext; context : PPacketContext;
begin begin
push_trace('net.recv'); //push_trace('net.recv');
writeToLogLn('L1: net.recv'); //writeToLogLn('L1: net.recv');
context:= newPacketContext; context:= newPacketContext;
if CBNext <> nil then CBNext(p_data, p_len, context); if CBNext <> nil then CBNext(p_data, p_len, context);
freePacketContext(context); freePacketContext(context);

View File

@ -34,7 +34,6 @@ var
procedure registerTypePromisc(eType : uint16; RecvCB : TRecvCallback); procedure registerTypePromisc(eType : uint16; RecvCB : TRecvCallback);
begin begin
push_trace('eth2.registerType');
register; register;
if EthTypes[eType] = nil then EthTypes[eType]:= RecvCB; if EthTypes[eType] = nil then EthTypes[eType]:= RecvCB;
Promisc[eType]:= true; Promisc[eType]:= true;
@ -42,7 +41,6 @@ end;
procedure registerType(eType : uint16; RecvCB : TRecvCallback); procedure registerType(eType : uint16; RecvCB : TRecvCallback);
begin begin
push_trace('eth2.registerType');
register; register;
if EthTypes[eType] = nil then EthTypes[eType]:= RecvCB; if EthTypes[eType] = nil then EthTypes[eType]:= RecvCB;
end; end;
@ -83,8 +81,7 @@ var
buf : puint8; buf : puint8;
begin begin
push_trace('eth2.recv'); //writeToLogLn(' L2: eth2.recv');
writeToLogLn(' L2: eth2.recv');
buf:= puint8(p_data); buf:= puint8(p_data);
Header:= PEthernetHeader(buf); Header:= PEthernetHeader(buf);
@ -102,7 +99,6 @@ begin
EthTypes[proto_type](void(buf), p_len - 14, p_context); EthTypes[proto_type](void(buf), p_len - 14, p_context);
end; end;
end; end;
pop_trace;
end; end;
procedure register; procedure register;

View File

@ -80,8 +80,6 @@ var
hSize, pSize : uint8; hSize, pSize : uint8;
begin begin
push_trace('arp.send');
writeToLogLn(' L3: arp.send');
if p_context <> nil then begin if p_context <> nil then begin
buf:= kalloc(sizeof(TARPHeader)); buf:= kalloc(sizeof(TARPHeader));
hdr:= PARPHeader(buf); hdr:= PARPHeader(buf);
@ -189,10 +187,6 @@ var
context : PPacketContext; context : PPacketContext;
begin begin
push_trace('arp.recv');
writeToLogLn(' L3: arp.recv');
console.redrawWindows;
{ Get our converted Header } { Get our converted Header }
Header:= PARPHeader(p_data); Header:= PARPHeader(p_data);
AHeader.Hardware_Type:= (Header^.Hardware_Type_Hi SHL 8) + Header^.Hardware_Type_Lo; AHeader.Hardware_Type:= (Header^.Hardware_Type_Hi SHL 8) + Header^.Hardware_Type_Lo;
@ -219,7 +213,6 @@ begin
if IPEqual(@AHeader.Destination_Protocol[0], @getIPv4Config^.Address[0]) then begin if IPEqual(@AHeader.Destination_Protocol[0], @getIPv4Config^.Address[0]) then begin
case AHeader.Operation of case AHeader.Operation of
$1:begin { ARP Request } $1:begin { ARP Request }
writeToLogLn(' arp.recv.arp.req');
context:= newPacketContext; context:= newPacketContext;
copyMAC(@AHeader.Source_Hardware[0], @context^.MAC.Destination[0]); copyMAC(@AHeader.Source_Hardware[0], @context^.MAC.Destination[0]);
copyIPv4(@AHeader.Source_Protocol[0], @context^.IP.Destination[0]); copyIPv4(@AHeader.Source_Protocol[0], @context^.IP.Destination[0]);
@ -229,28 +222,28 @@ begin
freePacketContext(context); freePacketContext(context);
end; end;
$2:begin { ARP Reply } $2:begin { ARP Reply }
writeToLogLn(' arp.recv.arp.rep');
end; end;
$3:begin { RARP Request } $3:begin { RARP Request }
writeToLogLn(' arp.recv.rarp.req');
end; end;
$4:begin { RARP Reply } $4:begin { RARP Reply }
writeToLogLn(' arp.recv.rarp.rep');
end; end;
$5:begin { DRARP Request } $5:begin { DRARP Request }
writeToLogLn(' arp.recv.drarp.req');
end; end;
$6:begin { DRARP Reply } $6:begin { DRARP Reply }
writeToLogLn(' arp.recv.drarp.rep');
end; end;
$7:begin { DRARP Error } $7:begin { DRARP Error }
writeToLogLn(' arp.recv.drarp.err');
end; end;
$8:begin { InARP Request } $8:begin { InARP Request }
writeToLogLn(' arp.recv.inarp.req');
end; end;
$9:begin { InARP Reply } $9:begin { InARP Reply }
writeToLogLn(' arp.recv.inarp.rep');
end; end;
end; end;
end; end;

View File

@ -44,7 +44,6 @@ var
buffer : void; buffer : void;
begin begin
writeToLogLn(' L3: ipv4.send');
inc(CurrentID); inc(CurrentID);
Header.version:= 4; Header.version:= 4;
Header.header_len:= 5; Header.header_len:= 5;
@ -83,8 +82,6 @@ var
len : uint16; len : uint16;
begin begin
push_trace('ipv4.recv');
writeToLogLn(' L3: ipv4.recv');
Header:= PIPV4Header(p_data); Header:= PIPV4Header(p_data);
AHeader.version:= Header^.version; AHeader.version:= Header^.version;
AHeader.header_len:= Header^.header_len; AHeader.header_len:= Header^.header_len;
@ -112,7 +109,7 @@ begin
copyIPv4(@AHeader.Dst[0], @p_context^.IP.Destination[0]); copyIPv4(@AHeader.Dst[0], @p_context^.IP.Destination[0]);
if Config.UP then begin if Config.UP then begin
if (IPEqual(@Config.Address[0], @AHeader.Dst[0])) OR (AHeader.Dst[3] = 255) then begin if (IPEqual(@Config.Address[0], @AHeader.Dst[0])) OR (AHeader.Dst[3] = 255) OR (IPEqual(@Config.Address[0], @NULL_IP[0])) then begin
if Protocols[AHeader.Protocol] <> nil then begin if Protocols[AHeader.Protocol] <> nil then begin
Protocols[AHeader.Protocol](void(buf), len, p_context); Protocols[AHeader.Protocol](void(buf), len, p_context);
end; end;
@ -130,7 +127,6 @@ var
i : uint32; i : uint32;
begin begin
push_trace('ipv4.terminal_command_ifconfig');
if paramCount(params) > 1 then begin if paramCount(params) > 1 then begin
Command:= GetParam(0, Params); Command:= GetParam(0, Params);
if StringEquals(Command, 'set') then begin if StringEquals(Command, 'set') then begin
@ -177,7 +173,6 @@ begin
else else
writestringlnWND(' NetUP: false', getTerminalHWND); writestringlnWND(' NetUP: false', getTerminalHWND);
end; end;
pop_trace;
end; end;
procedure register; procedure register;
@ -205,7 +200,6 @@ end;
procedure registerProtocol(Protocol_ID : uint8; recv_callback : TRecvCallback); procedure registerProtocol(Protocol_ID : uint8; recv_callback : TRecvCallback);
begin begin
push_trace('ipv4.registerProtocol');
register; register;
if Protocols[Protocol_ID] = nil then Protocols[Protocol_ID]:= recv_callback; if Protocols[Protocol_ID] = nil then Protocols[Protocol_ID]:= recv_callback;
pop_trace; pop_trace;

View File

@ -118,12 +118,10 @@ var
Handle : uint8; Handle : uint8;
begin begin
writeToLogLn(' L4: icmp.recv');
Header:= PICMPHeader(p_data); Header:= PICMPHeader(p_data);
//writehexlnWND(Header^.ICMP_Type, getTerminalHWND); //writehexlnWND(Header^.ICMP_Type, getTerminalHWND);
case Header^.ICMP_Type of case Header^.ICMP_Type of
$08:Begin //Request $08:Begin //Request
writeToLogLn(' L4: icmp.request');
contextMACSwitch(p_context); contextMACSwitch(p_context);
contextIPv4Switch(p_context); contextIPv4Switch(p_context);
Header^.ICMP_Type:= 0; Header^.ICMP_Type:= 0;
@ -137,7 +135,6 @@ begin
ipv4.send(p_data, p_len, p_context); ipv4.send(p_data, p_len, p_context);
end; end;
$00:begin //Reply $00:begin //Reply
writeToLogLn(' L4: icmp.reply');
Handle:= Header^.Identifier; Handle:= Header^.Identifier;
if (Handle > 0) and (Handle < 256) then begin if (Handle > 0) and (Handle < 256) then begin
If Handlers[Handle].Active then begin If Handlers[Handle].Active then begin

View File

@ -123,20 +123,6 @@ begin
memcpy(uint32(hdr), uint32(buffer), sizeof(TUDPHeader)); memcpy(uint32(hdr), uint32(buffer), sizeof(TUDPHeader));
memcpy(uint32(p_data), uint32(buffer) + sizeof(TUDPHeader), p_len); memcpy(uint32(p_data), uint32(buffer) + sizeof(TUDPHeader), p_len);
writehexln(uint32(buffer) + sizeof(TUDPHeader));
for i:=0 to p_len-1 do begin
writehexpair(puint8(p_data)[i]);
end;
writestringln(' ');
for i:=0 to p_len-1 do begin
writechar(pchar(p_data)[i]);
end;
writestringln(' ');
for i:=0 to size-1 do begin
writehexpair(puint8(buffer)[i]);
end;
writestringln(' ');
udpContext^.context^.Protocol.L4:= $11; udpContext^.context^.Protocol.L4:= $11;
ipv4.send(buffer, size, udpContext^.context); ipv4.send(buffer, size, udpContext^.context);
@ -203,7 +189,6 @@ var
size : uint16; size : uint16;
begin begin
writeToLogLn(' L4: udp.recv');
header:= PUDPHeader(p_data); header:= PUDPHeader(p_data);
if Ports[switchendian16(header^.DstPort)] <> nil then begin if Ports[switchendian16(header^.DstPort)] <> nil then begin
context:= PUDPPacketContext(kalloc(sizeof(TUDPPacketContext))); context:= PUDPPacketContext(kalloc(sizeof(TUDPPacketContext)));

View File

@ -1,3 +1,8 @@
{
Driver->Net->L5->DHCP - Dynamic Host Configuration Protocol Driver.
@author(Kieron Morris <kjm@kieronmorris.me>)
}
unit dhcp; unit dhcp;
interface interface
@ -5,7 +10,7 @@ interface
uses uses
lmemorymanager, console, lmemorymanager, console,
nettypes, netutils, udp, netlog, net, nettypes, netutils, udp, netlog, net,
util, rand, lists, tracer, ipv4; util, rand, lists, tracer, ipv4, arp;
type type
TDHCPOptions = PLinkedListBase; TDHCPOptions = PLinkedListBase;
@ -26,16 +31,59 @@ implementation
type type
TFlipExclude = Array[0..255] of boolean; TFlipExclude = Array[0..255] of boolean;
PFlipExclude = ^TFlipExclude; PFlipExclude = ^TFlipExclude;
TDHCPConfiguration = record
Transaction : uint32;
Options : array[0..255] of void;
end;
PDHCPConfiguation = ^TDHCPConfiguration;
var var
XID : uint32; Configuration : PDHCPConfiguation;
Socket : PUDPBindContext; Socket : PUDPBindContext = nil;
FlipExclude : PFlipExclude; FlipExclude : PFlipExclude;
function newHeader : PDHCPHeader; procedure nullConfiguration;
var
i : uint8;
begin
if configuration <> nil then begin
Configuration^.Transaction:= 0;
for i:=0 to 255 do begin
if Configuration^.Options[i] <> nil then begin
kfree(Configuration^.Options[i]);
end;
Configuration^.Options[i]:= nil;
end;
end;
end;
function createHeader(): PDHCPHeader;
var
result : PDHCPHeader;
MAC : puint8;
begin begin
tracer.push_trace('dhcp.newHeader'); tracer.push_trace('dhcp.newHeader');
newHeader:= PDHCPHeader(kalloc(sizeof(TDHCPHeader))); result:= PDHCPHeader(kalloc(sizeof(TDHCPHeader)));
result^.Message_Type:= $01;
result^.Hardware_Type:= $01;
result^.Hardware_Address_Length:= $06;
result^.Hops:= $00;
result^.Transaction_ID:= Configuration^.Transaction;
result^.Seconds_Elapsed:= $0000;
result^.Bootp_Flags:= $0000;
CopyIPv4(@NULL_IP[0], @result^.Client_IP[0]);
CopyIPv4(@NULL_IP[0], @result^.Your_IP[0]);
CopyIPv4(@NULL_IP[0], @result^.Server_IP[0]);
CopyIPv4(@NULL_IP[0], @result^.Relay_Agent_IP[0]);
MAC:= getMAC;
CopyMAC(MAC, @result^.Client_MAC[0]);
memset(uint32(@result^.Padding[0]), 0, 10);
memset(uint32(@result^.Server_Hostname[0]), 0, 64);
memset(uint32(@result^.Boot_File[0]), 0, 128);
memcpy(uint32(@DHCP_MAGIC[0]), uint32(@result^.Magic_Cookie[0]), 4);
createHeader:= result;
end; end;
function newOption(DHCPOptions : PDHCPOptions; Opcode : TDHCPOpCode; Data : void; Length : uint32; SwapEndian : Boolean) : PDHCPOption; function newOption(DHCPOptions : PDHCPOptions; Opcode : TDHCPOpCode; Data : void; Length : uint32; SwapEndian : Boolean) : PDHCPOption;
@ -145,6 +193,30 @@ begin
getEndianCorrectValue32:= Value; getEndianCorrectValue32:= Value;
end; end;
function readOption8(Option : PDHCPOption) : uint8;
var
read8 : puint8;
begin
read8:= puint8(Option^.Value);
readOption8:= read8^;
end;
function readOption16(Option : PDHCPOption) : uint16;
var
read16 : puint16;
begin
read16:= puint16(Option^.Value);
readOption16:= read16^;
end;
function readOption32(Option : PDHCPOption) : uint32;
var
read32 : puint32;
begin
read32:= puint32(Option^.Value);
readOption32:= read32^;
end;
function writeOptions(Header : PDHCPHeader; Options : PDHCPOptions; newLength : puint16) : PDHCPHeader; function writeOptions(Header : PDHCPHeader; Options : PDHCPOptions; newLength : puint16) : PDHCPHeader;
var var
OptionsSize : uint16; OptionsSize : uint16;
@ -165,7 +237,7 @@ begin
NewBuffer:= kalloc(TotalSize); NewBuffer:= kalloc(TotalSize);
//Copy over Header //Copy over Header
NewHeader:= PDHCPHeader(buffer); NewHeader:= PDHCPHeader(NewBuffer);
memcpy(uint32(Header), uint32(NewHeader), sizeof(TDHCPHeader)); memcpy(uint32(Header), uint32(NewHeader), sizeof(TDHCPHeader));
//Write all options //Write all options
@ -221,14 +293,26 @@ var
begin begin
tracer.push_trace('dhcp.register'); tracer.push_trace('dhcp.register');
{ Get the beginning & end of the Options buffer }
HeaderSize:= sizeOf(TDHCPHeader); HeaderSize:= sizeOf(TDHCPHeader);
bufferEnd:= puint8(uint32(p_data) + p_len); bufferEnd:= puint8(uint32(p_data) + p_len);
bufferStart:= puint8(uint32(p_data) + headerSize); bufferStart:= puint8(uint32(p_data) + headerSize);
{ Buffer is our iterator }
buffer:= bufferStart; buffer:= bufferStart;
HaveOp:= false; HaveOp:= false;
HaveLen:= false; HaveLen:= false;
while (uint32(buffer) < uint32(bufferEnd)) do begin while (uint32(buffer) < uint32(bufferEnd)) do begin
{
If we have a length, read the value (bytes[length])
If we have an Opcode read the length (bytes[1])
If we have neither, read the opcode (bytes[1])
}
if HaveLen then begin if HaveLen then begin
{ Get a new option LinkedList 'object' and store everything inside }
Option:= newOption(DHCPOptions, Opcode, void(buffer), Length, not FlipExclude^[ord(Opcode)]); Option:= newOption(DHCPOptions, Opcode, void(buffer), Length, not FlipExclude^[ord(Opcode)]);
if Length = 2 then begin if Length = 2 then begin
if Option^.Reverse_Endian then begin if Option^.Reverse_Endian then begin
@ -263,57 +347,271 @@ begin
end; end;
end; end;
procedure processHeader(Header : PDHCPHeader);
begin
{ Switch endianness of any network-byte-order values }
Header^.Transaction_ID:= switchendian32(Header^.Transaction_ID);
Header^.Seconds_Elapsed:= switchendian16(Header^.Seconds_Elapsed);
Header^.Bootp_Flags:= switchendian16(Header^.Bootp_Flags);
end;
procedure processPacket_NAK(Header : PDHCPHeader; Options : PDHCPOptions);
begin
console.outputln('DHCP', 'Process NAK.');
nullConfiguration();
end;
procedure processPacket_ACK(Header : PDHCPHeader; Options : PDHCPOptions);
var
i : uint16;
Option : PDHCPOption;
read16 : puint16;
read32 : puint32;
cfgopt : void;
begin
console.outputln('DHCP', 'Process ACK.');
getIPv4Config^.UP:= false;
//Copy new address
Configuration^.Options[Ord(TDHCPOpCode.REQUESTED_IP_ADDRESS)]:= kalloc(sizeof(TIPv4Address));
copyIPv4(@Header^.Your_IP[0], puint8(Configuration^.Options[Ord(TDHCPOpCode.REQUESTED_IP_ADDRESS)]));
{ Copy any given configuration data }
for i:=0 to getOptionsCount(Options)-1 do begin
Option:= getOption(Options, i);
case Option^.Opcode of
PAD,END_VENDOR_OPTIONS:begin
end;
else begin
cfgopt:= kalloc(Option^.Size);
Configuration^.Options[ord(Option^.Opcode)]:= cfgopt;
memcpy(uint32(Option^.Value), uint32(cfgopt), Option^.Size);
end;
end;
end;
{ Copy into IPv4 Configuration }
if Configuration^.Options[Ord(TDHCPOpCode.REQUESTED_IP_ADDRESS)] <> nil then
copyIPv4(puint8(Configuration^.Options[Ord(TDHCPOpCode.REQUESTED_IP_ADDRESS)]), puint8(@getIPv4Config^.address[0]));
if Configuration^.Options[Ord(TDHCPOpCode.ROUTER)] <> nil then
copyIpv4(puint8(Configuration^.Options[Ord(TDHCPOpCode.ROUTER)]), puint8(@getIPv4Config^.Gateway[0]));
if Configuration^.Options[Ord(TDHCPOpCode.SUBNET_MASK)] <> nil then
copyIPv4(puint8(Configuration^.Options[Ord(TDHCPOpCode.SUBNET_MASK)]), puint8(@getIPv4Config^.Netmask[0]));
arp.sendGratuitous;
arp.sendRequest(@getIPv4Config^.Gateway[0]);
getIPv4Config^.UP:= true;
end;
procedure processPacket_OFFER(Header : PDHCPHeader; Options : PDHCPOptions);
Var
SendHeader : PDHCPHeader;
SendOptions : PDHCPOptions;
SendMsgType : uint8;
NewSendHeader : PDHCPHeader;
NewHeaderSize : uint32;
SendCtx : PUDPSendContext;
PacketCtx : PPacketContext;
MAC : puint8;
begin
console.outputln('DHCP', 'Process OFFER.');
{ Check the Transaction ID matches our stored ID, discard if not. }
if Header^.Transaction_ID = Configuration^.Transaction then begin
console.outputln('DHCP', 'XID Match');
SendHeader:= createHeader();
CopyIPv4(puint8(@Header^.Your_IP[0]), puint8(@SendHeader^.Client_IP[0]));
CopyIPv4(puint8(@Header^.Server_IP[0]), puint8(@SendHeader^.Server_IP[0]));
SendOptions:= newOptions();
SendMsgType:= ord(TDHCPMessageType.REQUEST);
NewOption(SendOptions, TDHCPOpCode.DHCP_MESSAGE_TYPE, void(@SendMsgType), 1, false);
NewOption(SendOptions, TDHCPOpCode.REQUESTED_IP_ADDRESS, void(@SendHeader^.Client_IP[0]), 4, false);
NewOption(SendOptions, TDHCPOpCode.SERVER_IDENTIFIER, void(@SendHeader^.Server_IP[0]), 4, false);
NewOption(SendOptions, TDHCPOpCode.END_VENDOR_OPTIONS, nil, 0, false);
NewSendHeader:= writeOptions(SendHeader, SendOptions, @NewHeaderSize);
{ Setup Packet Context (IPv4 & ETH2) }
MAC:= getMAC();
packetCtx:= PPacketContext(Kalloc(sizeof(TPacketContext)));
packetCtx^.TTL:= 128;
copyMAC(@BROADCAST_MAC[0], @packetCtx^.MAC.Destination[0]);
copyMAC(MAC, @packetCtx^.MAC.Source[0]);
copyIPv4(@NULL_IP[0], @packetCtx^.IP.Source[0]);
copyIPv4(@BROADCAST_IP[0], @packetCtx^.IP.Destination[0]);
{ Setup UDPContext (UDP) }
sendCtx:= PUDPSendContext(Kalloc(sizeof(TUDPSendContext)));
sendCtx^.DstPort:= 67;
sendCtx^.context:= packetCtx;
sendCtx^.socket:= Socket;
{ Send }
udp.send(void(NewSendHeader), NewHeaderSize, sendCtx);
freeOptions(SendOptions);
kfree(void(NewSendHeader));
kfree(void(SendHeader));
kfree(void(packetCtx));
kfree(void(sendCtx));
end else begin
console.outputln('DHCP', 'XID Mismatch');
end;
end;
procedure processPacket(p_data : void; p_len : uint16; context : PUDPPacketContext); procedure processPacket(p_data : void; p_len : uint16; context : PUDPPacketContext);
var var
Header : PDHCPHeader; Header : PDHCPHeader;
Options : PDHCPOptions; Options : PDHCPOptions;
Option : PDHCPOption;
MAC : puint8;
i : uint32;
MsgType : uint8;
begin begin
tracer.push_trace('dhcp.processPacket'); tracer.push_trace('dhcp.processPacket.enter');
Outputln('DHCP','processPacket');
{ Give access to header values & process to correct endianness. }
Header:= PDHCPHeader(p_data); Header:= PDHCPHeader(p_data);
processHeader(Header);
{ Process Options }
Options:= newOptions; Options:= newOptions;
readOptions(Options, p_data, p_len); readOptions(Options, p_data, p_len);
{ Check the frame is for us and then process }
MAC:= getMAC;
if MACEqual(@context^.PacketContext^.MAC.Destination[0], MAC) then begin
Outputln('DHCP','Frame is addressed to us.');
{ Check the message type is client specific }
If Header^.Message_Type = $02 then begin
Outputln('DHCP','Packet is a client packet.');
Outputln('DHCP','Searching for message type in Options');
{ Iterate options to find DHCP_MESSAGE_TYPE }
for i:=0 to getOptionsCount(Options)-1 do begin
Option:= getOption(Options, i);
if Option^.Opcode = DHCP_MESSAGE_TYPE then begin
break;
end else begin
Option:= nil;
end;
end;
Outputln('DHCP','Done searching for message type in Options');
{ Did we successfully get the DHCP_MESSAGE_TYPE option? }
if Option <> nil then begin
Outputln('DHCP','Found message type option.');
{ Read the value of DHCP_MESSAGE_TYPE }
MsgType:= readOption8(Option);
case TDHCPMessageType(MsgType) of
{ Pass to the correct packet processing function }
TDHCPMessageType.OFFER:processPacket_OFFER(Header, Options);
TDHCPMessageType.PACK:processPacket_ACK(Header, Options);
TDHCPMessageType.NAK:processPacket_NAK(Header, Options);
end;
end else begin
{ Could not find the DHCP_MESSAGE_TYPE option }
Outputln('DHCP','Could not find message type option.');
end;
end else begin
{ Packet is intended for a DHCP server }
Outputln('DHCP','Packet is a server packet.');
end;
end;
freeOptions(Options);
tracer.push_trace('dhcp.processPacket.exit');
end; end;
procedure DHCPDiscover(); procedure DHCPDiscover();
var var
SendCtx : PUDPSendContext;
PacketCtx : PPacketContext;
Header : PDHCPHeader; Header : PDHCPHeader;
NewHeader : PDHCPHeader; NewHeader : PDHCPHeader;
HeaderSize : Puint32; HeaderSize : uint32;
Options : PDHCPOptions; Options : PDHCPOptions;
MsgType : uint8; MsgType : uint8;
MAC : puint8;
begin begin
tracer.push_trace('dhcp.DHCPDiscover'); tracer.push_trace('dhcp.DHCPDiscover.begin');
Header:= newHeader; { Ensure we have a socket bound. }
if Socket <> nil then begin
{ Clear any current configuration }
nullConfiguration();
{ Setup our Transaction ID }
Configuration^.Transaction:= rand32();
{ Setup header }
Header:= createHeader();
processHeader(Header);
{ Setup options }
Options:= newOptions; Options:= newOptions;
XID:= rand32();
//Setup header
Header^.Message_Type:= $01;
Header^.Hardware_Type:= $01;
Header^.Hardware_Address_Length:= $06;
Header^.Hops:= $00;
Header^.Transaction_ID:= switchendian32(XID);
Header^.Seconds_Elapsed:= $0000;
CopyIPv4(@NULL_IP[0], @Header^.Client_IP[0]);
CopyIPv4(@NULL_IP[0], @Header^.Your_IP[0]);
CopyIPv4(@NULL_IP[0], @Header^.Server_IP[0]);
CopyIPv4(@NULL_IP[0], @Header^.Relay_Agent_IP[0]);
CopyMAC(@getMAC[0], @Header^.Client_MAC[0]);
memset(uint32(@Header^.Padding[0]), 0, 10);
memset(uint32(@Header^.Server_Hostname[0]), 0, 64);
memset(uint32(@Header^.Boot_File[0]), 0, 128);
memcpy(uint32(@DHCP_MAGIC[0]), uint32(@Header^.Magic_Cookie[0]), 4);
//Setup options
MsgType:= Ord(TDHCPMessageType.DISCOVER); MsgType:= Ord(TDHCPMessageType.DISCOVER);
newOption(Options, DHCP_MESSAGE_TYPE, void(@MsgType), 1, false); newOption(Options, DHCP_MESSAGE_TYPE, void(@MsgType), 1, false);
NewOption(Options, END_VENDOR_OPTIONS, nil, 0, false); NewOption(Options, END_VENDOR_OPTIONS, nil, 0, false);
{ Write options to header }
NewHeader:= writeOptions(Header, Options, @HeaderSize);
{ Setup Packet Context (IPv4 & ETH2) }
packetCtx:= PPacketContext(Kalloc(sizeof(TPacketContext)));
packetCtx^.TTL:= 128;
copyMAC(@BROADCAST_MAC[0], @packetCtx^.MAC.Destination[0]);
MAC:= getMAC;
copyMAC(MAC, @packetCtx^.MAC.Source[0]);
copyIPv4(@NULL_IP[0], @packetCtx^.IP.Source[0]);
copyIPv4(@BROADCAST_IP[0], @packetCtx^.IP.Destination[0]);
{ Setup UDPContext (UDP) }
sendCtx:= PUDPSendContext(Kalloc(sizeof(TUDPSendContext)));
sendCtx^.DstPort:= 67;
sendCtx^.context:= packetCtx;
sendCtx^.socket:= Socket;
{ NET UP }
getIPv4Config^.UP:= true; getIPv4Config^.UP:= true;
{ Send }
udp.send(void(NewHeader), HeaderSize, sendCtx);
{ Free }
kfree(void(PacketCtx));
kfree(void(sendCtx));
kfree(void(Header));
kfree(void(NewHeader));
freeOptions(Options);
end;
tracer.push_trace('dhcp.DHCPDiscover.exit');
end;
procedure bind();
begin
{ Bind our socket, free the socket in case of failure }
Socket:= PUDPBindContext(Kalloc(sizeof(TUDPBindContext)));
Socket^.Port:= 68;
Socket^.Callback:= @processPacket;
Socket^.UID:= rand32;
case UDP.bind(Socket) of
tueOK:console.outputln('DHCP', 'Successfully bound port 68.');
else begin
kfree(void(Socket));
Socket:= nil;
console.outputln('DHCP', 'Failed to bind port 68.');
end;
end;
end; end;
procedure register(); procedure register();
@ -323,10 +621,23 @@ var
begin begin
tracer.push_trace('dhcp.register'); tracer.push_trace('dhcp.register');
console.outputln('DHCP', 'Register begin.'); console.outputln('DHCP', 'Register begin.');
{ Kalloc our Configuration Data }
Configuration:= PDHCPConfiguation(kalloc(sizeof(TDHCPConfiguration)));
{ Null Existing Coniguration }
for i:=0 to 255 do begin
Configuration^.Options[i] := nil;
end;
nullConfiguration();
{ Clear FlipExclude Table }
FlipExclude:= PFlipExclude(kalloc(sizeof(TFlipExclude))); FlipExclude:= PFlipExclude(kalloc(sizeof(TFlipExclude)));
for i:=0 to 255 do begin for i:=0 to 255 do begin
FlipExclude^[i]:= false; FlipExclude^[i]:= false;
end; end;
{ Set FlipExclude Table up to exclude certain OPCode from EndianFlips }
FlipExclude^[ord(PAD)]:= true; FlipExclude^[ord(PAD)]:= true;
FlipExclude^[ord(SUBNET_MASK)]:= true; FlipExclude^[ord(SUBNET_MASK)]:= true;
FlipExclude^[ord(ROUTER)]:= true; FlipExclude^[ord(ROUTER)]:= true;
@ -383,15 +694,10 @@ begin
FlipExclude^[ord(TZ_TIMEZONE)]:= true; FlipExclude^[ord(TZ_TIMEZONE)]:= true;
FlipExclude^[ord(DOMAIN_SEARCH)]:= true; FlipExclude^[ord(DOMAIN_SEARCH)]:= true;
FlipExclude^[ord(CLASSLESS_STATIC_ROUTE)]:= true; FlipExclude^[ord(CLASSLESS_STATIC_ROUTE)]:= true;
Socket:= PUDPBindContext(Kalloc(sizeof(TUDPBindContext)));
Socket^.Port:= 68; { Bind to port 68 }
Socket^.Callback:= @processPacket; bind();
Socket^.UID:= rand32;
case UDP.bind(Socket) of
tueOK:console.outputln('DHCP', 'Successfully bound port 68.');
else console.outputln('DHCP', 'Failed to bind port 68.');
end;
DHCPDiscover;
console.outputln('DHCP', 'Register end.'); console.outputln('DHCP', 'Register end.');
end; end;

View File

@ -165,7 +165,6 @@ var
mem : puint32; mem : puint32;
begin begin
push_trace('E1000.writeCommand');
if (bar_type = 0) then begin if (bar_type = 0) then begin
mem:= puint32(mem_base + p_address); mem:= puint32(mem_base + p_address);
mem^:= p_value; mem^:= p_value;
@ -173,7 +172,6 @@ begin
outl(io_base + 0, p_address); outl(io_base + 0, p_address);
outl(io_base + 4, p_address) outl(io_base + 4, p_address)
end; end;
pop_trace;
end; end;
function readCommand(p_address : uint16) : uint32; function readCommand(p_address : uint16) : uint32;
@ -181,7 +179,6 @@ var
mem : puint32; mem : puint32;
begin begin
push_trace('E1000.readCommand');
if (bar_type = 0) then begin if (bar_type = 0) then begin
mem:= puint32(mem_base + p_address); mem:= puint32(mem_base + p_address);
readCommand:= mem^; readCommand:= mem^;
@ -189,7 +186,6 @@ begin
outl(io_base, p_address); outl(io_base, p_address);
readCommand:= inl(io_base + 4); readCommand:= inl(io_base + 4);
end; end;
pop_trace;
end; end;
function readStatus : uint32; function readStatus : uint32;
@ -202,7 +198,6 @@ var
val, i : uint32; val, i : uint32;
begin begin
push_trace('E1000.detectEEPROM');
val:= 0; val:= 0;
writeCommand(REG_EEPROM, $1); writeCommand(REG_EEPROM, $1);
for i:=0 to 1000 do begin for i:=0 to 1000 do begin
@ -211,7 +206,6 @@ begin
if (val and $10) > 0 then eeprom_exists:= true else eeprom_exists:= false; if (val and $10) > 0 then eeprom_exists:= true else eeprom_exists:= false;
end; end;
detectEEPROM:= eeprom_exists; detectEEPROM:= eeprom_exists;
pop_trace;
end; end;
function EEPROMRead( address : uint8 ) : uint32; function EEPROMRead( address : uint8 ) : uint32;
@ -220,7 +214,6 @@ var
tmp : uint32; tmp : uint32;
begin begin
push_trace('E1000.EEPROMRead');
tmp:= 0; tmp:= 0;
if (eeprom_exists) then begin if (eeprom_exists) then begin
writeCommand( REG_EEPROM, 1 OR (uint32(address) SHL 8) ); writeCommand( REG_EEPROM, 1 OR (uint32(address) SHL 8) );
@ -235,7 +228,6 @@ begin
end; end;
data:= uint16( (tmp SHR 16) AND ($FFFF) ); data:= uint16( (tmp SHR 16) AND ($FFFF) );
EEPROMRead:= data; EEPROMRead:= data;
pop_trace;
end; end;
function readMACAddress() : boolean; function readMACAddress() : boolean;
@ -271,7 +263,6 @@ begin
end; end;
end; end;
readMACAddress:= res; readMACAddress:= res;
pop_trace;
end; end;
procedure startLink(); procedure startLink();
@ -279,10 +270,8 @@ var
val : uint32; val : uint32;
begin begin
push_trace('E1000.startLink');
val:= readCommand(REG_CTRL); val:= readCommand(REG_CTRL);
writeCommand(REG_CTRL, val OR ECTRL_SLU); writeCommand(REG_CTRL, val OR ECTRL_SLU);
pop_trace;
end; end;
procedure rxinit(); procedure rxinit();
@ -293,7 +282,6 @@ var
i : uint32; i : uint32;
begin begin
push_trace('E1000.rxinit');
ptr:= puint8(kalloc(sizeof(TE1000_rx_desc) * E1000_NUM_RX_DESC + 16)); ptr:= puint8(kalloc(sizeof(TE1000_rx_desc) * E1000_NUM_RX_DESC + 16));
descs:= PE1000_rx_desc(ptr); descs:= PE1000_rx_desc(ptr);
for i:=0 to E1000_NUM_RX_DESC do begin for i:=0 to E1000_NUM_RX_DESC do begin
@ -323,7 +311,6 @@ begin
rx_curr:= 0; rx_curr:= 0;
writeCommand(REG_RCTRL, RCTL_EN OR RCTL_SBP OR RCTL_UPE OR RCTL_MPE OR RCTL_LBM_NONE OR RTCL_RDMTS_HALF OR RCTL_BAM OR RCTL_SECRC OR RCTL_BSIZE_2048); writeCommand(REG_RCTRL, RCTL_EN OR RCTL_SBP OR RCTL_UPE OR RCTL_MPE OR RCTL_LBM_NONE OR RTCL_RDMTS_HALF OR RCTL_BAM OR RCTL_SECRC OR RCTL_BSIZE_2048);
pop_trace;
end; end;
procedure txinit(); procedure txinit();
@ -334,7 +321,6 @@ var
i : uint32; i : uint32;
begin begin
push_trace('E1000.txinit');
ptr:= puint8(kalloc(sizeof(TE1000_tx_desc) * (E1000_NUM_TX_DESC + 16))); ptr:= puint8(kalloc(sizeof(TE1000_tx_desc) * (E1000_NUM_TX_DESC + 16)));
descs:= PE1000_tx_desc(ptr); descs:= PE1000_tx_desc(ptr);
for i:=0 to E1000_NUM_TX_DESC do begin for i:=0 to E1000_NUM_TX_DESC do begin
@ -346,9 +332,7 @@ begin
outptr:= puint8(vtop(uint32(ptr))); //puint8(uint32(ptr) - KERNEL_VIRTUAL_BASE); outptr:= puint8(vtop(uint32(ptr))); //puint8(uint32(ptr) - KERNEL_VIRTUAL_BASE);
console.output('E1000 Driver', 'TX VMem: ');
console.writehexln(uint32(ptr)); console.writehexln(uint32(ptr));
console.output('E1000 Driver', 'TX Mem: ');
console.writehexln(uint32(outptr)); console.writehexln(uint32(outptr));
writeCommand(REG_TXDESCHI, 0); writeCommand(REG_TXDESCHI, 0);
@ -366,16 +350,13 @@ begin
writeCommand(REG_TCTRL, $3003F0FA); writeCommand(REG_TCTRL, $3003F0FA);
writeCommand(REG_TIPG, $0060200A); writeCommand(REG_TIPG, $0060200A);
end; end;
pop_trace;
end; end;
procedure enableInturrupt(); procedure enableInturrupt();
begin begin
push_trace('E1000.enableInterrupt');
writeCommand(REG_IMASK, $1F6DC); writeCommand(REG_IMASK, $1F6DC);
writeCommand(REG_IMASK, $FF AND NOT(4)); writeCommand(REG_IMASK, $FF AND NOT(4));
readCommand($C0); readCommand($C0);
pop_trace;
end; end;
procedure handleReceive(); procedure handleReceive();
@ -387,7 +368,6 @@ var
i : uint16; i : uint16;
begin begin
push_trace('E1000.handleReceive');
while (rx_descs[rx_curr]^.status AND $1) > 0 do begin while (rx_descs[rx_curr]^.status AND $1) > 0 do begin
got_packet:= true; got_packet:= true;
buf:= rx_buffs[rx_curr]; buf:= rx_buffs[rx_curr];
@ -401,7 +381,6 @@ begin
rx_curr:= (rx_curr + 1) mod E1000_NUM_RX_DESC; rx_curr:= (rx_curr + 1) mod E1000_NUM_RX_DESC;
writeCommand(REG_RXDESCTAIL, old_cur); writeCommand(REG_RXDESCTAIL, old_cur);
end; end;
pop_trace;
end; end;
procedure writeCardType(); procedure writeCardType();
@ -421,8 +400,6 @@ var
data : uint32; data : uint32;
begin begin
push_trace('E1000.fire');
writeToLogLn('L0: E1000 Fire');
status:= readCommand($C0); status:= readCommand($C0);
if (status AND $04) > 0 then begin if (status AND $04) > 0 then begin
startLink(); startLink();
@ -439,9 +416,7 @@ end;
procedure console_command_mac(params : PParamList); procedure console_command_mac(params : PParamList);
begin begin
push_trace('E1000.console_command_mac');
writeMACAddress(@mac[0], getTerminalHWND); writeMACAddress(@mac[0], getTerminalHWND);
pop_trace;
end; end;
procedure console_command_sendtest(params : PParamList); procedure console_command_sendtest(params : PParamList);
@ -461,7 +436,6 @@ var
); );
begin begin
push_trace('E1000.console_command_sendtest');
TestPacket[6]:= mac[0]; TestPacket[6]:= mac[0];
TestPacket[7]:= mac[1]; TestPacket[7]:= mac[1];
TestPacket[8]:= mac[2]; TestPacket[8]:= mac[2];
@ -579,35 +553,29 @@ end;
function loadE1000(ptr : void) : boolean; function loadE1000(ptr : void) : boolean;
begin begin
push_trace('E1000.loadE1000');
loadE1000:= false; loadE1000:= false;
if not Loaded then begin if not Loaded then begin
card_type:= ctE1000; card_type:= ctE1000;
loadE1000:= load(ptr); loadE1000:= load(ptr);
end; end;
pop_trace;
end; end;
function load82577LM(ptr : void) : boolean; function load82577LM(ptr : void) : boolean;
begin begin
push_trace('E1000.load82577LM');
load82577LM:= false; load82577LM:= false;
if not Loaded then begin if not Loaded then begin
card_type:= ct82577LM; card_type:= ct82577LM;
load82577LM:= load(ptr); load82577LM:= load(ptr);
end; end;
pop_trace;
end; end;
function loadI217(ptr : void) : boolean; function loadI217(ptr : void) : boolean;
begin begin
push_trace('E1000.loadI217');
loadI217:= false; loadI217:= false;
if not Loaded then begin if not Loaded then begin
card_type:= ctI217; card_type:= ctI217;
loadI217:= load(ptr); loadI217:= load(ptr);
end; end;
pop_trace;
end; end;
procedure init(); procedure init();
@ -643,7 +611,6 @@ var
timeout : uint32; timeout : uint32;
begin begin
push_trace('E1000.sendPacket');
tx_descs[tx_curr]^.address:= uint32(vtop(uint32(p_data))); tx_descs[tx_curr]^.address:= uint32(vtop(uint32(p_data)));
tx_descs[tx_curr]^.length:= p_len; tx_descs[tx_curr]^.length:= p_len;
tx_descs[tx_curr]^.cmd:= CMD_EOP OR CMD_IFCS OR CMD_RS OR CMD_RPS; tx_descs[tx_curr]^.cmd:= CMD_EOP OR CMD_IFCS OR CMD_RS OR CMD_RPS;
@ -657,7 +624,6 @@ begin
end; end;
sendPacket:= 1; sendPacket:= 1;
if timeout > 0 then sendPacket:= 0; if timeout > 0 then sendPacket:= 0;
pop_trace;
end; end;
end. end.

View File

@ -20,7 +20,7 @@ end;
function rand32 : uint32; function rand32 : uint32;
begin begin
rand32:= (rand SHL 16) AND rand; rand32:= (rand SHL 16) OR rand;
end; end;
function rand16 : uint16; function rand16 : uint16;
@ -35,7 +35,7 @@ end;
procedure srand(seed : uint32); procedure srand(seed : uint32);
begin begin
next:= seed; next:= next + seed;
end; end;
end. end.

View File

@ -19,8 +19,8 @@ uses
tracer, tracer,
drivermanagement, drivermanagement,
scheduler, scheduler,
progmanager,
PCI, PCI,
Terminal,
strings, strings,
USB, USB,
testdriver, testdriver,
@ -35,22 +35,12 @@ uses
fonts, fonts,
RTC, RTC,
serial, serial,
shell,
memview,
splash,
themer,
netlog,
vmlog,
vm, vm,
vmstate,
edit,
udpcat,
cpu, cpu,
md5, md5,
md5sum,
base64, base64,
base64_prog, rand,
rand; terminal;
procedure kmain(mbinfo: Pmultiboot_info_t; mbmagic: uint32); stdcall; procedure kmain(mbinfo: Pmultiboot_info_t; mbmagic: uint32); stdcall;
@ -159,7 +149,7 @@ begin
isrmanager.init(); isrmanager.init();
faults.init(); faults.init();
RTC.init(); RTC.init();
rand.srand((getDateTime.Seconds SHR 24) OR (getDateTime.Minutes SHR 16) OR (getDateTime.Hours SHR 8) OR (getDateTime.Day));
pmemorymanager.init(); pmemorymanager.init();
vmemorymanager.init(); vmemorymanager.init();
lmemorymanager.init(); lmemorymanager.init();
@ -214,24 +204,7 @@ begin
//vm.init(); //vm.init();
{ Init Progs } { Init Progs }
tracer.push_trace('kmain.SHELLINIT'); progmanager.init();
shell.init();
tracer.push_trace('kmain.MEMVIEWINIT');
memview.init();
tracer.push_trace('kmain.THEMERINIT');
themer.init();
tracer.push_trace('kmain.NETLOGINIT');
netlog.init();
tracer.push_trace('kmain.VMLOGINIT');
vmlog.init();
tracer.push_trace('kmain.VMSTATEINIT');
vmstate.init();
tracer.push_trace('kmain.EDIT');
edit.init();
udpcat.init();
md5sum.init();
base64_prog.init();
terminal.run();
{ Init Splash } { Init Splash }
//tracer.push_trace('kmain.SPLASHINIT'); //tracer.push_trace('kmain.SPLASHINIT');
@ -244,8 +217,10 @@ begin
console.setdefaultattribute(console.combinecolors($17E0, $0000)); console.setdefaultattribute(console.combinecolors($17E0, $0000));
console.writestringln('Asuro Booted Correctly!'); console.writestringln('Asuro Booted Correctly!');
console.setdefaultattribute(console.combinecolors($FFFF, $0000)); console.setdefaultattribute(console.combinecolors($FFFF, $0000));
writestringln(' ');
tracer.push_trace('kmain.END'); tracer.push_trace('kmain.END');
rand.srand((getDateTime.Seconds SHR 24) OR (getDateTime.Minutes SHR 16) OR (getDateTime.Hours SHR 8) OR (getDateTime.Day));
tracer.push_trace('kmain.TICK'); tracer.push_trace('kmain.TICK');
while true do begin while true do begin

View File

@ -1,5 +1,5 @@
{ {
Prog->VMLog - Virtual Machine Event Log. Prog->MD5Sum - MD5 Checksum of a given string.
@author(Kieron Morris <kjm@kieronmorris.me>) @author(Kieron Morris <kjm@kieronmorris.me>)
} }

View File

@ -20,6 +20,14 @@ implementation
uses uses
console, lmemorymanager, util, strings, serial, terminal; console, lmemorymanager, util, strings, serial, terminal;
type
PTracerEntry = ^TTracerEntry;
TTracerEntry = record
Next : PTracerEntry;
Data : pchar;
Previous : PTracerEntry;
end;
const const
MAX_TRACE = 40; MAX_TRACE = 40;
@ -29,6 +37,9 @@ var
Traces : Array[0..MAX_TRACE-1] of PChar; Traces : Array[0..MAX_TRACE-1] of PChar;
c_lock : Boolean = false; c_lock : Boolean = false;
var
head : PTracerEntry;
tail : PTracerEntry;
procedure terminal_command_tracer(Params : PParamList); procedure terminal_command_tracer(Params : PParamList);
var var