#!/usr/bin/perl # radwho.cgi a quick hack to show the users on-line # Version: @(#)radwho.cgi 0.01 04-Jul-1998 bruno@openline.com.br # # Copyright (c) 1998 Bruno Lopes F. Cabral, Openline ISP # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. use POSIX; use Socket; use CGI qw/:standard/; sub who { my($utmpsize, $utmpfile, %proto, $i); my($login, $nas_port, $session_id, $nas_address, $framed_address); my($protocol, $time, $delay, $type, @info, $j, $name, $from); my($location, $host, $tm); # Size of radutmp structure $utmpsize = 100; # Location of utmp file. $utmpfile = '/var/log/utmp'; %proto = ( 'L' => 'LOCAL', 'R' => 'RLOGI', 'S' => 'SLIP', 'C' => 'CSLIP', 'P' => 'PPP', 'E' => 'TELNE', 'T' => 'TCPCL', 'U' => 'TCPLO', '!' => 'CONSO', 'X' => 'SHELL', '' => 'UNKNO', ); open(FD, "<$utmpfile"); $i=1; while (read(FD, $ut, $utmpsize)) { ($login, $nas_port, $session_id, $nas_address, $framed_address, $protocol, $time, $delay, $type) = &unpackradutmp($ut); next if ! $type; @info = getpwnam($login); $j = index($info[6],','); $name = ($j < 0 ) ? $info[6] : substr($info[6],0,$j); $name = $login if ! $name; # FIXME: cache the NASLIST instead of printing NAS IP # remember that doing a DNS lookup took a lot of time! $from = join('.',unpack("CCCC",$nas_address)); $location = join('.',unpack("CCCC",$framed_address)); $host = gethostbyip($location); $tm = strftime( "%a %H:%M", localtime($time)); print < Ord Name LoginTime RAS Host
EOM printf "%3d %-20.20s %-9.9s %-15.15s %-25.25s%s\n", $i++, $name, $tm, $from, $host; } close FD; print < EOM } # Unpack RADUTMP file, and return an array consisting of: # # 0. char login[32] Loginname # 1. int nas_port Port on the terminal server (32 bits) # 2. char session_id[8] Radius session ID (8 first char) # 3. UINT4 nas_address IP of portmaster # 4. UINT4 framed_address SLIP/PPP address or login-host # 5. int proto Protocol # 6. time_t time Time entry was last updated # 7. time_t delay Delay time of request # 8. int type Type of entry (login/logout) # 9. char reserved[32] 8 ints reserved # sub unpackradutmp { my @tmp; my ($la); @tmp = unpack("A32 i A8 a4 a4 a4 I I i A32", $_[0]); $tmp[5] =~ s/\0+$//g; return @tmp; } sub gethostbyip { my( $ip ) = @_; my( $ipadd, $remotehost ); $ipadd = gethostbyname( $ip ); ($remotehost) = gethostbyaddr( $ipadd, AF_INET ); return ($ip, $remotehost); } print header(-expires=>'+300s'), start_html(-title=>'Users on-line', -author=>'bruno@openline.com.br', -base=>'true', -target=>'_top', -BGCOLOR=>'#ffffff'),"\n"; &who; print end_html;