2011-02-14 16 views
5

Actualmente estoy trabajando en una asignación de programación. La tarea es implementar un cliente, un emulador de red y un servidor. El cliente pasa los paquetes a un emulador de red y el emulador de red pasa al servidor. Viceversa también se aplica. El requisito previo para la asignación es que solo puedo usar conectores crudos. Así que crearé mis propios encabezados de IP y UDP. He probado mis paquetes con wireshark. Todos son correctos y están en el formato correcto (los lee correctamente).¿Cómo vincular un Socket Raw a un puerto específico?

Otro requisito es que el emulador, el cliente y el servidor tienen puertos específicos a los que deben estar vinculados. Ahora, no entiendo cómo vincular un socket sin formato a un puerto específico. Todos mis sockets sin procesar reciben todo el tráfico en la dirección de host a la que están vinculados. Según las páginas de manual, y en cualquier otro sitio en Internet, incluida la "Programación de red Unix" de Richard Stevens, así es como se supone que funcionan. Mi profesor no ha respondido a ninguno de mis correos electrónicos y probablemente no pueda preguntarle hasta el martes. Veo dos opciones frente a mí. Primero puedo usar libpcap para filtrar desde un dispositivo específico y luego enviarlo a mi socket sin procesar. Sin embargo, siento que esto está fuera del alcance de nuestra tarea. O puedo filtrarlos después de recibirlos del socket. Esto aparentemente tiene una sobrecarga porque todos los paquetes se están copiando/moviendo a través del kernel. Al menos, eso es lo que entiendo (por favor, siéntete libre de corregirme si estoy equivocado).

Así que mi pregunta es: ¿Es su una opción o algo que puedo configurar para esto? Donde el zócalo sin procesar se unirá a un puerto? ¿Me he perdido algo obvio?

Gracias por su tiempo.

-

Respuesta

3

El man page for raw(7) dice:

Un conector sin procesar se puede enlazar a una dirección local concreto utilizando la (2) llamada bind. Si no está vinculado, se reciben todos los paquetes con el protocolo IP especificado. Además, un socket RAW puede vincularse a un dispositivo de red específico utilizando SO_BINDTODEVICE; ver el zócalo (7).

Editar: No se puede vincular un socket sin formato a un puerto específico porque "puerto" es un concepto en TCP y UDP, no en IP. Observe los diagramas de encabezado para esos tres protocolos y debería ser obvio: está trabajando en un nivel inferior, donde no se conoce el concepto de puerto.

+0

Entonces, para asegurarme de que estoy interpretando esto correctamente, ¿no puedo enlazar a un puerto específico? Si ese es el caso, ¿cómo implementarías el "filtro"? Libérese a un dispositivo específico y filtre los puertos o, dado que esto es solo para una tarea, simplemente fíltrelos después de que el socket los reciba. ¿O quizás tienes una mejor manera de implementar en mente? Gracias por su respuesta y tiempo por cierto. – user614885

+0

Ver la edición en mi respuesta. Creo que estás en el camino correcto. –

+0

Un "puerto" es una construcción del protocolo de transporte. Desde el nivel de red (IP), los paquetes se dirigen a las direcciones. El trabajo de los protocolos de transporte de nivel superior es implementar la semántica de "puerto". Me imagino que tiene que decodificar los paquetes recibidos usted mismo, para determinar a qué "puerto" está dirigido y filtrar en consecuencia. – Santa

1

Creo que se espera que filtre los paquetes en su software. Parece que el ejercicio consiste en aprender qué hacen los diferentes componentes de la pila de IP recreando una parte simplificada en el espacio de usuario. Normalmente en el kernel, el código IP procesa todos los paquetes, verifica los encabezados de IP, vuelve a armar fragmentos y verifica el campo de protocolo. Si el campo de protocolo es 17 (udp), lo pasa al código UDP (cada paquete UDP). Depende del código UDP para validar el encabezado UDP y determinar si las aplicaciones están interesadas en ellos en función del puerto de destino.

Imagino que se espera que su proyecto imite más o menos este proceso. Obviamente, nada de esto será tan eficiente como hacerlo en el kernel, pero como la tarea es escribir (parte de) una pila de IP en el espacio de usuario, supongo que la eficiencia no es el objetivo del ejercicio.

Cuestiones relacionadas