git-svn-id: https://spexeah.com:8443/svn/Asuro@974 6dbc8c32-bb84-406f-8558-d1cf31a0ab0c

This commit is contained in:
kieron 2020-07-11 18:50:23 +00:00
parent fd564f56b7
commit b9666fb196
3 changed files with 194 additions and 30 deletions

View File

@ -200,8 +200,8 @@ type
Bootp_Flags : uint16; Bootp_Flags : uint16;
Client_IP : TIPv4Address; Client_IP : TIPv4Address;
Your_IP : TIPv4Address; Your_IP : TIPv4Address;
Server_IP : TIPV4Header; Server_IP : TIPv4Address;
Relay_Agent_IP : TIPV4Header; Relay_Agent_IP : TIPv4Address;
Client_MAC : TMACAddress; Client_MAC : TMACAddress;
Padding : Array[0..9] of uint8; Padding : Array[0..9] of uint8;
Server_Hostname : Array[0..63] of uint8; Server_Hostname : Array[0..63] of uint8;

View File

@ -5,7 +5,7 @@ interface
uses uses
lmemorymanager, console, lmemorymanager, console,
nettypes, netutils, udp, netlog, net, nettypes, netutils, udp, netlog, net,
util, rand, lists, tracer; util, rand, lists, tracer, ipv4;
type type
TDHCPOptions = PLinkedListBase; TDHCPOptions = PLinkedListBase;
@ -32,13 +32,18 @@ var
Socket : PUDPBindContext; Socket : PUDPBindContext;
FlipExclude : PFlipExclude; FlipExclude : PFlipExclude;
procedure newOption(DHCPOptions : PDHCPOptions; Opcode : TDHCPOpCode; Data : void; Length : uint32; SwapEndian : Boolean); function newHeader : PDHCPHeader;
begin
tracer.push_trace('dhcp.newHeader');
newHeader:= PDHCPHeader(kalloc(sizeof(TDHCPHeader)));
end;
function newOption(DHCPOptions : PDHCPOptions; Opcode : TDHCPOpCode; Data : void; Length : uint32; SwapEndian : Boolean) : PDHCPOption;
var var
Option : PDHCPOption; Option : PDHCPOption;
read32 : puint32;
read16 : puint16;
begin begin
tracer.push_trace('dhcp.newOption');
Option:= PDHCPOption(LL_Add(PLinkedListBase(DHCPOptions))); Option:= PDHCPOption(LL_Add(PLinkedListBase(DHCPOptions)));
Option^.Opcode:= Opcode; Option^.Opcode:= Opcode;
Option^.Size:= Length; Option^.Size:= Length;
@ -46,21 +51,10 @@ begin
if Length > 0 then begin if Length > 0 then begin
Option^.Value:= kalloc(Length); Option^.Value:= kalloc(Length);
memcpy(uint32(Data), uint32(Option^.Value), Length); memcpy(uint32(Data), uint32(Option^.Value), Length);
if Length = 2 then begin
if SwapEndian then begin
read16:= puint16(Option^.Value);
read16^:= switchendian16(read16^);
end;
end;
if Length = 4 then begin
if SwapEndian then begin
read32:= puint32(Option^.Value);
read32^:= switchendian32(read32^);
end;
end;
end else begin end else begin
Option^.Value:= nil; Option^.Value:= nil;
end; end;
newOption:= Option;
end; end;
procedure deleteOption(DHCPOptions : PDHCPOptions; idx : uint32); procedure deleteOption(DHCPOptions : PDHCPOptions; idx : uint32);
@ -68,6 +62,7 @@ var
Option : PDHCPOption; Option : PDHCPOption;
begin begin
tracer.push_trace('dhcp.deleteOptions');
Option:= PDHCPOption(LL_Get(PLinkedListBase(DHCPOptions), idx)); Option:= PDHCPOption(LL_Get(PLinkedListBase(DHCPOptions), idx));
if Option <> nil then begin if Option <> nil then begin
if Option^.Value <> nil then begin if Option^.Value <> nil then begin
@ -77,13 +72,21 @@ begin
end; end;
end; end;
function getOption(DHCPOptions : PDHCPOptions; idx : uint32) : PDHCPOption;
begin
tracer.push_trace('dhcp.getOption');
getOption:= PDHCPOption(LL_Get(PLinkedListBase(DHCPOptions),idx));
end;
function newOptions : PDHCPOptions; function newOptions : PDHCPOptions;
begin begin
tracer.push_trace('dhcp.newOptions');
newOptions:= PDHCPOptions(LL_New(sizeof(TDHCPOption))); newOptions:= PDHCPOptions(LL_New(sizeof(TDHCPOption)));
end; end;
procedure freeOptions(Options : PDHCPOptions); procedure freeOptions(Options : PDHCPOptions);
begin begin
tracer.push_trace('dhcp.freeOptions');
if Options <> nil then begin if Options <> nil then begin
while LL_Size(PLinkedListBase(Options)) > 0 do begin while LL_Size(PLinkedListBase(Options)) > 0 do begin
deleteOption(Options, 0); deleteOption(Options, 0);
@ -92,27 +95,132 @@ begin
end; end;
end; end;
function writeOptions(Header : PDHCPHeader; Options : PDHCPOptions; newLength : puint16) : PDHCPHeader; function getOptionsCount(Options : PDHCPOptions) : uint32;
begin begin
tracer.push_trace('dhcp.getOptionsCount');
getOptionsCount:= LL_Size(PLinkedListBase(Options));
end; end;
function calculateOptionsSize(Options : PDHCPOptions) : uint16;
var
i : uint32;
Option : PDHCPOption;
OptionsSize : uint16;
begin
tracer.push_trace('dhcp.calculateOptionsSize');
OptionsSize := 0;
for i:=0 to getOptionsCount(Options)-1 do begin
Option:= PDHCPOption(LL_Get(PLinkedListBase(Options),i));
case Option^.Opcode of
PAD,END_VENDOR_OPTIONS : inc(OptionsSize,1);
else inc(OptionsSize, 2 + Option^.Size);
end;
end;
calculateOptionsSize:= OptionsSize;
end;
function getEndianCorrectValue16(Option : PDHCPOption) : uint16;
var
Value : uint16;
begin
tracer.push_trace('dhcp.getEndianCorrectValue16');
Value:= PuInt16(Option^.Value)^;
if Option^.Reverse_Endian then
getEndianCorrectValue16:= switchendian16(Value)
else
getEndianCorrectValue16:= Value;
end;
function getEndianCorrectValue32(Option : PDHCPOption) : uint32;
var
Value : uint32;
begin
tracer.push_trace('dhcp.getEndianCorrectValue32');
Value:= puint32(Option^.Value)^;
if Option^.Reverse_Endian then
getEndianCorrectValue32:= switchendian32(Value)
else
getEndianCorrectValue32:= Value;
end;
function writeOptions(Header : PDHCPHeader; Options : PDHCPOptions; newLength : puint16) : PDHCPHeader;
var
OptionsSize : uint16;
TotalSize : uint16;
NewBuffer : void;
NewHeader : PDHCPHeader;
buffer : puint8;
read8 : puint8;
read16 : puint16;
read32 : puint32;
Option : PDHCPOption;
i : uint32;
begin
tracer.push_trace('dhcp.writeOptions');
OptionsSize := calculateOptionsSize(Options);
TotalSize:= OptionsSize + SizeOf(TDHCPHeader);
NewBuffer:= kalloc(TotalSize);
//Copy over Header
NewHeader:= PDHCPHeader(buffer);
memcpy(uint32(Header), uint32(NewHeader), sizeof(TDHCPHeader));
//Write all options
buffer:= puint8(NewBuffer);
inc(buffer, SizeOf(TDHCPHeader));
for i:=0 to getOptionsCount(Options)-1 do begin
Option:= getOption(Options, i);
case Option^.Opcode of
PAD,END_VENDOR_OPTIONS:begin
buffer^:= Ord(Option^.Opcode);
inc(buffer);
end;
else begin
buffer^:= Ord(Option^.OpCode);
inc(buffer);
buffer^:= Option^.Size;
inc(buffer);
case Option^.Size of
2:begin
read16:= puint16(buffer);
read16^:= getEndianCorrectValue16(Option);
end;
4:begin
read32:= puint32(buffer);
read32^:= getEndianCorrectValue32(Option);
end;
else begin
memcpy(uint32(Option^.Value), uint32(buffer), Option^.Size);
end;
end;
inc(buffer, Option^.Size);
end;
end;
end;
newLength^:= TotalSize;
writeOptions:= PDHCPHeader(NewBuffer);
end;
procedure readOptions(DHCPOptions : PDHCPOptions; p_data : void; p_len : uint16); procedure readOptions(DHCPOptions : PDHCPOptions; p_data : void; p_len : uint16);
var var
headerSize : uint32; headerSize : uint32;
buffer : puint8; buffer : puint8;
bufferEnd : puint8; bufferEnd : puint8;
bufferStart : puint8; bufferStart : puint8;
HaveOp : boolean; HaveOp : boolean;
HaveLen : boolean; HaveLen : boolean;
Opcode : TDHCPOpCode; Opcode : TDHCPOpCode;
Length : uint8; Length : uint8;
read32 : puint32;
read16 : puint16;
Option : PDHCPOption;
begin begin
tracer.push_trace('dhcp.register');
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);
@ -121,7 +229,19 @@ begin
HaveLen:= false; HaveLen:= false;
while (uint32(buffer) < uint32(bufferEnd)) do begin while (uint32(buffer) < uint32(bufferEnd)) do begin
if HaveLen then begin if HaveLen then begin
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 Option^.Reverse_Endian then begin
read16:= puint16(Option^.Value);
read16^:= switchendian16(read16^);
end;
end;
if Length = 4 then begin
if Option^.Reverse_Endian then begin
read32:= puint32(Option^.Value);
read32^:= switchendian32(read32^);
end;
end;
inc(buffer, Length); inc(buffer, Length);
HaveOp:= false; HaveOp:= false;
HaveLen:= false; HaveLen:= false;
@ -132,11 +252,7 @@ begin
end else begin end else begin
Opcode:= TDHCPOpCode(buffer^); Opcode:= TDHCPOpCode(buffer^);
case opcode of case opcode of
PAD:begin PAD,END_VENDOR_OPTIONS:begin
Length:= 0;
haveLen:= true;
end;
END_VENDOR_OPTIONS:begin
Length:= 0; Length:= 0;
haveLen:= true; haveLen:= true;
end; end;
@ -148,12 +264,55 @@ begin
end; end;
procedure processPacket(p_data : void; p_len : uint16; context : PUDPPacketContext); procedure processPacket(p_data : void; p_len : uint16; context : PUDPPacketContext);
begin var
Header : PDHCPHeader;
Options : PDHCPOptions;
begin
tracer.push_trace('dhcp.processPacket');
Header:= PDHCPHeader(p_data);
Options:= newOptions;
readOptions(Options, p_data, p_len);
end; end;
procedure DHCPDiscover(); procedure DHCPDiscover();
var
Header : PDHCPHeader;
NewHeader : PDHCPHeader;
HeaderSize : Puint32;
Options : PDHCPOptions;
MsgType : uint8;
begin 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);
//Setup options
MsgType:= Ord(TDHCPMessageType.DISCOVER);
newOption(Options, DHCP_MESSAGE_TYPE, void(@MsgType), 1, false);
NewOption(Options, END_VENDOR_OPTIONS, nil, 0, false);
getIPv4Config^.UP:= true;
end; end;
@ -232,6 +391,7 @@ begin
tueOK:console.outputln('DHCP', 'Successfully bound port 68.'); tueOK:console.outputln('DHCP', 'Successfully bound port 68.');
else console.outputln('DHCP', 'Failed to bind port 68.'); else console.outputln('DHCP', 'Failed to bind port 68.');
end; end;
DHCPDiscover;
console.outputln('DHCP', 'Register end.'); console.outputln('DHCP', 'Register end.');
end; end;

View File

@ -54,6 +54,10 @@ type
Void = ^uInt32; Void = ^uInt32;
HWND = uint32; HWND = uint32;
yord = uInt8;
xord = uInt8;
zord = uInt16;
//Alternate Types //Alternate Types
UBit1 = 0..(1 shl 01) - 1; UBit1 = 0..(1 shl 01) - 1;
UBit2 = 0..(1 shl 02) - 1; UBit2 = 0..(1 shl 02) - 1;