2008-09-16 13 views
19

私は初心者のC++プログラマー/ネットワーク管理者ですが、誰かが私を正しい方向に向けると、これを行う方法を学ぶことができます。チュートリアルのほとんどは、何らかの理由でもはや機能しなくなった古いコードを使って説明されています。C++でRAW TCP/IPパケットを作成するにはどうすればよいですか?

私はLinuxを使っているので、未加工のバークレーソケットを書く方法については説明が必要です。誰かが私に急いでダウンを与えることができますか?

+1

RAWソケットは非常にトリッキーで、異なるシステムでは少し異なります。私は、スニッファ(「wireshark」のような)をコードする人々や、やや難解な診断を知っている人のみを認識しています。彼らは確かにソケットプログラミングを学ぶのに良い場所ではありません。ほとんどの場合、「私はC++プログラマ/ネットワーク管理者の初めです」とは、「SOCK_RAWから離れる」ことを意味します。 –

+0

@ChuckKollars、私は同意しません。私は生のソケットを学ぶことはC++、特にCを学習する素晴らしい方法だと思います。ライブラリを使うことも一つですが、Linuxのrawソケットは非常に洞察力のある経験です。 C++は多くのユニークなことを行うことができます。私はあなたが暗示している心配を避けることが間違いだと思います。 – motoku

+0

あなたはどんなシステムを持っていますか? 「生の」ソケット実装は、あるシステムから次のシステムへとかなり異なっているので、あなたが学ぶもの(実際にはC++についてではなく、システムについてのほとんどが他の場所に持ち越されません)。 –

答えて

5

ネットワーク通信のための優れたクロスプラットフォーム(Linuxを含む)ライブラリであるAsioを使用することをお勧めします。

+1

UDPパケットを見たり、TCPパケットのように振る舞うことはできません。その2つのIPパケットヘッダーは相互に排他的です。 –

13

Beej's guide on socket programmingから開始してください。それは、ネットワークコードの作成を開始する方法をあなたにアップになります。その後、マニュアルページを読むことでより多くの情報を得ることができるはずです。

お気に入りのライブラリのマニュアルを読み、マニュアルページを基本的に理解することで構成されます。

1

これにはたくさんの参考文献がありますが(もちろん、スティーブンスの本が思い浮かぶようですが)、私はBeej guideが非常に便利であることを発見しました。実際に何が起こっているのかを理解するのに十分なだけの肉体ですが、単純なことで、「こんにちは世界」のクライアント/サーバーを書くのに数日かかることはありません。簡単

1

#include <sys/socket.h> 
#include <sys/types.h> 

int socket(int protocolFamily, int Type, int Protocol) 
// returns a socket descriptor 

int bind(int socketDescriptor, struct sockaddr* localAddress, unsigned int addressLength) 
// returns 0 

...など。

が、それはあなたが定期的にCの場合とまったく同じようにあなたがこれを行うのsys/socket.hに

3

ですべてです、何のC++標準ライブラリでこれを行うための具体的な方法はありません。

私がこれを学ぶのに使ったチュートリアルはhttp://beej.us/guide/bgnet/でした。それは私が周りを見て見つけた最高のチュートリアルでした、それはそれが説明するすべての機能の明確な例と良い説明を与えました。 TCPクライアント側の場合

6

:IPへのDNS名を検索する

使用のgethostbynameは、それはhostent構造体を返します。この戻り値のホストを呼び出してみましょう。

s = socket(AF_INET, SOCK_STREAM, 0); 
connect(s, (struct sockaddr *)&sock, sizeof(sock)) 

をTCPサーバ側の場合:

sockaddr_in sock; 
sock.sin_family = AF_INET; 
sock.sin_port = htons(REMOTE_PORT); 
sock.sin_addr.s_addr = ((struct in_addr *)(host->h_addr))->s_addr; 

が接続ソケットを作成し、呼び出します

hostent *host = gethostbyname(HOSTNAME_CSTR); 

は、ソケットアドレス構造体を記入

セットアップソケットを

バインドを使用してそのソケットにアドレスをバインドします。スタート聞く

コールして、そのソケット上で待機

は接続されたクライアントを取得するために受け入れます。 < - 接続を処理するために新しいスレッドを生成し、次の接続されたクライアントを取得するためにもう一度acceptを呼び出します。

総合通信:

使用送ると読み、クライアントとサーバの間の書き込みにrecvを。

BSDソケットのソースコードの例:

あなたはwikipediaで、このいくつかの良い例のコードを見つけることができます。

さらに読書:

私は非常にthis bookthis online tutorialをお勧めします。

alt text

4

+2

gethostbynameは、新しいプロジェクトには使用しないでください。IPバージョン(IPv4)に関連付けられています。 IPv4アドレスの残りの在庫が[急速に枯渇している](http://www.potaroo.net/tools/ipv4/index.html)ので、実際にはバージョンに依存しないgetaddrinfoを使うべきです(v4とv6で動作します) 。 – bortzmeyer

1

ポスター、あなたの質問に明確にしてください。

ほぼすべての回答は、あなたがソケットのチュートリアルを要求していると思われるようです。あなたの質問を読んで、任意のIPパケットを送信できるrawソケットを作成する必要があることを意味します。 私が前の答えで言ったように、いくつかのOSはrawソケットの使用を制限しています。

http://linux.die.net/man/7/raw「0の実効ユーザーIDプロセスか、CAP_NET_RAW権限を持つプロセスだけがrawソケットを開くことが許可されています。」

10

まず、「生」という意味を明確にすると便利です。伝統的にこれは、レイヤ4ヘッダー(TCP/UDP/ICMP ...ヘッダー)と、おそらくいくつかのIPヘッダーのすべてを自分で作成することを意味します。このためには、beejのチュートリアル以上のものが必要です。私の多くはすでにここに挙げられています。この場合、socketへの呼び出しでSOCK_RAW引数を使って取得したraw IPソケットが必要です(いくつかの基本についてはhttp://mixter.void.ru/rawip.htmlを参照してください)。

もしあなたが本当に望むのは、stackoverflow.com上のポート80のようなリモートホストへのTCP接続を確立することだけであれば、おそらく "生の"ソケットは必要なく、beejのガイドはうまく機能します。

この件に関する権威的な参考文献として、Stevens氏によるUnix Network Programming、Volume 1:The Sockets Networking API(第3版)を実際に取り上げるべきです。

1

Unix Network Programming Richard Stevensによると、それは絶対必要です。どのように動作するか、コードを提供し、ヘルパーメソッドを提供することさえも説明しています。彼の他の本のいくつかをチェックしたいかもしれません。 Advanced Programming In The Unix Enviernmentは、Unixにおける低レベルプログラミングのための必須項目です。私はもはやUnixスタック上のものをやっていないし、これらの本からのstufは、私がどのようにコードするかを助ける。

1

Libpcapは、完全なパケット(レイヤー2からレイヤー7)を作成し、それらをワイヤーを介して送信できるようにします。それが聞こえるほど面白くて、そこにはいくつかの注意点があります。すべての適切なヘッダーを作成し、すべてのチェックサムを自分で行う必要があります。しかし、Libnetはそれを助けることができます。

C++プログラミングプールから抜け出したい場合は、Python用にscapyがあります。 TCP/IPパケットを作成して送信するのは簡単です。

2

私は過去1年間にlibtinsを開発しています。それは高レベルのC + +のパケットを作成し、スニッフィングライブラリです。

ホイールを改造してすべてのプロトコルの内部を実装したいのでない限り、すでにそれを行う上位レベルのライブラリを使用することをお勧めします。

関連する問題