Чтение содержимого пакета Netflow с использованием MySQL
Я разрабатываю программное обеспечение, которое захватывает каждый пакет udp, который проходит через мой брандмауэр (виртуальная машина OpenBSD 5.4), с имеющейся у меня виртуальной машины, и сохраняю пакет в базе данных 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: Packet Content
2 ответа
Вы можете преобразовать неподписанные байты в и 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;
}
Удачи:)
Дейтаграммы NetFlow 5 очень компактны: каждое поле является просто числом. Вам лучше разобрать его в своем коде и либо записать аннотированную строку в вашу базу данных, либо добавить поля базы данных для каждого из полей в дейтаграмме NetFlow.
Разбор прост: вы просто отсчитываете количество байтов и интерпретируете их как целые числа или символы, в зависимости от поля.
Изменить: Формат здесь: Форматы записи потока Cisco Они перечисляют смещение байтов, поэтому, если вы хотите, чтобы dOctets (вы делаете, из того, что вы описали), возьмите байты 20-24 из полезной нагрузки и преобразовать их в целое число.