Código de C/Visual C - DATAGRAMAS-PCAP

Imágen de perfil

DATAGRAMAS-PCAPgráfica de visualizaciones


C/Visual C

Publicado el 27 de Septiembre del 2022 por Hilario (121 códigos)
466 visualizaciones desde el 27 de Septiembre del 2022
/*
-------------------------
datagrama.c
-------------------------------
Dulce bellum inexpertis.
--------------------------------
Hilario Iglesias Martínez
-----------------------------
El programa fue realizado en una plataforma
LINUX Ubuntu 20.04.4 LTS.
Bajo el standard ANSI-C,
bajo una consola Linux, con las
librerías libpcap cargadas
**********************************
Este programa una vez compilado
debe ejecutarse bajo administrador
principal ROOT.
************************************
Compilar:
gcc -Wall -o datagrama datagrama.c -lpcap

Ejecutar:
$ sudo ./datagrama
CAPTURA PAQUETES.
-----------------
Para agilizar la captura de paquetes,
se puede iciar la navegación por intertet.
Por defecto he configurado el puerto 443.

El tamaño del PAYLOAD recuperado está
está configurado solamente para 128 bytes.

*/

Requerimientos

El programa fue realizado en una plataforma
LINUX Ubuntu 20.04.4 LTS.
Bajo el standard ANSI-C,
bajo una consola Linux, con las
librerías libpcap cargadas
**********************************
Este programa una vez compilado
debe ejecutarse bajo administrador
principal ROOT.
************************************

V-0

Publicado el 27 de Septiembre del 2022gráfica de visualizaciones de la versión: V-0
468 visualizaciones desde el 27 de Septiembre del 2022
estrellaestrellaestrellaestrellaestrella
estrellaestrellaestrellaestrella
estrellaestrellaestrella
estrellaestrella
estrella

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
/*
-------------------------
     datagrama.c
-------------------------------
Dulce bellum inexpertis.
--------------------------------
Hilario Iglesias Martínez
-----------------------------
El programa fue realizado en una plataforma
LINUX Ubuntu 20.04.4 LTS.
Bajo el standard ANSI-C,
bajo una consola Linux, con las
librerías libpcap cargadas
**********************************
Este programa una vez compilado
debe ejecutarse bajo administrador
principal ROOT.
************************************
Compilar:
gcc -Wall -o datagrama   datagrama.c -lpcap
Ejecutar:
$ sudo ./datagrama
           CAPTURA PAQUETES.
           -----------------
Para agilizar la captura de paquetes,
se puede iciar la navegación por intertet.
Por defecto he configurado el puerto 443.
El tamaño del PAYLOAD recuperado está
está configurado solamente para 128 bytes.
*/
 
#include <pcap.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/if_ether.h>
#include <netinet/ether.h>
#include <netinet/ip.h>
#include <string.h>
 
