Enviar paquetes TCP/IP

Iniciado por soyloqbuskas, 27 Marzo 2012, 16:24 PM

0 Miembros y 1 Visitante están viendo este tema.

soyloqbuskas

Buenas!

Quiero hacer un programa para enviar paquetes TCP y paquetes IP, solo enviar. ¿Me podeis decir alguna libreria e instrucciones basicas para poder hacerme el programa?
El programa lo voy ha hacer en C y sobre linux.

Gracias, un saludo!
"Si tienes 1 manzana y yo tengo otra manzana...
y las intercambiamos, ambos seguiremos teniendo 1 manzana.
Pero...si tu tienes 1 idea y yo tengo otra idea...
y las intercambiamos, ambos tendremos 2 ideas."


George Bernard Shaw

vikour92

Lo de enviar paquetes yo lo he intentado pero lo he dejado para más tarde ya que quiero ahondar más en C y C++. Pero te voy a pasar información en la que yo me base:

- Mira esta página, explica como va la estructura de la red un poco y como hacer comunicaciones en C.
http://www.chuidiang.com/clinux/sockets/sockets_simp.php

Espero que te sirva de ayuda. Yo supongo que si quieres ahondar más, yo te recomiendo que hagas lo que voy a hacer yo que es comprar un libro sobre eso en particular. Aunque creo que por un hilo del foro había varios libros en PDF.

Un saludo.

soyloqbuskas

Gracias por la ayuda.

Yo mas que un libro sobre redes lo que necesito es saber mas de C. La teoria de redes me la se bastante bien, mi problema viene al implementarlo.

Lo que pretendo es hacer un programa tipo hping3. Este es un programa que te permite mandar paquetes TCP (y de mas tipo) dejandote elegir la ip de origen, la ip de destino, el nº de secuencia, el nº de ACK, y los FLAGS de TCP.

Entonces solo necesito (mas o menos) sabes cual es la instruccion de C para enviar un paquete TCP pasandole por parametro los campos de la cabecera de un paquete TCP.

Un saludo.
"Si tienes 1 manzana y yo tengo otra manzana...
y las intercambiamos, ambos seguiremos teniendo 1 manzana.
Pero...si tu tienes 1 idea y yo tengo otra idea...
y las intercambiamos, ambos tendremos 2 ideas."


George Bernard Shaw

vikour92

Creo recordar, que en el enlace que te he pasado te enseñaba a enviar paquetes TCP/IP con C. Al principio empieza con la teoría pero al final hace un ejemplo práctico, además, te deja descargarte un programa que el de la página hizo para que te sirva como ejemplo.

Lo de libro, me refiero a un libro de C en el que implemente las redes.

Un saludo.

Eternal Idol

Me da la impresion de que buscas esto: raw sockets.
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

soyloqbuskas

Muchas gracias!

Eso es precisamente lo que necesitaba.

Bueno por ahora tengo este codigo....y ando un poco atascado.
No se como especificar mi ip de origen, y tampoco se porque me manda los FLAGS: FYN SYN PSH y NS, cuando en realidad solo deberia mandar el SYN....

#include <sys/types.h>
#define __FAVOR_BSD
#include <sys/socket.h>
#include <stdio.h>
#include <netdb.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <string.h>
char data[1024] = "";



unsigned short csum(unsigned short *buf,int nwords)
{
//this function returns the checksum of a buffer
unsigned long sum;
for (sum = 0; nwords > 0; nwords--){sum += *buf++;}
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
return (unsigned short) (~sum);
}

int createRaw(int protocol_to_sniff)
{
int raw_fd = socket(AF_INET, SOCK_RAW, protocol_to_sniff);
if (raw_fd < 0)
{
printf("ERROR creating raw socket\n");
return(1);
}else{
printf( "Raw Socket Created! :-D\n");
return raw_fd;
}
}
int bindRaw(int socketToBind,struct sockaddr_in *sin)
{
int err = bind(socketToBind,(struct sockaddr *)sin,sizeof(*sin));
if (err < 0)
{
printf("ERROR binding socket.\n");
return(1);
}else{
printf("Bound socket! :-D\n");
return 0;
}
}

