/* Udns 1.0 - Jean-Marc Zucconi * This file is in the public domain */ /* usage: Udns -h hostname -p password IP_Address * example: Udns -h mydomain.com -p f90284f 194.11.98.45 * if you want to update your IP address whenever the PPP session restarts, * simply add this line in your /etc/ppp/ppp.linkup file: * * default: * !bg /usr/local/bin/Udns -h -p MYADDR * */ #include #include #include #include #include #include #include #include #define HOST "www.dtdns.net" #define PORT 80 #define TIMEOUT 300 /* seconds */ char buffer[8192]; int http_open (char *, int), httpget (char *, int, char *); void parse (int); int debug = 0; void usage () { extern char *__progname; fprintf (stderr, "usage: %s -h hostname -p password IP_Address\n", __progname); exit (1); } main (int argc, char **argv) { int c, len; char *password = 0, *name = 0, *ip = 0; char *command; while ((c = getopt (argc, argv, "dh:p:")) != -1) { switch (c) { case 'd': debug = 1; break; case 'p': password = strdup (optarg); break; case 'h': name = strdup (optarg); break; default: usage (); } } if (!argv[optind] || argv[optind+1] || !password || !name) usage (); ip = strdup (argv[optind]); len = 0; for (c = 1; c <= optind; c++) { /* hide command line */ int l = strlen (argv[c]); len += l; memset (argv[c], ' ', l); } command = (char *) malloc (len + 1000); sprintf (command, "GET /autodns.cfm?id=%s&pw=%s&ip=%s&client=Udns" " HTTP/1.1\n" "Host: %s\n" "User-Agent: Udns\n" "\n", name, password, ip, HOST); len = httpget (HOST, PORT, command); /* reply looks like * HTTP/1.1 200 OK\r\n * Server: Microsoft-IIS/5.0\r\n * Date: Fri, 27 Oct 2000 15:59:19 GMT\r\n * Connection: close\r\n * Content-type: text/html\n * Page-Completion-Status: Normal\n * Page-Completion-Status: Normal\n * \n * The hostname you supplied is not valid. */ parse (len); exit (0); } void parse (int len) { char *p; buffer[len] = 0; if (debug) printf ("read %d bytes from server: <%s>\n", len, buffer); p = strstr (buffer, "\n\n"); if (!p) /* OK */ return; p += 2; printf ("%s\n", p); if (strstr (p, "Host already points to this IP")) return; /* OK too */ exit (1); } int httpget (char *host, int port, char *str) { char *cp; struct timeval tv; time_t tout; fd_set fdset; int i, s; s = http_open (host, port); if (debug) printf ("sending command: <%s>\n", str); i = strlen (str); if (i != write (s, str, i)) err (1, "could not send GET command to %s.", host); FD_ZERO (&fdset); FD_SET (s, &fdset); tout = TIMEOUT; tv.tv_sec = tout; tv.tv_usec = 0; i = select (s+1, &fdset, 0, 0, &tv); switch (i) { case 0: errx (1, "timeout"); case 1: i = read (s, buffer, sizeof (buffer)); return i; default: err (1, "communication error with %s.", host); } } int http_open (char *host, int port) { unsigned long a; struct sockaddr_in sin, sin2; struct hostent *h; int s; if (debug) printf ("establishing conection with %s, port %d\n", host, port); a = inet_addr (host); if (a != INADDR_NONE) { sin.sin_family = AF_INET; sin.sin_addr.s_addr = a; } else { h = gethostbyname (host); if (!h) err (1, "could not lookup host %s.", host); sin.sin_family = h->h_addrtype; bcopy (h->h_addr, (char *) &sin.sin_addr, h->h_length); } sin.sin_port = htons (port); if ((s = socket (sin.sin_family, SOCK_STREAM, 0)) < 0) err (1, "socket"); bzero ((char *)&sin2, sizeof (sin2)); sin2.sin_family = AF_INET; sin2.sin_port = 0; sin2.sin_addr.s_addr = htonl (INADDR_ANY); if (bind (s, (struct sockaddr *) &sin2, sizeof (sin2))) err (1, "could not bind to socket."); if (connect (s, (struct sockaddr *) &sin, sizeof(sin)) < 0) err (1, "connection failed."); return s; }