Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

257 lines
5.6 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) Microsoft Corporation
  4. //
  5. // SYNOPSIS
  6. //
  7. // Defines
  8. //
  9. ///////////////////////////////////////////////////////////////////////////////
  10. #include "radcommon.h"
  11. #include "clientstrie.h"
  12. #include <iomanip>
  13. SubNet::SubNet(uint32_t ipAddress, uint32_t width) throw ()
  14. : address(ipAddress)
  15. {
  16. if (width == 0)
  17. {
  18. subNetMask = 0;
  19. firstUniqueBitMask = 0x80000000;
  20. }
  21. else if (width == 32)
  22. {
  23. subNetMask = 0xffffffff;
  24. firstUniqueBitMask = 0;
  25. }
  26. else
  27. {
  28. subNetMask = 0xffffffff;
  29. subNetMask >>= (32 - width);
  30. subNetMask <<= (32 - width);
  31. firstUniqueBitMask = 0x80000000;
  32. firstUniqueBitMask >>= width;
  33. }
  34. address &= subNetMask;
  35. }
  36. SubNet SubNet::SmallestContainingSubNet(const SubNet& subnet) const throw ()
  37. {
  38. // Find the most significant bit where the addresses differ.
  39. uint32_t width = 0;
  40. for (uint32_t mask = 0x80000000;
  41. (mask != 0) && (subnet.address & mask) == (address & mask);
  42. (mask >>= 1), (++width))
  43. {
  44. }
  45. return SubNet(address, width);
  46. }
  47. ClientNodePtr& ClientNodePtr::operator=(ClientNodePtr& rhs) throw ()
  48. {
  49. if (p != rhs.p)
  50. {
  51. delete p;
  52. p = rhs.p;
  53. rhs.p = 0;
  54. }
  55. return *this;
  56. }
  57. ClientNode::Relationship ClientNode::RelationshipTo(
  58. const ClientNode& node
  59. ) const throw ()
  60. {
  61. if (key == node.key)
  62. {
  63. return self;
  64. }
  65. else if (key.Contains(node.key))
  66. {
  67. return parent;
  68. }
  69. else if (node.key.Contains(key))
  70. {
  71. return child;
  72. }
  73. else
  74. {
  75. return brother;
  76. }
  77. }
  78. void ClientNode::SetChild(ClientNodePtr& node) throw ()
  79. {
  80. // assert(node.get() != 0);
  81. WhichBranch(*node) = node;
  82. }
  83. inline ClientNode::ClientNode(
  84. const SubNet& subnet,
  85. IIasClient* client
  86. ) throw ()
  87. : key(subnet), value(client)
  88. {
  89. }
  90. ClientNodePtr ClientNode::CreateInstance(
  91. const SubNet& subnet,
  92. IIasClient* client
  93. ) throw ()
  94. {
  95. return ClientNodePtr(new ClientNode(subnet, client));
  96. }
  97. void ClientNode::Write(
  98. const ClientNodePtr& branch,
  99. std::ostream& output,
  100. size_t startingIndent
  101. )
  102. {
  103. for (size_t i = 0; i < startingIndent; ++i)
  104. {
  105. output.put(' ');
  106. }
  107. if (branch.get() != 0)
  108. {
  109. output << branch->Key()
  110. << ((branch->Value() != 0) ? " <value>\n" : " <null>\n");
  111. Write(branch->zero, output, startingIndent + 2);
  112. Write(branch->one, output, startingIndent + 2);
  113. }
  114. else
  115. {
  116. output << "<null>\n";
  117. }
  118. }
  119. ClientNode::~ClientNode() throw ()
  120. {
  121. }
  122. IIasClient* ClientTrie::Find(uint32_t ipAddress) const throw ()
  123. {
  124. IIasClient* bestMatch = 0;
  125. for (const ClientNode* n = root.get();
  126. n != 0 && n->Key().HasMember(ipAddress);
  127. n = n->WhichChild(ipAddress))
  128. {
  129. if (n->Value() != 0)
  130. {
  131. // As we walk down the tree, we are finding longer and longer matches,
  132. // so the last one we find is the best.
  133. bestMatch = n->Value();
  134. }
  135. }
  136. return bestMatch;
  137. }
  138. void ClientTrie::Insert(const SubNet& subnet, IIasClient* client)
  139. {
  140. Insert(root, ClientNode::CreateInstance(subnet, client));
  141. }
  142. void ClientTrie::Write(std::ostream& output) const
  143. {
  144. ClientNode::Write(root, output);
  145. }
  146. void ClientTrie::Insert(ClientNodePtr& node, ClientNodePtr& newEntry)
  147. {
  148. if (node.get() == 0)
  149. {
  150. // We made it to the end of the branch, so we're a leaf.
  151. node = newEntry;
  152. }
  153. else
  154. {
  155. switch (node->RelationshipTo(*newEntry))
  156. {
  157. case ClientNode::parent:
  158. {
  159. // This is an ancestor of ours, so keep walking.
  160. Insert(node->WhichBranch(*newEntry), newEntry);
  161. break;
  162. }
  163. case ClientNode::child:
  164. {
  165. // This is our child, ...
  166. newEntry->SetChild(node);
  167. // ... so we take its place in the tree.
  168. node = newEntry;
  169. break;
  170. }
  171. case ClientNode::brother:
  172. {
  173. // We found a brother, so our parent is missing.
  174. ClientNodePtr parent(node->CreateParent(*newEntry));
  175. parent->SetChild(node);
  176. parent->SetChild(newEntry);
  177. node = parent;
  178. break;
  179. }
  180. case ClientNode::self:
  181. {
  182. if (node->Value() == 0)
  183. {
  184. node->SetValue(newEntry->Value());
  185. }
  186. // Otherwise, this is a duplicate entry. We do nothing so that the
  187. // first entry in the UI will take precedence.
  188. break;
  189. }
  190. default:
  191. // assert(false);
  192. break;
  193. }
  194. }
  195. }
  196. std::ostream& operator<<(std::ostream& output, const SubNet& subnet)
  197. {
  198. output << std::hex
  199. << std::setfill('0')
  200. << std::setiosflags(std::ios_base::right)
  201. << std::setw(8)
  202. << subnet.IpAddress()
  203. << ':'
  204. << std::setw(8)
  205. << subnet.SubNetMask();
  206. return output;
  207. }
  208. std::ostream& operator<<(std::ostream& output, const ClientTrie& tree)
  209. {
  210. tree.Write(output);
  211. return output;
  212. }