INET Framework for OMNeT++/OMNEST
inet::serializer::ICMPv6Serializer Class Reference

Converts between ICMPMessage and binary (network byte order) ICMP header. More...

#include <ICMPv6Serializer.h>

Inheritance diagram for inet::serializer::ICMPv6Serializer:
inet::serializer::SerializerBase

Public Member Functions

 ICMPv6Serializer (const char *name=nullptr)
 
- Public Member Functions inherited from inet::serializer::SerializerBase
 SerializerBase (const char *name=nullptr)
 
void serializePacket (const cPacket *pkt, Buffer &b, Context &context)
 
cPacket * deserializePacket (const Buffer &b, Context &context)
 

Protected Member Functions

virtual void serialize (const cPacket *pkt, Buffer &b, Context &context) override
 Serializes a cPacket for transmission on the wire. More...
 
virtual cPacket * deserialize (const Buffer &b, Context &context) override
 Puts a packet sniffed from the wire into an EtherFrame. More...
 

Additional Inherited Members

- Static Public Member Functions inherited from inet::serializer::SerializerBase
static SerializerBaselookupSerializer (const cPacket *pkt, Context &context, ProtocolGroup group, int id)
 
static void lookupAndSerialize (const cPacket *pkt, Buffer &b, Context &context, ProtocolGroup group, int id, unsigned int maxLength=(unsigned int)(-1))
 
static SerializerBaselookupDeserializer (Context &context, ProtocolGroup group, int id)
 
static cPacket * lookupAndDeserialize (const Buffer &b, Context &context, ProtocolGroup group, int id, unsigned int maxLength=(unsigned int)(-1))
 

Detailed Description

Converts between ICMPMessage and binary (network byte order) ICMP header.

Constructor & Destructor Documentation

inet::serializer::ICMPv6Serializer::ICMPv6Serializer ( const char *  name = nullptr)
inline
38 : SerializerBase(name) {}
SerializerBase(const char *name=nullptr)
Definition: SerializerBase.h:84

Member Function Documentation

cPacket * inet::serializer::ICMPv6Serializer::deserialize ( const Buffer b,
Context context 
)
overrideprotectedvirtual

Puts a packet sniffed from the wire into an EtherFrame.

Implements inet::serializer::SerializerBase.

