#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) |
|
00032 {}
|
|
Helper: calculate checksum 00136 { 00137 long sum = 0; 00138 00139 while (count > 1) { 00140 sum += *((unsigned short *&)addr)++; 00141 if (sum & 0x80000000) 00142 sum = (sum & 0xFFFF) + (sum >> 16); 00143 count -= 2; 00144 } 00145 00146 if (count) 00147 sum += *(unsigned char *)addr; 00148 00149 while (sum >> 16) 00150 sum = (sum & 0xffff) + (sum >> 16); 00151 00152 return ~sum; 00153 }
|
|
Puts a packet sniffed from the wire into an ICMPMessage. 00085 { 00086 struct icmp *icmp = (struct icmp*) buf; 00087 00088 switch(icmp->icmp_type) 00089 { 00090 case ICMP_ECHO: 00091 { 00092 PingPayload *pp; 00093 char name[32]; 00094 00095 pkt->setType(ICMP_ECHO_REQUEST); 00096 pkt->setCode(0); 00097 pkt->setByteLength(4); 00098 sprintf(name,"ping%ld", ntohs(icmp->icmp_seq)); 00099 pp = new PingPayload(name); 00100 pp->setOriginatorId(ntohs(icmp->icmp_id)); 00101 pp->setSeqNo(ntohs(icmp->icmp_seq)); 00102 pp->setByteLength(bufsize - 4); 00103 pp->setDataArraySize(bufsize - ICMP_MINLEN); 00104 for(unsigned int i=0; i<bufsize - ICMP_MINLEN; i++) 00105 pp->setData(i, icmp->icmp_data[i]); 00106 pkt->encapsulate(pp); 00107 pkt->setName(pp->name()); 00108 break; 00109 } 00110 case ICMP_ECHOREPLY: 00111 { 00112 PingPayload *pp; 00113 char name[32]; 00114 00115 pkt->setType(ICMP_ECHO_REPLY); 00116 pkt->setCode(0); 00117 pkt->setByteLength(4); 00118 sprintf(name,"ping%ld-reply", ntohs(icmp->icmp_seq)); 00119 pp = new PingPayload(name); 00120 pp->setOriginatorId(ntohs(icmp->icmp_id)); 00121 pp->setSeqNo(ntohs(icmp->icmp_seq)); 00122 pp->setByteLength(bufsize - 4); 00123 pkt->encapsulate(pp); 00124 pkt->setName(pp->name()); 00125 break; 00126 } 00127 default: 00128 { 00129 EV << "Can not create ICMP packet: type " << icmp->icmp_type << " not supported."; 00130 break; 00131 } 00132 } 00133 }
|
|
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 switch(pkt->getType()) 00046 { 00047 case ICMP_ECHO_REQUEST: 00048 { 00049 PingPayload *pp = check_and_cast<PingPayload* >(pkt->encapsulatedMsg()); 00050 icmp->icmp_type = ICMP_ECHO; 00051 icmp->icmp_code = 0; 00052 icmp->icmp_id = htons(pp->originatorId()); 00053 icmp->icmp_seq = htons(pp->seqNo()); 00054 unsigned int datalen = (pp->byteLength() - 4); 00055 for(unsigned int i=0; i < datalen; i++) 00056 icmp->icmp_data[i] = 'a'; 00057 packetLength = ICMP_MINLEN + datalen; 00058 break; 00059 } 00060 case ICMP_ECHO_REPLY: 00061 { 00062 PingPayload *pp = check_and_cast<PingPayload* >(pkt->encapsulatedMsg()); 00063 icmp->icmp_type = ICMP_ECHOREPLY; 00064 icmp->icmp_code = 0; 00065 icmp->icmp_id = htons(pp->originatorId()); 00066 icmp->icmp_seq = htons(pp->seqNo()); 00067 unsigned int datalen = pp->dataArraySize(); 00068 for(unsigned int i=0; i < datalen; i++) 00069 icmp->icmp_data[i] = pp->data(i); 00070 packetLength = ICMP_MINLEN + datalen; 00071 break; 00072 } 00073 default: 00074 { 00075 packetLength = 0; 00076 EV << "Can not serialize ICMP packet: type " << icmp->icmp_type << " not supported."; 00077 break; 00078 } 00079 } 00080 icmp->icmp_cksum = checksum(buf, packetLength); 00081 return packetLength; 00082 }
|