#include <IPSerializer.h>
Public Member Functions | |
IPSerializer () | |
int | serialize (IPDatagram *dgram, unsigned char *buf, unsigned int bufsize) |
void | parse (unsigned char *buf, unsigned int bufsize, IPDatagram *dest) |
int IPSerializer::serialize | ( | IPDatagram * | dgram, | |
unsigned char * | buf, | |||
unsigned int | bufsize | |||
) |
Serializes an IPDatagram for transmission on the wire. The checksum is NOT filled in. (The kernel does that when sending the frame over a raw socket.) Returns the length of data written into buffer.
00052 { 00053 int packetLength; 00054 struct ip *ip = (struct ip *) buf; 00055 00056 ip->ip_hl = IP_HEADER_BYTES >> 2; 00057 ip->ip_v = dgram->getVersion(); 00058 ip->ip_tos = dgram->getDiffServCodePoint(); 00059 ip->ip_id = htons(dgram->getIdentification()); 00060 ip->ip_off = htons(dgram->getFragmentOffset()); 00061 ip->ip_ttl = dgram->getTimeToLive(); 00062 ip->ip_p = dgram->getTransportProtocol(); 00063 ip->ip_src.s_addr = htonl(dgram->getSrcAddress().getInt()); 00064 ip->ip_dst.s_addr = htonl(dgram->getDestAddress().getInt()); 00065 ip->ip_sum = 0; 00066 00067 if (dgram->getHeaderLength() > IP_HEADER_BYTES) 00068 EV << "Serializing an IP packet with options. Dropping the options.\n"; 00069 00070 packetLength = IP_HEADER_BYTES; 00071 00072 cMessage *encapPacket = dgram->getEncapsulatedMsg(); 00073 switch (dgram->getTransportProtocol()) 00074 { 00075 case IP_PROT_ICMP: 00076 packetLength += ICMPSerializer().serialize(check_and_cast<ICMPMessage *>(encapPacket), 00077 buf+IP_HEADER_BYTES, bufsize-IP_HEADER_BYTES); 00078 break; 00079 case IP_PROT_UDP: 00080 packetLength += UDPSerializer().serialize(check_and_cast<UDPPacket *>(encapPacket), 00081 buf+IP_HEADER_BYTES, bufsize-IP_HEADER_BYTES); 00082 break; 00083 case IP_PROT_SCTP: //I.R. 00084 packetLength += SCTPSerializer().serialize(check_and_cast<SCTPMessage *>(encapPacket), 00085 buf+IP_HEADER_BYTES, bufsize-IP_HEADER_BYTES); 00086 break; 00087 case IP_PROT_TCP: //I.R. 00088 { 00089 TCPSegment *tcpPacket = check_and_cast<TCPSegment *>(encapPacket); 00090 pseudoheader *pseudo = (pseudoheader*)malloc(sizeof(pseudoheader)); 00091 pseudo->srcaddr = htonl(dgram->getSrcAddress().getInt()); 00092 pseudo->dstaddr = htonl(dgram->getDestAddress().getInt()); 00093 pseudo->zero = 0; 00094 pseudo->ptcl = IPPROTO_TCP; 00095 pseudo->len = htons(tcpPacket->getBitLength()/8); 00096 packetLength += TCPSerializer().serialize(check_and_cast<TCPSegment *>(encapPacket), 00097 buf+IP_HEADER_BYTES, bufsize-IP_HEADER_BYTES, pseudo); 00098 free(pseudo); 00099 00100 break; 00101 } 00102 default: 00103 opp_error("IPSerializer: cannot serialize protocol %d", dgram->getTransportProtocol()); 00104 } 00105 00106 #ifdef linux 00107 ip->ip_len = htons(packetLength); 00108 #else 00109 ip->ip_len = packetLength; 00110 #endif 00111 return packetLength; 00112 }
void IPSerializer::parse | ( | unsigned char * | buf, | |
unsigned int | bufsize, | |||
IPDatagram * | dest | |||
) |
Puts a packet sniffed from the wire into an IPDatagram. Does NOT verify the checksum.
00115 { 00116 const struct ip *ip = (struct ip *) buf; 00117 unsigned int totalLength, headerLength; 00118 00119 dest->setVersion(ip->ip_v); 00120 dest->setHeaderLength(IP_HEADER_BYTES); 00121 dest->setSrcAddress(ntohl(ip->ip_src.s_addr)); 00122 dest->setDestAddress(ntohl(ip->ip_dst.s_addr)); 00123 dest->setTransportProtocol(ip->ip_p); 00124 dest->setTimeToLive(ip->ip_ttl); 00125 dest->setIdentification(ntohs(ip->ip_id)); 00126 dest->setMoreFragments((ip->ip_off) & !IP_OFFMASK & IP_MF); 00127 dest->setDontFragment((ip->ip_off) & !IP_OFFMASK & IP_DF); 00128 dest->setFragmentOffset((ntohs(ip->ip_off)) & IP_OFFMASK); 00129 dest->setDiffServCodePoint(ip->ip_tos); 00130 totalLength = ntohs(ip->ip_len); 00131 headerLength = ip->ip_hl << 2; 00132 00133 if (headerLength > (unsigned int)IP_HEADER_BYTES) 00134 EV << "Handling an captured IP packet with options. Dropping the options.\n"; 00135 if (totalLength > bufsize) 00136 EV << "Can not handle IP packet of total length " << totalLength << "(captured only " << bufsize << " bytes).\n"; 00137 dest->setByteLength(IP_HEADER_BYTES); 00138 00139 cPacket *encapPacket = NULL; 00140 switch (dest->getTransportProtocol()) 00141 { 00142 case IP_PROT_ICMP: 00143 encapPacket = new ICMPMessage("icmp-from-wire"); 00144 ICMPSerializer().parse(buf + headerLength, std::min(totalLength, bufsize) - headerLength, (ICMPMessage *)encapPacket); 00145 break; 00146 case IP_PROT_UDP: 00147 encapPacket = new UDPPacket("udp-from-wire"); 00148 UDPSerializer().parse(buf + headerLength, std::min(totalLength, bufsize) - headerLength, (UDPPacket *)encapPacket); 00149 break; 00150 case IP_PROT_SCTP: 00151 encapPacket = new SCTPMessage("sctp-from-wire"); 00152 SCTPSerializer().parse(buf + headerLength, (unsigned int)(std::min(totalLength, bufsize) - headerLength), (SCTPMessage *)encapPacket); 00153 break; 00154 default: 00155 opp_error("IPSerializer: cannot serialize protocol %d", dest->getTransportProtocol()); 00156 } 00157 00158 ASSERT(encapPacket); 00159 dest->encapsulate(encapPacket); 00160 dest->setName(encapPacket->getName()); 00161 }