Jump to content

TFTP Client & Server


Recommended Posts

Hello all,
 
I'm trying to write a TFTP Client and a TFTP Server in autoIT..., so far I'm only at the client... I would greatly appreciate the input of some RFC gurus.
This is the code that I have:

#include <String.au3>

UDPStartup()
$socket = UDPOpen("192.168.1.84", 69)
$rrq="0x"&"0001676574006f6374657400"
$status = UDPSend($socket, $rrq)
If $status = 0 then
    MsgBox(0, "ERROR", "Error while sending UDP message: " & @error)
    Exit
EndIf
$srcv = UDPRecv($socket, 516)
ConsoleWrite("Received Response: "&_HexToString(Stringmid($srcv,9)))
ConsoleWrite(@CR)
ConsoleWrite("Received Response: "&$srcv)
ConsoleWrite(@CR)
$rrq2="0x"&"0004001"
$status2 = UDPSend($socket, $rrq2)
$srcv2 = UDPRecv($socket, 516)
ConsoleWrite("Received Response: "&_HexToString(Stringmid($srcv2,9)))
ConsoleWrite(@CR)
ConsoleWrite("Received Response: "&$srcv2)
ConsoleWrite(@CR)
UDPCloseSocket($socket)
UDPShutdown()

the first packet that I send is in the $rrq (READ REQUEST) variable: |2 byte op code "00:01" for RRQ|file name "67:65:74", meaning "get"|1 byte delimiter 0 "00"|mode "6f:63:74:65:74" meaning "octet"|1 byte ending 0 "00"

I actually get back the file from the server, its a text file named get, containing the string "TRANSFER TEST FILE"

I get the response:

 

Received Response: <SOH>TRANSFER TEST FILE

Received Response: 0x000300015452414E5346455220544553542046494C45

 

meaning: 2 byte opcode "00:03" which is DATA|2 byte block ID for block #1 "00:01" (also in this case this 4 bytes are SOH = start of header)|18 bytes as the content of the file....

and this is the part where Im stuck since after I receive this I send an ACK "00:04" <- ACK opcode|"00:01" <- block ID but the TFTP server respondes with a EBADOP "Illegal TFP operation" adding an EOT (end of transmission) header:

 

Received Response: <EOT>Illegal TFTP operation

Received Response: 0x00050004496C6C6567616C2054465450206F7065726174696F6E00

 

the "00:05" is opcode for error, and "00:04" is illegal TFTP operation, "00" is closing byte for the opcode...

I'm using Tftpd32 4.0.0.0 as a server, I'm getting this error from it:

 

Connection received from 192.168.1.84 on port 65047 [29/06 01:29:49.019]

Read request for file <get>. Mode octet [29/06 01:29:49.023]
Using local port 65048 [29/06 01:29:49.024]
Connection received from 192.168.1.84 on port 65047 [29/06 01:29:49.030]
Unexpected request 4 from peer [29/06 01:29:49.036]
Returning EBADOP to Peer [29/06 01:29:49.036]
File <get> : error 10054 in system call recv An existing connection was forcibly closed by the remote host. [29/06 01:29:50.028]

 

I really don't know what to try... I'm guessing that I'm miss interpreting something from the RFC http://www.networksorcery.com/enp/rfc/rfc1350.txt

Link to comment
Share on other sites

OK... I have isolated my problem, it appears that the scenario is the following:

Using AutoIT, through UDP I connect to port 69 of the server and send him the RRQ package <-- this step is SUCCESSFUL

The server in reply sends a DATA package with ID #0, as a confirmation (also its the first packet of the requested file) HOWEVER this packet is already sent on an ephemeral port, which AutoIT appears to follow since I get the reply package (in the example that I posted this port seems to be 65048, which is the original ephemeral port for my connection+1), however when I do my next UDPSend with the ACK packet for DATA packet #0 (I know in the example I sent a wrong reply packet with #1 it should be #0 I corrected that since) AutoIT seems to forget that the ephemeral since the original UDPOpen was changed and connects back to the original port (in the example 65047) which the server considers a new connection...

