#include #include #include #include #include #include #include int MakeSocketAddr( struct sockaddr *sockaddrPtr, /* socket address */ char *hostname, /* name or ip of host. NULL implies INADDR_ANY */ int port, /* port number */ char dotted_ip[16]) { /* resolved ip addr */ /* Workaround for cases, where the local cache is not updated (yet) often, gethostbyname gets a cached value, but dig will get a fresh one note after an internet research: dig is recommended over nslookup */ struct hostent *hostent; /* Host database entry */ struct sockaddr_in *sadr = (struct sockaddr_in *)sockaddrPtr; FILE *fil; char line[256]; int l; (void) memset(sadr, 0, sizeof(*sadr)); if (dotted_ip) { /* default value: failure */ dotted_ip[0] = 0; } sadr->sin_family = AF_INET; sadr->sin_port = htons((unsigned short)port); if (hostname == NULL) { /* do not need to copy, as INADDR_ANY is all zero bytes */ return 1; } if (inet_pton(AF_INET, hostname, &sadr->sin_addr) == 1) { /* resolved as dotted numbers notation */ return 1; } hostent = gethostbyname(hostname); if (hostent == 0) { /* we assume that when gethostname gets no entry, dig will also fail. That way, dig will not be called repeatedly for no reason */ return 0; } /* copy the address: in case dig fails, we use the cached value */ memcpy(&sadr->sin_addr, hostent->h_addr_list[0], 4); /* we use hostent->h_name instead of hostname here, as this has already the proper domain added */ snprintf(line, sizeof line, "timeout 1 dig +short %s", hostent->h_name); fil = popen(line, "r"); if (fil != NULL) { if (fgets(line, sizeof(line), fil) != NULL) { l = strlen(line); if (line[l-1] <= ' ') line[l-1] = 0; /* strip off newline */ /* silently ignore return value, if it fails, we take the cached value */ inet_pton(AF_INET, line, &sadr->sin_addr); } fclose(fil); } if (dotted_ip) { inet_ntop(AF_INET, &sadr->sin_addr, dotted_ip, 16); } return 1; } int CreateSocketAdress(struct sockaddr_in *sockaddrPtr, /* Socket address */ char *host, /* Host. NULL implies INADDR_ANY */ int port) { return MakeSocketAddr((struct sockaddr *)sockaddrPtr, host, port, NULL); }