INET Framework for OMNeT++/OMNEST
inet::Icmpv6HeaderSerializer Class Reference

Converts between Icmpv6Header and binary (network byte order) ICMPv6 header. More...

#include <Icmpv6HeaderSerializer.h>

Inheritance diagram for inet::Icmpv6HeaderSerializer:
inet::FieldsChunkSerializer inet::ChunkSerializer

Public Member Functions

 Icmpv6HeaderSerializer ()
 
- Public Member Functions inherited from inet::FieldsChunkSerializer
virtual void serialize (MemoryOutputStream &stream, const Ptr< const Chunk > &chunk, b offset, b length) const override
 Serializes a chunk into a stream by writing the bytes representing the chunk at the end of the stream. More...
 
virtual const Ptr< Chunkdeserialize (MemoryInputStream &stream, const std::type_info &typeInfo) const override
 Deserializes a chunk from a stream by reading the bytes at the current position of the stream. More...
 

Protected Member Functions

virtual void serialize (MemoryOutputStream &stream, const Ptr< const Chunk > &chunk) const override
 Serializes a chunk into a stream by writing all bytes representing the chunk at the end of the stream. More...
 
virtual const Ptr< Chunkdeserialize (MemoryInputStream &stream) const override
 Deserializes a chunk from a stream by reading the bytes at the current position of the stream. More...
 

Additional Inherited Members

- Static Public Attributes inherited from inet::ChunkSerializer
static b totalSerializedLength = b(0)
 
static b totalDeserializedLength = b(0)
 

Detailed Description

Converts between Icmpv6Header and binary (network byte order) ICMPv6 header.

Constructor & Destructor Documentation

◆ Icmpv6HeaderSerializer()

inet::Icmpv6HeaderSerializer::Icmpv6HeaderSerializer ( )
inline
25 : FieldsChunkSerializer() {}

Member Function Documentation

◆ deserialize()

const Ptr< Chunk > inet::Icmpv6HeaderSerializer::deserialize ( MemoryInputStream stream) const
overrideprotectedvirtual

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.

296 {
297  auto icmpv6Header = makeShared<Icmpv6Header>();
298  Icmpv6Type type = static_cast<Icmpv6Type>(stream.readByte()); // type
299  uint8_t subcode = stream.readByte(); // subcode
300  uint16_t chksum = stream.readUint16Be();
301 
302  switch (type) {
303  case ICMPv6_ECHO_REQUEST: {
304  auto echoRequest = makeShared<Icmpv6EchoRequestMsg>();
305  icmpv6Header = echoRequest;
306  echoRequest->setType(type);
307  echoRequest->setCode(subcode);
308  echoRequest->setIdentifier(stream.readUint16Be());
309  echoRequest->setSeqNumber(stream.readUint16Be());
310  break;
311  }
312 
313  case ICMPv6_ECHO_REPLY: {
314  auto echoReply = makeShared<Icmpv6EchoReplyMsg>();
315  icmpv6Header = echoReply;
316  echoReply->setType(type);
317  echoReply->setCode(subcode);
318  echoReply->setIdentifier(stream.readUint16Be());
319  echoReply->setSeqNumber(stream.readUint16Be());
320  break;
321  }
322 
324  auto destUnreach = makeShared<Icmpv6DestUnreachableMsg>();
325  icmpv6Header = destUnreach;
326  destUnreach->setType(type);
327  destUnreach->setCode(static_cast<Icmpv6DestUnav>(subcode));
328  stream.readUint32Be(); // unused
329  break;
330  }
331 
332  case ICMPv6_TIME_EXCEEDED: {
333  auto timeExceeded = makeShared<Icmpv6TimeExceededMsg>();
334  icmpv6Header = timeExceeded;
335  timeExceeded->setType(type);
336  timeExceeded->setCode(static_cast<Icmpv6TimeEx>(subcode));
337  stream.readUint32Be(); // unused
338  break;
339  }
340 
341  case ICMPv6_NEIGHBOUR_SOL: { // RFC 4861 Section 4.3
342  auto neighbourSol = makeShared<Ipv6NeighbourSolicitation>();
343  icmpv6Header = neighbourSol;
344  neighbourSol->setType(type);
345  neighbourSol->setCode(subcode);
346  neighbourSol->setReserved(stream.readUint32Be());
347  neighbourSol->setTargetAddress(stream.readIpv6Address());
348  deserializeIpv6NdOptions(*neighbourSol, neighbourSol->getOptionsForUpdate(), stream);
349  break;
350  }
351 
352  case ICMPv6_NEIGHBOUR_AD: {
353  auto neighbourAd = makeShared<Ipv6NeighbourAdvertisement>();
354  icmpv6Header = neighbourAd;
355  neighbourAd->setType(type);
356  neighbourAd->setCode(subcode);
357  uint32_t reserved = stream.readUint32Be(); // reserved
358  neighbourAd->setRouterFlag((reserved & 0x80000000u) != 0);
359  neighbourAd->setSolicitedFlag((reserved & 0x40000000u) != 0);
360  neighbourAd->setOverrideFlag((reserved & 0x20000000u) != 0);
361  neighbourAd->setReserved(reserved & 0x1fffffffu);
362  neighbourAd->setTargetAddress(stream.readIpv6Address());
363  deserializeIpv6NdOptions(*neighbourAd, neighbourAd->getOptionsForUpdate(), stream);
364  break;
365  }
366 
367  case ICMPv6_ROUTER_SOL: {
368  auto routerSol = makeShared<Ipv6RouterSolicitation>();
369  icmpv6Header = routerSol;
370  routerSol->setType(type);
371  routerSol->setCode(subcode);
372  routerSol->setReserved(stream.readUint32Be());
373  deserializeIpv6NdOptions(*routerSol, routerSol->getOptionsForUpdate(), stream);
374  break;
375  }
376 
377  case ICMPv6_ROUTER_AD: {
378  auto routerAd = makeShared<Ipv6RouterAdvertisement>();
379  icmpv6Header = routerAd;
380  routerAd->setType(type);
381  routerAd->setCode(subcode);
382  routerAd->setCurHopLimit(stream.readUint8());
383  uint32_t reserved = stream.readUint8(); // reserved
384  routerAd->setManagedAddrConfFlag((reserved & 0x80u) != 0);
385  routerAd->setOtherStatefulConfFlag((reserved & 0x40u) != 0);
386  routerAd->setHomeAgentFlag((reserved & 0x20u) != 0);
387  routerAd->setReserved(reserved & 0x1fu);
388  routerAd->setRouterLifetime(stream.readUint16Be());
389  routerAd->setReachableTime(stream.readUint32Be());
390  routerAd->setRetransTimer(stream.readUint32Be());
391  deserializeIpv6NdOptions(*routerAd, routerAd->getOptionsForUpdate(), stream);
392  break;
393  }
394 
395  default: {
396  EV_ERROR << "Can not parse ICMP packet: type " << (int)type << " not supported.";
397  icmpv6Header->markImproperlyRepresented();
398  break;
399  }
400  }
401  icmpv6Header->setCrcMode(CRC_COMPUTED);
402  icmpv6Header->setChksum(chksum);
403  return icmpv6Header;
404 }

