00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
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
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
00162 sprintf(temp, "%d.", a);
00163
00164
00165
00166 strcat(str, temp);
00167 }
00168 int len;
00169 len = strlen(str);
00170 addrstr = new char[len+1];
00171 str[len-1]= 0;
00172 strcpy(addrstr, str);
00173
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
00206 return(addrstr);
00207 }
00208 return NULL;
00209 }
00210
00211
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
00225 int Address::create_ipaddr(int nodeid, int)
00226 {
00227 return nodeid;
00228
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
00265
00266 return(addrstr);
00267 }
00268
00269
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
00287
00288
00289
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