00001 /* 00002 * Copyright (c) 2007 Regents of the SIGNET lab, University of Padova. 00003 * All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions 00007 * are met: 00008 * 1. Redistributions of source code must retain the above copyright 00009 * notice, this list of conditions and the following disclaimer. 00010 * 2. Redistributions in binary form must reproduce the above copyright 00011 * notice, this list of conditions and the following disclaimer in the 00012 * documentation and/or other materials provided with the distribution. 00013 * 3. Neither the name of the University of Padova (SIGNET lab) nor the 00014 * names of its contributors may be used to endorse or promote products 00015 * derived from this software without specific prior written permission. 00016 * 00017 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00018 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 00019 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 00020 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 00021 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00022 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00023 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 00024 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 00025 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 00026 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 00027 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00028 */ 00029 00030 #include <ip.h> 00031 00032 #include "ip-interface.h" 00033 00034 #define NEXT_HOP_UNREACHABLE_DEPHT 5 00035 #define NEXT_HOP_UNREACHABLE_REASON "NHU" 00036 00037 static class IPInterfaceModuleClass : public TclClass { 00038 public: 00039 IPInterfaceModuleClass() : TclClass("Module/IP/Interface") {} 00040 TclObject* create(int, const char*const*) { 00041 return (new IPInterfaceModule); 00042 00043 } 00044 } class_ipinterface_module; 00045 00046 00047 IPInterfaceModule::IPInterfaceModule() 00048 { 00049 } 00050 00051 IPInterfaceModule::~IPInterfaceModule() 00052 { 00053 } 00054 00055 00056 void IPInterfaceModule::recv(Packet *p) 00057 { 00058 hdr_ip *iph = HDR_IP(p); 00059 hdr_cmn *ch = HDR_CMN(p); 00060 00061 if(ch->direction() == hdr_cmn::UP) 00062 { 00063 00064 if (iph->daddr() == ipAddr_ ) 00065 { 00066 // I am the final destination 00067 // Unfortunately current IpRouting implementation is not 00068 // aware of the IP address of each underlying interface, so 00069 // it can only see if the destination is equal to the next 00070 // hop. For this reason, the IP Interface module must 00071 // explicitly perform the following operation to let 00072 // IpRouting do the right thing(TM). 00073 ch->next_hop_ = iph->daddr(); 00074 } 00075 00076 if ( (ch->next_hop_ == ipAddr_ ) 00077 || (iph->daddr() == ipAddr_ ) ) 00078 { // I am either the next hop or the destination, 00079 // so I'll forward this packet up 00080 sendUp(p); 00081 } 00082 else 00083 { // I am NOT the next hop 00084 drop(p, NOT_FOR_ME_DEPTH, NOT_FOR_ME_REASON); 00085 } 00086 } 00087 else 00088 { /* direction DOWN */ 00089 00090 // If destination is local, the next_hop_ is the destination 00091 // NO! This is BAD! Think about it! How can you do ad-hoc routing then? 00092 // if((ipAddr_ & subnet_) == (iph->daddr() & subnet_)) 00093 // ch->next_hop_ = iph->daddr(); 00094 00095 /* Check if next hop can be reached through this interface */ 00096 if ( ! ((ch->next_hop_ & subnet_) == (ipAddr_ & subnet_))) 00097 { 00098 drop(p,NEXT_HOP_UNREACHABLE_DEPHT, NEXT_HOP_UNREACHABLE_REASON); 00099 } 00100 else 00101 { // next hop is reachable, packet will be sent through this interface 00102 00103 00104 // Set source IP ONLY IF it was not set before 00105 // (0.0.0.0 is not a valid address) 00106 if (iph->saddr() == 0) 00107 iph->saddr() = ipAddr_; 00108 00109 // Mark this IP interface as the previous hop 00110 ch-> prev_hop_ = ipAddr_; 00111 00112 sendDown(p); 00113 } 00114 } 00115 }