#include <ICMPSerializer.h>
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) |
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 }