Можно ли сидеть в сети и получать TCP-поток / UDP-дейтаграммы? - PullRequest
0 голосов
/ 03 декабря 2009

Кто-нибудь делал работу над интерфейсом захвата пакетов (например, jpcap) с реализацией UDPSocket (для дейтаграмм UDP) и InputStream (для потоков TCP)?

Я полагаю, это не будет слишком сложно сделать, учитывая API обратного вызова в jpcap, но кто-нибудь уже это сделал? Есть ли какие-либо проблемы с этим (я должен выяснить, как самостоятельно собрать поток TCP, например?)

Ответы [ 2 ]

2 голосов
/ 23 июня 2010

Tcp повторная сборка может быть сделана с JNetPcap . Вот полный пример:

final String SOME_PORT = 8888;

StringBuilder errbuf = new StringBuilder();
Pcap pcap = Pcap.openOffline("/dir/someFile.pcap", errbuf); //Can be replace with .openLive(...)

if (pcap == null) {
    System.err.printf("Error: "+errbuf.toString());
    return;
}

//Handler that receive Tcp Event one by one
AnalyzerListener<TcpStreamEvent> handler = new AnalyzerListener<TcpStreamEvent>() {

    @Override
    public void processAnalyzerEvent(TcpStreamEvent evt) {
        JPacket packet = evt.getPacket();

        Tcp tcp = new Tcp();
        if (packet.hasHeader(tcp)) {

              //Limiting the analysis to a specific protocol
              if (tcp.destination() == SOME_PORT || tcp.source() == SOME_PORT) {
                    String data = new String(tcp.getPayload());
                    System.out.println("Capture data:{"+data+"}");
              }
        }
    }
};

TcpAnalyzer tcpAnalyzer = JRegistry.getAnalyzer(TcpAnalyzer.class);
tcpAnalyzer.addTcpStreamListener(handler, null);

//Starting the capture
pcap.loop(Pcap.LOOP_INFINATE,  JRegistry.getAnalyzer(JController.class), null);
2 голосов
/ 03 декабря 2009

Я не делал эту конкретную вещь, но я много работаю с анализом захваченных пакетов в C / C ++. Я не знаю, существуют ли библиотеки Java для всего этого.

По сути, вам нужно продвигаться вверх по стеку протоколов, начиная с IP. Данные pcap начинаются с заголовка канального уровня, но я не думаю, что в этом есть что-то, что вас беспокоит, кроме игнорирования не-IP-пакетов.

Самое сложное в работе с IP - это сборка фрагментированных дейтаграмм. Это делается с помощью бита «Больше фрагментов» в поле «Флаги» и в поле «Смещение фрагмента» в сочетании с полем «Идентификация», чтобы отличать фрагменты от разных дейтаграмм. Затем вы используете поле «Протокол» для идентификации пакетов TCP и UDP и поле «Длина заголовка», чтобы найти начало соответствующего заголовка.

Следующим шагом для TCP и UDP является демультиплексирование, разделяющее различные соединения в потоке захваченных пакетов. Оба протокола идентифицируют соединения (ну, у UDP нет соединений как таковых, но у меня нет лучшего слова, пригодного для использования) по 4 кортежам IP-адреса источника и назначения и порта источника и назначения, поэтому соединение будет быть последовательностью пакетов, которая соответствует всем 4 из этих значений.

Как только это будет сделано, для UDP вы почти закончите, если не хотите проверять контрольную сумму. Поле длины в заголовке UDP говорит вам, как долго пакет; вычтите 8 байтов для заголовка, и это ваши данные.

TCP несколько сложнее, так как вам действительно нужно заново собрать поток. Это делается с использованием порядкового номера в заголовке в сочетании с длиной. Сумма этих двух говорит вам следующий порядковый номер в потоке. Помните, что вы отслеживаете движение в двух направлениях.

(Это намного проще, чем написать настоящую реализацию TCP, так как тогда вам нужно реализовать алгоритм Nagle и другие мелочи.)

В сети много информации о форматах заголовков; Google "IP header" для начинающих. Для этой работы необходим сетевой анализатор, такой как Wireshark, поскольку он покажет вам, как должны выглядеть ваши захваченные данные. Действительно, поскольку Wireshark является открытым исходным кодом, вы, вероятно, можете многое узнать, посмотрев, как он работает

...