示例#1
0
    /// <summary>
    /// This routine builds the ICMPv6 packet and payload into a byte array.
    /// It also computes the IPv6 pseudo header checksum that appears in the
    /// ICMPv6 packet.
    /// </summary>
    /// <param name="payLoad">A byte array representing the ICMPv6 payload</param>
    /// <returns>A byte array of the ICMPv6 packet and payload</returns>
    public override byte[] GetProtocolPacketBytes(byte[] payLoad)
    {
        byte[] icmpv6Packet, pseudoHeader, byteValue;
        int    offset = 0, payLoadLength;

        // Build the ICMPv6 packet first since its required in the pseudo header calculation
        icmpv6Packet = new byte[Icmpv6HeaderLength + payLoad.Length];

        offset = 0;
        icmpv6Packet[offset++] = icmpType;
        icmpv6Packet[offset++] = icmpCode;
        icmpv6Packet[offset++] = 0;
        icmpv6Packet[offset++] = 0;

        // Copy the payload into the build ICMPv6 packet
        Array.Copy(payLoad, 0, icmpv6Packet, offset, payLoad.Length);

        // Now build the pseudo header
        pseudoHeader = new byte[40 + icmpv6Packet.Length];

        offset = 0;

        byteValue = ipv6Header.SourceAddress.GetBytes();
        Array.Copy(byteValue, 0, pseudoHeader, offset, byteValue.Length);
        offset += byteValue.Length;

        byteValue = ipv6Header.DestinationAddress.GetBytes();
        Array.Copy(byteValue, 0, pseudoHeader, offset, byteValue.Length);
        offset += byteValue.Length;

        // Packet total length
        payLoadLength = NetworkingHelpers.HostToNetworkOrder(Icmpv6HeaderLength + payLoad.Length);

        byteValue = BitConverter.GetBytes(payLoadLength);
        Array.Copy(byteValue, 0, pseudoHeader, offset, byteValue.Length);
        offset += byteValue.Length;

        // 3 bytes of zero padding
        pseudoHeader[offset++] = (byte)0;
        pseudoHeader[offset++] = (byte)0;
        pseudoHeader[offset++] = (byte)0;
        pseudoHeader[offset++] = (byte)ipv6Header.NextHeader;

        // Next is the icmpv6 header and its payload
        Array.Copy(icmpv6Packet, 0, pseudoHeader, offset, icmpv6Packet.Length);
        offset += icmpv6Packet.Length;

        // Compute checksum on pseudo header
        Checksum = ComputeChecksum(pseudoHeader);

        // Go back and put the checksum value into the marshalled byte array
        byteValue = BitConverter.GetBytes(icmpChecksum);
        Array.Copy(byteValue, 0, icmpv6Packet, 2, byteValue.Length);
        return(icmpv6Packet);
    }
示例#2
0
    /// <summary>
    /// This method builds the byte array representation of the UDP header as it would appear
    /// on the wire. To do this it must build the IPv4 or IPv6 pseudo header in order to
    /// calculate the checksum on the packet. This requires knowledge of the IPv4 or IPv6 header
    /// so one of these must be set before a UDP packet can be set.
    ///
    /// The IPv4 pseudo header consists of:
    ///   4-byte source IP address
    ///   4-byte destination address
    ///   1-byte zero field
    ///   1-byte protocol field
    ///   2-byte UDP length
    ///   2-byte source port
    ///   2-byte destination port
    ///   2-byte UDP packet length
    ///   2-byte UDP checksum (zero)
    ///   UDP payload (padded to the next 16-bit boundary)

    /// The IPv6 pseudo header consists of:
    ///   16-byte source address
    ///   16-byte destination address
    ///   4-byte payload length
    ///   3-byte zero pad
    ///   1-byte protocol value
    ///   2-byte source port
    ///   2-byte destination port
    ///   2-byte UDP length
    ///   2-byte UDP checksum (zero)
    ///   UDP payload (padded to the next 16-bit boundary)
    /// </summary>
    /// <param name="payLoad">Payload that follows the UDP header</param>
    /// <returns></returns>
    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);
    }