Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <platdep/sockets.h>
00019 #include "headers/defs.h"
00020 namespace INETFw
00021 {
00022 #include "headers/bsdint.h"
00023 #include "headers/in.h"
00024 #include "headers/in_systm.h"
00025 #include "headers/ip.h"
00026 #include "headers/ip_icmp.h"
00027 };
00028 #include "IPSerializer.h"
00029 #include "ICMPSerializer.h"
00030 #include "PingPayload_m.h"
00031 #include "TCPIPchecksum.h"
00032
00033 #if !defined(_WIN32) && !defined(__WIN32__) && !defined(WIN32) && !defined(__CYGWIN__) && !defined(_WIN64)
00034 #include <netinet/in.h>
00035 #endif
00036
00037
00038 using namespace INETFw;
00039
00040
00041 int ICMPSerializer::serialize(const ICMPMessage *pkt, unsigned char *buf, unsigned int bufsize)
00042 {
00043 struct icmp *icmp = (struct icmp *) (buf);
00044 int packetLength;
00045
00046 packetLength = ICMP_MINLEN;
00047
00048 switch(pkt->getType())
00049 {
00050 case ICMP_ECHO_REQUEST:
00051 {
00052 PingPayload *pp = check_and_cast<PingPayload* >(pkt->getEncapsulatedMsg());
00053 icmp->icmp_type = ICMP_ECHO;
00054 icmp->icmp_code = 0;
00055 icmp->icmp_id = htons(pp->getOriginatorId());
00056 icmp->icmp_seq = htons(pp->getSeqNo());
00057 unsigned int datalen = (pp->getByteLength() - 4);
00058 for (unsigned int i=0; i < datalen; i++)
00059 if (i < pp->getDataArraySize()) {
00060 icmp->icmp_data[i] = pp->getData(i);
00061 } else {
00062 icmp->icmp_data[i] = 'a';
00063 }
00064 packetLength += datalen;
00065 break;
00066 }
00067 case ICMP_ECHO_REPLY:
00068 {
00069 PingPayload *pp = check_and_cast<PingPayload* >(pkt->getEncapsulatedMsg());
00070 icmp->icmp_type = ICMP_ECHOREPLY;
00071 icmp->icmp_code = 0;
00072 icmp->icmp_id = htons(pp->getOriginatorId());
00073 icmp->icmp_seq = htons(pp->getSeqNo());
00074 unsigned int datalen = pp->getDataArraySize();
00075 for(unsigned int i=0; i < datalen; i++)
00076 icmp->icmp_data[i] = pp->getData(i);
00077 packetLength += datalen;
00078 break;
00079 }
00080 case ICMP_DESTINATION_UNREACHABLE:
00081 {
00082 IPDatagram *ip = check_and_cast<IPDatagram* >(pkt->getEncapsulatedMsg());
00083 icmp->icmp_type = ICMP_UNREACH;
00084 icmp->icmp_code = pkt->getCode();
00085 packetLength += IPSerializer().serialize(ip, (unsigned char *)icmp->icmp_data, bufsize - ICMP_MINLEN);
00086 break;
00087 }
00088 case ICMP_TIME_EXCEEDED:
00089 {
00090 IPDatagram *ip = check_and_cast<IPDatagram* >(pkt->getEncapsulatedMsg());
00091 icmp->icmp_type = ICMP_TIMXCEED;
00092 icmp->icmp_code = ICMP_TIMXCEED_INTRANS;
00093 packetLength += IPSerializer().serialize(ip, (unsigned char *)icmp->icmp_data, bufsize - ICMP_MINLEN);
00094 break;
00095 }
00096 default:
00097 {
00098 packetLength = 0;
00099 EV << "Can not serialize ICMP packet: type " << pkt->getType() << " not supported.";
00100 break;
00101 }
00102 }
00103 icmp->icmp_cksum = TCPIPchecksum::checksum(buf, packetLength);
00104 return packetLength;
00105 }
00106
00107 void ICMPSerializer::parse(const unsigned char *buf, unsigned int bufsize, ICMPMessage *pkt)
00108 {
00109 struct icmp *icmp = (struct icmp*) buf;
00110
00111 switch(icmp->icmp_type)
00112 {
00113 case ICMP_ECHO:
00114 {
00115 PingPayload *pp;
00116 char name[32];
00117
00118 pkt->setType(ICMP_ECHO_REQUEST);
00119 pkt->setCode(0);
00120 pkt->setByteLength(4);
00121 sprintf(name,"ping%d", ntohs(icmp->icmp_seq));
00122 pp = new PingPayload(name);
00123 pp->setOriginatorId(ntohs(icmp->icmp_id));
00124 pp->setSeqNo(ntohs(icmp->icmp_seq));
00125 pp->setByteLength(bufsize - 4);
00126 pp->setDataArraySize(bufsize - ICMP_MINLEN);
00127 for(unsigned int i=0; i<bufsize - ICMP_MINLEN; i++)
00128 pp->setData(i, icmp->icmp_data[i]);
00129 pkt->encapsulate(pp);
00130 pkt->setName(pp->getName());
00131 break;
00132 }
00133 case ICMP_ECHOREPLY:
00134 {
00135 PingPayload *pp;
00136 char name[32];
00137
00138 pkt->setType(ICMP_ECHO_REPLY);
00139 pkt->setCode(0);
00140 pkt->setByteLength(4);
00141 sprintf(name,"ping%d-reply", ntohs(icmp->icmp_seq));
00142 pp = new PingPayload(name);
00143 pp->setOriginatorId(ntohs(icmp->icmp_id));
00144 pp->setSeqNo(ntohs(icmp->icmp_seq));
00145 pp->setByteLength(bufsize - 4);
00146 pp->setDataArraySize(bufsize - ICMP_MINLEN);
00147 for (unsigned int i=0; i<bufsize - ICMP_MINLEN; i++)
00148 pp->setData(i, icmp->icmp_data[i]);
00149 pkt->encapsulate(pp);
00150 pkt->setName(pp->getName());
00151 break;
00152 }
00153 default:
00154 {
00155 EV << "Can not create ICMP packet: type " << icmp->icmp_type << " not supported.";
00156 break;
00157 }
00158 }
00159 }