#!/bin/perl -w use strict; use IO::Socket; use File::Basename; use Getopt::Std qw(getopts); my $PHRODO_PORT = 8009; my $MAXLEN= 1024; my $CONNECT_TIMEOUT = 10; my $phonebook="phonebook"; my $phonebook_new="phonebook_new"; my $log="log"; my $date; my $date2; # usage stuff use vars ( q!$opt_d!, # debug mode ); my $prog = basename $0; my $usage = "Usage: $prog [-d]\n"; getopts('d') or die $usage; my $debug = $opt_d; warn "Debug logging enabled\n" if $debug; # server stuff my $server; $server = IO::Socket::INET->new( LocalPort => $PHRODO_PORT, Proto => 'tcp', Type => SOCK_STREAM, Listen => SOMAXCONN, Reuse => 1, ); unless( $server ) { die "socket could not be created: $@\n"; } while (my $client = $server->accept()){ $client->autoflush(1); $client->peeraddr(); open (PHONEBOOK, "<$phonebook") or die "can't open $phonebook: $!"; open (LOG, ">>$log") or die "can't open $log: $!"; # Get hostname by name or by IP Address (whatever you prefer) # my $hostname = gethostbyaddr( $client->peeraddr(), AF_INET ) ; my $hostname = inet_ntoa($client->peeraddr()); $date=localtime; print LOG "$date - Got connection from $hostname\n"; # Get the message from the client my $newmsg; $client->recv($newmsg, $MAXLEN); $date=localtime; print LOG "$date - Recieved message from $hostname\n" if $debug; # If the message is a registration if ($newmsg =~ /register/) { # Open phonebook_new filehandler open (PHONEBOOK_NEW, ">>$phonebook_new") or die "can't open $phonebook_new: $!"; # Substitute the blank ip with the client address $newmsg =~ s/ip=0.0.0.0/ip=$hostname/g; $newmsg =~ s/\0//; # Store the register and host info as primary key in $unique_info (my $unique_info, my $other_info) = split /\|p/, $newmsg; (my $box_info, my $host_info) = split /\|/, $unique_info; # Parse the phonebook. If the unique info is there, client # already has entry. Check to see if the host has changed. # If it has changed, modify the entry for that box. # If the box is not found, add an entry to the phonebook. my $found=0; while(){ my $line = $_; if ( $line =~ /^$box_info/ ){ $found=1; # Update the registration time $date2=time(); $line =~ s/rtime=\d.*\d\|udp_ip/rtime=$date2|udp_ip/; # Replace corresponding hostname with new one, if different if ($line !~ /ip=$hostname/ ){ # existing entry for box_id has diff hostname $line =~ s/ip=\w.*\w\|p/ip=$hostname|p/; $line =~ s/udp_ip=\w.*\w\|u/udp_ip=$hostname|u/; $date=localtime; print LOG "$date - Changed entry in phonebook for $box_info on $hostname\n" if $debug; } } print PHONEBOOK_NEW $line; } if (not $found) { print PHONEBOOK_NEW "$newmsg\n"; $date=localtime; print LOG "$date - Added $box_info to phonebook at $hostname\n" if $debug; } close (PHONEBOOK) or die "can't close $phonebook: $!"; close (PHONEBOOK_NEW) or die "can't close $phonebook_new: $!"; # Rename the phonebook with the modified entry rename($phonebook, "phonebook.orig") or system("rename", $phonebook, "phonebook.orig") or die "can't rename $phonebook to $phonebook.orig: $!"; rename($phonebook_new, $phonebook) or system("rename", $phonebook_new, $phonebook) or die "can't rename $phonebook_new to $phonebook: $!"; # Assign response variable to send to client. Must append # null character. my $msg = "rtimer=600\0"; $client->send($msg); $date=localtime; print LOG "$date - Sent message $msg to $hostname\n" if $debug; } # If the message is a query if ($newmsg =~ /query/){ # Grab the box ID that the client is looking up (my $query, my $lookup) = split /\|/, $newmsg; (my $fieldlabel, my $box_id) = split /=/, $lookup; # Remove the null character $box_id =~ s/\0//; $date=localtime; print LOG "$date - $query looking for $box_id on $hostname\n" if $debug; # Parse phonebook. If the queried box ID is found, format a response. my $sendmsg = 0; while(){ my $line = $_; if ( $line =~ /^register=$box_id\|ip/ ){ $line =~ s/register=/serial=/g; $line =~ s/flags=[0-9]*\|/flags=1\|/g; $line =~ s/\|rtime/\|ctime=995591865\|utime=1016013554\|rtime/g; $sendmsg = "$line\0"; $date=localtime; print LOG "$date - Query found $box_id in phonebook\n" if $debug; } } if ($sendmsg){ # Send back response to client. $client->send($sendmsg); } else { # Send back unknown response to client my $unknown = "UNKNOWN\0"; $client->send($unknown); $date=localtime; print LOG "$date - Query did not find $box_id in phonebook\n"; } close (PHONEBOOK) or die "can't close $phonebook: $!"; } $client->close(); undef $client; close (LOG) or die "can't close $log: $!"; } $server->close;