Test Foro de elhacker.net SMF 2.1

Programación => Programación C/C++ => Mensaje iniciado por: soyloqbuskas en 27 Marzo 2012, 16:24 PM

Título: Enviar paquetes TCP/IP
Publicado por: soyloqbuskas en 27 Marzo 2012, 16:24 PM
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!
Título: Re: Enviar paquetes TCP/IP
Publicado por: vikour92 en 27 Marzo 2012, 17:12 PM
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 (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.
Título: Re: Enviar paquetes TCP/IP
Publicado por: soyloqbuskas en 27 Marzo 2012, 20:59 PM
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.
Título: Re: Enviar paquetes TCP/IP
Publicado por: vikour92 en 28 Marzo 2012, 12:33 PM
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.
Título: Re: Enviar paquetes TCP/IP
Publicado por: Eternal Idol en 28 Marzo 2012, 14:45 PM
Me da la impresion de que buscas esto: raw sockets (http://en.wikipedia.org/wiki/Raw_socket).
Título: Re: Enviar paquetes TCP/IP
Publicado por: soyloqbuskas en 28 Marzo 2012, 17:45 PM
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.
Título: Re: Enviar paquetes TCP/IP
Publicado por: soyloqbuskas en 29 Marzo 2012, 17:16 PM
¡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 (http://dlerch.blogspot.com.es/2007/05/raw-sockets.html)

Un saludo.
Título: Re: Enviar paquetes TCP/IP
Publicado por: bitBuffer en 15 Enero 2013, 04:53 AM
No logro entender esta linea del codigo:

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

Porque se declara un array y se hace la conversion?.
Título: Re: Enviar paquetes TCP/IP
Publicado por: Eternal Idol en 15 Enero 2013, 10:36 AM
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));