私は最近、libpcap &のLinux固有のライブラリとnetinet/tcp.hのようなヘッダを使ってパケットスニファを書き始めました。 問題は次のとおりです。TH_OFF(tcp)* 4を使用してtcpヘッダーを取得すると、値が20バイト未満になることがよくあります。うわー、私は知っています、それは不正な形式ですが、Wiresharkは他の値(20 <)を表示しています。同じことがフラグで起こります。ここでtcpヘッダーとフラグ
コードです:
struct nread_tcp {
u_short th_sport; /* source port */
u_short th_dport; /* destination port */
u_short th_seq; /* sequence number */
u_short th_ack; /* acknowledgement number */
#if BYTE_ORDER == LITTLE_ENDIAN
u_int th_x2:4, /* (unused) */
th_off:4; /* data offset */
#endif
#if BYTE_ORDER == BIG_ENDIAN
u_int th_off:4, /* data offset */
th_x2:4; /* (unused) */
#endif
u_char th_flags;
#define TH_FIN 0x01
#define TH_SYN 0x02
#define TH_RST 0x04
#define TH_PUSH 0x08
#define TH_ACK 0x10
#define TH_URG 0x20
#define TH_ECE 0x40
#define TH_CWR 0x80
#define TH_NS 0x100
#define TH_RS 0xE00
u_short th_win; /* window */
u_short th_sum; /* checksum */
u_short th_urp; /* urgent pointer */
u_char th_offx2; /* data offset, rsvd */
#define TH_OFF(th) (((th)->th_offx2 & 0xf0) >> 4)
};
const struct nread_tcp* tcp = (struct nread_tcp*)(pachet + sizeof(struct ether_header) + sizeof(struct crt_ip));
...
int hlen = TH_OFF(tcp)*4;
char * tmp = new char[strlen("000000000000")+1];
strcpy(tmp,"000000000000");
if (tcp->th_flags & TH_NS){
tmp[3] = '1';
}
else
tmp[3] = '0';
if (tcp->th_flags & TH_ECE){
tmp[4] = '1';
}
else
tmp[4] = '0';
if (tcp->th_flags & TH_CWR){
tmp[5] = '1';
}
else
tmp[5] = '0';
if (tcp->th_flags & TH_URG){
tmp[6] = '1';
}
else
tmp[6] = '0';
if (tcp->th_flags & TH_ACK){
tmp[7] = '1';
}
else
tmp[7] = '0';
if (tcp->th_flags & TH_PUSH){
tmp[8] = '1';
}
else
tmp[8] = '0';
if (tcp->th_flags & TH_RST){
tmp[9] = '1';
}
else
tmp[9] = '0';
if (tcp->th_flags & TH_SYN){
tmp[10] = '1';
}
else
tmp[10] = '0';
if (tcp->th_flags & TH_FIN){
tmp[11] = '1';
}
else
tmp[11] = '0';
私はそれをかなりググてきたし、有益な何かを見つけることがあります。多分それは別の初心者のエラーですが、私はそれを理解することはできません。 ありがとうございます。
もう一度、ヒント/アイデアをお寄せいただきありがとうございます。
リンクレイヤヘッダーの処理を含むすべてのpcap処理機能は正しいです。私のアプリはQt 4.7.4で書かれています。私の論理についてもう少し詳しく説明しましょう。おそらくI m using pointers that are not pointing correctly. I wish to emphasize the fact that tcp is the only protocol with this issue. The others that I
mは、イーサネットフレームヘッダ、IPヘッダ、UDPヘッダ、ARP/RARPヘッダ、ICMPヘッダを詳細に分析しています。 ロジックについては、次のようになります。 スレッド・ウィッチがあります。
-pcap_loop(captureHandler、-1、packetHandler、(unsigned char *)dumpfile); packetHandlerは "engine.cpp"という名前の別の.cppにあります。 .cppには、プロトコルタイプに応じてパケットインタープリタの魔法使いがあり、正しいクラス(TCPプロトコル用のtcpPacketHandler)をインスタンス化します。 私のtcp構造体は、tcpPacketHandlerヘッダーではなく、engine.hで宣言されています。 tcp構造体は私の最初の質問で掲示されたものです。 tcpPacketHandlerコンストラクタは次のようになります。私は、TCPヘッダデータの残りの部分にこの時点から
#define TH_OFF(th) (((th)->th_offx2 & 0xf0) >> 4)
「データフィールドのオフセット」ヒットまで
tcpPacketHandler::tcpPacketHandler(u_char *arg, const pcap_pkthdr * header,const u_char * pachet)
{
(void)arg;
(void)header;
const struct nread_tcp* tcp = (struct nread_tcp*)(pachet + sizeof(struct ether_header) + sizeof(struct crt_ip));
//fprintf(stdout,"\nSEQUENCE NUMBER %u \nACK %u \nWINDOW %u\nURGENT POINTER %u\n", tcp->th_seq, tcp->th_ack, tcp->th_win,tcp->th_urp);
//qDebug() <<sizeof(struct ether_header)<< " "<< sizeof(struct crt_ip);
this->seqNr = ntohs(tcp->th_seq);
this->ackNr = ntohs(tcp->th_ack);
this->window = ntohs(tcp->th_win);
this->urgentPointer = ntohs(tcp->th_urp);
this->portSursa = ntohs(tcp->th_sport);
this->portDestinatie = ntohs(tcp->th_dport);
this->checksum = ntohs(tcp->th_sum);
char * tmp = new char[strlen("000000000000")+1];
strcpy(tmp,"000000000000");
if (tcp->th_flags & TH_NS){
tmp[3] = '1';
}
else
tmp[3] = '0';
if (tcp->th_flags & TH_ECE){
tmp[4] = '1';
}
else
tmp[4] = '0';
if (tcp->th_flags & TH_CWR){
tmp[5] = '1';
}
else
tmp[5] = '0';
if (tcp->th_flags & TH_URG){
tmp[6] = '1';
}
else
tmp[6] = '0';
if (tcp->th_flags & TH_ACK){
tmp[7] = '1';
}
else
tmp[7] = '0';
if (tcp->th_flags & TH_PUSH){
tmp[8] = '1';
}
else
tmp[8] = '0';
if (tcp->th_flags & TH_RST){
tmp[9] = '1';
}
else
tmp[9] = '0';
if (tcp->th_flags & TH_SYN){
tmp[10] = '1';
}
else
tmp[10] = '0';
if (tcp->th_flags & TH_FIN){
tmp[11] = '1';
}
else
tmp[11] = '0';
this->hdrLen = TH_OFF(tcp)*4;
// qDebug() << this->hdrLen;
this->flags = new char[13];
strcpy(this->flags,tmp);
if(tmp)
{
delete [] tmp;
tmp = NULL;
}
}
すべてのTCPヘッダフィールドが正しく表示されますWiresharkの結果(Data offset、Flags、およびPayload)に対応していません。
nread_tcp構造体が複数のパケットで共有されるファイルで宣言され、短い間隔で多くのパケットをキャプチャするときにポインタが間違ってしまうことがあります。 私は本当に手掛かりがありません。 Googleで見つけたものはすべてこの構造体を使用しますが、私のコードではt know what
の問題はありません。 二次的な質問として、packetHandler関数(pcap_loop関数から)をクラスのメンバーとして宣言できますか? (私は型がないことに気づいたので、コンパイラでクラスメンバーにしようとするとエラーが出ました)。
ありがとうございます。
おかげで、しかし、あなたは、 'は、pcap_open_live()'、 'pcap_open_offlineを(呼び出した後' pcap_datalinkを() 'を呼び出す場合は、残念ながら結果は同じ:( – user1300795
です:
に変更します)、 'pcap_activate()'、どの値を返すのか、[tcpdump.org link-layer headers page](http:// www)に記述されているように、そのタイプのリンク層ヘッダーヘッダーを適切に処理していますか? .tcpdump.org/linktypes.html)? –