encodeSelf method

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

Encodes this object.

Implementation

@override
void encodeSelf(RawWriter writer) {
  final start = writer.length;
  if (parentPacket == null) {
    throw StateError(
      "TcpPacket field 'parentPacket' is null. TCP protocol requires IP packet for calculating checksum.",
    );
  }

  // 4-byte span at index 0
  writer.writeUint32(_v0);

  // 4-byte span at index 4
  writer.writeUint32(sequenceNumber);

  // 4-byte span at index 8
  writer.writeUint32(acknowledgementNumber);

  // 4-byte span at index 12 will be set later
  writer.writeUint32(0);

  // 4-byte span at index 16
  // Checksum must have 0 during calculation.
  writer.writeUint32(0x0000FFFF & _v4);

  // Options
  final options = optionsByteData;
  writer.writeByteData(options);
  var headerLength = writer.length - start;

  // Adding padding
  while (headerLength % 4 != 0) {
    writer.writeUint8(0);
    headerLength++;
  }

  // We have header length
  // Set 4-byte span at index 12
  final v3 = transformUint32Bits(_v3, 28, 0xF, headerLength ~/ 4);
  writer.bufferAsByteData.setUint32(start + 12, v3);

  // Payload
  payload.encodeSelf(writer);

  // ------------
  // Set checksum
  // ------------
  var 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,
  );
  writer.bufferAsByteData.setUint16(
      start + 16,
      Ip4Packet.calculateChecksum(
          writer.bufferAsByteData, start, writer.length - start));
}