Advertisement
AntonioVillanueva

Header Datagram TCP IP

Aug 22nd, 2016
152
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 12.84 KB | None | 0 0
  1. /*
  2. https://seguridadyredes.wordpress.com/2009/11/05/wireshark-windump-analisis-capturas-trafico-red-interpretacian-datagrama-ip-actualizacian/
  3. http://www.thegeekstuff.com/2012/05/ip-header-checksum/
  4. https://en.wikipedia.org/wiki/IPv4
  5. http://www.tcpipguide.com/free/t_IPDatagramEncapsulation.htm
  6. http://lacl.u-pec.fr/cegielski/sec/ch2.pdf
  7.  
  8. Para conectarse a la web la tarjeta de red debe transmitir un paquete IP que encapsula un segmento especial del TCP.
  9. 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]),
  10.  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
  11.  y este se debe almacenar en formato hexadecimal en un archivo seleccionado por el usuario donde cada línea contenga 16 bytes.
  12.  
  13. *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!!
  14.  
  15. En las imagenes el formato de los headers de IPv4 y TCP
  16. */
  17.  
  18. #include <iostream>
  19. #include <vector>
  20. #include <string>
  21. #include <cmath>
  22. #include <limits.h>
  23. #include  <iomanip>
  24.  
  25. using namespace std;
  26.  
  27. //La funcion de estos "defines" es efectuar test sin escribir entradas y proporcionarlos como parametros al constructor de la clase
  28. /*
  29. #define _VERSION 0x4 //4 en ipv4  o 6 ipv6
  30. #define _IHL 0x5 //Longitud de la Header en palabras de 32bits 5*32=160bits 20bytes ....
  31. #define _TOS 0x00 //TypeService
  32. #define _LENGTH 0x003C //60...SOLO TEST ....
  33. #define _ID 0x1C46//SOLO TEST ....
  34. #define _FLAGS 0x4
  35. #define _FRAGMENT_OFFSET 0x0000
  36. #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.
  37. #define _PROTOCOL 0x06 //TCP     UDP  SCTP
  38. #define _SOURCE_IP 0xAC100A63 //172.16.0.99 TESTs.....
  39. #define _DEST_IP 0xAC100A0C //172.16.0.12
  40. */
  41. //Otro test del header IPV4
  42. #define _VERSION 0x4 //4 en ipv4  o 6 ipv6
  43. #define _IHL 0x5 //Longitud de la Header en palabras de 32bits 5*32=160bits 20bytes ....
  44. #define _TOS 0x00 //TypeService
  45. #define _LENGTH 0x003C //60...SOLO TEST ....
  46. #define _ID 0x2ADF//SOLO TEST ....
  47. #define _FLAGS 0x0
  48. #define _FRAGMENT_OFFSET 0x000
  49. #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.
  50. #define _PROTOCOL 0x11 //UDP
  51. #define _SOURCE_IP 0xC0A8010C //192.168.1.12 TESTs.....
  52. #define _DEST_IP 0xC0A80101 //192.168.1.1
  53.  
  54.  
  55. //Activa o desactiva el formato HEX en COUT<<
  56. #define HEX_ON std::cout.setf ( std::ios::hex, std::ios::basefield );std::cout.setf ( std::ios::showbase );
  57. #define HEX_OFF std::cout.unsetf ( std::ios::showbase );std::cout.setf ( std::ios::dec, std::ios::basefield );
  58.  
  59. //----------------------------------------------------------------------
  60.  //Enumeracion para acceso por "nombre" o desde un bucle,puede usarlo la struct HeaderIp ..
  61.  enum fieldDatagram: int {VERSION_,IHL_,TOS_,TOTAL_LENGTH_,ID_,FLAGS_,FRAGMENT_OFFSET_,TTL_,PROTOCOL_,HEADER_CHEKSUM_,SOURCE_ADDRESS_,DESTINATION_ADDRESS_};
  62. //----------------------------------------------------------------------
  63.  //Se usa para mostrar el nombre del campo asociado ....
  64.  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",
  65.                         "SOURCE_ADDRESS\t","DESTINATION_ADDRESS"};
  66. //----------------------------------------------------------------------
  67. //Estructura Header Ip IPV4  
  68. typedef struct{//Cabecera de 20 bytes IHL==5 sin OPTION
  69.     unsigned char VERSION:4;//IPV4 = 4 IPV6 =6
  70.     unsigned char IHL:5;//Longitud cabecera ,valor minimo 5 5*32=160 bits ,cabecera de 20 bytes !,indica donde termina la cabecera del programa.
  71.     unsigned char TOS;//8 TypeService
  72.     unsigned short TOTAL_LENGTH ;//16 Longitud total del datagrama medida en octetos ,incluyendo datos encapsulados ,cabecera y datos ...max 65,535 bytes
  73.    
  74.     unsigned short ID;//16 Num. de identificacion unico del datagrama, para reensamblado posterior
  75.     unsigned char FLAGS:3;//1er bit 0 , 2o. NO fragmentacion ,3o. activo en todos excepto el ultimo (no hay mas fragmentos)
  76.     unsigned short FRAGMENT_OFFSET:13;//Posicion dentro del datagrama en caso de fragmentacion
  77.     unsigned char TTL;//8 TimeToLive Tiempo de vida , impide que el paquete viaje indefinidamente por la red , cada router decrementa uno
  78.     unsigned char PROTOCOL;//8 Protocolo de siguiente nivel se usa en parte de datos  TCP =6
  79.     unsigned short HEADER_CHEKSUM;//16 CRC calculo CRC de esta cabecera ,suma y complemento
  80.    
  81.     unsigned int SOURCE_ADDRESS:32;//IP ORIGEN
  82.     unsigned int DESTINATION_ADDRESS:32;//IP DESTINO  
  83.    
  84.     int retcampo (int sel){//Funcion interna , permite el direccioanmiento de los campos desde un bucle for p.e
  85.         switch (sel){
  86.             case VERSION_:return VERSION;
  87.             case IHL_:return IHL;
  88.             case TOS_:return TOS;
  89.             case TOTAL_LENGTH_:return TOTAL_LENGTH;
  90.            
  91.             case ID_:return ID;
  92.             case FLAGS_:return FLAGS;
  93.             case FRAGMENT_OFFSET_:return FRAGMENT_OFFSET;
  94.             case TTL_:return TTL;
  95.             case PROTOCOL_:return PROTOCOL;
  96.             case HEADER_CHEKSUM_:return HEADER_CHEKSUM;
  97.            
  98.             case SOURCE_ADDRESS_:return SOURCE_ADDRESS;                    
  99.             case DESTINATION_ADDRESS_:return DESTINATION_ADDRESS;      
  100.             default :return -1;//No hay resultados                             
  101.         };     
  102.     }
  103.  
  104. }HeaderIp;
  105. //----------------------------------------------------------------------
  106. //------------------------Declaracion-----------------------------------
  107. //----------------------------------------------------------------------
  108.  
  109. class DatagramIp{
  110.     public:
  111.     //Constructor con parametros por defecto para efectuar tests..
  112.     DatagramIp (unsigned char VERSION=_VERSION,unsigned char IHL=_IHL,unsigned char TOS=_TOS,unsigned short TOTAL_LENGTH=0,
  113.     unsigned short ID=0,unsigned char FLAGS=_FLAGS,unsigned char FRAGMENT_OFFSET=_FRAGMENT_OFFSET,unsigned char TTL=_TTL,
  114.     unsigned char PROTOCOL=_PROTOCOL,unsigned short HEADER_CHEKSUM=0,
  115.     unsigned int SOURCE_ADDRESS=_SOURCE_IP,unsigned int DESTINATION_ADDRESS=_DEST_IP
  116.     );
  117.    
  118.     ~DatagramIp ();
  119.    
  120.     void muestraHeader();//Muestra en formato Hex 32 bits el datagrama IP , ...la Header
  121.     void muestraPacket()const;//Muestra el paquete packetIp formado por 20 chars ...
  122.     bool lecturaIp();
  123.     bool escribirFichero();
  124.     void packet();//Crea el packet de 20 bytes
  125.     string HexToIp(unsigned int hexIp);//Transforma una direccion en formato Hex a un string en formato ip
  126.     unsigned short int calculoCRC();
  127.    
  128.     private:
  129.     HeaderIp header;
  130.     //unsigned char  packetIp[20];//20 Ip header empaquetada .. 20*8=160 bits ,bytess=[ihl*32/8]
  131.     //El datagrama puede ser variable por las OPCIONES, valor minimo 5*4W=20bytes ...
  132.     unsigned char *packetIp=new unsigned char [(header.IHL*32)/8];//Ip header de base 20 bytes ihl(5)*32/8=
  133. };
  134. //----------------------------------------------------------------------
  135. //-------------------------Implementacion-------------------------------
  136. //----------------------------------------------------------------------
  137.  
  138.     //Constructor con parametros por defecto para efectuar tests..
  139.     DatagramIp::DatagramIp (unsigned char VERSION,unsigned char IHL,unsigned char TOS,unsigned short TOTAL_LENGTH,
  140.     unsigned short ID,unsigned char FLAGS,unsigned char FRAGMENT_OFFSET,unsigned char TTL,
  141.     unsigned char PROTOCOL,unsigned short HEADER_CHEKSUM,
  142.     unsigned int SOURCE_ADDRESS,unsigned int DESTINATION_ADDRESS):
  143.     header({_VERSION,_IHL,_TOS,_LENGTH,_ID,_FLAGS,_FRAGMENT_OFFSET,_TTL,_PROTOCOL,0,_SOURCE_IP,_DEST_IP}){}
  144.    
  145. //----------------------------------------------------------------------
  146. //----------------------------------------------------------------------    
  147.    DatagramIp::~DatagramIp(){delete [] packetIp;}
  148. //----------------------------------------------------------------------
  149. //----------------------------------------------------------------------  
  150.     //Muestra en formato Hex 32 bits el datagrama IP , ...la Header
  151.     void DatagramIp::muestraHeader(){
  152.         HEX_ON
  153.          cout <<endl<<"------------DATOS HEADER -----------------"<<endl;
  154.          for (int field =VERSION_;field<=DESTINATION_ADDRESS_;field++ ){
  155.              
  156.              cout<<campo[field]<<"\t= "<<header.retcampo(field)
  157.              <<((field==SOURCE_ADDRESS_ || field==DESTINATION_ADDRESS_) ? HexToIp(header.retcampo(field)):"\0")
  158.              << endl;
  159.          }
  160.         HEX_OFF
  161.     }
  162. //----------------------------------------------------------------------
  163. //----------------------------------------------------------------------    
  164.     unsigned short int DatagramIp::calculoCRC(){
  165.         //Dividimos la cabecera en paquetes de 16bits y sumamos cada una teniendo en cuenta carry
  166.         //Y al final efectuamos el complemento a 1
  167.         unsigned short int res(0);
  168.         int buffer(0);//Dteteccion de carry
  169.        
  170.         #define CARRY if (buffer>USHRT_MAX){buffer&= 0xFFFF ;buffer++;};//carry >65 535 = 0xFFFF
  171.         header.HEADER_CHEKSUM=0;//Antes del calculo tiene que estar a 0
  172.        
  173.         for (int x=0,y=1;y<((header.IHL*32)/8);x+=2,y+=2){//Permite un array dinamico en funcion del IHL...  
  174. //      for (unsigned int x=0,y=1;y<sizeof (packetIp);x+=2,y+=2){
  175.             buffer+=(packetIp[x]<<8 | packetIp[y] );
  176.             CARRY
  177.             res=buffer;        
  178.         }
  179.    
  180.         header.HEADER_CHEKSUM=~res;//Escribe complemento en la estructura
  181.        
  182.     #undef CARRY
  183.         return ~res;
  184.     }
  185. //----------------------------------------------------------------------
  186. //----------------------------------------------------------------------   
  187.    
  188.     void DatagramIp::packet(){//Crea el packet de 20 bytes
  189.        
  190.         //Version + IHL
  191.         packetIp[0]=((header.VERSION)<<4) | (header.IHL);      
  192.                
  193.         //TOS
  194.         packetIp[1]=(header.TOS);
  195.  
  196.         //Total Length
  197.         packetIp[2]=(header.TOTAL_LENGTH)>>8;
  198.         packetIp[3]=(header.TOTAL_LENGTH);
  199. //----------------------------------------------------------------------       
  200.         //Identification
  201.         packetIp[4]=header.ID>>8;
  202.         packetIp[5]=header.ID;
  203.  
  204.         //Flags+Fragment Offset
  205.         packetIp[6]=((header.FLAGS)<<4)| ((header.FRAGMENT_OFFSET)>>8);
  206.         packetIp[7]=header.FRAGMENT_OFFSET;    
  207. //----------------------------------------------------------------------
  208.         //TimeToLive
  209.         packetIp[8]=header.TTL;
  210.        
  211.         //Protocol
  212.         packetIp[9]=header.PROTOCOL;
  213.        
  214.         //Header Checksum
  215.         packetIp[10]=(header.HEADER_CHEKSUM)>>8;
  216.         packetIp[11]=header.HEADER_CHEKSUM;
  217. //----------------------------------------------------------------------
  218.         //Source Address
  219.         packetIp[12]=header.SOURCE_ADDRESS>>24;
  220.         packetIp[13]=header.SOURCE_ADDRESS>>16;
  221.         packetIp[14]=header.SOURCE_ADDRESS>>8;
  222.         packetIp[15]=header.SOURCE_ADDRESS;    
  223.        
  224. //----------------------------------------------------------------------
  225.         //Destination Address
  226.         packetIp[16]=header.DESTINATION_ADDRESS>>24;
  227.         packetIp[17]=header.DESTINATION_ADDRESS>>16;
  228.         packetIp[18]=header.DESTINATION_ADDRESS>>8;
  229.         packetIp[19]=header.DESTINATION_ADDRESS;                                       
  230.     }
  231. //----------------------------------------------------------------------   
  232. //----------------------------------------------------------------------
  233.      void DatagramIp::muestraPacket()const{//Muestra el paquete packetIp formado por 20 chars ...      
  234.         std::cout.setf ( std::ios::hex, std::ios::basefield );
  235.  
  236.         cout <<endl<<"------Analisis packet linea ---------"<<endl;    
  237.         //Analisis seguido
  238.         for (int i=0 ;i<((header.IHL*32)/8);i++){//y<sizeof (packetIp)
  239.             cout <<' '<<setfill('0') << setw(2)<<(int) packetIp[i];
  240.         }
  241. /*
  242.         std::cout.setf ( std::ios::showbase );     
  243.         cout <<endl<<"-----    Analisis packet    ---------"<<endl;
  244.        
  245.         //Analisis por lineas y posicion en array
  246.    
  247.         for (int i=0 ;i<((header.IHL*32)/8);i++){//y<sizeof (packetIp)
  248.             cout <<"["<<i<<"] ="<< setfill('0') << setw(4)<<(int) packetIp[i]<<endl;
  249.  
  250.         }
  251. */     
  252.         HEX_OFF
  253.      }
  254. //----------------------------------------------------------------------
  255. //----------------------------------------------------------------------     
  256.     string DatagramIp::HexToIp(unsigned int hexIp){//Transforma una direccion 32bits  en formato Hex a un string en formato ip   
  257.         string tmp(" ");
  258.         for (int rot=24;rot>=0;rot-=8){ tmp+=std::to_string((hexIp>>rot)&0xFF) + ((rot>0) ? '.':'\0');}
  259.         return tmp;    
  260.     }
  261. //----------------------------------------------------------------------
  262. //----------------------------------------------------------------------
  263. int main()
  264. {
  265.   DatagramIp ip;
  266.  // ip.muestraHeader();//Estado inicial tras su creacion
  267.   ip.packet();//Crea el packet de 20 bytes ihl*4 = 5*4 ....
  268.  
  269.     HEX_ON
  270.     cout <<endl<<"CRC ="<<ip.calculoCRC()<<endl;//Calculo CRC
  271.     HEX_OFF
  272.    
  273.    ip.packet ();//Copia nuevos datos de CRC
  274.    ip.muestraPacket();
  275.    ip.muestraHeader();
  276.  
  277. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement