path.cc
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:11k
源码类别:

通讯编程

开发平台:

Visual C++

  1. /*
  2.  * path.cc
  3.  * Copyright (C) 2000 by the University of Southern California
  4.  * $Id: path.cc,v 1.7 2005/08/25 18:58:05 johnh Exp $
  5.  *
  6.  * This program is free software; you can redistribute it and/or
  7.  * modify it under the terms of the GNU General Public License,
  8.  * version 2, as published by the Free Software Foundation.
  9.  *
  10.  * This program is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  * GNU General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU General Public License along
  16.  * with this program; if not, write to the Free Software Foundation, Inc.,
  17.  * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
  18.  *
  19.  *
  20.  * The copyright of this module includes the following
  21.  * linking-with-specific-other-licenses addition:
  22.  *
  23.  * In addition, as a special exception, the copyright holders of
  24.  * this module give you permission to combine (via static or
  25.  * dynamic linking) this module with free software programs or
  26.  * libraries that are released under the GNU LGPL and with code
  27.  * included in the standard release of ns-2 under the Apache 2.0
  28.  * license or under otherwise-compatible licenses with advertising
  29.  * requirements (or modified versions of such code, with unchanged
  30.  * license).  You may copy and distribute such a system following the
  31.  * terms of the GNU GPL for this module and the licenses of the
  32.  * other code concerned, provided that you include the source code of
  33.  * that other code when and as the GNU GPL requires distribution of
  34.  * source code.
  35.  *
  36.  * Note that people who make modified versions of this module
  37.  * are not obligated to grant this special exception for their
  38.  * modified versions; it is their choice whether to do so.  The GNU
  39.  * General Public License gives permission to release a modified
  40.  * version without this exception; this exception also makes it
  41.  * possible to release a modified version which carries forward this
  42.  * exception.
  43.  *
  44.  */
  45. //
  46. // Other copyrights might apply to parts of this software and are so
  47. // noted when applicable.
  48. //
  49. // Ported from CMU/Monarch's code, appropriate copyright applies.  
  50. /* path.cc
  51.    handles source routes
  52. */
  53. extern "C" {
  54. #include <assert.h>
  55. #include <stdio.h>
  56. }
  57. #include <packet.h>
  58. #include <ip.h>
  59. #include "hdr_sr.h"
  60. #include "path.h"
  61. /*===========================================================================
  62.   global statics
  63. ---------------------------------------------------------------------------*/
  64. ID invalid_addr(0xffffffff,::NONE);
  65. ID IP_broadcast(IP_BROADCAST,::IP);
  66. /*===========================================================================
  67.   ID methods
  68. ---------------------------------------------------------------------------*/
  69. void
  70. ID::unparse(FILE *out) const
  71. {
  72.   fprintf(out,"%d",(int) addr);
  73. }
  74. char *
  75. ID::dump() const
  76. {
  77.   static char buf[MAX_SR_LEN+1][50];
  78.   static int which = 0;
  79.   char *ptr = buf[which];
  80.   which = (which + 1) % (MAX_SR_LEN+1);
  81.   assert(type == ::NONE || type == ::MAC || type == ::IP);
  82.   if (type == ::IP)
  83.     sprintf(ptr,"%d",(int) addr);
  84.   else if (type == ::NONE)
  85.     sprintf(ptr,"NONE");
  86.   else
  87.     sprintf(ptr,"0x%x",(int) addr);
  88.   return ptr;
  89. }
  90. /*===========================================================================
  91.   Path methods
  92. ---------------------------------------------------------------------------*/
  93. /* rep invariants:
  94.    -1 <= cur_index <= len  (neither bound is really hard)
  95.    0 <= len < MAX_SR_LEN
  96. */
  97. Path::Path(int route_len, const ID *route)
  98. {
  99.   path = new ID[MAX_SR_LEN];
  100.   assert(route_len <= MAX_SR_LEN);
  101.   //  route_len = (route == NULL : 0 ? route_len); 
  102.   // a more cute solution, follow the above with the then clause
  103.   if (route != NULL)
  104.     {
  105.       for (int c = 0; c < route_len; c++)
  106.         {
  107.   path[c] = route[c];
  108.         }
  109.       len = route_len;
  110.     }
  111.   else
  112.     {
  113.       len = 0;
  114.     }
  115.   cur_index = 0;
  116. }
  117. Path::Path()
  118. {
  119.   path = new ID[MAX_SR_LEN];
  120.   len = 0;
  121.   cur_index = 0;
  122. }
  123. Path::Path(const struct sr_addr *addrs, int len)
  124. { /* make a path from the bits of an NS source route header */
  125.   assert(len <= MAX_SR_LEN);
  126.   path = new ID[MAX_SR_LEN];
  127.   for (int i = 0 ; i < len ; i++)
  128.     path[i] = ID(addrs[i]);
  129.   this->len = len;
  130.   cur_index = 0;
  131. }
  132. Path::Path(struct hdr_sr *srh)
  133. { /* make a path from the bits of an NS source route header */
  134. path = new ID[MAX_SR_LEN];
  135. if (! srh->valid()) {
  136. len = 0;
  137. cur_index = 0;
  138. return;
  139. }
  140. len = srh->num_addrs();
  141. cur_index = srh->cur_addr();
  142. assert(len <= MAX_SR_LEN);
  143. for (int i = 0 ; i < len ; i++)
  144. path[i] = ID(srh->addrs()[i]);
  145. }
  146. void
  147. Path::fillSR(struct hdr_sr *srh)
  148. {
  149.   for (int i = 0 ; i < len ; i++)
  150.     {
  151.       path[i].fillSRAddr(srh->addrs()[i]);
  152.     }
  153.   srh->num_addrs() = len;
  154.   srh->cur_addr() = cur_index;
  155. }
  156. Path::Path(const Path& old)
  157. {
  158.   path = new ID[MAX_SR_LEN];
  159.   if (old.path != NULL)
  160.     {
  161.       for (int c = 0; c < old.len; c++)
  162. path[c] = old.path[c];
  163.       len = old.len;
  164.     }
  165.   else
  166.     {
  167.       len = 0;
  168.     }
  169.   cur_index = old.cur_index;
  170.   path_owner = old.path_owner;
  171. }
  172. Path::~Path()
  173. {
  174.   delete[] path;
  175. }
  176. void
  177. Path::operator=(const Path &rhs)
  178.      // makes the lhs a copy of the rhs: lhs may share data with
  179.      // the rhs such that changes to one will be seen by the other
  180.      // use the provided copy operation if you don't want this.
  181. {
  182. /* OLD  NOTE:
  183.   we save copying the path by doing a delete[] path; path = rhs.path;
  184.    but then the following code will be fatal (it calls delete[]
  185.    twice on the same address)
  186.      { Path p1();
  187.        { Path p2();
  188.          p2 = p1;
  189.        }
  190.      }
  191.    you'd have to implement reference counts on the path array to
  192.    save copying the path.
  193.    NEW NOTE: we just copy like everything else
  194. */
  195.   if (this != &rhs)
  196.     {// beware of path = path (see Stroustrup p. 238)
  197.       cur_index = rhs.cur_index;
  198.       path_owner = rhs.path_owner;
  199.       len = rhs.len;
  200.       for (int c = 0 ; c < len ; c++)
  201. path[c] = rhs.path[c];
  202.     }
  203.   // note: i don't return *this cause I don't think assignments should
  204.   // be expressions (and it has slightly incorrect semantics: (a=b) should
  205.   // have the value of b, not the new value of a)
  206. }
  207. bool
  208. Path::operator==(const Path &rhs)
  209. {
  210.   int c;
  211.   if (len != rhs.len) return false;
  212.   for (c = 0; c < len; c++)
  213.     if (path[c] != rhs.path[c]) return false;
  214.   return true;
  215. }
  216.  
  217. void 
  218. Path::appendPath(Path& p)
  219. {
  220.   int i;
  221.   for (i = 0; i < p.length() ; i++)
  222.     {
  223.       path[len] = p[i];
  224.       len++;
  225.       if (len > MAX_SR_LEN)
  226. {
  227.   fprintf(stderr,"DFU: overflow in appendPath len2 %dn",
  228.   p.length());
  229.   len--;
  230.   return;
  231. }
  232.     }
  233. }
  234. void 
  235. Path::removeSection(int from, int to)
  236.   // the elements at indices from -> to-1 are removed from the path
  237. {
  238.   int i,j;
  239.   if (to <= from) return;
  240.   if (cur_index > from) cur_index = cur_index - (to - from);
  241.   for (i = to, j = 0; i < len ; i++, j++)
  242.     path[from + j] = path[i];
  243.   len = from + j;
  244. }
  245. Path
  246. Path::copy() const
  247. {
  248.   Path p(len,path);
  249.   p.cur_index = cur_index;
  250.   p.path_owner = path_owner;
  251.   return p;
  252. }
  253. void
  254. Path::copyInto(Path& to) const
  255. {
  256.   to.cur_index = cur_index;
  257.   to.len = len;
  258.   for (int c = 0 ; c < len ; c++)
  259.     to.path[c] = path[c];  
  260.   to.path_owner = path_owner;
  261. }
  262. Path
  263. Path::reverse() const
  264.      // return an identical path with the index pointing to the same
  265.      // host, but the path in reverse order
  266. {
  267.   if (len == 0) return *this;
  268.   Path p;
  269.   int from, to;
  270.   for (from = 0, to = (len-1) ; from < len ; from++,to--)
  271.     p.path[to] = path[from];
  272.   p.len = len;
  273.   p.cur_index = (len - 1) - cur_index;
  274.   return p;
  275. }
  276. void
  277. Path::reverseInPlace()
  278. {
  279.   if (len == 0) return;
  280.   int fp,bp;    // forward ptr, back ptr
  281.   ID temp;
  282.   for (fp = 0, bp = (len-1) ; fp < bp ; fp++, bp--)
  283.     {
  284.       temp = path[fp];
  285.       path[fp] = path[bp];
  286.       path[bp] = temp;
  287.     }
  288.   cur_index = (len - 1) - cur_index;
  289. }
  290. int
  291. Path::size() const
  292. {
  293.   // this should be more clever and ask the id's what their sizes are.
  294.   return len*4;
  295. }
  296. bool
  297. Path::member(const ID& id) const
  298. // rtn true iff id is in path
  299. {
  300.   return member(id, invalid_addr);  
  301. }
  302. bool
  303. Path::member(const ID& id, const ID& MAC_id) const
  304. // rtn true iff id or MAC_id is in path
  305. {
  306.   for (int c = 0; c < len ; c++)
  307.     if (path[c] == id || path[c] == MAC_id)
  308.       return true;
  309.   return false;
  310. }
  311. void
  312. Path::unparse(FILE *out) const
  313. {
  314.   // change to put ()'s around the cur_index entry?
  315.   if (len==0)
  316.     {
  317.       fprintf(out,"<empty path>");
  318.       return;
  319.     }
  320.   for (int c = 0 ; c < len-1 ; c ++)
  321.     {
  322.       if (c == cur_index) fprintf(out,"(");
  323.       path[c].unparse(out);
  324.       if (c == cur_index) fprintf(out,")");
  325.       fprintf(out,",");
  326.     }
  327.   if (len-1 == cur_index) fprintf(out,"(");
  328.   path[len-1].unparse(out);
  329.   if (len-1 == cur_index) fprintf(out,")");
  330. }
  331. char *
  332. Path::dump() const
  333. {
  334.   static int which = 0;
  335.   static char buf[4][100];
  336.   char *ptr = buf[which];
  337.   char *rtn_buf = ptr;
  338.   which = (which + 1) % 4;
  339.   
  340.   if (len == 0)
  341.     {
  342.       sprintf(rtn_buf,"[<empty path>]");
  343.       return rtn_buf;
  344.     }
  345.   *ptr++ = '[';
  346.   for (int c = 0 ; c < len ; c ++)
  347.     {
  348.       if (c == cur_index) *ptr++ = '(';
  349.       ptr += sprintf(ptr,"%s%s ",path[c].dump(), c == cur_index ? ")" : "");
  350.     }
  351.   *ptr++ = ']';
  352.   *ptr++ = '';
  353.   return rtn_buf;
  354. }
  355. void
  356. compressPath(Path &path)
  357. // take a path and remove any double backs from it
  358. // eg:  A B C B D --> A B D
  359. {
  360.   // idea: walk one pointer from begining
  361.   //  for each elt1 start at end of path and walk a pointer backwards (elt2)
  362.   //   if forward pointer = backward pointer, go on and walk foward one more
  363.   //   if elt1 = elt2 then append {(elt2 + 1) to end} after forward pointer
  364.   //    update length of path (we just cut out a loopback) and walk forward
  365.   //  when forward walking pointer reaches end of path we're done
  366.   int fp = 0, bp; // the forward walking ptr and the back walking ptr
  367.   while (fp < path.len)
  368.     {
  369.       for (bp = path.len - 1; bp != fp; bp--)
  370. {
  371.   if (path.path[fp] == path.path[bp])
  372.     { int from, to;
  373.       for (from = bp, to = fp;
  374.    from < path.len ;
  375.    from++, to++)
  376. path.path[to] = path.path[from];
  377.       path.len = to;
  378.       break;
  379.     } // end of removing double back
  380. } // end of scaning to check for double back
  381.       fp++; // advance the forward moving pointer
  382.     }
  383. }
  384. void 
  385. CopyIntoPath(Path& to, const Path& from, int start, int stop)
  386. // sets to[0->(stop-start)] = from[start->stop]
  387. {
  388.   assert(start >= 0 && stop < from.len);
  389.   int f, t,c ; // from and to indices
  390.   for(f = start, t = 0; f <= stop; f++, t++)
  391.     to.path[t] = from.path[f];
  392.   if (to.len < stop - start + 1) to.len = stop - start + 1;
  393.   for (c = to.len - 1; c >= 0; c--)
  394.     {
  395.       if (to.path[c] == to.owner()) break;
  396.       if (to.path[c] == ((Path &)from).owner()) 
  397. {
  398.   to.owner() = ((Path &)from).owner();
  399.   break;
  400. }
  401.     } 
  402. }
  403. void
  404. Path::checkpath() const
  405. {
  406.   for(int c = 0; c < MAX_SR_LEN; c++)
  407.     {     
  408.       assert(path[c].type == NONE ||
  409.              path[c].type == MAC ||
  410.              path[c].type == IP);
  411.     }
  412. }