port-mux.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 "port-mux.h"
00033 
00034 
00035 #define PORT_ALLOC_PER_TIMES 10
00036 
00037 static class PortMuxClass : public TclClass {
00038 public:
00039         PortMuxClass() : TclClass("Module/Port") {}
00040         TclObject* create(int, const char*const*) {
00041         return (new PortMux);
00042 
00043 }
00044 } class_transportmodule;
00045 
00046 PortMux::PortMux() : Module(), allocatedPort_(0), allocatedId_(0)
00047 {
00048 }
00049 
00050 PortMux::~PortMux()
00051 {
00052 }
00053 
00054 int PortMux::command(int argc, const char*const* argv)
00055 {
00056         Tcl& tcl = Tcl::instance();
00057         if(argc == 3)
00058         {
00059                 if (strcasecmp(argv[1],"assignPort")==0)
00060                 {
00061                         Module *m = (Module *)tcl.lookup(argv[2]);
00062                         if(!m)
00063                                 return TCL_ERROR;
00064                         if(allocatedId_ < getUpLaySAPnum())
00065                         {
00066                                 int *tmp = new int[getUpLaySAPnum()];
00067                                 for(int j = 0; j < getUpLaySAPnum(); j++)
00068                                 {
00069                                         if(j < allocatedId_)
00070                                                 tmp[j] = ids_[j];
00071                                         else
00072                                                 tmp[j] = -1;
00073                                 }
00074                                 if(allocatedId_)
00075                                         delete [] ids_;
00076                                 allocatedId_ = getUpLaySAPnum();
00077                                 ids_ = tmp;
00078                         }
00079                         for(int i = 0; i < getUpLaySAPnum(); i++)
00080                         {
00081                                 SAP *s = getUpLaySAP(i);
00082                                 if(s->getModuleUpId() == m->getId())
00083                                 {
00084                                         if(m->getId() >= allocatedPort_)
00085                                         {
00086                                                 int k = allocatedPort_ + ((m->getId() - allocatedPort_) / PORT_ALLOC_PER_TIMES + 1) * PORT_ALLOC_PER_TIMES;
00087                                                 int *temp = new int[k];
00088                                                 for(int j = 0; j < k; j++)
00089                                                 {
00090                                                         if(j < allocatedPort_)
00091                                                                 temp[j] = ports_[j];
00092                                                         else
00093                                                                 temp[j] = -1;
00094                                                 }
00095                                                 if(allocatedPort_)
00096                                                         delete [] ports_;
00097                                                 ports_ = temp;
00098                                                 allocatedPort_ += k;
00099                                         }
00100                                         if(debug_)
00101                                                 printf("PortMux::command module id=%d - i=%d\n", m->getId(), i);
00102                                         ports_[m->getId()] = i;
00103                                         ids_[i] = m->getId();
00104                                         tcl.resultf("%d", i);
00105                                         return TCL_OK;
00106                                 }
00107                         }
00108                         return TCL_ERROR;
00109                 }
00110         }
00111         return Module::command(argc, argv);
00112 }
00113 
00114 void PortMux::recv(Packet *p)
00115 {
00116         fprintf(stderr, "PortMux: a Packet is sent without source module!!\n");
00117         Packet::free(p);
00118 }
00119 
00120 void PortMux::recv(Packet *p, int idSrc)
00121 {
00122         hdr_cmn *ch = HDR_CMN(p);
00123         hdr_ip *iph = HDR_IP(p);
00124         if(ch->direction() == hdr_cmn::UP)
00125         {
00126           assert((iph->dport() >= 0) && (iph->dport() < allocatedPort_));
00127 
00128                 if(debug_ > 5)
00129                         printf("dest port %d id %d\n", iph->dport(), ids_[iph->dport()]);
00130                 sendUp(ids_[iph->dport()], p);
00131         }
00132         else
00133         {
00134                 if(idSrc < allocatedPort_ && ports_[idSrc] >= 0)
00135                 {
00136                         iph->sport() = ports_[idSrc];
00137                         sendDown(p);
00138                 }
00139                 else
00140                 {
00141                         fprintf(stderr, "PortMux: a Packet is sent from a source module that I don't know!!\n");
00142                         Packet::free(p);
00143                 }
00144         }
00145 }

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