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
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058 extern "C" {
00059 #include <assert.h>
00060 #include <stdio.h>
00061 }
00062
00063 #include <packet.h>
00064 #include <ip.h>
00065 #include "hdr_sr.h"
00066 #include "path.h"
00067
00068
00069
00070
00071
00072 ID invalid_addr(0xffffffff,::NONE);
00073 ID IP_broadcast(IP_BROADCAST,::IP);
00074
00075
00076
00077
00078
00079 void
00080 ID::unparse(FILE *out) const
00081 {
00082 fprintf(out,"%d",(int) addr);
00083 }
00084
00085 char *
00086 ID::dump() const
00087 {
00088 static char buf[MAX_SR_LEN+1][50];
00089 static int which = 0;
00090 char *ptr = buf[which];
00091 which = (which + 1) % (MAX_SR_LEN+1);
00092
00093 assert(type == ::NONE || type == ::MAC || type == ::IP);
00094
00095 if (type == ::IP)
00096 sprintf(ptr,"%d",(int) addr);
00097 else if (type == ::NONE)
00098 sprintf(ptr,"NONE");
00099 else
00100 sprintf(ptr,"0x%x",(int) addr);
00101 return ptr;
00102 }
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113 Path::Path(int route_len, const ID *route)
00114 {
00115 path = new ID[MAX_SR_LEN];
00116 assert(route_len <= MAX_SR_LEN);
00117
00118
00119 if (route != NULL)
00120 {
00121 for (int c = 0; c < route_len; c++)
00122 {
00123 path[c] = route[c];
00124 }
00125 len = route_len;
00126 }
00127 else
00128 {
00129 len = 0;
00130 }
00131 cur_index = 0;
00132 }
00133
00134 Path::Path()
00135 {
00136 path = new ID[MAX_SR_LEN];
00137 len = 0;
00138 cur_index = 0;
00139 }
00140
00141
00142 Path::Path(const struct sr_addr *addrs, int len)
00143 {
00144 assert(len <= MAX_SR_LEN);
00145 path = new ID[MAX_SR_LEN];
00146
00147 for (int i = 0 ; i < len ; i++)
00148 path[i] = ID(addrs[i]);
00149
00150 this->len = len;
00151 cur_index = 0;
00152 }
00153
00154 Path::Path(struct hdr_sr *srh)
00155 {
00156 path = new ID[MAX_SR_LEN];
00157
00158 if (! srh->valid()) {
00159 len = 0;
00160 cur_index = 0;
00161 return;
00162 }
00163
00164 len = srh->num_addrs();
00165 cur_index = srh->cur_addr();
00166
00167 assert(len <= MAX_SR_LEN);
00168
00169 for (int i = 0 ; i < len ; i++)
00170 path[i] = ID(srh->addrs()[i]);
00171 }
00172
00173 void
00174 Path::fillSR(struct hdr_sr *srh)
00175 {
00176 for (int i = 0 ; i < len ; i++)
00177 {
00178 path[i].fillSRAddr(srh->addrs()[i]);
00179 }
00180 srh->num_addrs() = len;
00181 srh->cur_addr() = cur_index;
00182 }
00183
00184 Path::Path(const Path& old)
00185 {
00186 path = new ID[MAX_SR_LEN];
00187 if (old.path != NULL)
00188 {
00189 for (int c = 0; c < old.len; c++)
00190 path[c] = old.path[c];
00191 len = old.len;
00192 }
00193 else
00194 {
00195 len = 0;
00196 }
00197 cur_index = old.cur_index;
00198 path_owner = old.path_owner;
00199 }
00200
00201 Path::~Path()
00202 {
00203 delete[] path;
00204 }
00205
00206 void
00207 Path::operator=(const Path &rhs)
00208
00209
00210
00211 {
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226 if (this != &rhs)
00227 {
00228 cur_index = rhs.cur_index;
00229 path_owner = rhs.path_owner;
00230 len = rhs.len;
00231 for (int c = 0 ; c < len ; c++)
00232 path[c] = rhs.path[c];
00233 }
00234
00235
00236
00237 }
00238
00239 bool
00240 Path::operator==(const Path &rhs)
00241 {
00242 int c;
00243 if (len != rhs.len) return false;
00244 for (c = 0; c < len; c++)
00245 if (path[c] != rhs.path[c]) return false;
00246 return true;
00247 }
00248
00249 void
00250 Path::appendPath(Path& p)
00251 {
00252 int i;
00253 for (i = 0; i < p.length() ; i++)
00254 {
00255 path[len] = p[i];
00256 len++;
00257 if (len > MAX_SR_LEN)
00258 {
00259 fprintf(stderr,"DFU: overflow in appendPath len2 %d\n",
00260 p.length());
00261 len--;
00262 return;
00263 }
00264 }
00265 }
00266
00267 void
00268 Path::removeSection(int from, int to)
00269
00270 {
00271 int i,j;
00272
00273 if (to <= from) return;
00274 if (cur_index > from) cur_index = cur_index - (to - from);
00275 for (i = to, j = 0; i < len ; i++, j++)
00276 path[from + j] = path[i];
00277 len = from + j;
00278 }
00279
00280 Path
00281 Path::copy() const
00282 {
00283 Path p(len,path);
00284 p.cur_index = cur_index;
00285 p.path_owner = path_owner;
00286 return p;
00287 }
00288
00289 void
00290 Path::copyInto(Path& to) const
00291 {
00292 to.cur_index = cur_index;
00293 to.len = len;
00294 for (int c = 0 ; c < len ; c++)
00295 to.path[c] = path[c];
00296 to.path_owner = path_owner;
00297 }
00298
00299 Path
00300 Path::reverse() const
00301
00302
00303 {
00304 if (len == 0) return *this;
00305 Path p;
00306
00307 int from, to;
00308 for (from = 0, to = (len-1) ; from < len ; from++,to--)
00309 p.path[to] = path[from];
00310 p.len = len;
00311 p.cur_index = (len - 1) - cur_index;
00312 return p;
00313 }
00314
00315 void
00316 Path::reverseInPlace()
00317 {
00318 if (len == 0) return;
00319 int fp,bp;
00320 ID temp;
00321 for (fp = 0, bp = (len-1) ; fp < bp ; fp++, bp--)
00322 {
00323 temp = path[fp];
00324 path[fp] = path[bp];
00325 path[bp] = temp;
00326 }
00327 cur_index = (len - 1) - cur_index;
00328 }
00329
00330 int
00331 Path::size() const
00332 {
00333
00334 return len*4;
00335 }
00336
00337 bool
00338 Path::member(const ID& id) const
00339
00340 {
00341 return member(id, invalid_addr);
00342 }
00343
00344 bool
00345 Path::member(const ID& id, const ID& MAC_id) const
00346
00347 {
00348 for (int c = 0; c < len ; c++)
00349 if (path[c] == id || path[c] == MAC_id)
00350 return true;
00351 return false;
00352 }
00353
00354 void
00355 Path::unparse(FILE *out) const
00356 {
00357
00358 if (len==0)
00359 {
00360 fprintf(out,"<empty path>");
00361 return;
00362 }
00363 for (int c = 0 ; c < len-1 ; c ++)
00364 {
00365 if (c == cur_index) fprintf(out,"(");
00366 path[c].unparse(out);
00367 if (c == cur_index) fprintf(out,")");
00368 fprintf(out,",");
00369 }
00370 if (len-1 == cur_index) fprintf(out,"(");
00371 path[len-1].unparse(out);
00372 if (len-1 == cur_index) fprintf(out,")");
00373 }
00374
00375 char *
00376 Path::dump() const
00377 {
00378 static int which = 0;
00379 static char buf[4][100];
00380 char *ptr = buf[which];
00381 char *rtn_buf = ptr;
00382 which = (which + 1) % 4;
00383
00384 if (len == 0)
00385 {
00386 sprintf(rtn_buf,"[<empty path>]");
00387 return rtn_buf;
00388 }
00389 *ptr++ = '[';
00390 for (int c = 0 ; c < len ; c ++)
00391 {
00392 if (c == cur_index) *ptr++ = '(';
00393 ptr += sprintf(ptr,"%s%s ",path[c].dump(), c == cur_index ? ")" : "");
00394 }
00395 *ptr++ = ']';
00396 *ptr++ = '\0';
00397 return rtn_buf;
00398 }
00399
00400 void
00401 compressPath(Path &path)
00402
00403
00404 {
00405
00406
00407
00408
00409
00410
00411
00412 int fp = 0, bp;
00413 while (fp < path.len)
00414 {
00415 for (bp = path.len - 1; bp != fp; bp--)
00416 {
00417 if (path.path[fp] == path.path[bp])
00418 { int from, to;
00419 for (from = bp, to = fp;
00420 from < path.len ;
00421 from++, to++)
00422 path.path[to] = path.path[from];
00423 path.len = to;
00424 break;
00425 }
00426 }
00427 fp++;
00428 }
00429 }
00430
00431 void
00432 CopyIntoPath(Path& to, const Path& from, int start, int stop)
00433
00434 {
00435 assert(start >= 0 && stop < from.len);
00436 int f, t,c ;
00437 for(f = start, t = 0; f <= stop; f++, t++)
00438 to.path[t] = from.path[f];
00439 if (to.len < stop - start + 1) to.len = stop - start + 1;
00440 for (c = to.len - 1; c >= 0; c--)
00441 {
00442 if (to.path[c] == to.owner()) break;
00443 if (to.path[c] == ((Path &)from).owner())
00444 {
00445 to.owner() = ((Path &)from).owner();
00446 break;
00447 }
00448 }
00449 }
00450
00451 void
00452 Path::checkpath() const
00453 {
00454 for(int c = 0; c < MAX_SR_LEN; c++)
00455 {
00456 assert(path[c].type == NONE ||
00457 path[c].type == MAC ||
00458 path[c].type == IP);
00459 }
00460 }