Estoy tratando de escribir una .archivo pcap, que es algo que puede ser utilizado en Wireshark.
Con el fin de hacer eso, tengo un par de estructuras con distintos tipos de datos que necesito para escribir en un archivo. (ver código)

Así, creo que la estructura de los casos, rellenar los datos, el uso de FILE* fp = fopen(«prueba.pcap»,»w»), y entonces estoy seguro de cómo se escribe correctamente en el archivo. Creo que debería usar memcpy, pero no estoy seguro de que la mejor manera de hacerlo. Yo en su mayoría han recurrido a las bibliotecas de C++ en el pasado para hacer esto. Alguna sugerencia?

typedef struct pcap_hdr_s {
        uint32_t magic_number;   /* magic number */
        uint16_t version_major;  /* major version number */
        uint16_t version_minor;  /* minor version number */
        int32_t  thiszone;       /* GMT to local correction */
        uint32_t sigfigs;        /* accuracy of timestamps */
        uint32_t snaplen;        /* max length of captured packets, in octets */
        uint32_t network;        /* data link type */
} pcap_hdr_t;

typedef struct pcaprec_hdr_s {
   uint32_t ts_sec;         /* timestamp seconds */
   uint32_t ts_usec;        /* timestamp microseconds */
   uint32_t incl_len;       /* number of octets of packet saved in file */
   uint32_t orig_len;       /* actual length of packet */
} pcaprec_hdr_t;

typedef struct ethernet_hdr_s {
   uint8_t dst[6];    /* destination host address */
   uint8_t src[6];    /* source host address */
   uint16_t type;     /* IP? ARP? RARP? etc */
} ethernet_hdr_t;

typedef struct ip_hdr_s {
   uint8_t  ip_hl:4, /* both fields are 4 bits */
            ip_v:4;
   uint8_t        ip_tos;
   uint16_t       ip_len;
   uint16_t       ip_id;
   uint16_t       ip_off;
   uint8_t        ip_ttl;
   uint8_t        ip_p;
   uint16_t       ip_sum;
   uint32_t ip_src;
   uint32_t ip_dst;
}ip_hdr_t;

typedef struct udp_header
{
  uint16_t src;
  uint16_t dst;
  uint16_t length;
  uint16_t checksum;
} udp_header_t;
Tener cuidado con el orden de los bytes — creo que los paquetes capturados siempre use orden de byte de red, pero usted puede ser que necesite para comprobar el orden de bytes de la cabecera. Tal vez no sea una preocupación, si el formato de archivo se utiliza la magic_number de campo para determinar el orden de los bytes de la cabecera.
El número mágico que le permite escribir, ya sea en grandes o little-endian, usted puede incluso cambiar de ida y vuelta después de cada paquete, si quieres. El número mágico también avisa a los daños causados por inadecuadamente transferir el archivo.
El número mágico que hace no permite escribir el paquete datos en big-endian o little-endian orden; usted tiene que escribir en el orden en que aparecen en el cable, que, por Ethernet, IP, TCP, UDP y multi-byte integral campos, es big-endian. no permite escribir los campos en el archivo y registro de encabezado en su nativo de orden de bytes, pero puede ser que también acaba de dejar libpcap/WinPcap hacer ese trabajo. Y, lamentablemente, el número mágico no es afectada por, por ejemplo, FTPing el archivo en modo ASCII entre Windows y de las naciones unidas*X.

OriginalEl autor KaiserJohaan | 2011-09-05

