encodeSelf method

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

Writes this object to the provided RawWriter.

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
    ..writeUint16(destinationPort)
    // 16-bit payload length will be filled later
    ..writeUint16(0)
    // 16-bit checksum
    // Must have 0 during calculation
    ..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 = 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);
}