Did anyone had the same problem with UDP connections or am I doing something wrong? is this a bug in AutoIT? 

Link to comment
Share on other sites

OK :) I know I didn't got any replies... still in the hope that someone find this interesting, I managed to make it work (the client part), here is how:

Setup: Tftpd32 as server: http://tftpd32.jounin.net/tftpd32_download.html

in the example I used a file named: get001 which is actually the tftpd32.ini just copy/renamed

the solution it self to handle the ephemeral port problem:

UDPOpen() returns an array:

$array[1] = real socket

$array[2] = connected IP

$array[3] = connected port

the UDPRecv() if called with flag 2 (or 3) also return an array:

$array[0] = data received

$array[1] = received from IP

$array[2] = received from port

AND VOILA the ephemeral port is in the UDPRecv()'s value, array item 2, so I declared a new variable $socket2, made it equal with $socket (original UDPOpen()) and changed $socket2[3] to UDPRecv() array item [2], this way it works :D

now that I had this worked out I gonna go ahead to make the TFTP server & client, once I'm done with it I will post it here, I think its gonna be a good example of a server/client implementation of an actual RFC described protocol:

Im planning to implement all opcodes (1 = RRQ, 2 = WRQ, 3 = DATA, 4 = ACK, 5 = ERROR, 6 = OACK) including opcode 6 OACK...

here is the working example of my first post (remember a copy of tftp32.ini needs to exist in the tftp32.exe directory named get001 in order for this to work)

#include <String.au3>

UDPStartup()
$socket = UDPOpen(@IPAddress1, 69)
$File = "get001"
$FileHex = _StringToHex($File)
$RRQ = "0x0001" & $FileHex & "00" & "6F63746574" & "00" & "626C6B73697A65" & "00" & "353132" & "00" & "7473697A65" & "00" & "353330" & "00"
$status = UDPSend($socket, $rrq)
$srcv = UDPRecv($socket, 516, 2)
ConsoleWrite("Received Response: "&_HexToString(Stringmid($srcv[0],9)))
ConsoleWrite(@CR)
ConsoleWrite("Received Response: "&$srcv[0])
ConsoleWrite(@CR)

$socket2 = $socket
$socket2[3] = $srcv[2]

$rrq2 = "0x00040000"
$status2 = UDPSend($socket2, $rrq2)
$srcv2 = UDPRecv($socket2, 516)
ConsoleWrite("Received Response: "&_HexToString(Stringmid($srcv2,9)))
ConsoleWrite(@CR)
ConsoleWrite("Received Response: "&$srcv2)
ConsoleWrite(@CR)

$rrq3 = "0x00040001"
$status3 = UDPSend($socket2, $rrq3)
$srcv3 = UDPRecv($socket2, 516)
ConsoleWrite("Received Response: "&_HexToString(Stringmid($srcv3,9)))
ConsoleWrite(@CR)
ConsoleWrite("Received Response: "&$srcv3)
ConsoleWrite(@CR)

$rrq4 = "0x00040002"
$status3 = UDPSend($socket2, $rrq4)
$srcv4 = UDPRecv($socket2, 516)
ConsoleWrite("Received Response: "&_HexToString(Stringmid($srcv4,9)))
ConsoleWrite(@CR)
ConsoleWrite("Received Response: "&$srcv4)
ConsoleWrite(@CR)

UDPCloseSocket($socket)
UDPShutdown()
Link to comment
Share on other sites

I'm sure you will get replies on this subject, it is an interesting one, but there are two things to consider.

First, it's a very niche subject, and second, there are very fewer people visit the forums over the weekend.

Hang in there.

AutoIt Absolute Beginners    Require a serial    Pause Script    Video Tutorials by Morthawt   ipify 

Monkey's are, like, natures humans.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...