◆ serialize()

void inet::Icmpv6HeaderSerializer::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.

196 {
197  const auto& pkt = staticPtrCast<const Icmpv6Header>(chunk);
198 
199  switch (pkt->getType()) {
200  case ICMPv6_ECHO_REQUEST: {
201  const Icmpv6EchoRequestMsg *frame = check_and_cast<const Icmpv6EchoRequestMsg *>(pkt.get());
202  stream.writeByte(pkt->getType());
203  stream.writeByte(frame->getCode());
204  stream.writeUint16Be(frame->getChksum());
205  stream.writeUint16Be(frame->getIdentifier());
206  stream.writeUint16Be(frame->getSeqNumber());
207  break;
208  }
209 
210  case ICMPv6_ECHO_REPLY: {
211  const Icmpv6EchoReplyMsg *frame = check_and_cast<const Icmpv6EchoReplyMsg *>(pkt.get());
212  stream.writeByte(pkt->getType());
213  stream.writeByte(frame->getCode());
214  stream.writeUint16Be(frame->getChksum());
215  stream.writeUint16Be(frame->getIdentifier());
216  stream.writeUint16Be(frame->getSeqNumber());
217  break;
218  }
219 
221  auto frame = check_and_cast<const Icmpv6DestUnreachableMsg *>(pkt.get());
222  stream.writeByte(pkt->getType());
223  stream.writeByte(frame->getCode());
224  stream.writeUint16Be(frame->getChksum());
225  stream.writeUint32Be(0); // unused
226  break;
227  }
228 
229  case ICMPv6_TIME_EXCEEDED: {
230  auto frame = check_and_cast<const Icmpv6TimeExceededMsg *>(pkt.get());
231  stream.writeByte(pkt->getType());
232  stream.writeByte(frame->getCode());
233  stream.writeUint16Be(frame->getChksum());
234  stream.writeUint32Be(0); // unused
235  break;
236  }
237 
238  case ICMPv6_NEIGHBOUR_SOL: {
239  auto frame = check_and_cast<const Ipv6NeighbourSolicitation *>(pkt.get());
240  stream.writeByte(pkt->getType());
241  stream.writeByte(frame->getCode());
242  stream.writeUint16Be(frame->getChksum());
243  stream.writeUint32Be(frame->getReserved());
244  stream.writeIpv6Address(frame->getTargetAddress());
245  serializeIpv6NdOptions(stream, frame->getOptions());
246  break;
247  }
248 
249  case ICMPv6_NEIGHBOUR_AD: {
250  auto frame = check_and_cast<const Ipv6NeighbourAdvertisement *>(pkt.get());
251  stream.writeByte(pkt->getType());
252  stream.writeByte(frame->getCode());
253  stream.writeUint16Be(frame->getChksum());
254  stream.writeUint32Be((frame->getRouterFlag() ? 0x80000000u : 0)
255  | (frame->getSolicitedFlag() ? 0x40000000u : 0)
256  | (frame->getOverrideFlag() ? 0x20000000u : 0)
257  | (frame->getReserved() & 0x1fffffffu));
258  stream.writeIpv6Address(frame->getTargetAddress());
259  serializeIpv6NdOptions(stream, frame->getOptions());
260  break;
261  }
262 
263  case ICMPv6_ROUTER_SOL: {
264  auto frame = check_and_cast<const Ipv6RouterSolicitation *>(pkt.get());
265  stream.writeByte(pkt->getType());
266  stream.writeByte(frame->getCode());
267  stream.writeUint16Be(frame->getChksum());
268  stream.writeUint32Be(frame->getReserved()); // unused
269  serializeIpv6NdOptions(stream, frame->getOptions());
270  break;
271  }
272 
273  case ICMPv6_ROUTER_AD: {
274  auto frame = check_and_cast<const Ipv6RouterAdvertisement *>(pkt.get());
275  stream.writeByte(pkt->getType());
276  stream.writeByte(frame->getCode());
277  stream.writeUint16Be(frame->getChksum());
278  stream.writeUint8(frame->getCurHopLimit());
279  stream.writeUint8((frame->getManagedAddrConfFlag() ? 0x80u : 0)
280  | (frame->getOtherStatefulConfFlag() ? 0x40u : 0)
281  | (frame->getHomeAgentFlag() ? 0x20u : 0)
282  | (frame->getReserved() & 0x1fu));
283  stream.writeUint16Be(frame->getRouterLifetime());
284  stream.writeUint32Be(frame->getReachableTime());
285  stream.writeUint32Be(frame->getRetransTimer());
286  serializeIpv6NdOptions(stream, frame->getOptions());
287  break;
288  }
289 
290  default:
291  throw cRuntimeError("Cannot serialize ICMPv6 packet: type %d not supported.", pkt->getType());
292  }
293 }