128 {
129  ASSERT(b.getPos() == 0);
130 
131  ICMPv6Message *_pkt = nullptr;
132  uint8_t type = b.readByte(); // type
133  uint8_t subcode = b.readByte(); // subcode
134  b.readUint16(); // crc
135 
136  switch (type) {
137  case ICMPv6_ECHO_REQUEST: {
138  ICMPv6EchoRequestMsg *pkt = new ICMPv6EchoRequestMsg(); _pkt = pkt;
139  PingPayload *pp = new PingPayload();
140  pkt->setType(type);
141  pkt->setCode(subcode);
142  pkt->setByteLength(4);
143  pp->setOriginatorId(b.readUint16());
144  uint16_t seqno = b.readUint16();
145  pp->setSeqNo(seqno);
146 
147  char name[32];
148  sprintf(name, "parsed-ping-%u", seqno);
149  pp->setName(name);
150  pkt->setName(name);
151 
152  pp->setByteLength(4 + b.getRemainingSize());
153  pp->setDataArraySize(b.getRemainingSize());
154  for (unsigned int i = 0; b.getRemainingSize() > 0; i++)
155  pp->setData(i, b.readByte());
156  pkt->encapsulate(pp);
157  break;
158  }
159 
160  case ICMPv6_ECHO_REPLY: {
161  ICMPv6EchoReplyMsg *pkt = new ICMPv6EchoReplyMsg(); _pkt = pkt;
162  PingPayload *pp = new PingPayload();
163  pkt->setType(type);
164  pkt->setCode(subcode);
165  pkt->setByteLength(4);
166  pp->setOriginatorId(b.readUint16());
167  uint16_t seqno = b.readUint16();
168 
169  char name[32];
170  sprintf(name, "parsed-ping-%u-reply", ntohs(seqno));
171  pp->setName(name);
172  pkt->setName(name);
173 
174  pp->setByteLength(4 + b.getRemainingSize());
175  pp->setDataArraySize(b.getRemainingSize());
176  for (unsigned int i = 0; b.getRemainingSize() > 0; i++)
177  pp->setData(i, b.readByte());
178  pkt->encapsulate(pp);
179  break;
180  }
181 
182  case ICMPv6_NEIGHBOUR_SOL: { // RFC 4861 Section 4.3
183  IPv6NeighbourSolicitation *pkt = new IPv6NeighbourSolicitation(); _pkt = pkt;
184  pkt->setType(type);
185  pkt->setCode(subcode);
186  pkt->setByteLength(b._getBufSize());
187 
188  b.readUint32(); // reserved
189  pkt->setTargetAddress(b.readIPv6Address());
190  while (b.getRemainingSize()) { // has options
191  unsigned int pos = b.getPos();
192  unsigned char type = b.readByte();
193  unsigned char length = b.readByte();
194  if (type == 0 || length == 0) {
195  pkt->setBitError(true);
196  break;
197  }
198  if (type == 1) {
199  pkt->setSourceLinkLayerAddress(b.readMACAddress()); // sourceLinkLayerAddress
200  }
201  b.seek(pos + 8 * length);
202  }
203  break;
204  }
205 
206  default: {
207  EV_ERROR << "Can not parse ICMP packet: type " << type << " not supported.";
208  return nullptr;
209  }
210  }
211  uint16_t ccrc = TCPIPchecksum::checksum(b._getBuf(), b.getPos());
212  if (ccrc)
213  _pkt->setBitError(true);
214  return _pkt;
215 }
u16_t ntohs(u16_t n)
Definition: ICMPv6Message_m.h:82
static uint16_t checksum(const void *addr, unsigned int count)
Definition: TCPIPchecksum.h:44
Definition: ICMPv6Message_m.h:76
Definition: ICMPv6Message_m.h:75
value< double, units::m > b
Definition: Units.h:1054
void inet::serializer::ICMPv6Serializer::serialize ( const cPacket *  pkt,
Buffer b,
Context context 
)
overrideprotectedvirtual

Serializes a cPacket for transmission on the wire.

Returns the length of data written into buffer.

Implements inet::serializer::SerializerBase.

