Converts between TcpHeader and binary (network byte order) Tcp header.
More...
#include <TcpHeaderSerializer.h>
Converts between TcpHeader and binary (network byte order) Tcp header.
◆ TcpHeaderSerializer()
| inet::tcp::TcpHeaderSerializer::TcpHeaderSerializer |
( |
| ) |
|
|
inline |
31 : FieldsChunkSerializer() {}
◆ deserialize()
Deserializes a chunk from a stream by reading the bytes at the current position of the stream.
The current stream position is updated according to the length of the returned chunk.
Implements inet::FieldsChunkSerializer.
159 auto position = stream.getPosition();
162 auto tcpHeader = makeShared<TcpHeader>();
163 const struct tcphdr& tcp = *
static_cast<const struct tcphdr *
>((
void *)&buffer);
167 tcpHeader->setSrcPort(
ntohs(tcp.th_sport));
168 tcpHeader->setDestPort(
ntohs(tcp.th_dport));
169 tcpHeader->setSequenceNo(
ntohl(tcp.th_seq));
170 tcpHeader->setAckNo(
ntohl(tcp.th_ack));
171 B headerLength =
B(tcp.th_offs * 4);
174 unsigned char flags = tcp.th_flags;
184 tcpHeader->setWindow(
ntohs(tcp.th_win));
186 tcpHeader->setUrgentPointer(
ntohs(tcp.th_urp));
189 while (stream.getPosition() - position < headerLength) {
191 tcpHeader->appendHeaderOption(option);
194 tcpHeader->setHeaderLength(headerLength);
195 tcpHeader->setCrc(
ntohs(tcp.th_sum));
◆ deserializeOption()
203 unsigned char length = 0;
207 return new TcpOptionEnd();
210 return new TcpOptionNop();
213 length = stream.readByte();
215 auto *option =
new TcpOptionMaxSegmentSize();
216 option->setLength(length);
217 option->setMaxSegmentSize(stream.readUint16Be());
223 length = stream.readByte();
225 auto *option =
new TcpOptionWindowScale();
226 option->setLength(length);
227 option->setWindowScale(stream.readByte());
233 length = stream.readByte();
235 auto *option =
new TcpOptionSackPermitted();
236 option->setLength(length);
242 length = stream.readByte();
243 if (length > 2 && (length % 8) == 2) {
244 auto *option =
new TcpOptionSack();
245 option->setLength(length);
246 option->setSackItemArraySize(length / 8);
247 unsigned int count = 0;
248 for (
unsigned int i = 2; i < length; i += 8) {
250 si.setStart(stream.readUint32Be());
251 si.setEnd(stream.readUint32Be());
252 option->setSackItem(
count++, si);
259 length = stream.readByte();
261 auto *option =
new TcpOptionTimestamp();
262 option->setLength(length);
263 option->setSenderTimestamp(stream.readUint32Be());
264 option->setEchoedTimestamp(stream.readUint32Be());
270 length = stream.readByte();
274 auto *option =
new TcpOptionUnknown();
275 option->setKind(
kind);
276 option->setLength(length);
278 option->setBytesArraySize(length - 2);
279 for (
unsigned int i = 2; i < length; i++)
280 option->setBytes(i - 2, stream.readByte());
Referenced by deserialize().
◆ serialize()
| void inet::tcp::TcpHeaderSerializer::serialize |
( |
MemoryOutputStream & |
stream, |
|
|
const Ptr< const Chunk > & |
chunk |
|
) |
| const |
|
overrideprotectedvirtual |
Serializes a chunk into a stream by writing all bytes representing the chunk at the end of the stream.
Implements inet::FieldsChunkSerializer.
26 const auto& tcpHeader = staticPtrCast<const TcpHeader>(chunk);
31 throw cRuntimeError(
"Cannot serialize Tcp header without a properly computed CRC");
32 tcp.th_sum =
htons(tcpHeader->getCrc());
33 tcp.th_sport =
htons(tcpHeader->getSrcPort());
34 tcp.th_dport =
htons(tcpHeader->getDestPort());
35 tcp.th_seq =
htonl(tcpHeader->getSequenceNo());
36 tcp.th_ack =
htonl(tcpHeader->getAckNo());
41 if (tcpHeader->getFinBit())
43 if (tcpHeader->getSynBit())
45 if (tcpHeader->getRstBit())
47 if (tcpHeader->getPshBit())
49 if (tcpHeader->getAckBit())
51 if (tcpHeader->getUrgBit())
53 if (tcpHeader->getEceBit())
55 if (tcpHeader->getCwrBit())
59 tcp.th_win =
htons(tcpHeader->getWindow());
60 tcp.th_urp =
htons(tcpHeader->getUrgentPointer());
61 if (
B(tcpHeader->getHeaderLength()).get() % 4 != 0)
62 throw cRuntimeError(
"invalid Tcp header length=%s: must be dividable by 4 bytes", tcpHeader->getHeaderLength().str().c_str());
63 tcp.th_offs =
B(tcpHeader->getHeaderLength()).get() / 4;
67 unsigned short numOptions = tcpHeader->getHeaderOptionArraySize();
68 unsigned int optionsLength = 0;
70 for (
unsigned short i = 0; i < numOptions; i++) {
71 const TcpOption *option = tcpHeader->getHeaderOption(i);
73 optionsLength += option->getLength();
75 if (optionsLength % 4 != 0)
76 stream.writeByteRepeatedly(0, 4 - optionsLength % 4);
◆ serializeOption()
84 unsigned short length = option->getLength();
86 stream.writeByte(
kind);
88 stream.writeByte(length);
90 auto *opt =
dynamic_cast<const TcpOptionUnknown *
>(option);
92 unsigned int datalen = opt->getBytesArraySize();
93 ASSERT(length == 2 + datalen);
94 for (
unsigned int i = 0; i < datalen; i++)
95 stream.writeByte(opt->getBytes(i));
101 check_and_cast<const TcpOptionEnd *>(option);
106 check_and_cast<const TcpOptionNop *>(option);
111 auto *opt = check_and_cast<const TcpOptionMaxSegmentSize *>(option);
113 stream.writeUint16Be(opt->getMaxSegmentSize());
118 auto *opt = check_and_cast<const TcpOptionWindowScale *>(option);
120 stream.writeByte(opt->getWindowScale());
125 auto *opt = check_and_cast<const TcpOptionSackPermitted *>(option);
132 auto *opt = check_and_cast<const TcpOptionSack *>(option);
133 ASSERT(length == 2 + opt->getSackItemArraySize() * 8);
134 for (
unsigned int i = 0; i < opt->getSackItemArraySize(); i++) {
135 SackItem si = opt->getSackItem(i);
136 stream.writeUint32Be(si.getStart());
137 stream.writeUint32Be(si.getEnd());
143 auto *opt = check_and_cast<const TcpOptionTimestamp *>(option);
144 ASSERT(length == 10);
145 stream.writeUint32Be(opt->getSenderTimestamp());
146 stream.writeUint32Be(opt->getEchoedTimestamp());
151 throw cRuntimeError(
"Unknown TCPOption kind=%d (not in a TCPOptionUnknown option)",
kind);
Referenced by serialize().
The documentation for this class was generated from the following files: