web-dev-qa-db-ja.com

C ++でRAWTCP / IPパケットを作成するにはどうすればよいですか?

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

私はLinuxを使用しているので、必要なのは生のバークレーソケットの書き方の説明だけです。誰かが私に簡単な要約を与えることができますか?

19
Tim

読むことから始めます ソケットプログラミングに関するBeejのガイド 。これにより、ネットワークコードの記述を開始する方法を理解できます。その後、manページを読むことでより多くの情報を得ることができるはずです。

そのほとんどは、お気に入りのライブラリのドキュメントを読むことと、manページの基本的な理解で構成されます。

13
X-Istence

手始めに、「生」の意味を明確にすると便利です。従来、これは、すべてのレイヤー4ヘッダー(TCP/UDP/ICMP ...ヘッダー)と、場合によっては一部のIPヘッダーを独自に作成することを意味します。このためには、すでにここで私の多くに言及されているbeejのチュートリアル以上のものが必要になります。この場合、ソケットの呼び出しでSOCK_RAW引数を使用して生のIPソケットを取得する必要があります(いくつかの基本については http://mixter.void.ru/rawip.html を参照してください)。

本当に必要なのが、stackoverflow.comのポート80などのリモートホストへのTCP接続を確立できるようにすることだけである場合は、「raw」ソケットやbeejはおそらく必要ありません。ガイドはあなたによく役立ちます。

このテーマに関する信頼できる参考資料として、Stevens etalによるUnixNetwork Programming、Volume 1:The Sockets Networking API(3rd Edition)を実際に入手する必要があります。

10
Chris

TCPクライアント側:

Gethostbynameを使用してDNS名をIPに検索すると、hostent構造が返されます。この戻り値をHostと呼びましょう。

hostent *Host = gethostbyname(HOSTNAME_CSTR);

ソケットアドレス構造を入力します。

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;

ソケットを作成し、connectを呼び出します。

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

TCPサーバー側:

ソケットを設定する

Bindを使用して、アドレスをそのソケットにバインドします。

そのソケットでlistenを使って聞き始めます

Acceptを呼び出して、接続されたクライアントを取得します。 <-この時点で、接続を処理するための新しいスレッドを生成し、次に接続されたクライアントを取得するために別の呼び出しを行って受け入れます。

一般的なコミュニケーション:

Sendとrecvを使用して、クライアントとサーバー間で読み取りと書き込みを行います。

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

この良いサンプルコードは wikipedia にあります。

さらに読む:

私は強くお勧めします この本このオンラインチュートリアル

alt text

4

6
Brian R. Bondy

開始するのに適した場所は、ネットワーク通信用の優れたクロスプラットフォーム(Linuxを含む)ライブラリである Asio を使用することです。

5
Tom Leys

これは通常のCの場合とまったく同じ方法で行います。標準ライブラリでは、これを行うC++固有の方法はありません。

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

3
HappySmileMan

私はこの1年間、 libtins を開発してきました。これは、高レベルのC++パケット作成およびスニッフィングライブラリです。

車輪の再発明を行い、すべてのプロトコルの内部を実装したい場合を除いて、すでにそれを行っている高レベルのライブラリを使用することをお勧めします。

2
mfontanini

読む nix Network Programming リチャードスティーブンス著。それは絶対必要です。それはすべてがどのように機能するかを説明し、コードを提供し、さらにヘルパーメソッドも提供します。あなたは彼の他の本のいくつかをチェックしたいかもしれません。 nix環境での高度なプログラミング は、Unixでの低レベルのプログラミングには必須です。私はもうUnixスタックで何もしていません、そしてこれらの本からのstufはまだ私がコーディングする方法を助けます。

1
Charles Graham

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

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

1
jdizzle

これについてはたくさんの参考文献がありますが(もちろん、スティーブンスの本が思い浮かびます)、 Beejガイド を始めるのに非常に役立つことがわかりました。実際に何が起こっているのかを理解できるほど肉厚ですが、「helloworld」udpクライアント/サーバーを作成するのに数日もかからないほど単純です。

1
Ben Collins

簡単:

#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 

...等。

それはすべてsys/socket.hにあります

1
vimm

ポスター、質問を明確にしてください。

ほとんどすべての応答は、ソケットのチュートリアルを求めていると考えているようです。私はあなたの質問を読んで、任意のIPパケットを送信できるrawソケットを作成する必要があることを意味します。以前の回答で述べたように、一部のOSはrawソケットの使用を制限しています。

http://linux.die.net/man/7/raw "有効なユーザーIDが0またはCAP_NET_RAW機能を持つプロセスのみがrawソケットを開くことができます。"

1
Mike F