2008-09-16 14 views
19

Soy un programador de C++/administrador de red comienzo, pero calculo que puedo aprender cómo hacer esto si alguien me apunta en la dirección correcta. La mayoría de los tutoriales se demuestran utilizando un código antiguo que ya no funciona por algún motivo.¿Cómo creo paquetes RAW TCP/IP en C++?

Desde que estoy en Linux, todo lo que necesito es una explicación sobre cómo escribir conectores de Berkeley primas. ¿Alguien puede darme una carrera rápida?

+1

Los conectores RAW son muy complicados y son un poco diferentes en diferentes sistemas. Solo estoy al tanto de personas que los usan para codificar sniffers (como 'wireshark') y algunos diagnósticos bastante arcanos. Ciertamente no son un buen lugar para comenzar a aprender la programación de socket. En la mayoría de los casos, "soy un programador/administrador de red de C++ que comienza" significa "mantenerse alejado de SOCK_RAW". –

+0

@ChuckKollars, no estoy de acuerdo. Creo que aprender sockets sin procesar es una gran manera de aprender C++, y especialmente C. Usar una biblioteca es una cosa, pero los sockets crudos con Linux son una experiencia muy perspicaz. C++ puede hacer muchas cosas únicas. Creo que evitar el dolor de corazón que implica es un error. – motoku

+0

¿Qué sistema exactamente tienes? Las implementaciones de socket "en bruto" difieren considerablemente de un sistema a otro, por lo que lo que aprende (en realidad, más que todo sobre el sistema, no sobre C++) no se traslada a otro lado. –

Respuesta

5

Un buen lugar para comenzar sería usar Asio que es una gran biblioteca multiplataforma (incluso Linux) para la comunicación de red.

+1

Nunca puede hacer que un paquete UDP se vea o se comporte como un paquete TCP; los encabezados de paquetes IP para los dos son mutuamente exclusivos. –

13

de inicio mediante la lectura de Beej's guide on socket programming. Le informará sobre cómo comenzar a escribir código de red. Después de eso, debería poder obtener más y más información leyendo las páginas man.

La mayor parte consistirá en la lectura de la documentación de la biblioteca favorita, y una comprensión básica de las páginas man.

1

Hay toneladas de referencias sobre esto (por supuesto, el libro de Stevens me viene a la mente), pero encontré que el Beej guide es increíblemente útil para comenzar. Es lo suficientemente sustancioso como para que puedas entender lo que realmente está sucediendo, pero es lo suficientemente simple como para que no te tome varios días escribir un cliente/servidor udp "hello world".

1

fácil:

#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.

todo está en sys/socket.h

3

Esto se hace de la misma manera lo haría en C regular, no hay C++ manera específica de hacer esto en la biblioteca estándar.

El tutorial he usado para el aprendizaje de esta era http://beej.us/guide/bgnet/. Fue el mejor tutorial que encontré después de mirar alrededor, dio ejemplos claros y buenas explicaciones de todas las funciones que describe.

6

Por el lado del cliente TCP:

Uso Gethostbyname a las operaciones de búsqueda de nombres DNS para IP, devolverá una estructura hostent. Llamemos a este host de valor devuelto.

hostent *host = gethostbyname(HOSTNAME_CSTR); 

llenar la estructura dirección de socket:

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; 

crear un socket y Conexión de llamada:

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

Por el lado del servidor TCP:

instalación de una toma de

vincular a su dirección a ese socket usando bind.

empezar a escuchar en ese socket con escuchar

aceptación de llamada para conseguir un cliente conectado. < - en este punto genera un nuevo hilo para manejar la conexión mientras realiza otra llamada para aceptar y obtener el próximo cliente conectado.

Comunicación general:

Uso de envío y recv para leer y escribir entre el cliente y el servidor.

ejemplo de código fuente de sockets BSD:

Se puede encontrar un buen código de ejemplo de esto en wikipedia.

Más información:

recomiendo altamente this book y this online tutorial:

alt text

4:

+2

gethostbyname ya no se debe usar para un nuevo proyecto: está vinculado a una versión de IP (IPv4). Ahora que el stock restante de direcciones IPv4 está [agotando rápidamente] (http://www.potaroo.net/tools/ipv4/index.html), realmente debería usar getaddrinfo, que es independiente de la versión (funciona con v4 y v6) . – bortzmeyer

1

cartel, por favor aclarar su pregunta.

Casi todas las respuestas parecen pensar que estás pidiendo un tutorial de sockets; Leí su pregunta en el sentido de que necesita crear un socket sin formato capaz de enviar paquetes IP arbitrarios. Como dije en mi respuesta anterior, algunos sistemas operativos restringen el uso de conectores sin formato.

http://linux.die.net/man/7/raw "Solo los procesos con un ID de usuario efectivo de 0 o la capacidad CAP_NET_RAW pueden abrir tomas sin procesar."

10

Para empezar, sería útil si aclaras lo que quieres decir con "crudo". Tradicionalmente esto significa que desea crear todo el encabezado de capa 4 (encabezado TCP/UDP/ICMP ...) y tal vez parte del encabezado IP por su cuenta. Para esto necesitarás más que el tutorial de beej, que ya mencioné aquí mis muchos. En este caso, desea obtener los zócalos IP sin procesar utilizando el argumento SOCK_RAW en su llamada al socket (consulte http://mixter.void.ru/rawip.html para algunos conceptos básicos).

Si lo que realmente desea es establecer una conexión TCP con un host remoto como el puerto 80 en stackoverflow.com, entonces probablemente no necesite conectores "crudos" y la guía de beej le servirá bien. .

Para obtener una referencia autorizada sobre el tema, realmente debe elegir Unix Network Programming, Volume 1: The Sockets Networking API (3rd Edition) de Stevens et al.

1

Lee Unix Network Programming por Richard Stevens. Es un deber. Explica cómo funciona todo, te da código e incluso te brinda métodos de ayuda. Es posible que desee revisar algunos de sus otros libros. Advanced Programming In The Unix Enviernment es una necesidad para la programación de nivel inferior en Unix es general. Ni siquiera hago cosas en la pila de Unix, y el material de estos libros aún me ayuda a codificar.

1

Libpcap le permitirá elaborar paquetes completos (layer2 a layer 7) y enviarlos a través del cable. Aunque suena divertido, hay algunas advertencias con eso. Debe crear todos los encabezados apropiados y hacer todas las sumas de comprobación usted mismo. Libnet puede ayudar con eso, sin embargo.

Si desea salir del grupo de programación C++, hay scapy para python. Hace trivial crear y transmitir paquetes TCP/IP.

2

He estado desarrollando libtins durante el año pasado.Es una biblioteca de elaboración y olfateo de paquetes C++ de alto nivel.

A menos que desee reinventar la rueda e implementar las partes internas de cada protocolo, le recomendaría que use una biblioteca de nivel superior que ya lo hace por usted.