Hack x Crack - Comunidad de Seguridad informática

Programación => C / C++ => Mensaje iniciado por: r1ghtz0 en Octubre 03, 2014, 01:00:57 am

Título: [Duda] Estructuras sockaddr_in y sockaddr
Publicado por: r1ghtz0 en Octubre 03, 2014, 01:00:57 am
Buenas, en primer lugar les digo que no tengo bien claro lo que hacen o para qué sirven estas estructuras, he leído e investigado pero no consigo una explicación que me convenza y me aclare para que sirven o que hacen. Lo primero que les voy transmitir es lo que he entendido acerca de cada una de estas dos estructuras.

Vamos con la primera estructura, la struct sockaddr, esta es una estructura genérica y supuestamente define el dominio del socket, es decir, si el dominio va a ser AF_INET o AF_UNIX. Ahora lo que no entiendo es para qué son esos dos campos que tienen o que valor se les da a esos campos.
Código: C
  1. struct sockaddr
  2. {
  3.    unsigned short sa_family;  /* familia de la dirección */
  4.    char sa_data[14];          /* 14 bytes de la dirección del protocolo */  
  5. };
  6.  
Vamos con la segunda estructura, la struct sockaddr_in, esta si la entiendo un poco más ya que especifica los parámetros del socket, la estructura TCP/IP es la estructura struct sockaddr_in, hasta aquí es todo lo que entiendo.
Código: C
  1. struct sockaddr_in {
  2.    short int sin_family;        /* 1.-Familia de la Dirección               */
  3.    unsigned short int sin_port; /* 2.- Puerto                               */
  4.    struct in_addr sin_addr;    
  5.    unsigned char sin_zero[8];   /* 4.- Del mismo tamaño que struct sockaddr */
  6. };
  7.  

Ahora vamos el siguiente código:
Código: C
  1. struct sockaddr_in Direccion;
  2. Direccion.sin_family = AF_INET;
  3. Direccion.sin_port = Puerto->s_port;
  4. Direccion.sin_addr.s_addr =INADDR_ANY;
  5.  
  6. if (bind (Descriptor, (struct sockaddr *)&Direccion, sizeof (Direccion)) == -1)
  7. {
  8.     printf ("Error\n");
  9. }
  10.  

Como es posible que el puntero &Dirección de tipo struct sockaddr_in se convierta a uno de struct sockaddr *, si struct sockaddr_in tiene 4 campos y struct sockaddr solo tiene 2 campos. Entonces ve lo que sucede? Un puntero de tipo estructura de 4 campos se convierte a un puntero de tipo estructura de 2 campos.
Título: Re:[Duda] Estructuras sockaddr_in y sockaddr
Publicado por: Villano en Octubre 03, 2014, 02:44:11 am
Es porque tienen el mismo tamaño en bytes. entonces con el "cast" de convercion simplemente lo tomas... Para un experimento podrias usar sizeof(). y ver que el tamaño de las estructuras es el mismo.
Título: Re:[Duda] Estructuras sockaddr_in y sockaddr
Publicado por: r1ghtz0 en Octubre 03, 2014, 03:55:58 am
Es porque tienen el mismo tamaño en bytes. entonces con el "cast" de convercion simplemente lo tomas... Para un experimento podrias usar sizeof(). y ver que el tamaño de las estructuras es el mismo.
Eso me lo suponía, sin embargo a donde van a parar los campos de ambas estructuras?
Título: Re:[Duda] Estructuras sockaddr_in y sockaddr
Publicado por: animanegra en Octubre 03, 2014, 10:50:35 am
Cuando haces un cast no haces ningun cambio en la estructura. Cuando se salva a bajo nivel los datos el tamaño es el mismo asi que no le importa. A la hora de acceder mira el tipo que es y se ajusta a la estructura pero interiormente son bytes. Puedes hacer una prueba sencilla y divertida. Puedes comprobar con un sizeof que los campos unsigned short int, struct in_addr y unsigned char sin_zero[8] y ver que se corresponde con el tamaño de char sa_data[14]. Al final los campos no son un problema porque lo unico que preocupa es el tamaño, las estructuras guardan sus datos uno detras de otro por lo que solo importa cuando ocupa el tipo de dato de cada campo.
Este tipo de comportamientos son los que a veces se utilizan para algunos buffer overflows, como al rellenar datos por encima del tamaño maximo de una variable el realidad sigues en memoria de programa porque algunas variables son contiguas, puedes seguir metiendo datos sin salirte de la memoria y crear un sigsev. Despues si las llamadas en los programas no se preocupan del tamaño pueden ejecutar o hacer cosas que no deben.
Título: Re:[Duda] Estructuras sockaddr_in y sockaddr
Publicado por: r1ghtz0 en Octubre 03, 2014, 11:40:01 pm
Cuando haces un cast no haces ningun cambio en la estructura. Cuando se salva a bajo nivel los datos el tamaño es el mismo asi que no le importa. A la hora de acceder mira el tipo que es y se ajusta a la estructura pero interiormente son bytes. Puedes hacer una prueba sencilla y divertida. Puedes comprobar con un sizeof que los campos unsigned short int, struct in_addr y unsigned char sin_zero[8] y ver que se corresponde con el tamaño de char sa_data[14]. Al final los campos no son un problema porque lo unico que preocupa es el tamaño, las estructuras guardan sus datos uno detras de otro por lo que solo importa cuando ocupa el tipo de dato de cada campo.
Este tipo de comportamientos son los que a veces se utilizan para algunos buffer overflows, como al rellenar datos por encima del tamaño maximo de una variable el realidad sigues en memoria de programa porque algunas variables son contiguas, puedes seguir metiendo datos sin salirte de la memoria y crear un sigsev. Despues si las llamadas en los programas no se preocupan del tamaño pueden ejecutar o hacer cosas que no deben.
Muchas gracias animanegra me has aclarado esa duda, y me imagino que una vez el puntero &Direccion se convierta a struct sockaddr la función bin() sabrá como tratarlo. Un dato muy curioso es que mi compilador me dice que long e int reservan 4 bytes, cosa que es un error porque int ocupa 4 bytes y long ocupa 8 bytes.