#include <IPSerializer.h>
Public Member Functions | |
IPSerializer () | |
int | serialize (const IPDatagram *dgram, unsigned char *buf, unsigned int bufsize) |
void | parse (const unsigned char *buf, unsigned int bufsize, IPDatagram *dest) |
Converts between IPDatagram and binary (network byte order) IP header.
Definition at line 27 of file IPSerializer.h.
IPSerializer::IPSerializer | ( | ) | [inline] |
Definition at line 30 of file IPSerializer.h.
{}
void IPSerializer::parse | ( | const unsigned char * | buf, | |
unsigned int | bufsize, | |||
IPDatagram * | dest | |||
) |
Puts a packet sniffed from the wire into an IPDatagram. Does NOT verify the checksum.
Definition at line 107 of file IPSerializer.cc.
{ const struct ip *ip = (const struct ip *) buf; unsigned int totalLength, headerLength; dest->setVersion(ip->ip_v); dest->setHeaderLength(IP_HEADER_BYTES); dest->setSrcAddress(ntohl(ip->ip_src.s_addr)); dest->setDestAddress(ntohl(ip->ip_dst.s_addr)); dest->setTransportProtocol(ip->ip_p); dest->setTimeToLive(ip->ip_ttl); dest->setIdentification(ntohs(ip->ip_id)); dest->setMoreFragments((ip->ip_off) & !IP_OFFMASK & IP_MF); dest->setDontFragment((ip->ip_off) & !IP_OFFMASK & IP_DF); dest->setFragmentOffset((ntohs(ip->ip_off)) & IP_OFFMASK); dest->setDiffServCodePoint(ip->ip_tos); totalLength = ntohs(ip->ip_len); headerLength = ip->ip_hl << 2; if (headerLength > (unsigned int)IP_HEADER_BYTES) EV << "Handling an captured IP packet with options. Dropping the options.\n"; if (totalLength > bufsize) EV << "Can not handle IP packet of total length " << totalLength << "(captured only " << bufsize << " bytes).\n"; dest->setByteLength(IP_HEADER_BYTES); cPacket *encapPacket = NULL; switch (dest->getTransportProtocol()) { case IP_PROT_ICMP: encapPacket = new ICMPMessage("icmp-from-wire"); ICMPSerializer().parse(buf + headerLength, std::min(totalLength, bufsize) - headerLength, (ICMPMessage *)encapPacket); break; case IP_PROT_UDP: encapPacket = new UDPPacket("udp-from-wire"); UDPSerializer().parse(buf + headerLength, std::min(totalLength, bufsize) - headerLength, (UDPPacket *)encapPacket); break; case IP_PROT_SCTP: encapPacket = new SCTPMessage("sctp-from-wire"); SCTPSerializer().parse(buf + headerLength, (unsigned int)(std::min(totalLength, bufsize) - headerLength), (SCTPMessage *)encapPacket); break; case IP_PROT_TCP: encapPacket = new TCPSegment("tcp-from-wire"); TCPSerializer().parse(buf + headerLength, (unsigned int)(std::min(totalLength, bufsize) - headerLength), (TCPSegment *)encapPacket); break; default: opp_error("IPSerializer: cannot serialize protocol %d", dest->getTransportProtocol()); } ASSERT(encapPacket); dest->encapsulate(encapPacket); dest->setName(encapPacket->getName()); }
int IPSerializer::serialize | ( | const 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.
Definition at line 57 of file IPSerializer.cc.
{ int packetLength; struct ip *ip = (struct ip *) buf; ip->ip_hl = IP_HEADER_BYTES >> 2; ip->ip_v = dgram->getVersion(); ip->ip_tos = dgram->getDiffServCodePoint(); ip->ip_id = htons(dgram->getIdentification()); ip->ip_off = htons(dgram->getFragmentOffset()); ip->ip_ttl = dgram->getTimeToLive(); ip->ip_p = dgram->getTransportProtocol(); ip->ip_src.s_addr = htonl(dgram->getSrcAddress().getInt()); ip->ip_dst.s_addr = htonl(dgram->getDestAddress().getInt()); ip->ip_sum = 0; if (dgram->getHeaderLength() > IP_HEADER_BYTES) EV << "Serializing an IP packet with options. Dropping the options.\n"; packetLength = IP_HEADER_BYTES; cMessage *encapPacket = dgram->getEncapsulatedMsg(); switch (dgram->getTransportProtocol()) { case IP_PROT_ICMP: packetLength += ICMPSerializer().serialize(check_and_cast<ICMPMessage *>(encapPacket), buf+IP_HEADER_BYTES, bufsize-IP_HEADER_BYTES); break; case IP_PROT_UDP: packetLength += UDPSerializer().serialize(check_and_cast<UDPPacket *>(encapPacket), buf+IP_HEADER_BYTES, bufsize-IP_HEADER_BYTES); break; case IP_PROT_SCTP: //I.R. packetLength += SCTPSerializer().serialize(check_and_cast<SCTPMessage *>(encapPacket), buf+IP_HEADER_BYTES, bufsize-IP_HEADER_BYTES); break; case IP_PROT_TCP: //I.R. packetLength += TCPSerializer().serialize(check_and_cast<TCPSegment *>(encapPacket), buf+IP_HEADER_BYTES, bufsize-IP_HEADER_BYTES, dgram->getSrcAddress(), dgram->getDestAddress()); break; default: opp_error("IPSerializer: cannot serialize protocol %d", dgram->getTransportProtocol()); } ip->ip_len = htons(packetLength); return packetLength; }