2008-09-16 4 views
19

Ich bin ein Anfänger C++ Programmierer/Netzwerkadministrator, aber ich denke, ich kann lernen, wie das geht, wenn mir jemand in die richtige Richtung zeigt. Die meisten Tutorials werden mit altem Code demonstriert, der aus irgendeinem Grund nicht mehr funktioniert.Wie erstelle ich RAW TCP/IP-Pakete in C++?

Da ich auf Linux bin, brauche ich nur eine Erklärung, wie man rohe Berkeley-Sockel schreibt. Kann mir jemand einen schnellen Run geben?

+1

RAW-Buchsen sind sehr schwierig und unterscheiden sich auf verschiedenen Systemen ein wenig. Ich kenne nur Leute, die sie benutzen, um Sniffer zu codieren (wie 'wireshark') und einige ziemlich arkane Diagnosen. Sie sind sicherlich kein guter Ort, um Socket-Programmierung zu lernen. In den meisten Fällen bedeutet "Ich bin ein beginnender C++ Programmierer/Netzwerkadministrator" bedeutet "Bleib weg von SOCK_RAW". –

+0

@ChuckKollars, stimme ich nicht zu. Ich denke, rohe Sockets zu lernen ist eine großartige Möglichkeit, C++ zu lernen, und besonders C. Eine Bibliothek zu benutzen ist eine Sache, aber rohe Sockets mit Linux sind eine sehr aufschlussreiche Erfahrung. C++ kann so viele einzigartige Dinge tun. Ich denke, es ist ein Fehler, den Herzschmerz zu vermeiden, den du implizierst. – motoku

+0

Welches System haben Sie genau? "Raw" Socket-Implementierungen unterscheiden sich erheblich von einem System zum nächsten, so dass das, was Sie lernen (wirklich hauptsächlich über das System, nicht über C++), nicht anderswo übertragen wird. –

Antwort

5

Ein guter Ausgangspunkt wäre Asio, eine großartige plattformübergreifende (inkl. Linux) Bibliothek für die Netzwerkkommunikation.

+1

Sie können niemals ein UDP-Paket so aussehen lassen oder sich wie ein TCP-Paket verhalten - die IP-Paket-Header für die beiden schließen sich gegenseitig aus. –

13

Beginnen Sie mit dem Lesen Beej's guide on socket programming. Sie erfahren, wie Sie mit dem Schreiben von Netzwerkcode beginnen können. Danach sollten Sie in der Lage sein, immer mehr Informationen vom Lesen der man-Seiten zu bekommen.

Die meisten davon werden das Lesen der Dokumentation für Ihre Lieblingsbibliothek und ein grundlegendes Verständnis von man-Seiten enthalten.

1

