| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710 |
- {
- $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: UInt16;
- const AHwAddressLen, AProtocolLen: UInt8; const AnOpType: UInt16;
- ASenderHw: TIdEtherAddr; ASenderPr: TIdInAddr; ATargetHw: TIdEtherAddr;
- ATargetPr: TIdInAddr; const APayload: TIdBytes; var VBuffer: TIdBytes);
- // DNS
- procedure IdRawBuildDns(const AnId, AFlags, ANumQuestions, ANumAnswerRecs, ANumAuthRecs, ANumAddRecs: UInt16;
- const APayload: TIdBytes; var VBuffer: TIdBytes);
- // Ethernet
- procedure IdRawBuildEthernet(ADest, ASource: TIdEtherAddr; AType: UInt16;
- const APayload: TIdBytes; var VBuffer: TIdBytes);
- // ICMP
- procedure IdRawBuildIcmpEcho(AType, ACode: UInt8; AnId, ASeq: UInt16;
- const APayload: TIdBytes; var VBuffer: TIdBytes);
- procedure IdRawBuildIcmpMask(AType, ACode: UInt8; AnId, ASeq: UInt16; AMask: UInt32;
- const APayload: TIdBytes; var VBuffer: TIdBytes);
- procedure IdRawBuildIcmpRedirect(const AType, ACode: UInt8; AGateway: TIdInAddr;
- const AnOrigLen: UInt16; const AnOrigTos: UInt8; const AnOrigId, AnOrigFrag: UInt16;
- const AnOrigTtl, AnOrigProtocol: UInt8; AnOrigSource, AnOrigDest: TIdInAddr;
- const AnOrigPayload: TIdBytes; var VBuffer: TIdBytes);
- procedure IdRawBuildIcmpTimeExceed(const AType, ACode: UInt8; const AnOrigLen: UInt16;
- const AnOrigTos: UInt8; const AnOrigId, AnOrigFrag: UInt16;
- const AnOrigTtl, AnOrigProtocol: UInt8; const AnOrigSource, AnOrigDest: TIdInAddr;
- const AnOrigPayload: TIdBytes; var VBuffer: TIdBytes);
- procedure IdRawBuildIcmpTimestamp(const AType, ACode: UInt8; const AnId, ASeq: UInt16;
- const AnOtime, AnRtime, ATtime: TIdNetTime; const APayload: TIdBytes;
- var VBuffer: TIdBytes);
- procedure IdRawBuildIcmpUnreach(AType, ACode: UInt8; AnOrigLen: UInt16;
- AnOrigTos: UInt8; AnOrigId, AnOrigFrag: UInt16; AnOrigTtl, AnOrigProtocol: UInt8;
- AnOrigSource, AnOrigDest: TIdInAddr; const AnOrigPayload, APayloadSize: Integer;
- var VBuffer: TIdBytes);
- // IGMP
- procedure IdRawBuildIgmp(AType, ACode: UInt8; AnIp: TIdInAddr;
- const APayload: UInt16; var VBuffer: TIdBytes);
- // IP
- procedure IdRawBuildIp(ALen: UInt16; ATos: UInt8; AnId, AFrag: UInt16;
- ATtl, AProtocol: UInt8; ASource, ADest: TIdInAddr; const APayload: TIdBytes;
- var VBuffer: TIdBytes; const AIdx: Integer = 0);
- // RIP
- procedure IdRawBuildRip(const ACommand, AVersion: UInt8;
- const ARoutingDomain, AnAddressFamily, ARoutingTag: UInt16;
- const AnAddr, AMask, ANextHop, AMetric: UInt32;
- const APayload: TIdBytes; var VBuffer: TIdBytes);
- // TCP
- procedure IdRawBuildTcp(const ASourcePort, ADestPort: UInt16;
- const ASeq, AnAck: UInt32; const AControl: UInt8;
- const AWindowSize, AnUrgent: UInt16; const APayload: TIdBytes;
- var VBuffer: TIdBytes);
- // UDP
- procedure IdRawBuildUdp(const ASourcePort, ADestPort: UInt16;
- const APayload: TIdBytes; var VBuffer: TIdBytes);
- implementation
- uses
- SysUtils;
- procedure IdRawBuildArp(const AHwAddressFormat, AProtocolFormat: UInt16;
- const AHwAddressLen, AProtocolLen: UInt8; const AnOpType: UInt16;
- ASenderHw: TIdEtherAddr; ASenderPr: TIdInAddr; ATargetHw: TIdEtherAddr;
- ATargetPr: TIdInAddr; const APayload: TIdBytes; var VBuffer: TIdBytes);
- var
- HdrArp: TIdArpHdr;
- LIdx: UInt32;
- LLen : UInt32;
- begin
- // check input
- LIdx := Id_ARP_HSIZE + Length(VBuffer);
- LLen := Length(VBuffer);
- if LLen < LIdx then begin
- SetLength(VBuffer, LIdx);
- end;
- // construct header
- HdrArp := TIdArpHdr.Create;
- try
- HdrArp.arp_hrd := GStack.HostToNetwork(AHwAddressFormat);
- HdrArp.arp_pro := GStack.HostToNetwork(AProtocolFormat);
- HdrArp.arp_hln := AHwAddressLen;
- HdrArp.arp_pln := AProtocolLen;
- HdrArp.arp_op := GStack.HostToNetwork(AnOpType);
- HdrArp.arp_sha.CopyFrom(ASenderHw);
- HdrArp.arp_spa.s_l := ASenderPr.s_l;
- HdrArp.arp_tha.CopyFrom(ATargetHw);
- HdrArp.arp_tpa.CopyFrom(ATargetPr);
- // copy payload
- if Length(APayload) > 0 then begin
- CopyTIdBytes(APayload, 0, VBuffer, Id_ICMP_ECHO_HSIZE, Length(APayload));
- end;
- // copy header
- LIdx := 0;
- HdrArp.WriteStruct(VBuffer, LIdx);
- finally
- FreeAndNil(HdrArp);
- end;
- end;
- procedure IdRawBuildDns(const AnId, AFlags, ANumQuestions, ANumAnswerRecs,
- ANumAuthRecs, ANumAddRecs: UInt16; const APayload: TIdBytes;
- var VBuffer: TIdBytes);
- var
- HdrDns: TIdDnsHdr;
- LIdx: UInt32;
- LLen : UInt32;
- begin
- // check input
- LIdx := Length(APayload) + Id_DNS_HSIZE;
- LLen := UInt32(Length(VBuffer));
- if LLen < LIdx then begin
- SetLength(VBuffer, LIdx);
- end;
- // construct header
- HdrDns := TIdDnsHdr.Create;
- try
- HdrDns.dns_id := GStack.HostToNetwork(AnId);
- HdrDns.dns_flags := GStack.HostToNetwork(AFlags);
- HdrDns.dns_num_q := GStack.HostToNetwork(ANumQuestions);
- HdrDns.dns_num_answ_rr := GStack.HostToNetwork(ANumAnswerRecs);
- HdrDns.dns_num_auth_rr := GStack.HostToNetwork(ANumAuthRecs);
- HdrDns.dns_num_addi_rr := GStack.HostToNetwork(ANumAddRecs);
- // copy payload
- if Length(APayload) > 0 then begin
- CopyTIdBytes(APayload, 0, VBuffer, Id_DNS_HSIZE, Length(APayload));
- end;
- // copy header
- LIdx := 0;
- HdrDns.WriteStruct(VBuffer, LIdx);
- finally
- FreeAndNil(HdrDns);
- end;
- end;
- procedure IdRawBuildEthernet(ADest, ASource: TIdEtherAddr; AType: UInt16;
- const APayload: TIdBytes; var VBuffer: TIdBytes);
- var
- HdrEth: TIdEthernetHdr;
- LIdx: UInt32;
- LLen : UInt32;
- begin
- // make sure VBuffer will be long enough
- LIdx := Length(ASource.Data) + Length(ADest.Data) + 2 + Length(APayload);
- LLen := Length(VBuffer);
- if LLen < LIdx then begin
- SetLength(VBuffer, LIdx);
- end;
- // construct header
- HdrEth := TIdEthernetHdr.Create;
- try
- HdrEth.ether_dhost.CopyFrom(ADest);
- HdrEth.ether_shost.CopyFrom(ASource);
- HdrEth.ether_type := GStack.HostToNetwork(AType);
- // copy header
- LIdx := 0;
- HdrEth.WriteStruct(VBuffer, LIdx);
- // copy payload if present
- if Length(APayload) > 0 then begin
- CopyTIdBytes(APayload, 0, VBuffer, LIdx, Length(APayload));
- end;
- finally
- FreeAndNil(HdrEth);
- end;
- end;
- // TODO: check nibbles in IP header
- procedure IdRawBuildIp(ALen: UInt16; ATos: UInt8; AnId, AFrag: UInt16; ATtl, AProtocol: UInt8;
- ASource, ADest: TIdInAddr; const APayload: TIdBytes; var VBuffer: TIdBytes;
- const AIdx: Integer = 0);
- var
- HdrIp: TIdIpHdr;
- LIdx: UInt32;
- LLen : UInt32;
- begin
- // check input
- LIdx := Id_IP_HSIZE + Length(APayload) + AIdx;
- LLen := Length(VBuffer);
- if LLen < LIdx then begin
- SetLength(VBuffer, LIdx);
- end;
- // construct header
- HdrIp := TIdIpHdr.Create;
- try
- 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 := GStack.HostToNetwork(UInt16(ALen + Id_IP_HSIZE));
- HdrIp.ip_id := GStack.HostToNetwork(AnId);
- HdrIp.ip_off := GStack.HostToNetwork(AFrag);
- HdrIp.ip_ttl := ATtl;
- HdrIp.ip_p := AProtocol;
- HdrIp.ip_sum := 0; // do checksum later
- HdrIp.ip_src.CopyFrom(ASource);
- HdrIp.ip_dst.CopyFrom(ADest);
- // copy header
- LIdx := AIdx;
- HdrIp.WriteStruct(VBuffer, LIdx);
- // copy payload
- if Length(APayload) > 0 then begin
- CopyTIdBytes(APayload, 0, VBuffer, LIdx, Length(APayload));
- end;
- finally
- FreeANdNil(HdrIp);
- end;
- end;
- procedure IdRawBuildIcmpEcho(AType, ACode: UInt8; AnId, ASeq: UInt16;
- const APayload: TIdBytes; var VBuffer: TIdBytes);
- var
- HdrIcmp: TIdIcmpHdr;
- LIdx, LLen : UInt32;
- begin
- // check input
- LIdx := Id_ICMP_ECHO_HSIZE + Length(APayload);
- LLen := Length(VBuffer);
- if LLen < LIdx then begin
- SetLength(VBuffer, LIdx);
- end;
- // construct header
- HdrIcmp := TIdIcmpHdr.Create;
- try
- HdrIcmp.icmp_type := AType;
- HdrIcmp.icmp_code := ACode;
- HdrIcmp.icmp_hun.echo_id := GStack.HostToNetwork(AnId);
- HdrIcmp.icmp_hun.echo_seq := GStack.HostToNetwork(ASeq);
- // copy payload
- if Length(APayload) > 0 then begin
- CopyTIdBytes(APayload, 0, VBuffer, Id_ICMP_ECHO_HSIZE, Length(APayload));
- end;
- // copy header
- LIdx := 0;
- HdrIcmp.WriteStruct(VBuffer, LIdx);
- finally
- FreeAndNil(HdrIcmp);
- end;
- end;
- type
- TIdICMPMask = class(TIdICMPHdr)
- protected
- Ficmp_mask: UInt32;
- function GetBytesLen: UInt32; override;
- public
- procedure ReadStruct(const ABytes : TIdBytes; var VIndex : UInt32); override;
- procedure WriteStruct(var VBytes : TIdBytes; var VIndex : UInt32); override;
- property icmp_mask: UInt32 read Ficmp_mask write Ficmp_mask;
- end;
- function TIdICMPMask.GetBytesLen: UInt32;
- begin
- Result := inherited GetBytesLen + 4;
- end;
- procedure TIdICMPMask.ReadStruct(const ABytes : TIdBytes; var VIndex : UInt32);
- begin
- inherited ReadStruct(ABytes, VIndex);
- Ficmp_mask := BytesToUInt32(ABytes, VIndex);
- Inc(VIndex, 4);
- end;
- procedure TIdICMPMask.WriteStruct(var VBytes : TIdBytes; var VIndex : UInt32);
- begin
- inherited WriteStruct(VBytes, VIndex);
- CopyTIdUInt32(Ficmp_mask, VBytes, VIndex);
- Inc(VIndex, 4);
- end;
- procedure IdRawBuildIcmpMask(AType, ACode: UInt8; AnId, ASeq: UInt16; AMask: UInt32;
- const APayload: TIdBytes; var VBuffer: TIdBytes);
- var
- HdrIcmp: TIdICMPMask;
- LIdx: UInt32;
- LLen : UInt32;
- begin
- // check input
- LIdx := Id_ICMP_MASK_HSIZE + Length(APayload);
- LLen := Length(VBuffer);
- if LLen < LIdx then begin
- SetLength(VBuffer, LIdx);
- end;
- // construct header
- HdrIcmp := TIdICMPMask.Create;
- try
- HdrIcmp.icmp_type := AType;
- HdrIcmp.icmp_code := ACode;
- HdrIcmp.icmp_hun.echo_id := GStack.HostToNetwork(AnId);
- HdrIcmp.icmp_hun.echo_seq := GStack.HostToNetwork(ASeq);
- HdrIcmp.icmp_mask := GStack.HostToNetwork(AMask);
- // copy header
- LIdx := 0;
- HdrIcmp.WriteStruct(VBuffer, LIdx);
- // copy payload
- if Length(APayload) > 0 then begin
- CopyTIdBytes(APayload, 0, VBuffer, LIdx, Length(APayload));
- end;
- finally
- FreeAndNil(HdrIcmp);
- end;
- end;
- procedure IdRawBuildIcmpUnreach(AType, ACode: UInt8; AnOrigLen: UInt16;
- AnOrigTos: UInt8; AnOrigId, AnOrigFrag: UInt16; AnOrigTtl, AnOrigProtocol: UInt8;
- AnOrigSource, AnOrigDest: TIdInAddr; const AnOrigPayload, APayloadSize: Integer;
- var VBuffer: TIdBytes);
- var
- HdrIcmp: TIdIcmpHdr;
- LIdx: UInt32;
- LLen : UInt32;
- begin
- // check input
- LIdx := Id_ICMP_UNREACH_HSIZE + Id_IP_HSIZE + 2;
- LLen := Length(VBuffer);
- if LLen < LIdx then begin
- SetLength(VBuffer, LIdx);
- end;
- // construct header
- HdrIcmp := TIdIcmpHdr.Create;
- try
- 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, ToBytes(AnOrigPayload), VBuffer, Id_ICMP_UNREACH_HSIZE);
- // copy header
- LIdx := 0;
- HdrIcmp.WriteStruct(VBuffer, LIdx);
- finally
- FreeAndNil(HdrIcmp);
- end;
- end;
- procedure IdRawBuildIcmpTimeExceed(const AType, ACode: UInt8; const AnOrigLen: UInt16;
- const AnOrigTos: UInt8; const AnOrigId, AnOrigFrag: UInt16;
- const AnOrigTtl, AnOrigProtocol: UInt8; const AnOrigSource, AnOrigDest: TIdInAddr;
- const AnOrigPayload: TIdBytes; var VBuffer: TIdBytes);
- var
- HdrIcmp: TIdIcmpHdr;
- LIdx: UInt32;
- LLen : UInt32;
- begin
- // check input
- LIdx := Id_ICMP_TIMEXCEED_HSIZE + Id_IP_HSIZE + Length(AnOrigPayload);
- Llen := Length(VBuffer);
- if Llen < LIdx then begin
- SetLength(VBuffer, LIdx);
- end;
- // construct header
- HdrIcmp := TIdIcmpHdr.Create;
- try
- 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, VBuffer, Id_ICMP_TIMEXCEED_HSIZE);
- // copy header
- LIdx := 0;
- HdrIcmp.WriteStruct(VBuffer, LIdx);
- finally
- FreeAndNil(HdrIcmp);
- end;
- end;
- type
- TIdIcmpTS = class(TIdIcmpHdr)
- protected
- Ficmp_dun: TIdicmp_dun;
- function GetBytesLen: UInt32; override;
- public
- constructor Create; override;
- destructor Destroy; override;
- procedure ReadStruct(const ABytes : TIdBytes; var VIndex : UInt32); override;
- procedure WriteStruct(var VBytes : TIdBytes; var VIndex : UInt32); override;
- property icmp_dun: TIdicmp_dun read Ficmp_dun;
- end;
- constructor TIdIcmpTS.Create;
- begin
- inherited Create;
- Ficmp_dun := TIdicmp_dun.Create;
- end;
- destructor TIdIcmpTS.Destroy;
- begin
- Ficmp_dun.Free;
- inherited Destroy;
- end;
- function TIdIcmpTS.GetBytesLen: UInt32;
- begin
- Result := inherited GetBytesLen + Ficmp_dun.BytesLen;
- end;
- procedure TIdIcmpTS.ReadStruct(const ABytes : TIdBytes; var VIndex : UInt32);
- begin
- inherited ReadStruct(ABytes, VIndex);
- Ficmp_dun.ReadStruct(ABytes, VIndex);
- end;
- procedure TIdIcmpTS.WriteStruct(var VBytes : TIdBytes; var VIndex : UInt32);
- begin
- inherited WriteStruct(VBytes, VIndex);
- Ficmp_dun.WriteStruct(VBytes, VIndex);
- end;
- procedure IdRawBuildIcmpTimestamp(const AType, ACode: UInt8; const AnId, ASeq: UInt16;
- const AnOtime, AnRtime, ATtime: TIdNetTime; const APayload: TIdBytes;
- var VBuffer: TIdBytes);
- var
- HdrIcmp: TIdIcmpTS;
- LIdx, LLen : UInt32;
- begin
- // check input
- LIdx := Id_ICMP_TS_HSIZE + Length(APayload);
- LLen := Length(VBuffer);
- if LLen < LIdx then begin
- SetLength(VBuffer, LIdx);
- end;
- // construct header
- HdrIcmp := TIdIcmpTS.Create;
- try
- HdrIcmp.icmp_type := AType;
- HdrIcmp.icmp_code := ACode;
- HdrIcmp.icmp_hun.echo_id := GStack.HostToNetwork(AnId);
- HdrIcmp.icmp_hun.echo_seq := GStack.HostToNetwork(ASeq);
- HdrIcmp.icmp_dun.ts_otime := GStack.HostToNetwork(AnOtime); // original timestamp
- HdrIcmp.icmp_dun.ts_rtime := GStack.HostToNetwork(AnRtime); // receive timestamp
- HdrIcmp.icmp_dun.ts_ttime := GStack.HostToNetwork(ATtime); // transmit timestamp
- // copy header
- LIdx := 0;
- HdrIcmp.WriteStruct(VBuffer, LIdx);
- // copy payload
- if Length(APayload) > 0 then begin
- CopyTIdBytes(APayload, 0, VBuffer, LIdx, Length(APayload));
- end;
- finally
- FreeAndNil(HdrIcmp);
- end;
- end;
- procedure IdRawBuildIcmpRedirect(const AType, ACode: UInt8; AGateway: TIdInAddr;
- const AnOrigLen: UInt16; const AnOrigTos: UInt8; const AnOrigId, AnOrigFrag: UInt16;
- const AnOrigTtl, AnOrigProtocol: UInt8; AnOrigSource, AnOrigDest: TIdInAddr;
- const AnOrigPayload: TIdBytes; var VBuffer: TIdBytes);
- var
- HdrIcmp: TIdIcmpHdr;
- LIdx, LLen : UInt32;
- begin
- // check input
- LIdx := Id_ICMP_REDIRECT_HSIZE + Id_IP_HSIZE + Length(AnOrigPayload);
- LLen := Length(VBuffer);
- if LLen < LIdx then begin
- SetLength(VBuffer, LIdx);
- end;
- // construct header
- HdrIcmp := TIdIcmpHdr.Create;
- try
- HdrIcmp.icmp_type := AType;
- HdrIcmp.icmp_code := ACode;
- HdrIcmp.icmp_hun.gateway_s_b1 := AGateway.s_l; // gateway address
- // attach original header
- IdRawBuildIp(0, AnOrigTos, AnOrigId, AnOrigFrag, AnOrigTtl, AnOrigProtocol,
- AnOrigSource, AnOrigDest, AnOrigPayload, VBuffer, Id_ICMP_REDIRECT_HSIZE);
- // copy header
- LIdx := 0;
- HdrIcmp.WriteStruct(VBuffer, LIdx);
- finally
- FreeAndNil(HdrIcmp);
- end;
- end;
- procedure IdRawBuildIgmp(AType, ACode: UInt8; AnIp: TIdInAddr;
- const APayload: UInt16; var VBuffer: TIdBytes);
- var
- HdrIgmp: TIdIgmpHdr;
- LIdx: UInt32;
- LLen : UInt32;
- begin
- // check input
- LIdx := 2 + Id_IGMP_HSIZE;
- LLen := Length(VBuffer);
- if LLen < LIdx then begin
- SetLength(VBuffer, LIdx);
- end;
- // construct header
- HdrIgmp := TIdIgmpHdr.Create;
- try
- HdrIgmp.igmp_type := AType;
- HdrIgmp.igmp_code := ACode;
- HdrIgmp.igmp_sum := 0;
- HdrIgmp.igmp_group.s_l := AnIp.s_l; // group address or 0
- // copy payload
- CopyTIdUInt16(APayload, VBuffer, Id_IGMP_HSIZE);
- // copy header
- LIdx := 0;
- HdrIgmp.WriteStruct(VBuffer, LIdx);
- finally
- FreeAndNil(HdrIgmp);
- end;
- end;
- procedure IdRawBuildRip(const ACommand, AVersion: UInt8;
- const ARoutingDomain, AnAddressFamily, ARoutingTag: UInt16;
- const AnAddr, AMask, ANextHop, AMetric: UInt32;
- const APayload: TIdBytes; var VBuffer: TIdBytes);
- var
- HdrRip: TIdRipHdr;
- LIdx: UInt32;
- LLen : UInt32;
- begin
- // check input
- LIdx := Id_RIP_HSIZE + Length(APayload);
- LLen := Length(VBuffer);
- if LLen < LIdx then begin
- SetLength(VBuffer, LIdx);
- end;
- // construct header
- HdrRip := TIdRipHdr.Create;
- try
- HdrRip.rip_cmd := ACommand;
- HdrRip.rip_ver := AVersion;
- HdrRip.rip_rd := GStack.HostToNetwork(ARoutingDomain);
- HdrRip.rip_af := GStack.HostToNetwork(AnAddressFamily);
- HdrRip.rip_rt := GStack.HostToNetwork(ARoutingTag);
- HdrRip.rip_addr := GStack.HostToNetwork(AnAddr);
- HdrRip.rip_mask := GStack.HostToNetwork(AMask);
- HdrRip.rip_next_hop := GStack.HostToNetwork(ANextHop);
- HdrRip.rip_metric := GStack.HostToNetwork(AMetric);
- // copy payload
- if Length(APayload) > 0 then begin
- CopyTIdBytes(APayload, 0, VBuffer, Id_RIP_HSIZE, Length(APayload));
- end;
- // copy header
- LIdx := 0;
- HdrRip.WriteStruct(VBuffer, LIdx);
- finally
- FreeAndNil(HdrRip);
- end;
- end;
- // TODO: check nibbles in TCP header
- procedure IdRawBuildTcp(const ASourcePort, ADestPort: UInt16;
- const ASeq, AnAck: UInt32; const AControl: UInt8;
- const AWindowSize, AnUrgent: UInt16; const APayload: TIdBytes;
- var VBuffer: TIdBytes);
- var
- HdrTcp: TIdTcpHdr;
- LIdx, LLen: UInt32;
- begin
- // check input
- LIdx := Id_TCP_HSIZE + Length(VBuffer);
- LLen := Length(VBuffer);
- if LLen < LIdx then begin
- SetLength(VBuffer, LIdx);
- end;
- // construct header
- HdrTcp := TIdTcpHdr.Create;
- try
- HdrTcp.tcp_sport := GStack.HostToNetwork(ASourcePort);
- HdrTcp.tcp_dport := GStack.HostToNetwork(ADestPort);
- HdrTcp.tcp_seq := GStack.HostToNetwork(ASeq);
- HdrTcp.tcp_ack := GStack.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 := GStack.HostToNetwork(AWindowSize); // window size
- HdrTcp.tcp_sum := 0;
- HdrTcp.tcp_urp := AnUrgent; // urgent pointer
- // copy payload
- if Length(APayload) > 0 then begin
- CopyTIdBytes(APayload, 0, VBuffer, Id_TCP_HSIZE, Length(APayload));
- end;
- // copy header
- LIdx := 0;
- HdrTcp.WriteStruct(VBuffer, LIdx);
- finally
- FreeAndNil(HdrTcp);
- end;
- end;
- procedure IdRawBuildUdp(const ASourcePort, ADestPort: UInt16;
- const APayload: TIdBytes; var VBuffer: TIdBytes);
- var
- HdrUdp: TIdUdpHdr;
- LIdx: UInt32;
- LLen : UInt32;
- begin
- // check input
- LIdx := Id_UDP_HSIZE + Length(APayload);
- LLen := Length(VBuffer);
- if LLen < Lidx then begin
- SetLength(VBuffer, LIdx);
- end;
- // construct header
- HdrUdp := TIdUdpHdr.Create;
- try
- HdrUdp.udp_sport := 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
- FreeAndNil(HdrUdp);
- end;
- end;
- end.
|