赞
踩
FlowMgr类:
package cic.cs.unb.ca.flow; import cic.cs.unb.ca.Sys; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.time.LocalDate; public class FlowMgr { protected static final Logger logger = LoggerFactory.getLogger(FlowMgr.class); public static final String FLOW_SUFFIX = "_Flow.csv"; private static FlowMgr Instance = new FlowMgr(); private String mFlowSavePath; private String mDataPath; private FlowMgr() { super(); } public static FlowMgr getInstance() { return Instance; } public FlowMgr init() { String rootPath = System.getProperty("user.dir"); StringBuilder sb = new StringBuilder(rootPath); sb.append(Sys.FILE_SEP).append("data").append(Sys.FILE_SEP); mDataPath = sb.toString(); sb.append("daily").append(Sys.FILE_SEP); mFlowSavePath = sb.toString(); return Instance; } public void destroy() { } public String getSavePath() { return mFlowSavePath; } public String getmDataPath() { return mDataPath; } public String getAutoSaveFile() { String filename = LocalDate.now().toString()+FLOW_SUFFIX; return mFlowSavePath+filename; } }
ChartContainer.java类:
package cic.cs.unb.ca.flow.ui; import org.jfree.chart.ChartPanel; import org.jfree.chart.JFreeChart; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.swing.*; import java.awt.*; public class ChartContainer extends JPanel{ protected static final Logger logger = LoggerFactory.getLogger(ChartContainer.class); private static Dimension maxDim; private static Dimension minDim; private static double zoomPercentage; private static Color boxDefaultColor; private static Color focusColor; Box parentBox; Box chartBox; ChartPanel chartPane; static{ maxDim = new Dimension(ChartPanel.DEFAULT_MAXIMUM_DRAW_WIDTH*4, ChartPanel.DEFAULT_MAXIMUM_DRAW_HEIGHT*4); minDim = new Dimension(ChartPanel.DEFAULT_MINIMUM_DRAW_WIDTH, ChartPanel.DEFAULT_MINIMUM_DRAW_HEIGHT); zoomPercentage = 0.1; boxDefaultColor = Box.createHorizontalBox().getBackground(); focusColor = UIManager.getColor("Tree.selectionBackground"); } public ChartContainer(JFreeChart chart) { setLayout(new BorderLayout(0,0)); chartPane = new ChartPanel(chart); chartPane.setMaximumSize(maxDim); chartPane.setMaximumDrawWidth(maxDim.width); chartPane.setMaximumDrawHeight(maxDim.height); chartPane.setMouseWheelEnabled(true); chartPane.setMouseZoomable(true); chartPane.setFillZoomRectangle(true); add(initChartBox(chartPane), BorderLayout.CENTER); } private Box initChartBox(ChartPanel chart) { parentBox = Box.createVerticalBox(); chartBox = Box.createHorizontalBox(); //Dimension d = new Dimension(500, 500); chartBox.setPreferredSize(minDim); chartBox.setMinimumSize(minDim); chartBox.setMaximumSize(minDim); //chartBox.add(Box.createHorizontalGlue()); chartBox.add(chart); //chartBox.add(Box.createHorizontalGlue()); parentBox.add(chartBox); parentBox.add(Box.createVerticalStrut(4)); parentBox.add(new JSeparator(SwingConstants.HORIZONTAL)); parentBox.add(Box.createVerticalStrut(4)); return parentBox; } private JPanel init_btnPane(ChartPanel chart) { JPanel pane = new JPanel(); pane.setLayout(new BoxLayout(pane,BoxLayout.Y_AXIS)); JButton zoomIn = new JButton("Zoom In"); JButton zoomOut = new JButton("Zoom Out"); zoomIn.addActionListener(actionEvent -> { int w = getWidth(); int h = getHeight(); Dimension d = new Dimension(w + 10, h + 10); setPreferredSize(d); setMinimumSize(d); setMaximumSize(d); repaint(); revalidate(); }); zoomOut.addActionListener(actionEvent -> chart.restoreAutoBounds()); pane.add(Box.createVerticalGlue()); pane.add(zoomIn); pane.add(Box.createVerticalGlue()); pane.add(zoomOut); pane.add(Box.createVerticalGlue()); return pane; } public void setFocus(boolean focus) { parentBox.setOpaque(true); if (focus) { parentBox.setBackground(focusColor); } else { parentBox.setBackground(boxDefaultColor); } } public void zoomIn() { Dimension d = chartBox.getSize(); double w = d.width + d.width * zoomPercentage; double h = (w * d.height)/d.width; d.setSize(w, h); d = clipDim(d); chartBox.setPreferredSize(d); chartBox.setMinimumSize(d); chartBox.setMaximumSize(d); parentBox.setMaximumSize(d); chartBox.repaint(); chartBox.revalidate(); } public void zoomOut() { Dimension d = chartBox.getSize(); double w = d.width - d.width * zoomPercentage; double h = (w * d.height)/d.width; d.setSize(w, h); chartBox.setPreferredSize(d); chartBox.setMinimumSize(d); chartBox.setMaximumSize(d); chartBox.repaint(); chartBox.revalidate(); } public void resetSize() { chartBox.setPreferredSize(minDim); chartBox.setMinimumSize(minDim); chartBox.setMaximumSize(minDim); chartBox.repaint(); chartBox.revalidate(); } public void resetScale() { chartPane.restoreAutoBounds(); } private Dimension clipDim(Dimension dimension) { if (dimension == null) { return null; } if (dimension.width < minDim.width || dimension.height < minDim.height) { return minDim; } else if (dimension.width > maxDim.width || dimension.height > maxDim.height) { return maxDim; } else { return dimension; } } }
FlowChartInfo.java类:
package cic.cs.unb.ca.flow.ui; public class FlowChartInfo { private String name; private ChartContainer cc; public FlowChartInfo(String name, ChartContainer cc) { this.name = name; this.cc = cc; } public String getName() { return name; } public ChartContainer getCc() { return cc; } @Override public String toString() { return name; } }
FlowChartPane.java类:
package cic.cs.unb.ca.flow.ui; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.swing.*; import java.awt.*; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.ArrayList; import java.util.List; public class FlowChartPane extends JPanel{ protected static final Logger logger = LoggerFactory.getLogger(FlowChartPane.class); private JPanel chartPane; private List<ChartContainer> ccList = new ArrayList<>(); private ChartContainer focusCC = null; public FlowChartPane() { init(); setLayout(new BorderLayout(0,0)); setOpaque(true); JScrollPane jScrollPane = new JScrollPane(initBoxPane()); jScrollPane.setPreferredSize(getPreferredSize()); jScrollPane.setOpaque(true); add(jScrollPane, BorderLayout.CENTER); } private void init() { } private JPanel initBoxPane() { chartPane = new JPanel(); chartPane.setLayout(new BoxLayout(chartPane,BoxLayout.Y_AXIS)); chartPane.setOpaque(true); return chartPane; } public void addChartContainer(ChartContainer cc) { if (cc == null) { return; } cc.addMouseListener(mChartContainerMouseListener); ccList.add(cc); chartPane.add(cc); chartPane.repaint(); chartPane.revalidate(); } public void removeChart(){ chartPane.removeAll(); chartPane.revalidate(); chartPane.repaint(); } public void zoomIn() { if (focusCC != null) { focusCC.zoomIn(); } } public void zoomOut() { if (focusCC != null) { focusCC.zoomOut(); } } public void resetSize() { for (ChartContainer chartContainer : ccList) { chartContainer.resetSize(); } } public void resetScale() { for (ChartContainer chartContainer : ccList) { chartContainer.resetScale(); } } private MouseAdapter mChartContainerMouseListener = new MouseAdapter() { @Override public void mouseClicked(MouseEvent mouseEvent) { super.mouseClicked(mouseEvent); ChartContainer cc = (ChartContainer) mouseEvent.getSource(); for (ChartContainer chartContainer : ccList) { chartContainer.setFocus(false); } cc.setFocus(true); focusCC = cc; } }; }
FlowChartWorkerFactory.java类:
package cic.cs.unb.ca.flow.ui; import cic.cs.unb.ca.jnetpcap.FlowFeature; import cic.cs.unb.ca.weka.WekaFactory; import cic.cs.unb.ca.weka.WekaXMeans; import com.google.common.collect.Multimap; import org.apache.commons.lang3.math.NumberUtils; import org.jfree.chart.ChartFactory; import org.jfree.chart.JFreeChart; import org.jfree.chart.plot.PlotOrientation; import org.jfree.data.category.DefaultCategoryDataset; import org.jfree.data.general.DefaultPieDataset; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import weka.core.Attribute; import weka.core.Instance; import javax.swing.*; public class FlowChartWorkerFactory { protected static final Logger logger = LoggerFactory.getLogger(FlowChartWorkerFactory.class); public static final int PIE_CHART = 1; public static final int BAR_CHART = 2; public static abstract class FlowChartSwingWorker<T, V> extends SwingWorker<T, V> { protected FlowFileInfo flowFileInfo; protected FlowFeature feature; protected int chartType; protected String title = "undefined"; public FlowFileInfo getFlowFileInfo() { return flowFileInfo; } public FlowFeature getFeature() { return feature; } public int getChartType() { return chartType; } public String getChartTitle() { return title; } } public static class BuildProtocolChartWorker extends FlowChartSwingWorker<JFreeChart, String> { WekaXMeans xMeans; public BuildProtocolChartWorker(FlowFileInfo info, int type) { flowFileInfo = info; feature = FlowFeature.prot; chartType = type; xMeans = flowFileInfo.getxMeans(); } @Override protected JFreeChart doInBackground() { if (xMeans ==null) { throw new IllegalArgumentException("xMeans should not be null"); } JFreeChart chart; title = "Flows By " + feature.getName(); Attribute attribute = WekaFactory.feature2attr(feature.getName(),feature.isNumeric()); Multimap<String, Instance> protocol_multimap = xMeans.getMultiMap(attribute); switch(chartType){ case PIE_CHART: DefaultPieDataset pieDataset = new DefaultPieDataset(); for (String key : protocol_multimap.keySet()) { pieDataset.setValue(FlowFeature.featureValue2String(feature,key),protocol_multimap.get(key).size()); } chart = ChartFactory.createPieChart( title, // chart title pieDataset, // data true, // include legend true, false); break; case BAR_CHART: DefaultCategoryDataset barDataSet = new DefaultCategoryDataset(); for (String key : protocol_multimap.keySet()) { barDataSet.setValue(protocol_multimap.get(key).size(),key,feature.getAbbr()); } chart = ChartFactory.createBarChart(title, "", "num", barDataSet, PlotOrientation.HORIZONTAL, true, true, false); break; default: return null; } return chart; } } public static class BuildIPChartWorker extends FlowChartSwingWorker<JFreeChart, String> { WekaXMeans xMeans; public BuildIPChartWorker(FlowFileInfo info, FlowFeature f, int type) { flowFileInfo = info; feature = f; chartType = type; xMeans = flowFileInfo.getxMeans(); } @Override protected JFreeChart doInBackground() { if (xMeans == null || feature ==null) { throw new IllegalArgumentException("xMeans or feature should not be null"); } JFreeChart chart; title = "Flows By " + feature.getName(); Attribute attribute = WekaFactory.feature2attr(feature.getName(),feature.isNumeric()); Multimap<String, Instance> feature_value_map = xMeans.getMultiMap(attribute); switch(chartType){ case PIE_CHART: DefaultPieDataset pieDataset = new DefaultPieDataset(); for (String key : feature_value_map.keySet()) { pieDataset.setValue(key,feature_value_map.get(key).size()); } chart = ChartFactory.createPieChart( title, // chart title pieDataset, // data true, // include legend true, false); break; case BAR_CHART: DefaultCategoryDataset barDataSet = new DefaultCategoryDataset(); for (String key : feature_value_map.keySet()) { double value = feature_value_map.get(key).size(); String rowKey = feature.getAbbr(); String colKey = key; barDataSet.setValue(value,rowKey,colKey); } chart = ChartFactory.createBarChart(title, null, "Count", barDataSet, PlotOrientation.HORIZONTAL, false, true, false); break; default: return null; } return chart; } } public static class BuildPortChartWorker extends FlowChartSwingWorker<JFreeChart, String> { WekaXMeans xMeans; public BuildPortChartWorker(FlowFileInfo info, FlowFeature f, int type) { flowFileInfo = info; feature = f; chartType = type; xMeans = flowFileInfo.getxMeans(); } @Override protected JFreeChart doInBackground() { if (xMeans == null || feature ==null) { throw new IllegalArgumentException("xMeans or feature should not be null"); } JFreeChart chart; title = "Flows By " + feature.getName(); Attribute attribute = WekaFactory.feature2attr(feature.getName(),feature.isNumeric()); Multimap<String, Instance> port_multimap = xMeans.getMultiMap(attribute); switch(chartType){ case PIE_CHART: DefaultPieDataset pieDataSet = new DefaultPieDataset(); for (String key : port_multimap.keySet()) { Integer port = NumberUtils.createNumber(key).intValue(); pieDataSet.setValue(port,port_multimap.get(key).size()); } chart = ChartFactory.createPieChart( title, // chart title pieDataSet, // data true, // include legend true, false); break; case BAR_CHART: DefaultCategoryDataset barDataSet = new DefaultCategoryDataset(); for (String key : port_multimap.keySet()) { double value = port_multimap.get(key).size(); String rowKey = feature.getAbbr(); Integer colKey = NumberUtils.createNumber(key).intValue(); barDataSet.setValue(value,rowKey,colKey); } chart = ChartFactory.createBarChart(title, "", "Count", barDataSet,PlotOrientation.HORIZONTAL, false, true, false); break; default: return null; } return chart; } } }
FlowFileInfo.java类:
package cic.cs.unb.ca.flow.ui; import cic.cs.unb.ca.weka.WekaXMeans; import java.io.File; public class FlowFileInfo { private File filepath; private WekaXMeans xMeans; public FlowFileInfo(File filepath, WekaXMeans xMeans) { this.filepath = filepath; this.xMeans = xMeans; } @Override public String toString() { return filepath.getName(); } public File getFilepath() { return filepath; } public WekaXMeans getxMeans() { return xMeans; } }
FlowMonitorPane.java类:
package cic.cs.unb.ca.flow.ui; import cic.cs.unb.ca.Sys; import cic.cs.unb.ca.flow.FlowMgr; import cic.cs.unb.ca.guava.Event.FlowVisualEvent; import cic.cs.unb.ca.guava.GuavaMgr; import cic.cs.unb.ca.jnetpcap.BasicFlow; import cic.cs.unb.ca.jnetpcap.FlowFeature; import cic.cs.unb.ca.jnetpcap.PcapIfWrapper; import cic.cs.unb.ca.jnetpcap.worker.LoadPcapInterfaceWorker; import cic.cs.unb.ca.jnetpcap.worker.TrafficFlowWorker; import org.apache.commons.io.FilenameUtils; import org.apache.commons.lang3.StringUtils; import org.jnetpcap.PcapIf; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import cic.cs.unb.ca.jnetpcap.worker.InsertCsvRow; import swing.common.InsertTableRow; import swing.common.JTable2CSVWorker; import swing.common.TextFileFilter; import javax.swing.*; import javax.swing.border.EmptyBorder; import javax.swing.table.DefaultTableModel; import java.awt.*; import java.io.File; import java.time.LocalDate; import java.util.ArrayList; import java.util.List; import java.util.concurrent.CancellationException; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class FlowMonitorPane extends JPanel { protected static final Logger logger = LoggerFactory.getLogger(FlowMonitorPane.class); private JTable flowTable; private DefaultTableModel defaultTableModel; private JList<PcapIfWrapper> list; private DefaultListModel<PcapIfWrapper> listModel; private JLabel lblStatus; private JLabel lblFlowCnt; private TrafficFlowWorker mWorker; private JButton btnLoad; private JToggleButton btnStart; private JToggleButton btnStop; private ButtonGroup btnGroup; private JButton btnSave = new JButton(); private File lastSave; private JButton btnGraph = new JButton(); private JFileChooser fileChooser; private ExecutorService csvWriterThread; public FlowMonitorPane() { init(); setLayout(new BorderLayout(5, 5)); setBorder(new EmptyBorder(10, 10, 10, 10)); add(initCenterPane(), BorderLayout.CENTER); } private void init() { csvWriterThread = Executors.newSingleThreadExecutor(); } public void destory() { csvWriterThread.shutdown(); } private JPanel initCenterPane(){ JPanel pane = new JPanel(); pane.setLayout(new BorderLayout(0, 0)); pane.setBorder(BorderFactory.createEmptyBorder(0,0,0,0)); JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT,initFlowPane(), initNWifsPane()); splitPane.setBorder(BorderFactory.createEmptyBorder(0,0,0,0)); splitPane.setOneTouchExpandable(true); splitPane.setResizeWeight(1.0); pane.add(splitPane,BorderLayout.CENTER); return pane; } private JPanel initFlowPane() { JPanel pane = new JPanel(); pane.setLayout(new BorderLayout(0, 5)); pane.setBorder(BorderFactory.createLineBorder(new Color(0x555555))); //pane.add(initTableBtnPane(), BorderLayout.NORTH); pane.add(initTablePane(), BorderLayout.CENTER); pane.add(initStatusPane(), BorderLayout.SOUTH); return pane; } private JPanel initTablePane() { JPanel pane = new JPanel(); pane.setLayout(new BorderLayout(0, 0)); pane.setBorder(BorderFactory.createEmptyBorder(0,0,0,0)); String[] arrayHeader = StringUtils.split(FlowFeature.getHeader(), ","); defaultTableModel = new DefaultTableModel(arrayHeader,0); flowTable = new JTable(defaultTableModel); flowTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); JScrollPane scrollPane = new JScrollPane(flowTable); scrollPane.setBorder(BorderFactory.createEmptyBorder(0,0,0,0)); pane.add(scrollPane,BorderLayout.CENTER); return pane; } private JPanel initTableBtnPane(){ JPanel btnPane = new JPanel(); btnPane.setLayout(new BoxLayout(btnPane, BoxLayout.X_AXIS)); btnSave = new JButton("Save as"); btnGraph = new JButton("Graphs"); btnSave.setFocusable(false); btnSave.setEnabled(false); btnGraph.setFocusable(false); btnGraph.setEnabled(false); fileChooser = new JFileChooser(new File(FlowMgr.getInstance().getmDataPath())); TextFileFilter csvChooserFilter = new TextFileFilter("csv file (*.csv)", new String[]{"csv"}); fileChooser.setFileFilter(csvChooserFilter); btnSave.addActionListener(actionEvent -> { int action = fileChooser.showSaveDialog(FlowMonitorPane.this); if (action == JFileChooser.APPROVE_OPTION) { File selectedFile = fileChooser.getSelectedFile(); String filename = selectedFile.getName(); if (FilenameUtils.getExtension(filename).equalsIgnoreCase("csv")) { //save name ok } else { selectedFile = new File(selectedFile.getParentFile(), FilenameUtils.getBaseName(filename) + ".csv"); } String title = "file conflict"; String message = "Another file with the same name already exists,do you want to overwrite?"; if (selectedFile.exists()) { int reply = JOptionPane.showConfirmDialog(this, message, title, JOptionPane.YES_NO_OPTION); if (reply == JOptionPane.YES_OPTION) { JTable2CSVWorker worker = new JTable2CSVWorker(flowTable, selectedFile); worker.execute(); } else { btnSave.doClick(); } } else { JTable2CSVWorker worker = new JTable2CSVWorker(flowTable, selectedFile); worker.execute(); } lastSave = selectedFile; btnGraph.setEnabled(true); } }); btnGraph.addActionListener(actionEvent -> GuavaMgr.getInstance().getEventBus().post(new FlowVisualEvent(lastSave))); btnPane.add(Box.createHorizontalGlue()); btnPane.add(btnSave); btnPane.add(Box.createHorizontalGlue()); btnPane.add(btnGraph); btnPane.add(Box.createHorizontalGlue()); btnPane.setBorder(BorderFactory.createRaisedSoftBevelBorder()); return btnPane; } private JPanel initStatusPane() { JPanel pane = new JPanel(); pane.setLayout(new BoxLayout(pane, BoxLayout.X_AXIS)); lblStatus = new JLabel("Get ready"); lblStatus.setForeground(SystemColor.desktop); lblFlowCnt = new JLabel("0"); pane.add(Box.createHorizontalStrut(5)); pane.add(lblStatus); pane.add(Box.createHorizontalGlue()); pane.add(lblFlowCnt); pane.add(Box.createHorizontalStrut(5)); return pane; } private JPanel initNWifsPane() { JPanel pane = new JPanel(new BorderLayout(0, 0)); pane.setBorder(BorderFactory.createLineBorder(new Color(0x555555))); pane.add(initNWifsButtonPane(), BorderLayout.WEST); pane.add(initNWifsListPane(), BorderLayout.CENTER); return pane; } private JPanel initNWifsButtonPane() { JPanel pane = new JPanel(); pane.setBorder(BorderFactory.createEmptyBorder(10,15,10,15)); pane.setLayout(new BoxLayout(pane, BoxLayout.Y_AXIS)); Dimension d = new Dimension(80,48); btnLoad = new JButton("Load"); btnLoad.setMinimumSize(d); btnLoad.setMaximumSize(d); btnLoad.addActionListener(actionEvent -> loadPcapIfs()); btnStart = new JToggleButton("Start"); btnStart.setMinimumSize(d); btnStart.setMaximumSize(d); btnStart.setEnabled(false); btnStart.addActionListener(actionEvent -> startTrafficFlow()); btnStop = new JToggleButton("Stop"); btnStop.setMinimumSize(d); btnStop.setMaximumSize(d); btnStop.setEnabled(false); btnStop.addActionListener(actionEvent -> stopTrafficFlow()); btnGroup = new ButtonGroup(); btnGroup.add(btnStart); btnGroup.add(btnStop); pane.add(Box.createVerticalGlue()); pane.add(btnLoad); pane.add(Box.createVerticalGlue()); pane.add(btnStart); pane.add(Box.createVerticalGlue()); pane.add(btnStop); pane.add(Box.createVerticalGlue()); return pane; } private JPanel initNWifsListPane() { JPanel pane = new JPanel(); pane.setLayout(new BorderLayout(0, 0)); pane.setBorder(BorderFactory.createEmptyBorder(0,0,0,0)); listModel = new DefaultListModel<>(); listModel.addElement(new PcapIfWrapper("Click Load button to load network interfaces")); list = new JList<>(listModel); list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); list.setSelectedIndex(0); JScrollPane scrollPane = new JScrollPane(list); scrollPane.setBorder(BorderFactory.createEmptyBorder(0,0,0,0)); pane.add(scrollPane,BorderLayout.CENTER); return pane; } private void loadPcapIfs() { LoadPcapInterfaceWorker task = new LoadPcapInterfaceWorker(); task.addPropertyChangeListener(event -> { if ("state".equals(event.getPropertyName())) { LoadPcapInterfaceWorker task1 = (LoadPcapInterfaceWorker) event.getSource(); switch (task1.getState()) { case STARTED: break; case DONE: try { java.util.List<PcapIf> ifs = task1.get(); List<PcapIfWrapper> pcapiflist = PcapIfWrapper.fromPcapIf(ifs); listModel.removeAllElements(); for(PcapIfWrapper pcapif :pcapiflist) { listModel.addElement(pcapif); } btnStart.setEnabled(true); btnGroup.clearSelection(); lblStatus.setText("pick one network interface to listening"); lblStatus.validate(); } catch (InterruptedException | ExecutionException e) { logger.debug(e.getMessage()); } break; } } }); task.execute(); } private void startTrafficFlow() { String ifName = list.getSelectedValue().name(); if (mWorker != null && !mWorker.isCancelled()) { return; } mWorker = new TrafficFlowWorker(ifName); mWorker.addPropertyChangeListener(event -> { TrafficFlowWorker task = (TrafficFlowWorker) event.getSource(); if("progress".equals(event.getPropertyName())){ lblStatus.setText((String) event.getNewValue()); lblStatus.validate(); }else if (TrafficFlowWorker.PROPERTY_FLOW.equalsIgnoreCase(event.getPropertyName())) { insertFlow((BasicFlow) event.getNewValue()); }else if ("state".equals(event.getPropertyName())) { switch (task.getState()) { case STARTED: break; case DONE: try { lblStatus.setText(task.get()); lblStatus.validate(); } catch(CancellationException e){ lblStatus.setText("stop listening"); lblStatus.setForeground(SystemColor.GRAY); lblStatus.validate(); logger.info("Pcap stop listening"); }catch (InterruptedException | ExecutionException e) { logger.debug(e.getMessage()); } break; } } }); mWorker.execute(); lblStatus.setForeground(SystemColor.desktop); btnLoad.setEnabled(false); btnStop.setEnabled(true); } private void stopTrafficFlow() { if (mWorker != null) { mWorker.cancel(true); } //FlowMgr.getInstance().stopFetchFlow(); btnLoad.setEnabled(true); String path = FlowMgr.getInstance().getAutoSaveFile(); logger.info("path:{}", path); if(defaultTableModel.getRowCount()>0 && new File(path).exists()) { StringBuilder msg = new StringBuilder("The flow has been saved to :"); msg.append(Sys.LINE_SEP); msg.append(path); UIManager.put("OptionPane.minimumSize",new Dimension(0, 0)); JOptionPane.showMessageDialog(this.getParent(),msg.toString()); } } private void insertFlow(BasicFlow flow) { List<String> flowStringList = new ArrayList<>(); List<String[]> flowDataList = new ArrayList<>(); String flowDump = flow.dumpFlowBasedFeaturesEx(); flowStringList.add(flowDump); flowDataList.add(StringUtils.split(flowDump, ",")); //write flows to csv file String header = FlowFeature.getHeader(); String path = FlowMgr.getInstance().getSavePath(); String filename = LocalDate.now().toString() + FlowMgr.FLOW_SUFFIX; csvWriterThread.execute(new InsertCsvRow(header, flowStringList, path, filename)); //insert flows to JTable SwingUtilities.invokeLater(new InsertTableRow(defaultTableModel,flowDataList,lblFlowCnt)); btnSave.setEnabled(true); } }
FlowOfflinePane.java类:
package cic.cs.unb.ca.flow.ui; import cic.cs.unb.ca.flow.FlowMgr; import cic.cs.unb.ca.jnetpcap.BasicFlow; import cic.cs.unb.ca.jnetpcap.FlowFeature; import cic.cs.unb.ca.jnetpcap.worker.ReadPcapFileWorker; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import cic.cs.unb.ca.jnetpcap.worker.InsertCsvRow; import swing.common.PcapFileFilter; import javax.swing.*; import javax.swing.border.Border; import javax.swing.border.EmptyBorder; import java.awt.*; import java.io.File; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Vector; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class FlowOfflinePane extends JPanel{ protected static final Logger logger = LoggerFactory.getLogger(FlowOfflinePane.class); private static final Border PADDING = BorderFactory.createEmptyBorder(10,5,10,5); private JFileChooser fileChooser; private PcapFileFilter pcapChooserFilter; private JTextArea textArea; private JButton btnClr; private JComboBox<File> cmbInput; private JComboBox<File> cmbOutput; private Vector<File> cmbInputEle; private Vector<File> cmbOutputEle; private JComboBox<Long> param1; private JComboBox<Long> param2; private Vector<Long> param1Ele; private Vector<Long> param2Ele; private Box progressBox; private JProgressBar fileProgress; private JProgressBar fileCntProgress; private ExecutorService csvWriterThread; public FlowOfflinePane() { init(); setLayout(new BorderLayout(5, 5)); setBorder(new EmptyBorder(10, 10, 10, 10)); add(initOutPane(), BorderLayout.CENTER); add(initCtrlPane(), BorderLayout.SOUTH); } private void init(){ fileChooser = new JFileChooser(new File(".")); pcapChooserFilter = new PcapFileFilter(); fileChooser.setFileFilter(pcapChooserFilter); csvWriterThread = Executors.newSingleThreadExecutor(); } public void destroy() { csvWriterThread.shutdown(); } private JPanel initOutPane(){ JPanel jPanel = new JPanel(new BorderLayout(5, 5)); JScrollPane scrollPane = new JScrollPane(); textArea = new JTextArea(); textArea.setRows(36); textArea.setToolTipText("message"); scrollPane.setViewportView(textArea); scrollPane.setBorder(BorderFactory.createLineBorder(new Color(0x555555))); /*JPanel msgSettingPane = new JPanel(); msgSettingPane.setLayout(new BoxLayout(msgSettingPane, BoxLayout.X_AXIS)); btnClr = new JButton("Clear"); msgSettingPane.add(Box.createHorizontalGlue()); msgSettingPane.add(btnClr); btnClr.addActionListener(actionEvent -> textArea.setText(""));*/ jPanel.add(scrollPane, BorderLayout.CENTER); jPanel.add(initOutStatusPane(), BorderLayout.SOUTH); return jPanel; } private JPanel initOutStatusPane() { JPanel pane = new JPanel(); pane.setLayout(new BoxLayout(pane, BoxLayout.X_AXIS)); progressBox = Box.createVerticalBox(); fileProgress = new JProgressBar(); fileCntProgress = new JProgressBar(); fileProgress.setBorderPainted(true); fileProgress.setStringPainted(true); fileCntProgress.setBorderPainted(true); fileCntProgress.setStringPainted(true); progressBox.add(fileProgress); progressBox.add(fileCntProgress); btnClr = new JButton("Clear"); int height = fileProgress.getPreferredSize().height + fileCntProgress.getPreferredSize().height; Dimension d = new Dimension(80,height); btnClr.setPreferredSize(d); btnClr.setMaximumSize(d); btnClr.setMinimumSize(d); btnClr.addActionListener(actionEvent -> textArea.setText("")); progressBox.setVisible(false); pane.add(btnClr); pane.add(Box.createHorizontalStrut(18)); pane.add(progressBox); return pane; } private JPanel initCtrlPane(){ JPanel jPanel = new JPanel(new BorderLayout(5, 5)); JPanel optPane = new JPanel(); optPane.setLayout(new BoxLayout(optPane,BoxLayout.Y_AXIS)); optPane.add(initFilePane()); optPane.add(initSettingPane()); optPane.add(initActionPane()); jPanel.add(optPane, BorderLayout.CENTER); jPanel.setBorder(BorderFactory.createLineBorder(new Color(0x555555))); return jPanel; } private JPanel initFilePane(){ JPanel jPanel = new JPanel(); jPanel.setLayout(new GridBagLayout()); jPanel.setBorder(PADDING); GridBagConstraints gc = new GridBagConstraints(); gc.insets = new Insets(10, 0, 10, 0); JLabel lblInputDir = new JLabel("Pcap dir:"); JButton btnInputBrowse = new JButton("Browse"); cmbInputEle = new Vector<>(); cmbInput = new JComboBox<>(cmbInputEle); cmbInput.setEditable(true); btnInputBrowse.addActionListener(actionEvent -> { fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); fileChooser.setFileFilter(pcapChooserFilter); int action = fileChooser.showOpenDialog(FlowOfflinePane.this); if (action == JFileChooser.APPROVE_OPTION) { File inputFile = fileChooser.getSelectedFile(); logger.debug("offline select input {}", inputFile.getPath()); setComboBox(cmbInput, cmbInputEle, inputFile); } }); JLabel lblOutputDir = new JLabel("Output dir:"); JButton btnOutputBrowse = new JButton("Browse"); cmbOutputEle = new Vector<>(); cmbOutput = new JComboBox<>(cmbOutputEle); cmbOutput.setEditable(true); btnOutputBrowse.addActionListener(actionEvent -> { fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); fileChooser.removeChoosableFileFilter(pcapChooserFilter); int action = fileChooser.showOpenDialog(FlowOfflinePane.this); if (action == JFileChooser.APPROVE_OPTION) { File outputFile = fileChooser.getSelectedFile(); logger.debug("offline select output {}", outputFile.getPath()); setComboBox(cmbOutput, cmbOutputEle, outputFile); } }); //first row gc.gridx = 0; gc.gridy = 0; gc.weightx = 0; gc.weighty = 0.1; gc.fill = GridBagConstraints.NONE; gc.anchor = GridBagConstraints.LINE_END; //gc.insets = new Insets(10, 5, 10, 5); jPanel.add(lblInputDir, gc); gc.gridx = 1; gc.gridy = 0; gc.weightx = 1; gc.weighty = 0.1; gc.fill = GridBagConstraints.HORIZONTAL; gc.anchor = GridBagConstraints.LINE_START; //gc.insets = new Insets(0, 10, 0, 0); gc.insets.left = gc.insets.right = 10; jPanel.add(cmbInput, gc); gc.gridx = 2; gc.gridy = 0; gc.weightx = 0; gc.fill = GridBagConstraints.NONE; gc.anchor = GridBagConstraints.LINE_END; //gc.insets = new Insets(10, 5, 10, 0); jPanel.add(btnInputBrowse, gc); //second row gc.gridx = 0; gc.gridy = 1; gc.weightx = 0; gc.weighty = 0.1; gc.fill = GridBagConstraints.NONE; gc.anchor = GridBagConstraints.LINE_END; //gc.insets = new Insets(10, 5, 10, 5); jPanel.add(lblOutputDir, gc); gc.gridx = 1; gc.gridy = 1; gc.weightx = 1; gc.fill = GridBagConstraints.HORIZONTAL; gc.anchor = GridBagConstraints.LINE_START; //gc.insets = new Insets(0, 10, 0, 0); gc.insets.left = gc.insets.right = 10; jPanel.add(cmbOutput, gc); gc.gridx = 2; gc.gridy = 1; gc.weightx = 0; gc.fill = GridBagConstraints.NONE; gc.anchor = GridBagConstraints.LINE_END; //gc.insets = new Insets(10, 5, 10, 0); jPanel.add(btnOutputBrowse, gc); return jPanel; } private JPanel initSettingPane(){ JPanel jPanel = new JPanel(); jPanel.setLayout(new BoxLayout(jPanel,BoxLayout.X_AXIS)); jPanel.setBorder(PADDING); JLabel lbl1 = new JLabel("Flow TimeOut:"); param1Ele = new Vector<>(); param1Ele.add(120000000L); param1 = new JComboBox<>(param1Ele); param1.setEditable(true); JLabel lbl2 = new JLabel("Activity Timeout:"); param2Ele = new Vector<>(); param2Ele.add(5000000L); param2 = new JComboBox<>(param2Ele); param2.setEditable(true); jPanel.add(lbl1); jPanel.add(param1); jPanel.add(Box.createHorizontalGlue()); jPanel.add(lbl2); jPanel.add(param2); return jPanel; } private JPanel initActionPane() { JPanel jPanel = new JPanel(); jPanel.setLayout(new BoxLayout(jPanel,BoxLayout.X_AXIS)); jPanel.setBorder(PADDING); JButton btnOK = new JButton("OK"); Dimension d = new Dimension(80,36); btnOK.setPreferredSize(d); btnOK.setMaximumSize(d); btnOK.setMinimumSize(d); jPanel.add(Box.createHorizontalGlue()); jPanel.add(btnOK); jPanel.add(Box.createHorizontalGlue()); btnOK.addActionListener(actionEvent -> startReadPcap()); return jPanel; } private void setComboBox(JComboBox<File> combo, Vector<File> comboEle, File ele) { if (comboEle.contains(ele)) { combo.setSelectedItem(ele); } else { comboEle.addElement(ele); combo.setSelectedItem(comboEle.lastElement()); } } private void updateOut(String str) { textArea.append(str); textArea.append(System.lineSeparator()); } private long getComboParameter(JComboBox<Long> param,Vector<Long> paramEle) throws ClassCastException,NumberFormatException{ long ret; int index = param.getSelectedIndex(); String input; if (index < 0) { Object o = param.getEditor().getItem(); if (o instanceof Long) { ret = (long) o; } else { input = (String) param.getEditor().getItem(); ret = Long.valueOf(input); } paramEle.add(ret); } else { ret = paramEle.get(index); } return ret; } private void startReadPcap(){ final File in; int cmbInIndex = cmbInput.getSelectedIndex(); if (cmbInIndex < 0) { in = new File((String) cmbInput.getEditor().getItem()); }else{ in = cmbInputEle.get(cmbInIndex); } final File out; int cmbOutIndex = cmbOutput.getSelectedIndex(); if (cmbOutIndex < 0) { out = new File((String) cmbOutput.getEditor().getItem()); }else{ out = cmbOutputEle.get(cmbOutIndex); } updateOut("You select: " + in.toString()); updateOut("Out folder: " + out.toString()); updateOut("-------------------------------"); long flowTimeout; long activityTimeout; try { flowTimeout = getComboParameter(param1, param1Ele); activityTimeout = getComboParameter(param2, param2Ele); Map<String, Long> flowCnt = new HashMap<>(); ReadPcapFileWorker worker = new ReadPcapFileWorker(in, out.getPath(), flowTimeout, activityTimeout); worker.addPropertyChangeListener(evt -> { ReadPcapFileWorker task = (ReadPcapFileWorker) evt.getSource(); if ("progress".equals(evt.getPropertyName())) { //logger.info("progress -> {}", evt.getNewValue()); List<String> chunks = (List<String>) evt.getNewValue(); if (chunks != null) { SwingUtilities.invokeLater(() -> { for (String str : chunks) { updateOut(str); } }); } } else if ("state".equals(evt.getPropertyName())) { switch (task.getState()) { case STARTED: progressBox.setVisible(true); break; case DONE: progressBox.setVisible(false); flowCnt.clear(); break; } } else if (ReadPcapFileWorker.PROPERTY_FILE_CNT.equalsIgnoreCase(evt.getPropertyName())) { int max = (int) evt.getOldValue(); int cur = (int) evt.getNewValue()+1; fileCntProgress.setIndeterminate(false); fileCntProgress.setMaximum(max); fileCntProgress.setValue(cur); } else if (ReadPcapFileWorker.PROPERTY_CUR_FILE.equalsIgnoreCase(evt.getPropertyName())) { fileProgress.setIndeterminate(true); String curFile = (String) evt.getNewValue(); fileProgress.setString(curFile); flowCnt.put(curFile, 0L); } else if (ReadPcapFileWorker.PROPERTY_FLOW.equalsIgnoreCase(evt.getPropertyName())) { String fileName = (String) evt.getOldValue(); BasicFlow flow = (BasicFlow) evt.getNewValue(); flowCnt.put(fileName, flowCnt.get(fileName) + 1); String msg = String.format("%d flows on Reading %s",flowCnt.get(fileName),fileName); fileProgress.setString(msg); //write flows to csv file String header = FlowFeature.getHeader(); csvWriterThread.execute(new InsertCsvRow(header, flow.dumpFlowBasedFeaturesEx(), out.getPath(), fileName+FlowMgr.FLOW_SUFFIX)); } }); worker.execute(); } catch(ClassCastException | NumberFormatException e){ logger.info("startRead: {}",e.getMessage()); JOptionPane.showMessageDialog(FlowOfflinePane.this, "The parameter is not a number,please check and try again.", "Parameter error", JOptionPane.ERROR_MESSAGE); } } }
FlowVisualPane.java类:
package cic.cs.unb.ca.flow.ui; import cic.cs.unb.ca.weka.WekaFactory; import cic.cs.unb.ca.weka.WekaXMeans; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Multimap; import org.jfree.chart.ChartPanel; import org.jfree.chart.JFreeChart; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import swing.common.CsvPickerPane; import swing.common.SwingUtils; import javax.swing.*; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeModel; import java.awt.*; import java.beans.PropertyChangeEvent; import java.io.File; import java.util.concurrent.ExecutionException; import static cic.cs.unb.ca.jnetpcap.FlowFeature.*; /** * Created by yzhang29 on 03/01/18. */ public class FlowVisualPane extends JDesktopPane implements CsvPickerPane.CsvSelect{ protected static final Logger logger = LoggerFactory.getLogger(FlowVisualPane.class); private CsvPickerPane pickerPane; private FlowChartPane flowChartPane; private JProgressBar progressBar; private JTree graphTree; private Multimap<FlowFileInfo,FlowChartInfo> treeNodeData; public FlowVisualPane() { init(); setLayout(new BorderLayout(0, 3)); //setBorder(Constants.LINEBORDER); pickerPane = new CsvPickerPane(this); pickerPane.setFilter("Flow"); pickerPane.setSelectListener(this); flowChartPane = new FlowChartPane(); add(pickerPane, BorderLayout.NORTH); add(flowChartPane,BorderLayout.CENTER); add(initOptionPane(), BorderLayout.WEST); } public FlowVisualPane(File file) { this(); visualFile(file); } private void init() { progressBar = new JProgressBar(); progressBar.setIndeterminate(true); treeNodeData = ArrayListMultimap.create(); } public void visualFile(File file) { logger.info("visualFile {}",file.getPath()); if (isFlowFileInfoExist(file)) { return; } else { flowChartPane.removeChart(); final CreateXMeansWorker xMeansWorker = new CreateXMeansWorker(file); SwingUtils.setBorderLayoutPane(FlowVisualPane.this,progressBar,BorderLayout.SOUTH); xMeansWorker.execute(); } } @Override public void onSelected(File file) { visualFile(file); } private JPanel initOptionPane() { JPanel pane = new JPanel(new BorderLayout()); pane.add(initGraphTreePane(), BorderLayout.CENTER); pane.add(initGraphButtonPane(), BorderLayout.SOUTH); return pane; } private JScrollPane initGraphTreePane() { graphTree = new JTree(createTree()); JScrollPane treeView = new JScrollPane(graphTree); return treeView; } private JPanel initGraphButtonPane() { JPanel pane = new JPanel(); pane.setLayout(new BoxLayout(pane,BoxLayout.Y_AXIS)); Box sizeBox = Box.createHorizontalBox(); JLabel wlbl = new JLabel("Width: "); JSpinner widthSpinner; JSpinner heightSpinner; JLabel hlbl = new JLabel("Height: "); SpinnerNumberModel widthSpinnerModel; SpinnerNumberModel heightSpinnerModel; widthSpinnerModel = new SpinnerNumberModel(300,ChartPanel.DEFAULT_MINIMUM_DRAW_WIDTH,ChartPanel.DEFAULT_MAXIMUM_DRAW_WIDTH,12); heightSpinnerModel = new SpinnerNumberModel(200,ChartPanel.DEFAULT_MINIMUM_DRAW_HEIGHT,ChartPanel.DEFAULT_MAXIMUM_DRAW_HEIGHT,12); widthSpinner = new JSpinner(widthSpinnerModel); heightSpinner = new JSpinner(heightSpinnerModel); widthSpinner.setPreferredSize(heightSpinner.getPreferredSize()); sizeBox.add(Box.createHorizontalStrut(16)); sizeBox.add(wlbl); sizeBox.add(widthSpinner); sizeBox.add(Box.createHorizontalStrut(16)); sizeBox.add(hlbl); sizeBox.add(heightSpinner); sizeBox.add(Box.createHorizontalStrut(16)); sizeBox.setVisible(false); Dimension btnDim = new Dimension(116, 64); JButton zoomIn = new JButton("Zoom In"); zoomIn.setPreferredSize(btnDim); zoomIn.addActionListener(actionEvent -> flowChartPane.zoomIn()); JButton zoomOut = new JButton("Zoom Out"); zoomOut.setPreferredSize(btnDim); zoomOut.addActionListener(actionEvent -> flowChartPane.zoomOut()); JButton reset_size = new JButton("Reset size"); reset_size.setPreferredSize(btnDim); reset_size.setMinimumSize(btnDim); reset_size.addActionListener(actionEvent -> flowChartPane.resetSize()); JButton reset_scale = new JButton("Reset scale"); reset_scale.setPreferredSize(btnDim); reset_scale.setMinimumSize(btnDim); reset_scale.addActionListener(actionEvent -> flowChartPane.resetScale()); Box zoomBox = Box.createHorizontalBox(); zoomBox.add(Box.createHorizontalStrut(16)); zoomBox.add(zoomIn); zoomBox.add(Box.createHorizontalGlue()); zoomBox.add(zoomOut); zoomBox.add(Box.createHorizontalStrut(16)); Box resetBox = Box.createHorizontalBox(); resetBox.add(Box.createHorizontalStrut(16)); resetBox.add(reset_scale); resetBox.add(Box.createHorizontalGlue()); resetBox.add(reset_size); resetBox.add(Box.createHorizontalStrut(16)); pane.add(sizeBox); pane.add(Box.createVerticalStrut(24)); pane.add(zoomBox); pane.add(Box.createVerticalStrut(24)); pane.add(resetBox); pane.add(Box.createVerticalStrut(16)); return pane; } private DefaultMutableTreeNode createTree() { DefaultMutableTreeNode top = new DefaultMutableTreeNode("Flow Chart"); // DefaultMutableTreeNode branch1 = new DefaultMutableTreeNode("File Name"); // DefaultMutableTreeNode graph1 = new DefaultMutableTreeNode(new FlowChartInfo("Flows By Protocol")); // DefaultMutableTreeNode graph2 = new DefaultMutableTreeNode(new FlowChartInfo("Flows By Src IP")); // DefaultMutableTreeNode graph3 = new DefaultMutableTreeNode(new FlowChartInfo("Flows By Dst IP")); // DefaultMutableTreeNode graph4 = new DefaultMutableTreeNode(new FlowChartInfo("Flows By Src Port")); // DefaultMutableTreeNode graph5 = new DefaultMutableTreeNode(new FlowChartInfo("Flows By Dst Port")); // branch1.add(graph1); // branch1.add(graph2); // branch1.add(graph3); // branch1.add(graph4); // branch1.add(graph5); //top.add(branch1); return top; } private void addChart2Tree(FlowFileInfo flowFileInfo, FlowChartInfo flowChartInfo) { DefaultTreeModel model = (DefaultTreeModel) graphTree.getModel(); DefaultMutableTreeNode root = (DefaultMutableTreeNode) model.getRoot(); DefaultMutableTreeNode fileInfoNode=null; for(int i=0;i<root.getChildCount();i++) { DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) root.getChildAt(i); FlowFileInfo fileInfoInNode = (FlowFileInfo) treeNode.getUserObject(); if (fileInfoInNode == flowFileInfo) { logger.debug("tree node -> {} exist",flowFileInfo.getFilepath().getPath()); fileInfoNode = treeNode; break; } } if (fileInfoNode == null) { fileInfoNode = new DefaultMutableTreeNode(flowFileInfo); } fileInfoNode.add(new DefaultMutableTreeNode(flowChartInfo)); root.add(fileInfoNode); model.reload(); treeNodeData.put(flowFileInfo, flowChartInfo); } private boolean isFlowFileInfoExist(File file) { if (file == null) { return false; } for (FlowFileInfo info : treeNodeData.keySet()) { if (info.getFilepath().getPath().equalsIgnoreCase(file.getPath())) { return true; } } return false; } private class CreateXMeansWorker extends SwingWorker<FlowFileInfo, String> { File csv; CreateXMeansWorker(File csv) { this.csv = csv; } @Override protected FlowFileInfo doInBackground() { if (csv == null) { throw new IllegalArgumentException("csv cannot be null"); } WekaXMeans xMeans = new WekaXMeans(WekaFactory.loadFlowCsv(csv)); FlowFileInfo flowFileInfo = new FlowFileInfo(csv, xMeans); return flowFileInfo; } @Override protected void done() { super.done(); try { FlowFileInfo flowFileInfo = get(); buildChart(flowFileInfo); SwingUtils.setBorderLayoutPane(FlowVisualPane.this,null,BorderLayout.SOUTH); } catch (InterruptedException | ExecutionException e) { logger.debug(e.getMessage()); } } } public void buildChart(FlowFileInfo info) { logger.info("buildChart"); FlowChartWorkerFactory.BuildProtocolChartWorker protocol_worker = new FlowChartWorkerFactory.BuildProtocolChartWorker(info,FlowChartWorkerFactory.PIE_CHART); protocol_worker.addPropertyChangeListener(event -> { //logger.info("build Protocol chart"); ChartWorkerPropertyChange(event, protocol_worker); }); protocol_worker.execute(); FlowChartWorkerFactory.BuildIPChartWorker sip_worker = new FlowChartWorkerFactory.BuildIPChartWorker(info,src_ip,FlowChartWorkerFactory.BAR_CHART); sip_worker.addPropertyChangeListener(event -> { //logger.info("build src ip chart"); ChartWorkerPropertyChange(event, sip_worker); }); sip_worker.execute(); FlowChartWorkerFactory.BuildIPChartWorker dip_worker = new FlowChartWorkerFactory.BuildIPChartWorker(info,dst_ip,FlowChartWorkerFactory.BAR_CHART); dip_worker.addPropertyChangeListener(event -> { //logger.info("build dst ip chart"); ChartWorkerPropertyChange(event, dip_worker); }); dip_worker.execute(); FlowChartWorkerFactory.BuildPortChartWorker spt_worker = new FlowChartWorkerFactory.BuildPortChartWorker(info, src_port, FlowChartWorkerFactory.BAR_CHART); spt_worker.addPropertyChangeListener(event -> { //logger.info("build src port chart"); ChartWorkerPropertyChange(event, spt_worker); }); spt_worker.execute(); FlowChartWorkerFactory.BuildPortChartWorker dpt_worker = new FlowChartWorkerFactory.BuildPortChartWorker(info, dst_pot, FlowChartWorkerFactory.BAR_CHART); dpt_worker.addPropertyChangeListener(event -> { //logger.info("build dst port chart"); ChartWorkerPropertyChange(event, dpt_worker); }); dpt_worker.execute(); } private void ChartWorkerPropertyChange(PropertyChangeEvent event, FlowChartWorkerFactory.FlowChartSwingWorker<JFreeChart, String> task) { if ("state".equalsIgnoreCase(event.getPropertyName())) { SwingWorker.StateValue sv = (SwingWorker.StateValue) event.getNewValue(); switch (sv) { case STARTED: SwingUtils.setBorderLayoutPane(FlowVisualPane.this,progressBar,BorderLayout.SOUTH); break; case DONE: try { JFreeChart chart = task.get(); FlowFileInfo fileInfo = task.getFlowFileInfo(); ChartContainer cc = new ChartContainer(chart); FlowChartInfo chartInfo = new FlowChartInfo(task.getChartTitle(),cc); flowChartPane.addChartContainer(cc); addChart2Tree(fileInfo, chartInfo); SwingUtils.setBorderLayoutPane(FlowVisualPane.this,null,BorderLayout.SOUTH); } catch (InterruptedException | ExecutionException e) { logger.debug(e.getMessage()); } break; } } } }
FlowVisualEvent.java类:
package cic.cs.unb.ca.guava.Event; import java.io.File; public class FlowVisualEvent { private File csv_file; public FlowVisualEvent(File csv_file) { this.csv_file = csv_file; } public File getCsv_file() { return csv_file; } }
GuavaMgr.java类:
package cic.cs.unb.ca.guava; import com.google.common.eventbus.EventBus; public class GuavaMgr { private static GuavaMgr Instance = new GuavaMgr(); private EventBus mEventBus; public GuavaMgr() { } public static GuavaMgr getInstance() { return Instance; } public void init(){ mEventBus = new EventBus("CICFlowMeter"); } public EventBus getEventBus() { return mEventBus; } }
FlowGenListener.java类:
package cic.cs.unb.ca.jnetpcap.worker;
import cic.cs.unb.ca.jnetpcap.BasicFlow;
public interface FlowGenListener {
void onFlowGenerated(BasicFlow flow);
}
InsertCsvRow.java类:
package cic.cs.unb.ca.jnetpcap.worker; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import static cic.cs.unb.ca.jnetpcap.Utils.FILE_SEP; import static cic.cs.unb.ca.jnetpcap.Utils.LINE_SEP; public class InsertCsvRow implements Runnable { public static final Logger logger = LoggerFactory.getLogger(InsertCsvRow.class); private String header; private List<String> rows; private String savepath = null; private String filename = null; public InsertCsvRow(String header, List<String> rows, String savepath, String filename) { this.header = header; this.rows = rows; this.savepath = savepath; this.filename = filename; } public InsertCsvRow(String header, String row, String savepath, String filename) { this.header = header; this.rows = new ArrayList<>(); this.savepath = savepath; this.filename = filename; rows.add(row); } @Override public void run() { insert(header,rows,savepath,filename); } public static void insert(String header,List<String> rows,String savepath, String filename) { if (savepath == null || filename == null || rows == null || rows.size() <= 0) { String ex = String.format("savepath=%s,filename=%s", savepath, filename); throw new IllegalArgumentException(ex); } File fileSavPath = new File(savepath); if(!fileSavPath.exists()) { fileSavPath.mkdirs(); } if(!savepath.endsWith(FILE_SEP)){ savepath += FILE_SEP; } File file = new File(savepath+filename); FileOutputStream output = null; try { if (file.exists()) { output = new FileOutputStream(file, true); }else{ if (file.createNewFile()) { output = new FileOutputStream(file); } if (header != null) { output.write((header+LINE_SEP).getBytes()); } } for (String row : rows) { output.write((row+LINE_SEP).getBytes()); } } catch (IOException e) { logger.debug(e.getMessage()); } finally { try { if (output != null) { output.flush(); output.close(); } } catch (IOException e) { logger.debug(e.getMessage()); } } } }
LoadPcapInterfaceWorker.java类:
package cic.cs.unb.ca.jnetpcap.worker; import java.util.ArrayList; import java.util.List; import javax.swing.SwingWorker; import org.jnetpcap.Pcap; import org.jnetpcap.PcapIf; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class LoadPcapInterfaceWorker extends SwingWorker<List<PcapIf>,String>{ public static final Logger logger = LoggerFactory.getLogger(LoadPcapInterfaceWorker.class); public LoadPcapInterfaceWorker() { super(); } @Override protected List<PcapIf> doInBackground() throws Exception { StringBuilder errbuf = new StringBuilder(); List<PcapIf> ifs = new ArrayList<>(); if(Pcap.findAllDevs(ifs, errbuf)!=Pcap.OK) { logger.error("Error occured: " + errbuf.toString()); throw new Exception(errbuf.toString()); } return ifs; } @Override protected void done() { super.done(); } }
PcapReader.java类:
package cic.cs.unb.ca.jnetpcap.worker; import cic.cs.unb.ca.jnetpcap.*; import org.jnetpcap.PcapClosedException; import java.io.File; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; import static cic.cs.unb.ca.jnetpcap.Utils.FILE_SEP; import static cic.cs.unb.ca.jnetpcap.Utils.FLOW_SUFFIX; import static cic.cs.unb.ca.jnetpcap.Utils.countLines; public class PcapReader { public static void readFile(String inputFile, String outPath, long flowTimeout, long activityTimeout) { if(inputFile==null ||outPath==null ) { return; } //String fileName = FilenameUtils.getName(inputFile); Path p = Paths.get(inputFile); String fileName = p.getFileName().toString(); if(!outPath.endsWith(FILE_SEP)){ outPath += FILE_SEP; } File saveFileFullPath = new File(outPath+fileName+FLOW_SUFFIX); if (saveFileFullPath.exists()) { if (!saveFileFullPath.delete()) { System.out.println("Saved file full path cannot be deleted"); } } FlowGenerator flowGen = new FlowGenerator(true, flowTimeout, activityTimeout); flowGen.addFlowListener(new FlowListener(fileName,outPath)); boolean readIP6 = false; boolean readIP4 = true; PacketReader packetReader = new PacketReader(inputFile, readIP4, readIP6); System.out.println(String.format("Working on... %s",fileName)); int nValid=0; int nTotal=0; int nDiscarded = 0; long start = System.currentTimeMillis(); while(true) { try{ BasicPacketInfo basicPacket = packetReader.nextPacket(); nTotal++; if(basicPacket !=null){ flowGen.addPacket(basicPacket); nValid++; }else{ nDiscarded++; } }catch(PcapClosedException e){ break; } } flowGen.dumpLabeledCurrentFlow(saveFileFullPath.getPath(), FlowFeature.getHeader()); long lines = countLines(saveFileFullPath.getPath()); System.out.println(String.format("%s is done. total %d flows ",fileName,lines)); System.out.println(String.format("Packet stats: Total=%d,Valid=%d,Discarded=%d",nTotal,nValid,nDiscarded)); System.out.println("-----------------------------------------------------------------------------------------"); } static class FlowListener implements FlowGenListener { private String fileName; private String outPath; private long cnt; public FlowListener(String fileName, String outPath) { this.fileName = fileName; this.outPath = outPath; } @Override public void onFlowGenerated(BasicFlow flow) { String flowDump = flow.dumpFlowBasedFeaturesEx(); List<String> flowStringList = new ArrayList<>(); flowStringList.add(flowDump); InsertCsvRow.insert(FlowFeature.getHeader(),flowStringList,outPath,fileName+ FLOW_SUFFIX); cnt++; String console = String.format("%s -> %d flows \r", fileName,cnt); System.out.print(console); } } }
ReadPcapFileWorker.java类:
package cic.cs.unb.ca.jnetpcap.worker; import cic.cs.unb.ca.jnetpcap.*; import org.jnetpcap.PcapClosedException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.swing.*; import java.io.File; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; import static cic.cs.unb.ca.jnetpcap.Utils.*; public class ReadPcapFileWorker extends SwingWorker<List<String>,String> { public static final Logger logger = LoggerFactory.getLogger(ReadPcapFileWorker.class); public static final String PROPERTY_FILE_CNT = "file_count"; public static final String PROPERTY_CUR_FILE = "file_current"; public static final String PROPERTY_FLOW = "file_flow"; private static final String DividingLine = "---------------------------------------------------------------------------------------------------------------"; private long flowTimeout; private long activityTimeout; private int totalFlows = 0; private File pcapPath; private String outPutDirectory; private List<String> chunks; public ReadPcapFileWorker(File inputFile, String outPutDir) { super(); pcapPath = inputFile; outPutDirectory = outPutDir; chunks = new ArrayList<>(); if(!outPutDirectory.endsWith(FILE_SEP)) { outPutDirectory = outPutDirectory + FILE_SEP; } flowTimeout = 120000000L; activityTimeout = 5000000L; } public ReadPcapFileWorker(File inputFile, String outPutDir,long param1,long param2) { super(); pcapPath = inputFile; outPutDirectory = outPutDir; chunks = new ArrayList<>(); if(!outPutDirectory.endsWith(FILE_SEP)) { outPutDirectory = outPutDirectory + FILE_SEP; } flowTimeout = param1; activityTimeout = param2; } @Override protected List<String> doInBackground() { if (pcapPath.isDirectory()) { readPcapDir(pcapPath,outPutDirectory); } else { if (!isPcapFile(pcapPath)) { publish("Please select pcap file!"); publish(""); } else { publish("CICFlowMeter received 1 pcap file"); publish(""); publish(""); firePropertyChange(PROPERTY_CUR_FILE,"",pcapPath.getName()); firePropertyChange(PROPERTY_FILE_CNT,1,1);//begin with 1 readPcapFile(pcapPath.getPath(), outPutDirectory); } } /*chunks.clear(); chunks.add(""); chunks.add(DividingLine); chunks.add(String.format("TOTAL FLOWS GENERATED :%s", totalFlows)); chunks.add(DividingLine); publish(chunks.toArray( new String[chunks.size()]));*/ return chunks; } @Override protected void done() { super.done(); } @Override protected void process(List<String> chunks) { super.process(chunks); firePropertyChange("progress","",chunks); } private void readPcapDir(File inputPath, String outPath) { if(inputPath==null||outPath==null) { return; } //File[] pcapFiles = inputPath.listFiles(file -> file.getName().toLowerCase().endsWith("pcap")); File[] pcapFiles = inputPath.listFiles(file -> isPcapFile(file)); int file_cnt = pcapFiles.length; logger.debug("CICFlowMeter found :{} pcap files", file_cnt); publish(String.format("CICFlowMeter found :%s pcap files", file_cnt)); publish(""); publish(""); for(int i=0;i<file_cnt;i++) { File file = pcapFiles[i]; if (file.isDirectory()) { continue; } firePropertyChange(PROPERTY_CUR_FILE,"",file.getName()); firePropertyChange(PROPERTY_FILE_CNT,file_cnt,i+1);//begin with 1 readPcapFile(file.getPath(),outPath); } } private void readPcapFile(String inputFile, String outPath) { if(inputFile==null ||outPath==null ) { return; } Path p = Paths.get(inputFile); String fileName = p.getFileName().toString();//FilenameUtils.getName(inputFile); if(!outPath.endsWith(FILE_SEP)){ outPath += FILE_SEP; } File saveFileFullPath = new File(outPath+fileName+Utils.FLOW_SUFFIX); if (saveFileFullPath.exists()) { if (!saveFileFullPath.delete()) { System.out.println("Saved file full path cannot be deleted"); } } FlowGenerator flowGen = new FlowGenerator(true, flowTimeout, activityTimeout); flowGen.addFlowListener(new FlowListener(fileName)); boolean readIP6 = false; boolean readIP4 = true; PacketReader packetReader = new PacketReader(inputFile, readIP4, readIP6); publish(String.format("Working on... %s",inputFile)); logger.debug("Working on... {}",inputFile); int nValid=0; int nTotal=0; int nDiscarded = 0; long start = System.currentTimeMillis(); while(true) { try{ BasicPacketInfo basicPacket = packetReader.nextPacket(); nTotal++; if(basicPacket !=null){ flowGen.addPacket(basicPacket); nValid++; }else{ nDiscarded++; } }catch(PcapClosedException e){ break; } } flowGen.dumpLabeledCurrentFlow(saveFileFullPath.getPath(), FlowFeature.getHeader()); long lines = countLines(saveFileFullPath.getPath()); long end = System.currentTimeMillis(); chunks.clear(); chunks.add(String.format("Done! Total %d flows",lines)); chunks.add(String.format("Packets stats: Total=%d,Valid=%d,Discarded=%d",nTotal,nValid,nDiscarded)); chunks.add(DividingLine); publish(chunks.toArray( new String[chunks.size()])); /*chunks.add(String.format("\t Total packets: %d",nTotal)); chunks.add(String.format("\t Valid packets: %d",nValid)); chunks.add(String.format("\t Ignored packets:%d %d ", nDiscarded,(nTotal-nValid))); chunks.add(String.format("PCAP duration %d seconds",((packetReader.getLastPacket()- packetReader.getFirstPacket())/1000))); chunks.add(DividingLine); int singleTotal = flowGen.dumpLabeledFlowBasedFeatures(outPath, fullname+ FlowMgr.FLOW_SUFFIX, FlowFeature.getHeader()); chunks.add(String.format("Number of Flows: %d",singleTotal)); chunks.add(""); publish(chunks.toArray( new String[chunks.size()])); totalFlows += singleTotal; logger.debug("{} is done,Total {}",inputFile,singleTotal);*/ } class FlowListener implements FlowGenListener { private String fileName; FlowListener(String fileName) { this.fileName = fileName; } @Override public void onFlowGenerated(BasicFlow flow) { firePropertyChange(PROPERTY_FLOW,fileName,flow); } } }
TrafficFlowWorker.java类:
package cic.cs.unb.ca.jnetpcap.worker; import cic.cs.unb.ca.jnetpcap.BasicFlow; import cic.cs.unb.ca.jnetpcap.FlowGenerator; import cic.cs.unb.ca.jnetpcap.PacketReader; import org.jnetpcap.Pcap; import org.jnetpcap.nio.JMemory.Type; import org.jnetpcap.packet.PcapPacket; import org.jnetpcap.packet.PcapPacketHandler; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.swing.*; import java.util.List; public class TrafficFlowWorker extends SwingWorker<String,String> implements FlowGenListener{ public static final Logger logger = LoggerFactory.getLogger(TrafficFlowWorker.class); public static final String PROPERTY_FLOW = "flow"; private String device; public TrafficFlowWorker(String device) { super(); this.device = device; } @Override protected String doInBackground() { FlowGenerator flowGen = new FlowGenerator(true,120000000L, 5000000L); flowGen.addFlowListener(this); int snaplen = 64 * 1024;//2048; // Truncate packet at this size int promiscous = Pcap.MODE_PROMISCUOUS; int timeout = 60 * 1000; // In milliseconds StringBuilder errbuf = new StringBuilder(); Pcap pcap = Pcap.openLive(device, snaplen, promiscous, timeout, errbuf); if (pcap == null) { logger.info("open {} fail -> {}",device,errbuf.toString()); return String.format("open %s fail ->",device)+errbuf.toString(); } PcapPacketHandler<String> jpacketHandler = (packet, user) -> { /* * BufferUnderflowException while decoding header * that is because: * 1.PCAP library is not multi-threaded * 2.jNetPcap library is not multi-threaded * 3.Care must be taken how packets or the data they referenced is used in multi-threaded environment * * typical rule: * make new packet objects and perform deep copies of the data in PCAP buffers they point to * * but it seems not work */ PcapPacket permanent = new PcapPacket(Type.POINTER); packet.transferStateAndDataTo(permanent); flowGen.addPacket(PacketReader.getBasicPacketInfo(permanent, true, false)); if(isCancelled()) { pcap.breakloop(); logger.debug("break Packet loop"); } }; //FlowMgr.getInstance().setListenFlag(true); logger.info("Pcap is listening..."); firePropertyChange("progress","open successfully","listening: "+device); int ret = pcap.loop(Pcap.DISPATCH_BUFFER_FULL, jpacketHandler, device); String str; switch (ret) { case 0: str = "listening: " + device + " finished"; break; case -1: str = "listening: " + device + " error"; break; case -2: str = "stop listening: " + device; break; default: str = String.valueOf(ret); } return str; } @Override protected void process(List<String> chunks) { super.process(chunks); } @Override protected void done() { super.done(); } @Override public void onFlowGenerated(BasicFlow flow) { firePropertyChange(PROPERTY_FLOW,null,flow); } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。