3 Comentarios

  1. 4

    Uso fwrite(). Usted necesita para comprobar esta información, pero creo que .pcap los archivos se escriben en binario modo.

    Ejemplo:

    pcaprec_hdr_t pcaprec_hdr;
    //fill pcaprec_hdr with valid info
    
    FILE* pFile = NULL;
    pFile = fopen ("myfile.pcap" , "wb"); //open for writing in binary mode
    
    fwrite (&pcaprec_hdr, 1, sizeof(pcaprec_hdr_t) , pFile);
    
    fclose(pFile);
    +1 para fwrite y mencionar el modo binario.
    -1 para olvidar escribir el encabezado del archivo y para no acaba de decir «usar libpcap/WinPcap, que ya saben cómo escribir el encabezado de archivo y el registro de encabezado».
    Usted asume que ya saben. Pero, ¿es así? Obtener esta respuesta seleccionada como la oficial se muestra algo más.
    «Usted asume que ya saben. Pero, ¿es así?» Sí, son ellos. Ellos fueron la primera aplicación del formato de archivo cada vez.
    Estoy teniendo problemas con ello, puedes editar tu respuesta con la de «lleno» ejemplo? Cuando abro mi archivo pcap en wireshark tengo un error diciendo The capture file appears to have been cut short in the middle of a packet. Y sólo puedo ver el «marco» de la fila. Gracias.

    OriginalEl autor karlphillip

  2. 16

    Uso libpcap o WinPcap – pcap_open_dead() para obtener un «falso» pcap_t para su uso con pcap_dump_open() para especificar la capa de enlace de tipo de encabezado (por Ethernet, utilice DLT_EN10MB) y la instantánea de longitud (uso 65535), pcap_dump_open() a abrir el archivo para escritura, pcap_dump() escribir un paquete, y pcap_dump_close() para cerrar el archivo. MUCHO más fácil de utilizar directamente fopen(), fwrite(), y fclose() (que son lo que libpcap/WinPcap uso «bajo el capó»).

    Y, sí, usted tiene que obtener el orden de los bytes de los paquetes correctos. El orden de los bytes depende del protocolo; para el type campo en el encabezado de Ethernet, y para todos los multi-byte campos en IP, TCP, UDP y los encabezados, tienen que estar en orden big-endian. (El número mágico en el archivo pcap es irrelevante para esto lo único que indica el orden de los bytes de los campos en el encabezado del archivo y el paquete de encabezado de registro, NO el orden de los bytes de los campos en el paquete, así como, debido a la forma en que está implementado en Linux, los meta-datos en el principio de paquetes en Linux USB de captura. El paquete de datos se supone que se vea exactamente como lo sería «en el cable».)

    puede por favor compartir «más el código»? Me refiero a escribir un ejemplo?

    OriginalEl autor

  3. 2

    Aquí mi comprensión de lo que Guy Harris es lo que sugiere. Así que, como por Kyslik de la solicitud, tenemos:

    #include <libpcap/pcap.h>
    /* Ethernet/IP/SCTP INIT chunk */
    static const unsigned char pkt1[82] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
    0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00, /* ......E. */
    0x00, 0x44, 0x55, 0xb1, 0x00, 0x00, 0x40, 0x84, /* [email protected] */
    0x26, 0x83, 0x7f, 0x00, 0x00, 0x01, 0x7f, 0x00, /* &....... */
    0x00, 0x01, 0x00, 0x01, 0x1f, 0x90, 0x00, 0x00, /* ........ */
    0x00, 0x00, 0x68, 0xe5, 0x88, 0x1b, 0x01, 0x00, /* ..h..... */
    0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, /* .$...... */
    0xa0, 0x00, 0x00, 0x04, 0xff, 0xff, 0x00, 0x00, /* ........ */
    0x16, 0x2e, 0x80, 0x00, 0x00, 0x04, 0xc0, 0x00, /* ........ */
    0x00, 0x04, 0x00, 0x0c, 0x00, 0x06, 0x00, 0x05, /* ........ */
    0x00, 0x00                                      /* .. */
    };
    int main(int argc, char *argv[]) {
    pcap_t *handle = pcap_open_dead(DLT_EN10MB, 1 << 16);
    pcap_dumper_t *dumper = pcap_dump_open(handle, "/tmp/pktcap/cap.pcap");
    struct pcap_pkthdr pcap_hdr;
    pcap_hdr.caplen = sizeof(pkt1);
    pcap_hdr.len = pcap_hdr.caplen;
    pcap_dump((u_char *)dumper, &pcap_hdr, pkt1);
    pcap_dump_close(dumper);
    return 0;
    }
    He tenido que modificar pcap_pkthdr pcap_hdr; a struct pcap_pkthdr pcap_hdr; para hacer esta compilación con gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609

    OriginalEl autor Asblarf

Dejar respuesta

Please enter your comment!
Please enter your name here