Es gibt Tonnen von Verweisen darauf (natürlich kommt Stevens 'Buch in den Sinn), aber ich fand die Beej guide, um unglaublich nützlich für den Anfang zu sein. Es ist fleischig genug, dass Sie verstehen können, was wirklich passiert, aber es ist einfach genug, dass Sie nicht mehrere Tage brauchen, um einen "Hallo Welt" udp Client/Server zu schreiben.

1

einfach:

#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 

... etc.

es ist alles in sys/socket.h

3

Sie tun dies genau die gleiche Art und Weise Sie sich in regelmäßigen C, gibt es keine C++ spezifische Art und Weise dies in der Standardbibliothek zu tun.

Das Tutorial, das ich für das Lernen verwendete, war http://beej.us/guide/bgnet/. Es war das beste Tutorial, das ich gefunden habe, nachdem ich mich umgeschaut hatte, es gab klare Beispiele und gute Erklärungen für alle Funktionen, die es beschreibt.

6

Für TCP Client-Seite:

Verwenden gethostbyname DNS-Namen zu IP-Lookup, wird es eine hostent Struktur zurück. Nennen wir diesen zurückgegebenen Werthost.

hostent *host = gethostbyname(HOSTNAME_CSTR); 

die Struktur Socket-Adresse, geben Sie bitte:

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; 

einen Socket erstellen und rufen Sie an:

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

Für TCP Server-Seite:

Einrichtung eine Buchse

Binden Sie Ihre Adresse mit Bind an diesen Socket.

Beginnen Sie mit auf diesem Sockel hören hören

Anruf einen angeschlossenen Client bekommen akzeptieren. < - An dieser Stelle spawnen Sie einen neuen Thread, um die Verbindung zu handhaben, während Sie einen weiteren Anruf tätigen, um den nächsten verbundenen Client zu akzeptieren.

Allgemeine Kommunikation:

Verwenden Sende- und recv lesen und zwischen dem Client und dem Server zu schreiben.

Quellcode Beispiel für BSD-Sockets:

Sie können einige gute Beispiel-Code von diesem Baby in wikipedia finden.

Weiterführende Literatur:

ich sehr empfehlen this book und this online tutorial:

alt text

4:

+2

gethostbyname sollte nicht mehr für ein neues Projekt verwendet werden: Es ist an eine IP-Version (IPv4) gebunden. Jetzt, da der Restbestand an IPv4-Adressen [schnell erschöpft] ist (http://www.potaroo.net/tools/ipv4/index.html), sollten Sie getaddrinfo verwenden, das versionsunabhängig ist (funktioniert mit v4 und v6). . – bortzmeyer

1

Plakat, geben Sie bitte Ihre Frage klären.

Fast alle Antworten scheinen zu denken, dass Sie nach einem Sockets-Tutorial fragen; Ich habe Ihre Frage gelesen, dass Sie einen Raw-Socket erstellen müssen, der beliebige IP-Pakete senden kann. Wie ich bereits in meiner vorherigen Antwort gesagt habe, beschränken einige Betriebssysteme die Verwendung von rohen Sockets.

http://linux.die.net/man/7/raw "Nur Prozesse mit einer effektiven Benutzer-ID von 0 oder der Funktion CAP_NET_RAW dürfen Raw-Sockets öffnen."

10

Für den Anfang wäre es hilfreich, wenn Sie klarstellen, was Sie mit "roh" meinen. Traditionell bedeutet dies, dass Sie alle Layer-4-Header (TCP/UDP/ICMP ... Header) und vielleicht einige der IP-Header selbst erstellen möchten. Dafür benötigst du mehr als beejs Tutorial, von dem schon viele hier erwähnt wurden. In diesem Fall möchten Sie, dass rohe IP-Sockets mit dem SOCK_RAW-Argument in Ihrem Aufruf an Socket erhalten werden (für einige Grundlagen siehe http://mixter.void.ru/rawip.html).

Wenn Sie wirklich nur eine TCP-Verbindung zu einem entfernten Host wie Port 80 auf stackoverflow.com herstellen möchten, dann brauchen Sie wahrscheinlich keine "rohen" Sockets und der beej's Guide wird Ihnen gut helfen .

Für eine maßgebliche Referenz zu diesem Thema sollten Sie wirklich Unix Network Programming, Volume 1: Die Sockets Networking API (3. Edition) von Stevens et al.

1

Lesen Unix Network Programming von Richard Stevens. Es ist ein Muss. Es erklärt, wie alles funktioniert, gibt Ihnen Code und gibt Ihnen sogar Hilfsmethoden. Vielleicht möchten Sie einige seiner anderen Bücher überprüfen. Advanced Programming In The Unix Enviernment ist ein Muss für die Programmierung der unteren Ebene in Unix ist allgemein. Ich mache nicht mal mehr Sachen auf dem Unix-Stack, und der Stuff aus diesen Büchern hilft mir immer noch, wie ich code.

1

Libpcap können Sie komplette Pakete (Layer2 bis Layer 7) fertigen und senden sie über die Leitung. So lustig das klingt, es gibt einige Vorbehalte. Sie müssen alle geeigneten Header erstellen und alle Checksummen selbst durchführen. Libnet kann aber dabei helfen.

Wenn Sie aus dem C++ - Programmierpool aussteigen möchten, gibt es scapy für Python. Es macht es trivial, TCP/IP-Pakete herzustellen und zu übertragen.

2

Ich habe libtins für das vergangene Jahr entwickelt.Es ist eine High-Level C++ Packet Crafting und Sniffing-Bibliothek.

Sofern Sie das Rad nicht neu erfinden und die Interna jedes Protokolls implementieren möchten, empfehle ich Ihnen, eine höhere Bibliothek zu verwenden, die das bereits für Sie erledigt.