TFTP server

Problem this snippet solves:

This rule implements a very basic tftp server within an iRule, calling an external class with text file converted to UTF-8 hex.

Much thanks to community members natty76 & jquinby on this effort

Code :

when RULE_INIT {
        set ::debug 1
}
when CLIENT_ACCEPTED {
binary scan [UDP::payload] xc opcode
  if { $::debug } { log local0. "Opcode is $opcode" }
switch $opcode {
1 {
    binary scan [UDP::payload] xxa* string
if { $::debug } { log local0. "String is $string" }
set file [lindex [split $string \000] 0]
set mode [lindex [split $string \000] 1]
if { $::debug} { log local0. "File is $file, Mode is $mode" }
if { ($mode == "octet" || $mode ==  "netascii") && !($file eq "") } {
switch $file {
    "test.txt" {
set flen [string length $::tftp_file_contents]
set total_blocks [expr {$flen / 1024.0}]
if { [lindex [split $total_blocks "."] 1] > 0 } { 
set total_blocks [expr [lindex [split $total_blocks "."] 0] + 1 ]
if { $::debug } { log local0. "block isn't integer, incrementing for final block" }
} else {
set total_blocks [lindex [split $total_blocks "."] 0]
if { $::debug } { log local0. "Block is integer, no increment necessary" }
}
set str_index 0
for { set x 1 } { $x <= $total_blocks } { incr x } {
set data [binary format SSH* 3 $x [string range $::tftp_file_contents $str_index [expr {$str_index + 1023}] ] ]
if { $::debug } { log local0. "data = $data, size = [string length $data]" }
UDP::respond $data
incr str_index 1024
}
}
default {
if { $::debug } { log local0. "File not found: $file" }
}
}
} else {
if { $::debug } { log local0. "Mode is incorrect: $mode, or file is not specified: $file" }
reject 
}
} 
2 {
if { $::debug } { log local0. "Write request not supported here" }
}
3 {
if { $::debug } { log local0. "Data receipt not supported here" }
}
4 {
if { $::debug } { log local0. "Ack from client received" }
}
5 {
if { $::debug } { log local0. "Error: $string" }
}
default {
if { $::debug } { log local0. "Opcode $opcode is invalid" }
reject
}
}
}
Published Mar 18, 2015
Version 1.0

Was this article helpful?

No CommentsBe the first to comment