//Dynu Premium Dynamic DNS Client v2.1 //Copyright (c) 1997-2001 Dynu Systems, Inc. //All rights reserved. //Compile line: g++ premium.c -o dynupremium //Source modified to compile under FreeBSD. //Paul A. Hoadley #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifndef SIOCGIFADDR #include #endif #define DEBUG #define IPLEN 16 #define CONFSTRLEN 64 int debug = 0; int log2syslog = 0; char suppliedIP[IPLEN+6]; char device[CONFSTRLEN]; char ipaddress[IPLEN] = ""; char lastipaddress[IPLEN]; char ipdetect[1]; //1-Server side //2-Client side //3-Both //4-Specify int NAT = 0; int PROXY = 0; int DAEMON = 0; int POLLINTERVAL = 30; struct ac { char first[50], second[70], password[8]; ac *next; }; //Function Definitions BEGIN/////////////////////////////////////////////// int fetchURL(char first[50], char second[70], char password[8], char ipaddress[IPLEN]); void GetIP(char *p); void ErrMsg(char *fmt, ...); //Function Definitions END///////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// //MAIN PROGRAM BEGIN/////////////////////////////////////////////////////// main() { ac *cell, *first, *move; char more[2]; char temp[255]; char onechar[2]; char responses[2048]; onechar[0] = 'n'; onechar[1] = '\0'; ipdetect[0] = '1'; ipdetect[1] = '\0'; more[0] = 'y'; more[1] = '\0'; responses[0] = '\0'; first = NULL; cell = NULL; move = NULL; cout << "Dynu Premium Client v2.0" << endl; //Check if firewall exists. cout << "Are you behind a firewall(NAT)?(y/n) : "; cin >> onechar[0]; strcat(responses, onechar); strcat(responses, "\r\n"); if (onechar[0] == 'y' || onechar[0] == 'Y') NAT = 1; //Get IPDETECT type cout << "Please choose one of the following IP detection options:" << endl; cout << "1 - Detect IP from Dynu server side"; if (NAT) cout << "(Recommended behind NAT firewall)"; cout << endl << "2 - Detect IP on my computer" << endl; cout << "3 - I want to specify my IP address" << endl; cout << "(1-3) : "; cin >> ipdetect[0]; strcat(responses, ipdetect); strcat(responses, "\r\n"); if (ipdetect[0] == '3') { cout << "What is your IP Address? : "; cin >> ipaddress; strcat(responses, ipaddress); strcat(responses, "\r\n"); } if (ipdetect[0] == '2') { //Get the device name cout << "Please enter the device used to make external connection(The value for this can be obtained by looking at the output of the /sbin/ifconfig program while connected to the Net. e.g. eth0 or ppp0) : "; cin >> device; strcat(responses, device); strcat(responses, "\r\n"); } //Check to run once or perpetually cout << "Would you like Dynu Premium Client to keep running in the background?(y/n) : "; cin >> onechar[0]; strcat(responses, onechar); strcat(responses, "\r\n"); if (onechar[0] == 'y' || onechar[0] == 'Y') DAEMON = 1; //Get user defined poll interval cout << "How often in seconds should the client poll to check for IP Address changes : "; cin >> POLLINTERVAL; sprintf(responses, "%s%d", responses, POLLINTERVAL); strcat(responses, "\r\n"); //Load the domains and password while(more[0] == 'y' || more[0] == 'Y') { if (cell == NULL) cell = new ac; else { cell->next = new ac; cell = cell->next; } if (first == NULL) first = cell; cout << "Please type your domain(e.g. dynu, microsoft, netscape etc): "; cin >> cell->second; strcat(responses, cell->second); strcat(responses, "\r\n"); cout << "Please type your top level(e.g. com, net, co.uk etc): "; cin >> cell->first; strcat(responses, cell->first); strcat(responses, "\r\n"); cout << "Please type your password(6-8 characters): "; cin >> cell->password; strcat(responses, cell->password); strcat(responses, "\r\n"); cout << "Do you want add another domain?(y/n): "; cin >> more[0]; strcat(responses, more); strcat(responses, "\r\n"); } cout << "Would you like to save these settings so you can run Dynu Premium using the command './dynupremium < premium.cfg'?(y/n) : "; cin >> onechar[0]; strcat(responses, onechar); strcat(responses, "\r\n\0"); if (onechar[0] == 'y' || onechar[0] == 'Y') { //save the settings to premium.cfg file FILE *fildes; fildes = fopen("premium.cfg","w"); fprintf(fildes, responses); fclose(fildes); } if (DAEMON) //Run continuosly in the background { int x; x = fork(); switch (x) { case -1: //error default: //parent exit(0); case 0: //child setsid(); syslog(LOG_INFO, "Dynu Premium Client started as a background process\n"); cout << "Dynu Premium Client running...\r\n"; cell = first; while(1) { while(cell != NULL) { strcpy(lastipaddress,ipaddress); if (ipdetect[0] == '2') { GetIP(ipaddress); } fetchURL(cell->first, cell->second, cell->password, ipaddress); cell = cell->next; } sleep(POLLINTERVAL); } break; } } else //Run only once and quit { cell = first; while(cell != NULL) { strcpy(lastipaddress,ipaddress); if (ipdetect[0] == '2') { GetIP(ipaddress); } fetchURL(cell->first, cell->second, cell->password, ipaddress); cell = cell->next; } } return(0); } //MAIN PROGRAM END///////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// //Function fetchURL BEGIN////////////////////////////////////////////////// int fetchURL(char first[50], char second[70], char password[8], char ipaddress[IPLEN]) { int sock1; struct sockaddr_in server ; struct hostent *hp; const char *servername = "premiumupdate.dynu.com"; char reply[512], ch[2], url[255]; bool flag=false; bool error=false; strcpy(url, "GET http://premiumupdate.dynu.com:80/premium/update.asp?first="); strcat(url, first); strcat(url, "&second="); strcat(url, second); strcat(url, "&password="); strcat(url, password); strcat(url, "&ip_address="); strcat(url, ipaddress); strcat(url, " HTTP/1.0\n\n"); sock1 = socket(AF_INET, SOCK_STREAM,0); if ( sock1 < 0 ) { //perror("Error creating socket!\n"); return 0; } else { server.sin_family = AF_INET; hp = gethostbyname(servername); bcopy(hp->h_addr, &(server.sin_addr.s_addr), hp->h_length); server.sin_port = htons(80); if ( connect(sock1,(struct sockaddr *)&server, sizeof(server)) < 0 ) { close(sock1); //perror("Error in connecting a stream socket"); return 0; } else { if ( write(sock1, url, strlen(url)) <0) { //cout << "Error writing to server\n"; return 0; } else { if ( read(sock1, reply,512) < 0 ) { //error reading from socket return 0; } else { if (strstr(reply,"expired")!=NULL) cout << "Dynu Premium subscription for " << second << "." << first << " has expired! Please visit http://www.dynu.com to extend your subscription.\r\n"; if (strstr(reply,"nodomain")!=NULL) cout << "Domain " << second << "." << first << " does not exist! Please check the domain to make sure it is registered!\r\n"; if (strstr(reply,"wrongpassword")!=NULL) cout << "The password for domain " << second << "." << first << " is incorrect! Please start up Dynu Premium Client with the right password again!\r\n"; close(sock1); } } } } return 1; } //Function fetchURL END//////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// //Function GetIP BEGIN///////////////////////////////////////////////////// void GetIP(char *p) { int fd; int *x; struct ifreq ifr; struct in_addr z; *p = 0; // remove old address /* Create a channel to the NET kernel. */ if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { ErrMsg("Can't talk to kernel! (%d)\n", errno); return; } strcpy(ifr.ifr_name, device); if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) { ErrMsg("Can't get status for %s. (%d)\n", device, errno); close(fd); return; } if ((ifr.ifr_flags & IFF_UP) == 0) { // No longer print message when interface down (johna 6-28-00) // ErrMsg("Interface %s not active.\n", device); close(fd); return; } if (ioctl(fd, SIOCGIFADDR, &ifr) != 0) { ErrMsg("Can't get IP address for %s. (%d)\n", device, errno); close(fd); return; } close(fd); x = (int *)&ifr.ifr_addr; // seems to be off by 2 bytes z.s_addr = x[1]; strcpy(p, inet_ntoa(z)); //sprintf(suppliedIP, "&ip=%s", p); // force sending local address } //Function GetIP END/////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// //Function ErrMsg BEGIN//////////////////////////////////////////////////// void ErrMsg(char *fmt, ...) { va_list ap; char errmsg[256]; va_start(ap, fmt); vsprintf(errmsg, fmt, ap); va_end(ap); if (log2syslog) syslog(LOG_ERR, "%s\n", errmsg); else fprintf(stderr, "%s\n", errmsg); } //Function ErrMsg END////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////