ipmodule.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 "ipmodule.h"
00031 #include "ip.h"
00032 #include "ip-clmsg.h"
00033 
00034 static class IPModuleClass : public TclClass {
00035 public:
00036         IPModuleClass() : TclClass("Module/IP") {}
00037         TclObject* create(int, const char*const*) {
00038         return (new IPModule());
00039 
00040 }
00041 } class_ipmodule;
00042 
00043 nsaddr_t lastIP = 0;
00044 
00045 IPModule::IPModule() : Module()
00046 {
00047         ipAddr_ = ++lastIP;
00048 }
00049 
00050 IPModule::~IPModule()
00051 {
00052 }
00053 
00054 int IPModule::command(int argc, const char*const* argv)
00055 {
00056         Tcl& tcl = Tcl::instance();
00057         if(argc == 2)
00058         {
00059                 if (strcasecmp(argv[1],"addr")==0)
00060                 {
00061                         tcl.resultf("%d", ipAddr_);
00062                         return TCL_OK;
00063                 }
00064                 else if (strcasecmp(argv[1],"subnet")==0)
00065                 {
00066                         tcl.resultf("%d", subnet_);
00067                         return TCL_OK;
00068                 }
00069                 else if (strcasecmp(argv[1],"addr-string")==0)
00070                 {
00071                         tcl.resultf("%d.%d.%d.%d", (ipAddr_ & 0xff000000)>>24,(ipAddr_ & 0x00ff0000)>>16, (ipAddr_ & 0x0000ff00)>>8, (ipAddr_ & 0x000000ff));
00072                         return TCL_OK;
00073                 }
00074                 else if (strcasecmp(argv[1],"subnet-string")==0)
00075                 {
00076                         tcl.resultf("%d.%d.%d.%d", (subnet_ & 0xff000000)>>24,(subnet_ & 0x00ff0000)>>16, (subnet_ & 0x0000ff00)>>8, (subnet_ & 0x000000ff));
00077                         return TCL_OK;
00078                 }
00079         }
00080         else if (argc == 3) {
00081                 if (strcasecmp (argv[1], "addr") == 0) {
00082                         ipAddr_ = str2addr((char *)argv[2]);
00083                         if (ipAddr_ == 0)
00084                           {
00085                             fprintf(stderr,"0.0.0.0 is not a valid IP address");
00086                             return TCL_ERROR;
00087                           }
00088                         subnet_ = get_subnetaddr(ipAddr_);
00089                         return TCL_OK;
00090                 }
00091                 else if (strcasecmp (argv[1], "subnet") == 0) {
00092                         subnet_ = str2sub((char *)argv[2]);
00093                         return TCL_OK;
00094                 }
00095         }
00096         return Module::command(argc, argv);
00097 }
00098 
00099 void IPModule::recv(Packet *p)
00100 {
00101         hdr_ip *iph = HDR_IP(p);
00102         hdr_cmn *ch = HDR_CMN(p);
00103         if(ch->direction() == hdr_cmn::UP)
00104         {
00105                 if(iph->daddr() == ipAddr_ || iph->daddr() == IP_BROADCAST)
00106                 {
00107                         ch->size() -= IP_HDR_LEN;
00108                         sendUp(p);
00109                 }
00110                 else
00111                 {
00112                         /*
00113                         This is a simple IP module. If you want to add routing feature, put here the code for forward the packets.
00114                         */
00115                         drop(p, NOT_FOR_ME_DEPTH, NOT_FOR_ME_REASON);
00116                 }
00117         }
00118         else
00119         {
00120 
00121                 iph->saddr() = ipAddr_;
00122                 iph->ttl() = IP_DEF_TTL;
00123                 ch->addr_type() = NS_AF_INET;
00124                 ch->size() += IP_HDR_LEN;
00125                 if ((u_int32_t)iph->daddr() == IP_BROADCAST)
00126                         ch->next_hop()  = IP_BROADCAST;
00127                 else {
00128                         ch->next_hop() = iph->daddr();
00129                 }
00130                 sendDown(p);
00131         }
00132 }
00133 
00134 nsaddr_t IPModule::str2addr(const char *str)
00135 {
00136         int level[4] = {0,0,0,0};
00137         char tmp[20];
00138         strncpy(tmp,str,19);
00139         tmp[19] = '\0';
00140         char *p = strtok(tmp, ".");
00141         for(int i = 0; p && i < 4; p = strtok(NULL, "."), i++)
00142         {
00143                 level[i] = atoi(p);
00144                 if(level[i] > 255)
00145                         level[i] = 255;
00146                 else if(level[i] < 0)
00147                         level[i] = 0;
00148         }
00149         nsaddr_t addr = 0;
00150         for(int i = 0; i < 4; i++)
00151         {
00152                 addr += (level[i] << 8 * (3 - i));
00153         }
00154         return addr;
00155 }
00156 
00157 nsaddr_t IPModule::str2sub(const char *str)
00158 {
00159         int level[4] = {0,0,0,0};
00160         char tmp[20];
00161         strncpy(tmp,str,19);
00162         tmp[19] = '\0';
00163         char *p = strtok(tmp, ".");
00164         for(int i = 0; p && i < 4; p = strtok(NULL, "."), i++)
00165         {
00166                 level[i] = atoi(p);
00167                 if(level[i] > 255)
00168                         level[i] = 255;
00169                 else if(level[i] < 0)
00170                         level[i] = 0;
00171         }
00172         nsaddr_t sub = 0;
00173         for(int i = 0; i < 4; i++)
00174         {
00175                 sub += (level[i] << 8 * (3 - i));
00176         }
00177         return sub;
00178 }
00179 
00180 nsaddr_t IPModule::get_subnetaddr(nsaddr_t addr)
00181 {
00182         int c = 0;
00183         nsaddr_t a = (addr & 0xff000000)>>24;
00184         if (a < 128)
00185                 c = 1;
00186         else if (a < 192)
00187                 c = 2;
00188         else if (a < 224)
00189                 c = 3;
00190         else if (a < 240)
00191                 c = 4;
00192         else
00193                 c = 5;
00194         
00195         if (c > 3)
00196                 return 0;
00197         
00198         switch(c)
00199         {
00200                 case 1:
00201                         return (nsaddr_t)0xff000000;
00202                 case 2:
00203                         return (nsaddr_t)0xffff0000;
00204                 case 3:
00205                         return (nsaddr_t)0xffffff00;
00206         }
00207 }
00208 
00209 
00210 int IPModule::recvSyncClMsg(ClMessage* m)
00211 {
00212         if(m->type() == IP_CLMSG_SEND_ADDR)
00213         {
00214                 IPClMsgSendAddr *c = new IPClMsgSendAddr(UNICAST, m->getSource());
00215                 c->setAddr(ipAddr_);
00216 //              sendDown(m->getSource(), c);            // DEPRECATED method
00217                 sendAsyncClMsgDown(c);
00218                 return 0;
00219         }
00220         return Module::recvSyncClMsg(m);
00221 }

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