|
INET Framework for OMNeT++/OMNEST
|
00001 // 00002 // Copyright (C) 2005 Christian Dankbar, Irene Ruengeler, Michael Tuexen, Andras Varga 00003 // Copyright (C) 2009 Thomas Reschka 00004 // 00005 // This program is free software; you can redistribute it and/or 00006 // modify it under the terms of the GNU General Public License 00007 // as published by the Free Software Foundation; either version 2 00008 // of the License, or (at your option) any later version. 00009 // 00010 // This program is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 // GNU General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU General Public License 00016 // along with this program; if not, see <http://www.gnu.org/licenses/>. 00017 // 00018 00019 #include <algorithm> // std::min 00020 #include <platdep/sockets.h> 00021 #include "headers/defs.h" 00022 00023 namespace INETFw // load headers into a namespace, to avoid conflicts with platform definitions of the same stuff 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" //I.R. 00035 #include "TCPSerializer.h" //I.R. 00036 00037 #if defined(_MSC_VER) 00038 #undef s_addr /* MSVC #definition interferes with us */ 00039 #endif 00040 00041 #if !defined(_WIN32) && !defined(__WIN32__) && !defined(WIN32) && !defined(__CYGWIN__) && !defined(_WIN64) 00042 #include <netinet/in.h> // htonl, ntohl, ... 00043 #endif 00044 00045 #ifndef IP_PROT_SCTP //I.R. 00046 #define IP_PROT_SCTP 132 00047 #endif 00048 00049 // This in_addr field is defined as a macro in Windows and Solaris, which interferes with us 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->getEncapsulatedPacket(); 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: //I.R. 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: //I.R. 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 }