Lets Start A New Standard Service!
Okeydokey, Lots of people have problems translating IPs since NAT came into existance. Internal network IPs, External Network IPs, IPs used over some WAN interface. Its just a pain in the ass. There have been ALOT of questions between several threads here and threads on other forums for even other languages looking for a simple way to obtain your EXTERNAL IP address. (The One That The Internet Sees!)
What I Propose: We should enact a new standard service that runs on an arbitrarily assigned unused port, (Im thinking port 412 just for $$$$s and giggles.) That accepts a connection from a host, simply prints the IP of the connecting host, and closes the connection. Boom. Simple, fast, effective. Then it will be a simple matter to run on multiple network servers, and possibly a few large central static points on the internet, such as a root nameserver, or one of the official NTP servers to determine how a given remote host will view your connection. This shouldnt take alot of work, involves no obvious security flaws, eats few if any system resources and bandwidth, and serves as an important network status and troubleshooting tool! Anybody interested in helping? Im thinking a simple "EchoIPd" IP Daemon writen in C (30 lines of code) and possibly a nice message to a few internet standards orginizations and we could have our own little chunk of immortality! What do you guys think?
Submitted For Your Approval
Submitted for your approval, Code for the EchoIPDaemon:
Code:
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <signal.h>
#include <errno.h>
#include <stdio.h>
int terminate=0;
void signalhd(int senal){
if (senal==SIGINT){
printf("...Interrupt...\n");
terminate=1;
}
}
void sigchld_handler(int s)
{
while(wait(NULL) > 0);
}
int main()
{
struct sigaction sa;
struct sockaddr_in sin, fsin;
int s, ssock, alen;
char *ipaddress;
sa.sa_handler = sigchld_handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART;
if (sigaction(SIGCHLD, &sa, NULL) == -1) {
perror("sigaction");
exit(1);
}
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = htonl(INADDR_ANY);
sin.sin_port = htons(6666);
if ((s = socket(PF_INET, SOCK_STREAM, 0)) < 0)
{
perror("Cant create socket");
exit(1);
}
if (bind(s, (struct sockaddr *)&sin, sizeof sin) < 0)
{
perror("Cant assign addres");
exit(2);
}
if (listen(s, 5) < 0)
{
perror("Cant turn to listening mode");
exit(3);
}
signal (SIGINT,signalhd);
while (1)
{
if (terminate==1)
{
close(s);
exit(0);
}
alen = sizeof(fsin);
if ((ssock=accept(s, (struct sockaddr *)&fsin, &alen)) < 0)
{
if (errno == EINTR) continue;
perror("Accept failed");
exit(4);
}
switch (fork()) {
case -1:{
perror ("Forking error");
exit (5);
}
case 0: {
close(s);
exit(0);
}
default: {
ipaddress=(char *)inet_ntoa(fsin.sin_addr);
write(ssock, ipaddress, strlen(ipaddress));
close(ssock);
break;
}
}
}
return 0;
}
Its short, sweet, and to the point. I ran it and stress tested it on an extremely low end box and it can do about 70 per second. Im looking for suggestions on how to speed it up or improve it. Im thinking about implimenting it on a university server with a static IP and trying to get somebody with power to recognise it. Using it would be a simple matter of telling your program to connect and take all recieved information and just convert it to an ip address or display it as a string or whatever.