Zoltan Hudak / TFTPServer

Dependents:   TFTPServerTest

Fork of TFTPServer by Jaap Vermaas

Revision:
1:9c973065a97e
Parent:
0:3b0027b76acf
Child:
2:f7c0fbc8c5aa
diff -r 3b0027b76acf -r 9c973065a97e TFTPServer.cpp
--- a/TFTPServer.cpp	Mon Dec 26 18:18:32 2011 +0000
+++ b/TFTPServer.cpp	Fri Mar 16 19:22:10 2018 +0000
@@ -3,6 +3,7 @@
  * Simple TFTP server
  *
  * Copyright (c) 2011 Jaap Vermaas
+ * Modified for MBED-OS5 by Zoltan Hudak 2018
  *
  *   This file is part of the LaOS project (see: http://wiki.laoslaser.org)
  *
@@ -21,383 +22,551 @@
  *
  */
 #include "TFTPServer.h"
+#include "EthernetInterface.h"
 
-// create a new tftp server, with file directory dir and
-// listening on port
-TFTPServer::TFTPServer(char* dir) {
-    ListenSock = new UDPSocket();
-    ListenSock->setOnEvent(this, &TFTPServer::onListenUDPSocketEvent);
-    state = listen;
-    if (ListenSock->bind(Host(IpAddr(), TFTP_PORT)))
-        state = error;
-    TFTPServerTimer.attach(this, &TFTPServer::cleanUp, 5000);
-    sprintf(workdir, "%s", dir);
-    filecnt = 0;
+//#define TFTP_DEBUG
+
+/**
+ * @brief   Creates a new TFTP server listening on myPort.
+ * @note
+ * @param   net  A pointer to EthernetInterface object.
+ * @param   port A port to listen on (defaults to 69).
+ * @retval
+ */
+TFTPServer::TFTPServer(EthernetInterface* net, uint16_t myPort /* = 69 */)
+{
+    port = myPort;
+#ifdef TFTP_DEBUG
+    printf("TFTPServer(): port=%d\r\n", myPort);
+#endif
+    socket = new UDPSocket(net);
+    state = LISTENING;
+    if (socket->bind(port))
+    {
+        socketAddr = SocketAddress(0, port);
+        state = ERROR;
+    }
+
+#ifdef TFTP_DEBUG
+    printf("FTP server state = %d\r\n", getState());
+#endif
+    socket->set_blocking(false);
+    fileCounter = 0;
 }
 
-// destroy this instance of the tftp server
-TFTPServer::~TFTPServer() {
-    ListenSock->resetOnEvent();
-    delete(ListenSock);
-    delete(remote);
-    state = deleted;
+/**
+ * @brief   Destroys this instance of the TFTP server.
+ * @note
+ * @param
+ * @retval
+ */
+TFTPServer::~TFTPServer()
+{
+    socket->close();
+    delete(socket);
+    strcpy(remoteIP, "");
+    state = DELETED;
 }
 
-void TFTPServer::reset() {
-    ListenSock->resetOnEvent();
-    delete(ListenSock);
-    delete(remote);
-    TFTPServerTimer.detach();
-    ListenSock = new UDPSocket();
-    ListenSock->setOnEvent(this, &TFTPServer::onListenUDPSocketEvent);
-    state = listen;
-    if (ListenSock->bind(Host(IpAddr(), TFTP_PORT)))
-        state = error;
-    TFTPServerTimer.attach(this, &TFTPServer::cleanUp, 5000);
-    sprintf(filename, "");
-    filecnt = 0;
+/**
+ * @brief   Resets the TFTP server.
+ * @note
+ * @param
+ * @retval
+ */
+void TFTPServer::reset()
+{
+    socket->close();
+    delete(socket);
+    strcpy(remoteIP, "");
+    socket = new UDPSocket();
+    state = LISTENING;
+    if (socket->bind(port))
+    {
+        socketAddr = SocketAddress(0, port);
+        state = ERROR;
+    }
+
+    socket->set_blocking(false);
+    strcpy(fileName, "");
+    fileCounter = 0;
 }
 
-// get current tftp status
-TFTPServerState TFTPServer::State() {
+/**
+ * @brief   Gets current TFTP status.
+ * @note
+ * @param
+ * @retval
+ */
+TFTPServer::State TFTPServer::getState()
+{
     return state;
 }
 
-// Temporarily disable incoming TFTP connections
-void TFTPServer::suspend() {
-    state = suspended;
+/**
+ * @brief   Temporarily disables incoming TFTP connections.
+ * @note
+ * @param
+ * @retval
+ */
+void TFTPServer::suspend()
+{
+    state = SUSPENDED;
 }
 
-// Resume after suspension
-void TFTPServer::resume() {
-    if (state == suspended)
-        state = listen;
-}
-
-// During read and write, this gives you the filename
-void TFTPServer::getFilename(char* name) {
-    sprintf(name, "%s", filename);
-}
-
-// return number of received files
-int TFTPServer::fileCnt() {
-    return filecnt;
+/**
+ * @brief   Resumes incoming TFTP connection after suspension.
+ * @note
+ * @param
+ * @retval
+ */
+void TFTPServer::resume()
+{
+    if (state == SUSPENDED)
+        state = LISTENING;
 }
 
-// create a new connection reading a file from server
-void TFTPServer::ConnectRead(char* buff, Host* client) {
-    IpAddr clientIp = client->getIp();
-    int clientPort = client->getPort();
-    remote = new Host(clientIp, clientPort);
-    Ack(0);
-    blockcnt = 0;
-    dupcnt = 0;
+/**
+ * @brief   Polls for data or new connection.
+ * @note
+ * @param
+ * @retval
+ */
+void TFTPServer::poll()
+{
+    if ((state == SUSPENDED) || (state == DELETED) || (state == ERROR))
+        return;
+
+    socket->set_blocking(false);
+
+    char    buff[516];
+    int     len = socket->recvfrom(&socketAddr, buff, sizeof(buff));
+
+    if (len <= 0)
+        return;
+
+#ifdef TFTP_DEBUG
+    printf("Got block with size %d.\n\r", len);
+#endif
+    switch (state) {
+        case LISTENING:
+            {
+                switch (buff[1]) {
+                    case 0x01:          // RRQ
+                        connectRead(buff);
+                        break;
+
+                    case 0x02:          // WRQ
+                        connectWrite(buff);
+                        break;
+
+                    case 0x03:          // DATA before connection established
+                        sendError("No data expected.\r\n");
+                        break;
+
+                    case 0x04:          // ACK before connection established
+                        sendError("No ack expected.\r\n");
+                        break;
+
+                    case 0x05:          // ERROR packet received
+        #ifdef TFTP_DEBUG
+                        printf("TFTP Eror received.\r\n");
+        #endif
+                        break;
+
+                    default:            // unknown TFTP packet type
+                        sendError("Unknown TFTP packet type.\r\n");
+                        break;
+                }                       // switch buff[1]
+                break;                  // case listening
+            }
+
+        case READING:
+            {
+                if (cmpHost())
+                {
+                    switch (buff[1]) {
+                        case 0x01:
+                            // if this is the receiving host, send first packet again
+                            if (blockCounter == 1)
+                            {
+                                ack(0);
+                                dupCounter++;
+                            }
+
+                            if (dupCounter > 10)
+                            {           // too many dups, stop sending
+                                sendError("Too many dups");
+                                fclose(file);
+                                state = LISTENING;
+                                strcpy(remoteIP, "");
+                            }
+                            break;
+
+                        case 0x02:
+                            // this should never happen, ignore
+                            sendError("WRQ received on open read socket");
+                            fclose(file);
+                            state = LISTENING;
+                            strcpy(remoteIP, "");
+                            break;
+
+                        case 0x03:
+                            // we are the sending side, ignore
+                            sendError("Received data package on sending socket");
+                            fclose(file);
+                            state = LISTENING;
+                            strcpy(remoteIP, "");
+                            break;
+
+                        case 0x04:
+                            // last packet received, send next if there is one
+                            dupCounter = 0;
+                            if (blockSize == 516)
+                            {
+                                getBlock();
+                                sendBlock();
+                            }
+                            else
+                            {           //EOF
+                                fclose(file);
+                                state = LISTENING;
+                                strcpy(remoteIP, "");
+                            }
+                            break;
+
+                        default:        // this includes 0x05 errors
+                            sendError("Received 0x05 error message");
+                            fclose(file);
+                            state = LISTENING;
+                            strcpy(remoteIP, "");
+                            break;
+                    }                   // switch (buff[1])
+                }
+
+    #ifdef TFTP_DEBUG
+                else
+                    printf("Ignoring package from other remote client during RRQ.\r\n");
+    #endif
+                break;                  // reading
+            }
+
+        case WRITING:
+            {
+                if (cmpHost())
+                {
+                    switch (buff[1]) {
+                        case 0x02:
+                            {
+                                // if this is a returning host, send ack again
+                                ack(0);
+        #ifdef TFTP_DEBUG
+                                TFTP_DEBUG("Resending Ack on WRQ.\r\n");
+        #endif
+                                break;  // case 0x02
+                            }
 
-    sprintf(filename, "%s%s", workdir, &buff[2]);
-    
-    fp = fopen(filename, "rb");
-    if (fp == NULL) {
-        state  = listen;
-        delete(remote);
-        Err("Could not read file", client);
-    } else {
+                        case 0x03:
+                            {
+                                int block = (buff[2] << 8) + buff[3];
+                                if ((blockCounter + 1) == block)
+                                {
+                                    ack(block);
+                                    // new packet
+                                    char*   data = &buff[4];
+                                    fwrite(data, 1, len - 4, file);
+                                    blockCounter++;
+                                    dupCounter = 0;
+                                }
+                                else
+                                {       // mismatch in block nr
+                                    if ((blockCounter + 1) < block)
+                                    {   // too high
+                                        sendError("Packet count mismatch");
+                                        fclose(file);
+                                        state = LISTENING;
+                                        remove(fileName);
+                                        strcpy(remoteIP, "");
+                                    }
+                                    else
+                                    {   // duplicate packet, send ACK again
+                                        if (dupCounter > 10)
+                                        {
+                                            sendError("Too many dups");
+                                            fclose(file);
+                                            remove(fileName);
+                                            state = LISTENING;
+                                        }
+                                        else
+                                        {
+                                            ack(blockCounter);
+                                            dupCounter++;
+                                        }
+                                    }
+                                }
+
+                                if (len < 516)
+                                {
+                                    ack(blockCounter);
+                                    fclose(file);
+                                    state = LISTENING;
+                                    strcpy(remoteIP, "");
+                                    fileCounter++;
+        #ifdef TFTP_DEBUG
+                                    printf("File receive finished.\r\n");
+        #endif
+                                }
+                                break;  // case 0x03
+                            }
+
+                        default:
+                            {
+                                sendError("No idea why you're sending me this!");
+                                break;  // default
+                            }
+                    }                   // switch (buff[1])
+                }
+
+    #ifdef TFTP_DEBUG
+                else
+                    printf("Ignoring packege from other remote client during WRQ.\r\n");
+    #endif
+                break;                  // writing
+            }
+
+        case ERROR:
+            { }
+
+        case SUSPENDED:
+            { }
+
+        case DELETED:
+            { }
+    }                                   // state
+}
+
+/**
+ * @brief   Gets the file name during read and write.
+ * @note
+ * @param   name  A pointer to C-style string to be filled with file name.
+ * @retval
+ */
+void TFTPServer::getFileName(char* name)
+{
+    sprintf(name, "%s", fileName);
+}
+
+/**
+ * @brief   Returns number of received files.
+ * @note
+ * @param
+ * @retval
+ */
+int TFTPServer::fileCount()
+{
+    return fileCounter;
+}
+
+/**
+ * @brief   Creates a new connection reading a file from server.
+ * @note    Sends the file to the remote client.
+ *          Sends en error message to the remote client in case of failure.
+ * @param   buff  A char array for passing input data.
+ * @retval
+ */
+void TFTPServer::connectRead(char* buff)
+{
+    remoteIP = const_cast<char*>(socketAddr.get_ip_address());
+    remotePort = socketAddr.get_port();
+    blockCounter = 0;
+    dupCounter = 0;
+
+    sprintf(fileName, "%s", &buff[2]);
+
+    if (modeOctet(buff))
+        file = fopen(fileName, "rb");
+    else
+        file = fopen(fileName, "r");
+
+    if (!file)
+    {
+        state = LISTENING;
+
+        char    msg[123] = { "Could not read file: " };
+
+        strcat(msg, fileName);
+        strcat(msg, "\r\n");
+        sendError(msg);
+    }
+    else
+    {
         // file ready for reading
-        blockcnt = 0;
-        state = reading;
-        #ifdef TFTP_DEBUG
-            char debugmsg[256];
-            sprintf(debugmsg, "Listen: Requested file %s from TFTP connection %d.%d.%d.%d port %d",
-                filename, clientIp[0], clientIp[1], clientIp[2], clientIp[3], clientPort);
-            TFTP_DEBUG(debugmsg);
-        #endif
+        state = READING;
+#ifdef TFTP_DEBUG
+        printf
+        (
+            "Listening: Requested file %s from TFTP connection %d.%d.%d.%d port %d\r\n",
+            fileName,
+            clientIp[0],
+            clientIp[1],
+            clientIp[2],
+            clientIp[3],
+            clientPort
+        );
+#endif
         getBlock();
         sendBlock();
     }
 }
 
-// create a new connection writing a file to the server
-void TFTPServer::ConnectWrite(char* buff, Host* client) {
-    IpAddr clientIp = client->getIp();
-    int clientPort = client->getPort();
-    remote = new Host(clientIp, clientPort);
-    Ack(0);
-    blockcnt = 0;
-    dupcnt = 0;
+/**
+ * @brief   Creates a new connection for writing a file to the server.
+ * @note    Sends the file to the TFTP server.
+ *          Sends error message to the remote client in case of failure.
+ * @param   buff  A char array for passing input data.
+ * @retval
+ */
+void TFTPServer::connectWrite(char* buff)
+{
+    remoteIP = const_cast<char*>(socketAddr.get_ip_address());
+    remotePort = socketAddr.get_port();
+    ack(0);
+    blockCounter = 0;
+    dupCounter = 0;
+    sprintf(fileName, "%s", &buff[2]);
 
-    sprintf(filename, "%s%s", workdir, &buff[2]);
+    if (modeOctet(buff))
+        file = fopen(fileName, "wb");
+    else
+        file = fopen(fileName, "w");
 
-    fp = fopen(filename, "wb");
-    if (fp == NULL) {
-        Err("Could not open file to write", client);
-        state  = listen;
-        delete(remote);
-    } else {
+    if (file == NULL)
+    {
+        sendError("Could not open file to write.\r\n");
+        state = LISTENING;
+        strcpy(remoteIP, "");
+    }
+    else
+    {
         // file ready for writing
-        blockcnt = 0;
-        state = writing;
-        #ifdef TFTP_DEBUG 
-            char debugmsg[256];
-            sprintf(debugmsg, "Listen: Incoming file %s on TFTP connection from %d.%d.%d.%d clientPort %d",
-                filename, clientIp[0], clientIp[1], clientIp[2], clientIp[3], clientPort);
-            TFTP_DEBUG(debugmsg);
-        #endif
+        blockCounter = 0;
+        state = WRITING;
+#ifdef TFTP_DEBUG
+        printf
+        (
+            "Listening: Incoming file %s on TFTP connection from %d.%d.%d.%d clientPort %d\r\n",
+            fileName,
+            clientIp[0],
+            clientIp[1],
+            clientIp[2],
+            clientIp[3],
+            clientPort
+        );
+#endif
     }
 }
 
-// get DATA block from file on disk into memory
-void TFTPServer::getBlock() {
-    blockcnt++;
-    char *p;
-    p = &sendbuff[4];
-    int len = fread(p, 1, 512, fp);
-    sendbuff[0] = 0x00;
-    sendbuff[1] = 0x03;
-    sendbuff[2] = blockcnt >> 8;
-    sendbuff[3] = blockcnt & 255;
-    blocksize = len+4;
+/**
+ * @brief   Gets DATA block from file on disk into memory.
+ * @note
+ * @param
+ * @retval
+ */
+void TFTPServer::getBlock()
+{
+    blockCounter++;
+
+    blockBuff[0] = 0x00;
+    blockBuff[1] = 0x03;
+    blockBuff[2] = blockCounter >> 8;
+    blockBuff[3] = blockCounter & 255;
+    blockSize = 4 + fread((void*) &blockBuff[4], 1, 512, file);
 }
 
-// send DATA block to the client
-void TFTPServer::sendBlock() {
-    ListenSock->sendto(sendbuff, blocksize, remote);
-}
-
-
-// compare host IP and Port with connected remote machine
-int TFTPServer::cmpHost(Host* client) {
-    IpAddr clientIp = client->getIp();
-    IpAddr remoteIp = remote->getIp();
-    int clientPort = client->getPort();
-    int remotePort = remote->getPort();
-    return ((clientIp == remoteIp) && (clientPort == remotePort));
+/**
+ * @brief   Sends DATA block to remote client.
+ * @note
+ * @param
+ * @retval
+ */
+void TFTPServer::sendBlock()
+{
+    socket->sendto(socketAddr, blockBuff, blockSize);
 }
 
-// send ACK to remote
-void TFTPServer::Ack(int val) {
-    char ack[4];
-    ack[0] = 0x00;
-    ack[1] = 0x04;
-    if ((val>603135) || (val<0)) val = 0;
-    ack[2] = val >> 8;
-    ack[3] = val & 255;
-    ListenSock->sendto(ack, 4, remote);
+/**
+ * @brief   Compares host's IP and Port with connected remote machine.
+ * @note
+ * @param
+ * @retval
+ */
+int TFTPServer::cmpHost()
+{
+    char    ip[17];
+    strcpy(ip, socketAddr.get_ip_address());
+
+    int port = socketAddr.get_port();
+    return((strcmp(ip, remoteIP) == 0) && (port == remotePort));
 }
 
-// send ERR message to named client
-void TFTPServer::Err(char* msg, Host* client) {
-    char message[32];
-    strncpy(message, msg, 32);
-    char err[37];
-    sprintf(err, "0000%s0", message);
-    err[0] = 0x00;
-    err[1] = 0x05;
-    err[2]=0x00;
-    err[3]=0x00;
-    int len = strlen(err);
-    err[len-1] = 0x00;
-    ListenSock->sendto(err, len, client);
+/**
+ * @brief   Sends ACK to remote client.
+ * @note
+ * @param
+ * @retval
+ */
+void TFTPServer::ack(int val)
+{
+    char    ack[4];
+    ack[0] = 0x00;
+    ack[1] = 0x04;
+    if ((val > 603135) || (val < 0))
+        val = 0;
+    ack[2] = val >> 8;
+    ack[3] = val & 255;
+    socket->sendto(socketAddr, ack, 4);
+}
+
+/**
+ * @brief   Sends ERROR message to remote client.
+ * @note    msg A C-style string with error message to be sent.
+ * @param
+ * @retval
+ */
+void TFTPServer::sendError(const char* msg)
+{
+    errorBuff[0] = 0x00;
+    errorBuff[1] = 0x05;
+    errorBuff[2] = 0x00;
+    errorBuff[3] = 0x00;
+    errorBuff[4] = '\0';    // termination char
+    strcat(&errorBuff[4], msg);
+
+    int len = 4 + strlen(&errorBuff[4]) + 1;
+    socket->sendto(socketAddr, errorBuff, len);
     #ifdef TFTP_DEBUG
-        char debugmsg[256];
-        sprintf(debugmsg, "Error: %s", message);
-        TFTP_DEBUG(debugmsg);
+        printf("Error: %s\r\n", msg);
     #endif
 }
 
-// check if connection mode of client is octet/binary
-int TFTPServer::modeOctet(char* buff) {
+/**
+ * @brief   Checks if connection mode of client is octet/binary.
+ * @note    buff  A char array.
+ * @param
+ * @retval
+ */
+int TFTPServer::modeOctet(char* buff)
+{
     int x = 2;
-    while (buff[x++] != 0); // get beginning of mode field
+
+    while (buff[x++] != 0);
+    // get beginning of mode field
     int y = x;
-    while (buff[y] != 0) {
+    while (buff[y] != 0)
+    {
         buff[y] = tolower(buff[y]);
         y++;
-    } // make mode field lowercase
-    return (strcmp(&buff[x++], "octet") == 0);
-}
-
-// timed routine to avoid hanging after interrupted transfers
-void TFTPServer::cleanUp() {
-    static int lastcnt;
-    switch (state) {
-        case reading:
-            if (lastcnt == blockcnt) {
-                fclose(fp);
-                state=listen;
-                delete(remote);
-            }
-            break;
-        case writing:
-            if (lastcnt == blockcnt) {
-                fclose(fp);
-                state = listen;
-                remove(filename);
-                delete(remote);
-            }
-            break;
-    } // state
-    lastcnt = blockcnt;
-}
+    }   // make mode field lowercase
 
-// event driven routines to handle incoming packets
-void TFTPServer::onListenUDPSocketEvent(UDPSocketEvent e) {
-    extern SDFileSystem sd;
-    Host* client = new Host();
-    char buff[516];
-    if (e == UDPSOCKET_READABLE) {
-        switch (state) {
-            case listen:
-                if (int len = ListenSock->recvfrom(buff, 516, client)) {
-                    switch (buff[1]) {
-                        case 0x01: // RRQ
-                            if (modeOctet(buff))
-                                ConnectRead(buff, client);
-                            else
-                                Err("Not in octet mode", client);
-                            break;
-                        case 0x02: // WRQ
-                            if (modeOctet(buff))
-                                ConnectWrite(buff, client);
-                            else
-                                Err("Not in octet mode", client);
-                            break;
-                        case 0x03: // DATA before connection established
-                            Err("No data expected", client);
-                            break;
-                        case 0x04:  // ACK before connection established
-                            Err("No ack expected", client);
-                            break;
-                        case 0x05: // ERROR packet received
-                            #ifdef TFTP_DEBUG
-                                TFTP_DEBUG("TFTP Eror received\n\r");
-                            #endif
-                            break;
-                        default:    // unknown TFTP packet type
-                            Err("Unknown TFTP packet type", client);
-                            break;
-                    } // switch buff[1]
-                } // recvfrom
-                break; // case listen
-            case reading:
-                while (int len = ListenSock->recvfrom(buff, 516, client) ) {
-                    switch (buff[1]) {
-                        case 0x01:
-                            // if this is the receiving host, send first packet again
-                            if ((cmpHost(client) && blockcnt==1)) {
-                                sendBlock();
-                                dupcnt++;
-                            }
-                            if (dupcnt>10) { // too many dups, stop sending
-                                fclose(fp);
-                                state=listen;
-                                delete(remote);
-                            }
-                            break;
-                        case 0x02:
-                            // this should never happen, ignore
-                            break; // case 0x02
-                        case 0x03:
-                            // we are the sending side, ignore
-                            break;
-                        case 0x04:
-                            // last packet received, send next if there is one
-                            dupcnt = 0;
-                            if (blocksize == 516) {
-                                getBlock();
-                                sendBlock();
-                            } else { //EOF
-                                fclose(fp);
-                                state = listen;
-                                delete(remote);
-                            }
-                            break;
-                        default:  // this includes 0x05 errors
-                            fclose(fp);
-                            state = listen;
-                            delete(remote);
-                            break;
-                    } // switch (buff[1])
-                } // while
-                break; // reading
-            case writing:
-                while (int len = ListenSock->recvfrom(buff, 516, client) ) {
-                    switch (buff[1]) {
-                        case 0x02:
-                            // if this is a returning host, send ack again
-                            if (cmpHost(client)) {
-                                Ack(0);
-                                #ifdef TFTP_DEBUG
-                                    TFTP_DEBUG("Resending Ack on WRQ");
-                                #endif
-                            }
-                            break; // case 0x02
-                        case 0x03:
-                            if (cmpHost(client)) { // check if this is our partner
-                                int block = (buff[2] << 8) + buff[3];
-                                if ((blockcnt+1) == block) {
-                                    Ack(block);
-                                    // new packet
-                                    char *data = &buff[4];
-                                    fwrite(data, 1,len-4, fp);
-                                    blockcnt++;
-                                    dupcnt = 0;
-                                } else {
-                                    if ((blockcnt+1) < block) { // high block nr
-                                        // we missed a packet, error
-                                        #ifdef TFTP_DEBUG
-                                            TFTP_DEBUG("Missed packet!");
-                                        #endif
-                                        fclose(fp);
-                                        state = listen;
-                                        remove(filename);
-                                        delete(remote);
-                                    } else { // duplicate packet, do nothing
-                                        #ifdef TFTP_DEBUG
-                                            char debugmsg[256];
-                                            sprintf(debugmsg, "Dupblicate packet %d", blockcnt);
-                                            TFTP_DEBUG(debugmsg);
-                                        #endif
-                                        if (dupcnt > 10) {
-                                            Err("Too many dups", client);
-                                            fclose(fp);
-                                            remove(filename);
-                                            state = listen;
-                                        } else {
-                                            Ack(blockcnt);
-                                        }
-                                        dupcnt++;
-                                    }
-                                }
-                                //printf ("Read packet %d with blocksize = %d\n\r", blockcnt, len);
-                                if (len<516) {
-                                    #ifdef TFTP_DEBUG
-                                        char debugmsg[256];
-                                        sprintf(debugmsg, "Read last block %d", len);
-                                        TFTP_DEBUG(debugmsg);
-                                    #endif
-                                    fclose(fp);
-                                    state = listen;
-                                    delete(remote);
-                                    filecnt++;
-                                }
-                                break; // case 0x03
-                            }  else // if cmpHost
-                                Err("Wrong IP/Port: Not your connection!", client);
-                            break; // case 0x03
-                        default:
-                            Err("No idea why you're sending me this!", client);
-                            break; // default
-                    } // switch (buff[1])
-                } // while
-                break; // writing
-            case suspended:
-                if (int len = ListenSock->recvfrom(buff, 516, client))
-                    Err("Packet received on suspended socket, discarded", client);
-                break;
-        } // state
-    } else {
-        #ifdef TFTP_DEBUG
-            TFTP_DEBUG("TFTP unknown UDP status");
-        #endif
-    }
-    delete(client);
+    return(strcmp(&buff[x++], "octet") == 0);
 }