ICMPSerializer Class Reference

#include <ICMPSerializer.h>

List of all members.


Detailed Description

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


Public Member Functions

 ICMPSerializer ()
int serialize (ICMPMessage *pkt, unsigned char *buf, unsigned int bufsize)
void parse (unsigned char *buf, unsigned int bufsize, ICMPMessage *pkt)

Static Public Member Functions

static unsigned short checksum (unsigned char *addr, unsigned int count)


Constructor & Destructor Documentation

ICMPSerializer::ICMPSerializer (  )  [inline]

00032 {}


Member Function Documentation

unsigned short ICMPSerializer::checksum ( unsigned char *  addr,
unsigned int  count 
) [static]

Helper: calculate checksum

00154 {
00155     long sum = 0;
00156 
00157     while (count > 1)  {
00158         sum += *((unsigned short *&)addr)++;
00159         if (sum & 0x80000000)
00160             sum = (sum & 0xFFFF) + (sum >> 16);
00161         count -= 2;
00162     }
00163 
00164     if (count)
00165         sum += *(unsigned char *)addr;
00166 
00167     while (sum >> 16)
00168         sum = (sum & 0xffff) + (sum >> 16);
00169 
00170     return ~sum;
00171 }

void ICMPSerializer::parse ( unsigned char *  buf,
unsigned int  bufsize,
ICMPMessage pkt 
)

Puts a packet sniffed from the wire into an ICMPMessage.

00103 {
00104     struct icmp *icmp = (struct icmp*) buf;
00105 
00106     switch(icmp->icmp_type)
00107     {
00108         case ICMP_ECHO:
00109         {
00110             PingPayload *pp;
00111             char name[32];
00112 
00113             pkt->setType(ICMP_ECHO_REQUEST);
00114             pkt->setCode(0);
00115             pkt->setByteLength(4);
00116             sprintf(name,"ping%d", ntohs(icmp->icmp_seq));
00117             pp = new PingPayload(name);
00118             pp->setOriginatorId(ntohs(icmp->icmp_id));
00119             pp->setSeqNo(ntohs(icmp->icmp_seq));
00120             pp->setByteLength(bufsize - 4);
00121             pp->setDataArraySize(bufsize - ICMP_MINLEN);
00122             for(unsigned int i=0; i<bufsize - ICMP_MINLEN; i++)
00123                 pp->setData(i, icmp->icmp_data[i]);
00124             pkt->encapsulate(pp);
00125             pkt->setName(pp->name());
00126             break;
00127         }
00128         case ICMP_ECHOREPLY:
00129         {
00130             PingPayload *pp;
00131             char name[32];
00132 
00133             pkt->setType(ICMP_ECHO_REPLY);
00134             pkt->setCode(0);
00135             pkt->setByteLength(4);
00136             sprintf(name,"ping%d-reply", ntohs(icmp->icmp_seq));
00137             pp = new PingPayload(name);
00138             pp->setOriginatorId(ntohs(icmp->icmp_id));
00139             pp->setSeqNo(ntohs(icmp->icmp_seq));
00140             pp->setByteLength(bufsize - 4);
00141             pkt->encapsulate(pp);
00142             pkt->setName(pp->name());
00143             break;
00144         }
00145         default:
00146         {
00147             EV << "Can not create ICMP packet: type " << icmp->icmp_type << " not supported.";
00148             break;
00149         }
00150     }
00151 }

int ICMPSerializer::serialize ( ICMPMessage pkt,
unsigned char *  buf,
unsigned int  bufsize 
)

Serializes an ICMPMessage for transmission on the wire. Returns the length of data written into buffer.

00041 {
00042     struct icmp *icmp = (struct icmp *) (buf);
00043     int packetLength;
00044 
00045     packetLength = ICMP_MINLEN;
00046 
00047     switch(pkt->getType())
00048     {
00049         case ICMP_ECHO_REQUEST:
00050         {
00051             PingPayload *pp = check_and_cast<PingPayload* >(pkt->encapsulatedMsg());
00052             icmp->icmp_type = ICMP_ECHO;
00053             icmp->icmp_code = 0;
00054             icmp->icmp_id   = htons(pp->originatorId());
00055             icmp->icmp_seq  = htons(pp->seqNo());
00056             unsigned int datalen = (pp->byteLength() - 4);
00057             for(unsigned int i=0; i < datalen; i++)
00058                 icmp->icmp_data[i] = 'a';
00059             packetLength += datalen;
00060             break;
00061         }
00062         case ICMP_ECHO_REPLY:
00063         {
00064             PingPayload *pp = check_and_cast<PingPayload* >(pkt->encapsulatedMsg());
00065             icmp->icmp_type = ICMP_ECHOREPLY;
00066             icmp->icmp_code = 0;
00067             icmp->icmp_id   = htons(pp->originatorId());
00068             icmp->icmp_seq  = htons(pp->seqNo());
00069             unsigned int datalen = pp->dataArraySize();
00070             for(unsigned int i=0; i < datalen; i++)
00071                 icmp->icmp_data[i] = pp->data(i);
00072             packetLength += datalen;
00073             break;
00074         }
00075         case ICMP_DESTINATION_UNREACHABLE:
00076         {
00077             IPDatagram *ip = check_and_cast<IPDatagram* >(pkt->encapsulatedMsg());
00078             icmp->icmp_type = ICMP_UNREACH;
00079             icmp->icmp_code = pkt->getCode();
00080             packetLength += IPSerializer().serialize(ip, (unsigned char *)icmp->icmp_data, bufsize - ICMP_MINLEN);
00081             break;
00082         }
00083         case ICMP_TIME_EXCEEDED:
00084         {
00085             IPDatagram *ip = check_and_cast<IPDatagram* >(pkt->encapsulatedMsg());
00086             icmp->icmp_type = ICMP_TIMXCEED;
00087             icmp->icmp_code = ICMP_TIMXCEED_INTRANS;
00088             packetLength += IPSerializer().serialize(ip, (unsigned char *)icmp->icmp_data, bufsize - ICMP_MINLEN);
00089             break;
00090         }
00091         default:
00092         {
00093             packetLength = 0;
00094             EV << "Can not serialize ICMP packet: type " << pkt->getType() << " not supported.";
00095             break;
00096         }
00097     }
00098     icmp->icmp_cksum = checksum(buf, packetLength);
00099     return packetLength;
00100 }


The documentation for this class was generated from the following files:
Generated on Wed Apr 4 13:20:19 2007 for INET Framework for OMNeT++/OMNEST by  doxygen 1.4.7