int main(int argc,char* argv[])
{
//create raw socket for binding
int bindSocket = createRaw(6);

//create structures
struct sockaddr_in sin;
unsigned char packetBuf[4096];

//specify port to bind to
bzero((char *)&sin,sizeof(sin));
sin.sin_port = htons(55000);

//bind socket
bindRaw(bindSocket,&sin);

//inform os of recieving raw ip packet
{
int tmp = 1;
setsockopt(bindSocket, 0, IP_HDRINCL,&tmp,sizeof(tmp));
}

//re-use socket structure
//Details about where this custom packet is going:
bzero((char *)& sin, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_port = htons(55000); //port to send packet to
sin.sin_addr.s_addr = inet_addr("173.194.34.215"); //IP to send packet to


unsigned short buffer_size = sizeof(struct ip) + sizeof(struct tcphdr);//+ sizeof(data);
//cout << "Buffer size: " << buffer_size << endl;

struct ip *IPheader = (struct ip *) packetBuf;
struct tcphdr *TCPheader = (struct tcphdr *) (packetBuf + sizeof (struct ip));

//Fill out IP Header information:
IPheader->ip_hl = 5;
IPheader->ip_v = 4; //IPv4
IPheader->ip_tos = 0; //type of service
IPheader->ip_len = htons(buffer_size); //length
IPheader->ip_id = htonl(54321);
IPheader->ip_off = 0;
IPheader->ip_ttl = 255; //max routers to pass through
IPheader->ip_p = 6; //tcp
IPheader->ip_sum = 0; //Set to 0 before calulating later
IPheader->ip_src.s_addr = inet_addr("11.11.11.11"); //source IP address
IPheader->ip_dst.s_addr = inet_addr("173.194.34.215"); //destination IP address

//Fill out TCP Header information:
TCPheader->th_sport = htons(55000); //source port
TCPheader->th_dport = htons(55000); //destination port
TCPheader->th_seq = 0;
TCPheader->th_ack = 0; //Only 0 on initial SYN
TCPheader->th_off = 0;
TCPheader->th_flags = TH_SYN; //SYN flag set
TCPheader->th_win = htonl(65535); //used for segmentation
TCPheader->th_sum = 0; //Kernel fill this out
TCPheader->th_urp = 0;

//Now fill out the checksum for the IPheader
IPheader->ip_sum = csum((unsigned short *) packetBuf, IPheader->ip_len >> 1);
//cout << "IP Checksum: " << IPheader->ip_sum << endl;
//create raw socket for sending ip packet
int sendRaw = createRaw(6);
if (sendRaw < 0)
{
printf( "ERROR creating raw socket for sending.\n");
return(1);
}else{
printf( "Raw socket created for sending! :-D\n");
}
int sendErr = sendto(sendRaw,packetBuf,
sizeof(packetBuf),0,(struct sockaddr *)&sin,sizeof(sin));

if (sendErr < sizeof(packetBuf))
{
//cout << sendErr << " out of " << sizeof(packetBuf) << " were sent.\n";
return(1);
}else{
//cout << "<" << sendErr << "> Sent message!!! :-D\n";
}

printf( "Sleeping for 2 seconds");
sleep(1);
printf(".");
sleep(1);
printf(".\n");
char recvPacket[4096] = "";
int newData = recv(bindSocket,recvPacket,sizeof(recvPacket),0);
if (newData <=0)
{
//cout << newData << " returned by recv! :(\n";
return(1);
}else{
//cout << "<" << newData << "> RECIEVE SUCCESSFULL!! :-D\n";
}

return 0;
}



¿alguna idea?

Gracias.
"Si tienes 1 manzana y yo tengo otra manzana...
y las intercambiamos, ambos seguiremos teniendo 1 manzana.
Pero...si tu tienes 1 idea y yo tengo otra idea...
y las intercambiamos, ambos tendremos 2 ideas."


George Bernard Shaw

soyloqbuskas

¡Buenas a todos!

Bueno, dado mi nivel de mediocridad para el lenguaje C al final no he sabido solucionar el problema....pero he encontrado un enlace espectacular donde esta el codigo que necesitaba bien programado. La verdad es que la info de este blog es buenisima y muy recomendable para la gente que quiera programar socket y aprender sobre estos.

http://dlerch.blogspot.com.es/2007/05/raw-sockets.html

Un saludo.
"Si tienes 1 manzana y yo tengo otra manzana...
y las intercambiamos, ambos seguiremos teniendo 1 manzana.
Pero...si tu tienes 1 idea y yo tengo otra idea...
y las intercambiamos, ambos tendremos 2 ideas."


George Bernard Shaw

bitBuffer

No logro entender esta linea del codigo:

struct ip *IPheader = (struct ip *) packetBuf;

Porque se declara un array y se hace la conversion?.

Eternal Idol

Comodidad mas que nada, un paquete contiene varias estructuras que varian de acuerdo al tipo (TCP o UDP por ejemplo) y sendto recibe como parametro un puntero a char. En este caso podes ver que usa primero IP y despues TCP en la siguiente linea:

struct tcphdr *TCPheader = (struct tcphdr *) (packetBuf + sizeof (struct ip));

Es decir que justo despues de la estructura IP viene la TCP (para eso usa el tamaño de la estructura ip con sizeof).

Despues de llenar ambas:

int sendErr = sendto(sendRaw,packetBuf,
sizeof(packetBuf),0,(struct sockaddr *)&sin,sizeof(sin));
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón