TCP
libnetライブラリを使用してパケットを作成しようとしています。'0'
関数のチェックサム値の自動計算に使用しlibnet_build_tcp
ます。ただし、チェックサムは計算時にを無視してpseudo-header
いるため、チェックサムエラーのためにパケットが役に立たないようです。誰かがこれを解決する方法を知っていますか?
1 に答える
コードで確認できる限り、のパラメーターでlibnet_toggle_checksum(l, ptag, 1);
yourを使用していない限り、を呼び出してチェックサムを自動計算する必要があります。0
sum
libnet_build_tcp()
libnet_pblock_setflags(p, LIBNET_PBLOCK_DO_CHECKSUM)
解決方法を実際に説明することはできませんでしたが、パケットを作成しているのはあなたなので、独自のチェックサムを作成することを選択できますか?
TCP疑似ヘッダーは、それぞれ4バイトの送信元IPアドレスと宛先IPアドレスを含む12バイトのフィールド、2バイトで常にゼロに設定される予約済みフィールド、およびサイズに等しい4バイトのTCPセグメント長です。 TCPヘッダー+ペイロードの長さ。
次のようなものを作成できます。
まず、変数を作成します。
int bytesRead;
int pseudoHeaderLength;
int payloadLength;
int tcpHdrLength;
int tcpSegmentLength;
int ipHdrLength;
int headerLengths;
int ethIPHdrLengths;
struct ethhdr *ethHdr;
struct iphdr *ipHdr;
struct tcphdr *tcpHdr;
u_int8_t *pkt_data;
u_int8_t pseudoHeader[12];
u_int8_t packetBuffer[1600];
u_int16_t newChecksum;
次に、b-> lenがパケットの合計サイズである実際の関数を作成し(すべてのヘッダーとペイロードを追加して合計サイズを取得するだけです)、ヘッダーとデータをpkt_dataにmemcpyする必要があります。
ethHdr = (struct ethhdr*)pkt_data;
ipHdr = (struct iphdr*)(pkt_data + ETH_HLEN);
ipHdrLength = ipHdr->ihl * 4;
ethIPHdrLengths = ETH_HLEN + ipHdrLength;
tcpHdr = (struct tcphdr*)(pkt_data + ethIPHdrLengths);
tcpHdrLength = tcpHdr->doff * 4;
headerLengths = ethIPHdrLengths + tcpHdrLength;
payloadLength = b->len - headerLengths;
tcpSegmentLength = tcpHdrLength + payloadLength;
pseudoHeaderLength = tcpSegmentLength + 12;
pseudoHeader[0] = pkt_data[30];
pseudoHeader[1] = pkt_data[31];
pseudoHeader[2] = pkt_data[32];
pseudoHeader[3] = pkt_data[33];
pseudoHeader[4] = pkt_data[26];
pseudoHeader[5] = pkt_data[27];
pseudoHeader[6] = pkt_data[28];
pseudoHeader[7] = pkt_data[29];
pseudoHeader[8] = 0x00;
pseudoHeader[9] = 0x06;
pseudoHeader[10] = (tcpSegmentLength >> 8) & 0xFF;
pseudoHeader[11] = tcpSegmentLength & 0xFF;
bytesRead = 0;
for(i = 0; i < 12; i++) {
packetBuffer[bytesRead] = pseudoHeader[i];
bytesRead++;
}
for(i = ethIPHdrLengths; i < headerLengths; i++) {
packetBuffer[bytesRead] = pkt_data[i];
bytesRead++;
}
for(i = b->len - payloadLength; i < b->len; i++) {
packetBuffer[bytesRead] = pkt_data[i];
bytesRead++;
}
newChecksum = checksum((uint16_t *)packetBuffer, pseudoHeaderLength);
そして、https://www.rfc-editor.org/rfc/rfc1071によって提供されるチェックサム関数を使用して、バッファーのチェックサムを計算します。
uint16_t checksum(uint16_t *addr, int len)
{
int count = len;
register uint32_t sum = 0;
uint16_t answer = 0;
while (count > 1) {
sum += *(addr++);
count -= 2;
}
if (count > 0) {
sum += *(uint8_t *) addr;
}
while (sum >> 16) {
sum = (sum & 0xffff) + (sum >> 16);
}
answer = ~sum;
return (answer);
}
これを現実的な環境で使用して、500万PPSのチェックサムを計算します。