Packet tracing web interface

Brian Candler B.Candler at pobox.com
Mon Mar 14 14:37:42 CET 2011


On Mon, Mar 14, 2011 at 12:47:36PM +0000, Phil Mayers wrote:
> Ok, correct usage is:
> 
> radmin
> > inject to (auth|acct) dstip dstport

Aha. The 'help' message is decidedly unhelpful there (so is the error
"Unknown socket type").  It works when I add 'auth', thank you.

> > inject from srcip
> > inject file input output

And it turns out radiusd forces a prepend onto the output path, but not the
input path:

++[exec] returns noop
Failed to send injected file to /v/build/fr/var/log/radius//home/brian/test.out: No such file or directory

It would be nice to allow '-' for input and output, so you didn't have to
mess with temporary files, but that would involve sending the request and
response across the socket.

I'll probably stick to radclient + loopbacks for now, although the ability
to set an arbitrary source IP using radmin inject is nice.

Simple GUI app attached. It's quite neat what you can do in 70 lines of ruby
:-)

Regards,

Brian.

---------------------------------------------------------------------------
require 'rubygems'
require 'sinatra'
require 'haml'

RADCLIENT = "/usr/bin/radclient"
RADIUSD = "/usr/sbin/freeradius"

# List available loopback interfaces [Label, IP address, secret]
SOURCES = [
  ['Default', '127.0.0.1', 'testing123'],
  ['Test LAC', '192.0.2.1', 'anothersecret'],
]

$radiusd = IO.popen("#{RADIUSD} -X -i 127.0.0.1 -p 18123","w+")
begin
  exit unless (line = $radiusd.gets)
  print line
end until line =~ /Ready to process requests/

set :lock, true   # prevent concurrent requests

get '/' do
  haml :root
end

post '/' do
  # Flush any remaining debug info
  $radiusd.gets while select([$radiusd], nil, nil, 0)
  @radclient = ""
  @radiusd = ""
  source = SOURCES.find { |src| src[1] == params[:source] } || SOURCES.first
  IO.popen("#{RADCLIENT} -x 127.0.0.1:18123 auth '#{source[2]}' 2>&1","w+") do |io|
    io.puts "Packet-Src-IP-Address = #{source[1]}"
    io.puts params[:avp]
    io.close_write
    loop do
      ready, _ = select([io, $radiusd], nil, nil, 10)
      unless ready
        @radiusd << "** TIMEOUT **"
        break
      end
      if ready.include?(io)
        break unless (line = io.gets)
        @radclient << line
      end
      if ready.include?($radiusd)
        exit unless (line = $radiusd.gets)
        @radiusd << line
      end
    end
  end
  haml :root
end

__END__

@@ root
%html
  %head
    %title radtest GUI
  %body
    %form{:action=>'/',:method=>'post'}
      %ul
        - SOURCES.each do |label, ip, secret|
          %li
            %input{:type=>'radio',:name=>'source',:value=>ip,:checked=>params[:source]==ip}&= label
      %textarea{:name=>'avp',:rows=>12, :cols=>60}&= params[:avp]
      %input{:type=>'submit'}
    - if @radclient
      %h1 radclient response
      %pre&= @radclient
    - if @radiusd
      %h1 radiusd debug output
      %pre&= @radiusd



More information about the Freeradius-Users mailing list