encodeSelf method

  1. @override
void encodeSelf(
  1. RawWriter writer
)
override

Encodes this object.

Implementation

@override
void encodeSelf(RawWriter writer) {
  // ----------------------------
  // Check that we have IP packet
  // ----------------------------
  if (parentPacket == null) {
    throw StateError(
      "UdpPacket field 'parentPacket' is null. UDP protocol requires IP packet for calculating checksum.",
    );
  }

  // ------
  // Fields
  // ------
  final start = writer.length;

  // 16-bit source port
  writer.writeUint16(sourcePort);

  // 16-bit destination port
  writer.writeUint16(destinationPort);

  // 16-bit payload length will be filled later
  writer.writeUint16(0);

  // 16-bit checksum
  // Must have 0 during calculation
  writer.writeUint16(0);

  // -------
  // Payload
  // -------
  final payloadStart = writer.length;
  payload.encodeSelf(writer);
  final payloadLength = writer.length - payloadStart;

  // Set payload length
  writer.bufferAsByteData.setUint16(start + 4, payloadLength);

  // ------------------
  // Calculate checksum
  // ------------------
  int checksum = 0;
  final ipPacket = this.parentPacket;
  final ipPacketPayloadLength = writer.length - start;
  if (ipPacket is Ip4Packet) {
    checksum += ipPacket.source.asUint32;
    checksum += ipPacket.destination.asUint32;
    checksum += ipPacket.typeOfService;
    checksum += ipPacketPayloadLength;
  } else if (ipPacket is Ip6Packet) {
    checksum += _checksumIp6Address(ipPacket.source);
    checksum += _checksumIp6Address(ipPacket.destination);
    checksum += ipPacketPayloadLength;
    checksum += ipPacket.payloadProtocolNumber;
  } else {
    throw StateError("IP packet is invalid");
  }
  checksum = Ip4Packet.calculateChecksum(
    writer.bufferAsByteData,
    start,
    ipPacketPayloadLength,
    checksum: checksum,
  );

  // Set checksum
  writer.bufferAsByteData.setUint16(start + 6, checksum);
}