Net::TFTPd(3pm)

๐Ÿ“ฆ
version 0.10 ยท 3 versions
, in ubuntu noble, ubuntu resolute, ubuntu stonking

๐Ÿ’– Net::TFTPd โ€” the manual, but make it cute ๐Ÿ’–

okay bestie, so this is a page from the User Contributed Perl Documentation, and it's all about Net::TFTPd, a Perl extension that gives you a whole Trivial File Transfer Protocol server. yes really. a whole server. in Perl. she's serving (literally) โœจ


๐ŸŒธ NAME ๐ŸŒธ

Net::TFTPd โ€” Perl extension for Trivial File Transfer Protocol Server ๐ŸŽ€


๐Ÿฆ‹ SYNOPSIS ๐Ÿฆ‹

the vibe is: you make a listener, you wait for a request, you process that request, you brag about the bytes. periodt.

use strict;
use Net::TFTPd;

my $tftpdOBJ = Net::TFTPd->new('RootDir' => 'path/to/files')
  or die "Error creating TFTPd listener: %s", Net::TFTPd->error;

my $tftpRQ = $tftpdOBJ->waitRQ(10)
  or die "Error waiting for TFTP request: %s", Net::TFTPd->error;

$tftpRQ->processRQ()
  or die "Error processing TFTP request: %s", Net::TFTPd->error;

printf "%u bytes has been transferred", $tftpRQ->getTotalBytes() || 0;

no cap, that's the whole lifecycle right there ๐Ÿซถ


๐Ÿ’œ DESCRIPTION ๐Ÿ’œ

Net::TFTPd is a class that implements a simple Trivial File Transfer Protocol server in Perl, exactly as described in RFC1350. she's a whole class. she does the thing.

and not only that โ€” Net::TFTPd also supports the TFTP Option Extension (as described in RFC2347), with these options:

  • RFC2348 TFTP Blocksize Option
  • RFC2349 TFTP Timeout Interval and Transfer Size Options

like?? she read the RFCs so you don't have to. iconic behavior ๐Ÿ‘‘


โœจ EXPORT โœจ

None by default. nope, not a single thing. you gotta ask. consent is key ๐Ÿ’…

๐ŸŽ€ %OPCODES ๐ŸŽ€

the %OPCODES tag exports the %OPCODES hash:

%OPCODES = (
  1       => 'RRQ',
  2       => 'WRQ',
  3       => 'DATA',
  4       => 'ACK',
  5       => 'ERROR',
  6       => 'OACK',
  'RRQ'   => 1,
  'WRQ'   => 2,
  'DATA'  => 3,
  'ACK'   => 4,
  'ERROR' => 5,
  'OACK'  => 6
);

it goes both ways. number โ†’ name, name โ†’ number. bilingual queen ๐Ÿงš


๐ŸŒˆ Listener constructor ๐ŸŒˆ

new() ๐ŸŒŸ

$listener = new Net::TFTPd( ['RootDir' => 'path/to/files' | 'FileName' => 'path/to/file'] [, OPTIONS ] );

or, if you prefer the arrow-y way:

$listener = Net::TFTPd->new( ['RootDir' => 'path/to/files' | 'FileName' => 'path/to/file'] [, OPTIONS ] );

so what's happening: you create a new Net::TFTPd object. 'path/to/files' is the default path to the file repository, OR 'path/to/file' is the single file that's allowed for download (pick one, bestie), and OPTIONS are the default server options. โœจ

valid options are:

  • LocalAddr โ€” Interface to bind to (for multi-homed server) โ€” default: any
  • LocalPort โ€” Port to bind server to โ€” default: 69
  • Timeout โ€” Timeout in seconds to wait for a request โ€” default: 10
  • ACKtimeout โ€” Timeout in seconds to wait for an ACK packet โ€” default: 4
  • ACKretries โ€” Maximum number of retries waiting for ACK โ€” default: 4
  • Readable โ€” Clients are allowed to read files โ€” default: 1
  • Writable โ€” Clients are allowed to write files โ€” default: 0
  • BlkSize โ€” Minimum blocksize to negotiate for transfers โ€” default: 512
  • CallBack โ€” Reference to code executed for each transferred block โ€” default: -
  • Debug โ€” Activates debug mode (verbose) โ€” default: 0
  • Family โ€” Address family IPv4/IPv6 โ€” default: IPv4
    • Valid values for IPv4: 4, v4, ip4, ipv4, AF_INET (constant)
    • Valid values for IPv6: 6, v6, ip6, ipv6, AF_INET6 (constant)
  • V6Only โ€” Enable / disable v6only (see IO::Socket::IP) โ€” default: 1
