2011-07-14 1 views
2

私は私program.Since内のIPヘッダフィールドの値を知っておく必要がありますするプログラムを開発していたIPヘッダは20バイトである:CプログラムのLinux IPスタックからIPヘッダフィールドの値を取得するための

struct ipheader { 

    unsigned char ip_hl:4, ip_v:4; /* this means that each member is 4 bits */ 
    unsigned char ip_tos; 
    unsigned short int ip_len; 
    unsigned short int ip_id; 
    unsigned short int ip_off; 
    unsigned char ip_ttl; 
    unsigned char ip_p; 
    unsigned short int ip_sum; 
    unsigned int ip_src; 
    unsigned int ip_dst; 
    }; 

私のCプログラムの中にこれらのフィールドの値がわかる方法はありますか?

+0

あなたはどのようにすでに利用可能なパケットからフィールドを解析するために不思議に思っている、またはどのように最初にヘッダを含むパケットを捕捉することを場所? –

+1

[libpcap](http://www.tcpdump.org/)を見てみることをお勧めします。あなたの人生を楽にするはずです。 –

+0

クエリは、シンプルなデータグラムパケット(UDP)を作成している間に、SrcIPとポート、DEst IPアドレスとポートを作成してパケットを送信し、残りの値がデフォルトでシステムstack.so私は残りのフィールドの値を知りたいと思う:例えば、ttl、tos等 – sumant

答えて

1

その構造内の任意のアライメントブロックを導入していない、あなたのコンパイラが、あるとして、あなただけの、あなたのコードに含めることができるはずです(CHAR_BITは8とsizeof(struct ipheader)が20であることを確認してください)、その後のような何かを追加提供:

そのコードで
struct ipheader *iph = (struct ipheader *)blk; 
printf ("TTL = %d\n", iph->ip_ttl); 

、あなたはおそらくchar*あるblkによって指さIPヘッダを、持っています。正しいポインタタイプにキャストすると、フィールドに簡単にアクセスできます。

次の完全なプログラムは、この動作を示している:予想通り

#include <stdio.h> 
#include <limits.h> 

struct ipheader { 
    /* 0 */ unsigned char ip_hl:4, ip_v:4; 
    /* 1 */ unsigned char ip_tos; 
    /* 2 */ unsigned short int ip_len; 
    /* 3 */ unsigned short int ip_id; 
    /* 4 */ unsigned short int ip_off; 
    /* 5 */ unsigned char ip_ttl; 
    /* 6 */ unsigned char ip_p; 
    /* 7 */ unsigned short int ip_sum; 
    /* 8 */ unsigned int ip_src; 
    /* 9 */ unsigned int ip_dst; 
}; 

int main (void) { 
    char blk[] = { 
     '\x00','\x11','\x22','\x22','\x33','\x33','\x44','\x44', 
     '\x55','\x66','\x77','\x77','\x88','\x88','\x88','\x88', 
     '\x99','\x99','\x99','\x99' 
    }; 
    struct ipheader *iph = (struct ipheader *)(&blk); 

    printf ("TTL = %x\n", iph->ip_ttl); 
    printf ("sum = %x\n", iph->ip_sum); 
    printf ("dst = %x\n", iph->ip_dst); 

    return 0; 
} 

出力される。これらの値の

TTL = 55 
sum = 7777 
dst = 99999999 
+0

基本的に私が提供した構造は参考のためのものであり、実際のクエリは単純なデータグラムパケット(UDP)私はSrcIPとポート、DEst IPアドレスとポートを入力してパケットを送信し、残りの値はデフォルトでシステムスタックに格納されます。残りの値にはip_ttl、ip_tosなどが含まれます – sumant

1

一部がSOL_IP/IPPROTO/IPレベルでsetsockopt()/getsockopt()呼び出しを介して取得/設定することができます。 OSのマニュアルを参照してください(例:Linux man 7 ip)。

0

setsockopt/getsockoptルーチンを使用して、ソケットメカニズムとインターフェイスする必要があります。これらの機能は異なるレベルで動作し(IPPROTO_IPIPPROTO_TCPなど)、一部のオプションは特定のソケットタイプでのみ使用できます(たとえば、IP_TTLAF_INETソケットの場合のみ利用可能です)。

は、TTLの値を取得する:

int sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); 
unsigned int opt_val;               
unsigned int opt_len;              
getsockopt(sock, IPPROTO_IP, IP_TTL, &opt_val, &opt_len); 
printf("ttl %d\n", opt_val); 

セットのTTL値:

int sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); 
unsigned char ttl_val = 32;                                   
setsockopt(sock, IPPROTO_IP, IP_TTL, &ttl_val, sizeof(ttl_val)); 
関連する問題