Чтение содержимого пакета Netflow с использованием MySQL

Я разрабатываю программное обеспечение, которое перехватывает каждый пакет udp, проходящий через мой брандмауэр (виртуальная машина 5.4 OpenBSD) с виртуальной машины, которая у меня есть, и сохраняет пакет в базе данных MySQL.

Мой код в основном:

try
{
DatagramSocket serverSocket = new DatagramSocket(9876);        
byte[] receiveData = new byte [1024];
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
serverSocket.receive(receivePacket);
String sentence = new String(receivePacket.getData());
InetAddress IPAddress = receivePacket.getAddress();
Connection conn = DriverManager.getConnection(url, user, password);
String sql = "INSERT INTO tabela_netflow (fluxo) values (?)";
PreparedStatement statement = conn.prepareStatement(sql);
statement.setBytes(1,receivePacket.getData());
int row = statement.executeUpdate();
if (row > 0) 
{
   System.out.println("Packet saved:" +receivePacket.getData());
}

} catch (SQLException ex) 
{
   ex.printStackTrace();
}

Код работает нормально, моя проблема в том, что когда я пытаюсь просмотреть содержимое, сохраненное в базе данных, появляется много странных символов, поскольку он двоичный (я думаю), я не могу прочитать его, чтобы получить нужную мне информацию. (формат записи потока, который можно посмотреть здесь)

Моя таблица очень проста: есть 2 столбца, код (int, автоинкремент) и еще один столбец, fluxo (varbinary(10000)). Вот что я вижу, когда нажимаю «открыть значение в редакторе» в MySQL Workbench: Содержимое пакета


person Ganso    schedule 03.06.2014    source источник


Ответы (2)


Дейтаграммы NetFlow 5 очень компактны: каждое поле — это просто число. Вам лучше разобрать его в своем коде и либо записать аннотированную строку в свою базу данных, либо добавить поля базы данных для каждого из полей в дейтаграмме NetFlow.

Анализ прост: вы просто считаете количество байтов и интерпретируете их как целые числа или символы, в зависимости от поля.

Изменить: формат здесь: Форматы Cisco Flow Record В них указано смещение в байтах, поэтому, если вам нужны dOctets (вы делаете, исходя из того, что вы описываете), возьмите байты 20-24 полезной нагрузки и преобразуйте их в целое число.

person John Murphy    schedule 04.06.2014
comment
Я понимаю, что вы имели в виду, поскольку формат заголовка netflow известен, вы можете считать байты на основе байтов каждого поля, но как я могу это сделать? У меня есть только receivePacket.getData() для получения содержимого пакета, и я не знаю, как разделить этот метод. - person Ganso; 08.06.2014
comment
Формат см. здесь: cisco.com/c/en/us/td/docs/net_mgmt/netflow_collection_engine/ - person John Murphy; 11.06.2014
comment
Я имею в виду, я знаю формат, я просто не знаю, как отделиться от receivePacket.getData(), чтобы получить всю необходимую мне информацию... метод просто возвращает байтовый вектор, содержащий данные буфера, но как я должен получить точно любая часть мне нужна? Например: если мне нужна версия (первые 0-1 байт) byte[] buffer = new byte[1024]; буфер = ReceivePacket.getData(); целая версия = буфер [0]; Я не знаю, смогу ли я это сделать, и я не могу использовать parseInt, так как мне нужно отправить строку для преобразования. - person Ganso; 12.06.2014

Вы можете преобразовать байты без знака в и int с помощью:

public static int unsignedByteToInt(byte b) {
    return (int) b & 0xFF;
}

Это вернет целочисленное значение байта. Однако вы ищете значение из байта [0-1] правильно? У вас будет сумма этих значений, вот очень быстрый (и, вероятно, ужасный способ сделать это):

public static int unsignedByteToInt(byte[] b, int offset, int len) {
    int r = 0;
    for(int i = 0; i < len; i++){
        r += unsignedByteToInt(b[offset+i]);// the method shown earlier
    }
    return r;
}

Учитывая DatagramPacket, вы можете позвонить:

int version = unsignedByteToInt(receivedDatagramPacketPacket.getData(), 0,2);

Вот два метода для строк (кстати, я их не тестировал :-\):

public static String byteToHex(byte b){
    int i = b & 0xFF;
    return Integer.toHexString(i);
}

public static String byteToHex(byte[] b, int offset, int len){
    String r = "";
    for(int i = 0; i < len; i++){
        r += byteToHex(b[offset+i]);
    }
    return r;
}

Удачи :)

person kristophbarbour    schedule 28.07.2014
comment
Я проверил ваш код, возможно, он работал для версии (при тестировании я получил версию = 5, звучит нормально), но затем я попробовал следующие 2 байта (байты 2-3) для подсчета, и я получил количество = 130 (и это должно быть между 1-30), поэтому я не знаю, что делать.. - person Ganso; 22.08.2014