The branch main has been updated by manu:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=bf07f2f8623d5e29e814b9dc49a0cdff920778c3

commit bf07f2f8623d5e29e814b9dc49a0cdff920778c3
Author:     Emmanuel Vadot <m...@freebsd.org>
AuthorDate: 2021-12-08 15:18:49 +0000
Commit:     Emmanuel Vadot <m...@freebsd.org>
CommitDate: 2021-12-16 10:50:29 +0000

    loader: tftp: Don't error on tftp error 0
    
    tftp-hpa sends NAK with tftp error set to 0 when trying to get
    a directory and this is the first thing that loader tries to do
    and this make it hangs.
    
    Reviewed by:    imp, tsoome
    MFC after:      2 weeks
    Sponsored by:   Beckhoff Automation GmbH & Co. KG
    Differential Revision:  https://reviews.freebsd.org/D33406
---
 stand/libsa/tftp.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/stand/libsa/tftp.c b/stand/libsa/tftp.c
index 01f5753a2163..80156cf95ef0 100644
--- a/stand/libsa/tftp.c
+++ b/stand/libsa/tftp.c
@@ -122,7 +122,7 @@ struct tftprecv_extra {
 
 #define        TFTP_MAX_ERRCODE EOPTNEG
 static const int tftperrors[TFTP_MAX_ERRCODE + 1] = {
-       0,                      /* ??? */
+       0,                      /* NAK */
        ENOENT,
        EPERM,
        ENOSPC,
@@ -188,6 +188,7 @@ recvtftp(struct iodesc *d, void **pkt, void **payload, 
time_t tleft,
        struct tftphdr *t;
        void *ptr = NULL;
        ssize_t len;
+       int tftp_error;
 
        errno = 0;
        extra = recv_extra;
@@ -234,16 +235,20 @@ recvtftp(struct iodesc *d, void **pkt, void **payload, 
time_t tleft,
                return (got);
        }
        case ERROR:
-               if ((unsigned)ntohs(t->th_code) > TFTP_MAX_ERRCODE) {
-                       printf("illegal tftp error %d\n", ntohs(t->th_code));
+               tftp_error = ntohs(t->th_code);
+               if ((unsigned)tftp_error > TFTP_MAX_ERRCODE) {
+                       printf("illegal tftp error %d\n", tftp_error);
                        errno = EIO;
                } else {
 #ifdef TFTP_DEBUG
-                       printf("tftp-error %d\n", ntohs(t->th_code));
+                       printf("tftp-error %d\n", tftp_error);
 #endif
-                       errno = tftperrors[ntohs(t->th_code)];
+                       errno = tftperrors[tftp_error];
                }
                free(ptr);
+               /* If we got a NAK return 0, it's usually a directory */
+               if (tftp_error == 0)
+                       return (0);
                return (-1);
        case OACK: {
                struct udphdr *uh;

Reply via email to