1

IP パケット ヘッダーを生成する C++ コードがあります。コードは、パケット内の各フィールドを表す構造体を使用します。

struct cip {
   uint8_t        ip_hl:4, /* both fields are 4 bytes */
                  ip_v:4;
   uint8_t        ip_tos;
   uint16_t       ip_len;
   uint16_t       ip_id;
   uint16_t       ip_off;
   uint8_t        ip_ttl;
   uint8_t        ip_p;
   uint16_t       ip_sum;
   struct in_addr ip_src;
   struct in_addr ip_dst;
   char       head[100];
};

ユーザーは、構造体の各変数の値を入力するように入力メッセージを求められます。

パケットを保存するファイル名を入力してください: packet

IP バージョン (0-15) を入力してください: 4

ヘッダーの長さを入力してください (5-15): 5

サービスの種類を入力してください (0-255): 55

パケットの合計サイズを入力してください (バイト、20、200): 25

パケットが作成され、ファイルに保存されます。

FILE* f = fopen(file, "w");
int success = fwrite(&packet, sizeof(char), ((unsigned int)packet.ip_hl)*4,f);
if(success <= 0) {
    printf("Error writing packet header");
}
success = fwrite(&data, sizeof(char),ntohs(packet.ip_len)-(4*packet.ip_hl),f);
if(success < 0) {
    printf("Error writing packet data");
}
fflush(f);
fclose(f);
printf("\nPacket Written.\n");

私はこのコードを作成しませんでした。誰かがコードをくれたので、上記のプログラムによって作成されたパケットを検証する他のプログラムを Python で作成できます。検証には、パケットに対して生成されたチェックサム、IP パケットのバージョン、プロトコル、ヘッダーの長さなどの検証が含まれます。

だから、誰かがファイルを読んでフレームを解析する方法を理解するのを手伝ってくれるかどうか知りたい. ファイル内の行を文字列として読み取ろうとしましたが、問題は、作成後にファイルが次のようになることです: (読み取れません)

O È , @ šÀ¨À¨ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxDATA_ _ _ _ _ _ _ _ __ _ _ _ _ _ _ _ _ _ _ _ __ _ __ ô ·

理由がわかりません:(これは、1バイトより大きい変数が関数「htons」によってビッグエンディアンに変換されるためだと推測しています:

printf("\nEnter ip ID number(0-65535):\n");
scanf("%d", &input);
packet.ip_id = htons(input);

これをsocket.makefile()で処理する別のオプションを検索しようとしましたが、これは私のプログラムのソケットをファイルとして支援しますが、私がする必要があるのは、このファイルで私に与えられたフレームを解析することです.

何か案は?

ありがとう。

PS: また、Python で整数をビッグ エンディアンからスモール エンディアンに、またはその逆に変換する方法を見つけることができるリンクを教えてください。ありがとう!

4

1 に答える 1

1

通常どおりファイルを読み取る必要があります (Windows の場合は「バイナリ」モードを指定します)。

with open("test.txt", 'br') as f:
    for line in f.readlines():
        # process lines

バイナリ データをアンパックするには、ビッグ エンディアンやリトルエンディアンstructなども処理できるパッケージを使用する必要があります。構造体の例:

print struct.unpack('BBHHHBBH100s', line)

構造体の内容を指定していないため、省略ip_srcして解凍しました。ip_dst読み取ることができる最小値は 1 バイトであるため、最初のフィールドを 2 つの部分に分割するには、次を使用できます。

(ip_hl, ip_v) = (value >> 4, value & 15)

もちろん、8 ビット コンポーネントの順序は構造体のエンディアンに依存します。

于 2013-05-06T06:25:41.960 に答える