Question

Quelqu'un at-il là-bas fait le travail d'être assis sur le dessus d'une interface de capture de paquets (comme jpcap) avec une mise en œuvre de UDPSocket (pour les datagrammes UDP) et InputStream (pour les flux TCP)?

Je suppose que ce ne serait pas trop difficile à faire compte tenu de l'API de rappel dans jpcap, mais a quelqu'un là-bas déjà fait? Y a-t-il des problèmes avec le faire (dois-je comprendre comment réassembler moi-même flux TCP, par exemple?)

Était-ce utile?

La solution

Je ne l'ai pas fait cette chose en particulier, mais je faire beaucoup de travail avec les paquets capturés d'analyse syntaxique en C / C ++. Je ne sais pas s'il existe des bibliothèques Java pour tout cela.

Pour l'essentiel, vous devez travailler votre chemin jusqu'à la pile de protocoles, en commençant par IP. Les données pcap commence par l'en-tête de niveau de lien, mais je ne pense pas qu'il y ait beaucoup à ce que vous êtes préoccupé par autre que d'ignorer les paquets non-IP.

La chose la plus délicate avec IP est Remontage de datagrammes fragmentés. On utilise pour cela le plus Fragments bit dans le champ Flags et le champ Fragment Offset, combiné avec le champ d'identification pour distinguer des fragments de différents datagrammes Ensuite, vous utilisez le champ Protocole pour identifier les paquets TCP et UDP, et le champ Longueur d'en-tête pour trouver la début de l'en-tête correspondant.

L'étape suivante, pour les protocoles TCP et UDP, est démultiplexage, en séparant les différentes connexions dans le flux de paquets capturés. Les deux protocoles identifier les connexions (bien, UDP ne dispose pas de connexions en soi, mais je ne dispose pas d'un meilleur mot à portée de main) par le 4-tuple de la source et l'adresse IP de destination et la source et le port de destination, de sorte qu'une connexion serait une séquence de paquets qui correspond à tous les 4 de ces valeurs.

Une fois cela fait, pour UDP, vous êtes sur le point de terminer, à moins que vous voulez vérifier la somme de contrôle. Le champ Longueur dans l'en-tête UDP vous indique combien de temps le paquet est; soustraire 8 octets pour l'en-tête et il y a vos données.

TCP est un peu plus compliquée, que vous avez en effet de remonter le cours d'eau, cela se fait à l'aide du numéro de séquence dans l'en-tête, combinée à la longueur. La somme de ces deux vous indique le numéro de séquence dans le flux. Rappelez-vous que vous garder une trace du trafic dans les deux sens.

(Ceci est beaucoup plus facile que d'écrire une implémentation TCP réelle, comme vous devez mettre en œuvre l'algorithme Nagle et d'autres menus détails.)

Il y a beaucoup d'informations sur le net sur les formats d'en-tête; google « en-tête IP » pour commencer. Un analyseur de réseau comme Wireshark est indispensable pour ce travail, car il vous montrera comment vos données capturées est censé regarder. En effet, comme Wireshark est open source, vous pouvez probablement trouver beaucoup de choses en regardant la façon dont il fait des choses

Autres conseils

réassemblage Tcp peut être fait avec JNetPcap . Voici un exemple complet:

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);
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top