Provided by:
manpages-es_1.55-10_all 
NOMBRE
packet, PF_PACKET - Interfaz de paquetes a nivel de dispositivo.
SINOPSIS
#include <sys/socket.h>
#include <features.h> /* para el n'umero de versi'on de glibc */
#if __GLIBC__ >= 2 && __GLIBC_MINOR >= 1
#include <netpacket/packet.h>
#include <net/ethernet.h> /* los protocolos de nivel 2 */
#else
#include <asm/types.h>
#include <linux/if_packet.h>
#include <linux/if_ether.h> /* los protocolos de nivel 2 */
#endif
packet_socket = socket(PF_PACKET, int socket_type, int protocol);
DESCRIPCI'ON
Los conectores de paquetes (packet sockets) se usan para recibir o
enviar paquetes directos (raw) en el nivel del manejador de dispositivo
(Nivel 2 de OSI). Permiten al usuario implementar modulos de protocolo
en el espacio de usuario por encima de la capa fisica.
socket_type es o bien SOCK_RAW para paquetes directos incluyendo la
cabecera del nivel de enlace o bien SOCK_DGRAM para paquetes preparados
con la cabecera del nivel de enlace eliminada. La informacion de la
cabecera del nivel de enlace esta disponible en un formato comun en una
estructura sockaddr_ll. protocol es el protocolo IEEE 802.3 con los
bytes en orden de red. Vea el fichero cabecera <linux/if_ether.h> para
una lista de los protocolos permitidos. Cuando se asigna a protocol el
valor htons(ETH_P_ALL), se reciben todos los protocolos. Todos los
paquetes de entrada con el tipo de protocolo indicado se pasaran al
conector de paquetes antes de que sean pasados a los protocolos
implementados dentro del nucleo.
Solo los procesos con uid efectivo 0 o la capacidad CAP_NET_RAW pueden
abrir conectores de paquetes.
Los paquetes SOCK_RAW se pasan a y desde el manejador de dispositivo
sin ningun cambio en los datos del paquete. Cuando se recibe un
paquete, la direccion todavia se analiza y se pasa en una estructura de
direccion sockaddr_ll estandar. Cuando se transmite un paquete, el
buffer proporcionado por el usuario deberia contener la cabecera de la
capa fisica. A continuacion, ese paquete se encola sin modificar en la
tarjeta de red de la interfaz definida por la direccion de destino.
Algunos manejadores (`drivers') de dispositivo siempre anaden otras
cabeceras. SOCK_RAW es similar pero no compatible con el obsoleto
SOCK_PACKET de la version 2.0 de Linux.
SOCK_DGRAM opera en un nivel ligeramente superior. Se elimina la
cabecera fisica antes de que el paquete se pase al usuario. Los
paquetes enviados a traves de un conector de paquetes SOCK_DGRAM
obtienen una cabecera adecuada de la capa fisica segun la informacion
de la direccion de destino sockaddr_ll, antes de ser encolados.
Por defecto, todos los paquetes del tipo de protocolo especificado se
pasan a un conector de paquetes. Para obtener solo los paquetes de una
interfaz especifica, use bind(2) especificando una direccion en una
estructura struct sockaddr_ll para enlazar el conector de paquetes a
una interfaz. Solo se usan para propositos de enlace los campos de
direccion sll_protocol y sll_ifindex.
La operacion connect(2) no esta soportada en conectores de paquetes.
Cuando se pasa la opcion MSG_TRUNC a recvmsg(2), recv(2), recvfrom(2)
se devuelve siempre en ultima instancia la longitud real del paquete,
incluso cuando es mayor que la del buffer.
TIPOS DE DIRECCIONES
sockaddr_ll es una direccion de la capa fisica independiente del
dispositivo.
struct sockaddr_ll {
unsigned short sll_family; /* Siempre es AF_PACKET */
unsigned short sll_protocol; /* Protocolo de la capa fisica */
int sll_ifindex; /* Numero de la interfaz */
unsigned short sll_hatype; /* Tipo de cabecera */
unsigned char sll_pkttype; /* Tipo de paquete */
unsigned char sll_halen; /* Longitud de la direccion */
unsigned char sll_addr[8]; /* Direccion de la capa fisica */
};
sll_protocol es el tipo del protocolo ethernet estandar dado en orden
de red definido en el fichero cabecera linux/if_ether.h. Su valor por
defecto es el protocolo del conector. sll_ifindex es el indice de la
interfaz (vea netdevice(7)); el valor 0 concuerda con cualquier
interfaz (solo legal para enlazar). sll_hatype es un tipo ARP de los
definidos en el fichero cabecera linux/if_arp.h. sll_pkttype contiene
el tipo del paquete. Los tipos validos son PACKET_HOST para un paquete
aplicado al anfitrion (host) local, PACKET_BROADCAST para un paquete de
difusion de la capa fisica, PACKET_MULTICAST para un paquete enviado a
una direccion multidestino de la capa fisica, PACKET_OTHERHOST para un
paquete destinado a otros anfitriones que ha sido capturado por el
manejador del dispositivo en modo promiscuo y PACKET_OUTGOING para un
paquete originado desde el anfitrion local que es devuelto de regreso a
un conector de paquetes. Estos tipos solo tienen sentido para recibir.
sll_addr y sll_halen contienen la direccion de la capa fisica (por
ejemplo, IEEE 802.3) y su longitud. La interpretacion exacta depende
del dispositivo.
Cuando se envian paquetes es suficiente con especificar sll_family,
sll_addr, sll_halen, sll_ifindex. Los otros campos deberian estar a 0.
sll_hatype y sll_pkttype toman sus valores en los paquetes recibidos
para su informacion. Para enlazar solo se utilizan sll_protocol y
sll_ifindex.
OPCIONES DE LOS CONECTORES
Los conectores de paquetes solo se pueden usar para configurar el envio
multidestino de la capa fisica y el modo promiscuo. Esto funciona
llamando a setsockopt(2) con SOL_PACKET, para un conector de paquetes,
y una de las opciones PACKET_ADD_MEMBERSHIP para anadir un enlace o
PACKET_DROP_MEMBERSHIP para eliminarlo. Ambas esperan una estructura
packet_mreq como argumento:
struct packet_mreq
{
int mr_ifindex; /* indice de la interfaz */
unsigned short mr_type; /* accion */
unsigned short mr_alen; /* longitud de la direccion */
unsigned char mr_address[8]; /* direccion de la capa fisica */
};
mr_ifindex contien el indice de la interfaz cuyo estado debe cambiarse.
El parametro mr_type indica la accion a realizar. PACKET_MR_PROMISC
habilita la recepcion de todos los paquetes sobre un medio compartido
(conocido normalmente como ``modo promiscuo''), PACKET_MR_MULTICAST
enlaza el conector al grupo multidestino de la capa fisica indicado en
mr_address y mr_alen, y PACKET_MR_ALLMULTI configura el conector para
recibir todos los paquetes multidestino que lleguen a la interfaz.
Ademas, se pueden usar las ioctls tradicionales, SIOCSIFFLAGS,
SIOCADDMULTI y SIOCDELMULTI, para el mismo proposito.
IOCTLS
SIOCGSTAMP se puede usar para recibir la marca de tiempo del ultimo
paquete recibido. El argumento es una esctructura struct timeval.
Ademas, todas las ioctls estandares definidas en netdevice(7) y
socket(7) son validas en los conectores de paquetes.
MANEJO DE ERRORES
Los conectores de paquetes no manejan otros errores que los ocurridos
al pasar el paquete al manejador del dispositivo. No poseen el concepto
de error pendiente.
COMPATIBILIDAD
En la version 2.0 de Linux, la unica forma de obtener un conector de
paquetes era llamando a socket(PF_INET, SOCK_PACKET, protocol). Esto
todavia esta soportado pero se desaprueba fuertemente. La principal
diferencia entre los dos metodos es que SOCK_PACKET, para especificar
una interfaz, usa la antigua struct sockaddr_pkt que no proporciona
independencia de la capa fisica.
struct sockaddr_pkt
{
unsigned short spkt_family;
unsigned char spkt_device[14];
unsigned short spkt_protocol;
};
spkt_family contiene el tipo del dispositivo, spkt_protocol es el tipo
del protocolo IEEE 802.3 de los definidos en <sys/if_ether.h> y
spkt_device es el nombre del dispositivo dado como una cadena terminada
en un nulo, por ejemplo, eth0.
Esta estructura esta obsoleta y no deberia usarse en codigo nuevo.
OBSERVACIONES
Se sugiere que los programas transportables usen PF_PACKET a traves de
pcap(3), aunque esto solo cubre un subconjunto de las caracteristicas
de PF_PACKET.
Los conectores de paquetes SOCK_DGRAM no intentan crear o analizar la
cabecera LLC IEEE 802.2 para una trama IEEE 802.3. Cuando se
especifica ETH_P_802_3 como protocolo para enviar, el nucleo crea la
trama 802.3 y rellena el campo de longitud. El usuario tiene que
proporcionar la cabecera LLC para obtener un paquete totalmente
conforme. Los paquetes 802.3 de entrada no son multiplexados en los
campos DSAP/SSAP del protocolo. En su lugar, se entregan al usuario
como protocolo ETH_P_802_2 con la cabecera LLC anadida. Por tanto, es
imposible enlazar con ETH_P_802_3. Enlace en su lugar con ETH_P_802_2
y haga usted mismo la multiplexacion del protocolo. Para enviar por
omision se utiliza la encapsulacion estandar Ethernet DIX con el dato
del protocolo lleno.
Los conectores de paquetes no estan sujetos a las cadenas de entrada ni
de salida del cortafuegos.
ERRORES
ENETDOWN
La interfaz no esta activa.
ENOTCONN
No se ha pasado una direccion de interfaz.
ENODEV Nombre de dispositivo o indice de interfaz, especificados en la
direccion de interfaz, desconocidos.
EMSGSIZE
El paquete es mas grande que la MTU de la interfaz.
ENOBUFS
No hay suficiente memoria para colocar el paquete.
EFAULT El usuario ha pasado una direccion de memoria invalida.
EINVAL Argumento invalido.
ENXIO La direccion de interfaz contiene un indice de interfaz ilegal.
EPERM El usuario no tiene privilegios suficientes para llevar a cabo
esta operacion.
EADDRNOTAVAIL
Se ha pasado una direccion desconocida de grupo multidestino.
ENOENT No se ha recibido ningun paquete.
Ademas, el manejador de bajo nivel puede generar otros errores.
VERSIONES
PF_PACKET es una nueva caracteristica de la version 2.2 de Linux. Las
primeras versiones de Linux solo soportaban SOCK_PACKET.
FALLOS
glibc 2.1 no posee una macro "define" para SOL_PACKET. La solucion
sugerida es usar
#ifndef SOL_PACKET
#define SOL_PACKET 263
#endif
Esto se soluciona en versiones posteriores de glibc. Este problema
tampoco se produce en sistemas libc5.
El tratamiento del IEEE 802.2/803.3 LLC se podria considerar un fallo.
No se han documentado los filtros de los conectores.
La extension MSG_TRUNC de recvmsg es una solucion chapucera y deberia
ser reemplazada por un mensaje de control. Actualmente no hay ninguna
manera de obtener la direccion de destino original de paquetes via
SOCK_DGRAM.
CREDITOS
Esta pagina de manual fue escrita por Andi Kleen con la ayuda de
Matthew Wilcox.
Alexey Kuznetsov implemento la caracteristica PF_PACKET de la version
2.2 de Linux basandose en el codigo de Alan Cox y otros.
V'EASE TAMBI'EN
ip(7), socket(7), socket(2), raw(7), pcap(3)
RFC 894 for the standard IP Ethernet encapsulation.
RFC 1700 for the IEEE 802.3 IP encapsulation.
El fichero cabecera <linux/if_ether.h> para los protocolos de la capa
fisica.
Pagina man de Linux 29 abril 1999 PACKET(7)