]> The Tcpdump Group git mirrors - tcpdump/commitdiff
Just dissect the TFTP packet byte by byte.
authorGuy Harris <[email protected]>
Wed, 15 Feb 2017 23:24:56 +0000 (15:24 -0800)
committerDenis Ovsienko <[email protected]>
Wed, 13 Sep 2017 11:25:44 +0000 (12:25 +0100)
Don't use a structure to define the layout - Coverity gets confused by
tu_stuff being 1 byte, and complains that we're going past 1 byte.

Should fix Coverity CID 1400556.

print-tftp.c

index 69bc601fdda4ed8be3ac4f5e2bb9e24098be8ce8..6600c9cf673100acf5650734acb9663a197317d2 100644 (file)
 #define        TFTP_ERROR      05                      /* error code */
 #define OACK   06                      /* option acknowledgement */
 
-struct tftphdr {
-       unsigned short  th_opcode;              /* packet type */
-       union {
-               unsigned short  tu_block;       /* block # */
-               unsigned short  tu_code;        /* error code */
-               char    tu_stuff[1];    /* request packet stuff */
-       } th_u;
-       char    th_data[1];             /* data or error string */
-};
-
-#define        th_block        th_u.tu_block
-#define        th_code         th_u.tu_code
-#define        th_stuff        th_u.tu_stuff
-#define        th_msg          th_data
-
 /*
  * Error codes.
  */
@@ -106,80 +91,75 @@ void
 tftp_print(netdissect_options *ndo,
            register const u_char *bp, u_int length)
 {
-       register const struct tftphdr *tp;
        register const char *cp;
-       register const u_char *p;
        register int opcode;
        u_int ui;
 
-       tp = (const struct tftphdr *)bp;
-
        /* Print length */
        ND_PRINT((ndo, " %d", length));
 
        /* Print tftp request type */
        if (length < 2)
                goto trunc;
-       ND_TCHECK(tp->th_opcode);
-       opcode = EXTRACT_16BITS(&tp->th_opcode);
+       ND_TCHECK_16BITS(bp);
+       opcode = EXTRACT_16BITS(bp);
        cp = tok2str(op2str, "tftp-#%d", opcode);
-       length -= 2;
        ND_PRINT((ndo, " %s", cp));
        /* Bail if bogus opcode */
        if (*cp == 't')
                return;
+       bp += 2;
+       length -= 2;
 
        switch (opcode) {
 
        case RRQ:
        case WRQ:
-               p = (const u_char *)tp->th_stuff;
                if (length == 0)
                        goto trunc;
                ND_PRINT((ndo, " "));
                /* Print filename */
                ND_PRINT((ndo, "\""));
-               ui = fn_printztn(ndo, p, length, ndo->ndo_snapend);
+               ui = fn_printztn(ndo, bp, length, ndo->ndo_snapend);
                ND_PRINT((ndo, "\""));
                if (ui == 0)
                        goto trunc;
-               p += ui;
+               bp += ui;
                length -= ui;
 
                /* Print the mode - RRQ and WRQ only */
                if (length == 0)
                        goto trunc;     /* no mode */
                ND_PRINT((ndo, " "));
-               ui = fn_printztn(ndo, p, length, ndo->ndo_snapend);
+               ui = fn_printztn(ndo, bp, length, ndo->ndo_snapend);
                if (ui == 0)
                        goto trunc;
-               p += ui;
+               bp += ui;
                length -= ui;
 
                /* Print options, if any */
                while (length != 0) {
-                       ND_TCHECK(*p);
-                       if (*p != '\0')
+                       ND_TCHECK(*bp);
+                       if (*bp != '\0')
                                ND_PRINT((ndo, " "));
-                       ui = fn_printztn(ndo, p, length, ndo->ndo_snapend);
+                       ui = fn_printztn(ndo, bp, length, ndo->ndo_snapend);
                        if (ui == 0)
                                goto trunc;
-                       p += ui;
+                       bp += ui;
                        length -= ui;
                }
                break;
 
        case OACK:
-               p = (const u_char *)tp->th_stuff;
                /* Print options */
                while (length != 0) {
-                       ND_TCHECK(*p);
-                       if (*p != '\0')
+                       ND_TCHECK(*bp);
+                       if (*bp != '\0')
                                ND_PRINT((ndo, " "));
-                       ui = fn_printztn(ndo, p, length, ndo->ndo_snapend);
+                       ui = fn_printztn(ndo, bp, length, ndo->ndo_snapend);
                        if (ui == 0)
                                goto trunc;
-                       p += ui;
+                       bp += ui;
                        length -= ui;
                }
                break;
@@ -188,23 +168,24 @@ tftp_print(netdissect_options *ndo,
        case DATA:
                if (length < 2)
                        goto trunc;     /* no block number */
-               ND_TCHECK(tp->th_block);
-               ND_PRINT((ndo, " block %d", EXTRACT_16BITS(&tp->th_block)));
+               ND_TCHECK_16BITS(bp);
+               ND_PRINT((ndo, " block %d", EXTRACT_16BITS(bp)));
                break;
 
        case TFTP_ERROR:
                /* Print error code string */
                if (length < 2)
                        goto trunc;     /* no error code */
-               ND_TCHECK(tp->th_code);
+               ND_TCHECK_16BITS(bp);
                ND_PRINT((ndo, " %s", tok2str(err2str, "tftp-err-#%d \"",
-                                      EXTRACT_16BITS(&tp->th_code))));
+                                      EXTRACT_16BITS(bp))));
+               bp += 2;
                length -= 2;
                /* Print error message string */
                if (length == 0)
                        goto trunc;     /* no error message */
                ND_PRINT((ndo, " \""));
-               ui = fn_printztn(ndo, (const u_char *)tp->th_data, length, ndo->ndo_snapend);
+               ui = fn_printztn(ndo, bp, length, ndo->ndo_snapend);
                ND_PRINT((ndo, "\""));
                if (ui == 0)
                        goto trunc;