NOTE: IPv6 requires IO::Socket::IP. Failback is IO::Socket::INET and only IPv4 support. so if you're trying to be all v6 and fancy without IO::Socket::IP, she will simply not. ๐Ÿ˜ญ

๐Ÿ“ CallBack ๐Ÿ“

the CallBack code gets called by the processRQ method for each transferred block. every. single. one. she's keeping you posted fr fr.

the code receives (into the @_ array) a reference to the internal $request object.

example:

sub callback
{
  my $req = shift;
  printf "block: %u\/%u\n", $req->{'_REQUEST_'}{'LASTACK'}, $req->{'_REQUEST_'}{'LASTBLK'};
}

my $tftpdOBJ = Net::TFTPd->new('RootDir' => 'c:/temp', 'Timeout' => 60, 'CallBack' => \&callback) or die Net::TFTPd->error;

look at her, peeking at '_REQUEST_' internals like it's nothing. nosy in the best way ๐Ÿ™ˆ


๐Ÿ’ซ Listener methods ๐Ÿ’ซ

waitRQ() โณ

$request = $listener->waitRQ([Timeout]);

waits for a client request (RRQ or WRQ) and returns a $request object, or undef if it timed out. she's just sitting there, patiently, like a bestie waiting for you to text back.

if Timeout is missing, the timeout defined for the $listener object is used instead. respect the defaults. ๐Ÿ’…

when the method returns, the program should fork() and process the request by invoking processRQ(), while the parent process should re-start waiting for another request. yes, that's the whole pattern โ€” parent keeps listening, child does the work. main character energy for the parent, side quest for the child ๐Ÿ‘‘


๐ŸŒŸ Request methods ๐ŸŒŸ

processRQ() ๐Ÿ”ฅ

$ret = $request->processRQ();

processes a request and returns 1 if success, undef if error. that's it, that's the method.

getFileName() ๐Ÿ“„

$ret = $request->getFileName();

returns the requested file name.

getMode() ๐ŸŽ›๏ธ

$ret = $request->getMode();

returns the transfer mode for the request.

getBlkSize() ๐Ÿ“ฆ

$ret = $request->getBlkSize();

returns the block size used for the transfer.

server() ๐ŸŒ

$ret = $request->server();

return the IO::Socket::* object for the created server. all IO::Socket::* accessors can then be called. go wild, she's giving you the whole socket ๐Ÿ’–

getPeerAddr() ๐Ÿ“

$ret = $request->getPeerAddr();

returns the address of the requesting client.

getPeerPort() ๐Ÿ”Œ

$ret = $request->getPeerMode();

returns the port of the requesting client.

(ngl that's exactly what the page says โ€” the method is getPeerPort() and the call inside is $request->getPeerMode(). i'm not touching it. i report, you decide ๐Ÿ™ˆ)

getTotalBytes() ๐Ÿงฎ

$ret = $request->getTotalBytes();

returns the number of bytes transferred for the request. the receipts!! ๐Ÿ’…


๐Ÿ’ CREDITS ๐Ÿ’

thanks to Michael Vincent (<<VINSWORLD>>) for the NETASCII support, transferred bytes and IPv6 patches. king behavior, we love to see it ๐Ÿซถโœจ


๐Ÿ‘‘ AUTHOR ๐Ÿ‘‘

Luigino Masarati, <lmasarati@hotmail.com> ๐Ÿ’–


๐ŸŒˆ SEE ALSO ๐ŸŒˆ

Net::TFTP.


and that's the whole page bestie!! this one goes out as perl v5.36.0, dated 2022-10-13, from the lovely folks in the User Contributed Perl Documentation corner of the world ๐ŸŽ€ go transfer some files, you got this ๐Ÿ’œ๐Ÿฆ‹

๐Ÿ“ฆ where this page comes from