The documentation for this class was generated from the following files:
inet::Icmpv6DestUnav
Icmpv6DestUnav
Enum generated from inet/networklayer/icmpv6/Icmpv6Header.msg:50 by opp_msgtool.
Definition: Icmpv6Header_m.h:122
inet::CRC_COMPUTED
@ CRC_COMPUTED
Definition: CrcMode_m.h:59
inet::Icmpv6Type
Icmpv6Type
Enum generated from inet/networklayer/icmpv6/Icmpv6Header.msg:25 by opp_msgtool.
Definition: Icmpv6Header_m.h:83
inet::deserializeIpv6NdOptions
void deserializeIpv6NdOptions(Ipv6NdMessage &msg, Ipv6NdOptions &options, MemoryInputStream &stream)
Definition: Icmpv6HeaderSerializer.cc:84
inet::ICMPv6_ECHO_REPLY
@ ICMPv6_ECHO_REPLY
Definition: Icmpv6Header_m.h:90
inet::ICMPv6_ROUTER_SOL
@ ICMPv6_ROUTER_SOL
Definition: Icmpv6Header_m.h:94
inet::ICMPv6_TIME_EXCEEDED
@ ICMPv6_TIME_EXCEEDED
Definition: Icmpv6Header_m.h:87
type
removed type
Definition: IUdp-gates.txt:7
inet::Icmpv6TimeEx
Icmpv6TimeEx
Enum generated from inet/networklayer/icmpv6/Icmpv6Header.msg:63 by opp_msgtool.
Definition: Icmpv6Header_m.h:145
inet::serializeIpv6NdOptions
void serializeIpv6NdOptions(MemoryOutputStream &stream, const Ipv6NdOptions &options)
Definition: Icmpv6HeaderSerializer.cc:31
inet::ICMPv6_ROUTER_AD
@ ICMPv6_ROUTER_AD
Definition: Icmpv6Header_m.h:95
inet::ICMPv6_NEIGHBOUR_SOL
@ ICMPv6_NEIGHBOUR_SOL
Definition: Icmpv6Header_m.h:96
inet::ICMPv6_NEIGHBOUR_AD
@ ICMPv6_NEIGHBOUR_AD
Definition: Icmpv6Header_m.h:97
inet::ICMPv6_DESTINATION_UNREACHABLE
@ ICMPv6_DESTINATION_UNREACHABLE
Definition: Icmpv6Header_m.h:85
inet::ICMPv6_ECHO_REQUEST
@ ICMPv6_ECHO_REQUEST
Definition: Icmpv6Header_m.h:89