/* Prototype uptime daemon for uptime.eggheads.org/uptime.energymech.net * (c) 2001 MadCamel and proton - Public Domain * * This just recieves the packets and prints them. The system in use today * pokes the values into a mySQL table. */ #include #include #include #include #include #include #include #include #include #include #include #include #define PERR(x) { perror(x); exit(1); } #define LPORT 9969 char filterchars[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; char executable[40]; int sock; typedef struct upPack { int regnr; int pid; int type; ulong cookie; ulong uptime; ulong ontime; ulong now; ulong sysup; char string[1]; } upPack; int bindsock (int port) { struct sockaddr_in sai; int s; if ((s = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) PERR ("Socket"); sai.sin_family = AF_INET; sai.sin_port = htons (port); sai.sin_addr.s_addr = INADDR_ANY; if (bind (s, (struct sockaddr *) &sai, sizeof (sai)) < 0) PERR ("Bind"); return s; } void handle_segv (const int sig) { close (sock); execl (executable, executable, NULL); _exit (0); } #define PACKSIZE 512 int main (int argc, char **argv) { struct sockaddr_in sai; struct upPack *up; char packet[PACKSIZE]; char *pt; int sz,res; strcpy(executable,*argv); signal(SIGSEGV,handle_segv); up = (struct upPack *)packet; sock = bindsock(LPORT); loopit: sz = sizeof(sai); res = recvfrom(sock,&packet,PACKSIZE-1,0,(struct sockaddr *)&sai,&sz); /* * Why +5 ? * * Minimum nick length 1 * Space 1 * Minimum hostname 1 (`x' is a legal hostname) * Space 1 * Minimal version string 1 (they may hack versions all they want) * \0 1 * upPack.string[1] -1 (+1 is added extra by sizeof(upPack)) * --------------------------- * Total +5 */ if (res < (sizeof(upPack)+5)) goto loopit; /* * res can not be bigger than res - 1 == 511 == end of buffer * This already IS a \0 unless the client has been hacked */ packet[res] = 0; printf("%s ",inet_ntoa(sai.sin_addr)); printf("%i ",ntohs(sai.sin_port)); printf("%i ",up->regnr); printf("%i ",up->pid); printf("%i ",up->type); printf("%lu ",up->cookie); printf("%lu ",up->uptime); printf("%lu ",up->ontime); printf("%lu ",up->now); printf("%lu ",up->sysup); /* * evil char filter, drop anything that looks ugly */ for(pt=up->string;*pt;pt++) { if (filterchars[(unsigned char)*pt] == 0) goto loopit; } printf("%s\n",up->string); goto loopit; }