git-svn-id: https://spexeah.com:8443/svn/Asuro@974 6dbc8c32-bb84-406f-8558-d1cf31a0ab0c
This commit is contained in:
parent
fd564f56b7
commit
b9666fb196
@ -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;
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user