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

通讯编程

开发平台:

Visual C++

  1. /* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
  2. /*
  3.  * Copyright (c) 1996-1997 Regents of the University of California.
  4.  * All rights reserved.
  5.  * 
  6.  * Redistribution and use in source and binary forms, with or without
  7.  * modification, are permitted provided that the following conditions
  8.  * are met:
  9.  * 1. Redistributions of source code must retain the above copyright
  10.  *    notice, this list of conditions and the following disclaimer.
  11.  * 2. Redistributions in binary form must reproduce the above copyright
  12.  *    notice, this list of conditions and the following disclaimer in the
  13.  *    documentation and/or other materials provided with the distribution.
  14.  * 3. All advertising materials mentioning features or use of this software
  15.  *    must display the following acknowledgement:
  16.  *  This product includes software developed by the MASH Research
  17.  *  Group at the University of California Berkeley.
  18.  * 4. Neither the name of the University nor of the Research Group may be
  19.  *    used to endorse or promote products derived from this software without
  20.  *    specific prior written permission.
  21.  * 
  22.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  23.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  24.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  25.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  26.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  27.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  28.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  29.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  30.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  31.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  32.  * SUCH DAMAGE.
  33.  */
  34. #ifndef lint
  35. static const char rcsid[] =
  36.     "@(#) $Header: /cvsroot/nsnam/ns-2/classifier/classifier-mcast.cc,v 1.32 2005/09/26 07:38:08 lacage Exp $";
  37. #endif
  38. #include <stdlib.h>
  39. #include "config.h"
  40. #include "packet.h"
  41. #include "ip.h"
  42. #include "classifier.h"
  43. #include "classifier-mcast.h"
  44. const char MCastClassifier::STARSYM[]= "x"; //"source" field for shared trees
  45. static class MCastClassifierClass : public TclClass {
  46. public:
  47. MCastClassifierClass() : TclClass("Classifier/Multicast") {}
  48. TclObject* create(int, const char*const*) {
  49. return (new MCastClassifier());
  50. }
  51. } class_mcast_classifier;
  52. MCastClassifier::MCastClassifier()
  53. {
  54. memset(ht_, 0, sizeof(ht_));
  55. memset(ht_star_, 0, sizeof(ht_star_));
  56. }
  57. MCastClassifier::~MCastClassifier()
  58. {
  59. clearAll();
  60. }
  61. void MCastClassifier::clearHash(hashnode* h[], int size) 
  62. {
  63. for (int i = 0; i < size; ++i) {
  64. hashnode* p = h[i];
  65. while (p != 0) {
  66. hashnode* n = p->next;
  67. delete p;
  68. p = n;
  69. }
  70. }
  71. memset(h, 0, size * sizeof(hashnode*));
  72. }
  73. void MCastClassifier::clearAll()
  74. {
  75. clearHash(ht_, HASHSIZE);
  76. clearHash(ht_star_, HASHSIZE);
  77. }
  78. MCastClassifier::hashnode*
  79. MCastClassifier::lookup(nsaddr_t src, nsaddr_t dst, int iface) const
  80. {
  81. int h = hash(src, dst);
  82. hashnode* p;
  83. for (p = ht_[h]; p != 0; p = p->next) {
  84. if (p->src == src && p->dst == dst)
  85.   if (p->iif == iface ||
  86.       //p->iif == UNKN_IFACE.value() ||
  87.       iface == ANY_IFACE.value())
  88. break;
  89. }
  90. return (p);
  91. }
  92. MCastClassifier::hashnode*
  93. MCastClassifier::lookup_star(nsaddr_t dst, int iface) const
  94. {
  95. int h = hash(0, dst);
  96. hashnode* p;
  97. for (p = ht_star_[h]; p != 0; p = p->next) {
  98. if (p->dst == dst && 
  99.     (iface == ANY_IFACE.value() || p->iif == iface))
  100.           break;
  101.    }
  102. return (p);
  103. }
  104. int MCastClassifier::classify(Packet *pkt)
  105. {
  106. hdr_cmn* h = hdr_cmn::access(pkt);
  107. hdr_ip* ih = hdr_ip::access(pkt);
  108. nsaddr_t src = ih->saddr();
  109. nsaddr_t dst = ih->daddr();
  110. int iface = h->iface();
  111. Tcl& tcl = Tcl::instance();
  112. hashnode* p = lookup(src, dst, iface);
  113. //printf("%s, src %d, dst %d, iface %d, p %dn", name(), src, dst, iface, p);
  114.   if (p == 0)
  115.           p = lookup_star(dst, iface);
  116. if (p == 0) {
  117. if ((p = lookup(src, dst)) == 0)
  118. p = lookup_star(dst);
  119. if (p == 0) {
  120.    // Didn't find an entry.
  121. tcl.evalf("%s new-group %d %d %d cache-miss", 
  122.   name(), src, dst, iface);
  123. // XXX see McastProto.tcl for the return values 0 -
  124. // once, 1 - twice 
  125. //printf("cache-miss result= %sn", tcl.result());
  126. int res= atoi(tcl.result());
  127. return (res)? Classifier::TWICE : Classifier::ONCE;
  128. }
  129. if (p->iif == ANY_IFACE.value()) // || iface == UNKN_IFACE.value())
  130. return p->slot;
  131. tcl.evalf("%s new-group %d %d %d wrong-iif", 
  132.   name(), src, dst, iface);
  133. //printf("wrong-iif result= %sn", tcl.result());
  134. int res= atoi(tcl.result());
  135. return (res)? Classifier::TWICE : Classifier::ONCE;
  136. }
  137. return p->slot;
  138. }
  139. int MCastClassifier::findslot()
  140. {
  141. int i;
  142. for (i = 0; i < nslot_; ++i)
  143. if (slot_[i] == 0)
  144. break;
  145. return (i);
  146. }
  147. void MCastClassifier::set_hash(hashnode* ht[], nsaddr_t src, nsaddr_t dst,
  148.        int slot, int iface)
  149. {
  150. int h = hash(src, dst);
  151. hashnode* p = new hashnode;
  152. p->src = src;
  153. p->dst = dst;
  154. p->slot = slot;
  155. p->iif = iface;
  156. p->next = ht[h];
  157. ht[h] = p;
  158. }
  159. int MCastClassifier::command(int argc, const char*const* argv)
  160. {
  161. if (argc == 6) {
  162. if (strcmp(argv[1], "set-hash") == 0) {
  163. // $classifier set-hash $src $group $slot $iif
  164. //      $iif can be:(1) <number>
  165. //                  (2) "*" - matches any interface
  166. //                  (3) "?" - interface is unknown (usually this means that
  167. //        the packet came from a local agent)
  168. nsaddr_t src = strtol(argv[2], (char**)0, 0);
  169. nsaddr_t dst = strtol(argv[3], (char**)0, 0);
  170. int slot = atoi(argv[4]);
  171.                         int iface = (strcmp(argv[5], ANY_IFACE.name())==0) ? ANY_IFACE.value() 
  172. : (strcmp(argv[5], UNKN_IFACE.name())==0) ? UNKN_IFACE.value() 
  173. : atoi(argv[5]); 
  174. if (strcmp(STARSYM, argv[2]) == 0) {
  175.     // install a <x,G> entry: give 0 as src, but can be anything
  176.     set_hash(ht_star_, 0, dst, slot, iface);
  177. } else {
  178.     //install a <S,G> entry
  179.     set_hash(ht_, src, dst, slot, iface);
  180. }
  181. return (TCL_OK);
  182. }
  183. if (strcmp(argv[1], "change-iface") == 0) {
  184. // $classifier change-iface $src $dst $olfiif $newiif
  185. nsaddr_t src = strtol(argv[2], (char**)0, 0);
  186. nsaddr_t dst = strtol(argv[3], (char**)0, 0);
  187. int oldiface = atoi(argv[4]);
  188. int newiface = atoi(argv[5]);
  189. if (strcmp(STARSYM, argv[2]) == 0) {
  190. change_iface(dst, oldiface, newiface);
  191. } else {
  192. change_iface(src, dst, oldiface, newiface);
  193. }
  194. return (TCL_OK);
  195. }
  196. } else if (argc == 5) {
  197. if (strcmp(argv[1], "lookup") == 0) {
  198. // $classifier lookup $src $group $iface
  199. // returns name of the object (replicator)
  200. Tcl &tcl = Tcl::instance();
  201. nsaddr_t src = strtol(argv[2], (char**)0, 0);
  202. nsaddr_t dst = strtol(argv[3], (char**)0, 0);
  203. int iface = atoi(argv[4]);
  204. hashnode* p= (strcmp(STARSYM, argv[2]) == 0) ? lookup_star(dst, iface)
  205. : lookup(src, dst, iface);
  206. if ((p == 0) || (slot_[p->slot] == 0))
  207. tcl.resultf("");
  208. else 
  209. tcl.resultf("%s", slot_[p->slot]->name());
  210. return (TCL_OK);
  211. }
  212. } else if (argc == 4) {
  213. if (strcmp(argv[1], "lookup-iface") == 0) {
  214. // $classifier lookup-iface $src $group 
  215. // returns incoming iface
  216. Tcl &tcl = Tcl::instance();
  217. nsaddr_t src = strtol(argv[2], (char**)0, 0);
  218. nsaddr_t dst = strtol(argv[3], (char**)0, 0);
  219. hashnode* p= (strcmp(argv[2], STARSYM) == 0) ? lookup_star(dst)
  220. : lookup(src, dst);
  221. if (p == 0)
  222. tcl.resultf("");
  223. else 
  224. tcl.resultf("%d", p->iif);
  225. return (TCL_OK);
  226. }
  227. } else if (argc == 2) {
  228. if (strcmp(argv[1], "clearAll") == 0) {
  229. clearAll();
  230. return (TCL_OK);
  231. }
  232. }
  233. return (Classifier::command(argc, argv));
  234. }
  235. /* interface look up for the interface code*/
  236. void MCastClassifier::change_iface(nsaddr_t src, nsaddr_t dst, int oldiface, int newiface)
  237. {
  238. hashnode* p = lookup(src, dst, oldiface);
  239. if (p) p->iif = newiface;
  240. }
  241. void MCastClassifier::change_iface(nsaddr_t dst, int oldiface, int newiface)
  242. {
  243. hashnode* p = lookup_star(dst, oldiface);
  244. if (p) p->iif = newiface;
  245. }