IPSerializer Class Reference

#include <IPSerializer.h>

List of all members.


Detailed Description

Converts between IPDatagram and binary (network byte order) IP header.

Public Member Functions

 IPSerializer ()
int serialize (IPDatagram *dgram, unsigned char *buf, unsigned int bufsize)
void parse (unsigned char *buf, unsigned int bufsize, IPDatagram *dest)

Constructor & Destructor Documentation

IPSerializer::IPSerializer (  )  [inline]

00030 {}


Member Function Documentation

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 }


The documentation for this class was generated from the following files:

Generated on Fri Mar 20 18:51:19 2009 for INET Framework for OMNeT++/OMNEST by  doxygen 1.5.5