|
INET Framework for OMNeT++/OMNEST
|
#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.
| IPSerializer::IPSerializer | ( | ) | [inline] |
{}
| 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.
Referenced by ExtInterface::handleMessage().
{
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.
Referenced by TCPDump::handleMessage(), and ExtInterface::handleMessage().
{
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->getEncapsulatedPacket();
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;
}