public override byte[] GetProtocolPacketBytes(byte[] payLoad)
{
byte[] udpPacket = new byte[UdpHeaderLength + payLoad.Length], pseudoHeader = null, byteValue = null;
int offset = 0;
// Build the UDP packet first
byteValue = BitConverter.GetBytes(srcPort);
Array.Copy(byteValue, 0, udpPacket, offset, byteValue.Length);
offset += byteValue.Length;
byteValue = BitConverter.GetBytes(destPort);
Array.Copy(byteValue, 0, udpPacket, offset, byteValue.Length);
offset += byteValue.Length;
byteValue = BitConverter.GetBytes(udpLength);
Array.Copy(byteValue, 0, udpPacket, offset, byteValue.Length);
offset += byteValue.Length;
udpPacket[offset++] = 0; // Checksum is initially zero
udpPacket[offset++] = 0;
// Copy payload to end of packet
Array.Copy(payLoad, 0, udpPacket, offset, payLoad.Length);
if (ipv4PacketHeader != null)
{
pseudoHeader = new byte[UdpHeaderLength + 12 + payLoad.Length];
// Build the IPv4 pseudo header
offset = 0;
// Source address
byteValue = ipv4PacketHeader.SourceAddress.GetBytes();
Array.Copy(byteValue, 0, pseudoHeader, offset, byteValue.Length);
offset += byteValue.Length;
// Destination address
byteValue = ipv4PacketHeader.DestinationAddress.GetBytes();
Array.Copy(byteValue, 0, pseudoHeader, offset, byteValue.Length);
offset += byteValue.Length;
// 1 byte zero pad plus next header protocol value
pseudoHeader[offset++] = 0;
pseudoHeader[offset++] = ipv4PacketHeader.Protocol;
// Packet length
byteValue = BitConverter.GetBytes(udpLength);
Array.Copy(byteValue, 0, pseudoHeader, offset, byteValue.Length);
offset += byteValue.Length;
// Copy the UDP packet to the end of this
Array.Copy(udpPacket, 0, pseudoHeader, offset, udpPacket.Length);
}
else if (ipv6PacketHeader != null)
{
uint ipv6PayloadLength;
pseudoHeader = new byte[UdpHeaderLength + 40 + payLoad.Length];
// Build the IPv6 pseudo header
offset = 0;
// Source address
byteValue = ipv6PacketHeader.SourceAddress.GetBytes();
Array.Copy(byteValue, 0, pseudoHeader, offset, byteValue.Length);
offset += byteValue.Length;
// Destination address
byteValue = ipv6PacketHeader.DestinationAddress.GetBytes();
Array.Copy(byteValue, 0, pseudoHeader, offset, byteValue.Length);
offset += byteValue.Length;
ipv6PayloadLength = (uint)NetworkingHelpers.HostToNetworkOrder((int)(payLoad.Length + UdpHeaderLength));
// Packet payload: ICMPv6 headers plus payload
byteValue = BitConverter.GetBytes(ipv6PayloadLength);
Array.Copy(byteValue, 0, pseudoHeader, offset, byteValue.Length);
offset += byteValue.Length;
// 3 bytes zero pad plus next header protocol value
pseudoHeader[offset++] = 0;
pseudoHeader[offset++] = 0;
pseudoHeader[offset++] = 0;
pseudoHeader[offset++] = ipv6PacketHeader.NextHeader;
// Copy the UDP packet to the end of this
Array.Copy(udpPacket, 0, pseudoHeader, offset, udpPacket.Length);
}
if (pseudoHeader != null)
{
Checksum = ComputeChecksum(pseudoHeader);
}
// Put checksum back into packet
byteValue = BitConverter.GetBytes(udpChecksum);
Array.Copy(byteValue, 0, udpPacket, 6, byteValue.Length);
return udpPacket;
}