C++ La fonction getaddrinfo(...)

Par Cinux, le 10 février 2017Lire la suite

J'utilisais habituellement la fonction gethostbyname2() pour récupérer l'adresse IP d'un nom de domaine pour mes softs en C++. En relisant la man page je suis tombé sur ceci:
" gethostbyname*(), gethostbyaddr*(), herror() et hstrerror() sont déconseillées. Les applications devraient utiliser getaddrinfo(3), getnameinfo(3) et gai_strerror(3) à la place."
La fonction getaddrindo() permet de récupérer des informations une ou plusieurs machines distantes. Voyons en premier lieu, les différents prototypes dont nous aurons besoin:

/************* P R O T O *************/
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>

int getaddrinfo(const char *nodename, const char *servname,
                const struct addrinfo *hints, struct addrinfo **res);

void freeaddrinfo(struct addrinfo *ai);

const char* gai_strerror(int ecode);

struct addrinfo {
  int     ai_flags;              // AI_PASSIVE, AI_CANONNAME, ...
  int     ai_family;            // AF_xxx
  int     ai_socktype;       // SOCK_xxx
  int     ai_protocol;         // 0 (auto) or IPPROTO_TCP, IPPROTO_UDP 

  socklen_t  ai_addrlen;        // length of ai_addr
  char   *ai_canonname;       // canonical name for nodename
  struct sockaddr  *ai_addr;  // binary address
  struct addrinfo  *ai_next;    // next structure in linked list
};
/******************* E N D   C O D E *****************/


La fonction getaddrinfo():
Elle retourne 0 si elle réussi et un code d'erreur en cas de problème (voir man getaddrinfo).
  • const char* nodename est le nom de l'hôte. Il peut être une IP de la forme 123.123.123.123 ou un nom de domaine comme un.exemple.com.
  • const char* servname est le nom du service. Il s'agit typiquement d'un port, mais on peut aussi lui passer des chaînes de caractères comme ftp, http... Ce paramètre peut être NULL.
  • struct addrinfo* hints pointe sur une structure addrinfo qui indique les critères de sélection des structures d'adresses de sockets renvoyées dans la liste pointée par res. Si hints n'est pas NULL, il doit pointer sur une structure addrinfo dont les membres ai_family, ai_socktype, et ai_protocol indiquent les critères limitant l'ensemble d'adresses de sockets renvoyées par getaddrinfo().
  • struct addrinfo** res pointe sur une liste de structures addrinfo qui auront été créé par la fonction grâce aux paramètres passés via 'hints'.

    Exemple:
    #include <itostream>
    #include <string.h>
    #include <sys/socket.h>
    #include <sys/types.h>
    #include <netdb.h>
    #include <arpa/inet.h>
    
    int main() 
    {
        const  std::string       hostname = "qwant.com";
        struct addrinfo          hints; 
        struct addrinfo         *addrLst;
        struct sockaddr_in       sin;
    
        memset(&hints, 0, sizeof(hints)); // initialisation à 0 de la structure
        // On paramètre ensuite hints
        hints.ai_family     =   AF_INET; // AF_INET6 pour de l'ipv6
        hints.ai_socktype   =   SOCK_STREAM; // On est en TCP. Pour l'UDP on utilisera SOCK_DGRAM
        hints.ai_protocol   =   0;
        hints.ai_addr       =   NULL;
        hints.ai_canonname  =   NULL;
        hints.ai_next       =   NULL;
    
    
        int info = getaddrinfo(hostname.c_str(), NULL, &hints, &addrLst);
        if (info != 0) // On vérifie que tout se soit bien passé
        {
            // gai_strerror prend en arg le code d'erreur. 
            std::cout << hostname.c_str() << " : " <<  gai_strerror(info) <<  std::endl; 
            return 1;
        }
    
         // On stock l'adresse du serveur dans sin pour pouvoir l'utiliser au format sockaddr_in
        sin.sin_addr    = *(struct sockaddr_in*)info_retv->ai_addr; 
        sin.sin_family  = AF_INET;
    
        std::cout << "IP du serveur = " << inet_ntoa(sin.sin_addr) << std::endl; 
    
        freeaddrinfo(addrLst);    // On n'oublie pas de rendre la mémoire au système 
        return 0;
    }
  • Hey!

    J'ai fait un petit script en python qui permet rapidement de mettre en avant l'importance de n'utiliser que des mots de pass forts

    Le fonctionnement est simple. Vous entrez un mot de pass à tester. Il vous affichera le nombre de combinaisons possibles en fonction ds caractères utilisés et de la taille du pass. Ensuite il vous propose d'afficher les combinaisons testées à l'écran ou non. Une fois lancé il teste toutes les combinaisons les unes après les autres, puis affiche le nombre de combinaisons testées et le temps qu'il a mis à tester.

    Afin de bien insister sur la vitesse de calcul je fais le test en live avec mon pc portable.
  • Je commence par faire un test par bruteforce sur un pass genre "totot". En acceptant d'afficher les combinaisons testées à l'écran, il teste 2 050 289 combinaisons en 17.81 secondes. On peut en conclure qu'il teste environ 115 100 combinaisons par secondes)
  • Je fais ensuite le même test mais sans afficher les combinaisons testées (car cela consomme BEAUCOUP de ressources). Il teste alors les 2 050 289 combinaisons en 1.35 secondes, soit 1 518 700 combinaisons par secondes!

    Lorsque l'on sait que l'on peut aller encore bien plus vite en utilisant les processeurs des cartes graphiques, on réfléchi à deux fois avant d'utiliser un mot de pass comme "toto".

    Vous trouverez le script sur GitHub (https://github.com/mistercinux/BFSpeed). Je n'ai pas de dictionnaire de pass fourni par défaut il faudra donc utiliser les vôtres. Bien sure si vous détectez un bug n'hésitez pas à le faire remonter.
  • Algorithmes de tri

    Par Cinux, le 15 décembre 2016Lire la suite

    Hey! En recherchant un moyen de trier efficacement les données à l'aide d'un script, je suis tombé sur ce site : http://lwh.free.fr/pages/algo/tri/tri.htm Inutile de faire de grands discours. Le site présente les différents algorithmes de tri et les compare. Si vous êtes curieux, ca vaut le détour!