Реконструкция сеанса TCP в реальном времени в Java с использованием jPcap

Я прослушиваю определенную сетевую карту и перехватываю пакеты TCP (только TCP) с помощью библиотеки jPcap. Однако мне нужны целые сеансы TCP, а не отдельные пакеты.

В Wireshark я могу выбрать «следить за потоком tcp», чтобы получить весь разговор от начала до конца. Я хочу сделать именно это на Java. Как я могу реконструировать эти пакеты в режиме реального времени? Я хочу реконструировать сеансы TCP, прослушивая сетевую карту и захватывая новые пакеты. Как я могу этого добиться? Вот мой код для захвата пакетов:

jpcap.NetworkInterface[] devices = JpcapCaptor.getDeviceList();
            JpcapCaptor captor = JpcapCaptor.openDevice(devices[1], 65535, true, 1000);
            JpcapWriter writer = JpcapWriter.openDumpFile(captor, "myNetworkDump");
            captor.loopPacket(-1, new PacketPrinter(writer));

class PacketPrinter implements PacketReceiver {

    private HashMap<Long, ArrayList<Packet>> sessions;
    private BufferedWriter out;
    private JpcapWriter writer;

    Map<Long, TCPBodyData> bodies = new HashMap<Long, TCPBodyData>();

    public PacketPrinter(JpcapWriter writer) {
        this.writer = writer;
        this.sessions = new HashMap<Long, ArrayList<Packet>>();
    }

    public void receivePacket(Packet packet) {
        System.out.println(packet);
        if (packet instanceof TCPPacket) {
            TCPPacket tcppacl = (TCPPacket) packet;
            byte[] body = addBodyData(tcppacl);
            // System.out.println(new String(body));
        }
}
}

person Alpay    schedule 24.06.2014    source источник


Ответы (3)


Я мало что знаю о jPcap (и я помню, что где-то читал - здесь, что лучше использовать jNetPcap) но я бы использовал HashMap<String,TCPPacket> tcp-разговор в соответствии с сохранением разговора, ключ String, например, String.join('.',remotehost_tcp_address,remote_host_tcp_port), а затем дождался последовательности RST или FIN-FIN+ACK-ACK, чтобы удалить его.

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

person CaptainCap    schedule 24.06.2014
comment
Есть как минимум три разных проекта под названием jPcap разного качества. - person user207421; 12.07.2014

Вы можете попытаться сгруппировать пакеты по исходному узлу, исходному порту, целевому узлу, порту назначения и последовательным порядковым номерам. Чтобы узнать, когда начинается сеанс, вы можете проверить пакеты с SYN, установленным на 1, в этот момент вы можете захватить ISN (начальный порядковый номер), и все последующие пакеты с ISN+1..ISN+n будут в том же потоке tcp. Чтобы узнать, когда сеанс заканчивается, вы должны проверить пакет FIN. Ссылка на Википедию неплохая http://en.m.wikipedia.org/wiki/Transmission_Control_Protocol но для лучшего и глубокого чтения рекомендую "TCP/IP Illustrated vol.1".

person R.Sicart    schedule 15.07.2014
comment
Пакеты fin определенно закончат разговоры, это правильно. А как же первые? - person Alpay; 16.07.2014
comment
Я думаю, вы все еще можете использовать порядковый номер ACK из пакета RST, чтобы связать его с правильным потоком tcp, но я не уверен. - person R.Sicart; 17.07.2014

Проект pcap-reconst предоставляет основу для восстановления потока TCP из файлов pcap. Вы можете использовать метод public void reassemblePacket(TcpPacket tcpPacket) класса TcpReassembler для выполнения задания.

/*
* The main function of the class receives a tcp packet and reconstructs the stream
*/
public void reassemblePacket(TcpPacket tcpPacket) throws Exception {
    ....
}
/*
 *Get the TCP stream
 */
 public OutputStream getOutputStream() {
    return outputStream;
}

/*
 * Reconstructs the tcp session
 * @param sequence Sequence number of the tcp packet
 * @param length The size of the original packet data
 * @param data The captured data
 * @param data_length The length of the captured data
 * @param synflag
 * @param net_src The source ip address
 * @param net_dst The destination ip address
 * @param srcport The source port
 * @param dstport The destination port
 */
 private void reassembleTcp(long sequence, long ack_num, long length, byte[] data, 
                            int dataLength, boolean synflag,
                            TcpConnection tcpConnection) throws Exception {
      ....
 }
person Ortomala Lokni    schedule 11.07.2014
comment
Похоже, это не то, о чем просит ОП. - person user207421; 16.07.2014
comment
ОП сказал: как я могу реконструировать эти пакеты в режиме реального времени? Я хочу реконструировать сеансы TCP, прослушивая сетевую карту и захватывая новые пакеты. Я отвечаю на это. Код, который он предоставил, всего лишь пробный. - person Ortomala Lokni; 16.07.2014
comment
Ваш ответ касается восстановления пакетов. Он спрашивает о восстановлении сеансов. - person user207421; 17.07.2014
comment
В первом предложении я ошибся и поменял местами пакет и поток, но теперь это исправлено. В остальном ответ правильный. Метод reassemblePacket получает TCP-пакет и реконструирует поток. - person Ortomala Lokni; 17.07.2014