Ver Mensaje Individual
  #9 (permalink)  
Antiguo 17/10/2007, 07:46
liza
 
Fecha de Ingreso: junio-2004
Mensajes: 8
Antigüedad: 20 años, 5 meses
Puntos: 0
Re: Envíar datos de red mediante NetFlow al ntop

Cita:
Iniciado por Alnorte Ver Mensaje
Hola!

Estoy haciendo un programa en "C" que envía datos de red, como direcciones IP, mediante el protocolo NetFlow para poder visualizar esa información en el ntop.

El problema es que si lo programo para envíar menos de 3 flow data records no me aparece nada en el ntop. Y si envío 3 o más flow data records me aparecen todos excepto los 2 últimos. Vamos que el problema es que los 2 últimos flow data records no salen.

Para usar el ntop para recoger datos Netflow simplemente hay que activar el plugin netflow (en la interfaz web del netflow, en admin->plugins) de manera que se crea un nuevo interfaz de red aparte del eth0. Luego se va a admin->switch NIC y se selecciona la nueva interfaz netflow para que sean esos datos los que muestre en tráfico y demás.

Por tanto no creo que el error esté en el ntop, pienso que será algo que hago mal en el programa que estoy haciendo. Lo he programado acorde a los datos del RFC de Netflow, y siguiendo el ejemplo del RFC pero sin las opciones y con algún campo menos.

A continuación dejo el código del programa que envía 3 flow data records por si alguién sabe algo y me puede echar una mano. Cualquier duda la respondere con mucho gusto. Gracias de antemano.

Código:

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#define PORT 2055 /* el puerto donde se enviaran los datos (el que usa NetFlow por defecto)*/

/* Cabecera NetFlow */
struct netflow_hdr {
unsigned short int version;
unsigned short int count;
unsigned long int sys_up_time;
unsigned long int unix_secs;
unsigned long int sequence_number;
unsigned long int source_id;
};

struct template_flowset {
unsigned short int flowset_id;
unsigned short int length;
unsigned short int template_id;
unsigned short int field_count;
unsigned short int fields[8];
};

struct data_flowset {
unsigned short int flowset_id;
unsigned short int length;
unsigned long int field[12];// 3 data records de 4 campos cada uno
};

int main()
{
int sockfd;
struct sockaddr_in their_addr; /*Almacenara la direccion IP y numero de puerto del destino*/
struct hostent *he;
int numbytes;
FILE *fichero=NULL;
unsigned long int temp;


/* Tamaño del buffer capaz de contener un paquete NetFlow */
unsigned int buffer_size=sizeof(struct netflow_hdr)+sizeof(struct template_flowset)+sizeof(struct data_flowset);

/* Buffer que contendra el paquete NetFlow */
unsigned char buffer[buffer_size];
memset(buffer,0,buffer_size);//se rellena con ceros

/* Cabecera NetFlow */
struct netflow_hdr *header=(struct netflow_hdr *)buffer;

/* template flowset */
struct template_flowset *template=(struct template_flowset *)(buffer + sizeof(struct netflow_hdr));

/* data flowset */
struct data_flowset *data=(struct data_flowset *)(buffer + sizeof(struct netflow_hdr)+ sizeof(struct template_flowset));

/* convertimos el hostname a su direccion IP */
if ((he=gethostbyname("localhost")) == NULL)
{

herror("gethostbyname");
exit(1);

}
/* Creamos el socket */
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
{

perror("socket");
exit(1);

}

//rellenamos el paquete NetFlow teniendo en cuenta que hay que usar network byte order:

fichero = popen ("date +%s", "r");//para rellenar header->unix_secs
if (fichero == NULL)
{
perror ("No se puede abrir /bin/ls");
exit (-1);
}

fscanf(fichero,"%d",&(temp));//Se guarda la información de salida del comando "date +%s" que
// estaba en el fichero en la variable temp para después rellenar la estructura

header->version=htons(9);// versión 9 de netflow
header->count=htons(4);// número total de records: 1 template record + 3 data record
header->sys_up_time=htonl(10000);// milisegundos desde que el dispositivo fue arrancado
header->unix_secs=htonl(temp);// segundos que han pasado desde 1970
header->sequence_number=htonl(1);//número de secuencia
header->source_id=htonl(250);//identificador de la fuente

template->flowset_id=htons(0);//El cero está reservado para el template flowset ID
template->length=htons(sizeof(struct template_flowset));
template->template_id=htons(256);//Template ID de data flowsets son mumerados desde 256 hasta 65535
template->field_count=htons(4); //Número de campos en cada template record
//(para que el colector sepa el final de cada template record)
template->fields[0]=htons(8);//campo 1: IP_SRC_ADDR
template->fields[1]=htons(4);//longitud del campo IP_SRC_ADDR
template->fields[2]=htons(12);//campo 2: IP_DEST_ADDR
template->fields[3]=htons(4);//longitud del campo IP_DEST_ADDR
template->fields[4]=htons(2);//campo 3: IN _PKTS
template->fields[5]=htons(4);//longitud del campo IN_PKTS
template->fields[6]=htons(1);//campo 4: IN_BYTES
template->fields[7]=htons(4);//longitud del campo IN_BYTES

data->flowset_id=htons(256);//Tiene que ser igual que el template_id
data->length=htons(sizeof(struct data_flowset));
data->field[0]=inet_addr("198.168.1.12");//record 1, valor del campo 1
data->field[1]=inet_addr("10.5.12.254");//record 1, valor del campo 2
data->field[2]=htonl(5009);//record 1, valor del campo 3
data->field[3]=htonl(5344385);//record 1, valor del campo 4
data->field[4]=inet_addr("198.168.1.15");//record 2, valor del campo 1
data->field[5]=inet_addr("10.5.10.254");//record 2, valor del campo 2
data->field[6]=htonl(3000);//record 2, valor del campo 3
data->field[7]=htonl(2863790);//record 2, valor del campo 4
data->field[8]=inet_addr("198.168.1.16");//record 3, valor del campo 1
data->field[9]=inet_addr("10.5.18.254");//record 3, valor del campo 2
data->field[10]=htonl(2000);//record 3, valor del campo 3
data->field[11]=htonl(1563790);//record 3, valor del campo 4

//Procedemos al envío (sobre UDP)

their_addr.sin_family = AF_INET; /* host byte order */
their_addr.sin_port = htons(PORT); /* network byte order */
their_addr.sin_addr = *((struct in_addr *)he->h_addr);
bzero(&(their_addr.sin_zero), 8);

if ((numbytes=sendto(sockfd, buffer, buffer_size, 0, (struct sockaddr *)&their_addr,sizeof(struct sockaddr))) == -1)
{

perror("sendto");
exit(1);

}
printf("enviados %d bytes hacia %s\n",numbytes,inet_ntoa(their_addr.sin_addr));
close(sockfd);
return 0;
}
RESPUESTA DE LIZA
HOLA, ES UN PLACER CONOCERTE LA INQUIETUD QUE TENGO HACERCA DE TU CODIGO ES LA SIGUIENTE.: DONDE LO COLOCAS DENTRO DEL NTOP PARA CORRERLO. CREO QUE LE PUEDO HACER UNAS MODIFICACION PARA QUE HAGA LO QUE TU QUIERES. BUENO ESPERO TU PRONTA RESPUESTA MI CORREO ES [email protected] SOY DE VENEZUELA