40 {
41  unsigned int startpos = b.getPos();
42  const ICMPv6Message *pkt = check_and_cast<const ICMPv6Message *>(_pkt);
43 
44  switch (pkt->getType()) {
45  case ICMPv6_ECHO_REQUEST: {
46  const ICMPv6EchoRequestMsg *frame = check_and_cast<const ICMPv6EchoRequestMsg *>(pkt);
47  PingPayload *pp = check_and_cast<PingPayload *>(pkt->getEncapsulatedPacket());
48  b.writeByte(pkt->getType());
49  b.writeByte(frame->getCode());
50  b.writeUint16(0); // checksum
51  b.writeUint16(pp->getOriginatorId());
52  b.writeUint16(pp->getSeqNo());
53  unsigned int datalen = pp->getDataArraySize();
54  for (unsigned int i = 0; i < datalen; i++)
55  b.writeByte(pp->getData(i));
56  datalen = (pp->getByteLength() - 4) - datalen;
57  b.fillNBytes(datalen, 'a');
58  break;
59  }
60 
61  case ICMPv6_ECHO_REPLY: {
62  const ICMPv6EchoReplyMsg *frame = check_and_cast<const ICMPv6EchoReplyMsg *>(pkt);
63  PingPayload *pp = check_and_cast<PingPayload *>(pkt->getEncapsulatedPacket());
64  b.writeByte(pkt->getType());
65  b.writeByte(frame->getCode());
66  b.writeUint16(0); // checksum
67  b.writeUint16(pp->getOriginatorId());
68  b.writeUint16(pp->getSeqNo());
69  unsigned int datalen = pp->getDataArraySize();
70  for (unsigned int i = 0; i < datalen; i++)
71  b.writeByte(pp->getData(i));
72  datalen = (pp->getByteLength() - 4) - datalen;
73  b.fillNBytes(datalen, 'a');
74  break;
75  }
76 
78  const ICMPv6DestUnreachableMsg *frame = check_and_cast<const ICMPv6DestUnreachableMsg *>(pkt);
79  b.writeByte(pkt->getType());
80  b.writeByte(frame->getCode());
81  b.writeUint16(0); // crc
82  b.writeUint32(0); // unused
83  SerializerBase::lookupAndSerialize(pkt->getEncapsulatedPacket(), b, c, ETHERTYPE, ETHERTYPE_IPv6);
84  break;
85  }
86 
87  case ICMPv6_TIME_EXCEEDED: {
88  const ICMPv6TimeExceededMsg *frame = check_and_cast<const ICMPv6TimeExceededMsg *>(pkt);
89  b.writeByte(pkt->getType());
90  b.writeByte(frame->getCode());
91  b.writeUint16(0); // crc
92  b.writeUint32(0); // unused
93  SerializerBase::lookupAndSerialize(pkt->getEncapsulatedPacket(), b, c, ETHERTYPE, ETHERTYPE_IPv6);
94  break;
95  }
96 
97  case ICMPv6_NEIGHBOUR_SOL: {
98  const IPv6NeighbourSolicitation *frame = check_and_cast<const IPv6NeighbourSolicitation *>(pkt);
99  b.writeByte(pkt->getType());
100  b.writeByte(frame->getCode());
101  b.writeUint16(0); // crc
102  b.writeUint32(0); // unused
103  b.writeIPv6Address(frame->getTargetAddress());
104  if (frame->getByteLength() > 8 + 16) { // has optional sourceLinkLayerAddress (TLB options)
106  b.writeByte(1); // length = 1 * 8byte
107  b.writeMACAddress(frame->getSourceLinkLayerAddress());
108  ASSERT(1 + 1 + MAC_ADDRESS_SIZE == 8);
109  }
110  break;
111  }
112 
113  default: {
114  if (c.throwOnSerializerNotFound)
115  throw cRuntimeError("Can not serialize ICMPv6 packet: type %d not supported.", pkt->getType());
116  b.writeByte(pkt->getType());
117  b.writeByte(0xFF); // unknown
118  b.writeUint16(0); // crc
119  ASSERT(pkt->getByteLength() >= 4);
120  b.fillNBytes(pkt->getByteLength() - 4, 'a');
121  break;
122  }
123  }
124  b.writeUint16To(startpos + 2, TCPIPchecksum::checksum(b._getBuf() + startpos, b.getPos() - startpos));
125 }
Definition: SerializerBase.h:39
Definition: ICMPv6Message_m.h:82
static uint16_t checksum(const void *addr, unsigned int count)
Definition: TCPIPchecksum.h:44
Definition: ICMPv6Message_m.h:71
const value< double, compose< units::m, pow< units::s,-1 > > > c(299792458)
static void lookupAndSerialize(const cPacket *pkt, Buffer &b, Context &context, ProtocolGroup group, int id, unsigned int maxLength=(unsigned int)(-1))
Definition: SerializerBase.cc:88
Definition: ICMPv6Message_m.h:76
Definition: ICMPv6Message_m.h:75
#define MAC_ADDRESS_SIZE
Definition: MACAddress.h:27
Definition: ICMPv6Message_m.h:73
Definition: Ieee802Ctrl_m.h:120
value< double, units::m > b
Definition: Units.h:1054
Definition: IPv6NDMessage_m.h:76

The documentation for this class was generated from the following files: