www.pudn.com > indy10.0.52_source.rar > IdRawFunctions.pas


{ $HDR$} 
{**********************************************************************} 
{ Unit archived using Team Coherence                                   } 
{ Team Coherence is Copyright 2002 by Quality Software Components      } 
{                                                                      } 
{ For further information / comments, visit our WEB site at            } 
{ http://www.TeamCoherence.com                                         } 
{**********************************************************************} 
{} 
{ $Log:  11958: IdRawFunctions.pas  
{ 
{   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 
 
uses 
  IdStackBSDBase, IdRawHeaders, IdStack; 
 
// ARP 
function IdRawBuildArp(AHwAddressFormat, AProtocolFormat: word; AHwAddressLen, AProtocolLen: byte; 
  AnOpType: word; ASenderHw: TIdEtherAddr; ASenderPr: TIdInAddr; ATargetHw: TIdEtherAddr; ATargetPr: TIdInAddr; 
  const APayload; APayloadSize: integer; var ABuffer): boolean; 
 
// DNS 
function IdRawBuildDns(AnId, AFlags, ANumQuestions, ANumAnswerRecs, ANumAuthRecs, ANumAddRecs: word; 
  const APayload; APayloadSize: integer; var ABuffer): boolean; 
 
// Ethernet 
function IdRawBuildEthernet(ADest, ASource: TIdEtherAddr; AType: word; 
  const APayload; APayloadSize: integer; var ABuffer): boolean; 
 
// ICMP 
function IdRawBuildIcmpEcho(AType, ACode: byte; AnId, ASeq: word; 
  const APayload; APayloadSize: integer; var ABuffer): boolean; 
function IdRawBuildIcmpMask(AType, ACode: byte; AnId, ASeq: word; AMask: longword; 
  const APayload; APayloadSize: integer; var ABuffer): boolean; 
function IdRawBuildIcmpRedirect(AType, ACode: byte; AGateway: TIdInAddr; 
  AnOrigLen: word; AnOrigTos: byte; AnOrigId, AnOrigFrag: word; AnOrigTtl, AnOrigProtocol: byte; 
  AnOrigSource, AnOrigDest: TIdInAddr; const AnOrigPayload; APayloadSize: integer; var ABuffer): boolean; 
function IdRawBuildIcmpTimeExceed(AType, ACode: byte; AnOrigLen: word; AnOrigTos: byte; 
  AnOrigId, AnOrigFrag: word; AnOrigTtl: byte; AnOrigProtocol: byte; 
  AnOrigSource, AnOrigDest: TIdInAddr; const AnOrigPayload; APayloadSize: integer; var ABuffer): boolean; 
function IdRawBuildIcmpTimestamp(AType, ACode: byte; AnId, ASeq: word; 
  AnOtime, AnRtime, ATtime: TIdNetTime; const APayload; APayloadSize: integer; var ABuffer): boolean; 
function IdRawBuildIcmpUnreach(AType, ACode: byte; AnOrigLen: word; 
  AnOrigTos: byte; AnOrigId, AnOrigFrag: word; AnOrigTtl, AnOrigProtocol: byte; 
  AnOrigSource, AnOrigDest: TIdInAddr; const AnOrigPayload, APayloadSize: integer; var ABuffer): boolean; 
 
// IGMP 
function IdRawBuildIgmp(AType, ACode: byte; AnIp: TIdInAddr; 
  const APayload, APayloadSize: integer; var ABuffer): boolean; 
 
// IP 
function IdRawBuildIp(ALen: word; ATos: byte; AnId, AFrag: word; ATtl, AProtocol: byte; 
  ASource, ADest: TIdInAddr; const APayload; APayloadSize: integer; var ABuffer): boolean; 
 
// RIP 
function IdRawBuildRip(ACommand, AVersion: byte; ARoutingDomain, AnAddressFamily, 
  ARoutingTag: word; AnAddr, AMask, ANextHop, AMetric: longword; 
  const APayload; APayloadSize: integer; var ABuffer): boolean; 
 
// TCP 
function IdRawBuildTcp(ASourcePort, ADestPort: word; ASeq, AnAck: longword; 
  AControl: byte; AWindowSize, AnUrgent: word; 
  const APayload, APayloadSize: integer; var ABuffer): boolean; 
 
// UDP 
function IdRawBuildUdp(ASourcePort, ADestPort: word; const APayload; 
  APayloadSize: integer; var ABuffer): boolean; 
 
 
implementation 
 
uses 
  IdGlobal; 
 
function IdRawBuildArp(AHwAddressFormat, AProtocolFormat: word; AHwAddressLen, AProtocolLen: byte; 
  AnOpType: word; ASenderHw: TIdEtherAddr; ASenderPr: TIdInAddr; ATargetHw: TIdEtherAddr; ATargetPr: TIdInAddr; 
  const APayload; APayloadSize: integer; var ABuffer): boolean; 
var 
  HdrArp: TIdArpHdr; 
begin 
  // init result 
  Result := FALSE; 
 
  // check input 
	if (@ABuffer = nil) then 
    Exit; 
 
  // construct header 
 
  HdrArp.arp_hrd := GBSDStack.HostToNetwork(AHwAddressFormat); 
  HdrArp.arp_pro := GBSDStack.HostToNetwork(AProtocolFormat); 
  HdrArp.arp_hln := AHwAddressLen; 
  HdrArp.arp_pln := AProtocolLen; 
  HdrArp.arp_op  := GBSDStack.HostToNetwork(AnOpType); 
  Move(ASenderHw, HdrArp.arp_sha, AHwAddressLen); 
  Move(ASenderPr, HdrArp.arp_spa, AProtocolLen);           
  Move(ATargetHw, HdrArp.arp_tha, AHwAddressLen);          
  Move(ATargetPr, HdrArp.arp_tpa, AProtocolLen); 
 
  // copy payload 
  if ((@APayload <> nil) and (APayloadSize > 0)) then 
    Move(APayload, pointer(integer(@ABuffer) + Id_ARP_HSIZE)^, APayloadSize); 
 
  // copy header 
  Move(HdrArp, ABuffer, sizeof(HdrArp)); 
 
  Result := TRUE; 
end; 
 
function IdRawBuildDns(AnId, AFlags, ANumQuestions, ANumAnswerRecs, ANumAuthRecs, ANumAddRecs: word; 
  const APayload; APayloadSize: integer; var ABuffer): boolean; 
var 
  HdrDns: TIdDnsHdr; 
begin 
  // init result 
  Result := FALSE; 
 
  // check input 
	if (@ABuffer = nil) then 
    Exit; 
 
  // construct header 
  HdrDns.dns_id          := GBSDStack.HostToNetwork(AnId); 
 
  HdrDns.dns_flags       := GBSDStack.HostToNetwork(AFlags); 
 
  HdrDns.dns_num_q       := GBSDStack.HostToNetwork(ANumQuestions); 
 
  HdrDns.dns_num_answ_rr := GBSDStack.HostToNetwork(ANumAnswerRecs); 
  HdrDns.dns_num_auth_rr := GBSDStack.HostToNetwork(ANumAuthRecs); 
 
  HdrDns.dns_num_addi_rr := GBSDStack.HostToNetwork(ANumAddRecs); 
 
  // copy payload 
  if ((@APayload <> nil) and (APayloadSize > 0)) then 
    Move(APayload, pointer(integer(@ABuffer) + Id_DNS_HSIZE)^, APayloadSize); 
 
  // copy header 
  Move(HdrDns, ABuffer, sizeof(HdrDns)); 
 
  Result := TRUE; 
end; 
 
function IdRawBuildEthernet(ADest, ASource: TIdEtherAddr; AType: word; 
  const APayload; APayloadSize: integer; var ABuffer): boolean; 
var 
  HdrEth: TIdEthernetHdr; 
begin 
  // init result 
  Result := FALSE; 
 
  // check input 
	if (@ABuffer = nil) then 
    Exit; 
 
  // construct header 
  Move(ADest, HdrEth.ether_dhost, Id_ETHER_ADDR_LEN); 
  Move(ASource, HdrEth.ether_shost, Id_ETHER_ADDR_LEN); 
  HdrEth.ether_type := (GStack as TIdStackBSDBase).HostToNetwork(AType); 
 
  // copy payload 
  if ((@APayload <> nil) and (APayloadSize > 0)) then 
    Move(APayload, pointer(integer(@ABuffer) + Id_ETH_HSIZE)^, APayloadSize); 
 
  // copy header 
  Move(HdrEth, ABuffer, sizeof(HdrEth)); 
 
  Result := TRUE; 
end; 
 
// TODO: check nibbles in IP header 
function IdRawBuildIp(ALen: word; ATos: byte; AnId, AFrag: word; ATtl, AProtocol: byte; 
  ASource, ADest: TIdInAddr; const APayload; APayloadSize: integer; var ABuffer): boolean; 
var 
  HdrIp: TIdIpHdr; 
begin 
  // init result 
  Result := FALSE; 
 
  // check input 
	if (@ABuffer = nil) then 
    Exit; 
 
  // construct header 
  HdrIp.ip_verlen := (4 shl 4) + (Id_IP_HSIZE div 4);     // IPv4 shl 4, 20 bytes div 4 
  HdrIp.ip_tos    := ATos; 
  HdrIp.ip_len    := GBSDStack.HostToNetwork(Id_IP_HSIZE + ALen); 
  HdrIp.ip_id     := GBSDStack.HostToNetwork(AnId); 
  HdrIp.ip_off    := GBSDStack.HostToNetwork(AFrag); 
  HdrIp.ip_ttl    := ATtl; 
  HdrIp.ip_p      := AProtocol; 
  HdrIp.ip_sum    := 0;                                     // do checksum later 
  HdrIp.ip_src    := ASource; 
  HdrIp.ip_dst    := ADest; 
 
  // copy payload 
  if ((@APayload <> nil) and (APayloadSize > 0)) then 
    Move(APayload, pointer(integer(@ABuffer) + Id_IP_HSIZE)^, APayloadSize); 
 
  // copy header 
  Move(HdrIp, ABuffer, Id_IP_HSIZE); 
 
  Result := TRUE; 
end; 
 
function IdRawBuildIcmpEcho(AType, ACode: byte; AnId, ASeq: word; 
  const APayload; APayloadSize: integer; var ABuffer): boolean; 
var 
  HdrIcmp: TIdIcmpHdr; 
begin 
  // init result 
  Result := FALSE; 
 
  // check input 
	if (@ABuffer = nil) then 
    Exit; 
 
  // construct header 
  HdrIcmp.icmp_type := AType; 
  HdrIcmp.icmp_code := ACode; 
  HdrIcmp.icmp_hun.echo.id := GBSDStack.HostToNetwork(AnId); 
  HdrIcmp.icmp_hun.echo.seq := GBSDStack.HostToNetwork(ASeq); 
 
  // copy payload 
  if ((@APayload <> nil) and (APayloadSize > 0)) then 
    Move(APayload, pointer(integer(@ABuffer) + Id_ICMP_ECHO_HSIZE)^, APayloadSize); 
 
  // copy header 
  Move(HdrIcmp, ABuffer, Id_ICMP_ECHO_HSIZE); 
 
  Result := TRUE; 
end; 
 
function IdRawBuildIcmpMask(AType, ACode: byte; AnId, ASeq: word; AMask: longword; 
  const APayload; APayloadSize: integer; var ABuffer): boolean; 
var 
  HdrIcmp: TIdIcmpHdr; 
begin 
  // init result 
  Result := FALSE; 
 
  // check input 
	if (@ABuffer = nil) then 
    Exit; 
 
  // construct header 
  HdrIcmp.icmp_type := AType; 
  HdrIcmp.icmp_code := ACode; 
  HdrIcmp.icmp_hun.echo.id := GBSDStack.HostToNetwork(AnId); 
  HdrIcmp.icmp_hun.echo.seq := GBSDStack.HostToNetwork(ASeq); 
  HdrIcmp.icmp_dun.mask := GBSDStack.HostToNetwork(AMask); 
 
  // copy payload 
  if ((@APayload <> nil) and (APayloadSize > 0)) then 
    Move(APayload, pointer(integer(@ABuffer) + Id_ICMP_MASK_HSIZE)^, APayloadSize); 
 
  // copy header 
  Move(HdrIcmp, ABuffer, Id_ICMP_MASK_HSIZE); 
 
  Result := TRUE; 
end; 
 
function IdRawBuildIcmpUnreach(AType, ACode: byte; AnOrigLen: word; 
  AnOrigTos: byte; AnOrigId, AnOrigFrag: word; AnOrigTtl, AnOrigProtocol: byte; 
  AnOrigSource, AnOrigDest: TIdInAddr; const AnOrigPayload, APayloadSize: integer; var ABuffer): boolean; 
var 
  HdrIcmp: TIdIcmpHdr; 
begin 
  // init result 
  Result := FALSE; 
 
  // check input 
	if (@ABuffer = nil) then 
    Exit; 
 
  // construct header 
  HdrIcmp.icmp_type := AType; 
  HdrIcmp.icmp_code := ACode; 
  HdrIcmp.icmp_hun.echo.id := 0; 
  HdrIcmp.icmp_hun.echo.seq := 0; 
 
  // attach original header 
  IdRawBuildIp(0, AnOrigTos, AnOrigId, AnOrigFrag, AnOrigTtl, AnOrigProtocol, 
    AnOrigSource, AnOrigDest, AnOrigPayload, APayloadSize, 
    pointer(integer(@ABuffer) + Id_ICMP_UNREACH_HSIZE)^); 
 
  // copy header 
  Move(HdrIcmp, ABuffer, Id_ICMP_UNREACH_HSIZE); 
 
  Result := TRUE; 
end; 
 
function IdRawBuildIcmpTimeExceed(AType, ACode: byte; AnOrigLen: word; AnOrigTos: byte; 
  AnOrigId, AnOrigFrag: word; AnOrigTtl: byte; AnOrigProtocol: byte; 
  AnOrigSource, AnOrigDest: TIdInAddr; const AnOrigPayload; APayloadSize: integer; var ABuffer): boolean; 
var 
  HdrIcmp: TIdIcmpHdr; 
begin 
  // init result 
  Result := FALSE; 
 
  // check input 
	if (@ABuffer = nil) then 
    Exit; 
 
  // construct header 
  HdrIcmp.icmp_type := AType; 
  HdrIcmp.icmp_code := ACode; 
  HdrIcmp.icmp_hun.echo.id := 0; 
  HdrIcmp.icmp_hun.echo.seq := 0; 
 
  // attach original header 
  IdRawBuildIp(0, AnOrigTos, AnOrigId, AnOrigFrag, AnOrigTtl, AnOrigProtocol, 
    AnOrigSource, AnOrigDest, AnOrigPayload, APayloadSize, 
    pointer(integer(@ABuffer) + Id_ICMP_TIMEXCEED_HSIZE)^); 
 
  // copy header 
  Move(HdrIcmp, ABuffer, Id_ICMP_TIMEXCEED_HSIZE); 
 
  Result := TRUE; 
end; 
 
function IdRawBuildIcmpTimestamp(AType, ACode: byte; AnId, ASeq: word; 
  AnOtime, AnRtime, ATtime: TIdNetTime; const APayload; APayloadSize: integer; var ABuffer): boolean; 
var 
  HdrIcmp: TIdIcmpHdr; 
begin 
  // init result 
  Result := FALSE; 
 
  // check input 
	if (@ABuffer = nil) then 
    Exit; 
 
  // construct header 
  HdrIcmp.icmp_type             := AType; 
  HdrIcmp.icmp_code             := ACode; 
  HdrIcmp.icmp_hun.echo.id      := (GStack as TIdStackBSDBase).HostToNetwork(AnId); 
  HdrIcmp.icmp_hun.echo.seq     := (GStack as TIdStackBSDBase).HostToNetwork(ASeq); 
  HdrIcmp.icmp_dun.ts.otime     := (GStack as TIdStackBSDBase).HostToNetwork(AnOtime);      // original timestamp 
  HdrIcmp.icmp_dun.ts.rtime     := (GStack as TIdStackBSDBase).HostToNetwork(AnRtime);      // receive timestamp 
  HdrIcmp.icmp_dun.ts.ttime     := (GStack as TIdStackBSDBase).HostToNetwork(ATtime);       // transmit timestamp 
 
  // copy payload 
  if ((@APayload <> nil) and (APayloadSize > 0)) then 
    Move(APayload, pointer(integer(@ABuffer) + Id_ICMP_TS_HSIZE)^, APayloadSize); 
 
  // copy header 
  Move(HdrIcmp, ABuffer, Id_ICMP_TS_HSIZE); 
 
  Result := TRUE; 
end; 
 
function IdRawBuildIcmpRedirect(AType, ACode: byte; AGateway: TIdInAddr; 
  AnOrigLen: word; AnOrigTos: byte; AnOrigId, AnOrigFrag: word; AnOrigTtl, AnOrigProtocol: byte; 
  AnOrigSource, AnOrigDest: TIdInAddr; const AnOrigPayload; APayloadSize: integer; var ABuffer): boolean; 
var 
  HdrIcmp: TIdIcmpHdr; 
begin 
  // init result 
  Result := FALSE; 
 
  // check input 
	if (@ABuffer = nil) then 
    Exit; 
 
  // construct header 
  HdrIcmp.icmp_type           := AType; 
  HdrIcmp.icmp_code           := ACode; 
  HdrIcmp.icmp_hun.gateway    := AGateway;      // gateway address 
 
  // attach original header 
  IdRawBuildIp(0, AnOrigTos, AnOrigId, AnOrigFrag, AnOrigTtl, AnOrigProtocol, 
    AnOrigSource, AnOrigDest, AnOrigPayload, APayloadSize, 
    pointer(integer(@ABuffer) + Id_ICMP_REDIRECT_HSIZE)^); 
 
  // copy header 
  Move(HdrIcmp, ABuffer, Id_ICMP_REDIRECT_HSIZE); 
 
  Result := TRUE; 
end; 
 
function IdRawBuildIgmp(AType, ACode: byte; AnIp: TIdInAddr; 
  const APayload, APayloadSize: integer; var ABuffer): boolean; 
var 
  HdrIgmp: TIdIgmpHdr; 
begin 
  // init result 
  Result := FALSE; 
 
  // check input 
	if (@ABuffer = nil) then 
    Exit; 
 
  // construct header 
  HdrIgmp.igmp_type         := AType; 
  HdrIgmp.igmp_code         := ACode; 
  HdrIgmp.igmp_sum          := 0; 
  HdrIgmp.igmp_group        := AnIp;      // group address or 0 
 
  // copy payload 
  if ((@APayload <> nil) and (APayloadSize > 0)) then 
    Move(APayload, pointer(integer(@ABuffer) + Id_IGMP_HSIZE)^, APayloadSize); 
 
  // copy header 
  Move(HdrIgmp, ABuffer, sizeof(HdrIgmp)); 
 
  Result := TRUE; 
end; 
 
function IdRawBuildRip(ACommand, AVersion: byte; ARoutingDomain, AnAddressFamily, 
  ARoutingTag: word; AnAddr, AMask, ANextHop, AMetric: longword; 
  const APayload; APayloadSize: integer; var ABuffer): boolean; 
var 
  HdrRip: TIdRipHdr; 
begin 
  // init result 
  Result := FALSE; 
 
  // check input 
	if (@ABuffer = nil) then 
    Exit; 
 
  // construct header 
  HdrRip.rip_cmd      := ACommand; 
  HdrRip.rip_ver      := AVersion; 
  HdrRip.rip_rd       := GBSDStack.HostToNetwork(ARoutingDomain); 
  HdrRip.rip_af       := GBSDStack.HostToNetwork(AnAddressFamily); 
  HdrRip.rip_rt       := GBSDStack.HostToNetwork(ARoutingTag); 
  HdrRip.rip_addr     := GBSDStack.HostToNetwork(AnAddr); 
  HdrRip.rip_mask     := GBSDStack.HostToNetwork(AMask); 
  HdrRip.rip_next_hop := GBSDStack.HostToNetwork(ANextHop); 
  HdrRip.rip_metric   := GBSDStack.HostToNetwork(AMetric); 
 
  // copy payload 
  if ((@APayload <> nil) and (APayloadSize > 0)) then 
    Move(APayload, pointer(integer(@ABuffer) + Id_RIP_HSIZE)^, APayloadSize); 
 
  // copy header 
  Move(HdrRip, ABuffer, sizeof(HdrRip)); 
 
  Result := TRUE; 
end; 
 
// TODO: check nibbles in TCP header 
function IdRawBuildTcp(ASourcePort, ADestPort: word; ASeq, AnAck: longword; 
  AControl: byte; AWindowSize, AnUrgent: word; 
  const APayload, APayloadSize: integer; var ABuffer): boolean; 
var 
  HdrTcp: TIdTcpHdr; 
begin 
  // init result 
  Result := FALSE; 
 
  // check input 
	if (@ABuffer = nil) then 
    Exit; 
 
  // construct header 
  HdrTcp.tcp_sport    := GBSDStack.HostToNetwork(ASourcePort); 
  HdrTcp.tcp_dport    := GBSDStack.HostToNetwork(ADestPort); 
  HdrTcp.tcp_seq      := GBSDStack.HostToNetwork(ASeq); 
  HdrTcp.tcp_ack      := GBSDStack.HostToNetwork(AnAck);                // acknowledgement number 
  HdrTcp.tcp_flags    := AControl;                              // control flags 
  HdrTcp.tcp_x2off    := ((Id_TCP_HSIZE div 4) shl 4) + 0;      // 20 bytes div 4, x2 unused 
  HdrTcp.tcp_win      := GBSDStack.HostToNetwork(AWindowSize);          // window size 
  HdrTcp.tcp_sum      := 0; 
  HdrTcp.tcp_urp      := AnUrgent;                              // urgent pointer 
 
  // copy payload 
  if ((@APayload <> nil) and (APayloadSize > 0)) then 
    Move(APayload, pointer(integer(@ABuffer) + Id_TCP_HSIZE)^, APayloadSize); 
 
  // copy header 
  Move(HdrTcp, ABuffer, sizeof(HdrTcp)); 
 
  Result := TRUE; 
end; 
 
function IdRawBuildUdp(ASourcePort, ADestPort: word; const APayload; 
  APayloadSize: integer; var ABuffer): boolean; 
var 
  HdrUdp: TIdUdpHdr; 
begin 
  Result := FALSE; 
 
  // check input 
	if (@ABuffer = nil) then 
    Exit; 
 
  // construct header 
  HdrUdp.udp_dport    := GBSDStack.HostToNetwork(ASourcePort); 
  HdrUdp.udp_dport    := GBSDStack.HostToNetwork(ADestPort); 
  HdrUdp.udp_ulen     := GBSDStack.HostToNetwork(Id_UDP_HSIZE + APayloadSize); 
  HdrUdp.udp_sum      := 0; 
 
  // copy payload 
  if ((@APayload <> nil) and (APayloadSize > 0)) then 
    Move(APayload, pointer(integer(@ABuffer) + Id_UDP_HSIZE)^, APayloadSize); 
 
  // copy header 
  Move(HdrUdp, ABuffer, sizeof(HdrUdp)); 
 
  Result := TRUE; 
end; 
 
 
end.