1. /*
  2. * @(#)file NetMaskImpl.java
  3. * @(#)author Sun Microsystems, Inc.
  4. * @(#)version 1.6
  5. * @(#)date 04/09/15
  6. *
  7. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  8. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  9. *
  10. */
  11. package com.sun.jmx.snmp.IPAcl;
  12. import java.util.Vector;
  13. import java.util.Enumeration;
  14. import java.io.Serializable;
  15. import java.net.UnknownHostException;
  16. import java.net.InetAddress;
  17. import java.security.Principal;
  18. import java.security.acl.Group;
  19. import com.sun.jmx.trace.Trace;
  20. /**
  21. * This class is used to represent a subnet mask (a group of hosts matching the same
  22. * IP mask).
  23. *
  24. * @see java.security.acl.Group
  25. * @version 4.5 02/03/00
  26. * @author Sun Microsystems, Inc
  27. */
  28. class NetMaskImpl extends PrincipalImpl implements Group, Serializable {
  29. protected byte[] subnet = null;
  30. protected int prefix = -1;
  31. /**
  32. * Constructs an empty group.
  33. * @exception UnknownHostException Not implemented
  34. */
  35. public NetMaskImpl () throws UnknownHostException {
  36. }
  37. private byte[] extractSubNet(byte[] b) {
  38. int addrLength = b.length;
  39. byte[] subnet = null;
  40. if(isDebugOn()) {
  41. debug("extractSubNet","BINARY ARRAY :");
  42. StringBuffer buff = new StringBuffer();
  43. for(int i =0; i < addrLength; i++) {
  44. buff.append((int)(b[i] &0xFF) +":");
  45. }
  46. debug("extractSubNet", buff.toString());
  47. }
  48. // 8 is a byte size. Common to any InetAddress (V4 or V6).
  49. int fullyCoveredByte = prefix / 8;
  50. if(fullyCoveredByte == addrLength) {
  51. if(isDebugOn()) {
  52. debug("extractSubNet"," The mask is the complete address, strange..." + addrLength);
  53. }
  54. subnet = b;
  55. return subnet;
  56. }
  57. if(fullyCoveredByte > addrLength) {
  58. if(isDebugOn()) {
  59. debug("extractSubNet"," The number of covered byte is longer than the address. BUG");
  60. }
  61. throw new IllegalArgumentException("The number of covered byte is longer than the address.");
  62. }
  63. int partialyCoveredIndex = fullyCoveredByte;
  64. if(isDebugOn()) {
  65. debug("extractSubNet"," Partialy covered index : " + partialyCoveredIndex);
  66. }
  67. byte toDeal = b[partialyCoveredIndex];
  68. if(isDebugOn()) {
  69. debug("extractSubNet"," Partialy covered byte : " + toDeal);
  70. }
  71. // 8 is a byte size. Common to any InetAddress (V4 or V6).
  72. int nbbits = prefix % 8;
  73. int subnetSize = 0;
  74. if(nbbits == 0)
  75. subnetSize = partialyCoveredIndex;
  76. else
  77. subnetSize = partialyCoveredIndex + 1;
  78. if(isDebugOn()) {
  79. debug("extractSubNet"," Remains : " + nbbits);
  80. }
  81. byte mask = 0;
  82. for(int i = 0; i < nbbits; i++) {
  83. mask |= (1 << (7 - i));
  84. }
  85. if(isDebugOn()) {
  86. debug("extractSubNet","Mask value" + (int) (mask & 0xFF));
  87. }
  88. byte maskedValue = (byte) ((int)toDeal & (int)mask);
  89. if(isDebugOn()) {
  90. debug("extractSubNet","Masked byte :" + (int) (maskedValue &0xFF));
  91. }
  92. subnet = new byte[subnetSize];
  93. if(isDebugOn()) {
  94. debug("extractSubNet","Resulting subnet : ");
  95. }
  96. for(int i = 0; i < partialyCoveredIndex; i++) {
  97. subnet[i] = b[i];
  98. if(isDebugOn()) {
  99. debug("extractSubNet",(int) (subnet[i] & 0xFF) +":");
  100. }
  101. }
  102. if(nbbits != 0) {
  103. subnet[partialyCoveredIndex] = maskedValue;
  104. if(isDebugOn()) {
  105. debug("extractSubNet"," Last subnet byte : " + (int) (subnet[partialyCoveredIndex] &0xFF));
  106. }
  107. }
  108. return subnet;
  109. }
  110. /**
  111. * Constructs a group using the specified subnet mask.
  112. * THIS ALGORITHM IS V4 and V6 compatible.
  113. *
  114. * @exception UnknownHostException if the subnet mask cann't be built.
  115. */
  116. public NetMaskImpl (String a, int prefix) throws UnknownHostException {
  117. super(a);
  118. this.prefix = prefix;
  119. subnet = extractSubNet(getAddress().getAddress());
  120. }
  121. /**
  122. * Adds the specified member to the group.
  123. *
  124. * @param p the principal to add to this group.
  125. * @return true if the member was successfully added, false if the
  126. * principal was already a member.
  127. */
  128. public boolean addMember(Principal p) {
  129. // we don't need to add members because the ip address is a subnet mask
  130. return true;
  131. }
  132. public int hashCode() {
  133. return super.hashCode();
  134. }
  135. /**
  136. * Compares this group to the specified object. Returns true if the object
  137. * passed in matches the group represented.
  138. *
  139. * @param p the object to compare with.
  140. * @return true if the object passed in matches the subnet mask,
  141. * false otherwise.
  142. */
  143. public boolean equals (Object p) {
  144. if (p instanceof PrincipalImpl || p instanceof NetMaskImpl){
  145. PrincipalImpl received = (PrincipalImpl) p;
  146. InetAddress addr = received.getAddress();
  147. if(isDebugOn()) {
  148. debug("equals","Received Address : " + addr);
  149. }
  150. byte[] recAddr = addr.getAddress();
  151. for(int i = 0; i < subnet.length; i++) {
  152. if(isDebugOn()) {
  153. debug("equals","(recAddr[i]) :" + (recAddr[i] & 0xFF));
  154. debug("equals","(recAddr[i] & subnet[i]) :" +
  155. ( (int) (recAddr[i] & (int)subnet[i]) &0xFF) +
  156. "subnet[i] :" + (int) (subnet[i] &0xFF));
  157. }
  158. if((recAddr[i] & subnet[i]) != subnet[i]) {
  159. if(isDebugOn()) {
  160. debug("equals","FALSE");
  161. }
  162. return false;
  163. }
  164. }
  165. if(isDebugOn()) {
  166. debug("equals","TRUE");
  167. }
  168. return true;
  169. } else
  170. return false;
  171. }
  172. /**
  173. * Returns true if the passed principal is a member of the group.
  174. *
  175. * @param p the principal whose membership is to be checked.
  176. * @return true if the principal is a member of this group, false otherwise.
  177. */
  178. public boolean isMember(Principal p) {
  179. if ((p.hashCode() & super.hashCode()) == p.hashCode()) return true;
  180. else return false;
  181. }
  182. /**
  183. * Returns an enumeration which contains the subnet mask.
  184. *
  185. * @return an enumeration which contains the subnet mask.
  186. */
  187. public Enumeration members(){
  188. Vector v = new Vector(1);
  189. v.addElement(this);
  190. return v.elements();
  191. }
  192. /**
  193. * Removes the specified member from the group. (Not implemented)
  194. *
  195. * @param p the principal to remove from this group.
  196. * @return allways return true.
  197. */
  198. public boolean removeMember(Principal p) {
  199. return true;
  200. }
  201. /**
  202. * Prints a string representation of this group.
  203. *
  204. * @return a string representation of this group.
  205. */
  206. public String toString() {
  207. return ("NetMaskImpl :"+ super.getAddress().toString() + "/" + prefix);
  208. }
  209. // TRACES & DEBUG
  210. //---------------
  211. boolean isTraceOn() {
  212. return Trace.isSelected(Trace.LEVEL_TRACE, Trace.INFO_SNMP);
  213. }
  214. void trace(String clz, String func, String info) {
  215. Trace.send(Trace.LEVEL_TRACE, Trace.INFO_SNMP, clz, func, info);
  216. }
  217. void trace(String func, String info) {
  218. trace(dbgTag, func, info);
  219. }
  220. boolean isDebugOn() {
  221. return Trace.isSelected(Trace.LEVEL_DEBUG, Trace.INFO_SNMP);
  222. }
  223. void debug(String clz, String func, String info) {
  224. Trace.send(Trace.LEVEL_DEBUG, Trace.INFO_SNMP, clz, func, info);
  225. }
  226. void debug(String clz, String func, Throwable exception) {
  227. Trace.send(Trace.LEVEL_DEBUG, Trace.INFO_SNMP, clz, func, exception);
  228. }
  229. void debug(String func, String info) {
  230. debug(dbgTag, func, info);
  231. }
  232. void debug(String func, Throwable exception) {
  233. debug(dbgTag, func, exception);
  234. }
  235. String dbgTag = "NetMaskImpl";
  236. }