2008-09-21 18 views
15

Bueno, me doy cuenta de que esta situación es algo inusual, pero necesito establecer una conexión TCP (el enlace de tres vías) utilizando solo conectores crudos (en C, en Linux), es decir, necesito construyo los encabezados IP y los encabezados TCP yo mismo. Estoy escribiendo un servidor (así que primero tengo que responder al paquete SYN entrante) y, por la razón que sea, parece que no puedo hacerlo bien. Sí, me doy cuenta de que SOCK_STREAM se encargará de esto por mí, pero por razones que no quiero mencionar, no es una opción.Protocolo de enlace TCP con socket SOCK_RAW

Los tutoriales que he encontrado en línea sobre el uso de sockets sin formato describen cómo crear un flooder SYN, pero esto es algo más fácil que establecer una conexión TCP, ya que no tiene que construir una respuesta basada en el original paquete. Obtuve el funcionamiento de los ejemplos de Flooder SYN, y puedo leer el paquete SYN entrante sin problemas desde el socket sin formato, pero todavía tengo problemas para crear una respuesta SYN/ACK válida a un SYN entrante del cliente.

Entonces, ¿alguien sabe un buen tutorial sobre el uso de sockets sin formato que va más allá de crear un flooder SYN, o alguien tiene algún código que pueda hacer esto (usando SOCK_RAW, y no SOCK_STREAM)? Estaría muy agradecido.


MarkR tiene toda la razón - el problema es que el núcleo es el envío de paquetes de restablecimiento en respuesta al paquete inicial, ya que piensa que el puerto está cerrado. El núcleo me está golpeando a la respuesta y la conexión muere. Ya estaba usando tcpdump para monitorear la conexión, debería haber sido más observador y haber notado que había DOS respuestas, una de ellas era un reinicio que estaba estropeando las cosas, así como la respuesta que creó mi programa. D'OH!

La solución que parece funcionar mejor es usar una regla de iptables, como sugiere MarkR, para bloquear los paquetes de salida. Sin embargo, hay una manera más fácil de hacerlo que usar la opción de marca, como se sugiere. Solo coincido si está configurado el indicador de reinicio TCP. Durante el curso de una conexión normal, es poco probable que sea necesario, y realmente no importa a mi aplicación si bloqueo todos los paquetes de reinicio salientes del puerto que se está utilizando. Esto efectivamente bloquea la respuesta no deseada del kernel, pero no mis propios paquetes. Si el puerto de mi programa está escuchando en el 9999 es entonces la regla de iptables se parece a esto:

iptables -t filter -I OUTPUT -p tcp --sport 9999 --tcp-flags RST RST -j DROP 

Respuesta

1

que no tienen un tutorial, pero recientemente he utilizado Wireshark con buenos resultados para depurar algunas tomas de programación prima que estaba haciendo . Si captura los paquetes que está enviando, wireshark hará un buen trabajo mostrándole si están malformados o no. También es útil para comparar con una conexión normal.

2

No puedo ayudarte con ningún tutorial.

Pero puedo darle algunos consejos sobre las herramientas que puede utilizar para ayudar en la depuración.

En primer lugar, como bmdhacks ha sugerido, consiga una copia de wireshark (o tcpdump - pero wireshark es más fácil de usar). Capture un buen apretón de manos. Asegúrate de guardar esto.

Capture uno de sus apretones de manos que falla. Wireshark tiene un análisis de paquetes y una comprobación de errores bastante buenos, por lo que si hay un error directo probablemente se lo diga.

A continuación, obtenga una copia de tcpreplay. Esto también debería incluir una herramienta llamada "tcprewrite". tcprewrite le permitirá dividir los archivos de captura previamente guardados en dos: uno para cada lado del intercambio de información. Luego, puede usar tcpreplay para reproducir un lado del enlace de modo que tenga un conjunto consistente de paquetes para jugar.

Luego usa wireshark (nuevamente) para verificar sus respuestas.

9

Desea implementar parte de una pila TCP en el espacio de usuario ... esto está bien, algunas otras aplicaciones lo hacen.

Un problema que se encontrará es que el kernel enviará respuestas (generalmente negativas, inútiles) a los paquetes entrantes. Esto va a arruinar cualquier comunicación que intente iniciar.

Una forma de evitar esto es usar una dirección IP e interfaz que el kernel no tenga su propia pila IP, lo cual está bien, pero tendrá que ocuparse de cosas de la capa de enlace (específicamente, arp). Eso requeriría un socket más bajo que IPPROTO_IP, SOCK_RAW - necesitas un socket de paquete (creo).

También es posible bloquear las respuestas del kernel usando una regla de iptables, pero sospecho que las reglas se aplicarán también a tus propios paquetes, a menos que puedas tratarlos de manera diferente (quizás aplicando un netfilter "marca" a sus propios paquetes?)

Leer la toma de páginas man

(7) ip (7) de paquetes (7)

que explican a utilizar varias opciones y ioctls que se aplican a los tipos de enchufes

Por supuesto, necesitará una herramienta como Wireshark para inspeccionar lo que está sucediendo. Necesitará varias máquinas para probar esto. Recomiendo usar vmware (o similar) para reducir la cantidad de hardware requerido.

Lo siento, no puedo recomendar un tutorial específico.

Buena suerte.

0

Existen estructuras para encabezados IP y TCP declaradas en netinet/ip.h & netinet/tcp.h respectivamente. Es posible que desee mirar las otras cabeceras en este directorio para macros adicionales & cosas que pueden ser de utilidad.

Envía un paquete con el conjunto de banderas SYN y un número de secuencia aleatorio (x). Debería recibir un SYN + ACK del otro lado. Este paquete tendrá un número de reconocimiento (y) que indica el próximo número de secuencia que el otro lado espera recibir, así como otro número de secuencia (z). Usted devuelve un paquete ACK que tiene el número de secuencia x + 1 y el número de entrada z + 1 para completar la conexión.

También debe asegurarse de calcular las sumas de comprobación TCP/IP adecuadas & llene el resto del encabezado de los paquetes que envíe. Además, no se olvide de cosas como el orden de bytes de la red del host &.

TCP se define en el RFC 793, disponible aquí: http://www.faqs.org/rfcs/rfc793.html

0

Dependiendo de lo que estamos tratando de hacer que sea más fácil conseguir el software existente para manejar el protocolo de enlace TCP para usted.

Una pila de IP de fuente abierta es lwIP (http://savannah.nongnu.org/projects/lwip/) que proporciona una pila completa de tcp/ip. Es muy posible ejecutarlo en modo de usuario usando SOCK_RAW o pcap.

0

si está utilizando sockets sin formato, si envía utilizando una dirección mac de origen diferente a la real, linux ignorará el paquete de respuesta y no enviará una primera.

+0

Sé que es una pregunta de hace 4 años, pero su sugerencia parece bastante interesante, así que decidí pedirle una aclaración. La pregunta es: ¿Hay algún problema con el enrutador mientras enruta el paquete de respuesta a cierta máquina con la dirección MAC del dispositivo incorrecto? ¿El paquete será filtrado por el firewall o antivirus de hoy en día? –

+0

Los switches pueden filtrar un MAC falso si están configurados para la seguridad del puerto. Es posible que haya ACL en la capa MAC, pero normalmente no hay nada que le impida falsificar MAC. Solo necesita asegurarse de que su tarjeta de red acepte respuestas a este mac falsificado (agregando el mac a la tabla de paquetes aceptados o poniéndolo en modo promisc). Esta es una mala idea para hacer esto si no está autorizado. – eckes

Cuestiones relacionadas