001 /*
002 * Copyright 2010 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016 package com.hs.mail.util;
017
018 import java.net.InetAddress;
019 import java.util.ArrayList;
020 import java.util.List;
021 import java.util.StringTokenizer;
022
023 public class InetAddressMatcher {
024
025 private List<Integer> addresses = new ArrayList<Integer>();
026 private List<Integer> netmasks = new ArrayList<Integer>();
027
028 public InetAddressMatcher(String networks) {
029 StringTokenizer st = new StringTokenizer(networks, ", ");
030 while (st.hasMoreElements()) {
031 String s = st.nextToken().trim();
032 int i = s.indexOf('/');
033 if (i != -1) {
034 addresses.add(toByte(s.substring(0, i)));
035 String mask = s.substring(i + 1);
036 if (mask.indexOf('.') == -1) {
037 int nm = Integer.parseInt(mask);
038 netmasks.add((nm == 0) ? 0 : 0xffffffff << (32 - nm));
039 } else {
040 netmasks.add(toByte(mask));
041 }
042 } else {
043 addresses.add(toByte(s));
044 netmasks.add(0xffffffff);
045 }
046 }
047 }
048
049 public static int toByte(String address) {
050 StringTokenizer st = new StringTokenizer(address, ".");
051 int bytes = Integer.parseInt(st.nextToken()) << 24
052 | Integer.parseInt(st.nextToken()) << 16
053 | Integer.parseInt(st.nextToken()) << 8
054 | Integer.parseInt(st.nextToken());
055 return bytes;
056 }
057
058 public boolean matches(InetAddress address) {
059 int ipaddr = toByte(address.getHostAddress());
060 for (int i = 0; i < addresses.size(); i++) {
061 int nm = netmasks.get(i);
062 if ((ipaddr & nm) == (addresses.get(i) & nm)) {
063 return true;
064 }
065 }
066 return false;
067 }
068
069 public static boolean matches(String networks, InetAddress address) {
070 return new InetAddressMatcher(networks).matches(address);
071 }
072
073 private String toString(int addr) {
074 StringBuffer sb = new StringBuffer();
075 for (int i = 0; i < 4; i++) {
076 int x = addr >>> 24;
077 addr = addr << 8;
078 if (i != 0)
079 sb.append('.');
080 sb.append(x);
081 }
082 return sb.toString();
083 }
084
085 private String toString(int address, int netmask) {
086 if (netmask == -1)
087 return toString(address);
088 else
089 return toString(address) + '/' + toString(netmask);
090 }
091
092 public String toString() {
093 StringBuilder sb = new StringBuilder();
094 for (int i = 0; i < addresses.size(); i++) {
095 if (i != 0)
096 sb.append(' ');
097 sb.append(toString(addresses.get(i), netmasks.get(i)));
098 }
099 return sb.toString();
100 }
101
102 }