ip-routing.cc

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-routing.h"
00033 #include"ipmodule.h"
00034 
00035 
00036 
00037 #define DROP_TTL_EXPIRED_DEPHT 1
00038 #define DROP_TTL_EXPIRED_REASON "TTL"
00039 
00040 #define DROP_DEST_UNREACHABLE_DEPTH 1
00041 #define DROP_DEST_UNREACHABLE_REASON "DUR"
00042 
00043 static class IPRoutingModuleClass : public TclClass {
00044 public:
00045   IPRoutingModuleClass() : TclClass("Module/IP/Routing") {}
00046   TclObject* create(int, const char*const*) {
00047     return (new IPRoutingModule);
00048 
00049   }
00050 } class_ipinterface_module;
00051 
00052 
00053 IPRoutingModule::IPRoutingModule() : nroutes(0)
00054 {
00055   clearRoutes();
00056 }
00057 
00058 IPRoutingModule::~IPRoutingModule() 
00059 {
00060 }
00061 
00062 
00063 void IPRoutingModule::clearRoutes()
00064 {
00065   for (int i=0; i<IP_ROUTING_MAX_ROUTES; i++)
00066     {
00067       destination[i] = 0;
00068       subnetmask[i] = 0;
00069       nexthop[i] = 0;
00070     } 
00071 
00072   nroutes = 0;
00073 }
00074 
00075 void IPRoutingModule::addRoute(nsaddr_t dst, nsaddr_t mask, nsaddr_t next)
00076 { 
00077   assert(nroutes < IP_ROUTING_MAX_ROUTES);
00078   destination[nroutes] = dst;
00079   subnetmask[nroutes] = mask;
00080   nexthop[nroutes] = next;
00081   nroutes++;
00082 
00083 
00084 }
00085 
00086 
00087 int IPRoutingModule::command(int argc, const char*const* argv)
00088 {
00089   Tcl& tcl = Tcl::instance();
00090   if(argc == 2)
00091     {
00092       if (strcasecmp(argv[1],"numroutes")==0) 
00093         {
00094           tcl.resultf("%d", nroutes);
00095           return TCL_OK;
00096           
00097         }
00098       if (strcasecmp(argv[1],"clearroutes")==0) 
00099         {
00100           clearRoutes();
00101           return TCL_OK;
00102         }
00103       else if (strcasecmp(argv[1],"printroutes")==0) 
00104         {
00105           printf("Destination    Subnet Mask    Next Hop\n");
00106           for (int i=0; i<nroutes; i++) {               
00107             printf("%d.%d.%d.%d\t\t",
00108                    (destination[i] & 0xff000000)>>24,
00109                    (destination[i] & 0x00ff0000)>>16,
00110                    (destination[i] & 0x0000ff00)>>8,
00111                    (destination[i] & 0x000000ff));
00112             printf("%d.%d.%d.%d\t\t",
00113                    (subnetmask[i] & 0xff000000)>>24,
00114                    (subnetmask[i] & 0x00ff0000)>>16,
00115                    (subnetmask[i] & 0x0000ff00)>>8,
00116                    (subnetmask[i] & 0x000000ff));
00117             printf("%d.%d.%d.%d\n",
00118                    (nexthop[i] & 0xff000000)>>24,
00119                    (nexthop[i] & 0x00ff0000)>>16,
00120                    (nexthop[i] & 0x0000ff00)>>8,
00121                    (nexthop[i] & 0x000000ff));
00122           }
00123           return TCL_OK;
00124         }                               
00125     }
00126   else if (argc == 3) {
00127     if (strcasecmp (argv[1], "defaultGateway") == 0) {
00128       addRoute( 0x00000000, 0x00000000, str2addr(argv[2]));
00129       return TCL_OK;
00130     }
00131               
00132   }
00133   else if (argc == 5) {
00134     if (strcasecmp (argv[1], "addroute") == 0) {
00135       addRoute(str2addr(argv[2]) ,
00136                str2addr(argv[3]),
00137                str2addr(argv[4]));
00138       return TCL_OK;
00139     }
00140               
00141   }
00142 
00143   /* we DON'T call IPModule::command here
00144    since we don't need the tcl functionality 
00145    of IPModule class */
00146   return Module::command(argc, argv);
00147 }
00148 
00149 
00150 
00151 
00152 void IPRoutingModule::recv(Packet *p)
00153 {
00154   hdr_ip *iph = HDR_IP(p);
00155   hdr_cmn *ch = HDR_CMN(p);
00156 
00157   if(ch->direction() == hdr_cmn::UP)
00158     {
00159 
00160       /* WARNING 
00161        * it is required that there is an IP module below this 
00162        * which checks if the IP of the interface corresponds to
00163        * the next_hop address
00164        * otherwise ALL nodes receiving the last hop transmission
00165        * will forward the packet to upper layers!
00166        */ 
00167 
00168       if(iph->daddr() == ch->next_hop_ || iph->daddr() == IP_BROADCAST)
00169         { /* Packet is arrived at its destination */
00170           ch->size() -= IP_HDR_LEN;
00171           sendUp(p);
00172           return;
00173         }
00174                   
00175       /* Check TTL */
00176 
00177       iph->ttl()--; 
00178       if (iph->ttl() == 0)
00179         {
00180           drop(p,DROP_TTL_EXPIRED_DEPHT, DROP_TTL_EXPIRED_REASON);
00181           return;
00182         }
00183 
00184       /* Forward Packet */      
00185       ch->direction() = hdr_cmn::DOWN; 
00186       ch->next_hop_ = GetNextHop(p);
00187 
00188       if (ch->next_hop_ == 0) 
00189         {
00190           drop(p,DROP_DEST_UNREACHABLE_DEPTH, DROP_DEST_UNREACHABLE_REASON);
00191         }
00192       else
00193         {
00194           sendDown(p);
00195         }
00196       
00197       
00198     }
00199   else
00200     {  /* direction DOWN */
00201       //assert(iph->saddr() == 0); /* who the hell has set IP source address ? */
00202       iph->saddr() = 0;
00203 
00204       iph->ttl() = IP_DEF_TTL;      
00205       ch->size() += IP_HDR_LEN;
00206       ch->addr_type()   = NS_AF_INET;
00207       
00208 
00209 //       if ((u_int32_t)iph->daddr() == IP_BROADCAST)
00210 //      ch->next_hop()  = IP_BROADCAST;
00211       
00212       
00213       ch->next_hop_ = GetNextHop(p);
00214      
00215       
00216       if (ch->next_hop_ == 0) 
00217         {
00218           drop(p,DROP_DEST_UNREACHABLE_DEPTH, DROP_DEST_UNREACHABLE_REASON);
00219         }
00220       else
00221         {
00222           sendDown(p);
00223         }
00224   
00225     }
00226 
00227 }  
00228  
00229 
00230 nsaddr_t IPRoutingModule::GetNextHop(Packet *p)
00231 {
00232   hdr_ip *iph = HDR_IP(p);
00233   GetNextHop(iph->daddr());
00234 }
00235 
00236 
00237 nsaddr_t IPRoutingModule::GetNextHop(nsaddr_t dst)
00238 {
00239 //   printf("IPRoutingModule::GetNextHop destination %x (%d.%d.%d.%d)\n",
00240 //       dst,
00241 //       (dst & 0xff000000)>>24,
00242 //       (dst & 0x00ff0000)>>16,
00243 //       (dst & 0x0000ff00)>>8,
00244 //       (dst & 0x000000ff));
00245 
00246   for (int i=0; i<nroutes; i++) 
00247     {     
00248       if ((dst & subnetmask[i]) == (destination[i] & subnetmask[i]))
00249         {
00250           
00251           return nexthop[i];      
00252         }
00253     }
00254 
00255   return 0; 
00256 }
00257 
00258 

Generated on Wed Nov 26 15:47:27 2008 for NS-MIRACLE library by  doxygen 1.5.2