www.pudn.com > indyprelim.zip > IdRawFunctions.pas
{
$Project$
$Workfile$
$Revision$
$DateUTC$
$Id$
This file is part of the Indy (Internet Direct) project, and is offered
under the dual-licensing agreement described on the Indy website.
(http://www.indyproject.org/)
Copyright:
(c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved.
}
{
$Log$
}
{
Rev 1.5 2004.02.03 4:16:50 PM czhower
For unit name changes.
Rev 1.4 2/1/2004 4:52:30 PM JPMugaas
Removed the rest of the Todo; items.
Rev 1.3 2/1/2004 4:20:30 PM JPMugaas
Should work in Win32. TODO: See about DotNET.
Rev 1.2 2003.10.11 5:49:06 PM czhower
-VCL fixes for servers
-Chain suport for servers (Super core)
-Scheduler upgrades
-Full yarn support
Rev 1.1 2003.09.30 1:23:00 PM czhower
Stack split for DotNet
Rev 1.0 11/13/2002 08:45:36 AM JPMugaas
}
unit IdRawFunctions;
interface
{$i IdCompilerDefines.inc}
uses
IdGlobal, IdRawHeaders, IdStack;
// ARP
procedure IdRawBuildArp(const AHwAddressFormat, AProtocolFormat: word;
const AHwAddressLen, AProtocolLen: byte;
const AnOpType: word;
ASenderHw: TIdEtherAddr;
ASenderPr: TIdInAddr;
ATargetHw: TIdEtherAddr;
ATargetPr: TIdInAddr;
const APayload : TIdBytes; var VBuffer : TIdBytes);
// DNS
procedure IdRawBuildDns(const AnId, AFlags, ANumQuestions, ANumAnswerRecs, ANumAuthRecs, ANumAddRecs: word;
const APayload : TIdBytes;
var VBuffer : TIdBytes);
// Ethernet
procedure IdRawBuildEthernet(ADest, ASource: TIdEtherAddr; AType: word;
const APayload : TIdBytes; var VBuffer : TIdBytes);
// ICMP
procedure IdRawBuildIcmpEcho(AType, ACode: byte; AnId, ASeq: word;
const APayload : TIdBytes; var VBuffer : TIdBytes);
procedure IdRawBuildIcmpMask(AType, ACode: byte; AnId, ASeq: word; AMask: longword;
const APayload : TIdBytes; var VBuffer : TIdBytes);
procedure IdRawBuildIcmpRedirect(const AType, ACode: byte;
AGateway: TIdInAddr;
const AnOrigLen: word;
const AnOrigTos: byte;
const AnOrigId, AnOrigFrag: word;
const AnOrigTtl, AnOrigProtocol: byte;
AnOrigSource, AnOrigDest: TIdInAddr;
const AnOrigPayload : TIdBytes;
var VBuffer : TIdBytes);
procedure IdRawBuildIcmpTimeExceed(const AType, ACode: byte;
const AnOrigLen: word;
const AnOrigTos: byte;
const AnOrigId, AnOrigFrag: word;
const AnOrigTtl: byte;
const AnOrigProtocol: byte;
const AnOrigSource, AnOrigDest: TIdInAddr;
const AnOrigPayload : TIdBytes;
var VBuffer : TIdBytes);
procedure IdRawBuildIcmpTimestamp(const AType, ACode: byte;
const AnId, ASeq: word;
const AnOtime, AnRtime, ATtime: TIdNetTime;
const APayload : TIdBytes;
var VBuffer : TIdBytes);
procedure IdRawBuildIcmpUnreach(AType, ACode: byte;
AnOrigLen: word;
AnOrigTos: byte; AnOrigId, AnOrigFrag: word;
AnOrigTtl, AnOrigProtocol: byte;
AnOrigSource, AnOrigDest: TIdInAddr;
const AnOrigPayload, APayloadSize: integer;
var VBuffer : TIdBytes);
// IGMP
procedure IdRawBuildIgmp(AType, ACode: byte;
AnIp: TIdInAddr;
const APayload : Word; const APayloadSize: integer;
var VBuffer : TIdBytes);
// IP
procedure IdRawBuildIp(ALen: word; ATos: byte; AnId, AFrag: word; ATtl, AProtocol: byte;
ASource, ADest: TIdInAddr; const APayload : TIdBytes; var VBuffer : TIdBytes; const AIdx : Integer = 0);
// RIP
procedure IdRawBuildRip(const ACommand, AVersion: byte;
const ARoutingDomain, AnAddressFamily, ARoutingTag: word;
const AnAddr, AMask, ANextHop, AMetric: longword;
const APayload : TIdBytes;
var VBuffer : TIdBytes);
// TCP
procedure IdRawBuildTcp(const ASourcePort, ADestPort: word;
const ASeq, AnAck: longword;
const AControl: byte;
const AWindowSize, AnUrgent: word;
const APayload : TIdBytes;
var VBuffer : TIdBytes);
// UDP
procedure IdRawBuildUdp(const ASourcePort, ADestPort: word;
const APayload :TIdBytes;
var VBuffer :TIdBytes);
implementation
uses IdSys;
procedure IdRawBuildArp(const AHwAddressFormat, AProtocolFormat: word;
const AHwAddressLen, AProtocolLen: byte;
const AnOpType: word;
ASenderHw: TIdEtherAddr;
ASenderPr: TIdInAddr;
ATargetHw: TIdEtherAddr;
ATargetPr: TIdInAddr;
const APayload : TIdBytes; var VBuffer : TIdBytes);
var
HdrArp: TIdArpHdr;
LIdx : Integer;
begin
// check input
LIdx := Id_ARP_HSIZE + Length(VBuffer);
if Length(VBuffer) 0) then
begin
CopyTIdBytes(APayload,0,VBuffer,Id_ICMP_ECHO_HSIZE,Length(APayload));
end;
// copy header
LIdx := 0;
HdrArp.WriteStruct(VBuffer,LIdx);
finally
Sys.FreeAndNil(HdrArp);
end;
end;
procedure IdRawBuildDns(const AnId, AFlags, ANumQuestions, ANumAnswerRecs, ANumAuthRecs, ANumAddRecs: word;
const APayload : TIdBytes;
var VBuffer : TIdBytes);
var
HdrDns: TIdDnsHdr;
LIdx : Integer;
begin
// check input
LIdx := Length(APayload) +Id_DNS_HSIZE;
if Length(VBuffer)0 then
begin
CopyTIdBytes(APayload,0,VBuffer,Id_DNS_HSIZE,Length(APayload));
end;
// copy header
LIdx := 0;
HdrDns.WriteStruct(VBuffer,LIdx);
finally
Sys.FreeAndNil(HdrDns);
end;
end;
procedure IdRawBuildEthernet(ADest, ASource: TIdEtherAddr; AType: word;
const APayload : TIdBytes; var VBuffer : TIdBytes);
var
HdrEth: TIdEthernetHdr;
LIdx : Integer;
begin
// init result
HdrEth:= TIdEthernetHdr.create;
try
// make sure VBuffer will be long enough
LIdx := Length(ASource.Data)+ Length(ADest.Data)+2+Length(APayload);
if Length(VBuffer)0 then
begin
CopyTIdBytes(APayload,0,VBuffer,LIdx,Length(APayload));
end;
finally
Sys.FreeAndNil(HdrEth);
end;
end;
// TODO: check nibbles in IP header
procedure IdRawBuildIp(ALen: word; ATos: byte; AnId, AFrag: word; ATtl, AProtocol: byte;
ASource, ADest: TIdInAddr; const APayload : TIdBytes; var VBuffer : TIdBytes; const AIdx : Integer = 0);
var
HdrIp: TIdIpHdr;
LIdx : Integer;
begin
// init result
HdrIp := TIdIpHdr.create;
// check input
try
LIdx := Id_IP_HSIZE+Length(APayload)+AIdx;
if Length(VBuffer)0 then
begin
CopyTIdBytes(APayload,0,VBuffer,LIdx,Length(APayload));
end;
finally
Sys.FreeANdNil(HdrIp);
end;
end;
procedure IdRawBuildIcmpEcho(AType, ACode: byte; AnId, ASeq: word;
const APayload : TIdBytes; var VBuffer : TIdBytes);
var
HdrIcmp: TIdIcmpHdr;
LIdx : Integer;
begin
// check input
if Length(VBuffer) 0) then
begin
CopyTIdBytes(APayload,0,VBuffer,Id_ICMP_ECHO_HSIZE,Length(APayload));
end;
// copy header
LIdx := 0;
HdrIcmp.WriteStruct(VBuffer,LIdx);
finally
Sys.FreeAndNil(HdrIcmp);
end;
end;
procedure IdRawBuildIcmpMask(AType, ACode: byte; AnId, ASeq: word; AMask: longword;
const APayload : TIdBytes; var VBuffer : TIdBytes);
var
HdrIcmp: TIdIcmpHdr;
LIdx : Integer;
begin
// check input
if Length(VBuffer) 0) then
begin
CopyTIdBytes(APayload,0,VBuffer, Id_ICMP_MASK_HSIZE,Length(APayload));
end;
// copy header
LIdx := 0;
HdrIcmp.WriteStruct(VBuffer,LIdx);
finally
Sys.FreeANdNil(HdrIcmp);
end;
end;
procedure IdRawBuildIcmpUnreach(AType, ACode: byte;
AnOrigLen: word;
AnOrigTos: byte;
AnOrigId, AnOrigFrag: word;
AnOrigTtl, AnOrigProtocol: byte;
AnOrigSource, AnOrigDest: TIdInAddr;
const AnOrigPayload, APayloadSize: integer;
var VBuffer : TIdBytes);
var
HdrIcmp: TIdIcmpHdr;
LIdx : Integer;
begin
// check input
if Length(VBuffer) 0) then
begin
CopyTIdBytes(APayload,0,VBuffer, Id_ICMP_TS_HSIZE,Length(APayload));
end;
// copy header
LIdx := 0;
HdrIcmp.WriteStruct(VBuffer,LIdx);
finally
Sys.FreeAndNil(HdrIcmp);
end;
end;
procedure IdRawBuildIcmpRedirect(const AType, ACode: byte;
AGateway: TIdInAddr;
const AnOrigLen: word;
const AnOrigTos: byte;
const AnOrigId, AnOrigFrag: word;
const AnOrigTtl, AnOrigProtocol: byte;
AnOrigSource, AnOrigDest: TIdInAddr;
const AnOrigPayload : TIdBytes;
var VBuffer : TIdBytes);
var
HdrIcmp: TIdIcmpHdr;
LIdx : Integer;
begin
// check input
LIdx := Id_ICMP_REDIRECT_HSIZE+Length(AnOrigPayload)+Id_IP_HSIZE;
if Length(VBuffer) 0) then
begin
CopyTIdBytes(APayload,0,VBuffer, Id_RIP_HSIZE,Length(APayload));
end;
// copy header
LIdx := 0;
HdrRip.WriteStruct(VBuffer,LIdx);
finally
Sys.FreeAndNil(HdrRip);
end;
end;
// TODO: check nibbles in TCP header
procedure IdRawBuildTcp(const ASourcePort, ADestPort: word;
const ASeq, AnAck: longword;
const AControl: byte;
const AWindowSize, AnUrgent: word;
const APayload : TIdBytes;
var VBuffer : TIdBytes);
var
HdrTcp: TIdTcpHdr;
LIdx : Integer;
begin
// check input
LIdx := Id_TCP_HSIZE + Length(VBuffer);
if Length(VBuffer) 0) then
begin
CopyTIdBytes(APayload,0,VBuffer, Id_TCP_HSIZE,Length(APayload));
end;
// copy header
LIdx := 0;
HdrTcp.WriteStruct(VBuffer,LIdx);
finally
Sys.FreeAndNil(HdrTcp);
end;
end;
procedure IdRawBuildUdp(const ASourcePort, ADestPort: word;
const APayload :TIdBytes;
var VBuffer :TIdBytes);
var
HdrUdp: TIdUdpHdr;
LIdx : Integer;
begin
// check input
LIdx := Id_UDP_HSIZE + Length(APayload);
if Length(VBuffer)< Lidx then
begin
SetLength(VBuffer,LIdx);
end;
// construct header
HdrUdp:= TIdUdpHdr.create;
try
HdrUdp.udp_dport := GStack.HostToNetwork(ASourcePort);
HdrUdp.udp_dport := GStack.HostToNetwork(ADestPort);
//LIdx should be okay here since we set that to the packet length earlier
HdrUdp.udp_ulen := GStack.HostToNetwork(LIdx);
HdrUdp.udp_sum := 0;
// copy payload
if (Length(APayload) > 0) then
begin
CopyTIdBytes(APayload,0,VBuffer, Id_UDP_HSIZE,Length(APayload));
end;
// copy header
LIdx := 0;
HdrUdp.WriteStruct(VBuffer,LIdx);
finally
Sys.FreeAndNil(HdrUdp);
end;
end;
end.