INET Framework for OMNeT++/OMNEST
IPv6Datagram.cc
Go to the documentation of this file.
00001 //
00002 // Copyright (C) 2005 Andras Varga
00003 //
00004 // This program is free software; you can redistribute it and/or
00005 // modify it under the terms of the GNU Lesser General Public License
00006 // as published by the Free Software Foundation; either version 2
00007 // of the License, or (at your option) any later version.
00008 //
00009 // This program is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 // GNU Lesser General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU Lesser General Public License
00015 // along with this program; if not, see <http://www.gnu.org/licenses/>.
00016 //
00017 
00018 
00019 #include "IPv6Datagram.h"
00020 #include "IPv6ExtensionHeaders_m.h"
00021 
00022 
00023 Register_Class(IPv6Datagram);
00024 
00025 
00026 std::ostream& operator<<(std::ostream& os, IPv6ExtensionHeaderPtr eh)
00027 {
00028     return os << "(" << eh->getClassName() << ") " << eh->info();
00029 }
00030 
00031 IPv6Datagram& IPv6Datagram::operator=(const IPv6Datagram& other)
00032 {
00033     IPv6Datagram_Base::operator=(other);
00034 
00035     for (ExtensionHeaders::const_iterator i=other.extensionHeaders.begin(); i!=other.extensionHeaders.end(); ++i)
00036         addExtensionHeader((*i)->dup());
00037 
00038     return *this;
00039 }
00040 
00041 void IPv6Datagram::setExtensionHeaderArraySize(unsigned int size)
00042 {
00043     throw cRuntimeError(this, "setExtensionHeaderArraySize() not supported, use addExtensionHeader()");
00044 }
00045 
00046 unsigned int IPv6Datagram::getExtensionHeaderArraySize() const
00047 {
00048     return extensionHeaders.size();
00049 }
00050 
00051 IPv6ExtensionHeaderPtr& IPv6Datagram::getExtensionHeader(unsigned int k)
00052 {
00053     static IPv6ExtensionHeaderPtr null;
00054     if (k>=extensionHeaders.size())
00055         return (null=NULL);
00056     return extensionHeaders[k];
00057 }
00058 
00059 void IPv6Datagram::setExtensionHeader(unsigned int k, const IPv6ExtensionHeaderPtr& extensionHeader_var)
00060 {
00061     throw cRuntimeError(this, "setExtensionHeader() not supported, use addExtensionHeader()");
00062 }
00063 
00064 void IPv6Datagram::addExtensionHeader(IPv6ExtensionHeader *eh, int atPos)
00065 {
00066     if (atPos<0 || atPos>=(int)extensionHeaders.size())
00067     {
00068         extensionHeaders.push_back(eh);
00069         return;
00070     }
00071 
00072     // insert at position atPos, shift up the rest of the array
00073     extensionHeaders.insert(extensionHeaders.begin()+atPos, eh);
00074 }
00075 
00076 int IPv6Datagram::calculateHeaderByteLength() const
00077 {
00078     int len = 40;
00079     for (unsigned int i=0; i<extensionHeaders.size(); i++)
00080         len += extensionHeaders[i]->getByteLength();
00081     return len;
00082 }
00083 
00084 //---
00085 
00086 Register_Class(IPv6ExtensionHeader);
00087 
00088 
00089 IPProtocolId IPv6ExtensionHeader::getExtensionType() const
00090 {
00091     // FIXME msg files don't yet support readonly attrs that can be
00092     // redefined in subclasses, so for now we resort to the following
00093     // unsafe and unextensible nasty solution
00094     if (dynamic_cast<const IPv6HopByHopOptionsHeader*>(this)) {
00095         return IP_PROT_IPv6EXT_HOP;
00096     } else if (dynamic_cast<const IPv6RoutingHeader*>(this)) {
00097         return IP_PROT_IPv6EXT_ROUTING;
00098     } else if (dynamic_cast<const IPv6FragmentHeader*>(this)) {
00099         return IP_PROT_IPv6EXT_FRAGMENT;
00100     } else if (dynamic_cast<const IPv6DestinationOptionsHeader*>(this)) {
00101         return IP_PROT_IPv6EXT_DEST;
00102     } else if (dynamic_cast<const IPv6AuthenticationHeader*>(this)) {
00103         return IP_PROT_IPv6EXT_AUTH;
00104     } else if (dynamic_cast<const IPv6EncapsulatingSecurityPayloadHeader*>(this)) {
00105         return IP_PROT_IPv6EXT_ESP;
00106     } else {
00107         throw cRuntimeError("unrecognised HeaderExtension subclass %s in IPv6ExtensionHeader::getExtensionType()", getClassName());
00108     }
00109 }
00110 
00111 int IPv6ExtensionHeader::getByteLength() const
00112 {
00113     // FIXME msg files don't yet support readonly attrs that can be
00114     // redefined in subclasses, so for now we resort to the following
00115     // unsafe and unextensible nasty solution
00116     if (dynamic_cast<const IPv6HopByHopOptionsHeader*>(this)) {
00117         return 8; // FIXME verify
00118     } else if (dynamic_cast<const IPv6RoutingHeader*>(this)) {
00119         return 8; // FIXME verify
00120     } else if (dynamic_cast<const IPv6FragmentHeader*>(this)) {
00121         return 8;
00122     } else if (dynamic_cast<const IPv6DestinationOptionsHeader*>(this)) {
00123         return 8; // FIXME verify
00124     } else if (dynamic_cast<const IPv6AuthenticationHeader*>(this)) {
00125         return 8; // FIXME verify
00126     } else if (dynamic_cast<const IPv6EncapsulatingSecurityPayloadHeader*>(this)) {
00127         return 8; // FIXME verify
00128     } else {
00129         throw cRuntimeError("unrecognised HeaderExtension subclass %s in IPv6ExtensionHeader::getExtensionType()", getClassName());
00130     }
00131 }
00132 
00133