Provided by: manpages-es_1.55-10_all bug

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)