6

最近、Jnetpcapを使用してネットワーク経由で生のパケットを送受信しています。

Jnetpcapは、によるパケットの送信を提供しますPcap.sendPacket()。このメソッドは、送信するrawバッファーまたはバイトを取得します。

一方、org.jnetpcap.protocol.*プロトコルヘッダーをラップするクラスがあり、それらを使用してキャプチャされたパケットをデコードできます。

以下のコードを使用してIp4パケットを作成すると、NullPointerExceptionが発生します。

import org.jnetpcap.protocol.network.Ip4;

public class Test {

    public static void main(String[] args) {

        Ip4 ip4 = new Ip4();

        ip4.ttl(10);

    }
}

エラー:

Exception in thread "main" java.lang.NullPointerException
    at org.jnetpcap.nio.JBuffer.check(Unknown Source)
    at org.jnetpcap.nio.JBuffer.setUByte(Unknown Source)
    at org.jnetpcap.protocol.network.Ip4.ttl(Unknown Source)
    at jaeger.Test.main(Test.java:17)

どうすればそのパケットを作成してから送信できPcap.sendPacket()ますか?

注:パケットをバイト単位で準備することにはあまり興味がありません... C / C ++ libpcapとJpcapには機能がありますが、Jnetpcapを使用したいと思います。

4

2 に答える 2

9

1)ライブラリの主な目的はキャプチャされたパケットのバッファを分析することであるため、ラッパークラスは以前に割り当てられたバッファを使用してのみ機能するため、コードは例外をスローします。そのため、使用する前にバッファを割り当てる必要があります。

2)パケットは、必要なすべてのバイトを供給して構築する必要があります。ただし、実際に必要なのは数バイトだけになるようにコードを記述できます(上記を参照)。

3) sendPacketパケット全体、完全なイーサネットフレームを想定しています。したがって、イーサネット、IP、TCPヘッダー、およびペイロードをバッファーに書き込む必要があります。

4)ラッパークラスを使用できるようにするための主なアイデアは、バッファーを割り当て、ライブラリをスキャンしてヘッダーを検出することですが、最小限の情報(バイト)を提供する必要があります。

JMemoryPacket packet = new JMemoryPacket(packetSize);
packet.order(ByteOrder.BIG_ENDIAN); 

イーサネットフレームには、位置12にプロトコルタイプ(0x0800)が必要です。

packet.setUShort(12, 0x0800);
packet.scan(JProtocol.ETHERNET_ID); 

その後scan、イーサネットインスタンスを取得し、セッターを使用できます。

Ethernet ethernet = packet.getHeader( new Ethernet() );  
ethernet.destination(...);
...

IP4ヘッダーには、位置14にバージョン(0x04)とサイズ(0x05)が必要です。

packet.setUByte(14, 0x40 | 0x05);
packet.scan(JProtocol.ETHERNET_ID);  

Ip4 ip4 = packet.getHeader( new Ip4() );
ip4.type(0x06); //TCP
ip4.length( packetSize - ethernet.size() );
ip4.ttl(...);  
...

TCPヘッダーにはサイズ(0x50)が必要です:

packet.setUByte(46, 0x50);
packet.scan(JProtocol.ETHERNET_ID);  

Tcp tcp = packet.getHeader( new Tcp() );  
tcp.seq(...); 
...

したがって、ペイロード:

Payload payload = packet.getHeader( new Payload() );
payload.set...(...);
...

そして最後に:

pcap.sendPacket( ByteBuffer.wrap( packet.getByteArray(0, packet.size() )  );

5)必要なすべてのバイトを一度に書き込むことができるため、scanメソッドへの呼び出しが非常に多くなるのを防ぐことができます。

于 2012-02-27T22:58:00.617 に答える
1

jNetPcapでサブヘッダーを作成する方法の問題に直面していますか?はい、JNetPcapは送信にバイトを取りますが、私が提供した支援により、コンテンツをサブヘッダーで埋めることができます。その後、パケット内でデータを送信する場合、多くのJavaタイプにはtoBytes()関数などがあります。

編集:
その特定のIcmpクラスのAPIはここにあります。同様に、指定されたリンク上の他のクラスに対しても実行できます。Googleを開いて、「Icmpclassreferencejnetpcap」などのヘッダータイプを指定するだけです。

edit2:
ICMPパケットを作成する簡単な方法は、ICMPパケットの単純なコンストラクターを持つICMPPacketクラスを使用することです。このクラスでは、ヘッダーが1回のコンストラクター呼び出しで作成されます。クラスリファレンスによると、次のようになります。

IPパケットを拡張し、ICMPヘッダーとICMPデータペイロードを追加します。

于 2011-11-19T16:49:36.610 に答える