Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- https://seguridadyredes.wordpress.com/2009/11/05/wireshark-windump-analisis-capturas-trafico-red-interpretacian-datagrama-ip-actualizacian/
- http://www.thegeekstuff.com/2012/05/ip-header-checksum/
- https://en.wikipedia.org/wiki/IPv4
- http://www.tcpipguide.com/free/t_IPDatagramEncapsulation.htm
- http://lacl.u-pec.fr/cegielski/sec/ch2.pdf
- Para conectarse a la web la tarjeta de red debe transmitir un paquete IP que encapsula un segmento especial del TCP.
- El programa (en C++) debe leer la dirección IP fuente (en formato x.x.x.x y se debe asegurar que cada x sea un entero en el rango [0,255]),
- la dirección IP de destino, el puerto TCP de destino (en un rango [1,65535]) y cree el paquete IP que encapsule el segmento TCP requerido
- y este se debe almacenar en formato hexadecimal en un archivo seleccionado por el usuario donde cada línea contenga 16 bytes.
- *Importante: si la dirección IP comienza con 130.140 o 160.170 y el puerto TCP de destino es 80 NO se debe generar el paquete IP!!
- En las imagenes el formato de los headers de IPv4 y TCP
- */
- #include <iostream>
- #include <vector>
- #include <string>
- #include <cmath>
- #include <limits.h>
- #include <iomanip>
- using namespace std;
- //La funcion de estos "defines" es efectuar test sin escribir entradas y proporcionarlos como parametros al constructor de la clase
- /*
- #define _VERSION 0x4 //4 en ipv4 o 6 ipv6
- #define _IHL 0x5 //Longitud de la Header en palabras de 32bits 5*32=160bits 20bytes ....
- #define _TOS 0x00 //TypeService
- #define _LENGTH 0x003C //60...SOLO TEST ....
- #define _ID 0x1C46//SOLO TEST ....
- #define _FLAGS 0x4
- #define _FRAGMENT_OFFSET 0x0000
- #define _TTL 0x40 //128 mpide que un paquete esté indefinidamente viajando por la red. 128 indica que cada vez que un datagrama atraviese un router este numero se decrementa en 1. cuando el TTL llege a 0 el datagrama se descarta y se informa de ello al origen con un mensaje de tiempo excedido.
- #define _PROTOCOL 0x06 //TCP UDP SCTP
- #define _SOURCE_IP 0xAC100A63 //172.16.0.99 TESTs.....
- #define _DEST_IP 0xAC100A0C //172.16.0.12
- */
- //Otro test del header IPV4
- #define _VERSION 0x4 //4 en ipv4 o 6 ipv6
- #define _IHL 0x5 //Longitud de la Header en palabras de 32bits 5*32=160bits 20bytes ....
- #define _TOS 0x00 //TypeService
- #define _LENGTH 0x003C //60...SOLO TEST ....
- #define _ID 0x2ADF//SOLO TEST ....
- #define _FLAGS 0x0
- #define _FRAGMENT_OFFSET 0x000
- #define _TTL 0x80 //128 mpide que un paquete esté indefinidamente viajando por la red. 128 indica que cada vez que un datagrama atraviese un router este numero se decrementa en 1. cuando el TTL llege a 0 el datagrama se descarta y se informa de ello al origen con un mensaje de tiempo excedido.
- #define _PROTOCOL 0x11 //UDP
- #define _SOURCE_IP 0xC0A8010C //192.168.1.12 TESTs.....
- #define _DEST_IP 0xC0A80101 //192.168.1.1
- //Activa o desactiva el formato HEX en COUT<<
- #define HEX_ON std::cout.setf ( std::ios::hex, std::ios::basefield );std::cout.setf ( std::ios::showbase );
- #define HEX_OFF std::cout.unsetf ( std::ios::showbase );std::cout.setf ( std::ios::dec, std::ios::basefield );
- //----------------------------------------------------------------------
- //Enumeracion para acceso por "nombre" o desde un bucle,puede usarlo la struct HeaderIp ..
- enum fieldDatagram: int {VERSION_,IHL_,TOS_,TOTAL_LENGTH_,ID_,FLAGS_,FRAGMENT_OFFSET_,TTL_,PROTOCOL_,HEADER_CHEKSUM_,SOURCE_ADDRESS_,DESTINATION_ADDRESS_};
- //----------------------------------------------------------------------
- //Se usa para mostrar el nombre del campo asociado ....
- const string campo[]={"VERSION\t\t","IHL\t\t","TOS\t\t","TOTAL_LENGTH\t","ID\t\t","FLAGS\t\t","FRAGMENT_OFFSET\t","TTL\t\t","PROTOCOL\t","HEADER_CHEKSUM\t",
- "SOURCE_ADDRESS\t","DESTINATION_ADDRESS"};
- //----------------------------------------------------------------------
- //Estructura Header Ip IPV4
- typedef struct{//Cabecera de 20 bytes IHL==5 sin OPTION
- unsigned char VERSION:4;//IPV4 = 4 IPV6 =6
- unsigned char IHL:5;//Longitud cabecera ,valor minimo 5 5*32=160 bits ,cabecera de 20 bytes !,indica donde termina la cabecera del programa.
- unsigned char TOS;//8 TypeService
- unsigned short TOTAL_LENGTH ;//16 Longitud total del datagrama medida en octetos ,incluyendo datos encapsulados ,cabecera y datos ...max 65,535 bytes
- unsigned short ID;//16 Num. de identificacion unico del datagrama, para reensamblado posterior
- unsigned char FLAGS:3;//1er bit 0 , 2o. NO fragmentacion ,3o. activo en todos excepto el ultimo (no hay mas fragmentos)
- unsigned short FRAGMENT_OFFSET:13;//Posicion dentro del datagrama en caso de fragmentacion
- unsigned char TTL;//8 TimeToLive Tiempo de vida , impide que el paquete viaje indefinidamente por la red , cada router decrementa uno
- unsigned char PROTOCOL;//8 Protocolo de siguiente nivel se usa en parte de datos TCP =6
- unsigned short HEADER_CHEKSUM;//16 CRC calculo CRC de esta cabecera ,suma y complemento
- unsigned int SOURCE_ADDRESS:32;//IP ORIGEN
- unsigned int DESTINATION_ADDRESS:32;//IP DESTINO
- int retcampo (int sel){//Funcion interna , permite el direccioanmiento de los campos desde un bucle for p.e
- switch (sel){
- case VERSION_:return VERSION;
- case IHL_:return IHL;
- case TOS_:return TOS;
- case TOTAL_LENGTH_:return TOTAL_LENGTH;
- case ID_:return ID;
- case FLAGS_:return FLAGS;
- case FRAGMENT_OFFSET_:return FRAGMENT_OFFSET;
- case TTL_:return TTL;
- case PROTOCOL_:return PROTOCOL;
- case HEADER_CHEKSUM_:return HEADER_CHEKSUM;
- case SOURCE_ADDRESS_:return SOURCE_ADDRESS;
- case DESTINATION_ADDRESS_:return DESTINATION_ADDRESS;
- default :return -1;//No hay resultados
- };
- }
- }HeaderIp;
- //----------------------------------------------------------------------
- //------------------------Declaracion-----------------------------------
- //----------------------------------------------------------------------
- class DatagramIp{
- public:
- //Constructor con parametros por defecto para efectuar tests..
- DatagramIp (unsigned char VERSION=_VERSION,unsigned char IHL=_IHL,unsigned char TOS=_TOS,unsigned short TOTAL_LENGTH=0,
- unsigned short ID=0,unsigned char FLAGS=_FLAGS,unsigned char FRAGMENT_OFFSET=_FRAGMENT_OFFSET,unsigned char TTL=_TTL,
- unsigned char PROTOCOL=_PROTOCOL,unsigned short HEADER_CHEKSUM=0,
- unsigned int SOURCE_ADDRESS=_SOURCE_IP,unsigned int DESTINATION_ADDRESS=_DEST_IP
- );
- ~DatagramIp ();
- void muestraHeader();//Muestra en formato Hex 32 bits el datagrama IP , ...la Header
- void muestraPacket()const;//Muestra el paquete packetIp formado por 20 chars ...
- bool lecturaIp();
- bool escribirFichero();
- void packet();//Crea el packet de 20 bytes
- string HexToIp(unsigned int hexIp);//Transforma una direccion en formato Hex a un string en formato ip
- unsigned short int calculoCRC();
- private:
- HeaderIp header;
- //unsigned char packetIp[20];//20 Ip header empaquetada .. 20*8=160 bits ,bytess=[ihl*32/8]
- //El datagrama puede ser variable por las OPCIONES, valor minimo 5*4W=20bytes ...
- unsigned char *packetIp=new unsigned char [(header.IHL*32)/8];//Ip header de base 20 bytes ihl(5)*32/8=
- };
- //----------------------------------------------------------------------
- //-------------------------Implementacion-------------------------------
- //----------------------------------------------------------------------
- //Constructor con parametros por defecto para efectuar tests..
- DatagramIp::DatagramIp (unsigned char VERSION,unsigned char IHL,unsigned char TOS,unsigned short TOTAL_LENGTH,
- unsigned short ID,unsigned char FLAGS,unsigned char FRAGMENT_OFFSET,unsigned char TTL,
- unsigned char PROTOCOL,unsigned short HEADER_CHEKSUM,
- unsigned int SOURCE_ADDRESS,unsigned int DESTINATION_ADDRESS):
- header({_VERSION,_IHL,_TOS,_LENGTH,_ID,_FLAGS,_FRAGMENT_OFFSET,_TTL,_PROTOCOL,0,_SOURCE_IP,_DEST_IP}){}
- //----------------------------------------------------------------------
- //----------------------------------------------------------------------
- DatagramIp::~DatagramIp(){delete [] packetIp;}
- //----------------------------------------------------------------------
- //----------------------------------------------------------------------
- //Muestra en formato Hex 32 bits el datagrama IP , ...la Header
- void DatagramIp::muestraHeader(){
- HEX_ON
- cout <<endl<<"------------DATOS HEADER -----------------"<<endl;
- for (int field =VERSION_;field<=DESTINATION_ADDRESS_;field++ ){
- cout<<campo[field]<<"\t= "<<header.retcampo(field)
- <<((field==SOURCE_ADDRESS_ || field==DESTINATION_ADDRESS_) ? HexToIp(header.retcampo(field)):"\0")
- << endl;
- }
- HEX_OFF
- }
- //----------------------------------------------------------------------
- //----------------------------------------------------------------------
- unsigned short int DatagramIp::calculoCRC(){
- //Dividimos la cabecera en paquetes de 16bits y sumamos cada una teniendo en cuenta carry
- //Y al final efectuamos el complemento a 1
- unsigned short int res(0);
- int buffer(0);//Dteteccion de carry
- #define CARRY if (buffer>USHRT_MAX){buffer&= 0xFFFF ;buffer++;};//carry >65 535 = 0xFFFF
- header.HEADER_CHEKSUM=0;//Antes del calculo tiene que estar a 0
- for (int x=0,y=1;y<((header.IHL*32)/8);x+=2,y+=2){//Permite un array dinamico en funcion del IHL...
- // for (unsigned int x=0,y=1;y<sizeof (packetIp);x+=2,y+=2){
- buffer+=(packetIp[x]<<8 | packetIp[y] );
- CARRY
- res=buffer;
- }
- header.HEADER_CHEKSUM=~res;//Escribe complemento en la estructura
- #undef CARRY
- return ~res;
- }
- //----------------------------------------------------------------------
- //----------------------------------------------------------------------
- void DatagramIp::packet(){//Crea el packet de 20 bytes
- //Version + IHL
- packetIp[0]=((header.VERSION)<<4) | (header.IHL);
- //TOS
- packetIp[1]=(header.TOS);
- //Total Length
- packetIp[2]=(header.TOTAL_LENGTH)>>8;
- packetIp[3]=(header.TOTAL_LENGTH);
- //----------------------------------------------------------------------
- //Identification
- packetIp[4]=header.ID>>8;
- packetIp[5]=header.ID;
- //Flags+Fragment Offset
- packetIp[6]=((header.FLAGS)<<4)| ((header.FRAGMENT_OFFSET)>>8);
- packetIp[7]=header.FRAGMENT_OFFSET;
- //----------------------------------------------------------------------
- //TimeToLive
- packetIp[8]=header.TTL;
- //Protocol
- packetIp[9]=header.PROTOCOL;
- //Header Checksum
- packetIp[10]=(header.HEADER_CHEKSUM)>>8;
- packetIp[11]=header.HEADER_CHEKSUM;
- //----------------------------------------------------------------------
- //Source Address
- packetIp[12]=header.SOURCE_ADDRESS>>24;
- packetIp[13]=header.SOURCE_ADDRESS>>16;
- packetIp[14]=header.SOURCE_ADDRESS>>8;
- packetIp[15]=header.SOURCE_ADDRESS;
- //----------------------------------------------------------------------
- //Destination Address
- packetIp[16]=header.DESTINATION_ADDRESS>>24;
- packetIp[17]=header.DESTINATION_ADDRESS>>16;
- packetIp[18]=header.DESTINATION_ADDRESS>>8;
- packetIp[19]=header.DESTINATION_ADDRESS;
- }
- //----------------------------------------------------------------------
- //----------------------------------------------------------------------
- void DatagramIp::muestraPacket()const{//Muestra el paquete packetIp formado por 20 chars ...
- std::cout.setf ( std::ios::hex, std::ios::basefield );
- cout <<endl<<"------Analisis packet linea ---------"<<endl;
- //Analisis seguido
- for (int i=0 ;i<((header.IHL*32)/8);i++){//y<sizeof (packetIp)
- cout <<' '<<setfill('0') << setw(2)<<(int) packetIp[i];
- }
- /*
- std::cout.setf ( std::ios::showbase );
- cout <<endl<<"----- Analisis packet ---------"<<endl;
- //Analisis por lineas y posicion en array
- for (int i=0 ;i<((header.IHL*32)/8);i++){//y<sizeof (packetIp)
- cout <<"["<<i<<"] ="<< setfill('0') << setw(4)<<(int) packetIp[i]<<endl;
- }
- */
- HEX_OFF
- }
- //----------------------------------------------------------------------
- //----------------------------------------------------------------------
- string DatagramIp::HexToIp(unsigned int hexIp){//Transforma una direccion 32bits en formato Hex a un string en formato ip
- string tmp(" ");
- for (int rot=24;rot>=0;rot-=8){ tmp+=std::to_string((hexIp>>rot)&0xFF) + ((rot>0) ? '.':'\0');}
- return tmp;
- }
- //----------------------------------------------------------------------
- //----------------------------------------------------------------------
- int main()
- {
- DatagramIp ip;
- // ip.muestraHeader();//Estado inicial tras su creacion
- ip.packet();//Crea el packet de 20 bytes ihl*4 = 5*4 ....
- HEX_ON
- cout <<endl<<"CRC ="<<ip.calculoCRC()<<endl;//Calculo CRC
- HEX_OFF
- ip.packet ();//Copia nuevos datos de CRC
- ip.muestraPacket();
- ip.muestraHeader();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement