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

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

#include <ICMPSerializer.h>

Inheritance diagram for inet::serializer::ICMPSerializer:
inet::serializer::SerializerBase

Public Member Functions

 ICMPSerializer (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::ICMPSerializer::ICMPSerializer ( const char *  name = nullptr)
inline
38 : SerializerBase(name) {}
SerializerBase(const char *name=nullptr)
Definition: SerializerBase.h:84

Member Function Documentation

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

Puts a packet sniffed from the wire into an EtherFrame.

Implements inet::serializer::SerializerBase.

107 {
108  ASSERT(b.getPos() == 0);
109 
110  ICMPMessage *pkt = new ICMPMessage("parsed-icmp");
111  uint8_t type = b.readByte(); // type
112  uint8_t subcode = b.readByte(); // subcode
113  b.readUint16(); // checksum
114 
115  switch (type) {
116  case ICMP_ECHO_REQUEST: {
117  PingPayload *pp = new PingPayload();
118  pkt->setType(ICMP_ECHO_REQUEST);
119  pkt->setCode(subcode);
120  pkt->setByteLength(4);
121  pp->setOriginatorId(b.readUint16());
122  uint16_t seqno = b.readUint16();
123  pp->setSeqNo(seqno);
124 
125  char name[32];
126  sprintf(name, "parsed-ping%d", seqno);
127  pp->setName(name);
128  pkt->setName(name);
129 
130  pp->setByteLength(4 + b.getRemainingSize());
131  pp->setDataArraySize(b.getRemainingSize());
132  for (unsigned int i = 0; b.getRemainingSize() > 0; i++)
133  pp->setData(i, b.readByte());
134  pkt->encapsulate(pp);
135  break;
136  }
137 
138  case ICMP_ECHO_REPLY: {
139  PingPayload *pp = new PingPayload();
140  pkt->setType(ICMP_ECHO_REPLY);
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%d-reply", 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 
161  pkt->setType(ICMP_DESTINATION_UNREACHABLE);
162  pkt->setCode(subcode);
163  b.readUint16(); // unused
164  b.readUint16(); // next hop MTU
165  pkt->setByteLength(8);
166  Buffer s(b, b.getRemainingSize()); // save buffer error bit (encapsulated packet usually larger than ICMPPacket payload size)
168  b.accessNBytes(s.getPos());
169  pkt->encapsulate(pp);
170  pkt->setByteLength(b.getPos());
171  break;
172  }
173 
174  case ICMP_TIME_EXCEEDED: {
175  pkt->setType(ICMP_TIME_EXCEEDED);
176  pkt->setCode(subcode);
177  b.readUint32(); // unused
178  pkt->setByteLength(8);
179  Buffer s(b, b.getRemainingSize()); // save buffer error bit (encapsulated packet usually larger than ICMPPacket payload size)
181  b.accessNBytes(s.getPos());
182  pkt->encapsulate(pp);
183  pkt->setByteLength(b.getPos());
184  break;
185  }
186 
187  default: {
188  EV_ERROR << "Can not parse ICMP packet: type " << type << " not supported.";
189  delete pkt;
190  return nullptr;
191  }
192  }
193  uint16_t cchecksum = TCPIPchecksum::checksum(b._getBuf(), b.getPos());
194  if (cchecksum)
195  pkt->setBitError(true);
196  return pkt;
197 }
Definition: ICMPMessage_m.h:69
Definition: ICMPMessage_m.h:66
Definition: SerializerBase.h:39
static uint16_t checksum(const void *addr, unsigned int count)
Definition: TCPIPchecksum.h:44
const value< double, compose< units::m, pow< units::s,-1 > > > c(299792458)
Definition: ICMPMessage_m.h:74
Definition: ICMPMessage_m.h:72
value< double, units::s > s
Definition: Units.h:1049
static cPacket * lookupAndDeserialize(const Buffer &b, Context &context, ProtocolGroup group, int id, unsigned int maxLength=(unsigned int)(-1))
Definition: SerializerBase.cc:99
Definition: Ieee802Ctrl_m.h:115
value< double, units::m > b
Definition: Units.h:1054
void inet::serializer::ICMPSerializer::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 ICMPMessage *pkt = check_and_cast<const ICMPMessage *>(_pkt);
43 
44  switch (pkt->getType()) {
45  case ICMP_ECHO_REQUEST: {
46  PingPayload *pp = check_and_cast<PingPayload *>(pkt->getEncapsulatedPacket());
47  b.writeByte(ICMP_ECHO_REQUEST);
48  b.writeByte(pkt->getCode());
49  b.writeUint16(0); // checksum
50  b.writeUint16(pp->getOriginatorId());
51  b.writeUint16(pp->getSeqNo());
52  unsigned int datalen = pp->getDataArraySize();
53  for (unsigned int i = 0; i < datalen; i++)
54  b.writeByte(pp->getData(i));
55  datalen = (pp->getByteLength() - 4) - datalen;
56  b.fillNBytes(datalen, 'a');
57  break;
58  }
59 
60  case ICMP_ECHO_REPLY: {
61  PingPayload *pp = check_and_cast<PingPayload *>(pkt->getEncapsulatedPacket());
62  b.writeByte(ICMP_ECHO_REPLY);
63  b.writeByte(pkt->getCode());
64  b.writeUint16(0); // checksum
65  b.writeUint16(pp->getOriginatorId());
66  b.writeUint16(pp->getSeqNo());
67  unsigned int datalen = pp->getDataArraySize();
68  for (unsigned int i = 0; i < datalen; i++)
69  b.writeByte(pp->getData(i));
70  datalen = (pp->getByteLength() - 4) - datalen;
71  b.fillNBytes(datalen, 'a');
72  break;
73  }
74 
77  b.writeByte(pkt->getCode());
78  b.writeUint16(0); // checksum
79  b.writeUint16(0); // unused
80  b.writeUint16(0); // next hop MTU
81  Buffer s(b, b.getRemainingSize()); // save buffer error bit (encapsulated packet usually larger than ICMPPacket payload size)
82  SerializerBase::lookupAndSerialize(pkt->getEncapsulatedPacket(), s, c, ETHERTYPE, ETHERTYPE_IPv4);
83  b.accessNBytes(std::min((unsigned int)(pkt->getByteLength() - ICMP_MINLEN), s.getPos()));
84  break;
85  }
86 
87  case ICMP_TIME_EXCEEDED: {
88  b.writeByte(ICMP_TIME_EXCEEDED);
89  b.writeByte(ICMP_TIMXCEED_INTRANS);
90  b.writeUint16(0); // checksum
91  b.writeUint32(0); // unused
92  Buffer s(b, b.getRemainingSize()); // save buffer error bit (encapsulated packet usually larger than ICMPPacket payload size)
93  SerializerBase::lookupAndSerialize(pkt->getEncapsulatedPacket(), s, c, ETHERTYPE, ETHERTYPE_IPv4);
94  b.accessNBytes(std::min((unsigned int)(pkt->getByteLength() - ICMP_MINLEN), s.getPos()));
95  break;
96  }
97 
98  default: {
99  //TODO if (c.throwOnSerializerNotFound)
100  throw cRuntimeError("Can not serialize ICMP packet: type %d not supported.", pkt->getType());
101  }
102  }
103  b.writeUint16To(startpos + 2, TCPIPchecksum::checksum(b._getBuf() + startpos, b.getPos() - startpos));
104 }
Definition: ICMPMessage_m.h:69
Definition: ICMPMessage_m.h:66
double min(const double a, const double b)
Returns the minimum of a and b.
Definition: SCTPAssociation.h:270
Definition: SerializerBase.h:39
static uint16_t checksum(const void *addr, unsigned int count)
Definition: TCPIPchecksum.h:44
const value< double, compose< units::m, pow< units::s,-1 > > > c(299792458)
Definition: ICMPMessage_m.h:115
Definition: ICMPMessage_m.h:74
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: ICMPMessage_m.h:72
value< double, units::s > s
Definition: Units.h:1049
Definition: Ieee802Ctrl_m.h:115
#define ICMP_MINLEN
Definition: ip_icmp.h:135
value< double, units::m > b
Definition: Units.h:1054

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