void Llamada_Rutina(u_char *args,const struct pcap_pkthdr *header,const u_char *packet)
{
/*
Argumentos de "Llamada_Rutina":
Esta función es void no tiene valor de retorno
al funcionar en bucle.
u_char *args:
Es el primer argumento que corresponde al último argumento de pcap_loop (),
con el fin de controlar el bucle repetitivo
Cualquier valor que se pase como último argumento a pcap_loop ()
se pasa al primer argumento de nuestra función de devolución de
llamada cada vez que se llama a la función.
El segundo argumento es el encabezado pcap,
que contiene información sobre cuándo se detectó
el paquete, qué tamaño tiene, etc. La estructura
es la sigiente:
struct pcap_pkthdr {
    struct timeval ts;   marca de tiempo
    bpf_u_int32 caplen;  longitud de la porción presente
    bpf_u_int32 len;     longitud de este paquete (fuera de línea)
En <sys/time.h>
Cabecera que define la estructura timeval
incluyendo al menos los siguientes miembros:
time_t         tv_sec      seconds
suseconds_t    tv_usec     microseconds
*/
//------------------------------------------------------
/* Tenemos que localizar un paquete de protocolo IP,
para ello utilizaremos struct ether_header
contenida en netinet/if_ether.h, con el siguiente
formato, con los tipos más importantes que define.
struct  ether_header {
    u_char  ether_dhost[6];
    u_char  ether_shost[6];
    u_short ether_type;
};
#define ETHERTYPE_PUP   0x0200       PUP protocol
#define ETHERTYPE_IP    0x0800       IP protocol
#define ETHERTYPE_ARP   0x0806       Addr. resolution protocol
 */
 
 
    struct ether_header *Puntero_Cabecera; //eth_header
    Puntero_Cabecera = (struct ether_header *) packet;
    if (ntohs(Puntero_Cabecera->ether_type) != ETHERTYPE_IP) {
     printf("No es un paquete IP \n\n");
        return;
    }
 
     /*La función htons () convierte el entero
     corto sin signo hostshort del orden de bytes del host al orden de bytes de la red.
     */
 
    /* Volver a mirar la struct pcap_pkthdr.
       ************************************
        La longitud total del paquete, incluidos todos los encabezados.
        y la carga útil de datos se almacena en
        encabezado->len y encabezado->caplen. Caplen es
        la cantidad realmente disponible, y len es el
        longitud total del paquete incluso si es más grande
        que lo que actualmente hemos capturado. Si la instantánea
        longitud establecida con pcap_open_live() es demasiado pequeña, puede
        no tener todo el paquete. */
 
 
    printf("------------------------------------------------------------------------\n");
    printf("Total de paquetes disponibles: %d bytes\n", header->caplen);
    printf("Tamaño del paquete esperado: %d bytes\n", header->len);
 
 
    /* Punteros al inicio del encabezado */
    const u_char *ip_header;
    const u_char *tcp_header;
    const u_char *payload;
 
    /* Longitud de cabecera en bytes */
    int ethernet_header_length = 14;
 
    /*
       ethernet_header_length:
        Capa de transmisión Ethernet 14 bytes.
        48 bits: Dirección Ethernet de destino
        48 bits: Dirección Ethernet del emisor
        16 bits: Tipo de protocolo = ether_type$ADDRESS_RESOLUTION.
    */
    int ip_header_length;
/*
La longitud mínima de un encabezado IP es de 20
bytes o cinco incrementos de 32 bits.
La longitud máxima de un encabezado IP
es de 24 bytes o seis incrementos de 32 bits.
*/
 
    int tcp_header_length;
    /*
    El encabezado de tamaño mínimo es de 5 palabras
    y el máximo de 15 palabras, lo que da un tamaño
    mínimo de 20 bytes y un máximo de 60 bytes,
    lo que permite hasta 40 bytes de opciones en el encabezado.
    Este campo recibe su nombre del hecho de que
    también es el desplazamiento desde el inicio
    del segmento TCP hasta los datos reales.
    */
 
    int payload_length;
 
 
    /*
El tamaño máximo de la carga útil para los paquetes IP
está limitado por el campo Longitud total en el encabezado
del paquete IP; ese campo tiene una longitud de 16 bits,
lo que significa que el valor máximo posible es 216 y el
valor más alto posible para la longitud del paquete es 65 535;
ninguna carga útil puede ser mayor,
menos la cantidad de bytes necesarios para el encabezado del paquete.
    */
 
    /* Según las dimensiones explicadas anteriormente
    deberemos buscar lo que nos interesa, la cabecera IP.
    struct ip
  {
#if __BYTE_ORDER == __LITTLE_ENDIAN
    unsigned int ip_hl:4;                header length
    unsigned int ip_v:4;                 version
#endif
#if __BYTE_ORDER == __BIG_ENDIAN
    unsigned int ip_v:4;                 version
    unsigned int ip_hl:4;                header length
#endif
    u_int8_t ip_tos;                     type of service
    u_short ip_len;                      total length
    u_short ip_id;                       identification
    u_short ip_off;                      fragment offset field
#define        IP_RF 0x8000              reserved fragment flag
#define        IP_DF 0x4000              dont fragment flag
#define        IP_MF 0x2000              more fragments flag
#define        IP_OFFMASK 0x1fff         mask for fragmenting bits
    u_int8_t ip_ttl;                     time to live
    u_int8_t ip_p;                       protocol
    u_short ip_sum;                      checksum
    struct in_addr ip_src, ip_dst;       source and dest address
  };
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |Version|  IHL  |Type of Service|          Total Length         |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |         Identification        |Flags|      Fragment Offset    |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |  Time to Live |    Protocol   |         Header Checksum       |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                       Source Address                          |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                    Destination Address                        |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                    Options                    |    Padding    |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    Example Internet Datagram Header
     */
    ip_header = packet + ethernet_header_length;
    /*La segunda mitad del primer byte en ip_header
        contiene la longitud del encabezado IP (IHL). */
    ip_header_length = ((*ip_header) &0x0F);
    /* El IHL es un número de segmentos de 32 bits.
     Multiplicar  por cuatro para obtener
     un recuento de bytes para la aritmética de punteros*/
    ip_header_length = ip_header_length * 4;
    printf("IP longitud de cabecera (IHL) in bytes: %d\n", ip_header_length);
 
    /* Ahora que sabemos dónde está el encabezado IP, podemos
        inspeccionar el encabezado IP para un número de protocolo para
        asegúrese de que sea TCP antes de continuar.
        El protocolo es siempre el décimo byte del encabezado IP */
    u_char protocol = *(ip_header + 9);
    if (protocol != IPPROTO_TCP) {
        printf("No es un paquete TCP\n\n");
        return;
    }
 
    /* Agrega la longitud del encabezado ethernet e ip al inicio del paquete
     para encontrar el comienzo del encabezado TCP */
    tcp_header = packet + ethernet_header_length + ip_header_length;
 
    /* La longitud del encabezado TCP se almacena en la primera mitad
        del byte 12 en el encabezado TCP. porque solo queremos
        el valor de la mitad superior del byte, tenemos que cambiarlo
        hasta la mitad inferior, de lo contrario, está utilizando la mayoría
        bits significativos en lugar de los bits menos significativos */
    tcp_header_length = ((*(tcp_header + 12)) & 0xF0) >> 4;
 
    /* La longitud del encabezado TCP almacenada en esos 4 bits representa
        cuántas palabras de 32 bits hay en el encabezado, al igual que
        la longitud del encabezado IP. Volvemos a multiplicar por cuatro para obtener un
        conteo de bytes */
    tcp_header_length = tcp_header_length * 4;
    printf("Tamaño  de la cabecera TCP en bytes: %d\n", tcp_header_length);
 
    /* Sumamos todos los tamaños de encabezado para encontrar el desplazamiento de la carga útil */
    int total_headers_size = ethernet_header_length+ip_header_length+tcp_header_length;
    printf("Tamaño de todas las cabeceras: %d bytes\n", total_headers_size);
    payload_length = header->caplen -(ethernet_header_length + ip_header_length + tcp_header_length);
    printf("Tamaño del PAYLOAD: %d bytes\n", payload_length);
    payload = packet + total_headers_size;
    printf("Direccion de memoria donde comienza el PAYLOAD: %p\n\n", payload);
    printf("--------------------------------------------------------------------------------\n");
 
/*
Con la siguiente rutina pretendemos volcar  el payload configurado a la pantalla.
*/
 
 
char Codigo_ascii[17];
int i;
 
for (i = 0; i < 128; ++i) {
        printf("%02X ", ((unsigned char*)payload)[i]);
        if (((unsigned char*)&payload)[i] >= ' ' && ((unsigned char*)payload)[i] <= '~')
         {
            Codigo_ascii[i % 16] = ((unsigned char*)payload)[i];
        } else {
            Codigo_ascii[i % 16] = '.';
        }
        if ((i+1) % 8 == 0 || i+1==128) {
            printf(" ");
            if ((i+1) % 16 == 0) {
                printf(" |  %s \n", Codigo_ascii);
 
}}}
 
    return ;
}
 
 
//----------------------------------------
int main(int argc,char **argv)
 
