0

C言語のスニファプログラムがあります。ソース IP と宛先 IP のペアごとにキャッチされたパッケージ (パケット) の数を記録するリストがあります。私がそのようなパッケージを手に入れたように:

[192.168.1.1] -> [192.168.1.2] Total package amount:[100]
[192.168.1.3] -> [192.168.1.4] Total package amount:[100]
[192.168.1.4] -> [192.168.1.3] Total package amount:[100]

私の構造は次のとおりです。

 struct node {
  u_char s_ip[16];        //source IP
  u_char d_ip[16];        //destination IP
  u_int32_t package_amount;   //Would be sum
  struct node *next;
};
struct node *head;      
struct node *search;      //(1)position (2)for new malloc
struct node *tail;

しかし、ご存じのように、TCP と UDP にはポートがあるため、構造体にポート フィールドを追加すると、次のようになります。

struct tu_node {
  u_char s_ip[16];        //source IP
  u_char d_ip[16];        //destination IP
  u_int32_t s_port;      //source port
  u_int32_t d_port;      //destination port
  u_int32_t package_amount;   
  struct node *next;
};
struct tu_node *tu_head;         // tu means tcp and udp
struct tu_node *tu_search;    
struct tu_node *tu_tail;  

私のスニファーは TCP と UDP しか解析できないという制限がありますが、s_ip と d_ip のペアごとに不明なプロトコル パッケージの量を出力したいと考えています。ご覧のとおり、ポート フィールド (s_port および d_port) は未知のプロトコルには適用されません。私にとって簡単な方法は、次のような新しい構造体を定義することです。

struct unknown_node {
  u_char s_ip[16];        //source IP
  u_char d_ip[16];        //destination IP
  u_int32_t package_amount;   
  struct node *next;
};
struct unknown_node *unknown_head;      
struct unknown_node *unknown_search;      
struct unknown_node *unknown_tail;  

今、私は問題を抱えています。私は 2 つの異なる構造を持っているので、基本的にリスト操作 (head、search、tail) を処理するには 2 つの異なる関数が必要です。

では、構造を再設計/リファクタリングする方法について考えるのを手伝ってくれる人や、リスト関数をリファクタリングして良い設計にするポイントを教えてくれる人はいますか?


これまでのところ、可能性が高いが不明な方法が 2 つあります。

  1. 1 つは、d_port と s_port に対応するため#ifに(最初のコード スニペット) のようなものを使用することです。struct nodeしかし、スニファーは実行時に TCP と UDP しか認識していないため、実現可能ではないと思いますが、#ifディレクティブはコンパイル時に修正する必要があります。
  2. 2 つ目は、互換性のある「struct tu_node」と「struct unknown_node」の両方に「overload」機能を実装する方法を考えることです。しかし、C言語はできないようです。
4

1 に答える 1

0

C はオーバーロードをサポートしていないため、C++ がサポートする C のサブセットを使用するという2 番目の質問に答えがあると思います。そのサブセットはオーバーロードを許可します。

または、両方のタイプの構造体を処理できる関数を作成します。これは ANSI C では不可能であるため、構造体定義で両方のプロトコルをサポートし、どちらが使用されているかを判断することをお勧めします。

3 つ目の最後のオプションは、ライブラリを使用することです。これが課題ではない場合は、同様の実装を研究することに加えて、そのような目的のために設計されたライブラリを使用することを強くお勧めします。

頭に浮かぶのは、tcpdump および libcapライブラリーです。

http://www.tcpdump.org/

なぜ第三者の提案なのですか?衒学的に聞こえるつもりはありませんが、学術的な演習や主に自己学習のためでない限り、独自のライブラリを展開するよりも、可能であればライブラリを使用することをお勧めします (そうする理由がない限り)。時間はあなたの最も重要な資産です。それをどのように使用するかについて効率的である必要があります。

tcpdump と libcap を検討する価値があるかどうかを確認するために調べることができるいくつかの例を次に示します com/2010/10/create-your-own-packet-sniffer-in-c.html?q=sniffer

幸運を!

于 2013-07-16T04:27:06.163 に答える