package net.websoup.wormscan; /* * This file is part of WormScan. * * WormScan is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ import java.util.Arrays; import java.util.Comparator; import java.util.Date; import java.util.Collection; import net.websoup.wormscan.AttackSource; /** * Sort Attacks by specified parameters * Copyright: Copyright (c) 2001-2004 Andriy Rozeluk * @author Andriy Rozeluk * @version 1.6.1 */ public class Sorter extends Thread { private boolean finished = false; private Object[] results; private Collection source; private Comparator compare; private String sortMethodName; /** * Sort by IP address of attacking host */ public static final Comparator SORT_IP = new Comparator() { public int compare( Object a, Object b ){ if ( a instanceof Attack && b instanceof Attack ){ long ip1 = ((Attack)a).getSourceOfAttack().getIntegerIP(); long ip2 = ((Attack)b).getSourceOfAttack().getIntegerIP(); if ( ip1 < 0 && ip2 > 0 ){ return 1; } else if ( ip1 > 0 && ip2 < 0 ){ return -1; } else if ( ip1 < 0 && ip2 < 0 ){ boolean unres1 = ((Attack)a).getSourceOfAttack().isHostnameUnresolved(); boolean unres2 = ((Attack)b).getSourceOfAttack().isHostnameUnresolved(); if ( unres1 && unres2 ){ return SORT_DATE.compare( a, b ); } else { return SORT_HOSTNAME.compare( a, b ); } } else { long c = ip1 - ip2; if ( c == 0 ){ return SORT_DATE.compare(a, b); } else if( c > 0 ){ return 1; } else{ return -1; } } } else { return 0; } } }; /** * Sort by Date of attack */ public static final Comparator SORT_DATE = new Comparator() { public int compare( Object a, Object b ){ if ( a instanceof Attack && b instanceof Attack ){ Date ip1 = ((Attack)a).getDateOfAttack(); Date ip2 = ((Attack)b).getDateOfAttack(); int c = ip1.compareTo(ip2); if ( c == 0 ){ return a.hashCode() - b.hashCode(); } return c; } else { return 0; } } }; /** * Sort by name of worm */ public static final Comparator SORT_WORM = new Comparator() { public int compare( Object a, Object b ){ if ( a instanceof Attack && b instanceof Attack ){ String ip1 = ((Attack)a).getAttackingWorm().getName(); String ip2 = ((Attack)b).getAttackingWorm().getName(); int c = ip1.compareTo(ip2); if ( c == 0 ){ return SORT_NUMATTACKS.compare( a, b ); } return c; } else { return 0; } } }; /** * Sort by number of attacks by host */ public static final Comparator SORT_NUMATTACKS = new Comparator() { public int compare( Object a, Object b ){ if ( a instanceof Attack && b instanceof Attack ){ int ip1 = ((Attack)a).getSourceOfAttack().getAttackCount(); int ip2 = ((Attack)b).getSourceOfAttack().getAttackCount(); int c = ip1 - ip2; if ( c == 0 ){ return SORT_IP.compare(a, b); } return c; } else { return 0; } } }; /** * Sort by hostname of attacker */ public static final Comparator SORT_HOSTNAME = new Comparator() { public int compare( Object a, Object b ){ if ( a instanceof Attack && b instanceof Attack ){ AttackSource source1 = ((Attack)a).getSourceOfAttack(); AttackSource source2 = ((Attack)b).getSourceOfAttack(); boolean unres1 = source1.isHostnameUnresolved(); boolean unres2 = source2.isHostnameUnresolved(); if ( unres1 || unres2 ){ if ( unres1 && source1.getIntegerIP() > 0 && unres2 && source2.getIntegerIP() > 0 ){ return SORT_IP.compare( a, b ); } else if ( unres1 && source1.getIntegerIP() > 0 ){ return 1; } else if ( unres2 && source2.getIntegerIP() > 0 ){ return -1; } } String[] ip1 = source1.getReversedHostnames(); String[] ip2 = source2.getReversedHostnames(); if ( ip1 != null && ip1.length > 0 && ip2 != null && ip2.length > 0 ){ int c = ip1[0].compareTo( ip2[0] ); if ( c == 0 ) return SORT_DATE.compare( a, b ); return c; } else if ( (ip1 == null || ip1.length <= 0) && (ip2 != null && ip2.length > 0) ){ return -1; } else if ( (ip2 == null || ip2.length <= 0) && (ip1 != null && ip1.length > 0) ){ return 1; } else { return SORT_DATE.compare( a, b ); } } else { return 0; } } }; /** * Initialize a sort thread for specified order */ public Sorter( Collection c, Comparator sortOrder, String sortMethodName ){ source = c; compare = sortOrder; this.sortMethodName = sortMethodName; } /** * Begin sorting */ public void run(){ Object[] working = source.toArray(); Arrays.sort( working, compare ); results = working; finished = true; } /** * Utility method to reverse an array. This is the easy way to get reversed * sorts. */ public static Object[] reverseArray( Object[] array ){ int len = array.length; for ( int i = 0; i < (len >> 1); i++ ){ Object temp = array[i]; array[i] = array[ len - i - 1 ]; array[ len - i - 1 ] = temp; } return array; } /** * Return the sorted array of objects, or null if we're not done sorting yet. */ public Object[] getResults(){ if ( !finished ) return null; return results; } /** * Is sorting complete yet? Maybe it's easier to just check if the Thread's * stopped executing. */ public boolean isFinished(){ return finished; } public String getSortMethodName(){ return sortMethodName; } }