{
char *filtro="tcp and port 443"; //solo el trafico web
//char *dev;
char errbuf[PCAP_ERRBUF_SIZE];
pcap_t* descr;
//const u_char *packet;
struct pcap_pkthdr_hdr;
//struct ether_header *eptr; // Ethernet
bpf_u_int32 maskp; // mascara de subred
bpf_u_int32 netp; // direccion de red
struct bpf_program fp; // El programa de filtrado compilado
pcap_if_t *Dispositivo;
//**********************************
//struct ip* iphdr=malloc(sizeof(iphdr->ip_ttl));
 
if(pcap_findalldevs(&Dispositivo, errbuf) == 0) {
 
            printf("El dispositivo de captura es:%s \n", Dispositivo->name);
 
        }
 
    else {
        printf("error: %s\n", errbuf);
        exit(-1);
    }
 
pcap_lookupnet(Dispositivo->name,&netp,&maskp,errbuf); //extraemos la direccion de red y la mascara
descr = pcap_open_live(Dispositivo->name,BUFSIZ,1,-1,errbuf); //comenzamos la captura en modo promiscuo
if (pcap_compile(descr,&fp,filtro,0,netp) == -1) //compilamos el programa
{
	fprintf(stderr,"Error compilando el filtro\n");
	 exit(1);
}
 
if (pcap_setfilter(descr,&fp) == -1) //aplicamos el filtro
{
	fprintf(stderr,"Error aplicando el filtro\n");
	 exit(1);
}
if (descr == NULL)
{
	printf("pcap_open_live(): %s\n",errbuf);
	 exit(1);
	 }
pcap_loop(descr,-1,Llamada_Rutina,NULL); //entramos en el bucle (infinito)
return 0;
}



Comentarios sobre la versión: V-0 (0)


No hay comentarios
 

Comentar la versión: V-0

Nombre
Correo (no se visualiza en la web)
Valoración
Comentarios...
CerrarCerrar
CerrarCerrar
Cerrar

Tienes que ser un usuario registrado para poder insertar imágenes, archivos y/o videos.

Puedes registrarte o validarte desde aquí.

Codigo
Negrita
Subrayado
Tachado
Cursiva
Insertar enlace
Imagen externa
Emoticon
Tabular
Centrar
Titulo
Linea
Disminuir
Aumentar
Vista preliminar
sonreir
dientes
lengua
guiño
enfadado
confundido
llorar
avergonzado
sorprendido
triste
sol
estrella
jarra
camara
taza de cafe
email
beso
bombilla
amor
mal
bien
Es necesario revisar y aceptar las políticas de privacidad

http://lwp-l.com/s7286