Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <algorithm>
00020 #include <platdep/sockets.h>
00021 #include "headers/defs.h"
00022
00023 namespace INETFw
00024 {
00025 #include "headers/bsdint.h"
00026 #include "headers/in.h"
00027 #include "headers/in_systm.h"
00028 #include "headers/ip.h"
00029 };
00030
00031 #include "IPSerializer.h"
00032 #include "ICMPSerializer.h"
00033 #include "UDPSerializer.h"
00034 #include "SCTPSerializer.h"
00035 #include "TCPSerializer.h"
00036
00037 #if defined(_MSC_VER)
00038 #undef s_addr
00039 #endif
00040
00041 #if !defined(_WIN32) && !defined(__WIN32__) && !defined(WIN32) && !defined(__CYGWIN__) && !defined(_WIN64)
00042 #include <netinet/in.h>
00043 #endif
00044
00045 #ifndef IP_PROT_SCTP //I.R.
00046 #define IP_PROT_SCTP 132
00047 #endif
00048
00049
00050 #undef s_addr
00051
00052
00053 using namespace INETFw;
00054
00055
00056
00057 int IPSerializer::serialize(const IPDatagram *dgram, unsigned char *buf, unsigned int bufsize)
00058 {
00059 int packetLength;
00060 struct ip *ip = (struct ip *) buf;
00061
00062 ip->ip_hl = IP_HEADER_BYTES >> 2;
00063 ip->ip_v = dgram->getVersion();
00064 ip->ip_tos = dgram->getDiffServCodePoint();
00065 ip->ip_id = htons(dgram->getIdentification());
00066 ip->ip_off = htons(dgram->getFragmentOffset());
00067 ip->ip_ttl = dgram->getTimeToLive();
00068 ip->ip_p = dgram->getTransportProtocol();
00069 ip->ip_src.s_addr = htonl(dgram->getSrcAddress().getInt());
00070 ip->ip_dst.s_addr = htonl(dgram->getDestAddress().getInt());
00071 ip->ip_sum = 0;
00072
00073 if (dgram->getHeaderLength() > IP_HEADER_BYTES)
00074 EV << "Serializing an IP packet with options. Dropping the options.\n";
00075
00076 packetLength = IP_HEADER_BYTES;
00077
00078 cMessage *encapPacket = dgram->getEncapsulatedMsg();
00079 switch (dgram->getTransportProtocol())
00080 {
00081 case IP_PROT_ICMP:
00082 packetLength += ICMPSerializer().serialize(check_and_cast<ICMPMessage *>(encapPacket),
00083 buf+IP_HEADER_BYTES, bufsize-IP_HEADER_BYTES);
00084 break;
00085 case IP_PROT_UDP:
00086 packetLength += UDPSerializer().serialize(check_and_cast<UDPPacket *>(encapPacket),
00087 buf+IP_HEADER_BYTES, bufsize-IP_HEADER_BYTES);
00088 break;
00089 case IP_PROT_SCTP:
00090 packetLength += SCTPSerializer().serialize(check_and_cast<SCTPMessage *>(encapPacket),
00091 buf+IP_HEADER_BYTES, bufsize-IP_HEADER_BYTES);
00092 break;
00093 case IP_PROT_TCP:
00094 packetLength += TCPSerializer().serialize(check_and_cast<TCPSegment *>(encapPacket),
00095 buf+IP_HEADER_BYTES, bufsize-IP_HEADER_BYTES,
00096 dgram->getSrcAddress(), dgram->getDestAddress());
00097 break;
00098 default:
00099 opp_error("IPSerializer: cannot serialize protocol %d", dgram->getTransportProtocol());
00100 }
00101
00102 ip->ip_len = htons(packetLength);
00103
00104 return packetLength;
00105 }
00106
00107 void IPSerializer::parse(const unsigned char *buf, unsigned int bufsize, IPDatagram *dest)
00108 {
00109 const struct ip *ip = (const struct ip *) buf;
00110 unsigned int totalLength, headerLength;
00111
00112 dest->setVersion(ip->ip_v);
00113 dest->setHeaderLength(IP_HEADER_BYTES);
00114 dest->setSrcAddress(ntohl(ip->ip_src.s_addr));
00115 dest->setDestAddress(ntohl(ip->ip_dst.s_addr));
00116 dest->setTransportProtocol(ip->ip_p);
00117 dest->setTimeToLive(ip->ip_ttl);
00118 dest->setIdentification(ntohs(ip->ip_id));
00119 dest->setMoreFragments((ip->ip_off) & !IP_OFFMASK & IP_MF);
00120 dest->setDontFragment((ip->ip_off) & !IP_OFFMASK & IP_DF);
00121 dest->setFragmentOffset((ntohs(ip->ip_off)) & IP_OFFMASK);
00122 dest->setDiffServCodePoint(ip->ip_tos);
00123 totalLength = ntohs(ip->ip_len);
00124 headerLength = ip->ip_hl << 2;
00125
00126 if (headerLength > (unsigned int)IP_HEADER_BYTES)
00127 EV << "Handling an captured IP packet with options. Dropping the options.\n";
00128 if (totalLength > bufsize)
00129 EV << "Can not handle IP packet of total length " << totalLength << "(captured only " << bufsize << " bytes).\n";
00130 dest->setByteLength(IP_HEADER_BYTES);
00131
00132 cPacket *encapPacket = NULL;
00133 switch (dest->getTransportProtocol())
00134 {
00135 case IP_PROT_ICMP:
00136 encapPacket = new ICMPMessage("icmp-from-wire");
00137 ICMPSerializer().parse(buf + headerLength, std::min(totalLength, bufsize) - headerLength, (ICMPMessage *)encapPacket);
00138 break;
00139 case IP_PROT_UDP:
00140 encapPacket = new UDPPacket("udp-from-wire");
00141 UDPSerializer().parse(buf + headerLength, std::min(totalLength, bufsize) - headerLength, (UDPPacket *)encapPacket);
00142 break;
00143 case IP_PROT_SCTP:
00144 encapPacket = new SCTPMessage("sctp-from-wire");
00145 SCTPSerializer().parse(buf + headerLength, (unsigned int)(std::min(totalLength, bufsize) - headerLength), (SCTPMessage *)encapPacket);
00146 break;
00147 case IP_PROT_TCP:
00148 encapPacket = new TCPSegment("tcp-from-wire");
00149 TCPSerializer().parse(buf + headerLength, (unsigned int)(std::min(totalLength, bufsize) - headerLength), (TCPSegment *)encapPacket);
00150 break;
00151 default:
00152 opp_error("IPSerializer: cannot serialize protocol %d", dest->getTransportProtocol());
00153 }
00154
00155 ASSERT(encapPacket);
00156 dest->encapsulate(encapPacket);
00157 dest->setName(encapPacket->getName());
00158 }