KEFE Posted June 28, 2013 Posted June 28, 2013 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
KEFE Posted June 30, 2013 Author Posted June 30, 2013 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?
KEFE Posted June 30, 2013 Author Posted June 30, 2013 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 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) expandcollapse popup#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()
JohnOne Posted June 30, 2013 Posted June 30, 2013 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.
LarryDalooza Posted July 1, 2013 Posted July 1, 2013 I only use TFTP as a PXE boot server. I am interested as an observer of your work. You may want to begin a thread in the 'Examples' forum. Lar AutoIt has helped make me wealthy
KEFE Posted July 7, 2013 Author Posted July 7, 2013 OK... I will no longer post updates here LarryDalooza is right, the Examples forum better fits this thread The new topic is here: '?do=embed' frameborder='0' data-embedContent>>
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now