From fbc59a16170043cc9b33e012ea5dcf7bfec802e7 Mon Sep 17 00:00:00 2001 From: kieron Date: Sun, 12 Jul 2020 17:02:14 +0000 Subject: [PATCH] DHCP Works now. git-svn-id: https://spexeah.com:8443/svn/Asuro@1034 6dbc8c32-bb84-406f-8558-d1cf31a0ab0c --- src/driver/net/l1/net.pas | 10 +- src/driver/net/l2/eth2.pas | 6 +- src/driver/net/l3/arp.pas | 23 +-- src/driver/net/l3/ipv4.pas | 8 +- src/driver/net/l4/icmp.pas | 3 - src/driver/net/l4/udp.pas | 15 -- src/driver/net/l5/dhcp.pas | 400 +++++++++++++++++++++++++++++++----- src/driver/netdev/E1000.pas | 34 --- src/include/rand.pas | 4 +- src/kernel.pas | 39 +--- src/prog/md5sum.pas | 2 +- src/tracer.pas | 11 + 12 files changed, 389 insertions(+), 166 deletions(-) diff --git a/src/driver/net/l1/net.pas b/src/driver/net/l1/net.pas index e6fc37db..0256e763 100644 --- a/src/driver/net/l1/net.pas +++ b/src/driver/net/l1/net.pas @@ -36,7 +36,7 @@ uses var CBSend : TNetSendCallback = nil; CBNext : TRecvCallback = nil; - MAC : puint8 = @NULL_MAC[0]; + MAC : puint8 = @NULL_MAC[0]; procedure writeToLog(str : pchar); var @@ -92,8 +92,8 @@ end; procedure send(p_data : void; p_len : uint16); begin - push_trace('net.send'); - writeToLogLn('L1: net.send'); + //push_trace('net.send'); + //writeToLogLn('L1: net.send'); if CBSend <> nil then CBSend(p_data, p_len); pop_trace; end; @@ -103,8 +103,8 @@ var context : PPacketContext; begin - push_trace('net.recv'); - writeToLogLn('L1: net.recv'); + //push_trace('net.recv'); + //writeToLogLn('L1: net.recv'); context:= newPacketContext; if CBNext <> nil then CBNext(p_data, p_len, context); freePacketContext(context); diff --git a/src/driver/net/l2/eth2.pas b/src/driver/net/l2/eth2.pas index e265ba29..559ee9e6 100644 --- a/src/driver/net/l2/eth2.pas +++ b/src/driver/net/l2/eth2.pas @@ -34,7 +34,6 @@ var procedure registerTypePromisc(eType : uint16; RecvCB : TRecvCallback); begin - push_trace('eth2.registerType'); register; if EthTypes[eType] = nil then EthTypes[eType]:= RecvCB; Promisc[eType]:= true; @@ -42,7 +41,6 @@ end; procedure registerType(eType : uint16; RecvCB : TRecvCallback); begin - push_trace('eth2.registerType'); register; if EthTypes[eType] = nil then EthTypes[eType]:= RecvCB; end; @@ -83,8 +81,7 @@ var buf : puint8; begin - push_trace('eth2.recv'); - writeToLogLn(' L2: eth2.recv'); + //writeToLogLn(' L2: eth2.recv'); buf:= puint8(p_data); Header:= PEthernetHeader(buf); @@ -102,7 +99,6 @@ begin EthTypes[proto_type](void(buf), p_len - 14, p_context); end; end; - pop_trace; end; procedure register; diff --git a/src/driver/net/l3/arp.pas b/src/driver/net/l3/arp.pas index fe30f770..be26cd1c 100644 --- a/src/driver/net/l3/arp.pas +++ b/src/driver/net/l3/arp.pas @@ -80,8 +80,6 @@ var hSize, pSize : uint8; begin - push_trace('arp.send'); - writeToLogLn(' L3: arp.send'); if p_context <> nil then begin buf:= kalloc(sizeof(TARPHeader)); hdr:= PARPHeader(buf); @@ -189,10 +187,6 @@ var context : PPacketContext; begin - push_trace('arp.recv'); - writeToLogLn(' L3: arp.recv'); - console.redrawWindows; - { Get our converted Header } Header:= PARPHeader(p_data); 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 case AHeader.Operation of $1:begin { ARP Request } - writeToLogLn(' arp.recv.arp.req'); context:= newPacketContext; copyMAC(@AHeader.Source_Hardware[0], @context^.MAC.Destination[0]); copyIPv4(@AHeader.Source_Protocol[0], @context^.IP.Destination[0]); @@ -229,28 +222,28 @@ begin freePacketContext(context); end; $2:begin { ARP Reply } - writeToLogLn(' arp.recv.arp.rep'); + end; $3:begin { RARP Request } - writeToLogLn(' arp.recv.rarp.req'); + end; $4:begin { RARP Reply } - writeToLogLn(' arp.recv.rarp.rep'); + end; $5:begin { DRARP Request } - writeToLogLn(' arp.recv.drarp.req'); + end; $6:begin { DRARP Reply } - writeToLogLn(' arp.recv.drarp.rep'); + end; $7:begin { DRARP Error } - writeToLogLn(' arp.recv.drarp.err'); + end; $8:begin { InARP Request } - writeToLogLn(' arp.recv.inarp.req'); + end; $9:begin { InARP Reply } - writeToLogLn(' arp.recv.inarp.rep'); + end; end; end; diff --git a/src/driver/net/l3/ipv4.pas b/src/driver/net/l3/ipv4.pas index c7f70e94..420d98e7 100644 --- a/src/driver/net/l3/ipv4.pas +++ b/src/driver/net/l3/ipv4.pas @@ -44,7 +44,6 @@ var buffer : void; begin - writeToLogLn(' L3: ipv4.send'); inc(CurrentID); Header.version:= 4; Header.header_len:= 5; @@ -83,8 +82,6 @@ var len : uint16; begin - push_trace('ipv4.recv'); - writeToLogLn(' L3: ipv4.recv'); Header:= PIPV4Header(p_data); AHeader.version:= Header^.version; AHeader.header_len:= Header^.header_len; @@ -112,7 +109,7 @@ begin copyIPv4(@AHeader.Dst[0], @p_context^.IP.Destination[0]); 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 Protocols[AHeader.Protocol](void(buf), len, p_context); end; @@ -130,7 +127,6 @@ var i : uint32; begin - push_trace('ipv4.terminal_command_ifconfig'); if paramCount(params) > 1 then begin Command:= GetParam(0, Params); if StringEquals(Command, 'set') then begin @@ -177,7 +173,6 @@ begin else writestringlnWND(' NetUP: false', getTerminalHWND); end; - pop_trace; end; procedure register; @@ -205,7 +200,6 @@ end; procedure registerProtocol(Protocol_ID : uint8; recv_callback : TRecvCallback); begin - push_trace('ipv4.registerProtocol'); register; if Protocols[Protocol_ID] = nil then Protocols[Protocol_ID]:= recv_callback; pop_trace; diff --git a/src/driver/net/l4/icmp.pas b/src/driver/net/l4/icmp.pas index d0224c3f..42f9aa1c 100644 --- a/src/driver/net/l4/icmp.pas +++ b/src/driver/net/l4/icmp.pas @@ -118,12 +118,10 @@ var Handle : uint8; begin - writeToLogLn(' L4: icmp.recv'); Header:= PICMPHeader(p_data); //writehexlnWND(Header^.ICMP_Type, getTerminalHWND); case Header^.ICMP_Type of $08:Begin //Request - writeToLogLn(' L4: icmp.request'); contextMACSwitch(p_context); contextIPv4Switch(p_context); Header^.ICMP_Type:= 0; @@ -137,7 +135,6 @@ begin ipv4.send(p_data, p_len, p_context); 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 diff --git a/src/driver/net/l4/udp.pas b/src/driver/net/l4/udp.pas index 01c7e9da..86095bb4 100644 --- a/src/driver/net/l4/udp.pas +++ b/src/driver/net/l4/udp.pas @@ -123,20 +123,6 @@ begin memcpy(uint32(hdr), uint32(buffer), sizeof(TUDPHeader)); 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; ipv4.send(buffer, size, udpContext^.context); @@ -203,7 +189,6 @@ var size : uint16; begin - writeToLogLn(' L4: udp.recv'); header:= PUDPHeader(p_data); if Ports[switchendian16(header^.DstPort)] <> nil then begin context:= PUDPPacketContext(kalloc(sizeof(TUDPPacketContext))); diff --git a/src/driver/net/l5/dhcp.pas b/src/driver/net/l5/dhcp.pas index 4fbb8a4b..d4fda3a6 100644 --- a/src/driver/net/l5/dhcp.pas +++ b/src/driver/net/l5/dhcp.pas @@ -1,3 +1,8 @@ +{ + Driver->Net->L5->DHCP - Dynamic Host Configuration Protocol Driver. + + @author(Kieron Morris ) +} unit dhcp; interface @@ -5,7 +10,7 @@ interface uses lmemorymanager, console, nettypes, netutils, udp, netlog, net, - util, rand, lists, tracer, ipv4; + util, rand, lists, tracer, ipv4, arp; type TDHCPOptions = PLinkedListBase; @@ -26,16 +31,59 @@ implementation type TFlipExclude = Array[0..255] of boolean; PFlipExclude = ^TFlipExclude; + TDHCPConfiguration = record + Transaction : uint32; + Options : array[0..255] of void; + end; + PDHCPConfiguation = ^TDHCPConfiguration; var - XID : uint32; - Socket : PUDPBindContext; - FlipExclude : PFlipExclude; + Configuration : PDHCPConfiguation; + Socket : PUDPBindContext = nil; + FlipExclude : PFlipExclude; + +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; -function newHeader : PDHCPHeader; begin 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; function newOption(DHCPOptions : PDHCPOptions; Opcode : TDHCPOpCode; Data : void; Length : uint32; SwapEndian : Boolean) : PDHCPOption; @@ -145,6 +193,30 @@ begin getEndianCorrectValue32:= Value; 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; var OptionsSize : uint16; @@ -165,7 +237,7 @@ begin NewBuffer:= kalloc(TotalSize); //Copy over Header - NewHeader:= PDHCPHeader(buffer); + NewHeader:= PDHCPHeader(NewBuffer); memcpy(uint32(Header), uint32(NewHeader), sizeof(TDHCPHeader)); //Write all options @@ -221,14 +293,26 @@ var begin tracer.push_trace('dhcp.register'); + + { Get the beginning & end of the Options buffer } HeaderSize:= sizeOf(TDHCPHeader); bufferEnd:= puint8(uint32(p_data) + p_len); bufferStart:= puint8(uint32(p_data) + headerSize); + + { Buffer is our iterator } buffer:= bufferStart; + HaveOp:= false; HaveLen:= false; + 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 + { Get a new option LinkedList 'object' and store everything inside } Option:= newOption(DHCPOptions, Opcode, void(buffer), Length, not FlipExclude^[ord(Opcode)]); if Length = 2 then begin if Option^.Reverse_Endian then begin @@ -263,57 +347,271 @@ begin end; end; -procedure processPacket(p_data : void; p_len : uint16; context : PUDPPacketContext); +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 - Header : PDHCPHeader; - Options : PDHCPOptions; + i : uint16; + Option : PDHCPOption; + read16 : puint16; + read32 : puint32; + cfgopt : void; begin - tracer.push_trace('dhcp.processPacket'); + 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); +var + Header : PDHCPHeader; + Options : PDHCPOptions; + Option : PDHCPOption; + MAC : puint8; + i : uint32; + MsgType : uint8; + +begin + tracer.push_trace('dhcp.processPacket.enter'); + Outputln('DHCP','processPacket'); + + { Give access to header values & process to correct endianness. } Header:= PDHCPHeader(p_data); + processHeader(Header); + + { Process Options } Options:= newOptions; 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; procedure DHCPDiscover(); var + SendCtx : PUDPSendContext; + PacketCtx : PPacketContext; Header : PDHCPHeader; NewHeader : PDHCPHeader; - HeaderSize : Puint32; + HeaderSize : uint32; Options : PDHCPOptions; MsgType : uint8; + MAC : puint8; begin - tracer.push_trace('dhcp.DHCPDiscover'); - Header:= newHeader; - 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); + tracer.push_trace('dhcp.DHCPDiscover.begin'); + { Ensure we have a socket bound. } + if Socket <> nil then begin + { Clear any current configuration } + nullConfiguration(); - //Setup options - MsgType:= Ord(TDHCPMessageType.DISCOVER); - newOption(Options, DHCP_MESSAGE_TYPE, void(@MsgType), 1, false); + { Setup our Transaction ID } + Configuration^.Transaction:= rand32(); + + { Setup header } + Header:= createHeader(); + processHeader(Header); - NewOption(Options, END_VENDOR_OPTIONS, nil, 0, false); + { Setup options } + Options:= newOptions; + MsgType:= Ord(TDHCPMessageType.DISCOVER); + newOption(Options, DHCP_MESSAGE_TYPE, void(@MsgType), 1, false); + NewOption(Options, END_VENDOR_OPTIONS, nil, 0, false); - getIPv4Config^.UP:= true; + { 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; + + { 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; procedure register(); @@ -323,10 +621,23 @@ var begin tracer.push_trace('dhcp.register'); 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))); for i:=0 to 255 do begin FlipExclude^[i]:= false; end; + + { Set FlipExclude Table up to exclude certain OPCode from EndianFlips } FlipExclude^[ord(PAD)]:= true; FlipExclude^[ord(SUBNET_MASK)]:= true; FlipExclude^[ord(ROUTER)]:= true; @@ -383,15 +694,10 @@ begin FlipExclude^[ord(TZ_TIMEZONE)]:= true; FlipExclude^[ord(DOMAIN_SEARCH)]:= true; FlipExclude^[ord(CLASSLESS_STATIC_ROUTE)]:= true; - 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 console.outputln('DHCP', 'Failed to bind port 68.'); - end; - DHCPDiscover; + + { Bind to port 68 } + bind(); + console.outputln('DHCP', 'Register end.'); end; diff --git a/src/driver/netdev/E1000.pas b/src/driver/netdev/E1000.pas index 7f6ed044..5d0e63bb 100644 --- a/src/driver/netdev/E1000.pas +++ b/src/driver/netdev/E1000.pas @@ -165,7 +165,6 @@ var mem : puint32; begin - push_trace('E1000.writeCommand'); if (bar_type = 0) then begin mem:= puint32(mem_base + p_address); mem^:= p_value; @@ -173,7 +172,6 @@ begin outl(io_base + 0, p_address); outl(io_base + 4, p_address) end; - pop_trace; end; function readCommand(p_address : uint16) : uint32; @@ -181,7 +179,6 @@ var mem : puint32; begin - push_trace('E1000.readCommand'); if (bar_type = 0) then begin mem:= puint32(mem_base + p_address); readCommand:= mem^; @@ -189,7 +186,6 @@ begin outl(io_base, p_address); readCommand:= inl(io_base + 4); end; - pop_trace; end; function readStatus : uint32; @@ -202,7 +198,6 @@ var val, i : uint32; begin - push_trace('E1000.detectEEPROM'); val:= 0; writeCommand(REG_EEPROM, $1); 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; end; detectEEPROM:= eeprom_exists; - pop_trace; end; function EEPROMRead( address : uint8 ) : uint32; @@ -220,7 +214,6 @@ var tmp : uint32; begin - push_trace('E1000.EEPROMRead'); tmp:= 0; if (eeprom_exists) then begin writeCommand( REG_EEPROM, 1 OR (uint32(address) SHL 8) ); @@ -235,7 +228,6 @@ begin end; data:= uint16( (tmp SHR 16) AND ($FFFF) ); EEPROMRead:= data; - pop_trace; end; function readMACAddress() : boolean; @@ -271,7 +263,6 @@ begin end; end; readMACAddress:= res; - pop_trace; end; procedure startLink(); @@ -279,10 +270,8 @@ var val : uint32; begin - push_trace('E1000.startLink'); val:= readCommand(REG_CTRL); writeCommand(REG_CTRL, val OR ECTRL_SLU); - pop_trace; end; procedure rxinit(); @@ -293,7 +282,6 @@ var i : uint32; begin - push_trace('E1000.rxinit'); ptr:= puint8(kalloc(sizeof(TE1000_rx_desc) * E1000_NUM_RX_DESC + 16)); descs:= PE1000_rx_desc(ptr); for i:=0 to E1000_NUM_RX_DESC do begin @@ -323,7 +311,6 @@ begin 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); - pop_trace; end; procedure txinit(); @@ -334,7 +321,6 @@ var i : uint32; begin - push_trace('E1000.txinit'); ptr:= puint8(kalloc(sizeof(TE1000_tx_desc) * (E1000_NUM_TX_DESC + 16))); descs:= PE1000_tx_desc(ptr); 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); - console.output('E1000 Driver', 'TX VMem: '); console.writehexln(uint32(ptr)); - console.output('E1000 Driver', 'TX Mem: '); console.writehexln(uint32(outptr)); writeCommand(REG_TXDESCHI, 0); @@ -366,16 +350,13 @@ begin writeCommand(REG_TCTRL, $3003F0FA); writeCommand(REG_TIPG, $0060200A); end; - pop_trace; end; procedure enableInturrupt(); begin - push_trace('E1000.enableInterrupt'); writeCommand(REG_IMASK, $1F6DC); writeCommand(REG_IMASK, $FF AND NOT(4)); readCommand($C0); - pop_trace; end; procedure handleReceive(); @@ -387,7 +368,6 @@ var i : uint16; begin - push_trace('E1000.handleReceive'); while (rx_descs[rx_curr]^.status AND $1) > 0 do begin got_packet:= true; buf:= rx_buffs[rx_curr]; @@ -401,7 +381,6 @@ begin rx_curr:= (rx_curr + 1) mod E1000_NUM_RX_DESC; writeCommand(REG_RXDESCTAIL, old_cur); end; - pop_trace; end; procedure writeCardType(); @@ -421,8 +400,6 @@ var data : uint32; begin - push_trace('E1000.fire'); - writeToLogLn('L0: E1000 Fire'); status:= readCommand($C0); if (status AND $04) > 0 then begin startLink(); @@ -439,9 +416,7 @@ end; procedure console_command_mac(params : PParamList); begin - push_trace('E1000.console_command_mac'); writeMACAddress(@mac[0], getTerminalHWND); - pop_trace; end; procedure console_command_sendtest(params : PParamList); @@ -461,7 +436,6 @@ var ); begin - push_trace('E1000.console_command_sendtest'); TestPacket[6]:= mac[0]; TestPacket[7]:= mac[1]; TestPacket[8]:= mac[2]; @@ -579,35 +553,29 @@ end; function loadE1000(ptr : void) : boolean; begin - push_trace('E1000.loadE1000'); loadE1000:= false; if not Loaded then begin card_type:= ctE1000; loadE1000:= load(ptr); end; - pop_trace; end; function load82577LM(ptr : void) : boolean; begin - push_trace('E1000.load82577LM'); load82577LM:= false; if not Loaded then begin card_type:= ct82577LM; load82577LM:= load(ptr); end; - pop_trace; end; function loadI217(ptr : void) : boolean; begin - push_trace('E1000.loadI217'); loadI217:= false; if not Loaded then begin card_type:= ctI217; loadI217:= load(ptr); end; - pop_trace; end; procedure init(); @@ -643,7 +611,6 @@ var timeout : uint32; begin - push_trace('E1000.sendPacket'); tx_descs[tx_curr]^.address:= uint32(vtop(uint32(p_data))); tx_descs[tx_curr]^.length:= p_len; tx_descs[tx_curr]^.cmd:= CMD_EOP OR CMD_IFCS OR CMD_RS OR CMD_RPS; @@ -657,7 +624,6 @@ begin end; sendPacket:= 1; if timeout > 0 then sendPacket:= 0; - pop_trace; end; end. \ No newline at end of file diff --git a/src/include/rand.pas b/src/include/rand.pas index 95f55ec3..f76f3584 100644 --- a/src/include/rand.pas +++ b/src/include/rand.pas @@ -20,7 +20,7 @@ end; function rand32 : uint32; begin - rand32:= (rand SHL 16) AND rand; + rand32:= (rand SHL 16) OR rand; end; function rand16 : uint16; @@ -35,7 +35,7 @@ end; procedure srand(seed : uint32); begin - next:= seed; + next:= next + seed; end; end. \ No newline at end of file diff --git a/src/kernel.pas b/src/kernel.pas index d499b639..c9f17e77 100644 --- a/src/kernel.pas +++ b/src/kernel.pas @@ -19,8 +19,8 @@ uses tracer, drivermanagement, scheduler, + progmanager, PCI, - Terminal, strings, USB, testdriver, @@ -35,22 +35,12 @@ uses fonts, RTC, serial, - shell, - memview, - splash, - themer, - netlog, - vmlog, vm, - vmstate, - edit, - udpcat, cpu, md5, - md5sum, base64, - base64_prog, - rand; + rand, + terminal; procedure kmain(mbinfo: Pmultiboot_info_t; mbmagic: uint32); stdcall; @@ -159,7 +149,7 @@ begin isrmanager.init(); faults.init(); RTC.init(); - rand.srand((getDateTime.Seconds SHR 24) OR (getDateTime.Minutes SHR 16) OR (getDateTime.Hours SHR 8) OR (getDateTime.Day)); + pmemorymanager.init(); vmemorymanager.init(); lmemorymanager.init(); @@ -214,24 +204,7 @@ begin //vm.init(); { Init Progs } - tracer.push_trace('kmain.SHELLINIT'); - 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(); + progmanager.init(); { Init Splash } //tracer.push_trace('kmain.SPLASHINIT'); @@ -244,8 +217,10 @@ begin console.setdefaultattribute(console.combinecolors($17E0, $0000)); console.writestringln('Asuro Booted Correctly!'); console.setdefaultattribute(console.combinecolors($FFFF, $0000)); + writestringln(' '); 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'); while true do begin diff --git a/src/prog/md5sum.pas b/src/prog/md5sum.pas index 1f0cf8f3..2d8bbdb2 100644 --- a/src/prog/md5sum.pas +++ b/src/prog/md5sum.pas @@ -1,5 +1,5 @@ { - Prog->VMLog - Virtual Machine Event Log. + Prog->MD5Sum - MD5 Checksum of a given string. @author(Kieron Morris ) } diff --git a/src/tracer.pas b/src/tracer.pas index 18233228..5db519d1 100644 --- a/src/tracer.pas +++ b/src/tracer.pas @@ -20,6 +20,14 @@ implementation uses console, lmemorymanager, util, strings, serial, terminal; +type + PTracerEntry = ^TTracerEntry; + TTracerEntry = record + Next : PTracerEntry; + Data : pchar; + Previous : PTracerEntry; + end; + const MAX_TRACE = 40; @@ -29,6 +37,9 @@ var Traces : Array[0..MAX_TRACE-1] of PChar; c_lock : Boolean = false; +var + head : PTracerEntry; + tail : PTracerEntry; procedure terminal_command_tracer(Params : PParamList); var