address.cc

Go to the documentation of this file.
00001 /* -*-  Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
00002 /*
00003  * Copyright (c) 1990-1997 Regents of the University of California.
00004  * All rights reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions
00008  * are met:
00009  * 1. Redistributions of source code must retain the above copyright
00010  *    notice, this list of conditions and the following disclaimer.
00011  * 2. Redistributions in binary form must reproduce the above copyright
00012  *    notice, this list of conditions and the following disclaimer in the
00013  *    documentation and/or other materials provided with the distribution.
00014  * 3. All advertising materials mentioning features or use of this software
00015  *    must display the following acknowledgement:
00016  *  This product includes software developed by the Computer Systems
00017  *  Engineering Group at Lawrence Berkeley Laboratory.
00018  * 4. Neither the name of the University nor of the Laboratory may be used
00019  *    to endorse or promote products derived from this software without
00020  *    specific prior written permission.
00021  *
00022  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00023  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00024  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00025  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00026  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00027  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00028  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00029  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00031  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00032  * SUCH DAMAGE.
00033  *
00034  * $Header: /nfs/jade/vint/CVSROOT/ns-2/routing/address.cc,v 1.27 2005/07/27 01:13:44 tomh Exp $
00035  */
00036 
00037 #include <stdio.h>
00038 #include <stdlib.h>
00039 #include <assert.h>
00040 #include "address.h"
00041 #include "route.h"
00042 
00043 static class AddressClass : public TclClass {
00044 public:
00045     AddressClass() : TclClass("Address") {} 
00046     TclObject* create(int, const char*const*) {
00047         return (new Address());
00048     }
00049 } class_address;
00050 
00051 
00052 Address* Address::instance_;
00053 
00054 Address::Address() : 
00055     NodeShift_(NULL), NodeMask_(NULL), McastShift_(0), McastMask_(0), 
00056     levels_(0)
00057 {
00058 }
00059 
00060 
00061 Address::~Address() 
00062 { 
00063     delete [] NodeShift_;
00064     delete [] NodeMask_;
00065 }
00066 
00067 int Address::command(int argc, const char*const* argv)
00068 {
00069     int i, c, temp=0;
00070 
00071     Tcl& tcl = Tcl::instance();
00072     if ((instance_ == 0) || (instance_ != this))
00073         instance_ = this;
00074     if (argc == 3) {
00075         if (strcmp(argv[1], "str2addr") == 0) {
00076             tcl.resultf("%d", str2addr(argv[2]));
00077             return (TCL_OK);
00078         }
00079     }
00080     if (argc >= 3) {
00081         if (strcmp(argv[1], "bpl-are") == 0) {
00082             if (levels_ != (argc-2)) {
00083                 tcl.resultf("#bpl don't match with #hier levels\n");
00084                 return (TCL_ERROR);
00085             }
00086             bpl_ = new int[levels_ + 1];
00087             for (c=1; c<=levels_; c++)
00088                 bpl_[c] = atoi(argv[c+1]);
00089             return TCL_OK;
00090         }
00091     }
00092     if (argc == 4) {
00093         if (strcmp(argv[1], "mcastbits-are") == 0) {
00094             McastShift_ = atoi(argv[2]);
00095             McastMask_ = atoi(argv[3]);
00096             return (TCL_OK);
00097         }
00098     }
00099     if (argc >= 4) {
00100         if (strcmp(argv[1], "add-hier") == 0) {
00101             /*
00102              * <address> add-hier <level> <mask> <shift>
00103              */
00104             int level = atoi(argv[2]);
00105             int mask = atoi(argv[3]);
00106             int shift = atoi(argv[4]);
00107             if (levels_ < level)
00108                 levels_ = level;
00109             NodeShift_[level] = shift;
00110             NodeMask_[level] = mask;
00111             return (TCL_OK);
00112         }
00113 
00114         if (strcmp(argv[1], "idsbits-are") == 0) {
00115             temp = (argc - 2)/2;
00116             if (levels_) { 
00117                 if (temp != levels_) {
00118                     tcl.resultf("#idshiftbits don't match with #hier levels\n");
00119                     return (TCL_ERROR);
00120                 }
00121             }
00122             else 
00123                 levels_ = temp;
00124             NodeShift_ = new int[levels_ + 1];
00125             for (i = 3, c = 1; c <= levels_; c++, i+=2)
00126                 NodeShift_[c] = atoi(argv[i]);
00127             return (TCL_OK); 
00128         }
00129     
00130         if (strcmp(argv[1], "idmbits-are") == 0) {
00131             temp = (argc - 2)/2;
00132             if (levels_) { 
00133                 if (temp != levels_) {
00134                     tcl.resultf("#idmaskbits don't match with #hier levels\n");
00135                     return (TCL_ERROR);
00136                 }
00137             }
00138             else 
00139                 levels_ = temp;
00140             NodeMask_ = new int[levels_ + 1];
00141             for (i = 3, c = 1; c <= levels_; c++, i+=2) 
00142                 NodeMask_[c] = atoi(argv[i]);
00143             return (TCL_OK);
00144         }
00145     }
00146     return TclObject::command(argc, argv);
00147 }
00148 
00149 char *Address::print_nodeaddr(int address)
00150 {
00151     int a;
00152     char temp[SMALL_LEN];
00153     char str[SMALL_LEN];
00154     char *addrstr;
00155 
00156     str[0] = '\0';
00157     for (int i=1; i <= levels_; i++) {
00158         a = address >> NodeShift_[i];
00159         if (levels_ > 1)
00160             a = a & NodeMask_[i];
00161         //if (i < levels_)
00162         sprintf(temp, "%d.", a);
00163         //else
00164         //sprintf(temp, "%d", a);
00165         
00166         strcat(str, temp);
00167     }
00168     int len;
00169     len = strlen(str);
00170     addrstr = new char[len+1];
00171     str[len-1]= 0; //kill the last dot
00172     strcpy(addrstr, str);
00173     // printf("Nodeaddr - %s\n",addrstr);
00174     return(addrstr);
00175 }
00176 
00177 int Address::hier_addr(int address, int level) {
00178     if (level <= levels_) {
00179         return ( (address >> NodeShift_[level]) & NodeMask_[level]);
00180     }
00181     perror("Address::hier_addr: levels greater than total h_levels_\n");
00182     return -1;
00183 }
00184 
00185 char *Address::get_subnetaddr(int address)
00186 {
00187     int a;
00188     char temp[SMALL_LEN];
00189     char str[SMALL_LEN];
00190     char *addrstr;
00191 
00192     if (levels_ > 1) {
00193         str[0] = '\0';
00194         for (int i=1; i < levels_; i++) {
00195             a = address >> NodeShift_[i];
00196             a = a & NodeMask_[i];
00197             if (i < (levels_-1))
00198                 sprintf(temp, "%d.", a);
00199             else
00200                 sprintf(temp, "%d", a);
00201             strcat(str, temp);
00202         }
00203         addrstr = new char[strlen(str)+1];
00204         strcpy(addrstr, str);
00205         //printf("Subnet_addr - %s\n",addrstr);
00206         return(addrstr);
00207     }
00208     return NULL;
00209 }
00210 
00211 // returns nodeaddr in integer form (relevant especially for hier-addr)
00212 int Address::get_nodeaddr(int address)
00213 {
00214     int a;
00215     char *temp;
00216     
00217     temp = print_nodeaddr(address);
00218     a = str2addr(temp);
00219     delete [] temp;
00220     return a;
00221 }
00222 
00223 
00224 //Sets address in pkthdr format (having port and node fields)
00225 int Address::create_ipaddr(int nodeid, int)
00226 {
00227     return nodeid;
00228     // The following code is obsolete
00229 #if 0
00230     int address;
00231     if (levels_ < 2) 
00232         address = (nodeid & NodeMask_[1]) << NodeShift_[1];
00233     else 
00234         address = nodeid;
00235     address = ((portid & PortMask_) << PortShift_) | \
00236         ((~(PortMask_) << PortShift_) & address);
00237     return address;
00238 #endif
00239 }
00240 
00241 int Address::get_lastaddr(int address)
00242 {
00243     int a;
00244     a = address >> NodeShift_[levels_];
00245     a = a & NodeMask_[levels_];
00246     return a;
00247  }
00248 
00249 
00250 char *Address::print_portaddr(int address)
00251 {
00252     char str[SMALL_LEN];
00253     char *addrstr;
00254 
00255     str[0] = '\0';
00256 #if 0
00257     int a;
00258     a = address >> PortShift_;
00259     a = a & PortMask_;
00260 #endif
00261     sprintf(str, "%d", address);
00262     addrstr = new char[strlen(str)+1];
00263     strcpy(addrstr, str);
00264     // printf("Portaddr - %s\n",addrstr);
00265 
00266     return(addrstr);
00267 }
00268 
00269 // Convert address in string format to binary format (int). 
00270 int Address::str2addr(const char *str) const
00271 {
00272     
00273     if (levels_ < 2) {
00274         int tmp = atoi(str);        
00275         if (tmp < 0)     
00276             return (tmp);
00277         u_int uitmp = (u_int) tmp;
00278         if (uitmp > ((unsigned long)(1 << bpl_[1])) ) {
00279             fprintf(stderr, "Error!!\nstr2addr:Address %u outside range of address field length %lu\n", 
00280                 uitmp, ((unsigned long)(1<< bpl_[1])));
00281             exit(1);
00282         }
00283         return tmp;
00284     }
00285     /*
00286       int istr[levels_], addr= 0;
00287     */
00288     /*
00289      * for VC++
00290      */
00291 
00292     int *istr= new int[levels_];
00293     int addr= 0;
00294     
00295     RouteLogic::ns_strtok((char*)str, istr);
00296     for (int i = 0; i < levels_; i++) {
00297         assert (istr[i] - 1 >= 0);
00298         if (((unsigned long)--istr[i]) > ((unsigned long)(1 << bpl_[i+1])) ) {
00299             fprintf(stderr, "Error!!\nstr2addr:Address %d outside range of address field length %lu\n", 
00300                 istr[i], ((unsigned long)(1<< bpl_[i+1])));
00301             exit(1);
00302         }
00303         addr = set_word_field(addr, istr[i],
00304                       NodeShift_[i+1], NodeMask_[i+1]);
00305     }
00306     
00307     delete [] istr;
00308     
00309     return addr;
00310 }
00311 
00312 
00313 
00314 
00315 
00316 
00317 
00318 
00319 

Generated on Tue Mar 6 16:47:43 2007 for ns2 Network Simulator 2.29 by  doxygen 1.4.6